1;(function (){ 2 'use strict' 3 let txtRadio = `<div class="txt-radio" id="txtRadio"> 4 <span class="com-search-tit">{{label}}ï¼</span> 5 <div class="com-search-cont multi" 6 ref="searchCont" 7 v-show="!moreboxShow && !multiShow && !multiSelectShow" 8 style="position: relative"> 9 <a class="txt-radio-con" 10 v-if="isShowAll" 11 :class="{on: value == ''}" 12 @click="$emit('input', '')"> 13 å ¨é¨ 14 </a> 15 <a v-for="item, index in list" 16 class="txt-radio-con" 17 :title="item.name" 18 :class="{on: currentValue.indexOf(String(item.id)) > -1}" 19 @click="select(item.id, index)" 20 ref="searchCon"> 21 {{item.name}} 22 </a> 23 </div> 24 <template> 25 <div class="multi-search-cont checked-box" v-if="multi" v-show="multiSelectShow && !multiShow"> 26 <div class="checked-cont-bar">{{currentMultiName}}</div> 27 <div class="txt-muitl-search-clear" @click="clearMulti"> 28 æ¸ é¤å¤é<i class="icon-X"></i> 29 </div> 30 </div> 31 <div class="multi-search-cont more-box multi" v-if="multi" v-show="multiShow"> 32 <div class="multi-tit"> 33 <div class="search-bar"> 34 <input class="txt-radio-name" 35 type="text" 36 :value="multiKey" 37 @input="multiFilter" 38 @compositionstart="banInput(false)" 39 @compositionend="banInput(true)"/> 40 <span class="multi-seach-btn"><i class="icon-search"></i></span> 41 <a class="txt-radio-clear o8 blue" v-show="multiKey" @click="clear('multi')">æ¸ é¤</a> 42 </div> 43 </div> 44 <div class="multi-cont"> 45 <div class="multi-item-box letter"> 46 <div class="multi-item" 47 v-for="item, index in filterListMul" 48 @click="multiSelect(item.id, index)"> 49 <span class="span-checkbox" 50 :title="item.name" 51 :class="{'checked-part': multiItem.some((val)=>{return val.id == item.id })}"> 52 </span> 53 {{item.name}} 54 </div> 55 </div> 56 </div> 57 <div class="multi-bottom"> 58 <div class="checked-item-bar"> 59 <span>å·²é{{title}}ï¼</span> 60 <label :title="item.name" v-for="item ,index in multiItem" @click="multiItem.splice(index, 1)"> 61 <span class="checked-part-icon"></span>{{item.name}} 62 </label> 63 </div> 64 <div class="btn-bar"> 65 <a class="cancel-btn main-btn-w" @click="multiboxToggle(false)">åæ¶</a> 66 <a class=" main-btn-b ml15" @click="multiSubmit">æäº¤</a> 67 </div> 68 </div> 69 </div> 70 <div class="multi-search-cont more-box more" v-if="morebox" v-show="moreboxShow"> 71 <div class="multi-tit"> 72 <div class="search-bar"> 73 <input class="txt-radio-name" 74 type="text" 75 :value="singleKey" 76 @input="singleFilter" 77 @compositionstart="banInput(false)" 78 @compositionend="banInput(true)" />
79 <span class="multi-seach-btn"><i class="icon-search"></i></span> 80 <a class="txt-radio-clear o8 blue" v-show="singleKey" @click="clear('single')">æ¸ é¤</a> 81 </div> 82 </div> 83 <div class="multi-cont"> 84 <div class="multi-item-box letter"> 85 <div class="multi-item" v-for="item, index in filterListSin"> 86 <span class="txt-radio-con" 87 :title="item.name" 88 :class="{on: currentValue.indexOf(String(item.id)) > -1}" 89 @click="select(item.id, index)">{{item.name}}</span> 90 </div> 91 </div> 92 </div> 93 </div> 94 <div class="multi-btn-bar"> 95 <a class="multi-search-btn multi" 96 v-if="morebox" 97 v-show="!moreboxShow && !multiShow && !multiSelectShow" 98 @click="moreboxToggle"> 99 æ´å¤ 100 <i class="icon-down1"></i> 101 </a> 102 <a class="multi-search-btn multi" v-if="multi" v-show="!multiShow && !moreboxShow" @click="multiboxToggle">+å¤é</a> 103 <a class="multi-search-btn multi" v-if="morebox" v-show="moreboxShow" @click="moreboxToggle">æ¶èµ·<i class="icon-top"></i></a> 104 </div> 105 </template> 106 </div>`; 107 /** 108 * æç´¢ç»ä»¶--åéãå¤éãæ··åæç´¢ 109 * @props: 110 * morebox: æ¯å¦æ··åæç´¢æ å¿ä½ï¼é»è®¤false 111 * multi: æ¯å¦å¤éæ å¿ä½ï¼é»è®¤false 112 * data: æ°æ®åè¡¨ï¼æ¯æid-nameæ°ç» æ 对象 113 * value: éä¸çå¼(ååç»å®) 114 * label: æç´¢é¡¹çtitle 115 * å®ä¾ä½¿ç¨ï¼ /zwdc/view/factory/process/index.php 116 * <txt-radio label="å å·¥ç¶æ" :data="processStatus" v-model="param.status"></txt-radio> 117 */ 118 Vue.component('txtRadio', { 119 props: { 120 label: String, 121 data: [Array, Object], 122 value: String, 123 morebox: { 124 type: Boolean, 125 default: false 126 }, 127 multi: { 128 type: Boolean, 129 default: false 130 }, 131 // æ¯å¦æ¾ç¤ºå ¨é¨é项 132 isShowAll: { 133 type: Boolean, 134 default: true 135 } 136 }, 137 data() { 138 return { 139 list: [], // åé页é¢å±ç¤ºæ°æ® 140 filterListSin: [], // åéboxæ°æ®æº 141 filterListMul: [], // å¤éboxæ°æ®æº 142 multiItem: [], // å¤éboxå·²é项 143 singleKey: '', //åéboxæç´¢å ³é®å 144 multiKey: '', //å¤éboxæç´¢å ³é®å 145 input: true, //æ¯ä¸ºè¾å ¥æ¨¡å¼ 146 multiSelectShow: false, 147 moreboxShow: false, 148 multiShow: false 149 }; 150 }, 151 computed: { 152 currentData: function () { 153 return this.data instanceof Array ? 154 this.data : 155 Object.keys(this.data).map((id) => { 156 return {id: id, name: this.data[id]}; 157 }); 158 }, 159 currentValue: function () { 160 return this.value.split(','); 161 }, 162 currentMultiValue: function () { 163 if(this.currentValue.length > 1) { 164 this.multiSelectShow = true; 165 return this.currentData.filter((item) => { 166 return this.currentValue.indexOf(String(item.id)) > -1; 167 }); 168 } 169 else return []; 170 }, 171 currentMultiName: function () { 172 return this.currentMultiValue.map((item) => { 173 return item.name; 174 }).join('ã'); 175 } 176 }, 177 created() { 178 this.list = [...this.currentData]; 179 this.filterListSin = this.currentData; 180 this.filterListMul = this.currentData; 181 182 this.multiItem = [...this.currentMultiValue]; 183 }, 184 mounted() { 185 this.calculate(); 186 }, 187 methods: { 188 moreboxToggle() { 189 this.moreboxShow = !this.moreboxShow; 190 }, 191 multiboxToggle(flag) { 192 this.multiShow = !this.multiShow; 193 if(!flag) { 194 this.multiItem = []; 195 } 196 }, 197 select(id, index) { 198 let exist = this.list.some((item) => { 199 return item.id === id; 200 }); 201 if(this.value === id) return; 202 this.$emit('input', String(id)); 203 if(exist) return; 204 this.list.push(this.currentData[index]); 205 this.moreboxToggle(); 206 }, 207 multiSelect(id, index) { 208 let exist = this.multiItem.some((item) => { 209 return item.id === id; 210 }); 211 if(exist) return; 212 this.multiItem.push(this.currentData[index]); 213 }, 214 multiSubmit() { 215 if(this.multiItem.length === 0) { 216 promptInfo('请å¾éæç´¢é¡¹'); 217 return; 218 } 219 this.$emit('input', this.multiItem.map((item) => { return item.id; }).join(',')); 220 this.multiboxToggle(true); 221 this.multiSelectShow = true; 222 }, 223 banInput(flag) { 224 this.input = flag; 225 }, 226 singleFilter(e) { 227 setTimeout(() => { 228 if(!this.input) return; 229 let value = e.target.value; 230 this.singleKey = value; 231 this.filterListSin = this.currentData.filter((item) => { 232 return item.name.indexOf(value) >= 0; 233 });
234 }, 0); 235 }, 236 multiFilter(e) { 237 setTimeout(() => { 238 if(!this.input) return; 239 let value = e.target.value; 240 this.multiKey = value; 241 this.filterListMul = this.currentData.filter((item) => { 242 return item.name.indexOf(value) >= 0; 243 }); 244 }, 0); 245 }, 246 clearMulti() { 247 this.multiSelectShow = false; 248 this.$emit('input', ''); 249 this.$nextTick(()=> { 250 this.calculate(); 251 }); 252 }, 253 clear(type) { 254 if(type === 'single') { 255 this.singleKey = ''; 256 this.filterListSin = this.currentData; 257 } 258 else { 259 this.multiKey = ''; 260 this.filterListMul = this.currentData; 261 } 262 }, 263 calculate() { 264 let startIndex; 265 this.$refs.searchCon.some((item, index) => { 266 if(item.offsetTop > 6) { 267 startIndex = index; 268 return true; 269 } 270 }); 271 this.list = this.currentData.slice(0, startIndex); 272 } 273 }, 274 template: txtRadio 275 }); 276 277 let inputText = `<div class="input-text"> 278 <span class="com-search-tit">{{label}}ï¼</span> 279 <div class="com-search-cont"> 280 <input class="com-search-input w50" 281 :value="value" 282 @input="$emit('input', $refs.input.value)" 283 ref="input"/> 284 </div> 285 </div>`; 286 /** 287 * æç´¢ç»ä»¶--åéæ¡ 288 * @props: 289 * value: é»è®¤å¼(ååç»å®) 290 * label: æç´¢é¡¹çtitle 291 * å®ä¾ä½¿ç¨ï¼ /zwdc/view/factory/process/index.php 292 * <input-text label="å å·¥åå·" v-model="param.process_id" @keydown.enter.native="search()"></input-text> 293 */ 294 Vue.component('inputText', { 295 props: ['label', 'value'], 296 template: inputText 297 }); 298 299 let txtTip = `<div :class="['txt-tip', direction]"> 300 <slot></slot> 301 <div class="txt-tip-wrap" :style="style"> 302 <slot name="tip"></slot> 303 </div> 304 </div>`; 305 /** 306 * æ¬æµ®æ°æ³¡ç»ä»¶ 307 * @props: 308 * direction: æ°æ³¡æ¹å 309 * position: æ°æ³¡åç§»é 310 * å®ä¾ä½¿ç¨ï¼ /zwdc/view/factory/process/index.php 311 * <txt-tip direction="top" position="-20px"> 312 * <i class="icon icon-question2"></i> 313 * <template v-slot:tip> 314 * <p>å¤è´§å¨æ=åºå卿+æ¶è´§å¨æ</p> 315 * </template> 316 * </txt-tip> 317 */ 318 Vue.component('txtTip', { 319 props: { 320 direction: { // ä½ç½®ï¼left, top, bottom 321 type: String, 322 default: 'left' 323 }, 324 position: { // åç§»è·ç¦»ï¼px$, %$ 325 type: String 326 } 327 }, 328 data() { 329 return { 330 style: '', 331 }; 332 }, 333 created() { 334 if(this.position){ 335 switch(this.direction) { 336 case 'top': { 337 this.style = `left: ${this.position};`; 338 break; 339 } 340 case 'bottom': { 341 this.style = `left: ${this.position};`; 342 break; 343 } 344 default: { 345 this.style = `top: ${this.position};`; 346 break; 347 } 348 } 349 } 350 }, 351 template: txtTip 352 }); 353 354 let pagination = `<div id="pagination"> 355 <div class="page-sel"> 356 æ¾ç¤º 357 <select class="page-num" v-model="perPage" @change="reset"> 358 <option :value="item" v-for="item, index in pages">{{item}}</option> 359 </select> 360 æ¯é¡µ 361 </div> 362 <div class="page-plugin"> 363 <div class="letter page-div"> 364 <div class="light-pagination light-theme simple-pagination"> 365 <ul> 366 <li class="active" @click="prev(thispage - 1)"> 367 <span :class="thispage > 1? 'active' : 'current prev'"><div><i class="icon-previous_page"></i></div></span> 368 </li> 369 <template v-if="lastpage < 5"> 370 <li v-for="item in lastpage" 371 :class="{active: thispage == item}" 372 @click="goto(item)"> 373 <a :class="thispage == item? 'current' : 'page-link'">{{item}}</a> 374 </li> 375 </template> 376 <template v-else> 377 <li v-if="thispage>=2" @click="goto(1)"> 378 <a class="page-link">1</a> 379 </li> 380 <template v-if="thispage>=4"> 381 <li v-if="thispage==4" @click="goto(4)"><a class="page-link">2</a></li> 382 <li v-else class="disabled"><span class="ellipse">â¦</span></li> 383 </template> 384 <li v-if="thispage>=3" @click="goto(thispage-1)"><a class="page-link">{{thispage-1}}</a></li> 385 <li class="active"><a class="current">{{thispage}}</a></li> 386 <li v-if="thispage<=lastpage-2" @click="goto(thispage+1)"><a class="page-link">{{thispage+1}}</a></li> 387 <template v-if="thispage<=lastpage-3">
388 <li v-if="lastpage-thispage==3"><a class="page-link">{{lastpage-1}}</a></li> 389 <li v-else class="disabled"><span class="ellipse">â¦</span></li> 390 </template> 391 <li v-if="thispage<=lastpage-1" @click="goto(lastpage)"><a class="page-link">{{lastpage}}</a></li> 392 </template> 393 <li @click="next(thispage + 1)"> 394 <span :class="thispage < lastpage? 'active' : 'current next'"><div><i class="icon-next_page"></i></div></span> 395 </li> 396 </ul> 397 </div> 398 <div class="page-info">å ±<span class="total-page">{{lastpage}}</span>页 å°ç¬¬ 399 <input type="text" class="page-input" v-model="nextPage">页<a class="main-btn-w flip-page" @click="goto(nextPage)">ç¡®å®</a></div> 400 </div> 401 </div> 402 </div>`; 403 /** 404 * å页ç»ä»¶ 405 * @props: 406 * pages: æ¯é¡µæ¾ç¤ºç项æ°çå表æ°ç» 407 * perpage: é»è®¤æ¯é¡µæ¾ç¤ºçé¡¹æ° 408 * lastpage: æ»é¡µæ° 409 * thispage: å½åé¡µé¢ 410 * å®ä¾ä½¿ç¨ï¼ /zwdc/view/factory/process/index.php 411 * <pagination :perpage="gridData.per_page" :lastpage="gridData.last_page" @change="search" :thispage="thisPage"></pagination> 412 */ 413 Vue.component('pagination', { 414 props: { 415 pages: { 416 type: Array, 417 default: function () { 418 return [20, 30, 50, 100, 200]; 419 } 420 }, 421 perpage: { 422 type: Number, 423 default: 20 424 }, 425 lastpage: { 426 type: Number, 427 require: true 428 }, 429 thispage: {} 430 }, 431 data() { 432 return { 433 nextPage: '', 434 perPage: this.perpage 435 }; 436 }, 437 watch: { 438 'nextPage': function (val) { 439 this.nextPage = val.replace(/\D/g, ''); 440 }, 441 'perpage': function(val){ 442 this.perPage = val; 443 } 444 }, 445 created() { 446 }, 447 methods: { 448 goto(page) { 449 if(this.thispage == page) return; 450 if(page > this.lastpage) { 451 promptInfo('è¾å ¥é¡µç å¤§äºæ»é¡µæ°'); 452 return; 453 } 454 this.$emit('change', page, this.perPage); 455 this.nextPage = ''; 456 }, 457 reset() { 458 this.$emit('change', 1, this.perPage); 459 }, 460 prev(page) { 461 if(page < 1) return; 462 this.goto(page); 463 }, 464 next(page) { 465 if(page > this.lastpage) return; 466 this.goto(page); 467 } 468 }, 469 template: pagination 470 }); 471 472 /** 473 * æ¥çå¼¹çª 474 * @props: 475 * title: å¼¹çªæ é¢ 476 * value: æ§å¶å¼¹çªæ¯å¦æ¾ç¤ºçåéåï¼å¤é¨ä¼ å ¥ 477 * width: å¼¹çªæå°å®½åº¦ 478 * slot: 479 * é»è®¤ææ§½ï¼å¼¹çªä¸»é¢ 480 * footer: å¼¹çªåºé¨äº¤äºæé®åºå 481 * 482 * å®ä¾ä½¿ç¨ï¼ /zwdc/view/factory/process/index.php 483 */ 484 Vue.component('pop-module', { 485 props: { 486 title: { 487 type: String, 488 default: 'æ¥ç详æ ' 489 }, 490 value: { 491 type: Boolean, 492 default: false 493 }, 494 width: { 495 default: '580px' 496 } 497 }, 498 template: `<transition name="pop-ani"> 499 <div style="position: fixed; z-index: 99; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,.4);" 500 v-show="value" @click="$emit('input', false)"> 501 <div class="com-pop-module" 502 style="display: block;" :style="'min-width:'+ width" @click.stop=""> 503 <div class="com-pop-title com-bg-color-w"> 504 <a class="pop-close-btn opacity8" @click="$emit('input', false)"> 505 <i class="icon-X"></i> 506 </a> 507 {{title}} 508 </div> 509 <div class="com-pop-cont"> 510 <slot></slot> 511 </div> 512 <div class="com-pop-bottom" v-if="'footer' in this.$slots"> 513 <slot name="footer"></slot> 514 </div> 515 </div> 516 </div> 517 </transition>` 518 }); 519 520 let dialogContainer = document.body; 521 let alert = `<pop-module :title="title" :width="width" v-model="isShow"> 522 <div class="box-wrap" style="text-align: center;"> 523 {{text}} 524 </div> 525 <template v-slot:footer> 526 <a class="main-btn-w" @click="close(false)" v-if="buttons[1]">{{buttons[1]}}</a> 527 <a class="main-btn-b ml15" @click="close(true)">{{buttons[0]}}</a> 528 </template> 529 </pop-module>`; 530 /** 531 * VUEå®ä¾æ¹æ³æå±--å¼¹çªå®ä¾ 532 * @param text æç¤ºå 容 533 * @param opt æ é¢ 534 * @returns {Promise<any>} 535 * vue对象å é¨ä½¿ç¨ï¼this.$alert('å¼¹çªæç¤ºå 容', 'æ é¢opt').then(dlg => { dlg.close(); ... });
535 è¿åpromise对象,æ¥åthenåè°ï¼ 536 * @param opt ä¹å¯ä»¥æ¯å¯¹è±¡ï¼æä¾æ´å¤é ç½® { 537 * title : 'æ é¢', 538 * width : '360px', 539 * buttons : ['ç¡®å®', 'åæ¶'], 540 * } 541 * 使ç¨èä¾ï¼ /zwdc/view/factory/process/materialRelation.php 542 */ 543 function showAlert(text, opt){ 544 let vm = null; 545 let options; 546 let defaults = { 547 title : 'æç¤º', 548 width : '360px', 549 buttons : ['ç¡®å®', 'åæ¶'], 550 }; 551 if(Object.prototype.toString.call(opt).slice(8, -1) === 'String') { 552 options = Object.assign({}, defaults, {title: opt}); 553 } 554 else{ 555 options = Object.assign({}, defaults, opt); 556 } 557 let exec = new Promise((resolve, reject)=>{ 558 let alertOptions = { 559 data:function(){ 560 return { 561 title: options.title, 562 text: text, 563 width: options.width, 564 buttons: options.buttons, 565 isShow: true 566 }; 567 }, 568 watch: { 569 'isShow': function (val) { 570 if(!val) this.close(false); 571 } 572 }, 573 methods:{ 574 close(flag) { 575 let dlg = () => {dialogClose(vm);} 576 if(flag) { 577 resolve(dlg); 578 } 579 else dlg(); 580 } 581 }, 582 template: alert 583 }; 584 let creator = Vue.extend(alertOptions); 585 vm = new creator().$mount(); 586 dialogContainer.appendChild(vm.$el); 587 }); 588 return exec; 589 } 590 //å é¤ç»ä»¶vmï¼ä»ææ¬æµä¸ç§»é¤ï¼å¹¶å¨vueä¸éæ¯ï¼ 591 function dialogClose(vm){ 592 try{ dialogContainer.removeChild(vm.$el); } 593 catch (e) {} 594 vm.$destroy(); 595 } 596 Vue.prototype.$alert = showAlert; 597 598 Vue.component('tooltip', { 599 template: ` 600 <div v-tip> 601 <slot></slot> 602 <div style="display:none;" class="group-type-wrap">{{content}}</div> 603 </div> 604 `, 605 props: { 606 content: "" 607 }, 608 data() { 609 return { 610 show: false 611 } 612 }, 613 directives: { 614 tip: { 615 inserted(el) { 616 el.addEventListener('mouseover', () => { 617 el.querySelector('.group-type-wrap').style.display = 'block' 618 }) 619 el.addEventListener('mouseout',() => { 620 el.querySelector('.group-type-wrap').style.display = 'none' 621 }) 622 } 623 } 624 } 625 }) 626 627 Vue.component('sort-th', { 628 template: ` 629 <th style="cursor:pointer;" @click="sort"> 630 {{title}} 631 <div class="filter-up-down"> 632 <span :class='["filter-up", {active: active === "asc"}]'></span> 633 <span :class='["filter-down", {active: active === "desc"}]'></span> 634 </div> 635 </th> 636 `, 637 props: { 638 title: "" 639 }, 640 data() { 641 return { 642 active: false 643 } 644 }, 645 methods: { 646 reset() { 647 this.active = false 648 }, 649 sort() { 650 if (!this.active) { 651 this.active = 'desc' 652 } else if (this.active === 'asc') { 653 this.active = 'desc' 654 } else { 655 this.active = 'asc' 656 } 657 this.$emit('sort', this.active) 658 } 659 } 660 661 }) 662 663 // æ å½¢ç»ä»¶ 664 Vue.component('tree', { 665 template: 666 `<div class="category-tree" @click.stop> 667 <div class="selected-box" @click="toggleDropdown"> 668 <input type="text" :value="selectedCg" readonly> 669 <i class="icon-drop-down"></i> 670 </div> 671 <div class="result-box" v-show="isShow"> 672 <div class="search-box"> 673 <input type="text" placeholder="æç´¢åç±»" :value="keyword" @keydown.13="treeSearch" /> 674 </div> 675 <div class="result-list"> 676 <tree-item :tree-data="treeData" :keyword="keyword" :selected-node="selectedNode"></tree-item> 677 </div> 678 </div> 679 </div>`, 680 props:{ 681 selectedNode:{ 682 type: Number, 683 default: -1 684 } 685 }, 686 data(){ 687 return { 688 treeData: [{ 689 title: 'ææåç±»', 690 id: -1, 691 isOpen: true, 692 subCg:[ 693 { 694 title: '1æè£ ç±»', 695 id: 1, 696 isOpen: true, 697 subCg:[ 698 { 699 title: '1-1çè¢Tæ¤', 700 id: 101, 701 isOpen: false, 702 subCg:[ 703 {title: 'ç·è£ ', id: 10101}, 704 {title: 'å¥³è£ ', id: 10102}, 705 {title: 'éå°å¹´', id: 10103}, 706 ] 707 } 708 ] 709 },{ 710 title: '1-2å®¶å± ç¨å', 711 id: 2, 712 isOpen: false, 713 subCg:[ 714 {title: '客å ç¨å', id: 201}, 715 ] 716 } 717 ] 718 }], 719 keyword: '', 720 isShow:false, 721 selectedCg: 'ææåç±»' 722 } 723 }, 724 methods:{ 725 toggleDropdown(e){ 726 this.isShow = !this.isShow; 727 }, 728 treenodeChange(data){ 729 this.isShow = false; 730 this.selectedCg = data; 731 }, 732 treeSearch(e){ 733 this.keyword = e.target.value; 734 } 735 }, 736 created(){ 737 this.$root.$on('treenode-change', (data)=>{ 738 this.isShow = false; 739 this.selectedCg = data.fullname; 740 }) 741 }, 742 mounted(){ 743 $(document).on('click', ()=>{ 744 this.isShow = false; 745 }) 746 } 747 }); 748 Vue.component('tree-item', { 749 template: 750 `<ul> 751 <li v-for="item in treeDataFilter" 752 :class="{'open': item.isOpen}" 753 :key=""> 754 <div class="node" :style="styless"> 755 <template v-if="item.subCg"> 756 <!--<i class="icon-drop-down open" @click="item.isOpen=false"></i> 757 <i class="icon-next_page close" @click="item.isOpen=true"></i>--> 758 <i class="icon-drop-down open" @click="changeOpenStatus(item, false)"></i> 759 <i class="icon-next_page close" @click="changeOpenStatus(item, true)"></i> 760 </template> 761 <a @click="selectTreeNode(event, item, iParent+'>'+item.id, iParentName+'>'+item.title)"> 762 {{item.title}} 763 </a> 764 </div> 765 <template v-if="item.subCg"> 766 <tree-item 767 :tree-data="item.subCg" 768 :i-count="count" 769 :i-parent="iParent+'>'+item.id" 770 :i-parent-name="iParentName+'>'+item.title"> 771 </tree-item> 772 </template> 773 </li> 774 </ul>`, 775 props:{ 776 treeData:{ 777 type: Array, 778 default:[] 779 }, 780 keyword: { 781 type: String, 782 default: '' 783 }, 784 selectedNode:{ 785 type: Number, 786 default: -1 787 }, 788 iCount:{ 789 type: Number, 790 default: 0 791 }, 792 iParent: { 793 type: String, 794 default: '', 795 }, 796 iParentName: { 797 type: String, 798 default: '', 799 } 800 }, 801 data(){ 802 return{ 803 activeNode: this.selectedNode, 804 } 805 }, 806 computed: { 807 count(){ 808 return ++this.iCount; 809 }, 810 styless(){ 811 return { 812 'padding-left': this.count>=2 ? this.count*10+'px' : 0 813 } 814 }, 815 // treeDataByName(){ 816 // return this.filterTreeNode(this.treeData, node=>node.title.indexOf(this.keyword)>-1); 817 // }, 818 // treeDataById(){ 819 // return this.filterTreeNode(this.treeData, node=>node.id==this.selectedNode); 820 // }, 821 treeDataFilter(){ 822 let newTreeData = this.filterTreeNode(this.treeData, node=>node.title.indexOf(this.keyword)>-1); 823 return newTreeData; 824 }, 825 }, 826 watch:{ 827 'keyword': function(){ 828 console.log('keywordæ¹åäº', this.keyword); 829 } 830 }, 831 methods:{ 832 filterTreeNode(nodes, predicate) { 833 // å¦æå·²ç»æ²¡æèç¹äºï¼ç»æéå½ 834 if (!(nodes && nodes.length)) { 835 return; 836 } 837 // let nodesCopy = [...nodes]; 838 let nodesCopy = base.deepCopy(nodes); 839 let newChildren = []; 840 for (let node of nodesCopy) { 841 if (predicate(node)) { 842 // 妿èªå·±ï¼èç¹ï¼ç¬¦åæ¡ä»¶ï¼ç´æ¥å å ¥å°æ°çèç¹é 843 newChildren.push(node); 844 // å¹¶æ¥çå¤çå ¶ children 845 node.subCg = this.filterTreeNode(node.subCg, predicate); 846 } else { 847 // 妿èªå·±ä¸ç¬¦åæ¡ä»¶ï¼éè¦æ ¹æ®å鿥夿宿¯å¦å°å ¶å å ¥æ°èç¹é,æ ¹æ®éå½è°ç¨ filterTreeNode() çè¿å弿¥å¤æ 848 let subs = this.filterTreeNode(node.subCg, predicate); 849 if (subs && subs.length) { 850 // 1. 妿ååéä¸æç¬¦åè¦æ±çèç¹ï¼è¿å [...])ï¼å å ¥ 851 node.subCg = subs; 852 newChildren.push(node); 853 } 854 // 2. å¦åï¼ä¸å å ¥ï¼å 为æ´ä¸ªåé齿²¡æç¬¦åæ¡ä»¶çï¼ 855 } 856 } 857 return newChildren.length ? newChildren : void 0; 858 }, 859 // èç¹éä¸ï¼æ´¾åäºä»¶ 860 selectTreeNode(e, item, fullpath, fullname){ 861 // this.selectedNode = item.id; 862 this.$root.$emit('treenode-change', {item, fullpath:fullpath.slice(1), fullname:fullname.slice(1)}); 863 }, 864 changeOpenStatus(item, status){ 865 this.$set(item, 'isOpen', status); 866 this.$forceUpdate(); 867 } 868 }, 869 watch:{ 870 871 }, 872 created(){ 873 // console.log('sss'); 874 // console.log(this.treeData); 875 } 876 }); 877 878 // æç´¢ä¸ææ¡,åºåsku/ååskué¡µé¢ 879 Vue.component('ajax-select', { 880 template: `<div class="custom-select-box" @click.stop> 881 <div class="cont"> 882 <div class="option-selected" @click="showDropdown"> 883 <div class="overHidden" v-if="selectedTxt.length > 0" v-bind:title="selectedTxt" v-html="selectedTxt"></div> 884 <input v-else class="selected" placeholder="è¯·éæ©" style="background:#fff !important" :value="selectedTxt" readonly /> 885 <i class="icon-moredown"></i> 886 </div> 887 <div class="option-box" v-show="value"> 888 <div class="search-box"> 889 <input type="text" class="keyword" v-model="keyword" :placeholder="placeholder" @keydown.enter="search" v-focus="value" ref="keyword"> 890 <i class="icon-checkout_close clear" @click="clearAll"></i> 891 <i class="icon-search search" @click="search"></i> 892 </div> 893 <div class="option-list scroll-bar"> 894 <ul v-if="resultData.length"> 895 <template v-if="deleteJudge"> 896 <li v-for="item in resultData" :class="{selected: item.isChecked}" :key="item.id" @click="optionSelect($event,item)"> 897 <label> 898 <!--<input type="checkbox" v-model="item.isChecked" @click="optionSelect($event,item)" v-show="multiple" />--> 899 <input type="checkbox" :checked="item.isChecked" v-show="multiple" /> 900 <span v-html="item.name"></span> 901 </label> 902 </li> 903 </template> 904 <template v-else> 905 <li v-for="item in resultData" :class="{selected: item.isChecked}" :key="item.id"> 906 <label> 907 <input type="checkbox" :checked="item.isChecked" v-show="multiple" @change="optionSelect($event,item)" /> 908 <span v-html="item.name"></span> 909 </label> 910 </li> 911 </template> 912 </ul> 913 <div class="no-result" v-else>{{noResultTxt}}</div> 914 </div> 915 </div> 916 </div> 917 </div>`, 918 props:{ 919 url:{ 920 type: String, 921 default: '' 922 }, 923 multiple:{ 924 type: Boolean, 925 default: false 926 }, 927 type:{ 928 type: String 929 }, 930 init:{ //åå§éä¸å¼ 931 type: Array, 932 default: ()=>[] 933 }, 934 deleteJudge:{ //å 餿¶æ¯å¦è¿è¡å¤æ 935 type: Boolean, 936 default: false 937 }, 938 placeholder: { 939 type: String, 940 default: 'æç´¢è´¦å·ãå§åã群ç»ç¼å·' 941 } 942 }, 943 data(){ 944 return{ 945 value: false, 946 keyword: '', 947 noResultTxt: '请å è¾å ¥æç´¢å ³é®å', 948 resultData:[], 949 selectedData: this.init ? this.init : [] 950 } 951 }, 952 computed:{ 953 selectedTxt(){ 954 let txtArr = this.selectedData.map(item=>{ 955 return item.name; 956 }) 957 return txtArr.join(','); 958 } 959 }, 960 watch:{ 961 'selectedData': { 962 handler(newValue, oldValue) { 963 this.$parent.$emit('selected-change', newValue, this.type); 964 }, 965 deep: true 966 } 967 }, 968 directives:{ 969 focus:{ 970 // update: function(el, binding, vnode, oldVnode){ 971 // if(binding.value){ 972 // el.focus(); 973 // } 974 // } 975 } 976 }, 977 methods:{ 978 // è¿æ»¤htmlæ ç¾ 979 filterHTMLTag(data){ 980 data = data.replace(/<\/?[^>]*>/g, ''); //å»é¤HTML Tag 981 data = data.replace(/[|]*\n/, '') //å»é¤è¡å°¾ç©ºæ ¼ 982 data = data.replace(/&npsp;/ig, ''); //廿npsp 983 return data; 984 }, 985 showDropdown(){ 986 this.value = !this.value; 987 if(this.value){ //å±å¼æ¶ï¼é»è®¤å 容为空 988 this.$nextTick(()=>{ 989 this.$refs.keyword.focus(); 990 }) 991 this.keyword = ''; 992 this.resultData = []; 993 this.noResultTxt = '请å è¾å ¥æç´¢å ³é®å'; 994 // 页é¢ä¸çå ¶å®ä¸ææ¡æ¶èµ· 995 this.$parent.$emit('close-other'); 996 this.value = true; 997 } 998 }, 999 search(){ 1000 if(this.keyword){ 1001 this.resultData = []; 1002 this.noResultTxt = 'æç´¢ä¸...'; 1003 let self = this; 1004 $.ajax({
1005 type: 'post', 1006 url: this.url, 1007 data:{keyword: self.keyword}, 1008 success: function(res){ 1009 if(res.status>0){ 1010 if(res.data && !$.isEmptyObject(res.data)){ 1011 self.resultData = res.data.constructor=='Array' ? res.data : Object.values(res.data); 1012 // æ è¯éä¸é¡¹ 1013 self.resultData.forEach(item=>{ 1014 let isExist = self.selectedData.some(sItem=>sItem.id==item.id); 1015 self.$set(item, 'isChecked', isExist ? true : false); 1016 }); 1017 } else{ 1018 self.noResultTxt = '没æå¹é å°ä»»ä½ç»æ'; 1019 } 1020 } else{ 1021 self.noResultTxt = '没æå¹é å°ä»»ä½ç»æ'; 1022 } 1023 } 1024 }) 1025 } else{ 1026 this.resultData = []; 1027 this.noResultTxt = '请å è¾å ¥æç´¢å ³é®å'; 1028 } 1029 }, 1030 clearAll(){ 1031 this.keyword = ''; 1032 this.resultData = []; 1033 this.noResultTxt = '请å è¾å ¥æç´¢å ³é®å'; 1034 }, 1035 // å°é项设置为éä¸ 1036 optionCheck(item){ 1037 this.resultData.forEach(sItem=>{ 1038 if(sItem.id==item.id){ 1039 this.$set(sItem, 'isChecked', true); 1040 } 1041 return sItem; 1042 }); 1043 let isExist = this.selectedData.some(sItem=>sItem.id==item.id); 1044 if(!isExist){ 1045 this.selectedData.push(item); 1046 } 1047 }, 1048 // å°é项设置为ä¸éä¸ 1049 optionUncheck(item){ 1050 this.resultData.forEach(sItem=>{ 1051 if(sItem.id==item.id){ 1052 this.$set(sItem, 'isChecked', false); 1053 } 1054 return sItem; 1055 }); 1056 let _index = this.selectedData.findIndex(sItem=>sItem.id==item.id); 1057 if(_index>-1){ 1058 this.selectedData.splice(_index, 1); 1059 } 1060 }, 1061 optionSelect(e, item){ 1062 if(!this.multiple){ //åé 1063 this.resultData.forEach(sItem=>{ 1064 if(sItem.id != item.id){ 1065 this.$set(sItem, 'isChecked', false); 1066 } else{ 1067 this.$set(sItem, 'isChecked', true); 1068 } 1069 return sItem; 1070 }) 1071 this.selectedData = [item]; 1072 this.value = false; 1073 } else { //å¤é 1074 if(!item.isChecked) { //æ·»å 1075 this.optionCheck(item); 1076 } else{ //å é¤éä¸ 1077 // 妿å é¤é项éè¦è¿è¡å¤æï¼åæ´¾åäºä»¶ç»ç¶çº§ï¼ç±ç¶çº§æä½ï¼å¦åç´æ¥å é¤ 1078 if(this.deleteJudge){ 1079 this.$parent.$emit('option-del', item, e, this.type); 1080 } else{ 1081 this.optionUncheck(item); 1082 } 1083 } 1084 } 1085 } 1086 }, 1087 beforeMount() { 1088 this._close = e => { 1089 // 妿ç¹å»åçå¨å½åç»ä»¶å é¨, åä¸å¤ç, å¦åæ¶èµ· 1090 if(this.$el.contains(e.target)) { 1091 return; 1092 } 1093 this.value = false; 1094 }; 1095 }, 1096 mounted(){ 1097 document.body.addEventListener('click', this._close); 1098 }, 1099 beforeDestroy() { 1100 document.body.removeEventListener('click', this._close); 1101 }, 1102 }) 1103 1104 // 产åéæ©å¼¹çª 1105 Vue.component('product-select-pop', { 1106 template: 1107 `<transition name="fade"> 1108 <div class="popup product-select-popup" v-show="value"> 1109 <div class="cont" style="width:740px"> 1110 <i class="icon-checkout_close" @click="closePop"></i> 1111 <div class="popup-title">éæ©äº§å</div> 1112 <div class="popup-content"> 1113 <div class="product-select-pop"> 1114 <div class="flex-row flex-x-full"> 1115 <div class="form-item flex-row flex-y-center" style="width:50%"> 1116 <div class="form-label mr5">产ååç±»ï¼</div> 1117 <div class="form-content"> 1118 <treeselect 1119 v-model="selectedCg" 1120 :options="cgData" 1121 :multiple="false" 1122 placeholder="ææåç±»" 1123 :show-count="true" 1124 :default-expand-level="0" 1125 @select="selectCg" 1126 :normalizer="normalizer" 1127 noOptionsText="æ æ³è¯»ååç±»" 1128 /> 1129 </div> 1130 </div> 1131 <div class="form-item ml15 flex-row flex-y-center" style="width:50%"> 1132 <div class="form-label mr5">产åç±»åï¼</div> 1133 <div class="form-content"> 1134 <select v-model="searchParam.type"> 1135 <option value="">è¯·éæ©</option> 1136 <option value="2">ä¿é产å</option> 1137 <option value="1">ä¼é产å</option> 1138 <option value="3">ææ°äº§å</option> 1139 </select> 1140 </div> 1141 </div> 1142 </div> 1143 <div class="flex-row flex-wrap mt10"> 1144 <div class="form-item flex-row flex-y-center"> 1145 <div class="form-label mr5">产ååç§°/IDï¼</div> 1146 <div class="form-content"> 1147 <input type="text" :placeholder="isMultiple?'å¤ä¸ªåç§°/IDç¨éå·æç©ºæ ¼åå¼':'请è¾å ¥äº§ååç§°/ID'" v-model="searchParam.pro_name_num" style="width:346px;"> 1148 </div> 1149 </div> 1150 <div class="ml15 mt10"> 1151 <a class="main-btn mr5" @click="search(1)">æç´¢</a> 1152 <a class="main-btn gray" @click="reset">éç½®</a> 1153 <!--<a class="main-btn" @click="batchSelect">æ¹ééå</a> 1154 <a class="main-btn gray" @click="batchCancel">æ¹éåæ¶</a>--> 1155 </div> 1156 </div> 1157 <div style="max-height: 340px;min-height: 260px;overflow-y:auto" class="scrollbar mt10"> 1158 <table class="normal product-table"> 1159 <thead> 1160 <tr> 1161 <th style="width:40px;"> 1162 <input v-if="isMultiple" type="checkbox" v-model="checkAll" @change="toggleCheckAll" /> 1163 </th> 1164 <th>ç¼å·</th> 1165 <th style="width:260px">产ååç§°</th> 1166 <th>æä½èµ·æ¹ä»·</th> 1167 <th>ç产å</th> 1168 </tr> 1169 </thead> 1170 <tbody> 1171 <template v-if="!productList.length"> 1172 <tr><td colspan="5">æ¥è¯¢æ ç»æ</td></tr> 1173 </template> 1174 <template v-else> 1175 <tr v-for="item,index in productList"> 1176 <td> 1177 <label><input :type="isMultiple ? 'checkbox' : 'radio'" v-model="checkItems" :value="item.id" @change="toggleCheckItem(item, index)" /></label> 1178 </td> 1179 <td>{{item.id}}</td> 1180 <td class="tl"> 1181 <div> 1182 <div class="img-wrap"> 1183 <img :src="Object.values(Object.values(item.productTypeImg)[0])[0].small" /> 1184 </div> 1185 {{item.pro_name}} 1186 </div> 1187 </td> 1188 <td>{{item.price ? 'ï¿¥'+item.price : 'æªè®¾å®éå®ä»·æ ¼'}}</td> 1189 <td>{{item.factory_name}}</td> 1190 </tr> 1191 </template> 1192 </tbody> 1193 </table> 1194 </div> 1195 <div class="flex-row flex-x-full flex-y-center mt10"> 1196 <pagination-pro :total="pageTotal" :per-page="perPage" :current-page="curPage" @change="changePage"></pagination-pro> 1197 <div><span v-if="isMultiple">已鿩 <span class="blue">{{checkItems.length}}</span> 个产å</span><a class="main-btn red" style="color:#fff !important" @click="save">{{saveBtnLabel}}</a></div> 1198 </div> 1199 </div> 1200 </div> 1201 </div> 1202 </div> 1203 </transition>`, 1204 props: { 1205 value: { 1206 type: Boolean, 1207 default: true 1208 }, 1209 categories: { 1210 type: Array, 1211 default:()=>[] 1212 }, 1213 products: { //å·²å ³èç产åid 1214 type: Array, 1215 default: ()=>[] 1216 }, 1217 checkProducts: { //å·²å ³èç产å项 1218 type: Array, 1219 default: [] 1220 }, 1221 extraParams: { //æç´¢çé¢å¤åæ° 1222 type: Object, 1223 default: ()=>{} 1224 }, 1225 saveBtnLabel: { 1226 type: String, 1227 default: 'ç¡®å®å ³è' 1228 }, 1229 searchProductUrl: { 1230 type: String, 1231 default: '/admin/page/searchProduct' 1232 }, 1233 getCategoryUrl: { 1234 type: String, 1235 default: '/admin/page/getCategory' 1236 }, 1237 isMultiple: { // æ¯å¦æ¯æå¤éï¼é»è®¤å¤é 1238 type: Boolean, 1239 default: true 1240 } 1241 }, 1242 data(){ 1243 return { 1244 cgData: this.categories, 1245 productList: [], 1246 perPage: 20, 1247 curPage:1, 1248 pageTotal: 0, 1249 searchParam:{ 1250 cat_id: this.selectedCg, 1251 type: '', 1252 pro_name_num: '', 1253 }, 1254 selectedCg: -2, 1255 checkAll: false, //æ¯å¦å ¨é 1256 checkItems: this.products, //éä¸é¡¹ 1257 checkProductList: JSON.parse(JSON.stringify(this.checkProducts)) , //éä¸çè¡ 1258 } 1259 }, 1260 watch:{ 1261 'selectedCg': function(newValue, oldValue){ 1262 if(!newValue){ 1263 this.selectedCg = -2; 1264 this.$set(this.searchParam, 'cat_id', this.selectedCg); 1265 } 1266 }, 1267 }, 1268 methods:{ 1269 // æç´¢ 1270 search(page=this.curPage, pageSize=this.perPage){ 1271 let self = this; 1272 self.searchParam = Object.assign({}, self.searchParam, { 1273 page: page, 1274 pageSize: pageSize, 1275 cat_id: !self.searchParam.cat_id || self.searchParam.cat_id==-2 ? '' : self.searchParam.cat_id 1276 }, self.extraParams); 1277 showLoading(); 1278 $.ajax({
1279 type: 'post', 1280 url: self.searchProductUrl, 1281 data: self.searchParam, 1282 success: function(res){ 1283 hideLoading(); 1284 if(res.status>0){ 1285 self.productList = res.data.data; 1286 self.curPage = res.data.current_page; 1287 self.pageTotal = res.data.total; 1288 self.checkAll = false; 1289 } else{ 1290 promptInfo(res.msg); 1291 } 1292 } 1293 }) 1294 }, 1295 // 翻页 1296 changePage(page){ 1297 this.curPage = page; 1298 this.search(); 1299 }, 1300 // éç½® 1301 reset(){ 1302 this.curPage = 1; 1303 this.selectedCg = -2; 1304 this.searchParam = Object.assign({},{ 1305 cat_id: '', 1306 type: '', 1307 pro_name_num: '', 1308 page: this.curPage 1309 }); 1310 this.search(); 1311 }, 1312 // éä¸äº§ååç±» 1313 selectCg(node, instanceId){ 1314 this.selectedCg = node.id; 1315 this.$set(this.searchParam, 'cat_id', this.selectedCg); 1316 }, 1317 // å ¨éåé 1318 toggleCheckAll(){ 1319 if(this.checkAll){ //å ¨é 1320 this.productList.forEach((item,index)=>{ 1321 let isExist = this.checkItems.some(jItem=>jItem==item.id); 1322 if(!isExist){ 1323 this.checkItems.push(item.id); 1324 this.checkProductList.push(item) 1325 } 1326 }); 1327 } else{ //åé 1328 this.productList.forEach((item,index)=>{ 1329 let jIndex = this.checkItems.findIndex(jItem=>jItem==item.id); 1330 if(jIndex>-1){ 1331 this.checkItems.splice(jIndex,1); 1332 this.checkProductList.splice(jIndex,1); 1333 } 1334 }); 1335 } 1336 }, 1337 toggleCheckItem(item, index){ 1338 let checkItems = JSON.parse(JSON.stringify(this.checkItems)) 1339 if (!this.isMultiple) { 1340 checkItems = [checkItems] 1341 } 1342 // å表ä¸å卿ªéä¸ç项æ¶ï¼å ¨éä¸å¾é 1343 this.productList.forEach(item=>{ 1344 let isExist = checkItems.some(jItem=>jItem==item.id); 1345 if(!isExist){ 1346 this.checkAll = false; 1347 return; 1348 } 1349 }) 1350 let jIndex = this.checkProductList.findIndex(jItem=>jItem.id==item.id); 1351 if(jIndex>-1){ 1352 this.checkProductList.splice(jIndex,1); 1353 } else { 1354 if (this.isMultiple) { 1355 this.checkProductList.push(item) 1356 } else { 1357 this.checkProductList = [item] 1358 } 1359 } 1360 }, 1361 // ç¡®å®ä½¿ç¨ 1362 save(){ 1363 this.$emit('save', {checkItems: this.checkItems, checkProductList: this.checkProductList}); 1364 }, 1365 closePop(){ 1366 this.$emit('input', false); 1367 }, 1368 // è·ååç±» 1369 getCategory(){ 1370 let self = this; 1371 $.ajax({
1372 type: 'post', 1373 url: self.getCategoryUrl, 1374 success: function(res){ 1375 if(res.status>0){ 1376 self.cgData = res.data; 1377 self.$emit('updateCgData', self.cgData); 1378 } 1379 } 1380 }) 1381 }, 1382 normalizer(node){ 1383 return { 1384 id: node.id, 1385 label: node.curName, 1386 children: node.subCg, 1387 } 1388 }, 1389 }, 1390 created(){ 1391 if(!this.cgData.length){ 1392 // é¢è®¾ä¸ºææåç±»ï¼è§£å³æ¾ç¤ºunknowné®é¢ 1393 this.cgData = [{ 1394 curName: "ææäº§å", 1395 id: -2 1396 }]; 1397 this.getCategory(); 1398 } 1399 }, 1400 mounted(){ 1401 this.search(); 1402 } 1403 }) 1404 1405// å®å¶äº§åéæ©å¼¹çª 1406 Vue.component('custom-select-pop', { 1407 template: 1408 `<transition name="fade"> 1409 <div class="popup product-select-popup" v-show="value"> 1410 <div class="cont" style="width:740px"> 1411 <i class="icon-checkout_close" @click="closePop"></i> 1412 <div class="popup-title">éæ©äº§å</div> 1413 <div class="popup-content"> 1414 <div class="product-select-pop"> 1415 <div class="flex-row flex-wrap mt10"> 1416 <div class="form-item flex-row flex-y-center"> 1417 <div class="form-label mr5">å®å¶äº§åç¼å·ï¼</div> 1418 <div class="form-content"> 1419 <input type="text" :placeholder="isMultiple?'å¤ä¸ªç¼å·ç¨éå·æç©ºæ ¼åå¼':'请è¾å ¥ç¼å·'" v-model="searchParam.ids" style="width:346px;"> 1420 </div> 1421 </div> 1422 <div class="ml15 mt10"> 1423 <a class="main-btn mr5" @click="search(1)">æç´¢</a> 1424 <a class="main-btn gray" @click="reset">éç½®</a> 1425 </div> 1426 </div> 1427 <div style="max-height: 340px;min-height: 260px;overflow-y:auto" class="scrollbar mt10"> 1428 <table class="normal product-table"> 1429 <thead> 1430 <tr> 1431 <th style="width:40px;"> 1432 <input v-if="isMultiple" type="checkbox" v-model="checkAll" @change="toggleCheckAll" /> 1433 </th> 1434 <th>ç¼å·</th> 1435 <th>å¾ç</th> 1436 </tr> 1437 </thead> 1438 <tbody> 1439 <template v-if="!firstFlag && !productList.length"> 1440 <tr><td colspan="3">æ¥è¯¢æ ç»æ</td></tr> 1441 </template> 1442 <template v-else> 1443 <tr v-for="item,index in productList"> 1444 <td> 1445 <label><input :type="isMultiple ? 'checkbox' : 'radio'" v-model="checkItems" :value="item.id" @change="toggleCheckItem(item, index)" /></label> 1446 </td> 1447 <td>{{item.id}}</td> 1448 <td><img :src="item.image" /></td> 1449 </tr> 1450 </template> 1451 </tbody> 1452 </table> 1453 </div> 1454 <div class="flex-row flex-x-full flex-y-center mt10"> 1455 <pagination-pro :total="pageTotal" :per-page="perPage" :current-page="curPage" @change="changePage"></pagination-pro> 1456 <div><span v-if="isMultiple">已鿩 <span class="blue">{{checkItems.length}}</span> 个产å</span><a class="main-btn red" style="color:#fff !important" @click="save">{{saveBtnLabel}}</a></div> 1457 </div> 1458 </div> 1459 </div> 1460 </div> 1461 </div> 1462 </transition>`, 1463 props: { 1464 value: { 1465 type: Boolean, 1466 default: true 1467 }, 1468 products: { //å·²å ³èç产åid 1469 type: Array, 1470 default: ()=>[] 1471 }, 1472 checkProducts: { //å·²å ³èç产å项 1473 type: Array, 1474 default: [] 1475 }, 1476 extraParams: { //æç´¢çé¢å¤åæ° 1477 type: Object, 1478 default: ()=>{} 1479 }, 1480 saveBtnLabel: { 1481 type: String, 1482 default: 'ç¡®å®å ³è' 1483 }, 1484 searchProductUrl: { 1485 type: String, 1486 default: '/admin/product/getProductList' 1487 }, 1488 isMultiple: { // æ¯å¦æ¯æå¤éï¼é»è®¤å¤é 1489 type: Boolean, 1490 default: true 1491 } 1492 }, 1493 data(){ 1494 return { 1495 firstFlag: true, 1496 productList: [], 1497 perPage: 20, 1498 curPage:1, 1499 pageTotal: 0, 1500 searchParam:{ 1501 ids: '', 1502 }, 1503 checkAll: false, //æ¯å¦å ¨é 1504 checkItems: this.products, //éä¸é¡¹ 1505 checkProductList: JSON.parse(JSON.stringify(this.checkProducts)) , //éä¸çè¡ 1506 } 1507 }, 1508 methods:{ 1509 // æç´¢ 1510 search(page=this.curPage, pageSize=this.perPage){ 1511 this.firstFlag = false; 1512 let self = this; 1513 self.searchParam = Object.assign({}, self.searchParam, { 1514 page: page, 1515 pageSize: pageSize, 1516 }, self.extraParams); 1517 showLoading(); 1518 $.ajax({
1519 type: 'post', 1520 url: self.searchProductUrl, 1521 data: self.searchParam, 1522 success: function(res){ 1523 hideLoading(); 1524 if(res.status>0){ 1525 self.productList = res.data.list; 1526 self.curPage = res.data.current_page; 1527 self.pageTotal = res.data.total; 1528 self.checkAll = false; 1529 } else{ 1530 promptInfo(res.msg); 1531 } 1532 } 1533 }) 1534 }, 1535 // 翻页 1536 changePage(page){ 1537 this.curPage = page; 1538 this.search(); 1539 }, 1540 // éç½® 1541 reset(){ 1542 this.curPage = 1; 1543 this.searchParam = Object.assign({},{ 1544 ids: '', 1545 page: this.curPage 1546 }); 1547 this.search(); 1548 }, 1549 // å ¨éåé 1550 toggleCheckAll(){ 1551 if(this.checkAll){ //å ¨é 1552 this.productList.forEach((item,index)=>{ 1553 let isExist = this.checkItems.some(jItem=>jItem==item.id); 1554 if(!isExist){ 1555 this.checkItems.push(item.id); 1556 this.checkProductList.push(item) 1557 } 1558 }); 1559 } else{ //åé 1560 this.productList.forEach((item,index)=>{ 1561 let jIndex = this.checkItems.findIndex(jItem=>jItem==item.id); 1562 if(jIndex>-1){ 1563 this.checkItems.splice(jIndex,1); 1564 this.checkProductList.splice(jIndex,1); 1565 } 1566 }); 1567 } 1568 }, 1569 toggleCheckItem(item, index){ 1570 let checkItems = JSON.parse(JSON.stringify(this.checkItems)) 1571 if (!this.isMultiple) { 1572 checkItems = [checkItems] 1573 } 1574 // å表ä¸å卿ªéä¸ç项æ¶ï¼å ¨éä¸å¾é 1575 this.productList.forEach(item=>{ 1576 let isExist = checkItems.some(jItem=>jItem==item.id); 1577 if(!isExist){ 1578 this.checkAll = false; 1579 return; 1580 } 1581 }) 1582 let jIndex = this.checkProductList.findIndex(jItem=>jItem.id==item.id); 1583 if(jIndex>-1){ 1584 this.checkProductList.splice(jIndex,1); 1585 } else { 1586 if (this.isMultiple) { 1587 this.checkProductList.push(item) 1588 } else { 1589 this.checkProductList = [item] 1590 } 1591 } 1592 }, 1593 // ç¡®å®ä½¿ç¨ 1594 save(){ 1595 this.$emit('save', {checkItems: this.checkItems, checkProductList: this.checkProductList}); 1596 }, 1597 closePop(){ 1598 this.$emit('input', false); 1599 }, 1600 }, 1601 mounted(){ 1602 // this.search(); 1603 } 1604 }) 1605 // å®å¶äº§åéæ©å¼¹çª 1606 Vue.component('custom-select', { 1607 template: 1608 `<div> 1609 <div class="product-select-pop"> 1610 <div class="flex-row flex-wrap mt10"> 1611 <div class="form-item flex-row flex-y-center"> 1612 <div class="form-label mr5">å®å¶äº§åç¼å·ï¼</div> 1613 <div class="form-content"> 1614 <input type="text" :placeholder="isMultiple?'å¤ä¸ªç¼å·ç¨éå·åå¼':'请è¾å ¥ç¼å·'" v-model="searchParam.ids" style="width:346px;"> 1615 </div> 1616 </div> 1617 <div class="ml15 mt10"> 1618 <a class="main-btn mr5" @click="search(1)">æç´¢</a> 1619 <a class="main-btn gray" @click="reset">éç½®</a> 1620 </div> 1621 </div> 1622 <div style="max-height: 340px;min-height:100px;overflow-y:auto" class="scrollbar mt10"> 1623 <table class="normal product-table"> 1624 <thead> 1625 <tr> 1626 <th style="width:40px;"> 1627 <input v-if="isMultiple" type="checkbox" v-model="checkAll" @change="toggleCheckAll" /> 1628 </th> 1629 <th>å®å¶äº§åç¼å·</th> 1630 <th>é å¥å®å¶äº§å</th> 1631 <th>å¾ç 1632 <span class='tip-box'> 1633 <span class="tips-icon icon-error_explain"></span> 1634 <div class="tips-info"> 1635 <span class="tips-info-trangle"></span> 1636 <p>æéå®å¶äº§åç主å¾</p> 1637 </div> 1638 </span> 1639 </th> 1640 <th style='width:100px'>æåºå¼ 1641 <span class='tip-box'> 1642 <span class="tips-icon icon-error_explain"></span> 1643 <div class="tips-info l300"> 1644 <span class="tips-info-trangle"></span> 1645 <p>æç §æåºå¼éåºæåï¼æåºå¼è¶é«ï¼<br>ä½ç½®è¶é åï¼æåºå¼æé«ç产åï¼ä¼å æ¾ç¤ºå®å¶äº§å主å¾ï¼</p> 1646 </div> 1647 </span> 1648 </th> 1649 </tr> 1650 </thead> 1651 <tbody> 1652 <template v-if="!productList.length"> 1653 <tr style="height:70px"><td colspan="5">æ¥è¯¢æ ç»æ</td></tr> 1654 </template> 1655 <template v-else> 1656 <tr v-for="item,index in productList" :data-id='item.id' :key='item.id'> 1657 <td> 1658 <label><input :type="isMultiple ? 'checkbox' : 'radio'" v-model="checkItems" :value="item.id" @change="toggleCheckItem(item, index)" /></label> 1659 </td> 1660 <td>{{item.id}}</td> 1661 <td> 1662 <span class="custompro-id" @click="changeCustomizedProId(item)">{{item.sub_products}}</span> 1663 </td> 1664 <td><img :src="item.image" /></td> 1665 <td><input style="width:100%;height:100%;border:1px solid #949494" class='position' class="sort" type="text" oninput="onlyNum(this)" @blur='inputChange($event,item.id)' maxlength="9" v-model='item.position'></td> 1666 </tr> 1667 </template> 1668 </tbody> 1669 </table> 1670 </div> 1671 <div class="flex-row flex-x-full flex-y-center mt10"> 1672 <pagination-pro :total="pageTotal" :per-page="perPage" :current-page="curPage" @change="changePage"></pagination-pro> 1673 </div> 1674 </div> 1675 </div>`, 1676 props: { 1677 value: { 1678 type: Boolean, 1679 default: true 1680 }, 1681 products: { //å·²å ³èç产åid 1682 type: Array, 1683 default: ()=>[] 1684 }, 1685 checkProducts: { //å·²å ³èç产å项 1686 type: Array, 1687 default: ()=>[] 1688 }, 1689 extraParams: { //æç´¢çé¢å¤åæ° 1690 type: Object, 1691 default: ()=>{} 1692 }, 1693 saveBtnLabel: { 1694 type: String, 1695 default: 'ç¡®å®å ³è' 1696 }, 1697 searchProductUrl: { 1698 type: String, 1699 default: '/admin/product/getProductList' 1700 }, 1701 isMultiple: { // æ¯å¦æ¯æå¤éï¼é»è®¤å¤é 1702 type: Boolean, 1703 default: true 1704 }, 1705 productList:{ 1706 type: Array, 1707 default: ()=>[] 1708 } 1709 }, 1710 data(){ 1711 return { 1712 // productList: [], 1713 perPage: 20, 1714 curPage:1, 1715 pageTotal: 0, 1716 searchParam:{ 1717 ids: '', 1718 }, 1719 checkAll: false, //æ¯å¦å ¨é 1720 checkItems: this.products, //éä¸é¡¹ 1721 checkProductList: JSON.parse(JSON.stringify(this.checkProducts)) , //éä¸çè¡ 1722 setProducts: [] 1723 } 1724 }, 1725 methods:{ 1726 // æç´¢ 1727 search(page=this.curPage, pageSize=this.perPage){ 1728 let self = this; 1729 self.searchParam = Object.assign({}, self.searchParam, { 1730 page: page, 1731 pageSize: pageSize, 1732 }, self.extraParams); 1733 showLoading(); 1734 $.ajax({
1735 type: 'post', 1736 url: self.searchProductUrl, 1737 data: self.searchParam, 1738 success: function(res){ 1739 hideLoading(); 1740 if(res.status>0){ 1741 self.productList = res.data.list; 1742 self.curPage = res.data.current_page; 1743 self.pageTotal = res.data.total; 1744 self.checkAll = false; 1745 self.productList.forEach(item=>{ 1746 self.$set(item,'position','') 1747 }) 1748 self.$nextTick(()=>{ 1749 self.setPosition() 1750 self.$emit('changeproductlist', self.productList); 1751 }) 1752 } else{ 1753 promptInfo(res.msg); 1754 } 1755 } 1756 }) 1757 }, 1758 // 翻页 1759 changePage(page){ 1760 this.curPage = page; 1761 this.search(); 1762 }, 1763 // éç½® 1764 reset(){ 1765 this.curPage = 1; 1766 this.searchParam = Object.assign({},{ 1767 ids: '', 1768 page: this.curPage 1769 }); 1770 this.$emit('resetlist'); 1771 // this.search(); 1772 }, 1773 inputChange(e,id){ 1774 let self = this 1775 self.checkProductList.forEach((item,index)=>{ 1776 if(item.id==id){ 1777 self.checkProductList[index].position = e.currentTarget._value 1778 } 1779 }) 1780 this.setDataInit() 1781 }, 1782 // å ¨éåé 1783 toggleCheckAll(){ 1784 if(this.checkAll){ //å ¨é 1785 this.productList.forEach((item,index)=>{ 1786 let isExist = this.checkItems.some(jItem=>jItem==item.id); 1787 if(!isExist){ 1788 this.checkItems.push(item.id); 1789 this.checkProductList.push(item) 1790 } 1791 }); 1792 } else{ //åé 1793 this.productList.forEach((item,index)=>{ 1794 let jIndex = this.checkItems.findIndex(jItem=>jItem==item.id); 1795 if(jIndex>-1){ 1796 this.checkItems.splice(jIndex,1); 1797 this.checkProductList.splice(jIndex,1); 1798 } 1799 }); 1800 } 1801 this.setDataInit() 1802 }, 1803 toggleCheckItem(item, index){ 1804 let checkItems = JSON.parse(JSON.stringify(this.checkItems)) 1805 if (!this.isMultiple) { 1806 checkItems = [checkItems] 1807 } 1808 // å表ä¸å卿ªéä¸ç项æ¶ï¼å ¨éä¸å¾é 1809 this.productList.forEach(item=>{ 1810 let isExist = checkItems.some(jItem=>jItem==item.id); 1811 if(!isExist){ 1812 this.checkAll = false; 1813 return; 1814 } 1815 }) 1816 let jIndex = this.checkProductList.findIndex(jItem=>jItem.id==item.id); 1817 if(jIndex>-1){ 1818 this.checkProductList.splice(jIndex,1); 1819 } else { 1820 if (this.isMultiple) { 1821 this.checkProductList.push(item) 1822 } else { 1823 this.checkProductList = [item] 1824 } 1825 } 1826 this.setDataInit() 1827 }, 1828 // ç¡®å®ä½¿ç¨ 1829 save(){ 1830 this.$emit('save', {checkItems: this.checkItems, checkProductList: this.checkProductList}); 1831 }, 1832 closePop(){ 1833 this.$emit('input', false); 1834 }, 1835 setDataInit(){ 1836 this.$emit('save', {checkItems: this.checkItems, checkProductList: this.checkProductList}); 1837 }, 1838 setPosition(){ 1839 // this.checkProductList.forEach(item=>{ 1840 // $(`[data-id=${item.product_id}] td`).eq(3).find('input').val(item.position) 1841 // $(`[data-id=${item.product_id}] td`).eq(3).find('input')[0].dispatchEvent(new Event('input')) 1842 // }) 1843 let self = this 1844 self.productList.forEach(item=>{ 1845 self.checkProductList.forEach(item2=>{ 1846 if(item.id==item2.id){ 1847 item.position = item2.position 1848 } 1849 }) 1850 }) 1851 // self.checkProductList.forEach(item=>{ 1852 // $(`[data-id=${item.product_id}] td`).eq(3).find('input').val(item.position) 1853 // $(`[data-id=${item.product_id}] td`).eq(3).find('input')[0].dispatchEvent(new Event('input')) 1854 // }) 1855 }, 1856 changeCustomizedProId(item) { 1857 this.$emit('changecustomizedproid', item) 1858 }, 1859 }, 1860 mounted(){ 1861 // this.search(); 1862 }, 1863 watch:{ 1864 products(){ 1865 this.checkItems = this.products 1866 }, 1867 checkProducts(){ 1868 const self = this 1869 self.checkProductList = JSON.parse(JSON.stringify(this.checkProducts)) 1870 self.$nextTick(()=>{ 1871 self.setPosition() 1872 }) 1873 } 1874 } 1875 }) 1876 1877 // å页(ç¨äºäº§å鿩弹çª) 1878 Vue.component('pagination-pro', { 1879 template: 1880 `<div class="pagination"> 1881 <a class="icon-previous_page prev" :class="{disabled:curPage<=1}" @click="gotoPrev"></a> 1882 <ul> 1883 <template v-if="max<=5"> 1884 <li v-for="item in max" :class="{active:currentPage==item}" @click="curPage=item">{{item}}</li> 1885 </template> 1886 <template v-else> 1887 <li v-if="curPage>=2" @click="curPage=1">1</li> 1888 <template v-if="curPage>=4"> 1889 <li v-if="curPage==4" @click="curPage=4">2</li> 1890 <li v-else>...</li> 1891 </template> 1892 <li v-if="curPage>=3" @click="--curPage">{{curPage-1}}</li> 1893 <li class="active">{{curPage}}</li> 1894 <li v-if="curPage<=max-2" @click="++curPage">{{curPage+1}}</li> 1895 <template v-if="curPage<=max-3"> 1896 <li v-if="max-curPage==3">{{max-1}}</li> 1897 <li v-else>...</li> 1898 </template> 1899 <li v-if="curPage<=max-1" @click="curPage=max">{{max}}</li> 1900 </template> 1901 </ul> 1902 <a class="icon-next_page next" :class="{disabled:curPage>=max}" @click="gotoNext"></a>
1903 <span>å ±{{max}}页</span> 1904 <span class="ml5 mr5">è·³è³ <input type="text" v-model="inputPage" @input="onlyNumber" @keydown.13="gotoPage" /> 页</span> 1905 <a class="main-btn gray" @click="gotoPage">ç¡®å®</a> 1906 </div>`, 1907 props:{ 1908 total:{ 1909 type: Number, 1910 default: 1 1911 }, 1912 perPage:{ 1913 type: Number, 1914 default: 20 1915 }, 1916 currentPage:{ 1917 type: Number, 1918 default: 1, 1919 } 1920 }, 1921 data(){ 1922 return { 1923 curPage: this.currentPage || 1, 1924 inputPage: '' 1925 } 1926 }, 1927 computed:{ 1928 max(){ 1929 if(this.total<=0){ 1930 return 1; 1931 } 1932 return Math.ceil(this.total/this.perPage); 1933 } 1934 }, 1935 methods:{ 1936 gotoPrev(){ 1937 if(this.curPage<=1){ 1938 return; 1939 } 1940 this.curPage--; 1941 }, 1942 gotoNext(){ 1943 if(this.curPage>=this.max){ 1944 return; 1945 } 1946 this.curPage++; 1947 }, 1948 gotoPage(){ 1949 if(!this.inputPage || this.inputPage<1 || this.inputPage>this.max){ 1950 return; 1951 } 1952 this.curPage = Number(this.inputPage); 1953 }, 1954 onlyNumber(){ 1955 this.inputPage = this.inputPage.replace(/\D/g,''); 1956 } 1957 }, 1958 watch:{ 1959 'curPage':function(){ 1960 this.$emit('change', this.curPage); 1961 } 1962 } 1963 }); 1964 1965 // å页(ç¨äºæ¹æ¬¡å·çæè§å) 1966 Vue.component('pagination-index', { 1967 template: 1968 `<div class="pagination"> 1969 <span class="prev-page" :class="{'not': curPage==1}" @click="gotoPrev"><i class="icon-previous_page"></i></span> 1970 <input type="text" class="input-page" v-model="curPage" @input="onlyNumber" @keydown.enter="changePage" /> 1971 <span class="next-page" :class="{'not': curPage==max}" @click="gotoNext"><i class="icon-next_page"></i></span> 1972 <span class="total-page-box"> 1973 å ±<span class="total-page">{{max}}</span>页 | 1974 </span> 1975 æ¾ç¤º <select v-model="everyPage" @change="changePageSize"> 1976 <option v-for="item in pageSizes" :key="item" :value="item">{{item}}</option> 1977 </select> æ¯é¡µ | å ±æ¾å° {{total}} æ¡è®°å½ 1978 </div>`, 1979 props:{ 1980 total: { 1981 type: Number, 1982 default: 1, 1983 }, 1984 perPage:{ 1985 type: Number, 1986 default: 20 1987 }, 1988 currentPage: { 1989 type: Number, 1990 default: 1, 1991 }, 1992 pageSizes: { 1993 type: Array, 1994 default: ()=>([20, 30, 50, 100, 200]) 1995 } 1996 }, 1997 data(){ 1998 return { 1999 curPage: this.currentPage || 1, 2000 everyPage: this.perPage || 20, 2001 } 2002 }, 2003 computed:{ 2004 max(){ 2005 if(this.total<=0){ 2006 return 1; 2007 } 2008 return Math.ceil(this.total/this.perPage); 2009 } 2010 }, 2011 methods:{ 2012 gotoPrev(){ 2013 if(this.curPage<=1) return; 2014 this.curPage--; 2015 this.changePage(); 2016 }, 2017 gotoNext(){ 2018 if(this.curPage>=this.max) return; 2019 this.curPage++; 2020 this.changePage(); 2021 }, 2022 onlyNumber(){ 2023 this.curPage = this.curPage.replace(/\D/g,''); 2024 if(Number(this.curPage) == 0){ 2025 this.curPage = ''; 2026 } 2027 }, 2028 changePage(){ 2029 if(!this.curPage){ 2030 promptInfo('请è¾å ¥é¡µç '); 2031 return; 2032 } 2033 if(this.curPage>this.max){ 2034 promptInfo('è¾å ¥ç页ç å¤§äºæ»é¡µæ°'); 2035 return; 2036 } 2037 this.$emit('change', this.curPage); 2038 }, 2039 changePageSize(){ 2040 this.$emit('changesize', this.everyPage); 2041 }, 2042 } 2043 }); 2044 2045 //å¿«æ·æ¶æ¯ 2046 const quickReply = ` 2047 <div> 2048 <div class="quick-reply relative"> 2049 <a class="select-btn" :class="showSelect?'active':''" @click="openSelect">
2050 <span class="text">{{title}}</span> 2051 <span class="icon"><i class="icon-drop-down"></i></span> 2052 </a> 2053 <div v-if="showSelect" style="display:block;z-index:10"> 2054 <ul> 2055 <li v-for="item in conhtml" :key="item.id" @click="selectSave(item)">{{item.content}}</li> 2056 </ul> 2057 <div class="tr setting-div"><a class="setting-btn" @click="openReplyPop">{{title}}设置</a></div> 2058 </div> 2059 </div> 2060 <div v-if="isReplyList" class="popmask" style="display:block;z-index: 2000" @click="isReplyList = false"></div> 2061 <div v-if="isReplyList" class="popup popup-reply-setting" style="display:block;z-index:2001"> 2062 <i class="icon-operation_close" @click="isReplyList = false"></i> 2063 <div class="popup-title">{{title}}设置</div> 2064 <div class="popup-content"> 2065 <div class="desc-text">{{title}}</div> 2066 <div class="flex-row flex-x-full"> 2067 <ul> 2068 <li :class="item.active?'active':''" v-for="item in conhtml" :key="item.id" @click="selectLine(item)">{{item.content}}</li> 2069 </ul> 2070 <div class="operate-btns"> 2071 <p class="mb10"><a class="main-btn big gray" @click="operateReply('add')">æ·»å </a></p> 2072 <p class="mb10"><a :class="isSelect?'':'disabled'" class="main-btn big gray" @click="operateReply('edit')">ä¿®æ¹</a></p> 2073 <p><a :class="isSelect?'':'disabled'" class="main-btn big gray" @click="operateReply('del')">å é¤</a></p> 2074 </div> 2075 </div> 2076 </div> 2077 </div> 2078 <div v-if="isAddReply" class="popmask2" style="display:block;z-index: 3000" @click="isAddReply = false"></div> 2079 <div v-if="isAddReply" class="popup popup-reply-add" style="display:block;z-index:3001"> 2080 <i class="icon-operation_close close2" @click="isAddReply = false"></i> 2081 <div class="popup-title">{{popupTitle}}</div> 2082 <div class="popup-content"> 2083 <div class="desc-text">å 容ï¼500å以å ï¼</div> 2084 <div> 2085 <div class="relative"> 2086 <textarea maxlength="500" rows="4" class="w100 border" oninput="stringCalc($(this), 500, 0)" onpaste="stringPasteCalc($(this), 500, 0)" v-model="content"></textarea> 2087 <div class="tr" style="position: absolute; right:10px;bottom:8px"><span class="inputed-total">0</span>/500</div> 2088 </div> 2089 <div v-if="errorMsg" class="error-msg"><i class="icon-warning"></i>请填åå 容</div> 2090 </div> 2091 </div> 2092 <div class="popup-btn"> 2093 <a class="popup-cancel2" @click="isAddReply = false">åæ¶</a> 2094 <a class="popup-save" @click="saveBtn">ç¡®å®</a> 2095 </div> 2096 </div> 2097 </div> 2098 ` 2099 Vue.component('quickReply', { 2100 template: quickReply, 2101 props: { 2102 replyType: { 2103 require: true, 2104 }, 2105 title: { 2106 require: false, 2107 default: 'å¿«æ·æ¶æ¯' 2108 }, 2109 isCache: false, //æ¯å¦ä½¿ç¨åå§ç¼åæ°æ®, å¦æä½¿ç¨ç¼åæ°æ®ï¼éè¦å¨ç¶ç»ä»¶çå¬å表ååï¼ï¼è§£å³å¿«æ·åå¤å è½½æ ¢çé®é¢ï¼ 2110 initial: { 2111 require: false, 2112 default: () => [] 2113 } 2114 }, 2115 data() { 2116 return { 2117 conhtml: [...this.initial], 2118 isReplyList: false, 2119 isAddReply: false, 2120 isEditReply: false, 2121 popupTitle: 'æ·»å ' + this.title, 2122 selectItem: null, 2123 content: '', 2124 errorMsg: false, 2125 showSelect: false, 2126 isSaving: false, 2127 } 2128 }, 2129 beforeMount() { 2130 this._close = e => { 2131 // 妿ç¹å»åçå¨å½åç»ä»¶å é¨ï¼åä¸å¤ç 2132 if (this.$el.contains(e.target)) { 2133 return; 2134 } 2135 this.showSelect = false; 2136 }; 2137 document.body.addEventListener('click', this._close); 2138 }, 2139 mounted() { 2140 }, 2141 computed: { 2142 isSelect() { 2143 return this.conhtml.some(item => { 2144 if(item.active) { 2145 return true 2146 } 2147 }) 2148 } 2149 }, 2150 watch:{ 2151 'initial': { 2152 deep: true, 2153 handler: function(newval, oldval){ 2154 this.conhtml = newval 2155 } 2156 }, 2157 'conhtml': { 2158 deep: true, 2159 handler: function(newval, oldval){ 2160 this.$parent.$emit('list-changed', {data: newval}); 2161 } 2162 } 2163 }, 2164 methods: { 2165 openSelect() { 2166 if(!this.showSelect){ 2167 this.showSelect = true; 2168 const _this = this; 2169 if(!_this.isCache){ 2170 $.ajax({
2171 type: 'post', 2172 url: '/admin/QuickReply/getQuickReply', 2173 data: {type: this.replyType}, 2174 success(res){ 2175 if(res.length){ 2176 _this.conhtml = res 2177 _this.conhtml.map(items => { 2178 _this.$set(items, 'active', false) 2179 }) 2180 } 2181 } 2182 }); 2183 } 2184 } 2185 }, 2186 openReplyPop() { 2187 2188 this.isReplyList = true 2189 this.showSelect = false 2190 }, 2191 operateReply(type) { 2192 const _this = this 2193 switch(type){ 2194 case 'add': 2195 this.isAddReply = true 2196 this.isEditReply = false 2197 this.popupTitle = 'æ·»å '+ _this.title; 2198 this.content = '' 2199 break; 2200 case 'edit': 2201 if(this.isSelect) { 2202 this.isAddReply = true 2203 this.isEditReply = true 2204 this.popupTitle = 'ç¼è¾'+ _this.title 2205 this.content = this.selectItem.content 2206 } 2207 break; 2208 case 'del': 2209 if(this.isSelect) { 2210 showLoading(); 2211 $.ajax({
2212 type: 'post', 2213 url: '/admin/QuickReply/delete', 2214 data: {id: _this.selectItem.id, type: _this.replyType}, 2215 success(res){ 2216 hideLoading(); 2217 if(res.status>0){ 2218 _this.conhtml.splice(_this.conhtml.findIndex(item => {return item.id == _this.selectItem.id}),1) 2219 } else{ 2220 promptInfo(res.msg); 2221 } 2222 } 2223 }); 2224 } 2225 break; 2226 } 2227 }, 2228 selectLine(item) { 2229 this.conhtml.map(items => { 2230 this.$set(items, 'active', false) 2231 if(items.id === item.id) { 2232 this.$set(items, 'active', true) 2233 } 2234 }) 2235 this.selectItem = item 2236 }, 2237 saveBtn() { 2238 if(this.isSaving) return; 2239 if(this.content === '') { 2240 this.errorMsg = true 2241 return 2242 } 2243 const _this = this 2244 let params = { 2245 type: this.replyType, 2246 content: this.content 2247 } 2248 if(this.isEditReply) { //ç¼è¾å¿«æ·æ¶æ¯ 2249 params.id = this.selectItem.id 2250 } 2251 this.isSaving = true; 2252 let self = this; 2253 showLoading(); 2254 $.ajax({
2255 type: 'post', 2256 url: '/admin/QuickReply/save', 2257 data: params, 2258 success(res){ 2259 hideLoading(); 2260 self.isSaving = false; 2261 if(res.status>0){ 2262 promptInfo(res.msg); 2263 $('.popup-reply-add, .popmask2').hide(); 2264 if(_this.isEditReply){ 2265 _this.conhtml.map((item) => { 2266 if(item.id == _this.selectItem.id){ 2267 item.content = res.data.content 2268 } 2269 }) 2270 } else{ 2271 _this.conhtml.push({id: res.data.id, content: res.data.content}) 2272 } 2273 _this.isAddReply = false 2274 } else{ 2275 promptInfo(res.msg); 2276 } 2277 }, 2278 error(){ 2279 self.isSaving = false; 2280 } 2281 }); 2282 }, 2283 selectSave(item) { 2284 this.showSelect = false; 2285 this.$emit('selectsave',{item: item, el: this}); 2286 } 2287 }, 2288 beforeDestroy() { 2289 document.body.removeEventListener('click', this._close); 2290 } 2291 }) 2292 2293 //å¿«æ·å¼ç¨ 2294 const quickCite = ` 2295 <div> 2296 <div class="quick-cite relative"> 2297 <a class="select-btn" :class="showSelect?'active':''" @click="openSelect"> 2298 <span class="text">{{title}}</span> 2299 <span class="icon"><i class="icon-drop-down"></i></span> 2300 </a> 2301 <div v-if="showSelect" style="display:block;z-index:10;padding:10px"> 2302 <div class="display-method mr10"> 2303 <div class="tit"> 2304 ä¸äº«ä»·å±ç¤ºæ¹å¼ï¼ 2305 <span class="selected">{{showType}}</span><i class="icon-collection"></i> 2306 </div> 2307 <div class="select-box"> 2308 <p class="mb5">éæ©å±ç¤ºæ¹å¼ï¼</p> 2309 <div> 2310 <label class="mr10"> 2311 <input type="radio" name="display_type" data-val="2" v-model='showType' value="ä» çæ¾ç¤º" /> 2312 ä» çæ¾ç¤º 2313 </label> 2314 <label> 2315 <input type="radio" name="display_type" data-val="1" value="å ¨é¨å±ç¤º" v-model='showType' /> 2316 å ¨é¨å±ç¤º 2317 </label> 2318 </div> 2319 </div> 2320 </div> 2321 <table class="normal" style="table-layout: fixed;"> 2322 <thead> 2323 <th style="width: 120px">ä»¶æ°èå´</th> 2324 <th style="width: 80px">ä¸äº«ä»·(å )</th> 2325 <th style="width: 80px">平尿ç»è´¹ç¾åæ¯</th> 2326 <th style="width: 80px">æç»è´¹ææ£</th> 2327 <th style="width: 80px">åºç¡æå¡è´¹</th> 2328 <th style="width: 80px">平尿å¡è´¹</th> 2329 <th style="width: 80px">ç»ç®ä»·</th> 2330 <th style="width: 100px">ä¸äº«ä»·è§å</th> 2331 <th>æä½</th> 2332 </thead> 2333 </table> 2334 <div class="table-box" style="height: 202px;overflow-y: auto;margin-top:unset"> 2335 <table class="normal"> 2336 <tbody> 2337 <template v-if="citeList.length"> 2338 <template v-for="(item, index) in citeList" :key="item.id"> 2339 <template v-if="showType=='å ¨é¨å±ç¤º'||item.is_show==1"> 2340 <tr :class="{'red-background':item.is_default==1,'white-background':item.is_show==1,'gray-background':item.is_show=='-1'}" v-for="(jItem, jIndex) in item.items" :key="jIndex" @click="selectCite(jItem.id,item.items,item.name,index)" :style='index===numI?"background:#E7F3FC;":""'> 2341 <td style="width: 120px">{{jItem.qty_from}} - {{jItem.qty_to}}</td> 2342 <td style="width: 80px">{{jItem.price}}</td> 2343 <td style="width: 80px">{{jItem.base_service_percent}}%</td> 2344 <td style="width: 80px">{{jItem.service_charge_discount}}</td> 2345 <td style="width: 80px">{{getSettlementFee(jItem)}}</td> 2346 <td style="width: 80px">{{getSettlementFee(jItem)}}</td> 2347 <td style="width: 80px">{{jItem.factory_settlement_price}}</td> 2348 <td style="width: 100px" v-if="jIndex==0" :rowspan="item.items.length">{{item.name}}</td> 2349 <td v-if="jIndex==0" :rowspan="item.items.length"> 2350 <div> 2351 <span v-if='item.is_default==1'>é»è®¤è§å</span> 2352 <a v-else @click.stop='setDef(item,index)'>设为é»è®¤</a> 2353 </div> 2354 <div> 2355 <a v-if='item.is_show==1' @click.stop='setShowRule(item)'>éèè§å</a> 2356 <a v-else @click.stop='setShowRule(item)'>æ¾ç¤ºè§å</a> 2357 </div> 2358 </td> 2359 </tr> 2360 </template> 2361 </template> 2362 </template> 2363 <template v-else> 2364 <tr class="empty-tr" height="50"> 2365 <td colspan="8">ææ ä¸äº«ä»·è®¾ç½®</td> 2366 </tr> 2367 </template> 2368 </tbody> 2369 </table> 2370 </div> 2371 </div> 2372 </div> 2373 </div> 2374 ` 2375 Vue.component('quickCite', { 2376 template: quickCite, 2377 props: { 2378 title: { 2379 require: false, 2380 default: 'å¿«æ·å¼ç¨' 2381 }, 2382 numI: { 2383 require: false, 2384 default: '' 2385 }, 2386 editId:{ 2387 require: false, 2388 default: null, 2389 }, 2390 isCache: false, //æ¯å¦ä½¿ç¨åå§ç¼åæ°æ®, å¦æä½¿ç¨ç¼åæ°æ®ï¼éè¦å¨ç¶ç»ä»¶çå¬å表ååï¼ï¼è§£å³å¿«æ·åå¤å è½½æ ¢çé®é¢ï¼ 2391 citeList: { 2392 require: false, 2393 default: () => [] 2394 } 2395 }, 2396 data() { 2397 return { 2398 conhtml: [], 2399 selectItem: null, 2400 content: '', 2401 errorMsg: false, 2402 showSelect: false, 2403 nowId:'', 2404 showType: 'ä» çæ¾ç¤º', 2405 // numI:'' 2406 } 2407 }, 2408 beforeMount() { 2409 this._close = e => { 2410 // 妿ç¹å»åçå¨å½åç»ä»¶å é¨ï¼åä¸å¤ç 2411 if (this.$el.contains(e.target)) { 2412 return; 2413 } 2414 this.showSelect = false; 2415 }; 2416 document.body.addEventListener('click', this._close); 2417 }, 2418 mounted() { 2419 }, 2420 computed: { 2421 isSelect() { 2422 return this.conhtml.some(item => { 2423 if(item.active) { 2424 return true 2425 } 2426 }) 2427 } 2428 }, 2429 watch:{
2430 'initial': { 2431 deep: true, 2432 handler: function(newval, oldval){ 2433 this.conhtml = newval 2434 } 2435 }, 2436 'conhtml': { 2437 deep: true, 2438 handler: function(newval, oldval){ 2439 this.$parent.$emit('list-changed', {data: newval}); 2440 } 2441 } 2442 }, 2443 methods: { 2444 setDef(item){ 2445 this.citeList.forEach(citem=>{ 2446 this.$set(citem,'is_default',-1) 2447 }) 2448 this.citeList = this.citeList.filter(citem=>citem.id!=item.id) 2449 item.is_default = 1 2450 item.is_show = 1 2451 this.citeList.unshift(item) 2452 this.setDefShow(item,'1') 2453 }, 2454 setDefShow(item,type,val){ 2455 let saveParams = { 2456 id: item.id, 2457 apply_id: this.editId 2458 } 2459 saveParams = Object.assign(saveParams,type==1?{is_default: 1}:{is_show: val}) 2460 showLoading(); 2461 $.ajax({ 2462 type: 'post', 2463 url: '/admin/batchExclusivePrice/saveRecordConf', 2464 data: saveParams, 2465 success: function(res){ 2466 hideLoading(); 2467 if(res.status>0){ 2468 promptInfo('设置æå'); 2469 } else{ 2470 promptInfo(res.msg); 2471 } 2472 } 2473 }) 2474 }, 2475 setShowRule(item){ 2476 let is_show = null 2477 item.is_show == 1&&item.is_default == 1?this.$set(item,'is_default',-1):"" 2478 item.is_show == 1 ? is_show = -1 : is_show = 1 2479 item.is_show = is_show 2480 this.citeList.sort(function (a, b) { return b.is_show - a.is_show; }) 2481 this.setDefShow(item,'2',is_show) 2482 }, 2483 openSelect() { 2484 if(!this.showSelect){ 2485 this.showSelect = true; 2486 } 2487 }, 2488 selectCite(id,items,name,index) { 2489 this.numI = index 2490 let numL = 0 2491 for(let i=0;i<index;i++){ 2492 numL+= this.citeList[i].items.length 2493 } 2494 this.showSelect = false; 2495 this.nowId = id 2496 this.$emit('selectcite',{id: id, el: this,items:items,name:name,numL:numL,numI:index}); 2497 }, 2498 // è·å平尿å¡è´¹ 2499 getServiceFee(item){ 2500 let _price = parseInt(item.price*100); 2501 let _ret = _price*parseInt(item.base_service_percent); 2502 _ret = _ret * item.service_charge_discount; 2503 _ret = (_ret + parseInt(item.base_service_price*10000))/10000; 2504 return accuracyFun2(_ret); 2505 },//è·ååºç¡æå¡è´¹ 2506 getSettlementFee(item){ 2507 let _price = parseFloat(item.price||0); 2508 let _ret = parseFloat(item.factory_settlement_price!=''?item.factory_settlement_price:0); 2509 _ret = parseFloat(_price-_ret).toFixed(2); 2510 return _ret<0?0:accuracyFun2(_ret); 2511 }, 2512 // è·åç»ç®ä»· 2513 getSettlement(item){ 2514 let _price = parseInt(item.price*100), 2515 _fee = parseInt(this.getServiceFee(item)*100); 2516 let _ret = (_price - _fee)/100; 2517 return accuracyFun2(_ret); 2518 }, 2519 }, 2520 beforeDestroy() { 2521 document.body.removeEventListener('click', this._close); 2522 } 2523 }) 2524 2525 /** 2526 * éæ©ç¾¤ç» 2527 * å®ä¾ä½¿ç¨ï¼ /zwdc/view/admin/couponRule/index.php 2528 */ 2529 Vue.component('choice-group', { 2530 template: ` 2531 <transition name="fade"> 2532 <div class="popup popup-group" style="width:700px;display:block"> 2533 <i class="icon-checkout_close" @click="closePop"></i> 2534 <div class="popup-title">{{popTitle}}</div> 2535 <div class="popup-content" v-cloak> 2536 <div class="form-item flex-row"> 2537 <div class="form-label">群ç»ç±»åï¼</div> 2538 <div class="form-content"> 2539 <select class="group_type" v-model="searchParam.group_type"> 2540 <option value="">å ¨é¨ç±»å</option> 2541 <option v-for="item in groupType" :value="item.value">{{item.key}}</option> 2542 </select> 2543 </div> 2544 </div> 2545 <div class="form-item flex-row"> 2546 <div class="form-label">群ç»ç级ï¼</div> 2547 <div class="form-content"> 2548 <select class="level" v-model="searchParam.level"> 2549 <option value="">å ¨é¨ç级</option> 2550 <option v-for="item in groupLevel" :value="item.value">{{item.key}}</option> 2551 </select> 2552 </div> 2553 </div> 2554 <div class="group-content flex-row"> 2555 <div class="left w50"> 2556 <div class="search-box"> 2557 <input type="text" placeholder="æç´¢è´¦å·ãå§åã群ç»ç¼å·" class="keywords" 2558 v-model.trim="searchParam.keyword"
2559 @keydown.enter="searchGroup" 2560 > 2561 <i class="search icon-search" @click="searchGroup"></i> 2562 </div> 2563 <ul class="all-list" v-if="Object.keys(searchRes).length"> 2564 <li v-for="item of searchRes"> 2565 <label> 2566 <span v-html="item.name"></span> 2567 <input type="checkbox" v-model="item.isChecked" :value="item.id" :disabled="item.disabled" @change="itemClickHandler($event,item)"> 2568 </label> 2569 </li> 2570 </ul> 2571 <div class="no-data" v-else>{{emptyTxt}}</div> 2572 </div> 2573 <div class="right w50"> 2574 <div class="selected-number">{{ischecked}}</div> 2575 <ul class="selected-list"> 2576 <li v-for="item of selectedData"> 2577 <label> 2578 <span v-html="item.name"></span> 2579 <i class="remove icon-operation_close" @click="delSelected(item)"></i> 2580 </label> 2581 </li> 2582 </ul> 2583 </div> 2584 </div> 2585 </div> 2586 <div class="popup-btn"> 2587 <a class="popup-cancel" @click="closePop">åæ¶</a> 2588 <a class="popup-save" @click="save">ç¡®å®</a> 2589 </div> 2590 </div> 2591 </transition> 2592 `, 2593 props: { 2594 groupLevel: {}, 2595 groupType: {}, 2596 checkedData: {}, 2597 isRequire: { 2598 type: Boolean, 2599 default: true 2600 }, 2601 }, 2602 data() { 2603 return { 2604 emptyTxt: '请å è¾å ¥æç´¢å ³é®å', 2605 searchParam:{ 2606 level: '', 2607 group_type: '', 2608 keyword: '' 2609 }, 2610 searchRes: {}, 2611 selectedData: JSON.parse(JSON.stringify(this.checkedData)), 2612 isMultiple: false, 2613 initData: null, 2614 // reverseData: [], //ç¨äºåæ¾ææç¾¤ç»è®¾ç½®ä¸çé»ååæè ç¦ç¨ç¾¤ç»çç½åå 2615 reqUrl: '', 2616 saveUrl: '', 2617 popFlag: 1, //å¼¹æ¡æ è¯, 1æå±ç¾¤ç», 2ææç¾¤ç», 3æå®ç¦ç¨ç¾¤ç», 4 2618 // editingId: '', //ç¼è¾çæ°æ®ç¼å· 2619 } 2620 }, 2621 computed: { 2622 popTitle(){ 2623 let str = ''; 2624 switch(this.popFlag){ 2625 case 1: 2626 str = 'æå±ç¾¤ç»'; 2627 break; 2628 case 2: 2629 str = 'ææç¾¤ç»'; 2630 break; 2631 case 3: 2632 str = 'æå®ç¦ç¨ç¾¤ç»'; 2633 break; 2634 case 4: 2635 str = 'å®å¶äº§åæå®å ±äº«'; 2636 break; 2637 } 2638 return str; 2639 }, 2640 ischecked() { 2641 let data = {} 2642 if(Object.keys(this.selectedData).length) { 2643 data = this.selectedData 2644 }else { 2645 for(let key in this.searchRes){ 2646 if(this.searchRes[key].isChecked) { 2647 data[key] = this.searchRes[key] 2648 } 2649 } 2650 } 2651 if(Object.keys(data).length) { 2652 return `已鿩äº${Object.keys(data).length}个群ç»` 2653 }else { 2654 return '请å¾ééè¦æ·»å ç群ç»' 2655 } 2656 }, 2657 // selectedData() { 2658 // if(Object.keys(this.checkedData).length) { 2659 // return this.checkedData 2660 // }else { 2661 // let data = {} 2662 // for(let key in this.searchRes){ 2663 // if(this.searchRes[key].isChecked) { 2664 // data[key] = this.searchRes[key] 2665 // } 2666 // } 2667 // return data 2668 // } 2669 // } 2670 }, 2671 mounted(){ 2672 }, 2673 methods:{ 2674 // ç¾¤ç»æç´¢ 2675 searchGroup(){ 2676 if(!this.searchParam.keyword){ 2677 this.searchRes = Object.assign({}); 2678 return false; 2679 } 2680 let self = this; 2681 showLoading(); 2682 $.ajax({
2683 type: 'post', 2684 url: '/admin/statistics/getGroupInfo', 2685 data: self.searchParam, 2686 success: function(res){ 2687 hideLoading(); 2688 if(res.status>0){ 2689 if(res.data){ 2690 self.searchRes = Object.assign({}, res.data); 2691 for(let key in self.searchRes) { 2692 self.$set(self.searchRes[key], 'isChecked', false); 2693 } 2694 // è¥æ¯éä¸çï¼å°checkboxç¶æè®¾ç½®ä¸ºtrue 2695 Object.keys(self.selectedData).map(id=>{ 2696 if(self.searchRes[id]){ 2697 self.$set(self.searchRes[id], 'isChecked', true); 2698 self.$set(self.searchRes[id], 'disabled', self.selectedData[id].disabled); 2699 } 2700 }); 2701 //self.checkedData = {} 2702 } else{ 2703 self.searchRes = Object.assign({}); 2704 self.emptyTxt = '没æå¹é å°ä»»ä½ç»æ'; 2705 } 2706 } else{ 2707 self.searchRes = Object.assign({}); 2708 self.emptyTxt = '没æå¹é å°ä»»ä½ç»æ'; 2709 } 2710 } 2711 }) 2712 }, 2713 // 左侧æç´¢éä¸ï¼æ·»å æå é¤ 2714 itemClickHandler(event, item){ 2715 if(item.isChecked) { 2716 // if(!this.isMultiple){ //åé 2717 // for(let i in this.searchRes){ 2718 // if(i != item.id && this.searchRes[i]){ 2719 // this.$set(this.searchRes[i], 'isChecked', false); 2720 // } 2721 // } 2722 // this.selectedData = Object.assign({}); 2723 // } 2724 this.$set(this.selectedData, item.id, item); 2725 } 2726 else { 2727 this.$delete(this.selectedData, item.id); 2728 if(this.searchRes[item.id]){ 2729 this.$set(this.searchRes[item.id], 'isChecked', false); 2730 } 2731 } 2732 }, 2733 // å é¤éä¸ 2734 delSelected(item){ 2735 if (item.disabled) return 2736 this.$delete(this.selectedData, item.id); 2737 if(this.searchRes[item.id]){ 2738 this.$set(this.searchRes[item.id], 'isChecked', false); 2739 } 2740 }, 2741 // ä¿åé ç½® 2742 save(){ 2743 if(!Object.keys(this.selectedData).length && this.isRequire) { 2744 promptInfo('请添å è´¦æ·') 2745 return 2746 } 2747 this.$emit('groupsave', {selectedData: this.selectedData}) 2748 }, 2749 //å ³éå¼¹çª 2750 closePop() { 2751 this.$emit('closepop') 2752 } 2753 }, 2754 }) 2755 2756 /** 2757 * èªå®ä¹å¯¼åºå段 2758 */ 2759 Vue.component('custom-export', { 2760 template: ` 2761 <transition name="fade"> 2762 <div class="popup popup-sort" style="z-index: 1011;"> 2763 <div class="popup-title">éæ©é导åºçæ°æ®å段</div> 2764 <i class="icon-checkout_close" @click="closePop"></i> 2765 <div class="popup-content" v-cloak> 2766 <div class="sort-head"> 2767 <span class="blue cursorp" @click="resetFiled()">éç½®</span> 2768 <span class="check-all cursorp" :class="{select: allChecked}" @click="selectAllItem()">å ¨é</span> 2769 </div> 2770 <div class="sort-box" style="max-height:40vh"> 2771 <transition-group class="transition-wrapper" name="sort"> 2772 <div v-for="(item, index) in exportList" :key='item.field' 2773 :draggable="true" 2774 class="sort-item" 2775 style="cursor: move;" 2776 @dragstart="dragstart(item, $event)" 2777 @dragenter="dragenter(item, $event)" 2778 @click="selectCurItem(item)"> 2779 <span class="zw_icon-icon_yidong mr10"></span> 2780 <span class="title text-overflow" 2781 @mouseover="showTitle(item.name, $event)" 2782 @mouseleave="hideTitle()">{{ item.name }}</span> 2783 <span class="zw_icon-icon_tick" v-if="item.status == 1"></span> 2784 </div> 2785 </transition-group> 2786 </div> 2787 </div> 2788 <div class="popup-btn tr pr10 pt10" style="border-top: 1px solid #ccc;"> 2789 <a class="popup-cancel mr10" @click="closePop">åæ¶</a> 2790 <a class="popup-save" @click="save">导åº</a> 2791 </div> 2792 </div> 2793 </transition> 2794 `, 2795 props: { 2796 exportList: Array 2797 }, 2798 data() { 2799 return { 2800 oldData: null 2801 } 2802 }, 2803 computed: { 2804 allChecked() { 2805 let hasCheck = this.exportList && this.exportList.find(i => i['status'] == -1) 2806 if (hasCheck) { 2807 return false 2808 } else { 2809 return true 2810 } 2811 } 2812 }, 2813 methods: { 2814 resetFiled() { 2815 this.$emit('reset'); 2816 }, 2817 showTitle(txt, event) { 2818 if (txt.length <= 14) return; 2819 let {top, left} = $(event.target).offset(); 2820 if ($('body').find('.color-tip-box').length <= 0) { 2821 $('body').append(`<div class="color-tip-box"><span class="tips-info-trangle"></span><div class="color-tip-txt tl"></div></div>`); 2822 } 2823 $('.color-tip-box').find('.color-tip-txt').html(txt).css('max-width', '180px'); 2824 let h = $('.color-tip-box').height(); 2825 $('.color-tip-box').css({top: top - h - 20, left: left - 26}).show(); 2826 }, 2827 hideTitle() { 2828 $('.color-tip-box').css({top: 0, left: 0}).hide(); 2829 }, 2830 selectCurItem(item) { 2831 this.$set(item, 'status', item.status == 1 ? -1 : 1) 2832 }, 2833 selectAllItem() { 2834 let hasCheck = this.exportList.find(i => i['status'] == -1) 2835 if (hasCheck) { 2836 this.exportList.forEach( i => this.$set(i, 'status', 1)) 2837 } else { 2838 this.exportList.forEach( i => this.$set(i, 'status', -1)) 2839 } 2840 }, 2841 dragstart(value, e) { 2842 this.oldData = value 2843 }, 2844 dragenter(value, e) { 2845 e.preventDefault() 2846 if (this.oldData !== value) { 2847 let oldIndex = this.exportList.indexOf(this.oldData) 2848 let newIndex = this.exportList.indexOf(value) 2849 let newItems = [...this.exportList] 2850 newItems.splice(oldIndex, 1) 2851 newItems.splice(newIndex, 0, this.oldData) 2852 this.exportList = [...newItems] 2853 } 2854 }, 2855 closePop() { 2856 $('.popup-sort, .maskPop').hide() 2857 }, 2858 save() { 2859 let resultIds = this.exportList.map((i, index) => { 2860 const {status, field} = i 2861 return { 2862 status, 2863 field, 2864 sort: index + 1, 2865 } 2866 }) 2867 if (!resultIds.length) { 2868 promptInfo('è¯·éæ©è¦å¯¼åºçåæ®µ') 2869 return 2870 } 2871 this.$emit('save', resultIds) 2872 } 2873 } 2874 }) 2875})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.