index.vue 5.53 KB
<script lang="ts" setup name="Popover">
import { ref, unref } from "vue";
import { Search, QuestionFilled } from "@element-plus/icons-vue";
import Table from "../Table/index.vue";

const props = defineProps({
  popoverInfo: {
    type: Object,
    default: {},
  },
});
const emits = defineEmits(["showPopver", "popverBtnClick"]);

const popoverRef = ref()
const inputValue = ref("");
const checkAll = ref(false);
const checkedVal: any = ref([])
const authorities: any = ref([])
const isIndeterminate = ref(false);

const size = computed(() => {
  return props.popoverInfo.size ?? 230;
})
const placement = computed(() => {
  return props.popoverInfo.placement ?? 'bottom-end';
})
const offset = computed(() => {
  return props.popoverInfo.offset ?? 0;
})
const trigger = computed(() => {
  return props.popoverInfo.trigger ?? 'click';
})
const type = computed(() => {
  return props.popoverInfo.type ?? '';
})
const tableInfo = computed(() => {
  return props.popoverInfo.tableInfo ?? {}
})
const actionInfo = computed(() => {
  return props.popoverInfo.actionInfo ?? {}
})
const btn = computed(() => {
  return props.popoverInfo.btn ?? {};
});

const dataProps = computed(() => {
  return <any>(props.popoverInfo.props || {});
});

const initAttr = () => {
  const data = props.popoverInfo.data ?? []
  const check = props.popoverInfo.checked ?? []
  checkedVal.value = check;
  checkAll.value = data.length > 0 && data.length == check?.filter(c => data.some(d => d.guid == c))?.length;
  isIndeterminate.value = !checkAll.value && (check.length > 0 && data.length > check.length)
  authorities.value = data
}

const filterPopover = (val) => {
  let data = props.popoverInfo.data ?? []
  if (val) {
    authorities.value = data.filter(item => item[dataProps.value.label || 'dataPermissionName'].indexOf(val) > -1)
  } else {
    authorities.value = data
  }
}

const handleCheckAllChange = (val) => {
  checkedVal.value = val ? authorities.value.map(item => item.guid) : [];
  isIndeterminate.value = false;
};
const handleCheckedCitiesChange = (val) => {
  const checkedCount = val?.filter(c => authorities.value.some(d => d.guid == c))?.length;
  checkAll.value = checkedCount > 0 && checkedCount === authorities.value.length;
  isIndeterminate.value = !checkAll.value && (checkedCount > 0 && checkedCount < authorities.value.length);
};
const showPopver = () => {
  inputValue.value = '';
  initAttr();
  emits('showPopver', props.popoverInfo.scope, btn.value)
}
const btnClick = () => {
  let scope = { ...props.popoverInfo.scope }
  scope.row.selectedData = checkedVal.value
  emits('popverBtnClick', scope, { ...btn.value, value: 'addRolePermise' })
  popoverRef.value?.hide()
}


watch(() => props.popoverInfo, async (val) => {
  if (val) {
    initAttr()
  }
})

</script>

<template>
  <el-popover ref="popoverRef" :placement="placement" :width="size" :offset="offset" :trigger="trigger"
    popper-class="table_cell_popover" :hide-after="100">
    <div class="self_content">
      <template v-if="type == 'table'">
        <Table :tableInfo="tableInfo" :action-info="actionInfo" />
      </template>
      <template v-else-if="type == 'checkbox-list-btns'">
        <div class="content_body">
          <el-input v-model.trim="inputValue" v-show="popoverInfo.data?.length > 8" :placeholder="props.popoverInfo.placeholder ?? '请输入权限名称'" :prefix-icon="Search" clearable
            @input="filterPopover" />
          <el-checkbox-group v-model="checkedVal" @change="handleCheckedCitiesChange">
            <el-checkbox v-for="auth in authorities" :key="auth.guid" :value="auth.guid">{{ auth[dataProps.label || 'dataPermissionName']
            }}</el-checkbox>
          </el-checkbox-group>
        </div>
        <div class="content_foot">
          <div class="selector">
            <el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange">
              全选
            </el-checkbox>
            <span>已选<span style="color: #4fa1a4; margin: 0 2px;">{{ checkedVal?.filter(c => authorities.some(d => d.guid == c))?.length }}</span></span>
          </div>
          <el-button size="small" type="primary" @click="btnClick" v-preReClick>确定</el-button>
        </div>
      </template>
    </div>
    <template #reference>
      <span v-if="btn.value == 'authority'" @click="showPopver" v-preReClick>{{ btn.label }}</span>
      <el-icon class="filter-icon" v-else-if="btn.value == 'filter'"  @click="showPopver">
         <svg-icon :name="checkedVal.length ? 'filter-mobile-select' : 'filter-mobile'" />
      </el-icon>
      <el-icon v-else-if="btn.value == 'QuestionFilled'">
        <QuestionFilled />
      </el-icon>
      <span v-else></span>
    </template>
  </el-popover>
</template>

<style lang="scss" scoped>
.self_content {
  :deep(.table_panel) {
    min-height: unset;
  }
}

.content_body {
  padding: 8px 8px 0;
}

.el-checkbox-group {
  margin: 0px -8px 0;
  max-height: 256px;
  overflow: hidden auto;

  .el-checkbox {
    --el-checkbox-font-size: 12px;

    display: flex;
    align-items: center;
    margin-right: 0;
    padding: 0 8px;
    color: var(--el-color-regular);

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

.content_foot {
  height: 40px;
  padding: 0 8px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  box-shadow: 0 -1px 0 0 #d9d9d9;

  .selector {
    display: flex;
    align-items: center;

    >span {
      margin-left: 12px;
      color: #999;
    }
  }

  .el-checkbox {
    --el-checkbox-font-size: 12px;
    color: var(--el-color-regular);
  }
}
</style>