This commit is contained in:
laodaming
2023-06-12 16:47:48 +08:00
parent ff05e127bd
commit b1393950f2
32 changed files with 729 additions and 196 deletions

View File

@@ -7,15 +7,39 @@ import (
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/rest/httpx"
"fusenapi/utils/auth"
"fusenapi/server/canteen/internal/logic"
"fusenapi/server/canteen/internal/svc"
"fusenapi/server/canteen/internal/types"
)
// 获取餐厅详情
func GetCanteenDetailHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// 解析jwtToken
claims, err := svcCtx.ParseJwtToken(r)
// 如果解析出错则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &types.Response{
Code: 401,
Message: "unauthorized",
})
logx.Info("unauthorized:", err.Error())
}
// 从Token里获取对应的信息
userinfo, err := auth.GetUserInfoFormMapClaims(claims)
// 如果获取用户信息出错则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &types.Response{
Code: 401,
Message: "unauthorized",
})
logx.Info("unauthorized:", err.Error())
}
var req types.GetCanteenDetailReq
// 如果端点有请求结构体则使用httpx.Parse方法从HTTP请求体中解析请求数据
if err := httpx.Parse(r, &req); err != nil {
httpx.OkJsonCtx(r.Context(), w, &types.Response{
Code: 510,
@@ -24,9 +48,11 @@ func GetCanteenDetailHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
logx.Info(err)
return
}
// 创建一个业务逻辑层实例
l := logic.NewGetCanteenDetailLogic(r.Context(), svcCtx)
resp := l.GetCanteenDetail(&req)
resp := l.GetCanteenDetail(&req, userinfo)
// 如果响应不为nil则使用httpx.OkJsonCtx方法返回JSON响应;
// 否则发送500内部服务器错误的JSON响应并记录错误消息logx.Error。
if resp != nil {
httpx.OkJsonCtx(r.Context(), w, resp)
} else {

View File

@@ -7,6 +7,8 @@ import (
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/rest/httpx"
"fusenapi/utils/auth"
"fusenapi/server/canteen/internal/logic"
"fusenapi/server/canteen/internal/svc"
"fusenapi/server/canteen/internal/types"
@@ -14,7 +16,30 @@ import (
func SaveCanteenTypeProductHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// 解析jwtToken
claims, err := svcCtx.ParseJwtToken(r)
// 如果解析出错则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &types.Response{
Code: 401,
Message: "unauthorized",
})
logx.Info("unauthorized:", err.Error())
}
// 从Token里获取对应的信息
userinfo, err := auth.GetUserInfoFormMapClaims(claims)
// 如果获取用户信息出错则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &types.Response{
Code: 401,
Message: "unauthorized",
})
logx.Info("unauthorized:", err.Error())
}
var req types.SaveCanteenTypeProductReq
// 如果端点有请求结构体则使用httpx.Parse方法从HTTP请求体中解析请求数据
if err := httpx.Parse(r, &req); err != nil {
httpx.OkJsonCtx(r.Context(), w, &types.Response{
Code: 510,
@@ -23,9 +48,11 @@ func SaveCanteenTypeProductHandler(svcCtx *svc.ServiceContext) http.HandlerFunc
logx.Info(err)
return
}
// 创建一个业务逻辑层实例
l := logic.NewSaveCanteenTypeProductLogic(r.Context(), svcCtx)
resp := l.SaveCanteenTypeProduct(&req)
resp := l.SaveCanteenTypeProduct(&req, userinfo)
// 如果响应不为nil则使用httpx.OkJsonCtx方法返回JSON响应;
// 否则发送500内部服务器错误的JSON响应并记录错误消息logx.Error。
if resp != nil {
httpx.OkJsonCtx(r.Context(), w, resp)
} else {

View File

@@ -2,14 +2,12 @@ package logic
import (
"context"
"errors"
"fmt"
"fusenapi/model"
"fusenapi/utils/basic"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"fusenapi/model/gmodel"
"fusenapi/server/canteen/internal/svc"
"fusenapi/server/canteen/internal/types"
"fusenapi/utils/auth"
"fusenapi/utils/basic"
"github.com/zeromicro/go-zero/core/logx"
)
@@ -29,19 +27,19 @@ func NewGetCanteenDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *
}
// 获取餐厅详情
func (l *GetCanteenDetailLogic) GetCanteenDetail(req *types.GetCanteenDetailReq) (resp *types.Response) {
func (l *GetCanteenDetailLogic) GetCanteenDetail(req *types.GetCanteenDetailReq, loginInfo *auth.UserInfo) (resp *types.Response) {
//获取餐厅类型数据
canteenTypeModel := model.NewFsCanteenTypeModel(l.svcCtx.MysqlConn)
canteenTypeModel := gmodel.NewFsCanteenTypeModel(l.svcCtx.MysqlConn)
canteenTypeInfo, err := canteenTypeModel.FindOne(l.ctx, req.Id)
if err != nil && !errors.Is(err, sqlx.ErrNotFound) {
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get canteen type info ")
}
if canteenTypeInfo == nil {
if canteenTypeInfo.Id == 0 {
return resp.SetStatusWithMessage(basic.CodeServiceErr, "canteen type is not exists ")
}
//获取餐厅类型关联的所有产品
canteenProductModel := model.NewFsCanteenProductModel(l.svcCtx.MysqlConn)
canteenProductModel := gmodel.NewFsCanteenProductModel(l.svcCtx.MysqlConn)
canteenProductList, err := canteenProductModel.GetAllByCanteenTypeId(l.ctx, req.Id)
if err != nil {
logx.Error(err)
@@ -50,43 +48,43 @@ func (l *GetCanteenDetailLogic) GetCanteenDetail(req *types.GetCanteenDetailReq)
if len(canteenProductList) == 0 {
return resp.SetStatusWithMessage(basic.CodeOK, "ok with no canteen product")
}
productIds := make([]string, 0, len(canteenProductList))
sizeIds := make([]string, 0, len(canteenProductList))
productIds := make([]int64, 0, len(canteenProductList))
sizeIds := make([]int64, 0, len(canteenProductList))
for _, v := range canteenProductList {
productIds = append(productIds, fmt.Sprintf("%d", v.ProductId))
sizeIds = append(sizeIds, fmt.Sprintf("%d", v.SizeId))
productIds = append(productIds, *v.ProductId)
sizeIds = append(sizeIds, *v.SizeId)
}
productModel := model.NewFsProductModel(l.svcCtx.MysqlConn)
productModel := gmodel.NewFsProductModel(l.svcCtx.MysqlConn)
productList, err := productModel.GetProductListByIds(l.ctx, productIds, "")
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product list")
}
mapProduct := make(map[int64]model.FsProduct)
tagIds := make([]string, 0, len(productList))
mapProduct := make(map[int64]gmodel.FsProduct)
tagIds := make([]int64, 0, len(productList))
for _, v := range productList {
mapProduct[v.Id] = v
tagIds = append(tagIds, fmt.Sprintf("%d", v.Type))
tagIds = append(tagIds, *v.Type)
}
//获取分类列表
tagModel := model.NewFsTagsModel(l.svcCtx.MysqlConn)
tagModel := gmodel.NewFsTagsModel(l.svcCtx.MysqlConn)
tagList, err := tagModel.GetAllByIds(l.ctx, tagIds)
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get tag list")
}
mapTag := make(map[int64]model.FsTags)
mapTag := make(map[int64]gmodel.FsTags)
for _, v := range tagList {
mapTag[v.Id] = v
}
//获取尺寸列表
productSizeModel := model.NewFsProductSizeModel(l.svcCtx.MysqlConn)
productSizeModel := gmodel.NewFsProductSizeModel(l.svcCtx.MysqlConn)
productSizeList, err := productSizeModel.GetAllByIds(l.ctx, sizeIds, "")
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product size list")
}
mapSize := make(map[int64]model.FsProductSize)
mapSize := make(map[int64]gmodel.FsProductSize)
for _, v := range productSizeList {
mapSize[v.Id] = v
}
@@ -95,18 +93,18 @@ func (l *GetCanteenDetailLogic) GetCanteenDetail(req *types.GetCanteenDetailReq)
for _, v := range canteenProductList {
data := types.CanteenProduct{
Id: v.Id,
SizeId: v.SizeId,
SId: v.Sid,
SizeId: *v.SizeId,
SId: *v.Sid,
}
p, ok := mapProduct[v.ProductId]
p, ok := mapProduct[*v.ProductId]
if !ok {
continue
}
tag, ok := mapTag[p.Type]
tag, ok := mapTag[*p.Type]
if !ok {
continue
}
size, ok := mapSize[v.SizeId]
size, ok := mapSize[*v.SizeId]
if !ok {
continue
}
@@ -115,7 +113,7 @@ func (l *GetCanteenDetailLogic) GetCanteenDetail(req *types.GetCanteenDetailReq)
}
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetCanteenDetailRsp{
Id: canteenTypeInfo.Id,
Name: canteenTypeInfo.Name,
Name: *canteenTypeInfo.Name,
ProductList: list,
})
}

View File

@@ -3,10 +3,10 @@ package logic
import (
"context"
"fmt"
"fusenapi/model"
"fusenapi/model/gmodel"
"fusenapi/utils/auth"
"fusenapi/utils/basic"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"strings"
"gorm.io/gorm"
"time"
"fusenapi/server/canteen/internal/svc"
@@ -30,34 +30,36 @@ func NewSaveCanteenTypeProductLogic(ctx context.Context, svcCtx *svc.ServiceCont
}
// 保存餐厅类型的关联产品
func (l *SaveCanteenTypeProductLogic) SaveCanteenTypeProduct(req *types.SaveCanteenTypeProductReq) (resp *types.Response) {
func (l *SaveCanteenTypeProductLogic) SaveCanteenTypeProduct(req *types.SaveCanteenTypeProductReq, loginInfo *auth.UserInfo) (resp *types.Response) {
if len(req.ProductList) == 0 {
return resp.SetStatusWithMessage(basic.CodeServiceErr, "product list can`t be empty")
}
canteenProductModel := model.NewFsCanteenProductModel(l.svcCtx.MysqlConn)
canteenProductModel := gmodel.NewFsCanteenProductModel(l.svcCtx.MysqlConn)
//获取原有餐厅类型的所有产品
oldCanteenProductList, err := canteenProductModel.GetAllByCanteenTypeId(l.ctx, req.Id)
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get canteen product list")
}
sizeIds := make([]string, 0, len(req.ProductList))
sizeIds := make([]int64, 0, len(req.ProductList))
for _, v := range req.ProductList {
sizeIds = append(sizeIds, fmt.Sprintf("%d", v.SizeId))
sizeIds = append(sizeIds, v.SizeId)
}
productSizeModel := model.NewFsProductSizeModel(l.svcCtx.MysqlConn)
productSizeModel := gmodel.NewFsProductSizeModel(l.svcCtx.MysqlConn)
productSizeList, err := productSizeModel.GetAllByIds(l.ctx, sizeIds, "")
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product size list")
}
fmt.Println(len(productSizeList))
mapProductSize := make(map[int64]model.FsProductSize)
mapProductSize := make(map[int64]gmodel.FsProductSize)
for _, v := range productSizeList {
mapProductSize[v.Id] = v
}
now := time.Now().Unix()
//开启事务
err = l.svcCtx.MysqlConn.TransactCtx(l.ctx, func(ctx context.Context, session sqlx.Session) error {
err = l.svcCtx.MysqlConn.Transaction(func(tx *gorm.DB) error {
canteenProductModel = gmodel.NewFsCanteenProductModel(tx)
sort := int64(0)
//新的变更记录
mapUpdateCanteenPid := make(map[int64]struct{})
@@ -69,33 +71,47 @@ func (l *SaveCanteenTypeProductLogic) SaveCanteenTypeProduct(req *types.SaveCant
}
if v.Id > 0 { //更新
mapUpdateCanteenPid[v.Id] = struct{}{}
if _, err = session.ExecCtx(l.ctx, "update `fs_canteen_product` set "+
"`size_id` = ?,`sid` = ?,`sort` = ?,`product_id` = ? where `id` = ? ",
v.SizeId, v.SId, sort, sizeInfo.ProductId, v.Id,
); err != nil {
err = canteenProductModel.UpdateById(l.ctx, v.Id, &gmodel.FsCanteenProduct{
SizeId: &v.SizeId,
Sid: &v.SId,
Sort: &sort,
ProductId: sizeInfo.ProductId,
})
if err != nil {
return err
}
continue
}
//新增
if _, err = session.ExecCtx(l.ctx, "insert into `fs_canteen_product` "+
"(`size_id`,`sid`,`sort`,`status`,`ctime`,`canteen_type`,`product_id`) "+
"values (?, ?, ?, ?, ?, ?, ?)", sizeInfo.Id, v.SId, sort, 1, time.Now().Unix(), req.Id, sizeInfo.ProductId); err != nil {
err = canteenProductModel.Create(l.ctx, &gmodel.FsCanteenProduct{
SizeId: &v.SizeId,
Sid: &v.SId,
Sort: &sort,
Ctime: &now,
CanteenType: &req.Id,
ProductId: sizeInfo.ProductId,
})
if err != nil {
return err
}
}
diffCanteenProductId := make([]string, 0, len(oldCanteenProductList))
diffCanteenProductId := make([]int64, 0, len(oldCanteenProductList))
//旧的中不包含在更新的里面则去掉
for _, v := range oldCanteenProductList {
if _, ok := mapUpdateCanteenPid[v.Id]; !ok {
diffCanteenProductId = append(diffCanteenProductId, fmt.Sprintf("%d", v.Id))
diffCanteenProductId = append(diffCanteenProductId, v.Id)
}
}
if len(diffCanteenProductId) == 0 {
return nil
}
_, err = session.ExecCtx(l.ctx, "update `fs_canteen_product` set `status` = ? where `id` in (?)", 0, strings.Join(diffCanteenProductId, ","))
return err
delStatus := int64(0)
if err = canteenProductModel.UpdateByIdArr(l.ctx, diffCanteenProductId, &gmodel.FsCanteenProduct{
Status: &delStatus,
}); err != nil {
return err
}
return nil
})
if err != nil {
logx.Error(err)

View File

@@ -1,9 +1,13 @@
package svc
import (
"errors"
"fmt"
"fusenapi/initalize"
"fusenapi/server/canteen/internal/config"
"github.com/golang-jwt/jwt"
"gorm.io/gorm"
"net/http"
)
type ServiceContext struct {
@@ -13,8 +17,35 @@ type ServiceContext struct {
}
func NewServiceContext(c config.Config) *ServiceContext {
return &ServiceContext{
Config: c,
MysqlConn: initalize.InitMysql(c.SourceMysql),
}
}
func (svcCxt *ServiceContext) ParseJwtToken(r *http.Request) (jwt.MapClaims, error) {
AuthKey := r.Header.Get("Authorization")
if len(AuthKey) <= 50 {
return nil, errors.New(fmt.Sprint("Error parsing token, len:", len(AuthKey)))
}
token, err := jwt.Parse(AuthKey, func(token *jwt.Token) (interface{}, error) {
// 检查签名方法是否为 HS256
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
// 返回用于验证签名的密钥
return svcCxt.Config.Auth.AccessSecret, nil
})
if err != nil {
return nil, errors.New(fmt.Sprint("Error parsing token:", err))
}
// 验证成功返回
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
return claims, nil
}
return nil, errors.New(fmt.Sprint("Invalid token", err))
}