企业授权增强与资产列表扩展
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m9s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m9s
- 企业卡授权唯一约束:新增 DB 迁移(000154),卡级部分唯一索引防止同一张卡被多个企业同时持有,Service 层新增跨企业冲突检测 - 单卡列表新增 network_status 过滤参数 - 单卡/设备列表新增 asset_status、asset_status_name、generation 响应字段 - 单卡/设备列表新增企业维度过滤(authorized_enterprise_id、is_authorized_to_enterprise)及响应中企业授权信息(批量加载,无 N+1) - 主钱包流水/退款列表新增 asset_identifier 精确过滤参数 - 企业卡授权/收回接口升级为三模式(list/range/filter),企业设备授权/收回升级为双模式(list/filter) - 升级 sonic v1.14.2 → v1.15.2 以兼容 Go 1.26 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -20,19 +20,21 @@ import (
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
db *gorm.DB
|
||||
redis *redis.Client
|
||||
deviceStore *postgres.DeviceStore
|
||||
deviceSimBindingStore *postgres.DeviceSimBindingStore
|
||||
iotCardStore *postgres.IotCardStore
|
||||
shopStore *postgres.ShopStore
|
||||
assetAllocationRecordStore *postgres.AssetAllocationRecordStore
|
||||
shopPackageAllocationStore *postgres.ShopPackageAllocationStore
|
||||
shopSeriesAllocationStore *postgres.ShopSeriesAllocationStore
|
||||
packageSeriesStore *postgres.PackageSeriesStore
|
||||
gatewayClient *gateway.Client
|
||||
assetIdentifierStore *postgres.AssetIdentifierStore
|
||||
assetAuditService AssetAuditService
|
||||
db *gorm.DB
|
||||
redis *redis.Client
|
||||
deviceStore *postgres.DeviceStore
|
||||
deviceSimBindingStore *postgres.DeviceSimBindingStore
|
||||
iotCardStore *postgres.IotCardStore
|
||||
shopStore *postgres.ShopStore
|
||||
assetAllocationRecordStore *postgres.AssetAllocationRecordStore
|
||||
shopPackageAllocationStore *postgres.ShopPackageAllocationStore
|
||||
shopSeriesAllocationStore *postgres.ShopSeriesAllocationStore
|
||||
packageSeriesStore *postgres.PackageSeriesStore
|
||||
gatewayClient *gateway.Client
|
||||
assetIdentifierStore *postgres.AssetIdentifierStore
|
||||
assetAuditService AssetAuditService
|
||||
enterpriseDeviceAuthStore *postgres.EnterpriseDeviceAuthorizationStore
|
||||
enterpriseStore *postgres.EnterpriseStore
|
||||
}
|
||||
|
||||
func New(
|
||||
@@ -49,21 +51,25 @@ func New(
|
||||
gatewayClient *gateway.Client,
|
||||
assetIdentifierStore *postgres.AssetIdentifierStore,
|
||||
assetAuditService AssetAuditService,
|
||||
enterpriseDeviceAuthStore *postgres.EnterpriseDeviceAuthorizationStore,
|
||||
enterpriseStore *postgres.EnterpriseStore,
|
||||
) *Service {
|
||||
return &Service{
|
||||
db: db,
|
||||
redis: rds,
|
||||
deviceStore: deviceStore,
|
||||
deviceSimBindingStore: deviceSimBindingStore,
|
||||
iotCardStore: iotCardStore,
|
||||
shopStore: shopStore,
|
||||
assetAllocationRecordStore: assetAllocationRecordStore,
|
||||
shopPackageAllocationStore: shopPackageAllocationStore,
|
||||
shopSeriesAllocationStore: shopSeriesAllocationStore,
|
||||
packageSeriesStore: packageSeriesStore,
|
||||
gatewayClient: gatewayClient,
|
||||
assetIdentifierStore: assetIdentifierStore,
|
||||
assetAuditService: assetAuditService,
|
||||
db: db,
|
||||
redis: rds,
|
||||
deviceStore: deviceStore,
|
||||
deviceSimBindingStore: deviceSimBindingStore,
|
||||
iotCardStore: iotCardStore,
|
||||
shopStore: shopStore,
|
||||
assetAllocationRecordStore: assetAllocationRecordStore,
|
||||
shopPackageAllocationStore: shopPackageAllocationStore,
|
||||
shopSeriesAllocationStore: shopSeriesAllocationStore,
|
||||
packageSeriesStore: packageSeriesStore,
|
||||
gatewayClient: gatewayClient,
|
||||
assetIdentifierStore: assetIdentifierStore,
|
||||
assetAuditService: assetAuditService,
|
||||
enterpriseDeviceAuthStore: enterpriseDeviceAuthStore,
|
||||
enterpriseStore: enterpriseStore,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,6 +139,12 @@ func (s *Service) List(ctx context.Context, req *dto.ListDeviceRequest) (*dto.Li
|
||||
if req.HasActivePackage != nil {
|
||||
filters["has_active_package"] = *req.HasActivePackage
|
||||
}
|
||||
if req.AuthorizedEnterpriseID != nil {
|
||||
filters["authorized_enterprise_id"] = *req.AuthorizedEnterpriseID
|
||||
}
|
||||
if req.IsAuthorizedToEnterprise != nil {
|
||||
filters["is_authorized_to_enterprise"] = *req.IsAuthorizedToEnterprise
|
||||
}
|
||||
|
||||
devices, total, err := s.deviceStore.List(ctx, opts, filters)
|
||||
if err != nil {
|
||||
@@ -151,9 +163,31 @@ func (s *Service) List(ctx context.Context, req *dto.ListDeviceRequest) (*dto.Li
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 批量查询有效企业授权(避免 N+1 查询)
|
||||
deviceEnterpriseMap, err := s.enterpriseDeviceAuthStore.GetActiveAuthEnterpriseByDeviceIDs(ctx, deviceIDs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询设备企业授权失败")
|
||||
}
|
||||
enterpriseIDs := make([]uint, 0)
|
||||
seen := make(map[uint]struct{})
|
||||
for _, eid := range deviceEnterpriseMap {
|
||||
if _, ok := seen[eid]; !ok {
|
||||
seen[eid] = struct{}{}
|
||||
enterpriseIDs = append(enterpriseIDs, eid)
|
||||
}
|
||||
}
|
||||
enterpriseNameMap, err := s.enterpriseStore.GetNameMapByIDs(ctx, enterpriseIDs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询企业名称失败")
|
||||
}
|
||||
|
||||
list := make([]*dto.DeviceResponse, 0, len(devices))
|
||||
for _, device := range devices {
|
||||
item := s.toDeviceResponse(device, shopMap, seriesMap, bindingCounts, activationStatuses)
|
||||
if eid, ok := deviceEnterpriseMap[device.ID]; ok {
|
||||
item.AuthorizedEnterpriseID = &eid
|
||||
item.AuthorizedEnterpriseName = enterpriseNameMap[eid]
|
||||
}
|
||||
list = append(list, item)
|
||||
}
|
||||
|
||||
@@ -941,6 +975,9 @@ func (s *Service) toDeviceResponse(device *model.Device, shopMap map[uint]string
|
||||
SoftwareVersion: device.SoftwareVersion,
|
||||
SwitchMode: device.SwitchMode,
|
||||
LastGatewaySyncAt: device.LastGatewaySyncAt,
|
||||
AssetStatus: device.AssetStatus,
|
||||
AssetStatusName: constants.GetAssetStatusName(device.AssetStatus),
|
||||
Generation: device.Generation,
|
||||
}
|
||||
|
||||
if device.ShopID != nil && *device.ShopID > 0 {
|
||||
|
||||
Reference in New Issue
Block a user