收口审计治理与套餐任务进展
Constraint: 在线热修前必须保存当前迭代分支全部有效代码进展 Confidence: medium Scope-risk: broad Directive: 后续修改需保持审计事件与业务事务边界一致 Tested: git diff --cached --check Not-tested: 未运行全量测试,提交用于切换分支前保存既有工作
This commit is contained in:
111
internal/service/package/audit.go
Normal file
111
internal/service/package/audit.go
Normal file
@@ -0,0 +1,111 @@
|
||||
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,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user