5 lines
19 KiB
JavaScript
5 lines
19 KiB
JavaScript
import{d as Xe,o as Ze,L as et,a as o,c as i,b as me,B as tt,e as a,F as B,r as G,t as r,w as we,G as st,u as at,f as h,N as nt,n as lt,a4 as ne,a5 as ot,a6 as it,a7 as rt,g as d,h as L,a8 as ut,E as u,i as H,a9 as ct,aa as dt,ab as ft,ac as vt,ad as pt,U as Ce,ae as gt,af as yt,ag as ht,ah as _t,ai as kt,a2 as mt,aj as wt,_ as Ct,q as It,s as St}from"./pywebview-ZMN052YE.js";/* empty css */import{e as bt}from"./brand-DfxdJ4w6.js";import{c as Tt}from"./categorized-timers-JPA-olTr.js";const Pt={class:"page-shell module-page"},Ft={class:"main-content"},Et={class:"left-panel"},Nt={class:"upload-zone"},Rt={class:"selected-files"},xt={key:0},At={class:"prompt-card"},Dt={class:"condition-actions"},Ut=["disabled"],$t={key:0,class:"empty-conditions"},Bt={key:1,class:"condition-list"},Gt={class:"condition-check"},Lt=["value","onChange"],Ht=["title"],Mt=["onClick"],jt={class:"category-card"},qt={class:"category-card-head"},Vt={class:"category-actions"},zt={key:0,class:"empty-conditions"},Kt={key:1,class:"selected-category-list"},Ot={class:"run-row"},Jt=["disabled"],Qt=["disabled"],Yt={key:0,class:"parse-card"},Wt={key:1,class:"queue-payload"},Xt={class:"right-panel"},Zt={class:"task-list-wrap"},es={class:"clean-result-summary"},ts={class:"summary-card"},ss={class:"summary-card"},as={class:"summary-card"},ns={class:"summary-card"},ls={class:"result-list-wrap"},os={key:0,class:"empty-tasks"},is={key:1,class:"task-list clean-result-list"},rs={class:"left"},us={class:"id"},cs={class:"files"},ds={class:"files"},fs={class:"task-right"},vs={class:"status running"},ps=["onClick"],gs={class:"result-list-wrap"},ys={key:0,class:"empty-tasks"},hs={key:1,class:"task-list clean-result-list"},_s={class:"left"},ks={class:"id"},ms={class:"files"},ws={key:0,class:"files"},Cs={key:1,class:"files result-hint"},Is={key:2,class:"file-progress"},Ss={class:"file-progress-meta"},bs={class:"file-progress-track"},Ts={class:"file-progress-count"},Ps={key:3,class:"files"},Fs={class:"task-right"},Es=["onClick"],Ns=["onClick"],Rs={key:0,class:"empty-tasks"},xs={key:1,class:"empty-tasks"},As={class:"category-tree-node"},Ds={key:0,class:"category-description"},Us=3e3,$s=Xe({__name:"BrandSimilarAsinTab",setup(Gs){const M=d([]),C=d([]),k=d(null),I=d(null),S=d(""),b=d([]),_=d(null),j=d([]),le=d([]),T=d([]),P=d(!1),q=d(!1),F=d(null),V=d(!1),z=d(!1),K=d(!1),m=d(""),v=d([]),f=d([]),g=d(null),Y=d(!1);let E=null,oe=0,N=!1;const R=Tt("similar-asin"),x=d({pendingTaskCount:0,processedTaskCount:0,successTaskCount:0,failedTaskCount:0}),p=d([]),A=L(()=>k.value||I.value),W=L(()=>{const e=k.value;return!e?.taskId||p.value.some(n=>n.taskId===e.taskId)?null:{taskId:e.taskId,sourceFilename:e.sourceFilename,rowCount:e.acceptedRows,taskStatus:"PENDING",success:!1}}),ie=L(()=>{const e=new Set([...v.value,...f.value]),t=p.value.filter(l=>{const s=$(l);return l.taskId!=null&&(e.has(l.taskId)||s==="RUNNING"||s==="PENDING")});return W.value?t.some(l=>l.taskId===W.value?.taskId)?t:[W.value,...t]:t}),re=L(()=>p.value.filter(e=>{const t=$(e);return t!=="RUNNING"&&t!=="PENDING"}));function Ie(){const e=_.value;return e==null?"":b.value.find(t=>t.id===e)?.conditionText?.trim()||""}function ue(){return Se(S.value.trim()||Ie())}function O(){return mt("similar-asin").trim()}const X=L(()=>{const e=new Set(T.value);return le.value.filter(t=>e.has(t.id))});function Se(e){const t=X.value.map(l=>{const s=l.path||l.name,c=l.description?.trim();return c?`${s}(${c})`:s}).filter(Boolean);if(!t.length)return e;const n=["商品类目要求:",...t.map(l=>`- ${l}`)].join(`
|
||
`);return e?`${e}
|
||
|
||
${n}`:n}async function ce(){if(!q.value){q.value=!0;try{const e=await ut();j.value=e.tree||[],le.value=e.items||[]}catch(e){u.error(e instanceof Error?e.message:"加载商品类目失败")}finally{q.value=!1}}}async function be(){P.value=!0,j.value.length||await ce(),requestAnimationFrame(()=>{F.value?.setCheckedKeys?.(T.value)})}function de(e,t){return!!e.children?.some(n=>t.has(n.id)||de(n,t))}function Te(){const e=F.value?.getCheckedNodes?.(!1,!1)||[],t=new Set(e.map(n=>n.id));T.value=e.filter(n=>!de(n,t)).map(n=>n.id),P.value=!1}function Pe(){F.value?.setCheckedKeys?.([])}function Fe(){T.value=[],F.value?.setCheckedKeys?.([])}function Ee(e){return e?e.length<=10?"***":`${e.slice(0,6)}***${e.slice(-4)}`:""}function Ne(e){return{...e,data:e.data?{...e.data,api_key:Ee(String(e.data.api_key||""))}:e.data}}function Re(){return typeof window<"u"&&window.localStorage.getItem("uid")||"0"}function Z(){return`similar-asin:tasks:${Re()}`}function xe(e){return{taskId:e.taskId,totalRows:e.totalRows,acceptedRows:e.acceptedRows,groupCount:e.groupCount,droppedRows:e.droppedRows}}function w(){if(typeof window>"u")return;const e=Array.from(new Set([...v.value,...f.value]));e.length?window.localStorage.setItem(Z(),JSON.stringify(e)):window.localStorage.removeItem(Z())}function Ae(){if(!(typeof window>"u"))try{const e=window.localStorage.getItem(Z()),t=e?JSON.parse(e):[];v.value=Array.isArray(t)?t.filter(n=>typeof n=="number"&&n>0):[]}catch{v.value=[]}}async function fe(e){const t=H();if(!t?.upload_file_to_java)throw new Error("当前桌面端未提供文件上传能力");const n=[];for(const l of e){const s=typeof l=="string"?l:l.absolutePath,c=typeof l=="string"?void 0:l.relativePath,y=await t.upload_file_to_java(s,c);if(!y?.success||!y.data)throw new Error(y?.error||y?.message||`上传失败:${s}`);n.push(y.data)}return n}async function De(){const e=H();if(!e?.select_brand_xlsx_files||!e.upload_file_to_java){u.warning("当前桌面端未提供文件选择或上传能力");return}const t=await e.select_brand_xlsx_files();if(!t?.length)return;const n=await fe(t);C.value=n,M.value=n.map(l=>l.relativePath||l.originalFilename||l.fileKey),k.value=null,I.value=null,m.value=""}async function Ue(){const e=H();if(!e?.select_brand_folder||!e.upload_file_to_java){u.warning("当前桌面端未提供文件夹选择或上传能力");return}try{const t=await e.select_brand_folder();if(!t)return;const n=await bt(t);if(!n.success||!n.items?.length){u.warning(n.error||"该文件夹下没有可用的 xlsx 文件");return}const l=await fe(n.items);C.value=l,M.value=n.items.map(s=>s.relativePath||s.absolutePath),k.value=null,I.value=null,m.value="",u.success(`已选择文件夹内 ${n.items.length} 个 Excel 文件`)}catch(t){u.error(t instanceof Error?t.message:"选择失败")}}async function ee(){try{b.value=await ct();const e=new Set(b.value.map(t=>t.id));_.value!=null&&!e.has(_.value)&&(_.value=null)}catch(e){u.error(e instanceof Error?e.message:"加载筛选条件失败")}}async function $e(){const e=S.value.trim();if(!e){u.warning("请输入筛选条件");return}K.value=!0;try{const t=await dt(e);await ee(),t?.id&&(_.value=t.id),u.success("筛选条件已保存")}catch(t){u.error(t instanceof Error?t.message:"保存筛选条件失败")}finally{K.value=!1}}function Be(e){S.value=e.conditionText||""}async function Ge(e){try{await ft(e),_.value===e&&(_.value=null),await ee(),u.success("筛选条件已删除")}catch(t){u.error(t instanceof Error?t.message:"删除筛选条件失败")}}async function Le(){if(!C.value.length){u.warning("请先选择 Excel");return}const e=ue();if(!e){u.warning("请输入筛选条件,或在备选区选择一个筛选条件");return}if(!O()){u.warning("请先在左上角设置中填写货源查询密钥");return}V.value=!0;try{const t=C.value.map(l=>({fileKey:l.fileKey,originalFilename:l.originalFilename,relativePath:l.relativePath})),n=await vt(t,e,O());k.value=n,I.value=null,m.value="",u.success(`解析完成,共 ${n.acceptedRows} 条`)}catch(t){u.error(t instanceof Error?t.message:"解析失败")}finally{V.value=!1}}async function He(){const e=H(),t=k.value,n=t?.taskId;if(!n){u.warning("请先解析文件");return}if(!e?.enqueue_json){u.error("当前环境未启用 pywebview enqueue_json");return}if(!O()){u.warning("请先在左上角设置中填写货源查询密钥");return}z.value=!0;try{const l={type:"similar-asin-run",ts:Date.now(),data:{taskId:n,prompt:t.aiPrompt||ue(),api_key:O(),sourceFileCount:t.sourceFileCount||0,totalRows:t.totalRows||0,acceptedRows:t.acceptedRows||0,groupCount:t.groupCount||0}};m.value=JSON.stringify(Ne(l),null,2),await pt(n);const s=await e.enqueue_json(l);if(!s?.success){u.error(s?.error||"推送失败");return}I.value=xe(t),je(n),Me(),await J(),await Q({force:!0}),u.success("已推送到 Python 队列")}finally{z.value=!1}}function Me(){k.value=null,m.value=""}function je(e){v.value.includes(e)||(v.value=[...v.value,e],w()),D()}function te(e){v.value=v.value.filter(t=>t!==e),w()}function qe(e){f.value.includes(e)||(f.value=[...f.value,e],w()),D()}function se(e){f.value=f.value.filter(t=>t!==e),w()}function D(){N||g.value==null&&Ve(!0)}function ve(){g.value!=null&&(R.clearTimer("task-poll",g.value),g.value=null)}function Ve(e=!1){if(N)return;if(g.value!=null){if(!e)return;R.clearTimer("task-poll",g.value),g.value=null}const t=async()=>{g.value=null,!N&&(!v.value.length&&!f.value.length||(await ze(),!N&&g.value==null&&(v.value.length||f.value.length)&&(g.value=R.setTimeout("task-poll",t,Ce()))))};e?t():g.value=R.setTimeout("task-poll",t,Ce())}async function ze(){if(Y.value||!v.value.length&&!f.value.length){!v.value.length&&!f.value.length&&ve();return}Y.value=!0;try{let e=!1,t=!1;const n=Array.from(new Set([...v.value,...f.value]));if(n.length){const l=await wt(n,{force:f.value.length>0});for(const s of l.items||[]){const c=s.task;if(!c?.id)continue;const y=s.items?.[0];if(y&&Ke(y),(c.status==="SUCCESS"||c.status==="FAILED")&&(te(c.id),e=!0,c.status==="SUCCESS"?qe(c.id):se(c.id)),y&&c.status==="SUCCESS"&&f.value.includes(c.id)){const ke=(y.fileStatus||"").toUpperCase();(y.fileReady||ke==="SUCCESS"||ke==="FAILED")&&(se(c.id),e=!0,t=!0)}}l.missingTaskIds?.length&&(l.missingTaskIds.forEach(s=>{te(s),se(s)}),t=!0,e=!0)}e&&await J(),t&&await Q(),Oe()}finally{Y.value=!1}}function Ke(e){if(!e.taskId&&!e.resultId)return;const t=p.value.findIndex(n=>e.resultId!=null&&n.resultId===e.resultId||e.taskId!=null&&n.taskId===e.taskId);t>=0?p.value[t]={...p.value[t],...e}:p.value=[e,...p.value]}function Oe(){if(!f.value.length)return;const e=[];for(const t of f.value){const n=p.value.find(c=>c.taskId===t);if(!n){e.push(t);continue}const l=(n.taskStatus||"").toUpperCase(),s=(n.fileStatus||"").toUpperCase();l==="FAILED"||n.fileReady||s==="SUCCESS"||s==="FAILED"||l==="SUCCESS"&&e.push(t)}f.value=e,w(),f.value.length&&D()}function Je(){const e=p.value.filter(t=>t.taskId!=null&&U(t)).map(t=>t.taskId);f.value=Array.from(new Set(e)),w(),f.value.length&&D()}async function J(){x.value=await gt()}async function Q(e={}){const t=Date.now();if(!(!e.force&&p.value.length&&t-oe<Us))return E||(E=yt().then(n=>{p.value=n.items||[],oe=Date.now()}).finally(()=>{E=null}),E)}function pe(e){const t=$(e);return t==="RUNNING"?"执行中":t==="PENDING"?"已解析待推送":U(e)?"结果生成中":ae(e)?"结果生成失败":t==="SUCCESS"||e.success?"已完成":t==="FAILED"?"失败":"等待中"}function Qe(e){const t=$(e);return t==="RUNNING"||U(e)?"running":ae(e)||t==="FAILED"?"failed":t==="SUCCESS"||e.success?"success":"pending"}function U(e){const t=$(e),n=(e.fileStatus||"").toUpperCase();return!(t!=="SUCCESS"||ye(e)||n==="FAILED"||n==="SUCCESS")}function $(e){return(e.taskStatus||"").toUpperCase()}function ae(e){return(e.fileStatus||"").toUpperCase()==="FAILED"}function ge(e){if(ae(e))return e.fileError||"结果文件生成失败,请稍后重试或检查后端日志";if(!U(e))return"";const t=(e.fileStatus||"").toUpperCase();return t==="RUNNING"?"任务已完成,正在等待 Coze 回流并组装结果文件,下载按钮稍后出现":t==="PENDING"?"任务已完成,结果文件已入队,正在等待后端开始处理":"任务已完成,正在生成结果文件,下载按钮稍后出现"}function ye(e){return!!(e.resultId&&(e.fileReady||e.downloadUrl))}function he(e){const t=Number(e.fileProgressPercent||0);return Number.isFinite(t)?Math.max(0,Math.min(100,Math.round(t))):0}function Ye(e){return U(e)&&(e.fileProgressTotal||0)>0}async function We(e){if(!e.resultId)return;const t=H();if(!t?.save_file_from_url_new){u.error("当前客户端未提供下载能力");return}const n=e.downloadUrl||ht(e.resultId),l=e.resultFilename||`${e.sourceFilename||"similar-asin"}.xlsx`,s=await t.save_file_from_url_new(n,l);s.success?u.success(`已保存: ${s.path||l}`):s.error&&s.error!=="用户取消"&&u.error(s.error)}async function _e(e){try{e.taskStatus==="RUNNING"&&e.taskId?(await _t(e.taskId),te(e.taskId)):e.resultId&&await kt(e.resultId),await J(),await Q({force:!0}),u.success("已删除")}catch(t){u.error(t instanceof Error?t.message:"删除失败")}}return Ze(async()=>{Ae(),await Promise.all([ee().catch(()=>{}),ce().catch(()=>{}),J().catch(()=>{}),Q().catch(()=>{})]),Je(),(v.value.length||f.value.length)&&D()}),et(()=>{N=!0,ve(),R.clearScope()}),(e,t)=>{const n=it,l=rt;return o(),i("div",Pt,[me(tt,{active:"similar-asin"}),a("div",Ft,[a("aside",Et,[t[8]||(t[8]=a("div",{class:"section-title"},"上传文件",-1)),a("div",Nt,[t[4]||(t[4]=a("div",{class:"hint"},"选择 Excel 后点击解析,后端会提取 id、ASIN、国家、价格,每一行都会独立送检。",-1)),a("div",{class:"btns"},[a("button",{type:"button",class:"opt-btn",onClick:De},"选择 Excel"),a("button",{type:"button",class:"opt-btn",onClick:Ue},"选择文件夹")]),a("div",Rt,[M.value.length?(o(!0),i(B,{key:1},G(M.value,s=>(o(),i("span",{key:s},r(s),1))),128)):(o(),i("span",xt,"暂未选择文件"))])]),a("div",At,[t[5]||(t[5]=a("div",{class:"section-title"},"筛选条件",-1)),we(a("textarea",{"onUpdate:modelValue":t[0]||(t[0]=s=>S.value=s),class:"prompt-input",rows:"4",placeholder:"请输入筛选条件"},null,512),[[st,S.value]]),a("div",Dt,[a("button",{type:"button",class:"opt-btn",disabled:K.value,onClick:$e},r(K.value?"保存中...":"保存"),9,Ut)]),t[6]||(t[6]=a("div",{class:"section-title condition-list-title"},"备选区",-1)),b.value.length?(o(),i("ul",Bt,[(o(!0),i(B,null,G(b.value,s=>(o(),i("li",{key:s.id,class:"condition-item"},[a("label",Gt,[we(a("input",{"onUpdate:modelValue":t[1]||(t[1]=c=>_.value=c),type:"radio",name:"similar-asin-filter-condition",value:s.id,onChange:c=>Be(s)},null,40,Lt),[[at,_.value]]),a("span",{title:s.conditionText},r(s.conditionText),9,Ht)]),a("button",{type:"button",class:"link-danger",onClick:c=>Ge(s.id)},"删除",8,Mt)]))),128))])):(o(),i("div",$t,"暂无筛选条件,输入后保存即可加入备选区"))]),a("div",jt,[a("div",qt,[t[7]||(t[7]=a("div",{class:"section-title"},"商品类目",-1)),a("div",Vt,[a("button",{type:"button",class:"opt-btn",onClick:be},"选择类目"),T.value.length?(o(),i("button",{key:0,type:"button",class:"link-danger",onClick:Fe}," 清空 ")):h("",!0)])]),X.value.length?(o(),i("div",Kt,[(o(!0),i(B,null,G(X.value,s=>(o(),i("span",{key:s.id,class:"category-chip"},r(s.path||s.name),1))),128))])):(o(),i("div",zt,"暂未选择商品类目"))]),a("div",Ot,[a("button",{type:"button",class:"btn-run",disabled:V.value||!C.value.length,onClick:Le},r(V.value?"解析中...":"解析并创建任务"),9,Jt),a("button",{type:"button",class:"btn-run btn-queue",disabled:z.value||!k.value?.taskId,onClick:He},r(z.value?"推送中...":"推送到 Python 队列"),9,Qt)]),t[9]||(t[9]=a("p",{class:"loading-msg"},"Python 回传字段按 id、asin、国家、价格、标题、图片链接数组提交;后端接收分片后按 10 条一批送检,结果区展示真实 Coze 批次进度。",-1)),A.value?(o(),i("div",Yt,[a("div",null,"任务 ID:"+r(A.value.taskId),1),a("div",null,"总行数:"+r(A.value.totalRows)+",有效:"+r(A.value.acceptedRows)+",过滤:"+r(A.value.droppedRows),1)])):h("",!0),m.value?(o(),i("pre",Wt,r(m.value),1)):h("",!0)]),a("section",Xt,[t[17]||(t[17]=a("div",{class:"panel-header"},"货源查询",-1)),a("div",Zt,[a("div",es,[a("div",ts,[t[10]||(t[10]=a("span",{class:"summary-label"},"运行中任务",-1)),a("strong",null,r(x.value.pendingTaskCount),1)]),a("div",ss,[t[11]||(t[11]=a("span",{class:"summary-label"},"已结束任务",-1)),a("strong",null,r(x.value.processedTaskCount),1)]),a("div",as,[t[12]||(t[12]=a("span",{class:"summary-label"},"成功任务",-1)),a("strong",null,r(x.value.successTaskCount),1)]),a("div",ns,[t[13]||(t[13]=a("span",{class:"summary-label"},"失败任务",-1)),a("strong",null,r(x.value.failedTaskCount),1)])]),t[16]||(t[16]=a("div",{class:"subsection-title"},"匹配任务",-1)),a("div",ls,[t[14]||(t[14]=a("div",{class:"result-list-header"},[a("span",null,"当前任务")],-1)),ie.value.length?(o(),i("ul",is,[(o(!0),i(B,null,G(ie.value,s=>(o(),i("li",{key:`cur-${s.taskId}`,class:"task-item"},[a("div",rs,[a("span",us,r(s.sourceFilename||"货源查询"),1),a("div",cs,"任务 ID:"+r(s.taskId),1),a("div",ds,"行数:"+r(s.rowCount??"-"),1)]),a("div",fs,[a("span",vs,r(pe(s)),1),a("button",{type:"button",class:"btn-delete",onClick:c=>_e(s)},"删除",8,ps)])]))),128))])):(o(),i("div",os,"暂无当前任务"))]),a("div",gs,[t[15]||(t[15]=a("div",{class:"result-list-header"},[a("span",null,"历史记录")],-1)),re.value.length?(o(),i("ul",hs,[(o(!0),i(B,null,G(re.value,s=>(o(),i("li",{key:`his-${s.resultId}-${s.taskId}`,class:"task-item"},[a("div",_s,[a("span",ks,r(s.sourceFilename||"货源查询"),1),a("div",ms,"任务 ID:"+r(s.taskId??"-"),1),s.resultFilename?(o(),i("div",ws,r(s.resultFilename||"下载结果"),1)):h("",!0),ge(s)?(o(),i("div",Cs,r(ge(s)),1)):h("",!0),Ye(s)?(o(),i("div",Is,[a("div",Ss,[a("span",null,r(s.fileProgressMessage||"结果生成中"),1),a("span",null,r(he(s))+"%",1)]),a("div",bs,[a("div",{class:"file-progress-bar",style:nt({width:`${he(s)}%`})},null,4)]),a("div",Ts,r(s.fileProgressCurrent||0)+"/"+r(s.fileProgressTotal||0),1)])):h("",!0),s.error?(o(),i("div",Ps,"错误:"+r(s.error),1)):h("",!0)]),a("div",Fs,[a("span",{class:lt(["status",Qe(s)])},r(pe(s)),3),ye(s)?(o(),i("button",{key:0,type:"button",class:"download",onClick:c=>We(s)},"下载",8,Es)):h("",!0),s.resultId?(o(),i("button",{key:1,type:"button",class:"btn-delete",onClick:c=>_e(s)},"删除",8,Ns)):h("",!0)])]))),128))])):(o(),i("div",ys,"暂无历史记录"))])])])]),me(l,{modelValue:P.value,"onUpdate:modelValue":t[3]||(t[3]=s=>P.value=s),title:"选择商品类目",width:"560px",class:"category-dialog"},{footer:ne(()=>[a("button",{type:"button",class:"opt-btn",onClick:t[2]||(t[2]=s=>P.value=!1)},"取消"),a("button",{type:"button",class:"btn-run category-confirm",onClick:Te},"确定")]),default:ne(()=>[a("div",{class:"category-dialog-toolbar"},[t[18]||(t[18]=a("span",{class:"muted"},"可多选,确认后会追加到筛选条件 prompt 后面。",-1)),a("button",{type:"button",class:"link-danger",onClick:Pe},"清空选择")]),q.value?(o(),i("div",Rs,"正在加载商品类目...")):j.value.length?(o(),ot(n,{key:2,ref_key:"categoryTreeRef",ref:F,class:"category-tree",data:j.value,"node-key":"id","show-checkbox":"","default-expand-all":"",props:{label:"name",children:"children"}},{default:ne(({data:s})=>[a("span",As,[a("span",null,r(s.name),1),s.description?(o(),i("span",Ds,r(s.description),1)):h("",!0)])]),_:1},8,["data"])):(o(),i("div",xs,"暂无商品类目"))]),_:1},8,["modelValue"])])}}}),Bs=Ct($s,[["__scopeId","data-v-597fff27"]]);It(Bs).use(St).mount("#app");
|