singleChoice.vue 5.76 KB
<!--
 * @Description: 
 * @Date: 2021-06-10 18:57:34
-->
<template>
  <div class="bi-single-choice" ref="bi-single-choice">
    <slot></slot>
    <vue-draggable
      class="bi-single-choice_group"
      :class="{ wrap: pageWrap }"
      handle=".bi-chart-title_name"
      v-model="copySingleChoice"
      :disabled="disabled"
      chosen-class="chosen"
      force-fallback="true"
      :group="groupName"
      animation="500"
      touchStartThreshold="0"
      @start="onStart"
      @end="onEnd"
    >
      <transition-group v-for="(item, index) in copySingleChoice" :key="index">
        <div
          :key="index"
          style="position:relative;"
          class="bi-single-choice_item_block"
        >
          <BiChartBlock
            ref="bi-single-choice_item"
            class="bi-single-choice_item"
            :style="{
              zIndex: guideStepShow(index, 3) ? 11 : ''
            }"
            :class="{ dragging: drag }"
            :showGuide="index === 0"
            :chartConfig="item"
          >
            <BiBlank height="28" slot="top"></BiBlank>
            <BiBlank height="28" slot="bottom"></BiBlank>
          </BiChartBlock>
          <BiTips v-if="guide.use && index === 0"></BiTips>
        </div>
      </transition-group>
    </vue-draggable>
  </div>
</template>

<script>
import BiBlank from '../commonComponents/blank.vue';
import BiChartBlock from '../commonComponents/chart-block.vue';
import BiTips from '../commonComponents/tips.vue';
import eventBus from '../eventBus/index';
import mixin from '../mixin/index';
import { getQueryVariable } from '../chart-type/common';

export default {
  name: 'bi-single-choice',
  mixins: [mixin],
  components: {
    BiBlank,
    BiTips,
    BiChartBlock,
    'vue-draggable':
      this.isPrint || getQueryVariable('print') == 1
        ? {
            template: '<div><slot></slot></div>'
          }
        : require('vuedraggable')
  },
  props: {
    singleChoice: {
      type: Array,
      default: () => []
    },
    pageWrap: Boolean,
    disabled: Boolean
  },
  data() {
    return {
      drag: false,
      groupName: `single-choice-chart-${parseInt(
        Math.random() * new Date().getTime()
      )}`,
      copySingleChoice: []
    };
  },
  computed: {
    guideStepShow() {
      return (index, step) =>
        index === 0 && this.guide.use && this.guide.step == step;
    }
  },
  methods: {
    onStart() {
      this.drag = true;
      document
        .getElementsByClassName('xrk-components-bi')[0]
        .parentElement.parentElement.parentElement.scrollTo(
          0,
          this.$refs['bi-single-choice'].offsetTop
        );
    },
    onEnd() {
      this.drag = false;
      this.$emit('sort', this.copySingleChoice);
    },
    getPageSize() {
      const topDom = (this.$slots.default || [{}])[0].elm || {
        offsetHeight: 0
      };
      const domArr = [
        {
          $el: topDom
        },
        ...(this.$refs['bi-single-choice_item'] || []).map(item => {
          let height = 0;
          item.pervPage = item.$children.reduce(
            (pre, { $el: { offsetHeight } }) => {
              height += offsetHeight;
              if (height >= 1697) {
                pre += 1;
                height = offsetHeight;
              }
              return pre;
            },
            0
          );
          return item;
        })
      ];
      const pageSizeInfo = {
        pervHeight: 0,
        pervPage: 0,
        height: 0,
        page: this.pageWrap ? 0 : 1
      };
      const catalogueInfoArr = [];
      domArr.forEach(
        ({ $el: { offsetHeight }, title, pervPage = 0 }, index) => {
          pageSizeInfo.height += offsetHeight;
          if (this.pageWrap) {
            if (index == 1) {
              // 遍历到第二个时,如果存在顶部标题,则将两个高度相加(汇总标题和表格不做强制分页)
              pageSizeInfo.pervHeight = offsetHeight + topDom.offsetHeight;
              if (offsetHeight + topDom.offsetHeight > 1697) {
                pageSizeInfo.page += 1;
              }
            } else {
              pageSizeInfo.page += pageSizeInfo.pervPage + 1;
              pageSizeInfo.pervPage = pervPage;
            }
          } else if (pageSizeInfo.height >= 1697) {
            pageSizeInfo.page += 1;
            pageSizeInfo.height = offsetHeight;
          }
          catalogueInfoArr.push({
            name: (title || {}).name,
            page: pageSizeInfo.page
          });
        }
      );

      this.$emit('page', {
        pageSize: pageSizeInfo.page,
        info: catalogueInfoArr
      });
    }
  },
  mounted() {
    eventBus.$on('addStep', () => {
      this.guide.step += 1;
    });
    eventBus.$on('hideGuide', () => {
      this.guide.use = false;
    });
  },
  watch: {
    singleChoice: {
      handler(v) {
        this.copySingleChoice = v;
        this.$nextTick(this.getPageSize);
      },
      deep: true,
      immediate: true
    }
  }
};
</script>

<style lang="scss" scoped>
.bi-single-choice {
  page-break-before: always;
  &_group {
    & > span {
      display: block;
      margin-top: 8px;
      page-break-inside: avoid;
      // & + span {
      // }
      &.chosen {
        border: 2px solid #016cd6;
        z-index: 9;
        position: relative;
      }
      &.sortable-fallback {
        height: 150px !important;
        overflow: hidden;
      }
    }
    &.wrap {
      & > span {
        & + span {
          page-break-before: always;
        }
      }
    }
  }
  &_item {
    padding: 0 28px;
    border-radius: 4px;
    border: 1px solid #f4f4f4;
    box-shadow: 0px 3px 6px rgba(27, 39, 64, 0.04);
    background-color: #fff;
    &_block {
      page-break-inside: avoid;
      // margin-top: 8px;
    }
    &.dragging {
      height: 140px;
      overflow: hidden;
    }
  }
}
</style>