package packagepkg import ( "context" "strconv" "gorm.io/gorm" "github.com/break/junhong_cmp_fiber/internal/infrastructure/audit" "github.com/break/junhong_cmp_fiber/internal/model" "github.com/break/junhong_cmp_fiber/pkg/constants" "github.com/break/junhong_cmp_fiber/pkg/errors" ) // SetAccessAudit 注入套餐商品统一审计 Writer。 func (s *Service) SetAccessAudit(db *gorm.DB, writer *audit.Writer) { s.db = db s.auditWriter = writer } func (s *Service) appendPackageAudit(ctx context.Context, tx *gorm.DB, actionCode, summary string, pkg *model.Package, beforeData, afterData map[string]any) error { if s.auditWriter == nil || s.db == nil { return errors.New(errors.CodeInvalidStatus, "套餐商品统一审计接缝未配置") } resources := []audit.ResourceInput{ audit.PackageResource(pkg, constants.AuditResourceRelationPrimary, constants.AuditResourceRolePackageTarget, beforeData, afterData), } if pkg.SeriesID > 0 { var series model.PackageSeries if err := tx.WithContext(ctx).Unscoped().Where("id = ?", pkg.SeriesID).First(&series).Error; err != nil { return errors.Wrap(errors.CodeDatabaseError, err, "查询套餐系列审计快照失败") } resources = append(resources, audit.PackageSeriesResource(&series, constants.AuditResourceRelationReference, constants.AuditResourceRolePackageSeries, nil, nil)) } return s.auditWriter.Append(ctx, tx, audit.AppendInput{ ActionCode: actionCode, Summary: summary, ScopeType: constants.AuditScopePlatform, Result: constants.AuditResultSuccess, Resources: resources, }) } func (s *Service) appendAllocationAudit(ctx context.Context, tx *gorm.DB, actionCode, summary string, allocation *model.ShopPackageAllocation, pkg *model.Package, beforeData, afterData map[string]any) error { if s.auditWriter == nil || s.db == nil { return errors.New(errors.CodeInvalidStatus, "店铺套餐统一审计接缝未配置") } resources := []audit.ResourceInput{ audit.ShopPackageAllocationResource(allocation, constants.AuditResourceRelationPrimary, constants.AuditResourceRoleShopPackageAllocation, beforeData, afterData), audit.PackageResource(pkg, constants.AuditResourceRelationReference, constants.AuditResourceRolePackageTarget, nil, nil), } var shop model.Shop if err := tx.WithContext(ctx).Unscoped().Where("id = ?", allocation.ShopID).First(&shop).Error; err != nil { return errors.Wrap(errors.CodeDatabaseError, err, "查询店铺套餐审计快照失败") } resources = append(resources, audit.ShopResource(&shop, constants.AuditResourceRelationReference, constants.AuditResourceRolePackageConfigShop)) return s.auditWriter.Append(ctx, tx, audit.AppendInput{ ActionCode: actionCode, Summary: summary, ScopeType: constants.AuditScopeShop, ScopeID: allocationShopID(allocation), Result: constants.AuditResultSuccess, Resources: resources, }) } func (s *Service) recordPackageFailure(ctx context.Context, actionCode, summary string, pkg *model.Package, beforeData map[string]any, businessErr error) { if pkg == nil { return } s.auditWriter.RecordFailure(ctx, s.db, audit.AppendInput{ ActionCode: actionCode, Summary: summary, ScopeType: constants.AuditScopePlatform, Resources: []audit.ResourceInput{audit.PackageResource( pkg, constants.AuditResourceRelationPrimary, constants.AuditResourceRolePackageTarget, beforeData, nil, )}, }, businessErr) } func (s *Service) recordAllocationFailure(ctx context.Context, actionCode, summary string, allocation *model.ShopPackageAllocation, pkg *model.Package, beforeData map[string]any, businessErr error) { if allocation == nil || pkg == nil { return } shop := &model.Shop{Model: gorm.Model{ID: allocation.ShopID}} s.auditWriter.RecordFailure(ctx, s.db, audit.AppendInput{ ActionCode: actionCode, Summary: summary, ScopeType: constants.AuditScopeShop, ScopeID: allocationShopID(allocation), Resources: []audit.ResourceInput{ audit.ShopPackageAllocationResource(allocation, constants.AuditResourceRelationPrimary, constants.AuditResourceRoleShopPackageAllocation, beforeData, nil), audit.PackageResource(pkg, constants.AuditResourceRelationReference, constants.AuditResourceRolePackageTarget, nil, nil), audit.ShopResource(shop, constants.AuditResourceRelationReference, constants.AuditResourceRolePackageConfigShop), }, }, businessErr) } func allocationShopID(allocation *model.ShopPackageAllocation) string { if allocation == nil { return "" } return uintString(allocation.ShopID) } func uintString(value uint) string { return strconv.FormatUint(uint64(value), 10) } func packageData(pkg *model.Package) map[string]any { if pkg == nil { return nil } return map[string]any{ "package_name": pkg.PackageName, "series_id": pkg.SeriesID, "package_type": pkg.PackageType, "duration_months": pkg.DurationMonths, "duration_days": pkg.DurationDays, "real_data_mb": pkg.RealDataMB, "virtual_data_mb": pkg.VirtualDataMB, "enable_virtual_data": pkg.EnableVirtualData, "cost_price": pkg.CostPrice, "suggested_retail_price": pkg.SuggestedRetailPrice, "price_config_status": pkg.PriceConfigStatus, "is_gift": pkg.IsGift, "status": pkg.Status, "shelf_status": pkg.ShelfStatus, "calendar_type": pkg.CalendarType, "data_reset_cycle": pkg.DataResetCycle, "expiry_base": pkg.ExpiryBase, } }