CaiWuXiTong/modules/EcommerceFinance/AccountBillColumns.php
qiuxiang a0c99c3e8d 新增店铺收款京喜账单页签并从京东账单切分
在京东账单右侧新增京喜账单页签,复用京东日账单的取数、列定义、筛选、排序、分页与导出,只增加平台维度过滤:京东账单排除京喜店铺,京喜账单只取京喜店铺。平台口径集中在 config/jd_bill_platform.php 与 JdBillPlatform(含口径切换起始日期参数,默认全量历史),仓库通过 forPlatform() 收窄,两个口径互补、总额守恒,底层镜像数据不修改不删除。真实镜像实测:京喜 488,464 笔 + 京东 210,983 笔 = 拆分前 699,447 笔,收入/支出/差额逐项误差为 0。
2026-09-28 19:25:53 +08:00

309 lines
15 KiB
PHP
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.

<?php
namespace Modules\EcommerceFinance;
/**
* 店铺收款账户账单 - 各账户类型的列配置(单一数据源)。
*
* 列定义来自「账单抬头.xlsx」的各子表(sheet 名 = 账户类型)。
* sheet 名 ↔ tab slug ↔ 列 三者在此一一对应,避免错乱。
*
* 账户可选配置分组表头 groups,字段列统一由 columns 定义。
* 每列: [label, field, kind]
* field: 真实列名(如 record_code / income / occurred_at / updated_at),
* 或 'payload.xxx' 表示存在 payload JSON 中。
* kind: text | num | money | money_in | money_out | balance | date | tag
*
* 淘系支付宝账户(taobao-alipay)已有独立实现,不在此处定义。
*/
class AccountBillColumns
{
/**
* 京东账单 / 京喜账单共用列定义(顺序、字段名、导出口径完全一致,只按平台拆分数据)。
*
* @var array<int,array{0:string,1:string,2:string}>
*/
private const JD_BILL_COLUMNS = [
['记录编码', 'record_code', 'num'],
['店铺', 'store_name', 'text'],
['自定义备注', 'custom_remark', 'text'],
['账单项目', 'bill_item', 'tag'],
['线上单号', 'payload.online_order_no', 'num'],
['单据编号', 'payload.document_no', 'num'],
['订单编号', 'order_no', 'num'],
['商户订单号', 'payload.merchant_order_no', 'num'],
['单据类型', 'payload.document_type', 'text'],
['商品编码', 'payload.product_id', 'num'],
['商品名称', 'payload.product_name', 'text'],
['费用结算时间', 'occurred_at', 'date'],
['费用发生时间', 'payload.cost_happened_at', 'date'],
['费用项', 'payload.cost_name', 'text'],
['收入金额', 'income', 'money_in'],
['支出金额', 'expense', 'money_out'],
['币种', 'payload.currency', 'text'],
['钱包结算备注', 'payload.settle_remark', 'text'],
['备注', 'remark', 'text'],
['店铺号', 'payload.shop_no', 'num'],
['京东门店编码', 'payload.jd_shop_no', 'num'],
['品牌门店编号', 'payload.brand_shop_no', 'num'],
['门店名称', 'payload.shop_name', 'text'],
['账户代码', 'payload.account_code', 'text'],
['修改时间', 'updated_at', 'date'],
['修改人', 'modifier', 'text'],
];
/**
* @return array<string,array{title:string,groups?:array<int,array{0:string,1:int}>,columns:array<int,array{0:string,1:string,2:string}>}>
*/
public static function map(): array
{
return [
'vipshop' => [
'title' => '唯品会MP账户',
'columns' => [
['全局ID', 'record_code', 'num'],
['店铺ID', 'payload.shop_id', 'num'],
['店铺名称', 'store_name', 'text'],
['订单签收或退款时间', 'occurred_at', 'date'],
['订单类型名称', 'bill_item', 'text'],
['行类型名称', 'payload.vip_5', 'text'],
['售后类型名称', 'payload.vip_6', 'text'],
['售后单号', 'payload.vip_7', 'text'],
['订单编号', 'order_no', 'num'],
['SKU', 'payload.vip_9', 'num'],
['商品款号', 'payload.vip_10', 'num'],
['商品SKU', 'payload.vip_11', 'num'],
['商品描述', 'payload.vip_12', 'text'],
['店铺协议编号', 'payload.vip_13', 'text'],
['二级类目', 'payload.vip_14', 'text'],
['三级类目', 'payload.vip_15', 'text'],
['商品单价', 'payload.vip_16', 'money'],
['商品数量', 'payload.vip_17', 'num'],
['商品金额(A)', 'payload.vip_18', 'money'],
['商家优惠(B)', 'payload.vip_19', 'money'],
['调整金额(C)', 'payload.vip_20', 'money'],
['无需退款金额(D)', 'payload.vip_21', 'money'],
['总金额(E=A-B-C-D)', 'payload.vip_22', 'money'],
['扣点', 'payload.vip_23', 'text'],
['技术服务费(F)', 'payload.vip_24', 'money'],
['海淘综合税(G)', 'payload.vip_25', 'money'],
['分享金扣点', 'payload.vip_26', 'text'],
['唯品仓分享金', 'payload.vip_27', 'money'],
['商家应收(G=E-F-G)', 'balance', 'money'],
],
],
// 唯品会JX(JITX 入仓/经销)账单只有 5 列原始字段(店铺/类型/二次备注/销售订单号/含税金额),
// 没有日期列;订单日期由销售订单号前 6 位(YYMMDD)还原,其余列由金额正负拆出收/支。
'vipshop-jx' => [
'title' => '唯品会JX账户',
'columns' => [
['记录编码', 'record_code', 'num'],
['店铺', 'store_name', 'text'],
['类型', 'bill_item', 'tag'],
['二次备注', 'payload.second_remark', 'text'],
['销售订单号', 'order_no', 'num'],
['订单日期(按订单号)', 'occurred_at', 'date'],
['含税金额', 'amount', 'money'],
['收入金额', 'income', 'money_in'],
['支出金额', 'expense', 'money_out'],
],
],
'taobao-wechat' => [
'title' => '淘系微信账户',
'groups' => [
['基础信息', 7],
['账户与交易', 5],
['金额', 2],
['业务关联', 2],
['维护信息', 2],
],
'columns' => [
['记录编码', 'record_code', 'num'],
['店铺', 'store_name', 'text'],
['财务备注', 'finance_remark', 'text'],
['订单号', 'order_no', 'num'],
['金额', 'amount', 'money'],
['自定义备注', 'custom_remark', 'text'],
['账单项目', 'bill_item', 'tag'],
['线上单号', 'payload.online_order_no', 'num'],
['淘宝订单编号', 'payload.taobao_order_no', 'num'],
['支付流水号', 'payload.pay_serial_no', 'num'],
['入账时间', 'occurred_at', 'date'],
['入账类型', 'payload.entry_type', 'text'],
['收入金额', 'income', 'money_in'],
['支出金额', 'expense', 'money_out'],
['业务描述', 'payload.business_desc', 'text'],
['备注', 'remark', 'text'],
['JST拉取时间', 'payload.jst_pulled_at', 'date'],
['修改人', 'modifier', 'text'],
],
],
'pinduoduo' => [
'title' => '拼多多账户',
'columns' => [
['记录编码', 'record_code', 'num'],
['店铺', 'store_name', 'text'],
['财务备注', 'finance_remark', 'text'],
['订单', 'order_no', 'num'],
['金额', 'amount', 'money'],
['自定义备注', 'custom_remark', 'text'],
['账单项目', 'bill_item', 'tag'],
['商户订单号', 'payload.merchant_order_no', 'num'],
['线上单号', 'payload.online_order_no', 'num'],
['财务类型', 'payload.finance_type', 'text'],
['类型', 'payload.type', 'text'],
['发生时间', 'occurred_at', 'date'],
['收入金额', 'income', 'money_in'],
['支出金额', 'expense', 'money_out'],
['备注', 'remark', 'text'],
['修改时间', 'updated_at', 'date'],
['修改人', 'modifier', 'text'],
],
],
'jd-wallet' => [
'title' => '京东网银钱包账户',
'columns' => [
['记录编码', 'record_code', 'num'],
['店铺', 'store_name', 'text'],
['自定义备注', 'custom_remark', 'text'],
['账单项目', 'bill_item', 'tag'],
['线上单号', 'payload.online_order_no', 'num'],
['流水号', 'payload.serial_no', 'num'],
['交易订单号', 'order_no', 'num'],
['账户名称', 'payload.account_name', 'text'],
['费用结算时间', 'occurred_at', 'date'],
['账单日期', 'payload.bill_date', 'date'],
['商户订单号', 'payload.merchant_order_no', 'num'],
['交易备注', 'payload.tx_remark', 'text'],
['交易类型', 'payload.tx_type', 'text'],
['收入金额', 'income', 'money_in'],
['支出金额', 'expense', 'money_out'],
['账户余额', 'balance', 'balance'],
['币种', 'payload.currency', 'text'],
['记账请求号', 'payload.book_request_no', 'num'],
['业务订单号', 'payload.business_order_no', 'num'],
['修改时间', 'updated_at', 'date'],
['修改人', 'modifier', 'text'],
],
],
// 京喜账单与京东账单共用同一份列定义,只按平台口径拆分数据。
'jd-transactions' => [
'title' => '京东账单',
'columns' => self::JD_BILL_COLUMNS,
],
'jingxi' => [
'title' => '京喜账单',
'columns' => self::JD_BILL_COLUMNS,
],
'douyin' => [
'title' => '抖音账户',
'columns' => [
['记录编码', 'record_code', 'num'],
['店铺', 'store_name', 'text'],
['财务备注', 'finance_remark', 'text'],
['订单', 'order_no', 'num'],
['金额', 'amount', 'money'],
['自定义备注', 'custom_remark', 'text'],
['商户主体名称', 'payload.merchant_name', 'text'],
['账单项目', 'bill_item', 'tag'],
['动账流水号', 'payload.move_serial_no', 'num'],
['订单号', 'payload.order_no_2', 'num'],
['线上单号', 'payload.online_order_no', 'num'],
['子订单号', 'payload.sub_order_no', 'num'],
['商品ID', 'payload.goods_id', 'num'],
['账务类型', 'payload.account_type', 'text'],
['结算时间', 'occurred_at', 'date'],
['动账摘要', 'payload.move_summary', 'text'],
['下单时间', 'payload.order_placed_at', 'date'],
['业务类型', 'payload.business_type', 'text'],
['结算账户', 'payload.settle_account', 'text'],
['动账场景', 'payload.move_scene', 'text'],
['达人ID', 'payload.talent_id', 'num'],
['达人名称', 'payload.talent_name', 'text'],
['备注', 'remark', 'text'],
['收入', 'income', 'money_in'],
['支出', 'expense', 'money_out'],
['创建时间', 'created_at', 'date'],
['修改时间', 'updated_at', 'date'],
['修改人', 'modifier', 'text'],
],
],
'dewu' => [
'title' => '得物账户',
'columns' => [
['记录编码', 'record_code', 'num'],
['店铺', 'store_name', 'text'],
['财务备注', 'finance_remark', 'text'],
['金额', 'amount', 'money'],
['订单号', 'order_no', 'num'],
['线上单号', 'payload.online_order_no', 'num'],
['自定义备注', 'custom_remark', 'text'],
['账单项目', 'bill_item', 'tag'],
['店铺', 'payload.store_2', 'text'],
['订单类型', 'payload.order_type', 'text'],
['商品名称', 'payload.goods_name', 'text'],
['商品货号', 'payload.goods_no', 'num'],
['数量', 'payload.quantity', 'num'],
['渠道', 'payload.channel', 'text'],
['源渠道代码', 'payload.source_channel', 'text'],
['业务类型', 'payload.business_type', 'text'],
['收入金额', 'income', 'money_in'],
['支出金额', 'expense', 'money_out'],
['线上单号对应实际店铺', 'payload.online_real_store', 'text'],
['订单创建时间', 'payload.order_created_at', 'date'],
['支付/退款时间', 'occurred_at', 'date'],
['发货/退货时间', 'payload.ship_return_at', 'date'],
['结算状态', 'payload.settle_status', 'text'],
['收款账期', 'payload.pay_period', 'text'],
['拉取时间', 'payload.pulled_at', 'date'],
['修改时间', 'updated_at', 'date'],
['修改人', 'modifier', 'text'],
],
],
];
}
public static function types(): array
{
return array_keys(self::map());
}
public static function has(string $type): bool
{
return isset(self::map()[$type]);
}
/**
* @return array{title:string,groups:array<int,array{label:string,span:int}>,columns:array<int,array{label:string,field:string,kind:string}>}
*/
public static function for(string $type): ?array
{
$map = self::map();
if (! isset($map[$type])) {
return null;
}
$columns = array_map(function ($c) {
return ['label' => $c[0], 'field' => $c[1], 'kind' => $c[2]];
}, $map[$type]['columns']);
$groups = array_map(function ($group) {
return ['label' => $group[0], 'span' => $group[1]];
}, $map[$type]['groups'] ?? []);
return [
'title' => $map[$type]['title'],
'groups' => $groups,
'columns' => $columns,
];
}
}