diff --git a/document/content/self-host/config/env.en.mdx b/document/content/self-host/config/env.en.mdx index 919ddc3a017b..fb72df5bff41 100644 --- a/document/content/self-host/config/env.en.mdx +++ b/document/content/self-host/config/env.en.mdx @@ -338,7 +338,6 @@ These variables are mainly read by `pro/admin`. Admin also uses the shared App/A | `BING_OAUTH_CLIENT_SECRET` | Empty | Bing OAuth client secret. | | `BING_OAUTH_REFRESH_TOKEN` | Empty | Bing OAuth refresh token. | | `SHOW_WECOM_CONFIG` | `false` | Whether WeCom configuration is shown. | -| `WECOM_DEV` | `false` | Development mode switch for WeCom Pay. | ## Code Sandbox Variables diff --git a/document/content/self-host/config/env.mdx b/document/content/self-host/config/env.mdx index d1a7d9d051ab..43a1afb6eb33 100644 --- a/document/content/self-host/config/env.mdx +++ b/document/content/self-host/config/env.mdx @@ -338,7 +338,6 @@ DOC2X_KEY=your-api-key | `BING_OAUTH_CLIENT_SECRET` | 空 | Bing OAuth Client Secret。 | | `BING_OAUTH_REFRESH_TOKEN` | 空 | Bing OAuth Refresh Token。 | | `SHOW_WECOM_CONFIG` | `false` | 是否展示企业微信相关配置。 | -| `WECOM_DEV` | `false` | 企业微信支付相关开发模式开关。 | ## Code Sandbox 变量 diff --git a/packages/global/support/user/type.ts b/packages/global/support/user/type.ts index cb42c9798f2a..857eee4f9894 100644 --- a/packages/global/support/user/type.ts +++ b/packages/global/support/user/type.ts @@ -11,9 +11,7 @@ export const UserTagsSchema = z.enum(['wecom']); export const UserTagsEnum = UserTagsSchema.enum; export type UserTagsType = z.infer; -export type UserMetaType = { - isActivatedWecomLicense?: boolean; -}; +export type UserMetaType = Record; export type UserModelSchema = { _id: string; @@ -58,8 +56,7 @@ export const TeamMetaSchema = z.object({ wecom: z .object({ permanentCode: z.string(), - corpId: z.string(), - licenseCapacity: z.int().min(0).default(0) + corpId: z.string() }) .optional() }); diff --git a/packages/global/support/wallet/sub/type.ts b/packages/global/support/wallet/sub/type.ts index 924ca04cd299..f6ee479c7247 100644 --- a/packages/global/support/wallet/sub/type.ts +++ b/packages/global/support/wallet/sub/type.ts @@ -38,14 +38,6 @@ export const TeamStandardSubPlanItemSchema = z.object({ // Active annualBonusPoints: z.int().optional(), // 年度赠送积分 - /** 企微设置 */ - wecom: z - .object({ - price: z.number().describe('企微价格'), - points: z.number().describe('企微积分') - }) - .nullish(), - /** @deprecated */ pointPrice: z.number().optional() }); @@ -103,13 +95,7 @@ const TeamStandardSubPlanItemInputSchema = TeamStandardSubPlanItemSchema.extend( maxUploadFileSize: configOptionalIntegerInputSchema, maxUploadFileCount: configOptionalIntegerInputSchema, annualBonusPoints: configOptionalIntegerInputSchema, - pointPrice: configOptionalNumberInputSchema, - wecom: z - .object({ - price: NumSchema.nonnegative(), - points: NumSchema.nonnegative() - }) - .nullish() + pointPrice: configOptionalNumberInputSchema }); const CustomStandardSubPlanItemInputSchema = z.preprocess((value) => { diff --git a/packages/service/support/user/team/teamMemberSchema.ts b/packages/service/support/user/team/teamMemberSchema.ts index 74a974dd74e4..3fccf1095eca 100644 --- a/packages/service/support/user/team/teamMemberSchema.ts +++ b/packages/service/support/user/team/teamMemberSchema.ts @@ -80,6 +80,15 @@ defineIndex(TeamMemberSchema, { key: { userId: 1, teamId: 1 }, options: { unique: true, background: true } }); +defineIndex(TeamMemberSchema, { + key: { teamId: 1, wecomUserId: 1 }, + options: { + unique: true, + partialFilterExpression: { wecomUserId: { $exists: true } }, + background: true + }, + deprecated: true +}); export const MongoTeamMember = getMongoModel( TeamMemberCollectionName, diff --git a/packages/service/support/wallet/sub/utils.ts b/packages/service/support/wallet/sub/utils.ts index 3870266d5b59..6dcc1cf86499 100644 --- a/packages/service/support/wallet/sub/utils.ts +++ b/packages/service/support/wallet/sub/utils.ts @@ -13,7 +13,7 @@ import type { } from '@fastgpt/global/support/wallet/sub/type'; import dayjs from 'dayjs'; import { type ClientSession } from '../../../common/mongo'; -import { addMonths, addDays } from 'date-fns'; +import { addMonths } from 'date-fns'; import { readFromSecondary } from '../../../common/mongo/utils'; import { TeamPointCache, teamQpmCache } from '@fastgpt/dal/redis/caches'; import { getLogger, LogCategories } from '../../../common/logger'; @@ -65,7 +65,6 @@ export const buildStandardPlan = ( priceDescription: standardConstants.priceDescription, customFormUrl: standardConstants.customFormUrl, customDescriptions: standardConstants.customDescriptions, - wecom: standardConstants.wecom, maxTeamMember: standard?.maxTeamMember ?? standardConstants.maxTeamMember, maxAppAmount: standard?.maxApp ?? standardConstants.maxAppAmount, maxDatasetAmount: standard?.maxDataset ?? standardConstants.maxDatasetAmount, @@ -85,16 +84,12 @@ export const buildStandardPlan = ( export const initTeamFreePlan = async ({ teamId, - isWecomTeam = false, session }: { teamId: string; - isWecomTeam?: boolean; session?: ClientSession; }) => { - const freePoints = isWecomTeam - ? Math.round((global.subPlans?.standard?.basic?.totalPoints ?? 4000) / 2) - : global?.subPlans?.standard?.[StandardSubLevelEnum.free]?.totalPoints || 100; + const freePoints = global?.subPlans?.standard?.[StandardSubLevelEnum.free]?.totalPoints || 100; const freePlan = await MongoTeamSub.findOne({ teamId, @@ -102,27 +97,6 @@ export const initTeamFreePlan = async ({ currentSubLevel: StandardSubLevelEnum.free }); - // Get basic plan config for wecom mode - const specialConfig: Record | null = (() => { - const config = global?.subPlans?.standard?.[StandardSubLevelEnum.basic]; - if (isWecomTeam && config) { - return { - maxTeamMember: config.maxTeamMember, - maxApp: config.maxAppAmount, - maxDataset: config.maxDatasetAmount, - requestsPerMinute: config.requestsPerMinute, - chatHistoryStoreDuration: config.chatHistoryStoreDuration, - maxDatasetSize: config.maxDatasetSize, - websiteSyncPerDataset: config.websiteSyncPerDataset, - appRegistrationCount: config.appRegistrationCount, - auditLogStoreDuration: config.auditLogStoreDuration, - ticketResponseTime: config.ticketResponseTime, - customDomain: config.customDomain - } as TeamSubSchemaType; - } - return null; - })(); - // Reset one month free plan if (freePlan) { freePlan.currentMode = SubModeEnum.month; @@ -139,13 +113,6 @@ export const initTeamFreePlan = async ({ ? freePlan.surplusPoints + freePoints : freePoints; - // Apply basic plan config for wecom, but with limited points and dataset size - if (specialConfig) { - for (const key in specialConfig) { - (freePlan as any)[key] = specialConfig[key]; - } - } - return freePlan.save({ session }); } @@ -157,14 +124,13 @@ export const initTeamFreePlan = async ({ currentMode: SubModeEnum.month, nextMode: SubModeEnum.month, startTime: new Date(), - expiredTime: isWecomTeam ? addDays(new Date(), 15) : addMonths(new Date(), 1), + expiredTime: addMonths(new Date(), 1), currentSubLevel: StandardSubLevelEnum.free, nextSubLevel: StandardSubLevelEnum.free, totalPoints: freePoints, - surplusPoints: freePoints, - ...(specialConfig && specialConfig) + surplusPoints: freePoints } ], { session, ordered: true } @@ -172,17 +138,20 @@ export const initTeamFreePlan = async ({ }; // 获取团队标准套餐 -export const getTeamStandPlan = async ({ teamId }: { teamId: string }) => { - const standardPlans = global.subPlans?.standard; +export const getTeamStandPlan = async ({ + teamId, + readFromPrimary = false +}: { + teamId: string; + readFromPrimary?: boolean; +}) => { const plans = await MongoTeamSub.find( { teamId, type: SubTypeEnum.standard }, undefined, - { - ...readFromSecondary - } + readFromPrimary ? { readPreference: 'primary' } : { ...readFromSecondary } ).lean(); sortStandPlans(plans); diff --git a/packages/service/test/common/mongo/indexManager.test.ts b/packages/service/test/common/mongo/indexManager.test.ts index 12fd8614f36c..511f6d5cc8e7 100644 --- a/packages/service/test/common/mongo/indexManager.test.ts +++ b/packages/service/test/common/mongo/indexManager.test.ts @@ -94,6 +94,46 @@ describe('MongoIndexManager.syncModelIndexes', () => { }); }); + it('removes deprecated partial compound indexes', async () => { + const schema = new Schema( + { + teamId: String, + wecomUserId: String + }, + { autoIndex: false } + ); + defineDeprecatedTestIndexes(schema, [ + { + indexName: 'teamId_1_wecomUserId_1', + key: { teamId: 1, wecomUserId: 1 }, + options: { + unique: true, + partialFilterExpression: { wecomUserId: { $exists: true } } + } + } + ]); + const model = createModel({ schema }); + await model.collection.createIndex( + { teamId: 1, wecomUserId: 1 }, + { + name: 'teamId_1_wecomUserId_1', + unique: true, + partialFilterExpression: { wecomUserId: { $exists: true } } + } + ); + + const result = await MongoIndexManager.syncModelIndexes({ model, logger }); + + expect(await getIndexNames(model)).not.toContain('teamId_1_wecomUserId_1'); + expect(result.cleanupReport.items).toEqual([ + expect.objectContaining({ + action: 'drop', + applied: true, + indexName: 'teamId_1_wecomUserId_1' + }) + ]); + }); + it('does not delete schema-external indexes when the Schema has no deprecated declarations', async () => { const schema = new Schema( { currentField: String, customerField: String }, diff --git a/packages/service/test/support/user/team/teamMemberSchema.test.ts b/packages/service/test/support/user/team/teamMemberSchema.test.ts new file mode 100644 index 000000000000..b269266c8bed --- /dev/null +++ b/packages/service/test/support/user/team/teamMemberSchema.test.ts @@ -0,0 +1,24 @@ +import { describe, expect, it } from 'vitest'; +import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema'; +import { getDeprecatedIndexes } from '@fastgpt/service/common/mongo/schemaIndexes'; + +describe('TeamMember schema', () => { + it('does not declare a duplicated WeCom user identity or active index', () => { + expect(MongoTeamMember.schema.path('wecomUserId')).toBeUndefined(); + expect(MongoTeamMember.schema.indexes()).not.toContainEqual([ + { teamId: 1, wecomUserId: 1 }, + expect.any(Object) + ]); + }); + + it('registers the removed WeCom index for safe cleanup', () => { + expect(getDeprecatedIndexes(MongoTeamMember.schema)).toContainEqual({ + indexName: 'teamId_1_wecomUserId_1', + key: { teamId: 1, wecomUserId: 1 }, + options: { + unique: true, + partialFilterExpression: { wecomUserId: { $exists: true } } + } + }); + }); +}); diff --git a/packages/service/test/support/wallet/sub/utils.test.ts b/packages/service/test/support/wallet/sub/utils.test.ts index dac7e2993114..1bad50cc5b01 100644 --- a/packages/service/test/support/wallet/sub/utils.test.ts +++ b/packages/service/test/support/wallet/sub/utils.test.ts @@ -22,6 +22,7 @@ import { } from '@fastgpt/service/support/wallet/sub/utils'; import { MongoTeamSub } from '@fastgpt/service/support/wallet/sub/schema'; import { redisCacheAdapter } from '@fastgpt/dal/redis/adapter'; +import { addMonths } from 'date-fns'; // Valid ObjectId for testing const mockTeamId = '507f1f77bcf86cd799439011'; @@ -444,21 +445,11 @@ describe('buildStandardPlan', () => { expect(result.customDescriptions).toEqual(['特性A', '特性B']); }); - it('wecom 取自 standardConstants', () => { - const constants: TeamStandardSubPlanItemType = { - ...baseConstants, - wecom: { price: 9.9, points: 500 } - }; - const result = buildStandardPlan(baseStandard, constants); - expect(result.wecom).toEqual({ price: 9.9, points: 500 }); - }); - it('standardConstants 展示字段为 undefined 时结果也为 undefined', () => { const result = buildStandardPlan(baseStandard, baseConstants); expect(result.priceDescription).toBeUndefined(); expect(result.customFormUrl).toBeUndefined(); expect(result.customDescriptions).toBeUndefined(); - expect(result.wecom).toBeUndefined(); }); }); @@ -691,6 +682,9 @@ describe('initTeamFreePlan', () => { expect(MongoTeamSub.findOne).toHaveBeenCalled(); expect(MongoTeamSub.create).toHaveBeenCalled(); + const [createdPlan] = (MongoTeamSub.create as any).mock.calls[0][0]; + expect(createdPlan.expiredTime).toEqual(addMonths(createdPlan.startTime, 1)); + expect(createdPlan.maxTeamMember).toBeUndefined(); expect(result).toEqual([mockCreatedPlan]); }); @@ -790,6 +784,24 @@ describe('getTeamStandPlan', () => { expect(result[SubTypeEnum.standard]?.name).toBe('Basic Plan'); }); + it('支持强制从主库读取团队标准套餐', async () => { + const mockQuery = { + lean: vi.fn().mockResolvedValue([]) + }; + vi.spyOn(MongoTeamSub, 'find').mockReturnValue(mockQuery as any); + + await getTeamStandPlan({ teamId: mockTeamId, readFromPrimary: true }); + + expect(MongoTeamSub.find).toHaveBeenCalledWith( + { + teamId: mockTeamId, + type: SubTypeEnum.standard + }, + undefined, + { readPreference: 'primary' } + ); + }); + it('开启标准套餐配置但没有套餐记录时返回 undefined', async () => { vi.spyOn(MongoTeamSub, 'find').mockReturnValue({ lean: vi.fn().mockResolvedValue([]) diff --git a/pro b/pro index cfb1275c6524..febb0ca5a5e0 160000 --- a/pro +++ b/pro @@ -1 +1 @@ -Subproject commit cfb1275c6524ede20542b01c8e9addad3f0ca662 +Subproject commit febb0ca5a5e05c2806266315d3582fcdfb4969e4 diff --git a/projects/app/src/components/CommunityModal/index.tsx b/projects/app/src/components/CommunityModal/index.tsx index 12d022547a7c..da0bc84adc02 100644 --- a/projects/app/src/components/CommunityModal/index.tsx +++ b/projects/app/src/components/CommunityModal/index.tsx @@ -4,13 +4,10 @@ import MyModal from '@fastgpt/web/components/common/MyModal'; import { useClientTranslation } from '@fastgpt/web/i18n/useClientTranslation'; import Markdown from '../Markdown'; import { useSystemStore } from '@/web/common/system/useSystemStore'; -import { useUserStore } from '@/web/support/user/useUserStore'; const CommunityModal = ({ onClose }: { onClose: () => void }) => { const { t } = useClientTranslation(); const { feConfigs } = useSystemStore(); - const { userInfo } = useUserStore(); - const isWecomTeam = !!userInfo?.team.isWecomTeam; return ( void }) => { title={t('common:system.Concat us')} > - {isWecomTeam ? ( - t('common:contact_email', { email: 'archer@fastgpt.io' }) - ) : ( - - )} + diff --git a/projects/app/src/components/support/user/inform/EnterpriseAuthNoticeModal.tsx b/projects/app/src/components/support/user/inform/EnterpriseAuthNoticeModal.tsx index 1a674882deaa..0bef85df7379 100644 --- a/projects/app/src/components/support/user/inform/EnterpriseAuthNoticeModal.tsx +++ b/projects/app/src/components/support/user/inform/EnterpriseAuthNoticeModal.tsx @@ -69,6 +69,7 @@ const EnterpriseAuthNoticeModal = () => { router.pathname === '/dashboard/agent' && !!feConfigs?.show_enterprise_auth && !!teamId && + !userInfo?.team?.isWecomTeam && canCheckEnterpriseAuthNotice && !isAccountCancellationPending && !enterpriseAuthNoticeReadTeamIds?.includes(teamId); diff --git a/projects/app/src/components/support/wallet/NotSufficientModal/index.tsx b/projects/app/src/components/support/wallet/NotSufficientModal/index.tsx index 695d90352e4f..534c8acbcc3b 100644 --- a/projects/app/src/components/support/wallet/NotSufficientModal/index.tsx +++ b/projects/app/src/components/support/wallet/NotSufficientModal/index.tsx @@ -97,7 +97,7 @@ export const RechargeModal = ({ }) => { const { t } = useClientTranslation(); const router = useRouter(); - const { userInfo, teamPlanStatus, initTeamPlanStatus } = useUserStore(); + const { teamPlanStatus, initTeamPlanStatus } = useUserStore(); const { subPlans } = useSystemStore(); useMount(() => { @@ -116,7 +116,6 @@ export const RechargeModal = ({ const [tab, setTab] = useState<'standard' | 'extra'>('standard'); const [userSubMode, setUserSubMode] = useState<`${SubModeEnum}`>(SubModeEnum.month); const selectSubMode = subPlans?.activityExpirationTime ? SubModeEnum.year : userSubMode; - const isWecomTeam = !!userInfo?.team?.isWecomTeam; return ( - {tab === 'standard' && !isWecomTeam && ( + {tab === 'standard' && ( diff --git a/projects/app/src/components/support/wallet/QRCodePayModal.tsx b/projects/app/src/components/support/wallet/QRCodePayModal.tsx index fac14515e3d6..4832b464a220 100644 --- a/projects/app/src/components/support/wallet/QRCodePayModal.tsx +++ b/projects/app/src/components/support/wallet/QRCodePayModal.tsx @@ -251,59 +251,43 @@ const QRCodePayModal = ({ )} - {/* WeChat Work payment: only show WeChat Work option, no switching allowed */} - {payment === BillPayWayEnum.wecom ? ( - + + {isWxConfigured && ( - - ) : ( - - {isWxConfigured && ( - - )} - {isAlipayConfigured && ( - - )} - {isBankConfigured && ( - - )} - - )} + )} + {isAlipayConfigured && ( + + )} + {isBankConfigured && ( + + )} + {feConfigs.payFormUrl && ( diff --git a/projects/app/src/components/support/wallet/StandardPlanContentList.tsx b/projects/app/src/components/support/wallet/StandardPlanContentList.tsx index d10fc6b8067e..71a31ef2c0ac 100644 --- a/projects/app/src/components/support/wallet/StandardPlanContentList.tsx +++ b/projects/app/src/components/support/wallet/StandardPlanContentList.tsx @@ -10,7 +10,6 @@ import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip'; import dynamic from 'next/dynamic'; import Markdown from '@/components/Markdown'; import MyPopover from '@fastgpt/web/components/common/MyPopover'; -import { useUserStore } from '@/web/support/user/useUserStore'; import { formatFileSize } from '@fastgpt/global/common/file/tools'; import type { TeamPlanStandardType } from '@fastgpt/global/support/wallet/sub/type'; @@ -30,32 +29,19 @@ const StandardPlanContentList = ({ const { t } = useClientTranslation(); const { subPlans, feConfigs } = useSystemStore(); - const { userInfo } = useUserStore(); - const planContent = useMemo(() => { - const isWecomTeam = !!userInfo?.team?.isWecomTeam; - const formatMode = isWecomTeam ? SubModeEnum.year : mode; - - // For wecom teams, free plan should use basic plan config - const effectiveLevel = isWecomTeam && level === 'free' ? 'basic' : level; - const plan = subPlans?.standard?.[effectiveLevel]; + const plan = subPlans?.standard?.[level]; if (!plan) return; - // For wecom free plan (trial), use WecomFreePlan constants return { - price: plan.price * (formatMode === SubModeEnum.month ? 1 : 10), + price: plan.price * (mode === SubModeEnum.month ? 1 : 10), level: level as `${StandardSubLevelEnum}`, ...standardSubLevelMap[level as `${StandardSubLevelEnum}`], annualBonusPoints: - formatMode === SubModeEnum.month - ? 0 - : (standplan?.annualBonusPoints ?? plan.annualBonusPoints), + mode === SubModeEnum.month ? 0 : (standplan?.annualBonusPoints ?? plan.annualBonusPoints), totalPoints: - standplan?.totalPoints ?? - (isWecomTeam - ? (plan.wecom?.points ?? 2000) - : plan.totalPoints * (formatMode === SubModeEnum.month ? 1 : 12)), + standplan?.totalPoints ?? plan.totalPoints * (mode === SubModeEnum.month ? 1 : 12), requestsPerMinute: standplan?.requestsPerMinute ?? plan.requestsPerMinute, maxTeamMember: standplan?.maxTeamMember ?? plan.maxTeamMember, maxAppAmount: standplan?.maxAppAmount ?? plan.maxAppAmount, @@ -80,7 +66,6 @@ const StandardPlanContentList = ({ subPlans?.standard, level, mode, - userInfo?.team?.isWecomTeam, standplan?.totalPoints, standplan?.annualBonusPoints, standplan?.requestsPerMinute, diff --git a/projects/app/src/pageComponents/account/bill/BillTable.tsx b/projects/app/src/pageComponents/account/bill/BillTable.tsx index bfd6c76357cf..eed3cea5c986 100644 --- a/projects/app/src/pageComponents/account/bill/BillTable.tsx +++ b/projects/app/src/pageComponents/account/bill/BillTable.tsx @@ -94,16 +94,6 @@ const BillTable = () => { payWay }); - // 企微支付直接打开 URL - if (payWay === 'wecom' && paymentData.payUrl) { - toast({ - title: t('account_bill:wecom_not_pay_tip'), - status: 'success' - }); - window.open(paymentData.payUrl, '_blank'); - return; - } - setQRPayData({ billId: bill._id, readPrice: formatStorePrice2Read(bill.price), diff --git a/projects/app/src/pageComponents/account/info/standardDetailModal.tsx b/projects/app/src/pageComponents/account/info/standardDetailModal.tsx index d27a04af7896..d0ef23389239 100644 --- a/projects/app/src/pageComponents/account/info/standardDetailModal.tsx +++ b/projects/app/src/pageComponents/account/info/standardDetailModal.tsx @@ -27,7 +27,6 @@ import { import { formatTime2YMDHM } from '@fastgpt/global/common/string/time'; import { useSystemStore } from '@/web/common/system/useSystemStore'; import { useRequest } from '@fastgpt/web/hooks/useRequest'; -import { useUserStore } from '@/web/support/user/useUserStore'; type packageStatus = 'active' | 'inactive' | 'expired'; @@ -35,8 +34,6 @@ const StandDetailModal = ({ onClose }: { onClose: () => void }) => { const { t } = useClientTranslation('account_info'); const { Loading } = useLoading(); const { subPlans } = useSystemStore(); - const { userInfo } = useUserStore(); - const isWecomTeam = !!userInfo?.team.isWecomTeam; const { data: teamPlans = [], loading: isLoading } = useRequest( () => getTeamPlans().then((res) => { @@ -141,14 +138,12 @@ const StandDetailModal = ({ onClose }: { onClose: () => void }) => { - {!isWecomTeam && ( - - - - {t('account_info:package_usage_rules')} - - - )} + + + + {t('account_info:package_usage_rules')} + + ); diff --git a/projects/app/src/pageComponents/account/team/EnterpriseAuth/index.tsx b/projects/app/src/pageComponents/account/team/EnterpriseAuth/index.tsx index 279352ef423a..93cbc230f1e5 100644 --- a/projects/app/src/pageComponents/account/team/EnterpriseAuth/index.tsx +++ b/projects/app/src/pageComponents/account/team/EnterpriseAuth/index.tsx @@ -97,6 +97,7 @@ const EnterpriseAuthStatusRow = ({ onClose: onCloseContactBusiness } = useDisclosure(); const autoOpenHandledRef = useRef(false); + const isWecomTeam = !!userInfo?.team?.isWecomTeam; const { data, @@ -105,8 +106,8 @@ const EnterpriseAuthStatusRow = ({ refresh: refreshStatus } = useRequest(getEnterpriseAuthStatus, { manual: false, - ready: !!feConfigs?.show_enterprise_auth && !!userInfo?.team?.teamId, - refreshDeps: [userInfo?.team?.teamId], + ready: !!feConfigs?.show_enterprise_auth && !!userInfo?.team?.teamId && !isWecomTeam, + refreshDeps: [userInfo?.team?.teamId, isWecomTeam], errorToast: '' }); @@ -174,6 +175,11 @@ const EnterpriseAuthStatusRow = ({ useEffect(() => { if (!autoOpen || autoOpenHandledRef.current) return; + if (isWecomTeam) { + autoOpenHandledRef.current = true; + onAutoOpenFinish?.(); + return; + } if (error) { autoOpenHandledRef.current = true; onAutoOpenFinish?.(); @@ -230,6 +236,7 @@ const EnterpriseAuthStatusRow = ({ error, feConfigs?.show_enterprise_auth, hasOtherMemberProcessingTask, + isWecomTeam, loading, needContactBusiness, onAutoOpenFinish, @@ -244,7 +251,7 @@ const EnterpriseAuthStatusRow = ({ autoOpenHandledRef.current = false; }, [autoOpen]); - if (!feConfigs?.show_enterprise_auth || data?.enabled === false) return null; + if (!feConfigs?.show_enterprise_auth || isWecomTeam || data?.enabled === false) return null; if (loading && !data) { return ; diff --git a/projects/app/src/pageComponents/dashboard/TeamPlanStatusCard.tsx b/projects/app/src/pageComponents/dashboard/TeamPlanStatusCard.tsx index 89920d3e81ce..73b0037b920d 100644 --- a/projects/app/src/pageComponents/dashboard/TeamPlanStatusCard.tsx +++ b/projects/app/src/pageComponents/dashboard/TeamPlanStatusCard.tsx @@ -14,7 +14,7 @@ import { webPushTrack } from '@/web/common/middle/tracks/utils'; const TeamPlanStatusCard = () => { const { t } = useTranslation(); - const { teamPlanStatus, userInfo } = useUserStore(); + const { teamPlanStatus } = useUserStore(); const { operationalAd, loadOperationalAd, feConfigs, subPlans } = useSystemStore(); const router = useRouter(); @@ -40,17 +40,13 @@ const TeamPlanStatusCard = () => { } ); - const isWecomTeam = userInfo?.team.isWecomTeam; - const planName = useMemo(() => { if (!teamPlanStatus?.standard?.currentSubLevel) return ''; - if (isWecomTeam && teamPlanStatus.standard.currentSubLevel === StandardSubLevelEnum.free) - return t('common:support.wallet.subscription.standardSubLevel.trial'); return ( subPlans?.standard?.[teamPlanStatus.standard.currentSubLevel]?.name || standardSubLevelMap[teamPlanStatus.standard.currentSubLevel]?.label ); - }, [teamPlanStatus?.standard?.currentSubLevel, isWecomTeam, t, subPlans?.standard]); + }, [teamPlanStatus?.standard?.currentSubLevel, t, subPlans?.standard]); const aiPointsUsageMap = useMemo(() => { if ( diff --git a/projects/app/src/pageComponents/price/ExtraPlan.tsx b/projects/app/src/pageComponents/price/ExtraPlan.tsx index 414eec2160f5..5e10885cdbbb 100644 --- a/projects/app/src/pageComponents/price/ExtraPlan.tsx +++ b/projects/app/src/pageComponents/price/ExtraPlan.tsx @@ -15,7 +15,6 @@ import { calculatePrice } from '@fastgpt/global/support/wallet/bill/tools'; import { formatNumberWithUnit } from '@fastgpt/global/common/string/tools'; import { formatActivityExpirationTime } from './utils'; import { useUserStore } from '@/web/support/user/useUserStore'; -import { StandardSubLevelEnum } from '@fastgpt/global/support/wallet/sub/constants'; import type { PricePurchaseIntent } from './purchaseIntent'; const PLAN_CARD_MAX_WIDTH = '483px'; @@ -37,12 +36,7 @@ const ExtraPlan = ({ const { toast } = useToast(); const { subPlans } = useSystemStore(); const [qrPayData, setQRPayData] = useState(); - const { userInfo, teamPlanStatus } = useUserStore(); - - // For Wecom teams, free plan should not be able to buy extra plan - const isDisabledBuy = - userInfo?.team.isWecomTeam && - teamPlanStatus?.standard?.currentSubLevel === StandardSubLevelEnum.free; + const { userInfo } = useUserStore(); // 额外的知识库索引量 const extraDatasetPrice = subPlans?.extraDatasetSize?.price || 0; @@ -135,17 +129,9 @@ const ExtraPlan = ({ onLoginRequired(intent); return; } - if (isDisabledBuy) { - toast({ - status: 'warning', - title: t('price:support.wallet.subscription.extra_plan_disabled_tip') - }); - return; - } - void onclickBuyExtraPoints({ points: intent.points, month: intent.month }); }, - [isDisabledBuy, onLoginRequired, onclickBuyExtraPoints, t, toast, userInfo] + [onLoginRequired, onclickBuyExtraPoints, userInfo] ); const submitExtraDatasetPurchase = useCallback( @@ -154,17 +140,9 @@ const ExtraPlan = ({ onLoginRequired(intent); return; } - if (isDisabledBuy) { - toast({ - status: 'warning', - title: t('price:support.wallet.subscription.extra_plan_disabled_tip') - }); - return; - } - void onclickBuyDatasetSize({ datasetSize: intent.datasetSize, month: intent.month }); }, - [isDisabledBuy, onLoginRequired, onclickBuyDatasetSize, t, toast, userInfo] + [onLoginRequired, onclickBuyDatasetSize, userInfo] ); useEffect(() => { diff --git a/projects/app/src/pageComponents/price/Standard.tsx b/projects/app/src/pageComponents/price/Standard.tsx index 2b335d2bac29..d22795e1895b 100644 --- a/projects/app/src/pageComponents/price/Standard.tsx +++ b/projects/app/src/pageComponents/price/Standard.tsx @@ -163,14 +163,9 @@ const Standard = ({ [PackageChangeStatusEnum.upgrade]: t('price:pay.package_tip.upgrade') }; - // Check if it's a wecom team - const isWecomTeam = !!userInfo?.team?.isWecomTeam; - const [packageChange, setPackageChange] = useState(); const { subPlans, feConfigs } = useSystemStore(); - const [internalSubMode, setInternalSubMode] = useState<`${SubModeEnum}`>( - isWecomTeam ? SubModeEnum.year : SubModeEnum.month - ); + const [internalSubMode, setInternalSubMode] = useState<`${SubModeEnum}`>(SubModeEnum.month); const planContainerRef = useRef(null); const [responsivePlanLayout, setResponsivePlanLayout] = useState({ columnCount: 4, @@ -183,13 +178,8 @@ const Standard = ({ !!subPlans?.activityExpirationTime && selectSubMode === SubModeEnum.year; useEffect(() => { - // For WeCom teams, always default to yearly mode - if (isWecomTeam) { - setSelectSubMode(SubModeEnum.year); - } else { - setSelectSubMode(subPlans?.activityExpirationTime ? SubModeEnum.year : SubModeEnum.month); - } - }, [isWecomTeam, setSelectSubMode, subPlans?.activityExpirationTime]); + setSelectSubMode(subPlans?.activityExpirationTime ? SubModeEnum.year : SubModeEnum.month); + }, [setSelectSubMode, subPlans?.activityExpirationTime]); useEffect(() => { if (!responsiveCardLayout || !planContainerRef.current) return; @@ -289,10 +279,7 @@ const Standard = ({ ...standardSubLevelMap[level as `${StandardSubLevelEnum}`], ...(value.desc ? { desc: value.desc } : {}), ...(value.name ? { label: value.name } : {}), - price: - isWecomTeam && value.wecom - ? value.wecom.price - : value.price * (selectSubMode === SubModeEnum.month ? 1 : 10), + price: value.price * (selectSubMode === SubModeEnum.month ? 1 : 10), level: level as `${StandardSubLevelEnum}`, maxTeamMember: myStandardPlan?.maxTeamMember ?? value.maxTeamMember, maxAppAmount: myStandardPlan?.maxAppAmount ?? value.maxAppAmount, @@ -300,10 +287,7 @@ const Standard = ({ chatHistoryStoreDuration: value.chatHistoryStoreDuration, maxDatasetSize: value.maxDatasetSize, annualBonusPoints: selectSubMode === SubModeEnum.month ? 0 : value.annualBonusPoints, - totalPoints: - isWecomTeam && value.wecom - ? value.wecom.points - : value.totalPoints * (selectSubMode === SubModeEnum.month ? 1 : 12), + totalPoints: value.totalPoints * (selectSubMode === SubModeEnum.month ? 1 : 12), // custom plan priceDescription: value.priceDescription, @@ -314,7 +298,6 @@ const Standard = ({ : []; }, [ subPlans, - isWecomTeam, selectSubMode, myStandardPlan?.maxTeamMember, myStandardPlan?.maxAppAmount, @@ -327,7 +310,7 @@ const Standard = ({ /* Get pay code */ const { runAsync: onPay, loading: isLoading } = useRequest(postCreatePayBill, { onSuccess(res) { - // For WeChat Work payment, open payment URL in new tab + // Redirect-based payment opens in a new tab; QR-based payment uses the modal below. if (res.payUrl) { window.open(res.payUrl, '_blank'); return; @@ -393,7 +376,7 @@ const Standard = ({ position={'relative'} w={'100%'} > - {!hideBillingToggle && !isWecomTeam && ( + {!hideBillingToggle && ( )} @@ -430,12 +413,6 @@ const Standard = ({ const isHigherLevel = packageChangeStatus === PackageChangeStatusEnum.upgrade; - // For wecom teams with advanced plan, cannot buy basic plan - const isWecomDowngrade = - isWecomTeam && - myStandardPlan?.currentSubLevel === StandardSubLevelEnum.advanced && - item.level === StandardSubLevelEnum.basic; - return ( - {isWecomTeam && item.level === StandardSubLevelEnum.free - ? t('common:support.wallet.subscription.standardSubLevel.trial') - : t(item.label as any)} + {t(item.label as any)} {item.level === StandardSubLevelEnum.custom ? ( @@ -583,17 +558,6 @@ const Standard = ({ ? matchedCoupon.discount * item.price : (matchedCoupon.discount * item.price).toFixed(1) : item.price} - {isWecomTeam && item.level !== StandardSubLevelEnum.free && ( - - {t('price:support.wallet.subscription.per_year')} - - )} {item.level !== StandardSubLevelEnum.free && matchedCoupon && ( - {isWecomTeam && item.level === StandardSubLevelEnum.free - ? t('price:support.wallet.subscription.standardSubLevel.trial_desc') - : t(item.desc as any, { title: feConfigs?.systemTitle })} + {t(item.desc as any, { title: feConfigs?.systemTitle })} {/* Button */} @@ -734,24 +696,6 @@ const Standard = ({ ); } - // For wecom teams with advanced plan, disable basic plan purchase - if (isWecomDowngrade) { - return ( - - ); - } return (