import React, { useState } from 'react'; import { useQueryClient } from '@tanstack/react-query'; import { Button, Table, Space, Form, Input, 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 { XunlianCode, XunlianCodeListResponse } from '../share/types_stock.ts'; import { getEnumOptions } from './utils.ts'; import { XunlianCodeAPI } from './api/xunlian_codes.ts'; // 配置 dayjs 插件 dayjs.extend(weekday); dayjs.extend(localeData); // 设置 dayjs 语言 dayjs.locale('zh-cn'); // 训练代码管理页面组件 export const XunlianCodePage = () => { 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({ code: '', page: 1, limit: 10, }); // 使用React Query获取训练代码列表 const { data: codesData, isLoading: isListLoading, refetch } = useQuery({ queryKey: ['xunlianCodes', searchParams], queryFn: async () => { const response = await XunlianCodeAPI.getXunlianCodes({ page: searchParams.page, pageSize: searchParams.limit, code: searchParams.code, }); return response.data; }, placeholderData: { data: [], pagination: { current: 1, pageSize: 10, total: 0, totalPages: 1 } } }); const codes = React.useMemo(() => (codesData as XunlianCodeListResponse)?.data || [], [codesData]); const pagination = React.useMemo(() => ({ current: (codesData as XunlianCodeListResponse)?.pagination?.current || 1, pageSize: (codesData as XunlianCodeListResponse)?.pagination?.pageSize || 10, total: (codesData as XunlianCodeListResponse)?.pagination?.total || 0, totalPages: (codesData as XunlianCodeListResponse)?.pagination?.totalPages || 1 }), [codesData]); // 获取单个训练代码 const fetchCode = async (id: number) => { try { const response = await XunlianCodeAPI.getXunlianCode(id); return response.data; } catch (error) { message.error('获取训练代码详情失败'); return null; } }; // 处理表单提交 const handleSubmit = async (values: Partial) => { try { // 转换交易日期格式为ISO格式,确保不为null const submitValues = { ...values, ...(values.trade_date && { trade_date: dayjs(values.trade_date).format('YYYY-MM-DD') }) }; const response = formMode === 'create' ? await XunlianCodeAPI.createXunlianCode(submitValues) : await XunlianCodeAPI.updateXunlianCode(editingId!, submitValues); message.success(formMode === 'create' ? '创建训练代码成功' : '更新训练代码成功'); setModalVisible(false); form.resetFields(); refetch(); } catch (error) { message.error((error as Error).message); } }; // 处理编辑 const handleEdit = async (id: number) => { const code = await fetchCode(id); if (code) { setFormMode('edit'); setEditingId(id); // 转换交易日期格式为dayjs对象 form.setFieldsValue({ ...code, trade_date: code.trade_date ? dayjs(code.trade_date) : null }); setModalVisible(true); } }; // 处理删除 const handleDelete = async (id: number) => { try { await XunlianCodeAPI.deleteXunlianCode(id); message.success('删除训练代码成功'); refetch(); } catch (error) { message.error((error as Error).message); } }; // 处理搜索 const handleSearch = async (values: any) => { try { queryClient.removeQueries({ queryKey: ['xunlianCodes'] }); setSearchParams({ code: values.code || '', 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 columns = [ { title: 'ID', dataIndex: 'id', key: 'id', width: 80, }, { title: '股票代码', dataIndex: 'code', key: 'code', }, { title: '股票名称', dataIndex: 'stock_name', key: 'stock_name', }, { title: '案例名称', dataIndex: 'name', key: 'name', }, { title: '案例类型', dataIndex: 'type', key: 'type', }, { title: '交易日期', dataIndex: 'trade_date', key: 'trade_date', render: (date: string) => dayjs(date).format('YYYY-MM-DD'), }, { title: '提交用户', dataIndex: 'nickname', key: 'nickname', }, { title: '创建时间', dataIndex: 'created_at', key: 'created_at', render: (date: string) => dayjs(date).format('YYYY-MM-DD HH:mm:ss'), }, { title: '操作', key: 'action', render: (_: any, record: XunlianCode) => ( handleDelete(record.id)} okText="确定" cancelText="取消" > ), }, ]; return (
`共 ${total} 条`, }} /> { form.validateFields() .then(values => { handleSubmit(values); }) .catch(info => { console.log('表单验证失败:', info); }); }} onCancel={() => setModalVisible(false)} width={800} okText="确定" cancelText="取消" destroyOnClose >
); };