You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
637 lines
20 KiB
637 lines
20 KiB
import util from "../js/util"
|
|
export const MdpSelectMixin = {
|
|
|
|
computed: {
|
|
avaterCpd(){
|
|
var isEmpty= !this.myVal || this.myVal.length==0
|
|
var obj={isNull:isEmpty,icon:this.icon,color:this.color,id:'',name:''}
|
|
if(isEmpty){
|
|
obj.icon='el-icon-full-screen'
|
|
obj.color='#E4E7ED'
|
|
return obj;
|
|
}else{
|
|
if(this.multiple==true){
|
|
if(this.sels && this.sels.length>0){
|
|
return this.sels[0]
|
|
}else{
|
|
var val=this.myVal[0]
|
|
if(!obj.color){
|
|
obj.color=this.colorFun?this.colorFun(val):util.getColorById(val)
|
|
}
|
|
if(!obj.icon){
|
|
obj.icon=this.iconFun?this.iconFun(val):util.getIconById(val)
|
|
}
|
|
obj.name=val
|
|
obj.id=val
|
|
}
|
|
}else{
|
|
if(this.sels){
|
|
return this.sels
|
|
}else{
|
|
var val=this.myVal
|
|
if(!obj.color){
|
|
obj.color=this.colorFun?this.colorFun(val):util.getColorById(val)
|
|
}
|
|
if(!obj.icon){
|
|
obj.icon=this.iconFun?this.iconFun(val):util.getIconById(val)
|
|
}
|
|
obj.name=val
|
|
obj.id=val
|
|
}
|
|
}
|
|
}
|
|
return obj;
|
|
},
|
|
optionsCpd(){
|
|
var options=[]
|
|
var map=new Map();
|
|
var idKey=this.props?this.props['id']:'id'
|
|
var nameKey=this.props?this.props['name']:'name'
|
|
if(this.initOptions){
|
|
this.initOptions.forEach(k=>map.set(k[idKey],k))
|
|
}
|
|
if(this.options){
|
|
this.options.forEach(k=>map.set(k[idKey],k))
|
|
}
|
|
if(this.plusOptions){
|
|
this.plusOptions.forEach(k=>map.set(k[idKey],k))
|
|
}
|
|
|
|
if(this.item && this.item.options){
|
|
this.item.options.forEach(k=>map.set(k[idKey],k))
|
|
}
|
|
var options2=[]
|
|
var needFilter=!!this.filterFun
|
|
var needTran=this.props!=null && (idKey!='id' || nameKey!='name')
|
|
var all=map.values();
|
|
for(let value of all) {
|
|
if(needFilter){
|
|
if(!this.filterFun(value,options)){
|
|
continue;
|
|
}
|
|
}
|
|
var idValue=value[idKey]
|
|
if(needTran){
|
|
if((idKey in value)){
|
|
value['id']=idValue
|
|
}
|
|
if((nameKey in value)){
|
|
value['name']=value[nameKey]
|
|
}
|
|
}
|
|
|
|
|
|
if(this.colorFun){
|
|
value.color=this.colorFun(idValue,value,options)
|
|
}else{
|
|
value.color=this.getColorById(idValue,value,options)
|
|
}
|
|
if(this.iconFun){
|
|
value.icon=this.iconFun(idValue,value,options)
|
|
}else{
|
|
value.icon=this.getIconById(idValue,value,options)
|
|
}
|
|
options2.push(value)
|
|
}
|
|
return options2
|
|
|
|
},
|
|
sels(){
|
|
if(this.multiple==true){
|
|
if(this.myVal==null || this.myVal==''|| this.myVal.length==0 ){
|
|
return this.optionsCpd.filter(k=>this.myVal==k[this.props['id']])
|
|
}
|
|
if(this.myVal instanceof Array ){
|
|
return this.optionsCpd.filter(k=>this.myVal.some(v=>v==k[this.props['id']]))
|
|
}else{
|
|
return this.optionsCpd.filter(k=>this.myVal==k[this.props['id']])
|
|
}
|
|
|
|
}else{
|
|
if(this.myVal==null || this.myVal=='' || this.myVal.length==0 ){
|
|
return null
|
|
}else {
|
|
return this.optionsCpd.find(k=>k[this.props['id']]==this.myVal)
|
|
}
|
|
}
|
|
},
|
|
codeKey(){
|
|
if(this.itemCode){
|
|
return util.getCodeKey(this.itemCode,this.params)
|
|
}else{
|
|
|
|
if(this.loadFun){
|
|
return util.getCodeKey(this.loadFun.name,this.params)
|
|
}else{
|
|
return "xxxx"
|
|
}
|
|
|
|
}
|
|
},
|
|
},
|
|
data(){
|
|
return {
|
|
defaultColors:util.getDefaultColors(),
|
|
myVal:[],
|
|
item:{
|
|
itemType:'4',
|
|
options:[]
|
|
},
|
|
initOptions:[],
|
|
}
|
|
},
|
|
watch:{
|
|
codeKey(){
|
|
this.initItemOptions();
|
|
},
|
|
value(val){
|
|
this.initMyValByValue(val)
|
|
}
|
|
},
|
|
props: {
|
|
title:{
|
|
type: String,
|
|
default:'',
|
|
},
|
|
itemCode:String,
|
|
disabled:{
|
|
type:Boolean,
|
|
default:false,
|
|
},
|
|
closable:{
|
|
type:Boolean,
|
|
default:false,
|
|
},
|
|
effect:{
|
|
type:String,
|
|
default:'dark'//dark / light / plain
|
|
},
|
|
autoSelect:{
|
|
type:Boolean,
|
|
default:false,
|
|
},
|
|
/**
|
|
* 如果是itemCode,将提交后台过滤部分列表数据
|
|
* 如果是loadFun,将提交后台参与过滤
|
|
*/
|
|
params:{
|
|
type:Object,
|
|
default:null,
|
|
},
|
|
value: {
|
|
type:[String,Number,Array],
|
|
default:'',
|
|
},
|
|
clearable:{
|
|
type:Boolean,
|
|
default:true,
|
|
},
|
|
styleObj:{
|
|
type:Object,
|
|
default:function(){return { marginTop:'5px' }}
|
|
},
|
|
|
|
label: {
|
|
type: String,
|
|
default: "",
|
|
},
|
|
emptyText:{
|
|
type:String,
|
|
default:'请选择'
|
|
},
|
|
options:{
|
|
type:Array,
|
|
default:null
|
|
},
|
|
/**
|
|
* 在加载完options后追加进入列表的plusOptions.
|
|
* 整个列表长度为 options+plusOptions 或者 后台返回的 options+plusOptions
|
|
*/
|
|
plusOptions:{
|
|
type:Array,
|
|
default:null,
|
|
},
|
|
width:{
|
|
type:[String,Number],
|
|
default:null
|
|
},
|
|
/**
|
|
* 支持select radio checkbox 三种
|
|
*/
|
|
showType:{
|
|
type:String,
|
|
default:'select'
|
|
},
|
|
/**
|
|
* 控制组件的布局
|
|
* origin 原始方式,保持element-ui原组件样式
|
|
* tag 未编辑前以tag显示,鼠标放入后显示原生组件模样
|
|
* x 综合布局,适合于表单追求美观的样式,将颜色+图标+布局进行柔和组成新的组件
|
|
*/
|
|
showStyle:{
|
|
type:String,
|
|
default:'origin'
|
|
},
|
|
/**
|
|
* 是否多选
|
|
*/
|
|
multiple:{
|
|
type:Boolean,
|
|
default:false,
|
|
},
|
|
/**
|
|
* 分隔符,如果多选,并且指定了分隔符,将接受分格符连接的字符串及返回分给符连接的字符串
|
|
*/
|
|
split:{
|
|
type:String,
|
|
default:null
|
|
},
|
|
/**
|
|
* 对列表进行转换,{
|
|
id:'key',
|
|
name:'label'
|
|
},
|
|
将把option.key=>option.id,把option.label=>option.name
|
|
*/
|
|
props:{
|
|
type: Object,
|
|
default: function(){
|
|
return {id:'id',name:'name'}
|
|
},
|
|
},
|
|
/**
|
|
* 从接口拉取数据的函数,加载顺序 options,itemCode,loadOption,
|
|
* 其中 params为 params属性
|
|
* loadFun(params).then(res=>options=res.data.data)
|
|
*/
|
|
loadFun:{
|
|
type:Function,
|
|
default:null,
|
|
},
|
|
/**
|
|
* 对选项值进行过滤,
|
|
* 返回false将被过滤,返回true将在列表显示
|
|
* true/false=filterFun(option,idx,options)
|
|
*/
|
|
filterFun:{
|
|
type:Function,
|
|
default:null
|
|
},
|
|
/**
|
|
* 指定每个选项的颜色,option.color属性
|
|
* option.color=colorFun(option,idx,options)
|
|
*/
|
|
colorFun:{
|
|
type:Function,
|
|
default:null
|
|
},
|
|
icon:{
|
|
type:String,
|
|
default:null,
|
|
},
|
|
iconFun:{
|
|
type: Function,
|
|
default: null,
|
|
},
|
|
/**
|
|
* placeholder
|
|
*/
|
|
placeholder:{
|
|
type: String,
|
|
default:'请选择',
|
|
},
|
|
/**输入框尺寸
|
|
* medium/small/mini
|
|
*/
|
|
size:{
|
|
type: String,
|
|
default:'small'
|
|
},
|
|
/**
|
|
* 多选时是否将选中值按文字的形式展示
|
|
*/
|
|
collapseTags:{
|
|
type:Boolean,
|
|
default:true,
|
|
},
|
|
/**
|
|
* 多选时用户最多可以选择的项目数,为 0 则不限制
|
|
*/
|
|
multipleLimit:{
|
|
type:Number,
|
|
default:0,
|
|
},
|
|
/**
|
|
* select input 的 name 属性
|
|
*/
|
|
name:{
|
|
type:String,
|
|
default:'',
|
|
},
|
|
/**
|
|
* select input 的 autocomplete 属性
|
|
*/
|
|
autoComplete:{
|
|
type:String,
|
|
default:'off',
|
|
},
|
|
/**
|
|
* 是否可搜索
|
|
*/
|
|
filterable:{
|
|
type:Boolean,
|
|
default:false,
|
|
},
|
|
/**
|
|
* 搜素的时候,的过滤函数
|
|
*/
|
|
filterMethod:{
|
|
type:Function,
|
|
default:null,
|
|
},
|
|
/**
|
|
* 搜索条件无匹配时显示的文字,也可以使用slot="empty"设置
|
|
*/
|
|
noMatchText:{
|
|
type:String,
|
|
default:'',
|
|
},
|
|
/**
|
|
* 选项为空时显示的文字,也可以使用slot="empty"设置
|
|
*/
|
|
noDataText:{
|
|
type:String,
|
|
default:'',
|
|
},
|
|
/**
|
|
* Select 下拉框的类名
|
|
*/
|
|
popperClass:{
|
|
type:String,
|
|
default:'-',
|
|
},
|
|
/**
|
|
* 多选且可搜索时,是否在选中一个选项后保留当前的搜索关键词
|
|
*/
|
|
reserveKeyword:{
|
|
type:Boolean,
|
|
default:false,
|
|
},
|
|
/**
|
|
* 当有时候,传入的值不一定在列表中存在,事先已值值对应的名称,则可以通过initName设置,此时就算下拉列表没有对应的选项,也会反显,而不是显示早的值
|
|
*/
|
|
initName:{
|
|
type:String,
|
|
default:null
|
|
}
|
|
},
|
|
methods: {
|
|
showSelect(){
|
|
if(this.disabled){
|
|
return;
|
|
}
|
|
if(this.$refs["operRef"]){
|
|
if(this.$refs["operRef"].onFieldClick){
|
|
this.$refs["operRef"].onFieldClick();
|
|
}
|
|
}
|
|
},
|
|
isCheck(option){
|
|
if(!option && this.myVal){
|
|
return false
|
|
}else if(option && !option.id && !this.myVal){
|
|
return false;
|
|
}
|
|
if(this.multiple){
|
|
if(this.myVal instanceof Array){
|
|
return this.myVal.some(k=>k==option.id)
|
|
}else {
|
|
return this.myVal==option.id
|
|
}
|
|
}else{
|
|
return this.myVal==option.id
|
|
}
|
|
},
|
|
filterOptions(itemOptions){
|
|
if(this.filterFun && itemOptions!=null && itemOptions.length>0){
|
|
itemOptions=itemOptions.filter(k=>this.filterFun(k,itemOptions))
|
|
}
|
|
return itemOptions;
|
|
},
|
|
transOptions(itemOptions){
|
|
if(this.props!=null && this.props['id']=='id' && this.props['name']=='name'){
|
|
return itemOptions;
|
|
}
|
|
if(itemOptions!=null && itemOptions.length>0){
|
|
itemOptions.forEach(k=>{
|
|
if((this.props['id'] in k)){
|
|
k['id']=k[this.props['id']]
|
|
}
|
|
if((this.props['name'] in k)){
|
|
k['name']=k[this.props['name']]
|
|
}
|
|
|
|
})
|
|
}
|
|
return itemOptions;
|
|
},
|
|
colorAndIconOptions(itemOptions){
|
|
if(!itemOptions){
|
|
return itemOptions
|
|
}
|
|
itemOptions.forEach((k,idx,all)=>{
|
|
if(this.colorFun){
|
|
k.color=this.colorFun(k[this.props['id']],k,all)
|
|
}else{
|
|
k.color=this.getColorById(k[this.props['id']],k,all)
|
|
}
|
|
if(this.iconFun){
|
|
k.icon=this.iconFun(k[this.props['id']],k,all)
|
|
}else{
|
|
k.icon=this.getIconById(k[this.props['id']],k,all)
|
|
}
|
|
})
|
|
return itemOptions;
|
|
},
|
|
iconOptions(itemOptions){
|
|
if(this.iconFun){
|
|
itemOptions.forEach((k,idx,all)=>{
|
|
k.color=this.iconFun(k[this.props['id']],k,all)
|
|
})
|
|
}else{
|
|
itemOptions.forEach((k,idx,all)=>{
|
|
if(!k.icon){
|
|
k.icon=this.getIconById(k[this.props['id']],k,all)
|
|
}
|
|
})
|
|
}
|
|
return itemOptions;
|
|
},
|
|
getColorById(id,option,itemOptions){
|
|
return util.getColorById(id);
|
|
},
|
|
getIconById(id,option,itemOptions){
|
|
if(id){
|
|
return ''
|
|
}else{
|
|
return "el-icon-full-screen"
|
|
}
|
|
|
|
},
|
|
afterLoad(itemOptions){
|
|
|
|
return itemOptions;
|
|
},
|
|
clearCache(){
|
|
this.$mdp.clearDictCache(this.itemCode,this.params)
|
|
this.item.options=[]
|
|
},
|
|
initItemOptions(){
|
|
if(this.itemCode){
|
|
this.$mdp.ajaxGetDictOptions (this.itemCode,this.params).then(res=>{
|
|
if(res.tips.isOk){
|
|
var item=res.data
|
|
var itemOptions=item.options?item.options:[]
|
|
item.options=this.afterLoad(itemOptions)
|
|
this.item=item
|
|
}else{
|
|
this.item={itemType:'4'}
|
|
this.item.options=[]
|
|
}
|
|
|
|
})
|
|
}else if(this.loadFun){
|
|
this.loadFun(this.params).then(res=>{
|
|
this.item={itemType:'4'}
|
|
var itemOptions=res.data.data
|
|
this.item.options=this.afterLoad(itemOptions)
|
|
})
|
|
}
|
|
|
|
},
|
|
onChange(val){
|
|
if(val==this.value){
|
|
return;
|
|
}
|
|
if(!val){
|
|
this.$emit("input",val)
|
|
this.$emit("change",val)
|
|
this.$emit("change2",null)
|
|
return;
|
|
}
|
|
if(this.multiple==true ){
|
|
if(this.split){
|
|
var valJoin=val.join(this.split)
|
|
if(valJoin!=this.value){
|
|
|
|
this.$emit("input",valJoin)
|
|
this.$emit('change',valJoin)
|
|
}
|
|
}else{
|
|
this.$emit("input",val)
|
|
this.$emit('change',val)
|
|
}
|
|
|
|
}else{
|
|
this.$emit("input",val)
|
|
this.$emit('change',val)
|
|
}
|
|
this.onChange2(val)
|
|
},
|
|
onChange2(data){
|
|
var options=null
|
|
|
|
if(this.multiple==true ){
|
|
options=this.optionsCpd.filter(k=>data.some(d=>d==k[this.props['id']]))
|
|
}else{
|
|
options=this.optionsCpd.find(k=>data==k[this.props['id']])
|
|
}
|
|
this.$emit("change2",options)
|
|
},
|
|
initData(){
|
|
this.initMyValByValue(this.value,true)
|
|
},
|
|
/**
|
|
* 只能初始化时执行一次,否则性能有问题
|
|
* @returns
|
|
*/
|
|
initOptionsByInitName(myVal,myName){
|
|
|
|
this.initOptions=myVal.map((v,idx)=>{
|
|
var option={}
|
|
option[this.props['id']]=v
|
|
option[this.props['name']]=myName[idx]
|
|
return option
|
|
})
|
|
},
|
|
initMyValByValue(val,isFirst){
|
|
if( this.myVal==val){
|
|
return;
|
|
}
|
|
if(!val){
|
|
this.myVal=null
|
|
return;
|
|
}
|
|
|
|
var initName=this.initName
|
|
if(this.multiple==true){
|
|
if(!val){
|
|
this.myVal=null
|
|
return;
|
|
}
|
|
if(this.split){
|
|
if(typeof val == "string"){
|
|
this.myVal=val.split(this.split)
|
|
if(initName){
|
|
this.initOptionsByInitName(this.myVal,initName.split(this.split))
|
|
}
|
|
|
|
}else if(val instanceof Array){
|
|
this.myVal=val
|
|
if(initName){
|
|
this.initOptionsByInitName(this.myVal,initName)
|
|
}
|
|
}else {
|
|
this.myVal=[val]
|
|
if(initName){
|
|
this.initOptionsByInitName(this.myVal,[initName])
|
|
}
|
|
}
|
|
}else{
|
|
if(val instanceof Array){
|
|
this.myVal=val
|
|
if(initName){
|
|
this.initOptionsByInitName(this.myVal,initName)
|
|
}
|
|
}else {
|
|
this.myVal=[val+'']
|
|
if(initName){
|
|
this.initOptionsByInitName(this.myVal,[initName])
|
|
}
|
|
}
|
|
}
|
|
}else{
|
|
this.myVal=val+''
|
|
if(initName){
|
|
this.initOptionsByInitName([this.myVal],[initName])
|
|
}
|
|
}
|
|
|
|
},
|
|
getMyColor(option){
|
|
return option.color?option.color:(this.colorFun?this.colorFun(option[this.props['id']]):this.getColorById(option[this.props['id']]))
|
|
},
|
|
getMyIcon(option){
|
|
return option.icon?option.icon:(this.iconFun?this.iconFun(option[this.props['id']]):this.getIconById(option[this.props['id']]))
|
|
},
|
|
focus(){
|
|
var selectRef=this.$refs['selectRef']
|
|
selectRef.focus();
|
|
},
|
|
blur(){
|
|
var selectRef=this.$refs['selectRef']
|
|
selectRef.blur();
|
|
}
|
|
},
|
|
|
|
}
|