【GPT-3.5 Turbo】React、AntD5:Table中的Select条件渲染成输入值(输入值来自Table外)

前端项目技术栈:React18, Antd 5, TypeScript。
问题和实现:1. Antd 5,在一个Table中,最后一列是Select单项选择器,它有两个值分别是“值”和“参数”,因此value分别绑定了"value",“param”。
2. 当在选择器里选择了值或者参数后,会在页面下弹出一个div,里面是Form,Form里可以输入对应的值或参数,输入的内容将被显示在Select所在的列,也就是说如果在Table第一行的选择器选了参数,并在弹出的Form里输入参数并提交,第一行的选择器所在的列就没有选择器了,取而代之的是输入的参数文本。
以上如何实现,请提供详细的代码

实现上述功能,你可以使用React18和Antd 5来创建一个Table组件,然后在Table的最后一列使用Antd的Select组件来实现单项选择器。接下来,当用户在选择器中选择了值或参数后,可以在页面下方弹出一个Modal组件,里面放置一个Form组件,用户可以在Form中输入对应的值或参数。

下面是一个简单的示例代码来实现上述功能:

import React, { useState } from 'react';
import { Table, Select, Modal, Form, Input } from 'antd';

const { Option } = Select;

const MyTable = () => {
  const [modalVisible, setModalVisible] = useState(false);
  const [selectedRow, setSelectedRow] = useState(null);

  const handleSelectChange = (value, row) => {
    if (value === 'param') {
      setModalVisible(true);
      setSelectedRow(row);
    }
  };

  const handleModalOk = (values) => {
    const newData = [...dataSource];
    const index = newData.findIndex((item) => selectedRow.key === item.key);
    const item = newData[index];
    newData.splice(index, 1, {
      ...item,
      value: values.value,
    });
    setDataSource(newData);
    setModalVisible(false);
  };

  const columns = [
    // other columns
    {
      title: 'Select',
      dataIndex: 'select',
      render: (text, record) => (
        <Select defaultValue="value" style={{ width: 120 }} onChange={(value) => handleSelectChange(value, record)}>
          <Option value="value">Value</Option>
          <Option value="param">Param</Option>
        </Select>
      ),
    },
  ];

  const dataSource = [
    // your data source
  ];

  return (
    <div>
      <Table columns={columns} dataSource={dataSource} />
      <Modal
        title="Input Value/Param"
        visible={modalVisible}
        onOk={handleModalOk}
        onCancel={() => setModalVisible(false)}
      >
        <Form
          name="inputForm"
          onFinish={handleModalOk}
        >
          <Form.Item
            label="Value/Param"
            name="value"
            rules={[{ required: true, message: 'Please input value or param!' }]}
          >
            <Input />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
};

export default MyTable;

在上面的代码中,我们使用了useState来管理Modal的显示与隐藏以及用户输入的值,同时在handleSelectChange函数中根据用户选择的值来决定是否显示Modal。在Modal中,用户可以输入对应的值或参数,并在点击确定后更新Table中选择器所在的列的值。
?可以修改一下上述代码中的一个地方吗:在render里通过条件渲染的方式,当Form提交了input的数据后,把Select去掉,通过record换成来自Form的数据,也就是把Form里input的数据放进record里面。?
当Form提交了input的数据后,可以通过条件渲染的方式将Select替换为Form输入的数据。以下是修改后的代码:

// ...(上面的代码保持不变)

const MyTable = () => {
  const [modalVisible, setModalVisible] = useState(false);
  const [selectedRow, setSelectedRow] = useState(null);
  const [formData, setFormData] = useState(null);

  const handleSelectChange = (value, row) => {
    if (value === 'param') {
      setModalVisible(true);
      setSelectedRow(row);
    }
  };

  const handleModalOk = (values) => {
    setFormData(values);
    const newData = [...dataSource];
    const index = newData.findIndex((item) => selectedRow.key === item.key);
    const item = newData[index];
    newData.splice(index, 1, {
      ...item,
      select: values.value, // replace select with form input
    });
    setDataSource(newData);
    setModalVisible(false);
  };

  const columns = [
    // other columns
    {
      title: 'Select',
      dataIndex: 'select',
      render: (text, record) => {
        if (formData && selectedRow.key === record.key) {
          return formData.value; // render form input value if form is submitted
        }
        return (
          <Select defaultValue="value" style={{ width: 120 }} onChange={(value) => handleSelectChange(value, record)}>
            <Option value="value">Value</Option>
            <Option value="param">Param</Option>
          </Select>
        );
      },
    },
  ];

  const dataSource = [
    // your data source
  ];

  return (
    <div>
      <Table columns={columns} dataSource={dataSource} />
      <Modal
        title="Input Value/Param"
        visible={modalVisible}
        onOk={handleModalOk}
        onCancel={() => setModalVisible(false)}
      >
        <Form
          name="inputForm"
          onFinish={handleModalOk}
        >
          <Form.Item
            label="Value/Param"
            name="value"
            rules={[{ required: true, message: 'Please input value or param!' }]}
          >
            <Input />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
};

export default MyTable;

在上述代码中,我们添加了一个formData状态来存储Form提交的数据,并在Select的render方法中通过条件渲染来决定是否显示Select或者Form输入的数据。当Form提交后,如果当前行的key与selectedRow的key相匹配,则渲染Form输入的值而不是Select。

?好的,上述代码已经比较接近我的需求了,但还是有点差距,请实现把input的数据放入render里的record,这个要如何实现呢??
要将Form输入的数据放入render里的record中,需要在handleModalOk函数中更新record的值。以下是修改后的代码:

// ...(上面的代码保持不变)

const MyTable = () => {
  const [modalVisible, setModalVisible] = useState(false);
  const [selectedRow, setSelectedRow] = useState(null);
  const [dataSource, setDataSource] = useState([]);
  const [formData, setFormData] = useState(null);

  const handleSelectChange = (value, row) => {
    if (value === 'param') {
      setModalVisible(true);
      setSelectedRow(row);
    }
  };

  const handleModalOk = (values) => {
    setFormData(values);
    const newData = dataSource.map((item) => {
      if (item.key === selectedRow.key) {
        return {
          ...item,
          select: values.value, // replace select with form input
        };
      }
      return item;
    });
    setDataSource(newData);
    setModalVisible(false);
  };

  const columns = [
    // other columns
    {
      title: 'Select',
      dataIndex: 'select',
      render: (text, record) => {
        if (formData && selectedRow.key === record.key) {
          return formData.value; // render form input value if form is submitted
        }
        return (
          <Select defaultValue="value" style={{ width: 120 }} onChange={(value) => handleSelectChange(value, record)}>
            <Option value="value">Value</Option>
            <Option value="param">Param</Option>
          </Select>
        );
      },
    },
  ];

  // Initialize dataSource with initial data
  useEffect(() => {
    // Fetch initial data and set it to dataSource
    // Example:
    // const initialData = fetchInitialData();
    // setDataSource(initialData);
  }, []);

  return (
    <div>
      <Table columns={columns} dataSource={dataSource} />
      <Modal
        title="Input Value/Param"
        visible={modalVisible}
        onOk={handleModalOk}
        onCancel={() => setModalVisible(false)}
      >
        <Form
          name="inputForm"
          onFinish={handleModalOk}
        >
          <Form.Item
            label="Value/Param"
            name="value"
            rules={[{ required: true, message: 'Please input value or param!' }]}
          >
            <Input />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
};

export default MyTable;

在上述代码中,我们使用map方法遍历dataSource,当找到与selectedRow对应的item时,更新其select值为Form输入的数据。这样就实现了将Form输入的数据放入render里的record中。同时,使用useEffect来初始化dataSource的值,可以根据实际情况从后端获取初始数据并设置到dataSource中。

?以上还是没有实现“把form中的输入数据放进record中”,你那是把它放进formdata了?
抱歉,我理解错了您的需求。要将Form输入的数据放入render里的record中,我们需要在handleModalOk函数中更新record的值,并将Form输入的数据直接放入record中。以下是修改后的代码:

// ...(上面的代码保持不变)

const MyTable = () => {
  const [modalVisible, setModalVisible] = useState(false);
  const [selectedRow, setSelectedRow] = useState(null);
  const [dataSource, setDataSource] = useState([]);

  const handleSelectChange = (value, row) => {
    if (value === 'param') {
      setModalVisible(true);
      setSelectedRow(row);
    }
  };

  const handleModalOk = (values) => {
    const newData = dataSource.map((item) => {
      if (item.key === selectedRow.key) {
        return {
          ...item,
          select: values.value, // update select value with form input
        };
      }
      return item;
    });
    setDataSource(newData);
    setModalVisible(false);
  };

  const columns = [
    // other columns
    {
      title: 'Select',
      dataIndex: 'select',
      render: (text, record) => {
        return record.select ? record.select : (
          <Select defaultValue="value" style={{ width: 120 }} onChange={(value) => handleSelectChange(value, record)}>
            <Option value="value">Value</Option>
            <Option value="param">Param</Option>
          </Select>
        );
      },
    },
  ];

  // Initialize dataSource with initial data
  useEffect(() => {
    // Fetch initial data and set it to dataSource
    // Example:
    // const initialData = fetchInitialData();
    // setDataSource(initialData);
  }, []);

  return (
    <div>
      <Table columns={columns} dataSource={dataSource} />
      <Modal
        title="Input Value/Param"
        visible={modalVisible}
        onOk={handleModalOk}
        onCancel={() => setModalVisible(false)}
      >
        <Form
          name="inputForm"
          onFinish={handleModalOk}
        >
          <Form.Item
            label="Value/Param"
            name="value"
            rules={[{ required: true, message: 'Please input value or param!' }]}
          >
            <Input />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
};

export default MyTable;

在上述代码中,我们在handleModalOk函数中直接更新record的select值,将Form输入的数据放入record中。这样就实现了将Form输入的数据放入render里的record中。

?上述你提供的所有代码中(包括我之前问的其他问题对应的回答),是否存在同一个Bug:首先Table数据肯定是多行的,假设我在第一行触发了Select,并提交了Form数据重新渲染了Select,以上是OK的。问题在于当触发第二行的Select时,第一行被重新渲染成了Select,原本第一行保存的Form数据被渲染到第二行Select所在的单元格了。
请判断是否有这个Bug,分析原因并提供妥善的解决方法。?

是的,您提到的问题是存在的。这是因为在处理Modal的显示和隐藏时,我们使用了全局的selectedRow状态来保存当前选中的行,而这个状态是全局共享的,会导致在处理第二行的Select时,第一行的selectedRow也会被更新,从而导致数据混乱。
为了解决这个问题,我们可以将selectedRow状态改为局部状态,使其与每一行的Select和Modal独立。同时,我们还需要在Modal关闭时,清空selectedRow状态,以确保每次打开Modal时都是针对当前行的操作。
以下是修改后的代码:

// ...(其他部分保持不变)

const MyTable = () => {
  const [modalVisible, setModalVisible] = useState(false);
  const [formData, setFormData] = useState(null); // 用于保存Form数据
  const [dataSource, setDataSource] = useState([]);

  const handleSelectChange = (value, record) => {
    if (value === 'param') {
      setModalVisible(true);
      setFormData({ record }); // 设置Form数据的同时保存当前行的信息
    }
  };

  const handleModalOk = (values) => {
    const newData = dataSource.map((item) => {
      if (item.key === formData.record.key) {
        return {
          ...item,
          select: values.value, // 更新当前行的select值
        };
      }
      return item;
    });
    setDataSource(newData);
    setModalVisible(false);
    setFormData(null); // 清空Form数据
  };

  const columns = [
    // other columns
    {
      title: 'Select',
      dataIndex: 'select',
      render: (text, record) => {
        if (formData && formData.record.key === record.key) {
          return formData.value; // 渲染Form输入的值
        }
        return (
          <Select defaultValue="value" style={{ width: 120 }} onChange={(value) => handleSelectChange(value, record)}>
            <Option value="value">Value</Option>
            <Option value="param">Param</Option>
          </Select>
        );
      },
    },
  ];

  // ...(其他部分保持不变)
};

export default MyTable;

在上述代码中,我们将selectedRow状态改为formData状态,并且在Modal关闭时清空formData状态,以确保每次打开Modal时都是针对当前行的操作。这样就解决了数据混乱的问题。

?问:上述代码还有Bug吗?帮我检查一下?
经过检查,上述代码中存在一个潜在的问题。在handleSelectChange函数中,我们使用了formData来保存当前行的信息,但是在Modal关闭后,我们没有清空formData状态。这可能会导致formData中仍然保存着之前选中的行的信息,从而影响下一次的操作。

为了解决这个问题,我们需要在Modal关闭时,显式地清空formData状态。以下是修改后的代码:

// ...(其他部分保持不变)

const MyTable = () => {
  const [modalVisible, setModalVisible] = useState(false);
  const [formData, setFormData] = useState(null); // 用于保存Form数据
  const [dataSource, setDataSource] = useState([]);

  // ...(其他部分保持不变)

  const handleModalOk = (values) => {
    const newData = dataSource.map((item) => {
      if (item.key === formData.record.key) {
        return {
          ...item,
          select: values.value, // 更新当前行的select值
        };
      }
      return item;
    });
    setDataSource(newData);
    setModalVisible(false);
    setFormData(null); // 清空Form数据
  };

  return (
    <div>
      <Table columns={columns} dataSource={dataSource} />
      <Modal
        title="Input Value/Param"
        visible={modalVisible}
        onOk={handleModalOk}
        onCancel={() => {
          setModalVisible(false);
          setFormData(null); // 清空Form数据
        }}
      >
        <Form
          name="inputForm"
          onFinish={handleModalOk}
        >
          <Form.Item
            label="Value/Param"
            name="value"
            rules={[{ required: true, message: 'Please input value or param!' }]}
          >
            <Input />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
};

export default MyTable;

在上述代码中,我们在Modal的onCancel回调中,添加了对formData状态的显式清空操作,以确保每次关闭Modal时都清空formData状态。这样就解决了潜在的问题。

?问:继续完善上述业务代码,
补充:现在把Form表单里设置两个form-item,对应两个input,也就是说现在需要输入至少两个input的数据,并且这些数据全部渲染在同样的位置,用’|'隔开。
那么是否要把formdata这一状态改成对象形式,请判断并提供代码。?

并且检查修改后的代码是否会出现Bug。
是的,我们可以将formData状态改成对象形式,以便保存多个表单项的数据。以下是修改后的代码:

// ...(其他部分保持不变)

const MyTable = () => {
  const [modalVisible, setModalVisible] = useState(false);
  const [formData, setFormData] = useState(null); // 用于保存Form数据
  const [dataSource, setDataSource] = useState([]);

  const handleSelectChange = (value, record) => {
    if (value === 'param') {
      setModalVisible(true);
      setFormData({ record, values: {} }); // 保存当前行的信息和表单项的数据
    }
  };

  const handleModalOk = (values) => {
    const newData = dataSource.map((item) => {
      if (item.key === formData.record.key) {
        return {
          ...item,
          select: Object.values(values).join(' | '), // 将所有表单项的数据用'|'隔开
        };
      }
      return item;
    });
    setDataSource(newData);
    setModalVisible(false);
    setFormData(null); // 清空Form数据
  };

  const columns = [
    // other columns
    {
      title: 'Select',
      dataIndex: 'select',
      render: (text, record) => {
        if (formData && formData.record.key === record.key) {
          return (
            <Form
              name="inputForm"
              initialValues={formData.values} // 将之前输入的数据作为初始值
              onFinish={handleModalOk}
            >
              <Form.Item
                label="Value"
                name="value1"
                rules={[{ required: true, message: 'Please input value!' }]}
              >
                <Input />
              </Form.Item>
              <Form.Item
                label="Param"
                name="value2"
                rules={[{ required: true, message: 'Please input param!' }]}
              >
                <Input />
              </Form.Item>
            </Form>
          );
        }
        return (
          <Select defaultValue="value" style={{ width: 120 }} onChange={(value) => handleSelectChange(value, record)}>
            <Option value="value">Value</Option>
            <Option value="param">Param</Option>
          </Select>
        );
      },
    },
  ];

  return (
    <div>
      <Table columns={columns} dataSource={dataSource} />
      <Modal
        title="Input Value/Param"
        visible={modalVisible}
        onOk={() => {
          const form = document.querySelector('#inputForm');
          form.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true }));
        }}
        onCancel={() => {
          setModalVisible(false);
          setFormData(null); // 清空Form数据
        }}
      >
        {formData && formData.record && (
          <Form
            id="inputForm"
            name="inputForm"
            initialValues={formData.values} // 将之前输入的数据作为初始值
            onFinish={handleModalOk}
          >
            <Form.Item
              label="Value"
              name="value1"
              rules={[{ required: true, message: 'Please input value!' }]}
            >
              <Input />
            </Form.Item>
            <Form.Item
              label="Param"
              name="value2"
              rules={[{ required: true, message: 'Please input param!' }]}
            >
              <Input />
            </Form.Item>
          </Form>
        )}
      </Modal>
    </div>
  );
};

export default MyTable;

在上述代码中,我们将formData状态改成了对象形式,其中包含了当前行的信息和表单项的数据。在handleSelectChange函数中,我们设置了formData状态的初始值为一个空对象,以便保存表单项的数据。在handleModalOk函数中,我们将所有表单项的数据用’|'隔开,并将其保存到当前行的select字段中。在render函数中,我们根据formData状态是否存在来渲染Select或Form组件,并将之前输入的数据作为Form的初始值。在Modal的onOk回调中,我们手动触发Form的submit事件,以便触发表单的校验和提交操作。在Modal的onCancel回调中,我们显式地清空formData状态,以确保下一次打开Modal时是针对当前行的操作。

?继续完善上述问题,现在需要在渲染form数据后衔接一个类型为text的button,button名为‘重选’,点击重选后请清空这次渲染的form数据,这一单元格重新渲染回Select初始未被选中状态。
另外,一定要清空得彻底,比如说当前单元格的数据,还有formdata中是否有数据残留。
此外,关于上述回答中“ initialValues={formData.values} // 将之前输入的数据作为初始值 ”,Form表单重新打开即Modal重新打开时是不需要初始值的,因为我刚才提到了“重选”逻辑,所以再检查一下这个问题,以及这类代码是否需要删除。?

好的,让我来完善上述代码,以满足您的需求。

首先,我们需要在Form组件后面添加一个类型为text的Button,名为“重选”,并且在点击该按钮后清空当前行的表单数据,将单元格重新渲染为Select初始未被选中状态。同时,确保清空formData中的数据残留。

另外,您提到Form表单重新打开时不需要初始值,我们需要确保在重新打开Modal时不会保留之前的输入数据。

以下是修改后的代码:

// ...(其他部分保持不变)

const MyTable = () => {
  // ...(其他部分保持不变)

  const handleModalCancel = () => {
    setModalVisible(false);
    setFormData(null); // 清空Form数据
  };

  const handleResetForm = () => {
    setFormData(null); // 清空Form数据
  };

  // ...(其他部分保持不变)

  const columns = [
    // ...(其他列保持不变)
    {
      title: 'Select',
      dataIndex: 'select',
      render: (text, record) => {
        if (formData && formData.record.key === record.key) {
          return (
            <>
              <Form
                name="inputForm"
                onFinish={handleModalOk}
              >
                {/* 表单项 */}
              </Form>
              <Button type="text" onClick={handleResetForm}>重选</Button> {/* 重选按钮 */}
            </>
          );
        }
        return (
          // ...(其他部分保持不变)
        );
      },
    },
  ];

  // ...(其他部分保持不变)

  return (
    <div>
      <Table columns={columns} dataSource={dataSource} />
      <Modal
        title="Input Value/Param"
        visible={modalVisible}
        onOk={() => {
          const form = document.querySelector('#inputForm');
          form.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true }));
        }}
        onCancel={handleModalCancel}
      >
        {formData && formData.record && (
          <Form
            id="inputForm"
            name="inputForm"
            onFinish={handleModalOk}
          >
            {/* 表单项 */}
          </Form>
        )}
      </Modal>
    </div>
  );
};

export default MyTable;

在上述代码中,我们添加了一个名为“重选”的Button,并将其放置在Form组件后面。在点击“重选”按钮时,我们调用handleResetForm函数来清空formData状态,确保单元格重新渲染为Select初始未被选中状态,并且彻底清空formData中的数据残留。
另外,我们移除了Form组件的initialValues属性,确保在Modal重新打开时不会保留之前的输入数据。

?检查上述代码有无Bug?
经过检查,我发现上述代码中有一处问题。在handleResetForm函数中,我们应该在清空formData之后,重新渲染表格,以确保单元格重新渲染为Select初始未被选中状态。另外,我们需要在Form组件中添加一个resetFields方法,以确保彻底清空表单数据。

以下是修改后的代码:

// ...(其他部分保持不变)

const MyTable = () => {
  // ...(其他部分保持不变)

  const handleModalCancel = () => {
    setModalVisible(false);
    setFormData(null); // 清空Form数据
  };

  const handleResetForm = () => {
    setFormData(null); // 清空Form数据
    formRef.current.resetFields(); // 彻底清空表单数据
    setModalVisible(true); // 重新渲染表格
  };

  // ...(其他部分保持不变)

  const formRef = useRef(null);

  const columns = [
    // ...(其他列保持不变)
    {
      title: 'Select',
      dataIndex: 'select',
      render: (text, record) => {
        if (formData && formData.record.key === record.key) {
          return (
            <>
              <Form
                name="inputForm"
                onFinish={handleModalOk}
                ref={formRef}
              >
                {/* 表单项 */}
              </Form>
              <Button type="text" onClick={handleResetForm}>重选</Button> {/* 重选按钮 */}
            </>
          );
        }
        return (
          // ...(其他部分保持不变)
        );
      },
    },
  ];

  // ...(其他部分保持不变)

  return (
    <div>
      <Table columns={columns} dataSource={dataSource} />
      <Modal
        title="Input Value/Param"
        visible={modalVisible}
        onOk={() => {
          const form = document.querySelector('#inputForm');
          form.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true }));
        }}
        onCancel={handleModalCancel}
      >
        {formData && formData.record && (
          <Form
            id="inputForm"
            name="inputForm"
            onFinish={handleModalOk}
          >
            {/* 表单项 */}
          </Form>
        )}
      </Modal>
    </div>
  );
};

export default MyTable;

在上述代码中,我们使用了useRef钩子来创建一个formRef引用,以便在handleResetForm函数中调用resetFields方法。此外,我们在handleResetForm函数中将modalVisible状态设置为true,以触发Modal重新渲染,确保单元格重新渲染为Select初始未被选中状态。

// ...(其他部分保持不变)

const MyTable = () => {
  // ...(其他部分保持不变)

  const handleModalCancel = () => {
    setModalVisible(false);
    setFormData(null); // 清空Form数据
  };

  const handleResetForm = () => {
    setFormData(null); // 清空Form数据
    setModalVisible(true); // 重新渲染表格
  };

  // ...(其他部分保持不变)

  const columns = [
    // ...(其他列保持不变)
    {
      title: 'Select',
      dataIndex: 'select',
      render: (text, record) => {
        if (formData && formData.record.key === record.key) {
          return (
            <>
              <Form
                name="inputForm"
                onFinish={handleModalOk}
                key={formData.record.key} // 添加key属性
              >
                {/* 表单项 */}
              </Form>
              <Button type="text" onClick={handleResetForm}>重选</Button> {/* 重选按钮 */}
            </>
          );
        }
        return (
          // ...(其他部分保持不变)
        );
      },
    },
  ];

  // ...(其他部分保持不变)

  return (
    <div>
      <Table columns={columns} dataSource={dataSource} />
      <Modal
        title="Input Value/Param"
        visible={modalVisible}
        onOk={() => {
          const form = document.querySelector('#inputForm');
          form.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true }));
        }}
        onCancel={handleModalCancel}
      >
        {formData && formData.record && (
          <Form
            id="inputForm"
            name="inputForm"
            onFinish={handleModalOk}
          >
            {/* 表单项 */}
          </Form>
        )}
      </Modal>
    </div>
  );
  };

export default MyTable;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值