企业授权增强与资产列表扩展
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:
@@ -69,6 +69,8 @@ type Service struct {
|
||||
redis *redis.Client
|
||||
assetIdentifierStore *postgres.AssetIdentifierStore
|
||||
assetAuditService AssetAuditService
|
||||
enterpriseCardAuthStore *postgres.EnterpriseCardAuthorizationStore
|
||||
enterpriseStore *postgres.EnterpriseStore
|
||||
}
|
||||
|
||||
func New(
|
||||
@@ -107,6 +109,16 @@ func (s *Service) SetAssetIdentifierStore(store *postgres.AssetIdentifierStore)
|
||||
s.assetIdentifierStore = store
|
||||
}
|
||||
|
||||
// SetEnterpriseCardAuthStore 注入企业卡授权 store(用于列表响应回填企业信息)
|
||||
func (s *Service) SetEnterpriseCardAuthStore(store *postgres.EnterpriseCardAuthorizationStore) {
|
||||
s.enterpriseCardAuthStore = store
|
||||
}
|
||||
|
||||
// SetEnterpriseStore 注入企业 store(用于批量加载企业名称)
|
||||
func (s *Service) SetEnterpriseStore(store *postgres.EnterpriseStore) {
|
||||
s.enterpriseStore = store
|
||||
}
|
||||
|
||||
// SetDataDeductor 设置流量扣减回调
|
||||
// 在应用启动时由 bootstrap 调用,注入套餐扣减服务
|
||||
func (s *Service) SetDataDeductor(deductor DataDeductor) {
|
||||
@@ -229,6 +241,15 @@ func (s *Service) ListStandalone(ctx context.Context, req *dto.ListStandaloneIot
|
||||
if req.Keyword != "" {
|
||||
filters["keyword"] = req.Keyword
|
||||
}
|
||||
if req.NetworkStatus != nil {
|
||||
filters["network_status"] = *req.NetworkStatus
|
||||
}
|
||||
if req.AuthorizedEnterpriseID != nil {
|
||||
filters["authorized_enterprise_id"] = *req.AuthorizedEnterpriseID
|
||||
}
|
||||
if req.IsAuthorizedToEnterprise != nil {
|
||||
filters["is_authorized_to_enterprise"] = *req.IsAuthorizedToEnterprise
|
||||
}
|
||||
|
||||
// 代理用户注入 subordinate_shop_ids,让 Store 层走并行查询路径
|
||||
// 避免 PG 对 shop_id IN (...) + ORDER BY 选择全表扫描
|
||||
@@ -260,9 +281,45 @@ func (s *Service) ListStandalone(ctx context.Context, req *dto.ListStandaloneIot
|
||||
//TODO 这里不对,现在已经快照了,这里如果还这样处理明显是浪费的
|
||||
seriesMap := s.loadSeriesNames(ctx, cards)
|
||||
|
||||
// 批量加载企业授权信息
|
||||
cardAuthMap := make(map[uint]uint)
|
||||
enterpriseNameMap := make(map[uint]string)
|
||||
if s.enterpriseCardAuthStore != nil && len(cards) > 0 {
|
||||
cardIDs := make([]uint, 0, len(cards))
|
||||
for _, card := range cards {
|
||||
cardIDs = append(cardIDs, card.ID)
|
||||
}
|
||||
authMap, err := s.enterpriseCardAuthStore.GetActiveAuthEnterpriseByCardIDs(ctx, cardIDs)
|
||||
if err != nil {
|
||||
s.logger.Error("批量加载卡企业授权失败", zap.Error(err))
|
||||
} else {
|
||||
cardAuthMap = authMap
|
||||
}
|
||||
if s.enterpriseStore != nil && len(cardAuthMap) > 0 {
|
||||
eIDs := make([]uint, 0, len(cardAuthMap))
|
||||
seen := make(map[uint]struct{})
|
||||
for _, eid := range cardAuthMap {
|
||||
if _, ok := seen[eid]; !ok {
|
||||
seen[eid] = struct{}{}
|
||||
eIDs = append(eIDs, eid)
|
||||
}
|
||||
}
|
||||
nameMap, err := s.enterpriseStore.GetNameMapByIDs(ctx, eIDs)
|
||||
if err != nil {
|
||||
s.logger.Error("批量加载企业名称失败", zap.Error(err))
|
||||
} else {
|
||||
enterpriseNameMap = nameMap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list := make([]*dto.StandaloneIotCardResponse, 0, len(cards))
|
||||
for _, card := range cards {
|
||||
item := s.toStandaloneResponse(card, shopMap, seriesMap)
|
||||
if eid, ok := cardAuthMap[card.ID]; ok {
|
||||
item.AuthorizedEnterpriseID = &eid
|
||||
item.AuthorizedEnterpriseName = enterpriseNameMap[eid]
|
||||
}
|
||||
list = append(list, item)
|
||||
}
|
||||
|
||||
@@ -411,6 +468,9 @@ func (s *Service) toStandaloneResponse(card *model.IotCard, shopMap map[uint]str
|
||||
EnablePolling: card.EnablePolling,
|
||||
SeriesID: card.SeriesID,
|
||||
DeviceVirtualNo: card.DeviceVirtualNo,
|
||||
AssetStatus: card.AssetStatus,
|
||||
AssetStatusName: constants.GetAssetStatusName(card.AssetStatus),
|
||||
Generation: card.Generation,
|
||||
CreatedAt: card.CreatedAt,
|
||||
UpdatedAt: card.UpdatedAt,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user