查询条件进行封装

62 阅读2分钟

一、先建一个 ListQueryForm.vue

<!-- eslint-disable vue/no-use-v-if-with-v-for -->
<template>
  <div class="search_box">
    <template v-if="formItems.length">
      <zk-form
        id="listQueryForm"
        ref="refListQueryForm"
        :label-width="labelWidth"
        :label-position="labelPosition"
        :model="listQueryForm">
        <!-- :item-min-width="268"-->
        <zk-flexbox
          handler
          :col-max-number="colMaxNum"
          :item-min-width="itemMinWidth"
          :gutter="[6, 8]">
          <zk-flexbox-item
            v-for="item in formItems"
            :key="item.key"
            v-if="!item.isHidden">
            <template #default>
              <!-- isHidden 是否隐藏 -->
              <zk-form-item :prop="item.model">
                <template slot="label">
                  <span v-if="item.bindingConfig.required" class="zk-form-item__required">*</span>
                  {{ item.bindingConfig.label }}
                  <zk-popover
                    v-if="item.bindingConfig.labelIntact"
                    trigger="hover"
                    :content="item.bindingConfig.labelIntact">
                    <i class="zds-icon-warning-filled" slot="reference"> </i>
                  </zk-popover>
                </template>
                <zk-select
                  v-if="item.type === 'select'"
                  v-model="item.value"
                  :placeholder="$tc('common.pleaseSelect')"
                  :size="item.bindingConfig.size"
                  :disabled="item.bindingConfig.disabled"
                  :multiple="item.bindingConfig.multiple"
                  :clearable="!item.bindingConfig.required"
                  filterable
                  :collapse-tags="item.bindingConfig.multiple"
                  :multiple-limit="item.bindingConfig.multipleLimit"
                  :all-select="item.bindingConfig?.allSelect !== undefined ? item.bindingConfig.allSelect : item.bindingConfig.multiple"
                  popper-class="option_a"
                  @change="bindChange(item)"
                  :filter-method="dataFilter">
                  <zk-option
                    v-for="opt in item.options"
                    :key="opt.value"
                    :label="opt.label"
                    :value="opt.value" />
                </zk-select>
                <zk-input
                  v-if="item.type === 'input'"
                  v-model="item.value"
                  :placeholder="$tc('common.pleaseInput')"
                  clearable
                  @blur="blurValue(item)"
                  @pressEnter="onSearch(item)">
                  <span
                    v-if="item.bindingConfig.isBatch"
                    slot="suffix"
                    @click="bacthHandle(item)">
                    <i
                      class="zds-icon-edit-filled"
                      title="Please use coma to seperate goodscode" />
                  </span>
                </zk-input>
                <zk-input
                  v-if="item.type === 'textarea'"
                  v-model="item.value"
                  clearable
                  :maxlength="item.bindingConfig.maxlength"
                  show-word-limit
                  :placeholder="$tc('common.pleaseInput')"
                  rows="3">
                </zk-input>
                <zk-date-picker
                  v-if="item.type === 'year'"
                  v-model="item.value"
                  type="year"
                  :placeholder="$tc('common.pleaseSelect')"
                  clearable></zk-date-picker>
                <zk-date-picker
                  v-if="item.type === 'monthrange'"
                  v-model="item.value"
                  type="month-range"
                  clearable
                  :placeholder="$tc('common.pleaseSelect')"
                  :picker-options="item.bindingConfig.pickerOptions"></zk-date-picker>
                <zk-date-picker
                  v-if="item.type === 'datePicker'"
                  v-model="item.value"
                  type="daterange"
                  :picker-options="item.bindingConfig.pickerOptions"
                  clearable />
                <zk-date-picker
                  v-if="item.type === 'datetimerange'"
                  v-model="item.value"
                  type="datetimerange"
                  :placeholder="$tc('common.pleaseSelect')"
                  :picker-options="item.bindingConfig.pickerOptions"
                  clearable />

                <zk-cascader
                  v-if="item.type === 'cascader'"
                  :placeholder="$tc('common.pleaseSelect')"
                  :data="item.options"
                  v-model="item.value"
                  clearable
                  filterable
                  :props="{ expandTrigger: 'hover' }"></zk-cascader>
                <div v-if="item.type === 'slot'">
                  <slot :name="item.slot" :scope="item" />
                </div>
              </zk-form-item>
            </template>
          </zk-flexbox-item>
          <template #handler>
            <!-- style="margin-top: 14px;" -->
            <zk-form-item>
              <zk-button plain type="secondary" @click="onReset">
                {{ $tc('common.reset') }}
              </zk-button>
              <zk-button type="outline" @click="onSearch" class="search_btn">
                {{ $tc('common.search') }}
              </zk-button>
            </zk-form-item>
          </template>
        </zk-flexbox>
      </zk-form>
    </template>
    <zk-modal
      v-model="visible"
      :title="$tc('common.Search in batch')"
      top="100px"
      width="700px"
      @on-cancel="batchCancel"
      @on-ok="batchOk">
      <div class="pure_flex">
        <p style="margin: 0 0 8px 0;">
          {{ batchTitle }}:
        </p>
        <zk-input
          v-model="batchValues"
          type="textarea"
          :placeholder="$tc('common.Please use coma to seperate')"
          rows="8"
          clearable />
      </div>
    </zk-modal>
  </div>
</template>

<script>
export default {
  name: 'ListQueryFormZeeKr',
  props: {
    labelWidth: {
      type: String,
      default: '120px',
    },
    labelPosition: {
      type: String,
      default: 'top',
    },
    // 筛选条件配置项
    formItems: {
      type: Array,
      required: true,
    },
    // 表格数据
    tableData: {
      type: Array,
      default: () => [],
    },
    colMaxNum: {
      type: Number,
      default: 4,
    },
    itemMinWidth: {
      type: Number,
      default: 280,
    },
  },
  data() {
    return {
      listQueryForm: {},
      // 是否显示批量模态框
      visible: false,
      // 批量模态框标题
      batchTitle: '',
      // 批量输入的值
      batchValues: '',
      // 当前点击批量输入的 对象
      batchObj: {},
      resetParams: {},
    };
  },
  mounted() {
    this.initForm();
  },
  methods: {
    initForm() {
      this.formItems.forEach((item) => {
        this.resetParams[item.model] = item.value;
      });
    },
    onSelectChange(data) {
      this.$emit('onSelectChange', data);
    },
    // 查询
    onSearch() {
      this.$emit('onSearch', this.formItems);
    },
    blurValue(item) {
      if (item.bindingConfig.isBatch) {
        item.value = this.commaSeparated(item.value);
      }
    },
    // 重置
    onReset() {
      this.formItems.forEach((item) => {
        if (item.default) {
          item.value = item.default;
        } else if (!item.bindingConfig.disabled) {
          item.value = item.value instanceof Array ? [] : '';
        }
        item.bindingConfig.onChange && item.bindingConfig.onChange(item);
      });
      this.$emit('onReset');
    },
    // 取消批量输入
    batchCancel() {
      this.batchValues = '';
      this.visible = false;
    },
    // 批量输入确定
    batchOk() {
      this.batchObj.value = this.commaSeparated(this.batchValues);
      this.visible = false;
      this.onSearch();
    },
    // 过滤输入内容
    commaSeparated(data) {
      let str = data.replace(/[ ,\n]/g, ',');
      const parts = str.split(',');
      // Filter out empty strings
      const filteredParts = parts.filter((part) => part !== '');
      // Join the filtered parts back into a string
      return filteredParts.join(',');
    },
    // 批量输入
    bacthHandle(item) {
      this.batchValues = item.value || '';
      this.batchTitle = item.bindingConfig.label;
      this.batchObj = item;
      this.visible = true;
    },
    // 筛选条件选中数据变更触发的事件
    bindChange(item) {
      item.bindingConfig.onChange && item.bindingConfig.onChange(item);
    },
    // 支持大小写字母查询
    dataFilter(keyword, value, label) {
      // 自定义搜索的方法,返回true展示
      return label.toLowerCase().search(keyword.toLowerCase()) > -1;
    },
  },
};
</script>

<style lang="less">
@import "./index.less";
.search_box {
  background: var(--color_bg-primary);
  // margin-top: 10px;
  .zk-page-container__content {
    padding: 11px 20px !important;
  }
  .hide .zk-form-item__label-text {
    font-size: 0;
  }
  .zk-form-item--placeholder {
    margin-bottom: 0;
  }
  .zds-icon-warning-filled {
    font-size: 16px;
  }
}
.search_btn {
  background: var(--color_bg-primary);
}
</style>


2. 如果在list.vue 里使用

<template>
    <ListQueryForm
        ref="form"
        :form-items="formItems"
        :itemMinWidth="268"
        @onSearch="onReset"
        :colMaxNum="5"
    @onReset="onReset" />
</template>

<script>
import ListQueryForm from '@/components/ListQueryForm/index.vue';
import { formItems } from './config.js';

 data() {
    return {
      formItems: [],
    };
  },
  async mounted() {
     // 根据当前实例初始化表单项目
     this.formItems = await formItems(this);
  },
</script>

3. 配置confin.js 文件

import { getZoneTree, queryCompanyBaseList } from '@/api/modules/claimRebatePayment';
import i18n from '@/locale';

function getRegionList(list) {
  getZoneTree({
    zoningNodeType: 'COUNTRY',
    useHeaderPrincipal: true,
    isChild: true
  }).then(res=> {
    let regionList = [];
    res.forEach(item => {
      regionList = [...regionList, ...item.childList];
    });
    regionList.forEach(item => {
      item.label = item.zoningName;
      item.value = item.zoningCode;
    });
    list.find((item) => item.model === 'regionList').options = regionList;
    getCountryList([], list, regionList);
  });
}

function getCountryList(regionList, list) {
  const countryOpts = [];
  const regionOpts = list.find((item) => item.model === 'regionList').options;
  if (regionList?.length) {
    regionList.forEach(region => {
      const index = regionOpts.findIndex(item => item.zoningCode === region);
      countryOpts.push(...regionOpts[index].childList);
    });
  } else {
    (regionOpts || []).forEach(item => {
      countryOpts.push(...item.childList);
    });
  }
  countryOpts.forEach(item => {
    item.label = item.zoningName;
    item.value = item.zoningCode;
  });
  list.find((item) => item.model === 'countryList').options = countryOpts;
  getCompanyOpts( list);
}

function getCompanyOpts(list) {
  const areaZoningCodeList = list.find((item) => item.model === 'regionList').value;
  const countryZoningCodeList = list.find((item) => item.model === 'countryList').value;
  queryCompanyBaseList({
    areaZoningCodeList,
    countryZoningCodeList,
  }).then(res => {
    let companyOpts = [];
    if (res.length) {
      companyOpts = res.map(item => ({
        label: item.companyName,
        value: item.companyCode,
      }));
      list.find((item) => item.model === 'companyList').options = companyOpts;
    }
    console.log(res, '===res');
  });

}
export const formItems = async (self) => {

  const list = [
    {
      type: 'input',
      model: 'intentionNoList',
      value: '',
      bindingConfig: {
        label: i18n.tc('Policy Application NO.'),
        isBatch: true,
      },
    },
    {
      type: 'select',
      model: 'intentionType',
      value: '',
      bindingConfig: {
        label: i18n.tc('Rebate Type'),
        multiple: false,
      },
      options: self.rebateTypeDataMap,
    },
    {
      type: 'select',
      model: 'regionList',
      value: [],
      bindingConfig: {
        label:i18n.tc('Region'),
        multiple: true,
        onChange: (ls) => {
          list.find((item) => item.model === 'countryList').options = [];
          list.find((item) => item.model === 'companyList').options = [];
          list.find((item) => item.model === 'countryList').value = [];
          list.find((item) => item.model === 'companyList').value = [];
          getCountryList(ls.value, list);
        },
      },
      options:[],
    },
    {
      type: 'select',
      model: 'countryList',
      value: [],
      bindingConfig: {
        label:  i18n.tc('Countries'),
        multiple: true,
        onChange: (ls) => {
          list.find((item) => item.model === 'companyList').options = [];
          list.find((item) => item.model === 'companyList').value = [];
          getCompanyOpts(list );
        },
      },
      options: [],
    },
    {
      type: 'select',
      model: 'companyList',
      value: [],
      bindingConfig: {
        label:i18n.tc('Company'),
        multiple: true,
      },
      options: [],
    },
    {
      type: 'select',
      model: 'status',
      value: '',
      bindingConfig: {
        label: i18n.tc('Approval Status'),
        multiple: false,
      },
      options: self.statusOpts,
    },


  ];
  getRegionList(list);
  return list;
};