fix: 修复抖音账户账单筛选 #147

Merged
WuYongJie merged 1 commits from fix/qiuxiang-douyin-bill-filters into main 2026-09-09 17:44:00 +08:00
4 changed files with 55 additions and 6 deletions

View File

@ -257,7 +257,7 @@ class StoreReceivingAlipayBillMirrorRepository
{
if (($filters['store_name'] ?? '') !== '') {
$shopIds = $this->mirror->connection()->table('ops_jst_shop_info')
->where('shop_name', $filters['store_name'])
->where('shop_name', 'like', '%' . $this->escapeLike((string) $filters['store_name']) . '%')
->pluck('shop_id')
->filter(static fn (mixed $value): bool => $value !== null && $value !== '')
->all();
@ -271,7 +271,7 @@ class StoreReceivingAlipayBillMirrorRepository
$query->where('b.channel', 'like', '%' . $this->escapeLike((string) $filters['alipay_account']) . '%');
}
if (($filters['bill_item'] ?? '') !== '') {
$query->where('b.fee_name', $filters['bill_item']);
$query->where('b.fee_name', 'like', '%' . $this->escapeLike((string) $filters['bill_item']) . '%');
}
if (($filters['business_type'] ?? '') !== '') {
$query->where('b.inout_type', $this->directionCode((string) $filters['business_type']));

View File

@ -68,4 +68,5 @@ export default {
.table-workspace{padding:1rem;color:#171717;font:400 .8125rem/1.5 "JetBrains Mono","Microsoft YaHei","PingFang SC",monospace}.tw-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.75rem;margin-bottom:.75rem}.tw-stat{padding:.875rem 1rem;border:1px solid #d8d2c7;border-radius:.5rem;background:#fff}.tw-label,.tw-note,.tw-count{color:#595959;font-size:.75rem}.tw-value{margin-top:.375rem;font-size:1.375rem;font-weight:700;font-variant-numeric:tabular-nums}.tw-note{margin-top:.1875rem}.is-income{color:#53793e}.is-expense{color:#b80000}.tw-filter{display:flex;flex-wrap:wrap;gap:.75rem;margin-bottom:.75rem;padding:.875rem 1rem;border:1px solid #d8d2c7;border-radius:.5rem;background:#fff}.tw-filter>label{display:flex;flex-direction:column;gap:.25rem;color:#595959;font-size:.75rem;font-weight:500}.tw-filter input,.tw-tools select{height:2.125rem;min-width:10rem;padding:0 .625rem;border:1px solid #d8d2c7;border-radius:.5rem;background:#fff;color:#171717;font:400 .8125rem/1 inherit}.tw-filter input:focus,.tw-tools select:focus{border-color:#856632;box-shadow:0 0 0 3px rgba(133,102,50,.2);outline:none}.tw-filter .tw-keyword{flex:1;min-width:14rem}.tw-keyword input{width:100%}.tw-date span,.tw-actions,.tw-tools,.tw-page-actions{display:flex;align-items:center;gap:.5rem}.tw-date b{font-weight:400}.tw-date input{min-width:8.5rem}.tw-actions{align-self:flex-end;margin-left:auto}.tw-button,.tw-page-actions button{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;height:2.125rem;padding:0 .875rem;border:1px solid #d8d2c7;border-radius:.5rem;background:#fff;color:#171717;font:500 .8125rem/1 inherit;cursor:pointer}.tw-button:hover{border-color:#856632;color:#856632}.tw-primary{border-color:#856632;background:#856632;color:#fff}.tw-primary:hover{background:#6a5129;color:#fff}.tw-button .material-icons-outlined{font-size:1.125rem}.tw-panel{overflow:visible;border:1px solid #d8d2c7;border-radius:.5rem;background:#fff}.tw-alert{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin:.75rem;padding:.75rem;border:1px solid #b80000;border-radius:.5rem;background:#fff4f4;color:#b80000}.tw-alert button{border:0;background:transparent;color:#b80000;font:inherit;font-weight:600;cursor:pointer}.tw-toolbar{display:flex;align-items:center;justify-content:space-between;gap:.75rem;min-height:3.5rem;padding:.625rem .875rem;border-bottom:1px solid #d8d2c7}.tw-toolbar strong{margin-right:.625rem;font-size:.875rem}.tw-tools{flex-wrap:wrap;justify-content:flex-end}.tw-tools>select{min-width:13.75rem}.tw-scroll{position:relative;max-height:min(62vh,42rem);overflow:auto;overscroll-behavior:contain;scrollbar-gutter:stable}.tw-table{width:max-content;min-width:100%;border-collapse:separate;border-spacing:0;font-size:.78125rem}.tw-table th,.tw-table td{min-width:7.5rem;padding:.5rem .625rem;border-right:1px solid #eeeae2;border-bottom:1px solid #eeeae2;white-space:nowrap}.tw-table thead th{position:sticky;z-index:4;background:#f7f0de;color:#171717;font-weight:600}.tw-groups th{top:0;height:2rem;text-align:center;color:#856632;font-size:.75rem}.tw-columns th{top:2rem;height:2.25rem;text-align:left;background:#fbfaf7;box-shadow:inset 0 -1px #d8d2c7}.tw-columns.is-single th{top:0}.tw-columns th.is-sortable{cursor:pointer}.tw-columns th.is-sortable:hover,.tw-sort{color:#856632}.tw-table tbody tr:hover{background:#f7f0de}.tw-table .is-number{text-align:right;font-variant-numeric:tabular-nums}.tw-table .is-id{color:#595959}.tw-tag{display:inline-block;padding:.0625rem .375rem;border-radius:.25rem;background:#f7f0de;color:#856632}.tw-empty{padding:3rem 1rem!important;text-align:center!important;color:#595959}.tw-pager{display:flex;align-items:center;justify-content:space-between;gap:.75rem;min-height:3.5rem;padding:.625rem .875rem;border-top:1px solid #d8d2c7;color:#595959}.tw-page-actions select{height:1.875rem;border:1px solid #d8d2c7;border-radius:.375rem}.tw-page-actions button{width:1.875rem;height:1.875rem;padding:0}.tw-page-actions button:disabled{cursor:not-allowed;opacity:.45}@media(max-width:900px){.table-workspace{padding:.75rem}.tw-stats{grid-template-columns:repeat(2,minmax(0,1fr))}.tw-filter>label,.tw-filter .tw-keyword{width:100%}.tw-filter input{width:100%}.tw-date input{min-width:0}.tw-actions{margin-left:0}.tw-toolbar,.tw-pager{align-items:flex-start;flex-direction:column}.tw-tools{justify-content:flex-start}.tw-scroll{max-height:58vh;width:100%}}@media(max-width:520px){.tw-stats{grid-template-columns:1fr}.tw-date span{align-items:stretch;flex-direction:column}.tw-tools>select{min-width:0;max-width:100%}.tw-page-actions{flex-wrap:wrap}}
.tw-toolbar { flex-wrap: wrap; }
.tw-tools { flex: 1 1 24rem; min-width: 0; }
.tw-filter{display:grid;grid-template-columns:minmax(10rem,1fr) minmax(10rem,1fr) auto minmax(14rem,2fr) auto;align-items:end}.tw-filter>label{min-width:0}.tw-actions{align-self:auto;justify-self:end;margin-left:0}@media(max-width:900px){.tw-filter{grid-template-columns:1fr}.tw-actions{justify-self:start}}
</style>

View File

@ -157,6 +157,43 @@ class PagesTest extends FeatureTestCase
->assertJsonPath('summary.count', 1);
}
public function testDouyinAccountBillsEndpointPassesAllFiltersToTheMirror(): void
{
$this->user->attachPermission(
Permission::where('name', 'read-admin-panel')->firstOrFail()
);
$filters = [
'store_name' => '放心购',
'bill_item' => '交易佣',
'start' => '2026-08-01',
'end' => '2026-08-01',
'keyword' => '',
];
$repository = Mockery::mock(StoreReceivingDouyinBillMirrorRepository::class);
$repository->shouldReceive('paginate')->once()->with(
$filters, 'occurred_at', 'desc', 1, 10,
)->andReturn([
'current_page' => 1,
'last_page' => 1,
'per_page' => 10,
'total' => 0,
'data' => [],
'summary' => ['income' => 0.0, 'expense' => 0.0, 'balance' => 0.0, 'count' => 0],
]);
$this->app->instance(StoreReceivingDouyinBillMirrorRepository::class, $repository);
$this->loginAs()
->withHeader('X-Requested-With', 'XMLHttpRequest')
->get(route('ecommerce-finance.account-bills.index', [
'bill_type' => 'douyin',
...$filters,
]))
->assertOk()
->assertJsonPath('total', 0);
}
public function testDouyinAccountBillsExportUsesSelectedColumnOrder(): void
{
$this->user->attachPermission(

View File

@ -273,21 +273,32 @@ class StoreReceivingAlipayBillMirrorRepositoryTest extends TestCase
$db->table('ops_jst_original_bill_info')->insert([
$this->row(1, 7, '2026-08-01 09:00:00', '1', 100.25, 'TouTiaoFXGZJ'),
$this->row(2, 7, '2026-08-02 09:00:00', '-1', 20.10, 'CommonBillTGCPay'),
$this->row(3, 7, '2026-08-02 10:00:00', '1', 55.40, 'TouTiaoFXGZJ'),
]);
$douyin = new StoreReceivingDouyinBillMirrorRepository($this->repository);
$result = $douyin->paginate([], 'occurred_at', 'desc', 1, 10);
$this->assertSame(1, $result['total']);
$this->assertSame('1', $result['data'][0]['record_code']);
$this->assertSame(2, $result['total']);
$this->assertSame('3', $result['data'][0]['record_code']);
$this->assertSame('放心购旗舰店', $result['data'][0]['store_name']);
$this->assertSame('TouTiaoFXGZJ', $result['data'][0]['payload']['settle_account']);
$this->assertSame('头条放心购', $result['data'][0]['payload']['move_scene']);
$this->assertSame(100.25, $result['summary']['income']);
$this->assertSame(155.65, $result['summary']['income']);
$this->assertSame(0.0, $result['summary']['expense']);
$filtered = $douyin->paginate([
'store_name' => '放心购',
'bill_item' => '交易佣',
'start' => '2026-08-01',
'end' => '2026-08-01',
], 'occurred_at', 'desc', 1, 10);
$this->assertSame(1, $filtered['total']);
$this->assertSame('1', $filtered['data'][0]['record_code']);
$rows = iterator_to_array($douyin->exportRows([], 'occurred_at', 'asc'));
$this->assertCount(1, $rows);
$this->assertCount(2, $rows);
$this->assertSame('1', $rows[0]['record_code']);
}