feat: support sub route config (#3071)
* feat: support sub route config * dockerfile * fix upload * delete unused code
This commit is contained in:
parent
dc95ab1dc1
commit
3b82ed0aa1
@ -16,7 +16,7 @@ export const bucketNameMap = {
|
||||
}
|
||||
};
|
||||
|
||||
export const ReadFileBaseUrl = `${process.env.FE_DOMAIN || ''}/api/common/file/read`;
|
||||
export const ReadFileBaseUrl = `${process.env.FE_DOMAIN || ''}${process.env.NEXT_PUBLIC_BASE_URL}/api/common/file/read`;
|
||||
|
||||
export const documentFileType = '.txt, .docx, .csv, .xlsx, .pdf, .md, .html, .pptx';
|
||||
export const imageFileType =
|
||||
|
||||
@ -14,7 +14,6 @@ import type {
|
||||
ChatCompletionToolMessageParam
|
||||
} from '../../core/ai/type.d';
|
||||
import { ChatCompletionRequestMessageRoleEnum } from '../../core/ai/constants';
|
||||
|
||||
const GPT2Chat = {
|
||||
[ChatCompletionRequestMessageRoleEnum.System]: ChatRoleEnum.System,
|
||||
[ChatCompletionRequestMessageRoleEnum.User]: ChatRoleEnum.Human,
|
||||
@ -61,14 +60,14 @@ export const chats2GPTMessages = ({
|
||||
return {
|
||||
type: 'image_url',
|
||||
image_url: {
|
||||
url: item.file?.url || ''
|
||||
url: item.file.url
|
||||
}
|
||||
};
|
||||
} else if (item.file?.type === ChatFileTypeEnum.file) {
|
||||
return {
|
||||
type: 'file_url',
|
||||
name: item.file?.name || '',
|
||||
url: item.file?.url || ''
|
||||
url: item.file.url
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,3 +9,12 @@ export const getUserFingerprint = async () => {
|
||||
export const hasHttps = () => {
|
||||
return window.location.protocol === 'https:';
|
||||
};
|
||||
|
||||
export const getWebReqUrl = (url: string = '') => {
|
||||
if (!url) return '/';
|
||||
const baseUrl = process.env.NEXT_PUBLIC_BASE_URL;
|
||||
if (!baseUrl) return url;
|
||||
|
||||
if (!url.startsWith('/') || url.startsWith(baseUrl)) return url;
|
||||
return `${baseUrl}${url}`;
|
||||
};
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import React from 'react';
|
||||
import { Box, Flex, Image } from '@chakra-ui/react';
|
||||
import { Box } from '@chakra-ui/react';
|
||||
import type { ImageProps } from '@chakra-ui/react';
|
||||
import { LOGO_ICON } from '@fastgpt/global/common/system/constants';
|
||||
import MyIcon from '../Icon';
|
||||
import { iconPaths } from '../Icon/constants';
|
||||
import MyImage from '../Image/MyImage';
|
||||
|
||||
const Avatar = ({ w = '30px', src, ...props }: ImageProps) => {
|
||||
// @ts-ignore
|
||||
@ -14,7 +15,7 @@ const Avatar = ({ w = '30px', src, ...props }: ImageProps) => {
|
||||
<MyIcon name={src as any} w={w} borderRadius={props.borderRadius} />
|
||||
</Box>
|
||||
) : (
|
||||
<Image
|
||||
<MyImage
|
||||
fallbackSrc={LOGO_ICON}
|
||||
fallbackStrategy={'onError'}
|
||||
objectFit={'contain'}
|
||||
|
||||
7
packages/web/components/common/Image/MyImage.tsx
Normal file
7
packages/web/components/common/Image/MyImage.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
import React from 'react';
|
||||
import { Image, ImageProps } from '@chakra-ui/react';
|
||||
import { getWebReqUrl } from '../../../common/system/utils';
|
||||
const MyImage = (props: ImageProps) => {
|
||||
return <Image {...props} src={getWebReqUrl(props.src)} alt={props.alt || ''} />;
|
||||
};
|
||||
export default React.memo(MyImage);
|
||||
@ -1,9 +1,10 @@
|
||||
import React from 'react';
|
||||
import { PhotoProvider, PhotoView } from 'react-photo-view';
|
||||
import 'react-photo-view/dist/react-photo-view.css';
|
||||
import { Box, Image, ImageProps } from '@chakra-ui/react';
|
||||
import { ImageProps } from '@chakra-ui/react';
|
||||
import { useSystem } from '../../../hooks/useSystem';
|
||||
import Loading from '../MyLoading';
|
||||
import MyImage from './MyImage';
|
||||
|
||||
const MyPhotoView = ({ ...props }: ImageProps) => {
|
||||
const { isPc } = useSystem();
|
||||
@ -15,7 +16,7 @@ const MyPhotoView = ({ ...props }: ImageProps) => {
|
||||
loadingElement={<Loading fixed={false} />}
|
||||
>
|
||||
<PhotoView src={props.src}>
|
||||
<Image cursor={'pointer'} {...props} />
|
||||
<MyImage cursor={'pointer'} {...props} />
|
||||
</PhotoView>
|
||||
</PhotoProvider>
|
||||
);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import MyIcon from '../Icon';
|
||||
import { Flex, Image, Box, CloseButton, FlexProps } from '@chakra-ui/react';
|
||||
import { Flex, Box, CloseButton, FlexProps } from '@chakra-ui/react';
|
||||
import { useLoading } from '../../../hooks/useLoading';
|
||||
import Avatar from '../Avatar';
|
||||
|
||||
type Props = FlexProps & {
|
||||
onClose: () => void;
|
||||
@ -50,15 +50,7 @@ const CustomRightDrawer = ({
|
||||
py={'10px'}
|
||||
px={5}
|
||||
>
|
||||
{iconSrc && (
|
||||
<>
|
||||
{iconSrc.startsWith('/') ? (
|
||||
<Image mr={3} objectFit={'contain'} alt="" src={iconSrc} w={'20px'} />
|
||||
) : (
|
||||
<MyIcon mr={3} name={iconSrc as any} w={'20px'} />
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{iconSrc && <Avatar mr={3} w={'20px'} src={iconSrc} />}
|
||||
<Box flex={'1'} fontSize={'md'}>
|
||||
{title}
|
||||
</Box>
|
||||
|
||||
@ -13,6 +13,7 @@ import {
|
||||
Box
|
||||
} from '@chakra-ui/react';
|
||||
import { useLoading } from '../../../hooks/useLoading';
|
||||
import Avatar from '../Avatar';
|
||||
|
||||
type Props = DrawerContentProps & {
|
||||
onClose: () => void;
|
||||
@ -52,15 +53,7 @@ const MyRightDrawer = ({
|
||||
py={'10px'}
|
||||
px={5}
|
||||
>
|
||||
{iconSrc && (
|
||||
<>
|
||||
{iconSrc.startsWith('/') ? (
|
||||
<Image mr={3} objectFit={'contain'} alt="" src={iconSrc} w={'20px'} />
|
||||
) : (
|
||||
<MyIcon mr={3} name={iconSrc as any} w={'20px'} />
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{iconSrc && <Avatar mr={3} w={'20px'} src={iconSrc} />}
|
||||
<Box flex={'1'} fontSize={'md'}>
|
||||
{title}
|
||||
</Box>
|
||||
|
||||
@ -2,9 +2,10 @@ import React, { useCallback, useRef, useState } from 'react';
|
||||
import Editor, { Monaco, loader } from '@monaco-editor/react';
|
||||
import { Box, BoxProps } from '@chakra-ui/react';
|
||||
import MyIcon from '../../Icon';
|
||||
import { getWebReqUrl } from '../../../../common/system/utils';
|
||||
|
||||
loader.config({
|
||||
paths: { vs: '/js/monaco-editor.0.45.0/vs' }
|
||||
paths: { vs: getWebReqUrl('/js/monaco-editor.0.45.0/vs') }
|
||||
});
|
||||
|
||||
type EditorVariablePickerType = {
|
||||
|
||||
@ -4,9 +4,10 @@ import { Box, BoxProps } from '@chakra-ui/react';
|
||||
import MyIcon from '../../Icon';
|
||||
import { useToast } from '../../../../hooks/useToast';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { getWebReqUrl } from '../../../../common/system/utils';
|
||||
|
||||
loader.config({
|
||||
paths: { vs: '/js/monaco-editor.0.45.0/vs' }
|
||||
paths: { vs: getWebReqUrl('/js/monaco-editor.0.45.0/vs') }
|
||||
});
|
||||
|
||||
type EditorVariablePickerType = {
|
||||
|
||||
@ -1,97 +0,0 @@
|
||||
import { Box, Button, Image } from '@chakra-ui/react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
export default function ComfirmVar({
|
||||
newVariables,
|
||||
onCancel,
|
||||
onConfirm
|
||||
}: {
|
||||
newVariables: string[];
|
||||
onCancel: () => void;
|
||||
onConfirm: () => void;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<>
|
||||
<Box
|
||||
background={'rgba(35, 56, 118, 0.2)'}
|
||||
rounded={'sm'}
|
||||
position={'absolute'}
|
||||
top={0}
|
||||
left={0}
|
||||
right={0}
|
||||
bottom={0}
|
||||
/>
|
||||
<Box
|
||||
position={'absolute'}
|
||||
top={'50%'}
|
||||
left={'50%'}
|
||||
transform={'translate(-50%, -50%)'}
|
||||
w={'70%'}
|
||||
h={'70%'}
|
||||
bg={'white'}
|
||||
rounded={'lg'}
|
||||
boxShadow={'0 2px 4px rgba(0, 0, 0, 0.1)'}
|
||||
display={'flex'}
|
||||
flexDirection={'column'}
|
||||
justifyContent={'space-between'}
|
||||
pb={4}
|
||||
>
|
||||
<Box display={'flex'} mt={4} mr={4}>
|
||||
<Box
|
||||
w={'36px'}
|
||||
h={'36px'}
|
||||
minW={'36px'}
|
||||
boxShadow={'0 4px 8px rgba(0, 0, 0, 0.1)'}
|
||||
display={'flex'}
|
||||
alignItems={'center'}
|
||||
justifyContent={'center'}
|
||||
rounded={'md'}
|
||||
border={'1px solid rgba(0, 0, 0, 0.1)'}
|
||||
mx={4}
|
||||
>
|
||||
<Image alt={''} src={'/imgs/workflow/variable.png'} objectFit={'contain'} w={'20px'} />
|
||||
</Box>
|
||||
<Box>{t('common:undefined_var')}</Box>
|
||||
</Box>
|
||||
<Box
|
||||
ml={16}
|
||||
mt={4}
|
||||
fontSize={'sm'}
|
||||
color={'rgb(28,100,242)'}
|
||||
display={'flex'}
|
||||
whiteSpace={'wrap'}
|
||||
>
|
||||
{newVariables.map((item, index) => (
|
||||
<Box
|
||||
key={index}
|
||||
display={'flex'}
|
||||
alignItems={'center'}
|
||||
justifyContent={'center'}
|
||||
bg={'rgb(237,242,250)'}
|
||||
px={1}
|
||||
h={6}
|
||||
rounded={'md'}
|
||||
mr={2}
|
||||
>
|
||||
<span>
|
||||
<span style={{ opacity: '60%' }}>{`{{`}</span>
|
||||
<span>{item}</span>
|
||||
<span style={{ opacity: '60%' }}>{`}}`}</span>
|
||||
</span>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
<Box>
|
||||
<Box display={'flex'} justifyContent={'flex-end'} mt={4} mr={4}>
|
||||
<Button size={'sm'} variant={'ghost'} onClick={onCancel}>
|
||||
{t('common:common.Cancel')}
|
||||
</Button>
|
||||
<Button size={'sm'} variant={'primary'} ml={4} onClick={onConfirm}>
|
||||
{t('common:common.Confirm')}
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@ -1119,7 +1119,6 @@
|
||||
"tag_list": "Tag List",
|
||||
"team_tag": "Team Tag",
|
||||
"textarea_variable_picker_tip": "Enter \"/\" to select a variable",
|
||||
"undefined_var": "Referenced an undefined variable, add it automatically?",
|
||||
"unit.character": "Character",
|
||||
"unit.minute": "Minute",
|
||||
"unusable_variable": "No Usable Variables",
|
||||
|
||||
@ -1125,7 +1125,6 @@
|
||||
"tag_list": "标签列表",
|
||||
"team_tag": "团队标签",
|
||||
"textarea_variable_picker_tip": "输入\"/\"可选择变量",
|
||||
"undefined_var": "引用了未定义的变量,是否自动添加?",
|
||||
"unit.character": "字符",
|
||||
"unit.minute": "分钟",
|
||||
"unusable_variable": "无可用变量",
|
||||
|
||||
@ -35,6 +35,8 @@ SANDBOX_URL=http://localhost:3001
|
||||
PRO_URL=
|
||||
# 页面的地址,用于自动补全相对路径资源的 domain
|
||||
FE_DOMAIN=http://localhost:3000
|
||||
# 二级路由
|
||||
# NEXT_PUBLIC_BASE_URL=/fastai
|
||||
|
||||
# 日志等级: debug, info, warn, error
|
||||
LOG_LEVEL=debug
|
||||
|
||||
@ -26,6 +26,7 @@ FROM node:20.14.0-alpine AS builder
|
||||
WORKDIR /app
|
||||
|
||||
ARG proxy
|
||||
ARG base_url
|
||||
|
||||
# copy common node_modules and one project node_modules
|
||||
COPY package.json pnpm-workspace.yaml .npmrc tsconfig.json ./
|
||||
@ -39,6 +40,7 @@ RUN [ -z "$proxy" ] || sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /
|
||||
RUN apk add --no-cache libc6-compat && npm install -g pnpm@9.4.0
|
||||
|
||||
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||
ENV NEXT_PUBLIC_BASE_URL=$base_url
|
||||
RUN pnpm --filter=app build
|
||||
|
||||
# --------- runner -----------
|
||||
@ -46,6 +48,7 @@ FROM node:20.14.0-alpine AS runner
|
||||
WORKDIR /app
|
||||
|
||||
ARG proxy
|
||||
ARG base_url
|
||||
|
||||
# create user and use it
|
||||
RUN addgroup --system --gid 1001 nodejs
|
||||
@ -81,6 +84,7 @@ RUN chown -R nextjs:nodejs /app/data
|
||||
ENV NODE_ENV=production
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
ENV PORT=3000
|
||||
ENV NEXT_PUBLIC_BASE_URL=$base_url
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ const isDev = process.env.NODE_ENV === 'development';
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
basePath: process.env.NEXT_PUBLIC_BASE_URL,
|
||||
i18n,
|
||||
output: 'standalone',
|
||||
reactStrictMode: isDev ? false : true,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Image, Skeleton, ImageProps } from '@chakra-ui/react';
|
||||
import { Skeleton, ImageProps } from '@chakra-ui/react';
|
||||
import CustomImage from '@fastgpt/web/components/common/Image/MyImage';
|
||||
|
||||
export const MyImage = (props: ImageProps) => {
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
@ -13,7 +14,7 @@ export const MyImage = (props: ImageProps) => {
|
||||
justifyContent={'center'}
|
||||
my={1}
|
||||
>
|
||||
<Image
|
||||
<CustomImage
|
||||
display={'inline-block'}
|
||||
borderRadius={'md'}
|
||||
alt={''}
|
||||
|
||||
@ -13,6 +13,7 @@ import MySelect from '@fastgpt/web/components/common/MySelect';
|
||||
import { defaultTTSConfig } from '@fastgpt/global/core/app/constants';
|
||||
import ChatFunctionTip from './Tip';
|
||||
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
|
||||
import MyImage from '@fastgpt/web/components/common/Image/MyImage';
|
||||
|
||||
const TTSSelect = ({
|
||||
value = defaultTTSConfig,
|
||||
@ -133,7 +134,7 @@ const TTSSelect = ({
|
||||
<Flex mt={10} justifyContent={'end'}>
|
||||
{audioPlaying ? (
|
||||
<Flex>
|
||||
<Image src="/icon/speaking.gif" w={'24px'} alt={''} />
|
||||
<MyImage src="/icon/speaking.gif" w={'24px'} alt={''} />
|
||||
<Button
|
||||
ml={2}
|
||||
variant={'grayBase'}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useI18n } from '@/web/context/I18n';
|
||||
import { Box, Flex, Image } from '@chakra-ui/react';
|
||||
import { Box, Flex } from '@chakra-ui/react';
|
||||
import MyImage from '@fastgpt/web/components/common/Image/MyImage';
|
||||
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import React, { useRef } from 'react';
|
||||
@ -77,7 +77,7 @@ const ChatFunctionTip = ({ type }: { type: `${FnTypeEnum}` }) => {
|
||||
label={
|
||||
<Box pt={2}>
|
||||
<Flex alignItems={'flex-start'}>
|
||||
<Image src={data.icon} w={'36px'} alt={''} />
|
||||
<MyImage src={data.icon} w={'36px'} alt={''} />
|
||||
<Box ml={3}>
|
||||
<Box fontWeight="bold">{data.title}</Box>
|
||||
<Box fontSize={'xs'} color={'myGray.500'}>
|
||||
@ -85,7 +85,7 @@ const ChatFunctionTip = ({ type }: { type: `${FnTypeEnum}` }) => {
|
||||
</Box>
|
||||
</Box>
|
||||
</Flex>
|
||||
<Image src={data.imgUrl} w={'100%'} minH={['auto', '250px']} mt={2} alt={''} />
|
||||
<MyImage src={data.imgUrl} w={'100%'} minH={['auto', '250px']} mt={2} alt={''} />
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||
import { Flex, FlexProps, Image, css, useTheme } from '@chakra-ui/react';
|
||||
import { Flex, FlexProps, css, useTheme } from '@chakra-ui/react';
|
||||
import { ChatSiteItemType } from '@fastgpt/global/core/chat/type';
|
||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||
import React, { useMemo } from 'react';
|
||||
@ -9,6 +9,7 @@ import { formatChatValue2InputType } from '../utils';
|
||||
import { ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
|
||||
import { ChatBoxContext } from '../Provider';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import MyImage from '@fastgpt/web/components/common/Image/MyImage';
|
||||
|
||||
export type ChatControllerProps = {
|
||||
isLastChild: boolean;
|
||||
@ -124,7 +125,7 @@ const ChatController = ({
|
||||
onClick={cancelAudio}
|
||||
/>
|
||||
</MyTooltip>
|
||||
<Image
|
||||
<MyImage
|
||||
src="/icon/speaking.gif"
|
||||
w={'23px'}
|
||||
alt={''}
|
||||
|
||||
@ -6,6 +6,7 @@ import { useTranslation } from 'next-i18next';
|
||||
import type { SearchDataResponseItemType } from '@fastgpt/global/core/dataset/type';
|
||||
import QuoteItem from '@/components/core/dataset/QuoteItem';
|
||||
import RawSourceBox from '@/components/core/dataset/RawSourceBox';
|
||||
import { getWebReqUrl } from '@fastgpt/web/common/system/utils';
|
||||
|
||||
const QuoteModal = ({
|
||||
rawSearch = [],
|
||||
@ -42,13 +43,13 @@ const QuoteModal = ({
|
||||
h={['90vh', '80vh']}
|
||||
isCentered
|
||||
minW={['90vw', '600px']}
|
||||
iconSrc={!!metadata ? undefined : '/imgs/modal/quote.svg'}
|
||||
iconSrc={!!metadata ? undefined : getWebReqUrl('/imgs/modal/quote.svg')}
|
||||
title={
|
||||
<Box>
|
||||
{metadata ? (
|
||||
<RawSourceBox {...metadata} canView={showDetail} />
|
||||
) : (
|
||||
<>{t('core.chat.Quote Amount', { amount: rawSearch.length })}</>
|
||||
<>{t('common:core.chat.Quote Amount', { amount: rawSearch.length })}</>
|
||||
)}
|
||||
<Box fontSize={'xs'} color={'myGray.500'} fontWeight={'normal'}>
|
||||
{t('common:core.chat.quote.Quote Tip')}
|
||||
|
||||
@ -6,6 +6,7 @@ import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import { ChatFileTypeEnum } from '@fastgpt/global/core/chat/constants';
|
||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||
import MyImage from '@fastgpt/web/components/common/Image/MyImage';
|
||||
|
||||
const RenderFilePreview = ({
|
||||
fileList,
|
||||
@ -70,7 +71,7 @@ const RenderFilePreview = ({
|
||||
/>
|
||||
)}
|
||||
{isImage && (
|
||||
<Image
|
||||
<MyImage
|
||||
alt={'img'}
|
||||
src={item.icon}
|
||||
w={'full'}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { getCaptchaPic } from '@/web/support/user/api';
|
||||
import { Button, Input, Image, ModalBody, ModalFooter, Skeleton } from '@chakra-ui/react';
|
||||
import MyImage from '@fastgpt/web/components/common/Image/MyImage';
|
||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
@ -42,7 +43,7 @@ const SendCodeAuthModal = ({
|
||||
justifyContent={'center'}
|
||||
my={1}
|
||||
>
|
||||
<Image
|
||||
<MyImage
|
||||
borderRadius={'md'}
|
||||
w={'100%'}
|
||||
h={'200px'}
|
||||
|
||||
@ -13,6 +13,7 @@ import '@/web/styles/reset.scss';
|
||||
import NextHead from '@/components/common/NextHead';
|
||||
import { ReactElement, useEffect } from 'react';
|
||||
import { NextPage } from 'next';
|
||||
import { getWebReqUrl } from '@fastgpt/web/common/system/utils';
|
||||
|
||||
type NextPageWithLayout = NextPage & {
|
||||
setLayout?: (page: ReactElement) => JSX.Element;
|
||||
@ -49,7 +50,7 @@ function App({ Component, pageProps }: AppPropsWithLayout) {
|
||||
process.env.SYSTEM_DESCRIPTION ||
|
||||
`${title}${t('app:intro')}`
|
||||
}
|
||||
icon={feConfigs?.favicon || process.env.SYSTEM_FAVICON}
|
||||
icon={getWebReqUrl(feConfigs?.favicon || process.env.SYSTEM_FAVICON)}
|
||||
/>
|
||||
{scripts?.map((item, i) => <Script key={i} strategy="lazyOnload" {...item}></Script>)}
|
||||
|
||||
|
||||
@ -9,7 +9,6 @@ import {
|
||||
Link,
|
||||
Progress,
|
||||
Grid,
|
||||
Image,
|
||||
BoxProps
|
||||
} from '@chakra-ui/react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
@ -45,6 +44,7 @@ import StandardPlanContentList from '@/components/support/wallet/StandardPlanCon
|
||||
import { TeamMemberRoleEnum } from '@fastgpt/global/support/user/team/constant';
|
||||
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||
import MyImage from '@fastgpt/web/components/common/Image/MyImage';
|
||||
|
||||
const StandDetailModal = dynamic(() => import('./standardDetailModal'));
|
||||
const TeamMenu = dynamic(() => import('@/components/support/user/team/TeamMenu'));
|
||||
@ -653,7 +653,7 @@ const Other = ({ onOpenContact }: { onOpenContact: () => void }) => {
|
||||
onClick={onOpenLaf}
|
||||
fontSize={'sm'}
|
||||
>
|
||||
<Image src="/imgs/workflow/laf.png" w={'18px'} alt="laf" />
|
||||
<MyImage src="/imgs/workflow/laf.png" w={'18px'} alt="laf" />
|
||||
<Box ml={2} flex={1}>
|
||||
{'laf' + t('common:navbar.Account')}
|
||||
</Box>
|
||||
|
||||
@ -13,6 +13,7 @@ import { serviceSideProps } from '@/web/common/utils/i18n';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import Script from 'next/script';
|
||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||
import { getWebReqUrl } from '@fastgpt/web/common/system/utils';
|
||||
|
||||
const Promotion = dynamic(() => import('./components/Promotion'));
|
||||
const UsageTable = dynamic(() => import('./components/UsageTable'));
|
||||
@ -128,7 +129,7 @@ const Account = ({ currentTab }: { currentTab: TabEnum }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Script src="/js/qrcode.min.js" strategy="lazyOnload"></Script>
|
||||
<Script src={getWebReqUrl('/js/qrcode.min.js')} strategy="lazyOnload"></Script>
|
||||
<PageContainer>
|
||||
<Flex flexDirection={['column', 'row']} h={'100%'} pt={[4, 0]}>
|
||||
{isPc ? (
|
||||
|
||||
@ -2,7 +2,7 @@ import { OutLinkSchema } from '@fastgpt/global/support/outLink/type';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { Box, Flex, FlexProps, Grid, Image, ModalBody, Switch, useTheme } from '@chakra-ui/react';
|
||||
import { Box, Flex, FlexProps, Grid, ModalBody, Switch, useTheme } from '@chakra-ui/react';
|
||||
import MyRadio from '@/components/common/MyRadio';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
@ -10,6 +10,7 @@ import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||
import { useSelectFile } from '@/web/common/file/hooks/useSelectFile';
|
||||
import { fileToBase64 } from '@/web/common/file/utils';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import MyImage from '@fastgpt/web/components/common/Image/MyImage';
|
||||
|
||||
enum UsingWayEnum {
|
||||
link = 'link',
|
||||
@ -29,15 +30,15 @@ const SelectUsingWayModal = ({ share, onClose }: { share: OutLinkSchema; onClose
|
||||
|
||||
const VariableTypeList = [
|
||||
{
|
||||
title: <Image src={'/imgs/outlink/link.svg'} alt={''} />,
|
||||
title: <MyImage src={'/imgs/outlink/link.svg'} alt={''} />,
|
||||
value: UsingWayEnum.link
|
||||
},
|
||||
{
|
||||
title: <Image src={'/imgs/outlink/iframe.svg'} alt={''} />,
|
||||
title: <MyImage src={'/imgs/outlink/iframe.svg'} alt={''} />,
|
||||
value: UsingWayEnum.iframe
|
||||
},
|
||||
{
|
||||
title: <Image src={'/imgs/outlink/script.svg'} alt={''} />,
|
||||
title: <MyImage src={'/imgs/outlink/script.svg'} alt={''} />,
|
||||
value: UsingWayEnum.script
|
||||
}
|
||||
];
|
||||
@ -162,7 +163,7 @@ console.log("Chat box loaded")
|
||||
</Flex>
|
||||
<Flex {...gridItemStyle}>
|
||||
<Box flex={1}>{t('common:core.app.outLink.Script Open Icon')}</Box>
|
||||
<Image
|
||||
<MyImage
|
||||
src={getValues('scriptOpenIcon')}
|
||||
alt={''}
|
||||
w={'20px'}
|
||||
@ -173,7 +174,7 @@ console.log("Chat box loaded")
|
||||
</Flex>
|
||||
<Flex {...gridItemStyle}>
|
||||
<Box flex={1}>{t('common:core.app.outLink.Script Close Icon')}</Box>
|
||||
<Image
|
||||
<MyImage
|
||||
src={getValues('scriptCloseIcon')}
|
||||
alt={''}
|
||||
w={'20px'}
|
||||
|
||||
@ -3,6 +3,7 @@ import { Box, Image, Flex, ModalBody } from '@chakra-ui/react';
|
||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import MyImage from '@fastgpt/web/components/common/Image/MyImage';
|
||||
|
||||
export type ShowShareLinkModalProps = {
|
||||
shareLink: string;
|
||||
@ -40,7 +41,7 @@ function ShowShareLinkModal({ shareLink, onClose, img }: ShowShareLinkModalProps
|
||||
</Box>
|
||||
</Box>
|
||||
<Box mt="4" borderRadius="0.5rem" border="1px" borderStyle="solid" borderColor="myGray.200">
|
||||
<Image src={img} borderRadius="0.5rem" alt="" />
|
||||
<MyImage src={img} borderRadius="0.5rem" alt="" />
|
||||
</Box>
|
||||
</ModalBody>
|
||||
</MyModal>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { Box, Button, Card, Flex, FlexProps, Image } from '@chakra-ui/react';
|
||||
import { Box, Button, Card, Flex, FlexProps } from '@chakra-ui/react';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import type { FlowNodeItemType } from '@fastgpt/global/core/workflow/type/node.d';
|
||||
@ -15,7 +15,7 @@ import { ConnectionSourceHandle, ConnectionTargetHandle } from './Handle/Connect
|
||||
import { useDebug } from '../../hooks/useDebug';
|
||||
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
||||
import { getPreviewPluginNode } from '@/web/core/app/api/plugin';
|
||||
import { storeNode2FlowNode, getLatestNodeTemplate } from '@/web/core/workflow/utils';
|
||||
import { storeNode2FlowNode } from '@/web/core/workflow/utils';
|
||||
import { getNanoid } from '@fastgpt/global/common/string/tools';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { WorkflowContext } from '../../../context';
|
||||
@ -28,6 +28,7 @@ import { WholeResponseContent } from '@/components/core/chat/components/WholeRes
|
||||
import { getDocPath } from '@/web/common/system/doc';
|
||||
import { WorkflowActionContext } from '../../../context/workflowInitContext';
|
||||
import { WorkflowEventContext } from '../../../context/workflowEventContext';
|
||||
import MyImage from '@fastgpt/web/components/common/Image/MyImage';
|
||||
|
||||
type Props = FlowNodeItemType & {
|
||||
children?: React.ReactNode | React.ReactNode[] | string;
|
||||
@ -244,7 +245,7 @@ const NodeCard = (props: Props) => {
|
||||
{!!nodeTemplate?.diagram && !hasNewVersion && (
|
||||
<MyTooltip
|
||||
label={
|
||||
<Image
|
||||
<MyImage
|
||||
src={nodeTemplate?.diagram}
|
||||
w={'100%'}
|
||||
minH={['auto', '200px']}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import React, { Dispatch } from 'react';
|
||||
import { LoginPageTypeEnum } from '@/web/support/user/login/constants';
|
||||
import type { ResLogin } from '@/global/support/api/userRes';
|
||||
import { Box, Center, Image } from '@chakra-ui/react';
|
||||
import { Box, Center } from '@chakra-ui/react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { getWXLoginQR, getWXLoginResult } from '@/web/support/user/api';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
@ -9,6 +9,7 @@ import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import FormLayout from './components/FormLayout';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import Loading from '@fastgpt/web/components/common/MyLoading';
|
||||
import MyImage from '@fastgpt/web/components/common/Image/MyImage';
|
||||
|
||||
interface Props {
|
||||
loginSuccess: (e: ResLogin) => void;
|
||||
@ -44,7 +45,7 @@ const WechatForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
</Box>
|
||||
<Box p={5} display={'flex'} w={'full'} justifyContent={'center'}>
|
||||
{wechatInfo?.codeUrl ? (
|
||||
<Image w="200px" src={wechatInfo?.codeUrl} alt="qrcode"></Image>
|
||||
<MyImage w="200px" src={wechatInfo?.codeUrl} alt="qrcode"></MyImage>
|
||||
) : (
|
||||
<Center w={200} h={200} position={'relative'}>
|
||||
<Loading fixed={false} />
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { LoginPageTypeEnum } from '@/web/support/user/login/constants';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import { AbsoluteCenter, Box, Button, Flex, Image } from '@chakra-ui/react';
|
||||
import { AbsoluteCenter, Box, Button, Flex } from '@chakra-ui/react';
|
||||
import { LOGO_ICON } from '@fastgpt/global/common/system/constants';
|
||||
import { OAuthEnum } from '@fastgpt/global/support/user/constant';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
@ -10,6 +10,7 @@ import { Dispatch, useRef } from 'react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import I18nLngSelector from '@/components/Select/I18nLngSelector';
|
||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||
import MyImage from '@fastgpt/web/components/common/Image/MyImage';
|
||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 8);
|
||||
|
||||
interface Props {
|
||||
@ -86,7 +87,7 @@ const FormLayout = ({ children, setPageType, pageType }: Props) => {
|
||||
alignItems={'center'}
|
||||
justifyContent={'center'}
|
||||
>
|
||||
<Image src={LOGO_ICON} w={['22.5px', '36px']} alt={'icon'} />
|
||||
<MyImage src={LOGO_ICON} w={['22.5px', '36px']} alt={'icon'} />
|
||||
</Flex>
|
||||
<Box ml={[3, 5]} fontSize={['lg', 'xl']} fontWeight={'bold'} color={'myGray.900'}>
|
||||
{feConfigs?.systemTitle}
|
||||
@ -137,7 +138,7 @@ const FormLayout = ({ children, setPageType, pageType }: Props) => {
|
||||
w={'100%'}
|
||||
h={'40px'}
|
||||
borderRadius={'sm'}
|
||||
leftIcon={<Image alt="" src={feConfigs.sso.icon as any} w="20px" />}
|
||||
leftIcon={<MyImage alt="" src={feConfigs.sso.icon as any} w="20px" />}
|
||||
onClick={() => {
|
||||
feConfigs.sso?.url && router.replace(feConfigs.sso?.url, '_self');
|
||||
}}
|
||||
|
||||
@ -28,6 +28,7 @@ import I18nLngSelector from '@/components/Select/I18nLngSelector';
|
||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||
import { GET } from '@/web/common/api/request';
|
||||
import { getDocPath } from '@/web/common/system/doc';
|
||||
import { getWebReqUrl } from '@fastgpt/web/common/system/utils';
|
||||
|
||||
const RegisterForm = dynamic(() => import('./components/RegisterForm'));
|
||||
const ForgetPasswordForm = dynamic(() => import('./components/ForgetPasswordForm'));
|
||||
@ -136,7 +137,7 @@ const Login = ({ ChineseRedirectUrl }: { ChineseRedirectUrl: string }) => {
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
justifyContent={'center'}
|
||||
bg={`url('/icon/login-bg.svg') no-repeat`}
|
||||
bg={`url(${getWebReqUrl('/icon/login-bg.svg')}) no-repeat`}
|
||||
backgroundSize={'cover'}
|
||||
userSelect={'none'}
|
||||
h={'100%'}
|
||||
|
||||
@ -11,6 +11,7 @@ import {
|
||||
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';
|
||||
import { useSystemStore } from '../system/useSystemStore';
|
||||
import { formatTime2YMDHMW } from '@fastgpt/global/common/string/time';
|
||||
import { getWebReqUrl } from '@fastgpt/web/common/system/utils';
|
||||
|
||||
type StreamFetchProps = {
|
||||
url?: string;
|
||||
@ -136,7 +137,7 @@ export const streamFetch = ({
|
||||
};
|
||||
|
||||
// send request
|
||||
await fetchEventSource(url, {
|
||||
await fetchEventSource(getWebReqUrl(url), {
|
||||
...requestData,
|
||||
async onopen(res) {
|
||||
clearTimeout(timeoutId);
|
||||
|
||||
@ -8,6 +8,7 @@ import { clearToken } from '@/web/support/user/auth';
|
||||
import { TOKEN_ERROR_CODE } from '@fastgpt/global/common/error/errorCode';
|
||||
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';
|
||||
import { useSystemStore } from '../system/useSystemStore';
|
||||
import { getWebReqUrl } from '@fastgpt/web/common/system/utils';
|
||||
|
||||
interface ConfigType {
|
||||
headers?: { [key: string]: string };
|
||||
@ -114,7 +115,7 @@ function responseError(err: any) {
|
||||
!(window.location.pathname === '/chat/share' || window.location.pathname === '/chat/team')
|
||||
) {
|
||||
window.location.replace(
|
||||
`/login?lastRoute=${encodeURIComponent(location.pathname + location.search)}`
|
||||
getWebReqUrl(`/login?lastRoute=${encodeURIComponent(location.pathname + location.search)}`)
|
||||
);
|
||||
}
|
||||
|
||||
@ -160,7 +161,7 @@ function request(
|
||||
|
||||
return instance
|
||||
.request({
|
||||
baseURL: '/api',
|
||||
baseURL: getWebReqUrl('/api'),
|
||||
url,
|
||||
method,
|
||||
data: ['POST', 'PUT'].includes(method) ? data : null,
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { getWebReqUrl } from '@fastgpt/web/common/system/utils';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
export const getMd = async (url: string) => {
|
||||
const response = await fetch(`/docs/${url}`);
|
||||
const response = await fetch(getWebReqUrl(`/docs/${url}`));
|
||||
const textContent = await response.text();
|
||||
return textContent;
|
||||
};
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { getWebReqUrl } from '@fastgpt/web/common/system/utils';
|
||||
import { useSystemStore } from './useSystemStore';
|
||||
export const getDocPath = (path: string) => {
|
||||
const feConfigs = useSystemStore.getState().feConfigs;
|
||||
@ -5,5 +6,6 @@ export const getDocPath = (path: string) => {
|
||||
if (!feConfigs?.docUrl) return '';
|
||||
if (!path.startsWith('/')) return path;
|
||||
if (feConfigs.docUrl.endsWith('/')) return feConfigs.docUrl.slice(0, -1);
|
||||
return feConfigs.docUrl + path;
|
||||
|
||||
return getWebReqUrl(feConfigs.docUrl + path);
|
||||
};
|
||||
|
||||
@ -8,6 +8,7 @@ import { TTSTypeEnum } from '@/web/core/app/constants';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import type { OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat.d';
|
||||
import { useMount } from 'ahooks';
|
||||
import { getWebReqUrl } from '@fastgpt/web/common/system/utils';
|
||||
|
||||
const contentType = 'audio/mpeg';
|
||||
const splitMarker = 'SPLIT_MARKER';
|
||||
@ -45,7 +46,7 @@ export const useAudioPlay = (props?: OutLinkChatAuthProps & { ttsConfig?: AppTTS
|
||||
setAudioLoading(true);
|
||||
audioController.current = new AbortController();
|
||||
|
||||
const response = await fetch('/api/core/chat/item/getSpeech', {
|
||||
const response = await fetch(getWebReqUrl('/api/core/chat/item/getSpeech'), {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user