fix(web): 官方 antd lint 清零——Alert title、Flex vertical 替代弃用 Space/List、App.useApp 包裹
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { history } from '@umijs/max';
|
||||
import {
|
||||
Flex,
|
||||
Alert,
|
||||
Button,
|
||||
Card,
|
||||
@@ -172,12 +173,12 @@ export default function AccountManagementList({ mode }: { mode: 'owned' | 'monit
|
||||
dataIndex: 'status',
|
||||
render: (_, account) =>
|
||||
account.source_type === 'owned' ? (
|
||||
<Space direction="vertical" size={0}>
|
||||
<Flex>
|
||||
<Tag color={account.runtime_status === 'active' ? 'success' : 'default'}>
|
||||
{account.runtime_status === 'active' ? '启用' : '暂停'}
|
||||
</Tag>
|
||||
<Typography.Text type="secondary">{account.authorization_status === 'authorized' ? '已授权' : '已撤销'}</Typography.Text>
|
||||
</Space>
|
||||
</Flex>
|
||||
) : (
|
||||
<Tag color={account.enabled ? 'success' : 'default'}>{account.enabled ? '监控中' : '已暂停'}</Tag>
|
||||
),
|
||||
@@ -244,7 +245,7 @@ export default function AccountManagementList({ mode }: { mode: 'owned' | 'monit
|
||||
共 {rows.length} 个{isMonitoring ? '监控' : '自有'}账号
|
||||
</Typography.Text>
|
||||
{error ? (
|
||||
<Alert type="error" showIcon style={{ marginBottom: 16 }} message={error.message} action={<Button size="small" onClick={load}>重试</Button>} />
|
||||
<Alert type="error" showIcon style={{ marginBottom: 16 }} title={error.message} action={<Button size="small" onClick={load}>重试</Button>} />
|
||||
) : null}
|
||||
<Table
|
||||
rowKey={(row) => `${row.source_type}:${row.id}`}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useState } from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import { history, Outlet, useLocation } from '@umijs/max';
|
||||
import { PageContainer, ProLayout } from '@ant-design/pro-components';
|
||||
import { Dropdown, Typography } from 'antd';
|
||||
import { App, Dropdown, Typography } from 'antd';
|
||||
import { LogoutOutlined } from '@ant-design/icons';
|
||||
import { PageActionsContext } from '@/components/PageActions';
|
||||
import { menu, menuSelectedKey, pageMetadata } from '@/utils/metadata';
|
||||
@@ -59,6 +59,8 @@ export default function Layout() {
|
||||
}}
|
||||
>
|
||||
{/* 页面标题在卡片外(内容区左上角),动作按钮与标题同一行(右侧);卡片内不再重复渲染标题。 */}
|
||||
{/* App 包裹:App.useApp() 的 message 等实例需要此上下文(component=false 不增加 DOM,避免破坏 ProLayout 布局)。 */}
|
||||
<App component={false}>
|
||||
<PageContainer
|
||||
ghost
|
||||
title={
|
||||
@@ -73,6 +75,7 @@ export default function Layout() {
|
||||
>
|
||||
<Outlet />
|
||||
</PageContainer>
|
||||
</App>
|
||||
</ProLayout>
|
||||
</PageActionsContext.Provider>
|
||||
);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { history, useParams } from '@umijs/max';
|
||||
import {
|
||||
Flex,
|
||||
Alert,
|
||||
Button,
|
||||
Card,
|
||||
@@ -262,13 +263,13 @@ export default function Page() {
|
||||
if (error && !selected)
|
||||
return (
|
||||
<div>
|
||||
<Alert type="error" showIcon message={error.message || '账号不存在'} />
|
||||
<Alert type="error" showIcon title={error.message || '账号不存在'} />
|
||||
<Button style={{ marginTop: 16 }} onClick={() => history.push('/accounts')}>
|
||||
返回社媒账号
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
if (!selected) return <Alert type="warning" showIcon message="账号不存在。" />;
|
||||
if (!selected) return <Alert type="warning" showIcon title="账号不存在。" />;
|
||||
|
||||
const smallAccounts = profiles.filter(
|
||||
(profile) => profile.id !== selected.id && profile.authorization_kind === 'owned' && profile.platform === selected.platform,
|
||||
@@ -276,7 +277,7 @@ export default function Page() {
|
||||
|
||||
const profileTab = (
|
||||
<div>
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={16}>
|
||||
<Flex>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'space-between', gap: 12 }}>
|
||||
<Descriptions column={1} size="small" style={{ flex: 1, minWidth: 260 }}>
|
||||
<Descriptions.Item label="登录核验">
|
||||
@@ -371,13 +372,13 @@ export default function Page() {
|
||||
</Button>
|
||||
</div>
|
||||
</Form>
|
||||
</Space>
|
||||
</Flex>
|
||||
</div>
|
||||
);
|
||||
|
||||
const strategyTab = selected.big_account ? (
|
||||
<div>
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={16}>
|
||||
<Flex>
|
||||
<Typography.Text type="secondary">先绑定同平台小号,再保存单动作策略;没有平台执行证据时只记录为不确定。</Typography.Text>
|
||||
<Form form={strategyForm} layout="vertical" onFinish={createStrategy} style={{ background: '#fafafa', padding: 16, borderRadius: 8 }}>
|
||||
<Space size={16} wrap style={{ display: 'flex' }}>
|
||||
@@ -418,8 +419,8 @@ export default function Page() {
|
||||
) : null}
|
||||
</Space>
|
||||
</Form>
|
||||
{strategyError ? <Alert type="warning" showIcon message={`策略读取失败:${conflictMessage(strategyError, '请只读重试')}`} /> : null}
|
||||
{relationError ? <Alert type="warning" showIcon message={`账号关系读取失败:${conflictMessage(relationError, '请只读重试')}`} /> : null}
|
||||
{strategyError ? <Alert type="warning" showIcon title={`策略读取失败:${conflictMessage(strategyError, '请只读重试')}`} /> : null}
|
||||
{relationError ? <Alert type="warning" showIcon title={`账号关系读取失败:${conflictMessage(relationError, '请只读重试')}`} /> : null}
|
||||
{relations.map((relation) => (
|
||||
<Card key={`${relation.big_account_id}:${relation.small_account_id}`} size="small">
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
@@ -470,7 +471,7 @@ export default function Page() {
|
||||
</Card>
|
||||
))}
|
||||
{!strategies.length && !strategyError ? <Typography.Text type="secondary">尚未配置策略。</Typography.Text> : null}
|
||||
</Space>
|
||||
</Flex>
|
||||
</div>
|
||||
) : (
|
||||
<Typography.Text type="secondary">开启大号模式后可配置有序自动响应策略。</Typography.Text>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { history, useParams } from '@umijs/max';
|
||||
import {
|
||||
Flex,
|
||||
Alert,
|
||||
Button,
|
||||
Card,
|
||||
@@ -103,7 +104,7 @@ export default function Page() {
|
||||
}
|
||||
|
||||
if (pending) return <Card loading />;
|
||||
if (error || !account) return <Alert type="error" showIcon message={error?.message || '账号不存在'} />;
|
||||
if (error || !account) return <Alert type="error" showIcon title={error?.message || '账号不存在'} />;
|
||||
|
||||
const statusTag = (
|
||||
<Tag
|
||||
@@ -119,7 +120,7 @@ export default function Page() {
|
||||
label: '账号状态',
|
||||
children: (
|
||||
<div>
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={16}>
|
||||
<Flex>
|
||||
<div>{statusTag}</div>
|
||||
<Descriptions column={1} bordered size="small">
|
||||
<Descriptions.Item label="授权">{account.authorization_status === 'authorized' ? '已授权' : '已撤销'}</Descriptions.Item>
|
||||
@@ -134,8 +135,8 @@ export default function Page() {
|
||||
恢复账号
|
||||
</Button>
|
||||
</Space>
|
||||
<Alert type="info" showIcon message="暂停会把待领取任务置为 hold;恢复账号只恢复账号可用性,不会自动恢复既有 hold。" />
|
||||
</Space>
|
||||
<Alert type="info" showIcon title="暂停会把待领取任务置为 hold;恢复账号只恢复账号可用性,不会自动恢复既有 hold。" />
|
||||
</Flex>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
@@ -146,7 +147,7 @@ export default function Page() {
|
||||
<Alert
|
||||
type="error"
|
||||
showIcon
|
||||
message="环境不可用:运行环境与网络出口状态未知,依赖资源状态的操作暂不可用。"
|
||||
title="环境不可用:运行环境与网络出口状态未知,依赖资源状态的操作暂不可用。"
|
||||
action={
|
||||
<Button size="small" onClick={loadAll}>
|
||||
重试环境状态
|
||||
@@ -181,7 +182,7 @@ export default function Page() {
|
||||
label: '文本草稿',
|
||||
children: (
|
||||
<div>
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={16}>
|
||||
<Flex>
|
||||
<Typography.Text type="secondary">仅支持单用户 Phase A Mock 文本;内部 ID 与版本由系统生成。</Typography.Text>
|
||||
<Form form={draftForm} layout="vertical">
|
||||
<Form.Item
|
||||
@@ -216,7 +217,7 @@ export default function Page() {
|
||||
</div>
|
||||
</Card>
|
||||
))}
|
||||
</Space>
|
||||
</Flex>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
|
||||
@@ -177,7 +177,7 @@ export default function Page() {
|
||||
</Button>
|
||||
</div>
|
||||
{error ? (
|
||||
<Alert type="error" showIcon style={{ marginBottom: 16 }} message={error.message} action={<Button size="small" onClick={loadShareJobs}>重试</Button>} />
|
||||
<Alert type="error" showIcon style={{ marginBottom: 16 }} title={error.message} action={<Button size="small" onClick={loadShareJobs}>重试</Button>} />
|
||||
) : null}
|
||||
<Table rowKey="id" columns={columns} dataSource={jobs} loading={pending} pagination={false} locale={{ emptyText: '暂无分享链接解析任务。' }} />
|
||||
<Modal open={createOpen} title="创建账号导入任务" onCancel={closeCreate} onOk={createJob} confirmLoading={busy} okText={busy ? '加入中…' : '加入解析队列'} width={560}>
|
||||
|
||||
@@ -45,7 +45,7 @@ export default function Page() {
|
||||
return (
|
||||
<Card variant="outlined">
|
||||
{error ? (
|
||||
<Alert type="error" showIcon style={{ marginBottom: 16 }} message={conflictMessage(error, '该平台的账号 ID 已存在;表单内容已保留。')} />
|
||||
<Alert type="error" showIcon style={{ marginBottom: 16 }} title={conflictMessage(error, '该平台的账号 ID 已存在;表单内容已保留。')} />
|
||||
) : null}
|
||||
<Form form={form} layout="vertical" onFinish={onFinish} style={{ maxWidth: 720 }}>
|
||||
<Form.Item name="name" label="账号名称" required rules={[{ required: true, message: '请输入账号名称' }]} extra="展示名称,支持中文">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Attempt 详情:语义对齐 web.archived TracePages.jsx 的 AttemptDetail。
|
||||
import { useEffect, useState } from 'react';
|
||||
import { history, useParams } from '@umijs/max';
|
||||
import { Alert, Button, Card, Descriptions, Space, Typography } from 'antd';
|
||||
import { Flex, Alert, Button, Card, Descriptions, Space, Typography } from 'antd';
|
||||
import { getOne } from '@/services/api';
|
||||
import { dateTime } from '@/utils/helpers';
|
||||
|
||||
@@ -31,7 +31,7 @@ export default function Page() {
|
||||
}, [id]);
|
||||
|
||||
if (pending) return <Card loading />;
|
||||
if (error) return <Alert type="error" showIcon message={error.message} />;
|
||||
if (error) return <Alert type="error" showIcon title={error.message} />;
|
||||
if (!attempt) return null;
|
||||
|
||||
return (
|
||||
@@ -42,7 +42,7 @@ export default function Page() {
|
||||
</Typography.Text>
|
||||
</div>
|
||||
<Card>
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={16}>
|
||||
<Flex>
|
||||
<Descriptions column={1} bordered size="small">
|
||||
<Descriptions.Item label="结果">{attempt.outcome || '执行中'}</Descriptions.Item>
|
||||
<Descriptions.Item label="开始">{dateTime(attempt.started_at)}</Descriptions.Item>
|
||||
@@ -61,7 +61,7 @@ export default function Page() {
|
||||
<Button onClick={() => history.push(`/network-exits/${encodeURIComponent(attempt.network_exit_id)}`)}>查看出口</Button>
|
||||
) : null}
|
||||
</Space>
|
||||
</Space>
|
||||
</Flex>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// 运行环境详情:语义对齐 web.archived BrowsersPage.jsx 的 BrowserDetail。
|
||||
import { useEffect, useState } from 'react';
|
||||
import { history, useParams } from '@umijs/max';
|
||||
import { Alert, Button, Card, Descriptions, Space, Tag, Typography, message } from 'antd';
|
||||
import { Flex, Alert, App, Button, Card, Descriptions, Space, Tag, Typography } from 'antd';
|
||||
import { CopyOutlined } from '@ant-design/icons';
|
||||
import { getOne } from '@/services/api';
|
||||
|
||||
@@ -19,6 +19,8 @@ const stateText: Record<string, string> = {
|
||||
};
|
||||
|
||||
export default function Page() {
|
||||
// 官方规范:静态 message 吃不到 ConfigProvider 上下文,用 App.useApp() 取实例。
|
||||
const { message } = App.useApp();
|
||||
const { id = '' } = useParams<{ id: string }>();
|
||||
const [runtime, setRuntime] = useState<any>(null);
|
||||
const [pending, setPending] = useState(true);
|
||||
@@ -44,7 +46,7 @@ export default function Page() {
|
||||
}, [id]);
|
||||
|
||||
if (pending) return <Card loading />;
|
||||
if (error || !runtime) return <Alert type="error" showIcon message={error?.message || '运行环境不存在'} />;
|
||||
if (error || !runtime) return <Alert type="error" showIcon title={error?.message || '运行环境不存在'} />;
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -55,7 +57,7 @@ export default function Page() {
|
||||
<Button onClick={() => history.push('/browsers')}>返回运行环境</Button>
|
||||
</div>
|
||||
<Card>
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={16}>
|
||||
<Flex>
|
||||
<Tag color={runtime.state === 'running' ? 'success' : runtime.state === 'stopped' ? 'warning' : 'default'}>
|
||||
{stateText[runtime.state] ?? `未知状态:${runtime.state}`}
|
||||
</Tag>
|
||||
@@ -104,7 +106,7 @@ export default function Page() {
|
||||
<Button onClick={() => history.push(`/network-exits/${encodeURIComponent(runtime.network_exit_id)}`)}>查看出口</Button>
|
||||
) : null}
|
||||
</Space>
|
||||
</Space>
|
||||
</Flex>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -170,7 +170,7 @@ export default function Page() {
|
||||
<Card variant="outlined">
|
||||
{contextHolder}
|
||||
{error ? (
|
||||
<Alert type="error" showIcon style={{ marginBottom: 16 }} message={error.message} action={<Button size="small" onClick={load}>重试</Button>} />
|
||||
<Alert type="error" showIcon style={{ marginBottom: 16 }} title={error.message} action={<Button size="small" onClick={load}>重试</Button>} />
|
||||
) : null}
|
||||
<Table
|
||||
rowKey="alias"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// 竞品分析:语义对齐 web.archived/src/features/creator/competitors/CreatorCompetitorsPage.jsx(提交 d97cade)。
|
||||
// 仅用 antd 默认组件;筛选自动刷新、手动上一页/下一页(后端 has_next)、素材三步处理与仿写流程原样保留。
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Alert, Button, Card, Input, InputNumber, Modal, Select, Space, Table, Tag, Typography, message } from 'antd';
|
||||
import { Flex, Alert, Button, Card, Input, InputNumber, Modal, Select, Space, Table, Tag, Typography, message } from 'antd';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import { creatorAction, creatorGet, creatorUpdate, getList } from '@/services/api';
|
||||
import { conflictMessage, dateTime } from '@/utils/helpers';
|
||||
@@ -264,7 +264,7 @@ export default function Page() {
|
||||
return (
|
||||
<div>
|
||||
{contextHolder}
|
||||
<Space direction="vertical" size={16} style={{ width: '100%' }}>
|
||||
<Flex>
|
||||
<Card title="筛选作品" extra={<Typography.Text type="secondary" style={{ fontSize: 12 }}>调整条件后自动刷新</Typography.Text>}>
|
||||
<Space size={12} wrap style={{ display: 'flex' }}>
|
||||
<Select
|
||||
@@ -292,7 +292,7 @@ export default function Page() {
|
||||
</Card>
|
||||
<Card title="作品与指标">
|
||||
{error ? (
|
||||
<Alert type="error" showIcon style={{ marginBottom: 16 }} message={error.message} action={<Button size="small" onClick={load}>重试</Button>} />
|
||||
<Alert type="error" showIcon style={{ marginBottom: 16 }} title={error.message} action={<Button size="small" onClick={load}>重试</Button>} />
|
||||
) : null}
|
||||
<Table rowKey="id" columns={columns} dataSource={works} loading={pending} pagination={false} locale={{ emptyText: '暂无符合条件的作品。' }} />
|
||||
{workPageInfo.total > works.length ? (
|
||||
@@ -314,7 +314,7 @@ export default function Page() {
|
||||
title={<span>作品详情 <Typography.Text type="secondary" style={{ fontSize: 12, fontWeight: 'normal' }}>{workDetail.work_key || workDetail.id}</Typography.Text></span>}
|
||||
extra={<Button size="small" onClick={() => setWorkDetail(null)}>关闭</Button>}
|
||||
>
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={16}>
|
||||
<Flex>
|
||||
{workDetail.cover_url ? <img src={workDetail.cover_url} alt="作品封面" style={{ maxHeight: 256, borderRadius: 4, border: '1px solid #f0f0f0' }} /> : null}
|
||||
<Typography.Paragraph style={{ whiteSpace: 'pre-wrap', marginBottom: 0 }}>{workDetail.body || workDetail.title || '暂无正文'}</Typography.Paragraph>
|
||||
<Space wrap>
|
||||
@@ -339,7 +339,7 @@ export default function Page() {
|
||||
]}
|
||||
locale={{ emptyText: '暂无指标记录。' }}
|
||||
/>
|
||||
</Space>
|
||||
</Flex>
|
||||
</Card>
|
||||
) : null}
|
||||
{material ? (
|
||||
@@ -348,13 +348,13 @@ export default function Page() {
|
||||
<Button type="primary" onClick={processMaterial} loading={materialPending || material.download_status === 'running'} style={{ marginBottom: 16 }}>
|
||||
开始处理素材
|
||||
</Button>
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={16}>
|
||||
<Flex>
|
||||
<Space wrap>
|
||||
{statusTag(material.download_status === 'succeeded' ? 'success' : material.download_status === 'failed' ? 'error' : 'default', `下载:${material.download_status}`)}
|
||||
{statusTag(material.audio_status === 'succeeded' ? 'success' : material.audio_status === 'failed' ? 'error' : 'default', `音轨:${material.audio_status}`)}
|
||||
{statusTag(material.transcription_status === 'succeeded' ? 'success' : material.transcription_status === 'failed' ? 'error' : 'default', `转写:${material.transcription_status}`)}
|
||||
</Space>
|
||||
{material.failure_reason ? <Alert type="error" showIcon message={`失败步骤:${material.failed_step || '未记录'};${material.failure_reason}`} /> : null}
|
||||
{material.failure_reason ? <Alert type="error" showIcon title={`失败步骤:${material.failed_step || '未记录'};${material.failure_reason}`} /> : null}
|
||||
<div>
|
||||
<Typography.Text strong>仿写要求</Typography.Text>
|
||||
<Typography.Paragraph type="secondary" style={{ fontSize: 12, marginBottom: 4 }}>必须先确认要求,才允许保存可编辑结果。</Typography.Paragraph>
|
||||
@@ -366,7 +366,7 @@ export default function Page() {
|
||||
style={{ marginBottom: 12 }}
|
||||
/>
|
||||
{material.rewrite_confirmed_at ? (
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={12}>
|
||||
<Flex>
|
||||
<Space>
|
||||
<Button onClick={generateRewrite} disabled={materialPending}>
|
||||
生成仿写草稿
|
||||
@@ -384,17 +384,17 @@ export default function Page() {
|
||||
<Button type="primary" onClick={saveRewrite} disabled={materialPending}>
|
||||
保存仿写结果
|
||||
</Button>
|
||||
</Space>
|
||||
</Flex>
|
||||
) : (
|
||||
<Button type="primary" onClick={confirmRewrite} disabled={materialPending || !materialReadyForConfirm}>
|
||||
确认仿写要求
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</Space>
|
||||
</Flex>
|
||||
</Card>
|
||||
) : null}
|
||||
</Space>
|
||||
</Flex>
|
||||
<Modal
|
||||
open={Boolean(pendingSwitchWork)}
|
||||
title="放弃未保存的素材文稿"
|
||||
|
||||
@@ -71,7 +71,7 @@ export default function Page() {
|
||||
}
|
||||
|
||||
if (pending) return <Card loading />;
|
||||
if (error) return <Alert type="error" showIcon message={error.message} action={<Button size="small" onClick={load}>重试</Button>} />;
|
||||
if (error) return <Alert type="error" showIcon title={error.message} action={<Button size="small" onClick={load}>重试</Button>} />;
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// 六个页签:评论/线索/规则/事件监听/私信/操作记录;实时更新走 /creator/updates SSE;仅用 antd 默认组件。
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import { Alert, Button, Card, Checkbox, Col, Empty, Input, List, Modal, Row, Select, Space, Spin, Table, Tabs, Tag, Typography, message } from 'antd';
|
||||
import { Flex, Alert, Button, Card, Checkbox, Col, Empty, Input, Modal, Row, Select, Space, Spin, Table, Tabs, Tag, Typography, message } from 'antd';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import { create, creatorAction, creatorCreate, creatorGet, creatorSubscribe, creatorSyncConversation, creatorUpdate, getList } from '@/services/api';
|
||||
import { conflictMessage, dateTime } from '@/utils/helpers';
|
||||
@@ -82,7 +82,7 @@ function TabShell({ pending, error, onRetry, children }: { pending: boolean; err
|
||||
return (
|
||||
<div>
|
||||
{error ? (
|
||||
<Alert type="error" showIcon style={{ marginBottom: 16 }} message={error.message} action={<Button size="small" onClick={onRetry}>重试</Button>} />
|
||||
<Alert type="error" showIcon style={{ marginBottom: 16 }} title={error.message} action={<Button size="small" onClick={onRetry}>重试</Button>} />
|
||||
) : null}
|
||||
<Spin spinning={pending}>{children}</Spin>
|
||||
</div>
|
||||
@@ -556,7 +556,7 @@ export default function Page() {
|
||||
const replyFormCard =
|
||||
reply.target_comment_id && replyTarget ? (
|
||||
<Card size="small" style={{ marginBottom: 16 }}>
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={8}>
|
||||
<Flex>
|
||||
<Space size={12} wrap style={{ display: 'flex', alignItems: 'flex-end' }}>
|
||||
<div>
|
||||
<Typography.Text>发送账号</Typography.Text>
|
||||
@@ -585,7 +585,7 @@ export default function Page() {
|
||||
<Typography.Text type="secondary" style={{ fontSize: 12 }}>
|
||||
{tab === 'comments' ? '回复' : ''}目标 UID:{reply.target_uid || '不可用,无法发送'}
|
||||
</Typography.Text>
|
||||
</Space>
|
||||
</Flex>
|
||||
</Card>
|
||||
) : null;
|
||||
|
||||
@@ -609,7 +609,7 @@ export default function Page() {
|
||||
<Empty description="暂无一级评论。" />
|
||||
) : (
|
||||
<>
|
||||
<Space direction="vertical" size={12} style={{ width: '100%' }}>
|
||||
<Flex>
|
||||
{visibleData.map((comment: any) => (
|
||||
<Card key={comment.id} size="small">
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'space-between', gap: 12 }}>
|
||||
@@ -655,7 +655,7 @@ export default function Page() {
|
||||
</div>
|
||||
</Card>
|
||||
))}
|
||||
</Space>
|
||||
</Flex>
|
||||
<PageNav page={listPage} total={listPageInfo.total} count={visibleData.length} hasNext={listPageInfo.hasNext} onPageChange={setListPage} />
|
||||
</>
|
||||
)}
|
||||
@@ -668,7 +668,7 @@ export default function Page() {
|
||||
{!pending && !error && !visibleData.length ? (
|
||||
<Empty description="暂无命中线索。" />
|
||||
) : (
|
||||
<Space direction="vertical" size={12} style={{ width: '100%' }}>
|
||||
<Flex>
|
||||
{visibleData.map((lead: any) => (
|
||||
<Card key={lead.comment.id} size="small">
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
|
||||
@@ -702,7 +702,7 @@ export default function Page() {
|
||||
</div>
|
||||
</Card>
|
||||
))}
|
||||
</Space>
|
||||
</Flex>
|
||||
)}
|
||||
</TabShell>
|
||||
);
|
||||
@@ -713,7 +713,7 @@ export default function Page() {
|
||||
<Empty description="暂无监听事件。" />
|
||||
) : (
|
||||
<>
|
||||
<Space direction="vertical" size={12} style={{ width: '100%' }}>
|
||||
<Flex>
|
||||
{visibleData.map((event: any) => (
|
||||
<Card key={event.id} size="small">
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'space-between', gap: 12 }}>
|
||||
@@ -739,7 +739,7 @@ export default function Page() {
|
||||
</Typography.Paragraph>
|
||||
</Card>
|
||||
))}
|
||||
</Space>
|
||||
</Flex>
|
||||
<PageNav page={listPage} total={listPageInfo.total} count={visibleData.length} hasNext={listPageInfo.hasNext} onPageChange={setListPage} />
|
||||
</>
|
||||
)}
|
||||
@@ -750,7 +750,7 @@ export default function Page() {
|
||||
<Row gutter={16}>
|
||||
<Col xs={24} lg={8}>
|
||||
<Card size="small" title={editingRuleID ? '编辑规则' : '新建规则'} style={{ marginBottom: 16 }}>
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={12}>
|
||||
<Flex>
|
||||
<div>
|
||||
<Typography.Text>规则名称</Typography.Text>
|
||||
<RequiredMark />
|
||||
@@ -800,7 +800,7 @@ export default function Page() {
|
||||
</Button>
|
||||
) : null}
|
||||
</Space>
|
||||
</Space>
|
||||
</Flex>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col xs={24} lg={16}>
|
||||
@@ -866,12 +866,21 @@ export default function Page() {
|
||||
<Row gutter={16}>
|
||||
<Col xs={24} lg={7}>
|
||||
<Card size="small" style={{ marginBottom: 16 }}>
|
||||
<List
|
||||
dataSource={visibleConversations}
|
||||
locale={{ emptyText: '暂无私信会话。' }}
|
||||
renderItem={(conversation: any) => (
|
||||
<List.Item
|
||||
style={{ cursor: 'pointer', padding: '8px 8px', background: conversation.id === conversationID ? '#e6f4ff' : undefined, borderRadius: 4 }}
|
||||
{/* List 已在 antd 6 弃用:会话切换用按钮列表(Flex vertical + Button block)等价实现。 */}
|
||||
<Flex vertical gap={4}>
|
||||
{visibleConversations.map((conversation: any) => (
|
||||
<Button
|
||||
key={conversation.id}
|
||||
block
|
||||
style={{
|
||||
height: 'auto',
|
||||
padding: '8px 8px',
|
||||
textAlign: 'left',
|
||||
whiteSpace: 'normal',
|
||||
background: conversation.id === conversationID ? '#e6f4ff' : undefined,
|
||||
}}
|
||||
type={conversation.id === conversationID ? 'primary' : 'default'}
|
||||
ghost={conversation.id === conversationID}
|
||||
onClick={() => switchConversation(conversation.id)}
|
||||
>
|
||||
<div style={{ minWidth: 0 }}>
|
||||
@@ -882,9 +891,9 @@ export default function Page() {
|
||||
{conversation.peer_uid}
|
||||
</Typography.Paragraph>
|
||||
</div>
|
||||
</List.Item>
|
||||
)}
|
||||
/>
|
||||
</Button>
|
||||
))}
|
||||
</Flex>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col xs={24} lg={17}>
|
||||
@@ -910,14 +919,14 @@ export default function Page() {
|
||||
</Space>
|
||||
</div>
|
||||
{messageError ? (
|
||||
<Alert type="error" showIcon style={{ marginBottom: 12 }} message={messageError.message} action={<Button size="small" onClick={() => setMessageRetry((value) => value + 1)}>重试</Button>} />
|
||||
<Alert type="error" showIcon style={{ marginBottom: 12 }} title={messageError.message} action={<Button size="small" onClick={() => setMessageRetry((value) => value + 1)}>重试</Button>} />
|
||||
) : null}
|
||||
<Spin spinning={messagePending}>
|
||||
{!messagePending && !messageError && !messages.length ? (
|
||||
<Empty description="暂无消息记录。" />
|
||||
) : (
|
||||
<>
|
||||
<Space direction="vertical" size={12} style={{ width: '100%' }}>
|
||||
<Flex>
|
||||
{messages.map((msg: any) => (
|
||||
<div
|
||||
key={msg.id}
|
||||
@@ -935,7 +944,7 @@ export default function Page() {
|
||||
</Typography.Text>
|
||||
</div>
|
||||
))}
|
||||
</Space>
|
||||
</Flex>
|
||||
<PageNav page={messagePage} total={messagePageInfo.total} count={messages.length} hasNext={messagePageInfo.hasNext} onPageChange={setMessagePage} />
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { history, useParams } from '@umijs/max';
|
||||
import {
|
||||
Flex,
|
||||
Alert,
|
||||
Button,
|
||||
Card,
|
||||
@@ -64,7 +65,7 @@ export default function Page() {
|
||||
}, [load]);
|
||||
|
||||
if (pending) return <Card loading />;
|
||||
if (error || !draft) return <Alert type="error" showIcon message={error?.message || '草稿不存在'} />;
|
||||
if (error || !draft) return <Alert type="error" showIcon title={error?.message || '草稿不存在'} />;
|
||||
|
||||
const versions = draft.versions || [];
|
||||
const confirmations = draft.confirmations || [];
|
||||
@@ -119,14 +120,14 @@ export default function Page() {
|
||||
<Button onClick={() => history.push(`/accounts/${draft.account_id}`)}>返回账号详情</Button>
|
||||
</div>
|
||||
{browsersError ? (
|
||||
<Alert type="error" showIcon style={{ marginBottom: 16 }} message="环境不可用:当前运行环境与网络出口状态未知,不能确认或排队。" />
|
||||
<Alert type="error" showIcon style={{ marginBottom: 16 }} title="环境不可用:当前运行环境与网络出口状态未知,不能确认或排队。" />
|
||||
) : null}
|
||||
{!isLatest ? (
|
||||
<Alert
|
||||
type="info"
|
||||
showIcon
|
||||
style={{ marginBottom: 16 }}
|
||||
message={`当前只读快照已不是最新草稿版本,请刷新到版本 ${latestVersion} 后重新核对。`}
|
||||
title={`当前只读快照已不是最新草稿版本,请刷新到版本 ${latestVersion} 后重新核对。`}
|
||||
action={
|
||||
<Button size="small" onClick={() => history.push(`/drafts/${versions[0]?.id}`)}>
|
||||
打开最新版本
|
||||
@@ -134,12 +135,12 @@ export default function Page() {
|
||||
}
|
||||
/>
|
||||
) : null}
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={16}>
|
||||
<Flex>
|
||||
<Card title="只读内容快照">
|
||||
<Typography.Paragraph style={{ whiteSpace: 'pre-wrap', marginBottom: 0 }}>{draft.content}</Typography.Paragraph>
|
||||
</Card>
|
||||
<Card title="版本与当前资源">
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={16}>
|
||||
<Flex>
|
||||
<Descriptions column={1} bordered size="small">
|
||||
<Descriptions.Item label="账号版本">{draft.account.version}</Descriptions.Item>
|
||||
<Descriptions.Item label="草稿版本">{draft.version}</Descriptions.Item>
|
||||
@@ -147,10 +148,10 @@ export default function Page() {
|
||||
<Descriptions.Item label="网络出口">{browsersError ? '状态未知' : binding?.network_exit_id || '当前机器直连'}</Descriptions.Item>
|
||||
</Descriptions>
|
||||
<Tag color={readiness.ready ? 'success' : 'warning'}>{readiness.label}</Tag>
|
||||
</Space>
|
||||
</Flex>
|
||||
</Card>
|
||||
<Card title="版本链">
|
||||
<Space direction="vertical" size={4}>
|
||||
<Flex>
|
||||
{versions.map((item: any) =>
|
||||
item.id === draft.id ? (
|
||||
<Typography.Text key={item.id} strong>
|
||||
@@ -162,10 +163,10 @@ export default function Page() {
|
||||
</Button>
|
||||
),
|
||||
)}
|
||||
</Space>
|
||||
</Flex>
|
||||
</Card>
|
||||
<Card title="显式核对与入队">
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={16}>
|
||||
<Flex>
|
||||
<Checkbox checked={reviewed} onChange={(e) => setReviewed(e.target.checked)}>
|
||||
我已核对当前账号、草稿内容、运行环境和网络出口
|
||||
</Checkbox>
|
||||
@@ -186,23 +187,23 @@ export default function Page() {
|
||||
) : (
|
||||
<Typography.Text type="secondary">保存有效确认后才可加入队列。</Typography.Text>
|
||||
)}
|
||||
</Space>
|
||||
</Flex>
|
||||
</Card>
|
||||
<Card title="关联任务">
|
||||
{tasks.length === 0 ? (
|
||||
<Typography.Text type="secondary">尚未入队。</Typography.Text>
|
||||
) : (
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={8}>
|
||||
<Flex>
|
||||
{tasks.map((task: any) => (
|
||||
<Card key={task.id} size="small">
|
||||
<Typography.Text strong>{task.id}</Typography.Text>
|
||||
<Typography.Paragraph style={{ marginBottom: 0 }}>任务状态:{task.state}</Typography.Paragraph>
|
||||
</Card>
|
||||
))}
|
||||
</Space>
|
||||
</Flex>
|
||||
)}
|
||||
</Card>
|
||||
</Space>
|
||||
</Flex>
|
||||
<Modal
|
||||
open={confirmOpen}
|
||||
title="确认草稿版本"
|
||||
|
||||
@@ -33,7 +33,7 @@ function GatewayFormModal({
|
||||
|
||||
return (
|
||||
<Modal open={open} title={editing ? '编辑网关' : '注册网关'} onCancel={onCancel} onOk={() => form.submit()} confirmLoading={busy} okText={busy ? (editing ? '保存中…' : '注册中…') : editing ? '保存' : '注册网关'}>
|
||||
{error ? <Alert type="error" showIcon style={{ marginBottom: 16 }} message={error.message} /> : null}
|
||||
{error ? <Alert type="error" showIcon style={{ marginBottom: 16 }} title={error.message} /> : null}
|
||||
<Form form={form} layout="vertical" onFinish={onSubmit}>
|
||||
<Form.Item
|
||||
name="name"
|
||||
@@ -184,7 +184,7 @@ export default function Page() {
|
||||
type="success"
|
||||
showIcon
|
||||
style={{ marginBottom: 16 }}
|
||||
message={
|
||||
title={
|
||||
<Space size={4}>
|
||||
<span>网关 {created.name} 已注册。令牌</span>
|
||||
<Typography.Text code>{created.token}</Typography.Text>
|
||||
@@ -203,7 +203,7 @@ export default function Page() {
|
||||
/>
|
||||
) : null}
|
||||
{error ? (
|
||||
<Alert type="error" showIcon style={{ marginBottom: 16 }} message={error.message} action={<Button size="small" onClick={load}>重试</Button>} />
|
||||
<Alert type="error" showIcon style={{ marginBottom: 16 }} title={error.message} action={<Button size="small" onClick={load}>重试</Button>} />
|
||||
) : null}
|
||||
<Table rowKey="name" columns={columns} dataSource={gateways} loading={pending} pagination={false} locale={{ emptyText: '暂无网关;注册后环境即可调度到该网关。' }} />
|
||||
<GatewayFormModal
|
||||
|
||||
@@ -45,7 +45,7 @@ export default function Page() {
|
||||
<Typography.Title level={4} style={{ marginBottom: 24, textAlign: 'center' }}>
|
||||
CreatorHub
|
||||
</Typography.Title>
|
||||
{error ? <Alert type="error" showIcon style={{ marginBottom: 16 }} message={error} /> : null}
|
||||
{error ? <Alert type="error" showIcon style={{ marginBottom: 16 }} title={error} /> : null}
|
||||
<Form form={form} layout="vertical" onFinish={onFinish} requiredMark={false}>
|
||||
<Form.Item name="username" label="用户名" rules={[{ required: true, message: '请输入用户名' }]}>
|
||||
<Input autoComplete="username" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// 网络出口详情:语义对齐 web.archived NetworkExitsPage.jsx 的 NetworkExitDetail。
|
||||
import { useEffect, useState } from 'react';
|
||||
import { history, useParams } from '@umijs/max';
|
||||
import { Alert, Button, Card, Descriptions, Space, Tag, Typography } from 'antd';
|
||||
import { Flex, Alert, Button, Card, Descriptions, Space, Tag, Typography } from 'antd';
|
||||
import { getOne } from '@/services/api';
|
||||
import { dateTime } from '@/utils/helpers';
|
||||
|
||||
@@ -38,7 +38,7 @@ export default function Page() {
|
||||
}, [id]);
|
||||
|
||||
if (pending) return <Card loading />;
|
||||
if (error || !exit) return <Alert type="error" showIcon message={error?.message || '网络出口不存在'} />;
|
||||
if (error || !exit) return <Alert type="error" showIcon title={error?.message || '网络出口不存在'} />;
|
||||
|
||||
const known = Object.hasOwn(healthText, exit.health_status ?? '');
|
||||
return (
|
||||
@@ -52,7 +52,7 @@ export default function Page() {
|
||||
<Button onClick={() => history.push('/network-exits')}>返回出口列表</Button>
|
||||
</div>
|
||||
<Card>
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={16}>
|
||||
<Flex>
|
||||
<Tag color={exit.health_status === 'healthy' ? 'success' : exit.health_status === 'disabled' ? 'default' : exit.health_status === 'unchecked' ? 'warning' : 'error'}>
|
||||
{known ? healthText[exit.health_status] : `未知状态:${exit.health_status}`}
|
||||
</Tag>
|
||||
@@ -68,7 +68,7 @@ export default function Page() {
|
||||
<Descriptions.Item label="出口IP">{exit.observed_public_ip || '尚无观测'}</Descriptions.Item>
|
||||
<Descriptions.Item label="最近检测">{exit.last_checked_at ? dateTime(exit.last_checked_at) : '未检测'}</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</Space>
|
||||
</Flex>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -64,7 +64,7 @@ function ExitFormModal({
|
||||
|
||||
return (
|
||||
<Modal open={open} title={title} onCancel={onCancel} onOk={() => form.submit()} confirmLoading={busy} okText={busy ? '保存中…' : submitLabel} width={640}>
|
||||
{error ? <Alert type="error" showIcon style={{ marginBottom: 16 }} message={conflictMessage(error, '出口地址或认证信息与现有资源冲突;表单内容已保留。')} /> : null}
|
||||
{error ? <Alert type="error" showIcon style={{ marginBottom: 16 }} title={conflictMessage(error, '出口地址或认证信息与现有资源冲突;表单内容已保留。')} /> : null}
|
||||
<Form form={form} layout="vertical" onFinish={onSubmit}>
|
||||
<Space size={16} wrap style={{ display: 'flex' }}>
|
||||
<Form.Item name="protocol" label="协议" required rules={[{ required: true }]} extra="代理协议">
|
||||
@@ -288,14 +288,14 @@ export default function Page() {
|
||||
<Card variant="outlined">
|
||||
{contextHolder}
|
||||
{error ? (
|
||||
<Alert type="error" showIcon style={{ marginBottom: 16 }} message={error.message} action={<Button size="small" onClick={load}>重试</Button>} />
|
||||
<Alert type="error" showIcon style={{ marginBottom: 16 }} title={error.message} action={<Button size="small" onClick={load}>重试</Button>} />
|
||||
) : null}
|
||||
{bindingsError ? (
|
||||
<Alert
|
||||
type="error"
|
||||
showIcon
|
||||
style={{ marginBottom: 16 }}
|
||||
message={`环境不可用${bindingsError.status ? `(${bindingsError.status})` : ''}:无法读取账号绑定,状态暂时未知。`}
|
||||
title={`环境不可用${bindingsError.status ? `(${bindingsError.status})` : ''}:无法读取账号绑定,状态暂时未知。`}
|
||||
action={
|
||||
<Button size="small" onClick={loadBindings}>
|
||||
重试环境状态
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// 四卡改用 Tabs(当前状态 / 确认快照 / 执行关联 / 唯一安全动作)——antd 默认组件的信息组织方式。
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { history, useParams } from '@umijs/max';
|
||||
import { Alert, Button, Card, Descriptions, Select, Space, Tabs, Tag, Typography, message } from 'antd';
|
||||
import { Flex, Alert, Button, Card, Descriptions, Select, Space, Tabs, Tag, Typography, message } from 'antd';
|
||||
import { getOne, taskAction } from '@/services/api';
|
||||
import { dateTime } from '@/utils/helpers';
|
||||
|
||||
@@ -100,7 +100,7 @@ export default function Page() {
|
||||
}
|
||||
|
||||
if (pending) return <Card loading />;
|
||||
if (error || !task) return <Alert type="error" showIcon message={error?.message || '任务不存在'} />;
|
||||
if (error || !task) return <Alert type="error" showIcon title={error?.message || '任务不存在'} />;
|
||||
|
||||
const confirmation = task.confirmation || {};
|
||||
const unknownHold = task.hold_reason && !holdText[task.hold_reason];
|
||||
@@ -110,20 +110,20 @@ export default function Page() {
|
||||
key: 'status',
|
||||
label: '当前状态',
|
||||
children: (
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={16}>
|
||||
<Flex>
|
||||
<Tag color={stateColor[task.state] || 'default'}>{stateText[task.state] || `未知状态:${task.state}`}</Tag>
|
||||
<Descriptions column={1} bordered size="small">
|
||||
<Descriptions.Item label="停止原因">{holdLabel(task.hold_reason)}</Descriptions.Item>
|
||||
<Descriptions.Item label="人工核验">{task.verification_result || '尚未记录'}</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</Space>
|
||||
</Flex>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'confirmation',
|
||||
label: '确认快照',
|
||||
children: (
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={16}>
|
||||
<Flex>
|
||||
<Descriptions column={1} bordered size="small">
|
||||
<Descriptions.Item label="确认">
|
||||
<Typography.Text copyable>{confirmation.id || '未记录'}</Typography.Text> · v{confirmation.version || '—'}
|
||||
@@ -141,14 +141,14 @@ export default function Page() {
|
||||
查看草稿
|
||||
</Button>
|
||||
</Space>
|
||||
</Space>
|
||||
</Flex>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'execution',
|
||||
label: '执行关联',
|
||||
children: (
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={16}>
|
||||
<Flex>
|
||||
<Descriptions column={1} bordered size="small">
|
||||
<Descriptions.Item label="环境">{task.browser_env_alias || '未记录'}</Descriptions.Item>
|
||||
<Descriptions.Item label="固定出口">{task.network_exit_id || '未记录'}</Descriptions.Item>
|
||||
@@ -168,18 +168,18 @@ export default function Page() {
|
||||
</Button>
|
||||
) : null}
|
||||
</Space>
|
||||
</Space>
|
||||
</Flex>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'action',
|
||||
label: '唯一安全动作',
|
||||
children: (
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={16}>
|
||||
{task.readiness_reason ? <Alert type="info" showIcon message={`当前仍被阻断:${holdLabel(task.readiness_reason)}。修复原资源并刷新后,才会开放恢复。`} /> : null}
|
||||
<Flex>
|
||||
{task.readiness_reason ? <Alert type="info" showIcon title={`当前仍被阻断:${holdLabel(task.readiness_reason)}。修复原资源并刷新后,才会开放恢复。`} /> : null}
|
||||
{task.allowed_action === 'verify' ? (
|
||||
<>
|
||||
<Alert type="info" showIcon message='先在原环境和原出口核验真实结果。选择"未执行"不会立即重试,仍需下一步显式恢复。' />
|
||||
<Alert type="info" showIcon title='先在原环境和原出口核验真实结果。选择"未执行"不会立即重试,仍需下一步显式恢复。' />
|
||||
<Select
|
||||
style={{ width: 280 }}
|
||||
value={verification}
|
||||
@@ -209,14 +209,14 @@ export default function Page() {
|
||||
) : null}
|
||||
{task.allowed_action === 'reconfirm' ? (
|
||||
<>
|
||||
<Alert type="info" showIcon message="版本已变化,旧确认不可继续使用。" />
|
||||
<Alert type="info" showIcon title="版本已变化,旧确认不可继续使用。" />
|
||||
<Button type="primary" onClick={() => history.push(`/drafts/${task.draft_id}`)}>
|
||||
重新核对并确认草稿
|
||||
</Button>
|
||||
</>
|
||||
) : null}
|
||||
{task.allowed_action ? null : <Typography.Text type="secondary">当前没有可安全执行的动作。</Typography.Text>}
|
||||
</Space>
|
||||
</Flex>
|
||||
),
|
||||
},
|
||||
];
|
||||
@@ -233,11 +233,11 @@ export default function Page() {
|
||||
</div>
|
||||
<Button onClick={() => history.push('/tasks')}>返回任务中心</Button>
|
||||
</div>
|
||||
{unknownHold ? <Alert type="warning" showIcon style={{ marginBottom: 16 }} message={`后端返回了未知停止原因"${task.hold_reason}";为避免不安全操作,本页不提供恢复动作。`} /> : null}
|
||||
{unknownHold ? <Alert type="warning" showIcon style={{ marginBottom: 16 }} title={`后端返回了未知停止原因"${task.hold_reason}";为避免不安全操作,本页不提供恢复动作。`} /> : null}
|
||||
<Tabs defaultActiveKey="status" items={items} />
|
||||
<Typography.Title level={5} style={{ marginTop: 24, marginBottom: 12 }}>执行尝试</Typography.Title>
|
||||
{task.attempts?.length ? (
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={12}>
|
||||
<Flex>
|
||||
{task.attempts.map((attempt: any) => (
|
||||
<Card key={attempt.id} size="small">
|
||||
<Typography.Link onClick={() => history.push(`/attempts/${encodeURIComponent(attempt.id)}`)}>{attempt.id}</Typography.Link>
|
||||
@@ -247,7 +247,7 @@ export default function Page() {
|
||||
<Typography.Text type="secondary">脱敏证据:{attempt.evidence?.mock_outcome || '无可公开证据'}</Typography.Text>
|
||||
</Card>
|
||||
))}
|
||||
</Space>
|
||||
</Flex>
|
||||
) : (
|
||||
<Card size="small">
|
||||
<Typography.Text type="secondary">尚未产生执行尝试。</Typography.Text>
|
||||
|
||||
@@ -131,7 +131,7 @@ export default function Page() {
|
||||
</Space>
|
||||
</Card>
|
||||
<Card variant="outlined">
|
||||
{error ? <Alert type="error" showIcon style={{ marginBottom: 16 }} message={error.message} action={<Button size="small" onClick={load}>重试</Button>} /> : null}
|
||||
{error ? <Alert type="error" showIcon style={{ marginBottom: 16 }} title={error.message} action={<Button size="small" onClick={load}>重试</Button>} /> : null}
|
||||
<Table
|
||||
rowKey="id"
|
||||
columns={columns}
|
||||
|
||||
Reference in New Issue
Block a user