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