diff --git a/modules/EcommerceFinance/AccountBillColumns.php b/modules/EcommerceFinance/AccountBillColumns.php index 12cf9a58..cf1e2d27 100644 --- a/modules/EcommerceFinance/AccountBillColumns.php +++ b/modules/EcommerceFinance/AccountBillColumns.php @@ -67,7 +67,7 @@ class AccountBillColumns ['店铺名称', 'store_name', 'text'], ['总账备注', 'payload.ledger_remark', 'text'], ['订单签收或退款时间', 'occurred_at', 'date'], - ['订单结算时间', 'payload.settle_period', 'date'], + ['账单期间', 'payload.settle_period', 'text'], ['订单类型名称', 'bill_item', 'text'], ['行类型名称', 'payload.vip_5', 'text'], ['售后类型名称', 'payload.vip_6', 'text'], @@ -107,7 +107,7 @@ class AccountBillColumns ['类型', 'bill_item', 'tag'], ['二次备注', 'payload.second_remark', 'text'], ['销售订单号', 'order_no', 'num'], - ['订单结算时间', 'payload.settle_period', 'date'], + ['账单期间', 'payload.settle_period', 'text'], ['订单日期(按订单号)', 'occurred_at', 'date'], ['含税金额', 'amount', 'money'], ['收入金额', 'income', 'money_in'], diff --git a/modules/EcommerceFinance/Http/Controllers/AccountBills.php b/modules/EcommerceFinance/Http/Controllers/AccountBills.php index 6caeeb14..822ea2aa 100644 --- a/modules/EcommerceFinance/Http/Controllers/AccountBills.php +++ b/modules/EcommerceFinance/Http/Controllers/AccountBills.php @@ -22,6 +22,13 @@ class AccountBills extends Controller /** 走共享业务镜像的账户类型(其余类型读本系统账单表 ec_account_bills)。 */ private const MIRROR_TABS = ['douyin', 'pinduoduo', 'dewu', 'jd-transactions', 'jingxi', 'jd-wallet']; + /** + * 时间筛选按「账单期间」(payload.settle_period,形如 2026-07)而不是按发生时间过滤的页签。 + * + * 唯品会两个页签里「订单结算时间」其实是一个账期月份,用它筛选才跟页面列对得上。 + */ + private const SETTLE_PERIOD_TABS = ['vipshop', 'vipshop-jx']; + /** * 通用账单列表(店铺收款账户账单 › 各账户类型 tab)。 * 经 admin 路由组(web 会话)暴露,前端带 CSRF 调用。 @@ -291,12 +298,25 @@ class AccountBills extends Controller $query->where('bill_item', $item); } - if ($start = $request->get('start')) { - $query->where('occurred_at', '>=', $start); - } + $start = $request->get('start'); + $end = $request->get('end'); + if (in_array($billType, self::SETTLE_PERIOD_TABS, true)) { + // 账单期间是「YYYY-MM」,与日期区间按月份取交集:只要月份落在所选区间内就算命中。 + $period = "JSON_UNQUOTE(JSON_EXTRACT(payload, '$.settle_period'))"; + if ($start) { + $query->whereRaw($period . ' >= ?', [substr((string) $start, 0, 7)]); + } + if ($end) { + $query->whereRaw($period . ' <= ?', [substr((string) $end, 0, 7)]); + } + } else { + if ($start) { + $query->where('occurred_at', '>=', $start); + } - if ($end = $request->get('end')) { - $query->where('occurred_at', '<=', $end . ' 23:59:59'); + if ($end) { + $query->where('occurred_at', '<=', $end . ' 23:59:59'); + } } if ($keyword = $request->get('keyword')) { diff --git a/resources/assets/js/components/business/AccountBills.vue b/resources/assets/js/components/business/AccountBills.vue index eb0c1e87..7307cba6 100644 --- a/resources/assets/js/components/business/AccountBills.vue +++ b/resources/assets/js/components/business/AccountBills.vue @@ -125,7 +125,8 @@ const SORTABLE = ['occurred_at','income','expense','balance','record_code']; // 京东账单与京喜账单共用同一份列定义与同一套交互,只在数据口径上拆分。 const JD_BILL_TABS = ['jd-transactions','jingxi']; // 时间筛选标签与该页签的时间列名保持一致(其余页签沿用「发生时间」)。 -const DATE_FILTER_LABELS = {'jd-transactions':'费用结算时间','jingxi':'费用结算时间','jd-wallet':'费用结算时间','douyin':'结算时间','vipshop':'结算时间','vipshop-jx':'结算时间'}; +// 唯品会两个页签的筛选项按「账单期间」筛(后端也只按 payload.settle_period 过滤)。 +const DATE_FILTER_LABELS = {'jd-transactions':'费用结算时间','jingxi':'费用结算时间','jd-wallet':'费用结算时间','douyin':'结算时间','vipshop':'账单期间','vipshop-jx':'账单期间'}; const dateConfig = {dateFormat:'Y-m-d',locale:Mandarin,disableMobile:true,allowInput:false,onReady:(_,value,picker)=>picker.calendarContainer.classList.add('account-bill-calendar')}; // 默认账期=本月:不填日期时查全表(几百万行)会很慢,默认落到当月既快又符合日常用法。 const currentMonthRange = () => { const now = new Date(); const year = now.getFullYear(); const month = now.getMonth() + 1; const pad = value => String(value).padStart(2, '0'); const lastDay = new Date(year, month, 0).getDate(); return { start: `${year}-${pad(month)}-01`, end: `${year}-${pad(month)}-${pad(lastDay)}` }; }; diff --git a/tests/Unit/View/AccountBillsTableTest.php b/tests/Unit/View/AccountBillsTableTest.php index b3724e5c..794f598d 100644 --- a/tests/Unit/View/AccountBillsTableTest.php +++ b/tests/Unit/View/AccountBillsTableTest.php @@ -45,7 +45,8 @@ class AccountBillsTableTest extends TestCase $this->assertStringContainsString("const JD_BILL_TABS = ['jd-transactions','jingxi'];", $source); $this->assertStringContainsString("isJdBillTab(){return JD_BILL_TABS.indexOf(this.billType)!==-1;}", $source); - $this->assertStringContainsString("const DATE_FILTER_LABELS = {'jd-transactions':'费用结算时间','jingxi':'费用结算时间','jd-wallet':'费用结算时间','douyin':'结算时间','vipshop':'结算时间','vipshop-jx':'结算时间'};", $source); + // 唯品会两个页签的筛选标签是「账单期间」(后端也只按 payload.settle_period 过滤)。 + $this->assertStringContainsString("const DATE_FILTER_LABELS = {'jd-transactions':'费用结算时间','jingxi':'费用结算时间','jd-wallet':'费用结算时间','douyin':'结算时间','vipshop':'账单期间','vipshop-jx':'账单期间'};", $source); $this->assertStringContainsString('{{ dateFilterLabel }}', $source); $this->assertStringContainsString('v-if="isJdBillTab && sync"', $source); $this->assertStringContainsString("netLabel=JD_BILL_TABS.concat(['vipshop-jx']).indexOf(this.billType)!==-1", $source);