【form校验】3.0项目多层list嵌套

news2024/12/25 14:15:59

请添加图片描述


const { required, phoneOrMobile } = CjmForm.rules;
export default function detail() {
  const { query } = getRouterInfo(location);

  const formRef = useRef(null);

  const [crumbList, setCrumbList] = useState([
    {
      url: "/wenling/Reviewer",
      name: "审核人员",
    },
    {
      name: query.type == "look" ? "查看" : "编辑",
    },
  ]);
  const [form, setForm] = useState({
    auditNodeConfig: [
      {
        nextAuditNode: "农办审批",
        userList: [
          {
            batchAudit: false,
            phone: "",
          },
        ],
      },
      {
        nextAuditNode: "农水局审批",
        userList: [
          {
            batchAudit: false,
            phone: "",
          },
        ],
      },
      {
        nextAuditNode: "同步财政局审核结果",
        userList: [
          {
            batchAudit: false,
            phone: "",
          },
        ],
      },
    ],
  });
  const [loading, setLoading] = useState(false);
  const [spinning, setSpinning] = useState(false);

  useEffect(() => {
    getConfigInfo();
  }, []);

  async function getConfigInfo() {
    setSpinning(true);
    const res = await configLook({ confId: query.confId });
    if (res.results && res.state && res.state == 200) {
      setForm(transformData(res.results));
    } else {
      if (query.processCode == "10001002") {
        setForm({
          auditNodeConfig: [
            {
              nextAuditNode: "农办审批",
              userList: [
                {
                  batchAudit: false,
                  phone: "",
                },
              ],
            },
          ],
        });
      }
    }
    setSpinning(false);
  }

  const rules = useMemo(() => {
    let newRule = {};
    form["auditNodeConfig"].forEach((item, key) => {
      item["userList"].forEach((record, recordKey) => {
        newRule[`auditNodeConfig.${key}.userList.${recordKey}.phone`] = [
          required,
          phoneOrMobile,
        ];
        newRule[`auditNodeConfig.${key}.userList.${recordKey}.userId`] = [
          required,
        ];
      });
    });
    return newRule;
  }, [form]);

  const modalForm = useMemo(() => {
    let newForm = {};
    form["auditNodeConfig"].forEach((item, key) => {
      item["userList"].forEach((record, recordKey) => {
        newForm[`auditNodeConfig.${key}.userList.${recordKey}.phone`] =
          record["phone"];
        newForm[`auditNodeConfig.${key}.userList.${recordKey}.userId`] =
          record["userId"];
      });
    });
    return newForm;
  }, [form]);

  const getValue = (eventOrvalue) => {
    const type = typeof eventOrvalue;
    if (
      type === "object" &&
      eventOrvalue !== null &&
      eventOrvalue.target &&
      eventOrvalue.target.value
    ) {
      return eventOrvalue.target.value;
    }
    return eventOrvalue;
  };

  const setFormData = (fieldName, index, recordKey) => {
    return (eventOrvalue) => {
      let value = getValue(eventOrvalue);
      if (fieldName == "batchAudit") {
        value = eventOrvalue.target.checked;
      }
      form["auditNodeConfig"][index]["userList"][recordKey][fieldName] = value;
      setForm(Object.assign({}, form));
    };
  };

  const addHandle = (index) => {
    const listLen = get(form, `auditNodeConfig[${index}].userList`, []).length;
    if (listLen >= 4) {
      Message.warning("最多添加4个审批人员!");
    } else {
      form["auditNodeConfig"][index]["userList"].push({
        batchAudit: false,
        phone: "",
      });
      setForm(Object.assign({}, form));
    }
  };

  const saveHandle = async () => {
    setLoading(true);
    const valid = await formRef.current.validate();
    if (valid) {
      let data = { ...form };
      data["confId"] = query.confId;
      data["processCode"] = query.processCode;
      const res = await configEdit(transformTree(data));
      if (res.state && res.state == 200) {
        Message.success("操作成功");
        historyBack();
      } else {
        Message.error("操作失败,请重试!");
      }
    }
    setLoading(false);
  };

  const delHandle = (index, recordKey) => {
    form["auditNodeConfig"][index]["userList"].splice(recordKey, 1);
    setForm(Object.assign({}, form));
  };

  return (
    <div className={styles.reviewerBox}>
      <Spin spinning={spinning}>
        <CrumbBar list={crumbList} />
        <CjmForm
          labelWidth="180px"
          ref={formRef}
          model={modalForm}
          rules={rules}
        >
          <CjmForm.Item label="审批类型:">
            <CjmInput
              value={query.processName}
              disabled={true}
              style={{ width: "380px" }}
            />
          </CjmForm.Item>
          {form &&
            form.auditNodeConfig.map((item, index) => {
              return (
                <div className={styles.auditItem} key={index}>
                  <h2 style={{ marginLeft: "24px" }}>
                    {item["nextAuditNode"]}
                  </h2>
                  {item["userList"] &&
                    item["userList"].map((record, recordKey) => {
                      return (
                        <div key={recordKey} className={styles.formItem}>
                          <CjmForm.Item
                            label="审批人名称:"
                            prop={`auditNodeConfig.${index}.userList.${recordKey}.userId`}
                          >
                            <RemoteSelect
                              style={{ width: "380px" }}
                              disabled={query.type == "look" ? true : false}
                              labelKey="userName"
                              valueKey="userId"
                              value={record.userId}
                              label={record.userName}
                              remoteUrl={`${api.reviewer.departmentId}?departmentId=${query.optDeptId}&disableFlag=1`}
                              onChange={{
                                userName: setFormData(
                                  "userName",
                                  index,
                                  recordKey
                                ),
                                userId: setFormData("userId", index, recordKey),
                                departmentId: setFormData(
                                  "deptId",
                                  index,
                                  recordKey
                                ),
                                mobileId: setFormData(
                                  "phone",
                                  index,
                                  recordKey
                                ),
                              }}
                            />
                          </CjmForm.Item>
                          <CjmForm.Item
                            label="审批人手机号:"
                            prop={`auditNodeConfig.${index}.userList.${recordKey}.phone`}
                          >
                            <CjmInput
                              disabled={query.type == "look" ? true : false}
                              style={{ width: "380px" }}
                              value={record.phone}
                              onChange={setFormData("phone", index, recordKey)}
                            />
                          </CjmForm.Item>
                          <CjmForm.Item label="审批操作:" prop="batchAudit">
                            <Checkbox
                              disabled={query.type == "look" ? true : false}
                              checked={record.batchAudit}
                              onChange={setFormData(
                                "batchAudit",
                                index,
                                recordKey
                              )}
                            >
                              批量通过
                            </Checkbox>
                            <span style={{ marginLeft: "24px" }}>
                              默认单个审核,设置批量审核后允许该节点可批量审核
                            </span>
                          </CjmForm.Item>
                          <Divider className={styles.line} />
                          {recordKey != 0 && (
                            <img
                              className={styles.close}
                              src={deleteImg}
                              onClick={() => delHandle(index, recordKey)}
                            />
                          )}
                        </div>
                      );
                    })}
                  {query.type !== "look" && index == 0 && (
                    <Button
                      type="primary"
                      style={{ marginLeft: "224px" }}
                      onClick={() => addHandle(index)}
                    >
                      +新增(最多添加4个审批人员)
                    </Button>
                  )}
                </div>
              );
            })}
        </CjmForm>
        <Button className={styles.btnLeave} onClick={() => historyBack()}>
          返回
        </Button>
        {query.type !== "look" && (
          <Button
            type="primary"
            className={styles.btnSave}
            loading={loading}
            onClick={saveHandle}
          >
            保存
          </Button>
        )}
      </Spin>
    </div>
  );
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1180525.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Cesium 展示——将每个点和点所在线段进行关联

文章目录 需求分析1. 数据结构2. 点线绘制3. ID获取4. 进行关联需求 点的集合和线的集合已知,现需将每个点和每个点所在的关联的线进行关联起来 输入 输出 分析 1. 数据结构 l

Mac平台文件传输工具Transmit 5

Transmit 是一款由Panic开发的文件传输软件&#xff0c;它可以帮助用户在不同的服务器间进行文件传输。Transmit 支持多种协议&#xff0c;包括FTP、SFTP、WebDAV等&#xff0c;同时它也内置了一个强大的文件管理器&#xff0c;可以方便地对文件进行管理和操作。 Transmit 的界…

分享86个节日庆典PPT,总有一款适合您

分享86个节日庆典PPT&#xff0c;总有一款适合您 链接&#xff1a;https://pan.baidu.com/s/1oE2LIr6en4js9L0fzUyqgw?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整理更不易。知识付费甚欢…

web —— css(1)

Web —— css基础 1. CSS样式表2. CSS的三种引入方式3. CSS 语法4. CSS 选择器4.1 元素选择器4.2 类选择器4.3 ID选择器4.4 属性选择器4.5 后代选择器4.6 子元素选择器4.7 伪类选择器4.8 分组选择器 5. 颜色和字体6. 显示方式display7. 盒子模型7.1 盒子模型 - 外边距塌陷7.2 盒…

Java之SpringCloud Alibaba【八】【Spring Cloud微服务Gateway整合sentinel限流】

一、Gateway整合sentinel限流 网关作为内部系统外的一层屏障,对内起到-定的保护作用&#xff0c;限流便是其中之- - .网关层的限流可以简单地针对不同路由进行限流,也可针对业务的接口进行限流,或者根据接口的特征分组限流。 1、添加依赖 <dependency><groupId>c…

串口中断(9)即时解析用户自定义通讯协议--接收数据固定情况

本文为博主 日月同辉&#xff0c;与我共生&#xff0c;csdn原创首发。希望看完后能对你有所帮助&#xff0c;不足之处请指正&#xff01;一起交流学习&#xff0c;共同进步&#xff01; > 发布人&#xff1a;日月同辉,与我共生_单片机-CSDN博客 > 欢迎你为独创博主日月同…

共享WiFi贴项目可以带来哪些优势?

当谈到共享WiFi贴的推广时&#xff0c;我们不禁要问&#xff1a;这项新兴的服务项目究竟给我们带来了哪些便利&#xff1f;在这篇文章中&#xff0c;我们将探讨共享WiFi贴推广所带来的益处以及其未来潜力。 共享WiFi贴的推广为人们提供了更加快捷的网络接入方式。无论是商场、餐…

远程运维用什么软件?可以保障更安全?

远程运维顾名思义就是通过远程的方式IT设备等运行、维护。远程运维适用场景包含因疫情居家办公&#xff0c;包含放假期间出现运维故障远程解决&#xff0c;包含项目太远需要远程操作等等。但远程运维过程存在一定风险&#xff0c;安全性无法保障&#xff0c;所以一定要选择靠谱…

项目构建工具maven的基本配置+idea 中配置 maven

&#x1f451; 博主简介&#xff1a;知名开发工程师 &#x1f463; 出没地点&#xff1a;北京 &#x1f48a; 2023年目标&#xff1a;成为一个大佬 ——————————————————————————————————————————— 版权声明&#xff1a;本文为原创文…

hp惠普星15青春版笔记本15s-dr2000/15s-du2000原厂Windows11家庭中文版OEM预装系统

适用型号&#xff1a; 15s-dr2002tx&#xff0c;15s-dr2003tx&#xff0c;15s-dr2004tx&#xff0c;15s-dr2005tx&#xff0c;15s-dr2006tx&#xff0c;15s-dr2016TU&#xff0c;15s-dr2017TU&#xff0c;15s-dr2020TU 15s-du2003tx&#xff0c;15s-du2004tx&#xff0c;15s-…

微信小程序(非个人)备案指南

一、小程序备案法律法规参考 1、《中华人民共和国反电信网络诈骗法》 第二十三条 设立移动互联网应用程序应当按照国家有关规定向电信主管部门办理许可或者备案手续。 2、《互联网信息服务管理办法》 第四条 国家对经营性互联网信息服务实行许可制度&#xff1b;对非经营性互…

多维时序 | MATLAB实现TCN-selfAttention自注意力机制结合时间卷积神经网络多变量时间序列预测

多维时序 | MATLAB实现TCN-selfAttention自注意力机制结合时间卷积神经网络多变量时间序列预测 目录 多维时序 | MATLAB实现TCN-selfAttention自注意力机制结合时间卷积神经网络多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现TCN-s…

python自动化测试(2)-自动化基本技术原理

1 概述 在之前的文章里面提到过&#xff1a;做自动化的首要本领就是要会 透过现象看本质 &#xff0c;落实到实际的IT工作中就是 透过界面看数据。 掌握上面的这样的本领可不是容易的事情&#xff0c;必须要有扎实的计算机理论基础&#xff0c;才能看到深层次的本质东西。 …

零代码编程:用ChatGPT批量删除文件名的字符

文件夹里面的文件标题如下&#xff0c;后面都带有一个网址&#xff0c;怎么批量删除掉呢&#xff1f; 这样让ChatGPT编写一段Python代码&#xff1a; 你是一个Python编程专家&#xff0c;要完成一个处理批量删除文件名中字符的任务&#xff0c;具体步骤如下&#xff1a; 打开…

GO语言数据抓取代码示例

安装Go语言的net/http和io/ioutil包&#xff0c;这两个包是爬虫程序的基础。你可以使用下面的命令来安装&#xff1a; bash go get -u github.com/golang.org/x/net/http2 go get -u golang.org/x/net/html 然后&#xff0c;你可以使用下面的代码来获取爬虫信息&#xff1a; …

第一个ARM程序裸板点灯

硬件知识LED原理图 如何点亮一个LED灯&#xff1f; 看原理图&#xff0c;确定控制LED的引脚。看主芯片的芯片手册&#xff0c;确定如何设置控制这个引脚。写程序。 LED有插脚封装的、贴片封装的。 它们长得完全不一样&#xff0c;因此我们在原理图中把它们抽象出来。 点亮…

ESXi配置两个不同网段虚拟机互通

ESXi配置两个不同网段虚拟机互通 拓扑图&#xff1a; 步骤 在ESXi上新建一个虚拟交换机新建两个端口组&#xff0c;VLAN ID分别为30和31&#xff0c;添加到新建的虚拟交换机上创建两个虚拟机&#xff0c;网络适配器分别使用新建的端口组30和31对新建的虚拟机配置IP在物理交换…

论文阅读:LOGO-Former: Local-Global Spatio-Temporal Transformer for DFER(ICASSP2023)

文章目录 摘要动机与贡献具体方法整体架构输入嵌入生成LOGO-Former多头局部注意力多头全局注意力 紧凑损失正则化 实验思考总结 本篇论文 LOGO-Former: Local-Global Spatio-Temporal Transformer for Dynamic Facial Expression Recognition发表在ICASSP&#xff08;声学顶会…

369B1860G0028 44A730240-G01 IC697ACC722B

369B1860G0028 44A730240-G01 IC697ACC722B 在NOA&#xff0c;一个名为MO(监控和优化)的独立领域与现有系统分开准备&#xff0c;数据直接从机器人、无人机和新传感器收集&#xff0c;例如腐蚀、声音和振动传感器。此外&#xff0c;现有系统中的数据通过OPC UA导入&#xff0c…

实现前后端分离开发:构建现代化Web应用

文章目录 什么是前后端分离开发&#xff1f;为什么要采用前后端分离开发&#xff1f;前后端分离的最佳实践1. 定义API2. 使用RESTful风格3. 选择适当的前端框架4. 选择合适的后端技术5. 数据交互格式6. 前端路由7. 自动化构建和部署8. 跨域问题 示例&#xff1a;前后端分离开发…