free plan workorder entrance (#6085)

This commit is contained in:
heheer 2025-12-12 16:08:20 +08:00 committed by GitHub
parent b22ba1aa53
commit 8ad9e15571
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 56 additions and 28 deletions

View File

@ -14,6 +14,7 @@ export enum TeamErrEnum {
appFolderAmountNotEnough = 'appFolderAmountNotEnough',
websiteSyncNotEnough = 'websiteSyncNotEnough',
reRankNotEnough = 'reRankNotEnough',
ticketNotAvailable = 'ticketNotAvailable',
groupNameEmpty = 'groupNameEmpty',
groupNameDuplicate = 'groupNameDuplicate',
groupNotExist = 'groupNotExist',
@ -78,6 +79,10 @@ const teamErr = [
statusText: TeamErrEnum.reRankNotEnough,
message: i18nT('common:code_error.team_error.re_rank_not_enough')
},
{
statusText: TeamErrEnum.ticketNotAvailable,
message: i18nT('common:code_error.team_error.ticket_not_available')
},
{
statusText: TeamErrEnum.groupNameEmpty,
message: i18nT('common:code_error.team_error.group_name_empty')

View File

@ -43,6 +43,7 @@ export type SubPlanType = {
[SubTypeEnum.standard]?: StandSubPlanLevelMapType;
planDescriptionUrl?: string;
appRegistrationUrl?: string;
communitySupportTip?: string;
[SubTypeEnum.extraDatasetSize]: {
price: number;
};

View File

@ -195,6 +195,7 @@
"code_error.team_error.over_size": "Team members exceed limit",
"code_error.team_error.plugin_amount_not_enough": "Plugin Limit Reached",
"code_error.team_error.re_rank_not_enough": "Search rearrangement cannot be used in the free version~",
"code_error.team_error.ticket_not_available": "The current package does not support work order services. You can go to the community to get help for free ~",
"code_error.team_error.too_many_invitations": "You have reached the maximum number of active invitation links, please clean up some links first",
"code_error.team_error.un_auth": "Unauthorized to Operate This Team",
"code_error.team_error.user_not_active": "The user did not accept or has left the team",
@ -1224,6 +1225,9 @@
"support.wallet.subscription.function.Max members": "{{amount}} Member",
"support.wallet.subscription.function.Points": "{{amount}} points",
"support.wallet.subscription.function.Requests per minute": "{{amount}} QPM",
"support.wallet.subscription.function.Ticket response time": "{{amount}} hours ticket support response",
"support.wallet.subscription.function.Community free support": "Community free support",
"support.wallet.subscription.function.Community support tip": "Visit the FastGPT community for free help and technical support",
"support.wallet.subscription.function.Website sync per dataset": "Single knowledge base {{amount}} web pages synchronized",
"support.wallet.subscription.function.custom domain tip": "The number of custom domain names that the team can configure, which can currently be used to access Wecom intelligent robots",
"support.wallet.subscription.mode.Month": "Month",

View File

@ -196,6 +196,7 @@
"code_error.team_error.over_size": "团队成员超出限制",
"code_error.team_error.plugin_amount_not_enough": "插件数量已达上限~",
"code_error.team_error.re_rank_not_enough": "免费版无法使用检索重排~",
"code_error.team_error.ticket_not_available": "当前套餐暂不支持工单服务,可以前往社区免费获取帮助~",
"code_error.team_error.too_many_invitations": "您的有效邀请链接数已达上限,请先清理链接",
"code_error.team_error.un_auth": "无权操作该团队",
"code_error.team_error.user_not_active": "用户未接受或已离开团队",
@ -1234,6 +1235,8 @@
"support.wallet.subscription.function.Points": "{{amount}} 积分",
"support.wallet.subscription.function.Requests per minute": "{{amount}} QPM",
"support.wallet.subscription.function.Ticket response time": "{{amount}} 小时工单支持响应",
"support.wallet.subscription.function.Community free support": "社区免费支持",
"support.wallet.subscription.function.Community support tip": "可前往 FastGPT 社区免费获取帮助和技术支持",
"support.wallet.subscription.function.Website sync per dataset": "站点同步最大 {{amount}} 页",
"support.wallet.subscription.function.custom domain tip": "团队可以配置的自定义域名数量,目前可用于接入企微智能机器人",
"support.wallet.subscription.function.qpm tip": "主要指团队每分钟请求 Agent 的最大次数,与单个 Agent 复杂度无关。其他 OpenAPI 接口也受此影响,每个接口单独计算",

View File

@ -195,6 +195,7 @@
"code_error.team_error.over_size": "團隊成員超出限制",
"code_error.team_error.plugin_amount_not_enough": "已達外掛程式數量上限",
"code_error.team_error.re_rank_not_enough": "免費版無法使用檢索重排~",
"code_error.team_error.ticket_not_available": "當前套餐暫不支持工單服務,可以前往社區免費獲取幫助~",
"code_error.team_error.too_many_invitations": "您的有效邀請連結數已達上限,請先清理連結",
"code_error.team_error.un_auth": "無權操作此團隊",
"code_error.team_error.user_not_active": "使用者未接受或已離開團隊",
@ -1221,6 +1222,9 @@
"support.wallet.subscription.function.Max members": "{{amount}} 個團隊成員",
"support.wallet.subscription.function.Points": "{{amount}} 積分",
"support.wallet.subscription.function.Requests per minute": "{{amount}} QPM",
"support.wallet.subscription.function.Ticket response time": "{{amount}} 小時工單支持響應",
"support.wallet.subscription.function.Community free support": "社群免費支持",
"support.wallet.subscription.function.Community support tip": "可前往 FastGPT 社群免費獲取幫助和技術支持",
"support.wallet.subscription.function.Website sync per dataset": "單知識庫 {{amount}} 個網頁同步",
"support.wallet.subscription.function.custom domain tip": "團隊可以配置的自定義域名數量,目前可用於接入企微智能機器人",
"support.wallet.subscription.mode.Month": "按月",

View File

@ -6,9 +6,9 @@ import { useRouter } from 'next/router';
import { useState, useEffect, useMemo } from 'react';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import { useUserStore } from '@/web/support/user/useUserStore';
import { StandardSubLevelEnum } from '@fastgpt/global/support/wallet/sub/constants';
import { useTranslation } from 'next-i18next';
import { getWorkorderURL } from '@/web/common/workorder/api';
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';
const BotShowRouter: { [key: string]: boolean } = {
'/dashboard/agent': true,
@ -28,21 +28,14 @@ const HelperBot = () => {
const [showChat, setShowChat] = useToggle(false);
const [isLoading, setIsLoading] = useState(true);
const { feConfigs, subPlans } = useSystemStore();
const { feConfigs, setNotSufficientModalType } = useSystemStore();
const { teamPlanStatus } = useUserStore();
const isPlanUser = useMemo(() => {
if (!teamPlanStatus) return false;
if (teamPlanStatus.standard?.currentSubLevel !== StandardSubLevelEnum.free) return true;
if (teamPlanStatus.datasetMaxSize !== subPlans?.standard?.free?.maxDatasetSize) return true;
if (teamPlanStatus.totalPoints !== subPlans?.standard?.free?.totalPoints) return true;
return false;
}, [
subPlans?.standard?.free?.maxDatasetSize,
subPlans?.standard?.free?.totalPoints,
teamPlanStatus
]);
const showWorkorder = feConfigs?.show_workorder && isPlanUser;
const hasTicketAccess = useMemo(() => {
const ticketResponseTime = teamPlanStatus?.standard?.ticketResponseTime;
return ticketResponseTime !== undefined && ticketResponseTime > 0;
}, [teamPlanStatus?.standard?.ticketResponseTime]);
const botIframeUrl = feConfigs?.botIframeUrl;
useEffect(() => {
@ -54,6 +47,11 @@ const HelperBot = () => {
useEffect(() => {
const handleMessage = async (event: MessageEvent) => {
if (event.data?.type === 'workorderRequest') {
if (!hasTicketAccess) {
setNotSufficientModalType(TeamErrEnum.ticketNotAvailable);
return;
}
try {
const data = await getWorkorderURL();
if (data?.redirectUrl) {
@ -67,7 +65,7 @@ const HelperBot = () => {
window.addEventListener('message', handleMessage);
return () => window.removeEventListener('message', handleMessage);
}, []);
}, [hasTicketAccess, setNotSufficientModalType]);
if (!botIframeUrl || !BotShowRouter[router.pathname]) {
return null;
@ -122,7 +120,7 @@ const HelperBot = () => {
{/* iframe */}
<Box
as="iframe"
src={`${botIframeUrl}&showWorkorder=${showWorkorder ? '1' : '0'}`}
src={`${botIframeUrl}&showWorkorder=1`}
w={'100%'}
h={'100%'}
border={'none'}

View File

@ -33,7 +33,8 @@ const NotSufficientModal = () => {
[TeamErrEnum.appAmountNotEnough]: t('common:support.wallet.App_amount_not_sufficient'),
[TeamErrEnum.pluginAmountNotEnough]: t('common:support.wallet.App_amount_not_sufficient'),
[TeamErrEnum.websiteSyncNotEnough]: t('common:code_error.team_error.website_sync_not_enough'),
[TeamErrEnum.reRankNotEnough]: t('common:code_error.team_error.re_rank_not_enough')
[TeamErrEnum.reRankNotEnough]: t('common:code_error.team_error.re_rank_not_enough'),
[TeamErrEnum.ticketNotAvailable]: t('common:code_error.team_error.ticket_not_available')
};
return type ? (

View File

@ -9,6 +9,7 @@ import { useTranslation } from 'next-i18next';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import dynamic from 'next/dynamic';
import type { TeamSubSchema } from '@fastgpt/global/support/wallet/sub/type';
import Markdown from '@/components/Markdown';
const ModelPriceModal = dynamic(() =>
import('@/components/core/ai/ModelTable').then((mod) => mod.ModelPriceModal)
@ -157,16 +158,26 @@ const StandardPlanContentList = ({
</Box>
</Flex>
)}
{!!planContent.ticketResponseTime && (
<Flex alignItems={'center'}>
<MyIcon name={'price/right'} w={'16px'} mr={3} />
<Box color={'myGray.600'}>
{t('common:support.wallet.subscription.function.Ticket response time', {
amount: planContent.ticketResponseTime
})}
</Box>
</Flex>
)}
<Flex alignItems={'center'}>
<MyIcon name={'price/right'} w={'16px'} mr={3} />
<Box color={'myGray.600'}>
{planContent.ticketResponseTime
? t('common:support.wallet.subscription.function.Ticket response time', {
amount: planContent.ticketResponseTime
})
: t('common:support.wallet.subscription.function.Community free support')}
</Box>
{!planContent.ticketResponseTime && subPlans?.communitySupportTip && (
<QuestionTip
ml={1}
label={
<Box maxW="300px">
<Markdown source={subPlans.communitySupportTip} />
</Box>
}
/>
)}
</Flex>
{!!planContent.appRegistrationCount && (
<Flex alignItems={'center'}>
<MyIcon name={'price/right'} w={'16px'} mr={3} />

View File

@ -29,7 +29,8 @@ export type NotSufficientModalType =
| TeamErrEnum.aiPointsNotEnough
| TeamErrEnum.datasetAmountNotEnough
| TeamErrEnum.teamMemberOverSize
| TeamErrEnum.appAmountNotEnough;
| TeamErrEnum.appAmountNotEnough
| TeamErrEnum.ticketNotAvailable;
type State = {
initd: boolean;