萬安算交所AIXX GLOBAL

GLOBAL SUPPLY HALL

全球货源大厅

(function(){ const btn=document.getElementById('memberBtn'),menu=document.getElementById('memberMenu'),name=document.getElementById('memberName'); if(!btn)return; const sess=localStorage.getItem('wanan_session'); const ME={center:{zh:'个人中心',en:'Account'},loginreg:{zh:'注册 / 登录',en:'Sign up / Log in'},profile:{zh:'我的资料 / 实名状态',en:'Profile & Verification'},buy:{zh:'我的求购单',en:'Buy Orders'},sell:{zh:'我的货源单',en:'Supply Orders'},soon:{zh:'即将上线',en:'Coming soon'},logout:{zh:'退出登录',en:'Log out'}}; const mt=k=>{const t=T[lang]||T.en;return t[k]||T.en[k]||ME[k][T.en[k]?'en':'zh']||ME[k].zh}; const DRAFT=[['profile','register.html?v=20260903g',''], ['buy','','soon'], ['sell','','soon']]; let currentUser=null; function render(){ const who=currentUser?((currentUser.email||'').split('@')[0]):null; name.textContent=mt('center')+(who?(' · '+who):''); menu.innerHTML=''; menu.innerHTML=''; const item=(label,href,tag)=>{ const a=document.createElement('a');a.href=href||'javascript:void(0)'; a.innerHTML=mt(label)+(tag?' '+mt('soon')+'':''); a.style.cssText='display:block;padding:9px 12px;border-radius:9px;color:rgba(255,255,255,.82);text-decoration:none;font-size:12px'; a.onmouseenter=()=>a.style.background='rgba(255,255,255,.07)'; a.onmouseleave=()=>a.style.background='none'; menu.appendChild(a); }; if(!currentUser)item('loginreg','register.html?v=20260903g',''); else{ DRAFT.forEach(([label,href,tag])=>item(label,href,tag)); const b=document.createElement('button');b.textContent=mt('logout'); b.style.cssText='display:block;width:100%;text-align:left;padding:9px 12px;border-radius:9px;border:0;background:none;color:#ff9d8f;font:inherit;font-size:12px;cursor:pointer'; b.onclick=()=>{localStorage.removeItem('wanan_session');location.reload()}; menu.appendChild(b); } } window.__renderMember=render; fetch('/api/auth/me',{headers:sess?{'x-session':sess}:{}}).then(r=>r.ok?r.json():null).then(x=>{ currentUser=(x&&x.user)?x.user:null;render(); }).catch(()=>render()); btn.onclick=e=>{e.stopPropagation();menu.style.display=menu.style.display==='none'?'block':'none'}; document.addEventListener('click',()=>menu.style.display='none'); })(); let V2_DATA={supply:[],buyers:[],reports:[]}; let page=1,pageSize=24,totalCount=0,totalPages=1; async function loadV2Market(){ const CITY_LABELS={zh:{shenzhen:'深圳',beijing:'北京',newyork:'纽约',osaka:'大阪',paris:'巴黎',dubai:'迪拜'},en:{shenzhen:'Shenzhen',beijing:'Beijing',newyork:'New York',osaka:'Osaka',paris:'Paris',dubai:'Dubai'}}; if(typeof I18N!=='undefined'&&I18N){for(const code of Object.keys(I18N)){if(I18N[code]&&I18N[code].city)Object.assign(I18N[code].city,CITY_LABELS[code]||CITY_LABELS.en)}} if(typeof T!=='undefined'&&T){for(const code of Object.keys(T)){if(T[code]&&T[code].city)Object.assign(T[code].city,CITY_LABELS[code]||CITY_LABELS.en)}} try{ const endpoint=`/api/v2/listings?query=${encodeURIComponent(query||'')}&model=${encodeURIComponent(modelParam)}&country=${encodeURIComponent(countryParam)}&page=${page}&pageSize=${pageSize}&status=all`; const [l,b]=await Promise.all([ fetch(endpoint,{cache:'no-store'}).then(r=>r.json()), fetch(`/api/v2/buyer-orders?model=${encodeURIComponent(modelParam)}`,{cache:'no-store'}).then(r=>r.json()) ]); const mapCat={'gpu_strict':'gpu','gpu_regional':'gpu','ai_server':'server','ai_rack':'server','memory_node':'server','storage':'server','network':'network','rack':'rack'}; V2_DATA.supply=l.items.map(x=>({model:x.model,country:x.country.toLowerCase(),city:x.city||'city',total:x.total,unit:x.unitLabel==='rack'?'rack':'unit',price:x.price,moq:x.moq,status:'verified',lifecycle:x.lifecycle||'available',reportNo:x.reportNo,_no:x.publicNo})); totalCount=l.total||V2_DATA.supply.length;totalPages=Math.max(1,l.totalPages||1); if(l.facets)FACETS.supply=l.facets; if(b.facets)FACETS.buyers=b.facets; V2_DATA.buyers=b.items.map(x=>({model:x.model,country:x.country.toLowerCase(),target:x.target,funds:x.funds,report:x.report,reportNo:x.reportNo||'',_no:x.publicNo})); // Replace hardcoded arrays in place so every renderer consumes generated data. SUPPLY.splice(0, SUPPLY.length, ...V2_DATA.supply); BUYERS.splice(0, BUYERS.length, ...V2_DATA.buyers); if(typeof renderFilters==='function'&&typeof renderMarket==='function'){renderFilters();renderMarket()} if(typeof render==='function'&&document.getElementById('cards')){render()} }catch(e){console.warn('v2 data unavailable',e);const c=el('cards');if(c)c.innerHTML='
'+((T[lang]||T.en).noResult||'暂无数据')+'(数据加载失败,请刷新重试)
'} } const SUPPLY=[]; const BUYERS=[]; const REPORTS=[]; const T={ zh:{soldOut:'售罄',resultOf:'{a} / {b} 条货源',pageOf:'第 {a} / {b} 页',noResult:'未找到匹配货源或报告编号',supply:'全球货源大厅',buyers:'全球订单大厅',supplyLabel:'GLOBAL SUPPLY HALL',buyersLabel:'GLOBAL ORDER HALL',searchPh:'搜索报告编号 / 型号 / 地区',searchBtn:'搜索',all:'全部',total:'总数量',moq:'最低起售',price:'单价',threshold:'最低验资',seek:'求购',target:'目标数量',funds:'已验资金额',report:'验资报告',inspect:'验货报告',contact:'直接联系',from:'起',verified:'已验货',fundVerified:'已验资',units:{unit:'台',rack:'架'},city:{singapore:'新加坡',dallas:'达拉斯',johor:'新山',hanoi:'河内',abudhabi:'阿布扎比',shanghai:'上海',tokyo:'东京',frankfurt:'法兰克福',sanjose:'圣何塞',hongkong:'香港',seoul:'首尔'}}, en:{soldOut:'SOLD OUT',resultOf:'{a} / {b} listings',pageOf:'Page {a} / {b}',noResult:'No matching listings or report numbers',supply:'Global Supply Hall',buyers:'Global Order Hall',supplyLabel:'GLOBAL SUPPLY HALL',buyersLabel:'GLOBAL ORDER HALL',searchPh:'Search report no. / model / region',searchBtn:'Search',all:'All',total:'Total',moq:'Min. Order',price:'Unit Price',threshold:'Min. Verification',seek:'Seeking',target:'Target',funds:'Verified Funds',report:'Fund Report',inspect:'Inspection Report',contact:'Direct Contact',from:'from',verified:'VERIFIED',fundVerified:'FUNDS VERIFIED',units:{unit:'units',rack:'racks'},city:{singapore:'Singapore',dallas:'Dallas',johor:'Johor',hanoi:'Hanoi',abudhabi:'Abu Dhabi',shanghai:'Shanghai',tokyo:'Tokyo',frankfurt:'Frankfurt',sanjose:'San Jose',hongkong:'Hong Kong',seoul:'Seoul'}}, ja:{resultOf:'{a} / {b} 件の出品',pageOf:'{a} / {b} ページ',supply:'グローバル供給ホール',buyers:'グローバル注文ホール',supplyLabel:'GLOBAL SUPPLY HALL',buyersLabel:'GLOBAL ORDER HALL',searchPh:'報告番号 / 型番 / 地域を検索',searchBtn:'検索',all:'すべて',total:'総数',moq:'最低注文',price:'単価',threshold:'最低認証額',seek:'希望',target:'目標数',funds:'認証資金',report:'資金報告',inspect:'検収報告',contact:'直接連絡',from:'から',verified:'検収済',fundVerified:'資金認証済',units:{unit:'台',rack:'ラック'},city:{singapore:'シンガポール',dallas:'ダラス',johor:'ジョホール',hanoi:'ハノイ',abudhabi:'アブダビ',shanghai:'上海',tokyo:'東京',frankfurt:'フランクフルト',sanjose:'サンノゼ',hongkong:'香港',seoul:'ソウル'}}, ko:{resultOf:'{a} / {b}개 출품',pageOf:'{a} / {b} 페이지',supply:'글로벌 공급 홀',buyers:'글로벌 주문 홀',supplyLabel:'GLOBAL SUPPLY HALL',buyersLabel:'GLOBAL ORDER HALL',searchPh:'보고서 번호 / 모델 / 지역 검색',searchBtn:'검색',all:'전체',total:'총수',moq:'최소주문',price:'단가',threshold:'최소 인증',seek:'구매 희망',target:'목표 수량',funds:'인증 자금',report:'자금 보고서',inspect:'검수 보고서',contact:'직접 연락',from:'부터',verified:'검수 완료',fundVerified:'자금 인증',units:{unit:'대',rack:'랙'},city:{singapore:'싱가포르',dallas:'달라스',johor:'조호르',hanoi:'하노이',abudhabi:'아부다비',shanghai:'상하이',tokyo:'도쿄',frankfurt:'프랑크푸르트',sanjose:'산호세',hongkong:'홍콩',seoul:'서울'}}, de:{resultOf:'{a} / {b} Angebote',pageOf:'Seite {a} / {b}',supply:'Globales Angebot',buyers:'Globaler Auftragsmarkt',supplyLabel:'GLOBAL SUPPLY HALL',buyersLabel:'GLOBAL ORDER HALL',searchPh:'Berichtsnr. / Modell / Region suchen',searchBtn:'Suchen',all:'Alle',total:'Gesamt',moq:'Mindestmenge',price:'Stückpreis',threshold:'Mindestprüfung',seek:'Sucht',target:'Zielmenge',funds:'Geprüftes Kapital',report:'Kapitalbericht',inspect:'Prüfbericht',contact:'Direktkontakt',from:'ab',verified:'GEPRÜFT',fundVerified:'KAPITAL GEPRÜFT',units:{unit:'Stück',rack:'Racks'},city:{singapore:'Singapur',dallas:'Dallas',johor:'Johor',hanoi:'Hanoi',abudhabi:'Abu Dhabi',shanghai:'Shanghai',tokyo:'Tokio',frankfurt:'Frankfurt',sanjose:'San Jose',hongkong:'Hongkong',seoul:'Seoul'}}, fr:{resultOf:'{a} / {b} offres',pageOf:'Page {a} / {b}',supply:'Offre Mondiale',buyers:'Marché Global des Ordres',supplyLabel:'GLOBAL SUPPLY HALL',buyersLabel:'GLOBAL ORDER HALL',searchPh:'Rechercher n° / modèle / région',searchBtn:'Rechercher',all:'Tous',total:'Total',moq:'Minimum',price:'Prix unitaire',threshold:'Vérification min.',seek:'Recherche',target:'Objectif',funds:'Fonds vérifiés',report:'Rapport de fonds',inspect:'Rapport d’inspection',contact:'Contact direct',from:'à partir de',verified:'VÉRIFIÉ',fundVerified:'FONDS VÉRIFIÉS',units:{unit:'unités',rack:'racks'},city:{singapore:'Singapour',dallas:'Dallas',johor:'Johor',hanoi:'Hanoï',abudhabi:'Abu Dhabi',shanghai:'Shanghai',tokyo:'Tokyo',frankfurt:'Francfort',sanjose:'San José',hongkong:'Hong Kong',seoul:'Séoul'}}, es:{resultOf:'{a} / {b} ofertas',pageOf:'Página {a} / {b}',supply:'Oferta Global',buyers:'Mercado Global de Órdenes',supplyLabel:'GLOBAL SUPPLY HALL',buyersLabel:'GLOBAL ORDER HALL',searchPh:'Buscar informe / modelo / región',searchBtn:'Buscar',all:'Todos',total:'Total',moq:'Mínimo',price:'Precio unit.',threshold:'Verif. mínima',seek:'Busca',target:'Objetivo',funds:'Fondos verificados',report:'Informe de fondos',inspect:'Informe de inspección',contact:'Contacto directo',from:'desde',verified:'VERIFICADO',fundVerified:'FONDOS VERIFICADOS',units:{unit:'unid.',rack:'racks'},city:{singapore:'Singapur',dallas:'Dallas',johor:'Johor',hanoi:'Hanói',abudhabi:'Abu Dabi',shanghai:'Shanghái',tokyo:'Tokio',frankfurt:'Fráncfort',sanjose:'San José',hongkong:'Hong Kong',seoul:'Seúl'}}, pt:{resultOf:'{a} / {b} ofertas',pageOf:'Página {a} / {b}',supply:'Oferta Global',buyers:'Mercado Global de Ordens',supplyLabel:'GLOBAL SUPPLY HALL',buyersLabel:'GLOBAL ORDER HALL',searchPh:'Pesquisar relatório / modelo / região',searchBtn:'Pesquisar',all:'Todos',total:'Total',moq:'Mínimo',price:'Preço un.',threshold:'Verif. mínima',seek:'Procura',target:'Meta',funds:'Fundos verificados',report:'Relatório de fundos',inspect:'Relatório de inspeção',contact:'Contato direto',from:'a partir de',verified:'VERIFICADO',fundVerified:'FUNDOS VERIFICADOS',units:{unit:'unid.',rack:'racks'},city:{singapore:'Singapura',dallas:'Dallas',johor:'Johor',hanoi:'Hanói',abudhabi:'Abu Dabi',shanghai:'Xangai',tokyo:'Tóquio',frankfurt:'Frankfurt',sanjose:'San Jose',hongkong:'Hong Kong',seoul:'Seul'}}, ru:{resultOf:'{a} / {b} предложений',pageOf:'Стр. {a} / {b}',supply:'Глобальные предложения',buyers:'Глобальный зал ордеров',supplyLabel:'GLOBAL SUPPLY HALL',buyersLabel:'GLOBAL ORDER HALL',searchPh:'Поиск: отчет / модель / регион',searchBtn:'Найти',all:'Все',total:'Всего',moq:'Мин. заказ',price:'Цена за ед.',threshold:'Мин. проверка',seek:'Ищет',target:'Цель',funds:'Проверенные средства',report:'Отчет о средствах',inspect:'Отчет об осмотре',contact:'Прямой контакт',from:'от',verified:'ПРОВЕРЕНО',fundVerified:'СРЕДСТВА ПРОВЕРЕНЫ',units:{unit:'шт.',rack:'стойки'},city:{singapore:'Сингапур',dallas:'Даллас',johor:'Джохор',hanoi:'Ханой',abudhabi:'Абу-Даби',shanghai:'Шанхай',tokyo:'Токио',frankfurt:'Франкфурт',sanjose:'Сан-Хосе',hongkong:'Гонконг',seoul:'Сеул'}}, ar:{resultOf:'{a} / {b} من العروض',pageOf:'صفحة {a} / {b}',supply:'قاعة العرض العالمية',buyers:'قاعة الطلبات العالمية',supplyLabel:'GLOBAL SUPPLY HALL',buyersLabel:'GLOBAL ORDER HALL',searchPh:'البحث: رقم التقرير / الطراز / المنطقة',searchBtn:'بحث',all:'الكل',total:'الإجمالي',moq:'الحد الأدنى',price:'سعر الوحدة',threshold:'الحد الأدنى للتحقق',seek:'يبحث عن',target:'الكمية',funds:'أموال موثقة',report:'تقرير الأموال',inspect:'تقرير الفحص',contact:'اتصال مباشر',from:'من',verified:'موثق',fundVerified:'أموال موثقة',units:{unit:'وحدة',rack:'حاويات'},city:{singapore:'سنغافورة',dallas:'دالاس',johor:'جوهر',hanoi:'هانوي',abudhabi:'أبوظبي',shanghai:'شنغهاي',tokyo:'طوكيو',frankfurt:'فرانكفورت',sanjose:'سان خوسيه',hongkong:'هونغ كونغ',seoul:'سيول'}} }; let type=new URLSearchParams(location.search).get('type')||'supply'; const urlLang=new URLSearchParams(location.search).get('lang');if(['zh','en','ja','ko','de','fr','es','pt','ru','ar'].includes(urlLang))lang=urlLang; const el=id=>document.getElementById(id); const MODEL_I18N={ en:{'液冷CDU':'Liquid Cooling CDU','42U AI机柜':'42U AI Rack'}, ja:{'液冷CDU':'液冷CDU','42U AI机柜':'42U AIラック'}, ko:{'液冷CDU':'액냉 CDU','42U AI机柜':'42U AI 랙'}, de:{'液冷CDU':'Flüssigkeits-CDU','42U AI机柜':'42U KI-Rack'}, fr:{'液冷CDU':'CDU de refroidissement liquide','42U AI机柜':'Rack IA 42U'}, es:{'液冷CDU':'CDU de líquido','42U AI机柜':'Rack de IA 42U'}, pt:{'液冷CDU':'CDU a líquido','42U AI机柜':'Rack de IA 42U'}, ru:{'液冷CDU':'Жидкостная CDU','42U AI机柜':'Стойка ИИ 42U'}, ar:{'液冷CDU':'وحدة توزيع سائل التبريد','42U AI机柜':'رف AI 42U'}}; function modelName(m){return (MODEL_I18N[lang]&&MODEL_I18N[lang][m])||m} const COUNTRY_I18N={ja:{EU:'欧州連合'},ko:{EU:'유럽연합'},fr:{EU:'Union européenne'},es:{EU:'Unión Europea'},pt:{EU:'União Europeia'},ru:{EU:'ЕС'},ar:{EU:'الاتحاد الأوروبي'}}; function region(code){if(code.toUpperCase()==='CN')return lang==='zh'?'中国大陆':'Mainland China';if(COUNTRY_I18N[lang]&&COUNTRY_I18N[lang][code.toUpperCase()])return COUNTRY_I18N[lang][code.toUpperCase()];try{return new Intl.DisplayNames([lang],{type:'region'}).of(code.toUpperCase())}catch(e){return code.toUpperCase()}} function setLang(l){lang=l;document.documentElement.lang=l;document.body.classList.toggle('rtl-content',l==='ar');const t=T[l]||T.en;document.getElementById('q').placeholder=t.searchPh;document.getElementById('searchBtn').textContent=t.searchBtn;document.getElementById('langName').textContent=LANGS.find(x=>x[0]===l)[1];document.querySelectorAll('#langMenu button').forEach(b=>b.classList.toggle('active',b.dataset.code===l));document.getElementById('brandCn').style.display=l==='zh'?'inline':'none';document.getElementById('brandEn').textContent='AIXX GLOBAL';el('pageTitle').textContent=t[type]||T.en[type];el('label').textContent=t[type+'Label']||T.en[type+'Label'];render();window.__renderMember&&window.__renderMember()} function setMode(m){type=m;modelParam='all';countryParam='all';page=1;history.replaceState(null,'',`hall.html?type=${m}`);loadV2Market()} function metric(k,v){return `
${k}${v}
`} const PRICE_LIVE={zh:'价格实时波动,实际以联系货主为准。',en:'Prices fluctuate in real time; final terms subject to owner contact.',ja:'価格はリアルタイムで変動します。最終条件は出品者へ確認してください。',ko:'가격은 실시간 변동되며 최종 조건은 판매자와 확인하세요.',de:'Preise ändern sich in Echtzeit; endgültige Konditionen beim Anbieter klären.',fr:'Prix en temps réel; conditions finales à confirmer avec le propriétaire.',es:'Precios en tiempo real; condiciones finales sujetas al propietario.',pt:'Preços em tempo real; condições finais sujeitas ao proprietário.',ru:'Цены меняются в реальном времени; условия уточните у владельца.',ar:'الأسعار تتغير في الوقت الفعلي؛ الشروط النهائية عبر الاتصال بالمالك.'}; let modelParam='all',countryParam='all'; let query=''; let FACETS={supply:null,buyers:null}; function interp(key,a,b){const tpl=(T[lang]||T.en)[key]||(T.en&&T.en[key])||key;return tpl.replace('{a}',a).replace('{b}',b)} function pageButton(label,target,active=false,disabled=false){return ``} function renderPagination(){ const box=el('pagination');if(!box)return; let nums=[];const start=Math.max(1,page-2),end=Math.min(totalPages,start+4); for(let i=start;i<=end;i++)nums.push(i); box.innerHTML=pageButton('‹',page-1,false,page<=1)+nums.map(i=>pageButton(i,i,i===page)).join('')+pageButton('›',page+1,false,page>=totalPages); box.querySelectorAll('button[data-page]').forEach(b=>b.onclick=()=>{const target=parseInt(b.dataset.page,10);if(target>=1&&target<=totalPages&&target!==page){page=target;loadV2Market()}}); } function renderFilters(){ const t=T[lang]||T.en; const src=type==='supply'?FACETS.supply:FACETS.buyers; const fallback=[...new Set((type==='supply'?SUPPLY:BUYERS).map(x=>x.model))]; const models=(src&&src.models&&src.models.length)?src.models:fallback; el('filters').innerHTML=``+models.map(m=>``).join(''); const cf=el('countryFilters'); const countries=type==='supply'&&FACETS.supply&&FACETS.supply.countries&&FACETS.supply.countries.length?FACETS.supply.countries:[]; if(countries.length){ cf.style.display='flex'; cf.innerHTML=``+countries.map(c=>``).join(''); }else{cf.style.display='none';cf.innerHTML=''} document.querySelectorAll('#filters .chip').forEach(b=>b.onclick=()=>{modelParam=b.dataset.model;page=1;loadV2Market()}); document.querySelectorAll('#countryFilters .chip').forEach(b=>b.onclick=()=>{countryParam=b.dataset.country;page=1;loadV2Market()}); } function render(){ const t=T[lang]||T.en; renderFilters(); const rows=type==='supply'?SUPPLY:BUYERS; el('resultCount').textContent=type==='supply'?interp('resultOf',rows.length,totalCount):`${rows.length}`; el('pageInfo').textContent=type==='supply'?interp('pageOf',page,totalPages):''; el('cards').innerHTML=type==='supply'?(rows.length?rows.map(x=>{ const sold=x.lifecycle==='sold_out'; return `
${modelName(x.model)}
${region(x.country)}${x.city&&x.city!=='city'?(t.city[x.city]?' · '+t.city[x.city]:' · '+x.city):''}
${sold?(t.soldOut||T.en.soldOut):t.verified}
${metric(t.total,`${x.total} ${t.units[x.unit]}`)}${metric(t.moq,`${x.moq} ${t.units[x.unit]}`)}${metric(t.price,`¥${x.price}万 ${t.from}`)}${metric(t.threshold,`¥${(x.price*x.moq).toFixed(0)}万 ${t.from}`)}

${PRICE_LIVE[lang]||PRICE_LIVE.en}

`}).join(''):``): rows.map(x=>`
${t.seek} ${modelName(x.model)}
${region(x.country)}
${t.fundVerified}
${metric(t.target,`${x.target} ${t.units.unit}`)}${metric(t.funds,x.funds)}

${t.report} · ${x.report}

`).join(''); document.querySelectorAll('[data-contact]').forEach(b=>b.onclick=openGate); renderPagination(); } const LANGS=[['zh','简体中文'],['en','English'],['ja','日本語'],['ko','한국어'],['de','Deutsch'],['fr','Français'],['es','Español'],['pt','Português'],['ru','Русский'],['ar','العربية']]; const langMenu=document.getElementById('langMenu'),langName=document.getElementById('langName'); LANGS.forEach(([code,name])=>{const b=document.createElement('button');b.className='lang-item';b.style.cssText='display:flex;justify-content:space-between;width:100%;padding:9px 11px;border:0;border-radius:9px;background:transparent;color:rgba(255,255,255,.66);font:inherit;font-size:12px;cursor:pointer;text-align:left';b.textContent=name;b.onclick=()=>{setLang(code);langMenu.style.display='none'};b.dataset.code=code;langMenu.appendChild(b)}); document.getElementById('langBtn').onclick=e=>{e.stopPropagation();langMenu.style.display=langMenu.style.display==='block'?'none':'block'}; document.addEventListener('click',()=>langMenu.style.display='none'); document.getElementById('searchBtn').onclick=()=>{query=document.getElementById('q').value.trim().toLowerCase();page=1;loadV2Market()}; document.getElementById('q').addEventListener('keydown',e=>{if(e.key==='Enter'){query=e.target.value.trim().toLowerCase();page=1;loadV2Market()}}); const docOverlay=document.getElementById('docOverlay'),gateOverlay=document.getElementById('gateOverlay'); function docRow(label,status,quantity,note){const U=String(status).toUpperCase();const shown=U==='NOT_EXECUTED'?(lang==='zh'?'未执行':'NOT EXECUTED'):U==='PASS'?(lang==='zh'?'通过':'PASS'):U==='WARN'?(lang==='zh'?'警告':'WARN'):U==='RISK'?(lang==='zh'?'风险':'RISK'):status;const cls=U.includes('PASS')?'pass':U.includes('WARN')?'warn':U.includes('NOT')?'warn':'fail';return `${label}${shown}${quantity}${note||'—'}`} function reportText(kind){const t=T[lang]||T.en;return kind==='inspect'?t.inspect:t.report} function gateText(){const M={ zh:{title:'请先注册',cancel:'关闭',register:'立即注册'}, en:{title:'Register to contact',cancel:'Close',register:'Register Now'}, ja:{title:'先に登録',cancel:'閉じる',register:'登録する'}, ko:{title:'먼저 가입',cancel:'닫기',register:'가입하기'}, de:{title:'Bitte registrieren',cancel:'Schließen',register:'Jetzt registrieren'}, fr:{title:'Inscription requise',cancel:'Fermer',register:'S’inscrire'}, es:{title:'Regístrese primero',cancel:'Cerrar',register:'Registrarme'}, pt:{title:'Cadastre-se primeiro',cancel:'Fechar',register:'Cadastrar'}, ru:{title:'Сначала регистрация',cancel:'Закрыть',register:'Зарегистрироваться'}, ar:{title:'الرجاء التسجيل أولاً',cancel:'إغلاق',register:'التسجيل الآن'}}; return M[lang]||M.en} function openGate(){ const x=gateText();document.getElementById('gateTitle').textContent=x.title;document.getElementById('gateCancel').textContent=x.cancel;document.getElementById('gateRegister').textContent=x.register; const sess=localStorage.getItem('wanan_session'); if(!sess){gateOverlay.classList.add('open');return} fetch('/api/auth/me',{headers:{'x-session':sess}}).then(r=>r.ok?r.json():null).then(mx=>{ const me=mx&&mx.user; if(me&&me.kycStatus!=='approved'){ document.getElementById('gateTitle').textContent=lang==='zh'?'请先完成实名认证':'Complete identity verification first'; document.getElementById('gateRegister').textContent=lang==='zh'?'去实名认证':'Verify identity'; } gateOverlay.classList.add('open'); }).catch(()=>gateOverlay.classList.add('open')); } async function loadReport(no){ try{const r=await fetch('/api/v2/reports/'+encodeURIComponent(no),{cache:'no-store'});if(!r.ok)return null;return await r.json()}catch(e){return null} } async function openDoc(no){ const x=await loadReport(no);if(!x)return; const t=T[lang]||T.en; document.getElementById('docKind').textContent=reportText(x.kind); document.getElementById('docNo').textContent=x.no; const isIns=x.kind==='inspect'; const meta=isIns?[['grade',x.grade||'—'],['time',x.time],['inspector',x.inspector?`${x.inspector.n} · ${x.inspector.id}`:'—'],['reviewer',x.reviewer?`${x.reviewer.n} · ${x.reviewer.id}`:'—'],['method',lang==='zh'?'上门验收':'On-site Acceptance']]:[['fundtime',x.time],['amount',x.amount||'—'],['currency',x.currency||'—'],['authority',x.authority||'—']]; const L={ zh:{inspector:'验货人',reviewer:'复验人',grade:'验货等级',time:'验货时间',method:'核验方式',fundtime:'验资时间',amount:'金额门槛',currency:'币种',authority:'出具单位',summary:'摘要',items:'检测项',item:'检测项',result:'结果',quantity:'数量',note:'备注',config:'配置表',spec:'规格'}, en:{inspector:'Inspector',reviewer:'Reviewer',grade:'Grade',time:'Date',method:'Verification',fundtime:'Verification Date',amount:'Threshold',currency:'Currency',authority:'Issuing Authority',summary:'Summary',items:'Checks',item:'Check',result:'Result',quantity:'Quantity',note:'Notes',config:'Configuration',spec:'Spec'}, ja:{inspector:'Inspector',reviewer:'Reviewer',grade:'検収等級',time:'検収日',method:'検証方法',fundtime:'資金認証日',amount:'金額しきい値',currency:'通貨',authority:'発行機関',summary:'要旨',items:'検査項目',item:'項目',result:'結果',quantity:'数量',note:'備考',config:'仕様表',spec:'仕様'}, ko:{inspector:'Inspector',reviewer:'Reviewer',grade:'검수 등급',time:'검수일',method:'검증 방식',fundtime:'자금 인증일',amount:'금액 기준',currency:'통화',authority:'발급 기관',summary:'요약',items:'검사 항목',item:'항목',result:'결과',quantity:'수량',note:'비고',config:'사양표',spec:'사양'}, de:{inspector:'Inspector',reviewer:'Reviewer',grade:'Prüfgrad',time:'Prüfdatum',method:'Verfahren',fundtime:'Kapitalprüfung',amount:'Schwelle',currency:'Währung',authority:'Ausstellende Stelle',summary:'Zusammenfassung',items:'Prüfpunkte',item:'Punkt',result:'Ergebnis',quantity:'Menge',note:'Hinweis',config:'Konfiguration',spec:'Spec'}, fr:{inspector:'Inspector',reviewer:'Reviewer',grade:'Grade',time:'Date',method:'Méthode',fundtime:'Vérification des fonds',amount:'Seuil',currency:'Devise',authority:'Autorité émettrice',summary:'Résumé',items:'Contrôles',item:'Point',result:'Résultat',quantity:'Quantité',note:'Note',config:'Configuration',spec:'Spéc.'}, es:{inspector:'Inspector',reviewer:'Reviewer',grade:'Grado',time:'Fecha',method:'Método',fundtime:'Fecha de verificación',amount:'Umbral',currency:'Moneda',authority:'Autoridad emisora',summary:'Resumen',items:'Controles',item:'Punto',result:'Resultado',quantity:'Cantidad',note:'Nota',config:'Configuración',spec:'Espec.'}, pt:{inspector:'Inspector',reviewer:'Reviewer',grade:'Grau',time:'Data',method:'Método',fundtime:'Data de verificação',amount:'Limiar',currency:'Moeda',authority:'Autoridade emissora',summary:'Resumo',items:'Controles',item:'Ponto',result:'Resultado',quantity:'Quantidade',note:'Nota',config:'Configuração',spec:'Espec.'}, ru:{inspector:'Inspector',reviewer:'Reviewer',grade:'Грейд',time:'Дата',method:'Метод',fundtime:'Дата проверки',amount:'Порог',currency:'Валюта',authority:'Выдавший орган',summary:'Резюме',items:'Проверки',item:'Пункт',result:'Результат',quantity:'Кол-во',note:'Примечание',config:'Конфигурация',spec:'Спец.'}, ar:{inspector:'Inspector',reviewer:'Reviewer',grade:'التصنيف',time:'التاريخ',method:'طريقة التحقق',fundtime:'تاريخ توثيق الأموال',amount:'الحد الأدنى',currency:'العملة',authority:'الجهة المُصدِرة',summary:'الملخص',items:'بنود الفحص',item:'البند',result:'النتيجة',quantity:'الكمية',note:'ملاحظة',config:'جدول المواصفات',spec:'المواصفة'} };const labels=L[lang]||L.en; document.getElementById('docBody').innerHTML=`
${meta.map(([k,v])=>`
${labels[k]||k}${v}
`).join('')}
${labels.summary}

${x.summary}

${labels.items}
${x.items.map(i=>docRow(i[0],i[1],i[2],i[3])).join('')}
${labels.item}${labels.result}${labels.quantity}${labels.note}
${x.config?`
${labels.config}
${x.config.map(c=>``).join('')}
${labels.item}${labels.spec}${labels.result}
${c[0]}${c[1]}PASSED
`:''}
${isIns?`Exception policy: mismatch and non-new units are marked separately. Accepted currencies: ${(x.config||[]).filter(c=>c[0]==='Accepted currencies').map(c=>c[1])[0]||'USD / CNY'}. Full raw diagnostics remain available to qualified members after NDA.

交易、结算、物流、税务与发票安排由买卖双方自行协商,平台不参与交易资金与票据。`:`Fund evidence is matched to the verified real-name entity. Accepted settlement currencies: ${x.currency}. Counterparty details remain protected until direct contact is unlocked.`}
`; docOverlay.classList.add('open'); } function openDocByModel(){/* v2-only:报告一律按编号 openDoc(reportNo) 打开 */} document.getElementById('docClose').onclick=()=>docOverlay.classList.remove('open'); document.getElementById('gateClose').onclick=()=>gateOverlay.classList.remove('open'); document.getElementById('gateCancel').onclick=()=>gateOverlay.classList.remove('open'); document.addEventListener('click',e=>{ const ins=e.target.closest('[data-inspect]');if(ins)return ins.dataset.reportNo?openDoc(ins.dataset.reportNo):openDocByModel(ins.dataset.inspect,'inspect'); const rep=e.target.closest('[data-report-no]');if(rep&&rep.dataset.reportNo)return openDoc(rep.dataset.reportNo); }); try{if(!Array.isArray(SUPPLY)||!Array.isArray(BUYERS)||!Array.isArray(REPORTS))throw new Error('market data missing');setLang(lang);loadV2Market()}catch(e){document.getElementById('cards').innerHTML='
Data load error: '+e.message+'
'}