feat: manually mirror opencoze's code from bytedance

Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
fanlv
2025-07-20 17:36:12 +08:00
commit 890153324f
14811 changed files with 1923430 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { UserLevel, type MemberVersionRights } from '../types';
interface UseBenefitBasicResult {
name: string; // 当前用户套餐名称
level: UserLevel; // 当前工作空间:用户的套餐级别
compareLevel: UserLevel; // 当前工作空间:如果是专业版,值是 UserLevel.ProPersonal其他场景同 level
currPlan: MemberVersionRights; // 当前套餐信息
nextPlan: MemberVersionRights; // 下一个套餐信息。如果当前已经是最高套餐级别,则值为最高级别套餐
accountPlan: MemberVersionRights; // 账号维度的套餐信息
instanceStatus: unknown; // 当前套餐状态,可以用来判断退订/到期状态
isOverdue: boolean; // 是否欠费
isExpired: boolean; // 是否过期
isTerminated: boolean; // 是否退订
maxMember: number; //成员上限
}
const defaultData = {
name: '',
level: UserLevel.Free,
compareLevel: UserLevel.Free,
currPlan: {},
nextPlan: {},
accountPlan: {},
instanceStatus: 1,
isOverdue: false,
isExpired: false,
isTerminated: false,
maxMember: -1,
};
/**
* 获取国内权益基础信息
*/
export function useBenefitBasic(): UseBenefitBasicResult {
return defaultData;
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const quota = {
/** 当前消耗的额度,对应到套餐内每天刷新的 */
remain: 0,
total: 0,
used: 0,
/** 额外购买的额度,目前只处理国内 */
extraRemain: 0,
extraTotal: 0,
extraUsed: 0,
};
export function usePremiumQuota() {
return quota;
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { type SubscriptionDetail } from '../types';
const defaultData = {
isFree: false,
isPremiumPlus: false,
hasLowLevelActive: false,
hasHighLevelActive: false,
sub: {},
activeSub: {},
};
export function usePremiumType(): {
isFree: boolean;
isPremiumPlus: boolean;
hasLowLevelActive: boolean;
hasHighLevelActive: boolean;
sub: SubscriptionDetail;
activeSub: SubscriptionDetail;
} {
return defaultData;
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export {
usePremiumStore,
PremiumPlanLevel,
PremiumChannel,
} from './stores/premium';
export { useBenefitBasic } from './hooks/use-benefit-basic';
export { usePremiumType } from './hooks/use-premium-type';
export { usePremiumQuota } from './hooks/use-premium-quota';
export { formatPremiumType } from './utils/premium-type';
export { UserLevel } from '@coze-arch/idl/benefit';
export type { PremiumPlan, PremiumSubs, MemberVersionRights } from './types';

View File

@@ -0,0 +1,189 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { devtools } from 'zustand/middleware';
import { create } from 'zustand';
import {
UserLevel,
type PremiumPlan,
type PremiumSubs,
type SubscriptionDetail,
type BindConnection,
type SubscriptionDetailV2,
type MemberVersionRights,
} from '../types';
// 只处理最低和最高订阅服务档位
export enum PremiumPlanLevel {
Free = 0,
PremiumPlus = 20,
}
export enum PremiumChannel {
Coze = '10000010',
Telegram = '11000007',
Discord = '10000028',
}
export interface VolcanoInfo {
authInstanceId?: string;
authUserId?: string;
loading?: boolean;
}
interface PremiumStoreState {
polling: boolean; // 是否开启订阅数据自动轮询
plans: PremiumPlan[]; // 付费订阅计划列表
subs: PremiumSubs; // 所有订阅数据
currentPlan: SubscriptionDetail; // 当前订阅详情
hasTrial: boolean;
connections: BindConnection[]; // 第三方账号连接数据
benefit: SubscriptionDetailV2; // 用户权益数据
plansCN: Array<MemberVersionRights>; // 国内订阅套餐列表
volcanoInfo: VolcanoInfo; // oauth跳转到火山需要用到的参数
}
interface PremiumStoreAction {
/**
* 重置状态
*/
reset: () => void;
/**
* 设置是否轮询获取订阅数据,以下场景需要:
* - Bot详情判断是否需要显示订阅卡片
* - 左侧菜单栏判断是否需要显示'coze premium'
* - 左侧菜单栏展示credits数量信息
*/
setPolling: (polling: boolean) => void;
/**
* 获取海外订阅套餐列表
*/
fetchPremiumPlans: () => Promise<{
plans: PremiumPlan[];
subs: PremiumSubs;
hasTrial: boolean;
}>;
/**
* 设置国内套餐列表
*/
setPremiumPlansCN: (plans: Array<MemberVersionRights>) => void;
/**
* 恢复订阅,暂时只有海外
*/
renewCurrentPlan: (plan: SubscriptionDetail) => void;
/**
* 获取当前用户订阅详情,暂时只有海外
*/
fetchPremiumPlan: () => Promise<SubscriptionDetail>;
/**
* 取消订阅,暂时只有海外
*/
cancelCurrentPlan: () => void;
/**
* 获取渠道绑定信息,暂时只有海外
*/
fetchConnections: () => Promise<void>;
/**
* 取消渠道用户绑定,暂时只有海外
*/
disconnectUser: (connectorId: string) => void;
/**
* 设置当前登录用户权益信息,海内外通用
*/
setUserBenefit: (benefit: unknown) => void;
/**
* 设置当前账号相关火山信息
*/
setVolcanoInfo: (info: VolcanoInfo) => void;
}
const defaultState: PremiumStoreState = {
polling: false,
plans: [],
subs: {},
currentPlan: {},
hasTrial: false,
connections: [],
benefit: {
user_basic_info: {
user_level: UserLevel.Free,
},
},
plansCN: [],
volcanoInfo: {},
};
export const usePremiumStore = create<PremiumStoreState & PremiumStoreAction>()(
devtools(
(set, get) => ({
...defaultState,
reset: () => {
console.log('unImplement usePremiumStore reset ');
},
setPolling: _polling => {
console.log('unImplement usePremiumStore setPolling ');
},
fetchPremiumPlans: async () => {
const { plans, subs, hasTrial } = get();
await 0;
return { plans, subs, hasTrial };
},
setPremiumPlansCN: (plans = []) => {
set({ plansCN: plans });
},
fetchPremiumPlan: async () => {
await 0;
return get().currentPlan;
},
cancelCurrentPlan: () => {
console.log('unImplement usePremiumStore cancelCurrentPlan ');
},
renewCurrentPlan: _detail => {
console.log('unImplement usePremiumStore renewCurrentPlan ');
},
fetchConnections: async () => {
await 0;
console.log('unImplement usePremiumStore fetchConnections ');
},
disconnectUser: _connectorId => {
console.log('unImplement usePremiumStore disconnectUser ');
},
setUserBenefit: _benefit => {
console.log('unImplement usePremiumStore setUserBenefit ');
},
setVolcanoInfo: _volcanoInfo => {
console.log('unImplement usePremiumStore setVolcanoInfo ');
},
}),
{
enabled: IS_DEV_MODE,
name: 'botStudio.premiumStore',
},
),
);

View File

@@ -0,0 +1,61 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
type SubscriptionBenefitDetail,
type SKUInfo,
type SubscriptionUserInfo,
type SubscriptionDetail,
type SubscriptionRelateBenefit,
type MemberVersionRights,
type SubscriptionDetailV2,
} from '@coze-arch/bot-api/trade';
import { type BindConnection } from '@coze-arch/bot-api/developer_api';
export enum UserLevel {
/** 免费版。 */
Free = 0,
/** 海外
PremiumLite */
PremiumLite = 10,
/** Premium */
Premium = 15,
PremiumPlus = 20,
/** 国内
V1火山专业版 */
V1ProInstance = 100,
/** 个人旗舰版 */
ProPersonal = 110,
/** 团队版 */
Team = 120,
/** 企业版 */
Enterprise = 130,
}
export type {
MemberVersionRights,
SubscriptionDetail,
BindConnection,
SubscriptionDetailV2,
SubscriptionUserInfo,
SKUInfo,
};
export type PremiumPlan = SKUInfo & {
benefit_info?: SubscriptionBenefitDetail;
relate_benefit?: SubscriptionRelateBenefit;
};
export type PremiumSubs = Record<string, SubscriptionUserInfo>;

View File

@@ -0,0 +1,17 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/// <reference types='@coze-arch/bot-typings' />

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type {
PremiumPlan,
PremiumSubs,
SKUInfo,
SubscriptionUserInfo,
} from '../types';
const result = {
isFree: false,
isPremiumPlus: false,
hasLowLevelActive: false,
hasHighLevelActive: false,
sub: {},
activeSub: {},
};
export function formatPremiumType(_props: {
currentPlan?: SKUInfo;
plans: PremiumPlan[];
subs: PremiumSubs;
}): {
isFree: boolean;
isPremiumPlus: boolean;
hasLowLevelActive: boolean;
hasHighLevelActive: boolean;
sub: SubscriptionUserInfo;
activeSub: SubscriptionUserInfo;
} {
return result;
}