CaiWuXiTong/modules/EcommerceFinance/AccountBillColumns.php
qiuxiang e147c90a2c 店铺收款账户账单新增「总账备注」列(按平台+账单项目映射表取值)
- 新增 ec_account_ledger_remarks 映射表与 account-ledger-remarks:import 导入命令(平台/账单项目/总账备注)
- 新增 AccountLedgerRemarkMap:按店铺名前缀识别平台,无前缀时用页签默认平台;缺失匹配保持空白
- 全部账户页签(含淘系支付宝自有列定义)在「店铺/店铺名称」右侧新增「总账备注」列,页面/列设置/导出共用同一份列定义
- 控制器在分页与导出流读取时补齐 payload.ledger_remark,不改动上游账单与共享镜像数据
- 用例:新增 AccountLedgerRemarkMapTest;修正唯品会 JX/MP 列清单断言
2026-10-06 15:42:57 +08:00

319 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'],
['总账备注', 'payload.ledger_remark', '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'],
['总账备注', 'payload.ledger_remark', 'text'],
['订单签收或退款时间', 'occurred_at', 'date'],
['订单结算时间', 'payload.settle_period', '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'],
['总账备注', 'payload.ledger_remark', 'text'],
['类型', 'bill_item', 'tag'],
['二次备注', 'payload.second_remark', 'text'],
['销售订单号', 'order_no', 'num'],
['订单结算时间', 'payload.settle_period', 'date'],
['订单日期(按订单号)', 'occurred_at', 'date'],
['含税金额', 'amount', 'money'],
['收入金额', 'income', 'money_in'],
['支出金额', 'expense', 'money_out'],
],
],
'taobao-wechat' => [
'title' => '淘系微信账户',
'groups' => [
['基础信息', 8],
['账户与交易', 5],
['金额', 2],
['业务关联', 2],
['维护信息', 2],
],
'columns' => [
['记录编码', 'record_code', 'num'],
['店铺', 'store_name', 'text'],
['总账备注', 'payload.ledger_remark', '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'],
['总账备注', 'payload.ledger_remark', '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'],
['总账备注', 'payload.ledger_remark', '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'],
['总账备注', 'payload.ledger_remark', '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'],
['总账备注', 'payload.ledger_remark', '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,
];
}
}