ERPTurbo_Admin/packages/app-operation/src/components/Modal/SelectModal/index.tsx
shenyifei 1429319b01 refactor(components): 调整组件导入路径并新增验证码组件
- 将多个组件中的 @chageable/components 导入改为从 @/components 导入
- 在 BoxBrandList.tsx、CostList.tsx、ProductDataList.tsx 等文件中更新 ProFormBizSelect 相关组件导入
- 在 CaptchaModal/index.tsx 中将 Captcha 组件导入从 @chageable/components 改为 @/components
- 在 ChannelList.tsx、CompanyList.tsx、EmployeeList.tsx 等文件中更新 ProFormUploadMaterial 导入
- 在 MaterialList.tsx 中更新 ProFormBizTreeSelect 和 ProFormUploadOss 导入
- 在 MenuList.tsx、OrderCostList.tsx 中更新 ProFormBizSelect 相关组件导入
- 在 DealerModal.tsx、MaterialModal.tsx、OrderModal.tsx 等文件中更新 SelectModal 导入
- 在 app.tsx 中将 LeftMenu 导入从 @chageable/components 改为 @/components
- 新增 UploadMaterial 组件并添加到 components/index.ts 导出
- 在 Captcha 组件中添加滑动验证码功能,包含样式和交互逻辑
- 在 companyPaymentAccount 工具函数中添加 branchName 字段支持
2026-01-07 00:12:26 +08:00

203 lines
5.6 KiB
TypeScript

import { ProTable, ProTableProps } from '@ant-design/pro-components';
import type { ParamsType } from '@ant-design/pro-provider';
import { Modal, ModalProps, type TableProps } from 'antd';
import React, {
forwardRef,
useEffect,
useImperativeHandle,
useState,
} from 'react';
export interface ISelectModalProps<
DataType extends Record<string, any>,
Params extends ParamsType = ParamsType,
> {
rowKey: string;
type: 'checkbox' | 'radio' | undefined;
onFinish: (selectId: DataType[]) => void;
num?: number;
selectedList?: DataType[];
modalProps: ModalProps;
tableProps: ProTableProps<DataType, Params>;
ghost?: boolean;
disabled?: (record: DataType) => boolean;
}
export type SelectModalHandle<DataType> = {
onFinish: () => void;
getSelectedList: () => DataType[];
};
const SelectModal = forwardRef<
SelectModalHandle<any>,
ISelectModalProps<any, any>
>(
<
DataType extends Record<string, any>,
Params extends ParamsType = ParamsType,
>(
props: ISelectModalProps<DataType, Params>,
ref: React.Ref<SelectModalHandle<DataType>>,
) => {
const {
rowKey,
type: selectType,
num,
onFinish,
modalProps,
tableProps,
ghost = false,
disabled,
} = props;
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
const [selectedList, setSelectedList] = useState<DataType[]>([]);
const [open, setOpen] = useState<boolean>();
useEffect(() => {
setOpen(modalProps?.open);
}, [modalProps?.open]);
useImperativeHandle(ref, () => ({
getSelectedList: () => selectedList,
onFinish: () => {
onFinish(selectedList);
if (!selectedList || selectedList.length === 0) {
return;
}
setSelectedRowKeys([]);
setSelectedList([]);
setOpen(false);
},
}));
useEffect(() => {
const initSelectedList = props.selectedList;
if (initSelectedList) {
setSelectedRowKeys(
initSelectedList?.map((v) => {
return v?.[rowKey] || '';
}),
);
setSelectedList(initSelectedList);
} else {
setSelectedRowKeys([]);
setSelectedList([]);
}
}, [props.selectedList]);
const rowSelection: TableProps<DataType>['rowSelection'] = {
selectedRowKeys,
preserveSelectedRowKeys: true,
type: selectType || 'checkbox',
onChange: (selectedRowKeys: React.Key[], selectedRows: DataType[]) => {
const dataTypes = [...selectedList, ...selectedRows];
const newSelectList = selectedRowKeys
.map((v) =>
dataTypes.find((item: DataType) => {
return item?.[rowKey] === v;
}),
)
.filter((item) => item !== undefined);
setSelectedRowKeys(selectedRowKeys.slice(0, num || 1));
setSelectedList(newSelectList.slice(0, num || 1) as any);
},
getCheckboxProps: (record: DataType) => ({
disabled:
((selectType || 'checkbox') === 'checkbox' &&
selectedList.length >= (num || 1) &&
!selectedRowKeys.includes(record?.[rowKey] || '')) ||
disabled?.(record),
}),
};
const renderTable = () => {
return (
<ProTable<DataType, Params>
ghost={true}
search={false}
scroll={{ x: 'max-content' }}
onRow={(data) => ({
onClick: () => {
if (disabled?.(data)) {
return;
}
if (selectType === 'radio') {
setSelectedRowKeys([data[rowKey]]);
setSelectedList([data]);
}
if (selectType === 'checkbox') {
if (selectedList.length >= (num || 1)) {
return;
}
if (selectedRowKeys.length === 0) {
setSelectedRowKeys([data[rowKey]]);
setSelectedList([data]);
} else {
if (selectedRowKeys.includes(data[rowKey])) {
setSelectedRowKeys(
selectedRowKeys
.filter((v) => v !== data[rowKey])
.slice(0, num || 1),
);
setSelectedList(
selectedList
.filter((v) => v?.[rowKey] !== data[rowKey])
.slice(0, num || 1),
);
} else {
setSelectedRowKeys(
[...selectedRowKeys, data[rowKey]].slice(0, num || 1),
);
setSelectedList([...selectedList, data].slice(0, num || 1));
}
}
}
if (ghost) {
onFinish([data]);
}
},
})}
rowSelection={rowSelection}
{...tableProps}
/>
);
};
if (ghost) {
return renderTable();
}
return (
<Modal
width={1000}
{...modalProps}
open={open}
onOk={async (event) => {
onFinish(selectedList);
if (!selectedList || selectedList.length === 0) {
return;
}
modalProps.onOk?.(event);
if (selectedList && !modalProps.open) {
setSelectedRowKeys([]);
setSelectedList([]);
}
}}
>
{renderTable()}
</Modal>
);
},
) as <
DataType extends Record<string, any>,
Params extends ParamsType = ParamsType,
>(
props: ISelectModalProps<DataType, Params> & React.RefAttributes<unknown>,
) => JSX.Element;
export default SelectModal;