| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- import React, { useState, useEffect, useImperativeHandle, forwardRef } from 'react';
- import { Modal, Table, Button, Image, message, Space } from 'antd';
- import { DeleteOutlined, ZoomInOutlined } from '@ant-design/icons';
- import { userCharacteristicApi } from '../../api/user/characteristic';
- import { UserCharacteristic } from '../../types';
- import { formatDateTimeFull } from '../../utils/formatTime';
- import type { ColumnsType } from 'antd/es/table';
- interface FaceOrFingerFormProps {
- onSuccess?: () => void;
- }
- export interface FaceOrFingerFormRef {
- open: (type: string, id: number, row: any) => void;
- }
- const FaceOrFingerForm = forwardRef<FaceOrFingerFormRef, FaceOrFingerFormProps>(({ onSuccess }, ref) => {
- const [dialogVisible, setDialogVisible] = useState(false);
- const [dialogTitle, setDialogTitle] = useState('');
- const [formLoading, setFormLoading] = useState(false);
- const [tableData, setTableData] = useState<UserCharacteristic[]>([]);
- const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
- const [total, setTotal] = useState(0);
- const [queryParams, setQueryParams] = useState({
- pageNo: 1,
- pageSize: 10,
- });
- const [userId, setUserId] = useState<number>();
- const [userType, setUserType] = useState<string>();
- // 打开弹窗
- const open = async (type: string, id: number, row: any) => {
- setDialogVisible(true);
- setDialogTitle(type === 'finger' ? '人员指纹数据' : '人员面部数据');
- setUserId(row.id);
- setUserType(type === 'finger' ? '1' : '2');
- setQueryParams({ pageNo: 1, pageSize: 10 });
- setTotal(0);
- setSelectedRowKeys([]);
- await getFaceOrFingerList();
- };
- useImperativeHandle(ref, () => ({
- open,
- }));
- // 获取指纹或人脸列表
- const getFaceOrFingerList = async () => {
- if (!userId || !userType) return;
- setFormLoading(true);
- try {
- const response = await userCharacteristicApi.getUserType({
- pageNo: queryParams.pageNo,
- pageSize: queryParams.pageSize,
- userId: userId,
- type: userType,
- });
- setTableData(response.list || []);
- setTotal(response.total || 0);
- } catch (error: any) {
- message.error(error.message || '获取数据失败');
- } finally {
- setFormLoading(false);
- }
- };
- useEffect(() => {
- if (dialogVisible && userId && userType) {
- getFaceOrFingerList();
- }
- }, [queryParams.pageNo, queryParams.pageSize, dialogVisible]);
- // 删除指纹或人脸
- const handleDelete = async (id?: number) => {
- const idsToDelete = id ? [id] : selectedRowKeys.map(key => Number(key));
-
- if (idsToDelete.length === 0) {
- message.warning('请选择要删除的数据');
- return;
- }
- Modal.confirm({
- title: '确认删除',
- content: `确定要删除选中的 ${idsToDelete.length} 条数据吗?`,
- okText: '确定',
- cancelText: '取消',
- onOk: async () => {
- try {
- // 逐个删除
- for (const deleteId of idsToDelete) {
- await userCharacteristicApi.deleteUserFaceOrFinger(deleteId);
- }
- message.success('删除成功');
- await getFaceOrFingerList();
- setSelectedRowKeys([]);
- onSuccess?.();
- } catch (error: any) {
- message.error(error.message || '删除失败');
- }
- },
- });
- };
- // 表格列配置
- const columns: ColumnsType<UserCharacteristic> = [
- {
- title: '序号',
- width: 80,
- align: 'center',
- render: (_: any, __: UserCharacteristic, index: number) => {
- return (queryParams.pageNo - 1) * queryParams.pageSize + index + 1;
- },
- },
- {
- title: dialogTitle === '人员指纹数据' ? '指纹' : '人脸',
- align: 'center',
- render: (_: any, record: UserCharacteristic) => (
- <div style={{ position: 'relative', display: 'inline-block' }}>
- <Image
- width={60}
- height={60}
- src={record.imageUrl}
- alt={dialogTitle === '人员指纹数据' ? '指纹' : '人脸'}
- preview={{
- mask: <ZoomInOutlined />,
- }}
- style={{ borderRadius: 4, border: '1px solid #dcdfe6' }}
- />
- </div>
- ),
- },
- {
- title: '创建时间',
- align: 'center',
- width: 180,
- render: (_: any, record: UserCharacteristic) => formatDateTimeFull(record.createTime),
- },
- {
- title: '操作',
- align: 'center',
- width: 120,
- render: (_: any, record: UserCharacteristic) => (
- <Button
- type="link"
- danger
- icon={<DeleteOutlined />}
- onClick={() => handleDelete(record.id)}
- >
- 删除
- </Button>
- ),
- },
- ];
- // 行选择配置
- const rowSelection = {
- selectedRowKeys,
- onChange: (selectedKeys: React.Key[]) => {
- setSelectedRowKeys(selectedKeys);
- },
- };
- return (
- <Modal
- title={dialogTitle}
- open={dialogVisible}
- onCancel={() => setDialogVisible(false)}
- footer={[
- <Button key="close" onClick={() => setDialogVisible(false)}>
- 关闭
- </Button>,
- ]}
- width={800}
- destroyOnClose
- >
- <div style={{ marginBottom: 16, display: 'flex', justifyContent: 'flex-end' }}>
- <Button
- type="primary"
- danger
- icon={<DeleteOutlined />}
- onClick={() => handleDelete()}
- disabled={selectedRowKeys.length === 0 || formLoading}
- >
- 删除
- </Button>
- </div>
- <Table
- columns={columns}
- dataSource={tableData}
- rowKey="id"
- loading={formLoading}
- pagination={false}
- rowSelection={rowSelection}
- scroll={{ y: 450 }}
- bordered
- />
- {/* 分页 */}
- {total > 0 && (
- <div style={{ marginTop: 16, paddingTop: 16, borderTop: '1px solid #f0f0f0', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
- <div style={{ fontSize: 14, color: '#666' }}>
- 共 <span style={{ color: '#1890ff', fontWeight: 500 }}>{total}</span> 条记录
- </div>
- <Space>
- <Button
- onClick={() => setQueryParams({ ...queryParams, pageNo: queryParams.pageNo - 1 })}
- disabled={queryParams.pageNo <= 1}
- >
- 上一页
- </Button>
- <span style={{ padding: '0 16px', fontSize: 14, color: '#666' }}>
- {queryParams.pageNo} / {Math.ceil(total / queryParams.pageSize)}
- </span>
- <Button
- onClick={() => setQueryParams({ ...queryParams, pageNo: queryParams.pageNo + 1 })}
- disabled={queryParams.pageNo >= Math.ceil(total / queryParams.pageSize)}
- >
- 下一页
- </Button>
- </Space>
- </div>
- )}
- </Modal>
- );
- });
- FaceOrFingerForm.displayName = 'FaceOrFingerForm';
- export default FaceOrFingerForm;
|