当前位置: 首页 > news >正文

项目实战 - 用户列表

用户列表想要实现这样的效果: 

渲染数据:

import React,{useState,useEffect} from 'react';
import { Button,Table, Tag,Modal,Popover, Switch } from 'antd';
import { EditOutlined,DeleteOutlined,ExclamationCircleOutlined } from '@ant-design/icons';
import axios from 'axios';
import { data } from 'react-router-dom';
import Item from 'antd/es/list/Item';
const { confirm } = Modal;

function UserList() {
    const [dataSource,setdataSource]=useState([])
    useEffect(()=>{
        axios.get("http://localhost:3000/users?_expand=role").then(res=>{
          console.log(res.data);
          const list = res.data
          setdataSource(list)
       })
    },[])
    const columns = [
        {
          title: '区域',
          dataIndex: 'region',
          render:(region)=>{
            return <b>{region===""?'全球':region}</b>
        }
        },
        {
          title: '角色名称',
          dataIndex: 'role',
          render:(role)=>{
              return role?.roleName
          }
        },
        {
          title: '用户名',
          dataIndex: 'username',
        },
        {
            title:"用户状态",
            dataIndex:"roleState",
            render:(roleState,item)=>{
                return <Switch checked={roleState} disabled={item.default}>

                </Switch>
            }
        },
        {
          title: '操作',
          render:(record)=>{
            return <div>
               <Button type="primary" shape="circle" icon={<EditOutlined />} disabled={record.default} />
               <Button danger type="primary" shape="circle" icon={<DeleteOutlined />} disabled={record.default}/>
            </div>
          }
        },
      ];

      const deleteMethod = (record) => {
        console.log(record);
      }

      return (
        <div>
            <Button></Button>
            <Table dataSource={dataSource} columns={columns}
            pagination={{
              pageSize:5 
            }}
            >
            rowKey = {item => item.id}
            </Table>
        </div>
      )
}

export default UserList;

接下来我逐步完成增删改查的功能

增数据需要用到弹出型的新增表单:

还需要从后端拿取数据,所以定义新的状态: 

import React,{useState,useEffect,useRef} from 'react';
import { Button,Table, Tag,Modal,Popover, Switch,Form,Input,Radio,Select } from 'antd';
import { EditOutlined,DeleteOutlined,ExclamationCircleOutlined } from '@ant-design/icons';
import axios from 'axios';
import { data } from 'react-router-dom';
import Item from 'antd/es/list/Item';
import UserForm from '../../../components/user-manage/UserForm';

const { confirm } = Modal;
function UserList() {
    const [dataSource,setdataSource]=useState([])
    const [isAddVisible,setisAddVisible]=useState(false)
    const [roleList,setroleList]=useState([])
    const [regionList,setregionList]=useState([])
    const addForm = useRef(null)

    useEffect(()=>{
        axios.get("http://localhost:3000/users?_expand=role").then(res=>{
          // console.log(res.data);
          const list = res.data
          setdataSource(list)
       })
    },[])

    useEffect(()=>{
      axios.get("http://localhost:3000/regions").then(res=>{
        // console.log(res.data);
        const list = res.data
        setregionList(list)
     })
  },[])

  useEffect(()=>{
    axios.get("http://localhost:3000/roles").then(res=>{
      // console.log(res.data);
      const list = res.data
      setroleList(list)
   })
},[])
    const columns = [
        {
          title: '区域',
          dataIndex: 'region',
          render:(region)=>{
            return <b>{region===""?'全球':region}</b>
        }
        },
        {
          title: '角色名称',
          dataIndex: 'role',
          render:(role)=>{
              return role?.roleName
          }
        },
        {
          title: '用户名',
          dataIndex: 'username',
        },
        {
            title:"用户状态",
            dataIndex:"roleState",
            render:(roleState,item)=>{
                return <Switch checked={roleState} disabled={item.default}>

                </Switch>
            }
        },
        {
          title: '操作',
          render:(record)=>{
            return <div>
               <Button type="primary" shape="circle" icon={<EditOutlined />} disabled={record.default} />
               <Button danger type="primary" shape="circle" icon={<DeleteOutlined />} disabled={record.default}/>
            </div>
          }
        },
      ];

      const deleteMethod = (record) => {
        // console.log(record);
      }

      const [open, setOpen] = useState(false);

      return (
        <div>
            <Button type='primary' onClick={
              () => setOpen(true)
            }>添加用户</Button>
            <Table dataSource={dataSource} columns={columns}
            pagination={{
              pageSize:5 
            }}
            >
            rowKey = {item => item.id}
            </Table>
            <Modal
        open={open}
        title="添加用户"
        okText="确定"
        cancelText="取消"
        okButtonProps={{ autoFocus: true, htmlType: 'submit' }}
        onCancel={() => setOpen(false)}
        onOk={()=>{
          addForm.current.validateFields().then((value)=>{
            console.log(value);
          }).catch((errInfo)=>{
            console.log(errInfo);
          })
        }}
        destroyOnClose
        modalRender={(dom) => (
          <Form
            layout="vertical"
          >
            {dom}
          </Form>
        )}
      >
        <UserForm regionList={regionList} roleList={roleList}
        ref={addForm}
        ></UserForm>
      </Modal>
        </div>
      )
}

export default UserList;

 把Form单独抽象成组件:

import React, { forwardRef, useImperativeHandle } from 'react';
import { Form, Input, Select } from 'antd';

const UserForm = forwardRef((props, ref) => {
  const [form] = Form.useForm();

  // 让外部 ref 访问 form 的方法
  useImperativeHandle(ref, () => ({
    validateFields: () => form.validateFields(),
    resetFields: () => form.resetFields(),
  }));

  // 选择框事件
  const onChange = (value) => {
    console.log(`selected ${value}`);
  };

  return (
    <Form form={form} layout="vertical"> 
      {/* 用户名 */}
      <Form.Item
        name="username"
        label="用户名"
        rules={[{ required: true, message: '请输入用户名' }]}
      >
        <Input placeholder="请输入用户名" />
      </Form.Item>

      {/* 密码 */}
      <Form.Item
        name="password"
        label="密码"
        rules={[{ required: true, message: '请输入密码' }]}
      >
        <Input.Password placeholder="请输入密码" />
      </Form.Item>

      {/* 区域选择 */}
      <Form.Item
        name="region"
        label="区域"
        rules={[{ required: true, message: '请选择区域' }]}
      >
        <Select
          showSearch
          placeholder="请选择区域"
          optionFilterProp="label"
          onChange={onChange}
          options={props.regionList.map(item => ({
            value: item.id,
            label: item.value,
          }))}
        />
      </Form.Item>

      {/* 角色选择 */}
      <Form.Item
        name="roleId"
        label="角色"
        rules={[{ required: true, message: '请选择角色' }]}
      >
        <Select
          showSearch
          placeholder="请选择角色"
          optionFilterProp="label"
          onChange={onChange}
          options={props.roleList.map(item => ({
            value: item.id,
            label: item.roleName,
          }))}
        />
      </Form.Item>
    </Form>
  );
});

export default UserForm;

这个UserForm组件需要使用forwardRef,这样才可以把ref传递出去,以及遇到的bug:穿出去值了但是打印出结果是空数组: 

修改后就是暴露方法,把之前的div去掉,以及useForm()绑定Form组件

接下来实现超级管理员禁用地区的功能,定义状态禁用

介绍一下Form组件,在 antd 中,我们可以使用 Form.useForm() 来创建一个受控的表单实例:

import { Form, Input, Button } from 'antd';

const MyForm = () => {
  const [form] = Form.useForm(); // 创建表单实例

  const handleSubmit = () => {
    form.validateFields().then(values => {
      console.log('提交的数据:', values);
    }).catch(error => {
      console.log('表单验证失败:', error);
    });
  };

  return (
    <Form form={form} layout="vertical">
      <Form.Item name="username" label="用户名" rules={[{ required: true, message: '请输入用户名' }]}>
        <Input placeholder="请输入用户名" />
      </Form.Item>

      <Form.Item name="password" label="密码" rules={[{ required: true, message: '请输入密码' }]}>
        <Input.Password placeholder="请输入密码" />
      </Form.Item>

      <Button type="primary" onClick={handleSubmit}>提交</Button>
    </Form>
  );
};

Form的一些常用方法:

 加上处理的逻辑,角色和区域的事件应该分开写,改变区域设定的规则,如果是超级管理员的话不能选择区域也可以使表单成功的提交

import React, { useState,forwardRef, useImperativeHandle } from 'react';
import { Form, Input, Select } from 'antd';

// 封装一下
const UserForm = forwardRef((props, ref) => {
    // 使用forwardRef 可以让子组件获取父组件的方法
    const [form] = Form.useForm();

  // 让外部 ref 访问 form 的方法
  useImperativeHandle(ref, () => ({
    validateFields: () => form.validateFields(),
    resetFields: () => form.resetFields(),
  }));

  const [isDisabled, setIsDisabled] = useState(false);

  // 选择框事件
  // 角色选择事件
const handleRoleChange = (value) => {
    if (value === 1) { 
      setIsDisabled(true);
      form.setFieldsValue({ region: "" }); // 清空区域
    } else {
      setIsDisabled(false);
    }
  };
  
  // 区域选择事件 (不影响角色逻辑)
  const handleRegionChange = (value) => {
    console.log("区域选择:", value);
  };
  

  return (
    <Form form={form} layout="vertical"> 
      {/* 用户名 */}
      <Form.Item
        name="username"
        label="用户名"
        rules={[{ required: true, message: '请输入用户名' }]}
      >
        <Input placeholder="请输入用户名" />
      </Form.Item>

      {/* 密码 */}
      <Form.Item
        name="password"
        label="密码"
        rules={[{ required: true, message: '请输入密码' }]}
      >
        <Input.Password placeholder="请输入密码" />
      </Form.Item>

      {/* 区域选择 */}
      <Form.Item
        name="region"
        label="区域"
        rules={isDisabled?[]:[{ required: true, message: '请选择区域' }]}
      >
        <Select
        disabled={isDisabled}
          showSearch
          placeholder="请选择区域"
          optionFilterProp="label"
          onChange={handleRegionChange}
          options={props.regionList.map(item => ({
            value: item.id,
            label: item.value,
          }))}
        />
      </Form.Item>

      {/* 角色选择 */}
      <Form.Item
        name="roleId"
        label="角色"
        rules={[{ required: true, message: '请选择角色' }]}
      >
        <Select
          showSearch
          placeholder="请选择角色"
          optionFilterProp="label"
          onChange={handleRoleChange}
          options={props.roleList.map(item => ({
            value: item.id,
            label: item.roleName,
          }))}
        />
      </Form.Item>
    </Form>
  );
});

export default UserForm;

现在想要将改动同步到页面上:

import React, { useState, useEffect, useRef } from 'react'
import {
  Button,
  Table,
  Tag,
  Modal,
  Popover,
  Switch,
  Form,
  Input,
  Radio,
  Select,
} from 'antd'
import {
  EditOutlined,
  DeleteOutlined,
  ExclamationCircleOutlined,
} from '@ant-design/icons'
import axios from 'axios'
import { data } from 'react-router-dom'
import Item from 'antd/es/list/Item'
import UserForm from '../../../components/user-manage/UserForm'

const { confirm } = Modal
function UserList() {
  const [dataSource, setdataSource] = useState([])
  const [isAddVisible, setisAddVisible] = useState(false)
  const [roleList, setroleList] = useState([])
  const [regionList, setregionList] = useState([])
  const addForm = useRef(null)

  useEffect(() => {
    axios.get('http://localhost:3000/users?_expand=role').then((res) => {
      // console.log(res.data);
      const list = res.data
      setdataSource(list)
    })
  }, [])

  useEffect(() => {
    axios.get('http://localhost:3000/regions').then((res) => {
      // console.log(res.data);
      const list = res.data
      setregionList(list)
    })
  }, [])

  useEffect(() => {
    axios.get('http://localhost:3000/roles').then((res) => {
      // console.log(res.data);
      const list = res.data
      setroleList(list)
    })
  }, [])
  const columns = [
    {
      title: '区域',
      dataIndex: 'region',
      render: (region) => {
        return <b>{region === '' ? '全球' : region}</b>
      },
    },
    {
      title: '角色名称',
      dataIndex: 'role',
      render: (role) => {
        return role?.roleName
      },
    },
    {
      title: '用户名',
      dataIndex: 'username',
    },
    {
      title: '用户状态',
      dataIndex: 'roleState',
      render: (roleState, item) => {
        return <Switch checked={roleState} disabled={item.default}></Switch>
      },
    },
    {
      title: '操作',
      render: (record) => {
        return (
          <div>
            <Button
              type="primary"
              shape="circle"
              icon={<EditOutlined />}
              disabled={record.default}
            />
            <Button
              danger
              type="primary"
              shape="circle"
              icon={<DeleteOutlined />}
              disabled={record.default}
            />
          </div>
        )
      },
    },
  ]

  const deleteMethod = (record) => {
    // console.log(record);
  }
  const addFormOk = () => {
    addForm.current
      .validateFields()
      .then((value) => {
        // console.log(value)
        setOpen(false)
        //post到后端生成id,再设置dataSource,方便删除和更新
        // 修正: 确保 `region` 存储的是字符串,而不是 id
        const selectedRegion = regionList.find(item => item.id === value.region)?.value || "";
        // 获取所选角色的名称
        const selectedRole = roleList.find(item => item.id === value.roleId)?.roleName || "";
        axios.post(`http://localhost:3000/users`,{
          ...value,
          "roleState": true,
          "default": false,
          region: selectedRegion, // 修正 `region` 的值
          roleName: selectedRole, // 修正 `roleName` 的值
        }).then((res) => {
          console.log(res.data)
          setdataSource([...dataSource, res.data])
        })
      })
      .catch((errInfo) => {
        console.log(errInfo)
      })
  }

  const [open, setOpen] = useState(false)

  return (
    <div>
      <Button type="primary" onClick={() => setOpen(true)}>
        添加用户
      </Button>
      <Table
        dataSource={dataSource}
        columns={columns}
        pagination={{
          pageSize: 5,
        }}
      >
        rowKey = {(item) => item.id}
      </Table>
      <Modal
        open={open}
        title="添加用户"
        okText="确定"
        cancelText="取消"
        okButtonProps={{ autoFocus: true, htmlType: 'submit' }}
        onCancel={() => setOpen(false)}
        onOk={() => addFormOk()}
        destroyOnClose
        modalRender={(dom) => <Form layout="vertical">{dom}</Form>}
      >
        <UserForm
          regionList={regionList}
          roleList={roleList}
          ref={addForm}
        ></UserForm>
      </Modal>
    </div>
  )
}

export default UserList

同步确实是同步了,可是这个角色的名称总是不显示,只有刷新一次才会正常的显示。。

这下就又要修改代码了:

import React, { useState, useEffect, useRef } from 'react'
import {
  Button,
  Table,
  Tag,
  Modal,
  Popover,
  Switch,
  Form,
  Input,
  Radio,
  Select,
} from 'antd'
import {
  EditOutlined,
  DeleteOutlined,
  ExclamationCircleOutlined,
} from '@ant-design/icons'
import axios from 'axios'
import { data } from 'react-router-dom'
import Item from 'antd/es/list/Item'
import UserForm from '../../../components/user-manage/UserForm'

const { confirm } = Modal
function UserList() {
  const [dataSource, setdataSource] = useState([])
  const [isAddVisible, setisAddVisible] = useState(false)
  const [roleList, setroleList] = useState([])
  const [regionList, setregionList] = useState([])
  const addForm = useRef(null)

  useEffect(() => {
    axios.get('http://localhost:3000/users?_expand=role').then((res) => {
      // console.log(res.data);
      const list = res.data
      setdataSource(list)
    })
  }, [])

  useEffect(() => {
    axios.get('http://localhost:3000/regions').then((res) => {
      // console.log(res.data);
      const list = res.data
      setregionList(list)
    })
  }, [])

  useEffect(() => {
    axios.get('http://localhost:3000/roles').then((res) => {
      // console.log(res.data);
      const list = res.data
      setroleList(list)
    })
  }, [])
  const columns = [
    {
      title: '区域',
      dataIndex: 'region',
      render: (region) => {
        return <b>{region === '' ? '全球' : region}</b>
      },
    },
    {
      title: '角色名称',
      dataIndex: 'role',
      render: (role) => {
        return role?.roleName
      },
    },
    {
      title: '用户名',
      dataIndex: 'username',
    },
    {
      title: '用户状态',
      dataIndex: 'roleState',
      render: (roleState, item) => {
        return <Switch checked={roleState} disabled={item.default}></Switch>
      },
    },
    {
      title: '操作',
      render: (record) => {
        return (
          <div>
            <Button
              type="primary"
              shape="circle"
              icon={<EditOutlined />}
              disabled={record.default}
            />
            <Button
              danger
              type="primary"
              shape="circle"
              icon={<DeleteOutlined />}
              disabled={record.default}
            />
          </div>
        )
      },
    },
  ]

  const deleteMethod = (record) => {
    // console.log(record);
  }
  const addFormOk = () => {
    addForm.current
      .validateFields()
      .then((value) => {
        // console.log(value)
        setOpen(false)

        addForm.current.resetFields()
        //post到后端生成id,再设置dataSource,方便删除和更新
        // 修正: 确保 `region` 存储的是字符串,而不是 id
        const selectedRegion = regionList.find(item => item.id === value.region)?.value || "";
        // 获取所选角色的名称
        const selectedRole = roleList.find(item => item.id === value.roleId)?.roleName || "";
        axios.post(`http://localhost:3000/users`,{
          ...value,
          "roleState": true,
          "default": false,
          region: selectedRegion, // 修正 `region` 的值
          roleName: selectedRole, // 修正 `roleName` 的值
        }).then((res) => {
          console.log(res.data)
          setdataSource([...dataSource, {...res.data,
            role:roleList.filter(item => item.id === value.roleId)[0],
          }])
        })
      })
      .catch((errInfo) => {
        console.log(errInfo)
      })
  }

  const [open, setOpen] = useState(false)

  return (
    <div>
      <Button type="primary" onClick={() => setOpen(true)}>
        添加用户
      </Button>
      <Table
        dataSource={dataSource}
        columns={columns}
        pagination={{
          pageSize: 5,
        }}
      >
        rowKey = {(item) => item.id}
      </Table>
      <Modal
        open={open}
        title="添加用户"
        okText="确定"
        cancelText="取消"
        okButtonProps={{ autoFocus: true, htmlType: 'submit' }}
        onCancel={() => setOpen(false)}
        onOk={() => addFormOk()}
        destroyOnClose
        modalRender={(dom) => <Form layout="vertical">{dom}</Form>}
      >
        <UserForm
          regionList={regionList}
          roleList={roleList}
          ref={addForm}
        ></UserForm>
      </Modal>
    </div>
  )
}

export default UserList

更新了dataSource的装填,就可以更新并渲染了

分为:扩展现有数据、添加新用户数据、更新状态

至此添加部分的功能都完毕了,来写删除

进行删除的判定确认,同步后端数据:

import React, { useState, useEffect, useRef } from 'react'
import {
  Button,
  Table,
  Tag,
  Modal,
  Popover,
  Switch,
  Form,
  Input,
  Radio,
  Select,
} from 'antd'
import {
  EditOutlined,
  DeleteOutlined,
  ExclamationCircleOutlined,
} from '@ant-design/icons'
import axios from 'axios'
import { data } from 'react-router-dom'
import Item from 'antd/es/list/Item'
import UserForm from '../../../components/user-manage/UserForm'

const { confirm } = Modal
function UserList() {
  const [dataSource, setdataSource] = useState([])
  const [isAddVisible, setisAddVisible] = useState(false)
  const [roleList, setroleList] = useState([])
  const [regionList, setregionList] = useState([])
  const addForm = useRef(null)

  useEffect(() => {
    axios.get('http://localhost:3000/users?_expand=role').then((res) => {
      // console.log(res.data);
      const list = res.data
      setdataSource(list)
    })
  }, [])

  useEffect(() => {
    axios.get('http://localhost:3000/regions').then((res) => {
      // console.log(res.data);
      const list = res.data
      setregionList(list)
    })
  }, [])

  useEffect(() => {
    axios.get('http://localhost:3000/roles').then((res) => {
      // console.log(res.data);
      const list = res.data
      setroleList(list)
    })
  }, [])

  const confirmMethod = (record) => {
    confirm({
      title: '确定要删除这个角色吗?',
      icon: <ExclamationCircleOutlined />,
      onOk() {
        deleteMethod(record)
      },
      onCancel() {
        console.log('取消删除')
      },
    })
  }

  const columns = [
    {
      title: '区域',
      dataIndex: 'region',
      render: (region) => {
        return <b>{region === '' ? '全球' : region}</b>
      },
    },
    {
      title: '角色名称',
      dataIndex: 'role',
      render: (role) => {
        return role?.roleName
      },
    },
    {
      title: '用户名',
      dataIndex: 'username',
    },
    {
      title: '用户状态',
      dataIndex: 'roleState',
      render: (roleState, item) => {
        return <Switch checked={roleState} disabled={item.default}></Switch>
      },
    },
    {
      title: '操作',
      render: (record) => {
        return (
          <div>
            <Button
              type="primary"
              shape="circle"
              icon={<EditOutlined />}
              disabled={record.default}
            />
            <Button
              danger
              type="primary"
              shape="circle"
              icon={<DeleteOutlined />}
              disabled={record.default}
              onClick={()=>confirmMethod(record)}
            />
          </div>
        )
      },
    },
  ]

  const deleteMethod = (record) => {
    // console.log(record);
    //页面状态+后端
    setdataSource(dataSource.filter((item) => item.id !== record.id))
    axios.delete(`http://localhost:3000/users/${record.id}`)
  }
  const addFormOk = () => {
    addForm.current
      .validateFields()
      .then((value) => {
        // console.log(value)
        setOpen(false)

        addForm.current.resetFields()
        //post到后端生成id,再设置dataSource,方便删除和更新
        // 修正: 确保 `region` 存储的是字符串,而不是 id
        const selectedRegion = regionList.find(item => item.id === value.region)?.value || "";
        // 获取所选角色的名称
        const selectedRole = roleList.find(item => item.id === value.roleId)?.roleName || "";
        axios.post(`http://localhost:3000/users`,{
          ...value,
          "roleState": true,
          "default": false,
          region: selectedRegion, // 修正 `region` 的值
          roleName: selectedRole, // 修正 `roleName` 的值
        }).then((res) => {
          console.log(res.data)
          setdataSource([...dataSource, {...res.data,
            role:roleList.filter(item => item.id === value.roleId)[0],
          }])
        })
      })
      .catch((errInfo) => {
        console.log(errInfo)
      })
  }

  const [open, setOpen] = useState(false)

  return (
    <div>
      <Button type="primary" onClick={() => setOpen(true)}>
        添加用户
      </Button>
      <Table
        dataSource={dataSource}
        columns={columns}
        pagination={{
          pageSize: 5,
        }}
      >
        rowKey = {(item) => item.id}
      </Table>
      <Modal
        open={open}
        title="添加用户"
        okText="确定"
        cancelText="取消"
        okButtonProps={{ autoFocus: true, htmlType: 'submit' }}
        onCancel={() => setOpen(false)}
        onOk={() => addFormOk()}
        destroyOnClose
        modalRender={(dom) => <Form layout="vertical">{dom}</Form>}
      >
        <UserForm
          regionList={regionList}
          roleList={roleList}
          ref={addForm}
        ></UserForm>
      </Modal>
    </div>
  )
}

export default UserList

改就是更改状态和更改信息 ,这是更改选择并同步到后端:

import React, { useState, useEffect, useRef } from 'react'
import {
  Button,
  Table,
  Tag,
  Modal,
  Popover,
  Switch,
  Form,
  Input,
  Radio,
  Select,
} from 'antd'
import {
  EditOutlined,
  DeleteOutlined,
  ExclamationCircleOutlined,
} from '@ant-design/icons'
import axios from 'axios'
import { data } from 'react-router-dom'
import Item from 'antd/es/list/Item'
import UserForm from '../../../components/user-manage/UserForm'

const { confirm } = Modal
function UserList() {
  const [dataSource, setdataSource] = useState([])
  const [isAddVisible, setisAddVisible] = useState(false)
  const [roleList, setroleList] = useState([])
  const [regionList, setregionList] = useState([])
  const addForm = useRef(null)

  useEffect(() => {
    axios.get('http://localhost:3000/users?_expand=role').then((res) => {
      // console.log(res.data);
      const list = res.data
      setdataSource(list)
    })
  }, [])

  useEffect(() => {
    axios.get('http://localhost:3000/regions').then((res) => {
      // console.log(res.data);
      const list = res.data
      setregionList(list)
    })
  }, [])

  useEffect(() => {
    axios.get('http://localhost:3000/roles').then((res) => {
      // console.log(res.data);
      const list = res.data
      setroleList(list)
    })
  }, [])

  const deleteMethod = (record) => {
    // console.log(record);
    //页面状态+后端
    setdataSource(dataSource.filter((item) => item.id !== record.id))
    axios.delete(`http://localhost:3000/users/${record.id}`)
  }

  const confirmMethod = (record) => {
    confirm({
      title: '确定要删除这个角色吗?',
      icon: <ExclamationCircleOutlined />,
      onOk() {
        deleteMethod(record)
      },
      onCancel() {
        console.log('取消删除')
      },
    })
  }

  const handleChange = (item)=>{
    // console.log(item)
    item.roleState = !item.roleState
    setdataSource([...dataSource])

    axios.patch(`http://localhost:3000/users/${item.id}`,{
      roleState:item.roleState
    })
  }

  const columns = [
    {
      title: '区域',
      dataIndex: 'region',
      render: (region) => {
        return <b>{region === '' ? '全球' : region}</b>
      },
    },
    {
      title: '角色名称',
      dataIndex: 'role',
      render: (role) => {
        return role?.roleName
      },
    },
    {
      title: '用户名',
      dataIndex: 'username',
    },
    {
      title: '用户状态',
      dataIndex: 'roleState',
      render: (roleState, item) => {
        return <Switch checked={roleState} disabled={item.default}
        onChange={()=>handleChange(item)}
        ></Switch>
      },
    },
    {
      title: '操作',
      render: (record) => {
        return (
          <div>
            <Button
              type="primary"
              shape="circle"
              icon={<EditOutlined />}
              disabled={record.default}
            />
            <Button
              danger
              type="primary"
              shape="circle"
              icon={<DeleteOutlined />}
              disabled={record.default}
              onClick={()=>confirmMethod(record)}
            />
          </div>
        )
      },
    },
  ]

  const addFormOk = () => {
    addForm.current
      .validateFields()
      .then((value) => {
        // console.log(value)
        setOpen(false)

        addForm.current.resetFields()
        //post到后端生成id,再设置dataSource,方便删除和更新
        // 修正: 确保 `region` 存储的是字符串,而不是 id
        const selectedRegion = regionList.find(item => item.id === value.region)?.value || "";
        // 获取所选角色的名称
        const selectedRole = roleList.find(item => item.id === value.roleId)?.roleName || "";
        axios.post(`http://localhost:3000/users`,{
          ...value,
          "roleState": true,
          "default": false,
          region: selectedRegion, // 修正 `region` 的值
          roleName: selectedRole, // 修正 `roleName` 的值
        }).then((res) => {
          console.log(res.data)
          setdataSource([...dataSource, {...res.data,
            role:roleList.filter(item => item.id === value.roleId)[0],
          }])
        })
      })
      .catch((errInfo) => {
        console.log(errInfo)
      })
  }

  const [open, setOpen] = useState(false)

  return (
    <div>
      <Button type="primary" onClick={() => setOpen(true)}>
        添加用户
      </Button>
      <Table
        dataSource={dataSource}
        columns={columns}
        pagination={{
          pageSize: 5,
        }}
      >
        rowKey = {(item) => item.id}
      </Table>
      <Modal
        open={open}
        title="添加用户"
        okText="确定"
        cancelText="取消"
        okButtonProps={{ autoFocus: true, htmlType: 'submit' }}
        onCancel={() => setOpen(false)}
        onOk={() => addFormOk()}
        destroyOnClose
        modalRender={(dom) => <Form layout="vertical">{dom}</Form>}
      >
        <UserForm
          regionList={regionList}
          roleList={roleList}
          ref={addForm}
        ></UserForm>
      </Modal>
    </div>
  )
}

export default UserList

接下来实现点击编辑按钮弹出框可以修改信息的功能

在实现这个功能的时候遇到了问题,我觉得是事件绑定和useEffect的依赖项的问题,现在修改完可以成功的显示旧的数据了:

import React, {
  useState,
  forwardRef,
  useImperativeHandle,
  useEffect,
} from 'react'
import { Form, Input, Select } from 'antd'

const UserForm = forwardRef((props, ref) => {
  const [form] = Form.useForm()
  const internalForm = props.form || form // 使用外部传递的 form 实例
  const [isDisabled, setIsDisabled] = useState(false)

  // useEffect(() => {
  //   if (props.form) {
  //     props.form.setFieldValue(props.initialValues)
  //   }
  //   // setIsDisabled(props.isUpdateDisabled);
  // }, [props.isUpdateDisabled, props.form]) // 修复 useEffect 的语法

  useEffect(() => {
    if (props.form && props.initialValues) {
      props.form.setFieldsValue(props.initialValues);
    }
    setIsDisabled(props.isUpdateDisabled);
  }, [props.isUpdateDisabled, props.form, props.initialValues]); // 确保依赖项正确

  useImperativeHandle(ref, () => ({
    validateFields: () => internalForm.validateFields(),
    resetFields: () => internalForm.resetFields(),
    setFieldsValue: (values) => internalForm.setFieldsValue(values),
  }))

  // const handleRoleChange = (value) => {
  //   if (value === 1) {
  //     setIsDisabled(true);
  //     form.setFieldsValue({ region: "" });
  //   } else {
  //     setIsDisabled(false);
  //   }
  // };
  // UserForm 组件中的角色切换逻辑
  const handleRoleChange = (value) => {
    const isSuperAdmin = value === 1 // 假设角色ID=1是超级管理员
    setIsDisabled(isSuperAdmin)
    if (isSuperAdmin) {
      internalForm.setFieldsValue({ region: '' }) // 清空区域选择
    }
  }

  const handleRegionChange = (value) => {
    console.log('区域选择:', value)
  }

  return (
    <Form form={internalForm} layout="vertical">
      <Form.Item
        name="username"
        label="用户名"
        rules={[{ required: true, message: '请输入用户名' }]}
      >
        <Input placeholder="请输入用户名" />
      </Form.Item>
      {/* 
      <Form.Item
        name="password"
        label="密码"
        rules={[{ required: true, message: '请输入密码' }]}
      >
        <Input.Password placeholder="请输入密码" />
      </Form.Item> */}

      <Form.Item
        name="password"
        label="密码"
        rules={[{ required: true, message: '请输入密码' }]}
      >
        <Input.Password placeholder="请输入密码" />
      </Form.Item>
      <Form.Item
        name="region"
        label="区域"
        rules={isDisabled ? [] : [{ required: true, message: '请选择区域' }]}
      >
        <Select
          disabled={isDisabled}
          showSearch
          placeholder="请选择区域"
          optionFilterProp="label"
          onChange={handleRegionChange}
          options={props.regionList.map((item) => ({
            value: item.id,
            label: item.value,
          }))}
        />
      </Form.Item>

      <Form.Item
        name="roleId"
        label="角色"
        rules={[{ required: true, message: '请选择角色' }]}
      >
        <Select
          showSearch
          placeholder="请选择角色"
          optionFilterProp="label"
          onChange={handleRoleChange}
          options={props.roleList.map((item) => ({
            value: item.id,
            label: item.roleName,
          }))}
        />
      </Form.Item>
    </Form>
  )
})

export default UserForm
import React, { useState, useEffect, useRef } from 'react'
import { Button, Table, Modal, Switch, Form, Menu } from 'antd'
import {
  EditOutlined,
  DeleteOutlined,
  ExclamationCircleOutlined,
} from '@ant-design/icons'
import axios from 'axios'
import UserForm from '../../../components/user-manage/UserForm'

const { confirm } = Modal
function UserList() {
  const [dataSource, setdataSource] = useState([])
  const [isAddVisible, setisAddVisible] = useState(false)
  const [roleList, setroleList] = useState([])
  const [regionList, setregionList] = useState([])
  const [isUpdateVisible, setisUpdateVisible] = useState(false)
  const [isUpdateDisabled, setisUpdateDisabled] = useState(false)
  const [form] = Form.useForm() //创建antd的form实例

  const updateForm = useRef(null)
  const addForm = useRef(null)

  useEffect(() => {
    axios.get('http://localhost:3000/users?_expand=role').then((res) => {
      // console.log(res.data);
      const list = res.data
      setdataSource(list)
    })
  }, [])

  useEffect(() => {
    axios.get('http://localhost:3000/regions').then((res) => {
      // console.log(res.data);
      const list = res.data
      setregionList(list)
    })
  }, [])

  useEffect(() => {
    axios.get('http://localhost:3000/roles').then((res) => {
      // console.log(res.data);
      const list = res.data
      setroleList(list)
    })
  }, [])

  const deleteMethod = (record) => {
    // console.log(record);
    //页面状态+后端
    setdataSource(dataSource.filter((item) => item.id !== record.id))
    axios.delete(`http://localhost:3000/users/${record.id}`)
  }

  const confirmMethod = (record) => {
    confirm({
      title: '确定要删除这个角色吗?',
      icon: <ExclamationCircleOutlined />,
      onOk() {
        deleteMethod(record)
      },
      onCancel() {
        console.log('取消删除')
      },
    })
  }

  const handleChange = (item) => {
    // console.log(item)
    item.roleState = !item.roleState
    setdataSource([...dataSource])

    axios.patch(`http://localhost:3000/users/${item.id}`, {
      roleState: item.roleState,
    })
  }

  const columns = [
    {
      title: '区域',
      dataIndex: 'region',
      render: (region) => {
        return <b>{region === '' ? '全球' : region}</b>
      },
    },
    {
      title: '角色名称',
      dataIndex: 'role',
      render: (role) => {
        return role?.roleName
      },
    },
    {
      title: '用户名',
      dataIndex: 'username',
    },
    {
      title: '用户状态',
      dataIndex: 'roleState',
      render: (roleState, item) => {
        return (
          <Switch
            checked={roleState}
            disabled={item.default}
            onChange={() => handleChange(item)}
          ></Switch>
        )
      },
    },
    {
      title: '操作',
      render: (record) => {
        return (
          <div>
            <Button
              type="primary"
              shape="circle"
              icon={<EditOutlined />}
              disabled={record.default}
              onClick={() => handleUpdate(record)}
            />
            <Button
              danger
              type="primary"
              shape="circle"
              icon={<DeleteOutlined />}
              disabled={record.default}
              onClick={() => confirmMethod(record)}
            />
          </div>
        )
      },
    },
  ]

  const addFormOk = () => {
    addForm.current
      .validateFields()
      .then((value) => {
        // console.log(value)
        setOpen(false)

        addForm.current.resetFields()
        //post到后端生成id,再设置dataSource,方便删除和更新
        // 修正: 确保 `region` 存储的是字符串,而不是 id
        // const selectedRegion = regionList.find(item => item.id === value.region)?.value || "";
        // 添加用户的代码逻辑
        const selectedRegion =
          regionList.find((item) => item.id === value.region)?.value || ''
        axios.post(`http://localhost:3000/users`, {
          ...value,
          region: selectedRegion, // 存储的是区域的名称(如"华东")
        })
        // 获取所选角色的名称
        const selectedRole =
          roleList.find((item) => item.id === value.roleId)?.roleName || ''
        axios
          .post(`http://localhost:3000/users`, {
            ...value,
            roleState: true,
            default: false,
            region: selectedRegion, // 修正 `region` 的值
            roleName: selectedRole, // 修正 `roleName` 的值
          })
          .then((res) => {
            console.log(res.data)
            setdataSource([
              ...dataSource,
              {
                ...res.data,
                role: roleList.filter((item) => item.id === value.roleId)[0],
              },
            ])
          })
      })
      .catch((errInfo) => {
        console.log(errInfo)
      })
  }

  const [isUpdate, setisUpdate] = useState(false)
  const [updateform] = Form.useForm() //创建antd的updateform实例

  // const handleUpdate = (item) => {
  //   setisUpdateVisible(true)
  //   setisUpdateDisabled(item.default)
  //   if(item.roleId === 1){
  //       //禁用
  //       setisUpdateDisabled(true)
  //   }
  //   else{
  //     setisUpdateDisabled(false) // 启用更新表单的编辑
  //   }
  //   setTimeout(() => {
  //     updateform.setFieldsValue({
  //       username: item.username,
  //       region: item.region,
  //       roleId: item.role?.id,
  //     })
  //   }, 100) // 增加一定的延迟确保 Modal 已渲染

  //   // //更新要想办法让已有数据展示出来
  //   // // setisUpdate(true)
  //   // updateform.setFieldsValue({ // 填充表单数据
  //   // username: item.username,
  //   // region: item.region,
  //   // roleId: item.role?.id
  //   // });
  // }
  // const handleUpdate = (item) => {
  //   setisUpdateVisible(true);
  //   setisUpdateDisabled(item.default);
  //   if (item.roleId === 1) {
  //     setisUpdateDisabled(true);
  //   } else {
  //     setisUpdateDisabled(false);
  //   }
  //   setTimeout(() => {
  //     updateform.setFieldsValue({
  //       username: item.username,
  //       region: item.region,
  //       roleId: item.role?.id,
  //       password: item.password, // 确保密码字段被正确设置
  //     });
  //   }, 100);
  // }
  const handleUpdate = (item) => {
    setisUpdateVisible(true);
    setisUpdateDisabled(item.default);
    setTimeout(() => {
      updateform.setFieldsValue({
        username: item.username,
        password: item.password, // 确保密码字段被正确设置
        region: item.region,
        roleId: item.role?.id,
      });
    }, 100); // 增加一定的延迟确保 Modal 已渲染
  }

  const [open, setOpen] = useState(false)
  const updateFormOk = () => {}

  return (
    <div>
      <Button type="primary" onClick={() => setOpen(true)}>
        添加用户
      </Button>
      <Table
        dataSource={dataSource}
        columns={columns}
        pagination={{
          pageSize: 5,
        }}
      >
        rowKey = {(item) => item.id}
      </Table>
      <Modal
        open={open}
        title="添加用户"
        okText="确定"
        cancelText="取消"
        okButtonProps={{ autoFocus: true, htmlType: 'submit' }}
        onCancel={() => setOpen(false)}
        onOk={() => addFormOk()}
        destroyOnClose
        modalRender={(dom) => <Form layout="vertical">{dom}</Form>}
      >
        <UserForm
          regionList={regionList}
          roleList={roleList}
          ref={addForm}
        ></UserForm>
      </Modal>

      {/* 更新  */}
      <Modal
        open={isUpdateVisible}
        title="更新用户"
        okText="更新"
        cancelText="取消"
        okButtonProps={{ autoFocus: true, htmlType: 'submit' }}
        onCancel={() => {setisUpdateVisible(false)
            setisUpdateDisabled(!isUpdateDisabled)
        }}
        onOk={() => updateFormOk()}
        destroyOnClose
        modalRender={(dom) => (
          <Form layout="vertical" form={updateform}>
            {/* //将form实例传递给Form组件 */}
            {dom}
          </Form>
        )}
      >
        <UserForm
          regionList={regionList}
          roleList={roleList}
          form={updateform}
          isUpdateDisabled={isUpdateDisabled}
        ></UserForm>
      </Modal>
    </div>
  )
}

export default UserList

更改并且同步了后端的数据:

import React, { useState, useEffect, useRef } from 'react'
import { Button, Table, Modal, Switch, Form, Menu } from 'antd'
import {
  EditOutlined,
  DeleteOutlined,
  ExclamationCircleOutlined,
} from '@ant-design/icons'
import axios from 'axios'
import UserForm from '../../../components/user-manage/UserForm'

const { confirm } = Modal
function UserList() {
  const [dataSource, setdataSource] = useState([])
  const [isAddVisible, setisAddVisible] = useState(false)
  const [roleList, setroleList] = useState([])
  const [regionList, setregionList] = useState([])
  const [isUpdateVisible, setisUpdateVisible] = useState(false)
  const [isUpdateDisabled, setisUpdateDisabled] = useState(false)
  const [form] = Form.useForm() //创建antd的form实例
  const [current,setCurrent] = useState(null)

  const updateForm = useRef(null)
  const addForm = useRef(null)

  useEffect(() => {
    axios.get('http://localhost:3000/users?_expand=role').then((res) => {
      // console.log(res.data);
      const list = res.data
      setdataSource(list)
    })
  }, [])

  useEffect(() => {
    axios.get('http://localhost:3000/regions').then((res) => {
      // console.log(res.data);
      const list = res.data
      setregionList(list)
    })
  }, [])

  useEffect(() => {
    axios.get('http://localhost:3000/roles').then((res) => {
      // console.log(res.data);
      const list = res.data
      setroleList(list)
    })
  }, [])

  const deleteMethod = (record) => {
    // console.log(record);
    //页面状态+后端
    setdataSource(dataSource.filter((item) => item.id !== record.id))
    axios.delete(`http://localhost:3000/users/${record.id}`)
  }

  const confirmMethod = (record) => {
    confirm({
      title: '确定要删除这个角色吗?',
      icon: <ExclamationCircleOutlined />,
      onOk() {
        deleteMethod(record)
      },
      onCancel() {
        console.log('取消删除')
      },
    })
  }

  const handleChange = (item) => {
    // console.log(item)
    item.roleState = !item.roleState
    setdataSource([...dataSource])

    axios.patch(`http://localhost:3000/users/${item.id}`, {
      roleState: item.roleState,
    })
  }

  const columns = [
    {
      title: '区域',
      dataIndex: 'region',
      render: (region) => {
        return <b>{region === '' ? '全球' : region}</b>
      },
    },
    {
      title: '角色名称',
      dataIndex: 'role',
      render: (role) => {
        return role?.roleName
      },
    },
    {
      title: '用户名',
      dataIndex: 'username',
    },
    {
      title: '用户状态',
      dataIndex: 'roleState',
      render: (roleState, item) => {
        return (
          <Switch
            checked={roleState}
            disabled={item.default}
            onChange={() => handleChange(item)}
          ></Switch>
        )
      },
    },
    {
      title: '操作',
      render: (record) => {
        return (
          <div>
            <Button
              type="primary"
              shape="circle"
              icon={<EditOutlined />}
              disabled={record.default}
              onClick={() => handleUpdate(record)}
            />
            <Button
              danger
              type="primary"
              shape="circle"
              icon={<DeleteOutlined />}
              disabled={record.default}
              onClick={() => confirmMethod(record)}
            />
          </div>
        )
      },
    },
  ]

  const addFormOk = () => {
    addForm.current
      .validateFields()
      .then((value) => {
        // console.log(value)
        setOpen(false)

        addForm.current.resetFields()
        //post到后端生成id,再设置dataSource,方便删除和更新
        // 修正: 确保 `region` 存储的是字符串,而不是 id
        // const selectedRegion = regionList.find(item => item.id === value.region)?.value || "";
        // 添加用户的代码逻辑
        const selectedRegion =
          regionList.find((item) => item.id === value.region)?.value || ''
        axios.post(`http://localhost:3000/users`, {
          ...value,
          region: selectedRegion, // 存储的是区域的名称(如"华东")
        })
        // 获取所选角色的名称
        const selectedRole =
          roleList.find((item) => item.id === value.roleId)?.roleName || ''
        axios
          .post(`http://localhost:3000/users`, {
            ...value,
            roleState: true,
            default: false,
            region: selectedRegion, // 修正 `region` 的值
            roleName: selectedRole, // 修正 `roleName` 的值
          })
          .then((res) => {
            console.log(res.data)
            setdataSource([
              ...dataSource,
              {
                ...res.data,
                role: roleList.filter((item) => item.id === value.roleId)[0],
              },
            ])
          })
      })
      .catch((errInfo) => {
        console.log(errInfo)
      })
  }

  const [isUpdate, setisUpdate] = useState(false)
  const [updateform] = Form.useForm() //创建antd的updateform实例

  const handleUpdate = (item) => {
    setisUpdateVisible(true);
    setisUpdateDisabled(item.default);
    setTimeout(() => {
      //保证超级管理员的区域禁用
      if(item.roleId === 1) {
        setisUpdateDisabled(true)
      } else {
        setisUpdateDisabled(false)
      }
      updateform.setFieldsValue({
        username: item.username,
        password: item.password, // 确保密码字段被正确设置
        region: item.region,
        roleId: item.role?.id,
      });
    }, 100); // 增加一定的延迟确保 Modal 已渲染
    setCurrent(item)
  }

  const [open, setOpen] = useState(false)

  const updateFormOk = () => {
    updateform
      .validateFields()
      .then((value) => {
        setisUpdateVisible(false);
        const selectedRegion = regionList.find(region => region.id === value.region)?.value || '';
        setdataSource(dataSource.map((item) => {
          if (item.id === current.id) {
            return {
              ...item,
              ...value,
              region: selectedRegion, // 将区域 ID 转换为区域名称
              role: roleList.filter((data) => data.id === value.roleId)[0],
            }
          }
          return item;
        }));
        // 同步后端数据
        axios.patch(`http://localhost:3000/users/${current.id}`, {
          ...value,
          region: selectedRegion, // 确保后端也存储区域名称
        });
      });
  }

  return (
    <div>
      <Button type="primary" onClick={() => setOpen(true)}>
        添加用户
      </Button>
      <Table
        dataSource={dataSource}
        columns={columns}
        pagination={{
          pageSize: 5,
        }}
      >
        rowKey = {(item) => item.id}
      </Table>
      <Modal
        open={open}
        title="添加用户"
        okText="确定"
        cancelText="取消"
        okButtonProps={{ autoFocus: true, htmlType: 'submit' }}
        onCancel={() => setOpen(false)}
        onOk={() => addFormOk()}
        destroyOnClose
        modalRender={(dom) => <Form layout="vertical">{dom}</Form>}
      >
        <UserForm
          regionList={regionList}
          roleList={roleList}
          ref={addForm}
        ></UserForm>
      </Modal>

      {/* 更新  */}
      <Modal
        open={isUpdateVisible}
        title="更新用户"
        okText="更新"
        cancelText="取消"
        okButtonProps={{ autoFocus: true, htmlType: 'submit' }}
        onCancel={() => {setisUpdateVisible(false)
            setisUpdateDisabled(!isUpdateDisabled)
        }}
        onOk={() => updateFormOk()}
        destroyOnClose
        modalRender={(dom) => (
          <Form layout="vertical" form={updateform}>
            {/* //将form实例传递给Form组件 */}
            {dom}
          </Form>
        )}
      >
        <UserForm
          regionList={regionList}
          roleList={roleList}
          form={updateform}
          isUpdateDisabled={isUpdateDisabled}
        ></UserForm>
      </Modal>
    </div>
  )
}

export default UserList
import React, {
  useState,
  forwardRef,
  useImperativeHandle,
  useEffect,
} from 'react'
import { Form, Input, Select } from 'antd'

const UserForm = forwardRef((props, ref) => {
  const [form] = Form.useForm()
  const internalForm = props.form || form // 使用外部传递的 form 实例
  const [isDisabled, setIsDisabled] = useState(false)

  // useEffect(() => {
  //   if (props.form) {
  //     props.form.setFieldValue(props.initialValues)
  //   }
  //   // setIsDisabled(props.isUpdateDisabled);
  // }, [props.isUpdateDisabled, props.form]) // 修复 useEffect 的语法

  useEffect(() => {
    if (props.form && props.initialValues) {
      props.form.setFieldsValue(props.initialValues);
    }
    setIsDisabled(props.isUpdateDisabled);
  }, [props.isUpdateDisabled, props.form, props.initialValues]); // 确保依赖项正确

  useImperativeHandle(ref, () => ({
    validateFields: () => internalForm.validateFields(),
    resetFields: () => internalForm.resetFields(),
    setFieldsValue: (values) => internalForm.setFieldsValue(values),
  }))

  // const handleRoleChange = (value) => {
  //   if (value === 1) {
  //     setIsDisabled(true);
  //     form.setFieldsValue({ region: "" });
  //   } else {
  //     setIsDisabled(false);
  //   }
  // };
  // UserForm 组件中的角色切换逻辑
  const handleRoleChange = (value) => {
    const isSuperAdmin = value === 1 // 假设角色ID=1是超级管理员
    setIsDisabled(isSuperAdmin)
    if (isSuperAdmin) {
      internalForm.setFieldsValue({ region: '' }) // 清空区域选择
    }
  }

  const handleRegionChange = (value) => {
    console.log('区域选择:', value)
  }

  return (
    <Form form={internalForm} layout="vertical">
      <Form.Item
        name="username"
        label="用户名"
        rules={[{ required: true, message: '请输入用户名' }]}
      >
        <Input placeholder="请输入用户名" />
      </Form.Item>
      {/* 
      <Form.Item
        name="password"
        label="密码"
        rules={[{ required: true, message: '请输入密码' }]}
      >
        <Input.Password placeholder="请输入密码" />
      </Form.Item> */}

      <Form.Item
        name="password"
        label="密码"
        rules={[{ required: true, message: '请输入密码' }]}
      >
        <Input.Password placeholder="请输入密码" />
      </Form.Item>
      <Form.Item
        name="region"
        label="区域"
        rules={isDisabled ? [] : [{ required: true, message: '请选择区域' }]}
      >
        <Select
          disabled={isDisabled}
          showSearch
          placeholder="请选择区域"
          optionFilterProp="label"
          onChange={handleRegionChange}
          options={props.regionList.map((item) => ({
            value: item.id,
            label: item.value,
          }))}
        />
      </Form.Item>

      <Form.Item
        name="roleId"
        label="角色"
        rules={[{ required: true, message: '请选择角色' }]}
      >
        <Select
          showSearch
          placeholder="请选择角色"
          optionFilterProp="label"
          onChange={handleRoleChange}
          options={props.roleList.map((item) => ({
            value: item.id,
            label: item.roleName,
          }))}
        />
      </Form.Item>
    </Form>
  )
})

export default UserForm

实现一个过滤地区的功能

这个过滤是table组件自带的功能

筛选主要控制的是onFilter属性

import React, { useState, useEffect, useRef } from 'react'
import { Button, Table, Modal, Switch, Form, Menu } from 'antd'
import {
  EditOutlined,
  DeleteOutlined,
  ExclamationCircleOutlined,
} from '@ant-design/icons'
import axios from 'axios'
import UserForm from '../../../components/user-manage/UserForm'

const { confirm } = Modal
function UserList() {
  const [dataSource, setdataSource] = useState([])
  const [isAddVisible, setisAddVisible] = useState(false)
  const [roleList, setroleList] = useState([])
  const [regionList, setregionList] = useState([])
  const [isUpdateVisible, setisUpdateVisible] = useState(false)
  const [isUpdateDisabled, setisUpdateDisabled] = useState(false)
  const [form] = Form.useForm() //创建antd的form实例
  const [current,setCurrent] = useState(null)

  const updateForm = useRef(null)
  const addForm = useRef(null)

  useEffect(() => {
    axios.get('http://localhost:3000/users?_expand=role').then((res) => {
      // console.log(res.data);
      const list = res.data
      setdataSource(list)
    })
  }, [])

  useEffect(() => {
    axios.get('http://localhost:3000/regions').then((res) => {
      // console.log(res.data);
      const list = res.data
      setregionList(list)
    })
  }, [])

  useEffect(() => {
    axios.get('http://localhost:3000/roles').then((res) => {
      // console.log(res.data);
      const list = res.data
      setroleList(list)
    })
  }, [])

  const deleteMethod = (record) => {
    // console.log(record);
    //页面状态+后端
    setdataSource(dataSource.filter((item) => item.id !== record.id))
    axios.delete(`http://localhost:3000/users/${record.id}`)
  }

  const confirmMethod = (record) => {
    confirm({
      title: '确定要删除这个角色吗?',
      icon: <ExclamationCircleOutlined />,
      onOk() {
        deleteMethod(record)
      },
      onCancel() {
        console.log('取消删除')
      },
    })
  }

  const handleChange = (item) => {
    // console.log(item)
    item.roleState = !item.roleState
    setdataSource([...dataSource])

    axios.patch(`http://localhost:3000/users/${item.id}`, {
      roleState: item.roleState,
    })
  }

  const columns = [
    {
      title: '区域',
      dataIndex: 'region',
      filters:[
        ...regionList.map((item) => ({
            text: item.value,
            value: item.value,
        }))
        ,{
          text: '全球',
          value: '全球',
        }
      ],

      onFilter: (value, item) =>
        {
          if(value === '全球') {
            return item.region === ""
          }
          return item.region===value
        }, 

      render: (region) => {
        return <b>{region === '' ? '全球' : region}</b>
      },
    },
    {
      title: '角色名称',
      dataIndex: 'role',
      render: (role) => {
        return role?.roleName
      },
    },
    {
      title: '用户名',
      dataIndex: 'username',
    },
    {
      title: '用户状态',
      dataIndex: 'roleState',
      render: (roleState, item) => {
        return (
          <Switch
            checked={roleState}
            disabled={item.default}
            onChange={() => handleChange(item)}
          ></Switch>
        )
      },
    },
    {
      title: '操作',
      render: (record) => {
        return (
          <div>
            <Button
              type="primary"
              shape="circle"
              icon={<EditOutlined />}
              disabled={record.default}
              onClick={() => handleUpdate(record)}
            />
            <Button
              danger
              type="primary"
              shape="circle"
              icon={<DeleteOutlined />}
              disabled={record.default}
              onClick={() => confirmMethod(record)}
            />
          </div>
        )
      },
    },
  ]

  const addFormOk = () => {
    addForm.current
      .validateFields()
      .then((value) => {
        // console.log(value)
        setOpen(false)

        addForm.current.resetFields()
        //post到后端生成id,再设置dataSource,方便删除和更新
        // 修正: 确保 `region` 存储的是字符串,而不是 id
        // const selectedRegion = regionList.find(item => item.id === value.region)?.value || "";
        // 添加用户的代码逻辑
        const selectedRegion =
          regionList.find((item) => item.id === value.region)?.value || ''
        axios.post(`http://localhost:3000/users`, {
          ...value,
          region: selectedRegion, // 存储的是区域的名称(如"华东")
        })
        // 获取所选角色的名称
        const selectedRole =
          roleList.find((item) => item.id === value.roleId)?.roleName || ''
        axios
          .post(`http://localhost:3000/users`, {
            ...value,
            roleState: true,
            default: false,
            region: selectedRegion, // 修正 `region` 的值
            roleName: selectedRole, // 修正 `roleName` 的值
          })
          .then((res) => {
            console.log(res.data)
            setdataSource([
              ...dataSource,
              {
                ...res.data,
                role: roleList.filter((item) => item.id === value.roleId)[0],
              },
            ])
          })
      })
      .catch((errInfo) => {
        console.log(errInfo)
      })
  }

  const [isUpdate, setisUpdate] = useState(false)
  const [updateform] = Form.useForm() //创建antd的updateform实例

  const handleUpdate = (item) => {
    setisUpdateVisible(true);
    setisUpdateDisabled(item.default);
    setTimeout(() => {
      //保证超级管理员的区域禁用
      if(item.roleId === 1) {
        setisUpdateDisabled(true)
      } else {
        setisUpdateDisabled(false)
      }
      updateform.setFieldsValue({
        username: item.username,
        password: item.password, // 确保密码字段被正确设置
        region: item.region,
        roleId: item.role?.id,
      });
    }, 100); // 增加一定的延迟确保 Modal 已渲染
    setCurrent(item)
  }

  const [open, setOpen] = useState(false)

  const updateFormOk = () => {
    updateform
      .validateFields()
      .then((value) => {
        setisUpdateVisible(false);
        const selectedRegion = regionList.find(region => region.id === value.region)?.value || '';
        setdataSource(dataSource.map((item) => {
          if (item.id === current.id) {
            return {
              ...item,
              ...value,
              region: selectedRegion, // 将区域 ID 转换为区域名称
              role: roleList.filter((data) => data.id === value.roleId)[0],
            }
          }
          return item;
        }));
        // 同步后端数据
        axios.patch(`http://localhost:3000/users/${current.id}`, {
          ...value,
          region: selectedRegion, // 确保后端也存储区域名称
        });
      });
  }

  return (
    <div>
      <Button type="primary" onClick={() => setOpen(true)}>
        添加用户
      </Button>
      <Table
        dataSource={dataSource}
        columns={columns}
        pagination={{
          pageSize: 5,
        }}
      >
        rowKey = {(item) => item.id}
      </Table>
      <Modal
        open={open}
        title="添加用户"
        okText="确定"
        cancelText="取消"
        okButtonProps={{ autoFocus: true, htmlType: 'submit' }}
        onCancel={() => setOpen(false)}
        onOk={() => addFormOk()}
        destroyOnClose
        modalRender={(dom) => <Form layout="vertical">{dom}</Form>}
      >
        <UserForm
          regionList={regionList}
          roleList={roleList}
          ref={addForm}
        ></UserForm>
      </Modal>

      {/* 更新  */}
      <Modal
        open={isUpdateVisible}
        title="更新用户"
        okText="更新"
        cancelText="取消"
        okButtonProps={{ autoFocus: true, htmlType: 'submit' }}
        onCancel={() => {setisUpdateVisible(false)
            setisUpdateDisabled(!isUpdateDisabled)
        }}
        onOk={() => updateFormOk()}
        destroyOnClose
        modalRender={(dom) => (
          <Form layout="vertical" form={updateform}>
            {/* //将form实例传递给Form组件 */}
            {dom}
          </Form>
        )}
      >
        <UserForm
          regionList={regionList}
          roleList={roleList}
          form={updateform}
          isUpdateDisabled={isUpdateDisabled}
        ></UserForm>
      </Modal>
    </div>
  )
}

export default UserList

至此用户阶段的增删改查全部完成

相关文章:

  • AIP-203 域行为文档
  • MyBatis执行批量插入sqlserver报错:不允许从数据类型 varbinary 到 datetime2 的隐式转换
  • PowerBi 桑基图(SanKey)显示多节点的解决方法
  • 数据结构与算法基本概念
  • 使用大语言模型进行Python图表可视化
  • 【质量管理】质量的系统是预防,那以预防为主的质量管理系统包括什么?
  • 【QT】练习1
  • 里昂惕夫矩阵:投入产出分析
  • element-plus走马灯(el-carousel)不显示问题
  • 【数论3】裴属定理与扩展欧几里得算法
  • naive_admin项目实战03 基于Go语言的后端
  • LearnOpenGL小练习(QOpenGLWidget版本)
  • 【杂谈】-大型语言模型对具身人工智能发展的推动与挑战
  • Apache Hive和Snowflake的`CREATE VIEW`语法和功能特性整理的对比表
  • 移动端六大语言速记:第5部分 - 面向对象编程(OOP)
  • 翻译: 人工智能如何让世界变得更美好三
  • 深入解析HTTP请求方法:Spring Boot实战与最佳实践
  • 【LeetCode 热题100】208:实现 Trie (前缀树)(详细解析)(Go语言版)
  • leetcode 53.Maximum Subarray
  • Docker学习--容器生命周期管理相关命令--run命令
  • 简述网站开发的三层架构/windows优化大师手机版
  • 专业做辅助的网站/现在广告行业好做吗
  • 网站建设业务员提成/百度手机快速排名点击软件
  • 设计网站公司的口号/知乎关键词排名
  • 沈阳大型网站制作公司/手游推广个人合作平台
  • 提供网站建设报价/移动建站优化