优化任务操作台交互体验
This commit is contained in:
@@ -38,6 +38,9 @@ const QUICK_ACTIONS = [
|
||||
{ key: 'donate_elite_gift', icon: <GiftOutlined /> },
|
||||
];
|
||||
|
||||
const BIND_ACTION_KEYS = ['get_bind_qr', 'confirm_bind', 'query_game_name', 'query_change_bind_time'];
|
||||
const QUERY_ACTION_KEYS = ['query_points', 'query_limited_goods', 'query_gold_balance'];
|
||||
|
||||
const STATUS_COLORS: Record<string, string> = {
|
||||
planned: 'default', pending: 'default', running: 'processing',
|
||||
success: 'success', failed: 'error', error: 'error', stopped: 'warning',
|
||||
@@ -680,6 +683,48 @@ export default function DouyuTasksPage() {
|
||||
const payAccountName = payTask
|
||||
? (payTask.account_nickname || payTask.account_username || payTask.account_uid || `#${payTask.account_id}`)
|
||||
: '';
|
||||
const selectedText = selectedIds.length > 0 ? `已选 ${selectedIds.length} 个账号` : '请先勾选账号';
|
||||
const actionByKey = useMemo(() => new Map(QUICK_ACTIONS.map((item) => [item.key, item])), []);
|
||||
const actionDisabled = (taskType: string) => {
|
||||
if (batchBusy || selectedIds.length === 0) return true;
|
||||
if (taskType === 'exchange_goods') return !selectedGoodsId;
|
||||
return false;
|
||||
};
|
||||
const renderActionButton = (taskType: string, type: 'default' | 'primary' = 'default') => {
|
||||
const item = actionByKey.get(taskType);
|
||||
return (
|
||||
<Button
|
||||
key={taskType}
|
||||
size="small"
|
||||
block
|
||||
type={type}
|
||||
icon={item?.icon}
|
||||
onClick={() => startTask(taskType)}
|
||||
disabled={actionDisabled(taskType)}
|
||||
style={{ justifyContent: 'flex-start' }}
|
||||
>
|
||||
{taskTypes[taskType] || taskType}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
const sectionStyle = {
|
||||
border: '1px solid #f0f0f0',
|
||||
borderRadius: 6,
|
||||
padding: 8,
|
||||
background: '#fff',
|
||||
};
|
||||
const sectionTitleStyle = {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 6,
|
||||
marginBottom: 8,
|
||||
fontWeight: 600,
|
||||
};
|
||||
const actionGridStyle = {
|
||||
display: 'grid',
|
||||
gridTemplateColumns: '1fr 1fr',
|
||||
gap: 6,
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ height: '100%', display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
|
||||
@@ -765,63 +810,113 @@ export default function DouyuTasksPage() {
|
||||
|
||||
{/* Right: operations + logs */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 12, overflow: 'auto' }}>
|
||||
<Card size="small" title="操作" styles={{ body: { padding: 8 } }}>
|
||||
<Card
|
||||
size="small"
|
||||
title="操作"
|
||||
extra={<Tag color={selectedIds.length ? 'blue' : 'default'}>{selectedText}</Tag>}
|
||||
styles={{ body: { padding: 8 } }}
|
||||
>
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={8}>
|
||||
<Space style={{ width: '100%', justifyContent: 'space-between' }}>
|
||||
<Text type="secondary">{selectedIds.length > 0 ? `已选 ${selectedIds.length} 个账号` : '点击/右键选择账号'}</Text>
|
||||
<InputNumber size="small" min={1} max={10} value={concurrency} onChange={(v) => setConcurrency(v || 1)} style={{ width: 70 }} addonBefore="并发" />
|
||||
</Space>
|
||||
<Space wrap size={4}>
|
||||
{QUICK_ACTIONS.map((item) => (
|
||||
<Button
|
||||
key={item.key} size="small" icon={item.icon}
|
||||
onClick={() => startTask(item.key)}
|
||||
disabled={batchBusy || selectedIds.length === 0}
|
||||
>
|
||||
{taskTypes[item.key] || item.key}
|
||||
</Button>
|
||||
))}
|
||||
</Space>
|
||||
<Card size="small" title="兑换" styles={{ body: { padding: 8 } }}>
|
||||
<Space direction="vertical" style={{ width: '100%' }}>
|
||||
<Space.Compact style={{ width: '100%' }}>
|
||||
<Button size="small" disabled>并发</Button>
|
||||
<InputNumber
|
||||
size="small"
|
||||
min={1}
|
||||
max={10}
|
||||
value={concurrency}
|
||||
onChange={(v) => setConcurrency(v || 1)}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
</Space.Compact>
|
||||
|
||||
<div style={sectionStyle}>
|
||||
<div style={sectionTitleStyle}>
|
||||
<QrcodeOutlined />
|
||||
<span>绑定与角色</span>
|
||||
</div>
|
||||
<div style={actionGridStyle}>
|
||||
{BIND_ACTION_KEYS.map((key) => renderActionButton(key))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={sectionStyle}>
|
||||
<div style={sectionTitleStyle}>
|
||||
<SearchOutlined />
|
||||
<span>查询</span>
|
||||
</div>
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={6}>
|
||||
{QUERY_ACTION_KEYS.map((key) => renderActionButton(key))}
|
||||
</Space>
|
||||
</div>
|
||||
|
||||
<div style={sectionStyle}>
|
||||
<div style={sectionTitleStyle}>
|
||||
<ShoppingOutlined />
|
||||
<span>兑换</span>
|
||||
</div>
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={6}>
|
||||
<Select
|
||||
size="small" value={selectedGoodsId || undefined} onChange={setSelectedGoodsId}
|
||||
size="small"
|
||||
value={selectedGoodsId || undefined}
|
||||
onChange={setSelectedGoodsId}
|
||||
options={goods.map((item) => ({ value: item.commodity_id, label: goodsLabel(item) }))}
|
||||
placeholder="选择兑换商品" showSearch optionFilterProp="label"
|
||||
placeholder="选择兑换商品"
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
<Space>
|
||||
<Button size="small" icon={<ReloadOutlined />} onClick={() => startTask('refresh_goods')} disabled={batchBusy || selectedIds.length === 0}>
|
||||
刷新商品
|
||||
</Button>
|
||||
<div style={actionGridStyle}>
|
||||
{renderActionButton('refresh_goods')}
|
||||
{renderActionButton('exchange_goods', 'primary')}
|
||||
</div>
|
||||
</Space>
|
||||
</div>
|
||||
|
||||
<div style={sectionStyle}>
|
||||
<div style={sectionTitleStyle}>
|
||||
<CreditCardOutlined />
|
||||
<span>充值与送礼</span>
|
||||
</div>
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={6}>
|
||||
<Space.Compact style={{ width: '100%' }}>
|
||||
<InputNumber
|
||||
size="small"
|
||||
min={1}
|
||||
value={goldAmount}
|
||||
onChange={(v) => setGoldAmount(v || 1)}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
<Button
|
||||
size="small"
|
||||
type="primary"
|
||||
icon={<ShoppingOutlined />}
|
||||
onClick={() => startTask('exchange_goods')}
|
||||
disabled={batchBusy || selectedIds.length === 0 || !selectedGoodsId}
|
||||
icon={<CreditCardOutlined />}
|
||||
onClick={() => startTask('create_gold_qr')}
|
||||
disabled={actionDisabled('create_gold_qr')}
|
||||
>
|
||||
兑换商品
|
||||
</Button>
|
||||
</Space>
|
||||
</Space>
|
||||
</Card>
|
||||
<Card size="small" title="充值与送礼" styles={{ body: { padding: 8 } }}>
|
||||
<Space direction="vertical" style={{ width: '100%' }}>
|
||||
<Space>
|
||||
<InputNumber size="small" min={1} value={goldAmount} onChange={(v) => setGoldAmount(v || 1)} style={{ width: 80 }} />
|
||||
<Button size="small" icon={<CreditCardOutlined />} onClick={() => startTask('create_gold_qr')} disabled={batchBusy || selectedIds.length === 0}>
|
||||
充值鱼翅
|
||||
</Button>
|
||||
</Space>
|
||||
<Space>
|
||||
<InputNumber size="small" min={1} value={giftCount} onChange={(v) => setGiftCount(v || 1)} style={{ width: 80 }} />
|
||||
<Button size="small" icon={<GiftOutlined />} onClick={() => startTask('donate_elite_gift')} disabled={batchBusy || selectedIds.length === 0}>
|
||||
</Space.Compact>
|
||||
<Space.Compact style={{ width: '100%' }}>
|
||||
<InputNumber
|
||||
size="small"
|
||||
min={1}
|
||||
value={giftCount}
|
||||
onChange={(v) => setGiftCount(v || 1)}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
<Button
|
||||
size="small"
|
||||
icon={<GiftOutlined />}
|
||||
onClick={() => startTask('donate_elite_gift')}
|
||||
disabled={actionDisabled('donate_elite_gift')}
|
||||
>
|
||||
赠送精英令
|
||||
</Button>
|
||||
</Space>
|
||||
</Space.Compact>
|
||||
</Space>
|
||||
</Card>
|
||||
</div>
|
||||
<Text type="secondary" style={{ fontSize: 12 }}>
|
||||
勾选账号后可批量执行;右键账号行可快速执行单账号动作。
|
||||
</Text>
|
||||
</Space>
|
||||
</Card>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user