<script>
export default {
  name: "PopoverSelect",
  props: {
    // 参照类型 ，对应后端
    type: {
      type: String,
      require: true,
    },
    // v-model
    value: {
      type: [Array, String],
      require: true,
    },
    // 参照弹窗标题
    title: {
      type: String,
      default: "TITLE",
    },
    // 作为 value 唯一标识的键名，绑定值为对象类型时必填
    valueKey: {
      type: String,
      default: "id",
    },
    // 默认查询参数
    queryParams: {
      type: Object,
      default: () => ({}),
    },
    // 组件大小
    size: {
      type: String,
      default: "mini",
    },
    // 提示
    placeholder: {
      type: String,
      default: "",
    },
    // 是否可读
    readonly: {
      type: Boolean,
      default: false,
    },
    // 是否禁止
    disabled: {
      type: Boolean,
      default: false,
    },
    // 是否清除
    clearable: {
      type: Boolean,
      default: false,
    },
    // 是否多选
    multiple: {
      type: Boolean,
      default: false,
    },
    // 需映射源数据
    source: Object,
    // 参照内外映射
    dataMapping: Object,
  },
  emits: ["hide"],
  components: {
    TableDialog: () => import("./components/index.vue"),
  },
  data() {
    return {
      // popover宽度
      width: "",
      // 显示value
      showValue: "",
      // 选中data
      data: [],
    };
  },
  computed: {},
  watch: {
    "$props.value": {
      handler: function (newProp, oldProp) {
        if (!newProp) {
          this.data = [];
          this.showValue = "";
        } else {
          this.showValue = newProp;
        }
      },
      immediate: true,
    },
  },
  methods: {
    // 打开弹窗
    handleAsyncOpenDialog() {
      this.$nextTick(() => {
        const { setVisible } = this.$refs.TableDialogFef;
        setVisible(true);
      });
    },
    // 新增操作
    handleAdd(prop) {
      this.data = prop;
      this.handleUpdate(this.data);
      this.$emit("hide", prop);
    },
    // 删除操作
    handleDelete(prop) {
      this.data.splice(prop, 1);
      this.handleUpdate(this.data);
    },
    // 更新操作
    handleUpdate(prop) {
      const { source, multiple, valueKey, dataMapping } = this.$props;
      // 多选
      if (multiple) {
        this.showValue = "";
        this.$emit(
          "input",
          prop.map((item) => item[valueKey])
        );
      }
      // 单选
      if (!multiple) {
        this.showValue = prop[0].name;
        this.$emit("input", prop[0][valueKey]);
        // 更新映射数据
        for (let key in dataMapping) {
          source[key] = prop[0][dataMapping[key]];
        }
        this.$emit("update:source", source);
      }
      //
      this.$emit("change", prop, source);
    },
  },
  created() {
    this.$nextTick(() => {
      const { clientWidth } = this.$refs.PopoverSelect;
      this.width = clientWidth;
    });
  },
  mounted() {},
  destroyed() {},
};
</script>
<template>
  <div ref="PopoverSelect" style="position: relative">
    <el-input
      v-model="showValue"
      :size="size"
      :disabled="disabled"
      :clearable="clearable"
      :placeholder="placeholder"
      readonly
      style="width: 100%; cursor: pointer"
      @click.native.stop="handleAsyncOpenDialog"
    >
      <template #suffix>
        <el-icon class="el-icon-more"></el-icon>
      </template>
    </el-input>
    <div
      v-if="multiple && data.length"
      style="
        position: absolute;
        left: 10px;
        top: 50%;
        transform: translateY(-50%);
        padding-right: 30px;
        overflow: hidden;
      "
    >
      <div style="width: 150px; display: flex">
        <el-popover
          :offset="-10"
          :width="width"
          :visible-arrow="false"
          title=""
          content=""
          trigger="click"
          placement="bottom-start"
        >
          <el-tag slot="reference" :size="size" style="margin-right: 10px">
            + {{ data.length }}
          </el-tag>
          <el-tag
            v-for="(item, index) in data"
            :size="size"
            hit
            closable
            style="
              display: flex;
              justify-content: space-between;
              align-items: center;
              margin: 0 0 5px 0;
            "
            @close="handleDelete(index)"
          >
            {{ item.name }}
          </el-tag>
        </el-popover>
      </div>
    </div>
    <table-dialog
      v-model="data"
      ref="TableDialogFef"
      :type="type"
      :title="title"
      :multiple="multiple"
      :queryParams="queryParams"
      @confirm="handleAdd"
    ></table-dialog>
  </div>
</template>
<style scoped></style>
