七月迭代短暂完结,还有很多后端的关键东西没有弄,这是一版赶时间做的东西
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m26s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m26s
This commit is contained in:
@@ -47,64 +47,6 @@ func (s *Service) GatewayGetSlotInfo(ctx context.Context, identifier string) (*g
|
||||
})
|
||||
}
|
||||
|
||||
// GatewaySetSpeedLimit 通过标识符设置设备限速
|
||||
func (s *Service) GatewaySetSpeedLimit(ctx context.Context, identifier string, req *dto.SetSpeedLimitRequest) error {
|
||||
device, imei, err := s.getGatewayDevice(ctx, identifier)
|
||||
if err != nil {
|
||||
s.logDeviceOperation(
|
||||
ctx,
|
||||
constants.AssetAuditOpDeviceSpeedLimit,
|
||||
"设备限速失败",
|
||||
constants.AssetAuditResultFailed,
|
||||
nil,
|
||||
nil,
|
||||
map[string]any{
|
||||
"identifier": identifier,
|
||||
"speed_limit": req.SpeedLimit,
|
||||
},
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
err,
|
||||
)
|
||||
return err
|
||||
}
|
||||
if err = s.gatewayClient.SetSpeedLimit(ctx, &gateway.SpeedLimitReq{
|
||||
DeviceID: imei,
|
||||
SpeedLimit: req.SpeedLimit,
|
||||
}); err != nil {
|
||||
s.logDeviceOperation(
|
||||
ctx,
|
||||
constants.AssetAuditOpDeviceSpeedLimit,
|
||||
"设备限速失败",
|
||||
constants.AssetAuditResultFailed,
|
||||
device,
|
||||
map[string]any{"device": deviceSnapshot(device)},
|
||||
map[string]any{"speed_limit": req.SpeedLimit},
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
err,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
s.logDeviceOperation(
|
||||
ctx,
|
||||
constants.AssetAuditOpDeviceSpeedLimit,
|
||||
"设备限速",
|
||||
constants.AssetAuditResultSuccess,
|
||||
device,
|
||||
map[string]any{"device": deviceSnapshot(device)},
|
||||
map[string]any{"speed_limit": req.SpeedLimit},
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
nil,
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GatewaySetWiFi 通过标识符设置设备 WiFi
|
||||
func (s *Service) GatewaySetWiFi(ctx context.Context, identifier string, req *dto.SetWiFiRequest) error {
|
||||
device, imei, err := s.getGatewayDevice(ctx, identifier)
|
||||
|
||||
84
internal/service/device/realname_policy_batch.go
Normal file
84
internal/service/device/realname_policy_batch.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package device
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
||||
"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 devices []model.Device
|
||||
query := middleware.ApplyShopFilter(ctx, tx.Model(&model.Device{})).Clauses(clause.Locking{Strength: "UPDATE"})
|
||||
if err := query.Where("id IN ?", ids).Find(&devices).Error; err != nil {
|
||||
return errors.Wrap(errors.CodeDatabaseError, err, "查询批量设备资产失败")
|
||||
}
|
||||
if len(devices) != len(ids) {
|
||||
return errors.New(errors.CodeForbidden, "无权限操作该资源或资源不存在")
|
||||
}
|
||||
result := tx.Model(&model.Device{}).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.logDeviceOperation(
|
||||
ctx,
|
||||
constants.AssetAuditOpAssetRealnamePolicy,
|
||||
"批量更新设备实名认证策略",
|
||||
constants.AssetAuditResultSuccess,
|
||||
nil,
|
||||
nil,
|
||||
map[string]any{"asset_ids": ids, "realname_policy": req.RealnamePolicy},
|
||||
len(ids),
|
||||
len(ids),
|
||||
0,
|
||||
nil,
|
||||
)
|
||||
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
|
||||
}
|
||||
@@ -206,6 +206,9 @@ func (s *Service) List(ctx context.Context, req *dto.ListDeviceRequest) (*dto.Li
|
||||
if req.ActivationStatus != nil {
|
||||
filters["activation_status"] = *req.ActivationStatus
|
||||
}
|
||||
if req.RealNameStatus != nil {
|
||||
filters["real_name_status"] = *req.RealNameStatus
|
||||
}
|
||||
shopIDs, hasShopIDs := normalizeShopIDs(req.ShopIDs)
|
||||
if hasShopIDs {
|
||||
filters["shop_ids"] = shopIDs
|
||||
|
||||
Reference in New Issue
Block a user