const { test } = require("node:test") const assert = require("node:assert/strict") const fs = require("node:fs") const path = require("node:path") const ts = require("typescript") const vue = require("vue") const { parse, compileScript, compileTemplate } = require("@vue/compiler-sfc") const root = path.join(__dirname, "../src") function load(source, mocks, globals = {}) { const compiled = ts.transpileModule(source, { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2021 } }).outputText const mod = { exports: {} } new Function("module", "exports", "require", ...Object.keys(globals), compiled)(mod, mod.exports, key => key in mocks ? mocks[key] : require(key), ...Object.values(globals)) return mod.exports } function component(relativePath) { const filename = path.join(root, relativePath) const descriptor = parse(fs.readFileSync(filename, "utf8"), { filename }).descriptor assert.deepEqual(compileTemplate({ source: descriptor.template.content, filename, id: relativePath }).errors, []) const downloads = [], navigations = [] const money = load(fs.readFileSync(path.join(root, "utils/formatMoney.ts"), "utf8"), {}) const mod = load(compileScript(descriptor, { id: relativePath }).content, { vue, dayjs: { default: require("dayjs") }, "/@/hooks/table": { useTable: () => ({ tableStyle: {}, postDownBlobFile: (...args) => downloads.push(args) }) }, "/@/utils/formatMoney": money, "/@/api/hard/hard-total": {}, "/@/components/AsyncTaskProgress.vue": {}, "/@/hooks/batchExport": { useBatchExport: () => ({ exportTaskConfig: {} }) }, }, { ref: vue.ref, reactive: vue.reactive, useRouter: () => ({ push: value => navigations.push(value) }) }) return { bindings: mod.default.setup({}, { expose() {} }), downloads, navigations } } test("未归属商户无法结账或单独导出,有效商户导出保持原查询条件和接口", () => { const { bindings, downloads, navigations } = component("views/hard/hard-sh/components/hard-sh-by-day.vue") const query = { payTimeList: ["2026-09-01 00:00:00", "2026-10-01 00:00:00"], userDeptIds: ["1875013738914156546"], isInclude: false, walletTypeIdList: ["99"] } bindings.state.queryForm = query for (const merchantId of [null, undefined]) { bindings.doCheckout({ merchantId, merchantType: 2 }) bindings.exportMchExcel({ merchantId }) } bindings.doCheckout({ merchantId: "123", merchantType: 1 }) assert.deepEqual(downloads, []) assert.deepEqual(navigations, []) bindings.doCheckout({ merchantId: "123", merchantType: "2" }) assert.deepEqual(navigations, [{ path: "/mch/mch-checkout/index", query: { mchId: "123" } }]) bindings.exportMchExcel({ merchantId: "123" }) assert.deepEqual(downloads, [["/hard/hard-total/export-mch-cs", { ...query, merchantId: "123" }, "商户流水.xlsx"]]) assert.deepEqual(bindings.state.queryForm, query) }) for (const scene of ["day", "month", "dept"]) { test(`${scene} 合计保留未归属数据、负净额并正确累加字符串数值`, () => { const relativePath = scene === "dept" ? "views/hard/hard-dept-total/index.vue" : `views/hard/hard-sh/components/hard-sh-by-${scene}.vue` const { bindings } = component(relativePath) const fields = scene === "dept" ? ["orderPayPrice", "orderPayCount", "orderRefundPrice", "orderRefundCont", "orderProfitPrice", "orderProfitCont"] : ["totalPayPrice", "totalPayCount", "totalRefundPrice", "totalRefundCount", "totalProfitPrice", "totalProfitCount"] const columns = [{ property: "" }, ...fields.map(property => ({ property }))] const row = (merchantId, values) => ({ merchantId, ...Object.fromEntries(fields.map((field, index) => [field, values[index]])) }) const data = [row("123", ["10000", "2", 3000, 1, "7000", "1"]), row(null, [0, 0, "8000", "2", -8000, -2]), row("456", [null, null, null, null, null, null])] const result = bindings.getSummaries({ columns, data }) assert.deepEqual(result.slice(1), scene === "dept" ? ["100.00元", "2次", "110.00元", "3次", "-10.00元", "-1次"] : ["100.00元", 2, "110.00元", 3, "-10.00元", -1]) if (scene === "month") assert.equal(result[0], "本页合计") }) }