package repository import ( "fmt" "github.com/wmms/wmms/internal/model" "github.com/wmms/wmms/pkg/database" ) type PartnerRepository struct{} func NewPartnerRepository() *PartnerRepository { return &PartnerRepository{} } func (r *PartnerRepository) List(organizationID int64, role string, limit, offset int) ([]model.BusinessPartner, int64, error) { // 角色过滤写成一份,由计数和取数共用:两处各写一遍,改一处漏一处就会让 // 总数和列表对不上(总数算的是全部,列表却只有供应商)。 filter := `FROM organization_partners op JOIN business_partners bp ON bp.id = op.business_partner_id WHERE op.organization_id = ?` args := []interface{}{organizationID} if role == "supplier" { filter += ` AND op.is_supplier = TRUE` } if role == "customer" { filter += ` AND op.is_customer = TRUE` } var total int64 if err := database.DB.QueryRow(`SELECT COUNT(*) `+filter, args...).Scan(&total); err != nil { return nil, 0, err } query := `SELECT op.id, op.organization_id, bp.id, op.partner_code, bp.legal_name, COALESCE(bp.unified_credit_code, ''), COALESCE(bp.contact_name, ''), COALESCE(bp.contact_phone, ''), COALESCE(bp.address, ''), op.is_supplier, op.is_customer, COALESCE(op.supplier_status, ''), COALESCE(op.customer_status, ''), COALESCE(op.settlement_currency, ''), COALESCE(op.payment_terms, '') ` + filter + ` ORDER BY op.partner_code LIMIT ? OFFSET ?` // 计数查询已经用完 args,这里追加分页参数不会再影响到它 rows, err := database.DB.Query(query, append(args, limit, offset)...) if err != nil { return nil, 0, err } defer rows.Close() items := make([]model.BusinessPartner, 0) for rows.Next() { var item model.BusinessPartner if err := rows.Scan(&item.ID, &item.OrganizationID, &item.BusinessPartnerID, &item.PartnerCode, &item.LegalName, &item.UnifiedCreditCode, &item.ContactName, &item.ContactPhone, &item.Address, &item.IsSupplier, &item.IsCustomer, &item.SupplierStatus, &item.CustomerStatus, &item.SettlementCurrency, &item.PaymentTerms); err != nil { return nil, 0, err } items = append(items, item) } return items, total, rows.Err() } func (r *PartnerRepository) Create(item *model.BusinessPartner) (err error) { tx, err := database.DB.Begin() if err != nil { return err } defer func() { if err != nil { _ = tx.Rollback() } }() result, err := tx.Exec(`INSERT INTO business_partners (legal_name, unified_credit_code, contact_name, contact_phone, address) VALUES (?, NULLIF(?, ''), NULLIF(?, ''), NULLIF(?, ''), NULLIF(?, ''))`, item.LegalName, item.UnifiedCreditCode, item.ContactName, item.ContactPhone, item.Address) if err != nil { return err } item.BusinessPartnerID, err = result.LastInsertId() if err != nil { return err } result, err = tx.Exec(`INSERT INTO organization_partners (organization_id, business_partner_id, partner_code, is_supplier, is_customer, supplier_status, customer_status, settlement_currency, payment_terms) VALUES (?, ?, ?, ?, ?, NULLIF(?, ''), NULLIF(?, ''), NULLIF(?, ''), NULLIF(?, ''))`, item.OrganizationID, item.BusinessPartnerID, item.PartnerCode, item.IsSupplier, item.IsCustomer, item.SupplierStatus, item.CustomerStatus, item.SettlementCurrency, item.PaymentTerms) if err != nil { return err } item.ID, err = result.LastInsertId() if err != nil { return err } return tx.Commit() } func (r *PartnerRepository) Update(item *model.BusinessPartner) (err error) { tx, err := database.DB.Begin() if err != nil { return err } defer func() { if err != nil { _ = tx.Rollback() } }() var businessPartnerID int64 if err = tx.QueryRow(`SELECT business_partner_id FROM organization_partners WHERE id = ? AND organization_id = ? FOR UPDATE`, item.ID, item.OrganizationID).Scan(&businessPartnerID); err != nil { return err } if _, err = tx.Exec(`UPDATE business_partners SET legal_name = ?, unified_credit_code = NULLIF(?, ''), contact_name = NULLIF(?, ''), contact_phone = NULLIF(?, ''), address = NULLIF(?, '') WHERE id = ?`, item.LegalName, item.UnifiedCreditCode, item.ContactName, item.ContactPhone, item.Address, businessPartnerID); err != nil { return err } if _, err = tx.Exec(`UPDATE organization_partners SET is_supplier = ?, is_customer = ?, supplier_status = NULLIF(?, ''), customer_status = NULLIF(?, ''), settlement_currency = NULLIF(?, ''), payment_terms = NULLIF(?, '') WHERE id = ? AND organization_id = ?`, item.IsSupplier, item.IsCustomer, item.SupplierStatus, item.CustomerStatus, item.SettlementCurrency, item.PaymentTerms, item.ID, item.OrganizationID); err != nil { return err } if err = tx.Commit(); err != nil { return fmt.Errorf("commit partner update: %w", err) } return nil }