import { ssIcon, commonIcon } from "./icon-config.js";
import * as IndexComponents from "./ss-index-components.js";
import * as EchartComponents from "./ss-echarts-compnents.js";
import { isNum, toStyleStr } from "./tools.js";
import { EVEN_VAR } from "./EventBus.js";

// import * as elements from "../lib/element-plus.js";
(function () {
  const {
    createApp,
    ref,
    reactive,
    watch,
    onMounted,
    onBeforeUnmount,
    h,
    computed,
    resolveComponent,
    watchEffect,
    nextTick,
    onVnodeMounted,
    Teleport,
    inject,
    provide,
  } = Vue;

  // 弹窗默认遮罩z-index
  let currentZIndex = 100;
  //   目前已存在的弹窗
  const topWindow = window.top;
  topWindow.dialogInstances = topWindow.dialogInstances || [];
  // 新建弹窗
  function createSsDialogInstance(setting, callbackEvent) {
    currentZIndex += 10; // 动态提升 z-index
    const container = document.createElement("div");
    document.body.appendChild(container);
    const app = Vue.createApp({
      render() {
        return h(SsDialog, {
          ...setting,
          zIndex: currentZIndex,
          onClose() {
            document.body.removeChild(container); // 仅移除弹窗容器
            const index = topWindow.dialogInstances.indexOf(app);
            if (index > -1) {
              topWindow.dialogInstances.splice(index, 1); // 移除实例
            }
            // 关闭后的回调
            if (callbackEvent && typeof callbackEvent === "function") {
              callbackEvent();
            }
            app.unmount(); // 仅卸载弹窗实例
            if (container.parentNode) {
              container.parentNode.removeChild(container); // 确保移除容器
            }
          },
        });
      },
    });
    topWindow.dialogInstances.push({ app, callbackEvent, container });
    app.component("ss-mark", SsMark); // 注册 ss-mark 组件
    app.component("ss-icon", SsIcon);
    app.component("ss-full-style-header", SsFullStyleHeader); // 注册 ss-full-style-header 组件
    app.mount(container);
  }
  // ss-breadcrumb 一级菜单页面面包屑
  const SsBreadcrumb = {
    name: "SsBreadcrumb",
    props: {
      level: {
        type: Object,
        default: null,
      },
    },
    setup(props) {
      const currentMenu = ref(null);
      const folderPath = ref([]);
      const eventBus = window.parent.sharedEventBus;

      // 监听页面变化
      onMounted(() => {
        // 获取初始页面
        currentMenu.value = eventBus.getState(EVEN_VAR.currentPage);
        folderPath.value = eventBus.getState("folderPath") || [];

        // 订阅页面变化
        eventBus.subscribe(EVEN_VAR.currentPage, (page) => {
          currentMenu.value = page;
        });
        eventBus.subscribe("folderPath", (path) => {
          folderPath.value = path || [];
        });
      });
      // 修改点击处理函数
      const handlePathClick = (index) => {
        if (props.level?.onBack) {
          // 截取到点击的位置，后面的路径会被销毁
          const newPath = folderPath.value.slice(0, index + 1);
          eventBus.publish("folderPath", newPath);
          // 返回到对应层级
          const targetFolder = newPath[newPath.length - 1]?.folder || null;
          props.level.onBack(targetFolder);
        }
      };
      const SsCommonIcon = resolveComponent("SsCommonIcon");
      return () =>
          h("div", { class: "bread-crumb" }, [
            currentMenu.value &&
            h(
                "div",
                {
                  onClick: () => {
                    if (props.level?.onBack) {
                      eventBus.publish("folderPath", []);
                      props.level.onBack(null); // 返回到根目录
                    } else {
                      eventBus.publish(EVEN_VAR.currentPage, currentMenu.value);
                    }
                  },
                },
                currentMenu.value.label || currentMenu.value.name
            ),

            ...(folderPath.value || [])
                .map((folder, index) => [
                  h(SsCommonIcon, { class: "common-icon-arrow-right" }),
                  h(
                      "div",
                      {
                        class: "bread-crumb-item",
                        onClick: () => handlePathClick(index),
                        style: { cursor: "pointer" },
                      },
                      folder.title
                  ),
                ])
                .flat(),
          ]);
    },
  };

  // ss-input form表单的输入
  const SsInput = {
    name: "SsInput",
    inheritAttrs: false, // 不直接继承属性到组件根元素
    props: {
      name: {
        type: String,
        required: true,
        default: "",
      },
      // 接收 v-model 绑定的值
      errTip: {
        type: String,
      },
      required: {
        type: Boolean,
        default: false,
      },
      placeholder: {
        type: String,
        default: "请输入",
      },
      defaultValue: [String, Number],
      modelValue: [String, Number],
    },
    emits: ["update:modelValue", "input", "blur", "change"], // 允许更新 v-model 绑定的值
    setup(props, { emit }) {
      const errMsg = ref("");
      const inputRef = ref(null);
      const textareaRef = ref(null);
      const inputValue = ref(props.modelValue || props.defaultValue || "");
      const contentFloatingDiv = ref(false); // 控制浮动 DIV 的显示

      const showRequired = computed(() => {
        // 检查是否有验证规则（通过 window.ssVm 判断）
        const hasValidationRule = window.ssVm?.validations?.has(props.name);

        if (!hasValidationRule) return false;
        if (errMsg.value) return true;
        if (!inputValue.value) return true;
        return false;
      });

      const validate = () => {
        if (window.ssVm) {
          const result = window.ssVm.validateField(props.name);
          console.log(result);

          errMsg.value = result.valid ? "" : result.message;
        }
      };

      // 使用 watch 监听 props.errTip 和 props.modelValue 的变化
      watch(
          () => props.errTip,
          (newVal) => {
            errMsg.value = newVal;
          },
          { immediate: true }
      );
      watch(
          () => props.modelValue,
          (newVal) => {
            inputValue.value = newVal;
          }
      );

      // 挂载时的逻辑
      onMounted(() => {
        errMsg.value = props.errTip;
        inputValue.value = props.modelValue || props.defaultValue || "";
      });
      // 计算并调整textarea的高度
      const adjustHeight = () => {
        nextTick(() => {
          const textarea = textareaRef.value;
          if (!textarea) return;
          // 重置高度以获得正确的scrollHeight
          textarea.style.height = "auto";
          // 计算新高度
          const maxHeight =
              parseInt(getComputedStyle(textarea).lineHeight, 10) * 5; // 假设lineHeight是单行高度
          const newHeight = Math.min(textarea.scrollHeight, maxHeight);
          textarea.style.height = `${newHeight}px`;
        });
      };
      // 定义事件处理函数
      const onInput = (event) => {
        const newValue = event.target.value;
        inputValue.value = newValue;
        emit("update:modelValue", newValue);
        validate(); // 输入时验证
        nextTick(() => {
          contentFloatingDiv.value =
              inputRef.value.scrollWidth > inputRef.value.offsetWidth;
        });
        adjustHeight();
      };
      const onFocus = (event) => {
        nextTick(() => {
          contentFloatingDiv.value =
              inputRef.value.scrollWidth > inputRef.value.offsetWidth;
        });
        adjustHeight();
      };

      // 失去焦点时进行验证
      const onBlur = (event) => {
        emit("blur", event.target);
        validate(); // 失焦时验证
        nextTick(() => {
          // 如果焦点不在 input 或 textarea 上，则隐藏浮动 div
          if (!document.activeElement.classList.contains("input-control")) {
            contentFloatingDiv.value = false;
          }
        });
      };
      const onChange = (event) => {
        inputValue.value = event.target.value || "";
        emit("change", inputValue.value);
      };
      const onMouseover = (event) => {
        nextTick(() => {
          // setTimeout(contentFloatingDiv.value = true, 500)
        });
      };
      const onMouseleave = (event) => {
        // contentFloatingDiv.value = false
      };
      return {
        errMsg,
        inputValue,
        showRequired,
        onInput,
        onBlur,
        onChange,
        onMouseover,
        onMouseleave,
        contentFloatingDiv,
        inputRef,
        textareaRef,
        onFocus,
      };
    },
    render() {
      return h("div", { class: "input" }, [
        h("div", { class: "input-container" }, [
          h("div", { class: "input" }, [
            h("input", {
              ref: "inputRef",
              class: "input-control",
              name: this.name,
              value: this.inputValue,
              onInput: this.onInput,
              onFocus: this.onFocus,
              onBlur: this.onBlur,
              onChange: this.onChange,
              placeholder: this.placeholder,
              onMouseover: this.onMouseover, // 监听鼠标悬停
              onMouseleave: this.onMouseleave, // 监听鼠标离开
              ...this.$attrs,
              autocomplete: "off",
            }),
            // this.showRequired ? h("div", { class: "required" }) : null,
          ]),
          this.contentFloatingDiv || ""
              ? h("div", { class: "floating-div" }, [
                h("textarea", {
                  ref: "textareaRef",
                  class: "input-control",
                  value: this.inputValue,
                  onInput: this.onInput,
                  onBlur: this.onBlur,
                  onFocus: this.onFocus,
                  onMouseover: this.onMouseover, // 监听鼠标悬停
                  onMouseleave: this.onMouseleave, // 监听鼠标离开
                  autocomplete: "off",
                  onVnodeMounted: (vnode) => {
                    vnode.el.focus();
                  },
                }),
              ])
              : null,
          // this.errMsg ? h(SsValidate, { errMsg: this.errMsg }) : null,
        ]),
      ]);
    },
  };
  // ss-normal-input 登录输入
  const SsLoginInput = {
    name: "SsLoginInput",
    inheritAttrs: false,
    props: {
      errTip: {
        type: String,
      },

      type: {
        type: String,
        default: "text",
      },
      required: {
        type: Boolean,
        default: false,
      },
      placeholder: {
        type: String,
        default: "请输入",
      },
      name: {
        type: String,
        default: "",
      },
      defaultValue: [String, Number],
      modelValue: [String, Number],
    },
    emits: ["update:modelValue", "input", "blur", "change"], // 允许更新 v-model 绑定的值
    setup(props, { emit }) {
      const errMsg = ref("");
      const inputRef = ref(null);
      const textareaRef = ref(null);
      const inputValue = ref(props.modelValue || props.defaultValue || "");

      // 使用 watch 监听 props.errTip 和 props.modelValue 的变化
      watch(
          () => props.errTip,
          (newVal) => {
            errMsg.value = newVal;
          },
          { immediate: true }
      );
      watch(
          () => props.modelValue,
          (newVal) => {
            inputValue.value = newVal;
          }
      );

      // 挂载时的逻辑
      onMounted(() => {
        errMsg.value = props.errTip;
        inputValue.value = props.modelValue || props.defaultValue || "";
      });

      // 定义事件处理函数
      const onInput = (event) => {
        const newValue = event.target.value;
        inputValue.value = newValue;
        emit("update:modelValue", newValue);
      };
      return { inputValue, onInput, inputRef, textareaRef };
    },
    render() {
      return h("div", { class: "input" }, [
        h("div", { class: "input-container" }, [
          h("div", { class: "input" }, [
            h("input", {
              ref: "inputRef",
              class: "input-control",
              name: this.name,
              value: this.inputValue,
              onInput: this.onInput,
              type: this.type,
              placeholder: this.placeholder,
              required: this.required,
              ...this.$attrs,
              autocomplete: "off",
            }),
            this.required ? h("div", { class: "required" }) : null,
          ]),
        ]),
      ]);
    },
  };
  // ss-login-button
  const SsLoginButton = {
    name: "SsLoginButton",
    inheritAttrs: false,
    props: {
      class: {
        type: String,
        default: "",
      },
      text: {
        type: String,
        default: "",
      },
      type: {
        type: String,
        default: "button",
      },
    },
    emits: ["click"],
    setup(props, { emit }) {
      // 定义事件处理函数
      const onClick = (event) => {
        // 发射一个 'click' 事件，你可以传递所需的参数
        emit("click", event);
      };

      return { props, onClick };
    },
    render() {
      const SsIcon = resolveComponent("ss-icon");
      const SsLoginIcon = resolveComponent("ss-login-icon");
      return h(
          "button",
          { class: "login-button", type: this.type, onClick: this.onClick },
          [
            h("span", [h(SsLoginIcon, { class: this.class })]),
            h("span", {}, this.text),
          ]
      );
    },
  };
  // ss-objp 下拉选择
  const SsObjp = {
    name: "SsObjp",
    inheritAttrs: false,
    props: {
      filter: {
        type: String,
        required: false,
      },
      cb: {
        type: String,
        required: true,
      },
      url: {
        type: String,
        required: true,
      },
      name: {
        type: String,
        required: true,
      },
      width: {
        type: String,
        default: "100%",
      },
      placeholder: {
        type: String,
        default: "请选择",
      },
      inp: {
        type: Boolean,
        default: false,
      },
      opt: {
        type: Array,
        default: () => [],
      },
      errTip: String,
      defaultValue: [String, Number],
      modelValue: [String, Number],
      direction: {
        type: String,
        default: "bottom",
      },
    },
    emits: ["update:modelValue", "input", "blur", "change"],
    setup(props, { emit }) {
      const canInput = props.inp;
      const errMsg = Vue.ref(props.errTip);
      const selectItem = Vue.ref({});
      let inputText = Vue.ref(""); // 用于存储输入框的文本
      const popupWinVisible = Vue.ref(false);

      const filteredOptions = Vue.ref(props.opt);
      const popupDirection = Vue.ref("bottom");

      // const showRequired = Vue.computed(() => {
      //   const hasValidationRule = window.ssVm?.validations?.has(props.name);
      //   if (!hasValidationRule) return false;
      //   if (errMsg.value) return true;
      //   if (!selectItem.value?.value) return true;
      //   return false;
      // });

      const validate = () => {
        if (window.ssVm) {
          const result = window.ssVm.validateField(props.name);
          // console.log("validate", window.ssVm.validateField(props.name));
          errMsg.value = result.valid ? "" : result.message;
        }
      };

      //在objPicker界面，选中value对应的项
      const updateSelectItem = () => {
        // console.log(props.opt);
        const item = props.opt.find((it) => it.value === props.modelValue);
        if (item) {
          selectItem.value = item;
          inputText.value = item.label;
        } else {
          selectItem.value = { label: "", value: "" };
          inputText.value = "";
        }
        // validate();
      };

      Vue.watch(
          () => props.errTip,
          (newVal) => {
            errMsg.value = newVal;
          }
      );

      Vue.watch(() => props.modelValue, updateSelectItem, { immediate: true });
      Vue.watch(
          () => props.opt,
          (newVal) => {
            updateSelectItem();
            filteredOptions.value = [...newVal];
            // console.log("filteredOptions", filteredOptions.value);
          }
      );

      //初始化objPicker在页面刚打开时的默认值
      async function initDefaultValue() {
        try {
          if (props.url && props.cb && props.modelValue) {
            const objectPickerParam = { input: props.inp, codebook: props.cb };
            const objectPickerParamStr = JSON.stringify(objectPickerParam);

            const params = new URLSearchParams();
            params.append("objectpickerparam", objectPickerParamStr);
            params.append("objectpickertype", "2");
            params.append("objectpickervalue", props.modelValue); //需回显的值

            axios
                .post(props.url, params, {
                  headers: {
                    "Content-Type": "application/x-www-form-urlencoded", // 必须手动设置！
                  },
                })
                .then((response) => {
                  // alert(JSON.stringify(response.data));

                  if ("timeout" == response.data.statusText) {
                    alert("网络超时!");
                    return;
                  }

                  if (response.data.result) {
                    const keys = Object.keys(response.data.result);
                    if (keys.length === 1) {
                      let code = keys[0];
                      let desc = response.data.result[keys[0]];
                      if (props.opt)
                        props.opt.length = 0; //通过修改数组的length属性，直接清空数组元素，内存会被自动释放。这是性能最优的方式
                      else {
                        props.opt = [];
                      }
                      props.opt.push({ label: desc, value: code });
                      updateSelectItem();

                      // alert('props.opt:'+JSON.stringify(props.opt));
                    }
                  }
                });
          }
        } catch (error) {
          // callback(null, error.message); // 失败回调，传递错误
        }
      }

      // Vue.onMounted(updateSelectItem);

      const doSelectItem = (item) => {
        emit("update:modelValue", item.value);
        selectItem.value = item;
        inputText.value = item.label;
        hidePopup();
        nextTick(() => {
          console.log(item.value + "@@@props.modelValue:" + props.modelValue);
          validate();
          if (window.ssVm) {
            // 遍历所有验证规则，找到依赖当前字段的规则
            for (const [field, rules] of window.ssVm.validations.entries()) {
              for (const rule of rules) {
                if (rule.opt?.relField === props.name) {
                  // console.log("Found dependent field:", field); // 调试日志
                  window.ssVm.validateField(field);
                }
              }
            }
          }
        });
      };

      //可录入的objPicker，更新下拉菜单选项
      async function updateOptionBYInputText(inpTxt) {
        try {
          let objectPickerParam;
          let url = props.url;

          if (props.url && props.cb) {
            //如果有定义过滤器
            if (props.filter) {
              //包含HTML实体的JSON字符串转为JSON对象,如原字符串是{&quot;dwid&quot;:&quot;88&quot;},注意key也必需用单引号包着
              const decodedString = props.filter.replace(/&quot;/g, '"'); // 转换为: {"dwid":"88"}
              objectPickerParam = JSON.parse(decodedString); // 转为json对象
              objectPickerParam["input"] = props.inp;
              objectPickerParam["codebook"] = props.cb;

              const filterObj = JSON.parse(decodedString); // 转为json对象
              for (let k in filterObj) {
                let v = filterObj[k];
                url += "&" + k + "=" + v;
              }

              // alert(url);
            } else {
              objectPickerParam = { input: props.inp, codebook: props.cb };
            }

            const objectPickerParamStr = JSON.stringify(objectPickerParam);
            const params = new URLSearchParams();
            params.append("objectpickerparam", objectPickerParamStr);
            params.append("objectpickertype", "1");
            if (props.inp && props.inp === "true") {
              params.append("objectpickersearchAll", 0); //只查录入的值
              params.append("objectpickerinput", inpTxt); //录入的值
            } else {
              params.append("objectpickersearchAll", 1);
            }

            axios
                .post(url, params, {
                  headers: {
                    "Content-Type": "application/x-www-form-urlencoded", // 必须手动设置！
                  },
                })
                .then((response) => {
                  if ("timeout" == response.data.statusText) {
                    alert("网络超时!");
                    return;
                  }

                  if (response.data.result) {
                    const keys = Object.keys(response.data.result);
                    // console.log("params:"+params+"@@response.data:"+JSON.stringify(response.data));
                    if (keys.length > 0) {
                      if (props.opt)
                        props.opt.length = 0; //通过修改数组的length属性，直接清空数组元素，内存会被自动释放。这是性能最优的方式
                      else {
                        props.opt = [];
                      }
                      for (let k in response.data.result) {
                        props.opt.push({
                          label: response.data.result[k],
                          value: k,
                        });
                      }

                      // console.log('###inpTxt:'+inpTxt+';');
                      if (
                          props.inp &&
                          props.inp === "true" &&
                          inpTxt.length > 0
                      ) {
                        //对于可录入的，用已录入的值作过滤

                        filteredOptions.value = props.opt.filter((option) =>
                            option.label
                                .toLowerCase()
                                .includes(inputText.value.toLowerCase())
                        );
                        filteredOptions.value.unshift({ label: "", value: "" });

                        // console.log('###做了过滤:'+inputText.value.toLowerCase()+';');
                      } else {
                        filteredOptions.value = props.opt;
                        filteredOptions.value.unshift({ label: "", value: "" });
                      }

                      if (!popupWinVisible.value) {
                        popupWinVisible.value = true; // 确保下拉框在输入时打开
                      }

                      console.log("props.opt11:" + JSON.stringify(props.opt));
                    }
                  }
                });
          }
        } catch (error) {
          // callback(null, error.message); // 失败回调，传递错误
        }
      }

      // 计算弹出方向的方法
      const calculatePopupDirection = () => {
        // 1. 获取select容器元素
        const selectEl = document
            .querySelector(`[name="${props.name}"]`)
            ?.closest(".select-container");
        if (!selectEl) return;

        // 2. 获取位置信息
        const selectRect = selectEl.getBoundingClientRect();
        const viewportHeight = window.innerHeight;

        // 3. 简单判断：如果下方剩余空间小于300px就向上弹出
        const spaceBelow = viewportHeight - selectRect.bottom;

        // 调试信息
        // console.log('空间判断:', {
        //   elementBottom: selectRect.bottom,
        //   viewportHeight,
        //   spaceBelow,
        //   willPopUp: spaceBelow < 300,
        //   popupDirection: popupDirection.value
        // });

        // 4. 设置方向
        popupDirection.value = spaceBelow < 300 ? "top" : "bottom";
      };

      //点击下拉菜单的文本区域时，会触发的方法
      function togglePopup() {
        //可录入的objPicker，更新下拉菜单选项
        updateOptionBYInputText(inputText.value);
        // popupWinVisible.value = !popupWinVisible.value;
        Vue.nextTick(() => {
          calculatePopupDirection();
        });
      }

      const hidePopup = () => {
        popupWinVisible.value = false;
      };

      //点击下拉菜单的三角形时，会触发的方法
      const suffixClick = () => {
        //可录入的objPicker，更新下拉菜单选项
        updateOptionBYInputText("");
        // popupWinVisible.value = !popupWinVisible.value;
        Vue.nextTick(() => {
          calculatePopupDirection();
        });
        console.log("点三角");
      };

      //可录入的objPicker，录入项变化时，会触发
      async function handleInputChange(event) {
        inputText.value = event.target.value;
        if (!inputText.value) {
          inputText.value = "";
        }

        //可录入的objPicker，更新下拉菜单选项
        updateOptionBYInputText(inputText.value);

        // filteredOptions.value = props.opt.filter((option) =>
        //     option.label.toLowerCase().includes(inputText.value.toLowerCase())
        // );
        // if (!popupWinVisible.value) {
        //   popupWinVisible.value = true; // 确保下拉框在输入时打开
        // }
      }
      Vue.onMounted(() => {
        initDefaultValue();
        window.addEventListener("resize", calculatePopupDirection);
      });
      Vue.onUnmounted(() => {
        window.removeEventListener("resize", calculatePopupDirection);
      });

      return {
        errMsg,
        selectItem,
        inputText,
        canInput,
        filteredOptions,
        popupWinVisible,
        popupDirection,
        suffixClick,
        togglePopup,
        hidePopup,
        doSelectItem,
        handleInputChange,
      };
    },

    template: `
      <div class="input" style="position: relative" :style="{width: width}">
        <div class="select-container" @mouseleave="hidePopup">
          <div class="input" @click="togglePopup">
            <input 
              type="hidden"
              :name="name"
              :value="selectItem.value"
              .value="selectItem.value" 
            />
            <input
              v-model="inputText"
              @input="handleInputChange"
              v-if="canInput"
              :placeholder="placeholder"
              
            />
            
            <input
              v-else
              :placeholder="placeholder"
              :value="selectItem.label"
              
              disabled
              style="pointer-events: none;"
            />
           
            <div class="suffix" @click.stop="suffixClick">
              <ss-form-icon :class="popupWinVisible ? 'form-icon-transform-select select' : 'form-icon-select'" />
              
            </div>
          </div>
         
            
          <div v-show="popupWinVisible" class="popup-win" :class="popupDirection">
            <div v-if="opt && opt.length && filteredOptions.length > 0" class="popup-content">
              <div class="content-area">
                <div v-for="(item, index) in filteredOptions" :key="index" @click="doSelectItem(item)" :class="{ active: item.value === selectItem.value }">
                  <span class="check-icon">
                   
                    <ss-form-icon class="form-icon-select-checked" />
                  </span>
                  <span>{{ item.label }}</span>
                </div>
              </div>
            </div>
            <div v-else class="popup-content"><div class="content-area"><div class="content-area"> <span>无选项</span></div></div></div>
          </div>
        </div>
      </div>

    `,
  };
  // ss-hidden 隐藏字段组件
  const SsHidden = {
    name: "SsHidden",
    props: {
      modelValue: String,
      name: {
        type: String,
        required: true,
      },
      rule: {
        type: String,
        required: true,
      },

      param: {
        type: String,
        required: true,
      },
      url: {
        type: String,
        required: true,
      },
    },
    emits: ["update:modelValue"],

    setup(props, { emit }) {
      const errMsg = Vue.ref("");
      const validate = () => {
        if (window.ssVm) {
          const result = window.ssVm.validateField(props.name);
          console.log("validate", window.ssVm.validateField(props.name));
          errMsg.value = result.valid ? "" : result.message;
        }
      };
      Vue.onMounted(() => {
        /**
         * 初始化级联菜单值初始值思路：
         * 1. 带隐藏字段（即带编码规则）的级联菜单
         *  在隐藏字段这，可以取到要回显的值和编码规则，从而计算出各级下拉菜单要回显的值。
         *  然后通过ajax取各级级联菜单的值回显。
         *  2. 不带隐藏字段的级联，只能在各个下拉菜单的setup事件中通过ajax取回显值回显
         */

        // 当同组级联下拉菜单选中值变化时，会调用本隐藏字段下面这方法设置隐藏字段值
        window.addEventListener(
            "cascader-setHiddenVal-" + props.name,
            (event) => {
              const { value } = event.detail;
              emit("update:modelValue", value);
              console.log(value);
              setTimeout(() => {
                validate();
              }, 50);
            }
        );

        // 如果有初始值，触发回显过程
        if (props.modelValue) {
          console.log("级联隐藏字段，开始回显，初始值:", props.modelValue);
          triggerCascaderEcho(props.modelValue);
          validate();
        }
      });

      // 触发级联回显
      const triggerCascaderEcho = (code) => {
        /**
         * 开始回显，初始值: 440304
         * 解析后的所有值: Array(3)0: "440000"1: "440300"2: "440304"length: 3[[Prototype]]: Array(0)
         */
        const values = parseHiddenCodeForAll(code, props.rule);
        console.log("解析后的所有值:", values);

        // 转换为 JSON 对象
        // const paramObj = JSON.parse(props.param);
        const paramObj = props.param;
        let selectArr = paramObj.fieldOrd; //保存本组级联菜单项的数组，如：['hksheng','hkshi','hkxian']
        if (selectArr.length != values.length) {
          // alert('属性'+props.name+'的值'+code+'与级联菜单中下拉菜单的数目不匹配!');
          return;
        }

        // 按顺序触发回显，并增加延迟确保数据加载
        /**
         * 通过隐藏字段的setup事件，
         * 循环遍历各级下拉菜单，并触发定义在下拉菜单中的'cascader-echo'事件，
         * 在此事件中完成每个下拉菜单回显值操作（只取当前要回显的键值对显示，
         * 下拉菜单所有的值，在点击下拉菜单时，才通过ajax取）。
         */
        values.forEach((value, index) => {
          if (value) {
            setTimeout(() => {
              let upperVal = undefined;
              if (index != 0) {
                upperVal = values[index - 1];
              }

              const echoEvent = new CustomEvent(
                  "cascader-echo-" + selectArr[index],
                  {
                    detail: {
                      name: props.name,
                      value: value,
                      // level: index + 1,
                      isAuto: true, // 标记为自动回显
                      upperVal: upperVal,
                    },
                  }
              );

              console.log(props.name + "--upperValue:" + upperVal);

              window.dispatchEvent(echoEvent);
            }, index * 500); // 每级增加500ms延迟
          }
        });
      };

      // 解析所有级别的代码
      const parseHiddenCodeForAll = (code, rule) => {
        if (!code || !rule) return [];

        // 获取规则中每段的长度
        const segments = [];
        let currentChar = rule[0];
        let currentLength = 1;

        for (let i = 1; i < rule.length; i++) {
          if (rule[i] === currentChar) {
            currentLength++;
          } else {
            segments.push(currentLength);
            currentChar = rule[i];
            currentLength = 1;
          }
        }
        segments.push(currentLength);

        // 解析每一级的值
        const values = [];
        let position = 0;

        segments.forEach((length, index) => {
          const value = code
              .substring(0, position + length)
              .padEnd(rule.length, "0");
          values.push(value);
          position += length;
        });

        return values;
      };
      watchEffect(() => {});
      return {};
    },
    template: `<input type="hidden" :name="name" :value="modelValue">`,
  };
  // ss-cascader 级联选择器
  const SsCcp = {
    name: "SsCcp",
    inheritAttrs: false,
    props: {
      modelValue: String,

      name: {
        type: String,
        required: true,
      },
      level: {
        type: Number,
        required: true,
      },
      opt: {
        type: Array,
        default: () => [],
      },
      placeholder: {
        type: String,
        default: "请选择",
      },
      width: {
        type: String,
        default: "150px",
      },
      direction: {
        type: String,
        default: "bottom",
      },
      mode: {
        type: String,
        default: "1",
      },

      //级联菜单配置参数，如果是数组，则代表本下拉菜单是多套级联菜单共用的第一级菜单。如果是对象，则只有一套级联菜单用此下拉菜单。
      param: {
        type: String,
        required: true,
      },
      //向后台拿数据的url
      url: {
        type: String,
        required: true,
      },
    },
    emits: ["update:modelValue", "change"],

    setup(props, { emit }) {
      // alert('级联菜单初始化：'+props.name+':--:'+props.modelValue);
      const selectItem = Vue.ref({ label: props.placeholder, value: "" });
      const popupWinVisible = Vue.ref(false);
      const isAutoEcho = Vue.ref(false); // 用于标记是否是自动回显
      const upperValue = Vue.ref(""); //上级下拉菜单当前值，在初始化下拉菜单默认值时，和上级下拉菜单的值变化时，修改此upperValue变量
      const popupDirection = Vue.ref("bottom");

      //有隐藏字段的下拉菜单，加载菜单项并展开事件
      // 被上级下拉菜单选中值后，触发本下拉菜单刷新菜单项并弹出显示
      window.addEventListener("cascader-open-" + props.name, async (event) => {
        const { upperVal } = event.detail;
        upperValue.value = upperVal;
        console.log(
            "22props.name:" +
            props.name +
            ",22props.upperValue:" +
            upperValue.value
        );

        selectItem.value = ""; //清除本下拉菜单当前选中的值
        emit("update:modelValue", ""); //通知父级

        //清空下拉菜单，并设置第一项的值为placeholder
        clearAndInit1stOpt();

        //下个下拉菜单名
        let nextSelName = getNextSel(props.name, props.param.fieldOrd);
        if (nextSelName) {
          //清下个下拉菜单选中值和选项
          event = new CustomEvent("cascader-cleanOpt-" + nextSelName, {
            detail: {},
          });
          window.dispatchEvent(event);
        }

        showPopup();
      });

      //设置mode2的下级下拉菜单的上级菜单当前值
      function setNextSelectUpperValue() {
        //设置下级菜单的上级菜单当前值upperValue
        let paramArr = undefined;
        if (Array.isArray(props.param)) {
          paramArr = props.param;
        } else {
          paramArr = [];
          paramArr.push(props.param);
        }

        for (const oneParam of paramArr) {
          //下个下拉菜单名
          const nextSelName = getNextSel(props.name, oneParam.fieldOrd);
          if (nextSelName) {
            setTimeout(() => {
              const openNextEvent = new CustomEvent(
                  "cascade-setUpperVal-" + nextSelName,
                  {
                    detail: {
                      upperVal: props.modelValue,
                    },
                  }
              );
              window.dispatchEvent(openNextEvent);
            }, 100);
          }
        } // end for
      }

      // 把上级 级联下拉菜单的值，设置进本组件的事件
      window.addEventListener("cascade-setUpperVal-" + props.name, (event) => {
        // alert('props.name:'+props.name+',props.upperValue:'+event.detail.upperVal);
        const { upperVal } = event.detail;
        upperValue.value = upperVal;

        // console.log('props.name:'+props.name+',props.upperValue:'+upperValue.value);
      });

      //清空下拉菜单，并设置第一项的值为空
      function clearAndInit1stOpt() {
        if (props.opt)
          props.opt.length = 0; //通过修改数组的length属性，直接清空数组元素，内存会被自动释放。这是性能最优的方式
        else {
          props.opt = [];
        }
        props.opt.push({ label: "", value: "" });
      }

      //获取下一级下拉菜单，如果下一级下拉菜单不存在，则返回undefined
      function getNextSel(selName, selNameArr) {
        // 检查参数有效性
        if (!Array.isArray(selNameArr) || selNameArr.length === 0) {
          return undefined;
        }

        // 查找当前元素的索引
        const currentIndex = selNameArr.indexOf(selName);

        // 如果元素不存在或已经是最后一个元素，返回undefined
        if (currentIndex === -1 || currentIndex === selNameArr.length - 1) {
          return undefined;
        }

        // 返回下一个元素
        return selNameArr[currentIndex + 1];
      }

      // 处理选择事件
      const doSelectItem = (item) => {
        selectItem.value = item;
        emit("update:modelValue", item.value); //修改本下拉菜单在vue中保存的值

        // alert('item.value:'+item.value);
        if (props.mode === "1") {
          // mode 1 模式：修改隐藏字段值

          let event = new CustomEvent(
              "cascader-setHiddenVal-" + props.param.combField,
              {
                detail: {
                  value: item.value,
                },
              }
          );
          window.dispatchEvent(event);
        }
        emit("change", item.value); //触发配置的change方法

        //设置下级菜单的上级菜单当前值upperValue
        let paramArr = undefined;
        if (Array.isArray(props.param)) {
          paramArr = props.param;
        } else {
          paramArr = [];
          paramArr.push(props.param);
        }

        for (const oneParam of paramArr) {
          //下个下拉菜单名
          const nextSelName = getNextSel(props.name, oneParam.fieldOrd);
          if (nextSelName) {
            setTimeout(() => {
              const openNextEvent = new CustomEvent(
                  "cascader-open-" + nextSelName,
                  {
                    detail: {
                      upperVal: item.value,
                    },
                  }
              );
              window.dispatchEvent(openNextEvent);
            }, 100);
          }
        } // end for

        hidePopup();

        //下个下拉菜单名
        // let nextSelName = getNextSel(props.name, props.param.fieldOrd);
        // if(nextSelName){
        //   // //设置下一级下拉菜单中保存的本下拉菜单值（upperValue）
        //   // event = new CustomEvent('cascade-setUpperVal-'+nextSelName, {
        //   //   detail: {
        //   //     value: item.value
        //   //   }
        //   // });
        //   // window.dispatchEvent(event);
        //
        //   //触发下一级下拉菜单，重新初始化下拉菜单项并弹出显示
        //   event = new CustomEvent('cascader-open-' +nextSelName, {
        //     detail: {
        //       upperVal: item.value
        //     }
        //   });
        //   window.dispatchEvent(event);
        // }

        // 只在手动选择时自动展开下一级
        // if (!isAutoEcho.value) {
        //   const nextLevel = props.level + 1;
        //   setTimeout(() => {
        //     const openNextEvent = new CustomEvent('open-next-cascader', {
        //       detail: {
        //         name: props.name,
        //         level: nextLevel
        //       }
        //     });
        //     window.dispatchEvent(openNextEvent);
        //   }, 100);
        // }
      };

      // 监听下一级展开事件 (仅 mode 2)
      window.addEventListener("cascade-open", (event) => {
        if (props.mode === "2") {
          const { level } = event.detail;
          if (level === props.level) {
            popupWinVisible.value = true;
          }
        }
      });

      if (props.mode === "1") {
        //如果是有隐藏字段的下拉菜单
        // 监听回显事件
        window.addEventListener(
            "cascader-echo-" + props.name,
            async (event) => {
              const { name, value, isAuto, upperVal } = event.detail;
              // level,
              if (upperVal) {
                upperValue.value = upperVal;
                console.log(
                    "value:" +
                    value +
                    ",upperValue:" +
                    upperValue +
                    ",初始化级联组件时props.name:" +
                    props.name
                );
              }

              // if (name === props.name && level === props.level) {
              // 设置自动回显标记
              isAutoEcho.value = true;

              // if (props.opt.length === 0) {
              // const loadDataEvent = new CustomEvent('cascader-load-data', {
              //   detail: {
              //     name: props.name,
              //     level: props.level,
              //     value: value
              //   }
              // });
              // window.dispatchEvent(loadDataEvent);

              //下面的代码只用于页面刚打开时，初始化级联菜单的回显值。

              //Vue.watch用于监听数据的变化，并在数据变化时执行特定的回调函数。
              //这段代码使用了 Vue.js 的 watch API 来监听 props.opt 的变化，如果props.opt有变化，则自动

              //   const unwatch = Vue.watch(
              //       () => props.opt,                // 监听的数据源（props.opt）
              //       (newOptions) => {              // 回调函数
              //         if (newOptions.length > 0) { // 条件判断
              //           matchAndSelect(value);     // 执行逻辑
              //           unwatch();                 // 停止监听
              //         }
              //       },
              //       { immediate: true }            // 配置：立即触发一次
              //   );
              // } else {
              //   matchAndSelect(value);
              // }

              // 初始化级联菜单在页面刚打开时的默认值
              async function initDefaultValue(value) {
                try {
                  // alert(1);
                  if (props.url && props.param && props.modelValue) {
                    // alert(2);
                    /**
                     *         let objectPickerParam=
                     *             {"objectpickerparam":"{\"input\":\"false\",\"cascadingLevel\":\"hksheng,hkshi,hkxian\"," +
                     *                     "\"name\":\"hksheng\"," +
                     *                     "\"cascadingName\":\"dq\",\"cascadingInputsName\":\"hkdqm\"," +
                     *                     "\"codebook\":\"sheng\"}",
                     *                 "objectpickertype":2,
                     *                 "objectpickervalue":"440000"
                     *             };
                     */

                    const objectPickerParam = {
                      input: "false",
                      cascadingLevel: props.param.fieldOrd.join(","), //如："hksheng,hkshi,hkxian"
                      name: props.name, //本下拉菜单名
                      cascadingName: props.param.name, //级联菜单名
                      cascadingInputsName: props.param.combField, //对象属性，即隐藏字段名，如：hkdqm
                      codebook: props.param.codebook,
                    };

                    const objectPickerParamStr =
                        JSON.stringify(objectPickerParam);

                    const params = new URLSearchParams();
                    params.append("objectpickerparam", objectPickerParamStr);
                    params.append("objectpickertype", "2");
                    params.append("objectpickervalue", value); //需回显的值

                    axios
                        .post(props.url, params, {
                          headers: {
                            "Content-Type": "application/x-www-form-urlencoded", // 必须手动设置！
                          },
                        })
                        .then((response) => {
                          // alert(JSON.stringify(response.data));

                          if ("timeout" == response.data.statusText) {
                            alert("网络超时!");
                            return;
                          }

                          if (response.data.result) {
                            const keys = Object.keys(response.data.result);
                            if (keys.length === 1) {
                              let code = keys[0];
                              let desc = response.data.result[keys[0]];
                              clearAndInit1stOpt();
                              props.opt.push({ label: desc, value: code });

                              if (value) matchAndSelect(value);
                              // updateSelectItem();

                              // alert('props.opt:'+JSON.stringify(props.opt));
                            }
                          }
                        });
                  }
                } catch (error) {
                  alert(error);
                  // callback(null, error.message); // 失败回调，传递错误
                }
              }

              //下面的代码只用于页面刚打开时，初始化级联菜单的回显值。
              initDefaultValue(value);

              // 延迟重置自动回显标记
              setTimeout(() => {
                isAutoEcho.value = false;
              }, 500);
            }
        );

        // 被上级下拉菜单触发的，清除选中值和下拉菜单选项
        window.addEventListener(
            "cascader-cleanOpt-" + props.name,
            async (event) => {
              upperValue.value = "";

              selectItem.value = ""; //清除本下拉菜单当前选中的值
              emit("update:modelValue", ""); //通知父级

              //清空所有下拉菜单项
              if (props.opt) {
                props.opt.length = 0;
              } else {
                props.opt = [];
              }

              //下个下拉菜单名
              let nextSelName = getNextSel(props.name, props.param.fieldOrd);
              // alert('nextSelName:'+nextSelName+'--,props.name:'+props.name);
              if (nextSelName) {
                //清下个下拉菜单选中值和选项
                event = new CustomEvent("cascader-cleanOpt-" + nextSelName, {
                  detail: {},
                });
                window.dispatchEvent(event);
              }
            }
        );
      } else if (props.mode === "2") {
        //没隐藏字段的下拉菜单，在这初始化默认值

        let needInitParam = undefined;
        if (Array.isArray(props.param)) {
          needInitParam = props.param[props.param.length - 1]; //只初始化数组最后一项
          console.log("needInitParam最后一项:" + JSON.stringify(needInitParam));
        } else {
          needInitParam = props.param;
        }

        // 初始化级联菜单在页面刚打开时的默认值
        async function initDefaultValue(value, param) {
          try {
            // alert(1);
            if (props.url && param && props.modelValue) {
              // alert(2);
              /**
               *        let param=
               *             {"objectpickerparam":"{\"input\":\"false\",\"cascadingLevel\":\"rylbm,gwid\"," +
               *                     "\"name\":\"gwid\",\"cascadingName\":\"rylb_gw\"," +
               *                     "\"codebook\":\"gwByRylb\"}",
               *                 "objectpickertype":2,
               *                 "objectpickervalue":"102121"};
               */

                  // alert('props.name:'+props.name+',props.param.fieldOrd:'+props.param.fieldOrd);

              const objectPickerParam = {
                    input: "false",
                    cascadingLevel: param.fieldOrd.join(","), //如："hksheng,hkshi,hkxian"
                    name: props.name, //本下拉菜单名
                    cascadingName: param.name, //级联菜单名
                    codebook: param.codebook,
                  };

              const objectPickerParamStr = JSON.stringify(objectPickerParam);

              const sendParams = new URLSearchParams();
              sendParams.append("objectpickerparam", objectPickerParamStr);
              sendParams.append("objectpickertype", "2");
              sendParams.append("objectpickervalue", value); //需回显的值

              axios
                  .post(props.url, sendParams, {
                    headers: {
                      "Content-Type": "application/x-www-form-urlencoded", // 必须手动设置！
                    },
                  })
                  .then((response) => {
                    // alert(JSON.stringify(response.data));

                    if ("timeout" == response.data.statusText) {
                      alert("网络超时!");
                      return;
                    }

                    if (response.data.result) {
                      const keys = Object.keys(response.data.result);

                      console.log(
                          "name:" +
                          props.name +
                          ",@@级联初始化默认值value：" +
                          value +
                          "--param:" +
                          JSON.stringify(param) +
                          "--objectPickerParamStr:" +
                          objectPickerParamStr +
                          "--response.data:" +
                          JSON.stringify(response.data)
                      );

                      if (keys.length === 1) {
                        let code = keys[0];
                        let desc = response.data.result[keys[0]];

                        if (props.opt)
                          props.opt.length = 0; //通过修改数组的length属性，直接清空数组元素，内存会被自动释放。这是性能最优的方式
                        else {
                          props.opt = [];
                        }
                        props.opt.push({ label: desc, value: code });

                        if (value) matchAndSelect(value);

                        console.log(
                            "GOOD mode2回显的默认值：" +
                            JSON.stringify({ label: desc, value: code }) +
                            "--props.param:" +
                            JSON.stringify(param)
                        );

                        // updateSelectItem();

                        // alert('props.opt:'+JSON.stringify(props.opt));
                      }
                    }
                  });
            }
          } catch (error) {
            alert(error);
            // callback(null, error.message); // 失败回调，传递错误
          }

          // 重置自动回显标记
          isAutoEcho.value = false;
        }

        // 初始化级联菜单在页面刚打开时的默认值
        initDefaultValue(props.modelValue, needInitParam);

        //设置mode2的下级下拉菜单的上级菜单当前值
        setNextSelectUpperValue();
      }

      //选中要回显的默认值
      const matchAndSelect = (value) => {
        const matchedOption = props.opt.find((opt) => opt.value === value);
        if (matchedOption) {
          selectItem.value = matchedOption;
          emit("update:modelValue", value);
          emit("change", value);
        }
      };

      const calculatePopupDirection = () => {
        // 1. 获取select容器元素
        const selectEl = document.querySelector(
            `[name="${props.name}"]`
        )?.nextElementSibling;
        console.log("selectEl:" + selectEl, props.name);
        if (!selectEl) return;

        // 2. 获取位置信息
        const selectRect = selectEl.getBoundingClientRect();
        const viewportHeight = window.innerHeight;

        // 3. 简单判断：如果下方剩余空间小于300px就向上弹出
        const spaceBelow = viewportHeight - selectRect.bottom;

        // 调试信息
        console.log("空间判断:", {
          elementBottom: selectRect.bottom,
          viewportHeight,
          spaceBelow,
          willPopUp: spaceBelow < 300,
          popupDirection: popupDirection.value,
        });

        // 4. 设置方向
        popupDirection.value = spaceBelow < 300 ? "top" : "bottom";
      };
      //级联菜单点击事件
      const togglePopup = () => {
        if (!popupWinVisible.value) {
          //如果当前下拉菜单是隐藏的，先ajax重新加载下拉菜单项，再显示。

          showPopup();
        } else {
          hidePopup();
        }
      };

      //显示下拉菜单，在此之前先清除下拉菜单项
      const showPopup = () => {
        //清空下拉菜单，并设置第一项的值为空
        clearAndInit1stOpt();
        Vue.nextTick(() => {
          calculatePopupDirection();
        });
        let url = props.url;
        let filterObj = props.param.filter;

        if (filterObj) {
          for (let k in filterObj) {
            let v = filterObj[k];
            url += "&" + k + "=" + v;
          }
        }

        if (props.mode === "1") {
          //如果是有隐藏字段的下拉菜单

          console.log("666url:" + url);

          // alert('url:'+url);

          // 获取级联菜单所有下拉菜单项
          async function getSelectItems(value) {
            try {
              // alert(1);
              if (props.url && props.param) {
                // alert(2);
                /**
                 *            param={"objectpickerparam":"{\"input\":\"false\",\"cascadingLevel\":\"hksheng,hkshi,hkxian\"," +
                 *                     "\"name\":\"hksheng\",\"cascadingName\":\"dq\"," +
                 *                     "\"cascadingInputsName\":\"hkdqm\",\"codebook\":\"sheng\"}",
                 *                 "objectpickertype":1,//2表示获取要回显的一项，1表示获取所有下拉菜单项
                 *                 "upperValue":"440000"
                 *             };
                 */

                const objectPickerParam = {
                  input: "false",
                  cascadingLevel: props.param.fieldOrd.join(","), //如："hksheng,hkshi,hkxian"
                  name: props.name, //本下拉菜单名
                  cascadingName: props.param.name, //级联菜单名
                  cascadingInputsName: props.param.combField, //对象属性，即隐藏字段名，如：hkdqm
                  codebook: props.param.codebook,
                };

                console.log("mode1 upperValue.value:" + upperValue.value);

                const objectPickerParamStr = JSON.stringify(objectPickerParam);

                const params = new URLSearchParams();
                params.append("objectpickerparam", objectPickerParamStr);
                params.append("objectpickertype", "1");
                if (upperValue.value) {
                  params.append("upperValue", upperValue.value);
                }
                // params.append('objectpickervalue', value); //需回显的值

                axios
                    .post(url, params, {
                      headers: {
                        "Content-Type": "application/x-www-form-urlencoded", // 必须手动设置！
                      },
                    })
                    .then((response) => {
                      if ("timeout" == response.data.statusText) {
                        alert("网络超时!");
                        return;
                      }

                      if (response.data.result) {
                        const keys = Object.keys(response.data.result);
                        console.log(
                            "params:" +
                            params +
                            "@@response.data:" +
                            JSON.stringify(response.data)
                        );

                        if (keys.length > 0) {
                          for (let k in response.data.result) {
                            props.opt.push({
                              label: response.data.result[k],
                              value: k,
                            });
                          }

                          if (!popupWinVisible.value) {
                            popupWinVisible.value = true; // 确保下拉框打开
                          }

                          console.log("props.opt11:" + JSON.stringify(props.opt));
                        }
                      }
                    });
              }
            } catch (error) {
              alert(error);
              // callback(null, error.message); // 失败回调，传递错误
            }
          }

          getSelectItems(props.modelValue);
        } else if (props.mode === "2") {
          //没隐藏字段的下拉菜单

          let needInitParam = undefined;
          if (Array.isArray(props.param)) {
            needInitParam = props.param[props.param.length - 1]; //只初始化数组最后一项
            console.log(
                "needInitParam最后一项:" + JSON.stringify(needInitParam)
            );
          } else {
            needInitParam = props.param;
          }

          // 获取级联菜单所有下拉菜单项
          async function getSelectItems(value, sendParam) {
            try {
              // alert(1);
              if (props.url && sendParam) {
                // alert(2);
                /**
                 *            param="{\"input\":\"false\",\"cascadingLevel\":\"dwid,sjryid\",
                 *            \"ryid\":\"111121\",\"name\":\"sjryid\",
                 *            \"cascadingName\":\"dw_sjry\",\"codebook\":\"sjryByDw\"}"
                 */

                const objectPickerParam = {
                  input: "false",
                  cascadingLevel: sendParam.fieldOrd.join(","), //如："hksheng,hkshi,hkxian"
                  name: props.name, //本下拉菜单名
                  cascadingName: sendParam.name, //级联菜单名
                  codebook: sendParam.codebook,
                };

                console.log("mode2 upperValue.value:" + upperValue.value);

                const objectPickerParamStr = JSON.stringify(objectPickerParam);

                const params = new URLSearchParams();
                params.append("objectpickerparam", objectPickerParamStr);
                params.append("objectpickertype", "1");
                if (upperValue.value) {
                  params.append("upperValue", upperValue.value);
                }
                // params.append('objectpickervalue', value); //需回显的值

                axios
                    .post(url, params, {
                      headers: {
                        "Content-Type": "application/x-www-form-urlencoded", // 必须手动设置！
                      },
                    })
                    .then((response) => {
                      if ("timeout" == response.data.statusText) {
                        alert("网络超时!");
                        return;
                      }

                      if (response.data.result) {
                        const keys = Object.keys(response.data.result);
                        console.log(
                            "params:" +
                            params +
                            "@@response.data:" +
                            JSON.stringify(response.data)
                        );

                        if (keys.length > 0) {
                          for (let k in response.data.result) {
                            props.opt.push({
                              label: response.data.result[k],
                              value: k,
                            });
                          }

                          if (!popupWinVisible.value) {
                            popupWinVisible.value = true; // 确保下拉框打开
                          }

                          console.log("props.opt11:" + JSON.stringify(props.opt));
                        }
                      }
                    });
              }
            } catch (error) {
              alert(error);
              // callback(null, error.message); // 失败回调，传递错误
            }
          }

          getSelectItems(props.modelValue, needInitParam);

          // popupWinVisible.value = !popupWinVisible.value;
        }
      };

      const hidePopup = () => {
        popupWinVisible.value = false;
      };

      // 合并所有的 onMounted 逻辑
      Vue.onMounted(() => {
        window.addEventListener("resize", calculatePopupDirection);

        // 1. 监听展开下一级事件
        window.addEventListener("open-next-cascader", (event) => {
          const { name, level } = event.detail;
          if (name === props.name && level === props.level) {
            popupWinVisible.value = true;
          }
        });

        // 2. 监听级联事件
        window.addEventListener("cascader-change", (event) => {
          const { name, level, value } = event.detail;
          if (name === props.name && level < props.level) {
            selectItem.value = { label: "", value: "" };
            emit("update:modelValue", "");
            if (ssHidden) {
              ssHidden.updateValue(value);
            }
          }
        });
      });
      Vue.onUnmounted(() => {
        window.removeEventListener("resize", calculatePopupDirection);
      });
      // 监听值变化，处理回显 (mode 2)
      Vue.watch(
          () => props.modelValue,
          (newVal) => {
            if (props.mode === "2" && newVal) {
              // 使用 watchEffect 替代嵌套的 watch
              Vue.watchEffect(() => {
                if (props.opt.length > 0) {
                  const matchedOption = props.opt.find(
                      (opt) => opt.value === newVal
                  );
                  if (matchedOption) {
                    selectItem.value = matchedOption;
                  }
                }
              });
            } else {
              // 原有的值变化处理
              const item = props.opt.find((it) => it.value === newVal);
              if (item) {
                selectItem.value = item;
              } else {
                selectItem.value = { label: "", value: "" };
              }
            }
          },
          { immediate: true }
      );

      // 监听选项变化，当数据加载完成时进行匹配
      Vue.watch(
          () => props.opt,
          (newOptions) => {
            if (newOptions.length > 0) {
              const matchedOption = newOptions.find(
                  (opt) => opt.value === selectItem.value.value
              );
              if (matchedOption) {
                selectItem.value = matchedOption;
                emit("update:modelValue", matchedOption.value);
                emit("change", matchedOption.value);
              }
            }
          }
      );

      return {
        selectItem,
        popupWinVisible,
        popupDirection,
        togglePopup,
        hidePopup,
        doSelectItem,
      };
    },

    template: `
      <div class="input" style="position: relative" :style="{width: width}">
        <input type="hidden" :name="name" :value="modelValue">
        <div class="select-container" @mouseleave="hidePopup">
          <div class="input" @click="togglePopup">
            <input 
              type="hidden"
              :name="name"
              :value="selectItem.value"
            />
            <input
              :placeholder="placeholder"
              :value="selectItem.label"
              disabled
              style="pointer-events: none;"
            />
            <div class="suffix">
              <ss-form-icon :class="popupWinVisible ? 'form-icon-transform-select select' : 'form-icon-select'" />
            </div>
          </div>

          <div v-show="popupWinVisible" class="popup-win " :class="popupDirection">
            <div v-if="opt && opt.length > 0" class="popup-content">
              <div class="content-area">
                <div 
                  v-for="(item, index) in opt" 
                  :key="index" 
                  @click="doSelectItem(item)" 
                  :class="{ active: item.value === selectItem.value }"
                >
                  <span class="check-icon">
                    <ss-form-icon class="form-icon-select-checked" />
                  </span>
                  <span>{{ item.label }}</span>
                </div>
              </div>
            </div>
            <div v-else class="popup-content">
              <div class="content-area">
                <div class="content-area">
                  <span>无选项</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    `,
  };
  // ss-date-picker 日期时间选择器组件
  const SsDatePicker = {
    name: "SsDatePicker",
    props: {
      modelValue: {
        type: [String, Number, Date],
        default: "",
      },
      name: {
        type: String,
        required: true,
      },
      type: {
        type: String,
        default: "date",
        validator: (value) => ["date", "datetime", "time"].includes(value),
      },
      fmt: {
        type: String,
        default: null,
      },
      placeholder: {
        type: String,
        default: "",
      },
      width: {
        type: String,
        default: "100%",
      },
    },

    emits: ["update:modelValue"],

    setup(props, { emit }) {
      const errMsg = ref("");
      const validate = () => {
        if (window.ssVm) {
          const result = window.ssVm.validateField(props.name);
          console.log("validate", window.ssVm.validateField(props.name));
          errMsg.value = result.valid ? "" : result.message;
        }
      };
      // 根据type确定默认格式
      const defaultFormat = computed(() => {
        switch (props.type) {
          case "datetime":
            return "YYYY-MM-DD HH:mm:ss";
          case "date":
            return "YYYY-MM-DD";
          case "time":
            return "HH:mm:ss";
        }
      });
      const convertJavaFormatToElement = (javaFormat) => {
        if (!javaFormat) return null;
        return javaFormat
            .replace("yyyy", "YYYY")
            .replace("MM", "MM")
            .replace("dd", "DD")
            .replace("HH", "HH")
            .replace("mm", "mm")
            .replace("ss", "ss");
      };

      const finalFormat = computed(() => {
        if (props.fmt) {
          return convertJavaFormatToElement(props.fmt);
        }
        return defaultFormat.value;
      });

      // 使用 resolveComponent 获取组件
      const ElDatePicker = resolveComponent("ElDatePicker");
      const ElTimePicker = resolveComponent("ElTimePicker");
      const SsFormIcon = resolveComponent("SsFormIcon");
      const ElIcon = resolveComponent("ElIcon");

      const handleValueUpdate = (val) => {
        emit("update:modelValue", val);
        emit("change", val); // 同时触发 change 事件
        setTimeout(() => {
          validate();
        }, 50);
      };
      const dateType = computed(() => {
        const fmt = props.fmt || "";
        if (fmt.includes("HH:mm:ss")) {
          return "datetime";
        } else if (fmt.includes("HH:mm")) {
          return "datetime";
        } else if (fmt.includes("mm:ss")) {
          return "time";
        }
        return "date";
      });

      let useTimePicker = true;
      //"yyyy-MM-dd HH:mm:ss";  "日期字符串格式在java的写法",传到本组件fmt属性也是按这个格式
      if (props.fmt) {
        //有fmt属性，则以fmt属性优先判断类型
        if (/[dMy]/.test(props.fmt)) {
          //如果有传入日期格式，且含年月日
          useTimePicker = false;
        } else {
          useTimePicker = true;
        }
      } else if (props.type !== "time") {
        useTimePicker = false;
      }

      return () =>
          h("div", { class: "ss-date-picker", style: { width: props.width } }, [
            h("input", {
              type: "hidden",
              name: props.name,
              value: props.modelValue,
            }),
            // 选择组件
            h(useTimePicker ? ElTimePicker : ElDatePicker, {
              modelValue: props.modelValue,
              "onUpdate:modelValue": handleValueUpdate,
              type: dateType.value,
              format: finalFormat.value,
              "value-format": finalFormat.value,
              clearable: true,
              placeholder: props.placeholder,
              class: "custom-date-picker", // 用于自定义样式
              "time-arrow-control": props.type === "datetime", // 修改这里
              size: "large", // 添加这一行，改为 large 尺寸
              style: { width: "100%" },
              "prefix-icon": h(SsFormIcon, { class: "form-icon-time" }),
            }),
          ]);
    },
  };
  // ss-icon 图标
  const SsIcon = {
    name: "SsIcon",
    props: {
      name: { type: String, required: true },
      size: { type: [Number, String], default: 16 },
      unit: { type: String, default: "px" },
      color: String,
      type: {
        type: String,
        default: ssIcon.name,
        validator: function (value) {
          return [ssIcon, commonIcon].some((icon) => icon.name === value);
        },
      },
    },
    emits: ["update:modelValue", "input", "blur", "change"],
    setup(props, { emit }) {
      const useIconType = computed(() => {
        return [ssIcon, commonIcon].find(
            (iconConfig) => iconConfig.name === props.type
        );
      });
      const iconName = computed(() => {
        const iconConfig = useIconType.value; // 注意：使用 .value 来访问响应式引用的值
        if (!iconConfig) {
          console.error(`Icon type "${props.type}" not found.`);
          return "";
        }
        const iconType = iconConfig.types[props.name];
        if (!iconType) {
          console.error(
              `Icon name "${props.name}" not found in type "${props.type}".`
          );
          return "";
        }
        return `${iconConfig.prefix}${iconType}`;
      });

      // 类似地，你可以计算 fontFamily 和 style
      const fontFamily = computed(() => {
        return useIconType.value ? useIconType.value.family : "";
      });
      // console.log(iconName.value,fontFamily.value)
      const style = computed(() => {
        const sizeStyle = isNum(props.size)
            ? `${props.size}${props.unit}`
            : props.size;
        const styleObj = {
          fontSize: sizeStyle,
          color: props.color || "",
        };
        return toStyleStr(styleObj);
      });

      // 使用渲染函数定义模板逻辑
      return () =>
          h("i", {
            class: ["icon-container", iconName.value, fontFamily.value],
            style: style.value,
          });
    },
  };
  // 通用icon
  const SsCommonIcon = {
    name: "SsCommonIcon",
    props: {
      class: {
        type: String,
        required: true,
      },
    },
    setup(props) {
      return () =>
          h("i", {
            class: props.class + " common-icon",
          });
    },
  };
  // 登录页icon
  const SsLoginIcon = {
    name: "SsLoginIcon",
    props: {
      class: {
        type: String,
        required: true,
      },
    },
    setup(props) {
      return () =>
          h("div", {
            class: props.class + " login-icon",
          });
    },
  };
  // 弹窗icon
  const SsDialogIcon = {
    name: "SsDialogIcon",
    props: {
      class: {
        type: String,
        required: true,
      },
    },
    setup(props) {
      return () =>
          h("i", {
            class: props.class + " dialog-icon",
          });
    },
  };
  // 全局左侧导航图标组件
  const SsNavIcon = {
    name: "SsNavIcon",
    props: {
      class: {
        type: String,
        required: true,
      },
    },
    setup(props) {
      return () =>
          h("div", {
            class: props.class + " nav-icon",
          });
    },
  };
  // 顶部工具栏图标组件
  const SsHeaderIcon = {
    name: "SsHeaderIcon",
    props: {
      class: {
        type: String,
        required: true,
      },
    },
    setup(props) {
      return () =>
          h("div", {
            class: props.class + " header-icon",
          });
    },
  };
  // 全局菜单图标组件
  const SsGolbalMenuIcon = {
    name: "SsGolbalMenuIcon",
    props: {
      class: {
        type: String,
        required: true,
      },
    },
    setup(props) {
      return () =>
          h("div", {
            class: props.class + " global-menu-icon",
          });
    },
  };
  // 全局查询列表卡片图标
  const SsCartListIcon = {
    name: "SsCartListIcon",
    props: {
      class: {
        type: String,
        required: true,
      },
    },
    setup(props) {
      return () =>
          h("div", {
            class: props.class + " cart-list-icon",
          });
    },
  };
  // 全局底部工具栏图标组件
  const SsQuickIcon = {
    name: "SsQuickIcon",
    props: {
      class: {
        type: String,
        required: true,
      },
    },
    setup(props) {
      return () =>
          h("div", {
            class: props.class + " quick-icon",
          });
    },
  };
  // 表单组件icon
  const SsFormIcon = {
    name: "SsFormIcon",
    props: {
      class: {
        type: String,
        required: true,
      },
    },
    setup(props) {
      return () =>
          h("div", {
            class: props.class + " form-icon",
          });
    },
  };
  // 弹窗底部按钮icon
  const SsBottomDivIcon = {
    name: "SsBottomDivIcon",
    props: {
      class: {
        type: String,
        required: true,
      },
    },
    setup(props) {
      return () =>
          h("div", {
            class: props.class + " bottom-div-icon",
          });
    },
  };
  // editor组件icon
  const SsEditorIcon = {
    name: "SsEditorIcon",
    props: {
      class: {
        type: String,
        required: true,
      },
    },
    setup(props) {
      return () =>
          h("i", {
            class: props.class + " editor-icon",
          });
    },
  };
  // ss-validate校验器
  const SsValidate = {
    name: "SsValidate",
    props: {
      errMsg: { type: String },
      textAlign: { type: String, default: "left" },
      style: { type: Object, default: () => ({}) },
    },
    template: `<div class="validate-vline"></div>
    <div class="validate-tip" :style="style">
      <div class="tip" :style="{ textAlign: textAlign }">{{ errMsg }}</div>
      <div class="tip-more" :style="{ textAlign: textAlign }">{{ errMsg }}</div>
    </div>`,
  };
  // ss-onoffbutton-array 多选按钮 数组形式
  const SsOnoffbuttonArray = {
    name: "SsOnoffbuttonArray",
    props: {
      name: {
        type: String,
        required: true,
      },
      opt: {
        type: Array,
        default: () => [],
      },
      defaultValue: [String, Number, Array],
      modelValue: [String, Number, Array],
      multiple: {
        // 新增多选模式属性
        type: Boolean,
        default: false,
      },
    },
    emits: ["update:modelValue"], // 允许更新 v-model 绑定的值
    setup(props, { emit }) {
      console.log("多选按钮", props.opt);
      // 使用数组来存储选中值
      const checkedValue = ref(
          props.multiple
              ? Array.isArray(props.defaultValue)
                  ? props.defaultValue
                  : []
              : props.defaultValue
      );
      const errMsg = ref(props.errTip);

      // 生成icon名字
      const genIconName = (itemValue) => {
        if (props.multiple) {
          return checkedValue.value.includes(itemValue)
              ? "form-icon-onoffbutton-checked"
              : "form-icon-onoffbutton-unchecked";
        }
        return checkedValue.value === itemValue
            ? "form-icon-onoffbutton-checked"
            : "form-icon-onoffbutton-unchecked";
      };
      // 选中项
      const selectItem = (value) => {
        if (props.multiple) {
          // 多选模式
          const index = checkedValue.value.indexOf(value);
          if (index === -1) {
            checkedValue.value = [...checkedValue.value, value];
          } else {
            checkedValue.value = checkedValue.value.filter((v) => v !== value);
          }
        } else {
          // 单选模式
          checkedValue.value = value;
        }

        emit("update:modelValue", checkedValue.value);
        nextTick(() => {
          // 触发验证
          if (window.ssVm) {
            window.ssVm.validateField(props.name);
          }
        });
      };

      return { checkedValue, genIconName, selectItem };
    },
    // 使用渲染函数定义模板逻辑
    render() {
      const SsFormIcon = resolveComponent("ss-form-icon");
      return h("div", { class: "radio-container" }, [
        // 根据情况创建 input
        this.multiple
            ? this.checkedValue.length
                ? // 多选且有选中值：为选中项创建 input
                this.checkedValue.map((value) =>
                    h("input", {
                      type: "checkbox",
                      name: this.name,
                      value: value,
                      checked: true,
                      style: { display: "none" },
                    })
                )
                : // 多选但没有选中值：创建一个空值 input
                h("input", {
                  type: "hidden",
                  name: this.name,
                  value: "",
                })
            : // 单选模式：创建一个 input
            h("input", {
              type: "hidden",
              name: this.name,
              value: this.checkedValue || "",
            }),

        this.opt.map((item, i) =>
            h(
                "div",
                {
                  key: i,
                  class: {
                    checked: this.multiple
                        ? this.checkedValue.includes(item.value)
                        : this.checkedValue === item.value,
                  },
                  style: { width: item.width },
                  onClick: () => this.selectItem(item.value),
                },
                [
                  h("span", null, item.label),
                  h("div", { class: "mark" }, [
                    h(SsFormIcon, {
                      class: this.genIconName(item.value),
                    }),
                  ]),
                ]
            )
        ),
      ]);
    },
  };

  // ss-onoffbutton 一个按钮
  const SsOnoffbutton = {
    name: "SsOnoffbutton",
    props: {
      name: {
        type: String,
        required: true,
      },
      label: {
        type: String,
        required: true,
      },
      value: {
        type: [String, Number],
        required: true,
      },
      width: {
        type: String,
        default: "",
      },
      modelValue: [String, Number, Array],
      multiple: {
        type: Boolean,
        default: false,
      },
    },
    emits: ["update:modelValue"],

    setup(props, { emit }) {
      const parseModelValue = (val) => {
        if (!val) return [];
        // 如果以逗号开头，去掉开头的逗号
        const cleanValue = val.toString().replace(/^,+/, "");
        if (cleanValue.includes("|")) {
          return cleanValue.split("|");
        }
        if (cleanValue.includes(",")) {
          return cleanValue.split(",");
        }
        return [cleanValue];
      };
      // 判断当前按钮是否选中
      const isChecked = computed(() => {
        if (props.multiple) {
          const currentValue = parseModelValue(props.modelValue);
          return currentValue.includes(props.value.toString());

          // return Array.isArray(props.modelValue) && props.modelValue.includes(props.value);
        }
        return props.modelValue === props.value;
      });

      // 切换选中状态
      const toggleSelect = () => {
        if (props.multiple) {
          const currentValue = parseModelValue(props.modelValue);
          const index = currentValue.indexOf(props.value.toString());
          let newValue;
          if (index === -1) {
            newValue = [...currentValue, props.value];
          } else {
            newValue = currentValue.filter((v) => v !== props.value.toString());
          }
          emit("update:modelValue", newValue.join(","));
        } else {
          emit("update:modelValue", props.value);
        }

        nextTick(() => {
          // 触发验证
          if (window.ssVm) {
            window.ssVm.validateField(props.name);
          }
        });
      };

      return { isChecked, toggleSelect };
    },

    render() {
      const SsFormIcon = resolveComponent("ss-form-icon");
      return h("div", { class: "radio-container2" }, [
        // 隐藏的表单元素
        this.multiple
            ? h("input", {
              type: "hidden",
              name: `${this.name}`, // 多选模式下使用数组形式的 name
              value: this.isChecked ? this.value : "",
            })
            : this.isChecked &&
            h("input", {
              // 只有当前按钮被选中时才创建 input
              type: "hidden",
              name: this.name,
              value: this.value,
            }),

        // 按钮显示
        h(
            "div",
            {
              class: { checked: this.isChecked },
              style: { width: this.width },
              onClick: this.toggleSelect,
            },
            [
              h("span", null, this.label),
              h("div", { class: "mark" }, [
                h(SsFormIcon, {
                  class: this.isChecked
                      ? "form-icon-onoffbutton-checked"
                      : "form-icon-onoffbutton-unchecked",
                }),
              ]),
            ]
        ),
      ]);
    },
  };

  // ss-textarea
  const SsTextarea = {
    name: "SsTextarea",
    props: {
      name: {
        type: String,
        required: true,
      },
      placeholder: {
        type: String,
        default: "请输入",
      },
      defaultValue: [String, Number],
      modelValue: [String, Number],
    },
    emits: ["update:modelValue"],
    setup(props, { emit }) {
      const inputValue = ref(props.modelValue || props.defaultValue || "");

      // 监听 modelValue 变化
      watch(
          () => props.modelValue,
          (newVal) => {
            inputValue.value = newVal;
          }
      );

      // 输入事件处理
      const onInput = (event) => {
        const newValue = event.target.value;
        inputValue.value = newValue;
        emit("update:modelValue", newValue);
        // 触发验证
        if (window.ssVm) {
          window.ssVm.validateField(props.name);
        }
      };

      // 失焦时验证
      const onBlur = () => {
        if (window.ssVm) {
          window.ssVm.validateField(props.name);
        }
      };

      return { inputValue, onInput, onBlur };
    },
    render() {
      return h("div", { class: "textarea-container" }, [
        h("div", { class: "textarea" }, [
          // 添加隐藏的 input 用于验证
          h("input", {
            type: "hidden",
            name: this.name,
            value: this.inputValue || "",
          }),
          h("textarea", {
            placeholder: this.placeholder,
            value: this.inputValue,
            onInput: this.onInput,
            onBlur: this.onBlur,
          }),
        ]),
      ]);
    },
  };
  // ss-editor 富文本编辑器 基于Jodit
  const SsEditor = {
    name: "SsEditor",
    props: {
      modelValue: {
        type: String,
        default: "",
      },
      name: {
        type: String,
        default: "",
      },
      url: {
        type: String,
        default: "",
      },
      height: {
        type: [Number, String],
        default: 400,
      },
      placeholder: {
        type: String,
        default: "请输入内容",
      },
      readonly: {
        type: Boolean,
        default: false,
      },
      uploadUrl: {
        type: String,
        default: "/upload",
      },
      param: {
        type: Object,
        default: () => ({}),
      },
    },

    emits: ["update:modelValue", "ready", "change"],

    setup(props, { emit }) {
      const SsEditorIcon = resolveComponent("SsEditorIcon");
      const editorRef = ref(null);
      let editorContent = '';//保存富文本编辑器里面的富文本内容
      const uniqueId = "editor-" + Date.now();
      const errMsg = Vue.ref("");
      let fjid = ref(props.param.button.val);
      let fjName = props.param.button.desc;
      let mode = props.param.mode;
      const validate = () => {
        if (window.ssVm) {
          const result = window.ssVm.validateField(props.name);
          console.log("validate", window.ssVm.validateField(props.name));
          errMsg.value = result.valid ? "" : result.message;
        }
      };
      onMounted(() => {
        validate();
        const editor = Jodit.make(`#${uniqueId}`, {
          height: props.height,
          placeholder: props.placeholder,
          readonly: props.readonly,
          language: "zh_cn",
          i18n: {
            zh_cn: {
              Link: "链接",
              URL: "链接",
              "No follow": "无跟踪",
              "Class name": "类名",
              Image: "图片",
              File: "文件",
              "Line height": "行高",
              Alternative: "描述",
              "Alternative text": "描述",
              "Lower Alpha": "小写字母",
              "Upper Alpha": "大写字母",
              "Upper Roman": "大写罗马数字",
              "Lower Roman": "小写罗马数字",
              "Lower Greek": "小写希腊字母",
              "Lower Letter": "小写字母",
              "Upper Letter": "大写字母",
            },
          },
          showXPathInStatusbar: false,
          showCharsCounter: false,
          showWordsCounter: false,
          allowResizeY: false,
          toolbarSticky: false,

          statusbar: false,
          uploader: {
            url: props.uploadUrl,
            format: "json",
            method: "POST",
            filesVariableName: function (i) {
              return "imgs[" + i + "]";
            },
            headers: {
              Accept: "application/json",
            },
            prepareData: function (formData) {
              // 这里可以在发送前处理表单数据
              return formData;
            },
            isSuccess: function (resp) {
              console.log("isSuccess resp:", resp);
              return resp.code === 0;
            },
            getMessage: function (resp) {
              console.log("getMessage resp:", resp);
              return resp.msg || "上传失败";
            },
            process: function (resp) {
              console.log("process resp:", resp);
              return resp.data.url;
            },
            error: function (e) {
              console.error("上传失败:", e.message);
            },
            defaultHandlerSuccess: function (resp) {
              console.log("上传成功:", resp);
            },
            defaultHandlerError: function (err) {
              console.error("上传错误:", err);
            },
            contentType: function (requestData) {
              // 可以根据需要修改 Content-Type
              return false; // 让浏览器自动设置
            },
          },

          // 自定义字体列表
          controls: {
            font: {
              list: {
                Arial: "Arial",
                SimSun: "宋体",
                SimHei: "黑体",
                "Microsoft YaHei": "微软雅黑",
                KaiTi: "楷体",
                FangSong: "仿宋",
                "Times New Roman": "Times New Roman",
                "Courier New": "Courier New",
              },
            },
            customLinkButton: {
              name: "link",
              tooltip: "附件",
              exec: function (editor) {
                // 按钮点击时的处理函数
                console.log("附件点击了");
                console.log("param", props.param);
                console.log("cmsAddUrl",props.param.button.cmsAddUrl);

                if (fjid.value == null || fjid.value == "") {
                  $.ajax({
                    type: "post",
                    url: props.param.button.cmsAddUrl,
                    async: false,
                    data: {
                      name: "fjid",
                      ssNrObjName: "sh",
                      ssNrObjId: "",
                    },
                    success: function (_fjid) {
                      console.log("cmsAddUrl success", _fjid);
                      fjid.value = _fjid;
                    },
                  });
                }
                var str =
                    "&nrid=T-" +
                    fjid.value +
                    "&objectId=" +
                    fjid.value +
                    "&objectName=" +
                    fjName +
                    "&callback=" +
                    (window["fjidCallbackName"] || "");
                console.log("str", str);
                SS.openDialog({
                  src: props.param.button.cmsUpdUrl + str,
                  headerTitle: "编辑",
                  width: 900,
                  high: 664,
                  zIndex:51
                });
                // ss.display.showComponent({
                //   show: ["wdDialog"],
                //   url: props.param.button.cmsUpdUrl + str,
                //   title: "编辑",
                //   width: 900,
                //   high: 664,
                // });
              },
            },
          },
          toolbarAdaptive: true,
          buttons: [
            "fullsize",
            "bold",
            "italic",
            "underline",
            "strikethrough",
            "eraser",
            "|",
            "font",
            "fontsize",
            "brush",
            "paragraph",
            "|",
            "left",
            "center",
            "right",
            "justify",
            "|",
            "ul",
            "ol",
            "indent",
            "outdent",
            "|",
            "image",
            "table",
            "customLinkButton",
            "print",
            "|",
            "undo",
            "redo",
            "find",
          ],
          // 中等宽度时显示的按钮
          buttonsMD: [
            "fullsize",
            "bold",
            "italic",
            "underline",
            "strikethrough",
            "eraser",
            "|",
            "font",
            "fontsize",
            "brush",
            "paragraph",
            "|",
            "font",
            "fontsize",
            "|",
            "left",
            "center",
            "right",
            "justify",
            "|",
            "image",
            "customLinkButton",
            "|",
            "dots", // 其余按钮会自动进入 dots 菜单
          ],

          // 小屏幕时显示的按钮
          buttonsSM: ["fullsize", "bold", "italic", "|", "image", "|", "dots"],

          // 超小屏幕时显示的按钮
          buttonsXS: ["fullsize", "bold", "|", "dots"],
          // 设置响应式断点
          sizeLG: 1024, // 大屏幕
          sizeMD: 768, // 中等屏幕
          sizeSM: 576, // 小屏幕
          // 自定义图标
          getIcon: function (name, clearName) {
            // 定义图标映射
            const iconMap = {
              bold: "editor-icon-bold",
              italic: "editor-icon-italic",
              underline: "editor-icon-underline",
              strikethrough: "editor-icon-strikethrough",
              eraser: "editor-icon-eraser",
              copyformat: "editor-icon-copyformat",
              font: "editor-icon-font",
              fontsize: "editor-icon-fontsize",
              brush: "editor-icon-brush",
              paragraph: "editor-icon-paragraph",
              left: "editor-icon-align-left",
              center: "editor-icon-align-center",
              right: "editor-icon-align-right",
              justify: "editor-icon-align-justify",
              ul: "editor-icon-ul",
              ol: "editor-icon-ol",
              indent: "editor-icon-indent",
              outdent: "editor-icon-outdent",
              image: "editor-icon-image",
              file: "editor-icon-file",
              video: "editor-icon-video",
              table: "editor-icon-table",
              link: "editor-icon-link",
              source: "editor-icon-source",
              eye: "editor-icon-preview",
              fullsize: "editor-icon-fullsize",
              shrink: "editor-icon-fullsize-exit", // 添加退出全屏图标

              print: "editor-icon-print",
              undo: "editor-icon-undo",
              redo: "editor-icon-redo",
              search: "editor-icon-find",
              selectall: "editor-icon-selectall",
            };
            // 获取对应的图标类名
            const iconClass = iconMap[clearName] || iconMap[name];

            if (iconClass) {
              // 返回带有我们自定义图标类的 span 元素
              return `<span class="editor-icon ${iconClass}"></span>`;
            }

            return null;
          },
        });



        // 设置初始值
        editor.value = editorContent;
        // editor.value = props.modelValue;

        // 监听变化
        editor.events.on("change", () => {
          // emit("update:modelValue", editor.value);
          editorContent = editor.value;
          // alert('editorContent:'+editorContent);
          let contentElements = document.getElementsByName(props.name.replace(/wj$/, "") + "Edit");
          if(contentElements.length>0){
            contentElements[0].value = editorContent;
          }
          emit("change", editor.value);
          setTimeout(() => {
            validate();
          }, 50);
        });

        // 保存编辑器实例
        editorRef.value = editor;

        emit("ready", editor);

        //回显编辑器富文本文件
        if (props.url ) {
          const params = new URLSearchParams();

        if(mode)
          params.append("mode", mode);

          if(props.modelValue)
            params.append("path", props.modelValue);

          // alert('props.url:'+props.url+',props.modelValue:'+props.modelValue);

          axios
              .post(props.url, params, {
                headers: {
                  "Content-Type": "application/x-www-form-urlencoded", // 必须手动设置！
                },
              })
              .then((response) => {
                // alert(JSON.stringify(response.data));

                if ("timeout" == response.data.statusText) {
                  alert("网络超时!");
                  return;
                }

                let content = response.data.content;
                if (content) {
                  // editor.value = content;
                  editorRef.value.value = content;
                  editorContent = content;
                  // alert('editor.value:'+editor.value)
                }

                let filePath = response.data.path;
                // alert('response.data:'+JSON.stringify(response.data));
                if(filePath){
                  props.modelValue = filePath;
                  emit("update:modelValue", filePath);
                }
              });
        }
      });

      // 监听值变化
      watch(
          // () => props.modelValue,
          () => editorContent,
          (newValue) => {
            if (editorRef.value && newValue !== editorRef.value.value) {
              editorRef.value.value = newValue || "";
            }
          }
      );

      // 监听只读状态变化
      watch(
          () => props.readonly,
          (newValue) => {
            if (editorRef.value) {
              editorRef.value.setReadOnly(newValue);
            }
          }
      );

      // 组件销毁时清理
      onBeforeUnmount(() => {
        if (editorRef.value) {
          editorRef.value.destruct();
        }
      });

      return () =>
          h("div", { class: "ss-editor-container" }, [
            fjid.value &&
            h("input", {
              type: "hidden",
              name: "fjid",
              value: fjid.value,
            }),
            h("input", {
              type: "hidden",
              name: props.name.replace(/wj$/, "") + "Edit",
              value: editorContent
              // value: props.modelValue,
            }),
            h("input", {
              type: "hidden",
              name: props.name.replace(/wj$/, "") + "wj",
              value: props.modelValue
              // value: props.url
            }),
            h("input", { type: "hidden", name: "ueditorpath", value: "mswj" }),
            h("textarea", { id: uniqueId }),
          ]);
    },
  };
  // 弹窗右边图标
  const SsFullStyleHeader = {
    name: "SsFullStyleHeader",
    props: {
      title: {
        type: String,
        default: "标题",
      },
    },
    emits: ["close"],
    setup(props, { emit }) {
      // console.log(props.title)
      const onClose = () => {
        emit("close");
      };
      const SsIcon = resolveComponent("ss-icon");
      return () =>
          h("div", { class: "header-container" }, [
            h("div", { class: "title" }, props.title),
            h("div", { class: "handle-bar" }, [
              h("div", { class: "left-bar" }, [
                h(SsDialogIcon, { class: "dialog-icon-download" }),
                h(SsDialogIcon, { class: "dialog-icon-print" }),
                h(SsDialogIcon, { class: "dialog-icon-setting" }),
                h(SsDialogIcon, { class: "dialog-icon-collect" }),
                h(SsDialogIcon, { class: "dialog-icon-help" }),
                h(SsDialogIcon, { class: "dialog-icon-full-screen" }),
                h(SsDialogIcon, { class: "dialog-icon-lock" }),
              ]),
              h("div", { class: "close-bar", onClick: onClose }, [
                h(SsDialogIcon, { class: "dialog-icon-close" }),
              ]),
            ]),
          ]);
    },
  };
  // ss-dialog弹窗
  const SsDialog = {
    name: "SsDialog",
    props: {
      src: {
        type: String,
      },
      headerTitle: {
        type: String,
        // required: true,
        default: "弹窗",
      },
      width: {
        type: String,
        default: "1400",
      },
      height: {
        type: String,
        default: "600",
      },
      params: {
        type: Object,
        default: () => ({}),
      },
      zIndex: {
        type: Number,
        default: 1000,
      },
    },
    emits: ["close"],
    setup(props, { slots, emit }) {
      // 关闭窗口方法
      const onClose = () => {
        emit("close");
      };
      const showHeader = ref(true);
      const headerVisible = ref(false);
      const popupHieght = ref(props.height);
      // 状态：存储位置信息
      const position = reactive({
        // 页面居中
        x: (window.innerWidth - props.width) / 2,
        y: (window.innerHeight - popupHieght.value) / 2,
        isDragging: false,
        offsetX: 0,
        offsetY: 0,
      });
      // 鼠标按下时设置起始坐标并开始拖拽
      const startDrag = (event) => {
        position.isDragging = true;
        position.offsetX = event.clientX - position.x;
        position.offsetY = event.clientY - position.y;
      };
      // 鼠标移动时更新位置
      const onDrag = (event) => {
        if (position.isDragging) {
          position.x = event.clientX - position.offsetX;
          position.y = event.clientY - position.offsetY;
        }
      };
      // 鼠标放开时结束拖拽
      const endDrag = () => {
        position.isDragging = false;
      };
      // 监听来自 iframe 的消息
      const handleMessage = (event) => {
        //  顶天立地
        if (event.data && typeof event.data.hasScrollBar !== "undefined") {
          if (event.data.hasScrollBar) {
            //   console.log(event);
            position.y = 10;
            showHeader.value = false;
            headerVisible.value = true;
            popupHieght.value = window.innerHeight - 20;
            //   console.log(popupHieght.value);
            document.querySelector(".body").style.height = "100%";
            document.querySelector(".body").style.paddingTop = "30px";
            document.querySelector(".header-container ").style.position =
                "absolute";
            document.querySelector(".header-container ").style.zIndex = "10";
          }
        }
      };
      // 鼠标移入关闭按钮区域时显示头部
      const onMouseEnterCloseButton = () => {
        headerVisible.value = false;
      };
      // 鼠标移出关闭按钮区域时隐藏头部
      const onMouseLeaveCloseButton = () => {
        headerVisible.value = true;
      };
      // 在组件挂载时添加全局事件监听器
      Vue.onMounted(() => {
        // 如果传过来的高度大于窗口高度，则设置为窗口高度减去20 否则保持传过来的高度
        popupHieght.value =
            popupHieght.value > window.innerHeight
                ? window.innerHeight - 20
                : popupHieght.value;
        const container = document.querySelector(".header-container");
        if (container) {
          container.addEventListener("mousedown", startDrag);
        }
        document.addEventListener("mousemove", onDrag);
        document.addEventListener("mouseup", endDrag);
        window.addEventListener("message", handleMessage);
      });

      // 在组件卸载时移除全局事件监听器
      Vue.onUnmounted(() => {
        document.removeEventListener("mousemove", onDrag);
        document.removeEventListener("mouseup", endDrag);
        window.removeEventListener("message", handleMessage);
      });
      const SsMark = resolveComponent("ss-mark");
      const SsFullStyleHeader = resolveComponent("ss-full-style-header");
      // render函数定义组件结构
      return () =>
          h(
              Teleport,
              { to: "body" }, // 使用 Teleport 将弹窗内容挂载到 body
              h(SsMark, { }, [
                h(
                    "div",
                    {
                      class: "popup-container",
                      style: {
                        position: "absolute",
                        left: `${position.x}px`,
                        top: `${position.y}px`,
                        width: props.width + "px",
                        height: popupHieght.value + "px",
                        zIndex: props.zIndex, // 确保弹窗在最上层
                      },
                    },
                    [
                      h(SsFullStyleHeader, {
                        class: "header",
                        title: props.headerTitle,
                        onClose: onClose,
                        onMousedown: startDrag, // 绑定拖动事件
                        onMouseUp: endDrag,
                        ...(!showHeader.value && {
                          onMouseenter: onMouseEnterCloseButton,
                          onMouseleave: onMouseLeaveCloseButton,
                        }),
                        style: {
                          cursor: position.isDragging ? "grabbing" : "grab",
                          visibility: headerVisible.value ? "hidden" : "visible",
                        },
                      }),
                      h(
                          "div",
                          {
                            class: "body",
                            style: {},
                          },
                          [
                            h("iframe", {
                              src: props.src,
                              frameborder: 0,
                              style: { width: "100%", height: "100%" },
                            }),
                          ]
                      ),
                      headerVisible.value &&
                      h("div", {
                        class: "close-button",

                        onMouseenter: onMouseEnterCloseButton,
                        onMouseleave: onMouseLeaveCloseButton,
                        style: {
                          position: "absolute",
                          top: "0",
                          right: "0",
                          // background: 'black',
                          width: "60px",
                          height: "60px",
                          cursor: "pointer",
                        },
                      }),
                    ]
                ),
              ])
          );
    },
  };
  // ss-mark遮罩层
  const SsMark = {
    name: "SsMark",

    setup(props, { slots, emit }) {
      return () =>
          h("div", { class: "dialog-container" }, [
            h("div", { class: "mark-content" }, [
              h("div", { class: "dialog-contianer" }, [
                slots.default ? slots.default() : "",
              ]),
            ]),
          ]);
    },
  };
  // ss-bottom-button 底部按钮
  const SsBottomButton = {
    name: "SsBottomButton",
    props: {
      text: {
        type: String,
        required: true,
      },
      type: {
        type: String,
        default: "button",
      },
      iconClass: {
        type: String,
      },
      class: {
        type: String,
        default: "",
      },
      onclick: {
        type: [Function, String],
        default: null,
      },
    },
    setup(props, { emit }) {
      const SsBottomDivIcon = Vue.resolveComponent("ss-bottom-div-icon");
      return () =>
          h(
              "button",
              {
                class: props.class,
                onClick: (e) => {
                  e.stopPropagation();
                  if (props.onclick) {
                    // 如果是函数直接调用
                    if (typeof props.onclick === "function") {
                      props.onclick(e);
                    } else if (typeof props.onclick === "string") {
                      // 如果是字符串，使用直接的方法执行
                      // 临时存储按钮元素到全局变量
                      window.__ss_current_button = e.currentTarget;

                      // 直接执行代码，使用eval以保留原始上下文
                      try {
                        eval(props.onclick);
                      } finally {
                        // 清理全局变量
                        delete window.__ss_current_button;
                      }
                    }
                  }
                },
                type: props.type,
              },
              [
                h("span", null, [
                  h(SsBottomDivIcon, {
                    class: props.iconClass,
                  }),
                ]),
                h("span", null, props.text),
              ]
          );
    },
  };
  // ss-search搜索框
  const SsSearch = {
    name: "SsSearch",
    props: {
      theme: {
        type: String,
        default: "light",
        validator: function (value) {
          return ["dark", "light"].includes(value);
        },
      },
      placeholder: {
        type: String,
        default: "请输入搜索条件",
      },
    },
    setup(props, { emit }) {
      const onClick = () => {
        console.log("Search clicked");
        emit("click");
      };
      const SsIcon = Vue.resolveComponent("ss-icon");
      return () =>
          Vue.h(
              "div",
              {
                class: ["search-container", props.theme],
                onClick: onClick,
              },
              [
                Vue.h("input", {
                  placeholder: props.placeholder,
                  disabled: true,
                }),
                Vue.h(SsIcon, {
                  name: "search-result",
                  size: "20px",
                }),
              ]
          );
    },
  };
  // ss-cart-item 菜单页面的卡片 左右结构
  const SsCartItem = {
    name: "SsCartItem",
    props: {
      active: Boolean,
      item: {
        type: Object,
        default: () => ({
          thumb: "images/example/project-img.png",
          title: "广州（国际）科技成果转化天河基地专",
          description: "佳能中国广州分公司",
          all: 50,
          finish: 5,
        }),
      },
    },
    setup(props, { emit }) {
      const item = props.item;

      const itemWidth = Vue.computed(() => {
        const containerWidth =
            document.body.clientWidth || document.body.scrollWidth - 520;
        const halfWidth = containerWidth / 2;
        if (halfWidth < 480) {
          return Math.min(containerWidth, 702) + "px";
        } else {
          return Math.min(halfWidth, 702) + "px";
        }
      });

      const onItemClick = (e) => {
        emit("click", e);
      };

      return {
        item,
        itemWidth,
        onItemClick,
      };
    },
    render() {
      const SsIcon = Vue.resolveComponent("ss-icon");
      return Vue.h(
          "div",
          {
            class: { "item-container": true, active: this.active },
            onClick: this.onItemClick,
            style: { width: this.itemWidth },
          },
          [
            Vue.h("div", { class: "header" }, [
              Vue.h(SsIcon, { name: "setting", size: "20px" }),
            ]),
            Vue.h("div", { class: "body" }, [
              Vue.h("div", { class: "left" }, [
                Vue.h("img", {
                  src: this.item.thumb,
                  alt: "Thumbnail",
                  class: "imgUnHandle",
                  style: { "object-fit": "cover", width: "100%", height: "100%" },
                }),
              ]),
              Vue.h("div", { class: "right" }, [
                Vue.h("div", { class: "title" }, this.item.title),
                Vue.h("div", { class: "desc" }, this.item.description),
                Vue.h("div", { class: "progress" }, [
                  Vue.h(
                      "div",
                      {
                        style: {
                          width: `${(this.item.finish / this.item.all) * 100}%`,
                        },
                      },
                      [Vue.h("div", `${this.item.finish}/${this.item.all}`)]
                  ),
                ]),
              ]),
            ]),
          ]
      );
    },
  };
  // ss-cart-item2 菜单页面的卡片 上下结构
  const SsCartItem2 = {
    name: "SsCartItem2",
    props: {
      active: Boolean,
      item: {
        type: Object,
        default: () => ({
          thumb: "images/example/project-img.png",
          title: "广州（国际）科技成果转化天河基地专",
          description: "佳能中国广州分公司",
          all: 50,
          finish: 5,
        }),
      },
    },
    setup(props, { emit }) {
      const item = props.item;
      const itemWidth = Vue.computed(() => {
        const containerWidth =
            document.body.clientWidth || document.body.scrollWidth - 520;
        const halfWidth = containerWidth / 2;
        if (halfWidth < 480) {
          return Math.min(containerWidth, 702) + "px";
        } else {
          return Math.min(halfWidth, 702) + "px";
        }
      });

      const onItemClick = (e) => {
        emit("click", e);
      };

      return {
        item,
        itemWidth,
        onItemClick,
      };
    },

    render() {
      const SsIcon = Vue.resolveComponent("ss-icon");
      return Vue.h(
          "div",
          {
            class: { "item-container2": true, active: this.active },
            onClick: this.onItemClick,
            style: { width: this.itemWidth },
          },
          [
            Vue.h("div", { class: "action-bar" }, [
              Vue.h(SsIcon, { name: "setting", size: "20px" }),
            ]),
            Vue.h("div", { class: "header" }, [
              Vue.h("div", { class: "title" }, `${this.item.title}`),
            ]),
            Vue.h("div", { class: "body" }, [
              Vue.h("div", { class: "left" }, [
                Vue.h("img", {
                  src: this.item.thumb,
                  alt: "Thumbnail",
                  class: "imgUnHandle",
                  style: { "object-fit": "cover", width: "100%", height: "100%" },
                }),
              ]),
              Vue.h("div", { class: "right" }, [
                Vue.h("div", { class: "content" }, this.item.description),
                Vue.h("div", { class: "tip" }, [
                  Vue.h("div", { class: "progress" }, [
                    Vue.h(
                        "div",
                        {
                          style: {
                            width: `${(this.item.finish / this.item.all) * 100}%`,
                          },
                        },
                        [Vue.h("div", `${this.item.finish}/${this.item.all}`)]
                    ),
                  ]),
                ]),
              ]),
            ]),
          ]
      );
    },
  };
  // ss-list-card 通用列表卡片
  const SsListCard = {
    name: "SsListCard",
    props: {
      item: {
        type: Object,
        required: true,
      },
    },
    emits: ["click", "change"],
    setup(props, { emit }) {
      const item = props.item;
      const itemWidth = Vue.computed(() => {
        const containerWidth =
            document.body.clientWidth || document.body.scrollWidth;
        if (containerWidth > 1200) {
          return "30%";
        }
        return "45%";
      });
      const onItemClick = (e) => {
        // 清除所有类型卡片的 active 状态
        const allListCards = document.querySelectorAll(
            ".knowledge-item-container"
        );
        const allFolderCards = document.querySelectorAll(".ss-folder-list");

        allListCards.forEach((card) => card.classList.remove("active"));
        allFolderCards.forEach((card) => card.classList.remove("active"));

        // 设置当前项的 active 状态
        e.currentTarget.classList.add("active");
        props.item.onclick();
      };
      const onItemChange = (e, icon, index) => {
        e.stopPropagation(); // 阻止事件冒泡到卡片
        props.item.buttons[0].onclick();
        // emit("change", { item: props.item, icon, index });
      };
      return {
        item,
        itemWidth,
        onItemClick,
        onItemChange,
      };
    },

    data() {
      return {
        showButtons: false,
      };
    },

    render() {
      const SsCartListIcon = Vue.resolveComponent("ss-cart-list-icon");
      return Vue.h(
          "div",
          {
            class: { "knowledge-item-container": true, active: this.item.active },
            onClick: this.onItemClick,
            style: { width: this.itemWidth },
          },
          [
            this.item?.buttons?.length > 0 &&
            Vue.h(
                "div",
                {
                  class: "header",
                  onMouseenter: () => (this.showButtons = true),
                  onMouseleave: () => (this.showButtons = false),
                  onClick: (e) => this.onItemChange(e, this.item.buttons[0], 0),
                },
                [
                  // 只在有按钮时渲染设置图标
                  // this.item?.buttons?.length > 0 &&
                  Vue.h("div", {
                    class: "cart-list-setting cart-list-icon",
                    title: this.item?.buttons?.[0]?.title,
                  }),

                  // 鼠标移入时显示按钮列表，与图标同级
                  // this.item?.buttons?.length > 0 &&
                  this.showButtons &&
                  this.item?.buttons?.length > 1 &&
                  Vue.h(
                      "div",
                      {
                        class: "cart-list-button-popup",
                      },
                      this.item.buttons.map((btn) =>
                          Vue.h(
                              "div",
                              {
                                onClick: (e) => {
                                  e.stopPropagation();
                                  btn.onclick?.();
                                },
                              },
                              [
                                // 如果有 class，显示对应的图标
                                btn.class &&
                                Vue.h(SsCartListIcon, {
                                  class: [btn.class],
                                }),
                                // 显示按钮文本
                                Vue.h("span", null, btn.title),
                              ]
                          )
                      )
                  ),
                ]
            ),

            Vue.h("div", { class: "body" }, [
              Vue.h("div", { class: "box-header" }, [
                Vue.h("div", `${this.item.title}`),
              ]),
              Vue.h(
                  "div",
                  {
                    class: !this.item.thumb ? "no-thumb box-body" : "box-body",
                  },
                  [
                    this.item.thumb
                        ? Vue.h("div", { class: "left" }, [
                          Vue.h("img", {
                            src: this.item.thumb,
                            alt: "Thumbnail",
                            class: "imgUnHandle",
                            style: {
                              "object-fit": "cover",
                              width: "100%",
                              height: "100%",
                            },
                          }),
                        ])
                        : null,
                    Vue.h("div", { class: "right" }, [
                      ...this.item.tags.map((tag) => {
                        const [key, value] = Object.entries(tag)[0];
                        return Vue.h(
                            "div",
                            {
                              class: "title",
                              title: `${key}: ${value}`,
                            },
                            `${key}: ${value}`
                        );
                      }),
                    ]),
                  ]
              ),
            ]),
          ]
      );
    },
  };
  // ss-folder-card 文件夹卡片
  const SsFolderCard = {
    name: "SsFolderCard",
    props: {
      item: {
        type: Object,
        required: true,
      },
    },
    data() {
      return {
        showButtons: false,
      };
    },
    emits: ["click", "change"],
    setup(props, { emit }) {
      const item = props.item;
      const showChildren = ref(false);
      const eventBus = window.parent.sharedEventBus;

      const itemWidth = Vue.computed(() => {
        const containerWidth =
            document.body.clientWidth || document.body.scrollWidth;
        return containerWidth > 1200 ? "45%" : "90%";
      });
      onMounted(() => {
        eventBus.subscribe("folderPath", (path) => {
          const currentPath = path || [];
          // 如果当前文件夹不在路径中，则销毁视图
          if (
              !currentPath.some((item) => item.folder.title === props.item.title)
          ) {
            showChildren.value = false;
          }
        });
      });
      const onItemClick = (e) => {
        if (e && e.stopPropagation) {
          e.stopPropagation();
        }
        // 单击只处理 active 状态
        if (e && e.currentTarget) {
          const allListCards = document.querySelectorAll(
              ".knowledge-item-container"
          );
          const allFolderCards = document.querySelectorAll(".ss-folder-list");

          allListCards.forEach((card) => card.classList.remove("active"));
          allFolderCards.forEach((card) => card.classList.remove("active"));

          e.currentTarget.classList.add("active");
        } else {
          // 如果是数据对象，需要找到对应的 DOM 元素
          const allListCards = document.querySelectorAll(
              ".knowledge-item-container"
          );
          const allFolderCards = document.querySelectorAll(".ss-folder-list");
          allListCards.forEach((card) => card.classList.remove("active"));
          allFolderCards.forEach((card) => card.classList.remove("active"));
          // 找到标题匹配的文件夹元素
          const targetFolder = Array.from(allFolderCards).find((card) =>
              card.textContent.includes(e.title)
          );

          if (targetFolder) {
            targetFolder.classList.add("active");
          }
        }
        emit("click", item);
      };
      // 修改双击处理函数
      const handleFolderDblClick = (folder, e) => {
        if (e) e.stopPropagation();
        if (folder.children?.length) {
          showChildren.value = true;
          const pathInfo = {
            title: folder.title,
            folder: folder,
          };
          const currentPath = eventBus.getState("folderPath") || [];
          if (!currentPath.some((item) => item.title === folder.title)) {
            eventBus.publish("folderPath", [...currentPath, pathInfo]);
          }
        }
      };
      const onItemChange = (e, icon, index) => {
        e.stopPropagation();
        props.item.buttons[0].onclick();
        // emit("change", { item: props.item, icon, index });
      };
      return {
        item,
        itemWidth,
        showChildren,
        onItemClick,
        onItemChange,
        handleFolderDblClick,
      };
    },
    render() {
      const SsCartListIcon = Vue.resolveComponent("ss-cart-list-icon");
      if (this.showChildren) {
        return h(SsFolderCartView, {
          folder: this.item,
        });
      }
      return Vue.h(
          "div",
          {
            class: { "ss-folder-list": true, active: this.item.active },
            onClick: (e) => {
              e.stopPropagation();
              this.onItemClick(e);
            },
            onDblclick: (e) => this.handleFolderDblClick(this.item, e),
            style: { width: this.itemWidth },
          },
          [
            // 文件夹特有的装饰元素
            Vue.h("div", { class: "ss-folder-list-trapezoid" }),
            Vue.h("div", { class: "ss-folder-list-top-transparent" }),
            Vue.h("div", { class: "ss-folder-list-top" }),
            Vue.h("div", { class: "ss-folder-list-right" }),

            // header 部分（按钮）
            this.item?.buttons?.length > 0 &&
            Vue.h(
                "div",
                {
                  class: "header",
                  onMouseenter: () => (this.showButtons = true),
                  onMouseleave: () => (this.showButtons = false),
                  onClick: (e) => this.onItemChange(e, this.item.buttons[0], 0),
                },
                [
                  // this.item?.buttons?.length > 0 &&
                  Vue.h("div", {
                    class: "cart-list-setting cart-list-icon",
                    title: this.item?.buttons?.[0]?.title,
                  }),

                  // this.item?.buttons?.length > 0 &&
                  this.showButtons &&
                  this.item?.buttons?.length > 1 &&
                  Vue.h(
                      "div",
                      {
                        class: "cart-list-button-popup",
                      },
                      this.item.buttons.map((btn) =>
                          Vue.h(
                              "div",
                              {
                                onClick: (e) => {
                                  e.stopPropagation();
                                  btn.onclick?.();
                                },
                              },
                              [
                                btn.class &&
                                Vue.h(SsCartListIcon, {
                                  class: [btn.class],
                                }),
                                Vue.h("span", null, btn.title),
                              ]
                          )
                      )
                  ),
                ]
            ),
            // body 部分
            Vue.h("div", { class: "body" }, [
              Vue.h("div", { class: "box-header" }, [
                Vue.h("div", null, this.item.title),
              ]),
              Vue.h(
                  "div",
                  {
                    class: !this.item.thumb ? "no-thumb box-body" : "box-body",
                  },
                  [
                    this.item.thumb
                        ? Vue.h("div", { class: "left" }, [
                          Vue.h("img", {
                            src: this.item.thumb,
                            alt: "Thumbnail",
                            class: "imgUnHandle",
                            style: {
                              "object-fit": "cover",
                              width: "100%",
                              height: "100%",
                            },
                          }),
                        ])
                        : null,
                    Vue.h("div", { class: "right" }, [
                      ...this.item.tags.map((tag) => {
                        const [key, value] = Object.entries(tag)[0];
                        return Vue.h(
                            "div",
                            {
                              class: "title",
                              title: `${key}: ${value}`,
                            },
                            `${key}: ${value}`
                        );
                      }),
                    ]),
                  ]
              ),
            ]),
          ]
      );
    },
  };
  // SsFolderCartView 组件 - 用于显示文件夹内容
  const SsFolderCartView = {
    name: "SsFolderCartView",
    props: {
      folder: {
        type: Object,
        required: true,
      },
    },
    emits: ["click"],
    setup(props, { emit }) {
      const eventBus = window.parent.sharedEventBus;
      const currentFolder = ref(props.folder);
      const showChildren = ref(false);

      const onItemClick = (e) => {
        if (e && e.stopPropagation) {
          e.stopPropagation();
        }
        // 单击只处理 active 状态
        if (e && e.currentTarget) {
          const allListCards = document.querySelectorAll(
              ".knowledge-item-container"
          );
          const allFolderCards = document.querySelectorAll(".ss-folder-list");

          allListCards.forEach((card) => card.classList.remove("active"));
          allFolderCards.forEach((card) => card.classList.remove("active"));

          e.currentTarget.classList.add("active");
        } else {
          // 如果是数据对象，需要找到对应的 DOM 元素
          const allListCards = document.querySelectorAll(
              ".knowledge-item-container"
          );
          const allFolderCards = document.querySelectorAll(".ss-folder-list");

          allListCards.forEach((card) => card.classList.remove("active"));
          allFolderCards.forEach((card) => card.classList.remove("active"));

          // 找到标题匹配的文件夹元素
          const targetFolder = Array.from(allFolderCards).find((card) =>
              card.textContent.includes(e.title)
          );

          if (targetFolder) {
            targetFolder.classList.add("active");
          }
        }
        emit("click", props.folder);
      };
      const handleFolderDblClick = (folder, e) => {
        if (e) e.stopPropagation();
        if (folder.children?.length) {
          showChildren.value = true;
          const pathInfo = {
            title: folder.title,
            folder: folder,
          };
          const currentPath = eventBus.getState("folderPath") || [];
          if (!currentPath.some((item) => item.title === folder.title)) {
            eventBus.publish("folderPath", [...currentPath, pathInfo]);
            currentFolder.value = folder;
          }
        }
      };

      const goBack = (targetFolder) => {
        if (targetFolder === null) {
          // 返回根目录
          eventBus.publish("folderPath", []);
        } else {
          currentFolder.value = targetFolder;
        }
      };

      return {
        currentFolder,
        showChildren,
        onItemClick,
        handleFolderDblClick,
        goBack,
      };
    },

    render() {
      return h(
          "div",
          {
            class: "page-container",
            style: {
              position: "fixed",
              top: 0,
              left: 0,
              width: "100%",
              height: "100%",
              background: "var(--lightgray)",
              padding: "20px 0",
              zIndex: 1000,
            },
          },
          [
            // 搜索栏
            h("div", { class: "search-bar" }, [
              h("div", { class: "search-bar-contaienr" }, [
                h(SsBreadcrumb, {
                  level: {
                    onBack: this.goBack,
                  },
                }),
              ]),
            ]),

            // 内容区域
            h(
                "div",
                {
                  class: "content-area item-content-area",
                  style: { gap: "20px" },
                },
                [
                  ...(this.currentFolder.children || []).map((child, index) =>
                      h(child.children ? SsFolderCard : SsListCard, {
                        key: index,
                        item: child,
                        onClick: (e) => this.onItemClick(e),
                        onDblclick: (e) => this.handleFolderDblClick(child, e),
                      })
                  ),
                ]
            ),
          ]
      );
    },
  };

  // ss-page分页
  const SsPage = {
    name: "SsPage",
    props: {
      total: {
        type: Number,
        required: true,
      },

      size: {
        type: Number,
        default: 10,
      },
      page: {
        type: Number,
        default: 1,
      },
      onChange: {
        type: Function,
        default: () => {},
      },
    },
    setup(props) {
      const totalItems = ref(props.total); // 总条目数
      const totalPages = ref(Math.ceil(props.total / props.size));
      const currentPage = ref(props.page); // 当前页码

      // 计算显示的信息
      const pageInfo = ref(
          `共${totalItems.value}条，第 ${currentPage.value}/${totalPages.value} 页`
      );

      // 上一页的逻辑
      const goToPreviousPage = (e) => {
        e.preventDefault(); // 阻止默认行为
        if (currentPage.value > 1) {
          currentPage.value -= 1;
          updatePageInfo();
          props.onChange?.({
            pageNo: currentPage.value, // 当前页码
            rowNumPer: props.size, // 每页条数
            rowNum: props.total, // 总记录数
          });
        }
      };

      // 下一页的逻辑
      const goToNextPage = (e) => {
        e.preventDefault(); // 阻止默认行为
        if (currentPage.value < totalPages.value) {
          currentPage.value += 1;
          updatePageInfo();
          props.onChange?.({
            pageNo: currentPage.value, // 当前页码
            rowNumPer: props.size, // 每页条数
            rowNum: props.total, // 总记录数
          });
        }
      };

      // 更新页码信息的函数
      const updatePageInfo = () => {
        pageInfo.value = `共${totalItems.value}条，第 ${currentPage.value}/${totalPages.value} 页`;
      };

      return {
        pageInfo,
        totalPages,
        goToPreviousPage,
        goToNextPage,
      };
    },

    render(props, { slots, emit }) {
      return Vue.h("div", { class: "pager-container" }, [
        Vue.h("input", { type: "hidden", name: "rowNum", value: props.total }),
        Vue.h("input", {
          type: "hidden",
          name: "rowNumPer",
          value: props.size,
        }),
        Vue.h("input", {
          type: "hidden",
          name: "pageCount",
          value: this.totalPages,
        }),
        Vue.h("input", { type: "hidden", name: "pageNo", value: props.page }),
        Vue.h("div", { class: "pager-content" }, [
          Vue.h("div", { class: "info" }, this.pageInfo),
          Vue.h(
              "div",
              { class: "btn" },
              Vue.h(
                  "button",
                  { onClick: (e) => this.goToPreviousPage(e) },
                  "上一页"
              )
          ),
          Vue.h(
              "div",
              { class: "btn" },
              Vue.h("button", { onClick: (e) => this.goToNextPage(e) }, "下一页")
          ),
        ]),
      ]);
    },
  };
  // ss-right-info 一级页面右边栏
  const SSRightInfo = {
    name: "SSRightInfo",
    setup() {
      // 初始化响应式数据
      const item = ref({
        thumb: "images/example/project-img.png", // 更换为适合你项目的实际路径
        title: "工业和信息化产业高质量发展资金",
      });

      return {
        item,
      };
    },
    render() {
      return Vue.h("div", { class: "info-container" }, [
        Vue.h("div", { class: "header" }, [
          Vue.h("div", [
            Vue.h("img", {
              src: this.item.thumb,
              class: "imgUnHandle",
              style: { "object-fit": "cover", width: "100%", height: "100%" },
            }), // 将 ImageViewer 替换为 img 标签
          ]),
          Vue.h("div", [Vue.h("div", this.item.title)]),
        ]),
        Vue.h("div", { class: "section-container" }, [
          Vue.h("div", { class: "section" }, [
            Vue.h("div", { class: "title" }, "合同"),
            Vue.h("div", { class: "text" }, "合同总金额：42,399,320"),
            Vue.h(
                "div",
                { class: "a" },
                "《工业和信息化产业高质量发展资金补助合同》"
            ),
          ]),
          Vue.h("div", { class: "section" }, [
            Vue.h("div", { class: "title" }, "发票"),
            Vue.h("div", { class: "text" }, "应开发票总额：42,399,320"),
            Vue.h("div", { class: "text" }, "已开发票金额：17,235,345"),
            Vue.h("div", { class: "text" }, "未开发票金额：25,163,975"),
          ]),
          Vue.h("div", { class: "section" }, [
            Vue.h("div", { class: "title" }, "项目组成员"),
            Vue.h("div", { class: "text" }, "我司：3人"),
            Vue.h("div", { class: "text" }, "对方：2人"),
            Vue.h("div", { class: "text" }, "项目负责人：张三"),
          ]),
          Vue.h("div", { class: "section" }, [
            Vue.h("div", { class: "title" }, "采购"),
            Vue.h("div", { class: "text" }, "总额：999,320"),
            Vue.h("div", { class: "text" }, "已付金额：335,345"),
            Vue.h("div", { class: "text" }, "未付金额：663,975"),
          ]),
        ]),
      ]);
    },
  };
  //
  const SsSuccessPopup = {
    name: "SsSuccessPopup",
    props: {
      right: {
        type: String,
        default: "20px",
      },
      bottom: {
        type: String,
        default: "calc(100% + 5px)",
      },
    },
    setup(props, { expose }) {
      // 响应式状态：是否可见
      const visible = ref(false);

      // 计算样式
      const style = computed(() => {
        return {
          "--message-dialog-right": props.right,
          "--message-dialog-bottom": props.bottom,
        };
      });

      // 显示对话框的方法
      const show = () => {
        visible.value = true;
      };

      // 隐藏对话框的方法
      const hide = () => {
        visible.value = false;
      };

      // 将方法暴露给外部使用
      expose({ show, hide });

      // 返回渲染函数
      return () => {
        if (!visible.value) return null;
        const SsIcon = resolveComponent("ss-icon");
        return h(
            "div",
            {
              class: "success-popup",
              style: style.value,
              onClick: (e) => e.stopPropagation(),
            },
            [
              h("div", { class: "left" }, [
                h("div", { class: "icon" }, [
                  h(SsIcon, { name: "check", size: "36px" }),
                ]),
              ]),
              h("div", { class: "right" }, [
                h("div", { class: "title" }, "提交成功"),
                h("div", { class: "desc" }, "您的信息已成功提交。"),
              ]),
            ]
        );
      };
    },
  };
  const SsErrorDialog = {
    name: "SsErrorDialog",
    setup(props, { emit }) {
      const visible = ref(false);

      const style = computed(() => {
        return {};
      });

      const show = () => {
        visible.value = true;
      };

      const hide = () => {
        visible.value = false;
      };

      const onBack = () => {
        emit("back");
        hide();
      };

      return {
        visible,
        style,
        show,
        hide,
        onBack,
      };
    },
    render() {
      const SsIcon = resolveComponent("ss-icon");
      return this.visible
          ? h(
              "div",
              {
                class: "errorDialog",
                style: this.style,
                onClick: (event) => event.stopPropagation(),
              },
              [
                h("div", { class: "body" }, [
                  h("div", { class: "left" }, [
                    h("div", { class: "icon" }, [
                      h(SsIcon, { name: "close", size: "36px" }),
                    ]),
                  ]),
                  h("div", { class: "right" }, [
                    h("div", { class: "title" }, "操作失败"),
                    h("div", { class: "desc" }, "请点击返回以继续。"),
                  ]),
                ]),
                h("div", { class: "footer" }, [
                  h("div", { class: "left" }),
                  h("div", { class: "right" }, [
                    h(
                        "div",
                        {
                          class: "btn",
                          onClick: this.onBack,
                        },
                        [h(SsIcon, { name: "arrow-left-line" }), h("div", "返回")]
                    ),
                  ]),
                ]),
              ]
          )
          : null;
    },
  };
  /**
   * 审核链条
   * @name ss-verify
   * @param { Array } verify-list 审核节点列表
   * @property { Array } verify-list 审核节点列表
   * @example <ss-verify :verify-list="verifyList"></ss-verify>
   * verify-list [
   *    {
   *        groupName: "",  // 群组名称
   *        open: true, // 默认是否展开
   *        children:[ //群组里的人员
   *           {
   *            thumb: "images/example/user-4.png", // 头像
   *             name: "李丽思 ", // 姓名
   *             role: "人事处处长",  // 角色
   *             description: "同意。",  // 审核意见
   *             time: "09:38 08/11", // 审核时间
   *             video: false,  // false不显示/true显示 视频icon
   *             link: false,  // false不显示/true显示 链接icon 后续应该是附件
   *           }
   *        ]
   *    }
   *  ]
   */
  const SsVerify = {
    name: "SsVerify",
    props: {
      verifyList: {
        type: Array,
        required: true,
      },
    },
    setup(props) {
      const toggleOpen = (item) => {
        item.open = !item.open;
      };
      onMounted(() => {
        setTimeout(() => {
          const lastOpenGroup = document.querySelector(".group-item-last-open");
          console.log("lastOpenGroup", lastOpenGroup);
          if (lastOpenGroup) {
            const nodes = $(lastOpenGroup).find(".verify-node-container");
            if (nodes.length) {
              let totalHeight = 0;
              const gudingHeight = 100;

              if (nodes.length === 1) {
                totalHeight = gudingHeight;
              } else {
                // 累加除最后一个节点外的所有节点高度
                for (let i = 0; i < nodes.length - 1; i++) {
                  totalHeight += $(nodes[i]).outerHeight();
                }
                totalHeight += gudingHeight;
              }

              console.log("节点信息:", {
                节点总数: nodes.length,
                计算后的高度: totalHeight,
              });

              lastOpenGroup.style.setProperty(
                  "--group-line-height",
                  `${totalHeight}px`
              );
            }
          }
        }, 0);
      });
      return {
        toggleOpen,
      };
    },
    render() {
      const SsIcon = resolveComponent("ss-icon");
      const SsCommonIcon = resolveComponent("ss-common-icon");
      const SsVerifyNode = resolveComponent("ss-verify-node");
      return h(
          "div",
          { class: "verify-nodes" },
          this.verifyList.map((item, i) =>
              h(
                  "div",
                  {
                    key: i,
                    class: {
                      "group-item": true,
                      "group-item-last-open":
                          i === this.verifyList.length - 1 && item.open,
                    },
                  },
                  [
                    h(
                        "div",
                        {
                          class: "group-item-title",
                          onClick: () => this.toggleOpen(item),
                        },
                        [
                          h("div", { class: "icon" }, [
                            item.open
                                ? h(SsCommonIcon, { class: "common-icon-folder-open" })
                                : h(SsCommonIcon, { class: "common-icon-folder-close" }),
                            h(
                                "div",
                                {
                                  class: "num",
                                  style: { top: item.open ? "60%" : "55%" },
                                },
                                item.children?.length || 0
                            ),
                          ]),
                          h("div", { class: "name" }, item.groupName),
                        ]
                    ),
                    item.open && item.children?.length > 0
                        ? h(
                            "div",
                            { class: "group-item-children" },
                            item.children.map((citem, j) =>
                                h(SsVerifyNode, {
                                  key: j,
                                  item: citem,
                                  // isGroup: i + 1 !== this.verifyList.length,
                                  isGroup: true,
                                })
                            )
                        )
                        : null,
                  ]
              )
          )
      );
    },
  };

  /**
   * 审核页面的审核节点
   * @name ss-verify-node
   * @param {Object} item 审核节点信息
   * @param {Boolean} isGroup 是否为分组节点
   */
  const SsVerifyNode = {
    name: "SsVerifyNode",
    props: {
      item: {
        type: Object,
        required: true,
      },
      isGroup: {
        type: Boolean,
        default: false,
      },
    },
    render() {
      const SsIcon = resolveComponent("ss-icon");
      const SsCommonIcon = resolveComponent("ss-common-icon");
      return Vue.h("div", { class: "verify-node-container" }, [
        Vue.h("div", { class: "info" }, [
          Vue.h("div", { class: "avatar" }, [
            Vue.h("img", {
              src: this.item.thumb,
              style: {
                width: "50px",
                height: "50px",
                borderRadius: "50%",
              },
            }),
          ]),
          Vue.h("div", { class: "desc" }, [
            Vue.h("div", this.item.name),
            Vue.h("div", this.item.role),
          ]),
          Vue.h("div", { class: "link" }, [
            Vue.h("div", [
              this.item.video
                  ? Vue.h(SsCommonIcon, { class: "common-icon-video" })
                  : null,
              this.item.link
                  ? Vue.h(SsCommonIcon, {
                    class: "common-icon-paper-clip",
                  })
                  : null,
            ]),
          ]),
        ]),
        Vue.h(
            "div",
            {
              class: {
                description: true,
                link: this.isGroup,
              },
              attrs: { "data-num": "3" },
            },
            [Vue.h("div", this.item.description)]
        ),
        Vue.h("div", { class: "time" }, this.item.time),
      ]);
    },
  };
  /**
   * 智能识别图片的左侧图片播放 可以放大缩小旋转图片
   * @name ss-orc-img-box
   * @param { Object } image-obj 包含图片的url, 和图片的名称
   *
   */
  const SsOrcImgBox = {
    name: "SsOrcImgBox",
    props: {
      imageObj: {
        type: Object,
        required: true,
      },
    },
    setup(props) {
      const zoom = ref(1);
      const rotation = ref(0);
      const containerWidth = ref(0);
      const containerHeight = ref(0);
      const container = ref(null);
      const imgPosition = ref({ x: 0, y: 0 });
      const isDragging = ref(false);
      const lastMousePosition = ref({ x: 0, y: 0 });
      const imgStyle = computed(() => ({
        width: `${zoom.value * 100}%`,
        height: `${zoom.value * 100}%`,
        transform: `rotate(${rotation.value}deg) translate(${imgPosition.value.x}px, ${imgPosition.value.y}px)`,
        transformOrigin: "center center",
        cursor: isDragging.value ? "grabbing" : "grab",
      }));

      const resetZoom = () => {
        zoom.value = 1;
        rotation.value = rotation.value + 90;
        imgPosition.value = { x: 0, y: 0 };
      };

      const handleRangeChange = (event) => {
        const value = event.target.value / 50; // 0 到 100 映射到 0 到 2 的缩放
        zoom.value = Math.max(value, 0.1); // 设置最小缩放值为 0.1
      };
      const updateImgBoxDimensions = () => {
        if (container.value) {
          containerWidth.value = container.value.clientWidth;
          containerHeight.value = container.value.clientHeight;
        }
      };
      const onMouseDown = (event) => {
        isDragging.value = true;
        lastMousePosition.value = { x: event.clientX, y: event.clientY };
      };

      const onMouseMove = (event) => {
        if (isDragging.value) {
          const dx = event.clientX - lastMousePosition.value.x;
          const dy = event.clientY - lastMousePosition.value.y;

          // 防止旋转后拖动的x,y反转
          // 首先将当前旋转角度从度数转换为弧度，因为 JavaScript 的 Math 库使用弧度
          const angle = rotation.value * (Math.PI / 180);
          // 使用基本的二维旋转矩阵将原始位移 dx 和 dy 转换为旋转后的位移 rotatedDx 和 rotatedDy。
          const rotatedDx = dx * Math.cos(angle) + dy * Math.sin(angle);
          const rotatedDy = dy * Math.cos(angle) - dx * Math.sin(angle);

          imgPosition.value = {
            x: imgPosition.value.x + rotatedDx,
            y: imgPosition.value.y + rotatedDy,
          };
          lastMousePosition.value = { x: event.clientX, y: event.clientY };
        }
      };

      const onMouseUp = () => {
        isDragging.value = false;
      };
      onMounted(() => {
        nextTick(() => {
          updateImgBoxDimensions();
          window.addEventListener("resize", updateImgBoxDimensions);
          window.addEventListener("mousemove", onMouseMove);
          window.addEventListener("mouseup", onMouseUp);
        });
      });

      return {
        zoom,
        rotation,
        container,
        imgStyle,
        resetZoom,
        handleRangeChange,
        containerWidth,
        containerHeight,
        onMouseDown,
        imgPosition,
      };
    },
    render() {
      const SsIcon = resolveComponent("ss-icon");
      return h("div", { class: "ocr-img-box" }, [
        h("div", { class: "img-bar" }, [
          h("div", this.imageObj.name),
          h("div", { class: "action-bar" }, [
            h("div", { class: "ocr-img-range-box" }, [
              h("input", {
                type: "range",
                min: 0,
                max: 100,
                value: this.zoom * 50, // 初始位置为50
                onInput: this.handleRangeChange,
              }),
              h("span", { class: "line" }),
            ]),
            h(SsIcon, {
              name: "reset",
              size: "26px",
              onClick: this.resetZoom,
            }),
          ]),
        ]),
        h("div", { class: "img-viewer", ref: "container" }, [
          h(
              "div",
              {
                class: "img-box",
                style: {
                  width: `${this.containerWidth}px`,
                  height: `${this.containerHeight}px`,
                  overflow: "hidden",
                  position: "relative",
                },
              },
              [
                h("img", {
                  src: this.imageObj.thumb,
                  style: this.imgStyle,
                  class: "zoomable-img",
                  onMousedown: this.onMouseDown,
                }),
              ]
          ),
        ]),
      ]);
    },
  };
  // 搜索输入框组件
  const SsSearchInput = {
    name: "SsSearchInput",
    props: {
      name: String,
      placeholder: String,
      width: {
        type: String,
        default: "100px",
      },
      modelValue: String,
    },
    emits: ["update:modelValue", "search"],
    setup(props, { emit }) {
      const handleInput = (e) => {
        emit("update:modelValue", e.target.value);
      };
      const handleKeyup = (e) => {
        if (e.key === "Enter") {
          emit("search");
        }
      };

      return { handleInput, handleKeyup };
    },
    render() {
      return h(
          "div",
          {
            class: "input",
            style: this.width ? { width: this.width } : undefined,
          },
          [
            h("input", {
              name: this.name,
              placeholder: this.placeholder,
              value: this.modelValue,
              onInput: this.handleInput,
              onKeyup: this.handleKeyup,
            }),
          ]
      );
    },
  };
  // ss-search-date-picker 日期时间选择器组件
  const SsSearchDatePicker = {
    name: "SsSearchDatePicker",
    props: {
      modelValue: {
        type: [String, Number, Date],
        default: "",
      },
      name: {
        type: String,
        required: true,
      },
      type: {
        type: String,
        default: "date",
        validator: (value) => ["date", "datetime", "time"].includes(value),
      },
      fmt: {
        type: String,
        default: null,
      },
      placeholder: {
        type: String,
        default: "",
      },
      width: {
        type: String,
        default: "100%",
      },
    },

    emits: ["update:modelValue"],

    setup(props, { emit }) {
      const errMsg = ref("");
      const validate = () => {
        if (window.ssVm) {
          const result = window.ssVm.validateField(props.name);
          console.log("validate", window.ssVm.validateField(props.name));
          errMsg.value = result.valid ? "" : result.message;
        }
      };
      // 根据type确定默认格式
      const defaultFormat = computed(() => {
        switch (props.type) {
          case "datetime":
            return "YYYY-MM-DD HH:mm:ss";
          case "date":
            return "YYYY-MM-DD";
          case "time":
            return "HH:mm:ss";
        }
      });

      const convertJavaFormatToElement = (javaFormat) => {
        if (!javaFormat) return null;
        return javaFormat
            .replace("yyyy", "YYYY")
            .replace("MM", "MM")
            .replace("dd", "DD")
            .replace("HH", "HH")
            .replace("mm", "mm")
            .replace("ss", "ss");
      };

      const finalFormat = computed(() => {
        if (props.fmt) {
          return convertJavaFormatToElement(props.fmt);
        }
        return defaultFormat.value;
      });

      // 使用 resolveComponent 获取组件
      const ElDatePicker = resolveComponent("ElDatePicker");
      const ElTimePicker = resolveComponent("ElTimePicker");
      const SsFormIcon = resolveComponent("SsFormIcon");
      const ElIcon = resolveComponent("ElIcon");
      let useTimePicker = true;
      //"yyyy-MM-dd HH:mm:ss";  "日期字符串格式在java的写法",传到本组件fmt属性也是按这个格式
      if (props.fmt) {
        //有fmt属性，则以fmt属性优先判断类型
        if (/[dMy]/.test(props.fmt)) {
          //如果有传入日期格式，且含年月日
          useTimePicker = false;
        } else {
          useTimePicker = true;
        }
      } else if (props.type !== "time") {
        useTimePicker = false;
      }
      const dateType = computed(() => {
        const fmt = props.fmt || "";
        if (fmt.includes("HH:mm:ss")) {
          return "datetime";
        } else if (fmt.includes("HH:mm")) {
          return "datetime";
        } else if (fmt.includes("mm:ss")) {
          return "time";
        }
        return "date";
      });
      const handleValueUpdate = (val) => {
        emit("update:modelValue", val);
        emit("change", val); // 同时触发 change 事件
        setTimeout(() => {
          validate();
        }, 50);
      };
      return () =>
          h(
              "div",
              { class: "ss-search-date-picker", style: { width: props.width } },
              [
                h("input", {
                  type: "hidden",
                  name: props.name,
                  value: props.modelValue,
                }),
                h(useTimePicker ? ElTimePicker : ElDatePicker, {
                  modelValue: props.modelValue,
                  "onUpdate:modelValue": handleValueUpdate,
                  type: dateType.value,
                  format: finalFormat.value,
                  "value-format": finalFormat.value,
                  clearable: true,
                  placeholder: props.placeholder,
                  class: "custom-date-picker", // 用于自定义样式
                  "time-arrow-control": props.type === "datetime", // 修改这里
                  size: "large", // 添加这一行，改为 large 尺寸
                  style: { width: "100%" },
                  "prefix-icon": h(SsFormIcon, { class: "form-icon-time" }),
                }),
              ]
          );
    },
  };
  // 搜索按钮组件(包含下拉按钮)
  const SsSearchButton = {
    name: "SsSearchButton",
    props: {
      text: {
        type: String,
        required: true,
      },
      iconClass: {
        type: String,
        required: true,
      },
      opt: {
        type: Array,
        default: () => [],
      },
      checkId: {
        type: String,
        default: "0",
      },
    },
    setup(props, { emit }) {
      const currentId = ref(props.checkId || "0");
      const showPopup = ref(false);

      const handleMouseEnter = () => {
        showPopup.value = true;
      };

      const handleMouseLeave = () => {
        showPopup.value = false;
      };

      // 添加点击事件处理，阻止默认行为
      const handleClick = (e) => {
        e.preventDefault();
        if (props.opt?.length > 0) {
          const selectedOption =
              currentId.value === "0"
                  ? props.opt[0]
                  : props.opt.find((opt) => opt.id === currentId.value);

          if (selectedOption) {
            selectedOption.callback?.();
          }
        } else {
          emit("click", e);
        }
      };
      // 获取显示文本
      const getDisplayText = () => {
        if (!props.opt?.length) return props.text;

        const selectedOption =
            currentId.value === "0"
                ? props.opt[0]
                : props.opt.find((opt) => opt.id === currentId.value);

        return selectedOption ? selectedOption.desc : props.opt[0].desc;
      };

      return () =>
          h(
              "button",
              {
                class:
                    props.opt?.length > 0
                        ? "ss-drop-button ss-drop-button-more"
                        : "ss-drop-button",
                type: "button", // 明确指定按钮类型为 button
                onMouseenter: handleMouseEnter,
                onMouseleave: handleMouseLeave,
                onClick: handleClick, // 添加点击事件处理
              },
              [
                props.iconClass
                    ? h("span", {
                      class: props.iconClass,
                      style: { fontFamily: "iconfont", marginRight: "5px" },
                    })
                    : null,
                h("span", getDisplayText()),
                props.opt.length > 0 &&
                showPopup.value &&
                h(
                    "div",
                    {
                      class: "popup",
                    },
                    props.opt.map((item) =>
                        h(
                            "div",
                            {
                              onClick: (e) => {
                                e.preventDefault(); // 选项点击也阻止默认行为
                                e.stopPropagation(); // 阻止事件冒泡
                                currentId.value = item.id; // 更新当前选中的ID
                                item.callback();
                                showPopup.value = false; // 选择后关闭弹窗
                              },
                            },
                            item.desc
                        )
                    )
                ),
              ]
          );
    },
  };
  // 下拉按钮组件
  const SsDropButton = {
    name: "SsDropButton",
    props: {
      text: {
        type: String,
        required: true,
      },
      iconClass: {
        type: String,
        required: true,
      },
      opt: {
        type: Array,
        default: () => [],
      },
      checkId: {
        type: String,
        default: "0",
      },
      onclick: {
        type: Function,
        default: null,
      },
    },
    setup(props) {
      const currentId = ref(props.checkId || "0");
      const showPopup = ref(false);

      const handleMouseEnter = () => {
        showPopup.value = true;
      };

      const handleMouseLeave = () => {
        showPopup.value = false;
      };

      // 添加点击事件处理，阻止默认行为
      const handleClick = (e) => {
        e.preventDefault();
        if (props.opt?.length > 0) {
          const selectedOption =
              currentId.value === "0"
                  ? props.opt[0]
                  : props.opt.find((opt) => opt.id === currentId.value);

          if (selectedOption) {
            selectedOption.callback?.();
          }
        } else if (props.onclick) {
          props.onclick();
        }
      };
      // 获取显示文本
      const getDisplayText = () => {
        if (!props.opt?.length) return props.text;

        const selectedOption =
            currentId.value === "0"
                ? props.opt[0]
                : props.opt.find((opt) => opt.id === currentId.value);

        return selectedOption ? selectedOption.desc : props.opt[0].desc;
      };

      return () =>
          h(
              "button",
              {
                class:
                    props.opt?.length > 0
                        ? "ss-drop-button ss-drop-button-more"
                        : "ss-drop-button",
                type: "button", // 明确指定按钮类型为 button
                onMouseenter: handleMouseEnter,
                onMouseleave: handleMouseLeave,
                onClick: handleClick, // 添加点击事件处理
              },
              [
                h("span", {
                  class: props.iconClass,
                  style: { fontFamily: "iconfont" },
                }),
                h("span", getDisplayText()),
                props.opt.length > 0 &&
                showPopup.value &&
                h(
                    "div",
                    {
                      class: "popup",
                    },
                    props.opt.map((item) =>
                        h(
                            "div",
                            {
                              onClick: (e) => {
                                e.preventDefault(); // 选项点击也阻止默认行为
                                e.stopPropagation(); // 阻止事件冒泡
                                currentId.value = item.id; // 更新当前选中的ID
                                item.callback();
                                showPopup.value = false; // 选择后关闭弹窗
                              },
                            },
                            item.desc
                        )
                    )
                ),
              ]
          );
    },
  };
  /**
   * 二级页面标签组件
   * @name ss-sub-tab
   * @description 用于展示二级页面的布局组件，包含左侧垂直标签导航（支持分组）和右侧iframe内容区
   * @property {String} headerImage - 左侧顶部图片地址
   * @property {Array} menuList - 菜单配置列表
   * @property {Object} [activeMenu] - 当前选中的菜单项，不传则自动选择第一个可选菜单
   * @property {Array} footerButtons - 底部按钮配置列表

   */
  const SsSubTab = {
    name: "SsSubTab",
    props: {
      headerImage: {
        type: String,
        default: "",
      },
      menuList: {
        type: Array,
        required: true,
      },
      activeMenu: {
        // 只需要传入标题
        type: String,
        default: "",
      },
      footerButtons: {
        type: Array,
        default: () => [],
      },
      leftDisplay: {
        type: Boolean,
        default: true,
      },
    },
    emits: ["menu-change", "footer-click"],
    setup(props, { emit }) {
      // 根据标题找到对应的菜单项
      const findMenuByTitle = (title) => {
        for (const item of props.menuList) {
          if (item.children?.length > 0) {
            const child = item.children.find((c) => c.title === title);
            if (child) return child;
          } else if (item.title === title) {
            return item;
          }
        }
        return null;
      };

      // 计算默认选中的菜单项
      const defaultActiveMenu = computed(() => {
        if (props.activeMenu) {
          const menu = findMenuByTitle(props.activeMenu);
          if (menu) return menu;
        }

        const firstItem = props.menuList[0];
        if (!firstItem) return null;

        return firstItem.children?.length > 0
            ? firstItem.children[0]
            : firstItem;
      });

      const currentMenu = ref(defaultActiveMenu.value);

      // 监听外部activeMenu变化
      watch(
          () => props.activeMenu,
          (newTitle) => {
            if (newTitle) {
              const menu = findMenuByTitle(newTitle);
              if (menu) {
                currentMenu.value = menu;
              }
            }
          }
      );

      // 选择菜单项时触发 menu-change 钩子
      const selectItem = (item) => {
        currentMenu.value = item;
        emit("menu-change", item);
      };

      // 处理底部按钮点击
      const handleFooterClick = (button, index) => {
        emit("footer-click", { button, index });
      };

      return {
        currentMenu,
        selectItem,
        handleFooterClick,
      };
    },
    template: `
          <div class="project-edit-container">
              <div class="left-side" v-if="leftDisplay">
              
                  <!-- 头部图片 -->
                  <div v-if="headerImage" class="menu-header">
                      <div class="thumb">
                          <img :src="headerImage" style="object-fit: cover;width: 100%;height: 100%;" />
                      </div>
                  </div>

                  <!-- 菜单内容 -->
                  <div class="menu-content">
                      <div class="scroll-view">
                          <template v-for="(menuItem, i) in menuList" :key="i">
                              <!-- 分组菜单 -->
                              <div v-if="menuItem.children?.length > 0" class="group">
                                  <div class="menu-item" @click="menuItem.open = !menuItem.open">
                                      <span>{{ menuItem.title }}</span>
                                      
                                      <span class="arrow">
                                          <ss-icon :name="menuItem.open ? 'arrow-up' : 'arrow-down'" size="20px" />
                                      </span>
                                  </div>
                                  <div v-show="menuItem.open" class="group-detail">
                                      <div v-for="(item, j) in menuItem.children" 
                                          :key="j" 
                                          class="menu-item"
                                          :class="{ active: item.name === currentMenu?.name }"
                                          @click="selectItem(item)"
                                      >
                                          {{ item.title }}
                                           
                                           &nbsp;
                                          <span class="menu-item-point" v-if="item.cgxList || item.objectList"></span>
                                      </div>
                                  </div>
                              </div>
                              <!-- 普通菜单项 -->
                              <div v-else 
                                  class="menu-item"
                                  :class="{ active: menuItem.name === currentMenu?.name }"
                                  @click="selectItem(menuItem)"
                              >
                                    {{ menuItem.title }}
                                   &nbsp;
                                  <span class="menu-item-point" v-if="menuItem.cgxList || menuItem.objectList"></span>
                              </div>
                          </template>
                      </div>
                  </div>
                  
                  <!-- 底部按钮 -->
                  <div v-if="footerButtons.length > 0" 
                      class="sub-tab-menu-footer"
                      @click="footerButtons[0].onclick"
                  >
                      <div>{{ footerButtons[0].text }}</div>
                      <ss-icon 
                          v-if="footerButtons.length > 1" 
                          name="arrow-up" 
                          size="24px" 
                      />
                      
                      <!-- 悬浮按钮 -->
                      <div v-if="footerButtons.length > 1" class="sub-tab-menu-popup">
                          <div v-for="(button, index) in footerButtons.slice(1)" 
                              :key="index"
                              @click.stop="button.onclick"
                          >
                              {{ button.text }}
                          </div>
                      </div>
                  </div>
                  
              </div>

              <!-- 右侧内容区域 -->
              <div class="content-area fit-height-content" style="overflow: hidden;" :style="!leftDisplay ? { width: '100%' } : {}">
                 
                  <template v-for="(menuItem, i) in menuList" :key="i">
                      <iframe 
                          :src="menuItem.url"
                          style="height: 100%;width: 100%;"
                          frameborder="0"
                          class="sub-tab-iframe"
                          :id="i === 0 ? 'sub-tab-iframe' : ''"
                          v-show="currentMenu?.name === menuItem.name"
                      />
                  </template>
              </div>
          </div>
      `,
  };
  // <iframe
  //     v-if="currentMenu?.url"
  //     :src="currentMenu.url"
  //     style="height: 100%;width: 100%;"
  //     frameborder="0"
  //     id="sub-tab-iframe"
  // />

  // ss-photo-upload 通用图片上传组件
  const SsImgUpload = {
    name: "SsImgUpload",
    props: {
      name: {
        type: String,
        required: true,
      },
      // 图片URL，用于回显
      // url: {
      //   type: String,
      //   default: "",
      // },
      // 样式类名
      class: {
        type: String,
        required: true,
      },
      // 裁剪配置
      cropperOpt: {
        type: Object,
        default: () => ({
          width: 360,
          height: 360,
          aspectRatio: 1,
        }),
      },
      //上传图片url(未加图片名参数之前的部分)
      ulUrl: {
        type: String,
        required: true,
      },
      //下载图片url(未加图片名参数之前的部分)
      dlUrl: {
        type: String,
        required: true,
      },
      modelValue: [String, Number],
    },

    emits: ["update:modelValue"],

    setup(props, { emit }) {
      const inputId = Vue.computed(
          () => `file_${Vue.getCurrentInstance().uid}`
      );
      //修改图片初始显示路径
      let pathVal = ref(props.modelValue);
      let picUrl = ref("");
      if (props.modelValue) {
        picUrl.value = props.dlUrl + "&path=" + props.modelValue;
      }

      Vue.onMounted(() => {
        window.SS.cropper.init({
          el: $(`#${inputId.value}`),
          photoSize: {
            width: props.cropperOpt.width,
            height: props.cropperOpt.height,
          },
          aspectRatio: props.cropperOpt.aspectRatio,
          uploadUrl: props.ulUrl,
          success: (path) => {
            pathVal.value = path;
            picUrl.value = props.dlUrl + "&path=" + path;
            emit("update:modelValue", path);
          },
        });
      });

      return () =>
          h("div", { class: [props.class] }, [
            h("input", {
              type: "file",
              accept: "image/*",
              id: inputId.value,
              style: { display: "none" },
            }),
            h("input", {
              type: "hidden",
              name: props.name,
              value: pathVal.value,
            }),
            h(
                "div",
                {
                  style: {
                    width: "100%",
                    height: "100%",
                  },
                  onClick: () => $(`#${inputId.value}`).click(),
                },
                [
                  picUrl.value &&
                  h("img", {
                    src: picUrl.value,
                    style:
                        "width: 100%; height: 100%;object-fit: inherit;position: relative;z-index: 11;",
                  }),
                ]
            ),
          ]);
    },
  };

  // 初始化函数，负责创建和挂载 Vue 应用
  // window.SS = { dom: {} };
  /**
   * 获取当前窗口的父窗口
   * @returns {Window} 父窗口对象
   */
  window.SS.topWin = (function (p, c) {
    while (p != c) {
      c = p;
      p = p.parent;
    }
    return c;
  })(window.parent, window);

  window.SS.createSsDialogInstance = createSsDialogInstance;
  /**
   * 创建弹窗
   * @param {Object} setting
   * @param {Function} callbackEvent
   */
  window.SS.openDialog = function (setting, callbackEvent) {
    if (setting.params) {
      const encodedParams = encodeURIComponent(JSON.stringify(setting.params));
      setting.src +=
          (setting.src.includes("?") ? "&" : "?") + "params=" + encodedParams;
    }

    if (window.parent && window.parent !== window) {
      window.parent.SS.createSsDialogInstance(setting, callbackEvent);
    } else {
      createSsDialogInstance(setting, callbackEvent);
    }
  };
  //关闭弹窗
  window.SS.closeDialog = function () {
    console.log("关闭弹窗");
    if (topWindow.dialogInstances.length > 0) {
      const instance = topWindow.dialogInstances.pop();
      console.log("instance", instance);
      console.log("instance.callbackEvent", instance.callbackEvent);
      console.log(
          "instance.callbackEvent.end",
          typeof instance.callbackEvent === "function"
      );
      if (instance.callbackEvent) {
        // 判断是否有end回调并执行
        if (typeof instance.callbackEvent === "function") {
          instance.callbackEvent();
        }
        if (typeof instance.callbackEvent.end === "function") {
          instance.callbackEvent.end();
        }
      }
      instance.app.unmount(); // 卸载最后一个实例
      if (instance.container && instance.container.parentNode) {
        instance.container.parentNode.removeChild(instance.container); // 移除容器
      }
    }
  };

  /**
   * 裁剪插件
   */
  window.SS.cropper = {
    init: function (setting) {
      if (!window.top.SS) window.top.SS = {};
      // 重要：确保 cropper 对象的完整初始化
      if (!window.top.SS.cropper) {
        window.top.SS.cropper = {
          settings: new Map(),
          _backupSettings: {},
          getSetting: this.getSetting,
          clearSetting: this.clearSetting,
          debug: this.debug,
        };
      } else if (!window.top.SS.cropper.settings) {
        // 如果 cropper 存在但 settings 不存在，重新初始化 settings
        window.top.SS.cropper.settings = new Map();
        window.top.SS.cropper._backupSettings = {};
      }
      const uploaderId = `uploader_${Date.now()}_${Math.random()
          .toString(36)
          .substr(2, 9)}`;

      window.top.SS.cropper.settings.set(uploaderId, setting);
      window.top.SS.cropper._backupSettings[uploaderId] = setting;

      setting.box = setting.box || "1";
      var winSetting = {
        headerTitle: "图片裁剪",
        src: "/newUI/page/cropper.jsp",
        width: "900",
        height: "500",
      };

      $(setting.el).change(function () {
        if (!window.SS.cropper.verify(setting)) {
          $(setting.el).val(""); // 清空文件选择
          return false;
        }
        var files = this.files;
        if (files && files.length) {
          if (!window.SS.cropper.verifySize($(setting.el)[0], 5)) {
            $(setting.el).val(""); // 清空文件选择
            alert("文件大小不能超过5M，请重新选择");
            return false;
          }
          var URL = window.URL || window.webkitURL;
          var file = files[0];
          setting.file = file;

          if (
              /^image\/\w+$/.test(file.type) &&
              /\.(jpg|jpeg|png|)$/i.test(file.name)
          ) {
            var uploadedImageURL = URL.createObjectURL(file);
            setting.data = uploadedImageURL;
            setting.fileName = file.name;
            // console.log()
            winSetting.params = {
              ...setting,
              uploaderId,
            };
            console.log("ss-componets中change之后的winSetting", winSetting);
            SS.openDialog(winSetting, {
              success: function (win) {
                console.log("裁剪插件成功");
                // win.cropperSetting = setting;
              },
              end: function () {
                console.log("裁剪插件结束");
                $(setting.el).val(""); // 清空文件选择
              },
            });
          } else {
            alert("请选择图片文件，支持jpg、jpeg、png格式");
          }
        }
      });
      return uploaderId;
    },
    verify: function (setting) {
      if (!setting) {
        console.error(" cropper setting is not undefined! ");
        return false;
      }
      if (!setting.el) {
        console.error(" cropper setting.el is not undefined! ");
        return false;
      }
      if (setting.photoSize) {
        if (
            (!setting.photoSize.width && setting.photoSize.height) ||
            (!setting.photoSize.height && setting.photoSize.width)
        ) {
          console.error(
              " cropper setting.photoSize { width, height } is not undefined! "
          );
          return false;
        }
      }
      if (!setting.box) {
        setting.box = "1";
      }

      if (!setting.aspectRatio) {
        setting.aspectRatio = 1 / 1;
      }

      return true;
    },
    verifySize: function (fileEl, maxSize) {
      // 判断是否为IE浏览器： /msie/i.test(navigator.userAgent) 为一个简单正则
      var isIE = /msie/i.test(navigator.userAgent) && !window.opera;
      var fileSize = 0;
      if (isIE && !fileEl.files) {
        // IE浏览器
        var filePath = fileEl.value; // 获得上传文件的绝对路径
        var fileSystem = new ActiveXObject("Scripting.FileSystemObject");
        var file = fileSystem.GetFile(filePath);
        fileSize = file.Size; // 文件大小，单位：b
      } else {
        // 非IE浏览器
        fileSize = fileEl.files[0].size;
      }

      var size = fileSize / 1024 / 1024;
      return !(size > maxSize);
    },
    // 获取特定上传组件的setting
    getSetting: function (uploaderId) {
      if (!window.top.SS?.cropper) {
        console.warn("顶层窗口中未找到 SS.cropper");
        return null;
      }

      // 优先从 Map 中获取
      let setting = window.top.SS.cropper.settings.get(uploaderId);

      // 如果 Map 中没有，尝试从备份中获取
      if (!setting && window.top.SS.cropper._backupSettings[uploaderId]) {
        console.log("从备份中恢复 setting");
        setting = window.top.SS.cropper._backupSettings[uploaderId];
        // 恢复到 Map 中
        window.top.SS.cropper.settings.set(uploaderId, setting);
      }

      return setting;
    },

    // 清理特定上传组件的setting
    clearSetting: function (uploaderId) {
      if (!window.top.SS?.cropper) return;

      window.top.SS.cropper.settings.delete(uploaderId);
      delete window.top.SS.cropper._backupSettings[uploaderId];
      console.log(
          "清理设置后的 Map size:",
          window.top.SS.cropper.settings.size
      );
    },
  };

  /**
   * 获取url中的参数
   * @returns {Object}
   */
  window.SS.getQueryParams = function () {
    const params = {};
    const queryString = window.location.search.substring(1);
    const pairs = queryString.split("&");
    for (let i = 0; i < pairs.length; i++) {
      const pair = pairs[i].split("=");
      params[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
    }
    if (params.params) {
      try {
        params.params = JSON.parse(params.params);
      } catch (e) {
        console.error("Failed to parse params:", e);
      }
    }

    return params;
  };

  /**
   * 创建vue应用
   * @param {Object} config 配置项
   * @values {String} config.el 挂载的元素
   * @values {Boolean} config.isDialogPage 是否是弹窗页面 决定了是否可以使用顶天立地
   * @values {Object} config.vueOptions vue配置项
   * @returns {Object} vue实例
   */
  window.SS.dom.initializeFormApp = function (config) {
    const { el, isDialogPage = false, ...vueOptions } = config;
    const app = createApp({
      ...vueOptions,
    });
    // 如果是弹窗iframe里面的html的话 给当前的页面挂上事件 实现顶天立地的效果
    if (isDialogPage) {
      function checkScroll() {
        // 选出所有fit-height-content的元素 如果有滚动条
        const elements = document.querySelectorAll(".fit-height-content");
        let hasScrollBar = false;
        // 检查元素是否有滚动条 检查当前窗口的所有元素
        // 如果有滚动条，则将结果设置为true
        elements.forEach((el) => {
          if (el.scrollHeight > el.clientHeight) {
            hasScrollBar = true;
          }
        });
        // 将结果发送给父窗口
        window.parent.postMessage({ hasScrollBar }, "*");
      }

      function addScrollListeners() {
        const elements = document.querySelectorAll("div");
        elements.forEach((el) => {
          el.addEventListener("scroll", checkScroll);
        });
      }
      const observer = new MutationObserver((mutations) => {
        addScrollListeners();
        checkScroll();
      });

      observer.observe(document.body, {
        childList: true,
        subtree: true,
      });

      window.addEventListener("resize", checkScroll);
    }
    // 注册组件
    app.component("SsLoginIcon", SsLoginIcon);
    app.component("SsMark", SsMark);
    app.component("SsFullStyleHeader", SsFullStyleHeader);
    app.component("SsDialog", SsDialog);
    app.component("SsInput", SsInput);
    app.component("SsObjp", SsObjp);
    app.component("SsHidden", SsHidden);
    app.component("SsCcp", SsCcp);
    app.component("SsDatePicker", SsDatePicker);
    app.component("SsIcon", SsIcon);
    app.component("SsCommonIcon", SsCommonIcon);
    app.component("SsBreadcrumb", SsBreadcrumb);
    app.component("SsEditor", SsEditor);
    app.component("SsDialogIcon", SsDialogIcon);
    app.component("SsBottomButton", SsBottomButton);
    app.component("SsNavIcon", SsNavIcon);
    app.component("SsHeaderIcon", SsHeaderIcon);
    app.component("SsGolbalMenuIcon", SsGolbalMenuIcon);
    app.component("SsCartListIcon", SsCartListIcon);
    app.component("SsQuickIcon", SsQuickIcon);
    app.component("SsFormIcon", SsFormIcon);
    app.component("SsBottomDivIcon", SsBottomDivIcon);
    app.component("SsEditorIcon", SsEditorIcon);
    app.component("SsValidate", SsValidate);
    app.component("SsOnoffbutton", SsOnoffbutton);
    app.component("SsOnoffbuttonArray", SsOnoffbuttonArray);
    app.component("SsTextarea", SsTextarea);
    app.component("SsLoginInput", SsLoginInput);
    app.component("SsLoginButton", SsLoginButton);
    app.component("SsSearch", SsSearch);
    app.component("SsCartItem", SsCartItem);
    app.component("SsCartItem2", SsCartItem2);
    app.component("SsListCard", SsListCard);
    app.component("SsFolderCard", SsFolderCard);
    app.component("SsFolderCartView", SsFolderCartView);
    app.component("SsPage", SsPage);
    app.component("SsRightInfo", SSRightInfo);
    app.component("SsSuccessPopup", SsSuccessPopup);
    app.component("SsErrorDialog", SsErrorDialog);
    app.component("SsVerify", SsVerify);
    app.component("SsVerifyNode", SsVerifyNode);
    app.component("SsOrcImgBox", SsOrcImgBox);
    app.component("ss-search-input", SsSearchInput);
    app.component("ss-search-date-picker", SsSearchDatePicker);

    app.component("ss-search-button", SsSearchButton);
    app.component("ss-drop-button", SsDropButton);
    app.component("ss-sub-tab", SsSubTab);
    app.component("ss-img", SsImgUpload);
    // 设置为中文
    app.use(ElementPlus, {
      locale: ElementPlusLocaleZhCn,
    });
    // console.log(ElementPlus);
    // 确保 ElementPlusIconsVue
    // if (window.ElementPlusIconsVue) {
    //   // 注册 Element Plus 图标组件
    //   for (const [key, component] of Object.entries(
    //     window.ElementPlusIconsVue
    //   )) {
    //     console.log(key, component);
    //     app.component(key, component);
    //   }
    // }
    // 挂载首页的组件
    for (const componentName in IndexComponents) {
      app.component(componentName, IndexComponents[componentName]);
    }
    // 挂载echarts的组件
    for (const componentName in EchartComponents) {
      app.component(componentName, EchartComponents[componentName]);
    }
    // 挂载 Vue 应用
    const vm = app.mount(el);
    vm.data = vueOptions.data();

    return vm;
  };
})();
