Files
crawler-plugin/app/assets/split.js

2 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { d as q, o as G, a, c as n, b as L, B as O, e, F as x, r as I, t as i, f, n as F, w as C, u as V, G as M, g as d, h as Q, i as E, E as r, H as W, I as X, p as Y, v as Z, J as ss, K as es, _ as ts, q as ls, s as as } from "./pywebview-C66x_2Dh.js"; import { e as ns } from "./brand-BZije8D7.js"; const os = { class: "page-shell module-page" }, is = { class: "main-content" }, rs = { class: "left-panel" }, us = { class: "upload-zone" }, ds = { class: "selected-files clean-placeholder split-selected-files" }, cs = { key: 0, class: "more-line" }, ps = { key: 1 }, vs = { class: "option-group column-option-group" }, fs = { class: "column-toolbar" }, _s = { class: "column-count" }, ms = { class: "column-actions" }, ys = { key: 0, class: "column-grid" }, gs = ["value"], hs = { key: 1, class: "empty-column-state" }, bs = { class: "option-group" }, ws = { class: "radio-item active" }, ks = { class: "desc" }, Cs = { class: "option-group" }, Ss = { class: "option-group" }, xs = { key: 0, class: "split-input-card" }, Fs = { key: 1, class: "split-input-card" }, Es = { class: "run-row" }, Ps = ["disabled"], $s = { class: "loading-msg" }, Is = { class: "right-panel" }, Rs = { class: "task-list-wrap" }, Bs = { class: "clean-result-summary" }, Us = { class: "summary-card" }, Vs = { class: "summary-card" }, Ms = { class: "summary-card" }, Ts = { class: "result-list-wrap" }, Ds = { key: 0, class: "empty-tasks" }, Hs = { key: 1, class: "task-list clean-result-list" }, Ks = { class: "left split-result-main" }, Ns = ["title"], js = { key: 0, class: "files" }, As = { key: 1, class: "time" }, zs = { key: 2, class: "files" }, Js = { key: 3, class: "files split-entry-list" }, qs = { key: 4, class: "files" }, Gs = { class: "task-right split-result-actions" }, Ls = ["onClick"], Os = ["onClick"], Qs = q({ __name: "BrandSplitTab", setup(Xs) { const _ = d([]), S = d(""), c = d([]), m = d([]), p = d([]), R = d(0), u = d("rows_per_file"), y = d(2e3), g = d(5), h = d(!1), b = d([]), w = d({ total: 0, successCount: 0, failedCount: 0, items: [] }), P = Q(() => _.value.slice(0, 8)); function T(l) { w.value = { total: l.length, successCount: l.filter(s => s.success).length, failedCount: l.filter(s => !s.success).length, items: l } } async function B(l) { const s = E(); if (!s?.upload_file_to_java) throw new Error("当前桌面端未提供文件上传桥接能力"); const t = []; for (const o of l) { const v = typeof o == "string" ? o : o.absolutePath, J = typeof o == "string" ? void 0 : o.relativePath, k = await s.upload_file_to_java(v, J); if (!k?.success || !k.data) throw new Error(k?.error || k?.message || `上传失败:${v}`); t.push(k.data) } return t } async function U(l) { const s = await Y(l); m.value = s.headers || [], p.value = [...s.headers || []], R.value = s.totalRows || 0 } async function D(l, s) { _.value = l, S.value = "", c.value = await B(l), c.value.length > 0 && await U(c.value[0].fileKey), r.success(s) } async function H() { const l = E(); if (!l?.select_brand_xlsx_files) { r.warning("当前环境不支持文件选择,请在本机客户端中打开"); return } try { const s = await l.select_brand_xlsx_files(); if (!s?.length) return; await D(s, `已选择 ${s.length} 个待拆分文件`) } catch (s) { r.error(s instanceof Error ? s.message : "选择失败") } } async function K() { const l = E(); if (!l?.select_brand_folder) { r.warning("当前环境不支持文件夹选择,请在本机客户端中打开"); return } try { const s = await l.select_brand_folder(); if (!s) return; S.value = s.split(/[/\\]/).filter(Boolean).pop() || ""; const t = await ns(s); if (t.success && t.items?.length) { _.value = t.items.map(o => o.relativePath), c.value = await B(t.items), c.value.length > 0 && await U(c.value[0].fileKey), r.success(`已选择文件夹内 ${t.items.length} 个 xlsx 文件`); return } r.warning(t.error || "该文件夹下没有 xlsx 文件") } catch (s) { r.error(s instanceof Error ? s.message : "选择失败") } } async function N() { if (!c.value.length) { r.warning("请先选择待拆分 Excel 文件或文件夹"); return } if (!p.value.length) { r.warning("请至少选择一列保留列"); return } if (u.value === "rows_per_file" && (!y.value || y.value <= 0)) { r.warning("请输入有效的每份条数"); return } if (u.value === "parts" && (!g.value || g.value <= 0)) { r.warning("请输入有效的拆分份数"); return } try { h.value = !0; const l = await W({ files: c.value.map(s => ({ fileKey: s.fileKey, originalFilename: s.originalFilename, relativePath: s.relativePath })), selectedColumns: p.value, splitMode: u.value, rowsPerFile: u.value === "rows_per_file" && y.value || void 0, parts: u.value === "parts" && g.value || void 0, archiveName: c.value.some(s => !!s.relativePath) && S.value ? S.value : void 0 }); w.value = l, b.value = l.items || [], await $(), r.success("数据拆分完成") } catch (l) { r.error(l instanceof Error ? l.message : "数据拆分失败") } finally { h.value = !1 } } async function $() { try { const l = await X(); b.value = l.items || [], T(b.value) } catch { } } async function j(l) { try { await ss(l), await $(), r.success("已删除") } catch (s) { r.error(s instanceof Error ? s.message : "删除失败") } } function A(l) { const s = l.slice(0, 4).map(o => o.rowCount !== void 0 ? `${o.filename}${o.rowCount}条)` : o.filename); return l.length - s.length > 0 ? `${s.join("、")}${l.length} 个文件` : s.join("、") } async function z(l) { const s = E(), t = l.downloadUrl || (l.resultId ? es(l.resultId) : ""); if (!t) { r.warning("当前结果没有下载地址"); return } const o = l.outputFilename || `${new Date().toISOString().slice(0, 10).replace(/-/g, "")}.zip`; if (s?.save_file_from_url_new) { const v = await s.save_file_from_url_new(t, o); v.success ? r.success(`已保存:${v.path || o}`) : v.error && v.error !== "用户取消" && r.error(v.error); return } } return G(() => { $().catch(() => { }) }), (l, s) => (a(), n("div", os, [L(O, { active: "split" }), e("div", is, [e("aside", rs, [s[14] || (s[14] = e("div", { class: "section-title" }, "选择文件", -1)), e("div", us, [s[7] || (s[7] = e("div", { class: "hint" }, "选择需要拆分的 Excel 文件或文件夹,按规则拆成多个 Excel 文件。", -1)), e("div", { class: "btns" }, [e("button", { type: "button", class: "opt-btn", onClick: H }, "选择 Excel 文件"), e("button", { type: "button", class: "opt-btn", onClick: K }, "选择文件夹")]), e("div", ds, [_.value.length ? (a(), n(x, { key: 0 }, [(a(!0), n(x, null, I(P.value, t => (a(), n("span", { key: t }, i(t), 1))), 128)), _.value.length > P.value.length ? (a(), n("span", cs, " 还有 " + i(_.value.length - P.value.length) + " 个文件未展开显示 ", 1)) : f("", !0)], 64)) : (a(), n("span", ps, "暂未选择待拆分文件"))])]), s[15] || (s[15] = e("div", { class: "section-title" }, "保留列设置", -1)), e("div", vs, [e("div", fs, [e("span", _s, "已选择 " + i(p.value.length) + " / " + i(m.value.length) + " 列", 1), e("div", ms, [e("button", { type: "button", class: "opt-btn small", onClick: s[0] || (s[0] = t => p.value = [...m.value]) }, "全选"), e("button", { type: "button", class: "opt-btn small", onClick: s[1] || (s[1] = t => p.value = []) }, "清空")])]), m.value.length ? (a(), n("div", ys, [(a(!0), n(x, null, I(m.value, t => (a(), n("label", { key: t, class: F(["column-item", { active: p.value.includes(t) }]) }, [C(e("input", { "onUpdate:modelValue": s[2] || (s[2] = o => p.value = o), type: "checkbox", value: t }, null, 8, gs), [[Z, p.value]]), e("span", null, i(t), 1)], 2))), 128))])) : (a(), n("div", hs, "请选择 Excel 文件后读取表头并填充可保留列"))]), s[16] || (s[16] = e("div", { class: "section-title" }, "总条数", -1)), e("div", bs, [e("label", ws, [s[9] || (s[9] = e("input", { type: "checkbox", checked: "", disabled: "" }, null, -1)), e("div", null, [s[8] || (s[8] = e("span", { class: "label" }, "当前数据总条数", -1)), e("div", ks, i(R.value) + " 条(不含表头)", 1)])])]), s[17] || (s[17] = e("div", { class: "section-title" }, "拆分模式", -1)), e("div", Cs, [e("label", { class: F(["radio-item", { active: u.value === "rows_per_file" }]) }, [C(e("input", { "onUpdate:modelValue": s[3] || (s[3] = t => u.value = t), type: "radio", value: "rows_per_file", name: "split-mode" }, null, 512), [[V, u.value]]), s[10] || (s[10] = e("div", null, [e("span", { class: "label" }, "按每份条数"), e("div", { class: "desc" }, "例如每份 2000 条,最后一份放剩余数据")], -1))], 2), e("label", { class: F(["radio-item", { active: u.value === "parts" }]) }, [C(e("input", { "onUpdate:modelValue": s[4] || (s[4] = t => u.value = t), type: "radio", value: "parts", name: "split-mode" }, null, 512), [[V, u.value]]), s[11] || (s[11] = e("div", null, [e("span", { class: "label" }, "按份数平均拆分"), e("div", { class: "desc" }, "例如拆 5 份,按总条数尽量平均分配")], -1))], 2)]), s[18] || (s[18] = e("div", { class: "section-title" }, "拆分参数", -1)), e("div", Ss, [u.value === "rows_per_file" ? (a(), n("label", xs, [s[12] || (s[12] = e("span", { class: "label" }, "每份条数", -1)), C(e("input", { "onUpdate:modelValue": s[5] || (s[5] = t => y.value = t), class: "split-number-input", type: "number", min: "1", placeholder: "例如 2000" }, null, 512), [[M, y.value, void 0, { number: !0 }]])])) : (a(), n("label", Fs, [s[13] || (s[13] = e("span", { class: "label" }, "拆分份数", -1)), C(e("input", { "onUpdate:modelValue": s[6] || (s[6] = t => g.value = t), class: "split-number-input", type: "number", min: "1", placeholder: "例如 5" }, null, 512), [[M, g.value, void 0, { number: !0 }]])]))]), e("div", Es, [e("button", { type: "button", class: "btn-run", disabled: h.value, onClick: N }, i(h.value ? "拆分中..." : "开始拆分"), 9, Ps), e("span", $s, i(h.value ? "正在拆分并上传结果,请稍候…" : "选择文件、保留列和拆分规则后即可执行拆分,结果会显示在右侧供下载"), 1)])]), e("section", Is, [s[23] || (s[23] = e("div", { class: "panel-header" }, "拆分结果", -1)), e("div", Rs, [e("div", Bs, [e("div", Us, [s[19] || (s[19] = e("span", { class: "summary-label" }, "已处理文件", -1)), e("strong", null, i(w.value.total), 1)]), e("div", Vs, [s[20] || (s[20] = e("span", { class: "summary-label" }, "成功结果", -1)), e("strong", null, i(w.value.successCount), 1)]), e("div", Ms, [s[21] || (s[21] = e("span", { class: "summary-label" }, "失败文件", -1)), e("strong", null, i(w.value.failedCount), 1)])]), e("div", Ts, [s[22] || (s[22] = e("div", { class: "result-list-header" }, [e("span", null, "拆分结果压缩包列表")], -1)), b.value.length === 0 ? (a(), n("div", Ds, " 暂无拆分结果,完成数据拆分后会在这里展示压缩包文件 ")) : (a(), n("ul", Hs, [(a(!0), n(x, null, I(b.value, t => (a(), n("li", { key: `${t.resultId || t.outputFilename || t.sourceFilename}-${t.rowCount || 0}`, class: "task-item split-result-item" }, [e("div", Ks, [e("span", { class: "id", title: t.sourceFilename }, i(t.sourceFilename || "-"), 9, Ns), t.outputFilename ? (a(), n("div", js, "压缩包文件:" + i(t.outputFilename), 1)) : f("", !0), t.rowCount !== void 0 ? (a(), n("div", As, "压缩包共包含 " + i(t.rowCount) + " 条数据", 1)) : f("", !0), t.entryCount && t.entryCount > 0 ? (a(), n("div", zs, "压缩包内共 " + i(t.entryCount) + " 个拆分文件 ", 1)) : f("", !0), t.entries && t.entries.length ? (a(), n("div", Js, " 压缩包内容:" + i(A(t.entries)), 1)) : f("", !0), t.error ? (a(), n("div", qs, "错误信息:" + i(t.error), 1)) : f("", !0)]), e("div", Gs, [e("span", { class: F(["status", t.success ? "success" : "failed"]) }, i(t.success ? "已完成" : "失败"), 3), t.success && (t.downloadUrl || t.resultId) ? (a(), n("button", { key: 0, type: "button", class: "download", onClick: o => z(t) }, " 下载压缩包 ", 8, Ls)) : f("", !0), t.resultId ? (a(), n("button", { key: 1, type: "button", class: "btn-delete", onClick: o => j(t.resultId) }, " 删除 ", 8, Os)) : f("", !0)])]))), 128))]))])])])])])) } }), Ws = ts(Qs, [["__scopeId", "data-v-f3b42aa3"]]); ls(Ws).use(as).mount("#app");