import{d as xt,o as Kt,I as zt,a as u,c as i,b as p,B as Jt,e as n,R as jt,S as Yt,t as l,T as I,U as Wt,V as Xt,f as m,Y as Gt,n as G,u as mt,F as Z,r as yt,g as v,h as F,aP as Zt,aQ as te,aR as ee,E as c,aS as se,aT as ae,aU as ne,i as _t,aV as oe,aW as le,aX as re,aY as ue,aZ as ie,Q as tt,a_ as ce,_ as de,at as fe,p as he,q as ve}from"./pywebview-CeWJDVeG.js";import{z as pe}from"./zh-cn-DyKmB71i.js";/* empty css */const me={class:"page-shell module-page"},ye={class:"main-content"},_e={class:"left-panel"},we={class:"input-zone"},ge={class:"input-row"},ke=["disabled"],Ie={key:0,class:"empty-candidates"},Se={key:1,class:"candidate-table-scroll"},be=["onClick"],Ce={class:"run-row"},Te=["disabled"],$e=["disabled"],Ee={key:2,class:"queue-debug-card"},De={class:"queue-debug-line"},Ne={key:0,class:"queue-debug-payload"},Pe={class:"right-panel"},Me={class:"task-list-wrap"},Re={class:"clean-result-summary"},Ae={class:"summary-card"},Qe={class:"summary-card"},qe={class:"summary-card"},Le={class:"summary-card"},Be={key:0,class:"empty-tasks narrow"},Fe=["onClick"],Ue={class:"result-list-wrap"},Oe={key:0,class:"empty-tasks"},He={key:0,class:"result-subsection"},Ve={class:"task-list"},xe={class:"left split-result-main"},Ke=["title"],ze={class:"files"},Je={key:0,class:"files"},je={key:1,class:"files"},Ye={key:2,class:"files"},We={class:"files"},Xe={class:"files"},Ge={key:3,class:"files"},Ze={class:"task-right"},ts=["onClick"],es={key:1,class:"result-subsection"},ss={class:"task-list"},as={class:"left split-result-main"},ns=["title"],os={class:"files"},ls={key:0,class:"files"},rs={key:1,class:"files"},us={key:2,class:"files"},is={class:"files"},cs={key:3,class:"files"},ds={class:"files"},fs={key:4,class:"files"},hs={class:"task-right"},vs=["onClick"],ps=["onClick"],wt=30,ms=xt({__name:"BrandPatrolDeleteTab",setup(_s){const et=["德国","英国","法国","意大利","西班牙"],E=v(""),U=v([]),D=v([]),y=v([]),g=v([]),b=v({candidateCount:0,processedTaskCount:0,successTaskCount:0,failedTaskCount:0}),N=v(!1),P=v(!1),M=v(!1),_=v(""),O=v(""),f=v([]),h=v(null),C=v(null),R=v(!1),H=v(!1);let A=null;const V=F(()=>y.value.filter(t=>t.matched)),Q=F(()=>g.value.filter(t=>!ut(t.taskStatus))),x=F(()=>g.value.filter(t=>ut(t.taskStatus))),K=F(()=>R.value||!!h.value||f.value.length>0);function z(){return typeof window<"u"&&window.localStorage.getItem("uid")||"0"}function st(){return`patrol-delete:matched:${z()}`}function at(){return`patrol-delete:queue-state:${z()}`}function w(t){return`${(t.shopName||"").trim()}::${t.shopId||""}`}function q(t){return`${t.taskId??0}:${t.resultId??0}`}function nt(t){return new Promise(e=>window.setTimeout(e,t))}function ot(t){const e=t instanceof Error?t.message.toLowerCase():String(t||"").toLowerCase();return e.includes("network error")||e.includes("failed to fetch")||e.includes("timeout")||e.includes("503")||e.includes("502")||e.includes("504")||e.includes("500")||e.includes("load failed")}async function gt(t,e,o=20){let a=0;for(;;)try{return await t()}catch(r){if(!ot(r)||a>=o-1)throw r;a+=1,e?.(a,o),await nt(tt())}}function kt(t,e){return`patrol-delete:${t}:${e||"shop"}:${Date.now()}`}function J(t){if(!t)return"-";const e=new Date(t);if(Number.isNaN(e.getTime()))return t;const o=e.getFullYear(),a=String(e.getMonth()+1).padStart(2,"0"),r=String(e.getDate()).padStart(2,"0"),s=String(e.getHours()).padStart(2,"0"),d=String(e.getMinutes()).padStart(2,"0"),k=String(e.getSeconds()).padStart(2,"0");return`${o}-${a}-${r} ${s}:${d}:${k}`}function It(t){const e=(t||"").trim();return{MATCHED:"已匹配",PENDING:"待匹配",CONFLICT:"需人工确认",INDEX_STALE:"索引过期"}[e]||e||"-"}function St(t){const e=(t.matchMessage||"").trim();return e||(t.matched&&t.matchStatus==="MATCHED"?"索引已命中,可推送到 Python 队列":t.matched?"已命中索引,请结合状态列确认":"未命中或未就绪,请检查店铺名")}function bt(){return et.map(t=>({country:t,rows:[{status:"全部",quantity:"",deleteQuantity:"",processStatus:""}]}))}function Ct(){return et.map(t=>({country:t,ratio:""}))}function lt(t){const e=t.countrySections||[],o=t.cartRatios||[],a=Math.max(...e.map(r=>r.rows.length),1);return Array.from({length:a},(r,s)=>({shopName:s===0?t.shopName:"",countries:e.map(d=>{const k=d.rows[s];return{country:d.country,status:k?.status||"",quantity:k?.quantity||"",deleteQuantity:k?.deleteQuantity||"",processStatus:k?.processStatus||""}}),cartRatios:s===0?o.map(d=>({country:d.country,ratio:d.ratio})):[]}))}function rt(t){return`${lt(t).length} 行状态数据,首行含 ${t.cartRatios?.length||0} 个购物车比例列`}function ut(t){return t==="SUCCESS"||t==="FAILED"||t==="COMPLETED"}function it(t){return t==="SUCCESS"||t==="COMPLETED"?"已完成":t==="FAILED"?"失败":"执行中"}function ct(t){return t==="SUCCESS"||t==="COMPLETED"?"success":t==="FAILED"?"failed":"running"}function Tt(t){return!!(t.resultId&&(t.outputFilename||t.downloadUrl))}function j(){typeof window>"u"||window.localStorage.setItem(st(),JSON.stringify(y.value))}function $t(){try{const t=typeof window<"u"?window.localStorage.getItem(st()):null;y.value=t?JSON.parse(t):[]}catch{y.value=[]}}function S(){if(typeof window>"u")return;const t={pendingQueue:f.value,activeTaskId:h.value,activeQueueItem:C.value};window.localStorage.setItem(at(),JSON.stringify(t))}function Et(){try{const t=typeof window<"u"?window.localStorage.getItem(at()):null;if(!t)return;const e=JSON.parse(t);f.value=e.pendingQueue||[],h.value=e.activeTaskId??null,C.value=e.activeQueueItem??null}catch{f.value=[],h.value=null,C.value=null}}function L(){h.value=null,C.value=null,S()}function Dt(t){const e=t instanceof Error?t.message:String(t||"");return/记录不存在|任务不存在|不存在|已删除|not\s*found|404/i.test(e)}function dt(t){y.value=y.value.filter(e=>w(e)!==w(t)),j()}function Nt(t){g.value=g.value.filter(e=>!(t.resultId!=null&&e.resultId===t.resultId||t.taskId!=null&&e.taskId===t.taskId))}function ft(t,e){const o=new Map;for(const a of t)o.set(w(a),a);for(const a of e)o.set(w(a),a);return Array.from(o.values())}async function T(){U.value=await Zt()}async function B(){b.value=await te()}async function Y(){const t=await ee();g.value=t.items||[]}async function $(){await Promise.all([B(),Y()])}function Pt(t){if(!t.length)return;const e=new Map(t.map(a=>[q(a),a])),o=g.value.map(a=>{const r=e.get(q(a));return r?{...a,...r,countrySections:r.countrySections||a.countrySections||[],cartRatios:r.cartRatios||a.cartRatios||[]}:a});for(const a of t){const r=q(a);o.some(s=>q(s)===r)||o.push(a)}g.value=o}async function ht(t){const e=Array.from(new Set((t&&t.length?t:Q.value.map(a=>a.taskId??0)).filter(a=>Number.isFinite(a)&&a>0)));if(!e.length)return;const o=await ce(e);Pt(o.items||[]),(o.missingTaskIds||[]).length&&await Y()}function Mt(){W(),K.value&&(A=window.setInterval(()=>{ht()},tt()*2))}function W(){A&&(window.clearInterval(A),A=null)}function Rt(t){D.value=t}async function vt(){const t=E.value.trim();if(!t){c.warning("请输入店铺名");return}N.value=!0;try{await se(t),E.value="",await Promise.all([T(),B()]),c.success("已加入备选区")}catch(e){c.error(e instanceof Error?e.message:"添加失败")}finally{N.value=!1}}async function At(t){try{await ae(t),D.value=D.value.filter(e=>e.id!==t),await Promise.all([T(),B()]),c.success("已删除")}catch(e){c.error(e instanceof Error?e.message:"删除失败")}}function Qt(t,e){const o=new Map;for(const a of t)o.set(w(a),a);for(const a of e)o.set(w(a),a);return Array.from(o.values())}async function qt(){const t=D.value.map(e=>e.shop_name).filter(Boolean);if(!t.length){c.warning("请先勾选备选区店铺");return}P.value=!0;try{const e=await ne(t);y.value=Qt(y.value,e.items||[]),j(),H.value&&(f.value=ft(f.value,V.value),S(),X()),c.success(`本次返回 ${e.items?.length||0} 条匹配结果`)}catch(e){c.error(e instanceof Error?e.message:"匹配失败")}finally{P.value=!1}}function Lt(t){if(K.value){c.warning("队列执行中,请等待当前串行任务结束后再调整");return}y.value=y.value.filter(e=>w(e)!==w(t)),j()}function Bt(t){return{shopName:t.shopName,matched:t.matched,shopId:t.shopId,platform:t.platform,companyName:t.companyName,matchStatus:t.matchStatus,matchMessage:t.matchMessage,countrySections:bt(),cartRatios:Ct()}}function Ft(t,e){return{type:"patrol-delete-run",ts:Date.now(),data:{taskId:t,user_id:Number(z())||0,source:"frontend-vue-patrol-delete",items:[{shopName:e.shopName,shopId:e.shopId,platform:e.platform,companyName:e.companyName,matched:e.matched,matchStatus:e.matchStatus,matchMessage:e.matchMessage}],template_rows:lt(e),country_sections:e.countrySections||[],cart_ratios:e.cartRatios||[]}}}function Ut(t){return g.value.find(e=>e.taskId===t)}async function Ot(t){let e=0;for(;;){try{await ht([t]),e>0&&(_.value=`任务 ${t} 后端已恢复,继续等待执行结果...`),e=0;const a=Ut(t)?.taskStatus||"";if(a==="SUCCESS"||a==="FAILED"||a==="COMPLETED")return a}catch(o){if(!ot(o))throw o;if(e+=1,e>=wt)throw new Error(`任务 ${t} 等待后端恢复超时,请稍后刷新查看状态`);_.value=`任务 ${t} 执行中,正在等待后端服务恢复(${e}/${wt})...`}await nt(tt())}}async function X(){if(!R.value){R.value=!0,M.value=!0,Mt();try{const t=_t();if(!t?.enqueue_json)throw new Error("当前客户端未提供 enqueue_json");for(;h.value||f.value.length;){if(h.value){const d=await Ot(h.value);_.value=f.value.length>0?`任务 ${h.value} ${d==="SUCCESS"?"已完成":"执行失败"},自动继续下一个(剩余 ${f.value.length} 条)`:`任务 ${h.value} ${d==="SUCCESS"?"已完成":"执行失败"}`,L();continue}const e=f.value.shift();if(S(),!e)break;const o=await gt(()=>oe([Bt(e)]),(d,k)=>{_.value=`后端服务暂时不可用,正在重试创建任务(${d}/${k})...`}),a=o.items?.[0];if(!a?.taskId||!a.resultId)throw new Error("后端未返回有效任务标识");h.value=o.taskId,C.value=e,S(),await $();const r=Ft(o.taskId,a);O.value=JSON.stringify(r,null,2);const s=await t.enqueue_json(r);if(!s?.success){await le(o.taskId,{shops:[{shopName:a.shopName||e.shopName||"",error:s?.error||`任务 ${o.taskId} 推送失败`,countrySections:a.countrySections||[],cartRatios:a.cartRatios||[],shopDone:!0,submissionId:kt(o.taskId,a.shopName||e.shopName),chunkIndex:1,chunkTotal:1}]}),dt(e),await $(),_.value=`任务 ${o.taskId} 推送失败,已自动继续下一个任务`,L();continue}dt(e),_.value=f.value.length>0?`任务 ${o.taskId} 已入队,等待完成后自动继续下一个(剩余 ${f.value.length} 条)`:`任务 ${o.taskId} 已入队,等待执行完成`}_.value="串行队列已执行完成",await $(),c.success("巡店删除队列已按顺序执行完成")}catch(t){const e=t instanceof Error?t.message:"队列执行失败";_.value=e,c.error(e),await $()}finally{R.value=!1,M.value=!1,W(),S()}}}async function Ht(){H.value=!0;const t=V.value;if(!t.length){c.warning("请先匹配可用店铺");return}f.value=ft(f.value,t),S(),_.value=`已加入 ${t.length} 条店铺,开始串行执行`,await X()}async function Vt(t){if(!t.resultId)return;const e=_t();if(!e?.save_file_from_url_new){c.error("当前客户端未提供下载能力");return}const o=re(t.resultId),a=t.outputFilename||`${t.shopName||"result"}.xlsx`,r=await e.save_file_from_url_new(o,a);r.success?c.success(`已保存: ${r.path||a}`):r.error&&r.error!=="用户取消"&&c.error(r.error)}async function pt(t){try{if(t.taskId)await ue(t.taskId),h.value===t.taskId&&L();else if(t.resultId)await ie(t.resultId);else throw new Error("缺少可删除的任务标识");await Promise.all([T(),$()]),c.success("已删除")}catch(e){if(Dt(e)){t.taskId&&h.value===t.taskId&&L(),Nt(t),await T(),c.success("后端记录已不存在,已同步移除本地记录");return}c.error(e instanceof Error?e.message:"删除失败")}}return Kt(async()=>{$t(),Et(),await Promise.all([T(),B(),Y()]),(h.value||f.value.length)&&(H.value=!0,_.value=h.value!=null?`检测到未完成队列,继续等待任务 ${h.value} 完成并自动接续后续店铺`:`检测到未完成队列,继续执行剩余 ${f.value.length} 条店铺`,X())}),zt(()=>{W()}),(t,e)=>{const o=Yt,a=Wt,r=Xt;return u(),i("div",me,[p(Jt,{active:"patrol-delete"}),n("div",ye,[n("aside",_e,[e[3]||(e[3]=n("div",{class:"section-title"},"店铺输入",-1)),n("div",we,[e[1]||(e[1]=n("div",{class:"hint"}," 左侧负责录入店铺并加入备选区,确认命中后推送到 Python 队列。巡店删除按店铺串行执行:上一个任务完成后会自动开始下一个,失败也会继续下一个。 ",-1)),n("div",ge,[p(o,{modelValue:E.value,"onUpdate:modelValue":e[0]||(e[0]=s=>E.value=s),clearable:"",placeholder:"请输入店铺名后回车或点击添加",onKeyup:jt(vt,["enter"])},null,8,["modelValue"]),n("button",{type:"button",class:"opt-btn",disabled:N.value,onClick:vt},l(N.value?"添加中...":"添加"),9,ke)])]),e[4]||(e[4]=n("div",{class:"section-title"},"备选区",-1)),U.value.length?(u(),i("div",Se,[p(r,{data:U.value,"row-key":"id",height:"260",class:"candidate-table",onSelectionChange:Rt},{default:I(()=>[p(a,{type:"selection",width:"42"}),p(a,{prop:"shop_name",label:"店铺名","min-width":"140","show-overflow-tooltip":""}),p(a,{label:"操作",width:"72",align:"center"},{default:I(({row:s})=>[n("button",{type:"button",class:"link-danger",onClick:d=>At(s.id)}," 删除 ",8,be)]),_:1})]),_:1},8,["data"])])):(u(),i("div",Ie," 暂无备选店铺,请先输入并添加 ")),n("div",Ce,[n("button",{type:"button",class:"btn-run",disabled:P.value||K.value,onClick:qt},l(P.value?"匹配中...":"匹配店铺"),9,Te),n("button",{type:"button",class:"btn-run btn-queue",disabled:M.value||!V.value.length,onClick:Ht},l(M.value?"串行执行中...":"推送到 Python 队列"),9,$e)]),e[5]||(e[5]=n("p",{class:"loading-msg"}," 当前页面会按店铺串行推送任务,并在任务成功或失败后自动接续下一个任务。服务端临时重启时会自动重试查询状态,恢复后继续后续店铺。 ",-1)),_.value?(u(),i("div",Ee,[e[2]||(e[2]=n("div",{class:"section-title queue-debug-title"},"队列状态",-1)),n("div",De,l(_.value),1),O.value?(u(),i("pre",Ne,l(O.value),1)):m("",!0)])):m("",!0)]),n("section",Pe,[e[14]||(e[14]=n("div",{class:"panel-header"},"匹配与任务",-1)),n("div",Me,[n("div",Re,[n("div",Ae,[e[6]||(e[6]=n("span",{class:"summary-label"},"备选店铺",-1)),n("strong",null,l(b.value.candidateCount),1)]),n("div",Qe,[e[7]||(e[7]=n("span",{class:"summary-label"},"已处理任务",-1)),n("strong",null,l(b.value.processedTaskCount),1)]),n("div",qe,[e[8]||(e[8]=n("span",{class:"summary-label"},"成功任务",-1)),n("strong",null,l(b.value.successTaskCount),1)]),n("div",Le,[e[9]||(e[9]=n("span",{class:"summary-label"},"失败任务",-1)),n("strong",null,l(b.value.failedTaskCount),1)])]),e[13]||(e[13]=n("div",{class:"subsection-title"},"匹配结果",-1)),y.value.length?(u(),Gt(r,{key:1,data:y.value,"row-key":w,"highlight-current-row":!1,class:"result-table match-table"},{default:I(()=>[p(a,{prop:"shopName",label:"店铺名","min-width":"120"}),p(a,{label:"匹配",width:"72",align:"center"},{default:I(({row:s})=>[n("span",{class:G(s.matched?"ok":"fail")},l(s.matched?"是":"否"),3)]),_:1}),p(a,{prop:"shopId",label:"店铺 ID","min-width":"120","show-overflow-tooltip":""}),p(a,{prop:"platform",label:"平台",width:"88","show-overflow-tooltip":""}),p(a,{prop:"companyName",label:"公司","min-width":"120","show-overflow-tooltip":""}),p(a,{label:"状态",width:"110","show-overflow-tooltip":""},{default:I(({row:s})=>[mt(l(It(s.matchStatus)),1)]),_:1}),p(a,{label:"说明","min-width":"180","show-overflow-tooltip":""},{default:I(({row:s})=>[mt(l(St(s)),1)]),_:1}),p(a,{label:"操作",width:"72",align:"center"},{default:I(({row:s})=>[n("button",{type:"button",class:"link-danger",onClick:d=>Lt(s)}," 删除 ",8,Fe)]),_:1})]),_:1},8,["data"])):(u(),i("div",Be," 完成“匹配店铺”后,这里会展示匹配结果。 ")),n("div",Ue,[e[12]||(e[12]=n("div",{class:"result-list-header"},[n("span",null,"任务记录")],-1)),!Q.value.length&&!x.value.length?(u(),i("div",Oe," 暂无任务记录。推送到 Python 队列后,这里会展示当前任务和历史任务。 ")):(u(),i(Z,{key:1},[Q.value.length?(u(),i("div",He,[e[10]||(e[10]=n("div",{class:"result-subsection-title"},"当前任务",-1)),n("ul",Ve,[(u(!0),i(Z,null,yt(Q.value,s=>(u(),i("li",{key:`${s.resultId}-${s.taskId}`,class:"task-item"},[n("div",xe,[n("span",{class:"id",title:s.shopName||""},l(s.shopName||"-"),9,Ke),n("div",ze,"任务 ID: "+l(s.taskId??"-"),1),s.resultId?(u(),i("div",Je," 结果 ID: "+l(s.resultId),1)):m("",!0),s.shopId?(u(),i("div",je," 店铺 ID: "+l(s.shopId),1)):m("",!0),s.platform?(u(),i("div",Ye," 平台: "+l(s.platform),1)):m("",!0),n("div",We," 创建时间: "+l(J(s.createdAt)),1),n("div",Xe," 模板结构: "+l(rt(s)),1),s.error?(u(),i("div",Ge," 错误: "+l(s.error),1)):m("",!0)]),n("div",Ze,[n("span",{class:G(["status",ct(s.taskStatus)])},l(it(s.taskStatus)),3),n("button",{type:"button",class:"btn-delete",onClick:d=>pt(s)}," 删除 ",8,ts)])]))),128))])])):m("",!0),x.value.length?(u(),i("div",es,[e[11]||(e[11]=n("div",{class:"result-subsection-title"},"历史任务",-1)),n("ul",ss,[(u(!0),i(Z,null,yt(x.value,s=>(u(),i("li",{key:`${s.resultId}-${s.taskId}`,class:"task-item"},[n("div",as,[n("span",{class:"id",title:s.shopName||""},l(s.shopName||"-"),9,ns),n("div",os,"任务 ID: "+l(s.taskId??"-"),1),s.resultId?(u(),i("div",ls," 结果 ID: "+l(s.resultId),1)):m("",!0),s.shopId?(u(),i("div",rs," 店铺 ID: "+l(s.shopId),1)):m("",!0),s.platform?(u(),i("div",us," 平台: "+l(s.platform),1)):m("",!0),n("div",is," 创建时间: "+l(J(s.createdAt)),1),s.finishedAt?(u(),i("div",cs," 完成时间: "+l(J(s.finishedAt)),1)):m("",!0),n("div",ds," 模板结构: "+l(rt(s)),1),s.error?(u(),i("div",fs," 错误: "+l(s.error),1)):m("",!0)]),n("div",hs,[n("span",{class:G(["status",ct(s.taskStatus)])},l(it(s.taskStatus)),3),Tt(s)?(u(),i("button",{key:0,type:"button",class:"archive",onClick:d=>Vt(s)}," 下载结果 ",8,vs)):m("",!0),n("button",{type:"button",class:"btn-delete",onClick:d=>pt(s)}," 删除 ",8,ps)])]))),128))])])):m("",!0)],64))])])])])])}}}),ys=de(ms,[["__scopeId","data-v-7d108ffe"]]);fe.locale("zh-cn");he(ys).use(ve,{locale:pe}).mount("#app");