Skip to content

Commit

Permalink
numberRange
Browse files Browse the repository at this point in the history
  • Loading branch information
szuprefix committed Oct 28, 2020
1 parent 72e9c58 commit 5c943cf
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 12 deletions.
103 changes: 103 additions & 0 deletions src/components/form/widgets/NumberRange.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<template>
<el-dropdown @command="handleCommand" trigger="click" class="number-range">
<el-button class="el-dropdown-link" :class="{empty: isEmpty}">
{{field.label}} {{selectValue}}<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="o in options" :command="o" v-key="o.text">{{o.text}}</el-dropdown-item>
<el-dropdown-item :command="undefined">无</el-dropdown-item>
<el-dropdown-item>
<div @click.stop="noCommand">
<el-input-number v-model="range[0]" controls-position="right" clearable
@change="onInputChange"></el-input-number>
-
<el-input-number v-model="range[1]" controls-position="right" clearable
@change="onInputChange"></el-input-number>
</div>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
import {get} from 'lodash'
// let DEFAULT_OPTIONS = [
// {text: '0-99', range: [0, 99]},
// {text: '100-199', range: [100, 199]},
// {text: '200-299', range: [200, 299]},
// {text: '300-', range: [300, 99999]}
//
// ]
export default{
props: {
value: String,
field: Object,
separator: {type: String, default: ''}
},
data () {
return {
selectValue: '',
range: [undefined, undefined]
}
},
components: {},
methods: {
handleCommand (c) {
if (!c) {
this.range = [undefined, undefined]
this.selectValue = null
} else {
this.range = c.range
this.selectValue = c.text || this.genRangeText(c.range)
}
},
noCommand() {
},
genRangeText(range) {
if (!range[0] && !range[1]) {
return null
}
else if (!range[0] && range[1]) {
return `${range[1]}及以下`
} else if (!range[1] && range[0]) {
return `${range[0]}及以上`
} else {
return `${range[0]}-${range[1]}`
}
},
onInputChange () {
this.selectValue = this.genRangeText(this.range)
}
},
computed: {
isEmpty () {
return !this.range[0] && !this.range[1]
},
options () {
return get(this.field, 'search.options') || [] // || DEFAULT_OPTIONS
}
},
watch: {
selectValue(v){
if (this.isEmpty) {
this.$emit('input', undefined)
} else {
let min = this.range[0] || 0
let max = this.range[1] || 999999
this.$emit('input', `${min},${max}`)
}
}
}
}
</script>
<style>
.number-range .empty {
color: lightgray;
}
.el-input.range_begin, .el-input.range_end {
width: 6rem;
text-align: right;
}
</style>
75 changes: 75 additions & 0 deletions src/components/form/widgets/NumberRange2.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<template>
<el-select class="number-range model-select" :placeholder="field.placeholder || `请选择${field.label}`" v-model="selectValue">
<el-option v-for="a in options" :key="a.key" :label="a.label" :value="a.value"></el-option>
<div>
<el-input v-model="range[0]" :placeholder="`${field.label}最小`" class="range_begin" type="number" clearable @change="onChange"></el-input>
-
<el-input v-model="range[1]" :placeholder="`${field.label}最大`" class="range_end" type="number" clearable @change="onChange"></el-input>
</div>
<template #empty>
<div>
<el-input v-model="range[0]" :placeholder="`${field.label}最小`" class="range_begin" type="number" clearable @change="onChange"></el-input>
-
<el-input v-model="range[1]" :placeholder="`${field.label}最大`" class="range_end" type="number" clearable @change="onChange"></el-input>
</div>
</template>
</el-select>
</template>
<script>
export default{
props: {
value: String,
field: Object,
separator: {type: String, default: ''}
},
data () {
return {
options: [],
defaultSeparator: '-',
selectValue: '',
range: [undefined, undefined]
}
},
components: {},
mounted () {
this.setRange()
},
methods: {
setRange () {
if(!this.value) {
this.range = [undefined, undefined]
} else {
let ps = this.value.split(this.separator).map(a => {
return parseInt(a) || undefined
})
if(ps.length<2) {
ps.append(undefined)
}
this.range = ps
}
},
onChange () {
let r = this.range
let s = r.join(this.separator) || undefined
this.selectValue = s
let label= (r[0] || r[1]) ? s.replace(this.separator, this.defaultSeparator) : ''
let opt = {key: 'self', label, value: s}
this.options = this.options.filter(a => a.key!== opt.key).concat([opt])
this.$emit(s)
}
},
computed: {},
watch: {
range () {
this.onChange()
}
}
}
</script>
<style>
.el-input.range_begin, .el-input.range_end {
width: 10rem;
text-align: right;
}
</style>
48 changes: 36 additions & 12 deletions src/components/model/Search.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<template>
<div>
<el-input title="模糊搜索, 多个关键词请用空格隔开"
:placeholder="`搜索${searchFieldNames}`"
v-model="value.search"
suffix-icon="el-icon-search"
@change="onSearch"
clearable
:style="`width:${searchFieldNames.length+5}rem;min-width:10rem;`"
ref="search"
v-if="searchFields.length>0">
:placeholder="`搜索${searchFieldNames}`"
v-model="value.search"
suffix-icon="el-icon-search"
@change="onSearch"
clearable
:style="`width:${searchFieldNames.length+5}rem;min-width:10rem;`"
ref="search"
v-if="searchFields.length>0">
</el-input>
<template v-for="f in visiableFilterFields">
<el-select v-model="value[f.name]" clearable :placeholder="`请选择${f.label}`" v-if="f.widget =='boolean'"
Expand All @@ -28,6 +28,9 @@
<date-range :field="f" v-model="value[`${f.name}__range`]" separator=","
:title="f.label" v-else-if="f.widget === 'daterange'" @input="onSearch"></date-range>

<number-range :field="f" v-model="value[`${f.name}__range`]" separator="-"
:title="f.label" v-else-if="f.widget === 'numberrange'" @input="onSearch"></number-range>

<array-input v-if="f.widget === 'array'"
v-model="value[`${f.name}__in`]" :placeholder="`批量查询${f.label}`" style="width: 10rem;"
:title="f.label" :autosize="{minRows:1,maxRows:4}" @change="onSearch"></array-input>
Expand All @@ -39,6 +42,7 @@
</template>
<script>
import DateRange from '../form/widgets/DateRange.vue'
import NumberRange from '../form/widgets/NumberRange.vue'
import ModelSelect from './Select.vue'
import ArrayInput from '../widgets/ArrayInput.vue'
import arrayNormalize from '../../utils/array_normalize'
Expand All @@ -47,7 +51,11 @@
model: Object,
items: Array,
value: Object,
map: {type: Object, default: () => { return {}}},
map: {
type: Object, default: () => {
return {}
}
},
exclude: [Array, Object]
},
data () {
Expand All @@ -58,7 +66,7 @@
baseQueries: {}
}
},
components: {ModelSelect, ArrayInput, DateRange},
components: {ModelSelect, ArrayInput, DateRange, NumberRange},
created () {
this.init()
},
Expand All @@ -74,9 +82,23 @@
let label = this.map[a.name] && this.map[a.name].label || a.label
return {multiple: false, ...a, label, widget: this.defaultWidget(a)}
})
this.addSelectOptions(ffields)
this.filterFields = this.reorder(ffields)
this.filters = Object.assign({}, this.getFilters())
},
addSelectOptions (fields) {
let ss = this.model.viewsConfig.search
if (!ss) {
return
}
console.log(ss)
fields.forEach(f => {
let a = ss[f.name]
if (a) {
f.search = a
}
})
},
defaultWidget (item) {
let f = item
if (f.type == 'boolean') {
Expand All @@ -87,14 +109,16 @@
return 'select'
} else if (['date', 'datetime'].includes(f.type) && f.lookups && f.lookups.includes('range')) {
return 'daterange'
} else if (['number', 'integer', 'decimal'].includes(f.type) && f.lookups && f.lookups.includes('range')) {
return 'numberrange'
} else if (f.type === 'string' && f.lookups && f.lookups.includes('in')) {
return 'array'
} else if (f.type === 'string' && f.lookups && f.lookups.includes('exact') && !f.lookups.includes('in')) {
return 'input'
}
},
reorder (items) {
let os = ['boolean', 'select', 'modelselect', 'input', 'array', 'daterange']
let os = ['boolean', 'select', 'modelselect', 'input', 'array', 'numberrange', 'daterange']
let rs = []
os.forEach(w => {
rs = rs.concat(items.filter(a => a.widget === w))
Expand Down Expand Up @@ -139,7 +163,7 @@
})
let rs = this.searchFields.filter((a) => !(a in vns))
let vm = {}
if(this.map) {
if (this.map) {
Object.keys(this.map).forEach(a => {
let c = this.model.fieldConfigs[a]
if (c) {
Expand Down
8 changes: 8 additions & 0 deletions src/utils/array_normalize.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
*/

export default function (items, templates, normalize) {
// console.log(templates)
// if(!(templates instanceof Array)) {
// templates = [templates]
// }
return items.map((a, i) => {
let d = {}
if (typeof a === 'string' || a instanceof String) {
Expand All @@ -11,7 +15,11 @@ export default function (items, templates, normalize) {
} else if (a instanceof Array) {
d = a
} else {
// templates.forEach(t => {
// Object.assign(d, t[a.name])
// })
Object.assign(d, templates[a.name], a)
// console.log(d)
}
if (normalize) {
d = normalize(d, i)
Expand Down

0 comments on commit 5c943cf

Please sign in to comment.