import React, { useContext, useEffect, useRef, useState } from "react"; import { Table, Form, InputRef, Input, Row, Button, message, Modal, InputNumber, } from "antd"; import type { FormInstance } from "antd/es/form"; import * as API from "../api"; import styles from "./index.less"; import { MAX_NUM } from "../entity"; type EditableTableProps = Parameters[0]; type ColumnTypes = Exclude; interface Item { id: string; shopName: string; taskCount: number; newEnergyTaskCount: number; fuelVehicleTaskCount: number; tackCarTaskCount: number; } interface EditableRowProps { index: number; } interface EditableCellProps { title: React.ReactNode; editable: boolean; children: React.ReactNode; dataIndex: keyof Item; record: Item; handleSave: (record: Item) => void; } const defaultColumns: (ColumnTypes[number] & { editable?: boolean; dataIndex: string; })[] = [ { title: "门店", dataIndex: "shopName", editable: false, }, { title: "零售任务(台)", dataIndex: "taskCount", editable: true, }, { title: "新能源车任务(台)", dataIndex: "newEnergyTaskCount", editable: true, }, { title: "传统燃油车任务(台)", dataIndex: "fuelVehicleTaskCount", editable: false, }, { title: "攻坚车任务数(台)", dataIndex: "tackCarTaskCount", editable: true, }, ]; interface SaleTaskAutoAssignProps { id: number; value?: API.ShopTaskItem[]; onRefresh: () => void; } export default function SaleTaskAutoAssign({ id, value, onRefresh, }: SaleTaskAutoAssignProps) { const EditableContext = React.createContext | null>(null); const [dataSource, setDataSource] = useState([]); useEffect(() => { setDataSource(value ? [...value] : []); }, [value]); const EditableRow: React.FC = ({ index, ...props }) => { const [form] = Form.useForm(); return (
); }; const EditableCell: React.FC = ({ title, editable, children, dataIndex, record, handleSave, ...restProps }) => { const [editing, setEditing] = useState(false); const inputRef = useRef(null); const form = useContext(EditableContext)!; useEffect(() => { if (editing) { inputRef.current!.focus(); } }, [editing]); const toggleEdit = () => { setEditing(!editing); form.setFieldsValue({ [dataIndex]: record[dataIndex] }); }; const save = async () => { try { const values = await form.validateFields(); toggleEdit(); handleSave({ ...record, ...values }); } catch (errInfo) { console.log("Save failed:", errInfo); } }; let childNode = children; if (editable) { childNode = editing ? ( ) : (
{children}
); } return {childNode}; }; const handleSave = (row: API.ShopTaskItem) => { const newData = [...dataSource]; const index = newData.findIndex((item) => row.id === item.id); const item = newData[index]; if (row.taskCount !== 0 && row.newEnergyTaskCount > row.taskCount) { message.warn("新能源车任务台数不得超过零售任务台数"); return; } const newRow = { ...item, ...row, fuelVehicleTaskCount: row.taskCount - row.newEnergyTaskCount, }; if (row.taskCount === 0) { newRow.taskCount = 0; newRow.newEnergyTaskCount = 0; newRow.fuelVehicleTaskCount = 0; } newData.splice(index, 1, newRow); console.log("handleSave newData", newData); setDataSource(newData); }; const autoAssignSaleTask = (isAssignToAdviser: boolean) => { Modal.confirm({ title: isAssignToAdviser ? "确认分配到门店和顾问吗?" : "确认分配到门店吗?", zIndex: 1002, onOk: async () => { const hide = message.loading("分配中,请稍候", 0); API.autoAssignSaleTask({ id, shopTaskList: dataSource.map((item) => ({ shopId: item.shopId, taskCount: item.taskCount, newEnergyTaskCount: item.newEnergyTaskCount, fuelVehicleTaskCount: item.fuelVehicleTaskCount, tackCarTaskCount: item.tackCarTaskCount, })), assignTask: isAssignToAdviser, }) .then((res) => { message.success("分配成功"); onRefresh(); }) .catch((error: any) => { message.error(error.message ?? "请求失败"); }) .finally(() => { hide(); }); }, }); }; const components = { body: { row: EditableRow, cell: EditableCell, }, }; const columns = defaultColumns.map((col) => { if (!col.editable) { return col; } return { ...col, onCell: (record: API.ShopTaskItem) => ({ record, editable: col.editable, dataIndex: col.dataIndex, title: col.title, handleSave, }), }; }); return ( <> "editable-row"} bordered rowKey="id" dataSource={dataSource} columns={columns as ColumnTypes} /> ); }