<template>
  <div class="awc-containter">
    <a-form v-bind="layout" v-if="data" :key="data.key" size="small">
      <a-form-item
        :label="t('不存表')"
        v-if="data.type == 'input' && hasKey('isSave') && designType !== 'notable'"
      >
        <a-switch v-model:checked="data.options.isSave" @change="handleIsSave" />
      </a-form-item>
      <template v-if="designType === 'data'">
        <a-form-item
          :label="t('绑定表')"
          v-if="
            (data.type == 'input' && !data.options.isSave) ||
            (!noHaveTableAndField.includes(data.type) &&
              (!data.isSubFormChild || data.type === 'sun-form') &&
              !data.isSingleFormChild &&
              data.type !== 'input')
          "
        >
          <a-select
            @change="handleTableChange"
            v-model:value="data.bindTable"
            size="mini"
            :placeholder="t('请选择数据表')"
            allowClear
          >
            <a-select-option
              v-for="(table, idx) in tableInfo"
              :disabled="table.disabled"
              :value="table.name"
              :key="idx"
            >
              <a-tooltip>
                <template #title>
                  {{ table.name }}
                  <a-tag :color="table.isMain ? 'blue' : table.isSubForm ? 'orange' : 'green'">
                    {{ table.isMain ? t('主表') : table.isSubForm ? t('附表') : '次表' }}
                  </a-tag>
                </template>
                {{ table.name }}
                <span>
                  <a-tag :color="table.isMain ? 'blue' : table.isSubForm ? 'orange' : 'green'">
                    {{ table.isMain ? t('主表') : table.isSubForm ? t('附表') : '次表' }}
                  </a-tag>
                </span>
              </a-tooltip>
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item :label="t('关联字段')" v-if="data.type === 'sun-form'">
          <a-select
            v-model:value="data.relationField"
            size="mini"
            :placeholder="t('请选择关联字段')"
            showSearch
            @change="handleRelationChange"
          >
            <a-select-option v-for="(field, idx) in relationOptions" :value="field.name" :key="idx">
              <a-tooltip>
                <template #title>
                  {{ field.name }}
                  <a-tag color="blue">
                    {{ getFieldType(field.type) }}
                  </a-tag>
                </template>
                {{ field.name }}
                <span>
                  <a-tag color="blue">
                    {{ getFieldType(field.type) }}
                  </a-tag>
                </span>
              </a-tooltip>
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item :label="t('关联表字段')" v-if="data.type === 'sun-form'">
          <a-select
            v-model:value="data.relationTableField"
            size="mini"
            :placeholder="t('请选择表关联字段')"
            showSearch
            @change="handleRelationTableChange"
          >
            <a-select-option
              v-for="(field, idx) in relationTableOptions"
              :value="field.name"
              :key="idx"
            >
              <a-tooltip>
                <template #title>
                  {{ field.name }}
                  <a-tag color="blue">
                    {{ getFieldType(field.type) }}
                  </a-tag>
                </template>
                {{ field.name }}
                <span>
                  <a-tag color="blue">
                    {{ getFieldType(field.type) }}
                  </a-tag>
                </span>
              </a-tooltip>
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item
          :label="t('绑定字段')"
          v-if="
            (data.type == 'input' && !data.options.isSave) ||
            (!noHaveField.includes(data.type) && data.type !== 'input')
          "
        >
          <a-select
            v-model:value="data.bindField"
            size="mini"
            :placeholder="t('请选择表字段')"
            showSearch
            @change="handleFieldChange"
          >
            <a-select-option
              v-for="(field, idx) in changedFieldsInfo"
              :value="field.name"
              :key="idx"
              :length="field.length"
            >
              <a-tooltip>
                <template #title>
                  {{ field.name }}
                  <a-tag color="blue">
                    {{ getFieldType(field.type) }}
                  </a-tag>
                </template>
                <span class="mr-2">{{ field.name }}</span>
                <a-tag color="blue">
                  {{ getFieldType(field.type) }}
                </a-tag>
              </a-tooltip>
            </a-select-option>
          </a-select>
        </a-form-item>
      </template>

      <template v-if="data.type === 'form' || data.type === 'form-view'">
        <a-form-item :label="t('预加载数据')">
          <a-radio-group
            button-style="solid"
            v-model:value="data.options.preloadType"
            size="small"
            @change="preloadChange"
          >
            <a-radio-button value="api">API</a-radio-button>
            <a-radio-button value="dic">{{ t('数据字典') }}</a-radio-button>
          </a-radio-group>
        </a-form-item>

        <a-form-item :label="t('接口配置')" v-if="data.options.preloadType === 'api'">
          <a-input
            v-model:value="data.options.apiConfig.path"
            :placeholder="t('点击进行接口配置')"
            @click="showApiConfig()"
          >
            <template #suffix>
              <Icon icon="ant-design:ellipsis-outlined" />
            </template>
          </a-input>
        </a-form-item>

        <a-form-item :label="t('数据选项')" v-if="data.options.preloadType === 'dic'">
          <DicTreeSelect v-model:value="data.options.itemId" @change="handleDicChange" />
        </a-form-item>

        <a-form-item :label="t('按钮选数据')" v-if="data.type === 'form'">
          <a-switch v-model:checked="data.options.useSelectButton" />
        </a-form-item>
        <a-form-item :label="t('是否分页')" v-if="data.type === 'form'">
          <a-switch v-model:checked="data.options.showPagenation" />
        </a-form-item>
        <template v-if="data.options.useSelectButton">
          <a-form-item :label="t('按钮名称')">
            <a-input v-model:value="data.options.buttonName" :placeholder="t('请填写按钮名称')" />
          </a-form-item>

          <a-form-item :label="t('表头配置')">
            <a-input
              :value="configText"
              :placeholder="t('点击进行表头配置')"
              @click="tableTitleClick"
            >
              <template #suffix>
                <Icon icon="ant-design:ellipsis-outlined" />
              </template>
            </a-input>
          </a-form-item>
        </template>

        <template v-if="data.options.preloadType && data.type === 'form'">
          <a-form-item
            :label="item.label"
            v-for="item in data.children.filter((x) => !unPreloadComponents.includes(x.type))"
            :key="item.key"
          >
            <a-input
              v-if="data.options.preloadType === 'api'"
              v-model:value="item.options.prestrainField"
              :placeholder="t('请填写接口出参字段')"
            />
            <a-select
              v-else-if="data.options.preloadType === 'dic'"
              v-model:value="item.options.prestrainField"
            >
              <a-select-option value="name">name</a-select-option>
              <a-select-option value="value">value</a-select-option>
            </a-select>
          </a-form-item>
        </template>
      </template>
      <template v-if="data.type === 'form' || data.type === 'sun-form'">
        <a-form-item :label="t('行合并配置')">
          <a-select
            v-model:value="data.options.rowSpan"
            :placeholder="t('请选择需要行合并的列')"
            allowClear
            :disabled="hasSunform(data.children)"
          >
            <a-select-option
              v-for="(item, index) in data.children"
              :key="index"
              :value="item.bindField"
              >{{ item.label }}</a-select-option
            >
          </a-select>
        </a-form-item>
      </template>
      <template v-if="data.type === 'form-view'">
        <a-form-item :label="t('行合并配置')">
          <a-select
            v-model:value="data.options.rowSpan"
            :placeholder="t('请选择需要行合并的列')"
            allowClear
          >
            <a-select-option
              v-for="(item, index) in data.tableColumns"
              :key="index"
              :value="item"
              >{{ item }}</a-select-option
            >
          </a-select>
        </a-form-item>
      </template>
      <template
        v-if="data.type === 'form' || data.type === 'sun-form' || data.type === 'form-view'"
      >
        <a-form-item :label="t('列宽配置')">
          <a-input
            :value="data.options.widths?.length > 0 ? t('已配置') : ''"
            :placeholder="t('点击进行列宽配置')"
            @click="showWidthConfig()"
          >
            <template #suffix>
              <Icon icon="ant-design:ellipsis-outlined" />
            </template>
          </a-input>
        </a-form-item>
        <a-form-item :label="t('行高可拖拽')">
          <a-switch v-model:checked="data.options.rowResize" />
        </a-form-item>
      </template>
      <template
        v-if="
          data.type === 'multiple-popup' ||
          data.type === 'associate-popup' ||
          data.type === 'associate-select' ||
          data.type === 'select' ||
          data.type === 'checkbox' ||
          data.type === 'auto-complete' ||
          data.type === 'radio'
        "
      >
        <DataSourceSetting v-model:data="data" @handle-options-remove="handleOptionsRemove" />
      </template>
      <a-form-item v-if="hasKey('pageSize')" :label="t('每页显示条数')">
        <a-input-number v-model:value.number="data.options.pageSize" />
      </a-form-item>
      <a-form-item v-if="hasKey('assoTitle')" :label="t('弹窗标题')">
        <a-input v-model:value="data.options.assoTitle" />
      </a-form-item>

      <a-form-item v-if="hasKey('showTime') && designType === 'data'" :label="t('开始字段')">
        <a-select v-model:value="data.bindStartTime" size="mini" :placeholder="t('请选择开始字段')">
          <a-select-option v-for="(field, idx) in changedFieldsInfo" :value="field.name" :key="idx">
            {{ field.name }}
            <span>
              <a-tag color="blue">
                {{ getFieldType(field.type) }}
              </a-tag>
            </span>
          </a-select-option>
        </a-select>
      </a-form-item>

      <a-form-item v-if="hasKey('showTime') && designType === 'data'" :label="t('结束字段')">
        <a-select v-model:value="data.bindEndTime" size="mini" :placeholder="t('请选择结束字段')">
          <a-select-option v-for="(field, idx) in changedFieldsInfo" :value="field.name" :key="idx">
            {{ field.name }}
            <span>
              <a-tag color="blue">
                {{ getFieldType(field.type) }}
              </a-tag>
            </span>
          </a-select-option>
        </a-select>
      </a-form-item>
      <a-form-item :label="t('级联配置')" v-if="data.type === 'cascader'" required>
        <a-input
          v-model:value="data.options.apiConfig.path"
          :placeholder="t('点击进行级联配置')"
          @click="showApiConfig(true)"
        >
          <template #suffix>
            <Icon icon="ant-design:ellipsis-outlined" />
          </template>
        </a-input>
      </a-form-item>
      <a-form-item v-if="hasKey('showFormat')" :label="t('显示格式')">
        <a-select v-model:value="data.options.showFormat" :options="formatOptions" />
      </a-form-item>
      <a-form-item v-if="hasKey('separator')" :label="t('分隔符')">
        <a-select v-model:value="data.options.separator" :options="separatorOptions" />
      </a-form-item>
      <a-form-item v-if="hasKey('selectedConfig')" :label="t('选择设置')">
        <a-select v-model:value="data.options.selectedConfig" :options="selectedOptions" />
      </a-form-item>
      <a-form-item label="数据分页" v-if="hasKey('isPagination')">
        <a-switch v-model:checked="data.options.isPagination" />
      </a-form-item>
      <a-form-item :label="t('标题')" v-if="!noHaveTitle.includes(data.type)">
        <a-input v-model:value="data.label" size="mini" />
      </a-form-item>
      <a-form-item :label="t('标题')" v-if="data.type === 'card'">
        <a-input v-model:value="data.options.title" size="mini" />
      </a-form-item>
      <a-form-item v-if="hasKey('showTime')" :label="t('开始占位')">
        <a-input v-model:value="data.options.startTimePlaceholder" />
      </a-form-item>

      <a-form-item v-if="hasKey('showTime')" :label="t('结束占位')">
        <a-input v-model:value="data.options.endTimePlaceholder" />
      </a-form-item>

      <a-form-item :label="t('占位提示')" v-if="hasKey('placeholder')">
        <a-textarea
          v-if="data.type === 'opinion'"
          v-model:value="data.options.placeholder"
          :placeholder="t('请输入占位提示')"
        />
        <a-input
          v-else
          v-model:value="data.options.placeholder"
          :placeholder="t('请输入占位提示')"
        />
      </a-form-item>

      <a-form-item
        :label="t('默认值')"
        v-if="
          (hasKey('defaultValue') &&
            (data.type === 'input' ||
              data.type === 'password' ||
              data.type === 'textarea' ||
              data.type === 'rate' ||
              data.type === 'switch' ||
              data.type === 'slider' ||
              data.type === 'number' ||
              data.type === 'picker-color' ||
              data.type === 'money-chinese' ||
              data.type === 'computational')) ||
          (needDicDefaultValue.includes(data.type) && data.options.datasourceType == 'dic')
        "
      >
        <a-textarea
          v-if="data.type === 'textarea'"
          v-model:value="data.options.defaultValue"
          :placeholder="t('请输入默认值')"
        />
        <a-rate
          v-else-if="data.type === 'rate'"
          v-model:value="data.options.defaultValue"
          :count="data.options.count"
          :allowHalf="data.options.allowHalf"
          :allowClear="data.options.allowClear"
        />
        <ColorPicker
          v-else-if="data.type === 'picker-color'"
          v-model:value="data.options.defaultValue"
        />
        <a-input-number
          v-else-if="
            data.type === 'money-chinese' || data.type === 'computational' || data.type === 'number'
          "
          v-model:value="data.options.defaultValue"
          :placeholder="t('请输入默认值')"
          :formatter="formatterVal"
          :parser="formatterVal"
          @blur="changeNumber"
        />
        <a-switch
          v-else-if="data.type === 'switch'"
          v-model:checked="data.options.defaultValue"
          :checkedValue="1"
          :unCheckedValue="0"
        />
        <template v-else-if="data.type === 'slider'">
          <a-input-number
            v-if="!data.options.range"
            v-model:value.number="data.options.defaultValue"
          />
          <template v-if="data.options.range">
            <a-input-number
              v-model:value.number="data.options.defaultValue[0]"
              :max="data.options.max"
            />
            <a-input-number
              v-model:value.number="data.options.defaultValue[1]"
              :max="data.options.max"
            />
          </template>
        </template>
        <a-select
          v-else-if="data.type == 'multiple-popup' || data.type == 'checkbox'"
          :options="defaultSelectOption"
          mode="multiple"
          :placeholder="t('请选择默认值')"
          :fieldNames="{ label: 'name', value: 'value' }"
          v-model:value="data.options.defaultTempValue"
          @change="handleDfValChange"
          :allowClear="true"
          @dropdown-visible-change="handleDfValueFocus"
        />
        <a-select
          v-else-if="needDicDefaultValue.includes(data.type)"
          :options="defaultSelectOption"
          :placeholder="t('请选择默认值')"
          :fieldNames="{ label: 'name', value: 'value' }"
          v-model:value="data.options.defaultSelect"
          :allowClear="true"
          @dropdown-visible-change="handleDfValueFocus"
        />
        <a-input
          v-else
          v-model:value="data.options.defaultValue"
          :placeholder="t('请输入默认值')"
        />
      </a-form-item>

      <a-form-item
        v-if="hasKey('format') && (data.type === 'time' || data.type === 'time-range')"
        :label="t('时间格式')"
      >
        <a-select v-model:value="data.options.format" disabled>
          <a-select-option value="HH:mm:ss" />
        </a-select>
      </a-form-item>

      <a-form-item
        v-if="hasKey('format') && (data.type === 'date' || data.type === 'date-range')"
        :label="t('日期格式')"
      >
        <a-select
          v-model:value="data.options.format"
          :disabled="data.type === 'date-range'"
          @change="formatChange"
        >
          <a-select-option value="YYYY-MM-DD HH:mm:ss" />
          <a-select-option value="YYYY-MM-DD" />
          <a-select-option value="YYYY-MM" />
          <a-select-option value="YYYY" />
        </a-select>
      </a-form-item>

      <template v-if="data.type === 'time'">
        <a-form-item :label="t('默认值')">
          <TimePicker
            style="width: 100%"
            v-model:value="data.options.defaultValue"
            :format="data.options.format"
            :placeholder="data.options.placeholder"
          />
        </a-form-item>
      </template>

      <template v-if="data.type === 'date'">
        <a-form-item :label="t('默认值')">
          <XjrDatePicker
            style="width: 100%"
            v-model:value="data.options.defaultValue"
            :format="data.options.format"
            :placeholder="data.options.placeholder"
          />
        </a-form-item>
      </template>
      <template v-if="data.type === 'time' || data.type === 'date'">
        <a-form-item :label="t('查询方式')">
          <a-select v-model:value="data.options.searchType">
            <a-select-option value="time">{{ t('时间选择') }}</a-select-option>
            <a-select-option value="range">{{ t('时间范围选择') }}</a-select-option>
          </a-select>
        </a-form-item>
      </template>
      <template v-if="data.type === 'signature'">
        <a-form-item :label="t('关联组件')">
          <a-select
            :options="SignSelectOption"
            mode="multiple"
            :placeholder="t('请选择关联组件')"
            :allowClear="true"
            v-model:value="data.options.associateComponents"
          />
        </a-form-item>
        <a-form-item :label="t('默认值类型')">
          <a-select
            :options="SignValueOption"
            :placeholder="t('请选择默认值类型')"
            :allowClear="true"
            @select="
              () => {
                data.options.defaultValue = '';
              }
            "
            v-model:value="data.options.signValueType"
          />
        </a-form-item>
        <a-form-item :label="t('默认值')">
          <SelectUser
            v-if="data.options.signValueType === 1"
            :multiple="true"
            :selectedIds="data.options.defaultValue"
            @change="
              (ids) => {
                data.options.defaultValue = ids.toString();
              }
            "
            @change-names="
              (names) => {
                userNames = names;
              }
            "
          >
            <a-input readonly placeholder="请选择默认值" v-model:value="userNames" />
          </SelectUser>
          <SelectRole
            v-else-if="data.options.signValueType === 0"
            :multiple="true"
            :selectedIds="data.options.defaultValue"
            @change="
              (ids) => {
                data.options.defaultValue = ids.toString();
              }
            "
            @change-names="
              (names) => {
                roleNames = names;
              }
            "
          >
            <a-input readonly placeholder="请选择默认值" v-model:value="roleNames" />
          </SelectRole>
          <a-input v-else readonly placeholder="请先选择默认值类型" />
        </a-form-item>
      </template>

      <template v-if="data.type === 'custom'">
        <a-form-item :label="t('编译类型')">
          <a-select v-model:value="data.options.type" @change="customCompTypeChange">
            <a-select-option value="html" />
            <a-select-option value="vue" />
            <a-select-option value="远程vue组件" />
            <a-select-option value="远程html组件" />
          </a-select>
        </a-form-item>
        <a-form-item :label="t('接口配置')">
          <LabelComponentApiConfig v-model:value="data.options.apiConfig" />
        </a-form-item>
        <template v-if="['html', 'vue'].includes(data.options.type)">
          <a-form-item :label="t('组件内容')">
            <a-input
              v-model:value="data.options.content"
              :placeholder="t('点击编写组件内容')"
              readonly
              @click="customDia = true"
            />
          </a-form-item>
        </template>
        <template v-if="data.options.type.includes('远程')">
          <a-form-item :label="t('组件地址')">
            <a-textarea v-model:value="data.options.compUrl" :placeholder="t('请填写地址')" />
          </a-form-item>
        </template>
      </template>

      <a-form-item :label="t('编码规则')" v-if="hasKey('autoCodeRule')" required>
        <a-select
          v-model:value="data.options.autoCodeRule"
          size="mini"
          :placeholder="t('请选择编码规则')"
        >
          <a-select-option v-for="rule in codeRuleOptions" :value="rule.code" :key="rule.id">
            {{ rule.name }}
          </a-select-option>
        </a-select>
      </a-form-item>

      <template v-if="data.type === 'computational' || data.type === 'money-chinese'">
        <a-form-item label="保留小数位">
          <a-input-number v-model:value="data.options.decimals" :min="0" :max="4" />
        </a-form-item>
        <a-form-item :label="t('计算式配置')">
          <a-input
            v-model:value="data.options.computationalConfigValue"
            readonly
            @click="computationalDialog = true"
          />
        </a-form-item>
        <ComputationalSetting
          v-if="computationalDialog"
          v-model:computationalConfig="data.options.computationalConfig"
          @set-computational-config-value="(val) => (data.options.computationalConfigValue = val)"
          v-model:computationalDialog="computationalDialog"
        />
      </template>

      <!-- iframe  添加参数-->
      <template v-if="data.type == 'iframe'">
        <a-form-item label="url" v-if="hasKey('url')">
          <a-textarea
            v-model:value="data.options.url"
            placeholder="请填写url,参数可用@代替。例如:https://www.learun.cn?id=@id"
          />
        </a-form-item>
        <a-form-item label="参数配置">
          <a-input
            :value="iframeText"
            :placeholder="t('点击进行参数配置')"
            @click="handleIframeConfig"
          >
            <template #suffix>
              <Icon icon="ant-design:ellipsis-outlined" />
            </template>
          </a-input>
        </a-form-item>
      </template>
      <template v-else>
        <a-form-item label="url" v-if="hasKey('url')">
          <a-textarea v-model:value="data.options.url" placeholder="请输入url" />
        </a-form-item>
      </template>

      <a-form-item :label="t('标签宽度')" v-if="hasKey('labelWidth')">
        <a-input-number v-model:value="data.options.labelWidth" :min="0" />
      </a-form-item>

      <a-form-item :label="t('组件宽度')" v-if="hasKey('width') || data.type == 'iframe'">
        <a-input v-model:value="data.options.width" />
      </a-form-item>
      <a-form-item
        :label="t('组件高度')"
        v-if="
          hasKey('height') ||
          data.type == 'iframe' ||
          data.type == 'form' ||
          data.type == 'sun-form'
        "
      >
        <a-input-number
          v-if="data.type == 'form' || data.type == 'sun-form'"
          v-model:value="data.options.height"
          :min="0"
        />
        <a-input v-else v-model:value="data.options.height" />
      </a-form-item>
      <a-form-item :label="t('信息类型')" v-if="hasKey('infoType')">
        <a-select v-model:value="data.options.infoType" size="mini">
          <a-select-option :value="CommonInfoType.USER_NAME">{{ t('当前用户') }}</a-select-option>
          <a-select-option :value="CommonInfoType.DEPT_NAME">{{ t('当前组织') }}</a-select-option>
          <a-select-option :value="CommonInfoType.TIME">{{ t('当前时间') }}</a-select-option>
          <a-select-option :value="CommonInfoType.USER_CODE">{{
            t('当前登录人编码')
          }}</a-select-option>
          <a-select-option :value="CommonInfoType.USER_MOBILE">{{
            t('当前登录人电话')
          }}</a-select-option>
          <a-select-option :value="CommonInfoType.USER_EMAIL">{{
            t('当前登录人邮箱')
          }}</a-select-option>
          <a-select-option :value="CommonInfoType.POST_NAME">{{
            t('当前登录人岗位')
          }}</a-select-option>
          <a-select-option :value="CommonInfoType.ROLE_NAME">{{
            t('当前登录人角色')
          }}</a-select-option>
          <a-select-option :value="CommonInfoType.USER_ADDRESS">{{
            t('当前登录人联系地址')
          }}</a-select-option>
          <a-select-option :value="CommonInfoType.DEPT_ID">{{
            t('当前登录人组织ID')
          }}</a-select-option>
          <a-select-option :value="CommonInfoType.DEPT_CODE">{{
            t('当前登录人组织编码')
          }}</a-select-option>
        </a-select>
      </a-form-item>

      <a-form-item :label="t('组件类型')" v-if="hasKey('orgzType')">
        <a-select v-model:value="data.options.orgzType" size="mini">
          <a-select-option :value="0">{{ t('系统组织架构') }}</a-select-option>
        </a-select>
      </a-form-item>

      <a-form-item :label="t('组件类型')" v-if="hasKey('userType')">
        <a-select v-model:value="data.options.userType" size="mini">
          <a-select-option :value="0">{{ t('系统用户') }}</a-select-option>
        </a-select>
      </a-form-item>

      <a-form-item
        :label="t('显示全路径')"
        v-if="data.options.infoType === CommonInfoType.DEPT_NAME || data.type === 'organization'"
      >
        <a-switch v-model:checked="data.options.isShowAllName" />
      </a-form-item>

      <a-form-item v-if="hasKey('loadAgain')">
        <template #label>
          <a-tooltip>
            <template #title> 二次加载是决定编辑状态是否重新获取信息体数据 </template>
            <Icon icon="ant-design:question-circle-outlined" color="#909399" />
          </a-tooltip>
          &nbsp;{{ t('二次加载') }}
        </template>
        <a-switch v-model:checked="data.options.loadAgain" />
      </a-form-item>

      <template v-if="data.type === 'button'">
        <a-form-item :label="t('按钮名称')">
          <a-input v-model:value="data.options.name" @change="changeBtnName" />
        </a-form-item>
        <template v-if="!data.options.buttonType && data.isSubFormChild">
          <DataSourceSetting v-model:data="data" :hasExample="false" />
        </template>
        <template v-if="data.options.isSpecial">
          <a-form-item :label="t('按钮类型')" required>
            <a-select
              v-model:value="data.options.buttonType"
              size="mini"
              disabled
              :placeholder="t('请选择按钮类型')"
            >
              <a-select-option :value="1">{{ t('联想弹层按钮') }}</a-select-option>
              <a-select-option :value="2">{{ t('表格选择数据按钮') }}</a-select-option>
            </a-select>
          </a-form-item>
          <template v-if="data.options.buttonType">
            <DataSourceSetting v-model:data="data" @handle-options-remove="handleOptionsRemove" />
          </template>
          <template v-if="data.options.buttonType == 2">
            <a-form-item :label="t('表格选择')" required>
              <a-select
                v-model:value="data.options.selectTable"
                size="mini"
                :placeholder="t('请选择表格')"
              >
                <a-select-option
                  v-for="item in buttonTableOptions"
                  :value="item.key"
                  :key="item.key"
                  >{{ item.label }}</a-select-option
                >
              </a-select>
            </a-form-item>
            <a-form-item :label="t('表头配置')">
              <a-input
                :value="configText"
                :placeholder="t('点击进行表头配置')"
                @click="tableTitleClick"
              >
                <template #suffix>
                  <Icon icon="ant-design:ellipsis-outlined" />
                </template>
              </a-input>
            </a-form-item>
            <template v-if="data.options.selectTable">
              <a-form-item
                :label="item.label"
                v-for="item in data.options.tableColumns.filter(
                  (x) => !unPreloadComponents.includes(x.type),
                )"
                :key="item.key"
              >
                <a-input
                  v-if="data.options.datasourceType === 'api'"
                  v-model:value="item.prestrainField"
                  :placeholder="t('请填写接口出参字段')"
                  @change="handlePreChange(item)"
                />
                <a-select
                  v-else-if="data.options.datasourceType === 'dic'"
                  v-model:value="item.prestrainField"
                  @change="handlePreChange(item)"
                >
                  <a-select-option value="name">name</a-select-option>
                  <a-select-option value="value">value</a-select-option>
                </a-select>
              </a-form-item>
            </template>
          </template>
        </template>
        <a-form-item :label="t('按钮宽度')">
          <a-input
            v-model:value="data.options.buttonWidth"
            :placeholder="t('请填写按钮宽度，不填则默认')"
          />
        </a-form-item>
        <a-form-item :label="t('按钮高度')">
          <a-input
            v-model:value="data.options.buttonHeight"
            :placeholder="t('请填写按钮高度，不填则默认')"
          />
        </a-form-item>
      </template>

      <a-form-item :label="t('最大值')" v-if="hasKey('max')">
        <a-input-number v-model:value.number="data.options.max" @change="changeNumber" />
      </a-form-item>

      <a-form-item :label="t('最大值')" v-if="hasKey('count')">
        <a-input-number v-model:value.number="data.options.count" @change="changeNumber" />
      </a-form-item>

      <a-form-item :label="t('最小值')" v-if="hasKey('min')">
        <a-input-number v-model:value.number="data.options.min" @change="changeNumber" />
      </a-form-item>

      <a-form-item :label="t('步长')" v-if="hasKey('step')">
        <a-input-number v-model:value.number="data.options.step" :min="0" />
      </a-form-item>

      <a-form-item :label="t('前置标签')" v-if="hasKey('addonBefore')">
        <a-input v-model:value="data.options.addonBefore" :placeholder="t('请输入前置标签')" />
      </a-form-item>

      <a-form-item :label="t('后置标签')" v-if="hasKey('addonAfter')">
        <a-input v-model:value="data.options.addonAfter" :placeholder="t('请输入后置标签')" />
      </a-form-item>

      <a-form-item :label="t('前置图标')" v-if="hasKey('prefix')">
        <IconPicker v-model:value="data.options.prefix" :disabled="false" :readonly="false" />
      </a-form-item>

      <a-form-item :label="t('后置图标')" v-if="hasKey('suffix')">
        <IconPicker v-model:value="data.options.suffix" :disabled="false" :readonly="false" />
      </a-form-item>

      <a-form-item :label="t('按钮样式')" v-if="data.options.buttonStyleType">
        <a-select v-model:value="data.options.buttonStyleType">
          <a-select-option value="primary">主按钮</a-select-option>
          <a-select-option value="default">默认按钮</a-select-option>
          <a-select-option value="dashed">危险按钮</a-select-option>
          <a-select-option value="text">文本按钮</a-select-option>
          <a-select-option value="link">链接按钮</a-select-option>
        </a-select>
      </a-form-item>

      <a-form-item
        label="按钮类型"
        :name="['sights', index, 'label']"
        :labelCol="{ span: 8 }"
        :wrapperCol="{ span: 16 }"
        labelAlign="left"
        :colon="false"
      >
        <a-select
          @change="
            () => {
              data.options.event = [];
              if (data.options.type == CustomButtonModalType.Modal) {
                data.options.event.push({
                  operateType: 2,
                  operateConfig: { js: `formActionType.openModal(curRowData)` },
                });
              }
            }
          "
          v-model:value="data.options.type"
          style="width: 100%"
        >
          <a-select-option :value="CustomButtonModalType.COMMON">普通按钮</a-select-option>
          <a-select-option :value="CustomButtonModalType.Modal">弹窗按钮</a-select-option>
        </a-select>
      </a-form-item>
      <template v-if="data.options.type == CustomButtonModalType.Modal">
        <a-form-item
          label="按钮弹窗配置"
          :labelCol="{ span: 8 }"
          :wrapperCol="{ span: 16 }"
          labelAlign="left"
          :colon="false"
        >
          <ButtonModalConfig v-model:modalData="data.options.modal" :formJson="[]">
            <a-input
              :value="data.options.modal?.bindModal ? t('已配置') : t('点击进行配置')"
              :placeholder="t('点击进行配置')"
            >
              <template #suffix>
                <Icon icon="ant-design:ellipsis-outlined" />
              </template>
            </a-input>
          </ButtonModalConfig>
        </a-form-item>
      </template>

      <a-form-item :label="t('最大长度')" v-if="hasKey('maxlength')">
        <a-input
          v-model:value.number="data.options.maxlength"
          :placeholder="t('请输入最大长度，按字符计算')"
        />
      </a-form-item>
      <a-form-item :label="t('地址栏参数')" v-if="data.type == 'input'">
        <a-input v-model:value="data.options.addressKey" :placeholder="t('请输入地址栏参数名称')" />
      </a-form-item>

      <a-form-item :label="t('开启提示')" v-if="hasKey('checkedChildren')">
        <a-input v-model:value="data.options.checkedChildren" />
      </a-form-item>

      <a-form-item :label="t('关闭提示')" v-if="hasKey('unCheckedChildren')">
        <a-input v-model:value="data.options.unCheckedChildren" />
      </a-form-item>

      <a-form-item :label="t('开启颜色')" v-if="hasKey('checkedColor')">
        <ColorPicker v-model:value="data.options.checkedColor" />
      </a-form-item>

      <a-form-item :label="t('关闭颜色')" v-if="hasKey('unCheckedColor')">
        <ColorPicker v-model:value="data.options.unCheckedColor" />
      </a-form-item>

      <a-form-item :label="t('地址字段')" v-if="hasKey('address')">
        <a-select v-model:value="data.options.address" size="mini" allowClear>
          <a-select-option v-for="it in mapComps" :key="it.model" :value="it.bindField">{{
            it.label
          }}</a-select-option>
        </a-select>
      </a-form-item>
      <a-form-item :label="t('经纬度字段')" v-if="hasKey('latiAndLong')">
        <a-select v-model:value="data.options.latiAndLong" size="mini" allowClear>
          <a-select-option v-for="it in mapComps" :key="it.model" :value="it.bindField">{{
            it.label
          }}</a-select-option>
        </a-select>
      </a-form-item>
      <a-form-item :label="t('配置类型')" v-if="hasKey('codeType')">
        <a-select
          v-model:value="data.options.codeType"
          size="mini"
          :placeholder="t('请选择配置类型')"
          @change="handleChangeCode"
        >
          <a-select-option value="fixed" key="fixed">
            {{ data.type === 'qrcode' ? t('固定二维码') : t('固定一维码') }}
          </a-select-option>
          <a-select-option value="api" key="api"> {{ t('接口配置') }} </a-select-option>
        </a-select>
      </a-form-item>
      <!-- 标签组件 配置 -->
      <template v-if="data.type == 'labelComponent'">
        <a-form-item :label="t('数据来源')">
          <a-radio-group
            button-style="solid"
            v-model:value="data.options.datasourceType"
            size="small"
          >
            <a-radio-button value="static">
              {{ t('客户配置') }}
            </a-radio-button>
            <a-radio-button value="api">API</a-radio-button>
            <a-radio-button value="dic">{{ t('数据字典') }}</a-radio-button>
          </a-radio-group>
        </a-form-item>

        <a-form-item :label="t('接口配置')" v-if="data.options.datasourceType === 'api'">
          <LabelComponentApiConfig v-model:value="data.options.apiConfig" />
        </a-form-item>

        <a-form-item :label="t('数据选项')" v-if="data.options.datasourceType === 'dic'">
          <DicTreeSelect v-model:value="data.options.itemId" @change="handleDicChange" />
        </a-form-item>
        <a-form-item :label="t('样式配置')">
          <StyleConfiguration v-model:value="data.options.styleConfig" :data="data" />
        </a-form-item>
      </template>

      <!-- 树形选择组件 配置 -->
      <a-form-item :label="t('选择树')" v-if="data.type == 'tree-select-component'">
        <a-select
          v-model:value="data.options!.treeConfig.id"
          style="width: 100%"
          :options="treeSelectOption"
          :field-names="{ label: 'name', value: 'id', options: 'children' }"
          @change="
            (_, option) => {
              data.options.treeConfig.type = option.type;
              data.options.treeConfig.innerParams = [];
            }
          "
        />
      </a-form-item>
      <!-- 树形组件 配置 -->
      <a-form-item :label="t('选择树')" v-if="data.type == 'tree-component'">
        <a-select
          v-model:value="data.options!.treeConfig.id"
          style="width: 100%"
          :options="treeSelectOption"
          @change="
            (_, option) => {
              data.options.treeConfig.type = option.type;
              data.options.treeConfig.innerParams = [];
            }
          "
          :field-names="{ label: 'name', value: 'id', options: 'children' }"
        />
      </a-form-item>
      <a-form-item
        label="api入参配置"
        v-if="
          data.type &&
          (data.type == 'tree-select-component' || data.type == 'tree-component') &&
          data.options.treeConfig.type == 2
        "
      >
        <a-input
          :value="data.options.treeConfig.innerParams?.length ? t('已配置') : ''"
          :placeholder="t('点击进行参数配置')"
          @click="handleTreeConfig"
        >
          <template #suffix>
            <Icon icon="ant-design:ellipsis-outlined" />
          </template>
        </a-input>
      </a-form-item>
      <a-form-item
        :label="t('存储方式')"
        v-if="data.type == 'tree-select-component' || data.type == 'tree-component'"
      >
        <a-select
          v-model:value="data.options.treeConfig.isSaveLast"
          size="mini"
          :placeholder="t('请选择数据存储方式')"
        >
          <a-select-option :value="true">只存储选中节点</a-select-option>
          <a-select-option :value="false">全路径存储包括父级</a-select-option>
        </a-select>
      </a-form-item>
      <a-form-item
        :label="t('允许多选')"
        v-if="data.type == 'tree-select-component' || data.type == 'tree-component'"
      >
        <a-switch v-model:checked="data.options.treeConfig.isMultiple" />
      </a-form-item>
      <a-form-item :label="t('组件最大高度')" v-if="data.type == 'tree-component'">
        <a-input v-model:value="data.options.treeConfig.height" />
      </a-form-item>
      <a-form-item :label="t('一维码格式')" v-if="data.type == 'barcode'">
        <a-select
          v-model:value="data.options.format"
          size="mini"
          :placeholder="t('请选择一维码格式')"
        >
          <a-select-option value="CODE128" />
          <a-select-option value="CODE39" />
          <a-select-option value="EAN13" />
        </a-select>
      </a-form-item>
      <a-form-item
        :label="data.type === 'qrcode' ? t('二维码内容') : t('一维码内容')"
        v-if="(data.type == 'qrcode' || data.type == 'barcode') && data.options.codeType == 'fixed'"
      >
        <a-textarea
          v-model:value="data.options.defaultValue"
          :placeholder="data.type === 'qrcode' ? t('请填写二维码内容') : t('请填写一维码内容')"
          :rows="4"
        />
      </a-form-item>
      <a-form-item
        :label="t('接口配置')"
        v-if="(data.type == 'qrcode' || data.type == 'barcode') && data.options.codeType == 'api'"
      >
        <a-input
          v-model:value="data.options.apiConfig.path"
          :placeholder="t('点击进行接口配置')"
          @click="handleApiConfig()"
        >
          <template #suffix>
            <Icon icon="ant-design:ellipsis-outlined" />
          </template>
        </a-input>
      </a-form-item>
      <!-- 子表不需要span -->
      <a-form-item
        label="标签宽度"
        v-if="hasKey('span') && (!data.isSubFormChild || !data.isSingleFormChild)"
      >
        <a-input-number
          v-model:value="data.options.span"
          :min="0"
          :max="24"
          addonAfter="/ 24"
          @change="handleSpanChange"
        />
      </a-form-item>

      <a-form-item :label="t('双滑块模式')" v-if="hasKey('range')">
        <a-switch v-model:checked="data.options.range" @change="handleSliderModeChange" />
      </a-form-item>

      <a-form-item :label="t('反向坐标轴')" v-if="hasKey('reverse')">
        <a-switch v-model:checked="data.options.reverse" />
      </a-form-item>

      <template v-if="data.type === 'image'">
        <a-form-item :label="t('默认值')">
          <div class="flex">
            <a-input v-model:value="imageUrl" :disabled="true" class="!mr-1.5" />
            <a-upload
              action=""
              :beforeUpload="submitUpload"
              accept=""
              :max-count="1"
              :show-upload-list="false"
              class="image-box"
            >
              <div class="image-default">
                <SvgIcon name="upload" />
              </div>
            </a-upload>
          </div>
        </a-form-item>
        <a-form-item :label="t('图片来源')">
          <a-select
            v-model:value="data.options.sourceType"
            size="mini"
            :placeholder="t('请选择图片来源')"
          >
            <a-select-option value="album,camera">{{ t('使用相机和相册') }}</a-select-option>
            <a-select-option value="album">{{ t('从相册选图') }}</a-select-option>
            <a-select-option value="camera">{{ t('使用相机') }}</a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item :label="t('二次上传')">
          <a-switch v-model:checked="data.options.isUpload" />
        </a-form-item>
      </template>

      <template v-if="data.type === 'file'">
        <a-form-item :label="t('默认值')">
          <a-upload action="" :beforeUpload="submitUpload" accept="" :show-upload-list="false">
            <a-button>
              <SvgIcon name="upload" style="margin-right: 10px" />
              {{ t('点击上传') }}
            </a-button>
          </a-upload>
        </a-form-item>
      </template>

      <a-form-item :label="t('切换按钮')" v-if="hasKey('visibilityToggle')">
        <a-switch v-model:checked="data.options.visibilityToggle" />
      </a-form-item>

      <a-form-item :label="t('行数')" v-if="hasKey('rows') && !data.options.autoSize">
        <a-input-number v-model:value="data.options.rows" :min="0" />
      </a-form-item>

      <a-form-item :label="t('显示字数')" v-if="hasKey('showCount')">
        <a-switch v-model:checked="data.options.showCount" />
      </a-form-item>

      <a-form-item :label="t('自适应高度')" v-if="hasKey('autoSize')">
        <a-switch v-model:checked="data.options.autoSize" />
      </a-form-item>

      <a-form-item :label="t('最小行数')" v-if="hasKey('minRows') && !data.options.autoSize">
        <a-input-number v-model:value="data.options.minRows" :min="0" />
      </a-form-item>

      <a-form-item :label="t('最大行数')" v-if="hasKey('maxRows') && !data.options.autoSize">
        <a-input-number v-model:value="data.options.maxRows" :min="0" />
      </a-form-item>

      <a-form-item :label="t('允许半选')" v-if="hasKey('allowHalf')">
        <a-switch v-model:checked="data.options.allowHalf" />
      </a-form-item>
      <template v-if="data.type === 'divider'">
        <a-form-item :label="t('标题')">
          <a-input v-model:value="data.options.defaultValue" />
        </a-form-item>
        <a-form-item :label="t('上间距')">
          <a-input-number v-model:value="data.options.marginTop" :min="0" />
        </a-form-item>
        <a-form-item :label="t('下间距')">
          <a-input-number v-model:value="data.options.marginBottom" :min="0" />
        </a-form-item>
        <a-form-item :label="t('文案对齐')">
          <a-radio-group button-style="solid" v-model:value="data.options.orientation">
            <a-radio-button value="left">{{ t('左') }}</a-radio-button>
            <a-radio-button value="center">{{ t('中') }}</a-radio-button>
            <a-radio-button value="right">{{ t('右') }}</a-radio-button>
          </a-radio-group>
        </a-form-item>
      </template>
      <template v-if="data.type === 'upload'">
        <a-form-item :label="t('上传列表样式')">
          <a-radio-group v-model:value="data.options.listType" button-style="solid">
            <a-radio-button value="text">text</a-radio-button>
            <a-radio-button value="picture">picture </a-radio-button>
            <a-radio-button value="picture-card" class="upload-pic">picture-card</a-radio-button>
            <!-- <a-radio-button value="dragger">dragger</a-radio-button> -->
          </a-radio-group>
        </a-form-item>

        <a-form-item :label="t('文件类型')">
          <a-input
            v-model:value="data.options.accept"
            :placeholder="t('用“,”号隔开,例如:.jpg,.bmp')"
          />
        </a-form-item>

        <a-form-item :label="t('最大文件数')">
          <a-input-number v-model:value.number="data.options.maxNumber" :min="1" />
        </a-form-item>

        <a-form-item :label="t('大小限制')">
          <a-input v-model:value.number="data.options.maxSize" suffix="MB" />
        </a-form-item>
        <a-form-item :label="t('图片来源')" v-if="data.options.listType == 'picture-card'">
          <a-select
            v-model:value="data.options.sourceType"
            size="mini"
            :placeholder="t('请选择图片来源')"
          >
            <a-select-option value="album,camera">{{ t('使用相机和相册') }}</a-select-option>
            <a-select-option value="album">{{ t('从相册选图') }}</a-select-option>
            <a-select-option value="camera">{{ t('使用相机') }}</a-select-option>
          </a-select>
        </a-form-item>
        <!-- <a-form-item :label="t('支持多选')">
          <a-switch v-model:checked="data.options.multiple" />
        </a-form-item> -->
      </template>
      <a-form-item :label="t('调用签名')" v-if="hasKey('isCallSign')">
        <a-switch v-model:checked="data.options.isCallSign" />
      </a-form-item>
      <a-form-item :label="t('选项样式')" v-if="hasKey('optionType')">
        <a-radio-group button-style="solid" v-model:value="data.options.optionType">
          <a-radio-button value="default">{{ t('默认') }}</a-radio-button>
          <a-radio-button value="button">{{ t('按钮') }}</a-radio-button>
        </a-radio-group>
      </a-form-item>

      <template v-if="data.type === 'form'">
        <a-form-item label="列表查看">
          <a-switch v-model:checked="data.options.isListView" @change="getViewList" />
        </a-form-item>
        <template v-if="data.options.isListView">
          <a-table
            class="view-table"
            :key="viewTableKey"
            :columns="listViewColumns"
            :data-source="data.options.viewList"
            :pagination="false"
          >
            <template #headerCell="{ column }">
              <template v-if="column.dataIndex === 'sort'">
                <svg class="icon" aria-hidden="true">
                  <use xlink:href="#icon-fangxiang1" />
                </svg>
              </template>
            </template>
            <template #bodyCell="{ column, record }">
              <template v-if="column.dataIndex === 'sort'">
                <svg class="icon viewDraggable-icon" aria-hidden="true" style="cursor: move">
                  <use xlink:href="#icon-paixu" />
                </svg>
              </template>
              <template v-if="column.dataIndex === 'checked'">
                <a-checkbox v-model:checked="record[column.dataIndex]" />
              </template>
            </template>
          </a-table>
        </template>
      </template>
      <template v-if="data.type === 'modal' || data.type === 'drawer'">
        <a-form-item :label="t('弹窗配置')">
          <a-input
            :value="data.options.bindModal ? t('已配置') : ''"
            :placeholder="t('点击进行弹窗配置')"
            @click="handleModalConfig(3)"
          >
            <template #suffix>
              <Icon icon="ant-design:ellipsis-outlined" />
            </template>
          </a-input>
        </a-form-item>
        <a-form-item label="入参配置">
          <a-input
            :value="data.options.innerParams?.length ? t('已配置') : ''"
            :placeholder="t('点击进行参数配置')"
            @click="handleModalConfig(1)"
          >
            <template #suffix>
              <Icon icon="ant-design:ellipsis-outlined" />
            </template>
          </a-input>
        </a-form-item>
        <a-form-item label="出参配置">
          <a-input
            :value="data.options.outParams?.length ? t('已配置') : ''"
            :placeholder="t('点击进行参数配置')"
            @click="handleModalConfig(2)"
          >
            <template #suffix>
              <Icon icon="ant-design:ellipsis-outlined" />
            </template>
          </a-input>
        </a-form-item>
        <a-form-item label="弹窗宽度">
          <a-input-group compact>
            <a-input-number
              v-model:value="data.options.modalWidth"
              :min="0"
              :max="data.options.modalWidthUnit == 'px' ? null : 100"
              :placeholder="t('请设置弹窗宽度')"
              style="width: calc(100% - 60px)"
            />
            <a-select
              v-model:value="data.options.modalWidthUnit"
              style="width: 60px"
              @change="
                (val) => {
                  if (val == '%' && data.options.modalWidth > 100) {
                    data.options.modalWidth = 100;
                  }
                }
              "
            >
              <a-select-option value="px">px</a-select-option>
              <a-select-option value="%">%</a-select-option>
            </a-select>
          </a-input-group>
        </a-form-item>
        <a-form-item label="弹窗高度" v-if="data.type === 'modal'">
          <a-input-group compact>
            <a-input-number
              v-model:value="data.options.modalHeight"
              :min="0"
              :max="data.options.modalHeightUnit == 'px' ? null : 100"
              :placeholder="t('请设置弹窗高度')"
              style="width: calc(100% - 60px)"
            />
            <a-select
              v-model:value="data.options.modalHeightUnit"
              style="width: 60px"
              @change="
                (val) => {
                  if (val == '%' && data.options.modalHeight > 100) {
                    data.options.modalHeight = 100;
                  }
                }
              "
            >
              <a-select-option value="px">px</a-select-option>
              <a-select-option value="%">%</a-select-option>
            </a-select>
          </a-input-group>
        </a-form-item>
      </template>

      <a-form-item :label="t('是否多选')" v-if="hasKey('multiple')">
        <a-switch v-model:checked="data.options.multiple" />
      </a-form-item>
      <a-form-item :label="t('是否显示文本')" v-if="data.type == 'barcode'">
        <a-switch v-model:checked="data.options.displayValue" />
      </a-form-item>
      <a-form-item :label="t('显示Tips')" v-if="hasKey('tooltipConfig')">
        <a-switch v-model:checked="data.options.tooltipConfig.visible" />
      </a-form-item>
      <a-form-item
        :label="t('Tips内容')"
        v-if="hasKey('tooltipConfig') && data.options.tooltipConfig.visible"
      >
        <a-input v-model:value="data.options.tooltipConfig.title" />
      </a-form-item>
      <a-form-item :label="t('显示标签')" v-if="hasKey('showLabel')">
        <a-switch v-model:checked="data.options.showLabel" />
      </a-form-item>
      <a-form-item :label="t('是否显示')" v-if="hasKey('isShow')">
        <a-switch v-model:checked="data.options.isShow" />
      </a-form-item>
      <template v-if="data.type == 'card'">
        <div class="setting-box">
          <div class="setting-head">标题样式设置</div>
          <div class="setting-content">
            <span class="label">是否显示</span>
            <a-switch v-model:checked="data.options.cardStyle.title.isShow" />
          </div>
          <template v-if="data.options.cardStyle.title.isShow">
            <div class="setting-content">
              <span class="label">字体颜色</span>
              <ColorPicker v-model:value="data.options.cardStyle.title.color" />
            </div>
            <div class="setting-content">
              <span class="label">字体大小</span>
              <a-input-number
                v-model:value="data.options.cardStyle.title.fontSize"
                :min="6"
                :max="120"
              />
            </div>
            <div class="setting-content">
              <span class="label">字体权重</span>
              <a-input-number
                v-model:value="data.options.cardStyle.title.fontWeight"
                :min="100"
                :max="800"
              />
            </div>
          </template>
        </div>
        <div class="setting-box">
          <div class="setting-head">分割线样式设置</div>
          <div class="setting-content">
            <span class="label">是否显示</span>
            <a-switch v-model:checked="data.options.cardStyle.divider.isShow" />
          </div>
          <template v-if="data.options.cardStyle.divider.isShow">
            <div class="setting-content">
              <span class="label">分割线颜色</span>
              <ColorPicker v-model:value="data.options.cardStyle.divider.color" />
            </div>
            <div class="setting-content">
              <span class="label">分割线宽度</span>
              <a-input-number
                v-model:value="data.options.cardStyle.divider.width"
                :min="1"
                :max="10"
              />
            </div>
          </template>
        </div>
        <div class="setting-box">
          <div class="setting-head">图标样式设置</div>
          <div class="setting-content">
            <span class="label">是否显示</span>
            <a-switch v-model:checked="data.options.cardStyle.icon.isShow" />
          </div>
          <div class="setting-content" v-if="data.options.cardStyle.icon.isShow">
            <span class="label">边框颜色</span>
            <ColorPicker v-model:value="data.options.cardStyle.icon.color" />
          </div>
        </div>

        <div class="setting-box">
          <div class="setting-head">边框样式设置</div>
          <div class="setting-content">
            <span class="label">是否显示</span>
            <a-switch v-model:checked="data.options.cardStyle.border.isShow" />
          </div>
          <template v-if="data.options.cardStyle.border.isShow">
            <div class="setting-content">
              <span class="label">边框颜色</span>
              <ColorPicker v-model:value="data.options.cardStyle.border.color" />
            </div>
            <div class="setting-content">
              <span class="label">边框宽度</span>
              <a-input-number
                v-model:value="data.options.cardStyle.border.width"
                :min="1"
                :max="10"
              />
            </div>
          </template>
        </div>
        <div class="setting-box">
          <div class="setting-head">背景样式设置</div>
          <div class="setting-content">
            <span class="label">是否显示</span>
            <a-switch v-model:checked="data.options.cardStyle.background.isShow" />
          </div>
          <template v-if="data.options.cardStyle.background.isShow">
            <div class="setting-content">
              <span class="label">背景颜色</span>
              <ColorPicker v-model:value="data.options.cardStyle.background.bgColor" />
            </div>
            <div class="setting-content">
              <span class="label">背景图片</span>

              <div class="flex">
                <a-input
                  v-model:value="data.options.cardStyle.background.bgImgUrl"
                  allow-clear
                  class="!mr-1.5"
                />
                <a-upload
                  action=""
                  :beforeUpload="submitCardBgUpload"
                  accept=""
                  :max-count="1"
                  :show-upload-list="false"
                  class="image-box"
                >
                  <div class="image-default">
                    <SvgIcon name="upload" />
                  </div>
                </a-upload>
              </div>
            </div>
          </template>
        </div>
        <div class="setting-box">
          <div class="setting-head">内容区域样式设置</div>
          <div class="setting-content">
            <span class="label">是否显示</span>
            <a-switch v-model:checked="data.options.cardStyle.content.isShow" />
          </div>
          <template v-if="data.options.cardStyle.content.isShow">
            <div class="setting-content">
              <span class="label">背景颜色</span>
              <ColorPicker v-model:value="data.options.cardStyle.content.bgColor" />
            </div>
            <div class="setting-content">
              <span class="label">背景图片</span>
              <div class="flex">
                <a-input
                  v-model:value="data.options.cardStyle.content.bgImgUrl"
                  allow-clear
                  class="!mr-1.5"
                />
                <a-upload
                  action=""
                  :beforeUpload="submitCardContentBgUpload"
                  accept=""
                  :max-count="1"
                  :show-upload-list="false"
                  class="image-box"
                >
                  <div class="image-default">
                    <SvgIcon name="upload" />
                  </div>
                </a-upload>
              </div>
            </div>
          </template>
        </div>
      </template>

      <a-form-item :label="t('允许搜索')" v-if="hasKey('showSearch')">
        <a-switch v-model:checked="data.options.showSearch" />
      </a-form-item>
      <a-form-item :label="t('允许多选')" v-if="hasKey('isMultiple')">
        <a-switch v-model:checked="data.options.isMultiple" />
      </a-form-item>
      <a-form-item :label="t('是否必填')" v-if="hasKey('required')">
        <a-switch
          v-model:checked="data.options.required"
          :disabled="
            data.options.isShow === false || data.options.readonly || data.options.disabled
          "
        />
      </a-form-item>

      <a-form-item :label="t('是否只读')" v-if="hasKey('readonly')">
        <a-switch
          v-model:checked="data.options.readonly"
          :disabled="data.options.disabled || data.options.disabled"
          @change="changeReadonly"
        />
      </a-form-item>

      <a-form-item :label="t('是否禁用')" v-if="hasKey('disabled')">
        <a-switch
          v-model:checked="data.options.disabled"
          @change="changeDisabled"
          :disabled="data.type === 'info' || (data.type == 'input' && data.options.isSave)"
        />
      </a-form-item>
      <a-form-item :label="t('是否合计')" v-if="hasKey('subTotal') && data.isSubFormChild">
        <a-switch v-model:checked="data.options.subTotal" />
      </a-form-item>

      <a-form-item :label="t('开启清除')" v-if="hasKey('allowClear')">
        <a-switch
          v-model:checked="data.options.allowClear"
          :disabled="data.options.readonly || data.options.disabled"
        />
      </a-form-item>
      <a-form-item :label="t('获取当前时间')" v-if="hasKey('isGetCurrent')">
        <a-switch v-model:checked="data.options.isGetCurrent" />
      </a-form-item>
      <!-- <a-form-item :label="t('显示边框')" v-if="hasKey('bordered') && !data.isSubFormChild">
        <a-switch v-model:checked="data.options.bordered" />
      </a-form-item> -->
      <a-form-item :label="t('移动端扫描')" v-if="hasKey('scan')">
        <a-switch v-model:checked="data.options.scan" />
      </a-form-item>
      <a-form-item :label="t('开启AI')" v-if="hasKey('isShowAi')">
        <a-switch v-model:checked="data.options.isShowAi" />
      </a-form-item>
      <!-- <a-form-item :label="t('组件边框')" v-if="hasKey('showComponentBorder')">
        <a-switch v-model:checked="data.options.showComponentBorder" />
      </a-form-item> -->

      <a-form-item :label="t('表单边框')" v-if="hasKey('showFormBorder')">
        <a-switch v-model:checked="data.options.showFormBorder" />
      </a-form-item>

      <a-form-item :label="t('显示序号')" v-if="hasKey('showIndex')">
        <a-switch v-model:checked="data.options.showIndex" />
      </a-form-item>
      <a-form-item :label="t('是否导入')" v-if="hasKey('isImport')">
        <a-switch v-model:checked="data.options.isImport" />
      </a-form-item>
      <a-form-item :label="t('是否导出')" v-if="hasKey('isExport')">
        <a-switch v-model:checked="data.options.isExport" />
      </a-form-item>
      <a-form-item :label="t('是否批量删除')" v-if="hasKey('isDeleteSelected')">
        <a-switch
          v-model:checked="data.options.isDeleteSelected"
          @change="
            (v) => {
              if (v) data.options.hasCheckedCol = true;
            }
          "
        />
      </a-form-item>
      <a-form-item
        :label="t('显示列显隐设置')"
        v-if="data.type === 'form'"
        :labelCol="{ span: 10 }"
      >
        <a-switch v-model:checked="data.options.showColunmSet" />
      </a-form-item>
      <a-form-item :label="t('显示新增')" v-if="hasKey('isShowAdd')">
        <a-switch v-model:checked="data.options.isShowAdd" />
      </a-form-item>
      <a-form-item :label="t('显示删除')" v-if="hasKey('isShowDelete')">
        <a-switch v-model:checked="data.options.isShowDelete" />
      </a-form-item>
      <a-form-item :label="t('允许勾选')" v-if="hasKey('hasCheckedCol')">
        <a-switch v-model:checked="data.options.hasCheckedCol" />
      </a-form-item>
      <template v-if="data.type === 'title' || data.type === 'text'">
        <a-form-item :label="data.type === 'title' ? t('标题') : t('内容')">
          <a-input v-model:value="data.options.defaultValue" />
        </a-form-item>
        <a-form-item :label="t('字体颜色')">
          <ColorPicker v-model:value="data.options.color" />
        </a-form-item>
        <a-form-item :label="t('字体')" v-if="data.type === 'text'">
          <a-select v-model:value="data.options.fontFamily">
            <a-select-option value="Arial"> Arial </a-select-option>
            <a-select-option value="宋体">{{ t('宋体') }}</a-select-option>
            <a-select-option value="微软雅黑">{{ t('微软雅黑') }}</a-select-option>
            <a-select-option value="黑体">{{ t('黑体') }}</a-select-option>
            <a-select-option value="fangsong">fangsong</a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item :label="t('字体大小')">
          <a-input-number v-model:value="data.options.fontSize" :min="0" />
        </a-form-item>
        <a-form-item :label="t('粗细')" v-if="data.type === 'text'">
          <a-select v-model:value="data.options.fontWeight">
            <a-select-option value="lighter"> lighter </a-select-option>
            <a-select-option value="normal"> normal </a-select-option>
            <a-select-option value="bold"> bold </a-select-option>
            <a-select-option value="500">500</a-select-option>
            <a-select-option value="600">600</a-select-option>
            <a-select-option value="700">700</a-select-option>
            <a-select-option value="800">800</a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item :label="t('样式')" v-if="data.type === 'text'">
          <a-select v-model:value="data.options.fontStyle">
            <a-select-option value="italic"> italic </a-select-option>
            <a-select-option value="normal"> normal </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item :label="t('对齐方式')">
          <a-radio-group v-model:value="data.options.align" button-style="solid">
            <a-radio-button value="left">{{ t('左对齐') }}</a-radio-button>
            <a-radio-button value="center">{{ t('居中对齐') }}</a-radio-button>
            <a-radio-button value="right">{{ t('右对齐') }}</a-radio-button>
          </a-radio-group>
        </a-form-item>
      </template>

      <template v-if="data.type === 'grid'">
        <a-form-item :label="t('栅格间隔')">
          <a-input-number v-model:value="data.options.gutter" :min="0" />
        </a-form-item>
        <div class="top-box">
          <div>列配置项</div>
          <PlusCircleFilled class="add-btn" @click="handleInsertColumn" />
        </div>
        <div class="config-box">
          <div v-for="(item, index) in data.layout" :key="index" class="coll-box">
            <a-input-number
              :placeholder="t('栅格值')"
              size="small"
              v-model:value="item.span"
              :min="0"
              :max="24"
            />
            <!-- <DragOutlined class="draggable-icon" /> -->
            <MinusCircleFilled @click.stop="handleOptionsRemove(index)" class="delete-btn" />
          </div>
        </div>

        <a-form-item :label="t('垂直对齐')" class="vertical-box" :wrapperCol="{ span: 24 }">
          <a-radio-group v-model:value="data.options.align" button-style="solid">
            <a-radio-button value="top">{{ t('顶部对齐') }}</a-radio-button>
            <a-radio-button value="middle">{{ t('居中对齐') }}</a-radio-button>
            <a-radio-button value="bottom">{{ t('底部对齐') }}</a-radio-button>
          </a-radio-group>
        </a-form-item>

        <a-form-item :label="t('水平排列')">
          <a-select v-model:value="data.options.justify">
            <a-select-option value="start">{{ t('左对齐') }}</a-select-option>
            <a-select-option value="end">{{ t('右对齐') }}</a-select-option>
            <a-select-option value="center">{{ t('居中') }}</a-select-option>
            <a-select-option value="space-around">{{ t('两侧间隔相等') }}</a-select-option>
            <a-select-option value="space-between">{{ t('两端对齐') }}</a-select-option>
          </a-select>
        </a-form-item>
      </template>
      <a-form-item :label="t('内边距')" v-if="hasKey('padding')">
        <a-input v-model:value="data.options.padding" placeholder="例如：0 或 10px 或 10px 20px" />
      </a-form-item>
      <a-form-item :label="t('外边距')" v-if="hasKey('margin')">
        <a-input v-model:value="data.options.margin" placeholder="例如：0 或 10px 或 10px 20px" />
      </a-form-item>
      <template v-if="data.type === 'tab'">
        <div class="top-box">
          <div>选项卡配置</div>
          <PlusCircleFilled class="add-btn" @click="handleInsertColumn" />
        </div>
        <div class="config-box">
          <div v-for="(item, index) in data.layout" :key="index" class="coll-box">
            <a-input
              :placeholder="t('选项卡名称')"
              size="small"
              v-model:value="item.name"
              :min="0"
              :max="24"
            />

            <a-popover :title="t('高级设置')" placement="topLeft" trigger="click">
              <template #content>
                <a-form-item :label="t('前置图标')">
                  <IconPicker v-model:value="item.prefix" />
                </a-form-item>

                <a-form-item :label="t('后置图标')">
                  <IconPicker v-model:value="item.suffix" />
                </a-form-item>
                <a-form-item :label="t('选中色')" :colon="false" labelAlign="left">
                  <SelectColor v-model:value="item.activeColor" style="min-width: 200px" />
                </a-form-item>
                <a-form-item :label="t('页签背景图')" :colon="false" labelAlign="left">
                  <a-input
                    v-model:value="item.imageUrl"
                    :disabled="true"
                    style="margin-bottom: 10px"
                  />
                  <a-upload
                    action=""
                    :beforeUpload="
                      (file) => {
                        tabBgUpload(file, index);
                      }
                    "
                    accept=""
                    :max-count="1"
                    :show-upload-list="false"
                  >
                    <a-button type="primary">
                      {{ t('点击上传') }}
                    </a-button>
                  </a-upload>
                </a-form-item>
                <a-form-item :label="t('内容区背景图')" :colon="false" labelAlign="left">
                  <a-input
                    v-model:value="item.conImageUrl"
                    :disabled="true"
                    style="margin-bottom: 10px"
                  />
                  <a-upload
                    action=""
                    :beforeUpload="
                      (file) => {
                        tabBgUpload(file, index, 2);
                      }
                    "
                    accept=""
                    :max-count="1"
                    :show-upload-list="false"
                  >
                    <a-button type="primary">
                      {{ t('点击上传') }}
                    </a-button>
                  </a-upload>
                </a-form-item>
              </template>
              <Icon icon="icon-park-solid:setting-two" :size="24" class="draggable-icon" />
            </a-popover>
            <DragOutlined class="draggable-icon" />
            <MinusCircleFilled @click.stop="handleOptionsRemove(index)" class="delete-btn" />
          </div>
        </div>
        <a-form-item :label="t('选项卡风格')" class="vertical-box" :wrapperCol="{ span: 24 }">
          <a-radio-group button-style="solid" v-model:value="data.options.type">
            <a-radio-button value="line">line</a-radio-button>
            <a-radio-button value="card">card</a-radio-button>
          </a-radio-group>
        </a-form-item>

        <a-form-item :label="t('选项卡位置')" class="vertical-box" :wrapperCol="{ span: 24 }">
          <a-radio-group button-style="solid" v-model:value="data.options.tabPosition">
            <a-radio-button value="top">{{ t('顶部') }}</a-radio-button>
            <a-radio-button value="right">{{ t('右侧') }}</a-radio-button>
            <a-radio-button value="bottom">{{ t('底部') }}</a-radio-button>
            <a-radio-button value="left">{{ t('左侧') }}</a-radio-button>
          </a-radio-group>
        </a-form-item>
      </template>
    </a-form>
    <ApiConfig
      v-if="apiConfigDialog"
      v-model:apiConfigDialog="apiConfigDialog"
      v-model:apiConfig="data.options.apiConfig"
      :isCascader="isCascader"
      :isQrcode="isQrcode"
      :formItem="data"
      :title="isCascader ? t('级联配置-API') : t('API配置')"
    />
    <ApiAssoConfig
      v-if="apiAssoDia"
      v-model:apiAssoDia="apiAssoDia"
      v-model:apiConfig="data.options.apiConfig"
      type="preload-title"
    />
    <DicAssoConfig
      v-if="dicAssoDia"
      v-model:dicAssoDia="dicAssoDia"
      v-model:dicOptions="data.options.dicOptions"
      type="preload-title"
    />
    <CustomScript
      v-if="customDia"
      v-model:customDia="customDia"
      v-model:script="data.options.content"
      v-model:id="data.options.id"
      :customComponentList="customComponentList"
    />
    <IframeConfig
      v-if="iframeConfigDia"
      v-model:iframeConfigDia="iframeConfigDia"
      v-model:list="data.options.list"
    />
    <ModalConfig
      v-if="modalConfigDia"
      v-model:modalConfigDia="modalConfigDia"
      v-model:list="data.options.innerParams"
      :formJson="modalConfigFormJson"
      type="inner"
      :from="data.isSubFormChild ? 'table' : undefined"
    />
    <ModalConfig
      v-if="modalOutConfigDia"
      v-model:modalConfigDia="modalOutConfigDia"
      v-model:list="data.options.outParams"
      :formJson="modalConfigFormJson"
      type="out"
      :from="data.isSubFormChild ? 'table' : undefined"
    />
    <TreeApiConfig
      v-if="treeConfigDia"
      v-model:modalConfigDia="treeConfigDia"
      v-model:list="data.options.treeConfig.innerParams"
      :formJson="widgetForm?.list"
      :curCompKey="data.key"
    />
    <ModalSelect
      v-if="modalSelectDia"
      v-model:multipleDialog="modalSelectDia"
      v-model:value="data.options.bindModal"
      @submit="bindModalChange"
    />
    <ColunmWidthConfig
      v-if="widthConfigDialog"
      v-model:visible="widthConfigDialog"
      :dataSource="data.children || data.tableColumns"
      :type="data.type"
      v-model:widths="data.options.widths"
    />
  </div>
</template>

<script lang="ts">
  import { defineComponent, inject, Ref, ref, watch, onMounted, nextTick, computed, h } from 'vue';
  import { DragOutlined, PlusCircleFilled, MinusCircleFilled } from '@ant-design/icons-vue';
  // import Draggable from 'vuedraggable';
  import { SvgIcon, IconPicker, Icon } from '/@/components/Icon';
  import {
    FieldInfo,
    noHaveTableAndField,
    noHaveField,
    noHaveTitle,
    TableInfo,
    unPreloadComponents,
    needDicDefaultValue,
    filterType,
    unListViewComponents,
    CommonInfoType,
  } from '../../types';
  import { getDicDetailList } from '/@/api/system/dic';
  import { getCodeRule } from '/@/api/system/code';
  // import { useUserStore } from '/@/store/modules/user';
  import { Button, message, notification } from 'ant-design-vue';
  import type { SelectProps } from 'ant-design-vue';
  import DataSourceSetting from './settings/DataSourceSetting.vue';
  import ApiAssoConfig from './settings/ApiAssoConfig.vue';
  import DicAssoConfig from './settings/DicAssoConfig.vue';
  import ComputationalSetting from './settings/ComputationalSetting.vue';
  // import StaticData from './settings/StaticData.vue';
  import StyleConfiguration from './settings/StyleConfiguration.vue';
  import LabelComponentApiConfig from './settings/LabelComponentApiConfig.vue';
  import CustomScript from './settings/CustomScript.vue';
  import IframeConfig from './settings/IframeConfig.vue';
  import ModalConfig from './settings/ModalConfig.vue';
  import ModalSelect from './settings/ModalSelect.vue';
  import TreeApiConfig from './settings/TreeApiConfig.vue';
  import ApiConfig from '/@/components/ApiConfig/src/ApiConfig.vue';
  // import { DicItemSelect } from '/@/components/DicItemSelect';
  import SelectColor from '/@/views/mobileDesign/dataDesign/components/designer/properties/SelectColor.vue';
  import { ColorPicker } from '/@/components/ColorPicker';
  import { TimePicker } from '/@/components/TimePicker';
  import { XjrDatePicker } from '/@/components/DatePicker';
  import { DicTreeSelect } from '/@/components/DicTreeSelect';
  import Sortable from 'sortablejs';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { changeToPinyin, formatter, getFileUrl } from '/@/utils/event/design';
  import { cloneDeep, random, isNumber } from 'lodash-es';
  import { uploadMultiApi } from '/@/api/sys/upload';
  import { getFileList } from '/@/api/system/file';
  import { geList, getInfo } from '/@/api/system/generator/treeStructure';
  import { SelectUser, SelectRole } from '/@/components/SelectOrganizational/index';
  import { isNullAndUnDef } from '/@/utils/is';
  import { GeneratorConfig } from '/@/model/generator/generatorConfig';
  import ButtonModalConfig from '/@/components/CreateCodeStep/src/components/ButtonModalConfig.vue';
  import { CustomButtonModalType } from '/@/enums/userEnum';
  import { ColumnType } from '/@/components/Designer/src/types';
  import { getModalManage } from '/@/api/dataconfig/modalmanage';
  import ColunmWidthConfig from './settings/colunmWidthConfig.vue';
  import { TreeStructureType } from '/@/enums/treeStructure';
  const { t } = useI18n();
  export default defineComponent({
    name: 'PropertyOption',
    components: {
      // Draggable,
      SvgIcon,
      SelectColor,
      IconPicker,
      Icon,
      DataSourceSetting,
      ComputationalSetting,
      // StaticData,
      ApiConfig,
      // DicItemSelect,
      DragOutlined,
      ColorPicker,
      TimePicker,
      XjrDatePicker,
      DicTreeSelect,
      ApiAssoConfig,
      StyleConfiguration,
      LabelComponentApiConfig,
      IframeConfig,
      DicAssoConfig,
      SelectUser,
      SelectRole,
      PlusCircleFilled,
      MinusCircleFilled,
      CustomScript,
      ModalConfig,
      ModalSelect,
      ColunmWidthConfig,
      TreeApiConfig,
      ButtonModalConfig,
    },
    props: {
      //所选组件配置
      select: {
        type: Object,
      },
      widgetForm: {
        type: Object,
      },
      customComponentList: {
        type: Array,
      },
    },
    emits: ['update:select'],
    setup(props, context) {
      const tableInfo = inject<Ref<TableInfo[]>>('tableInfo') as Ref<TableInfo[]>;
      const designType = inject<string>('designType');
      const isFieldUpper = inject<Ref<boolean>>('isFieldUpper', ref(false));
      const generatorConfig = inject<GeneratorConfig>('generatorConfig');

      const mapComps = ref<any[]>([]); //地图可以映射的组件
      const modalConfigFormJson = ref<any[]>([]); //弹窗组件所在表单JSON
      const checkFlag = (o) => {
        return !filterType?.includes(o.type);
      };
      watch(
        () => props.widgetForm,
        (val) => {
          let curComp: any = props.select;
          if (curComp?.type && val) {
            getMapRelationComps(curComp, val?.list);
            initDetailList(val);
          }
        },
        { deep: true, immediate: true },
      );

      // 根据组件类型查询数据字段列表

      const changedFieldsInfo = computed(() => {
        // 需要字符串字段类型的组件
        // 单行文本 多行文本 密码 编辑器 自动完成 编码组件 手写签名 人员选择
        // 下拉选择框 树选择 级联选择器 联想下拉 联想弹层 多选弹层 行政区域 多选组件 单选组件
        // 颜色选择 上传组件 图片组件 地图选择 树形组件
        // 信息体 组织架构 人员选择
        const stringComponents = [
          'input',
          'textarea',
          'password',
          'richtext-editor',
          'auto-complete',
          'auto-code',
          'signature',
          'select',
          'tree-select-component',
          'cascader',
          'associate-select',
          'associate-popup',
          'multiple-popup',
          'area',
          'checkbox',
          'radio',
          'picker-color',
          'upload',
          'image',
          'map',
          'tree-component',
          'info',
          'organization',
          'user',
          'role',
        ];
        // 需要数字类型字段类型的组件
        //  开关组件  滑块组件 评分组件 计算组件 货币大写
        const numberComponents = [
          'switch',
          'slider',
          'rate',
          'computational',
          'money-chinese',
          'number',
        ];
        // 需要时间类型字段类型的组件 时间选择 时间范围
        const timeComponents = ['time', 'time-range'];
        // 需要日期类型字段类型的组件 日期选择 日期范围
        const dateComponents = ['date', 'date-range'];

        if (fieldsInfo.value && fieldsInfo.value.length > 0) {
          if (stringComponents.includes(data.value.type)) {
            return fieldsInfo.value.filter(function (field) {
              if (data.value.type === 'info') {
                return (
                  (field.type == ColumnType.STRING ||
                    field.type == ColumnType.LONG ||
                    field.type == ColumnType.DATE) &&
                  !field.isPk
                );
              } else {
                let flag =
                  field.type == ColumnType.STRING ||
                  field.type == ColumnType.LONG ||
                  field.type == ColumnType.KEY ||
                  field.type == ColumnType.LONGTEXT;
                return data.value.type === 'input' ? flag : flag && !field.isPk;
              }
            });
          } else if (numberComponents.includes(data.value.type)) {
            return fieldsInfo.value.filter(function (field) {
              return (
                (field.type == ColumnType.NUMBER ||
                  field.type == ColumnType.DIGITAL ||
                  field.type == ColumnType.LONG) &&
                !field.isPk
              );
            });
          } else if (timeComponents.includes(data.value.type)) {
            return fieldsInfo.value.filter(function (field) {
              return field.type == ColumnType.TIME && !field.isPk;
            });
          } else if (dateComponents.includes(data.value.type)) {
            return fieldsInfo.value.filter(function (field) {
              return (
                (field.type == ColumnType.DATE || field.type == ColumnType.DATETIME) && !field.isPk
              );
            });
          } else {
            return fieldsInfo.value;
          }
        } else {
          return [];
        }
      });

      const data = ref<any>();
      const fieldsInfo = ref<FieldInfo[]>([]); //所选表字段
      const remoteOptions = ref<Recordable>([]);
      const remoteDefaultOptions = ref<Recordable[]>([]);
      const codeRuleOptions = ref<any>([]);
      const SignSelectOption = ref<SelectProps['options']>([]);
      const SignValueOption = [
        {
          value: 0,
          label: '角色',
        },
        {
          value: 1,
          label: '人员',
        },
      ];
      // const userStore = useUserStore();
      const computationalDialog = ref<boolean>(false);
      const layout = {
        labelCol: { span: 8 },
        wrapperCol: { span: 16 },
        labelAlign: 'left',
        colon: false,
      };
      const apiConfigDialog = ref<boolean>(false);
      const apiAssoDia = ref<boolean>(false);
      const dicAssoDia = ref<boolean>(false);
      const customDia = ref<boolean>(false);
      const widthConfigDialog = ref<boolean>(false);
      const iframeConfigDia = ref<boolean>(false);
      const modalConfigDia = ref<boolean>(false);
      const modalOutConfigDia = ref<boolean>(false);
      const modalSelectDia = ref<boolean>(false);
      const treeConfigDia = ref<boolean>(false);
      const isCascader = ref<boolean>(false);
      const isQrcode = ref<boolean>(false);
      const defaultSelectOption = ref<any>([]);
      const userNames = ref<string>();
      const roleNames = ref<string>();
      const buttonTableOptions = ref<any>([]);

      const formatOptions = [
        {
          label: t('显示全部结果'),
          value: 'all',
        },
        {
          label: t('显示最子级结果'),
          value: 'showMostChildLevel',
        },
      ];
      const separatorOptions = [
        {
          label: '/',
          value: '/',
        },
        {
          label: '--',
          value: '--',
        },
        {
          label: '|',
          value: '|',
        },
      ];
      const selectedOptions = [
        {
          label: t('必须选择到最子级'),
          value: 'selectMostChildLevel',
        },
        {
          label: t('可以选到任意一级'),
          value: 'any',
        },
      ];

      const listViewColumns = [
        {
          dataIndex: 'sort',
        },
        {
          title: '显示',
          dataIndex: 'checked',
          align: 'center',
          width: '30%',
        },
        {
          title: '组件名称',
          dataIndex: 'label',
          width: '60%',
        },
      ];
      let treeSelectOption = ref([]);
      const viewTableKey = ref<number>(0);

      const relationOptions = computed(() => {
        const info = tableInfo.value.find((x) => x.name === data.value.bindTable);
        return info?.fields || [];
      });
      const relationTableOptions = computed(() => {
        const info = tableInfo.value.find((x) => x.name === data.value.parentTable);
        return info?.fields || [];
      });

      const configText = computed(() => {
        let preloadType = data.value.options.preloadType;
        if (data.value.type == 'button' && data.value.options.buttonType == 2) {
          preloadType = data.value.options.datasourceType;
        }
        const dicOptions = data.value.options.dicOptions;
        const outputParams = data.value.options.apiConfig?.outputParams;
        if (
          (preloadType === 'dic' && dicOptions?.length) ||
          (preloadType === 'api' && outputParams?.length)
        ) {
          return t('已配置');
        } else {
          return '';
        }
      });

      const iframeText = computed(() => {
        return data.value.options.list?.length ? t('已配置') : '';
      });
      const imageUrl = ref('');
      const handleTableChange = (value: string) => {
        const currentTable = tableInfo.value.find((table) => table.name === value)!;
        fieldsInfo.value = currentTable?.fields;
        if (data.value.type === 'sun-form') {
          const tableInfo = generatorConfig!.tableConfigs!.find((x) => x.tableName === value);
          if (tableInfo) {
            tableInfo!.parentTable = data.value.parentTable;
          }
        }
      };
      const selectedTables = ref<string[]>([]);

      watch(
        () => props.select,
        (val) => {
          //如果选择组件变化  首先判断它是否为子表单组件
          data.value = val;
          if (val?.type === 'form' || val?.type === 'one-for-one') {
            selectedTables.value = [];
            getSelectedTables(props.widgetForm?.list);
            tableInfo?.value.map((x) => {
              x.disabled =
                !!x.isMain ||
                !x.isSubForm ||
                (selectedTables.value.includes(x.name) && val.bindTable !== x.name);
            });
            if (val?.type == 'form') {
              if (data.value.options.isDeleteSelected === undefined) {
                data.value.options.isDeleteSelected = false;
              }
              if (data.value.options.showPagenation === undefined) {
                data.value.options.showPagenation = true;
              }
            }
          } else if (val?.type === 'sun-form') {
            tableInfo?.value.map((x) => {
              x.disabled = !!x.isMain || !!x.isSubForm;
            });
          } else {
            tableInfo?.value.map((x) => {
              x.disabled = !x.isMain;
            });
          }

          if (designType === 'data') {
            val?.bindTable ? handleTableChange(val?.bindTable) : (fieldsInfo.value = []); //没有选择数据表时 不展示数据字段
          }
          getMapRelationComps(val, props.widgetForm?.list);
          initDetailList(val);
          if (val?.type == 'button' && val?.options.buttonType == 2) {
            buttonTableOptions.value = [];
            getButtonRelatonTables(props.widgetForm?.list);
          }
          if (val?.type === 'image') {
            getImage();
          }
          if (val?.type === 'signature') {
            SignSelectOption.value = [];
            if (!val.options.defaultValue?.length) {
              userNames.value = '';
              roleNames.value = '';
            }
            getSignAssoComponents(props.widgetForm?.list);
          }
          if (val?.type === 'modal' || val?.type === 'drawer') {
            if (data.value.options.modalWidth === undefined)
              data.value.options.modalWidth = val.type === 'modal' ? '1000' : '50';
            if (data.value.options.modalWidthUnit === undefined)
              data.value.options.modalWidthUnit = val.type === 'modal' ? 'px' : '%';
            if (data.value.options.modalHeightUnit === undefined)
              data.value.options.modalHeightUnit = 'px';
            if (data.value.options.modalHeight === undefined)
              data.value.options.modalHeight = '500';
          }
          if (val?.type == 'time' || val?.type == 'date') {
            if (data.value.options.searchType === undefined) data.value.options.searchType = 'time';
          }
          if (val?.type == 'form-view') {
            if (data.value.options.rowResize === undefined) data.value.options.rowResize = false;
          }
        },
        {
          deep: true,
          immediate: true,
        },
      );
      watch(
        data,
        (val) => {
          context.emit('update:select', val);
        },
        {
          immediate: true,
          deep: true,
        },
      );
      watch(
        () => data.value.bindTable,
        (_, old) => {
          if (data.value.type === 'modal' && old) {
            data.value.options.outParams.forEach((o) => {
              o.mainComponent = '';
            });
          }
        },
      );
      watch(
        () => data.value.options.selectTable,
        () => {
          let curComp: any = cloneDeep(data.value);
          if (
            curComp?.type === 'button' &&
            curComp?.options.buttonType === 2 &&
            curComp?.options.selectTable
          ) {
            findBindTable(props.widgetForm?.list, curComp);
          }
        },
      );
      watch(
        () => data.value.options.latiAndLong,
        (val) => {
          if (data.value.type === 'map') {
            let arr = mapComps.value.filter((o) => {
              return o.bindField == val;
            });
            if (arr.length <= 0) {
              data.value.options.latiAndLong = null;
            }
          }
        },
      );
      watch(
        () => data.value.options.address,
        (val) => {
          if (data.value.type === 'map') {
            let arr = mapComps.value.filter((o) => {
              return o.bindField == val;
            });
            if (arr.length <= 0) {
              data.value.options.address = null;
            }
          }
        },
      );
      watch(
        () => data.value.options?.apiConfig,
        (val) => {
          if (val && !val?.path && Object.keys(val).length) {
            data.value.options.apiConfig = {};
          }
        },
        {
          deep: true,
        },
      );

      watch(
        () => data.value?.label,
        (curVal, oldVal) => {
          if (data.value.options.placeholder) {
            data.value.options.placeholder = oldVal
              ? data.value.options.placeholder.replace(oldVal, curVal)
              : data.value.options.placeholder + curVal;
          }
        },
      );
      watch(
        () => data.value.options.isShow,
        (val) => {
          if (data.value.options.required !== undefined && !val) {
            data.value.options.required = false;
          }
        },
      );

      function bindModalChange(val) {
        getModalManage(val).then((res) => {
          if (res) {
            let json = JSON.parse(res.configJson);
            if (json.innerParams?.length <= 0) {
              data.value.options.innerParams = json.innerParams;
            } else {
              let newParams: any = [];
              json.innerParams.forEach((o) => {
                let obj = data.value.options.innerParams.find((k) => {
                  return k.name == o.name;
                });
                if (obj) {
                  newParams.push(obj);
                } else {
                  newParams.push(o);
                }
              });
              data.value.options.innerParams = newParams;
            }
            if (json.outParams?.length <= 0) {
              data.value.options.outParams = json.outParams;
            } else {
              let newParams: any = [];
              json.outParams.forEach((o) => {
                let obj = data.value.options.outParams.find((k) => {
                  return k.name == o.name;
                });
                if (obj) {
                  newParams.push({
                    name: o.name,
                    component: o.component,
                    mainComponent: obj.mainComponent,
                  });
                } else {
                  newParams.push(o);
                }
              });
              data.value.options.outParams = newParams;
            }
          }
        });
      }

      onMounted(() => {
        getCodeRuleList();
        if (data.value.type === 'tab') {
          sortableColumn();
        }
        initTreeData();
      });

      watch(
        () => data.value.children,
        () => {
          getViewList();
        },
        {
          deep: true,
        },
      );

      watch(
        () => data.value.options?.viewList,
        () => {
          nextTick(() => {
            const tbody: any = document.querySelector('.view-table .ant-table-tbody');
            if (!tbody) return;
            Sortable.create(tbody, {
              handle: '.viewDraggable-icon',
              onEnd: ({ oldIndex, newIndex }) => {
                if (isNullAndUnDef(oldIndex) || isNullAndUnDef(newIndex) || newIndex === oldIndex) {
                  return;
                }
                const columns = cloneDeep(data.value.options.viewList);
                if (oldIndex > newIndex) {
                  columns.splice(newIndex, 0, columns[oldIndex]);
                  columns.splice(oldIndex + 1, 1);
                } else {
                  columns.splice(newIndex + 1, 0, columns[oldIndex]);
                  columns.splice(oldIndex, 1);
                }
                data.value.options.viewList = cloneDeep(columns);
                viewTableKey.value++;
              },
            });
          });
        },
        {
          deep: true,
        },
      );

      function getViewList() {
        if (data.value.type === 'form' && data.value.options.isListView) {
          const children = data.value.children.filter(
            (x) => !unListViewComponents.includes(x.type),
          );
          children.forEach((child) => {
            data.value.options.viewList.forEach((item) => {
              if (item.key === child.key) {
                item.label = child.label;
                item.field = child.bindField;
              }
            });
            const hasChild = data.value.options.viewList.some((item) => item.key === child.key);
            if (!hasChild && child.key) {
              const info = {
                key: child.key,
                label: child.label,
                field: child.bindField,
                componentType: child.type,
                checked: true,
              };
              if (child.type === 'time-range' || child.type === 'date-range') {
                data.value.options.viewList.push({
                  ...info,
                  label: child.label + '开始时间',
                  field: child.bindStartTime,
                });
                data.value.options.viewList.push({
                  ...info,
                  label: child.label + '结束时间',
                  field: child.bindEndTime,
                });
              } else {
                data.value.options.viewList.push(info);
              }
            }
          });
          data.value.options.viewList.forEach((child, index) => {
            const hasChild = children.some((item) => item.key === child.key);
            if (!hasChild) {
              data.value.options.viewList.splice(index, 1);
            }
          });
        }
      }

      function getSelectedTables(list) {
        list.forEach((x) => {
          if (['tab', 'grid', 'card'].includes(x.type)) {
            for (const child of x.layout!) {
              getSelectedTables(child.list);
            }
          } else if (x.type === 'table-layout') {
            for (const child of x.layout!) {
              for (const item of child.list) {
                getSelectedTables(item.children);
              }
            }
          } else if (['form', 'one-for-one'].includes(x.type) && x.bindTable) {
            selectedTables.value!.push(x.bindTable);
          }
        });
      }

      function getSignAssoComponents(list) {
        list.forEach((x) => {
          if (['tab', 'grid', 'card'].includes(x.type)) {
            for (const child of x.layout!) {
              getSignAssoComponents(child.list);
            }
          } else if (x.type === 'table-layout') {
            for (const child of x.layout!) {
              for (const item of child.list) {
                getSignAssoComponents(item.children);
              }
            }
          } else if (x.type === 'user' || x.type === 'role') {
            SignSelectOption.value!.push({
              label: x.label,
              value: x.key,
            });
          }
        });
      }
      function getTabMapRelaton(o, bindTable) {
        o.layout.forEach((k) => {
          if (k.list?.length > 0) {
            k.list.forEach((j) => {
              if (j.bindTable == bindTable && checkFlag(j)) {
                mapComps.value.push(j);
              } else if (j.type == 'tab' && j.layout?.length > 0) {
                getTabMapRelaton(j, bindTable);
              } else if (j.bindTable == bindTable && j.type == 'form' && j.children?.length > 0) {
                j.children.forEach((f) => {
                  if (f.bindTable == bindTable && checkFlag(f)) {
                    mapComps.value.push(f);
                  }
                });
              }
            });
          }
        });
      }
      function getMapRelationComps(curComp, list) {
        //获取地图可以映射的组件
        if (curComp.type == 'map') {
          mapComps.value = [];
          list?.forEach((o: any) => {
            if (o.bindTable == curComp.bindTable && checkFlag(o)) {
              mapComps.value.push(o);
            } else if (o.type == 'tab' && o.layout?.length > 0) {
              getTabMapRelaton(o, curComp.bindTable);
            } else if (
              o.bindTable == curComp.bindTable &&
              (o.type == 'form' || o.type == 'one-for-one') &&
              o.children?.length > 0
            ) {
              o.children.forEach((k) => {
                if (k.bindTable == curComp.bindTable && checkFlag(k)) {
                  mapComps.value.push(k);
                }
              });
            }
          });
        }
      }

      async function initDetailList(val) {
        if (needDicDefaultValue.includes(val.type)) {
          if (!val.options.itemId) {
            defaultSelectOption.value = [];
          } else {
            let res = await getDicDetailList({ itemId: val.options.itemId });
            defaultSelectOption.value = res;
          }
        }
      }
      function getButtonRelatonTables(list) {
        list.forEach((x) => {
          if (['tab', 'grid', 'card'].includes(x.type)) {
            for (const child of x.layout!) {
              getButtonRelatonTables(child.list);
            }
          } else if (x.type == 'table-layout') {
            for (const child of x.layout!) {
              for (const item of child.list) {
                getButtonRelatonTables(item.children);
              }
            }
          } else {
            if (x.type == 'form') {
              buttonTableOptions.value.push({
                key: x.key,
                bindTable: x.bindTable,
                label: x.label,
              });
            }
          }
        });
      }
      const sortableColumn = () => {
        nextTick(() => {
          const tbody: any = document.querySelector('.awc-containter .config-box');
          Sortable.create(tbody, {
            handle: '.draggable-icon',
            onEnd: ({ oldIndex, newIndex }) => {
              const columns = cloneDeep(data.value.layout);
              if (oldIndex! > newIndex!) {
                columns.splice(newIndex, 0, columns[oldIndex!]);
                columns.splice(oldIndex! + 1, 1);
              } else {
                columns.splice(newIndex! + 1, 0, columns[oldIndex!]);
                columns.splice(oldIndex, 1);
              }
              data.value.layout = cloneDeep(columns);
            },
          });
        });
      };

      const hasKey = (key: string) => Object.keys(data.value.options).includes(key);

      const handleInsertColumn = () => {
        data.value.layout.push({
          span: 0,
          list: [],
        });
        if (data.value.type === 'tab') {
          sortableColumn();
        }
      };

      const showApiConfig = (cascader = false) => {
        apiConfigDialog.value = true;
        isCascader.value = cascader;
      };
      const handleApiConfig = () => {
        apiConfigDialog.value = true;
        isQrcode.value = true;
      };
      const showWidthConfig = () => {
        widthConfigDialog.value = true;
      };
      const formatChange = () => {
        data.value.options.defaultValue = '';
      };

      const handleOptionsRemove = (index: number) => {
        if (data.value.type === 'grid' || data.value.type === 'tab') {
          data.value.layout.splice(index, 1);
        } else {
          data.value.options.staticOptions.splice(index, 1);
        }
      };

      const handleSelectModeChange = (event: any) => {
        const { value } = event.target;
        if (value === null) {
          data.value.options.defaultValue.length
            ? (data.value.options.defaultValue = data.value.options.defaultValue[0])
            : (data.value.options.defaultValue = null);
        } else {
          if (data.value.options.defaultValue) {
            if (!(data.value.options.defaultValue instanceof Array)) {
              data.value.options.defaultValue = [data.value.options.defaultValue];
            }
          } else {
            data.value.options.defaultValue = [];
          }
        }
      };

      const handleSliderModeChange = (checked: boolean) => {
        checked
          ? (data.value.options.defaultValue = [0, 0])
          : (data.value.options.defaultValue = 0);
      };

      const tableTitleClick = () => {
        if (
          data.value.options.preloadType === 'dic' ||
          (data.value.type == 'button' &&
            data.value.options.buttonType == 2 &&
            data.value.options.datasourceType == 'dic')
        ) {
          dicAssoDia.value = true;
        } else if (
          data.value.options.preloadType === 'api' ||
          (data.value.type == 'button' &&
            data.value.options.buttonType == 2 &&
            data.value.options.datasourceType == 'api')
        ) {
          apiAssoDia.value = true;
        }
      };

      const handleDicChange = async (value: string) => {
        const result = await getDicDetailList({ itemId: value });

        remoteDefaultOptions.value = result.map((item) => ({
          label: item.name,
          value: item.id,
        }));
      };

      const preloadChange = () => {
        if (data.value.type === 'form') {
          data.value.children.map((item) => {
            if (!unPreloadComponents.includes(item.type)) {
              return (item.options.prestrainField = '');
            }
          });
        }
      };

      const changeBtnName = (e) => {
        data.value.label = e.target.value;
      };

      const getCodeRuleList = async () => {
        const result = await getCodeRule();
        codeRuleOptions.value = result;
      };

      const handleApiInputFocus = () => {
        const { labelField, valueField, api } = data.value.options.props;
        // 如果三个条件  某一个为空 都不执行
        if (!labelField || !valueField || !api) return;

        fetch(api, {})
          .then((resp) => resp.json())
          .then((json) => {
            if (Array.isArray(json)) {
              data.value.options.staticOptions = json.map((res: any) => ({
                label: res[labelField],
                value: res[valueField],
              }));
            } else {
              // 最多显示不超过100
              if (json.data.length > 100) {
                json.data.length = 100;
              }
              data.value.options.staticOptions = json.data.map((res: any) => ({
                label: res[labelField],
                value: res[valueField],
              }));
            }
          })
          .catch((_) => {
            data.value.options.staticOptions = [
              {
                label: 'datasource_1',
                value: 'datasource_1',
              },
              {
                label: 'datasource_2',
                value: 'datasource_2',
              },
            ];
          });
      };

      const getFieldType = (type: number): string => {
        switch (type) {
          case ColumnType.NUMBER:
            return 'Integer';
          case ColumnType.DATE:
          case ColumnType.DATETIME:
            return 'LocalDateTime';
          case ColumnType.TIME:
            return 'Time';
          case ColumnType.LONG:
          case ColumnType.KEY:
            return 'long';
          case ColumnType.DIGITAL:
            return 'Double';
          default:
            return 'string';
        }
      };
      const changeReadonly = (checked: Boolean) => {
        if (checked) {
          hasKey('allowClear') ? (data.value.options.allowClear = false) : '';
          hasKey('required') ? (data.value.options.required = false) : '';
        }
      };
      const changeDisabled = (checked: Boolean) => {
        if (checked) {
          hasKey('readonly') ? (data.value.options.readonly = true) : '';
          hasKey('allowClear') ? (data.value.options.allowClear = false) : '';
          hasKey('required') ? (data.value.options.required = false) : '';
        }
      };
      const changeNumber = () => {
        if (data.value.type !== 'number') return;
        const minNum = data.value.options.min;
        const maxNum = data.value.options.max;
        const value = data.value.options.defaultValue;
        if (isNumber(maxNum) && minNum > maxNum) {
          message.error(t('计数器最小值只能小于等于最大值'));
          data.value.options.min = data.value.options.max - 1;
        } else if (isNumber(value) && minNum > value) {
          message.error(t('计数器默认值不能小于最小值'));
          data.value.options.defaultValue = '';
        } else if (isNumber(maxNum) && value > maxNum) {
          message.error(t('计数器默认值不能大于最大值'));
          data.value.options.defaultValue = '';
        }
      };
      const submitCardBgUpload = (file) => {
        const folderId = '';
        uploadMultiApi(
          {
            name: 'file',
            file: [file],
          },
          folderId,
        ).then((res) => {
          data.value.options.cardStyle.background.bgImgUrl = res[0].fileUrl;
        });
      };
      const submitCardContentBgUpload = (file) => {
        const folderId = '';
        uploadMultiApi(
          {
            name: 'file',
            file: [file],
          },
          folderId,
        ).then((res) => {
          data.value.options.cardStyle.content.bgImgUrl = res[0].fileUrl;
        });
      };
      const submitUpload = (file) => {
        // let action = getAppEnvConfig().VITE_GLOB_API_URL + '/system/file';
        // const formData = new FormData();
        // formData.append('file', file.file);
        // formData.append('remark', '上传');
        // const xhr = new XMLHttpRequest();
        // xhr.open('post', action, true);
        // xhr.setRequestHeader('Authorization', 'Bearer ' + userStore.getToken);
        // xhr.onload = () => {
        //   const response = JSON.parse(xhr.response);
        //   console.log(response);
        //   data.value.options.defaultValue = response.data;
        // };
        // xhr.onerror = () => {
        //   console.log(t('上传失败'));
        // };
        // xhr.ontimeout = function timeout() {
        //   console.log(t('上传超时'));
        // };
        // xhr.send(formData);
        let folderId = data.value.options.defaultValue;
        uploadMultiApi(
          {
            name: 'file',
            file: [file],
          },
          folderId,
        ).then((res) => {
          data.value.options.defaultValue = res[0].folderId;
          getImage();
        });
      };

      const tabBgUpload = (file, index, type?) => {
        let folderId =
          (type == 2 ? data.value.layout[index].conFolderId : data.value.layout[index].folderId) ||
          '';
        uploadMultiApi(
          {
            name: 'file',
            file: [file],
          },
          folderId,
        ).then((res) => {
          if (type == 2) {
            data.value.layout[index].conImageUrl = res[0].fileUrl;
            data.value.layout[index].conFolderId = res[0].folderId;
          } else {
            data.value.layout[index].imageUrl = res[0].fileUrl;
            data.value.layout[index].folderId = res[0].folderId;
          }
        });
      };

      async function getImage() {
        if (data.value.options.defaultValue) {
          let fileList = await getFileList({ folderId: data.value.options.defaultValue });
          if (fileList.length) {
            imageUrl.value = getFileUrl(fileList[0]);
            data.value.options.defaultValue = fileList[0].folderId;
          }
        } else {
          imageUrl.value = '';
        }
      }

      function handleChangeCode() {
        data.value.options.defaultValue = '';
      }

      async function initTreeData() {
        let res: any = await geList();
        treeSelectOption.value = res;
      }

      function handleSpanChange(val) {
        if (val === null) val = '';
      }

      function formatterVal(value) {
        return formatter(value, data.value.options.decimals);
      }

      async function handleDfValueFocus(open) {
        if (open && needDicDefaultValue.includes(data.value.type)) {
          if (!data.value.options.itemId) {
            notification.error({
              message: t('提示'),
              description: t('请先选择数据选项后再选择默认值'),
            });
            defaultSelectOption.value = [];
          } else {
            let res = await getDicDetailList({ itemId: data.value.options.itemId });
            defaultSelectOption.value = res;
          }
        }
      }
      function handleDfValChange(e) {
        data.value.options.defaultSelect = e.join(',');
      }
      function handleIsSave(e) {
        data.value.options.disabled = e;
        if (
          designType == 'data' &&
          data.value.type == 'input' &&
          data.value.options.isSave !== undefined
        ) {
          data.value.bindField = e
            ? changeToPinyin(data.value.label, isFieldUpper.value) + random(1000, 9999)
            : null;
          //if (e) data.value.bindTable = null;
        }
      }
      function findBindTable(list, curComp) {
        list.forEach((x) => {
          if (['tab', 'grid', 'card'].includes(x.type)) {
            for (const child of x.layout!) {
              findBindTable(child.list, curComp);
            }
          } else if (x.type == 'table-layout') {
            for (const child of x.layout!) {
              for (const item of child.list) {
                findBindTable(item.children, curComp);
              }
            }
          } else {
            if (
              x.type === 'form' &&
              x.key == curComp.options.selectTable &&
              curComp.options.selectTable
            ) {
              let columns = cloneDeep(curComp.options.tableColumns);
              data.value.options.tableColumns = [];
              x.children.forEach((o) => {
                let obj = columns.find((k) => k.key == o.key);
                if (obj) {
                  data.value.options.tableColumns.push({
                    key: o.key,
                    bindField: o.bindField,
                    bindTable: x.bindTable,
                    prestrainField: obj.prestrainField,
                    label: o.label,
                    type: o.type,
                  });
                } else {
                  data.value.options.tableColumns.push({
                    key: o.key,
                    bindField: o.bindField,
                    bindTable: x.bindTable,
                    prestrainField: null,
                    label: o.label,
                    type: o.type,
                  });
                }
              });
            }
          }
        });
      }

      function handlePreChange(info) {
        getButtonRelatonInfo(props.widgetForm?.list, info);
      }

      function getButtonRelatonInfo(list, info) {
        list.forEach((x) => {
          if (x.type == 'form' && x.bindTable === info.bindTable) {
            getButtonRelatonInfo(x.children, info);
          } else if (x.bindField === info.bindField) {
            if (x.type === 'associate-popup' || x.type === 'associate-select') {
              x.options.prestrainField = info.prestrainField;
            }
          }
        });
      }

      function handleRelationChange(val) {
        const tableInfo = generatorConfig!.tableConfigs!.find(
          (x) => x.tableName === data.value.bindTable,
        );
        tableInfo!.relationField = val;
      }

      function handleRelationTableChange(val) {
        const tableInfo = generatorConfig!.tableConfigs!.find(
          (x) => x.tableName === data.value.bindTable,
        );
        tableInfo!.relationTableField = val;
      }

      const handleIframeConfig = () => {
        iframeConfigDia.value = true;
      };
      const handleModalConfig = (val) => {
        if (val == 1 || val == 2) {
          let list = props.widgetForm?.list || [];
          modalConfigFormJson.value = data.value.isSubFormChild
            ? getTableComponents(list, data.value.bindTable)
            : list;
        }

        if (val == 1) modalConfigDia.value = true;
        else if (val == 2) modalOutConfigDia.value = true;
        else modalSelectDia.value = true;
      };
      async function handleTreeConfig() {
        if (!data.value.options.treeConfig?.id) return;
        let formState = await getInfo(data.value.options.treeConfig?.id);
        let config = JSON.parse(formState.config);

        let temp = cloneDeep(data.value.options.treeConfig.innerParams);
        if (formState.type == TreeStructureType.API) {
          let arr: any = [];
          config.apiData.apiConfig.requestParamsConfigs.forEach((o) => {
            if (o.assignmentType == 'value') {
              arr.push({
                key: 'requestParamsConfigs',
                title: 'Query Params',
                name: o.name,
                bindComp: findCurComp(o.name, temp),
              });
            }
          });
          config.apiData.apiConfig.requestHeaderConfigs.forEach((o) => {
            if (o.assignmentType == 'value') {
              arr.push({
                key: 'requestHeaderConfigs',
                title: 'Header',
                name: o.name,
                bindComp: findCurComp(o.name, temp),
              });
            }
          });
          config.apiData.apiConfig.requestBodyConfigs.forEach((o) => {
            if (o.assignmentType == 'value') {
              arr.push({
                key: 'requestBodyConfigs',
                title: 'Body',
                name: o.name,
                bindComp: findCurComp(o.name, temp),
              });
            }
          });
          data.value.options.treeConfig.innerParams = arr;
        }
        treeConfigDia.value = true;
      }
      function findCurComp(name, list) {
        let obj = list.find((o) => o.name == name);
        return obj ? obj.bindComp : '';
      }
      function customCompTypeChange(e) {
        if (e == 'vue' || e == 'html') {
          data.value.options.compUrl = '';
        } else {
          data.value.options.content = '';
        }
      }

      function handleFieldChange(_, opt) {
        let msg = '';
        if (data.value.type == 'select') {
          if (Number(opt.length) < 19) {
            msg = t('当前绑定字段长度不满足主键类型字节长度，可能存在风险，请确认是否选择？');
          }
        } else if (data.value.type == 'textarea' || data.value.type == 'richtext-editor') {
          if (Number(opt.length) < 200) {
            msg = t(
              '当前绑定字段长度不满足长文本至少200的字节长度，可能存在风险，请确认是否选择？',
            );
          }
        } else {
          msg = '';
        }
        if (msg) {
          const key = `open${Date.now()}`;
          notification.open({
            message: t('提示'),
            description: msg,
            btn: () =>
              h(
                Button,
                {
                  type: 'primary',
                  size: 'small',
                  onClick: () => notification.close(key),
                },
                { default: () => t('确认') },
              ),
            key,
            duration: null,
            onClose: () => {
              data.value.bindField = '';
            },
          });
        }
      }
      function hasSunform(data) {
        let obj = data.find((o) => {
          return o.type == 'sun-form';
        });
        return obj ? true : false;
      }

      const getTableComponents = (schemaArr, table) => {
        let schema;
        const formListComponent = ['tab', 'grid', 'card'];
        schemaArr?.some((info) => {
          if (formListComponent.includes(info.type!)) {
            const hasComponent = info.children.some((childInfo) => {
              schema = childInfo.list.find((com) => {
                return ['form'].includes(com.type) && com.bindTable == table;
              });
              if (!!schema) return true;
              schema = getTableComponents(childInfo.list, table);
              return !!schema;
            });
            return !!hasComponent;
          } else if (info.type === 'table-layout') {
            const hasComponent = info.children.some((childInfo) => {
              return childInfo.list.some((chil) => {
                schema = chil.children.find((com) => {
                  return ['form'].includes(com.type) && com.bindTable == table;
                });
                if (!!schema) return true;
                schema = getTableComponents(chil.children, table);
                return !!schema;
              });
            });
            return !!hasComponent;
          } else if (info.type === 'form') {
            if (info.bindTable == table) {
              schema = info.children;
              return true;
            } else {
              const hasComponent = info.children.some((childInfo) => {
                if (['sun-form'].includes(childInfo.type) && childInfo.bindTable == table) {
                  schema = childInfo.children;
                  return true;
                } else {
                  return false;
                }
              });
              return !!hasComponent;
            }
          }
        });
        if (schema) schema = schema.filter((o) => !['modal', 'sun-form'].includes(o.type));
        return schema || [];
      };
      return {
        data,
        hasKey,
        handleInsertColumn,
        handleOptionsRemove,
        handleSelectModeChange,
        handleSliderModeChange,
        handleTableChange,
        handleApiInputFocus,
        handleDicChange,
        showApiConfig,
        showWidthConfig,
        getFieldType,
        getCodeRule,
        changeReadonly,
        changeDisabled,
        changeNumber,
        handleDfValueFocus,
        handleDfValChange,
        submitUpload,
        tableTitleClick,
        apiConfigDialog,
        widthConfigDialog,
        apiAssoDia,
        dicAssoDia,
        isCascader,
        configText,
        noHaveTableAndField,
        unPreloadComponents,
        needDicDefaultValue,
        defaultSelectOption,
        preloadChange,
        formatChange,
        noHaveField,
        noHaveTitle,
        tableInfo,
        fieldsInfo,
        changedFieldsInfo,
        designType,
        isFieldUpper,
        remoteOptions,
        remoteDefaultOptions,
        codeRuleOptions,
        computationalDialog,
        layout,
        formatOptions,
        separatorOptions,
        selectedOptions,
        mapComps,
        handleApiConfig,
        isQrcode,
        handleChangeCode,
        handleSpanChange,
        handleIsSave,
        buttonTableOptions,
        t,
        imageUrl,
        treeSelectOption,
        SignSelectOption,
        SignValueOption,
        SelectUser,
        userNames,
        roleNames,
        formatterVal,
        listViewColumns,
        getViewList,
        viewTableKey,
        CommonInfoType,
        handlePreChange,
        relationOptions,
        relationTableOptions,
        handleRelationChange,
        handleRelationTableChange,
        customDia,
        customCompTypeChange,
        iframeText,
        handleIframeConfig,
        handleModalConfig,
        iframeConfigDia,
        tabBgUpload,
        handleFieldChange,
        modalConfigDia,
        modalOutConfigDia,
        modalSelectDia,
        treeConfigDia,
        hasSunform,
        submitCardBgUpload,
        submitCardContentBgUpload,
        changeBtnName,
        bindModalChange,
        modalConfigFormJson,
        handleTreeConfig,
        CustomButtonModalType,
      };
    },
  });
</script>
<style scoped lang="less">
  .fc-style .widget-config-container .config-content .ant-form-item,
  .fc-style .widget-config-container .config-content .el-form-item,
  .fc-style .widget-config-container .config-content h4 {
    padding-bottom: 12px;
    border-bottom: 1px dashed #e1e1e1;
    margin-bottom: 16px;
  }

  .select-list {
    margin-bottom: 10px;
  }

  .select-list label {
    padding: 0 11px;
  }

  :deep(.ant-row) {
    align-items: center;
  }

  :deep(.ant-input-number) {
    width: 100%;
  }

  :deep(.ant-table-wrapper) {
    margin: 5px 0 10px;
  }

  .icon {
    width: 1em;
    height: 1em;
    vertical-align: -0.15em;
    fill: currentcolor;
    overflow: hidden;
  }

  .view-table {
    :deep(.ant-table-thead) tr th {
      padding: 12px 16px;
    }
  }

  :deep(.ant-form-horizontal .ant-form-item-control) {
    text-align: right;
  }

  :deep(.ant-form-item .ant-select) {
    text-align: left;
  }

  .image-box {
    :deep(.ant-upload.ant-upload-select) {
      height: 100%;
    }

    .image-default {
      display: flex;
      align-items: center;
      height: 100%;
      border: 1px solid #1c8dff;
      background: #edf6ff;
      padding: 0 5px 0 7px;
      border-radius: 4px;
      color: #1c8dff;
    }
  }

  .top-box {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;

    > div {
      font-size: 14px !important;
    }

    .add-btn {
      font-size: 14px !important;
      color: @primary-color;
    }
  }

  .delete-btn {
    position: absolute;
    top: -7px;
    right: 0;
    color: #ff5461;
    cursor: pointer;
    font-size: 14px !important;
  }

  .vertical-box {
    display: block !important;

    :deep(.ant-radio-button-wrapper) {
      &:first-child {
        border-radius: 4px 0 0 4px;
      }

      &:last-child {
        border-radius: 0 4px 4px 0;
      }
    }
  }

  .coll-box {
    display: flex;
    position: relative;
    background: #f3f3f3;
    height: 52px;
    padding: 12px;
    border-radius: 4px;
    margin-bottom: 10px;

    .draggable-icon {
      display: flex;
      justify-content: center;
      align-items: center;
      color: #c3c8cf;
      background: #fff;
      border: 1px solid #ddd;
      border-radius: 4px;
      margin-left: 15px;
      padding: 7px;
      cursor: move;
      font-size: 14px !important;
    }
  }

  .upload-pic {
    text-align: center;
    line-height: 14px;
  }
  // @import '/@/assets/style/designer/index.css';
  .setting-box {
    .setting-head {
      font-weight: 800;
      font-size: 14px;
      padding-bottom: 10px;
      margin: 16px 0;
      border-bottom: 1px solid #e2dddd;
    }

    .setting-head::after {
      content: ':';
    }

    .setting-content {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin: 6px 0;

      .label {
        width: 120px;
      }
    }
  }
</style>
