1<!doctype html> 2<html lang="zh-CN" data-v10-runtime-source="nuxt-v10-runtime:archive-full-page:categories:news" data-v10-runtime-fetched-at="2026-10-02T06:04:32.299Z" data-v10-posts-cache-status="fresh" data-content-surface="taxonomy" data-content-source="https://dashboard.gooood.cn/wp-json/wp/v2/posts?categories=36119" data-content-cache-status="refreshed" data-content-source-fetched-at="2026-10-02T06:04:36.660Z" data-content-served-at="2026-10-02T06:04:36.660Z" data-content-fingerprint="8f60dfacbc872470" data-content-degraded-sources=""> 3<head>
3<script type="module" src="/assets/navigation/20260914/navigation.mjs" data-gooood-managed-navigation="1"></script>
3<base href="/candidates/v10-home-20260709/"> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1"><link rel="dns-prefetch" href="https://oss.gooood.cn"><link rel="preconnect" href="https://oss.gooood.cn"><link rel="preload" as="image" href="https://oss.gooood.cn/uploads/2026/09/library-%E6%8B%B7%E8%B4%9Dppt.jpg" media="(min-width: 768px)" fetchpriority="high"><link rel="preload" as="image" href="https://oss.gooood.cn/uploads/2026/09/library-%E6%8B%B7%E8%B4%9Dppt-768x230.jpg" media="(max-width: 767px)" fetchpriority="high"><link rel="preload" as="image" href="https://oss.gooood.cn/uploads/2026/09/%E5%B0%81%E9%9D%A2%E7%94%A8-472x303.png" imagesrcset="https://oss.gooood.cn/uploads/2026/09/%E5%B0%81%E9%9D%A2%E7%94%A8-472x303.png 472w, https://oss.gooood.cn/uploads/2026/09/%E5%B0%81%E9%9D%A2%E7%94%A8-650x417.png 650w" imagesizes="(max-width: 767px) calc(100vw - 52px), 472px" media="(max-width: 767px)" fetchpriority="high">
5<script data-gooood-v10-analytics>(function(){ 6 var id="G-CH5FSBW2P3"; 7 var production=location.hostname==='www.gooood.cn'||location.hostname==='gooood.cn'; 8 var debug=false; 9 try{debug=localStorage.getItem('gooood:analytics:debug')==='1';}catch(e){} 10 if(!production&&!debug){window.__GOOOOD_ANALYTICS_STATUS__={provider:'ga4',enabled:false,measurementId:id,reason:'non-production-host'};return;} 11 window.dataLayer=window.dataLayer||[]; 12 window.gtag=window.gtag||function(){window.dataLayer.push(arguments);}; 13 if(!document.querySelector('script[data-gooood-ga4="'+id+'"]')){var s=document.createElement('script');s.async=true;s.src='https://www.googletagmanager.com/gtag/js?id='+encodeURIComponent(id);s.dataset.goooodGa4=id;document.head.appendChild(s);} 14 gtag('js',new Date());gtag('config',id,{send_page_view:false}); 15 gtag('event','page_view',{page_location:location.href,page_path:location.pathname+location.search+location.hash,page_title:document.title}); 16 window.__GOOOOD_ANALYTICS_STATUS__={provider:'ga4',enabled:true,measurementId:id,pageViewMode:'v10-full-page',rum:true,adVisibility:true}; 17 var sent={}; 18 function metric(name,value){if(sent[name]||!isFinite(value))return;sent[name]=true;gtag('event','web_vital',{metric_name:name,metric_value:Math.round(value),non_interaction:true});} 19 try{var nav=performance.getEntriesByType('navigation')[0];if(nav)metric('TTFB',nav.responseStart);}catch(e){} 20 var lcp=0,cls=0,inp=0; 21 try{new PerformanceObserver(function(list){var entries=list.getEntries();if(entries.length)lcp=entries[entries.length-1].startTime;}).observe({type:'largest-contentful-paint',buffered:true});}catch(e){} 22 try{new PerformanceObserver(function(list){list.getEntries().forEach(function(entry){if(!entry.hadRecentInput)cls+=entry.value;});}).observe({type:'layout-shift',buffered:true});}catch(e){} 23 try{new PerformanceObserver(function(list){list.getEntries().forEach(function(entry){if(entry.interactionId&&entry.duration>inp)inp=entry.duration;});}).observe({type:'event',buffered:true,durationThreshold:40});}catch(e){} 24 function flush(){metric('LCP',lcp);metric('CLS',cls*1000);metric('INP',inp);} 25 addEventListener('pagehide',flush,{once:true});document.addEventListener('visibilitychange',function(){if(document.visibilityState==='hidden')flush();}); 26 addEventListener('error',function(event){gtag('event','frontend_error',{error_type:'error',error_message:String(event.message||'unknown').slice(0,120),non_interaction:true});}); 27 addEventListener('unhandledrejection',function(event){gtag('event','frontend_error',{error_type:'unhandledrejection',error_message:String(event.reason?.message||event.reason||'unknown').slice(0,120),non_interaction:true});}); 28 function observeAds(){if(!('IntersectionObserver'in window))return;var seen=new WeakSet();var observer=new IntersectionObserver(function(entries){entries.forEach(function(entry){if(entry.isIntersecting&&entry.intersectionRatio>=.5&&!seen.has(entry.target)){seen.add(entry.target);gtag('event','ad_view',{ad_position:entry.target.getAttribute('data-ad-position')||entry.target.getAttribute('aria-label')||'unknown',non_interaction:true});observer.unobserve(entry.target);}});},{threshold:[.5]});document.querySelectorAll('[data-ad-position]').forEach(function(node){observer.observe(node);});} 29 function bindAdvertisementClicks(){if(window.__GOOOOD_AD_CLICK_COUNTER_BOUND__)return;window.__GOOOOD_AD_CLICK_COUNTER_BOUND__=true;var endpoint='https://dashboard.gooood.cn/wp-json/wp/v2/shows';window.__GOOOOD_AD_CLICK_COUNTER__={bound:true,endpoint:endpoint};document.addEventListener('click',function(event){if(event.defaultPrevented)return;var target=event.target&&event.target.closest?event.target:null;var link=target&&target.closest('a[href]');var wordlink=link&&link.closest('[data-legacy-ad-wordlink]');if(!link||(wordlink&&!wordlink.hasAttribute('data-wordlink-click-tracking')))return;var href=link.getAttribute('href')||'';if(!href||href==='#'||/^javascript:/i.test(href))return;var ad=link.closest('[data-ad-record-id],[data-ad-id]');if(!ad)return;var id=ad.getAttribute('data-ad-record-id')||ad.getAttribute('data-ad-id')||'';if(!/^[1-9]\d*$/.test(id))return;fetch(endpoint,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({post_ids:[id]}),credentials:'omit',keepalive:true,mode:'cors'}).catch(function(){});},true);} 30 bindAdvertisementClicks(); 31 if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',observeAds,{once:true});else observeAds(); 32 })();</script>
32<script data-gooood-v10-pagination-jump>(function(){ 33 document.addEventListener('submit',function(event){ 34 var form=event.target&&event.target.closest?event.target.closest('form.page-jump'):null; 35 if(!form)return; 36 event.preventDefault(); 37 var input=form.querySelector('input[type="number"]'); 38 var nav=form.closest('nav.pagination'); 39 if(!input||!nav)return; 40 var page=Math.floor(Number(input.value)); 41 var total=Math.max(1,Number(nav.dataset.totalPages||input.max||1)); 42 if(!Number.isFinite(page)||page<1||page>total){input.focus();return;} 43 var target=page===1?nav.dataset.pageOneUrl:String(nav.dataset.pageUrlTemplate||'').replace('__PAGE__',String(page)); 44 if(target)location.assign(target); 45 }); 46 })();</script>
46<script>window.__GOOOOD_V10_CRITICAL_IMAGES__={"https://oss.gooood.cn/uploads/2026/04/odd-ppt-æ·è´.jpg":"/assets/v10-lcp/carousel-d3dab1b69f.webp","https://oss.gooood.cn/uploads/2026/07/00-gooood-interview-Yang-Dingliangç坿¬_坿¬-ykt-472x303.png":"/assets/v10-lcp/article-1ff2f16a78.webp"};</script>
46 47 <title>èµè®¯ - gooood</title> 48
48<script> 49 const v10Embed = new URLSearchParams(window.location.search).get('embed'); 50 if (v10Embed === 'body' || v10Embed === 'header') { 51 document.documentElement.dataset.v10Embed = v10Embed; 52 } 53 </script>
53 54
54<script data-v10-legacy-cache-cleanup="1"> 55 (() => { 56 const legacyWorkerPath = '/dist/public/sw.js'; 57 const legacyCachePrefixes = ['cache_v1']; 58 59 window.addEventListener('pageshow', (event) => { 60 if (!event.persisted) return; 61 window.location.reload(); 62 }); 63 64 const clearLegacyHomepageCache = async () => { 65 try { 66 if ('serviceWorker' in navigator) { 67 const registrations = await navigator.serviceWorker.getRegistrations(); 68 await Promise.all(registrations.map((registration) => { 69 const worker = registration.active || registration.waiting || registration.installing; 70 const scriptUrl = worker?.scriptURL || ''; 71 return scriptUrl.endsWith(legacyWorkerPath) ? registration.unregister() : false; 72 })); 73 } 74 } catch (_) {} 75 76 try { 77 if ('caches' in window) { 78 const keys = await caches.keys(); 79 await Promise.all(keys 80 .filter((key) => legacyCachePrefixes.some((prefix) => key === prefix || key.startsWith(`${prefix}-`))) 81 .map((key) => caches.delete(key))); 82 } 83 } catch (_) {} 84 }; 85 86 void clearLegacyHomepageCache(); 87 })(); 88 </script>
88 89 <style> 90 :root { 91 --bg: #ffffff; 92 --paper: #ffffff; 93 --soft: #ffffff; 94 --ink: #080b0f; 95 --muted: #5f6f7d; 96 --meta-light: #aeb7bf; 97 --line: #d2dee8; 98 --line2: #e7edf2; 99 --accent: #006cad; 100 --blue: #075d93; 101 --deep-blue: #07324f; 102 --pale-blue: #e6f2fa; 103 --ice: #f3f8fc; 104 --steel: #8ba1b2; 105 --gap: 20px; 106 --article-column-gap: 0px; 107 --main-pad-left: 15px; 108 --main-pad-right: 15px; 109 --article-flow-max: 936px; 110 --sidebar-flow-width: 390px; 111 } 112 * { box-sizing: border-box; min-width: 0; } 113 body { 114 margin: 0; 115 background: var(--bg); 116 color: var(--ink); 117 font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif; 118 line-height: 1.52; 119 letter-spacing: 0; 120 overflow-x: hidden; 121 } 122 a { color: inherit; text-decoration: none; } 123 a:hover, 124 a:focus-visible { 125 text-decoration: underline; 126 text-decoration-thickness: 2px; 127 text-underline-offset: 4px; 128 } 129 .site img { display: block; width: 100%; height: 100%; object-fit: cover; background: #dfe6ed; } 130 .site .gooood-account-avatar { width: 32px; height: 32px; } 131 .site { 132 max-width: 1280px; 133 margin: 0 auto; 134 padding-top: 64px; 135 background: var(--paper); 136 min-height: 100vh; 137 } 138 html[data-v10-embed="body"] .site { 139 padding-top: 0; 140 } 141 html[data-v10-embed="body"] .site-header { 142 display: none; 143 } 144 html[data-v10-embed="header"], 145 html[data-v10-embed="header"] body { 146 background: transparent; 147 overflow: hidden; 148 } 149 html[data-v10-embed="header"] .site { 150 min-height: 0; 151 padding-top: 0; 152 } 153 html[data-v10-embed="header"] .site > :not(.site-header) { 154 display: none !important; 155 } 156 .site-header { 157 position: fixed; 158 top: 0; 159 left: 0; 160 right: 0; 161 z-index: 80; 162 width: 100%; 163 max-width: none; 164 margin: 0 auto; 165 background: rgba(255,255,255,.97); 166 border-bottom: 1px solid var(--line); 167 backdrop-filter: blur(10px); 168 } 169 .header-row { 170 min-height: 64px; 171 display: grid; 172 grid-template-columns: 178px minmax(0, 1fr) auto; 173 gap: 16px; 174 align-items: center; 175 width: 100%; 176 max-width: 1280px; 177 margin: 0 auto; 178 padding: 0 34px; 179 } 180 .mobile-menu-toggle, 181 .mobile-menu { 182 display: none; 183 } 184 .mobile-menu-toggle { 185 border: 0; 186 background: transparent; 187 padding: 0; 188 cursor: pointer; 189 } 190 .mobile-menu-toggle span { 191 display: block; 192 width: 22px; 193 height: 2px; 194 margin: 0 0 6px; 195 background: #333; 196 } 197 .mobile-menu-toggle span:last-child { 198 margin-bottom: 0; 199 } 200 .header-actions { 201 display: flex; 202 align-items: center; 203 justify-content: end; 204 gap: 8px; 205 color: var(--muted); 206 font-size: 14px; 207 font-weight: 400; 208 white-space: nowrap; 209 } 210 .header-actions > a, 211 .header-actions > button, 212 .action-menu > a { 213 min-height: 28px; 214 display: inline-flex; 215 align-items: center; 216 color: var(--muted); 217 } 218 .header-actions > button { 219 border: 0; 220 background: transparent; 221 font: inherit; 222 cursor: pointer; 223 padding: 0; 224 } 225 .visually-hidden { 226 position: absolute; 227 width: 1px; 228 height: 1px; 229 padding: 0; 230 margin: -1px; 231 overflow: hidden; 232 clip: rect(0, 0, 0, 0); 233 white-space: nowrap; 234 border: 0; 235 } 236 .header-search { 237 position: relative; 238 display: inline-flex; 239 align-items: center; 240 } 241 .header-search-toggle { 242 min-height: 28px; 243 display: inline-flex; 244 align-items: center; 245 gap: 6px; 246 justify-content: center; 247 border: 0; 248 background: transparent; 249 color: var(--muted); 250 font: inherit; 251 cursor: pointer; 252 padding: 0; 253 } 254 .header-search-icon { 255 width: 14px; 256 height: 14px; 257 position: relative; 258 display: inline-block; 259 box-sizing: border-box; 260 border: 2px solid currentColor; 261 border-radius: 50%; 262 } 263 .header-search-icon::after { 264 content: ""; 265 position: absolute; 266 right: -6px; 267 bottom: -4px; 268 width: 7px; 269 height: 2px; 270 background: currentColor; 271 transform: rotate(45deg); 272 transform-origin: left center; 273 } 274 .header-search-panel { 275 position: fixed; 276 inset: 0; 277 z-index: 180; 278 } 279 .header-search-panel[hidden] { 280 display: none; 281 } 282 .header-search-backdrop { 283 position: absolute; 284 inset: 0; 285 border: 0; 286 background: rgba(255,255,255,.72); 287 cursor: default; 288 } 289 .header-search-modal { 290 position: absolute; 291 top: 94px; 292 left: 50%; 293 width: min(860px, calc(100vw - 48px)); 294 transform: translateX(-50%); 295 box-sizing: border-box; 296 padding: 34px 38px 30px; 297 border: 1px solid var(--line); 298 background: rgba(255,255,255,.99); 299 box-shadow: 0 18px 48px rgba(7,50,79,.18); 300 color: var(--ink); 301 } 302 .header-search-close { 303 position: absolute; 304 top: 10px; 305 right: 14px; 306 width: 28px; 307 height: 28px; 308 border: 0; 309 background: transparent; 310 color: var(--muted); 311 font-size: 24px; 312 line-height: 1; 313 cursor: pointer; 314 } 315 .header-search-form { 316 display: flex; 317 align-items: center; 318 gap: 12px; 319 margin: 0; 320 } 321 .header-search-form input { 322 min-width: 0; 323 flex: 1 1 auto; 324 height: 48px; 325 border: 0; 326 border-bottom: 1px solid var(--line); 327 outline: none; 328 color: var(--ink); 329 font-size: 20px; 330 line-height: 48px; 331 background: transparent; 332 } 333 .header-search-form button { 334 width: 42px; 335 height: 42px; 336 display: inline-flex; 337 align-items: center; 338 justify-content: center; 339 border: 0; 340 background: transparent; 341 color: var(--muted); 342 cursor: pointer; 343 } 344 .header-search-tags { 345 margin-top: 24px; 346 padding-top: 20px; 347 border-top: 1px solid var(--line2); 348 color: var(--muted); 349 text-align: left; 350 white-space: normal; 351 } 352 .header-search-tags h2 { 353 margin: 0 0 14px; 354 color: var(--ink); 355 font-size: 16px; 356 font-weight: 400; 357 } 358 .header-search-tags .tags-group { 359 display: flex; 360 flex-wrap: wrap; 361 gap: 8px 12px; 362 align-items: center; 363 margin-top: 8px; 364 } 365 .header-search-tags .tags-group span { 366 min-width: 44px; 367 color: var(--ink); 368 font-size: 13px; 369 } 370 .header-search-tags .tags-group a { 371 color: var(--muted); 372 font-size: 13px; 373 } 374 .action-menu { 375 position: relative; 376 display: inline-flex; 377 align-items: center; 378 } 379 .action-dropdown, 380 .nav-dropdown { 381 position: absolute; 382 top: calc(100% + 12px); 383 z-index: 120; 384 min-width: 168px; 385 padding: 8px 0; 386 background: rgba(255,255,255,.98); 387 border: 1px solid var(--line); 388 box-shadow: 0 12px 28px rgba(7,50,79,.12); 389 opacity: 0; 390 visibility: hidden; 391 transform: translateY(-4px); 392 transition: opacity .16s ease, transform .16s ease, visibility .16s ease; 393 } 394 .action-dropdown { right: 0; } 395 .nav-dropdown { left: 0; } 396 .action-menu:hover .action-dropdown, 397 .action-menu:focus-within .action-dropdown, 398 .nav-item:hover .nav-dropdown, 399 .nav-item:focus-within .nav-dropdown { 400 opacity: 1; 401 visibility: visible; 402 transform: translateY(0); 403 } 404 .action-dropdown a, 405 .nav-dropdown a, 406 .action-dropdown span { 407 display: block; 408 padding: 7px 12px; 409 color: var(--ink); 410 font-size: 14px; 411 line-height: 1.35; 412 font-weight: 400; 413 text-transform: none; 414 } 415 .action-dropdown span { 416 max-width: 220px; 417 color: var(--muted); 418 white-space: normal; 419 } 420 .action-dropdown a:hover, 421 .nav-dropdown a:hover { 422 color: var(--accent); 423 background: var(--ice); 424 } 425 .header-actions .post-job { 426 min-height: 34px; 427 display: inline-flex; 428 align-items: center; 429 justify-content: center; 430 padding: 0 13px; 431 background: var(--ink); 432 color: #fff; 433 } 434 .topbar { 435 min-height: 34px; 436 display: flex; 437 align-items: center; 438 justify-content: space-between; 439 gap: 18px; 440 padding: 0 34px; 441 background: var(--deep-blue); 442 color: rgba(255,255,255,.78); 443 font-size: 12px; 444 font-weight: 760; 445 } 446 .topbar nav { display: flex; gap: 18px; flex-wrap: wrap; } 447 .masthead { 448 display: grid; 449 grid-template-columns: 196px minmax(260px, 1fr) auto; 450 gap: 24px; 451 align-items: center; 452 padding: 24px 34px 20px; 453 border-bottom: 1px solid var(--line); 454 background: 455 linear-gradient(90deg, rgba(0,108,173,.08), rgba(255,255,255,0) 34%), 456 var(--paper); 457 } 458 .logo { 459 display: block; 460 width: 176px; 461 height: 56px; 462 background: url("gooood-logo-online.jpg") left center / contain no-repeat; 463 overflow: hidden; 464 text-indent: -9999px; 465 } 466 .mast-copy { 467 max-width: 560px; 468 color: var(--muted); 469 font-size: 13px; 470 } 471 .mast-actions { 472 display: flex; 473 align-items: center; 474 gap: 10px; 475 justify-content: end; 476 } 477 .search-pill { 478 width: 190px; 479 min-height: 40px; 480 display: inline-flex; 481 align-items: center; 482 gap: 8px; 483 padding: 0 12px; 484 border: 1px solid var(--line); 485 background: #fff; 486 color: var(--muted); 487 font-size: 12px; 488 font-weight: 760; 489 white-space: nowrap; 490 } 491 .search-pill::before { 492 content: ""; 493 width: 10px; 494 height: 10px; 495 border: 2px solid var(--accent); 496 border-radius: 50%; 497 box-shadow: 6px 6px 0 -4px var(--accent); 498 } 499 .mast-button { 500 min-height: 40px; 501 display: inline-flex; 502 align-items: center; 503 justify-content: center; 504 padding: 0 16px; 505 border: 1px solid var(--ink); 506 background: var(--ink); 507 color: #fff; 508 font-size: 12px; 509 font-weight: 900; 510 white-space: nowrap; 511 } 512 .nav { 513 display: flex; 514 gap: 3px; 515 flex-wrap: nowrap; 516 align-items: center; 517 min-width: 0; 518 overflow: visible; 519 padding: 0; 520 border-bottom: 0; 521 background: transparent; 522 font-size: 14px; 523 font-weight: 400; 524 text-transform: none; 525 white-space: nowrap; 526 } 527 .nav-item { 528 position: relative; 529 flex: 0 0 auto; 530 } 531 .nav-link { 532 min-height: 36px; 533 display: inline-flex; 534 align-items: center; 535 padding: 0 5px; 536 } 537 .nav-item.has-dropdown .nav-link::after, 538 .action-menu.has-dropdown > a::after { 539 content: ""; 540 width: 0; 541 height: 0; 542 margin-left: 5px; 543 border-left: 3px solid transparent; 544 border-right: 3px solid transparent;
545 border-top: 4px solid var(--steel); 546 } 547 .nav-item:hover .nav-link, 548 .nav-item:focus-within .nav-link, 549 .header-actions a:hover, 550 .header-actions button:hover { 551 color: var(--accent); 552 } 553 .layout { 554 display: grid; 555 grid-template-columns: minmax(0, var(--article-flow-max)) var(--sidebar-flow-width); 556 align-items: start; 557 justify-content: center; 558 } 559 .main { 560 width: 100%; 561 max-width: var(--article-flow-max); 562 min-width: 0; 563 padding-bottom: 42px; 564 } 565 .side { 566 min-width: 0; 567 border-left: 1px solid var(--line2); 568 background: var(--soft); 569 width: var(--sidebar-flow-width); 570 } 571 .section-label { 572 display: grid; 573 grid-template-columns: auto minmax(30px,1fr) auto; 574 gap: 12px; 575 align-items: center; 576 padding: 26px var(--main-pad-right) 16px var(--main-pad-left); 577 color: var(--muted); 578 font-size: 12px; 579 font-weight: 950; 580 letter-spacing: .09em; 581 text-transform: uppercase; 582 } 583 .quick-board { 584 display: grid; 585 grid-template-columns: repeat(5, minmax(0, 1fr)); 586 margin: 0 var(--main-pad-right) 22px var(--main-pad-left); 587 border: 1px solid var(--line); 588 background: var(--ice); 589 } 590 .quick-card { 591 min-height: 82px; 592 display: grid; 593 align-content: center; 594 gap: 5px; 595 padding: 14px 16px; 596 border-right: 1px solid var(--line); 597 } 598 .quick-card:last-child { border-right: 0; } 599 .quick-card strong { 600 color: var(--deep-blue); 601 font-size: 15px; 602 line-height: 1.25; 603 } 604 .quick-card span { 605 color: var(--muted); 606 font-size: 11px; 607 line-height: 1.35; 608 } 609 .quick-card.primary { 610 background: var(--deep-blue); 611 color: #fff; 612 } 613 .quick-card.primary strong { color: #fff; } 614 .quick-card.primary span { color: rgba(255,255,255,.68); } 615 .section-label::before, 616 .section-label::after { 617 content: ""; 618 height: 1px; 619 background: currentColor; 620 opacity: .42; 621 } 622 .row { 623 display: grid; 624 grid-template-columns: repeat(2, minmax(0, 1fr)); 625 column-gap: var(--article-column-gap); 626 row-gap: var(--gap); 627 padding: 0 var(--main-pad-right) 42px var(--main-pad-left); 628 } 629 .article { 630 min-width: 0; 631 display: grid; 632 grid-template-rows: auto 1fr; 633 padding: 0 10px; 634 background: var(--paper); 635 } 636 .cover { 637 border: 1px solid var(--line); 638 overflow: hidden; 639 } 640 .article-cover-link { 641 display: block; 642 width: 100%; 643 height: auto; 644 text-decoration: none; 645 } 646 .article-cover-link:hover, 647 .article-cover-link:focus-visible { 648 text-decoration: none; 649 } 650 .article-cover-link:focus-visible { 651 outline: 2px solid var(--accent); 652 outline-offset: -2px; 653 } 654 .article .cover { 655 height: auto; 656 aspect-ratio: auto; 657 border: 0; 658 } 659 .article .cover img { 660 height: auto; 661 object-fit: cover; 662 } 663 .article-text { 664 height: 247px; 665 min-height: 247px; 666 display: flex; 667 flex-direction: column; 668 gap: 0; 669 padding: 15px 0 0; 670 } 671 .kicker { 672 margin: 0 0 10px; 673 color: #bbbbbb; 674 font-size: 12px; 675 line-height: 17.1428px; 676 font-weight: 400; 677 letter-spacing: 0; 678 text-transform: none; 679 } 680 h1, h2, h3, h4 { 681 margin: 0; 682 line-height: 1.18; 683 letter-spacing: 0; 684 overflow-wrap: break-word; 685 } 686 .article h3 { 687 display: -webkit-box; 688 margin: 0 0 10px; 689 max-height: 54px; 690 overflow: hidden; 691 font-size: 18px; 692 font-weight: 700; 693 line-height: 27px; 694 text-overflow: ellipsis; 695 -webkit-line-clamp: 2; 696 -webkit-box-orient: vertical; 697 } 698 .article h3 a { 699 display: block; 700 color: #4a4a4a; 701 text-decoration: none; 702 } 703 .article h3 a:hover, 704 .article h3 a:focus-visible { 705 text-decoration: underline; 706 text-decoration-thickness: 2px; 707 text-underline-offset: 4px; 708 } 709 .article-subtitle { 710 display: -webkit-box; 711 color: #666666; 712 height: 63px; 713 overflow: hidden; 714 font-size: 14px; 715 line-height: 21px; 716 font-weight: 400; 717 text-overflow: ellipsis; 718 white-space: normal; 719 -webkit-box-orient: vertical; 720 -webkit-line-clamp: 3; 721 } 722 .article-foot { 723 display: flex; 724 align-items: center; 725 justify-content: space-between; 726 gap: 10px; 727 margin-top: auto; 728 padding-top: 10px; 729 color: #bbbbbb; 730 font-size: 12px; 731 line-height: 17.1428px; 732 font-weight: 400; 733 } 734 .article-actions { 735 display: inline-flex; 736 align-items: center; 737 gap: 10px; 738 white-space: nowrap; 739 } 740 .article-actions a, 741 .article-actions button { 742 color: #bbbbbb; 743 font-weight: 400; 744 text-decoration: none; 745 } 746 .action-item { 747 display: inline-flex; 748 align-items: center; 749 gap: 3px; 750 color: #bbbbbb; 751 font: inherit; 752 cursor: pointer; 753 } 754 .share-action { 755 position: relative; 756 } 757 .share-action button { 758 display: inline-flex; 759 align-items: center; 760 gap: 3px; 761 border: 0; 762 background: transparent; 763 padding: 0; 764 font: inherit; 765 } 766 .share-action button:hover, 767 .share-action button:focus-visible { 768 text-decoration: underline; 769 text-decoration-thickness: 2px; 770 text-underline-offset: 4px; 771 } 772 .share-icons-dropdown { 773 position: absolute; 774 right: 0; 775 bottom: calc(100% + 8px); 776 z-index: 40; 777 display: flex; 778 gap: 5px; 779 padding: 7px; 780 background: rgba(255,255,255,.98); 781 border: 1px solid var(--line2); 782 box-shadow: 0 8px 20px rgba(7,50,79,.12); 783 opacity: 0; 784 visibility: hidden; 785 transform: translateY(4px); 786 transition: opacity .16s ease, transform .16s ease, visibility .16s ease; 787 } 788 .share-action:hover .share-icons-dropdown, 789 .share-action:focus-within .share-icons-dropdown { 790 opacity: 1; 791 visibility: visible; 792 transform: translateY(0); 793 } 794 .share-icons-dropdown a { 795 width: 22px; 796 height: 22px; 797 display: grid; 798 place-items: center; 799 border: 1px solid #aeb7bf; 800 color: #8d98a1; 801 font-size: 10px; 802 line-height: 1; 803 } 804 .meta { 805 color: var(--muted); 806 font-size: 11px; 807 font-weight: 750; 808 } 809 .ad-embed { 810 margin: 0 var(--main-pad-right) 30px var(--main-pad-left); 811 } 812 .ad-embed table { 813 max-width: 100% !important; 814 } 815 .ad-embed.page-bottom { 816 margin-top: 0; 817 } 818 .ad-embed.materials-ad, 819 .ad-embed.project-ad { 820 padding-bottom: 30px; 821 } 822 .ad-strip { 823 margin: 0 var(--main-pad-right) 22px var(--main-pad-left); 824 display: grid; 825 grid-template-columns: 1.1fr minmax(0, 1fr) auto; 826 gap: 16px; 827 align-items: center; 828 min-height: 76px; 829 padding: 15px 18px; 830 background: var(--pale-blue); 831 border: 1px solid #a9c6da; 832 color: var(--deep-blue); 833 } 834 .ad-strip.dark { 835 background: var(--blue); 836 border-color: #486b80; 837 color: #fff; 838 } 839 .ad-strip.green { 840 background: var(--deep-blue); 841 border-color: #355971; 842 color: #fff; 843 } 844 .top-slider { 845 position: relative; 846 margin: 0 var(--main-pad-right) 22px var(--main-pad-left); 847 aspect-ratio: 2000 / 600; 848 overflow: hidden; 849 border: 1px solid #a9c6da; 850 background: var(--deep-blue); 851 } 852 .top-slider .slide { 853 position: absolute; 854 inset: 0; 855 opacity: 0; 856 pointer-events: none; 857 transition: opacity .25s ease; 858 } 859 .top-slider .slide.is-active { 860 opacity: 1; 861 pointer-events: auto; 862 } 863 .top-slider .slide-link { 864 display: block; 865 width: 100%; 866 height: 100%; 867 text-decoration: none; 868 } 869 .top-slider .slide-link:hover, 870 .top-slider .slide-link:focus-visible { 871 text-decoration: none; 872 } 873 .top-slider img { 874 width: 100%; 875 height: 100%; 876 object-fit: cover; 877 } 878 .top-slider-dots { 879 position: absolute; 880 right: 24px; 881 bottom: 24px; 882 z-index: 1; 883 display: flex; 884 gap: 7px; 885 } 886 .top-slider-dots button { 887 width: 9px; 888 height: 9px; 889 padding: 0; 890 border: 0; 891 border-radius: 999px; 892 background: rgba(255,255,255,.58); 893 cursor: pointer; 894 } 895 .top-slider-dots button.is-active { 896 width: 22px; 897 background: #fff; 898 }
899 .slider-controls { 900 position: absolute; 901 inset: 0; 902 z-index: 2; 903 display: flex; 904 align-items: center; 905 justify-content: space-between; 906 padding: 0 14px; 907 pointer-events: none; 908 } 909 .slider-btn { 910 width: 38px; 911 height: 38px; 912 display: grid; 913 place-items: center; 914 border: 1px solid rgba(255,255,255,.62); 915 background: rgba(7,50,79,.48); 916 color: #fff; 917 font-size: 24px; 918 line-height: 1; 919 cursor: pointer; 920 pointer-events: auto; 921 backdrop-filter: blur(6px); 922 } 923 .slider-btn:hover, 924 .slider-btn:focus-visible { 925 background: rgba(255,255,255,.92); 926 color: var(--deep-blue); 927 } 928 .ad-strip .ad-label { 929 color: var(--accent); 930 font-size: 10px; 931 font-weight: 950; 932 letter-spacing: .12em; 933 text-transform: uppercase; 934 } 935 .ad-strip.dark .ad-label, 936 .ad-strip.green .ad-label { color: #b8d4e8; } 937 .ad-strip h2 { 938 margin-top: 2px; 939 font-size: 20px; 940 font-weight: 950; 941 } 942 .ad-strip p { 943 margin: 0; 944 color: #4f6373; 945 font-size: 12px; 946 font-weight: 730; 947 } 948 .ad-strip.dark p, 949 .ad-strip.green p { color: rgba(255,255,255,.66); } 950 .ad-strip a { 951 padding: 9px 12px; 952 border: 1px solid currentColor; 953 font-size: 12px; 954 font-weight: 900; 955 white-space: nowrap; 956 } 957 .job-text { 958 margin: 0 var(--main-pad-right) 56px var(--main-pad-left); 959 border: 0; 960 background: #fff; 961 box-shadow: none; 962 } 963 .job-head { 964 display: flex; 965 gap: 0; 966 align-items: center; 967 padding: 10px 13px; 968 border-bottom: 0; 969 background: #fff; 970 font-size: 12px; 971 font-weight: 950; 972 } 973 .job-head .job-submit { 974 margin-left: 2ch; 975 color: var(--meta-light); 976 font-weight: 400; 977 } 978 .job-head .job-all { 979 margin-left: auto; 980 color: var(--ink); 981 font-weight: 950; 982 } 983 .job-cols { 984 display: grid; 985 grid-template-columns: repeat(3, minmax(0, 1fr)); 986 } 987 .job-col { 988 border-right: 1px solid var(--line2); 989 } 990 .job-col:last-child { border-right: 0; } 991 .job-line { 992 display: grid; 993 grid-template-columns: minmax(0, 1fr); 994 gap: 8px; 995 padding: 7px 10px; 996 border-bottom: 1px solid var(--line2); 997 color: var(--muted); 998 font-size: 11px; 999 line-height: 1.32; 1000 } 1001 .job-line:last-child { border-bottom: 0; } 1002 .job-line:hover, 1003 .job-line:focus-visible { 1004 text-decoration: none; 1005 } 1006 .job-line b { 1007 display: block; 1008 min-width: 0; 1009 overflow: hidden; 1010 color: #4a4a4a; 1011 font-size: 11px; 1012 font-weight: 400; 1013 text-overflow: ellipsis; 1014 white-space: nowrap; 1015 } 1016 .job-line:hover b, 1017 .job-line:focus-visible b { 1018 text-decoration: underline; 1019 text-decoration-thickness: 1px; 1020 text-underline-offset: 2px; 1021 } 1022 .job-line em { display: none; } 1023 .ops { 1024 display: grid; 1025 grid-template-columns: repeat(2, minmax(0, 1fr)); 1026 gap: var(--gap); 1027 padding: 0 var(--main-pad-right) 30px var(--main-pad-left); 1028 } 1029 .panel { 1030 border: 1px solid var(--line); 1031 background: var(--paper); 1032 } 1033 .side .panel { 1034 margin-bottom: 12px; 1035 background: var(--paper); 1036 } 1037 .panel-head { 1038 display: flex; 1039 justify-content: space-between; 1040 gap: 12px; 1041 padding: 12px 14px; 1042 border-bottom: 2px solid var(--deep-blue); 1043 font-size: 13px; 1044 font-weight: 950; 1045 } 1046 .album { 1047 display: grid; 1048 grid-template-columns: 96px minmax(0, 1fr); 1049 gap: 12px; 1050 padding: 11px 13px; 1051 border-bottom: 1px solid var(--line2); 1052 } 1053 .side .album { 1054 grid-template-columns: 82px minmax(0, 1fr); 1055 gap: 10px; 1056 padding: 10px; 1057 } 1058 .side .album span { 1059 display: none; 1060 } 1061 .album:last-child { border-bottom: 0; } 1062 .album .cover { border: 0; } 1063 .album b, 1064 .hot b { 1065 display: block; 1066 font-size: 13px; 1067 line-height: 1.36; 1068 } 1069 .album span, 1070 .hot span { 1071 display: block; 1072 margin-top: 4px; 1073 color: var(--muted); 1074 font-size: 11px; 1075 } 1076 .hot { 1077 display: grid; 1078 grid-template-columns: 34px minmax(0, 1fr); 1079 gap: 10px; 1080 padding: 11px 13px; 1081 border-bottom: 1px solid var(--line2); 1082 } 1083 .side .hot { 1084 grid-template-columns: 28px minmax(0, 1fr); 1085 gap: 8px; 1086 padding: 10px; 1087 } 1088 .side .hot span { 1089 display: none; 1090 } 1091 .hot:last-child { border-bottom: 0; } 1092 .rank { 1093 color: var(--accent); 1094 font: 950 20px/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; 1095 } 1096 .ops-ad { 1097 display: grid; 1098 align-content: center; 1099 gap: 10px; 1100 grid-column: 1 / -1; 1101 min-height: 96px; 1102 padding: 18px; 1103 background: var(--blue); 1104 color: white; 1105 } 1106 .ops-ad .kicker { color: #c7e3f5; } 1107 .ops-ad h3 { font-size: 23px; } 1108 .ops-ad p { margin: 0; color: rgba(255,255,255,.7); font-size: 12px; } 1109 .ops-ad a { 1110 justify-self: start; 1111 padding: 8px 10px; 1112 border: 1px solid rgba(255,255,255,.42); 1113 font-size: 12px; 1114 font-weight: 900; 1115 } 1116 .pagination { 1117 display: flex; 1118 justify-content: center; 1119 gap: 7px; 1120 flex-wrap: wrap; 1121 margin: 10px var(--main-pad-right) 0 var(--main-pad-left); 1122 padding-top: 26px; 1123 border-top: 1px solid var(--line); 1124 } 1125 .pagination a, 1126 .pagination .page-item { 1127 min-width: 40px; 1128 height: 40px; 1129 display: grid; 1130 place-items: center; 1131 border: 1px solid var(--line); 1132 font-size: 13px; 1133 font-weight: 900; 1134 } 1135 .pagination .active { background: var(--ink); color: white; } 1136 .pagination .disabled { 1137 color: #c7c7c7; 1138 background: #f8f8f8; 1139 pointer-events: none; 1140 } 1141 .pagination .dots { 1142 border-color: transparent; 1143 color: var(--muted); 1144 } 1145 .pagination .page-count { 1146 display: inline-flex; 1147 align-items: center; 1148 height: 40px; 1149 padding: 0 4px 0 10px; 1150 color: var(--muted); 1151 font-size: 12px; 1152 font-weight: 400; 1153 } 1154 .page-jump { 1155 display: inline-flex; 1156 align-items: center; 1157 gap: 5px; 1158 height: 40px; 1159 color: var(--muted); 1160 font-size: 12px; 1161 } 1162 .page-jump input { 1163 width: 54px; 1164 height: 32px; 1165 border: 1px solid var(--line); 1166 padding: 0 8px; 1167 color: var(--ink); 1168 font: inherit; 1169 font-weight: 400; 1170 text-align: center; 1171 } 1172 .page-jump button { 1173 height: 32px; 1174 border: 1px solid var(--ink); 1175 padding: 0 10px; 1176 background: #fff; 1177 color: var(--ink); 1178 font: inherit; 1179 font-size: 12px; 1180 cursor: pointer; 1181 } 1182 .page-jump button:hover { 1183 background: var(--ink); 1184 color: #fff; 1185 } 1186 .sidebar { 1187 position: sticky; 1188 top: 76px; 1189 padding: 0 20px 18px 35px; 1190 } 1191 .side-head { 1192 display: flex; 1193 justify-content: space-between; 1194 gap: 10px; 1195 align-items: center; 1196 padding: 9px 2px 11px; 1197 font-size: 13px; 1198 font-weight: 950; 1199 } 1200 .side-head a { color: var(--accent); font-size: 10px; } 1201 .side-feature { 1202 display: grid; 1203 gap: 8px; 1204 padding: 12px; 1205 margin-bottom: 10px; 1206 background: var(--deep-blue); 1207 color: #fff; 1208 border: 1px solid #174a6e; 1209 } 1210 .side-feature b { 1211 font-size: 18px; 1212 line-height: 1.15; 1213 } 1214 .side-feature span { 1215 color: rgba(255,255,255,.72); 1216 font-size: 11px; 1217 line-height: 1.42; 1218 } 1219 .side-feature a { 1220 justify-self: start; 1221 padding: 7px 9px; 1222 border: 1px solid rgba(255,255,255,.5); 1223 font-size: 11px; 1224 font-weight: 900; 1225 } 1226 .side-jobs { 1227 display: grid; 1228 grid-template-columns: repeat(2, 150px); 1229 column-gap: 35px; 1230 row-gap: 10px; 1231 } 1232 .side-section { 1233 margin-top: 12px; 1234 } 1235 .side-section:first-of-type { 1236 margin-top: 0; 1237 } 1238 .side-section-title { 1239 display: flex; 1240 align-items: center; 1241 justify-content: space-between; 1242 gap: 8px; 1243 padding: 9px 2px 10px; 1244 color: var(--ink); 1245 font-size: 13px; 1246 font-weight: 950; 1247 border-top: 2px solid var(--deep-blue); 1248 } 1249 .side-section-title .side-title-action { 1250 color: var(--ink); 1251 font-size: 13px; 1252 font-weight: 950; 1253 } 1254 .job-region-filter { 1255 margin: -4px 0 9px; 1256 padding: 0 2px 1px; 1257 color: var(--muted); 1258 font-size: 10px; 1259 font-weight: 760; 1260 line-height: 1.6; 1261 } 1262 .job-region-filter a { 1263 color: var(--accent); 1264 font-weight: 900; 1265 } 1266 .side-jobs.home-pinned { 1267 grid-template-columns: repeat(2, 150px); 1268 column-gap: 35px; 1269 row-gap: 10px; 1270 justify-content: stretch; 1271 } 1272 1273 .side-jobs.home-pinned .side-job { 1274 width: 100%; 1275 } 1276 .side-job { 1277 border: 0; 1278 background: var(--paper); 1279 overflow: hidden; 1280 transition: transform .18s ease; 1281 } 1282 .side-job:hover, 1283 .side-job:focus-visible { 1284 transform: translateY(-1px); 1285 text-decoration: none; 1286 } 1287 .side-job:hover b, 1288 .side-job:focus-visible b { 1289 text-decoration: underline; 1290 text-decoration-thickness: 1px; 1291 text-underline-offset: 2px; 1292 } 1293 .side-job .cover { 1294 width: 150px; 1295 height: 96px; 1296 aspect-ratio: auto; 1297 border: 0; 1298 } 1299 .side-job-text { 1300 padding: 6px 0 7px; 1301 } 1302 .side-job b { 1303 display: -webkit-box; 1304 min-height: 39px; 1305 overflow: hidden; 1306 color: #4a4a4a; 1307 font-size: 12px; 1308 font-weight: 400; 1309 line-height: 17px; 1310 -webkit-box-orient: vertical; 1311 -webkit-line-clamp: 3; 1312 } 1313 .side-job span { 1314 display: none; 1315 margin-top: 2px; 1316 color: var(--muted); 1317 font-size: 9px; 1318 line-height: 1.25; 1319 } 1320 .footer-nav { 1321 width: 100vw; 1322 margin-left: calc(50% - 50vw); 1323 padding: 0; 1324 background: #333333; 1325 color: rgba(255,255,255,.62); 1326 border-top: 1px solid rgba(255,255,255,.08); 1327 } 1328 .footer-nav-inner { 1329 width: min(var(--article-flow-max), calc(100vw - 32px)); 1330 display: grid; 1331 grid-template-columns: repeat(5, minmax(0, 1fr)); 1332 gap: 28px; 1333 margin-left: max(16px, calc((100vw - (var(--article-flow-max) + var(--sidebar-flow-width))) / 2)); 1334 padding: 34px 0 30px; 1335 } 1336 .footer-col h4 { 1337 margin-bottom: 13px; 1338 color: #fff; 1339 font-size: 12px; 1340 font-weight: 950; 1341 } 1342 .footer-col a, 1343 .footer-col span { 1344 display: block; 1345 margin-bottom: 7px; 1346 color: rgba(255,255,255,.58); 1347 font-size: 11px; 1348 line-height: 1.35; 1349 } 1350 .footer-social { 1351 display: flex; 1352 gap: 8px; 1353 margin-top: 2px; 1354 } 1355 .footer-social a { 1356 width: 24px; 1357 height: 24px; 1358 display: grid; 1359 place-items: center; 1360 border: 1px solid rgba(255,255,255,.28); 1361 color: rgba(255,255,255,.8); 1362 font-size: 11px; 1363 } 1364 .footer { 1365 width: 100vw; 1366 margin-left: calc(50% - 50vw); 1367 padding: 18px 34px 28px; 1368 background: #333333; 1369 color: rgba(255,255,255,.45); 1370 text-align: center; 1371 font-size: 10px; 1372 } 1373 .footer a { 1374 color: rgba(255,255,255,.6); 1375 text-decoration: none; 1376 } 1377 @media (max-width: 960px) { 1378 .layout { grid-template-columns: 1fr; } 1379 .main { max-width: none; } 1380 .side { display: none; } 1381 .sidebar { position: static; padding: 16px; } 1382 .side-jobs { grid-template-columns: repeat(3, minmax(0, 1fr)); } 1383 .masthead, .ad-strip, .ops { grid-template-columns: 1fr; } 1384 .row { grid-template-columns: repeat(2, minmax(0, 1fr)); } 1385 .quick-board { grid-template-columns: repeat(2, minmax(0, 1fr)); } 1386 .quick-card:nth-child(2) { border-right: 0; } 1387 .quick-card { border-bottom: 1px solid var(--line); } 1388 .quick-card:nth-child(3), 1389 .quick-card:nth-child(4) { border-bottom: 0; } 1390 } 1391 @media (max-width: 640px) { 1392 html, 1393 body, 1394 .site { 1395 width: 100%; 1396 max-width: 100%; 1397 overflow-x: hidden; 1398 } 1399 .layout, 1400 .main { 1401 width: 100%; 1402 max-width: 100vw; 1403 } 1404 .site { 1405 padding-top: 60px; 1406 } 1407 .topbar > span { display: none; } 1408 .topbar, .masthead { padding-left: 16px; padding-right: 16px; } 1409 .header-row { 1410 grid-template-columns: 60px minmax(0, 1fr) 60px; 1411 min-height: 60px; 1412 gap: 0; 1413 padding: 0; 1414 } 1415 .mobile-menu-toggle { 1416 grid-column: 1; 1417 display: grid; 1418 justify-self: start; 1419 align-content: center; 1420 justify-content: center; 1421 width: 60px; 1422 height: 60px; 1423 } 1424 .header-actions { 1425 grid-column: 3; 1426 display: flex; 1427 justify-content: end; 1428 } 1429 .header-actions > a, 1430 .header-actions > button, 1431 .header-actions > .action-menu, 1432 .header-actions > .header-search { 1433 display: none; 1434 } 1435 .header-actions > .action-menu:last-of-type { 1436 display: inline-flex; 1437 } 1438 .header-actions > .action-menu:last-of-type > a { 1439 position: relative; 1440 width: 60px; 1441 min-height: 60px; 1442 justify-content: center; 1443 color: #777; 1444 font-size: 14px; 1445 font-weight: 400; 1446 line-height: 1; 1447 } 1448 .header-actions > .action-menu:last-of-type > a::before { 1449 display: none; 1450 } 1451 .header-actions > .action-menu:last-of-type > a::after { 1452 display: none; 1453 } 1454 .nav { 1455 display: none; 1456 } 1457 .mobile-menu { 1458 position: fixed; 1459 top: 0; 1460 left: 0; 1461 z-index: 85; 1462 width: 240px; 1463 height: 100vh; 1464 display: block; 1465 overflow-y: auto; 1466 background: #3a3a3a; 1467 transform: translateX(-100%); 1468 transition: transform .22s ease; 1469 -webkit-overflow-scrolling: touch; 1470 } 1471 .mobile-menu.is-open { 1472 transform: translateX(0); 1473 } 1474 .mobile-search-form { 1475 width: 240px; 1476 height: 60px; 1477 display: flex; 1478 align-items: center; 1479 position: relative; 1480 padding: 10px 30px; 1481 box-sizing: border-box; 1482 } 1483 .mobile-search-form input { 1484 width: 180px; 1485 height: 40px; 1486 border: 0; 1487 border-radius: 22px; 1488 padding: 0 10px; 1489 box-sizing: border-box; 1490 color: #555; 1491 font-size: 16px; 1492 line-height: 40px; 1493 outline: none; 1494 } 1495 .mobile-search-form button { 1496 width: 37px; 1497 height: 40px; 1498 border: 0; 1499 border-radius: 0; 1500 background: transparent; 1501 color: #555; 1502 font-size: 28px; 1503 line-height: 40px; 1504 cursor: pointer; 1505 } 1506 .mobile-menu-primary { 1507 margin: 20px 0 0; 1508 padding: 0; 1509 list-style: none; 1510 } 1511 .mobile-menu a, 1512 .mobile-menu button { 1513 width: 100%; 1514 min-height: 50px; 1515 display: block; 1516 padding: 0 18px; 1517 box-sizing: border-box; 1518 border: 0; 1519 background: transparent; 1520 color: #fff; 1521 font-size: 16px; 1522 font-weight: 400; 1523 line-height: 50px; 1524 text-align: left; 1525 } 1526 .mobile-menu button { 1527 cursor: pointer; 1528 } 1529 .mobile-menu a:hover, 1530 .mobile-menu a:focus-visible, 1531 .mobile-menu button:hover, 1532 .mobile-menu button:focus-visible { 1533 color: #fff; 1534 text-decoration: none; 1535 background: #4a4a4a; 1536 } 1537 .mobile-menu .caret { 1538 display: inline-block; 1539 flex: 0 0 auto; 1540 float: none; 1541 width: 0; 1542 height: 0; 1543 margin: 0 0 0 12px;
1544 border-top: 4px solid #fff; 1545 border-right: 4px solid transparent; 1546 border-left: 4px solid transparent; 1547 } 1548 .mobile-submenu { 1549 display: none; 1550 margin: 0; 1551 padding: 0; 1552 list-style: none; 1553 background: #333; 1554 } 1555 .mobile-menu-item.is-open > .mobile-submenu { 1556 display: block; 1557 } 1558 .mobile-submenu a { 1559 min-height: 38px; 1560 padding-left: 32px; 1561 color: #d8d8d8; 1562 font-size: 13px; 1563 line-height: 38px; 1564 } 1565 .mobile-menu-tools { 1566 position: absolute; 1567 left: 0; 1568 bottom: 0; 1569 width: 240px; 1570 margin: 0; 1571 padding: 0; 1572 list-style: none; 1573 background: #333; 1574 } 1575 .mobile-menu-tools a, 1576 .mobile-menu-tools button { 1577 min-height: 72px; 1578 line-height: 50px; 1579 color: #fff; 1580 font-size: 18px; 1581 } 1582 .mobile-menu-tools a { 1583 display: flex; 1584 align-items: center; 1585 gap: 14px; 1586 } 1587 .mobile-user-icon { 1588 width: 34px; 1589 height: 34px; 1590 display: inline-flex; 1591 align-items: center; 1592 justify-content: center; 1593 border: 1px solid #fff; 1594 border-radius: 50%; 1595 font-size: 17px; 1596 line-height: 1; 1597 } 1598 .mobile-menu-backdrop { 1599 position: fixed; 1600 inset: 0; 1601 z-index: 70; 1602 width: 100vw; 1603 height: 100vh; 1604 display: none; 1605 padding: 0; 1606 border: 0; 1607 background: rgba(255,255,255,.72); 1608 } 1609 .mobile-menu-backdrop.is-open { 1610 display: block; 1611 } 1612 .mobile-menu[hidden], 1613 .mobile-menu-backdrop[hidden] { 1614 display: none; 1615 } 1616 .mobile-menu[hidden] { 1617 transform: translateX(-100%); 1618 } 1619 .mobile-menu-primary, 1620 .mobile-menu-tools { 1621 border: 0; 1622 } 1623 .mobile-menu-primary li, 1624 .mobile-menu-tools li { 1625 min-height: 50px; 1626 } 1627 .mobile-menu-primary li li { 1628 min-height: 38px; 1629 } 1630 .mobile-menu-toggle { 1631 position: relative; 1632 z-index: 90; 1633 } 1634 .mobile-menu-toggle[aria-expanded="true"] { 1635 position: fixed; 1636 top: 0; 1637 left: 240px; 1638 background: transparent; 1639 } 1640 .header-actions.menu-open { 1641 display: none; 1642 } 1643 .mobile-menu-toggle[aria-expanded="true"] span:nth-child(1) { 1644 transform: translateY(8px) rotate(45deg); 1645 } 1646 .mobile-menu-toggle[aria-expanded="true"] span:nth-child(2) { 1647 opacity: 0; 1648 } 1649 .mobile-menu-toggle[aria-expanded="true"] span:nth-child(3) { 1650 transform: translateY(-8px) rotate(-45deg); 1651 } 1652 .mobile-menu-toggle span { 1653 transition: transform .2s ease, opacity .2s ease; 1654 } 1655 .mobile-menu button.mobile-menu-parent { 1656 display: flex; 1657 align-items: center; 1658 justify-content: space-between; 1659 line-height: 1; 1660 } 1661 .mobile-menu .mobile-search-form button { 1662 position: absolute; 1663 top: 10px; 1664 right: 32px; 1665 width: 40px; 1666 height: 40px; 1667 min-height: 40px; 1668 display: flex; 1669 align-items: center; 1670 justify-content: center; 1671 padding: 0; 1672 color: #555; 1673 background: transparent; 1674 font-size: 0; 1675 line-height: 32px; 1676 text-align: center; 1677 } 1678 .mobile-menu .mobile-search-form button::before { 1679 width: 20px; 1680 height: 20px; 1681 border: 3px solid #555; 1682 border-radius: 50%; 1683 box-sizing: border-box; 1684 content: ""; 1685 position: absolute; 1686 left: 8px; 1687 top: 7px; 1688 } 1689 .mobile-menu .mobile-search-form button::after { 1690 width: 11px; 1691 height: 3px; 1692 background: #555; 1693 content: ""; 1694 position: absolute; 1695 left: 24px; 1696 top: 24px; 1697 transform: rotate(45deg); 1698 transform-origin: left center; 1699 } 1700 .masthead { 1701 grid-template-columns: 1fr; 1702 gap: 14px; 1703 align-items: start; 1704 } 1705 .logo { 1706 grid-column: 2; 1707 justify-self: center; 1708 width: 120px; 1709 height: 34px; 1710 background-position: center; 1711 } 1712 .mast-actions { justify-content: start; flex-wrap: wrap; } 1713 .search-pill { width: min(100%, 220px); } 1714 .section-label, .row { padding-left: 16px; padding-right: 16px; } 1715 .row, .job-cols { grid-template-columns: 1fr; } 1716 .job-col { border-right: 0; border-bottom: 1px solid var(--line2); } 1717 .job-text .job-col:nth-child(n+2) { display: none; } 1718 .job-col:last-child { border-bottom: 0; } 1719 .ad-strip, .top-slider, .job-text, .pagination, .quick-board, .ad-embed { margin-left: 16px; margin-right: 16px; } 1720 .ad-embed { 1721 overflow: hidden; 1722 } 1723 .ad-embed table { 1724 width: 100% !important; 1725 max-width: 100% !important; 1726 table-layout: fixed; 1727 } 1728 .ad-embed td { 1729 max-width: 100% !important; 1730 } 1731 .pagination { gap: 5px; justify-content: flex-start; } 1732 .pagination a, 1733 .pagination .page-item { min-width: 34px; height: 34px; font-size: 12px; } 1734 .pagination .page-count, 1735 .page-jump { height: 34px; } 1736 .page-jump input, 1737 .page-jump button { height: 30px; } 1738 .ops { padding-left: 16px; padding-right: 16px; } 1739 .article-text { height: auto; min-height: 128px; } 1740 .article h3 { 1741 height: auto; 1742 max-height: 46px; 1743 font-size: 16px; 1744 line-height: 1.45; 1745 } 1746 .article-subtitle { 1747 height: 63px; 1748 min-height: 63px; 1749 white-space: normal; 1750 } 1751 .article-foot { padding-top: 22px; } 1752 .mast-copy { max-width: calc(100vw - 32px);
1752 overflow-wrap: anywhere; } 1753 .ad-strip { 1754 gap: 10px; 1755 min-height: 0; 1756 padding: 12px 14px; 1757 } 1758 .ad-strip h2 { font-size: 20px; } 1759 .ad-strip a { justify-self: start; } 1760 .quick-board { grid-template-columns: 1fr; } 1761 .quick-card, 1762 .quick-card:nth-child(2) { border-right: 0; border-bottom: 1px solid var(--line); } 1763 .quick-card:last-child { border-bottom: 0; } 1764 .side-jobs { grid-template-columns: repeat(2, minmax(0, 1fr)); } 1765 .side-feature b { font-size: 17px; } 1766 .footer-nav { display: none; } 1767 .footer { 1768 padding: 16px; 1769 line-height: 1.7; 1770 } 1771 } 1772 </style><style data-gooood-home-auth-favorites>.gooood-auth-modal[hidden], .gooood-auth-toast[hidden], .gooood-auth-panel[hidden], .gooood-auth-social[hidden] { display: none !important; } 1773.gooood-auth-modal { align-items: flex-start; background: rgba(0,0,0,.38); display: flex; inset: 0; justify-content: center; padding: 90px 16px 24px; position: fixed; z-index: 12000; } 1774.gooood-auth-dialog { background: #fff; box-shadow: 0 8px 36px rgba(0,0,0,.2); max-width: 340px; padding: 30px; position: relative; width: 100%; } 1775.gooood-auth-dialog h2 { color: #222; font-size: 18px; font-weight: 400; margin: 0 0 28px; text-align: center; } 1776.gooood-auth-close { background: transparent; border: 0; color: #333; cursor: pointer; font-size: 24px; line-height: 1; opacity: .6; padding: 6px; position: absolute; right: 8px; top: 6px; } 1777.gooood-auth-field { display: block; margin: 0 0 14px; } 1778.gooood-auth-field span { display: none; } 1779.gooood-auth-field input, .gooood-auth-field select { background: #fff; border: 1px solid #dedede; border-radius: 0; box-sizing: border-box; font: inherit; height: 42px; padding: 0 11px; width: 100%; } 1780.gooood-auth-code-row { align-items: flex-start; display: grid; gap: 8px; grid-template-columns: minmax(0, 1fr) 104px; } 1781.gooood-auth-code-row .gooood-auth-field { margin-bottom: 14px; } 1782.gooood-auth-submit, .gooood-auth-wechat, .gooood-auth-code { background: #1268b3; border: 0; color: #fff; cursor: pointer; font: inherit; min-height: 42px; width: 100%; } 1783.gooood-auth-code { background: #555; font-size: 13px; white-space: nowrap; } 1784.gooood-auth-submit:disabled, .gooood-auth-wechat:disabled { cursor: progress; opacity: .65; } 1785.gooood-auth-submit:disabled, .gooood-auth-wechat:disabled, .gooood-auth-code:disabled { cursor: progress; opacity: .65; } 1786.gooood-auth-error, .gooood-auth-feedback { font-size: 13px; line-height: 1.5; margin: 0 0 14px; } 1787.gooood-auth-error { color: #b42318; } 1788.gooood-auth-feedback { color: #1268b3; } 1789.gooood-auth-hint { color: #555; font-size: 13px; line-height: 1.55; margin: 0 0 14px; } 1790.gooood-auth-method-toggle { background: transparent; border: 0; color: #1268b3; cursor: pointer; font: inherit; font-size: 13px; margin: -2px 0 14px; padding: 0; text-align: left; } 1791.gooood-auth-method-toggle:hover { text-decoration: underline; } 1792.gooood-auth-links { align-items: center; display: flex; justify-content: space-between; margin: 13px 0 0; } 1793.gooood-auth-links button { background: transparent; border: 0; color: #1268b3; cursor: pointer; font: inherit; font-size: 13px; padding: 0; text-align: left; } 1794.gooood-auth-links button + button { color: #666; text-align: right; } 1795.gooood-auth-links button:hover { text-decoration: underline; } 1796.gooood-auth-divider { align-items: center; color: #888; display: flex; font-size: 12px; gap: 12px; margin: 22px 0 16px; } 1797.gooood-auth-divider::before, .gooood-auth-divider::after { background: #e8e8e8; content: ''; flex: 1; height: 1px; } 1798.gooood-auth-wechat-mobile-guidance { background: #f5f8fa; border-left: 2px solid #9eb9cf; color: #5d6973; font-size: 13px; line-height: 1.55; margin: 0; padding: 10px 12px; } 1799.gooood-auth-toast { background: rgba(20,20,20,.92); bottom: 28px; color: #fff; font-size: 14px; left: 50%; max-width: calc(100vw - 32px); padding: 11px 18px; position: fixed; transform: translateX(-50%); z-index: 12001; } 1800.favorite-action.is-favorited { color: #1268b3 !important; } 1801.favorite-action.is-pending { opacity: .55; pointer-events: none; } 1802body.gooood-auth-open { overflow: hidden; } 1803 1804.gooood-auth-slot { align-items: center; display: inline-flex; position: relative; } 1805.gooood-auth-slot > a { align-items: center; color: var(--muted, #5f6f7d); cursor: pointer; display: inline-flex; min-height: 32px; } 1806.gooood-account { position: relative; } 1807.gooood-account-toggle { align-items: center; background: transparent; border: 0; color: #4f5c66; cursor: pointer; display: inline-flex; font: inherit; gap: 7px; justify-content: center; padding: 0; } 1808.gooood-account-avatar { 1809 background: #eef3f7; 1810 border: 1px solid rgba(0,0,0,.1); 1811 border-radius: 50%; 1812 display: block; 1813 flex: 0 0 auto; 1814 height: 32px; 1815 object-fit: cover; 1816 width: 32px; 1817} 1818.gooood-account-avatar--placeholder { 1819 background: radial-gradient(circle at 66% 34%, #f3d56b 0 12%, transparent 13%), 1820 radial-gradient(circle at 36% 38%, #78b5d8 0 18%, transparent 19%), 1821 radial-gradient(circle at 56% 68%, #66a96a 0 18%, transparent 19%), 1822 radial-gradient(circle at 70% 72%, #d06969 0 11%, transparent 12%), 1823 #eef6fc; 1824} 1825.gooood-account-name { display: none; } 1826.gooood-account-menu { 1827 background: #fff; 1828 border: 1px solid #e4e7e9; 1829 box-shadow: 0 10px 30px rgba(0,0,0,.14); 1830 display: none; 1831 min-width: 176px; 1832 padding: 7px 0; 1833 position: absolute; 1834 right: 0; 1835 top: calc(100% + 8px); 1836 z-index: 12100; 1837} 1838.gooood-account.is-open .gooood-account-menu { display: block; } 1839.gooood-account-menu a, .gooood-account-menu button { 1840 background: transparent; 1841 border: 0; 1842 box-sizing: border-box; 1843 color: #333; 1844 cursor: pointer; 1845 display: block; 1846 font: inherit; 1847 font-size: 13px; 1848 line-height: 1.4; 1849 padding: 9px 16px; 1850 text-align: left; 1851 text-decoration: none; 1852 white-space: nowrap; 1853 width: 100%; 1854} 1855.gooood-account-menu a:hover, .gooood-account-menu button:hover { background: #f4f6f7; color: #1268b3; } 1856.gooood-account-divider { border-top: 1px solid #e7e9eb; display: block; margin: 5px 0; } 1857.mobile-menu-tools [data-gooood-auth-slot="mobile"] { display: block; position: relative; } 1858.mobile-menu-tools [data-gooood-auth-slot="mobile"] > a { align-items: center; color: #fff; display: flex; gap: 4px; } 1859 1860@media (max-width: 767px) { 1861 .gooood-auth-modal { background: #fff; padding: 35px 16px 20px; } 1862 .gooood-auth-dialog { box-shadow: none; max-width: none; } 1863 .gooood-auth-code-row { grid-template-columns: minmax(0, 1fr) 96px; } 1864 .header-actions > .gooood-auth-slot { display: none !important; } 1865 .gooood-account--mobile { width: 100%; } 1866 .gooood-account--mobile .gooood-account-toggle { color: #fff; gap: 8px; justify-content: flex-start; width: 100%; } 1867 .gooood-account--mobile .gooood-account-avatar { height: 30px; width: 30px; } 1868 .gooood-account--mobile .gooood-account-name { display: inline; max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } 1869 .gooood-account--mobile .gooood-account-menu { bottom: calc(100% + 8px); left: 0; right: auto; top: auto; width: min(240px, calc(100vw - 38px)); } 1870} 1871</style><style data-gooood-home-share>body.gooood-share-open { overflow: hidden; } 1872.header-actions > [data-gooood-page-share] { display: none !important; } 1873.share-action.is-open .share-icons-dropdown, 1874[data-gooood-page-share].is-open .action-dropdown { display: block !important; opacity: 1 !important; visibility: visible !important; transform: translateY(0) !important; } 1875.gooood-share-modal[hidden], .gooood-share-toast[hidden] { display: none !important; } 1876.gooood-share-modal { position: fixed; inset: 0; z-index: 10050; display: grid; place-items: center; padding: 20px; background: rgba(3,24,39,.58); } 1877.gooood-share-dialog { position: relative; width: min(340px, calc(100vw - 40px)); padding: 30px 28px 26px; border: 1px solid #d8d8d8; background: #fff; box-shadow: 0 24px 70px rgba(0,0,0,.22); color: #222; text-align: center; } 1878.gooood-share-dialog h2 { margin: 0 0 18px; font-size: 18px; line-height: 1.4; }
1879.gooood-share-dialog canvas { display: block; width: 200px; height: 200px; margin: 0 auto; } 1880.gooood-share-qr-title { margin: 14px 0; color: #666; font-size: 12px; line-height: 1.55; } 1881.gooood-share-manual-copy { display: block; box-sizing: border-box; width: 100%; min-height: 42px; margin: 0 0 14px; padding: 8px 10px; border: 1px solid #b8c1c8; color: #333; font-size: 12px; } 1882.gooood-share-manual-copy[hidden] { display: none; } 1883.gooood-share-close { position: absolute; top: 8px; right: 10px; border: 0; background: transparent; color: #777; font-size: 26px; cursor: pointer; } 1884.gooood-share-copy { min-height: 38px; padding: 0 18px; border: 1px solid #07344f; background: #07344f; color: #fff; cursor: pointer; } 1885.gooood-share-toast { position: fixed; left: 50%; bottom: 26px; z-index: 10060; transform: translateX(-50%); padding: 10px 16px; background: #07344f; color: #fff; box-shadow: 0 10px 28px rgba(0,0,0,.18); font-size: 13px; white-space: nowrap; } 1886@media (max-width: 767px) { 1887 .v10-candidate-header .site-header, 1888 .site-header[data-v10-fragment="header"] { 1889 z-index: 10030 !important; 1890 overflow: visible !important; 1891 } 1892 .v10-candidate-header .header-row, 1893 .site-header[data-v10-fragment="header"] .header-row, 1894 .v10-candidate-header .header-actions, 1895 .site-header[data-v10-fragment="header"] .header-actions { 1896 overflow: visible !important; 1897 } 1898 .v10-candidate-header .header-actions > [data-gooood-page-share], 1899 .site-header[data-v10-fragment="header"] .header-actions > [data-gooood-page-share], 1900 .header-actions > [data-gooood-page-share] { display: none !important; } 1901 .mobile-share, 1902 .user-field > .share-action { 1903 display: none !important; 1904 } 1905 .header-actions > .gooood-auth-slot { 1906 display: none !important; 1907 } 1908 .v10-candidate-header .header-actions > .header-search, 1909 .site-header[data-v10-fragment="header"] .header-actions > .header-search, 1910 .header-actions > .header-search { 1911 display: inline-flex !important; 1912 } 1913 .header-actions > .header-search .header-search-toggle { 1914 align-items: center !important; 1915 background: #fff !important; 1916 color: #333 !important; 1917 display: inline-flex !important; 1918 font-size: 13px !important; 1919 gap: 5px !important; 1920 height: 60px !important; 1921 justify-content: center !important; 1922 min-height: 60px !important; 1923 width: 76px !important; 1924 } 1925 .header-actions > .header-search .header-search-icon, 1926 .user-field > .search-action .header-search-icon { 1927 height: 15px !important; 1928 width: 15px !important; 1929 } 1930 .header-actions > .header-search .header-search-icon::after, 1931 .user-field > .search-action .header-search-icon::after { 1932 bottom: -3px !important; 1933 right: -5px !important; 1934 width: 7px !important; 1935 } 1936 .user-field { 1937 background: #fff !important; 1938 display: flex !important; 1939 height: 60px !important; 1940 position: fixed !important; 1941 right: 0 !important; 1942 top: 0 !important; 1943 width: 76px !important; 1944 z-index: 2000 !important; 1945 } 1946 .user-field > li:not(.search-action) { 1947 display: none !important; 1948 } 1949 .user-field > .search-action { 1950 display: flex !important; 1951 height: 60px !important; 1952 width: 76px !important; 1953 } 1954 .user-field > .search-action button { 1955 align-items: center !important; 1956 display: inline-flex !important; 1957 flex-direction: row-reverse !important; 1958 font-size: 13px !important; 1959 gap: 5px !important; 1960 height: 60px !important; 1961 justify-content: center !important; 1962 padding: 0 !important; 1963 width: 76px !important; 1964 } 1965 .mobile-menu-item > a, 1966 .mobile-menu-parent, 1967 .mobile-menu-tools a, 1968 .mobile-user-links button { font-size: 16px !important; } 1969 .mobile-submenu a, 1970 .dropdown-menu a { font-size: 14px !important; line-height: 42px !important; padding-left: 46px !important; } 1971 .header-actions > [data-gooood-page-share] { 1972 position: relative; 1973 z-index: 10046; 1974 pointer-events: auto; 1975 overflow: visible; 1976 } 1977 .header-actions > [data-gooood-page-share] > a { 1978 align-items: center; 1979 display: inline-flex; 1980 justify-content: center; 1981 min-height: 60px; 1982 width: 60px; 1983 } 1984 .header-actions > [data-gooood-page-share] > a::after { display: none !important; } 1985 [data-gooood-page-share] .action-dropdown { 1986 min-width: 184px; 1987 position: fixed; 1988 right: 0; 1989 top: 60px; 1990 z-index: 10047 !important; 1991 pointer-events: auto; 1992 } 1993 [data-gooood-page-share].is-open .action-dropdown { 1994 display: block !important; 1995 opacity: 1 !important; 1996 visibility: visible !important; 1997 transform: translateY(0) !important; 1998 } 1999 [data-gooood-share="wechat"], 2000 [data-gooood-share-legacy-wechat], 2001 .share-icon.wechat, 2002 .wechat-share-wrap, 2003 .wechat-control { 2004 display: none !important; 2005 } 2006 .share-action .share-icons-dropdown { gap: 7px; padding: 9px; } 2007 .share-action .share-icons-dropdown a { width: 28px; height: 28px; } 2008 .gooood-share-dialog { padding: 28px 20px 22px; } 2009} 2010/* step-share-g3-header-search-final */ 2011@media (max-width: 991px) { 2012 .v10-candidate-header .header-actions > [data-gooood-page-share="1"], 2013 .site-header[data-v10-fragment="header"] .header-actions > [data-gooood-page-share="1"], 2014 [data-v10-fragment="header"] .header-actions > [data-gooood-page-share="1"] { 2015 display: none !important; 2016 } 2017 .v10-candidate-header .header-actions > .header-search, 2018 .site-header[data-v10-fragment="header"] .header-actions > .header-search, 2019 [data-v10-fragment="header"] .header-actions > .header-search { 2020 display: inline-flex !important; 2021 } 2022} 2023</style> 2024<style data-gooood-company-cases-top-ad-b-reservation>[data-gooood-company-cases-top-ad-b]{display:block;min-block-size:112px}@media(max-width:700px){[data-gooood-company-cases-top-ad-b]{min-block-size:301px}}</style>
2024<script data-gooood-company-cases-top-ad-b-widget data-gooood-company-cases-top-ad-b-inline>/* The single client implementation for <!-- gooood-company-cases:top-ad-b -->. */ 2025;(function (window, document) { 2026 'use strict' 2027 var markerText = 'gooood-company-cases:top-ad-b' 2028 var hostSelector = '[data-gooood-company-cases-top-ad-b]' 2029 var styleId = 'gooood-company-cases-top-ad-b-style' 2030 var css = '.gooood-company-top-ad-b__featured>a:hover,.gooood-company-top-ad-b__results a:hover{color:#fff;text-decoration-color:#fff}.gooood-company-top-ad-b__company-panel--results .gooood-company-top-ad-b__featured{display:none}.gooood-company-top-ad-b{background:#0f3d68;color:#fff;display:grid;font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",sans-serif;grid-template-columns:66% 34%;height:112px;max-width:1100px;overflow:hidden;width:100%}.gooood-company-top-ad-b--results{height:150px}.gooood-company-top-ad-b__company-panel{background:linear-gradient(100deg,#174a80,#236aaa);display:grid;grid-template-columns:56% 44%;transition:background .2s}.gooood-company-top-ad-b__company-panel:hover{background:#286fad}.gooood-company-top-ad-b__company-panel--results{display:block}.gooood-company-top-ad-b__featured{background:linear-gradient(135deg,#0f3d68,#174a80);border-right:1px solid rgba(255,255,255,.22);padding:13px 15px;transition:background .2s}.gooood-company-top-ad-b__featured:hover{background:#174a80}.gooood-company-top-ad-b__featured h2{color:#fff;font-size:13px;line-height:1.2;margin:0 0 7px}.gooood-company-top-ad-b__loading{color:#d9ebf8;font-size:11px}.gooood-company-top-ad-b__featured>a{align-items:center;color:#fff;display:grid;gap:5px;grid-template-columns:minmax(0,1.05fr) minmax(0,1.45fr);line-height:1.15;text-decoration:none}.gooood-company-top-ad-b__featured>a+a{margin-top:7px}.gooood-company-top-ad-b__featured>a:hover>b{color:#fff;text-decoration-color:#fff;text-decoration-line:underline;text-underline-offset:2px}.gooood-company-top-ad-b__featured b{display:block;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gooood-company-top-ad-b__stats{display:grid;gap:3px;grid-template-columns:1.2fr .7fr .8fr;min-width:0}.gooood-company-top-ad-b__featured small{color:#d7e9f7;display:block;font-size:9px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gooood-company-top-ad-b__featured strong{color:#fff;display:block;font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gooood-company-top-ad-b__search{padding:13px 15px}.gooood-company-top-ad-b__search form{align-items:center;display:flex;height:100%;justify-content:center;margin:0}.gooood-company-top-ad-b__field{border-bottom:1px solid rgba(255,255,255,.92);display:flex;flex-direction:column;height:37px;justify-content:flex-end;max-width:310px;width:65%}.gooood-company-top-ad-b__field span{color:#d5e6f4;font-size:10px;line-height:1;margin-bottom:2px}.gooood-company-top-ad-b__field input{background:transparent;border:0;color:#fff;font:inherit;font-size:12px;height:17px;min-width:0;outline:0;padding:0;width:100%}.gooood-company-top-ad-b__field input::-webkit-search-cancel-button{filter:invert(1)}.gooood-company-top-ad-b__search form button{background:transparent;border:0;color:#fff;cursor:pointer;font:inherit;font-size:12px;font-weight:700;margin-left:14px;padding:5px 0;transition:color .2s}.gooood-company-top-ad-b__search form button:hover{color:#d5e6f4;text-decoration:underline;text-underline-offset:3px}.gooood-company-top-ad-b__result-head{align-items:center;color:#d9ebf8;display:flex;font-size:10px;justify-content:space-between;line-height:1;margin-bottom:8px}.gooood-company-top-ad-b__result-actions{align-items:center;display:flex;gap:8px}.gooood-company-top-ad-b__result-head button{background:transparent;border:0;color:#fff;cursor:pointer;font:inherit;font-size:10px;padding:0;text-decoration:underline;text-decoration-color:#fff}.gooood-company-top-ad-b__results{display:grid;gap:5px 1px;grid-template-columns:repeat(6,minmax(0,1fr))}.gooood-company-top-ad-b__results a{color:#fff;display:block;min-width:0;padding:2px 4px;text-align:center;text-decoration:none}.gooood-company-top-ad-b__results a:hover b{color:#fff;text-decoration-color:#fff;text-decoration-line:underline;text-underline-offset:2px}.gooood-company-top-ad-b__results b,.gooood-company-top-ad-b__results small{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gooood-company-top-ad-b__results b{font-size:11px;font-weight:400}.gooood-company-top-ad-b__results small{color:#d8eaf6;font-size:10px;margin-top:2px}.gooood-company-top-ad-b__search>p{color:#d9ebf8;font-size:11px;margin:26px 0 0;text-align:center}.gooood-company-top-ad-b__actions{background:#1d5f99;display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}.gooood-company-top-ad-b__actions a{color:#fff;display:block;padding:20px 10px;text-align:center;text-decoration:none;transition:background .2s}.gooood-company-top-ad-b__actions a+a{border-left:1px solid rgba(255,255,255,.22)}.gooood-company-top-ad-b__actions a:hover{background:#174a80}.gooood-company-top-ad-b__actions b,.gooood-company-top-ad-b__actions span,.gooood-company-top-ad-b__actions i{display:block}.gooood-company-top-ad-b__actions b{font-size:18px;line-height:1.2}.gooood-company-top-ad-b__actions span{color:#dcecf8;font-size:11px;margin-top:6px}.gooood-company-top-ad-b__actions i{font-size:11px;font-style:normal;margin-top:4px}@media(max-width:700px){.gooood-company-top-ad-b{display:block;height:auto;max-width:none;overflow:visible}.gooood-company-top-ad-b__company-panel{display:block}.gooood-company-top-ad-b__featured{border-bottom:1px solid rgba(255,255,255,.22);border-right:0;min-height:119px;padding:13px 14px}.gooood-company-top-ad-b__featured h2{font-size:14px;margin-bottom:9px}.gooood-company-top-ad-b__featured>a{gap:8px;grid-template-columns:minmax(105px,1fr) minmax(0,1.55fr)}.gooood-company-top-ad-b__featured>a+a{margin-top:9px}.gooood-company-top-ad-b__featured b{font-size:13px}.gooood-company-top-ad-b__featured small{font-size:10px}.gooood-company-top-ad-b__featured strong{font-size:12px}.gooood-company-top-ad-b__search{min-height:62px;padding:11px 14px}.gooood-company-top-ad-b__search form{justify-content:center}.gooood-company-top-ad-b__field{max-width:none;width:72%}.gooood-company-top-ad-b__search form button{margin-left:13px}.gooood-company-top-ad-b__results{grid-template-columns:repeat(3,minmax(0,1fr))}.gooood-company-top-ad-b__result-head{margin-bottom:9px}.gooood-company-top-ad-b__search:has(.gooood-company-top-ad-b__results){min-height:150px}.gooood-company-top-ad-b__actions{height:76px}.gooood-company-top-ad-b__actions a{padding:15px 6px}.gooood-company-top-ad-b__actions b{font-size:16px}.gooood-company-top-ad-b__actions span{font-size:10px;margin-top:4px}.gooood-company-top-ad-b__actions i{display:none}}' 2031 2032 var priorityCss = '.gooood-company-top-ad-b{background:transparent;column-gap:4px;grid-template-columns:25% calc(75% - 4px)}.gooood-company-top-ad-b--results{height:112px}.gooood-company-top-ad-b__company-panel{grid-template-columns:50% 50%}.gooood-company-top-ad-b__company-panel--results{display:grid}.gooood-company-top-ad-b__company-panel--results .gooood-company-top-ad-b__featured{display:block}.gooood-company-top-ad-b__actions{background:#0f3d68;display:block}.gooood-company-top-ad-b__actions a:first-child{background:#0f3d68;padding:21px 10px}.gooood-company-top-ad-b__actions a:first-child:hover{background:#092844}.gooood-company-top-ad-b__featured{background:#174a80}.gooood-company-top-ad-b__featured:hover{background:#10375f}.gooood-company-top-ad-b__search{background:#1d5f99}.gooood-company-top-ad-b__search:hover{background:#174a80}.gooood-company-top-ad-b__results{grid-template-columns:repeat(3,minmax(0,1fr))}.gooood-company-top-ad-b__company-panel--results .gooood-company-top-ad-b__search{background:#1d5f99}@media(max-width:700px){.gooood-company-top-ad-b--results{height:auto}.gooood-company-top-ad-b__company-panel--results{display:block}.gooood-company-top-ad-b__company-panel--results .gooood-company-top-ad-b__featured{display:block}.gooood-company-top-ad-b__actions{height:98px;margin-bottom:6px}.gooood-company-top-ad-b__actions a:first-child{height:98px;padding:17px 8px}.gooood-company-top-ad-b__actions a:first-child b{font-size:16px}.gooood-company-top-ad-b__actions a:first-child span,.gooood-company-top-ad-b__actions a:first-child i{display:block;font-size:11px}.gooood-company-top-ad-b__actions a:first-child span{margin-top:5px}.gooood-company-top-ad-b__actions a:first-child i{margin-top:2px}}' 2033 // Window media queries do not react when this widget is placed in a narrow 2034 // article side rail on a desktop viewport. This mirrors the existing mobile 2035 // layout whenever the widget host itself is narrow. 2036 var compactCss = '.gooood-company-top-ad-b--compact{display:block;height:auto;max-width:none;overflow:visible}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__company-panel{display:block}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__featured{border-bottom:1px solid rgba(255,255,255,.22);border-right:0;min-height:119px;padding:13px 14px}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__featured h2{font-size:14px;margin-bottom:9px}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__featured>a{gap:8px;grid-template-columns:minmax(105px,1fr) minmax(0,1.55fr)}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__featured>a+a{margin-top:9px}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__featured b{font-size:13px}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__featured small{font-size:10px}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__featured strong{font-size:12px}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__search{min-height:62px;padding:11px 14px}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__search form{justify-content:center}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__field{max-width:none;width:72%}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__search form button{margin-left:13px}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__results{grid-template-columns:repeat(3,minmax(0,1fr))}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__result-head{margin-bottom:9px}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__search:has(.gooood-company-top-ad-b__results){min-height:150px}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__actions{height:98px;margin-bottom:6px}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__actions a{padding:15px 6px}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__actions b{font-size:16px}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__actions span{font-size:10px;margin-top:4px}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__actions i{display:none}.gooood-company-top-ad-b--compact.gooood-company-top-ad-b--results{height:auto}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__company-panel--results{display:block}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__company-panel--results .gooood-company-top-ad-b__featured{display:block}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__actions a:first-child{height:98px;padding:17px 8px}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__actions a:first-child b{font-size:16px}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__actions a:first-child span,.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__actions a:first-child i{display:block;font-size:11px}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__actions a:first-child span{margin-top:5px}.gooood-company-top-ad-b--compact .gooood-company-top-ad-b__actions a:first-child i{margin-top:2px}' 2037 2038 function ensureStyle () { 2039 if (document.getElementById(styleId)) return 2040 var style = document.createElement('style') 2041 style.id = styleId 2042 style.textContent = css + priorityCss + compactCss 2043 document.head.appendChild(style) 2044 } 2045 function text (value) { return String(value == null ? '' : value) } 2046 function displayName (value) { return text(value).split('|')[0].trim() || text(value) } 2047 function formatViews (value) { value = Number(value); return !isFinite(value) || value <= 0 ? 'â' : value >= 10000 ? (value / 10000).toFixed(1) + 'ä¸' : String(Math.round(value)) } 2048 function companyUrl (item) { var value = text(item && item.url); return value.indexOf('/') === 0 ? value : '/company/' } 2049 function node (name, className, value) { var element = document.createElement(name); if (className) element.className = className; if (value != null) element.textContent = text(value); return element } 2050 function link (item, compact) { 2051 var a = node('a'); a.href = companyUrl(item); a.target = '_blank'; a.rel = 'noopener noreferrer' 2052 a.appendChild(node('b', '', displayName(item && item.name))) 2053 if (compact) { a.appendChild(node('small', '', formatViews(item && item.totalViews))); return a } 2054 var stats = node('span', 'gooood-company-top-ad-b__stats'); 2055 [['ç½ç«é 读', formatViews(item && item.totalViews)], ['é¡¹ç®æ°', item && item.projectCount || 'â'], ['åé 读', Number(item && item.projectCount) > 0 ? formatViews(Number(item.totalViews) / Number(item.projectCount)) : 'â']].forEac
2055h(function (pair) { var part = node('span'), small = node('small', '', pair[0]), strong = node('strong', '', pair[1]); part.appendChild(small); part.appendChild(strong); stats.appendChild(part) }) 2056 a.appendChild(stats); return a 2057 } 2058 function request (host, query) { 2059 // This is the established public component API. Keeping the B placement 2060 // in the query lets the same widget work wherever its WordPress marker is 2061 // rendered, without adding page-specific routes. 2062 var endpoint = host.getAttribute('data-gooood-company-cases-api-endpoint') || '/api/company/embed-cases' 2063 return fetch(endpoint + '?' + query, { credentials: 'same-origin', headers: { accept: 'application/json' } }).then(function (response) { if (!response.ok) throw Error('company-top-ad HTTP ' + response.status); return response.json() }) 2064 } 2065 function syncCompactLayout (host, root) { 2066 root.classList.toggle('gooood-company-top-ad-b--compact', host.getBoundingClientRect().width <= 700) 2067 } 2068 function observeCompactLayout (host, root) { 2069 function sync () { syncCompactLayout(host, root) } 2070 sync() 2071 if (window.ResizeObserver) { 2072 var observer = new window.ResizeObserver(sync) 2073 observer.observe(host) 2074 } else window.addEventListener('resize', sync) 2075 } 2076 function mount (host) { 2077 if (host.getAttribute('data-mounted') === '1') return 2078 host.setAttribute('data-mounted', '1') 2079 var root = node('section', 'gooood-company-top-ad-b'), panel = node('section', 'gooood-company-top-ad-b__company-panel'), featured = node('section', 'gooood-company-top-ad-b__featured'), search = node('section', 'gooood-company-top-ad-b__search'), actions = node('nav', 'gooood-company-top-ad-b__actions') 2080 root.setAttribute('aria-label', '人æ°å ¬å¸éæºæ¡ä¾'); panel.setAttribute('aria-label', 'å ¬å¸æ¡ä¾'); search.setAttribute('aria-label', 'å ¬å¸æ¡ä¾æç´¢'); actions.setAttribute('aria-label', 'gooood æå¡å ¥å£') 2081 featured.appendChild(node('h2', '', '人æ°å ¬å¸éæºæ¡ä¾')); var status = node('span', 'gooood-company-top-ad-b__loading', 'æ£å¨å è½½æ¡ä¾â¦'); featured.appendChild(status) 2082 panel.appendChild(featured); panel.appendChild(search); 2083 [['æç« é¡¹ç®æ¨å¹¿', 'ä¸å½ä¸å ¨çä¼ æ', 'æ¥çæ¨å¹¿æ¹æ¡ â', 'https://www.gooood.cn/ad-article']].forEach(function (item) { var a = node('a'); a.href = item[3]; a.target = '_blank'; a.rel = 'noopener noreferrer'; a.appendChild(node('b', '', item[0])); a.appendChild(node('span', '', item[1])); a.appendChild(node('i', '', item[2])); actions.appendChild(a) }) 2084 root.appendChild(actions); root.appendChild(panel); syncCompactLayout(host, root); host.appendChild(root); observeCompactLayout(host, root) 2085 var keyword = '', page = 1, hasMore = false 2086 function form () { search.replaceChildren(); var f = node('form'), label = node('label', 'gooood-company-top-ad-b__field'), hint = node('span', '', 'è¾å ¥å ¬å¸åç§°'), input = node('input'); label.appendChild(hint); input.maxLength = 20; input.type = 'search'; input.setAttribute('aria-label', 'è¾å ¥å ¬å¸åç§°'); input.value = keyword; input.addEventListener('input', function () { keyword = input.value }); var button = node('button', '', 'æç´¢'); button.type = 'submit'; f.appendChild(label); label.appendChild(input); f.appendChild(button); f.addEventListener('submit', function (event) { event.preventDefault(); loadResults(1) }); search.appendChild(f) } 2087 function resultView (items, loading) { search.replaceChildren(); var head = node('div', 'gooood-company-top-ad-b__result-head'), label = node('span', '', loading ? 'æ£å¨æç´¢â¦' : 'æç´¢ç»æ' + (items.length ? ' · 第 ' + page + ' 页' : '')), buttons = node('span', 'gooood-company-top-ad-b__result-actions'); head.appendChild(label); if (page > 1) { var previous = node('button', '', 'ä¸ä¸é¡µ'); previous.type = 'button'; previous.addEventListener('click', function () { loadResults(page - 1) }); buttons.appendChild(previous) } if (hasMore) { var next = node('button', '', 'ä¸ä¸é¡µ'); next.type = 'button'; next.addEventListener('click', function () { loadResults(page + 1) }); buttons.appendChild(next) } var restart = node('button', '', 'éæ°æç´¢ Ã'); restart.type = 'button'; restart.addEventListener('click', function () { keyword = ''; page = 1; hasMore = false; root.classList.remove('gooood-company-top-ad-b--results'); panel.classList.remove('gooood-company-top-ad-b__company-panel--results'); form() }); buttons.appendChild(restart); head.appendChild(buttons); search.appendChild(head); if (!loading && items.length) { var results = node('div', 'gooood-company-top-ad-b__results');
2087 items.forEach(function (item) { results.appendChild(link(item, true)) }); search.appendChild(results) } else if (!loading) search.appendChild(node('p', '', 'æ²¡ææ¾å°å¹é å ¬å¸ã')) } 2088 function loadResults (targetPage) { if (!text(keyword).trim()) return; page = targetPage; hasMore = false; root.classList.add('gooood-company-top-ad-b--results'); panel.classList.add('gooood-company-top-ad-b__company-panel--results'); resultView([], true); request(host, 'q=' + encodeURIComponent(text(keyword).trim()) + '&page=' + targetPage).then(function (payload) { page = Math.max(1, Number(payload.page) || targetPage); hasMore = Boolean(payload.hasMore); resultView(Array.isArray(payload.items) ? payload.items.slice(0, 6) : [], false) }).catch(function () { resultView([], false) }) } 2089 function loadFeatured (attempt) { 2090 request(host, 'placement=top-ad-b&_=' + Date.now()).then(function (payload) { 2091 var items = Array.isArray(payload.featured) ? payload.featured.slice(0, 2) : [] 2092 if (!items.length && attempt < 3) { 2093 setTimeout(function () { loadFeatured(attempt + 1) }, 1200) 2094 return 2095 } 2096 featured.replaceChildren(node('h2', '', '人æ°å ¬å¸éæºæ¡ä¾')) 2097 items.forEach(function (item) { featured.appendChild(link(item, false)) }) 2098 if (!items.length) featured.appendChild(node('span', 'gooood-company-top-ad-b__loading', 'æ¡ä¾æ°æ®ææ¶ä¸å¯ç¨')) 2099 }).catch(function () { 2100 if (attempt < 3) { 2101 setTimeout(function () { loadFeatured(attempt + 1) }, 1200) 2102 return 2103 } 2104 status.textContent = 'æ¡ä¾æ°æ®ææ¶ä¸å¯ç¨' 2105 }) 2106 } 2107 form(); loadFeatured(0) 2108 } 2109 function mountAll (scope) { ensureStyle(); var hosts = []; if (scope && scope.nodeType === 1 && scope.matches && scope.matches(hostSelector)) hosts.push(scope); if (scope && scope.querySelectorAll) hosts = hosts.concat(Array.prototype.slice.call(scope.querySelectorAll(hostSelector))); hosts.forEach(mount) } 2110 function mountMarkers (scope) { 2111 if (!scope || !document.createTreeWalker) return 2112 var walker = document.createTreeWalker(scope, NodeFilter.SHOW_COMMENT), markers = [], current 2113 while ((current = walker.nextNode())) if (text(current.nodeValue).trim() === markerText) markers.push(current) 2114 markers.forEach(function (marker) { 2115 var host = document.createElement('div') 2116 host.setAttribute('data-gooood-company-cases-top-ad-b', '') 2117 host.setAttribute('aria-live', 'polite') 2118 marker.replaceWith(host) 2119 mount(host) 2120 }) 2121 } 2122 function scan (scope) { mountMarkers(scope); mountAll(scope) } 2123 function observeMarkers () { 2124 if (!document.body || window.__goooodCompanyCasesTopAdBObserver) return 2125 window.__goooodCompanyCasesTopAdBObserver = new MutationObserver(function (records) { 2126 records.forEach(function (record) { Array.prototype.forEach.call(record.addedNodes, function (node) { scan(node) }) }) 2127 }) 2128 window.__goooodCompanyCasesTopAdBObserver.observe(document.body, { childList: true, subtree: true }) 2129 } 2130 function start () { scan(document); observeMarkers() } 2131 window.__goooodCompanyCasesTopAdB = { mount: scan } 2132 if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start); else start() 2133})(window, document) 2134</script>
2134<style data-v10-archive-title> 2135 .v10-taxonomy-title { 2136 align-items: baseline; 2137 border-bottom: 1px solid #d8d8d8; 2138 display: flex; 2139 gap: 12px; 2140 margin: 0 10px 24px; 2141 padding-bottom: 14px; 2142 } 2143 .v10-taxonomy-title h1 { 2144 color: #111; 2145 font-size: 18px; 2146 font-weight: 700; 2147 line-height: 27px; 2148 margin: 0; 2149 } 2150 .v10-taxonomy-title span { 2151 color: #bbb; 2152 font-size: 12px; 2153 line-height: 17.1428px; 2154 } 2155 @media (max-width: 767px) { 2156 .v10-taxonomy-title { 2157 margin-left: 26px; 2158 margin-right: 26px; 2159 } 2160 } 2161 </style><meta name="description" content="gooood èµè®¯|News页é¢ï¼æ´ç建çãæ¯è§ã室å ä¸è®¾è®¡é¢åçææ°é¡¹ç®ãæç« ãæèåä¸é¢å 容ã"><meta name="robots" content="index,follow"><meta property="og:site_name" content="è°·å¾·è®¾è®¡ç½ - gooood"><meta property="og:title" content="èµè®¯ - gooood"><meta property="og:description" content="gooood èµè®¯|News页é¢ï¼æ´ç建çãæ¯è§ã室å ä¸è®¾è®¡é¢åçææ°é¡¹ç®ãæç« ãæèåä¸é¢å 容ã"><meta property="og:type" content="website"><meta property="og:url" content="https://www.gooood.cn/category/news"><link rel="canonical" href="https://www.gooood.cn/category/news"><link rel="alternate" hreflang="zh-CN" href="https://www.gooood.cn/category/news"><link rel="alternate" hreflang="en" href="https://www.gooood.cn/en/category/news"><link rel="alternate" hreflang="x-default" href="https://www.gooood.cn/category/news"><meta name="gooood-preview-route" content="v10-home-full-page"></head> 2162<body> 2163<div class="site"> 2164 <header class="site-header" data-v10-fragment="header"> 2165 <div class="header-row"> 2166 <button class="mobile-menu-toggle" type="button" aria-label="æå¼èå" aria-controls="mobile-menu" aria-expanded="false"> 2167 <span></span><span></span><span></span> 2168 </button> 2169 <a class="logo" href="/" aria-label="gooood">gooood</a> 2170 <nav class="nav" aria-label="主导èª"> 2171 <div class="nav-item"><a class="nav-link" href="/" data-zh="é¦é¡µ" data-en="Home">é¦é¡µ</a></div> 2172 <div class="nav-item has-dropdown"> 2173 <a class="nav-link" href="/category/series" data-zh="ä¸è¾" data-en="Series">ä¸è¾</a> 2174 <div class="nav-dropdown"> 2175 <a href="/category/series" data-zh="ææä¸è¾" data-en="All Series">ææä¸è¾</a> 2176 <a href="/category/series/gooood-interview" data-zh="访è°ä¸è¾" data-en="Interview">访è°ä¸è¾</a> 2177 <a href="/category/series/office-fact" data-zh="åå ¬å®¤çç¸" data-en="Office Fact">åå ¬å®¤çç¸</a> 2178 <a href="/category/series/under-35" data-zh="æªæ»¡35å²åæäººè®°å½" data-en="Under 35">æªæ»¡35å²åæäººè®°å½</a> 2179 <a href="/category/type/anniversary" data-zh="大å¨å¹´" data-en="Anniversary">大å¨å¹´</a> 2180 <a href="/category/series/everyone" data-zh="æ¯ä¸ªäºº" data-en="Everyone">æ¯ä¸ªäºº</a> 2181 <a href="/category/series/oversea" data-zh="卿µ·å¤" data-en="Oversea">卿µ·å¤</a> 2182 <a href="/category/series/topic" data-zh="æ¥å¸¸æ·±åº¦+" data-en="Topic">æ¥å¸¸æ·±åº¦+</a> 2183 <a href="/category/type/unbuilt" data-zh="æªå»ºæ" data-en="Unbuilt">æªå»ºæ</a> 2184 <a href="/category/series/material-and-detail" data-zh="ææä¸ç»é¨" data-en="Material and Detail">ææä¸ç»é¨</a> 2185 <a href="/category/series/gooood-idea" data-zh="æ³æ³ä¸è¾" data-en="gooood Idea">æ³æ³ä¸è¾</a> 2186 <a href="/category/series/ramble" data-zh="ä¿¡æ¥è¾" data-en="Ramble">ä¿¡æ¥è¾</a> 2187 <a href="/category/series/avant-garde" data-zh="å éä¸è¾" data-en="Avant-garde">å éä¸è¾</a> 2188 <a href="/category/series/we-work-for-mad" data-zh="We work for MAD" data-en="We work for MAD">We work for MAD</a> 2189 <a href="/category/series/other-series" data-zh="å ¶ä»ä¸è¾" data-en="Other Series">å ¶ä»ä¸è¾</a> 2190 </div> 2191 </div> 2192 <div class="nav-item has-dropdown"> 2193 <a class="nav-link" href="/search" data-zh="åç±»" data-en="Type">åç±»</a> 2194 <div class="nav-dropdown"> 2195 <a href="/category/type/architecture" data-zh="建ç" data-en="Architecture">建ç</a> 2196 <a href="/category/type/landscape" data-zh="æ¯è§" data-en="Landscape">æ¯è§</a> 2197 <a href="/category/type/design" data-zh="设计" data-en="Design">设计</a> 2198 <a href="/category/type/art" data-zh="èºæ¯" data-en="Art">èºæ¯</a> 2199 <a href="/category/news" data-zh="èµè®¯" data-en="News">èµè®¯</a> 2200 <a href="/category/type/archive" data-zh="åé" data-en="Archive">åé</a> 2201 <a href="/filter/type/all/country/all/material/all/office/all" data-zh="å¤åæ£ç´¢" data-en="Tag Search">å¤åæ£ç´¢</a> 2202 </div> 2203 </div> 2204 <div class="nav-item"><a class="nav-link" href="/aboutus" data-zh="å ³äºè°·å¾·" data-en="About us">å ³äºè°·å¾·</a></div> 2205 <div class="nav-item has-dropdown"> 2206 <a class="nav-link" href="/submissions" data-zh="æç¨¿ä¸æ¨å¹¿" data-en="Submissions & AD">æç¨¿ä¸æ¨å¹¿</a> 2207 <div class="nav-dropdown"> 2208 <a href="/submissions" data-zh="æç¨¿è°·å¾·" data-en="Submissions">æç¨¿è°·å¾·</a> 2209 <a href="/ad-article" data-zh="æç« æ¨å¹¿" data-en="Article AD">æç« æ¨å¹¿</a> 2210 <a href="/materials" data-zh="å»ºææ¨å¹¿" data-en="Materials">å»ºææ¨å¹¿</a> 2211 </div> 2212 </div> 2213 <div class="nav-item has-dropdown"> 2214 <a class="nav-link" href="/category/jobs" data-zh="å·¥ä½/æè" data-en="Jobs">å·¥ä½/æè</a> 2215 <div class="nav-dropdown"> 2216 <a href="/category/jobs" data-zh="ææ¯æ±èè ï¼æ¥çææå¥½å·¥ä½" data-en="All jobs">ææ¯æ±èè ï¼æ¥çææå¥½å·¥ä½</a> 2217 <a href="/job-service-info" data-zh="ææ¯é主ï¼å¦ä½åå¸å¥½å·¥ä½" data-en="Recruitment service">ææ¯é主ï¼å¦ä½åå¸å¥½å·¥ä½</a> 2218 </div> 2219 </div> 2220 <div class="nav-item has-dropdown"> 2221 <a class="nav-link" href="/find-designer" data-zh="设计å¸/æ¾é¡¹ç®" data-en="Find designers / Get Projects">设计å¸/æ¾é¡¹ç®</a> 2222 <div class="nav-dropdown"> 2223 <a href="/find-designer" data-zh="ä¸ä¸»æ¾è®¾è®¡å¸" data-en="Find designers">ä¸ä¸»æ¾è®¾è®¡å¸</a> 2224 <a href="/get-project-designer" data-zh="è®¾è®¡å¸æ¥é¡¹ç®" data-en="Get Projects">è®¾è®¡å¸æ¥é¡¹ç®</a> 2225 </div> 2226 </div> 2227 <div class="nav-item"><a class="nav-link" href="/talks" data-zh="è¯å¬ä¼å" data-en="Talks">è¯å¬ä¼å</a></div> 2228 </nav> 2229 <div class="header-actions"> 2230 <button type="button" data-lang-toggle data-zh="En" data-en="ä¸">En</button> 2231 <div class="header-search"> 2232 <button class="header-search-toggle" type="button" data-header-search-toggle aria-label="æç´¢" aria-expanded="false" aria-controls="header-search-panel"><span data-zh="æç´¢" data-en="Search">æç´¢</span><span class="header-search-icon" aria-hidden="true"></span></button> 2233 <div class="header-search-panel" id="header-search-panel" role="dialog" aria-modal="true" aria-label="æç´¢" hidden> 2234 <button class="header-search-backdrop" type="button" data-header-search-close aria-label="å ³éæç´¢"></button> 2235 <div class="header-search-modal"> 2236 <button class="header-search-close" type="button" data-header-search-close aria-label="å ³éæç´¢">Ã</button> 2237 <form class="header-search-form" role="search" action="https://www.gooood.cn/search" method="get"> 2238 <input type="search" name="q" id="search-on-modal" data-placeholder-zh="è¾å ¥å ³é®è¯è¿è¡å ¨ææç´¢" data-placeholder-en="Enter keywords" placeholder="è¾å ¥å ³é®è¯è¿è¡å ¨ææç´¢" autocomplete="off"> 2239 <button type="submit" aria-label="æç´¢"><span class="header-search-icon" aria-hidden="true"></span></button> 2240 </form> 2241 <div class="header-search-tags"> 2242 <h2 data-zh="æ¨ä¹å¯ä»¥æ ¹æ®æ ç¾è¿è¡æ£ç´¢" data-en="You can also filter post by featured tags">æ¨ä¹å¯ä»¥æ ¹æ®æ ç¾è¿è¡æ£ç´¢</h2> 2243 <div class="tags-group"><span data-zh="ç±»å" data-en="Type">ç±»å</span><a href="/category/type/architecture">Architecture</a><a href="/category/type/landscape">Landscape</a><a href="/category/type/design">Design</a><a href="/category/type/art">Art</a></div> 2244 <div class="tags-group"><span data-zh="æå¡" data-en="Service">æå¡</span><a href="/submissions">Submissions</a><a href="/ad-article">Article AD</a><a href="/job-service-info">Jobs</a></div> 2245 </div> 2246 </div> 2247 </div> 2248 </div> 2249 <div class="gooood-auth-slot" data-gooood-auth-slot="desktop"> 2250 <a data-gooood-auth-member="desktop" data-gooood-login-trigger="1" href="#login" data-zh="ä¼å/ç»å½" data-en="VIP/Login">ä¼å/ç»å½</a> 2251 </div> 2252 </div> 2253 </div> 2254 <button class="mobile-menu-backdrop" type="button" aria-label="å ³éèå" hidden></button> 2255 <div class="mobile-menu" id="mobile-menu" hidden> 2256 <form class="mobile-search-form" role="search" action="https://www.gooood.cn/search" method="get"> 2257 <input type="text" name="q" data-placeholder-zh="è¾å ¥å ³é®åæç´¢" data-placeholder-en="Enter keywords" placeholder="è¾å ¥å ³é®åæç´¢"> 2258 <button type="submit" aria-label="æç´¢">â</button> 2259 </form> 2260 <ul class="mobile-menu-primary"> 2261 <li class="mobile-menu-item"><a href="/" data-zh="é¦é¡µ" data-en="Home">é¦é¡µ</a></li> 2262 <li class="mobile-menu-item"> 2263 <button class="mobile-menu-parent" type="button"><span data-zh="ä¸è¾" data-en="Series">
2263ä¸è¾</span><span class="caret"></span></button> 2264 <ul class="mobile-submenu"> 2265 <li><a href="/category/series" data-zh="ææä¸è¾" data-en="All Series">ææä¸è¾</a></li> 2266 <li><a href="/category/series/gooood-interview" data-zh="访è°ä¸è¾" data-en="Interview">访è°ä¸è¾</a></li> 2267 <li><a href="/category/series/office-fact" data-zh="åå ¬å®¤çç¸" data-en="Office Fact">åå ¬å®¤çç¸</a></li> 2268 <li><a href="/category/series/under-35" data-zh="æªæ»¡35å²åæäººè®°å½" data-en="Under 35">æªæ»¡35å²åæäººè®°å½</a></li> 2269 <li><a href="/category/type/anniversary" data-zh="大å¨å¹´" data-en="Anniversary">大å¨å¹´</a></li> 2270 <li><a href="/category/series/everyone" data-zh="æ¯ä¸ªäºº" data-en="Everyone">æ¯ä¸ªäºº</a></li> 2271 <li><a href="/category/series/oversea" data-zh="卿µ·å¤" data-en="Oversea">卿µ·å¤</a></li> 2272 <li><a href="/category/series/topic" data-zh="æ¥å¸¸æ·±åº¦+" data-en="Topic">æ¥å¸¸æ·±åº¦+</a></li> 2273 <li><a href="/category/type/unbuilt" data-zh="æªå»ºæ" data-en="Unbuilt">æªå»ºæ</a></li> 2274 <li><a href="/category/series/material-and-detail" data-zh="ææä¸ç»é¨" data-en="Material and Detail">ææä¸ç»é¨</a></li> 2275 <li><a href="/category/series/gooood-idea" data-zh="æ³æ³ä¸è¾" data-en="gooood Idea">æ³æ³ä¸è¾</a></li> 2276 <li><a href="/category/series/ramble" data-zh="ä¿¡æ¥è¾" data-en="Ramble">ä¿¡æ¥è¾</a></li> 2277 <li><a href="/category/series/avant-garde" data-zh="å éä¸è¾" data-en="Avant-garde">å éä¸è¾</a></li> 2278 <li><a href="/category/series/we-work-for-mad" data-zh="We work for MAD" data-en="We work for MAD">We work for MAD</a></li> 2279 <li><a href="/category/series/other-series" data-zh="å ¶ä»ä¸è¾" data-en="Other Series">å ¶ä»ä¸è¾</a></li> 2280 </ul> 2281 </li> 2282 <li class="mobile-menu-item"> 2283 <button class="mobile-menu-parent" type="button"><span data-zh="åç±»" data-en="Type">åç±»</span><span class="caret"></span></button> 2284 <ul class="mobile-submenu"> 2285 <li><a href="/category/type/architecture" data-zh="建ç" data-en="Architecture">建ç</a></li> 2286 <li><a href="/category/type/landscape" data-zh="æ¯è§" data-en="Landscape">æ¯è§</a></li> 2287 <li><a href="/category/type/design" data-zh="设计" data-en="Design">设计</a></li> 2288 <li><a href="/category/type/art" data-zh="èºæ¯" data-en="Art">èºæ¯</a></li> 2289 <li><a href="/category/news" data-zh="èµè®¯" data-en="News">èµè®¯</a></li> 2290 <li><a href="/category/type/archive" data-zh="åé" data-en="Archive">åé</a></li> 2291 <li><a href="/filter/type/all/country/all/material/all/office/all" data-zh="å¤åæ£ç´¢" data-en="Tag Search">å¤åæ£ç´¢</a></li> 2292 </ul> 2293 </li> 2294 <li class="mobile-menu-item"><a href="/aboutus" data-zh="å ³äºæä»¬" data-en="About us">å ³äºæä»¬</a></li> 2295 <li class="mobile-menu-item"> 2296 <button class="mobile-menu-parent" type="button"><span data-zh="æç¨¿ä¸æ¨å¹¿" data-en="Submissions & AD">æç¨¿ä¸æ¨å¹¿</span><span class="caret"></span></button> 2297 <ul class="mobile-submenu"> 2298 <li><a href="/submissions" data-zh="å è´¹æç¨¿" data-en="Submissions">å è´¹æç¨¿</a></li> 2299 <li><a href="/ad-article" data-zh="æç« ä»è´¹æ¨å¹¿" data-en="Article AD">æç« ä»è´¹æ¨å¹¿</a></li> 2300 <li><a href="/materials" data-zh="å»ºææ¨å¹¿" data-en="Materials">å»ºææ¨å¹¿</a></li> 2301 </ul> 2302 </li> 2303 <li class="mobile-menu-item"> 2304 <button class="mobile-menu-parent" type="button"><span data-zh="å·¥ä½/æè" data-en="Jobs">å·¥ä½/æè</span><span class="caret"></span></button> 2305 <ul class="mobile-submenu"> 2306 <li><a href="/category/jobs" data-zh="ææå·¥ä½" data-en="All jobs">ææå·¥ä½</a></li> 2307 <li><a href="/job-service-info" data-zh="å叿è" data-en="Recruitment service">å叿è</a></li> 2308 </ul> 2309 </li> 2310 <li class="mobile-menu-item"> 2311 <button class="mobile-menu-parent" type="button"><span data-zh="æ¾è®¾è®¡å¸/æ¾é¡¹ç®" data-en="Find designers / Get Projects">æ¾è®¾è®¡å¸/æ¾é¡¹ç®</span><span class="caret"></span></button> 2312 <ul class="mobile-submenu"> 2313 <li><a href="/find-designer" data-zh="ä¸ä¸»æ¾è®¾è®¡å¸" data-en="Find designers">ä¸ä¸»æ¾è®¾è®¡å¸</a></li> 2314 <li><a href="/get-project-designer" data-zh="è®¾è®¡å¸æ¥é¡¹ç®" data-en="Get Projects">è®¾è®¡å¸æ¥é¡¹ç®</a></li> 2315 </ul> 2316 </li> 2317 <li class="mobile-menu-item"><a href="/talks" data-zh="è¯å¬ä¼å" data-en="Talks">è¯å¬ä¼å</a></li> 2318 <li class="mobile-menu-item"><button type="button" data-lang-toggle data-zh="En" data-en="ä¸">En</button></li> 2319 </ul> 2320 <ul class="mobile-menu-tools"> 2321 <li data-gooood-auth-slot="mobile"><a href="#login" data-gooood-auth-member="mobile" data-gooood-login-trigger="1"><span class="mobile-user-icon">â</span><span data-zh="ä¼å/ç»å½" data-en="VIP/Login">ä¼å/ç»å½</span></a></li> 2322 </ul> 2323 </div> 2324 </header>
2324<script data-gooood-v10-lang-switch-fallback>(function(){ 2325 if(window.__goooodV10LangSwitchFallback)return; 2326 window.__goooodV10LangSwitchFallback=true; 2327 function saveLanguage(value){ 2328 var parts=['language='+encodeURIComponent(value),'Path=/','SameSite=Lax','Max-Age=31536000']; 2329 if(window.location.protocol==='https:')parts.push('Secure'); 2330 if(window.location.hostname==='gooood.cn'||window.location.hostname.endsWith('.gooood.cn'))parts.push('Domain=.gooood.cn'); 2331 document.cookie=parts.join('; '); 2332 } 2333 function targetPath(path,target){ 2334 var normalized=path||'/'; 2335 var clean=normalized==='/en'||normalized==='/en/'?'/':normalized.indexOf('/en/')===0?normalized.slice(3)||'/':normalized; 2336 if(target==='zh')return clean||'/'; 2337 return clean==='/'?'/en/':'/en'+clean; 2338 } 2339 document.addEventListener('click',function(event){ 2340 var trigger=event.target&&event.target.closest&&event.target.closest('[data-lang-toggle]'); 2341 if(!trigger)return; 2342 var current=window.location.pathname==='/en'||window.location.pathname.indexOf('/en/')===0?'en':'zh'; 2343 var target=current==='en'?'zh':'en'; 2344 var url=new URL(window.location.href); 2345 url.pathname=targetPath(url.pathname,target); 2346 url.searchParams.delete('lang'); 2347 saveLanguage(target==='en'?'en_US':'zh_CN'); 2348 event.preventDefault(); 2349 event.stopImmediatePropagation(); 2350 window.location.assign(url.pathname+url.search+url.hash); 2351 },true); 2352})();</script>
2352 2353 2354 <div class="layout"> 2355 <main class="main"> 2356 <section class="top-slider" aria-label="é¦é¡µè½®æå¾å¹¿å" data-v10-fragment="carousel" data-ad-position="é¦é¡µè½®æå¾å¹¿å" data-wp-tag-id="34627" data-wp-term-slug="home_banners" data-ad-ratio="2000:600" data-ad-source="legacy-api:home_banners" data-backend-ad-position="34627" data-backend-ad-source="dashboard.api.api-advert-adposition.php?slugName=home_banners" data-backend-ad-status="connected" data-ad-item-count="6" data-ad-set-fingerprint="ea47907ae0d8dcf6" data-ad-source-fetched-at="2026-10-02T06:04:17.042Z" data-ad-cache-status="stale"> 2357 <div class="slide is-active" data-ad-record-id="1725185" data-ad-slug="library-everyone-ppt" data-ad-modified="" data-ad-title="library-everyone" data-ad-fingerprint="fc7c92366ac341aa"><a class="slide-link" href="/everyone-beijing-city-library.htm" target="_blank" rel="noopener"><picture><source media="(max-width: 767px)" srcset="https://oss.gooood.cn/uploads/2026/09/library-%E6%8B%B7%E8%B4%9Dppt-768x230.jpg"><img src="https://oss.gooood.cn/uploads/2026/09/library-%E6%8B%B7%E8%B4%9Dppt.jpg" loading="eager" fetchpriority="high" alt="library-everyone" width="2000" height="600" decoding="async"></picture></a></div> 2358 <div class="slide" data-ad-record-id="1728618" data-ad-slug="office-fact-no-64-atelier-cns-ppt" data-ad-modified="" data-ad-title="OFFICE FACT NO.64 - Atelier cnS-ppt" data-ad-fingerprint="6cc93598fb3eb79c"><a class="slide-link" href="/office-fact-atelier-cns.htm" target="_blank" rel="noopener"><picture><source media="(max-width: 767px)" srcset="https://oss.gooood.cn/uploads/2026/09/cns-ppt-%E6%8B%B7%E8%B4%9D-768x230.jpg"><img data-src="https://oss.gooood.cn/uploads/2026/09/cns-ppt-%E6%8B%B7%E8%B4%9D.jpg" loading="lazy" fetchpriority="low" alt="OFFICE FACT NO.64 - Atelier cnS-ppt" width="2000" height="600" decoding="async"></picture></a></div> 2359 <div class="slide" data-ad-record-id="1721821" data-ad-slug="under-35-zhang-miaojie-ppt" data-ad-modified="" data-ad-title="under-35-zhang-miaojie-ppt" data-ad-fingerprint="5ce9a89d6c3c1809"><a class="slide-link" href="/under-35-zhang-miaojie.htm" target="_blank" rel="noopener"><picture><source media="(max-width: 767px)" srcset="https://oss.gooood.cn/uploads/2026/08/odd-ppt-%E6%8B%B7%E8%B4%9D-5j1-768x230.jpg"><img data-src="https://oss.gooood.cn/uploads/2026/08/odd-ppt-%E6%8B%B7%E8%B4%9D-5j1.jpg" loading="lazy" fetchpriority="low" alt="under-35-zhang-miaojie-ppt" width="2000" height="600" decoding="async"></picture></a></div> 2360 <div class="slide" data-ad-record-id="1681888" data-ad-slug="everyone-x-shenzhen-bay-cultural-square-mayansong-ppt" data-ad-modified="" data-ad-title="everyone-x-shenzhen-bay-cultural-square" data-ad-fingerprint="1a35e30b42d20d1f"><a class="slide-link" href="/everyone-x-shenzhen-bay-cultural-square.htm" target="_blank" rel="noopener"><picture><source media="(max-width: 767px)" srcset="https://oss.gooood.cn/uploads/2026/04/maysongmad-768x230.jpg"><img data-src="https://oss.gooood.cn/uploads/2026/04/maysongmad.jpg" loading="lazy" fetchpriority="low" alt="everyone-x-shenzhen-bay-cultural-square" width="2000" height="600" decoding="async"></picture></a></div> 2361 <div class="slide" data-ad-record-id="1714060" data-ad-slug="gooood-is-16-years-old-ppt" data-ad-modified="" data-ad-title="gooood is 16 years old!" data-ad-fingerprint="8203a6d353bc4e6f"><a class="slide-link" href="/gooood-happy-bday-16.htm" target="_blank" rel="noopener"><picture><source media="(max-width: 767px)" srcset="https://oss.gooood.cn/uploads/2026/07/happybirthday-ppt-768x230.jpg"><img data-src="https://oss.gooood.cn/uploads/2026/07/happybirthday-ppt.jpg" loading="lazy" fetchpriority="low" alt="gooood is 16 years old!" width="2000" height="600" decoding="async"></picture></a></div> 2362 <div class="slide" data-ad-record-id="1308764" data-ad-slug="preserving-twilight-shanghai-midnight-swim-craft-beer-bar-ppt" data-ad-modified="" data-ad-title="项ç®å¯¹æ¥æ¡ä¾No.22ï¼çä½é»æ - 䏿µ·å¤æ¸¸ç²¾é ¿åº" data-ad-fingerprint="7da6fae4e2530878"><a class="slide-link" href="/get-project-case-preserving-twilight-midnight-swim-craft
2362-beer-bar-by-ka-design-lab.htm" target="_blank" rel="noopener"><picture><source media="(max-width: 767px)" srcset="https://oss.gooood.cn/uploads/2026/03/%E5%A4%9C%E6%B8%B8-KA-08-%E6%8B%B7%E8%B4%9D-3-768x230.jpg"><img data-src="https://oss.gooood.cn/uploads/2026/03/%E5%A4%9C%E6%B8%B8-KA-08-%E6%8B%B7%E8%B4%9D-3.jpg" loading="lazy" fetchpriority="low" alt="项ç®å¯¹æ¥æ¡ä¾No.22ï¼çä½é»æ - 䏿µ·å¤æ¸¸ç²¾é ¿åº" width="2000" height="600" decoding="async"></picture></a></div> 2363 <div class="slider-controls"><button class="slider-btn" type="button" data-slide-prev aria-label="ä¸ä¸å¼ ">â¹</button><button class="slider-btn" type="button" data-slide-next aria-label="ä¸ä¸å¼ ">âº</button></div> 2364 <div class="top-slider-dots"><button class="is-active" type="button" data-slide-dot="0" aria-label="第 1 å¼ "></button><button class="" type="button" data-slide-dot="1" aria-label="第 2 å¼ "></button><button class="" type="button" data-slide-dot="2" aria-label="第 3 å¼ "></button><button class="" type="button" data-slide-dot="3" aria-label="第 4 å¼ "></button><button class="" type="button" data-slide-dot="4" aria-label="第 5 å¼ "></button><button class="" type="button" data-slide-dot="5" aria-label="第 6 å¼ "></button></div> 2365 </section> 2366 2367 <section class="ad-embed hero-below" aria-label="é¦é¡µè½®æå¾ä¸æ¹å¹¿å" data-v10-fragment="ad-34628" data-ad-position="é¦é¡µè½®æå¾ä¸æ¹å¹¿å" data-wp-tag-id="34628" data-wp-term-slug="home_list_0" data-backend-ad-position="34628" data-backend-ad-source="dashboard.api.api-advert-adposition.php?slugName=home_list_0" data-backend-ad-status="connected" data-ad-item-count="2" data-ad-record-id="1699563" data-ad-record-ids="1699563,346280001" data-ad-slug="top-ads" data-ad-modified="2026-08-21T14:08:20" data-ad-title="top ads ·" data-ad-href="#" data-ad-source="legacy-api:home_list_0" data-ad-fingerprint="343e3697f5d989c3" data-ad-set-fingerprint="dbff819325088d7f" data-ad-source-fetched-at="2026-10-02T06:04:17.285Z" data-ad-cache-status="stale" data-backend-ad-content="acf.ad_content"><div data-ad-record-id="1699563" style="display:contents"><p><span data-gooood-company-cases-top-ad-b aria-live="polite"></span></p></div><div data-ad-record-id="346280001" style="display:contents"><div class="job-text legacy-wordlink-jobs" data-legacy-ad-wordlink="1" data-wordlink-source="https://dashboard.gooood.cn/api/api-jobs-param.php?page=1&pageSize=12" data-admin-setting="options_column_count" data-configured-count="4" data-rendered-count="12" style="margin:0 auto 30px;max-width:1100px"><div class="job-head"><b>ææ°å·¥ä½</b><a class="job-submit" href="/job-service-info" target="_blank" rel="noopener">+æäº¤æ°å·¥ä½</a><a class="job-all" href="/category/jobs" target="_blank" rel="noopener">ææå·¥ä½ â</a></div><div class="job-cols"><div class="job-col" data-admin-setting="options_column_count" data-configured-count="4"><a class="job-line" href="https://www.gooood.cn/jobs/job-mengarchitects" target="_blank" rel="noopener" data-backend-job-id="1731355" data-backend-job-slug="job-mengarchitects"><b>ï¼æ·±å³ï¼MENG ARCHITECTS å建æ°å¢é â 建çè®¾è®¡å¸ / å©çç ç©¶å / åå¡ç»ç</b><em></em></a><a class="job-line" href="https://www.gooood.cn/jobs/job-plat-asia" target="_blank" rel="noopener" data-backend-job-id="940077" data-backend-job-slug="job-plat-asia"><b>ï¼å京ï¼PLAT ASIA - èµæ·±å»ºçå¸ / ä¸çº§å»ºçå¸ / å©ç建çå¸ / 建ç/æ¯è§å®ä¹ ç / æ¯è§è®¾è®¡å¸</b><em></em></a><a class="job-line" href="https://www.gooood.cn/jobs/job-cloud-seven" target="_blank" rel="noopener" data-backend-job-id="1730871" data-backend-job-slug="job-cloud-seven"><b>ï¼ä¸æµ·ï¼CLOUD7 äºä¸å»ºç - AI è®¾è®¡å¸ / ä¸çº§å»ºçè®¾è®¡å¸ / å级建çè®¾è®¡å¸ / 室å 设计å¸</b><em></em></a><a class="job-line" href="https://www.gooood.cn/jobs/job-bai-design-international" target="_blank" rel="noopener" data-backend-job-id="1500188" data-backend-job-slug="job-bai-design-international"><b>ï¼å京ï¼è±å½æ°å ¸å½é 建ç - èµæ·±å»ºçå¸ / 建çå¸ / å©ç建çå¸&åºå±æ¯ä¸ç / å®ä¹ ç / 室å 建çå¸ / åªä½ä¸å</b><em></em></a></div><div class="job-col" data-admin-setting="options_column_count" data-configured-count="4"><a class="job-line" href="https://www.gooood.cn/jobs/latest-20-companies-recruit-information-10" target="_blank" rel="noopener" data-backend-job-id="1636057" data-backend-job-slug="latest-20-companies-recruit-information-10"><b>æè¿æåªäºå¥½å·¥ä½ï¼è°·å¾·ææ°20å®¶æèä¿¡æ¯æ±æ»</b><em></em></a><a class="job-line" href="https://www.gooood.cn/jobs/job-youngdesign" target="_blank" rel="noopener" data-backend-job-id="1729522" data-backend-job-slug="job-youngdesign"><b>
2367ï¼æ¦æ±ï¼æ¬æ ·è®¾è®¡ YOUNGDESIGN - 设计æ»ç / 主æ¡è®¾è®¡å¸ / 空é´å©ç设计å¸</b><em></em></a><a class="job-line" href="https://www.gooood.cn/jobs/job-airwall-architecture-office" target="_blank" rel="noopener" data-backend-job-id="1617081" data-backend-job-slug="job-airwall-architecture-office"><b>ï¼éåºï¼ç©ºæ°å¢å»ºçå·¥ä½å®¤ AIRWALL ARCHITECTURE OFFICE - æ¹æ¡è®¾è®¡å¸ / å©çè®¾è®¡å¸ / 设计å®ä¹ ç</b><em></em></a><a class="job-line" href="https://www.gooood.cn/jobs/job-voice-architecture-lab" target="_blank" rel="noopener" data-backend-job-id="1610416" data-backend-job-slug="job-voice-architecture-lab"><b>ï¼ä¸æµ·ï¼Voice Architecture Lab - AI è®¾è®¡å¸ / ä¸çº§å»ºçè®¾è®¡å¸ / å级建çè®¾è®¡å¸ / å®¤å §è®¾è®¡å¸</b><em></em></a></div><div class="job-col" data-admin-setting="options_column_count" data-configured-count="4"><a class="job-line" href="https://www.gooood.cn/jobs/job-jz-lab" target="_blank" rel="noopener" data-backend-job-id="1408038" data-backend-job-slug="job-jz-lab"><b>ï¼æé½ï¼ä»æ¢åä¸è®¾è®¡ - åä¸è´è´£äºº / 项ç®è´è´£äºº / è®¾è®¡å¸ / å©çè®¾è®¡å¸ / å®ä¹ ç</b><em></em></a><a class="job-line" href="https://www.gooood.cn/jobs/job-euv" target="_blank" rel="noopener" data-backend-job-id="1618237" data-backend-job-slug="job-euv"><b>ï¼æ·±å³ï¼æ·±å³æå 设计ï¼E+UV å·¥ä½å®¤ï¼- 建çå¸ / å©ç建çå¸ / å®ä¹ ç</b><em></em></a><a class="job-line" href="https://www.gooood.cn/jobs/job-pha" target="_blank" rel="noopener" data-backend-job-id="1154247" data-backend-job-slug="job-pha"><b>ï¼æ·±å³ï¼PH Alpha Design æ¹æå½é 建çè®¾è®¡é¡¾é®æéå ¬å¸ â é«çº§å»ºçè®¾è®¡å¸ / 建çè®¾è®¡å¸ / 主æ¡è®¾è®¡å¸ / 室å è®¾è®¡å¸ / åå¡ç»ç</b><em></em></a><a class="job-line" href="https://www.gooood.cn/jobs/job-shiji" target="_blank" rel="noopener" data-backend-job-id="1558304" data-backend-job-slug="job-shiji"><b>ï¼ä¸æµ·ï¼æ¾é建ç - 项ç®è®¾è®¡å¸ / åå¡ä¸åªä½ä¸å / åä¸è½¯è£ è®¾è®¡å¸ / å©çè®¾è®¡å¸ / å®ä¹ ç</b><em></em></a></div></div></div></div></section> 2368 2369 <section class="archive-title-row v10-taxonomy-title" aria-label="å½å页é¢"><h1 data-zh="èµè®¯" data-en="News">èµè®¯</h1><span data-zh="ææ°æç« " data-en="Latest Articles">ææ°æç« </span></section><section class="row"> 2370 <article class="article" data-v10-fragment="article" data-backend-post-id="1730182" data-backend-post-slug="goodone-future-timber-architecture-design-competition" data-backend-post-modified="" data-backend-post-fingerprint="06018ab02864a95c" data-backend-primary-type-id=""><div class="cover"><a class="article-cover-link" href="/goodone-future-timber-architecture-design-competition.htm" target="_blank" rel="noopener" aria-label="ç«èµï½âæªæ¥æ¨æå»ºç设计ç«èµâåèµ·ï¼åå®¶ç¨ãè£åãç½å®æ°æ ä»»è¯å§"><img src="https://oss.gooood.cn/uploads/2026/09/%E5%B0%81%E9%9D%A2%E7%94%A8-472x303.png" srcset="https://oss.gooood.cn/uploads/2026/09/%E5%B0%81%E9%9D%A2%E7%94%A8-472x303.png 472w, https://oss.gooood.cn/uploads/2026/09/%E5%B0%81%E9%9D%A2%E7%94%A8-650x417.png 650w" sizes="(max-width: 767px) calc(100vw - 52px), 472px" alt="ç«èµï½âæªæ¥æ¨æå»ºç设计ç«èµâåèµ·ï¼åå®¶ç¨ãè£åãç½å®æ°æ ä»»è¯å§" width="650" height="417" decoding="async" loading="eager" fetchpriority="high"></a></div><div class="article-text"><div class="kicker" data-zh="èµè®¯" data-en="News">èµè®¯</div><h3><a href="/goodone-future-timber-architecture-design-competition.htm" target="_blank" rel="noopener" data-zh="ç«èµï½âæªæ¥æ¨æå»ºç设计ç«èµâåèµ·ï¼åå®¶ç¨ãè£åãç½å®æ°æ ä»»è¯å§" data-en="ç«èµï½âæªæ¥æ¨æå»ºç设计ç«èµâåèµ·ï¼åå®¶ç¨ãè£åãç½å®æ°æ ä»»è¯å§">ç«èµï½âæªæ¥æ¨æå»ºç设计ç«èµâåèµ·ï¼åå®¶ç¨ãè£åãç½å®æ°æ ä»»è¯å§</a></h3><div class="article-subtitle" data-zh="" data-en=""></div><div class="article-foot"><time datetime="2026-09-29T08:30:37">2026.09.29</time><span class="article-actions"><a href="#login" data-gooood-favorite-trigger="1" data-zh="æ¶è" data-en="Favorites">æ¶è</a><a href="#" data-zh="å享" data-en="Share">å享</a></span></div></div></article> 2371 <article class="article" data-v10-fragment="article" data-backend-p
2371ost-id="1730153" data-backend-post-slug="the-seventh-half-stage-exhibition-structuring-fragments-opens" data-backend-post-modified="" data-backend-post-fingerprint="71fa6f5b6737c817" data-backend-primary-type-id=""><div class="cover"><a class="article-cover-link" href="/the-seventh-half-stage-exhibition-structuring-fragments-opens.htm" target="_blank" rel="noopener" aria-label="ååºç¬¬ä¸åºå±è§ãçæ®µä¸ç»æä¹é´ãå¼å¹"><img src="https://oss.gooood.cn/uploads/2026/09/0-the-seventh-half-stage-exhibition-structuring-fragments-opens-472x303.jpg" srcset="https://oss.gooood.cn/uploads/2026/09/0-the-seventh-half-stage-exhibition-structuring-fragments-opens-472x303.jpg 472w, https://oss.gooood.cn/uploads/2026/09/0-the-seventh-half-stage-exhibition-structuring-fragments-opens-650x417.jpg 650w" sizes="(max-width: 767px) calc(100vw - 52px), 472px" alt="ååºç¬¬ä¸åºå±è§ãçæ®µä¸ç»æä¹é´ãå¼å¹" width="650" height="417" decoding="async" loading="lazy" fetchpriority="low"></a></div><div class="article-text"><div class="kicker" data-zh="èµè®¯" data-en="News">èµè®¯</div><h3><a href="/the-seventh-half-stage-exhibition-structuring-fragments-opens.htm" target="_blank" rel="noopener" data-zh="ååºç¬¬ä¸åºå±è§ãçæ®µä¸ç»æä¹é´ãå¼å¹" data-en="The Seventh âHALF STAGEâ Exhibition, Structuring Fragments, Opens">ååºç¬¬ä¸åºå±è§ãçæ®µä¸ç»æä¹é´ãå¼å¹</a></h3><div class="article-subtitle" data-zh="âå ³ç³»çç»æâä¸ âç©è´¨çç»æâ" data-en="âå ³ç³»çç»æâä¸ âç©è´¨çç»æâ">âå ³ç³»çç»æâä¸ âç©è´¨çç»æâ</div><div class="article-foot"><time datetime="2026-09-24T11:49:34">2026.09.24</time><span class="article-actions"><a href="#login" data-gooood-favorite-trigger="1" data-zh="æ¶è" data-en="Favorites">æ¶è</a><a href="#" data-zh="å享" data-en="Share">å享</a></span></div></div></article> 2372 </section> 2373 <section class="row"> 2374 <article class="article" data-v10-fragment="article" data-backend-post-id="1724037" data-backend-post-slug="grand-opening-suzhou-contemporary-art-museum-officially-open-to-the-public" data-backend-post-modified="" data-backend-post-fingerprint="67b2a5a579808251" data-backend-primary-type-id=""><div class="cover"><a class="article-cover-link" href="/grand-opening-suzhou-contemporary-art-museum-officially-open-to-the-public.htm" target="_blank" rel="noopener" aria-label="ç大å¯å¹ï¼èå·å½ä»£ç¾æ¯é¦æ£å¼åå ¬ä¼å¼æ¾"><img src="https://oss.gooood.cn/uploads/2026/09/01-grand-opening-suzhou-contemporary-art-museum-officially-open-to-the-public-472x303.jpg" srcset="https://oss.gooood.cn/uploads/2026/09/01-grand-opening-suzhou-contemporary-art-museum-officially-open-to-the-public-472x303.jpg 472w, https://oss.gooood.cn/uploads/2026/09/01-grand-opening-suzhou-contemporary-art-museum-officially-open-to-the-public-650x417.jpg 650w" sizes="(max-width: 767px) calc(100vw - 52px), 472px" alt="ç大å¯å¹ï¼èå·å½ä»£ç¾æ¯é¦æ£å¼åå ¬ä¼å¼æ¾" width="650" height="417" decoding="async" loading="lazy" fetchpriority="low"></a></div><div class="article-text"><div class="kicker" data-zh="èµè®¯" data-en="News">èµè®¯</div><h3><a href="/grand-opening-suzhou-contemporary-art-museum-officially-open-to-the-public.htm" target="_blank" rel="noopener" data-zh="ç大å¯å¹ï¼èå·å½ä»£ç¾æ¯é¦æ£å¼åå ¬ä¼å¼æ¾" data-en="Grand Opening: Suzhou Contemporary Art Museum Officially Opens to the Public">ç大å¯å¹ï¼èå·å½ä»£ç¾æ¯é¦æ£å¼åå ¬ä¼å¼æ¾</a></h3><div class="article-subtitle" data-zh="æä¸ºè¿æ¥åå¸ä¸æ¹æ³ç纽带" data-en="æä¸ºè¿æ¥åå¸ä¸æ¹æ³ç纽带">æä¸ºè¿æ¥åå¸ä¸æ¹æ³ç纽带</div><div class="article-foot"><time datetime="2026-09-04T10:21:19">2026.09.04</time><span class="article-actions"><a href="#login" data-gooood-favorite-trigger="1" data-zh="æ¶è" data-en="Favorites">æ¶è</a><a href="#" data-zh="å享" data-en="Share">å享</a></span></div></div></article> 2375 <article class="article" data-v10-fragment="article" data-backend-post-id="1715537" data-backend-p
2375ost-slug="bihailou-art-village-by-mvrdv" data-backend-post-modified="" data-backend-post-fingerprint="0bb0bbcdc3009b59" data-backend-primary-type-id=""><div class="cover"><a class="article-cover-link" href="/bihailou-art-village-by-mvrdv.htm" target="_blank" rel="noopener" aria-label="ç±MVRDVè®¾è®¡çæ·±å³ç¢§æµ·æ¥¼èºæ¯ææ£å¼å¼å·¥"><img src="https://oss.gooood.cn/uploads/2026/08/02-bihailou-art-village-by-mvrdv-472x303.jpg" srcset="https://oss.gooood.cn/uploads/2026/08/02-bihailou-art-village-by-mvrdv-472x303.jpg 472w, https://oss.gooood.cn/uploads/2026/08/02-bihailou-art-village-by-mvrdv-650x417.jpg 650w" sizes="(max-width: 767px) calc(100vw - 52px), 472px" alt="ç±MVRDVè®¾è®¡çæ·±å³ç¢§æµ·æ¥¼èºæ¯ææ£å¼å¼å·¥" width="650" height="417" decoding="async" loading="lazy" fetchpriority="low"></a></div><div class="article-text"><div class="kicker" data-zh="èµè®¯" data-en="News">èµè®¯</div><h3><a href="/bihailou-art-village-by-mvrdv.htm" target="_blank" rel="noopener" data-zh="ç±MVRDVè®¾è®¡çæ·±å³ç¢§æµ·æ¥¼èºæ¯ææ£å¼å¼å·¥" data-en="Bihailou Art Village by MVRDV">ç±MVRDVè®¾è®¡çæ·±å³ç¢§æµ·æ¥¼èºæ¯ææ£å¼å¼å·¥</a></h3><div class="article-subtitle" data-zh="å±äºèºæ¯å®¶çâåç´æè½â" data-en="å±äºèºæ¯å®¶çâåç´æè½â">å±äºèºæ¯å®¶çâåç´æè½â</div><div class="article-foot"><time datetime="2026-08-06T11:20:45">2026.08.06</time><span class="article-actions"><a href="#login" data-gooood-favorite-trigger="1" data-zh="æ¶è" data-en="Favorites">æ¶è</a><a href="#" data-zh="å享" data-en="Share">å享</a></span></div></div></article> 2376 </section> 2377 2378 <section class="ad-embed home-list-4-ad" data-v10-fragment="ad-34629" data-ad-position="é¦é¡µç¬¬ 4 ç¯æç« å广å" data-wp-tag-id="34629" data-wp-term-slug="home_list_4" data-backend-ad-position="34629" data-backend-ad-source="dashboard.api.api-advert-adposition.php?slugName=home_list_4" data-backend-ad-status="connected" data-ad-item-count="1" data-ad-record-id="1719764" data-ad-record-ids="1719764" data-ad-slug="homepage-top-3-buttor" data-ad-modified="" data-ad-title="é¦é¡µä¸é¨3æé®å¹¿å" data-ad-href="/advertisement/homepage-top-3-buttor" data-ad-source="legacy-api:home_list_4" data-ad-fingerprint="c2c5a37f7816dccb" data-ad-set-fingerprint="e93244b40c4bf2e8" data-ad-source-fetched-at="2026-10-02T06:04:17.067Z" data-ad-cache-status="stale" data-backend-ad-content="acf.ad_content"><div data-ad-record-id="1719764" style="display:contents"> 2379<style>._eOwner,._eDesigner,._eMaterial{transition:all 0.2s ease;line-height:1.2!important}._eOwner:hover{background:#092844!important}._eDesigner:hover{background:#10375f!important}._eMaterial:hover{background:#174a80!important}._eRow td{vertical-align:top!important}._eTitle,._eDesc,._eAction{display:block!important;line-height:1.22!important}._eBtn{display:flex!important;width:100%!important;height:auto!important;min-height:0!important;aspect-ratio:700/449;padding:24px 12px!important;box-sizing:border-box!important;flex-direction:column!important;align-items:center!important;justify-content:center!important}@media(max-width:600px){._eRow td{display:block!important;width:100%!important;padding:0 0 6px!important;box-sizing:border-box!important}._eBtn{height:98px!important;min-height:98px!important;aspect-ratio:auto!important;padding:17px 8px!important}._eTitle{font-size:15px!important}._eDesc,._eAction{font-size:11px!important}}</style> 2380<table style="max-width: 1100px; margin: 0 auto 30px; table-layout: fixed;" border="0" width="100%" cellspacing="0" cellpadding="0"> 2381<tbody> 2382<tr class="_eRow"> 2383<td style="padding-right: 12.667px;" width="33.333%"><a class="_eOwner _eBtn" style="display: flex; width: 100%; height: auto; aspect-ratio: 700 / 449; padding: 24px 12px; background: #0f3d68; color: #fff; text-align: center; text-decoration: none; font-weight: bold; box-sizing: border-box; line-height: 1.2!important; flex-direction: column; align-items: center; justify-content: center;" href="https://gooood.mike-x.com/22mtJ" target="_blank" rel="noopener noreferrer"><span class="_eTitle" style="display: block; color: #fff; font-size: 19px; font-weight: bold; line-height: 1.22!important;">ä¸ ä¸» æ¾ è®¾ 计 å¸</span><span class="_eDesc" style="display: block; padding-top: 6px; color: #dce8f2; font-size: 13px; font-weight: 400; line-height: 1.22!important;">çå®é¡¹ç®éæ±</span><span class="_eAction" style="display: block; padding-top: 2px; color: #fff; font-size: 13px; font-weight: 400; line-height: 1.22!important;">æäº¤é¡¹ç® â</span></a></td> 2384<td style="padding: 0 6.333px;" width="33.333%"><a class="_eDesigner _eBtn" style="display: flex; width: 100%; height: auto; aspect-ratio: 700 / 449; padding: 24px 12px; background: #174a80; color: #fff; text-align: center; text-decoration: none; font-weight: bold; box-sizing: border-box; line-height: 1.2!important; flex-direction: column; align-items: center; justify-content: center;" href="https://gooood.mike-x.com/i5usj" target="_blank" rel="noopener noreferrer"><span class="_eTitle" style="display: block; color: #fff; font-size: 19px; font-weight: bold; line-height: 1.22!important;">设 计 å¸ æ¥ é¡¹ ç®</span><span class="_eDesc" style="display: block; padding-top: 6px; color: #dce8f2; font-size: 13px; font-weight: 400; line-height: 1.22!important;">å¨çº¿é¡¹ç®</span><span class="_eAction" style="display: block; padding-top: 2px; color: #dce8f2; font-size: 13px; font-weight: 400; line-height: 1.22!important;">æ¥çæºä¼ â</span></a></td> 2385<td style="padding-left: 12.667px;" width="33.333%"><a class="_eMaterial _eBtn" style="display: flex; width: 100%; height: auto; aspect-ratio: 700 / 449; padding: 24px 12px; background: #1d5f99; color: #fff; text-align: center; text-decoration: none; font-weight: bold; box-sizing: border-box; line-height: 1.2!important; flex-direction: column; align-items: center; justify-content: center;" href="/materials" target="_blank" rel="noopener noreferrer"><span class="_eTitle" style="display: block; color: #fff; font-size: 19px; font-weight: bold; line-height: 1.22!important;">建 æ å ç æ¨ 广</span><span class="_eDesc" style="display: block; padding-top: 6px; color: #dce8f2; font-size: 13px; font-weight: 400; line-height: 1.22!important;">åçå±ç¤º · 项ç®éæ</span><span class="_eAction" style="display: block; padding-top: 2px; color: #dce8f2; font-size: 13px; font-weight: 400; line-height: 1.22!important;">è¿å ¥ææåº â</span></a></td> 2386</tr> 2387</tbody> 2388</table> 2389 </div></section> 2390 2391 2392 2393 <section class="row"> 2394 <article class="article" data-v10-fragment="article" data-backend-p
2394ost-id="1713780" data-backend-post-slug="half-stage-opens-its-sixth-exhibition-investigate-things-anew-the-use-and-being-of-industrial-objects" data-backend-post-modified="" data-backend-post-fingerprint="cedcd51c86cf67c0" data-backend-primary-type-id=""><div class="cover"><a class="article-cover-link" href="/half-stage-opens-its-sixth-exhibition-investigate-things-anew-the-use-and-being-of-industrial-objects.htm" target="_blank" rel="noopener" aria-label="âååºâ第å åºå±è§ãæ ¼ç©æ°è®®ï¼å·¥ä¸ç©çç¨ä¸å¨ãå¼å¹"><img src="https://oss.gooood.cn/uploads/2026/07/0-vaj-472x303.jpg" srcset="https://oss.gooood.cn/uploads/2026/07/0-vaj-472x303.jpg 472w, https://oss.gooood.cn/uploads/2026/07/0-vaj-650x417.jpg 650w" sizes="(max-width: 767px) calc(100vw - 52px), 472px" alt="âååºâ第å åºå±è§ãæ ¼ç©æ°è®®ï¼å·¥ä¸ç©çç¨ä¸å¨ãå¼å¹" width="472" height="303" decoding="async" loading="lazy" fetchpriority="low"></a></div><div class="article-text"><div class="kicker" data-zh="èµè®¯" data-en="News">èµè®¯</div><h3><a href="/half-stage-opens-its-sixth-exhibition-investigate-things-anew-the-use-and-being-of-industrial-objects.htm" target="_blank" rel="noopener" data-zh="âååºâ第å åºå±è§ãæ ¼ç©æ°è®®ï¼å·¥ä¸ç©çç¨ä¸å¨ãå¼å¹" data-en="âHALF STAGEâ Opens Its Sixth Exhibition, Investigate Things Anew: The Use and Being of Industrial Objects">âååºâ第å åºå±è§ãæ ¼ç©æ°è®®ï¼å·¥ä¸ç©çç¨ä¸å¨ãå¼å¹</a></h3><div class="article-subtitle" data-zh="å·¥ä¸ç©çâç¨âä¸âå¨â" data-en="å·¥ä¸ç©çâç¨âä¸âå¨â">å·¥ä¸ç©çâç¨âä¸âå¨â</div><div class="article-foot"><time datetime="2026-07-30T17:06:39">2026.07.30</time><span class="article-actions"><a href="#login" data-gooood-favorite-trigger="1" data-zh="æ¶è" data-en="Favorites">æ¶è</a><a href="#" data-zh="å享" data-en="Share">å享</a></span></div></div></article> 2395 <article class="article" data-v10-fragment="article" data-backend-post-id="1713021" data-backend-post-slug="z8-tower-construction-to-begin-by-zaha-hadid-architects" data-backend-post-modified="" data-backend-post-fingerprint="98511214ba1b6940" data-backend-primary-type-id=""><div class="cover"><a class="article-cover-link" href="/z8-tower-construction-to-begin-by-zaha-hadid-architects.htm" target="_blank" rel="noopener" aria-label="ZHA建çäºå¡æè®¾è®¡çZ8å°å项ç®å³å°å¼å·¥"><img src="https://oss.gooood.cn/uploads/2026/07/00-Z8-Tower-construction-to-begin-472x303.jpg" srcset="https://oss.gooood.cn/uploads/2026/07/00-Z8-Tower-construction-to-begin-472x303.jpg 472w, https://oss.gooood.cn/uploads/2026/07/00-Z8-Tower-construction-to-begin-650x417.jpg 650w" sizes="(max-width: 767px) calc(100vw - 52px), 472px" alt="ZHA建çäºå¡æè®¾è®¡çZ8å°å项ç®å³å°å¼å·¥" width="472" height="303" decoding="async" loading="lazy" fetchpriority="low"></a></div><div class="article-text"><div class="kicker" data-zh="èµè®¯" data-en="News">èµè®¯</div><h3><a href="/z8-tower-construction-to-begin-by-zaha-hadid-architects.htm" target="_blank" rel="noopener" data-zh="ZHA建çäºå¡æè®¾è®¡çZ8å°å项ç®å³å°å¼å·¥" data-en="Z8 Tower construction to begin by Zaha Hadid Architects">ZHA建çäºå¡æè®¾è®¡çZ8å°å项ç®å³å°å¼å·¥</a></h3><div class="article-subtitle" data-zh="髿äºèç âåç´é½ä¼â" data-en="髿äºèç âåç´é½ä¼â">髿äºèç âåç´é½ä¼â</div><div class="article-foot"><time datetime="2026-07-29T09:18:37">2026.07.29</time><span class="article-actions"><a href="#login" data-gooood-favorite-trigger="1" data-zh="æ¶è" data-en="Favorites">æ¶è</a><a href="#" data-zh="å享" data-en="Share">å享</a></span></div></div></article> 2396 </section> 2397 2398 <section class="row"> 2399 <article class="article" data-v10-fragment="article" data-backend-post-id="1712748" data-backend-post-slug="tashkent-s-modernist-architecture-uzbekistan" data-backend-post-modified="" data-backend-post-fingerprint="eab323956d6c5731" data-backend-primary-type-id=""><div class="cover"><a class="article-cover-link" href="/tashkent-s-modernist-architecture-uzbekistan.htm" target="_blank" rel="noopener" aria-label="å¡ä»å¹²ç°ä»£ä¸»ä¹å»ºçåå ¥ãä¸çé产åå½ã"><img src="https://oss.gooood.cn/uploads/2026/07/00-Tashkent-s-Modernist-Architecture-Uzbekistan-472x303.jpg" srcset="https://oss.gooood.cn/uploads/2026/07/00-Tashkent-s-Modernist-Architecture-Uzbekistan-472x303.jpg 472w, https://oss.gooood.cn/uploads/2026/07/00-Tashkent-s-Modernist-Architecture-Uzbekistan-650x417.jpg 650w" sizes="(max-width: 767px) calc(100vw - 52px), 472px" alt="å¡ä»å¹²ç°ä»£ä¸»ä¹å»ºçåå ¥ãä¸çé产åå½ã" width="472" height="303" decoding="async" loading="lazy" fetchpriority="low"></a></div><div class="article-text"><div class="kicker" data-zh="èµè®¯" data-en="News">èµè®¯</div><h3><a href="/tashkent-s-modernist-architecture-uzbekistan.htm" target="_blank" rel="noopener" data-zh="å¡ä»å¹²ç°ä»£ä¸»ä¹å»ºçåå ¥ãä¸çé产åå½ã" data-en="Tashkent's Modernist Architecture, Uzbekistan">å¡ä»å¹²ç°ä»£ä¸»ä¹å»ºçåå ¥ãä¸çé产åå½ã</a></h3><div class="article-subtitle" data-zh="å座åå ¥èåå½æç§æç»ç»ä¸çé产åå½çå°æ æ§å»ºç" data-en="å座åå ¥èåå½æç§æç»ç»ä¸çé产åå½çå°æ æ§å»ºç">å座åå ¥èåå½æç§æç»ç»ä¸çé产åå½çå°æ æ§å»ºç</div><div class="article-foot"><time datetime="2026-07-28T15:02:04">2026.07.28</time><span class="article-actions"><a href="#login" data-gooood-favorite-trigger="1" data-zh="æ¶è" data-en="Favorites">æ¶è</a><a href="#" data-zh="å享" data-en="Share">å享</a></span></div></div></article> 2400 <article class="article" data-v10-fragment="article" data-backend-p
2400ost-id="1709762" data-backend-post-slug="vital-architecture-atelier-li-xinggang-in-barcelona" data-backend-post-modified="" data-backend-post-fingerprint="d1a0683bcc6597bf" data-backend-primary-type-id=""><div class="cover"><a class="article-cover-link" href="/vital-architecture-atelier-li-xinggang-in-barcelona.htm" target="_blank" rel="noopener" aria-label="âçå¢å»ºçVital Architecture: Atelier Li Xinggangâå·´å¡ç½é£å±åå¼å¹å¦æ¯æ´»å¨æå举å"><img src="https://oss.gooood.cn/uploads/2026/07/02-vital-architecture-atelier-li-xinggang-in-barcelona-472x303.jpg" srcset="https://oss.gooood.cn/uploads/2026/07/02-vital-architecture-atelier-li-xinggang-in-barcelona-472x303.jpg 472w, https://oss.gooood.cn/uploads/2026/07/02-vital-architecture-atelier-li-xinggang-in-barcelona-650x417.jpg 650w" sizes="(max-width: 767px) calc(100vw - 52px), 472px" alt="âçå¢å»ºçVital Architecture: Atelier Li Xinggangâå·´å¡ç½é£å±åå¼å¹å¦æ¯æ´»å¨æå举å" width="472" height="303" decoding="async" loading="lazy" fetchpriority="low"></a></div><div class="article-text"><div class="kicker" data-zh="èµè®¯" data-en="News">èµè®¯</div><h3><a href="/vital-architecture-atelier-li-xinggang-in-barcelona.htm" target="_blank" rel="noopener" data-zh="âçå¢å»ºçVital Architecture: Atelier Li Xinggangâå·´å¡ç½é£å±åå¼å¹å¦æ¯æ´»å¨æå举å" data-en="âVital Architecture: Atelier Li Xinggangâ Barcelona Exhibition and Opening Event Successfully Held">âçå¢å»ºçVital Architecture: Atelier Li Xinggangâå·´å¡ç½é£å±åå¼å¹å¦æ¯æ´»å¨æå举å</a></h3><div class="article-subtitle" data-zh="以å½ä»£æ§ç设计ååºå½ä¸å ¨çåççåä¸çæ´»ææ" data-en="以å½ä»£æ§ç设计ååºå½ä¸å ¨çåççåä¸çæ´»ææ">以å½ä»£æ§ç设计ååºå½ä¸å ¨çåççåä¸çæ´»ææ</div><div class="article-foot"><time datetime="2026-07-20T11:24:51">2026.07.20</time><span class="article-actions"><a href="#login" data-gooood-favorite-trigger="1" data-zh="æ¶è" data-en="Favorites">æ¶è</a><a href="#" data-zh="å享" data-en="Share">å享</a></span></div></div></article> 2401 </section> 2402 <section class="ad-embed materials-ad" data-v10-fragment="ad-34630" data-ad-position="é¦é¡µç¬¬ 8 ç¯æç« å" data-wp-tag-id="34630" data-wp-term-slug="home_list_8" data-backend-ad-position="34630" data-backend-ad-source="dashboard.api.api-advert-adposition.php?slugName=home_list_8" data-backend-ad-status="empty" data-ad-item-count="0" data-ad-source="legacy-api:home_list_8" data-ad-set-fingerprint="811c9dc59e3779b9" data-ad-source-fetched-at="2026-10-02T06:04:17.052Z" data-ad-cache-status="stale" hidden aria-hidden="true"></section> 2403 <section class="row"> 2404 <article class="article" data-v10-fragment="article" data-backend-post-id="1707711" data-backend-post-slug="architectures-inscriptions-exhibition-opens-at-tank-shanghai" data-backend-post-modified="" data-backend-post-fingerprint="60a631cf5f766053" data-backend-primary-type-id=""><div class="cover"><a class="article-cover-link" href="/architectures-inscriptions-exhibition-opens-at-tank-shanghai.htm" target="_blank" rel="noopener" aria-label="å±è§â建ççéåâäºä¸æµ·æ²¹ç½èºæ¯ä¸å¿å¼å¹"><img src="https://oss.gooood.cn/uploads/2026/07/00-Architectures-Inscriptions-Exhibition-Opens-at-Tank-Shanghai-472x303.jpg" srcset="https://oss.gooood.cn/uploads/2026/07/00-Architectures-Inscriptions-Exhibition-Opens-at-Tank-Shanghai-472x303.jpg 472w, https://oss.gooood.cn/uploads/2026/07/00-Architectures-Inscriptions-Exhibition-Opens-at-Tank-Shanghai-650x417.jpg 650w" sizes="(max-width: 767px) calc(100vw - 52px), 472px" alt="å±è§â建ççéåâäºä¸æµ·æ²¹ç½èºæ¯ä¸å¿å¼å¹" width="472" height="303" decoding="async" loading="lazy" fetchpriority="low"></a></div><div class="article-text"><div class="kicker" data-zh="èµè®¯" data-en="News">èµè®¯</div><h3><a href="/architectures-inscriptions-exhibition-opens-at-tank-shanghai.htm" target="_blank" rel="noopener" data-zh="å±è§â建ççéåâäºä¸æµ·æ²¹ç½èºæ¯ä¸å¿å¼å¹" data-en="Architecture's Inscriptions Exhibition Opens at Tank Shanghai">å±è§â建ççéåâäºä¸æµ·æ²¹ç½èºæ¯ä¸å¿å¼å¹</a></h3><div class="article-subtitle" data-zh="å¨âéåâä¸éæè¿å»ä¸æªæ
2404¥" data-en="å¨âéåâä¸éæè¿å»ä¸æªæ¥">å¨âéåâä¸éæè¿å»ä¸æªæ¥</div><div class="article-foot"><time datetime="2026-07-14T14:25:41">2026.07.14</time><span class="article-actions"><a href="#login" data-gooood-favorite-trigger="1" data-zh="æ¶è" data-en="Favorites">æ¶è</a><a href="#" data-zh="å享" data-en="Share">å享</a></span></div></div></article> 2405 <article class="article" data-v10-fragment="article" data-backend-post-id="1707158" data-backend-post-slug="the-2026-european-prize-for-urban-public-space-announces-the-25-shortlisted-projects" data-backend-post-modified="" data-backend-post-fingerprint="f777d908f49e249c" data-backend-primary-type-id=""><div class="cover"><a class="article-cover-link" href="/the-2026-european-prize-for-urban-public-space-announces-the-25-shortlisted-projects.htm" target="_blank" rel="noopener" aria-label="2026欧洲åå¸å ¬å ±ç©ºé´å¥å ¬å¸25ä¸ªå ¥å´é¡¹ç®"><img src="https://oss.gooood.cn/uploads/2026/07/%E8%B5%84%E8%AE%AF%E7%B1%BB%E6%96%87%E7%AB%A0%E5%B0%81%E9%9D%A2-472x303.png" srcset="https://oss.gooood.cn/uploads/2026/07/%E8%B5%84%E8%AE%AF%E7%B1%BB%E6%96%87%E7%AB%A0%E5%B0%81%E9%9D%A2-472x303.png 472w, https://oss.gooood.cn/uploads/2026/07/%E8%B5%84%E8%AE%AF%E7%B1%BB%E6%96%87%E7%AB%A0%E5%B0%81%E9%9D%A2-650x417.png 650w" sizes="(max-width: 767px) calc(100vw - 52px), 472px" alt="2026欧洲åå¸å ¬å ±ç©ºé´å¥å ¬å¸25ä¸ªå ¥å´é¡¹ç®" width="472" height="303" decoding="async" loading="lazy" fetchpriority="low"></a></div><div class="article-text"><div class="kicker" data-zh="èµè®¯" data-en="News">èµè®¯</div><h3><a href="/the-2026-european-prize-for-urban-public-space-announces-the-25-shortlisted-projects.htm" target="_blank" rel="noopener" data-zh="2026欧洲åå¸å ¬å ±ç©ºé´å¥å ¬å¸25ä¸ªå ¥å´é¡¹ç®" data-en="The 2026 European Prize for Urban Public Space Announces the 25 Shortlisted Projects">2026欧洲åå¸å ¬å ±ç©ºé´å¥å ¬å¸25ä¸ªå ¥å´é¡¹ç®</a></h3><div class="article-subtitle" data-zh="ä»¥å ¬å ±ç©ºé´ååºæ°åãçæä¸ç¤¾ä¼ææ" data-en="ä»¥å ¬å ±ç©ºé´ååºæ°åãçæä¸ç¤¾ä¼ææ">ä»¥å ¬å ±ç©ºé´ååºæ°åãçæä¸ç¤¾ä¼ææ</div><div class="article-foot"><time datetime="2026-07-13T12:20:29">2026.07.13</time><span class="article-actions"><a href="#login" data-gooood-favorite-trigger="1" data-zh="æ¶è" data-en="Favorites">æ¶è</a><a href="#" data-zh="å享" data-en="Share">å享</a></span></div></div></article> 2406 </section> 2407 <section class="row"> 2408 <article class="article" data-v10-fragment="article" data-backend-post-id="1679499" data-backend-post-slug="materials-information" data-backend-post-modified="" data-backend-post-fingerprint="c0a3ac6f3715e523" data-backend-primary-type-id=""><div class="cover"><a class="article-cover-link" href="/materials-information.htm" target="_blank" rel="noopener" aria-label="èä¼è´¨å»ºæï¼èµè®¾è®¡çµæï½æ¾å»ºæï¼æ¥è°·å¾·ï¼"><img src="https://oss.gooood.cn/uploads/2026/04/%E6%9D%90%E6%96%99%E5%B0%81%E9%9D%A2--472x303.jpg" srcset="https://oss.gooood.cn/uploads/2026/04/%E6%9D%90%E6%96%99%E5%B0%81%E9%9D%A2--472x303.jpg 472w, https://oss.gooood.cn/uploads/2026/04/%E6%9D%90%E6%96%99%E5%B0%81%E9%9D%A2--650x417.jpg 650w" sizes="(max-width: 767px) calc(100vw - 52px), 472px" alt="èä¼è´¨å»ºæï¼èµè®¾è®¡çµæï½æ¾å»ºæï¼æ¥è°·å¾·ï¼" width="472" height="303" decoding="async" loading="lazy" fetchpriority="low"></a></div><div class="article-text"><div class="kicker" data-zh="èµè®¯" data-en="News">èµè®¯</div><h3><a href="/materials-information.htm" target="_blank" rel="noopener" data-zh="èä¼è´¨å»ºæï¼èµè®¾è®¡çµæï½æ¾å»ºæï¼æ¥è°·å¾·ï¼" data-en="Materials information">èä¼è´¨å»ºæï¼èµè®¾è®¡çµæï½æ¾å»ºæï¼æ¥è°·å¾·ï¼</a></h3><div class="article-subtitle" data-zh="" data-en=""></div><div class="article-foot"><time datetime="2026-07-06T16:00:23">2026.07.06</time><span class="article-actions"><a href="#login" data-gooood-favorite-trigger="1" data-zh="æ¶è" data-en="Favorites">æ¶è</a><a href="#" data-zh="å享" data-en="Share">å享</a></span></div></div></article> 2409 <article class="article" data-v10-fragment="article" data-backend-p
2409ost-id="1703682" data-backend-post-slug="uia-world-congress-of-architects-2026-barcelona" data-backend-post-modified="" data-backend-post-fingerprint="92a94bf8e5b649b4" data-backend-primary-type-id=""><div class="cover"><a class="article-cover-link" href="/uia-world-congress-of-architects-2026-barcelona.htm" target="_blank" rel="noopener" aria-label="2026å·´å¡ç½é£UIAä¸ç建çå¸å¤§ä¼"><img src="https://oss.gooood.cn/uploads/2026/07/UIA-World-Congress-of-Architects-2026-Barcelona-472x303.jpg" srcset="https://oss.gooood.cn/uploads/2026/07/UIA-World-Congress-of-Architects-2026-Barcelona-472x303.jpg 472w, https://oss.gooood.cn/uploads/2026/07/UIA-World-Congress-of-Architects-2026-Barcelona-650x417.jpg 650w" sizes="(max-width: 767px) calc(100vw - 52px), 472px" alt="2026å·´å¡ç½é£UIAä¸ç建çå¸å¤§ä¼" width="472" height="303" decoding="async" loading="lazy" fetchpriority="low"></a></div><div class="article-text"><div class="kicker" data-zh="èµè®¯" data-en="News">èµè®¯</div><h3><a href="/uia-world-congress-of-architects-2026-barcelona.htm" target="_blank" rel="noopener" data-zh="2026å·´å¡ç½é£UIAä¸ç建çå¸å¤§ä¼" data-en="UIA World Congress of Architects 2026 Barcelona">2026å·´å¡ç½é£UIAä¸ç建çå¸å¤§ä¼</a></h3><div class="article-subtitle" data-zh="å·´å¡ç½é£æ±èå ¨çä¸ä¸å建çå¸ï¼å ±ååºå¯¹ä½æ¿å±æºãæ°åç´§æ¥ç¶æä¸å叿æ" data-en="å·´å¡ç½é£æ±èå ¨çä¸ä¸å建çå¸ï¼å ±ååºå¯¹ä½æ¿å±æºãæ°åç´§æ¥ç¶æä¸å叿æ">å·´å¡ç½é£æ±èå ¨çä¸ä¸å建çå¸ï¼å ±ååºå¯¹ä½æ¿å±æºãæ°åç´§æ¥ç¶æä¸å叿æ</div><div class="article-foot"><time datetime="2026-07-02T12:04:17">2026.07.02</time><span class="article-actions"><a href="#login" data-gooood-favorite-trigger="1" data-zh="æ¶è" data-en="Favorites">æ¶è</a><a href="#" data-zh="å享" data-en="Share">å享</a></span></div></div></article> 2410 </section> 2411 2412 <section class="ad-embed project-ad" data-v10-fragment="ad-34632" data-ad-position="é¦é¡µç¬¬ 12 ç¯æç« å" data-wp-tag-id="34632" data-wp-term-slug="home_list_12" data-backend-ad-position="34632" data-backend-ad-source="dashboard.api.api-advert-adposition.php?slugName=home_list_12" data-backend-ad-status="empty" data-ad-item-count="0" data-ad-source="legacy-api:home_list_12" data-ad-set-fingerprint="811c9dc59e3779b9" data-ad-source-fetched-at="2026-10-02T06:04:17.059Z" data-ad-cache-status="stale" hidden aria-hidden="true"></section> 2413 2414 <section class="row"> 2415 <article class="article" data-v10-fragment="article" data-backend-post-id="1703658" data-backend-post-slug="mvrdv-wins-competition-to-renovate-turins-civic-gallery-of-modern-and-contemporary-art" data-backend-post-modified="" data-backend-post-fingerprint="1524597d724756b9" data-backend-primary-type-id=""><div class="cover"><a class="article-cover-link" href="/mvrdv-wins-competition-to-renovate-turins-civic-gallery-of-modern-and-contemporary-art.htm" target="_blank" rel="noopener" aria-label="MVRDVèµ¢å¾é½çµå¸ç«ç°ä»£ä¸å½ä»£èºæ¯é¦æ¹é ç«èµ">
2415<img src="https://oss.gooood.cn/uploads/2026/07/Turins-Civic-Gallery-472x303.jpg" srcset="https://oss.gooood.cn/uploads/2026/07/Turins-Civic-Gallery-472x303.jpg 472w, https://oss.gooood.cn/uploads/2026/07/Turins-Civic-Gallery-650x417.jpg 650w" sizes="(max-width: 767px) calc(100vw - 52px), 472px" alt="MVRDVèµ¢å¾é½çµå¸ç«ç°ä»£ä¸å½ä»£èºæ¯é¦æ¹é ç«èµ" width="472" height="303" decoding="async" loading="lazy" fetchpriority="low"></a></div><div class="article-text"><div class="kicker" data-zh="èµè®¯" data-en="News">èµè®¯</div><h3><a href="/mvrdv-wins-competition-to-renovate-turins-civic-gallery-of-modern-and-contemporary-art.htm" target="_blank" rel="noopener" data-zh="MVRDVèµ¢å¾é½çµå¸ç«ç°ä»£ä¸å½ä»£èºæ¯é¦æ¹é ç«èµ" data-en="MVRDV wins competition to renovate Turin's Civic Gallery of Modern and Contemporary Art">MVRDVèµ¢å¾é½çµå¸ç«ç°ä»£ä¸å½ä»£èºæ¯é¦æ¹é ç«èµ</a></h3><div class="article-subtitle" data-zh="以弿¾å¼èååºåå¯çµæ´»è°æ´çå±ç¤ºç³»ç»éå¡åç©é¦" data-en="以弿¾å¼èååºåå¯çµæ´»è°æ´çå±ç¤ºç³»ç»éå¡åç©é¦">以弿¾å¼èååºåå¯çµæ´»è°æ´çå±ç¤ºç³»ç»éå¡åç©é¦</div><div class="article-foot"><time datetime="2026-07-02T10:14:48">2026.07.02</time><span class="article-actions"><a href="#login" data-gooood-favorite-trigger="1" data-zh="æ¶è" data-en="Favorites">æ¶è</a><a href="#" data-zh="å享" data-en="Share">å享</a></span></div></div></article> 2416 <article class="article" data-v10-fragment="article" data-backend-post-id="1692671" data-backend-post-slug="solar-architectural-design-competition" data-backend-post-modified="" data-backend-post-fingerprint="8e32fc6199b82afd" data-backend-primary-type-id=""><div class="cover"><a class="article-cover-link" href="/solar-architectural-design-competition.htm" target="_blank" rel="noopener" aria-label="èç¦BIPVæªæ¥è¶å¿ï¼å宿°è½å ä¼å»ºçè®¾è®¡å¤§èµæ£å¼å¯å¨"><img src="https://oss.gooood.cn/uploads/2026/05/%E6%96%B0%E5%B0%81%E9%9D%A2%E5%B0%8F-472x303.png" srcset="https://oss.gooood.cn/uploads/2026/05/%E6%96%B0%E5%B0%81%E9%9D%A2%E5%B0%8F-472x303.png 472w, https://oss.gooood.cn/uploads/2026/05/%E6%96%B0%E5%B0%81%E9%9D%A2%E5%B0%8F-650x417.png 650w" sizes="(max-width: 767px) calc(100vw - 52px), 472px" alt="èç¦BIPVæªæ¥è¶å¿ï¼å宿°è½å ä¼å»ºçè®¾è®¡å¤§èµæ£å¼å¯å¨" width="472" height="303" decoding="async" loading="lazy" fetchpriority="low"></a></div><div class="article-text"><div class="kicker" data-zh="èµè®¯" data-en="News">èµè®¯</div><h3><a href="/solar-architectural-design-competition.htm" target="_blank" rel="noopener" data-zh="èç¦BIPVæªæ¥è¶å¿ï¼å宿°è½å ä¼å»ºçè®¾è®¡å¤§èµæ£å¼å¯å¨" data-en="Solar Architectural Design Competition">èç¦BIPVæªæ¥è¶å¿ï¼å宿°è½å ä¼å»ºçè®¾è®¡å¤§èµæ£å¼å¯å¨</a></h3><div class="article-subtitle" data-zh="ééæåå ¨ç设计åéï¼éæ°å®ä¹æªæ¥å»ºçå±é¡¶" data-en="ééæåå ¨ç设计åéï¼éæ°å®ä¹æªæ¥å»ºçå±é¡¶">ééæåå ¨ç设计åéï¼éæ°å®ä¹æªæ¥å»ºçå±é¡¶</div><div class="article-foot"><time datetime="2026-05-29T18:30:39">2026.05.29</time><span class="article-actions"><a href="#login" data-gooood-favorite-trigger="1" data-zh="æ¶è" data-en="Favorites">æ¶è</a><a href="#" data-zh="å享" data-en="Share">å享</a></span></div></div></article> 2417 </section> 2418 <section class="row"> 2419 <article class="article" data-v10-fragment="article" data-backend-post-id="1689306" data-backend-post-slug="architecture-drawing-prize-exhibition-by-soane-museum" data-backend-post-modified="" data-backend-post-fingerprint="db34da7e9c9f2a5a" data-backend-primary-type-id=""><div class="cover"><a class="article-cover-link" href="/architecture-drawing-prize-exhibition-by-soane-museum.htm" target="_blank" rel="noopener" aria-label="2025年建çç»å¾å¥è·å¥ä½åååå ¬å¸"><img src="https://oss.gooood.cn/uploads/2026/05/02-architecture-drawing-prize-exhibition-by-soane-museum-472x303.jpg" srcset="https://oss.gooood.cn/uploads/2026/05/02-architecture-drawing-prize-exhibition-by-soane-museum-472x303.jpg 472w, https://oss.gooood.cn/uploads/2026/05/02-architecture-drawing-prize-exhibition-by-soane-museum-650x417.jpg 650w" sizes="(max-width: 767px) calc(100vw - 52px), 472px" alt="2025年建çç»å¾å¥è·å¥ä½åååå ¬å¸" width="472" height="303" decoding="async" loading="lazy" fetchpriority="low"></a></div><div class="article-text"><div class="kicker" data-zh="èµè®¯" data-en="News">èµè®¯</div><h3><a href="/architecture-drawing-prize-exhibition-by-soane-museum.htm" target="_blank" rel="noopener" data-zh="2025年建çç»å¾å¥è·å¥ä½åååå ¬å¸" data-en="2025 Architecture Drawing Prize Exhibition by Soane Museum">2025年建çç»å¾å¥è·å¥ä½åååå ¬å¸</a></h3><div class="article-subtitle" data-zh="è±å½å»ºçç³»å¦çSanjidah Chowdhur
2419yè·å¾æ»å åï¼å«å®æ´è·å¥ååï¼" data-en="è±å½å»ºçç³»å¦çSanjidah Chowdhuryè·å¾æ»å åï¼å«å®æ´è·å¥ååï¼">è±å½å»ºçç³»å¦çSanjidah Chowdhuryè·å¾æ»å åï¼å«å®æ´è·å¥ååï¼</div><div class="article-foot"><time datetime="2026-05-14T15:34:29">2026.05.14</time><span class="article-actions"><a href="#login" data-gooood-favorite-trigger="1" data-zh="æ¶è" data-en="Favorites">æ¶è</a><a href="#" data-zh="å享" data-en="Share">å享</a></span></div></div></article> 2420 <article class="article" data-v10-fragment="article" data-backend-post-id="1688911" data-backend-post-slug="the-eumies-awards-days-2026-celebrate-the-best-of-european-architecture-in-barcelona-with-a-programme-focused-on-reuse-and-transformation" data-backend-post-modified="" data-backend-post-fingerprint="65c6841d6eee9d79" data-backend-primary-type-id=""><div class="cover"><a class="article-cover-link" href="/the-eumies-awards-days-2026-celebrate-the-best-of-european-architecture-in-barcelona-with-a-programme-focused-on-reuse-and-transformation.htm" target="_blank" rel="noopener" aria-label="2026年坿¯å¥æ¥äº®ç¸å·´å¡ç½é£"><img src="https://oss.gooood.cn/uploads/2026/05/02-the-eumies-awards-days-2026-celebrate-the-best-of-european-architecture-in-barcelona-with-a-programme-focused-on-reuse-and-transformation-472x303.jpg" srcset="https://oss.gooood.cn/uploads/2026/05/02-the-eumies-awards-days-2026-celebrate-the-best-of-european-architecture-in-barcelona-with-a-programme-focused-on-reuse-and-transformation-472x303.jpg 472w, https://oss.gooood.cn/uploads/2026/05/02-the-eumies-awards-days-2026-celebrate-the-best-of-european-architecture-in-barcelona-with-a-programme-focused-on-reuse-and-transformation-650x417.jpg 650w" sizes="(max-width: 767px) calc(100vw - 52px), 472px" alt="2026年坿¯å¥æ¥äº®ç¸å·´å¡ç½é£" width="472" height="303" decoding="async" loading="lazy" fetchpriority="low"></a></div><div class="article-text"><div class="kicker" data-zh="èµè®¯" data-en="News">èµè®¯</div><h3><a href="/the-eumies-awards-days-2026-celebrate-the-best-of-european-architecture-in-barcelona-with-a-programme-focused-on-reuse-and-transformation.htm" target="_blank" rel="noopener" data-zh="2026年坿¯å¥æ¥äº®ç¸å·´å¡ç½é£" data-en="The EUmies Awards Days 2026 celebrate the best of European architecture in Barcelona with a programme focused on reuse and transformation">2026年坿¯å¥æ¥äº®ç¸å·´å¡ç½é£</a></h3><div class="article-subtitle" data-zh="èç¦åå©ç¨ä¸è½¬å" data-en="èç¦åå©ç¨ä¸è½¬å">èç¦åå©ç¨ä¸è½¬å</div><div class="article-foot"><time datetime="2026-05-13T11:53:44">2026.05.13</time><span class="article-actions"><a href="#login" data-gooood-favorite-trigger="1" data-zh="æ¶è" data-en="Favorites">æ¶è</a><a href="#" data-zh="å享" data-en="Share">å享</a></span></div></div></article> 2421 </section> 2422 <section class="row"> 2423 <article class="article" data-v10-fragment="article" data-backend-post-id="1682894" data-backend-post-slug="from-green-enjoyment-to-built-reality-built-projects-from-the-2024-subtropical-sustainable-design-competition" data-backend-post-modified="" data-backend-post-fingerprint="e1562889f17a92a5" data-backend-primary-type-id=""><div class="cover"><a class="article-cover-link" href="/from-green-enjoyment-to-built-reality-built-projects-from-the-2024-subtropical-sustainable-design-competition.htm" target="_blank" rel="noopener" aria-label="å¹ç»¿æçââ2024äºç另坿ç»è®¾è®¡ç«èµè·å¥ä½åè½æåå¸"><img src="https://oss.gooood.cn/uploads/2026/04/2-bal-472x303.jpg" srcset="https://oss.gooood.cn/uploads/2026/04/2-bal-472x303.jpg 472w, https://oss.gooood.cn/uploads/2026/04/2-bal-650x417.jpg 650w" sizes="(max-width: 767px) calc(100vw - 52px), 472px" alt="å¹ç»¿æçââ2024äºç另坿ç»è®¾è®¡ç«èµè·å¥ä½åè½æåå¸" width="472" height="303" decoding="async" loading="lazy" fetchpriority="low"></a></div><div class="article-text"><div class="kicker" data-zh="èµè®¯" data-en="News">èµè®¯</div><h3><a href="/from-green-enjoyment-to-built-reality-built-projects-from-the-2024-subtropical-sustainable-design-competition.htm" target="_blank" rel="noopener" data-zh="å¹ç»¿æçââ2024äºç另坿ç»è®¾è®¡ç«èµè·å¥ä½åè½æåå¸" data-en="From Green Enjoyment to Built RealityâBuilt Projects from the 2024 Subtropical Sustainable Design Competition">å¹ç»¿æçââ2024äºç另坿ç»è®¾è®¡ç«èµè·å¥ä½åè½æåå¸</a></h3><div class="article-subtitle" data-zh="å¨çå®åºå°ä¸çé¿çé¶ç¢³å®éª" data-en="å¨çå®åºå°ä¸çé¿çé¶ç¢³å®éª">å¨çå®åºå°ä¸çé¿çé¶ç¢³å®éª</div><div class="article-foot"><time datetime="2026-04-21T16:21:46">2026.04.21</time><span class="article-actions"><a href="#login" data-gooood-favorite-trigger="1" data-zh="æ¶è" data-en="Favorites">æ¶è</a><a href="#" data-zh="å享" data-en="Share">å享</a></span></div></div></article> 2424 <article class="article" data-v10-fragment="article" data-backend-p
2424ost-id="1682278" data-backend-post-slug="winners-announcement-of-european-union-prize-for-the-2026-eumies-awards" data-backend-post-modified="" data-backend-post-fingerprint="887c7440aaa8e044" data-backend-primary-type-id=""><div class="cover"><a class="article-cover-link" href="/winners-announcement-of-european-union-prize-for-the-2026-eumies-awards.htm" target="_blank" rel="noopener" aria-label="2026年坿¯å¥æç»è·å¥ååå ¬å¸"><img src="https://oss.gooood.cn/uploads/2026/04/01-winners-announcement-of-european-union-prize-for-the-2026-eumies-awards-472x303.jpg" srcset="https://oss.gooood.cn/uploads/2026/04/01-winners-announcement-of-european-union-prize-for-the-2026-eumies-awards-472x303.jpg 472w, https://oss.gooood.cn/uploads/2026/04/01-winners-announcement-of-european-union-prize-for-the-2026-eumies-awards-650x417.jpg 650w" sizes="(max-width: 767px) calc(100vw - 52px), 472px" alt="2026年坿¯å¥æç»è·å¥ååå ¬å¸" width="472" height="303" decoding="async" loading="lazy" fetchpriority="low"></a></div><div class="article-text"><div class="kicker" data-zh="èµè®¯" data-en="News">èµè®¯</div><h3><a href="/winners-announcement-of-european-union-prize-for-the-2026-eumies-awards.htm" target="_blank" rel="noopener" data-zh="2026年坿¯å¥æç»è·å¥ååå ¬å¸" data-en="WINNERS ANNOUNCEMENT OF EUROPEAN UNION PRIZE FOR THE 2026 EUMIES AWARDS">2026年坿¯å¥æç»è·å¥ååå ¬å¸</a></h3><div class="article-subtitle" data-zh="æ²åç½ç¦å±è§å®«è·å¾2026年建ç大å¥" data-en="æ²åç½ç¦å±è§å®«è·å¾2026年建ç大å¥">æ²åç½ç¦å±è§å®«è·å¾2026年建ç大å¥</div><div class="article-foot"><time datetime="2026-04-20T12:34:43">2026.04.20</time><span class="article-actions"><a href="#login" data-gooood-favorite-trigger="1" data-zh="æ¶è" data-en="Favorites">æ¶è</a><a href="#" data-zh="å享" data-en="Share">å享</a></span></div></div></article> 2425 </section> 2426 2427 <nav class="pagination" aria-label="å页导èª" data-v10-fragment="pagination" data-current-page="1" data-total-pages="21" data-page-one-url="/category/news" data-page-url-template="/category/news/page/__PAGE__" data-total-items="367"><span class="page-item disabled" aria-disabled="true">â</span><a class="active" href="/category/news">1</a><a href="/category/news/page/2">2</a><a href="/category/news/page/3">3</a><span class="page-item dots">...</span><a href="/category/news/page/21">21</a><a href="/category/news/page/2" aria-label="ä¸ä¸é¡µ">â</a><span class="page-count">1/21</span><form class="page-jump"><input type="number" min="1" max="21" placeholder="5" aria-label="跳转页ç "><button type="submit" data-zh="跳页" data-en="Go">跳页</button></form></nav> 2428 <section class="ad-embed page-bottom" data-v10-fragment="ad-34642" data-ad-position="页ç 䏿¹å¹¿å" data-wp-tag-id="34642" data-wp-term-slug="list_pagination_bottom" data-backend-ad-position="34642" data-backend-ad-source="dashboard.api.api-advert-adposition.php?slugName=list_pagination_bottom" data-backend-ad-status="connected" data-ad-item-count="1" data-ad-record-id="1485604" data-ad-record-ids="1485604" data-ad-slug="%e9%a1%b5%e7%a0%81%e4%b8%8b%e6%96%b9%e6%96%87%e5%ad%97%e5%b9%bf%e5%91%8a" data-ad-modified="" data-ad-title="页ç åºåæå广å" data-ad-href="/advertisement/%e9%a1%b5%e7%a0%81%e4%b8%8b%e6%96%b9%e6%96%87%e5%ad%97%e5%b9%bf%e5%91%8a" data-ad-source="legacy-api:list_pagination_bottom" data-ad-fingerprint="455c5dd4d0e41eb0" data-ad-set-fingerprint="674fcfc4d1839700" data-ad-source-fetched-at="2026-10-02T06:04:17.100Z" data-ad-cache-status="stale" data-backend-ad-content="acf.ad_content"><div data-ad-record-id="1485604" style="display:contents"><style>._b1{transition:all 0.2s ease}._b1:hover{background:#3584cc!important}._b2{transition:all 0.2s ease}._b2:hover{background:#0e3460!important}@media(max-width:600px){._br td{display:block!important;width:100%!important;padding:0 0 18px 0!important;box-sizing:border-box!important}._br td:last-child{padding-bottom:0!important}}</style> 2429<table class="_br" style="width: 100%; max-width: 1100px; margin: 56px auto 0 auto; border-collapse: collapse; border-spacing: 0;" border="0" width="100%" cellspacing="0" cellpadding="0"> 2430<tbody> 2431<tr> 2432<td style="padding: 0 0 0 0; box-sizing: border-box;" valign="middle" width="50%"><a class="_b1" style="display: block; width: 100%; padding: 56px 36px; background: #256eb8; color: #fff; text-align: center; text-decoration: none; border-radius: 0; box-sizing: border-box; font-size: 24px; font-weight: bold;" href="/category/jobs" target="_blank"> 2433<span style="font-size: 32px; display: block; line-height: 1.2;">â</span><span style="font-size: 24px; display: block; line-height: 1.4;">æ±èä¸æäºº</span><span style="font-size: 24px; display: block; line-height: 1.4;">ä¸è°·å¾·æè</span> 2434</a></td> 2435<td style="padding: 0 0 0 0; box-sizing: border-box;" valign="middle" width="50%"><a class="_b2" style="display: block; width: 100%; padding: 56px 36px; background: #174a80; color: #fff; text-align: center; text-decoration: none; border-radius: 0; box-sizing: border-box; font-size: 24px; font-weight: bold;" href="/ad-article" target="_blank"> 2436<span style="font-size: 32px; display: block; line-height: 1.2;">â</span><span style="font-size: 24px; display: block; line-height: 1.4;">ä¸ççº§ä¼ æ</span><span style="font-size: 24px; display: block; line-height: 1.4;">éè°·å¾·æ¨å¹¿</span> 2437</a></td> 2438</tr> 2439</tbody> 2440</table></div></section> 2441 </main> 2442 2443 <aside class="side"> 2444 <div class="sidebar"> 2445 <div class="panel" data-v10-fragment="sidebar-series"><div class="panel-head"><span data-zh="ææ°ä¸è¾" data-en="Latest Series">
2445ææ°ä¸è¾</span><a href="/category/series" data-zh="å ¨é¨ â" data-en="All â">å ¨é¨ â</a></div><a class="album" href="/everyone-beijing-city-library.htm" target="_blank" rel="noopener"><div class="cover"><img src="https://oss.gooood.cn/uploads/2026/09/everyonelibrary-%E6%8B%B7%E8%B4%9D-472x303.jpg" alt="æ¯ä¸ªäºº à å京åå¸å¾ä¹¦é¦" width="310" height="200" decoding="async" loading="lazy" fetchpriority="low"></div><div><b data-zh="æ¯ä¸ªäºº à å京åå¸å¾ä¹¦é¦" data-en="everyone à Beijing City Library">æ¯ä¸ªäºº à å京åå¸å¾ä¹¦é¦</b><span data-zh="ï¼æè§é¢ï¼ï¼å¨âä¸çæå¤§é è§ç©ºé´âéï¼ä»ä»¬è¿æ ·è¯´" data-en="In the âworldâs largest reading spaceâ, they sayâ¦â¦">ï¼æè§é¢ï¼ï¼å¨âä¸çæå¤§é è§ç©ºé´âéï¼ä»ä»¬è¿æ ·è¯´</span></div></a><a class="album" href="/office-fact-atelier-cns.htm" target="_blank" rel="noopener"><div class="cover"><img src="https://oss.gooood.cn/uploads/2026/09/00-office-fact-cns-%E6%8B%B7%E8%B4%9D-472x303.jpg" alt="OFFICEçç¸ä¸è¾ NO.64 - ç«æ¢ç¤¾" width="310" height="200" decoding="async" loading="lazy" fetchpriority="low"></div><div><b data-zh="OFFICEçç¸ä¸è¾ NO.64 - ç«æ¢ç¤¾" data-en="OFFICE FACT NO.64 - Atelier cnS">OFFICEçç¸ä¸è¾ NO.64 - ç«æ¢ç¤¾</b><span data-zh="建çå¸è¦è¿å ¥å ·ä½é®é¢ã" data-en="Architects must engage with specific issues.">建çå¸è¦è¿å ¥å ·ä½é®é¢ã</span></div></a><a class="album" href="/everyone-sanlitun.htm" target="_blank" rel="noopener"><div class="cover"><img src="https://oss.gooood.cn/uploads/2026/08/everyonesanliitun-472x303.jpg" alt="æ¯ä¸ªäºº à ä¸é屯" width="310" height="200" decoding="async" loading="lazy" fetchpriority="low"></div><div><b data-zh="æ¯ä¸ªäºº à ä¸é屯" data-en="everyone à Sanlitun">æ¯ä¸ªäºº à ä¸é屯</b><span data-zh="ï¼æè§é¢ï¼ï¼å½âæ½®æµå°æ âéä¸âæ¥å¸¸æ¸´æâ" data-en="When âtrendy landmarksâ meet âdaily desiresâ">ï¼æè§é¢ï¼ï¼å½âæ½®æµå°æ âéä¸âæ¥å¸¸æ¸´æâ</span></div></a></div> 2446 <div class="panel" data-v10-fragment="sidebar-week-hot"><div class="panel-head"><span data-zh="7 天æç" data-en="Most Popular in 7 Days">7 天æç</span></div><a class="hot" href="/the-long-necked-house-dream-home-makeover-2026-dragon-tv-by-not-a-studio.htm" target="_blank" rel="noopener"><div class="rank">01</div><div><b data-zh="䏿¹å«è§ãæ¢¦æ³æ¹é å®¶2026ãé¿èåçå®¶ï¼ç¦å»ºæ³å· / æ 设建ç" data-en="The Long-Necked House, Dream Home Makeover 2026 (Dragon TV) by Not A Studio">䏿¹å«è§ãæ¢¦æ³æ¹é å®¶2026ãé¿èåçå®¶ï¼ç¦å»ºæ³å· / æ 设建ç</b><span></span></div></a><a class="hot" href="/everyone-beijing-city-library.htm" target="_blank" rel="noopener"><div class="rank">02</div><div><b data-zh="æ¯ä¸ªäºº à å京åå¸å¾ä¹¦é¦" data-en="everyone à Beijing City Library">æ¯ä¸ªäºº à å京åå¸å¾ä¹¦é¦</b><span></span></div></a><a class="hot" href="/pavilia-farm-clubhouses-by-snohetta.htm" target="_blank" rel="noopener"><div class="rank">03</div><div><b data-zh="Pavilia Farm伿ï¼é¦æ¸¯ / Snøhetta" data-en="Pavilia Farm Clubhouses by Snøhetta">Pavilia Farm伿ï¼é¦æ¸¯ / Snøhetta</b><span></span></div></a><a class="hot" href="/xicheng-canal-landscape-opposite-parks-by-brearley-architects-urbanists-bau.htm" target="_blank" rel="noopener"><div class="rank">04</div><div><b data-zh="æ±é´é¡æ¾è¿æ²³å ¬åââ对æ¯å ¬åï¼æ±è / Brearley Architects + Urbanists (BAU)" data-en="XICHENG CANAL LANDSCAPE â Opposite Parks by Brearley Architects + Urbanists (BAU)">æ±é´é¡æ¾è¿æ²³å ¬åââ对æ¯å ¬åï¼æ±è / Brearley Architects + Urbanists (BAU)</b><span></span></div></a><a class="hot" href="/aranya-youyi-bay-community-regeneration-by-genarchitects.htm" target="_blank" rel="noopener"><div class="rank">05</div><div><b data-zh="é¿é£äºåè°æ¹¾ç¤¾åºæ´æ°ï¼ç§¦çå² / äºå»ºç" data-en="Aranya Youyi Bay Community Regeneration by genarchitects">é¿é£äºåè°æ¹¾ç¤¾åºæ´æ°ï¼ç§¦çå² / äºå»ºç</b><span></span></div></a></div> 2447 <div class="side-section pinned-jobs-section" hidden data-empty-state="no-pinned-jobs" data-v10-fragment="sidebar-pinned-jobs" data-rendered-count="0" data-source="wp/v2/jobs?categories=sidebar-top"><div class="side-section-title"><span class="side-title-main" data-zh="æè置顶" data-en="Featured Jobs">æè置顶</span> <a class="side-title-action" href="/job-service-info" target="_blank" rel="noopener" data-zh="è´ä¹°ç½®é¡¶ â" data-en="Buy Top â">è´ä¹°ç½®é¡¶ â</a></div><div class="side-jobs pinned"></div></div> 2448 <div class="side-section"> 2449 <div class="side-section-title"><span class="side-title-main" data-zh="ææ°å·¥ä½" data-en="Latest Jobs">ææ°å·¥ä½</span> <a class="side-title-action" href="/job-service-info" target="_blank" rel="noopener" data-zh="è´ä¹°æè â" data-en="Recruitment service â">è´ä¹°æè â</a></div> 2450 <div class="job-region-filter"><span data-zh="æå°åºæ¥ç ï¼" data-en="Browse by region: ">æå°åºæ¥ç ï¼</span><a href="/category/jobs" data-zh="å ¨é¨" data-en="All">å ¨é¨</a> | <a href="/category/jobs/northern" data-zh="åæ¹" data-en="Northern">åæ¹</a> | <a href="/category/jobs/yangtze-area" data-zh="é¿æ±" data-en="Yangtze Area">é¿æ±</a> | <a href="/category/jobs/southern" data-zh="åå" data-en="Southern">åå</a></div> 2451 <div class="side-jobs home-pinned" data-admin-setting="homepage_jobs_latest_range" data-default-count="70" data-v10-fragment="side-jobs" data-source="https://dashboard.gooood.cn/wp-json/gooood/v1/dashboard/settings#fresh" data-rendered-count="64" data-backend-count="177" data-configured-start="1" data-configured-end="64" data-configured-count="64"><a class="side-job" data-job-id="1731355" data-job-slug="job-mengarchitects" data-job-date="2026-09-30 14:18:34" data-job-modified="2026-09-30T14:18:34" data-job-modified-source="wp/v2/jobs" data-job-fingerprint="98946f6bf5d40a27" href="/job-mengarchitects.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/09/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2-%E5%AD%9F%E5%BB%BA%E6%B0%91.jpg" alt="ï¼æ·±å³ï¼MENG ARCHITECTS å建æ°å¢é â 建çè®¾è®¡å¸ / å©çç ç©¶å / åå¡ç»ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼æ·±å³ï¼MENG ARCHITECTS å建æ°å¢é â 建çè®¾è®¡å¸ / å©çç ç©¶å / åå¡ç»ç" data-en="ï¼æ·±å³ï¼MENG ARCHITECTS å建æ°å¢é â 建çè®¾è®¡å¸ / å©çç ç©¶å / åå¡ç»ç">ï¼æ·±å³ï¼MENG ARCHITECTS å建æ°å¢é â 建çè®¾è®¡å¸ / å©çç ç©¶å / åå¡ç»ç</b><span></span></div></a><a class="side-job" data-job-id="940077" data-job-slug="job-plat-asia" data-job-date="2026-09-30 09:00:07" data-job-modified="2026-09-30T09:18:25" data-job-modified-source="wp/v2/jobs" data-job-fingerprint="6c2923cb798ae757" href="/job-plat-asia.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2023/02/Plat_asia.jpg" alt="ï¼å京ï¼PLAT ASIA - èµæ·±å»ºçå¸ / ä¸çº§å»ºçå¸ / å©ç建çå¸ / 建ç/æ¯è§å®ä¹ ç / æ¯è§è®¾è®¡å¸" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼å京ï¼PLAT ASIA - èµæ·±å»ºçå¸ / ä¸çº§å»ºçå¸ / å©ç建çå¸ / 建ç/æ¯è§å®ä¹ ç / æ¯è§è®¾è®¡å¸" data-en="ï¼å京ï¼PLAT ASIA - èµæ·±å»ºçå¸ / ä¸çº§å»ºçå¸ / å©ç建çå¸ / 建ç/æ¯è§å®ä¹ ç / æ¯è§è®¾è®¡å¸">ï¼å京ï¼PLAT ASIA - èµæ·±å»ºçå¸ / ä¸çº§å»ºçå¸ / å©ç建çå¸ / 建ç/æ¯è§å®ä¹ ç / æ¯è§è®¾è®¡å¸</b><span></span></div></a><a class="side-job" data-job-id="1730871" data-job-slug="job-cloud-seven" data-job-date="2026-09-28 18:00:23" data-job-modified="2026-09-29T08:49:41" data-job-modified-source="wp/v2/jobs" data-job-fingerprint="71c0a21741a5b3f3" href="/job-cloud-seven.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/09/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2%E6%A8%A1%E6%9D%BF-wui.jpg" alt="ï¼ä¸æµ·ï¼CLOUD7 äºä¸å»ºç - AI 设
2451è®¡å¸ / ä¸çº§å»ºçè®¾è®¡å¸ / å级建çè®¾è®¡å¸ / 室å
设计å¸" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼CLOUD7 äºä¸å»ºç - AI è®¾è®¡å¸ / ä¸çº§å»ºçè®¾è®¡å¸ / å级建çè®¾è®¡å¸ / 室å
设计å¸" data-en="ï¼ä¸æµ·ï¼CLOUD7 äºä¸å»ºç - AI è®¾è®¡å¸ / ä¸çº§å»ºçè®¾è®¡å¸ / å级建çè®¾è®¡å¸ / 室å
设计å¸">ï¼ä¸æµ·ï¼CLOUD7 äºä¸å»ºç - AI è®¾è®¡å¸ / ä¸çº§å»ºçè®¾è®¡å¸ / å级建çè®¾è®¡å¸ / 室å
设计å¸</b><span></span></div></a><a class="side-job" data-job-id="1500188" data-job-slug="job-bai-design-international" data-job-date="2026-09-28 09:50:23" data-job-modified="2026-09-29T09:26:42" data-job-modified-source="wp/v2/jobs" data-job-fingerprint="f2a1208046e8df44" href="/job-bai-design-international.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2024/07/%E7%BD%91%E7%AB%99%E6%8B%9B%E8%81%98%E6%96%87%E7%AB%A0%E6%A8%A1%E6%9D%BF-enn.jpg" alt="ï¼å京ï¼è±å½æ°å
¸å½é
建ç - èµæ·±å»ºçå¸ / 建çå¸ / å©ç建çå¸&åºå±æ¯ä¸ç / å®ä¹ ç / 室å
建çå¸ / åªä½ä¸å" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼å京ï¼è±å½æ°å
¸å½é
建ç - èµæ·±å»ºçå¸ / 建çå¸ / å©ç建çå¸&åºå±æ¯ä¸ç / å®ä¹ ç / 室å
建çå¸ / åªä½ä¸å" data-en="ï¼å京ï¼è±å½æ°å
¸å½é
建ç - èµæ·±å»ºçå¸ / 建çå¸ / å©ç建çå¸&åºå±æ¯ä¸ç / å®ä¹ ç / 室å
建çå¸ / åªä½ä¸å">ï¼å京ï¼è±å½æ°å
¸å½é
建ç - èµæ·±å»ºçå¸ / 建çå¸ / å©ç建çå¸&åºå±æ¯ä¸ç / å®ä¹ ç / 室å
建çå¸ / åªä½ä¸å</b><span></span></div></a><a class="side-job" data-job-id="1636057" data-job-slug="latest-20-companies-recruit-information-10" data-job-date="2026-09-27 08:00:22" data-job-modified="2026-09-28T09:33:42" data-job-modified-source="wp/v2/jobs" data-job-fingerprint="5148f183aa7f71cf" href="/latest-20-companies-recruit-information-10.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2025/11/jobs-2-472x303.jpg" alt="æè¿æåªäºå¥½å·¥ä½ï¼è°·å¾·ææ°20å®¶æèä¿¡æ¯æ±æ»" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="æè¿æåªäºå¥½å·¥ä½ï¼è°·å¾·ææ°20å®¶æèä¿¡æ¯æ±æ»" data-en="æè¿æåªäºå¥½å·¥ä½ï¼è°·å¾·ææ°20å®¶æèä¿¡æ¯æ±æ»">æè¿æåªäºå¥½å·¥ä½ï¼è°·å¾·ææ°20å®¶æèä¿¡æ¯æ±æ»</b><span></span></div></a><a class="side-job" data-job-id="1729522" data-job-slug="job-youngdesign" data-job-date="2026-09-22 17:07:53" data-job-modified="2026-09-22T17:07:53" data-job-modified-source="wp/v2/jobs" data-job-fingerprint="47c2f56eec3cf532" href="/job-youngdesign.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/09/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2%E6%A8%A1%E6%9D%BF-%E6%9C%AC%E6%A0%B7%E8%AE%BE%E8%AE%A1.jpg" alt="ï¼æ¦æ±ï¼æ¬æ ·è®¾è®¡ YOUNGDESIGN - 设计æ»ç / 主æ¡è®¾è®¡å¸ / 空é´å©ç设计å¸" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼æ¦æ±ï¼æ¬æ ·è®¾è®¡ YOUNGDESIGN - 设计æ»ç / 主æ¡è®¾è®¡å¸ / 空é´å©ç设计å¸" data-en="ï¼æ¦æ±ï¼æ¬æ ·è®¾è®¡ YOUNGDESIGN - 设计æ»ç / 主æ¡è®¾è®¡å¸ / 空é´å©ç设计å¸">ï¼æ¦æ±ï¼æ¬æ ·è®¾è®¡ YOUNGDESIGN - 设计æ»ç / 主æ¡è®¾è®¡å¸ / 空é´å©ç设计å¸</b><span></span></div></a><a class="side-job" data-job-id="1617081" data-job-slug="job-airwall-architecture-office" data-job-date="2026-09-07 03:30:39" data-job-modified="2026-09-07T16:44:29" data-job-modified-source="wp/v2/jobs" data-job-fingerprint="6e3eb5b0f343c534" href="/job-airwall-architecture-office.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2025/09/2.jpg" alt="ï¼éåºï¼ç©ºæ°å¢å»ºçå·¥ä½å®¤ AIRWALL ARCHITECTURE OFFICE - æ¹æ¡è®¾è®¡å¸ / å©çè®¾è®¡å¸ / 设计å®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼éåºï¼ç©ºæ°å¢å»ºçå·¥ä½å®¤ AIRWALL ARCHITECTURE OFFICE - æ¹æ¡è®¾è®¡å¸ / å©çè®¾è®¡å¸ / 设计å®ä¹ ç" data-en="ï¼éåºï¼ç©ºæ°å¢å»ºçå·¥ä½å®¤ AIRWALL ARCHITECTURE OFFICE - æ¹æ¡è®¾è®¡å¸ / å©çè®¾è®¡å¸ / 设计å®ä¹ ç">ï¼éåºï¼ç©ºæ°å¢å»ºçå·¥ä½å®¤ AIRWALL ARCHITECTURE OFFICE - æ¹æ¡è®¾è®¡å¸ / å©çè®¾è®¡å¸ / 设计å®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="1610416" data-job-slug="job-voice-architecture-lab" data-job-date="2026-09-04 14:35:49" data-job-modified="2026-09-04T14:43:19" data-job-modified-source="wp/v2/jobs" data-job-fingerprint="a2331a8b33061927" href="/job-voice-architecture-lab.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2025/08/VAL-%E7%BD%91%E7%AB%99%E6%8B%9B%E8%81%98%E6%96%87%E7%AB%A0%E5%B0%81%E9%9D%A2.jpg" alt="ï¼ä¸æµ·ï¼Voice Architecture Lab - AI è®¾è®¡å¸ / ä¸çº§å»ºçè®¾è®¡å¸ / å级建çè®¾è®¡å¸ / 室å
§è®¾è®¡å¸" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼Voice Architecture Lab - AI è®¾è®¡å¸ / ä¸çº§å»ºçè®¾è®¡å¸ / å级建çè®¾è®¡å¸ / 室å
§è®¾è®¡å¸" data-en="ï¼ä¸æµ·ï¼Voice Architecture Lab - AI è®¾è®¡å¸ / ä¸çº§å»ºçè®¾è®¡å¸ / å级建çè®¾è®¡å¸ / 室å
§è®¾è®¡å¸">ï¼ä¸æµ·ï¼Voice Architecture Lab - AI è®¾è®¡å¸ / ä¸çº§å»ºçè®¾è®¡å¸ / å级建çè®¾è®¡å¸ / 室å
§è®¾è®¡å¸</b><span></span></div></a><a class="side-job" data-job-id="1408038" data-job-slug="job-jz-lab" data-job-date="2026-09-03 14:00:52" data-job-modified="2026-09-03T14:32:58" data-job-modified-source="wp/v2/jobs" data-job-fingerprint="217caf0f2bd0933b" href="/job-jz-lab.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2024/10/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2%E6%A8%A1%E6%9D%BF-mfr.jpg" alt="ï¼æé½ï¼ä»æ¢åä¸è®¾è®¡ - åä¸è´è´£äºº / 项ç®è´è´£äºº / è®¾è®¡å¸ / å©çè®¾è®¡å¸ / å®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼æé½ï¼ä»æ¢åä¸è®¾è®¡ - åä¸è´è´£äºº / 项ç®è´è´£äºº / è®¾è®¡å¸ / å©çè®¾è®¡å¸ / å®ä¹ ç" data-en="ï¼æé½ï¼ä»æ¢åä¸è®¾è®¡ - åä¸è´è´£äºº / 项ç®è´è´£äºº / è®¾è®¡å¸ / å©çè®¾è®¡å¸ / å®ä¹ ç">ï¼æé½ï¼ä»æ¢åä¸è®¾è®¡ - åä¸è´è´£äºº / 项ç®è´è´£äºº / è®¾è®¡å¸ / å©çè®¾è®¡å¸ / å®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="1618237" data-job-slug="job-euv" data-job-date="2026-09-02 16:20:44" data-job-modified="2026-09-02T16:17:22" data-job-modified-source="wp/v2/jobs" data-job-fingerprint="f47b1a9d4bf86d79" href="/job-euv.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2025/09/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2%E6%A8%A1%E6%9D%BF-s7v.jpg" alt="ï¼æ·±å³ï¼æ·±å³æå 设计ï¼E+UV å·¥ä½å®¤ï¼- 建çå¸ / å©ç建çå¸ / å®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼æ·±å³ï¼æ·±å³æå 设计ï¼E+UV å·¥ä½å®¤ï¼- 建çå¸ / å©ç建çå¸ / å®ä¹ ç" data-en="ï¼æ·±å³ï¼æ·±å³æå 设计ï¼E+UV å·¥ä½å®¤ï¼- 建çå¸ / å©ç建çå¸ / å®ä¹ ç">ï¼æ·±å³ï¼æ·±å³æå 设计ï¼E+UV å·¥ä½å®¤ï¼- 建çå¸ / å©ç建çå¸ / å®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="1154247" data-job-slug="job-pha" data-job-date="2026-09-02 16:00:41" data-job-modified="2026-09-17T12:02:30" data-job-modified-source="wp/v2/jobs" data-job-fingerprint="4b8473dee3e07622" href="/job-pha.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2025/07/%E6%B9%83%E6%98%82%E5%9B%BD%E9%99%85%E8%AE%BE%E8%AE%A1-%E6%9B%B4%E6%96%B00422.jpg" alt="ï¼æ·±å³ï¼PH Alpha Design æ¹æå½é
建çè®¾è®¡é¡¾é®æéå
¬å¸ â é«çº§å»ºçè®¾è®¡å¸ / 建çè®¾è®¡å¸ / 主æ¡è®¾è®¡å¸ / 室å
è®¾è®¡å¸ / åå¡ç»ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼æ·±å³ï¼PH Alpha Design æ¹æå½é
建çè®¾è®¡é¡¾é®æéå
¬å¸ â é«çº§å»ºçè®¾è®¡å¸ / 建çè®¾è®¡å¸ / 主æ¡è®¾è®¡å¸ / 室å
è®¾è®¡å¸ / åå¡ç»ç" data-en="ï¼æ·±å³ï¼PH Alpha Design æ¹æå½é
建çè®¾è®¡é¡¾é®æéå
¬å¸ â é«çº§å»ºçè®¾è®¡å¸ / 建çè®¾è®¡å¸ / 主æ¡è®¾è®¡å¸ / 室å
è®¾è®¡å¸ / åå¡ç»ç">ï¼æ·±å³ï¼PH Alpha Design æ¹æå½é
建çè®¾è®¡é¡¾é®æéå
¬å¸ â é«çº§å»ºçè®¾è®¡å¸ / 建çè®¾è®¡å¸ / 主æ¡è®¾è®¡å¸ / 室å
è®¾è®¡å¸ / åå¡ç»ç</b><span></span></div></a><a class="side-job" data-job-id="1558304" data-job-slug="job-shiji" data-job-date="2026-09-01 14:34:47" data-job-modified="2026-09-01T15:00:51" data-job-modified-source="wp/v2/jobs" data-job-fingerprint="8e5ebc912a4e1255" href="/job-shiji.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2025/02/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2%E6%A8%A1%E6%9D%BF-%E6%8B%BE%E9%9B%86.jpg" alt="ï¼ä¸æµ·ï¼æ¾é建ç - 项ç®è®¾è®¡å¸ / åå¡ä¸åªä½ä¸å / åä¸è½¯è£
è®¾è®¡å¸ / å©çè®¾è®¡å¸ / å®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼æ¾é建ç - 项ç®è®¾è®¡å¸ / åå¡ä¸åªä½ä¸å / åä¸è½¯è£
è®¾è®¡å¸ / å©çè®¾è®¡å¸ / å®ä¹ ç" data-en="ï¼ä¸æµ·ï¼æ¾é建ç - 项ç®è®¾è®¡å¸ / åå¡ä¸åªä½ä¸å / åä¸è½¯è£
è®¾è®¡å¸ / å©çè®¾è®¡å¸ / å®ä¹ ç">ï¼ä¸æµ·ï¼æ¾é建ç - 项ç®è®¾è®¡å¸ / åå¡ä¸åªä½ä¸å / åä¸è½¯è£
è®¾è®¡å¸ / å©çè®¾è®¡å¸ / å®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="896685" data-job-slug="job-rlphk" data-job-date="2026-08-31 16:00:36" data-job-modified="2026-08-31T16:39:38" data-job-modified-source="wp/v2/jobs" data-job-fingerprint="a24fba236603002f" href="/job-rlphk.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2025/10/%E5%90%95%E5%85%83%E7%A5%A5-%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2.jpg" alt="ï¼ä¸æµ·/æ·±å³/广å·ï¼åå
祥建çå¸äºå¡æ Ronald Lu & Partners - 建çå¸ / é«çº§å®¤å
è®¾è®¡å¸ / å©ç建çå¸ / å®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·/æ·±å³/广å·ï¼åå
祥建çå¸äºå¡æ Ronald Lu & Partners - 建çå¸ / é«çº§å®¤å
è®¾è®¡å¸ / å©ç建çå¸ / å®ä¹ ç" data-en="ï¼ä¸æµ·/æ·±å³/广å·ï¼åå
祥建çå¸äºå¡æ Ronald Lu & Partners - 建çå¸ / é«çº§å®¤å
è®¾è®¡å¸ / å©ç建çå¸ / å®ä¹ ç">ï¼ä¸æµ·/æ·±å³/广å·ï¼åå
祥建çå¸äºå¡æ Ronald Lu & Partners - 建çå¸ / é«çº§å®¤å
è®¾è®¡å¸ / å©ç建çå¸ / å®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="1719478" data-job-slug="latest-20-companies-recruit-information-20" data-job-date="2026-08-30 16:00:19" data-job-modified="2026-08-28T18:11:46" data-job-modified-source="wp/v2/jobs" data-job-fingerprint="0ea7945cf5d77360" href="/latest-20-companies-recruit-information-20.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/08/jobs-2-650x417-20%E5%AE%B6%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2.jpg" alt="æè¿æåªäºå¥½å·¥ä½ï¼è°·å¾·ææ°20å®¶æèä¿¡æ¯æ±æ»" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="æè¿æåªäºå¥½å·¥ä½ï¼è°·å¾·ææ°20å®¶æèä¿¡æ¯æ±æ»" data-en="æè¿æåªäºå¥½å·¥ä½ï¼è°·å¾·ææ°20å®¶æèä¿¡æ¯æ±æ»">æè¿æåªäºå¥½å·¥ä½ï¼è°·å¾·ææ°20å®¶æèä¿¡æ¯æ±æ»</b><span></span></div></a><a class="side-job" data-job-id="1721956" data-job-slug="job-callisonrtkl" data-job-date="2026-08-28 15:20:51" data-job-modified="2026-08-28T15:20:51" data-job-modified-source="wp/v2/jobs" data-job-fingerprint="f7a4e0959de9c409" href="/job-callisonrtkl.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/08/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2%E6%A8%A1%E6%9D%BF-%E5%87%AF%E8%B0%9B%E6%80%9D.jpg" alt="ï¼ä¸æµ·/å京ï¼CallisonRTKL - å级建çè®¾è®¡å¸ / èµæ·±å»ºçè®¾è®¡å¸ / å级室å
è®¾è®¡å¸ / èµæ·±å®¤å
设计å¸" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·/å京ï¼CallisonRTKL - å级建çè®¾è®¡å¸ / èµæ·±å»ºçè®¾è®¡å¸ / å级室å
è®¾è®¡å¸ / èµæ·±å®¤å
设计å¸" data-en="ï¼ä¸æµ·/å京ï¼CallisonRTKL - å级建çè®¾è®¡å¸ / èµæ·±å»ºçè®¾è®¡å¸ / å级室å
è®¾è®¡å¸ / èµæ·±å®¤å
设计å¸">ï¼ä¸æµ·/å京ï¼CallisonRTKL - å级建çè®¾è®¡å¸ / èµæ·±å»ºçè®¾è®¡å¸ / å级室å
è®¾è®¡å¸ / èµæ·±å®¤å
设计å¸</b><span></span></div></a><a class="side-job" data-job-id="980925" data-job-slug="job-dnd" data-job-date="2026-08-25 13:50:24" data-job-modified="2026-08-25T14:38:50" data-job-modified-source="wp/v2/jobs" data-job-fingerprint="17d77fb8b99e04fc" href="/job-dnd.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2023/08/zhijing.jpg" alt="ï¼å京ï¼ç´å¾åäºè®¾è®¡ - 设计å²ä½åæ¶åå®ä¹ ç弿¾ / 空é´è®¾è®¡ / åäºç ç©¶å / å¹³é¢/æ°åªä½è®¾è®¡å¸ / 项ç®ç®¡ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼å京ï¼ç´å¾åäºè®¾è®¡ - 设计å²ä½åæ¶åå®ä¹ ç弿¾ / 空é´è®¾è®¡ / åäºç ç©¶å / å¹³é¢/æ°åªä½è®¾è®¡å¸ / 项ç®ç®¡ç" data-en="ï¼å京ï¼ç´å¾åäºè®¾è®¡ - 设计å²ä½åæ¶åå®ä¹ ç弿¾ / 空é´è®¾è®¡ / åäºç ç©¶å / å¹³é¢/æ°åªä½è®¾è®¡å¸ / 项ç®ç®¡ç">ï¼å京ï¼ç´å¾åäºè®¾è®¡ - 设计å²ä½åæ¶åå®ä¹ ç弿¾ / 空é´è®¾è®¡ / åäºç ç©¶å / å¹³é¢/æ°åªä½è®¾è®¡å¸ / 项ç®ç®¡ç</b><span></span></div></a><a class="side-job" data-job-id="714154" data-job-slug="job-oli" data-job-date="2026-08-25 08:50:47" data-job-modified="2026-08-25T09:19:28" data-job-modified-source="wp/v2/jobs" data-job-fingerprint="dc5cacbfc7c5d0cb" href="/job-oli.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2022/11/job-template_350-%E6%8B%B7%E8%B4%9D.jpg" alt="ï¼ä¸æµ·ï¼ç¾å½OLI建ç设计äºå¡æ - 项ç®ç»ç / 项ç®å»ºçå¸ / é©»åºå»ºçå¸ / 建çè®¾è®¡å¸ / å¹³é¢/å±é设计å¸" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼ç¾å½OLI建ç设计äºå¡æ - 项ç®ç»ç / 项ç®å»ºçå¸ / é©»åºå»ºçå¸ / 建çè®¾è®¡å¸ / å¹³é¢/å±é设计å¸" data-en="ï¼ä¸æµ·ï¼ç¾å½OLI建ç设计äºå¡æ - 项ç®ç»ç / 项ç®å»ºçå¸ / é©»åºå»ºçå¸ / 建çè®¾è®¡å¸ / å¹³é¢/å±é设计å¸">ï¼ä¸æµ·ï¼ç¾å½OLI建ç设计äºå¡æ - 项ç®ç»ç / 项ç®å»ºçå¸ / é©»åºå»ºçå¸ / 建çè®¾è®¡å¸ / å¹³é¢/å±é设计å¸</b><span></span></div></a><a class="side-job" data-job-id="1352914" data-job-slug="job-aura" data-job-date="2026-08-23 10:00:06" data-job-modified="2026-08-18T18:27:52" data-job-modified-source="wp/v2/jobs" data-job-fingerprint="bbe48c732d1da0d7" href="/job-aura.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2023/03
2451/job-template_350-%E6%8B%B7%E8%B4%9D.jpg" alt="ï¼ä¸æµ·ï¼AURAåå¸è§å忝è§è®¾è®¡äºå¡æ - 项ç®ç»è®¾è®¡æ»ç / ä¸çº§æ¹æ¡è®¾è®¡å¸ / åçº§æ¹æ¡è®¾è®¡å¸ / æ½å·¥å¾è®¾è®¡å¸ /æ¯è§å®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼AURAåå¸è§å忝è§è®¾è®¡äºå¡æ - 项ç®ç»è®¾è®¡æ»ç / ä¸çº§æ¹æ¡è®¾è®¡å¸ / åçº§æ¹æ¡è®¾è®¡å¸ / æ½å·¥å¾è®¾è®¡å¸ /æ¯è§å®ä¹ ç" data-en="ï¼ä¸æµ·ï¼AURAåå¸è§å忝è§è®¾è®¡äºå¡æ - 项ç®ç»è®¾è®¡æ»ç / ä¸çº§æ¹æ¡è®¾è®¡å¸ / åçº§æ¹æ¡è®¾è®¡å¸ / æ½å·¥å¾è®¾è®¡å¸ /æ¯è§å®ä¹ ç">ï¼ä¸æµ·ï¼AURAåå¸è§å忝è§è®¾è®¡äºå¡æ - 项ç®ç»è®¾è®¡æ»ç / ä¸çº§æ¹æ¡è®¾è®¡å¸ / åçº§æ¹æ¡è®¾è®¡å¸ / æ½å·¥å¾è®¾è®¡å¸ /æ¯è§å®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="1717988" data-job-slug="job-ai-planetworks" data-job-date="2026-08-21 17:19:57" data-job-modified="" data-job-modified-source="" data-job-fingerprint="b430a14acf99dde6" href="/job-ai-planetworks.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/08/AI-planetworks%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2.jpg" alt="ï¼ä¸æµ·ï¼AI Planetworks䏿µ·å·¥ä½å®¤ - å级建çè®¾è®¡å¸ / ä¸çº§å»ºçå¸" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼AI Planetworks䏿µ·å·¥ä½å®¤ - å级建çè®¾è®¡å¸ / ä¸çº§å»ºçå¸" data-en="ï¼ä¸æµ·ï¼AI Planetworks䏿µ·å·¥ä½å®¤ - å级建çè®¾è®¡å¸ / ä¸çº§å»ºçå¸">ï¼ä¸æµ·ï¼AI Planetworks䏿µ·å·¥ä½å®¤ - å级建çè®¾è®¡å¸ / ä¸çº§å»ºçå¸</b><span></span></div></a><a class="side-job" data-job-id="1614460" data-job-slug="job-hbaarchitecture" data-job-date="2026-08-17 14:00:53" data-job-modified="" data-job-modified-source="" data-job-fingerprint="36d566e13a29b0ed" href="/job-hbaarchitecture.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2025/08/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2HBA.jpg" alt="ï¼ä¸æµ·ï¼HBA Architecture - èµæ·±é¡¹ç®ç»ç / èµæ·±å»ºçè§åå¸ / èµæ·±å»ºçè®¾è®¡å¸ / å塿å±ç»ç / å®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼HBA Architecture - èµæ·±é¡¹ç®ç»ç / èµæ·±å»ºçè§åå¸ / èµæ·±å»ºçè®¾è®¡å¸ / å塿å±ç»ç / å®ä¹ ç" data-en="ï¼ä¸æµ·ï¼HBA Architecture - èµæ·±é¡¹ç®ç»ç / èµæ·±å»ºçè§åå¸ / èµæ·±å»ºçè®¾è®¡å¸ / å塿å±ç»ç / å®ä¹ ç">ï¼ä¸æµ·ï¼HBA Architecture - èµæ·±é¡¹ç®ç»ç / èµæ·±å»ºçè§åå¸ / èµæ·±å»ºçè®¾è®¡å¸ / å塿å±ç»ç / å®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="927974" data-job-slug="job-wonderlabs" data-job-date="2026-08-07 18:00:14" data-job-modified="" data-job-modified-source="" data-job-fingerprint="00a22fbfc92cd763" href="/job-wonderlabs.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2022/10/wonderlabs-472x303.jpg" alt="ï¼ä¸æµ·ï¼Wonderlabs - 3Då»ºæ¨¡è®¾è®¡å¸ / è£
ç½®&å±è§å±ç¤ºè®¾è®¡å¸ / å¹³é¢è®¾è®¡å¸&çé¢è®¾è®¡æ¹å" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼Wonderlabs - 3Då»ºæ¨¡è®¾è®¡å¸ / è£
ç½®&å±è§å±ç¤ºè®¾è®¡å¸ / å¹³é¢è®¾è®¡å¸&çé¢è®¾è®¡æ¹å" data-en="ï¼ä¸æµ·ï¼Wonderlabs - 3Då»ºæ¨¡è®¾è®¡å¸ / è£
ç½®&å±è§å±ç¤ºè®¾è®¡å¸ / å¹³é¢è®¾è®¡å¸&çé¢è®¾è®¡æ¹å">ï¼ä¸æµ·ï¼Wonderlabs - 3Då»ºæ¨¡è®¾è®¡å¸ / è£
ç½®&å±è§å±ç¤ºè®¾è®¡å¸ / å¹³é¢è®¾è®¡å¸&çé¢è®¾è®¡æ¹å</b><span></span></div></a><a class="side-job" data-job-id="1339105" data-job-slug="job-martha-schwartz-partners" data-job-date="2026-08-07 17:00:44" data-job-modified="" data-job-modified-source="" data-job-fingerprint="5da21036ee8667aa" href="/job-martha-schwartz-partners.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2023/01/martha-472x303.jpg" alt="ï¼ä¸æµ·ï¼ ç
2451èæ½ç¦è¨ååä¼äººäºå¡æ Martha Schwartz Partners â é«çº§æ¯è§å»ºçå¸ Senior Landscape Designer / æ¯è§å»ºçå¸ Landscape Designer" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼ çèæ½ç¦è¨ååä¼äººäºå¡æ Martha Schwartz Partners â é«çº§æ¯è§å»ºçå¸ Senior Landscape Designer / æ¯è§å»ºçå¸ Landscape Designer" data-en="ï¼ä¸æµ·ï¼ çèæ½ç¦è¨ååä¼äººäºå¡æ Martha Schwartz Partners â é«çº§æ¯è§å»ºçå¸ Senior Landscape Designer / æ¯è§å»ºçå¸ Landscape Designer">ï¼ä¸æµ·ï¼ çèæ½ç¦è¨ååä¼äººäºå¡æ Martha Schwartz Partners â é«çº§æ¯è§å»ºçå¸ Senior Landscape Designer / æ¯è§å»ºçå¸ Landscape Designer</b><span></span></div></a><a class="side-job" data-job-id="1716293" data-job-slug="job-hdg-group" data-job-date="2026-08-07 14:01:20" data-job-modified="" data-job-modified-source="" data-job-fingerprint="51067fb3b73ae02f" href="/job-hdg-group.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/08/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2-%E8%89%BE%E6%B4%BE%E6%96%AF.jpg" alt="ï¼å京ï¼åäº¬è¾æ´¾æ¯å±è§å±ç¤ºæå¡æéå
¬å¸ - 软è£
è®¾è®¡å¸ / éåè®¾è®¡å¸ / éè´å / é«çº§å®¤å
设计å¸" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼å京ï¼åäº¬è¾æ´¾æ¯å±è§å±ç¤ºæå¡æéå
¬å¸ - 软è£
è®¾è®¡å¸ / éåè®¾è®¡å¸ / éè´å / é«çº§å®¤å
设计å¸" data-en="ï¼å京ï¼åäº¬è¾æ´¾æ¯å±è§å±ç¤ºæå¡æéå
¬å¸ - 软è£
è®¾è®¡å¸ / éåè®¾è®¡å¸ / éè´å / é«çº§å®¤å
设计å¸">ï¼å京ï¼åäº¬è¾æ´¾æ¯å±è§å±ç¤ºæå¡æéå
¬å¸ - 软è£
è®¾è®¡å¸ / éåè®¾è®¡å¸ / éè´å / é«çº§å®¤å
设计å¸</b><span></span></div></a><a class="side-job" data-job-id="1714973" data-job-slug="job-qiu" data-job-date="2026-08-05 08:45:54" data-job-modified="" data-job-modified-source="" data-job-fingerprint="2c29068dd289e6c1" href="/job-qiu.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/08/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2-Q
2451IU-w77.jpg" alt="ï¼æ·±å³ï¼è±å½Quality Innovation Unitedæ·±å³åå
¬å¸ - 建çè®¾è®¡å¸ / èµæ·±å»ºçè®¾è®¡å¸ / 设计å®ä¹ ç / 室å
设计å¸ï¼æææ»¡ï¼" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼æ·±å³ï¼è±å½Quality Innovation Unitedæ·±å³åå
¬å¸ - 建çè®¾è®¡å¸ / èµæ·±å»ºçè®¾è®¡å¸ / 设计å®ä¹ ç / 室å
设计å¸ï¼æææ»¡ï¼" data-en="ï¼æ·±å³ï¼è±å½Quality Innovation Unitedæ·±å³åå
¬å¸ - 建çè®¾è®¡å¸ / èµæ·±å»ºçè®¾è®¡å¸ / 设计å®ä¹ ç / 室å
设计å¸ï¼æææ»¡ï¼">ï¼æ·±å³ï¼è±å½Quality Innovation Unitedæ·±å³åå
¬å¸ - 建çè®¾è®¡å¸ / èµæ·±å»ºçè®¾è®¡å¸ / 设计å®ä¹ ç / 室å
设计å¸ï¼æææ»¡ï¼</b><span></span></div></a><a class="side-job" data-job-id="1714288" data-job-slug="job-landtek-group" data-job-date="2026-07-31 17:00:21" data-job-modified="" data-job-modified-source="" data-job-fingerprint="f768aa081dc97034" href="/job-landtek-group.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/07/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2-%E9%A3%8E%E7%89%A9%E8%90%A5%E9%80%A0-8gl.jpg" alt="ï¼å¹¿å·ï¼é£ç©è¥é LANDTEK GROUP - æ¯è§è®¾è®¡å¸ / æ¤ç©è®¾è®¡å¸ / åçè¿è¥ / å®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼å¹¿å·ï¼é£ç©è¥é LANDTEK GROUP - æ¯è§è®¾è®¡å¸ / æ¤ç©è®¾è®¡å¸ / åçè¿è¥ / å®ä¹ ç" data-en="ï¼å¹¿å·ï¼é£ç©è¥é LANDTEK GROUP - æ¯è§è®¾è®¡å¸ / æ¤ç©è®¾è®¡å¸ / åçè¿è¥ / å®ä¹ ç">ï¼å¹¿å·ï¼é£ç©è¥é LANDTEK GROUP - æ¯è§è®¾è®¡å¸ / æ¤ç©è®¾è®¡å¸ / åçè¿è¥ / å®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="1709760" data-job-slug="job-studio-kukannai" data-job-date="2026-07-31 10:59:11" data-job-modified="" data-job-modified-source="" data-job-fingerprint="2cc0e4fd09f20dc1" href="/job-studio-kukannai.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/07/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2-%E7%A9%BA%E9%97%B4%E9%87%8C.jpg" alt="ï¼ä¸æµ·ï¼ç©ºé´é建ç设计äºå¡æ â 项ç®å»ºçå¸ / 室å
è®¾è®¡å¸ / å®ä¹ çï¼å»ºç/室å
ï¼" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼ç©ºé´é建ç设计äºå¡æ â 项ç®å»ºçå¸ / 室å
è®¾è®¡å¸ / å®ä¹ çï¼å»ºç/室å
ï¼" data-en="ï¼ä¸æµ·ï¼ç©ºé´é建ç设计äºå¡æ â 项ç®å»ºçå¸ / 室å
è®¾è®¡å¸ / å®ä¹ çï¼å»ºç/室å
ï¼">ï¼ä¸æµ·ï¼ç©ºé´é建ç设计äºå¡æ â 项ç®å»ºçå¸ / 室å
è®¾è®¡å¸ / å®ä¹ çï¼å»ºç/室å
ï¼</b><span></span></div></a><a class="side-job" data-job-id="1270605" data-job-slug="job-topo-design" data-job-date="2026-07-28 16:40:58" data-job-modified="" data-job-modified-source="" data-job-fingerprint="b95606b81aff111c" href="/job-topo-design.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2022/05/0513-topo-472x303.jpg" alt="ï¼ä¸æµ·ï¼TOPO Design Group - æ¯è§è®¾è®¡å¸ / æ¯è§åæè®¾è®¡å¸ / æ¯è§å®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼TOPO Design Group - æ¯è§è®¾è®¡å¸ / æ¯è§åæè®¾è®¡å¸ / æ¯è§å®ä¹ ç" data-en="ï¼ä¸æµ·ï¼TOPO Design Group - æ¯è§è®¾è®¡å¸ / æ¯è§åæè®¾è®¡å¸ / æ¯è§å®ä¹ ç">ï¼ä¸æµ·ï¼TOPO Design Group - æ¯è§è®¾è®¡å¸ / æ¯è§åæè®¾è®¡å¸ / æ¯è§å®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="747401" data-job-slug="job-flo" data-job-date="2026-07-21 12:00:00" data-job-modified="" data-job-modified-source="" data-job-fingerprint="633e96e61f0d56b2" href="/job-flo.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2022/11/flo-472x303.jpg" alt="ï¼ä¸æµ·ï¼FLOæ¯è§è®¾è®¡äºå¡æ - 主å/èµæ·±æ¯è§è®¾è®¡å¸ / æ¯è§è®¾è®¡å¸ / 设计å®ä¹ ç / åå¡è¡æ¿å©ç / å©çæ½å·¥å¾è®¾è®¡å¸" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼FLOæ¯è§è®¾è®¡äºå¡æ - 主å/èµæ·±æ¯è§è®¾è®¡å¸ / æ¯è§è®¾è®¡å¸ / 设计å®ä¹ ç / åå¡è¡æ¿å©ç / å©çæ½å·¥å¾è®¾è®¡å¸" data-en="ï¼ä¸æµ·ï¼FLOæ¯è§è®¾è®¡äºå¡æ - 主å/èµæ·±æ¯è§è®¾è®¡å¸ / æ¯è§è®¾è®¡å¸ / 设计å®ä¹ ç / åå¡è¡æ¿å©ç / å©çæ½å·¥å¾è®¾è®¡å¸">ï¼ä¸æµ·ï¼FLOæ¯è§è®¾è®¡äºå¡æ - 主å/èµæ·±æ¯è§è®¾è®¡å¸ / æ¯è§è®¾è®¡å¸ / 设计å®ä¹ ç / åå¡è¡æ¿å©ç / å©çæ½å·¥å¾è®¾è®¡å¸</b><span></span></div></a><a class="side-job" data-job-id="418137" data-job-slug="job-way-studio" data-job-date="2026-07-21 10:30:04" data-job-modified="" data-job-modified-source="" data-job-fingerprint="5b716e3fd3c39c03" href="/job-way-studio.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2025/07/waystudio-2.jpg" alt="ï¼åäº¬ï¼æª/WAY Studio建ç设计ç ç©¶æ - 建çè®¾è®¡å¸ / å©ç设计å¸/åçº§è®¾è®¡å¸ / å®ä¹ ç / åå
¬å®¤è¡æ¿ä¸åå¡å©ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼åäº¬ï¼æª/WAY Studio建ç设计ç ç©¶æ - 建çè®¾è®¡å¸ / å©ç设计å¸/åçº§è®¾è®¡å¸ / å®ä¹ ç / åå
¬å®¤è¡æ¿ä¸åå¡å©ç" data-en="ï¼åäº¬ï¼æª/WAY Studio建ç设计ç ç©¶æ - 建çè®¾è®¡å¸ / å©ç设计å¸/åçº§è®¾è®¡å¸ / å®ä¹ ç / åå
¬å®¤è¡æ¿ä¸åå¡å©ç">ï¼åäº¬ï¼æª/WAY Studio建ç设计ç ç©¶æ - 建çè®¾è®¡å¸ / å©ç设计å¸/åçº§è®¾è®¡å¸ / å®ä¹ ç / åå
¬å®¤è¡æ¿ä¸åå¡å©ç</b><span></span></div></a><a class="side-job" data-job-id="1570854" data-job-slug="job-kokaistudios" data-job-date="2026-07-16 09:00:56" data-job-modified="" data-job-modified-source="" data-job-fingerprint="b850e5fbc0c06097" href="/job-kokaistudios.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2025/03/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2-kokai.jpg" alt="ï¼ä¸æµ·ï¼Kokaistudios - 室å
设计å¸ï¼åä¸/é
åºï¼" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼Kokaistudios - 室å
设计å¸ï¼åä¸/é
åºï¼" data-en="ï¼ä¸æµ·ï¼Kokaistudios - 室å
设计å¸ï¼åä¸/é
åºï¼">ï¼ä¸æµ·ï¼Kokaistudios - 室å
设计å¸ï¼åä¸/é
åºï¼</b><span></span></div></a><a class="side-job" data-job-id="4578" data-job-slug="job-kengo-kuma-and-associates" data-job-date="2026-07-15 10:00:00" data-job-modified="" data-job-modified-source="" data-job-fingerprint="c2006ec91d57b415" href="/job-kengo-kuma-and-associates.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/07/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2-%E9%9A%88%E7%A0%94%E5%90%BE.jpg" alt="ï¼å京ï¼éç å¾å»ºçé½å¸è®¾è®¡äºå¡æ - 设计管çç»ç¹ / å
¨è建çè
2451®¾è®¡å¸ / å®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼å京ï¼éç å¾å»ºçé½å¸è®¾è®¡äºå¡æ - 设计管çç»ç¹ / å
¨è建çè®¾è®¡å¸ / å®ä¹ ç" data-en="ï¼å京ï¼éç å¾å»ºçé½å¸è®¾è®¡äºå¡æ - 设计管çç»ç¹ / å
¨è建çè®¾è®¡å¸ / å®ä¹ ç">ï¼å京ï¼éç å¾å»ºçé½å¸è®¾è®¡äºå¡æ - 设计管çç»ç¹ / å
¨è建çè®¾è®¡å¸ / å®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="1023216" data-job-slug="job-pao" data-job-date="2026-07-14 12:00:13" data-job-modified="" data-job-modified-source="" data-job-fingerprint="08985529f292aa1d" href="/job-pao.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/07/PAO.jpg" alt="ï¼å京/广å·ï¼ä¼å»ºç PAO - 建çå¸ / å¸åºæ¿çç ç©¶è°æ¥å/ ç»æå·¥ç¨å¸ / 模åå产å建çè®¾è®¡å¸ / 室å
è£
修工ç¨å¸ / æºçµå·¥ç¨å¸ / å®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼å京/广å·ï¼ä¼å»ºç PAO - 建çå¸ / å¸åºæ¿çç ç©¶è°æ¥å/ ç»æå·¥ç¨å¸ / 模åå产å建çè®¾è®¡å¸ / 室å
è£
修工ç¨å¸ / æºçµå·¥ç¨å¸ / å®ä¹ ç" data-en="ï¼å京/广å·ï¼ä¼å»ºç PAO - 建çå¸ / å¸åºæ¿çç ç©¶è°æ¥å/ ç»æå·¥ç¨å¸ / 模åå产å建çè®¾è®¡å¸ / 室å
è£
修工ç¨å¸ / æºçµå·¥ç¨å¸ / å®ä¹ ç">ï¼å京/广å·ï¼ä¼å»ºç PAO - 建çå¸ / å¸åºæ¿çç ç©¶è°æ¥å/ ç»æå·¥ç¨å¸ / 模åå产å建çè®¾è®¡å¸ / 室å
è£
修工ç¨å¸ / æºçµå·¥ç¨å¸ / å®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="1706949" data-job-slug="job-the-triangle-jp" data-job-date="2026-07-13 14:00:50" data-job-modified="" data-job-modified-source="" data-job-fingerprint="74037e04bdc4b6e8" href="/job-the-triangle-jp.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/07/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2-%E5%A4%9A%E4%B8%89%E8%A7%92%E7%A9%BA%E9%97%B4-0712.jpg" alt="ï¼ä¸æµ·ï¼å¤ä¸è§ç©ºé´è®¾è®¡ â èµæ·±ä¸»åè®¾è®¡å¸ / 主åè®¾è®¡å¸ / å©çè®¾è®¡å¸ / åçå
容è¿è¥è´è´£äºº" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼å¤ä¸è§ç©ºé´è®¾è®¡ â èµæ·±ä¸»åè®¾è®¡å¸ / 主åè®¾è®¡å¸ / å©çè®¾è®¡å¸ / åçå
容è¿è¥è´è´£äºº" data-en="ï¼ä¸æµ·ï¼å¤ä¸è§ç©ºé´è®¾è®¡ â èµæ·±ä¸»åè®¾è®¡å¸ / 主åè®¾è®¡å¸ / å©çè®¾è®¡å¸ / åçå
容è¿è¥è´è´£äºº">ï¼ä¸æµ·ï¼å¤ä¸è§ç©ºé´è®¾è®¡ â èµæ·±ä¸»åè®¾è®¡å¸ / 主åè®¾è®¡å¸ / å©çè®¾è®¡å¸ / åçå
容è¿è¥è´è´£äºº</b><span></span></div></a><a class="side-job" data-job-id="950416" data-job-slug="job-chiasmus-partners" data-job-date="2026-07-13 11:00:59" data-job-modified="" data-job-modified-source="" data-job-fingerprint="446b6a9487f1b4f8" href="/job-chiasmus-partners.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2024/02/Chiasmus.jpg" alt="ï¼å京ï¼Chiasmus 建ç设计äºå¡æ - 建çå¸ / 建çå¸å©ç / 室å
è®¾è®¡å¸ / æ°åªä½å
Œ
³ / 建çå®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼å京ï¼Chiasmus 建ç设计äºå¡æ - 建çå¸ / 建çå¸å©ç / 室å
è®¾è®¡å¸ / æ°åªä½å
Œ
³ / 建çå®ä¹ ç" data-en="ï¼å京ï¼Chiasmus 建ç设计äºå¡æ - 建çå¸ / 建çå¸å©ç / 室å
è®¾è®¡å¸ / æ°åªä½å
Œ
³ / 建çå®ä¹ ç">ï¼å京ï¼Chiasmus 建ç设计äºå¡æ - 建çå¸ / 建çå¸å©ç / 室å
è®¾è®¡å¸ / æ°åªä½å
Œ
³ / 建çå®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="1705723" data-job-slug="job-l-p-architects" data-job-date="2026-07-09 16:31:39" data-job-modified="" data-job-modified-source="" data-job-fingerprint="c4c32b9d02212fe1" href="/job-l-p-architects.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/07/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2-LP.jpg" alt="ï¼æ·±å³/馿¸¯ï¼L&P Architects ç´æå½é
è®¾è®¡é¡¾é®æéå
¬å¸ - é«çº§å»ºçå¸ / 建çè®¾è®¡å¸ / èµæ·±å«å¢
豪å®
ç²¾è£
设计å¸" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼æ·±å³/馿¸¯ï¼L&P Architects ç´æå½é
è®¾è®¡é¡¾é®æéå
¬å¸ - é«çº§å»ºçå¸ / 建çè®¾è®¡å¸ / èµæ·±å«å¢
豪å®
ç²¾è£
设计å¸" data-en="ï¼æ·±å³/馿¸¯ï¼L&P Architects ç´æå½é
è®¾è®¡é¡¾é®æéå
¬å¸ - é«çº§å»ºçå¸ / 建çè®¾è®¡å¸ / èµæ·±å«å¢
豪å®
ç²¾è£
设计å¸">ï¼æ·±å³/馿¸¯ï¼L&P Architects ç´æå½é
è®¾è®¡é¡¾é®æéå
¬å¸ - é«çº§å»ºçå¸ / 建çè®¾è®¡å¸ / èµæ·±å«å¢
豪å®
ç²¾è£
设计å¸</b><span></span></div></a><a class="side-job" data-job-id="1594637" data-job-slug="job-nian-landscape" data-job-date="2026-07-09 13:46:36" data-job-modified="" data-job-modified-source="" data-job-fingerprint="021e63de8680358a" href="/job-nian-landscape.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture">
2451<img src="https://oss.gooood.cn/uploads/2025/06/%E5%BB%BF%E6%99%AF%E8%A7%82-%E7%BD%91%E7%AB%99%E6%8B%9B%E8%81%98%E6%96%87%E7%AB%A0%E5%B0%81%E9%9D%A2.jpg" alt="ï¼ä¸æµ·ï¼å»¿æ¯è§ NIAN LANDSCAPE - èµæ·±æ¯è§è®¾è®¡å¸/项ç®è´è´£äºº / æ¯è§è®¾è®¡å¸ / æ¯è§è®¾è®¡å®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼å»¿æ¯è§ NIAN LANDSCAPE - èµæ·±æ¯è§è®¾è®¡å¸/项ç®è´è´£äºº / æ¯è§è®¾è®¡å¸ / æ¯è§è®¾è®¡å®ä¹ ç" data-en="ï¼ä¸æµ·ï¼å»¿æ¯è§ NIAN LANDSCAPE - èµæ·±æ¯è§è®¾è®¡å¸/项ç®è´è´£äºº / æ¯è§è®¾è®¡å¸ / æ¯è§è®¾è®¡å®ä¹ ç">ï¼ä¸æµ·ï¼å»¿æ¯è§ NIAN LANDSCAPE - èµæ·±æ¯è§è®¾è®¡å¸/项ç®è´è´£äºº / æ¯è§è®¾è®¡å¸ / æ¯è§è®¾è®¡å®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="1705138" data-job-slug="job-deep-design-consultant" data-job-date="2026-07-07 10:52:09" data-job-modified="" data-job-modified-source="" data-job-fingerprint="06b8e3a8a09b8a74" href="/job-deep-design-consultant.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/07/0707%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2-%E5%AE%BD%E5%93%81%E8%AE%BE%E8%AE%A1.jpg" alt="ï¼å¦é¨ï¼å®½å设计 - 室å
è®¾è®¡å¸ / 设计å©ç / é¡¹ç®æ·±å设计å¸" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼å¦é¨ï¼å®½å设计 - 室å
è®¾è®¡å¸ / 设计å©ç / é¡¹ç®æ·±å设计å¸" data-en="ï¼å¦é¨ï¼å®½å设计 - 室å
è®¾è®¡å¸ / 设计å©ç / é¡¹ç®æ·±å设计å¸">ï¼å¦é¨ï¼å®½å设计 - 室å
è®¾è®¡å¸ / 设计å©ç / é¡¹ç®æ·±å设计å¸</b><span></span></div></a><a class="side-job" data-job-id="972843" data-job-slug="job-vari-architects" data-job-date="2026-07-06 16:00:09" data-job-modified="" data-job-modified-source="" data-job-fingerprint="ee30548cb047a4f0" href="/job-vari-architects.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2024/06/VARI-kla.jpg" alt="ï¼éåºï¼vari architects å é建ç - 建çå¸ / å©ç建çå¸ / 室å
è®¾è®¡å¸ / åªä½è¿è¥ä¸å / å®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼éåºï¼vari architects å é建ç - 建çå¸ / å©ç建çå¸ / 室å
è®¾è®¡å¸ / åªä½è¿è¥ä¸å / å®ä¹ ç" data-en="ï¼éåºï¼vari architects å é建ç - 建çå¸ / å©ç建çå¸ / 室å
è®¾è®¡å¸ / åªä½è¿è¥ä¸å / å®ä¹ ç">ï¼éåºï¼vari architects å é建ç - 建çå¸ / å©ç建çå¸ / 室å
è®¾è®¡å¸ / åªä½è¿è¥ä¸å / å®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="725861" data-job-slug="job-gmp" data-job-date="2026-07-06 14:30:40" data-job-modified="" data-job-modified-source="" data-job-fingerprint="47678ec6a7edb2aa" href="/job-gmp.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2023/06/gmp.jpg" alt="ï¼æ·±å³ï¼å¾·å½gmp建çå¸äºå¡æï¼Architects von Gerkan, Marg and Partnerï¼- 建çå®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼æ·±å³ï¼å¾·å½gmp建çå¸äºå¡æï¼Architects von Gerkan, Marg and Partnerï¼- 建çå®ä¹ ç" data-en="ï¼æ·±å³ï¼å¾·å½gmp建çå¸äºå¡æï¼Architects von Gerkan, Marg and Partnerï¼- 建çå®ä¹ ç">ï¼æ·±å³ï¼å¾·å½gmp建çå¸äºå¡æï¼Architects von Gerkan, Marg and Partnerï¼- 建çå®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="1702374" data-job-slug="job-whatever-design-office" data-job-date="2026-07-03 17:06:50" data-job-modified="" data-job-modified-source="" data-job-fingerprint="eeaf47ab3864d217" href="/job-whatever-design-office.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/07/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2-%E5%8B%89%E5%BC%BA%E8%AE%BE%E8%AE%A1.jpg" alt="ï¼éåºï¼å强设计äºå¡æ - 空é´è®¾è®¡å¸ / 空é´è®¾è®¡å©ç / æ½å·¥å¾è®¾è®¡å¸ / å®ä¹ çï¼é¿ææåï¼" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼éåºï¼å强设计äºå¡æ - 空é´è®¾è®¡å¸ / 空é´è®¾è®¡å©ç / æ½å·¥å¾è®¾è®¡å¸ / å®ä¹ çï¼é¿ææåï¼" data-en="ï¼éåºï¼å强设计äºå¡æ - 空é´è®¾è®¡å¸ / 空é´è®¾è®¡å©ç / æ½å·¥å¾è®¾è®¡å¸ / å®ä¹ çï¼é¿ææåï¼">ï¼éåºï¼å强设计äºå¡æ - 空é´è®¾è®¡å¸ / 空é´è®¾è®¡å©ç / æ½å·¥å¾è®¾è®¡å¸ / å®ä¹ çï¼é¿ææåï¼</b><span></span></div></a><a class="side-job" data-job-id="1606496" data-job-slug="job-tens-atelier" data-job-date="2026-07-03 15:00:17" data-job-modified="" data-job-modified-source="" data-job-fingerprint="ee5c939affce3c06" href="/job-tens-atelier.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/07/tens-atelier-2.jpg" alt="ï¼ä¸æµ·ï¼å¼¹æ§å·¥ä½å®¤Tens Atelier - 项ç®å®¤å
è®¾è®¡å¸ / å©ç室å
è®¾è®¡å¸ / å®ä¹ çï¼é¿ææåï¼" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼å¼¹æ§å·¥ä½å®¤Tens Atelier - 项ç®å®¤å
è®¾è®¡å¸ / å©ç室å
è®¾è®¡å¸ / å®ä¹ çï¼é¿ææåï¼" data-en="ï¼ä¸æµ·ï¼å¼¹æ§å·¥ä½å®¤Tens Atelier - 项ç®å®¤å
è®¾è®¡å¸ / å©ç室å
è®¾è®¡å¸ / å®ä¹ çï¼é¿ææåï¼">ï¼ä¸æµ·ï¼å¼¹æ§å·¥ä½å®¤Tens Atelier - 项ç®å®¤å
è®¾è®¡å¸ / å©ç室å
è®¾è®¡å¸ / å®ä¹ çï¼é¿ææåï¼</b><span></span></div></a><a class="side-job" data-job-id="617902" data-job-slug="job-leeko" data-job-date="2026-07-02 15:00:58" data-job-modified="" data-job-modified-source="" data-job-fingerprint="76b450787361da84" href="/job-leeko.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2022/08/0228-472x303-slb.jpg" alt="ï¼ä¸æµ·ï¼ä»¥é 建ç - 室å
è®¾è®¡å¸ / å©ç室å
è®¾è®¡å¸ / 建çå¸ / å©ç建çå¸ / å©çæ¯è§è®¾è®¡å¸" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼ä»¥é 建ç - 室å
è®¾è®¡å¸ / å©ç室å
è®¾è®¡å¸ / 建çå¸ / å©ç建çå¸ / å©çæ¯è§è®¾è®¡å¸" data-en="ï¼ä¸æµ·ï¼ä»¥é 建ç - 室å
è®¾è®¡å¸ / å©ç室å
è®¾è®¡å¸ / 建çå¸ / å©ç建çå¸ / å©çæ¯è§è®¾è®¡å¸">ï¼ä¸æµ·ï¼ä»¥é 建ç - 室å
è®¾è®¡å¸ / å©ç室å
è®¾è®¡å¸ / 建çå¸ / å©ç建çå¸ / å©çæ¯è§è®¾è®¡å¸</b><span></span></div></a><a class="side-job" data-job-id="834732" data-job-slug="job-wsp" data-job-date="2026-06-29 16:30:44" data-job-modified="" data-job-modified-source="" data-job-fingerprint="05aa28a3341ea85f" href="/job-wsp.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2022/09/WechatIMG13.jpg" alt="ï¼å京ï¼ç»´æå¹³WSP - æ°åªä½è¿è¥ / å塿»ç/åå¡ç»ç / 建ç主åè®¾è®¡å¸ / 建çå©çè®¾è®¡å¸ / 建ç设计å®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼å京ï¼ç»´æå¹³WSP - æ°åªä½è¿è¥ / å塿»ç/åå¡ç»ç / 建ç主åè®¾è®¡å¸ / 建çå©çè®¾è®¡å¸ / 建ç设计å®ä¹ ç" data-en="ï¼å京ï¼ç»´æå¹³WSP - æ°åªä½è¿è¥ / å塿»ç/åå¡ç»ç / 建ç主åè®¾è®¡å¸ / 建çå©çè®¾è®¡å¸ / 建ç设计å®ä¹ ç">ï¼å京ï¼ç»´æå¹³WSP - æ°åªä½è¿è¥ / å塿»ç/åå¡ç»ç / 建ç主åè®¾è®¡å¸ / 建çå©çè®¾è®¡å¸ / 建ç设计å®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="1070070" data-job-slug="job-ask-architecture" data-job-date="2026-06-29 14:00:04" data-job-modified="" data-job-modified-source="" data-job-fingerprint="c07b5d85e33cc271" href="/job-ask-architecture.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2024/04/0629%E9%97%A8%E5%8F%A3-%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2.jpg" alt="ï¼æé½ï¼éå£å»ºçå·¥ä½å®¤ Ask Architecture - 建çå¸ / 室å
è®¾è®¡å¸ / 设计å®ä¹ ç / åªä½å©ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼æé½ï¼éå£å»ºçå·¥ä½å®¤ Ask Architecture - 建çå¸ / 室å
è®¾è®¡å¸ / 设计å®ä¹ ç / åªä½å©ç" data-en="ï¼æé½ï¼éå£å»ºçå·¥ä½å®¤ Ask Architecture - 建çå¸ / 室å
è®¾è®¡å¸ / 设计å®ä¹ ç / åªä½å©ç">ï¼æé½ï¼éå£å»ºçå·¥ä½å®¤ Ask Architecture - 建çå¸ / 室å
è®¾è®¡å¸ / 设计å®ä¹ ç / åªä½å©ç</b><span></span></div></a><a class="side-job" data-job-id="777945" data-job-slug="job-fab-architects" data-job-date="2026-06-26 09:00:22" data-job-modified="" data-job-modified-source="" data-job-fingerprint="8f03695cb173eaa0" href="/job-fab-architects.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2022/05/qinghua-1-22-472x303.jpg" alt="ï¼åäº¬ï¼æ¸
å大å¦å»ºç设计ç ç©¶é¢ç¬¬ä¸åé¢ â 建çå¸ï¼å»ç康å
»ï¼ / å®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼åäº¬ï¼æ¸
å大å¦å»ºç设计ç ç©¶é¢ç¬¬ä¸åé¢ â 建çå¸ï¼å»ç康å
»ï¼ / å®ä¹ ç" data-en="ï¼åäº¬ï¼æ¸
å大å¦å»ºç设计ç ç©¶é¢ç¬¬ä¸åé¢ â 建çå¸ï¼å»ç康å
»ï¼ / å®ä¹ ç">ï¼åäº¬ï¼æ¸
å大å¦å»ºç设计ç ç©¶é¢ç¬¬ä¸åé¢ â 建çå¸ï¼å»ç康å
»ï¼ / å®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="1701215" data-job-slug="job-atmosphere" data-job-date="2026-06-24 11:50:34" data-job-modified="" data-job-modified-source="" data-job-fingerprint="638f4d49fc94841d" href="/job-atmosphere.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/06/ATMOSPHERE-Architects-2.jpg" alt="ï¼æé½ï¼ATMOSPHERE Architectsæ°£è±¡å»ºç¯ - 建çè®¾è®¡å¸ / 空é´è®¾è®¡å¸ / 设计å¸å©ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼æé½ï¼ATMOSPHERE Architectsæ°£è±¡å»ºç¯ - 建çè®¾è®¡å¸ / 空é´è®¾è®¡å¸ / 设计å¸å©ç" data-en="ï¼æé½ï¼ATMOSPHERE Architectsæ°£è±¡å»ºç¯ - 建çè®¾è®¡å¸ / 空é´è®¾è®¡å¸ / 设计å¸å©ç">ï¼æé½ï¼ATMOSPHERE Architectsæ°£è±¡å»ºç¯ - 建çè®¾è®¡å¸ / 空é´è®¾è®¡å¸ / 设计å¸å©ç</b><span></span></div></a><a class="side-job" data-job-id="1542809" data-job-slug="job-eeri-studio-2" data-job-date="2026-06-22 16:00:47" data-job-modified="" data-job-modified-source="" data-job-fingerprint="cee1dca8a7aee994" href="/job-eeri-studio-2.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/06/eeri-2.jpg" alt="ï¼ä¸æµ·ï¼EERI å³å建çè
2451®¾è®¡å·¥ä½å®¤ - 项ç®å»ºçå¸ / å©ç建çå¸ / å©ç室å
è®¾è®¡å¸ / åªä½ä¸ç ç©¶å©ç / 建çå®ä¹ çï¼é¿æææï¼" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼EERI å³å建ç设计工ä½å®¤ - 项ç®å»ºçå¸ / å©ç建çå¸ / å©ç室å
è®¾è®¡å¸ / åªä½ä¸ç ç©¶å©ç / 建çå®ä¹ çï¼é¿æææï¼" data-en="ï¼ä¸æµ·ï¼EERI å³å建ç设计工ä½å®¤ - 项ç®å»ºçå¸ / å©ç建çå¸ / å©ç室å
è®¾è®¡å¸ / åªä½ä¸ç ç©¶å©ç / 建çå®ä¹ çï¼é¿æææï¼">ï¼ä¸æµ·ï¼EERI å³å建ç设计工ä½å®¤ - 项ç®å»ºçå¸ / å©ç建çå¸ / å©ç室å
è®¾è®¡å¸ / åªä½ä¸ç ç©¶å©ç / 建çå®ä¹ çï¼é¿æææï¼</b><span></span></div></a><a class="side-job" data-job-id="1699206" data-job-slug="job-oll-opple" data-job-date="2026-06-16 10:30:47" data-job-modified="" data-job-modified-source="" data-job-fingerprint="c0a89c3ac2a05306" href="/job-oll-opple.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/06/oll-2.jpg" alt="ï¼ä¸æµ·ï¼OLLï¼æ¬§ä¹ç
§æï¼- 室å
è®¾è®¡å¸ / ç
§æè®¾è®¡å¸ / 客æ·/è®¾è®¡å¸æå±ä¸»ç®¡ / åçå¸åºä¸»ç®¡ / 设计å®ä¹ çï¼å®¤å
/å¹³é¢/ç
§æè®¾è®¡ï¼" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼OLLï¼æ¬§ä¹ç
§æï¼- 室å
è®¾è®¡å¸ / ç
§æè®¾è®¡å¸ / 客æ·/è®¾è®¡å¸æå±ä¸»ç®¡ / åçå¸åºä¸»ç®¡ / 设计å®ä¹ çï¼å®¤å
/å¹³é¢/ç
§æè®¾è®¡ï¼" data-en="ï¼ä¸æµ·ï¼OLLï¼æ¬§ä¹ç
§æï¼- 室å
è®¾è®¡å¸ / ç
§æè®¾è®¡å¸ / 客æ·/è®¾è®¡å¸æå±ä¸»ç®¡ / åçå¸åºä¸»ç®¡ / 设计å®ä¹ çï¼å®¤å
/å¹³é¢/ç
§æè®¾è®¡ï¼">ï¼ä¸æµ·ï¼OLLï¼æ¬§ä¹ç
§æï¼- 室å
è®¾è®¡å¸ / ç
§æè®¾è®¡å¸ / 客æ·/è®¾è®¡å¸æå±ä¸»ç®¡ / åçå¸åºä¸»ç®¡ / 设计å®ä¹ çï¼å®¤å
/å¹³é¢/ç
§æè®¾è®¡ï¼</b><span></span></div></a><a class="side-job" data-job-id="1266653" data-job-slug="job-ondo-studio" data-job-date="2026-06-12 16:00:03" data-job-modified="" data-job-modified-source="" data-job-fingerprint="0523c4d6bce3feaa" href="/job-ondo-studio.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2023/05/ondo.jpg" alt="ï¼æå·ï¼æ¸©åº¦ONDO空é´è®¾è®¡ - 室å
è®¾è®¡å¸ / è¾
æ¡è®¾è®¡å©ç / å®ä¹ ç / æ½å·¥å¾æ·±åè®¾è®¡å¸ / å塿»ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼æå·ï¼æ¸©åº¦ONDO空é´è®¾è®¡ - 室å
è®¾è®¡å¸ / è¾
æ¡è®¾è®¡å©ç / å®ä¹ ç / æ½å·¥å¾æ·±åè®¾è®¡å¸ / å塿»ç" data-en="ï¼æå·ï¼æ¸©åº¦ONDO空é´è®¾è®¡ - 室å
è®¾è®¡å¸ / è¾
æ¡è®¾è®¡å©ç / å®ä¹ ç / æ½å·¥å¾æ·±åè®¾è®¡å¸ / å塿»ç">ï¼æå·ï¼æ¸©åº¦ONDO空é´è®¾è®¡ - 室å
è®¾è®¡å¸ / è¾
æ¡è®¾è®¡å©ç / å®ä¹ ç / æ½å·¥å¾æ·±åè®¾è®¡å¸ / å塿»ç</b><span></span></div></a><a class="side-job" data-job-id="1697755" data-job-slug="job-uad-acrc" data-job-date="2026-06-11 17:10:25" data-job-modified="" data-job-modified-source="" data-job-fingerprint="5855a30d8a4c15a1" href="/job-uad-acrc.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/06/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2.jpg" alt="ï¼æå·ï¼UAD-ACRCæµæ±å¤§å¦å»ºç设计ç ç©¶é¢æéå
¬å¸ - 建çå¸" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼æå·ï¼UAD-ACRCæµæ±å¤§å¦å»ºç设计ç ç©¶é¢æéå
¬å¸ - 建çå¸" data-en="ï¼æå·ï¼UAD-ACRCæµæ±å¤§å¦å»ºç设计ç ç©¶é¢æéå
¬å¸ - 建çå¸">ï¼æå·ï¼UAD-ACRCæµæ±å¤§å¦å»ºç设计ç ç©¶é¢æéå
¬å¸ - 建çå¸</b><span></span></div></a><a class="side-job" data-job-id="843832" data-job-slug="job-formless-architects" data-job-date="2026-06-11 14:20:45" data-job-modified="" data-job-modified-source="" data-job-fingerprint="b4ad82fffceadafb" href="/job-formless-architects.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/06/formless-2.jpg" alt="ï¼ä¸æµ·ï¼å½¢é建ç Formless Architects - å©ç室å
è®¾è®¡å¸ / 室å
è®¾è®¡å¸ / 建çè®¾è®¡å¸ / å©ç建çå¸ / 建çå®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼å½¢é建ç Formless Architects - å©ç室å
è®¾è®¡å¸ / 室å
è®¾è®¡å¸ / 建çè®¾è®¡å¸ / å©ç建çå¸ / 建çå®ä¹ ç" data-en="ï¼ä¸æµ·ï¼å½¢é建ç Formless Architects - å©ç室å
è®¾è®¡å¸ / 室å
è®¾è®¡å¸ / 建çè®¾è®¡å¸ / å©ç建çå¸ / 建çå®ä¹ ç">ï¼ä¸æµ·ï¼å½¢é建ç Formless Architects - å©ç室å
è®¾è®¡å¸ / 室å
è®¾è®¡å¸ / 建çè®¾è®¡å¸ / å©ç建çå¸ / 建çå®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="1693839" data-job-slug="job-office-mass" data-job-date="2026-06-01 14:03:16" data-job-modified="" data-job-modified-source="" data-job-fingerprint="73597b0522d48469" href="/job-office-mass.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/05/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2.jpg" alt="ï¼ä¸æµ·ï¼æ¼æ¯å»ºç OFFICE MASS - 主å建çå¸ / 建çå¸ / å©ç建çå¸/åªä½å®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼æ¼æ¯å»ºç OFFICE MASS - 主å建çå¸ / 建çå¸ / å©ç建çå¸/åªä½å®ä¹ ç" data-en="ï¼ä¸æµ·ï¼æ¼æ¯å»ºç OFFICE MASS - 主å建çå¸ / 建çå¸ / å©ç建çå¸/åªä½å®ä¹ ç">ï¼ä¸æµ·ï¼æ¼æ¯å»ºç OFFICE MASS - 主å建çå¸ / 建çå¸ / å©ç建çå¸/åªä½å®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="1693904" data-job-slug="jobs-xian-architects" data-job-date="2026-05-29 17:04:14" data-job-modified="" data-job-modified-source="" data-job-fingerprint="02f72c2e3e91074a" href="/jobs-xian-architects.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/05/0529%E6%B0%99%E5%BB%BA%E7%AD%91%E5%B7%A5%E4%BD%9C%E5%AE%A4-p2t.jpg" alt="ï¼å京ï¼xiÄnæ°å»ºçå·¥ä½å®¤ - 项ç®å»ºçå¸ / å©çè®¾è®¡å¸ / å®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼å京ï¼xiÄnæ°å»ºçå·¥ä½å®¤ - 项ç®å»ºçå¸ / å©çè®¾è®¡å¸ / å®ä¹ ç" data-en="ï¼å京ï¼xiÄnæ°å»ºçå·¥ä½å®¤ - 项ç®å»ºçå¸ / å©çè®¾è®¡å¸ / å®ä¹ ç">ï¼å京ï¼xiÄnæ°å»ºçå·¥ä½å®¤ - 项ç®å»ºçå¸ / å©çè®¾è®¡å¸ / å®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="1571492" data-job-slug="job-duts-design" data-job-date="2026-05-29 09:34:25" data-job-modified="" data-job-modified-source="" data-job-fingerprint="57dd601ff1fd3f9b" href="/job-duts-design.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture">
2451<img src="https://oss.gooood.cn/uploads/2026/05/duts-design-2.jpg" alt="ï¼ä¸æµ·ï¼æå
¹è®¾è®¡ DUTS design - 室å
设计å¸ï¼ä¸»åï¼/ å©ç建çè®¾è®¡å¸ / å®ä¹ çï¼å»ºçãåªä½ãæ¯è§ã室å
ï¼" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼æå
¹è®¾è®¡ DUTS design - 室å
设计å¸ï¼ä¸»åï¼/ å©ç建çè®¾è®¡å¸ / å®ä¹ çï¼å»ºçãåªä½ãæ¯è§ã室å
ï¼" data-en="ï¼ä¸æµ·ï¼æå
¹è®¾è®¡ DUTS design - 室å
设计å¸ï¼ä¸»åï¼/ å©ç建çè®¾è®¡å¸ / å®ä¹ çï¼å»ºçãåªä½ãæ¯è§ã室å
ï¼">ï¼ä¸æµ·ï¼æå
¹è®¾è®¡ DUTS design - 室å
设计å¸ï¼ä¸»åï¼/ å©ç建çè®¾è®¡å¸ / å®ä¹ çï¼å»ºçãåªä½ãæ¯è§ã室å
ï¼</b><span></span></div></a><a class="side-job" data-job-id="1692907" data-job-slug="jobs-waa" data-job-date="2026-05-28 17:36:56" data-job-modified="" data-job-modified-source="" data-job-fingerprint="8d0a58ef2bec96db" href="/jobs-waa.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/05/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2-waa%E6%9C%AA%E8%A7%89%E5%BB%BA%E7%AD%910528.jpg" alt="ï¼å京ï¼waaæªè§å»ºç - 建çè®¾è®¡å¸ / 室å
è®¾è®¡å¸ / å©çè®¾è®¡å¸ / 建çå®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼å京ï¼waaæªè§å»ºç - 建çè®¾è®¡å¸ / 室å
è®¾è®¡å¸ / å©çè®¾è®¡å¸ / 建çå®ä¹ ç" data-en="ï¼å京ï¼waaæªè§å»ºç - 建çè®¾è®¡å¸ / 室å
è®¾è®¡å¸ / å©çè®¾è®¡å¸ / 建çå®ä¹ ç">ï¼å京ï¼waaæªè§å»ºç - 建çè®¾è®¡å¸ / 室å
è®¾è®¡å¸ / å©çè®¾è®¡å¸ / 建çå®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="1117478" data-job-slug="job-fangxia" data-job-date="2026-05-28 10:00:13" data-job-modified="" data-job-modified-source="" data-job-fingerprint="7e1bd063641cf7d7" href="/job-fangxia.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2025/05/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2-0522%E6%96%B9%E5%A4%8F.jpg" alt="ï¼åäº¬ï¼æ¹å¤è®¾è®¡ - é«çº§å®¤å
è®¾è®¡å¸ / 室å
æ¹æ¡è®¾è®¡å¸ / é«çº§è½¯è£
è®¾è®¡å¸ / ä¸ç»´å»ºæ¨¡è®¾è®¡å¸ / åå¡è´è´£äººæç»ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼åäº¬ï¼æ¹å¤è®¾è®¡ - é«çº§å®¤å
è®¾è®¡å¸ / 室å
æ¹æ¡è®¾è®¡å¸ / é«çº§è½¯è£
è®¾è®¡å¸ / ä¸ç»´å»ºæ¨¡è®¾è®¡å¸ / åå¡è´è´£äººæç»ç" data-en="ï¼åäº¬ï¼æ¹å¤è®¾è®¡ - é«çº§å®¤å
è®¾è®¡å¸ / 室å
æ¹æ¡è®¾è®¡å¸ / é«çº§è½¯è£
è®¾è®¡å¸ / ä¸ç»´å»ºæ¨¡è®¾è®¡å¸ / åå¡è´è´£äººæç»ç">ï¼åäº¬ï¼æ¹å¤è®¾è®¡ - é«çº§å®¤å
è®¾è®¡å¸ / 室å
æ¹æ¡è®¾è®¡å¸ / é«çº§è½¯è£
è®¾è®¡å¸ / ä¸ç»´å»ºæ¨¡è®¾è®¡å¸ / åå¡è´è´£äººæç»ç</b><span></span></div></a><a class="side-job" data-job-id="1170463" data-job-slug="job-plpl" data-job-date="2026-05-27 11:30:30" data-job-modified="" data-job-modified-source="" data-job-fingerprint="12f70af5ca125c31" href="/job-plpl.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2025/10/%E5%B0%81%E9%9D%A2%E6%8B%9B%E8%81%98.jpg" alt="ï¼ä¸æµ·ï¼PLPLï½Philip Liao & Partners Limited(Shanghai) å»å®åº·å»ºç设计顾é®ï¼ä¸æµ·ï¼æéå
¬å¸ - 室å
è®¾è®¡å¸ / ææå¾è®¾è®¡å¸ / 建ç设计å¸&é«çº§å»ºçå¸ / å®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼PLPLï½Philip Liao & Partners Limited(Shanghai) å»å®åº·å»ºç设计顾é®ï¼ä¸æµ·ï¼æéå
¬å¸ - 室å
è®¾è®¡å¸ / ææå¾è®¾è®¡å¸ / 建ç设计å¸&é«çº§å»ºçå¸ / å®ä¹ ç" data-en="ï¼ä¸æµ·ï¼PLPLï½Philip Liao & Partners Limited(Shanghai) å»å®åº·å»ºç设计顾é®ï¼ä¸æµ·ï¼æéå
¬å¸ - 室å
è®¾è®¡å¸ / ææå¾è®¾è®¡å¸ / 建ç设计å¸&é«çº§å»ºçå¸ / å®ä¹ ç">ï¼ä¸æµ·ï¼PLPLï½Philip Liao &
2451 Partners Limited(Shanghai) å»å®åº·å»ºç设计顾é®ï¼ä¸æµ·ï¼æéå ¬å¸ - 室å è®¾è®¡å¸ / ææå¾è®¾è®¡å¸ / 建ç设计å¸&é«çº§å»ºçå¸ / å®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="994853" data-job-slug="job-atelier-lai" data-job-date="2026-05-27 10:00:42" data-job-modified="" data-job-modified-source="" data-job-fingerprint="5e10d1bc6af2ee70" href="/job-atelier-lai.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2023/01/LAI.jpg" alt="ï¼ä¸æµ· / åè¥ï¼æ¥å»ºç设计工ä½å®¤ Atelier LAI - 项ç®å»ºçå¸ / 建çå¸ / å®ä¹ ç / é©»åºè®¾è®¡å¸" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ· / åè¥ï¼æ¥å»ºç设计工ä½å®¤ Atelier LAI - 项ç®å»ºçå¸ / 建çå¸ / å®ä¹ ç / é©»åºè®¾è®¡å¸" data-en="ï¼ä¸æµ· / åè¥ï¼æ¥å»ºç设计工ä½å®¤ Atelier LAI - 项ç®å»ºçå¸ / 建çå¸ / å®ä¹ ç / é©»åºè®¾è®¡å¸">ï¼ä¸æµ· / åè¥ï¼æ¥å»ºç设计工ä½å®¤ Atelier LAI - 项ç®å»ºçå¸ / 建çå¸ / å®ä¹ ç / é©»åºè®¾è®¡å¸</b><span></span></div></a><a class="side-job" data-job-id="1215830" data-job-slug="job-dazhou" data-job-date="2026-05-27 09:00:10" data-job-modified="" data-job-modified-source="" data-job-fingerprint="bf5d9fd70436a05b" href="/job-dazhou.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/05/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2-dazhou.jpg" alt="ï¼ä¸æµ·ï¼å¤§è建ç设计äºå¡æ - 项ç®å»ºçå¸ / å©ç建çå¸ / 建çå®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼å¤§è建ç设计äºå¡æ - 项ç®å»ºçå¸ / å©ç建çå¸ / 建çå®ä¹ ç" data-en="ï¼ä¸æµ·ï¼å¤§è建ç设计äºå¡æ - 项ç®å»ºçå¸ / å©ç建çå¸ / 建çå®ä¹ ç">ï¼ä¸æµ·ï¼å¤§è建ç设计äºå¡æ - 项ç®å»ºçå¸ / å©ç建çå¸ / 建çå®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="1059049" data-job-slug="job-project" data-job-date="2026-05-26 13:50:57" data-job-modified="" data-job-modified-source="" data-job-fingerprint="cf713aa0e945786c" href="/job-project.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2024/06/%E6%8B%9B%E8%81%98%E5%B0%81%E9%9D%A2-%E6%99%AE%E7%BD%97%E5%BB%BA%E7%AD%91-20260526.jpg" alt="ï¼å京ï¼PROJECTæ®ç½å»ºç - 建çå®ä¹ ç / å©ç建çå¸ / 项ç®å»ºçå¸ / åªä½ä¸å" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼å京ï¼PROJECTæ®ç½å»ºç - 建çå®ä¹ ç / å©ç建çå¸ / 项ç®å»ºçå¸ / åªä½ä¸å" data-en="ï¼å京ï¼PROJECTæ®ç½å»ºç - 建çå®ä¹ ç / å©ç建çå¸ / 项ç®å»ºçå¸ / åªä½ä¸å">ï¼å京ï¼PROJECTæ®ç½å»ºç - 建çå®ä¹ ç / å©ç建çå¸ / 项ç®å»ºçå¸ / åªä½ä¸å</b><span></span></div></a><a class="side-job" data-job-id="761016" data-job-slug="job-zxdarchitects" data-job-date="2026-05-26 10:30:27" data-job-modified="" data-job-modified-source="" data-job-fingerprint="423b494f2996e7d3" href="/job-zxdarchitects.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/05/zxd-2.jpg" alt="ï¼åäº¬ï¼æ±å°å°å»ºçäºå¡æ - åçå®£ä¼ ä¸å / å©ç建çå¸ / 建çå®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼åäº¬ï¼æ±å°å°å»ºçäºå¡æ - åçå®£ä¼ ä¸å / å©ç建çå¸ / 建çå®ä¹ ç" data-en="ï¼åäº¬ï¼æ±å°å°å»ºçäºå¡æ - åçå®£ä¼ ä¸å / å©ç建çå¸ / 建çå®ä¹ ç">ï¼åäº¬ï¼æ±å°å°å»ºçäºå¡æ - åçå®£ä¼ ä¸å / å©ç建çå¸ / 建çå®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="782112" data-job-slug="job-chengwai" data-job-date="2026-05-25 11:30:49" data-job-modified="" data-job-modified-source="" data-job-fingerprint="4022114ed2cd710a" href="/job-chengwai.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2022/09/0901-472x303.jpg" alt="ï¼å¹¿å·ï¼åå¤å»ºç - 建çå¸ / å©ç建çå¸ / 室å /ç¯èºè®¾è®¡å¸ / 建çå®ä¹ çï¼é¿æææï¼" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼å¹¿å·ï¼åå¤å»ºç - 建çå¸ / å©ç建çå¸ / 室å /ç¯èºè®¾è®¡å¸ / 建çå®ä¹ çï¼é¿æææï¼" data-en="ï¼å¹¿å·ï¼åå¤å»ºç - 建çå¸ / å©ç建çå¸ / 室å /ç¯èºè®¾è®¡å¸ / 建çå®ä¹ çï¼é¿æææï¼">ï¼å¹¿å·ï¼åå¤å»ºç - 建çå¸ / å©ç建çå¸ / 室å /ç¯èºè®¾è®¡å¸ / 建çå®ä¹ çï¼é¿æææï¼</b><span></span></div></a><a class="side-job" data-job-id="4496" data-job-slug="job-verse-design" data-job-date="2026-05-19 16:30:00" data-job-modified="" data-job-modified-source="" data-job-fingerprint="28c2f7ddc7e80189" href="/job-verse-design.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/07/verse-design-refine.jpg" alt="ï¼ä¸æµ·ï¼Verse Design 建è¨å»ºç â 建çå¸ / å©ç建çå¸ / 建çå®ä¹ ç" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼ä¸æµ·ï¼Verse Design 建è¨å»ºç â 建çå¸ / å©ç建çå¸ / 建çå®ä¹ ç" data-en="ï¼ä¸æµ·ï¼Verse Design 建è¨å»ºç â 建çå¸ / å©ç建çå¸ / 建çå®ä¹ ç">ï¼ä¸æµ·ï¼Verse Design 建è¨å»ºç â 建çå¸ / å©ç建çå¸ / 建çå®ä¹ ç</b><span></span></div></a><a class="side-job" data-job-id="792389" data-job-slug="job-11architecture" data-job-date="2026-05-19 13:30:25" data-job-modified="" data-job-modified-source="" data-job-fingerprint="f5fc81a697848f8a" href="/job-11architecture.htm" target="_blank" rel="noopener"><div class="cover"><picture class="job-cover-picture"><img src="https://oss.gooood.cn/uploads/2026/05/%E4%B8%80%E5%8D%81%E4%B8%80-2.jpg" alt="ï¼æ·±å³ï¼ä¸åä¸å»ºç - 建çè®¾è®¡å¸ / å©ç建çå¸ / 室å è®¾è®¡å¸ / å¹³é¢è®¾è®¡å¸" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></picture></div><div class="side-job-text"><b data-zh="ï¼æ·±å³ï¼ä¸åä¸å»ºç - 建çè®¾è®¡å¸ / å©ç建çå¸ / 室å è®¾è®¡å¸ / å¹³é¢è®¾è®¡å¸" data-en="ï¼æ·±å³ï¼ä¸åä¸å»ºç - 建çè®¾è®¡å¸ / å©ç建çå¸ / 室å è®¾è®¡å¸ / å¹³é¢è®¾è®¡å¸">ï¼æ·±å³ï¼ä¸åä¸å»ºç - 建çè®¾è®¡å¸ / å©ç建çå¸ / 室å è®¾è®¡å¸ / å¹³é¢è®¾è®¡å¸</b><span></span></div></a></div> 2452 </div> 2453 </div> 2454 </div> 2455 </aside> 2456 </div> 2457 <section class="footer-nav" aria-label="页åºå¯¼èª"> 2458 <div class="footer-nav-inner"> 2459 <div class="footer-col"> 2460 <h4 data-zh="æç¨¿ä¸å ³äº" data-en="Submissions & About">æç¨¿ä¸å ³äº</h4> 2461 <a href="/submissions" data-zh="å è´¹æç¨¿" data-en="Submissions">å è´¹æç¨¿</a> 2462 <a href="/aboutus" data-zh="å ³äºæä»¬" data-en="About us">
2462å ³äºæä»¬</a> 2463 <a href="/work-for-gooood" data-zh="å å ¥æä»¬" data-en="Work for gooood">å å ¥æä»¬</a> 2464 <a href="/copyright" data-zh="çæå£°æ" data-en="Copyright">çæå£°æ</a> 2465 </div> 2466 <div class="footer-col"> 2467 <h4 data-zh="æå¡" data-en="Services">æå¡</h4> 2468 <a href="/job-service-info" data-zh="é主æè人æ" data-en="Recruitment service">é主æè人æ</a> 2469 <a href="/ad-article" data-zh="æç« ä»è´¹æ¨å¹¿" data-en="Article AD">æç« ä»è´¹æ¨å¹¿</a> 2470 <a href="/materials" data-zh="å»ºææ¨å¹¿" data-en="Materials">å»ºææ¨å¹¿</a> 2471 <a href="/find-designer" data-zh="ä¸ä¸»æ¾è®¾è®¡å¸" data-en="Find designers">ä¸ä¸»æ¾è®¾è®¡å¸</a> 2472 <a href="/get-project-designer" data-zh="è®¾è®¡å¸æ¥é¡¹ç®" data-en="Get Projects">è®¾è®¡å¸æ¥é¡¹ç®</a> 2473 <a href="/talks" data-zh="è¯å¬ä¼å" data-en="Talks">è¯å¬ä¼å</a> 2474 </div> 2475 <div class="footer-col"> 2476 <h4 data-zh="ç¬å®¶ä¸è¾" data-en="Series">ç¬å®¶ä¸è¾</h4> 2477 <a href="/category/series" data-zh="ææä¸è¾" data-en="All Series">ææä¸è¾</a> 2478 <a href="/category/series/gooood-interview" data-zh="访è°ä¸è¾" data-en="Interview">访è°ä¸è¾</a> 2479 <a href="/category/series/office-fact" data-zh="åå ¬å®¤çç¸" data-en="Office Fact">åå ¬å®¤çç¸</a> 2480 <a href="/category/series/under-35" data-zh="æªæ»¡35å²åæäººè®°å½" data-en="Under 35">æªæ»¡35å²åæäººè®°å½</a> 2481 <a href="/category/series/topic" data-zh="æ¥å¸¸æ·±åº¦+" data-en="Topic">æ¥å¸¸æ·±åº¦+</a> 2482 <a href="/category/series/oversea" data-zh="卿µ·å¤" data-en="Oversea">卿µ·å¤</a> 2483 <a href="/category/type/anniversary" data-zh="大å¨å¹´" data-en="Anniversary">大å¨å¹´</a> 2484 </div> 2485 <div class="footer-col"> 2486 <h4 data-zh="åç±»" data-en="Type">åç±»</h4> 2487 <a href="/category/jobs" data-zh="å·¥ä½" data-en="Jobs">å·¥ä½</a> 2488 <a href="/category/type/architecture" data-zh="建ç" data-en="Architecture">建ç</a> 2489 <a href="/category/type/landscape" data-zh="æ¯è§" data-en="Landscape">æ¯è§</a> 2490 <a href="/category/type/archive" data-zh="åé" data-en="Archive">åé</a> 2491 <a href="/category/type/art" data-zh="èºæ¯" data-en="Art">èºæ¯</a> 2492 <a href="/category/type/design" data-zh="设计" data-en="Design">设计</a> 2493 </div> 2494 <div class="footer-col"> 2495 <h4 data-zh="å ³æ³¨æä»¬" data-en="Follow us">å ³æ³¨æä»¬</h4> 2496 <a href="http://weibo.com/goooodgooood" target="_blank" rel="noopener" data-zh="å¾®å" data-en="Weibo">å¾®å</a> 2497 <a href="https://oss.gooood.cn/uploads/2020/06/weixin1.jpg" target="_blank" rel="noopener" data-zh="微信" data-en="WeChat">微信</a> 2498 <a href="https://www.xiaohongshu.com/user/profile/63ede8e3000000001001ce69?xhsshare=WeixinSession&appuid=641404080000000014013693&apptime=1730862558" target="_blank" rel="noopener" data-zh="å°çº¢ä¹¦" data-en="Xiaohongshu">å°çº¢ä¹¦</a> 2499 <a href="https://www.instagram.com/goooodofficial/" target="_blank" rel="noopener" data-zh="Instagram" data-en="Instagram">Instagram</a> 2500 <a href="https://www.pinterest.com/gooood0103/pins/" target="_blank" rel="noopener" data-zh="Pinterest" data-en="Pinterest">Pinterest</a> 2501 </div> 2502 </div> 2503 </section> 2504 <footer class="footer"><a href="/aboutus" data-zh="å ³äºæä»¬" data-en="About us">å ³äºæä»¬</a> ï½ Â©2010-2026 è°·å¾·è®¾è®¡ç½ | <a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">京ICPå¤17062545å·-1</a> | <a href="https://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11010502061450" target="_blank" rel="noopener">äº¬å ¬ç½å®å¤11010502061450å·</a></footer> 2505</div> 2506
2506<script data-v10-ssr-snapshot="1"> 2507 document.documentElement.dataset.ssrHomeData = 'connected'; 2508 document.documentElement.dataset.ssrHomeSource = "nuxt-v10-runtime:archive-full-page:categories:news"; 2509 document.documentElement.dataset.liveHomeData = 'connected'; 2510 document.documentElement.dataset.liveHomeSource = "nuxt-v10-runtime:archive-full-page:categories:news"; 2511</script>
vendor: 1 bytes, line 2511
2511
2512<script> 2513 (() => { 2514 const latestJobTitles = [ 2515 '妿©è®¾è®¡ä¸æµ·æè室å 设计å¸', 2516 'gad · line+ studio æå·æè项ç®å»ºçå¸', 2517 'OPEN Architecture å京æè建ç设计å¸', 2518 '大è建ç䏿µ·æè项ç®è´è´£äºº', 2519 'ç´å建çå京æèå级建çå¸', 2520 'Heatherwick Studio 䏿µ·æèé«çº§è®¾è®¡å¸', 2521 'BIG æ·±å³æè项ç®å»ºçå¸', 2522 'è¤æ¬å£®ä»å»ºç䏿µ·æè建ç设计å¸', 2523 'Snøhetta 馿¸¯æè项ç®å»ºçå¸', 2524 'é常建çå京æè建çå¸', 2525 'åå®¶ç¨å»ºçæé½æè项ç®å»ºçå¸', 2526 'éç å¾å»ºçé½å¸ä¸äº¬æè建ç设计å¸', 2527 'OMA 馿¸¯æèé«çº§å»ºçå¸', 2528 'MVRDV 䏿µ·æè项ç®è´è´£äºº', 2529 '迹 · 建çäºå¡æå京æè建çå¸', 2530 'äºå»ºçäºå¡æä¸æµ·æè建çå¸', 2531 'åºåå»ºçæ·±å³æè项ç®å»ºçå¸', 2532 'SOM 䏿µ·æèåå¸è®¾è®¡å¸', 2533 'AECOM å京æèæ¯è§è®¾è®¡å¸', 2534 'KPF 䏿µ·æè建ç设计å¸', 2535 'Gensler å京æè室å 设计å¸', 2536 'Perkins&Will 䏿µ·æè项ç®å»ºçå¸', 2537 'HPP æ·±å³æè建ç设计å¸', 2538 'Chapman Taylor 䏿µ·æèé«çº§å»ºçå¸', 2539 'çå¢è®¾è®¡æå·æè项ç®è´è´£äºº', 2540 'é½è®¾è®¾è®¡ä¸æµ·æè建çå¸', 2541 '山水ç§å京æèä¸çº§å»ºçå¸', 2542 'é´çè®¾è®¡ä¸æµ·æè室å 设计å¸', 2543 'å½¢æè®¾è®¡ä¸æµ·æè建ç设计å¸', 2544 'Link-Arc æå·æè项ç®å»ºçå¸', 2545 'å°å¹³çº¿æ°è±¡æé½æè空é´è®¾è®¡å¸', 2546 'çè§è§éå京æèå©ç建çå¸', 2547 'Mind Studio 䏿µ·æè室å 设计å¸', 2548 'PMT Partners æ·±å³æèæ¯è§è®¾è®¡å¸', 2549 'PILLS å京æèåç空é´è®¾è®¡å¸', 2550 '墨工工ä½å®¤å¹¿å·æè建çå¸', 2551 'F.O.G. 䏿µ·æè建ç设计å¸', 2552 'LYCS Architecture æå·æè项ç®è´è´£äºº', 2553 'é½å¸å®è·µæ·±å³æè主å建çå¸', 2554 'æºè®¡å建çå¹¿å·æè建ç设计å¸', 2555 'æ¬å²å»ºç䏿µ·æè项ç®å»ºçå¸', 2556 '䏿工ä½å®¤å京æè室å 设计å¸', 2557 'ç«æ¨è®¾è®¡æå·æèæ¯è§è®¾è®¡å¸', 2558 'è´æ£å»ºç䏿µ·æèå©ç建çå¸', 2559 'ææ¹ç©ºé´æ·±å³æèåçç¼è¾', 2560 'å¹³ä»è®¾è®¡ä¸æµ·æè室å 主æ¡', 2561 'åä½è®¾è®¡æé½æè建ç设计å¸', 2562 'æ¹æè¥é å京æè项ç®ç»ç', 2563 '空é´ç«å»ºçå京æè建çå¸', 2564 'å±±å·è®¾è®¡å¹¿å·æèæ¯è§è®¾è®¡å¸', 2565 'ä¼å»ºçå京æè建çå®ä¹ ç', 2566 'goa 大象设计æå·æè建çå¸', 2567 'line+ 䏿µ·æè室å 设计å¸', 2568 'MDO æ¨å䏿µ·æè项ç®å»ºçå¸', 2569 'æ°´ç³è®¾è®¡ä¸æµ·æèåå¸è®¾è®¡å¸', 2570 'æ åè®¾è®¡æ·±å³æèæ¯è§è®¾è®¡å¸', 2571 'è£¸çæ´æ°å京æè项ç®è´è´£äºº', 2572 'ç±³å¹å·¥ä½å®¤æå·æè建ç设计å¸', 2573 '森ä¸å»ºçæé½æè室å 设计å¸', 2574 'ä¸ç¤¾è®¾è®¡ä¸æµ·æèåç空é´è®¾è®¡å¸', 2575 'atelier tao+c 䏿µ·æè项ç®å»ºçå¸', 2576 'BAU æ·±å³æèåå¸è®¾è®¡å¸', 2577 'Crossboundaries å京æè建çå¸', 2578 'Wutopia Lab 䏿µ·æè主å建çå¸', 2579 'ä¸æå»ºçå京æè项ç®è´è´£äºº', 2580 '妿¯è®¾è®¡æå·æè室å 设计å¸',
2581 'å¤§è§æ¯è§æ·±å³æèæ¯è§è®¾è®¡å¸', 2582 'æªè§å»ºç䏿µ·æèå©ç建çå¸', 2583 'ç´ å»ºçå¹¿å·æè建ç设计å¸', 2584 'æ¶å°å»ºçæé½æè项ç®å»ºçå¸' 2585 ]; 2586 2587 const backendSnapshot = window.__GOOOOD_V10_BACKEND_SNAPSHOT__ || null; 2588 let backendRenderedLatestJobs = false; 2589 let language = 'zh'; 2590 2591 const decodeHtml = (value) => { 2592 const node = document.createElement('textarea'); 2593 node.innerHTML = String(value || ''); 2594 return node.value.trim(); 2595 }; 2596 const escapeHtml = (value) => String(value || '').replace(/[&<>"']/g, (char) => ({ 2597 '&': '&', 2598 '<': '<', 2599 '>': '>', 2600 '"': '"', 2601 "'": ''' 2602 })[char]); 2603 const zhText = (value) => decodeHtml(value).split('|')[0].trim(); 2604 const enText = (value, fallback = '') => { 2605 const parts = decodeHtml(value).split('|'); 2606 return (parts[1] || fallback || parts[0] || '').trim(); 2607 }; 2608 const setBilingualText = (node, zh, en = zh) => { 2609 if (!node) return; 2610 node.dataset.zh = zh || ''; 2611 node.dataset.en = en || zh || ''; 2612 node.textContent = language === 'en' ? node.dataset.en : node.dataset.zh; 2613 }; 2614 const formatDate = (value) => { 2615 const date = value ? new Date(value) : null; 2616 if (!date || Number.isNaN(date.getTime())) return ''; 2617 const y = date.getFullYear(); 2618 const m = String(date.getMonth() + 1).padStart(2, '0'); 2619 const d = String(date.getDate()).padStart(2, '0'); 2620 return `${y}.${m}.${d}`; 2621 }; 2622 const postUrl = (slug) => slug ? `https://www.gooood.cn/${slug}.htm` : '#'; 2623 const communityUrl = (slug) => slug ? `https://www.gooood.cn/community/${slug}` : '#'; 2624 const criticalImageReplacements = window.__GOOOOD_V10_CRITICAL_IMAGES__ || {}; 2625 const decodeCriticalImageUrl = (url) => { 2626 try { 2627 return decodeURI(url || ''); 2628 } catch (error) { 2629 return url || ''; 2630 } 2631 }; 2632 const optimizeCriticalImage = (url) => criticalImageReplacements[url] || criticalImageReplacements[decodeCriticalImageUrl(url)] || url; 2633 const postImage = (post) => optimizeCriticalImage(post?.summary_image_url || post?.featured_image?.sizes?.medium?.source_url || post?.featured_image?.source_url || post?.cover || post?.thumbnail || ''); 2634 const jobTitle = (job) => job?.title?.rendered || job?.title?.fulltitle || job?.title || ''; 2635 const jobImage = (job) => job?.thumb || job?.thumbnail || job?.cover || job?.featured_image?.sizes?.['size-310']?.source_url || job?.featured_image?.source_url || ''; 2636 const compactTitle = (value) => zhText(value); 2637 const applyImageAttrs = (img, width, height, loading = 'lazy', fetchPriority = 'low') => { 2638 if (!img) return; 2639 if (width && !img.hasAttribute('width')) img.setAttribute('width', String(width)); 2640 if (height && !img.hasAttribute('height')) img.setAttribute('height', String(height)); 2641 img.setAttribute('decoding', 'async'); 2642 img.setAttribute('loading', loading); 2643 img.setAttribute('fetchpriority', fetchPriority); 2644 }; 2645 const normalizeV10ImagePerformanceAttrs = () => { 2646 document.querySelectorAll('.top-slider img').forEach((img, index) => { 2647 applyImageAttrs(img, 2000, 600, index === 0 ? 'eager' : 'lazy', 'low'); 2648 }); 2649 document.querySelectorAll('.article .cover img').forEach((img, index) => { 2650 applyImageAttrs(img, index < 4 ? 650 : 472, index < 4 ? 417 : 303, index === 0 ? 'eager' : 'lazy', index === 0 ? 'auto' : 'low'); 2651 }); 2652 document.querySelectorAll('.album .cover img').forEach((img) => applyImageAttrs(img, 310, 200)); 2653 document.querySelectorAll('.side-job .cover img').forEach((img) => applyImageAttrs(img, 150, 96)); 2654 document.querySelectorAll('.home-top-ad-image img, .home-inline-ad-image img').forEach((img) => applyImageAttrs(img, 1100, 220)); 2655 document.querySelectorAll('img:not([width]), img:not([height])').forEach((img) => { 2656 if (img.closest('.side-job')) return; 2657 if (img.naturalWidth && img.naturalHeight) {
2658 applyImageAttrs(img, img.naturalWidth, img.naturalHeight); 2659 } else { 2660 img.addEventListener('load', () => applyImageAttrs(img, img.naturalWidth, img.naturalHeight), { once: true }); 2661 } 2662 }); 2663 }; 2664 const normalizeUrl = (value) => { 2665 const url = String(value || '').trim(); 2666 if (!url) return '#'; 2667 if (url.startsWith('mailto:') || url.startsWith('tel:') || url.startsWith('//')) return url; 2668 try { 2669 const parsed = new URL(url, 'https://www.gooood.cn'); 2670 if (parsed.origin === 'https://www.gooood.cn') { 2671 return `${parsed.pathname}${parsed.search}${parsed.hash}` || '/'; 2672 } 2673 } catch {} 2674 return url; 2675 }; 2676 const jobPostUrl = (slug) => { 2677 const normalized = String(slug || '').trim().replace(/^\/+/, '').replace(/^jobs\//, '').replace(/\.htm$/, ''); 2678 return /^[a-z0-9][a-z0-9_-]*$/i.test(normalized) ? `https://www.gooood.cn/${normalized}.htm` : '#'; 2679 }; 2680 const normalizeJobUrl = (value) => { 2681 const normalized = normalizeUrl(value);
2682 try { 2683 const parsed = new URL(normalized, 'https://www.gooood.cn'); 2684 if (parsed.origin !== 'https://www.gooood.cn') return normalized; 2685 const match = parsed.pathname.match(/^\/jobs\/([a-z0-9][a-z0-9_-]*)\/?$/i); 2686 return match ? `/${match[1]}.htm${parsed.search}${parsed.hash}` : normalized; 2687 } catch { 2688 return normalized; 2689 } 2690 }; 2691 const buildPostLink = (post) => { 2692 if (!post) return '#'; 2693 if (post.linkurl) return normalizeUrl(post.linkurl); 2694 if (post.link) return normalizeUrl(post.link); 2695 return post.slug ? postUrl(post.slug) : '#'; 2696 }; 2697 const pageUrl = (page, pageInfo = {}) => { 2698 const pageNumber = Number(page) || 1; 2699 const basePath = String(pageInfo.basePath || '').replace(/\/$/, ''); 2700 const pagePathStyle = String(pageInfo.pagePathStyle || 'page-segment'); 2701 if (basePath) { 2702 if (pageNumber <= 1) return basePath || '/'; 2703 const suffix = pagePathStyle === 'trailing-number' ? `/${pageNumber}` : `/page/${pageNumber}`; 2704 return `${basePath}${suffix}`; 2705 } 2706 return pageNumber <= 1 ? '/' : `/page/${pageNumber}`; 2707 }; 2708 const currentPageFromLocation = () => { 2709 const match = window.location.pathname.match(/\/page\/(\d+)\/?$/) || window.location.pathname.match(/\/(\d+)\/?$/); 2710 return match ? Number(match[1]) || 1 : 1; 2711 }; 2712 const authoritativeAdArray = (sources, label) => { 2713 const source = sources.find((items) => items !== undefined); 2714 if (source === undefined) return []; 2715 if (!Array.isArray(source)) throw new Error(`${label} advertisement source is not an array`); 2716 return source; 2717 }; 2718 const getCarouselAds = (snapshot) => { 2719 const sources = [ 2720 snapshot?.home?.carouselAds, 2721 snapshot?.ads?.home_banners, 2722 snapshot?.indexAds?.home_banners, 2723 snapshot?.ads?.['é¦é¡µè½®æå¾å¹¿å'], 2724 snapshot?.indexAds?.['é¦é¡µè½®æå¾å¹¿å'], 2725 snapshot?.adsByPosition?.home_banners, 2726 snapshot?.adsByPosition?.home_carousel, 2727 snapshot?.adsByPosition?.['34627'] 2728 ]; 2729 return authoritativeAdArray(sources, 'home carousel').filter((ad) => ad?.acf?.ad_image || ad?.image || ad?.featured_image?.source_url || ad?.cover || ad?.gallery?.[0]?.full_url).slice(0, 20); 2730 }; 2731 2732 const getHomeTopAds = (snapshot) => { 2733 const sources = [ 2734 snapshot?.home?.homeTopAds, 2735 snapshot?.ads?.home_list_0, 2736 snapshot?.indexAds?.home_list_0, 2737 snapshot?.ads?.['é¦é¡µè½®æå¾ä¸æ¹å¹¿å'], 2738 snapshot?.indexAds?.['é¦é¡µè½®æå¾ä¸æ¹å¹¿å'], 2739 snapshot?.adsByPosition?.home_list_0, 2740 snapshot?.adsByPosition?.['34628'] 2741 ]; 2742 return authoritativeAdArray(sources, 'home top').filter((ad) => ad?.acf?.ad_content || ad?.acf?.ad_image || ad?.image || ad?.featured_image?.source_url || ad?.cover || ad?.gallery?.[0]?.full_url).slice(0, 2); 2743 }; 2744 2745 const getHomeInlineAds = (snapshot, field, slug, positionId, label) => { 2746 const sources = [ 2747 snapshot?.home?.[field], 2748 snapshot?.ads?.[slug], 2749 snapshot?.indexAds?.[slug], 2750 snapshot?.ads?.[label], 2751 snapshot?.indexAds?.[label], 2752 snapshot?.adsByPosition?.[slug], 2753 snapshot?.adsByPosition?.[positionId] 2754 ]; 2755 return authoritativeAdArray(sources, `home ${positionId}`).filter((ad) => ad?.acf?.ad_content || ad?.acf?.ad_image || ad?.image || ad?.featured_image?.source_url || ad?.cover || ad?.gallery?.[0]?.full_url).slice(0, 1); 2756 }; 2757 2758 const adText = (value) => String(value || '').trim(); 2759 const adFnv1a32 = (value, seed) => { 2760 let hash = seed >>> 0; 2761 for (let index = 0; index < value.length; index += 1) { 2762 hash ^= value.charCodeAt(index); 2763 hash = Math.imul(hash, 0x01000193); 2764 } 2765 return (hash >>> 0).toString(16).padStart(8, '0'); 2766 }; 2767 const adFingerprint = (ad = {}) => { 2768 const canonical = [ 2769 adText(ad.id), 2770 adText(ad.slug), 2771 adText(ad.acf?.ad_name), 2772 adText(typeof ad.title === 'string' ? ad.title : ad.title?.fulltitle || ad.title?.rendered), 2773 adText(ad.acf?.ad_link || ad.linkurl || ad.imagelink || ad.url || ad.href || ad.link), 2774 adText(ad.acf?.ad_image || ad.image || ad.cover || ad.featured_image?.source_url || ad.gallery?.[0]?.full_url), 2775 adText(ad.acf?.ad_content) 2776 ].join('\u001f'); 2777 return `${adFnv1a32(canonical, 0x811c9dc5)}${adFnv1a32(canonical, 0x9e3779b9)}`; 2778 }; 2779 const adSetFingerprint = (ads = []) => { 2780 const canonical = ads.map((ad) => `${adText(ad.id)}:${adFingerprint(ad)}`).join('\u001e'); 2781 return `${adFnv1a32(canonical, 0x811c9dc5)}${adFnv1a32(canonical, 0x9e3779b9)}`; 2782 }; 2783 const clearAdIdentity = (node) => { 2784 ['adRecordId', 'adRecordIds', 'adSlug', 'adModified', 'adTitle', 'adHref', 'adFingerprint', 'backendAdContent'].forEach((key) => { 2785 delete node.dataset[key]; 2786 }); 2787 }; 2788 const applyAdState = ({ node, snapshot, ads, positionId, slug, sourceLabel }) => { 2789 const freshness = snapshot?.adFreshnessByPosition?.[positionId] || {}; 2790 const first = ads[0]; 2791 clearAdIdentity(node); 2792 node.dataset.backendAdPosition = positionId; 2793 node.dataset.backendAdSource = `dashboard.api.api-advert-adposition.php?slugName=${slug}`; 2794 node.dataset.backendAdStatus = first ? 'connected' : 'empty'; 2795 node.dataset.adItemCount = String(ads.length); 2796 node.dataset.wpTagId = positionId; 2797 node.dataset.wpTermSlug = slug; 2798 node.dataset.adSource = freshness.source || sourceLabel || `legacy-api:${slug}`; 2799 node.dataset.adSetFingerprint = freshness.setFingerprint || adSetFingerprint(ads); 2800 node.dataset.adSourceFetchedAt = freshness.sourceFetchedAt || snapshot?.fetchedAt || new Date().toISOString(); 2801 node.dataset.adCacheStatus = freshness.cacheStatus || 'direct-request'; 2802 if (first) { 2803 node.dataset.adRecordId = String(first.id || ''); 2804 node.dataset.adRecordIds = ads.map((ad) =>
2804 String(ad.id || '')).filter(Boolean).join(','); 2805 node.dataset.adSlug = String(first.slug || ''); 2806 node.dataset.adModified = String(first.modified || ''); 2807 node.dataset.adTitle = zhText(first.acf?.ad_name || first.name || first.title?.fulltitle || first.title?.rendered || first.title || ''); 2808 node.dataset.adHref = normalizeUrl(first.acf?.ad_link || first.linkurl || first.imagelink || first.url || first.href || '#'); 2809 node.dataset.adFingerprint = first.acf?.advertisement_fingerprint || adFingerprint(first); 2810 } 2811 node.hidden = !first; 2812 if (first) node.removeAttribute('aria-hidden'); 2813 else node.setAttribute('aria-hidden', 'true'); 2814 }; 2815 2816 const renderBackendCarousel = (snapshot) => { 2817 const ads = getCarouselAds(snapshot); 2818 const slider = document.querySelector('.top-slider'); 2819 if (!slider) return; 2820 Array.from(slider.querySelectorAll('.slide')).forEach((node) => node.remove()); 2821 const dotsWrap = slider.querySelector('.top-slider-dots'); 2822 if (dotsWrap) dotsWrap.innerHTML = ''; 2823 applyAdState({ node: slider, snapshot, ads, positionId: '34627', slug: 'home_banners', sourceLabel: 'legacy-api:home_banners' }); 2824 if (!ads.length) return; 2825 const controls = slider.querySelector('.slider-controls'); 2826 ads.forEach((ad, index) => { 2827 const title = zhText(ad.acf?.ad_name || ad.name || ad.title?.fulltitle || ad.title?.rendered || ad.title || `é¦é¡µè½®æå¾å¹¿å ${index + 1}`); 2828 const image = optimizeCriticalImage(ad.acf?.ad_image || ad.image || ad.featured_image?.source_url || ad.featured_image?.sizes?.medium?.source_url || ad.cover || ad.gallery?.[0]?.full_url || ''); 2829 const href = normalizeUrl(ad.acf?.ad_link || ad.linkurl || ad.imagelink || ad.url || ad.href || '#'); 2830 const slide = document.createElement('div'); 2831 slide.className = `slide${index === 0 ? ' is-active' : ''}`; 2832 slide.dataset.adRecordId = String(ad.id || ''); 2833 slide.dataset.adSlug = String(ad.slug || ''); 2834 slide.dataset.adModified = String(ad.modified || ''); 2835 slide.dataset.adTitle = title; 2836 slide.dataset.adFingerprint = ad.acf?.advertisement_fingerprint || adFingerprint(ad); 2837 const imageSource = index === 0 2838 ? `src="${escapeHtml(image)}" loading="eager" fetchpriority="low"` 2839 : `data-src="${escapeHtml(image)}" loading="lazy" fetchpriority="low"`; 2840 slide.innerHTML = `<a class="slide-link" href="${escapeHtml(href)}" target="_blank" rel="noopener"><img ${imageSource} alt="${escapeHtml(title)}" width="2000" height="600" decoding="async" loading="lazy" fetchpriority="low"></a>`; 2841 slider.insertBefore(slide, controls); 2842 }); 2843 if (dotsWrap) { 2844 dotsWrap.innerHTML = ads.map((_, index) => `<button class="${index === 0 ? 'is-active' : ''}" type="button" data-slide-dot="${index}" aria-label="第 ${index + 1} å¼ "></button>`).join(''); 2845 } 2846 }; 2847 2848 const renderBackendHomeTopAd = (snapshot) => { 2849 const ads = getHomeTopAds(snapshot); 2850 const section = document.querySelector('.ad-embed.hero-below'); 2851 if (!section) return; 2852 const ad = ads[0]; 2853 applyAdState({ node: section, snapshot, ads, positionId: '34628', slug: 'home_list_0', sourceLabel: 'legacy-api:home_list_0' }); 2854 if (!ad) { 2855 section.replaceChildren(); 2856 return; 2857 } 2858 const contentKinds = []; 2859 const bodies = ads.map((item) => { 2860 const html = typeof item.acf?.ad_content === 'string' ? item.acf.ad_content.trim() : ''; 2861 if (html) { 2862 contentKinds.push('acf.ad_content'); 2863 return html; 2864 } 2865 const image = item.acf?.ad_image || item.image || item.featured_image?.source_url || item.featured_image?.sizes?.medium?.source_url || item.cover || item.gallery?.[0]?.full_url || ''; 2866 if (!image) return ''; 2867 contentKinds.push('ad_image'); 2868 const title = zhText(item.acf?.ad_name || item.name || item.title?.fulltitle || item.title?.rendered || item.title || 'é¦é¡µè½®æå¾ä¸æ¹å¹¿å'); 2869 const href = normalizeUrl(item.acf?.ad_link || item.linkurl || item.imagelink || item.url || item.href || '#'); 2870 return `<a class="home-top-ad-image" href="${escapeHtml(href)}" target="_blank" rel="noopener"><img src="${escapeHtml(image)}" alt="${escapeHtml(title)}" width="1100" height="220" decoding="async" loading="lazy" fetchpriority="low"></a>`; 2871 }
2871).filter(Boolean); 2872 section.innerHTML = bodies.join(''); 2873 const uniqueContentKinds = Array.from(new Set(contentKinds)); 2874 section.dataset.backendAdContent = uniqueContentKinds.length === 1 ? uniqueContentKinds[0] : 'mixed'; 2875 }; 2876 2877 const renderBackendInlineAd = ({ snapshot, selector, field, slug, positionId, label }) => { 2878 const ads = getHomeInlineAds(snapshot, field, slug, positionId, label); 2879 const section = document.querySelector(selector); 2880 if (!section) return; 2881 const ad = ads[0]; 2882 applyAdState({ node: section, snapshot, ads, positionId, slug, sourceLabel: `legacy-api:${slug}` }); 2883 if (!ad) { 2884 section.replaceChildren(); 2885 return; 2886 } 2887 const html = typeof ad.acf?.ad_content === 'string' ? ad.acf.ad_content.trim() : ''; 2888 if (html) { 2889 section.innerHTML = html; 2890 section.dataset.backendAdContent = 'acf.ad_content'; 2891 return; 2892 } 2893 const image = ad.acf?.ad_image || ad.image || ad.featured_image?.source_url || ad.featured_image?.sizes?.medium?.source_url || ad.cover || ad.gallery?.[0]?.full_url || ''; 2894 if (!image) return; 2895 const title = zhText(ad.acf?.ad_name || ad.name || ad.title?.fulltitle || ad.title?.rendered || ad.title || label); 2896 const href = normalizeUrl(ad.acf?.ad_link || ad.linkurl || ad.imagelink || ad.url || ad.href || '#'); 2897 section.innerHTML = `<a class="home-inline-ad-image" href="${escapeHtml(href)}" target="_blank" rel="noopener"><img src="${escapeHtml(image)}" alt="${escapeHtml(title)}" width="1100" height="220" decoding="async" loading="lazy" fetchpriority="low"></a>`; 2898 section.dataset.backendAdContent = 'ad_image'; 2899 }; 2900 2901 const renderBackendPosts = (posts = []) => { 2902 const articles = Array.from(document.querySelectorAll('.article')); 2903 posts.slice(0, articles.length).forEach((post, index) => { 2904 const article = articles[index]; 2905 const titleSource = post.title?.fulltitle || post.title?.rendered || post.title; 2906 const subtitleSource = post.goooodSubtitle?.zh || post.homeSubtitleZh || post.excerpt?.rendered || post.excerpt; 2907 const categorySource = post.taxonomies?.category?.[0]?.name || ''; 2908 const title = zhText(titleSource); 2909 const titleEn = enText(titleSource, title); 2910 const subtitle = zhText(subtitleSource); 2911 const subtitleEn = post.goooodSubtitle?.en || post.homeSubtitleEn || enText(post.excerpt?.rendered || post.excerpt || subtitleSource, subtitle); 2912 const category = zhText(categorySource); 2913 const categoryEn = enText(categorySource, category); 2914 const url = buildPostLink(post); 2915 const image = postImage(post); 2916 const titleLink = article.querySelector('h3 a'); 2917 const coverLink = article.querySelector(':scope > .cover a'); 2918 const coverImg = article.querySelector(':scope > .cover img, :scope > .cover .article-cover-link img'); 2919 const kicker = article.querySelector('.kicker'); 2920 const subtitleNode = article.querySelector('.article-subtitle'); 2921 const time = article.querySelector('time'); 2922 article.dataset.backendPostId = String(post.id || ''); 2923 article.dataset.backendPostSlug = post.slug || ''; 2924 article.dataset.backendPrimaryTypeId = String(post.primary_type_id || post.type?.[0] || post.taxonomies?.type?.[0]?.id || post.taxonomies?.type?.[0]?.term_id || ''); 2925 if (titleLink) { 2926 titleLink.href = url; 2927 titleLink.target = '_blank'; 2928 titleLink.rel = 'noopener'; 2929 setBilingualText(titleLink, title, titleEn); 2930 } 2931 if (coverLink) { 2932 coverLink.href = url; 2933 coverLink.target = '_blank'; 2934 coverLink.rel = 'noopener'; 2935 coverLink.setAttribute('aria-label', title); 2936 } 2937 if (coverImg && image) { 2938 coverImg.src = image; 2939 coverImg.alt = title; 2940 applyImageAttrs(coverImg, index < 4 ? 650 : 472, index < 4 ? 417 : 303, index === 0 ? 'eager' : 'lazy', index === 0 ? 'auto' : 'low'); 2941 } 2942 if (kicker && category) setBilingualText(kicker, category, c
2942ategoryEn); 2943 if (subtitleNode) setBilingualText(subtitleNode, subtitle, subtitleEn); 2944 if (time) { 2945 const label = formatDate(post.date); 2946 time.textContent = label; 2947 if (post.date) time.dateTime = post.date; 2948 } 2949 }); 2950 articles.slice(posts.length).forEach((article) => { 2951 const row = article.closest('section.row'); 2952 article.remove(); 2953 if (row && !row.querySelector('.article')) row.remove(); 2954 }); 2955 }; 2956 2957 const buildJobLink = (job) => { 2958 if (!job) return '#'; 2959 if (job.linkurl) return normalizeJobUrl(job.linkurl); 2960 if (job.link) return normalizeJobUrl(job.link); 2961 return job.slug ? jobPostUrl(job.slug) : '#'; 2962 }; 2963 2964 const renderBackendTextJobs = (jobs = [], showNumbers = {}, jumpUrls = {}) => { 2965 const list = document.querySelector('.job-cols'); 2966 if (!list || !jobs.length) return; 2967 const parsedRowsPerColumn = Number(showNumbers.options_column_count); 2968 const rowsPerColumn = Number.isFinite(parsedRowsPerColumn) && parsedRowsPerColumn >= 1 ? Math.floor(parsedRowsPerColumn) : 13; 2969 const count = Math.min(jobs.length, rowsPerColumn * 3); 2970 const columns = [[], [], []]; 2971 jobs.slice(0, count).forEach((job, index) => columns[Math.floor(index / rowsPerColumn)].push(job)); 2972 list.innerHTML = columns.map((column) => ` 2973 <div class="job-col" data-admin-setting="options_column_count" data-configured-count="${rowsPerColumn}"> 2974 ${column.map((job) => { const source = jobTitle(job); const zh = zhText(source); const en = enText(source, zh); return `<a class="job-line" href="${escapeHtml(buildJobLink(job))}" target="_blank" rel="noopener"><b data-zh="${escapeHtml(zh)}" data-en="${escapeHtml(en)}">${escapeHtml(language === 'en' ? en : zh)}</b><em></em></a>`; }).join('')} 2975 </div> 2976 `).join(''); 2977 const submit = document.querySelector('.job-head .job-submit'); 2978 const all = document.querySelector('.job-head .job-all'); 2979 if (submit && jumpUrls.options_new_recommend_linkurl) submit.href = jumpUrls.options_new_recommend_linkurl; 2980 if (all) all.href = 'https://www.gooood.cn/category/jobs'; 2981 }; 2982 2983 const latestShowNumbers = (snapshot = {}) => { 2984 return snapshot?.home?.showNumbers || snapshot?.showNumbers || {}; 2985 }; 2986 2987 const renderBackendSideJobs = (jobs = [], showNumbers = {}) => { 2988 const list = document.querySelector('.side-jobs.home-pinned'); 2989 if (!list || !jobs.length) return; 2990 const backendJobCount = Number( 2991 showNumbers.options_jobs_index_number || 2992 latestShowNumbers(backendSnapshot).options_jobs_index_number 2993 ) || 0; 2994 const targetCount = backendJobCount || Number(list.dataset.defaultCount) || 74; 2995 const normalizedJobs = jobs.slice(0, targetCount); 2996 list.dataset.source = snapshot?.home?.showNumbersSource || (showNumbers.options_jobs_index_number ? 'live-home-runtime.showNumbers' : 'window.__GOOOOD_V10_BACKEND_SNAPSHOT__.home.homeSideJobs'); 2997 list.dataset.renderedCount = String(normalizedJobs.length); 2998 list.dataset.backendCount = String(jobs.length); 2999 list.dataset.configuredCount = String(targetCount); 3000 list.innerHTML = normalizedJobs.map((job) => { 3001 const titleSource = jobTitle(job); 3002 const title = zhText(titleSource); 3003 const titleEn = enText(titleSource, title); 3004 const image = jobImage(job); 3005 return `<a class="side-job" href="${escapeHtml(buildJobLink(job))}" target="_blank" rel="noopener"><div class="cover"><img src="${escapeHtml(image)}" alt="${escapeHtml(title)}" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></div><div class="side-job-text"><b data-zh="${escapeHtml(title)}" data-en="${escapeHtml(titleEn)}">${escapeHtml(language === 'en' ? titleEn : title)}</b><span></span></div></a>`; 3006 }).join(''); 3007 backendRenderedLatestJobs = true; 3008 }; 3009
3010 const collectPinnedJobs = (snapshot) => { 3011 const home = snapshot?.home || {}; 3012 const candidates = [ 3013 home.pinnedJobs, 3014 home.topJobs, 3015 home.featuredJobs, 3016 home.homeTopJobs, 3017 home.homePinnedJobs, 3018 home.topRecruitJobs, 3019 snapshot?.pinnedJobs, 3020 snapshot?.topJobs 3021 ]; 3022 return candidates.find((items) => Array.isArray(items) && items.length) || []; 3023 }; 3024 3025 const renderBackendPinnedJobs = (jobs = [], jumpUrls = {}) => { 3026 const list = document.querySelector('.side-jobs.pinned'); 3027 const section = list?.closest('.pinned-jobs-section'); 3028 if (!list || !section) return; 3029 const normalizedJobs = Array.isArray(jobs) ? jobs.filter(Boolean) : []; 3030 const topLink = section.querySelector('.side-title-action'); 3031 if (topLink) { 3032 topLink.href = jumpUrls.options_top_recruit_linkurl || jumpUrls.options_buy_top_linkurl || topLink.href; 3033 } 3034 if (!normalizedJobs.length) { 3035 list.innerHTML = ''; 3036 section.hidden = true; 3037 section.dataset.renderedCount = '0'; 3038 section.dataset.emptyState = 'no-pinned-jobs'; 3039 return; 3040 } 3041 section.hidden = false; 3042 section.dataset.renderedCount = String(normalizedJobs.length); 3043 section.dataset.emptyState = ''; 3044 list.innerHTML = normalizedJobs.map((job) => { 3045 const titleSource = jobTitle(job); 3046 const title = zhText(titleSource); 3047 const titleEn = enText(titleSource, title); 3048 const image = jobImage(job); 3049 return `<a class="side-job" href="${escapeHtml(buildJobLink(job))}" target="_blank" rel="noopener"><div class="cover"><img src="${escapeHtml(image)}" alt="${escapeHtml(title)}" width="150" height="96" decoding="async" loading="lazy" fetchpriority="low"></div><div class="side-job-text"><b data-zh="${escapeHtml(title)}" data-en="${escapeHtml(titleEn)}">${escapeHtml(language === 'en' ? titleEn : title)}</b><span></span></div></a>`; 3050 }).join(''); 3051 }; 3052 3053 const renderPagination = (pageInfo = {}) => { 3054 const nav = document.querySelector('.pagination'); 3055 if (!nav) return; 3056 const current = Math.max(1, Number(pageInfo.page || currentPageFromLocation() || 1)); 3057 const totalPages = Math.max(1, Number(pageInfo.totalPages || pageInfo.total_pages || nav.dataset.totalPages || 1)); 3058 const totalItems = Number(pageInfo.total || nav.dataset.totalItems || 0); 3059 const items = []; 3060 items.push(current > 1 3061 ? `<a href="${escapeHtml(pageUrl(current - 1, pageInfo))}" aria-label="ä¸ä¸é¡µ">â</a>` 3062 : '<span class="page-item disabled" aria-disabled="true">â</span>'); 3063 items.push(`<a class="active" href="${escapeHtml(pageUrl(current, pageInfo))}">${current}</a>`); 3064 [current + 1, current + 2].forEach((page) => { 3065 if (page <= totalPages) items.push(`<a href="${escapeHtml(pageUrl(page, pageInfo))}">${page}</a>`); 3066 }); 3067 if (current + 3 < totalPages) items.push('<span class="page-item dots">...</span>'); 3068 if (current + 2 < totalPages) items.push(`<a href="${escapeHtml(pageUrl(totalPages, pageInfo))}">${totalPages}</a>`); 3069 items.push(current < totalPages 3070 ? `<a href="${escapeHtml(pageUrl(current + 1, pageInfo))}" aria-label="ä¸ä¸é¡µ">â</a>` 3071 : '<span class="page-item disabled" aria-disabled="true">â</span>'); 3072 items.push(`<span class="page-count">${current}/${totalPages}</span>`); 3073 items.push(`<label class="page-jump"><input type="number" min="1" max="${totalPages}" placeholder="5" aria-label="跳转页ç "><button type="button" data-zh="跳页" data-en="Go">${language === 'en' ? 'Go' : '跳页'}</button></label>`); 3074 nav.dataset.currentPage = String(current); 3075 nav.dataset.totalPages = String(totalPages); 3076 if (totalItems) nav.dataset.totalItems = String(totalItems); 3077 nav.innerHTML = items.join(''); 3078 const input = nav.querySelector('.page-jump input'); 3079 const button = nav.querySelector('.page-jump button'); 3080 const go = () => { 3081 const target = Math.min(totalPages, Math.max(1, Number(input?.value || 1))); 3082 window.location.href = pageUrl(target, pageInfo); 3083 }; 3084 button?.addEventListener('click', go); 3085 input?.addEventListener('keydown', (event) => { 3086 if (event.key === 'Enter') go(); 3087 }); 3088 }; 3089 3090 const renderBackendSeries = (posts = []) => { 3091 const panel = document.querySelector('.sidebar .panel:nth-of-type(1)'); 3092 if (!panel || !posts.length) return; 3093 const head = panel.querySelector('.panel-head'); 3094 const allLink = head?.querySelector('a'); 3095 if (allLink) { 3096 allLink.href = 'https://www.gooood.cn/category/series'; 3097 allLink.target = '_blank'; 3098 allLink.rel = 'noopener'; 3099 } 3100 panel.innerHTML = ''; 3101 if (head) panel.appendChild(head); 3102 posts.slice(0, 3).forEach((post) => {
3103 const title = post.titleZh || zhText(post.title); 3104 const titleEn = post.titleEn || enText(post.title, title); 3105 const subtitle = post.excerptZh || zhText(post.excerpt); 3106 const subtitleEn = post.excerptEn || enText(post.excerpt, subtitle); 3107 const link = document.createElement('a'); 3108 link.className = 'album'; 3109 link.href = normalizeUrl(post.url || post.link || (post.slug ? postUrl(post.slug) : '#')); 3110 link.target = '_blank'; 3111 link.rel = 'noopener'; 3112 const image = post.thumbnail || post.cover || post.summary_image_url || post.image || post.featured_image?.source_url || post.featured_image?.sizes?.medium?.source_url || ''; 3113 link.innerHTML = `<div class="cover"><img src="${escapeHtml(image)}" alt="${escapeHtml(title)}" width="310" height="200" decoding="async" loading="lazy" fetchpriority="low"></div><div><b data-zh="${escapeHtml(title)}" data-en="${escapeHtml(titleEn)}">${escapeHtml(language === 'en' ? titleEn : title)}</b><span data-zh="${escapeHtml(subtitle)}" data-en="${escapeHtml(subtitleEn)}">${escapeHtml(language === 'en' ? subtitleEn : subtitle)}</span></div>`; 3114 panel.appendChild(link); 3115 }); 3116 }; 3117 3118 const renderBackendHot = (posts = []) => { 3119 const panel = document.querySelector('.sidebar .panel:nth-of-type(2)'); 3120 if (!panel || !posts.length) return; 3121 const head = panel.querySelector('.panel-head'); 3122 head?.querySelector('a')?.remove(); 3123 panel.innerHTML = ''; 3124 if (head) panel.appendChild(head);
3125 posts.slice(0, 5).forEach((post, index) => { 3126 const title = post.titleZh || compactTitle(post.title); 3127 const titleEn = post.titleEn || enText(post.title, title); 3128 const visibleTitle = language === 'en' ? titleEn : title; 3129 const link = document.createElement('a'); 3130 link.className = 'hot'; 3131 link.href = normalizeUrl(post.url || post.link || (post.slug ? postUrl(post.slug) : '#')); 3132 link.target = '_blank'; 3133 link.rel = 'noopener'; 3134 link.innerHTML = `<div class="rank">${String(index + 1).padStart(2, '0')}</div><div><b data-zh="${escapeHtml(title)}" data-en="${escapeHtml(titleEn)}">${escapeHtml(visibleTitle)}</b><span></span></div>`; 3135 panel.appendChild(link); 3136 }); 3137 }; 3138 3139 const renderBackendData = (snapshot) => { 3140 if (!snapshot?.home) return; 3141 renderBackendCarousel(snapshot); 3142 renderBackendHomeTopAd(snapshot); 3143 renderBackendInlineAd({ snapshot, selector: '.ad-embed.materials-ad', field: 'homeMaterialAds', slug: 'home_list_8', positionId: '34630', label: 'é¦é¡µç¬¬ 8 ç¯æç« å' }); 3144 renderBackendInlineAd({ snapshot, selector: '.ad-embed.project-ad', field: 'homeProjectAds', slug: 'home_list_12', positionId: '34632', label: 'é¦é¡µç¬¬ 12 ç¯æç« å' }); 3145 renderBackendInlineAd({ snapshot, selector: '.ad-embed.page-bottom', field: 'homePaginationBottomAds', slug: 'home_pagination_bottom', positionId: '34642', label: '页ç 䏿¹å¹¿å' }); 3146 const latestJobs = snapshot.home.homeSideJobs?.length ? snapshot.home.homeSideJobs : (snapsh
3146ot.home.jobs || []); 3147 const showNumbers = latestShowNumbers(snapshot); 3148 renderBackendPosts(snapshot.home.posts || []); 3149 renderBackendTextJobs(latestJobs, showNumbers, snapshot.jumpUrls || snapshot.home.jumpUrls || {}); 3150 renderBackendPinnedJobs(collectPinnedJobs(snapshot), snapshot.jumpUrls || snapshot.home.jumpUrls || {}); 3151 renderBackendSideJobs(latestJobs, showNumbers); 3152 renderBackendSeries(snapshot.home.top_posts || []); 3153 renderBackendHot(snapshot.home.week_hot || []); 3154 renderPagination(snapshot.home.pageInfo || snapshot.pageInfo || {}); 3155 normalizeV10ImagePerformanceAttrs(); 3156 document.documentElement.dataset.backendSnapshot = '20260709'; 3157 }; 3158 3159 const shouldUseLiveHomeData = () => { 3160 const params = new URLSearchParams(window.location.search); 3161 const hostname = window.location.hostname; 3162 return hostname === 'www.gooood.cn' || hostname === '127.0.0.1' || hostname === 'localhost' || params.get('live') === '1' || params.has('fixture'); 3163 }; 3164 3165 const loadFixtureSnapshot = async () => { 3166 const params = new URLSearchParams(window.location.search); 3167 const fixture = params.get('fixture'); 3168 if (!fixture) return null; 3169 if (!/^[a-zA-Z0-9._-]+$/.test(fixture)) throw new Error('Invalid V10 fixture name'); 3170 const fixtureResponse = await fetch(`/api/home/v10-fixture?name=${encodeURIComponent(fixture)}`, { 3171 credentials: 'omit', 3172 cache: 'no-store' 3173 }); 3174 if (!fixtureResponse.ok) throw new Error(`V10 fixture not found: ${fixture}`); 3175 const fixtureSnapshot = await fixtureResponse.json(); 3176 return { fixture, snapshot: fixtureSnapshot }; 3177 }; 3178 3179 const withFreshCarouselAds = async (snapshot) => { 3180 try { 3181 const carouselUrl = `https://dashboard.gooood.cn/wp-json/wp/v2/advertisement?adposition=34627&per_page=20&order=asc&orderby=menu_order&_fresh=${Date.now()}`; 3182 const response = await fetch(carouselUrl, { credentials: 'omit', cache: 'no-store' }); 3183 if (!response.ok) return snapshot; 3184 const carouselAds = await response.json(); 3185 if (!Array.isArray(carouselAds)) return snapshot; 3186 const freshSnapshot = JSON.parse(JSON.stringify(snapshot)); 3187 freshSnapshot.home = freshSnapshot.home || {}; 3188 freshSnapshot.home.carouselAds = carouselAds; 3189 freshSnapshot.adsByPosition = freshSnapshot.adsByPosition || {}; 3190 freshSnapshot.adsByPosition['34627'] = carouselAds; 3191 freshSnapshot.adFreshnessByPosition = freshSnapshot.adFreshnessByPosition || {}; 3192 freshSnapshot.adFreshnessByPosition['34627'] = { 3193 source: 'wp/v2/advertisement', 3194 sourceFetchedAt: new Date().toISOString(), 3195 cacheStatus: 'direct-request', 3196 itemCount: carouselAds.length, 3197 setFingerprint: adSetFingerprint(carouselAds) 3198 }; 3199 return freshSnapshot; 3200 } catch (error) { 3201 return snapshot; 3202 } 3203 }; 3204 3205 const refreshLiveHomeData = async () => { 3206 if (!backendSnapshot?.home || !shouldUseLiveHomeData()) return null; 3207 if (backendSnapshot.home.pageInfo?.basePath) { 3208 const freshArchiveSnapshot = await withFreshCarouselAds(backendSnapshot); 3209 renderBackendData(freshArchiveSnapshot); 3210 document.documentElement.dataset.liveHomeData = 'ssr-archive-snapshot'; 3211 document.documentElement.dataset.liveHomeSource = freshArchiveSnapshot.source || 'nuxt-v10-runtime:archive-full-page'; 3212 return freshArchiveSnapshot; 3213 } 3214 const page = currentPageFromLocation(); 3215 const fixtureResult = await loadFixtureSnapshot(); 3216 if (fixtureResult?.snapshot) { 3217 renderBackendData(fixtureResult.snapshot); 3218 document.documentElement.dataset.liveHomeData = 'connected'; 3219 document.documentElement.dataset.liveHomeSource = `v10-fixture:${fixtureResult.fixture}`; 3220 return fixtureResult.snapshot; 3221 } 3222 try { 3223 const localPreview = window.location.hostname === '127.0.0.1' || window.location.hostname === 'localhost'; 3224 const runtimeUrl = `/api/home/v10-runtime?page=${page}&hotPerPage=5${localPreview ? '&refresh=1' : ''}`; 3225 const runtimeResponse = await fetch(runtimeUrl, { credentials: 'omit', cache: localPreview ? 'no-store' : 'default' }); 3226 if (runtimeResponse.ok) { 3227 const runtimeSnapshot = await withFreshCarouselAds(await runtimeResponse.json()); 3228 renderBackendData(runtimeSnapshot); 3229 document.documentElement.dataset.liveHomeData = 'connected'; 3230 document.documentElement.dataset.liveHomeSource = runtimeSnapshot.source || 'nuxt-v10-runtime'; 3231 return runtimeSnapshot; 3232 } 3233 } catch (error) {
3234 document.documentElement.dataset.liveHomeData = 'nuxt-v10-runtime-fallback'; 3235 } 3236 const initialPerPage = Number(backendSnapshot.home.pageInfo?.perPage) || 18; 3237 let perPage = initialPerPage; 3238 try { 3239 const countResponse = await fetch(`https://dashboard.gooood.cn/api/api-blogjobs-number.php?_fresh=${Date.now()}`, { credentials: 'omit', cache: 'no-store' }); 3240 const countText = await countResponse.text(); 3241 perPage = Number(countText.trim()) || initialPerPage; 3242 } catch (error) { 3243 perPage = initialPerPage; 3244 } 3245 const postsEndpoint = `https://dashboard.gooood.cn/wp-json/wp/v2/fetch-posts?post_type%5B0%5D=post&post_type%5B1%5D=jobs&page=${page}&per_page=${perPage}&orderby=date&order=desc&_fresh=${Date.now()}`; 3246 const [postsResult, jobsResult, carouselResult, runtimeResult, showNumbersResult] = await Promise.allSettled([ 3247 fetch(postsEndpoint, { credentials: 'omit', cache: 'no-store' }), 3248 fetch('https://dashboard.gooood.cn/api/api-jobs-index.php', { credentials: 'omit' }), 3249 fetch(`https://dashboard.gooood.cn/wp-json/wp/v2/advertisement?adposition=34627&per_page=20&order=asc&orderby=menu_order&_fresh=${Date.now()}`, { credentials: 'omit', cache: 'no-store' }), 3250 fetch('/api/home/runtime?hotPerPage=5', { credentials: 'omit' }), 3251 fetch(`https://dashboard.gooood.cn/api/api-show-number.php?_fresh=${Date.now()}`, { credentials: 'omit', cache: 'no-store' }) 3252 ]); 3253 const postsResponse = postsResult.status === 'fulfilled' && postsResult.value.ok ? postsResult.value : null; 3254 const posts = postsResponse ? await postsResponse.json() : (backendSnapshot.home.posts || []); 3255 const jobs = jobsResult.status === 'fulfilled' && jobsResult.value.ok ? await jobsResult.value.json() : backendSnapshot.home.homeSideJobs || []; 3256 const carouselAds = carouselResult.status === 'fulfilled' && carouselResult.value.ok ? await carouselResult.value.json() : null; 3257 const runtime = runtimeResult.status === 'fulfilled' && runtimeResult.value.ok ? await runtimeResult.value.json() : null; 3258 const freshShowNumbers = showNumbersResult.status === 'fulfilled' && showNumbersResult.value.ok ? await showNumbersResult.value.json() : null; 3259 const total = Number(postsResponse?.headers.get('x-wp-total')) || Number(backendSnapshot.home.pageInfo?.total) || posts.length; 3260 const totalPages = Number(postsResponse?.headers.get('x-wp-totalpages')) || Number(backendSnapshot.home.pageInfo?.totalPages) || Math.max(1, Math.ceil(total / perPage)); 3261 const liveSnapshot = JSON.parse(JSON.stringify(backendSnapshot)); 3262 liveSnapshot.home.posts = posts; 3263 liveSnapshot.home.homeSideJobs = jobs; 3264 liveSnapshot.home.sideJobsCount = jobs.length; 3265 const liveShowNumbers = freshShowNumbers && Object.keys(freshShowNumbers).length ? freshShowNumbers : runtime?.showNumbers; 3266 if (liveShowNumbers) { 3267 liveSnapshot.showNumbers = liveShowNumbers; 3268 liveSnapshot.home.showNumbers = liveShowNumbers; 3269 liveSnapshot.home.showNumbersSource = freshShowNumbers ? 'https://dashboard.gooood.cn/api/api-show-number.php' : (runtime.home?.showNumbersSource || runtime.home?.v10RuntimeSources?.showNumbers || runtime.source || 'local-home-runtime'); 3270 liveSnapshot.home.showNumbersFetchedAt = freshShowNumbers ? new Date().toISOString() : (runtime.home?.showNumbersFetchedAt || runtime.fetchedAt || ''); 3271 } 3272 if (Array.isArray(runtime?.weekHot) && runtime.weekHot.length) { 3273 liveSnapshot.home.week_hot = runtime.weekHot; 3274 } 3275 liveSnapshot.home.pageInfo = { 3276 page, 3277 perPage, 3278 total, 3279 totalPages, 3280 source: postsEndpoint, 3281 countSource: 'https://dashboard.gooood.cn/api/api-blogjobs-number.php', 3282 frontendBaseUrl: 'https://www.gooood.cn', 3283 corsAllowedOrigin: 'https://www.gooood.cn' 3284 }; 3285 if (Array.isArray(carouselAds)) { 3286 liveSnapshot.adsByPosition = liveSnapshot.adsByPosition || {}; 3287 liveSnapshot.ads = liveSnapshot.ads || {}; 3288 liveSnapshot.indexAds = liveSnapshot.indexAds || {}; 3289 liveSnapshot.adsByPosition['34627'] = carouselAds; 3290 liveSnapshot.ads.home_banners = carouselAds; 3291 liveSnapshot.indexAds.home_banners = carouselAds; 3292 liveSnapshot.home.carouselAds = carouselAds; 3293 liveSnapshot.adFreshnessByPosition = liveSnapshot.adFreshnessByPosition || {}; 3294 liveSnapshot.adFreshnessByPosition['34627'] = { 3295 source: 'wp/v2/advertisement', 3296 sourceFetchedAt: new Date().toISOString(), 3297 cacheStatus: 'direct-request', 3298 itemCount: carouselAds.length, 3299 setFingerprint: adSetFingerprint(carouselAds) 3300 }; 3301 } 3302 renderBackendData(liveSnapshot); 3303 document.documentElement.dataset.liveHomeData = 'connected'; 3304 return liveSnapshot; 3305 }; 3306
3307 renderBackendData(backendSnapshot); 3308 3309 document.querySelectorAll('.article').forEach((article) => { 3310 const titleLink = article.querySelector('.article-text h3 a'); 3311 const cover = article.querySelector(':scope > .cover'); 3312 if (!titleLink || !cover || cover.querySelector('a')) return; 3313 const coverLink = document.createElement('a'); 3314 coverLink.className = 'article-cover-link'; 3315 coverLink.href = titleLink.getAttribute('href') || '#'; 3316 coverLink.setAttribute('aria-label', titleLink.textContent.trim()); 3317 if (titleLink.target) coverLink.target = titleLink.target; 3318 if (titleLink.rel) coverLink.rel = titleLink.rel; 3319 while (cover.firstChild) coverLink.appendChild(cover.firstChild); 3320 cover.appendChild(coverLink); 3321 }); 3322 3323 document.querySelectorAll('.article-actions').forEach((actions) => { 3324 actions.innerHTML = ` 3325 <a class="action-item favorite-action" href="#login" data-gooood-favorite-trigger="1" role="button"> 3326 <span class="action-icon">â</span><span data-zh="æ¶è" data-en="Favorites">æ¶è</span> 3327 </a> 3328 <div class="action-item share-action"> 3329 <button type="button" aria-label="å享"><span class="action-icon">â</span><span data-zh="å享" data-en="Share">å享</span></button> 3330 <div class="share-icons-dropdown"> 3331 <a href="javascript:;" class="share-icon wechat" aria-label="微信">å¾®</a> 3332 <a href="javascript:;" class="share-icon weibo" aria-label="å¾®å">å</a> 3333 <a href="javascript:;" class="share-icon twitter" aria-label="X">X</a> 3334 <a href="javascript:;" class="share-icon facebook" aria-label="Facebook">f</a> 3335 <a href="javascript:;" class="share-icon pinterest" aria-label="Pinterest">P</a> 3336 <a href="javascript:;" class="share-icon copy-link" aria-label="å¤å¶é¾æ¥">é¾</a> 3337 </div> 3338 </div> 3339 `; 3340 }); 3341 3342 document.querySelectorAll('.article-actions').forEach((actions) => { 3343 const links = actions.querySelectorAll('a, button'); 3344 setBilingualText(links[0], 'æ¶è', 'Favorites'); 3345 setBilingualText(links[1], 'å享', 'Share'); 3346 }); 3347 document.querySelectorAll('.page-jump button').forEach((button) => setBilingualText(button, '跳页', 'Go')); 3348 3349 const translatable = () => Array.from(document.querySelectorAll('[data-zh][data-en]')); 3350 const languageToggles = Array.from(document.querySelectorAll('[data-lang-toggle]')); 3351 const applyLanguage = (next) => { 3352 language = next === 'en' ? 'en' : 'zh'; 3353 document.documentElement.lang = language === 'en' ? 'en' : 'zh-CN'; 3354 translatable().forEach((node) => { 3355 node.textContent = node.dataset[language] || ''; 3356 }); 3357 document.querySelectorAll('[data-placeholder-zh][data-placeholder-en]').forEach((node) => { 3358 node.setAttribute('placeholder', node.dataset[`placeholder${language === 'en' ? 'En' : 'Zh'}`] || ''); 3359 }); 3360 }; 3361 languageToggles.forEach((toggle) => { 3362 toggle.addEventListener('click', () => applyLanguage(language === 'zh' ? 'en' : 'zh')); 3363 }); 3364 applyLanguage('zh'); 3365 3366 const headerSearchToggle = document.querySelector('[data-header-search-toggle]'); 3367 const headerSearchPanel = document.querySelector('#header-search-panel'); 3368 const headerSearchInput = headerSearchPanel?.querySelector('input'); 3369 const setHeaderSearchOpen = (nextOpen) => { 3370 if (!headerSearchToggle || !headerSearchPanel) return; 3371 headerSearchToggle.setAttribute('aria-expanded', String(nextOpen)); 3372 headerSearchPanel.hidden = !nextOpen; 3373 if (nextOpen) { 3374 window.setTimeout(() => headerSearchInput?.focus(), 0); 3375 } 3376 }; 3377 const buildSearchPath = (value) => { 3378 const query = String(value || '').trim(); 3379 return query ? `https://www.gooood.cn/search/${encodeURIComponent(query)}` : ''; 3380 }; 3381 const bindSearchPathSubmit = (form) => { 3382 form?.addEventListener('submit', (event) => { 3383 const input = form.querySelector('input[name="q"], input[name="s"]'); 3384 const path = buildSearchPath(input?.value); 3385 if (!path) return; 3386 event.preventDefault(); 3387 const navigationTarget = document.documentElement.dataset.v10Embed === 'header' && window.top !== window 3388 ? window.top 3389 : window; 3390 navigationTarget.location.href = path; 3391 }); 3392 }; 3393 headerSearchToggle?.addEventListener('click', (event) => { 3394 event.preventDefault(); 3395 event.stopPropagation(); 3396 setHeaderSearchOpen(headerSearchToggle.getAttribute('aria-expanded') !== 'true'); 3397 }); 3398 headerSearchPanel?.addEventListener('click', (event) => { 3399 event.stopPropagation(); 3400 }); 3401 document.querySelectorAll('[data-header-search-close]').forEach((button) => { 3402 button.addEventListener('click', () => setHeaderSearchOpen(false)); 3403 }); 3404 document.addEventListener('click', () => setHeaderSearchOpen(false)); 3405 document.addEventListener('keydown', (event) => { 3406 if (event.key === 'Escape') setHeaderSearchOpen(false); 3407 }); 3408 bindSearchPathSubmit(document.querySelector('.header-search-form')); 3409 bindSearchPathSubmit(document.querySelector('.mobile-search-form')); 3410 3411 const mobileMenuToggle = document.querySelector('.mobile-menu-toggle'); 3412 const mobileMenu = document.querySelector('#mobile-menu'); 3413 const mobileMenuBackdrop = document.querySelector('.mobile-menu-backdrop'); 3414 const headerActions = document.querySelector('.header-actions'); 3415 const setMobileMenuOpen = (nextOpen) => { 3416 mobileMenuToggle?.setAttribute('aria-expanded', String(nextOpen)); 3417 if (mobileMenu) { 3418 mobileMenu.hidden = !nextOpen; 3419 mobileMenu.classList.toggle('is-open', nextOpen); 3420 } 3421 if (mobileMenuBackdrop) { 3422 mobileMenuBackdrop.hidden = !nextOpen; 3423 mobileMenuBackdrop.classList.toggle('is-open', nextOpen); 3424 } 3425 headerActions?.classList.toggle('menu-open', nextOpen); 3426 }; 3427 mobileMenuToggle?.addEventListener('click', () => { 3428 const isOpen = mobileMenuToggle.getAttribute('aria-expanded') === 'true'; 3429 setMobileMenuOpen(!isOpen); 3430 }); 3431 mobileMenuBackdrop?.addEventListener('click', () => setMobileMenuOpen(false)); 3432 document.addEventListener('keydown', (event) => { 3433 if (event.key === 'Escape') setMobileMenuOpen(false); 3434 }); 3435 document.querySelectorAll('.mobile-menu-parent').forEach((button) => { 3436 button.addEventListener('click', () => { 3437 button.closest('.mobile-menu-item')?.classList.toggle('is-open'); 3438 }); 3439 }); 3440 3441 const setupSlider = () => { 3442 const slider = document.querySelector('.top-slider'); 3443 if (!slider) return; 3444 const slides = Array.from(slider.querySelectorAll('.slide')); 3445 const dots = Array.from(slider.querySelectorAll('[data-sli
3445de-dot]')); 3446 const prev = slider.querySelector('[data-slide-prev]'); 3447 const next = slider.querySelector('[data-slide-next]'); 3448 if (!slides.length) return; 3449 let active = Math.max(0, slides.findIndex((slide) => slide.classList.contains('is-active'))); 3450 const loadSlideImage = (slide) => { 3451 const img = slide?.querySelector('img[data-src]'); 3452 if (!img) return; 3453 img.src = img.dataset.src || ''; 3454 img.removeAttribute('data-src'); 3455 }; 3456 3457 const show = (index) => { 3458 active = (index + slides.length) % slides.length; 3459 loadSlideImage(slides[active]); 3460 slides.forEach((slide, i) => slide.classList.toggle('is-active', i === active)); 3461 dots.forEach((dot, i) => dot.classList.toggle('is-active', i === active)); 3462 }; 3463 3464 if (prev) prev.onclick = () => show(active - 1); 3465 if (next) next.onclick = () => show(active + 1); 3466 dots.forEach((dot, i) => { 3467 dot.onclick = () => show(i); 3468 }); 3469 show(active); 3470 }; 3471 3472 if (document.documentElement.dataset.v10Embed === 'header') return; 3473 3474 setupSlider(); 3475 refreshLiveHomeData() 3476 .then((snapshot) => { 3477 if (!snapshot) return; 3478 applyLanguage(language); 3479 setupSlider(); 3480 }) 3481 .catch((error) => { 3482 document.documentElement.dataset.liveHomeData = 'snapshot-fallback'; 3483 console.warn('[gooood V10] live home data fallback', error); 3484 }); 3485 })(); 3486</script>
vendor: 1 bytes, line 3486
3486
3487<script data-v10-header-embed="1"> 3488 (() => { 3489 if (document.documentElement.dataset.v10Embed !== 'header' || window.parent === window) return; 3490 3491 const reportHeight = (height) => { 3492 window.parent.postMessage({ type: 'gooood-v10-header-height', height }, window.location.origin); 3493 }; 3494 const header = document.querySelector('.site-header'); 3495 const desktopHeight = 65; 3496 const expandedHeight = 460; 3497 3498 document.querySelectorAll('.site-header a[href]').forEach((link) => { 3499 const href = link.getAttribute('href') || ''; 3500 if (href && !href.startsWith('#') && !href.startsWith('javascript:')) link.target = '_top'; 3501 }); 3502 document.querySelectorAll('.site-header form').forEach((form) => { form.target = '_top'; }); 3503 3504 header?.addEventListener('pointerover', () => reportHeight(expandedHeight)); 3505 header?.addEventListener('pointerout', (event) => { 3506 if (!header.contains(event.relatedTarget)) reportHeight(desktopHeight); 3507 }); 3508 document.addEventListener('click', (event) => { 3509 if (event.target.closest('[data-header-search-toggle], .mobile-menu-toggle, .mobile-menu-parent')) { 3510 reportHeight(Math.max(expandedHeight, window.innerHeight)); 3511 } 3512 if (event.target.closest('[data-header-search-close], .mobile-menu-backdrop')) reportHeight(desktopHeight); 3513 }); 3514 new MutationObserver(() => { 3515 if (document.querySelector('.mobile-menu-toggle[aria-expanded="true"]')) { 3516 reportHeight(Math.max(expandedHeight, window.innerHeight)); 3517 } 3518 }).observe(document.documentElement, { attributes: true, subtree: true, attributeFilter: ['aria-expanded'] }); 3519 reportHeight(desktopHeight); 3520 })(); 3521</script>
vendor: 1 bytes, line 3521
3521
3522<script data-gooood-home-auth-favorites>(() => { 3523 if (window.__GOOOOD_HOME_AUTH_FAVORITES__) return; 3524 window.__GOOOOD_HOME_AUTH_FAVORITES__ = true; 3525 const API_BASE = 'https://dashboard.gooood.cn/wp-json'; 3526 const BROKEN_ACCOUNT_PATHS = new Set(['/member']); 3527 let pendingFavorite = null; 3528 let toastTimer = 0; 3529 let currentUser = null; 3530 let authMode = 'login'; 3531 let forgotMethod = 'email'; 3532 let telCodesLoaded = false; 3533 let telCodes = [{ en: 'China', zh: 'ä¸å½', locale: 'CN', code: '86' }]; 3534 let registerCountdown = 0; 3535 let forgotCountdown = 0; 3536 let registerCountdownTimer = 0; 3537 let forgotCountdownTimer = 0; 3538 let authRestoreRetryTimer = 0; 3539 let authRestoreRetryAttempts = 0; 3540 const ALIYUN_CAPTCHA_SRC = 'https://o.alicdn.com/captcha-frontend/aliyunCaptcha/AliyunCaptcha.js'; 3541 const CAPTCHA_INIT_TIMEOUT_MS = 90000; 3542 const CAPTCHA_VERIFY_TIMEOUT_MS = 180000; 3543 const CAPTCHA_LOAD_ERROR_GRACE_MS = 20000; 3544 const CAPTCHA_REQUEST_TIMEOUT_MS = 15000; 3545 const CAPTCHA_VISIBLE_ACTION_TIMEOUT_MS = 25000; 3546 const CAPTCHA_EXISTING_SCRIPT_TIMEOUT_MS = 3000; 3547 const CAPTCHA_MIN_WARMUP_MS = 2200; 3548 const CAPTCHA_UI_SCALE = 1; 3549 let aliyunCaptchaScriptPromise = null; 3550 3551 const logCaptchaDiagnostic = (stage, details = {}) => { 3552 try { 3553 window.console && window.console.warn && window.console.warn('[gooood sms captcha]', stage, JSON.stringify(details)); 3554 } catch (_) { 3555 // Best-effort browser-side diagnostics only. 3556 } 3557 }; 3558 const sanitizeAliyunResourceName = (name) => { 3559 try { 3560 const url = new URL(name); 3561 if (!/alicdn\.com$/.test(url.hostname)) return url.hostname; 3562 return `${url.hostname}${url.pathname}`; 3563 } catch (_) { 3564 return String(name || '').slice(0, 160); 3565 } 3566 }; 3567 const aliyunResourceDiagnostics = () => { 3568 try { 3569 return window.performance.getEntriesByType('resource') 3570 .filter((entry) => /captcha|FeiLin|aliyun/i.test(entry.name)) 3571 .slice(-12) 3572 .map((entry) => ({ 3573 name: sanitizeAliyunResourceName(entry.name), 3574 type: entry.initiatorType || 'unknown', 3575 durationMs: Math.round(entry.duration), 3576 transferSize: entry.transferSize || 0, 3577 decodedBodySize: entry.decodedBodySize || 0 3578 })); 3579 } catch (_) { 3580 return []; 3581 } 3582 }; 3583 const cookieValue = (name) => { 3584 const prefix = `${name}=`; 3585 const values = document.cookie.split(';').map((part) => part.trim()).filter((part) => part.startsWith(prefix)).map((part) => { 3586 try { return decodeURIComponent(part.slice(prefix.length)); } catch (_) { return part.slice(prefix.length); } 3587 }).filter(Boolean); 3588 return values.length ? values[values.length - 1] : ''; 3589 }; 3590 const saveToken = (token, expire) => { 3591 const stale = ['auth_token=', 'Path=/', 'SameSite=Lax', 'Max-Age=0']; 3592 if (window.location.protocol === 'https:') stale.push('Secure'); 3593 document.cookie = stale.join('; '); 3594 const parts = [`auth_token=${encodeURIComponent(token)}`, 'Path=/', 'SameSite=Lax']; 3595 if (window.location.protocol === 'https:') parts.push('Secure'); 3596 if (window.location.hostname === 'gooood.cn' || window.location.hostname.endsWith('.gooood.cn')) parts.push('Domain=.gooood.cn'); 3597 const unix = Number(expire); 3598 if (Number.isFinite(unix) && unix > 0) parts.push(`Expires=${new Date(unix * 1000).toUTCString()}`); 3599 document.cookie = parts.join('; '); 3600 }; 3601 const clearToken = () => { 3602 const expire = (domain = '') => { 3603 const parts = ['auth_token=', 'Path=/', 'SameSite=Lax', 'Max-Age=0']; 3604 if (window.location.protocol === 'https:') parts.push('Secure'); 3605 if (domain) parts.push(`Domain=${domain}`); 3606 document.cookie = parts.join('; '); 3607 }; 3608 expire(); 3609 if (window.location.hostname === 'gooood.cn' || window.location.hostname.endsWith('.gooood.cn')) expire('.gooood.cn'); 3610 }; 3611 const resolveAvatarUrl = (user) => { 3612 if (!user) return ''; 3613 if (user.avatar) return user.avatar; 3614 if (user.user_data && user.user_data.avatar) return user.user_data.avatar; 3615 const urls = user.avatar_urls; 3616 if (urls && typeof urls === 'object') return urls['96'] || urls['48'] || urls['24'] || Object.values(urls)[0] || ''; 3617 return ''; 3618 }; 3619 const resolveDisplayName = (user) => { 3620 if (!user) return ''; 3621 return user.displayname || user.name || (user.user_data && user.user_data.nickname) || user.nickname || ''; 3622 }; 3623 const resolveUserId = (user) => Number(user && (user.id || (user.user_data && user.user_data.id))) || 0; 3624 const hasRole = (user, expected) => { 3625 const roles = user && (user.roles || (user.user_data && user.user_data.roles)); 3626 if (Array.isArray(roles)) return roles.includes(expected); 3627 return Boolean(roles && typeof roles === 'object' && roles[expected]); 3628 }; 3629 const setAuthState = (status, user) => { 3630 window.__GOOOOD_HOME_AUTH_STATE__ = { status, userId: resolveUserId(user) || null }; 3631 }; 3632 const closeAccountMenus = (except = null) => { 3633 document.querySelectorAll('.gooood-account.is-open').forEach((account) => { 3634 if (account === except) return; 3635 account.classList.remove('is-open'); 3636 const toggle = account.querySelector('[data-gooood-account-toggle]'); 3637 if (toggle) toggle.setAttribute('aria-expanded', 'false'); 3638 }); 3639 }; 3640 const appendMenuLink = (menu, href, zh, en, options = {}) => { 3641 const link = document.createElement('a'); 3642 link.href = href; 3643 link.dataset.zh = zh; 3644 link.dataset.en = en; 3645 link.textContent = currentLanguage() === 'en' ? en : zh; 3646 if (options.external) link.rel = 'noopener'; 3647 menu.appendChild(link); 3648 }; 3649 const renderLoggedOutSlot = (slot) => { 3650 const mode = slot.dataset.goooodAuthSlot || 'desktop'; 3651 const link = document.createElement('a'); 3652 link.href = '#login'; 3653 link.dataset.goooodAuthMember = mode; 3654 link.dataset.goooodLoginTrigger = '1'; 3655 link.dataset.zh = 'ä¼å/ç»å½'; 3656 link.dataset.en = 'VIP/Login'; 3657 if (mode === 'mobile') { 3658 const icon = document.createElement('span'); 3659 icon.className = 'mobile-user-icon'; 3660 icon.textContent = 'â'; 3661 link.appendChild(icon); 3662 } 3663 const label = document.createElement('span'); 3664 label.dataset.zh = 'ä¼å/ç»å½'; 3665 label.dataset.en = 'VIP/Login'; 3666 label.textContent = currentLanguage() === 'en' ? 'VIP/Login' : 'ä¼å/ç»å½'; 3667 link.appendChild(label); 3668 slot.replaceChildren(link); 3669 }; 3670 const renderLoggedInSlot = (slot, user) => { 3671 const mode = slot.dataset.goooodAuthSlot || 'desktop'; 3672 const displayName = resolveDisplayName(user) || (currentLanguage() === 'en' ? 'Member' : 'ä¼å'); 3673 const avatarUrl = resolveAvatarUrl(user); 3674 const userId = resolveUserId(user); 3675 const account = document.createElement('div'); 3676 account.className = `gooood-account gooood-account--${mode}`; 3677 3678 const toggle = document.createElement('button'); 3679 toggle.type = 'button'; 3680 toggle.className = 'gooood-account-toggle'; 3681 toggle.dataset.goooodAccountToggle = '1'; 3682 toggle.setAttribute('aria-haspopup', 'menu'); 3683 toggle.setAttribute('aria-expanded', 'false'); 3684 toggle.setAttribute('aria-label', `${displayName} - ${currentLanguage() === 'en' ? 'Account menu' : 'è´¦æ·èå'}`); 3685 3686 if (avatarUrl) { 3687 const avatar = document.createElement('img'); 3688 avatar.className = 'gooood-account-avatar'; 3689 avatar.src = avatarUrl; 3690 avatar.alt = displayName; 3691 avatar.referrerPolicy = 'no-referrer'; 3692 toggle.appendChild(avatar); 3693 } else { 3694 const placeholder = document.createElement('span'); 3695 placeholder.className = 'gooood-account-avatar gooood-account-avatar--placeholder'; 3696 placeholder.setAttribute('aria-hidden', 'true'); 3697 toggle.appendChild(placeholder); 3698 } 3699 const name = document.createElement('span'); 3700 name.className = 'gooood-account-name'; 3701 name.textContent = displayName; 3702 toggle.appendChild(name); 3703 3704 const menu = document.createElement('div'); 3705 menu.className = 'gooood-account-menu'; 3706 menu.setAttribute('role', 'menu'); 3707 if (hasRole(user, 'administrator') || hasRole(user, 'editor') || hasRole(user, 'author')) { 3708 appendMenuLink(menu, 'https://dashboard.gooood.cn/wp-admin/', '管çåå°', 'Dashboard', { external: true }); 3709 } 3710 if (user && user.user_data && user.user_data.brand) appendMenuLink(menu, '/account/report', 'åçä¸å¿', 'Brand Center'); 3711 if (userId) appendMenuLink(menu, `/people/${encodeURIComponent(String(userId))}`, '个人ä¸å¿', 'Profile'); 3712 appendMenuLink(menu, '/account/profile', '设置', 'Settings'); 3713 const divider = document.createElement('span'); 3714 divider.className = 'gooood-account-divider'; 3715 divider.setAttribute('aria-hidden', 'true'); 3716 menu.appendChild(divider); 3717 const logout = document.createElement('button'); 3718 logout.type = 'button'; 3719 logout.dataset.goooodAccountLogout = '1'; 3720 logout.dataset.zh = 'éåºç»å½'; 3721 logout.dataset.en = 'Log out'; 3722 logout.textContent = currentLanguage() === 'en' ? 'Log out' : 'éåºç»å½'; 3723 menu.appendChild(logout); 3724 3725 account.append(toggle, menu); 3726 slot.replaceChildren(account); 3727 }; 3728 const updateMemberUI = (user) => { 3729 currentUser = user || null; 3730 closeAccountMenus(); 3731 document.querySelectorAll('[data-gooood-auth-slot]').forEach((slot) => { 3732 if (user) renderLoggedInSlot(slot, user); 3733 else renderLoggedOutSlot(slot); 3734 }); 3735 setAuthState(user ? 'authenticated' : 'logged-out', user); 3736 }; 3737 const isConfirmedAuthInvalidation = (error) => { 3738 const status = Number(error && (error.status || error.statusCode || (error.data && error.data.status)) || 0); 3739 const code = String(error && (error.code || (error.data && (error.data.code || error.data.error))) || '').toLowerCase(); 3740 if (status === 401) return true; 3741 return [ 3742 'gooood_account_temporarily_unavailable', 3743 'gooood_jwt_expired_by_security_policy', 3744 'gooood_login_name_security_hold', 3745 'jwt_auth_bad_auth_header',
3746 'jwt_auth_invalid_token', 3747 'jwt_auth_no_auth_header', 3748 'rest_not_logged_in' 3749 ].includes(code); 3750 }; 3751 const scheduleAuthRestoreRetry = () => { 3752 const delays = [1500, 5000, 15000]; 3753 if (authRestoreRetryTimer || authRestoreRetryAttempts >= delays.length) return; 3754 const delay = delays[authRestoreRetryAttempts++]; 3755 authRestoreRetryTimer = window.setTimeout(() => { 3756 authRestoreRetryTimer = 0; 3757 checkAndRestoreAuth(); 3758 }, delay); 3759 }; 3760 const retainAuthAfterTemporaryFailure = () => { 3761 setAuthState('temporarily-unavailable', null); 3762 scheduleAuthRestoreRetry(); 3763 }; 3764 const checkAndRestoreAuth = async () => { 3765 const token = cookieValue('auth_token'); 3766 if (!token) { updateMemberUI(null); return; } 3767 try { 3768 const user = await apiRequest('/wp/v2/users/me', { token }); 3769 authRestoreRetryAttempts = 0; 3770 updateMemberUI(user); 3771 } catch (error) { 3772 if (isConfirmedAuthInvalidation(error)) { 3773 clearToken(); 3774 updateMemberUI(null); 3775 } else { 3776 retainAuthAfterTemporaryFailure(); 3777 } 3778 } 3779 }; 3780 const apiRequest = async (path, options = {}) => { 3781 const headers = { Accept: 'application/json', ...(options.headers || {}) }; 3782 if (options.body) headers['Content-Type'] = 'application/json'; 3783 const token = options.token || cookieValue('auth_token'); 3784 if (token && options.auth !== false) headers.Authorization = `Bearer ${token}`; 3785 const response = await fetch(`${API_BASE}${path}`, { method: options.method || 'GET', body: options.body ? JSON.stringify(options.body) : undefined, headers, credentials: 'omit', cache: 'no-store' }); 3786 const data = await response.json().catch(() => ({})); 3787 if (!response.ok) { 3788 const error = new Error(data.msg || data.message || `请æ±å¤±è´¥ï¼${response.status}ï¼`); 3789 error.status = response.status; 3790 error.code = data.code; 3791 error.data = data; 3792 throw error; 3793 } 3794 return data; 3795 }; 3796 3797 const modal = document.createElement('div'); 3798 modal.className = 'gooood-auth-modal'; 3799 modal.hidden = true; 3800 modal.innerHTML = `<div class="gooood-auth-dialog" role="dialog" aria-modal="true" aria-labelledby="gooood-auth-title"><button class="gooood-auth-close" type="button" aria-label="å ³éç»å½">Ã</button><form class="gooood-auth-form"><h2 id="gooood-auth-title" data-zh="ä¼åç»å½" data-en="Member Login">ä¼åç»å½</h2><div class="gooood-auth-panel" data-auth-panel="login"><label class="gooood-auth-field"><span>è´¦å·</span><input name="username" type="text" autocomplete="username" data-placeholder-zh="请è¾å ¥è´¦å·æææºå·" data-placeholder-en="Username or mobile" placeholder="请è¾å ¥è´¦å·æææºå·" required></label><label class="gooood-auth-field"><span>å¯ç </span><input name="password" type="password" autocomplete="current-password" data-placeholder-zh="请è¾å ¥å¯ç " data-placeholder-en="Password" placeholder="请è¾å ¥å¯ç " required></label></div><div class="gooood-auth-panel" data-auth-panel="register" hidden><label class="gooood-auth-field"><span>åºå·</span><select name="register_region" autocomplete="tel-country-code"></select></label><label class="gooood-auth-field"><span>ææºå·</span><input name="register_mobile" type="tel" inputmode="tel" autocomplete="tel" data-placeholder-zh="请è¾å ¥ææºå·" data-placeholder-en="Mobile number" placeholder="请è¾å ¥ææºå·"></label><div class="gooood-auth-code-row"><label class="gooood-auth-field"><span>éªè¯ç </span><input name="register_code" type="text" inputmode="numeric" autocomplete="one-time-code" data-placeholder-zh="请è¾å ¥éªè¯ç " data-placeholder-en="Verification code" placeholder="请è¾å ¥éªè¯ç "></label><button class="gooood-auth-code" type="button" data-code-kind="register" data-zh="è·åéªè¯ç " data-en="Get code">è·åéªè¯ç </button></div><label class="gooood-auth-field"><span>å¯ç </span><input name="register_password" type="password" autocomplete="new-password" data-placeholder-zh="请è¾å ¥å¯ç " data-placeholder-en="Password" placeholder="请è¾å ¥å¯ç "></label><label class="gooood-auth-field"><span>确认å¯ç </span><input name="register_password2" type="password" autocomplete="new-password" data-placeholder-zh="è¯·åæ¬¡è¾å ¥å¯ç " data-placeholder-en="Confirm password" placeholder="è¯·åæ¬¡è¾å ¥å¯ç "></label></div><div class="gooood-auth-panel" data-auth-panel="forgot" hidden><div class="gooood-auth-forgot-email" data-forgot-method-panel="email"><p class="gooood-auth-hint" data-zh="请è¾å ¥ç¨æ·åæé®ç®±å°åãä½ å°éè¿é®ç®±æ¶å°å建æ°å¯ç ç龿¥ã" data-en="Please enter your username or email address. You will receive a link to create a new password via email.">请è¾å ¥ç¨æ·åæé®ç®±å°åãä½ å°éè¿é®ç®±æ¶å°å建æ°å¯ç ç龿¥ã</p><label class="gooood-auth-field"><span>Username or E-mail</span><input name="reset_login" type="text" autocomplete="username" data-placeholder-zh="username or email address" data-placeholder-en="username or email address" placeholder="username or email address"></label><button class="gooood-auth-method-toggle" type="button" data-auth-forgot-method="phone" data-zh="ææºå·æ¾å »" data-en="Mobile recovery »">ææºå·æ¾å »</button></div><div class="gooood-auth-forgot-phone" data-forgot-method-panel="phone" hidden><label class="gooood-auth-field"><span>åºå·</span><select name="forgot_region" autocomplete="tel-country-code"></select></label><label class="gooood-auth-field"><span>ææºå·</span><input name="forgot_mobile" type="tel" inputmode="tel" autocomplete="tel" data-placeholder-zh="å¡«åææºå·" data-placeholder-en="Mobile number" placeholder="å¡«åææºå·"></label><div class="gooood-auth-code-row"><label class="gooood-auth-field"><span>éªè¯ç </span><input name="forgot_code" type="text" inputmode="numeric" autocomplete="one-time-code" data-placeholder-zh="éªè¯ç " data-placeholder-en="Verification code" placeholder="éªè¯ç "></label><button class="gooood-auth-code" type="button" data-code-kind="forgot" data-zh="è·åéªè¯ç " data-en="Get code">è·åéªè¯ç </button></div><label class="gooood-auth-field"><span>æ°å¯ç </span><input name="forgot_password" type="password" autocomplete="new-password" data-placeholder-zh="æ°å¯ç " data-placeholder-en="New password" placeholder="æ°å¯ç "></label><label class="gooood-auth-field"><span>确认å¯ç </span><input name="forgot_password2" type="password" autocomplete="new-password" data-placeholder-zh="确认å¯ç " data-placeholder-en="Confirm password" placeholder="确认å¯ç "></label><button class="gooood-auth-method-toggle" type="button" data-auth-forgot-method="email" data-zh="é®ç®±æ¾å »" data-en="Email recovery »">é®ç®±æ¾å »</button></div></div><p class="gooood-auth-error" role="alert" hidden></p><p class="gooood-auth-feedback" role="status" hidden></p><button class="gooood-auth-submit" type="submit" data-zh="ç»å½" data-en="Login">ç»å½</button><div class="gooood-auth-links"><button type="button" data-auth-mode-button="register" data-zh="ææºå·æ³¨å »" data-en="Mobile register »">ææºå·æ³¨å »</button><button type="button" data-auth-mode-button="forgot" data-zh="å¿è®°å¯ç ï¼" data-en="Forgot password?">å¿è®°å¯ç ï¼</button></div><div class="gooood-auth-social"><div class="gooood-auth-divider" data-zh="社交ç»å½" data-en="Social Login">社交ç»å½</div><button class="gooood-auth-wechat" type="button" data-zh="微信ç»å½" data-en="Login with WeChat">微信ç»å½</button></div></form></div>`; 3801 document.body.appendChild(modal); 3802 const toast = document.createElement('div'); 3803 toast.className = 'gooood-auth-toast'; 3804 toast.setAttribute('role', 'status'); 3805 toast.hidden = true; 3806 document.body.appendChild(toast); 3807 const form = modal.querySelector('.gooood-auth-form'); 3808 const titleNode = modal.querySelector('#gooood-auth-title'); 3809 const errorNode = modal.querySelector('.gooood-auth-error'); 3810 const feedbackNode = modal.querySelector('.gooood-auth-feedback'); 3811 const submitButton = modal.querySelector('.gooood-auth-submit'); 3812 const codeButtons = Array.from(modal.querySelectorAll('.gooood-auth-code')); 3813 const wechatButton = modal.querySelector('.gooood-auth-wechat'); 3814 const socialBlock = modal.querySelector('.gooood-auth-social'); 3815 const wechatMobileGuidance = document.createElement('p'); 3816 wechatMobileGuidance.className = 'gooood-auth-wechat-mobile-guidance'; 3817 wechatMobileGuidance.setAttribute('role', 'status'); 3818 wechatMobileGuidance.dataset.zh = '微信ç»å½è¯·å¨å¾®ä¿¡å æå¼ãå½åæµè§å¨ä¼æ¾ç¤ºçµèæ«ç ï¼æ æ³å¨åä¸é¨ææºå®æç»å½ã'; 3819 wechatMobileGuidance.dataset.en = 'Open this page in WeChat to continue. This browser can only show a desktop QR code.'; 3820 wechatMobileGuidance.hidden = true; 3821 socialBlock.appendChild(wechatMobileGuidance); 3822 const currentLanguage = () => document.documentElement.lang === 'en' ? 'en' : 'zh'; 3823 const currentPathLanguage = () => /^\/en(?:\/|$)/.test(window.location.pathname) ? 'en' : 'zh';
3824 const isExternalMobileWechatLogin = () => window.matchMedia('(max-width: 767px)').matches && !/MicroMessenger/i.test(navigator.userAgent); 3825 const syncWechatLoginEntry = () => { 3826 const showGuidance = isExternalMobileWechatLogin(); 3827 wechatButton.hidden = showGuidance; 3828 wechatMobileGuidance.hidden = !showGuidance; 3829 if (showGuidance) wechatButton.disabled = false; 3830 }; 3831 const mobileWechatLoginMedia = window.matchMedia('(max-width: 767px)'); 3832 if (typeof mobileWechatLoginMedia.addEventListener === 'function') mobileWechatLoginMedia.addEventListener('change', syncWechatLoginEntry); 3833 const stripEnglishPrefix = (path) => { 3834 const normalized = path && path.startsWith('/') ? path : `/${path || ''}`; 3835 if (normalized === '/en' || normalized === '/en/') return '/'; 3836 return normalized.startsWith('/en/') ? normalized.slice(3) || '/' : normalized; 3837 }; 3838 const localizedPath = (path, language) => { 3839 const clean = stripEnglishPrefix(path); 3840 if (language !== 'en') return clean; 3841 return clean === '/' ? '/en/' : `/en${clean}`; 3842 }; 3843 const saveLanguage = (language) => { 3844 const parts = [ 3845 `language=${language === 'en' ? 'en_US' : 'zh_CN'}`, 3846 'Path=/', 3847 'SameSite=Lax', 3848 'Max-Age=31536000' 3849 ]; 3850 if (window.location.protocol === 'https:') parts.push('Secure'); 3851 if (window.location.hostname === 'gooood.cn' || window.location.hostname.endsWith('.gooood.cn')) parts.push('Domain=.gooood.cn'); 3852 document.cookie = parts.join('; '); 3853 }; 3854 const switchLanguage = (language) => { 3855 saveLanguage(language); 3856 const url = new URL(window.location.href); 3857 url.pathname = localizedPath(url.pathname, language); 3858 url.searchParams.delete('lang'); 3859 window.location.assign(`${url.pathname}${url.search}${url.hash}`); 3860 }; 3861 const responseMessage = (response, fallback) => String((response && (response.msg || response.message)) || fallback).split('|')[0] || fallback; 3862 const responseSucceeded = (response) => { 3863 if (!response) return true; 3864 const status = String(response.status || '').toLowerCase(); 3865 const code = String(response.code || ''); 3866 return status === '1' || status === 'success' || code === '200'; 3867 }; 3868 const showToast = (zh, en = zh) => { 3869 window.clearTimeout(toastTimer); 3870 toast.textContent = currentLanguage() === 'en' ? en : zh; 3871 toast.hidden = false; 3872 toastTimer = window.setTimeout(() => { toast.hidden = true; }, 2600); 3873 }; 3874 const setError = (message = '') => { errorNode.textContent = message; errorNode.hidden = !message; }; 3875 const setFeedback = (message = '') => { feedbackNode.textContent = message; feedbackNode.hidden = !message; }; 3876 const applyModalLanguage = () => { 3877 const language = currentLanguage(); 3878 modal.querySelectorAll('[data-zh][data-en]').forEach((node) => { node.textContent = node.dataset[language] || node.dataset.zh || ''; }); 3879 modal.querySelectorAll('[data-placeholder-zh][data-placeholder-en]').forEach((node) => { node.placeholder = language === 'en' ? node.dataset.placeholderEn : node.dataset.placeholderZh; }); 3880 }; 3881 const updateCodeButton = (kind, busy = false) => { 3882 const button = modal.querySelector(`[data-code-kind="${kind}"]`); 3883 if (!button) return; 3884 const countdown = kind === 'register' ? registerCountdown : forgotCountdown; 3885 if (busy) button.textContent = 'éªè¯ä¸...'; 3886 else if (countdown > 0) button.textContent = `å·²åé ${countdown} s`; 3887 else button.textContent = currentLanguage() === 'en' ? 'Get code' : 'è·åéªè¯ç '; 3888 button.disabled = busy || countdown > 0; 3889 }; 3890 const startCodeCountdown = (kind) => { 3891 if (kind === 'register' && registerCountdownTimer) window.clearInterval(registerCountdownTimer); 3892 if (kind === 'forgot' && forgotCountdownTimer) window.clearInterval(forgotCountdownTimer); 3893 if (kind === 'register') registerCountdown = 60; 3894 else forgotCountdown = 60; 3895 updateCodeButton(kind); 3896 const timer = window.setInterval(() => { 3897 if (kind === 'register') registerCountdown -= 1; 3898 else forgotCountdown -= 1; 3899 if ((kind === 'register' ? registerCountdown : forgotCountdown) <= 0) { 3900 if (kind === 'register') registerCountdown = 0; 3901 else forgotCountdown = 0; 3902 window.clearInterval(timer); 3903 } 3904 updateCodeButton(kind); 3905 }, 1000); 3906 if (kind === 'register') registerCountdownTimer = timer; 3907 else forgotCountdownTimer = timer; 3908 }; 3909 const populateTelSelects = () => { 3910 modal.querySelectorAll('select[name="register_region"], select[name="forgot_region"]').forEach((select) => { 3911 const selected = select.value || '86'; 3912 select.replaceChildren(...telCodes.map((item) => { 3913 const option = document.createElement('option');
3914 option.value = String(item.code); 3915 option.textContent = `${item.zh} + ${item.code}`; 3916 if (option.value === selected) option.selected = true; 3917 return option; 3918 })); 3919 if (!select.value) select.value = '86'; 3920 }); 3921 }; 3922 const loadTelCodes = async () => { 3923 populateTelSelects(); 3924 if (telCodesLoaded) { populateTelSelects(); return; } 3925 try { 3926 const response = await apiRequest('/wp/v2/tel/code', { auth: false }); 3927 if (Array.isArray(response) && response.length) telCodes = response; 3928 telCodesLoaded = true; 3929 } catch (_) { 3930 telCodes = [{ en: 'China', zh: 'ä¸å½', locale: 'CN', code: '86' }]; 3931 } 3932 populateTelSelects(); 3933 }; 3934 const ensureAliyunCaptchaElements = () => { 3935 const existingElement = document.getElementById('gooood-aliyun-captcha-element'); 3936 if (!existingElement) { 3937 const element = document.createElement('div'); 3938 element.id = 'gooood-aliyun-captcha-element'; 3939 document.body.appendChild(element); 3940 } else { 3941 existingElement.removeAttribute('style'); 3942 } 3943 if (!document.getElementById('gooood-aliyun-captcha-button')) { 3944 const button = document.createElement('button'); 3945 button.id = 'gooood-aliyun-captcha-button'; 3946 button.type = 'button'; 3947 button.style.position = 'fixed'; 3948 button.style.left = '0'; 3949 button.style.top = '0'; 3950 button.style.width = '1px'; 3951 button.style.height = '1px'; 3952 button.style.opacity = '0.01'; 3953 button.style.zIndex = '1'; 3954 document.body.appendChild(button); 3955 } 3956 }; 3957 const normalizeCaptchaParam = (payload) => { 3958 if (typeof payload === 'string') return payload; 3959 if (!payload || typeof payload !== 'object') return ''; 3960 const value = payload.captchaVerifyParam || payload.CaptchaVerifyParam || payload.verifyParam || payload.token || payload.verifyToken || payload.data; 3961 if (typeof value === 'string') return value; 3962 if (value && typeof value === 'object') return JSON.stringify(value); 3963 return JSON.stringify(payload); 3964 }; 3965 const loadAliyunCaptchaScript = () => { 3966 window.AliyunCaptchaConfig = { region: 'cn', prefix: 'svsmdc' }; 3967 if (typeof window.initAliyunCaptcha === 'function') return Promise.resolve(); 3968 if (aliyunCaptchaScriptPromise) return aliyunCaptchaScriptPromise; 3969 3970 aliyunCaptchaScriptPromise = new Promise((resolve, reject) => { 3971 let settled = false; 3972 let existingGuard = 0; 3973 const settleResolve = () => { 3974 if (settled) return; 3975 settled = true; 3976 if (existingGuard) window.clearTimeout(existingGuard); 3977 resolve(); 3978 }; 3979 const settleReject = (stage, error, details = {}) => { 3980 if (settled) return; 3981 settled = true; 3982 if (existingGuard) window.clearTimeout(existingGuard); 3983 logCaptchaDiagnostic(stage, details); 3984 reject(error); 3985 }; 3986 const injectScript = () => { 3987 const script = document.createElement('script'); 3988 script.src = ALIYUN_CAPTCHA_SRC; 3989 script.async = true; 3990 script.onload = () => { 3991 if (typeof window.initAliyunCaptcha === 'function') { 3992 settleResolve(); 3993 return; 3994 } 3995 settleReject('script_load_without_init', new Error('人æºéªè¯å 载失败ï¼è¯·å·æ°åéè¯')); 3996 }; 3997 script.onerror = () => { 3998 settleReject('script_load_error', new Error('人æºéªè¯å 载失败ï¼è¯·å·æ°åéè¯')); 3999 }; 4000 document.head.appendChild(script); 4001 }; 4002 4003 const existing = document.querySelector(`script[src="${ALIYUN_CAPTCHA_SRC}"]`); 4004 if (existing) { 4005 existing.addEventListener('load', () => { 4006 if (typeof window.initAliyunCaptcha === 'function') settleResolve(); 4007 else settleReject('script_existing_without_init', new Error('人æºéªè¯å 载失败ï¼è¯·å·æ°åéè¯'), { reason: 'load_without_init' }); 4008 }, { once: true }); 4009 existing.addEventListener('error', () => { 4010 settleReject('script_existing_error', new Error('人æºéªè¯å 载失败ï¼è¯·å·æ°åéè¯')); 4011 }, { once: true }); 4012 existingGuard = window.setTimeout(() => { 4013 if (typeof window.initAliyunCaptcha === 'function') settleResolve(); 4014 else settleReject('script_existing_missing_init', new Error('人æºéªè¯å 载失败ï¼è¯·å·æ°åéè¯')); 4015 }, CAPTCHA_EXISTING_SCRIPT_TIMEOUT_MS); 4016 return; 4017 } 4018 4019 injectScript(); 4020 }); 4021 return aliyunCaptchaScriptPromise; 4022 }; 4023 const captchaErrorMessage = (error, fallback = '人æºéªè¯å¤±è´¥ï¼è¯·éè¯') => { 4024 if (error && error.message) return error.message; 4025 if (error && typeof error === 'object') { 4026 const code = error.code ? String(error.code) : ''; 4027 const msg = error.msg || error.message; 4028 if (msg) return code ? `${code}: ${String(msg)}` : String(msg); 4029 } 4030 return fallback; 4031 }; 4032 const ensureGoooodAliyunCaptchaSms = () => { 4033 if (window.goooodAliyunCaptchaSms) return; 4034 let instance = null; 4035 let loading = false;
4036 let waiters = []; 4037 let pending = null; 4038 let pendingFail = null; 4039 let pendingTimer = 0; 4040 let initGuard = 0; 4041 let loadErrorGuard = 0; 4042 let visibleActionGuard = 0; 4043 let preferVisible = false; 4044 let reinitializeBeforeNextRun = false; 4045 let instanceReadyAt = 0; 4046 4047 const clearVisibleActionGuard = () => { 4048 if (visibleActionGuard) window.clearTimeout(visibleActionGuard); 4049 visibleActionGuard = 0; 4050 }; 4051 const clearPendingTimer = () => { 4052 if (pendingTimer) window.clearTimeout(pendingTimer); 4053 pendingTimer = 0; 4054 }; 4055 const armVisibleActionGuard = () => { 4056 clearVisibleActionGuard(); 4057 visibleActionGuard = window.setTimeout(() => { 4058 if (!pending) return; 4059 reinitializeBeforeNextRun = true; 4060 rejectPending(new Error('人æºéªè¯å è½½è¶ æ¶ï¼è¯·éæ°ç¹å»è·åéªè¯ç ')); 4061 }, CAPTCHA_VISIBLE_ACTION_TIMEOUT_MS); 4062 }; 4063 const armPendingTimer = () => { 4064 clearPendingTimer(); 4065 pendingTimer = window.setTimeout(() => { 4066 rejectPending(new Error('captcha_callback_timeout')); 4067 }, CAPTCHA_VERIFY_TIMEOUT_MS); 4068 }; 4069 const clearInitGuard = () => { 4070 if (initGuard) window.clearTimeout(initGuard); 4071 initGuard = 0; 4072 if (loadErrorGuard) window.clearTimeout(loadErrorGuard); 4073 loadErrorGuard = 0; 4074 }; 4075 const finish = (payload) => { 4076 const value = normalizeCaptchaParam(payload); 4077 if (!value) { 4078 rejectPending(new Error('人æºéªè¯ç»ææ æï¼è¯·éæ°ç¹å»è·åéªè¯ç ')); 4079 return; 4080 } 4081 clearPendingTimer(); 4082 clearVisibleActionGuard(); 4083 clearInitGuard(); 4084 loading = false; 4085 reinitializeBeforeNextRun = true; 4086 resolveWaiters(); 4087 const callback = pending; 4088 pending = null; 4089 pendingFail = null; 4090 if (callback) callback(value); 4091 }; 4092 const handleChallengeFailure = () => { 4093 // Aliyun refreshes a failed challenge in-place. Keep this request pending so 4094 // the user can complete the refreshed challenge without clicking SMS again. 4095 }; 4096 const handleLoadError = (error) => { 4097 reinitializeBeforeNextRun = true; 4098 logCaptchaDiagnostic(instance ? 'sdk_on_error_after_instance' : 'sdk_on_error_before_instance', { 4099 message: captchaErrorMessage(error, '') 4100 }); 4101 if (instance) { 4102 if (pending) rejectPending(error || new Error('人æºéªè¯ç½ç»è¯·æ±è¶ æ¶ï¼è¯·éæ°ç¹å»è·åéªè¯ç ')); 4103 return; 4104 } 4105 // The SDK can report a transient resource timeout before getInstance arrives. 4106 // Give that late initialization a short recovery window instead of showing a 4107 // terminal business error while the challenge is still appearing. 4108 if (!loading || instance) return; 4109 if (loadErrorGuard) window.clearTimeout(loadErrorGuard); 4110 loadErrorGuard = window.setTimeout(() => { 4111 loadErrorGuard = 0; 4112 if (!loading || instance) return; 4113 loading = false; 4114 if (initGuard) window.clearTimeout(initGuard); 4115 initGuard = 0; 4116 rejectWaiters(error || new Error('人æºéªè¯å è½½è¶ æ¶ï¼è¯·å·æ°åéè¯')); 4117 }, CAPTCHA_LOAD_ERROR_GRACE_MS); 4118 }; 4119 const rejectPending = (error) => { 4120 clearVisibleActionGuard(); 4121 clearPendingTimer(); 4122 clearInitGuard(); 4123 loading = false; 4124 const callback = pendingFail; 4125 pending = null; 4126 pendingFail = null; 4127 if (callback) callback(error); 4128 }; 4129 const resolveWaiters = () => { 4130 const queue = waiters.slice(); 4131 waiters = []; 4132 queue.forEach(({ resolve }) => resolve()); 4133 }; 4134 const rejectWaiters = (error) => { 4135 const queue = waiters.slice(); 4136 waiters = []; 4137 queue.forEach(({ reject }) => reject(error)); 4138 }; 4139 const ready = (resolve, reject) => { 4140 ensureAliyunCaptchaElements(); 4141 loadAliyunCaptchaScript().then(() => { 4142 if (instance) { resolve(); return; } 4143 waiters.push({ resolve, reject }); 4144 if (loading) return; 4145 loading = true; 4146 initGuard = window.setTimeout(() => { 4147 if (!loading) return; 4148 loading = false;
4149 rejectWaiters(new Error('captcha_init_timeout')); 4150 }, CAPTCHA_INIT_TIMEOUT_MS); 4151 4152 try { 4153 window.initAliyunCaptcha({ 4154 SceneId: '1rjb4fqs', 4155 mode: 'popup', 4156 element: '#gooood-aliyun-captcha-element', 4157 button: '#gooood-aliyun-captcha-button', 4158 success: finish, 4159 fail: handleChallengeFailure, 4160 onError: handleLoadError, 4161 getInstance: (captcha) => { 4162 clearInitGuard(); 4163 instance = captcha; 4164 instanceReadyAt = Date.now(); 4165 logCaptchaDiagnostic('sdk_instance_ready', { 4166 hasStartTracelessVerification: typeof captcha.startTracelessVerification === 'function', 4167 hasShow: typeof captcha.show === 'function', 4168 resources: aliyunResourceDiagnostics() 4169 }); 4170 loading = false; 4171 resolveWaiters(); 4172 }, 4173 slideStyle: { width: 360, height: 40 }, 4174 timeout: CAPTCHA_REQUEST_TIMEOUT_MS, 4175 rem: CAPTCHA_UI_SCALE, 4176 showErrorTip: false, 4177 language: 'cn' 4178 }); 4179 } catch (error) { 4180 clearInitGuard(); 4181 loading = false; 4182 rejectWaiters(error); 4183 } 4184 }).catch(reject); 4185 }; 4186 4187 window.goooodAliyunCaptchaPreferVisible = () => { 4188 preferVisible = true; 4189 }; 4190 4191 const resetCompletedCaptcha = () => { 4192 if (!reinitializeBeforeNextRun) return; 4193 try { 4194 const result = instance && instance.hide ? instance.hide() : null; 4195 if (result && typeof result.then === 'function') { 4196 Promise.resolve(result).catch(() => {}); 4197 } 4198 } catch (_) { 4199 // A completed V3 instance is discarded even if its best-effort hide fails. 4200 } 4201 instance = null; 4202 instanceReadyAt = 0; 4203 reinitializeBeforeNextRun = false; 4204 }; 4205 4206 const clickCaptchaButton = () => { 4207 const button = document.getElementById('gooood-aliyun-captcha-button'); 4208 if (!button) return false; 4209 try { 4210 button.click(); 4211 } catch (error) { 4212 rejectPending(error); 4213 } 4214 return true; 4215 }; 4216 const runPendingCaptchaAction = () => { 4217 if (!pending) return; 4218 armPendingTimer(); 4219 try { 4220 preferVisible = false; 4221 logCaptchaDiagnostic('sdk_button_click', { 4222 instanceAgeMs: instanceReadyAt ? Date.now() - instanceReadyAt : 0, 4223 hasStartTracelessVerification: typeof (instance && instance.startTracelessVerification) === 'function', 4224 hasShow: typeof (instance && instance.show) === 'function' 4225 }); 4226 if (clickCaptchaButton()) { 4227 armVisibleActionGuard(); 4228 return; 4229 } 4230 throw new Error('captcha_button_missing'); 4231 } catch (error) { 4232 rejectPending(error); 4233 } 4234 }; 4235 4236 window.goooodAliyunCaptchaSms = (ok, fail) => { 4237 pending = ok; 4238 pendingFail = fail || null; 4239 resetCompletedCaptcha(); 4240 ready(() => { 4241 if (!pending) return; 4242 const warmupRemaining = Math.max(0, CAPTCHA_MIN_WARMUP_MS - (Date.now() - instanceReadyAt)); 4243 if (warmupRemaining > 0) { 4244 window.setTimeout(runPendingCaptchaAction, warmupRemaining); 4245 return; 4246 } 4247 runPendingCaptchaAction(); 4248 }, rejectPending); 4249 }; 4250 4251 window.setTimeout(() => { 4252 ready(() => {}, () => {}); 4253 }, 0); 4254 4255 }; 4256 const runSmsCaptcha = async () => { 4257 ensureGoooodAliyunCaptchaSms(); 4258 return new Promise((resolve, reject) => { 4259 window.goooodAliyunCaptchaSms(resolve, (error) => { 4260 reject(new Error(captchaErrorMessage(error, '人æºéªè¯è¶ æ¶ï¼è¯·å·æ°åéè¯'))); 4261 }); 4262 }); 4263 }; 4264 const preferVisibleSmsCaptcha = () => { 4265 ensureGoooodAliyunCaptchaSms(); 4266 if (window.goooodAliyunCaptchaPreferVisible) window.goooodAliyunCaptchaPreferVisible(); 4267 }; 4268 const isCaptchaVerifyFailure = (source) => { 4269 const records = [source]; 4270 if (source && typeof source === 'object' && source.data) records.push(source.data); 4271 return records.some((item) => { 4272 if (!item) return false; 4273 if (typeof item === 'string') return item.includes('captcha_verify_failed') || item.includes('人æºéªè¯'); 4274 if (item instanceof Error) return isCaptchaVerifyFailure(item.message); 4275 if (typeof item !== 'object') return false;
4276 return [item.code, item.msg, item.message, item.error].some((value) => { 4277 const text = String(value || ''); 4278 return text.includes('captcha_verify_failed') || text.includes('人æºéªè¯') || text.includes('captcha'); 4279 }); 4280 }); 4281 }; 4282 const requestSmsCodeWithCaptcha = async (request, failureMessage) => { 4283 setFeedback('æ£å¨å 载人æºéªè¯...'); 4284 const captchaVerifyParam = await runSmsCaptcha(); 4285 try { 4286 const response = await request(captchaVerifyParam); 4287 if (!responseSucceeded(response)) { 4288 if (isCaptchaVerifyFailure(response)) { 4289 preferVisibleSmsCaptcha(); 4290 throw new Error('人æºéªè¯æªéè¿ï¼è¯·å次ç¹å»è·åéªè¯ç 宿å®å ¨éªè¯ã'); 4291 } 4292 throw new Error(responseMessage(response, failureMessage)); 4293 } 4294 return response; 4295 } catch (error) { 4296 if (isCaptchaVerifyFailure(error)) { 4297 preferVisibleSmsCaptcha(); 4298 throw new Error('人æºéªè¯æªéè¿ï¼è¯·å次ç¹å»è·åéªè¯ç 宿å®å ¨éªè¯ã'); 4299 } 4300 throw error; 4301 } 4302 }; 4303 const setForgotMethod = (method) => { 4304 forgotMethod = method; 4305 modal.querySelectorAll('[data-forgot-method-panel]').forEach((panel) => { 4306 const active = authMode === 'forgot' && panel.dataset.forgotMethodPanel === method; 4307 panel.hidden = !active; 4308 panel.querySelectorAll('input, select').forEach((control) => { 4309 control.disabled = !active; 4310 control.required = active; 4311 }); 4312 }); 4313 if (authMode === 'forgot') { 4314 titleNode.dataset.zh = method === 'phone' ? 'éç½®å¯ç ' : 'å¿è®°å¯ç '; 4315 titleNode.dataset.en = method === 'phone' ? 'Reset Password' : 'Forgot Password'; 4316 submitButton.dataset.zh = method === 'phone' ? 'ä¿åä¿®æ¹' : 'Get New Password'; 4317 submitButton.dataset.en = method === 'phone' ? 'Save changes' : 'Get New Password'; 4318 } 4319 if (method === 'phone') loadTelCodes(); 4320 applyModalLanguage(); 4321 }; 4322 const setMode = (mode, keepFeedback = false) => { 4323 authMode = mode; 4324 setError(''); 4325 if (!keepFeedback) setFeedback(''); 4326 modal.querySelectorAll('[data-auth-panel]').forEach((panel) => { 4327 const active = panel.dataset.authPanel === mode; 4328 panel.hidden = !active; 4329 panel.querySelectorAll('input, select').forEach((input) => { 4330 const nestedForgotPanel = input.closest('[data-forgot-method-panel]'); 4331 input.disabled = !active || (nestedForgotPanel && nestedForgotPanel.dataset.forgotMethodPanel !== forgotMethod); 4332 input.required = active && (!nestedForgotPanel || nestedForgotPanel.dataset.forgotMethodPanel === forgotMethod); 4333 }); 4334 }); 4335 if (mode !== 'forgot') setForgotMethod('email'); 4336 if (mode === 'login') { 4337 titleNode.dataset.zh = 'ä¼åç»å½'; 4338 titleNode.dataset.en = 'Member Login'; 4339 submitButton.dataset.zh = 'ç»å½'; 4340 submitButton.dataset.en = 'Login'; 4341 socialBlock.hidden = false; 4342 syncWechatLoginEntry(); 4343 } else if (mode === 'register') { 4344 titleNode.dataset.zh = 'ææºå·æ³¨å'; 4345 titleNode.dataset.en = 'Mobile Register'; 4346 submitButton.dataset.zh = '注å'; 4347 submitButton.dataset.en = 'Register'; 4348 socialBlock.hidden = true; 4349 loadTelCodes(); 4350 } else { 4351 setForgotMethod(forgotMethod); 4352 socialBlock.hidden = true; 4353 } 4354 modal.querySelectorAll('[data-auth-mode-button]').forEach((button) => { 4355 const target = button.dataset.authModeButton; 4356 if (target === 'register') { 4357 button.dataset.zh = mode === 'register' ? 'è¿åç»å½' : 'ææºå·æ³¨å »'; 4358 button.dataset.en = mode === 'register' ? 'Back to login' : 'Mobile register »'; 4359 button.dataset.authModeTarget = mode === 'register' ? 'login' : 'register'; 4360 } else { 4361 button.dataset.zh = mode === 'forgot' ? 'è¿åç»å½' : 'å¿è®°å¯ç ï¼'; 4362 button.dataset.en = mode === 'forgot' ? 'Back to login' : 'Forgot password?'; 4363 button.dataset.authModeTarget = mode === 'forgot' ? 'login' : 'forgot'; 4364 } 4365 }); 4366 applyModalLanguage(); 4367 updateCodeButton('register'); 4368 updateCodeButton('forgot'); 4369 }; 4370 const openModal = (mode = 'login') => { 4371 ensureGoooodAliyunCaptchaSms(); 4372 setMode(mode); 4373 modal.hidden = false;
4374 document.body.classList.add('gooood-auth-open'); 4375 const focusTarget = authMode === 'register' ? form.elements.register_mobile : authMode === 'forgot' ? form.elements.reset_login : form.elements.username; 4376 window.setTimeout(() => focusTarget && focusTarget.focus(), 0); 4377 }; 4378 const closeModal = () => { modal.hidden = true; document.body.classList.remove('gooood-auth-open'); setError(''); setFeedback(''); }; 4379 const favoriteContains = (favorites, postId) => Array.isArray(favorites) && favorites.some((entry) => typeof entry === 'number' || typeof entry === 'string' ? Number(entry) === postId : Number(entry && entry.post_id) === postId); 4380 const setFavoriteState = (trigger, active) => { 4381 if (!trigger) return; 4382 trigger.classList.toggle('is-favorited', active); 4383 trigger.setAttribute('aria-pressed', String(active)); 4384 const icon = trigger.querySelector('.action-icon'); 4385 const label = trigger.querySelector('[data-zh][data-en]'); 4386 if (icon) icon.textContent = active ? 'â ' : 'â'; 4387 if (label) { label.dataset.zh = active ? 'å·²æ¶è' : 'æ¶è'; label.dataset.en = active ? 'Saved' : 'Favorites'; label.textContent = currentLanguage() === 'en' ? label.dataset.en : label.dataset.zh; } 4388 }; 4389 const toggleFavorite = async (favorite) => { 4390 const { trigger, postId, typeId } = favorite || {}; 4391 if (!trigger || !postId || !typeId) { showToast('æç« æ¶èä¿¡æ¯å°æªå è½½ï¼è¯·ç¨åéè¯', 'Favorite data is still loading. Please try again.'); return; } 4392 trigger.classList.add('is-pending'); 4393 try { 4394 const response = await apiRequest('/wp/v2/fav', { method: 'POST', body: { post_id: postId, type_id: typeId } }); 4395 const active = favoriteContains(response.favorites, postId); 4396 setFavoriteState(trigger, active); 4397 showToast(active ? 'å·²æ¶è' : '已忶æ¶è', active ? 'Saved' : 'Removed from favorites'); 4398 } catch (error) { 4399 if (isConfirmedAuthInvalidation(error)) { clearToken(); pendingFavorite = favorite; openModal(); } 4400 else showToast(error.message || 'æ¶è失败', error.message || 'Unable to save'); 4401 } finally { trigger.classList.remove('is-pending'); } 4402 }; 4403 const articleFavoriteFrom = (trigger) => { 4404 const article = trigger.closest('.article'); 4405 return { trigger, postId: Number(article && article.dataset.backendPostId), typeId: Number(article && article.dataset.backendPrimaryTypeId) }; 4406 }; 4407 const normalizeBrokenTargets = () => { 4408 document.querySelectorAll('a[href]').forEach((link) => { 4409 let pathname = ''; 4410 try { pathname = new URL(link.href, window.location.href).pathname.replace(/\/$/, '') || '/'; } catch (_) {} 4411 const isLoginHash = link.hash === '#login'; 4412 if (!BROKEN_ACCOUNT_PATHS.has(pathname) && !isLoginHash) return; 4413 link.href = '#login'; 4414 if (link.classList.contains('favorite-action') || link.closest('.article-actions')) { link.dataset.goooodFavoriteTrigger = '1'; link.setAttribute('role', 'button'); } 4415 else { link.dataset.goooodLoginTrigger = '1'; link.setAttribute('role', 'button'); } 4416 }); 4417 }; 4418 4419 modal.querySelector('.gooood-auth-close').addEventListener('click', closeModal); 4420 document.querySelectorAll('[data-lang-toggle]').forEach((button) => { 4421 button.addEventListener('click', (event) => { 4422 event.preventDefault(); 4423 event.stopImmediatePropagation(); 4424 switchLanguage(currentPathLanguage() === 'en' ? 'zh' : 'en'); 4425 }, true); 4426 }); 4427 modal.addEventListener('click', (event) => { if (event.target === modal) closeModal(); }); 4428 document.addEventListener('keydown', (event) => { 4429 if (event.key !== 'Escape') return; 4430 if (!modal.hidden) closeModal(); 4431 closeAccountMenus(); 4432 }); 4433 codeButtons.forEach((button) => { 4434 button.addEventListener('click', async () => { 4435 const kind = button.dataset.codeKind || 'register'; 4436 setError(''); setFeedback(''); 4437 const mobile = kind === 'forgot' ? form.elements.forgot_mobile.value.trim() : form.elements.register_mobile.value.trim(); 4438 const region = kind === 'forgot' ? form.elements.forgot_region.value : form.elements.register_region.value; 4439 if (!mobile) { setError('请è¾å ¥ææºå·'); return; } 4440 if ((kind === 'forgot' ? forgotCountdown : registerCountdown) > 0) return; 4441 updateCodeButton(kind, true);
4442 try { 4443 const response = await requestSmsCodeWithCaptcha((captchaVerifyParam) => apiRequest('/wp/v2/sms202601', { 4444 method: 'POST', 4445 auth: false, 4446 body: { 4447 region_number: region || '86', 4448 mobile, 4449 event: kind === 'forgot' ? 'editpass' : 'register', 4450 captchaVerifyParam, 4451 CaptchaVerifyParam: captchaVerifyParam 4452 } 4453 }), 'éªè¯ç åé失败ï¼è¯·ç¨åéè¯ã'); 4454 setFeedback(responseMessage(response, 'éªè¯ç å·²åéï¼è¯·æ¥æ¶çä¿¡ã')); 4455 startCodeCountdown(kind); 4456 } catch (error) { setFeedback(''); setError(error.message || 'éªè¯ç åé失败ï¼è¯·ç¨åéè¯ã'); } 4457 finally { updateCodeButton(kind, false); } 4458 }); 4459 }); 4460 modal.querySelectorAll('[data-auth-mode-button]').forEach((button) => { 4461 button.addEventListener('click', () => setMode(button.dataset.authModeTarget || 'login')); 4462 }); 4463 modal.querySelectorAll('[data-auth-forgot-method]').forEach((button) => { 4464 button.addEventListener('click', () => { 4465 setError(''); 4466 setFeedback(''); 4467 setForgotMethod(button.dataset.authForgotMethod || 'email'); 4468 }); 4469 }); 4470 form.addEventListener('submit', async (event) => { 4471 event.preventDefault(); setError(''); setFeedback(''); submitButton.disabled = true; 4472 try { 4473 if (authMode === 'register') { 4474 const mobile = form.elements.register_mobile.value.trim(); 4475 const region = form.elements.register_region.value || '86'; 4476 const password = form.elements.register_password.value; 4477 const password2 = form.elements.register_password2.value; 4478 if (password !== password2) throw new Error('两次è¾å ¥çå¯ç å¿ é¡»ä¸è´'); 4479 const response = await apiRequest('/wp/v2/user/register', { method: 'POST', auth: false, body: { region_number: region, user_mobile: mobile, sms_code: form.elements.register_code.value.trim(), user_pass: password, user_pass2: password2, from_source: 2 } }); 4480 if (!responseSucceeded(response)) throw new Error(responseMessage(response, '注å失败ï¼è¯·æ£æ¥ä¿¡æ¯åéè¯ã')); 4481 form.elements.username.value = mobile; 4482 form.elements.password.value = ''; 4483 form.elements.register_code.value = ''; 4484 form.elements.register_password.value = ''; 4485 form.elements.register_password2.value = ''; 4486 setFeedback(responseMessage(response, '注åæåï¼è¯·ä½¿ç¨ææºå·åå¯ç ç»å½ã')); 4487 setMode('login', true); 4488 } else if (authMode === 'forgot') { 4489 if (forgotMethod === 'phone') { 4490 const mobile = form.elements.forgot_mobile.value.trim(); 4491 const smsCode = form.elements.forgot_code.value.trim(); 4492 const password = form.elements.forgot_password.value; 4493 const password2 = form.elements.forgot_password2.value; 4494 if (!mobile) throw new Error('请è¾å ¥ææºå·'); 4495 if (!smsCode) throw new Error('请è¾å ¥éªè¯ç '); 4496 if (!password) throw new Error('请è¾å ¥æ°å¯ç '); 4497 if (password !== password2) throw new Error('两次è¾å ¥çå¯ç å¿ é¡»ä¸è´'); 4498 const response = await apiRequest('/wp/v2/account/editpass', { method: 'POST', auth: false, body: { password: password2, mobile, sms_code: smsCode } }); 4499 if (!responseSucceeded(response)) throw new Error(responseMessage(response, 'å¯ç ä¿®æ¹å¤±è´¥ï¼è¯·æ£æ¥ä¿¡æ¯åéè¯ã')); 4500 form.elements.username.value = mobile; 4501 form.elements.password.value = ''; 4502 form.elements.forgot_code.value = ''; 4503 form.elements.forgot_password.value = ''; 4504 form.elements.forgot_password2.value = ''; 4505 setFeedback(responseMessage(response, 'å¯ç 已修æ¹ï¼è¯·è¿åç»å½ã')); 4506 setMode('login', true); 4507 } else { 4508 const response = await apiRequest('/wp/v2/account/forgotpwd', { method: 'POST', auth: false, body: { user_login: form.elements.reset_login.value.trim() } }); 4509 if (!responseSucceeded(response)) throw new Error(responseMessage(response, 'æäº¤å¤±è´¥ï¼è¯·ç¨åéè¯ã')); 4510 setFeedback(responseMessage(response, 'å¦æè´¦å·åå¨ï¼é设å¯ç é®ä»¶å°åéå°è´¦å·é®ç®±ã')); 4511 } 4512 } else { 4513 const response = await apiRequest('/jwt-auth/v1/token', { method: 'POST', auth: false, body: { username: form.elements.username.value.trim(), password: form.elements.password.value } }); 4514 if (!response.token) throw new Error('ç»å½ååºç¼ºå° token'); 4515 saveToken(response.token, response.expire); 4516 const user = await apiRequest('/wp/v2/users/me', { token: response.token }); 4517 updateMemberUI(user); 4518 closeModal(); form.reset(); showToast(`ç»å½æå${resolveDisplayName(user) ? `ï¼æ¬¢è¿ ${resolveDisplayName(user)}` : ''}`, 'Logged in'); 4519 if (pendingFavorite) { const favorite = pendingFavorite; pendingFavorite = null; await toggleFavorite(favorite); } 4520 } 4521 } catch (error) { 4522 if (authMode === 'login') clearToken(); 4523 setError(error.message || (authMode === 'register' ? '注å失败ï¼è¯·æ£æ¥ä¿¡æ¯åéè¯ã' : authMode === 'forgot' ? 'æäº¤å¤±è´¥ï¼è¯·ç¨åéè¯ã' : 'ç»å½å¤±è´¥')); 4524 } 4525 finally { submitButton.disabled = false; } 4526 }); 4527 wechatButton.addEventListener('click', async () => {
4528 if (isExternalMobileWechatLogin()) { 4529 syncWechatLoginEntry(); 4530 setFeedback('请å¨å¾®ä¿¡å æå¼æ¬é¡µåï¼å使ç¨å¾®ä¿¡ç»å½ã'); 4531 return; 4532 } 4533 setError(''); wechatButton.disabled = true; 4534 try { 4535 const response = await apiRequest('/wp/v2/account/oauth', { method: 'POST', auth: false, body: { action: 'login', target: 'wechat', back: window.location.pathname + window.location.search } }); 4536 const destination = response.url || response.redirect || response.location; 4537 if (!destination) throw new Error('微信ç»å½ææ¶ä¸å¯ç¨'); 4538 window.location.href = destination; 4539 } catch (error) { setError(error.message || '微信ç»å½å¯å¨å¤±è´¥'); wechatButton.disabled = false; } 4540 }); 4541 document.addEventListener('click', async (event) => { 4542 const accountToggle = event.target.closest('[data-gooood-account-toggle]'); 4543 if (accountToggle) { 4544 event.preventDefault(); 4545 const account = accountToggle.closest('.gooood-account'); 4546 const opening = !account.classList.contains('is-open'); 4547 closeAccountMenus(account); 4548 account.classList.toggle('is-open', opening); 4549 accountToggle.setAttribute('aria-expanded', String(opening)); 4550 return; 4551 } 4552 const accountLogout = event.target.closest('[data-gooood-account-logout]'); 4553 if (accountLogout) { 4554 event.preventDefault(); 4555 try { await apiRequest('/wp/v2/users/logout', { method: 'POST' }); } catch (_) {} 4556 clearToken(); 4557 updateMemberUI(null); 4558 showToast('å·²éåºç»å½', 'Logged out'); 4559 return; 4560 } 4561 if (!event.target.closest('.gooood-account')) closeAccountMenus(); 4562 const favoriteTrigger = event.target.closest('[data-gooood-favorite-trigger], .favorite-action'); 4563 if (favoriteTrigger) { 4564 event.preventDefault(); 4565 const favorite = articleFavoriteFrom(favoriteTrigger); 4566 if (!cookieValue('auth_token')) { pendingFavorite = favorite; openModal(); } else await toggleFavorite(favorite); 4567 return; 4568 } 4569 const loginTrigger = event.target.closest('[data-gooood-login-trigger], a[href="#login"], a[href$="#login"]'); 4570 if (!loginTrigger) return; 4571 event.preventDefault(); 4572 if (!cookieValue('auth_token')) { openModal(); return; } 4573 try { const user = await apiRequest('/wp/v2/users/me'); updateMemberUI(user); showToast('å½åå·²ç»å½ï¼å¯ç´æ¥ç¹å»æç« å¡çä¸çæ¶è', 'You are logged in. Use Favorites on an article card.'); } 4574 catch (error) { 4575 if (isConfirmedAuthInvalidation(error)) { clearToken(); updateMemberUI(null);
4575 openModal(); } 4576 else { retainAuthAfterTemporaryFailure(); showToast('ç»å½ç¶æææ¶æ æ³ç¡®è®¤ï¼è¯·ç¨åéè¯', 'Unable to confirm your sign-in right now. Please try again shortly.'); } 4577 } 4578 }); 4579 normalizeBrokenTargets(); 4580 new MutationObserver(normalizeBrokenTargets).observe(document.body, { childList: true, subtree: true }); 4581 setAuthState('checking', null); 4582 if (document.readyState === 'loading') { 4583 document.addEventListener('DOMContentLoaded', () => { checkAndRestoreAuth(); }); 4584 } else { 4585 checkAndRestoreAuth(); 4586 } 4587})(); 4588</script>
vendor: 1 bytes, line 4588
4588
4589<script data-gooood-home-share>"use strict";(()=>{var Ve=Object.create;var Ot=Object.defineProperty;var Ke=Object.getOwnPropertyDescriptor;var Je=Object.getOwnPropertyNames;var Ye=Object.getPrototypeOf,$e=Object.prototype.hasOwnProperty;var E=(o,t)=>()=>{try{return t||o((t={exports:{}}).exports,t),t.exports}catch(e){throw t=0,e}};var Ge=(o,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Je(t))!$e.call(o,r)&&r!==e&&Ot(o,r,{get:()=>t[r],enumerable:!(n=Ke(t,r))||n.enumerable});return o};var je=(o,t,e)=>(e=o!=null?Ve(Ye(o)):{},Ge(t||!o||!o.__esModule?Ot(e,"default",{value:o,enumerable:!0}):e,o));var Vt=E((Yo,Ht)=>{Ht.exports=function(){return typeof Promise=="function"&&Promise.prototype&&Promise.prototype.then}});var _=E(z=>{var wt,Qe=[0,26,44,70,100,134,172,196,242,292,346,404,466,532,581,655,733,815,901,991,1085,1156,1258,1364,1474,1588,1706,1828,1921,2051,2185,2323,2465,2611,2761,2876,3034,3196,3362,3532,3706];z.getSymbolSize=function(t){if(!t)throw new Error('"version" cannot be null or undefined');if(t<1||t>40)throw new Error('"version" should be in range from 1 to 40');return t*4+17};z.getSymbolTotalCodewords=function(t){return Qe[t]};z.getBCHDigit=function(o){let t=0;for(;o!==0;)t++,o>>>=1;return t};z.setToSJISFunction=function(t){if(typeof t!="function")throw new Error('"toSJISFunc" is not a valid function.');wt=t};z.isKanjiModeEnabled=function(){return typeof wt!="undefined"};z.toSJIS=function(t){return wt(t)}});var it=E(P=>{P.L={bit:1};P.M={bit:0};P.Q={bit:3};P.H={bit:2};function We(o){if(typeof o!="string")throw new Error("Param is not a string");switch(o.toLowerCase()){case"l":case"low":return P.L;case"m":case"medium":return P.M;case"q":case"quartile":return P.Q;case"h":case"high":return P.H;default:throw new Error("Unknown EC Level: "+o)}}P.isValid=function(t){return t&&typeof t.bit!="undefined"&&t.bit>=0&&t.bit<4};P.from=function(t,e){if(P.isValid(t))return t;try{return We(t)}catch{return e}}});var Yt=E((jo,Jt)=>{function Kt(){this.buffer=[],this.length=0}Kt.prototype={get:function(o){let t=Math.floor(o/8);return(this.buffer[t]>>>7-o%8&1)===1},put:function(o,t){for(let e=0;e<t;e++)this.putBit((o>>>t-e-1&1)===1)},getLengthInBits:function(){return this.length},putBit:function(o){let t=Math.floor(this.length/8);this.buffer.length<=t&&this.buffer.push(0),o&&(this.buffer[t]|=128>>>this.length%8),this.length++}};Jt.exports=Kt});var Gt=E((Qo,$t)=>{function Q(o){if(!o||o<1)throw new Error("BitMatrix size must be defined and greater than 0");this.size=o,this.data=new Uint8Array(o*o),this.reservedBit=new Uint8Array(o*o)}Q.prototype.set=function(o,t,e,n){let r=o*this.size+t;this.data[r]=e,n&&(this.reservedBit[r]=!0)};Q.prototype.get=function(o,t){return this.data[o*this.size+t]};Q.prototype.xor=function(o,t,e){this.data[o*this.size+t]^=e};Q.prototype.isReserved=function(o,t){return this.reservedBit[o*this.size+t]};$t.exports=Q});var jt=E(at=>{var Xe=_().getSymbolSize;at.getRowColCoords=function(t){if(t===1)return[];let e=Math.floor(t/7)+2,n=Xe(t),r=n===145?26:Math.ceil((n-13)/(2*e-2))*2,i=[n-7];for(let a=1;a<e-1;a++)i[a]=i[a-1]-r;return i.push(6),i.reverse()};at.getPositions=function(t){let e=[],n=at.getRowColCoords(t),r=n.length;for(let i=0;i<r;i++)for(let a=0;a<r;a++)i===0&&a===0||i===0&&a===r-1||i===r-1&&a===0||e.push([n[i],n[a]]);return e}});var Xt=E(Wt=>{var Ze=_().getSymbolSize,Qt=7;Wt.getPositions=function(t){let e=Ze(t);return[[0,0],[e-Qt,0],[0,e-Qt]]}});var Zt=E(C=>{C.Patterns={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};var F={N1:3,N2:3,N3:40,N4:10};C.isValid=function(t){return t!=null&&t!==""&&!isNaN(t)&&t>=0&&t<=7};C.from=function(t){return C.isValid(t)?parseInt(t,10):void 0};C.getPenaltyN1=function(t){let e=t.size,n=0,r=0,i=0,a=null,s=null;for(let u=0;u<e;u++){r=i=0,a=s=null;for(let f=0;f<e;f++){let g=t.get(u,f);g===a?r++:(r>=5&&(n+=F.N1+(r-5)),a=g,r=1),g=t.get(f,u),g===s?i++:(i>=5&&(n+=F.N1+(i-5)),s=g,i=1)}r>=5&&(n+=F.N1+(r-5)),i>=5&&(n+=F.N1+(i-5))}return n};C.getPenaltyN2=function(t){let e=t.size,n=0;for(let r=0;r<e-1;r++)for(let i=0;i<e-1;i++){let a=t.get(r,i)+t.get(r,i+1)+t.get(r+1,i)+t.get(r+1,i+1);(a===4||a===0)&&n++}return n*F.N2};C.getPenaltyN3=function(t){let e=t.size,n=0,r=0,i=0;for(let a=0;a<e;a++){r=i=0;for(let s=0;s<e;s++)r=r<<1&2047|t.get(a,s),s>=10&&(r===1488||r===93)&&n++,i=i<<1&2047|t.get(s,a),s>=10&&(i===1488||i===93)&&n++}return n*F.N3};C.getPenaltyN4=function(t){let e=0,n=t.data.length;for(let i=0;i<n;i++)e+=t.data[i];return Math.abs(Math.ceil(e*100/n/5)-10)*F.N4};function to(o,t,e){switch(o){case C.Patterns.PATTERN000:return(t+e)%2===0;case C.Patterns.PATTERN001:return t%2===0;case C.Patterns.PATTERN010:return e%3===0;case C.Patterns.PATTERN011:return(t+e)%3===0;case C.Patterns.PATTERN100:return(Math.floor(t/2)+Math.floor(e/3))%2===0;case C.Patterns.PATTERN101:return t*e%2+t*e%3===0;case C.Patterns.PATTERN110:return(t*e%2+t*e%3)%2===0;case C.Patterns.PATTERN111:return(t*e%3+(t+e)%2)%2===0;default:throw new Error("bad maskPattern:"+o)}}C.applyMask=function(t,e){let n=e.size;
4589for(let r=0;r<n;r++)for(let i=0;i<n;i++)e.isReserved(i,r)||e.xor(i,r,to(t,i,r))};C.getBestMask=function(t,e){let n=Object.keys(C.Patterns).length,r=0,i=1/0;for(let a=0;a<n;a++){e(a),C.applyMask(a,t);let s=C.getPenaltyN1(t)+C.getPenaltyN2(t)+C.getPenaltyN3(t)+C.getPenaltyN4(t);C.applyMask(a,t),s<i&&(i=s,r=a)}return r}});var Et=E(yt=>{var U=it(),st=[1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,4,1,2,4,4,2,4,4,4,2,4,6,5,2,4,6,6,2,5,8,8,4,5,8,8,4,5,8,11,4,8,10,11,4,9,12,16,4,9,16,16,6,10,12,18,6,10,17,16,6,11,16,19,6,13,18,21,7,14,21,25,8,16,20,25,8,17,23,25,9,17,23,34,9,18,25,30,10,20,27,32,12,21,29,35,12,23,34,37,12,25,34,40,13,26,35,42,14,28,38,45,15,29,40,48,16,31,43,51,17,33,45,54,18,35,48,57,19,37,51,60,19,38,53,63,20,40,56,66,21,43,59,70,22,45,62,74,24,47,65,77,25,49,68,81],ct=[7,10,13,17,10,16,22,28,15,26,36,44,20,36,52,64,26,48,72,88,36,64,96,112,40,72,108,130,48,88,132,156,60,110,160,192,72,130,192,224,80,150,224,264,96,176,260,308,104,198,288,352,120,216,320,384,132,240,360,432,144,280,408,480,168,308,448,532,180,338,504,588,196,364,546,650,224,416,600,700,224,442,644,750,252,476,690,816,270,504,750,900,300,560,810,960,312,588,870,1050,336,644,952,1110,360,700,1020,1200,390,728,1050,1260,420,784,1140,1350,450,812,1200,1440,480,868,1290,1530,510,924,1350,1620,540,980,1440,1710,570,1036,1530,1800,570,1064,1590,1890,600,1120,1680,1980,630,1204,1770,2100,660,1260,1860,2220,720,1316,1950,2310,750,1372,2040,2430];yt.getBlocksCount=function(t,e){switch(e){case U.L:return st[(t-1)*4+0];case U.M:return st[(t-1)*4+1];case U.Q:return st[(t-1)*4+2];case U.H:return st[(t-1)*4+3];default:return}};yt.getTotalCodewordsCount=function(t,e){switch(e){case U.L:return ct[(t-1)*4+0];case U.M:return ct[(t-1)*4+1];case U.Q:return ct[(t-1)*4+2];case U.H:return ct[(t-1)*4+3];default:return}}});var te=E(ut=>{var W=new Uint8Array(512),lt=new Uint8Array(256);(function(){let t=1;for(let e=0;e<255;e++)W[e]=t,lt[t]=e,t<<=1,t&256&&(t^=285);for(let e=255;e<512;e++)W[e]=W[e-255]})();ut.log=function(t){if(t<1)throw new Error("log("+t+")");return lt[t]};ut.exp=function(t){return W[t]};ut.mul=function(t,e){return t===0||e===0?0:W[lt[t]+lt[e]]}});var ee=E(X=>{var Ct=te();X.mul=function(t,e){let n=new Uint8Array(t.length+e.length-1);for(let r=0;r<t.length;r++)for(let i=0;i<e.length;i++)n[r+i]^=Ct.mul(t[r],e[i]);return n};X.mod=function(t,e){let n=new Uint8Array(t);for(;n.length-e.length>=0;){let r=n[0];for(let a=0;a<e.length;a++)n[a]^=Ct.mul(e[a],r);let i=0;for(;i<n.length&&n[i]===0;)i++;n=n.slice(i)}return n};X.generateECPolynomial=function(t){let e=new Uint8Array([1]);for(let n=0;n<t;n++)e=X.mul(e,new Uint8Array([1,Ct.exp(n)]));return e}});var re=E((nn,ne)=>{var oe=ee();function bt(o){this.genPoly=void 0,this.degree=o,this.degree&&this.initialize(this.degree)}bt.prototype.initialize=function(t){this.degree=t,this.genPoly=oe.generateECPolynomial(this.degree)};bt.prototype.encode=function(t){if(!this.genPoly)throw new Error("Encoder not initialized");let e=new Uint8Array(t.length+this.degree);e.set(t);let n=oe.mod(e,this.genPoly),r=this.degree-n.length;if(r>0){let i=new Uint8Array(this.degree);return i.set(n,r),i}return n};ne.exports=bt});var At=E(ie=>{ie.isValid=function(t){return!isNaN(t)&&t>=1&&t<=40}});var St=E(R=>{var ae="[0-9]+",eo="[A-Z $%*+\\-./:]+",Z="(?:[u3000-u303F]|[u3040-u309F]|[u30A0-u30FF]|[uFF00-uFFEF]|[u4E00-u9FAF]|[u2605-u2606]|[u2190-u2195]|u203B|[u2010u2015u2018u2019u2025u2026u201Cu201Du2225u2260]|[u0391-u0451]|[u00A7u00A8u00B1u00B4u00D7u00F7])+";Z=Z.replace(/u/g,"\\u");var oo="(?:(?![A-Z0-9 $%*+\\-./:]|"+Z+`)(?:.|[\r 4590]))+`;R.KANJI=new RegExp(Z,"g");R.BYTE_KANJI=new RegExp("[^A-Z0-9 $%*+\\-./:]+","g");R.BYTE=new RegExp(oo,"g");R.NUMERIC=new RegExp(ae,"g");R.ALPHANUMERIC=new RegExp(eo,"g");var no=new RegExp("^"+Z+"$"),ro=new RegExp("^"+ae+"$"),io=new RegExp("^[A-Z0-9 $%*+\\-./:]+$");R.testKanji=function(t){return no.test(t)};R.testNumeric=function(t){return ro.test(t)};R.testAlphanumeric=function(t){return io.test(t)}});var D=E(A=>{var ao=At(),Bt=St();A.NUMERIC={id:"Numeric",bit:1,ccBits:[10,12,14]};A.ALPHANUMERIC={id:"Alphanumeric",bit:2,ccBits:[9,11,13]};A.BYTE={id:"Byte",bit:4,ccBits:[8,16,16]};A.KANJI={id:"Kanji",bit:8,ccBits:[8,10,12]};A.MIXED={bit:-1};A.getCharCountIndicator=function(t,e){if(!t.ccBits)throw new Error("Invalid mode: "+t);if(!ao.isValid(e))throw new Error("Invalid version: "+e);return e>=1&&e<10?t.ccBits[0]:e<27?t.ccBits[1]:t.ccBits[2]};A.getBestModeForData=function(t){return Bt.testNumeric(t)?A.NUMERIC:Bt.testAlphanumeric(t)?A.ALPHANUMERIC:Bt.testKanji(t)?A.KANJI:A.BYTE};A.toString=function(t){if(t&&t.id)return t.id;throw new Error("Invalid mode")};A.isValid=function(t){return t&&t.bit&&t.ccBits};function so(o){if(typeof o!="string")throw new Error("Param is not a string");switch(o.toLowerCase()){case"numeric":return A.NUMERIC;case"alphanumeric":return A.ALPHANUMERIC;case"kanji":return A.KANJI;case"byte":return A.BYTE;default:throw new Error("Unknown mode: "+o)}}A.from=function(t,e){if(A.isValid(t))return t;try{return so(t)}catch{return e}}});var de=E(O=>{var dt=_(),co=Et(),se=it(),k=D(),xt=At(),le=7973,ce=dt.getBCHDigit
4590(le);function lo(o,t,e){for(let n=1;n<=40;n++)if(t<=O.getCapacity(n,e,o))return n}function ue(o,t){return k.getCharCountIndicator(o,t)+4}function uo(o,t){let e=0;return o.forEach(function(n){let r=ue(n.mode,t);e+=r+n.getBitsLength()}),e}function ho(o,t){for(let e=1;e<=40;e++)if(uo(o,e)<=O.getCapacity(e,t,k.MIXED))return e}O.from=function(t,e){return xt.isValid(t)?parseInt(t,10):e};O.getCapacity=function(t,e,n){if(!xt.isValid(t))throw new Error("Invalid QR Code version");typeof n=="undefined"&&(n=k.BYTE);let r=dt.getSymbolTotalCodewords(t),i=co.getTotalCodewordsCount(t,e),a=(r-i)*8;if(n===k.MIXED)return a;let s=a-ue(n,t);switch(n){case k.NUMERIC:return Math.floor(s/10*3);case k.ALPHANUMERIC:return Math.floor(s/11*2);case k.KANJI:return Math.floor(s/13);case k.BYTE:default:return Math.floor(s/8)}};O.getBestVersionForData=function(t,e){let n,r=se.from(e,se.M);if(Array.isArray(t)){if(t.length>1)return ho(t,r);if(t.length===0)return 1;n=t[0]}else n=t;return lo(n.mode,n.getLength(),r)};O.getEncodedBits=function(t){if(!xt.isValid(t)||t<7)throw new Error("Invalid QR Code version");let e=t<<12;for(;dt.getBCHDigit(e)-ce>=0;)e^=le<<dt.getBCHDigit(e)-ce;return t<<12|e}});var pe=E(ge=>{var Tt=_(),fe=1335,fo=21522,he=Tt.getBCHDigit(fe);ge.getEncodedBits=function(t,e){let n=t.bit<<3|e,r=n<<10;for(;Tt.getBCHDigit(r)-he>=0;)r^=fe<<Tt.getBCHDigit(r)-he;return(n<<10|r)^fo}});var we=E((un,me)=>{var go=D();function J(o){this.mode=go.NUMERIC,this.data=o.toString()}J.getBitsLength=function(t){return 10*Math.floor(t/3)+(t%3?t%3*3+1:0)};J.prototype.getLength=function(){return this.data.length};J.prototype.getBitsLength=function(){return J.getBitsLength(this.data.length)};J.prototype.write=function(t){let e,n,r;for(e=0;e+3<=this.data.length;e+=3)n=this.data.substr(e,3),r=parseInt(n,10),t.put(r,10);let i=this.data.length-e;i>0&&(n=this.data.substr(e),r=parseInt(n,10),t.put(r,i*3+1))};me.exports=J});var Ee=E((dn,ye)=>{var po=D(),It=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"," ","$","%","*","+","-",".","/",":"];function Y(o){this.mode=po.ALPHANUMERIC,this.data=o}Y.getBitsLength=function(t){return 11*Math.floor(t/2)+6*(t%2)};Y.prototype.getLength=function(){return this.data.length};Y.prototype.getBitsLength=function(){return Y.getBitsLength(this.data.length)};Y.prototype.write=function(t){let e;for(e=0;e+2<=this.data.length;e+=2){let n=It.indexOf(this.data[e])*45;n+=It.indexOf(this.data[e+1]),t.put(n,11)}this.data.length%2&&t.put(It.indexOf(this.data[e]),6)};ye.exports=Y});var be=E((hn,Ce)=>{var mo=D();function $(o){this.mode=mo.BYTE,typeof o=="string"?this.data=new TextEncoder().encode(o):this.data=new Uint8Array(o)}$.getBitsLength=function(t){return t*8};$.prototype.getLength=function(){return this.data.length};$.prototype.getBitsLength=function(){return $.getBitsLength(this.data.length)};$.prototype.write=function(o){for(let t=0,e=this.data.length;t<e;t++)o.put(this.data[t],8)};Ce.exports=$});var Se=E((fn,Ae)=>{var wo=D(),yo=_();function G(o){this.mode=wo.KANJI,this.data=o}G.getBitsLength=function(t){return t*13};G.prototype.getLength=function(){return this.data.length};G.prototype.getBitsLength=function(){return G.getBitsLength(this.data.length)};G.prototype.write=function(o){let t;for(t=0;t<this.data.length;t++){let e=yo.toSJIS(this.data[t]);if(e>=33088&&e<=40956)e-=33088;else if(e>=57408&&e<=60351)e-=49472;else throw new Error("Invalid SJIS character: "+this.data[t]+` 4591Make sure your charset is UTF-8`);e=(e>>>8&255)*192+(e&255),o.put(e,13)}};Ae.exports=G});var Be=E((gn,Mt)=>{"use strict";var tt={single_source_shortest_paths:function(o,t,e){var n={},r={};r[t]=0;var i=tt.PriorityQueue.make();i.push(t,0);for(var a,s,u,f,g,b,w,S,M;!i.empty();){a=i.pop(),s=a.value,f=a.cost,g=o[s]||{};for(u in g)g.hasOwnProperty(u)&&(b=g[u],w=f+b,S=r[u],M=typeof r[u]=="undefined",(M||S>w)&&(r[u]=w,i.push(u,w),n[u]=s))}if(typeof e!="undefined"&&typeof r[e]=="undefined"){var x=["Could not find a path from ",t," to ",e,"."].join("");throw new Error(x)}return n},extract_shortest_path_from_predecessor_list:function(o,t){for(var e=[],n=t,r;n;)e.push(n),r=o[n],n=o[n];return e.reverse(),e},find_path:function(o,t,e){var n=tt.single_source_shortest_paths(o,t,e);return tt.extract_shortest_path_from_predecessor_list(n,e)},PriorityQueue:{make:function(o){var t=tt.PriorityQueue,e={},n;o=o||{};for(n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e.queue=[],e.sorter=o.sorter||t.default_sorter,e},default_sorter:function(o,t){return o.cost-t.cost}
4591,push:function(o,t){var e={value:o,cost:t};this.queue.push(e),this.queue.sort(this.sorter)},pop:function(){return this.queue.shift()},empty:function(){return this.queue.length===0}}};typeof Mt!="undefined"&&(Mt.exports=tt)});var Re=E(j=>{var p=D(),Ie=we(),Me=Ee(),Ne=be(),Pe=Se(),et=St(),ht=_(),Eo=Be();function xe(o){return unescape(encodeURIComponent(o)).length}function ot(o,t,e){let n=[],r;for(;(r=o.exec(e))!==null;)n.push({data:r[0],index:r.index,mode:t,length:r[0].length});return n}function Le(o){let t=ot(et.NUMERIC,p.NUMERIC,o),e=ot(et.ALPHANUMERIC,p.ALPHANUMERIC,o),n,r;return ht.isKanjiModeEnabled()?(n=ot(et.BYTE,p.BYTE,o),r=ot(et.KANJI,p.KANJI,o)):(n=ot(et.BYTE_KANJI,p.BYTE,o),r=[]),t.concat(e,n,r).sort(function(a,s){return a.index-s.index}).map(function(a){return{data:a.data,mode:a.mode,length:a.length}})}function Nt(o,t){switch(t){case p.NUMERIC:return Ie.getBitsLength(o);case p.ALPHANUMERIC:return Me.getBitsLength(o);case p.KANJI:return Pe.getBitsLength(o);case p.BYTE:return Ne.getBitsLength(o)}}function Co(o){return o.reduce(function(t,e){let n=t.length-1>=0?t[t.length-1]:null;return n&&n.mode===e.mode?(t[t.length-1].data+=e.data,t):(t.push(e),t)},[])}function bo(o){let t=[];for(let e=0;e<o.length;e++){let n=o[e];switch(n.mode){case p.NUMERIC:t.push([n,{data:n.data,mode:p.ALPHANUMERIC,length:n.length},{data:n.data,mode:p.BYTE,length:n.length}]);break;case p.ALPHANUMERIC:t.push([n,{data:n.data,mode:p.BYTE,length:n.length}]);break;case p.KANJI:t.push([n,{data:n.data,mode:p.BYTE,length:xe(n.data)}]);break;case p.BYTE:t.push([{data:n.data,mode:p.BYTE,length:xe(n.data)}])}}return t}function Ao(o,t){let e={},n={start:{}},r=["start"];for(let i=0;i<o.length;i++){let a=o[i],s=[];for(let u=0;u<a.length;u++){let f=a[u],g=""+i+u;s.push(g),e[g]={node:f,lastCount:0},n[g]={};for(let b=0;b<r.length;b++){let w=r[b];e[w]&&e[w].node.mode===f.mode?(n[w][g]=Nt(e[w].lastCount+f.length,f.mode)-Nt(e[w].lastCount,f.mode),e[w].lastCount+=f.length):(e[w]&&(e[w].lastCount=f.length),n[w][g]=Nt(f.length,f.mode)+4+p.getCharCountIndicator(f.mode,t))}}r=s}for(let i=0;i<r.length;i++)n[r[i]].end=0;return{map:n,table:e}}function Te(o,t){let e,n=p.getBestModeForData(o);if(e=p.from(t,n),e!==p.BYTE&&e.bit<n.bit)throw new Error('"'+o+'" cannot be encoded with mode '+p.toString(e)+`. 4592 Suggested mode is: `+p.toString(n));switch(e===p.KANJI&&!ht.isKanjiModeEnabled()&&(e=p.BYTE),e){case p.NUMERIC:return new Ie(o);case p.ALPHANUMERIC:return new Me(o);case p.KANJI:return new Pe(o);case p.BYTE:return new Ne(o)}}j.fromArray=function(t){return t.reduce(function(e,n){return typeof n=="string"?e.push(Te(n,null)):n.data&&e.push(Te(n.data,n.mode)),e},[])};j.fromString=function(t,e){let n=Le(t,ht.isKanjiModeEnabled()),r=bo(n),i=Ao(r,e),a=Eo.find_path(i.map,"start","end"),s=[];for(let u=1;u<a.length-1;u++)s.push(i.table[a[u]].node);return j.fromArray(Co(s))};j.rawSplit=function(t){return j.fromArray(Le(t,ht.isKanjiModeEnabled()))}});var _e=E(qe=>
4592{var gt=_(),Pt=it(),So=Yt(),Bo=Gt(),xo=jt(),To=Xt(),qt=Zt(),_t=Et(),Io=re(),ft=de(),Mo=pe(),No=D(),Lt=Re();function Po(o,t){let e=o.size,n=To.getPositions(t);for(let r=0;r<n.length;r++){let i=n[r][0],a=n[r][1];for(let s=-1;s<=7;s++)if(!(i+s<=-1||e<=i+s))for(let u=-1;u<=7;u++)a+u<=-1||e<=a+u||(s>=0&&s<=6&&(u===0||u===6)||u>=0&&u<=6&&(s===0||s===6)||s>=2&&s<=4&&u>=2&&u<=4?o.set(i+s,a+u,!0,!0):o.set(i+s,a+u,!1,!0))}}function Lo(o){let t=o.size;for(let e=8;e<t-8;e++){let n=e%2===0;o.set(e,6,n,!0),o.set(6,e,n,!0)}}function Ro(o,t){let e=xo.getPositions(t);for(let n=0;n<e.length;n++){let r=e[n][0],i=e[n][1];for(let a=-2;a<=2;a++)for(let s=-2;s<=2;s++)a===-2||a===2||s===-2||s===2||a===0&&s===0?o.set(r+a,i+s,!0,!0):o.set(r+a,i+s,!1,!0)}}function qo(o,t){let e=o.size,n=ft.getEncodedBits(t),r,i,a;for(let s=0;s<18;s++)r=Math.floor(s/3),i=s%3+e-8-3,a=(n>>s&1)===1,o.set(r,i,a,!0),o.set(i,r,a,!0)}function Rt(o,t,e){let n=o.size,r=Mo.getEncodedBits(t,e),i,a;for(i=0;i<15;i++)a=(r>>i&1)===1,i<6?o.set(i,8,a,!0):i<8?o.set(i+1,8,a,!0):o.set(n-15+i,8,a,!0),i<8?o.set(8,n-i-1,a,!0):i<9?o.set(8,15-i-1+1,a,!0):o.set(8,15-i-1,a,!0);o.set(n-8,8,1,!0)}function _o(o,t){let e=o.size,n=-1,r=e-1,i=7,a=0;for(let s=e-1;s>0;s-=2)for(s===6&&s--;;){for(let u=0;u<2;u++)if(!o.isReserved(r,s-u)){let f=!1;a<t.length&&(f=(t[a]>>>i&1)===1),o.set(r,s-u,f),i--,i===-1&&(a++,i=7)}if(r+=n,r<0||e<=r){r-=n,n=-n;break}}}function Uo(o,t,e){let n=new So;e.forEach(function(u){n.put(u.mode.bit,4),n.put(u.getLength(),No.getCharCountIndicator(u.mode,o)),u.write(n)});let r=gt.getSymbolTotalCodewords(o),i=_t.getTotalCodewordsCount(o,t),a=(r-i)*8;for(n.getLengthInBits()+4<=a&&n.put(0,4);n.getLengthInBits()%8!==0;)n.putBit(0);let s=(a-n.getLengthInBits())/8;for(let u=0;u<s;u++)n.put(u%2?17:236,8);return Do(n,o,t)}function Do(o,t,e){let n=gt.getSymbolTotalCodewords(t),r=_t.getTotalCodewordsCount(t,e),i=n-r,a=_t.getBlocksCount(t,e),s=n%a,u=a-s,f=Math.floor(n/a),g=Math.floor(i/a),b=g+1,w=f-g,S=new Io(w),M=0,x=new Array(a),m=new Array(a),v=0,mt=new Uint8Array(o.buffer);for(let q=0;q<a;q++){let V=q<u?g:b;x[q]=mt.slice(M,M+V),m[q]=S.encode(x[q]),M+=V,v=Math.max(v,V)}let L=new Uint8Array(n),rt=0,N,T;for(N=0;N<v;N++)for(T=0;T<a;T++)N<x[T].length&&(L[rt++]=x[T][N]);for(N=0;N<w;N++)for(T=0;T<a;T++)L[rt++]=m[T][N];return L}function ko(o,t,e,n){let r;if(Array.isArray(o))r=Lt.fromArray(o);else if(typeof o=="string"){let f=t;if(!f){let g=Lt.rawSplit(o);f=ft.getBestVersionForData(g,e)}r=Lt.fromString(o,f||40)}else throw new Error("Invalid data");let i=ft.getBestVersionForData(r,e);if(!i)throw new Error("The amount of data is too big to be stored in a QR Code");if(!t)t=i;else if(t<i)throw new Error(` 4593The chosen QR Code version cannot contain this amount of data. 4594Minimum version required to store current data is: `+i+`. 4595`);let a=Uo(t,e,r),s=gt.getSymbolSize(t),u=new Bo(s);return Po(u,t),Lo(u),Ro(u,t),Rt(u,e,0),t>=7&&qo(u,t),_o(u,a),isNaN(n)&&(n=qt.getBestMask(u,Rt.bind(null,u,e))),qt.applyMask(n,u),Rt(u,e,n),{modules:u,version:t,errorCorrectionLevel:e,maskPattern:n,segments:r}}qe.create=function(t,e){if(typeof t=="undefined"||t==="")throw new Error("No input text");let n=Pt.M,r,i;return typeof e!="undefined"&&(n=Pt.from(e.errorCorrectionLevel,Pt.M),r=ft.from(e.version),i=qt.from(e.maskPattern),e.toSJISFunc&>.setToSJISFunction(e.toSJISFunc)),ko(t,r,n,i)}});var Ut=E(H=>{function Ue(o){if(typeof o=="number"&&(o=o.toString()),typeof o!="string")throw new Error("Color should be defined as hex string");let t=o.slice().replace("#","").split("");if(t.length<3||t.length===5||t.length>8)throw new Error("Invalid hex color: "+o);(t.length===3||t.length===4)&&(t=Array.prototype.concat.apply([],t.map(function(n){return[n,n]}))),t.length===6&&t.push("F","F");let e=parseInt(t.join(""),16);return{r:e>>24&255,g:e>>16&255,b:e>>8&255,a:e&255,hex:"#"+t.slice(0,6).join("")}}H.getOptions=function(t){t||(t={}),t.color||(t.color={});let e=typeof t.margin=="undefined"||t.margin===null||t.margin<0?4:t.margin,n=t.width&&t.width>=21?t.width:void 0,r=t.scale||4;
4595return{width:n,scale:n?4:r,margin:e,color:{dark:Ue(t.color.dark||"#000000ff"),light:Ue(t.color.light||"#ffffffff")},type:t.type,rendererOpts:t.rendererOpts||{}}};H.getScale=function(t,e){return e.width&&e.width>=t+e.margin*2?e.width/(t+e.margin*2):e.scale};H.getImageWidth=function(t,e){let n=H.getScale(t,e);return Math.floor((t+e.margin*2)*n)};H.qrToImageData=function(t,e,n){let r=e.modules.size,i=e.modules.data,a=H.getScale(r,n),s=Math.floor((r+n.margin*2)*a),u=n.margin*a,f=[n.color.light,n.color.dark];for(let g=0;g<s;g++)for(let b=0;b<s;b++){let w=(g*s+b)*4,S=n.color.light;if(g>=u&&b>=u&&g<s-u&&b<s-u){let M=Math.floor((g-u)/a),x=Math.floor((b-u)/a);S=f[i[M*r+x]?1:0]}t[w++]=S.r,t[w++]=S.g,t[w++]=S.b,t[w]=S.a}}});var De=E(pt=>{var Dt=Ut();function vo(o,t,e){o.clearRect(0,0,t.width,t.height),t.style||(t.style={}),t.height=e,t.width=e,t.style.height=e+"px",t.style.width=e+"px"}function zo(){try{return document.createElement("canvas")}catch{throw new Error("You need to specify a canvas element")}}pt.render=function(t,e,n){let r=n,i=e;typeof r=="undefined"&&(!e||!e.getContext)&&(r=e,e=void 0),e||(i=zo()),r=Dt.getOptions(r);let a=Dt.getImageWidth(t.modules.size,r),s=i.getContext("2d"),u=s.createImageData(a,a);return Dt.qrToImageData(u.data,t,r),vo(s,i,a),s.putImageData(u,0,0),i};pt.renderToDataURL=function(t,e,n){let r=n;typeof r=="undefined"&&(!e||!e.getContext)&&(r=e,e=void 0),r||(r={});let i=pt.render(t,e,r),a=r.type||"image/png",s=r.rendererOpts||{};return i.toDataURL(a,s.quality)}});var ze=E(ve=>{var Fo=Ut();function ke(o,t){let e=o.a/255,n=t+'="'+o.hex+'"';return e<1?n+" "+t+'-opacity="'+e.toFixed(2).slice(1)+'"':n}function kt(o,t,e){let n=o+t;return typeof e!="undefined"&&(n+=" "+e),n}function Oo(o,t,e){let n="",r=0,i=!1,a=0;for(let s=0;s<o.length;s++){let u=Math.floor(s%t),f=Math.floor(s/t);!u&&!i&&(i=!0),o[s]?(a++,s>0&&u>0&&o[s-1]||(n+=i?kt("M",u+e,.5+f+e):kt("m",r,0),r=0,i=!1),u+1<t&&o[s+1]||(n+=kt("h",a),a=0)):r++}return n}ve.render=function(t,e,n){let r=Fo.getOptions(e),i=t.modules.size,a=t.modules.data,s=i+r.margin*2,u=r.color.light.a?"<path "+ke(r.color.light,"fill")+' d="M0 0h'+s+"v"+s+'H0z"/>':"",f="<path "+ke(r.color.dark,"stroke")+' d="'+Oo(a,i,r.margin)+'"/>',g='viewBox="0 0 '+s+" "+s+'"',w='<svg xmlns="http://www.w3.org/2000/svg" '+(r.width?'width="'+r.width+'" height="'+r.width+'" ':"")+g+' shape-rendering="crispEdges">'+u+f+`</svg> 4596`;return typeof n=="function"&&n(null,w),w}});var Oe=E(nt=>{var Ho=Vt(),vt=_e(),Fe=De(),Vo=ze();function zt(o,t,e,n,r){let i=[].slice.call(arguments,1),a=i.length,s=typeof i[a-1]=="function";if(!s&&!Ho())throw new Error("Callback required as last argument");if(s){if(a<2)throw new Error("Too few arguments provided");a===2?(r=e,e=t,t=n=void 0):a===3&&(t.getContext&&typeof r=="undefined"?(r=n,n=void 0):(r=n,n=e,e=t,t=void 0))}else{if(a<1)throw new Error("Too few arguments provided");return a===1?(e=t,t=n=void 0):a===2&&!t.getContext&&(n=e,e=t,t=void 0),new Promise(function(u,f){try{let g=vt.create(e,n);u(o(g,t,n))}catch(g){f(g)}})}try{let u=vt.create(e,n);r(null,o(u,t,n))}catch(u){r(u)}}nt.create=vt.create;nt.toCanvas=zt.bind(null,Fe.render);nt.toDataURL=zt.bind(null,Fe.renderToDataURL);nt.toString=zt.bind(null,function(o,t,e){return Vo.render(o,e)})});var He=je(Oe(),1);(()=>{if(window.__GOOOOD_HOME_SHARE__)return;window.__GOOOOD_HOME_SHARE__=!0,window.__GOOOOD_HOME_SHARE_TOUCH__=!0;let o=0,t=null,e=0,n=()=>{if(document.getElementById("gooood-share-runtime-layer"))return;let l=document.createElement("style");l.id="gooood-share-runtime-layer",l.textContent=`@media (max-width: 767px) { 4597 .v10-candidate-header .site-header, 4598 .site-header[data-v10-fragment="header"] { z-index: 10030 !important; overflow: visible !important; } 4599 .v10-candidate-header .header-row, 4600 .site-header[data-v10-fragment="header"] .header-row, 4601 .v10-candidate-header .header-actions, 4602 .site-header[data-v10-fragment="header"] .header-actions { overflow: visible !important; } 4603 .v10-candidate-header .header-actions > [data-gooood-page-share], 4604 .site-header[data-v10-fragment="header"] .header-actions > [data-gooood-page-share], 4605 .header-actions > [data-gooood-page-share] { display: none !important; } 4606 .mobile-share, 4607 .user-field > .share-action { display: none !important; } 4608 .header-actions > .gooood-auth-slot { display: none !important; } 4609 .v10-candidate-header .header-actions > .header-search, 4610 .site-header[data-v10-fragment="header"] .header-actions > .header-search, 4611 .header-actions > .header-search { display: inline-flex !important; } 4612 .header-actions > .header-search .header-search-toggle {
4613 align-items: center !important; 4614 background: #fff !important; 4615 color: #333 !important; 4616 display: inline-flex !important; 4617 font-size: 13px !important; 4618 gap: 5px !important; 4619 height: 60px !important; 4620 justify-content: center !important; 4621 min-height: 60px !important; 4622 width: 76px !important; 4623 } 4624 .header-actions > .header-search .header-search-icon, 4625 .user-field > .search-action .header-search-icon { 4626 height: 15px !important; 4627 width: 15px !important; 4628 } 4629 .header-actions > .header-search .header-search-icon::after, 4630 .user-field > .search-action .header-search-icon::after { 4631 bottom: -3px !important; 4632 right: -5px !important; 4633 width: 7px !important; 4634 } 4635 .user-field { 4636 background: #fff !important; 4637 display: flex !important; 4638 height: 60px !important; 4639 position: fixed !important; 4640 right: 0 !important; 4641 top: 0 !important; 4642 width: 76px !important; 4643 z-index: 2000 !important; 4644 } 4645 .user-field > li:not(.search-action) { display: none !important; } 4646 .user-field > .search-action { 4647 display: flex !important; 4648 height: 60px !important; 4649 width: 76px !important; 4650 } 4651 .user-field > .search-action button { 4652 align-items: center !important; 4653 display: inline-flex !important; 4654 flex-direction: row-reverse !important; 4655 font-size: 13px !important; 4656 gap: 5px !important; 4657 height: 60px !important; 4658 justify-content: center !important; 4659 padding: 0 !important; 4660 width: 76px !important; 4661 } 4662 .mobile-menu-item > a, 4663 .mobile-menu-parent, 4664 .mobile-menu-tools a, 4665 .mobile-user-links button { font-size: 16px !important; } 4666 .mobile-submenu a, 4667 .dropdown-menu a { font-size: 14px !important; line-height: 42px !important; padding-left: 46px !important; } 4668 [data-gooood-page-share].is-open .action-dropdown, 4669 [data-gooood-page-share] .action-dropdown { position: fixed !important; right: 0 !important; top: 60px !important; z-index: 10047 !important; pointer-events: auto !important; } 4670 [data-gooood-page-share].is-open .action-dropdown { display: block !important; opacity: 1 !important; visibility: visible !important; transform: translateY(0) !important; } 4671 [data-gooood-share="wechat"], 4672 [data-gooood-share-legacy-wechat], 4673 .share-icon.wechat, 4674 .wechat-share-wrap, 4675 .wechat-control { display: none !important; } 4676} 4677/* step-share-g3-header-search-final */ 4678@media (max-width: 991px) { 4679 .v10-candidate-header .header-actions > [data-gooood-page-share="1"], 4680 .site-header[data-v10-fragment="header"] .header-actions > [data-gooood-page-share="1"], 4681 [data-v10-fragment="header"] .header-actions > [data-gooood-page-share="1"] { display: none !important; } 4682 .v10-candidate-header .header-actions > .header-search, 4683 .site-header[data-v10-fragment="header"] .header-actions > .header-search, 4684 [data-v10-fragment="header"] .header-actions > .header-search { display: inline-flex !important; } 4685}`,document.head.appendChild(l)},r=()=>document.documentElement.lang==="en"?"en":"zh",i=()=>{let l=r()==="en"?"Search":"\u641C\u7D22";document.querySelectorAll(".user-field > .search-action button, .mobile-search-top").forEach(c=>{c.setAttribute("aria-label",l),c.querySelectorAll("span:not(.header-search-icon)").forEach(d=>{d.textContent=l})})},a=()=>{var l;return((l=document.querySelector('link[rel="canonical"]'))==null?void 0:l.href)||`https://www.gooood.cn${location.pathname==="/"?"/":location.pathname}`},s=()=>window.matchMedia("(max-width: 767px)").matches,u=l=>{try{let c=new URL(l,location.href);return(c.hostname==="localhost"||c.hostname==="127.0.0.1")&&(c.hostname="www.gooood.cn",c.port=""),c.protocol="https:",c.hash="",c.href}catch{return a()}},f=l=>{var y;let c=l.closest(".article"),d=c==null?void 0:c.querySelector(".article-text h3 a"),h=c==null?void 0:c.querySelector(".cover img");return{url:u((d==null?void 0:d.href)||a()),title:(d==null?void 0:d.dataset[r()])||(d==null?void 0:d.dataset.zh)||((y=d==null?void 0:d.textContent)==null?void 0:y.trim())||document.title,image:(h==null?void 0:h.currentSrc)||(h==null?void 0:h.src)||""}},g=()=>{var l,c;return{url:a(),title:((l=document.querySelector('meta[property="og:title"]'))==null?void 0:l.content)||document.title,image:((c=document.querySelector('meta[property="og:image"]'))==null?void 0:c.content)||""}},b=l=>l.closest(".article")?f(l):g(),w=(l,c)=>{let d=encodeURIComponent(c.url),h=encodeURIComponent(c.title),y=encodeURIComponent(c.image||"");return{weibo:`https://service.weibo.com/share/share.php?url=${d}&title=${h}${c.image?`&pic=${y}`:""}`,twitter:`https://twitter.com/intent/tweet?url=${d}&text=${h}`,facebook:`https://www.facebook.com/sharer/sharer.php?u=${d}`,pinterest:`https://www.pinterest.com/pin/create/button/?url=${d}${c.image?`&media=${y}`:""}&description=${h}`}[l]||""},S=document.createElement("div");S.className="gooood-share-toast",S.hidden=!0,S.setAttribute("role","status"),document.body.appendChild(S);let M=(l,c=l)=>{clearTimeout(o),S.textContent=r()==="en"?c:l,S.hidden=!1,o=setTimeout(()=>{S.hidden=!0},2600)},x=async l=>{var B;let c=!1;try{if(!((B=navigator.clipboard)!=null&&B.writeText))throw new Error("clipboard unavailable");await navigator.clipboard.writeText(l),c=!0}catch{let I=document.createElement("textarea");I.value=l,I.setAttribute("readonly",""),I.style.cssText="position:fixed;top:0;left:0;width:1px;height:1px;opacity:0;z-index:-1",document.body.appendChild(I),I.focus(),I.select(),I.setSelectionRange(0,l.length);try{c=typeof document.execCommand=="function"&&document.execCommand("copy")}catch{c=!1}I.remove()}
4685if(c){M("\u94FE\u63A5\u5DF2\u590D\u5236","Link copied");return}let d=r(),h=m.querySelector(".gooood-share-manual-copy"),y=m.querySelector("canvas");m.querySelector("#gooood-share-title").textContent=d==="en"?"Copy link":"\u590D\u5236\u94FE\u63A5",m.querySelector(".gooood-share-qr-title").textContent=d==="en"?"Select and copy the link below.":"\u8BF7\u9009\u4E2D\u5E76\u590D\u5236\u4E0B\u65B9\u6B63\u5F0F\u94FE\u63A5",y.hidden=!0,h.hidden=!1,h.value=l,m.dataset.shareUrl=l,m.hidden=!1,document.body.classList.add("gooood-share-open"),setTimeout(()=>{h.focus(),h.select()},0),M("\u6D4F\u89C8\u5668\u9650\u5236\u81EA\u52A8\u590D\u5236\uFF0C\u8BF7\u624B\u52A8\u590D\u5236","Automatic copy is blocked. Please copy manually.")},m=document.createElement("div");m.className="gooood-share-modal",m.hidden=!0,m.innerHTML='<div class="gooood-share-dialog" role="dialog" aria-modal="true" aria-labelledby="gooood-share-title"><button class="gooood-share-close" type="button" aria-label="\u5173\u95ED\u5206\u4EAB">\xD7</button><h2 id="gooood-share-title" data-zh="\u5FAE\u4FE1\u626B\u7801\u5206\u4EAB" data-en="Share on WeChat">\u5FAE\u4FE1\u626B\u7801\u5206\u4EAB</h2><canvas width="240" height="240"></canvas><p class="gooood-share-qr-title"></p><input class="gooood-share-manual-copy" type="text" readonly hidden aria-label="\u6B63\u5F0F\u5206\u4EAB\u94FE\u63A5"><button class="gooood-share-copy" type="button" data-zh="\u590D\u5236\u94FE\u63A5" data-en="Copy link">\u590D\u5236\u94FE\u63A5</button></div>',document.body.appendChild(m);let v=()=>{m.hidden=!0,document.body.classList.remove("gooood-share-open")},mt=async l=>{let c=r();m.querySelectorAll("[data-zh][data-en]").forEach(d=>{d.textContent=d.dataset[c]||d.dataset.zh}),m.querySelector(".gooood-share-qr-title").textContent=l.title,m.dataset.shareUrl=l.url,m.querySelector("canvas").hidden=!1,m.querySelector(".gooood-share-manual-copy").hidden=!0,m.hidden=!1,document.body.classList.add("gooood-share-open");try{await He.default.toCanvas(m.querySelector("canvas"),l.url,{width:240,margin:1,errorCorrectionLevel:"M"})}catch{let h=m.querySelector("canvas"),y=m.querySelector(".gooood-share-manual-copy");h.hidden=!0,y.hidden=!1,y.value=l.url,M("\u4E8C\u7EF4\u7801\u751F\u6210\u5931\u8D25\uFF0C\u8BF7\u4F7F\u7528\u590D\u5236\u94FE\u63A5","QR code failed. Please copy the link.")}},L=(l=null)=>{document.querySelectorAll(".share-action.is-open, [data-gooood-page-share].is-open").forEach(c=>{var d;c!==l&&(c.classList.remove("is-open"),(d=c.querySelector("[data-gooood-share-toggle], :scope > a"))==null||d.setAttribute("aria-expanded","false"))}),l||(t=null)},rt=l=>{let c=b(l);l.querySelectorAll("[data-gooood-share]").forEach(d=>{let h=d.dataset.goooodShare,y=w(h,c);d.href=y||"#share",y?(d.target="_blank",d.rel="noopener noreferrer"):(d.removeAttribute("target"),d.removeAttribute("rel"))}),document.querySelectorAll("[data-gooood-page-share] [data-gooood-share]").forEach(d=>{d.href="#share",d.setAttribute("role","button"),d.removeAttribute("target"),d.removeAttribute("rel")})},N=()=>{document.querySelectorAll(".share-action").forEach(l=>{let c=l.querySelector("button");c&&(c.dataset.goooodShareToggle="1",c.setAttribute("aria-haspopup","true"),c.setAttribute("aria-expanded","false")),l.querySelectorAll(".share-icon").forEach(d=>{let h=["wechat","weibo","twitter","facebook","pinterest","copy-link"].find(y=>d.classList.contains(y));h&&(d.dataset.goooodShare=h==="copy-link"?"copy":h),d.href="#share",d.setAttribute("role","button")})}),document.querySelectorAll("[data-gooood-page-share]").forEach(l=>{let c=l.querySelector(":scope > a, :scope > button");c&&(c.dataset.goooodShareToggle="1",c.setAttribute("aria-haspopup","true"),c.setAttribute("aria-expanded","false"))}),document.querySelectorAll(".share-menu").forEach(l=>{l.querySelectorAll("button").forEach(c=>{var h;let d=((h=c.textContent)==null?void 0:h.trim())||"";d==="\u5FAE\u4FE1"?c.dataset.goooodShareLegacyWechat="1":/å¤å¶|Copy/i.test(d)&&(c.dataset.goooodShareCopy="1")})})};m.querySelector(".gooood-share-close").addEventListener("click",v),m.querySelector(".gooood-share-copy").addEventListener("click",()=>x(m.dataset.shareUrl||a())),m.addEventListener("click",l=>{l.target===m&&v()}),document.addEventListener("keydown",l=>{l.key==="Escape"&&(m.hidden||v(),L())});let T=async l=>{let c=b(l),d=l.dataset.goooodShare;if(L(),d==="wechat"&&s())return x(c.url);if(d==="wechat")return mt(c);if(d==="copy")return x(c.url);
4685let h=w(d,c);h&&window.open(h,"_blank","noopener,noreferrer,width=760,height=640")},q=l=>{var h;if(!s())return;let c=l.target,d=(h=c==null?void 0:c.closest)==null?void 0:h.call(c,'[data-gooood-share="copy"], .copy-link, [data-gooood-share-copy]');d&&(l.preventDefault(),l.stopPropagation(),typeof l.stopImmediatePropagation=="function"&&l.stopImmediatePropagation(),L(),x(b(d).url))},V=l=>{var y,B;if(!t)return null;let c=((y=l.changedTouches)==null?void 0:y[0])||((B=l.touches)==null?void 0:B[0]);if(!c)return null;let d=c.clientX,h=c.clientY;return Array.from(t.querySelectorAll("[data-gooood-share]")).find(K=>{let I=K.getBoundingClientRect();return d>=I.left&&d<=I.right&&h>=I.top&&h<=I.bottom})||null},Ft=async(l,c=!1)=>{let d=Date.now();if(c){if(d-e<250)return;e=d}else if(d-e<450)return;let h=l.target.closest("[data-gooood-share]");if(h)return l.preventDefault(),l.stopPropagation(),T(h);let y=l.target.closest("[data-gooood-share-toggle]");if(y){l.preventDefault(),l.stopPropagation();let B=y.closest(".share-action, [data-gooood-page-share]"),K=!B.classList.contains("is-open");rt(B),L(B),B.classList.toggle("is-open",K),y.setAttribute("aria-expanded",String(K)),t=K?B:null;return}t&&!t.contains(l.target)&&L()};document.addEventListener("click",q,!0),document.addEventListener("click",l=>{Ft(l)}),document.addEventListener("touchstart",l=>{var y;let c=l.target,d=((y=c==null?void 0:c.closest)==null?void 0:y.call(c,"[data-gooood-share]"))||V(l);if(!d)return;l.cancelable&&l.preventDefault(),l.stopPropagation();let h=Date.now();h-e<250||(e=h,T(d))},{capture:!0,passive:!1}),document.addEventListener("touchend",l=>{var h,y;let c=l.target,d=((h=c==null?void 0:c.closest)==null?void 0:h.call(c,"[data-gooood-share]"))||V(l);if(d){l.cancelable&&l.preventDefault(),l.stopPropagation();let B=Date.now();if(B-e<250)return;e=B,T(d);return}(y=c==null?void 0:c.closest)!=null&&y.call(c,"[data-gooood-share-toggle]")&&(l.cancelable&&l.preventDefault(),Ft(l,!1))},{capture:!0,passive:!1}),n(),N(),i(),new MutationObserver(()=>{N(),i()}).observe(document.body,{childList:!0,subtree:!0})})();})(); 4686</script>
4686 4687</body> 4688</html>
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.