react实现动态增减表单项

ops/2024/9/23 6:30:38/

在做项目的时候,甲方给的信息有限,网页的备案信息写成固定的,如下图所示
在这里插入图片描述
之后验收的时候,甲方要求把这个备案信息写成动态的,可以自增减,就去react组件库看看有没有具体的实现,果真有,具体实现如下:

import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { Button, Form, Input, Card, Space, message} from 'antd';
import CustomForm from '@/components/Form';
import { FormattedMessage, useIntl } from 'umi';
import { saveRecordInfomation, getRecordInfomation } from '@/services/record'
import { useEffect } from 'react';
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';const formItemLayout = {labelCol: {xs: {span: 24,},sm: {span: 6,},},wrapperCol: {xs: {span: 24,},sm: {span: 14,},},
};const RecordInformation = () => {const intl = useIntl()const [form] = Form.useForm();const onReset = () => {form.resetFields();};useEffect(() => {getRecordInfo()return () => { };}, []);const getRecordInfo = async () => {getRecordInfomation().then((res) => {if (res.code === 0) {form.setFieldsValue({recordsInformation: res.data.map((item, index) => ({...item,key: index,})),});}});}const onFinish = async (forms) => {const res = await saveRecordInfomation(forms.recordsInformation)if (res.code === 0) {message.success(intl.formatMessage({ id: 'pages.cms.save.success' }))getRecordInfo()} else {message.error(intl.formatMessage({ id: 'pages.cms.save.fail' }))}}return (<PageHeaderWrapper ghost={false}><div><Card style={{ height: '95%', }}><Form{...formItemLayout}variant="filled"style={{maxWidth: 1000,}}form={form}onFinish={onFinish}><Form.List name="recordsInformation">{(fields, { add, remove }) => (<>{fields.map(({ key, name, ...restField }) => (<Space key={key} style={{ display: 'flex', marginBottom: 8, marginRight: 0, }} align="baseline" ><Form.Item{...restField}name={[name, 'label']}rules={[{ required: true, message: 'Missing first name' }]}><Input placeholder={intl.formatMessage({ id: 'pages.record.info.content.public.net.example.filing'})} style={{ width:105,  textAlign: 'right', border:'none' }} /></Form.Item><Form.Item{...restField}name={[name, 'value']}rules={[{ required: true, message: 'Missing last name' }]}><Input placeholder={intl.formatMessage({ id: 'pages.record.info.content.public.net.example.filing.url'})} style={{ width:300,  }}/></Form.Item><MinusCircleOutlined onClick={() => remove(name)} /></Space>))}<Form.Item ><Button style={{width: 405}} type="dashed" onClick={() => add()} block icon={<PlusOutlined />}><FormattedMessage id='pages.record.info.content.add' /></Button></Form.Item></>)}</Form.List><Form.Item><Space><Button type="primary" htmlType="submit"><FormattedMessage id='pages.save' /></Button></Space></Form.Item></Form></Card></div></PageHeaderWrapper>);
};export default RecordInformation;
// record.js文件
import { request } from 'umi';
import { formatReqUrl } from '../../common';export async function saveRecordInfomation(data) {console.log(data)return request('/beian',{method:'POST', data: data});
}export async function getRecordInfomation() {return request('/beian',{method:'GET'});
}

前端向后端传送的是一个对象数组,也就是这种格式:[{label: ‘xxx’, value: ‘xxx’}]
后端用Go实现,因为每次新增的信息可能不一样,所以每次新增的时候,会先删除旧的数据,再插入。
代码如下:

go">// 定义结构体
type Beian struct {Label        string `bson:"label" json:"label"`Value        string `bson:"value" json:"value"`DefaultField `bson:",inline"`
}// controller
func (ctl *BeianController) Post(c *gin.Context) resp.JSON {c.Set("log-opt", "创建beian")doc := []models.Beian{}if err := c.ShouldBind(&doc); err != nil {return resp.Error(http.StatusBadRequest, gin.H{}, err)}c.Set("log-content", models.Doc2string(doc))id, err := ctl.srv.Insert(doc)if err != nil {return resp.Error(http.StatusInternalServerError, gin.H{}, err)}return resp.Success(gin.H{"id": id})
}//service
func (i *BeianServiceImpl) Insert(doc []models.Beian) (primitive.ObjectID, error) {ctx := context.Background()// 先删除_, err := i.m.DB.Collection(BeianColl).RemoveAll(ctx, bson.M{})if err != nil {return primitive.NilObjectID, err}// 再保存var insertedID primitive.ObjectIDfor _, info := range doc {result, err := i.m.DB.Collection(BeianColl).InsertOne(ctx, &info)if err != nil {return primitive.NilObjectID, err}if insertedID.IsZero() {insertedID = result.InsertedID.(primitive.ObjectID)}}return insertedID, nil
}

最终效果图如下:
在这里插入图片描述


http://www.ppmy.cn/ops/43907.html

相关文章

k8s devops实战教程+生产实践+可就业

k8s devops实战教程 简介教程涉及到内容教程获取学习教程后的收货助学群 简介 越来越多的企业应用云原生化&#xff0c;催生很多应用的部署方式也发生了很多变化。 从物理机部署应用过度到虚机部署应用再到应用容器化&#xff0c;从单应用再到服务拆分为微服务&#xff0c;靠人…

Linux-线程池

文章目录 前言一、线程池是什么&#xff1f;二、示例代码 前言 线程池主要是对之前内容的一个巩固&#xff0c;并且初步了解池化概念。 一、线程池是什么&#xff1f; 线程池就是提前开辟好一块空间&#xff0c;随时准备创造新线程来完成任务&#xff0c;可以理解为用空间来换…

python纯脚本搬砖DNF之深度学习,工作室适用

声明&#xff1a; 本文章仅作学习交流使用,对产生的任何影响&#xff0c;本人概不负责. 转载请注明出处:https://editor.csdn.net/md?articleId103674748 主要功能 脚本已初步完成&#xff0c;可以上机实战了 1.搬砖研究所、海伯伦&#xff08;持续更新中&#xff09; 2.自…

聚数力 以数兴 | 与“闽”同行,共话数字未来

闽江之畔&#xff0c;数智腾飞。5月24日&#xff0c;第七届数字中国建设峰会在海峡国际会展中心盛大举办。本届展会的主题是“释放数据要素价值&#xff0c;发展新质生产力”&#xff0c;由国家发展改革委、国家数据局、福建省人民政府等单位共同主办&#xff0c;福州市人民政府…

Python文件中动态导入多个.py文件

Python文件中动态导入多个.py文件 一、背景 在一些自动化脚本中,我们需要一些中间文件作为引用文件来处理一些自动化的工作,但是中间文件数量可能根据需求的变更发生不规律的变化,所以就需要一些读文件夹来自动获取这些需要引用的中间文件,下面就是我整理的一个能够实现动…

Hadoop学习之hdfs的操作

Hadoop学习之hdfs的操作 1.将HDFS中的文件复制到本地 package com.shujia.hdfs;import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.junit.After; import org.junit.Before; import org.j…

算法刷题笔记 高精度加法(C++实现)

文章目录 题目描述题目思路和代码 题目描述 给定两个正整数&#xff08;不含前导0&#xff09;&#xff0c;计算它们的和。 输入格式 共两行&#xff0c;每行包含一个整数。 输出格式 共一行&#xff0c;包含所求的和。 题目思路和代码 基本思路&#xff1a;模拟竖式计算…

C++复习笔记2

1&#xff0c;构造函数 1.1 实例 1.2 概念 防止忘记初始化&#xff0c;专门给类对象初始化 1.3 备注 2&#xff0c;析造函数 2.1 实例 2.2 概念 防止忘记销毁&#xff0c;专门销毁类对象 2.3 备注 3&#xff0c;默认构造函数 3.1 实例 3.2 概念 编译器自动生成的构造…