package iot_card import ( "context" "github.com/break/junhong_cmp_fiber/internal/model" "github.com/break/junhong_cmp_fiber/internal/model/dto" assetAuditSvc "github.com/break/junhong_cmp_fiber/internal/service/asset_audit" "github.com/break/junhong_cmp_fiber/pkg/constants" "github.com/break/junhong_cmp_fiber/pkg/errors" "github.com/break/junhong_cmp_fiber/pkg/middleware" "gorm.io/gorm" "gorm.io/gorm/clause" ) // BatchUpdateRealnamePolicy 批量更新卡实名认证策略,整批校验后在单事务内全成全败。 func (s *Service) BatchUpdateRealnamePolicy(ctx context.Context, req *dto.BatchUpdateAssetRealnamePolicyRequest) (*dto.BatchUpdateAssetRealnamePolicyResponse, error) { if middleware.GetUserTypeFromContext(ctx) == constants.UserTypeEnterprise { return nil, errors.New(errors.CodeForbidden, "企业账号无权修改卡实名认证策略") } ids, err := validateBatchRealnamePolicyRequest(req) if err != nil { return nil, err } err = s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { var cards []model.IotCard query := middleware.ApplyShopFilter(ctx, tx.Model(&model.IotCard{})).Clauses(clause.Locking{Strength: "UPDATE"}) if err := query.Where("id IN ?", ids).Find(&cards).Error; err != nil { return errors.Wrap(errors.CodeDatabaseError, err, "查询批量卡资产失败") } if len(cards) != len(ids) { return errors.New(errors.CodeForbidden, "无权限操作该资源或资源不存在") } result := tx.Model(&model.IotCard{}).Where("id IN ?", ids).Update("realname_policy", req.RealnamePolicy) if result.Error != nil { return errors.Wrap(errors.CodeDatabaseError, result.Error, "批量更新卡实名认证策略失败") } if result.RowsAffected != int64(len(ids)) { return errors.New(errors.CodeConflict, "卡资产状态已变化,请刷新后重试") } return nil }) if err != nil { return nil, err } s.logCardAudit(ctx, assetAuditSvc.BuildLogParams{ OperationType: constants.AssetAuditOpCardRealnamePolicy, OperationDesc: "批量更新卡实名认证策略", ResultStatus: constants.AssetAuditResultSuccess, BatchTotal: len(ids), SuccessCount: len(ids), AfterData: map[string]any{ "asset_ids": ids, "realname_policy": req.RealnamePolicy, }, }) return &dto.BatchUpdateAssetRealnamePolicyResponse{SuccessCount: len(ids), RealnamePolicy: req.RealnamePolicy}, nil } func validateBatchRealnamePolicyRequest(req *dto.BatchUpdateAssetRealnamePolicyRequest) ([]uint, error) { if req == nil || len(req.AssetIDs) == 0 || len(req.AssetIDs) > 500 || !isValidRealnamePolicy(req.RealnamePolicy) { return nil, errors.New(errors.CodeInvalidParam) } seen := make(map[uint]struct{}, len(req.AssetIDs)) ids := make([]uint, 0, len(req.AssetIDs)) for _, id := range req.AssetIDs { if id == 0 { return nil, errors.New(errors.CodeInvalidParam) } if _, exists := seen[id]; exists { return nil, errors.New(errors.CodeInvalidParam, "资产ID不能重复") } seen[id] = struct{}{} ids = append(ids, id) } return ids, nil } func isValidRealnamePolicy(policy string) bool { return policy == constants.RealnamePolicyNone || policy == constants.RealnamePolicyBeforeOrder || policy == constants.RealnamePolicyAfterOrder }