diff --git a/src/components/CarTableTreeAuth/SelectSpec.tsx b/src/components/CarTableTreeAuth/SelectSpec.tsx new file mode 100644 index 0000000..dce839d --- /dev/null +++ b/src/components/CarTableTreeAuth/SelectSpec.tsx @@ -0,0 +1,63 @@ +import React, { useEffect, useState } from "react"; +import { + Table, + Select, +} from "antd"; +import { + CarOptionVo, +} from "@/pages/stock/Components/api"; +import { ColumnsType } from 'antd/lib/table'; + +interface Props { + onChange?: (pa: any) => void; + value?: any[]; + disabled?: boolean; + level?: number; //1品牌,2车系,3车型 + specList?: CarOptionVo[] +} + +interface Item { + label: string; + value: number; + key?: number; +} +const { Column } = Table; +const { Option } = Select; + +const columns: ColumnsType = [ + { + title: '车型', + dataIndex: 'name', + }, + { + title: '配置代码', + dataIndex: 'specConfigCodeList', + render: (t) => t.map((i: string, key: number) => (
{key + 1}.{i}
)) + }, +]; +export default function index({ onChange: onSelected, value, disabled, specList = [] }: Props) { + const rowSelection = { + onChange: (selectedRowKeys: React.Key[], selectedRows: CarOptionVo[]) => { + onSelected && onSelected(selectedRows); + }, + }; + + return ( + <> + item.id), + ...rowSelection, + }} + pagination={false} + // loading={} + rowKey="id" + size="small" + scroll={{ y: 500 }} + columns={columns} + dataSource={specList} + /> + + ); +} diff --git a/src/components/CarTableTreeAuth/entity.ts b/src/components/CarTableTreeAuth/entity.ts new file mode 100644 index 0000000..fb3b11b --- /dev/null +++ b/src/components/CarTableTreeAuth/entity.ts @@ -0,0 +1,18 @@ +export interface CarAuthList { + authType: number; + brandId: number; + brandName: number; + children?: Array +} + +interface SeriesAuth { + authType: number; + seriesId: number; + seriesName: string; + children?: Array +} +interface SpecAuth { + authType: number; + specId: number; + specName: string; +} \ No newline at end of file diff --git a/src/components/CarTableTreeAuth/index.tsx b/src/components/CarTableTreeAuth/index.tsx new file mode 100644 index 0000000..9c6ff07 --- /dev/null +++ b/src/components/CarTableTreeAuth/index.tsx @@ -0,0 +1,373 @@ +import React, { useEffect, useState } from "react"; +import { + Button, + Card, + Table, + Modal, + Form, + Select, + Space, + Spin, + message, +} from "antd"; +import { + CarOptionVo, + getOnsaleSeriesApi, + getOnsaleSpecApi, +} from "@/pages/stock/Components/api"; +import { PlusOutlined } from '@ant-design/icons'; +import { ColumnsType } from 'antd/lib/table'; +import SelectSpec from './SelectSpec'; +import { CarAuthList } from './entity'; +import { getBrandFilterApi } from '@/common/api'; + +interface Props { + onChange?: (pa: any) => void; + value?: CarAuthList[]; + disabled?: boolean; + brandList?: CommonApi.OptionVO[]; + /**品牌是否多选,默认true */ + brandMultiple?: boolean; +} + +interface Item { + label: string; + value: number; + key?: number; +} +const { Column } = Table; +const { Option } = Select; + +export default function index({ onChange, value, disabled, brandMultiple = true, brandList }: Props) { + const [form] = Form.useForm(); + // 控制Modal是否可见 + const [visible, setVisible] = useState(false); + // 控制是否可见车型下拉框 + const [level, setLevel] = useState(1); + //存储表格当前车系 + const [currentItem, setCurrentItem] = useState(); + const [brandData, setBrandData] = useState([]); + //存储Modal中可选的车系 + const [series, setSeries] = useState([]); + //存储接口返回的车型 + const [specList, setSpecList] = useState([]); + //存储Modal选择的品牌和车系作为表格的数据源 + const [savaData, setSavadata] = useState([]); + // 存储已经选中的车系 + const [selectedSeries, setSelectedSeries] = useState([]); + const [fetchLoading, setFetchLoading] = useState(false); + + useEffect(() => { + if (value && value.length) { + setSelectedSeries([...value]); + setSavadata([...value]); + } + }, [value]); + + useEffect(() => { + if (brandList && Array.isArray(brandList)) { + setBrandData(brandList || []); + } + }, [brandList]); + + function getBrands() { + if (brandData.length) { + return; + } + setFetchLoading(true); + getBrandFilterApi().then(res => { + setBrandData(res.data || []); + setFetchLoading(false); + }).catch(err => { + message.error(err.message); + setFetchLoading(false); + }); + } + + const _onOk = () => { + form + .validateFields() + .then((fileds) => { + if (level === 2) { + const { series } = fileds; + const _series = series.map((item: Item) => ({ + seriesId: item.value, + seriesName: item.label, + authType: 1, + })); + + const currentSeries = (savaData.filter((i: any) => i.brandId === currentItem.brandId)[0] || {}).children || []; + /**判断已有数据保留 */ + if (currentSeries.length) { + const selectedIds = currentSeries.map(i => i.seriesId); + let newAuthSeries: any[] = []; + _series.forEach((item: any) => { + if (selectedIds.includes(item.seriesId)) { + newAuthSeries = newAuthSeries.concat(currentSeries.filter((list: any) => list.seriesId === item.seriesId)); + } else { + newAuthSeries.push(item); + } + }); + currentItem.children = newAuthSeries; + } else { + currentItem.children = _series; + } + + const tempData = savaData.map((item: any) => (item.brandId === currentItem.brandId ? { ...currentItem, authType: series.length ? 2 : 1 } : { ...item, authType: 1 })); + setSavadata([...tempData]); + onChange && onChange(tempData); + setVisible(false); + return; + } + if (level === 3) { + const { spec } = fileds; + const _spec = spec.map((item: any) => ({ + specId: item.id, + specName: item.name, + })); + currentItem.children = _spec; + currentItem.authType = 2; + const tempData = savaData.map((item: any) => { + if (item.children) { + const newChildren = item.children.map((i: any) => (i.seriesId === currentItem.seriesId ? { ...currentItem, authType: spec.length ? 2 : 1 } : i)); + item.children = newChildren; + } + return { ...item, authType: 1 }; + }); + setSavadata([...tempData]); + onChange && onChange(tempData); + setVisible(false); + return; + } + const { brand } = fileds; + const tempArray = (brandMultiple ? brand : [brand]).map((item: any) => ({ + brandName: item.label, + brandId: item.value, + authType: 1, //1全部2部分 + })); + const selectedBrands: number[] = savaData.map((i: any) => i.brandId); + let newAuthCar: any[] = []; + tempArray.forEach((item: any) => { + if (selectedBrands.includes(item.brandId)) { + newAuthCar = newAuthCar.concat(savaData.filter(list => list.brandId === item.brandId)); + } else { + newAuthCar.push(item); + } + }); + setSavadata(newAuthCar); + onChange && onChange(newAuthCar); + setVisible(false); + }) + .catch((err) => console.log(err.message)); + }; + + // 选择部分车辆表格==》删除车系 + const onDelete = (record: any) => { + const _savaData = savaData.filter( + (item: any) => item.seriesId != record.seriesId + ); + const _selectedSeries = selectedSeries.filter( + (item) => item.seriesId != record.seriesId + ); + setSavadata([..._savaData]); + onChange && onChange(_savaData); + setSelectedSeries([..._selectedSeries]); + }; + + // 选择部分车辆表格==》编辑选择部分车系、车型 + const onSelectSpec = async (record: any) => { + setCurrentItem(record); + setVisible(true); + if (record.brandId) { + setLevel(2); + setFetchLoading(true); + try { + const { data } = await getOnsaleSeriesApi(record.brandId); + const selectedSeries = savaData.filter((brand: any) => brand.brandId === record.brandId)[0].children; + selectedSeries && form.setFieldValue("series", selectedSeries.map(i => ({ value: i.seriesId, label: i.seriesName }))); + setSeries(data); + setFetchLoading(false); + } catch (err: any) { + message.error(err.message); + setFetchLoading(false); + } + } + if (record.seriesId) { + setLevel(3); + setFetchLoading(true); + try { + const { data } = await getOnsaleSpecApi(record.seriesId); + record.children && form.setFieldValue("spec", record.children.map(i => ({ id: i.specId, name: i.specName }))); + setSpecList(data); + setFetchLoading(false); + } catch (err: any) { + message.error(err.message); + setFetchLoading(false); + } + } + }; + + return ( + <> + + {!disabled && ( +
+ +
+ )} + +
String(record.brandId || record.seriesId || record.specId)} + > + + { + return (text || record.specName || (record.children && record.children.length !== 0) ? ( + + {text} + + ) : ( + 全部车系 + )); + }} + /> + { + return (text || (record.children && record.children.length !== 0) ? ( + + {text} + + ) : ( + 全部车型 + )); + }} + /> + {!disabled && ( + { + return ( + + + {/* onDelete(record)} + > + + */} + + ); + }} + /> + )} +
+ + + {/* 选择品牌和车系 */} + form.submit()} + onCancel={() => { + setVisible(false); + }} + maskClosable={false} + afterClose={() => { + form.resetFields(); + setCurrentItem({}); + }} + > + +
+ {level === 1 ? ( + + + + ) : null} + + {/* 车系 */} + {level === 2 && ( + + + + )} + {level === 3 ? ( + + {/* */} + + + ) : null} +
+
+
+ + ); +}