1import { getPageData, getCategoryData, setPageData, getPartnerLink, getDocumentPage, getProductMatchData } from './api/page.js' 2import { getContentCounts } from './api/site.js' 3import { getPageCategoryList, getVideoListPageBySearch, getArticleListPageBySearch, getPolymerizeList, getProductListPageBySearch, getSitemapTagsList, getFAQListPageBySearch } from './api/content.js' 4import { calcPathName } from './function.js' 5import { checkDetail, checkAnimat, getBasePagePath, getPageNumber, getPageId } from '../config/index.js' 6import localData from '../dist/js/data.js' 7import { pruneHiddenHtml } from './prune-hidden-html.js' 8 9class Page { 10 /** 11 * æé 彿° 12 */ 13 constructor(ctx) { 14 this.ctx = ctx 15 this.pageData = {} 16 } 17 18 /** 19 * åå§å 20 */ 21 async init() { 22 if (this.ctx.state.postCtxState && this.ctx.state.postCtxState.page) { 23 return this.ctx.state.postCtxState.page 24 } 25 26 let url_path = this.ctx.path 27 // 妿æ¯åç®å½å½¢å¼, è·¯å¾ä¸å»æå°è¯ç§åç¼ 28 if (this.ctx.state.site.domain_mode === 2 && this.ctx.state.site.lang_prefix !== '/') { 29 url_path = this.ctx.path.replace(this.ctx.state.site.lang_prefix, '') 30 } 31 // 请æ±é¡µé¢åæ° 32 const pageParams = { 33 language_code: this.getLanguageCode(), 34 site_id: this.ctx.state.site.site_id, 35 url_path: url_path || '/', 36 domain: this.ctx.state.site.domain 37 } 38 if (/\/product[_-]lives(|[_-]list\d+)\.html/.test(url_path)) { 39 pageParams.page_size = 12 40 } 41 // é¢è§æ¨¡å¼ 42 if (this.ctx.query.preview) pageParams.preview = this.ctx.query.preview 43 // è·åå½åé¡µæ°æ® 44 const urlType = this.ctx.path.replace('.html', '').replace('/', '') 45 if ( 46 globalThis.Server.checkDesign(this.ctx) && 47 ['product-detail', 'article-detail', 'video-detail', 'store-detail'].includes(urlType) 48 ) { 49 this.pageData = localData[urlType] 50 } else { 51 if ((this.ctx.path.slice(-1) !== '/' && this.ctx.path.slice(-5) !== '.html') || this.ctx.state.remote_server){ 52 this.pageData.page_type = '404' 53 } else { 54 this.pageData = await getPageData(this.ctx, pageParams) 55 } 56 } 57 58 this.pageData.page_category_id = this.pageData.category_id 59 this.pageData.url_path = url_path 60 61 if (this.pageData.page_category_id) { 62 const pageParams = { 63 language_code: this.getLanguageCode(), 64 site_id: this.ctx.state.site.site_id, 65 category_id: this.pageData.page_category_id 66 } 67 68 let categoryData = {} 69 let match_products = [] 70 const urlType = this.ctx.path.replace('.html', '').replace('/', '') 71 if ( 72 globalThis.Server.checkDesign(this.ctx) && 73 ['product-detail', 'article-detail', 'video-detail'].includes(urlType) 74 ) { 75 categoryData = localData[urlType.replace('-detail', '') + '-page-category'] 76 77 } else { 78 this.ctx.state.page = this.pageData 79 categoryData = await getCategoryData(this.ctx, pageParams) 80 if (this.pageData.page_type === 'product_detail') { 81 match_products = this.pageData.content.is_match_product? (await getProductMatchData(this.ctx, { ...pageParams, product_id: this.pageData.content.id })) : [] 82 } 83 } 84 this.pageData = setPageData(this.ctx, { ...categoryData, ...this.pageData, match_products }) 85 if (!this.ctx.query.design && this.pageData.page_type === "landing_page" && categoryData.category.ad_permissions === 3) { 86 this.ctx.state.redirect(301, '/') 87 } 88 } else { 89 this.pageData = setPageData(this.ctx, this.pageData) 90 } 91 92 if (this.pageData.page_type === '404' && this.ctx.state.site.redirect_mode === 1) { 93 if (this.ctx.query.force && this.ctx.query.force === 'html') { 94 this.pageData.page_type = '301' 95 } else { 96 this.ctx.state.redirect(301, '/') 97 } 98 } 99 100 this.pageData.children = [] 101 if (this.pageData.parents.length > 1) { 102 let pData = this.pageData.parents[1] 103 if (pData.id) this.pageData.children = [this.ctx.state.site.nav.find(p => p.id === pData.id)] 104 } 105 106 // 页é¢H1æ ç¾ç»è®¡ 107 this.pageData.h1_counter = 0 108 109 // allowAnimat 110 this.pageData.allowAnimat = checkAnimat(this.pageData.page_type) 111 112 // 伿 å·è¯¦æ id 113 if (!this.pageData.content_id) this.pageData.content_id = getPageId(this.ctx.path) 114 115 // å页 116 if (!this.pageData.page_number || this.pageData.page_number == 1) this.pageData.page_number = getPageNumber(this.ctx.path) 117 else if (this.pageData.page_number) this.pageData.page_number = parseInt(this.pageData.page_number) 118 119 // åå§è·ååæ é¾æ¥æ°æ® 120 await this.initPartnerLink() 121 // åå§è·åææ¡£é¡µé¢ç±»åæ°æ® 122 await this.initDocument() 123 124 // åå§è·åæ¥æ¾åè¡¨é¡µé¢æ°æ® 125 await this.initPageListData() 126 127 // æ£æ¥ç«ç¹TDK 128 this.checkTDK() 129 // ç«ç¹å°å¾ä¸ï¼è¯·æ±ç¸å ³æ°æ® 130 if (['sitemap', 'sitemap_articles', 'sitemap_products', 'sitemap_videos', 'sitemap_derivative_products', 'sitemap_blogs', 'sitemap_topics_blogs', 'sitemap_tags', 'sitemap_faq'].includes(this.pageData.page_type)) { 131 if (this.ctx.state.remote_server){ 132 this.pageData.page_type = '404' 133 } else { 134 await this.checkSiteMap() 135 } 136 } 137 this.initCanonicalHref() 138 this.initDetailsImg() 139 // this.initOgImage() 140 this.initDetailCssMode() 141 // this.pruneDetailHidesHtml() 142 return this.pageData 143 } 144 145 /** 146 * æ¸ çä¸ç«¯éèç详æ html 147 */ 148 pruneDetailHidesHtml() { 149 if (globalThis.Server.checkDesign(this.ctx)) { 150 return; 151 } 152 const pageTypes = [ 153 'product_detail', 'ai_product_detail', 'article_detail', 'video_detail' 154 ]; 155 const that = this 156 if (pageTypes.includes(this.pageData.page_type)) { 157 /** 158 * @type {[{detail: [{description: *}]}]|*} 159 */ 160 const arr = this.pageData.detail_description 161 if (Array.isArray(arr)) { 162 arr.forEach((sub, i) => { 163 const subArr = sub.detail 164 if (Array.isArray(subArr)) { 165 subArr.forEach((item, j) => { 166 if (item.description && typeof item.description === 'string') { 167 that.pageData.detail_description[i].detail[j].description = pruneHiddenHtml(item.description); 168 } 169 }) 170 } 171 }) 172 } 173 } 174 } 175 getLanguageCode() { 176 let languageCode = this.ctx.state.site.language_code 177 if (globalThis.Server.checkDesign(this.ctx)) { 178 const queryLanguageCode = globalThis.window.location.search.match(new RegExp("(\\?|&)language_code=([^&]*)(&|$)")) || [] 179 languageCode = queryLanguageCode[2] || languageCode 180 } 181 return languageCode 182 } 183 initDetailCssMode() { 184 this.pageData.detailCssMode = []; 185 if (this.pageData.page_type === 'product_detail' || this.pageData.page_type === 'ai_product_detail' || this.pageData.page_type === 'article_detail' || this.pageData.page_type === 'video_detail') { 186 if (this.pageData.page_type === 'article_detail' || this.pageData.page_type === 'video_detail') { 187 this.pageData.detailCssMode.push(this.pageData.edit_mode || 1) 188 } else { 189 this.pageData.detail_description.forEach(item => { 190 item.detail.forEach(text => { 191 this.pageData.detailCssMode.push(text.edit_mode || 1) 192 }) 193 }) 194 } 195 } else if (checkDetail(this.pageData.page_type)) { 196 this.pageData.detailCssMode.push(2) 197 } 198 if (globalThis.Server.checkDesign(this.ctx) && this.pageData.detailCssMode[0]) { // è£ ä¿®æ¶ï¼è¯¦æ 页å è½½å¯è§åæ ·å¼ 199 // è£ ä¿®æ¨¡å¼ä¸å®¢æ·ç«¯èµå¼ 200 let cssHref = '' 201 if (this.pageData.detailCssMode[0] === 1) { 202 cssHref = '//' + window.serverInfo.editorDomain + '/cloud-editor-responsive-out.css?v=4' 203 } else if (this.pageData.detailCssMode[0] === 2) { 204 if (typeof this.pageData.detail_css_name === 'string' && this.pageData.detail_css_name.length) { 205 cssHref = `/style/detail.css?unit=detail,${this.pageData.detail_css_name}` 206 } 207 } 208 document.querySelector('[style-mode="editor"]').setAttribute('href', cssHref) 209 } 210 } 211 /** æ´çåºè¯¦æ ä¸çimgï¼å¹¶ç»æ²¡æaltçå ä¸alt */ 212 initDetailsImg() { 213 this.detail_images = [] 214 // éå产åä¸»å¾ 215 this.pageData.album_list.forEach(item => { 216 this.detail_images.push(item.img) 217 item.alt = `${this.pageData.detail_title_text} ${this.detail_images.length}` 218 }) 219 // éåhtmlä¸çå¾ç 220 this.pageData.detail_description.forEach(item => { 221 item.detail.forEach(text => { 222 text.description = text.description.replace(/<img.*?src=\"(.*?)\".*?>/g, (match, p1) => { 223 this.detail_images.push(p1) 224 if (match.indexOf(' alt=') > 0) { 225 if (/alt=("|')\s*("|')/.test(match)) { //å¦æä¸ºç©ºï¼ä½¿ç¨æ é¢ 226 let matchUrl = `${match.slice(0, 4)} ${match.slice(4)}` 227 matchUrl = matchUrl.replace(/alt=("|')\s*("|')/, `alt="${this.pageData.detail_title_text} ${this.detail_images.length}"`) 228 return matchUrl 229 } else { //æè 使ç¨èªå¸¦çalt 230 return match 231 } 232 } else { 233 return `${match.slice(0, 4)} alt="${this.pageData.detail_title_text} ${this.detail_images.length}"${match.slice(4)}` 234 } 235 }) 236 }) 237 }) 238 } 239 initOgImage() { 240 if (this.pageData.album_list && this.pageData.album_list[0] && this.pageData.album_list[0].img) { 241 this.pageData.og_image = this.pageData.album_list[0].img 242 } else if (this.detail_images.length > 0) { 243 this.pageData.og_image = this.detail_images[0] 244 } else { 245 this.pageData.og_image = this.ctx.state.site.logo_url 246 } 247 } 248 initCanonicalHref() { 249 if (!this.ctx.query.design) { 250 this.pageData.canonical_href = this.ctx.state.site.language_list 251 .find(p => p.code === this.ctx.state.site.language_code).href || 252 `${this.ctx.state.site.protocol_domain}${calcPathName(this.ctx.path)}` 253 } 254 } 255 /**
256 * 妿æ¯é¦é¡µï¼TDK设置为ç«ç¹çTDK 257 */ 258 checkTDK() { 259 if (this.pageData.page_type === 'index') { 260 this.pageData.meta_keywords = this.ctx.state.site.meta_keywords 261 this.pageData.meta_description = this.ctx.state.site.meta_description 262 this.pageData.meta_title = this.ctx.state.site.meta_title 263 } else if (this.pageData.page_type === 'product_lives') { 264 this.pageData.meta_keywords = this.ctx.state.site.main_products 265 this.pageData.meta_description = this.ctx.state.site.company_name + ' ' + this.ctx.state.$t('Video Lists') 266 this.pageData.meta_title = this.ctx.state.site.company_name + ' ' + this.ctx.state.$t('Video Lists') 267 } 268 } 269 /** 270 * 妿æ¯ç«ç¹å°å¾ï¼è¯·æ±ç¸å ³æ°æ® 271 */ 272 async checkSiteMap() { 273 // ä¿®æ¹--ä¸sitemapç¸å ³ç页颿°æ® 274 this.pageData.sitemap = {} 275 const prefix = this.ctx.state.site.lang_prefix 276 277 // æ ¹æ®è·¯ç±åæ°è·åå½åé¡µæ° 278 this.pageData.page_number = 1 279 if (/_list/.test(this.ctx.path)) { 280 let num = this.ctx.path.split('_list')[1] 281 if (Number(num.split('.')[0])) this.pageData.page_number = Number(num.split('.')[0]) 282 } 283 // 以䏿¥å£åºç¡åæ° 284 const base_params = { 285 language_code: this.ctx.state.site.language_code, 286 site_id: this.ctx.state.site.site_id, 287 page_size: 1000, 288 page_number: this.pageData.page_number 289 } 290 291 let res = { list: [] } 292 if ('sitemap' === this.pageData.page_type) { 293 // è·åæ ç®æ°æ® 294 res.product_category = await getPageCategoryList(this.ctx, { 295 language_code: this.ctx.state.site.language_code, 296 site_id: this.ctx.state.site.site_id, 297 relate_type: 2, 298 open_type: '1,2', 299 jump_url: '' 300 }) 301 res.other_category = await getPageCategoryList(this.ctx, { 302 language_code: this.ctx.state.site.language_code, 303 site_id: this.ctx.state.site.site_id, 304 relate_type: '3,6,7,13,14,100,101', 305 open_type: '1,2', 306 jump_url: '' 307 }) 308 this.pageData.page_title = this.ctx.state.$t('sitemap') 309 310 } else if ('sitemap_articles' === this.pageData.page_type) { 311 res = await getArticleListPageBySearch(this.ctx, { 312 ...base_params, 313 status: 1, 314 show_status: 1, 315 content_type: 3 316 }) 317 this.pageData.page_title = this.ctx.state.$t('Articles Sitemap') 318 319 } else if ('sitemap_products' === this.pageData.page_type) { 320 res = await getProductListPageBySearch(this.ctx, { 321 ...base_params, 322 status: 1, 323 show_status: 1, 324 content_type: 2, 325 columns: 'title' 326 }) 327 this.pageData.page_title = this.ctx.state.$t('Products Sitemap') 328 329 } else if ('sitemap_videos' === this.pageData.page_type) { 330 res = await getVideoListPageBySearch(this.ctx, { 331 ...base_params, 332 status: 1, 333 show_status: 1 334 }) 335 this.pageData.page_title = this.ctx.state.$t('Videos Sitemap') 336 337 } else if ('sitemap_derivative_products' === this.pageData.page_type) { 338 res = await getProductListPageBySearch(this.ctx, { 339 ...base_params, 340 content_type: 4, 341 columns: 'title', 342 show_status: 1 343 }) 344 this.pageData.page_title = this.ctx.state.$t('Derivative Products Sitemap') 345 346 } else if ('sitemap_blogs' === this.pageData.page_type) { 347 res = await getArticleListPageBySearch(this.ctx, { 348 ...base_params, 349 content_type: 5, 350 show_status: 1 351 }) 352 this.pageData.page_title = this.ctx.state.$t('Derivative Blogs Sitemap') 353 354 } else if ('sitemap_topics_blogs' === this.pageData.page_type) { 355 res = await getPolymerizeList(this.ctx, { 356 ...base_params, 357 show_time_status: 2, 358 show_status: 1 359 }) 360 this.pageData.page_title = this.ctx.state.$t('Topics Blogs Sitemap') 361 } else if ('sitemap_tags' === this.pageData.page_type) { 362 res = await getSitemapTagsList(this.ctx, base_params) 363 this.pageData.page_title = this.ctx.state.$t('Tags Sitemap') 364 } else if ('sitemap_faq' === this.pageData.page_type) { 365 res = await getFAQListPageBySearch(this.ctx, { 366 ...base_params, 367 show_status: 1 368 }) 369 this.pageData.page_title = this.ctx.state.$t('Faq Sitemap') 370 } 371 372 373 374 if ('sitemap' !== this.pageData.page_type) { 375 this.pageData.page_count = res.page_count 376 this.pageData.page_total = res.total 377 this.pageData.page_size = base_params.page_size 378 } 379 this.pageData.meta_title = this.pageData.page_title + ' - ' + (this.ctx.state.site.company_brand_name || this.ctx.state.site.company_name_short || this.ctx.state.site.company_name) 380 this.pageData.meta_keywords = this.pageData.meta_title 381 this.pageData.meta_description = this.pageData.meta_title 382 this.pageData.page_base_url = `${prefix === '/' ? '' : prefix}/` + this.pageData.page_type 383 // é¢å å±é¨å 384 this.pageData.parents = [ 385 { href: '/', title: this.ctx.state.site.company_brand_name || this.ctx.state.site.company_name_short || this.ctx.state.site.company_name || this.ctx.state.$t('home') }, 386 { href: '', title: this.pageData.page_title } 387 ] 388 389 res.count = await getContentCounts(this.ctx, { 390 site_id: this.ctx.state.site.site_id 391 }) 392 this.pageData.sitemap = res 393 } 394 395 /** 396 * è·ååæ é¾æ¥ 397 */
398 async initPartnerLink() { 399 const content = await getPartnerLink(this.ctx, { site_id: this.ctx.state.site.site_id, url_path: this.pageData.page_url }) 400 let page_id = this.pageData.page_id || 0 401 this.pageData.partner_link = [] 402 if (page_id || (!page_id && this.pageData.page_url === '/')) { 403 if (content.hasOwnProperty(page_id)) { 404 this.pageData.partner_link = content[page_id] 405 } 406 } 407 } 408 409 /** 410 * åå§åææ¡£ç±»åé¡µé¢ 411 */ 412 async initDocument() { 413 //åå¨ææ¡£é¡µé¢ç±»åéé¢ï¼éç§ privacy_policy æ¡æ¬¾ terms_and_conditions 414 let page_url = '' 415 if (this.pageData.page_type === 'doc_privacy_policy') { 416 page_url = 'privacy_policy' 417 } else if (this.pageData.page_type === 'doc_terms_and_conditions') { 418 page_url = 'terms_and_conditions' 419 } 420 if (page_url) { 421 // æ ¹æ®å¼value为页é¢ç±»å廿¥æ¾ä¿¡æ¯ 422 const content = await getDocumentPage(this.ctx, { site_id: this.ctx.state.site.site_id, page_url }) 423 if (!content || !content.status) { 424 this.pageData.page_type = '404' 425 } else { 426 if (page_url === 'privacy_policy') { 427 content.title = content.title || 'Privacy Policy' 428 } 429 this.pageData.meta_title = content.title 430 this.pageData.page_title = content.title 431 this.pageData.detail_title = content.title 432 this.pageData.detail_summary = content.description 433 } 434 } 435 } 436 437 /** å¤çç³»ç»åè¡¨é¡µæ°æ®åå页 */ 438 initPageListData() { 439 switch (this.pageData.page_type) { 440 case 'product_list': 441 // æ´å¤çé¨äº§å 442 if (this.ctx.state.site.template_type === 'b2b') return 443 return this.initPageListDataBySearch({ sort: this.pageData.page_sort_type }) 444 case 'more_best_selle': 445 // æ´å¤çå产å 446 return this.initPageListDataBySearch({ is_hot: 1 }) 447 case 'more_new_products': 448 // æ´å¤ææ°äº§å 449 return this.initPageListDataBySearch({ is_new: 1 }) 450 case 'more_recommend': 451 // æ´å¤æ¨è产å 452 return this.initPageListDataBySearch({ is_recommend: 1 }) 453 case 'coupon_detail': 454 // 伿 å·å¯ç¨åå 455 return this.initPageListDataBySearch({ coupon_ids: `${this.pageData.content_id}` }) 456 case 'reduction_detail': 457 // 满å产å 458 return this.initPageListDataBySearch({ reduction_ids: `${this.pageData.content_id}` }) 459 // case 'faq_list': 460 // // faqå表页 461 // return this.initPageListForFAQ() 462 } 463 } 464 /** è·ååè¡¨é¡µæ°æ®-Search */ 465 async initPageListDataBySearch(params = {}) { 466 params.language_code = this.ctx.state.site.language_code 467 params.site_id = this.ctx.state.site.site_id 468 params.page_number = this.pageData.page_number 469 params.page_size = this.pageData.page_size <= 0 ? 12 : this.pageData.page_size 470 params.columns = 'title,summary,subtitle' + (this.ctx.state.site.is_shop ? ',price,discount,reduction' : '') 471 if (this.pageData.page_category_id) params.page_category_id = this.pageData.page_category_id 472 if (globalThis.Server.checkDesign(this.ctx)) { 473 const queryLanguageCode = globalThis.window.location.search.match(new RegExp("(\\?|&)language_code=([^&]*)(&|$)")) || [] 474 params.language_code = queryLanguageCode[2] || params.language_code 475 } 476 const res = await getProductListPageBySearch(this.ctx, params) 477 478 this.setPageListData({ 479 list: new globalThis.Server.ContentList().product(res.list), 480 page_count: res.page_number > res.page_count ? 0 : res.page_count, 481 page_base_url: getBasePagePath(this.ctx.path), 482 page_number: res.page_number, 483 page_total: res.total 484 }) 485 } 486 /* è·åfaqåè¡¨é¡µæ°æ® */ 487 async initPageListForFAQ(params = {}) { 488 params = { 489 language_code: this.ctx.state.site.language_code, 490 site_id: this.ctx.state.site.site_id, 491 page_number: this.pageData.page_number, 492 page_size: this.pageData.page_size <= 0 ? 12 : this.pageData.page_size, 493 ...params 494 } 495 const res = await getFAQListPageBySearch(this.ctx, params) 496 497 this.setPageListData({ 498 list: new globalThis.Server.ContentList().default(res.list), 499 page_count: res.page_number > res.page_count ? 0 : res.page_count, 500 page_base_url: getBasePagePath(this.ctx.path), 501 page_number: res.page_number, 502 page_total: res.total 503 }) 504 } 505 /** 设置åè¡¨é¡µæ°æ® */ 506 setPageListData({ list, page_count, page_base_url, page_number, page_size, page_total }) { 507 this.pageData.list = list || this.pageData.list 508 this.pageData.page_count = page_count || this.pageData.page_count 509 this.pageData.page_base_url = page_base_url || this.pageData.page_base_url 510 //å ä¸å°è¯ç§åç¼ 511 this.pageData.page_number = page_number || this.pageData.page_number 512 this.pageData.page_size = page_size || this.pageData.page_size 513 this.pageData.page_total = page_total || this.pageData.page_total 514 } 515 516 /** å便¨¡å¼ */ 517 static getInstance() { 518 if (!this.instance) return this.instance = new Page() 519 return this.instance 520 } 521} 522 523export default Page
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.