import React, { useState } from 'react'; import { useQueryClient } from '@tanstack/react-query'; import { Button, Table, Space, Form, Input, Select, message, Modal, Card, Row, Col, Popconfirm, Tag, DatePicker } from 'antd'; import { useQuery, } from '@tanstack/react-query'; import dayjs from 'dayjs'; import weekday from 'dayjs/plugin/weekday'; import localeData from 'dayjs/plugin/localeData'; import 'dayjs/locale/zh-cn'; import type { SubmissionRecord, SubmissionRecordListResponse } from '../share/types_stock.ts'; import { SubmissionRecordStatus, SubmissionRecordStatusNameMap, } from '../share/types_stock.ts'; import { getEnumOptions } from './utils.ts'; import { SubmissionRecordsAPI } from './api/index.ts'; // 配置 dayjs 插件 dayjs.extend(weekday); dayjs.extend(localeData); dayjs.locale('zh-cn'); // 提交记录管理页面组件 export const SubmissionRecordsPage = () => { const queryClient = useQueryClient(); const [modalVisible, setModalVisible] = useState(false); const [formMode, setFormMode] = useState<'create' | 'edit'>('create'); const [editingId, setEditingId] = useState(null); const [form] = Form.useForm(); const [searchForm] = Form.useForm(); const [searchParams, setSearchParams] = useState({ user_id: '', nickname: '', code: '', training_date: '', training_date_end: '', page: 1, limit: 10, }); // 使用React Query获取提交记录列表 const { data: recordsData, isLoading: isListLoading, refetch } = useQuery({ queryKey: ['submissionRecords', searchParams], queryFn: () => SubmissionRecordsAPI.getSubmissionRecords({ page: searchParams.page, pageSize: searchParams.limit, user_id: searchParams.user_id, nickname: searchParams.nickname, code: searchParams.code, training_date: searchParams.training_date }), placeholderData: { data: [], pagination: { current: 1, pageSize: 10, total: 0, totalPages: 1 } } }); const records = React.useMemo(() => (recordsData as SubmissionRecordListResponse)?.data || [], [recordsData]); const pagination = React.useMemo(() => ({ current: (recordsData as SubmissionRecordListResponse)?.pagination?.current || 1, pageSize: (recordsData as SubmissionRecordListResponse)?.pagination?.pageSize || 10, total: (recordsData as SubmissionRecordListResponse)?.pagination?.total || 0, totalPages: (recordsData as SubmissionRecordListResponse)?.pagination?.totalPages || 1 }), [recordsData]); // 获取单个提交记录 const fetchRecord = async (id: number) => { try { const response = await SubmissionRecordsAPI.getSubmissionRecord(id); return response.data; } catch (error) { message.error('获取提交记录详情失败'); return null; } }; // 处理表单提交 const handleSubmit = async (values: Omit) => { try { const response = formMode === 'create' ? await SubmissionRecordsAPI.createSubmissionRecord(values) : await SubmissionRecordsAPI.updateSubmissionRecord(editingId!, values); message.success(formMode === 'create' ? '创建提交记录成功' : '更新提交记录成功'); setModalVisible(false); form.resetFields(); refetch(); } catch (error) { message.error((error as Error).message); } }; // 处理编辑 const handleEdit = async (id: number) => { const record = await fetchRecord(id); if (record) { setFormMode('edit'); setEditingId(id); form.setFieldsValue({ ...record, training_date: record.training_date ? dayjs(record.training_date) : null }); setModalVisible(true); } }; // 处理删除 const handleDelete = async (id: number) => { try { await SubmissionRecordsAPI.deleteSubmissionRecord(id); message.success('删除提交记录成功'); refetch(); } catch (error) { message.error((error as Error).message); } }; // 处理搜索 const handleSearch = async (values: any) => { try { queryClient.removeQueries({ queryKey: ['submissionRecords'] }); setSearchParams({ user_id: values.user_id || '', nickname: values.nickname || '', code: values.code || '', training_date: values.training_date?.[0]?.format('YYYY-MM-DD') || '', training_date_end: values.training_date?.[1]?.format('YYYY-MM-DD') || '', page: 1, limit: searchParams.limit, }); } catch (error) { message.error('搜索失败'); } }; // 处理分页 const handlePageChange = (page: number, pageSize?: number) => { setSearchParams(prev => ({ ...prev, page, limit: pageSize || prev.limit, })); }; // 处理添加 const handleAdd = () => { setFormMode('create'); setEditingId(null); form.resetFields(); setModalVisible(true); }; // 状态映射 const statusOptions = getEnumOptions(SubmissionRecordStatus, SubmissionRecordStatusNameMap); // 表格列定义 const columns = [ { title: 'ID', dataIndex: 'id', key: 'id', width: 80, }, { title: '用户ID', dataIndex: 'user_id', key: 'user_id', }, { title: '昵称', dataIndex: 'nickname', key: 'nickname', }, { title: '成绩', dataIndex: 'score', key: 'score', }, { title: '代码', dataIndex: 'code', key: 'code', }, { title: '训练日期', dataIndex: 'training_date', key: 'training_date', render: (date: string) => date ? dayjs(date).format('YYYY-MM-DD') : '-', }, { title: '标记', dataIndex: 'mark', key: 'mark', }, { title: '状态', dataIndex: 'status', key: 'status', render: (status: SubmissionRecordStatus) => { const statusText = SubmissionRecordStatusNameMap[status]; const colorMap = { [SubmissionRecordStatus.PENDING]: 'orange', [SubmissionRecordStatus.APPROVED]: 'green', [SubmissionRecordStatus.REJECTED]: 'red' }; return statusText ? ( {statusText} ) : null; }, }, { title: '操作', key: 'action', render: (_: any, record: SubmissionRecord) => ( handleDelete(record.id)} okText="确定" cancelText="取消" > ), }, ]; return (
`共 ${total} 条`, }} /> { form.validateFields() .then(values => { handleSubmit({ ...values, training_date: values.training_date?.format('YYYY-MM-DD'), code: values.code || '', user_id: values.user_id || 0, score: values.score || 0, status: values.status || SubmissionRecordStatus.PENDING }); }) .catch(info => { console.log('表单验证失败:', info); }); }} onCancel={() => setModalVisible(false)} width={800} okText="确定" cancelText="取消" destroyOnClose >