react实现动态增减表单项

在做项目的时候,甲方给的信息有限,网页的备案信息写成固定的,如下图所示
在这里插入图片描述
之后验收的时候,甲方要求把这个备案信息写成动态的,可以自增减,就去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实现,因为每次新增的信息可能不一样,所以每次新增的时候,会先删除旧的数据,再插入。
代码如下:

// 定义结构体
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.ObjectID
	for _, 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
}

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值