feat: 实现企业卡授权和授权记录管理功能
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m9s

主要功能:
- 添加企业卡授权/回收接口 (POST /enterprises/:id/allocate-cards, recall-cards)
- 添加授权记录管理接口 (GET/PUT /authorizations)
- 实现代理用户数据权限过滤(只能查看自己店铺下企业的授权记录)
- 添加 GORM callback 支持授权记录表的数据权限过滤

技术改进:
- 原生 SQL 查询手动添加数据权限过滤(ListWithJoin, GetByIDWithJoin)
- 移除卡授权预检接口(allocate-cards/preview),保留内部方法
- 完善单元测试和集成测试覆盖
This commit is contained in:
2026-01-26 15:07:03 +08:00
parent 45aa7deb87
commit fdcff33058
42 changed files with 4782 additions and 298 deletions

View File

@@ -32,7 +32,7 @@ func New(
}
}
func (s *Service) AllocateCardsPreview(ctx context.Context, enterpriseID uint, req *dto.AllocateCardsPreviewReq) (*dto.AllocateCardsPreviewResp, error) {
func (s *Service) allocateCardsPreview(ctx context.Context, enterpriseID uint, req *dto.AllocateCardsPreviewReq) (*dto.AllocateCardsPreviewResp, error) {
currentUserID := middleware.GetUserIDFromContext(ctx)
if currentUserID == 0 {
return nil, errors.New(errors.CodeUnauthorized, "未授权访问")
@@ -172,7 +172,6 @@ func (s *Service) AllocateCardsPreview(ctx context.Context, enterpriseID uint, r
func (s *Service) AllocateCards(ctx context.Context, enterpriseID uint, req *dto.AllocateCardsReq) (*dto.AllocateCardsResp, error) {
currentUserID := middleware.GetUserIDFromContext(ctx)
currentShopID := middleware.GetShopIDFromContext(ctx)
if currentUserID == 0 {
return nil, errors.New(errors.CodeUnauthorized, "未授权访问")
}
@@ -182,7 +181,7 @@ func (s *Service) AllocateCards(ctx context.Context, enterpriseID uint, req *dto
return nil, errors.New(errors.CodeEnterpriseNotFound, "企业不存在")
}
preview, err := s.AllocateCardsPreview(ctx, enterpriseID, &dto.AllocateCardsPreviewReq{ICCIDs: req.ICCIDs})
preview, err := s.allocateCardsPreview(ctx, enterpriseID, &dto.AllocateCardsPreviewReq{ICCIDs: req.ICCIDs})
if err != nil {
return nil, err
}
@@ -224,18 +223,18 @@ func (s *Service) AllocateCards(ctx context.Context, enterpriseID uint, req *dto
}
now := time.Now()
userType := middleware.GetUserTypeFromContext(ctx)
auths := make([]*model.EnterpriseCardAuthorization, 0)
for _, cardID := range cardIDsToAllocate {
if existingAuths[cardID] {
continue
}
auths = append(auths, &model.EnterpriseCardAuthorization{
EnterpriseID: enterpriseID,
IotCardID: cardID,
ShopID: currentShopID,
AuthorizedBy: currentUserID,
AuthorizedAt: &now,
Status: 1,
EnterpriseID: enterpriseID,
CardID: cardID,
AuthorizedBy: currentUserID,
AuthorizedAt: now,
AuthorizerType: userType,
})
}
@@ -409,7 +408,7 @@ func (s *Service) updateCardNetworkStatus(ctx context.Context, enterpriseID, car
}
auth, err := s.enterpriseCardAuthStore.GetByEnterpriseAndCard(ctx, enterpriseID, cardID)
if err != nil || auth.Status != 1 {
if err != nil || auth.RevokedAt != nil {
return errors.New(errors.CodeForbidden, "无权限操作此卡")
}