feat: require compliance confirmation for paid features

Gate payment, redemption, subscription, and invitation reward flows behind an audited compliance acknowledgement.
This commit is contained in:
CaIon
2026-05-13 22:18:46 +08:00
parent aa56667b8f
commit 0526a22643
57 changed files with 1806 additions and 216 deletions
@@ -62,6 +62,7 @@ const RiskAcknowledgementModal = React.memo(function RiskAcknowledgementModal({
checklist = [],
inputPrompt = '',
requiredText = '',
requiredTextParts = [],
inputPlaceholder = '',
mismatchText = '',
cancelText = '',
@@ -72,24 +73,68 @@ const RiskAcknowledgementModal = React.memo(function RiskAcknowledgementModal({
const isMobile = useIsMobile();
const [checkedItems, setCheckedItems] = useState([]);
const [typedText, setTypedText] = useState('');
const [typedTextParts, setTypedTextParts] = useState([]);
const normalizedRequiredTextParts = useMemo(() => {
let inputIndex = 0;
return requiredTextParts.map((part) => {
if (part.type === 'input') {
const normalizedPart = { ...part, inputIndex };
inputIndex += 1;
return normalizedPart;
}
return part;
});
}, [requiredTextParts]);
const requiredTextInputCount = useMemo(
() =>
normalizedRequiredTextParts.filter((part) => part.type === 'input')
.length,
[normalizedRequiredTextParts],
);
const hasSegmentedRequiredText = requiredTextInputCount > 0;
const requiredTextToDisplay = hasSegmentedRequiredText
? normalizedRequiredTextParts.map((part) => part.text).join('')
: requiredText;
useEffect(() => {
if (!visible) return;
setCheckedItems(Array(checklist.length).fill(false));
setTypedText('');
}, [visible, checklist.length]);
setTypedTextParts(Array(requiredTextInputCount).fill(''));
}, [visible, checklist.length, requiredTextInputCount]);
const allChecked = useMemo(() => {
if (checklist.length === 0) return true;
return checkedItems.length === checklist.length && checkedItems.every(Boolean);
return (
checkedItems.length === checklist.length && checkedItems.every(Boolean)
);
}, [checkedItems, checklist.length]);
const typedMatched = useMemo(() => {
if (hasSegmentedRequiredText) {
return normalizedRequiredTextParts.every((part) => {
if (part.type === 'static') return true;
return (
typedTextParts[part.inputIndex ?? 0]?.trim() === part.text.trim()
);
});
}
if (!requiredText) return true;
return typedText.trim() === requiredText.trim();
}, [typedText, requiredText]);
}, [
hasSegmentedRequiredText,
normalizedRequiredTextParts,
requiredText,
typedText,
typedTextParts,
]);
const detailText = useMemo(() => detailItems.join(', '), [detailItems]);
const hasTypedRequiredText = hasSegmentedRequiredText
? typedTextParts.some((part) => part.trim() !== '')
: typedText.length > 0;
const canConfirm = allChecked && typedMatched;
const handleChecklistChange = useCallback((index, checked) => {
@@ -100,6 +145,14 @@ const RiskAcknowledgementModal = React.memo(function RiskAcknowledgementModal({
});
}, []);
const handleTextPartChange = useCallback((index, value) => {
setTypedTextParts((previous) => {
const next = [...previous];
next[index] = value;
return next;
});
}, []);
return (
<Modal
visible={visible}
@@ -134,7 +187,6 @@ const RiskAcknowledgementModal = React.memo(function RiskAcknowledgementModal({
}
>
<div className='flex flex-col gap-4'>
<RiskMarkdownBlock markdownContent={markdownContent} />
{detailItems.length > 0 ? (
@@ -176,7 +228,7 @@ const RiskAcknowledgementModal = React.memo(function RiskAcknowledgementModal({
</div>
) : null}
{requiredText ? (
{requiredTextToDisplay ? (
<div
className='flex flex-col gap-2 rounded-lg'
style={{
@@ -187,19 +239,51 @@ const RiskAcknowledgementModal = React.memo(function RiskAcknowledgementModal({
>
{inputPrompt ? <Text strong>{inputPrompt}</Text> : null}
<div className='font-mono text-xs break-all rounded-md p-2 bg-gray-50 border border-gray-200'>
{requiredText}
{requiredTextToDisplay}
</div>
<Input
value={typedText}
onChange={setTypedText}
placeholder={inputPlaceholder}
autoFocus={visible}
onCopy={(event) => event.preventDefault()}
onCut={(event) => event.preventDefault()}
onPaste={(event) => event.preventDefault()}
onDrop={(event) => event.preventDefault()}
/>
{!typedMatched && typedText ? (
{hasSegmentedRequiredText ? (
<div className='flex flex-wrap items-center gap-2'>
{normalizedRequiredTextParts.map((part, index) =>
part.type === 'static' ? (
<span
key={`static-${index}`}
className='select-none rounded-md border border-gray-200 bg-white px-2 py-1 font-mono text-sm text-gray-500'
>
{part.text}
</span>
) : (
<Input
key={`input-${index}`}
value={typedTextParts[part.inputIndex ?? 0] ?? ''}
onChange={(value) =>
handleTextPartChange(part.inputIndex ?? 0, value)
}
placeholder={
part.placeholder || part.text || inputPlaceholder
}
autoFocus={visible && part.inputIndex === 0}
onCopy={(event) => event.preventDefault()}
onCut={(event) => event.preventDefault()}
onPaste={(event) => event.preventDefault()}
onDrop={(event) => event.preventDefault()}
style={{ width: isMobile ? '100%' : 260 }}
/>
),
)}
</div>
) : (
<Input
value={typedText}
onChange={setTypedText}
placeholder={inputPlaceholder}
autoFocus={visible}
onCopy={(event) => event.preventDefault()}
onCut={(event) => event.preventDefault()}
onPaste={(event) => event.preventDefault()}
onDrop={(event) => event.preventDefault()}
/>
)}
{!typedMatched && hasTypedRequiredText ? (
<Text type='danger' size='small'>
{mismatchText}
</Text>
+196 -49
View File
@@ -18,15 +18,18 @@ For commercial licensing, please contact support@quantumnous.com
*/
import React, { useEffect, useState } from 'react';
import { Card, Spin, Tabs } from '@douyinfe/semi-ui';
import { Banner, Button, Card, Spin, Tabs } from '@douyinfe/semi-ui';
import SettingsGeneralPayment from '../../pages/Setting/Payment/SettingsGeneralPayment';
import SettingsPaymentGateway from '../../pages/Setting/Payment/SettingsPaymentGateway';
import SettingsPaymentGatewayStripe from '../../pages/Setting/Payment/SettingsPaymentGatewayStripe';
import SettingsPaymentGatewayCreem from '../../pages/Setting/Payment/SettingsPaymentGatewayCreem';
import SettingsPaymentGatewayWaffo from '../../pages/Setting/Payment/SettingsPaymentGatewayWaffo';
import SettingsPaymentGatewayWaffoPancake from '../../pages/Setting/Payment/SettingsPaymentGatewayWaffoPancake';
import { API, showError, toBoolean } from '../../helpers';
import { API, showError, showSuccess, toBoolean } from '../../helpers';
import { useTranslation } from 'react-i18next';
import RiskAcknowledgementModal from '../common/modals/RiskAcknowledgementModal';
const CURRENT_COMPLIANCE_TERMS_VERSION = 'v1';
const PaymentSetting = () => {
const { t } = useTranslation();
@@ -60,9 +63,59 @@ const PaymentSetting = () => {
WaffoPancakeCurrency: 'USD',
WaffoPancakeUnitPrice: 1.0,
WaffoPancakeMinTopUp: 1,
'payment_setting.compliance_confirmed': false,
'payment_setting.compliance_terms_version': '',
'payment_setting.compliance_confirmed_at': 0,
'payment_setting.compliance_confirmed_by': 0,
});
let [loading, setLoading] = useState(false);
const [complianceVisible, setComplianceVisible] = useState(false);
const complianceStatements = [
t('你已合法取得所接入模型 API、账号、密钥和额度的授权;'),
t(
'你承诺仅在已取得上游服务商、模型服务提供方或相关权利方合法授权的范围内使用其 API、账号、密钥、额度及服务能力,不进行未经授权的转售、倒卖、分销或其他违规商业化使用。',
),
t(
'如向中华人民共和国境内公众提供生成式人工智能服务,你将依法履行备案登记、安全评估、内容安全、投诉举报、生成合成内容标识、日志留存、个人信息保护等合规义务;',
),
t(
'你承诺不会利用本系统实施、协助实施或变相实施违反适用法律法规、监管要求、平台规则、社会公共利益或第三方合法权益的行为。',
),
t('你理解并自行承担部署、运营和收费行为产生的法律责任。'),
t(
'你理解本合规提醒仅用于风险提示,不构成法律意见、合规审查结论或对你使用本系统行为合法性的保证;你应根据实际业务场景自行咨询专业法律或合规顾问。',
),
];
const requiredComplianceText = t(
'我已阅读并理解上述合规提醒,知悉相关法律风险,并确认自行承担部署、运营和收费行为产生的法律责任',
);
const requiredComplianceTextParts = [
{
type: 'input',
text: t('我已阅读并理解上述合规提醒'),
},
{ type: 'static', text: t('') },
{
type: 'input',
text: t('知悉相关法律风险'),
},
{ type: 'static', text: t('') },
{
type: 'input',
text: t('并确认自行承担部署'),
},
{ type: 'static', text: t('、') },
{
type: 'input',
text: t('运营和收费行为产生的法律责任'),
},
];
const complianceConfirmed =
inputs['payment_setting.compliance_confirmed'] &&
inputs['payment_setting.compliance_terms_version'] ===
CURRENT_COMPLIANCE_TERMS_VERSION;
const getOptions = async () => {
const res = await API.get('/api/option/');
@@ -104,6 +157,16 @@ const PaymentSetting = () => {
newInputs['AmountDiscount'] = item.value;
}
break;
case 'payment_setting.compliance_confirmed':
newInputs[item.key] = toBoolean(item.value);
break;
case 'payment_setting.compliance_confirmed_at':
case 'payment_setting.compliance_confirmed_by':
newInputs[item.key] = parseInt(item.value) || 0;
break;
case 'payment_setting.compliance_terms_version':
newInputs[item.key] = item.value;
break;
case 'Price':
case 'MinTopUp':
case 'StripeUnitPrice':
@@ -154,59 +217,143 @@ const PaymentSetting = () => {
onRefresh();
}, []);
const confirmCompliance = async () => {
try {
const res = await API.post('/api/option/payment_compliance', {
confirmed: true,
});
if (res.data.success) {
showSuccess(t('合规声明确认成功'));
setComplianceVisible(false);
await onRefresh();
} else {
showError(res.data.message || t('确认失败'));
}
} catch (error) {
showError(t('确认失败'));
}
};
return (
<>
<Spin spinning={loading} size='large'>
<Card style={{ marginTop: '10px' }}>
<Tabs
type='card'
defaultActiveKey='general'
contentStyle={{ paddingTop: 24 }}
{!complianceConfirmed ? (
<Banner
type='warning'
title={t('需要确认合规声明')}
description={
<div className='flex flex-col gap-2'>
<span>
{t(
'确认前,支付、兑换码、订阅计划和邀请返利功能将保持锁定。',
)}
</span>
<Button
type='warning'
theme='solid'
onClick={() => setComplianceVisible(true)}
>
{t('确认合规声明')}
</Button>
</div>
}
closeIcon={null}
style={{ marginBottom: 16 }}
fullMode={false}
/>
) : (
<Banner
type='success'
title={t('合规声明已确认')}
description={t('确认时间:{{time}},确认用户:#{{userId}}', {
time: inputs['payment_setting.compliance_confirmed_at']
? new Date(
inputs['payment_setting.compliance_confirmed_at'] * 1000,
).toLocaleString()
: '-',
userId:
inputs['payment_setting.compliance_confirmed_by'] || '-',
})}
closeIcon={null}
style={{ marginBottom: 16 }}
fullMode={false}
/>
)}
<div
style={
complianceConfirmed
? undefined
: { opacity: 0.4, pointerEvents: 'none' }
}
>
<Tabs.TabPane tab={t('通用设置')} itemKey='general'>
<SettingsGeneralPayment
options={inputs}
refresh={onRefresh}
hideSectionTitle
/>
</Tabs.TabPane>
<Tabs.TabPane tab={t('易支付设置')} itemKey='epay'>
<SettingsPaymentGateway
options={inputs}
refresh={onRefresh}
hideSectionTitle
/>
</Tabs.TabPane>
<Tabs.TabPane tab={t('Stripe 设置')} itemKey='stripe'>
<SettingsPaymentGatewayStripe
options={inputs}
refresh={onRefresh}
hideSectionTitle
/>
</Tabs.TabPane>
<Tabs.TabPane tab={t('Creem 设置')} itemKey='creem'>
<SettingsPaymentGatewayCreem
options={inputs}
refresh={onRefresh}
hideSectionTitle
/>
</Tabs.TabPane>
<Tabs.TabPane tab={t('Waffo 设置')} itemKey='waffo'>
<SettingsPaymentGatewayWaffo
options={inputs}
refresh={onRefresh}
hideSectionTitle
/>
</Tabs.TabPane>
{/*<Tabs.TabPane tab={t('Waffo Pancake 设置')} itemKey='waffo-pancake'>*/}
{/* <SettingsPaymentGatewayWaffoPancake*/}
{/* options={inputs}*/}
{/* refresh={onRefresh}*/}
{/* hideSectionTitle*/}
{/* />*/}
{/*</Tabs.TabPane>*/}
</Tabs>
<Tabs
type='card'
defaultActiveKey='general'
contentStyle={{ paddingTop: 24 }}
>
<Tabs.TabPane tab={t('通用设置')} itemKey='general'>
<SettingsGeneralPayment
options={inputs}
refresh={onRefresh}
hideSectionTitle
/>
</Tabs.TabPane>
<Tabs.TabPane tab={t('易支付设置')} itemKey='epay'>
<SettingsPaymentGateway
options={inputs}
refresh={onRefresh}
hideSectionTitle
/>
</Tabs.TabPane>
<Tabs.TabPane tab={t('Stripe 设置')} itemKey='stripe'>
<SettingsPaymentGatewayStripe
options={inputs}
refresh={onRefresh}
hideSectionTitle
/>
</Tabs.TabPane>
<Tabs.TabPane tab={t('Creem 设置')} itemKey='creem'>
<SettingsPaymentGatewayCreem
options={inputs}
refresh={onRefresh}
hideSectionTitle
/>
</Tabs.TabPane>
<Tabs.TabPane tab={t('Waffo 设置')} itemKey='waffo'>
<SettingsPaymentGatewayWaffo
options={inputs}
refresh={onRefresh}
hideSectionTitle
/>
</Tabs.TabPane>
{/*<Tabs.TabPane tab={t('Waffo Pancake 设置')} itemKey='waffo-pancake'>*/}
{/* <SettingsPaymentGatewayWaffoPancake*/}
{/* options={inputs}*/}
{/* refresh={onRefresh}*/}
{/* hideSectionTitle*/}
{/* />*/}
{/*</Tabs.TabPane>*/}
</Tabs>
</div>
</Card>
<RiskAcknowledgementModal
visible={complianceVisible}
title={t('确认合规声明')}
markdownContent={t(
'该操作将启用支付、兑换码、订阅计划和邀请返利相关功能。请仔细阅读并确认以下声明。',
)}
checklist={complianceStatements}
inputPrompt={t('请输入以下文字以确认:')}
requiredText={requiredComplianceText}
requiredTextParts={requiredComplianceTextParts}
inputPlaceholder={t('请输入确认文案')}
mismatchText={t('输入内容与要求文案不一致')}
cancelText={t('取消')}
confirmText={t('确认并启用')}
onCancel={() => setComplianceVisible(false)}
onConfirm={confirmCompliance}
/>
</Spin>
</>
);
@@ -20,7 +20,7 @@ For commercial licensing, please contact support@quantumnous.com
import React from 'react';
import { Button } from '@douyinfe/semi-ui';
const SubscriptionsActions = ({ openCreate, t }) => {
const SubscriptionsActions = ({ openCreate, t, disabled = false }) => {
return (
<div className='flex gap-2 w-full md:w-auto'>
<Button
@@ -28,6 +28,7 @@ const SubscriptionsActions = ({ openCreate, t }) => {
className='w-full md:w-auto'
onClick={openCreate}
size='small'
disabled={disabled}
>
{t('新建套餐')}
</Button>
@@ -228,7 +228,11 @@ const renderPaymentConfig = (text, record, t, enableEpay) => {
);
};
const renderOperations = (text, record, { openEdit, setPlanEnabled, t }) => {
const renderOperations = (
text,
record,
{ openEdit, setPlanEnabled, t, complianceConfirmed },
) => {
const isEnabled = record?.plan?.enabled;
const handleToggle = () => {
@@ -256,11 +260,18 @@ const renderOperations = (text, record, { openEdit, setPlanEnabled, t }) => {
type='tertiary'
size='small'
onClick={() => openEdit(record)}
disabled={!complianceConfirmed}
>
{t('编辑')}
</Button>
{isEnabled ? (
<Button theme='light' type='danger' size='small' onClick={handleToggle}>
<Button
theme='light'
type='danger'
size='small'
onClick={handleToggle}
disabled={!complianceConfirmed}
>
{t('禁用')}
</Button>
) : (
@@ -269,6 +280,7 @@ const renderOperations = (text, record, { openEdit, setPlanEnabled, t }) => {
type='primary'
size='small'
onClick={handleToggle}
disabled={!complianceConfirmed}
>
{t('启用')}
</Button>
@@ -282,6 +294,7 @@ export const getSubscriptionsColumns = ({
openEdit,
setPlanEnabled,
enableEpay,
complianceConfirmed = true,
}) => {
return [
{
@@ -351,7 +364,12 @@ export const getSubscriptionsColumns = ({
fixed: 'right',
width: 160,
render: (text, record) =>
renderOperations(text, record, { openEdit, setPlanEnabled, t }),
renderOperations(text, record, {
openEdit,
setPlanEnabled,
t,
complianceConfirmed,
}),
},
];
};
@@ -35,6 +35,7 @@ const SubscriptionsTable = (subscriptionsData) => {
setPlanEnabled,
t,
enableEpay,
complianceConfirmed,
} = subscriptionsData;
const columns = useMemo(() => {
@@ -43,8 +44,9 @@ const SubscriptionsTable = (subscriptionsData) => {
openEdit,
setPlanEnabled,
enableEpay,
complianceConfirmed,
});
}, [t, openEdit, setPlanEnabled, enableEpay]);
}, [t, openEdit, setPlanEnabled, enableEpay, complianceConfirmed]);
const tableColumns = useMemo(() => {
return compactMode
+39 -3
View File
@@ -17,7 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import React, { useContext } from 'react';
import React, { useContext, useEffect, useState } from 'react';
import { Banner } from '@douyinfe/semi-ui';
import CardPro from '../../common/ui/CardPro';
import SubscriptionsTable from './SubscriptionsTable';
@@ -28,12 +28,14 @@ import { useSubscriptionsData } from '../../../hooks/subscriptions/useSubscripti
import { useIsMobile } from '../../../hooks/common/useIsMobile';
import { createCardProPagination } from '../../../helpers/utils';
import { StatusContext } from '../../../context/Status';
import { API } from '../../../helpers';
const SubscriptionsPage = () => {
const subscriptionsData = useSubscriptionsData();
const isMobile = useIsMobile();
const [statusState] = useContext(StatusContext);
const enableEpay = !!statusState?.status?.enable_online_topup;
const [complianceConfirmed, setComplianceConfirmed] = useState(true);
const {
showEdit,
@@ -47,6 +49,22 @@ const SubscriptionsPage = () => {
t,
} = subscriptionsData;
useEffect(() => {
const loadComplianceStatus = async () => {
try {
const res = await API.get('/api/user/topup/info');
if (res.data?.success) {
setComplianceConfirmed(
res.data.data?.payment_compliance_confirmed !== false,
);
}
} catch (error) {
// Keep the page usable if status loading fails; backend still enforces.
}
};
loadComplianceStatus();
}, []);
return (
<>
<AddEditSubscriptionModal
@@ -71,7 +89,11 @@ const SubscriptionsPage = () => {
<div className='flex flex-col md:flex-row justify-between items-start md:items-center gap-2 w-full'>
{/* Mobile: actions first; Desktop: actions left */}
<div className='order-1 md:order-0 w-full md:w-auto'>
<SubscriptionsActions openCreate={openCreate} t={t} />
<SubscriptionsActions
openCreate={openCreate}
t={t}
disabled={!complianceConfirmed}
/>
</div>
<Banner
type='info'
@@ -94,7 +116,21 @@ const SubscriptionsPage = () => {
})}
t={t}
>
<SubscriptionsTable {...subscriptionsData} enableEpay={enableEpay} />
{!complianceConfirmed && (
<Banner
type='warning'
description={t(
'订阅套餐创建和变更已锁定,管理员需先在支付设置中确认合规声明。',
)}
closeIcon={null}
className='!rounded-lg mb-3'
/>
)}
<SubscriptionsTable
{...subscriptionsData}
enableEpay={enableEpay}
complianceConfirmed={complianceConfirmed}
/>
</CardPro>
</>
);
+12
View File
@@ -38,6 +38,7 @@ const InvitationCard = ({
setOpenTransfer,
affLink,
handleAffLinkClick,
complianceConfirmed = true,
}) => {
return (
<Card className='!rounded-2xl shadow-sm border-0'>
@@ -81,6 +82,7 @@ const InvitationCard = ({
theme='solid'
size='small'
disabled={
!complianceConfirmed ||
!userState?.user?.aff_quota ||
userState?.user?.aff_quota <= 0
}
@@ -91,6 +93,16 @@ const InvitationCard = ({
{t('划转到余额')}
</Button>
</div>
{!complianceConfirmed && (
<Text
style={{
color: 'rgba(255,255,255,0.8)',
fontSize: 12,
}}
>
{t('邀请奖励划转已禁用,管理员需先确认合规声明。')}
</Text>
)}
{/* 统计数据 */}
<div className='grid grid-cols-3 gap-6 mt-4'>
+58 -48
View File
@@ -96,6 +96,7 @@ const RechargeCard = ({
activeSubscriptions = [],
allSubscriptions = [],
reloadSubscriptionSelf,
enableRedemption = true,
}) => {
const onlineFormApiRef = useRef(null);
const redeemFormApiRef = useRef(null);
@@ -566,57 +567,66 @@ const RechargeCard = ({
</Card>
{/* 兑换码充值 */}
<Card
className='!rounded-xl w-full'
title={
<Text type='tertiary' strong>
{t('兑换码充值')}
</Text>
}
>
<Form
getFormApi={(api) => (redeemFormApiRef.current = api)}
initValues={{ redemptionCode: redemptionCode }}
{enableRedemption ? (
<Card
className='!rounded-xl w-full'
title={
<Text type='tertiary' strong>
{t('兑换码充值')}
</Text>
}
>
<Form.Input
field='redemptionCode'
noLabel={true}
placeholder={t('请输入兑换码')}
value={redemptionCode}
onChange={(value) => setRedemptionCode(value)}
prefix={<IconGift />}
suffix={
<div className='flex items-center gap-2'>
<Button
type='primary'
theme='solid'
onClick={topUp}
loading={isSubmitting}
>
{t('兑换额度')}
</Button>
</div>
}
showClear
style={{ width: '100%' }}
extraText={
topUpLink && (
<Text type='tertiary'>
{t('在找兑换码?')}
<Text
type='secondary'
underline
className='cursor-pointer'
onClick={openTopUpLink}
<Form
getFormApi={(api) => (redeemFormApiRef.current = api)}
initValues={{ redemptionCode: redemptionCode }}
>
<Form.Input
field='redemptionCode'
noLabel={true}
placeholder={t('请输入兑换码')}
value={redemptionCode}
onChange={(value) => setRedemptionCode(value)}
prefix={<IconGift />}
suffix={
<div className='flex items-center gap-2'>
<Button
type='primary'
theme='solid'
onClick={topUp}
loading={isSubmitting}
>
{t('购买兑换码')}
{t('兑换额度')}
</Button>
</div>
}
showClear
style={{ width: '100%' }}
extraText={
topUpLink && (
<Text type='tertiary'>
{t('在找兑换码?')}
<Text
type='secondary'
underline
className='cursor-pointer'
onClick={openTopUpLink}
>
{t('购买兑换码')}
</Text>
</Text>
</Text>
)
}
/>
</Form>
</Card>
)
}
/>
</Form>
</Card>
) : (
<Banner
type='warning'
description={t('兑换码功能已禁用,管理员需先确认合规声明。')}
closeIcon={null}
className='!rounded-xl'
/>
)}
</Space>
);
+13 -1
View File
@@ -110,6 +110,8 @@ const TopUp = () => {
const [topupInfo, setTopupInfo] = useState({
amount_options: [],
discount: {},
enable_redemption: true,
payment_compliance_confirmed: true,
});
const confirmPayMethods = [
@@ -645,7 +647,7 @@ const TopUp = () => {
? data.waffo_min_topup
: enableWaffoPancakeTopUp
? data.waffo_pancake_min_topup
: 1;
: 1;
setEnableOnlineTopUp(enableOnlineTopUp);
setEnableStripeTopUp(enableStripeTopUp);
setEnableCreemTopUp(enableCreemTopUp);
@@ -657,6 +659,14 @@ const TopUp = () => {
setMinTopUp(minTopUpValue);
setTopUpCount(minTopUpValue);
setTopUpLink(data.topup_link || '');
setTopupInfo((prev) => ({
...prev,
enable_redemption: data.enable_redemption !== false,
payment_compliance_confirmed:
data.payment_compliance_confirmed !== false,
payment_compliance_terms_version:
data.payment_compliance_terms_version || '',
}));
// 设置 Creem 产品
try {
@@ -984,6 +994,7 @@ const TopUp = () => {
activeSubscriptions={activeSubscriptions}
allSubscriptions={allSubscriptions}
reloadSubscriptionSelf={getSubscriptionSelf}
enableRedemption={topupInfo.enable_redemption !== false}
/>
<InvitationCard
t={t}
@@ -992,6 +1003,7 @@ const TopUp = () => {
setOpenTransfer={setOpenTransfer}
affLink={affLink}
handleAffLinkClick={handleAffLinkClick}
complianceConfirmed={topupInfo.payment_compliance_confirmed !== false}
/>
</div>
</div>
+31 -1
View File
@@ -3794,6 +3794,36 @@
"见上方动态计费详情": "See dynamic pricing details above",
"含时间条件": "Time rules",
"含请求条件": "Request rules",
"(当前仅支持易支付接口,默认使用上方服务器地址作为回调地址!)": "(Currently only supports Epay interface, the default callback address is the server address above!)"
"(当前仅支持易支付接口,默认使用上方服务器地址作为回调地址!)": "(Currently only supports Epay interface, the default callback address is the server address above!)",
"你已合法取得所接入模型 API、账号、密钥和额度的授权;": "You have legally obtained authorization for the connected model APIs, accounts, keys, and quotas.",
"你承诺仅在已取得上游服务商、模型服务提供方或相关权利方合法授权的范围内使用其 API、账号、密钥、额度及服务能力,不进行未经授权的转售、倒卖、分销或其他违规商业化使用。": "You commit to using upstream APIs, accounts, keys, quotas, and service capabilities only within the scope of lawful authorization obtained from upstream service providers, model service providers, or relevant rights holders, and will not conduct unauthorized resale, trafficking, distribution, or other non-compliant commercialization.",
"如向中华人民共和国境内公众提供生成式人工智能服务,你将依法履行备案登记、安全评估、内容安全、投诉举报、生成合成内容标识、日志留存、个人信息保护等合规义务;": "If you provide generative AI services to the public in mainland China, you will fulfill legal compliance obligations.",
"你承诺不会利用本系统实施、协助实施或变相实施违反适用法律法规、监管要求、平台规则、社会公共利益或第三方合法权益的行为。": "You commit not to use this system to implement, assist with, or indirectly implement acts that violate applicable laws and regulations, regulatory requirements, platform rules, public interests, or the lawful rights and interests of third parties.",
"你理解并自行承担部署、运营和收费行为产生的法律责任。": "You understand and independently bear legal responsibility arising from deployment, operation, and charging behavior.",
"你理解本合规提醒仅用于风险提示,不构成法律意见、合规审查结论或对你使用本系统行为合法性的保证;你应根据实际业务场景自行咨询专业法律或合规顾问。": "You understand this compliance reminder is only for risk notice and does not constitute legal advice, a compliance review conclusion, or a guarantee of the legality of your use of this system; you should consult professional legal or compliance advisors based on your actual business scenario.",
"我已阅读并理解上述合规提醒,知悉相关法律风险,并确认自行承担部署、运营和收费行为产生的法律责任": "I have read and understood the above compliance reminder, acknowledge the related legal risks, and confirm that I bear legal responsibility arising from deployment, operation, and charging behavior.",
"需要确认合规声明": "Compliance confirmation required",
"确认前,支付、兑换码、订阅计划和邀请返利功能将保持锁定。": "Payment, redemption codes, subscription plans, and invitation rewards remain locked until confirmation.",
"确认合规声明": "Confirm compliance terms",
"合规声明已确认": "Compliance confirmed",
"确认时间:{{time}},确认用户:#{{userId}}": "Confirmed at {{time}} by user #{{userId}}",
"该操作将启用支付、兑换码、订阅计划和邀请返利相关功能。请仔细阅读并确认以下声明。": "This confirmation unlocks payment, redemption code, subscription plan, and invitation reward features. Please read carefully.",
"请输入以下文字以确认:": "Please type the following text to confirm:",
"请输入确认文案": "Type the confirmation text here",
"输入内容与要求文案不一致": "The entered text does not match the required text.",
"确认并启用": "Confirm and enable",
"合规声明确认成功": "Compliance confirmed successfully",
"确认失败": "Confirmation failed",
"兑换码功能已禁用,管理员需先确认合规声明。": "Redemption codes are disabled until the administrator confirms compliance terms.",
"订阅套餐创建和变更已锁定,管理员需先在支付设置中确认合规声明。": "Subscription plan creation and changes are locked until compliance terms are confirmed in payment settings.",
"邀请奖励划转已禁用,管理员需先确认合规声明。": "Invitation reward transfer is disabled until compliance terms are confirmed.",
"设置非零邀请奖励额度前,需要先在支付设置中确认合规声明。": "Non-zero invitation rewards require compliance confirmation in payment settings.",
"非零值需先确认合规声明": "Non-zero values require compliance confirmation first",
"我已阅读并理解上述合规提醒": "I have read and understood the above compliance reminder",
"知悉相关法律风险": "acknowledge the related legal risks",
"并确认自行承担部署": "confirm that I bear legal responsibility arising from deployment",
"运营和收费行为产生的法律责任": "operation and charging behavior",
"": ", ",
"、": ", "
}
}
+31 -1
View File
@@ -3649,6 +3649,36 @@
"默认用户消息": "Bonjour",
"默认补全倍率": "Taux de complétion par défaut",
"阶梯计费(表达式解析失败)": "Facturation par paliers (échec de l'analyse de l'expression)",
"阶梯计费(未匹配到对应阶梯)": "Facturation par paliers (aucun palier correspondant)"
"阶梯计费(未匹配到对应阶梯)": "Facturation par paliers (aucun palier correspondant)",
"你已合法取得所接入模型 API、账号、密钥和额度的授权;": "You have legally obtained authorization for the connected model APIs, accounts, keys, and quotas.",
"你承诺仅在已取得上游服务商、模型服务提供方或相关权利方合法授权的范围内使用其 API、账号、密钥、额度及服务能力,不进行未经授权的转售、倒卖、分销或其他违规商业化使用。": "You commit to using upstream APIs, accounts, keys, quotas, and service capabilities only within the scope of lawful authorization obtained from upstream service providers, model service providers, or relevant rights holders, and will not conduct unauthorized resale, trafficking, distribution, or other non-compliant commercialization.",
"如向中华人民共和国境内公众提供生成式人工智能服务,你将依法履行备案登记、安全评估、内容安全、投诉举报、生成合成内容标识、日志留存、个人信息保护等合规义务;": "If you provide generative AI services to the public in mainland China, you will fulfill legal compliance obligations.",
"你承诺不会利用本系统实施、协助实施或变相实施违反适用法律法规、监管要求、平台规则、社会公共利益或第三方合法权益的行为。": "You commit not to use this system to implement, assist with, or indirectly implement acts that violate applicable laws and regulations, regulatory requirements, platform rules, public interests, or the lawful rights and interests of third parties.",
"你理解并自行承担部署、运营和收费行为产生的法律责任。": "You understand and independently bear legal responsibility arising from deployment, operation, and charging behavior.",
"你理解本合规提醒仅用于风险提示,不构成法律意见、合规审查结论或对你使用本系统行为合法性的保证;你应根据实际业务场景自行咨询专业法律或合规顾问。": "You understand this compliance reminder is only for risk notice and does not constitute legal advice, a compliance review conclusion, or a guarantee of the legality of your use of this system; you should consult professional legal or compliance advisors based on your actual business scenario.",
"我已阅读并理解上述合规提醒,知悉相关法律风险,并确认自行承担部署、运营和收费行为产生的法律责任": "I have read and understood the above compliance reminder, acknowledge the related legal risks, and confirm that I bear legal responsibility arising from deployment, operation, and charging behavior.",
"需要确认合规声明": "Compliance confirmation required",
"确认前,支付、兑换码、订阅计划和邀请返利功能将保持锁定。": "Payment, redemption codes, subscription plans, and invitation rewards remain locked until confirmation.",
"确认合规声明": "Confirm compliance terms",
"合规声明已确认": "Compliance confirmed",
"确认时间:{{time}},确认用户:#{{userId}}": "Confirmed at {{time}} by user #{{userId}}",
"该操作将启用支付、兑换码、订阅计划和邀请返利相关功能。请仔细阅读并确认以下声明。": "This confirmation unlocks payment, redemption code, subscription plan, and invitation reward features. Please read carefully.",
"请输入以下文字以确认:": "Please type the following text to confirm:",
"请输入确认文案": "Type the confirmation text here",
"输入内容与要求文案不一致": "The entered text does not match the required text.",
"确认并启用": "Confirm and enable",
"合规声明确认成功": "Compliance confirmed successfully",
"确认失败": "Confirmation failed",
"兑换码功能已禁用,管理员需先确认合规声明。": "Redemption codes are disabled until the administrator confirms compliance terms.",
"订阅套餐创建和变更已锁定,管理员需先在支付设置中确认合规声明。": "Subscription plan creation and changes are locked until compliance terms are confirmed in payment settings.",
"邀请奖励划转已禁用,管理员需先确认合规声明。": "Invitation reward transfer is disabled until compliance terms are confirmed.",
"设置非零邀请奖励额度前,需要先在支付设置中确认合规声明。": "Non-zero invitation rewards require compliance confirmation in payment settings.",
"非零值需先确认合规声明": "Non-zero values require compliance confirmation first",
"我已阅读并理解上述合规提醒": "I have read and understood the above compliance reminder",
"知悉相关法律风险": "acknowledge the related legal risks",
"并确认自行承担部署": "confirm that I bear legal responsibility arising from deployment",
"运营和收费行为产生的法律责任": "operation and charging behavior",
"": ", ",
"、": ", "
}
}
+31 -1
View File
@@ -3618,6 +3618,36 @@
"默认用户消息": "こんにちは",
"默认补全倍率": "デフォルト補完倍率",
"阶梯计费(表达式解析失败)": "段階課金(式の解析に失敗)",
"阶梯计费(未匹配到对应阶梯)": "段階課金(一致する階層なし)"
"阶梯计费(未匹配到对应阶梯)": "段階課金(一致する階層なし)",
"你已合法取得所接入模型 API、账号、密钥和额度的授权;": "You have legally obtained authorization for the connected model APIs, accounts, keys, and quotas.",
"你承诺仅在已取得上游服务商、模型服务提供方或相关权利方合法授权的范围内使用其 API、账号、密钥、额度及服务能力,不进行未经授权的转售、倒卖、分销或其他违规商业化使用。": "You commit to using upstream APIs, accounts, keys, quotas, and service capabilities only within the scope of lawful authorization obtained from upstream service providers, model service providers, or relevant rights holders, and will not conduct unauthorized resale, trafficking, distribution, or other non-compliant commercialization.",
"如向中华人民共和国境内公众提供生成式人工智能服务,你将依法履行备案登记、安全评估、内容安全、投诉举报、生成合成内容标识、日志留存、个人信息保护等合规义务;": "If you provide generative AI services to the public in mainland China, you will fulfill legal compliance obligations.",
"你承诺不会利用本系统实施、协助实施或变相实施违反适用法律法规、监管要求、平台规则、社会公共利益或第三方合法权益的行为。": "You commit not to use this system to implement, assist with, or indirectly implement acts that violate applicable laws and regulations, regulatory requirements, platform rules, public interests, or the lawful rights and interests of third parties.",
"你理解并自行承担部署、运营和收费行为产生的法律责任。": "You understand and independently bear legal responsibility arising from deployment, operation, and charging behavior.",
"你理解本合规提醒仅用于风险提示,不构成法律意见、合规审查结论或对你使用本系统行为合法性的保证;你应根据实际业务场景自行咨询专业法律或合规顾问。": "You understand this compliance reminder is only for risk notice and does not constitute legal advice, a compliance review conclusion, or a guarantee of the legality of your use of this system; you should consult professional legal or compliance advisors based on your actual business scenario.",
"我已阅读并理解上述合规提醒,知悉相关法律风险,并确认自行承担部署、运营和收费行为产生的法律责任": "I have read and understood the above compliance reminder, acknowledge the related legal risks, and confirm that I bear legal responsibility arising from deployment, operation, and charging behavior.",
"需要确认合规声明": "Compliance confirmation required",
"确认前,支付、兑换码、订阅计划和邀请返利功能将保持锁定。": "Payment, redemption codes, subscription plans, and invitation rewards remain locked until confirmation.",
"确认合规声明": "Confirm compliance terms",
"合规声明已确认": "Compliance confirmed",
"确认时间:{{time}},确认用户:#{{userId}}": "Confirmed at {{time}} by user #{{userId}}",
"该操作将启用支付、兑换码、订阅计划和邀请返利相关功能。请仔细阅读并确认以下声明。": "This confirmation unlocks payment, redemption code, subscription plan, and invitation reward features. Please read carefully.",
"请输入以下文字以确认:": "Please type the following text to confirm:",
"请输入确认文案": "Type the confirmation text here",
"输入内容与要求文案不一致": "The entered text does not match the required text.",
"确认并启用": "Confirm and enable",
"合规声明确认成功": "Compliance confirmed successfully",
"确认失败": "Confirmation failed",
"兑换码功能已禁用,管理员需先确认合规声明。": "Redemption codes are disabled until the administrator confirms compliance terms.",
"订阅套餐创建和变更已锁定,管理员需先在支付设置中确认合规声明。": "Subscription plan creation and changes are locked until compliance terms are confirmed in payment settings.",
"邀请奖励划转已禁用,管理员需先确认合规声明。": "Invitation reward transfer is disabled until compliance terms are confirmed.",
"设置非零邀请奖励额度前,需要先在支付设置中确认合规声明。": "Non-zero invitation rewards require compliance confirmation in payment settings.",
"非零值需先确认合规声明": "Non-zero values require compliance confirmation first",
"我已阅读并理解上述合规提醒": "I have read and understood the above compliance reminder",
"知悉相关法律风险": "acknowledge the related legal risks",
"并确认自行承担部署": "confirm that I bear legal responsibility arising from deployment",
"运营和收费行为产生的法律责任": "operation and charging behavior",
"": ", ",
"、": ", "
}
}
+31 -1
View File
@@ -3669,6 +3669,36 @@
"默认用户消息": "Здравствуйте",
"默认补全倍率": "Коэффициент завершения по умолчанию",
"阶梯计费(表达式解析失败)": "Многоуровневая тарификация (ошибка разбора выражения)",
"阶梯计费(未匹配到对应阶梯)": "Многоуровневая тарификация (подходящий уровень не найден)"
"阶梯计费(未匹配到对应阶梯)": "Многоуровневая тарификация (подходящий уровень не найден)",
"你已合法取得所接入模型 API、账号、密钥和额度的授权;": "You have legally obtained authorization for the connected model APIs, accounts, keys, and quotas.",
"你承诺仅在已取得上游服务商、模型服务提供方或相关权利方合法授权的范围内使用其 API、账号、密钥、额度及服务能力,不进行未经授权的转售、倒卖、分销或其他违规商业化使用。": "You commit to using upstream APIs, accounts, keys, quotas, and service capabilities only within the scope of lawful authorization obtained from upstream service providers, model service providers, or relevant rights holders, and will not conduct unauthorized resale, trafficking, distribution, or other non-compliant commercialization.",
"如向中华人民共和国境内公众提供生成式人工智能服务,你将依法履行备案登记、安全评估、内容安全、投诉举报、生成合成内容标识、日志留存、个人信息保护等合规义务;": "If you provide generative AI services to the public in mainland China, you will fulfill legal compliance obligations.",
"你承诺不会利用本系统实施、协助实施或变相实施违反适用法律法规、监管要求、平台规则、社会公共利益或第三方合法权益的行为。": "You commit not to use this system to implement, assist with, or indirectly implement acts that violate applicable laws and regulations, regulatory requirements, platform rules, public interests, or the lawful rights and interests of third parties.",
"你理解并自行承担部署、运营和收费行为产生的法律责任。": "You understand and independently bear legal responsibility arising from deployment, operation, and charging behavior.",
"你理解本合规提醒仅用于风险提示,不构成法律意见、合规审查结论或对你使用本系统行为合法性的保证;你应根据实际业务场景自行咨询专业法律或合规顾问。": "You understand this compliance reminder is only for risk notice and does not constitute legal advice, a compliance review conclusion, or a guarantee of the legality of your use of this system; you should consult professional legal or compliance advisors based on your actual business scenario.",
"我已阅读并理解上述合规提醒,知悉相关法律风险,并确认自行承担部署、运营和收费行为产生的法律责任": "I have read and understood the above compliance reminder, acknowledge the related legal risks, and confirm that I bear legal responsibility arising from deployment, operation, and charging behavior.",
"需要确认合规声明": "Compliance confirmation required",
"确认前,支付、兑换码、订阅计划和邀请返利功能将保持锁定。": "Payment, redemption codes, subscription plans, and invitation rewards remain locked until confirmation.",
"确认合规声明": "Confirm compliance terms",
"合规声明已确认": "Compliance confirmed",
"确认时间:{{time}},确认用户:#{{userId}}": "Confirmed at {{time}} by user #{{userId}}",
"该操作将启用支付、兑换码、订阅计划和邀请返利相关功能。请仔细阅读并确认以下声明。": "This confirmation unlocks payment, redemption code, subscription plan, and invitation reward features. Please read carefully.",
"请输入以下文字以确认:": "Please type the following text to confirm:",
"请输入确认文案": "Type the confirmation text here",
"输入内容与要求文案不一致": "The entered text does not match the required text.",
"确认并启用": "Confirm and enable",
"合规声明确认成功": "Compliance confirmed successfully",
"确认失败": "Confirmation failed",
"兑换码功能已禁用,管理员需先确认合规声明。": "Redemption codes are disabled until the administrator confirms compliance terms.",
"订阅套餐创建和变更已锁定,管理员需先在支付设置中确认合规声明。": "Subscription plan creation and changes are locked until compliance terms are confirmed in payment settings.",
"邀请奖励划转已禁用,管理员需先确认合规声明。": "Invitation reward transfer is disabled until compliance terms are confirmed.",
"设置非零邀请奖励额度前,需要先在支付设置中确认合规声明。": "Non-zero invitation rewards require compliance confirmation in payment settings.",
"非零值需先确认合规声明": "Non-zero values require compliance confirmation first",
"我已阅读并理解上述合规提醒": "I have read and understood the above compliance reminder",
"知悉相关法律风险": "acknowledge the related legal risks",
"并确认自行承担部署": "confirm that I bear legal responsibility arising from deployment",
"运营和收费行为产生的法律责任": "operation and charging behavior",
"": ", ",
"、": ", "
}
}
+31 -1
View File
@@ -4183,6 +4183,36 @@
"默认用户消息": "Xin chào",
"默认补全倍率": "Tỷ lệ hoàn thành mặc định",
"阶梯计费(表达式解析失败)": "Thanh toán theo bậc (không phân tích được biểu thức)",
"阶梯计费(未匹配到对应阶梯)": "Thanh toán theo bậc (không tìm thấy bậc phù hợp)"
"阶梯计费(未匹配到对应阶梯)": "Thanh toán theo bậc (không tìm thấy bậc phù hợp)",
"你已合法取得所接入模型 API、账号、密钥和额度的授权;": "You have legally obtained authorization for the connected model APIs, accounts, keys, and quotas.",
"你承诺仅在已取得上游服务商、模型服务提供方或相关权利方合法授权的范围内使用其 API、账号、密钥、额度及服务能力,不进行未经授权的转售、倒卖、分销或其他违规商业化使用。": "You commit to using upstream APIs, accounts, keys, quotas, and service capabilities only within the scope of lawful authorization obtained from upstream service providers, model service providers, or relevant rights holders, and will not conduct unauthorized resale, trafficking, distribution, or other non-compliant commercialization.",
"如向中华人民共和国境内公众提供生成式人工智能服务,你将依法履行备案登记、安全评估、内容安全、投诉举报、生成合成内容标识、日志留存、个人信息保护等合规义务;": "If you provide generative AI services to the public in mainland China, you will fulfill legal compliance obligations.",
"你承诺不会利用本系统实施、协助实施或变相实施违反适用法律法规、监管要求、平台规则、社会公共利益或第三方合法权益的行为。": "You commit not to use this system to implement, assist with, or indirectly implement acts that violate applicable laws and regulations, regulatory requirements, platform rules, public interests, or the lawful rights and interests of third parties.",
"你理解并自行承担部署、运营和收费行为产生的法律责任。": "You understand and independently bear legal responsibility arising from deployment, operation, and charging behavior.",
"你理解本合规提醒仅用于风险提示,不构成法律意见、合规审查结论或对你使用本系统行为合法性的保证;你应根据实际业务场景自行咨询专业法律或合规顾问。": "You understand this compliance reminder is only for risk notice and does not constitute legal advice, a compliance review conclusion, or a guarantee of the legality of your use of this system; you should consult professional legal or compliance advisors based on your actual business scenario.",
"我已阅读并理解上述合规提醒,知悉相关法律风险,并确认自行承担部署、运营和收费行为产生的法律责任": "I have read and understood the above compliance reminder, acknowledge the related legal risks, and confirm that I bear legal responsibility arising from deployment, operation, and charging behavior.",
"需要确认合规声明": "Compliance confirmation required",
"确认前,支付、兑换码、订阅计划和邀请返利功能将保持锁定。": "Payment, redemption codes, subscription plans, and invitation rewards remain locked until confirmation.",
"确认合规声明": "Confirm compliance terms",
"合规声明已确认": "Compliance confirmed",
"确认时间:{{time}},确认用户:#{{userId}}": "Confirmed at {{time}} by user #{{userId}}",
"该操作将启用支付、兑换码、订阅计划和邀请返利相关功能。请仔细阅读并确认以下声明。": "This confirmation unlocks payment, redemption code, subscription plan, and invitation reward features. Please read carefully.",
"请输入以下文字以确认:": "Please type the following text to confirm:",
"请输入确认文案": "Type the confirmation text here",
"输入内容与要求文案不一致": "The entered text does not match the required text.",
"确认并启用": "Confirm and enable",
"合规声明确认成功": "Compliance confirmed successfully",
"确认失败": "Confirmation failed",
"兑换码功能已禁用,管理员需先确认合规声明。": "Redemption codes are disabled until the administrator confirms compliance terms.",
"订阅套餐创建和变更已锁定,管理员需先在支付设置中确认合规声明。": "Subscription plan creation and changes are locked until compliance terms are confirmed in payment settings.",
"邀请奖励划转已禁用,管理员需先确认合规声明。": "Invitation reward transfer is disabled until compliance terms are confirmed.",
"设置非零邀请奖励额度前,需要先在支付设置中确认合规声明。": "Non-zero invitation rewards require compliance confirmation in payment settings.",
"非零值需先确认合规声明": "Non-zero values require compliance confirmation first",
"我已阅读并理解上述合规提醒": "I have read and understood the above compliance reminder",
"知悉相关法律风险": "acknowledge the related legal risks",
"并确认自行承担部署": "confirm that I bear legal responsibility arising from deployment",
"运营和收费行为产生的法律责任": "operation and charging behavior",
"": ", ",
"、": ", "
}
}
+31 -1
View File
@@ -3778,6 +3778,36 @@
"缓存创建-1h": "缓存创建-1h",
"见上方动态计费详情": "见上方动态计费详情",
"含时间条件": "含时间条件",
"含请求条件": "含请求条件"
"含请求条件": "含请求条件",
"你已合法取得所接入模型 API、账号、密钥和额度的授权;": "你已合法取得所接入模型 API、账号、密钥和额度的授权;",
"你承诺仅在已取得上游服务商、模型服务提供方或相关权利方合法授权的范围内使用其 API、账号、密钥、额度及服务能力,不进行未经授权的转售、倒卖、分销或其他违规商业化使用。": "你承诺仅在已取得上游服务商、模型服务提供方或相关权利方合法授权的范围内使用其 API、账号、密钥、额度及服务能力,不进行未经授权的转售、倒卖、分销或其他违规商业化使用。",
"如向中华人民共和国境内公众提供生成式人工智能服务,你将依法履行备案登记、安全评估、内容安全、投诉举报、生成合成内容标识、日志留存、个人信息保护等合规义务;": "如向中华人民共和国境内公众提供生成式人工智能服务,你将依法履行备案登记、安全评估、内容安全、投诉举报、生成合成内容标识、日志留存、个人信息保护等合规义务;",
"你承诺不会利用本系统实施、协助实施或变相实施违反适用法律法规、监管要求、平台规则、社会公共利益或第三方合法权益的行为。": "你承诺不会利用本系统实施、协助实施或变相实施违反适用法律法规、监管要求、平台规则、社会公共利益或第三方合法权益的行为。",
"你理解并自行承担部署、运营和收费行为产生的法律责任。": "你理解并自行承担部署、运营和收费行为产生的法律责任。",
"你理解本合规提醒仅用于风险提示,不构成法律意见、合规审查结论或对你使用本系统行为合法性的保证;你应根据实际业务场景自行咨询专业法律或合规顾问。": "你理解本合规提醒仅用于风险提示,不构成法律意见、合规审查结论或对你使用本系统行为合法性的保证;你应根据实际业务场景自行咨询专业法律或合规顾问。",
"我已阅读并理解上述合规提醒,知悉相关法律风险,并确认自行承担部署、运营和收费行为产生的法律责任": "我已阅读并理解上述合规提醒,知悉相关法律风险,并确认自行承担部署、运营和收费行为产生的法律责任",
"需要确认合规声明": "需要确认合规声明",
"确认前,支付、兑换码、订阅计划和邀请返利功能将保持锁定。": "确认前,支付、兑换码、订阅计划和邀请返利功能将保持锁定。",
"确认合规声明": "确认合规声明",
"合规声明已确认": "合规声明已确认",
"确认时间:{{time}},确认用户:#{{userId}}": "确认时间:{{time}},确认用户:#{{userId}}",
"该操作将启用支付、兑换码、订阅计划和邀请返利相关功能。请仔细阅读并确认以下声明。": "该操作将启用支付、兑换码、订阅计划和邀请返利相关功能。请仔细阅读并确认以下声明。",
"请输入以下文字以确认:": "请输入以下文字以确认:",
"请输入确认文案": "请输入确认文案",
"输入内容与要求文案不一致": "输入内容与要求文案不一致",
"确认并启用": "确认并启用",
"合规声明确认成功": "合规声明确认成功",
"确认失败": "确认失败",
"兑换码功能已禁用,管理员需先确认合规声明。": "兑换码功能已禁用,管理员需先确认合规声明。",
"订阅套餐创建和变更已锁定,管理员需先在支付设置中确认合规声明。": "订阅套餐创建和变更已锁定,管理员需先在支付设置中确认合规声明。",
"邀请奖励划转已禁用,管理员需先确认合规声明。": "邀请奖励划转已禁用,管理员需先确认合规声明。",
"设置非零邀请奖励额度前,需要先在支付设置中确认合规声明。": "设置非零邀请奖励额度前,需要先在支付设置中确认合规声明。",
"非零值需先确认合规声明": "非零值需先确认合规声明",
"我已阅读并理解上述合规提醒": "我已阅读并理解上述合规提醒",
"知悉相关法律风险": "知悉相关法律风险",
"并确认自行承担部署": "并确认自行承担部署",
"运营和收费行为产生的法律责任": "运营和收费行为产生的法律责任",
"": "",
"、": "、"
}
}
+31 -1
View File
@@ -3642,6 +3642,36 @@
"默认用户消息": "你好",
"默认补全倍率": "預設補全倍率",
"阶梯计费(表达式解析失败)": "階梯計費(表達式解析失敗)",
"阶梯计费(未匹配到对应阶梯)": "階梯計費(未匹配到對應階梯)"
"阶梯计费(未匹配到对应阶梯)": "階梯計費(未匹配到對應階梯)",
"你已合法取得所接入模型 API、账号、密钥和额度的授权;": "你已合法取得所接入模型 API、账号、密钥和额度的授权;",
"你承诺仅在已取得上游服务商、模型服务提供方或相关权利方合法授权的范围内使用其 API、账号、密钥、额度及服务能力,不进行未经授权的转售、倒卖、分销或其他违规商业化使用。": "你承諾僅在已取得上游服務商、模型服務提供方或相關權利方合法授權的範圍內使用其 API、帳號、金鑰、額度及服務能力,不進行未經授權的轉售、倒賣、分銷或其他違規商業化使用。",
"如向中华人民共和国境内公众提供生成式人工智能服务,你将依法履行备案登记、安全评估、内容安全、投诉举报、生成合成内容标识、日志留存、个人信息保护等合规义务;": "如向中华人民共和国境内公众提供生成式人工智能服务,你将依法履行备案登记、安全评估、内容安全、投诉举报、生成合成内容标识、日志留存、个人信息保护等合规义务;",
"你承诺不会利用本系统实施、协助实施或变相实施违反适用法律法规、监管要求、平台规则、社会公共利益或第三方合法权益的行为。": "你承諾不會利用本系統實施、協助實施或變相實施違反適用法律法規、監管要求、平台規則、社會公共利益或第三方合法權益的行為。",
"你理解并自行承担部署、运营和收费行为产生的法律责任。": "你理解并自行承担部署、运营和收费行为产生的法律责任。",
"你理解本合规提醒仅用于风险提示,不构成法律意见、合规审查结论或对你使用本系统行为合法性的保证;你应根据实际业务场景自行咨询专业法律或合规顾问。": "你理解本合規提醒僅用於風險提示,不構成法律意見、合規審查結論或對你使用本系統行為合法性的保證;你應根據實際業務場景自行諮詢專業法律或合規顧問。",
"我已阅读并理解上述合规提醒,知悉相关法律风险,并确认自行承担部署、运营和收费行为产生的法律责任": "我已閱讀並理解上述合規提醒,知悉相關法律風險,並確認自行承擔部署、營運和收費行為產生的法律責任",
"需要确认合规声明": "需要确认合规声明",
"确认前,支付、兑换码、订阅计划和邀请返利功能将保持锁定。": "确认前,支付、兑换码、订阅计划和邀请返利功能将保持锁定。",
"确认合规声明": "确认合规声明",
"合规声明已确认": "合规声明已确认",
"确认时间:{{time}},确认用户:#{{userId}}": "确认时间:{{time}},确认用户:#{{userId}}",
"该操作将启用支付、兑换码、订阅计划和邀请返利相关功能。请仔细阅读并确认以下声明。": "该操作将启用支付、兑换码、订阅计划和邀请返利相关功能。请仔细阅读并确认以下声明。",
"请输入以下文字以确认:": "请输入以下文字以确认:",
"请输入确认文案": "请输入确认文案",
"输入内容与要求文案不一致": "输入内容与要求文案不一致",
"确认并启用": "确认并启用",
"合规声明确认成功": "合规声明确认成功",
"确认失败": "确认失败",
"兑换码功能已禁用,管理员需先确认合规声明。": "兑换码功能已禁用,管理员需先确认合规声明。",
"订阅套餐创建和变更已锁定,管理员需先在支付设置中确认合规声明。": "订阅套餐创建和变更已锁定,管理员需先在支付设置中确认合规声明。",
"邀请奖励划转已禁用,管理员需先确认合规声明。": "邀请奖励划转已禁用,管理员需先确认合规声明。",
"设置非零邀请奖励额度前,需要先在支付设置中确认合规声明。": "设置非零邀请奖励额度前,需要先在支付设置中确认合规声明。",
"非零值需先确认合规声明": "非零值需先确认合规声明",
"我已阅读并理解上述合规提醒": "我已閱讀並理解上述合規提醒",
"知悉相关法律风险": "知悉相關法律風險",
"并确认自行承担部署": "並確認自行承擔部署",
"运营和收费行为产生的法律责任": "營運和收費行為產生的法律責任",
"": "",
"、": "、"
}
}
+31 -2
View File
@@ -2561,7 +2561,6 @@
"默认补全倍率": "默认补全倍率",
"每日签到": "每日签到",
"今日已签到,累计签到": "今日已签到,累计签到",
"天": "天",
"每日签到可获得随机额度奖励": "每日签到可获得随机额度奖励",
"今日已签到": "今日已签到",
"立即签到": "立即签到",
@@ -2595,6 +2594,36 @@
"说明:本页测试为非流式请求;若渠道仅支持流式返回,可能出现测试失败,请以实际使用为准。": "说明:本页测试为非流式请求;若渠道仅支持流式返回,可能出现测试失败,请以实际使用为准。",
"提示:端点映射仅用于模型广场展示,不会影响模型真实调用。如需配置真实调用,请前往「渠道管理」。": "提示:端点映射仅用于模型广场展示,不会影响模型真实调用。如需配置真实调用,请前往「渠道管理」。",
"阶梯计费(表达式解析失败)": "阶梯计费(表达式解析失败)",
"阶梯计费(未匹配到对应阶梯)": "阶梯计费(未匹配到对应阶梯)"
"阶梯计费(未匹配到对应阶梯)": "阶梯计费(未匹配到对应阶梯)",
"你已合法取得所接入模型 API、账号、密钥和额度的授权;": "你已合法取得所接入模型 API、账号、密钥和额度的授权;",
"你承诺仅在已取得上游服务商、模型服务提供方或相关权利方合法授权的范围内使用其 API、账号、密钥、额度及服务能力,不进行未经授权的转售、倒卖、分销或其他违规商业化使用。": "你承诺仅在已取得上游服务商、模型服务提供方或相关权利方合法授权的范围内使用其 API、账号、密钥、额度及服务能力,不进行未经授权的转售、倒卖、分销或其他违规商业化使用。",
"如向中华人民共和国境内公众提供生成式人工智能服务,你将依法履行备案登记、安全评估、内容安全、投诉举报、生成合成内容标识、日志留存、个人信息保护等合规义务;": "如向中华人民共和国境内公众提供生成式人工智能服务,你将依法履行备案登记、安全评估、内容安全、投诉举报、生成合成内容标识、日志留存、个人信息保护等合规义务;",
"你承诺不会利用本系统实施、协助实施或变相实施违反适用法律法规、监管要求、平台规则、社会公共利益或第三方合法权益的行为。": "你承诺不会利用本系统实施、协助实施或变相实施违反适用法律法规、监管要求、平台规则、社会公共利益或第三方合法权益的行为。",
"你理解并自行承担部署、运营和收费行为产生的法律责任。": "你理解并自行承担部署、运营和收费行为产生的法律责任。",
"你理解本合规提醒仅用于风险提示,不构成法律意见、合规审查结论或对你使用本系统行为合法性的保证;你应根据实际业务场景自行咨询专业法律或合规顾问。": "你理解本合规提醒仅用于风险提示,不构成法律意见、合规审查结论或对你使用本系统行为合法性的保证;你应根据实际业务场景自行咨询专业法律或合规顾问。",
"我已阅读并理解上述合规提醒,知悉相关法律风险,并确认自行承担部署、运营和收费行为产生的法律责任": "我已阅读并理解上述合规提醒,知悉相关法律风险,并确认自行承担部署、运营和收费行为产生的法律责任",
"需要确认合规声明": "需要确认合规声明",
"确认前,支付、兑换码、订阅计划和邀请返利功能将保持锁定。": "确认前,支付、兑换码、订阅计划和邀请返利功能将保持锁定。",
"确认合规声明": "确认合规声明",
"合规声明已确认": "合规声明已确认",
"确认时间:{{time}},确认用户:#{{userId}}": "确认时间:{{time}},确认用户:#{{userId}}",
"该操作将启用支付、兑换码、订阅计划和邀请返利相关功能。请仔细阅读并确认以下声明。": "该操作将启用支付、兑换码、订阅计划和邀请返利相关功能。请仔细阅读并确认以下声明。",
"请输入以下文字以确认:": "请输入以下文字以确认:",
"请输入确认文案": "请输入确认文案",
"输入内容与要求文案不一致": "输入内容与要求文案不一致",
"确认并启用": "确认并启用",
"合规声明确认成功": "合规声明确认成功",
"确认失败": "确认失败",
"兑换码功能已禁用,管理员需先确认合规声明。": "兑换码功能已禁用,管理员需先确认合规声明。",
"订阅套餐创建和变更已锁定,管理员需先在支付设置中确认合规声明。": "订阅套餐创建和变更已锁定,管理员需先在支付设置中确认合规声明。",
"邀请奖励划转已禁用,管理员需先确认合规声明。": "邀请奖励划转已禁用,管理员需先确认合规声明。",
"设置非零邀请奖励额度前,需要先在支付设置中确认合规声明。": "设置非零邀请奖励额度前,需要先在支付设置中确认合规声明。",
"非零值需先确认合规声明": "非零值需先确认合规声明",
"我已阅读并理解上述合规提醒": "我已阅读并理解上述合规提醒",
"知悉相关法律风险": "知悉相关法律风险",
"并确认自行承担部署": "并确认自行承担部署",
"运营和收费行为产生的法律责任": "运营和收费行为产生的法律责任",
"": "",
"、": "、"
}
}
@@ -18,7 +18,7 @@ For commercial licensing, please contact support@quantumnous.com
*/
import React, { useEffect, useState, useRef } from 'react';
import { Button, Col, Form, Row, Spin } from '@douyinfe/semi-ui';
import { Banner, Button, Col, Form, Row, Spin } from '@douyinfe/semi-ui';
import { useTranslation } from 'react-i18next';
import {
compareObjects,
@@ -40,6 +40,9 @@ export default function SettingsCreditLimit(props) {
});
const refForm = useRef();
const [inputsRow, setInputsRow] = useState(inputs);
const complianceConfirmed =
props.options?.['payment_setting.compliance_confirmed'] === true ||
props.options?.['payment_setting.compliance_confirmed'] === 'true';
function onSubmit() {
const updateArray = compareObjects(inputs, inputsRow);
@@ -90,6 +93,16 @@ export default function SettingsCreditLimit(props) {
return (
<>
<Spin spinning={loading}>
{!complianceConfirmed && (
<Banner
type='warning'
description={t(
'设置非零邀请奖励额度前,需要先在支付设置中确认合规声明。',
)}
closeIcon={null}
className='!rounded-lg mb-3'
/>
)}
<Form
values={inputs}
getFormApi={(formAPI) => (refForm.current = formAPI)}
@@ -137,7 +150,9 @@ export default function SettingsCreditLimit(props) {
step={1}
min={0}
suffix={'Token'}
extraText={''}
extraText={
!complianceConfirmed ? t('非零值需先确认合规声明') : ''
}
placeholder={t('例如:2000')}
onChange={(value) =>
setInputs({
@@ -156,7 +171,9 @@ export default function SettingsCreditLimit(props) {
step={1}
min={0}
suffix={'Token'}
extraText={''}
extraText={
!complianceConfirmed ? t('非零值需先确认合规声明') : ''
}
placeholder={t('例如:1000')}
onChange={(value) =>
setInputs({