1class ScriptContentComment extends Script { 2 constructor(params) { 3 super(params) 4 this.$dom = document.querySelector(`#${this.attrId}`) 5 this.proId = Number(window.app.info.page.content_id) 6 this.pageType = window.app.info.page.page_type 7 this.vue = null 8 this.utilts = window.app.utilts 9 this.$t = window.app.utilts.$t 10 this.language_code = params.language_code 11 } 12 13 async init() { 14 await new Load('/assets/plugins/vue.min.js') 15 this.initVue() 16 } 17 18 initVue() { 19 const _this = this 20 this.vue = new Vue({ 21 el: `#${this.attrId} .unit-content-comment`, 22 mixins: [this.data], 23 methods: { 24 $t(tr_str) { 25 return _this.utilts.$t(tr_str) 26 }, 27 openTip() { 28 const tipEle = _this.$dom.querySelector('.unit-content-comment__tip').cloneNode(true) 29 const tipMaskTip = _this.$dom.querySelector('.tip-mask').cloneNode() 30 document.body.appendChild(tipMaskTip) 31 document.body.appendChild(tipEle) 32 tipEle.classList.add('active') 33 tipMaskTip.classList.add('active') 34 document.body.style.overflow = 'hidden' 35 const closeBtn = tipEle.querySelector('.tip-close') 36 closeBtn.addEventListener('click', () => { 37 tipEle.classList.remove('active') 38 tipMaskTip.classList.remove('active') 39 tipEle.remove() 40 tipMaskTip.remove() 41 if (!document.querySelector('.modal-content-comment__info.active')) document.body.style.overflow = '' 42 }) 43 }, 44 setContentHidden() { 45 const content = document.querySelectorAll('.unit-content-comment .comment-description'); 46 content.forEach(val => { 47 // const nextElement = val.nextElementSibling; 48 const moreBtn = val.nextElementSibling 49 if (val.scrollHeight > val.clientHeight) { 50 const tempSpan = document.createElement('span'); 51 tempSpan.textContent = val.textContent; 52 tempSpan.style.visibility = 'hidden'; 53 tempSpan.style.whiteSpace = 'nowrap'; 54 const range = document.createRange(); 55 range.selectNodeContents(val); 56 const rects = range.getClientRects(); 57 const secondLineEnd = rects[1]; // 第äºè¡çç©å½¢ä¿¡æ¯ 58 moreBtn?.classList.remove('d-none') 59 } 60 moreBtn?.addEventListener('click', (e) => { 61 e.stopImmediatePropagation() 62 if (val.classList.contains('rich-text')) { 63 val.classList.remove('rich-text') 64 moreBtn.innerText = 'Put Away' 65 moreBtn.classList.remove('expand-text') 66 } else { 67 val.classList.add('rich-text') 68 moreBtn.innerText = '...More' 69 moreBtn.classList.add('expand-text') 70 } 71 }) 72 }) 73 }, 74 formatTimeAgo(targetTime) { 75 return globalThis.Server.formatTimeAgo(targetTime, _this.language_code) 76 }, 77 transformNumber(num) { 78 return globalThis.Server.transformNumber(num) 79 }, 80 async init() { 81 // this.countryDatas = await window.app.info.getCountryList() 82 await this.updataDetailCommentConfig() 83 if (this.commentConfig.content_show === 1 || this.isDesign) { 84 await this._getCommentData() 85 if (window.app.info.user.is_login) { 86 this.getUserInfo() 87 } 88 this.getCommentTotal() 89 this.setContentHidden() 90 } else { 91 this.currentDom.parentNode?.removeChild(this.currentDom) 92 } 93 window.addEventListener('resize', () => { 94 this.setContentHidden() 95 }) 96 }, 97 getUserInfo() { 98 Utilts.ins().request({ 99 url: '/member/detail', 100 method: 'GET', 101 params: {} 102 }).then(res => { 103 if (res.code === 0) { 104 window.app.info.user.nickname = res.data.nickname 105 } 106 }).catch(err => reject(err)) 107 }, 108 treeToList(tree) { 109 const list = []; 110 function traverse(node) { 111 let resNode = { ...node } 112 delete resNode.children 113 list.push(resNode);
114 if (node.children) node.children.forEach(traverse); 115 } 116 tree.forEach(traverse); 117 return list; 118 }, 119 expandReply(item) { 120 if (item.hidden_reply) { 121 this.$set(item, 'hidden_reply', !item.hidden_reply) 122 if (_this.utilts.getScreen() === 'default') { 123 this.resetDrawContent() 124 } 125 return false 126 } 127 if (item.expandLoading) return 128 this.$set(item, 'expandLoading', true) 129 this.clickCommentIds.push(item.id) 130 this.clickCommentIds = [...new Set(this.clickCommentIds)] 131 this.getReplayData({ 132 site_id: window.app.info.site.site_id, 133 id: item.id, 134 comment_group_id: item.comment_group_id, 135 page_number: item.reply_map.page_number + 1, 136 page_size: this.reply_size 137 }).then(res => { 138 if (res.code === 0) { 139 if (res.data.list.length) { 140 res.data.list.forEach(val => { 141 if (val.media && !val.comment && !val.comment_img) { 142 val.comment_img = [{ img: "https://img.yfisher.com/b11108/1748428982821-default-media-comment.png", type: 1 }] 143 } 144 }) 145 } 146 item.expandLoading = false 147 item.reply_map.page_number++ 148 const groupArr = item.group_comment_tree || [] 149 this.$set(item, 'group_comment_tree', groupArr.concat(res.data.list)) 150 item.reply_map.total = item.reply_map.total - this.reply_size 151 if (_this.utilts.getScreen() === 'default') { 152 this.resetDrawContent() 153 } 154 } 155 }) 156 }, 157 hideReplies(item) { 158 this.$set(item, 'hidden_reply', !item.hidden_reply) 159 }, 160 getCommentTotal() { 161 Utilts.ins().request({ 162 url: '/product-comment/get-count', 163 method: 'GET', 164 params: { 165 site_id: window.app.info.site.site_id, 166 product_id: this.proId, 167 type: 3 168 } 169 }).then(res => { 170 if (res.code === 0) { 171 this.page.total = res.data 172 } 173 }) 174 }, 175 async _getCommentData(currentPageSize) { 176 await this.getCommentData({ 177 site_id: window.app.info.site.site_id, 178 product_id: this.proId, 179 page_number: currentPageSize ? 1 : this.page.page_number, 180 page_size: currentPageSize || this.page.page_size, 181 position: 1, 182 status: 1, 183 comment_type: this.pageType === 'article_detail' ? 2 : 3, 184 is_get_reply: 0 185 }).then(res => { 186 if (res.data.list.length) { 187 res.data.list.forEach((item, index) => { 188 if (item.media && !item.comment && !item.comment_img) { 189 item.comment_img = [{ img: "https://img.yfisher.com/b11108/1748428982821-default-media-comment.png", type: 1 }] 190 } 191 // item.group_comment_tree = this.treeToList(item.group_comment_tree) 192 if (!currentPageSize) { 193 item.group_comment_tree = [] 194 } 195 item.reply_map = { 196 page_number: 0, 197 total: item.comment_count, 198 page_count: Math.ceil(item.comment_count / this.reply_size) 199 } 200 if (this.clickCommentIds.length && this.clickCommentIds.includes(item.id)) { 201 const currentObj = this.commentList.find(val => val.id === item.id) 202 item.reply_map.page_number = currentObj?.reply_map.page_number 203 item.group_comment_tree = currentObj?.group_comment_tree 204 } 205 }) 206 } 207 if (this.page.page_number === 1) { 208 this.tempList = res.data.list 209 } 210 if (currentPageSize) { 211 this.tempList = res.data.list.slice(0, 10) 212 } 213 this.commentList = !currentPageSize ? this.commentList.concat(res.data.list) : [...res.data.list, ...this.commentList] 214 // this.page.total = res.data.total 215 if (!currentPageSize) this.page.page_count = res.data.page_count 216 }) 217 }, 218 async onPagination(index) { 219 this.page.page_number = index 220 await this._getCommentData() 221 }, 222 itemClasses(score_) { 223 score_ = typeof score_ === 'number' ? score_ : Number(score_) 224 score_ = score_ >= 5 ? 5 : score_ 225 let result = [] 226 let score = Math.floor(score_ * 2) / 2 227 // åæ (éè¿è·1åä½å¤ææ¯å¦ä¸ºå°æ°) 228 let hasDecimal = score_ % 1 !== 0 229 // å ¨æ ï¼åä¸åæ´ï¼è·åå ¨æé¨åï¼ 230 let integer = Math.floor(score) 231 // éåå ¨æ 232 for (let i = 0; i < integer; i++) { 233 result.push("icon-base-collection on") 234 } 235 // å¤çåæ 236 if (hasDecimal) { 237 result.push("icon-base-collection half") 238 } 239 // è¡¥é½ 240 while (result.length < 5) { // å°è¿éè¿ä¸å¤äºé¢æï¼åå空æ 241 result.push("icon-base-collection off") 242 } 243 return result 244 }, 245 /** è¯è®ºå表 */ 246 getCommentData(params) { 247 return new Promise((resolve, reject) => { 248 Utilts.ins().request({ 249 url: '/product-comment/list-page', 250 method: 'GET', 251 params 252 }).then(res => { 253 if (res.code === 0) resolve(res) 254 else reject(res) 255 }).catch(err => reject(err)) 256 }) 257 }, 258 // åå¤å表 259 getReplayData(params) { 260 return new Promise((resolve, reject) => { 261 Utilts.ins().request({ 262 url: '/product-comment/reply-list-page', 263 method: 'GET', 264 params 265 }).then(res => { 266 if (res.code === 0) resolve(res) 267 else reject(res) 268 }).catch(err => reject(err)) 269 }) 270 }, 271 async addReview(parent_id = 0) { 272 if (this.commentConfig.login_show && !window.app.info.user.is_login) { 273 window.location.href = globalThis.Server.getRinseHref('/login.html', window.app.info.site) 274 return false 275 } 276 await new Load('/assets/plugins/comment-form.js') 277 let params = { page_type: this.pageType, unit_type: 'content-comment' } 278 params.product_id = window.app.info.page.content_id 279 if (parent_id) params.parent_id = parent_id 280 this.currentCommentId = parent_id || 0 281 params.is_verify = this.commentConfig.is_verify 282 new PluginCommentForm(params).modal() 283 }, 284 async updataDetailCommentConfig() { 285 return new Promise((resolve, reject) => { 286 Utilts.ins().request({ 287 url: '/product-comment/get-comment-config', 288 method: 'GET', 289 params: { 290 site_id: window.app.info.site.site_id, 291 type: this.pageType === 'article_detail' ? 2 : 3 292 } 293 }) 294 .then(res => { 295 this.commentConfig.is_verify = res.data.is_verify || 0 296 this.commentConfig.content_show = res.data.is_show_module || 0 297 this.commentConfig.score_show = res.data.is_show_detail || 0 298 this.commentConfig.btn_show = res.data.is_show || 0 299 this.commentConfig.login_show = res.data.is_login || 0 300 resolve() 301 }) 302 .catch(err => reject(err)) 303 }) 304 }, 305 async getUpdateAfter() { 306 if (this.commentConfig.is_verify) return 307 document.querySelector('#modal').style.removeProperty('zIndex') 308 // const allSize = this.page.page_number * this.page.page_size 309 if (!this.currentCommentId) await this._getCommentData(1) 310 if (this.clickCommentIds.length && this.currentCommentId) { 311 this.commentList.filter(val => val === this.currentCommentId && this.clickCommentIds.includes(val.id)).forEac
311h(async (item) => { 312 await this.getReplayData({ 313 site_id: window.app.info.site.site_id, 314 id: item.id, 315 comment_group_id: item.comment_group_id, 316 page_number: 1, 317 page_size: 1 318 }).then(res => { 319 if (res.code === 0) { 320 if (res.data.list.length) { 321 res.data.list.forEach(val => { 322 if (val.media && !val.comment && !val.comment_img) { 323 val.comment_img = [{ img: "https://img.yfisher.com/b11108/1748428982821-default-media-comment.png", type: 1 }] 324 } 325 }) 326 } 327 item.comment_count++ 328 this.$set(item, 'group_comment_tree', [...res.data.list, ...item.group_comment_tree]) 329 this.resetDrawContent() 330 } 331 }) 332 }) 333 } 334 if (this.currentCommentId && !this.clickCommentIds.includes(this.currentCommentId)) { 335 this.commentList.forEach(val => { 336 if (val.id === this.currentCommentId) { 337 console.log(val); 338 val.comment_count++ 339 val.reply_map.total++ 340 val.reply_map.page_count = Math.ceil(val.comment_count / this.reply_size) 341 } 342 }) 343 } 344 this.page.total++ 345 this.resetDrawContent() 346 }, 347 async loadMore() { 348 if (!this.loading) { 349 this.loading = true 350 this.page.page_number++ 351 await this._getCommentData() 352 this.resetDrawContent() 353 setTimeout(() => { 354 this.loading = false 355 }, 1000) 356 } 357 }, 358 expandMore() { 359 if (_this.utilts.getScreen() === 'default') { 360 this.page.page_number = 1 361 this.commentList = this.tempList 362 // const parents = _this.utilts.getParentsByAttr(_this.$dom, 'package-item', 'cell') 363 // let bottomVal = 0 364 // if (parents) { 365 // const videoInner = parents[0].querySelector('[package-type="content-detail"] .video-inner') 366 // if (videoInner) { 367 // const videoRect = videoInner.getBoundingClientRect() 368 // bottomVal = videoRect.bottom 369 // } 370 // } 371 let drawer = new Drawer() 372 drawer.setOptions({ 373 title: _this.$dom.querySelector('.header-inner').innerHTML, 374 className: 'modal-content-comment__info unit-content-comment', 375 content: _this.$dom.querySelector('.unit-content-comment__inner').innerHTML, 376 hiddentMask: true, 377 // bottomVal 378 }) 379 drawer.open() 380 this.setModalReply() 381 this.setContentHidden() 382 } 383 }, 384 setModalReply() { 385 const commentDoms = _this.$dom.querySelectorAll('.unit-content-comment__container > .unit-content-comment__item') 386 const drawerCommentDoms = document.querySelectorAll('.modal-content-comment__info .unit-content-comment__container > .unit-content-comment__item') 387 drawerCommentDoms.forEach((val, index) => { 388 const replyContainer = val.querySelector('.unit-content-comment__reply-container') 389 val.querySelector('.reply-quantity .expand-reply')?.addEventListener('click', () => { 390 commentDoms[index].querySelector('.reply-quantity .expand-reply')?.click() 391 if (replyContainer && replyContainer.classList.contains('hide-reply')) { 392 replyContainer.classList.remove('hide-reply') 393 } 394 }) 395 val.querySelector('.reply-quantity .hide-tex')?.addEventListener('click', () => { 396 commentDoms[index].querySelector('.reply-quantity .hide-tex')?.click() 397 this.resetDrawContent() 398 }) 399 const replayBtns = val.querySelectorAll(`[commentid]`) 400 if (replayBtns.length) { 401 replayBtns.forEach(replayDom => { 402 replayDom.addEventListener('click', () => { 403 const commentid = replayDom.getAttribute('commentid') 404 commentDoms[index].querySelector(`[commentid='${commentid}']`)?.click() 405 document.querySelector('#modal').style.zIndex = 1000 406 }) 407 }) 408 } 409 }) 410 const commentBtn = document.querySelector('.modal-content-comment__info .unit-content-comment__header .reviews-entry') 411 commentBtn?.addEventListener('click', () => { 412 _this.$dom.querySelector('.unit-content-comment .header-inner .reviews-entry').click() 413 document.querySelector('#modal').style.zIndex = 1000 414 }) 415 const drawerContent = document.querySelector('.modal-content-comment__info .drawer-content') 416 drawerContent.addEventListener('scroll', (e) => { 417 if (drawerContent.scrollTop + drawerContent.clientHeight + 100 >= drawerContent.scrollHeight && this.page.page_count > 1 && !this.loading) { 418 this.loadMore() 419 } 420 })
421 const drawerTipIcon = document.querySelector('.modal-content-comment__info .drawer-title .iconfont ') 422 drawerTipIcon?.addEventListener('click', (e) => { 423 this.openTip() 424 }) 425 }, 426 resetDrawContent() { 427 setTimeout(() => { 428 if (_this.utilts.getScreen() === 'default') { 429 const drawerTitle = document.querySelector('.modal-content-comment__info .drawer-title') 430 const drawerContent = document.querySelector('.modal-content-comment__info .drawer-content') 431 const scrollTop = drawerContent.scrollTop 432 drawerTitle.innerHTML = _this.$dom.querySelector('.header-inner').innerHTML 433 drawerContent.innerHTML = _this.$dom.querySelector('.unit-content-comment__inner').innerHTML 434 this.setModalReply() 435 drawerContent.scrollTop = scrollTop 436 } 437 this.setContentHidden() 438 }, 0) 439 } 440 } 441 }) 442 } 443 444 /** åºæ¬æ°æ®ä¿¡æ¯ */ 445 get data() { 446 return { 447 data: { 448 page: { 449 page_number: 1, 450 page_size: 10, 451 page_count: 1, 452 total: 0 453 }, 454 proId: this.proId, 455 pageType: this.pageType, 456 commentList: [], 457 tempList: [], 458 scoreAvg: 5.0, 459 countryDatas: [], 460 scoreData: [ 461 { 462 count: 0, 463 pre: 0, 464 score: 1, 465 }, 466 { 467 count: 0, 468 pre: 0, 469 score: 2, 470 }, 471 { 472 count: 0, 473 pre: 0, 474 score: 3, 475 }, 476 { 477 count: 0, 478 pre: 0, 479 score: 4, 480 }, 481 { 482 count: 0, 483 pre: 0, 484 score: 5, 485 } 486 ], 487 videoFormat: ['.mp4', '.flv', '.f4v', '.avi', '.mov', '.wmv'], 488 commentConfig: { 489 score_show: 0, 490 content_show: 0, 491 btn_show: 0, 492 login_show: 0, 493 is_verify: 0 494 }, 495 currentDom: this.$dom, 496 isDesign: this.utilts.checkDesign(), 497 reply_size: 10, 498 clickCommentIds: [], 499 currentCommentId: 0, 500 loading: false 501 } 502 } 503 } 504 505 render(parmas) { 506 if (parmas) { 507 this.vue.getUpdateAfter() 508 } else { 509 this.vue.init() 510 } 511 } 512}
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.