feat(P20T2-1,P20T2-2,P20T2-3): 卡授权/交易/支付标记/发票绑定/ERP出站后端

这个提交包含在:
2026-03-11 06:41:11 +08:00
父节点 539c2cc4dd
当前提交 dc74d9e53f
共修改 23 个文件,包含 4265 行新增和 218 行删除
+111 -5
查看文件
@@ -230,6 +230,8 @@ model Department {
workflow_instances WorkflowInstance[]
budget_pools BudgetPool[]
travel_orders TravelOrder[]
card_authorizations CardAuthorization[]
card_transactions CardTransaction[]
@@index([parent_id])
@@map("departments")
@@ -300,7 +302,11 @@ model Employee {
uploaded_invoices InvoicePool[] @relation("InvoiceUploader")
overridden_invoices InvoicePool[] @relation("InvoiceOverrideBy")
requested_invoice_verifications InvoiceVerificationRecord[] @relation("InvoiceVerificationRequester")
travel_orders TravelOrder[]
travel_orders TravelOrder[] @relation("TravelOrderEmployee")
paid_travel_orders TravelOrder[] @relation("TravelOrderPaidBy")
card_authorizations CardAuthorization[]
card_transactions CardTransaction[] @relation("CardTransactionEmployee")
freeze_suggested_card_transactions CardTransaction[] @relation("CardTransactionFreezeSuggestedBy")
workflow_instances_started WorkflowInstance[] @relation("WorkflowInstanceSubmitter")
workflow_history_actions WorkflowHistory[] @relation("WorkflowHistoryActor")
@@ -487,6 +493,7 @@ model LegalEntity {
suppliers Supplier[]
purchase_requests PurchaseRequest[]
travel_requests TravelRequest[]
card_authorizations CardAuthorization[]
asset_cards AssetCard[]
budget_pools BudgetPool[] @relation("BudgetPoolLegalEntity")
@@ -517,6 +524,7 @@ model CostCenter {
budget_pools BudgetPool[] @relation("BudgetPoolCostCenter")
purchase_requests PurchaseRequest[]
travel_requests TravelRequest[]
card_authorizations CardAuthorization[]
asset_cards AssetCard[]
@@unique([legal_entity_id, code], map: "legal_entity_cost_center_code_ux")
@@ -1061,6 +1069,7 @@ model InvoicePool {
linked_reimbursement_id String? @db.Uuid
linked_item_id String? @db.Uuid
travel_order_id String? @db.Uuid
remarks String?
ocr_provider OcrProvider @default(tencent)
@@ -1099,6 +1108,7 @@ model InvoicePool {
ocr_result OcrResult? @relation(fields: [ocr_result_id], references: [id], onDelete: SetNull)
linked_reimbursement ReimbursementForm? @relation(fields: [linked_reimbursement_id], references: [id], onDelete: SetNull)
linked_item ReimbursementItem? @relation(fields: [linked_item_id], references: [id], onDelete: SetNull)
travel_order TravelOrder? @relation(fields: [travel_order_id], references: [id], onDelete: SetNull)
verification_records InvoiceVerificationRecord[]
@@index([owner_employee_id])
@@ -1109,6 +1119,7 @@ model InvoicePool {
@@index([status, ocr_locked_at, created_at], map: "idx_invoice_pool_ocr_queue")
@@index([owner_employee_id, status, created_at], map: "idx_invoice_pool_owner_status_created_at")
@@index([linked_reimbursement_id])
@@index([travel_order_id])
@@map("invoice_pool")
}
@@ -1169,6 +1180,7 @@ model BudgetPool {
ledger_entries BudgetLedgerEntry[]
purchase_requests PurchaseRequest[]
travel_requests TravelRequest[]
card_authorizations CardAuthorization[]
@@index([department_id, status], map: "idx_budget_pools_department_status")
@@index([legal_entity_id, cost_center_id, status], map: "idx_budget_pools_scope_status")
@@ -1307,9 +1319,11 @@ model TravelRequest {
cost_center CostCenter @relation(fields: [cost_center_id], references: [id], onDelete: Restrict)
budget_pool BudgetPool? @relation(fields: [budget_pool_id], references: [id], onDelete: SetNull)
segments TravelRequestSegment[]
travel_orders TravelOrder[]
workflow_instances WorkflowInstance[]
segments TravelRequestSegment[]
travel_orders TravelOrder[]
card_authorizations CardAuthorization[]
card_transactions CardTransaction[]
workflow_instances WorkflowInstance[]
@@index([applicant_employee_id, start_date], map: "idx_travel_requests_applicant_start")
@@index([submitter_id], map: "idx_travel_requests_submitter")
@@ -1354,6 +1368,11 @@ model TravelOrder {
amount Decimal? @db.Decimal(14, 2)
currency String @default("CNY") @db.VarChar(8)
status String @default("imported") @db.VarChar(20)
payment_voucher_no String? @db.VarChar(50)
payment_date DateTime? @db.Date
payment_channel String? @db.VarChar(20)
paid_at DateTime?
paid_by String? @db.Uuid
raw_payload Json?
created_at DateTime @default(now())
@@ -1361,18 +1380,105 @@ model TravelOrder {
updated_at DateTime @updatedAt
updated_by String? @db.Uuid
employee Employee @relation(fields: [employee_id], references: [id], onDelete: Restrict)
employee Employee @relation("TravelOrderEmployee", fields: [employee_id], references: [id], onDelete: Restrict)
department Department? @relation(fields: [department_id], references: [id], onDelete: SetNull)
linked_reimbursement ReimbursementForm? @relation(fields: [linked_reimbursement_id], references: [id], onDelete: SetNull)
travel_request TravelRequest? @relation(fields: [travel_request_id], references: [id], onDelete: SetNull)
paid_by_employee Employee? @relation("TravelOrderPaidBy", fields: [paid_by], references: [id], onDelete: SetNull)
invoice_pool_items InvoicePool[]
card_transactions CardTransaction[]
@@unique([source, external_order_no], map: "travel_orders_source_order_ux")
@@index([employee_id, occurred_at], map: "idx_travel_orders_employee_occurred")
@@index([linked_reimbursement_id])
@@index([travel_request_id])
@@index([paid_by])
@@map("travel_orders")
}
model CardAuthorization {
id String @id @default(uuid()) @db.Uuid
source String @default("manual") @db.VarChar(32)
external_auth_no String
employee_id String @db.Uuid
department_id String? @db.Uuid
travel_request_id String @db.Uuid
budget_pool_id String? @db.Uuid
legal_entity_id String @db.Uuid
cost_center_id String @db.Uuid
authorized_amount Decimal @db.Decimal(14, 2)
settled_amount Decimal @default(0) @db.Decimal(14, 2)
reversed_amount Decimal @default(0) @db.Decimal(14, 2)
currency String @default("CNY") @db.VarChar(8)
occurred_at DateTime?
expires_at DateTime?
status String @default("authorized") @db.VarChar(32)
raw_payload Json?
created_at DateTime @default(now())
created_by String? @db.Uuid
updated_at DateTime @updatedAt
updated_by String? @db.Uuid
employee Employee @relation(fields: [employee_id], references: [id], onDelete: Restrict)
department Department? @relation(fields: [department_id], references: [id], onDelete: SetNull)
travel_request TravelRequest @relation(fields: [travel_request_id], references: [id], onDelete: Cascade)
budget_pool BudgetPool? @relation(fields: [budget_pool_id], references: [id], onDelete: SetNull)
legal_entity LegalEntity @relation(fields: [legal_entity_id], references: [id], onDelete: Restrict)
cost_center CostCenter @relation(fields: [cost_center_id], references: [id], onDelete: Restrict)
card_transactions CardTransaction[]
@@unique([source, external_auth_no], map: "card_authorizations_source_auth_ux")
@@index([employee_id, occurred_at], map: "idx_card_authorizations_employee_occurred")
@@index([department_id, status], map: "idx_card_authorizations_department_status")
@@index([travel_request_id, status], map: "idx_card_authorizations_request_status")
@@index([budget_pool_id], map: "idx_card_authorizations_budget_pool")
@@index([legal_entity_id, cost_center_id], map: "idx_card_authorizations_legal_cost_center")
@@map("card_authorizations")
}
model CardTransaction {
id String @id @default(uuid()) @db.Uuid
source String @default("manual") @db.VarChar(32)
external_txn_id String
card_authorization_id String? @db.Uuid
employee_id String @db.Uuid
department_id String? @db.Uuid
travel_request_id String @db.Uuid
travel_order_id String? @db.Uuid
amount Decimal @db.Decimal(14, 2)
currency String @default("CNY") @db.VarChar(8)
txn_type String @db.VarChar(20)
status String @default("pending") @db.VarChar(20)
occurred_at DateTime?
freeze_suggested_at DateTime?
freeze_suggested_by String? @db.Uuid
freeze_reason_code String? @db.VarChar(32)
freeze_reason_note String?
raw_payload Json?
created_at DateTime @default(now())
created_by String? @db.Uuid
updated_at DateTime @updatedAt
updated_by String? @db.Uuid
card_authorization CardAuthorization? @relation(fields: [card_authorization_id], references: [id], onDelete: SetNull)
employee Employee @relation("CardTransactionEmployee", fields: [employee_id], references: [id], onDelete: Restrict)
department Department? @relation(fields: [department_id], references: [id], onDelete: SetNull)
travel_request TravelRequest @relation(fields: [travel_request_id], references: [id], onDelete: Cascade)
travel_order TravelOrder? @relation(fields: [travel_order_id], references: [id], onDelete: SetNull)
freeze_suggested_by_employee Employee? @relation("CardTransactionFreezeSuggestedBy", fields: [freeze_suggested_by], references: [id], onDelete: SetNull)
@@unique([source, external_txn_id], map: "card_transactions_source_txn_ux")
@@index([card_authorization_id], map: "idx_card_transactions_authorization")
@@index([employee_id, occurred_at], map: "idx_card_transactions_employee_occurred")
@@index([department_id, status], map: "idx_card_transactions_department_status")
@@index([travel_request_id], map: "idx_card_transactions_request")
@@index([travel_order_id], map: "idx_card_transactions_order")
@@index([freeze_suggested_by], map: "idx_card_transactions_freeze_suggested_by")
@@map("card_transactions")
}
model NotificationChannel {
id String @id @default(uuid()) @db.Uuid
channel_type String @db.VarChar(32)