修改校验逻辑

点击查看代码
const invalidRows = selectedRows
  .map(row => {
    const invalidFields = requiredFields
      .map(field => {
        const value = row[field.key];

        if (!value) {
          return `${field.label}(未填写)`;
        }

        if (field.key === 'dataOwner' && typeof value === 'string') {
          const trimmed = value.trim();
          if (/[,;;、]/.test(trimmed)) {
            return `${field.label}(只能选择一位,对接人过多)`;
          }
          const atCount = (trimmed.match(/@/g) || []).length;
          if (atCount > 1) {
            return `${field.label}(只能选择一位,对接人过多)`;
          }
        }

        return null;
      })
      .filter(Boolean);

    return invalidFields.length > 0 ? { row, invalidFields } : null;
  })
  .filter(Boolean);

组装提示
if (invalidRows.length > 0) {
  const errorMsg = invalidRows
    .map(item => {
      const { row, invalidFields } = item;
      return `台帐编号:${row.taskId} 的以下字段有问题: ${invalidFields.join('、')}`;
    })
    .join('\n\n');

  Modal.error({
    title: '存在未填写或格式错误的字段',
    content: <div style={{ maxHeight: 400, overflow: 'auto', whiteSpace: 'pre-line' }}>{errorMsg}</div>,
  });
  return reject(new Error('存在未填写或格式错误的字段'));
}



if (StringUtils.isNotBlank(detail.getDataOwner())) {
    String dataOwner = detail.getDataOwner().trim();

    // 防止手写多个邮箱(逗号、分号、中文分号、顿号、空格等)
    if (dataOwner.matches(".*[,\uFF1B;\u3001\\s].*")) {
        errorBuilder.append("Data Owner 只能选择一位!");
    } else {
        // 校验邮箱中 @ 的数量
        long atCount = dataOwner.chars().filter(c -> c == '@').count();
        if (atCount > 1) {
            errorBuilder.append("Data Owner 只能选择一位!");
        }
    }
}





你这段是 AntD v3(getFieldDecorator + AutoComplete dataSource)。如果要改成方案 A「只能从下拉选」,最小改动就是:把 AutoComplete 换成 Select showSearch(不启用 tags/combobox,就天然不能提交手输)。

下面按你截图的结构直接改:

import { Select } from "antd";
const { Option } = Select;

<Form.Item label="跟进人" style={{ width: "100%" }} {...FormItemLayout}>
  {getFieldDecorator("follower", {
    // rules: [{ required: true, message: "请选择跟进人" }],
  })(
    <Select
      showSearch
      allowClear
      style={{ width: "90%" }}
      placeholder="请选择跟进人"
      // 用显示文本(邮箱)来过滤,而不是用 value(userCode)
      optionFilterProp="children"
      filterOption={(input, option) =>
        (option.props.children || "")
          .toString()
          .toUpperCase()
          .includes(input.toUpperCase())
      }
    >
      {(AllUserInfo || []).map((user) => (
        <Option key={user.email} value={user.userCode}>
          {user.email}
        </Option>
      ))}
    </Select>
  )}
</Form.Item>

这样改完之后的行为

用户可以在框里输入关键字 只用于筛选下拉

最终只能选中某一项(表单值就是 user.userCode)

不会再出现“手输原文也能提交”的情况(除非你开 mode="tags" 或 combobox,我们没开)



---

如果你这个 AllUserInfo 是接口实时搜的(不是一次性全量),我再给你加上 onSearch + filterOption={false} 的远程搜索版。你现在是全量加载还是边输边查?
posted @ 2025-12-15 23:59  牛久安  阅读(8)  评论(0)    收藏  举报