fix(web): 编辑社媒账号页对齐全站布局——页头槽接管标识与操作,主体两张 Card 承载
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
// 编辑社媒账号:账号资料维护 + 登录二维码/身份核验。
|
||||
// 布局对齐全站模式:实体标识经 usePageInfo 进页头 content 左侧,返回/登录操作按钮经 usePageActions 进页头右侧;
|
||||
// 主体两张 Card 纵向堆叠(登录状态 / 账号资料),不再自绘标题行、不再裸铺背景。
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { history, useParams } from '@umijs/max';
|
||||
import { Alert, App, Button, Card, Descriptions, Flex, Form, Input, InputNumber, Select, Space, Typography } from 'antd';
|
||||
import { Alert, App, Button, Card, Descriptions, Divider, Flex, Form, Input, Select, Space, Typography } from 'antd';
|
||||
import { usePageActions, usePageInfo } from '@/components/PageActions';
|
||||
import { creatorAction, creatorGet, creatorUpdate, getList } from '@/services/api';
|
||||
import { conflictMessage, dateTime } from '@/utils/helpers';
|
||||
|
||||
@@ -30,6 +33,35 @@ export default function Page() {
|
||||
|
||||
const selected = profiles.find((item) => item.id === selectedID);
|
||||
|
||||
// 页头 content 行左侧:实体标识(账号名 + 平台/账号 ID),与详情页同形态。
|
||||
usePageInfo(
|
||||
selected ? (
|
||||
<Flex align="center" gap={8} wrap="wrap">
|
||||
<Typography.Title level={5} style={{ marginBottom: 0 }} ellipsis>
|
||||
{selected.name || selected.platform_account_key}
|
||||
</Typography.Title>
|
||||
<Typography.Text type="secondary">
|
||||
{platformLabelMap[selected.platform] || selected.platform} · {selected.platform_account_key}
|
||||
</Typography.Text>
|
||||
</Flex>
|
||||
) : null,
|
||||
[selected?.id, selected?.name, selected?.platform],
|
||||
);
|
||||
|
||||
// 页头 content 行右侧:返回 + 登录操作,不在卡片内重复渲染。
|
||||
usePageActions(
|
||||
<Space>
|
||||
<Button onClick={() => history.push('/accounts')}>返回社媒账号</Button>
|
||||
<Button disabled={busy || !selected || selected.platform !== 'douyin'} onClick={requestLoginQR}>
|
||||
显示登录二维码
|
||||
</Button>
|
||||
<Button disabled={busy || !selected || selected.platform !== 'douyin'} onClick={verifyLogin}>
|
||||
核验浏览器身份
|
||||
</Button>
|
||||
</Space>,
|
||||
[selected?.id, selected?.platform],
|
||||
);
|
||||
|
||||
const load = useCallback(async () => {
|
||||
setPending(true);
|
||||
setError(null);
|
||||
@@ -121,39 +153,19 @@ export default function Page() {
|
||||
if (!selected) return <Alert type="warning" showIcon title="账号不存在。" />;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div style={{ marginBottom: 16, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<div>
|
||||
<Typography.Title level={4} style={{ marginBottom: 0 }}>
|
||||
{selected.name || selected.platform_account_key}
|
||||
</Typography.Title>
|
||||
<Typography.Text type="secondary">
|
||||
{platformLabelMap[selected.platform] || selected.platform} · {selected.platform_account_key}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
<Button onClick={() => history.push('/accounts')}>返回社媒账号</Button>
|
||||
</div>
|
||||
<Flex vertical gap={16}>
|
||||
<Flex>
|
||||
<Descriptions column={1} size="small" style={{ flex: 1, minWidth: 260 }}>
|
||||
<Descriptions.Item label="登录核验">
|
||||
{selected.login_status === 'logged_in' ? '已登录' : '需人工确认'}
|
||||
{selected.login_checked_at ? ` · ${dateTime(selected.login_checked_at)}` : ' · 尚未核验'}
|
||||
{selected.login_reason ? ` · ${selected.login_reason}` : ''}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="密码凭据">{selected.password_configured ? '已配置' : '未配置'}</Descriptions.Item>
|
||||
</Descriptions>
|
||||
<Space wrap>
|
||||
<Button disabled={busy || selected.platform !== 'douyin'} onClick={requestLoginQR}>
|
||||
显示登录二维码
|
||||
</Button>
|
||||
<Button disabled={busy || selected.platform !== 'douyin'} onClick={verifyLogin}>
|
||||
核验浏览器身份
|
||||
</Button>
|
||||
</Space>
|
||||
</Flex>
|
||||
<Flex vertical gap={16}>
|
||||
<Card title="登录状态">
|
||||
<Descriptions column={1} size="small">
|
||||
<Descriptions.Item label="登录核验">
|
||||
{selected.login_status === 'logged_in' ? '已登录' : '需人工确认'}
|
||||
{selected.login_checked_at ? ` · ${dateTime(selected.login_checked_at)}` : ' · 尚未核验'}
|
||||
{selected.login_reason ? ` · ${selected.login_reason}` : ''}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="密码凭据">{selected.password_configured ? '已配置' : '未配置'}</Descriptions.Item>
|
||||
</Descriptions>
|
||||
{loginQR ? (
|
||||
<Card size="small" title="人工登录" extra={<Button size="small" onClick={requestLoginQR} disabled={busy}>刷新登录画面</Button>}>
|
||||
<>
|
||||
<Divider />
|
||||
<Typography.Text type="secondary">
|
||||
{loginQR.qr_detected ? '请使用抖音 App 扫描下方二维码。' : '当前画面未检测到二维码,请按画面提示人工完成验证。'}
|
||||
</Typography.Text>
|
||||
@@ -165,8 +177,10 @@ export default function Page() {
|
||||
<Typography.Text type="secondary" style={{ display: 'block', marginTop: 8, fontSize: 12 }}>
|
||||
当前画面有效至 {dateTime(loginQR.expires_at)};完成扫码后请点击“核验浏览器身份”。
|
||||
</Typography.Text>
|
||||
</Card>
|
||||
</>
|
||||
) : null}
|
||||
</Card>
|
||||
<Card title="账号资料">
|
||||
<Form form={form} layout="vertical" onFinish={save} initialValues={profileForm(selected)}>
|
||||
<Space size={16} wrap style={{ display: 'flex' }}>
|
||||
<Form.Item name="login_username" label="登录用户名" extra="密码只会进入凭据存储,不会回传到页面。">
|
||||
@@ -206,14 +220,14 @@ export default function Page() {
|
||||
<Form.Item name="note" label="账号备注">
|
||||
<Input.TextArea />
|
||||
</Form.Item>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<Flex justify="space-between" align="center" gap={16} wrap="wrap">
|
||||
<Typography.Text type="secondary">最近更新:{selected.updated_at ? dateTime(selected.updated_at) : '—'}</Typography.Text>
|
||||
<Button type="primary" htmlType="submit" loading={busy}>
|
||||
{busy ? '保存中…' : '保存账号资料'}
|
||||
</Button>
|
||||
</div>
|
||||
</Flex>
|
||||
</Form>
|
||||
</Flex>
|
||||
</div>
|
||||
</Card>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user