按「账单抬头.xlsx」各子表(微信/拼多多/京东网银钱包/京东流水/抖音/得物)设计对应 tab 页: - 新增通用表 ec_account_bills(bill_type + 通用列 + payload JSON) - AccountBill 模型 + AccountBillColumns 配置类(6类型列定义,单一数据源,sheet名↔tab↔列不乱) - AccountBills 控制器(admin 路由组,按 bill_type 筛选/排序/分页+汇总+下发列配置) - admin 路由登记 account-bills - 通用前端组件 AccountBills.vue(按后端下发 columns 动态渲染表头/单元格,含筛选/汇总/分页) - pages.js:store-receiving-bills 页按 tab 路由(taobao-alipay→独立组件;其余6个→AccountBills) - 修正 pages.js/Blade 的 section/page/tab 解析(按真实URL billing-transactions/store-receiving-bills/<tab>) - 种子:6类型各6行演示数据 淘系支付宝账户保持独立实现不变。
169 lines
5.7 KiB
PHP
169 lines
5.7 KiB
PHP
<?php
|
||
|
||
namespace Modules\EcommerceFinance\Database\Seeds;
|
||
|
||
use Illuminate\Database\Seeder;
|
||
use Illuminate\Support\Facades\DB;
|
||
use Modules\EcommerceFinance\AccountBillColumns;
|
||
|
||
class AccountBillsTableSeeder extends Seeder
|
||
{
|
||
/**
|
||
* 为 6 种账户类型生成演示行(淘系支付宝不在内,它有独立表/种子)。
|
||
* 运行:php artisan db:seed --class=Modules\\EcommerceFinance\\Database\\Seeds\\AccountBillsTableSeeder
|
||
*/
|
||
public function run()
|
||
{
|
||
$companyId = (int) (DB::table('companies')->value('id') ?? 1);
|
||
|
||
$shops = [
|
||
'淘宝-亿家达家居鞋柜电脑桌',
|
||
'天猫-亿家达旗舰店',
|
||
'天猫-卓禾家具旗舰店',
|
||
'拼多多-亿家达家居旗舰店',
|
||
'京东-亿家达旗舰店',
|
||
'抖音-亿家达旗舰店',
|
||
'得物-亿家达旗舰店',
|
||
];
|
||
|
||
$items = ['交易收款', '退款', '提现到银行卡', '服务费', '红包补贴', '佣金扣款', '平台补贴', '以旧换新自补平台过桥'];
|
||
|
||
$now = now();
|
||
$seq = 3000000000000000000;
|
||
|
||
foreach (AccountBillColumns::types() as $billType) {
|
||
$config = AccountBillColumns::for($billType);
|
||
DB::table('ec_account_bills')
|
||
->where('company_id', $companyId)
|
||
->where('bill_type', $billType)
|
||
->delete();
|
||
|
||
$balance = 50000.00;
|
||
|
||
for ($i = 0; $i < 6; $i++) {
|
||
$real = [
|
||
'company_id' => $companyId,
|
||
'bill_type' => $billType,
|
||
'modifier' => 'api',
|
||
'created_by' => null,
|
||
'created_from' => 'ecommerce-finance',
|
||
'created_at' => $now,
|
||
'updated_at' => $now,
|
||
];
|
||
$payload = [];
|
||
|
||
$income = $i % 2 === 0 ? round(60 + ($i * 37 % 600), 2) : 0.00;
|
||
$expense = $i % 2 === 1 ? round(8 + ($i * 13 % 120), 2) : 0.00;
|
||
$balance += $income - $expense;
|
||
|
||
$day = str_pad((string) (1 + ($i % 15)), 2, '0', STR_PAD_LEFT);
|
||
$hh = str_pad((string) (8 + ($i % 12)), 2, '0', STR_PAD_LEFT);
|
||
$mm = str_pad((string) (($i * 7) % 60), 2, '0', STR_PAD_LEFT);
|
||
$occurred = '2026-07-' . $day . ' ' . $hh . ':' . $mm . ':11';
|
||
|
||
foreach ($config['columns'] as $col) {
|
||
[$label, $field, $kind] = [$col['label'], $col['field'], $col['kind']];
|
||
$value = $this->valueFor($field, $kind, $label, [
|
||
'i' => $i,
|
||
'shop' => $shops[($i + crc32($billType)) % count($shops)],
|
||
'item' => $items[$i % count($items)],
|
||
'income' => $income,
|
||
'expense' => $expense,
|
||
'balance' => round($balance, 2),
|
||
'occurred' => $occurred,
|
||
'seq' => $seq,
|
||
]);
|
||
|
||
if (strpos($field, 'payload.') === 0) {
|
||
$payload[substr($field, 8)] = $value;
|
||
} else {
|
||
$real[$field] = $value;
|
||
}
|
||
}
|
||
|
||
$real['payload'] = json_encode($payload, JSON_UNESCAPED_UNICODE);
|
||
$seq++;
|
||
|
||
DB::table('ec_account_bills')->insert($this->normalizeRow($real));
|
||
}
|
||
}
|
||
}
|
||
|
||
private function valueFor($field, $kind, $label, array $c)
|
||
{
|
||
// 真实列优先按字段定值
|
||
switch ($field) {
|
||
case 'record_code':
|
||
return (string) ($c['seq']);
|
||
case 'store_name':
|
||
return $c['shop'];
|
||
case 'bill_item':
|
||
return $c['item'];
|
||
case 'occurred_at':
|
||
return $c['occurred'];
|
||
case 'income':
|
||
return $c['income'];
|
||
case 'expense':
|
||
return $c['expense'];
|
||
case 'balance':
|
||
return $c['balance'];
|
||
case 'amount':
|
||
return $c['income'] + $c['expense'];
|
||
case 'order_no':
|
||
return (string) (1570700000000000000 + $c['i']);
|
||
case 'finance_remark':
|
||
case 'custom_remark':
|
||
return $c['i'] % 3 === 0 ? '财务备注-' . $c['i'] : null;
|
||
case 'remark':
|
||
return $c['item'] . ' 演示备注';
|
||
case 'modifier':
|
||
return 'api';
|
||
case 'created_at':
|
||
case 'updated_at':
|
||
return now();
|
||
}
|
||
|
||
// payload 列按 kind 推断
|
||
switch ($kind) {
|
||
case 'date':
|
||
return $c['occurred'];
|
||
case 'num':
|
||
return (string) (3300000000000000 + $c['i'] + crc32($field));
|
||
case 'money':
|
||
case 'balance':
|
||
return $c['amount'] ?? 0;
|
||
case 'money_in':
|
||
return $c['income'];
|
||
case 'money_out':
|
||
return $c['expense'];
|
||
case 'tag':
|
||
return $c['item'];
|
||
default:
|
||
return $label . '-' . $c['i'];
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 保证插入行类型与表结构一致(decimal/null)。
|
||
*/
|
||
private function normalizeRow(array $real): array
|
||
{
|
||
$decimals = ['amount', 'income', 'expense', 'balance'];
|
||
|
||
foreach ($decimals as $k) {
|
||
if (isset($real[$k])) {
|
||
$real[$k] = (float) $real[$k];
|
||
}
|
||
}
|
||
|
||
if (empty($real['finance_remark'])) {
|
||
$real['finance_remark'] = null;
|
||
}
|
||
if (empty($real['custom_remark'])) {
|
||
$real['custom_remark'] = null;
|
||
}
|
||
|
||
return $real;
|
||
}
|
||
}
|