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