Files
crawler-plugin/app/assets/dedupe.js
2026-03-21 10:00:16 +08:00

2 lines
8.2 KiB
JavaScript

import{d as N,o as T,a,c as n,b as j,B as M,e as s,F as b,r as E,t as i,f as w,n as k,w as D,v as F,g as d,h as z,i as C,E as o,j as q,k as J,l as L,m as O,p as G,_ as Q,q as W,s as X}from"./pywebview-Rm5Hhqpf.js";const Y={class:"page-shell module-page"},Z={class:"main-content"},ee={class:"left-panel"},se={class:"upload-zone"},le={class:"selected-files clean-placeholder"},te={key:0,class:"more-line"},ae={key:1},ne={class:"option-group column-option-group"},oe={class:"column-toolbar"},re={class:"column-count"},ie={key:0,class:"column-grid"},ce=["value"],ue={key:1,class:"empty-column-state"},de={class:"option-group"},ve={class:"run-row"},pe=["disabled"],_e={class:"loading-msg"},fe={class:"right-panel"},me={class:"task-list-wrap"},ge={class:"clean-result-summary"},ye={class:"summary-card"},he={class:"summary-card"},be={class:"summary-card"},we={class:"result-list-wrap"},ke={key:0,class:"empty-tasks"},Ce={key:1,class:"task-list clean-result-list"},xe={class:"left"},Ie=["title"],Ee={key:0,class:"files"},De={key:1,class:"files"},Fe={class:"task-right"},Ue=["onClick"],Be=["onClick"],Se=N({__name:"BrandDedupeTab",setup(He){const v=d([]),u=d([]),p=d([]),_=d([]),f=d(!0),m=d(!0),g=d(!1),h=d([]),y=d({total:0,successCount:0,failedCount:0,items:[]}),x=z(()=>p.value.slice(0,8));function B(){u.value=[...v.value]}function S(){u.value=[]}async function $(t){const e=C();if(!e?.upload_file_to_java)throw new Error("当前桌面端未提供文件上传桥接能力");const l=[];for(const r of t){const c=await e.upload_file_to_java(r);if(!c?.success||!c.data)throw new Error(c?.error||c?.message||`上传失败:${r}`);l.push(c.data)}return l}async function H(t){const e=await G(t);if(!e.headers?.length){o.error("读取 Excel 表头失败"),v.value=[],u.value=[];return}const l=["id","ASIN","国家","价格","卖家名称"],r=[...l.filter(c=>e.headers?.includes(c)),...(e.headers||[]).filter(c=>!l.includes(c))];v.value=r,u.value=l.filter(c=>r.includes(c))}async function U(t,e){p.value=t,_.value=await $(t),_.value.length>0&&await H(_.value[0].fileKey),o.success(e)}async function A(){const t=C();if(!t?.select_brand_xlsx_files){o.warning("当前环境不支持文件选择,请在本机客户端中打开");return}try{const e=await t.select_brand_xlsx_files();if(!e?.length)return;await U(e,`已选择 ${e.length} 个待清洗文件`)}catch(e){o.error(e instanceof Error?e.message:"选择失败")}}async function V(){const t=C();if(!t?.select_brand_folder){o.warning("当前环境不支持文件夹选择,请在本机客户端中打开");return}try{const e=await t.select_brand_folder();if(!e)return;const l=await q(e);if(l.success&&l.paths?.length){await U(l.paths,`已选择文件夹内 ${l.paths.length} 个 xlsx 文件`);return}o.warning(l.error||"该文件夹下没有 xlsx 文件")}catch(e){o.error(e instanceof Error?e.message:"选择失败")}}async function K(){if(!_.value.length){o.warning("请先选择待清洗 Excel 文件或文件夹");return}if(!u.value.length){o.warning("请至少选择一列保留列");return}if(!f.value&&!m.value){o.warning("请至少选择一种 ID 保留规则");return}try{g.value=!0;const t=await J({files:_.value.map(e=>({fileKey:e.fileKey,originalFilename:e.originalFilename})),selectedColumns:u.value,keepIntegerIds:f.value,keepUnderscoreIds:m.value});y.value=t,h.value=t.items||[],await I(),o.success("数据去重完成")}catch(t){o.error(t instanceof Error?t.message:"去重失败")}finally{g.value=!1}}async function I(){try{const t=await L();h.value=t.items||[],y.value={total:t.items?.length||0,successCount:t.items?.filter(e=>e.success).length||0,failedCount:t.items?.filter(e=>!e.success).length||0,items:t.items||[]}}catch{}}async function P(t){try{await O(t),await I(),o.success("已删除")}catch(e){o.error(e instanceof Error?e.message:"删除失败")}}async function R(t){const e=C();if(!t.downloadUrl){o.warning("当前结果没有下载地址");return}const l=t.outputFilename||`${new Date().toISOString().slice(0,10).replace(/-/g,"")}_cleaned.xlsx`;if(e?.save_file_from_url){const r=await e.save_file_from_url(t.downloadUrl,l);r.success?o.success(`已保存:${r.path||l}`):r.error&&r.error!=="用户取消"&&o.error(r.error);return}window.open(t.downloadUrl,"_blank")}return T(()=>{I().catch(()=>{})}),(t,e)=>(a(),n("div",Y,[j(M,{active:"dedupe"}),s("div",Z,[s("aside",ee,[e[7]||(e[7]=s("div",{class:"section-title"},"选择文件",-1)),s("div",se,[e[3]||(e[3]=s("div",{class:"hint"},"选择需要清洗的 Excel 文件或文件夹,后续将按所选规则输出处理结果。",-1)),s("div",{class:"btns"},[s("button",{type:"button",class:"opt-btn",onClick:A},"选择 Excel 文件"),s("button",{type:"button",class:"opt-btn",onClick:V},"选择文件夹")]),s("div",le,[p.value.length?(a(),n(b,{key:0},[(a(!0),n(b,null,E(x.value,l=>(a(),n("span",{key:l},i(l),1))),128)),p.value.length>x.value.length?(a(),n("span",te," 还有 "+i(p.value.length-x.value.length)+" 个文件未展开显示 ",1)):w("",!0)],64)):(a(),n("span",ae,"暂未选择待清洗文件"))])]),e[8]||(e[8]=s("div",{class:"section-title"},"保留列设置",-1)),s("div",ne,[s("div",oe,[s("span",re,"已选择 "+i(u.value.length)+" / "+i(v.value.length)+" 列",1),s("div",{class:"column-actions"},[s("button",{type:"button",class:"opt-btn small",onClick:B},"全选"),s("button",{type:"button",class:"opt-btn small",onClick:S},"清空")])]),v.value.length?(a(),n("div",ie,[(a(!0),n(b,null,E(v.value,l=>(a(),n("label",{key:l,class:k(["column-item",{active:u.value.includes(l)}])},[D(s("input",{"onUpdate:modelValue":e[0]||(e[0]=r=>u.value=r),type:"checkbox",value:l},null,8,ce),[[F,u.value]]),s("span",null,i(l),1)],2))),128))])):(a(),n("div",ue,"请选择 Excel 文件后读取表头并填充可保留列")),e[4]||(e[4]=s("div",{class:"desc"},"读取首个 Excel 文件的第一行作为表头,用于动态选择需要保留的列。",-1))]),e[9]||(e[9]=s("div",{class:"section-title"},"ID 保留规则",-1)),s("div",de,[s("label",{class:k(["radio-item",{active:f.value}])},[D(s("input",{"onUpdate:modelValue":e[1]||(e[1]=l=>f.value=l),type:"checkbox"},null,512),[[F,f.value]]),e[5]||(e[5]=s("div",null,[s("span",{class:"label"},"保留整数 ID"),s("div",{class:"desc"},"例如 1、2、3 这种纯数字 ID")],-1))],2),s("label",{class:k(["radio-item",{active:m.value}])},[D(s("input",{"onUpdate:modelValue":e[2]||(e[2]=l=>m.value=l),type:"checkbox"},null,512),[[F,m.value]]),e[6]||(e[6]=s("div",null,[s("span",{class:"label"},"保留下划线 ID"),s("div",{class:"desc"},"例如 1_1、2_3 这种带下划线的子项 ID")],-1))],2)]),s("div",ve,[s("button",{type:"button",class:"btn-run",disabled:g.value,onClick:K},i(g.value?"清洗中...":"开始清洗"),9,pe),s("span",_e,i(g.value?"正在处理文件并上传结果,请稍候…":"选择文件、列和 ID 规则后即可执行清洗,结果会显示在右侧供下载"),1)])]),s("section",fe,[e[14]||(e[14]=s("div",{class:"panel-header"},"去重结果",-1)),s("div",me,[s("div",ge,[s("div",ye,[e[10]||(e[10]=s("span",{class:"summary-label"},"已处理文件",-1)),s("strong",null,i(y.value.total),1)]),s("div",he,[e[11]||(e[11]=s("span",{class:"summary-label"},"成功结果",-1)),s("strong",null,i(y.value.successCount),1)]),s("div",be,[e[12]||(e[12]=s("span",{class:"summary-label"},"失败文件",-1)),s("strong",null,i(y.value.failedCount),1)])]),s("div",we,[e[13]||(e[13]=s("div",{class:"result-list-header"},[s("span",null,"处理后的 Excel 列表")],-1)),h.value.length===0?(a(),n("div",ke," 暂无去重结果,完成数据去重后会在这里展示输出文件 ")):(a(),n("ul",Ce,[(a(!0),n(b,null,E(h.value,l=>(a(),n("li",{key:`${l.resultId||l.outputFilename||l.sourceFilename}`,class:"task-item"},[s("div",xe,[s("span",{class:"id",title:l.sourceFilename},i(l.sourceFilename||"-"),9,Ie),l.outputFilename?(a(),n("div",Ee,"输出文件:"+i(l.outputFilename),1)):l.error?(a(),n("div",De,"错误信息:"+i(l.error),1)):w("",!0)]),s("div",Fe,[s("span",{class:k(["status",l.success?"success":"failed"])},i(l.success?"已完成":"失败"),3),l.success&&l.downloadUrl?(a(),n("button",{key:0,type:"button",class:"download",onClick:r=>R(l)}," 下载文件 ",8,Ue)):w("",!0),l.resultId?(a(),n("button",{key:1,type:"button",class:"btn-delete",onClick:r=>P(l.resultId)}," 删除 ",8,Be)):w("",!0)])]))),128))]))])])])])]))}}),$e=Q(Se,[["__scopeId","data-v-09011d0a"]]);W($e).use(X).mount("#app");