1、新增自定义用户私人价格2、优化api服务鉴权缓存3、新增管理员端对公充值

This commit is contained in:
2024-10-21 16:01:20 +08:00
parent 8896fd6b30
commit 2292d25d74
37 changed files with 1903 additions and 907 deletions

View File

@@ -43,8 +43,10 @@ type (
UpdateWhitelistRequest = sentinel.UpdateWhitelistRequest
UserProductEmptyResponse = sentinel.UserProductEmptyResponse
UserProductItem = sentinel.UserProductItem
UserProductPageListResponse = sentinel.UserProductPageListResponse
UserProductResponse = sentinel.UserProductResponse
UserProuctPageListRequest = sentinel.UserProuctPageListRequest
UserProuctRequest = sentinel.UserProuctRequest
WhitePageListRequest = sentinel.WhitePageListRequest
Whitelist = sentinel.Whitelist
WhitelistResponse = sentinel.WhitelistResponse

View File

@@ -43,8 +43,10 @@ type (
UpdateWhitelistRequest = sentinel.UpdateWhitelistRequest
UserProductEmptyResponse = sentinel.UserProductEmptyResponse
UserProductItem = sentinel.UserProductItem
UserProductPageListResponse = sentinel.UserProductPageListResponse
UserProductResponse = sentinel.UserProductResponse
UserProuctPageListRequest = sentinel.UserProuctPageListRequest
UserProuctRequest = sentinel.UserProuctRequest
WhitePageListRequest = sentinel.WhitePageListRequest
Whitelist = sentinel.Whitelist
WhitelistResponse = sentinel.WhitelistResponse

View File

@@ -43,8 +43,10 @@ type (
UpdateWhitelistRequest = sentinel.UpdateWhitelistRequest
UserProductEmptyResponse = sentinel.UserProductEmptyResponse
UserProductItem = sentinel.UserProductItem
UserProductPageListResponse = sentinel.UserProductPageListResponse
UserProductResponse = sentinel.UserProductResponse
UserProuctPageListRequest = sentinel.UserProuctPageListRequest
UserProuctRequest = sentinel.UserProuctRequest
WhitePageListRequest = sentinel.WhitePageListRequest
Whitelist = sentinel.Whitelist
WhitelistResponse = sentinel.WhitelistResponse

View File

@@ -43,8 +43,10 @@ type (
UpdateWhitelistRequest = sentinel.UpdateWhitelistRequest
UserProductEmptyResponse = sentinel.UserProductEmptyResponse
UserProductItem = sentinel.UserProductItem
UserProductPageListResponse = sentinel.UserProductPageListResponse
UserProductResponse = sentinel.UserProductResponse
UserProuctPageListRequest = sentinel.UserProuctPageListRequest
UserProuctRequest = sentinel.UserProuctRequest
WhitePageListRequest = sentinel.WhitePageListRequest
Whitelist = sentinel.Whitelist
WhitelistResponse = sentinel.WhitelistResponse
@@ -52,7 +54,8 @@ type (
UserProduct interface {
// UserProduct methods
CreateUserProduct(ctx context.Context, in *CreateUserProductRequest, opts ...grpc.CallOption) (*UserProductEmptyResponse, error)
GetUserProductPageList(ctx context.Context, in *UserProuctPageListRequest, opts ...grpc.CallOption) (*UserProductResponse, error)
GetUserProductPageList(ctx context.Context, in *UserProuctPageListRequest, opts ...grpc.CallOption) (*UserProductPageListResponse, error)
GetUserProduct(ctx context.Context, in *UserProuctRequest, opts ...grpc.CallOption) (*UserProductResponse, error)
MatchingUserIdProductCode(ctx context.Context, in *MatchingUserIdProductCodeRequest, opts ...grpc.CallOption) (*MatchResponse, error)
}
@@ -73,11 +76,16 @@ func (m *defaultUserProduct) CreateUserProduct(ctx context.Context, in *CreateUs
return client.CreateUserProduct(ctx, in, opts...)
}
func (m *defaultUserProduct) GetUserProductPageList(ctx context.Context, in *UserProuctPageListRequest, opts ...grpc.CallOption) (*UserProductResponse, error) {
func (m *defaultUserProduct) GetUserProductPageList(ctx context.Context, in *UserProuctPageListRequest, opts ...grpc.CallOption) (*UserProductPageListResponse, error) {
client := sentinel.NewUserProductClient(m.cli.Conn())
return client.GetUserProductPageList(ctx, in, opts...)
}
func (m *defaultUserProduct) GetUserProduct(ctx context.Context, in *UserProuctRequest, opts ...grpc.CallOption) (*UserProductResponse, error) {
client := sentinel.NewUserProductClient(m.cli.Conn())
return client.GetUserProduct(ctx, in, opts...)
}
func (m *defaultUserProduct) MatchingUserIdProductCode(ctx context.Context, in *MatchingUserIdProductCodeRequest, opts ...grpc.CallOption) (*MatchResponse, error) {
client := sentinel.NewUserProductClient(m.cli.Conn())
return client.MatchingUserIdProductCode(ctx, in, opts...)

View File

@@ -43,8 +43,10 @@ type (
UpdateWhitelistRequest = sentinel.UpdateWhitelistRequest
UserProductEmptyResponse = sentinel.UserProductEmptyResponse
UserProductItem = sentinel.UserProductItem
UserProductPageListResponse = sentinel.UserProductPageListResponse
UserProductResponse = sentinel.UserProductResponse
UserProuctPageListRequest = sentinel.UserProuctPageListRequest
UserProuctRequest = sentinel.UserProuctRequest
WhitePageListRequest = sentinel.WhitePageListRequest
Whitelist = sentinel.Whitelist
WhitelistResponse = sentinel.WhitelistResponse

View File

@@ -34,7 +34,11 @@ func (l *CreateUserProductLogic) CreateUserProduct(in *sentinel.CreateUserProduc
if isExist {
return nil, errors.New("该产品已定阅读,无法重复订阅")
}
_, err = l.svcCtx.UserProductsModel.Insert(l.ctx, &model.UserProducts{UserId: in.UserId, ProductId: in.ProductId})
product, err := l.svcCtx.ProductsModel.FindOne(l.ctx, in.ProductId)
if err != nil {
return nil, err
}
_, err = l.svcCtx.UserProductsModel.Insert(l.ctx, &model.UserProducts{UserId: in.UserId, ProductId: in.ProductId, ProductPrice: product.ProductPrice})
if err != nil {
return nil, err
}

View File

@@ -0,0 +1,38 @@
package userproductlogic
import (
"context"
"tianyuan-api/apps/sentinel/internal/svc"
"tianyuan-api/apps/sentinel/sentinel"
"github.com/zeromicro/go-zero/core/logx"
)
type GetUserProductLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewGetUserProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserProductLogic {
return &GetUserProductLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
func (l *GetUserProductLogic) GetUserProduct(in *sentinel.UserProuctRequest) (*sentinel.UserProductResponse, error) {
userProduct, err := l.svcCtx.UserProductsModel.FindOneUserProduct(l.ctx, in.UserId, in.ProductId)
if err != nil {
return nil, err
}
return &sentinel.UserProductResponse{
Id: userProduct.Id,
UserId: userProduct.UserId,
ProductId: userProduct.ProductId,
ProductPrice: userProduct.ProductPrice,
}, nil
}

View File

@@ -25,7 +25,7 @@ func NewGetUserProductPageListLogic(ctx context.Context, svcCtx *svc.ServiceCont
}
}
func (l *GetUserProductPageListLogic) GetUserProductPageList(in *sentinel.UserProuctPageListRequest) (*sentinel.UserProductResponse, error) {
func (l *GetUserProductPageListLogic) GetUserProductPageList(in *sentinel.UserProuctPageListRequest) (*sentinel.UserProductPageListResponse, error) {
list, total, err := l.svcCtx.UserProductsModel.FindUserProductsList(l.ctx, in.UserId, in.Page, in.PageSize)
if err != nil {
return nil, err
@@ -45,7 +45,7 @@ func (l *GetUserProductPageListLogic) GetUserProductPageList(in *sentinel.UserPr
UpdatedAt: up.UpdatedAt.Format("2006-01-02 15:04:05"),
})
}
return &sentinel.UserProductResponse{
return &sentinel.UserProductPageListResponse{
Total: total,
UserProducts: userProducts,
}, nil

View File

@@ -61,7 +61,7 @@ func (m *defaultUserProductsModel) FindUserProductsList(ctx context.Context, use
p.product_code,
COALESCE(p.product_description, '') AS product_description,
p.product_group,
p.product_price,
up.product_price,
up.created_at,
up.updated_at
FROM user_products up
@@ -87,26 +87,11 @@ func (m *defaultUserProductsModel) FindUserProductsList(ctx context.Context, use
return userProducts, total, nil
}
func (m *customUserProductsModel) FindOneUserProduct(ctx context.Context, userId, productId int64) (*UserProducts, error) {
// 定义 Redis 缓存 Set 键
redisKey := fmt.Sprintf("user_products:%d", userId)
// 检查 Redis Set 中是否存在用户与产品的关联
isMember, err := m.rds.SismemberCtx(ctx, redisKey, productId)
if err == nil && isMember {
// 如果 Redis Set 中存在,返回空,因为不需要重复查询
return nil, nil
}
var userProduct UserProducts
query := fmt.Sprintf("SELECT %s FROM %s WHERE `user_id` = ? AND `product_id` = ? LIMIT 1", userProductsRows, m.table)
err = m.QueryRowNoCacheCtx(ctx, &userProduct, query, userId, productId)
err := m.QueryRowNoCacheCtx(ctx, &userProduct, query, userId, productId)
switch err {
case nil:
// 将用户产品的关联写入 Redis Set
_, err = m.rds.SaddCtx(ctx, redisKey, productId)
if err != nil {
return nil, err
}
return &userProduct, nil
case sqlc.ErrNotFound:
// 返回未找到的错误

View File

@@ -41,11 +41,12 @@ type (
}
UserProducts struct {
Id int64 `db:"id"` // 用户产品ID
UserId int64 `db:"user_id"` // 用户ID
ProductId int64 `db:"product_id"` // 产品ID
CreatedAt time.Time `db:"created_at"` // 创建时间
UpdatedAt time.Time `db:"updated_at"` // 更新时间
Id int64 `db:"id"` // 用户产品ID
UserId int64 `db:"user_id"` // 用户ID
ProductId int64 `db:"product_id"` // 产品ID
ProductPrice float64 `db:"product_price"` // 产品价格
CreatedAt time.Time `db:"created_at"` // 创建时间
UpdatedAt time.Time `db:"updated_at"` // 更新时间
}
)
@@ -85,8 +86,8 @@ func (m *defaultUserProductsModel) FindOne(ctx context.Context, id int64) (*User
func (m *defaultUserProductsModel) Insert(ctx context.Context, data *UserProducts) (sql.Result, error) {
userProductsIdKey := fmt.Sprintf("%s%v", cacheUserProductsIdPrefix, data.Id)
ret, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?)", m.table, userProductsRowsExpectAutoSet)
return conn.ExecCtx(ctx, query, data.UserId, data.ProductId)
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?)", m.table, userProductsRowsExpectAutoSet)
return conn.ExecCtx(ctx, query, data.UserId, data.ProductId, data.ProductPrice)
}, userProductsIdKey)
return ret, err
}
@@ -95,7 +96,7 @@ func (m *defaultUserProductsModel) Update(ctx context.Context, data *UserProduct
userProductsIdKey := fmt.Sprintf("%s%v", cacheUserProductsIdPrefix, data.Id)
_, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, userProductsRowsWithPlaceHolder)
return conn.ExecCtx(ctx, query, data.UserId, data.ProductId, data.Id)
return conn.ExecCtx(ctx, query, data.UserId, data.ProductId, data.ProductPrice, data.Id)
}, userProductsIdKey)
return err
}

View File

@@ -29,11 +29,16 @@ func (s *UserProductServer) CreateUserProduct(ctx context.Context, in *sentinel.
return l.CreateUserProduct(in)
}
func (s *UserProductServer) GetUserProductPageList(ctx context.Context, in *sentinel.UserProuctPageListRequest) (*sentinel.UserProductResponse, error) {
func (s *UserProductServer) GetUserProductPageList(ctx context.Context, in *sentinel.UserProuctPageListRequest) (*sentinel.UserProductPageListResponse, error) {
l := userproductlogic.NewGetUserProductPageListLogic(ctx, s.svcCtx)
return l.GetUserProductPageList(in)
}
func (s *UserProductServer) GetUserProduct(ctx context.Context, in *sentinel.UserProuctRequest) (*sentinel.UserProductResponse, error) {
l := userproductlogic.NewGetUserProductLogic(ctx, s.svcCtx)
return l.GetUserProduct(in)
}
func (s *UserProductServer) MatchingUserIdProductCode(ctx context.Context, in *sentinel.MatchingUserIdProductCodeRequest) (*sentinel.MatchResponse, error) {
l := userproductlogic.NewMatchingUserIdProductCodeLogic(ctx, s.svcCtx)
return l.MatchingUserIdProductCode(in)

View File

@@ -14,6 +14,10 @@ message UserProuctPageListRequest {
int64 page = 2;
int64 page_size = 3;
}
message UserProuctRequest {
int64 user_id = 1;
int64 product_id = 2;
}
message WhitePageListRequest {
int64 user_id = 1;
int64 page = 2;
@@ -85,7 +89,6 @@ message SecretResponse {
repeated Secret secrets = 2;
}
// Message for Products operations
message Product {
int64 id = 1;
string product_name = 2;
@@ -126,7 +129,6 @@ message ProductResponse {
repeated Product products = 2;
}
// Message for UserProducts operations
message UserProductEmptyResponse {
}
message UserProductItem {
@@ -153,10 +155,16 @@ message DeleteUserProductRequest {
int64 id = 1;
}
message UserProductResponse {
message UserProductPageListResponse {
int64 total = 1;
repeated UserProductItem user_products = 2;
}
message UserProductResponse {
int64 id = 1; // 用户产品ID
int64 userId = 2;
int64 productId = 3; // 产品ID
double productPrice = 4; // 产品价格
}
message matchingUserIdProductCodeRequest {
int64 id = 1;
@@ -184,7 +192,6 @@ message AliTopUpNotifyRequest {
message AliTopUpNotifyResponse {
bool success = 1;
}
// Service definitions for Whitelist, Secrets, Products, and UserProducts
service whitelist {
// Whitelist methods
rpc CreateWhitelist(CreateWhitelistRequest) returns (Whitelist);
@@ -211,7 +218,8 @@ service product {
service userProduct {
// UserProduct methods
rpc CreateUserProduct(CreateUserProductRequest) returns (UserProductEmptyResponse);
rpc GetUserProductPageList(UserProuctPageListRequest) returns (UserProductResponse);
rpc GetUserProductPageList(UserProuctPageListRequest) returns (UserProductPageListResponse);
rpc GetUserProduct(UserProuctRequest) returns (UserProductResponse);
rpc MatchingUserIdProductCode(matchingUserIdProductCodeRequest) returns (matchResponse);
}

View File

@@ -36,6 +36,7 @@ CREATE TABLE `user_products` (
`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '用户产品ID',
`user_id` INT(11) NOT NULL COMMENT '用户ID',
`product_id` INT(11) NOT NULL COMMENT '产品ID',
`product_price` DECIMAL(10, 2) NOT NULL COMMENT '产品价格',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`)

File diff suppressed because it is too large Load Diff

View File

@@ -29,8 +29,6 @@ const (
// WhitelistClient is the client API for Whitelist service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
//
// Service definitions for Whitelist, Secrets, Products, and UserProducts
type WhitelistClient interface {
// Whitelist methods
CreateWhitelist(ctx context.Context, in *CreateWhitelistRequest, opts ...grpc.CallOption) (*Whitelist, error)
@@ -101,8 +99,6 @@ func (c *whitelistClient) MatchWhitelistByIp(ctx context.Context, in *MatchWhite
// WhitelistServer is the server API for Whitelist service.
// All implementations must embed UnimplementedWhitelistServer
// for forward compatibility
//
// Service definitions for Whitelist, Secrets, Products, and UserProducts
type WhitelistServer interface {
// Whitelist methods
CreateWhitelist(context.Context, *CreateWhitelistRequest) (*Whitelist, error)
@@ -722,6 +718,7 @@ var Product_ServiceDesc = grpc.ServiceDesc{
const (
UserProduct_CreateUserProduct_FullMethodName = "/userProduct/CreateUserProduct"
UserProduct_GetUserProductPageList_FullMethodName = "/userProduct/GetUserProductPageList"
UserProduct_GetUserProduct_FullMethodName = "/userProduct/GetUserProduct"
UserProduct_MatchingUserIdProductCode_FullMethodName = "/userProduct/MatchingUserIdProductCode"
)
@@ -731,7 +728,8 @@ const (
type UserProductClient interface {
// UserProduct methods
CreateUserProduct(ctx context.Context, in *CreateUserProductRequest, opts ...grpc.CallOption) (*UserProductEmptyResponse, error)
GetUserProductPageList(ctx context.Context, in *UserProuctPageListRequest, opts ...grpc.CallOption) (*UserProductResponse, error)
GetUserProductPageList(ctx context.Context, in *UserProuctPageListRequest, opts ...grpc.CallOption) (*UserProductPageListResponse, error)
GetUserProduct(ctx context.Context, in *UserProuctRequest, opts ...grpc.CallOption) (*UserProductResponse, error)
MatchingUserIdProductCode(ctx context.Context, in *MatchingUserIdProductCodeRequest, opts ...grpc.CallOption) (*MatchResponse, error)
}
@@ -753,10 +751,20 @@ func (c *userProductClient) CreateUserProduct(ctx context.Context, in *CreateUse
return out, nil
}
func (c *userProductClient) GetUserProductPageList(ctx context.Context, in *UserProuctPageListRequest, opts ...grpc.CallOption) (*UserProductResponse, error) {
func (c *userProductClient) GetUserProductPageList(ctx context.Context, in *UserProuctPageListRequest, opts ...grpc.CallOption) (*UserProductPageListResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(UserProductPageListResponse)
err := c.cc.Invoke(ctx, UserProduct_GetUserProductPageList_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *userProductClient) GetUserProduct(ctx context.Context, in *UserProuctRequest, opts ...grpc.CallOption) (*UserProductResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(UserProductResponse)
err := c.cc.Invoke(ctx, UserProduct_GetUserProductPageList_FullMethodName, in, out, cOpts...)
err := c.cc.Invoke(ctx, UserProduct_GetUserProduct_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
@@ -779,7 +787,8 @@ func (c *userProductClient) MatchingUserIdProductCode(ctx context.Context, in *M
type UserProductServer interface {
// UserProduct methods
CreateUserProduct(context.Context, *CreateUserProductRequest) (*UserProductEmptyResponse, error)
GetUserProductPageList(context.Context, *UserProuctPageListRequest) (*UserProductResponse, error)
GetUserProductPageList(context.Context, *UserProuctPageListRequest) (*UserProductPageListResponse, error)
GetUserProduct(context.Context, *UserProuctRequest) (*UserProductResponse, error)
MatchingUserIdProductCode(context.Context, *MatchingUserIdProductCodeRequest) (*MatchResponse, error)
mustEmbedUnimplementedUserProductServer()
}
@@ -791,9 +800,12 @@ type UnimplementedUserProductServer struct {
func (UnimplementedUserProductServer) CreateUserProduct(context.Context, *CreateUserProductRequest) (*UserProductEmptyResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateUserProduct not implemented")
}
func (UnimplementedUserProductServer) GetUserProductPageList(context.Context, *UserProuctPageListRequest) (*UserProductResponse, error) {
func (UnimplementedUserProductServer) GetUserProductPageList(context.Context, *UserProuctPageListRequest) (*UserProductPageListResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetUserProductPageList not implemented")
}
func (UnimplementedUserProductServer) GetUserProduct(context.Context, *UserProuctRequest) (*UserProductResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetUserProduct not implemented")
}
func (UnimplementedUserProductServer) MatchingUserIdProductCode(context.Context, *MatchingUserIdProductCodeRequest) (*MatchResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method MatchingUserIdProductCode not implemented")
}
@@ -846,6 +858,24 @@ func _UserProduct_GetUserProductPageList_Handler(srv interface{}, ctx context.Co
return interceptor(ctx, in, info, handler)
}
func _UserProduct_GetUserProduct_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UserProuctRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(UserProductServer).GetUserProduct(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: UserProduct_GetUserProduct_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(UserProductServer).GetUserProduct(ctx, req.(*UserProuctRequest))
}
return interceptor(ctx, in, info, handler)
}
func _UserProduct_MatchingUserIdProductCode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MatchingUserIdProductCodeRequest)
if err := dec(in); err != nil {
@@ -879,6 +909,10 @@ var UserProduct_ServiceDesc = grpc.ServiceDesc{
MethodName: "GetUserProductPageList",
Handler: _UserProduct_GetUserProductPageList_Handler,
},
{
MethodName: "GetUserProduct",
Handler: _UserProduct_GetUserProduct_Handler,
},
{
MethodName: "MatchingUserIdProductCode",
Handler: _UserProduct_MatchingUserIdProductCode_Handler,