This commit is contained in:
laodaming 2023-06-28 17:05:31 +08:00
parent b012db8e4e
commit 6abca6b271
9 changed files with 320 additions and 2 deletions

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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),
},
},
)
}

View File

@ -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)
}
}
}

View File

@ -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)
}

View File

@ -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 {
}

View File

@ -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"`
}

View File

@ -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
}