<template>
  <div class="fc-style">
    <div style="position: absolute; left: 310px; right: 330px; z-index: 99"
      ><AntdHeader
        v-bind="$props"
        @preview="handlerPreview"
        @upload-json="uploadJsonVisible = true"
        @generate-json="handleGenerateJson"
        @generate-code="handleGenerateCode"
        @clearable="handleClearable"
        @saveFormTemplate="openModal()"
      >
        <slot name="header">
          <a-row class="text-left w-[240px] absolute left-0" align="middle" v-if="isShowSelectDb">
            <a-col :span="8" align="right">
              <span style="color: red">*</span>
              数据库：
            </a-col>
            <a-col :span="16">
              <DbSelect
                :placeholder="t('请选择数据库')"
                @change="handleDbChange"
                :disabled="isDbDisabled"
                v-model:value="dbValue"
              />
            </a-col>
          </a-row>
        </slot> </AntdHeader
    ></div>
    <a-layout class="fc-container">
      <!-- <a-layout-content class="fc-main">
        <a-layout> -->
      <a-layout-sider theme="light" :width="300" class="cg-container">
        <a-tabs v-model:activeKey="customTabKey" @change="handleTabChange">
          <a-tab-pane key="1" tab="系统默认组件">
            <div class="components h-full">
              <a-input
                v-model:value="searchVal"
                placeholder="请输入组件名称进行查询"
                :bordered="false"
                :class="['search-com-box', searchVal ? 'mb-1.5' : '']"
                @change="searchComponent"
              >
                <template #suffix>
                  <SearchOutlined />
                </template>
              </a-input>
              <div style="height: calc(100% - 50px); overflow-y: auto; padding: 0 10px">
                <ComponentGroup :fields="searchFields" :list="searchComList" v-if="searchVal" />
                <a-collapse
                  v-model:activeKey="componentGroupKey"
                  :bordered="false"
                  expand-icon-position="right"
                  ghost
                  v-else
                >
                  <a-collapse-panel v-for="(item, index) in componentList" :key="index + 1">
                    <template #header><NodeHead :nodeName="item.title" /> </template>
                    <ComponentGroup
                      :fields="item.fields"
                      :list="item.list"
                      :isDisabled="isComDisabled"
                    />
                  </a-collapse-panel>
                </a-collapse>
              </div>
            </div>
          </a-tab-pane>
          <a-tab-pane key="2" tab="自定义组件" force-render v-if="designType !== 'notable'">
            <div class="components h-full">
              <a-input
                v-model:value="searchVal"
                placeholder="请输入组件名称进行查询"
                :bordered="false"
                :class="['search-com-box', searchVal ? 'mb-1.5' : '']"
                @change="searchCustomComponent"
              >
                <template #suffix>
                  <SearchOutlined />
                </template>
              </a-input>
              <div style="height: calc(100% - 50px); overflow-y: auto; padding: 0 10px">
                <ComponentGroup :fields="['custom']" :list="searchCustomComList" v-if="searchVal" />
                <a-collapse
                  v-model:activeKey="componentGroupKey"
                  :bordered="false"
                  expand-icon-position="right"
                  ghost
                  v-else
                >
                  <a-collapse-panel v-for="(item, index) in customComponentList" :key="index + 1">
                    <template #header><NodeHead :nodeName="item.title" /> </template>
                    <ComponentGroup
                      :fields="item.fields"
                      :list="item.list"
                      :isDisabled="!dbValue"
                    />
                  </a-collapse-panel>
                </a-collapse>
              </div>
            </div>
          </a-tab-pane>
          <a-tab-pane key="3" tab="表单模板">
            <FormTemplate @getFormJson="getFormJson" ref="formTemInfoRef" />
          </a-tab-pane>
        </a-tabs>
      </a-layout-sider>
      <a-layout class="center-container">
        <a-layout-content id="layoutId" :class="{ 'widget-empty': widgetForm.list }">
          <AntdWidgetForm
            ref="antdWidgetFormRef"
            v-model:widgetForm="widgetForm"
            v-model:widgetFormSelect="widgetFormSelect"
          />
        </a-layout-content>
      </a-layout>
      <a-layout-sider theme="light" class="widget-config-container" :width="320">
        <a-layout class="layout-height">
          <!-- <a-layout-header class="right-tab"> -->
          <a-tabs v-model:activeKey="configTab" centered style="background: #fff; height: 100%">
            <a-tab-pane key="widget" :tab="t('组件属性')">
              <a-collapse
                v-model:activeKey="chooseTab"
                ghost
                expandIconPosition="right"
                v-if="widgetFormSelect"
              >
                <a-collapse-panel key="property">
                  <template #header><NodeHead nodeName="属性设置" /> </template>
                  <TableLayoutOption
                    v-if="widgetFormSelect.type == 'table-layout'"
                    v-model:select="widgetFormSelect"
                    :widgetForm="widgetForm"
                  ></TableLayoutOption>
                  <PropertyOption
                    v-else
                    v-model:select="widgetFormSelect"
                    :widgetForm="widgetForm"
                    :customComponentList="customComponentList"
                  />
                </a-collapse-panel>
                <a-collapse-panel
                  key="border"
                  v-if="widgetFormSelect.type === 'form' || widgetFormSelect.type === 'grid'"
                  :showArrow="false"
                  collapsible="disabled"
                  class="form-box"
                >
                  <template #header><NodeHead nodeName="表单边框配置" /> </template>
                  <template #extra>
                    <div @click.stop>
                      <a-switch
                        v-model:checked="widgetFormSelect.options.showBorder"
                        class="form-border"
                      />
                    </div>
                  </template>
                  <div class="coll-box" v-if="widgetFormSelect.options.showBorder">
                    <a-form-item :label="t('颜色')" :colon="false">
                      <ColorPicker
                        v-model:value="widgetFormSelect.options.bordercolor"
                        class="text-right"
                      />
                    </a-form-item>
                    <a-form-item :label="t('可见性')" :colon="false">
                      <BorderSetting
                        v-model:borderShowType="widgetFormSelect.options.bordershowtype"
                        class="w-full flex justify-end"
                      />
                    </a-form-item>
                    <a-form-item :label="t('大小')" :colon="false" class="!flex-nowrap">
                      <a-input-number
                        v-model:value="widgetFormSelect.options.borderwidth"
                        :min="0"
                        addonAfter="px"
                      />
                    </a-form-item>
                  </div>
                </a-collapse-panel>
                <a-collapse-panel
                  key="form"
                  v-if="widgetFormSelect.type === 'form'"
                  :showArrow="false"
                  class="form-box"
                >
                  <template #header><NodeHead nodeName="表头合并" /> </template>
                  <template #extra>
                    <PlusCircleFilled class="add-btn" @click.stop="addMutipleHeads" />
                  </template>
                  <div v-if="widgetFormSelect.options.multipleHeads?.length > 0">
                    <div
                      v-for="(sight, index) in widgetFormSelect.options.multipleHeads"
                      :key="sight.key"
                      class="coll-box"
                    >
                      <a-form-item
                        label="名称"
                        :name="['sights', index, 'title']"
                        :labelCol="{ span: 8 }"
                        :wrapperCol="{ span: 16 }"
                        labelAlign="left"
                        :colon="false"
                      >
                        <a-input v-model:value="sight.title" />
                      </a-form-item>
                      <a-form-item
                        :name="['sights', index, 'children']"
                        label="子列"
                        :labelCol="{ span: 8 }"
                        :wrapperCol="{ span: 16 }"
                        labelAlign="left"
                        :colon="false"
                      >
                        <a-select
                          mode="multiple"
                          v-model:value="sight.children"
                          :options="sight.headschilds"
                          :fieldNames="{ label: 'title', value: 'key' }"
                          style="width: 100%"
                          @click="sightChild(sight)"
                        ></a-select>
                      </a-form-item>
                      <a-form-item
                        :name="['sights', index, 'align']"
                        label="对齐"
                        :labelCol="{ span: 8 }"
                        :wrapperCol="{ span: 16 }"
                        labelAlign="left"
                        :colon="false"
                      >
                        <a-select
                          v-model:value="sight.align"
                          :options="sightsAlign"
                          style="width: 100%"
                        ></a-select>
                      </a-form-item>
                      <MinusCircleFilled
                        @click.stop="deleteSight(index, sight.key)"
                        class="delete-btn"
                      />
                    </div>
                  </div>
                </a-collapse-panel>
                <a-collapse-panel
                  key="topButton-action"
                  v-if="widgetFormSelect.type === 'form' || widgetFormSelect.type === 'sun-form'"
                  :showArrow="false"
                  class="form-box"
                >
                  <template #header><NodeHead nodeName="表格顶部按钮配置" /> </template>
                  <template #extra>
                    <PlusCircleFilled class="add-btn" @click.stop="addTopButtons" />
                  </template>
                  <div v-if="widgetFormSelect.options.topButtonList?.length > 0">
                    <div
                      v-for="(sight, index) in widgetFormSelect.options.topButtonList"
                      :key="sight.key"
                      class="coll-box"
                    >
                      <a-form-item
                        label="按钮名称"
                        :name="['sights', index, 'label']"
                        :labelCol="{ span: 8 }"
                        :wrapperCol="{ span: 16 }"
                        labelAlign="left"
                        :colon="false"
                      >
                        <a-input v-model:value="sight.label" />
                      </a-form-item>
                      <a-form-item
                        :label="t('按钮样式')"
                        :name="['sights', index, 'style']"
                        :labelCol="{ span: 8 }"
                        :wrapperCol="{ span: 16 }"
                        labelAlign="left"
                        :colon="false"
                      >
                        <a-select v-model:value="sight.style" :placeholder="t('请选择按钮样式')">
                          <a-select-option value="primary">主按钮</a-select-option>
                          <a-select-option value="default">默认按钮</a-select-option>
                          <a-select-option value="danger">危险按钮</a-select-option>
                          <a-select-option value="link">链接按钮</a-select-option>
                          <a-select-option value="text">文本按钮</a-select-option>
                        </a-select>
                      </a-form-item>
                      <a-form-item
                        :name="['sights', index, 'icon']"
                        label="按钮图标"
                        :labelCol="{ span: 8 }"
                        :wrapperCol="{ span: 16 }"
                        labelAlign="left"
                        :colon="false"
                      >
                        <IconPicker v-model:value="sight.icon" :disabled="false" />
                      </a-form-item>
                      <a-form-item
                        label="按钮类型"
                        :name="['sights', index, 'label']"
                        :labelCol="{ span: 8 }"
                        :wrapperCol="{ span: 16 }"
                        labelAlign="left"
                        :colon="false"
                      >
                        <a-select
                          @change="
                            () => {
                              sight.event = [];
                              if (sight.type == CustomButtonModalType.Modal) {
                                sight.event.push({
                                  operateType: 2,
                                  operateConfig: { js: `formActionType.openModal(curRowData)` },
                                });
                              }
                            }
                          "
                          v-model:value="sight.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="sight.type == CustomButtonModalType.Modal">
                        <a-form-item
                          :name="['sights', index, 'modal']"
                          label="按钮弹窗配置"
                          :labelCol="{ span: 8 }"
                          :wrapperCol="{ span: 16 }"
                          labelAlign="left"
                          :colon="false"
                        >
                          <ButtonModalConfig
                            v-model:modalData="sight.modal"
                            :formJson="widgetFormSelect.children || []"
                          >
                            <a-input
                              :value="sight.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
                        v-else
                        :name="['sights', index, 'event']"
                        label="按钮事件"
                        :labelCol="{ span: 8 }"
                        :wrapperCol="{ span: 16 }"
                        labelAlign="left"
                        :colon="false"
                      >
                        <ExecuteEvent v-model:processEvent="sight.event" classStyle="inline mr-1">
                          <a-input
                            :value="sight.event.length > 0 ? t('已配置') : t('点击进行配置')"
                            :placeholder="t('点击进行配置')"
                          >
                            <template #suffix>
                              <Icon icon="ant-design:ellipsis-outlined" />
                            </template>
                          </a-input>
                        </ExecuteEvent>
                      </a-form-item>

                      <MinusCircleFilled
                        @click.stop="deleteButtons('topButtonList', index)"
                        class="delete-btn"
                      />
                    </div>
                  </div>
                </a-collapse-panel>
                <a-collapse-panel
                  key="button-action"
                  v-if="widgetFormSelect.type === 'form' || widgetFormSelect.type === 'sun-form'"
                  :showArrow="false"
                  class="form-box"
                >
                  <template #header><NodeHead nodeName="操作列按钮配置" /> </template>
                  <template #extra>
                    <PlusCircleFilled class="add-btn" @click.stop="addButtons" />
                  </template>
                  <div v-if="widgetFormSelect.options.buttonList?.length > 0">
                    <div
                      v-for="(sight, index) in widgetFormSelect.options.buttonList"
                      :key="sight.key"
                      class="coll-box"
                    >
                      <a-form-item
                        label="按钮名称"
                        :name="['sights', index, 'label']"
                        :labelCol="{ span: 8 }"
                        :wrapperCol="{ span: 16 }"
                        labelAlign="left"
                        :colon="false"
                      >
                        <a-input v-model:value="sight.label" />
                      </a-form-item>

                      <a-form-item
                        :name="['sights', index, 'icon']"
                        label="按钮图标"
                        :labelCol="{ span: 8 }"
                        :wrapperCol="{ span: 16 }"
                        labelAlign="left"
                        :colon="false"
                      >
                        <IconPicker v-model:value="sight.icon" :disabled="false" />
                      </a-form-item>
                      <a-form-item
                        label="按钮类型"
                        :name="['sights', index, 'label']"
                        :labelCol="{ span: 8 }"
                        :wrapperCol="{ span: 16 }"
                        labelAlign="left"
                        :colon="false"
                      >
                        <a-select
                          @change="
                            () => {
                              sight.event = [];
                              if (sight.type == CustomButtonModalType.Modal) {
                                sight.event.push({
                                  operateType: 2,
                                  operateConfig: { js: `formActionType.openModal(curRowData)` },
                                });
                              }
                            }
                          "
                          v-model:value="sight.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="sight.type == CustomButtonModalType.Modal">
                        <a-form-item
                          :name="['sights', index, 'modal']"
                          label="按钮弹窗配置"
                          :labelCol="{ span: 8 }"
                          :wrapperCol="{ span: 16 }"
                          labelAlign="left"
                          :colon="false"
                        >
                          <ButtonModalConfig
                            v-model:modalData="sight.modal"
                            :formJson="widgetFormSelect.children || []"
                          >
                            <a-input
                              :value="sight.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
                        v-else
                        :name="['sights', index, 'event']"
                        label="按钮事件"
                        :labelCol="{ span: 8 }"
                        :wrapperCol="{ span: 16 }"
                        labelAlign="left"
                        :colon="false"
                      >
                        <ExecuteEvent
                          v-model:processEvent="sight.event"
                          classStyle="inline mr-1"
                          :hasComponent="true"
                          :formList="{
                            list: widgetFormSelect.children,
                            type: widgetFormSelect.type,
                            parentTable: widgetFormSelect.parentTable,
                          }"
                          :formTableName="widgetFormSelect.bindTable"
                        >
                          <a-input
                            :value="sight.event.length > 0 ? t('已配置') : t('点击进行配置')"
                            :placeholder="t('点击进行配置')"
                          >
                            <template #suffix>
                              <Icon icon="ant-design:ellipsis-outlined" />
                            </template>
                          </a-input>
                        </ExecuteEvent>
                      </a-form-item>

                      <MinusCircleFilled
                        @click.stop="deleteButtons('buttonList', index)"
                        class="delete-btn"
                      />
                    </div>
                  </div>
                </a-collapse-panel>
                <a-collapse-panel key="list" v-if="hasListConfigsComponents(widgetFormSelect.type)">
                  <template #header><NodeHead nodeName="列表配置" /> </template>
                  <ComponentListConfigs
                    v-model:select="widgetFormSelect"
                    :widgetForm="widgetForm"
                  />
                </a-collapse-panel>
                <a-collapse-panel key="event">
                  <template #header><NodeHead nodeName="触发事件" /> </template>
                  <div
                    class="widget-none"
                    v-if="noConfigComponentEvent.includes(widgetFormSelect.type)"
                  >
                    <SvgIcon name="exclamation" :size="44" />
                    <p>{{ t('当前组件无法配置触发组件') }}</p>
                  </div>
                  <ComponentEvent
                    v-model:select="widgetFormSelect"
                    :widgetForm="widgetForm"
                    v-else
                  />
                </a-collapse-panel>
                <a-collapse-panel key="regular">
                  <template #header><NodeHead nodeName="正则校验" /> </template>
                  <div
                    class="widget-none"
                    v-if="noConfigRegularSetting.includes(widgetFormSelect.type)"
                  >
                    <SvgIcon name="exclamation" :size="44" />
                    <p>{{ t('当前组件无法配置正则检验') }}</p>
                  </div>
                  <RegularSetting v-model:select="widgetFormSelect" v-else />
                </a-collapse-panel>
              </a-collapse>
              <div class="widget-none" v-else>
                <SvgIcon name="tool" :size="44" />
                <p>{{ t('请先拖入组件后再查看组件属性') }}</p>
              </div>
            </a-tab-pane>
            <a-tab-pane key="form" :tab="t('表单属性')">
              <a-collapse v-model:activeKey="formChooseTab" ghost expandIconPosition="right">
                <a-collapse-panel key="formproperty">
                  <template #header><NodeHead nodeName="属性设置" /> </template>
                  <AntdFormConfig v-model:config="widgetForm.config" />
                </a-collapse-panel>
                <a-collapse-panel key="hiddenComponent">
                  <template #header><NodeHead nodeName="隐藏组件列表" /> </template>
                  <template #extra>
                    <PlusCircleFilled class="add-btn" @click.stop="handleAddHidden" />
                  </template>
                  <HiddenComponent
                    ref="hiddenCompRef"
                    v-model:component="widgetForm.hiddenComponent"
                  />
                </a-collapse-panel>
              </a-collapse>
            </a-tab-pane>
            <a-tab-pane key="hidden" :tab="t('自定义按钮')">
              <ButtonList v-model:component="widgetForm.buttonList" />
            </a-tab-pane>
          </a-tabs>
        </a-layout>
      </a-layout-sider>
      <!-- </a-layout>
      </a-layout-content> -->

      <a-modal
        v-model:visible="uploadJsonVisible"
        :title="t('导入JSON')"
        :width="800"
        @ok="handleUploadJson"
        :okText="t('确认')"
        :cancelText="t('取消')"
        :body-style="{ height: '500px' }"
      >
        <a-alert
          type="info"
          :message="t('JSON格式如下，直接复制生成的json覆盖此处代码点击确定即可')"
          style="margin-bottom: 10px"
        />
        <CodeEditor v-model:value="jsonEg" language="json" style="height: calc(100% - 50px)" />
      </a-modal>
      <PreviewDrawer
        @register="registerViewModal"
        :config="widgetForm.config"
        :buttonList="widgetForm.buttonList"
        v-if="widgetForm.config.formType == 'modal'"
      />
      <PreviewDrawer
        @register="registerDrawer"
        :config="widgetForm.config"
        :buttonList="widgetForm.buttonList"
        v-else
      />

      <a-modal
        v-model:visible="generateJsonVisible"
        :title="t('生成JSON')"
        :okText="t('复制')"
        :cancelText="t('取消')"
        :width="800"
        :body-style="{ height: '500px' }"
        @ok="handleCopyClick(generateJsonTemplate)"
      >
        <CodeEditor :value="generateJsonTemplate" language="json" readonly />
      </a-modal>

      <a-modal
        v-model:visible="dataJsonVisible"
        :title="t('获取数据')"
        :okText="t('复制')"
        :cancelText="t('取消')"
        :width="800"
        @ok="handleCopyClick(dataJsonTemplate)"
      >
        <CodeEditor :value="dataJsonTemplate" language="json" readonly />
      </a-modal>

      <a-modal
        v-model:visible="dataCodeVisible"
        :title="t('生产代码')"
        :okText="t('复制')"
        :cancelText="t('取消')"
        :width="800"
        @ok="handleCopyClick(dataCodeTemplate)"
      >
        <a-tabs type="card" v-model:activeKey="codeLanguage" :tabBarStyle="{ margin: 0 }">
          <a-tab-pane tab="Vue Component" :key="codeType.Vue">
            <CodeEditor :value="dataCodeTemplate" language="html" readonly />
          </a-tab-pane>
          <a-tab-pane tab="HTML" :key="codeType.Html">
            <CodeEditor :value="dataCodeTemplate" language="html" readonly />
          </a-tab-pane>
        </a-tabs>
      </a-modal>
    </a-layout>
  </div>

  <FormTemplateModal ref="formTemplateRef" @register="registerModal" @success="handleSaveTemplate">
    <LoadingBox v-if="spinning" />
  </FormTemplateModal>
</template>

<script lang="ts">
  import {
    defineComponent,
    reactive,
    PropType,
    toRefs,
    watchEffect,
    provide,
    watch,
    inject,
    ref,
    onMounted,
    Ref,
    computed,
  } from 'vue';
  import { message } from 'ant-design-vue';
  import { cloneDeep, merge, debounce } from 'lodash-es';
  import { CodeEditor } from '/@/components/CodeEditor';
  import ComponentGroup from './components/ComponentGroup.vue';
  import AntdHeader from './components/AntdHeader.vue';
  import AntdWidgetForm from './components/AntdWidgetForm.vue';
  import PropertyOption from './components/componentProperty/PropertyOption.vue';
  import TableLayoutOption from './components/componentProperty/TableLayoutOption.vue';
  import RegularSetting from './components/componentProperty/RegularSetting.vue';
  import ComponentEvent from './components/componentProperty/ComponentEvent.vue';
  import ComponentListConfigs from './components/componentProperty/ComponentListConfigs.vue'; //列表属性配置
  import AntdFormConfig from './components/AntdFormConfig.vue';
  import HiddenComponent from './components/HiddenComponent.vue';
  import ButtonList from './components/buttonList.vue';
  import FormTemplate from './components/FormTemplate.vue';
  import FormTemplateModal from './components/componentProperty/FormTemplateModal.vue';
  import { useModal } from '/@/components/Modal';
  import { IconPicker } from '/@/components/Icon';
  import { DbSelect } from '/@/components/DbSelect';
  import * as antd from './types';
  import { copy } from '/@/utils';
  import generateCode from './util/generateCode';
  import {
    WidgetForm,
    CodeType,
    PlatformType,
    upperFieldDb,
    TableCell,
    TableTh,
    listConfigsComponents,
    componentListProps,
  } from './types';
  import PreviewDrawer from './components/PreviewDrawer.vue';
  import { useDrawer } from '/@/components/Drawer';
  import { GeneratorConfig } from '/@/model/generator/generatorConfig';
  import { noConfigComponentEvent, noConfigRegularSetting, noHaveTableAndField } from './types';
  import {
    DoubleRightOutlined,
    PlusCircleFilled,
    MinusCircleFilled,
    SearchOutlined,
  } from '@ant-design/icons-vue';
  import { SvgIcon } from '/@/components/Icon';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { NodeHead } from '/@/components/ModalPanel/index';
  import { ColorPicker } from '/@/components/ColorPicker';
  import BorderSetting from './components/componentProperty/settings/BorderSetting.vue';
  import { getCustomCompList } from '/@/api/system/customcomp';
  import { getDicDetailList } from '/@/api/system/dic';
  import { addFormTemplate } from '/@/api/form/formTemplate';
  import html2canvas from 'html2canvas';
  import { dataURLtoBlob } from '/@/utils/file/base64Conver';
  import { uploadApi } from '/@/api/sys/upload';
  import { LoadingBox } from '/@/components/ModalPanel/index';
  import ExecuteEvent from '/@/components/CreateCodeStep/src/components/ExecuteEvent.vue';
  import ButtonModalConfig from '/@/components/CreateCodeStep/src/components/ButtonModalConfig.vue';
  import { CustomButtonModalType } from '/@/enums/userEnum';
  const { t } = useI18n();
  export default defineComponent({
    name: 'AntdDesignForm',
    components: {
      AntdHeader,
      ComponentGroup,
      CodeEditor,
      AntdWidgetForm,
      PreviewDrawer,
      AntdFormConfig,
      PropertyOption,
      RegularSetting,
      ComponentEvent,
      HiddenComponent,
      ButtonList,
      DoubleRightOutlined,
      SvgIcon,
      DbSelect,
      TableLayoutOption,
      ComponentListConfigs,
      NodeHead,
      PlusCircleFilled,
      MinusCircleFilled,
      ColorPicker,
      BorderSetting,
      SearchOutlined,
      FormTemplate,
      FormTemplateModal,
      LoadingBox,
      ExecuteEvent,
      IconPicker,
      ButtonModalConfig,
    },
    props: {
      preview: {
        type: Boolean,
        default: true,
      },

      generateJson: {
        type: Boolean,
        default: true,
      },
      uploadJson: {
        type: Boolean,
        default: true,
      },
      clearable: {
        type: Boolean,
        default: true,
      },
      saveFormTemplate: {
        type: Boolean,
        default: true,
      },
      basicFields: {
        type: Array as PropType<Array<string>>,
        default: () => [
          'input',
          'textarea',
          'password',
          'number',
          'richtext-editor',
          'auto-code',
          'auto-complete',
          'signature',
          'labelComponent',
          // "custom",
          'ai-answer',
        ],
      },
      advanceFields: {
        type: Array as PropType<Array<string>>,
        default: () => [
          'select',
          'cascader',
          'associate-select',
          'multiple-popup',
          'associate-popup',
          'area',
          'checkbox',
          'radio',
          'switch',
          'slider',
          'time',
          'time-range',
          'date',
          'date-range',
          'rate',
          'picker-color',
          'upload',
          'image',
          'map',
          'qrcode',
          'tree-component',
          'tree-select-component',
          'barcode',
          'file',
          'modal',
          'drawer',
        ],
      },
      buttonFields: {
        type: Array as PropType<Array<string>>,
        default: () => ['button'],
      },
      layoutFields: {
        type: Array as PropType<Array<string>>,
        default: () => [
          'form',
          'sun-form',
          'one-for-one',
          'form-view',

          'title',
          'text',
          'grid',

          'tab',

          'card',
          'iframe',

          'divider',
          ,
          'table-layout',
        ],
      },
      workFlowFields: {
        type: Array as PropType<Array<string>>,
        default: () => ['opinion'],
      },
      infoFields: {
        type: Array as PropType<Array<string>>,
        default: () => ['info', 'organization', 'user', 'role'],
      },
      financeFields: {
        type: Array as PropType<Array<string>>,
        default: () => ['computational', 'money-chinese'],
      },
    },
    setup(props) {
      const state = reactive({
        antd,
        codeType: CodeType,
        widgetForm: undefined as any,
        widgetFormSelect: undefined as any,
        generateFormRef: null as any,
        configTab: 'widget',
        chooseTab: ['property', 'border'],
        previewVisible: false,
        uploadJsonVisible: false,
        dataJsonVisible: false,
        dataCodeVisible: false,
        generateJsonVisible: false,
        generateCodeVisible: false,
        generateJsonTemplate: JSON.stringify(antd.widgetForm, null, 2),
        dataJsonTemplate: '',
        dataCodeTemplate: '',
        codeLanguage: CodeType.Vue,
        jsonEg: JSON.stringify(antd.widgetForm, null, 2),
        componentGroupKey: ['1', '2', '3', '4', '5', '6', '7'],
        componentList: [
          {
            title: t('输入型组件'),
            fields: props.basicFields,
            list: antd.basicComponents,
          },
          {
            title: t('选择型组件'),
            fields: props.advanceFields,
            list: antd.advanceComponents,
          },
          {
            title: t('按钮型组件'),
            fields: props.buttonFields,
            list: antd.buttonComponents,
          },
          {
            title: t('布局型组件'),
            fields: props.layoutFields,
            list: antd.layoutComponents,
          },
          {
            title: t('工作流组件'),
            fields: props.workFlowFields,
            list: antd.workFlowComponents,
          },
          {
            title: t('组织架构'),
            fields: props.infoFields,
            list: antd.infoComponents,
          },
          {
            title: t('财务组件'),
            fields: props.financeFields,
            list: antd.financeComponents,
          },
        ],
        customTabKey: '1',
        customComponentList: [] as Array<componentListProps>,
      });
      const modalConfigDia = ref<boolean>(false);
      const sightsAlign = [
        {
          label: '左对齐',
          value: 'left',
        },
        {
          label: '居中',
          value: 'center',
        },
        {
          label: '右对齐',
          value: 'right',
        },
      ];
      state.widgetForm = inject('widgetForm');
      const generatorConfig = inject<GeneratorConfig>('generatorConfig') as GeneratorConfig;
      const designType = inject<string>('designType');
      let isFieldUpper = inject<Ref<boolean>>('isFieldUpper', ref(false));
      let mainTableName = inject<Ref<string>>('mainTableName', ref(''));
      const isCustomForm = inject<boolean>('isCustomForm', false);
      const hiddenCompRef = ref();
      const { notification } = useMessage();
      const formChooseTab = ref(['formproperty', 'hiddenComponent']);
      const isDbDisabled = ref(false);
      const dbValue = ref();
      const isShowSelectDb = ref(false);
      const tableCell = ref<TableCell>();
      const tableTh = ref<TableTh>();
      const searchVal = ref('');
      const searchComList = ref<any[]>([]);
      const searchCustomComList = ref<any[]>([]);
      const searchFields = ref<string[]>([]);
      const formTemplateRef = ref();
      const antdWidgetFormRef = ref();
      const spinning = ref<boolean>(false);
      const formTemInfoRef = ref();

      provide('tableCell', tableCell);
      provide('tableTh', tableTh);

      const [registerModal, { openModal }] = useModal();
      const [registerViewModal, { openModal: openViewModal }] = useModal();

      watch(
        () => generatorConfig.databaseId,
        (val) => {
          if (val) {
            dbValue.value = val;
            if (state.widgetForm?.list?.length) {
              isDbDisabled.value = true;
            }
          }
        },
        {
          immediate: true,
        },
      );

      onMounted(() => {
        isShowSelectDb.value = designType === 'code';
        getCustomComponent();
      });

      //注入数据
      provide('state', state);

      const isComDisabled = computed(() => {
        return !dbValue.value && designType === 'code';
      });

      // 列表配置
      const hasListConfigsComponents = (type) => {
        return listConfigsComponents.includes(type);
      };
      const handleUploadJson = () => {
        try {
          setJson(JSON.parse(state.jsonEg));
          state.uploadJsonVisible = false;
          message.success(t('上传成功'));
        } catch (error) {
          message.error(t('上传失败'));
        }
      };

      const handleCopyClick = (text: string) => {
        copy(text);
        message.success(t('Copy成功'));
      };

      const handleGetData = () => {
        state.generateFormRef.getData().then((res: any) => {
          state.dataJsonTemplate = JSON.stringify(res, null, 2);
          state.dataJsonVisible = true;
        });
      };

      const handleGenerateJson = () => {
        (state.generateJsonTemplate = JSON.stringify(state.widgetForm, null, 2)) &&
          (state.generateJsonVisible = true);
      };

      const handleGenerateCode = () => {
        state.codeLanguage = CodeType.Vue;
        state.dataCodeVisible = true;
      };

      watchEffect(() => {
        if (state.dataCodeVisible) {
          state.dataCodeTemplate = generateCode(
            state.widgetForm,
            state.codeLanguage,
            PlatformType.Antd,
          )!;
        }
      });

      const handleClearable = () => {
        state.widgetForm.list = [];
        merge(state.widgetForm, JSON.parse(JSON.stringify(antd.widgetForm)));
        state.widgetFormSelect = undefined;
      };

      const handleReset = () => state.generateFormRef.reset();

      const getJson = () => state.widgetForm;

      const setJson = (json: WidgetForm) => {
        state.widgetForm.list = [];
        merge(state.widgetForm, json);
        if (json.list?.length) {
          state.widgetFormSelect = json.list[0];
        }
      };
      const setWidgetFormSelect = (json: WidgetForm) => {
        if (json.list?.length) {
          state.widgetFormSelect = json.list[0];
        }
      };
      const handlerPreview = () => {
        if (designType === 'data' && hasNoBindTableOrField(state.widgetForm.list)) {
          notification.error({
            message: t('提示'),
            description: t('请先将组件绑定表和字段'),
          }); //提示消息
        } else {
          if (state.widgetForm.config.formType == 'modal') {
            openViewModal(true, getJson());
          } else {
            openDrawer(true, getJson());
          }
        }
      };

      const hasNoBindTableOrField = (component) => {
        const hasSubComponent = [
          'tab',
          'grid',
          'card',
          'one-for-one',
          'form',
          'table-layout',
          'sun-form',
        ];
        return component?.some((info) => {
          if (hasSubComponent.includes(info.type!)) {
            if (info.type === 'form' || info.type === 'one-for-one' || info.type === 'sun-form') {
              return hasNoBindTableOrField(info.children);
            } else if (info.type === 'table-layout') {
              return info.layout?.some((childInfo) => {
                return childInfo.list?.some((child) => {
                  return hasNoBindTableOrField(child.children);
                });
              });
            } else {
              return info.layout?.some((childInfo) => {
                return hasNoBindTableOrField(childInfo.list);
              });
            }
          } else {
            if (info.type === 'time-range' || info.type === 'date-range') {
              return !info.bindTable || !info.bindStartTime || !info.bindEndTime;
            }
            if (info.type === 'input' && info.options.isSave) {
              return false;
            }
            return noHaveTableAndField.includes(info.type)
              ? false
              : !info.bindTable || !info.bindField;
          }
        });
      };

      const handleDbChange = (value, option) => {
        generatorConfig.databaseId = value;
        if (option) isFieldUpper.value = upperFieldDb.includes(option.dbType);
        mainTableName.value = isFieldUpper.value
          ? mainTableName.value.toUpperCase()
          : mainTableName.value;
      };

      const getTemplate = (codeType: CodeType) =>
        generateCode(state.widgetForm, codeType, PlatformType.Antd);

      const clear = () => handleClearable();

      const addMutipleHeads = () => {
        if (!state.chooseTab.includes('form')) {
          state.chooseTab.push('form');
        }
        let len = state.widgetFormSelect.options.multipleHeads.length;
        let keys: number[] = [];
        state.widgetFormSelect.options.multipleHeads.map((o) => {
          keys.push(Number(o.key.split('di')[1].split('lie')[0]));
        });

        let num: number = -1;
        for (let i = 0; i < len; i++) {
          if (!keys.includes(i)) num = i;
        }
        if (num === -1) {
          num = len;
        }

        addHeadsObj({
          key: 'di' + num + 'lie',
          title: '第' + num + '列',
          dataIndex: 'di' + num + 'lie',
        });
      };
      const addButtons = () => {
        if (!state.chooseTab.includes('button-action')) {
          state.chooseTab.push('button-action');
        }

        if (!state.widgetFormSelect.options.buttonList)
          state.widgetFormSelect.options.buttonList = [];
        state.widgetFormSelect.options.buttonList.push({
          key: `button${Date.now()}`,
          label: '',
          icon: '',
          modal: null,
          event: [],
          type: CustomButtonModalType.COMMON,
        });
      };
      const addTopButtons = () => {
        if (!state.chooseTab.includes('topButton-action')) {
          state.chooseTab.push('topButton-action');
        }

        if (!state.widgetFormSelect.options.topButtonList)
          state.widgetFormSelect.options.topButtonList = [];
        state.widgetFormSelect.options.topButtonList.push({
          key: `button${Date.now()}`,
          label: '',
          icon: '',
          style: 'primary',
          event: [],
          type: CustomButtonModalType.COMMON,
        });
      };

      function addHeadsObj(o, obj?) {
        const com: antd.MutipleHeadInfo = {
          key: o.key,
          title: o.title,
          dataIndex: o.dataIndex,
          children: [],
          align: 'center',
        };
        if (obj) {
          obj.push(com);
        } else {
          state.widgetFormSelect.options.multipleHeads.push(com);
        }
      }

      const sightChild = (sight) => {
        let temp: antd.MutipleHeadInfo[] = [];
        let children = state.widgetFormSelect.children.filter((o) => o.type !== 'sun-form');
        children.map((a) => {
          a.title = a.label;
          a.dataIndex = a.bindField;
        });

        checkDatas(children, temp, sight);

        checkHeads(state.widgetFormSelect.options.multipleHeads, temp, sight);

        sight.headschilds = temp;
      };

      const filtercomps = ref<string[]>([]);
      const filterHeads = ref<string[]>([]);

      function checkDatas(origin, temp, sight) {
        filtercomps.value = [];

        origin.forEach((k) => {
          findParent(state.widgetFormSelect.options.multipleHeads, k, sight.key, filtercomps.value);
        });
        let datas = origin.filter((o) => {
          return !filtercomps.value.includes(o.key);
        });
        datas.forEach((o) => {
          if (o.key !== sight.key) {
            addHeadsObj(o, temp);
          }
        });
      }
      function checkHeads(origin, temp, sight) {
        filterHeads.value = [sight.key]; //不能选自己
        origin.forEach((o) => {
          if (o.children.length > 0 && sight.key != o.key) {
            //谁选了自己就排除谁
            findSelf(o, sight.key, o.key);
          }
          if (sight.key != o.key) {
            //兄弟列有被别人选中过的排除(被自己选中的除外)
            findBrother(origin, o.key, sight.key);
          }
          if (o.children.length <= 0) {
            //不能选子列是空的
            filterHeads.value.push(o.key);
          }
        });

        let datas = origin.filter((o) => {
          return !filterHeads.value.includes(o.key);
        });
        datas.forEach((o) => {
          if (o.key !== sight.key) {
            addHeadsObj(o, temp);
          }
        });
      }

      function findParent(arr, o, cur, filters) {
        for (let i = 0; i < arr.length; i++) {
          let k = arr[i];
          if (k.key != cur) {
            if (k == o.key) {
              filters.push(k);
              break;
            } else if (k.dataIndex !== undefined && k.children.length > 0) {
              findParent(k.children, o, cur, filters);
            }
          }
        }
      }
      function findSelf(obj, cur, parent) {
        for (let i = 0; i < obj.children.length; i++) {
          let k = obj.children[i];
          if (k == cur) {
            filterHeads.value.push(parent);
            break;
          } else {
            let temp = state.widgetFormSelect.options.multipleHeads.find((o) => {
              return o.key == k;
            });
            if (temp) {
              findSelf(temp, cur, parent);
            }
          }
        }
      }
      function findBrother(arr, cur, key) {
        arr.forEach((o) => {
          if (o.children.length > 0 && cur != o.key && o.key !== key) {
            findBrotherParent(o.children, cur);
          }
        });
      }

      function findBrotherParent(arr, cur) {
        for (let i = 0; i < arr.length; i++) {
          let k = arr[i];
          if (k == cur) {
            filterHeads.value.push(k);
            break;
          } else if (k.dataIndex !== undefined && k.children.length > 0) {
            findBrotherParent(k.children, cur);
          }
        }
      }

      const deleteSight = (index: number, key: string) => {
        state.widgetFormSelect.options.multipleHeads.splice(index, 1);
        state.widgetFormSelect.options.multipleHeads.forEach((o) => {
          let idx = o.children.findIndex((k) => {
            return k == key;
          });
          if (idx >= 0) {
            o.children.splice(idx, 1);
          }
        });
      };

      const deleteButtons = (field, index: number) => {
        state.widgetFormSelect.options[field].splice(index, 1);
      };

      const allComponents = [
        ...antd.basicComponents,
        ...antd.advanceComponents,
        ...antd.buttonComponents,
        ...antd.layoutComponents,
        ...antd.workFlowComponents,
        ...antd.infoComponents,
        ...antd.financeComponents,
      ];

      const searchComponent = () => {
        searchComList.value = [];
        searchFields.value = [];
        allComponents.forEach((item) => {
          if (item.label.includes(searchVal.value)) {
            searchComList.value.push(item);
            searchFields.value.push(item.type);
          }
        });
      };

      //这里使用了防抖 包裹  因为监听 state.widgetForm 会执行2次
      watch(
        () => state.widgetForm,
        debounce((val) => {
          isDbDisabled.value = !!val?.list?.length || !!val?.hiddenComponent?.length;
          generatorConfig.formJson = cloneDeep(val);
        }, 50),
        { deep: true },
      );

      //注册抽屉 获取外部操作抽屉得方法
      const [registerDrawer, { openDrawer }] = useDrawer();
      function getCustomComponent() {
        state.customComponentList = [];
        searchCustomComList.value = [];
        getDicDetailList({ itemId: '1881874836500508673' }).then((res) => {
          res.forEach(async (o) => {
            let obj = {
              title: o.name,
              fields: ['custom'],
              list: [],
            };
            let k = await getCustomCompList({
              zuJianMingChen2489: searchVal.value,
              zuJianFenLei1675: o.value,
            });
            // obj.fields = k.map((i) => {
            //   return i.zuJianBianMa6514;
            // });
            obj.list = k.map((j) => {
              return {
                label: t(j.zuJianMingChen2489),
                typeName: t(j.zuJianMingChen2489),
                customIcon: j.tubiao,
                // type: j.zuJianBianMa6514,
                // options: {
                //   content: j.bianXieQu9373,
                // },
                type: 'custom',
                options: {
                  width: '100%',
                  span: '',
                  defaultValue: '',
                  type: j.zuJianLeiBie9003,
                  compUrl: j.zuJianDiZhi8745,
                  apiConfig: {
                    path: '',
                    method: 'GET',
                    apiId: '',
                  },
                  content: null,
                  id: j.id,
                  disabled: false,
                  allowClear: false,
                  showLabel: true,
                  required: false,
                  rules: [],
                  events: {},
                  listStyle: '', //配置列表样式
                  isSave: false,
                  isShow: true,
                },
              };
            });
            state.customComponentList.push(obj);
          });
        });
      }
      function searchCustomComponent() {
        searchCustomComList.value = [];
        state.customComponentList.forEach((el) => {
          el.list.forEach((item) => {
            if (item.label.includes(searchVal.value)) {
              searchCustomComList.value.push(item);
            }
          });
        });
      }
      function handleTabChange() {
        state.customTabKey == '1' ? searchComponent() : searchCustomComponent();
      }

      function getFormJson(data) {
        const dataInfo = JSON.parse(data);
        generatorConfig.formJson = dataInfo.formJson;
        generatorConfig.tableStructureConfigs = dataInfo.tableStructureConfigs;
        generatorConfig.databaseId = dataInfo.databaseId;
        state.widgetForm = dataInfo.formJson;
      }

      async function getBgUrl() {
        let canvas = await html2canvas(antdWidgetFormRef.value.widgetFormRef, {
          backgroundColor: '#f5f5f5',
          useCORS: true,
          windowHeight: document.body.scrollHeight,
        });
        const url = canvas.toDataURL();
        const blob = dataURLtoBlob(url);
        const data = await uploadApi({
          name: 'file',
          file: blob,
          filename: 'bg.png',
        });
        return data.fileUrl;
      }

      function handleSaveTemplate(value) {
        spinning.value = true;
        setTimeout(async () => {
          const backgroundUrl = await getBgUrl();
          const source = isCustomForm ? 1 : 2;
          const formTemplateConfig = {
            source,
            backgroundUrl,
            ...value,
            formJson: generatorConfig,
          };
          try {
            await addFormTemplate(formTemplateConfig);
            notification.success({
              message: t('提示'),
              description: t('保存模板成功'),
            });
            if (formTemInfoRef.value) {
              formTemInfoRef.value.handleLimitChange();
            }
          } catch (error) {
            notification.error({
              message: t('提示'),
              description: t('保存模板失败'),
            });
          }
          spinning.value = false;
          formTemplateRef.value.closeModal();
        }, 100);
      }
      function handleAddHidden() {
        formChooseTab.value = ['hiddenComponent'];
        hiddenCompRef.value.addComponent();
      }
      return {
        ...toRefs(state),
        handleUploadJson,
        handleCopyClick,
        handleGetData,
        handleGenerateJson,
        handleGenerateCode,
        handleClearable,
        handleReset,
        getJson,
        setJson,
        setWidgetFormSelect,
        getTemplate,
        clear,
        noConfigComponentEvent,
        noConfigRegularSetting,
        handlerPreview,
        registerDrawer,
        t,
        handleDbChange,
        isDbDisabled,
        isShowSelectDb,
        dbValue,
        tableCell,
        tableTh,
        hasListConfigsComponents,
        addMutipleHeads,
        sightChild,
        sightsAlign,
        deleteSight,
        searchVal,
        searchComList,
        searchCustomComList,
        searchFields,
        searchComponent,
        searchCustomComponent,
        getCustomComponent,
        handleTabChange,
        isComDisabled,
        getFormJson,
        registerModal,
        registerViewModal,
        openModal,
        formTemplateRef,
        antdWidgetFormRef,
        handleSaveTemplate,
        spinning,
        hiddenCompRef,
        handleAddHidden,
        formChooseTab,
        addButtons,
        addTopButtons,
        deleteButtons,
        modalConfigDia,
        designType,
        formTemInfoRef,
        CustomButtonModalType,
      };
    },
  });
</script>
<style scoped lang="less">
  .fc-style {
    height: 100%;
    position: relative;
  }

  .layout-height {
    height: 100%;
    background-color: #f0f2f5;

    :deep(.ant-tabs-content-holder) {
      overflow-y: auto;
    }
  }

  .cg-container {
    box-sizing: border-box;

    :deep(.ant-tabs-content-holder) {
      padding: 0 0 10px;
    }

    :deep(.ant-collapse-content-box) {
      padding: 0 !important;
    }

    :deep(.ant-collapse-header) {
      padding-left: 5px !important;
      height: 24px;
      align-items: center !important;
      margin: 10px 0;

      .ant-collapse-arrow {
        right: 2px;
      }
    }

    :deep(.ant-collapse-ghost > .ant-collapse-item) {
      border-bottom: 0 !important;
    }

    :deep(.ant-tabs-tab) {
      margin-right: 0 !important;
      padding: 16px 14px !important;
    }
  }

  :deep(.ant-collapse-no-arrow > .ant-collapse-header) {
    padding-left: 16px !important;
  }

  :deep(.ant-collapse-content-box) {
    padding-top: 0 !important;
  }

  :deep(.ant-tabs) {
    height: 100%;
  }

  :deep(.ant-tabs-content-top) {
    height: 100%;
  }

  :deep(.ant-radio-group) {
    display: flex;
    flex-wrap: wrap;

    .ant-radio-button-wrapper {
      display: flex;
      justify-content: center;
      align-items: center;
      flex: 1;
      padding: 3px 0 !important;
    }
  }

  .widget-none {
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;

    p {
      margin: 10px;
      color: #cecece;
    }
  }

  :deep(.ant-tabs-nav) {
    margin-bottom: 8px;
  }

  :deep(.ant-form-item) {
    margin-bottom: 10px;
  }

  :deep(.ant-radio-group-small .ant-radio-button-wrapper) {
    padding: 3px 10px;
    box-sizing: content-box;
  }

  .fc-container {
    height: 100%;
  }

  .ant-layout.ant-layout-has-sider {
    height: 100%;
  }

  .center-container {
    height: 100%;
    background-color: #fff;
    padding-bottom: 20px;
    box-sizing: border-box;
    border-left: 8px solid #f0f2f5;
    border-right: 8px solid #f0f2f5;
    overflow: auto;
    padding-top: 51px;

    .center-header {
      padding: 10px;
    }
  }

  .add-btn {
    position: absolute;
    top: 35%;
    right: 16px;
    font-size: 15px;
    color: @primary-color;
  }

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

  .coll-box {
    position: relative;
    background: #f3f3f3;
    padding: 10px 10px 3px;
    border-radius: 4px;
    margin-bottom: 10px;
  }

  .form-box {
    .form-border {
      position: absolute;
      right: 16px;
    }

    :deep(.ant-collapse-content-box) {
      padding-bottom: 0 !important;
    }
  }

  .search-com-box {
    height: 50px;
    border-bottom: 1px solid #f0f0f0;

    :deep(.ant-input-suffix) {
      color: #c3c8cf;
    }

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

  .components :deep(.ant-input-affix-wrapper:not(.ant-input-affix-wrapper-disabled):hover) {
    border-bottom: 1px solid #f0f0f0;
  }
</style>
