2 lines
17 KiB
JavaScript
2 lines
17 KiB
JavaScript
import{g as y,N as pe,O as oe,d as me,o as ye,a as f,c as v,b as he,e as t,F as V,r as Y,t as l,f as D,w as z,p as ae,v as X,n as ne,P as ke,h as le,E as m,i as Q,_ as ge,j as _e,k as be}from"./pywebview-B8lwamDf.js";import{v as we,B as Ce,aZ as Se,a_ as Ie,a$ as Te,b0 as Ne,s as Pe,b1 as xe,b2 as Ae,b3 as Ee,b4 as Fe,b5 as De}from"./java-modules-B9jblDzU.js";import{e as Ue}from"./brand-DE-sObfq.js";import{c as re}from"./categorized-timers-JPA-olTr.js";const $e=c=>c==="SUCCESS"||c==="FAILED";function Be(c){if(!c||typeof window>"u")return[];try{const k=window.localStorage.getItem(c);if(!k)return[];const g=JSON.parse(k);return Array.isArray(g)?g.filter(b=>typeof b=="number"&&b>0):[]}catch{return[]}}function Re(c,k){if(!(!c||typeof window>"u"))try{k.length===0?window.localStorage.removeItem(c):window.localStorage.setItem(c,JSON.stringify(k))}catch{}}function Le(c){const k=re(`task-progress-loop:${c.scope}`),g=c.isTerminal??$e,b=c.getIntervalMs??we,p=y(Be(c.storageKey)),_=y({}),o=y(!1);let d=null,S=!1;function R(){Re(c.storageKey,p.value)}function O(n){!Number.isFinite(n)||n<=0||p.value.includes(n)||(p.value=[...p.value,n],R(),E(!0))}function U(n){if(p.value.includes(n)&&(p.value=p.value.filter(r=>r!==n),R(),_.value[n])){const r={..._.value};delete r[n],_.value=r}}function T(n){const r=Array.from(new Set(n.filter(M=>Number.isFinite(M)&&M>0)));p.value=r,R()}function w(n){const r=_.value[n];return!!r&&g(r)}async function N(){if(S)return;const n=p.value.filter(r=>r>0);if(n.length){o.value=!0;try{const M=(await c.fetchProgress(n))?.items||[],K=[],j={..._.value};for(const C of M){const F=c.extractTaskId(C);if(typeof F!="number"||F<=0)continue;const q=c.extractStatus(C)||"";try{c.onUpdate?.(F,C)}catch{}q&&(j[F]=q,g(q)&&K.push({taskId:F,detail:C,status:q}))}_.value=j;for(const C of K){U(C.taskId);try{await c.onTerminal?.(C.taskId,C.detail,C.status)}catch{}}}catch(r){c.onError?.(r)}finally{o.value=!1}}}function L(){d!=null&&(k.clearTimer("task-poll",d),d=null)}function A(n=!1){if(S||d!=null&&!n)return;L();const r=async()=>{if(d=null,!S&&p.value.length){if(o.value){d=k.setTimeout("task-poll",r,500);return}await N(),!S&&p.value.length>0&&(d=k.setTimeout("task-poll",r,b()))}};n?r():d=k.setTimeout("task-poll",r,b())}function E(n=!1){S||p.value.length&&(d!=null&&!n||A(n))}function $(){L()}pe(p,(n,r)=>{if(!S){if(!n.length){$();return}(!r||r.length===0)&&A(!0)}},{flush:"post"});let P=null;typeof document<"u"&&(P=()=>{document.visibilityState==="visible"&&p.value.length>0&&A(!0)},document.addEventListener("visibilitychange",P));function I(){S||(S=!0,$(),k.clearScope(),P&&typeof document<"u"&&(document.removeEventListener("visibilitychange",P),P=null))}return oe(()=>I()),p.value.length>0&&A(!0),{taskIds:p,taskStatuses:_,inFlight:o,add:O,remove:U,reset:T,ensure:E,stop:$,refreshOnce:N,isTerminal:w,dispose:I}}const Me={class:"page-shell module-page"},qe={class:"main-content"},Oe={class:"left-panel"},Ge={class:"upload-zone"},Ve={class:"selected-files"},ze={key:0,class:"more-line"},Ke={key:1},je={class:"filter-zone"},He={class:"filter-row"},Je={class:"range-inputs"},Ye={class:"filter-checks"},Qe={class:"filter-check-row"},We={class:"filter-check-row"},Ze={class:"filter-check-row"},Xe={class:"section-title country-section-title"},et={key:0,class:"country-pref-saving"},tt={class:"country-pref-radios"},st=["checked","onChange"],at={class:"country-check-text"},nt={class:"run-row"},lt=["disabled"],ot=["disabled"],rt={key:0,class:"queue-debug-card"},it={class:"queue-debug-line"},ut={key:0,class:"queue-debug-payload"},ct={class:"right-panel"},dt={class:"task-list-wrap"},ft={class:"clean-result-summary"},vt={class:"summary-card"},pt={class:"summary-card"},mt={class:"summary-card"},yt={class:"summary-card"},ht={class:"result-list-wrap"},kt={key:0,class:"empty-tasks"},gt={key:1,class:"task-list clean-result-list"},_t={class:"left"},bt={class:"id"},wt={class:"files"},Ct={class:"files"},St={class:"files"},It={class:"files"},Tt={class:"files"},Nt={class:"task-right"},Pt={class:"status running"},xt=["onClick"],At={class:"result-list-wrap"},Et={key:0,class:"empty-tasks"},Ft={key:1,class:"task-list clean-result-list"},Dt={class:"left"},Ut={class:"id"},$t={class:"files"},Bt={class:"files"},Rt={class:"files"},Lt={class:"files"},Mt={class:"files"},qt={key:0,class:"files"},Ot={key:1,class:"files"},Gt={class:"task-right"},Vt=["onClick"],zt=["onClick"],Kt="brand:collect-data:polling-task-ids",jt=me({__name:"BrandCollectDataTab",setup(c){const k=[{code:"DE",label:"德国"},{code:"UK",label:"英国"},{code:"FR",label:"法国"},{code:"IT",label:"意大利"},{code:"ES",label:"西班牙"}],g=y([]),b=y([]),p=y(!1),_=y(!1),o=ke({minAmount:null,maxAmount:null,rank:!1,fba:!1,fbm:!1}),d=y("DE"),S=le(()=>d.value?[d.value]:[]),R=y(!1),O=y(!1),U=re("collect-data-tab");let T=null;const w=y(null),N=y(null),L=y(""),A=y(""),E=y({pendingTaskCount:0,processedTaskCount:0,successTaskCount:0,failedTaskCount:0}),$=y([]),P=y([]),I=y({}),n=Le({scope:"collect-data-tab",storageKey:Kt,fetchProgress:s=>De(s),extractTaskId:s=>s.task?.id??null,extractStatus:s=>s.task?.status??"",onUpdate:(s,e)=>{const a=I.value[s];I.value={...I.value,[s]:a?{...a,task:{...a.task||{},...e.task||{}},items:e.items??a.items}:e}},onTerminal:async s=>{if(I.value[s]){const e={...I.value};delete e[s],I.value=e}await Promise.all([G(),H()])}}),r=le(()=>g.value.slice(0,8));function M(s){k.some(e=>e.code===s)&&d.value!==s&&(R.value=!0,d.value=s,K())}function K(){T!=null&&U.clearTimer("country-pref-save",T),T=U.setTimeout("country-pref-save",()=>{T=null,j()},450)}async function j(){if(d.value){O.value=!0;try{await Se([d.value])}catch(s){m.error(s instanceof Error?s.message:"保存国家顺序失败")}finally{O.value=!1}}}async function C(){try{const s=await Ie();if(R.value)return;const e=s?.country_codes;Array.isArray(e)&&e.length&&(d.value=String(e[0]||"DE"))}catch{}}async function F(s){const e=Q();if(!e?.upload_file_to_java)throw new Error("当前桌面端未提供文件上传能力");const a=[];for(const i of s){const x=typeof i=="string"?i:i.absolutePath,B=typeof i=="string"?void 0:i.relativePath,u=await e.upload_file_to_java(x,B);if(!u?.success||!u.data)throw new Error(u?.error||u?.message||`上传失败:${x}`);a.push(u.data)}return a}async function q(){const s=Q();if(!s?.select_brand_xlsx_files||!s.upload_file_to_java){m.warning("当前环境不支持文件选择或上传");return}try{const e=await s.select_brand_xlsx_files();if(!e?.length)return;const a=await F(e);b.value=a,g.value=a.map(i=>i.relativePath||i.originalFilename||i.fileKey),w.value=null,N.value=null}catch(e){m.error(e instanceof Error?e.message:"文件选择失败")}}async function ie(){const s=Q();if(!s?.select_brand_folder){m.warning("当前环境不支持文件夹选择,请在本地客户端中打开");return}try{const e=await s.select_brand_folder();if(!e)return;const a=await Ue(e);if(!a.success||!a.items?.length){m.warning(a.error||"该文件夹下没有可用的 xlsx 文件");return}const i=await F(a.items);b.value=i,g.value=a.items.map(x=>x.relativePath||x.absolutePath),w.value=null,N.value=null,m.success(`已选择文件夹内 ${a.items.length} 个 Excel 文件`)}catch(e){m.error(e instanceof Error?e.message:"选择失败")}}function ee(){const s=o.minAmount===null||o.minAmount===void 0||Number.isNaN(o.minAmount)?null:o.minAmount,e=o.maxAmount===null||o.maxAmount===void 0||Number.isNaN(o.maxAmount)?null:o.maxAmount;return{amount:e??s,minAmount:s,maxAmount:e,min_amount:s,max_amount:e,rank:!!o.rank,fba:!!o.fba,fbm:!!o.fbm,countryCodes:[...S.value],countryCode:d.value,country_code:d.value}}async function ue(){if(!b.value.length){m.warning("请先选择 Excel 文件");return}if(!d.value){m.warning("请选择采集国家");return}p.value=!0;try{const s=await Te({files:b.value.map(e=>({fileKey:e.fileKey,originalFilename:e.originalFilename,relativePath:e.relativePath})),task_type:"collect-data",filters:ee()});N.value=s,w.value=s.taskId??null,s.taskId&&n.add(s.taskId),m.success(`提交成功:任务 ${s.taskNo||s.taskId},落库 ${s.acceptedRows??0} 行`),await Promise.all([G(),H()])}catch(s){m.error(s instanceof Error?s.message:"提交失败")}finally{p.value=!1}}async function ce(){if(!w.value){m.warning("请先提交采集任务");return}const s=Q();if(!s?.enqueue_json){m.warning("当前环境未提供 Python 队列能力");return}_.value=!0;try{await Ne(w.value);const e={type:"collect-data-run",ts:Date.now(),data:{taskId:w.value,taskNo:N.value?.taskNo,taskType:"collect-data",totalRows:N.value?.acceptedRows??0,pageSize:N.value?.pageSize??50,filters:ee()}},a=await s.enqueue_json(e);if(!a?.success)throw new Error(a?.error||"入队失败");L.value=`已推送至 Python 队列(队列长度:${a.queue_size??"-"})`,A.value=JSON.stringify(e,null,2),w.value&&n.add(w.value),m.success("已推送到 Python 队列"),await G()}catch(e){m.error(e instanceof Error?e.message:"推送失败")}finally{_.value=!1}}function W(s){if(!s)return"-";const e=new Date(s);if(Number.isNaN(e.getTime()))return s;const a=e.getFullYear(),i=String(e.getMonth()+1).padStart(2,"0"),x=String(e.getDate()).padStart(2,"0"),B=String(e.getHours()).padStart(2,"0"),u=String(e.getMinutes()).padStart(2,"0"),h=String(e.getSeconds()).padStart(2,"0");return`${a}-${i}-${x} ${B}:${u}:${h}`}function Z(s){return(s.taskStatus||"").toUpperCase()}function te(s){const e=Z(s);return e==="RUNNING"?"执行中":e==="PENDING"?"等待中":e==="SUCCESS"||s.success?"已完成":e==="FAILED"?"失败":"等待中"}function de(s){const e=Z(s);return e==="RUNNING"?"running":e==="FAILED"?"failed":e==="SUCCESS"||s.success?"success":"pending"}function fe(s){const e=Z(s);return!!(s.downloadUrl&&(s.success||e==="SUCCESS"))}async function ve(s){if(!s.downloadUrl){m.warning("当前结果没有下载地址");return}const e=s.resultFilename||`${s.sourceFilename||"collect-data-result"}.xlsx`,a=`collect-data:${s.resultId||s.taskId||Date.now()}`,i=await Pe(s.downloadUrl,e,a);i.success?m.success(`已保存: ${i.path||e}`):i.error&&i.error!=="用户取消"&&m.error(i.error)}async function G(){try{E.value=await xe()}catch{}}async function H(){try{const e=(await Ae(50)).items||[],a=e.filter(u=>{const h=(u.taskStatus||"").toUpperCase();return h==="PENDING"||h==="RUNNING"});P.value=e.filter(u=>{const h=(u.taskStatus||"").toUpperCase();return h==="SUCCESS"||h==="FAILED"});const i=new Set;for(const u of a)u.taskId&&(i.add(u.taskId),n.add(u.taskId));for(const u of[...n.taskIds.value])e.some(J=>J.taskId===u)||n.remove(u);const x=new Set(a.map(u=>u.taskId).filter(u=>typeof u=="number")),B=[...a];for(const u of n.taskIds.value){if(x.has(u))continue;const h=I.value[u],J=h?.items?.[0];J?B.push(J):h?.task&&B.push({taskId:h.task.id,taskNo:h.task.taskNo,taskStatus:h.task.status,startedAt:h.task.createdAt,finishedAt:h.task.finishedAt,sourceFilename:"采集数据"})}$.value=B}catch{}}async function se(s){try{if(s.resultId)await Ee(s.resultId);else if(s.taskId)await Fe(s.taskId);else return;s.taskId&&n.remove(s.taskId),m.success("已删除"),await Promise.all([G(),H()])}catch(e){m.error(e instanceof Error?e.message:"删除失败")}}return ye(()=>{C(),G(),H()}),oe(()=>{T!=null&&(U.clearTimer("country-pref-save",T),T=null),U.clearScope()}),(s,e)=>(f(),v("div",Me,[he(Ce,{active:"collect-data"}),t("div",qe,[t("aside",Oe,[e[13]||(e[13]=t("div",{class:"section-title"},"上传文件",-1)),t("div",Ge,[e[5]||(e[5]=t("div",{class:"hint"},"选择需要采集的 Excel 文件或文件夹(默认根目录:采集前数据.xlsx),后续将按下方筛选条件交给 Python 端进行数据采集。",-1)),t("div",{class:"btns"},[t("button",{type:"button",class:"opt-btn",onClick:q},"选择 Excel"),t("button",{type:"button",class:"opt-btn",onClick:ie},"选择文件夹")]),t("div",Ve,[g.value.length?(f(),v(V,{key:0},[(f(!0),v(V,null,Y(r.value,a=>(f(),v("span",{key:a},l(a),1))),128)),g.value.length>r.value.length?(f(),v("span",ze," 还有 "+l(g.value.length-r.value.length)+" 个文件未展开显示 ",1)):D("",!0)],64)):(f(),v("span",Ke,"暂未选择文件"))])]),e[14]||(e[14]=t("div",{class:"section-title"},"筛选条件",-1)),t("div",je,[t("div",He,[e[7]||(e[7]=t("label",{class:"filter-label"},"金额区间",-1)),t("div",Je,[z(t("input",{"onUpdate:modelValue":e[0]||(e[0]=a=>o.minAmount=a),type:"number",step:"0.01",min:"0",class:"filter-input",placeholder:"最低"},null,512),[[ae,o.minAmount,void 0,{number:!0}]]),e[6]||(e[6]=t("span",{class:"range-separator"},"至",-1)),z(t("input",{"onUpdate:modelValue":e[1]||(e[1]=a=>o.maxAmount=a),type:"number",step:"0.01",min:"0",class:"filter-input",placeholder:"最高"},null,512),[[ae,o.maxAmount,void 0,{number:!0}]])])]),t("div",Ye,[t("label",Qe,[z(t("input",{type:"checkbox",class:"filter-check-input","onUpdate:modelValue":e[2]||(e[2]=a=>o.rank=a)},null,512),[[X,o.rank]]),e[8]||(e[8]=t("span",{class:"filter-check-text"},"排名",-1))]),t("label",We,[z(t("input",{type:"checkbox",class:"filter-check-input","onUpdate:modelValue":e[3]||(e[3]=a=>o.fba=a)},null,512),[[X,o.fba]]),e[9]||(e[9]=t("span",{class:"filter-check-text"},"FBA",-1))]),t("label",Ze,[z(t("input",{type:"checkbox",class:"filter-check-input","onUpdate:modelValue":e[4]||(e[4]=a=>o.fbm=a)},null,512),[[X,o.fbm]]),e[10]||(e[10]=t("span",{class:"filter-check-text"},"FBM",-1))])])]),t("div",Xe,[e[11]||(e[11]=t("span",null,"采集国家",-1)),O.value?(f(),v("span",et,"保存中…")):D("",!0)]),e[15]||(e[15]=t("p",{class:"hint country-pref-hint"}," 每次任务只采集一个国家,选择后会自动保存,下次进入默认使用该国家。 ",-1)),t("div",tt,[(f(),v(V,null,Y(k,a=>t("label",{key:a.code,class:ne(["country-check-row",{selected:d.value===a.code}])},[t("input",{type:"radio",name:"collect-data-country",class:"country-check-input",checked:d.value===a.code,onChange:i=>M(a.code)},null,40,st),t("span",at,l(a.label)+"("+l(a.code)+")",1)],2)),64))]),t("div",nt,[t("button",{type:"button",class:"btn-run",disabled:p.value||!b.value.length,onClick:ue},l(p.value?"提交中...":"提交采集任务"),9,lt),t("button",{type:"button",class:"btn-run btn-queue",disabled:_.value||!w.value,onClick:ce},l(_.value?"推送中...":"推送到 Python 队列"),9,ot)]),e[16]||(e[16]=t("p",{class:"loading-msg"},"提交后由 Java 解析 Excel 并落库为待采集任务(PENDING);推送到 Python 队列将激活任务(RUNNING),Python 端按 50 条/页拉取明细执行采集。",-1)),L.value?(f(),v("div",rt,[e[12]||(e[12]=t("div",{class:"section-title queue-debug-title"},"推送结果",-1)),t("div",it,l(L.value),1),A.value?(f(),v("pre",ut,l(A.value),1)):D("",!0)])):D("",!0)]),t("section",ct,[e[24]||(e[24]=t("div",{class:"panel-header"},"采集数据",-1)),t("div",dt,[t("div",ft,[t("div",vt,[e[17]||(e[17]=t("span",{class:"summary-label"},"运行中任务",-1)),t("strong",null,l(E.value.pendingTaskCount),1)]),t("div",pt,[e[18]||(e[18]=t("span",{class:"summary-label"},"已结束任务",-1)),t("strong",null,l(E.value.processedTaskCount),1)]),t("div",mt,[e[19]||(e[19]=t("span",{class:"summary-label"},"成功任务",-1)),t("strong",null,l(E.value.successTaskCount),1)]),t("div",yt,[e[20]||(e[20]=t("span",{class:"summary-label"},"失败任务",-1)),t("strong",null,l(E.value.failedTaskCount),1)])]),e[23]||(e[23]=t("div",{class:"subsection-title"},"匹配任务",-1)),t("div",ht,[e[21]||(e[21]=t("div",{class:"result-list-header"},[t("span",null,"当前任务")],-1)),$.value.length?(f(),v("ul",gt,[(f(!0),v(V,null,Y($.value,a=>(f(),v("li",{key:`cur-${a.taskId}`,class:"task-item"},[t("div",_t,[t("span",bt,l(a.sourceFilename||"采集数据"),1),t("div",wt,"任务 ID:"+l(a.taskId),1),t("div",Ct,"开始时间:"+l(W(a.startedAt||a.createdAt)),1),t("div",St,"行数:"+l(a.rowCount??"-"),1),t("div",It,"总数据去重过滤:"+l(a.dedupeFilteredCount??0),1),t("div",Tt,"不符合 ASIN 过滤:"+l(a.invalidFilteredCount??0),1)]),t("div",Nt,[t("span",Pt,l(te(a)),1),t("button",{type:"button",class:"btn-delete",onClick:i=>se(a)},"删除",8,xt)])]))),128))])):(f(),v("div",kt,"暂无当前任务"))]),t("div",At,[e[22]||(e[22]=t("div",{class:"result-list-header"},[t("span",null,"历史记录")],-1)),P.value.length?(f(),v("ul",Ft,[(f(!0),v(V,null,Y(P.value,a=>(f(),v("li",{key:`his-${a.resultId}-${a.taskId}`,class:"task-item"},[t("div",Dt,[t("span",Ut,l(a.sourceFilename||"采集数据"),1),t("div",$t,"任务 ID:"+l(a.taskId??"-"),1),t("div",Bt,"开始时间:"+l(W(a.startedAt||a.createdAt)),1),t("div",Rt,"结束时间:"+l(W(a.finishedAt)),1),t("div",Lt,"总数据去重过滤:"+l(a.dedupeFilteredCount??0),1),t("div",Mt,"不符合 ASIN 过滤:"+l(a.invalidFilteredCount??0),1),a.resultFilename?(f(),v("div",qt,l(a.resultFilename),1)):D("",!0),a.error?(f(),v("div",Ot,"错误:"+l(a.error),1)):D("",!0)]),t("div",Gt,[t("span",{class:ne(["status",de(a)])},l(te(a)),3),fe(a)?(f(),v("button",{key:0,type:"button",class:"download",onClick:i=>ve(a)},"下载",8,Vt)):D("",!0),a.resultId?(f(),v("button",{key:1,type:"button",class:"btn-delete",onClick:i=>se(a)},"删除",8,zt)):D("",!0)])]))),128))])):(f(),v("div",Et,"暂无历史记录"))])])])])]))}}),Ht=ge(jt,[["__scopeId","data-v-1311c61c"]]);_e(Ht).use(be).mount("#app");
|