From 3e3bd025834848ed4132e1f2817d3d12731c3718 Mon Sep 17 00:00:00 2001
From: dzc <2388224167@qq.com>
Date: Thu, 22 Oct 2026 19:22:28 +0800
Subject: [PATCH] =?UTF-8?q?feat:=E6=B5=81=E6=B0=B4=E9=94=99=E8=AF=AF?=
=?UTF-8?q?=E4=BF=AE=E6=94=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/views/hard/hard-dept-total/index.vue | 35 +++++-----
.../hard-sh/components/hard-sh-by-day.vue | 57 +++++++++-------
.../hard-sh/components/hard-sh-by-month.vue | 29 ++++-----
src/views/hard/hard-sh/index.vue | 21 ++++--
tests/hard-ledger-statistics.test.cjs | 65 +++++++++++++++++++
tests/hard-sh-query-lifecycle.test.cjs | 34 +++++++++-
6 files changed, 176 insertions(+), 65 deletions(-)
create mode 100644 tests/hard-ledger-statistics.test.cjs
diff --git a/src/views/hard/hard-dept-total/index.vue b/src/views/hard/hard-dept-total/index.vue
index 5793705..e10e47c 100644
--- a/src/views/hard/hard-dept-total/index.vue
+++ b/src/views/hard/hard-dept-total/index.vue
@@ -16,9 +16,13 @@
-
+
+
+
+
+ value-format="YYYY-MM-DD HH:mm:ss" type="datetimerange"
+ start-placeholder="开始时间(含)" end-placeholder="结束时间(不含)" />
{{ $t("common.queryBtn")
@@ -209,7 +213,6 @@ import { submitDepartmentExport as submitBatchExport } from "/@/api/hard/hard-to
import { BasicTableProps, useTable } from "/@/hooks/table"
import { displayPrice } from "/@/utils/formatMoney"
-import { useDict } from "/@/hooks/dict"
import * as hardTotalApi from "/@/api/hard/hard-total"
import dayjs from "dayjs"
@@ -221,8 +224,7 @@ const selectObjs = ref([]) as any
const multiple = ref(true)
const draggableDepTreeRef = ref() // 树组件ref引用
-/** 部门列说明每行数据的统计范围。 */
-const departmentHeaderTip = "每行显示一个部门,后面的金额和次数都是该部门在查询时间内的数据。"
+const transactionTimeTip = "按钱包流水的交易时间统计,包含开始时间,不包含结束时间。例如,统计 9 月可选择 9 月 1 日 00:00:00 到 10 月 1 日 00:00:00。"
/** 批量充值金额说明批量入账金额的计算方式。 */
const batchRechargeAmountHeaderTip = "通过批量充值给该部门人员增加的金额合计。"
/** 批量充值次数说明按人员入账记录计次。 */
@@ -243,18 +245,15 @@ const singleDeductionCountHeaderTip = "单次扣减产生的扣款记录数,
const returnCanteenAmountHeaderTip = "批量退还余额时,退回该部门人员各自所属食堂的金额合计。"
/** 退还食堂次数说明按人员退还记录计次。 */
const returnCanteenCountHeaderTip = "批量退还余额产生的记录数;同一次操作涉及多人时,每个人的退还记录各算 1 次。"
-/** 流水金额说明支付订单原始金额的统计范围。 */
-const payAmountHeaderTip = "查询时间内创建且已支付的订单金额合计;退款金额另行显示,不会从这里扣除。"
-/** 流水次数说明已支付订单的计次方式。 */
-const payCountHeaderTip = "查询时间内创建且已支付的订单数量,同一笔订单算 1 次。"
-/** 退款金额说明按退款完成时间统计。 */
-const refundAmountHeaderTip = "查询时间内已经完成退款的金额合计,按退款完成时间统计。"
-/** 退款次数说明按已完成退款记录计次。 */
-const refundCountHeaderTip = "查询时间内已经完成的退款记录数;一笔订单有多次退款时,每次完成的退款各算 1 次。"
+/** 支付和退款都按钱包流水的交易时间统计。 */
+const payAmountHeaderTip = "所选交易时间内的钱包支付流水金额合计;退款金额单独显示,不会从这里扣除。"
+const payCountHeaderTip = "所选交易时间内的钱包支付流水记录数,每条流水算 1 次;同一订单使用多个钱包支付时分别计次。"
+const refundAmountHeaderTip = "所选交易时间内的钱包退款流水金额合计,包含非订单退款。"
+const refundCountHeaderTip = "所选交易时间内的钱包退款流水记录数,每条流水算 1 次,包含非订单退款。"
/** 消费净金额说明支付与退款的相减关系。 */
-const netAmountHeaderTip = "流水金额减去退款金额。订单按创建时间统计,退款按完成时间统计;只选到退款的时间段时,结果可能为负数。"
-/** 消费净次数说明支付订单与退款记录的相减关系。 */
-const netCountHeaderTip = "流水次数减去退款次数。退款次数按退款记录计算,一笔订单多次退款会分别扣减。"
+const netAmountHeaderTip = "流水金额减去退款金额。支付和退款分别按各自钱包流水的交易时间统计,结果可能为负数。"
+/** 消费净次数说明支付流水与退款流水的相减关系。 */
+const netCountHeaderTip = "钱包支付流水次数减去钱包退款流水次数,每条流水分别计次,结果可能为负数。"
const defaultCreateTimeList = [
dayjs().subtract(3, "month").startOf("day").format("YYYY-MM-DD HH:mm:ss"),
@@ -270,7 +269,7 @@ const state: BasicTableProps = reactive({
})
// table hook
-const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, tableStyle } = useTable(state)
+const { getDataList, sortChangeHandle, tableStyle } = useTable(state)
// 导出excel
/** 当前页面只声明原导出场景,进度及重复提交由公共 hook 管理。 */
@@ -281,7 +280,7 @@ const { exportProgressRef, exportTaskConfig, submitExport, handleExportSuccess,
const exportExcel = () => submitExport({ ...state.queryForm })
-const cellClassName = ({ row, column, rowIndex }: any) => {
+const cellClassName = ({ column }: any) => {
if (column.property) {
if (column.property.includes("Count")) {
return 'success-cell'
diff --git a/src/views/hard/hard-sh/components/hard-sh-by-day.vue b/src/views/hard/hard-sh/components/hard-sh-by-day.vue
index 278d1ca..ec6c8bc 100644
--- a/src/views/hard/hard-sh/components/hard-sh-by-day.vue
+++ b/src/views/hard/hard-sh/components/hard-sh-by-day.vue
@@ -5,7 +5,11 @@
@selection-change="selectionChangHandle" @sort-change="sortChangeHandle">
-
+
+
+ {{ row.merchantName || (row.merchantId == null ? "未归属商户" : row.merchantId) }}
+
+
@@ -76,15 +80,23 @@
-
-
- 商户结账
-
+
+
+
+ 商户结账
+
+
+
+
+
+
+ 导出商户流水
+
+
-
- 导出商户流水
-
@@ -99,18 +111,15 @@ import * as hardTotalApi from "/@/api/hard/hard-total"
const { push } = useRouter()
-/** 流水金额说明已支付订单原始金额的统计方式。 */
-const payAmountHeaderTip = "所选时间内完成支付的订单金额合计;退款金额另行显示,不会从这里扣除。"
-/** 流水次数说明已支付订单的计次方式。 */
-const payCountHeaderTip = "所选时间内完成支付的订单数量,同一笔订单算 1 次。"
-/** 退款金额说明按退款完成时间统计。 */
-const refundAmountHeaderTip = "所选时间内已经完成退款的金额合计,按退款完成时间统计。"
-/** 退款次数说明按已完成退款记录计次。 */
-const refundCountHeaderTip = "所选时间内已经完成的退款记录数;一笔订单有多次退款时,每次完成的退款各算 1 次。"
+/** 支付和退款都按钱包流水的交易时间统计。 */
+const payAmountHeaderTip = "所选交易时间内的钱包支付流水金额合计;退款金额单独显示,不会从这里扣除。"
+const payCountHeaderTip = "所选交易时间内的钱包支付流水记录数,每条流水算 1 次;同一订单使用多个钱包支付时分别计次。"
+const refundAmountHeaderTip = "所选交易时间内的钱包退款流水金额合计,包含非订单退款;未归属商户的流水也计入合计。"
+const refundCountHeaderTip = "所选交易时间内的钱包退款流水记录数,每条流水算 1 次,包含非订单退款。"
/** 消费净金额说明支付与退款的相减关系。 */
-const netAmountHeaderTip = "流水金额减去退款金额。付款和退款分别按完成时间统计;只选到退款的时间段时,结果可能为负数。"
-/** 消费净次数说明支付订单与退款记录的相减关系。 */
-const netCountHeaderTip = "流水次数减去退款次数。退款次数按退款记录计算,一笔订单多次退款会分别扣减。"
+const netAmountHeaderTip = "流水金额减去退款金额。支付和退款分别按各自钱包流水的交易时间统计,结果可能为负数。"
+/** 消费净次数说明支付流水与退款流水的相减关系。 */
+const netCountHeaderTip = "钱包支付流水次数减去钱包退款流水次数,每条流水分别计次,结果可能为负数。"
const state: BasicTableProps = reactive({
createdIsNeed: false,
@@ -120,17 +129,19 @@ const state: BasicTableProps = reactive({
})
// table hook
-const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, postDownBlobFile, tableStyle } = useTable(state)
+const { getDataList, sortChangeHandle, postDownBlobFile, tableStyle } = useTable(state)
// 多选变量
const selectObjs = ref([]) as any
const multiple = ref(true)
const doCheckout = (row: any) => {
+ if (row.merchantId == null || row.merchantType != 2) return
push({ path: "/mch/mch-checkout/index", query: { mchId: row.merchantId } })
}
const exportMchExcel = (row: any) => {
+ if (row.merchantId == null) return
postDownBlobFile("/hard/hard-total/export-mch-cs", { ...state.queryForm, merchantId: row.merchantId }, "商户流水.xlsx")
}
@@ -149,7 +160,7 @@ const getSummaries = (param: any) => {
if (totalColumns.includes(i.property)) {
const total = data
.filter((v: any) => v[i.property] != null)
- .map((v: any) => v[i.property])
+ .map((v: any) => Number(v[i.property]))
.reduce((pren: number, next: number) => pren + next, 0)
if (i.property.includes("Price")) {
totalRow[index] = displayPrice(total)
@@ -176,4 +187,4 @@ defineExpose({
doSearch,
doCancel
})
-
\ No newline at end of file
+
diff --git a/src/views/hard/hard-sh/components/hard-sh-by-month.vue b/src/views/hard/hard-sh/components/hard-sh-by-month.vue
index 861997c..5a0d814 100644
--- a/src/views/hard/hard-sh/components/hard-sh-by-month.vue
+++ b/src/views/hard/hard-sh/components/hard-sh-by-month.vue
@@ -7,7 +7,7 @@
- {{ row.merchantName || row.merchantId }}
+ {{ row.merchantName || (row.merchantId == null ? "未归属商户" : row.merchantId) }}
@@ -90,18 +90,15 @@ import { displayPrice } from "/@/utils/formatMoney"
import * as hardTotalApi from "/@/api/hard/hard-total"
-/** 流水金额说明已支付订单原始金额的统计方式。 */
-const payAmountHeaderTip = "所选月份内完成支付的订单金额合计;退款金额另行显示,不会从这里扣除。"
-/** 流水次数说明已支付订单的计次方式。 */
-const payCountHeaderTip = "所选月份内完成支付的订单数量,同一笔订单算 1 次。"
-/** 退款金额说明按退款完成时间统计。 */
-const refundAmountHeaderTip = "所选月份内已经完成退款的金额合计,按退款完成时间归属月份。"
-/** 退款次数说明按已完成退款记录计次。 */
-const refundCountHeaderTip = "所选月份内已经完成的退款记录数;一笔订单有多次退款时,每次完成的退款各算 1 次。"
+/** 支付和退款都按钱包流水的交易时间归属月份。 */
+const payAmountHeaderTip = "所选月份内的钱包支付流水金额合计;退款金额单独显示,不会从这里扣除。"
+const payCountHeaderTip = "所选月份内的钱包支付流水记录数,每条流水算 1 次;同一订单使用多个钱包支付时分别计次。"
+const refundAmountHeaderTip = "所选月份内的钱包退款流水金额合计,包含非订单退款;未归属商户的流水也计入合计。"
+const refundCountHeaderTip = "所选月份内的钱包退款流水记录数,每条流水算 1 次,包含非订单退款。"
/** 消费净金额说明支付与退款的相减关系。 */
-const netAmountHeaderTip = "流水金额减去退款金额。付款按支付月份、退款按退款完成月份统计;只选到退款的月份时,结果可能为负数。"
-/** 消费净次数说明支付订单与退款记录的相减关系。 */
-const netCountHeaderTip = "流水次数减去退款次数。退款次数按退款记录计算,一笔订单多次退款会分别扣减。"
+const netAmountHeaderTip = "流水金额减去退款金额。支付和退款分别按各自钱包流水的交易时间归属月份,结果可能为负数。"
+/** 消费净次数说明支付流水与退款流水的相减关系。 */
+const netCountHeaderTip = "钱包支付流水次数减去钱包退款流水次数,每条流水分别计次,结果可能为负数。"
const state: BasicTableProps = reactive({
createdIsNeed: false,
@@ -114,7 +111,7 @@ const selectObjs = ref([]) as any
const multiple = ref(true)
// table hook
-const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, postDownBlobFile, tableStyle } = useTable(state)
+const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, tableStyle } = useTable(state)
// 多选事件
const selectionChangHandle = (objs: { id: string }[]) => {
@@ -126,12 +123,12 @@ const getSummaries = (param: any) => {
const { columns, data } = param
const totalColumns = ["totalPayPrice", "totalPayCount", "totalRefundPrice", "totalRefundCount", "totalProfitPrice", "totalProfitCount", "mchPlatformRankePrice"]
const totalRow = Array.from({ length: columns.length })
- totalRow[0] = "合计"
+ totalRow[0] = "本页合计"
columns.forEach((i: any, index: number) => {
if (totalColumns.includes(i.property)) {
const total = data
.filter((v: any) => v[i.property] != null)
- .map((v: any) => v[i.property])
+ .map((v: any) => Number(v[i.property]))
.reduce((pren: number, next: number) => pren + next, 0)
if (i.property.includes("Price")) {
totalRow[index] = displayPrice(total)
@@ -158,4 +155,4 @@ defineExpose({
doSearch,
doCancel
})
-
\ No newline at end of file
+
diff --git a/src/views/hard/hard-sh/index.vue b/src/views/hard/hard-sh/index.vue
index d08c83f..ea58acb 100644
--- a/src/views/hard/hard-sh/index.vue
+++ b/src/views/hard/hard-sh/index.vue
@@ -26,12 +26,15 @@
-
+
+
+
+ type="datetimerange" start-placeholder="开始时间(含)" end-placeholder="结束时间(不含)" />
-
@@ -100,6 +103,7 @@ const tabPane = ref([
}
])
const activeTab = ref("MCH")
+const transactionTimeTip = "按钱包流水的交易时间统计,包含开始时间,不包含结束时间。例如,统计 9 月可选择 9 月 1 日 00:00:00 到 10 月 1 日 00:00:00。"
const defaultCreateTimeList = [
dayjs().subtract(3, "month").startOf("day").format("YYYY-MM-DD HH:mm:ss"),
@@ -134,17 +138,22 @@ const { exportProgressRef, exportTaskConfig, submitExport, handleExportSuccess,
})
const exportExcel = () => {
+ normalizeTimeQuery()
exportTaskConfig.redisKey = activeTab.value === "MONTH" ? "hard:export:merchant-month" : "hard:export:merchant"
return submitExport({ ...state.queryForm })
}
-const search = () => {
+const normalizeTimeQuery = () => {
if (activeTab.value === "MCH") {
state.queryForm.payTimeYearStr = ""
}
if (activeTab.value === "MONTH") {
- state.queryForm.createTimeList = []
+ state.queryForm.payTimeList = []
}
+}
+
+const search = () => {
+ normalizeTimeQuery()
switch (activeTab.value) {
case "MCH":
hardShByDayRef.value?.doSearch(state.queryForm)
@@ -157,7 +166,7 @@ const search = () => {
const cancel = () => {
state.queryForm = { ...defaultQueryForm }
- console.log("state.queryForm:", state.queryForm);
+ normalizeTimeQuery()
switch (activeTab.value) {
case "MCH":
diff --git a/tests/hard-ledger-statistics.test.cjs b/tests/hard-ledger-statistics.test.cjs
new file mode 100644
index 0000000..4cc185e
--- /dev/null
+++ b/tests/hard-ledger-statistics.test.cjs
@@ -0,0 +1,65 @@
+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], "本页合计")
+ })
+}
diff --git a/tests/hard-sh-query-lifecycle.test.cjs b/tests/hard-sh-query-lifecycle.test.cjs
index 21298f3..3155ef1 100644
--- a/tests/hard-sh-query-lifecycle.test.cjs
+++ b/tests/hard-sh-query-lifecycle.test.cjs
@@ -16,6 +16,7 @@ const compiled = ts.transpileModule(source, {
function mountPage() {
const requests = []
+ const exportQueries = []
const child = (kind) => vue.defineComponent({
setup(_, { expose }) {
const query = (params) => requests.push({ kind, params: JSON.parse(JSON.stringify(params)) })
@@ -30,7 +31,7 @@ function mountPage() {
if (id.includes("hard-sh-by-month.vue")) return month
if (id.endsWith("AsyncTaskProgress.vue")) return {}
if (id.includes("hooks/batchExport")) return {
- useBatchExport: () => ({ exportTaskConfig: {}, submitExport() {}, handleExportSuccess() {}, handleExportFailure() {} }),
+ useBatchExport: () => ({ exportTaskConfig: {}, submitExport: query => exportQueries.push(JSON.parse(JSON.stringify(query))), handleExportSuccess() {}, handleExportFailure() {} }),
}
if (id.includes("api/hard/hard-total")) return {}
return require(id)
@@ -69,7 +70,7 @@ function mountPage() {
})
const app = renderer.createApp(host)
app.mount({ children: [] })
- return { bindings, requests, close: () => app.unmount() }
+ return { bindings, requests, exportQueries, close: () => app.unmount() }
}
async function settle() {
@@ -100,10 +101,39 @@ test("切换日/月子表每次只查询一次,查询条件重置后再发送"
assert.equal(page.requests[1].kind, "month")
assert.equal(page.requests[1].params.merchantId, undefined)
assert.match(page.requests[1].params.payTimeYearStr, /^\d{4}$/)
+ assert.deepEqual(page.requests[1].params.payTimeList, [])
page.bindings.activeTab.value = "MCH"
await settle()
assert.equal(page.requests.length, 3)
assert.equal(page.requests[2].kind, "day")
+ assert.equal(page.requests[2].params.payTimeYearStr, "")
+ assert.equal(page.requests[2].params.payTimeList.length, 2)
+ } finally { page.close() }
+})
+
+test("按月重置和导出清除隐藏日范围,按商户导出保留精确时间边界", async () => {
+ const page = mountPage()
+ try {
+ await settle()
+ page.bindings.activeTab.value = "MONTH"
+ await settle()
+ page.bindings.cancel()
+ assert.deepEqual(page.requests.at(-1).params.payTimeList, [])
+ assert.match(page.requests.at(-1).params.payTimeYearStr, /^\d{4}$/)
+ page.bindings.state.queryForm.payTimeList = ["2026-09-01 00:00:00", "2026-10-01 00:00:00"]
+ page.bindings.exportExcel()
+ assert.deepEqual(page.exportQueries[0].payTimeList, [])
+ assert.equal(page.bindings.exportTaskConfig.redisKey, "hard:export:merchant-month")
+ page.bindings.activeTab.value = "MCH"
+ await settle()
+ const timeRange = ["2026-09-01 00:00:00", "2026-10-01 00:00:00"]
+ Object.assign(page.bindings.state.queryForm, { payTimeList: timeRange, payTimeYearStr: "2025", userDeptIds: ["1875013738914156546"], isInclude: false })
+ page.bindings.exportExcel()
+ assert.deepEqual(page.exportQueries[1].payTimeList, timeRange)
+ assert.equal(page.exportQueries[1].payTimeYearStr, "")
+ assert.deepEqual(page.exportQueries[1].userDeptIds, ["1875013738914156546"])
+ assert.equal(page.exportQueries[1].isInclude, false)
+ assert.equal(page.bindings.exportTaskConfig.redisKey, "hard:export:merchant")
} finally { page.close() }
})