2 lines
18 KiB
JavaScript
2 lines
18 KiB
JavaScript
import{d as qe,o as je,M as Oe,a as i,c,b as Ve,B as We,e as a,F as se,r as te,t as r,w as Ye,H as Qe,f as _,O as ke,n as Xe,g as v,h as j,i as O,E as p,W as Ze,X as es,Y as ss,V as Ie,Z as ts,$ as as,a0 as ns,s as ls,a1 as rs,a2 as os,a3 as _e,a4 as us,_ as is,q as cs,u as ds}from"./java-modules-WSWRTEaR.js";import{e as fs}from"./brand-5GpfAyHD.js";import{c as ps}from"./categorized-timers-JPA-olTr.js";const vs={class:"page-shell module-page"},gs={class:"main-content"},hs={class:"left-panel"},ys={class:"upload-zone"},ks={class:"selected-files"},Is={key:0},_s={class:"prompt-card"},Ps={class:"run-row"},ws=["disabled"],Cs=["disabled"],Ss={key:0,class:"parse-card"},bs={key:1,class:"queue-payload"},ms={class:"right-panel"},Fs={class:"task-list-wrap"},Ns={class:"clean-result-summary"},Ts={class:"summary-card"},Rs={class:"summary-card"},As={class:"summary-card"},Es={class:"summary-card"},xs={class:"result-list-wrap"},Us={key:0,class:"empty-tasks"},Ds={key:1,class:"task-list clean-result-list"},$s={class:"left"},Ms={class:"id"},zs={class:"files"},Gs={class:"files"},Ls={class:"files"},Bs={class:"files"},Hs={key:0,class:"files result-hint"},Ks={key:1,class:"file-progress"},Js={class:"file-progress-meta"},qs={class:"file-progress-track"},js={class:"task-right"},Os={class:"status running"},Vs=["onClick"],Ws={class:"result-list-wrap"},Ys={key:0,class:"empty-tasks"},Qs={key:1,class:"task-list clean-result-list"},Xs={class:"left"},Zs={class:"id"},et={class:"files"},st={class:"files"},tt={class:"files"},at={key:0,class:"files"},nt={key:1,class:"files result-hint"},lt={key:2,class:"file-progress"},rt={class:"file-progress-meta"},ot={class:"file-progress-track"},ut={key:3,class:"files"},it={class:"task-right"},ct=["onClick"],dt=["onClick"],ft=3e3,pt=qe({__name:"BrandAppearancePatentTab",setup(gt){const D=v([]),N=v([]),P=v(null),T=v(null),$=v(""),M=v(!1),z=v(!1),C=v(""),f=v([]),u=v([]),h=v(null),V=v(!1);let R=null,ae=0,A=!1;const E=ps("appearance-patent"),x=v({pendingTaskCount:0,processedTaskCount:0,successTaskCount:0,failedTaskCount:0}),g=v([]),w=v({}),m=j(()=>P.value||T.value),W=j(()=>{const e=P.value;return!e?.taskId||g.value.some(t=>t.taskId===e.taskId)?null:{taskId:e.taskId,sourceFilename:e.sourceFilename,rowCount:e.acceptedRows,taskStatus:"PENDING",success:!1}}),ne=j(()=>{const e=new Set([...f.value,...u.value]),s=g.value.filter(n=>{const l=k(n);return n.taskId!=null&&(e.has(n.taskId)||l==="RUNNING"||l==="PENDING")}).map(n=>re(n));for(const[n,l]of Object.entries(w.value)){const o=Number(n);!Number.isFinite(o)||o<=0||!e.has(o)&&k(l)!=="RUNNING"&&k(l)!=="PENDING"||s.some(d=>d.taskId===o)||s.push(re(l))}return W.value?s.some(n=>n.taskId===W.value?.taskId)?s:[W.value,...s]:s}),le=j(()=>g.value.filter(e=>{const s=k(e);return s!=="RUNNING"&&s!=="PENDING"}));function re(e){if(e.taskId==null)return e;const s=w.value[e.taskId];return s?{...e,...s,sourceFilename:s.sourceFilename||e.sourceFilename,resultFilename:s.resultFilename||e.resultFilename,rowCount:s.rowCount??e.rowCount,createdAt:s.createdAt||e.createdAt}:e}function Pe(){return $.value.trim()}function we(){return $.value.trim()}function G(){return _e("appearance-patent").trim()}function oe(){return _e("appearance-patent-token").trim()}function Ce(){return typeof window<"u"&&window.localStorage.getItem("uid")||"0"}function Y(){return`appearance-patent:tasks:${Ce()}`}function Se(e){return{taskId:e.taskId,totalRows:e.totalRows,acceptedRows:e.acceptedRows,groupCount:e.groupCount,droppedRows:e.droppedRows}}function S(){if(typeof window>"u")return;const e=Array.from(new Set([...f.value,...u.value]));e.length?window.localStorage.setItem(Y(),JSON.stringify(e)):window.localStorage.removeItem(Y())}function be(){if(!(typeof window>"u"))try{const e=window.localStorage.getItem(Y()),s=e?JSON.parse(e):[];f.value=Array.isArray(s)?s.filter(t=>typeof t=="number"&&t>0):[]}catch{f.value=[]}}function L(e){if(!e)return"-";const s=new Date(e);if(Number.isNaN(s.getTime()))return e;const t=s.getFullYear(),n=String(s.getMonth()+1).padStart(2,"0"),l=String(s.getDate()).padStart(2,"0"),o=String(s.getHours()).padStart(2,"0"),d=String(s.getMinutes()).padStart(2,"0"),y=String(s.getSeconds()).padStart(2,"0");return`${t}-${n}-${l} ${o}:${d}:${y}`}async function ue(e){const s=O();if(!s?.upload_file_to_java)throw new Error("当前桌面端未提供文件上传能力");const t=[];for(const n of e){const l=typeof n=="string"?n:n.absolutePath,o=typeof n=="string"?void 0:n.relativePath,d=await s.upload_file_to_java(l,o);if(!d?.success||!d.data)throw new Error(d?.error||d?.message||`上传失败:${l}`);t.push(d.data)}return t}async function me(){const e=O();if(!e?.select_brand_xlsx_files||!e.upload_file_to_java){p.warning("当前环境不支持文件选择或上传");return}const s=await e.select_brand_xlsx_files();if(!s?.length)return;const t=await ue(s);N.value=t,D.value=t.map(n=>n.relativePath||n.originalFilename||n.fileKey),P.value=null,T.value=null,C.value=""}async function Fe(){const e=O();if(!e?.select_brand_folder){p.warning("当前环境不支持文件夹选择,请在本地客户端中打开");return}try{const s=await e.select_brand_folder();if(!s)return;const t=await fs(s);if(!t.success||!t.items?.length){p.warning(t.error||"该文件夹下没有可用的 xlsx 文件");return}const n=await ue(t.items);N.value=n,D.value=t.items.map(l=>l.relativePath||l.absolutePath),P.value=null,T.value=null,C.value="",p.success(`已选择文件夹内 ${t.items.length} 个 Excel 文件`)}catch(s){p.error(s instanceof Error?s.message:"选择失败")}}async function Ne(){if(!N.value.length){p.warning("请先选择 Excel");return}if(!G()){p.warning("请先在左上角设置中填写外观专利密钥");return}M.value=!0;try{const e=N.value.map(t=>({fileKey:t.fileKey,originalFilename:t.originalFilename,relativePath:t.relativePath})),s=await Ze(e,Pe(),G(),oe());P.value=s,T.value=null,C.value="",p.success(`解析完成,共 ${s.groupCount||0} 组 / ${s.acceptedRows} 条`)}catch(e){p.error(e instanceof Error?e.message:"解析失败")}finally{M.value=!1}}async function Te(){const e=O(),s=P.value,t=s?.taskId;if(!t){p.warning("请先解析文件");return}if(!e?.enqueue_json){p.error("当前环境未启用 pywebview enqueue_json");return}if(!G()){p.warning("请先在左上角设置中填写外观专利密钥");return}z.value=!0;try{const l=(await es(t)).groups||[],o={type:"appearance-patent-run",ts:Date.now(),data:{taskId:t,prompt:we(),api_key:G(),patent_token:oe(),sourceFileCount:s.sourceFileCount||0,totalRows:s.totalRows||0,acceptedRows:s.acceptedRows||0,groupCount:s.groupCount||0,groups:l.map(y=>({sourceFileKey:y.sourceFileKey||"",sourceFilename:y.sourceFilename||"",groupKey:y.groupKey||"",baseId:y.baseId||"",displayId:y.displayId||"",items:(y.items||[]).map(I=>({sourceFileKey:I.sourceFileKey||"",sourceFilename:I.sourceFilename||"",rowToken:I.rowToken||"",groupKey:I.groupKey||"",id:I.displayId,asin:I.asin,country:I.country,sku:I.sku||"",url:I.url||"",title:I.title||""}))}))}};C.value=`任务 ${t} 已准备推送,共 ${l.length} 组`,await ss(t);const d=await e.enqueue_json(o);if(!d?.success){p.error(d?.error||"推送失败");return}T.value=Se(s),Ae(t),Re(),await B(),await H({force:!0}),p.success("已推送到 Python 队列")}finally{z.value=!1}}function Re(){P.value=null,C.value=""}function Ae(e){f.value.includes(e)||(f.value=[...f.value,e],S()),F()}function Q(e){if(f.value=f.value.filter(s=>s!==e),!u.value.includes(e)){const s={...w.value};delete s[e],w.value=s}S()}function Ee(e){u.value.includes(e)||(u.value=[...u.value,e],S()),F()}function X(e){if(u.value=u.value.filter(s=>s!==e),!f.value.includes(e)){const s={...w.value};delete s[e],w.value=s}S()}function F(){A||h.value==null&&xe(!0)}function ie(){h.value!=null&&(E.clearTimer("task-poll",h.value),h.value=null)}function xe(e=!1){if(A)return;if(h.value!=null){if(!e)return;E.clearTimer("task-poll",h.value),h.value=null}const s=async()=>{h.value=null,!A&&(!f.value.length&&!u.value.length||(await Ue(),!A&&h.value==null&&(f.value.length||u.value.length)&&(h.value=E.setTimeout("task-poll",s,Ie()))))};e?s():h.value=E.setTimeout("task-poll",s,Ie())}async function Ue(){if(V.value||!f.value.length&&!u.value.length){!f.value.length&&!u.value.length&&ie();return}V.value=!0;try{let e=!1,s=!1;const t=Array.from(new Set([...f.value,...u.value]));if(t.length){const n=await us(t,{force:u.value.length>0});for(const l of n.items||[]){const o=l.task;if(!o?.id)continue;const d=l.items?.[0];if(d&&(w.value={...w.value,[o.id]:d},De(d)),(o.status==="SUCCESS"||o.status==="FAILED")&&(Q(o.id),e=!0,d&&b(d)?Ee(o.id):X(o.id)),d&&(o.status==="SUCCESS"||o.status==="FAILED")&&u.value.includes(o.id)){const y=(d.fileStatus||"").toUpperCase();(d.fileReady||y==="SUCCESS"||y==="FAILED")&&(X(o.id),e=!0,s=!0)}}n.missingTaskIds?.length&&(n.missingTaskIds.forEach(l=>{Q(l),X(l)}),s=!0,e=!0)}e&&await B(),s&&await H(),$e()}finally{V.value=!1}}function De(e){if(!e.taskId&&!e.resultId)return;const s=g.value.findIndex(t=>e.resultId!=null&&t.resultId===e.resultId||e.taskId!=null&&t.taskId===e.taskId);s>=0?g.value[s]={...g.value[s],...e}:g.value=[e,...g.value]}function $e(){if(!u.value.length)return;const e=[];for(const s of u.value){const t=g.value.find(o=>o.taskId===s);if(!t){e.push(s);continue}const n=(t.taskStatus||"").toUpperCase(),l=(t.fileStatus||"").toUpperCase();t.fileReady||l==="SUCCESS"||l==="FAILED"||(n==="SUCCESS"||n==="FAILED")&&e.push(s)}u.value=e,S(),u.value.length&&F()}function Me(){const e=g.value.filter(s=>s.taskId!=null&&b(s)).map(s=>s.taskId);u.value=Array.from(new Set(e)),S(),u.value.length&&F()}function ze(){const e=g.value.filter(s=>s.taskId!=null&&k(s)==="RUNNING").map(s=>s.taskId);e.length&&(f.value=Array.from(new Set([...f.value,...e])),S(),F())}async function B(){x.value=await ts()}async function H(e={}){const s=Date.now();if(!(!e.force&&g.value.length&&s-ae<ft))return R||(R=as().then(t=>{g.value=Ge(g.value,t.items||[]),ae=Date.now()}).finally(()=>{R=null}),R)}function Ge(e,s){const t=new Map,n=new Map;for(const l of e||[])l.taskId!=null&&t.set(l.taskId,l),l.resultId!=null&&n.set(l.resultId,l);return(s||[]).map(l=>{const o=l.resultId!=null?n.get(l.resultId):l.taskId!=null?t.get(l.taskId):void 0;return Le(o,l)})}function Le(e,s){return!e||!((k(e)==="RUNNING"||b(e)||U(e))&&!U(s)&&!J(s))?s:{...s,fileJobId:s.fileJobId??e.fileJobId,fileStatus:s.fileStatus||e.fileStatus,fileError:s.fileError||e.fileError,fileReady:s.fileReady||e.fileReady,fileProgressPercent:Z(s.fileProgressPercent)?s.fileProgressPercent:e.fileProgressPercent,fileProgressCurrent:Z(s.fileProgressCurrent)?s.fileProgressCurrent:e.fileProgressCurrent,fileProgressTotal:Z(s.fileProgressTotal)?s.fileProgressTotal:e.fileProgressTotal,fileProgressMessage:(s.fileProgressMessage||"").trim()?s.fileProgressMessage:e.fileProgressMessage}}function Z(e){const s=Number(e);return Number.isFinite(s)&&s>0}function ce(e){const s=k(e);return s==="RUNNING"?"执行中":s==="PENDING"?"已解析待推送":b(e)?"结果生成中":ee(e)?"结果生成失败":de(e)||s==="SUCCESS"||e.success?"已完成":s==="FAILED"?"失败":"等待中"}function Be(e){const s=k(e);return s==="RUNNING"||b(e)?"running":de(e)?"success":ee(e)||s==="FAILED"?"failed":s==="SUCCESS"||e.success?"success":"pending"}function b(e){const s=k(e),t=(e.fileStatus||"").toUpperCase();return s!=="SUCCESS"&&s!=="FAILED"||J(e)||t==="FAILED"||t==="SUCCESS"?!1:s==="SUCCESS"||ge(e)}function k(e){return(e.taskStatus||"").toUpperCase()}function ee(e){return(e.fileStatus||"").toUpperCase()==="FAILED"}function K(e){if(ee(e))return e.fileError||"结果文件生成失败,请稍后重试或检查后端日志";if(U(e)||!b(e))return"";const s=(e.fileStatus||"").toUpperCase();return s==="RUNNING"?"任务已完成,正在等待 Coze 回流并组装结果文件,下载按钮稍后出现":s==="PENDING"?"任务已完成,结果文件已入队,正在等待后端开始处理":"任务已完成,正在生成结果文件,下载按钮稍后出现"}function J(e){return!!(e.resultId&&(e.fileReady||e.downloadUrl))}function de(e){return J(e)}function q(e){const s=Number(e.fileProgressPercent||0);return Number.isFinite(s)&&s>0?Math.max(0,Math.min(100,Math.round(s))):he(e)?ve(e)==="PENDING"?6:10:0}function fe(e,s){const t=(e.fileProgressMessage||"").trim();return t?He(t):s}function He(e){const s=e.match(/^Coze submitted (\d+) batches, completed (\d+), waiting for results$/);if(s)return`已提交 Coze ${s[1]} 批,已完成 ${s[2]} 批,等待结果回流`;const t=e.match(/^Coze completed (\d+) batches, waiting for remaining Python data$/);return t?`Coze 已完成 ${t[1]} 批,等待 Python 继续回传数据`:{"Receiving Python data, waiting for 50 rows before Coze":"正在接收 Python 数据,累计 50 条后提交 Coze","Submitting Coze":"正在提交 Coze","Coze submitted, waiting for result":"Coze 已提交,等待结果回流","Waiting for Python upload":"等待 Python 继续回传数据","Coze results ready, assembling xlsx":"Coze 结果已回流,正在组装 xlsx","Assembling xlsx":"正在组装 xlsx","Uploading result file":"正在上传结果文件","Result file generated":"结果文件已生成"}[e]||e}function U(e){return(k(e)==="RUNNING"||b(e))&&(pe(e)||he(e))}function pe(e){return Ke(e)||Number(e.fileProgressPercent||0)>0||!!(e.fileProgressMessage||"").trim()}function Ke(e){return(e.fileProgressTotal||0)>0}function ve(e){return(e.fileStatus||"").toUpperCase()}function ge(e){const s=ve(e);return e.fileJobId!=null||s==="PENDING"||s==="RUNNING"}function he(e){return ge(e)&&!pe(e)}async function Je(e){if(!e.resultId)return;const s=e.downloadUrl||ns(e.resultId),t=e.resultFilename||`${e.sourceFilename||"appearance-patent"}.xlsx`,n=await ls(s,t,`appearance-patent:${e.resultId}`);n.success?p.success(`已保存: ${n.path||t}`):n.error&&n.error!=="用户取消"&&p.error(n.error)}async function ye(e){try{e.taskStatus==="RUNNING"&&e.taskId?(await rs(e.taskId),Q(e.taskId)):e.resultId&&await os(e.resultId),await B(),await H({force:!0}),p.success("已删除")}catch(s){p.error(s instanceof Error?s.message:"删除失败")}}return je(async()=>{be(),await Promise.all([B().catch(()=>{}),H().catch(()=>{})]),ze(),Me(),(f.value.length||u.value.length)&&F()}),Oe(()=>{A=!0,ie(),E.clearScope()}),(e,s)=>(i(),c("div",vs,[Ve(We,{active:"appearance-patent"}),a("div",gs,[a("aside",hs,[s[3]||(s[3]=a("div",{class:"section-title"},"上传文件",-1)),a("div",ys,[s[1]||(s[1]=a("div",{class:"hint"},"选择 Excel 后点击解析,后端会提取 id、ASIN、国家,并保留整数 id 与子数据的第一条。",-1)),a("div",{class:"btns"},[a("button",{type:"button",class:"opt-btn",onClick:me},"选择 Excel"),a("button",{type:"button",class:"opt-btn",onClick:Fe},"选择文件夹")]),a("div",ks,[D.value.length?(i(!0),c(se,{key:1},te(D.value,t=>(i(),c("span",{key:t},r(t),1))),128)):(i(),c("span",Is,"暂未选择文件"))])]),a("div",_s,[s[2]||(s[2]=a("div",{class:"section-title"},"新增条件要求",-1)),Ye(a("textarea",{"onUpdate:modelValue":s[0]||(s[0]=t=>$.value=t),class:"prompt-input",rows:"8",placeholder:"可选,留空则不向 Coze 传 prompt 字段;填写后将作为 prompt 透传"},null,512),[[Qe,$.value]])]),a("div",Ps,[a("button",{type:"button",class:"btn-run",disabled:M.value||!N.value.length,onClick:Ne},r(M.value?"解析中...":"解析并创建任务"),9,ws),a("button",{type:"button",class:"btn-run btn-queue",disabled:z.value||!P.value?.taskId,onClick:Te},r(z.value?"推送中...":"推送到 Python 队列"),9,Cs)]),s[4]||(s[4]=a("p",{class:"loading-msg"},"Python 回传字段按 asin、国家、url、标题提交;后端接收分片后累计 50 条调用 Coze,当前任务区展示 Coze 回流和结果组装进度。",-1)),m.value?(i(),c("div",Ss,[a("div",null,"任务 ID:"+r(m.value.taskId),1),a("div",null,"总行数:"+r(m.value.totalRows)+",有效:"+r(m.value.acceptedRows)+",分组:"+r(m.value.groupCount||0)+",过滤:"+r(m.value.droppedRows),1)])):_("",!0),C.value?(i(),c("pre",bs,r(C.value),1)):_("",!0)]),a("section",ms,[s[12]||(s[12]=a("div",{class:"panel-header"},"外观专利检测",-1)),a("div",Fs,[a("div",Ns,[a("div",Ts,[s[5]||(s[5]=a("span",{class:"summary-label"},"运行中任务",-1)),a("strong",null,r(x.value.pendingTaskCount),1)]),a("div",Rs,[s[6]||(s[6]=a("span",{class:"summary-label"},"已结束任务",-1)),a("strong",null,r(x.value.processedTaskCount),1)]),a("div",As,[s[7]||(s[7]=a("span",{class:"summary-label"},"成功任务",-1)),a("strong",null,r(x.value.successTaskCount),1)]),a("div",Es,[s[8]||(s[8]=a("span",{class:"summary-label"},"失败任务",-1)),a("strong",null,r(x.value.failedTaskCount),1)])]),s[11]||(s[11]=a("div",{class:"subsection-title"},"匹配任务",-1)),a("div",xs,[s[9]||(s[9]=a("div",{class:"result-list-header"},[a("span",null,"当前任务")],-1)),ne.value.length?(i(),c("ul",Ds,[(i(!0),c(se,null,te(ne.value,t=>(i(),c("li",{key:`cur-${t.taskId}`,class:"task-item"},[a("div",$s,[a("span",Ms,r(t.sourceFilename||"外观专利检测"),1),a("div",zs,"任务 ID:"+r(t.taskId),1),a("div",Gs,"开始时间:"+r(L(t.startedAt||t.createdAt)),1),a("div",Ls,"结束时间:"+r(L(t.finishedAt)),1),a("div",Bs,"行数:"+r(t.rowCount??"-"),1),K(t)?(i(),c("div",Hs,r(K(t)),1)):_("",!0),U(t)?(i(),c("div",Ks,[a("div",Js,[a("span",null,r(fe(t,"处理中")),1),a("span",null,r(q(t))+"%",1)]),a("div",qs,[a("div",{class:"file-progress-bar",style:ke({width:`${q(t)}%`})},null,4)])])):_("",!0)]),a("div",js,[a("span",Os,r(ce(t)),1),a("button",{type:"button",class:"btn-delete",onClick:n=>ye(t)},"删除",8,Vs)])]))),128))])):(i(),c("div",Us,"暂无当前任务"))]),a("div",Ws,[s[10]||(s[10]=a("div",{class:"result-list-header"},[a("span",null,"历史记录")],-1)),le.value.length?(i(),c("ul",Qs,[(i(!0),c(se,null,te(le.value,t=>(i(),c("li",{key:`his-${t.resultId}-${t.taskId}`,class:"task-item"},[a("div",Xs,[a("span",Zs,r(t.sourceFilename||"外观专利检测"),1),a("div",et,"任务 ID:"+r(t.taskId??"-"),1),a("div",st,"开始时间:"+r(L(t.startedAt||t.createdAt)),1),a("div",tt,"结束时间:"+r(L(t.finishedAt)),1),t.resultFilename?(i(),c("div",at,r(t.resultFilename||"下载结果"),1)):_("",!0),K(t)?(i(),c("div",nt,r(K(t)),1)):_("",!0),U(t)?(i(),c("div",lt,[a("div",rt,[a("span",null,r(fe(t,"结果生成中")),1),a("span",null,r(q(t))+"%",1)]),a("div",ot,[a("div",{class:"file-progress-bar",style:ke({width:`${q(t)}%`})},null,4)])])):_("",!0),t.error?(i(),c("div",ut,"错误:"+r(t.error),1)):_("",!0)]),a("div",it,[a("span",{class:Xe(["status",Be(t)])},r(ce(t)),3),J(t)?(i(),c("button",{key:0,type:"button",class:"download",onClick:n=>Je(t)},"下载",8,ct)):_("",!0),t.resultId?(i(),c("button",{key:1,type:"button",class:"btn-delete",onClick:n=>ye(t)},"删除",8,dt)):_("",!0)])]))),128))])):(i(),c("div",Ys,"暂无历史记录"))])])])])]))}}),vt=is(pt,[["__scopeId","data-v-aad32577"]]);cs(vt).use(ds).mount("#app");
|