/* eslint-disable */
import { useRef, useEffect, useState, useCallback, useMemo } from "react";
import { Button, Divider, Tabs, Tree, Radio, Image, Modal, Input, message, Badge, Checkbox, Carousel } from "antd";
import { ArrowLeftOutlined, FolderFilled, FolderOpenFilled, FileTextFilled, PlusOutlined, MinusOutlined, UploadOutlined } from "@ant-design/icons";
import { cloneDeep } from "lodash";
import commonConfig from "@/utils/config";
import * as commonUtils from "@/utils/utils";
import * as commonServices from "@/services/services";
import * as commonFunc from "@/components/Common/commonFunc";
import * as commonBusiness from "@/components/Common/commonBusiness";
import CommonViewTable from "@/components/Common/CommonViewTable";
import StaticEditTable from "@/components/Common/CommonTable";
import ShowImgM from "@/components/Common/BoxShowImgMaterial/indexNew";
import AntdDraggableModal from "@/components/Common/AntdDraggableModal";
import styles from "./index.less";
import Typesetting from "@/components/Common/Typesetting/typesetting";
import DynamicSVG from "@/components/Common/BoxDesignCompontent/svg";
import KapaiJson from "./kapai.json";
// 事件
const QuickQuoteEvent = props => {
  const addState = {};

  addState.onGetFilterState = (state, bInit) => {
    const result = Object.keys(state).reduce((pre, cur) => {
      if (cur.endsWith("Column") || cur.endsWith("Config") || ["formData", "treeData", "downAbleConfigs", "finishedConfigs"].includes(cur)) {
        return pre;
      }

      pre[cur] = state[cur];
      return pre;
    }, {});

    const { slaveData = [], manyData = [], masterData = {} } = result;
    const materialInfoFields = [
      "sMaterialsName",
      "sMaterialsNo",
      "sMaterialsId",
      "sAuxiliaryUnit",
      "sMaterialsUnit",
      "bReel",
      "dCoefficient",
      "bInverse",
      "sMaterialsStyle",
      "sComputeId",
      "sReComputeId",
      "dGramWeight",
      "sReConversionComputeId",
      "sConversionComputeId",
      "sMaterialsType",
      "bComMaterials",
      "dWlcd",
      "dWlkd",
    ];
    const slaveDataNew = bInit
      ? slaveData.map(item => {
        const { materialsInfo = [], sMaterialsName } = item;
        if (!materialsInfo.length && sMaterialsName) {
          return {
            ...item,
            materialsInfo: [
              materialInfoFields.reduce((pre, cur) => {
                pre[cur] = item[cur];
                return pre;
              }, {}),
            ],
          };
        } else {
          return item;
        }
      })
      : slaveData;

    const manyDataNew = manyData.map(item => {
      delete item.manyData;
      return item;
    });

    const { sType, sCustomerId, sCustomerName } = props.app.userinfo;
    const bCustomer = sType === "Customer";
    if (bCustomer && !masterData.sCustomerId) {
      masterData.sCustomerName = sCustomerName;
      masterData.sCustomerId = sCustomerId;
    }
    return { ...result, masterData, slaveData: slaveDataNew, manyData: manyDataNew };
  };

  const sQuoConfig = commonUtils.convertStrToObj(props.masterData.sQuoConfig, {});
  const [state, setState] = useState(addState.onGetFilterState(sQuoConfig, true));
  const { formData = [], masterConfig } = state;
  const { bLinkFieledClick } = props;
  const [hideBackBtn, setHideBackBtn] = useState(false);
  const [enabled, setEnabled] = useState(props.enabled);

  useEffect(() => {
    setHideBackBtn(!bLinkFieledClick);
    setEnabled(!bLinkFieledClick || props.enabled);
  }, [bLinkFieledClick, props.enabled]);

  // 获取formData
  useEffect(() => {
    const { masterConfig, token } = props;
    const quickQuoteConfig = masterConfig.gdsconfigformslave.find(item => item.sControlName === "BtnQuickQuote") || {};
    const { sActiveId } = quickQuoteConfig;

    const configUrl = `${commonConfig.server_host}business/getModelBysId/${sActiveId}?sModelsId=${sActiveId}`;
    commonServices.getService(token, configUrl).then(({ data: configReturn }) => {
      if (configReturn.code === 1) {
        const formData = configReturn.dataset.rows[0].formData;
        setState(pre => ({ ...pre, formData }));
      }
    });
  }, []);

  // 获取盒型定义配置
  useEffect(() => {
    if (!formData.length) return;
    const sBoxActiveId = formData.find(item => item.sGrd === "slave")?.gdsconfigformslave?.find(item => item.sName === "sName")?.sActiveId;
    if (!sBoxActiveId) return;
    const { token } = props;
    const configUrl = `${commonConfig.server_host}business/getModelBysId/${sBoxActiveId}?sModelsId=${sBoxActiveId}`;
    commonServices.getService(token, configUrl).then(({ data: configReturn }) => {
      if (configReturn.code === 1) {
        const formData = configReturn.dataset.rows[0].formData;
        setState(pre => ({ ...pre, boxConfig: formData[0] }));
      }
    });
  }, [formData.length]);

  // 获取column
  useEffect(() => {
    if (!formData.length) return;

    let result = {};
    for (let i = 0; i < formData.length; i++) {
      const tableConfig = formData[i];
      const { sGrd } = tableConfig;
      if (!sGrd) continue;
      const column = commonFunc.getHeaderConfig(tableConfig);
      result = {
        ...result,
        [`${sGrd}Column`]: column,
        [`${sGrd}Config`]: tableConfig,
      };
    }
    setState(pre => ({ ...pre, ...result }));
  }, [formData.length]);

  // 获取树形数据
  useEffect(() => {
    if (!masterConfig) return;
    // 产品分类
    const treeConfig = masterConfig.gdsconfigformslave.find(item => item.sName === "sProductClassifyName");
    if (!treeConfig) return;
    props
      .handleGetTreeDataSet({
        name: "product",
        configData: treeConfig,
        condition: {
          pageNum: 1,
          pageSize: 1000,
          bFilter: [],
        },
        isWait: true,
      })
      .then(dataReturn => {
        const { treeData = [] } = dataReturn;
        setState(pre => ({ ...pre, treeData }));
      });
  }, [masterConfig]);

  // 切换树节点时，设置后道参数默认值
  const { slaveData = [], masterData = {} } = state;
  useEffect(() => {
    if (!slaveData.length) return;
    const bNotInit = slaveData.some(item => item.sBackProcessData);
    if (!bNotInit) {
      const { downAbleConfigs = [] } = state;
      const downAbleConfigsNew = downAbleConfigs.filter(item => item.sDefaultProcessId);
      if (downAbleConfigsNew.length) {
        const slaveDataNew = slaveData.map(item => {
          let sBackProcessData = [];
          downAbleConfigsNew.forEach(({ sChineseDropDown: sChineseDropDownStr, sDefaultProcessId, sName, sId }) => {
            const sChineseDropDown = commonUtils.convertStrToObj(sChineseDropDownStr, []);
            const defaultProcess = sChineseDropDown.find(item => item.sId === sDefaultProcessId);
            const name = `slaveDown${item.sBoxModel}`;
            const sFieldName = sName;
            const changeValue = { [sFieldName]: defaultProcess.sId };
            const dropDownData = sChineseDropDown.map(item => ({
              ...item,
              sProductClassifyId: sId,
            }));
            const slaveDataReturn = onDataChange(name, sFieldName, changeValue, item.sId, dropDownData, true);
            sBackProcessData = [...sBackProcessData, ...(slaveDataReturn?.sBackProcessData?.filter(item => item.sProductClassifyId === sId) || [])];
          });
          return {
            ...item,
            sBackProcessData,
          };
        });
        setState(pre => {
          return { ...pre, slaveData: slaveDataNew };
        });
      }
    }

    const bNotInit1 = !!masterData.cpProcessName;
    if (!bNotInit1) {
      const { finishedConfigs = [] } = state;
      const finishedConfigsNew = finishedConfigs.filter(item => item.sDefaultProcessId);
      if (finishedConfigsNew.length) {
        let [cpProcessNameList, productProcessInfo] = [[], []];
        finishedConfigsNew.forEach(({ sChineseDropDown: sChineseDropDownStr, sDefaultProcessId, sName, sId }) => {
          const sChineseDropDown = commonUtils.convertStrToObj(sChineseDropDownStr, []);
          const defaultProcess = sChineseDropDown.find(item => item.sId === sDefaultProcessId);
          const name = "finished";
          const sFieldName = sName;
          const changeValue = { [sFieldName]: defaultProcess.sId };
          const dropDownData = sChineseDropDown.map(item => ({
            ...item,
            sProductClassifyId: sId,
          }));
          const { cpProcessName: cpProcessNameNew, productProcessInfo: productProcessInfoNew } = onDataChange(
            name,
            sFieldName,
            changeValue,
            masterData.sId,
            dropDownData,
            true
          );
          cpProcessNameNew.split(",").forEach((item, index) => {
            if (!cpProcessNameList.includes(item)) {
              cpProcessNameList.push(item);
              productProcessInfo.push(productProcessInfoNew[index]);
            }
          });
        });
        setState(pre => ({
          ...pre,
          masterData: {
            ...masterData,
            cpProcessName: cpProcessNameList.join(","),
            productProcessInfo,
          },
        }));
      }
    }
  }, [slaveData.map(item => item.sId).toString()]);

  addState.onBackClick = () => {
    props.onSaveState({ masterData: { ...props.masterData, sQuoConfig: JSON.stringify(addState.onGetFilterState(state)) }, quickQuoteModel: false });
  };

  // 获取国际化名称
  const getI18nName = (sFieldName, sDefault) => {
    return commonFunc.showMessage(props.app?.commonConst, sFieldName) || sDefault;
  };

  addState.getI18nName = getI18nName;

  addState.getI18nNameList = (...list) => {
    return list.map(item => getI18nName(...item));
  };

  const onDataChange = (name, sFieldName, changeValue, sId, dropDownData, isWait) => {
    const { masterData = {}, slaveData = [], selectedNode = {}, manyData = [] } = state;
    const extraState = {
      calcPriceFinished: false,
    };

    // if (manyData.some(item => Object.keys(item).length > 4)) {
    //   extraState.manyData = [];
    // }

    if (name === "master") {
      
      const { showName: sTreeNodeName } = selectedNode || {};
      const masterDataNew = { ...masterData, ...changeValue };
      masterDataNew.handleType = masterDataNew.handleType || "update";
      masterDataNew.sId = masterDataNew.sId || commonUtils.createSid();

      if (sFieldName === "dProductQty") {
        setState(pre => ({
          ...pre,
          dProductQty: changeValue.dProductQty,
        }));
      }
      if (sFieldName === "dLength" || sFieldName === "dWidth" || sFieldName === "dHeight") {
        if (sTreeNodeName) {
          if (props.currentBoxModel) {
          const boxModel = props.currentBoxModel.replace("slaveUp", "").replace("slaveDown", "");
          const iIndex = slaveData.findIndex(item => item.sTreeNodeName === sTreeNodeName && item.sBoxModel === boxModel);
          const sColumnNameConfig = commonUtils.convertStrToObj(slaveData[iIndex].sColumnNameConfig, []).map(item => ({
            ...item,
            iColValue: item.iColValue || 6,
          }));
          slaveData[iIndex] = {
            ...slaveData[iIndex],
            upAbleConfigsExtra: sColumnNameConfig,
          };
          } else {
            if (!slaveData[0]) return;
            const sColumnNameConfig = commonUtils.convertStrToObj(slaveData[0].sColumnNameConfig, []).map(item => ({
              ...item,
              iColValue: item.iColValue || 6,
            }));
            slaveData[0] = {
              ...slaveData[0],
              upAbleConfigsExtra: sColumnNameConfig,
            };
          }
        } else {
          masterDataNew[sFieldName] = changeValue[sFieldName];
        }
      }
      
      setState(pre => ({ ...pre, masterData: masterDataNew, ...extraState }));
    } else if (name.includes("slave")) {
      const boxModel = name.replace("slaveUp", "").replace("slaveDown", "");

      if (sFieldName === "sName") {
        let upAbleConfigsList = []

        if (!changeValue.sName) return;
        const dropDownDataSelected = dropDownData.find(item => item.sName === changeValue.sName);
        const { sColumnNameConfig, sColumnNameConfigExclusion, sColumnNameConfigPic } = dropDownDataSelected;
        const upAbleConfigsExtra = commonUtils.convertStrToObj(sColumnNameConfig, []).map(item => ({
          ...item,
          iColValue: item.iColValue || 6,
        }));
        const defaultData = commonFunc.getDefaultData({ gdsconfigformslave: upAbleConfigsExtra });
        delete defaultData.sId;
        delete dropDownDataSelected.sId;
        upAbleConfigsExtra?.forEach(item => {
          if (item.sTypes && item.sTypes.includes('09')) {
            const list = ['iSLength', 'iSWidth', 'iCLength', 'iCWidth']
            const nameList = ['层1长', '层1宽', '层2长', '层2宽']
            for (let index = 0; index < 4; index++) {
              upAbleConfigsList.push({
                ...item,
                sName: item.sName + list[index],
                sDefault: item[list[index]],
                showName: item.showName + nameList[index]
              })
            }
          } else {
            upAbleConfigsList.push(item)
          }
        })
        changeValue = {
          ...changeValue,
          ...defaultData,
          ...dropDownDataSelected,
          upAbleConfigsExtra,
          ...upAbleConfigsList.reduce((acc, item) => {
            acc[item.sName] = item.sDefault;
            return acc;
          }, {}),
          calcMethodData: commonUtils.convertStrToObj(sColumnNameConfigExclusion, []),
          boxPicData: commonUtils.convertStrToObj(sColumnNameConfigPic, []),
        };
      }

      const { selectedNode = {}, slaveConfig } = state;
      const { showName: sTreeNodeName } = selectedNode;

      if (sFieldName === "dSumPQty" && (sTreeNodeName.includes("骑马") || sTreeNodeName.includes("锁线"))) {
        if (!changeValue.dSumPQty || changeValue.dSumPQty % 4 !== 0) {
          message.info("P数要为4的倍数!");
          changeValue.dSumPQty = 4;
          extraState.slaveUpKey = `key_${commonUtils.createSid()}`;
        }
      }

      const iIndex = slaveData.findIndex(item => item.sTreeNodeName === sTreeNodeName && item.sBoxModel === boxModel);
      if (name.includes("slaveDown")) {
        const dropDownDataSelected = dropDownData.find(item => item.sId === changeValue[sFieldName]);
        const extraRowData = {};
        // if (dropDownDataSelected.sProcessName === "胶印") {
        //   extraRowData.sPrintProcessId = dropDownDataSelected.sId;
        // }

        if (dropDownDataSelected !== undefined) {
          dropDownDataSelected[sFieldName] = dropDownDataSelected.sProcessName;
          // 后道参数额外配置
          const { sParamConfig: sParamConfigStr } = dropDownDataSelected || {};
          const sParamConfig = commonUtils.convertStrToObj(sParamConfigStr, []);
          extraState.backendParamsConfig = sParamConfig;
          extraState.backendConfig = { sParentFieldsName: sFieldName, sBoxModel: boxModel };
          const sBackendParams = sParamConfig
            .map(item => {
              const { sParamDefault, sParam, sFieldName, iOrder } = item;
              return !sParamDefault
                ? ""
                : {
                  sId: commonUtils.createSid(),
                  value: sParamDefault,
                  sParam: sParam,
                  [`sParam${iOrder}`]: sParamDefault,
                  ...(sFieldName ? { [sFieldName]: sParamDefault } : {}),
                  sParamKey: sFieldName || `sParam${iOrder}`,
                };
            })
            .filter(item => item !== "");
          dropDownDataSelected.sBackendParams = sBackendParams;
        }

        if (iIndex === -1) {
          slaveData.push({
            sId: commonUtils.createSid(),
            handleType: "add",
            sBoxModel: boxModel,
            sTreeNodeName,
            sBackProcessData: dropDownDataSelected === undefined ? [] : [dropDownDataSelected],
            ...extraRowData,
          });
        } else {
          const sBackProcessData = slaveData[iIndex].sBackProcessData || [];
          const iIndex1 = sBackProcessData.findIndex(item => item.sProductClassifyId === dropDownData[0].sProductClassifyId);
          if (iIndex1 === -1) {
            dropDownDataSelected !== undefined && sBackProcessData.push(dropDownDataSelected);
          } else {
            if (dropDownDataSelected === undefined) {
              sBackProcessData.splice(iIndex1, 1);
            } else {
              sBackProcessData[iIndex1] = dropDownDataSelected;
            }
          }
          slaveData[iIndex].sBackProcessData = sBackProcessData;

          slaveData[iIndex] = {
            ...slaveData[iIndex],
            ...extraRowData,
            handleType: slaveData[iIndex].handleType || "update",
          };
        }
      } else {
        if (iIndex === -1) {
          slaveData.push({
            ...commonFunc.getDefaultData(slaveConfig, { tree: selectedNode }),
            ...changeValue,
            sId: commonUtils.createSid(),
            handleType: "add",
            sBoxModel: boxModel,
            sTreeNodeName,
          });
        } else {
          slaveData[iIndex] = {
            ...(sFieldName === "sName"
              ? {
                sId: slaveData[iIndex].sId,
                sBoxModel: boxModel,
                sTreeNodeName,
                ...commonFunc.getDefaultData(slaveConfig, { tree: selectedNode }),
                sBackProcessData: slaveData[iIndex].sBackProcessData,
              }
              : slaveData[iIndex]),
            ...changeValue,
            handleType: slaveData[iIndex].handleType || "update",
          };
        }
      }
      const saveIndex = slaveData.findIndex(item => item.sTreeNodeName === selectedNode.showName && item.sBoxModel === boxModel);
      const materialStyleLength = slaveData[saveIndex].materialLength || 0;
      const materialStyleWidth = slaveData[saveIndex].materialWidth || 0;


      slaveData[saveIndex] = {
        ...slaveData[saveIndex],
        sMachineStyle: materialStyleLength + "*" + materialStyleWidth,
        dMachineQty: masterData.sBillNo && slaveData[saveIndex].dMachineQty ? slaveData[saveIndex].dMachineQty : slaveData[saveIndex].dProductQty ? slaveData[saveIndex].dProductQty : masterData.dProductQty,
      };
      if (sFieldName === "dWlcd" || sFieldName === "dWlkd") {
        const horizontalBoxes = Math.floor(slaveData[saveIndex]?.dWlkd / Number(slaveData[saveIndex]?.dMachineWidth));
        const verticalBoxes = Math.floor(slaveData[saveIndex]?.dWlcd / Number(slaveData[saveIndex]?.dMachineLength));
        const newDMaterialsKQty = horizontalBoxes * verticalBoxes;
        slaveData[saveIndex] = {
          ...slaveData[saveIndex],
          dMachineQty: masterData.sBillNo && slaveData[saveIndex].dMachineQty ? slaveData[saveIndex].dMachineQty : Math.floor(slaveData[saveIndex].dMachineQty / slaveData[saveIndex].dSinglePQty),
          dMaterialsKQty: newDMaterialsKQty,
          newMaterialLength: sFieldName === "dWlcd" ? changeValue[sFieldName] : slaveData[saveIndex]?.dWlcd,
          newMaterialWidth: sFieldName === "dWlkd" ? changeValue[sFieldName] : slaveData[saveIndex]?.dWlkd,
          materialLength: sFieldName === "dWlcd" ? changeValue[sFieldName] : slaveData[saveIndex]?.dWlcd,
          materialWidth: sFieldName === "dWlkd" ? changeValue[sFieldName] : slaveData[saveIndex]?.dWlkd,
          sMaterialsStyle:  `${ sFieldName === "dWlcd" ? changeValue[sFieldName] : slaveData[saveIndex]?.dWlcd || 0}*${sFieldName === "dWlkd" ? changeValue[sFieldName] : slaveData[saveIndex]?.dWlkd|| 0}`,
        };
      }

      if (sFieldName === "sName") {
        slaveData[saveIndex] = {
          ...slaveData[saveIndex],
          dMaxLength: Number(selectedNode.sMachineStyle.split("*")[0]),
          dMaxWidth: Number(selectedNode.sMachineStyle.split("*")[1]),
        };
      }

      if (sFieldName === "bFlap") {
        slaveData[saveIndex] = {
          ...slaveData[saveIndex],
          bFold: false,
          sFold: "",
          dFold: "",
          dAdhesive: "",
        };
      }
      if (sFieldName === "bFold") {
        slaveData[saveIndex] = {
          ...slaveData[saveIndex],
          bFlap: false,
          dFlap: "",
        };
      }
      const { upAbleConfigsExtra = [] } = slaveData[saveIndex] || {};

      upAbleConfigsExtra.forEach(item => {
        if (item.sName === sFieldName) {
          item.sAssignFormula = null;
        }
      });

      if (isWait) {
        return slaveData.find(item => item.sBoxModel === boxModel);
      }
      setState(pre => ({ ...pre, slaveData, ...extraState }));
    } else if (name === "finished") {
      const { productProcessInfo = [] } = masterData;
      const dropDownDataSelected = dropDownData.find(item => item.sId === changeValue[sFieldName]);
      if (dropDownDataSelected !== undefined) {
        dropDownDataSelected[sFieldName] = dropDownDataSelected.sProcessName;
        // 后道参数额外配置
        const { sParamConfig: sParamConfigStr } = dropDownDataSelected || {};
        const sParamConfig = commonUtils.convertStrToObj(sParamConfigStr, []);
        extraState.backendParamsConfig = sParamConfig;
        extraState.backendConfig = { sParentFieldsName: sFieldName };
        const sBackendParams = sParamConfig
          .map(item => {
            const { sParamDefault, sParam, sFieldName, iOrder } = item;
            return !sParamDefault
              ? ""
              : {
                sId: commonUtils.createSid(),
                value: sParamDefault,
                sParam: sParam,
                [`sParam${iOrder}`]: sParamDefault,
                ...(sFieldName ? { [sFieldName]: sParamDefault } : {}),
                sParamKey: sFieldName || `sParam${iOrder}`,
              };
          })
          .filter(item => item !== "");
        dropDownDataSelected.sBackendParams = sBackendParams;
      }

      const iIndex = productProcessInfo.findIndex(item => item.sProductClassifyId === dropDownData[0].sProductClassifyId);
      if (iIndex === -1) {
        dropDownDataSelected !== undefined && productProcessInfo.push(dropDownDataSelected);
      } else {
        if (dropDownDataSelected === undefined) {
          productProcessInfo.splice(iIndex, 1);
        } else {
          productProcessInfo[iIndex] = dropDownDataSelected;
        }
      }
      const cpProcessName = productProcessInfo.map(item => item.sProcessName).join(",");
      const masterDataNew = { ...masterData, cpProcessName, productProcessInfo };
      masterDataNew.handleType = masterDataNew.handleType || "update";
      masterDataNew.sId = masterDataNew.sId || commonUtils.createSid();
      if (isWait) {
        return masterDataNew;
      }
      setState(pre => ({ ...pre, masterData: masterDataNew, ...extraState }));
    }

  };
  addState.onDataChange = onDataChange;

  addState.onGetAllDelData = () => {
    const {
      slaveData = [],
      slaveDelData: slaveDelDataOld = [],
      controlData = [],
      controlDelData: controlDelDataOld = [],
      materialsData = [],
      materialsDelData: materialsDelDataOld = [],
      processData = [],
      processDelData: processDelDataOld = [],
      manyqtysData = [],
      manyqtysDelData: manyqtysDelDataOld = [],
      colorData = [],
      colorDelData: colorDelDataOld = [],
      packData = [],
      packDelData: packDelDataOld = [],
    } = props;
    const addState = {
      slaveDelData: [
        ...slaveDelDataOld,
        ...slaveData.filter(item => !slaveDelDataOld.map(item1 => item1.sId).includes(item.sId)).map(item => ({ ...item, handleType: "del" })),
      ],
      controlDelData: [
        ...controlDelDataOld,
        ...controlData.filter(item => !controlDelDataOld.map(item1 => item1.sId).includes(item.sId)).map(item => ({ ...item, handleType: "del" })),
      ],
      materialsDelData: [
        ...materialsDelDataOld,
        ...materialsData
          .filter(item => !materialsDelDataOld.map(item1 => item1.sId).includes(item.sId))
          .map(item => ({ ...item, handleType: "del" })),
      ],
      processDelData: [
        ...processDelDataOld,
        ...processData.filter(item => !processDelDataOld.map(item1 => item1.sId).includes(item.sId)).map(item => ({ ...item, handleType: "del" })),
      ],
      manyqtysDelData: [
        ...manyqtysDelDataOld,
        ...manyqtysData.filter(item => !manyqtysDelDataOld.map(item1 => item1.sId).includes(item.sId)).map(item => ({ ...item, handleType: "del" })),
      ],
      colorDelData: [
        ...colorDelDataOld,
        ...colorData.filter(item => !colorDelDataOld.map(item1 => item1.sId).includes(item.sId)).map(item => ({ ...item, handleType: "del" })),
      ],
      packDelData: [
        ...packDelDataOld,
        ...packData.filter(item => !packDelDataOld.map(item1 => item1.sId).includes(item.sId)).map(item => ({ ...item, handleType: "del" })),
      ],
    };
    return addState;
  };

  // 判断单据是否被删除
  const bDataDeleted = async () => {
    const { masterConfig, currentId, masterData = {}, slaveConfig } = props;
    if (!masterData.sBillNo) return false;
    const sId = currentId || masterData.sId || "";
    const returnData = await props.handleGetDataOne({
      name: "master",
      configData: masterConfig,
      condition: { sId, pageSize: "", pageNum: "" },
      bEditClick: false,
      slaveConfig,
      isWait: true,
    });

    if (returnData) return false;
    message.info("当前报价单已被删除！请重新核价以生成新的报价单！", 5);
    props.onAdd();
    setState(pre => ({
      ...pre,
      // manyData: [],
      calcPriceFinished: false,
    }));
    return true;
  };
  addState.bDataDeleted = bDataDeleted;

  // 存草稿
  const onSaveDraft = async (nextState = state, nextProps = props) => {
    if (await bDataDeleted()) return;
    const { masterData = {} } = nextState;
    const { sProductName, sProductNo, sCustomerName, sCustomerId, sCustomerNo } = masterData;
    if (!sProductName || !sCustomerName) {
      message.info("请先填写客户名称和产品名称");
      return;
    }

    props.onSaveState(
      {
        ...addState.onGetAllDelData(),
        masterData: { ...nextProps.masterData, sQuoConfig: JSON.stringify(addState.onGetFilterState(nextState)) },
        slaveData: nextProps.slaveData.map(item => {
          return {
            ...item,
            sProductName: sProductName,
            sProductNo: sProductNo,
            sCustomerName: sCustomerName,
            sCustomerId: sCustomerId,
            sCustomerNo: sCustomerNo,
            handleType: "add",
          };
        }),
        controlData: nextProps.controlData.map(item => {
          return {
            ...item,
            // sPartsName: sProductName,
            handleType: "add",
          };
        }),
        materialsData: nextProps.materialsData?.map(item => {
          return {
            ...item,
            handleType: "add",
          };
        }),
        processData: nextProps.processData?.map(item => {
          return {
            ...item,
            handleType: "add",
          };
        }),
        manyqtysData: nextProps.manyqtysData?.map(item => {
          return {
            ...item,
            handleType: "add",
          };
        }),
        colorData: nextProps.colorData?.map(item => {
          return {
            ...item,
            handleType: "add",
          };
        }),
        packData: nextProps.packData?.map(item => {
          return {
            ...item,
            handleType: "add",
          };
        }),
        loading: true,
      },
      () => {
        props.onButtonClick("BtnDraft");
      }
    );
  };

  addState.onSaveDraft = onSaveDraft;

  // 核价按钮
  addState.handleCalcPrice = async () => {
    if (await bDataDeleted()) return;
    if (props.app.webSocket === null || props.app.webSocket?.readyState !== WebSocket.OPEN) {
      console.log("================webSocket连接======================");
      props.dispatch({
        type: "app/createWebSocket",
        payload: { reStart: true, dispatch: props.dispatch },
      });

      // 暂停2秒
      await new Promise(resolve => setTimeout(resolve, 2000));
    }

    const {
      masterConfig,
      masterData = {},
      slaveConfig,
      slaveData = [],
      selectedNode = {},
      extraParts = {},
      downAbleConfigs = [],
      downAbleExtraConfigs = [],
      finishedConfigs = [],
    } = state;
    const selectProduct = commonFunc.showLocalMessage(props, "selectProduct", "请先选择产品");
    if (commonUtils.isEmptyObject(selectedNode)) {
      message.error(selectProduct, 2);
      return;
    }

    const errMsgList = [];
    const masterConfigMust = masterConfig?.gdsconfigformslave.filter(item => item.bVisible && item.bNotEmpty);
    if (!masterConfigMust) return;
    const checkResult = masterConfigMust.filter(item => !masterData[item.sName]);
    if (checkResult.length) {
      errMsgList.push(
        checkResult.map(item => <span>【{item.showName}】</span>),
        <span>{getI18nName("isNotNull")}</span>,
        <br />
      );
    }

    const { bBox, showName, sId } = selectedNode;
    let { sAllPartsName } = selectedNode;
    if (!sAllPartsName) {
      sAllPartsName = showName;
    }

    const slaveConfigMust = slaveConfig.gdsconfigformslave
      .filter(item => item.bVisible && item.iTag && item.bNotEmpty && item.sName !== "sMaterialsName")
      .filter(item => (bBox ? true : item.sName !== "sName"));

    const sMaterialsNameConfig = slaveConfig.gdsconfigformslave.find(item => item.sName === "sMaterialsName");
    const downAbleConfigMust = [...downAbleConfigs, ...downAbleExtraConfigs].filter(item => item.bNotEmpty);

    const errorList = [];
    const partsList = [];
    slaveData.forEach(slaveRowData => {
      const list = slaveConfigMust.filter(item => !slaveRowData[item.sName]);
      if (!slaveRowData.materialsInfo || slaveRowData.materialsInfo.some(item => !item.sMaterialsName)) {
        list.push(sMaterialsNameConfig);
      }
      const { sBackProcessData = [] } = slaveRowData;
      downAbleConfigMust.forEach(item => {
        if (!sBackProcessData.some(x => x.sProductClassifyId === item.sId)) {
          list.push(item);
        }
      });
      errorList.push(list);
      partsList.push(slaveRowData.sBoxModel);
    });

    if (!errorList.some(item => !item.length)) {
      errMsgList.push(
        errorList.map((item, index0) => [
          <span>{partsList[index0]}:</span>,
          ...item.map(config => <span>【{config.showName}】</span>),
          <span>{getI18nName("isNotNull")}</span>,
          <br />,
        ])
      );
    }

    const finishedConfigMust = finishedConfigs.filter(item => item.bNotEmpty);
    const { productProcessInfo = [] } = masterData;

    const checkResult1 = finishedConfigMust.filter(item => !productProcessInfo.some(x => x.sProductClassifyId === item.sId));
    if (checkResult1.length) {
      errMsgList.push(
        checkResult1.map(item => <span>【{item.showName}】</span>),
        <span>{getI18nName("isNotNull")}</span>,
        <br />
      );
    }

    if (errMsgList.length) {
      message.error(errMsgList, 3);
      return;
    }

    setState(pre => ({ ...pre, calcPriceLoading: true, calcPriceFinished: false }));

    const { sModelsId, token, sBoxModel } = props;
    const extraPartsList = extraParts[showName] || [];
    const sAllPartsNameList = [...sAllPartsName.split(","), ...extraPartsList];

    const masterDataNew = {
      ...masterData,
      cpProcessName: masterData.cpProcessName || "",
      productProcessInfo: masterData.productProcessInfo?.map(item => ({ ...item, sProcessId: item.sId })) || [],
      sProductClassifyId: sId,
      sProductName1: masterData.sProductName,
      dProductWidth: masterData.dWidth,
      dProductLength: masterData.dLength,
      dProductHeight: masterData.dHeight,
      sProductStyle:
        masterData.dHeight !== undefined
          ? `${masterData.dLength}*${masterData.dWidth}*${masterData.dHeight}`
          : `${masterData.dLength}*${masterData.dWidth}`,
    };
    const paramMap = {
      bQuotation: true,
      ...masterDataNew,
      product: masterDataNew,
      sPartsStyle: "",
      partsInfo: sAllPartsNameList
        .map(partName => {
          const temp = {
            ...slaveData.find(item => item.sTreeNodeName === showName && item.sBoxModel === partName),
          };
          return temp;
        })
        .filter(item => commonUtils.isNotEmptyObject(item) && item.materialsInfo && item.materialsInfo.length)
        .map(item => {
          return {
            ...Object.keys(item).reduce((pre, cur) => {
              if (typeof item[cur] !== "object") {
                pre[cur] = item[cur];
              }
              return pre;
            }, {}),
            dPartsQty: masterData.dProductQty,
            // iPositiveColor: Number(item.sColor),
            iOppositeColor: item.sBackProcessData?.find(item => item.bPrintParams)?.iPositiveColor || 0,
            iOppositeSpecialColor: item.sBackProcessData?.find(item => item.bPrintParams)?.iPositiveSpecialColor || 0,
            sPartsName: item.sBoxModel,
            materialsInfo: item.materialsInfo?.filter(x => commonUtils.isNotEmptyObject(x)),
            processInfo:
              item.sBackProcessData?.map(item => ({
                ...item,
                sProcessId: item.sProcessId || item.sId,
              })) || [],
          };
        }),
    };
    paramMap.sPartsStyle = (paramMap.partsInfo[0].dPartsLength || 0) + "*" + (paramMap.partsInfo[0].dPartsWidth || 0);
    if (paramMap.sPartsStyle === "0*0") {
      delete paramMap.sPartsStyle;
    }
    const url = `${commonConfig.server_host}calculationStd/countMoney?sModelsId=${sModelsId}`;
    const dataReturn = (await commonServices.postValueService(token, paramMap, url)).data;

    if (dataReturn.code === 1) {
      const { slaveConfig, masterData: masterData1, materialsConfig, processConfig, sModelsId, app } = props;
      const { productClassify, partsNewInfo = [], productProcessInfo, partsInfo: partsOldInfo } = dataReturn.dataset.rows[0];
      const { bCalculatingArea } = selectedNode;

      const slaveData = [];
      const controlData = [];
      const materialsData = [];
      let processData = [];
      let tableDataRow = {};
      for (const item of slaveConfig.gdsconfigformslave) {
        tableDataRow[item.sName] = masterData[item.sName];
      }
      tableDataRow.sId = commonUtils.createSid();
      tableDataRow.handleType = "add";
      tableDataRow.iOrder = 1;
      tableDataRow.sParentId = masterData.sId;
      // const productIdDropDown = commonUtils.getStoreDropDownData(sModelsId, 'slave', 'sProductName');
      let productIdDropDown;
      const slaveIndex = slaveConfig.gdsconfigformslave.findIndex(item => item.sName === "sProductName");
      if (slaveIndex > -1) {
        const sqlDropDownData = await props.getSqlDropDownData(sModelsId, "slave", slaveConfig.gdsconfigformslave[slaveIndex], tableDataRow);
        productIdDropDown = sqlDropDownData.dropDownData;
      }
      const iProductIdIndex = commonUtils.isEmptyArr(productIdDropDown)
        ? -1
        : productIdDropDown.findIndex(item => item.sId === tableDataRow.sProductId);
      if (iProductIdIndex === -1) {
        tableDataRow.sProductId = tableDataRow.sProductName;
        const tableDataRowNew = { ...tableDataRow, ...masterDataNew };
        const extraProps = {
          sProductId: tableDataRowNew.sProductName,
          sProductName: tableDataRowNew.sProductName,
          sProductStyle: tableDataRowNew.sProductStyle,
          sProductUnit: tableDataRowNew.sProductUnit,
          sProductNo: tableDataRowNew.sProductNo || "XP0001",
          sCustomerProductNo: tableDataRowNew.sCustomerProductNo,
          sProductClassifyId: tableDataRowNew.sProductClassifyId,
          sProductClassifyName: tableDataRowNew.sProductClassifyName,
        };
        tableDataRow = { ...tableDataRow, ...extraProps };
        tableDataRow.sProductInfo = JSON.stringify(extraProps);
      } else {
        tableDataRow.sProductInfo = "";
      }
      slaveData.push(tableDataRow);
      const sInfoArr = [];
      let errorFlag = false;
      if (!commonUtils.isEmptyArr(partsOldInfo)) {
        partsOldInfo.forEach(item => {
          if (commonUtils.isNotEmptyObject(item) && !commonUtils.isEmpty(item.errorFlag)) {
            errorFlag = true;
            props.getServiceError({ msg: `${item.sPartsName}  ${item.errorFlag}` });
          }
        });
      }
      if (errorFlag) {
        setState(pre => ({ ...pre, calcPriceLoading: false }));
        return;
      }

      // 返回数据赋值
      const { slaveData: stateSlaveData = [] } = state;
      partsNewInfo.forEach(item => {
        const slaveRowData = stateSlaveData.find(row => item.sTreeNodeName === row.sTreeNodeName && item.sBoxModel === row.sBoxModel);
        slaveRowData.dMachineQty = item.dMachineQty;
        slaveRowData.dAuxiliaryQty = item.materialsInfo?.[0]?.dAuxiliaryQty;
        slaveRowData.sPrint = item.sProcessName;
        if (!bCalculatingArea) {
          // todo 核价成功后 判断bSpecialRules 为false 就要给材料长材料款赋值
          // partsNewInfo
          slaveRowData.dWlcd = item.dMaterialsLength;
          slaveRowData.dWlkd = item.dMaterialsWidth;
        }
        // slaveRowData.dMaterialsLength = item.dMaterialsLength;
        // slaveRowData.dMaterialsWidth = item.dMaterialsWidth;
        setState(pre => ({ ...pre, slaveData: stateSlaveData }));
      });

      if (props.app.userinfo.sType === "sysadmin") {
        /* 超级管理员，弹窗显示接口返回的sInfo  */
        partsNewInfo.forEach(item => {
          const { sPartsName, sInfo } = item;
          const sInfoObj = {};
          sInfoObj.sPartsName = sPartsName;
          sInfoObj.sInfo = sInfo;
          sInfoArr.push(sInfoObj);
        });
      }

      const bProcessAssort = true;
      let returnProcessAssort = [];
      let processAssignAssort = "";
      let dropDownDataProcessName;
      if (bProcessAssort) {
        const dataUrl = `${commonConfig.server_host}salesorder/getProcessAssort?sModelsId=${sModelsId}`;
        const dataProcessAssort = (await commonServices.postValueService(token, {}, dataUrl)).data;
        if (dataProcessAssort.code === 1) {
          returnProcessAssort = dataProcessAssort.dataset.rows[0].processassort;
          const iIndex = processConfig.gdsconfigformslave.findIndex(item => item.sName === "sProcessName");
          if (iIndex > -1) {
            const sqlDropDownData = await props.getSqlDropDownData(sModelsId, "slave", processConfig.gdsconfigformslave[iIndex]);
            dropDownDataProcessName = sqlDropDownData.dropDownData;
            processAssignAssort = processConfig.gdsconfigformslave[iIndex].sAssignField;
          }
        }
      }
      const newCopyTo = {};
      newCopyTo.master = masterData;
      newCopyTo.slave = commonUtils.isEmptyArr(slaveData) ? {} : slaveData[0];
      for (let i = 0; i < partsNewInfo.length; i++) {
        const partInfo = partsNewInfo[i];
        const iIndex = i;
        const partsDataRow = {};
        for (const child of Object.keys(partInfo)) {
          partsDataRow[child] = partInfo[child];
        }
        partsDataRow.handleType = "add";
        partsDataRow.iOrder = iIndex + 1; /* 快速下单编号从1开始 */
        partsDataRow.sId = commonUtils.createSid();
        partsDataRow.sParentId = masterData.sId;
        // partsDataRow.sSlaveId = ' ';
        if (partsDataRow.iPrintMode !== 3) {
          partsDataRow.iOppositeColor = partsDataRow.iPositiveColor;
        }
        delete partsDataRow.dMaterialsKQty;
        // delete partsDataRow.dMaterialsLength;
        // delete partsDataRow.dMaterialsWidth;
        // if (productClassify.bSpecialRules) {
        //   partsDataRow.dMachineLength = partsDataRow.dMaxMachineLength;
        //   partsDataRow.dMachineWidth = partsDataRow.dMaxMachineWidth;
        // }
        controlData.push(partsDataRow);
        // 材料信息
        for (let i = 0; i < partInfo.materialsInfo.length; i++) {
          const materialInfo = partInfo.materialsInfo[i];
          const iOrder = i;
          let materialDataRow = {};
          for (const item of materialsConfig.gdsconfigformslave) {
            materialDataRow[item.sName] = materialInfo[item.sName];
          }
          materialDataRow.handleType = "add";
          materialDataRow.sType = "0";
          materialDataRow.iPartOrder = iIndex;
          materialDataRow.iOrder = iOrder + 1;
          materialDataRow.sPartsName = partsDataRow.sPartsName;
          materialDataRow.sId = commonUtils.createSid();
          materialDataRow.sParentId = masterData.sId;
          materialDataRow.sControlId = partsDataRow.sId;
          // materialDataRow.sSlaveId = ' ';
          materialDataRow.dMaterialsKQty = partsDataRow.iNumberofMaterial;
          materialDataRow.sMaterialsStyle = partsDataRow.sMaterialsStyle;
          const models = "Materials";
          materialDataRow = await props.onMaterialsChange(materialDataRow, sModelsId, masterData, [], "dAuxiliaryQty", app, token, models);
          materialDataRow = commonBusiness.getCalculateAllMoney(app, models, "dAuxiliaryQty", masterData, materialDataRow);
          materialsData.push(materialDataRow);
        }

        // 工序信息
        let processPrintDataRow = {};
        processPrintDataRow.handleType = "add";
        processPrintDataRow.sProcessId = partInfo.sProcessId;
        const iProcessPrintIndex = dropDownDataProcessName.findIndex(item => item.sId === processPrintDataRow.sProcessId);
        if (iProcessPrintIndex > -1) {
          processPrintDataRow = {
            ...processPrintDataRow,
            ...commonFunc.getAssignFieldValue(processAssignAssort, dropDownDataProcessName[iProcessPrintIndex], newCopyTo),
          }; // 取赋值字段
        }
        processPrintDataRow.sType = partInfo.sType;
        processPrintDataRow.iPartOrder = iIndex;
        processPrintDataRow.iOrder = 1;
        processPrintDataRow.sProcessName = partInfo.sProcessName;
        processPrintDataRow.sPartsName = partsDataRow.sPartsName;
        processPrintDataRow.dProcessInQty = partInfo.dProcessInQty;
        processPrintDataRow.dLossQty = partInfo.dLossQty;
        processPrintDataRow.dAdjustLossQty = partInfo.dAdjustLossQty;
        processPrintDataRow.dProcessOutQty = partInfo.dProcessOutQty;
        processPrintDataRow.sId = commonUtils.createSid();
        processPrintDataRow.sParentId = masterData.sId;
        processPrintDataRow.sControlId = partsDataRow.sId;
        // processPrintDataRow.sSlaveId = ' ';
        const iSpecialColor = partInfo.iSpecialColor !== undefined ? partInfo.iSpecialColor : partInfo.partInfoiSpecialColor;
        processPrintDataRow.sColorSerialMemo = JSON.stringify([{ sId: partInfo.sColorId, sName: partInfo.sColor, dColor: partInfo.iColor, iSpecialColor }]);

        processData.push(processPrintDataRow);
        // 配套工序
        if (bProcessAssort) {
          returnProcessAssort
            .filter(item => item.sParentId === processPrintDataRow.sProcessId)
            .forEach(itemProcessAssort => {
              const iIndex = dropDownDataProcessName.findIndex(item => item.sId === itemProcessAssort.sProcessId);
              const iProcessIndex = -1;
              const iNewProcessIndex = processData.findIndex(
                item => item.sProcessId === itemProcessAssort.sProcessId && item.sControlId === partsDataRow.sId
              );
              if (iIndex > -1 && iProcessIndex < 0 && iNewProcessIndex < 0) {
                let processRow = commonFunc.getDefaultData(processConfig, newCopyTo); // 取默认值
                processRow = { ...processRow, ...commonFunc.getAssignFieldValue(processAssignAssort, dropDownDataProcessName[iIndex], newCopyTo) }; // 取赋值字段
                processRow.handleType = "add";
                processRow.sId = commonUtils.createSid();
                processRow.sParentId = masterData.sId;
                processRow.sControlId = partsDataRow.sId;
                processRow.sPartsName = partsDataRow.sPartsName;
                processRow.sType = dropDownDataProcessName[iIndex].sType;
                // processRow.sSlaveId = ' ';
                processData.push(processRow);
              }
            });
        }

        partInfo.processInfo.forEach((process, iOrder) => {
          let processAfterDataRow = {};
          for (const item of processConfig.gdsconfigformslave) {
            processAfterDataRow[item.sName] = process[item.sName];
          }
          for (const child of Object.keys(process)) {
            processAfterDataRow[child] = process[child];
          }
          processAfterDataRow.handleType = "add";
          processAfterDataRow.sProcessId = process.sProcessId;
          const iProcessAfterIndex = dropDownDataProcessName.findIndex(item => item.sId === processAfterDataRow.sProcessId);
          if (iProcessAfterIndex > -1) {
            processAfterDataRow = {
              ...processAfterDataRow,
              ...commonFunc.getAssignFieldValue(processAssignAssort, dropDownDataProcessName[iProcessAfterIndex], newCopyTo),
            }; // 取赋值字段
          }
          processAfterDataRow.sType = process.sType;
          processAfterDataRow.iPartOrder = iIndex;
          processAfterDataRow.iOrder = iOrder + 1;
          processAfterDataRow.sPartsName = partsDataRow.sPartsName;
          processAfterDataRow.sId = commonUtils.createSid();
          processAfterDataRow.sParentId = masterData.sId;
          processAfterDataRow.sControlId = partsDataRow.sId;

          const sBackendParams = process.sBackendParams || [];
          if (sBackendParams.length) {
            const sQuoParams = sBackendParams.map(item => ({
              sParamKey: item.sParamKey,
              sParamName: item.sParam,
              sParamValue: item.value !== undefined ? item.value : "",
              bSelfCbx: !(item.value === "" || item.value === undefined),
            }));
            processAfterDataRow.sQuoParams = JSON.stringify(sQuoParams);
          }

          // processAfterDataRow.sSlaveId = ' ';
          if (process.sColor) {
            processAfterDataRow.sColorSerialMemo = JSON.stringify([{ sId: process.sColorId, sName: process.sColor, dColor: process.iColor }]);
          }
          processData.push(processAfterDataRow);
          // 配套工序
          if (bProcessAssort) {
            returnProcessAssort
              .filter(item => item.sParentId === processPrintDataRow.sProcessId)
              .forEach(itemProcessAssort => {
                const iIndex = dropDownDataProcessName.findIndex(item => item.sId === itemProcessAssort.sProcessId);
                const iProcessIndex = -1;
                const iNewProcessIndex = processData.findIndex(
                  item => item.sProcessId === itemProcessAssort.sProcessId && item.sControlId === partsDataRow.sId
                );
                if (iIndex > -1 && iProcessIndex < 0 && iNewProcessIndex < 0) {
                  let processRow = commonFunc.getDefaultData(processConfig, newCopyTo); // 取默认值
                  processRow = { ...processRow, ...commonFunc.getAssignFieldValue(processAssignAssort, dropDownDataProcessName[iIndex], newCopyTo) }; // 取赋值字段
                  processRow.handleType = "add";
                  processRow.sId = commonUtils.createSid();
                  processRow.sParentId = masterData.sId;
                  processRow.sControlId = partsDataRow.sId;
                  processRow.sPartsName = partsDataRow.sPartsName;
                  processRow.sType = dropDownDataProcessName[iIndex].sType;
                  // processRow.sSlaveId = ' ';
                  processData.push(processRow);
                }
              });
          }
        });
      }
      productProcessInfo.forEach((process, iOrder) => {
        let processProductDataRow = {};
        for (const item of processConfig.gdsconfigformslave) {
          processProductDataRow[item.sName] = process[item.sName];
        }
        for (const child of Object.keys(process)) {
          processProductDataRow[child] = process[child];
        }
        const iProductProcessIndex = dropDownDataProcessName.findIndex(item => item.sId === processProductDataRow.sProcessId);
        if (iProductProcessIndex > -1) {
          processProductDataRow = {
            ...processProductDataRow,
            ...commonFunc.getAssignFieldValue(processAssignAssort, dropDownDataProcessName[iProductProcessIndex], newCopyTo),
          }; // 取赋值字段
        }
        processProductDataRow.handleType = "add";
        processProductDataRow.sType = "3";
        processProductDataRow.sPartsName = "";
        processProductDataRow.iPartOrder = 999;
        processProductDataRow.iOrder = iOrder + 1;
        processProductDataRow.sId = commonUtils.createSid();
        processProductDataRow.sParentId = masterData.sId;

        const sBackendParams = process.sBackendParams || [];
        if (sBackendParams.length) {
          const sQuoParams = sBackendParams.map(item => ({
            sParamKey: item.sParamKey,
            sParamName: item.sParam,
            sParamValue: item.value !== undefined ? item.value : "",
            bSelfCbx: !(item.value === "" || item.value === undefined),
          }));
          processProductDataRow.sQuoParams = JSON.stringify(sQuoParams);
        }

        // processProductDataRow.sSlaveId = ' ';
        processData.push(processProductDataRow);
        // 配套工序
        if (bProcessAssort) {
          returnProcessAssort
            .filter(item => item.sParentId === processProductDataRow.sProcessId)
            .forEach(itemProcessAssort => {
              const iIndex = dropDownDataProcessName.findIndex(item => item.sId === itemProcessAssort.sProcessId);
              const iProcessIndex = -1;
              const iNewProcessIndex = processData.findIndex(item => item.sProcessId === itemProcessAssort.sProcessId);
              if (iIndex > -1 && iProcessIndex < 0 && iNewProcessIndex < 0) {
                let processRow = commonFunc.getDefaultData(processConfig, newCopyTo); // 取默认值
                processRow = { ...processRow, ...commonFunc.getAssignFieldValue(processAssignAssort, dropDownDataProcessName[iIndex], newCopyTo) }; // 取赋值字段
                processRow.handleType = "add";
                processRow.sId = commonUtils.createSid();
                processRow.sParentId = masterData.sId;
                processRow.sType = dropDownDataProcessName[iIndex].sType;
                // processRow.sSlaveId = ' ';
                processData.push(processRow);
              }
            });
        }
      });
      processData = props.sortData(controlData, processData);
      const addState = { controlSelectedRowKeys: ["0000000"] };
      if (!commonUtils.isEmptyArr(slaveData)) {
        addState.slaveSelectedRowKeys = [slaveData[0].sId];
      }

      const { sPrintConfig = {}, downAbleConfigs = [], finishedConfigs = [] } = state;
      const processConfigs = [sPrintConfig, ...downAbleConfigs, ...finishedConfigs];

      const configOrderMap = {};
      processConfigs.forEach((config, index) => {
        configOrderMap[config.sId] = index;
      });

      processData.sort((a, b) => {
        return configOrderMap[a.sProcessClassifyId] - configOrderMap[b.sProcessClassifyId];
      });
      processData = processData.map((item, index) => ({ ...item, iOrder: index + 1 }));

      const newState = {
        materialsConfig,
        masterData: { ...masterData1, ...masterData },
        slaveData,
        controlData,
        materialsData,
        processData,
        fastOrderModalVisible: false,
        quotationAllprogress: 0,
        materialsSelectedRowKeys: [],
        ...addState,
        sInfoArr,
        // bVisiblesInfo: !!commonUtils.isNotEmptyArr(sInfoArr),
        Loading: false,
        // quickQuoteModel: false,
      };

      delete newState.masterData.sQuoConfig;

      const result = await props.handleCalculation(
        false,
        { ...props, ...newState, manyqtysConfig: state.manyConfig, manyqtysData: state.manyData },
        true
      );
      if (commonUtils.isEmptyObject(result)) {
        setState(pre => ({ ...pre, calcPriceLoading: false }));
        return;
      }

      const { manyqtysData = [] } = result;
      result.manyqtysData = manyqtysData.map(item => ({
        ...item,
        sParentId: newState.masterData.sId,
      }));

      let hasCalled = false;

      setState(pre => {
        const preNew = {
          ...pre,
          manyData: result.manyqtysData,
          calcPriceLoading: false,
          calcPriceFinished: true,
        };

        const stateNew = { ...newState, ...result };

        if (hasCalled) return preNew; // 防止重复执行
        hasCalled = true;

        props.onSaveState(stateNew, () => {
          onSaveDraft(preNew, stateNew);
        });

        return preNew;
      });
    } else {
      message.error(dataReturn.erroMsg || dataReturn.msg);
      setState(pre => ({ ...pre, calcPriceLoading: false }));
    }
  };

  // 新报价
  addState.onAdd = () => {
    const restList = ["formData", "manyColumn", "manyConfig", "masterConfig", "slaveConfig", "slaveColumn", "treeData"];
    const sBoxActiveId = formData.find(item => item.sGrd === "slave")?.gdsconfigformslave?.find(item => item.sName === "sName")?.sActiveId;
    if (!sBoxActiveId) return;
    const { token } = props;
    const configUrl = `${commonConfig.server_host}business/getModelBysId/${sBoxActiveId}?sModelsId=${sBoxActiveId}`;
    commonServices.getService(token, configUrl).then(({ data: configReturn }) => {
      if (configReturn.code === 1) {
        const formData = configReturn.dataset.rows[0].formData;
        setState(pre => ({ ...pre, boxConfig: formData[0] }));
      }
    });
    const stateNew = {
      ...restList.reduce((pre, cur) => {
        pre[cur] = state[cur];
        return pre;
      }, {}),
      masterData: {},
      slaveData: [],
      manyData: [],
    };
    setState(stateNew);
    props.onAdd();
    props.onSaveState({ currentId: "" });
  };

  // 选择盒型弹窗
  addState.onFieldPopupModal = (showConfig, name) => {
    if (showConfig.sName === "sName") {
      props.onSaveState({ boxModelSelectedModalVisible: true, currentBoxModel: name });
    }
  };

  return {
    ...props,
    onDataChange0: props.onDataChange,
    ...addState,
    hideBackBtn,
    enabled,
    state,
    setState,
  };
};
// 入口
const QuickQuote = baseProps => {
  const props = QuickQuoteEvent(baseProps);

  const [treeClassName, setTreeClassName] = useState("");

  // 监听页面滚动事件
  const rightContentRef = useRef(null);
  useEffect(() => {
    rightContentRef.current.addEventListener("scroll", () => {
      document.activeElement.blur();
    });
  }, []);

  return (
    <div className={styles.quickQuote}>
      <div className={styles.content}>
        {!props.hideBackBtn && (
          <Button className={styles.back} type="primary" shape="circle" size="large" onClick={props.onBackClick} icon={<ArrowLeftOutlined />} />
        )}
        <div
          className={`${styles.leftTree} ${treeClassName}`}
          onMouseEnter={() => {
            setTreeClassName(styles.overFlow);
          }}
          onMouseLeave={() => {
            setTreeClassName("");
          }}
        >
          <TreeComponent {...props} />
        </div>
        <div className={styles.rightContent} ref={rightContentRef}>
          <ContentComponent {...props} />
        </div>
      </div>
      <BoxModelSelectedModal {...props} />
    </div>
  );
};

// 树形组件
const TreeComponent = props => {

  const { treeData = [], selectedNode = {}, slaveConfig } = props.state;
  if (!treeData.length) return "";

  // 循环递归数据生成树节点
  const renderTreeNodes = data => {
    return data.map(item => {
      const { showName, children = [], sId } = item;
      const treeNodeProps = {
        title: showName,
        key: sId,
        treeNode: item,
        selectable: !children.length,
        switcherIcon: params => {
          const { expanded, isLeaf } = params;
          let icon = "";
          if (isLeaf) {
            icon = <FileTextFilled style={{ color: "#f7cc4f", fontSize: 20 }} />;
          } else if (expanded) {
            icon = <FolderOpenFilled style={{ color: "#f7cc4f", fontSize: 20 }} />;
          } else {
            icon = <FolderFilled style={{ color: "#f7cc4f", fontSize: 20 }} />;
          }
          return icon;
        },
      };

      return <Tree.TreeNode {...treeNodeProps}>{!!children.length && renderTreeNodes(children)}</Tree.TreeNode>;
    });
  };

  const timeRef = useRef(0);

  // 摊平数组
  const flattenArray = arr => {
    return arr.reduce((result, item) => {
      // 如果存在 children，则递归处理
      if (item.children && item.children.length > 0) {
        result.push(...flattenArray(item.children));
      } else {
        result.push(item);
      }
      return result;
    }, []);
  };

  // 点击节点后查询数据
  useEffect(() => {
    if (!selectedNode.sId || commonUtils.isEmptyObject(slaveConfig)) return;

    timeRef.current += 1;

    const getSqlDropDownData = async ({ sId }) => {
      const url = `${commonConfig.server_host}business/getSelectLimit/${sId}`;
      const body = {
        sSqlCondition: {
          sProductClassifyId: selectedNode.sId,
        },
        sKeyUpFilterName: "",
        pageNum: 1,
        pageSize: 20,
      };
      const retrunData = await commonServices.postValueService(props.app.token, body, url);
      const sColumnNameConfigStr = retrunData.data?.dataset?.rows?.[0]?.sColumnNameConfig;
      // 取上机尺寸
      return commonUtils.convertStrToObj(sColumnNameConfigStr, []);
    };
    const getDropDownData = async props => {
      const showDownConfig = slaveConfig.gdsconfigformslave.find(item => item.sControlName === "BtnDownConfig");
      const downAbleConfigs = await getSqlDropDownData({ ...showDownConfig });

      props.setState(pre => {
        const { slaveData = [], slaveConfig, manyData = [], masterData = {} } = pre;
        const addState = {};
        const defaultData = commonFunc.getDefaultData(slaveConfig, { tree: selectedNode });
        const slaveDataNew = slaveData.filter(item => item.sTreeNodeName === selectedNode.showName);
        if (!slaveDataNew.length) {
          const sAllPartsName = selectedNode.sAllPartsName || selectedNode.showName;
          sAllPartsName.split(",").forEach((item, index) => {
            const tempData = {
              sId: commonUtils.createSid(),
              handleType: "add",
              ...defaultData,
              sBoxModel: item,
              sTreeNodeName: selectedNode.showName,
            };
            if (selectedNode.sTypeKey === "huace") {
              if (index !== 0) {
                delete tempData.dSumPQty;
              } else {
                tempData.dSumPQty = 4;
              }
            }
            slaveDataNew.push(tempData);
          });
          addState.slaveData = slaveDataNew;
        }

        addState.slaveData = slaveDataNew.map(item => {
          const { sPackDetailPathUpLoad, sPackPath } = selectedNode;
          return {
            ...item,
            ...(sPackDetailPathUpLoad ? { sPackDetailPathUpLoad } : {}),
            ...(sPackPath ? { sPackPath } : {}),
          };
        });

        if (timeRef.current > 1) {
          delete masterData.cpProcessName;
          delete masterData.productProcessInfo;
          addState.masterData = masterData;
          addState.extraParts = {};
          addState.calcPriceFinished = false;
          addState.backendParamsConfig = [];
          addState.backendConfig = {};
          addState.downAbleExtraConfigs = [];
          if (manyData.some(item => Object.keys(item).length > 4)) {
            addState.manyData = [];
          }
        }
        return {
          ...pre,
          ...addState,
          sPrintConfig: downAbleConfigs.find(item => item.sType === "1" && item.sName === "胶印"),
          downAbleConfigs: downAbleConfigs
            .filter(item => item.sType === "2" || item.sType === "0")
            .map((item, index) => ({
              ...item,
              sName: `sParams${index}`,
              iColValue: item.iColValue || 4,
              sVisColumnName: "sProcessName",
            })),
          finishedConfigs: downAbleConfigs
            .filter(item => item.sType === "3")
            .map((item, index) => ({
              ...item,
              sName: `sParams${index}`,
              iColValue: item.iColValue || 4,
              sVisColumnName: "sProcessName",
            })),
        };
      });
    };
    if (selectedNode.sTypeKey === "juantong") {
      props.onSaveState({
        masterData: { ...props.masterData, sFormId: "101251240115016002356125200" },
      });
    } else {
      props.onSaveState({
        masterData: { ...props.masterData, sFormId: "101251240115016076506222050" },
      });
    }

    getDropDownData(props);
  }, [selectedNode.sId, commonUtils.isEmptyObject(slaveConfig)]);
  const { slaveData } = props.state;
  return (
    <Tree
      className={"hide-file-icon"}
      onSelect={(e, select) => {
        props.onSaveState({ currentBoxModel: undefined });
        props.setState(pre => {
          const { masterData = {} } = pre;
          const { sProductName, sProductUnit } = masterData;
          const showNameList = [...flattenArray(treeData).map(item => item.showName), "", undefined];
          return {
            ...pre,
            selectedNode: select.selectedNodes[0]?.treeNode || {},
            masterData: {
              ...masterData,
              sProductName: showNameList.includes(sProductName) ? select.node.title : sProductName,
              sProductUnit: sProductUnit || select.node.treeNode.sUnit,
            },
          };
        });
      }}
      // defaultSelectedKeys={[activeTree]}
      defaultExpandAll={true}
      selectedKeys={[selectedNode.sId]}
    >
      {renderTreeNodes(treeData)}
    </Tree>
  );
};

// 内容组件
const ContentComponent = props => {
  const { selectedNode = {}, extraParts = {}, slaveData } = props.state;
  const manyqtysInfo = props.getI18nName("manyqtysInfo", "多数量报价");
  const selectProduct = commonFunc.showLocalMessage(props, "selectProduct", "请先选择产品");
  const { showName, sAllPartsNameDefault } = selectedNode;
  const extraPartsList = extraParts[showName] || [];
  let { sAllPartsName = "" } = selectedNode;
  let bEmpty = false;
  if (commonUtils.isEmptyObject(selectedNode)) {
    sAllPartsName = selectProduct;
    bEmpty = true;
  } else if (!sAllPartsName) {
    sAllPartsName = showName;
  }
  const hasAutoSetDefault = useRef(false);

  useEffect(() => {
    hasAutoSetDefault.current = false;
  }, [selectedNode]);
  // 2. 监听两个依赖：sAllPartsNameDefault 与 slaveData
  const {sBillNo} = props.masterData
  useEffect(() => {
    if (
      !hasAutoSetDefault.current &&               // 尚未执行
      selectedNode?.sAllPartsNameDefault?.length && // 有默认值
      props.state.slaveData?.length  && !sBillNo              // 子表数据已就位
    ) {
      const boxModelList = sAllPartsName.split(',');
      const { slaveData } = props.state;

      // 数量对不上不处理
      if (slaveData.length !== boxModelList.length) return;

      // 标记为已执行，后续不再进来
      hasAutoSetDefault.current = true;

      // 取默认值列表（深拷贝，避免后续 JSON.parse 出错）
      const sAllPartsNameDefaultList = JSON.parse(
        sAllPartsNameDefault
      );

      const getSqlDropDownData = async ({ sId, sSqlCondition = {} }, cb) => {
        const url = `${commonConfig.server_host}business/getSelectLimit/${sId}`;
        const body = {
          sKeyUpFilterName: "",
          pageNum: 1,
          pageSize: 1000,
          sSqlCondition,
        };
        const retrunData = await commonServices.postValueService(props.app.token, body, url);
        const dropDownData = retrunData.data?.dataset?.rows;
        if (dropDownData && sAllPartsNameDefaultList.length) {
          sAllPartsNameDefaultList.forEach((item, index) => {
            const sPartNameList = item.sPartName?.split(",");
            if (sPartNameList && sPartNameList.length) {
              sPartNameList.forEach(sPartName => {
                const box = dropDownData.find(box => box.sId === item.sBoxId); // Define 'box' here
                const boxData = dropDownData.map((itemBox, indexBox) => ({
                  ...itemBox,
                  iOrder: indexBox + 1,
                }));
                if (box) { // Check if 'box' exists before using it
                  props.onDataChange("slaveUp" + sPartName, "sName", { sName: box.sName }, box.sId, boxData);
                }
              });
            }
          });
        }
      };

      getSqlDropDownData({
        sId: '17428091410008594700322758474000',
        sSqlCondition: { sProductClassifyId: selectedNode.sId },
      });
    }
  }, [selectedNode?.sAllPartsNameDefault, props.state.slaveData]);
  const boxModelList = sAllPartsName.split(",");
  const [activeKey, setActiveKey] = useState(0);

  useEffect(() => {
    if (!boxModelList.length) return;
    setActiveKey(0);
  }, [sAllPartsName]);
  useEffect(() => {
    props.setState(pre => ({
      ...pre,
      boxModelKey: activeKey,
    }));
  }, [activeKey]);
  const dividerProps = {
    className: styles.divider,
    orientation: "left",
    orientationMargin: "20px",
  };

  const onEdit = (targetKey, action) => {
    let tabValue = "";
    if (action === "add") {
      Modal.confirm({
        title: "请输入新标签名称：",
        content: (
          <Input
            onChange={e => {
              tabValue = e.target.value.trim();
            }}
          />
        ),
        // wrapClassName: styles.cardAdd,
        cancelText: "取消",
        okText: "确定",
        onOk() {
          if ([...boxModelList, ...extraPartsList].includes(tabValue)) {
            message.warning("标签名称已存在!");
            return;
          }

          extraPartsList.push(tabValue);
          props.setState(pre => ({
            ...pre,
            extraParts: {
              ...pre.extraParts,
              [showName]: extraPartsList,
            },
          }));
          setActiveKey(boxModelList.length - 1 + extraPartsList.length);
        },
        onCancel() { },
      });
    } else {
      extraPartsList.splice(targetKey - boxModelList.length, 1);
      props.setState(pre => ({
        ...pre,
        extraParts: {
          ...pre.extraParts,
          [showName]: extraPartsList,
        },
        calcPriceFinished: false,
        // manyData: [],
      }));
      setActiveKey(targetKey - 1);
    }
  };

  return (
    <>
      {/* <Divider {...dividerProps}>产品参数</Divider> */}
      <MasterComponent {...props} />
      <Tabs
        type="editable-card"
        activeKey={activeKey}
        onChange={key => {
          setActiveKey(key);
        }}
        onEdit={onEdit}
        hideAdd={bEmpty}
        className={`noXlyTabs ${styles.tabs}`}
        items={[...boxModelList, ...extraPartsList].map((boxModel, index) => {
          const boxProps = {
            ...props,
            dividerProps,
            boxModel,
          };

          return {
            label: boxModel,
            key: index,
            children: !bEmpty ? <BoxComponent {...boxProps} /> : "",
            closable: extraPartsList.includes(boxModel),
          };
        })}
      />
      <BackendParamsExtraComponent {...props} />
      <Divider {...dividerProps}>{manyqtysInfo}</Divider>
      <ManyComponent {...props} />
    </>
  );
};

// 主表组件
const MasterComponent = props => {

  const { masterConfig, masterData = {}, selectedNode = {} } = props.state;
  const { app } = props;
  
  if (!masterConfig) return "";

  const { userinfo } = app;
  const { sType } = userinfo;
  const bCustomer = sType === "Customer";

  const ableConfigs = masterConfig.gdsconfigformslave
    .filter(item => item.sName && item.bVisible)
    .map(item => {
      if (item.sName === "sCustomerName" && bCustomer) {
        return {
          ...item,
          iTag: 1,
        };
      } else {
        return item;
      }
    });
  const JosnAbleConfigs = JSON.parse(JSON.stringify(ableConfigs));
  const { sStripType = 0 } = selectedNode;
  const viewConfigs = Number(sStripType) === 0 ? JosnAbleConfigs : JosnAbleConfigs.filter(x => x.sName !== "dHeight");
  if (Number(sStripType) === 0) {
    viewConfigs.forEach(item => {
      if (item.sName === "dLength" || item.sName === "dWidth") {
        item.iColValue = 4;
      }
    });
  }
  const lengthData = viewConfigs.find(x => x.sName === "dLength");

  if (selectedNode && selectedNode.sTypeKey && selectedNode.sTypeKey !== "danye") {
    if (lengthData) {
      lengthData.showName = "高(D)";
      lengthData.sChinese = "高(D)";
      lengthData.sEnglish = "Height (D)";
      if (app.userinfo?.sLanguage === "sEnglish") {
        lengthData.showName = lengthData.sEnglish;
      }
    }
  } else {
    if (lengthData) {
      lengthData.showName = "长(L)";
      lengthData.sChinese = "长(L)";
      lengthData.sEnglish = "Length (L)";
      if (app.userinfo?.sLanguage === "sEnglish") {
        lengthData.showName = lengthData.sEnglish;
      }
    }
  }

  const viewProps = {
    ...props,
    viewConfigs: viewConfigs,
    tableConfig: masterConfig,
    iColValueView: 24,
    viewRow: { ...masterData, sProductClassifyId: selectedNode.sId },
    tableName: "master",
    extraContent: child => {
      if (child.sName === "sProductName") {
        return (
          <div className={styles.productNameBtns}>
            <Button
              type="link"
              icon={<UploadOutlined />}
              onClick={() => {
                const { slaveSelectedRowKeys } = props;
                if (commonUtils.isEmptyArr(slaveSelectedRowKeys)) {
                  message.warning("请先核价！");
                  return;
                }
                props.onToolBarBtnClick({ key: "BtnUpload" });
              }}
            ></Button>
          </div>
        );
      }
      return "";
    },
  };

  return (
    <div className={styles.viewTable}>
      <CommonViewTable {...viewProps} />
    </div>
  );
};

// 盒型组件
const BoxComponent = props => {

  const { dividerProps, state, boxModel } = props;
  const {
    masterData = {},
    slaveConfig,
    slaveData = [],
    selectedNode = {},
    downAbleConfigs = [],
    downAbleExtraConfigs = [],
    finishedConfigs = [],
    boxConfig = {},
  } = state;
  if (!slaveConfig) return "";

  const { bBox } = selectedNode;
  const [boxTypeList, setBoxTypeList] = useState([]);
  const sQuoConfig = commonUtils.convertStrToObj(props.masterData.sQuoConfig, {});
  // 卡牌类卷筒类默认使用矩形 当是核价保存过的需要在主表数据加载完后在赋值
  let slaveRowData = slaveData.find(item => item.sTreeNodeName === selectedNode.showName && item.sBoxModel === boxModel) || {};
  const { sBillNo } = slaveRowData;
  useEffect(() => {
    if (selectedNode.sTypeKey === "kapai" || selectedNode.sTypeKey === "juantong") {
      const { sBillNo } = slaveRowData;
      if (sBillNo) return;
      const getSqlDropDownData = async ({ sId, sSqlCondition = {} }, cb) => {
        const url = `${commonConfig.server_host}business/getSelectLimit/${sId}`;
        const body = {
          sKeyUpFilterName: "",
          pageNum: 1,
          pageSize: 1000,
          sSqlCondition,
        };
        const retrunData = await commonServices.postValueService(props.app.token, body, url);
        const dropDownData = retrunData.data?.dataset?.rows;
        if (dropDownData) {
          const box = dropDownData.find(box => box.sId === '17551384620004172929247856556500'); // Define 'box' here
          const boxData = dropDownData.map((itemBox, indexBox) => ({
            ...itemBox,
            iOrder: indexBox + 1,
          }));
          if (box) { // Check if 'box' exists before using it
            props.onDataChange("slaveUp" + boxModel, "sName", { sName: box.sName }, box.sId, boxData);
          }
        }
        // if (dropDownData && sAllPartsNameDefaultList.length) {
        //   sAllPartsNameDefaultList.forEach((item, index) => {
        //     const sPartNameList = item.sPartName?.split(",");
        //     if (sPartNameList && sPartNameList.length) {
        //       sPartNameList.forEach(sPartName => {
        //         const box = dropDownData.find(box => box.sId === '17551384620004172929247856556500'); // Define 'box' here
        //         const boxData = dropDownData.map((itemBox, indexBox) => ({
        //           ...itemBox,
        //           iOrder: indexBox + 1,
        //         }));
        //         if (box) { // Check if 'box' exists before using it
        //           props.onDataChange("slaveUp" + sPartName, "sName", { sName: box.sName }, box.sId, boxData);
        //         }
        //       });
        //     }
        //   });
        // }
      };

      getSqlDropDownData({
        sId: '17428091410008594700322758474000',
        sSqlCondition: { sProductClassifyId: selectedNode.sId },
      });
      // let dropDownData = [];
      // dropDownData.push(KapaiJson);
      // const boxData = (dropDownData || []).map((item, index) => ({
      //   ...item,
      //   iOrder: index + 1,
      // }));
      // props.onDataChange("slaveUp" + boxModel, "sName", { sName: KapaiJson.sName }, KapaiJson.sId, boxData);
    }
  }, [boxModel]);

  const { upAbleConfigsExtra = [], calcMethodData = [], boxPicData = [], radioValue = calcMethodData[0]?.sCode } = slaveRowData;
  const calcMethod = calcMethodData.map(item => ({
    value: item.sCode,
    label: item.showName,
  }));

  const showUpAbleConfigsExtra = upAbleConfigsExtra.filter(x => x.bVisible === 1);
  const upAbleConfigs = [
    ...slaveConfig.gdsconfigformslave.filter(item => item.iTag === 10).filter(item => (bBox ? true : item.sName !== "sName")),
    ...showUpAbleConfigsExtra,
  ];
  showUpAbleConfigsExtra.forEach(item => {
    if (item.sTypes && item.sTypes.includes('09')) {
      if (item.sName === 'dZTBW' || item.sName === 'dYTBW') {
        slaveRowData[item.sName] = (item.iSLength ? Number(item.iSLength) : 0) + (item.iCLength ? Number(item.iCLength) : 0)
        item.sDefault = (item.iSLength ? Number(item.iSLength) : 0) + (item.iCLength ? Number(item.iCLength) : 0)
      } else {
        slaveRowData[item.sName] = (item.iSWidth ? Number(item.iSWidth) : 0) + (item.iCWidth ? Number(item.iCWidth) : 0)
        item.sDefault = (item.iSWidth ? Number(item.iSWidth) : 0) + (item.iCWidth ? Number(item.iCWidth) : 0)
      }
    }
  })
  const upAbleConfigsList = upAbleConfigs
    .map(item =>
      item.sTypes?.includes('09')
        ? ['iSLength', 'iSWidth', 'iCLength', 'iCWidth'].map((key, idx) => ({
          ...item,
          sName: item.sName + key,
          sDefault: item[key],
          showName: item.showName + ['1长', '1宽', '2长', '2宽'][idx],
          sId: item.sId + idx
        }))
        : [item] // 非 '09' 也要包一层数组，保持结构一致
    )
    .flat();   // 把二维数组拍平成一维
  const type = upAbleConfigs.find(item =>
    item?.sTypes && item.sTypes.includes('09')
  );
  const upViewProps = {
    ...props,
    viewConfigs: upAbleConfigsList,
    tableConfig: { ...slaveConfig, gdsconfigformslave: upAbleConfigsList },
    iColValueView: 24,
    viewRow: slaveRowData,
    tableName: `slaveUp${boxModel}`,
  };


  const getUpViewPropsByITag = iTag => {
    const config = slaveConfig.gdsconfigformslave
      .filter(item => !["sPrint", "sColor", "iPrintModePo"].includes(item.sName))
      .filter(item => {
        if (item.sName === "dSumPQty" && selectedNode.sTypeKey !== "huace") {
          return false;
        }
        const { bAdvancedSetting, bFlap, bFold } = slaveRowData;
        const shouldExcludeItem = (condition, itemNameList) => !condition && itemNameList.includes(item.sName);
        if (selectedNode.showName === "封套") {
          slaveRowData.bFold = true;
        }
        if (
          shouldExcludeItem(bAdvancedSetting, ["dPortrait", "dHorizontal"]) ||
          shouldExcludeItem(bFlap, ["dFlap"]) ||
          shouldExcludeItem(bFold, ["sFold", "dAdhesive", "dFold"])
        ) {
          return false;
        }
        if (Number(selectedNode.iRateType) === 0 && item.sName === "iPage") {
          return false;
        } else {
          if (item.sName === "iPage") {
            const rateList = JSON.parse(slaveConfig.gdsconfigformslave.find(x => x.sName === "iRateType")?.showDropDown) || [];
            item.showName = rateList[Number(selectedNode.iRateType)] || "倍率";
          }
        }

        if (item.sName === "dWlcd" && selectedNode.sTypeKey === "juantong") {
          return false;
        }
        if (item.sName === "dAuxiliaryQty" && selectedNode.sTypeKey !== "juantong") {
          return false;
        }
        if (item.sName === "dWlkd") {
          if (selectedNode.sTypeKey === "juantong") {
            const FabricWidth = commonFunc.showLocalMessage(props, "FabricWidth", "门幅");
            item.showName = FabricWidth;
          } else {
            const MaterialWidth = commonFunc.showLocalMessage(props, "MaterialWidth", "材料宽");
            item.showName = MaterialWidth;
          }
        }
        if (item.sName === "sPaperDirection" && selectedNode.sTypeKey === "huace") {
          return false;
        }

        // 判断bPartsDimension 是否显示展长展宽，0不显示，1显示

        if (selectedNode.bPartsDimension === false && (item.sName === "dPartsLength" || item.sName === "dPartsWidth")) {
          return false;
        }

        if (!selectedNode.bBleed && item.sName === "dBleed") {
          return false;
        }
        if (selectedNode.sTypeKey !== "juantong" && item.sName === "sPaperDirection") {
          return false;
        }
        if ((selectedNode.showName === "封套" && item.sName === "dSpine") || (selectedNode.showName === "封套" && item.sName === "bFlap")) {
          return false;
        }

        return item.iTag === iTag;
      });

    let boxConfigList = [];
    if (iTag === 20) {
      let showNameKeyList = ["dZBLB", "dSBLB", "dYBLB", "dXBLB", "dZBJJ", "dYBJJ", "dSBJJ", "dXBJJ"];
      if (selectedNode.sTypeKey === "juantong") {
        showNameKeyList = ["dSBLB", "dZBJJ", "dYBJJ", "dSBJJ", "dXBJJ"];
      }
      const UlToolPosition = commonFunc.showLocalMessage(props, "UlToolPosition", "上下刀位");
      const RLToolPosition = commonFunc.showLocalMessage(props, "RLToolPosition", "左右刀位");
      const LeftMargin = commonFunc.showLocalMessage(props, "LeftMargin", "左右留白");
      const StayOnTheEdge = commonFunc.showLocalMessage(props, "StayOnTheEdge", "留边");
      const Spacing = commonFunc.showLocalMessage(props, "Spacing", "间距");
      const HopDistance = commonFunc.showLocalMessage(props, "HopDistance", "跳距");
      boxConfigList = boxConfig?.gdsconfigformslave?.filter(item => item.bVisible && showNameKeyList.includes(item.sName)) || [];
      if (selectedNode.sTypeKey === "juantong") {
        const mappings = {
          dZBLB: StayOnTheEdge,
          dXBJJ: Spacing,
          dYBJJ: HopDistance,
        };

        boxConfigList.forEach(item => {
          if (mappings[item.sName]) {
            item.showName = mappings[item.sName];
          }
        });
      } else {
        const mappings = {
          dZBLB: LeftMargin,
          dXBJJ: UlToolPosition,
          dYBJJ: RLToolPosition,
        };

        boxConfigList.forEach(item => {
          if (mappings[item.sName]) {
            item.showName = mappings[item.sName];
          }
        });
      }
    }
    const newConfig = [...boxConfigList, ...config];

    return {
      ...props,
      viewConfigs: newConfig,
      tableConfig: { ...slaveConfig, gdsconfigformslave: newConfig },
      iColValueView: 24,
      viewRow: { ...slaveRowData, sProductClassifyId: selectedNode.sId },
      tableName: `slaveUp${boxModel}`,
    };
  };

  // 材料信息表单
  // const upViewProps11 = getUpViewPropsByITag(11);
  // 印刷参数表单
  let upViewProps12 = getUpViewPropsByITag(12);
  const filterConditions = {
    juantong: x =>
      x.sName === "iPage" ||
      x.sName === "dPartsLength" ||
      x.sName === "dPartsWidth" ||
      x.sName === "dRowGap" ||
      x.sName === "dColGap" ||
      x.sName === "dBleed" ||
      x.sName === "sPaperDirection",
    default: x =>
      x.sName === "sPaperDirection" ||
      x.sName === "dBleed" ||
      x.sName === "iPage" ||
      x.sName === "dPartsLength" ||
      x.sName === "dPartsWidth" ||
      x.sName === "dSumPQty",
  };
  if (selectedNode.sTypeKey === "juantong") {
    upViewProps12.viewConfigs = upViewProps12.viewConfigs.filter(filterConditions.juantong);
  }
  if (!(selectedNode.sTypeKey === "huace" && slaveRowData.sBoxModel === "封面")) {
    upViewProps12.viewConfigs = upViewProps12.viewConfigs.filter(filterConditions.default);
  }

  // 拼板信息表单
  let upViewProps20 = getUpViewPropsByITag(20);
  
  // 如果是卷筒类需要单独处理

  const { sBackProcessData = [] } = slaveRowData;

  const downAbleConfigsNew = downAbleConfigs.reduce((pre, cur) => {
    const childConfigs = downAbleExtraConfigs.filter(item => item.sParentName === cur.showName);
    pre.push(cur, ...childConfigs);
    return pre;
  }, []);

  // 获取sType为2的
  const downViewProps = {
    ...props,
    viewConfigs: downAbleConfigsNew
      .filter(item => item.sPartsName === boxModel || !item.sPartsName)
      .map(config => ({
        ...config,
        costomStyle: sBackProcessData.find(item => item[config.sName])?.sParamConfig ? styles.sParamConfig : "",
      })),
    tableConfig: { ...slaveConfig, gdsconfigformslave: downAbleConfigsNew },
    iColValueView: 24,
    viewRow: slaveRowData,
    getViewRow: config => {
      return sBackProcessData.find(item => item[config.sName]) || {};
    },
    tableName: `slaveDown${boxModel}`,
    getSqlDropDownData: (...args) => {
      const showConfig = args[2];
      const { sChineseDropDown, sId } = showConfig;
      const dropDownData = commonUtils.convertStrToObj(sChineseDropDown, []);
      if (dropDownData?.length) {
        return {
          dropDownData: dropDownData.map(item => ({
            ...item,
            sProductClassifyId: sId,
          })),
          totalPageCount: 1,
          currentPageNo: 1,
          conditonValues: {},
        };
      }

      return props.getSqlDropDownData(...args);
    },
    extraContent: child => {
      const value = sBackProcessData.find(item => item[child.sName]) || {};
      const { bSetArea, bSetQty, sName, sSetQtyUnt } = value;

      const viewConfigs = [];
      if (bSetArea) {
        viewConfigs.push({
          sName: "dManualLength",
          showName: "x",
          iColValue: bSetQty ? 8 : 12,
          placeholder: "长",
        });
        viewConfigs.push({
          sName: "dManualWidth",
          showName: "mm",
          iColValue: bSetQty ? 8 : 12,
          placeholder: "宽",
        });
      }
      if (bSetQty) {
        viewConfigs.push({
          sName: "dManualQty",
          showName: sSetQtyUnt || "",
          iColValue: bSetArea ? 8 : 24,
          placeholder: "数量",
        });
      }

      const viewProps = {
        ...props,
        viewConfigs: viewConfigs,
        tableConfig: { ...slaveConfig, gdsconfigformslave: viewConfigs },
        iColValueView: 24,
        viewRow: value,
        tableName: `slaveDown${boxModel}${sName}`,
        onDataChange: (name, sFieldName, changeValue, sId, dropDownData, isWait) => {
          const iIndex = slaveData.findIndex(item => item.sId === slaveRowData.sId);
          const iIndex1 = slaveData[iIndex].sBackProcessData.findIndex(item => item[child.sName]);
          slaveData[iIndex].sBackProcessData[iIndex1][sFieldName] = changeValue[sFieldName];
          const { dManualLength, dManualWidth } = slaveData[iIndex].sBackProcessData[iIndex1];
          if (dManualLength !== undefined && dManualWidth !== undefined) {
            slaveData[iIndex].sBackProcessData[iIndex1].dManualValue = dManualLength * dManualWidth;
          }
          props.setState(pre => ({ ...pre, slaveData }));
        },
      };

      return viewConfigs.length ? (
        <div className={styles.subViewTable}>
          <CommonViewTable {...viewProps} />
        </div>
      ) : (
        ""
      );
    },
    extraContent2: child => {
      return (
        <div className={styles.downOperations}>
          {!child.sParentName ? (
            <Button
              icon={<PlusOutlined />}
              type="primary"
              onClick={() => {
                props.setState(pre => {
                  const newSId = commonUtils.createSid();
                  const newConfig = {
                    ...child,
                    sId: newSId,
                    sParentName: child.showName,
                    sName: `${child.sName}_${newSId}`,
                  };
                  return {
                    ...pre,
                    downAbleExtraConfigs: [...downAbleExtraConfigs, newConfig],
                  };
                });
              }}
            />
          ) : (
            <Button
              icon={<MinusOutlined />}
              type="primary"
              danger
              onClick={() => {
                props.setState(pre => {
                  const iIndex = downAbleExtraConfigs.findIndex(item => item.sId === child.sId);

                  const slaveRowIndex = slaveData.findIndex(item => item.sId === slaveRowData.sId);
                  const { sBackProcessData = [] } = slaveData[slaveRowIndex];
                  const iIndex1 = sBackProcessData.findIndex(item => item[child.sName]);
                  slaveData[slaveRowIndex].sBackProcessData?.splice(iIndex1, 1);
                  return {
                    ...pre,
                    downAbleExtraConfigs: [...downAbleExtraConfigs.slice(0, iIndex), ...downAbleExtraConfigs.slice(iIndex + 1)],
                    slaveData,
                  };
                });
              }}
            />
          )}
        </div>
      );
    },
    onCostomClick: (showConfig, { target }) => {
      const className = target.getAttribute("class");
      const nodeName = target.nodeName;
      if (className?.includes("select") && nodeName === "DIV") return;

      props.setState(pre => ({
        ...pre,
        backendParamsConfig: commonUtils.convertStrToObj(sBackProcessData.find(item => item[showConfig.sName])?.sParamConfig, []),
        backendConfig: { sParentFieldsName: showConfig.sName, sBoxModel: boxModel },
      }));
    },
  };

  // 获取sType为3的
  const { productProcessInfo = [] } = masterData;
  const finishedViewProps = {
    ...props,
    viewConfigs: finishedConfigs.map(config => ({
      ...config,
      costomStyle: productProcessInfo.find(item => item[config.sName])?.sParamConfig ? styles.sParamConfig : "",
    })),
    tableConfig: { ...slaveConfig, gdsconfigformslave: finishedConfigs },
    iColValueView: 24,
    viewRow: { ...masterData, sId : masterData.sId || "123" },
    getViewRow: config => {
      return productProcessInfo.find(item => item[config.sName]) || {};
    },
    tableName: "finished",
    getSqlDropDownData: (...args) => {
      const showConfig = args[2];
      const { sChineseDropDown, sId } = showConfig;
      const dropDownData = commonUtils.convertStrToObj(sChineseDropDown, []);
      if (dropDownData?.length) {
        return {
          dropDownData: dropDownData.map(item => ({
            ...item,
            sProductClassifyId: sId,
          })),
          totalPageCount: 1,
          currentPageNo: 1,
          conditonValues: {},
        };
      }

      return props.getSqlDropDownData(...args);
    },
    onCostomClick: (showConfig, { target }) => {
      const className = target.getAttribute("class");
      const nodeName = target.nodeName;
      if (className?.includes("select") && nodeName === "DIV") return;

      props.setState(pre => ({
        ...pre,
        backendParamsConfig: commonUtils.convertStrToObj(productProcessInfo.find(item => item[showConfig.sName])?.sParamConfig, []),
        backendConfig: { sParentFieldsName: showConfig.sName },
      }));
    },
  };

  const boxProps = {
    ...props,
    slaveRowData,
    dSBJJ: slaveRowData.dXBJJ,
    dZBJJ: slaveRowData.dYBJJ,
    radioValue: calcMethodData.find(item => item.sCode === radioValue),
    boxPicData,
  };

  const [materialLength, setMaterialLength] = useState(0);
  const [materialWidth, setMaterialWidth] = useState(0);

  // 使用 防抖防止输出数据错误
  const debounceTimer = useRef(null);

  const debouncedHandleSaveState = useCallback(
    (...args) => {
      clearTimeout(debounceTimer.current);
      debounceTimer.current = setTimeout(() => {
        handleSaveState(...args);
      }, 500);
    },
    [handleSaveState]
  );
  const handleSaveState = (
    length,
    width,
    slaveData,
    masterData,
    dSinglePQty,
    dMaterialsKQty,
    dProductQty,
    scale,
    dWlcd,
    dWlkd,
    innerWidth,
    innerHeight,
    dHorizontal,
    dPortrait,
    dHorizontalType,
    dPortraitType
  ) => {
    // 查找符合条件的索引
    const { selectedNode } = props.state;
    const index = slaveData?.findIndex(x => x.sTreeNodeName === selectedNode.showName && x.sBoxModel === props.boxModel);
   
    if (index !== undefined && index !== -1) {
      // 计算开数
      // 获取原始对象并创建一个新的对象进行更新
      const updatedProduct = {
        ...slaveData[index],
        materialLength: dWlcd,
        materialWidth: dWlkd,
        dMachineLength: dWlcd, // 上机长
        dMachineWidth: dWlkd, // 上机宽
        sMaterialsStyle: `${slaveData[index]?.dWlcd || dWlcd}*${slaveData[index]?.dWlkd || dWlkd}`, // 原纸尺寸
        sMachineStyle: `${length || slaveData[index].materialLength}*${width || slaveData[index].materialWidth}`, // 开料尺寸为计算的排版尺寸
        sMaterialRate: (((length * width) / ((slaveData[index].dWlcd || dWlcd) * (slaveData[index].dWlkd || dWlkd))) * 100).toFixed(2),
        newMaterialLength: dWlcd,
        newMaterialWidth: dWlkd,
        sLayoutRate: Number(
          (
            (((length || slaveData[index].materialLength) * (width || slaveData[index].materialWidth)) /
              (slaveData[index].dMaxLength * slaveData[index].dMaxWidth)) *
            100
          ).toFixed(2)
        ),
        // dWlcd: selectedNode.sTypeKey === 'juantong' ? Math.floor(dProductQty / dSinglePQty * ( length/ 1000)) : dWlcd,
        dWlcd: sBillNo ? slaveData[index]?.dWlcd : dWlcd,
        dWlkd: sBillNo ? slaveData[index]?.dWlkd : dWlkd,
        dAuxiliaryQty: Math.floor((dProductQty / dSinglePQty) * (length / 1000)),
        dMachineQty: sBillNo && slaveData[index].dMachineQty ? slaveData[index].dMachineQty : Math.floor(dProductQty / dSinglePQty),
        dSinglePQty: dSinglePQty,
        dMaterialsKQty: dMaterialsKQty,
        scale: scale,
        dPartsLength: innerWidth,
        dPartsWidth: innerHeight,
        dHorizontal: dHorizontalType,
        dPortrait: dPortraitType,
        dHorizontalType: dHorizontalType, // 判断
        dPortraitType: dPortraitType,
      };
      let juantongConfig = {};

      if (selectedNode.sTypeKey === "juantong") {
        const { dYBJJ, dXBJJ, dZBLB } = slaveData[index];
        juantongConfig = {
          dColGap: dYBJJ,
          dRowGap: dXBJJ,
          iCol: dPortraitType,
          iRow: dHorizontalType,
          dCutEdge: dZBLB,
        };
      }
      const newSlaveData = {
        ...updatedProduct,
        ...juantongConfig,
      };
      // 更新状态
      setTimeout(() => {
        props.setState(prevState => ({
          ...prevState,
          slaveData: slaveData.map((item, i) => (i === index ? newSlaveData : item)),
        }));
      }, 200);
    }

    setMaterialLength(length);
    setMaterialWidth(width);
  };

  const onSaveDPartsLength = useCallback((innerWidth, innerHeight, slaveData) => {
    const { selectedNode } = props.state;
    const index = slaveData?.findIndex(x => x.sTreeNodeName === selectedNode.showName && x.sBoxModel === props.boxModel);
    if (index !== undefined && index !== -1) {
      const updatedProduct = {
        ...slaveData[index],
        dPartsLength: innerWidth,
        dPartsWidth: innerHeight,
        materialLength: 0,
        materialWidth: 0,
        dMachineLength: 0, // 上机长
        dMachineWidth: 0, // 上机宽
        newMaterialLength: 0,
        newMaterialWidth: 0,
        sLayoutRate: 0,
        dWlcd: 0,
        dWlkd: 0,
        dMachineQty: 0,
        dSinglePQty: 0,
        dMaterialsKQty: 0,
        scale: 1,
      };
      props.setState(prevState => ({
        ...prevState,
        slaveData: slaveData.map((item, i) => (i === index ? updatedProduct : item)),
      }));
    }
  }, []);
  const showImgMProps = {
    ...props,
    materialLength,
    materialWidth,
    bBox: true, // 快速报价盒型展示
  };

  let boxList = [];
  const { sStripType = 0 } = selectedNode;
  
  if (
    (slaveRowData.sColumnNameConfig && masterData.dLength && masterData.dWidth && masterData.dHeight) ||
    (Number(sStripType) === 1 && slaveRowData.sColumnNameConfig && masterData.dLength && masterData.dWidth) ||
    slaveRowData.sName === "卡牌"
  ) {
    const slaveNewData = slaveRowData.upAbleConfigsExtra || JSON.parse(slaveRowData.sColumnNameConfig);
    const slaveRowDatas =  sBillNo ? sQuoConfig?.slaveData?.find(item => item.sTreeNodeName === selectedNode.showName && item.sBoxModel === boxModel) || {} :  slaveRowData;
    const tables = [
      { name: "盒型类别", value: slaveRowData.sBoxType, type: null },
      { name: "盒身", value: slaveRowData.sBoxBody, type: slaveRowData.sTypes },
      { name: "盒长", value: slaveRowData.dL ? slaveRowData.dL : masterData.dLength ? Number(masterData.dLength) : 0, type: null },
      { name: "盒宽", value: slaveRowData.dW ? slaveRowData.dW : masterData.dWidth ? Number(masterData.dWidth) : 0, type: null },
      { name: "盒高", value: slaveRowData.dD ? slaveRowData.dD : masterData.dHeight ? Number(masterData.dHeight) : 0, type: null },
    ];
    const titleList1 = [
      { name: "上方盒舌", value: "dSFHS" },
      { name: "盒底组件", value: "dHDC" },
      { name: "下方盒舌", value: "dXFHS" },
      { name: "左(上)插位组件", value: "dZSCW" },
      { name: "左贴边位", value: "dZTBW" },
      { name: "左(下)插位组件", value: "dZXCW" },
      { name: "右(上)插位组件", value: "dYSCW" },
      { name: "右贴边位", value: "dYTBW" },
      { name: "右(下)插位组件", value: "dYXCW" },
    ];
    const evaluateFormula = (formula, variables) => {
      if (!formula) return 0; // 如果公式为空，返回0
      try {
        // 提取公式中的变量名
        const variableNames = formula.match(/\b[a-zA-Z_][a-zA-Z0-9_]*\b/g) || [];
        // 构建函数参数
        const params = variableNames.join(",") + ",Math";
        // 替换公式中的变量为实际值
        const func = new Function(params, `return ${formula}`);
        // 提取变量值
        const args = variableNames.map(name => Number(variables[name]) || 0);
        // 执行函数并返回结果
        return func(...args, Math);
      } catch (error) {
        console.error("公式执行错误:", error);
        return 0;
      }
    };

    // 确认是竖向排列还是横向排列
    const L = masterData?.dLength || 0;
    const W = masterData?.dWidth || 0;
    const H = masterData?.dWidth || 0;
    const D = masterData?.dHeight || 0;
    const variables = {
      L,
      W,
      H,
      D,
      ...slaveRowData,
    };
    slaveNewData.forEach(item => {
      item.iSLength = slaveRowData[item.sName + 'iSLength']
      item.iCLength = slaveRowData[item.sName + 'iCLength']
      item.iSWidth = slaveRowData[item.sName + 'iSWidth']
      item.iCWidth = slaveRowData[item.sName + 'iCWidth']
    })
    slaveNewData.forEach(x => {
      let key = 0;
      if (x.sAssignFormula) {
        key = evaluateFormula(x.sAssignFormula, variables);
        slaveRowData[x.sName] = key;
      } else {
        if (x.sTypes && x.sTypes.includes('09')) {
          if (x.sName === 'dZTBW' || x.sName === 'dYTBW') {
            key = (x.iSLength ? Number(x.iSLength) : 0) + (x.iCLength ? Number(x.iCLength) : 0)
          } else {
            key = (x.iSWidth ? Number(x.iSWidth) : 0) + (x.iCWidth ? Number(x.iCWidth) : 0)
          }
        } else {
          key = slaveRowData[x.sName];
        }
      }
      boxList.push({
        value: key,
        sName: titleList1.find(item => item.value === x.sName)?.name || "",
        isEditable: true,
        isSelect: false,
        selectValue: null,
        selectLabel: "",
        selectImage: null,
        type: x.sTypes || null,
        show: true,
        showName: x.showName, // 参数名称
        sLength: x.iSLength,
        sWidth: x.iSWidth,
        sType: x.iSType,
        sTypeName: Number(x.iSType) === 0 ? "矩形" : "梯形",
        sOffset: x.sSOffset,
        sQuantity: x.iSQuantity,
        cLength: x.iCLength,
        cWidth: x.iCWidth,
        cType: x.iCType,
        cTypeName: Number(x.iCType) === 0 ? "矩形" : "梯形",
        cOffset: x.sCOffset,
        cQuantity: x.iCQuantity,
      });
    });
    tables.forEach(x => {
      boxList.push({
        value: x.value,
        sName: x.name,
        isEditable: true,
        isSelect: false,
        selectValue: null,
        selectLabel: "",
        selectImage: null,
        type: x.type || null,
        show: true,
        showName: x.name, // 参数名称
      });
    });
  }

  const svgProps = {
    ...props,
    boxList,
    dSvgBoxWidth: 300,
    dSvgBoxHeight: 200,
    showNew: 1,
  };
  // upViewProps.viewRow =

  const isShowImg = boxList.find(x => x.sName === "盒身")?.type !== "" || false;
  const PrintingParameters = props.getI18nName("PrintingParameters", "印刷参数");

  const BoxInformation = commonFunc.showLocalMessage(props, "Box-typeInformation", "盒型信息");
  const ImpositionInformation = commonFunc.showLocalMessage(props, "ImpositionInformation", "拼版信息");

  const noImage = commonFunc.showLocalMessage(props, "ImpositionInformation", "暂无图片");
  const removeExtension = (filename) => {
    if (!filename) return
    const lastDotIndex = filename.lastIndexOf('.');
    if (lastDotIndex === -1) {
      // 如果字符串中没有点，则返回原字符串
      return filename;
    }
    return filename.substring(0, lastDotIndex);
  }
  const getImageUrl = (sName) => {
    const imageUrlNew = `${commonConfig.server_host}file/downloadPrice?sLogoName=${sName}&date=${new Date().getTime()}`;
    return imageUrlNew;
  };
  
  let imagesData = useMemo(() => {
    if (!slaveRowData) return [];
    return [
      { src: getImageUrl(removeExtension(slaveRowData.sPackDetailPathUpLoad)), alt: "展开图" },
      { src: getImageUrl(removeExtension(slaveRowData.sPackPath)), alt: "立体图" },
    ];
  }, [slaveRowData?.sPackDetailPathUpLoad, slaveRowData?.sPackPath]);
  if (!slaveRowData.sPackDetailPathUpLoad) {
    imagesData = [{ src: getImageUrl(removeExtension(slaveRowData.sPackPath)), alt: "立体图" }];
  } else if (!slaveRowData.sPackPath) {
    imagesData = [{ src: getImageUrl(removeExtension(slaveRowData.sPackPath)), alt: "立体图" }];
  }
  const { activeKey = 0 } = state;
  useEffect(() => {
    props.setState(pre => {
      return { ...pre, activeKey: 0 };
    });
  }, [selectedNode]);
  return (
    <Tabs
      key={boxModel}
      type="card"
      activeKey={activeKey}
      className={`noXlyTabs ${styles.tabs} ${!bBox ? styles.hideTab : ""}`}
      items={[BoxInformation, ImpositionInformation].map((title, index) => {
        return {
          label: title,
          key: index,
          forceRender: true,
          children: (() => {
            let result = "";

            const cailiaoyinshuaDiv = (
              <>
                <Divider {...dividerProps} orientationMargin="10px">
                  {PrintingParameters}
                </Divider>
                <div className={styles.viewTable1}>
                  <PrintParamsComponent {...props} />
                  <div className={styles.materialsLine}>
                    <div className={styles.materialsViewTable} key={state.slaveUpKey}>
                      <CommonViewTable {...upViewProps12} />
                    </div>
                    <div className={styles.materialsBtns} style={{ width: "10%", height: "30px" }}></div>
                  </div>
                  {/* <CommonViewTable {...upViewProps12} /> */}
                </div>
                {/* <Divider {...dividerProps} orientationMargin="10px">
                  材料信息
                </Divider> */}
                <div className={styles.viewTable1}>
                  <MaterialsComponent {...props} slaveRowData={slaveRowData} boxModel={boxModel} />
                  {/* <CommonViewTable {...upViewProps11} /> */}
                </div>
              </>
            );

            const calcMethodDiv = (
              <div className={styles.boxRadio}>
                <Radio.Group
                  size="large"
                  onChange={e => {
                    const iIndex = slaveData.findIndex(item => item.sId === slaveRowData.sId);
                    slaveData[iIndex].radioValue = e.target.value;
                    slaveData[iIndex].bAdvancedSetting = false;
                    props.setState(pre => ({
                      ...pre,
                      slaveData: [...slaveData],
                      activeKey: 1,
                      calcPriceFinished: false,
                    }));
                  }}
                  value={radioValue}
                >
                  {calcMethod.map(item => (
                    <Radio value={item.value}>{item.label}</Radio>
                  ))}
                </Radio.Group>
              </div>
            );

            if (index === 0) {
              result = (
                <>
                  <div className={styles.boxPart1}>
                    <div className={styles.boxPart1Left}>
                      <div className={styles.viewTable1}>
                        {!(selectedNode.sTypeKey === "kapai" || selectedNode.sTypeKey === "juantong") ? <div>
                          <CommonViewTable {...upViewProps} />
                        </div> : ""}
                      </div>
                      {cailiaoyinshuaDiv}
                    </div>
                    <div className={styles.boxPart1Right}>
                      <div className={styles.boxRreview}>
                        <Image.PreviewGroup>
                          {bBox ? (
                            <>
                              {svgProps.boxList.length ? (
                                <div
                                  style={{
                                    width: " 300px",
                                    height: "290px",
                                    backgroundColor: "#fff",
                                    borderRight: "1px solid #ccc",
                                    position: "relative",
                                  }}
                                >
                                  <div
                                    style={{
                                      position: "absolute",
                                      left: "50%",
                                      top: "50%",
                                      transform: " translate(-50%, -50%)",
                                      width: "100%",
                                      height: "200px",
                                      margin:0
                                    }}
                                  >
                                    <DynamicSVG {...svgProps} />
                                  </div>
                                </div>
                              ) : (
                                <div className={styles.noImg}>{noImage}</div>
                              )}
                            </>
                          ) : (
                            ""
                          )}
                          {slaveRowData.sPackPath ? (
                            <div style={{ width: "300px", height: "300px" }}>
                              <Carousel dots style={{ width: "300px", height: "300px" }}>
                                {imagesData.map((image, index) => (
                                  <div key={index} className="carousel-item">
                                    <Image src={image.src} alt={image.alt} style={{ width: "300px", height: "290px" }} />
                                  </div>
                                ))}
                              </Carousel>
                            </div>
                          ) : selectedNode.sTypeKey === "kapai" || selectedNode.sTypeKey === "juantong" ? (
                            <Carousel dots style={{ width: "300px", height: "300px" }}>
                              {imagesData.map((image, index) => (
                                  <div key={index} className="carousel-item">
                                    <Image src={image.src} alt={image.alt} style={{ width: "300px", height: "290px" }} />
                                  </div>
                                ))}
                            </Carousel>
                          ) : (
                            <div className={styles.noImg}>{noImage}</div>
                          )}
                        </Image.PreviewGroup>
                      </div>
                      {calcMethodDiv}
                    </div>
                  </div>
                </>
              );
            } else {
              result = (
                <div className={styles.boxPinbanInfo}>
                  <div>
                    <div className={styles.viewTable}>
                      <CommonViewTable {...upViewProps20} />
                    </div>
                    {cailiaoyinshuaDiv}
                  </div>
                  <div>
                    <div style={{ width: "600px", height: "300px" }}>
                      <div className={styles.boxComponent}>
                        <Typesetting {...boxProps} onSaveStates={debouncedHandleSaveState} onSaveDPartsLength={onSaveDPartsLength} />
                      </div>
                      <div className={styles.boxComponent1}>
                        <ShowImgM {...showImgMProps} />
                      </div>
                    </div>
                    {calcMethodDiv}
                  </div>
                </div>
              );
            }

            return (
              <>
                {result}
                {downAbleConfigs.length ? (
                  <>
                    {/* <Divider {...dividerProps}>后道参数</Divider> */}
                    <div className={styles.boxPart2}>
                      <div className={`${styles.viewTable} ${styles.viewTableDownView}`}>
                        <CommonViewTable {...downViewProps} />
                      </div>
                    </div>
                  </>
                ) : (
                  ""
                )}
                {finishedConfigs.length ? (
                  <>
                    {/* <Divider {...dividerProps}>成品工序</Divider> */}
                    <div className={styles.boxPart2}>
                      <div className={`${styles.viewTable} ${styles.viewTableDownView1}`}>
                        <CommonViewTable {...finishedViewProps} />
                      </div>
                    </div>
                  </>
                ) : (
                  ""
                )}
              </>
            );
          })(),
        };
      })}
      onChange={activeKey => {
        // 切换事件的处理逻辑
        // const index = slaveData?.findIndex(x => x.sTreeNodeName === selectedNode.showName && x.sBoxModel === boxModel);
        // if (index !== -1) {
        //   slaveData[index].dMaxLength = Number(selectedNode.sMachineStyle.split("*")[0]);
        //   slaveData[index].dMaxWidth = Number(selectedNode.sMachineStyle.split("*")[1]);
        // }
        // 可以在这里执行其他操作，比如根据 activeKey 加载数据
        props.setState(pre => {
          return { ...pre, activeKey };
        });
      }}
    />
  );
};

// 印刷参数组件（印刷、颜色、单双面）
const PrintParamsComponent = props => {
  const { state, setState, boxModel } = props;
  const { slaveConfig, slaveData, selectedNode } = state;

  const slaveRowData = slaveData.find(item => item.sTreeNodeName === selectedNode.showName && item.sBoxModel === boxModel) || {};
  const slaveRowDataIndex = slaveData.findIndex(item => item.sId === slaveRowData.sId);
  const { sBackProcessData = [] } = slaveRowData;
  const printParams = sBackProcessData.filter(item => item.bPrintParams);

  const printParamsConfig = slaveConfig.gdsconfigformslave
    .filter(item => ["sPrint", "sColor", "iPrintModePo"].includes(item.sName))
    .map(item => {
      return {
        ...item,
        iColValue: 8,
      };
    });

  const result = [];
  for (let i = 0; i < printParams.length + 1; i++) {
    const printParamsItem = printParams[i - 1];
    const viewRow = { ...(i === 0 ? slaveRowData : printParamsItem), sProductClassifyId: selectedNode.sId };

    const viewTableId = "viewTableId_" + viewRow.sId;
    const viewProps = {
      ...props,
      viewConfigs: printParamsConfig.map(item => ({ ...item, costomStyle: `xlyPrintParams${i}` })),
      tableConfig: { ...slaveConfig, gdsconfigformslave: printParamsConfig },
      iColValueView: 24,
      viewRow,
      tableName: `${i === 0 ? "slaveUp" : "slaveDown"}${boxModel}`,
      onDataChange: (...args) => {
        setTimeout(() => {
          const oLabel = document.querySelector(`#${viewTableId}`)?.querySelector(`.xlyPrintParams${i}`)?.querySelector(".ant-form-item-label");
          oLabel?.click();
        }, 200);
        if (i === 0) {
          props.onDataChange(...args);
          return;
        }

        const iIndex = sBackProcessData.findIndex(item => item.sId === printParamsItem.sId);
        sBackProcessData[iIndex] = { ...sBackProcessData[iIndex], ...args[2] };
        slaveData[slaveRowDataIndex] = { ...slaveRowData, sBackProcessData };
        setState(pre => {
          return { ...pre, slaveData };
        });
      },
      onCostomClick: (showConfig, { target }) => {
        if (showConfig.sName !== "sPrint") return;
        const className = target.getAttribute("class");
        const nodeName = target.nodeName;
        if (className?.includes("select") && nodeName === "DIV") return;

        const { sPrintConfig } = state;

        if (!sPrintConfig) return;
        const backendConfigNew = {
          sParentFieldsName: "sPrint",
          sBoxModel: boxModel,
          printParamsId: viewRow.sId,
        };

        const dropDownData = commonUtils.convertStrToObj(sPrintConfig.sChineseDropDown, []);
        const dropDownDataSelected = dropDownData.find(item => item.sId === viewRow.sProcessId);
        if (!dropDownDataSelected) {
          props.setState(pre => ({
            ...pre,
            backendParamsConfig: [],
            backendConfig: {},
          }));
          return;
        }
        const backendParamsConfigNew = commonUtils.convertStrToObj(dropDownDataSelected.sParamConfig, []);

        props.setState(pre => ({
          ...pre,
          backendParamsConfig: backendParamsConfigNew,
          backendConfig: backendConfigNew,
        }));
      },
    };
    result.push(
      <div className={styles.materialsLine}>
        <div className={styles.materialsViewTable} id={viewTableId}>
          <CommonViewTable {...viewProps} />
        </div>
        <div className={styles.materialsBtns} style={{ width: "10%" }}>
          <Button
            type="primary"
            icon={<PlusOutlined />}
            onClick={() => {
              const defaultData = commonFunc.getDefaultData({ ...slaveConfig, gdsconfigformslave: printParamsConfig }, { tree: selectedNode });
              sBackProcessData.push({
                sId: commonUtils.createSid(),
                bPrintParams: true,
                ...defaultData,
              });
              slaveData[slaveRowDataIndex] = { ...slaveRowData, sBackProcessData };
              setState(pre => {
                return { ...pre, slaveData };
              });
            }}
          />
          <Button
            type="primary"
            icon={<MinusOutlined />}
            onClick={() => {
              const iIndex = sBackProcessData.findIndex(item => item.sId === printParamsItem.sId);
              sBackProcessData.splice(iIndex, 1);
              slaveData[slaveRowDataIndex] = { ...slaveRowData, sBackProcessData };
              setState(pre => {
                return { ...pre, slaveData };
              });
            }}
            style={i === 0 ? { visibility: "hidden" } : {}}
          />
        </div>
      </div>
    );
  }
  return result;
};

// 材料组件
const MaterialsComponent = props => {
  const { state, slaveRowData, boxModel } = props;
  const { slaveConfig, slaveData = [], selectedNode = {}, manyData = [] } = state;
  const { sParam = "" } = selectedNode;
  const sParamList = sParam.split(",");
  const materialsInfoDefaultData = sParam ? new Array(sParamList.length).fill({}).map((_, index) => ({ showName: sParamList[index] })) : [{}];
  const { materialsInfo = materialsInfoDefaultData } = slaveRowData;

  const materialsConfig = slaveConfig.gdsconfigformslave
    .filter(item => item.iTag === 11)
    .map(item => {
      const { sName } = item;
      if (sName === "sMaterialsName") {
        return {
          ...item,
          sVisColumnName: "sMaterialsName",
          iColValue: 8,
        };
      } else if (sName === "dMaterialPrice") {
        return {
          ...item,
          iColValue: 8,
        };
      } else if (sName === "sComMaterials") {
        return {
          ...item,
          sName: "bComMaterials",
          iColValue: 8,
        };
      } else {
        return item;
      }
    });

  const extraState = {
    calcPriceFinished: false,
  };

  // if (manyData.some(item => Object.keys(item).length > 4)) {
  //   extraState.manyData = [];
  // }

  return materialsInfo.map((item, index) => {
    let viewRow = { ...materialsInfo[index], sProductClassifyId: selectedNode.sId, sId: selectedNode.sId };
    viewRow = { ...viewRow, sMaterialsName0: viewRow.showName || "" };
    let materialsConfigNew = cloneDeep(materialsConfig);
    if (viewRow.showName) {
      const iIndex = materialsConfigNew.findIndex(item => item.sName === "sMaterialsName");
      if (iIndex !== -1) {
        materialsConfigNew[iIndex].showName = viewRow.showName;
      }
    }
    const viewProps = {
      ...props,
      viewConfigs: materialsConfigNew,
      tableConfig: { ...slaveConfig, gdsconfigformslave: materialsConfigNew },
      iColValueView: 24,
      viewRow,
      tableName: `slaveUp${boxModel}`,
      onDataChange: (name, sFieldName, changeValue, sId, dropDownData, isWait) => {
        const iIndex = slaveData.findIndex(item => item.sId === slaveRowData.sId);
        if (iIndex !== -1) {
          slaveData[iIndex].materialsInfo = materialsInfo.map((item, i) => (i === index ? { ...item, ...changeValue } : item));
        } else {
          const { selectedNode = {} } = state;
          const { showName: sTreeNodeName } = selectedNode;
          slaveData.push({
            sId: commonUtils.createSid(),
            handleType: "add",
            sBoxModel: boxModel,
            sTreeNodeName,
            materialsInfo: materialsInfo.map((item, i) => (i === index ? { ...item, ...changeValue } : item)),
          });
        }

        props.setState(pre => ({ ...pre, slaveData, ...extraState }));
      },
    };

    return (
      <div className={styles.materialsLine}>
        <div className={styles.materialsViewTable}>
          <CommonViewTable {...viewProps} />
        </div>
        <div className={styles.materialsBtns}>
          <Button
            type="primary"
            icon={<PlusOutlined />}
            onClick={() => {
              const iIndex = slaveData.findIndex(item => item.sId === slaveRowData.sId);
              const rowIndex = materialsInfo.findIndex((item, i) => i === index);
              const materialsInfoNew = [...materialsInfo];
              materialsInfoNew.splice(rowIndex + 1, 0, {});
              if (iIndex !== -1) {
                slaveData[iIndex].materialsInfo = materialsInfoNew;
              } else {
                const { selectedNode = {} } = state;
                const { showName: sTreeNodeName } = selectedNode;
                slaveData.push({
                  sId: commonUtils.createSid(),
                  handleType: "add",
                  sBoxModel: boxModel,
                  sTreeNodeName,
                  materialsInfo: materialsInfoNew,
                });
              }
              props.setState(pre => ({ ...pre, slaveData, ...extraState }));
            }}
          />
          <Button
            type="primary"
            icon={<MinusOutlined />}
            onClick={() => {
              const iIndex = slaveData.findIndex(item => item.sId === slaveRowData.sId);
              const rowIndex = materialsInfo.findIndex((item, i) => i === index);
              const materialsInfoNew = [...materialsInfo];
              materialsInfoNew.splice(rowIndex, 1);
              slaveData[iIndex].materialsInfo = materialsInfoNew;
              props.setState(pre => ({ ...pre, slaveData, ...extraState }));
            }}
            style={index === 0 || viewRow.showName ? { visibility: "hidden" } : {}}
          />
        </div>
      </div>
    );
  });
};

// 多数量表组件
const ManyComponent = props => {
  const { state, setState, enabled, loading } = props;
  const { masterData = {}, calcPriceLoading, calcPriceFinished, manyData = [], selectedNode = {} } = state;
  const [submitLoading, setSubmitLoading] = useState(false);
  const [processPercent, setProcessPercent] = useState(0);

  const [BtnNewQuotation, BtnDraft, BtnPriceverification, BtnConfirmQuantity, btnOrdering, BtnPriceDetails] = props.getI18nNameList(
    ["BtnNewQuotation", "新报价"],
    ["BtnDraft", "存草稿"],
    ["BtnPriceverification", "核价"],
    ["BtnConfirmQuantity", "确认下单数量"],
    ["btnOrdering", "下单中..."],
    ["BtnPriceDetails", "价格明细"]
  );

  // 核价事件
  const onCalcPrice = () => {
    const { state } = props;
    const { masterData = {}, slaveConfig, slaveData = [], selectedNode = {}, backendConfig = {}, boxModelKey = 0, bestAlgorithm, activeKey } = state;
    const { bBox } = selectedNode;
    if (bBox && activeKey === 0) {
      const radios = GetBestAlgorithm(props);
      slaveData[boxModelKey] = {
        ...slaveData[boxModelKey],
        radioValue: radios?.sCode || 0,
      };
      props.setState(pre => ({ ...pre, slaveData, bestAlgorithm: commonUtils.createSid(), onCalcPrices: true }));
    } else {
      const addState = {
        ...props.onGetAllDelData(),
        manyDataCache: [],
      };
      props.onSaveState({
        masterData: { ...props.masterData, handleType: props.masterData.handleType || "update" },
        calcPriceTime: commonUtils.createSid(),
        ...addState,
      });
      props.setState(pre => ({ ...pre, onCalcPrices: false }));
    }
  };
  const { bestAlgorithm, onCalcPrices } = state;
  useEffect(() => {
    if (!bestAlgorithm) return;
    if (!onCalcPrices) return;
    const addState = {
      ...props.onGetAllDelData(),
      manyDataCache: [],
    };

    props.onSaveState({
      masterData: { ...props.masterData, handleType: props.masterData.handleType || "update" },
      calcPriceTime: commonUtils.createSid(),
      ...addState,
    });
  }, [bestAlgorithm, onCalcPrices]);
  useEffect(() => {
    if (props.calcPriceTime) {
      props.onSaveState({ calcPriceTime: undefined });
      props.handleCalcPrice();
    }
  }, [props.calcPriceTime]);

  // 根据主表数量更改多数量表
  useEffect(() => {
    const baseCount = masterData.dProductQty || 1000;
    if (manyData[0]?.dManyQty === baseCount) return;

    const manyDataNew = Array(5)
      .fill("")
      .map((item, index) => ({
        sId: commonUtils.createSid(),
        handleType: "add",
        dManyQty: baseCount * (index + 1),
      }));
    setState(pre => ({
      ...pre,
      manyData: manyDataNew,
      manySelectedRowKeys: [manyDataNew[0].sId],
      dProductQty: baseCount,
      dQuickQuoteProductQty: baseCount,
    }));
    props.onSaveState({
      manyDataCache: [],
    });
  }, [masterData.dProductQty, manyData.length]);

  // 获取核价进度
  useEffect(() => {
    if (calcPriceLoading) {
      setProcessPercent(0);
      window.tempWsAction = ({ data } = {}) => {
        const { action, msg } = commonUtils.convertStrToObj(data, {});
        if (action === "quotationAllprogress") {
          setProcessPercent(msg);
        }
      };
    } else {
      window.tempWsAction = null;
    }
  }, [calcPriceLoading]);

  // 监听确认下单数量结束
  useEffect(() => {
    if (!loading && submitLoading) {
      setSubmitLoading(false);
    }
  }, [loading]);

  const tableProps = {
    ...commonBusiness.getTableTypes("many", { ...props, ...state }),
    onSelectRowChange: (name, selectedRowKeys) => {
      const dProductQty = manyData.find(item => item.sId === selectedRowKeys[0]).dManyQty;
      props.slaveData?.forEach(slaveRowData => {
        props.onDataChange0("slave", "dProductQty", { dProductQty }, slaveRowData.sId, []);
      });

      setState(pre => ({
        ...pre,
        manySelectedRowKeys: selectedRowKeys,
        dQuickQuoteProductQty: dProductQty,
      }));
    },
    onDataChange: (...args) => {
      const iIndex = state.manyData.findIndex(item => item.sId === args[3]);
      const rowData = { ...state.manyData[iIndex] };
      state.manyData[iIndex] = {
        sId: rowData.sId,
        iRowNum: rowData.iRowNum,
        sParentId: rowData.sParentId,
        handleType: rowData.handleType,
        ...args[2],
      };
      setState(pre => ({
        ...pre,
        calcPriceFinished: false,
        manyData: state.manyData,
      }));
    },
    fixedHeight: 145,
  };
  
  const pricingInProgress = commonFunc.showLocalMessage(props, "sNuclearPricing", "核价中");
  const progress = commonFunc.showLocalMessage(props, "progress", "进度");
  return (
    <div className={`xly-bill-list ${styles.many}`}>
      <StaticEditTable {...tableProps} />
      {enabled && (
        <div className={styles.btns}>
          <Button type="primary" size="large" loading={loading} onClick={props.onAdd}>
            {BtnNewQuotation}
          </Button>
          <Button
            type="primary"
            size="large"
            loading={loading}
            onClick={() => {
              props.onSaveDraft();
            }}
          >
            {BtnDraft}
          </Button>
          <Button
            type="primary"
            size="large"
            loading={loading}
            disabled={!calcPriceFinished}
            onClick={async () => {
              const { report = [] } = props;
              let reportDataOne = report[0];
              if (selectedNode.sTypeKey === "juantong") {
                reportDataOne = "";
                const sModelsId = "101251240115016002356125200";
                const configUrl = `${commonConfig.server_host}business/getModelBysId/${sModelsId}?sModelsId=${sModelsId}&sName=/commonAuto`;
                const configReturn = (await commonServices.getService("", configUrl)).data;
                if (configReturn.code === 1) {
                  const dataReturn = configReturn.dataset.rows;
                  if (commonUtils.isNotEmptyArr(dataReturn)) {
                    const { report = [] } = dataReturn[0];
                    reportDataOne = report[0];
                  }
                } else {
                  message.error(configReturn.msg);
                }
              }
              if (!reportDataOne) {
                message.info("报表未配置，请先配置报表！");
                return;
              }
              const { sId } = reportDataOne;
              props.onBtnPrint(sId, false, `BtnPrint.${sId}`);
            }}
          >
            {BtnPriceDetails}
          </Button>
          <Button type="primary" size="large" loading={loading || calcPriceLoading} className={styles.calcPrice} onClick={onCalcPrice}>
            {calcPriceLoading ? `${pricingInProgress}【${progress}${processPercent}%】...` : BtnPriceverification}
          </Button>
          <Button
            type="primary"
            size="large"
            disabled={!calcPriceFinished}
            loading={loading || submitLoading}
            className={styles.confirmOrder}
            onClick={async () => {
              if (await props.bDataDeleted()) return;
              props.onSaveState(
                {
                  ...props.onGetAllDelData(),
                  masterData: {
                    ...props.masterData,
                    handleType: props.masterData.handleType || "update",
                    sQuoConfig: JSON.stringify(props.onGetFilterState(state)),
                  },
                  dQuickQuoteProductQty: state.dQuickQuoteProductQty,
                  loading: true,
                },
                () => {
                  setSubmitLoading(true);
                  props.onSubmit();
                }
              );
            }}
          >
            {submitLoading ? btnOrdering : BtnConfirmQuantity}
          </Button>
        </div>
      )}
    </div>
  );
};

// 选择盒型弹窗
const BoxModelSelectedModal = props => {
  const { dividerProps, state, boxModel, boxModelSelectedModalVisible } = props;
  const { masterData = {}, slaveConfig, slaveData = [], selectedNode = {}, downAbleConfigs = [], finishedConfigs = [] } = state;
  const slaveRowData = slaveData.find(item => item.sTreeNodeName === selectedNode.showName && item.sBoxModel === boxModel) || {};

  if (!boxModelSelectedModalVisible) return "";

  const onCancel = () => {
    props.onSaveState({
      boxModelSelectedModalVisible: false,
    });
  };

  const [boxConfig, setBoxConfig] = useState({ gdsconfigformslave: [] });
  const [boxColumn, setBoxColumn] = useState([]);
  const [boxTypeList, setBoxTypeList] = useState([]);
  const [boxData, setBoxData] = useState([]);
  const [treeClassName, setTreeClassName] = useState("");
  const UniqueID = commonFunc.showLocalMessage(props, "UniqueID", "唯一ID");
  const sName = commonFunc.showLocalMessage(props, "jurCon", "名称");
  const KnifeLineChart = commonFunc.showLocalMessage(props, "KnifeLineChart", "刀线图");
  const ThreeDGraph = commonFunc.showLocalMessage(props, "3DGraph", "3D图");
  const BtnOperations = commonFunc.showLocalMessage(props, "BtnOperations", "操作");
  const allName = commonFunc.showLocalMessage(props, "btnAll", "全部");
  const otherName = commonFunc.showLocalMessage(props, "BtnOther", "其他");
  const [boxTypeSelected, setBoxTypeSelected] = useState(allName);

  useEffect(() => {
    const boxList = [
      ["sId", UniqueID],
      ["iOrder", "#", 60],
      // ["sBoxId", "盒型ID"],
      ["sName", sName, 119],
      ["sPackDetailPathUpLoad", KnifeLineChart, 300],
      // ["sPackDetailPathUpLoad", "刀线图", 300],
      ["sPackPath", ThreeDGraph, 300],
      ["operation", BtnOperations, 80],
    ];
    const config = {
      sId: commonUtils.createSid(),
      // bisMutiSelect: true,
      gdsconfigformslave: boxList.map(item => ({
        sId: commonUtils.createSid(),
        sName: item[0],
        showName: item[1],
        iFitWidth: item[2] || 120,
        bVisible: item[0] !== "sId",
      })),
    };
    setBoxConfig(config);
    const column = commonFunc.getHeaderConfig(config);
    setBoxColumn(column);

    const getSqlDropDownData = async ({ sId, sSqlCondition = {} }, cb) => {
      const url = `${commonConfig.server_host}business/getSelectLimit/${sId}`;
      const body = {
        sKeyUpFilterName: "",
        pageNum: 1,
        pageSize: 1000,
        sSqlCondition,
      };
      const retrunData = await commonServices.postValueService(props.app.token, body, url);
      const dropDownData = retrunData.data?.dataset?.rows;
      cb(dropDownData);
    };

    getSqlDropDownData({ sId: "17428091410008594700322758474000", sSqlCondition: { sProductClassifyId: selectedNode.sId } }, dropDownData => {
      const boxTypeList = Array.from(new Set(dropDownData.map(item => item.sBoxType || otherName)));
      setBoxTypeList(boxTypeList);
      setBoxData(
        dropDownData.map((item, index) => ({
          ...item,
          iOrder: index + 1,
        }))
      );
    });
  }, []);

  const renderTreeNodes = useMemo(
    () =>
      [allName, ...boxTypeList].map(boxType => (
        <Tree.TreeNode
          title={
            <Badge
              count={boxType === allName ? boxData.length : boxData.filter(item => (item.sBoxType || otherName) === boxType).length}
              offset={[20, 8]}
              color="#faad14"
            >
              <span>{boxType}</span>
            </Badge>
          }
          key={boxType === allName ? 0 : commonUtils.createSid()}
          treeData={boxType}
          switcherIcon={<FolderFilled style={{ color: "#f7cc4f", fontSize: 20 }} />}
        ></Tree.TreeNode>
      )),
    [boxTypeList.length, boxData.length]
  );
  const getSvgProps = svg => {
    if (!svg) return;
    const { sColumnNameConfig, sBoxType, sBoxBody, dBoxLength, dBoxWidth, dBoxHeight, sTypes } = svg;
    const slaveData = sColumnNameConfig ? JSON.parse(sColumnNameConfig) : null;
    if (!slaveData) return;
    const boxList = [];
    const tables = [
      { name: "盒型类别", value: sBoxType, type: null },
      { name: "盒身", value: sBoxBody, type: sTypes },
      { name: "盒长", value: dBoxLength, type: null },
      { name: "盒宽", value: dBoxWidth, type: null },
      { name: "盒高", value: dBoxHeight, type: null },
    ];
    // const { slaveData = [] } = this.props;
    const titleList1 = [
      { name: "上方盒舌", value: "dSFHS" },
      { name: "盒底组件", value: "dHDC" },
      { name: "下方盒舌", value: "dXFHS" },
      { name: "左(上)插位组件", value: "dZSCW" },
      { name: "左贴边位", value: "dZTBW" },
      { name: "左(下)插位组件", value: "dZXCW" },
      { name: "右(上)插位组件", value: "dYSCW" },
      { name: "右贴边位", value: "dYTBW" },
      { name: "右(下)插位组件", value: "dYXCW" },
    ];
    slaveData.forEach(x => {
      boxList.push({
        value: x.iValue || x.sDefault,
        sName: titleList1.find(item => item.value === x.sCode || item.value === x.sName)?.name || "",
        isEditable: true,
        isSelect: false,
        selectValue: null,
        selectLabel: "",
        selectImage: null,
        type: x.sTypes || null,
        show: true,
        showName: x.sName, // 参数名称
      });
    });
    tables.forEach(x => {
      boxList.push({
        value: x.value,
        sName: x.name,
        isEditable: true,
        isSelect: false,
        selectValue: null,
        selectLabel: "",
        selectImage: null,
        type: x.type || null,
        show: true,
        showName: x.name, // 参数名称
      });
    });
    const svgProps = {
      ...props,
      boxList,
      dSvgBoxWidth: 100,
      dSvgBoxHeight: 100,
      showNew: 1,
    };
    return svgProps;
  };
  const selectBoxList = boxData.filter(item => (boxTypeSelected === allName ? true : (item.sBoxType || otherName) === boxTypeSelected));
  const noImage = commonFunc.showLocalMessage(props, "ImpositionInformation", "暂无图片");
  let btnSelectTitle = commonFunc.showLocalMessage(props, "BtnSelect", "选择");
  const sLanguage = props.app?.userinfo?.sLanguage;
  // if (sLanguage === "sEnglish") {
  //   btnSelectTitle = "BtnSelect";
  // }
  const tableProps = {
    ...commonBusiness.getTableTypes("box", {
      ...props,
      boxData: boxData.filter(item => (boxTypeSelected === allName ? true : (item.sBoxType || otherName) === boxTypeSelected)),
      boxConfig,
      boxColumn,
    }),
    enabled: false,
    fixedHeight: "calc(100vh - 365px)",
    noVlistTable: true,
    onCostomColums: columns => {
      columns
        .filter(item => item.dataIndex?.includes("Path"))
        .forEach(column => {
          // (value ? (column.dataIndex === 'sPackDetailPath' ? (boxData[index].sPackPath ? <img src={value} alt="" width={270} height={270} /> : '') : <img src={value} alt="" width={270} height={270} />)  : "暂无图片");
          column.render = (value, record, index) =>

            column.dataIndex === "sPackDetailPathUpLoad" ? (
              !value ? (
                <div style={{ width: "auto", height: 100 }}>
                  <DynamicSVG {...getSvgProps(selectBoxList[index])} />
                </div>
              ) : (
                <img src={getImageUrl(value)} alt="" width={100} height={100} />
              )
            ) : value ? (
              <img src={getImageUrl(value)} alt="" width={100} height={100} />
            ) : (
              noImage
            );
        });

      columns
        .filter(item => item.dataIndex === "operation")
        .forEach(column => {
          column.fixed = "right";
          column.render = (value, record, index) => (
            <Button
              style={{ marginLeft: 8 }}
              onClick={() => {
                props.onDataChange(props.currentBoxModel, "sName", { sName: record.sName }, record.sId, boxData);
                props.onSaveState({
                  boxModelSelectedModalVisible: false,
                });
              }}
            >
              {btnSelectTitle}
            </Button>
          );
        });
    },
  };
  const getImageUrl = (sName) => {
    const imageUrlNew = `${commonConfig.server_host}file/downloadPrice?sLogoName=${sName}&date=${new Date().getTime()}`;
    return imageUrlNew
  }
  const BoxSelection = commonFunc.showLocalMessage(props, "Box-TypeSelection", "盒型选择");
  const BtnClose = commonFunc.showLocalMessage(props, "BtnClose", "关闭");
  return (
    <AntdDraggableModal
      width="min(calc(100vw - 350px), 1100px)"
      title={BoxSelection}
      visible={boxModelSelectedModalVisible}
      onCancel={onCancel}
      footer={
        <Button type="primary" onClick={onCancel}>
          {BtnClose}
        </Button>
      }
    >
      <div className={styles.boxModal}>
        <div
          className={`${styles.boxTree} ${treeClassName}`}
          onMouseEnter={() => {
            setTreeClassName(styles.overFlow);
          }}
          onMouseLeave={() => {
            setTreeClassName("");
          }}
        >
          {boxTypeList.length && (
            <Tree
              className={"hide-file-icon"}
              defaultExpandAll={true}
              defaultSelectedKeys={["0"]}
              onSelect={(e, select) => {
                const { treeData } = select.node;
                setBoxTypeSelected(treeData);
              }}
            >
              {renderTreeNodes}
            </Tree>
          )}
        </div>
        <div className={styles.boxTable} key={boxTypeSelected}>
          <StaticEditTable {...tableProps} />
        </div>
      </div>
    </AntdDraggableModal>
  );
};

// 后道参数额外配置
const BackendParamsExtraComponent = props => {
  const { state, slaveConfig } = props;
  const { backendParamsConfig = [], backendConfig = {}, slaveData, selectedNode, masterData = {} } = state;

  if (!backendParamsConfig.length) return "";

  const { sParentFieldsName, sBoxModel, printParamsId } = backendConfig;

  const slaveRowData = slaveData.find(item => item.sTreeNodeName === selectedNode.showName && item.sBoxModel === sBoxModel) || {};
  const { sBackProcessData = [] } = slaveRowData;

  const { productProcessInfo = [] } = masterData;

  if (sParentFieldsName !== "sPrint" && ![...sBackProcessData, ...productProcessInfo].some(item => item[sParentFieldsName])) return "";

  const viewConfigs = backendParamsConfig.map(item => ({
    ...item,
    sName: item.sFieldName || `sParam${item.iOrder}`,
    showName: item.sParam,
    sDropDownType: item.sParamDropDown ? "sql" : "",
    iColValue: 4,
  }));

  const viewProps = {
    ...props,
    viewConfigs: viewConfigs.map(item => ({
      ...item,
      costomStyle: `${styles.sParamConfig} ${item.showName?.length > 4 ? 'sParamConfigLong' : ""}`,
    })),
    tableConfig: { ...slaveConfig, gdsconfigformslave: viewConfigs },
    iColValueView: 24,
    viewRow: { sId: slaveRowData.sId },
    getViewRow: config => {
      if (sParentFieldsName === "sPrint") {
        return [slaveRowData, ...sBackProcessData].find(item => item.sId === printParamsId);
      }
      return (
        [...sBackProcessData, ...productProcessInfo]
          .find(item => item[sParentFieldsName])
          ?.sBackendParams?.find(item => item.sParam === config.showName) || {}
      );
    },
    tableName: `sBackendParams${sBoxModel}`,
    getSqlDropDownData: async (...args) => {
      const showConfig = args[2];
      const { sDropDownType, sParamDropDown = "", sName, sFieldName } = showConfig;
      if (sDropDownType === "sql" && sParamDropDown?.toLowerCase()?.includes("select")) {
        args[2] = {
          ...showConfig,
          showDropDown: sParamDropDown,
        };
        delete args[2].sId;
        const result = await props.getSqlDropDownData(...args);
        const { dropDownData } = result;
        const temp = {
          ...result,
          dropDownData: dropDownData.map(item => ({
            ...item,
            // sId: item.sValue,
            value: item.sValue,
            sParam: showConfig.sParam,
            [sName]: item.sValue,
            sParamKey: sName,
            sFieldName,
          })),
        };
        return temp;
      }
      const dropDownData = sParamDropDown.split(",");
      if (dropDownData?.length) {
        return {
          dropDownData: dropDownData.map(item => ({
            sId: item,
            value: item,
            sParam: showConfig.sParam,
            [sName]: item,
            sParamKey: sName,
          })),
          totalPageCount: 1,
          currentPageNo: 1,
          conditonValues: {},
        };
      }

      return props.getSqlDropDownData(...args);
    },
    onDataChange: (name, sFieldName, changeValue, sId, dropDownData, isWait) => {
      const extraState = {
        calcPriceFinished: false,
      };
      const iIndex = slaveData.findIndex(item => item.sId === slaveRowData.sId);

      if (sParentFieldsName === "sPrint") {
        if (slaveData[iIndex].sId === printParamsId) {
          let slaveDataNew = [...slaveData];
          slaveDataNew[iIndex] = { ...slaveDataNew[iIndex], ...changeValue };
          props.setState(pre => ({ ...pre, slaveData: slaveDataNew }));
        } else {
          const iIndex1 = sBackProcessData.findIndex(item => item.sId === printParamsId);
          let sBackProcessDataNew = [...sBackProcessData];
          sBackProcessDataNew[iIndex1] = { ...sBackProcessDataNew[iIndex1], ...changeValue };
          slaveData[iIndex].sBackProcessData = sBackProcessDataNew;
          props.setState(pre => ({ ...pre, slaveData, ...extraState }));
        }
        return;
      }

      const sBData = sBoxModel ? slaveData[iIndex].sBackProcessData : productProcessInfo;

      const iIndex1 = sBData.findIndex(item => item[sParentFieldsName]);
      const showConfig = viewConfigs.find(item => item.sName === sFieldName);
      const dropDownDataSelected = dropDownData?.length
        ? dropDownData.find(item => item.sId === changeValue[sFieldName])
        : {
          sId: commonUtils.createSid(),
          value: changeValue[sFieldName],
          sParam: showConfig.sParam,
          sParamKey: sFieldName,
        };
      if (!dropDownDataSelected) return;
      dropDownDataSelected[sFieldName] = dropDownDataSelected.value;
      const { sParam } = dropDownDataSelected;
      const { sBackendParams = [] } = sBData[iIndex1];
      const iIndex2 = sBackendParams.findIndex(item => item.sParam === sParam);
      if (iIndex2 !== -1) {
        sBackendParams[iIndex2] = dropDownDataSelected;
      } else {
        sBackendParams.push(dropDownDataSelected);
      }
      sBData[iIndex1].sBackendParams = sBackendParams;
      if (!showConfig.sName?.startsWith("sParams")) {
        sBData[iIndex1][showConfig.sName] = dropDownDataSelected[showConfig.sName];
        const { dManualLength, dManualWidth } = sBData[iIndex1];
        if (dManualLength !== undefined && dManualWidth !== undefined) {
          sBData[iIndex1].dManualValue = dManualLength * dManualWidth;
        }
      }

      if (sBoxModel) {
        slaveData[iIndex].sBackProcessData = sBData;
        props.setState(pre => ({ ...pre, slaveData, ...extraState }));
      } else {
        masterData.productProcessInfo = sBData;
        props.setState(pre => ({ ...pre, masterData, ...extraState }));
      }
    },
  };

  return (
    <>
      <Divider style={{ margin: "5px 0", height: "auto" }} />
      <div className={`${styles.viewTable} ${styles.viewTableDownView1} ${styles.viewTableDownView2}`}>
        <CommonViewTable {...viewProps} />
      </div>
    </>
  );
};
const GetBestAlgorithm = props => {
  const { state } = props;
  const { masterData = {}, slaveConfig, slaveData = [], selectedNode = {}, backendConfig = {}, boxModelKey = 0 } = state;
  if (!slaveConfig) return "";
  const { sParentFieldsName, sBoxModel, printParamsId } = backendConfig;
  const slaveRowData = slaveData.filter(item => item.sTreeNodeName === selectedNode.showName)[boxModelKey] || {};
  if (!slaveRowData) return null;
  const { sColumnNameConfigExclusion } = slaveRowData;
  const calcMethodData = commonUtils.convertStrToObj(sColumnNameConfigExclusion, []);
  let {
    dSBLB = 0, // 上边留白
    dXBLB = 0, // 下边留白
    dZBLB = 0, // 左边留白
    dYBLB = 0, // 右边留白
    // dXBJJ, // 上边距
    dXBJJ = 0, // 下边距
    // dYBJJ, // 左边距
    dYBJJ = 0, // 右边距
    sLengthFormula, // 盒长公式
    sWidthFormula, // 盒宽公式
    sPackDetailPath,
    sColumnNameConfig,
    bAdvancedSetting, // 高级设置
    sSvgPath,
    dL = 0,
    dW = 0,
    dD = 0,
  } = slaveRowData;
  if (selectedNode && selectedNode.sTypeKey === "juantong") {
    dXBLB = dSBLB;
    dZBLB = 0;
    dYBLB = 0;
  }
  let { dHorizontal, dPortrait, dHorizontalType, dPortraitType } = slaveRowData;
  const slaveDataDetail = slaveRowData;
  const maxWidth = Number(slaveDataDetail?.dMaxLength);
  const maxHeight = Number(slaveDataDetail?.dMaxWidth);

  let outerWidth = Number(slaveDataDetail?.dMaxLength); // 默认取最大上机尺寸
  let outerHeight = Number(slaveDataDetail?.dMaxWidth); // 默认取最大上机尺寸
  const L = slaveRowData.dL ? Number(dL) : Number(masterData?.dLength) || 0;
  const W = slaveRowData.dW ? Number(dW) : masterData?.dWidth || 0;
  const H = slaveRowData.dD ? Number(dD) : masterData?.dWidth || 0;
  const D = slaveRowData.dD ? Number(dD) : masterData?.dHeight || 0;
  // 动态计算公式值
  const evaluateFormula = (formula, variables) => {
    if (!formula) return 0; // 如果公式为空，返回0
    try {
      // 提取公式中的变量名
      const variableNames = formula.match(/\b[a-zA-Z_][a-zA-Z0-9_]*\b/g) || [];
      // 构建函数参数
      const params = variableNames.join(",") + ",Math";
      // 替换公式中的变量为实际值
      const func = new Function(params, `return ${formula}`);
      // 提取变量值
      const args = variableNames.map(name => Number(variables[name]) || 0);
      // 执行函数并返回结果
      return func(...args, Math);
    } catch (error) {
      return 0;
    }
  };

  // 计算公式值
  const variables = {
    L,
    W,
    H,
    D,
    ...slaveRowData,
  };
  let boxList = [];
  if (slaveRowData.sColumnNameConfig) {
    const slaveNewData = slaveRowData.upAbleConfigsExtra || JSON.parse(slaveRowData.sColumnNameConfig);
    const tables = [
      { name: "盒型类别", value: slaveRowData.sBoxType, type: null },
      { name: "盒身", value: slaveRowData.sBoxBody, type: slaveRowData.sTypes },
      { name: "盒长", value: L, type: null },
      { name: "盒宽", value: W, type: null },
      { name: "盒高", value: D, type: null },
    ];
    const titleList1 = [
      { name: "上方盒舌", value: "dSFHS" },
      { name: "盒底组件", value: "dHDC" },
      { name: "下方盒舌", value: "dXFHS" },
      { name: "左(上)插位组件", value: "dZSCW" },
      { name: "左贴边位", value: "dZTBW" },
      { name: "左(下)插位组件", value: "dZXCW" },
      { name: "右(上)插位组件", value: "dYSCW" },
      { name: "右贴边位", value: "dYTBW" },
      { name: "右(下)插位组件", value: "dYXCW" },
    ];
    slaveNewData.forEach(x => {
      let key = 0;
      if (x.sAssignFormula) {
        key = parseFloat(evaluateFormula(x.sAssignFormula, variables)).toFixed(2) || 0;
      } else {
        key = slaveRowData[x.sName];
      }
      boxList.push({
        value: key,
        sName: titleList1.find(item => item.value === x.sName)?.name || "",
        isEditable: true,
        isSelect: false,
        selectValue: null,
        selectLabel: "",
        selectImage: null,
        type: x.sTypes || null,
        show: true,
        sCode: titleList1.find(item => item.value === x.sName)?.value || "",
        showName: x.showName, // 参数名称
      });
    });
    tables.forEach(x => {
      boxList.push({
        value: x.value,
        sName: x.name,
        isEditable: true,
        isSelect: false,
        selectValue: null,
        selectLabel: "",
        selectImage: null,
        type: x.type || null,
        show: true,
        showName: x.name, // 参数名称
      });
    });
  }

  const result = boxList?.reduce((acc, { sCode, value }) => ({ ...acc, [sCode]: Number(value) }), {});

  // 计算表达式结果
  const variabless = {
    ...variables,
    ...result,
  };
  Object.keys(variabless).forEach(key => {
    if (variabless[key] === null || variabless[key] === undefined || variabless[key] === "") {
      variabless[key] = 0;
    }
  });
  const calculateLayout = (radioValue, i) => {
    const innerWidth = slaveRowData.sTypes === "6" ? evaluateFormula(sWidthFormula, variabless) : evaluateFormula(sLengthFormula, variabless);
    const innerHeight = slaveRowData.sTypes === "6" ? evaluateFormula(sLengthFormula, variabless) : evaluateFormula(sWidthFormula, variabless);
    const { sSettingMethod, sSGroupOffset, iFAngle, iSAngle, sSecondorizontalOffset, sSecondLongitudinalOffset } = radioValue ? radioValue : {};
    const dFWidthOffset = evaluateFormula(radioValue?.sFWidthOffset, variabless); // 首盒纵向偏移
    const dFLengthOffset = evaluateFormula(radioValue?.sFLengthOffset, variabless); // 首盒横向偏移
    const dSWidthOffset = evaluateFormula(radioValue?.sSWidthOffset, variabless); // 次盒纵向偏移
    const dSLengthOffset = evaluateFormula(radioValue?.sSLengthOffset, variabless); // 次盒横向偏移
    const boxLengthOffset = evaluateFormula(sSecondorizontalOffset, variabless); // 第二列横向偏移
    const boxWidthOffset = evaluateFormula(sSecondLongitudinalOffset, variabless); // 第二列纵向偏移
    const isVertical = sSettingMethod === "从上到下"; // true 表示竖向排列，false 表示横向排列 sSettingMethod === '从上到下'
    const reference = sSGroupOffset === "首盒"; // 第三列参考
    // 计算内层盒子尺寸 加上间距
    let jInnerHeight = innerHeight;
    let jInnerWidth = innerWidth;
    let dSvgBoxWidth = innerWidth;
    let dSvgBoxHeight = innerHeight;
    const isRrotate = iFAngle === 90 || iFAngle === 270 || iSAngle === 90 || iSAngle === 270;
    if (iFAngle === 90 || iFAngle === 270 || iSAngle === 90 || iSAngle === 270) {
      jInnerHeight = innerWidth;
      jInnerWidth = innerHeight;
    }
    if (state.selectedNode.sTypeKey === "kapai" || state.selectedNode.sTypeKey === "juantong") {
      jInnerHeight = innerHeight;
      jInnerWidth = innerWidth;
    }

    const innerHeightCombined =
      (isVertical ? jInnerHeight * 2 + dSWidthOffset + dFWidthOffset : Math.max(jInnerHeight + dFWidthOffset, jInnerHeight + dSWidthOffset)) + dXBJJ; // 计算内层盒子高度 从上向下排列 取首盒加偏移量和次盒加偏移量最大的值  从左往右排列 盒子尺寸 * 2 加上首盒偏移量和次盒偏移量
    // 计算内层盒子宽度 从上向下排列 取首盒加偏移量和次盒加偏移量最大的值  从左往右排列 盒子尺寸 * 2 加上首盒偏移量和次盒偏移量
    const innerWidthCombined =
      (isVertical ? Math.max(jInnerWidth + dFLengthOffset, jInnerWidth + dSLengthOffset) : jInnerWidth * 2 + dSLengthOffset + dFLengthOffset) + dYBJJ;
    // 加上间距后的最大盒子长宽 计算每列可以放多少个组合 需要计算间距
    // 每个盒子加上边距 和第二组偏移量 如果根据次盒再加上次盒偏移量
    const dSWidthOffsetCombined = innerWidthCombined + boxLengthOffset + (reference ? 0 : dSLengthOffset);
    let cols = dSWidthOffsetCombined === 0 ? 0 : Math.floor(outerWidth / dSWidthOffsetCombined);
    const rowsCombined = innerHeightCombined + boxWidthOffset + (reference ? 0 : dSWidthOffset);
    let rows = rowsCombined === 0 ? 0 : Math.floor(outerHeight / rowsCombined);
    let colsMaxLength =
      cols * (innerWidthCombined + boxLengthOffset + (reference ? 0 : dSLengthOffset) + dYBJJ) + dZBLB + dYBLB - (reference ? 0 : dSLengthOffset);
    let rowsMaxLength =
      rows * (innerHeightCombined + boxWidthOffset + (reference ? 0 : dSWidthOffset) + dXBJJ) + dSBLB + dXBLB - (reference ? 0 : dSWidthOffset);
    while (colsMaxLength > outerWidth && cols > 0) {
      cols = cols - 1;
      colsMaxLength = cols * (innerWidthCombined + boxLengthOffset + (reference ? 0 : dSLengthOffset) + dYBJJ);
    }

    while (rowsMaxLength > outerHeight && rows > 0) {
      rows = rows - 1;
      rowsMaxLength = rows * (innerHeightCombined + boxWidthOffset + (reference ? 0 : dSWidthOffset) + dXBJJ);
    }
    // 最大上机长 上机宽 开料尺寸
    // 计算剩余空间 每组都算上偏移量 那么剩余需要加上后面偏移的总量
    const remainingWidth = outerWidth - colsMaxLength + (boxLengthOffset + (reference ? 0 : dSLengthOffset));
    const remainingHeight = outerHeight - rowsMaxLength + (boxWidthOffset + (reference ? 0 : dSWidthOffset));
    //剩余量能不能放一下单独一个
    const commonHeightCheck = remainingHeight > jInnerHeight + dXBJJ;
    const commonWidthCheck = remainingWidth > jInnerWidth + dYBJJ;
    const isCustomized = bAdvancedSetting;
    let remaining = isVertical ? commonHeightCheck : commonWidthCheck;

    // 判断
    // const remaining = false;
    const isOdd = num => {
      return num % 2 !== 0;
    };

    // 是否定制
    if (isCustomized) {
      if (isVertical) {
        cols = dHorizontal || 0;
        rows = dPortrait ? Math.trunc(dPortrait / 2) : 0;
        if (isOdd(dPortrait)) {
          remaining = true;
        } else {
          remaining = false;
        }
      } else {
        cols = dHorizontal ? Math.trunc(dHorizontal / 2) : 0;
        rows = dPortrait || 0;
        if (isOdd(dHorizontal)) {
          remaining = true;
        } else {
          remaining = false;
        }
      }
    }
    const createDiv = (col, row, index, leftPosition, topPosition, offsetZ, icon) => (
      <div
        key={`${col}-${row}-${index}`}
        style={{
          width: `${jInnerWidth}px`,
          height: `${jInnerHeight}px`,
          // backgroundColor: "#fff",
          display: "flex",
          justifyContent: "center",
          alignItems: "center",
          position: "absolute",
          left: `${leftPosition}px`,
          top: `${topPosition}px`,

          zIndex: 10,
        }}
        onDoubleClick={() => {
          onClick();
        }}
      >
        <div style={{ transform: `rotateZ(${offsetZ}deg)` }}></div>
      </div>
    );

    const createBox = (col, row, index, leftPosition, topPosition, offsetZ, icon) => (
      <div
        key={`${col}-${row}-${index}`}
        style={{
          width: `${innerWidthCombined}px`,
          height: `${innerHeightCombined}px`,
          display: "flex",
          justifyContent: "center",
          alignItems: "center",
          position: "absolute",
          overflow: "hidden",
          left: `${calculateLeftPosition(col, reference, isVertical, leftPosition, dYBJJ, dSLengthOffset)}px`,
          top: `${calculateTopPosition(row, reference, isVertical, topPosition, dSWidthOffset, dXBJJ)}px`,
          zIndex: 10,
        }}
        onDoubleClick={() => {
          onClick();
        }}
      >
        <div
          key={`${col}-${row}-${index}`}
          style={{
            width: `${iSAngle === 90 || iSAngle === 270 ? jInnerWidth : innerWidth}px`,
            height: `${iFAngle === 90 || iFAngle === 270 ? jInnerHeight : innerHeight}px`,
            display: "flex",
            justifyContent: "center",
            alignItems: "center",
            position: "absolute",
            left: `${dFLengthOffset}px`,
            top: `${iFAngle === 90 || iFAngle === 270 ? dFLengthOffset : dFWidthOffset}px`,
          }}
        >
          <div style={{ transform: `rotateZ(${iFAngle}deg)` }}></div>
        </div>
        {/* 次盒 */}
        <div
          key={`${col}-${row}-${index}-1`}
          style={{
            width: `${iSAngle === 90 || iSAngle === 270 ? jInnerWidth : innerWidth}px`,
            height: `${iSAngle === 90 || iSAngle === 270 ? jInnerHeight : innerHeight}px`,
            display: "flex",
            justifyContent: "center",
            alignItems: "center",
            position: "absolute",
            left: `${isVertical
              ? dSLengthOffset
              : iSAngle === 90 || iSAngle === 270
                ? innerHeight + dFLengthOffset + dSLengthOffset + dYBJJ
                : innerWidth + dFLengthOffset + dSLengthOffset + dYBJJ
              }px`,
            top: `${isVertical ? jInnerHeight + dFWidthOffset + dSWidthOffset + dXBJJ : iSAngle === 90 || iSAngle === 270 ? dSWidthOffset : dSWidthOffset
              }px`,
          }}
        ></div>
      </div>
    );
    const createBoxOne = (col, row, index, leftPosition, topPosition, offsetZ, icon) => (
      <div
        key={`${col}-${row}-${index}`}
        style={{
          width: `${jInnerWidth}px`,
          height: `${jInnerHeight}px`,
          display: "flex",
          justifyContent: "center",
          alignItems: "center",
          position: "absolute",
          overflow: "hidden",
          left: `${calculateLeftPosition(col, reference, isVertical, leftPosition, dYBJJ, dSLengthOffset)}px`,
          top: `${calculateTopPosition(row, reference, isVertical, topPosition, dSWidthOffset, dXBJJ)}px`,
          zIndex: 10,
        }}
        onDoubleClick={() => {
          onClick();
        }}
      >
        <div
          key={`${col}-${row}-${index}`}
          style={{
            width: `${jInnerWidth}px`,
            height: `${jInnerHeight}px`,
            display: "flex",
            justifyContent: "center",
            alignItems: "center",
            position: "absolute",
            left: `${dFLengthOffset}px`,
            top: `${dFWidthOffset}px`,
          }}
        ></div>
      </div>
    );
    // 计算左偏移
    const calculateLeftPosition = (col, reference, isVertical, leftPosition, dYBJJ, dSLengthOffset) => {
      if (isVertical) {
        if (reference) {
          return col === 0 ? leftPosition : leftPosition + dYBJJ * col;
        }
        return col === 0 ? leftPosition : leftPosition + (boxLengthOffset + dYBJJ) * col;
      } else {
        if (reference) {
          return col === 0 ? leftPosition : leftPosition + dYBJJ * col;
        }
        return col === 0 ? leftPosition : leftPosition + (boxLengthOffset + dYBJJ) * col + dSLengthOffset * col;
      }
    };
    // 计算上偏移
    const calculateTopPosition = (row, reference, isVertical, topPosition, dSWidthOffset, dXBJJ) => {
      if (isVertical) {
        if (reference) {
          return row === 0 ? topPosition : topPosition + boxWidthOffset * row;
        } else {
          return row === 0 ? topPosition : topPosition + (dSWidthOffset + boxWidthOffset) * row;
        }
      } else {
        if (reference) {
          return row === 0 ? 0 : topPosition + boxWidthOffset * row;
        } else {
          return row === 0 ? topPosition : topPosition + (dSWidthOffset + boxWidthOffset) * row;
        }
      }
    };
    const innerDivs = [];
    // 生成盒子
    if (cols === 0 || rows === 0) {
      if (cols > 0) {
        for (let col = 0; col < cols; col++) {
          const leftPosition = col * innerWidthCombined;
          const topPosition = 0 * innerHeightCombined;
          innerDivs.push(createBoxOne(col, 0, 3, leftPosition, topPosition, iFAngle));
        }
      }
      if (rows > 0) {
        for (let row = 0; row < rows; row++) {
          const leftPosition = 0 * innerWidthCombined;
          const topPosition = row * innerHeightCombined;
          innerDivs.push(createBoxOne(0, row, 3, leftPosition, topPosition, iFAngle));
        }
      }
    } else {
      let hasPushed = false; // 标志变量
      for (let col = 0; col < cols; col++) {
        for (let row = 0; row < rows; row++) {
          const leftPosition = col * innerWidthCombined;
          const topPosition = row * innerHeightCombined;
          innerDivs.push(createBox(col, row, 1, leftPosition, topPosition, iFAngle));
        }
        // 如果可以放下首盒\
        if (remaining && isVertical) {
          let leftPosition = 0;
          let topPosition = 0;
          if (reference) {
            // 是否首盒
            // 首盒的上边距下边距 末尾盒子的上下边距 添加那一行的上边距
            leftPosition = col * innerWidthCombined + dFLengthOffset;
            topPosition = rows * innerHeightCombined + dFWidthOffset;
          } else {
            leftPosition = col * innerWidthCombined;
            topPosition = rows * innerHeightCombined;
          }
          innerDivs.push(createBoxOne(col, rows, 3, leftPosition, topPosition + dXBJJ, iFAngle));
        }
      }
      if (remaining && !isVertical) {
        for (let index = 0; index < rows; index++) {
          // 先默认为首盒参考
          let topPosition = 0;
          let leftPosition = 0;
          if (reference) {
            topPosition = index * (innerHeightCombined + boxWidthOffset);
            leftPosition = cols * (innerWidthCombined + boxLengthOffset);
          } else {
            topPosition = index * (innerHeightCombined + boxWidthOffset + dSWidthOffset);

            leftPosition = cols * (innerWidthCombined + boxLengthOffset + dSLengthOffset + dYBJJ);
          }
          innerDivs.push(createDiv(cols - 1, index, 3, leftPosition, topPosition, iFAngle));
        }
      }
    }
    const propsData = innerDivs[innerDivs.length - 1];
    if (!propsData) {
      return {
      newMaterialLength:0,
      newMaterialWidth:0,
      dSinglePQty:0,
      index: i,
    };
    }
    let openEdition = 0;
    const { dWlcd, sBillNo } = slaveRowData;

    const propsDataLeft = Number(propsData.props.style.left.slice(0, -2));
    // 长需要找出最大的
    const propsDataWidth = Number(propsData.props.style.width.slice(0, -2));
    const propsDataHeight = Number(propsData.props.style.height.slice(0, -2));
    const propsDataTop = Number(propsData.props.style.top.slice(0, -2));
    // 判断列是否是单独的

    const newMaterialLength = parseFloat(propsDataLeft + (remaining ? jInnerWidth : innerWidthCombined) + dZBLB + dYBLB).toFixed(2); // 原纸长
    const newMaterialWidth = parseFloat(
      propsDataTop + propsDataHeight + dSBLB + dXBLB - (isVertical ? 0 : rows >= 1 ? (remaining ? 0 : dXBJJ) : 0)
    ).toFixed(2);

    // 计算开数
    let dSinglePQty = isVertical
      ? remaining
        ? cols + cols * (rows * 2)
        : cols * (rows * 2)
      : remaining
        ? rows + rows * (cols * 2)
        : rows * (cols * 2);

    let dHorizontalType = isVertical ? cols : remaining ? cols * 2 + 1 : cols * 2;
    let dPortraitType = isVertical ? (remaining ? rows * 2 + 1 : rows * 2) : remaining ? rows : rows;
    if (cols === 0 || rows === 0) {
      if (innerDivs.length > 0) {
        if (cols === 0 && rows > 0) {
          dSinglePQty = rows;
          dPortraitType = rows;
          dHorizontalType = 1;
        } else if (rows === 0 && cols > 0) {
          dSinglePQty = cols;
          dHorizontalType = cols;
          dPortraitType = 1;
        }
      }
    }
    const newDProductQty = masterData.dProductQty;
    const dMaterialsKQty = slaveDataDetail.dMaterialsKQty || 1;
    openEdition = (((newMaterialLength * newMaterialWidth) / (maxWidth * maxHeight)) * 100).toFixed(2);

    return {
      newMaterialLength,
      newMaterialWidth,
      dSinglePQty,
      index: i,
    };
  };
  let list = [];
  if (calcMethodData && calcMethodData.length) {
    list = calcMethodData.map((item, i) => {
      return calculateLayout(item, i);
    });
  }
  const findMinValueItem = data => {
    let minItem = null;
    let minValue = Infinity;

    for (const item of data) {
      const { newMaterialLength, newMaterialWidth, dSinglePQty } = item;
      const length = parseFloat(newMaterialLength);
      const width = parseFloat(newMaterialWidth);
      const value = (length * width) / dSinglePQty;

      if (value < minValue) {
        minValue = value;
        minItem = item;
      }
    }

    return minItem;
  };
  return list.length ? calcMethodData[findMinValueItem(list).index] : calcMethodData[0];
};
export default QuickQuote;
