Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions packages/web/i18n/en/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -313,13 +313,6 @@
"plugin_cost_per_times": "{{cost}} points/time",
"plugin_offline_tips": "Your system does not have direct access to plugin market data,\n\nPlease manually copy the URL and go to get more plugins",
"plugin_offline_url": "URL",
"pro_modal_feature_1": "External organization structure integration and multi-tenancy",
"pro_modal_feature_2": "Team-exclusive application showcase page",
"pro_modal_feature_3": "Knowledge base enhanced indexing",
"pro_modal_later_button": "Maybe Later",
"pro_modal_subtitle": "Join the business edition now to unlock more premium features",
"pro_modal_title": "Business Edition Exclusive!",
"pro_modal_unlock_button": "Unlock Now",
"publish.chat_desc": "After logging into the portal, users can talk directly to the application",
"publish.playground_link": "Redirect Link",
"publish_channel": "Publish",
Expand Down
7 changes: 7 additions & 0 deletions packages/web/i18n/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,13 @@
"comfirn_create": "Confirm Creation",
"commercial_function_tip": "Please Upgrade to the Commercial Version to Use This Feature: https://doc.fastgpt.cn/guide/version/commercial",
"community_support": "community support",
"pro_modal_feature_1": "External organization structure integration and multi-tenancy",
"pro_modal_feature_2": "Team-exclusive application showcase page",
"pro_modal_feature_3": "Knowledge base enhanced indexing",
"pro_modal_later_button": "Maybe Later",
"pro_modal_subtitle": "Join the business edition now to unlock more premium features",
"pro_modal_title": "Business Edition Exclusive",
"pro_modal_unlock_button": "Unlock Now",
"compliance.chat": "The content is generated by third-party AI and cannot be guaranteed to be true and accurate. It is for reference only.",
"compliance.dataset": "Please ensure that your content strictly complies with relevant laws and regulations and avoid containing any illegal or infringing content. \nPlease be careful when uploading materials that may contain sensitive information.",
"confirm_choice": "Confirm Choice",
Expand Down
7 changes: 0 additions & 7 deletions packages/web/i18n/zh-CN/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -313,13 +313,6 @@
"plugin_cost_per_times": "{{cost}} 积分/次",
"plugin_offline_tips": "您的系统无法直接访问插件市场数据,\n请手动复制网址并前往,以获得更多插件",
"plugin_offline_url": "网址",
"pro_modal_feature_1": "外部组织架构接入与多租户",
"pro_modal_feature_2": "团队专属的应用展示页",
"pro_modal_feature_3": "知识库增强索引",
"pro_modal_later_button": "我再想想",
"pro_modal_subtitle": "即刻加入商业版,解锁更多高级功能",
"pro_modal_title": "商业版专享!",
"pro_modal_unlock_button": "去解锁",
"publish.chat_desc": "用户登录门户后可直接与应用对话",
"publish.playground_link": "跳转链接",
"publish_channel": "发布渠道",
Expand Down
7 changes: 7 additions & 0 deletions packages/web/i18n/zh-CN/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,13 @@
"comfirn_create": "确认创建",
"commercial_function_tip": "请升级商业版后使用该功能:https://doc.fastgpt.cn/guide/version/commercial",
"community_support": "社区支持",
"pro_modal_feature_1": "外部组织架构接入与多租户",
"pro_modal_feature_2": "团队专属的应用展示页",
"pro_modal_feature_3": "知识库增强索引",
"pro_modal_later_button": "我再想想",
"pro_modal_subtitle": "即刻加入商业版,解锁更多高级功能",
"pro_modal_title": "商业版专享",
"pro_modal_unlock_button": "去解锁",
"compliance.chat": "内容由第三方 AI 生成,无法确保真实准确,仅供参考",
"compliance.dataset": "请确保您的内容严格遵守相关法律法规,避免包含任何违法或侵权的内容。请谨慎上传可能涉及敏感信息的资料。",
"confirm_choice": "确认选择",
Expand Down
7 changes: 0 additions & 7 deletions packages/web/i18n/zh-Hant/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -305,13 +305,6 @@
"plugin_cost_per_times": "{{cost}} 積分/次",
"plugin_offline_tips": "您的系統無法直接訪問插件市場數據,\n請手動複製網址並前往,以獲得更多插件",
"plugin_offline_url": "網址",
"pro_modal_feature_1": "外部組織架構接入與多租戶",
"pro_modal_feature_2": "團隊專屬的應用展示頁",
"pro_modal_feature_3": "知識庫增強索引",
"pro_modal_later_button": "我再想想",
"pro_modal_subtitle": "即刻加入商業版,解鎖更多高級功能",
"pro_modal_title": "商業版專享!",
"pro_modal_unlock_button": "去解鎖",
"publish.chat_desc": "用戶登錄門戶後可直接與應用對話",
"publish.playground_link": "跳轉鏈接",
"publish_channel": "發布通道",
Expand Down
7 changes: 7 additions & 0 deletions packages/web/i18n/zh-Hant/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,13 @@
"comfirn_create": "確認建立",
"commercial_function_tip": "請升級為商業版後使用此功能:https://doc.fastgpt.cn/guide/version/commercial",
"community_support": "社區支持",
"pro_modal_feature_1": "外部組織架構接入與多租戶",
"pro_modal_feature_2": "團隊專屬的應用展示頁",
"pro_modal_feature_3": "知識庫增強索引",
"pro_modal_later_button": "我再想想",
"pro_modal_subtitle": "即刻加入商業版,解鎖更多高級功能",
"pro_modal_title": "商業版專享",
"pro_modal_unlock_button": "去解鎖",
"compliance.chat": "內容由第三方 AI 產生,無法保證其真實性與準確性,僅供參考。",
"compliance.dataset": "請確保您的內容嚴格遵守相關法律法規,避免包含任何違法或侵權的內容。\n在上傳可能涉及敏感資訊的資料時請務必謹慎。",
"confirm_choice": "確認選擇",
Expand Down
2 changes: 1 addition & 1 deletion pro
Submodule pro updated from 8c7626 to 336c7c
90 changes: 45 additions & 45 deletions projects/app/src/components/ProTip/ProModal.tsx

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

确认下,UI 是否需要变更,要跟设计对效果

Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ const ProModal = (props: { isOpen?: boolean; onClose?: () => void }) => {
>
<ModalBody
userSelect={'none'}
py={8}
pt={0}
pb={8}
px={6}
position={'relative'}
overflow={'hidden'}
_before={{
content: '""',
position: 'absolute',
Expand All @@ -34,68 +38,64 @@ const ProModal = (props: { isOpen?: boolean; onClose?: () => void }) => {
w: '100%',
h: '100%',
bgImage: 'url(/imgs/proModalBg.png)',
bgSize: 'cover',
bgPosition: 'center',
bgSize: '100% auto',
bgPosition: 'top center',
bgRepeat: 'no-repeat',
opacity: 0.48,
opacity: 0.32,
zIndex: -10
}}
display={'flex'}
justifyContent={'center'}
>
<VStack gap={4} w={'300px'} px={1}>
<MyIcon name={'star'} w={8} />
<Box
color={'myGray.900'}
fontSize="20px"
fontWeight={'medium'}
lineHeight="26px"
letterSpacing="0.15px"
>
{t('app:pro_modal_title')}
</Box>
<Box
color={'myGray.900'}
fontSize="18px"
fontWeight={'medium'}
lineHeight="26px"
letterSpacing="0.15px"
>
{t('app:pro_modal_subtitle')}
<VStack w={'full'} alignItems={'center'} textAlign={'center'} gap={0}>
<Flex h={'112px'} alignItems={'center'} justifyContent={'center'}>
<MyIcon name={'star'} w={9} h={9} transform={'translateY(40%)'} />
</Flex>
<Box color={'myGray.900'} fontSize={'26px'} fontWeight={'bold'} lineHeight={'34px'}>
{t('common:pro_modal_title')}
</Box>
<Flex
flexDirection={'column'}
gap={'10px'}
<VStack
w={'full'}
color={'myGray.900'}
fontSize={'14px'}
fontSize={'18px'}
alignItems={'center'}
gap={0}
mt={7}
>
<Box>{t('app:pro_modal_feature_1')}</Box>
<Box>{t('app:pro_modal_feature_2')}</Box>
<Box>{t('app:pro_modal_feature_3')}</Box>
<Box>
<MyIcon name={'common/ellipsis'} w={'18px'} />
<Box lineHeight={'26px'}>{t('common:pro_modal_subtitle')}</Box>
<Box lineHeight={'26px'}>{t('common:pro_modal_feature_1')}</Box>
<Box lineHeight={'26px'}>{t('common:pro_modal_feature_2')}</Box>
<Box lineHeight={'26px'}>{t('common:pro_modal_feature_3')}</Box>
<Box color={'myGray.500'} letterSpacing={'2px'} lineHeight={'26px'}>
......
</Box>
</Flex>
<Flex gap={'3'} flexDirection={'column'} w={'full'}>
</VStack>
<Flex gap={3} flexDirection={'column'} w={'full'} mt={6}>
<Button
w={'full'}
h={'48px'}
borderRadius={'10px'}
onClick={() => {
window.open(getDocPath('/guide/version/commercial'), '_blank');
}}
fontSize={'14px'}
fontSize={'16px'}
fontWeight={'medium'}
>
{t('app:pro_modal_unlock_button')}
{t('common:pro_modal_unlock_button')}
</Button>
<Button
w={'full'}
h={'48px'}
borderRadius={'10px'}
variant={'whiteBase'}
fontSize={'16px'}
fontWeight={'medium'}
borderColor={'#E4E7ED'}
boxShadow={'0 2px 5px rgba(15, 23, 42, 0.06)'}
onClick={onClose}
>
{t('common:pro_modal_later_button')}
</Button>
</Flex>
<Flex
rounded={'md'}
fontSize={'12px'}
color={'myGray.600'}
cursor={'pointer'}
onClick={onClose}
>
{t('app:pro_modal_later_button')}
</Flex>
</VStack>
</ModalBody>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
import type { CreateDatasetType } from './CreateModal';

/** Web 站点与第三方知识库仅商业版可创建;社区版在新建入口点击后弹出 ProModal。 */
export const commercialDatasetTypes: readonly CreateDatasetType[] = [
DatasetTypeEnum.websiteDataset,
DatasetTypeEnum.apiDataset,
DatasetTypeEnum.feishu,
DatasetTypeEnum.yuque,
DatasetTypeEnum.dingtalk
];

/** 判断是否为商业版专属知识库类型。 */
export const isCommercialDatasetType = (type: CreateDatasetType) =>
commercialDatasetTypes.includes(type);

export type DatasetCreateAction = 'create' | 'proModal';

/**
* 根据商业版状态与知识库类型,决定新建入口的下一步动作。
* 社区版点击 Web/第三方类型时返回 proModal,其余情况进入创建弹窗。
*/
export const resolveDatasetCreateAction = (
type: CreateDatasetType,
isPlus?: boolean
): DatasetCreateAction => {
if (!isPlus && isCommercialDatasetType(type)) {
return 'proModal';
}
return 'create';
};
26 changes: 14 additions & 12 deletions projects/app/src/pages/dataset/list/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import {
} from '@/web/core/dataset/api/collaborator';
import { useSystem } from '@fastgpt/web/hooks/useSystem';
import { type CreateDatasetType } from '@/pageComponents/dataset/list/CreateModal';
import { resolveDatasetCreateAction } from '@/pageComponents/dataset/list/commercialDatasetTypes';
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
import { useToast } from '@fastgpt/web/hooks/useToast';
import MyBox from '@fastgpt/web/components/common/MyBox';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import {
Expand All @@ -36,6 +36,7 @@ import {
normalizeParentId
} from '@fastgpt/global/common/parentFolder/depth';
import { ReadRoleVal } from '@fastgpt/global/support/permission/constant';
import ProModal from '@/components/ProTip/ProModal';

const EditFolderModal = dynamic(
() => import('@fastgpt/web/components/common/MyModal/EditFolderModal')
Expand Down Expand Up @@ -67,22 +68,20 @@ const Dataset = () => {
const { feConfigs } = useSystemStore();
const maxFolderDepth = feConfigs?.limit?.maxFolderDepth ?? DEFAULT_MAX_FOLDER_DEPTH;
const canCreateFolder = canCreateSubFolder(parentId, paths, maxFolderDepth);
const folderDepthLimitTip = t('common:folder_depth_limit_tip');
const { toast } = useToast();

const [editFolderData, setEditFolderData] = useState<EditFolderFormType>();
const [createDatasetType, setCreateDatasetType] = useState<CreateDatasetType>();
const [proModalOpen, setProModalOpen] = useState(false);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

proModal 有全局的么,还是得每个地方单独挂载


const onSelectDatasetType = useCallback(
(e: CreateDatasetType) => {
if (!feConfigs?.isPlus && [DatasetTypeEnum.websiteDataset].includes(e)) {
return toast({
status: 'warning',
title: t('common:commercial_function_tip')
});
(type: CreateDatasetType) => {
if (resolveDatasetCreateAction(type, feConfigs?.isPlus) === 'proModal') {
setProModalOpen(true);
return;
}
setCreateDatasetType(e);
setCreateDatasetType(type);
},
[t, toast, feConfigs]
[feConfigs?.isPlus]
);

const RenderSearchInput = useMemo(
Expand Down Expand Up @@ -227,7 +226,7 @@ const Dataset = () => {
icon: FolderIcon,
label: t('common:Folder'),
disabled: !canCreateFolder,
disabledTip: folderDepthLimitTip,
disabledTip: t('common:folder_depth_limit_tip'),
onClick: () => setEditFolderData({})
}
]
Expand Down Expand Up @@ -333,6 +332,9 @@ const Dataset = () => {
parentId={parentId || undefined}
/>
)}
{!feConfigs?.isPlus && (
<ProModal isOpen={proModalOpen} onClose={() => setProModalOpen(false)} />
)}
</MyBox>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { describe, expect, it } from 'vitest';
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
import {
commercialDatasetTypes,
isCommercialDatasetType,
resolveDatasetCreateAction
} from '@/pageComponents/dataset/list/commercialDatasetTypes';
import type { CreateDatasetType } from '@/pageComponents/dataset/list/CreateModal';

const expectedCommercialTypes: CreateDatasetType[] = [
DatasetTypeEnum.websiteDataset,
DatasetTypeEnum.apiDataset,
DatasetTypeEnum.feishu,
DatasetTypeEnum.yuque,
DatasetTypeEnum.dingtalk
];

describe('commercialDatasetTypes', () => {
it('should include all commercial-only dataset create types', () => {
expect([...commercialDatasetTypes]).toEqual(expectedCommercialTypes);
});
});

describe('isCommercialDatasetType', () => {
it.each(expectedCommercialTypes)('should mark %s as commercial-only', (type) => {
expect(isCommercialDatasetType(type)).toBe(true);
});

it('should not mark normal dataset as commercial-only', () => {
expect(isCommercialDatasetType(DatasetTypeEnum.dataset)).toBe(false);
});
});

describe('resolveDatasetCreateAction', () => {
it.each(expectedCommercialTypes)(
'should open ProModal for %s when team is not commercial edition',
(type) => {
expect(resolveDatasetCreateAction(type, false)).toBe('proModal');
}
);

it.each(expectedCommercialTypes)(
'should treat missing commercial edition flag as community edition for %s',
(type) => {
expect(resolveDatasetCreateAction(type, undefined)).toBe('proModal');
}
);

it.each(expectedCommercialTypes)(
'should allow creating %s when team is commercial edition',
(type) => {
expect(resolveDatasetCreateAction(type, true)).toBe('create');
}
);

it('should always allow creating normal dataset', () => {
expect(resolveDatasetCreateAction(DatasetTypeEnum.dataset, false)).toBe('create');
expect(resolveDatasetCreateAction(DatasetTypeEnum.dataset, true)).toBe('create');
expect(resolveDatasetCreateAction(DatasetTypeEnum.dataset, undefined)).toBe('create');
});
});