结构调整

dev
truthhun 2 years ago
parent d8681040ff
commit 40e15599f2

@ -0,0 +1,78 @@
syntax = "proto3";
import "google/protobuf/timestamp.proto";
import "gogoproto/gogo.proto";
// import "validate/validate.proto";
import "google/api/annotations.proto";
import "google/protobuf/empty.proto";
package api.v1;
option go_package = "moredoc/api/v1;v1";
option java_multiple_files = true;
option java_package = "api.v1";
message Group {
int64 id = 1;
string title = 2;
string color = 3;
string icon = 4;
int32 is_default = 5;
int32 is_display = 6;
string description = 7;
int32 user_count = 8;
int32 sort = 9;
google.protobuf.Timestamp created_at = 10 [ (gogoproto.stdtime) = true ];
google.protobuf.Timestamp updated_at = 11 [ (gogoproto.stdtime) = true ];
}
message DeleteGroupRequest { repeated int64 id = 1; }
// ID
message GetGroupRequest {
int64 id = 1;
string title = 2;
}
//
message ListGroupRequest { repeated string field = 1; }
message ListGroupReply { repeated Group group = 1; }
service GroupAPI {
//
rpc CreateGroup(Group) returns (Group) {
option (google.api.http) = {
post : '/api/v1/group',
body : '*',
};
}
//
rpc UpdateGroup(Group) returns (Group) {
option (google.api.http) = {
put : '/api/v1/group',
body : '*',
};
}
//
rpc DeleteGroup(DeleteGroupRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {
delete : '/api/v1/group',
};
}
//
rpc GetGroup(GetGroupRequest) returns (Group) {
option (google.api.http) = {
get : '/api/v1/group',
};
}
rpc ListGroup(ListGroupRequest) returns (ListGroupReply) {
option (google.api.http) = {
get : '/api/v1/group/list',
};
}
}

@ -0,0 +1,68 @@
package biz
import (
"context"
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 GroupAPIService struct {
pb.UnimplementedGroupAPIServer
dbModel *model.DBModel
logger *zap.Logger
}
func NewGroupAPIService(dbModel *model.DBModel, logger *zap.Logger) (service *GroupAPIService) {
return &GroupAPIService{dbModel: dbModel, logger: logger.Named("GroupAPIService")}
}
// CreateGroup 创建用户组
// 0. 检查用户权限
// 1. 检查用户组是否存在
// 2. 创建用户组
func (s *GroupAPIService) CreateGroup(ctx context.Context, req *pb.Group) (*pb.Group, error) {
s.logger.Debug("CreateGroup", zap.Any("req", req))
userClaims, ok := ctx.Value(auth.CtxKeyUserClaims).(*auth.UserClaims)
if !ok {
return nil, status.Errorf(codes.Unauthenticated, ErrorMessageInvalidToken)
}
fullMethod, _ := ctx.Value(auth.CtxKeyFullMethod).(string)
if yes := s.dbModel.CheckPermissionByUserId(userClaims.UserId, fullMethod); !yes {
return nil, status.Errorf(codes.PermissionDenied, ErrorMessagePermissionDenied)
}
return &pb.Group{}, nil
}
func (s *GroupAPIService) UpdateGroup(ctx context.Context, req *pb.Group) (*pb.Group, error) {
return &pb.Group{}, nil
}
func (s *GroupAPIService) DeleteGroup(ctx context.Context, req *pb.DeleteGroupRequest) (*emptypb.Empty, error) {
return &emptypb.Empty{}, nil
}
func (s *GroupAPIService) GetGroup(ctx context.Context, req *pb.GetGroupRequest) (*pb.Group, error) {
return &pb.Group{}, nil
}
// ListGroup 列出用户组。所有用户都可以查询
func (s *GroupAPIService) ListGroup(ctx context.Context, req *pb.ListGroupRequest) (*pb.ListGroupReply, error) {
s.logger.Debug("ListGroup", zap.Any("req", req))
groups, _, err := s.dbModel.GetGroupList(model.OptionGetGroupList{Page: 1, Size: 100000, SelectFields: req.Field, WithCount: false})
if err != nil && err != gorm.ErrRecordNotFound {
return nil, status.Errorf(codes.Internal, err.Error())
}
var pbGroups []*pb.Group
util.CopyStruct(&groups, &pbGroups)
return &pb.ListGroupReply{Group: pbGroups}, nil
}

@ -185,7 +185,7 @@ func (s *UserAPIService) UpdateUser(ctx context.Context, req *pb.User) (*emptypb
// 管理员更改用户资料,验证是否有权限
fullMethod, _ := ctx.Value(auth.CtxKeyFullMethod).(string)
yes := s.dbModel.CheckPermissionByUserId(userClaims.UserId, "", fullMethod)
yes := s.dbModel.CheckPermissionByUserId(userClaims.UserId, fullMethod)
if !yes {
return nil, status.Errorf(codes.PermissionDenied, ErrorMessagePermissionDenied)
}
@ -235,7 +235,7 @@ func (s *UserAPIService) UpdateUserPassword(ctx context.Context, req *pb.UpdateU
// 管理员更改用户密码
fullMethod, _ := ctx.Value(auth.CtxKeyFullMethod).(string)
yes := s.dbModel.CheckPermissionByUserId(userClaims.UserId, "", fullMethod)
yes := s.dbModel.CheckPermissionByUserId(userClaims.UserId, fullMethod)
if !yes {
return nil, status.Errorf(codes.PermissionDenied, ErrorMessagePermissionDenied)
}
@ -296,7 +296,7 @@ func (s *UserAPIService) ListUser(ctx context.Context, req *pb.ListUserRequest)
opt.Sort = strings.Split(req.Sort, ",")
}
if s.dbModel.CheckPermissionByUserId(userId, "", fullMethod) {
if s.dbModel.CheckPermissionByUserId(userId, fullMethod) {
limitFileds = []string{} // 管理员,可以查询全部信息
if req.Wd != "" {
opt.QueryLike = map[string][]interface{}{

@ -121,10 +121,11 @@ func (m *DBModel) DeletePermission(ids []interface{}) (err error) {
}
// CheckPermissionByUserId 根据用户ID检查用户是否有权限
func (m *DBModel) CheckPermissionByUserId(userId int64, method, path string) (yes bool) {
func (m *DBModel) CheckPermissionByUserId(userId int64, path string, httpMethod ...string) (yes bool) {
var (
userGroups []UserGroup
groupId []int64
method string
)
// NOTE: ID为1的用户拥有所有权限可以理解为类似linux的root用户
@ -133,6 +134,10 @@ func (m *DBModel) CheckPermissionByUserId(userId int64, method, path string) (ye
// return true
// }
if len(httpMethod) > 0 {
method = httpMethod[0]
}
if userId > 0 {
m.db.Where("user_id = ?", userId).Find(&userGroups)
for _, ug := range userGroups {

@ -1,17 +1,15 @@
package service
import (
"context"
"fmt"
"net/http"
"strings"
v1 "moredoc/api/v1"
"moredoc/biz"
"moredoc/conf"
"moredoc/middleware/auth"
"moredoc/middleware/jsonpb"
"moredoc/model"
"moredoc/service/serve"
"github.com/gin-contrib/cors"
"github.com/gin-contrib/gzip"
@ -59,29 +57,9 @@ func Run(cfg *conf.Config, logger *zap.Logger) {
return
}
endpoint := fmt.Sprintf("localhost:%v", cfg.Port)
// =========================================================================
// 【start】 在这里注册您的API服务模块
// =========================================================================
// 用户API接口服务
userAPIService := biz.NewUserAPIService(dbModel, logger, auth)
v1.RegisterUserAPIServer(grpcServer, userAPIService)
err = v1.RegisterUserAPIHandlerFromEndpoint(context.Background(), gwmux, endpoint, dialOpts)
if err != nil {
logger.Fatal("RegisterUserAPIHandlerFromEndpoint", zap.Error(err))
return
}
// =========================================================================
// 【end】 在这里注册您的API服务模块
// =========================================================================
if cfg.Level != "debug" {
gin.SetMode(gin.ReleaseMode)
}
app := gin.New()
app.Use(
gzip.Gzip(gzip.DefaultCompression), // gzip
@ -89,8 +67,14 @@ func Run(cfg *conf.Config, logger *zap.Logger) {
cors.Default(), // allows all origins
)
// Web router
mountWebRouter(app)
endpoint := fmt.Sprintf("localhost:%v", cfg.Port)
err = serve.RegisterGRPCService(dbModel, logger, endpoint, auth, grpcServer, gwmux, dialOpts...)
if err != nil {
logger.Fatal("registerAPIService", zap.Error(err))
return
}
serve.RegisterGinRouter(app)
// 根目录访问静态文件,要放在 grpc 服务的前面
// 可以在 dist 目录下创建一个 index.html 文件并添加内容,然后访问 http://ip:port
@ -128,10 +112,3 @@ func wrapH(h http.Handler) gin.HandlerFunc {
h.ServeHTTP(c.Writer, c.Request)
}
}
// mountWebRouter mount web router
func mountWebRouter(app *gin.Engine) {
app.GET("/helloworld", func(ctx *gin.Context) {
ctx.JSON(http.StatusOK, "hello world")
})
}

@ -0,0 +1,35 @@
package serve
import (
"context"
v1 "moredoc/api/v1"
"moredoc/biz"
"moredoc/middleware/auth"
"moredoc/model"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"go.uber.org/zap"
"google.golang.org/grpc"
)
// RegisterGRPCService 注册grpc服务
func RegisterGRPCService(dbModel *model.DBModel, logger *zap.Logger, endpoint string, authMiddleWare *auth.Auth, grpcServer *grpc.Server, gwmux *runtime.ServeMux, dialOpts ...grpc.DialOption) (err error) {
// 用户API接口服务
userAPIService := biz.NewUserAPIService(dbModel, logger, authMiddleWare)
v1.RegisterUserAPIServer(grpcServer, userAPIService)
err = v1.RegisterUserAPIHandlerFromEndpoint(context.Background(), gwmux, endpoint, dialOpts)
if err != nil {
logger.Error("RegisterUserAPIHandlerFromEndpoint", zap.Error(err))
return
}
// 分组API接口服务
groupAPIService := biz.NewGroupAPIService(dbModel, logger)
v1.RegisterGroupAPIServer(grpcServer, groupAPIService)
err = v1.RegisterGroupAPIHandlerFromEndpoint(context.Background(), gwmux, endpoint, dialOpts)
if err != nil {
logger.Error("RegisterGroupAPIHandlerFromEndpoint", zap.Error(err))
return
}
return
}

@ -0,0 +1,15 @@
package serve
import (
"net/http"
"github.com/gin-gonic/gin"
)
// RegisterGinRouter 注册gin路由
func RegisterGinRouter(app *gin.Engine) (err error) {
app.GET("/helloworld", func(ctx *gin.Context) {
ctx.JSON(http.StatusOK, "hello world")
})
return
}

@ -0,0 +1,43 @@
import service from '~/utils/request'
export const createGroup = (data) => {
return service({
url: '/api/v1/group',
method: 'post',
data,
})
}
export const updateGroup = (data) => {
return service({
url: '/api/v1/group',
method: 'put',
data,
})
}
export const deleteGroup = (params) => {
return service({
url: '/api/v1/group',
method: 'delete',
params,
})
}
export const getGroup = (params) => {
return service({
url: '/api/v1/group',
method: 'get',
params,
})
}
export const listGroup = (params) => {
return service({
url: '/api/v1/group/list',
method: 'get',
params,
})
}
Loading…
Cancel
Save