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 3da5410b..bf2d88de 100755 --- a/model/gmodel/fs_order_logic.go +++ b/model/gmodel/fs_order_logic.go @@ -12,7 +12,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 } @@ -20,7 +20,11 @@ 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 } func (o *FsOrderModel) FindOneAndCreateServiceContact(ctx context.Context, userId int64, OrderId int64) (order *FsOrder, err error) { diff --git a/model/gmodel/fs_product_design_logic.go b/model/gmodel/fs_product_design_logic.go index 0f3fd90e..afd82d0b 100755 --- a/model/gmodel/fs_product_design_logic.go +++ b/model/gmodel/fs_product_design_logic.go @@ -18,3 +18,13 @@ func (d *FsProductDesignModel) GetAllByIds(ctx context.Context, ids []int64) (re } return } +func (d *FsProductDesignModel) GetAllByIdsWithoutStatus(ctx context.Context, ids []int64) (resp []FsProductDesign, err error) { + if len(ids) == 0 { + return + } + err = d.db.WithContext(ctx).Model(&FsProductDesign{}).Where("`id` in (?)", ids).Find(&resp).Error + if err != nil { + return nil, err + } + return +} diff --git a/model/gmodel/fs_product_size_logic.go b/model/gmodel/fs_product_size_logic.go index 9219f214..146554fc 100755 --- a/model/gmodel/fs_product_size_logic.go +++ b/model/gmodel/fs_product_size_logic.go @@ -48,11 +48,11 @@ func (s *FsProductSizeModel) GetAllByProductIds(ctx context.Context, productIds } return } -func (s *FsProductSizeModel) GetAllByProductIdsWithoutStatus(ctx context.Context, productIds []int64, sort string) (resp []FsProductSize, err error) { - if len(productIds) == 0 { +func (s *FsProductSizeModel) GetAllByIdsWithoutStatus(ctx context.Context, ids []int64, sort string) (resp []FsProductSize, err error) { + if len(ids) == 0 { return nil, nil } - db := s.db.WithContext(ctx).Model(&FsProductSize{}).Where("`product_id` in(?)", productIds) + db := s.db.WithContext(ctx).Model(&FsProductSize{}).Where("`id` in(?)", ids) switch sort { case "sort-asc": db = db.Order("`sort` ASC") diff --git a/model/gmodel/fs_user_stock_logic.go b/model/gmodel/fs_user_stock_logic.go index bc122752..fb28363b 100644 --- a/model/gmodel/fs_user_stock_logic.go +++ b/model/gmodel/fs_user_stock_logic.go @@ -1,6 +1,8 @@ package gmodel -import "context" +import ( + "context" +) // TODO: 使用model的属性做你想做的 type GetStockListReq struct { 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/getcloudlistlogic.go b/server/inventory/internal/logic/getcloudlistlogic.go index 47be6dd1..81e58acc 100644 --- a/server/inventory/internal/logic/getcloudlistlogic.go +++ b/server/inventory/internal/logic/getcloudlistlogic.go @@ -1,11 +1,15 @@ package logic import ( + "fmt" "fusenapi/constants" "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" "fusenapi/utils/format" + "fusenapi/utils/image" + "fusenapi/utils/step_price" + "math" "strings" "context" @@ -38,13 +42,20 @@ func (l *GetCloudListLogic) GetCloudList(req *types.GetCloudListReq, userinfo *a req.Page = constants.DEFAULT_PAGE } if req.PageSize <= 0 || req.PageSize > 200 { - req.Page = constants.DEFAULT_PAGE_SIZE + req.PageSize = constants.DEFAULT_PAGE_SIZE + } + sizeFlag := false + if req.Size >= 200 { + sizeFlag = true + req.Size = int64(image.GetCurrentSize(uint32(req.Size))) } //获取个人云仓列表 + getStockListStatus := int64(1) stockList, total, err := l.svcCtx.AllModels.FsUserStock.GetStockList(l.ctx, gmodel.GetStockListReq{ UserId: userinfo.UserId, Page: int(req.Page), Limit: int(req.PageSize), + Status: &getStockListStatus, }) if err != nil { logx.Error(err) @@ -60,7 +71,7 @@ func (l *GetCloudListLogic) GetCloudList(req *types.GetCloudListReq, userinfo *a designIds = append(designIds, *v.DesignId) } //获取设计数据 - productDesignList, err := l.svcCtx.AllModels.FsProductDesign.GetAllByIds(l.ctx, designIds) + productDesignList, err := l.svcCtx.AllModels.FsProductDesign.GetAllByIdsWithoutStatus(l.ctx, designIds) if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product design list") @@ -73,23 +84,23 @@ func (l *GetCloudListLogic) GetCloudList(req *types.GetCloudListReq, userinfo *a templateIds := make([]int64, 0, len(productDesignList)) //配件ids optionalIds := make([]int64, 0, len(productDesignList)) - mapProductDesign := make(map[int64]int) - for k, v := range productDesignList { + mapProductDesign := make(map[int64]gmodel.FsProductDesign) + for _, v := range productDesignList { sizeIds = append(sizeIds, *v.SizeId) productIds = append(productIds, *v.ProductId) templateIds = append(templateIds, *v.TemplateId) optionalIds = append(optionalIds, *v.OptionalId) - mapProductDesign[v.Id] = k + mapProductDesign[v.Id] = v } //获取尺寸信息 - sizeList, err := l.svcCtx.AllModels.FsProductSize.GetAllByProductIdsWithoutStatus(l.ctx, sizeIds, "") + sizeList, err := l.svcCtx.AllModels.FsProductSize.GetAllByIdsWithoutStatus(l.ctx, sizeIds, "") if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product size list") } - mapSize := make(map[int64]int) - for k, v := range sizeList { - mapSize[v.Id] = k + mapSize := make(map[int64]gmodel.FsProductSize) + for _, v := range sizeList { + mapSize[v.Id] = v } //获取产品信息 productList, err := l.svcCtx.AllModels.FsProduct.GetProductListByIdsWithoutStatus(l.ctx, productIds, "") @@ -97,9 +108,9 @@ func (l *GetCloudListLogic) GetCloudList(req *types.GetCloudListReq, userinfo *a logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product list") } - mapProduct := make(map[int64]int) - for k, v := range productList { - mapProduct[v.Id] = k + mapProduct := make(map[int64]gmodel.FsProduct) + for _, v := range productList { + mapProduct[v.Id] = v } //获取模板信息 productTemplateList, err := l.svcCtx.AllModels.FsProductTemplateV2.FindAllByIdsWithoutStatus(l.ctx, templateIds) @@ -107,9 +118,9 @@ func (l *GetCloudListLogic) GetCloudList(req *types.GetCloudListReq, userinfo *a logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product template list") } - mapTemplate := make(map[int64]int) - for k, v := range productTemplateList { - mapTemplate[v.Id] = k + mapTemplate := make(map[int64]gmodel.FsProductTemplateV2) + for _, v := range productTemplateList { + mapTemplate[v.Id] = v } //获取配件列表 productModel3dList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllByIdsWithoutStatus(l.ctx, optionalIds) @@ -117,9 +128,9 @@ func (l *GetCloudListLogic) GetCloudList(req *types.GetCloudListReq, userinfo *a logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product 3d model list") } - mapProductModel := make(map[int64]int) - for k, v := range productModel3dList { - mapProductModel[v.Id] = k + mapProductModel := make(map[int64]gmodel.FsProductModel3d) + for _, v := range productModel3dList { + mapProductModel[v.Id] = v } //根据产品ids获取产品价格 priceList, err := l.svcCtx.AllModels.FsProductPrice.GetPriceListByProductIds(l.ctx, productIds) @@ -127,6 +138,8 @@ func (l *GetCloudListLogic) GetCloudList(req *types.GetCloudListReq, userinfo *a logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product price list") } + //根据产品id,材质,尺寸存储价格 + mapProductMaterialSizePrice := make(map[string][]types.PriceItem) for _, v := range priceList { if *v.StepNum == "" || *v.StepPrice == "" { return resp.SetStatusWithMessage(basic.CodeServiceErr, "price data`s step num or step price is empty") @@ -136,19 +149,122 @@ func (l *GetCloudListLogic) GetCloudList(req *types.GetCloudListReq, userinfo *a logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "parse step num err") } - lenStepNum := len(stepNum) stepPrice, err := format.StrSlicToIntSlice(strings.Split(*v.StepPrice, ",")) if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "parse step price err") } lenStepPrice := len(stepPrice) + //不确定长度给20 for *v.MinBuyNum < int64(stepPrice[lenStepPrice-1]+5) { - //根据材质,尺寸,价格计算阶梯价 - + mapKey := l.getMapProductMaterialSizePriceKey(*v.ProductId, *v.MaterialId, *v.SizeId) + mapProductMaterialSizePrice[mapKey] = append(mapProductMaterialSizePrice[mapKey], types.PriceItem{ + Num: *v.MinBuyNum, + TotalNum: *v.MinBuyNum * (*v.EachBoxNum), + Price: step_price.GetCentStepPrice(int(*v.MinBuyNum), stepNum, stepPrice), + }) *v.MinBuyNum++ } - } - return resp.SetStatus(basic.CodeOK) + warehouseBoxes := int64(0) + transitBoxes := int64(0) + listDataRsp := make([]types.ListDataItem, 0, len(stockList)) + for _, v := range stockList { + dataItem := types.ListDataItem{ + Id: v.Id, + Production: *v.Production, + EachBoxNum: *v.EachBoxNum, + Stick: *v.Stick, + Type: 1, + TakeNum: 1, // 步数 + } + //设计详情 + designInfo, designOk := mapProductDesign[*v.DesignId] + sizeId := int64(0) + optionalId := int64(0) + if designOk { + mapKey := l.getMapProductMaterialSizePriceKey(*v.ProductId, *designInfo.MaterialId, *designInfo.SizeId) + dataItem.DesignSn = *designInfo.Sn + dataItem.Cover = *designInfo.Cover + sizeId = *designInfo.SizeId + optionalId = *designInfo.OptionalId + dataItem.PriceList = mapProductMaterialSizePrice[mapKey] + } + //模型信息 + productModel3dInfo, model3dOk := mapProductModel[optionalId] + if model3dOk { + dataItem.Fitting = *productModel3dInfo.Title + //配件下架 + if *productModel3dInfo.Status == 0 { + dataItem.IsStop = 3 + } + } + //模板信息 + templateInfo, templateOk := mapTemplate[*designInfo.TemplateId] + if templateOk { + //模板下架 + if *templateInfo.IsDel == 1 || *templateInfo.Status == 0 { + dataItem.IsStop = 1 + } + } + //尺寸信息 + sizeInfo, sizeOk := mapSize[sizeId] + if sizeOk { + dataItem.Size = *sizeInfo.Capacity + //尺寸下架 + if *sizeInfo.Status == 0 { + dataItem.IsStop = 1 + } + } + //产品信息 + productInfo, productOk := mapProduct[*v.ProductId] + if productOk { + dataItem.Sn = *productInfo.Sn + dataItem.Name = *productInfo.Title + if *productInfo.IsShelf == 0 || *productInfo.IsDel == 1 { + dataItem.IsStop = 2 + } + } + if sizeFlag { + coverArr := strings.Split(*designInfo.Cover, ".") + if len(coverArr) < 2 { + return resp.SetStatusWithMessage(basic.CodeServiceErr, "cover split slice item count is less than 2") + } + dataItem.Cover = fmt.Sprintf("%s_%d.%s", coverArr[0], req.Size, coverArr[1]) + } + //生产中的箱数 + if *v.EachBoxNum > 0 { + dataItem.ProductionBox = *v.Production / *v.EachBoxNum + dataItem.StickBox = *v.Stick / *v.EachBoxNum + } + //判断提示类型1 2告急 3没有了 + if *v.Stick <= 0 && *v.Production <= 0 { + dataItem.Type = 3 + } + if (*v.Stick+*v.Production) / *v.EachBoxNum <= 3 { + dataItem.Type = 2 + } + listDataRsp = append(listDataRsp, dataItem) + //累加在库数量和运输数量 + if *v.EachBoxNum != 0 { + warehouseBoxes += *v.Stick / *v.EachBoxNum + transitBoxes += *v.TransNum / *v.EachBoxNum + } + } + return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetCloudListRsp{ + WarehouseBoxes: warehouseBoxes, + TransitBoxes: transitBoxes, + MinTakeNum: 3, + ListData: listDataRsp, + Pagnation: types.Pagnation{ + TotalCount: total, + TotalPage: int64(math.Ceil(float64(total) / float64(req.PageSize))), + CurPage: req.Page, + PageSize: req.PageSize, + }, + }) +} + +func (l *GetCloudListLogic) getMapProductMaterialSizePriceKey(productId int64, materialId int64, sizeId int64) string { + return fmt.Sprintf("%d-%d-%d", productId, materialId, sizeId) } diff --git a/server/inventory/internal/logic/supplementlogic.go b/server/inventory/internal/logic/supplementlogic.go new file mode 100644 index 00000000..ae981c8e --- /dev/null +++ b/server/inventory/internal/logic/supplementlogic.go @@ -0,0 +1,185 @@ +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 + newOrderDetailTemplateSn, err := id_generator.GenSnowFlakeId() + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "gen order detail template sn err") + } + newOrderDetailSn, 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: &newOrderDetailTemplateSn, + 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: &newOrderDetailSn, + 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.SetStatusWithMessage(basic.CodeOK, "success", types.SupplementRsp{ + Sn: newOrderSn, + }) +} diff --git a/server/inventory/internal/types/types.go b/server/inventory/internal/types/types.go index c7fc0c67..fccafa7c 100644 --- a/server/inventory/internal/types/types.go +++ b/server/inventory/internal/types/types.go @@ -16,9 +16,9 @@ type TakeForm struct { } type GetCloudListReq struct { - Page int64 `json:"page"` - PageSize int64 `json:"page_size"` - Size int64 `json:"size"` + Page int64 `form:"page"` + PageSize int64 `form:"page_size"` + Size int64 `form:"size"` } type GetCloudListRsp struct { @@ -49,9 +49,18 @@ type ListDataItem struct { } type PriceItem struct { - Num int `json:"num"` - TotalNum int `json:"total_num"` - Price int `json:"price"` + Num int64 `json:"num"` + TotalNum int64 `json:"total_num"` + 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 0e9908eb..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); } //提取云仓货物 @@ -28,9 +31,9 @@ type TakeForm { } //获取云仓库存列表 type GetCloudListReq { - Page int64 `json:"page"` - PageSize int64 `json:"page_size"` - Size int64 `json:"size"` + Page int64 `form:"page"` + PageSize int64 `form:"page_size"` + Size int64 `form:"size"` } type GetCloudListRsp { WarehouseBoxes int64 `json:"warehouse_boxes"` @@ -58,7 +61,16 @@ type ListDataItem { PriceList []PriceItem `json:"price"` } type PriceItem { - Num int `json:"num"` - TotalNum int `json:"total_num"` - Price int `json:"price"` + 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 +} diff --git a/utils/step_price/price.go b/utils/step_price/price.go index 6c50ee6c..0cfe5d09 100644 --- a/utils/step_price/price.go +++ b/utils/step_price/price.go @@ -1,5 +1,6 @@ package step_price +// 返回美元 func GetStepPrice(minBuyNum int, stepNum []int, stepPrice []int) float64 { if minBuyNum > stepNum[len(stepNum)-1] { return float64(stepPrice[len(stepPrice)-1]) / float64(100) @@ -14,3 +15,19 @@ func GetStepPrice(minBuyNum int, stepNum []int, stepPrice []int) float64 { } return float64(stepPrice[len(stepPrice)-1]) / float64(100) } + +// 返回美分 +func GetCentStepPrice(minBuyNum int, stepNum []int, stepPrice []int) int64 { + if minBuyNum > stepNum[len(stepNum)-1] { + return int64(stepPrice[len(stepPrice)-1]) + } + for k, v := range stepNum { + if minBuyNum <= v { + if k <= (len(stepPrice) - 1) { + return int64(stepPrice[k]) + } + return int64(stepPrice[len(stepPrice)-1]) + } + } + return int64(stepPrice[len(stepPrice)-1]) +}