|
@@ -0,0 +1,334 @@
|
|
|
+<script>
|
|
|
+import { REFER } from "../popover-select/api/index";
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: "PopoverSelectV2",
|
|
|
+ props: {
|
|
|
+ // v-model
|
|
|
+ value: {
|
|
|
+ type: [Array, String,Number],
|
|
|
+ require: true,
|
|
|
+ },
|
|
|
+ // 参照类型 ,对应后端
|
|
|
+ referName: {
|
|
|
+ type: String,
|
|
|
+ require: true,
|
|
|
+ },
|
|
|
+ // 作为 value 唯一标识的键名,绑定值
|
|
|
+ valueKey: {
|
|
|
+ type: String,
|
|
|
+ dafault: () => {
|
|
|
+ return "code";
|
|
|
+ },
|
|
|
+ },
|
|
|
+ // 默认查询参数
|
|
|
+ queryParams: {
|
|
|
+ type: Function,
|
|
|
+ default: () => {},
|
|
|
+ },
|
|
|
+ // 需映射源数据
|
|
|
+ source: {
|
|
|
+ type: Object,
|
|
|
+ default: () => ({}),
|
|
|
+ },
|
|
|
+ // 参照内外映射
|
|
|
+ dataMapping: {
|
|
|
+ type: Object,
|
|
|
+ default: () => ({}),
|
|
|
+ },
|
|
|
+ // 多选
|
|
|
+ checkbox: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ // 参照弹窗标题
|
|
|
+ title: {
|
|
|
+ type: String,
|
|
|
+ dafault: () => {
|
|
|
+ return "TITEL";
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ 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,
|
|
|
+ model: {
|
|
|
+ search: "",
|
|
|
+ isPage: true,
|
|
|
+ },
|
|
|
+ data: [],
|
|
|
+ selectData: [],
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ innerValue: {
|
|
|
+ get() {
|
|
|
+ return this.value;
|
|
|
+ },
|
|
|
+ set(value) {
|
|
|
+ this.$emit("input", value);
|
|
|
+ },
|
|
|
+ },
|
|
|
+ TableColumns() {
|
|
|
+ const { referName } = this.$props;
|
|
|
+ return require(`../popover-select/components/${referName}`).default;
|
|
|
+ },
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ innerValue: {
|
|
|
+ handler: function (newValue) {
|
|
|
+ if (!newValue) {
|
|
|
+ const {
|
|
|
+ $props: { source, dataMapping },
|
|
|
+ } = this;
|
|
|
+ for (let key in dataMapping) {
|
|
|
+ source[key] = undefined;
|
|
|
+ }
|
|
|
+ this.$emit("update:source", source);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // open dialog
|
|
|
+ async open() {
|
|
|
+ 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;
|
|
|
+
|
|
|
+
|
|
|
+ // 处理新增字段无法映射
|
|
|
+ let that = this;
|
|
|
+
|
|
|
+ this.TableColumns.forEach(({item,attr}) =>{
|
|
|
+
|
|
|
+ that.data = that.data.map(d =>{
|
|
|
+
|
|
|
+ if(!attr.is && attr.formatter){
|
|
|
+ d[item.key] = attr.formatter(d);
|
|
|
+ }
|
|
|
+
|
|
|
+ return d;
|
|
|
+
|
|
|
+ })
|
|
|
+
|
|
|
+ })
|
|
|
+
|
|
|
+ this.page.total = total;
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ // catch
|
|
|
+ console.error(err);
|
|
|
+ } finally {
|
|
|
+ // finally
|
|
|
+ this.loading = false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // reset
|
|
|
+ async useReset() {
|
|
|
+ this.data = [];
|
|
|
+ this.page.pageNum = 1;
|
|
|
+ this.page.pageSize = 10;
|
|
|
+ this.model.search = null;
|
|
|
+ await this.fetchList(this.model, this.page);
|
|
|
+ },
|
|
|
+ // query
|
|
|
+ async useQuery() {
|
|
|
+ await this.fetchList(this.model, this.page);
|
|
|
+ },
|
|
|
+ // auto
|
|
|
+ async useAutocomplete(prop, cb) {
|
|
|
+ if (prop) {
|
|
|
+ this.page.pageSize = 1000000;
|
|
|
+ this.model.search = prop;
|
|
|
+ await this.fetchList(this.model, this.page);
|
|
|
+ await cb(this.data);
|
|
|
+ } else {
|
|
|
+ cb([]);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // select
|
|
|
+ useSelect(prop) {
|
|
|
+ this.selectData = prop;
|
|
|
+ },
|
|
|
+ // confirm
|
|
|
+ useConfirm(prop) {
|
|
|
+ this.hide();
|
|
|
+
|
|
|
+ const {
|
|
|
+ $props: { source, checkbox, valueKey, dataMapping },
|
|
|
+ } = this;
|
|
|
+
|
|
|
+ if (checkbox) {
|
|
|
+ this.selectData = [...prop];
|
|
|
+ this.$emit(
|
|
|
+ "change",
|
|
|
+ this.selectData.map((item) => {
|
|
|
+ for (let key in dataMapping) {
|
|
|
+ item[key] = item[dataMapping[key]];
|
|
|
+ }
|
|
|
+ return item;
|
|
|
+ }),
|
|
|
+ this.$props
|
|
|
+ );
|
|
|
+
|
|
|
+ } else {
|
|
|
+ for (let key in dataMapping) {
|
|
|
+ source[key] = prop[0][dataMapping[key]];
|
|
|
+ }
|
|
|
+ this.innerValue = prop[0][valueKey];
|
|
|
+ this.$emit("update:source", source);
|
|
|
+ this.$emit("change", prop[0], this.$props);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ created() {},
|
|
|
+ mounted() {},
|
|
|
+ destroyed() {},
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <div class="popover-select-v2">
|
|
|
+ <el-autocomplete
|
|
|
+ clearable
|
|
|
+ v-bind="$attrs"
|
|
|
+ v-model="innerValue"
|
|
|
+ :value-key="valueKey"
|
|
|
+ :fetch-suggestions="useAutocomplete"
|
|
|
+ @select="useConfirm([$event])"
|
|
|
+ style="width: 100%"
|
|
|
+ >
|
|
|
+ <i class="el-icon-search" slot="suffix" @click="open"> </i>
|
|
|
+ <template slot-scope="{ item }">
|
|
|
+ <p
|
|
|
+ style="
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ overflow: hidden;
|
|
|
+ line-height: 15px;
|
|
|
+ margin: 5px 0;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ {{ item.name }}
|
|
|
+ </p>
|
|
|
+ <p
|
|
|
+ style="
|
|
|
+ font-size: 12px;
|
|
|
+ color: #b4b4b4;
|
|
|
+ line-height: 15px;
|
|
|
+ margin: 5px 0;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ {{ item.code }}
|
|
|
+ </p>
|
|
|
+ </template>
|
|
|
+ </el-autocomplete>
|
|
|
+ <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-search" @click="useQuery">搜索</el-button>
|
|
|
+ <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"
|
|
|
+ :radio="!checkbox"
|
|
|
+ :checkbox="checkbox"
|
|
|
+ pagination
|
|
|
+ highlight-current-row
|
|
|
+ @pagination="useQuery"
|
|
|
+ @row-select="useSelect"
|
|
|
+ @row-dblclick="useConfirm([$event])"
|
|
|
+ >
|
|
|
+ </el-super-table>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<style scoped>
|
|
|
+.popover-select-v2 .el-autocomplete {
|
|
|
+ width: inherit;
|
|
|
+}
|
|
|
+.popover-select-v2 .el-autocomplete .el-icon-search {
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+::v-deep .el-table--mini .el-table__cell {
|
|
|
+ height: 50px;
|
|
|
+}
|
|
|
+</style>
|