index.vue 5.59 KB

<script lang="ts" setup name="Transfer">
import { ref, computed } from "vue";
import { Search, ArrowLeft, ArrowRight } from "@element-plus/icons-vue";
import Tree from "../Tree/index.vue";
import Table from "../Table/index.vue";

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

const emits = defineEmits(["btnClick", "toolBtnClick", "treeCheckboxChange", "checkboxChange", "tableSelectionChange", "tableDataFilter"]);

const queryValue = ref('');
const contents = computed(() => {
  console.log(props.transferInfo.contents);
  return props.transferInfo.contents ?? [];
});

const btnClick = (btn) => {
  if (btn.value == 'left' || btn.value == 'right') {
    emits('btnClick', btn.value, props.transferInfo.id)
  } else {
    emits('toolBtnClick', btn, props.transferInfo.id)
  }
}

const treeCheckboxChange = (checkedObj, treeId) => {
  emits('treeCheckboxChange', checkedObj, treeId)
}

const tableSelectionChange = (val, item) => {
  emits("tableSelectionChange", val, item);
};

const onQueryChanged = (val, tableId) => {
  emits('tableDataFilter', val, tableId)
};

</script>

<template>
  <div class="transfer_panel_wrap" :id="props.transferInfo.id">
    <div :class="{ 'transfer_btns': item.type == 'bar' }" :style="{ width: item.size }" v-for="item in contents">
      <div class="btns" v-if="item.type == 'bar'">
        <el-button v-for="bar in item.btns" :type="bar.disabled ? 'info' : 'primary'"
          :icon="bar.icon == 'ArrowLeft' ? ArrowLeft : ArrowRight" :disabled="bar.disabled" :plain="bar.disabled"
          @click="btnClick(bar)" v-preReClick />
      </div>
      <div class="transfer_panel" v-else>
        <div class="panel_title" v-if="item.header">
          <div class="title_text">
            <span>{{ item.header.title }}</span>
            <span class="tips_text">{{ item.header.tips }}</span>
          </div>
          <div class="title_tool" v-if="item.header.tool">
            <el-button v-for="btn in item.header.tool.btns" type="primary" text @click="btnClick(btn)" v-preReClick>{{ btn.label
            }}</el-button>
          </div>
        </div>
        <div class="panel_content" :class="{ full: !item.header }">
          <Tree v-if="item.type == 'tree'" :treeInfo="item.treeInfo" @nodeCheck="treeCheckboxChange" />
          <div class="table_content_wrap" v-else>
            <div class="panel_title" v-if="item.tools">
              <div class="title_text">
                <span>{{ item.tools.title }}</span>
                <span class="tips_text">{{ item.tools.tips }}</span>
              </div>
              <div class="title_tool" v-if="item.tools.tool">
                <template v-for="tool in item.tools.tool.items">
                  <el-input v-model.trim="tool.default" :placeholder="tool.placeholder" :prefix-icon="Search"
                    @input="val => onQueryChanged(val, item.tableInfo.id)" :clearable="tool.clearable" size="small" />
                </template>
              </div>
            </div>
            <div class="panel_body" v-loading="item.tableInfo.loading" :class="{ full: !item.tools }">
              <Table ref="formTableRef" :tableInfo="item.tableInfo" @tableSelectionChange="(val) => tableSelectionChange(val, item)" />
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.transfer_panel_wrap {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: space-between;

  >div {
    width: calc(50% - 28px);
  }

  .transfer_btns {
    width: 56px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;

    .el-button {
      margin: 0 8px;

      &+.el-button {
        margin-top: 8px;
      }
    }
  }

  :deep(.el-button) {
    &.is-text {
      height: auto;
      padding: 0;
    }
  }

  .transfer_panel {
    width: 100%;
    height: 100%;
    overflow: hidden;

    &.is-block {
      width: 100%;
    }

    .panel_title {
      height: 48px;
      padding: 0 15px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      color: var(--el-color-regular);
      font-weight: 600;
      border-bottom: 1px solid #d9d9d9;

      .tips_text {
        font-size: 14px;
        color: #999;
        font-weight: normal;
        margin-left: 8px;
      }
    }

    .panel_content {
      height: calc(100% - 46px);

      &.full {
        height: 100%;
      }

      >div {
        width: 100%;
        height: 100%;
        overflow: hidden;

        &.table_content_wrap {
          .panel_title {
            height: 32px;
            padding: 0;
            border: none;

            .title_text {
              color: var(--el-text-color-regular);
              font-size: 12px;
              font-weight: normal;
            }
          }

          .panel_body {
            height: calc(100% - 40px);
            // overflow: hidden;

            &.full {
              height: 100%;
            }

            .table_panel {
              min-height: unset;
            }
          }
        }
      }

      .form_panel {
        padding: 8px 16px 0;
        overflow: hidden auto;
      }

      .tree_search_input {
        margin-bottom: 10px;
      }

      .list_panel {
        padding: 10px 0;
        overflow: hidden auto;

        .list_item {
          height: 32px;
          padding: 0 10px;
          display: flex;
          justify-content: space-between;
          align-items: center;

          &:hover {
            color: var(--g-sub-sidebar-menu-active-color);
            background-color: var(--g-sub-sidebar-menu-active-bg);
          }
        }
      }
    }
  }
}
</style>