import{d as Ye,o as Ze,L as es,a as u,c as i,b as v,B as ss,e as n,aj as ts,ak as as,t as r,a5 as b,a6 as ns,a7 as os,f as p,a4 as ls,n as ne,x as Se,F as oe,r as Ce,g as h,h as E,br as rs,bs as us,bt as is,E as d,bu as cs,bv as ds,bw as fs,i as Ae,bx as hs,by as vs,bz as ps,bA as ys,bB as ms,U as K,bC as gs,_ as _s,aS as ws,q as ks,s as Is}from"./pywebview-CcblbV5J.js";import{z as bs}from"./zh-cn-DCaAv7Wt.js";/* empty css *//* empty css */import{c as Ss}from"./categorized-timers-JPA-olTr.js";const Cs={class:"page-shell module-page"},As={class:"main-content"},Ts={class:"left-panel"},Ns={class:"input-zone"},$s={class:"input-row"},Es=["disabled"],Qs={key:0,class:"empty-candidates"},qs={key:1,class:"candidate-table-scroll"},Ds=["onClick"],Ms={class:"run-row"},Ps=["disabled"],Rs=["disabled"],Bs={key:2,class:"queue-debug-card"},Fs={class:"queue-debug-line"},Ls={key:0,class:"queue-debug-payload"},xs={class:"right-panel"},Us={class:"task-list-wrap"},Hs={class:"clean-result-summary"},Os={class:"summary-card"},zs={class:"summary-card"},Vs={class:"summary-card"},js={class:"summary-card"},Ks={key:0,class:"empty-tasks narrow"},Js=["onClick"],Ws={class:"result-list-wrap"},Xs={key:0,class:"empty-tasks"},Gs={key:0,class:"result-subsection"},Ys={class:"task-list"},Zs={class:"left split-result-main"},et=["title"],st={class:"files"},tt={key:0,class:"files"},at={key:1,class:"files"},nt={key:2,class:"files"},ot={class:"files"},lt={class:"files"},rt={key:3,class:"files"},ut={class:"task-right"},it=["onClick"],ct={key:1,class:"result-subsection"},dt={class:"task-list"},ft={class:"left split-result-main"},ht=["title"],vt={class:"files"},pt={key:0,class:"files"},yt={key:1,class:"files"},mt={key:2,class:"files"},gt={class:"files"},_t={key:3,class:"files"},wt={class:"files"},kt={key:4,class:"files"},It={class:"task-right"},bt=["onClick"],St=["onClick"],Te=30,Ct=Ye({__name:"BrandQueryAsinTab",setup(Tt){const R=h(""),J=h([]),B=h([]),m=h([]),w=h([]),Q=h({candidateCount:0,processedTaskCount:0,successTaskCount:0,failedTaskCount:0}),F=h(!1),L=h(!1),W=h(!1),y=h(""),X=h(""),f=h([]),c=h(null),S=h(null),C=h(!1),G=h(!1);let A=null;const T=Ss("query-asin"),le=E(()=>m.value.filter(e=>e.matched&&(e.queryAsins||[]).some(s=>s.asins?.length))),x=E(()=>w.value.filter(e=>!pe(e.taskStatus))),Y=E(()=>w.value.filter(e=>pe(e.taskStatus))),Z=E(()=>!!c.value||f.value.length>0),U=E(()=>C.value||Z.value),re=E(()=>C.value&&Z.value);function ee(){return typeof window<"u"&&window.localStorage.getItem("uid")||"0"}function ue(){return`query-asin:matched:${ee()}`}function ie(){return`query-asin:queue-state:${ee()}`}function I(e){return`${(e.shopName||"").trim()}::${e.shopId||""}`}function H(e){return`${e.taskId??0}:${e.resultId??0}`}let _=!1;function ce(e){return _?Promise.resolve():T.sleep("queue-wait",e)}function Ne(){T.clearCategory("queue-wait")}function de(e){const s=e instanceof Error?e.message.toLowerCase():String(e||"").toLowerCase();return s.includes("network error")||s.includes("failed to fetch")||s.includes("timeout")||s.includes("503")||s.includes("502")||s.includes("504")||s.includes("500")||s.includes("load failed")}async function $e(e,s,o=20){let a=0;for(;;){if(_)throw new Error("component disposed");try{return await e()}catch(l){if(!de(l)||a>=o-1)throw l;a+=1,s?.(a,o),await ce(K())}}}function fe(e,s){return`query-asin:${e}:${s||"shop"}:${Date.now()}`}function se(e){if(!e)return"-";const s=new Date(e);if(Number.isNaN(s.getTime()))return e;const o=s.getFullYear(),a=String(s.getMonth()+1).padStart(2,"0"),l=String(s.getDate()).padStart(2,"0"),t=String(s.getHours()).padStart(2,"0"),g=String(s.getMinutes()).padStart(2,"0"),ae=String(s.getSeconds()).padStart(2,"0");return`${o}-${a}-${l} ${t}:${g}:${ae}`}function Ee(e){const s=(e||"").trim();return{MATCHED:"已匹配",PENDING:"待匹配",CONFLICT:"需人工确认",INDEX_STALE:"索引过期"}[s]||s||"-"}function Qe(e){const s=(e.matchMessage||"").trim();return s||(e.matched&&e.matchStatus==="MATCHED"?"索引已命中,可推送到 Python 队列":e.matched?"已命中索引,请结合状态列确认":"未命中或未就绪,请检查店铺名")}function qe(e){const s=k(e),o=Math.max(...s.map(a=>a.asins?.length||0),1);return Array.from({length:o},(a,l)=>({shopName:l===0?e.shopName:"",countries:s.map(t=>({country:t.country,asin:t.asins?.[l]||""}))}))}function he(e){const s=k(e),o=s.reduce((l,t)=>l+(t.asins?.length||0),0);return`${s.filter(l=>l.asins?.length).map(l=>l.country).join("、")||"无国家"},共 ${o} 个 ASIN`}function O(e){return(e||[]).map(s=>({country:(s.country||"").trim().toUpperCase(),asins:Array.from(new Set((s.asins||[]).map(o=>(o||"").trim().toUpperCase()).filter(Boolean)))})).filter(s=>s.country&&s.asins.length)}function k(e){return O(e?.queryAsins?.length?e.queryAsins:e?.query_asins)}function z(e){return k(e).some(s=>s.asins.length)}function ve(e){const s=(e||"").trim(),o=[S.value,...f.value,...m.value],a=o.find(t=>(t?.shopName||"").trim()===s&&z(t)),l=o.find(t=>z(t));return k(a||l)}function N(e,s){const o=z(e)?k(e):k(s||void 0);return{...e,queryAsins:o.length?o:ve(e.shopName)}}function pe(e){return e==="SUCCESS"||e==="FAILED"||e==="COMPLETED"}function ye(e){return e==="SUCCESS"||e==="COMPLETED"?"已完成":e==="FAILED"?"失败":"执行中"}function me(e){return e==="SUCCESS"||e==="COMPLETED"?"success":e==="FAILED"?"failed":"running"}function De(e){return!!(e.resultId&&(e.fileReady||e.downloadUrl))}function ge(){typeof window>"u"||window.localStorage.setItem(ue(),JSON.stringify(m.value))}function Me(){try{const e=typeof window<"u"?window.localStorage.getItem(ue()):null;m.value=e?JSON.parse(e):[]}catch{m.value=[]}}function $(){if(typeof window>"u")return;const e={pendingQueue:f.value,activeTaskId:c.value,activeQueueItem:S.value};window.localStorage.setItem(ie(),JSON.stringify(e))}function Pe(){try{const e=typeof window<"u"?window.localStorage.getItem(ie()):null;if(!e)return;const s=JSON.parse(e);f.value=s.pendingQueue||[],c.value=s.activeTaskId??null,S.value=s.activeQueueItem??null}catch{f.value=[],c.value=null,S.value=null}}function q(){c.value=null,S.value=null,$()}function D(){Z.value||(C.value=!1,W.value=!1,G.value=!1,j(),$())}function Re(e){const s=e instanceof Error?e.message:String(e||"");return/记录不存在|任务不存在|不存在|已删除|not\s*found|404/i.test(s)}function Be(e){w.value=w.value.filter(s=>!(e.resultId!=null&&s.resultId===e.resultId||e.taskId!=null&&s.taskId===e.taskId))}function Fe(e,s){const o=new Map;for(const a of e)o.set(I(a),a);for(const a of s)o.set(I(a),a);return Array.from(o.values())}async function M(){J.value=await rs()}async function V(){Q.value=await us()}async function te(){const e=await is();w.value=(e.items||[]).map(s=>N(s))}async function P(){await Promise.all([V(),te()])}function _e(){if(!c.value){D();return}if(w.value.some(o=>o.taskId===c.value))return;const s=c.value;q(),y.value=f.value.length?`任务 ${s} 已不存在,已跳过并继续剩余队列`:"当前任务已不存在,已释放本地队列状态",D()}function Le(e){if(!e.length)return;const s=new Map(e.map(a=>[H(a),N(a)])),o=w.value.map(a=>{const l=s.get(H(a));if(!l)return N(a);const t=z(l)?k(l):k(a).length?k(a):ve(l.shopName||a.shopName);return{...a,...l,queryAsins:t}});for(const a of e){const l=H(a);o.some(t=>H(t)===l)||o.push(N(a))}w.value=o}async function we(e){const s=Array.from(new Set((e&&e.length?e:x.value.map(a=>a.taskId??0)).filter(a=>Number.isFinite(a)&&a>0)));if(!s.length)return;const o=await gs(s);Le(o.items||[]),(o.missingTaskIds||[]).length&&(await te(),_e())}function xe(){if(j(),_||!U.value)return;const e=async()=>{A=null,!(_||!U.value)&&(await we(),!_&&U.value&&(A=T.setTimeout("history-poll",e,K()*2)))};A=T.setTimeout("history-poll",e,K()*2)}function j(){A&&(T.clearTimer("history-poll",A),A=null)}function Ue(e){B.value=e}async function ke(){const e=R.value.trim();if(!e){d.warning("请输入店铺名");return}F.value=!0;try{await cs(e),R.value="",await Promise.all([M(),V()]),d.success("已加入备选区")}catch(s){d.error(s instanceof Error?s.message:"添加失败")}finally{F.value=!1}}async function He(e){try{await ds(e),B.value=B.value.filter(s=>s.id!==e),await Promise.all([M(),V()]),d.success("已删除")}catch(s){d.error(s instanceof Error?s.message:"删除失败")}}function Oe(e,s){const o=new Map;for(const a of e)o.set(I(a),a);for(const a of s)o.set(I(a),a);return Array.from(o.values())}async function ze(){const e=B.value.map(s=>s.shop_name).filter(Boolean);if(!e.length){d.warning("请先勾选备选区店铺");return}L.value=!0;try{const s=await fs(e);m.value=Oe(m.value,s.items||[]),ge(),d.success(`本次返回 ${s.items?.length||0} 条匹配结果`)}catch(s){d.error(s instanceof Error?s.message:"匹配失败")}finally{L.value=!1}}function Ve(e){if(U.value){d.warning("队列执行中,请等待当前串行任务结束后再调整");return}m.value=m.value.filter(s=>I(s)!==I(e)),ge()}function je(e){return{shopName:e.shopName,matched:e.matched,shopId:e.shopId,platform:e.platform,companyName:e.companyName,matchStatus:e.matchStatus,matchMessage:e.matchMessage,queryAsins:O(e.queryAsins)}}function Ke(e,s){const o=fe(e,s.shopName);return{type:"query-asin-run",ts:Date.now(),data:{taskId:e,user_id:Number(ee())||0,source:"frontend-vue-query-asin",submissionId:o,items:[{shopName:s.shopName,submissionId:o,shopId:s.shopId,platform:s.platform,companyName:s.companyName,matched:s.matched,matchStatus:s.matchStatus,matchMessage:s.matchMessage,queryAsins:O(s.queryAsins)}],query_asins:O(s.queryAsins),query_asin_rows:qe(s)}}}function Je(e){return w.value.find(s=>s.taskId===e)}async function We(e){let s=0;for(;;){if(_)return"STOPPED";try{if(await we([e]),c.value!==e)return"FAILED";s>0&&(y.value=`任务 ${e} 后端已恢复,继续等待执行结果...`),s=0;const a=Je(e)?.taskStatus||"";if(a==="SUCCESS"||a==="FAILED"||a==="COMPLETED")return a}catch(o){if(!de(o))throw o;if(s+=1,s>=Te)throw new Error(`任务 ${e} 等待后端恢复超时,请稍后刷新查看状态`);y.value=`任务 ${e} 执行中,正在等待后端服务恢复(${s}/${Te})...`}await ce(K())}}async function Ie(){if(!(_||C.value)){C.value=!0,W.value=!0,xe();try{const e=Ae();if(!e?.enqueue_json)throw new Error("当前客户端未提供 enqueue_json");for(;!_&&(c.value||f.value.length);){if(c.value){const g=await We(c.value);y.value=f.value.length>0?`任务 ${c.value} ${g==="SUCCESS"?"已完成":"执行失败"},自动继续下一个(剩余 ${f.value.length} 条)`:`任务 ${c.value} ${g==="SUCCESS"?"已完成":"执行失败"}`,q();continue}const s=f.value.shift();if($(),!s)break;const o=await $e(()=>hs([je(s)]),(g,ae)=>{y.value=`后端服务暂时不可用,正在重试创建任务(${g}/${ae})...`}),a=o.items?.[0]?N(o.items[0],s):void 0;if(!a?.taskId||!a.resultId)throw new Error("后端未返回有效任务标识");c.value=o.taskId,S.value=N(s,a),$(),await P();const l=Ke(o.taskId,a);X.value=JSON.stringify(l,null,2);const t=await e.enqueue_json(l);if(!t?.success){await vs(o.taskId,{shops:[{shopName:a.shopName||s.shopName||"",error:t?.error||`任务 ${o.taskId} 推送失败`,shopDone:!0,submissionId:fe(o.taskId,a.shopName||s.shopName)}]}),await P(),y.value=`任务 ${o.taskId} 推送失败,已自动继续下一个任务`,q();continue}y.value=f.value.length>0?`任务 ${o.taskId} 已入队,等待完成后自动继续下一个(剩余 ${f.value.length} 条)`:`任务 ${o.taskId} 已入队,等待执行完成`}y.value="串行队列已执行完成",await P(),d.success("查询ASIN队列已按顺序执行完成")}catch(e){if(_)return;const s=e instanceof Error?e.message:"队列执行失败";y.value=s,d.error(s),await P()}finally{C.value=!1,W.value=!1,j(),$()}}}async function Xe(){G.value=!0,D();const e=le.value;if(!e.length){d.warning("请先匹配可用店铺");return}f.value=Fe(f.value,e),$(),y.value=`已加入 ${e.length} 条店铺,开始串行执行`,await Ie()}async function Ge(e){if(!e.resultId)return;const s=Ae();if(!s?.save_file_from_url_new){d.error("当前客户端未提供下载能力");return}const o=ps(e.resultId),a=e.outputFilename||`${e.shopName||"result"}.xlsx`,l=await s.save_file_from_url_new(o,a);l.success?d.success(`已保存: ${l.path||a}`):l.error&&l.error!=="用户取消"&&d.error(l.error)}async function be(e){try{if(e.taskId)await ys(e.taskId),c.value===e.taskId&&q();else if(e.resultId)await ms(e.resultId);else throw new Error("缺少可删除的任务标识");await Promise.all([M(),P()]),D(),d.success("已删除")}catch(s){if(Re(s)){e.taskId&&c.value===e.taskId&&q(),Be(e),await M(),D(),d.success("后端记录已不存在,已同步移除本地记录");return}d.error(s instanceof Error?s.message:"删除失败")}}return Ze(async()=>{Me(),Pe(),await Promise.all([M(),V(),te()]),_e(),(c.value||f.value.length)&&(G.value=!0,y.value=c.value!=null?`检测到未完成队列,继续等待任务 ${c.value} 完成并自动接续后续店铺`:`检测到未完成队列,继续执行剩余 ${f.value.length} 条店铺`,Ie())}),es(()=>{_=!0,j(),Ne(),T.clearScope()}),(e,s)=>{const o=as,a=ns,l=os;return u(),i("div",Cs,[v(ss,{active:"query-asin"}),n("div",As,[n("aside",Ts,[s[3]||(s[3]=n("div",{class:"section-title"},"店铺输入",-1)),n("div",Ns,[s[1]||(s[1]=n("div",{class:"hint"}," 左侧负责录入店铺并加入备选区,确认命中后推送到 Python 队列。查询ASIN按店铺串行执行:上一个任务完成后会自动开始下一个,失败也会继续下一个。 ",-1)),n("div",$s,[v(o,{modelValue:R.value,"onUpdate:modelValue":s[0]||(s[0]=t=>R.value=t),clearable:"",placeholder:"请输入店铺名后回车或点击添加",onKeyup:ts(ke,["enter"])},null,8,["modelValue"]),n("button",{type:"button",class:"opt-btn",disabled:F.value,onClick:ke},r(F.value?"添加中...":"添加"),9,Es)])]),s[4]||(s[4]=n("div",{class:"section-title"},"备选区",-1)),J.value.length?(u(),i("div",qs,[v(l,{data:J.value,"row-key":"id",height:"260",class:"candidate-table",onSelectionChange:Ue},{default:b(()=>[v(a,{type:"selection",width:"42"}),v(a,{prop:"shop_name",label:"店铺名","min-width":"140","show-overflow-tooltip":""}),v(a,{label:"操作",width:"72",align:"center"},{default:b(({row:t})=>[n("button",{type:"button",class:"link-danger",onClick:g=>He(t.id)}," 删除 ",8,Ds)]),_:1})]),_:1},8,["data"])])):(u(),i("div",Qs," 暂无备选店铺,请先输入并添加 ")),n("div",Ms,[n("button",{type:"button",class:"btn-run",disabled:L.value,onClick:ze},r(L.value?"匹配中...":"匹配店铺"),9,Ps),n("button",{type:"button",class:"btn-run btn-queue",disabled:re.value||!le.value.length,onClick:Xe},r(re.value?"串行执行中...":"推送到 Python 队列"),9,Rs)]),s[5]||(s[5]=n("p",{class:"loading-msg"}," 当前页面会按店铺串行推送任务,并在任务成功或失败后自动接续下一个任务。服务端临时重启时会自动重试查询状态,恢复后继续后续店铺。 ",-1)),y.value?(u(),i("div",Bs,[s[2]||(s[2]=n("div",{class:"section-title queue-debug-title"},"队列状态",-1)),n("div",Fs,r(y.value),1),X.value?(u(),i("pre",Ls,r(X.value),1)):p("",!0)])):p("",!0)]),n("section",xs,[s[14]||(s[14]=n("div",{class:"panel-header"},"匹配与任务",-1)),n("div",Us,[n("div",Hs,[n("div",Os,[s[6]||(s[6]=n("span",{class:"summary-label"},"备选店铺",-1)),n("strong",null,r(Q.value.candidateCount),1)]),n("div",zs,[s[7]||(s[7]=n("span",{class:"summary-label"},"已处理任务",-1)),n("strong",null,r(Q.value.processedTaskCount),1)]),n("div",Vs,[s[8]||(s[8]=n("span",{class:"summary-label"},"成功任务",-1)),n("strong",null,r(Q.value.successTaskCount),1)]),n("div",js,[s[9]||(s[9]=n("span",{class:"summary-label"},"失败任务",-1)),n("strong",null,r(Q.value.failedTaskCount),1)])]),s[13]||(s[13]=n("div",{class:"subsection-title"},"匹配结果",-1)),m.value.length?(u(),ls(l,{key:1,data:m.value,"row-key":I,"highlight-current-row":!1,class:"result-table match-table"},{default:b(()=>[v(a,{prop:"shopName",label:"店铺名","min-width":"120"}),v(a,{label:"匹配",width:"72",align:"center"},{default:b(({row:t})=>[n("span",{class:ne(t.matched?"ok":"fail")},r(t.matched?"是":"否"),3)]),_:1}),v(a,{prop:"shopId",label:"店铺 ID","min-width":"120","show-overflow-tooltip":""}),v(a,{prop:"platform",label:"平台",width:"88","show-overflow-tooltip":""}),v(a,{prop:"companyName",label:"公司","min-width":"120","show-overflow-tooltip":""}),v(a,{label:"状态",width:"110","show-overflow-tooltip":""},{default:b(({row:t})=>[Se(r(Ee(t.matchStatus)),1)]),_:1}),v(a,{label:"说明","min-width":"180","show-overflow-tooltip":""},{default:b(({row:t})=>[Se(r(Qe(t)),1)]),_:1}),v(a,{label:"操作",width:"72",align:"center"},{default:b(({row:t})=>[n("button",{type:"button",class:"link-danger",onClick:g=>Ve(t)}," 删除 ",8,Js)]),_:1})]),_:1},8,["data"])):(u(),i("div",Ks," 完成“匹配店铺”后,这里会展示匹配结果。 ")),n("div",Ws,[s[12]||(s[12]=n("div",{class:"result-list-header"},[n("span",null,"任务记录")],-1)),!x.value.length&&!Y.value.length?(u(),i("div",Xs," 暂无任务记录。推送到 Python 队列后,这里会展示当前任务和历史任务。 ")):(u(),i(oe,{key:1},[x.value.length?(u(),i("div",Gs,[s[10]||(s[10]=n("div",{class:"result-subsection-title"},"当前任务",-1)),n("ul",Ys,[(u(!0),i(oe,null,Ce(x.value,t=>(u(),i("li",{key:`${t.resultId}-${t.taskId}`,class:"task-item"},[n("div",Zs,[n("span",{class:"id",title:t.shopName||""},r(t.shopName||"-"),9,et),n("div",st,"任务 ID: "+r(t.taskId??"-"),1),t.resultId?(u(),i("div",tt," 结果 ID: "+r(t.resultId),1)):p("",!0),t.shopId?(u(),i("div",at," 店铺 ID: "+r(t.shopId),1)):p("",!0),t.platform?(u(),i("div",nt," 平台: "+r(t.platform),1)):p("",!0),n("div",ot," 创建时间: "+r(se(t.createdAt)),1),n("div",lt," ASIN结构: "+r(he(t)),1),t.error?(u(),i("div",rt," 错误: "+r(t.error),1)):p("",!0)]),n("div",ut,[n("span",{class:ne(["status",me(t.taskStatus)])},r(ye(t.taskStatus)),3),n("button",{type:"button",class:"btn-delete",onClick:g=>be(t)}," 删除 ",8,it)])]))),128))])])):p("",!0),Y.value.length?(u(),i("div",ct,[s[11]||(s[11]=n("div",{class:"result-subsection-title"},"历史任务",-1)),n("ul",dt,[(u(!0),i(oe,null,Ce(Y.value,t=>(u(),i("li",{key:`${t.resultId}-${t.taskId}`,class:"task-item"},[n("div",ft,[n("span",{class:"id",title:t.shopName||""},r(t.shopName||"-"),9,ht),n("div",vt,"任务 ID: "+r(t.taskId??"-"),1),t.resultId?(u(),i("div",pt," 结果 ID: "+r(t.resultId),1)):p("",!0),t.shopId?(u(),i("div",yt," 店铺 ID: "+r(t.shopId),1)):p("",!0),t.platform?(u(),i("div",mt," 平台: "+r(t.platform),1)):p("",!0),n("div",gt," 创建时间: "+r(se(t.createdAt)),1),t.finishedAt?(u(),i("div",_t," 完成时间: "+r(se(t.finishedAt)),1)):p("",!0),n("div",wt," ASIN结构: "+r(he(t)),1),t.error?(u(),i("div",kt," 错误: "+r(t.error),1)):p("",!0)]),n("div",It,[n("span",{class:ne(["status",me(t.taskStatus)])},r(ye(t.taskStatus)),3),De(t)?(u(),i("button",{key:0,type:"button",class:"archive",onClick:g=>Ge(t)}," 下载结果 ",8,bt)):p("",!0),n("button",{type:"button",class:"btn-delete",onClick:g=>be(t)}," 删除 ",8,St)])]))),128))])])):p("",!0)],64))])])])])])}}}),At=_s(Ct,[["__scopeId","data-v-40c478d6"]]);ws.locale("zh-cn");ks(At).use(Is,{locale:bs}).mount("#app");