import{d as ds,g as m,o as fs,q as hs,a as i,c,b,e as l,x as vs,y as ps,t as v,z as A,A as ms,B as gs,F as B,r as j,C as St,n as pe,f as E,D as ys,G as kt,H as Ss,I as ks,w as ws,v as _s,J as bs,m as me,h as ge,E as p,i as wt,_ as Ts,K as Cs,j as Es,k as Is}from"./pywebview-B8lwamDf.js";import{z as Ds}from"./zh-cn-CqyuNHRW.js";import{B as $s,a1 as Ns,a2 as Ms,a3 as Ps,a4 as xs,a5 as As,a6 as Ls,a7 as Fs,a8 as Us,s as Rs,a9 as Os,aa as Bs,ab as Hs,ac as Vs,ad as Ue,ae as qs,v as zs}from"./java-modules-B9jblDzU.js";/* empty css */import{L as js}from"./listingFilters-BpGOU_pJ.js";import{c as Ks}from"./categorized-timers-JPA-olTr.js";const Gs={class:"page-shell module-page"},Js={class:"main-content"},Ys={class:"left-panel"},Qs={class:"input-zone"},Ws={class:"input-row"},Xs=["disabled"],Zs={key:0,class:"empty-candidates"},ea={key:1,class:"candidate-table-scroll"},ta=["onClick"],sa={class:"country-pref-checks"},aa=["checked","disabled","onChange"],na={class:"country-check-text"},oa={key:2,class:"country-order-panel"},la={class:"country-order-list"},ra=["onDragstart","onDrop"],ua={class:"country-drag-label"},ia={key:3,class:"country-pref-status"},ca={class:"listing-filter-row"},da={class:"schedule-switch"},fa=["disabled"],ha={key:4,class:"schedule-config"},va=["disabled","onClick"],pa=["disabled"],ma={class:"run-row"},ga=["disabled"],ya=["disabled"],Sa={key:5,class:"queue-debug-card"},ka={class:"queue-debug-line"},wa={key:0,class:"queue-debug-payload"},_a={class:"right-panel"},ba={class:"task-list-wrap"},Ta={class:"clean-result-summary"},Ca={class:"summary-card"},Ea={class:"summary-card"},Ia={class:"summary-card"},Da={class:"summary-card"},$a={key:0,class:"empty-tasks narrow"},Na=["onClick"],Ma={class:"result-list-wrap"},Pa={key:0,class:"empty-tasks"},xa={key:0,class:"result-subsection"},Aa={class:"task-list"},La={class:"left split-result-main"},Fa=["title"],Ua={class:"files"},Ra={key:0,class:"files"},Oa={key:1,class:"files"},Ba={key:2,class:"files"},Ha={key:3,class:"files"},Va={class:"task-right"},qa=["onClick"],za=["onClick"],ja={key:1,class:"result-subsection"},Ka={class:"task-list"},Ga={class:"left split-result-main"},Ja=["title"],Ya={class:"files"},Qa={key:0,class:"files"},Wa={key:1,class:"files"},Xa={class:"task-right"},Za=["onClick"],en=["onClick"],tn=ds({__name:"BrandShopMatchTab",setup(an){const ye=[{code:"DE",label:"德国"},{code:"UK",label:"英国"},{code:"FR",label:"法国"},{code:"IT",label:"意大利"},{code:"ES",label:"西班牙"}],ae=m(""),Se=m([]),Re=m([]),T=m([]),ke=m("Active"),ne=m(!1),oe=m(!1),P=m(!1),we=m(!1),_e=m(!1),S=m(""),K=m(""),g=m(["DE","UK","FR","IT","ES"]),G=m(null),be=m(!1),Te=m(!1);let H=null;const x=m(!0),k=m([$e()]),J=m({candidateCount:0,processedTaskCount:0,successTaskCount:0,failedTaskCount:0}),D=m([]),y=m([]),w=m({}),d=m({}),M=m(null),Ce=m(!1),N=new Map,Ee=m(!1);let Y=null,Oe=0,Be="",_=!1;const C=Ks("shop-match"),Ie=ge(()=>Je(D.value.filter(e=>!!I(e.taskId)&&!Xe(e)),d.value,"current")),De=ge(()=>Je(D.value.filter(e=>!I(e.taskId)||Xe(e)),d.value,"history")),_t=ge(()=>Ie.value.length>0||De.value.length>0),bt=ge(()=>{const e=new Set(g.value);return[...g.value.map(t=>({code:t,label:Ke(t)})),...ye.filter(t=>!e.has(t.code)).map(t=>({code:t.code,label:t.label}))]});function Q(){return typeof window<"u"&&window.localStorage.getItem("uid")||"0"}function Tt(){const e=Number(Q());return Number.isFinite(e)&&e>0?e:0}function I(e){const t=Number(e);return Number.isFinite(t)&&t>0?t:0}function He(){return`shop-match:tasks:${Q()}`}function Ve(){return`shop-match:task-status:${Q()}`}function qe(){return`shop-match:task-snapshots:${Q()}`}function ze(){return`shop-match:matched-items:${Q()}`}function le(e,t,s){s?window.localStorage.removeItem(e):window.localStorage.setItem(e,JSON.stringify(t))}function L(e){return`${(e.shopName||"").trim()}::${e.shopId||""}`}function je(e){return`${I(e.taskId)}-${e.resultId||0}-${e.shopName||""}`}function Ke(e){return ye.find(t=>t.code===e)?.label||e}function Ct(e){const t=e.getFullYear(),s=String(e.getMonth()+1).padStart(2,"0"),a=String(e.getDate()).padStart(2,"0"),n=String(e.getHours()).padStart(2,"0"),u=String(e.getMinutes()).padStart(2,"0"),r=String(e.getSeconds()).padStart(2,"0");return`${t}-${s}-${a}T${n}:${u}:${r}`}function re(e){const t=e.getFullYear(),s=String(e.getMonth()+1).padStart(2,"0"),a=String(e.getDate()).padStart(2,"0"),n=String(e.getHours()).padStart(2,"0"),u=String(e.getMinutes()).padStart(2,"0");return`${t}-${s}-${a} ${n}:${u}:00`}function $e(){const e=new Date;return e.setSeconds(0,0),e.setMinutes(e.getMinutes()+5),re(e)}function W(e){if(!e)return null;const s=e.trim().replace("T"," ").match(/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})(?::(\d{2}))?$/);if(!s)return null;const a=Number(s[1]),n=Number(s[2]),u=Number(s[3]),r=Number(s[4]),f=Number(s[5]),o=Number(s[6]||"0"),h=new Date(a,n-1,u,r,f,o,0);return Number.isNaN(h.getTime())||h.getFullYear()!==a||h.getMonth()!==n-1||h.getDate()!==u?null:h}function Et(e,t){const s=W(e)||new Date;return s.setSeconds(0,0),s.setMinutes(s.getMinutes()+t),re(s)}function Ge(e){const t=W(e);if(!t)return"-";const s=String(t.getMonth()+1).padStart(2,"0"),a=String(t.getDate()).padStart(2,"0"),n=String(t.getHours()).padStart(2,"0"),u=String(t.getMinutes()).padStart(2,"0");return`${s}-${a} ${n}:${u}`}function Je(e,t,s){const a=new Map;for(const n of e)a.set(je(n),n);for(const[n,u]of Object.entries(t)){const r=I(n),f=u.items?.[0];if(!f||!r)continue;const o=We(r);if(s==="current"&&o||s==="history"&&!o)continue;const h=je({...f,taskId:r});a.has(h)||a.set(h,{...f,taskId:r})}return Array.from(a.values())}function It(){try{const e=window.localStorage.getItem(He()),t=e?JSON.parse(e):[];y.value=Array.isArray(t)?t.filter(s=>typeof s=="number"&&s>0):[]}catch{y.value=[]}}function ue(){le(He(),y.value,y.value.length===0)}function Dt(){try{const e=window.localStorage.getItem(Ve());w.value=e?JSON.parse(e):{}}catch{w.value={}}}function F(){le(Ve(),w.value,Object.keys(w.value).length===0)}function $t(){try{const e=window.localStorage.getItem(qe());d.value=e?JSON.parse(e):{}}catch{d.value={}}}function V(){le(qe(),d.value,Object.keys(d.value).length===0)}function Nt(){try{const e=window.localStorage.getItem(ze());T.value=e?JSON.parse(e):[]}catch{T.value=[]}}function Ne(){le(ze(),T.value,T.value.length===0)}function Mt(e){const t=e instanceof Error?e.message:String(e||"");return/记录不存在|任务不存在|不存在|已删除|not\s*found|404/i.test(t)}function Pt(){const e=y.value.filter(t=>(w.value[t]||d.value[t]?.task?.status)==="RUNNING");e.length!==y.value.length&&(y.value=e,ue())}function Ye(e){y.value.includes(e)||(y.value=[...y.value,e],ue())}function ie(e){const t=N.get(e);t&&(C.clearTimer("scheduled-dispatch",t),N.delete(e),N.size||fe())}function ce(e){if(ie(e),y.value=y.value.filter(t=>t!==e),delete w.value[e],d.value[e]){const t={...d.value};delete t[e],d.value=t,V()}ue(),F()}function X(e){ce(e),D.value=D.value.filter(t=>I(t.taskId)!==e)}function Qe(e,t=!0){y.value=y.value.filter(s=>s!==e),t||delete w.value[e],ue(),F()}function Z(e){return e==="SUCCESS"||e==="FAILED"||e==="COMPLETED"}function We(e){if(!e)return!1;const t=w.value[e]||d.value[e]?.task?.status;return Z(t)}function Xe(e){const t=I(e.taskId);return t&&We(t)||Z(e.taskStatus)?!0:!!e.success}async function ee(){Se.value=await Ns()}async function U(){J.value=await Ms()}async function q(){const e=await Ps();D.value=e.items||[]}async function xt(){try{const e=await xs();if(Te.value)return;const t=(e.country_codes||[]).filter(s=>ye.some(a=>a.code===s));t.length&&(g.value=t)}catch{}}async function de(){await Promise.allSettled([q(),U()])}function Ze(){H&&C.clearTimer("preference-save",H),H=C.setTimeout("preference-save",()=>{H=null,At()},450)}async function At(){if(g.value.length){be.value=!0;try{await Vs(g.value)}catch(e){p.error(e instanceof Error?e.message:"保存国家配置失败")}finally{be.value=!1}}}function Lt(e){Re.value=e}async function et(){const e=ae.value.trim();if(!e){p.warning("请输入店铺名");return}ne.value=!0;try{await As(e),ae.value="",await ee(),await U()}catch(t){p.error(t instanceof Error?t.message:"添加失败")}finally{ne.value=!1}}async function Ft(e){try{await Ls(e.id),await ee(),await U()}catch(t){p.error(t instanceof Error?t.message:"删除失败")}}function Ut(e){return g.value.includes(e)}function tt(e){return g.value.length===1&&g.value[0]===e}function Rt(e,t){const s=t.target;if(s){if(!s.checked&&tt(e)){s.checked=!0,p.warning("至少保留 1 个国家");return}Ot(e,s.checked)}}function Ot(e,t){if(Te.value=!0,t)g.value.includes(e)||(g.value=[...g.value,e]);else{if(g.value.length<=1){p.warning("至少保留 1 个国家");return}g.value=g.value.filter(s=>s!==e)}Ze()}function Bt(e){G.value=e}function Ht(){G.value=null}function Vt(e){const t=G.value;if(G.value=null,t==null||t===e)return;Te.value=!0;const s=[...g.value],[a]=s.splice(t,1);s.splice(e,0,a),g.value=s,Ze()}function qt(){x.value&&(k.value=Me(k.value,!0)),x.value||(k.value=[])}function zt(){const e=k.value[k.value.length-1],t=e?Et(e,60):$e();k.value=[...k.value,t]}function jt(e){k.value.length<=1||(k.value=k.value.filter((t,s)=>s!==e))}function Kt(e,t){const s=[...k.value];s[e]=t||"",k.value=Me(s,!1)}function Gt(e,t){const s=new Map;for(const a of e)s.set(L(a),a);for(const a of t)s.set(L(a),a);return Array.from(s.values())}async function Jt(){const e=Re.value.map(t=>t.shop_name).filter(Boolean);if(!e.length){p.warning("请先选择候选店铺");return}oe.value=!0;try{const t=await Fs(e);T.value=Gt(T.value,t.items||[]),Ne(),_e.value&&mt(),p.success(`本次返回 ${t.items?.length||0} 条匹配结果`)}catch(t){p.error(t instanceof Error?t.message:"匹配失败")}finally{oe.value=!1}}function Yt(e){T.value=T.value.filter(t=>L(t)!==L(e)),Ne()}function R(e){const t=new Set(e.map(s=>L(s)));T.value=T.value.filter(s=>!t.has(L(s))),Ne()}function Qt(){if(!x.value)return;const e=Date.now(),t=k.value.map(n=>n.trim()).filter(Boolean);if(!t.length)throw new Error("请至少选择一个执行时间");const s=t.map(n=>{const u=W(n);if(!u)throw new Error(`时间格式无效: ${n}`);return{raw:Ct(u),picker:re(u),time:u.getTime()}}).sort((n,u)=>n.time-u.time);for(let n=1;nn.time>e);if(!a.length)throw new Error("执行时间必须晚于当前时间,请重新选择");return a.length!==s.length&&(k.value=a.map(n=>n.picker),p.warning("已自动移除早于当前时间的执行时间")),a.map(n=>n.raw)}function Me(e,t){const s=Date.now(),a=e.map(r=>r.trim()).filter(Boolean).map(r=>{const f=W(r);return f?{value:re(f),time:f.getTime()}:null}).filter(r=>!!r).filter(r=>r.time>s).sort((r,f)=>r.time-f.time),n=[],u=new Set;for(const r of a)u.has(r.value)||(u.add(r.value),n.push(r.value));return!n.length&&t?[$e()]:n}function Wt(e){return e.skipAsinsByCountry||e.skip_asins_by_country||{}}function Xt(e){return e.skipAsinDetailsByCountry||e.skip_asin_details_by_country||{}}function st(e,t,s,a,n=!0){const u=Wt(t),r=Xt(t);return{type:"shop-match-run",ts:Date.now(),data:{taskId:e,user_id:Tt(),items:[{shopName:t.shopName,shopId:t.shopId,platform:t.platform,companyName:t.companyName,matched:!0,matchStatus:t.matchStatus,matchMessage:t.matchMessage,skip_asins_by_country:u,skipAsinsByCountry:u,skip_asin_details_by_country:r,skipAsinDetailsByCountry:r}],country_codes:[...s],skip_asins_by_country:u,skipAsinsByCountry:u,skip_asin_details_by_country:r,skipAsinDetailsByCountry:r,risk_listing_filter:ke.value,stage_index:a,final_stage:n}}}function Pe(e){const t=d.value[e]?.task,s=t?.scheduleStages||[],a=t?.currentStageIndex;if(typeof a!="number")return null;const n=s.find(u=>u.stageIndex===a);return n?.scheduledAt?{stageIndex:a,scheduledAt:n.scheduledAt,finalStage:a===s.length-1}:null}async function Zt(e,t){const s=wt();if(!s?.enqueue_json)throw new Error("当前客户端未提供 enqueue_json");const a=Pe(e),n=d.value[e],u=n?.task?.countryCodes||g.value;if(!a)throw new Error(`任务 ${e} 缺少待执行阶段`);ie(e),await ot(()=>qs(e,a.stageIndex),(o,h)=>{S.value=`任务 ${e} 等待后端恢复后再激活执行(${o}/${h})...`}),w.value={...w.value,[e]:"RUNNING"},n?.task&&(d.value={...d.value,[e]:{...n,task:{...n.task,status:"RUNNING",activeStageIndex:a.stageIndex}}}),V(),F();const r=st(e,t,u,a.stageIndex,a.finalStage);K.value=JSON.stringify(r,null,2);const f=await s.enqueue_json(r);if(!f?.success)throw new Error(f?.error||`任务 ${e} 推送失败`);Ye(e),S.value=`任务 ${e} 已推送第 ${a.stageIndex+1} 轮`,se(!0)}function at(e){const t=W(e);return t?t.getTime():Number.NaN}function es(){const e=new Set(y.value);for(const s of Object.keys(d.value)){const a=I(s);a>0&&e.add(a)}for(const s of D.value){const a=I(s.taskId);a>0&&e.add(a)}const t=Array.from(e).map(s=>{const a=d.value[s],n=w.value[s]||a?.task?.status,u=a?.items?.[0]||D.value.find(o=>I(o.taskId)===s),r=Pe(s);if(n!=="SCHEDULED"||!u||!r?.scheduledAt)return null;const f=at(r.scheduledAt);return!Number.isFinite(f)||f>Date.now()?null:{taskId:s,item:u,scheduledTime:f}}).filter(s=>!!s);return t.sort((s,a)=>s.scheduledTime-a.scheduledTime||s.taskId-a.taskId),t}async function xe(){if(Ee.value)return;const e=es();if(e.length){Ee.value=!0;try{const t=e[0];try{await Zt(t.taskId,t.item),await ls(t.taskId)}catch(s){const a=s instanceof Error?s.message:`任务 ${t.taskId} 调度失败`,n=`${t.taskId}:${a}`,u=Date.now();S.value=a,(Be!==n||u-Oe>1e4)&&(Be=n,Oe=u,p.error(a)),await Promise.allSettled([q(),lt()])}}finally{Ee.value=!1,$()}}}function ts(e,t){if(_||!t)return;ie(e);const s=at(t);if(!Number.isFinite(s))return;const a=Math.max(0,s-Date.now()),n=C.setTimeout("scheduled-dispatch",()=>{N.delete(e),N.size||fe(),_||xe()},a);N.set(e,n),nt()}function $(){if(_)return;const e=new Set(y.value);for(const t of Object.keys(d.value)){const s=I(t);s>0&&e.add(s)}for(const t of D.value){const s=I(t.taskId);s>0&&e.add(s)}for(const t of e){const a=d.value[t]?.task?.status||w.value[t],n=Pe(t);a==="SCHEDULED"&&n?.scheduledAt?ts(t,n.scheduledAt):ie(t)}N.size?nt():fe(),xe()}function nt(){_||Y||!N.size||(Y=C.setInterval("schedule-heartbeat",()=>{_||xe()},3e4))}function fe(){Y&&(C.clearTimer("schedule-heartbeat",Y),Y=null)}function he(){$(),y.value.length&&se(!0)}const ss=["无法连接到后端服务","bad gateway","gateway timeout","network error","timeout","502","503","504"];function te(e){return _?Promise.resolve():C.sleep("queue-wait",e)}function as(){C.clearCategory("queue-wait")}function Ae(e){const t=(e instanceof Error?e.message:String(e||"")).toLowerCase();return ss.some(s=>t.includes(s.toLowerCase()))}async function ot(e,t,s=10){let a=0;for(;;){if(_)throw new Error("component disposed");try{return await e()}catch(n){if(a+=1,!Ae(n)||a>=s)throw n;t(a,s),await te(O())}}}async function lt(){if(!y.value.length)return{settledTaskIds:[]};try{const e=await Ue(y.value),t={...d.value},s=new Set;for(const a of e.missingTaskIds||[])X(a),delete t[a],s.add(a);for(const a of e.items||[]){const n=a.task?.id;if(!n)continue;const u=t[n];t[n]=u?{...u,task:{...u.task||{},...a.task||{}}}:a;const r=a.task?.status||"";if(r){if(w.value[n]=r,Z(r)){ce(n),s.add(n);continue}r==="SCHEDULED"&&(Qe(n),s.add(n))}}return d.value=t,V(),F(),$(),{settledTaskIds:Array.from(s)}}catch{return{settledTaskIds:[]}}}function O(){return zs()}function rt(e=!1){if(_)return;if(M.value){if(!e)return;C.clearTimer("task-poll",M.value),M.value=null}const t=async()=>{if(M.value=null,!_){if(Ce.value||!y.value.length){y.value.length&&rt();return}Ce.value=!0;try{const{settledTaskIds:s}=await lt();s.length&&await Promise.allSettled([q(),U()])}finally{Ce.value=!1}!_&&y.value.length&&(M.value=C.setTimeout("task-poll",t,O()))}};e?t():M.value=C.setTimeout("task-poll",t,O())}function se(e=!1){rt(e)}function ns(){M.value&&(C.clearTimer("task-poll",M.value),M.value=null)}async function os(e){let t=0;const s=30;for(;;){if(_)return"STOPPED";try{const a=await Ue([e]);if(t>0&&(S.value=`任务 ${e} 后端已恢复,继续等待执行结果...`),t=0,(a.missingTaskIds||[]).includes(e))return X(e),await de(),$(),"FAILED";const n=(a.items||[]).find(r=>r.task?.id===e),u=n?.task?.status||"";if(n){const r=d.value[e];d.value={...d.value,[e]:r?{...r,task:{...r.task||{},...n.task||{}}}:n},V()}if(u&&(w.value[e]=u,F()),Z(u))return ce(e),await de(),$(),u}catch(a){if(!Ae(a))throw a;if(t+=1,t>=s)throw new Error(`任务 ${e} 等待后端恢复超时,请稍后手动刷新查看状态`);S.value=`任务 ${e} 运行中,正在等待后端服务恢复(${t}/${s})...`,(t===1||t%5===0)&&p.warning(`任务 ${e} 运行中,后端服务暂时不可用,正在自动重试`),await te(O());continue}await te(O())}}async function ls(e){let t=0;const s=30;for(;;){if(_)return"STOPPED";try{const a=await Ue([e]);if(t>0&&(S.value=`任务 ${e} 后端已恢复,继续等待当前轮次结束...`),t=0,(a.missingTaskIds||[]).includes(e))return X(e),await de(),$(),"FAILED";const n=(a.items||[]).find(r=>r.task?.id===e),u=n?.task?.status||"";if(n){const r=d.value[e];d.value={...d.value,[e]:r?{...r,task:{...r.task||{},...n.task||{}}}:n},V()}if(u&&(w.value[e]=u,F()),!u||u==="RUNNING"){await te(O());continue}return Z(u)?(ce(e),await de(),$(),u):(u==="SCHEDULED"&&(Qe(e),$()),u)}catch(a){if(!Ae(a))throw a;if(t+=1,t>=s)throw new Error(`任务 ${e} 等待当前轮次结束超时,请稍后手动刷新查看状态`);S.value=`任务 ${e} 运行中,正在等待当前轮次结束(${t}/${s})...`,(t===1||t%5===0)&&p.warning(`任务 ${e} 运行中,后端服务暂时不可用,正在自动重试`),await te(O())}}}function Le(e){const t=I(e.taskId);return t?w.value[t]||d.value[t]?.task?.status||e.taskStatus||"":e.taskStatus||""}function ut(e){const t=I(e.taskId);return t?d.value[t]:void 0}function it(e){const s=ut(e)?.task,a=s?.scheduleStages||[];if(!a.length)return"";const n=a.length,u=typeof s?.activeStageIndex=="number"?s.activeStageIndex:void 0,r=typeof s?.currentStageIndex=="number"?s.currentStageIndex:void 0;return typeof u=="number"?`执行进度: 第 ${u+1}/${n} 次执行中`:typeof r=="number"?`执行进度: 等待第 ${r+1}/${n} 次`:`执行进度: 共 ${n} 次`}function ct(e){const s=ut(e)?.task,a=s?.scheduleStages||[];if(typeof s?.currentStageIndex=="number"){const n=a.find(u=>u.stageIndex===s.currentStageIndex);if(n?.scheduledAt)return Ge(n.scheduledAt)}return e.scheduledAt?Ge(e.scheduledAt):""}function dt(e){const t=Le(e);return t==="SCHEDULED"?"待执行":t==="RUNNING"?"执行中":t==="SUCCESS"||t==="COMPLETED"?"已完成":t==="FAILED"?"失败":e.success?"已完成":"未知"}function ft(e){const t=Le(e);return t==="SUCCESS"||t==="COMPLETED"?"success":t==="FAILED"?"failed":"running"}function ht(e){const t=Le(e);return!!e.resultId&&(!!e.fileReady||!!e.downloadUrl)&&(t==="SUCCESS"||t==="COMPLETED")}async function vt(e){if(!e.resultId)return;const t=Us(e.resultId),s=e.outputFilename||`${e.shopName||"result"}.xlsx`,a=await Rs(t,s,`shop-match:${e.resultId}`);a.success?p.success(`已保存: ${a.path||s}`):a.error&&a.error!=="用户取消"&&p.error(a.error)}async function pt(e){const t=I(e.taskId),s=Number(e.resultId||0);try{if(t>0)await Os(t),X(t);else if(s>0)await Bs(s),D.value=D.value.filter(a=>Number(a.resultId||0)!==s),R([e]);else throw new Error("缺少可删除的任务标识");await Promise.allSettled([q(),ee(),U()]),p.success("删除成功")}catch(a){if(Mt(a)){t>0?X(t):s>0&&(D.value=D.value.filter(n=>Number(n.resultId||0)!==s)),R([e]),await Promise.allSettled([q(),ee(),U()]),p.success("后端记录已不存在,本地记录已同步清理");return}p.error(a instanceof Error?a.message:"删除失败")}}function rs(e){const t=(e||"").trim();return{MATCHED:"已匹配",PENDING:"待匹配",CONFLICT:"需人工确认",INDEX_STALE:"索引过期"}[t]||t||"—"}function us(e){const t=(e.matchMessage||"").trim();return t||(e.matched&&e.matchStatus==="MATCHED"?"紫鸟索引已命中,可推送队列":e.matched?"已关联索引,请结合状态列查看是否可推送":"未命中或未就绪,请检查店铺名与索引刷新")}async function is(){_e.value=!0,await mt()}function cs(){return T.value.find(e=>e.matched)}async function mt(){if(_||we.value)return;const e=wt();if(!e?.enqueue_json){p.error("当前客户端未提供 enqueue_json");return}if(!T.value.filter(r=>r.matched).length){p.warning("请先匹配可用店铺");return}if(!g.value.length){p.warning("请至少勾选一个国家");return}let s;try{s=Qt()}catch(r){p.error(r instanceof Error?r.message:"定时配置无效");return}we.value=!0,P.value=!0,K.value="";let a=0,n=0,u=0;try{for(;!_&&_e.value;){const r=cs();if(!r)break;u+=1;try{const f=await ot(()=>Hs([r],g.value,s),(Fe,ve)=>{S.value=`后端服务暂时不可用,正在重试创建任务(${Fe}/${ve})...`}),o=f.taskId,h=s?.length?"SCHEDULED":"RUNNING",z={task:{id:o,status:h,scheduledAt:s?.[0],countryCodes:[...g.value],currentStageIndex:s?.length?0:void 0,activeStageIndex:void 0,scheduleStages:(s||[]).map((Fe,ve)=>({stageIndex:ve,scheduledAt:Fe,status:ve===0?"SCHEDULED":"PENDING"}))},items:f.items};if(d.value={...d.value,[o]:z},w.value={...w.value,[o]:h},V(),F(),!f.items?.[0]){R([r]);continue}if(s?.length){a+=1,$(),S.value=`任务 ${o} 已创建,共 ${s.length} 个执行时间点`,R([r]);continue}const gt=st(o,r,g.value);K.value=JSON.stringify(gt,null,2);const yt=await e.enqueue_json(gt);if(!yt?.success){n+=1,S.value=`任务 ${o} 推送失败,已自动继续下一条:${yt?.error||"未知错误"}`,p.error(S.value),R([r]);continue}if(Ye(o),se(!0),R([r]),S.value=`任务 ${o} 已入队,等待执行完成`,await os(o)!=="SUCCESS"){n+=1,S.value=`任务 ${o} 执行失败,已自动继续下一条`,p.error(S.value);continue}a+=1,S.value=`任务 ${o} 已完成`}catch(f){if(_)break;n+=1,S.value=`第 ${u} 条任务处理失败,已自动继续下一条:${f instanceof Error?f.message:"未知错误"}`,p.error(S.value),R([r]);continue}}$(),s?.length||se(!0),!_&&(a>0||n>0)&&p.success(s?.length?`定时任务已创建:成功 ${a} 条,失败 ${n} 条`:`店铺推送已完成:成功 ${a} 条,失败 ${n} 条`)}catch(r){if(_)return;const f=r instanceof Error?r.message:"推送失败";S.value=f,p.error(f)}finally{we.value=!1,P.value=!1}}return fs(async()=>{It(),Dt(),$t(),Nt(),k.value=Me(k.value,x.value),Pt(),await Promise.allSettled([ee(),xt(),q(),U()]),window.addEventListener("focus",he),document.addEventListener("visibilitychange",he),$(),y.value.length&&se(!0)}),hs(()=>{_=!0,ns(),fe(),as(),window.removeEventListener("focus",he),document.removeEventListener("visibilitychange",he),H&&C.clearTimer("preference-save",H);for(const e of N.values())C.clearTimer("scheduled-dispatch",e);N.clear(),C.clearScope()}),(e,t)=>{const s=ps,a=ms,n=gs,u=Ss,r=ks,f=bs;return i(),c("div",Gs,[b($s,{active:"shop-match"}),l("div",Js,[l("aside",Ys,[t[10]||(t[10]=l("div",{class:"section-title"},"店铺候选",-1)),l("div",Qs,[t[4]||(t[4]=l("div",{class:"hint"},"输入店铺名后点“添加”加入下方备选区。勾选备选店铺后先做“匹配店铺”,确认命中紫鸟索引后再推送到 Python 队列。",-1)),l("div",Ws,[b(s,{modelValue:ae.value,"onUpdate:modelValue":t[0]||(t[0]=o=>ae.value=o),clearable:"",placeholder:"请输入店铺名后回车或点击添加",onKeyup:vs(et,["enter"])},null,8,["modelValue"]),l("button",{type:"button",class:"opt-btn",disabled:ne.value,onClick:et},v(ne.value?"添加中...":"添加"),9,Xs)])]),t[11]||(t[11]=l("div",{class:"section-title"},"备选店铺",-1)),Se.value.length?(i(),c("div",ea,[b(n,{data:Se.value,"row-key":"id",height:"240",class:"candidate-table",onSelectionChange:Lt},{default:A(()=>[b(a,{type:"selection",width:"42"}),b(a,{prop:"shop_name",label:"店铺名","min-width":"120","show-overflow-tooltip":""}),b(a,{label:"操作",width:"72",align:"center"},{default:A(({row:o})=>[l("button",{type:"button",class:"link-danger",onClick:h=>Ft(o)},"删除",8,ta)]),_:1})]),_:1},8,["data"])])):(i(),c("div",Zs,"暂无备选店铺,请先输入并添加")),t[12]||(t[12]=l("div",{class:"section-title"},"国家配置",-1)),t[13]||(t[13]=l("p",{class:"hint country-pref-hint"},"勾选的国家会在每一个执行时间点都执行一遍。勾选区会按照已选顺序排在前面,下方支持拖拽排序,和商品风险页保持一致。",-1)),l("div",sa,[(i(!0),c(B,null,j(bt.value,o=>(i(),c("label",{key:o.code,class:"country-check-row"},[l("input",{type:"checkbox",class:"country-check-input",checked:Ut(o.code),disabled:tt(o.code),onChange:h=>Rt(o.code,h)},null,40,aa),l("span",na,v(o.label)+" ("+v(o.code)+")",1)]))),128))]),g.value.length?(i(),c("div",oa,[t[6]||(t[6]=l("div",{class:"country-order-caption"},"已选顺序(拖拽 ⋮⋮ 调整)",-1)),l("div",la,[(i(!0),c(B,null,j(g.value,(o,h)=>(i(),c("div",{key:o,class:pe(["country-drag-row",{dragging:G.value===h}]),draggable:"true",onDragstart:z=>Bt(h),onDragend:Ht,onDragover:t[1]||(t[1]=St(()=>{},["prevent"])),onDrop:St(z=>Vt(h),["prevent"])},[t[5]||(t[5]=l("span",{class:"drag-handle",title:"拖动排序"},"⋮⋮",-1)),l("span",ua,v(Ke(o))+" ("+v(o)+")",1)],42,ra))),128))])])):E("",!0),be.value?(i(),c("div",ia,"保存中...")):E("",!0),t[14]||(t[14]=l("div",{class:"section-title"},"商品列表筛选",-1)),t[15]||(t[15]=l("p",{class:"hint listing-filter-hint"},"与“推送到 Python 队列”一并下发,供 Python 区分处理场景。",-1)),l("div",ca,[b(r,{modelValue:ke.value,"onUpdate:modelValue":t[2]||(t[2]=o=>ke.value=o),class:"listing-filter-select",teleported:"",placeholder:"选择筛选类型"},{default:A(()=>[(i(!0),c(B,null,j(ys(js),o=>(i(),kt(u,{key:o.value,label:o.label,value:o.value},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),t[16]||(t[16]=l("div",{class:"section-title"},"定时执行",-1)),l("label",da,[ws(l("input",{"onUpdate:modelValue":t[3]||(t[3]=o=>x.value=o),type:"checkbox",disabled:P.value,onChange:qt},null,40,fa),[[_s,x.value]]),t[7]||(t[7]=l("span",null,"启用多时间点调度",-1))]),x.value?(i(),c("div",ha,[(i(!0),c(B,null,j(k.value,(o,h)=>(i(),c("div",{key:`schedule-${h}`,class:"schedule-row"},[b(f,{"model-value":o,type:"datetime","value-format":"YYYY-MM-DD HH:mm:ss",format:"MM-DD HH:mm",placeholder:"选择执行时间",disabled:P.value,class:"schedule-picker","onUpdate:modelValue":z=>Kt(h,z)},null,8,["model-value","disabled","onUpdate:modelValue"]),l("button",{type:"button",class:"schedule-remove",disabled:P.value||k.value.length<=1,onClick:z=>jt(h)},"删除",8,va)]))),128)),l("button",{type:"button",class:"schedule-add",disabled:P.value,onClick:zt},"添加时间点",8,pa),t[8]||(t[8]=l("p",{class:"hint schedule-hint"},"默认开启定时;支持按 `MM-DD HH:mm` 配置多个时间点,前端不再限制选择更早时间,实际是否可执行以后端校验为准。",-1))])):E("",!0),l("div",ma,[l("button",{type:"button",class:"btn-run",disabled:oe.value,onClick:Jt},v(oe.value?"匹配中...":"匹配店铺"),9,ga),l("button",{type:"button",class:"btn-run btn-queue",disabled:P.value||!T.value.length,onClick:is},v(P.value?"推送中...":x.value?"创建定时任务":"推送到 Python 队列"),9,ya)]),t[17]||(t[17]=l("p",{class:"loading-msg"},[me("已支持多阶段定时执行;Python 每处理完一店可回传 "),l("code",null,"/api/shop-match/tasks/{taskId}/result"),me(",后端会按阶段汇总并在超时场景自动收尾。")],-1)),S.value?(i(),c("div",Sa,[t[9]||(t[9]=l("div",{class:"section-title queue-debug-title"},"推送结果",-1)),l("div",ka,v(S.value),1),K.value?(i(),c("pre",wa,v(K.value),1)):E("",!0)])):E("",!0)]),l("section",_a,[t[26]||(t[26]=l("div",{class:"panel-header"},"匹配与任务",-1)),l("div",ba,[l("div",Ta,[l("div",Ca,[t[18]||(t[18]=l("span",{class:"summary-label"},"候选店铺",-1)),l("strong",null,v(J.value.candidateCount),1)]),l("div",Ea,[t[19]||(t[19]=l("span",{class:"summary-label"},"已结束任务",-1)),l("strong",null,v(J.value.processedTaskCount),1)]),l("div",Ia,[t[20]||(t[20]=l("span",{class:"summary-label"},"成功",-1)),l("strong",null,v(J.value.successTaskCount),1)]),l("div",Da,[t[21]||(t[21]=l("span",{class:"summary-label"},"失败",-1)),l("strong",null,v(J.value.failedTaskCount),1)])]),t[25]||(t[25]=l("div",{class:"subsection-title"},"匹配结果",-1)),T.value.length?(i(),kt(n,{key:1,data:T.value,"row-key":L,"highlight-current-row":!1,class:"result-table match-table"},{default:A(()=>[b(a,{prop:"shopName",label:"店铺名","min-width":"100"}),b(a,{label:"匹配",width:"72",align:"center"},{default:A(({row:o})=>[l("span",{class:pe(o.matched?"ok":"fail")},v(o.matched?"是":"否"),3)]),_:1}),b(a,{prop:"shopId",label:"店铺ID","min-width":"120","show-overflow-tooltip":""}),b(a,{prop:"platform",label:"平台",width:"88","show-overflow-tooltip":""}),b(a,{prop:"companyName",label:"公司","min-width":"100","show-overflow-tooltip":""}),b(a,{label:"状态",width:"100","show-overflow-tooltip":""},{default:A(({row:o})=>[me(v(rs(o.matchStatus)),1)]),_:1}),b(a,{label:"说明","min-width":"140","show-overflow-tooltip":""},{default:A(({row:o})=>[me(v(us(o)),1)]),_:1}),b(a,{label:"操作",width:"72",align:"center"},{default:A(({row:o})=>[l("button",{type:"button",class:"link-danger",onClick:h=>Yt(o)},"删除",8,Na)]),_:1})]),_:1},8,["data"])):(i(),c("div",$a,"完成“匹配店铺”后,在此展示紫鸟索引匹配结果,供核对后再推送队列。")),l("div",Ma,[t[24]||(t[24]=l("div",{class:"result-list-header"},[l("span",null,"处理记录")],-1)),_t.value?(i(),c(B,{key:1},[Ie.value.length?(i(),c("div",xa,[t[22]||(t[22]=l("div",{class:"result-subsection-title"},"当前任务",-1)),l("ul",Aa,[(i(!0),c(B,null,j(Ie.value,o=>(i(),c("li",{key:`cur-${o.resultId}-${o.taskId}`,class:"task-item"},[l("div",La,[l("span",{class:"id",title:o.shopName||""},v(o.shopName||"-"),9,Fa),l("div",Ua,"任务 ID: "+v(o.taskId??"-"),1),o.platform?(i(),c("div",Ra,"平台: "+v(o.platform),1)):E("",!0),it(o)?(i(),c("div",Oa,v(it(o)),1)):E("",!0),ct(o)?(i(),c("div",Ba,"下一次: "+v(ct(o)),1)):E("",!0),o.error?(i(),c("div",Ha,"错误: "+v(o.error),1)):E("",!0)]),l("div",Va,[l("span",{class:pe(["status",ft(o)])},v(dt(o)),3),ht(o)?(i(),c("button",{key:0,type:"button",class:"download",onClick:h=>vt(o)},"下载",8,qa)):E("",!0),l("button",{type:"button",class:"btn-delete",onClick:h=>pt(o)},"删除",8,za)])]))),128))])])):E("",!0),De.value.length?(i(),c("div",ja,[t[23]||(t[23]=l("div",{class:"result-subsection-title"},"历史任务",-1)),l("ul",Ka,[(i(!0),c(B,null,j(De.value,o=>(i(),c("li",{key:`his-${o.resultId}-${o.taskId}`,class:"task-item"},[l("div",Ga,[l("span",{class:"id",title:o.shopName||""},v(o.shopName||"-"),9,Ja),l("div",Ya,"任务 ID: "+v(o.taskId??"-"),1),o.outputFilename?(i(),c("div",Qa,"文件: "+v(o.outputFilename),1)):E("",!0),o.error?(i(),c("div",Wa,"错误: "+v(o.error),1)):E("",!0)]),l("div",Xa,[l("span",{class:pe(["status",ft(o)])},v(dt(o)),3),ht(o)?(i(),c("button",{key:0,type:"button",class:"download",onClick:h=>vt(o)},"下载",8,Za)):E("",!0),l("button",{type:"button",class:"btn-delete",onClick:h=>pt(o)},"删除",8,en)])]))),128))])])):E("",!0)],64)):(i(),c("div",Pa,"暂无处理记录。推送队列并等待 Python 回传后,将在此显示下载链接。"))])])])])])}}}),sn=Ts(tn,[["__scopeId","data-v-9e4d7259"]]);Cs.locale("zh-cn");Es(sn).use(Is,{locale:Ds}).mount("#app");