From 113b9c8ecb4591091fa730d5a6f104491f99ac7b Mon Sep 17 00:00:00 2001 From: admin Date: Sun, 14 Jun 2026 21:20:47 +0800 Subject: [PATCH] fix: unify light/dark primary color, fix doc management API, remove compliance restriction --- controller/document.go | 22 ++- model/document.go | 25 +++ .../components/settings/PaymentSetting.jsx | 148 +--------------- .../subscriptions/SubscriptionsColumnDefs.jsx | 7 +- .../subscriptions/SubscriptionsTable.jsx | 4 +- .../components/table/subscriptions/index.jsx | 29 --- .../src/components/topup/InvitationCard.jsx | 12 -- web/classic/src/components/topup/index.jsx | 1 - .../Setting/Operation/SettingsCreditLimit.jsx | 19 -- .../src/features/doc-categories/index.tsx | 2 +- .../src/features/docs-management/index.tsx | 4 +- web/default/src/features/pricing/index.tsx | 49 +++-- .../components/data-table-row-actions.tsx | 4 +- .../subscriptions-primary-buttons.tsx | 3 +- .../components/subscriptions-provider.tsx | 17 -- .../src/features/subscriptions/index.tsx | 10 -- .../system-settings/billing/index.tsx | 5 - .../billing/section-registry.tsx | 11 -- .../general/quota-settings-section.tsx | 12 -- .../integrations/payment-settings-section.tsx | 167 +----------------- .../components/affiliate-rewards-card.tsx | 10 -- web/default/src/features/wallet/index.tsx | 3 - web/default/src/i18n/static-keys.ts | 1 + web/default/src/styles/theme.css | 10 +- 24 files changed, 90 insertions(+), 485 deletions(-) diff --git a/controller/document.go b/controller/document.go index b42ad5bed..ee196893e 100644 --- a/controller/document.go +++ b/controller/document.go @@ -89,25 +89,31 @@ func GetDocuments(c *gin.Context) { } } + pageInfo := common.GetPageQuery(c) + // 根据用户认证状态决定可见性过滤 visibility := c.Query("visibility") role := c.GetInt("role") + + var documents []*model.Document + var total int64 + var err error + if role >= common.RoleAdminUser { - // 管理员可看所有,如果指定了 visibility 则按指定值过滤 - // visibility 保持原值 + // 管理员可看所有 + documents, total, err = model.GetDocuments(keyword, visibility, categoryId, pageInfo.GetStartIdx(), pageInfo.GetPageSize()) } else if role >= common.RoleCommonUser { // 普通用户只能看 public 和 auth - if visibility == "admin" { - visibility = "" // 不允许看 admin + if visibility == "public" || visibility == "auth" { + documents, total, err = model.GetDocuments(keyword, visibility, categoryId, pageInfo.GetStartIdx(), pageInfo.GetPageSize()) + } else { + documents, total, err = model.GetDocumentsByVisibility(keyword, []string{"public", "auth"}, categoryId, pageInfo.GetStartIdx(), pageInfo.GetPageSize()) } - // 如果没有指定 visibility,则过滤出 public 和 auth } else { // 未登录用户只能看 public - visibility = "public" + documents, total, err = model.GetDocuments(keyword, "public", categoryId, pageInfo.GetStartIdx(), pageInfo.GetPageSize()) } - pageInfo := common.GetPageQuery(c) - documents, total, err := model.GetDocuments(keyword, visibility, categoryId, pageInfo.GetStartIdx(), pageInfo.GetPageSize()) if err != nil { common.ApiError(c, err) return diff --git a/model/document.go b/model/document.go index 78c61bd8b..b74c6df9e 100644 --- a/model/document.go +++ b/model/document.go @@ -40,6 +40,29 @@ func GetDocuments(keyword string, visibility string, categoryId *int, startIdx i return documents, total, nil } +func GetDocumentsByVisibility(keyword string, visibilities []string, categoryId *int, startIdx int, num int) ([]*Document, int64, error) { + query := DB.Model(&Document{}) + if keyword != "" { + like := "%" + keyword + "%" + query = query.Where("title LIKE ? OR content LIKE ?", like, like) + } + if len(visibilities) > 0 { + query = query.Where("visibility IN ?", visibilities) + } + if categoryId != nil { + query = query.Where("category_id = ?", *categoryId) + } + var total int64 + if err := query.Count(&total).Error; err != nil { + return nil, 0, err + } + var documents []*Document + if err := query.Order("sort_order ASC, id DESC").Offset(startIdx).Limit(num).Find(&documents).Error; err != nil { + return nil, 0, err + } + return documents, total, nil +} + func GetDocumentBySlug(slug string) (*Document, error) { var doc Document err := DB.Where("slug = ?", slug).First(&doc).Error @@ -67,5 +90,7 @@ func UpdateDocument(doc *Document) error { } func DeleteDocument(id int) error { + // Delete associated versions first + DB.Where("document_id = ?", id).Delete(&DocumentVersion{}) return DB.Delete(&Document{}, id).Error } diff --git a/web/classic/src/components/settings/PaymentSetting.jsx b/web/classic/src/components/settings/PaymentSetting.jsx index 7e75b483f..d119064c7 100644 --- a/web/classic/src/components/settings/PaymentSetting.jsx +++ b/web/classic/src/components/settings/PaymentSetting.jsx @@ -26,9 +26,6 @@ import SettingsPaymentGatewayCreem from '../../pages/Setting/Payment/SettingsPay import SettingsPaymentGatewayWaffo from '../../pages/Setting/Payment/SettingsPaymentGatewayWaffo'; 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(); @@ -51,60 +48,9 @@ const PaymentSetting = () => { StripeUnitPrice: 8.0, StripeMinTopUp: 1, StripePromotionCodesEnabled: false, - - '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/'); @@ -146,16 +92,6 @@ 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': @@ -193,76 +129,11 @@ 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 ( <> - {!complianceConfirmed ? ( - - - {t( - '确认前,支付、兑换码、订阅计划和邀请返利功能将保持锁定。', - )} - - - - } - closeIcon={null} - style={{ marginBottom: 16 }} - fullMode={false} - /> - ) : ( - - )} -
+
{
- setComplianceVisible(false)} - onConfirm={confirmCompliance} - /> ); diff --git a/web/classic/src/components/table/subscriptions/SubscriptionsColumnDefs.jsx b/web/classic/src/components/table/subscriptions/SubscriptionsColumnDefs.jsx index 6161cc1f3..fff173486 100644 --- a/web/classic/src/components/table/subscriptions/SubscriptionsColumnDefs.jsx +++ b/web/classic/src/components/table/subscriptions/SubscriptionsColumnDefs.jsx @@ -231,7 +231,7 @@ const renderPaymentConfig = (text, record, t, enableEpay) => { const renderOperations = ( text, record, - { openEdit, setPlanEnabled, t, complianceConfirmed }, + { openEdit, setPlanEnabled, t }, ) => { const isEnabled = record?.plan?.enabled; @@ -260,7 +260,6 @@ const renderOperations = ( type='tertiary' size='small' onClick={() => openEdit(record)} - disabled={!complianceConfirmed} > {t('编辑')} @@ -270,7 +269,6 @@ const renderOperations = ( type='danger' size='small' onClick={handleToggle} - disabled={!complianceConfirmed} > {t('禁用')} @@ -280,7 +278,6 @@ const renderOperations = ( type='primary' size='small' onClick={handleToggle} - disabled={!complianceConfirmed} > {t('启用')} @@ -294,7 +291,6 @@ export const getSubscriptionsColumns = ({ openEdit, setPlanEnabled, enableEpay, - complianceConfirmed = true, }) => { return [ { @@ -368,7 +364,6 @@ export const getSubscriptionsColumns = ({ openEdit, setPlanEnabled, t, - complianceConfirmed, }), }, ]; diff --git a/web/classic/src/components/table/subscriptions/SubscriptionsTable.jsx b/web/classic/src/components/table/subscriptions/SubscriptionsTable.jsx index e4789f740..8efc7ff8a 100644 --- a/web/classic/src/components/table/subscriptions/SubscriptionsTable.jsx +++ b/web/classic/src/components/table/subscriptions/SubscriptionsTable.jsx @@ -35,7 +35,6 @@ const SubscriptionsTable = (subscriptionsData) => { setPlanEnabled, t, enableEpay, - complianceConfirmed, } = subscriptionsData; const columns = useMemo(() => { @@ -44,9 +43,8 @@ const SubscriptionsTable = (subscriptionsData) => { openEdit, setPlanEnabled, enableEpay, - complianceConfirmed, }); - }, [t, openEdit, setPlanEnabled, enableEpay, complianceConfirmed]); + }, [t, openEdit, setPlanEnabled, enableEpay]); const tableColumns = useMemo(() => { return compactMode diff --git a/web/classic/src/components/table/subscriptions/index.jsx b/web/classic/src/components/table/subscriptions/index.jsx index 187d15a67..e6e78e5a9 100644 --- a/web/classic/src/components/table/subscriptions/index.jsx +++ b/web/classic/src/components/table/subscriptions/index.jsx @@ -35,7 +35,6 @@ const SubscriptionsPage = () => { const isMobile = useIsMobile(); const [statusState] = useContext(StatusContext); const enableEpay = !!statusState?.status?.enable_online_topup; - const [complianceConfirmed, setComplianceConfirmed] = useState(true); const { showEdit, @@ -49,22 +48,6 @@ 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 ( <> {
{ })} t={t} > - {!complianceConfirmed && ( - - )} diff --git a/web/classic/src/components/topup/InvitationCard.jsx b/web/classic/src/components/topup/InvitationCard.jsx index 3e9bc7332..813c6fbb7 100644 --- a/web/classic/src/components/topup/InvitationCard.jsx +++ b/web/classic/src/components/topup/InvitationCard.jsx @@ -38,7 +38,6 @@ const InvitationCard = ({ setOpenTransfer, affLink, handleAffLinkClick, - complianceConfirmed = true, }) => { return ( @@ -82,7 +81,6 @@ const InvitationCard = ({ theme='solid' size='small' disabled={ - !complianceConfirmed || !userState?.user?.aff_quota || userState?.user?.aff_quota <= 0 } @@ -93,16 +91,6 @@ const InvitationCard = ({ {t('划转到余额')} - {!complianceConfirmed && ( - - {t('邀请奖励划转已禁用,管理员需先确认合规声明。')} - - )} {/* 统计数据 */}
diff --git a/web/classic/src/components/topup/index.jsx b/web/classic/src/components/topup/index.jsx index 49b6dc1ba..d4228e089 100644 --- a/web/classic/src/components/topup/index.jsx +++ b/web/classic/src/components/topup/index.jsx @@ -1024,7 +1024,6 @@ const TopUp = () => { setOpenTransfer={setOpenTransfer} affLink={affLink} handleAffLinkClick={handleAffLinkClick} - complianceConfirmed={topupInfo.payment_compliance_confirmed !== false} />
diff --git a/web/classic/src/pages/Setting/Operation/SettingsCreditLimit.jsx b/web/classic/src/pages/Setting/Operation/SettingsCreditLimit.jsx index ecdfaadf8..d1910ac6a 100644 --- a/web/classic/src/pages/Setting/Operation/SettingsCreditLimit.jsx +++ b/web/classic/src/pages/Setting/Operation/SettingsCreditLimit.jsx @@ -40,9 +40,6 @@ 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); @@ -93,16 +90,6 @@ export default function SettingsCreditLimit(props) { return ( <> - {!complianceConfirmed && ( - - )}
(refForm.current = formAPI)} @@ -150,9 +137,6 @@ export default function SettingsCreditLimit(props) { step={1} min={0} suffix={'Token'} - extraText={ - !complianceConfirmed ? t('非零值需先确认合规声明') : '' - } placeholder={t('例如:2000')} onChange={(value) => setInputs({ @@ -171,9 +155,6 @@ export default function SettingsCreditLimit(props) { step={1} min={0} suffix={'Token'} - extraText={ - !complianceConfirmed ? t('非零值需先确认合规声明') : '' - } placeholder={t('例如:1000')} onChange={(value) => setInputs({ diff --git a/web/default/src/features/doc-categories/index.tsx b/web/default/src/features/doc-categories/index.tsx index 558edecd6..a61eddebc 100644 --- a/web/default/src/features/doc-categories/index.tsx +++ b/web/default/src/features/doc-categories/index.tsx @@ -49,7 +49,7 @@ export function DocCategories() { const fetchCategories = useCallback(async () => { try { setLoading(true) - const res = await api.get('/api/docs/admin/categories') + const res = await api.get('/api/docs/categories') setCategories(res.data?.data || []) } catch (err) { console.error('Failed to fetch categories:', err) diff --git a/web/default/src/features/docs-management/index.tsx b/web/default/src/features/docs-management/index.tsx index ae9408d42..4c5cfdfe8 100644 --- a/web/default/src/features/docs-management/index.tsx +++ b/web/default/src/features/docs-management/index.tsx @@ -69,8 +69,8 @@ export function DocsManagement() { try { setLoading(true) const [docsRes, catsRes] = await Promise.all([ - api.get('/api/docs/admin/'), - api.get('/api/docs/admin/categories'), + api.get('/api/docs/'), + api.get('/api/docs/categories'), ]) setDocs(docsRes.data?.data || []) setCategories(catsRes.data?.data || []) diff --git a/web/default/src/features/pricing/index.tsx b/web/default/src/features/pricing/index.tsx index b19922859..798564b7e 100644 --- a/web/default/src/features/pricing/index.tsx +++ b/web/default/src/features/pricing/index.tsx @@ -148,8 +148,19 @@ export function Pricing() { if (isLoading) { return ( -
- +
+
+
+ +
) @@ -158,25 +169,33 @@ export function Pricing() { return (
+ {/* Background effects matching home page */}
+
+ - {/* Header */} -
-

- {t('Model Square')} + {/* Header - matching home page hero style */} +
+

+ {t('Model Square')}{' '} + {t('Pricing')}

-

+

{t('This site currently has {{count}} models enabled', { count: models?.length || 0, })} @@ -184,7 +203,7 @@ export function Pricing() {

{/* Search + Filters */} -
+
@@ -46,7 +46,6 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) { { setCurrentRow(row.original) setOpen('update') @@ -56,7 +55,6 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) { {t('Edit')} { setCurrentRow(row.original) setOpen('toggle-status') diff --git a/web/default/src/features/subscriptions/components/subscriptions-primary-buttons.tsx b/web/default/src/features/subscriptions/components/subscriptions-primary-buttons.tsx index 65367878f..fc4a4ddeb 100644 --- a/web/default/src/features/subscriptions/components/subscriptions-primary-buttons.tsx +++ b/web/default/src/features/subscriptions/components/subscriptions-primary-buttons.tsx @@ -23,13 +23,12 @@ import { useSubscriptions } from './subscriptions-provider' export function SubscriptionsPrimaryButtons() { const { t } = useTranslation() - const { setOpen, complianceConfirmed } = useSubscriptions() + const { setOpen } = useSubscriptions() return (
- - - ) : ( - - {t('Compliance confirmed')} - - {t('Confirmed at {{time}} by user #{{userId}}', { - time: complianceDefaults.confirmedAt - ? new Date( - complianceDefaults.confirmedAt * 1000 - ).toLocaleString() - : '-', - userId: complianceDefaults.confirmedBy || '-', - })} - - - )} - - confirmComplianceMutation.mutate()} - /> - void - complianceConfirmed?: boolean loading?: boolean } @@ -38,7 +37,6 @@ export function AffiliateRewardsCard({ user, affiliateLink, onTransfer, - complianceConfirmed = true, loading, }: AffiliateRewardsCardProps) { const { t } = useTranslation() @@ -112,7 +110,6 @@ export function AffiliateRewardsCard({ {hasRewards && ( )}
- {!complianceConfirmed ? ( -

- {t( - 'Referral reward transfer is disabled until the administrator confirms compliance terms.' - )} -

- ) : null} ) diff --git a/web/default/src/features/wallet/index.tsx b/web/default/src/features/wallet/index.tsx index e1a7e1733..31248376c 100644 --- a/web/default/src/features/wallet/index.tsx +++ b/web/default/src/features/wallet/index.tsx @@ -318,9 +318,6 @@ export function Wallet(props: WalletProps) { user={user} affiliateLink={affiliateLink} onTransfer={() => setTransferDialogOpen(true)} - complianceConfirmed={ - topupInfo?.payment_compliance_confirmed !== false - } loading={affiliateLoading} />
diff --git a/web/default/src/i18n/static-keys.ts b/web/default/src/i18n/static-keys.ts index 9a5b0268a..0d56fe74c 100644 --- a/web/default/src/i18n/static-keys.ts +++ b/web/default/src/i18n/static-keys.ts @@ -23,6 +23,7 @@ export const STATIC_I18N_KEYS = [ 'Home', 'Console', 'Model Square', + 'Pricing', 'Rankings', 'Docs', 'About', diff --git a/web/default/src/styles/theme.css b/web/default/src/styles/theme.css index 69e3beb7a..07bd66077 100644 --- a/web/default/src/styles/theme.css +++ b/web/default/src/styles/theme.css @@ -107,7 +107,7 @@ For commercial licensing, please contact admin@modelstoken.com --card-foreground: oklch(0.13 0.028 270); --popover: oklch(1 0 0); --popover-foreground: oklch(0.13 0.028 270); - --primary: oklch(0.55 0.15 240); + --primary: oklch(0.78 0.15 210); --primary-foreground: oklch(0.995 0 0); --secondary: oklch(0.96 0.005 260); --secondary-foreground: oklch(0.18 0.02 270); @@ -127,20 +127,20 @@ For commercial licensing, please contact admin@modelstoken.com --neutral-foreground: oklch(0.995 0 0); --border: oklch(0.92 0.003 260); --input: oklch(0.92 0.003 260); - --ring: oklch(0.55 0.15 240); - --chart-1: oklch(0.55 0.15 240); + --ring: oklch(0.78 0.15 210); + --chart-1: oklch(0.78 0.15 210); --chart-2: oklch(0.596 0.145 163.225); --chart-3: oklch(0.681 0.162 75.834); --chart-4: oklch(0.627 0.265 303.9); --chart-5: oklch(0.645 0.246 16.439); --sidebar: oklch(0.975 0.003 260); --sidebar-foreground: oklch(0.13 0.028 270); - --sidebar-primary: oklch(0.55 0.15 240); + --sidebar-primary: oklch(0.78 0.15 210); --sidebar-primary-foreground: oklch(0.995 0 0); --sidebar-accent: oklch(0.94 0.008 260); --sidebar-accent-foreground: oklch(0.13 0.028 270); --sidebar-border: oklch(0.92 0.003 260); - --sidebar-ring: oklch(0.55 0.15 240); + --sidebar-ring: oklch(0.78 0.15 210); --skeleton-base: oklch(0.96 0.005 260); --skeleton-highlight: oklch(0.995 0 0); }