|
@@ -0,0 +1,296 @@
|
|
|
|
+<script>
|
|
|
|
+import { REFER } from "../popover-select/api/index";
|
|
|
|
+import deepCopy from "@gby/deep-copy";
|
|
|
|
+
|
|
|
|
+export default {
|
|
|
|
+ name: "PopoverSelectV2",
|
|
|
|
+ props: {
|
|
|
|
+ // v-model
|
|
|
|
+ value: {
|
|
|
|
+ type: [Array, String, Number],
|
|
|
|
+ require: true,
|
|
|
|
+ },
|
|
|
|
+ // 参照类型 ,对应后端
|
|
|
|
+ referName: {
|
|
|
|
+ type: String,
|
|
|
|
+ require: true,
|
|
|
|
+ },
|
|
|
|
+ // 作为 value 唯一标识的键名,绑定值
|
|
|
|
+ valueKey: {
|
|
|
|
+ type: [String, null, undefined],
|
|
|
|
+ },
|
|
|
|
+ // 默认查询参数
|
|
|
|
+ queryParams: {
|
|
|
|
+ type: Function,
|
|
|
|
+ default: () => {},
|
|
|
|
+ },
|
|
|
|
+ // 需映射源数据
|
|
|
|
+ source: {
|
|
|
|
+ type: Object,
|
|
|
|
+ default: () => ({}),
|
|
|
|
+ },
|
|
|
|
+ // 参照内外映射
|
|
|
|
+ dataMapping: {
|
|
|
|
+ type: Object,
|
|
|
|
+ default: () => ({}),
|
|
|
|
+ },
|
|
|
|
+ // 回显
|
|
|
|
+ dataListArray: {
|
|
|
|
+ type: Array
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ components: {
|
|
|
|
+ ElSuperTable: () => import("@/components/super-table/index.vue"),
|
|
|
|
+ },
|
|
|
|
+ data() {
|
|
|
|
+ return {
|
|
|
|
+ size: "mini",
|
|
|
|
+ width: "50%",
|
|
|
|
+ page: { pageNum: 1, pageSize: 10, total: 0 },
|
|
|
|
+ visible: false,
|
|
|
|
+ loading: false,
|
|
|
|
+ scroll: false,
|
|
|
|
+ model: {
|
|
|
|
+ search: "",
|
|
|
|
+ isPage: true,
|
|
|
|
+ },
|
|
|
|
+ data: [],
|
|
|
|
+ selectData: [],
|
|
|
|
+ lastSelectData: [],
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+ computed: {
|
|
|
|
+ innerValue: {
|
|
|
|
+ get() {
|
|
|
|
+ return this.value;
|
|
|
|
+ },
|
|
|
|
+ set(value) {
|
|
|
|
+ this.$emit("input", value);
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ TableColumns: {
|
|
|
|
+ get() {
|
|
|
|
+ const { referName } = this.$props;
|
|
|
|
+ return require(`../popover-select/components/${referName}`).default;
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ watch: {
|
|
|
|
+ innerValue: {
|
|
|
|
+ handler: function (newValue) {
|
|
|
|
+ if (!newValue) this.lastSelectData = [];
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ dataListArray: {
|
|
|
|
+ handler: function (newValue) {
|
|
|
|
+ console.log("A:::" + JSON.stringify(newValue))
|
|
|
|
+ if (newValue.length>0){
|
|
|
|
+ newValue.forEach(element => {
|
|
|
|
+ this.lastSelectData.push(element)
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ immediate: true
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ // open dialog
|
|
|
|
+ async open() {
|
|
|
|
+ let { disabled } = this.$attrs;
|
|
|
|
+ if (!disabled) {
|
|
|
|
+ this.visible = true;
|
|
|
|
+ await this.useReset();
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // hide dialog
|
|
|
|
+ async hide() {
|
|
|
|
+ this.visible = false;
|
|
|
|
+ },
|
|
|
|
+ // fetch list
|
|
|
|
+ async fetchList(prop, page) {
|
|
|
|
+ try {
|
|
|
|
+ // try
|
|
|
|
+ this.loading = true;
|
|
|
|
+ const { pageNum, pageSize } = page;
|
|
|
|
+ const { referName: type, source, queryParams } = this.$props;
|
|
|
|
+ const { code, rows, total } = await REFER(
|
|
|
|
+ {
|
|
|
|
+ ...prop,
|
|
|
|
+ ...queryParams(source),
|
|
|
|
+ type: type,
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ pageNum,
|
|
|
|
+ pageSize,
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ if (code === 200) {
|
|
|
|
+ this.data = rows;
|
|
|
|
+ this.page.total = total;
|
|
|
|
+ }
|
|
|
|
+ } catch (err) {
|
|
|
|
+ // catch
|
|
|
|
+ console.error(err);
|
|
|
|
+ } finally {
|
|
|
|
+ // finally
|
|
|
|
+ this.loading = false;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // reset
|
|
|
|
+ async useReset() {
|
|
|
|
+ this.data = [];
|
|
|
|
+ this.model.search = null;
|
|
|
|
+ await this.fetchList(this.model, this.page);
|
|
|
|
+ },
|
|
|
|
+ // query
|
|
|
|
+ async useQuery() {
|
|
|
|
+ await this.fetchList(this.model, this.page);
|
|
|
|
+ },
|
|
|
|
+ // select
|
|
|
|
+ useSelect(prop) {
|
|
|
|
+ this.selectData = prop;
|
|
|
|
+ },
|
|
|
|
+ // delete
|
|
|
|
+ useDelete(prop) {
|
|
|
|
+ this.selectData.splice(prop, 1);
|
|
|
|
+ this.useConfirm(this.selectData);
|
|
|
|
+ },
|
|
|
|
+ // confirm
|
|
|
|
+ useConfirm(prop) {
|
|
|
|
+ const {
|
|
|
|
+ $props: { valueKey },
|
|
|
|
+ } = this;
|
|
|
|
+ // string
|
|
|
|
+ if (typeof valueKey === "string") {
|
|
|
|
+ this.innerValue = prop.map((item) => item[valueKey]);
|
|
|
|
+ }
|
|
|
|
+ // null
|
|
|
|
+ else {
|
|
|
|
+ this.innerValue = prop;
|
|
|
|
+ }
|
|
|
|
+ //
|
|
|
|
+ this.hide();
|
|
|
|
+ this.lastSelectData = deepCopy(prop);
|
|
|
|
+ // console.log("A:::" + JSON.stringify(this.lastSelectData))
|
|
|
|
+ this.$emit("change", prop, this.$props);
|
|
|
|
+ },
|
|
|
|
+ // cancel
|
|
|
|
+ useCancel() {
|
|
|
|
+ this.hide();
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ created() {},
|
|
|
|
+ mounted() {},
|
|
|
|
+ destroyed() {},
|
|
|
|
+};
|
|
|
|
+</script>
|
|
|
|
+<template>
|
|
|
|
+ <div class="popover-select-v2 popover-select-v2--multiple">
|
|
|
|
+ <el-input v-bind="$attrs" @focus="open">
|
|
|
|
+ <i class="el-icon-search" slot="suffix" @click="open"> </i>
|
|
|
|
+ </el-input>
|
|
|
|
+ <el-dialog
|
|
|
|
+ :width="width"
|
|
|
|
+ :visible.sync="visible"
|
|
|
|
+ :show-close="false"
|
|
|
|
+ :close-on-click-modal="false"
|
|
|
|
+ :close-on-press-escape="false"
|
|
|
|
+ append-to-body
|
|
|
|
+ >
|
|
|
|
+ <div slot="title" style="display: flex; justify-content: space-between">
|
|
|
|
+ <el-form
|
|
|
|
+ :size="size"
|
|
|
|
+ :inline="true"
|
|
|
|
+ :model="model"
|
|
|
|
+ @submit.native.prevent
|
|
|
|
+ style="display: flex; flex-direction: column"
|
|
|
|
+ >
|
|
|
|
+ <div>
|
|
|
|
+ <el-form-item prop="search">
|
|
|
|
+ <el-input
|
|
|
|
+ v-model="model.search"
|
|
|
|
+ @change="useQuery"
|
|
|
|
+ @keydown.enter="useQuery"
|
|
|
|
+ >
|
|
|
|
+ </el-input>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item>
|
|
|
|
+ <el-button icon="el-icon-refresh" @click="useReset"></el-button>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ </div>
|
|
|
|
+ </el-form>
|
|
|
|
+ <div>
|
|
|
|
+ <el-button
|
|
|
|
+ type="primary"
|
|
|
|
+ :size="$attrs.size"
|
|
|
|
+ :loading="loading"
|
|
|
|
+ @click="useConfirm(selectData)"
|
|
|
|
+ >
|
|
|
|
+ 确认
|
|
|
|
+ </el-button>
|
|
|
|
+ <el-button :size="$attrs.size" :loading="loading" @click="hide">
|
|
|
|
+ 取消
|
|
|
|
+ </el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div
|
|
|
|
+ v-loading="loading"
|
|
|
|
+ style="height: 40vh; display: flex; margin-top: -30px"
|
|
|
|
+ >
|
|
|
|
+ <el-super-table
|
|
|
|
+ v-model="data"
|
|
|
|
+ :size="size"
|
|
|
|
+ :page="page"
|
|
|
|
+ :columns="TableColumns"
|
|
|
|
+ checkbox
|
|
|
|
+ pagination
|
|
|
|
+ highlight-current-row
|
|
|
|
+ @pagination="useQuery"
|
|
|
|
+ @row-select="useSelect"
|
|
|
|
+ @row-dblclick="useConfirm([$event])"
|
|
|
|
+ >
|
|
|
|
+ </el-super-table>
|
|
|
|
+ </div>
|
|
|
|
+ </el-dialog>
|
|
|
|
+ <el-scrollbar
|
|
|
|
+ v-if="lastSelectData.length"
|
|
|
|
+ :viewStyle="{
|
|
|
|
+ display: 'flex',
|
|
|
|
+ alignItems: 'center',
|
|
|
|
+ padding: '5px 0 0 5px',
|
|
|
|
+ }"
|
|
|
|
+ class="popover-select-v2_tags"
|
|
|
|
+ >
|
|
|
|
+ <el-tag
|
|
|
|
+ v-for="(tag, index) in lastSelectData"
|
|
|
|
+ hit
|
|
|
|
+ closable
|
|
|
|
+ :size="size"
|
|
|
|
+ @close="useDelete(index)"
|
|
|
|
+ style="margin-right: 5px"
|
|
|
|
+ >
|
|
|
|
+ {{ tag.name || tag[valueKey] }}
|
|
|
|
+ </el-tag>
|
|
|
|
+ </el-scrollbar>
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+<style scoped>
|
|
|
|
+.popover-select-v2 .el-input {
|
|
|
|
+ width: inherit;
|
|
|
|
+ height: 100%;
|
|
|
|
+}
|
|
|
|
+.popover-select-v2 .el-input .el-icon-search {
|
|
|
|
+ cursor: pointer;
|
|
|
|
+}
|
|
|
|
+.popover-select-v2 .popover-select-v2_tags {
|
|
|
|
+ position: absolute;
|
|
|
|
+ left: 0;
|
|
|
|
+ top: 50%;
|
|
|
|
+ transform: translateY(-50%);
|
|
|
|
+ width: calc(100% - 40px);
|
|
|
|
+ height: 100%;
|
|
|
|
+}
|
|
|
|
+::v-deep .el-table--mini .el-table__cell {
|
|
|
|
+ height: 50px;
|
|
|
|
+}
|
|
|
|
+</style>
|