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.

636 lines
20 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. import util from "../js/util"
  2. export const MdpSelectMixin = {
  3. computed: {
  4. avaterCpd(){
  5. var isEmpty= !this.myVal || this.myVal.length==0
  6. var obj={isNull:isEmpty,icon:this.icon,color:this.color,id:'',name:''}
  7. if(isEmpty){
  8. obj.icon='el-icon-full-screen'
  9. obj.color='#E4E7ED'
  10. return obj;
  11. }else{
  12. if(this.multiple==true){
  13. if(this.sels && this.sels.length>0){
  14. return this.sels[0]
  15. }else{
  16. var val=this.myVal[0]
  17. if(!obj.color){
  18. obj.color=this.colorFun?this.colorFun(val):util.getColorById(val)
  19. }
  20. if(!obj.icon){
  21. obj.icon=this.iconFun?this.iconFun(val):util.getIconById(val)
  22. }
  23. obj.name=val
  24. obj.id=val
  25. }
  26. }else{
  27. if(this.sels){
  28. return this.sels
  29. }else{
  30. var val=this.myVal
  31. if(!obj.color){
  32. obj.color=this.colorFun?this.colorFun(val):util.getColorById(val)
  33. }
  34. if(!obj.icon){
  35. obj.icon=this.iconFun?this.iconFun(val):util.getIconById(val)
  36. }
  37. obj.name=val
  38. obj.id=val
  39. }
  40. }
  41. }
  42. return obj;
  43. },
  44. optionsCpd(){
  45. var options=[]
  46. var map=new Map();
  47. var idKey=this.props?this.props['id']:'id'
  48. var nameKey=this.props?this.props['name']:'name'
  49. if(this.initOptions){
  50. this.initOptions.forEach(k=>map.set(k[idKey],k))
  51. }
  52. if(this.options){
  53. this.options.forEach(k=>map.set(k[idKey],k))
  54. }
  55. if(this.plusOptions){
  56. this.plusOptions.forEach(k=>map.set(k[idKey],k))
  57. }
  58. if(this.item && this.item.options){
  59. this.item.options.forEach(k=>map.set(k[idKey],k))
  60. }
  61. var options2=[]
  62. var needFilter=!!this.filterFun
  63. var needTran=this.props!=null && (idKey!='id' || nameKey!='name')
  64. var all=map.values();
  65. for(let value of all) {
  66. if(needFilter){
  67. if(!this.filterFun(value,options)){
  68. continue;
  69. }
  70. }
  71. var idValue=value[idKey]
  72. if(needTran){
  73. if((idKey in value)){
  74. value['id']=idValue
  75. }
  76. if((nameKey in value)){
  77. value['name']=value[nameKey]
  78. }
  79. }
  80. if(this.colorFun){
  81. value.color=this.colorFun(idValue,value,options)
  82. }else{
  83. value.color=this.getColorById(idValue,value,options)
  84. }
  85. if(this.iconFun){
  86. value.icon=this.iconFun(idValue,value,options)
  87. }else{
  88. value.icon=this.getIconById(idValue,value,options)
  89. }
  90. options2.push(value)
  91. }
  92. return options2
  93. },
  94. sels(){
  95. if(this.multiple==true){
  96. if(this.myVal==null || this.myVal==''|| this.myVal.length==0 ){
  97. return this.optionsCpd.filter(k=>this.myVal==k[this.props['id']])
  98. }
  99. if(this.myVal instanceof Array ){
  100. return this.optionsCpd.filter(k=>this.myVal.some(v=>v==k[this.props['id']]))
  101. }else{
  102. return this.optionsCpd.filter(k=>this.myVal==k[this.props['id']])
  103. }
  104. }else{
  105. if(this.myVal==null || this.myVal=='' || this.myVal.length==0 ){
  106. return null
  107. }else {
  108. return this.optionsCpd.find(k=>k[this.props['id']]==this.myVal)
  109. }
  110. }
  111. },
  112. codeKey(){
  113. if(this.itemCode){
  114. return util.getCodeKey(this.itemCode,this.params)
  115. }else{
  116. if(this.loadFun){
  117. return util.getCodeKey(this.loadFun.name,this.params)
  118. }else{
  119. return "xxxx"
  120. }
  121. }
  122. },
  123. },
  124. data(){
  125. return {
  126. defaultColors:util.getDefaultColors(),
  127. myVal:[],
  128. item:{
  129. itemType:'4',
  130. options:[]
  131. },
  132. initOptions:[],
  133. }
  134. },
  135. watch:{
  136. codeKey(){
  137. this.initItemOptions();
  138. },
  139. value(val){
  140. this.initMyValByValue(val)
  141. }
  142. },
  143. props: {
  144. title:{
  145. type: String,
  146. default:'',
  147. },
  148. itemCode:String,
  149. disabled:{
  150. type:Boolean,
  151. default:false,
  152. },
  153. closable:{
  154. type:Boolean,
  155. default:false,
  156. },
  157. effect:{
  158. type:String,
  159. default:'dark'//dark / light / plain
  160. },
  161. autoSelect:{
  162. type:Boolean,
  163. default:false,
  164. },
  165. /**
  166. * 如果是itemCode将提交后台过滤部分列表数据
  167. * 如果是loadFun,将提交后台参与过滤
  168. */
  169. params:{
  170. type:Object,
  171. default:null,
  172. },
  173. value: {
  174. type:[String,Number,Array],
  175. default:'',
  176. },
  177. clearable:{
  178. type:Boolean,
  179. default:true,
  180. },
  181. styleObj:{
  182. type:Object,
  183. default:function(){return { marginTop:'5px' }}
  184. },
  185. label: {
  186. type: String,
  187. default: "",
  188. },
  189. emptyText:{
  190. type:String,
  191. default:'请选择'
  192. },
  193. options:{
  194. type:Array,
  195. default:null
  196. },
  197. /**
  198. * 在加载完options后追加进入列表的plusOptions.
  199. * 整个列表长度为 options+plusOptions 或者 后台返回的 options+plusOptions
  200. */
  201. plusOptions:{
  202. type:Array,
  203. default:null,
  204. },
  205. width:{
  206. type:[String,Number],
  207. default:null
  208. },
  209. /**
  210. * 支持select radio checkbox 三种
  211. */
  212. showType:{
  213. type:String,
  214. default:'select'
  215. },
  216. /**
  217. * 控制组件的布局
  218. * origin 原始方式保持element-ui原组件样式
  219. * tag 未编辑前以tag显示鼠标放入后显示原生组件模样
  220. * x 综合布局适合于表单追求美观的样式将颜色+图标+布局进行柔和组成新的组件
  221. */
  222. showStyle:{
  223. type:String,
  224. default:'origin'
  225. },
  226. /**
  227. * 是否多选
  228. */
  229. multiple:{
  230. type:Boolean,
  231. default:false,
  232. },
  233. /**
  234. * 分隔符如果多选并且指定了分隔符将接受分格符连接的字符串及返回分给符连接的字符串
  235. */
  236. split:{
  237. type:String,
  238. default:null
  239. },
  240. /**
  241. * 对列表进行转换{
  242. id:'key',
  243. name:'label'
  244. },
  245. 将把option.key=>option.id,把option.label=>option.name
  246. */
  247. props:{
  248. type: Object,
  249. default: function(){
  250. return {id:'id',name:'name'}
  251. },
  252. },
  253. /**
  254. * 从接口拉取数据的函数,加载顺序 options,itemCode,loadOption,
  255. * 其中 params为 params属性
  256. * loadFun(params).then(res=>options=res.data.data)
  257. */
  258. loadFun:{
  259. type:Function,
  260. default:null,
  261. },
  262. /**
  263. * 对选项值进行过滤
  264. * 返回false将被过滤返回true将在列表显示
  265. * true/false=filterFun(option,idx,options)
  266. */
  267. filterFun:{
  268. type:Function,
  269. default:null
  270. },
  271. /**
  272. * 指定每个选项的颜色,option.color属性
  273. * option.color=colorFun(option,idx,options)
  274. */
  275. colorFun:{
  276. type:Function,
  277. default:null
  278. },
  279. icon:{
  280. type:String,
  281. default:null,
  282. },
  283. iconFun:{
  284. type: Function,
  285. default: null,
  286. },
  287. /**
  288. * placeholder
  289. */
  290. placeholder:{
  291. type: String,
  292. default:'请选择',
  293. },
  294. /**
  295. * medium/small/mini
  296. */
  297. size:{
  298. type: String,
  299. default:'small'
  300. },
  301. /**
  302. * 多选时是否将选中值按文字的形式展示
  303. */
  304. collapseTags:{
  305. type:Boolean,
  306. default:true,
  307. },
  308. /**
  309. * 多选时用户最多可以选择的项目数 0 则不限制
  310. */
  311. multipleLimit:{
  312. type:Number,
  313. default:0,
  314. },
  315. /**
  316. * select input name 属性
  317. */
  318. name:{
  319. type:String,
  320. default:'',
  321. },
  322. /**
  323. * select input autocomplete 属性
  324. */
  325. autoComplete:{
  326. type:String,
  327. default:'off',
  328. },
  329. /**
  330. * 是否可搜索
  331. */
  332. filterable:{
  333. type:Boolean,
  334. default:false,
  335. },
  336. /**
  337. * 搜素的时候的过滤函数
  338. */
  339. filterMethod:{
  340. type:Function,
  341. default:null,
  342. },
  343. /**
  344. * 搜索条件无匹配时显示的文字也可以使用slot="empty"设置
  345. */
  346. noMatchText:{
  347. type:String,
  348. default:'',
  349. },
  350. /**
  351. * 选项为空时显示的文字也可以使用slot="empty"设置
  352. */
  353. noDataText:{
  354. type:String,
  355. default:'',
  356. },
  357. /**
  358. * Select 下拉框的类名
  359. */
  360. popperClass:{
  361. type:String,
  362. default:'-',
  363. },
  364. /**
  365. * 多选且可搜索时是否在选中一个选项后保留当前的搜索关键词
  366. */
  367. reserveKeyword:{
  368. type:Boolean,
  369. default:false,
  370. },
  371. /**
  372. * 当有时候传入的值不一定在列表中存在事先已值值对应的名称则可以通过initName设置此时就算下拉列表没有对应的选项也会反显而不是显示早的值
  373. */
  374. initName:{
  375. type:String,
  376. default:null
  377. }
  378. },
  379. methods: {
  380. showSelect(){
  381. if(this.disabled){
  382. return;
  383. }
  384. if(this.$refs["operRef"]){
  385. if(this.$refs["operRef"].onFieldClick){
  386. this.$refs["operRef"].onFieldClick();
  387. }
  388. }
  389. },
  390. isCheck(option){
  391. if(!option && this.myVal){
  392. return false
  393. }else if(option && !option.id && !this.myVal){
  394. return false;
  395. }
  396. if(this.multiple){
  397. if(this.myVal instanceof Array){
  398. return this.myVal.some(k=>k==option.id)
  399. }else {
  400. return this.myVal==option.id
  401. }
  402. }else{
  403. return this.myVal==option.id
  404. }
  405. },
  406. filterOptions(itemOptions){
  407. if(this.filterFun && itemOptions!=null && itemOptions.length>0){
  408. itemOptions=itemOptions.filter(k=>this.filterFun(k,itemOptions))
  409. }
  410. return itemOptions;
  411. },
  412. transOptions(itemOptions){
  413. if(this.props!=null && this.props['id']=='id' && this.props['name']=='name'){
  414. return itemOptions;
  415. }
  416. if(itemOptions!=null && itemOptions.length>0){
  417. itemOptions.forEach(k=>{
  418. if((this.props['id'] in k)){
  419. k['id']=k[this.props['id']]
  420. }
  421. if((this.props['name'] in k)){
  422. k['name']=k[this.props['name']]
  423. }
  424. })
  425. }
  426. return itemOptions;
  427. },
  428. colorAndIconOptions(itemOptions){
  429. if(!itemOptions){
  430. return itemOptions
  431. }
  432. itemOptions.forEach((k,idx,all)=>{
  433. if(this.colorFun){
  434. k.color=this.colorFun(k[this.props['id']],k,all)
  435. }else{
  436. k.color=this.getColorById(k[this.props['id']],k,all)
  437. }
  438. if(this.iconFun){
  439. k.icon=this.iconFun(k[this.props['id']],k,all)
  440. }else{
  441. k.icon=this.getIconById(k[this.props['id']],k,all)
  442. }
  443. })
  444. return itemOptions;
  445. },
  446. iconOptions(itemOptions){
  447. if(this.iconFun){
  448. itemOptions.forEach((k,idx,all)=>{
  449. k.color=this.iconFun(k[this.props['id']],k,all)
  450. })
  451. }else{
  452. itemOptions.forEach((k,idx,all)=>{
  453. if(!k.icon){
  454. k.icon=this.getIconById(k[this.props['id']],k,all)
  455. }
  456. })
  457. }
  458. return itemOptions;
  459. },
  460. getColorById(id,option,itemOptions){
  461. return util.getColorById(id);
  462. },
  463. getIconById(id,option,itemOptions){
  464. if(id){
  465. return ''
  466. }else{
  467. return "el-icon-full-screen"
  468. }
  469. },
  470. afterLoad(itemOptions){
  471. return itemOptions;
  472. },
  473. clearCache(){
  474. this.$mdp.clearDictCache(this.itemCode,this.params)
  475. this.item.options=[]
  476. },
  477. initItemOptions(){
  478. if(this.itemCode){
  479. this.$mdp.ajaxGetDictOptions (this.itemCode,this.params).then(res=>{
  480. if(res.tips.isOk){
  481. var item=res.data
  482. var itemOptions=item.options?item.options:[]
  483. item.options=this.afterLoad(itemOptions)
  484. this.item=item
  485. }else{
  486. this.item={itemType:'4'}
  487. this.item.options=[]
  488. }
  489. })
  490. }else if(this.loadFun){
  491. this.loadFun(this.params).then(res=>{
  492. this.item={itemType:'4'}
  493. var itemOptions=res.data.data
  494. this.item.options=this.afterLoad(itemOptions)
  495. })
  496. }
  497. },
  498. onChange(val){
  499. if(val==this.value){
  500. return;
  501. }
  502. if(!val){
  503. this.$emit("input",val)
  504. this.$emit("change",val)
  505. this.$emit("change2",null)
  506. return;
  507. }
  508. if(this.multiple==true ){
  509. if(this.split){
  510. var valJoin=val.join(this.split)
  511. if(valJoin!=this.value){
  512. this.$emit("input",valJoin)
  513. this.$emit('change',valJoin)
  514. }
  515. }else{
  516. this.$emit("input",val)
  517. this.$emit('change',val)
  518. }
  519. }else{
  520. this.$emit("input",val)
  521. this.$emit('change',val)
  522. }
  523. this.onChange2(val)
  524. },
  525. onChange2(data){
  526. var options=null
  527. if(this.multiple==true ){
  528. options=this.optionsCpd.filter(k=>data.some(d=>d==k[this.props['id']]))
  529. }else{
  530. options=this.optionsCpd.find(k=>data==k[this.props['id']])
  531. }
  532. this.$emit("change2",options)
  533. },
  534. initData(){
  535. this.initMyValByValue(this.value,true)
  536. },
  537. /**
  538. * 只能初始化时执行一次否则性能有问题
  539. * @returns
  540. */
  541. initOptionsByInitName(myVal,myName){
  542. this.initOptions=myVal.map((v,idx)=>{
  543. var option={}
  544. option[this.props['id']]=v
  545. option[this.props['name']]=myName[idx]
  546. return option
  547. })
  548. },
  549. initMyValByValue(val,isFirst){
  550. if( this.myVal==val){
  551. return;
  552. }
  553. if(!val){
  554. this.myVal=null
  555. return;
  556. }
  557. var initName=this.initName
  558. if(this.multiple==true){
  559. if(!val){
  560. this.myVal=null
  561. return;
  562. }
  563. if(this.split){
  564. if(typeof val == "string"){
  565. this.myVal=val.split(this.split)
  566. if(initName){
  567. this.initOptionsByInitName(this.myVal,initName.split(this.split))
  568. }
  569. }else if(val instanceof Array){
  570. this.myVal=val
  571. if(initName){
  572. this.initOptionsByInitName(this.myVal,initName)
  573. }
  574. }else {
  575. this.myVal=[val]
  576. if(initName){
  577. this.initOptionsByInitName(this.myVal,[initName])
  578. }
  579. }
  580. }else{
  581. if(val instanceof Array){
  582. this.myVal=val
  583. if(initName){
  584. this.initOptionsByInitName(this.myVal,initName)
  585. }
  586. }else {
  587. this.myVal=[val+'']
  588. if(initName){
  589. this.initOptionsByInitName(this.myVal,[initName])
  590. }
  591. }
  592. }
  593. }else{
  594. this.myVal=val+''
  595. if(initName){
  596. this.initOptionsByInitName([this.myVal],[initName])
  597. }
  598. }
  599. },
  600. getMyColor(option){
  601. return option.color?option.color:(this.colorFun?this.colorFun(option[this.props['id']]):this.getColorById(option[this.props['id']]))
  602. },
  603. getMyIcon(option){
  604. return option.icon?option.icon:(this.iconFun?this.iconFun(option[this.props['id']]):this.getIconById(option[this.props['id']]))
  605. },
  606. focus(){
  607. var selectRef=this.$refs['selectRef']
  608. selectRef.focus();
  609. },
  610. blur(){
  611. var selectRef=this.$refs['selectRef']
  612. selectRef.blur();
  613. }
  614. },
  615. }