<template>
  <div class="guns-layout">
    <div class="guns-layout-sidebar p-t-12" v-if="!props.isBusiness">
      <div class="sidebar-content">
        <SheetFieldTree @treeSelect="treeSelect" ref="FieldTreeRef" :data="props.data" :where="props.where"></SheetFieldTree>
      </div>
    </div>
    <div class="guns-layout-content">
      <a-spin :spinning="loading" :delay="100">
        <div class="guns-layout">
          <div class="guns-layout-content-header">
            <div class="guns-layout-content-header-left">
              <a-space :size="16">
                <a-button shape="circle" size="large" @click="back"><left-outlined /></a-button>
                <a-button class="border-radius" v-if="!tableCreateFlag"
                  >{{ currentModelData?.metaModelName }}
                  <span v-if="currentModelData?.metaModelCode" style="margin-left: 5px">
                    ({{ currentModelData.metaModelCode }})</span
                  ></a-button
                >
                <a-tabs v-model:activeKey="fieldQueryType" class="devops-tabs" v-if="tableCreateFlag" @change="getFieldList">
                  <a-tab-pane key="1" tab="真实字段" />
                  <a-tab-pane key="2" tab="虚拟字段" />
                </a-tabs>
              </a-space>
            </div>
            <div class="guns-layout-content-header-right">
              <a-space :size="16" v-if="!tableCreateFlag">
                <a-dropdown-button class="border-radius" @click="addField('N')">
                  添加字段
                  <template #overlay>
                    <a-menu @click="({ key }) => addDefaultField(key)">
                      <a-menu-item :key="1"> 乐观锁字段 </a-menu-item>
                      <a-menu-item :key="2"> 逻辑删除字段 </a-menu-item>
                      <a-menu-item :key="3"> 租户字段 </a-menu-item>
                    </a-menu>
                  </template>
                  <template #icon>
                    <caret-down-outlined />
                  </template>
                </a-dropdown-button>
                <a-button class="border-radius gree" @click="createSheet" v-permission="['META_CREATE_TABLE']">创建表</a-button>
                <a-button
                  class="border-radius"
                  type="primary"
                  @click="upgradeAndSave"
                  v-permission="['META_UPDATE_AND_SAVE']"
                  v-if="props.type != 'fill'"
                  >升级并保存</a-button
                >
                <a-button class="border-radius" type="primary" @click="save">保存</a-button>
              </a-space>
              <a-space :size="16" v-if="tableCreateFlag">
                <a-button class="border-radius orange" @click="updateSheet">更新表</a-button>
              </a-space>
            </div>
          </div>
          <div class="guns-layout-content-application">
            <div class="content-mian">
              <div class="content-mian-body">
                <div class="table-content" v-if="!tableCreateFlag">
                  <s-table
                    :columns="columns"
                    rowKey="fieldId"
                    bordered
                    :rangeSelection="false"
                    height="calc(100vh - 200px)"
                    style="border-right: 1px solid #eee"
                    :pagination="false"
                    :data-source="metaFieldList"
                    @rowDragEnd="rowDragEnd"
                    :animate-rows="false"
                    :scroll="{ y: 'calc(100vh - 200px)' }"
                  >
                    <template #bodyCell="{ column, text, record, index }">
                      <template
                        v-if="column.dataIndex == 'fieldCode' || column.dataIndex == 'description' || column.dataIndex == 'defaultValue'"
                      >
                        <div class="editable-cell">
                          <div v-if="editableData[record.fieldId + column.dataIndex]" class="editable-cell-input-wrapper">
                            <a-input
                              v-model:value="copyData[column.dataIndex]"
                              style="width: 100%; height: 30px"
                              @keydown.tab="e => tabClick(e, record, column)"
                              ref="durationRef"
                              @keyup.esc="e => pressEnterValue(e, record, column.dataIndex, index)"
                              @pressEnter="e => pressEnterValue(e, copyData, column.dataIndex, index)"
                              @blur="editClosedTypeEvent(copyData, column.dataIndex, index)"
                              @focus="onFocus"
                            />
                          </div>
                          <div v-else class="editable-cell-text-wrapper" @click="editClick(record, column.dataIndex)">
                            <span style="display: block; width: 100%">{{ text || ' ' }}</span>
                            <edit-outlined v-if="!text && !disabled(record)" class="outlined" />
                          </div>
                        </div>
                      </template>
                      <template v-if="column.dataIndex == 'fieldType'">
                        <a-select
                          v-model:value="metaFieldList[index]['fieldType']"
                          style="width: 100%"
                          @keydown.tab="e => tabClick(e, record, column)"
                          @change="val => valueChange(val, record)"
                          :disabled="disabled(record)"
                        >
                          <a-select-option :value="tyItem.dictCode" v-for="tyItem in typeList" :key="tyItem.dictId">{{
                            tyItem.dictName
                          }}</a-select-option>
                        </a-select>
                      </template>
                      <template v-if="column.dataIndex == 'defaultFormComponent'">
                        <a-select
                          v-model:value="metaFieldList[index]['defaultFormComponent']"
                          style="width: 100%"
                          allowClear
                          @keydown.tab="e => tabClick(e, record, column)"
                          :disabled="disabled(record)"
                        >
                          <a-select-option :value="cItem.componentCode" v-for="cItem in componentList" :key="cItem.componentId">{{
                            cItem.componentName
                          }}</a-select-option>
                        </a-select>
                      </template>
                      <template v-if="column.dataIndex == 'fieldLength' || column.dataIndex == 'decimalLength'">
                        <div class="editable-cell">
                          <div v-if="editableData[record.fieldId + column.dataIndex]" class="editable-cell-input-wrapper">
                            <a-input-number
                              v-model:value="copyData[column.dataIndex]"
                              style="width: 100%; height: 30px"
                              ref="durationRef"
                              :min="0"
                              @keydown.tab="e => tabClick(e, record, column)"
                              @keyup.esc="e => pressEnterValue(e, record, column.dataIndex, index)"
                              @pressEnter="e => pressEnterValue(e, copyData, column.dataIndex, index)"
                              @blur="editClosedTypeEvent(copyData, column.dataIndex, index)"
                              @focus="onFocus"
                            />
                          </div>
                          <div v-else class="editable-cell-text-wrapper" @click="editClick(record, column.dataIndex)">
                            <span style="display: block; width: 100%">{{ text || ' ' }}</span>
                            <edit-outlined v-if="!text && !disabled(record)" class="outlined" />
                          </div>
                        </div>
                      </template>
                      <template v-if="column.dataIndex == 'realFlag'">
                        <vxe-checkbox
                          v-model="metaFieldList[index][column.dataIndex]"
                          :disabled="disabled(record)"
                          checked-value="Y"
                          unchecked-value="N"
                        ></vxe-checkbox>
                      </template>
                      <template v-if="column.dataIndex == 'action' && !disabled(record)">
                        <a-space>
                          <icon-font
                            iconClass="icon-menu-type-waibulianjie"
                            font-size="24px"
                            color="#60666b"
                            title="向上插入"
                            @click="addField(index)"
                          ></icon-font>
                          <icon-font
                            iconClass="icon-opt-shanchu"
                            font-size="24px"
                            color="#60666b"
                            title="删除"
                            @click="remove(record.fieldId)"
                          ></icon-font>
                        </a-space>
                      </template>
                    </template>
                  </s-table>
                </div>
                <div class="table-content" v-if="tableCreateFlag">
                  <div class="real-t">
                    <a-space :size="16">
                      <span>表名称：{{ currentModelData?.metaModelName }}</span>
                      <span>数据库表名：{{ currentModelData?.metaModelCode }}</span>
                    </a-space>
                    <a-space :size="16">
                      <a @click="addField1">添加字段</a>
                      <a @click="insertField" v-if="fieldQueryType == '1'">插入字段</a>
                      <a style="color: red" @click="deleteField">删除字段</a>
                      <a @click="moveUp" v-if="fieldQueryType == '1'">上移</a>
                      <a @click="moveDown" v-if="fieldQueryType == '1'">下移</a>
                    </a-space>
                  </div>
                  <s-table
                    :columns="upColumns"
                    rowKey="fieldId"
                    bordered
                    size="small"
                    :rangeSelection="false"
                    :pagination="false"
                    :data-source="metaFieldList"
                    :animate-rows="false"
                    @cellClick="cellClick"
                    :rowClassName="rowClassName"
                  >
                    <template #bodyCell="{ column, text, record, index }">
                      <template v-if="column.dataIndex == 'index'">{{ index + 1 }}</template>
                      <template
                        v-if="column.dataIndex == 'fieldCode' || column.dataIndex == 'description' || column.dataIndex == 'defaultValue'"
                      >
                        <div class="editable-cell">
                          <div v-if="editableData[record.fieldId + column.dataIndex]" class="editable-cell-input-wrapper">
                            <a-input
                              v-model:value="copyData[column.dataIndex]"
                              style="width: 100%; height: 30px"
                              @keydown.tab="e => tabClick(e, record, column)"
                              ref="durationRef"
                              @keyup.esc="e => pressEnterValue(e, record, column.dataIndex, index)"
                              @pressEnter="e => pressEnterValue(e, copyData, column.dataIndex, index)"
                              @blur="editClosedTypeEvent(copyData, column.dataIndex, index)"
                              @focus="onFocus"
                            />
                          </div>
                          <div v-else class="editable-cell-text-wrapper" @click="editClick(record, column.dataIndex)">
                            <span style="display: block; width: 100%" class="span-t">{{ text || ' ' }}</span>
                            <edit-outlined v-if="!text" class="outlined" />
                          </div>
                        </div>
                      </template>
                      <template v-if="column.dataIndex == 'defaultFormComponent'">
                        <a-select
                          v-model:value="record.defaultFormComponent"
                          style="width: 100%"
                          allowClear
                          ref="durationRef"
                          @keydown.tab="e => tabClick(e, record, column)"
                          :bordered="false"
                          @change="val => valueChange(val, record, 'defaultFormComponent')"
                        >
                          <a-select-option :value="cItem.componentCode" v-for="cItem in componentList" :key="cItem.componentId">{{
                            cItem.componentName
                          }}</a-select-option>
                        </a-select>
                      </template>
                      <template v-if="column.dataIndex == 'fieldLength' || column.dataIndex == 'decimalLength'">
                        <div class="editable-cell">
                          <div v-if="editableData[record.fieldId + column.dataIndex]" class="editable-cell-input-wrapper">
                            <a-input-number
                              v-model:value="copyData[column.dataIndex]"
                              style="width: 100%; height: 30px"
                              ref="durationRef"
                              :min="0"
                              @keydown.tab="e => tabClick(e, record, column)"
                              @keyup.esc="e => pressEnterValue(e, record, column.dataIndex, index)"
                              @pressEnter="e => pressEnterValue(e, copyData, column.dataIndex, index)"
                              @blur="editClosedTypeEvent(copyData, column.dataIndex, index)"
                              @focus="onFocus"
                            />
                          </div>
                          <div v-else class="editable-cell-text-wrapper" @click="editClick(record, column.dataIndex)">
                            <span style="display: block; width: 100%">{{ text || ' ' }}</span>
                            <edit-outlined v-if="!text" class="outlined" />
                          </div>
                        </div>
                      </template>
                      <template v-if="column.dataIndex == 'fieldType'">
                        <a-select
                          v-model:value="record.fieldType"
                          style="width: 100%"
                          @keydown.tab="e => tabClick(e, record, column)"
                          @change="val => valueChange(val, record, 'fieldType')"
                          :bordered="false"
                        >
                          <a-select-option :value="tyItem.dictCode" v-for="tyItem in typeList" :key="tyItem.dictId">{{
                            tyItem.dictName
                          }}</a-select-option>
                        </a-select>
                      </template>
                      <template v-if="column.dataIndex == 'realFlag'">
                        <vxe-checkbox
                          v-model="record.realFlag"
                          checked-value="Y"
                          unchecked-value="N"
                          @change="val => valueChange(val, record, 'realFlag')"
                        ></vxe-checkbox>
                      </template>
                    </template>
                  </s-table>
                  <div class="real-t" style="margin-top: 40px" v-if="fieldQueryType == '1'">
                    <span>操作日志：</span>
                  </div>
                  <s-table
                    v-if="fieldQueryType == '1'"
                    :columns="logColumns"
                    rowKey="fieldId"
                    bordered
                    size="small"
                    :rangeSelection="false"
                    :pagination="false"
                    :data-source="tableAlterLogList"
                    :animate-rows="false"
                  >
                    <template #bodyCell="{ column, record, index }">
                      <template v-if="column.dataIndex == 'index'">{{ index + 1 }}</template>
                      <template v-if="column.dataIndex == 'defaultFormComponent'">
                        <a-select
                          v-model:value="record.defaultFormComponent"
                          style="width: 100%"
                          allowClear
                          :disabled="true"
                          :bordered="false"
                          :showArrow="false"
                        >
                          <a-select-option :value="cItem.componentCode" v-for="cItem in componentList" :key="cItem.componentId">{{
                            cItem.componentName
                          }}</a-select-option>
                        </a-select>
                      </template>
                      <template v-if="column.dataIndex == 'fieldType'">
                        <a-select
                          v-model:value="record.fieldType"
                          style="width: 100%"
                          :disabled="true"
                          :bordered="false"
                          :showArrow="false"
                        >
                          <a-select-option :value="tyItem.dictCode" v-for="tyItem in typeList" :key="tyItem.dictId">{{
                            tyItem.dictName
                          }}</a-select-option>
                        </a-select>
                      </template>
                      <template v-if="column.dataIndex == 'operationType'">
                        <span v-if="record.operationType == 'ADD_COLUMN'">新增</span>
                        <span v-if="record.operationType == 'CHANGE_COLUMN'">修改</span>
                        <span v-if="record.operationType == 'DROP_COLUMN'">删除</span>
                      </template>
                    </template>
                  </s-table>
                </div>
              </div>
            </div>
          </div>
        </div>
      </a-spin>
    </div>
  </div>
</template>

<script setup name="LowCodeField">
import { nextTick, onMounted, ref, computed, createVNode } from 'vue';
import SheetFieldTree from './sheet-field-tree.vue';
import { ModelFieldApi } from '../../api/ModelFieldApi';
import { ModelApi } from '../../api/ModelApi';
import { message, Modal } from 'ant-design-vue/es';
import { getUUID, getNowTime } from '@/utils/common/util';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { SysDictTypeApi } from '@/components/DictSelect/api/SysDictTypeApi';
import { cloneDeep } from 'lodash-es';
import { isNumberEnglish } from '@/utils/common/rules';

const props = defineProps({
  // 当前选中的模型数据
  data: Object,
  where: Object,
  // 是否是业务
  isBusiness: {
    type: Boolean,
    defalut: false
  },
  // 业务表数据
  businessSheetData: Object,
  type: {
    type: String,
    default: 'app'
  }
});

const emits = defineEmits(['back']);

// ref
const FieldTreeRef = ref();

const metaModelId = ref('');

// 模型字段列表
const metaFieldList = ref([]);

// 当前编辑的内容
const editableData = ref({});
// 复制的内容
const copyData = ref({});
// ref
const durationRef = ref();

// 默认数据列表
const defaultData = ref([
  {
    fieldCode: 'id',
    fieldType: 21,
    fieldLength: 20,
    decimalLength: 0,
    fieldId: getUUID(),
    description: '主键id',
    defaultValue: null,
    realFlag: 'Y',
    newData: true
  },
  {
    fieldCode: 'create_time',
    fieldType: 50,
    fieldLength: null,
    decimalLength: null,
    fieldId: getUUID(),
    description: '创建日期',
    defaultValue: null,
    realFlag: 'Y',
    newData: true
  },
  {
    fieldCode: 'create_user',
    fieldType: 21,
    fieldLength: null,
    fieldId: getUUID(),
    decimalLength: null,
    description: '创建人',
    defaultValue: null,
    realFlag: 'Y',
    newData: true
  },
  {
    fieldCode: 'update_time',
    fieldType: 50,
    fieldLength: null,
    fieldId: getUUID(),
    decimalLength: null,
    description: '更新日期',
    defaultValue: null,
    realFlag: 'Y',
    newData: true
  },
  {
    fieldCode: 'update_user',
    fieldType: 21,
    fieldId: getUUID(),
    fieldLength: null,
    decimalLength: null,
    description: '更新人',
    defaultValue: null,
    realFlag: 'Y',
    newData: true
  }
]);

// 字段属性配置
const columns = ref([
  {
    title: '#',
    dataIndex: '#',
    key: '#',
    rowDrag: true,
    align: 'center',
    width: '50px'
  },
  {
    title: '字段名',
    key: 1,
    dataIndex: 'fieldCode'
  },
  {
    title: '描述',
    key: 2,
    dataIndex: 'description'
  },
  {
    title: '类型',
    width: '150px',
    key: 3,
    dataIndex: 'fieldType'
  },
  {
    title: '长度',
    width: '100px',
    align: 'center',
    key: 4,
    dataIndex: 'fieldLength'
  },
  {
    title: '小数点',
    width: '100px',
    align: 'center',
    key: 5,
    dataIndex: 'decimalLength'
  },
  {
    title: '默认值',
    align: 'center',
    width: '100px',
    key: 6,
    dataIndex: 'defaultValue'
  },
  {
    title: '表单类型',
    width: '150px',
    key: 7,
    dataIndex: 'defaultFormComponent'
  },
  {
    title: '实际字段',
    align: 'center',
    width: '100px',
    dataIndex: 'realFlag'
  },
  {
    title: '操作',
    dataIndex: 'action',
    width: '80px',
    align: 'center'
  }
]);

// 字段类型列表
const typeList = ref([]);

// 当前模型数据
const currentModelData = ref({});
// 当前模型定义id
const currentDefinitionId = ref('');

// 表单组件列表
const componentList = ref([]);

// 字段属性配置
const upColumns = ref([
  {
    title: '序号',
    dataIndex: 'index',
    align: 'center',
    width: '80px'
  },
  {
    title: '字段名',
    key: 1,
    dataIndex: 'fieldCode'
  },
  {
    title: '描述',
    key: 2,
    dataIndex: 'description',
    ellipsis: true
  },
  {
    title: '类型',
    width: '150px',
    key: 3,
    dataIndex: 'fieldType'
  },
  {
    title: '长度',
    width: '100px',
    align: 'center',
    key: 4,
    dataIndex: 'fieldLength'
  },
  {
    title: '小数点',
    width: '100px',
    align: 'center',
    key: 5,
    dataIndex: 'decimalLength'
  },
  {
    title: '默认值',
    align: 'center',
    width: '100px',
    key: 6,
    dataIndex: 'defaultValue'
  },
  {
    title: '表单类型',
    width: '150px',
    key: 7,
    dataIndex: 'defaultFormComponent'
  }
]);

// 旧的模型字段列表
const oldFieldList = ref([]);

const currentRow = ref(null);

const currentRowIndex = ref(0);

// 日志列表
const tableAlterLogList = ref([]);

const logColumns = ref([
  {
    title: '序号',
    dataIndex: 'index',
    align: 'center',
    width: '80px'
  },
  {
    title: '操作类型',
    dataIndex: 'operationType',
    align: 'center',
    width: '100px'
  },
  {
    title: '原字段名',
    width: '150px',
    ellipsis: true,
    dataIndex: 'originFieldCode'
  },
  {
    title: '新字段名',
    width: '150px',
    ellipsis: true,
    dataIndex: 'fieldCode'
  },
  {
    title: '描述',
    width: '150px',
    dataIndex: 'description',
    ellipsis: true
  },
  {
    title: '类型',
    width: '150px',
    key: 3,
    dataIndex: 'fieldType'
  },
  {
    title: '长度',
    width: '100px',
    align: 'center',
    key: 4,
    dataIndex: 'fieldLength'
  },
  {
    title: '小数点',
    width: '100px',
    align: 'center',
    key: 5,
    dataIndex: 'decimalLength'
  },
  {
    title: '默认值',
    align: 'center',
    width: '100px',
    key: 6,
    dataIndex: 'defaultValue'
  },
  {
    title: '表单类型',
    width: '150px',
    key: 7,
    dataIndex: 'defaultFormComponent'
  },
  {
    title: '在字段后',
    width: '100px',
    key: 8,
    dataIndex: 'afterFieldCode'
  },
  {
    title: '更新时间',
    align: 'center',
    width: '150px',
    dataIndex: 'updateTime'
  }
]);

// 字段查询类型
const fieldQueryType = ref('1');

// 是否禁用
const disabled = computed(() => value => {
  if (value.fieldCode && defaultData.value.find(item => item.fieldCode == value.fieldCode)) {
    return true;
  }
  return false;
});

// 是否是更新表
const tableCreateFlag = ref(false);

const loading = ref(false);

onMounted(() => {
  if (props.data || props.isBusiness) {
    getFieldTypeList();
    getFormComponentList();

    if (props.isBusiness) {
      treeSelect({ node: props.businessSheetData });
    }
  }
});

// 获取字段类型列表
const getFieldTypeList = async () => {
  const res = await SysDictTypeApi.getDictListByParams({ dictTypeCode: 'FIELD_TYPE' });
  typeList.value = res.map(item => {
    return { dictId: item.dictId, dictCode: Number(item.dictCode), dictName: item.dictName };
  });
};

// 获取表单组件列表
const getFormComponentList = () => {
  ModelFieldApi.getCodeGenerateComponentList().then(res => {
    if (res.code == '00000') {
      componentList.value = res.data;
    }
  });
};

// 选中事件
const onFocus = e => {
  e.target.focus();
};

// tab键按下
const tabClick = (e, record, column) => {
  if (e.key == 'Tab') {
    let dataIndex = '';
    if (column.key < 7) {
      dataIndex = columns.value[column.key + 1].dataIndex;
    } else {
      dataIndex = columns.value[1].dataIndex;
    }
    if (!dataIndex) return;
    setTimeout(() => {
      editClick(record, dataIndex);
    }, 100);
  }
};

// 左侧分类选中
const treeSelect = async metadata => {
  const res = await ModelFieldApi.validateTableExisted({ tableName: metadata.node.metaModelCode });
  tableCreateFlag.value = res.data;
  currentModelData.value = metadata.node;
  metaModelId.value = metadata.node.metaModelId;
  currentDefinitionId.value = metadata.node.currentDefinitionId;
  getFieldList();
};

// 获取字段列表
const getFieldList = () => {
  tableAlterLogList.value = [];
  currentRow.value = null;
  let params = {
    metaDefinitionId: currentDefinitionId.value
  };
  if (tableCreateFlag.value) {
    params.fieldQueryType = fieldQueryType.value;
  }
  ModelFieldApi.getFieldList(params).then(res => {
    if (tableCreateFlag.value) {
      let arr = res || [];
      metaFieldList.value = arr?.map(item => {
        return { ...item, originFieldCode: item.fieldCode };
      });
      oldFieldList.value = cloneDeep(metaFieldList.value);
    } else {
      if (!res || res?.length == 0) {
        metaFieldList.value = [...defaultData.value];
      } else {
        metaFieldList.value = res;
      }
    }
  });
};

// 添加字段
const addField = index => {
  let obj = {
    fieldCode: '',
    fieldType: 10,
    fieldLength: 255,
    decimalLength: 0,
    defaultValue: null,
    realFlag: 'Y',
    fieldId: getUUID(),
    fldSort: metaFieldList.value.length + 1,
    description: '',
    newData: true,
    defaultFormComponent: 'input'
  };
  if (index == 'N') {
    metaFieldList.value.splice(-4, 0, obj);
  } else {
    metaFieldList.value.splice(index, 0, obj);
  }

  metaFieldList.value = [].concat(metaFieldList.value);
};

const cellClick = (event, { record, index }) => {
  currentRow.value = record;
  currentRowIndex.value = index;
};

const rowClassName = (record, index) => {
  if (currentRow.value && record.fieldId == currentRow.value.fieldId) {
    return 'td-row-select';
  }
  return null;
};

// 添加字段
const addField1 = () => {
  addFieldFn('N');
};

// 插入字段
const insertField = () => {
  if (!currentRow.value) return message.warn('请选择需要插入的行');
  addFieldFn(currentRowIndex.value);
};

// 删除字段
const deleteField = () => {
  if (!currentRow.value) return message.warn('请选择需要删除的行');
  Modal.confirm({
    title: '删除提醒',
    content: '删除后将无法恢复，确定删除吗?',
    icon: createVNode(ExclamationCircleOutlined),
    maskClosable: true,
    wrapClassName: 'delete-modal',
    onOk: async () => {
      metaFieldList.value = metaFieldList.value.filter(item => item.fieldId !== currentRow.value.fieldId);
      if (fieldQueryType.value == '1') {
        if (currentRow.value?.newData) {
          tableAlterLogList.value = tableAlterLogList.value.filter(item => item.fieldId !== currentRow.value.fieldId);
        } else {
          let newData = { ...currentRow.value, operationType: 'DROP_COLUMN', updateTime: getNowTime() };
          updateObjectInArray(tableAlterLogList.value, newData, 'del');
        }
        tableAlterLogList.value = [...tableAlterLogList.value];
      }
      currentRow.value = null;
      currentRowIndex.value = 0;
    }
  });
};

// 判断是否存在数组中，如果存在，先删除，在加入
const updateObjectInArray = (arr, newObj, flag = 'edit', isMove = false) => {
  const fieldId = newObj.fieldId;

  // 查找当前数组中是否存在相同 fieldId 的对象
  const index = arr.findIndex(item => item.fieldId === fieldId);

  // 如果存在，先删除
  if (index !== -1) {
    arr.splice(index, 1);
  }
  let isTrurn = true;
  if (flag == 'edit') {
    let fieldCodeList = [
      'fieldCode',
      'fieldType',
      'fieldLength',
      'decimalLength',
      'defaultValue',
      'realFlag',
      'description',
      'defaultFormComponent'
    ];
    const oldData = oldFieldList.value.find(item => item.fieldId == newObj.fieldId);
    if (oldData) {
      isTrurn = isMove ? true : areFieldsEqual(newObj, oldData, fieldCodeList) ? false : true;
    }
  }

  // 然后将新的对象推入数组
  if (isTrurn) arr.push(newObj);
};

/**
 * 判断两个obj里面的字段值是否相等
 * @param obj1
 * @param obj2
 * @param fields
 */
const areFieldsEqual = (obj1, obj2, fields) => {
  for (let field of fields) {
    // 检查字段是否存在于两个对象中
    if (!(field in obj1) || !(field in obj2)) {
      return false; // 如果某个字段不存在，返回 false
    }

    // 获取字段的值
    const value1 = obj1[field];
    const value2 = obj2[field];

    // 特殊处理：0、null 和 undefined 视为相等
    if ((value1 === 0 || value1 === null || value1 === undefined) && (value2 === 0 || value2 === null || value2 === undefined)) {
      continue; // 如果两个值都是 0、null 或 undefined，继续下一轮
    }

    // 检查其他情况下的值是否相等
    if (value1 !== value2) {
      return false; // 如果值不相等，返回 false
    }
  }
  return true; // 如果所有字段的值都相等，返回 true
};

// 上移
const moveUp = () => {
  if (!currentRow.value) return message.warn('请选择需要上移的行');
  let arr = cloneDeep(metaFieldList.value);
  metaFieldList.value = moveItem(arr, currentRowIndex.value, 'up');
  metaFieldList.value = [...metaFieldList.value];
};

// 下移
const moveDown = () => {
  if (!currentRow.value) return message.warn('请选择需要下移的行');
  let arr = cloneDeep(metaFieldList.value);
  metaFieldList.value = moveItem(arr, currentRowIndex.value, 'down');
  metaFieldList.value = [...metaFieldList.value];
};

const moveItem = (arr, index, direction) => {
  // 确保索引有效
  if (index < 0 || index >= arr.length) {
    return arr;
  }

  // 根据方向决定移动的目标索引
  let targetIndex = direction === 'up' ? index - 1 : index + 1;

  // 确保目标索引有效
  if (targetIndex < 0 || targetIndex >= arr.length) {
    return arr;
  }

  // 交换位置
  [arr[index], arr[targetIndex]] = [arr[targetIndex], arr[index]];
  currentRowIndex.value = targetIndex;
  let afterFieldCode = findFieldCodeBeforeIndex(metaFieldList.value, direction == 'up' ? targetIndex : targetIndex + 1);
  let newData = {
    ...currentRow.value,
    operationType: currentRow.value?.newData ? 'ADD_COLUMN' : 'CHANGE_COLUMN',
    updateTime: getNowTime(),
    afterFieldCode
  };
  updateObjectInArray(tableAlterLogList.value, newData, 'edit', true);
  tableAlterLogList.value = [...tableAlterLogList.value];
  return arr;
};

// 添加字段
const addFieldFn = index => {
  let parentIndex = index == 'N' ? metaFieldList.value.length : index;
  let afterFieldCode = findFieldCodeBeforeIndex(metaFieldList.value, parentIndex);
  let obj = {
    fieldCode: '',
    fieldType: 10,
    fieldLength: 255,
    decimalLength: 0,
    defaultValue: null,
    realFlag: fieldQueryType.value == '1' ? 'Y' : 'N',
    fieldId: getUUID(),
    fldSort: metaFieldList.value.length + 1,
    description: '',
    newData: true,
    originFieldCode: '',
    defaultFormComponent: 'input'
  };
  if (index == 'N') {
    metaFieldList.value.push(obj);
  } else {
    metaFieldList.value.splice(index, 0, obj);
  }

  metaFieldList.value = [].concat(metaFieldList.value);
  currentRow.value = obj;
  const objIndex = metaFieldList.value.findIndex(item => item.fieldId == obj.fieldId);
  currentRowIndex.value = objIndex || 0;

  if (fieldQueryType.value == '1') {
    tableAlterLogList.value.push({ ...obj, operationType: 'ADD_COLUMN', afterFieldCode: afterFieldCode, updateTime: getNowTime() });
    tableAlterLogList.value = [...tableAlterLogList.value];
  }
};

const findFieldCodeBeforeIndex = (arr, index) => {
  // 如果索引为 0，返回 -1
  if (index === 0) {
    return '-1';
  }

  // 查找索引之前的数据
  for (let i = index - 1; i >= 0; i--) {
    if (arr[i].fieldCode) {
      return arr[i].fieldCode; // 返回找到的索引
    }
  }

  // 如果没有找到，返回 -1
  return '-1';
};

// 添加默认字段
const addDefaultField = async type => {
  if (type != 3) {
    const res = await ModelFieldApi.getDefaultFieldList({ defaultFieldType: type });
    if (res && res.length) {
      res.forEach(item => {
        item.fieldId = getUUID();
        item.newData = true;
        item.realFlag = 'Y';
        if (type == 2) {
          item.fieldLength = 1;
        }
        metaFieldList.value.splice(-4, 0, item);
      });
    }
  } else {
    let obj = {
      fieldCode: 'tenant_id',
      fieldType: 21,
      fieldLength: undefined,
      decimalLength: undefined,
      defaultValue: null,
      realFlag: 'Y',
      fieldId: getUUID(),
      fldSort: metaFieldList.value.length + 1,
      description: '租户id',
      newData: true
    };
    metaFieldList.value.splice(-4, 0, obj);
  }

  metaFieldList.value = [].concat(metaFieldList.value);
};

// 返回模型页面
const back = () => {
  emits('back');
};
// 拖拽
const rowDragEnd = dragData => {
  const { record, nextTargetInfo, preTargetInfo, dir } = dragData;
  if (defaultData.value.find(item => item.fieldCode == record.fieldCode)) {
    message.warning('默认数据不能拖拽');
    return false;
  } else if (dir == 'up') {
    if (nextTargetInfo && defaultData.value.find(item => item.fieldCode == nextTargetInfo.record.fieldCode)) {
      message.warning('默认数据不能拖拽');
      return false;
    }
  } else if (dir == 'down') {
    if (preTargetInfo && defaultData.value.find(item => item.fieldCode == preTargetInfo.record.fieldCode)) {
      message.warning('默认数据不能拖拽');
      return false;
    }
  }

  nextTick(() => {
    const arr = getData(metaFieldList.value);
    metaFieldList.value = JSON.parse(JSON.stringify(arr));
  });

  function getData(arr) {
    if (arr && arr.length > 0) {
      arr.forEach((item, index) => {
        item.fldSort = index;
      });
    }
    return arr;
  }
};

// 值改变
const valueChange = (val, record, fieldTypeName = 'fieldType') => {
  if (fieldTypeName == 'fieldType') {
    if (val == 10) {
      record.fieldLength = 255;
    } else if (val == 12) {
      record.fieldLength = 1;
    } else if (val == 30) {
      record.fieldLength = 10;
      record.decimalLength = 2;
    } else {
      record.fieldLength = undefined;
      record.decimalLength = undefined;
    }
    metaFieldList.value = [].concat(metaFieldList.value);
  }
  if (tableCreateFlag.value) {
    let newData = { ...record, operationType: record?.newData ? 'ADD_COLUMN' : 'CHANGE_COLUMN', updateTime: getNowTime() };
    updateObjectInArray(tableAlterLogList.value, newData, 'edit');
    tableAlterLogList.value = [...tableAlterLogList.value];
  }
};

// 删除
const remove = fieldId => {
  metaFieldList.value = metaFieldList.value.filter(item => item.fieldId !== fieldId);
};

// 升级并保存
const upgradeAndSave = () => {
  ModelApi.upgradeModel({ metaModelId: metaModelId.value }).then(res => {
    currentDefinitionId.value = res.data.metaDefinitionId;
    save();
  });
};

// 保存
const save = () => {
  metaFieldList.value = metaFieldList.value.filter(item => item.fieldCode);
  let saveMetaFieldList = cloneDeep(metaFieldList.value);
  if (saveMetaFieldList && saveMetaFieldList.length > 0) {
    saveMetaFieldList.forEach(item => {
      if (item.newData) delete item.fieldId;
    });
  }
  loading.value = true;
  ModelFieldApi.saveOrUpdateFieldList({
    metaFieldList: saveMetaFieldList,
    metaDefinitionId: currentDefinitionId.value
  }).then(res => {
    message.success(res.message);
    getFieldList();
  }).finally(() => loading.value = false);
};

const editClick = (record, dataIndex) => {
  if (!disabled.value(record)) {
    editableData.value[record.fieldId + dataIndex] = true;
    copyData.value = record;
    nextTick(() => {
      durationRef.value && durationRef.value.focus();
    });
  }
};

// 回车
const pressEnterValue = (e, record, dataIndex, index) => {
  if (!isNumberEnglish(record.fieldCode)) {
    message.error('输入的字段名格式不正确，请输入英文、数字、_');
    copyData.value.fieldCode = '';
  }
  if (e.code == 'Enter') {
  }
  delete editableData.value[record.fieldId + dataIndex];
  metaFieldList.value.splice(index, 1, copyData.value);
};

// 失去焦点
const editClosedTypeEvent = (record, dataIndex, index) => {
  if (!isNumberEnglish(record.fieldCode)) {
    message.error('输入的字段名格式不正确，请输入英文、数字、_');
    copyData.value.fieldCode = '';
  }
  delete editableData.value[record.fieldId + dataIndex];
  metaFieldList.value.splice(index, 1, copyData.value);
  if (tableCreateFlag.value) {
    let afterFieldCode = findFieldCodeBeforeIndex(metaFieldList.value, index);
    let newData = {
      ...record,
      operationType: record?.newData ? 'ADD_COLUMN' : 'CHANGE_COLUMN',
      updateTime: getNowTime(),
      afterFieldCode
    };
    updateObjectInArray(tableAlterLogList.value, newData, 'edit');
    tableAlterLogList.value = [...tableAlterLogList.value];
  }
};

// 创建表
const createSheet = () => {
  loading.value = true;
  ModelFieldApi.createTableIntoDb({ definitionId: currentDefinitionId.value }).then(res => {
    message.success(res.message);
    tableCreateFlag.value = true;
    getFieldList();
  }).finally(() => loading.value = false);
};
// 更新表
const updateSheet = () => {
  if (fieldQueryType.value == '1') {
    if (tableAlterLogList.value?.length == 0) return message.warn('修改记录不能为空！');
    if (tableAlterLogList.value?.length && !tableAlterLogList.value?.find(item => item.fieldCode)) return message.warn('字段名称不能为空');
  } else if (fieldQueryType.value == '2') {
  }

  Modal.confirm({
    title: '操作提醒',
    content: '您确定更新当前表吗?',
    icon: createVNode(ExclamationCircleOutlined),
    maskClosable: true,
    wrapClassName: 'delete-modal',
    onOk: async () => {
      loading.value = true;
      let result;
      if (fieldQueryType.value == '1') {
        result = ModelFieldApi.updateTableIntoDb({ definitionId: currentDefinitionId.value, tableAlterLogList: tableAlterLogList.value });
      } else {
        metaFieldList.value = metaFieldList.value.filter(item => item.fieldCode);
        let saveMetaFieldList = cloneDeep(metaFieldList.value);
        if (saveMetaFieldList && saveMetaFieldList.length > 0) {
          saveMetaFieldList.forEach(item => {
            if (item.newData) delete item.fieldId;
          });
        }
        result = ModelFieldApi.updateVirtualField({ metaFieldList: saveMetaFieldList, metaDefinitionId: currentDefinitionId.value });
      }
      result.then(res => {
        message.success(res.message);
        tableAlterLogList.value = [];
        currentRowIndex.value = 0;
        currentRow.value = null;
        getFieldList();
      }).finally(() => loading.value = false);
    }
  });
};
</script>

<style scoped lang="less">
:deep(.ant-btn-group > .ant-btn:first-child:not(:last-child)) {
  border-top-left-radius: 5px;
  border-bottom-left-radius: 5px;
  color: #1890ff;
  font-weight: bold;
}
:deep(.ant-btn-group > .ant-btn:last-child:not(:first-child)) {
  border-top-right-radius: 5px;
  border-bottom-right-radius: 5px;
}
.orange {
  color: orange;
  font-weight: bold;
}
.gree {
  color: #43cf7c;
  font-weight: bold;
}
.guns-layout-content-header {
  margin-top: 8px;
}
.real-t {
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  span {
    color: #60666b;
    font-size: 16px;
  }
  .t-v {
    color: #43505e;
    font-size: 18px;
  }
}
:deep(.surely-table-cell-text-ellipsis, .surely-table-cell-ellipsis) {
  .editable-cell {
    width: 100%;
    .editable-cell-text-wrapper {
      width: 100%;
      .span-t {
        display: block;
        width: 100%;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
    }
  }
}
:deep(.td-row-select) {
  background-color: var(--primary-1) !important;
}
</style>
