fix: some api bug

This commit is contained in:
wwweww
2026-03-31 22:12:06 +08:00
parent c5ff4f0216
commit e7970ac25f
219 changed files with 16195 additions and 2126 deletions
-31
View File
@@ -1,31 +0,0 @@
# authz-adapter
Envoy `ext_authz` 适配服务,实现 `envoy.service.auth.v3.Authorization`,并调用 `user-rpc.ValidateToken`
## 环境变量
- `LISTEN_ON`:监听地址,默认 `0.0.0.0:9002`
- `USER_RPC_TARGET`user-rpc 地址,默认 `user-rpc-svc.juwan.svc.cluster.local:9001`
## 本地运行
```powershell
go run ./app/authz/adapter
```
## Docker 构建
在仓库根目录执行:
```powershell
docker build -f app/authz/adapter/Dockerfile -t authz-adapter:local .
docker run --rm -p 9002:9002 authz-adapter:local
```
## 说明
- 放行路径:`/healthz``/api/users/login``/api/users/register`
- 受保护路径:其余请求要求
- Cookie 中有 `JToken`
- Header 中有 `x-auth-user-id`(由 Envoy `jwt_authn` 注入)
- 鉴权通过后回传:`x-auth-user-id``x-auth-role-type`
+4 -1
View File
@@ -15,6 +15,7 @@ import (
corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
authv3 "github.com/envoyproxy/go-control-plane/envoy/service/auth/v3"
typev3 "github.com/envoyproxy/go-control-plane/envoy/type/v3"
"github.com/zeromicro/go-zero/core/logx"
codepb "google.golang.org/genproto/googleapis/rpc/code"
statuspb "google.golang.org/genproto/googleapis/rpc/status"
"google.golang.org/grpc"
@@ -68,15 +69,17 @@ func (s *authzServer) Check(ctx context.Context, req *authv3.CheckRequest) (*aut
UserId: userID,
})
if err != nil {
logx.Infof("validate token rpc failed, err: %v", err)
return deny(codepb.Code_UNAUTHENTICATED, typev3.StatusCode_Unauthorized, "validate token failed"), nil
}
if !resp.GetValid() {
logx.Infof("validate token rpc failed, err: %v", err)
return deny(codepb.Code_PERMISSION_DENIED, typev3.StatusCode_Forbidden, "token invalid"), nil
}
outHeaders := []*corev3.HeaderValueOption{
{Header: &corev3.HeaderValue{Key: headerAuthUserID, Value: strconv.FormatInt(resp.GetUserId(), 10)}},
{Header: &corev3.HeaderValue{Key: headerAuthRoleType, Value: strconv.FormatInt(resp.GetRoleType(), 10)}},
{Header: &corev3.HeaderValue{Key: headerAuthRoleType, Value: resp.GetRoleType()}},
}
if getHeader(httpReq.GetHeaders(), headerAuthIsAdmin) != "" {
+1 -1
View File
@@ -8,7 +8,7 @@ Prometheus:
Kmq:
Name: email-mq
Brokers:
- my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092
- "${KAFKA_BROKER}"
Topic: email-task
Group: email-consumer-group
ForceCommit: true
+10 -1
View File
@@ -7,5 +7,14 @@ Prometheus:
Port: 4001
Path: /metrics
# ===== PROC CONF =====
#GameRpcConf:
# Target: k8s://juwan/game-rpc-svc:8080
# ===== DEV CONF =====
GameRpcConf:
Target: k8s://juwan/game-rpc-svc:8080
Endpoints:
- game-rpc:8080
Log:
Level: debug
+3
View File
@@ -6,6 +6,7 @@ package main
import (
"flag"
"fmt"
"juwan-backend/common/middlewares"
"juwan-backend/app/game/api/internal/config"
"juwan-backend/app/game/api/internal/handler"
@@ -24,6 +25,8 @@ func main() {
conf.MustLoad(*configFile, &c)
server := rest.MustNewServer(c.RestConf)
server.Use(middlewares.NewRequestMiddleware().Handle)
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
defer server.Stop()
ctx := svc.NewServiceContext(c)
@@ -0,0 +1,32 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package game
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/game/api/internal/logic/game"
"juwan-backend/app/game/api/internal/svc"
"juwan-backend/app/game/api/internal/types"
)
// 创建游戏
func CreateGameHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.Game
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := game.NewCreateGameLogic(r.Context(), svcCtx)
resp, err := l.CreateGame(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
+6
View File
@@ -21,6 +21,12 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
Path: "/",
Handler: game.ListGamesHandler(serverCtx),
},
{
// 创建游戏
Method: http.MethodPost,
Path: "/",
Handler: game.CreateGameHandler(serverCtx),
},
{
// 获取游戏详情
Method: http.MethodGet,
@@ -0,0 +1,46 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package game
import (
"context"
"errors"
"juwan-backend/app/game/rpc/pb"
"juwan-backend/app/game/api/internal/svc"
"juwan-backend/app/game/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type CreateGameLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// 创建游戏
func NewCreateGameLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateGameLogic {
return &CreateGameLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *CreateGameLogic) CreateGame(req *types.Game) (resp *types.Game, err error) {
// todo: add your logic here and delete this line
_, err = l.svcCtx.GameRpc.AddGames(l.ctx, &pb.AddGamesReq{
Name: req.Name,
Icon: req.Icon,
Category: req.Category,
IsActive: false,
})
if err != nil {
logx.Errorf("add game err: %v", err)
return nil, errors.New("add game err")
}
return &types.Game{}, nil
}
@@ -35,6 +35,7 @@ func (l *ListGamesLogic) ListGames(req *types.PageReq) (resp *types.GameListResp
Limit: req.Limit,
})
if err != nil {
logx.Errorf("ListGames err:%v", err)
return nil, err
}
+31 -14
View File
@@ -6,23 +6,40 @@ Prometheus:
Port: 4001
Path: /metrics
DB:
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
# ===== PROC CONF =====
#DB:
# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
# Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
#
#
#SnowflakeRpcConf:
# Target: k8s://juwan/snowflake-svc:8080
#
#CacheConf:
# - Host: "${REDIS_M_HOST}"
# Type: node
# Pass: "${REDIS_PASSWORD}"
# User: "default"
# - Host: "${REDIS_S_HOST}"
# Type: node
# Pass: "${REDIS_PASSWORD}"
# User: "default"
#
#Log:
# Level: info
# ===== DEV CONF =====
SnowflakeRpcConf:
Target: k8s://juwan/snowflake-svc:8080
Endpoints:
- snowflake:8080
DB:
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
CacheConf:
- Host: "${REDIS_M_HOST}"
- Host: "${REDIS_HOST}:${REDIS_PORT}"
Type: node
Pass: "${REDIS_PASSWORD}"
User: "default"
- Host: "${REDIS_S_HOST}"
Type: node
Pass: "${REDIS_PASSWORD}"
User: "default"
Log:
Level: info
Level: debug
+1 -1
View File
@@ -37,7 +37,7 @@ func (l *AddGamesLogic) AddGames(in *pb.AddGamesReq) (*pb.AddGamesResp, error) {
SetName(in.Name).
SetIcon(in.Icon).
SetCategory(in.Category).
SetSortOrder(int(in.SortOrder)).
SetSortOrder(0).
Save(l.ctx)
if err != nil {
logx.Errorf("AddGamesLogic.addGames err:%v", err)
@@ -6,6 +6,7 @@ import (
"juwan-backend/app/game/rpc/internal/svc"
"juwan-backend/app/game/rpc/pb"
"ariga.io/entcache"
"github.com/jinzhu/copier"
"github.com/zeromicro/go-zero/core/logx"
)
@@ -25,14 +26,19 @@ func NewSearchGamesLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Searc
}
func (l *SearchGamesLogic) SearchGames(in *pb.SearchGamesReq) (*pb.SearchGamesResp, error) {
notFoundErr := entcache.ErrNotFound
if in.Page <= 0 || in.Limit <= 0 || in.Page > 1000 || in.Limit > 100 {
return nil, errors.New("invalid pagination parameters")
}
all, err := l.svcCtx.GameModelRO.Games.Query().Limit(int(in.Limit)).Offset(int(in.Limit * (in.Page - 1))).All(l.ctx)
if err != nil {
if err != nil && !errors.As(err, &notFoundErr) {
logx.Errorf("failed to query games: %v", err)
return nil, errors.New("failed to query games")
}
logx.Debugf("games: %v", all)
if err != nil {
return &pb.SearchGamesResp{}, nil
}
list := make([]*pb.Games, 0, len(all))
for _, v := range all {
temp := &pb.Games{}
+6 -2
View File
@@ -1,6 +1,7 @@
package svc
import (
stdsql "database/sql"
"juwan-backend/app/game/rpc/internal/config"
"juwan-backend/app/game/rpc/internal/models"
"juwan-backend/app/snowflake/rpc/snowflake"
@@ -10,6 +11,7 @@ import (
"time"
"ariga.io/entcache"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"github.com/zeromicro/go-zero/core/logx"
@@ -24,14 +26,16 @@ type ServiceContext struct {
}
func NewServiceContext(c config.Config) *ServiceContext {
RWConn, err := sql.Open("pgx", c.DB.Master)
rawRW, err := stdsql.Open("pgx", c.DB.Master)
if err != nil {
panic(err)
}
ROConn, err := sql.Open("pgx", c.DB.Slaves)
rawRO, err := stdsql.Open("pgx", c.DB.Slaves)
if err != nil {
panic(err)
}
RWConn := sql.OpenDB(dialect.Postgres, rawRW)
ROConn := sql.OpenDB(dialect.Postgres, rawRO)
redisCluster, err := redisx.ConnectMasterSlaveCluster(c.CacheConf, 5*time.Second)
if redisCluster == nil || err != nil {
+12 -2
View File
@@ -8,10 +8,20 @@ Prometheus:
Path: /metrics
FileRpcConf:
Target: k8s://juwan/objectstory-rpc-svc:8080
# ===== PROC CONF =====
#FileRpcConf:
# Target: k8s://juwan/objectstory-rpc-svc:8080
#
#Log:
# Level: info
# ===== DEV CONF =====
FileRpcConf:
Endpoints:
- objectstory-rpc:8080
Log:
Level: debug
# k8s://juwan/<service name>:8080
@@ -20,7 +20,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
{
// 文件获取接口 (如果是私有文件,通过此接口获取或重定向)
Method: http.MethodGet,
Path: "/files/:fileId",
Path: "/files",
Handler: file.GetFileHandler(serverCtx),
},
{
+1 -1
View File
@@ -4,7 +4,7 @@
package types
type GetFileReq struct {
FileId string `path:"fileId"`
FileId string `form:"key"`
}
type UploadReq struct {
+3
View File
@@ -6,6 +6,7 @@ package main
import (
"flag"
"fmt"
"juwan-backend/common/middlewares"
"juwan-backend/app/objectstory/api/internal/config"
"juwan-backend/app/objectstory/api/internal/handler"
@@ -24,6 +25,8 @@ func main() {
conf.MustLoad(*configFile, &c)
server := rest.MustNewServer(c.RestConf)
server.Use(middlewares.NewRequestMiddleware().Handle)
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
defer server.Stop()
ctx := svc.NewServiceContext(c)
+3 -2
View File
@@ -22,6 +22,9 @@ S3Conf:
Region: auto
UsePathStyle: true
Log:
Level: debug
#DB:
# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
# Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
@@ -36,5 +39,3 @@ S3Conf:
# Pass: "${REDIS_PASSWORD}"
# User: "default"
#
Log:
Level: info
+17 -3
View File
@@ -8,11 +8,25 @@ Prometheus:
Path: /metrics
# k8s://juwan/<service name>:8080
# ===== PROC CONF =====
#OrderRpcConf:
# Target: k8s://juwan/order-rpc-svc:8080
#
#PlayerRpcConf:
# Target: k8s://juwan/player-rpc-svc:8080
#
#ShopRpcConf:
# Target: k8s://juwan/shop-rpc-svc:8080
# ===== DEV CONF ====
OrderRpcConf:
Target: k8s://juwan/order-rpc-svc:8080
Endpoints:
- order-rpc:8080
PlayerRpcConf:
Target: k8s://juwan/player-rpc-svc:8080
Endpoints:
- player-rpc:8080
ShopRpcConf:
Target: k8s://juwan/shop-rpc-svc:8080
Endpoints:
- shop-rpc:8080
+3
View File
@@ -6,6 +6,7 @@ package main
import (
"flag"
"fmt"
"juwan-backend/common/middlewares"
"juwan-backend/app/order/api/internal/config"
"juwan-backend/app/order/api/internal/handler"
@@ -24,6 +25,8 @@ func main() {
conf.MustLoad(*configFile, &c)
server := rest.MustNewServer(c.RestConf)
server.Use(middlewares.NewRequestMiddleware().Handle)
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
defer server.Stop()
ctx := svc.NewServiceContext(c)
+29 -13
View File
@@ -14,25 +14,41 @@ Prometheus:
# Target: k8s://juwan/<service name>.<namespace>:8080
# ==== PROC CONF ====
#SnowflakeRpcConf:
# Target: k8s://juwan/snowflake-svc:8080
#
#
#DB:
# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
# Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
#
#
#CacheConf:
# - Host: "${REDIS_M_HOST}"
# Type: node
# Pass: "${REDIS_PASSWORD}"
# User: "default"
# - Host: "${REDIS_S_HOST}"
# Type: node
# Pass: "${REDIS_PASSWORD}"
# User: "default"
#
#Log:
# Level: info
# ==== DEV CONF ====
SnowflakeRpcConf:
Target: k8s://juwan/snowflake-svc:8080
Endpoints:
- snowflake:8080
DB:
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
CacheConf:
- Host: "${REDIS_M_HOST}"
- Host: "${REDIS_HOST}:${REDIS_PORT}"
Type: node
Pass: "${REDIS_PASSWORD}"
User: "default"
- Host: "${REDIS_S_HOST}"
Type: node
Pass: "${REDIS_PASSWORD}"
User: "default"
Log:
Level: info
Level: debug
+10 -6
View File
@@ -1,20 +1,22 @@
package svc
import (
stdsql "database/sql"
"fmt"
"strings"
"time"
"ariga.io/entcache"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
_ "github.com/jackc/pgx/v5/stdlib"
"github.com/zeromicro/go-zero/core/logx"
"juwan-backend/app/order/rpc/internal/config"
"juwan-backend/app/order/rpc/internal/models"
"juwan-backend/app/snowflake/rpc/snowflake"
"juwan-backend/common/redisx"
"juwan-backend/common/snowflakex"
"juwan-backend/pkg/adapter"
"ariga.io/entcache"
"entgo.io/ent/dialect/sql"
"github.com/zeromicro/go-zero/core/logx"
)
type ServiceContext struct {
@@ -25,14 +27,16 @@ type ServiceContext struct {
}
func NewServiceContext(c config.Config) *ServiceContext {
RWConn, err := sql.Open("pgx", c.DB.Master)
rawRW, err := stdsql.Open("pgx", c.DB.Master)
if err != nil {
panic(err)
}
ROConn, err := sql.Open("pgx", c.DB.Slaves)
rawRO, err := stdsql.Open("pgx", c.DB.Slaves)
if err != nil {
panic(err)
}
RWConn := sql.OpenDB(dialect.Postgres, rawRW)
ROConn := sql.OpenDB(dialect.Postgres, rawRO)
redisCluster, err := redisx.ConnectMasterSlaveCluster(c.CacheConf, 5*time.Second)
if redisCluster == nil || err != nil {
+1 -1
View File
@@ -22,7 +22,7 @@ func main() {
flag.Parse()
var c config.Config
conf.MustLoad(*configFile, &c)
conf.MustLoad(*configFile, &c, conf.UseEnv())
ctx := svc.NewServiceContext(c)
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
+7 -2
View File
@@ -8,6 +8,11 @@ Prometheus:
Path: /metrics
# k8s://juwan/<service name>:8080
PlayerRpcConf:
Target: k8s://juwan/player-rpc-svc:8080
# ===== PROC CONF =====
#PlayerRpcConf:
# Target: k8s://juwan/player-rpc-svc:8080
# ===== DEV CONF ====
PlayerRpcConf:
Endpoints:
- player-rpc:8080
@@ -32,9 +32,9 @@ func NewListPlayersLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListP
func (l *ListPlayersLogic) ListPlayers(req *types.PlayerListReq) (resp *types.PlayerListResp, err error) {
// todo: add your logic here and delete this line
p, err := l.svcCtx.PlayerRpc.SearchPlayers(l.ctx, &pb.SearchPlayersReq{
Page: req.Offset,
Limit: req.Limit,
Gender: int64(req.Gender),
Page: &req.Offset,
Limit: &req.Limit,
Gender: &req.Gender,
})
if err != nil {
return nil, err
+2 -1
View File
@@ -48,7 +48,7 @@ type PageReq struct {
type PlayerListReq struct {
PageReq
GameId int64 `form:"gameId,optional"`
Gender int `form:"gender,optional"`
Gender int64 `form:"gender,optional"`
}
type PlayerListResp struct {
@@ -67,6 +67,7 @@ type PlayerProfile struct {
Services []PlayerService `json:"services"`
ShopId string `json:"shopId,optional"`
ShopName string `json:"shopName,optional"`
Gender bool `json:"gender"`
Tags []string `json:"tags"`
}
+25 -12
View File
@@ -8,28 +8,41 @@ Prometheus:
Path: /metrics
SnowflakeRpcConf:
Target: k8s://juwan/snowflake-svc:8080
# ===== PROC CONF =====
#SnowflakeRpcConf:
# Target: k8s://juwan/snowflake-svc:8080
#DB:
# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
# Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
#
#CacheConf:
# - Host: "${REDIS_M_HOST}"
# Type: node
# Pass: "${REDIS_PASSWORD}"
# User: "default"
# - Host: "${REDIS_S_HOST}"
# Type: node
# Pass: "${REDIS_PASSWORD}"
# User: "default"
#
#Log:
# Level: info
# ===== DEV CONF =====
SnowflakeRpcConf:
Endpoints:
- snowflake:8080
DB:
Master: "postgresql://app:7BGs8CdEE8sLPshMjyXkYmxNMTV88EBrd2GN6tdIX1VhIgBzIcgKXbJjVdYiX4a9@user-db-rw:5432/app"
Slaves: "postgresql://app:7BGs8CdEE8sLPshMjyXkYmxNMTV88EBrd2GN6tdIX1VhIgBzIcgKXbJjVdYiX4a9@user-db-ro:5432/app"
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
CacheConf:
- Host: "${REDIS_M_HOST}"
- Host: "${REDIS_HOST}:${REDIS_PORT}"
Type: node
Pass: "${REDIS_PASSWORD}"
User: "default"
- Host: "${REDIS_S_HOST}"
Type: node
Pass: "${REDIS_PASSWORD}"
User: "default"
Log:
Level: info
Level: debug
@@ -4,7 +4,6 @@ import (
"context"
"errors"
"juwan-backend/app/player/rpc/internal/models/players"
"juwan-backend/app/player/rpc/internal/svc"
"juwan-backend/app/player/rpc/pb"
@@ -27,16 +26,17 @@ func NewSearchPlayersLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Sea
}
func (l *SearchPlayersLogic) SearchPlayers(in *pb.SearchPlayersReq) (*pb.SearchPlayersResp, error) {
gender := 0
if in.Gender > 0 {
gender = 1
}
searcher := l.svcCtx.PlayerModelRO.Players.Query()
if in.Gender >= 0 {
if in.Gender != nil && *in.Gender != 0 {
// 1 man 2 woman
gender := true
if *in.Gender == 2 {
gender = false
}
searcher.Where(players.GenderEQ(gender))
}
all, err := searcher.Limit(int(in.Limit)).Offset(int(in.Page * in.Limit)).All(l.ctx)
all, err := searcher.Limit(int(*in.Limit)).Offset(int(*in.Page * *in.Limit)).All(l.ctx)
if err != nil {
logx.Errorf("SearchPlayers err: %v", err)
return nil, errors.New("search players")
@@ -36,7 +36,7 @@ var (
{Name: "id", Type: field.TypeInt64, Increment: true},
{Name: "user_id", Type: field.TypeInt64, Unique: true},
{Name: "status", Type: field.TypeString, Size: 20, Default: "offline"},
{Name: "gender", Type: field.TypeInt, Unique: true},
{Name: "gender", Type: field.TypeBool, Default: true},
{Name: "rating", Type: field.TypeOther, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(3,2)"}},
{Name: "total_orders", Type: field.TypeInt, Nullable: true, Default: 0},
{Name: "completed_orders", Type: field.TypeInt, Nullable: true, Default: 0},
+6 -39
View File
@@ -1131,8 +1131,7 @@ type PlayersMutation struct {
user_id *int64
adduser_id *int64
status *string
gender *int
addgender *int
gender *bool
rating *decimal.Decimal
total_orders *int
addtotal_orders *int
@@ -1348,13 +1347,12 @@ func (m *PlayersMutation) ResetStatus() {
}
// SetGender sets the "gender" field.
func (m *PlayersMutation) SetGender(i int) {
m.gender = &i
m.addgender = nil
func (m *PlayersMutation) SetGender(b bool) {
m.gender = &b
}
// Gender returns the value of the "gender" field in the mutation.
func (m *PlayersMutation) Gender() (r int, exists bool) {
func (m *PlayersMutation) Gender() (r bool, exists bool) {
v := m.gender
if v == nil {
return
@@ -1365,7 +1363,7 @@ func (m *PlayersMutation) Gender() (r int, exists bool) {
// OldGender returns the old "gender" field's value of the Players entity.
// If the Players object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *PlayersMutation) OldGender(ctx context.Context) (v int, err error) {
func (m *PlayersMutation) OldGender(ctx context.Context) (v bool, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldGender is only allowed on UpdateOne operations")
}
@@ -1379,28 +1377,9 @@ func (m *PlayersMutation) OldGender(ctx context.Context) (v int, err error) {
return oldValue.Gender, nil
}
// AddGender adds i to the "gender" field.
func (m *PlayersMutation) AddGender(i int) {
if m.addgender != nil {
*m.addgender += i
} else {
m.addgender = &i
}
}
// AddedGender returns the value that was added to the "gender" field in this mutation.
func (m *PlayersMutation) AddedGender() (r int, exists bool) {
v := m.addgender
if v == nil {
return
}
return *v, true
}
// ResetGender resets all changes to the "gender" field.
func (m *PlayersMutation) ResetGender() {
m.gender = nil
m.addgender = nil
}
// SetRating sets the "rating" field.
@@ -2001,7 +1980,7 @@ func (m *PlayersMutation) SetField(name string, value ent.Value) error {
m.SetStatus(v)
return nil
case players.FieldGender:
v, ok := value.(int)
v, ok := value.(bool)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
@@ -2074,9 +2053,6 @@ func (m *PlayersMutation) AddedFields() []string {
if m.adduser_id != nil {
fields = append(fields, players.FieldUserID)
}
if m.addgender != nil {
fields = append(fields, players.FieldGender)
}
if m.addtotal_orders != nil {
fields = append(fields, players.FieldTotalOrders)
}
@@ -2096,8 +2072,6 @@ func (m *PlayersMutation) AddedField(name string) (ent.Value, bool) {
switch name {
case players.FieldUserID:
return m.AddedUserID()
case players.FieldGender:
return m.AddedGender()
case players.FieldTotalOrders:
return m.AddedTotalOrders()
case players.FieldCompletedOrders:
@@ -2120,13 +2094,6 @@ func (m *PlayersMutation) AddField(name string, value ent.Value) error {
}
m.AddUserID(v)
return nil
case players.FieldGender:
v, ok := value.(int)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.AddGender(v)
return nil
case players.FieldTotalOrders:
v, ok := value.(int)
if !ok {
+6 -4
View File
@@ -25,7 +25,7 @@ type Players struct {
// Status holds the value of the "status" field.
Status string `json:"status,omitempty"`
// Gender holds the value of the "gender" field.
Gender int `json:"gender,omitempty"`
Gender bool `json:"gender,omitempty"`
// Rating holds the value of the "rating" field.
Rating decimal.Decimal `json:"rating,omitempty"`
// TotalOrders holds the value of the "total_orders" field.
@@ -56,7 +56,9 @@ func (*Players) scanValues(columns []string) ([]any, error) {
values[i] = new(decimal.Decimal)
case players.FieldGames:
values[i] = new(pq.Int64Array)
case players.FieldID, players.FieldUserID, players.FieldGender, players.FieldTotalOrders, players.FieldCompletedOrders, players.FieldShopID:
case players.FieldGender:
values[i] = new(sql.NullBool)
case players.FieldID, players.FieldUserID, players.FieldTotalOrders, players.FieldCompletedOrders, players.FieldShopID:
values[i] = new(sql.NullInt64)
case players.FieldStatus:
values[i] = new(sql.NullString)
@@ -96,10 +98,10 @@ func (_m *Players) assignValues(columns []string, values []any) error {
_m.Status = value.String
}
case players.FieldGender:
if value, ok := values[i].(*sql.NullInt64); !ok {
if value, ok := values[i].(*sql.NullBool); !ok {
return fmt.Errorf("unexpected type %T for field gender", values[i])
} else if value.Valid {
_m.Gender = int(value.Int64)
_m.Gender = value.Bool
}
case players.FieldRating:
if value, ok := values[i].(*decimal.Decimal); !ok {
@@ -72,6 +72,8 @@ var (
DefaultStatus string
// StatusValidator is a validator for the "status" field. It is called by the builders before save.
StatusValidator func(string) error
// DefaultGender holds the default value on creation for the "gender" field.
DefaultGender bool
// DefaultRating holds the default value on creation for the "rating" field.
DefaultRating decimal.Decimal
// DefaultTotalOrders holds the default value on creation for the "total_orders" field.
@@ -67,7 +67,7 @@ func Status(v string) predicate.Players {
}
// Gender applies equality check predicate on the "gender" field. It's identical to GenderEQ.
func Gender(v int) predicate.Players {
func Gender(v bool) predicate.Players {
return predicate.Players(sql.FieldEQ(FieldGender, v))
}
@@ -212,45 +212,15 @@ func StatusContainsFold(v string) predicate.Players {
}
// GenderEQ applies the EQ predicate on the "gender" field.
func GenderEQ(v int) predicate.Players {
func GenderEQ(v bool) predicate.Players {
return predicate.Players(sql.FieldEQ(FieldGender, v))
}
// GenderNEQ applies the NEQ predicate on the "gender" field.
func GenderNEQ(v int) predicate.Players {
func GenderNEQ(v bool) predicate.Players {
return predicate.Players(sql.FieldNEQ(FieldGender, v))
}
// GenderIn applies the In predicate on the "gender" field.
func GenderIn(vs ...int) predicate.Players {
return predicate.Players(sql.FieldIn(FieldGender, vs...))
}
// GenderNotIn applies the NotIn predicate on the "gender" field.
func GenderNotIn(vs ...int) predicate.Players {
return predicate.Players(sql.FieldNotIn(FieldGender, vs...))
}
// GenderGT applies the GT predicate on the "gender" field.
func GenderGT(v int) predicate.Players {
return predicate.Players(sql.FieldGT(FieldGender, v))
}
// GenderGTE applies the GTE predicate on the "gender" field.
func GenderGTE(v int) predicate.Players {
return predicate.Players(sql.FieldGTE(FieldGender, v))
}
// GenderLT applies the LT predicate on the "gender" field.
func GenderLT(v int) predicate.Players {
return predicate.Players(sql.FieldLT(FieldGender, v))
}
// GenderLTE applies the LTE predicate on the "gender" field.
func GenderLTE(v int) predicate.Players {
return predicate.Players(sql.FieldLTE(FieldGender, v))
}
// RatingEQ applies the EQ predicate on the "rating" field.
func RatingEQ(v decimal.Decimal) predicate.Players {
return predicate.Players(sql.FieldEQ(FieldRating, v))
@@ -43,11 +43,19 @@ func (_c *PlayersCreate) SetNillableStatus(v *string) *PlayersCreate {
}
// SetGender sets the "gender" field.
func (_c *PlayersCreate) SetGender(v int) *PlayersCreate {
func (_c *PlayersCreate) SetGender(v bool) *PlayersCreate {
_c.mutation.SetGender(v)
return _c
}
// SetNillableGender sets the "gender" field if the given value is not nil.
func (_c *PlayersCreate) SetNillableGender(v *bool) *PlayersCreate {
if v != nil {
_c.SetGender(*v)
}
return _c
}
// SetRating sets the "rating" field.
func (_c *PlayersCreate) SetRating(v decimal.Decimal) *PlayersCreate {
_c.mutation.SetRating(v)
@@ -189,6 +197,10 @@ func (_c *PlayersCreate) defaults() {
v := players.DefaultStatus
_c.mutation.SetStatus(v)
}
if _, ok := _c.mutation.Gender(); !ok {
v := players.DefaultGender
_c.mutation.SetGender(v)
}
if _, ok := _c.mutation.Rating(); !ok {
v := players.DefaultRating
_c.mutation.SetRating(v)
@@ -282,7 +294,7 @@ func (_c *PlayersCreate) createSpec() (*Players, *sqlgraph.CreateSpec) {
_node.Status = value
}
if value, ok := _c.mutation.Gender(); ok {
_spec.SetField(players.FieldGender, field.TypeInt, value)
_spec.SetField(players.FieldGender, field.TypeBool, value)
_node.Gender = value
}
if value, ok := _c.mutation.Rating(); ok {
@@ -67,26 +67,19 @@ func (_u *PlayersUpdate) SetNillableStatus(v *string) *PlayersUpdate {
}
// SetGender sets the "gender" field.
func (_u *PlayersUpdate) SetGender(v int) *PlayersUpdate {
_u.mutation.ResetGender()
func (_u *PlayersUpdate) SetGender(v bool) *PlayersUpdate {
_u.mutation.SetGender(v)
return _u
}
// SetNillableGender sets the "gender" field if the given value is not nil.
func (_u *PlayersUpdate) SetNillableGender(v *int) *PlayersUpdate {
func (_u *PlayersUpdate) SetNillableGender(v *bool) *PlayersUpdate {
if v != nil {
_u.SetGender(*v)
}
return _u
}
// AddGender adds value to the "gender" field.
func (_u *PlayersUpdate) AddGender(v int) *PlayersUpdate {
_u.mutation.AddGender(v)
return _u
}
// SetRating sets the "rating" field.
func (_u *PlayersUpdate) SetRating(v decimal.Decimal) *PlayersUpdate {
_u.mutation.SetRating(v)
@@ -297,10 +290,7 @@ func (_u *PlayersUpdate) sqlSave(ctx context.Context) (_node int, err error) {
_spec.SetField(players.FieldStatus, field.TypeString, value)
}
if value, ok := _u.mutation.Gender(); ok {
_spec.SetField(players.FieldGender, field.TypeInt, value)
}
if value, ok := _u.mutation.AddedGender(); ok {
_spec.AddField(players.FieldGender, field.TypeInt, value)
_spec.SetField(players.FieldGender, field.TypeBool, value)
}
if value, ok := _u.mutation.Rating(); ok {
_spec.SetField(players.FieldRating, field.TypeOther, value)
@@ -411,26 +401,19 @@ func (_u *PlayersUpdateOne) SetNillableStatus(v *string) *PlayersUpdateOne {
}
// SetGender sets the "gender" field.
func (_u *PlayersUpdateOne) SetGender(v int) *PlayersUpdateOne {
_u.mutation.ResetGender()
func (_u *PlayersUpdateOne) SetGender(v bool) *PlayersUpdateOne {
_u.mutation.SetGender(v)
return _u
}
// SetNillableGender sets the "gender" field if the given value is not nil.
func (_u *PlayersUpdateOne) SetNillableGender(v *int) *PlayersUpdateOne {
func (_u *PlayersUpdateOne) SetNillableGender(v *bool) *PlayersUpdateOne {
if v != nil {
_u.SetGender(*v)
}
return _u
}
// AddGender adds value to the "gender" field.
func (_u *PlayersUpdateOne) AddGender(v int) *PlayersUpdateOne {
_u.mutation.AddGender(v)
return _u
}
// SetRating sets the "rating" field.
func (_u *PlayersUpdateOne) SetRating(v decimal.Decimal) *PlayersUpdateOne {
_u.mutation.SetRating(v)
@@ -671,10 +654,7 @@ func (_u *PlayersUpdateOne) sqlSave(ctx context.Context) (_node *Players, err er
_spec.SetField(players.FieldStatus, field.TypeString, value)
}
if value, ok := _u.mutation.Gender(); ok {
_spec.SetField(players.FieldGender, field.TypeInt, value)
}
if value, ok := _u.mutation.AddedGender(); ok {
_spec.AddField(players.FieldGender, field.TypeInt, value)
_spec.SetField(players.FieldGender, field.TypeBool, value)
}
if value, ok := _u.mutation.Rating(); ok {
_spec.SetField(players.FieldRating, field.TypeOther, value)
@@ -60,6 +60,10 @@ func init() {
players.DefaultStatus = playersDescStatus.Default.(string)
// players.StatusValidator is a validator for the "status" field. It is called by the builders before save.
players.StatusValidator = playersDescStatus.Validators[0].(func(string) error)
// playersDescGender is the schema descriptor for gender field.
playersDescGender := playersFields[3].Descriptor()
// players.DefaultGender holds the default value on creation for the gender field.
players.DefaultGender = playersDescGender.Default.(bool)
// playersDescRating is the schema descriptor for rating field.
playersDescRating := playersFields[4].Descriptor()
// players.DefaultRating holds the default value on creation for the rating field.
@@ -1,6 +1,7 @@
package schema
import (
"juwan-backend/pkg/types"
"time"
"entgo.io/ent"
@@ -23,7 +24,7 @@ func (Players) Fields() []ent.Field {
field.Int64("id").Immutable().Unique(),
field.Int64("user_id").Unique(),
field.String("status").MaxLen(20).Default("offline"),
field.Int("gender").Unique(),
field.Bool("gender").Default(true),
field.Other("rating", decimal.Decimal{}).
Optional().
Default(playerDefaultRating).
@@ -33,7 +34,9 @@ func (Players) Fields() []ent.Field {
field.Int("total_orders").Optional().Default(0),
field.Int("completed_orders").Optional().Default(0),
field.Int64("shop_id").Optional().Nillable(),
field.Strings("tags").Optional().Default([]string{}),
field.Other("tags", types.TextArray{}).SchemaType(map[string]string{
dialect.Postgres: "text[]",
}).Optional(),
field.Other("games", pq.Int64Array{}).
Optional().
Default(pq.Int64Array{}).
@@ -1,6 +1,7 @@
package schema
import (
"juwan-backend/pkg/types"
"time"
"entgo.io/ent"
@@ -47,7 +48,9 @@ func (PlayerServices) Fields() []ent.Field {
}),
field.String("unit").MaxLen(20),
field.String("rank_range").MaxLen(100).Optional().Nillable(),
field.Strings("availability").Optional().Default([]string{}),
field.Other("availability", types.TextArray{}).SchemaType(map[string]string{
dialect.Postgres: "text[]",
}).Optional().Nillable(),
field.Other("rating", decimal.Decimal{}).
Default(decFive).
SchemaType(map[string]string{
@@ -1,6 +1,7 @@
package svc
import (
stdsql "database/sql"
"juwan-backend/app/player/rpc/internal/config"
"juwan-backend/app/player/rpc/internal/models"
"juwan-backend/app/snowflake/rpc/snowflake"
@@ -10,6 +11,7 @@ import (
"time"
"ariga.io/entcache"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"github.com/zeromicro/go-zero/core/logx"
@@ -24,14 +26,16 @@ type ServiceContext struct {
}
func NewServiceContext(c config.Config) *ServiceContext {
RWConn, err := sql.Open("pgx", c.DB.Master)
rawRW, err := stdsql.Open("pgx", c.DB.Master)
if err != nil {
panic(err)
}
ROConn, err := sql.Open("pgx", c.DB.Slaves)
rawRO, err := stdsql.Open("pgx", c.DB.Slaves)
if err != nil {
panic(err)
}
RWConn := sql.OpenDB(dialect.Postgres, rawRW)
ROConn := sql.OpenDB(dialect.Postgres, rawRO)
redisCluster, err := redisx.ConnectMasterSlaveCluster(c.CacheConf, 5*time.Second)
if redisCluster == nil || err != nil {
+73 -57
View File
@@ -888,7 +888,7 @@ type Players struct {
Games []int64 `protobuf:"varint,9,rep,packed,name=games,proto3" json:"games,omitempty"` //games
CreatedAt int64 `protobuf:"varint,10,opt,name=createdAt,proto3" json:"createdAt,omitempty"` //createdAt
UpdatedAt int64 `protobuf:"varint,11,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` //updatedAt
Gender int64 `protobuf:"varint,12,opt,name=gender,proto3" json:"gender,omitempty"` //gender
Gender bool `protobuf:"varint,12,opt,name=gender,proto3" json:"gender,omitempty"` //gender
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -1000,11 +1000,11 @@ func (x *Players) GetUpdatedAt() int64 {
return 0
}
func (x *Players) GetGender() int64 {
func (x *Players) GetGender() bool {
if x != nil {
return x.Gender
}
return 0
return false
}
type AddPlayersReq struct {
@@ -1505,20 +1505,20 @@ func (x *GetPlayersByIdResp) GetPlayers() *Players {
type SearchPlayersReq struct {
state protoimpl.MessageState `protogen:"open.v1"`
Page int64 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` //page
Limit int64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` //limit
Id int64 `protobuf:"varint,3,opt,name=id,proto3" json:"id,omitempty"` //id
UserId int64 `protobuf:"varint,4,opt,name=userId,proto3" json:"userId,omitempty"` //userId
Status string `protobuf:"bytes,5,opt,name=status,proto3" json:"status,omitempty"` //status
Rating float64 `protobuf:"fixed64,6,opt,name=rating,proto3" json:"rating,omitempty"` //rating
TotalOrders int64 `protobuf:"varint,7,opt,name=totalOrders,proto3" json:"totalOrders,omitempty"` //totalOrders
CompletedOrders int64 `protobuf:"varint,8,opt,name=completedOrders,proto3" json:"completedOrders,omitempty"` //completedOrders
ShopId int64 `protobuf:"varint,9,opt,name=shopId,proto3" json:"shopId,omitempty"` //shopId
Tags []string `protobuf:"bytes,10,rep,name=tags,proto3" json:"tags,omitempty"` //tags
Games []int64 `protobuf:"varint,11,rep,packed,name=games,proto3" json:"games,omitempty"` //games
CreatedAt int64 `protobuf:"varint,12,opt,name=createdAt,proto3" json:"createdAt,omitempty"` //createdAt
UpdatedAt int64 `protobuf:"varint,13,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` //updatedAt
Gender int64 `protobuf:"varint,14,opt,name=gender,proto3" json:"gender,omitempty"` //gender
Page *int64 `protobuf:"varint,1,opt,name=page,proto3,oneof" json:"page,omitempty"` //page
Limit *int64 `protobuf:"varint,2,opt,name=limit,proto3,oneof" json:"limit,omitempty"` //limit
Id *int64 `protobuf:"varint,3,opt,name=id,proto3,oneof" json:"id,omitempty"` //id
UserId *int64 `protobuf:"varint,4,opt,name=userId,proto3,oneof" json:"userId,omitempty"` //userId
Status *string `protobuf:"bytes,5,opt,name=status,proto3,oneof" json:"status,omitempty"` //status
Rating *float64 `protobuf:"fixed64,6,opt,name=rating,proto3,oneof" json:"rating,omitempty"` //rating
TotalOrders *int64 `protobuf:"varint,7,opt,name=totalOrders,proto3,oneof" json:"totalOrders,omitempty"` //totalOrders
CompletedOrders *int64 `protobuf:"varint,8,opt,name=completedOrders,proto3,oneof" json:"completedOrders,omitempty"` //completedOrders
ShopId *int64 `protobuf:"varint,9,opt,name=shopId,proto3,oneof" json:"shopId,omitempty"` //shopId
Tags []string `protobuf:"bytes,10,rep,name=tags,proto3" json:"tags,omitempty"` //tags
Games []int64 `protobuf:"varint,11,rep,packed,name=games,proto3" json:"games,omitempty"` //games
CreatedAt *int64 `protobuf:"varint,12,opt,name=createdAt,proto3,oneof" json:"createdAt,omitempty"` //createdAt
UpdatedAt *int64 `protobuf:"varint,13,opt,name=updatedAt,proto3,oneof" json:"updatedAt,omitempty"` //updatedAt
Gender *int64 `protobuf:"varint,14,opt,name=gender,proto3,oneof" json:"gender,omitempty"` //gender
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -1554,64 +1554,64 @@ func (*SearchPlayersReq) Descriptor() ([]byte, []int) {
}
func (x *SearchPlayersReq) GetPage() int64 {
if x != nil {
return x.Page
if x != nil && x.Page != nil {
return *x.Page
}
return 0
}
func (x *SearchPlayersReq) GetLimit() int64 {
if x != nil {
return x.Limit
if x != nil && x.Limit != nil {
return *x.Limit
}
return 0
}
func (x *SearchPlayersReq) GetId() int64 {
if x != nil {
return x.Id
if x != nil && x.Id != nil {
return *x.Id
}
return 0
}
func (x *SearchPlayersReq) GetUserId() int64 {
if x != nil {
return x.UserId
if x != nil && x.UserId != nil {
return *x.UserId
}
return 0
}
func (x *SearchPlayersReq) GetStatus() string {
if x != nil {
return x.Status
if x != nil && x.Status != nil {
return *x.Status
}
return ""
}
func (x *SearchPlayersReq) GetRating() float64 {
if x != nil {
return x.Rating
if x != nil && x.Rating != nil {
return *x.Rating
}
return 0
}
func (x *SearchPlayersReq) GetTotalOrders() int64 {
if x != nil {
return x.TotalOrders
if x != nil && x.TotalOrders != nil {
return *x.TotalOrders
}
return 0
}
func (x *SearchPlayersReq) GetCompletedOrders() int64 {
if x != nil {
return x.CompletedOrders
if x != nil && x.CompletedOrders != nil {
return *x.CompletedOrders
}
return 0
}
func (x *SearchPlayersReq) GetShopId() int64 {
if x != nil {
return x.ShopId
if x != nil && x.ShopId != nil {
return *x.ShopId
}
return 0
}
@@ -1631,22 +1631,22 @@ func (x *SearchPlayersReq) GetGames() []int64 {
}
func (x *SearchPlayersReq) GetCreatedAt() int64 {
if x != nil {
return x.CreatedAt
if x != nil && x.CreatedAt != nil {
return *x.CreatedAt
}
return 0
}
func (x *SearchPlayersReq) GetUpdatedAt() int64 {
if x != nil {
return x.UpdatedAt
if x != nil && x.UpdatedAt != nil {
return *x.UpdatedAt
}
return 0
}
func (x *SearchPlayersReq) GetGender() int64 {
if x != nil {
return x.Gender
if x != nil && x.Gender != nil {
return *x.Gender
}
return 0
}
@@ -1800,7 +1800,7 @@ const file_player_proto_rawDesc = "" +
"\tcreatedAt\x18\n" +
" \x01(\x03R\tcreatedAt\x12\x1c\n" +
"\tupdatedAt\x18\v \x01(\x03R\tupdatedAt\x12\x16\n" +
"\x06gender\x18\f \x01(\x03R\x06gender\"\xb9\x02\n" +
"\x06gender\x18\f \x01(\bR\x06gender\"\xb9\x02\n" +
"\rAddPlayersReq\x12\x16\n" +
"\x06userId\x18\x01 \x01(\x03R\x06userId\x12\x16\n" +
"\x06status\x18\x02 \x01(\tR\x06status\x12\x16\n" +
@@ -1847,23 +1847,38 @@ const file_player_proto_rawDesc = "" +
"\x11GetPlayersByIdReq\x12\x0e\n" +
"\x02id\x18\x01 \x01(\x03R\x02id\";\n" +
"\x12GetPlayersByIdResp\x12%\n" +
"\aplayers\x18\x01 \x01(\v2\v.pb.PlayersR\aplayers\"\xf6\x02\n" +
"\x10SearchPlayersReq\x12\x12\n" +
"\x04page\x18\x01 \x01(\x03R\x04page\x12\x14\n" +
"\x05limit\x18\x02 \x01(\x03R\x05limit\x12\x0e\n" +
"\x02id\x18\x03 \x01(\x03R\x02id\x12\x16\n" +
"\x06userId\x18\x04 \x01(\x03R\x06userId\x12\x16\n" +
"\x06status\x18\x05 \x01(\tR\x06status\x12\x16\n" +
"\x06rating\x18\x06 \x01(\x01R\x06rating\x12 \n" +
"\vtotalOrders\x18\a \x01(\x03R\vtotalOrders\x12(\n" +
"\x0fcompletedOrders\x18\b \x01(\x03R\x0fcompletedOrders\x12\x16\n" +
"\x06shopId\x18\t \x01(\x03R\x06shopId\x12\x12\n" +
"\aplayers\x18\x01 \x01(\v2\v.pb.PlayersR\aplayers\"\xc3\x04\n" +
"\x10SearchPlayersReq\x12\x17\n" +
"\x04page\x18\x01 \x01(\x03H\x00R\x04page\x88\x01\x01\x12\x19\n" +
"\x05limit\x18\x02 \x01(\x03H\x01R\x05limit\x88\x01\x01\x12\x13\n" +
"\x02id\x18\x03 \x01(\x03H\x02R\x02id\x88\x01\x01\x12\x1b\n" +
"\x06userId\x18\x04 \x01(\x03H\x03R\x06userId\x88\x01\x01\x12\x1b\n" +
"\x06status\x18\x05 \x01(\tH\x04R\x06status\x88\x01\x01\x12\x1b\n" +
"\x06rating\x18\x06 \x01(\x01H\x05R\x06rating\x88\x01\x01\x12%\n" +
"\vtotalOrders\x18\a \x01(\x03H\x06R\vtotalOrders\x88\x01\x01\x12-\n" +
"\x0fcompletedOrders\x18\b \x01(\x03H\aR\x0fcompletedOrders\x88\x01\x01\x12\x1b\n" +
"\x06shopId\x18\t \x01(\x03H\bR\x06shopId\x88\x01\x01\x12\x12\n" +
"\x04tags\x18\n" +
" \x03(\tR\x04tags\x12\x14\n" +
"\x05games\x18\v \x03(\x03R\x05games\x12\x1c\n" +
"\tcreatedAt\x18\f \x01(\x03R\tcreatedAt\x12\x1c\n" +
"\tupdatedAt\x18\r \x01(\x03R\tupdatedAt\x12\x16\n" +
"\x06gender\x18\x0e \x01(\x03R\x06gender\":\n" +
"\x05games\x18\v \x03(\x03R\x05games\x12!\n" +
"\tcreatedAt\x18\f \x01(\x03H\tR\tcreatedAt\x88\x01\x01\x12!\n" +
"\tupdatedAt\x18\r \x01(\x03H\n" +
"R\tupdatedAt\x88\x01\x01\x12\x1b\n" +
"\x06gender\x18\x0e \x01(\x03H\vR\x06gender\x88\x01\x01B\a\n" +
"\x05_pageB\b\n" +
"\x06_limitB\x05\n" +
"\x03_idB\t\n" +
"\a_userIdB\t\n" +
"\a_statusB\t\n" +
"\a_ratingB\x0e\n" +
"\f_totalOrdersB\x12\n" +
"\x10_completedOrdersB\t\n" +
"\a_shopIdB\f\n" +
"\n" +
"_createdAtB\f\n" +
"\n" +
"_updatedAtB\t\n" +
"\a_gender\":\n" +
"\x11SearchPlayersResp\x12%\n" +
"\aplayers\x18\x01 \x03(\v2\v.pb.PlayersR\aplayers2\xc6\x05\n" +
"\rplayerService\x12H\n" +
@@ -1956,6 +1971,7 @@ func file_player_proto_init() {
}
file_player_proto_msgTypes[3].OneofWrappers = []any{}
file_player_proto_msgTypes[14].OneofWrappers = []any{}
file_player_proto_msgTypes[20].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
+8 -2
View File
@@ -9,6 +9,12 @@ Prometheus:
# k8s://juwan/<service name>:8080
ShopRpcConf:
Target: k8s://juwan/shop-rpc-svc.juwan:8080
# ===== PROC CONFIG =====
#ShopRpcConf:
# Target: k8s://juwan/shop-rpc-svc.juwan:8080
# ===== DEV CONFIG ====
ShopRpcConf:
Endpoints:
- shop-rpc:8080
@@ -4,17 +4,12 @@
package shop
import (
"errors"
"juwan-backend/common/utils/contextj"
"juwan-backend/common/utils/httpj"
"juwan-backend/common/utils/responses"
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/shop/api/internal/logic/shop"
"juwan-backend/app/shop/api/internal/svc"
"juwan-backend/app/shop/api/internal/types"
"github.com/zeromicro/go-zero/rest/httpx"
)
// 接受邀请
@@ -26,12 +21,7 @@ func AcceptInvitationHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return
}
userId, err := httpj.GetUserIdFromHeader(r.Header)
if err != nil {
httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated")))
}
ctx := contextj.WithUserID(r.Context(), userId)
l := shop.NewAcceptInvitationLogic(ctx, svcCtx)
l := shop.NewAcceptInvitationLogic(r.Context(), svcCtx)
resp, err := l.AcceptInvitation(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
@@ -4,17 +4,12 @@
package shop
import (
"errors"
"juwan-backend/common/utils/contextj"
"juwan-backend/common/utils/httpj"
"juwan-backend/common/utils/responses"
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/shop/api/internal/logic/shop"
"juwan-backend/app/shop/api/internal/svc"
"juwan-backend/app/shop/api/internal/types"
"github.com/zeromicro/go-zero/rest/httpx"
)
// 新增店铺公告
@@ -26,12 +21,7 @@ func AddAnnouncementHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return
}
userId, err := httpj.GetUserIdFromHeader(r.Header)
if err != nil {
httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated")))
}
ctx := contextj.WithUserID(r.Context(), userId)
l := shop.NewAddAnnouncementLogic(ctx, svcCtx)
l := shop.NewAddAnnouncementLogic(r.Context(), svcCtx)
resp, err := l.AddAnnouncement(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
@@ -4,17 +4,12 @@
package shop
import (
"errors"
"juwan-backend/common/utils/contextj"
"juwan-backend/common/utils/httpj"
"juwan-backend/common/utils/responses"
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/shop/api/internal/logic/shop"
"juwan-backend/app/shop/api/internal/svc"
"juwan-backend/app/shop/api/internal/types"
"github.com/zeromicro/go-zero/rest/httpx"
)
// 创建店铺
@@ -26,12 +21,7 @@ func CreateShopHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return
}
userId, err := httpj.GetUserIdFromHeader(r.Header)
if err != nil {
httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated")))
}
ctx := contextj.WithUserID(r.Context(), userId)
l := shop.NewCreateShopLogic(ctx, svcCtx)
l := shop.NewCreateShopLogic(r.Context(), svcCtx)
resp, err := l.CreateShop(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
@@ -4,17 +4,12 @@
package shop
import (
"errors"
"juwan-backend/common/utils/contextj"
"juwan-backend/common/utils/httpj"
"juwan-backend/common/utils/responses"
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/shop/api/internal/logic/shop"
"juwan-backend/app/shop/api/internal/svc"
"juwan-backend/app/shop/api/internal/types"
"github.com/zeromicro/go-zero/rest/httpx"
)
// 删除店铺公告
@@ -26,12 +21,7 @@ func DeleteAnnouncementHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return
}
userId, err := httpj.GetUserIdFromHeader(r.Header)
if err != nil {
httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated")))
}
ctx := contextj.WithUserID(r.Context(), userId)
l := shop.NewDeleteAnnouncementLogic(ctx, svcCtx)
l := shop.NewDeleteAnnouncementLogic(r.Context(), svcCtx)
resp, err := l.DeleteAnnouncement(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
@@ -4,17 +4,12 @@
package shop
import (
"errors"
"juwan-backend/common/utils/contextj"
"juwan-backend/common/utils/httpj"
"juwan-backend/common/utils/responses"
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/shop/api/internal/logic/shop"
"juwan-backend/app/shop/api/internal/svc"
"juwan-backend/app/shop/api/internal/types"
"github.com/zeromicro/go-zero/rest/httpx"
)
// 获取当前用户的店铺
@@ -26,12 +21,7 @@ func GetMyShopHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return
}
userId, err := httpj.GetUserIdFromHeader(r.Header)
if err != nil {
httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated")))
}
ctx := contextj.WithUserID(r.Context(), userId)
l := shop.NewGetMyShopLogic(ctx, svcCtx)
l := shop.NewGetMyShopLogic(r.Context(), svcCtx)
resp, err := l.GetMyShop(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
@@ -6,11 +6,10 @@ package shop
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/shop/api/internal/logic/shop"
"juwan-backend/app/shop/api/internal/svc"
"juwan-backend/app/shop/api/internal/types"
"github.com/zeromicro/go-zero/rest/httpx"
)
// 获取店铺详情
@@ -4,17 +4,12 @@
package shop
import (
"errors"
"juwan-backend/common/utils/contextj"
"juwan-backend/common/utils/httpj"
"juwan-backend/common/utils/responses"
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/shop/api/internal/logic/shop"
"juwan-backend/app/shop/api/internal/svc"
"juwan-backend/app/shop/api/internal/types"
"github.com/zeromicro/go-zero/rest/httpx"
)
// 获取收入统计
@@ -26,12 +21,7 @@ func GetShopIncomeStatsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return
}
userId, err := httpj.GetUserIdFromHeader(r.Header)
if err != nil {
httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated")))
}
ctx := contextj.WithUserID(r.Context(), userId)
l := shop.NewGetShopIncomeStatsLogic(ctx, svcCtx)
l := shop.NewGetShopIncomeStatsLogic(r.Context(), svcCtx)
resp, err := l.GetShopIncomeStats(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
@@ -6,11 +6,10 @@ package shop
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/shop/api/internal/logic/shop"
"juwan-backend/app/shop/api/internal/svc"
"juwan-backend/app/shop/api/internal/types"
"github.com/zeromicro/go-zero/rest/httpx"
)
// 获取店长的店铺
@@ -4,17 +4,12 @@
package shop
import (
"errors"
"juwan-backend/common/utils/contextj"
"juwan-backend/common/utils/httpj"
"juwan-backend/common/utils/responses"
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/shop/api/internal/logic/shop"
"juwan-backend/app/shop/api/internal/svc"
"juwan-backend/app/shop/api/internal/types"
"github.com/zeromicro/go-zero/rest/httpx"
)
// 邀请打手
@@ -26,12 +21,7 @@ func InvitePlayerHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return
}
userId, err := httpj.GetUserIdFromHeader(r.Header)
if err != nil {
httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated")))
}
ctx := contextj.WithUserID(r.Context(), userId)
l := shop.NewInvitePlayerLogic(ctx, svcCtx)
l := shop.NewInvitePlayerLogic(r.Context(), svcCtx)
resp, err := l.InvitePlayer(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
@@ -4,17 +4,12 @@
package shop
import (
"errors"
"juwan-backend/common/utils/contextj"
"juwan-backend/common/utils/httpj"
"juwan-backend/common/utils/responses"
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/shop/api/internal/logic/shop"
"juwan-backend/app/shop/api/internal/svc"
"juwan-backend/app/shop/api/internal/types"
"github.com/zeromicro/go-zero/rest/httpx"
)
// 拒绝邀请
@@ -26,12 +21,7 @@ func RejectInvitationHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return
}
userId, err := httpj.GetUserIdFromHeader(r.Header)
if err != nil {
httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated")))
}
ctx := contextj.WithUserID(r.Context(), userId)
l := shop.NewRejectInvitationLogic(ctx, svcCtx)
l := shop.NewRejectInvitationLogic(r.Context(), svcCtx)
resp, err := l.RejectInvitation(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
@@ -4,17 +4,12 @@
package shop
import (
"errors"
"juwan-backend/common/utils/contextj"
"juwan-backend/common/utils/httpj"
"juwan-backend/common/utils/responses"
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/shop/api/internal/logic/shop"
"juwan-backend/app/shop/api/internal/svc"
"juwan-backend/app/shop/api/internal/types"
"github.com/zeromicro/go-zero/rest/httpx"
)
// 移除打手
@@ -26,12 +21,7 @@ func RemovePlayerHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return
}
userId, err := httpj.GetUserIdFromHeader(r.Header)
if err != nil {
httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated")))
}
ctx := contextj.WithUserID(r.Context(), userId)
l := shop.NewRemovePlayerLogic(ctx, svcCtx)
l := shop.NewRemovePlayerLogic(r.Context(), svcCtx)
resp, err := l.RemovePlayer(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
@@ -4,10 +4,6 @@
package shop
import (
"errors"
"juwan-backend/common/utils/contextj"
"juwan-backend/common/utils/httpj"
"juwan-backend/common/utils/responses"
"net/http"
"juwan-backend/app/shop/api/internal/logic/shop"
@@ -26,12 +22,7 @@ func UpdateShopHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return
}
userId, err := httpj.GetUserIdFromHeader(r.Header)
if err != nil {
httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated")))
}
ctx := contextj.WithUserID(r.Context(), userId)
l := shop.NewUpdateShopLogic(ctx, svcCtx)
l := shop.NewUpdateShopLogic(r.Context(), svcCtx)
resp, err := l.UpdateShop(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
@@ -4,17 +4,12 @@
package shop
import (
"errors"
"juwan-backend/common/utils/contextj"
"juwan-backend/common/utils/httpj"
"juwan-backend/common/utils/responses"
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/shop/api/internal/logic/shop"
"juwan-backend/app/shop/api/internal/svc"
"juwan-backend/app/shop/api/internal/types"
"github.com/zeromicro/go-zero/rest/httpx"
)
// 更新店铺模板
@@ -26,12 +21,7 @@ func UpdateShopTemplateHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return
}
userId, err := httpj.GetUserIdFromHeader(r.Header)
if err != nil {
httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated")))
}
ctx := contextj.WithUserID(r.Context(), userId)
l := shop.NewUpdateShopTemplateLogic(ctx, svcCtx)
l := shop.NewUpdateShopTemplateLogic(r.Context(), svcCtx)
resp, err := l.UpdateShopTemplate(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
@@ -36,6 +36,9 @@ func (l *CreateShopLogic) CreateShop(req *types.CreateShopReq) (resp *types.Shop
if err != nil {
return nil, err
}
if ownerID == 0 {
return nil, errors.New("user not authenticated")
}
if req.Name == "" {
return nil, errors.New("name is required")
@@ -46,6 +46,7 @@ func (l *UpdateShopLogic) UpdateShop(req *types.UpdateShopReq) (resp *types.Shop
if current.Shops.OwnerId != userID {
return nil, contextj.ERRILLEGALUSER
}
logx.Debugf("update shop %+v", req)
name := current.Shops.Name
if req.Name != "" {
+8 -4
View File
@@ -6,18 +6,22 @@ package svc
import (
"juwan-backend/app/shop/api/internal/config"
"juwan-backend/app/shop/rpc/shopservice"
"juwan-backend/common/middlewares"
"github.com/zeromicro/go-zero/rest"
"github.com/zeromicro/go-zero/zrpc"
)
type ServiceContext struct {
Config config.Config
ShopRpc shopservice.ShopService
Config config.Config
ShopRpc shopservice.ShopService
HeaderExtractorMiddleware rest.Middleware
}
func NewServiceContext(c config.Config) *ServiceContext {
return &ServiceContext{
Config: c,
ShopRpc: shopservice.NewShopService(zrpc.MustNewClient(c.ShopRpcConf)),
Config: c,
ShopRpc: shopservice.NewShopService(zrpc.MustNewClient(c.ShopRpcConf)),
HeaderExtractorMiddleware: middlewares.NewHeaderExtractorMiddleware().Handle,
}
}
+3
View File
@@ -6,6 +6,7 @@ package main
import (
"flag"
"fmt"
"juwan-backend/common/middlewares"
"juwan-backend/app/shop/api/internal/config"
"juwan-backend/app/shop/api/internal/handler"
@@ -24,6 +25,8 @@ func main() {
conf.MustLoad(*configFile, &c)
server := rest.MustNewServer(c.RestConf)
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
server.Use(middlewares.NewRequestMiddleware().Handle)
defer server.Stop()
ctx := svc.NewServiceContext(c)
+36 -14
View File
@@ -1,7 +1,6 @@
Name: pb.rpc
ListenOn: 0.0.0.0:8080
Prometheus:
Host: 0.0.0.0
Port: 4001
@@ -12,26 +11,49 @@ Prometheus:
# - 127.0.0.1:2379
# Key: pb.rpc
# Target: k8s://juwan/<service name>.<namespace>:8080
# ===== PROC Config =====
#SnowflakeRpcConf:
# Target: k8s://juwan/snowflake-svc:8080
#UsersRpcConf:
# Target: k8s://juwan/user-rpc-svc:8080
#DB:
# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@{DB_HOST_RW}.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
# Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@{BD_HOST_RO}.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
#
#
#CacheConf:
# - Host: "${REDIS_M_HOST}"
# Type: node
# Pass: "${REDIS_PASSWORD}"
# User: "default"
# - Host: "${REDIS_S_HOST}"
# Type: node
# Pass: "${REDIS_PASSWORD}"
# User: "default"
# ===== DEV Config =====
SnowflakeRpcConf:
Target: k8s://juwan/snowflake-svc:8080
Endpoints:
- snowflake:8080
-
UsersRpcConf:
Endpoints:
- user-rpc:8080
DB:
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
CacheConf:
- Host: "${REDIS_M_HOST}"
- Host: "${REDIS_HOST}:${REDIS_PORT}"
Type: node
Pass: "${REDIS_PASSWORD}"
User: "default"
- Host: "${REDIS_S_HOST}"
Type: node
Pass: "${REDIS_PASSWORD}"
User: "default"
Log:
Level: info
# Target: k8s://juwan/<service name>.<namespace>:8080
#DB:
# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
# Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
+1
View File
@@ -8,6 +8,7 @@ import (
type Config struct {
zrpc.RpcServerConf
SnowflakeRpcConf zrpc.RpcClientConf
UsersRpcConf zrpc.RpcClientConf
DB struct {
Master string
Slaves string
+52 -5
View File
@@ -4,7 +4,11 @@ import (
"context"
"encoding/json"
"errors"
"juwan-backend/app/shop/rpc/internal/models/schema"
"juwan-backend/app/snowflake/rpc/snowflake"
pb2 "juwan-backend/app/users/rpc/pb"
"slices"
"strings"
"juwan-backend/app/shop/rpc/internal/svc"
"juwan-backend/app/shop/rpc/pb"
@@ -27,8 +31,25 @@ func NewAddShopsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddShops
}
}
var allowedRoles = []string{"owner", "admin"}
var allowedCommissionTypes = []string{"fixed", "percentage"}
var allowedDispatchModes = []string{"manual", "auto"}
// -----------------------shops-----------------------
func (l *AddShopsLogic) AddShops(in *pb.AddShopsReq) (*pb.AddShopsResp, error) {
user, err := l.svcCtx.UsersRpc.GetUsersById(l.ctx, &pb2.GetUsersByIdReq{
Id: in.OwnerId,
})
if err != nil {
logx.Errorf("add shops err: %v", err)
return nil, errors.New("user not found")
}
if !slices.Contains(allowedRoles, user.Users.CurrentRole) {
logx.Errorf("add shops err: user %v has no permission to add shop", in.OwnerId)
return nil, errors.New("no permission to add shop")
}
idResp, err := l.svcCtx.Snowflake.NextId(l.ctx, &snowflake.NextIdReq{})
if err != nil {
logx.Errorf("addPlayerServices err:%v", err)
@@ -44,28 +65,53 @@ func (l *AddShopsLogic) AddShops(in *pb.AddShopsReq) (*pb.AddShopsResp, error) {
rating, err := decimal.NewFromString(in.Rating)
if err != nil {
logx.Errorf("addPlayerServices new from string err:%v", err)
return nil, errors.New("invalid rating")
}
commissionValue, err := decimal.NewFromString(in.CommissionValue)
if err != nil {
logx.Errorf("addPlayerServices new from string err:%v", err)
return nil, errors.New("invalid commissionValue")
}
_, err = l.svcCtx.ShopModelRO.Shops.Create().
commissionType := strings.ToLower(strings.TrimSpace(in.CommissionType))
if commissionType == "" {
commissionType = "percentage"
}
if !slices.Contains(allowedCommissionTypes, commissionType) {
logx.Errorf("addPlayerServices contains err: invalid commissionType %v", in.CommissionType)
return nil, errors.New("invalid commissionType")
}
dispatchMode := strings.ToLower(strings.TrimSpace(in.DispatchMode))
if dispatchMode == "" {
dispatchMode = "manual"
}
if !slices.Contains(allowedDispatchModes, dispatchMode) {
logx.Errorf("addPlayerServices contains err: invalid dispatchMode %v", in.DispatchMode)
return nil, errors.New("invalid dispatchMode")
}
announcements := schema.TextArray{Elements: in.Announcements, Valid: true}
if announcements.Elements == nil {
announcements.Elements = []string{}
}
_, err = l.svcCtx.ShopModelRW.Shops.Create().
SetID(idResp.Id).
SetOwnerID(in.OwnerId).
SetOwnerID(idResp.Id).
SetName(in.Name).
SetBanner(in.Banner).
SetDescription(in.Description).
SetRating(rating).
SetTotalOrders(int(in.TotalOrders)).
SetPlayerCount(int(in.PlayerCount)).
SetNillableCommissionType(&in.CommissionType).
SetCommissionType(commissionType).
SetCommissionValue(commissionValue).
SetAllowMultiShop(in.AllowMultiShop).
SetAllowIndependentOrders(in.AllowIndependentOrders).
SetDispatchMode(in.DispatchMode).
SetAnnouncements(in.Announcements).
SetDispatchMode(dispatchMode).
SetAnnouncements(announcements).
SetTemplateConfig(templateConfig).
Save(l.ctx)
@@ -73,5 +119,6 @@ func (l *AddShopsLogic) AddShops(in *pb.AddShopsReq) (*pb.AddShopsResp, error) {
logx.Errorf("addPlayerServices err:%v", err)
return nil, errors.New("add player service failed")
}
logx.Debugf("shop created with id: %v", idResp.Id)
return &pb.AddShopsResp{}, nil
}
@@ -51,7 +51,7 @@ func (l *GetShopsByIdLogic) GetShopsById(in *pb.GetShopsByIdReq) (*pb.GetShopsBy
AllowMultiShop: shop.AllowMultiShop,
AllowIndependentOrders: shop.AllowIndependentOrders,
DispatchMode: shop.DispatchMode,
Announcements: shop.Announcements,
Announcements: shop.Announcements.Elements,
TemplateConfig: string(templateConfigBytes),
CreatedAt: shop.CreatedAt.Unix(),
UpdatedAt: shop.UpdatedAt.Unix(),
@@ -124,7 +124,7 @@ func (l *SearchShopsLogic) SearchShops(in *pb.SearchShopsReq) (*pb.SearchShopsRe
AllowMultiShop: item.AllowMultiShop,
AllowIndependentOrders: item.AllowIndependentOrders,
DispatchMode: item.DispatchMode,
Announcements: item.Announcements,
Announcements: item.Announcements.Elements,
TemplateConfig: string(templateConfigBytes),
CreatedAt: item.CreatedAt.Unix(),
UpdatedAt: item.UpdatedAt.Unix(),
@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"errors"
"juwan-backend/app/shop/rpc/internal/models/schema"
"juwan-backend/app/shop/rpc/internal/models/shops"
"time"
@@ -75,7 +76,7 @@ func (l *UpdateShopsLogic) UpdateShops(in *pb.UpdateShopsReq) (*pb.UpdateShopsRe
SetAllowIndependentOrders(in.AllowIndependentOrders)
if len(in.Announcements) > 0 {
updater = updater.SetAnnouncements(in.Announcements)
updater = updater.SetAnnouncements(schema.TextArray{Elements: in.Announcements, Valid: true})
}
if in.TemplateConfig != "" {
@@ -94,7 +94,7 @@ var (
{Name: "allow_multi_shop", Type: field.TypeBool, Nullable: true, Default: false},
{Name: "allow_independent_orders", Type: field.TypeBool, Nullable: true, Default: true},
{Name: "dispatch_mode", Type: field.TypeString, Size: 20, Default: "manual"},
{Name: "announcements", Type: field.TypeJSON, Nullable: true},
{Name: "announcements", Type: field.TypeOther, Nullable: true, SchemaType: map[string]string{"postgres": "text[]"}},
{Name: "template_config", Type: field.TypeJSON, Nullable: true},
{Name: "created_at", Type: field.TypeTime},
{Name: "updated_at", Type: field.TypeTime},
+7 -23
View File
@@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"juwan-backend/app/shop/rpc/internal/models/predicate"
"juwan-backend/app/shop/rpc/internal/models/schema"
"juwan-backend/app/shop/rpc/internal/models/shopinvitations"
"juwan-backend/app/shop/rpc/internal/models/shopplayers"
"juwan-backend/app/shop/rpc/internal/models/shops"
@@ -1437,8 +1438,7 @@ type ShopsMutation struct {
allow_multi_shop *bool
allow_independent_orders *bool
dispatch_mode *string
announcements *[]string
appendannouncements []string
announcements *schema.TextArray
template_config *map[string]interface{}
created_at *time.Time
updated_at *time.Time
@@ -2138,13 +2138,12 @@ func (m *ShopsMutation) ResetDispatchMode() {
}
// SetAnnouncements sets the "announcements" field.
func (m *ShopsMutation) SetAnnouncements(s []string) {
m.announcements = &s
m.appendannouncements = nil
func (m *ShopsMutation) SetAnnouncements(sa schema.TextArray) {
m.announcements = &sa
}
// Announcements returns the value of the "announcements" field in the mutation.
func (m *ShopsMutation) Announcements() (r []string, exists bool) {
func (m *ShopsMutation) Announcements() (r schema.TextArray, exists bool) {
v := m.announcements
if v == nil {
return
@@ -2155,7 +2154,7 @@ func (m *ShopsMutation) Announcements() (r []string, exists bool) {
// OldAnnouncements returns the old "announcements" field's value of the Shops entity.
// If the Shops object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *ShopsMutation) OldAnnouncements(ctx context.Context) (v []string, err error) {
func (m *ShopsMutation) OldAnnouncements(ctx context.Context) (v schema.TextArray, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldAnnouncements is only allowed on UpdateOne operations")
}
@@ -2169,23 +2168,9 @@ func (m *ShopsMutation) OldAnnouncements(ctx context.Context) (v []string, err e
return oldValue.Announcements, nil
}
// AppendAnnouncements adds s to the "announcements" field.
func (m *ShopsMutation) AppendAnnouncements(s []string) {
m.appendannouncements = append(m.appendannouncements, s...)
}
// AppendedAnnouncements returns the list of values that were appended to the "announcements" field in this mutation.
func (m *ShopsMutation) AppendedAnnouncements() ([]string, bool) {
if len(m.appendannouncements) == 0 {
return nil, false
}
return m.appendannouncements, true
}
// ClearAnnouncements clears the value of the "announcements" field.
func (m *ShopsMutation) ClearAnnouncements() {
m.announcements = nil
m.appendannouncements = nil
m.clearedFields[shops.FieldAnnouncements] = struct{}{}
}
@@ -2198,7 +2183,6 @@ func (m *ShopsMutation) AnnouncementsCleared() bool {
// ResetAnnouncements resets all changes to the "announcements" field.
func (m *ShopsMutation) ResetAnnouncements() {
m.announcements = nil
m.appendannouncements = nil
delete(m.clearedFields, shops.FieldAnnouncements)
}
@@ -2581,7 +2565,7 @@ func (m *ShopsMutation) SetField(name string, value ent.Value) error {
m.SetDispatchMode(v)
return nil
case shops.FieldAnnouncements:
v, ok := value.([]string)
v, ok := value.(schema.TextArray)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
-4
View File
@@ -76,10 +76,6 @@ func init() {
shops.DefaultDispatchMode = shopsDescDispatchMode.Default.(string)
// shops.DispatchModeValidator is a validator for the "dispatch_mode" field. It is called by the builders before save.
shops.DispatchModeValidator = shopsDescDispatchMode.Validators[0].(func(string) error)
// shopsDescAnnouncements is the schema descriptor for announcements field.
shopsDescAnnouncements := shopsFields[13].Descriptor()
// shops.DefaultAnnouncements holds the default value on creation for the announcements field.
shops.DefaultAnnouncements = shopsDescAnnouncements.Default.([]string)
// shopsDescCreatedAt is the schema descriptor for created_at field.
shopsDescCreatedAt := shopsFields[15].Descriptor()
// shops.DefaultCreatedAt holds the default value on creation for the created_at field.
+48 -1
View File
@@ -1,6 +1,9 @@
package schema
import (
"database/sql/driver"
"errors"
"strings"
"time"
"entgo.io/ent"
@@ -8,11 +11,53 @@ import (
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema"
"entgo.io/ent/schema/field"
"github.com/jackc/pgx/v5/pgtype"
"github.com/shopspring/decimal"
)
var shopDefaultRating = decimal.RequireFromString("5.00")
type TextArray pgtype.Array[string]
func (s *TextArray) Scan(src any) error {
if src == nil {
s.Elements = []string{}
s.Dims = nil
s.Valid = true
return nil
}
var strSrc string
switch v := src.(type) {
case string:
strSrc = v
case []byte:
strSrc = string(v)
default:
return errors.New("failed to scan text array")
}
trimmed := strings.Trim(strSrc, "{}")
if len(trimmed) == 0 {
s.Elements = []string{}
s.Dims = nil
s.Valid = true
return nil
}
s.Elements = strings.Split(trimmed, ",")
s.Dims = nil
s.Valid = true
return nil
}
func (s TextArray) Value() (driver.Value, error) {
if s.Elements == nil {
return []string{}, nil
}
return s.Elements, nil
}
// Shops holds the schema definition for the Shops entity.
type Shops struct {
ent.Schema
@@ -56,7 +101,9 @@ func (Shops) Fields() []ent.Field {
field.Bool("allow_multi_shop").Optional().Default(false),
field.Bool("allow_independent_orders").Optional().Default(true),
field.String("dispatch_mode").MaxLen(20).Default("manual"),
field.Strings("announcements").Optional().Default([]string{}),
field.Other("announcements", TextArray{}).
SchemaType(map[string]string{dialect.Postgres: "text[]"}).
Optional(),
field.JSON("template_config", map[string]any{}).Optional(),
field.Time("created_at").Default(time.Now).Immutable(),
field.Time("updated_at").Default(time.Now).UpdateDefault(time.Now),
+8 -7
View File
@@ -5,6 +5,7 @@ package models
import (
"encoding/json"
"fmt"
"juwan-backend/app/shop/rpc/internal/models/schema"
"juwan-backend/app/shop/rpc/internal/models/shops"
"strings"
"time"
@@ -44,7 +45,7 @@ type Shops struct {
// DispatchMode holds the value of the "dispatch_mode" field.
DispatchMode string `json:"dispatch_mode,omitempty"`
// Announcements holds the value of the "announcements" field.
Announcements []string `json:"announcements,omitempty"`
Announcements schema.TextArray `json:"announcements,omitempty"`
// TemplateConfig holds the value of the "template_config" field.
TemplateConfig map[string]interface{} `json:"template_config,omitempty"`
// CreatedAt holds the value of the "created_at" field.
@@ -59,10 +60,12 @@ func (*Shops) scanValues(columns []string) ([]any, error) {
values := make([]any, len(columns))
for i := range columns {
switch columns[i] {
case shops.FieldAnnouncements, shops.FieldTemplateConfig:
case shops.FieldTemplateConfig:
values[i] = new([]byte)
case shops.FieldRating, shops.FieldCommissionValue:
values[i] = new(decimal.Decimal)
case shops.FieldAnnouncements:
values[i] = new(schema.TextArray)
case shops.FieldAllowMultiShop, shops.FieldAllowIndependentOrders:
values[i] = new(sql.NullBool)
case shops.FieldID, shops.FieldOwnerID, shops.FieldTotalOrders, shops.FieldPlayerCount:
@@ -167,12 +170,10 @@ func (_m *Shops) assignValues(columns []string, values []any) error {
_m.DispatchMode = value.String
}
case shops.FieldAnnouncements:
if value, ok := values[i].(*[]byte); !ok {
if value, ok := values[i].(*schema.TextArray); !ok {
return fmt.Errorf("unexpected type %T for field announcements", values[i])
} else if value != nil && len(*value) > 0 {
if err := json.Unmarshal(*value, &_m.Announcements); err != nil {
return fmt.Errorf("unmarshal field announcements: %w", err)
}
} else if value != nil {
_m.Announcements = *value
}
case shops.FieldTemplateConfig:
if value, ok := values[i].(*[]byte); !ok {
+5 -2
View File
@@ -102,8 +102,6 @@ var (
DefaultDispatchMode string
// DispatchModeValidator is a validator for the "dispatch_mode" field. It is called by the builders before save.
DispatchModeValidator func(string) error
// DefaultAnnouncements holds the default value on creation for the "announcements" field.
DefaultAnnouncements []string
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
DefaultCreatedAt func() time.Time
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
@@ -180,6 +178,11 @@ func ByDispatchMode(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldDispatchMode, opts...).ToFunc()
}
// ByAnnouncements orders the results by the announcements field.
func ByAnnouncements(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldAnnouncements, opts...).ToFunc()
}
// ByCreatedAt orders the results by the created_at field.
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
@@ -4,6 +4,7 @@ package shops
import (
"juwan-backend/app/shop/rpc/internal/models/predicate"
"juwan-backend/app/shop/rpc/internal/models/schema"
"time"
"entgo.io/ent/dialect/sql"
@@ -115,6 +116,11 @@ func DispatchMode(v string) predicate.Shops {
return predicate.Shops(sql.FieldEQ(FieldDispatchMode, v))
}
// Announcements applies equality check predicate on the "announcements" field. It's identical to AnnouncementsEQ.
func Announcements(v schema.TextArray) predicate.Shops {
return predicate.Shops(sql.FieldEQ(FieldAnnouncements, v))
}
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
func CreatedAt(v time.Time) predicate.Shops {
return predicate.Shops(sql.FieldEQ(FieldCreatedAt, v))
@@ -740,6 +746,46 @@ func DispatchModeContainsFold(v string) predicate.Shops {
return predicate.Shops(sql.FieldContainsFold(FieldDispatchMode, v))
}
// AnnouncementsEQ applies the EQ predicate on the "announcements" field.
func AnnouncementsEQ(v schema.TextArray) predicate.Shops {
return predicate.Shops(sql.FieldEQ(FieldAnnouncements, v))
}
// AnnouncementsNEQ applies the NEQ predicate on the "announcements" field.
func AnnouncementsNEQ(v schema.TextArray) predicate.Shops {
return predicate.Shops(sql.FieldNEQ(FieldAnnouncements, v))
}
// AnnouncementsIn applies the In predicate on the "announcements" field.
func AnnouncementsIn(vs ...schema.TextArray) predicate.Shops {
return predicate.Shops(sql.FieldIn(FieldAnnouncements, vs...))
}
// AnnouncementsNotIn applies the NotIn predicate on the "announcements" field.
func AnnouncementsNotIn(vs ...schema.TextArray) predicate.Shops {
return predicate.Shops(sql.FieldNotIn(FieldAnnouncements, vs...))
}
// AnnouncementsGT applies the GT predicate on the "announcements" field.
func AnnouncementsGT(v schema.TextArray) predicate.Shops {
return predicate.Shops(sql.FieldGT(FieldAnnouncements, v))
}
// AnnouncementsGTE applies the GTE predicate on the "announcements" field.
func AnnouncementsGTE(v schema.TextArray) predicate.Shops {
return predicate.Shops(sql.FieldGTE(FieldAnnouncements, v))
}
// AnnouncementsLT applies the LT predicate on the "announcements" field.
func AnnouncementsLT(v schema.TextArray) predicate.Shops {
return predicate.Shops(sql.FieldLT(FieldAnnouncements, v))
}
// AnnouncementsLTE applies the LTE predicate on the "announcements" field.
func AnnouncementsLTE(v schema.TextArray) predicate.Shops {
return predicate.Shops(sql.FieldLTE(FieldAnnouncements, v))
}
// AnnouncementsIsNil applies the IsNil predicate on the "announcements" field.
func AnnouncementsIsNil() predicate.Shops {
return predicate.Shops(sql.FieldIsNull(FieldAnnouncements))
+11 -6
View File
@@ -6,6 +6,7 @@ import (
"context"
"errors"
"fmt"
"juwan-backend/app/shop/rpc/internal/models/schema"
"juwan-backend/app/shop/rpc/internal/models/shops"
"time"
@@ -166,11 +167,19 @@ func (_c *ShopsCreate) SetNillableDispatchMode(v *string) *ShopsCreate {
}
// SetAnnouncements sets the "announcements" field.
func (_c *ShopsCreate) SetAnnouncements(v []string) *ShopsCreate {
func (_c *ShopsCreate) SetAnnouncements(v schema.TextArray) *ShopsCreate {
_c.mutation.SetAnnouncements(v)
return _c
}
// SetNillableAnnouncements sets the "announcements" field if the given value is not nil.
func (_c *ShopsCreate) SetNillableAnnouncements(v *schema.TextArray) *ShopsCreate {
if v != nil {
_c.SetAnnouncements(*v)
}
return _c
}
// SetTemplateConfig sets the "template_config" field.
func (_c *ShopsCreate) SetTemplateConfig(v map[string]interface{}) *ShopsCreate {
_c.mutation.SetTemplateConfig(v)
@@ -274,10 +283,6 @@ func (_c *ShopsCreate) defaults() {
v := shops.DefaultDispatchMode
_c.mutation.SetDispatchMode(v)
}
if _, ok := _c.mutation.Announcements(); !ok {
v := shops.DefaultAnnouncements
_c.mutation.SetAnnouncements(v)
}
if _, ok := _c.mutation.CreatedAt(); !ok {
v := shops.DefaultCreatedAt()
_c.mutation.SetCreatedAt(v)
@@ -407,7 +412,7 @@ func (_c *ShopsCreate) createSpec() (*Shops, *sqlgraph.CreateSpec) {
_node.DispatchMode = value
}
if value, ok := _c.mutation.Announcements(); ok {
_spec.SetField(shops.FieldAnnouncements, field.TypeJSON, value)
_spec.SetField(shops.FieldAnnouncements, field.TypeOther, value)
_node.Announcements = value
}
if value, ok := _c.mutation.TemplateConfig(); ok {
+17 -23
View File
@@ -7,12 +7,12 @@ import (
"errors"
"fmt"
"juwan-backend/app/shop/rpc/internal/models/predicate"
"juwan-backend/app/shop/rpc/internal/models/schema"
"juwan-backend/app/shop/rpc/internal/models/shops"
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/dialect/sql/sqljson"
"entgo.io/ent/schema/field"
"github.com/shopspring/decimal"
)
@@ -262,14 +262,16 @@ func (_u *ShopsUpdate) SetNillableDispatchMode(v *string) *ShopsUpdate {
}
// SetAnnouncements sets the "announcements" field.
func (_u *ShopsUpdate) SetAnnouncements(v []string) *ShopsUpdate {
func (_u *ShopsUpdate) SetAnnouncements(v schema.TextArray) *ShopsUpdate {
_u.mutation.SetAnnouncements(v)
return _u
}
// AppendAnnouncements appends value to the "announcements" field.
func (_u *ShopsUpdate) AppendAnnouncements(v []string) *ShopsUpdate {
_u.mutation.AppendAnnouncements(v)
// SetNillableAnnouncements sets the "announcements" field if the given value is not nil.
func (_u *ShopsUpdate) SetNillableAnnouncements(v *schema.TextArray) *ShopsUpdate {
if v != nil {
_u.SetAnnouncements(*v)
}
return _u
}
@@ -437,15 +439,10 @@ func (_u *ShopsUpdate) sqlSave(ctx context.Context) (_node int, err error) {
_spec.SetField(shops.FieldDispatchMode, field.TypeString, value)
}
if value, ok := _u.mutation.Announcements(); ok {
_spec.SetField(shops.FieldAnnouncements, field.TypeJSON, value)
}
if value, ok := _u.mutation.AppendedAnnouncements(); ok {
_spec.AddModifier(func(u *sql.UpdateBuilder) {
sqljson.Append(u, shops.FieldAnnouncements, value)
})
_spec.SetField(shops.FieldAnnouncements, field.TypeOther, value)
}
if _u.mutation.AnnouncementsCleared() {
_spec.ClearField(shops.FieldAnnouncements, field.TypeJSON)
_spec.ClearField(shops.FieldAnnouncements, field.TypeOther)
}
if value, ok := _u.mutation.TemplateConfig(); ok {
_spec.SetField(shops.FieldTemplateConfig, field.TypeJSON, value)
@@ -708,14 +705,16 @@ func (_u *ShopsUpdateOne) SetNillableDispatchMode(v *string) *ShopsUpdateOne {
}
// SetAnnouncements sets the "announcements" field.
func (_u *ShopsUpdateOne) SetAnnouncements(v []string) *ShopsUpdateOne {
func (_u *ShopsUpdateOne) SetAnnouncements(v schema.TextArray) *ShopsUpdateOne {
_u.mutation.SetAnnouncements(v)
return _u
}
// AppendAnnouncements appends value to the "announcements" field.
func (_u *ShopsUpdateOne) AppendAnnouncements(v []string) *ShopsUpdateOne {
_u.mutation.AppendAnnouncements(v)
// SetNillableAnnouncements sets the "announcements" field if the given value is not nil.
func (_u *ShopsUpdateOne) SetNillableAnnouncements(v *schema.TextArray) *ShopsUpdateOne {
if v != nil {
_u.SetAnnouncements(*v)
}
return _u
}
@@ -913,15 +912,10 @@ func (_u *ShopsUpdateOne) sqlSave(ctx context.Context) (_node *Shops, err error)
_spec.SetField(shops.FieldDispatchMode, field.TypeString, value)
}
if value, ok := _u.mutation.Announcements(); ok {
_spec.SetField(shops.FieldAnnouncements, field.TypeJSON, value)
}
if value, ok := _u.mutation.AppendedAnnouncements(); ok {
_spec.AddModifier(func(u *sql.UpdateBuilder) {
sqljson.Append(u, shops.FieldAnnouncements, value)
})
_spec.SetField(shops.FieldAnnouncements, field.TypeOther, value)
}
if _u.mutation.AnnouncementsCleared() {
_spec.ClearField(shops.FieldAnnouncements, field.TypeJSON)
_spec.ClearField(shops.FieldAnnouncements, field.TypeOther)
}
if value, ok := _u.mutation.TemplateConfig(); ok {
_spec.SetField(shops.FieldTemplateConfig, field.TypeJSON, value)
+10 -2
View File
@@ -1,10 +1,12 @@
package svc
import (
stdsql "database/sql"
"fmt"
"juwan-backend/app/shop/rpc/internal/config"
"juwan-backend/app/shop/rpc/internal/models"
"juwan-backend/app/snowflake/rpc/snowflake"
"juwan-backend/app/users/rpc/usercenter"
"juwan-backend/common/redisx"
"juwan-backend/common/snowflakex"
"juwan-backend/pkg/adapter"
@@ -12,27 +14,32 @@ import (
"time"
"ariga.io/entcache"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
_ "github.com/jackc/pgx/v5/stdlib"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/zrpc"
)
type ServiceContext struct {
Config config.Config
Snowflake snowflake.SnowflakeServiceClient
UsersRpc usercenter.Usercenter
ShopModelRW *models.Client
ShopModelRO *models.Client
}
func NewServiceContext(c config.Config) *ServiceContext {
RWConn, err := sql.Open("pgx", c.DB.Master)
rawRW, err := stdsql.Open("pgx", c.DB.Master)
if err != nil {
panic(err)
}
ROConn, err := sql.Open("pgx", c.DB.Slaves)
rawRO, err := stdsql.Open("pgx", c.DB.Slaves)
if err != nil {
panic(err)
}
RWConn := sql.OpenDB(dialect.Postgres, rawRW)
ROConn := sql.OpenDB(dialect.Postgres, rawRO)
redisCluster, err := redisx.ConnectMasterSlaveCluster(c.CacheConf, 5*time.Second)
if redisCluster == nil || err != nil {
@@ -58,6 +65,7 @@ func NewServiceContext(c config.Config) *ServiceContext {
return &ServiceContext{
Config: c,
Snowflake: snowflakex.NewClient(c.SnowflakeRpcConf),
UsersRpc: usercenter.NewUsercenter(zrpc.MustNewClient(c.UsersRpcConf)),
ShopModelRO: models.NewClient(roModelOpts...),
ShopModelRW: models.NewClient(rwModelOpts...),
}
+32 -15
View File
@@ -1,28 +1,45 @@
Name: pb.rpc
ListenOn: 0.0.0.0:8080
DataSource: "${DB_URI}?sslmode=disable"
UserVeriRpcConf :
Target: k8s://juwan/user_verifications-rpc-svc.juwan:8080
# ===== PROC Config =====
#SnowflakeRpcConf:
# Target: k8s://juwan/snowflake-svc.juwan:8080
#UserRpcConf:
# Target: k8s://juwan/user-rpc-svc.juwan:8080
#
#DB:
# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
# Slave: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
#
#CacheConf:
# - Host: "${REDIS_M_HOST}"
# Type: node
# Pass: "${REDIS_PASSWORD}"
# User: "default"
# - Host: "${REDIS_S_HOST}"
# Type: node
# Pass: "${REDIS_PASSWORD}"
# User: "default"
#
#Log:
# Level: info
# ===== DEV Config =====
SnowflakeRpcConf:
Target: k8s://juwan/snowflake-svc.juwan:8080
Endpoints:
- snowflake:8080
UserRpcConf:
Endpoints:
- user-rpc:8080
DB:
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
Slave: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
Slave: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
CacheConf:
- Host: "${REDIS_M_HOST}"
- Host: "${REDIS_HOST}:${REDIS_PORT}"
Type: node
Pass: "${REDIS_PASSWORD}"
User: "default"
- Host: "${REDIS_S_HOST}"
Type: node
Pass: "${REDIS_PASSWORD}"
User: "default"
Log:
Level: info
Level: debug
@@ -12,6 +12,6 @@ type Config struct {
Slave string
}
CacheConf cache.CacheConf
UserVeriRpcConf zrpc.RpcClientConf
SnowflakeRpcConf zrpc.RpcClientConf
UserRpcConf zrpc.RpcClientConf
}
@@ -0,0 +1,113 @@
package logic
import (
"context"
"encoding/json"
"errors"
"juwan-backend/app/snowflake/rpc/snowflake"
"juwan-backend/app/user_verifications/rpc/internal/models"
"juwan-backend/app/user_verifications/rpc/internal/models/schema"
"juwan-backend/app/user_verifications/rpc/internal/models/userverifications"
"juwan-backend/app/user_verifications/rpc/internal/svc"
"juwan-backend/app/user_verifications/rpc/pb"
"juwan-backend/app/users/rpc/usercenter"
"slices"
"github.com/zeromicro/go-zero/core/logx"
)
type AddOrUpdateUserVerificationsLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewAddOrUpdateUserVerificationsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddOrUpdateUserVerificationsLogic {
return &AddOrUpdateUserVerificationsLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
func (l *AddOrUpdateUserVerificationsLogic) AddOrUpdateUserVerifications(in *pb.AddOrUpdateUserVerificationsReq) (*pb.AddOrUpdateUserVerificationsResp, error) {
NotFoundError := &models.NotFoundError{}
var materials schema.MaterialStruct
uv, vErr := l.svcCtx.UserVeriModelRO.Query().
Where(
userverifications.UserIDEQ(in.UserId),
userverifications.RoleEQ(in.Role),
userverifications.StatusNEQ("rejected"),
).
First(l.ctx)
if vErr != nil && !errors.As(vErr, &NotFoundError) {
logx.Errorf("add or update user verifications: get user err:%v", vErr)
return nil, errors.New("")
}
isRole, err := l.checkIsRole(in.UserId, in.Role)
if err != nil {
logx.Errorf("add or update user verifications: check user err:%v", err)
return nil, errors.New("check user role failed")
}
if isRole {
return nil, errors.New("user already has the role")
}
jsonErr := json.Unmarshal([]byte(in.Material), &materials)
if jsonErr != nil {
logx.Errorf("add or update user verifications: marshal materials err:%v", jsonErr)
return nil, errors.New("invalid materials")
}
idResp, rpcErr := l.svcCtx.SnowflakeRpc.NextId(l.ctx, &snowflake.NextIdReq{})
if errors.As(vErr, &NotFoundError) {
if rpcErr != nil {
logx.Errorf("add or update user verifications: get next id err:%v", rpcErr)
return nil, errors.New("generate id failed: ")
}
uv, err = l.svcCtx.UserVeriModelRW.Create().
SetID(idResp.Id).
SetUserID(in.UserId).
SetRole(in.Role).
SetMaterials(materials).
SetRejectReason("").
SetReviewedBy(0).
Save(l.ctx)
if err != nil {
logx.Errorf("add or update user verifications: create user verifications err:%v", err)
return nil, errors.New("create user verifications failed")
}
} else {
uv, err = uv.Update().
SetRole(in.Role).
SetMaterials(materials).
Save(l.ctx)
if err != nil {
logx.Errorf("add or update user verifications: update user verifications err:%v", err)
return nil, errors.New("update user verifications failed")
}
}
return &pb.AddOrUpdateUserVerificationsResp{
Success: true,
}, nil
}
func (l *AddOrUpdateUserVerificationsLogic) checkIsRole(userid int64, role string) (bool, error) {
user, err := l.svcCtx.UserRpc.GetUsersById(l.ctx, &usercenter.GetUsersByIdReq{
Id: userid,
})
logx.Debug("checkIsRole user:", user)
if err != nil {
return false, err
}
logx.Debug("checkIsRole user verified roles:", user.Users.VerifiedRoles)
if slices.Contains(user.Users.VerifiedRoles, role) {
return true, nil
}
return false, nil
}
@@ -0,0 +1,58 @@
package logic
import (
"context"
"errors"
"juwan-backend/app/user_verifications/rpc/internal/models/userverifications"
"juwan-backend/app/user_verifications/rpc/internal/svc"
"juwan-backend/app/user_verifications/rpc/pb"
"github.com/jinzhu/copier"
"github.com/zeromicro/go-zero/core/logx"
)
type ListUserVerificationsByUserIdLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewListUserVerificationsByUserIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListUserVerificationsByUserIdLogic {
return &ListUserVerificationsByUserIdLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
func (l *ListUserVerificationsByUserIdLogic) ListUserVerificationsByUserId(in *pb.ListUserVerificationsByUserIdReq) (*pb.ListUserVerificationsByUserIdResp, error) {
all, err := l.svcCtx.UserVeriModelRO.Query().
Where(userverifications.UserIDEQ(in.UserId)).
All(l.ctx)
if err != nil {
logx.Errorf("ListUserVerificationsByUserId err: %v", err)
return nil, errors.New("list user verifications by user id err")
}
list := make([]*pb.UserVerifications, 0, len(all))
for _, v := range all {
var temp pb.UserVerifications
err = copier.Copy(&temp, v)
if err != nil {
logx.Errorf("copy user verifications err: %v", err)
continue
}
temp.CreatedAt = v.CreatedAt.Unix()
temp.UpdatedAt = v.UpdatedAt.Unix()
if v.ReviewedAt != nil {
temp.ReviewedAt = v.ReviewedAt.Unix()
}
list = append(list, &temp)
}
return &pb.ListUserVerificationsByUserIdResp{
UserVerifications: list,
}, nil
}
@@ -31,11 +31,7 @@ func (l *SearchUserVerificationsLogic) SearchUserVerifications(in *pb.SearchUser
logx.Errorf("Limit exceeds max limit: %d", in.Limit)
return nil, errors.New("limit exceeds max limit")
}
verifications, err := l.svcCtx.UserVeriModelRO.Query().Where(userverifications.Or(
userverifications.UserIDEQ(in.UserId),
userverifications.StatusEQ(in.Status),
userverifications.Role(in.Role),
)).
verifications, err := l.svcCtx.UserVeriModelRO.Query().Where(userverifications.UserIDEQ(in.UserId)).
Offset(int(in.Page * in.Limit)).
Limit(int(in.Limit)).
All(l.ctx)
@@ -12,14 +12,14 @@ var (
UserVerificationsColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt64, Increment: true},
{Name: "user_id", Type: field.TypeInt64, Unique: true},
{Name: "role", Type: field.TypeString, Unique: true},
{Name: "role", Type: field.TypeString},
{Name: "status", Type: field.TypeString, Default: "pending"},
{Name: "materials", Type: field.TypeJSON},
{Name: "reject_reason", Type: field.TypeString, Default: ""},
{Name: "reviewed_by", Type: field.TypeInt64},
{Name: "reviewed_at", Type: field.TypeTime},
{Name: "created_at", Type: field.TypeTime},
{Name: "updated_at", Type: field.TypeTime},
{Name: "reject_reason", Type: field.TypeString, Nullable: true},
{Name: "reviewed_by", Type: field.TypeInt64, Nullable: true},
{Name: "reviewed_at", Type: field.TypeTime, Nullable: true},
{Name: "created_at", Type: field.TypeTime, Nullable: true},
{Name: "updated_at", Type: field.TypeTime, Nullable: true},
}
// UserVerificationsTable holds the schema information for the "user_verifications" table.
UserVerificationsTable = &schema.Table{
@@ -336,7 +336,7 @@ func (m *UserVerificationsMutation) RejectReason() (r string, exists bool) {
// OldRejectReason returns the old "reject_reason" field's value of the UserVerifications entity.
// If the UserVerifications object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *UserVerificationsMutation) OldRejectReason(ctx context.Context) (v string, err error) {
func (m *UserVerificationsMutation) OldRejectReason(ctx context.Context) (v *string, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldRejectReason is only allowed on UpdateOne operations")
}
@@ -350,9 +350,22 @@ func (m *UserVerificationsMutation) OldRejectReason(ctx context.Context) (v stri
return oldValue.RejectReason, nil
}
// ClearRejectReason clears the value of the "reject_reason" field.
func (m *UserVerificationsMutation) ClearRejectReason() {
m.reject_reason = nil
m.clearedFields[userverifications.FieldRejectReason] = struct{}{}
}
// RejectReasonCleared returns if the "reject_reason" field was cleared in this mutation.
func (m *UserVerificationsMutation) RejectReasonCleared() bool {
_, ok := m.clearedFields[userverifications.FieldRejectReason]
return ok
}
// ResetRejectReason resets all changes to the "reject_reason" field.
func (m *UserVerificationsMutation) ResetRejectReason() {
m.reject_reason = nil
delete(m.clearedFields, userverifications.FieldRejectReason)
}
// SetReviewedBy sets the "reviewed_by" field.
@@ -373,7 +386,7 @@ func (m *UserVerificationsMutation) ReviewedBy() (r int64, exists bool) {
// OldReviewedBy returns the old "reviewed_by" field's value of the UserVerifications entity.
// If the UserVerifications object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *UserVerificationsMutation) OldReviewedBy(ctx context.Context) (v int64, err error) {
func (m *UserVerificationsMutation) OldReviewedBy(ctx context.Context) (v *int64, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldReviewedBy is only allowed on UpdateOne operations")
}
@@ -405,10 +418,24 @@ func (m *UserVerificationsMutation) AddedReviewedBy() (r int64, exists bool) {
return *v, true
}
// ClearReviewedBy clears the value of the "reviewed_by" field.
func (m *UserVerificationsMutation) ClearReviewedBy() {
m.reviewed_by = nil
m.addreviewed_by = nil
m.clearedFields[userverifications.FieldReviewedBy] = struct{}{}
}
// ReviewedByCleared returns if the "reviewed_by" field was cleared in this mutation.
func (m *UserVerificationsMutation) ReviewedByCleared() bool {
_, ok := m.clearedFields[userverifications.FieldReviewedBy]
return ok
}
// ResetReviewedBy resets all changes to the "reviewed_by" field.
func (m *UserVerificationsMutation) ResetReviewedBy() {
m.reviewed_by = nil
m.addreviewed_by = nil
delete(m.clearedFields, userverifications.FieldReviewedBy)
}
// SetReviewedAt sets the "reviewed_at" field.
@@ -428,7 +455,7 @@ func (m *UserVerificationsMutation) ReviewedAt() (r time.Time, exists bool) {
// OldReviewedAt returns the old "reviewed_at" field's value of the UserVerifications entity.
// If the UserVerifications object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *UserVerificationsMutation) OldReviewedAt(ctx context.Context) (v time.Time, err error) {
func (m *UserVerificationsMutation) OldReviewedAt(ctx context.Context) (v *time.Time, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldReviewedAt is only allowed on UpdateOne operations")
}
@@ -442,9 +469,22 @@ func (m *UserVerificationsMutation) OldReviewedAt(ctx context.Context) (v time.T
return oldValue.ReviewedAt, nil
}
// ClearReviewedAt clears the value of the "reviewed_at" field.
func (m *UserVerificationsMutation) ClearReviewedAt() {
m.reviewed_at = nil
m.clearedFields[userverifications.FieldReviewedAt] = struct{}{}
}
// ReviewedAtCleared returns if the "reviewed_at" field was cleared in this mutation.
func (m *UserVerificationsMutation) ReviewedAtCleared() bool {
_, ok := m.clearedFields[userverifications.FieldReviewedAt]
return ok
}
// ResetReviewedAt resets all changes to the "reviewed_at" field.
func (m *UserVerificationsMutation) ResetReviewedAt() {
m.reviewed_at = nil
delete(m.clearedFields, userverifications.FieldReviewedAt)
}
// SetCreatedAt sets the "created_at" field.
@@ -478,9 +518,22 @@ func (m *UserVerificationsMutation) OldCreatedAt(ctx context.Context) (v time.Ti
return oldValue.CreatedAt, nil
}
// ClearCreatedAt clears the value of the "created_at" field.
func (m *UserVerificationsMutation) ClearCreatedAt() {
m.created_at = nil
m.clearedFields[userverifications.FieldCreatedAt] = struct{}{}
}
// CreatedAtCleared returns if the "created_at" field was cleared in this mutation.
func (m *UserVerificationsMutation) CreatedAtCleared() bool {
_, ok := m.clearedFields[userverifications.FieldCreatedAt]
return ok
}
// ResetCreatedAt resets all changes to the "created_at" field.
func (m *UserVerificationsMutation) ResetCreatedAt() {
m.created_at = nil
delete(m.clearedFields, userverifications.FieldCreatedAt)
}
// SetUpdatedAt sets the "updated_at" field.
@@ -514,9 +567,22 @@ func (m *UserVerificationsMutation) OldUpdatedAt(ctx context.Context) (v time.Ti
return oldValue.UpdatedAt, nil
}
// ClearUpdatedAt clears the value of the "updated_at" field.
func (m *UserVerificationsMutation) ClearUpdatedAt() {
m.updated_at = nil
m.clearedFields[userverifications.FieldUpdatedAt] = struct{}{}
}
// UpdatedAtCleared returns if the "updated_at" field was cleared in this mutation.
func (m *UserVerificationsMutation) UpdatedAtCleared() bool {
_, ok := m.clearedFields[userverifications.FieldUpdatedAt]
return ok
}
// ResetUpdatedAt resets all changes to the "updated_at" field.
func (m *UserVerificationsMutation) ResetUpdatedAt() {
m.updated_at = nil
delete(m.clearedFields, userverifications.FieldUpdatedAt)
}
// Where appends a list predicates to the UserVerificationsMutation builder.
@@ -762,7 +828,23 @@ func (m *UserVerificationsMutation) AddField(name string, value ent.Value) error
// ClearedFields returns all nullable fields that were cleared during this
// mutation.
func (m *UserVerificationsMutation) ClearedFields() []string {
return nil
var fields []string
if m.FieldCleared(userverifications.FieldRejectReason) {
fields = append(fields, userverifications.FieldRejectReason)
}
if m.FieldCleared(userverifications.FieldReviewedBy) {
fields = append(fields, userverifications.FieldReviewedBy)
}
if m.FieldCleared(userverifications.FieldReviewedAt) {
fields = append(fields, userverifications.FieldReviewedAt)
}
if m.FieldCleared(userverifications.FieldCreatedAt) {
fields = append(fields, userverifications.FieldCreatedAt)
}
if m.FieldCleared(userverifications.FieldUpdatedAt) {
fields = append(fields, userverifications.FieldUpdatedAt)
}
return fields
}
// FieldCleared returns a boolean indicating if a field with the given name was
@@ -775,6 +857,23 @@ func (m *UserVerificationsMutation) FieldCleared(name string) bool {
// ClearField clears the value of the field with the given name. It returns an
// error if the field is not defined in the schema.
func (m *UserVerificationsMutation) ClearField(name string) error {
switch name {
case userverifications.FieldRejectReason:
m.ClearRejectReason()
return nil
case userverifications.FieldReviewedBy:
m.ClearReviewedBy()
return nil
case userverifications.FieldReviewedAt:
m.ClearReviewedAt()
return nil
case userverifications.FieldCreatedAt:
m.ClearCreatedAt()
return nil
case userverifications.FieldUpdatedAt:
m.ClearUpdatedAt()
return nil
}
return fmt.Errorf("unknown UserVerifications nullable field %s", name)
}
@@ -5,6 +5,7 @@ package models
import (
"juwan-backend/app/user_verifications/rpc/internal/models/schema"
"juwan-backend/app/user_verifications/rpc/internal/models/userverifications"
"time"
)
// The init function reads all schema descriptors with runtime code
@@ -17,8 +18,12 @@ func init() {
userverificationsDescStatus := userverificationsFields[3].Descriptor()
// userverifications.DefaultStatus holds the default value on creation for the status field.
userverifications.DefaultStatus = userverificationsDescStatus.Default.(string)
// userverificationsDescRejectReason is the schema descriptor for reject_reason field.
userverificationsDescRejectReason := userverificationsFields[5].Descriptor()
// userverifications.DefaultRejectReason holds the default value on creation for the reject_reason field.
userverifications.DefaultRejectReason = userverificationsDescRejectReason.Default.(string)
// userverificationsDescCreatedAt is the schema descriptor for created_at field.
userverificationsDescCreatedAt := userverificationsFields[8].Descriptor()
// userverifications.DefaultCreatedAt holds the default value on creation for the created_at field.
userverifications.DefaultCreatedAt = userverificationsDescCreatedAt.Default.(func() time.Time)
// userverificationsDescUpdatedAt is the schema descriptor for updated_at field.
userverificationsDescUpdatedAt := userverificationsFields[9].Descriptor()
// userverifications.DefaultUpdatedAt holds the default value on creation for the updated_at field.
userverifications.DefaultUpdatedAt = userverificationsDescUpdatedAt.Default.(func() time.Time)
}
@@ -1,6 +1,8 @@
package schema
import (
"time"
"entgo.io/ent"
"entgo.io/ent/schema/field"
)
@@ -13,8 +15,8 @@ type UserVerifications struct {
type MaterialStruct struct {
IdCardFront string `json:"idCardFront"`
IdCardBack string `json:"idCardBack"`
GameScreenshots []string `json:"gameScreenshots"`
VoiceDemo string `json:"voiceDemo"`
GameScreenshots []string `json:"gameScreenshots,omitempty"`
VoiceDemo string `json:"voiceDemo,omitempty"`
}
// Fields of the UserVerifications.
@@ -22,14 +24,14 @@ func (UserVerifications) Fields() []ent.Field {
return []ent.Field{
field.Int64("id").Immutable().Unique(),
field.Int64("user_id").Immutable().Unique(),
field.String("role").Unique(),
field.String("role"),
field.String("status").Default("pending"),
field.JSON("materials", MaterialStruct{}),
field.String("reject_reason").Default(""),
field.Int64("reviewed_by"),
field.Time("reviewed_at").Immutable(),
field.Time("created_at").Immutable(),
field.Time("updated_at").Immutable(),
field.String("reject_reason").Nillable().Optional(),
field.Int64("reviewed_by").Nillable().Optional(),
field.Time("reviewed_at").Nillable().Optional(),
field.Time("created_at").Immutable().Optional().Default(time.Now),
field.Time("updated_at").Immutable().Optional().Default(time.Now),
}
}
@@ -14,7 +14,7 @@ import (
"entgo.io/ent/dialect/sql"
)
// UserVerifications is the models entity for the UserVerifications schema.
// UserVerifications is the model entity for the UserVerifications schema.
type UserVerifications struct {
config `json:"-"`
// ID of the ent.
@@ -28,11 +28,11 @@ type UserVerifications struct {
// Materials holds the value of the "materials" field.
Materials schema.MaterialStruct `json:"materials,omitempty"`
// RejectReason holds the value of the "reject_reason" field.
RejectReason string `json:"reject_reason,omitempty"`
RejectReason *string `json:"reject_reason,omitempty"`
// ReviewedBy holds the value of the "reviewed_by" field.
ReviewedBy int64 `json:"reviewed_by,omitempty"`
ReviewedBy *int64 `json:"reviewed_by,omitempty"`
// ReviewedAt holds the value of the "reviewed_at" field.
ReviewedAt time.Time `json:"reviewed_at,omitempty"`
ReviewedAt *time.Time `json:"reviewed_at,omitempty"`
// CreatedAt holds the value of the "created_at" field.
CreatedAt time.Time `json:"created_at,omitempty"`
// UpdatedAt holds the value of the "updated_at" field.
@@ -104,19 +104,22 @@ func (_m *UserVerifications) assignValues(columns []string, values []any) error
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field reject_reason", values[i])
} else if value.Valid {
_m.RejectReason = value.String
_m.RejectReason = new(string)
*_m.RejectReason = value.String
}
case userverifications.FieldReviewedBy:
if value, ok := values[i].(*sql.NullInt64); !ok {
return fmt.Errorf("unexpected type %T for field reviewed_by", values[i])
} else if value.Valid {
_m.ReviewedBy = value.Int64
_m.ReviewedBy = new(int64)
*_m.ReviewedBy = value.Int64
}
case userverifications.FieldReviewedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field reviewed_at", values[i])
} else if value.Valid {
_m.ReviewedAt = value.Time
_m.ReviewedAt = new(time.Time)
*_m.ReviewedAt = value.Time
}
case userverifications.FieldCreatedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
@@ -178,14 +181,20 @@ func (_m *UserVerifications) String() string {
builder.WriteString("materials=")
builder.WriteString(fmt.Sprintf("%v", _m.Materials))
builder.WriteString(", ")
builder.WriteString("reject_reason=")
builder.WriteString(_m.RejectReason)
if v := _m.RejectReason; v != nil {
builder.WriteString("reject_reason=")
builder.WriteString(*v)
}
builder.WriteString(", ")
builder.WriteString("reviewed_by=")
builder.WriteString(fmt.Sprintf("%v", _m.ReviewedBy))
if v := _m.ReviewedBy; v != nil {
builder.WriteString("reviewed_by=")
builder.WriteString(fmt.Sprintf("%v", *v))
}
builder.WriteString(", ")
builder.WriteString("reviewed_at=")
builder.WriteString(_m.ReviewedAt.Format(time.ANSIC))
if v := _m.ReviewedAt; v != nil {
builder.WriteString("reviewed_at=")
builder.WriteString(v.Format(time.ANSIC))
}
builder.WriteString(", ")
builder.WriteString("created_at=")
builder.WriteString(_m.CreatedAt.Format(time.ANSIC))
@@ -3,6 +3,8 @@
package userverifications
import (
"time"
"entgo.io/ent/dialect/sql"
)
@@ -60,8 +62,10 @@ func ValidColumn(column string) bool {
var (
// DefaultStatus holds the default value on creation for the "status" field.
DefaultStatus string
// DefaultRejectReason holds the default value on creation for the "reject_reason" field.
DefaultRejectReason string
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
DefaultCreatedAt func() time.Time
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
DefaultUpdatedAt func() time.Time
)
// OrderOption defines the ordering options for the UserVerifications queries.
@@ -319,6 +319,16 @@ func RejectReasonHasSuffix(v string) predicate.UserVerifications {
return predicate.UserVerifications(sql.FieldHasSuffix(FieldRejectReason, v))
}
// RejectReasonIsNil applies the IsNil predicate on the "reject_reason" field.
func RejectReasonIsNil() predicate.UserVerifications {
return predicate.UserVerifications(sql.FieldIsNull(FieldRejectReason))
}
// RejectReasonNotNil applies the NotNil predicate on the "reject_reason" field.
func RejectReasonNotNil() predicate.UserVerifications {
return predicate.UserVerifications(sql.FieldNotNull(FieldRejectReason))
}
// RejectReasonEqualFold applies the EqualFold predicate on the "reject_reason" field.
func RejectReasonEqualFold(v string) predicate.UserVerifications {
return predicate.UserVerifications(sql.FieldEqualFold(FieldRejectReason, v))
@@ -369,6 +379,16 @@ func ReviewedByLTE(v int64) predicate.UserVerifications {
return predicate.UserVerifications(sql.FieldLTE(FieldReviewedBy, v))
}
// ReviewedByIsNil applies the IsNil predicate on the "reviewed_by" field.
func ReviewedByIsNil() predicate.UserVerifications {
return predicate.UserVerifications(sql.FieldIsNull(FieldReviewedBy))
}
// ReviewedByNotNil applies the NotNil predicate on the "reviewed_by" field.
func ReviewedByNotNil() predicate.UserVerifications {
return predicate.UserVerifications(sql.FieldNotNull(FieldReviewedBy))
}
// ReviewedAtEQ applies the EQ predicate on the "reviewed_at" field.
func ReviewedAtEQ(v time.Time) predicate.UserVerifications {
return predicate.UserVerifications(sql.FieldEQ(FieldReviewedAt, v))
@@ -409,6 +429,16 @@ func ReviewedAtLTE(v time.Time) predicate.UserVerifications {
return predicate.UserVerifications(sql.FieldLTE(FieldReviewedAt, v))
}
// ReviewedAtIsNil applies the IsNil predicate on the "reviewed_at" field.
func ReviewedAtIsNil() predicate.UserVerifications {
return predicate.UserVerifications(sql.FieldIsNull(FieldReviewedAt))
}
// ReviewedAtNotNil applies the NotNil predicate on the "reviewed_at" field.
func ReviewedAtNotNil() predicate.UserVerifications {
return predicate.UserVerifications(sql.FieldNotNull(FieldReviewedAt))
}
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
func CreatedAtEQ(v time.Time) predicate.UserVerifications {
return predicate.UserVerifications(sql.FieldEQ(FieldCreatedAt, v))
@@ -449,6 +479,16 @@ func CreatedAtLTE(v time.Time) predicate.UserVerifications {
return predicate.UserVerifications(sql.FieldLTE(FieldCreatedAt, v))
}
// CreatedAtIsNil applies the IsNil predicate on the "created_at" field.
func CreatedAtIsNil() predicate.UserVerifications {
return predicate.UserVerifications(sql.FieldIsNull(FieldCreatedAt))
}
// CreatedAtNotNil applies the NotNil predicate on the "created_at" field.
func CreatedAtNotNil() predicate.UserVerifications {
return predicate.UserVerifications(sql.FieldNotNull(FieldCreatedAt))
}
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
func UpdatedAtEQ(v time.Time) predicate.UserVerifications {
return predicate.UserVerifications(sql.FieldEQ(FieldUpdatedAt, v))
@@ -489,6 +529,16 @@ func UpdatedAtLTE(v time.Time) predicate.UserVerifications {
return predicate.UserVerifications(sql.FieldLTE(FieldUpdatedAt, v))
}
// UpdatedAtIsNil applies the IsNil predicate on the "updated_at" field.
func UpdatedAtIsNil() predicate.UserVerifications {
return predicate.UserVerifications(sql.FieldIsNull(FieldUpdatedAt))
}
// UpdatedAtNotNil applies the NotNil predicate on the "updated_at" field.
func UpdatedAtNotNil() predicate.UserVerifications {
return predicate.UserVerifications(sql.FieldNotNull(FieldUpdatedAt))
}
// And groups predicates with the AND operator between them.
func And(predicates ...predicate.UserVerifications) predicate.UserVerifications {
return predicate.UserVerifications(sql.AndPredicates(predicates...))
@@ -73,24 +73,56 @@ func (_c *UserVerificationsCreate) SetReviewedBy(v int64) *UserVerificationsCrea
return _c
}
// SetNillableReviewedBy sets the "reviewed_by" field if the given value is not nil.
func (_c *UserVerificationsCreate) SetNillableReviewedBy(v *int64) *UserVerificationsCreate {
if v != nil {
_c.SetReviewedBy(*v)
}
return _c
}
// SetReviewedAt sets the "reviewed_at" field.
func (_c *UserVerificationsCreate) SetReviewedAt(v time.Time) *UserVerificationsCreate {
_c.mutation.SetReviewedAt(v)
return _c
}
// SetNillableReviewedAt sets the "reviewed_at" field if the given value is not nil.
func (_c *UserVerificationsCreate) SetNillableReviewedAt(v *time.Time) *UserVerificationsCreate {
if v != nil {
_c.SetReviewedAt(*v)
}
return _c
}
// SetCreatedAt sets the "created_at" field.
func (_c *UserVerificationsCreate) SetCreatedAt(v time.Time) *UserVerificationsCreate {
_c.mutation.SetCreatedAt(v)
return _c
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (_c *UserVerificationsCreate) SetNillableCreatedAt(v *time.Time) *UserVerificationsCreate {
if v != nil {
_c.SetCreatedAt(*v)
}
return _c
}
// SetUpdatedAt sets the "updated_at" field.
func (_c *UserVerificationsCreate) SetUpdatedAt(v time.Time) *UserVerificationsCreate {
_c.mutation.SetUpdatedAt(v)
return _c
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (_c *UserVerificationsCreate) SetNillableUpdatedAt(v *time.Time) *UserVerificationsCreate {
if v != nil {
_c.SetUpdatedAt(*v)
}
return _c
}
// SetID sets the "id" field.
func (_c *UserVerificationsCreate) SetID(v int64) *UserVerificationsCreate {
_c.mutation.SetID(v)
@@ -136,9 +168,13 @@ func (_c *UserVerificationsCreate) defaults() {
v := userverifications.DefaultStatus
_c.mutation.SetStatus(v)
}
if _, ok := _c.mutation.RejectReason(); !ok {
v := userverifications.DefaultRejectReason
_c.mutation.SetRejectReason(v)
if _, ok := _c.mutation.CreatedAt(); !ok {
v := userverifications.DefaultCreatedAt()
_c.mutation.SetCreatedAt(v)
}
if _, ok := _c.mutation.UpdatedAt(); !ok {
v := userverifications.DefaultUpdatedAt()
_c.mutation.SetUpdatedAt(v)
}
}
@@ -156,21 +192,6 @@ func (_c *UserVerificationsCreate) check() error {
if _, ok := _c.mutation.Materials(); !ok {
return &ValidationError{Name: "materials", err: errors.New(`models: missing required field "UserVerifications.materials"`)}
}
if _, ok := _c.mutation.RejectReason(); !ok {
return &ValidationError{Name: "reject_reason", err: errors.New(`models: missing required field "UserVerifications.reject_reason"`)}
}
if _, ok := _c.mutation.ReviewedBy(); !ok {
return &ValidationError{Name: "reviewed_by", err: errors.New(`models: missing required field "UserVerifications.reviewed_by"`)}
}
if _, ok := _c.mutation.ReviewedAt(); !ok {
return &ValidationError{Name: "reviewed_at", err: errors.New(`models: missing required field "UserVerifications.reviewed_at"`)}
}
if _, ok := _c.mutation.CreatedAt(); !ok {
return &ValidationError{Name: "created_at", err: errors.New(`models: missing required field "UserVerifications.created_at"`)}
}
if _, ok := _c.mutation.UpdatedAt(); !ok {
return &ValidationError{Name: "updated_at", err: errors.New(`models: missing required field "UserVerifications.updated_at"`)}
}
return nil
}
@@ -221,15 +242,15 @@ func (_c *UserVerificationsCreate) createSpec() (*UserVerifications, *sqlgraph.C
}
if value, ok := _c.mutation.RejectReason(); ok {
_spec.SetField(userverifications.FieldRejectReason, field.TypeString, value)
_node.RejectReason = value
_node.RejectReason = &value
}
if value, ok := _c.mutation.ReviewedBy(); ok {
_spec.SetField(userverifications.FieldReviewedBy, field.TypeInt64, value)
_node.ReviewedBy = value
_node.ReviewedBy = &value
}
if value, ok := _c.mutation.ReviewedAt(); ok {
_spec.SetField(userverifications.FieldReviewedAt, field.TypeTime, value)
_node.ReviewedAt = value
_node.ReviewedAt = &value
}
if value, ok := _c.mutation.CreatedAt(); ok {
_spec.SetField(userverifications.FieldCreatedAt, field.TypeTime, value)
@@ -9,6 +9,7 @@ import (
"juwan-backend/app/user_verifications/rpc/internal/models/predicate"
"juwan-backend/app/user_verifications/rpc/internal/models/schema"
"juwan-backend/app/user_verifications/rpc/internal/models/userverifications"
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
@@ -84,6 +85,12 @@ func (_u *UserVerificationsUpdate) SetNillableRejectReason(v *string) *UserVerif
return _u
}
// ClearRejectReason clears the value of the "reject_reason" field.
func (_u *UserVerificationsUpdate) ClearRejectReason() *UserVerificationsUpdate {
_u.mutation.ClearRejectReason()
return _u
}
// SetReviewedBy sets the "reviewed_by" field.
func (_u *UserVerificationsUpdate) SetReviewedBy(v int64) *UserVerificationsUpdate {
_u.mutation.ResetReviewedBy()
@@ -105,6 +112,32 @@ func (_u *UserVerificationsUpdate) AddReviewedBy(v int64) *UserVerificationsUpda
return _u
}
// ClearReviewedBy clears the value of the "reviewed_by" field.
func (_u *UserVerificationsUpdate) ClearReviewedBy() *UserVerificationsUpdate {
_u.mutation.ClearReviewedBy()
return _u
}
// SetReviewedAt sets the "reviewed_at" field.
func (_u *UserVerificationsUpdate) SetReviewedAt(v time.Time) *UserVerificationsUpdate {
_u.mutation.SetReviewedAt(v)
return _u
}
// SetNillableReviewedAt sets the "reviewed_at" field if the given value is not nil.
func (_u *UserVerificationsUpdate) SetNillableReviewedAt(v *time.Time) *UserVerificationsUpdate {
if v != nil {
_u.SetReviewedAt(*v)
}
return _u
}
// ClearReviewedAt clears the value of the "reviewed_at" field.
func (_u *UserVerificationsUpdate) ClearReviewedAt() *UserVerificationsUpdate {
_u.mutation.ClearReviewedAt()
return _u
}
// Mutation returns the UserVerificationsMutation object of the builder.
func (_u *UserVerificationsUpdate) Mutation() *UserVerificationsMutation {
return _u.mutation
@@ -158,12 +191,30 @@ func (_u *UserVerificationsUpdate) sqlSave(ctx context.Context) (_node int, err
if value, ok := _u.mutation.RejectReason(); ok {
_spec.SetField(userverifications.FieldRejectReason, field.TypeString, value)
}
if _u.mutation.RejectReasonCleared() {
_spec.ClearField(userverifications.FieldRejectReason, field.TypeString)
}
if value, ok := _u.mutation.ReviewedBy(); ok {
_spec.SetField(userverifications.FieldReviewedBy, field.TypeInt64, value)
}
if value, ok := _u.mutation.AddedReviewedBy(); ok {
_spec.AddField(userverifications.FieldReviewedBy, field.TypeInt64, value)
}
if _u.mutation.ReviewedByCleared() {
_spec.ClearField(userverifications.FieldReviewedBy, field.TypeInt64)
}
if value, ok := _u.mutation.ReviewedAt(); ok {
_spec.SetField(userverifications.FieldReviewedAt, field.TypeTime, value)
}
if _u.mutation.ReviewedAtCleared() {
_spec.ClearField(userverifications.FieldReviewedAt, field.TypeTime)
}
if _u.mutation.CreatedAtCleared() {
_spec.ClearField(userverifications.FieldCreatedAt, field.TypeTime)
}
if _u.mutation.UpdatedAtCleared() {
_spec.ClearField(userverifications.FieldUpdatedAt, field.TypeTime)
}
if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{userverifications.Label}
@@ -240,6 +291,12 @@ func (_u *UserVerificationsUpdateOne) SetNillableRejectReason(v *string) *UserVe
return _u
}
// ClearRejectReason clears the value of the "reject_reason" field.
func (_u *UserVerificationsUpdateOne) ClearRejectReason() *UserVerificationsUpdateOne {
_u.mutation.ClearRejectReason()
return _u
}
// SetReviewedBy sets the "reviewed_by" field.
func (_u *UserVerificationsUpdateOne) SetReviewedBy(v int64) *UserVerificationsUpdateOne {
_u.mutation.ResetReviewedBy()
@@ -261,6 +318,32 @@ func (_u *UserVerificationsUpdateOne) AddReviewedBy(v int64) *UserVerificationsU
return _u
}
// ClearReviewedBy clears the value of the "reviewed_by" field.
func (_u *UserVerificationsUpdateOne) ClearReviewedBy() *UserVerificationsUpdateOne {
_u.mutation.ClearReviewedBy()
return _u
}
// SetReviewedAt sets the "reviewed_at" field.
func (_u *UserVerificationsUpdateOne) SetReviewedAt(v time.Time) *UserVerificationsUpdateOne {
_u.mutation.SetReviewedAt(v)
return _u
}
// SetNillableReviewedAt sets the "reviewed_at" field if the given value is not nil.
func (_u *UserVerificationsUpdateOne) SetNillableReviewedAt(v *time.Time) *UserVerificationsUpdateOne {
if v != nil {
_u.SetReviewedAt(*v)
}
return _u
}
// ClearReviewedAt clears the value of the "reviewed_at" field.
func (_u *UserVerificationsUpdateOne) ClearReviewedAt() *UserVerificationsUpdateOne {
_u.mutation.ClearReviewedAt()
return _u
}
// Mutation returns the UserVerificationsMutation object of the builder.
func (_u *UserVerificationsUpdateOne) Mutation() *UserVerificationsMutation {
return _u.mutation
@@ -344,12 +427,30 @@ func (_u *UserVerificationsUpdateOne) sqlSave(ctx context.Context) (_node *UserV
if value, ok := _u.mutation.RejectReason(); ok {
_spec.SetField(userverifications.FieldRejectReason, field.TypeString, value)
}
if _u.mutation.RejectReasonCleared() {
_spec.ClearField(userverifications.FieldRejectReason, field.TypeString)
}
if value, ok := _u.mutation.ReviewedBy(); ok {
_spec.SetField(userverifications.FieldReviewedBy, field.TypeInt64, value)
}
if value, ok := _u.mutation.AddedReviewedBy(); ok {
_spec.AddField(userverifications.FieldReviewedBy, field.TypeInt64, value)
}
if _u.mutation.ReviewedByCleared() {
_spec.ClearField(userverifications.FieldReviewedBy, field.TypeInt64)
}
if value, ok := _u.mutation.ReviewedAt(); ok {
_spec.SetField(userverifications.FieldReviewedAt, field.TypeTime, value)
}
if _u.mutation.ReviewedAtCleared() {
_spec.ClearField(userverifications.FieldReviewedAt, field.TypeTime)
}
if _u.mutation.CreatedAtCleared() {
_spec.ClearField(userverifications.FieldCreatedAt, field.TypeTime)
}
if _u.mutation.UpdatedAtCleared() {
_spec.ClearField(userverifications.FieldUpdatedAt, field.TypeTime)
}
_node = &UserVerifications{config: _u.config}
_spec.Assign = _node.assignValues
_spec.ScanValues = _node.scanValues
@@ -48,3 +48,13 @@ func (s *UserVerificationsServer) SearchUserVerifications(ctx context.Context, i
l := logic.NewSearchUserVerificationsLogic(ctx, s.svcCtx)
return l.SearchUserVerifications(in)
}
func (s *UserVerificationsServer) AddOrUpdateUserVerifications(ctx context.Context, in *pb.AddOrUpdateUserVerificationsReq) (*pb.AddOrUpdateUserVerificationsResp, error) {
l := logic.NewAddOrUpdateUserVerificationsLogic(ctx, s.svcCtx)
return l.AddOrUpdateUserVerifications(in)
}
func (s *UserVerificationsServer) ListUserVerificationsByUserId(ctx context.Context, in *pb.ListUserVerificationsByUserIdReq) (*pb.ListUserVerificationsByUserIdResp, error) {
l := logic.NewListUserVerificationsByUserIdLogic(ctx, s.svcCtx)
return l.ListUserVerificationsByUserId(in)
}
@@ -1,20 +1,24 @@
package svc
import (
stdsql "database/sql"
"juwan-backend/app/snowflake/rpc/snowflake"
"juwan-backend/app/user_verifications/rpc/internal/config"
"juwan-backend/app/user_verifications/rpc/internal/models"
"juwan-backend/app/user_verifications/rpc/userverifications"
"juwan-backend/app/users/rpc/usercenter"
"juwan-backend/common/redisx"
"juwan-backend/common/snowflakex"
"juwan-backend/pkg/adapter"
"time"
"entgo.io/ent/dialect"
_ "github.com/jackc/pgx/v5/stdlib"
"github.com/zeromicro/go-zero/zrpc"
"ariga.io/entcache"
"entgo.io/ent/dialect/sql"
"github.com/redis/go-redis/v9"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/zrpc"
)
type ServiceContext struct {
@@ -22,19 +26,23 @@ type ServiceContext struct {
UserVeriModelRW *models.UserVerificationsClient
UserVeriModelRO *models.UserVerificationsClient
RedisClient *redis.ClusterClient
UserVeriRpc userverifications.UserVerificationsZrpcClient
SnowflakeRpc snowflake.SnowflakeServiceClient
UserRpc usercenter.Usercenter
}
func NewServiceContext(c config.Config) *ServiceContext {
RWConn, err := sql.Open("pgx", c.DB.Master)
rawRW, err := stdsql.Open("pgx", c.DB.Master)
if err != nil {
panic(err)
}
ROConn, err := sql.Open("pgx", c.DB.Slave)
rawRO, err := stdsql.Open("pgx", c.DB.Slave)
if err != nil {
panic(err)
}
RWConn := sql.OpenDB(dialect.Postgres, rawRW)
ROConn := sql.OpenDB(dialect.Postgres, rawRO)
logx.Infof("success to connect to postgres~")
redisConn, err := redisx.ConnectMasterSlaveCluster(c.CacheConf, 5*time.Second)
if err != nil || redisConn == nil {
@@ -49,7 +57,7 @@ func NewServiceContext(c config.Config) *ServiceContext {
UserVeriModelRW: models.NewClient(models.Driver(RWDrv)).UserVerifications,
UserVeriModelRO: models.NewClient(models.Driver(RODrv)).UserVerifications,
RedisClient: redisConn.Client,
UserVeriRpc: userverifications.NewUserVerificationsZrpcClient(zrpc.MustNewClient(c.UserVeriRpcConf)),
SnowflakeRpc: snowflakex.NewClient(c.SnowflakeRpcConf),
UserRpc: usercenter.NewUsercenter(zrpc.MustNewClient(c.UserRpcConf)),
}
}
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.11
// protoc v3.19.4
// protoc v5.29.6
// source: user_verifications.proto
package pb
@@ -778,6 +778,198 @@ func (x *SearchUserVerificationsResp) GetUserVerifications() []*UserVerification
return nil
}
type AddOrUpdateUserVerificationsReq struct {
state protoimpl.MessageState `protogen:"open.v1"`
UserId int64 `protobuf:"varint,1,opt,name=userId,proto3" json:"userId,omitempty"` // userId
Role string `protobuf:"bytes,2,opt,name=role,proto3" json:"role,omitempty"`
Material string `protobuf:"bytes,3,opt,name=material,proto3" json:"material,omitempty"` // material
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AddOrUpdateUserVerificationsReq) Reset() {
*x = AddOrUpdateUserVerificationsReq{}
mi := &file_user_verifications_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AddOrUpdateUserVerificationsReq) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AddOrUpdateUserVerificationsReq) ProtoMessage() {}
func (x *AddOrUpdateUserVerificationsReq) ProtoReflect() protoreflect.Message {
mi := &file_user_verifications_proto_msgTypes[11]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AddOrUpdateUserVerificationsReq.ProtoReflect.Descriptor instead.
func (*AddOrUpdateUserVerificationsReq) Descriptor() ([]byte, []int) {
return file_user_verifications_proto_rawDescGZIP(), []int{11}
}
func (x *AddOrUpdateUserVerificationsReq) GetUserId() int64 {
if x != nil {
return x.UserId
}
return 0
}
func (x *AddOrUpdateUserVerificationsReq) GetRole() string {
if x != nil {
return x.Role
}
return ""
}
func (x *AddOrUpdateUserVerificationsReq) GetMaterial() string {
if x != nil {
return x.Material
}
return ""
}
type AddOrUpdateUserVerificationsResp struct {
state protoimpl.MessageState `protogen:"open.v1"`
Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` // success
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AddOrUpdateUserVerificationsResp) Reset() {
*x = AddOrUpdateUserVerificationsResp{}
mi := &file_user_verifications_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AddOrUpdateUserVerificationsResp) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AddOrUpdateUserVerificationsResp) ProtoMessage() {}
func (x *AddOrUpdateUserVerificationsResp) ProtoReflect() protoreflect.Message {
mi := &file_user_verifications_proto_msgTypes[12]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AddOrUpdateUserVerificationsResp.ProtoReflect.Descriptor instead.
func (*AddOrUpdateUserVerificationsResp) Descriptor() ([]byte, []int) {
return file_user_verifications_proto_rawDescGZIP(), []int{12}
}
func (x *AddOrUpdateUserVerificationsResp) GetSuccess() bool {
if x != nil {
return x.Success
}
return false
}
type ListUserVerificationsByUserIdReq struct {
state protoimpl.MessageState `protogen:"open.v1"`
UserId int64 `protobuf:"varint,1,opt,name=userId,proto3" json:"userId,omitempty"` // userId
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ListUserVerificationsByUserIdReq) Reset() {
*x = ListUserVerificationsByUserIdReq{}
mi := &file_user_verifications_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListUserVerificationsByUserIdReq) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListUserVerificationsByUserIdReq) ProtoMessage() {}
func (x *ListUserVerificationsByUserIdReq) ProtoReflect() protoreflect.Message {
mi := &file_user_verifications_proto_msgTypes[13]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListUserVerificationsByUserIdReq.ProtoReflect.Descriptor instead.
func (*ListUserVerificationsByUserIdReq) Descriptor() ([]byte, []int) {
return file_user_verifications_proto_rawDescGZIP(), []int{13}
}
func (x *ListUserVerificationsByUserIdReq) GetUserId() int64 {
if x != nil {
return x.UserId
}
return 0
}
type ListUserVerificationsByUserIdResp struct {
state protoimpl.MessageState `protogen:"open.v1"`
UserVerifications []*UserVerifications `protobuf:"bytes,1,rep,name=userVerifications,proto3" json:"userVerifications,omitempty"` // userVerifications
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ListUserVerificationsByUserIdResp) Reset() {
*x = ListUserVerificationsByUserIdResp{}
mi := &file_user_verifications_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListUserVerificationsByUserIdResp) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListUserVerificationsByUserIdResp) ProtoMessage() {}
func (x *ListUserVerificationsByUserIdResp) ProtoReflect() protoreflect.Message {
mi := &file_user_verifications_proto_msgTypes[14]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListUserVerificationsByUserIdResp.ProtoReflect.Descriptor instead.
func (*ListUserVerificationsByUserIdResp) Descriptor() ([]byte, []int) {
return file_user_verifications_proto_rawDescGZIP(), []int{14}
}
func (x *ListUserVerificationsByUserIdResp) GetUserVerifications() []*UserVerifications {
if x != nil {
return x.UserVerifications
}
return nil
}
var File_user_verifications_proto protoreflect.FileDescriptor
const file_user_verifications_proto_rawDesc = "" +
@@ -863,13 +1055,25 @@ const file_user_verifications_proto_rawDesc = "" +
"\tcreatedAt\x18\v \x01(\x03R\tcreatedAt\x12\x1c\n" +
"\tupdatedAt\x18\f \x01(\x03R\tupdatedAt\"b\n" +
"\x1bSearchUserVerificationsResp\x12C\n" +
"\x11userVerifications\x18\x01 \x03(\v2\x15.pb.UserVerificationsR\x11userVerifications2\xd1\x03\n" +
"\x11userVerifications\x18\x01 \x03(\v2\x15.pb.UserVerificationsR\x11userVerifications\"i\n" +
"\x1fAddOrUpdateUserVerificationsReq\x12\x16\n" +
"\x06userId\x18\x01 \x01(\x03R\x06userId\x12\x12\n" +
"\x04role\x18\x02 \x01(\tR\x04role\x12\x1a\n" +
"\bmaterial\x18\x03 \x01(\tR\bmaterial\"<\n" +
" AddOrUpdateUserVerificationsResp\x12\x18\n" +
"\asuccess\x18\x01 \x01(\bR\asuccess\":\n" +
" ListUserVerificationsByUserIdReq\x12\x16\n" +
"\x06userId\x18\x01 \x01(\x03R\x06userId\"h\n" +
"!ListUserVerificationsByUserIdResp\x12C\n" +
"\x11userVerifications\x18\x01 \x03(\v2\x15.pb.UserVerificationsR\x11userVerifications2\xaa\x05\n" +
"\x12user_verifications\x12Q\n" +
"\x14AddUserVerifications\x12\x1b.pb.AddUserVerificationsReq\x1a\x1c.pb.AddUserVerificationsResp\x12Z\n" +
"\x17UpdateUserVerifications\x12\x1e.pb.UpdateUserVerificationsReq\x1a\x1f.pb.UpdateUserVerificationsResp\x12Q\n" +
"\x14DelUserVerifications\x12\x1b.pb.DelUserVerificationsReq\x1a\x1c.pb.DelUserVerificationsResp\x12]\n" +
"\x18GetUserVerificationsById\x12\x1f.pb.GetUserVerificationsByIdReq\x1a .pb.GetUserVerificationsByIdResp\x12Z\n" +
"\x17SearchUserVerifications\x12\x1e.pb.SearchUserVerificationsReq\x1a\x1f.pb.SearchUserVerificationsRespB\x06Z\x04./pbb\x06proto3"
"\x17SearchUserVerifications\x12\x1e.pb.SearchUserVerificationsReq\x1a\x1f.pb.SearchUserVerificationsResp\x12i\n" +
"\x1cAddOrUpdateUserVerifications\x12#.pb.AddOrUpdateUserVerificationsReq\x1a$.pb.AddOrUpdateUserVerificationsResp\x12l\n" +
"\x1dListUserVerificationsByUserId\x12$.pb.ListUserVerificationsByUserIdReq\x1a%.pb.ListUserVerificationsByUserIdRespB\x06Z\x04./pbb\x06proto3"
var (
file_user_verifications_proto_rawDescOnce sync.Once
@@ -883,38 +1087,47 @@ func file_user_verifications_proto_rawDescGZIP() []byte {
return file_user_verifications_proto_rawDescData
}
var file_user_verifications_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
var file_user_verifications_proto_msgTypes = make([]protoimpl.MessageInfo, 15)
var file_user_verifications_proto_goTypes = []any{
(*UserVerifications)(nil), // 0: pb.UserVerifications
(*AddUserVerificationsReq)(nil), // 1: pb.AddUserVerificationsReq
(*AddUserVerificationsResp)(nil), // 2: pb.AddUserVerificationsResp
(*UpdateUserVerificationsReq)(nil), // 3: pb.UpdateUserVerificationsReq
(*UpdateUserVerificationsResp)(nil), // 4: pb.UpdateUserVerificationsResp
(*DelUserVerificationsReq)(nil), // 5: pb.DelUserVerificationsReq
(*DelUserVerificationsResp)(nil), // 6: pb.DelUserVerificationsResp
(*GetUserVerificationsByIdReq)(nil), // 7: pb.GetUserVerificationsByIdReq
(*GetUserVerificationsByIdResp)(nil), // 8: pb.GetUserVerificationsByIdResp
(*SearchUserVerificationsReq)(nil), // 9: pb.SearchUserVerificationsReq
(*SearchUserVerificationsResp)(nil), // 10: pb.SearchUserVerificationsResp
(*UserVerifications)(nil), // 0: pb.UserVerifications
(*AddUserVerificationsReq)(nil), // 1: pb.AddUserVerificationsReq
(*AddUserVerificationsResp)(nil), // 2: pb.AddUserVerificationsResp
(*UpdateUserVerificationsReq)(nil), // 3: pb.UpdateUserVerificationsReq
(*UpdateUserVerificationsResp)(nil), // 4: pb.UpdateUserVerificationsResp
(*DelUserVerificationsReq)(nil), // 5: pb.DelUserVerificationsReq
(*DelUserVerificationsResp)(nil), // 6: pb.DelUserVerificationsResp
(*GetUserVerificationsByIdReq)(nil), // 7: pb.GetUserVerificationsByIdReq
(*GetUserVerificationsByIdResp)(nil), // 8: pb.GetUserVerificationsByIdResp
(*SearchUserVerificationsReq)(nil), // 9: pb.SearchUserVerificationsReq
(*SearchUserVerificationsResp)(nil), // 10: pb.SearchUserVerificationsResp
(*AddOrUpdateUserVerificationsReq)(nil), // 11: pb.AddOrUpdateUserVerificationsReq
(*AddOrUpdateUserVerificationsResp)(nil), // 12: pb.AddOrUpdateUserVerificationsResp
(*ListUserVerificationsByUserIdReq)(nil), // 13: pb.ListUserVerificationsByUserIdReq
(*ListUserVerificationsByUserIdResp)(nil), // 14: pb.ListUserVerificationsByUserIdResp
}
var file_user_verifications_proto_depIdxs = []int32{
0, // 0: pb.GetUserVerificationsByIdResp.userVerifications:type_name -> pb.UserVerifications
0, // 1: pb.SearchUserVerificationsResp.userVerifications:type_name -> pb.UserVerifications
1, // 2: pb.user_verifications.AddUserVerifications:input_type -> pb.AddUserVerificationsReq
3, // 3: pb.user_verifications.UpdateUserVerifications:input_type -> pb.UpdateUserVerificationsReq
5, // 4: pb.user_verifications.DelUserVerifications:input_type -> pb.DelUserVerificationsReq
7, // 5: pb.user_verifications.GetUserVerificationsById:input_type -> pb.GetUserVerificationsByIdReq
9, // 6: pb.user_verifications.SearchUserVerifications:input_type -> pb.SearchUserVerificationsReq
2, // 7: pb.user_verifications.AddUserVerifications:output_type -> pb.AddUserVerificationsResp
4, // 8: pb.user_verifications.UpdateUserVerifications:output_type -> pb.UpdateUserVerificationsResp
6, // 9: pb.user_verifications.DelUserVerifications:output_type -> pb.DelUserVerificationsResp
8, // 10: pb.user_verifications.GetUserVerificationsById:output_type -> pb.GetUserVerificationsByIdResp
10, // 11: pb.user_verifications.SearchUserVerifications:output_type -> pb.SearchUserVerificationsResp
7, // [7:12] is the sub-list for method output_type
2, // [2:7] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
0, // 2: pb.ListUserVerificationsByUserIdResp.userVerifications:type_name -> pb.UserVerifications
1, // 3: pb.user_verifications.AddUserVerifications:input_type -> pb.AddUserVerificationsReq
3, // 4: pb.user_verifications.UpdateUserVerifications:input_type -> pb.UpdateUserVerificationsReq
5, // 5: pb.user_verifications.DelUserVerifications:input_type -> pb.DelUserVerificationsReq
7, // 6: pb.user_verifications.GetUserVerificationsById:input_type -> pb.GetUserVerificationsByIdReq
9, // 7: pb.user_verifications.SearchUserVerifications:input_type -> pb.SearchUserVerificationsReq
11, // 8: pb.user_verifications.AddOrUpdateUserVerifications:input_type -> pb.AddOrUpdateUserVerificationsReq
13, // 9: pb.user_verifications.ListUserVerificationsByUserId:input_type -> pb.ListUserVerificationsByUserIdReq
2, // 10: pb.user_verifications.AddUserVerifications:output_type -> pb.AddUserVerificationsResp
4, // 11: pb.user_verifications.UpdateUserVerifications:output_type -> pb.UpdateUserVerificationsResp
6, // 12: pb.user_verifications.DelUserVerifications:output_type -> pb.DelUserVerificationsResp
8, // 13: pb.user_verifications.GetUserVerificationsById:output_type -> pb.GetUserVerificationsByIdResp
10, // 14: pb.user_verifications.SearchUserVerifications:output_type -> pb.SearchUserVerificationsResp
12, // 15: pb.user_verifications.AddOrUpdateUserVerifications:output_type -> pb.AddOrUpdateUserVerificationsResp
14, // 16: pb.user_verifications.ListUserVerificationsByUserId:output_type -> pb.ListUserVerificationsByUserIdResp
10, // [10:17] is the sub-list for method output_type
3, // [3:10] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
}
func init() { file_user_verifications_proto_init() }
@@ -929,7 +1142,7 @@ func file_user_verifications_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_user_verifications_proto_rawDesc), len(file_user_verifications_proto_rawDesc)),
NumEnums: 0,
NumMessages: 11,
NumMessages: 15,
NumExtensions: 0,
NumServices: 1,
},
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.6.1
// - protoc v3.19.4
// - protoc v5.29.6
// source: user_verifications.proto
package pb
@@ -19,11 +19,13 @@ import (
const _ = grpc.SupportPackageIsVersion9
const (
UserVerifications_AddUserVerifications_FullMethodName = "/pb.user_verifications/AddUserVerifications"
UserVerifications_UpdateUserVerifications_FullMethodName = "/pb.user_verifications/UpdateUserVerifications"
UserVerifications_DelUserVerifications_FullMethodName = "/pb.user_verifications/DelUserVerifications"
UserVerifications_GetUserVerificationsById_FullMethodName = "/pb.user_verifications/GetUserVerificationsById"
UserVerifications_SearchUserVerifications_FullMethodName = "/pb.user_verifications/SearchUserVerifications"
UserVerifications_AddUserVerifications_FullMethodName = "/pb.user_verifications/AddUserVerifications"
UserVerifications_UpdateUserVerifications_FullMethodName = "/pb.user_verifications/UpdateUserVerifications"
UserVerifications_DelUserVerifications_FullMethodName = "/pb.user_verifications/DelUserVerifications"
UserVerifications_GetUserVerificationsById_FullMethodName = "/pb.user_verifications/GetUserVerificationsById"
UserVerifications_SearchUserVerifications_FullMethodName = "/pb.user_verifications/SearchUserVerifications"
UserVerifications_AddOrUpdateUserVerifications_FullMethodName = "/pb.user_verifications/AddOrUpdateUserVerifications"
UserVerifications_ListUserVerificationsByUserId_FullMethodName = "/pb.user_verifications/ListUserVerificationsByUserId"
)
// UserVerificationsClient is the client API for UserVerifications service.
@@ -36,6 +38,8 @@ type UserVerificationsClient interface {
DelUserVerifications(ctx context.Context, in *DelUserVerificationsReq, opts ...grpc.CallOption) (*DelUserVerificationsResp, error)
GetUserVerificationsById(ctx context.Context, in *GetUserVerificationsByIdReq, opts ...grpc.CallOption) (*GetUserVerificationsByIdResp, error)
SearchUserVerifications(ctx context.Context, in *SearchUserVerificationsReq, opts ...grpc.CallOption) (*SearchUserVerificationsResp, error)
AddOrUpdateUserVerifications(ctx context.Context, in *AddOrUpdateUserVerificationsReq, opts ...grpc.CallOption) (*AddOrUpdateUserVerificationsResp, error)
ListUserVerificationsByUserId(ctx context.Context, in *ListUserVerificationsByUserIdReq, opts ...grpc.CallOption) (*ListUserVerificationsByUserIdResp, error)
}
type userVerificationsClient struct {
@@ -96,6 +100,26 @@ func (c *userVerificationsClient) SearchUserVerifications(ctx context.Context, i
return out, nil
}
func (c *userVerificationsClient) AddOrUpdateUserVerifications(ctx context.Context, in *AddOrUpdateUserVerificationsReq, opts ...grpc.CallOption) (*AddOrUpdateUserVerificationsResp, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(AddOrUpdateUserVerificationsResp)
err := c.cc.Invoke(ctx, UserVerifications_AddOrUpdateUserVerifications_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *userVerificationsClient) ListUserVerificationsByUserId(ctx context.Context, in *ListUserVerificationsByUserIdReq, opts ...grpc.CallOption) (*ListUserVerificationsByUserIdResp, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ListUserVerificationsByUserIdResp)
err := c.cc.Invoke(ctx, UserVerifications_ListUserVerificationsByUserId_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// UserVerificationsServer is the server API for UserVerifications service.
// All implementations must embed UnimplementedUserVerificationsServer
// for forward compatibility.
@@ -106,6 +130,8 @@ type UserVerificationsServer interface {
DelUserVerifications(context.Context, *DelUserVerificationsReq) (*DelUserVerificationsResp, error)
GetUserVerificationsById(context.Context, *GetUserVerificationsByIdReq) (*GetUserVerificationsByIdResp, error)
SearchUserVerifications(context.Context, *SearchUserVerificationsReq) (*SearchUserVerificationsResp, error)
AddOrUpdateUserVerifications(context.Context, *AddOrUpdateUserVerificationsReq) (*AddOrUpdateUserVerificationsResp, error)
ListUserVerificationsByUserId(context.Context, *ListUserVerificationsByUserIdReq) (*ListUserVerificationsByUserIdResp, error)
mustEmbedUnimplementedUserVerificationsServer()
}
@@ -131,6 +157,12 @@ func (UnimplementedUserVerificationsServer) GetUserVerificationsById(context.Con
func (UnimplementedUserVerificationsServer) SearchUserVerifications(context.Context, *SearchUserVerificationsReq) (*SearchUserVerificationsResp, error) {
return nil, status.Error(codes.Unimplemented, "method SearchUserVerifications not implemented")
}
func (UnimplementedUserVerificationsServer) AddOrUpdateUserVerifications(context.Context, *AddOrUpdateUserVerificationsReq) (*AddOrUpdateUserVerificationsResp, error) {
return nil, status.Error(codes.Unimplemented, "method AddOrUpdateUserVerifications not implemented")
}
func (UnimplementedUserVerificationsServer) ListUserVerificationsByUserId(context.Context, *ListUserVerificationsByUserIdReq) (*ListUserVerificationsByUserIdResp, error) {
return nil, status.Error(codes.Unimplemented, "method ListUserVerificationsByUserId not implemented")
}
func (UnimplementedUserVerificationsServer) mustEmbedUnimplementedUserVerificationsServer() {}
func (UnimplementedUserVerificationsServer) testEmbeddedByValue() {}
@@ -242,6 +274,42 @@ func _UserVerifications_SearchUserVerifications_Handler(srv interface{}, ctx con
return interceptor(ctx, in, info, handler)
}
func _UserVerifications_AddOrUpdateUserVerifications_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AddOrUpdateUserVerificationsReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(UserVerificationsServer).AddOrUpdateUserVerifications(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: UserVerifications_AddOrUpdateUserVerifications_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(UserVerificationsServer).AddOrUpdateUserVerifications(ctx, req.(*AddOrUpdateUserVerificationsReq))
}
return interceptor(ctx, in, info, handler)
}
func _UserVerifications_ListUserVerificationsByUserId_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListUserVerificationsByUserIdReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(UserVerificationsServer).ListUserVerificationsByUserId(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: UserVerifications_ListUserVerificationsByUserId_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(UserVerificationsServer).ListUserVerificationsByUserId(ctx, req.(*ListUserVerificationsByUserIdReq))
}
return interceptor(ctx, in, info, handler)
}
// UserVerifications_ServiceDesc is the grpc.ServiceDesc for UserVerifications service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@@ -269,6 +337,14 @@ var UserVerifications_ServiceDesc = grpc.ServiceDesc{
MethodName: "SearchUserVerifications",
Handler: _UserVerifications_SearchUserVerifications_Handler,
},
{
MethodName: "AddOrUpdateUserVerifications",
Handler: _UserVerifications_AddOrUpdateUserVerifications_Handler,
},
{
MethodName: "ListUserVerificationsByUserId",
Handler: _UserVerifications_ListUserVerificationsByUserId_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "user_verifications.proto",
@@ -14,17 +14,21 @@ import (
)
type (
AddUserVerificationsReq = pb.AddUserVerificationsReq
AddUserVerificationsResp = pb.AddUserVerificationsResp
DelUserVerificationsReq = pb.DelUserVerificationsReq
DelUserVerificationsResp = pb.DelUserVerificationsResp
GetUserVerificationsByIdReq = pb.GetUserVerificationsByIdReq
GetUserVerificationsByIdResp = pb.GetUserVerificationsByIdResp
SearchUserVerificationsReq = pb.SearchUserVerificationsReq
SearchUserVerificationsResp = pb.SearchUserVerificationsResp
UpdateUserVerificationsReq = pb.UpdateUserVerificationsReq
UpdateUserVerificationsResp = pb.UpdateUserVerificationsResp
UserVerifications = pb.UserVerifications
AddOrUpdateUserVerificationsReq = pb.AddOrUpdateUserVerificationsReq
AddOrUpdateUserVerificationsResp = pb.AddOrUpdateUserVerificationsResp
AddUserVerificationsReq = pb.AddUserVerificationsReq
AddUserVerificationsResp = pb.AddUserVerificationsResp
DelUserVerificationsReq = pb.DelUserVerificationsReq
DelUserVerificationsResp = pb.DelUserVerificationsResp
GetUserVerificationsByIdReq = pb.GetUserVerificationsByIdReq
GetUserVerificationsByIdResp = pb.GetUserVerificationsByIdResp
ListUserVerificationsByUserIdReq = pb.ListUserVerificationsByUserIdReq
ListUserVerificationsByUserIdResp = pb.ListUserVerificationsByUserIdResp
SearchUserVerificationsReq = pb.SearchUserVerificationsReq
SearchUserVerificationsResp = pb.SearchUserVerificationsResp
UpdateUserVerificationsReq = pb.UpdateUserVerificationsReq
UpdateUserVerificationsResp = pb.UpdateUserVerificationsResp
UserVerifications = pb.UserVerifications
UserVerificationsZrpcClient interface {
// -----------------------userVerifications-----------------------
@@ -33,6 +37,8 @@ type (
DelUserVerifications(ctx context.Context, in *DelUserVerificationsReq, opts ...grpc.CallOption) (*DelUserVerificationsResp, error)
GetUserVerificationsById(ctx context.Context, in *GetUserVerificationsByIdReq, opts ...grpc.CallOption) (*GetUserVerificationsByIdResp, error)
SearchUserVerifications(ctx context.Context, in *SearchUserVerificationsReq, opts ...grpc.CallOption) (*SearchUserVerificationsResp, error)
AddOrUpdateUserVerifications(ctx context.Context, in *AddOrUpdateUserVerificationsReq, opts ...grpc.CallOption) (*AddOrUpdateUserVerificationsResp, error)
ListUserVerificationsByUserId(ctx context.Context, in *ListUserVerificationsByUserIdReq, opts ...grpc.CallOption) (*ListUserVerificationsByUserIdResp, error)
}
defaultUserVerificationsZrpcClient struct {
@@ -71,3 +77,13 @@ func (m *defaultUserVerificationsZrpcClient) SearchUserVerifications(ctx context
client := pb.NewUserVerificationsClient(m.cli.Conn())
return client.SearchUserVerifications(ctx, in, opts...)
}
func (m *defaultUserVerificationsZrpcClient) AddOrUpdateUserVerifications(ctx context.Context, in *AddOrUpdateUserVerificationsReq, opts ...grpc.CallOption) (*AddOrUpdateUserVerificationsResp, error) {
client := pb.NewUserVerificationsClient(m.cli.Conn())
return client.AddOrUpdateUserVerifications(ctx, in, opts...)
}
func (m *defaultUserVerificationsZrpcClient) ListUserVerificationsByUserId(ctx context.Context, in *ListUserVerificationsByUserIdReq, opts ...grpc.CallOption) (*ListUserVerificationsByUserIdResp, error) {
client := pb.NewUserVerificationsClient(m.cli.Conn())
return client.ListUserVerificationsByUserId(ctx, in, opts...)
}
-601
View File
@@ -1,601 +0,0 @@
# JWT 集成指南
指导如何将 JWT Manager 集成到 RPC Handlers 和业务逻辑中。
## 1. gRPC Unary Interceptor 实现
在 RPC 服务中添加 JWT 验证拦截器。
### 创建拦截器
创建文件 [app/users/rpc/internal/interceptor/jwt_interceptor.go](../../../app/users/rpc/internal/interceptor/jwt_interceptor.go)
```go
package interceptor
import (
"context"
"log"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"yourmodule/app/users/rpc/internal/svc"
)
// JwtUnaryInterceptor 验证 gRPC 请求中的 JWT 令牌
func JwtUnaryInterceptor(svcCtx *svc.ServiceContext) grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
// 获取请求元数据
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return nil, status.Error(codes.Unauthenticated, "missing metadata")
}
// 从 Authorization 头提取令牌
tokens := md.Get("authorization")
if len(tokens) == 0 {
return nil, status.Error(codes.Unauthenticated, "missing authorization header")
}
token := tokens[0]
// 验证令牌
claims, err := svcCtx.JwtManager.Valid(ctx, token)
if err != nil {
log.Printf("Token validation failed: %v", err)
// 尝试刷新令牌(如果过期但仍在 Redis 中)
newToken, refreshErr := svcCtx.JwtManager.Renew(ctx, token)
if refreshErr == nil && newToken != "" {
// 在响应头中返回新令牌
grpc.SetHeader(ctx, metadata.Pairs("authorization", newToken))
// 继续处理请求,使用原令牌的声明
// 注意:实际应用中需要重新验证新令牌
newClaims, err := svcCtx.JwtManager.Valid(ctx, newToken)
if err != nil {
return nil, status.Error(codes.Unauthenticated, "token refresh failed")
}
claims = newClaims
} else {
return nil, status.Error(codes.Unauthenticated, "invalid or expired token")
}
}
// 将声明附加到上下文,供处理器使用
newCtx := context.WithValue(ctx, "claims", claims)
return handler(newCtx, req)
}
}
// JwtStreamInterceptor 验证流式 gRPC 请求中的 JWT 令牌
func JwtStreamInterceptor(svcCtx *svc.ServiceContext) grpc.StreamServerInterceptor {
return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
md, ok := metadata.FromIncomingContext(ss.Context())
if !ok {
return status.Error(codes.Unauthenticated, "missing metadata")
}
tokens := md.Get("authorization")
if len(tokens) == 0 {
return status.Error(codes.Unauthenticated, "missing authorization header")
}
token := tokens[0]
claims, err := svcCtx.JwtManager.Valid(ss.Context(), token)
if err != nil {
return status.Error(codes.Unauthenticated, "invalid token")
}
// 创建包装流以注入上下文
wrappedStream := &WrappedStream{
ServerStream: ss,
ctx: context.WithValue(ss.Context(), "claims", claims),
}
return handler(srv, wrappedStream)
}
}
// WrappedStream 包装 grpc.ServerStream 以注入新的上下文
type WrappedStream struct {
grpc.ServerStream
ctx context.Context
}
func (w *WrappedStream) Context() context.Context {
return w.ctx
}
```
### 在 Server 中注册拦截器
修改 [app/users/rpc/usercenter/usercenter.go](../../../app/users/rpc/usercenter/usercenter.go)
```go
package main
import (
"flag"
"fmt"
"log"
"yourmodule/app/users/rpc/internal/config"
"yourmodule/app/users/rpc/internal/interceptor"
"yourmodule/app/users/rpc/internal/server"
"yourmodule/app/users/rpc/internal/svc"
"yourmodule/app/users/rpc/pb"
"github.com/zeromicro/go-zero/core/conf"
"github.com/zeromicro/go-zero/core/logx"
"google.golang.org/grpc"
)
var configFile = flag.String("f", "etc/pb.yaml", "the config file")
func main() {
flag.Parse()
var c config.Config
conf.MustLoad(*configFile, &c)
ctx := svc.NewServiceContext(c)
logx.DisableStat()
s := grpc.NewServer(
grpc.UnaryInterceptor(interceptor.JwtUnaryInterceptor(ctx)),
grpc.StreamInterceptor(interceptor.JwtStreamInterceptor(ctx)),
)
pb.RegisterUsercenterServer(s, server.NewUsercenterServer(ctx))
logx.Infof("Starting gRPC server on %s:%d", c.Host, c.Port)
if err := s.Serve(net.Listen("tcp", "0.0.0.0:"+fmt.Sprintf("%d", c.Port))); err != nil {
logx.Error(err)
}
}
```
## 2. 登录 Handler 实现
实现 [app/users/api/internal/handler/user/loginHandler.go](../../../app/users/api/internal/handler/user/loginHandler.go)
```go
package user
import (
"context"
"log"
"net/http"
"yourmodule/app/users/api/internal/logic/user"
"yourmodule/app/users/api/internal/svc"
"yourmodule/app/users/api/internal/types"
)
// LoginHandler 处理用户登录
func LoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.LoginRequest
// 解析请求体...
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request", http.StatusBadRequest)
return
}
// 调用业务逻辑
resp, err := user.NewLoginLogic(r.Context(), svcCtx).Login(&req)
if err != nil {
log.Printf("Login failed: %v", err)
http.Error(w, "Login failed", http.StatusUnauthorized)
return
}
// 返回令牌
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(resp)
}
}
```
实现 [app/users/api/internal/logic/user/loginLogic.go](../../../app/users/api/internal/logic/user/loginLogic.go)
```go
package user
import (
"context"
"errors"
"yourmodule/app/users/api/internal/svc"
"yourmodule/app/users/api/internal/types"
)
type LoginLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic {
return &LoginLogic{
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *LoginLogic) Login(req *types.LoginRequest) (*types.LoginResponse, error) {
// 1. 验证用户凭证(密码等)
user, err := l.svcCtx.UserModel.FindByEmail(l.ctx, req.Email)
if err != nil {
return nil, errors.New("user not found")
}
// 2. 验证密码
if !user.VerifyPassword(req.Password) {
return nil, errors.New("invalid password")
}
// 3. 生成 JWT 令牌
token, err := l.svcCtx.JwtManager.New(
l.ctx,
user.ID,
user.Email,
user.Name,
)
if err != nil {
return nil, errors.New("failed to generate token")
}
// 4. 返回令牌
return &types.LoginResponse{
Token: token,
User: types.User{
ID: user.ID,
Email: user.Email,
Name: user.Name,
},
}, nil
}
```
## 3. 在 Handlers 中使用声明
在 Protected Handlers 中提取并使用声明:
```go
package user
import (
"context"
"log"
"net/http"
"yourmodule/app/users/api/internal/svc"
"yourmodule/app/users/api/internal/types"
"github.com/golang-jwt/jwt/v4"
)
// GetUserInfoHandler 获取当前用户信息
func GetUserInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// 从上下文提取声明(由拦截器设置)
claims, ok := r.Context().Value("claims").(*jwt.RegisteredClaims)
if !ok {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
// 使用声明中的用户信息
userID := claims.Subject // 用户 ID 存储在 Subject 中
log.Printf("User %s requested their info", userID)
// 查询用户信息
user, err := svcCtx.UserModel.FindByID(r.Context(), userID)
if err != nil {
http.Error(w, "User not found", http.StatusNotFound)
return
}
// 返回用户信息
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(user)
}
}
```
## 4. 令牌刷新端点
实现令牌刷新端点:
```go
package user
import (
"net/http"
"yourmodule/app/users/api/internal/svc"
"yourmodule/app/users/api/internal/types"
)
// RefreshTokenHandler 刷新过期的 JWT 令牌
func RefreshTokenHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.RefreshTokenRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request", http.StatusBadRequest)
return
}
// 提取旧令牌
oldToken := req.Token
// 尝试刷新令牌
newToken, err := svcCtx.JwtManager.Renew(r.Context(), oldToken)
if err != nil {
http.Error(w, "Token refresh failed", http.StatusUnauthorized)
return
}
// 返回新令牌
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(types.RefreshTokenResponse{
Token: newToken,
})
}
}
```
## 5. 登出处理
实现登出端点以撤销令牌:
```go
package user
import (
"net/http"
"yourmodule/app/users/api/internal/svc"
)
// LogoutHandler 登出用户(撤销令牌)
func LogoutHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// 从上下文提取声明
claims, ok := r.Context().Value("claims").(*jwt.RegisteredClaims)
if !ok {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
userID := claims.Subject
// 获取用户当前令牌
currentToken := r.Header.Get("Authorization")
// 撤销令牌
err := svcCtx.JwtManager.Revoke(r.Context(), userID, currentToken)
if err != nil {
http.Error(w, "Logout failed", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{"message": "logged out successfully"})
}
}
```
## 6. 特定端点的 JWT 验证
对于 REST API,在需要的 handlers 中手动验证令牌:
### 在 Routes 中配置
修改 [app/users/api/internal/handler/routes.go](../../../app/users/api/internal/handler/routes.go)
```go
package handler
import (
"net/http"
"yourmodule/app/users/api/internal/middleware"
"yourmodule/app/users/api/internal/svc"
"yourmodule/app/users/api/internal/handler/user"
)
// RegisterRoutes 注册所有路由
func RegisterRoutes(router *http.ServeMux, svcCtx *svc.ServiceContext) {
// 公开路由
router.HandleFunc("POST /api/v1/auth/login", user.LoginHandler(svcCtx))
router.HandleFunc("POST /api/v1/auth/refresh", user.RefreshTokenHandler(svcCtx))
// 受保护的路由(需要 JWT 验证)
protected := middleware.JwtMiddleware(svcCtx)
router.HandleFunc("GET /api/v1/users/me", protected(user.GetUserInfoHandler(svcCtx)))
router.HandleFunc("POST /api/v1/users/logout", protected(user.LogoutHandler(svcCtx)))
router.HandleFunc("PUT /api/v1/users/me", protected(user.UpdateUserInfoHandler(svcCtx)))
}
```
### 创建 JWT 中间件
创建 [app/users/api/internal/middleware/jwt.go](../../../app/users/api/internal/middleware/jwt.go)
```go
package middleware
import (
"context"
"net/http"
"strings"
"yourmodule/app/users/api/internal/svc"
)
// JwtMiddleware 为 HTTP 处理器添加 JWT 验证
func JwtMiddleware(svcCtx *svc.ServiceContext) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 从 Authorization 头提取令牌
authHeader := r.Header.Get("Authorization")
if authHeader == "" {
http.Error(w, "Missing authorization header", http.StatusUnauthorized)
return
}
// 期望格式: "Bearer <token>"
parts := strings.SplitN(authHeader, " ", 2)
if len(parts) != 2 || parts[0] != "Bearer" {
http.Error(w, "Invalid authorization header", http.StatusUnauthorized)
return
}
token := parts[1]
// 验证令牌
claims, err := svcCtx.JwtManager.Valid(r.Context(), token)
if err != nil {
// 尝试刷新
newToken, refreshErr := svcCtx.JwtManager.Renew(r.Context(), token)
if refreshErr != nil {
http.Error(w, "Invalid or expired token", http.StatusUnauthorized)
return
}
// 在响应头返回新令牌
w.Header().Set("X-New-Token", newToken)
// 重新验证新令牌
claims, err = svcCtx.JwtManager.Valid(r.Context(), newToken)
if err != nil {
http.Error(w, "Token refresh failed", http.StatusUnauthorized)
return
}
}
// 将声明附加到上下文
newCtx := context.WithValue(r.Context(), "claims", claims)
next.ServeHTTP(w, r.WithContext(newCtx))
})
}
}
```
## 7. 错误处理最佳实践
```go
package logic
import (
"errors"
"log"
"yourmodule/app/users/rpc/internal/utils"
)
// HandleJwtError 处理 JWT 相关错误
func HandleJwtError(err error) error {
if errors.Is(err, utils.ErrTokenExpired) {
log.Println("Token has expired, user needs to refresh")
return errors.New("token expired - use refresh endpoint")
}
if errors.Is(err, utils.ErrTokenInvalid) {
log.Println("Token is invalid or malformed")
return errors.New("invalid token")
}
if errors.Is(err, utils.ErrTokenNotFound) {
log.Println("Token not found in Redis (revoked or expired)")
return errors.New("token revoked or expired")
}
return err
}
```
## 8. 测试 JWT 集成
### 单元测试示例
```go
package interceptor
import (
"context"
"testing"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
)
func TestJwtUnaryInterceptor_ValidToken(t *testing.T) {
// 1. 创建有效的令牌
token, err := svcCtx.JwtManager.New(context.Background(), "user123", "user@example.com", "John")
if err != nil {
t.Fatalf("Failed to create token: %v", err)
}
// 2. 创建包含令牌的上下文
md := metadata.Pairs("authorization", token)
ctx := metadata.NewIncomingContext(context.Background(), md)
// 3. 调用拦截器
_, err = JwtUnaryInterceptor(svcCtx)(ctx, nil, nil, func(ctx context.Context, req interface{}) (interface{}, error) {
return "success", nil
})
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
}
func TestJwtUnaryInterceptor_ExpiredToken(t *testing.T) {
// 1. 创建过期的令牌或使用无效令牌
token := "invalid.token.here"
// 2. 创建包含令牌的上下文
md := metadata.Pairs("authorization", token)
ctx := metadata.NewIncomingContext(context.Background(), md)
// 3. 调用拦截器
_, err := JwtUnaryInterceptor(svcCtx)(ctx, nil, nil, func(ctx context.Context, req interface{}) (interface{}, error) {
return "success", nil
})
// 4. 验证错误
st, ok := status.FromError(err)
if !ok || st.Code() != codes.Unauthenticated {
t.Errorf("Expected Unauthenticated error, got: %v", err)
}
}
```
## 9. 生产部署清单
在将 JWT 集成部署到生产环境前:
- [ ] 所有令牌端点都进行了压力测试
- [ ] 令牌刷新逻辑已验证
- [ ] 错误处理覆盖了所有 JWT 失败情况
- [ ] 审计日志记录了所有认证尝试
- [ ] 密钥轮换计划已确定
- [ ] 监控和告警已配置
- [ ] 灾难恢复流程已文档化
- [ ] 所有依赖于 JWT 的服务都已更新
## 相关文件
- [app/users/rpc/internal/utils/jwt.go](../../../app/users/rpc/internal/utils/jwt.go) - JWT Manager 实现
- [app/users/rpc/internal/config/config.go](../../../app/users/rpc/internal/config/config.go) - JWT 配置
- [app/users/rpc/internal/svc/serviceContext.go](../../../app/users/rpc/internal/svc/serviceContext.go) - 依赖注入
- [deploy/k8s/secrets/jwt-secret.yaml](./jwt-secret.yaml) - Secret 和 RBAC
- [deploy/k8s/secrets/DEPLOYMENT.md](./DEPLOYMENT.md) - 部署指南
+14 -4
View File
@@ -7,9 +7,19 @@ Prometheus:
Port: 4001
Path: /metrics
# ===== PROC CONFIG =====
#UsercenterRpcConf:
# Target: k8s://juwan/user-rpc-svc:8080
#UserVerificationRpc:
# Target: k8s://juwan/user_verifications-svc:8080
SnowflakeRpcConf:
Target: k8s://juwan/snowflake-svc:8080
# ===== DEV CONFIG ====
UserVerificationRpc:
Target: k8s://juwan/user_verifications-svc:8080
Endpoints:
- user-verifications-rpc:8080
UsercenterRpcConf:
Endpoints:
- user-rpc:8080
Log:
Level: debug
+14 -17
View File
@@ -146,23 +146,20 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
)
server.AddRoutes(
rest.WithMiddlewares(
[]rest.Middleware{serverCtx.Logger},
[]rest.Route{
{
// 提交或修改角色认证申请 (支持幂等更新)
Method: http.MethodPost,
Path: "/me/verification",
Handler: verification_user.ApplyVerificationHandler(serverCtx),
},
{
// 获取我的所有认证状态
Method: http.MethodGet,
Path: "/me/verification",
Handler: verification_user.GetMyVerificationsHandler(serverCtx),
},
}...,
),
[]rest.Route{
{
// 提交或修改角色认证申请 (支持幂等更新)
Method: http.MethodPost,
Path: "/me/verification",
Handler: verification_user.ApplyVerificationHandler(serverCtx),
},
{
// 获取我的所有认证状态
Method: http.MethodGet,
Path: "/me/verification",
Handler: verification_user.GetMyVerificationsHandler(serverCtx),
},
},
rest.WithPrefix("/api/v1/users"),
)
}
@@ -6,6 +6,7 @@ package auth
import (
"context"
"errors"
"fmt"
"juwan-backend/app/users/rpc/pb"
"juwan-backend/app/users/rpc/usercenter"
"juwan-backend/common/utils/contextj"
@@ -57,7 +58,8 @@ func (l *RegisterLogic) Register(req *types.RegisterReq) (resp *types.RegisterRe
return nil, errors.New("hash password failed")
}
requestId, err := contextj.RequestIdFrom(l.ctx)
requestId, err := contextj.RIdFrom(l.ctx)
logx.Infof("requestId: %s", requestId)
if err != nil {
logx.Errorf("contextj.RequestIdFrom failed: %v", err)
return nil, errors.New("contextj.RequestIdFrom failed")
@@ -73,7 +75,7 @@ func (l *RegisterLogic) Register(req *types.RegisterReq) (resp *types.RegisterRe
})
if err != nil {
logx.Error("failed to register user: ", err)
return nil, errors.New("failed to register user")
return nil, errors.New(fmt.Sprintf("failed to register user: %v", err.Error()))
}
// 返回响应
@@ -5,6 +5,9 @@ package user
import (
"context"
"errors"
"juwan-backend/app/users/rpc/usercenter"
"juwan-backend/common/utils/contextj"
"juwan-backend/app/users/api/internal/svc"
"juwan-backend/app/users/api/internal/types"
@@ -29,6 +32,19 @@ func NewFollowUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Follow
func (l *FollowUserLogic) FollowUser(req *types.FollowUserReq) (resp *types.EmptyResp, err error) {
// todo: add your logic here and delete this line
userId, err := contextj.UserIDFrom(l.ctx)
if err != nil {
return nil, errors.New("unauthorized")
}
return
_, err = l.svcCtx.UserRpc.AddUserFollows(l.ctx, &usercenter.AddUserFollowsReq{
FollowerId: userId,
FolloweeId: req.Id,
CreatedAt: 0,
})
if err != nil {
logx.Errorf("add user follow err: %v", err)
return nil, errors.New("failed to follow user")
}
return &types.EmptyResp{}, nil
}
+25 -10
View File
@@ -6,15 +6,15 @@ package user
import (
"context"
"errors"
"juwan-backend/app/users/api/internal/svc"
"juwan-backend/app/users/api/internal/types"
"juwan-backend/app/users/rpc/usercenter"
"juwan-backend/common/converter"
"juwan-backend/common/utils/contextj"
"time"
"juwan-backend/app/users/api/internal/svc"
"juwan-backend/app/users/api/internal/types"
"github.com/jinzhu/copier"
"github.com/zeromicro/go-zero/core/logx"
"k8s.io/apimachinery/pkg/util/json"
)
type GetMeLogic struct {
@@ -35,19 +35,34 @@ func NewGetMeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetMeLogic
func (l *GetMeLogic) GetMe() (resp *types.User, err error) {
userId, err := contextj.UserIDFrom(l.ctx)
if err != nil {
return nil, errors.New("illegal id")
logx.Errorf("get user id from context: %v", err)
return nil, errors.New("illegal user")
}
user, err := l.svcCtx.UserRpc.GetUsersById(l.ctx, &usercenter.GetUsersByIdReq{
Id: userId,
})
if err != nil {
return nil, errors.New("get user by id error")
logx.Errorf("GetMeLogic.GetUsersById err: %v", err)
return nil, errors.New("get user failed")
}
err = converter.StructToStruct(user, &resp)
createAt := time.Unix(user.Users.CreatedAt, 0)
resp.CreatedAt = createAt.Format(time.DateTime)
logx.Debugf("get user resp: %+v", user)
resp = &types.User{}
err = copier.Copy(&resp, user.Users)
if err != nil {
return nil, errors.New("to struct error")
logx.Errorf("copier.Copy err: %v", err)
return nil, errors.New("copy user failed")
}
var verificationStatus map[string]string
err = json.Unmarshal([]byte(user.Users.VerificationStatus), &verificationStatus)
if err != nil {
logx.Errorf("json.Unmarshal err: %v", err)
}
resp.VerifiedRoles = user.Users.VerifiedRoles
resp.VerificationStatus = verificationStatus
resp.CreatedAt = time.Unix(user.Users.CreatedAt, 0).Format(time.DateTime)
return
}
@@ -32,7 +32,6 @@ func NewSwitchRoleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Switch
}
func (l *SwitchRoleLogic) SwitchRole(req *types.SwitchRoleReq) (resp *types.EmptyResp, err error) {
// todo: add your logic here and delete this line
id, err := contextj.UserIDFrom(l.ctx)
if err != nil {
logx.Errorf("get user id from context: %v", err)

Some files were not shown because too many files have changed in this diff Show More