262 lines
6.8 KiB
JavaScript
262 lines
6.8 KiB
JavaScript
import debounce from 'lodash/debounce'
|
||
import { getAction } from '@/api/manage'
|
||
import { cloneObject } from '@/utils/util'
|
||
import { filterDictText } from '@/components/dict/JDictSelectUtil'
|
||
import { ajaxGetDictItems, getDictItemsFromCache } from '@/api/api'
|
||
import JVxeCellMixins, { dispatchEvent } from '@/components/jeecg/JVxeTable/mixins/JVxeCellMixins'
|
||
|
||
/** 公共资源 */
|
||
const common = {
|
||
/** value - label map,防止重复查询(刷新清空缓存) */
|
||
labelMap: new Map(),
|
||
|
||
/** 公共data */
|
||
data() {
|
||
return {
|
||
loading: false,
|
||
innerSelectValue: null,
|
||
innerOptions: [],
|
||
}
|
||
},
|
||
/** 公共计算属性 */
|
||
computed: {
|
||
dict() {
|
||
return this.originColumn.dict
|
||
},
|
||
options() {
|
||
if (this.isAsync) {
|
||
return this.innerOptions
|
||
} else {
|
||
return this.originColumn.options || []
|
||
}
|
||
},
|
||
// 是否是异步模式
|
||
isAsync() {
|
||
let isAsync = this.originColumn.async
|
||
return (isAsync != null && isAsync !== '') ? !!isAsync : true
|
||
},
|
||
},
|
||
/** 公共属性监听 */
|
||
watch: {
|
||
innerValue: {
|
||
immediate: true,
|
||
handler(value) {
|
||
if (value == null || value === '') {
|
||
this.innerSelectValue = null
|
||
} else {
|
||
this.loadDataByValue(value)
|
||
}
|
||
}
|
||
},
|
||
dict() {
|
||
this.loadDataByDict()
|
||
}
|
||
},
|
||
/** 公共方法 */
|
||
methods: {
|
||
|
||
// 根据 value 查询数据,用于回显
|
||
async loadDataByValue(value) {
|
||
if (this.isAsync) {
|
||
if (this.innerSelectValue !== value) {
|
||
if (common.labelMap.has(value)) {
|
||
this.innerOptions = cloneObject(common.labelMap.get(value))
|
||
} else {
|
||
let {success, result} = await getAction(`/sys/dict/loadDictItem/${this.dict}`, {key: value})
|
||
if (success && result && result.length > 0) {
|
||
this.innerOptions = [{value: value, text: result[0]}]
|
||
common.labelMap.set(value, cloneObject(this.innerOptions))
|
||
}
|
||
}
|
||
}
|
||
}
|
||
this.innerSelectValue = (value || '').toString()
|
||
},
|
||
|
||
// 初始化字典
|
||
async loadDataByDict() {
|
||
if (!this.isAsync) {
|
||
// 如果字典项集合有数据
|
||
if (!this.originColumn.options || this.originColumn.options.length === 0) {
|
||
// 根据字典Code, 初始化字典数组
|
||
let dictStr = ''
|
||
if (this.dict) {
|
||
let arr = this.dict.split(',')
|
||
if (arr[0].indexOf('where') > 0) {
|
||
let tbInfo = arr[0].split('where')
|
||
dictStr = tbInfo[0].trim() + ',' + arr[1] + ',' + arr[2] + ',' + encodeURIComponent(tbInfo[1])
|
||
} else {
|
||
dictStr = this.dict
|
||
}
|
||
if (this.dict.indexOf(',') === -1) {
|
||
//优先从缓存中读取字典配置
|
||
let cache = getDictItemsFromCache(this.dict)
|
||
if (cache) {
|
||
this.innerOptions = cache
|
||
return
|
||
}
|
||
}
|
||
let {success, result} = await ajaxGetDictItems(dictStr, null)
|
||
if (success) {
|
||
this.innerOptions = result
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
|
||
},
|
||
|
||
}
|
||
|
||
// 显示组件,自带翻译
|
||
export const DictSearchSpanCell = {
|
||
name: 'JVxeSelectSearchSpanCell',
|
||
mixins: [JVxeCellMixins],
|
||
data() {
|
||
return {
|
||
...common.data.apply(this),
|
||
}
|
||
},
|
||
computed: {
|
||
...common.computed,
|
||
},
|
||
watch: {
|
||
...common.watch,
|
||
},
|
||
methods: {
|
||
...common.methods,
|
||
},
|
||
render(h) {
|
||
return h('span', {}, [
|
||
filterDictText(this.innerOptions, this.innerSelectValue || this.innerValue)
|
||
])
|
||
},
|
||
}
|
||
|
||
// 请求id
|
||
let requestId = 0
|
||
|
||
// 输入选择组件
|
||
export const DictSearchInputCell = {
|
||
name: 'JVxeSelectSearchInputCell',
|
||
mixins: [JVxeCellMixins],
|
||
data() {
|
||
return {
|
||
...common.data.apply(this),
|
||
|
||
hasRequest: false,
|
||
scopedSlots: {
|
||
notFoundContent: () => {
|
||
if (this.loading) {
|
||
return <a-spin size="small"/>
|
||
} else if (this.hasRequest) {
|
||
return <div>没有查询到任何数据</div>
|
||
} else {
|
||
return <div>{this.tipsContent}</div>
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
computed: {
|
||
...common.computed,
|
||
tipsContent() {
|
||
return this.originColumn.tipsContent || '请输入搜索内容'
|
||
},
|
||
filterOption() {
|
||
if (this.isAsync) {
|
||
return null
|
||
}
|
||
return (input, option) => option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||
},
|
||
},
|
||
watch: {
|
||
...common.watch,
|
||
},
|
||
created() {
|
||
this.loadData = debounce(this.loadData, 300)//消抖
|
||
},
|
||
methods: {
|
||
...common.methods,
|
||
|
||
loadData(value) {
|
||
const currentRequestId = ++requestId
|
||
this.loading = true
|
||
this.innerOptions = []
|
||
if (value == null || value.trim() === '') {
|
||
this.loading = false
|
||
this.hasRequest = false
|
||
return
|
||
}
|
||
// 字典code格式:table,text,code
|
||
this.hasRequest = true
|
||
getAction(`/sys/dict/loadDict/${this.dict}`, {keyword: value}).then(res => {
|
||
if (currentRequestId !== requestId) {
|
||
return
|
||
}
|
||
let {success, result, message} = res
|
||
if (success) {
|
||
this.innerOptions = result
|
||
result.forEach((item) => {
|
||
common.labelMap.set(item.value, [item])
|
||
})
|
||
} else {
|
||
this.$message.warning(message)
|
||
}
|
||
}).finally(() => {
|
||
this.loading = false
|
||
})
|
||
},
|
||
|
||
handleChange(selectedValue) {
|
||
this.innerSelectValue = selectedValue
|
||
this.handleChangeCommon(this.innerSelectValue)
|
||
},
|
||
handleSearch(value) {
|
||
if (this.isAsync) {
|
||
// 在输入时也应该开启加载,因为loadData加了消抖,所以会有800ms的用户主观上认为的卡顿时间
|
||
this.loading = true
|
||
if (this.innerOptions.length > 0) {
|
||
this.innerOptions = []
|
||
}
|
||
this.loadData(value)
|
||
}
|
||
},
|
||
|
||
renderOptionItem() {
|
||
let options = []
|
||
this.options.forEach(({value, text, label, title, disabled}) => {
|
||
options.push(
|
||
<a-select-option key={value} value={value} disabled={disabled}>{text || label || title}</a-select-option>
|
||
)
|
||
})
|
||
return options
|
||
},
|
||
},
|
||
render() {
|
||
return (
|
||
<a-select
|
||
showSearch
|
||
allowClear
|
||
value={this.innerSelectValue}
|
||
filterOption={this.filterOption}
|
||
style="width: 100%"
|
||
{...this.cellProps}
|
||
onSearch={this.handleSearch}
|
||
onChange={this.handleChange}
|
||
scopedSlots={this.scopedSlots}
|
||
>
|
||
{this.renderOptionItem()}
|
||
</a-select>
|
||
)
|
||
},
|
||
// 【组件增强】注释详见:JVxeCellMixins.js
|
||
enhanced: {
|
||
aopEvents: {
|
||
editActived(event) {
|
||
dispatchEvent.call(this, event, 'ant-select')
|
||
},
|
||
},
|
||
}
|
||
} |