Blame view

ant-design-vue-jeecg/src/components/jeecg/JSuperQuery.vue 12.4 KB
1
2
3
<template>
  <a-modal
    title="高级查询构造器"
4
    :width="1000"
5
6
7
8
    :visible="visible"
    @cancel="handleCancel"
    :mask="false"
    wrapClassName="ant-modal-cust-warp"
9
    class="j-super-query-modal"
10
    style="top:5%;max-height: 95%;">
11
12
    <template slot="footer">
13
14
15
16
17
18
      <div style="float: left">
        <a-button :loading="loading" @click="handleReset">重置</a-button>
        <a-button :loading="loading" @click="handleSave">保存查询条件</a-button>
      </div>
      <a-button :loading="loading" @click="handleCancel">关闭</a-button>
      <a-button :loading="loading" type="primary" @click="handleOk">查询</a-button>
19
20
    </template>
21
22
23
    <a-spin :spinning="loading">
      <a-row>
        <a-col :sm="24" :md="24-5">
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
          <a-empty v-if="queryParamsModel.length === 0">
            <div slot="description">
              <span>没有任何查询条件</span>
              <a-divider type="vertical"/>
              <a @click="handleAdd">点击新增</a>
            </div>
          </a-empty>

          <a-form v-else layout="inline">

            <a-form-item label="过滤条件匹配" style="margin-bottom: 12px;">
              <a-select v-model="selectValue">
                <a-select-option value="and">AND(所有条件都要求匹配)</a-select-option>
                <a-select-option value="or">OR(条件中的任意一个匹配)</a-select-option>
39
              </a-select>
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
            </a-form-item>

            <a-row type="flex" style="margin-bottom:10px" :gutter="16" v-for="(item, index) in queryParamsModel" :key="index">

              <a-col :span="8">
                <a-select placeholder="选择查询字段" v-model="item.field" @select="(val,option)=>handleSelected(option,item)">
                  <a-select-option v-for="(f,fIndex) in fieldList" :key=" 'field'+fIndex" :value="f.value" :data-idx="fIndex">{{ f.text }}</a-select-option>
                </a-select>
              </a-col>

              <a-col :span="4">
                <a-select placeholder="匹配规则" v-model="item.rule">
                  <a-select-option value="eq">等于</a-select-option>
                  <a-select-option value="ne">不等于</a-select-option>
                  <a-select-option value="gt">大于</a-select-option>
                  <a-select-option value="ge">大于等于</a-select-option>
                  <a-select-option value="lt">小于</a-select-option>
                  <a-select-option value="le">小于等于</a-select-option>
                  <a-select-option value="right_like">以..开始</a-select-option>
                  <a-select-option value="left_like">以..结尾</a-select-option>
                  <a-select-option value="like">包含</a-select-option>
                  <a-select-option value="in">在...中</a-select-option>
                </a-select>
              </a-col>

              <a-col :span="8">
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
                <template v-if="item.dictCode">
                  <template v-if="item.type === 'table-dict'">
                    <j-popup
                      v-model="item.val"
                      :code="item.dictTable"
                      :field="item.dictCode"
                      :orgFields="item.dictCode"
                      :destFields="item.dictCode"
                    ></j-popup>
                  </template>
                  <j-dict-select-tag v-else v-model="item.val" :dictCode="item.dictCode" placeholder="请选择"/>
                </template>
                <j-select-multi-user
                  v-else-if="item.type === 'select-user'"
                  v-model="item.val"
                  :buttons="false"
                  :multiple="false"
                  placeholder="请选择用户"
                  :returnKeys="['id', item.customReturnField || 'username']"
                />
                <j-select-depart
                  v-else-if="item.type === 'select-depart'"
                  v-model="item.val"
                  :multi="false"
                  placeholder="请选择部门"
                  :customReturnField="item.customReturnField || 'id'"
                />
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
                <j-date v-else-if=" item.type=='date' " v-model="item.val" placeholder="请选择日期" style="width: 100%"></j-date>
                <j-date v-else-if=" item.type=='datetime' " v-model="item.val" placeholder="请选择时间" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%"></j-date>
                <a-input-number v-else-if=" item.type=='int'||item.type=='number' " style="width: 100%" placeholder="请输入数值" v-model="item.val"/>
                <a-input v-else v-model="item.val" placeholder="请输入值"/>
              </a-col>

              <a-col :span="4">
                <a-button @click="handleAdd" icon="plus"></a-button>&nbsp;
                <a-button @click="handleDel( index )" icon="minus"></a-button>
              </a-col>

            </a-row>

          </a-form>
        </a-col>
        <a-col :sm="24" :md="5">
          <!-- 查询记录 -->

          <a-card class="j-super-query-history-card" :bordered="true">
            <div slot="title">
              保存的查询
            </div>
115
116

            <a-empty v-if="treeData.length === 0" class="j-super-query-history-empty" description="没有保存任何查询"/>
117
            <a-tree
118
              v-else
119
120
121
122
123
124
125
126
127
128
129
130
131
132
              class="j-super-query-history-tree"
              showIcon
              :treeData="treeData"
              @select="handleTreeSelect"
              @rightClick="handleTreeRightClick"
            >
            </a-tree>
          </a-card>


        </a-col>
      </a-row>
133
    </a-spin>
134
135
136
137
138

    <a-modal title="请输入保存的名称" :visible="prompt.visible" @cancel="prompt.visible=false" @ok="handlePromptOk">
      <a-input v-model="prompt.value"></a-input>
    </a-modal>
139
140
141
142
  </a-modal>
</template>

<script>
143
144
  import * as utils from '@/utils/util'
  import JDate from '@/components/jeecg/JDate.vue'
145
146
  import JSelectDepart from '@/components/jeecgbiz/JSelectDepart'
  import JSelectMultiUser from '@/components/jeecgbiz/JSelectMultiUser'
147
148
149

  export default {
    name: 'JSuperQuery',
150
    components: { JDate, JSelectDepart, JSelectMultiUser },
151
152
153
154
155
156
157
158
159
    props: {
      /*
       fieldList: [{
          value:'',
          text:'',
          type:'',
          dictCode:'' // 只要 dictCode 有值,无论 type 是什么,都显示为字典下拉框
       }]
       type:date datetime int number string
160
      * */
161
162
163
      fieldList: {
        type: Array,
        required: true
164
165
166
167
      },
      /*
      * 这个回调函数接收一个数组参数 即查询条件
      * */
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
      callback: {
        type: String,
        required: false,
        default: 'handleSuperQuery'
      },

      // 当前是否在加载中
      loading: {
        type: Boolean,
        default: false
      },

      // 保存查询条件的唯一 code,通过该 code 区分
      saveCode: {
        type: String,
        default: 'testSaveCode'
      }

    },
    data() {
      return {

        prompt: {
          visible: false,
          value: ''
        },

        visible: false,
        queryParamsModel: [{}],
        treeIcon: <a-icon type="file-text"/>,
        treeData: [],
        // 保存查询条件的前缀名
        saveCodeBefore: 'JSuperQuerySaved_',
        selectValue: 'and',
      }
    },
    watch: {
      // 当 saveCode 变化时,重新查询已保存的条件
      saveCode: {
        immediate: true,
        handler(val) {
          let list = this.$ls.get(this.saveCodeBefore + val)
          if (list instanceof Array) {
            this.treeData = list.map(item => {
              item.icon = this.treeIcon
              return item
            })
          }
        }
217
218
      }
    },
219
220
221
222

    methods: {
      show() {
        if (!this.queryParamsModel || this.queryParamsModel.length == 0) {
223
224
          this.queryParamsModel = [{}]
        }
225
        this.visible = true
226
      },
227
228
229
230
231
232
233
234
235
      handleOk() {
        console.log('---高级查询参数--->', this.queryParamsModel)
        if (!this.isNullArray(this.queryParamsModel)) {
          let event = {
            matchType: this.selectValue,
            params: this.removeEmptyObject(utils.cloneObject(this.queryParamsModel))
          }
          this.$emit(this.callback, event.params, event.matchType)
        } else {
236
237
238
          this.$emit(this.callback)
        }
      },
239
      handleCancel() {
240
241
        this.close()
      },
242
243
244
      close() {
        this.$emit('close')
        this.visible = false
245
      },
246
247
      handleAdd() {
        this.queryParamsModel.push({})
248
      },
249
250
      handleDel(index) {
        this.queryParamsModel.splice(index, 1)
251
      },
252
253
254
      handleSelected(option, item) {
        let index = option.data.attrs['data-idx']
255
        let { type, dictCode, dictTable, customReturnField } = this.fieldList[index]
256
257
        item['type'] = type
        item['dictCode'] = dictCode
258
259
260
        item['dictTable'] = dictTable
        item['customReturnField'] = customReturnField
        this.$set(item, 'val', '')
261
      },
262
263
      handleReset() {
        this.queryParamsModel = [{}]
264
265
        this.$emit(this.callback)
      },
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
      handleSave() {
        let queryParams = this.removeEmptyObject(utils.cloneObject(this.queryParamsModel))
        if (this.isNullArray(queryParams)) {
          this.$message.warning('空条件不能保存')
        } else {
          this.prompt.value = ''
          this.prompt.visible = true
        }
      },
      handlePromptOk() {

        let { value } = this.prompt
        // 判断有没有重名

        let filterList = this.treeData.filter(i => i.title === value)
        if (filterList.length > 0) {
          this.$confirm({
            content: `${value} 已存在,是否覆盖?`,
            onOk: () => {
              this.prompt.visible = false
              filterList[0].records = this.removeEmptyObject(utils.cloneObject(this.queryParamsModel))
              this.saveToLocalStore()
              this.$message.success('保存成功')
            }
          })
        } else {
          this.prompt.visible = false
          this.treeData.push({
            title: value,
            icon: this.treeIcon,
            records: this.removeEmptyObject(utils.cloneObject(this.queryParamsModel))
          })
          this.saveToLocalStore()
          this.$message.success('保存成功')
        }


      },
      handleTreeSelect(idx, event) {
        if (event.selectedNodes[0]) {
          this.queryParamsModel = utils.cloneObject(event.selectedNodes[0].data.props.records)
        }
      },
      handleTreeRightClick(args) {
        this.$confirm({
          content: '是否删除当前查询?',
          onOk: () => {
            let { node: { eventKey } } = args
            this.treeData.splice(Number.parseInt(eventKey.substring(2)), 1)
            this.saveToLocalStore()
            this.$message.success('删除成功')
          },
        })
      },

      // 将查询保存到 LocalStore 里
      saveToLocalStore() {
        this.$ls.set(this.saveCodeBefore + this.saveCode, this.treeData.map(item => {
          return { title: item.title, records: item.records }
        }))
      },

      isNullArray(array) {
329
        //判断是不是空数组对象
330
        if (!array || array.length === 0) {
331
332
          return true
        }
333
334
335
        if (array.length === 1) {
          let obj = array[0]
          if (!obj.field || !obj.val || !obj.rule) {
336
337
338
            return true
          }
        }
339
340
341
342
343
344
345
346
347
348
349
        return false
      },
      // 去掉数组中的空对象
      removeEmptyObject(array) {
        for (let i = 0; i < array.length; i++) {
          let item = array[i]
          if (item == null || Object.keys(item).length <= 0) {
            array.splice(i--, 1)
          }
        }
        return array
350
351
352
353
354
      }
    }
  }
</script>
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
<style lang="scss" scoped>

  .j-super-query-modal {

    /deep/ {
    }

    .j-super-query-history-card /deep/ {
      .ant-card-body,
      .ant-card-head-title {
        padding: 0;
      }

      .ant-card-head {
        padding: 4px 8px;
        min-height: initial;
      }
    }
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
    .j-super-query-history-empty /deep/ {
      .ant-empty-image {
        height: 80px;
        line-height: 80px;
        margin-bottom: 0;
      }

      img {
        width: 80px;
        height: 65px;
      }

      .ant-empty-description {
        color: #afafaf;
        margin: 8px 0;
      }
    }
392
393
394
395
396
397
398
399
400
401
402
    .j-super-query-history-tree /deep/ {
      .ant-tree-switcher {
        display: none;
      }

      .ant-tree-node-content-wrapper {
        width: 100%;
      }
    }

  }
403
404

</style>