Cookie 管理优化

This commit is contained in:
yml2213
2026-06-22 16:36:23 +08:00
parent 48b6a1623b
commit 480dfa6085
2 changed files with 81 additions and 12 deletions
+2
View File
@@ -37,6 +37,8 @@ def list_cookies(
"batch_id": t.batch_id,
"account_id": t.account_id,
"account_username": acc.username if acc else "",
"assigned_to": acc.assigned_to,
"assigned_username": acc.assigned_user.username if acc and acc.assigned_user else None,
"created_at": t.finished_at.isoformat() if t.finished_at else None,
}
# 只有有 cookie:view 权限才返回 cookie 内容
+79 -12
View File
@@ -1,13 +1,16 @@
import { useEffect, useState } from 'react';
import { Table, Button, Card, Row, Col, Statistic, message, Tag, Popconfirm, Space } from 'antd';
import { DownloadOutlined, DeleteOutlined, CopyOutlined } from '@ant-design/icons';
import { Table, Button, Card, Row, Col, Statistic, message, Tag, Popconfirm, Space, Typography, Input } from 'antd';
import { DownloadOutlined, DeleteOutlined, CopyOutlined, SearchOutlined } from '@ant-design/icons';
import { cookieApi } from '../api/modules';
import { getUser, hasPerm } from '../store/auth';
const { Text } = Typography;
export default function CookiePage() {
const [cookies, setCookies] = useState<any[]>([]);
const [loading, setLoading] = useState(false);
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
const [searchText, setSearchText] = useState('');
const user = getUser();
const canView = hasPerm(user, 'cookie:view');
@@ -83,9 +86,32 @@ export default function CookiePage() {
}
};
// 筛选
const filteredCookies = cookies.filter((c) => {
if (!searchText) return true;
const s = searchText.toLowerCase();
return (
c.account_username?.toLowerCase().includes(s) ||
c.assigned_username?.toLowerCase().includes(s)
);
});
const columns: any[] = [
{ title: 'ID', dataIndex: 'id', width: 60 },
{ title: '账号', dataIndex: 'account_username' },
{ title: 'ID', dataIndex: 'id', width: 60, align: 'center' },
{
title: '账号',
dataIndex: 'account_username',
width: 140,
ellipsis: true,
},
{
title: '分配',
dataIndex: 'assigned_username',
width: 100,
align: 'center',
render: (name: string | null) =>
name ? <Tag color="green" size="small">{name}</Tag> : <Text type="secondary" style={{ fontSize: 12 }}></Text>,
},
{
title: 'Cookie',
dataIndex: 'cookie_preview',
@@ -95,10 +121,18 @@ export default function CookiePage() {
return <span style={{ fontFamily: 'monospace', fontSize: 12 }}>{val}</span>;
},
},
{ title: '时间', dataIndex: 'created_at', width: 170 },
{
title: '时间',
dataIndex: 'created_at',
width: 180,
align: 'center',
render: (val: string) => val ? val.replace('T', ' ').slice(0, 19) : '-',
},
{
title: '操作',
width: 160,
width: 130,
align: 'center',
fixed: 'right',
render: (_: any, record: any) => (
<Space size={4}>
<Button
@@ -118,10 +152,13 @@ export default function CookiePage() {
},
];
const assignedCount = cookies.filter((c) => c.assigned_to).length;
const unassignedCount = cookies.length - assignedCount;
return (
<div>
<div style={{ marginBottom: 16, display: 'flex', justifyContent: 'space-between' }}>
<h2>Cookie </h2>
<div style={{ marginBottom: 16, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<h2 style={{ margin: 0 }}>Cookie </h2>
<Space>
<Button
icon={<CopyOutlined />}
@@ -137,23 +174,53 @@ export default function CookiePage() {
)}
</Space>
</div>
<Row gutter={16} style={{ marginBottom: 16 }}>
<Row gutter={12} style={{ marginBottom: 16 }}>
<Col span={6}>
<Card size="small"><Statistic title="Cookie 总数" value={cookies.length} /></Card>
</Col>
<Col span={6}>
<Card size="small">
<Statistic
title="已分配"
value={assignedCount}
valueStyle={{ color: '#3f8600' }}
/>
</Card>
</Col>
<Col span={6}>
<Card size="small">
<Statistic
title="未分配"
value={unassignedCount}
valueStyle={{ color: '#cf1322' }}
/>
</Card>
</Col>
</Row>
<div style={{ marginBottom: 12 }}>
<Input.Search
placeholder="搜索账号或分配客服"
allowClear
value={searchText}
onChange={(e) => setSearchText(e.target.value)}
style={{ width: 260 }}
size="small"
prefix={<SearchOutlined />}
/>
</div>
<Table
rowSelection={{
selectedRowKeys,
onChange: (keys) => setSelectedRowKeys(keys),
}}
columns={columns}
dataSource={cookies}
dataSource={filteredCookies}
rowKey="id"
loading={loading}
size="small"
pagination={{ pageSize: 20 }}
pagination={{ pageSize: 20, showSizeChanger: true, showTotal: (t) => `${t}` }}
scroll={{ x: 900 }}
/>
</div>
);
}
}