From 6abca6b2711529c0f7dfbbdde01f605acb3f11cc Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Wed, 28 Jun 2023 17:05:31 +0800 Subject: [PATCH] fix --- model/gmodel/fs_order_detail_logic.go | 7 + .../gmodel/fs_order_detail_template_logic.go | 7 + model/gmodel/fs_order_logic.go | 8 +- server/inventory/internal/handler/routes.go | 5 + .../internal/handler/supplementhandler.go | 78 ++++++++ .../internal/logic/supplementlogic.go | 182 ++++++++++++++++++ server/inventory/internal/types/types.go | 9 + server_api/inventory.api | 12 ++ utils/id_generator/snowflake.go | 14 ++ 9 files changed, 320 insertions(+), 2 deletions(-) create mode 100644 server/inventory/internal/handler/supplementhandler.go create mode 100644 server/inventory/internal/logic/supplementlogic.go create mode 100644 utils/id_generator/snowflake.go diff --git a/model/gmodel/fs_order_detail_logic.go b/model/gmodel/fs_order_detail_logic.go index e16fe337..59db58f1 100755 --- a/model/gmodel/fs_order_detail_logic.go +++ b/model/gmodel/fs_order_detail_logic.go @@ -11,3 +11,10 @@ func (od *FsOrderDetailModel) GetOrderDetailsByOrderId(ctx context.Context, orde } return } +func (od *FsOrderDetailModel) FindOneByOrderDetailTemplateId(ctx context.Context, templateId int64) (resp *FsOrderDetail, err error) { + err = od.db.WithContext(ctx).Model(&FsOrderDetail{}).Where("`order_detail_template_id` = ?", templateId).Take(&resp).Error + return resp, err +} +func (od *FsOrderDetailModel) Create(ctx context.Context, data *FsOrderDetail) error { + return od.db.WithContext(ctx).Model(&FsOrderDetail{}).Create(&data).Error +} diff --git a/model/gmodel/fs_order_detail_template_logic.go b/model/gmodel/fs_order_detail_template_logic.go index 571cec9e..a6764e22 100755 --- a/model/gmodel/fs_order_detail_template_logic.go +++ b/model/gmodel/fs_order_detail_template_logic.go @@ -14,3 +14,10 @@ func (dt *FsOrderDetailTemplateModel) GetListByIds(ctx context.Context, ids []in } return } +func (dt *FsOrderDetailTemplateModel) FindOneBySn(ctx context.Context, sn string) (resp *FsOrderDetailTemplate, err error) { + err = dt.db.WithContext(ctx).Model(&FsOrderDetailTemplate{}).Where("`sn` = ?", sn).Take(&resp).Error + return resp, err +} +func (dt *FsOrderDetailTemplateModel) Create(ctx context.Context, data *FsOrderDetailTemplate) error { + return dt.db.WithContext(ctx).Model(&FsOrderDetailTemplate{}).Create(&data).Error +} diff --git a/model/gmodel/fs_order_logic.go b/model/gmodel/fs_order_logic.go index 9e83d596..90e799e0 100755 --- a/model/gmodel/fs_order_logic.go +++ b/model/gmodel/fs_order_logic.go @@ -10,7 +10,7 @@ func (o *FsOrderModel) FindOneBySn(ctx context.Context, userId int64, sn string) } func (o *FsOrderModel) FindOne(ctx context.Context, userId int64, OrderId int64) (order *FsOrder, err error) { - err = o.db.WithContext(ctx).Model(&order).Where("`user_id` = ? and `id` = ?", userId, OrderId).Take(&order).Error + err = o.db.WithContext(ctx).Model(&FsOrder{}).Where("`user_id` = ? and `id` = ?", userId, OrderId).Take(&order).Error if err != nil { return nil, err } @@ -18,5 +18,9 @@ func (o *FsOrderModel) FindOne(ctx context.Context, userId int64, OrderId int64) } func (o *FsOrderModel) Update(ctx context.Context, data *FsOrder) error { - return o.db.WithContext(ctx).Model(data).Where("`id` = ?", data.Id).Updates(data).Error + return o.db.WithContext(ctx).Model(&FsOrder{}).Where("`id` = ?", data.Id).Updates(&data).Error +} + +func (o *FsOrderModel) Create(ctx context.Context, data *FsOrder) error { + return o.db.WithContext(ctx).Model(&FsOrder{}).Create(&data).Error } diff --git a/server/inventory/internal/handler/routes.go b/server/inventory/internal/handler/routes.go index f71306ed..1eca32bb 100644 --- a/server/inventory/internal/handler/routes.go +++ b/server/inventory/internal/handler/routes.go @@ -22,6 +22,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/inventory/list", Handler: GetCloudListHandler(serverCtx), }, + { + Method: http.MethodPost, + Path: "/inventory/supplement", + Handler: SupplementHandler(serverCtx), + }, }, ) } diff --git a/server/inventory/internal/handler/supplementhandler.go b/server/inventory/internal/handler/supplementhandler.go new file mode 100644 index 00000000..a056cdac --- /dev/null +++ b/server/inventory/internal/handler/supplementhandler.go @@ -0,0 +1,78 @@ +package handler + +import ( + "errors" + "net/http" + + "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/rest/httpx" + + "fusenapi/utils/auth" + "fusenapi/utils/basic" + + "fusenapi/server/inventory/internal/logic" + "fusenapi/server/inventory/internal/svc" + "fusenapi/server/inventory/internal/types" +) + +func SupplementHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var ( + // 定义错误变量 + err error + // 定义用户信息变量 + userinfo *auth.UserInfo + ) + // 解析JWT token,并对空用户进行判断 + claims, err := svcCtx.ParseJwtToken(r) + // 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &basic.Response{ + Code: 401, // 返回401状态码,表示未授权 + Message: "unauthorized", // 返回未授权信息 + }) + logx.Info("unauthorized:", err.Error()) // 记录错误日志 + return + } + + if claims != nil { + // 从token中获取对应的用户信息 + userinfo, err = auth.GetUserInfoFormMapClaims(claims) + // 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &basic.Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + return + } + } else { + // 如果claims为nil,则认为用户身份为白板用户 + userinfo = &auth.UserInfo{UserId: 0, GuestId: 0} + } + + var req types.SupplementReq + // 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据 + if err := httpx.Parse(r, &req); err != nil { + httpx.OkJsonCtx(r.Context(), w, &basic.Response{ + Code: 510, + Message: "parameter error", + }) + logx.Info(err) + return + } + // 创建一个业务逻辑层实例 + l := logic.NewSupplementLogic(r.Context(), svcCtx) + resp := l.Supplement(&req, userinfo) + // 如果响应不为nil,则使用httpx.OkJsonCtx方法返回JSON响应; + if resp != nil { + httpx.OkJsonCtx(r.Context(), w, resp) + } else { + err := errors.New("server logic is error, resp must not be nil") + httpx.ErrorCtx(r.Context(), w, err) + logx.Error(err) + } + } +} diff --git a/server/inventory/internal/logic/supplementlogic.go b/server/inventory/internal/logic/supplementlogic.go new file mode 100644 index 00000000..827f4929 --- /dev/null +++ b/server/inventory/internal/logic/supplementlogic.go @@ -0,0 +1,182 @@ +package logic + +import ( + "errors" + "fusenapi/constants" + "fusenapi/model/gmodel" + "fusenapi/utils/auth" + "fusenapi/utils/basic" + "fusenapi/utils/format" + "fusenapi/utils/id_generator" + "fusenapi/utils/step_price" + "gorm.io/gorm" + "math" + "strings" + "time" + + "context" + + "fusenapi/server/inventory/internal/svc" + "fusenapi/server/inventory/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type SupplementLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewSupplementLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SupplementLogic { + return &SupplementLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *SupplementLogic) Supplement(req *types.SupplementReq, userinfo *auth.UserInfo) (resp *basic.Response) { + if userinfo.GetIdType() != auth.IDTYPE_User { + return resp.SetStatusWithMessage(basic.CodeServiceErr, "please login first") + } + if req.Id <= 0 { + return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "param id must greater than 0") + } + if req.Num <= 0 { + return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "param num must greater than 0") + } + //获取云仓数据 + stockInfo, err := l.svcCtx.AllModels.FsUserStock.FindOne(l.ctx, req.Id, userinfo.UserId, true) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "your stock info is not exists") + } + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get stock info") + } + //获取订单详细模板数据 + orderDetailTemplateInfo, err := l.svcCtx.AllModels.FsOrderDetailTemplate.FindOneBySn(l.ctx, *stockInfo.OrderDetailTemplateSn) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order detail template info is not exists") + } + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get order detail template info") + } + //获取订单详细数据 + orderDetailInfo, err := l.svcCtx.AllModels.FsOrderDetail.FindOneByOrderDetailTemplateId(l.ctx, orderDetailTemplateInfo.Id) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order detail info is not exists") + } + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get order detail info") + } + //产品价格 + productPriceByParamsReq := gmodel.FindOneProductPriceByParamsReq{ + ProductId: orderDetailTemplateInfo.ProductId, + } + productPriceInfo, err := l.svcCtx.AllModels.FsProductPrice.FindOneProductPriceByParams(l.ctx, productPriceByParamsReq) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "product price info is not exists") + } + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product price info") + } + //获取阶梯价格和阶梯数量 + stepNum, err := format.StrSlicToIntSlice(strings.Split(*productPriceInfo.StepNum, ",")) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "invalid step num format: "+*productPriceInfo.StepNum) + } + stepPrice, err := format.StrSlicToIntSlice(strings.Split(*productPriceInfo.StepPrice, ",")) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "invalid step price format: "+*productPriceInfo.StepPrice) + } + //附件价格信息 + optionalPrice := int64(0) + if *orderDetailInfo.OptionPrice > 0 { + optionalPrice = *orderDetailInfo.OptionPrice + } + //获取总价 + minByNum := math.Ceil(float64(req.Num) / float64(*productPriceInfo.EachBoxNum)) + amount := step_price.GetCentStepPrice(int(minByNum), stepNum, stepPrice) + optionalPrice + totalAmount := amount * req.Num + newOrderSn := id_generator.GenPickUpTrackNum() + now := time.Now().Unix() + deliveryMethod := int64(constants.DELIVERY_METHOD_CLOUD) + isSup := int64(1) + //生成雪花id + orderDetailTemplateSn, err := id_generator.GenSnowFlakeId() + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "gen order detail template sn err") + } + orderDetailSn, err := id_generator.GenSnowFlakeId() + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "gen order detail sn err") + } + err = l.svcCtx.MysqlConn.Transaction(func(tx *gorm.DB) error { + orderModel := gmodel.NewFsOrderModel(tx) + orderDetailModel := gmodel.NewFsOrderDetailModel(tx) + orderDetailTemplateModel := gmodel.NewFsOrderDetailTemplateModel(tx) + //订单创建数据 + orderAddData := gmodel.FsOrder{ + Sn: &newOrderSn, + UserId: &userinfo.UserId, + TotalAmount: &totalAmount, + Ctime: &now, + Utime: &now, + DeliveryMethod: &deliveryMethod, + IsSup: &isSup, + } + if err = orderModel.Create(l.ctx, &orderAddData); err != nil { + return err + } + //添加订单详情模板数据 + orderDetailTemplateAddData := gmodel.FsOrderDetailTemplate{ + Sn: &orderDetailTemplateSn, + ProductId: orderDetailTemplateInfo.ProductId, + ModelId: orderDetailTemplateInfo.ModelId, + TemplateId: orderDetailTemplateInfo.TemplateId, + MaterialId: orderDetailTemplateInfo.MaterialId, + SizeId: orderDetailTemplateInfo.SizeId, + EachBoxNum: orderDetailTemplateInfo.EachBoxNum, + EachBoxWeight: orderDetailTemplateInfo.EachBoxWeight, + DesignId: orderDetailTemplateInfo.DesignId, + Ctime: &now, + } + if err = orderDetailTemplateModel.Create(l.ctx, &orderDetailTemplateAddData); err != nil { + return err + } + //添加订单详细数据 + factoryId := int64(1) + isCloud := int64(1) + orderDetailAddData := gmodel.FsOrderDetail{ + Sn: &orderDetailSn, + OrderId: &orderAddData.Id, + UserId: &userinfo.UserId, + FactoryId: &factoryId, + OrderDetailTemplateId: &orderDetailTemplateAddData.Id, + ProductId: orderDetailTemplateInfo.ProductId, + BuyNum: &req.Num, + Amount: &amount, + Cover: orderDetailInfo.Cover, + Ctime: &now, + OptionalId: orderDetailInfo.OptionalId, + OptionalTitle: orderDetailInfo.OptionalTitle, + OptionPrice: orderDetailInfo.OptionPrice, + IsCloud: &isCloud, + } + return orderDetailModel.Create(l.ctx, &orderDetailAddData) + }) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to supplement your stock") + } + return resp.SetStatus(basic.CodeOK) +} diff --git a/server/inventory/internal/types/types.go b/server/inventory/internal/types/types.go index 917428bd..fccafa7c 100644 --- a/server/inventory/internal/types/types.go +++ b/server/inventory/internal/types/types.go @@ -54,6 +54,15 @@ type PriceItem struct { Price int64 `json:"price"` } +type SupplementReq struct { + Id int64 `json:"id"` + Num int64 `json:"num"` +} + +type SupplementRsp struct { + Sn string `json:"sn"` +} + type Request struct { } diff --git a/server_api/inventory.api b/server_api/inventory.api index 7c185715..eca56923 100644 --- a/server_api/inventory.api +++ b/server_api/inventory.api @@ -15,6 +15,9 @@ service inventory { //获取云仓库存列表 @handler GetCloudListHandler get /inventory/list(GetCloudListReq) returns (response); + //云仓补货 + @handler SupplementHandler + post /inventory/supplement(SupplementReq) returns (response); } //提取云仓货物 @@ -61,4 +64,13 @@ type PriceItem { Num int64 `json:"num"` TotalNum int64 `json:"total_num"` Price int64 `json:"price"` +} + +//云仓补货 +type SupplementReq { + Id int64 `json:"id"` + Num int64 `json:"num"` +} +type SupplementRsp { + Sn string `json:"sn"` } \ No newline at end of file diff --git a/utils/id_generator/snowflake.go b/utils/id_generator/snowflake.go new file mode 100644 index 00000000..b845957a --- /dev/null +++ b/utils/id_generator/snowflake.go @@ -0,0 +1,14 @@ +package id_generator + +import ( + "github.com/bwmarrin/snowflake" +) + +func GenSnowFlakeId() (string, error) { + //暂时只用一个节点 + n, err := snowflake.NewNode(1) + if err != nil { + return "", err + } + return n.Generate().Base58(), nil +}