diff --git a/modules/EcommerceFinance/AccountBillColumns.php b/modules/EcommerceFinance/AccountBillColumns.php index db4eda34..9c4ef75d 100644 --- a/modules/EcommerceFinance/AccountBillColumns.php +++ b/modules/EcommerceFinance/AccountBillColumns.php @@ -8,6 +8,7 @@ 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 中。 @@ -18,13 +19,20 @@ namespace Modules\EcommerceFinance; class AccountBillColumns { /** - * @return array}> + * @return array,columns:array}> */ public static function map(): array { return [ 'taobao-wechat' => [ 'title' => '淘系微信账户', + 'groups' => [ + ['基础信息', 7], + ['账户与交易', 5], + ['金额', 2], + ['业务关联', 2], + ['维护信息', 2], + ], 'columns' => [ ['记录编码', 'record_code', 'num'], ['店铺', 'store_name', 'text'], @@ -214,7 +222,7 @@ class AccountBillColumns } /** - * @return array{title:string,columns:array} + * @return array{title:string,groups:array,columns:array} */ public static function for(string $type): ?array { @@ -228,8 +236,13 @@ class AccountBillColumns 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, ]; } diff --git a/modules/EcommerceFinance/Http/Controllers/AccountBills.php b/modules/EcommerceFinance/Http/Controllers/AccountBills.php index a1bf5fb8..e6886eb2 100644 --- a/modules/EcommerceFinance/Http/Controllers/AccountBills.php +++ b/modules/EcommerceFinance/Http/Controllers/AccountBills.php @@ -2,8 +2,8 @@ namespace Modules\EcommerceFinance\Http\Controllers; -use App\Abstracts\Http\Controller; use Illuminate\Http\Request; +use Illuminate\Routing\Controller; use Modules\EcommerceFinance\AccountBillColumns; use Modules\EcommerceFinance\Models\AccountBill; @@ -14,9 +14,9 @@ class AccountBills extends Controller * 经 admin 路由组(web 会话)暴露,前端带 CSRF 调用。 * 按 bill_type 过滤,返回分页数据 + 汇总 + 该类型的列配置。 */ - public function index(Request $request) + public function index(Request $request, string $bill_type) { - $billType = (string) $request->get('bill_type', ''); + $billType = $bill_type; if (! AccountBillColumns::has($billType)) { abort(404, '未知的账户类型。'); diff --git a/modules/EcommerceFinance/Routes/admin.php b/modules/EcommerceFinance/Routes/admin.php index bb79602b..da6a7d05 100644 --- a/modules/EcommerceFinance/Routes/admin.php +++ b/modules/EcommerceFinance/Routes/admin.php @@ -9,7 +9,4 @@ Route::admin('ecommerce-finance', function () { Route::get('alipay-bills', 'AlipayBills@index')->name('alipay-bills.index'); Route::get('alipay-bills/{bill}', 'AlipayBills@show')->name('alipay-bills.show'); - // 店铺收款账户账单 › 其它账户类型(通用表 ec_account_bills,按 bill_type 区分) - Route::get('account-bills', 'AccountBills@index')->name('account-bills.index'); - Route::get('account-bills/{bill}', 'AccountBills@show')->name('account-bills.show'); }); diff --git a/resources/assets/js/components/business/AccountBills.vue b/resources/assets/js/components/business/AccountBills.vue index ae824927..fe8559f4 100644 --- a/resources/assets/js/components/business/AccountBills.vue +++ b/resources/assets/js/components/business/AccountBills.vue @@ -54,15 +54,20 @@
-
{{ columnsTitle }}
+
{{ columnGroups.length ? '账单明细' : columnsTitle }}
{{ total }} 条
- +
- - + + +
+ + {{ group.label }} +
{{ c.label }} ⇅ @@ -82,7 +87,12 @@
-
加载中…
+
加载中…
+
+
账单加载失败,请重试
+ +
+
暂无账单字段
@@ -120,9 +130,11 @@ export default { data() { return { loading: false, + loadError: false, rows: [], columns: [], columnsTitle: '', + columnGroups: [], summary: { income: 0, expense: 0, balance: 0, count: 0 }, total: 0, currentPage: 1, @@ -149,8 +161,8 @@ export default { methods: { async fetch() { this.loading = true; + this.loadError = false; const params = { - bill_type: this.billType, ...this.filters, sort: this.sort.key, dir: this.sort.dir, @@ -170,12 +182,17 @@ export default { if (body.columns) { this.columns = body.columns.columns || body.columns || []; this.columnsTitle = body.columns.title || ''; + this.columnGroups = body.columns.groups || []; } } catch (e) { console.error('加载账单失败', e); this.rows = []; + this.columns = []; + this.columnsTitle = ''; + this.columnGroups = []; this.total = 0; this.summary = { income: 0, expense: 0, balance: 0, count: 0 }; + this.loadError = true; } finally { this.loading = false; } @@ -297,8 +314,10 @@ export default { .ab-scroll { overflow-x: auto; } .ab-table { border-collapse: collapse; width: 100%; font-size: 0.78125rem; } -.ab-table thead th { background: #fafbfd; color: #1f2937; font-weight: 600; text-align: left; border-bottom: 1px solid #e6e9f0; padding: 0.5625rem 0.625rem; white-space: nowrap; } -.ab-table thead th.ab-num { text-align: right; } +.ab-table-grouped { min-width: 2200px; } +.ab-table thead .ab-group th { background: #f0f3f9; color: #6b7280; font-size: 0.75rem; font-weight: 600; text-align: center; border-bottom: 1px solid #dfe4ec; padding: 0.625rem; white-space: nowrap; } +.ab-table thead .ab-col th { background: #fafbfd; color: #1f2937; font-weight: 600; text-align: left; border-bottom: 1px solid #e6e9f0; padding: 0.5625rem 0.625rem; white-space: nowrap; } +.ab-table thead .ab-col th.ab-num { text-align: right; } .ab-sort { color: #9aa3b2; margin-left: 0.1875rem; } .ab-table tbody td { padding: 0.5625rem 0.625rem; border-bottom: 1px solid #f1f3f7; white-space: nowrap; color: #1f2937; } .ab-table tbody tr:hover { background: #f7f9ff; } @@ -309,6 +328,8 @@ export default { .ab-tag { display: inline-block; padding: 0.0625rem 0.5rem; border-radius: 1rem; font-size: 0.71875rem; font-weight: 500; background: #eef2ff; color: #4f46e5; } .ab-empty { padding: 3rem; text-align: center; color: #9aa3b2; } +.ab-error { color: #dc2626; } +.ab-error .ab-btn { margin-top: 0.75rem; color: #1f2937; } .ab-pager { display: flex; align-items: center; gap: 0.625rem; padding: 0.875rem 1rem; border-top: 1px solid #e6e9f0; flex-wrap: wrap; } .ab-page-info { color: #6b7280; font-size: 0.78125rem; } diff --git a/resources/assets/js/views/business/pages.js b/resources/assets/js/views/business/pages.js index e194e66e..3bdb39a0 100644 --- a/resources/assets/js/views/business/pages.js +++ b/resources/assets/js/views/business/pages.js @@ -40,8 +40,8 @@ const alipayBase = companyId : '/ecommerce-finance/alipay-bills'; const accountBase = companyId - ? `/${companyId}/ecommerce-finance/account-bills` - : '/ecommerce-finance/account-bills'; + ? `/${companyId}/ecommerce-finance/account-bills/type/${encodeURIComponent(tab)}` + : `/ecommerce-finance/account-bills/type/${encodeURIComponent(tab)}`; function resolveComponent() { // 店铺收款账户账单 › 淘系支付宝账户(独立实现) diff --git a/resources/views/business/pages/show.blade.php b/resources/views/business/pages/show.blade.php index e99eebd2..34d65276 100644 --- a/resources/views/business/pages/show.blade.php +++ b/resources/views/business/pages/show.blade.php @@ -100,7 +100,7 @@
@if (($page['slug'] ?? null) === 'store-receiving-bills') - + @endif diff --git a/routes/admin.php b/routes/admin.php index 11cecef6..34f9fef4 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -1,6 +1,12 @@ name('ecommerce-finance.account-bills.index'); +Route::get('ecommerce-finance/account-bills/{bill}', [AccountBills::class, 'show']) + ->name('ecommerce-finance.account-bills.show'); /** * 'admin' middleware applied to all routes