style: 移动端响应式优化:MCPPlugins页面完整重构、多处Modal弹窗适配、项目卡片单列显示
This commit is contained in:
@@ -635,21 +635,19 @@ export default function ChapterAnalysis({ chapterId, visible, onClose }: Chapter
|
||||
title="章节分析"
|
||||
open={visible}
|
||||
onCancel={onClose}
|
||||
width={isMobile ? '100%' : '90%'}
|
||||
centered={!isMobile}
|
||||
width={isMobile ? 'calc(100vw - 32px)' : '90%'}
|
||||
centered
|
||||
style={{
|
||||
maxWidth: isMobile ? '100%' : '1400px',
|
||||
paddingBottom: 0,
|
||||
top: isMobile ? 0 : undefined,
|
||||
margin: isMobile ? 0 : undefined,
|
||||
maxHeight: isMobile ? '100vh' : undefined
|
||||
maxWidth: isMobile ? 'calc(100vw - 32px)' : '1400px',
|
||||
margin: isMobile ? '0 auto' : undefined,
|
||||
padding: isMobile ? '0 16px' : undefined
|
||||
}}
|
||||
styles={{
|
||||
body: {
|
||||
padding: isMobile ? '12px' : '24px',
|
||||
paddingBottom: 0,
|
||||
maxHeight: isMobile ? 'calc(100vh - 110px)' : undefined,
|
||||
overflowY: isMobile ? 'auto' : undefined
|
||||
maxHeight: isMobile ? 'calc(100vh - 200px)' : 'calc(90vh - 150px)',
|
||||
overflowY: 'auto'
|
||||
}
|
||||
}}
|
||||
footer={[
|
||||
|
||||
@@ -1230,16 +1230,16 @@ export default function Chapters() {
|
||||
<span style={{ wordBreak: 'break-word' }}>第{chapter.chapter_number}章展开规划</span>
|
||||
</Space>
|
||||
),
|
||||
width: isMobile ? '95%' : 800,
|
||||
width: isMobile ? 'calc(100vw - 32px)' : 800,
|
||||
centered: true,
|
||||
style: isMobile ? {
|
||||
top: 20,
|
||||
maxWidth: 'calc(100vw - 16px)',
|
||||
margin: '0 8px'
|
||||
maxWidth: 'calc(100vw - 32px)',
|
||||
margin: '0 auto',
|
||||
padding: '0 16px'
|
||||
} : undefined,
|
||||
styles: {
|
||||
body: {
|
||||
maxHeight: isMobile ? 'calc(100vh - 150px)' : 'calc(80vh - 110px)',
|
||||
maxHeight: isMobile ? 'calc(100vh - 200px)' : 'calc(80vh - 110px)',
|
||||
overflowY: 'auto'
|
||||
}
|
||||
},
|
||||
@@ -2006,17 +2006,16 @@ export default function Chapters() {
|
||||
open={isModalOpen}
|
||||
onCancel={() => setIsModalOpen(false)}
|
||||
footer={null}
|
||||
centered={!isMobile}
|
||||
width={isMobile ? 'calc(100% - 32px)' : 520}
|
||||
centered
|
||||
width={isMobile ? 'calc(100vw - 32px)' : 520}
|
||||
style={isMobile ? {
|
||||
top: 20,
|
||||
paddingBottom: 0,
|
||||
maxWidth: 'calc(100vw - 32px)',
|
||||
margin: '0 16px'
|
||||
margin: '0 auto',
|
||||
padding: '0 16px'
|
||||
} : undefined}
|
||||
styles={{
|
||||
body: {
|
||||
maxHeight: isMobile ? 'calc(100vh - 150px)' : 'calc(80vh - 110px)',
|
||||
maxHeight: isMobile ? 'calc(100vh - 200px)' : 'calc(80vh - 110px)',
|
||||
overflowY: 'auto'
|
||||
}
|
||||
}}
|
||||
@@ -2082,17 +2081,16 @@ export default function Chapters() {
|
||||
closable={!isGenerating}
|
||||
maskClosable={!isGenerating}
|
||||
keyboard={!isGenerating}
|
||||
width={isMobile ? 'calc(100% - 32px)' : '85%'}
|
||||
centered={!isMobile}
|
||||
width={isMobile ? 'calc(100vw - 32px)' : '85%'}
|
||||
centered
|
||||
style={isMobile ? {
|
||||
top: 20,
|
||||
paddingBottom: 0,
|
||||
maxWidth: 'calc(100vw - 32px)',
|
||||
margin: '0 16px'
|
||||
margin: '0 auto',
|
||||
padding: '0 16px'
|
||||
} : undefined}
|
||||
styles={{
|
||||
body: {
|
||||
maxHeight: isMobile ? 'calc(100vh - 150px)' : 'calc(100vh - 110px)',
|
||||
maxHeight: isMobile ? 'calc(100vh - 200px)' : 'calc(100vh - 110px)',
|
||||
overflowY: 'auto',
|
||||
padding: isMobile ? '16px 12px' : '8px'
|
||||
}
|
||||
@@ -2366,6 +2364,7 @@ export default function Chapters() {
|
||||
content: '批量生成正在进行中,确定要取消吗?',
|
||||
okText: '确定取消',
|
||||
cancelText: '继续生成',
|
||||
centered: true,
|
||||
onOk: () => {
|
||||
handleCancelBatchGenerate();
|
||||
setBatchGenerateVisible(false);
|
||||
@@ -2376,7 +2375,7 @@ export default function Chapters() {
|
||||
}
|
||||
}}
|
||||
footer={!batchGenerating ? (
|
||||
<Space style={{ width: '100%', justifyContent: 'flex-end' }}>
|
||||
<Space style={{ width: '100%', justifyContent: 'flex-end', flexWrap: 'wrap' }}>
|
||||
<Button onClick={() => setBatchGenerateVisible(false)}>
|
||||
取消
|
||||
</Button>
|
||||
@@ -2385,13 +2384,18 @@ export default function Chapters() {
|
||||
</Button>
|
||||
</Space>
|
||||
) : null}
|
||||
width={700}
|
||||
width={isMobile ? 'calc(100vw - 32px)' : 700}
|
||||
centered
|
||||
closable={!batchGenerating}
|
||||
maskClosable={!batchGenerating}
|
||||
style={isMobile ? {
|
||||
maxWidth: 'calc(100vw - 32px)',
|
||||
margin: '0 auto',
|
||||
padding: '0 16px'
|
||||
} : undefined}
|
||||
styles={{
|
||||
body: {
|
||||
maxHeight: 'calc(100vh - 260px)',
|
||||
maxHeight: isMobile ? 'calc(100vh - 200px)' : 'calc(100vh - 260px)',
|
||||
overflowY: 'auto',
|
||||
overflowX: 'hidden'
|
||||
}
|
||||
@@ -2419,7 +2423,7 @@ export default function Chapters() {
|
||||
/>
|
||||
|
||||
{/* 第一行:起始章节 + 生成数量 */}
|
||||
<div style={{ display: 'flex', gap: 16 }}>
|
||||
<div style={{ display: 'flex', flexDirection: isMobile ? 'column' : 'row', gap: isMobile ? 0 : 16 }}>
|
||||
<Form.Item
|
||||
label="起始章节"
|
||||
name="startChapterNumber"
|
||||
@@ -2444,7 +2448,7 @@ export default function Chapters() {
|
||||
rules={[{ required: true, message: '请选择' }]}
|
||||
style={{ marginBottom: 12 }}
|
||||
>
|
||||
<Radio.Group buttonStyle="solid">
|
||||
<Radio.Group buttonStyle="solid" size={isMobile ? 'small' : 'middle'}>
|
||||
<Radio.Button value={5}>5章</Radio.Button>
|
||||
<Radio.Button value={10}>10章</Radio.Button>
|
||||
<Radio.Button value={15}>15章</Radio.Button>
|
||||
@@ -2454,7 +2458,7 @@ export default function Chapters() {
|
||||
</div>
|
||||
|
||||
{/* 第二行:写作风格 + 目标字数 */}
|
||||
<div style={{ display: 'flex', gap: 16 }}>
|
||||
<div style={{ display: 'flex', flexDirection: isMobile ? 'column' : 'row', gap: isMobile ? 0 : 16 }}>
|
||||
<Form.Item
|
||||
label="写作风格"
|
||||
name="styleId"
|
||||
@@ -2494,7 +2498,7 @@ export default function Chapters() {
|
||||
</div>
|
||||
|
||||
{/* 第三行:AI模型 + 同步分析 */}
|
||||
<div style={{ display: 'flex', gap: 16 }}>
|
||||
<div style={{ display: 'flex', flexDirection: isMobile ? 'column' : 'row', gap: isMobile ? 0 : 16 }}>
|
||||
<Form.Item
|
||||
label="AI模型"
|
||||
tooltip="不选则使用默认模型"
|
||||
|
||||
@@ -37,8 +37,17 @@ const { Paragraph, Text, Title } = Typography;
|
||||
const { TextArea } = Input;
|
||||
|
||||
export default function MCPPluginsPage() {
|
||||
const isMobile = window.innerWidth <= 768;
|
||||
const [isMobile, setIsMobile] = useState(window.innerWidth <= 768);
|
||||
const [form] = Form.useForm();
|
||||
|
||||
// 响应式监听窗口大小变化
|
||||
useEffect(() => {
|
||||
const handleResize = () => {
|
||||
setIsMobile(window.innerWidth <= 768);
|
||||
};
|
||||
window.addEventListener('resize', handleResize);
|
||||
return () => window.removeEventListener('resize', handleResize);
|
||||
}, []);
|
||||
const [modal, contextHolder] = Modal.useModal();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [plugins, setPlugins] = useState<MCPPlugin[]>([]);
|
||||
@@ -591,10 +600,9 @@ export default function MCPPluginsPage() {
|
||||
<div style={{
|
||||
minHeight: '90vh',
|
||||
background: 'linear-gradient(180deg, var(--color-bg-base) 0%, #EEF2F3 100%)',
|
||||
padding: isMobile ? '20px 16px' : '24px 24px',
|
||||
padding: isMobile ? '20px 16px 70px' : '24px 24px 70px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
marginBottom: '55px',
|
||||
}}>
|
||||
<div style={{
|
||||
maxWidth: 1400,
|
||||
@@ -657,7 +665,7 @@ export default function MCPPluginsPage() {
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<div style={{ marginTop: isMobile ? 16 : 24, display: 'flex', gap: 16, flexDirection: isMobile ? 'column' : 'row' }}>
|
||||
<div style={{ marginTop: isMobile ? 16 : 24, display: 'flex', gap: isMobile ? 12 : 16, flexDirection: isMobile ? 'column' : 'row' }}>
|
||||
<Card
|
||||
variant="borderless"
|
||||
style={{
|
||||
@@ -668,27 +676,36 @@ export default function MCPPluginsPage() {
|
||||
backdropFilter: 'blur(10px)',
|
||||
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.03)'
|
||||
}}
|
||||
styles={{ body: { padding: 20 } }}
|
||||
styles={{ body: { padding: isMobile ? 14 : 20 } }}
|
||||
>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<Space align="start">
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
flexDirection: isMobile ? 'column' : 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: isMobile ? 'stretch' : 'center',
|
||||
gap: isMobile ? 12 : 0
|
||||
}}>
|
||||
<Space align="start" style={{ flex: 1 }}>
|
||||
<div style={{
|
||||
width: 40, height: 40, borderRadius: '50%',
|
||||
width: isMobile ? 36 : 40,
|
||||
height: isMobile ? 36 : 40,
|
||||
borderRadius: '50%',
|
||||
background: modelSupportStatus === 'supported' ? 'var(--color-success-bg)' : modelSupportStatus === 'unsupported' ? 'var(--color-error-bg)' : 'var(--color-info-bg)',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
border: `1px solid ${modelSupportStatus === 'supported' ? 'var(--color-success-border)' : modelSupportStatus === 'unsupported' ? 'var(--color-error-border)' : 'var(--color-info-border)'}`
|
||||
border: `1px solid ${modelSupportStatus === 'supported' ? 'var(--color-success-border)' : modelSupportStatus === 'unsupported' ? 'var(--color-error-border)' : 'var(--color-info-border)'}`,
|
||||
flexShrink: 0
|
||||
}}>
|
||||
{modelSupportStatus === 'supported' ? (
|
||||
<CheckCircleOutlined style={{ fontSize: 20, color: 'var(--color-success)' }} />
|
||||
<CheckCircleOutlined style={{ fontSize: isMobile ? 18 : 20, color: 'var(--color-success)' }} />
|
||||
) : modelSupportStatus === 'unsupported' ? (
|
||||
<CloseCircleOutlined style={{ fontSize: 20, color: 'var(--color-error)' }} />
|
||||
<CloseCircleOutlined style={{ fontSize: isMobile ? 18 : 20, color: 'var(--color-error)' }} />
|
||||
) : (
|
||||
<QuestionCircleOutlined style={{ fontSize: 20, color: 'var(--color-info)' }} />
|
||||
<QuestionCircleOutlined style={{ fontSize: isMobile ? 18 : 20, color: 'var(--color-info)' }} />
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<Text strong style={{ fontSize: 16, display: 'block', color: 'var(--color-text-primary)' }}>模型能力检查</Text>
|
||||
<Text type="secondary" style={{ fontSize: 13 }}>
|
||||
<div style={{ flex: 1, minWidth: 0 }}>
|
||||
<Text strong style={{ fontSize: isMobile ? 14 : 16, display: 'block', color: 'var(--color-text-primary)' }}>模型能力检查</Text>
|
||||
<Text type="secondary" style={{ fontSize: isMobile ? 12 : 13, display: 'block', lineHeight: 1.5 }}>
|
||||
{modelSupportStatus === 'supported'
|
||||
? '当前模型支持 Function Calling,可正常使用 MCP 插件'
|
||||
: modelSupportStatus === 'unsupported'
|
||||
@@ -702,7 +719,8 @@ export default function MCPPluginsPage() {
|
||||
icon={<ApiOutlined />}
|
||||
onClick={handleCheckFunctionCalling}
|
||||
loading={checkingFunctionCalling}
|
||||
style={{ borderRadius: 8 }}
|
||||
style={{ borderRadius: 8, width: isMobile ? '100%' : 'auto' }}
|
||||
size={isMobile ? 'middle' : 'middle'}
|
||||
>
|
||||
{modelSupportStatus === 'unknown' ? '开始检测' : '重新检测'}
|
||||
</Button>
|
||||
@@ -719,13 +737,13 @@ export default function MCPPluginsPage() {
|
||||
backdropFilter: 'blur(10px)',
|
||||
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.03)'
|
||||
}}
|
||||
styles={{ body: { padding: 20 } }}
|
||||
styles={{ body: { padding: isMobile ? 14 : 20 } }}
|
||||
>
|
||||
<Space align="start">
|
||||
<InfoCircleOutlined style={{ fontSize: 20, color: 'var(--color-primary)', marginTop: 4 }} />
|
||||
<div>
|
||||
<Text strong style={{ fontSize: 16, display: 'block', color: 'var(--color-text-primary)', marginBottom: 4 }}>什么是 MCP 插件?</Text>
|
||||
<Text style={{ fontSize: 13, display: 'block', color: 'var(--color-text-secondary)', lineHeight: 1.6 }}>
|
||||
<InfoCircleOutlined style={{ fontSize: isMobile ? 18 : 20, color: 'var(--color-primary)', marginTop: 2, flexShrink: 0 }} />
|
||||
<div style={{ flex: 1, minWidth: 0 }}>
|
||||
<Text strong style={{ fontSize: isMobile ? 14 : 16, display: 'block', color: 'var(--color-text-primary)', marginBottom: 4 }}>什么是 MCP 插件?</Text>
|
||||
<Text style={{ fontSize: isMobile ? 12 : 13, display: 'block', color: 'var(--color-text-secondary)', lineHeight: 1.6 }}>
|
||||
MCP (Model Context Protocol) 协议允许 AI 调用外部工具获取数据。通过添加插件,AI 可以访问搜索引擎、数据库、API 等服务,大幅增强创作能力。
|
||||
</Text>
|
||||
</div>
|
||||
@@ -769,7 +787,7 @@ export default function MCPPluginsPage() {
|
||||
</Button>
|
||||
</Empty>
|
||||
) : (
|
||||
<Space direction="vertical" size="middle" style={{ width: '100%' }}>
|
||||
<Space direction="vertical" size={isMobile ? 'small' : 'middle'} style={{ width: '100%' }}>
|
||||
{plugins.map((plugin) => (
|
||||
<Card
|
||||
key={plugin.id}
|
||||
@@ -778,30 +796,62 @@ export default function MCPPluginsPage() {
|
||||
borderRadius: 8,
|
||||
border: '1px solid #f0f0f0',
|
||||
}}
|
||||
styles={{ body: { padding: isMobile ? 12 : 16 } }}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'flex-start',
|
||||
gap: '16px',
|
||||
flexWrap: isMobile ? 'wrap' : 'nowrap',
|
||||
flexDirection: 'column',
|
||||
gap: isMobile ? 12 : 16,
|
||||
}}
|
||||
>
|
||||
{/* 插件信息区域 */}
|
||||
<div style={{ flex: 1, minWidth: 0 }}>
|
||||
<Space direction="vertical" size="small" style={{ width: '100%' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', flexWrap: 'wrap' }}>
|
||||
<Text strong style={{ fontSize: isMobile ? '14px' : '16px' }}>
|
||||
{plugin.display_name || plugin.plugin_name}
|
||||
</Text>
|
||||
{getStatusTag(plugin)}
|
||||
<Tag color={plugin.plugin_type === 'http' || plugin.plugin_type === 'streamable_http' || plugin.plugin_type === 'sse' ? 'blue' : 'cyan'}>
|
||||
{/* 标题和状态标签 */}
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '6px',
|
||||
flexWrap: 'wrap',
|
||||
justifyContent: 'space-between'
|
||||
}}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '6px', flexWrap: 'wrap', flex: 1 }}>
|
||||
<Text strong style={{ fontSize: isMobile ? '14px' : '16px' }}>
|
||||
{plugin.display_name || plugin.plugin_name}
|
||||
</Text>
|
||||
{getStatusTag(plugin)}
|
||||
</div>
|
||||
{/* 移动端:开关放在标题行右侧 */}
|
||||
{isMobile && (
|
||||
<Switch
|
||||
title={modelSupportStatus !== 'supported' ? '请先完成模型能力检查' : (plugin.enabled ? '禁用插件' : '启用插件')}
|
||||
checked={plugin.enabled}
|
||||
onChange={(checked) => handleToggle(plugin, checked)}
|
||||
disabled={modelSupportStatus !== 'supported'}
|
||||
size="small"
|
||||
checkedChildren="开"
|
||||
unCheckedChildren="关"
|
||||
style={{
|
||||
flexShrink: 0,
|
||||
height: 16,
|
||||
minHeight: 16,
|
||||
lineHeight: '16px'
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 类型和分类标签 */}
|
||||
<div style={{ display: 'flex', gap: '4px', flexWrap: 'wrap' }}>
|
||||
<Tag color={plugin.plugin_type === 'http' || plugin.plugin_type === 'streamable_http' || plugin.plugin_type === 'sse' ? 'blue' : 'cyan'} style={{ fontSize: isMobile ? 11 : 12 }}>
|
||||
{plugin.plugin_type?.toUpperCase() || 'UNKNOWN'}
|
||||
</Tag>
|
||||
{plugin.category && plugin.category !== 'general' && (
|
||||
<Tag color="purple">{plugin.category}</Tag>
|
||||
<Tag color="purple" style={{ fontSize: isMobile ? 11 : 12 }}>{plugin.category}</Tag>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{plugin.description && (
|
||||
<Paragraph
|
||||
type="secondary"
|
||||
@@ -817,8 +867,13 @@ export default function MCPPluginsPage() {
|
||||
|
||||
{/* 只显示有值的URL或命令,脱敏处理敏感信息 */}
|
||||
{(plugin.plugin_type === 'http' || plugin.plugin_type === 'streamable_http' || plugin.plugin_type === 'sse') && plugin.server_url && (
|
||||
<div style={{ fontSize: isMobile ? '11px' : '12px' }}>
|
||||
<Text type="secondary" code>
|
||||
<div style={{
|
||||
fontSize: isMobile ? '11px' : '12px',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap'
|
||||
}}>
|
||||
<Text type="secondary" code style={{ fontSize: 'inherit' }}>
|
||||
{(() => {
|
||||
// 脱敏处理:隐藏URL中的API Key
|
||||
const url = plugin.server_url;
|
||||
@@ -849,8 +904,13 @@ export default function MCPPluginsPage() {
|
||||
)}
|
||||
|
||||
{plugin.plugin_type === 'stdio' && plugin.command && (
|
||||
<div style={{ fontSize: isMobile ? '11px' : '12px' }}>
|
||||
<Text type="secondary" code>
|
||||
<div style={{
|
||||
fontSize: isMobile ? '11px' : '12px',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap'
|
||||
}}>
|
||||
<Text type="secondary" code style={{ fontSize: 'inherit' }}>
|
||||
{plugin.command} {plugin.args?.join(' ')}
|
||||
</Text>
|
||||
</div>
|
||||
@@ -865,20 +925,27 @@ export default function MCPPluginsPage() {
|
||||
</Space>
|
||||
</div>
|
||||
|
||||
<Space size="small" wrap>
|
||||
<Switch
|
||||
title={modelSupportStatus !== 'supported' ? '请先完成模型能力检查' : (plugin.enabled ? '禁用插件' : '启用插件')}
|
||||
checked={plugin.enabled}
|
||||
onChange={(checked) => handleToggle(plugin, checked)}
|
||||
disabled={modelSupportStatus !== 'supported'}
|
||||
size={isMobile ? 'small' : 'default'}
|
||||
style={{
|
||||
flexShrink: 0,
|
||||
height: isMobile ? 16 : 22,
|
||||
minHeight: isMobile ? 16 : 22,
|
||||
lineHeight: isMobile ? '16px' : '22px'
|
||||
}}
|
||||
/>
|
||||
{/* 操作按钮区域 */}
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
justifyContent: isMobile ? 'flex-end' : 'flex-start',
|
||||
alignItems: 'center',
|
||||
gap: isMobile ? 8 : 8,
|
||||
flexWrap: 'wrap',
|
||||
borderTop: isMobile ? '1px solid #f0f0f0' : 'none',
|
||||
paddingTop: isMobile ? 12 : 0
|
||||
}}>
|
||||
{/* 桌面端显示开关 */}
|
||||
{!isMobile && (
|
||||
<Switch
|
||||
title={modelSupportStatus !== 'supported' ? '请先完成模型能力检查' : (plugin.enabled ? '禁用插件' : '启用插件')}
|
||||
checked={plugin.enabled}
|
||||
onChange={(checked) => handleToggle(plugin, checked)}
|
||||
disabled={modelSupportStatus !== 'supported'}
|
||||
checkedChildren="开"
|
||||
unCheckedChildren="关"
|
||||
/>
|
||||
)}
|
||||
<Button
|
||||
title={modelSupportStatus !== 'supported' ? '请先完成模型能力检查' : '测试连接'}
|
||||
icon={<ThunderboltOutlined />}
|
||||
@@ -886,21 +953,27 @@ export default function MCPPluginsPage() {
|
||||
loading={testingPluginId === plugin.id}
|
||||
disabled={modelSupportStatus !== 'supported'}
|
||||
size={isMobile ? 'small' : 'middle'}
|
||||
/>
|
||||
>
|
||||
{!isMobile && '测试'}
|
||||
</Button>
|
||||
<Button
|
||||
title={modelSupportStatus !== 'supported' ? '请先完成模型能力检查' : '查看工具'}
|
||||
icon={<ToolOutlined />}
|
||||
onClick={() => handleViewTools(plugin.id)}
|
||||
disabled={modelSupportStatus !== 'supported' || !plugin.enabled || plugin.status !== 'active'}
|
||||
size={isMobile ? 'small' : 'middle'}
|
||||
/>
|
||||
>
|
||||
{!isMobile && '工具'}
|
||||
</Button>
|
||||
<Button
|
||||
title={modelSupportStatus !== 'supported' ? '请先完成模型能力检查' : '编辑'}
|
||||
icon={<EditOutlined />}
|
||||
onClick={() => handleEdit(plugin)}
|
||||
disabled={modelSupportStatus !== 'supported'}
|
||||
size={isMobile ? 'small' : 'middle'}
|
||||
/>
|
||||
>
|
||||
{!isMobile && '编辑'}
|
||||
</Button>
|
||||
<Button
|
||||
title={modelSupportStatus !== 'supported' ? '请先完成模型能力检查' : '删除'}
|
||||
danger
|
||||
@@ -908,8 +981,10 @@ export default function MCPPluginsPage() {
|
||||
onClick={() => handleDelete(plugin)}
|
||||
disabled={modelSupportStatus !== 'supported'}
|
||||
size={isMobile ? 'small' : 'middle'}
|
||||
/>
|
||||
</Space>
|
||||
>
|
||||
{!isMobile && '删除'}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
))}
|
||||
@@ -942,7 +1017,7 @@ export default function MCPPluginsPage() {
|
||||
extra="粘贴标准MCP配置,系统自动提取插件名称。支持HTTP和Stdio类型"
|
||||
>
|
||||
<TextArea
|
||||
rows={16}
|
||||
rows={isMobile ? 12 : 16}
|
||||
placeholder={`示例:
|
||||
{
|
||||
"mcpServers": {
|
||||
|
||||
@@ -253,10 +253,9 @@ export default function PromptTemplates() {
|
||||
<div style={{
|
||||
minHeight: '90vh',
|
||||
background: 'linear-gradient(180deg, var(--color-bg-base) 0%, #EEF2F3 100%)',
|
||||
padding: isMobile ? '20px 16px' : '24px 24px',
|
||||
padding: isMobile ? '20px 16px 70px' : '24px 24px 70px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
marginBottom: '55px',
|
||||
}}>
|
||||
<div style={{
|
||||
maxWidth: 1400,
|
||||
|
||||
@@ -794,10 +794,9 @@ export default function SettingsPage() {
|
||||
<div style={{
|
||||
minHeight: '90vh',
|
||||
background: 'linear-gradient(180deg, var(--color-bg-base) 0%, #EEF2F3 100%)',
|
||||
padding: isMobile ? '20px 16px' : '24px 24px',
|
||||
padding: isMobile ? '20px 16px 70px' : '24px 24px 70px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
marginBottom: '55px',
|
||||
}}>
|
||||
<div style={{
|
||||
maxWidth: 1400,
|
||||
|
||||
@@ -21,7 +21,7 @@ interface SponsorOption {
|
||||
const sponsorOptions: SponsorOption[] = [
|
||||
{ amount: 5, label: '🌶️ 一包辣条', image: '/5.png', description: '¥5' },
|
||||
{ amount: 10, label: '🍱 一顿拼好饭', image: '/10.png', description: '¥10' },
|
||||
{ amount: 20, label: '🧋 一杯咖啡', image: '/20.png', description: '¥20' },
|
||||
{ amount: 20, label: '☕ 一杯咖啡', image: '/20.png', description: '¥20' },
|
||||
{ amount: 50, label: '🍖 一次烧烤', image: '/50.png', description: '¥50' },
|
||||
{ amount: 99, label: '🍲 一顿海底捞', image: '/99.png', description: '¥99' },
|
||||
];
|
||||
|
||||
@@ -289,7 +289,13 @@ export const projectApi = {
|
||||
},
|
||||
|
||||
// 导出项目数据为JSON
|
||||
exportProjectData: async (id: string, options: { include_generation_history?: boolean; include_writing_styles?: boolean }) => {
|
||||
exportProjectData: async (id: string, options: {
|
||||
include_generation_history?: boolean;
|
||||
include_writing_styles?: boolean;
|
||||
include_careers?: boolean;
|
||||
include_memories?: boolean;
|
||||
include_plot_analysis?: boolean;
|
||||
}) => {
|
||||
const response = await axios.post(
|
||||
`/api/projects/${id}/export-data`,
|
||||
options,
|
||||
|
||||
Reference in New Issue
Block a user