123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- import React, { useEffect, useState } from 'react';
- // @ts-ignore
- import { Button, Input, Table } from 'antd';
- import type { ColumnsType } from 'antd/lib/table';
- import DDSelectField from '@/components/DDComponents/DDSelectField';
- import './index.css';
- import DDDateField from '@/components/DDComponents/DDDateField';
- import NumberField from '@/components/DDComponents/NumberField';
- import TextNote from '@/components/DDComponents/TextNote';
- import { PlusOutlined } from '@ant-design/icons';
- interface IProps {
- table?: any; // 整个表格
- columns?: Array<any>; // 当前列配置
- onChange?: (e?: any, id?: string, label?: string) => void; // 表格修改后的值
- displayOnly?: boolean; // 是否仅用于展示
- }
- type TableDataType = {
- index: number;
- id?: string;
- col1?: any;
- col2?: any;
- col3?: any;
- col4?: any;
- col5?: any;
- };
- function DIYTable(props: IProps) {
- const { table, columns, displayOnly, onChange } = props;
- // table数据
- const [tableData, setTableData] = useState<TableDataType[]>([{ index: 1 }]);
- // 列配置
- const tableColumnDef: ColumnsType<any> = [
- {
- title: '序号',
- dataIndex: 'index',
- className: 'hidden',
- },
- ];
- const [commitValue, setCommitValue] = useState<any[]>([]);
- const handleValueChange = (value: any, id: string, label: string) => {
- let ids = id.split(';');
- let [rowIndex, colIndex] = ids[0].split(',').map((item) => Number(item));
- let [columnID, tableID] = ids[1].split('>');
- let [columnLabel, tableLabel] = label.split('>');
- const cell = {
- name: columnLabel,
- id: columnID,
- type: columnID.split('_')[0],
- value: [value],
- };
- // 组装可能用到的数据
- const cols = [];
- cols[colIndex] = cell;
- const rows = [];
- rows[rowIndex] = cols;
- const newValues = JSON.parse(JSON.stringify(commitValue)) || [];
- if (newValues.length !== 0 && newValues[rowIndex] !== undefined) {
- newValues.forEach((row: any, rindex: number) => {
- if (rindex === rowIndex) {
- if (row[colIndex] !== undefined) {
- row.forEach((_col: any, cindex: number) => {
- if (cindex === colIndex) {
- row[colIndex] = cell;
- }
- });
- } else {
- row[colIndex] = cell;
- }
- }
- });
- } else {
- newValues[rowIndex] = cols;
- }
- const textNode = columns?.find((item) => item.componentName === 'TextNote');
- if (textNode) {
- const textNodeIndex = columns?.findIndex(
- (item) => item.componentName === 'TextNote',
- );
- const textCell = {
- name: textNode.props.label,
- id: textNode.props.id,
- type: textNode.componentName,
- value: [textNode.props.placeholder],
- };
- newValues.forEach((item) => {
- if (textNodeIndex !== -1) {
- item[textNodeIndex] = textCell;
- }
- });
- }
- setCommitValue(newValues);
- onChange(newValues);
- };
- // 表单填写时的表格生成
- const handleGenerateTable = () => {
- if (columns !== undefined && columns.length) {
- for (let index = 0; index < columns.length; index++) {
- let column = columns[index];
- let columnID = column.props.id;
- let columnLabel = column.props.label;
- let colDef: any = {
- dataIndex: 'col' + (index + 1),
- title: columnLabel || column.name,
- className: 'p-8',
- };
- switch (column.componentName) {
- case 'DDSelectField':
- colDef.render = (_: any, __: any, rowIndex: number) => {
- let id =
- rowIndex + ',' + index + ';' + columnID + '>' + table.props.id;
- return (
- <DDSelectField
- id={id}
- label={columnLabel + '>' + table.props.label}
- style={{ padding: '0', margin: '0' }}
- options={column.props.options}
- disabled={column.props.disabled}
- onChange={(value: any) => {
- handleValueChange(
- value,
- id,
- columnLabel + '>' + table.props.label,
- );
- }}
- />
- );
- };
- break;
- case 'DDDateField':
- colDef.render = (_: any, __: any, rowIndex: number) => {
- let id =
- rowIndex + ',' + index + ';' + columnID + '>' + table.props.id;
- return (
- <DDDateField
- id={id}
- label={columnLabel + '>' + table.props.label}
- key={index + rowIndex + ''}
- style={{ padding: '0', margin: '0' }}
- placeholder={column.props.placeholder}
- format={column.props.format}
- disabled={column.props.disabled}
- onChange={(value: any) => {
- handleValueChange(
- value,
- id,
- columnLabel + '>' + table.props.label,
- );
- }}
- />
- );
- };
- break;
- case 'NumberField':
- colDef.render = (_: any, __: any, rowIndex: number) => {
- let id =
- rowIndex + ',' + index + ';' + columnID + '>' + table.props.id;
- return (
- <NumberField
- id={id}
- label={columnLabel + '>' + table.props.label}
- size="small"
- width="50%"
- style={{ padding: '4px 11px' }}
- disabled={column.props.disabled}
- unit={column.props.unit}
- onChange={(value: any) => {
- handleValueChange(
- value,
- id,
- columnLabel + '>' + table.props.label,
- );
- }}
- />
- );
- };
- break;
- case 'TextField':
- colDef.render = (_: any, __: any, rowIndex: number) => {
- let id =
- rowIndex + ',' + index + ';' + columnID + '>' + table.props.id;
- return (
- <Input
- disabled={column.props.disabled}
- placeholder={column.props.placeholder}
- onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
- handleValueChange(
- e.target.value,
- id,
- columnLabel + '>' + table.props.label,
- );
- }}
- />
- );
- };
- break;
- case 'TextNote':
- colDef.title = '说明';
- colDef.render = (_: any, __: any, rowIndex: number) => {
- let id =
- rowIndex + ',' + index + ';' + columnID + '>' + table.props.id;
- return (
- <TextNote
- id={id}
- style={{ padding: '0', margin: '0' }}
- value={column.props.placeholder}
- />
- );
- };
- break;
- }
- tableColumnDef.push(colDef);
- }
- }
- };
- // 当仅用作展示时
- const handleDisplayOnly = () => {
- const rows = columns;
- if (rows && rows.length) {
- for (let index = 0; index < rows.length; index++) {
- // 把每一行的数据提出来到一个对象里
- if (rows) {
- const row = rows[index];
- if (index === 0) {
- // 列配置
- row.forEach((col: any) => {
- if (col) {
- tableColumnDef.push({
- title: col?.name || '',
- dataIndex: col?.type || '',
- className: '',
- });
- }
- });
- }
- }
- }
- }
- };
- const handleRowChange = () => {
- setTableData([...tableData, { index: tableData.length }]);
- };
- if (displayOnly) {
- handleDisplayOnly();
- } else {
- handleGenerateTable();
- }
- useEffect(() => {
- if (columns?.length === 0) {
- return;
- }
- const rows = columns;
- const newTableData = [];
- if (rows && rows.length) {
- if (displayOnly) {
- for (let index = 0; index < rows.length; index++) {
- // 把每一行的数据提出来到一个对象里
- const row = rows[index];
- const rowData: any = {};
- if (displayOnly) {
- row.forEach((col: any) => {
- if (col) {
- rowData.index = index + 1;
- // eslint-disable-next-line prefer-destructuring
- rowData[col.type] = col.value[0];
- rowData.key = col.id + index;
- }
- });
- newTableData.push(rowData);
- }
- }
- } else {
- newTableData.push({
- index: 1,
- });
- }
- setTableData(newTableData);
- }
- }, [columns]);
- return (
- <>
- {/* {table.name ? table.name : table.props.label} */}
- <Table
- style={displayOnly ? { margin: '10px 24px 10px 0' } : {}}
- columns={tableColumnDef}
- dataSource={tableData}
- pagination={false}
- />
- <Button
- type="dashed"
- icon={<PlusOutlined />}
- block
- onClick={handleRowChange}
- style={displayOnly ? { display: 'none' } : {}}
- >
- 新增行
- </Button>
- </>
- );
- }
- export default DIYTable;
|