dialog_grid.vue 5.42 KB
<script lang="ts" setup name="DialogGrid">
import { ref, computed, reactive } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { Search } from "@element-plus/icons-vue";
import Table from "../Table/index.vue";
import { setFormFields } from '@/utils/common'

const emits = defineEmits(["listSearch", "itemClick", "tableBtnClick"]);

const props = defineProps({
  gridInfo: {
    type: Object,
    default: {},
  },
});

const selectSource = ref("");
const fieldsTableInfoRef = ref()
const checkedFieldsTableRef = ref()
const keyValue = ref("");
const checkIndex = ref(-1);

const filters = ref({})

const sourceListInfo = computed(() => {
  return props.gridInfo.sourceListInfo ?? {}
})

const formItems = computed(() => {
  return props.gridInfo.sourceListInfo.filterItems ?? []
})
const formInline: any = computed(() => {
  return reactive(setFormFields(props.gridInfo.sourceListInfo.filterItems));
});

const fieldsTableInfo = computed(() => {
  return props.gridInfo.fieldsTableInfo ?? {}
})
const checkedFieldsTableInfo = computed(() => {
  return props.gridInfo.checkedFieldsTableInfo ?? {}
})

const search = (val) => {
  console.log()
  if (filters.value['dataSourceGuid'] == '') {
    ElMessage({
      type: 'error',
      message: '请选择数据源'
    })
  }
  /** 切换数据源之后选中的表清空。 */
  checkIndex.value = -1;
  emits('listSearch', formInline.value, val)
}

const itemClick = (row) => {
  emits('itemClick', row)
}

const tableBtnClick = (scope, btn) => {
  emits("tableBtnClick", scope, btn);
};

</script>
<template>
  <div class="dialog_panel_wrap">
    <div class="grid_panel">
      <div class="panel_header">
        <span>数据源对应的表</span>
      </div>
      <div class="panel_body">
        <div class="source_search">
          <template v-for="item in formItems">
            <el-select v-if="item.type == 'select'" v-model="formInline[item.field]" clearable placeholder="选择数据源"
              @change="(val) => search(val)">
              <el-option v-for="opts in item.options" :key="opts.value" :label="opts.label" :value="opts.value" />
            </el-select>
            <el-input v-else v-model.trim="formInline[item.field]" placeholder="关键字搜索" :suffix-icon="Search"
              clearable @input="(val) => search(val)" />
          </template>
        </div>
        <div class="sheet_panel" v-loading="sourceListInfo.loading">
          <div class="sheet_item" v-for="(item, i) in sourceListInfo.data" :class="{ active: checkIndex == i }"
            @click="checkIndex = i; itemClick(item)" v-preReClick>{{ item.tableName }}</div>
        </div>
      </div>
    </div>
    <div class="grid_panel col-1">
      <div class="panel_header">
        <span>{{ fieldsTableInfo.title ?? '表字段' }}</span>
      </div>
      <div class="panel_body">
        <Table ref="fieldsTableInfoRef" :tableInfo="fieldsTableInfo" @tableBtnClick="tableBtnClick" />
      </div>
    </div>
    <div class="grid_panel col-2">
      <div class="panel_header">
        <span>验证通过的字段</span>
      </div>
      <div class="panel_body">
        <Table ref="checkedFieldsTableRef" :tableInfo="checkedFieldsTableInfo" @tableBtnClick="tableBtnClick" />
      </div>
    </div>
  </div>
</template>
<style lang="scss" scoped>
.dialog_panel_wrap {
  display: flex;
  justify-content: space-between;

  .grid_panel {
    width: calc(25% - 8px);
    height: 452px;
    background: #ffffff;
    border: 1px solid rgba(217, 217, 217, 1);
    border-radius: 2px;
    overflow: hidden;

    &.col-1 {
      width: calc(30% - 8px);
    }

    &.col-2 {
      width: calc(45% - 8px);
    }

    .panel_header {
      padding: 0 12px;
      line-height: 32px;
      background: #f2f2f2;
      font-size: 12px;
      color: #666;
    }

    .panel_body {
      padding: 8px 0 0;
      height: calc(100% - 32px);

      .source_search {
        padding: 0 8px;

        >div {
          margin-bottom: 8px;
        }
      }

      .sheet_panel {
        height: calc(100% - 80px);
        overflow: hidden auto;
        
        .sheet_item {
          line-height: 32px;
          padding: 0 8px;
          font-size: 14px;
          color: var(--el-color-regular);
          cursor: default;

          &:hover {
            background-color: var(--el-option-bg-hover-color);
          }

          &.active {
            color: var(--el-color-primary);
            background-color: var(--el-menu-hover-bg-color);
          }
        }
      }

      .row_title {
        line-height: 32px;
        background: #f2f2f2;
        font-size: 14px;
        color: var(--el-color-regular);
        box-shadow: 0 1px 0 0 #d9d9d9;

        >span {
          display: inline-flex;
          padding: 0 8px;
          width: calc(100% - 80px);

          &+span {
            width: 80px;
            box-shadow: -1px 0 0 0 #d9d9d9;
          }
        }
      }

      .row_list {
        height: calc(100% - 32px);
        overflow: hidden auto;

        .row_item {
          line-height: 32px;
          font-size: 14px;
          color: var(--el-color-regular);
          box-shadow: 0 1px 0 0 #d9d9d9;

          >span {
            display: inline-flex;
            padding: 0 8px;
            width: calc(100% - 80px);

            &+span {
              width: 80px;
              box-shadow: -1px 0 0 0 #d9d9d9;
            }
          }
        }
      }
    }
  }
}

.table_panel {
  padding: 0;
  min-height: auto;
  margin: 1px -1px 0;
}
</style>