账期收付改为按累计已付同步 credit_ledger,修复多笔 partial_paid 与坏账核销重复释额;新增 API E2E(占成、权限、部分收付/坏账)与 GitHub Actions e2e-api job。 Co-authored-by: Cursor <cursoragent@cursor.com>
96 lines
3.3 KiB
TypeScript
96 lines
3.3 KiB
TypeScript
/**
|
||
* E2E:代理账期关账 → confirm → 登记收付 → 账单 settled。
|
||
*/
|
||
|
||
import { test, expect } from '@playwright/test';
|
||
import {
|
||
adminLoginViaBypass,
|
||
adminCtxOf,
|
||
fetchOpenDrawNo,
|
||
playerLoginViaBypass,
|
||
openSettlementPeriod,
|
||
setupCreditPlayer,
|
||
} from './_helper';
|
||
import { runWalletDrawSettlement } from './helpers/draw-settlement';
|
||
|
||
test('关账后 confirm + 全额收付 → 玩家账单 settled + payment_records', async () => {
|
||
test.setTimeout(300_000);
|
||
|
||
const credit = await setupCreditPlayer({
|
||
credit_limit: 100_000,
|
||
username: `e2e_pay_${Date.now()}`,
|
||
});
|
||
const drawNo = await fetchOpenDrawNo();
|
||
const winNumber = `8${String(Date.now()).slice(-3)}`;
|
||
|
||
const adminSession = await adminLoginViaBypass();
|
||
const admin = await adminCtxOf(adminSession.accessToken);
|
||
const periodId = await openSettlementPeriod(admin, credit.admin_site_id);
|
||
|
||
const playerSession = await playerLoginViaBypass({
|
||
site_code: credit.site_code,
|
||
username: credit.username,
|
||
password: credit.password,
|
||
});
|
||
|
||
await runWalletDrawSettlement({
|
||
adminToken: adminSession.accessToken,
|
||
playerToken: playerSession.access_token,
|
||
drawNo,
|
||
betNumber: winNumber,
|
||
betAmount: 10_000,
|
||
expectWalletIncrease: false,
|
||
});
|
||
|
||
const close = await admin.post(`/api/v1/admin/settlement-periods/${periodId}/close`);
|
||
expect(close.ok(), `close period status=${close.status()}`).toBeTruthy();
|
||
const closeBody = (await close.json()) as any;
|
||
expect(closeBody.code).toBe(0);
|
||
|
||
const bills = await admin.get(
|
||
`/api/v1/admin/settlement-bills?settlement_period_id=${periodId}&size=20`,
|
||
);
|
||
const billsBody = (await bills.json()) as any;
|
||
expect(billsBody.code).toBe(0);
|
||
const playerBill = billsBody.data.items.find(
|
||
(b: any) => b.bill_type === 'player' && Number(b.owner_id) === credit.player_id,
|
||
);
|
||
expect(playerBill, '应有该信用玩家的账单').toBeTruthy();
|
||
expect(playerBill.status).toBe('pending_confirm');
|
||
const unpaid = Number(playerBill.unpaid_amount);
|
||
expect(unpaid).toBeGreaterThan(0);
|
||
|
||
const confirm = await admin.post(`/api/v1/admin/settlement-bills/${playerBill.id}/confirm`);
|
||
expect(confirm.ok(), `confirm status=${confirm.status()}`).toBeTruthy();
|
||
const confirmBody = (await confirm.json()) as any;
|
||
expect(confirmBody.code).toBe(0);
|
||
expect(confirmBody.data.status).toBe('confirmed');
|
||
|
||
const pay = await admin.post(`/api/v1/admin/settlement-bills/${playerBill.id}/payments`, {
|
||
data: {
|
||
amount: unpaid,
|
||
method: 'e2e_cash',
|
||
remark: 'e2e full payment',
|
||
},
|
||
});
|
||
expect(pay.ok(), `payment status=${pay.status()}`).toBeTruthy();
|
||
const payBody = (await pay.json()) as any;
|
||
expect(payBody.code).toBe(0);
|
||
expect(payBody.data.bill.status).toBe('settled');
|
||
expect(Number(payBody.data.bill.paid_amount)).toBe(unpaid);
|
||
expect(Number(payBody.data.bill.unpaid_amount)).toBe(0);
|
||
|
||
const payments = await admin.get(
|
||
`/api/v1/admin/settlement-payments?settlement_period_id=${periodId}&size=20`,
|
||
);
|
||
const paymentsBody = (await payments.json()) as any;
|
||
expect(paymentsBody.code).toBe(0);
|
||
const recorded = paymentsBody.data.items.find(
|
||
(p: any) => Number(p.settlement_bill_id) === Number(playerBill.id),
|
||
);
|
||
expect(recorded, '收付台账应有该账单记录').toBeTruthy();
|
||
expect(Number(recorded.amount)).toBe(unpaid);
|
||
|
||
await admin.dispose();
|
||
});
|