mirror of
https://github.com/openimsdk/open-im-server.git
synced 2025-04-26 11:36:44 +08:00
group api
This commit is contained in:
parent
586a113994
commit
4cf29ad565
File diff suppressed because it is too large
Load Diff
@ -1,36 +0,0 @@
|
|||||||
package group
|
|
||||||
|
|
||||||
import (
|
|
||||||
"OpenIM/internal/a2r"
|
|
||||||
"OpenIM/pkg/common/config"
|
|
||||||
"OpenIM/pkg/proto/group"
|
|
||||||
"context"
|
|
||||||
"github.com/OpenIMSDK/openKeeper"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ context.Context = nil // 解决goland编辑器bug
|
|
||||||
|
|
||||||
func NewGroup(zk *openKeeper.ZkClient) *Group {
|
|
||||||
return &Group{zk: zk}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Group struct {
|
|
||||||
zk *openKeeper.ZkClient
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Group) getGroupClient() (group.GroupClient, error) {
|
|
||||||
conn, err := g.zk.GetConn(config.Config.RpcRegisterName.OpenImGroupName)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return group.NewGroupClient(conn), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Group) KickGroupMember(c *gin.Context) {
|
|
||||||
a2r.Call(group.GroupClient.KickGroupMember, g.getGroupClient, c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Group) GetGroupMembersInfo(c *gin.Context) {
|
|
||||||
a2r.Call(group.GroupClient.GetGroupMembersInfo, g.getGroupClient, c)
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
package group
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func TestName(t *testing.T) {
|
|
||||||
var g Group
|
|
||||||
|
|
||||||
g.KickGroupMember(nil)
|
|
||||||
g.GetGroupMembersInfo(nil)
|
|
||||||
|
|
||||||
}
|
|
@ -1,89 +0,0 @@
|
|||||||
package group
|
|
||||||
|
|
||||||
//import (
|
|
||||||
// jsonData "OpenIM/internal/utils"
|
|
||||||
// api "OpenIM/pkg/apistruct"
|
|
||||||
// "OpenIM/pkg/common/config"
|
|
||||||
// "OpenIM/pkg/common/log"
|
|
||||||
// "OpenIM/pkg/common/token_verify"
|
|
||||||
// "OpenIM/pkg/getcdv3"
|
|
||||||
// rpc "OpenIM/pkg/proto/group"
|
|
||||||
// "OpenIM/pkg/utils"
|
|
||||||
// "context"
|
|
||||||
// "github.com/gin-gonic/gin"
|
|
||||||
// "net/http"
|
|
||||||
// "strings"
|
|
||||||
//)
|
|
||||||
//
|
|
||||||
//func GetJoinedSuperGroupList(c *gin.Context) {
|
|
||||||
// req := api.GetJoinedSuperGroupListReq{}
|
|
||||||
// if err := c.BindJSON(&req); err != nil {
|
|
||||||
// log.NewError("0", "BindJSON failed ", err.Error())
|
|
||||||
// c.JSON(http.StatusBadRequest, gin.H{"errCode": 400, "errMsg": err.Error()})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req)
|
|
||||||
// ok, opUserID, errInfo := token_verify.GetUserIDFromToken(c.Request.Header.Get("token"), req.OperationID)
|
|
||||||
// if !ok {
|
|
||||||
// errMsg := req.OperationID + " " + "GetUserIDFromToken failed " + errInfo + " token:" + c.Request.Header.Get("token")
|
|
||||||
// log.NewError(req.OperationID, errMsg)
|
|
||||||
// c.JSON(http.StatusInternalServerError, gin.H{"errCode": 500, "errMsg": errMsg})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// reqPb := rpc.GetJoinedSuperGroupListReq{OperationID: req.OperationID, OpUserID: opUserID, UserID: req.FromUserID}
|
|
||||||
// etcdConn := rpc.GetDefaultConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImGroupName, req.OperationID)
|
|
||||||
// if etcdConn == nil {
|
|
||||||
// errMsg := req.OperationID + "getcdv3.GetDefaultConn == nil"
|
|
||||||
// log.NewError(req.OperationID, errMsg)
|
|
||||||
// c.JSON(http.StatusInternalServerError, gin.H{"errCode": 500, "errMsg": errMsg})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// client := rpc.NewGroupClient(etcdConn)
|
|
||||||
// rpcResp, err := client.GetJoinedSuperGroupList(context.Background(), &reqPb)
|
|
||||||
// if err != nil {
|
|
||||||
// log.NewError(req.OperationID, "InviteUserToGroup failed ", err.Error(), reqPb.String())
|
|
||||||
// c.JSON(http.StatusInternalServerError, gin.H{"errCode": 500, "errMsg": err.Error()})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// GroupListResp := api.GetJoinedSuperGroupListResp{GetJoinedGroupListResp: api.GetJoinedGroupListResp{CommResp: api.CommResp{ErrCode: rpcResp.CommonResp.ErrCode, ErrMsg: rpcResp.CommonResp.ErrMsg}, GroupInfoList: rpcResp.GroupList}}
|
|
||||||
// GroupListResp.Map = jsonData.JsonDataList(GroupListResp.GroupInfoList)
|
|
||||||
// log.NewInfo(req.OperationID, "GetJoinedSuperGroupList api return ", GroupListResp)
|
|
||||||
// c.JSON(http.StatusOK, GroupListResp)
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//func GetSuperGroupsInfo(c *gin.Context) {
|
|
||||||
// req := api.GetSuperGroupsInfoReq{}
|
|
||||||
// if err := c.BindJSON(&req); err != nil {
|
|
||||||
// log.NewError("0", "BindJSON failed ", err.Error())
|
|
||||||
// c.JSON(http.StatusBadRequest, gin.H{"errCode": 400, "errMsg": err.Error()})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req)
|
|
||||||
// ok, opUserID, errInfo := token_verify.GetUserIDFromToken(c.Request.Header.Get("token"), req.OperationID)
|
|
||||||
// if !ok {
|
|
||||||
// errMsg := req.OperationID + " " + "GetUserIDFromToken failed " + errInfo + " token:" + c.Request.Header.Get("token")
|
|
||||||
// log.NewError(req.OperationID, errMsg)
|
|
||||||
// c.JSON(http.StatusInternalServerError, gin.H{"errCode": 500, "errMsg": errMsg})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// reqPb := rpc.GetSuperGroupsInfoReq{OperationID: req.OperationID, OpUserID: opUserID, GroupIDList: req.GroupIDList}
|
|
||||||
// etcdConn := rpc.GetDefaultConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImGroupName, req.OperationID)
|
|
||||||
// if etcdConn == nil {
|
|
||||||
// errMsg := req.OperationID + "getcdv3.GetDefaultConn == nil"
|
|
||||||
// log.NewError(req.OperationID, errMsg)
|
|
||||||
// c.JSON(http.StatusInternalServerError, gin.H{"errCode": 500, "errMsg": errMsg})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// client := rpc.NewGroupClient(etcdConn)
|
|
||||||
// rpcResp, err := client.GetSuperGroupsInfo(context.Background(), &reqPb)
|
|
||||||
// if err != nil {
|
|
||||||
// log.NewError(req.OperationID, "InviteUserToGroup failed ", err.Error(), reqPb.String())
|
|
||||||
// c.JSON(http.StatusInternalServerError, gin.H{"errCode": 500, "errMsg": err.Error()})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// resp := api.GetSuperGroupsInfoResp{GetGroupInfoResp: api.GetGroupInfoResp{CommResp: api.CommResp{ErrCode: rpcResp.CommonResp.ErrCode, ErrMsg: rpcResp.CommonResp.ErrMsg}, GroupInfoList: rpcResp.GroupInfoList}}
|
|
||||||
// resp.Map = jsonData.JsonDataList(resp.GroupInfoList)
|
|
||||||
// log.NewInfo(req.OperationID, "GetGroupsInfo api return ", resp)
|
|
||||||
// c.JSON(http.StatusOK, resp)
|
|
||||||
//}
|
|
@ -81,8 +81,8 @@ func NewGinRouter() *gin.Engine {
|
|||||||
c.Set("opUserID", userID)
|
c.Set("opUserID", userID)
|
||||||
c.Next()
|
c.Next()
|
||||||
})
|
})
|
||||||
|
g := group.NewGroup(nil)
|
||||||
{
|
{
|
||||||
g := group.NewGroup(nil)
|
|
||||||
groupRouterGroup.POST("/create_group", g.NewCreateGroup) //1
|
groupRouterGroup.POST("/create_group", g.NewCreateGroup) //1
|
||||||
groupRouterGroup.POST("/set_group_info", g.NewSetGroupInfo) //1
|
groupRouterGroup.POST("/set_group_info", g.NewSetGroupInfo) //1
|
||||||
groupRouterGroup.POST("/join_group", g.JoinGroup) //1
|
groupRouterGroup.POST("/join_group", g.JoinGroup) //1
|
||||||
@ -93,25 +93,23 @@ func NewGinRouter() *gin.Engine {
|
|||||||
groupRouterGroup.POST("/get_user_req_group_applicationList", g.GetUserReqGroupApplicationList)
|
groupRouterGroup.POST("/get_user_req_group_applicationList", g.GetUserReqGroupApplicationList)
|
||||||
groupRouterGroup.POST("/get_groups_info", g.GetGroupsInfo) //1
|
groupRouterGroup.POST("/get_groups_info", g.GetGroupsInfo) //1
|
||||||
groupRouterGroup.POST("/kick_group", g.KickGroupMember) //1
|
groupRouterGroup.POST("/kick_group", g.KickGroupMember) //1
|
||||||
// groupRouterGroup.POST("/get_group_member_list", g.FindGroupMemberAll) //no use
|
//groupRouterGroup.POST("/get_group_all_member_list", g.GetGroupAllMemberList) //1
|
||||||
groupRouterGroup.POST("/get_group_all_member_list", g.GetGroupAllMemberList) //1
|
groupRouterGroup.POST("/get_group_members_info", g.GetGroupMembersInfo) //1
|
||||||
groupRouterGroup.POST("/get_group_members_info", g.GetGroupMembersInfo) //1
|
groupRouterGroup.POST("/invite_user_to_group", g.InviteUserToGroup) //1
|
||||||
groupRouterGroup.POST("/invite_user_to_group", g.InviteUserToGroup) //1
|
|
||||||
groupRouterGroup.POST("/get_joined_group_list", g.GetJoinedGroupList)
|
groupRouterGroup.POST("/get_joined_group_list", g.GetJoinedGroupList)
|
||||||
groupRouterGroup.POST("/dismiss_group", g.DismissGroup) //
|
groupRouterGroup.POST("/dismiss_group", g.DismissGroup) //
|
||||||
groupRouterGroup.POST("/mute_group_member", g.MuteGroupMember)
|
groupRouterGroup.POST("/mute_group_member", g.MuteGroupMember)
|
||||||
groupRouterGroup.POST("/cancel_mute_group_member", g.CancelMuteGroupMember) //MuteGroup
|
groupRouterGroup.POST("/cancel_mute_group_member", g.CancelMuteGroupMember) //MuteGroup
|
||||||
groupRouterGroup.POST("/mute_group", g.MuteGroup)
|
groupRouterGroup.POST("/mute_group", g.MuteGroup)
|
||||||
groupRouterGroup.POST("/cancel_mute_group", g.CancelMuteGroup)
|
groupRouterGroup.POST("/cancel_mute_group", g.CancelMuteGroup)
|
||||||
groupRouterGroup.POST("/set_group_member_nickname", g.SetGroupMemberNickname)
|
//groupRouterGroup.POST("/set_group_member_nickname", g.SetGroupMemberNickname)
|
||||||
groupRouterGroup.POST("/set_group_member_info", g.SetGroupMemberInfo)
|
groupRouterGroup.POST("/set_group_member_info", g.SetGroupMemberInfo)
|
||||||
groupRouterGroup.POST("/get_group_abstract_info", g.GetGroupAbstractInfo)
|
groupRouterGroup.POST("/get_group_abstract_info", g.GetGroupAbstractInfo)
|
||||||
//groupRouterGroup.POST("/get_group_all_member_list_by_split", g.GetGroupAllMemberListBySplit)
|
|
||||||
}
|
}
|
||||||
superGroupRouterGroup := r.Group("/super_group")
|
superGroupRouterGroup := r.Group("/super_group")
|
||||||
{
|
{
|
||||||
superGroupRouterGroup.POST("/get_joined_group_list", group.GetJoinedSuperGroupList)
|
superGroupRouterGroup.POST("/get_joined_group_list", g.GetJoinedSuperGroupList)
|
||||||
superGroupRouterGroup.POST("/get_groups_info", group.GetSuperGroupsInfo)
|
superGroupRouterGroup.POST("/get_groups_info", g.GetSuperGroupsInfo)
|
||||||
}
|
}
|
||||||
////certificate
|
////certificate
|
||||||
authRouterGroup := r.Group("/auth")
|
authRouterGroup := r.Group("/auth")
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
package api2rpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"OpenIM/pkg/common/constant"
|
|
||||||
"OpenIM/pkg/common/tracelog"
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"google.golang.org/grpc/status"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
//func ApiToRpc(c *gin.Context, apiReq, apiResp interface{}, rpcName string, rpcClientFunc interface{}, rpcFuncName string) {
|
|
||||||
// if rpcName == "" {
|
|
||||||
// rpcName = utils2.GetFuncName(1)
|
|
||||||
// }
|
|
||||||
// logFuncName := fmt.Sprintf("[ApiToRpc: %s]%s", utils2.GetFuncName(1), rpcFuncName)
|
|
||||||
// ctx := tracelog.NewCtx(c, rpcFuncName)
|
|
||||||
// defer log.ShowLog(ctx)
|
|
||||||
// if err := c.BindJSON(apiReq); err != nil {
|
|
||||||
// WriteErrorResponse(ctx, "BindJSON", err)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// tracelog.SetCtxInfo(ctx, logFuncName, nil, "apiReq", apiReq)
|
|
||||||
// etcdConn, err := rpcFn.GetConn(ctx, rpcName)
|
|
||||||
// if err != nil {
|
|
||||||
// WriteErrorResponse(ctx, "GetConn", err)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// rpcClient := reflect.ValueOf(rpcClientFunc).Call([]reflect.Value{
|
|
||||||
// reflect.ValueOf(etcdConn),
|
|
||||||
// })[0].MethodByName(rpcFuncName) // rpcClient func
|
|
||||||
// rpcReqPtr := reflect.New(rpcClient.Type().In(1).Elem()) // *req
|
|
||||||
// CopyAny(apiReq, rpcReqPtr.Interface())
|
|
||||||
// tracelog.SetCtxInfo(ctx, logFuncName, nil, "opUserID", c.GetString("opUserID"), "callRpcReq", rpcString(rpcReqPtr.Elem().Interface()))
|
|
||||||
// respArr := rpcClient.Call([]reflect.Value{
|
|
||||||
// reflect.ValueOf(context.Context(c)), // context.Context (ctx operationID. opUserID)
|
|
||||||
// rpcReqPtr, // rpcClient apiReq
|
|
||||||
// }) // respArr => (apiResp, error)
|
|
||||||
// if !respArr[1].IsNil() { // rpcClient err != nil
|
|
||||||
// err := respArr[1].Interface().(error)
|
|
||||||
// WriteErrorResponse(ctx, rpcFuncName, err, "callRpcResp", "error")
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// rpcResp := respArr[0].Elem()
|
|
||||||
// tracelog.SetCtxInfo(ctx, rpcFuncName, nil, "callRpcResp", rpcString(rpcResp.Interface()))
|
|
||||||
// if apiResp != nil {
|
|
||||||
// CopyAny(rpcResp.Interface(), apiResp)
|
|
||||||
// }
|
|
||||||
// SetSuccess(ctx, rpcFuncName, apiResp)
|
|
||||||
//}
|
|
||||||
|
|
||||||
func rpcString(v interface{}) string {
|
|
||||||
if s, ok := v.(interface{ String() string }); ok {
|
|
||||||
return s.String()
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%+v", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
type baseResp struct {
|
|
||||||
ErrCode int32 `json:"errCode"`
|
|
||||||
ErrMsg string `json:"errMsg"`
|
|
||||||
ErrDtl string `json:"errDtl"`
|
|
||||||
Data interface{} `json:"data"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func WriteErrorResponse(ctx context.Context, funcName string, err error, args ...interface{}) {
|
|
||||||
tracelog.SetCtxInfo(ctx, funcName, err, args)
|
|
||||||
e := tracelog.Unwrap(err)
|
|
||||||
switch t := e.(type) {
|
|
||||||
case *constant.ErrInfo:
|
|
||||||
ctx.Value(tracelog.TraceLogKey).(*tracelog.ApiInfo).GinCtx.JSON(http.StatusOK, baseResp{ErrCode: t.ErrCode, ErrMsg: t.ErrMsg, ErrDtl: t.DetailErrMsg})
|
|
||||||
//ctx.Value(TraceLogKey).(*ApiInfo).GinCtx.JSON(http.StatusOK, gin.H{"errCode": t.ErrCode, "errMsg": t.ErrMsg, "errDtl": t.DetailErrMsg})
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
s, ok := status.FromError(e)
|
|
||||||
if !ok {
|
|
||||||
ctx.Value(tracelog.TraceLogKey).(*tracelog.ApiInfo).GinCtx.JSON(http.StatusOK, &baseResp{ErrCode: constant.ErrDefaultOther.ErrCode, ErrMsg: err.Error(), ErrDtl: fmt.Sprintf("%+v", err)})
|
|
||||||
//ctx.Value(TraceLogKey).(*ApiInfo).GinCtx.JSON(http.StatusOK, gin.H{"errCode": constant.ErrDefaultOther.ErrCode, "errMsg": err.Error(), "errDtl": fmt.Sprintf("%+v", err)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var details []string
|
|
||||||
if err != e {
|
|
||||||
details = append(details, fmt.Sprintf("%+v", err))
|
|
||||||
}
|
|
||||||
for _, s := range s.Details() {
|
|
||||||
details = append(details, fmt.Sprintf("%+v", s))
|
|
||||||
}
|
|
||||||
ctx.Value(tracelog.TraceLogKey).(*tracelog.ApiInfo).GinCtx.JSON(http.StatusOK, &baseResp{ErrCode: int32(s.Code()), ErrMsg: s.Message(), ErrDtl: strings.Join(details, "\n")})
|
|
||||||
//ctx.Value(TraceLogKey).(*ApiInfo).GinCtx.JSON(http.StatusOK, gin.H{"errCode": s.Code(), "errMsg": s.Message(), "errDtl": strings.Join(details, "\n")})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetSuccess(ctx context.Context, funcName string, data interface{}) {
|
|
||||||
tracelog.SetCtxInfo(ctx, funcName, nil, "data", data)
|
|
||||||
ctx.Value(tracelog.TraceLogKey).(*tracelog.ApiInfo).GinCtx.JSON(http.StatusOK, gin.H{"errCode": 0, "errMsg": "", "errDtl": "", "data": data})
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
package api2rpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Ignore struct{}
|
|
||||||
|
|
||||||
type ApiBind[A, B any] interface {
|
|
||||||
OperationID() string
|
|
||||||
OpUserID() (string, error)
|
|
||||||
Bind(*A) error
|
|
||||||
Context() context.Context
|
|
||||||
Resp(resp *B, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Api interface {
|
|
||||||
OperationID() string
|
|
||||||
OpUserID() string
|
|
||||||
Context() context.Context
|
|
||||||
Bind(req any) error
|
|
||||||
Resp(resp any, err error)
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
package api2rpc
|
|
@ -1,274 +0,0 @@
|
|||||||
package api2rpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"google.golang.org/protobuf/types/known/wrapperspb"
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
func CopyAny(from, to interface{}) {
|
|
||||||
copyAny(reflect.ValueOf(from), reflect.Indirect(reflect.ValueOf(to)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func copyAny(from, to reflect.Value) {
|
|
||||||
if !to.CanSet() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if isBaseNil(from) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if isBaseNil(to) {
|
|
||||||
to.Set(getBaseZeroValue(to.Type()))
|
|
||||||
}
|
|
||||||
btFrom := baseType(from.Type())
|
|
||||||
btTo := baseType(to.Type())
|
|
||||||
if btTo.Kind() == reflect.Interface || typeEq(btFrom, btTo) {
|
|
||||||
setBaseValue(from, to)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, ok := wrapType[btTo.String()]; ok { // string -> wrapperspb.StringValue
|
|
||||||
val := reflect.New(btTo).Elem()
|
|
||||||
copyAny(from, val.FieldByName("Value"))
|
|
||||||
setBaseValue(val, to)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, ok := wrapType[btFrom.String()]; ok { // wrapperspb.StringValue -> string
|
|
||||||
copyAny(baseValue(from).FieldByName("Value"), to)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if btFrom.Kind() == reflect.Struct && btTo.Kind() == reflect.Struct {
|
|
||||||
copyStruct(baseValue(from), baseValue(to))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if btFrom.Kind() == reflect.Slice && btTo.Kind() == reflect.Slice {
|
|
||||||
copySlice(baseValue(from), baseValue(to))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if btFrom.Kind() == reflect.Map && btTo.Kind() == reflect.Map {
|
|
||||||
copyMap(baseValue(from), baseValue(to))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if btTo.Kind() == reflect.String {
|
|
||||||
if isBaseNil(to) {
|
|
||||||
to.Set(getBaseZeroValue(baseType(to.Type())))
|
|
||||||
}
|
|
||||||
setBaseValue(reflect.ValueOf(toString(from)), to)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if toNumber(from, to) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func setBaseValue(from, to reflect.Value) {
|
|
||||||
if isBaseNil(from) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var l int
|
|
||||||
t := to.Type()
|
|
||||||
for t.Kind() == reflect.Ptr {
|
|
||||||
l++
|
|
||||||
t = t.Elem()
|
|
||||||
}
|
|
||||||
v := baseValue(from)
|
|
||||||
for i := 0; i < l; i++ {
|
|
||||||
t := reflect.New(v.Type())
|
|
||||||
t.Elem().Set(v)
|
|
||||||
v = t
|
|
||||||
}
|
|
||||||
to.Set(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getBaseZeroValue(t reflect.Type) reflect.Value {
|
|
||||||
var l int
|
|
||||||
for t.Kind() == reflect.Ptr {
|
|
||||||
l++
|
|
||||||
t = t.Elem()
|
|
||||||
}
|
|
||||||
v := reflect.New(t)
|
|
||||||
if l == 0 {
|
|
||||||
v = v.Elem()
|
|
||||||
} else {
|
|
||||||
for i := 1; i < l; i++ {
|
|
||||||
t := reflect.New(v.Type())
|
|
||||||
t.Elem().Set(v)
|
|
||||||
v = t
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r := reflect.New(v.Type()).Elem()
|
|
||||||
r.Set(v)
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func isBaseNil(v reflect.Value) bool {
|
|
||||||
for {
|
|
||||||
switch v.Kind() {
|
|
||||||
case reflect.Ptr:
|
|
||||||
v = v.Elem()
|
|
||||||
case reflect.Invalid:
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return isNil(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func baseType(t reflect.Type) reflect.Type {
|
|
||||||
for t.Kind() == reflect.Ptr {
|
|
||||||
t = t.Elem()
|
|
||||||
}
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
func typeEq(t1, t2 reflect.Type) bool {
|
|
||||||
return t1.String() == t2.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func isNil(value reflect.Value) bool {
|
|
||||||
switch value.Kind() {
|
|
||||||
case reflect.Chan, reflect.Func, reflect.Map, reflect.Pointer, reflect.UnsafePointer, reflect.Interface, reflect.Slice:
|
|
||||||
return value.IsNil()
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func baseValue(value reflect.Value) reflect.Value {
|
|
||||||
for value.Kind() == reflect.Ptr {
|
|
||||||
value = value.Elem()
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
func copyStruct(from, to reflect.Value) {
|
|
||||||
toType := to.Type()
|
|
||||||
fromType := from.Type()
|
|
||||||
n := to.NumField()
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
toFieldType := toType.Field(i)
|
|
||||||
if _, found := fromType.FieldByName(toFieldType.Name); !found {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
copyAny(from.FieldByName(toFieldType.Name), to.Field(i))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func copySlice(from, to reflect.Value) {
|
|
||||||
size := from.Len()
|
|
||||||
temp := reflect.MakeSlice(to.Type(), 0, size)
|
|
||||||
elemTo := to.Type().Elem()
|
|
||||||
for i := 0; i < size; i++ {
|
|
||||||
var itemTo reflect.Value
|
|
||||||
if item := from.Index(i); isBaseNil(item) {
|
|
||||||
itemTo = reflect.Zero(elemTo)
|
|
||||||
} else {
|
|
||||||
itemTo = getBaseZeroValue(elemTo)
|
|
||||||
copyAny(from.Index(i), itemTo)
|
|
||||||
}
|
|
||||||
temp = reflect.Append(temp, itemTo)
|
|
||||||
}
|
|
||||||
to.Set(temp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func copyMap(from, to reflect.Value) {
|
|
||||||
to.Set(reflect.MakeMap(to.Type()))
|
|
||||||
toTypeKey := to.Type().Key()
|
|
||||||
toTypeVal := to.Type().Elem()
|
|
||||||
for r := from.MapRange(); r.Next(); {
|
|
||||||
key := getBaseZeroValue(toTypeKey)
|
|
||||||
copyAny(r.Key(), key)
|
|
||||||
var val reflect.Value
|
|
||||||
fVal := r.Value()
|
|
||||||
if isBaseNil(fVal) {
|
|
||||||
val = reflect.Zero(toTypeVal)
|
|
||||||
} else {
|
|
||||||
val = getBaseZeroValue(toTypeVal)
|
|
||||||
copyAny(fVal, val)
|
|
||||||
}
|
|
||||||
to.SetMapIndex(key, val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toString(value reflect.Value) string {
|
|
||||||
if value.Kind() == reflect.Slice {
|
|
||||||
switch value.Type().String() {
|
|
||||||
case "[]uint8": // []byte -> []uint8
|
|
||||||
return string(value.Interface().([]uint8))
|
|
||||||
case "[]int32": // []rune -> []int32
|
|
||||||
return string(value.Interface().([]int32))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmt.Sprint(value.Interface())
|
|
||||||
}
|
|
||||||
|
|
||||||
func toNumber(from, to reflect.Value) bool {
|
|
||||||
initTo := func() {
|
|
||||||
if isBaseNil(to) {
|
|
||||||
to.Set(getBaseZeroValue(to.Type()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch baseValue(from).Kind() {
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
switch baseValue(to).Kind() {
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
initTo()
|
|
||||||
baseValue(to).SetInt(baseValue(from).Int())
|
|
||||||
return true
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
initTo()
|
|
||||||
baseValue(to).SetUint(uint64(baseValue(from).Int()))
|
|
||||||
return true
|
|
||||||
case reflect.Float64, reflect.Float32:
|
|
||||||
initTo()
|
|
||||||
baseValue(to).SetFloat(float64(baseValue(from).Int()))
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
switch baseValue(to).Kind() {
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
initTo()
|
|
||||||
baseValue(to).SetInt(int64(baseValue(from).Uint()))
|
|
||||||
return true
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
initTo()
|
|
||||||
baseValue(to).SetInt(int64(baseValue(from).Uint()))
|
|
||||||
return true
|
|
||||||
case reflect.Float64, reflect.Float32:
|
|
||||||
initTo()
|
|
||||||
baseValue(to).SetFloat(float64(baseValue(from).Uint()))
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
case reflect.Float64, reflect.Float32:
|
|
||||||
switch baseValue(to).Kind() {
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
initTo()
|
|
||||||
baseValue(to).SetInt(int64(baseValue(from).Float()))
|
|
||||||
return true
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
initTo()
|
|
||||||
baseValue(to).SetUint(uint64(baseValue(from).Float()))
|
|
||||||
return true
|
|
||||||
case reflect.Float64, reflect.Float32:
|
|
||||||
initTo()
|
|
||||||
baseValue(to).SetFloat(baseValue(from).Float())
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func typeName(v interface{}) string {
|
|
||||||
return reflect.TypeOf(v).String()
|
|
||||||
}
|
|
||||||
|
|
||||||
var wrapType = map[string]struct{}{
|
|
||||||
typeName(wrapperspb.DoubleValue{}): {},
|
|
||||||
typeName(wrapperspb.FloatValue{}): {},
|
|
||||||
typeName(wrapperspb.Int64Value{}): {},
|
|
||||||
typeName(wrapperspb.UInt64Value{}): {},
|
|
||||||
typeName(wrapperspb.Int32Value{}): {},
|
|
||||||
typeName(wrapperspb.UInt32Value{}): {},
|
|
||||||
typeName(wrapperspb.BoolValue{}): {},
|
|
||||||
typeName(wrapperspb.StringValue{}): {},
|
|
||||||
typeName(wrapperspb.BytesValue{}): {},
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
package api2rpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
//func KickGroupMember(c *gin.Context) {
|
|
||||||
// // 默认 全部自动
|
|
||||||
// //var api ApiBind[apistruct.KickGroupMemberReq, apistruct.KickGroupMemberResp] = NewGin[apistruct.KickGroupMemberReq, apistruct.KickGroupMemberResp](c)
|
|
||||||
// var api ApiBind[apistruct.KickGroupMemberReq, apistruct.KickGroupMemberResp] = nil
|
|
||||||
// var client func(conn *grpc.ClientConn) group.GroupClient = nil
|
|
||||||
// var rpcFn func(ctx context.Context, in *group.KickGroupMemberReq, opts ...grpc.CallOption) (*group.KickGroupMemberResp, error) = nil
|
|
||||||
// //NewRpc(api, client, rpcFn).Name("group").Call()
|
|
||||||
// NewRpc(api, client, rpcFn).Name("group").Call()
|
|
||||||
//
|
|
||||||
// // 可以自定义编辑请求和响应
|
|
||||||
// //a := NewRpc(NewGin[apistruct.KickGroupMemberReq, apistruct.KickGroupMemberResp](c), "", group.NewGroupClient, group.GroupClient.KickGroupMember)
|
|
||||||
// //a.Before(func(apiReq *apistruct.KickGroupMemberReq, rpcReq *group.KickGroupMemberReq, bind func() error) error {
|
|
||||||
// // return bind()
|
|
||||||
// //}).After(func(rpcResp *group.KickGroupMemberResp, apiResp *apistruct.KickGroupMemberResp, bind func() error) error {
|
|
||||||
// // return bind()
|
|
||||||
// //}).Execute()
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
|
|
||||||
func NewGin[A, B any](c *gin.Context) ApiBind[A, B] {
|
|
||||||
return &ginApiBind[A, B]{
|
|
||||||
c: c,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type ginApiBind[A, B any] struct {
|
|
||||||
c *gin.Context
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *ginApiBind[A, B]) OperationID() string {
|
|
||||||
return g.c.GetHeader("operationID")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *ginApiBind[A, B]) OpUserID() (string, error) {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *ginApiBind[A, B]) Bind(a *A) error {
|
|
||||||
return g.c.BindJSON(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *ginApiBind[A, B]) Resp(resp *B, err error) {
|
|
||||||
if err == nil {
|
|
||||||
g.Write(resp)
|
|
||||||
} else {
|
|
||||||
g.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *ginApiBind[A, B]) Error(err error) {
|
|
||||||
//TODO implement me
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *ginApiBind[A, B]) Write(b *B) {
|
|
||||||
//TODO implement me
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *ginApiBind[A, B]) Context() context.Context {
|
|
||||||
return g.c
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewGin1(c *gin.Context) Api {
|
|
||||||
return &ginApi{
|
|
||||||
c: c,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type ginApi struct {
|
|
||||||
c *gin.Context
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *ginApi) OperationID() string {
|
|
||||||
return g.c.GetHeader("operationID")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *ginApi) OpUserID() string {
|
|
||||||
return g.c.MustGet("opUserID").(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *ginApi) Context() context.Context {
|
|
||||||
return g.c
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *ginApi) Bind(req any) error {
|
|
||||||
return g.c.BindJSON(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *ginApi) Resp(resp any, err error) {
|
|
||||||
//TODO implement me
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
package api2rpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
)
|
|
||||||
|
|
||||||
type FUNC[E, C, D any] func(client E, ctx context.Context, req *C, options ...grpc.CallOption) (*D, error)
|
|
||||||
|
|
||||||
// Call1 TEST
|
|
||||||
func Call1[A, B, C, D, E any](
|
|
||||||
apiReq *A,
|
|
||||||
apiResp *B,
|
|
||||||
rpc FUNC[E, C, D],
|
|
||||||
//client func() (E, error),
|
|
||||||
c *gin.Context,
|
|
||||||
before func(apiReq *A, rpcReq *C, bind func() error) error,
|
|
||||||
after func(rpcResp *D, apiResp *B, bind func() error) error,
|
|
||||||
) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func Call2[C, D, E any](
|
|
||||||
rpc func(client E, ctx context.Context, req *C, options ...grpc.CallOption) (*D, error),
|
|
||||||
client func() (E, error),
|
|
||||||
c *gin.Context,
|
|
||||||
) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func Call3[C, D, E any](
|
|
||||||
rpc func(client E, ctx context.Context, req *C, options ...grpc.CallOption) (*D, error),
|
|
||||||
//client func() (E, error),
|
|
||||||
c *gin.Context,
|
|
||||||
) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func Call4[C, D, E any](
|
|
||||||
rpc func(client E, ctx context.Context, req *C, options ...grpc.CallOption) (*D, error),
|
|
||||||
c *gin.Context,
|
|
||||||
) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func Call10[A, B, C, D, E any](apiReq A, apiResp B, client func() (E, error), call func(client E, rpcReq C) (D, error)) {
|
|
||||||
|
|
||||||
}
|
|
@ -1,114 +0,0 @@
|
|||||||
package api2rpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
var nameMap = map[string]string{}
|
|
||||||
|
|
||||||
func getName[T any]() string {
|
|
||||||
var t T
|
|
||||||
return reflect.TypeOf(&t).Elem().Name()
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRpc A: apiReq B: apiResp C: rpcReq D: rpcResp Z: rpcClient (group.GroupClient)
|
|
||||||
func NewRpc[A, B any, C, D any, Z any](bind ApiBind[A, B], client func(conn *grpc.ClientConn) Z, rpc func(client Z, ctx context.Context, req *C, options ...grpc.CallOption) (*D, error)) *RpcXXXX[A, B, C, D, Z] {
|
|
||||||
return &RpcXXXX[A, B, C, D, Z]{
|
|
||||||
bind: bind,
|
|
||||||
client: client,
|
|
||||||
rpc: rpc,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type RpcXXXX[A, B any, C, D any, Z any] struct {
|
|
||||||
bind ApiBind[A, B]
|
|
||||||
name string
|
|
||||||
client func(conn *grpc.ClientConn) Z
|
|
||||||
rpc func(client Z, ctx context.Context, req *C, options ...grpc.CallOption) (*D, error)
|
|
||||||
before func(apiReq *A, rpcReq *C, bind func() error) error
|
|
||||||
after func(rpcResp *D, apiResp *B, bind func() error) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *RpcXXXX[A, B, C, D, Z]) Name(name string) *RpcXXXX[A, B, C, D, Z] {
|
|
||||||
a.name = name
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *RpcXXXX[A, B, C, D, Z]) Before(fn func(apiReq *A, rpcReq *C, bind func() error) error) *RpcXXXX[A, B, C, D, Z] {
|
|
||||||
a.before = fn
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *RpcXXXX[A, B, C, D, Z]) After(fn func(rpcResp *D, apiResp *B, bind func() error) error) *RpcXXXX[A, B, C, D, Z] {
|
|
||||||
a.after = fn
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *RpcXXXX[A, B, C, D, Z]) defaultCopyReq(apiReq *A, rpcReq *C) error {
|
|
||||||
CopyAny(apiReq, rpcReq)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *RpcXXXX[A, B, C, D, Z]) defaultCopyResp(rpcResp *D, apiResp *B) error {
|
|
||||||
CopyAny(rpcResp, apiResp)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *RpcXXXX[A, B, C, D, Z]) getZtype() string {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *RpcXXXX[A, B, C, D, Z]) GetGrpcConn() (*grpc.ClientConn, error) {
|
|
||||||
if a.name == "" {
|
|
||||||
a.name = nameMap[getName[Z]()]
|
|
||||||
}
|
|
||||||
// todo 获取连接
|
|
||||||
|
|
||||||
return nil, nil // todo
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *RpcXXXX[A, B, C, D, Z]) execute() (*B, error) {
|
|
||||||
var apiReq A
|
|
||||||
if err := a.bind.Bind(&apiReq); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
opID := a.bind.OperationID()
|
|
||||||
userID, err := a.bind.OpUserID()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
_, _ = opID, userID
|
|
||||||
var rpcReq C
|
|
||||||
if a.before == nil {
|
|
||||||
err = a.defaultCopyReq(&apiReq, &rpcReq)
|
|
||||||
} else {
|
|
||||||
err = a.before(&apiReq, &rpcReq, func() error { return a.defaultCopyReq(&apiReq, &rpcReq) })
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
conn, err := a.GetGrpcConn()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
rpcResp, err := a.rpc(a.client(conn), a.bind.Context(), &rpcReq)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var apiResp B
|
|
||||||
if a.after == nil {
|
|
||||||
err = a.defaultCopyResp(rpcResp, &apiResp)
|
|
||||||
} else {
|
|
||||||
err = a.after(rpcResp, &apiResp, func() error { return a.defaultCopyResp(rpcResp, &apiResp) })
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &apiResp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *RpcXXXX[A, B, C, D, Z]) Call() {
|
|
||||||
a.bind.Resp(a.execute())
|
|
||||||
}
|
|
@ -1,104 +0,0 @@
|
|||||||
package api2rpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"OpenIM/pkg/errs"
|
|
||||||
"context"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
)
|
|
||||||
|
|
||||||
type rpcFunc[E, C, D any] func(client E, ctx context.Context, req *C, options ...grpc.CallOption) (*D, error)
|
|
||||||
|
|
||||||
func New[A, B, C, D, E any](apiReq *A, apiResp *B, rpc func(client E, ctx context.Context, req *C, options ...grpc.CallOption) (*D, error)) RpcCall[A, B, C, D, E] {
|
|
||||||
return &rpcCall[A, B, C, D, E]{
|
|
||||||
apiReq: apiReq,
|
|
||||||
apiResp: apiResp,
|
|
||||||
rpcFn: rpc,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type rpcCall[A, B, C, D any, E any] struct {
|
|
||||||
apiReq *A
|
|
||||||
apiResp *B
|
|
||||||
rpcFn func(client E, ctx context.Context, req *C, options ...grpc.CallOption) (*D, error)
|
|
||||||
before func(apiReq *A, rpcReq *C, bind func() error) error
|
|
||||||
after func(rpcResp *D, apiResp *B, bind func() error) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *rpcCall[A, B, C, D, E]) Before(fn func(apiReq *A, rpcReq *C, bind func() error) error) RpcCall[A, B, C, D, E] {
|
|
||||||
r.before = fn
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *rpcCall[A, B, C, D, E]) After(fn func(rpcResp *D, apiResp *B, bind func() error) error) RpcCall[A, B, C, D, E] {
|
|
||||||
r.after = fn
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *rpcCall[A, B, C, D, E]) Call(c *gin.Context, client func() (E, error)) {
|
|
||||||
var resp baseResp
|
|
||||||
err := r.call(c, client)
|
|
||||||
if err == nil {
|
|
||||||
resp.Data = r.apiResp
|
|
||||||
} else {
|
|
||||||
cerr, ok := err.(errs.Coderr)
|
|
||||||
if ok {
|
|
||||||
resp.ErrCode = int32(cerr.Code())
|
|
||||||
resp.ErrMsg = cerr.Msg()
|
|
||||||
resp.ErrDtl = cerr.Detail()
|
|
||||||
} else {
|
|
||||||
resp.ErrCode = 10000
|
|
||||||
resp.ErrMsg = err.Error()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *rpcCall[A, B, C, D, E]) defaultCopyReq(rpcReq *C) error {
|
|
||||||
if r.apiReq != nil {
|
|
||||||
CopyAny(r.apiReq, rpcReq)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *rpcCall[A, B, C, D, E]) defaultCopyResp(rpcResp *D) error {
|
|
||||||
if r.apiResp != nil {
|
|
||||||
CopyAny(rpcResp, r.apiResp)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *rpcCall[A, B, C, D, E]) call(c *gin.Context, client func() (E, error)) error {
|
|
||||||
if err := c.BindJSON(r.apiReq); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var err error
|
|
||||||
var rpcReq C
|
|
||||||
if r.before == nil {
|
|
||||||
err = r.defaultCopyReq(&rpcReq)
|
|
||||||
} else {
|
|
||||||
err = r.before(r.apiReq, &rpcReq, func() error { return r.defaultCopyReq(&rpcReq) })
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
cli, err := client()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
rpcResp, err := r.rpcFn(cli, c, &rpcReq)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var apiResp B
|
|
||||||
if r.after == nil {
|
|
||||||
return r.defaultCopyResp(rpcResp)
|
|
||||||
} else {
|
|
||||||
return r.after(rpcResp, &apiResp, func() error { return r.defaultCopyResp(rpcResp) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type RpcCall[A, B, C, D, E any] interface {
|
|
||||||
Before(fn func(apiReq *A, rpcReq *C, bind func() error) error) RpcCall[A, B, C, D, E]
|
|
||||||
After(fn func(rpcResp *D, apiResp *B, bind func() error) error) RpcCall[A, B, C, D, E]
|
|
||||||
Call(c *gin.Context, client func() (E, error))
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user