| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | import React, { useEffect, useState, useContext } from 'react'; |
| | import { |
| | Button, |
| | Card, |
| | Col, |
| | Form, |
| | Row, |
| | Switch, |
| | Typography, |
| | } from '@douyinfe/semi-ui'; |
| | import { API, showError, showSuccess } from '../../../helpers'; |
| | import { useTranslation } from 'react-i18next'; |
| | import { StatusContext } from '../../../context/Status'; |
| |
|
| | const { Text } = Typography; |
| |
|
| | export default function SettingsHeaderNavModules(props) { |
| | const { t } = useTranslation(); |
| | const [loading, setLoading] = useState(false); |
| | const [statusState, statusDispatch] = useContext(StatusContext); |
| |
|
| | |
| | const [headerNavModules, setHeaderNavModules] = useState({ |
| | home: true, |
| | console: true, |
| | pricing: { |
| | enabled: true, |
| | requireAuth: false, |
| | }, |
| | docs: true, |
| | about: true, |
| | }); |
| |
|
| | |
| | function handleHeaderNavModuleChange(moduleKey) { |
| | return (checked) => { |
| | const newModules = { ...headerNavModules }; |
| | if (moduleKey === 'pricing') { |
| | |
| | newModules[moduleKey] = { |
| | ...newModules[moduleKey], |
| | enabled: checked, |
| | }; |
| | } else { |
| | newModules[moduleKey] = checked; |
| | } |
| | setHeaderNavModules(newModules); |
| | }; |
| | } |
| |
|
| | |
| | function handlePricingAuthChange(checked) { |
| | const newModules = { ...headerNavModules }; |
| | newModules.pricing = { |
| | ...newModules.pricing, |
| | requireAuth: checked, |
| | }; |
| | setHeaderNavModules(newModules); |
| | } |
| |
|
| | |
| | function resetHeaderNavModules() { |
| | const defaultModules = { |
| | home: true, |
| | console: true, |
| | pricing: { |
| | enabled: true, |
| | requireAuth: false, |
| | }, |
| | docs: true, |
| | about: true, |
| | }; |
| | setHeaderNavModules(defaultModules); |
| | showSuccess(t('已重置为默认配置')); |
| | } |
| |
|
| | |
| | async function onSubmit() { |
| | setLoading(true); |
| | try { |
| | const res = await API.put('/api/option/', { |
| | key: 'HeaderNavModules', |
| | value: JSON.stringify(headerNavModules), |
| | }); |
| | const { success, message } = res.data; |
| | if (success) { |
| | showSuccess(t('保存成功')); |
| |
|
| | |
| | statusDispatch({ |
| | type: 'set', |
| | payload: { |
| | ...statusState.status, |
| | HeaderNavModules: JSON.stringify(headerNavModules), |
| | }, |
| | }); |
| |
|
| | |
| | if (props.refresh) { |
| | await props.refresh(); |
| | } |
| | } else { |
| | showError(message); |
| | } |
| | } catch (error) { |
| | showError(t('保存失败,请重试')); |
| | } finally { |
| | setLoading(false); |
| | } |
| | } |
| |
|
| | useEffect(() => { |
| | |
| | if (props.options && props.options.HeaderNavModules) { |
| | try { |
| | const modules = JSON.parse(props.options.HeaderNavModules); |
| |
|
| | |
| | if (typeof modules.pricing === 'boolean') { |
| | modules.pricing = { |
| | enabled: modules.pricing, |
| | requireAuth: false, |
| | }; |
| | } |
| |
|
| | setHeaderNavModules(modules); |
| | } catch (error) { |
| | |
| | const defaultModules = { |
| | home: true, |
| | console: true, |
| | pricing: { |
| | enabled: true, |
| | requireAuth: false, |
| | }, |
| | docs: true, |
| | about: true, |
| | }; |
| | setHeaderNavModules(defaultModules); |
| | } |
| | } |
| | }, [props.options]); |
| |
|
| | |
| | const moduleConfigs = [ |
| | { |
| | key: 'home', |
| | title: t('首页'), |
| | description: t('用户主页,展示系统信息'), |
| | }, |
| | { |
| | key: 'console', |
| | title: t('控制台'), |
| | description: t('用户控制面板,管理账户'), |
| | }, |
| | { |
| | key: 'pricing', |
| | title: t('模型广场'), |
| | description: t('模型定价,需要登录访问'), |
| | hasSubConfig: true, |
| | }, |
| | { |
| | key: 'docs', |
| | title: t('文档'), |
| | description: t('系统文档和帮助信息'), |
| | }, |
| | { |
| | key: 'about', |
| | title: t('关于'), |
| | description: t('关于系统的详细信息'), |
| | }, |
| | ]; |
| |
|
| | return ( |
| | <Card> |
| | <Form.Section |
| | text={t('顶栏管理')} |
| | extraText={t('控制顶栏模块显示状态,全局生效')} |
| | > |
| | <Row gutter={[16, 16]} style={{ marginBottom: '24px' }}> |
| | {moduleConfigs.map((module) => ( |
| | <Col key={module.key} xs={24} sm={12} md={6} lg={6} xl={6}> |
| | <Card |
| | style={{ |
| | borderRadius: '8px', |
| | border: '1px solid var(--semi-color-border)', |
| | transition: 'all 0.2s ease', |
| | background: 'var(--semi-color-bg-1)', |
| | minHeight: '80px', |
| | }} |
| | bodyStyle={{ padding: '16px' }} |
| | hoverable |
| | > |
| | <div |
| | style={{ |
| | display: 'flex', |
| | justifyContent: 'space-between', |
| | alignItems: 'center', |
| | height: '100%', |
| | }} |
| | > |
| | <div style={{ flex: 1, textAlign: 'left' }}> |
| | <div |
| | style={{ |
| | fontWeight: '600', |
| | fontSize: '14px', |
| | color: 'var(--semi-color-text-0)', |
| | marginBottom: '4px', |
| | }} |
| | > |
| | {module.title} |
| | </div> |
| | <Text |
| | type='secondary' |
| | size='small' |
| | style={{ |
| | fontSize: '12px', |
| | color: 'var(--semi-color-text-2)', |
| | lineHeight: '1.4', |
| | display: 'block', |
| | }} |
| | > |
| | {module.description} |
| | </Text> |
| | </div> |
| | <div style={{ marginLeft: '16px' }}> |
| | <Switch |
| | checked={ |
| | module.key === 'pricing' |
| | ? headerNavModules[module.key]?.enabled |
| | : headerNavModules[module.key] |
| | } |
| | onChange={handleHeaderNavModuleChange(module.key)} |
| | size='default' |
| | /> |
| | </div> |
| | </div> |
| | |
| | {/* 为模型广场添加权限控制子开关 */} |
| | {module.key === 'pricing' && |
| | (module.key === 'pricing' |
| | ? headerNavModules[module.key]?.enabled |
| | : headerNavModules[module.key]) && ( |
| | <div |
| | style={{ |
| | borderTop: '1px solid var(--semi-color-border)', |
| | marginTop: '12px', |
| | paddingTop: '12px', |
| | }} |
| | > |
| | <div |
| | style={{ |
| | display: 'flex', |
| | justifyContent: 'space-between', |
| | alignItems: 'center', |
| | }} |
| | > |
| | <div style={{ flex: 1, textAlign: 'left' }}> |
| | <div |
| | style={{ |
| | fontWeight: '500', |
| | fontSize: '12px', |
| | color: 'var(--semi-color-text-1)', |
| | marginBottom: '2px', |
| | }} |
| | > |
| | {t('需要登录访问')} |
| | </div> |
| | <Text |
| | type='secondary' |
| | size='small' |
| | style={{ |
| | fontSize: '11px', |
| | color: 'var(--semi-color-text-2)', |
| | lineHeight: '1.4', |
| | display: 'block', |
| | }} |
| | > |
| | {t('开启后未登录用户无法访问模型广场')} |
| | </Text> |
| | </div> |
| | <div style={{ marginLeft: '16px' }}> |
| | <Switch |
| | checked={ |
| | headerNavModules.pricing?.requireAuth || false |
| | } |
| | onChange={handlePricingAuthChange} |
| | size='default' |
| | /> |
| | </div> |
| | </div> |
| | </div> |
| | )} |
| | </Card> |
| | </Col> |
| | ))} |
| | </Row> |
| | |
| | <div |
| | style={{ |
| | display: 'flex', |
| | gap: '12px', |
| | justifyContent: 'flex-start', |
| | alignItems: 'center', |
| | paddingTop: '8px', |
| | borderTop: '1px solid var(--semi-color-border)', |
| | }} |
| | > |
| | <Button |
| | size='default' |
| | type='tertiary' |
| | onClick={resetHeaderNavModules} |
| | style={{ |
| | borderRadius: '6px', |
| | fontWeight: '500', |
| | }} |
| | > |
| | {t('重置为默认')} |
| | </Button> |
| | <Button |
| | size='default' |
| | type='primary' |
| | onClick={onSubmit} |
| | loading={loading} |
| | style={{ |
| | borderRadius: '6px', |
| | fontWeight: '500', |
| | minWidth: '100px', |
| | }} |
| | > |
| | {t('保存设置')} |
| | </Button> |
| | </div> |
| | </Form.Section> |
| | </Card> |
| | ); |
| | } |
| |
|