授权管理新增消耗列表
This commit is contained in:
+1
-1
@@ -21,4 +21,4 @@ video-gen-api/dist/
|
||||
|
||||
# 忽略特定类型文件但保留目录
|
||||
# *.pyc
|
||||
# !dir/*.pyc
|
||||
# !dir/*.pycnode_modules/
|
||||
|
||||
@@ -13,10 +13,6 @@ import InitialReplication from './pages/InitialReplication';
|
||||
import RemoveLens from './pages/RemoveLens';
|
||||
import GeneratedRecord from './pages/GeneratedRecord';
|
||||
import AuthorizationPage from './pages/AuthorizationPage';
|
||||
|
||||
|
||||
|
||||
|
||||
import { useAuthStore } from './store/useAuthStore';
|
||||
|
||||
const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
|
||||
@@ -96,10 +92,6 @@ const App = () => {
|
||||
<Route path="generated" element={<GeneratedRecord />} />
|
||||
<Route path="authorization" element={<AuthorizationPage />} />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</Route>
|
||||
<Route path="*" element={<Navigate to="/projects" replace />} />
|
||||
</Routes>
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import React, { useEffect, useState, useLayoutEffect, useRef, useCallback } from 'react';
|
||||
import { Button, Table, Checkbox, Tag, Space, message } from 'antd';
|
||||
import { PlusOutlined, CheckCircleOutlined, ClockCircleOutlined, CiCircleOutlined } from '@ant-design/icons';
|
||||
|
||||
import { Button, Table, Checkbox, Tag, Space, message, Modal } from 'antd';
|
||||
import { PlusOutlined, CheckCircleOutlined, ClockCircleOutlined, CiCircleOutlined, EyeOutlined, XOutlined } from '@ant-design/icons';
|
||||
// 模拟授权数据
|
||||
const mockAuthorizations = [
|
||||
{ id: '1867060028363785', status: 'active', description: '用户张三的API授权' },
|
||||
{ id: '1867059757929740', status: 'pending', description: '用户李四的API授权' },
|
||||
{ id: '1867059808785418', status: 'active', description: '用户王五的API授权' },
|
||||
];
|
||||
|
||||
// 状态配置
|
||||
const statusConfig = {
|
||||
active: { label: '已授权', color: 'green', icon: CheckCircleOutlined },
|
||||
@@ -17,10 +15,27 @@ const statusConfig = {
|
||||
revoked: { label: '已撤销', color: 'gray', icon: CiCircleOutlined },
|
||||
};
|
||||
|
||||
// 模拟消耗记录数据
|
||||
const mockConsumptionRecords = [
|
||||
{ id: 'C001', authorizationId: '1867060028363785', amount: 100, type: 'video', description: '视频生成消耗', createdAt: '2024-01-15 10:30:00' },
|
||||
{ id: 'C002', authorizationId: '1867060028363785', amount: 50, type: 'audio', description: '音频转换消耗', createdAt: '2024-01-15 11:20:00' },
|
||||
{ id: 'C003', authorizationId: '1867059808785418', amount: 200, type: 'video', description: '视频生成消耗', createdAt: '2024-01-14 14:45:00' },
|
||||
{ id: 'C004', authorizationId: '1867060028363785', amount: 75, type: 'image', description: '图片处理消耗', createdAt: '2024-01-14 09:15:00' },
|
||||
{ id: 'C005', authorizationId: '1867059757929740', amount: 150, type: 'video', description: '视频生成消耗', createdAt: '2024-01-13 16:00:00' },
|
||||
];
|
||||
|
||||
// 消耗类型配置
|
||||
const consumptionTypeConfig = {
|
||||
video: { label: '视频生成', color: 'blue' },
|
||||
audio: { label: '音频转换', color: 'purple' },
|
||||
image: { label: '图片处理', color: 'green' },
|
||||
};
|
||||
const AuthorizationPage: React.FC = () => {
|
||||
const [authorizations, setAuthorizations] = useState(mockAuthorizations);
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<string[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [showConsumptionModal, setShowConsumptionModal] = useState(false);
|
||||
const [consumptionRecords, setConsumptionRecords] = useState(mockConsumptionRecords);
|
||||
|
||||
// 状态标签渲染
|
||||
const renderStatus = (status: string) => {
|
||||
@@ -77,6 +92,26 @@ const AuthorizationPage: React.FC = () => {
|
||||
width: 140,
|
||||
render: (text: string) => renderStatus(text),
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'operation',
|
||||
key: 'operation',
|
||||
width: 120,
|
||||
render: (_: any, record: typeof mockAuthorizations[0]) => (
|
||||
<Button
|
||||
type="primary"
|
||||
size="small"
|
||||
style={{
|
||||
borderRadius: 8,
|
||||
// background: 'linear-gradient(135deg, #6366f1, #8b5cf6)',
|
||||
border: 'none',
|
||||
}}
|
||||
onClick={() => setShowConsumptionModal(true)}
|
||||
>
|
||||
查款消耗
|
||||
</Button>
|
||||
),
|
||||
}
|
||||
];
|
||||
|
||||
// 处理点击授权按钮
|
||||
@@ -85,7 +120,6 @@ const AuthorizationPage: React.FC = () => {
|
||||
message.warning('请先选择需要授权的记录');
|
||||
return;
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
// 模拟授权操作
|
||||
setTimeout(() => {
|
||||
@@ -107,6 +141,13 @@ const AuthorizationPage: React.FC = () => {
|
||||
key: item.id,
|
||||
}));
|
||||
|
||||
// 准备消耗记录表格数据(添加序号)
|
||||
const consumptionTableData = consumptionRecords.map((item, index) => ({
|
||||
...item,
|
||||
index: index + 1,
|
||||
key: item.id,
|
||||
}));
|
||||
|
||||
return (
|
||||
<div style={{ padding: 24, minHeight: '94vh', background: '#f8fafc' }}>
|
||||
{/* 页面标题 */}
|
||||
@@ -118,7 +159,7 @@ const AuthorizationPage: React.FC = () => {
|
||||
</div>
|
||||
|
||||
{/* 操作栏 */}
|
||||
<div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: 16 }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'flex-end', gap: 12, marginBottom: 16 }}>
|
||||
<Button
|
||||
type="primary"
|
||||
size="large"
|
||||
@@ -159,6 +200,81 @@ const AuthorizationPage: React.FC = () => {
|
||||
{/* <div style={{ marginTop: 16, textAlign: 'center', color: '#94a3b8', fontSize: 13 }}>
|
||||
提示:勾选记录后点击"点击授权"按钮可批量授权
|
||||
</div> */}
|
||||
|
||||
{/* 消耗记录弹窗 */}
|
||||
<Modal
|
||||
title="消耗记录"
|
||||
open={showConsumptionModal}
|
||||
onCancel={() => setShowConsumptionModal(false)}
|
||||
footer={null}
|
||||
width={800}
|
||||
destroyOnClose={true}
|
||||
>
|
||||
<div style={{ padding: 16 }}>
|
||||
<Table
|
||||
dataSource={consumptionTableData}
|
||||
columns={[
|
||||
{
|
||||
title: '序号',
|
||||
dataIndex: 'index',
|
||||
key: 'index',
|
||||
width: 80,
|
||||
render: (text: number) => <span style={{ color: '#94a3b8' }}>{text}</span>,
|
||||
},
|
||||
{
|
||||
title: '消耗ID',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
ellipsis: true,
|
||||
render: (text: string) => <span style={{ fontWeight: 500, color: '#1e293b' }}>{text}</span>,
|
||||
},
|
||||
{
|
||||
title: '授权ID',
|
||||
dataIndex: 'authorizationId',
|
||||
key: 'authorizationId',
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: '消耗类型',
|
||||
dataIndex: 'type',
|
||||
key: 'type',
|
||||
width: 120,
|
||||
render: (text: string) => {
|
||||
const config = consumptionTypeConfig[text as keyof typeof consumptionTypeConfig];
|
||||
return <Tag color={config?.color}>{config?.label}</Tag>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '消耗金额',
|
||||
dataIndex: 'amount',
|
||||
key: 'amount',
|
||||
width: 120,
|
||||
render: (text: number) => <span style={{ color: '#ef4444', fontWeight: 500 }}>{text} 元</span>,
|
||||
},
|
||||
{
|
||||
title: '消耗描述',
|
||||
dataIndex: 'description',
|
||||
key: 'description',
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: '消耗时间',
|
||||
dataIndex: 'createdAt',
|
||||
key: 'createdAt',
|
||||
width: 160,
|
||||
},
|
||||
]}
|
||||
pagination={{
|
||||
pageSize: 10,
|
||||
showSizeChanger: true,
|
||||
showTotal: (total) => `共 ${total} 条记录`,
|
||||
}}
|
||||
rowKey="id"
|
||||
bordered={false}
|
||||
scroll={{ x: 'max-content' }}
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -154,9 +154,6 @@ const RecordsPage: React.FC = () => {
|
||||
const isGenerating = generating[record.id];
|
||||
const isExpanded = expandedId === record.id;
|
||||
const type: any = record.genType || 'image';
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div key={record.id} className="animate-slideInCard" style={{ animationDelay: `${i * 0.04}s` }}>
|
||||
{/* Record summary row */}
|
||||
|
||||
Reference in New Issue
Block a user