猪齿鱼 table表单编辑

一、需求

1、table字段可编辑/查看。提交时校验整个table数据是否都填写。

2、授权列表中的数据。添加授权的数据,产品授权类别必须是唯一,不可重复。

3、【上游渠道】根据产品授权类别来。如果【产品授权类别】未选择,提示:请先选择【产品授权类别】。

4、【挂靠区域】跟据【上游渠道】下的授权区域字段显示。挂靠授权区域下的options也是根据【上游渠道】下的授权区域字段来。

二、效果图

三、代码实现

(1)html代码

javascript 复制代码
import React, {
  forwardRef,
  useEffect,
  useImperativeHandle,
  useMemo,
  useRef,
  useState,
} from "react";
import DataSet from "choerodon-ui/dataset";
import {
  Button,
  Icon,
  message,
  NumberField,
  Select,
  Table,
  TextField,
  Tooltip,
} from "choerodon-ui/pro";
import {
  COMMON_DELETE,
  COMMON_DELETE_TIPS,
  languageConfig,
  STATUS_NO,
  STATUS_YES,
  TABLE_COLUMN_OPERATION,
} from "@/language/language";
import { Popconfirm } from "choerodon-ui";
import { ButtonColor, FuncType } from "choerodon-ui/pro/lib/button/enum";
import { ColumnLock, SelectionMode } from "choerodon-ui/pro/lib/table/enum";
import { queryMapIdpValue } from "services/api";
import { StatusItems } from "@/interface";
import Title from "@/components/Title";
import TableEmpty from "@/components/TableEmpty";
import { renderIconCopy, renderSerialNumber, renderSplitTips } from "@/public";
import { DetailItems } from "@/interface/affiliationApplication";
import commonStyles from "@/assets/styles/global.less";
import { getCityOptions, handleCopy } from "@/public/store";
import { getFormalAuthChannelPageListApi } from "@/api/affiliationApplication";
import styles from "../../main.less";
import { tableList } from "./store";
import { useApplySelectChannelModal } from "./components/SelectChannel/main";

interface ApplyInfoProps {
  detailInfo: DetailItems;
  type: string;
}

interface Item {
  productAuthCategoryId: string;
  id: string;
}

const ApplyInfo = forwardRef(({ detailInfo, type }: ApplyInfoProps, ref) => {
  const { zoneCode, channelFormalAuthCategoryVOList } = detailInfo || {};

  // 上游渠道:弹框
  const { open } = useApplySelectChannelModal({
    onChannelSelect: (val) => handleAddChannelSelect(val),
  });

  const [show, setShow] = useState<boolean>(true); // 管理收缩状态

  const [selectOptions, setSelectOptions] = useState<{
    descList: StatusItems[]; // 获取提示文案:值集
    limitList: StatusItems[]; // 获取注册上限:值集
  }>({ descList: [], limitList: [] });

  useImperativeHandle(ref, () => ({
    getValues: () => {
      return {
        tableList: tableDs.toData(),
      };
    },
    validate: async () => {
      // const allValid = await tableDs.current?.validate(true);
      // return allValid;

      const tablePromises = tableDs.map((ds) => ds?.validate(true));
      const results = await Promise.all(tablePromises);
      const allValid = results.every((valid) => valid);
      return allValid;
    },
  }));

  /** 【获取】值集:'提示文案'、'注册上限' */
  useEffect(() => {
    const fetchCertOptions = async () => {
      const res = await queryMapIdpValue([
        "PRM_CA_APPLY_REASON",
        "PRM_CA_REGISTRATION_LIMIT",
      ]);
      setSelectOptions({ descList: res?.[0] || [], limitList: res?.[1] || [] });
    };
    fetchCertOptions();
  }, []);

  useEffect(() => {
    if (detailInfo) {
      const { itemVOList } = detailInfo || {};

      if (itemVOList && itemVOList.length > 0) {
        tableDs.loadData(itemVOList);
      }
    }
  }, [detailInfo]);

  /** 【渲染】提示文案 */
  const tipsRef = useRef<HTMLDivElement | null>(null);
  const handleCopy = async (tips) => {
    if (tips) {
      // 获取div内的所有文本内容
      const textToCopy = tips.textContent || tips.innerText;

      if (textToCopy && copy(textToCopy)) {
        message.success(
          languageConfig("common.copy.success", "复制成功!"),
          undefined,
          undefined,
          "top"
        );
      } else {
        message.error(
          languageConfig("common.copy.failed", "复制失败"),
          undefined,
          undefined,
          "top"
        );
      }
    }
  };
  const renderTips = useMemo(() => {
    const { affiliationType } = detailInfo || {};
    const data = selectOptions?.descList.find(
      (item) => item.value === affiliationType
    );

    return (
      <div>
        <div
          className={styles.affiliationApplicationDetail_copy}
          onClick={() => handleCopy(tipsRef.current)}
        >
          {renderIconCopy()}
        </div>

        <div ref={tipsRef}>
          <div>{data?.meaning}</div>
          {renderSplitTips(data?.description)}
        </div>
      </div>
    );
  }, [selectOptions, detailInfo]);

  /** 【渲染】注册上限 */
  const renderLimit = useMemo(() => {
    const { affiliationType } = detailInfo || {};
    const data = selectOptions?.limitList.find(
      (item) => item.value === affiliationType
    );

    return data?.tag;
  }, [selectOptions, detailInfo]);

  /** 【过滤】产品授权类别 */
  const handleOptionFilter = (item) => {
    // 1、合并现有数据源
    const existingData = [
      ...(channelFormalAuthCategoryVOList || []), // 已有正式授权:列表
      ...(tableDs?.toData() || []), // 申请挂靠信息
    ] as Item[];

    // 2、提取有效的授权ID
    const existingIds = existingData
      .filter(
        (item) =>
          item?.productAuthCategoryId != null &&
          item.productAuthCategoryId !== ""
      )
      .map((item) => String(item.productAuthCategoryId));

    // 3、添加'通用大包/1',
    const allIds = [...existingIds, "1"];

    return !allIds.includes(item.get("id"));
  };

  const tableDs = useMemo(() => new DataSet(tableList(zoneCode)), []);
  const columns: any = useMemo(() => {
    /** 操作列配置 */
    const operationColumn = {
      header: TABLE_COLUMN_OPERATION(),
      lock: ColumnLock.right,
      width: 130,
      command: ({ record }) => {
        const { changeType } = record.toData();
        return [
          <Popconfirm
            key="delete"
            title={COMMON_DELETE_TIPS()}
            okText={STATUS_YES()}
            cancelText={STATUS_NO()}
            onConfirm={() => {
              handleDelete(record);
            }}
          >
            <Button funcType={FuncType.link} color={ButtonColor.red}>
              <span style={{ marginTop: "-2px" }}>{COMMON_DELETE()}</span>
            </Button>
          </Popconfirm>,
        ];
      },
    };

    /** 基础配置 */
    const baseColumns = [
      ...renderSerialNumber(false),
      {
        name: "productAuthCategoryId",
        renderer: ({ value, record }) => {
          if (type === "edit") {
            return (
              <Select
                record={record}
                name="productAuthCategoryId"
                optionsFilter={(record) => handleOptionFilter(record)}
                onChange={() => handleSelectCategory(record)}
                style={{ width: "100%" }}
              />
            );
          }

          if (!value) return;

          const data = record
            ?.getField("productAuthCategoryId")
            ?.options?.toData();
          const { authCategoryName } =
            data?.find((item) => item.id == value) || {};
          return authCategoryName;
        },
      },
      {
        name: "upstreamChannelName",
        renderer: ({ value, record }) => {
          return type === "edit" ? (
            <TextField
              record={record}
              name="upstreamChannelName"
              addonAfter={
                <div
                  style={{ padding: "0px" }}
                  onClick={() => handleSelectChannel(record)}
                >
                  <Icon type="LOV-o" />
                </div>
              }
              onClick={() => handleSelectChannel(record)}
              style={{ width: "100%" }}
            />
          ) : (
            value
          );
        },
      },
      {
        name: "provinceCode",
        renderer: ({ value, record }) => {
          const index = tableDs.indexOf(record); // 获取当前行的索引

          if (type === "edit") {
            return (
              <Select
                record={record}
                name="provinceCode"
                multiple={true}
                // maxTagCount={3} //多值标签最大数量
                // maxTagTextLength={8} //多值标签文案最大长度
                onClick={() => handleProvinceClick(record)}
                onChange={() => handleProvinceChange(record)}
                style={{ width: "100%" }}
              />
            );
          }

          if (!value) return;

          const data = record?.getField("provinceCode")?.options?.toData();
          const result = data.reduce((acc, item) => {
            if (value.includes(item.code)) {
              acc.push(item.name);
            }
            return acc;
          }, []);

          return result ? result.join(",") : "";
        },
      },
      {
        name: "registrationLimit",
        width: 160,
        header: (record) => {
          return (
            <div>
              {record.title}
              <span style={{ color: "#788295", fontWeight: "400" }}>
                (
                {languageConfig(
                  "affiliationApplication.detail.applyInfo.registrationLimit.tips",
                  "最大"
                )}
                {renderLimit})
              </span>
            </div>
          );
        },
        renderer: ({ value, record }) => {
          return type === "edit" ? (
            <NumberField
              record={record}
              name="registrationLimit"
              precision={0}
              min={0}
              max={renderLimit}
              step={1}
              style={{ width: "100%" }}
            />
          ) : (
            value
          );
        },
      },
      {
        name: "applyReason",
        width: 240,
        header: (record) => {
          return (
            <div>
              {record.title}
              <Tooltip theme="dark" title={renderTips}>
                <span
                  style={{
                    color: "#0099F2",
                    cursor: "pointer",
                    fontWeight: "400",
                  }}
                >
                  {languageConfig(
                    "affiliationApplication.detail.applyInfo.applyReason.tips",
                    "(挂靠标准是什么?)"
                  )}
                </span>
              </Tooltip>
            </div>
          );
        },
        renderer: ({ value, record }) => {
          return type === "edit" ? (
            <TextField
              record={record}
              name="applyReason"
              style={{ width: "100%" }}
            />
          ) : (
            value
          );
        },
      },
    ];

    if (type === "edit") {
      baseColumns.push(operationColumn); // 添加操作列
    }

    return baseColumns;
  }, [selectOptions, detailInfo, type]);

  /** 新增 */
  const handleAdd = () => {
    tableDs.create({
      productAuthCategoryId: "",
      upstreamChannelName: "",
      provinceCode: "",
      registrationLimit: renderLimit,
      applyReason: "",
      changeType: "add",
    });
  };

  /** 删除 */
  const handleDelete = (record) => {
    tableDs.remove(record);
  };

  /** 【change】产品授权类别 */
  const handleSelectCategory = (record) => {
    const { productAuthCategoryId } = record.toData();

    if (productAuthCategoryId === null || productAuthCategoryId === "") {
      record.set("productAuthCategoryName", "");
      record.set("upstreamChannelName", "");
      record.set("upstreamChannelCode", "");
      record.set("provinceCode", "");
    }
  };

  /** 【选择】上游渠道 */
  const handleSelectChannel = (record) => {
    const { productAuthCategoryId } = record.toData();
    const index = tableDs.indexOf(record); // 获取当前行的索引

    if (!productAuthCategoryId) {
      message.error(
        languageConfig(
          "affiliationApplication.detail.applyInfo.pleaseChooseProductAuthCategory",
          "请先选择产品授权类别"
        ),
        undefined,
        undefined,
        "top"
      );
      return;
    }

    open({
      zoneCode,
      productAuthCategoryId,
      record, // 传递记录对象本身
      rowIndex: index, // 传递行索引
    });
  };

  /** 【回调】上游渠道 */
  const handleAddChannelSelect = (val) => {
    console.log("选择的渠道信息", val);
    const { row, channelInfo } = val;
    console.log("record", row.record.toData());

    const params = {
      upstreamChannelCode: channelInfo?.channelCode, // 上游渠道编码
      upstreamChannelName: channelInfo?.channelName, // 上游渠道名称
      provinceCode: channelInfo?.provinceCode?.split(","), // 挂靠省份编码
      provinceName: channelInfo?.provinceName, // 挂靠省份名称
      productAuthCategoryName: channelInfo?.productAuthCategoryName,
    };

    row.record.set({
      // ...row.record.toData(),
      ...params,
    });
  };

  /** 【click/chane】挂靠区域 */
  const handleProvinceClick = (record) => {
    const { upstreamChannelName } = record.toData();
    // if (!upstreamChannelName) {
    //   message.error(
    //     languageConfig(
    //       'affiliationApplication.detail.applyInfo.pleaseChooseChannel',
    //       '请先选择上游渠道',
    //     ),
    //     undefined,
    //     undefined,
    //     'top',
    //   );
    //   return;
    // }
  };

  const handleProvinceChange = async (record) => {
    const { productAuthCategoryId, upstreamChannelName, provinceCode } =
      record.toData();
    console.log("change:挂靠区域", record.toData());

    // 1、城市:列表
    const options = getCityOptions();
    const data = options.toData();

    // 2、获取渠道下的:授权区域,匹配出对的'中文'
    const info = await getFormalAuthChannelPageListApi({
      productAuthCategory: productAuthCategoryId,
      channelName: upstreamChannelName,
      zoneCode,
      page: 0,
      size: 10,
    });

    if (info) {
      const { content } = info;
      if (content?.length > 0 && provinceCode) {
        const result = data.reduce((acc, item) => {
          if (provinceCode.includes(item.code)) {
            acc.push(item.name);
          }
          return acc;
        }, []);

        record.set("provinceName", result ? result?.join(",") : "");
      }
    }
    console.log("record", record.toData());
  };

  return (
    <div>
      <Title
        title={languageConfig(
          "affiliationApplication.title.applyInfo",
          "申请挂靠信息"
        )}
        isExpanded={show}
        onToggle={() => setShow(!show)}
      />

      {show && (
        <>
          <div className={commonStyles.prmCaCustomerTable}>
            <Table
              dataSet={tableDs}
              columns={columns}
              pagination={false}
              parityRow={false}
              selectionMode={SelectionMode.click}
              style={{ marginBottom: "16px" }}
              headerRowHeight={30}
              rowHeight={type === "edit" ? 36 : 30}
              renderEmpty={() => {
                return <TableEmpty />;
              }}
              footer={
                type === "edit" ? (
                  <div
                    className={styles.affiliationApplicationDetail_table_footer}
                    onClick={handleAdd}
                  >
                    <Icon type="add" />
                    {languageConfig(
                      "affiliationApplication.applyInfo.createProductAuthCategory",
                      "新增产品授权类别"
                    )}
                  </div>
                ) : null
              }
            />
          </div>
        </>
      )}
    </div>
  );
});

export default ApplyInfo;
ApplyInfo.displayName = "ApplyInfo";

(2)store.ts

javascript 复制代码
import { getFormalAuthChannelPageListApi } from '@/api/affiliationApplication';
import { getCountryListApi } from '@/api/common';
import { languageConfig } from '@/language/language';
import { getProductAuthTypeOptions } from '@/public/store';
import { cityOptionsDs } from '@/types/commonDs';
import DataSet from 'choerodon-ui/dataset';
import { FieldType } from 'choerodon-ui/dataset/data-set/enum';

export const tableList = (zoneCode: string) => {
  return {
    autoQuery: true,
    paging: false, // 新增时不分页
    fields: [
      {
        name: 'productAuthCategoryId',
        type: FieldType.string,
        label: languageConfig(
          'affiliationApplication.detail.applyInfo.label.productAuthCategoryName',
          '产品授权类别',
        ),
        placeholder: languageConfig(
          'affiliationApplication.detail.applyInfo.label.placeholder.productAuthCategoryName',
          '请选择产品授权类别',
        ),
        textField: 'authCategoryName',
        valueField: 'id',
        options: getProductAuthTypeOptions(),
        required: true,
      },
      {
        name: 'productAuthCategoryName',
        type: FieldType.string,
      },
      {
        name: 'upstreamChannelName',
        type: FieldType.string,
        label: languageConfig(
          'affiliationApplication.detail.applyInfo.label.upstreamChannelName',
          '上游渠道',
        ),
        placeholder: languageConfig(
          'affiliationApplication.detail.applyInfo.label.placeholder.upstreamChannelName',
          '请选择上游渠道',
        ),
        required: true,
      },
      {
        name: 'upstreamChannelCode',
        type: FieldType.string,
      },
      {
        name: 'provinceCode',
        type: FieldType.string,
        label: languageConfig(
          'affiliationApplication.detail.applyInfo.label.provinceName',
          '挂靠区域',
        ),
        placeholder: languageConfig(
          'affiliationApplication.detail.applyInfo.label.placeholder.provinceName',
          '请选择挂靠区域',
        ),
        textField: 'name',
        valueField: 'code',
        // options: cityOptionsDs,
        options: new DataSet({}),
        computedProps: {
          options: ({ record }) => {
            const {
              upstreamChannelName,
              productAuthCategoryId,
            } = record.toData();

            const isUpstreamChannelName =
              upstreamChannelName !== '' &&
              upstreamChannelName !== null &&
              upstreamChannelName !== undefined;

            const isProductAuthCategoryId =
              productAuthCategoryId !== '' &&
              productAuthCategoryId !== null &&
              productAuthCategoryId !== undefined;

            if (isUpstreamChannelName || isProductAuthCategoryId || !zoneCode) {
              return new DataSet({
                autoQuery: true,
                idField: 'code',
                fields: [
                  { name: 'code', type: FieldType.string },
                  { name: 'name', type: FieldType.string },
                ],
                paging: false,
                transport: {
                  read: () => {
                    return {
                      ...getCountryListApi('CN'),
                      transformResponse: async res => {
                        const data = JSON.parse(res);

                        // 获取渠道下的:授权区域
                        const info = await getFormalAuthChannelPageListApi({
                          productAuthCategory: productAuthCategoryId,
                          channelName: upstreamChannelName,
                          zoneCode,
                          page: 0,
                          size: 10,
                        });

                        // 过滤出当前'上级渠道'下的'授权区域'
                        if (info) {
                          const { content } = info;
                          if (content?.length > 0) {
                            const provinceCodeStr = content?.[0]?.provinceCode;
                            const provinceCodeArray = provinceCodeStr?.split(
                              ',',
                            );
                            const filteredList = data.filter(item =>
                              provinceCodeArray.includes(item.code),
                            );

                            return filteredList;
                          }

                          return [];
                        }

                        return data;
                      },
                    };
                  },
                },
              });
            }
            return new DataSet({});
          },
        },
        required: true,
      },
      {
        name: 'provinceName',
        type: FieldType.string,
      },
      {
        name: 'registrationLimit',
        type: FieldType.string,
        label: languageConfig(
          'affiliationApplication.detail.applyInfo.label.registrationLimit',
          '注册上限',
        ),
        placeholder: languageConfig(
          'affiliationApplication.detail.applyInfo.label.placeholder.registrationLimit',
          '请输入注册上限',
        ),
        required: true,
      },
      {
        name: 'applyReason',
        type: FieldType.string,
        label: languageConfig(
          'affiliationApplication.detail.applyInfo.label.applyReason',
          '申请/变更理由',
        ),
        placeholder: languageConfig(
          'affiliationApplication.detail.applyInfo.label.placeholder.applyReason',
          '请输入申请/变更理由',
        ),
        required: true,
      },
    ],
  };
};

(3)上游渠道:弹框

javascript 复制代码
import React, {
  forwardRef,
  useEffect,
  useImperativeHandle,
  useMemo,
} from 'react';
import { useRef, useState } from 'react';
import {
  Modal,
  Button,
  message,
  DataSet,
  Table,
  TextField,
} from 'choerodon-ui/pro';
import { Icon, Tag } from 'choerodon-ui';
import { ButtonColor } from 'choerodon-ui/pro/lib/button/enum';
import {
  COMMON_CANCEL,
  COMMON_CONFIRM,
  languageConfig,
  STATUS_NO,
  STATUS_YES,
} from '@/language/language';
import { StatusItems } from '@/interface';
import styles from '@/assets/styles/global.less';
import { SelectionMode } from 'choerodon-ui/pro/lib/table/enum';
import { QueryBar } from '@ino/ltc-component-paas';
import { queryList, tableList } from './store';

interface ChannelItem {
  channelName?: string;
}

interface SelectChannelRef {
  getSelectedData: () => ChannelItem[];
  getTableDs: () => DataSet | undefined;
}

interface SearchParams {
  channelName?: string;
}

interface SelectChannelProps {
  searchParams: {
    productAuthCategoryId: string;
    zoneCode: string;
  };
  onAutoSelect?: (selectedData: ChannelItem[]) => void;
}

interface useApplySelectChannelProps {
  onChannelSelect: (val) => void;
}

let modal;

/** 内容组件 */
const SelectChannel = forwardRef<SelectChannelRef, SelectChannelProps>(
  ({ searchParams, onAutoSelect }, ref) => {
    /** 查询列表 */
    const querySearchList = async (data: SearchParams) => {
      const { channelName } = data;
      Object.entries({ channelName }).forEach(([key, value]) => {
        tableDs.setQueryParameter(key, value);
      });
      const response = await tableDs.query();

      // 查询出只有一个默认自动选择
      if (response?.totalElements === 1) {
        // 只有一条数据时,默认选中
        const records = tableDs.records;
        if (records.length === 1) {
          tableDs.select(records[0]);

          // 自动选中后立即调用回调
          const selectedData = records[0].toData();
          console.log('自动选中数据:', selectedData);
          onAutoSelect?.(selectedData);
        }
      }
    };

    /** 查询 ds */
    const onChange = async ({ record }) =>
      await querySearchList(record.toData());
    const queryListDs = useMemo(() => new DataSet(queryList(onChange)), []);
    const queryConfig = [
      {
        name: 'channelName',
        dom: TextField,
        clearButton: true,
      },
    ];

    /** table ds */
    const tableDs = useMemo(() => new DataSet(tableList(searchParams)), [
      searchParams,
    ]);
    const columns = useMemo(() => {
      return [
        { name: 'channelName', width: 220 },
        { name: 'productAuthCategory', width: 120 },
        { name: 'divisionName', width: 140 },
        { name: 'zoneName', width: 140 },
        { name: 'provinceName', width: 160 },
        {
          name: 'isSpecify',
          width: 150,
          renderer: ({ value }) => {
            return value === 'Y' ? STATUS_YES() : STATUS_NO();
          },
        },
        {
          name: 'effectiveStatus',
          renderer: ({ value, record }) => {
            const statusMap: StatusItems =
              record
                ?.getField('effectiveStatus')
                ?.getLookupData(value, record) || {};

            if (!value) return null;
            return (
              <Tag
                color={statusMap.tag}
                style={{ color: statusMap.description }}
              >
                {statusMap?.meaning}
              </Tag>
            );
          },
        },
        { name: 'effectiveTime' },
        { name: 'ineffectiveTime' },
      ];
    }, []);

    useImperativeHandle(
      ref,
      () => ({
        getSelectedData: () => {
          return tableDs?.selected?.map(record => record.toData()) || [];
        },
        getTableDs: () => tableDs,
      }),
      [tableDs],
    );

    /** 处理表格高度 */
    const handleRef = useRef(null);
    const [handleHeight, setHandleHeight] = useState(0);
    useEffect(() => {
      setHandleHeight(handleRef?.current?.offsetHeight);
    }, []);

    return (
      <>
        <div className="ltc-c7n-style">
          <div ref={handleRef}>
            <QueryBar
              onQuery={querySearchList}
              queryBarDs={queryListDs}
              queryConfig={queryConfig}
            />
          </div>

          <div style={{ height: `calc(100% - ${handleHeight}px)` }}>
            <Table
              alwaysShowRowBox
              dataSet={tableDs}
              columns={columns}
              selectionMode={SelectionMode.click}
              queryFieldsLimit={4}
              virtual
            />
          </div>
        </div>
      </>
    );
  },
);
SelectChannel.displayName = 'SelectChannel';

export const useApplySelectChannelModal = (
  props?: useApplySelectChannelProps,
) => {
  const selectChannelRef = useRef<SelectChannelRef>(null);
  const [buttonLoading, setButtonLoading] = useState<boolean>(false);

  // 保存当前操作的行信息
  const currentRowDataRef = useRef<{
    record?: any;
    rowIndex?: number;
  }>({});

  /** 渠道:回调 */
  const handleChannelSelect = async val => {
    // console.log('选择渠道:', val, currentRowDataRef.current);
    modal?.close();

    // 回调父组件逻辑
    if (props?.onChannelSelect) {
      await props.onChannelSelect({
        channelInfo: val,
        row: currentRowDataRef.current,
      });
    }
  };

  /** 弹框打开:当前产品授权类别、下游渠道的战区编辑 */
  const handleOpenModal = params => {
    const { productAuthCategoryId, zoneCode, record, rowIndex } = params;

    currentRowDataRef.current = { record, rowIndex }; // 保存当前行信息

    modal = Modal.open({
      className: styles.prmCaSelectCustomerModal,
      style: { width: '1100px' },
      header: (
        <div className={styles.prmCa_customerModal_header_modalTitle}>
          <div>
            {languageConfig(
              'affiliationApplication.selectChannel.title',
              '请选择上游渠道',
            )}
          </div>
          <div>
            <Icon
              type="close"
              style={{
                fontWeight: '400',
                fontSize: '20px',
                cursor: 'pointer',
              }}
              onClick={() => modal?.close()}
            />
          </div>
        </div>
      ),
      children: (
        <>
          <SelectChannel
            ref={selectChannelRef}
            onAutoSelect={handleChannelSelect}
            searchParams={{ productAuthCategoryId, zoneCode }}
          />
        </>
      ),
      footer: (
        <div style={{ textAlign: 'right' }}>
          <Button
            color={ButtonColor.primary}
            loading={buttonLoading}
            onClick={handleSubmit}
          >
            {COMMON_CONFIRM()}
          </Button>
          <Button loading={buttonLoading} onClick={() => modal?.close()}>
            {COMMON_CANCEL()}
          </Button>
        </div>
      ),
    });
  };

  const handleSubmit = async () => {
    setButtonLoading(true);

    try {
      const selectedData = selectChannelRef.current?.getSelectedData();

      if (!selectedData || selectedData.length === 0) {
        message.error(
          languageConfig(
            'affiliationApplication.selectChannel.tips.pleaseChooseChannelInfoOneData',
            '请选择一条上游渠道!',
          ),
          undefined,
          undefined,
          'top',
        );
        return false;
      }

      // 传递选中的数据和当前行信息
      handleChannelSelect(selectedData[0]);
    } catch (error) {
      console.error('提交出错:', error);
    } finally {
      setButtonLoading(false);
    }
  };

  return {
    open: handleOpenModal,
    close: () => modal?.close(),
  };
};


// store.ts
import { getFormalAuthChannelPageList } from '@/api/affiliationApplication';
import { languageConfig } from '@/language/language';
import {
  getBusinessOptions,
  getProductAuthTypeOptions,
  getZoneOptions,
} from '@/public/store';
import DataSet, { DataSetProps } from 'choerodon-ui/dataset/data-set/DataSet';
import {
  DataSetSelection,
  FieldType,
} from 'choerodon-ui/dataset/data-set/enum';
import moment from 'moment';

/** ds Query */
export const queryList = (onChange): DataSetProps => {
  return {
    autoCreate: true,
    fields: [
      {
        name: 'channelName',
        type: FieldType.string,
        placeholder: languageConfig(
          'affiliationApplication.applyInfo.selectChannel.label.channelName',
          '渠道名称',
        ),
      },
    ],
    events: {
      update: onChange,
    },
  };
};

/** ds Table */
export const tableList = (searchParams): DataSetProps => {
  return {
    autoQuery: true,
    selection: DataSetSelection.single,
    fields: [
      {
        name: 'channelName',
        type: FieldType.string,
        label: languageConfig(
          'affiliationApplication.applyInfo.selectChannel.label.channelName',
          '渠道名称',
        ),
      },
      {
        name: 'productAuthCategory',
        type: FieldType.string,
        label: languageConfig(
          'affiliationApplication.applyInfo.selectChannel.label.productAuthCategory',
          '产品授权类别',
        ),
        textField: 'authCategoryName',
        valueField: 'id',
        options: getProductAuthTypeOptions(),
      },
      {
        name: 'divisionName',
        type: FieldType.string,
        label: languageConfig(
          'affiliationApplication.applyInfo.selectChannel.label.divisionName',
          '事业部',
        ),
        textField: 'divisionName',
        valueField: 'divisionCode',
        options: getBusinessOptions(),
      },
      {
        name: 'zoneName',
        type: FieldType.string,
        label: languageConfig(
          'affiliationApplication.applyInfo.selectChannel.label.zoneName',
          '战区',
        ),
      },
      {
        name: 'provinceName',
        type: FieldType.string,
        label: languageConfig(
          'affiliationApplication.applyInfo.selectChannel.label.provinceName',
          '授权区域',
        ),
      },
      {
        name: 'isSpecify',
        type: FieldType.string,
        label: languageConfig(
          'affiliationApplication.applyInfo.selectChannel.label.isSpecify',
          '官方指定上游渠道',
        ),
      },
      {
        name: 'effectiveStatus',
        type: FieldType.string,
        label: languageConfig(
          'affiliationApplication.applyInfo.selectChannel.label.effectiveStatus',
          '授权状态',
        ),
        lookupCode: 'PRM_CA_AUTH_STATUS',
      },
      {
        name: 'effectiveTime',
        type: FieldType.date,
        label: languageConfig(
          'affiliationApplication.applyInfo.selectChannel.label.effectiveTime',
          '生效时间',
        ),
        transformRequest: data => {
          if (data) return `${moment(data).format('YYYY-MM-DD')}`;
        },
      },
      {
        name: 'ineffectiveTime',
        type: FieldType.date,
        label: languageConfig(
          'affiliationApplication.applyInfo.selectChannel.label.ineffectiveTime',
          '失效时间',
        ),
        transformRequest: data => {
          if (data) return `${moment(data).format('YYYY-MM-DD')}`;
        },
      },
    ],

    transport: {
      read: config => {
        const { productAuthCategoryId, zoneCode } = searchParams || {};
        const params = {
          productAuthCategory: productAuthCategoryId,
          zoneCode,
          page: config.params.page,
          size: config.params.size,
          ...config?.data,
        };

        return {
          ...getFormalAuthChannelPageList(),
          data: { ...params },
        };
      },
    },
  };
};
相关推荐
wuk99811 分钟前
梁非线性动力学方程MATLAB编程实现
前端·javascript·matlab
XiaoYu200222 分钟前
第11章 LangChain
前端·javascript·langchain
霉运全滚蛋好运围着转1 小时前
启动 Taro 4 项目报错:Error: The specified module could not be found.
前端
cxxcode1 小时前
前端模块化发展
前端
不务正业的前端学徒1 小时前
docker+nginx部署
前端
不务正业的前端学徒1 小时前
webpack/vite配置
前端
hhcccchh1 小时前
学习vue第八天 Vue3 模板语法和内置指令 - 简单入门
前端·vue.js·学习
yyf198905251 小时前
Vue 框架相关中文文献
前端·javascript·vue.js
粥里有勺糖1 小时前
开发一个美观的 VitePress 图片预览插件
前端·vue.js·vitepress
陟上青云2 小时前
一篇文章带你搞懂原型和原型链
前端