<!--
@ 作者: 秦东
@ 时间: 2024-05-10 08:47:28
@ 备注: 表单控件（app）专用
-->
<script lang="ts" setup>
import { getRequest } from "@/api/DesignForm";
import { chineseToPinyin, customerFormGroupList } from "@/api/DesignForm/requestapi";
import { formatNumber } from "@/api/DesignForm/utils";
import appValidate from "./validateApp";
import appNumberValidate from "./rule/numberRules";
import { useDesignFormStore } from "@/store/DesignForm/designForm";

import { VideoMsg, PublicAtrr } from "@/api/DesignForm/types";
import { genFileId } from "element-plus";
import type { UploadInstance, UploadProps, UploadRawFile } from "element-plus";

//数学计算公式编辑器
import MathFormula from "@/components/DesignForm/math/mathFormula.vue";
//样式布局
import LayoutPage from "@/components/DesignForm/layoutPage/index.vue";
/**
@ 作者: 秦东
@ 时间: 2024-05-10 09:07:53
@ 功能: 接收父级参数
*/
const props = withDefaults(
  defineProps<{
    formData: any;
    formList: any;
    formConfig: any;
    formOtherData: any;
    customerformid: number | string;
    formInfo: any;
    isEdit: boolean;
    formField: any[];
  }>(),
  {
    formConfig: () => {
      return {};
    },
    formOtherData: () => {
      // 其他不需要保存在formData里的数据
      return {};
    },
    isEdit: () => {
      return false;
    },
    formField: () => {
      return [];
    },
  }
);
//注册自定义事件
const emits = defineEmits<{
  (e: "openDialog", data: any): void;
  (e: "update:formOtherData", data: any): void;
  (e: "videoMsgChange", data: VideoMsg): void;
  //(e: 'update:formData', data: any): void
  //(e: 'update:formConfig', data: any): void
}>();
/**
@ 作者: 秦东
@ 时间: 2024-05-10 09:08:19
@ 功能: 接收值转化ref对象
*/
const { formConfig, formData } = toRefs(props);
const store = useDesignFormStore() as any;
const designType = inject("formDesignType");
const dataSourceOption = ref([]);

const controlData = computed(() => {
  // console.log("注册自定义事件----------------->",store.controlAttr)
  return store.controlAttr;
});
/**
@ 作者: 秦东
@ 时间: 2024-05-10 09:14:03
@ 功能: 表单及组件单元控制属性
*/
const state = reactive({
  dataSourceList: [], //数据源列表
  customRulesList: [...appValidate], // 自定义校验规则
  tooltip: {
    css: "当前表单应用页的样式，类似于.vue文件中的style scoped中的样式",
    dict:
      '数据字典，用于匹配多选组、下拉选择等，提供动态获取Options接口字典数据，一般不设置，从接口dict获取。json格式："sex":{"0":"男","1":"女"}',
    rules:
      "可参考UI组件表单校验，<a href='https://element-plus.gitee.io/zh-CN/component/form.html#%E8%A1%A8%E5%8D%95%E6%A0%A1%E9%AA%8C' target='_blank' style='color:red'>详情点击</a>",
    props: "可添加当前组件所有prop属性及事件方法",
  },
  tabsName: "second",
  numberRulesList: [...appNumberValidate],
});
/**
@ 作者: 秦东
@ 时间: 2024-05-10 10:15:14
@ 功能: 分组数据
*/
const page = ref<number>(1);
const pageSize = ref<number>(200000);
const loadingmore = ref(false);
const loadingnomore = ref(false);
const formGroup = ref<any[]>([]);
const gainFormGroupList = () => {
  loadingmore.value = true;
  let sendInfo = {
    page: page.value,
    pagesize: pageSize.value,
    state: 1,
  };
  customerFormGroupList(sendInfo)
    .then((data) => {
      formGroup.value = data.data;
    })
    .finally(() => {
      loadingmore.value = false;
    });
};
/**
@ 作者: 秦东
@ 时间: 2024-05-10 09:44:23
@ 功能: 表单控制项
*/
const formControlProject = computed(() => {
  const isSearch = state.isSearch;
  return [
    {
      label: "表单名称",
      placeholder: "用于保存的表单名称",
      value: props.formOtherData.formName,
      key: "formName",
      hide: isSearch,
    },
    {
      label: "数据源",
      placeholder: "请选择数据源",
      value: formatNumber(props.formOtherData.source),
      type: "select",
      options: dataSourceOption.value,
      key: "source",
      hide: isSearch || !dataSourceOption.value?.length,
      clearable: true,
    },
    {
      label: "表单标识",
      value: formData.value.name,
      placeholder: "表单唯一标识，可为空",
      key: "name",
      hide: isSearch,
    },
  ];
});
/**
@ 作者: 秦东
@ 时间: 2024-05-10 11:20:18
@ 功能: 根据选定数据源获取表单字段
*/
const getFormFieldBySource = (id?: string) => {
  if (state.isSearch) {
    // 搜索设计这里不需要数据源
    return;
  }
  const source = id;
  if (source) {
    getRequest("sourceById", { id: source })
      .then((res) => {
        // console.log(res)
        const tableData = res.data.result?.tableData;
        if (tableData && tableData.length) {
          state.dataSourceList = tableData.filter((item: any) => item.enterable);
        }
      })
      .catch((res) => {
        // console.log(res)
      });
  }
};
defineExpose({ getFormFieldBySource });

/**
@ 作者: 秦东
@ 时间: 2024-05-10 11:19:01
@ 功能: 表单属性修改
*/
const formAttrChange = (obj: any, val?: any) => {
  // console.log("表单属性修改--->",obj,val,{ [obj.key]: obj.value })
  if (obj.key === "source") {
    getFormFieldBySource(obj.value); // 改变了数据源了，重新请求数据
    // 清空设计区已选择的组件，再一次选择时字段标识才会变
    store.setActiveKey("");
    store.setControlAttr({});
  }
  if (["formName", "source"].includes(obj.key)) {
    emits(
      "update:formOtherData",
      Object.assign(props.formOtherData, { [obj.key]: obj.value })
    );
    formData.value[obj.key] = obj.value;
    return;
  }
  if (obj.path === "config") {
    formConfig.value[obj.key] = obj.value || val;
  } else {
    formData.value[obj.key] = obj.value;
  }
};
/**
@ 作者: 秦东
@ 时间: 2024-05-10 10:17:29
@ 功能: 组件加载完毕执行
*/
onMounted(() => {
  gainFormGroupList();
});
/**
@ 作者: 秦东
@ 时间: 2024-05-10 11:22:26
@ 功能: 判断输入框是否可写
*/
const isNotWrite = (val: any) => {
  if (val.key === "name" && props.customerformid != "") {
    return true;
  }
  return false;
};
const isNotWriteWord = (val: any) => {
  // console.log("判断输入框是否可写--->",val,props.customerformid)
  let ary = ["creater", "creater_time", "edit_time", "owner", "org"];
  if (ary.includes(val)) {
    return true;
  } else {
    if (
      val.eventName === "filedNameKey" &&
      props.customerformid != "" &&
      props.formField.includes(val.value)
    ) {
      return true;
    }
    return false;
  }
};
/**
@ 作者: 秦东
@ 时间: 2024-03-18 11:42:52
@ 功能: 上传图标相关
*/
const imgUploadApiUrl = import.meta.env.VITE_APP_BASE_API + "/api/upordown"; //上传地址
const handleAvatarSuccess: UploadProps["onSuccess"] = (response, uploadFile) => {
  //   imageUrl.value = URL.createObjectURL(uploadFile.raw!)
  formConfig.value.imageUrl = response.data.url;
};
/**
@ 作者: 秦东
@ 时间: 2024-05-10 11:28:40
@ 功能: 上传前验证
*/
const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
  // console.log("beforeAvatarUpload",rawFile.type)
  if (
    rawFile.type !== "image/jpeg" &&
    rawFile.type !== "image/jpg" &&
    rawFile.type !== "image/png" &&
    rawFile.type !== "image/gif" &&
    rawFile.type !== "image/icon"
  ) {
    ElMessage.error("请上传以下格式的图片(jpg、jpeg、png、gif、icon)!" + rawFile.type);
    return false;
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error("图片大小不要大于 2MB!");
    return false;
  }
  return true;
};
/**
@ 作者: 秦东
@ 时间: 2024-05-10 11:34:15
@ 功能: 表单接口事件
*/
const eventClick = (type: string, tooltip?: string) => {
  emits("openDialog", { type: type, title: tooltip, direction: "ltr" });
};
/**
@ 作者: 秦东
@ 时间: 2024-05-10 11:52:57
@ 功能: 编辑表单样式
*/
const editFormStyle = (tooltip: string) => {
  emits("openDialog", {
    codeType: "css",
    direction: "ltr",
    type: "css",
    title: tooltip,
  });
};
/**
@ 作者: 秦东
@ 时间: 2024-05-10 11:53:45
@ 功能: 设置数据字典
*/
const editFormDict = (tooltip: string) => {
  emits("openDialog", {
    type: "dict",
    direction: "ltr",
    codeType: "json",
    title: tooltip,
  });
};
/**
@ 作者: 秦东
@ 时间: 2024-05-10 13:19:37
@ 功能: 组件属性
*/
const attrList = computed(() => {
  if (Object.keys(controlData.value).length) {
    const {
      control = {},
      type,
      name,
      config = {},
      item = {},
      attr = {},
      selectvalue = "default",
      mathFormula = {},
    }: {
      control: any;
      type: any;
      name: any;
      item: any;
      attr: any;
      config: any;
      selectvalue: any;
      mathFormula: any;
    } = controlData.value;
    let columnIndex = false; // 是否显示序号列
    if (type === "table") {
      // 表格时处理
      const list = controlData.value && controlData.value.list;
      if (list && list.length > 0) {
        columnIndex = list[0].type === "index";
      }
    }
    const temp = reactive<PublicAtrr[]>([
      {
        label: "标签名称",
        value: item.label,
        path: "item.label",
        vHide: [
          "table",
          "grid",
          "tabs",
          "title",
          "gridChild",
          "div",
          "inputSlot",
          "flex",
          "button",
          "txt",
        ],
        eventName: "labelNameVal",
      },
      {
        label: "自定义Class",
        value: config.className,
        placeholder: "样式类名",
        path: "config.className",
      },
      {
        label: "字段标识",
        value: name,
        type: Object.keys(state.dataSourceList).length > 0 ? "select" : "text",
        placeholder: "字段唯一标识，对应数据库",
        dict: state.dataSourceList,
        path: "name",
        vHide: [
          "grid",
          "tabs",
          "card",
          "title",
          "gridChild",
          "tableColumn",
          "divider",
          "txt",
          "div",
          "button",
        ],
        eventName: "filedNameKey",
      },
      {
        label: "占位内容",
        value: control.placeholder,
        placeholder: "placeholder",
        path: "control.placeholder",
        vShow: [
          "password",
          "input",
          "textarea",
          "select",
          "date",
          "number",
          "datePicker",
          "tinymce",
          "timePicker",
          "treeSelect",
        ],
      },
      {
        label: "帮助信息",
        value: config.help,
        path: "config.help",
        vHide: [
          "table",
          "grid",
          "tabs",
          "gridChild",
          "divider",
          "div",
          "inputSlot",
          "flex",
          "button",
          "txt",
        ],
      },
      {
        label: "按钮类型",
        value: control.type,
        path: "control.type",
        type: "select",
        dict: {
          primary: "primary",
          success: "success",
          info: "info",
          warning: "warning",
          danger: "danger",
        },
        vShow: ["button"],
        clearable: true,
      },
      {
        label: "按钮名称",
        value: control.label,
        path: "control.label",
        vShow: ["button"],
      },
      {
        label: "按钮事件",
        value: control.key,
        path: "control.key",
        type: "select",
        dict: {
          submit: "提交表单",
          reset: "重置表单",
          cancel: "取消返回",
          none: "无动作(自定义)",
        },
        vShow: ["button"],
      },
      {
        label: "对齐方式",
        value: config.textAlign,
        path: "config.textAlign",
        type: "select",
        dict: {
          left: "left",
          right: "right",
          center: "center",
        },
        vShow: ["button", "div"],
      },

      {
        label: "隐藏label",
        value: item.showLabel,
        path: "item.showLabel",
        type: "switch",
        vHide: [
          "table",
          "grid",
          "tabs",
          "title",
          "gridChild",
          "divider",
          "card",
          "div",
          "inputSlot",
          "flex",
          "button",
          "txt",
        ],
      },

      {
        label: "表单栅格",
        value: config.span,
        placeholder: "表单区域栅格宽，0为自动宽",
        path: "config.span",
        vHide: ["gridChild"],
        isNum: true,
      },
      {
        label: "文本值",
        value: control.modelValue,
        placeholder: "支持html",
        path: "control.modelValue",
        vShow: ["txt"],
        inputStyle: "textarea",
      },
      {
        label: "设为密码",
        value: type,
        type: "select",
        dict: { input: "文本", password: "密码" },
        path: "type",
        vShow: ["input", "password"],
        vIf: state.isSearch, // 搜索模式下隐藏 为true
      },
      {
        label: "文本域高度",
        value: control.rows,
        placeholder: "输入框行数",
        path: "control.rows",
        vShow: ["textarea"],
        isNum: true,
      },
      {
        label: "前缀",
        value: config.prepend,
        placeholder: "文本前缀",
        path: "config.prepend",
        vShow: ["input", "password"],
      },
      {
        label: "后缀",
        value: config.append,
        placeholder: "文本后缀",
        path: "config.append",
        vShow: ["input", "password"],
      },
      {
        label: "状态打开时的值",
        value: control.activeValue,
        placeholder: "状态打开时的值",
        path: "control.activeValue",
        vShow: ["switch"],
        isNum: true,
      },
      {
        label: "状态关闭时的值",
        value: control.inactiveValue,
        placeholder: "状态关闭时的值",
        path: "control.inactiveValue",
        vShow: ["switch"],
        isNum: true,
      },
      {
        label: "增加按钮文案",
        value: config.addBtnText,
        path: "config.addBtnText",
        type: "text",
        Show: ["flex", "table"],
      },
      {
        label: "删除按钮文案",
        value: config.delBtnText,
        path: "config.delBtnText",
        type: "text",
        vShow: ["flex", "table"],
      },
      {
        label: "是否多选",
        value: control.multiple,
        path: "control.multiple",
        type: "switch",
        vShow: ["select", "treeSelect"],
        eventName: "selectMultiple",
      },
      {
        label: "可清空",
        value: control.clearable,
        path: "control.clearable",
        type: "switch",
        vShow: ["select"],
      },
      {
        label: "是否禁用",
        value: control.disabled,
        path: "control.disabled",
        type: "switch",
        vShow: [
          "input",
          "password",
          "textarea",
          "radio",
          "checkbox",
          "select",
          "date",
          "switch",
          "number",
          "cascader",
          "upload",
          "rate",
          "tinymce",
          "treeSelect",
        ],
        vIf: state.isSearch,
      },
      {
        label: "是否禁用编辑",
        value: config.editDisabled,
        path: "config.editDisabled",
        type: "switch",
        vShow: [
          "input",
          "password",
          "textarea",
          "radio",
          "checkbox",
          "select",
          "date",
          "switch",
          "number",
          "cascader",
          "upload",
          "treeSelect",
          "table",
          "flex",
        ],
        vIf: state.isSearch,
      },
      {
        label: "添加页隐藏",
        value: config.disabledAdd,
        path: "config.disabledAdd",
        type: "switch",
        vIf: state.isSearch,
        vHide: ["inputSlot"],
      },
      {
        label: "编辑页隐藏",
        value: config.disabledEdit,
        path: "config.disabledEdit",
        type: "switch",
        vIf: state.isSearch,
        vHide: ["inputSlot"],
      },
      {
        label: "详情页隐藏",
        value: config.disabledDetail,
        path: "config.disabledDetail",
        type: "switch",
        vIf: state.isSearch,
        vHide: ["inputSlot"],
      },
      {
        label: "设为Input输入框的前/后缀",
        value: type === "inputSlot",
        path: "",
        type: "switch",
        vShow: ["select", "inputSlot"],
        eventName: "setInputSlot",
      },
      {
        label: "标题",
        value: control.modelValue,
        path: "control.modelValue",
        vShow: ["title"],
      },
      {
        label: "占据的列数span",
        value: attr.span,
        path: "attr.span",
        vShow: ["gridChild"],
        eventName: "formatNumber",
        isNum: true,
      },
      {
        label: "左侧的间隔格数offset",
        value: attr.offset,
        path: "attr.offset",
        vShow: ["gridChild"],
        eventName: "formatNumber",
        isNum: true,
      },
      {
        label: "向右移动格数push",
        value: attr.push,
        path: "attr.push",
        vShow: ["gridChild"],
        eventName: "formatNumber",
        isNum: true,
      },
      {
        label: "向左移动格数pull",
        value: attr.pull,
        path: "attr.pull",
        vShow: ["gridChild"],
        eventName: "formatNumber",
        isNum: true,
      },
      {
        label: "序号列",
        value: columnIndex,
        type: "switch",
        vShow: ["table"],
        eventName: "tableColumn1",
      },
      {
        label: "组件名",
        value: config.componentName,
        placeholder: "全局注册的组件名称",
        path: "config.componentName",
        vShow: ["component"],
      },
      {
        label: "隐藏条件",
        value: config.associatedForms,
        path: "config.associatedForms",
        type: "associatedForms_hide",
        vIf: state.isSearch,
        vShow: ["associatedForms"],
      },
      {
        label: "关联表单",
        value: config.associatedForms,
        path: "config.associatedForms",
        type: "associatedForms_form",
        vIf: state.isSearch,
        vShow: ["associatedForms"],
      },
      {
        label: "数据范围",
        value: config.associatedForms,
        path: "config.associatedForms",
        type: "associatedForms_dataRange",
        vIf: state.isSearch,
        vShow: ["associatedForms"],
      },
      {
        label: "数据填充规则",
        value: config.associatedForms,
        path: "config.associatedForms",
        type: "associatedForms_FillRoles",
        vIf: state.isSearch,
        vShow: ["associatedForms"],
      },
      {
        label: "轮播图设置",
        value: config.carousel,
        path: "config.carousel",
        type: "carousel",
        vIf: state.isSearch,
        vShow: ["lowcodeCarsusel"],
      },

      {
        label: "穿梭框名",
        value: config.transfer,
        path: "config.transfer",
        type: "transfer_name",
        vIf: state.isSearch,
        vShow: ["lowcodeTransfer"],
      },
      {
        label: "选项数据源",
        value: config.transfer,
        path: "config.transfer",
        type: "transfer_options_datasource",
        vIf: state.isSearch,
        vShow: ["lowcodeTransfer"],
      },
      {
        label: "上传视频",
        value: config.uploadvideo,
        path: "config.uploadvideo",
        type: "uploadvideo_url",
        vIf: state.isSearch,
        vShow: ["videoUpAndPlay"],
      },
      {
        label: "上传图片",
        value: config.lowcodeImage,
        path: "config.lowcodeImage",
        type: "lowcodeImage_url",
        vIf: state.isSearch,
        vShow: ["lowcodeImage"],
      },
      {
        label: "尺寸",
        value: config.lowcodeImage,
        path: "config.lowcodeImage",
        type: "lowcodeImage_showMode",
        vIf: state.isSearch,
        vShow: ["lowcodeImage"],
      },
      {
        label: "契合度",
        value: config.lowcodeImage,
        path: "config.lowcodeImage",
        type: "lowcodeImage_fit",
        vIf: state.isSearch,
        vShow: ["lowcodeImage"],
      },
      {
        label: "圆角",
        value: config.lowcodeImage,
        path: "config.lowcodeImage",
        type: "lowcodeImage_radius",
        vIf: state.isSearch,
        vShow: ["lowcodeImage"],
      },
      {
        label: "边框和阴影",
        value: config.lowcodeImage,
        path: "config.lowcodeImage",
        type: "lowcodeImage_boderAndShadow",
        vIf: state.isSearch,
        vShow: ["lowcodeImage"],
      },
      {
        label: "图片链接",
        value: config.lowcodeImage,
        path: "config.lowcodeImage",
        type: "lowcodeImage_link",
        vIf: state.isSearch,
        vShow: ["lowcodeImage"],
      },
      {
        label: "浮动",
        value: config.lowcodeImage,
        path: "config.lowcodeImage",
        type: "lowcodeImage_float",
        vIf: state.isSearch,
        vShow: ["lowcodeImage"],
      },
      {
        label: "内外四边距",
        value: config.lowcodeImage,
        path: "config.lowcodeImage",
        type: "lowcodeImage_marginAndPadding",
        vIf: state.isSearch,
        vShow: ["lowcodeImage"],
      },
      {
        label: "视频宽度(像素)",
        value: config.uploadvideo,
        path: "config.uploadvideo",
        type: "uploadvideo_width",
        vIf: state.isSearch,
        vShow: ["videoUpAndPlay"],
      },
      {
        label: "视频高度(像素)",
        value: config.uploadvideo,
        path: "config.uploadvideo",
        type: "uploadvideo_height",
        vIf: state.isSearch,
        vShow: ["videoUpAndPlay"],
      },
      {
        label: "视频自动播放",
        value: config.uploadvideo,
        path: "config.uploadvideo",
        type: "uploadvideo_autoPlay",
        vIf: state.isSearch,
        vShow: ["videoUpAndPlay"],
      },
      {
        label: "视频循环播放",
        value: config.uploadvideo,
        path: "config.uploadvideo",
        type: "uploadvideo_loopPlay",
        vIf: state.isSearch,
        vShow: ["videoUpAndPlay"],
      },

      {
        label: "上传地址",
        value: control.action,
        placeholder: "图片/文件上传地址,可不填有默认值",
        path: "control.action",
        vShow: ["upload"],
      },
      {
        label: "文件字段名",
        value: control.name,
        placeholder: "上传的文件字段名,默认file",
        path: "control.name",
        vShow: ["upload"],
      },
      {
        label: "列表类型",
        value: control.listType,
        type: "select",
        dict: {
          text: "text",
          picture: "picture",
          "picture-card": "picture-card",
        },
        path: "control.listType",
        vShow: ["upload"],
      },
      {
        label: "提示文字",
        value: config.tip,
        placeholder: "提示说明文字",
        path: "config.tip",
        vShow: ["upload"],
      },
      {
        label: "按钮文本",
        value: config.btnText,
        placeholder: "上传按钮文本",
        path: "config.btnText",
        vShow: ["upload"],
      },
      {
        label: "分割线方向",
        type: "select",
        dict: { horizontal: "horizontal", vertical: "vertical" },
        placeholder: "分割线方向，默认horizontal",
        value: control.direction,
        path: "control.direction",
        vShow: ["divider"],
      },
      {
        label: "分隔符样式",
        placeholder: "分隔符样式，默认solid",
        value: control.borderStyle,
        path: "control.borderStyle",
        vShow: ["divider"],
      },
      {
        label: "文字方位",
        type: "select",
        dict: { left: "left", right: "right", center: "center" },
        value: control.contentPosition,
        path: "control.contentPosition",
        vShow: ["divider"],
      },
      {
        label: "最小值",
        value: control.min,
        path: "control.min",
        vShow: ["slider"],
        eventName: "formatNumber",
        isNum: true,
      },
      {
        label: "最大值",
        value: control.max,
        path: "control.max",
        vShow: ["rate", "slider"],
        eventName: "formatNumber",
        isNum: true,
      },
      {
        label: "步长",
        value: control.step,
        path: "control.step",
        vShow: ["slider"],
        eventName: "formatNumber",
        isNum: true,
      },
      {
        label: "显示类型",
        value: control.type,
        path: "control.type",
        vShow: ["datePicker"],
        type: "select",
        placeholder: "显示类型",
        dict: {
          year: "年",
          month: "月",
          date: "日期",
          datetime: "日期+时间",
          week: "周",
          datetimerange: "开始日期时间至结束日期时间",
          daterange: "开始日期至结束日期",
          monthrange: "开始月至结束月",
        },
      },
      {
        label: "时间格式",
        value: control.format,
        path: "control.format",
        vShow: ["datePicker", "timePicker"],
        placeholder: "显示在输入框中的格式",
      },
      {
        label: "color-format",
        value: control.colorFormat,
        path: "control.colorFormat",
        type: "select",
        placeholder: "写入 v-model 的颜色的格式",
        dict: { hsl: "hsl", hsv: "hsv", hex: "hex", rgb: "rgb" },
        vShow: ["colorPicker"],
      },
      {
        label: "文本高度",
        value: control.height,
        path: "control.height",
        placeholder: "文本高度(预览查看效果)",
        vShow: ["tinymce"],
      },
      {
        label: "文本宽度",
        value: control.width,
        path: "control.width",
        placeholder: "文本宽度(预览查看效果)",
        vShow: ["tinymce"],
      },
      {
        label: "图片上传地址",
        value: control.imgUrl,
        path: "control.imgUrl",
        placeholder: "图片上传地址",
        vShow: ["tinymce"],
      },
      {
        label: "附件上传地址",
        value: control.blobUrl,
        path: "control.blobUrl",
        placeholder: "附件上传地址",
        vShow: ["tinymce"],
      },
      {
        label: "显示模式",
        value: config.style,
        path: "config.style",
        placeholder: "显示风格(预览查看效果)",
        type: "select",
        dict: { default: "default", simple: "simple" },
        vShow: ["tinymce"],
      },
      {
        label: "默认值",
        value: control.mathsValue,
        selectvalue: selectvalue,
        path: "control.mathsValue",
        placeholder: "显示风格(预览查看效果)",
        type: "digitpage",
        dict: { default: "自定义", simple: "编辑公式" },
        vShow: ["digitpage"],
        control: control,
      },
    ]);
    // 过滤显示对应的值
    return temp.filter((item: any) => {
      let hasFilter = true;
      if (item.vShow) {
        hasFilter = item.vShow.includes(type);
      }
      if (item.vHide) {
        hasFilter = !item.vHide.includes(type);
      }
      if (item.vIf) {
        // 不显示vif＝true的
        hasFilter = false;
      }
      return hasFilter;
    });
  } else {
    return [];
  }
});
/**
@ 作者: 秦东
@ 时间: 2024-05-10 13:33:51
@ 功能: 组件属性变化
*/
const fileSignAry = reactive<any>([]);
const controlChange = (obj: any, val: any) => {
  switch (obj.eventName) {
    case "selectMultiple":
      if (val) {
        // 多选，将值改为数组
        controlData.value.control.modelValue = [];
      } else {
        // 单选
        controlData.value.control.modelValue = "";
      }
      break;
    case "tableColumn1":
      tableColumnAdd(val);
      break;
    case "formatNumber":
      val = parseInt(val); // 将值转数值
      break;
    case "filedNameKey":
      // 选择字段标识时，同时修改显示标题
      // 根据value找key
      if (obj.type === "select") {
        state.dataSourceList.forEach((item: any) => {
          if (item.name === val) {
            if (controlData.value.item) {
              controlData.value.item.label = item.label;
            }
            controlData.value.name = item.label;
          }
        });
      }
      break;
    case "setInputSlot":
      if (val) {
        // 将类型改为inputSlot
        controlData.value.type = "inputSlot";
        ElMessage.success(
          `请在对应的Input输入框属性前后缀设置key:${controlData.value.name}`
        );
      } else {
        controlData.value.type = "select";
      }
      // 这里会报错Cannot set properties of null (setting 'checked')
      // 因value:type===inputSlot，这里使用了v-model，影响不大暂不处理
      break;
    case "labelNameVal":
      if (val != "") {
        // console.log("props.customerformid",props.customerformid)
        // console.log("props.formField",props.formField)
        // console.log("props.formField.includes(obj.value)",props.formField.includes(controlData.value.name))
        // console.log("obj.value",controlData.value.name)
        let ary = ["founder", "founderTime", "editTime", "owner", "deptOrg"];
        if (!ary.includes(controlData.value.type)) {
          if (!props.formField.includes(controlData.value.name)) {
            chineseToPinyin({
              title: val,
              types: 8,
              connector: "",
              formJson: JSON.stringify(props.formInfo),
            }).then((data: any) => {
              if (data.code == 0) {
                if (data.data != "") {
                  if (!fileSignAry.includes(data.data)) {
                    controlData.value.name = data.data;
                    fileSignAry.push(data.data);
                  } else {
                    let isEnd = true;
                    do {
                      let titleVal = data.data + Rand(10000000, 99999999);
                      if (!fileSignAry.includes(titleVal)) {
                        controlData.value.name = titleVal;
                        fileSignAry.push(titleVal);
                        isEnd = false;
                      }
                    } while (isEnd);
                  }
                } else {
                  if (!fileSignAry.includes(val)) {
                    controlData.value.name = val;
                    fileSignAry.push(val);
                  } else {
                    let titleVal = val + Rand(10000000, 99999999);
                    if (!fileSignAry.includes(titleVal)) {
                      controlData.value.name = titleVal;
                      fileSignAry.push(titleVal);
                    }
                  }
                }
              }
            });
          }
        }
      }

      // console.log("字段编辑--fileSignAry--》",fileSignAry)
      break;
  }
  if (obj.path) {
    const newVal = obj.isNum ? formatNumber(val) : val; // 类型为数字时转整数
    obj.path && getPropByPath(controlData.value, obj.path, newVal);
  }
};
// 更多属性弹窗
const openAttrDialog = (type?: string, tooltip?: string) => {
  let editData = controlData.value.control;
  if (controlData.value.type === "button") {
    // 按钮组件编辑属性
    editData = controlData.value.config;
    type = "button";
  }
  switch (type) {
    case "treeSelect":
      editData = controlData.value.control.data;
      break;
    case "cascader":
      editData = controlData.value.options;
      break;
    case "optionsParams": // 选项请求附加参数
      editData = controlData.value.config.beforeRequest;
      // params.codeType = 'json'
      break;
    case "optionsResult":
      editData = controlData.value.config.afterResponse;
      break;
  }
  const emitsParams = {
    content: editData,
    title: tooltip,
    type: type,
    direction: "ltr",
    callback: (result: any) => {
      switch (type) {
        case "treeSelect":
          controlData.value.control.data = result;
          break;
        case "cascader":
          controlData.value.options = result;
          break;
        case "optionsParams":
          controlData.value.config.beforeRequest = result;
          break;
        case "optionsResult":
          controlData.value.config.afterResponse = result;
          break;
        case "button":
          controlData.value.config = result;
          break;
        default:
          controlData.value.control = {};
          Object.assign(controlData.value.control, result);
      }
    },
  };
  emits("openDialog", emitsParams);
};
// 必填校验
const requiredChange = (val: any) => {
  if (!controlData.value.item?.rules) {
    controlData.value.item.rules = [];
  }
  if (val) {
    controlData.value.item.rules.push({
      required: true,
      message: "必填项",
      trigger: "change",
    });
  } else {
    controlData.value.item.rules.splice(0, 1);
  }
};
// 多选固定选项增加
const addSelectOption = (type: any) => {
  if (controlData.value.type === "cascader") {
    // 级联时打开弹窗口
    openAttrDialog("cascader");
  } else if (controlData.value.type === "treeSelect") {
    openAttrDialog("treeSelect", "编辑组件下拉选项数据");
  } else {
    if (type === "tabs") {
      controlData.value.columns.push({
        label: "标签名称",
        list: [],
      });
    } else {
      controlData.value.options.push({
        label: "",
        value: "",
      });
    }
  }
};
// 属性设置相关结束
// 多选固定选项删除
const delSelectOption = (index: number, type?: string) => {
  if (type === "tabs") {
    controlData.value.columns.splice(index, 1);
  } else {
    controlData.value.options.splice(index, 1);
  }
};
// 添加校验规则
const addRules = (tooltip: string) => {
  if (!controlData.value.item?.rules) {
    controlData.value.item.rules = [];
  }
  const params = {
    content: controlData.value.item?.rules,
    title: tooltip,
    direction: "ltr",
    callback: (result: any) => {
      Object.assign(controlData.value.item.rules, result);
    },
  };
  emits("openDialog", params);
};
// 校验规则必填勾选设置，存在校验规则时勾选
const checkboxRequired = computed(() => {
  const val = controlData.value && controlData.value.item?.rules;
  if (val && val.length > 0) {
    return true;
  } else {
    return false;
  }
});
/**
@ 作者: 秦东
@ 时间: 2024-05-10 13:39:12
@ 功能: 子表时添加序号和操作列
*/
const tableColumnAdd = (val: string) => {
  const item = {
    name: "index",
    type: "index",
    item: {
      label: "序号",
    },
    control: {},
    config: {},
  };
  if (val) {
    controlData.value.list.unshift(item);
  } else {
    controlData.value.list.splice(0, 1);
  }
};
// 快速添加一条校验规则
const addRulesFast = () => {
  if (!controlData.value.customRules) {
    controlData.value.customRules = [];
  }
  controlData.value.customRules.push({
    type: "required",
    message: "必填项",
    trigger: "blur",
  });
};
/**
@ 作者: 秦东
@ 时间: 2024-05-10 13:40:14
@ 功能: 修改指定路径下的值
*/
const getPropByPath = (obj: any, path: string, val: any) => {
  let tempObj = obj;
  const keyArr = path.split(".");
  let i = 0;
  for (i; i < keyArr.length - 1; i++) {
    const key = keyArr[i];
    if (key in tempObj) {
      tempObj = tempObj[key];
    } else {
      throw new Error(`${key} is undefined`);
    }
  }
  const key = keyArr[i];
  const value = tempObj[keyArr[i]];

  if (val !== undefined) {
    tempObj[key] = val;
  }
  return {
    obj: tempObj,
    key: key,
    value: value,
  };
};
/**
@ 作者: 秦东
@ 时间: 2024-05-10 15:02:37
@ 功能: 默认值处理
*/
const unitInfo = ref<any>();
const formListmap = ref<any>();
const subUnit = ref<any>();
const mathBoxShow = ref(false);
const digitPageSub = (val: any, envt: any) => {
  subUnit.value = val;
  controlData.value.selectvalue = envt;
  formListmap.value = props.formList;
  if (envt == "simple") {
    unitInfo.value = attrList.value;
    mathBoxShow.value = true;
  }
};
/**
@ 作者: 秦东
@ 时间: 2024-05-10 15:05:47
@ 功能: 打开数学公司编辑器
*/
const openMathDialog = (val: any) => {
  subUnit.value = val;
  formListmap.value = props.formList;
  unitInfo.value = attrList.value;
  mathBoxShow.value = true;
};
/**
@ 作者: 秦东
@ 时间: 2024-05-10 15:30:55
@ 功能: 根据不同类型判断是否显示当前属性
*/
const showHide = (type: string[], show?: boolean) => {
  // show=true 条件成立显示，false符合条件隐藏
  if ((type && type.length === 0) || Object.keys(controlData.value).length === 0) {
    return false;
  }
  const index = type.indexOf(controlData.value.type);
  return show ? index !== -1 : index === -1;
};
/**
@ 作者: 秦东
@ 时间: 2024-03-01 08:16:459097
@ 功能: 判断是否是组件
*/
const cssIsShouw = (val: any) => {
  // console.log("判断是否是组件",val)
  if (val && val.length && val.length > 0) {
    return true;
  }
  return false;
};
/**
 * 获取非负整数随机数
 * @param Min 最小整数
 * @param Max 最大整数
 * @returns 随机数
 */
const Rand = (Min: number, Max: number) => {
  switch (Min) {
    case 0:
      return Math.round(Math.random() * Max);
    case 1:
      return Math.ceil(Math.random() * Max);
    default:
      return Math.round(Math.random() * (Max - Min) + Min);
  }
};
/**
@ 作者: 秦东
@ 时间: 2024-05-13 15:46:24
@ 功能: 
*/
watch(
  () => store.activeKey,
  (val: string) => {
    // console.log("监听数据编号--->", val)
    if (controlData.value.type === "lowcodeCarsusel") {
      const carsuselConfigData: CarsuselConfig[] =
        controlData.value.control.carsuselConfigArr;
      carsuselConfigData.forEach((element) => {
        //console.log(element)
        if (element.imgId == "") {
          //console.log("初始化imgid")
          let onlyNumber = uuidv4().replaceAll("-", "").toString(); //获取唯一编码
          element.imgId = onlyNumber;
        }
      });
    } else if (controlData.value.type === "associatedForms") {
      controlData.value.control.fillRoles[0].id = uuidv4().replaceAll("-", "").toString();
    }
    if (val) {
      // 有值时自动跳到第一项
      state.tabsName = "first";
      cssIsShouw(attrList);
    }
  }
);
/**
@ 作者: 秦东
@ 时间: 2024-05-15 11:07:37
@ 功能: 获取组件样式Demo
*/
const controlDataStyls = computed(() => {
  return store.controlAttr.styles;
});
// 返回选项配置提示
const getOptionPlaceholder = (type: number) => {
  switch (type) {
    case 1:
      return "数据源接口URL,可带参数";
    case 2:
      return "字典key，默认为字段标识";
  }
  return "";
};
// 删除一条校验规则
const delAddRules = (index: number) => {
  controlData.value.customRules && controlData.value.customRules.splice(index, 1);
};
//添加一条编码规则
const addNumRules = () => {
  if (!controlData.value.config.customRules) {
    controlData.value.config.customRules = [];
  }
  controlData.value.config.customRules.push({
    type: "time",
    rule: "YYYYMMDD",
  });
};
//删除一条编码规则
const delNumRules = (index: number) => {
  controlData.value.config.customRules &&
    controlData.value.config.customRules.splice(index, 1);
};
// 快速添加校验规则改变时，填写默认的校验提示信息
const rulesSelectChange = (item: any, val: string) => {
  const filter = validate.filter((item) => item.type === val);
  if (filter && filter.length) {
    item.message = filter[0].message;
  }
};
const rulesSelectNumChange = (item: any, val: string) => {
  // console.log("快速添加校验规则改变时",item,val)
  const filter = state.numberRulesList.filter((item) => item.type === val);
  if (filter && filter.length) {
    item.message = filter[0].msg;
    if (val == "time") {
      item.rule = "YYYYMMDD";
    } else {
      item.rule = "";
    }
  }
};

/**
@ 作者: 秦东
@ 时间: 2024-06-22 13:57:55
@ 功能: 判断该输入框是否不可编辑
*/
const disabledIstrue = (val: string) => {
  let ary = ["creater", "creater_time", "edit_time", "owner", "org"];
  if (ary.includes(val)) {
    return true;
  } else {
    return false;
  }
};
</script>
<template>
  <div class="sidebar-tools_e">
    <el-tabs v-model="state.tabsName">
      <el-tab-pane label="字段配置" name="first">
        <el-scrollbar class="formAttributeBox">
          <el-form size="small" class="form">
            <el-divider content-position="left">通用属性</el-divider>
            <template v-for="(item, index) in attrList" :key="index">
              <el-form-item :label="item.label" class="form_cont">
                <el-select
                  v-if="item.type === 'select'"
                  v-model="item.value"
                  :placeholder="item.placeholder"
                  :filterable="item.path === 'name'"
                  :allow-create="item.path === 'name'"
                  :clearable="item.clearable"
                  @change="controlChange(item, $event)"
                >
                  <el-option
                    v-for="(opt, key) in item.dict"
                    :key="key"
                    :value="item.path === 'name' ? opt.name : key"
                    :label="item.path === 'name' ? `${opt.label}(${opt.name})` : opt"
                  />
                </el-select>
                <el-switch
                  v-else-if="item.type === 'switch'"
                  v-model="item.value"
                  @change="controlChange(item, $event)"
                />
                <template v-else-if="item.type === 'digitpage'">
                  <el-row>
                    <el-col :span="12">
                      <el-select
                        v-model="item.selectvalue"
                        :placeholder="item.placeholder"
                        :filterable="item.path === 'name'"
                        :allow-create="item.path === 'name'"
                        :clearable="item.clearable"
                        @change="digitPageSub(item, $event)"
                      >
                        <el-option
                          v-for="(opt, key) in item.dict"
                          :key="key"
                          :value="item.path === 'name' ? opt.name : key"
                          :label="
                            item.path === 'name' ? `${opt.label}(${opt.name})` : opt
                          "
                        />
                      </el-select>
                    </el-col>
                    <el-col :span="12">
                      <el-input-number
                        v-if="item.selectvalue == 'default'"
                        v-model="item.value"
                        class="mx-4"
                      />
                    </el-col>
                  </el-row>
                  <div
                    v-if="item.selectvalue == 'simple'"
                    style="width: 100%; cursor: pointer; margin-top: 10px"
                    @click="openMathDialog(item)"
                    v-html="item.control.mathFormula.formulaHtml"
                  ></div>
                  <MathFormula
                    v-model:show="mathBoxShow"
                    :sub-unit="subUnit"
                    :unit-info="attrList"
                    :form-listmap="formListmap"
                    @updata-digit="updataDigit"
                  />
                </template>
                <el-row v-else-if="item.type === 'uploadvideo_url'">
                  <el-upload
                    :action="uploadUrl"
                    :before-remove="beforeRemove"
                    :on-success="videoUploadOk"
                    :show-file-list="true"
                    :on-error="videoUploadErr"
                    :limit="1"
                    :on-exceed="handleExceed"
                    accept=".mp4,.MOV,.WMV,.FLV,.AVI,.AVCHD,.WebM,.MKV,.rmvb"
                  >
                    <el-button
                      v-if="!controlData.control.videoMsg[videoIndex].videoReady"
                      type="primary"
                      >点此上传</el-button
                    >
                    <el-button
                      v-if="controlData.control.videoMsg[videoIndex].videoReady"
                      type="primary"
                      >已上传,点击修改</el-button
                    >
                  </el-upload>
                </el-row>
                <el-row v-else-if="item.type === 'uploadvideo_autoPlay'">
                  <el-switch
                    v-model="controlData.control.videoMsg[videoIndex].videoAutoPlay"
                  />
                </el-row>
                <el-row v-else-if="item.type === 'uploadvideo_loopPlay'">
                  <el-switch v-model="controlData.control.videoMsg[videoIndex].loop" />
                </el-row>
                <el-row v-else-if="item.type === 'uploadvideo_width'">
                  <el-input-number
                    v-model="controlData.control.videoMsg[videoIndex].videoWidth"
                    :step="50"
                    :max="4096"
                  />
                </el-row>
                <el-row v-else-if="item.type === 'uploadvideo_height'">
                  <el-input-number
                    v-model="controlData.control.videoMsg[videoIndex].videoHeight"
                    :step="50"
                    :max="2160"
                  />
                </el-row>
                <el-row v-else-if="item.type === 'carousel'">
                  <el-button
                    type="primary"
                    append-to-body="true"
                    modal="true"
                    @click="dialogTableVisible = true"
                    >轮播图设置</el-button
                  >
                </el-row>
                <el-row v-else-if="item.type === 'transfer_name'">
                  <el-input
                    v-model="controlData.config.transferName"
                    placeholder="请输入穿梭框名"
                    style="width: 221px"
                  />
                </el-row>
                <el-row v-else-if="item.type === 'transfer_options_datasource'">
                  <el-select
                    v-model="controlData.config.transferDataSource"
                    placeholder="选项数据源"
                    style="width: 150px; height: 20px"
                  >
                    <el-option
                      v-for="dataSourceOption1 in transferDataSourceOptions"
                      :key="dataSourceOption1.value"
                      :label="dataSourceOption1.label"
                      :value="dataSourceOption1.value"
                    />
                  </el-select>
                  <div
                    v-if="controlData.config.transferDataSource === '固定选项'"
                    style="
                      width: auto;
                      margin-top: 33px;
                      margin-left: -220px;
                      padding-bottom: 6px;
                    "
                  >
                    <el-button
                      type="primary"
                      append-to-body="true"
                      modal="true"
                      @click="transferDialogTableVisible = true"
                      >编辑固定选项</el-button
                    >
                  </div>
                  <div
                    v-if="controlData.config.transferDataSource === '数据源'"
                    style="width: auto; margin-top: 20px"
                  >
                    <el-input
                      v-model="controlData.config.apiUrl"
                      style="width: 278px; margin-left: -68px; margin-top: -5px"
                      placeholder="数据源接口url"
                    >
                      <template #prepend>
                        <el-select
                          v-model="controlData.config.method"
                          style="width: 100px"
                        >
                          <el-option label="get" value="get" />
                          <el-option label="post" value="post" />
                        </el-select>
                      </template>
                    </el-input>
                  </div>
                </el-row>
                <el-row v-else-if="item.type === 'lowcodeImage_radius'">
                  <el-switch
                    v-model="controlData.control.radius"
                    style="margin-right: 15px"
                  />
                  <el-popover
                    placement="top-start"
                    :width="200"
                    trigger="hover"
                    content="数值越大圆角程度越高"
                  >
                    <template #reference>
                      <el-input-number
                        v-if="controlData.control.radius"
                        v-model="controlData.control.radiusNum"
                        :step="1"
                      />
                    </template>
                  </el-popover>
                </el-row>
                <el-row v-else-if="item.type === 'lowcodeImage_url'">
                  <el-upload
                    :action="uploadUrl"
                    :before-remove="beforeRemove"
                    :on-success="lowcodeImageUploadSuccess"
                    :on-error="videoUploadErr"
                    :limit="1"
                    accept=".jpg,.jpeg,.png,.tif,.tga,.bmp,.dds,.svg,.eps,.pdf,.hdr,.raw,.exr,.psd,.afphoto,.afdesign"
                  >
                    <el-button v-if="!controlData.control.uploadFlag" type="primary"
                      >点此上传</el-button
                    >
                    <el-button v-if="controlData.control.uploadFlag" type="primary"
                      >已上传,点击修改</el-button
                    >
                  </el-upload>
                </el-row>
                <el-row v-else-if="item.type === 'lowcodeImage_showMode'">
                  <el-select
                    v-model="controlData.control.showMode"
                    placeholder="选项数据源"
                    style="width: 150px; height: 20px"
                  >
                    <el-option
                      v-for="showModeSelected in showModeSelectOptions"
                      :key="showModeSelected.value"
                      :label="showModeSelected.label"
                      :value="showModeSelected.value"
                    />
                  </el-select>
                  <div
                    v-if="controlData.control.showMode === '自定义像素值'"
                    style="
                      width: auto;
                      margin-top: 33px;
                      margin-left: -187px;
                      padding-bottom: 6px;
                    "
                  >
                    <span style="margin-right: 10px">宽度(像素) </span
                    ><el-input-number
                      v-model="controlData.control.pxWidth"
                      style="margin-bottom: 10px"
                    /><br />
                    <span style="margin-right: 10px">高度(像素) </span
                    ><el-input-number v-model="controlData.control.pxHeight" />
                  </div>
                  <div
                    v-if="controlData.control.showMode === '自定义占父容器比例'"
                    style="
                      width: auto;
                      margin-top: 33px;
                      margin-left: -187px;
                      padding-bottom: 6px;
                    "
                  >
                    <span style="margin-right: 10px">百分比宽 </span
                    ><el-input-number
                      v-model="controlData.control.widthPercent"
                      style="margin-bottom: 10px"
                    /><br />
                    <span style="margin-right: 10px">百分比高 </span
                    ><el-input-number v-model="controlData.control.heightPercent" />
                  </div>
                </el-row>
                <el-row v-else-if="item.type === 'lowcodeImage_fit'">
                  <el-radio-group v-model="controlData.control.fit">
                    <el-popover
                      placement="top-start"
                      title="填充"
                      :width="200"
                      trigger="hover"
                      content="默认值。调整替换后的内容大小，以填充元素的内容框。如有必要，将拉伸或挤压物体以适应该对象。"
                    >
                      <template #reference>
                        <el-radio :label="1" :value="1">填充</el-radio
                        ><!-- fill -->
                      </template>
                    </el-popover>

                    <el-popover
                      placement="top-start"
                      title="适应"
                      :width="200"
                      trigger="hover"
                      content="缩放替换后的内容以保持其纵横比，同时将其放入元素的内容框。"
                    >
                      <template #reference>
                        <el-radio :label="2" :value="2">适应</el-radio
                        ><!-- contain -->
                      </template>
                    </el-popover>

                    <el-popover
                      placement="top-start"
                      title="裁切"
                      :width="200"
                      trigger="hover"
                      content="调整替换内容的大小，以在填充元素的整个内容框时保持其长宽比。该对象将被裁剪以适应。"
                    >
                      <template #reference>
                        <el-radio :label="3" :value="3">裁切</el-radio
                        ><!-- cover -->
                      </template>
                    </el-popover>

                    <el-popover
                      placement="top-start"
                      title="无"
                      :width="200"
                      trigger="hover"
                      content="不对替换的内容调整大小。"
                    >
                      <template #reference>
                        <el-radio :label="4" :value="4">无</el-radio
                        ><!-- none -->
                      </template>
                    </el-popover>

                    <el-popover
                      placement="top-start"
                      title="缩减"
                      :width="200"
                      trigger="hover"
                      content="调整内容大小就像没有指定内容或包含内容一样（将导致较小的具体对象尺寸）"
                    >
                      <template #reference>
                        <el-radio :label="5" :value="5">缩减</el-radio
                        ><!-- scale-down -->
                      </template>
                    </el-popover>
                  </el-radio-group>
                </el-row>
                <el-row v-else-if="item.type === 'lowcodeImage_boderAndShadow'">
                  <el-switch
                    v-model="controlData.control.boderAndShadow"
                    style="margin-right: 15px"
                  />
                </el-row>
                <el-row v-else-if="item.type === 'lowcodeImage_link'">
                  <el-input
                    v-model="controlData.control.link"
                    placeholder="请录入图片链接地址"
                    style="width: 221px"
                  />
                </el-row>
                <el-row v-else-if="item.type === 'lowcodeImage_marginAndPadding'">
                  <div
                    style="
                      width: auto;
                      margin-top: 33px;
                      margin-left: -47px;
                      padding-bottom: 6px;
                    "
                  >
                    <span style="margin-right: 10px"> 外边距(上)</span
                    ><el-input-number
                      v-model="controlData.control.mt"
                      style="margin-bottom: 10px"
                    /><br />
                    <span style="margin-right: 10px"> 外边距(下)</span
                    ><el-input-number
                      v-model="controlData.control.mb"
                      style="margin-bottom: 10px"
                    /><br />
                    <span style="margin-right: 10px"> 外边距(左)</span
                    ><el-input-number
                      v-model="controlData.control.ml"
                      style="margin-bottom: 10px"
                    /><br />
                    <span style="margin-right: 10px"> 外边距(右)</span
                    ><el-input-number
                      v-model="controlData.control.mr"
                      style="margin-bottom: 10px"
                    /><br />
                    <span style="margin-right: 10px"> 内边距(上)</span
                    ><el-input-number
                      v-model="controlData.control.pt"
                      style="margin-bottom: 10px"
                    /><br />
                    <span style="margin-right: 10px"> 内边距(下)</span
                    ><el-input-number
                      v-model="controlData.control.pb"
                      style="margin-bottom: 10px"
                    /><br />
                    <span style="margin-right: 10px"> 内边距(左)</span
                    ><el-input-number
                      v-model="controlData.control.pl"
                      style="margin-bottom: 10px"
                    /><br />
                    <span style="margin-right: 10px"> 内边距(右)</span
                    ><el-input-number
                      v-model="controlData.control.pr"
                      style="margin-bottom: 10px"
                    /><br />
                  </div>
                </el-row>
                <el-row v-else-if="item.type === 'lowcodeImage_float'">
                  <el-switch
                    v-model="controlData.control.floatFlag"
                    style="margin-right: 15px"
                  />
                  <el-select
                    v-if="controlData.control.floatFlag"
                    v-model="controlData.control.floatValue"
                    style="width: 150px; height: 20px"
                  >
                    <el-option
                      v-for="showModeSelected1 in floatSelectOptions"
                      :key="showModeSelected1.value"
                      :label="showModeSelected1.label"
                      :value="showModeSelected1.value"
                    />
                  </el-select>
                </el-row>
                <el-row v-else-if="item.type === 'associatedForms_hide'">
                  <el-button
                    v-if="controlData.control.hideConditionHtml === ''"
                    style="padding-top: 5px"
                    type="primary"
                    link
                    append-to-body="true"
                    modal="true"
                    @click="associatedFormsHideDialoghandle"
                    >设置隐藏条件</el-button
                  >
                  <div
                    style="width: 100%; cursor: pointer"
                    @click="associatedFormsHideDialoghandle"
                    v-html="controlData.control.hideConditionHtml"
                  ></div>
                </el-row>
                <el-row v-else-if="item.type === 'associatedForms_form'">
                  <div style="margin-top: 25px; margin-left: -60px">
                    <el-tree-select
                      v-model="controlData.control.formid"
                      style="width: 260px"
                      :data="customerFormTree[0].children"
                      check-strictly
                      :render-after-expand="false"
                      filterable
                      @change="formidChanged"
                    />
                  </div>
                  <!-- <div v-html="controlData.control.formid"></div> -->
                </el-row>

                <el-row v-else-if="item.type === 'associatedForms_dataRange'">
                  <el-button
                    v-if="controlData.control.dataRangeConditionHtml === ''"
                    style="padding-top: 5px"
                    type="primary"
                    link
                    append-to-body="true"
                    modal="true"
                    @click="associatedFormsDataRangeDialoghandle"
                    >设置数据范围</el-button
                  >
                  <div
                    style="width: 100%; cursor: pointer"
                    @click="associatedFormsDataRangeDialoghandle"
                    v-html="controlData.control.dataRangeConditionHtml"
                  ></div>
                </el-row>

                <el-row v-else-if="item.type === 'associatedForms_FillRoles'">
                  <el-button
                    style="padding-top: 5px"
                    type="primary"
                    link
                    append-to-body="true"
                    modal="true"
                    @click="associatedFormsDataFillRolesDialoghandle"
                    >设置数据填充规则</el-button
                  >
                </el-row>
                <el-input
                  v-else
                  v-model="item.value"
                  :type="item.inputStyle"
                  :placeholder="item.placeholder"
                  :disabled="isNotWriteWord(item)"
                  @input="controlChange(item, $event)"
                />
              </el-form-item>
            </template>
            <template v-if="controlData.config">
              <!-- <el-form-item label="联动条件"  class="form_cont">
                                <el-switch v-model="controlData.config.linkKey" />
                            </el-form-item> -->
              <template v-if="controlData.config.linkKey">
                <el-form-item class="form_cont">
                  <el-input
                    v-model="controlData.config.linkValue"
                    type="textarea"
                    placeholder="表达式如: $.input>1 $表示为当前表单数据，input为字段标识"
                  />
                </el-form-item>
                <el-form-item
                  v-if="
                    showHide(
                      [
                        'input',
                        'textarea',
                        'radio',
                        'checkbox',
                        'select',
                        'date',
                        'switch',
                        'number',
                        'cascader',
                        'slider',
                        'datePicker',
                        'timePicker',
                        'colorPicker',
                        'inputNumber',
                        'rate',
                        'treeSelect',
                      ],
                      true
                    )
                  "
                  class="form_cont"
                  label="联动结果"
                >
                  <el-radio-group
                    v-model="controlData.config.linkResult"
                    class="option-radio"
                  >
                    <el-radio label="hidden">隐藏(默认)</el-radio>
                    <el-radio label="disabled">禁用</el-radio>
                  </el-radio-group>
                </el-form-item>
              </template>
            </template>
            <template v-if="showHide(['tabs'], true)">
              <!-- <div class="h3"><h3>标签配置项</h3></div> -->
              <el-divider content-position="left">标签配置项</el-divider>
              <el-form-item
                v-for="(item, index) in controlData.columns"
                :key="index"
                class="form_cont"
              >
                <el-col :span="12">
                  <el-input v-model="item.label" placeholder="标签配置项" />
                </el-col>
                <el-col :span="2" :offset="1">
                  <i
                    class="icon-del"
                    @click="delSelectOption(index as number, 'tabs')"
                  ></i>
                </el-col>
              </el-form-item>
              <el-form-item class="form_cont">
                <el-button @click="addSelectOption('tabs')">增加标签</el-button>
              </el-form-item>
            </template>
            <!--编号规则设置--->
            <div v-if="showHide(['serialNumber'], true)">
              <el-divider content-position="left">编码规则配置</el-divider>
              <el-form-item label="编码方式" class="form_cont">
                <el-switch
                  v-model="controlData.config.automatic"
                  inline-prompt
                  active-text="自动编码"
                  inactive-text="手动编码"
                  style="--el-switch-on-color: #13ce66; --el-switch-off-color: #e6a23c"
                />
              </el-form-item>
              <div v-if="controlData.config.automatic">
                <el-form-item
                  v-for="(item, index) in controlData.config.customRules"
                  :key="index"
                  class="form_cont"
                >
                  <el-input
                    v-model="item.rule"
                    :placeholder="item.message ? item.message : '请输入自定义字符'"
                  >
                    <template #prepend>
                      <el-select
                        v-model="item.type"
                        style="width: 100px"
                        @change="rulesSelectNumChange(item, $event)"
                      >
                        <el-option
                          v-for="list in state.numberRulesList"
                          :key="list.type"
                          :label="list.label"
                          :value="list.type"
                        />
                      </el-select>
                    </template>
                    <template #append>
                      <i class="icon-del" @click="delNumRules(index as number)"></i>
                    </template>
                  </el-input>
                </el-form-item>
                <el-form-item class="form_cont">
                  <el-button @click="addNumRules">添加规则</el-button>
                </el-form-item>
              </div>
            </div>
            <div
              v-if="
                showHide(
                  ['radio', 'select', 'checkbox', 'cascader', 'inputSlot', 'treeSelect'],
                  true
                )
              "
            >
              <el-divider content-position="left">选项配置</el-divider>
              <el-form-item
                v-if="showHide(['select'], true)"
                label="添加全部项"
                class="form_cont"
              >
                <el-input
                  v-model="controlData.config.addAll"
                  placeholder="请输入全部项文案"
                />
              </el-form-item>
              <el-form-item label="选项数据源" class="form_cont">
                <el-select
                  v-model="controlData.config.optionsType"
                  @change="controlData.config.optionsFun = ''"
                >
                  <el-option :value="0" label="固定选项" />
                  <el-option :value="1" label="数据源" />
                  <el-option :value="2" label="接口字典" />
                </el-select>
              </el-form-item>
              <template v-if="controlData.config.optionsType === 0">
                <div v-if="controlData.type !== 'cascader'">
                  <el-form-item
                    v-for="(item, index) in controlData.options"
                    :key="index"
                    class="form_cont"
                  >
                    <el-col :span="10">
                      <el-input v-model="item.label" placeholder="选项标签" />
                    </el-col>
                    <el-col :span="10" :offset="1">
                      <el-input v-model="item.value" placeholder="选项值" />
                    </el-col>
                    <el-col :span="2" :offset="1">
                      <i class="icon-del" @click="delSelectOption(index as number)"></i>
                    </el-col>
                  </el-form-item>
                </div>
                <el-form-item class="form_cont">
                  <el-button @click="addSelectOption">{{
                    controlData.type === "cascader" ? "编辑" : "新增"
                  }}</el-button>
                </el-form-item>
              </template>
              <template v-else>
                <el-form-item class="form_cont">
                  <el-input
                    v-model="controlData.config.optionsFun"
                    :placeholder="getOptionPlaceholder(controlData.config.optionsType)"
                  >
                    <template v-if="controlData.config.optionsType === 1" #prepend>
                      <el-select v-model="controlData.config.method" style="width: 80px">
                        <el-option label="get" value="get" />
                        <el-option label="post" value="post" />
                      </el-select>
                    </template>
                  </el-input>
                </el-form-item>
                <template v-if="controlData.config.optionsType === 1">
                  <el-form-item label="指定label属性值" class="form_cont">
                    <el-input
                      v-model="controlData.config.label"
                      placeholder="返回数据中没有label时可设置"
                    />
                  </el-form-item>
                  <el-form-item label="指定value属性值" class="form_cont">
                    <el-input
                      v-model="controlData.config.value"
                      placeholder="返回数据中没有value时可设置"
                    />
                  </el-form-item>
                </template>
                <el-form-item
                  v-if="controlData.config.optionsType === 1"
                  class="form_cont"
                >
                  <el-button
                    @click="
                      optionsEvent(
                        'optionsParams',
                        '请求前处理事件，参数(data,route,form) data请求参数,route页面路由,form表单值'
                      )
                    "
                    >beforeRequest</el-button
                  >
                  <el-button
                    @click="
                      optionsEvent(
                        'optionsResult',
                        '请求返回结束处理；，也可为字符串，如opt=formatTest'
                      )
                    "
                    >afterResponse</el-button
                  >
                </el-form-item>
              </template>
              <el-form-item label="尝试转换value值为" class="form_cont">
                <el-select
                  v-model="controlData.config.transformData"
                  placeholder="默认为number"
                >
                  <el-option value="none">不转换</el-option>
                  <el-option value="number">number</el-option>
                  <el-option value="string">string</el-option>
                </el-select>
              </el-form-item>
            </div>
            <template
              v-if="
                !state.isSearch &&
                showHide([
                  'txt',
                  'title',
                  'table',
                  'grid',
                  'tabs',
                  'card',
                  'switch',
                  'gridChild',
                  'tableColumn',
                  'divider',
                  'div',
                  'button',
                ])
              "
            >
              <el-divider content-position="left">校验设置</el-divider>
              <div v-if="showHide(['input', 'password', 'component'], true)">
                <el-form-item
                  v-for="(item, index) in controlData.customRules"
                  :key="item.type"
                  class="form_cont"
                >
                  <el-input v-model="item.message" placeholder="校验提示信息">
                    <template #prepend>
                      <el-select
                        v-model="item.type"
                        style="width: 80px"
                        @change="rulesSelectChange(item, $event)"
                      >
                        <el-option
                          v-for="list in state.customRulesList"
                          :key="list.type"
                          :label="list.label"
                          :value="list.type"
                        />
                      </el-select>
                    </template>
                    <template #append>
                      <i class="icon-del" @click="delAddRules(index as number)"></i>
                    </template>
                  </el-input>
                  <el-input
                    v-if="item.type === 'rules'"
                    v-model="item.rules"
                    placeholder="正则表达式"
                  />
                  <el-input
                    v-if="item.type === 'methods'"
                    v-model="item.methods"
                    placeholder="方法名称，此方法仅适用于导出vue文件"
                  />
                </el-form-item>
                <el-form-item class="form_cont">
                  <el-button @click="addRulesFast">快速添加</el-button>
                  <el-button @click="addRules(state.tooltip.rules)"
                    >编写校验规则
                    <el-tooltip
                      :content="state.tooltip.rules"
                      placement="top"
                      raw-content
                    >
                      <el-icon>
                        <QuestionFilled />
                      </el-icon>
                    </el-tooltip>
                  </el-button>
                </el-form-item>
              </div>
              <el-form-item v-else class="form_cont">
                <el-checkbox :model-value="checkboxRequired" @change="requiredChange"
                  >必填
                </el-checkbox>
                <el-input
                  v-if="controlData.item?.rules && controlData.item?.rules[0]"
                  v-model="controlData.item.rules[0].message"
                  placeholder="自定义必填错误提示"
                />
              </el-form-item>
            </template>
            <!-- <el-divider content-position="left">其他属性</el-divider>
						<div v-if="showHide(['grid', 'card', 'gridChild', 'divider', 'div'])"  class="form_cont">
                            
    
                            <el-button
                            size="small"
                            @click="openAttrDialog('', state.tooltip.props)"
                            >编辑属性
                            <el-tooltip :content="state.tooltip.props" placement="top">
                                <el-icon>
                                <QuestionFilled />
                                </el-icon>
                            </el-tooltip>
                            </el-button>
                        </div> -->
            <el-divider content-position="left">高级属性</el-divider>

            <LayoutPage
              v-if="cssIsShouw(attrList)"
              v-model:styles-val="controlDataStyls"
              :place="controlData.type"
            />
          </el-form>
        </el-scrollbar>
      </el-tab-pane>
      <el-tab-pane label="表单配置" name="second">
        <el-scrollbar class="formAttributeBox">
          <el-form size="small" class="form">
            <el-divider content-position="left">基础配置</el-divider>
            <el-form-item class="form_cont">
              <template #label> 归属分组 </template>
              <el-select
                id="groupForm"
                ref="groupForm"
                v-model="formConfig.groupKey"
                placeholder="Select"
              >
                <el-option
                  v-for="item in formGroup.list"
                  :key="item.idStr"
                  :label="item.title"
                  :value="item.idStr"
                />
                <p v-if="loadingmore">加载中</p>
                <p v-if="loadingnomore">无数据</p>
              </el-select>
            </el-form-item>
            <el-form-item
              v-for="(item, index) in formControlProject.filter((item) => !item.hide)"
              :key="index"
              :label="item.label"
              class="form_cont"
            >
              <el-select
                v-if="item.type === 'select'"
                v-model="item.value"
                :filterable="item.key === 'class'"
                :allow-create="item.key === 'class'"
                :placeholder="item.placeholder"
                :clearable="item.clearable"
                @change="formAttrChange(item)"
              >
                <el-option
                  v-for="opt in item.options"
                  :key="opt.label || opt.name"
                  :label="opt.label || opt.name"
                  :value="formatNumber(opt.value ?? opt.id)"
                />
              </el-select>
              <el-switch
                v-else-if="item.type === 'switch'"
                v-model="item.value"
                @input="formAttrChange(item)"
              />
              <el-input
                v-else
                v-model="item.value"
                :placeholder="item.placeholder"
                :disabled="isNotWrite(item)"
                @input="formAttrChange(item)"
              />
            </el-form-item>
            <el-form-item class="form_cont">
              <template #label> 表单图标 </template>
              <el-upload
                class="avatar-uploader"
                :action="imgUploadApiUrl"
                :show-file-list="false"
                :on-success="handleAvatarSuccess"
                :before-upload="beforeAvatarUpload"
              >
                <img
                  v-if="formConfig.imageUrl"
                  :src="formConfig.imageUrl"
                  class="avatar"
                />
                <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
              </el-upload>
            </el-form-item>
            <template v-if="!state.isSearch">
              <el-divider content-position="left">接口数据事件</el-divider>
              <el-form-item v-if="!state.isSearch" class="form_cont">
                <template #label>
                  添加时获取请求
                  <el-tooltip
                    content="新增表单数据时，从接口获取新增初始数据"
                    placement="top"
                  >
                    <el-icon><QuestionFilled /></el-icon>
                  </el-tooltip>
                </template>
                <el-switch
                  v-model="formConfig.addLoad"
                  @change="formAttrChange({ key: 'addLoad', path: 'config' }, $event)"
                />
              </el-form-item>
              <el-form-item label="新增数据保存url" class="form_cont">
                <el-input
                  v-model="formConfig.addUrl"
                  placeholder="表单提交的url，非特殊不需要设置"
                />
              </el-form-item>
              <el-form-item label="修改数据保存url" class="form_cont">
                <el-input
                  v-model="formConfig.editUrl"
                  placeholder="修改提交的url，非特殊不需要设置"
                />
              </el-form-item>
              <el-form-item label="获取表单数据url" class="form_cont">
                <el-input
                  v-model="formConfig.requestUrl"
                  placeholder="获取表单数据url，非特殊不需要设置"
                />
              </el-form-item>
              <el-form-item class="event-btn form_cont">
                <el-button
                  @click="
                    eventClick('beforeRequest', '获取表单初始数据前事件，可修改请求参数')
                  "
                >
                  beforeRequest
                </el-button>
                <el-button
                  @click="
                    eventClick(
                      'afterResponse',
                      '获取表单初始数据后事件，可对请求返回数据进行处理；也可为字符串，如opt=formatTest'
                    )
                  "
                  >afterResponse
                </el-button>
                <el-button
                  @click="
                    eventClick(
                      'beforeSubmit',
                      '表单数据提交前事件，可对提交数据进行处理；也可为字符串，如opt=formatTest'
                    )
                  "
                  >beforeSubmit
                </el-button>
                <el-button @click="eventClick('afterSubmit', '表单数据提交成功事件')"
                  >afterSubmit
                </el-button>
                <el-button
                  @click="
                    eventClick(
                      'change',
                      '表单组件值改变事件。当表单某值改变时，可修改其他组件的值；也可为字符串，如opt=formChange,字符串即为/utils/formChangeValue(name,model,key)中的key值'
                    )
                  "
                  >表单组件改变事件change
                </el-button>
              </el-form-item>
            </template>
            <el-divider content-position="left">表单整体布局</el-divider>
            <el-form-item label="组件尺寸" class="form_cont">
              <el-radio-group v-model="formData.size">
                <el-radio-button label="large">大</el-radio-button>
                <el-radio-button label="default">适中</el-radio-button>
                <el-radio-button label="small">小</el-radio-button>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="表单样式名称" class="form_cont">
              <el-select
                v-model="formData.class"
                class="m-2"
                placeholder="额外添加的表单class类名"
              >
                <el-option
                  v-for="item in optionsCss"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
            </el-form-item>
            <el-form-item label="行内表单模式" class="form_cont">
              <el-switch
                v-model="formData.inline"
                active-text="开启"
                inactive-text="关闭"
              />
            </el-form-item>
            <el-form-item label="标签宽度" class="form_cont">
              <el-input
                v-model="formData.labelWidth"
                clearable
                placeholder="表单标签宽度"
              >
                <template #suffix>PX</template>
              </el-input>
            </el-form-item>
            <el-form-item label="标签后缀" class="form_cont">
              <el-input v-model="formData.labelSuffix" placeholder="表单标签后缀" />
            </el-form-item>
            <el-form-item label="表单标签对齐方式" class="form_cont">
              <el-radio-group v-model="formData.labelPosition">
                <el-radio-button label="left">左</el-radio-button>
                <el-radio-button label="right">右</el-radio-button>
                <el-radio-button label="top">上</el-radio-button>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="必填项星号位置" class="form_cont">
              <el-radio-group v-model="formData.requireAsteriskPosition">
                <el-radio-button label="left">左</el-radio-button>
                <el-radio-button label="right">右</el-radio-button>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="是否隐藏星号" class="form_cont">
              <el-switch
                v-model="formData.hideRequiredAsterisk"
                active-text="隐藏"
                inactive-text="显示"
                style="--el-switch-on-color: #ff4949; --el-switch-off-color: #13ce66"
              />
            </el-form-item>
            <el-form-item label="校验错误信息" class="form_cont">
              <el-switch
                v-model="formData.showMessage"
                active-text="显示"
                inactive-text="隐藏"
              />
            </el-form-item>
            <el-form-item label="以行内形式展示校验信息" class="form_cont">
              <el-switch
                v-model="formData.inlineMessage"
                active-text="显示"
                inactive-text="隐藏"
              />
            </el-form-item>
            <el-form-item label="是否显示校验结果反馈图标" class="form_cont">
              <el-switch
                v-model="formData.statusIcon"
                active-text="显示"
                inactive-text="隐藏"
              />
            </el-form-item>
            <el-divider content-position="left">表单功能补充</el-divider>
            <el-form-item class="form_cont">
              <el-button @click="editFormStyle(state.tooltip.css)">
                编辑表单样式
                <el-tooltip :content="state.tooltip.css" placement="top">
                  <el-icon>
                    <QuestionFilled />
                  </el-icon>
                </el-tooltip>
              </el-button>
              <el-button @click="editFormDict(state.tooltip.dict)">
                设置数据字典
                <el-tooltip :content="state.tooltip.dict" placement="top">
                  <el-icon>
                    <QuestionFilled />
                  </el-icon>
                </el-tooltip>
              </el-button>
            </el-form-item>
          </el-form>
        </el-scrollbar>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>
<style lang="scss" scoped>
.formAttributeBox {
  height: calc(100vh - 105px);
}
li::before {
  content: "";
  display: inline-block;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background-color: gray;
  margin-right: 5px;
  margin-left: 5px;
  margin-bottom: 3.5px;
}

.sidebar-tools_e .el-tabs__content {
  padding: 0;
}
.el-collapse-item__header {
  padding-left: 10px;
  background-color: rgb(229, 229, 229);
}
.el-collapse-item__header {
  padding-left: 10px;
  background-color: rgb(229, 229, 229);
}

.form_cont {
  padding: 0 10px;
}
.avatar-uploader {
  width: 100px;
  height: 100px;
  .avatar {
    width: 100px;
    height: 100px;
  }
  .avatar-uploader-icon {
    width: 100px;
    height: 100px;
  }
}
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
.custom-tree-node:hover {
  background-color: antiquewhite;
}

.associatedFormsHideDialogMain7 {
  display: flex;
}
.el-main {
  --el-main-padding: 5px;
}
</style>
