feat(settlement): redesign factory/partner/store statement bills
CI / verify (pull_request) Has been cancelled

Add WineryBill/StoreBill tables, partner review-send-confirm flow, daily/monthly cron, and admin multi-select confirm with status filters.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-22 17:25:49 +08:00
parent b534a569f8
commit b392c28787
22 changed files with 1549 additions and 543 deletions
+73 -3
View File
@@ -199,12 +199,19 @@ enum HqAdminRole {
}
enum PartnerBillStatus {
DRAFT
CONFIRMED
PENDING_REVIEW
AWAITING_CONFIRM
UNPAID
PAID
REJECTED
}
// 酒厂/门店对账单打款状态
enum FinancePayStatus {
UNPAID
PAID
}
enum StoreStatus {
OPEN
PAUSED
@@ -646,8 +653,9 @@ model PartnerBill {
orderCommission Decimal @default(0) @map("order_commission") @db.Decimal(10, 2)
redeemCommission Decimal @default(0) @map("redeem_commission") @db.Decimal(10, 2)
totalAmount Decimal @map("total_amount") @db.Decimal(10, 2)
status PartnerBillStatus @default(DRAFT)
status PartnerBillStatus @default(PENDING_REVIEW)
confirmedAt DateTime? @map("confirmed_at") @db.DateTime(3)
sentAt DateTime? @map("sent_at") @db.DateTime(3)
paidAt DateTime? @map("paid_at") @db.DateTime(3)
rejectReason String? @map("reject_reason") @db.VarChar(500)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
@@ -655,6 +663,7 @@ model PartnerBill {
partnerAccount PartnerAccount @relation(fields: [partnerAccountId], references: [id], onDelete: Restrict)
@@index([partnerAccountId, status])
@@unique([partnerAccountId, periodStart])
@@map("partner_bill")
}
@@ -830,6 +839,7 @@ model Store {
redeemPendingRecords RedeemPendingRecord[]
ratings StoreRating[]
payouts StorePayout[]
storeBills StoreBill[]
@@index([cityId, status])
@@index([partnerAccountId])
@@ -1104,10 +1114,32 @@ model StoreRating {
@@map("user_store_rating")
}
model StoreBill {
id BigInt @id @default(autoincrement()) @db.UnsignedBigInt
billNo String @unique @map("bill_no") @db.VarChar(32)
storeId BigInt @map("store_id") @db.UnsignedBigInt
billDate DateTime @map("bill_date") @db.DateTime(3)
redeemCount Int @default(0) @map("redeem_count")
redeemAmount Decimal @map("redeem_amount") @db.Decimal(10, 2)
settlementRate Decimal @map("settlement_rate") @db.Decimal(5, 4)
payoutAmount Decimal @map("payout_amount") @db.Decimal(10, 2)
status FinancePayStatus @default(UNPAID)
paidAt DateTime? @map("paid_at") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
store Store @relation(fields: [storeId], references: [id], onDelete: Restrict)
payouts StorePayout[]
@@unique([storeId, billDate])
@@index([status, billDate])
@@map("store_bill")
}
model StorePayout {
id BigInt @id @default(autoincrement()) @db.UnsignedBigInt
redeemRecordId BigInt @unique @map("redeem_record_id") @db.UnsignedBigInt
storeId BigInt @map("store_id") @db.UnsignedBigInt
storeBillId BigInt? @map("store_bill_id") @db.UnsignedBigInt
redeemAmount Decimal @map("redeem_amount") @db.Decimal(10, 2)
payoutAmount Decimal @map("payout_amount") @db.Decimal(10, 2)
settlementRate Decimal @map("settlement_rate") @db.Decimal(5, 4)
@@ -1119,11 +1151,49 @@ model StorePayout {
redeemRecord RedeemRecord @relation(fields: [redeemRecordId], references: [id], onDelete: Restrict)
store Store @relation(fields: [storeId], references: [id], onDelete: Restrict)
storeBill StoreBill? @relation(fields: [storeBillId], references: [id], onDelete: SetNull)
@@index([storeId, status])
@@index([storeBillId])
@@map("store_payout")
}
model WineryBill {
id BigInt @id @default(autoincrement()) @db.UnsignedBigInt
billNo String @unique @map("bill_no") @db.VarChar(32)
billDate DateTime @map("bill_date") @db.DateTime(3)
orderCount Int @default(0) @map("order_count")
orderAmount Decimal @map("order_amount") @db.Decimal(10, 2)
wineryRate Decimal @map("winery_rate") @db.Decimal(5, 4)
wineryAmount Decimal @map("winery_amount") @db.Decimal(10, 2)
status FinancePayStatus @default(UNPAID)
paidAt DateTime? @map("paid_at") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
items WineryBillItem[]
@@unique([billDate])
@@index([status, billDate])
@@map("winery_bill")
}
model WineryBillItem {
id BigInt @id @default(autoincrement()) @db.UnsignedBigInt
wineryBillId BigInt @map("winery_bill_id") @db.UnsignedBigInt
orderId BigInt @unique @map("order_id") @db.UnsignedBigInt
orderNo String @map("order_no") @db.VarChar(32)
deliveryType String @map("delivery_type") @db.VarChar(16)
payAmount Decimal @map("pay_amount") @db.Decimal(10, 2)
wineryAmount Decimal @map("winery_amount") @db.Decimal(10, 2)
paidAt DateTime @map("paid_at") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
wineryBill WineryBill @relation(fields: [wineryBillId], references: [id], onDelete: Cascade)
@@index([wineryBillId])
@@map("winery_bill_item")
}
// ─── LOG ──────────────────────────────────────────────
model LogThirdParty {
+1 -1
View File
@@ -218,7 +218,7 @@ async function main() {
orderCommission: 1200,
redeemCommission: 800,
totalAmount: 2000,
status: 'CONFIRMED',
status: 'UNPAID',
confirmedAt: now,
},
});
+1 -1
View File
@@ -896,7 +896,7 @@ async function main() {
totalAmount: 2000,
status: 'CONFIRMED',
status: 'UNPAID',
confirmedAt: now,
@@ -0,0 +1,7 @@
-- Optional one-time data remap before/after prisma db push when upgrading PartnerBillStatus.
-- Run against MySQL if legacy DRAFT/CONFIRMED rows exist.
-- Step A (before removing old enum values): widen enum if needed via Prisma push,
-- then remap:
UPDATE partner_bill SET status = 'PENDING_REVIEW' WHERE status = 'DRAFT';
UPDATE partner_bill SET status = 'UNPAID' WHERE status = 'CONFIRMED';