代码拉取完成,页面将自动刷新
<template>
<span style="width:100%;">
<span v-if="showStyle=='origin'||showStyle==''||!showStyle" :title="title||placeholder">
<el-select v-if="showType=='select'" :style="{width:width?width:'auto'}" :multiple-limit="limit" :no-data-text="noDataText" :no-match-text="noMatchText" :popper-class="popperClass" :reserve-keyword="reserveKeyword" :size="size" :multiple="multiple" :placeholder="placeholder" :disabled="disabled" class="my-select" ref="selectRef" v-model="myVal" @change="onChange" :clearable="clearable" @visible-change="$emit('visible-change',$event)" @focus="$emit('focus',$event)" @blur="$emit('blur',$event)" @clear="$emit('clear',$event)" @click="$emit('click',$event)" @remove-tag="$emit('remove-tag',$event)" :collapse-tags="collapseTags">
<el-option disabled value="" style="height:40px;">
<slot name="toolbar">
<div><el-button @click.stop="$refs['tableDialog'].open({itemCode:itemCode})" icon="search" type="primary" plain title="查询更多数据" />
<el-button type="warning" icon="refresh" @click="doRefresh()" plain title="从后台重新加载,刷新数据"/>
<slot name="toolbarExt">
</slot>
</div>
</slot>
</el-option>
<slot name="options" :options="optionsCpd" :item="item">
<el-option :style="styleObj" v-for="(option,index) in optionsCpd" :key="index" :value="option[propsCpd['id']]" :label="option[propsCpd['name']]">
<div class="avatar-container" v-if="propsCpd.imgUrl">
<div class="avatar-wrapper">
<el-avatar class="user-avatar" :src="option[propsCpd.imgUrl]" :style="{backgroundColor:getMyColor(option)}">{{option[propsCpd['name']]?.substr(0,2)}}</el-avatar>
<span class="username">{{option[propsCpd['name']]}}</span>
<Icon v-if="multiple==false && myVal && myVal==option[propsCpd['id']]" icon="ep:check"/>
<i v-else> </i>
</div>
</div>
<div v-else>
<span :style="{backgroundColor:getMyColor(option),color:'white'}" class="padding">
<Icon v-if="option.icon" :icon="option.icon"/>
{{option[propsCpd['name']]}}
</span>
<Icon v-if="isCheck(option)" icon="ep:check" color="blue"/>
<i v-else> </i>
</div>
</el-option>
</slot>
</el-select>
</span>
<span v-else-if="showStyle=='tag' && disabled==true">
<span v-if="multiple===true" >
<span v-if="sels && sels.length>0">
<el-tag :style="{maxWidth:maxWidth?maxWidth+'px':'100%'}" class="truncate" :size="size" v-for="option,idx in sels" :key="idx" :color="getMyColor(option)" :closable="closable" :effect="effect" >{{ option[propsCpd['name']] }}</el-tag>
</span>
<span v-else-if="myVal && myVal.length>0">
<el-tag :style="{maxWidth:maxWidth?maxWidth+'px':'100%'}" class="truncate" :size="size" v-for="id,idx in myVal" :key="idx" :color="getMyColorById(id)" :closable="closable" :effect="effect">{{ id }}</el-tag>
</span>
<el-tag v-else>{{ noMatchText ||'无' }}</el-tag>
</span>
<span v-else>
<el-tag :style="{maxWidth:maxWidth?maxWidth+'px':'100%'}" :class="{'dashed-border':disabled==false,truncate:true}" :size="size" v-if="sels" :color="getMyColor(sels)" :closable="closable" :effect="effect" >{{sels[propsCpd['name']]||noMatchText}}</el-tag>
<el-tag :style="{maxWidth:maxWidth?maxWidth+'px':'100%'}" class="truncate" :size="size" v-else-if="myVal" :color="getMyColorById(myVal)" :effect="effect">{{ myVal }}</el-tag>
<el-tag v-else>{{ noMatchText ||'无'}}</el-tag>
</span>
</span>
<span v-else :title="title||placeholder">
<div :class="showStyle=='x'?{'field-box-x':true}:{'field-box':true}" @click="showSelect">
<span class="field-info" :class="{disabled:disabled===true,enabled:disabled!==true,hidden:selectOpen==true}">
<slot name="avater" class="field-avater" v-if="showStyle=='x'">
<el-avatar :size="size" :src="avaterCpd[propsCpd.imgUrl]"
:icon="avaterCpd.icon"
:style="{ backgroundColor: getMyColor( avaterCpd ) }"
>{{ avaterCpd.icon?"":formatImgFront(avaterCpd[propsCpd['name']]) }}</el-avatar>
</slot>
<slot name="info">
<span v-if="showStyle=='x'" class="info-box">
<div v-if="multiple==true" class="field-value">
<div v-if="sels&&sels.length>0" :style="{width:width?width:'100px'}">
<el-text truncated>{{ sels.map(k=>k[propsCpd['name']]).join(split) }}</el-text>
</div>
<div class="field-value" v-else-if="myVal && myVal.length>0">
{{ myVal.join(split) }}
</div>
<div>{{ noMatchText || '无'}}</div>
</div>
<div v-else class="field-value">
<div v-if="sels" :style="{width:width?width:'100px'}">
<el-text truncated>{{ sels[propsCpd['name']] }}</el-text>
</div>
<div v-else-if="myVal">
{{ myVal }}
</div>
<div v-else>{{ noMatchText || '无'}}</div>
</div>
<div class="field-label">{{ label||title||placeholder ||'无' }}</div>
</span>
<span v-else>
<div v-if="multiple===true">
<div v-if="sels && sels.length>0" >
<el-tag :style="{maxWidth:maxWidth?maxWidth+'px':'100%'}" class="truncate" :size="size" v-for="option,idx in sels" :key="idx" :color="getMyColor(option)" :closable="closable" :effect="effect">{{ option[propsCpd['name']] }}</el-tag>
</div>
<div v-else-if="myVal && myVal.length>0" >
<el-tag :style="{maxWidth:maxWidth?maxWidth+'px':'100%'}" class="truncate" :size="size" v-for="id,idx in myVal" :key="idx" :color="getMyColorById(id)" :closable="closable" :effect="effect">{{ id }}</el-tag>
</div>
<el-tag v-else>{{ noMatchText ||'无' }}</el-tag>
</div>
<div v-else>
<el-tag :style="{maxWidth:maxWidth?maxWidth+'px':'100%'}" :class="{'dashed-border':disabled==false,truncate:true}" :size="size" v-if="sels" :color="getMyColor(sels)" :closable="closable" :effect="effect" > {{sels[propsCpd['name']]||noMatchText}}</el-tag>
<el-tag :style="{maxWidth:maxWidth?maxWidth+'px':'100%'}" class="truncate" :size="size" v-else-if="myVal" :color="getMyColorById(myVal)" :effect="effect">{{ myVal }}</el-tag>
<el-tag v-else>{{ noMatchText ||'无'}}</el-tag>
</div>
</span>
</slot>
</span>
<span :class="{'field-oper-box':true,relative:relative}">
<span class="field-oper" :class="{disabled:disabled===true,enabled:disabled!==true,nohidden:selectOpen===true}">
<slot name="oper">
<el-select :disabled="disabled" :style="{width:width?width:'auto'}" :multiple="multiple" :multiple-limit="limit" :auto-complete="autoComplete" :filter-method="filterMethod" :collapse-tags="collapseTags" :filterable="filterable" :name="name" :no-data-text="noDataText" :no-match-text="noMatchText" :popper-class="popperClass" :reserve-keyword="reserveKeyword" :size="size" v-if="showType=='select'" class="my-select" ref="selectRef" v-model="myVal" @change="onChange" :clearable="clearable" @visible-change="visibleChange" @focus="$emit('focus',$event)" @blur="$emit('blur',$event)" @clear="$emit('blur',$event)" @click="$emit('click',$event)" @remove-tag="$emit('remove-tag',$event)">
<el-option disabled value="" style="height:40px;" >
<slot name="toolbar">
<div><el-button @click.stop="$refs['tableDialog'].open({itemCode:itemCode})" icon="search" title="查询更多数据" type="primary" plain/>
<el-button icon="refresh" type="warning" title="刷新数据" @click="doRefresh()" plain/>
<slot name="toolbarExt">
</slot>
</div>
</slot>
</el-option>
<slot name="options" :options="optionsCpd" :item="item">
<el-option :style="styleObj" :key="index" v-for="(option,index) in optionsCpd" :value="option[propsCpd['id']]" :label="option[propsCpd['name']]">
<div v-if="propsCpd.imgUrl" class="avatar-container">
<div class="avatar-wrapper">
<el-avatar class="user-avatar" :src="option[propsCpd.imgUrl]" :style="{backgroundColor:getMyColor(option)}">{{option[propsCpd['name']]}}</el-avatar>
<span class="username">{{option[propsCpd['name']]}}</span>
<Icon v-if="multiple==false && myVal && myVal==option[propsCpd['id']]" icon="ep:check"/>
<i v-else> </i>
</div>
</div>
<div v-else>
<span :style="{backgroundColor:getMyColor(option),color:'white'}" class="padding el-tag--dark">
<Icon v-if="option.icon" :icon="option.icon"/>
{{option[propsCpd['name']]}}
</span>
<Icon v-if="isCheck(option)" icon="ep:check"/>
<i v-else> </i>
</div>
</el-option>
</slot>
</el-select>
</slot>
</span>
</span>
</div>
</span>
<mdp-dialog ref="tableDialog" title="选择数据" width="80%">
<template #default="{visible}">
<mdp-table :multiple="multiple" sub-op-type="select" @loadDatas="onTableLoadDatas" :params="params" :visible="visible" :crud-apis="{list:loadFun}" :props="props" :column-cfgs="columnConfigs" @select="onTableDataSelect"/>
</template>
</mdp-dialog>
</span>
</template>
<script>
import {MdpSelectMixin } from "../../mdp-ui/mixin/MdpSelectMixin.js"
const tableDataCacheMap=new Map();
export default {
components: { },
name: 'mdp-select-table',
mixins:[MdpSelectMixin],
computed:{
columnConfigs(){
if(this.columnCfgs && this.columnCfgs.length>0){
return this.columnCfgs
}else{
var idColumn={property:this.propsCpd['id'],label:'编号'}
var nameColumn={property:this.propsCpd['name'],label:'名称'}
var columnConfigs=[]
if(this.propsCpd.imgUrl){
columnConfigs.push({property:this.propsCpd['imgUrl'],label:'图像'})
}
columnConfigs.push(idColumn)
columnConfigs.push(nameColumn)
return columnConfigs;
}
},
/**
* 如果定义了props属性,默认按客户定义的来,如果未定义,则进行以下推测
* 如果定义了columnCfgs,将取第一列作为id,取第二列作为name,不需要配置
* 如果都未定义,返回 {id:'id',name:'name'}
*/
propsCpd(){
if(this.props==null){
if(this.columnCfgs && this.columnCfgs.length>0){
return {id:this.columnCfgs[0].property,name:this.columnCfgs[1].property}
}else{
return {id:'id',name:'name'}
}
}else{
return this.props
}
},
},
watch:{
},
props:{
columnCfgs:{
type:Array,
default:null,
},
},
data(){
return {
selectOpen:false
}
},
methods:{
visibleChange($event){
this.$emit('visibleChange',$event)
},
doRefresh(){
this.initItemOptions(true)
},
getCacheList(){
var tableDataCacheList=tableDataCacheMap.get(this.codeKey)
return tableDataCacheList
},
/**
* 返回新添加的数据[...]
*/
setCacheList(datas){
var tableDataCacheList=tableDataCacheMap.get(this.codeKey)
if(!tableDataCacheList){
tableDataCacheList=[]
}
if(datas==null || datas.length==0){
tableDataCacheMap.set(this.codeKey,tableDataCacheList)
return [];
}
var dataArr=[]
if(Array.isArray(datas)){
dataArr=datas
}else{
dataArr=[datas]
}
var idKey=this.propsCpd['id']
var notExists=dataArr.filter(d=>!tableDataCacheList.some(c=>c[idKey]==d[idKey]))
if(notExists.length>0){
tableDataCacheList.push(...notExists)
}
tableDataCacheMap.set(this.codeKey,tableDataCacheList)
return notExists
},
initItemOptions(refresh){
var tableDataCacheList=this.getCacheList();
if(tableDataCacheList && tableDataCacheList.length>0){
this.item={itemType:'4',options:tableDataCacheList}
}else{
this.item={itemType:'4',options:[]}
}
if(!refresh && !this.initLoad){
return;
}
if(this.modelValue && this.modelValue.length>0){
var mVals=[]
if(Array.isArray(this.modelValue)){
mVals=this.modelValue
}else{
mVals=this.modelValue.split(this.split)
}
var notExistsVals=mVals.filter(v=>!this.item.options.some(k=>k[this.propsCpd['id']]==v))
if(notExistsVals && notExistsVals.length>0){
if(!this.loadFun){
return;
}
this.loadRemoteDatasByFun(false,notExistsVals).then(res=>{
res.data.forEach(k=>{
if(!this.item.options.some(m=>m[this.propsCpd.id]==k[this.propsCpd.id])){
this.item.options.unshift(k)
}
})
})
}
}else{//如果 没有条件,默认不执行
if(!this.loadFun){
return;
}
if(!this.initLoad){
return
}
this.loadRemoteDatasByFun(false).then(res=>{
this.item.options=this.getCacheList()
})
}
},
onTableDataSelect(tableDatas){
if(!tableDatas||tableDatas.length==0){
return;
}
if(this.multiple){
if(this.limit>0){
if(Array.isArray(tableDatas)){
if(tableDatas.length>this.limit){
this.$message("最多只能选择"+this.limit+"个")
return;
}
}
}
}
this.setCacheList(tableDatas)
if(this.multiple){
tableDatas.forEach(k=>{
if(!this.optionsCpd.some(m=>m[this.propsCpd.id]==k[this.propsCpd.id])){
this.item.options.unshift(k)
}
})
this.myVal=tableDatas.map(k=>k[this.propsCpd['id']])
}else{
if(!this.optionsCpd.some(m=>m[this.propsCpd.id]==tableDatas[this.propsCpd.id])){
this.item.options.unshift(tableDatas)
}
this.myVal=tableDatas[this.propsCpd['id']]
}
this.onClose();
this.$refs['tableDialog'].close();
},
onClose(){
},
getFromCache(initIds){
var datas=this.getCacheList()
if(datas==null || datas.length==0){
return datas
}
if(!initIds || initIds.length==0){
return datas
}
var idKey=this.propsCpd['id']
if(initIds && initIds.length>0){
if(initIds.some(k=> !datas.some(d=>d[idKey]==k))){
return null
}else{
return datas
}
}
},
/**
* 做请求排序锁定处理,防止在列表中多次查询下拉列表数据
**/
loadRemoteDatasByFun(refresh)
{
var codeKey=this.codeKey;
return new Promise((resolve,reject)=>{
var intervalCount=0
var interalFunc=null
var lockKey=codeKey+'@lock'
var lock=sessionStorage.getItem(lockKey)
var getFromCache=this.getFromCache
var idKey=this.propsCpd['id']
var loadFun=this.loadFun
var setCacheList=this.setCacheList
var params=Object.assign({pageSize:10,pageNum:1},this.params)
let func = function(){
intervalCount=intervalCount+1;
lock=sessionStorage.getItem(lockKey)
var data=refresh?null:getFromCache()
if(data!=null && data!='undefined' && data!=undefined){
var res2={
tips:{
isOk:true,
tipscode:'ok',
msg:'成功'
},
data:data
}
resolve(res2)
sessionStorage.removeItem(lockKey)
clearInterval(interalFunc)
return;
}
if(intervalCount>5){
sessionStorage.removeItem(lockKey)
clearInterval(interalFunc)
reject("等待超时")
return;
}
if(lock){
return;
}
if(!loadFun){
return;
}
sessionStorage.setItem(lockKey,"1")
loadFun(params).then(res=>{
clearInterval(interalFunc)
if(res.tips && res.tips.isOk){
if(!res.data || res.data.length==0){
setCacheList([])
sessionStorage.removeItem(lockKey)
resolve({tips:res.tips,data:[]})
return;
}
sessionStorage.removeItem(lockKey)
var res2={
tips:res.tips,
data:res.data
}
setCacheList(res2.data)
resolve(res2)
}else{
sessionStorage.removeItem(lockKey)
reject(res)
}
}).catch(e=>{
clearInterval(interalFunc)
sessionStorage.removeItem(lockKey)
reject(e)
})
}
if(lock){
interalFunc = setInterval(()=>{
func();
},2000)
}else{
func();
}
})
},
onTableLoadDatas(res){
let {tips,data} = res
if(tips.isOk && data && data.length>0){
let idKey=this.propsCpd['id']
let dataNotExists=data.filter(k=>!this.item.options.some(o=>o[idKey]==k[idKey]))
if(dataNotExists.length>0){
this.setCacheList(dataNotExists)
this.item.options.unshift(...dataNotExists)
}
}
}
},
mounted(){
this.initMyValByValue();
this.initData();
this.initItemOptions();
},
}
</script>
<style lang="scss" scoped>
@import url('../index.scss');
.truncate {
white-space: nowrap; /* 不换行 */
overflow: hidden; /* 隐藏溢出的文本 */
text-overflow: ellipsis; /* 使用省略号表示文本被截断 */
}
</style>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。