package service import ( "context" "fmt" "strings" "oci-portal/internal/oci" ) // maxInvoicePdfBytes 是发票 PDF 中转上限;正常发票远小于此,超限视为异常。 const maxInvoicePdfBytes = 20 << 20 // Invoices 列出租户发票;year>0 只取该自然年(前端按年懒加载),0 为全量。 func (s *OciConfigService) Invoices(ctx context.Context, id uint, year int) ([]oci.Invoice, error) { if year != 0 && (year < 2000 || year > 2100) { return nil, fmt.Errorf("invoices: invalid year %d", year) } cred, err := s.credentialsByID(ctx, id) if err != nil { return nil, err } return s.client.ListInvoices(ctx, cred, year) } // InvoiceLines 列出一张发票的费用明细。 func (s *OciConfigService) InvoiceLines(ctx context.Context, id uint, internalID string) ([]oci.InvoiceLine, error) { if internalID == "" { return nil, fmt.Errorf("invoice lines: internal invoice id is empty") } cred, err := s.credentialsByID(ctx, id) if err != nil { return nil, err } return s.client.ListInvoiceLines(ctx, cred, internalID) } // InvoicePdf 拉取一张发票的 PDF 原文。 func (s *OciConfigService) InvoicePdf(ctx context.Context, id uint, internalID string) ([]byte, error) { if internalID == "" { return nil, fmt.Errorf("invoice pdf: internal invoice id is empty") } cred, err := s.credentialsByID(ctx, id) if err != nil { return nil, err } return s.client.DownloadInvoicePdf(ctx, cred, internalID, maxInvoicePdfBytes) } // PayInvoice 按订阅默认付款方式支付发票;email 接收付款回执,必填。 func (s *OciConfigService) PayInvoice(ctx context.Context, id uint, internalID, email string) error { if internalID == "" { return fmt.Errorf("pay invoice: internal invoice id is empty") } if !strings.Contains(email, "@") { return fmt.Errorf("pay invoice: invalid receipt email") } cred, err := s.credentialsByID(ctx, id) if err != nil { return err } return s.client.PayInvoice(ctx, cred, internalID, email) } // PaymentMethods 列出订阅上登记的全部付款方式。 func (s *OciConfigService) PaymentMethods(ctx context.Context, id uint) ([]oci.PaymentMethod, error) { cred, err := s.credentialsByID(ctx, id) if err != nil { return nil, err } return s.client.ListPaymentMethods(ctx, cred) }