package biz import ( "context" "strings" pb "moredoc/api/v1" "moredoc/middleware/auth" "moredoc/model" "moredoc/util" "go.uber.org/zap" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/emptypb" "gorm.io/gorm" ) type PunishmentAPIService struct { pb.UnimplementedPunishmentAPIServer dbModel *model.DBModel logger *zap.Logger } func NewPunishmentAPIService(dbModel *model.DBModel, logger *zap.Logger) (service *PunishmentAPIService) { return &PunishmentAPIService{dbModel: dbModel, logger: logger.Named("PunishmentAPIService")} } func (s *PunishmentAPIService) checkPermission(ctx context.Context) (userClaims *auth.UserClaims, err error) { return checkGRPCPermission(s.dbModel, ctx) } func (s *PunishmentAPIService) CreatePunishment(ctx context.Context, req *pb.CreatePunishmentRequest) (*emptypb.Empty, error) { userClaims, err := s.checkPermission(ctx) if err != nil { return nil, err } if len(req.UserId) == 0 { return nil, status.Errorf(codes.InvalidArgument, "请选择用户") } if len(req.Type) == 0 { return nil, status.Errorf(codes.InvalidArgument, "请选择处罚类型") } for _, userId := range req.UserId { if userId == 1 { continue } for _, typ := range req.Type { punishment := &model.Punishment{ UserId: userId, Type: int(typ), Enable: req.Enable, Reason: req.Reason, Remark: req.Remark, EndTime: req.EndTime, } s.logger.Debug("CreatePunishment", zap.Any("punishment", punishment), zap.Any("req", req)) punishment.Operators = s.dbModel.MakePunishmentOperators(userClaims.UserId, typ) err = s.dbModel.CreatePunishment(punishment) if err != nil { s.logger.Error("CreatePunishment", zap.Error(err)) return nil, status.Errorf(codes.Internal, err.Error()) } } } return &emptypb.Empty{}, nil } func (s *PunishmentAPIService) UpdatePunishment(ctx context.Context, req *pb.Punishment) (*emptypb.Empty, error) { userClaims, err := s.checkPermission(ctx) if err != nil { return nil, err } punishment := &model.Punishment{} err = util.CopyStruct(req, punishment) if err != nil { s.logger.Error("CopyStruct", zap.Error(err)) return nil, status.Errorf(codes.InvalidArgument, err.Error()) } s.logger.Debug("UpdatePunishment", zap.Any("punishment", punishment), zap.Any("req", req)) if existPunishment, _ := s.dbModel.GetPunishment(punishment.Id, "id", "operators"); existPunishment.Id > 0 { punishment.Operators = s.dbModel.MakePunishmentOperators(userClaims.UserId, req.Type, existPunishment.Operators) } err = s.dbModel.UpdatePunishment(punishment) if err != nil { s.logger.Error("UpdatePunishment", zap.Error(err)) return nil, status.Errorf(codes.Internal, err.Error()) } return &emptypb.Empty{}, nil } func (s *PunishmentAPIService) GetPunishment(ctx context.Context, req *pb.GetPunishmentRequest) (*pb.Punishment, error) { _, err := s.checkPermission(ctx) if err != nil { return nil, err } punishment, err := s.dbModel.GetPunishment(req.Id) if err != nil { s.logger.Error("GetPunishment", zap.Error(err)) return nil, status.Errorf(codes.Internal, err.Error()) } res := &pb.Punishment{} err = util.CopyStruct(punishment, res) if err != nil { s.logger.Error("CopyStruct", zap.Error(err)) return nil, status.Errorf(codes.Internal, err.Error()) } if punishment.UserId > 0 { user, _ := s.dbModel.GetUser(punishment.UserId, "id", "username") if user.Id > 0 { res.Username = user.Username } } return res, nil } func (s *PunishmentAPIService) ListPunishment(ctx context.Context, req *pb.ListPunishmentRequest) (*pb.ListPunishmentReply, error) { _, err := s.checkPermission(ctx) if err != nil { return nil, err } opt := &model.OptionGetPunishmentList{ Page: int(req.Page), Size: int(req.Size_), WithCount: true, SelectFields: req.Field, QueryLike: make(map[string][]interface{}), QueryIn: make(map[string][]interface{}), } if len(req.UserId) > 0 { opt.QueryIn["user_id"] = util.Slice2Interface(req.UserId) } if len(req.Type) > 0 { opt.QueryIn["type"] = util.Slice2Interface(req.Type) } if len(req.Enable) > 0 { opt.QueryIn["enable"] = util.Slice2Interface(req.Enable) } if req.Order != "" { opt.Sort = strings.Split(req.Order, ",") } if req.Wd != "" { wd := strings.TrimSpace(req.Wd) opt.QueryLike["reason"] = []interface{}{wd} opt.QueryLike["remark"] = []interface{}{wd} } data, total, err := s.dbModel.GetPunishmentList(opt) if err != nil && err != gorm.ErrRecordNotFound { s.logger.Error("GetPunishmentList", zap.Error(err)) return nil, status.Errorf(codes.Internal, err.Error()) } res := &pb.ListPunishmentReply{ Total: total, } err = util.CopyStruct(data, &res.Punishment) if err != nil { s.logger.Error("CopyStruct", zap.Error(err)) return nil, status.Errorf(codes.Internal, err.Error()) } if len(res.Punishment) > 0 { var ( userIds []int64 userIdMapIndexes = make(map[int64][]int) ) for i, v := range res.Punishment { userIds = append(userIds, v.UserId) userIdMapIndexes[v.UserId] = append(userIdMapIndexes[v.UserId], i) } users, _, _ := s.dbModel.GetUserList(&model.OptionGetUserList{ Ids: userIds, WithCount: false, SelectFields: []string{ "id", "username", }, }) for _, v := range users { if indexes, ok := userIdMapIndexes[v.Id]; ok { for _, index := range indexes { res.Punishment[index].Username = v.Username } } } } return res, nil } // 取消惩罚 func (s *PunishmentAPIService) CancelPunishment(ctx context.Context, req *pb.CancelPunishmentRequest) (*emptypb.Empty, error) { userCliams, err := s.checkPermission(ctx) if err != nil { return nil, err } s.logger.Debug("CancelPunishment", zap.Any("req", req)) data, _, err := s.dbModel.GetPunishmentList(&model.OptionGetPunishmentList{ Ids: req.Id, }) if err != nil && err != gorm.ErrRecordNotFound { s.logger.Error("GetPunishmentList", zap.Error(err)) return nil, status.Errorf(codes.Internal, err.Error()) } for _, item := range data { item.Enable = false item.Operators = s.dbModel.MakePunishmentOperators(userCliams.UserId, 0, item.Operators) err = s.dbModel.UpdatePunishment(&item, "enable", "operators") if err != nil { s.logger.Error("UpdatePunishment", zap.Error(err)) return nil, status.Errorf(codes.Internal, err.Error()) } } return &emptypb.Empty{}, nil }