diff --git a/constants/orders.go b/constants/orders.go index 34b7ff71..d955c38c 100644 --- a/constants/orders.go +++ b/constants/orders.go @@ -2,8 +2,8 @@ package constants // 订单类型 const ( - DELIVERYMETHODDIRECTMAIL int64 = 1 - DELIVERYMETHODDSCLOUDSTORE int64 = 2 + DELIVERYMETHODDIRECTMAIL int64 = 1 // 直邮 + DELIVERYMETHODDSCLOUDSTORE int64 = 2 // 云仓 ) // 货币 diff --git a/model/gmodel/fs_address_gen.go b/model/gmodel/fs_address_gen.go index 2feb031b..cb740a7c 100644 --- a/model/gmodel/fs_address_gen.go +++ b/model/gmodel/fs_address_gen.go @@ -1,15 +1,14 @@ package gmodel import ( - "time" - "gorm.io/gorm" + "time" ) // fs_address 用户地址表 type FsAddress struct { AddressId int64 `gorm:"primary_key;default:0;auto_increment;" json:"address_id"` // - UserId *int64 `gorm:"index;default:0;" json:"user_id"` // 用户ID + UserId *int64 `gorm:"default:0;" json:"user_id"` // 用户ID FirstName *string `gorm:"default:'';" json:"first_name"` // FirstName LastName *string `gorm:"default:'';" json:"last_name"` // LastName Mobile *string `gorm:"default:'';" json:"mobile"` // 手机号码 @@ -21,8 +20,8 @@ type FsAddress struct { ZipCode *string `gorm:"default:'';" json:"zip_code"` // Status *int64 `gorm:"default:0;" json:"status"` // 1正常 0异常 Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` // 创建时间 - Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` // 更新时间 - Ltime *time.Time `gorm:"index;default:'0000-00-00 00:00:00';" json:"ltime"` // 上次被使用的时间 + Utime *time.Time `gorm:"index;default:'0000-00-00 00:00:00';" json:"utime"` // 更新时间 + Ltime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ltime"` // 上次被使用的时间 } type FsAddressModel struct { db *gorm.DB diff --git a/model/gmodel/fs_admin_role_gen.go b/model/gmodel/fs_admin_role_gen.go index 498a4a09..15dfeb91 100644 --- a/model/gmodel/fs_admin_role_gen.go +++ b/model/gmodel/fs_admin_role_gen.go @@ -23,6 +23,7 @@ type FsAdminRole struct { DeleteUid *int64 `gorm:"default:0;" json:"delete_uid"` // 删除人 IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除:1=是 0=否 MenuAuth *[]byte `gorm:"default:'';" json:"menu_auth"` // + ApiAuth *[]byte `gorm:"default:'';" json:"api_auth"` // } type FsAdminRoleModel struct { db *gorm.DB diff --git a/model/gmodel/fs_order_logic.go b/model/gmodel/fs_order_logic.go index 0c05b483..9398e5a8 100644 --- a/model/gmodel/fs_order_logic.go +++ b/model/gmodel/fs_order_logic.go @@ -73,14 +73,14 @@ type PayStatus struct { // 订单信息 type OrderInfo struct { - UserId int64 `json:"user_id"` // 物流类型 - Ctime *time.Time `json:"ctime"` // 创建日期 - DeliveryMethod int64 `json:"delivery_method"` // 物流类型 - Metadata map[string]interface{} `json:"metadata"` // 额外参数 - OrderSn string `json:"order_sn"` // 订单编号 - Status OrderStatus `json:"status"` // 当前状态 - StatusLink []OrderStatus `json:"status_link"` // 状态链路 - Utime *time.Time `json:"utime"` // 更新时间 + UserId int64 `json:"user_id"` // 物流类型 + Ctime *time.Time `json:"ctime"` // 创建日期 + DeliveryMethod int64 `json:"delivery_method"` // 物流类型 + Metadata OrderMetadata `json:"metadata"` // 额外参数 + OrderSn string `json:"order_sn"` // 订单编号 + Status OrderStatus `json:"status"` // 当前状态 + StatusLink []OrderStatus `json:"status_link"` // 状态链路 + Utime *time.Time `json:"utime"` // 更新时间 } // 订单状态--用户 @@ -112,6 +112,7 @@ type OrderProduct struct { SizeInfo *OrderProductSizeInfo `json:"size_info"` FittingInfo *OrderProductFittingInfo `json:"fitting_info"` IsHighlyCustomized int64 `json:"is_highly_customized"` + RenderImage string `json:"render_image"` } type PurchaseQuantity struct { Current interface{} `json:"current"` @@ -140,9 +141,9 @@ type ExpectedDelivery struct { } type OrderProductInter struct { + CartId int64 `json:"cart_id"` // 购物车ID TotalPrice AmountInfo `json:"total_price"` // 商品总价 ItemPrice AmountInfo `json:"item_price"` // 商品单价 - ExpectedDelivery *ExpectedDelivery `json:"expected_delivery"` // 预计到货 PurchaseQuantity *PurchaseQuantity `json:"purchase_quantity"` // 购买数量 ProductId int64 `json:"product_id"` // 商品ID ProductName string `json:"product_name"` // 商品名称 @@ -153,4 +154,8 @@ type OrderProductInter struct { SizeInfo *OrderProductSizeInfo `json:"size_info"` FittingInfo *OrderProductFittingInfo `json:"fitting_info"` IsHighlyCustomized int64 `json:"is_highly_customized"` + RenderImage string `json:"render_image"` +} +type OrderMetadata struct { + ExpectedDeliveryTime ExpectedDelivery `json:"expected_delivery_time"` // 预计到货时间 } diff --git a/model/gmodel/fs_product_collection_gen.go b/model/gmodel/fs_product_collection_gen.go new file mode 100644 index 00000000..320376a2 --- /dev/null +++ b/model/gmodel/fs_product_collection_gen.go @@ -0,0 +1,27 @@ +package gmodel + +import ( + "gorm.io/gorm" + "time" +) + +// fs_product_collection 产品收藏表 +type FsProductCollection struct { + Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // id + UserId *int64 `gorm:"default:0;" json:"user_id"` // 用户id + GuestId *int64 `gorm:"default:0;" json:"guest_id"` // 游客id + ProductId *int64 `gorm:"default:0;" json:"product_id"` // 产品id + TemplateTag *string `gorm:"default:'';" json:"template_tag"` // + SelectColorIndex *int64 `gorm:"default:0;" json:"select_color_index"` // 选择的颜色索引 + Logo *string `gorm:"default:'';" json:"logo"` // logo地址 + Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` // + Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` // +} +type FsProductCollectionModel struct { + db *gorm.DB + name string +} + +func NewFsProductCollectionModel(db *gorm.DB) *FsProductCollectionModel { + return &FsProductCollectionModel{db: db, name: "fs_product_collection"} +} diff --git a/model/gmodel/fs_product_collection_logic.go b/model/gmodel/fs_product_collection_logic.go new file mode 100644 index 00000000..e68225aa --- /dev/null +++ b/model/gmodel/fs_product_collection_logic.go @@ -0,0 +1,2 @@ +package gmodel +// TODO: 使用model的属性做你想做的 \ No newline at end of file diff --git a/model/gmodel/var_gen.go b/model/gmodel/var_gen.go index 96ae7dea..b29f8e91 100644 --- a/model/gmodel/var_gen.go +++ b/model/gmodel/var_gen.go @@ -67,6 +67,7 @@ type AllModelsGen struct { FsPay *FsPayModel // fs_pay 支付记录 FsPayEvent *FsPayEventModel // fs_pay_event 支付回调事件日志 FsProduct *FsProductModel // fs_product 产品表 + FsProductCollection *FsProductCollectionModel // fs_product_collection 产品收藏表 FsProductCopy1 *FsProductCopy1Model // fs_product_copy1 产品表 FsProductDesign *FsProductDesignModel // fs_product_design 产品设计表 FsProductDesignGather *FsProductDesignGatherModel // fs_product_design_gather @@ -178,6 +179,7 @@ func NewAllModels(gdb *gorm.DB) *AllModelsGen { FsPay: NewFsPayModel(gdb), FsPayEvent: NewFsPayEventModel(gdb), FsProduct: NewFsProductModel(gdb), + FsProductCollection: NewFsProductCollectionModel(gdb), FsProductCopy1: NewFsProductCopy1Model(gdb), FsProductDesign: NewFsProductDesignModel(gdb), FsProductDesignGather: NewFsProductDesignGatherModel(gdb), diff --git a/server/order/internal/logic/createorderlogic.go b/server/order/internal/logic/createorderlogic.go index 148078e4..5aaa7c8f 100644 --- a/server/order/internal/logic/createorderlogic.go +++ b/server/order/internal/logic/createorderlogic.go @@ -1,6 +1,7 @@ package logic import ( + "fmt" "fusenapi/constants" "fusenapi/service/repositories" "fusenapi/utils/auth" @@ -55,9 +56,25 @@ func (l *CreateOrderLogic) CreateOrder(req *types.CreateOrderReq, userinfo *auth } // 延时任务 - l.svcCtx.DelayQueue.AddTask(time.Now().Add(time.Minute*30), constants.QUEUE_NAME_ORDER, func(args ...interface{}) { + // l.svcCtx.DelayQueue.AddTask(time.Now().Add(time.Minute*30), constants.QUEUE_NAME_ORDER, func(args ...interface{}) { + // ctx := context.Background() + // orderSn := args[0].(string) + // svcCtx := svc.ServiceContext{ + // Config: l.svcCtx.Config, + // Repositories: l.svcCtx.Repositories, + // } + // svcCtx.Repositories.NewOrder.Close(ctx, &repositories.CloseReq{ + // OrderSn: orderSn, + // Type: 1, + // }) + // }, []interface{}{res.OrderSn}) + + // 延时任务 + time.AfterFunc(time.Minute*30, func() { + orderSn := res.OrderSn + fmt.Println("延时任务: OrderSn--", orderSn) ctx := context.Background() - orderSn := args[0].(string) + svcCtx := svc.ServiceContext{ Config: l.svcCtx.Config, Repositories: l.svcCtx.Repositories, @@ -66,7 +83,7 @@ func (l *CreateOrderLogic) CreateOrder(req *types.CreateOrderReq, userinfo *auth OrderSn: orderSn, Type: 1, }) - }, []interface{}{res.OrderSn}) + }) return resp.SetStatus(basic.CodeOK, map[string]interface{}{ "order_sn": res.OrderSn, diff --git a/server/order/internal/svc/servicecontext.go b/server/order/internal/svc/servicecontext.go index 74c47177..e109170c 100644 --- a/server/order/internal/svc/servicecontext.go +++ b/server/order/internal/svc/servicecontext.go @@ -21,10 +21,10 @@ type ServiceContext struct { func NewServiceContext(c config.Config) *ServiceContext { conn := initalize.InitMysql(c.SourceMysql) - delayQueue := initalize.InitDelayMessage() + // delayQueue := initalize.InitDelayMessage() repositories := initalize.NewAllRepositories(&initalize.NewAllRepositorieData{ - GormDB: conn, - DelayQueue: delayQueue, + GormDB: conn, + // DelayQueue: delayQueue, }) return &ServiceContext{ @@ -32,6 +32,6 @@ func NewServiceContext(c config.Config) *ServiceContext { MysqlConn: conn, AllModels: gmodel.NewAllModels(conn), Repositories: repositories, - DelayQueue: delayQueue, + // DelayQueue: delayQueue, } } diff --git a/server/order/internal/types/types.go b/server/order/internal/types/types.go index 9f32a256..6cc21a64 100644 --- a/server/order/internal/types/types.go +++ b/server/order/internal/types/types.go @@ -30,10 +30,10 @@ type CreatePrePaymentByBalanceReq struct { } type OrderListReq struct { - DeliveryMethod int64 `json:"delivery_method,options=[0,1,2],optional"` - OrderCycle string `json:"order_cycle,optional,options=[within_one_month,within_three_month,within_six_month,within_one_year]"` - CurrentPage int64 `json:"current_page,optional,default=1"` - PerPage int64 `json:"per_page,optional,default=10"` + DeliveryMethod int64 `form:"delivery_method,options=[0,1,2],optional"` + OrderCycle string `form:"order_cycle,optional,options=[within_one_month,within_three_month,within_six_month,within_one_year]"` + CurrentPage int64 `form:"current_page,optional,default=1"` + PerPage int64 `form:"per_page,optional,default=10"` } type Request struct { diff --git a/server/product/internal/handler/getproductlisthandler.go b/server/product/internal/handler/getproductlisthandler.go deleted file mode 100644 index 41360ef6..00000000 --- a/server/product/internal/handler/getproductlisthandler.go +++ /dev/null @@ -1,35 +0,0 @@ -package handler - -import ( - "net/http" - "reflect" - - "fusenapi/utils/basic" - - "fusenapi/server/product/internal/logic" - "fusenapi/server/product/internal/svc" - "fusenapi/server/product/internal/types" -) - -func GetProductListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - - var req types.GetProductListReq - userinfo, err := basic.RequestParse(w, r, svcCtx, &req) - if err != nil { - return - } - - // 创建一个业务逻辑层实例 - l := logic.NewGetProductListLogic(r.Context(), svcCtx) - - rl := reflect.ValueOf(l) - basic.BeforeLogic(w, r, rl) - - resp := l.GetProductList(&req, userinfo) - - if !basic.AfterLogic(w, r, rl, resp) { - basic.NormalAfterLogic(w, r, resp) - } - } -} diff --git a/server/product/internal/handler/getsuccessrecommandhandler.go b/server/product/internal/handler/getsuccessrecommandhandler.go deleted file mode 100644 index 63bdeae3..00000000 --- a/server/product/internal/handler/getsuccessrecommandhandler.go +++ /dev/null @@ -1,35 +0,0 @@ -package handler - -import ( - "net/http" - "reflect" - - "fusenapi/utils/basic" - - "fusenapi/server/product/internal/logic" - "fusenapi/server/product/internal/svc" - "fusenapi/server/product/internal/types" -) - -func GetSuccessRecommandHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - - var req types.GetSuccessRecommandReq - userinfo, err := basic.RequestParse(w, r, svcCtx, &req) - if err != nil { - return - } - - // 创建一个业务逻辑层实例 - l := logic.NewGetSuccessRecommandLogic(r.Context(), svcCtx) - - rl := reflect.ValueOf(l) - basic.BeforeLogic(w, r, rl) - - resp := l.GetSuccessRecommand(&req, userinfo) - - if !basic.AfterLogic(w, r, rl, resp) { - basic.NormalAfterLogic(w, r, resp) - } - } -} diff --git a/server/product/internal/handler/routes.go b/server/product/internal/handler/routes.go index 67db4302..e0a07c88 100644 --- a/server/product/internal/handler/routes.go +++ b/server/product/internal/handler/routes.go @@ -12,16 +12,6 @@ import ( func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { server.AddRoutes( []rest.Route{ - { - Method: http.MethodGet, - Path: "/api/product/list", - Handler: GetProductListHandler(serverCtx), - }, - { - Method: http.MethodGet, - Path: "/api/product/success-recommand", - Handler: GetSuccessRecommandHandler(serverCtx), - }, { Method: http.MethodGet, Path: "/api/product/get-size-by-product", diff --git a/server/product/internal/logic/calculateproductpricelogic.go b/server/product/internal/logic/calculateproductpricelogic.go index 22bb653a..ed2886b3 100644 --- a/server/product/internal/logic/calculateproductpricelogic.go +++ b/server/product/internal/logic/calculateproductpricelogic.go @@ -3,6 +3,7 @@ package logic import ( "encoding/json" "errors" + "fmt" "fusenapi/constants" "fusenapi/model/gmodel" "fusenapi/utils/auth" @@ -83,15 +84,38 @@ func (l *CalculateProductPriceLogic) CalculateProductPrice(req *types.CalculateP } fittingPrice = *fittingInfo.Price } + rangeLen := len(stepPrice.PriceRange) + stepRange := make([]interface{}, 0, rangeLen) + for rIndex, rangeInfo := range stepPrice.PriceRange { + //最后一个 + if rIndex+1 == rangeLen { + begin := format.NumToStringWithThousandthPercentile(fmt.Sprintf("%d", rangeInfo.StartQuantity)) + stepRange = append(stepRange, map[string]interface{}{ + "start": rangeInfo.StartQuantity, + "end": rangeInfo.EndQuantity, + "range_description": fmt.Sprintf(">=%s Units", begin), + "item_price": format.CentitoDollar(rangeInfo.Price+fittingPrice, 3), + }) + break + } + begin := format.NumToStringWithThousandthPercentile(fmt.Sprintf("%d", rangeInfo.StartQuantity)) + end := format.NumToStringWithThousandthPercentile(fmt.Sprintf("%d", rangeInfo.EndQuantity)) + stepRange = append(stepRange, map[string]interface{}{ + "start": rangeInfo.StartQuantity, + "end": rangeInfo.EndQuantity, + "range_description": fmt.Sprintf("%s-%s Units", begin, end), + "item_price": format.CentitoDollar(rangeInfo.Price+fittingPrice, 3), + }) + } totalPrice, itemPrice, err := l.svcCtx.Repositories.NewShoppingCart.CaculateStepPrice(req.PurchaseQuantity, stepPrice, fittingPrice) if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to calculate product price ") } return resp.SetStatusWithMessage(basic.CodeOK, "success", types.CalculateProductPriceRsp{ - ItemPrice: format.CentitoDollar(itemPrice, 3), - TotalPrice: format.CentitoDollarWithNoHalfAdjust(totalPrice, 2), - PurchaseQuantity: req.PurchaseQuantity, + ItemPrice: format.CentitoDollar(itemPrice, 3), + TotalPrice: format.CentitoDollarWithNoHalfAdjust(totalPrice, 2), + StepRange: stepRange, }) } diff --git a/server/product/internal/logic/getproductlistlogic.go b/server/product/internal/logic/getproductlistlogic.go deleted file mode 100644 index aa8d4daa..00000000 --- a/server/product/internal/logic/getproductlistlogic.go +++ /dev/null @@ -1,188 +0,0 @@ -package logic - -import ( - "context" - "encoding/json" - "errors" - "fusenapi/constants" - "fusenapi/model/gmodel" - "fusenapi/server/product/internal/svc" - "fusenapi/server/product/internal/types" - "fusenapi/utils/auth" - "fusenapi/utils/basic" - "fusenapi/utils/format" - "fusenapi/utils/image" - "math" - "sort" - "strings" - - "github.com/zeromicro/go-zero/core/logx" - "github.com/zeromicro/go-zero/core/stores/sqlc" - "gorm.io/gorm" -) - -type GetProductListLogic struct { - logx.Logger - ctx context.Context - svcCtx *svc.ServiceContext -} - -func NewGetProductListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetProductListLogic { - return &GetProductListLogic{ - Logger: logx.WithContext(ctx), - ctx: ctx, - svcCtx: svcCtx, - } -} - -// 获取产品列表 -func (l *GetProductListLogic) GetProductList(req *types.GetProductListReq, userinfo *auth.UserInfo) (resp *basic.Response) { - //如果是demo - if req.IsDemo == 1 { - var demo types.GetProductListRsp - if err := json.Unmarshal([]byte(constants.PRODUCT_LIST_DEMO), &demo); err != nil { - logx.Error(err) - return resp.SetStatusWithMessage(basic.CodeServiceErr, "demo data format err") - } - return resp.SetStatusWithMessage(basic.CodeOK, "success", demo) - } - if req.Page <= 0 { - req.Page = constants.DEFAULT_PAGE - } - //获取合适尺寸 - if req.Size > 0 { - req.Size = image.GetCurrentSize(req.Size) - } - pageSize := constants.DEFAULT_PAGE_SIZE - //查询用户信息(不用判断存在) - userModel := gmodel.NewFsUserModel(l.svcCtx.MysqlConn) - user, err := userModel.FindUserById(l.ctx, userinfo.UserId) - if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { - logx.Error(err) - return resp.SetStatusWithMessage(basic.CodeServiceErr, "get user info err") - } - //查询符合的产品列表 - productModel := gmodel.NewFsProductModel(l.svcCtx.MysqlConn) - productList, total, err := productModel.GetProductListByTypeIds(l.ctx, []int64{req.Cid}, int(req.Page), pageSize, "sort-desc") - if err != nil { - logx.Error(err) - return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product list") - } - productLen := len(productList) - if productLen == 0 { - return resp.SetStatusWithMessage(basic.CodeOK, "success") - } - //提取产品ids - productIds := make([]int64, 0, productLen) - for _, v := range productList { - productIds = append(productIds, v.Id) - } - productPriceModel := gmodel.NewFsProductPriceModel(l.svcCtx.MysqlConn) - productPriceList, err := productPriceModel.GetSimplePriceListByProductIds(l.ctx, productIds) - if err != nil { - logx.Error(err) - return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product min price list") - } - //存储产品最小价格 - mapProductMinPrice := make(map[int64]int64) - for _, v := range productPriceList { - priceStrSlic := strings.Split(v.Price, ",") - priceSlice, err := format.StrSlicToIntSlice(priceStrSlic) - if err != nil { - logx.Error(err) - return resp.SetStatusWithMessage(basic.CodeServiceErr, err.Error()) - } - if len(priceSlice) == 0 { - continue - } - sort.Ints(priceSlice) - mapProductMinPrice[v.ProductId] = int64(priceSlice[0]) - } - //获取模板 - productTemplateModel := gmodel.NewFsProductTemplateV2Model(l.svcCtx.MysqlConn) - productTemplatesV2, err := productTemplateModel.FindAllByProductIds(l.ctx, productIds, "") - if err != nil { - logx.Error(err) - return resp.SetStatusWithMessage(basic.CodeServiceErr, "get product template_v2 err") - } - mapProductTemplate := make(map[int64]struct{}) - for _, v := range productTemplatesV2 { - mapProductTemplate[*v.ProductId] = struct{}{} - } - //获取分类 - tagsModel := gmodel.NewFsTagsModel(l.svcCtx.MysqlConn) - tagInfo, err := tagsModel.FindOne(l.ctx, req.Cid) - if err != nil && !errors.Is(err, sqlc.ErrNotFound) { - if errors.Is(err, gorm.ErrRecordNotFound) { - return resp.SetStatusWithMessage(basic.CodeServiceErr, "tag is not exists") - } - logx.Error(err) - return resp.SetStatusWithMessage(basic.CodeServiceErr, "get tag err") - } - //获取产品尺寸数量 - productSizeModel := gmodel.NewFsProductSizeModel(l.svcCtx.MysqlConn) - productSizeCountList, err := productSizeModel.GetGroupProductSizeByStatus(l.ctx, productIds, 1) - if err != nil { - logx.Error(err) - return resp.SetStatusWithMessage(basic.CodeServiceErr, "get product size count err") - } - mapProductSizeCount := make(map[int64]int64) - for _, v := range productSizeCountList { - mapProductSizeCount[v.ProductId] = v.Num - } - //拼接返回 - itemList := make([]types.Items, 0, productLen) - for _, v := range productList { - minPrice, ok := mapProductMinPrice[v.Id] - _, tmpOk := mapProductTemplate[v.Id] - //无最小价格则不显示 || 没有模板也不显示 - if !ok || !tmpOk { - continue - } - sizeNum := int64(0) - if mapSizeNum, ok := mapProductSizeCount[v.Id]; ok { - sizeNum = mapSizeNum - } - item := types.Items{ - Id: v.Id, - Sn: *v.Sn, - Title: *v.Title, - Intro: *v.Intro, - IsEnv: *v.IsProtection, - IsMicro: *v.IsMicrowave, - SizeNum: uint32(sizeNum), - MinPrice: minPrice, - } - //千人千面处理 - r := image.ThousandFaceImageFormatReq{ - Size: int(req.Size), - IsThousandFace: 0, - Cover: *v.Cover, - CoverImg: *v.CoverImg, - CoverDefault: *v.CoverImg, - ProductId: v.Id, - UserId: user.Id, - } - if user.Id != 0 { - r.IsThousandFace = 1 - } - image.ThousandFaceImageFormat(&r) - item.Cover = r.Cover - item.CoverImg = r.CoverImg - item.CoverDefault = r.CoverDefault - itemList = append(itemList, item) - } - return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetProductListRsp{ - Ob: types.Ob{ - Items: itemList, - Meta: types.Meta{ - TotalCount: total, - PageCount: int64(math.Ceil(float64(total) / float64(pageSize))), - CurrentPage: int(req.Page), - PerPage: pageSize, - }, - }, - TypeName: *tagInfo.Title, - Description: *tagInfo.Description, - }) -} diff --git a/server/product/internal/logic/getproductsteppricelogic.go b/server/product/internal/logic/getproductsteppricelogic.go index 60527bcf..71a4f8fa 100644 --- a/server/product/internal/logic/getproductsteppricelogic.go +++ b/server/product/internal/logic/getproductsteppricelogic.go @@ -11,6 +11,7 @@ import ( "fusenapi/utils/basic" "fusenapi/utils/format" "gorm.io/gorm" + "strings" "fusenapi/server/product/internal/svc" "fusenapi/server/product/internal/types" @@ -50,15 +51,21 @@ func (l *GetProductStepPriceLogic) GetProductStepPrice(req *types.GetProductStep return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product info") } //查询产品价格 - modelPriceList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllByProductIdTag(l.ctx, req.ProductId, constants.TAG_MODEL, "id,size_id,part_id,step_price,packed_unit") + modelPriceList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllByProductIdTag(l.ctx, req.ProductId, constants.TAG_MODEL, "id,size_id,part_list,part_id,step_price,packed_unit") if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get model price list") } fittingIds := make([]int64, 0, len(modelPriceList)) for _, v := range modelPriceList { - if *v.PartId > 0 { - fittingIds = append(fittingIds, *v.PartId) + *v.PartList = strings.Trim(*v.PartList, ",") + if *v.PartList != "" { + tmpPartIds, err := format.StrSlicToInt64Slice(strings.Split(*v.PartList, ",")) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to parse model part list ") + } + fittingIds = append(fittingIds, tmpPartIds...) } } //查询配件价格列表 @@ -73,77 +80,38 @@ func (l *GetProductStepPriceLogic) GetProductStepPrice(req *types.GetProductStep } //遍历处理模型价格 mapRsp := make(map[string]interface{}) - for _, modelPriceInfo := range modelPriceList { + for _, modelInfo := range modelPriceList { var stepPrice gmodel.StepPriceJsonStruct - if err = json.Unmarshal(*modelPriceInfo.StepPrice, &stepPrice); err != nil { + if err = json.Unmarshal(*modelInfo.StepPrice, &stepPrice); err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse step price json") } rangeLen := len(stepPrice.PriceRange) if rangeLen == 0 { - return resp.SetStatusWithMessage(basic.CodeServiceErr, fmt.Sprintf("step price is not set:%d", modelPriceInfo.Id)) + return resp.SetStatusWithMessage(basic.CodeServiceErr, fmt.Sprintf("step price is not set:%d", modelInfo.Id)) } - //最小单价 - minPrice := stepPrice.PriceRange[rangeLen-1].Price - //最大单价 - maxPrice := stepPrice.PriceRange[0].Price - //购买数步进基数 - stepPurchaseQuantity := *modelPriceInfo.PackedUnit - //购买数步进基数描述 - stepPurchaseQuantityDescription := "主体装箱数为步进基数" - //配件价格 - fittingPrice := int64(0) - if *modelPriceInfo.PartId > 0 { - fittingPriceInfo, ok := mapFitting[*modelPriceInfo.PartId] - if !ok { - return resp.SetStatusWithMessage(basic.CodeServiceErr, fmt.Sprintf("fitting price is not exists:%d", *modelPriceInfo.PartId)) + *modelInfo.PartList = strings.Trim(*modelInfo.PartList, ",") + mapFittingUnit := make(map[string]interface{}) + if *modelInfo.PartList != "" { + tmpPartIds, err := format.StrSlicToInt64Slice(strings.Split(*modelInfo.PartList, ",")) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to parse model part list!! ") } - //最小/最大价格要加配件 - fittingPrice = *fittingPriceInfo.Price - minPrice += fittingPrice - maxPrice += fittingPrice - //如果配件装箱基数比主体大,则基数以配件为主 - if *fittingPriceInfo.PackedUnit > stepPurchaseQuantity { - stepPurchaseQuantity = *fittingPriceInfo.PackedUnit - stepPurchaseQuantityDescription = "配件装箱数为步进基数" + for _, partId := range tmpPartIds { + fittingInfo, ok := mapFitting[*modelInfo.PartId] + if !ok { + return resp.SetStatusWithMessage(basic.CodeServiceErr, fmt.Sprintf("fitting price is not exists:%d", *modelInfo.PartId)) + } + mapFittingUnit[fmt.Sprintf("_%d", partId)] = map[string]interface{}{ + "packed_unit": *fittingInfo.PackedUnit, //装箱个数 + } } } - stepRange := make([]interface{}, 0, rangeLen) - for rIndex, rangeInfo := range stepPrice.PriceRange { - //最后一个 - if rIndex+1 == rangeLen { - begin := format.NumToStringWithThousandthPercentile(fmt.Sprintf("%d", rangeInfo.StartQuantity)) - stepRange = append(stepRange, map[string]interface{}{ - "start": rangeInfo.StartQuantity, - "end": rangeInfo.EndQuantity, - "range_description": fmt.Sprintf(">=%s Units", begin), - "item_price": format.CentitoDollar(rangeInfo.Price+fittingPrice, 3), - }) - break - } - begin := format.NumToStringWithThousandthPercentile(fmt.Sprintf("%d", rangeInfo.StartQuantity)) - end := format.NumToStringWithThousandthPercentile(fmt.Sprintf("%d", rangeInfo.EndQuantity)) - stepRange = append(stepRange, map[string]interface{}{ - "start": rangeInfo.StartQuantity, - "end": rangeInfo.EndQuantity, - "range_description": fmt.Sprintf("%s-%s Units", begin, end), - "item_price": format.CentitoDollar(rangeInfo.Price+fittingPrice, 3), - }) - } - //计算起购数量的单价 - _, minBuyUnitsQuantityPrice, err := l.svcCtx.Repositories.NewShoppingCart.CaculateStepPrice(stepPrice.MinBuyUnitsNum, stepPrice, fittingPrice) - if err != nil { - return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get min buy quantity item price") - } - mapRsp[fmt.Sprintf("_%d", *modelPriceInfo.SizeId)] = map[string]interface{}{ - "step_purchase_quantity": stepPurchaseQuantity, - "step_purchase_quantity_description": stepPurchaseQuantityDescription, - "min_price": minPrice, - "max_price": maxPrice, - "step_range": stepRange, - "min_buy_units_quantity": stepPrice.MinBuyUnitsNum, - "min_buy_units_quantity_total_price": format.CentitoDollarWithNoHalfAdjust(minBuyUnitsQuantityPrice*stepPrice.MinBuyUnitsNum, 2), - "min_buy_units_quantity_item_price": format.CentitoDollar(minBuyUnitsQuantityPrice, 3), + mapRsp[fmt.Sprintf("_%d", *modelInfo.SizeId)] = map[string]interface{}{ + "min_buy_units_quantity": stepPrice.MinBuyUnitsNum, //起购数量 + "main_packed_unit": *modelInfo.PackedUnit, //主体装箱数 + "fitting": mapFittingUnit, } } return resp.SetStatusWithMessage(basic.CodeOK, "success", mapRsp) diff --git a/server/product/internal/logic/getsuccessrecommandlogic.go b/server/product/internal/logic/getsuccessrecommandlogic.go deleted file mode 100644 index 6fa90620..00000000 --- a/server/product/internal/logic/getsuccessrecommandlogic.go +++ /dev/null @@ -1,88 +0,0 @@ -package logic - -import ( - "context" - "errors" - "fusenapi/model/gmodel" - "fusenapi/server/product/internal/svc" - "fusenapi/server/product/internal/types" - "fusenapi/utils/auth" - "fusenapi/utils/basic" - "fusenapi/utils/image" - - "github.com/zeromicro/go-zero/core/logx" - "gorm.io/gorm" -) - -type GetSuccessRecommandLogic struct { - logx.Logger - ctx context.Context - svcCtx *svc.ServiceContext -} - -func NewGetSuccessRecommandLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetSuccessRecommandLogic { - return &GetSuccessRecommandLogic{ - Logger: logx.WithContext(ctx), - ctx: ctx, - svcCtx: svcCtx, - } -} - -// 获取推荐的产品列表 -func (l *GetSuccessRecommandLogic) GetSuccessRecommand(req *types.GetSuccessRecommandReq, userInfo *auth.UserInfo) (resp *basic.Response) { - if userInfo.GetIdType() != auth.IDTYPE_User { - return resp.SetStatusWithMessage(basic.CodeUnAuth, "please sign in first") - } - //获取用户信息 - userModel := gmodel.NewFsUserModel(l.svcCtx.MysqlConn) - user, err := userModel.FindUserById(l.ctx, userInfo.UserId) - if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { - logx.Error(err) - return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get user info") - } - if req.Num == 0 || req.Num > 500 { - req.Num = 8 - } - if req.Size > 0 { - req.Size = image.GetCurrentSize(req.Size) - } - //随机取8个产品 - productModel := gmodel.NewFsProductModel(l.svcCtx.MysqlConn) - productList, err := productModel.GetRandomProductList(l.ctx, int(req.Num)) - if err != nil { - logx.Error(err) - return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product list") - } - //没有推荐产品就返回 - if len(productList) == 0 { - return resp.SetStatusWithMessage(basic.CodeOK, "success") - } - list := make([]types.GetSuccessRecommandRsp, 0, len(productList)) - for _, v := range productList { - data := types.GetSuccessRecommandRsp{ - Title: *v.Title, - Sn: *v.Sn, - Id: v.Id, - SkuId: 0, //??????? - } - //千人千面处理 - r := image.ThousandFaceImageFormatReq{ - Size: int(req.Size), - IsThousandFace: 0, - Cover: *v.Cover, - CoverImg: *v.CoverImg, - CoverDefault: *v.CoverImg, - ProductId: v.Id, - UserId: user.Id, - } - if user.Id > 0 { - r.IsThousandFace = int(1) - } - image.ThousandFaceImageFormat(&r) - data.Cover = r.Cover - data.CoverImg = r.CoverImg - data.CoverDefault = r.CoverDefault - list = append(list, data) - } - return resp.SetStatusWithMessage(basic.CodeOK, "success", list) -} diff --git a/server/product/internal/types/types.go b/server/product/internal/types/types.go index 59bcb8a7..33475691 100644 --- a/server/product/internal/types/types.go +++ b/server/product/internal/types/types.go @@ -5,54 +5,6 @@ import ( "fusenapi/utils/basic" ) -type GetProductListReq struct { - Cid int64 `form:"cid"` - Size uint32 `form:"size"` - Page uint32 `form:"page,optional"` - IsDemo uint32 `form:"is_demo,optional"` -} - -type GetProductListRsp struct { - Ob Ob `json:"ob"` - TypeName string `json:"typeName"` - Description string `json:"description"` -} - -type Ob struct { - Items []Items `json:"items"` - Meta Meta `json:"_meta"` -} - -type Items struct { - Id int64 `json:"id"` - Sn string `json:"sn"` - Title string `json:"title"` - Cover string `json:"cover"` - Intro string `json:"intro"` - CoverImg string `json:"cover_img"` - IsEnv int64 `json:"isEnv"` - IsMicro int64 `json:"isMicro"` - SizeNum uint32 `json:"sizeNum"` - MinPrice int64 `json:"minPrice"` - CoverDefault string `json:"coverDefault"` -} - -type GetSuccessRecommandReq struct { - Num uint32 `form:"num"` - Size uint32 `form:"size"` - Sn string `form:"sn"` -} - -type GetSuccessRecommandRsp struct { - Title string `json:"title"` - Cover string `json:"cover"` - CoverImg string `json:"coverImg"` - Sn string `json:"sn"` - Id int64 `json:"id"` - SkuId int64 `json:"skuId"` - CoverDefault string `json:"coverDefault"` -} - type GetSizeByProductRsp struct { Id int64 `json:"id"` Name string `json:"name"` @@ -343,9 +295,9 @@ type CalculateProductPriceReq struct { } type CalculateProductPriceRsp struct { - ItemPrice string `json:"item_price"` - TotalPrice string `json:"total_price"` - PurchaseQuantity int64 `json:"purchase_quantity"` + ItemPrice string `json:"item_price"` + TotalPrice string `json:"total_price"` + StepRange interface{} `json:"step_range"` } type GetSizeByPidReq struct { diff --git a/server/resource/internal/types/types.go b/server/resource/internal/types/types.go index e8807725..e55d9bd3 100644 --- a/server/resource/internal/types/types.go +++ b/server/resource/internal/types/types.go @@ -28,6 +28,9 @@ type ResourceInfoReq struct { } type LogoCombineReq struct { + LogoUrl string `json:"logo_url"` // 合图参数 + TemplateTagColor TemplateTagColor `json:"template_tag_color"` + TemplateTagGroups []TemplateTagGroups `json:"template_tag_groups"` TemplateId int64 `json:"template_id"` // 合图参数 TemplateTag string `json:"template_tag"` // 合图参数 Website string `json:"website,optional"` // 合图参数 @@ -35,9 +38,6 @@ type LogoCombineReq struct { Address string `json:"address,optional"` // 合图参数 Phone string `json:"phone,optional"` // 合图参数 Qrcode string `json:"qrcode,optional"` // 合图参数 - LogoUrl string `json:"logo_url"` // 合图参数 - TemplateTagColor TemplateTagColor `json:"template_tag_color"` - TemplateTagGroups []TemplateTagGroups `json:"template_tag_groups"` } type TemplateTagColor struct { diff --git a/server/shopping-cart/internal/logic/addtocartlogic.go b/server/shopping-cart/internal/logic/addtocartlogic.go index 9b386fbf..2e28b3ef 100644 --- a/server/shopping-cart/internal/logic/addtocartlogic.go +++ b/server/shopping-cart/internal/logic/addtocartlogic.go @@ -13,6 +13,7 @@ import ( "fusenapi/utils/file" "fusenapi/utils/hash" "gorm.io/gorm" + "strings" "time" "github.com/zeromicro/go-zero/core/logx" @@ -53,9 +54,9 @@ func (l *AddToCartLogic) AddToCart(req *types.AddToCartReq, userinfo *auth.UserI if cartCount >= 100 { return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "sorry,the count of your carts can`t greater than 100") } - if req.RenderImage != "" { + //不是传路径则就是传base64 + if !strings.Contains(req.RenderImage, "https://") { //上传base64文件 - // 上传文件 var upload = file.Upload{ Ctx: l.ctx, MysqlConn: l.svcCtx.MysqlConn, @@ -270,6 +271,10 @@ func (l *AddToCartLogic) AddToCartParamVerify(req *types.AddToCartReq) error { if req.PurchaseQuantity <= 0 { return errors.New("purchase quantity can not less than 0 or equal 0") } + req.RenderImage = strings.Trim(req.RenderImage, " ") + if req.RenderImage == "" { + return errors.New("render image is required") + } return nil } diff --git a/server/upload/etc/upload.yaml b/server/upload/etc/upload.yaml index 36922560..7c6f72fb 100644 --- a/server/upload/etc/upload.yaml +++ b/server/upload/etc/upload.yaml @@ -19,6 +19,7 @@ AWS: Secret: sjCEv0JxATnPCxno2KNLm0X8oDc7srUR+4vkYhvm Token: BLMService: + Version: "2" Url: "http://18.119.109.254:8999" # Url: "http://192.168.1.9:8999" ImageProcess: diff --git a/server/upload/internal/config/config.go b/server/upload/internal/config/config.go index b474e0e4..ad24a1cd 100644 --- a/server/upload/internal/config/config.go +++ b/server/upload/internal/config/config.go @@ -22,6 +22,7 @@ type Config struct { } } BLMService struct { + Version string Url string ImageProcess struct { Url string diff --git a/server/upload/internal/logic/uploadlogologic.go b/server/upload/internal/logic/uploadlogologic.go index 7db0fed9..f5e0c6fa 100644 --- a/server/upload/internal/logic/uploadlogologic.go +++ b/server/upload/internal/logic/uploadlogologic.go @@ -171,12 +171,9 @@ func (l *UploadLogoLogic) UploadLogo(req *types.UploadLogoReq, userinfo *auth.Us logoHeight = 200 } var resultStr string - - var postMap = make(map[string]string, 1) - postMap["logo_url"] = logoUrl - resLogoStandard, err := l.svcCtx.Repositories.ImageHandle.LogoInfoSet(l.ctx, &repositories.LogoInfoSetReq{ LogoUrl: logoUrl, + Version: l.svcCtx.Config.BLMService.Version, }) if err != nil { diff --git a/server/websocket/internal/logic/datatransferlogic.go b/server/websocket/internal/logic/datatransferlogic.go index f313acc6..ac99c474 100644 --- a/server/websocket/internal/logic/datatransferlogic.go +++ b/server/websocket/internal/logic/datatransferlogic.go @@ -81,12 +81,12 @@ var ( // 用户标识的连接增删操作队列传输的值的结构 type userConnPoolCtlChanItem struct { - userId int64 //必须(两个用户id任意一个不为0) - guestId int64 //必须(两个用户id任意一个不为0) - uniqueId string //主连接池唯一标识(添加/删除时候必须) - message []byte //消息(发送消息传的,格式是经过标准输出序列化后的数据) - messageType constants.Websocket //消息类型(发送消息传的) - option int64 //操作 2发消息 1增加 0删除 + userId int64 //必须(两个用户id任意一个不为0) + guestId int64 //必须(两个用户id任意一个不为0) + uniqueId string //主连接池唯一标识(添加/删除时候必须) + message []byte //消息(发送消息传的,格式是经过标准输出序列化后的数据) + //messageType constants.Websocket //消息类型(发送消息传的) + option int64 //操作 2发消息 1增加 0删除 } // 每个连接的连接基本属性 diff --git a/server/websocket/internal/logic/ws_connect_statistics.go b/server/websocket/internal/logic/ws_connect_statistics.go index a1ea9731..226d1550 100644 --- a/server/websocket/internal/logic/ws_connect_statistics.go +++ b/server/websocket/internal/logic/ws_connect_statistics.go @@ -40,7 +40,7 @@ func ConsumeWebsocketConnectCountCtlChanData(ctx context.Context) { select { case num = <-websocketConnectCountCtlChan: currentWebsocketConnectCount += num - logx.Info("当前websocket连接总数:", currentWebsocketConnectCount) + //logx.Info("当前websocket连接总数:", currentWebsocketConnectCount) } } } diff --git a/server/websocket/internal/logic/ws_render_image.go b/server/websocket/internal/logic/ws_render_image.go index 2d20f1e5..a9a7b005 100644 --- a/server/websocket/internal/logic/ws_render_image.go +++ b/server/websocket/internal/logic/ws_render_image.go @@ -24,7 +24,7 @@ var ( //每个websocket渲染任务缓冲队列长度默认值 renderChanLen = 500 //每个websocket渲染并发数 - renderChanConcurrency = 500 + renderChanConcurrency = 10 ) // 渲染处理器 @@ -55,7 +55,6 @@ func (r *renderProcessor) allocationMessage(w *wsConnectItem, data []byte) { w.extendRenderProperty.selectColorIndex = renderImageData.RenderData.TemplateTagColor.SelectedColorIndex //让之前的失效 w.extendRenderProperty.renderCtxCancelFunc() - logx.Info("模板标签/颜色更换上下文取消") //重新赋值 w.extendRenderProperty.renderCtx, w.extendRenderProperty.renderCtxCancelFunc = context.WithCancel(w.logic.ctx) } @@ -85,18 +84,42 @@ func (w *wsConnectItem) consumeRenderImageData() { case <-w.closeChan: //已关闭 return case data := <-w.extendRenderProperty.renderChan: //消费数据 - logx.Info("准备执行任务。。。。。") + //标签不一样 + if data.RenderData.TemplateTag != w.extendRenderProperty.templateTag { + //logx.Info("标签不一致,丢弃消息") + continue + } + //颜色不一致 + if data.RenderData.TemplateTagColor.SelectedColorIndex != w.extendRenderProperty.selectColorIndex { + //logx.Info("颜色不一致,丢弃消息") + continue + } limitChan <- struct{}{} - logx.Info("执行任务中。。。。。") go func(d websocket_data.RenderImageReqMsg) { defer func() { if err := recover(); err != nil { - logx.Error("func renderImage panic:", err) + logx.Error("func renderImage main panic:", err) } }() + //临时chan用select io多路复用去判断携程退出 + tmpChan := make(chan struct{}, 1) + defer close(tmpChan) defer func() { <-limitChan }() + go func() { + defer func() { + if err := recover(); err != nil { + logx.Error("func renderImage panic:", err) + } + }() + select { + case <-w.extendRenderProperty.renderCtx.Done(): + panic("=========渲染取消旧的上下文=======") + case <-tmpChan: + return + } + }() w.renderImage(d) }(data) } @@ -159,25 +182,7 @@ func (w *wsConnectItem) renderImage(renderImageData websocket_data.RenderImageRe logx.Error("failed to get element ,", err) return } - //获取模板开关信息并且对于没有默认值的给赋值默认值(但凡DIY有一个是空的就要请求默认数据) - /*if renderImageData.RenderData.Website == "" || renderImageData.RenderData.Phone == "" || renderImageData.RenderData.Address == "" || renderImageData.RenderData.Qrcode == "" || renderImageData.RenderData.Slogan == "" { - templateSwitchInfo := template_switch_info.GetTemplateSwitchInfo(productTemplate.Id, productTemplate.TemplateInfo, *productTemplate.MaterialImg) - if renderImageData.RenderData.Website == "" && templateSwitchInfo.MaterialData.Website.IfShow { - renderImageData.RenderData.Website = templateSwitchInfo.MaterialData.Website.DefaultValue - } - if renderImageData.RenderData.Phone == "" && templateSwitchInfo.MaterialData.Phone.IfShow { - renderImageData.RenderData.Phone = templateSwitchInfo.MaterialData.Phone.DefaultValue - } - if renderImageData.RenderData.Address == "" && templateSwitchInfo.MaterialData.Address.IfShow { - renderImageData.RenderData.Address = templateSwitchInfo.MaterialData.Address.DefaultValue - } - if renderImageData.RenderData.Qrcode == "" && templateSwitchInfo.MaterialData.QRcode.IfShow { - renderImageData.RenderData.Qrcode = templateSwitchInfo.MaterialData.QRcode.DefaultValue - } - if renderImageData.RenderData.Slogan == "" && templateSwitchInfo.MaterialData.Slogan.IfShow { - renderImageData.RenderData.Slogan = templateSwitchInfo.MaterialData.Slogan.DefaultValue - } - }*/ + //获取刀版图 combineReq := repositories.LogoCombineReq{ UserId: renderImageData.RenderData.UserId, diff --git a/server/websocket/internal/logic/ws_reuse_last_connect.go b/server/websocket/internal/logic/ws_reuse_last_connect.go index f788b8fd..8dbe13ca 100644 --- a/server/websocket/internal/logic/ws_reuse_last_connect.go +++ b/server/websocket/internal/logic/ws_reuse_last_connect.go @@ -70,7 +70,7 @@ func (r *reuseConnProcessor) allocationMessage(w *wsConnectItem, data []byte) { createUserConnPoolElement(w.userId, w.guestId, wid) rsp := w.respondDataFormat(constants.WEBSOCKET_CONNECT_SUCCESS, wid) w.sendToOutChan(rsp) - logx.Info("重新绑定websocket连接标识成功") + //logx.Info("重新绑定websocket连接标识成功") } // 获取用户拼接部分(复用标识用到) diff --git a/server/websocket/internal/logic/ws_user_connect_pool.go b/server/websocket/internal/logic/ws_user_connect_pool.go index 8f02bb1d..a83fd8ed 100644 --- a/server/websocket/internal/logic/ws_user_connect_pool.go +++ b/server/websocket/internal/logic/ws_user_connect_pool.go @@ -19,12 +19,11 @@ func createUserConnPoolElement(userId, guestId int64, uniqueId string) { return } data := userConnPoolCtlChanItem{ - userId: userId, - guestId: guestId, - uniqueId: uniqueId, - message: nil, - messageType: "", - option: 1, + userId: userId, + guestId: guestId, + uniqueId: uniqueId, + message: nil, + option: 1, } select { case userConnPoolCtlChan <- data: @@ -38,17 +37,13 @@ func deleteUserConnPoolElement(userId, guestId int64, uniqueId string) { return } data := userConnPoolCtlChanItem{ - userId: userId, - guestId: guestId, - uniqueId: uniqueId, - message: nil, - messageType: "", - option: 0, - } - select { - case userConnPoolCtlChan <- data: - return + userId: userId, + guestId: guestId, + uniqueId: uniqueId, + message: nil, + option: 0, } + userConnPoolCtlChan <- data } // 根据用户索引发现链接并发送(广播)消息到出口队列 @@ -89,7 +84,7 @@ func ConsumeUserConnPoolCtlChanData(ctx context.Context) { userKey = getmapUserConnPoolUniqueId(data.userId, data.guestId) switch data.option { case 2: //发送消息 - logx.Info("通过用户id索引发送消息") + //logx.Info("通过用户id索引发送消息") mapUserUniqueId, ok := mapUserConnPool[userKey] if !ok { logx.Info("通过用户id索引发送消息,连接不存在,用户索引key:", userKey) @@ -110,7 +105,7 @@ func ConsumeUserConnPoolCtlChanData(ctx context.Context) { originConn.sendToOutChan(data.message) } case 1: //添加 - logx.Info("添加用户id索引标识:", data.uniqueId) + //logx.Info("添加用户id索引标识:", data.uniqueId) //存在这个用户的map池子 if mapUserUniqueId, ok := mapUserConnPool[userKey]; ok { mapUserUniqueId[data.uniqueId] = struct{}{} @@ -119,7 +114,7 @@ func ConsumeUserConnPoolCtlChanData(ctx context.Context) { mapUserConnPool[userKey][data.uniqueId] = struct{}{} } case 0: //删除 - logx.Info("删除用户id索引标识:", data.uniqueId) + //logx.Info("删除用户id索引标识:", data.uniqueId) if mapUserUniqueId, ok := mapUserConnPool[userKey]; ok { delete(mapUserUniqueId, data.uniqueId) } diff --git a/server_api/order.api b/server_api/order.api index 848b1464..5c53de53 100644 --- a/server_api/order.api +++ b/server_api/order.api @@ -54,8 +54,8 @@ type CreatePrePaymentByBalanceReq { } type OrderListReq { - DeliveryMethod int64 `json:"delivery_method,options=[0,1,2],optional"` - OrderCycle string `json:"order_cycle,optional,options=[within_one_month,within_three_month,within_six_month,within_one_year]"` - CurrentPage int64 `json:"current_page,optional,default=1"` - PerPage int64 `json:"per_page,optional,default=10"` + DeliveryMethod int64 `form:"delivery_method,options=[0,1,2],optional"` + OrderCycle string `form:"order_cycle,optional,options=[within_one_month,within_three_month,within_six_month,within_one_year]"` + CurrentPage int64 `form:"current_page,optional,default=1"` + PerPage int64 `form:"per_page,optional,default=10"` } \ No newline at end of file diff --git a/server_api/product.api b/server_api/product.api index 23c3e8fd..7485ebcd 100644 --- a/server_api/product.api +++ b/server_api/product.api @@ -10,12 +10,6 @@ info ( import "basic.api" service product { - //获取产品列表 - @handler GetProductListHandler - get /api/product/list(GetProductListReq) returns (response); - //获取支付成功后推荐产品 - @handler GetSuccessRecommandHandler - get /api/product/success-recommand(GetSuccessRecommandReq) returns (response); //获取分类下的产品以及尺寸 @handler GetSizeByProductHandler get /api/product/get-size-by-product(request) returns (response); @@ -83,51 +77,6 @@ service product { //*********************推荐产品接口结束×××××××××××××××××××××××××× } -//获取产品列表 -type GetProductListReq { - Cid int64 `form:"cid"` - Size uint32 `form:"size"` - Page uint32 `form:"page,optional"` - IsDemo uint32 `form:"is_demo,optional"` -} -type GetProductListRsp { - Ob Ob `json:"ob"` - TypeName string `json:"typeName"` - Description string `json:"description"` -} -type Ob { - Items []Items `json:"items"` - Meta Meta `json:"_meta"` -} -type Items { - Id int64 `json:"id"` - Sn string `json:"sn"` - Title string `json:"title"` - Cover string `json:"cover"` - Intro string `json:"intro"` - CoverImg string `json:"cover_img"` - IsEnv int64 `json:"isEnv"` - IsMicro int64 `json:"isMicro"` - SizeNum uint32 `json:"sizeNum"` - MinPrice int64 `json:"minPrice"` - CoverDefault string `json:"coverDefault"` -} -//获取支付成功后推荐产品 -type GetSuccessRecommandReq { - Num uint32 `form:"num"` - Size uint32 `form:"size"` - Sn string `form:"sn"` -} -type GetSuccessRecommandRsp { - Title string `json:"title"` - Cover string `json:"cover"` - CoverImg string `json:"coverImg"` - Sn string `json:"sn"` - Id int64 `json:"id"` - SkuId int64 `json:"skuId"` - CoverDefault string `json:"coverDefault"` -} - //获取分类下的产品以及尺寸 type GetSizeByProductRsp { Id int64 `json:"id"` @@ -394,9 +343,9 @@ type CalculateProductPriceReq { PurchaseQuantity int64 `json:"purchase_quantity"` } type CalculateProductPriceRsp { - ItemPrice string `json:"item_price"` - TotalPrice string `json:"total_price"` - PurchaseQuantity int64 `json:"purchase_quantity"` + ItemPrice string `json:"item_price"` + TotalPrice string `json:"total_price"` + StepRange interface{} `json:"step_range"` } //获取产品尺寸列表 type GetSizeByPidReq { diff --git a/server_api/resource.api b/server_api/resource.api index 433c4116..f71b6234 100644 --- a/server_api/resource.api +++ b/server_api/resource.api @@ -55,17 +55,16 @@ type ( type ( LogoCombineReq { - TemplateId int64 `json:"template_id"` // 合图参数 - TemplateTag string `json:"template_tag"` // 合图参数 - Website string `json:"website,optional"` // 合图参数 - Slogan string `json:"slogan,optional"` // 合图参数 - Address string `json:"address,optional"` // 合图参数 - Phone string `json:"phone,optional"` // 合图参数 - Qrcode string `json:"qrcode,optional"` // 合图参数 - LogoUrl string `json:"logo_url"` // 合图参数 - TemplateTagColor TemplateTagColor `json:"template_tag_color"` - + LogoUrl string `json:"logo_url"` // 合图参数 + TemplateTagColor TemplateTagColor `json:"template_tag_color"` TemplateTagGroups []TemplateTagGroups `json:"template_tag_groups"` + TemplateId int64 `json:"template_id"` // 合图参数 + TemplateTag string `json:"template_tag"` // 合图参数 + Website string `json:"website,optional"` // 合图参数 + Slogan string `json:"slogan,optional"` // 合图参数 + Address string `json:"address,optional"` // 合图参数 + Phone string `json:"phone,optional"` // 合图参数 + Qrcode string `json:"qrcode,optional"` // 合图参数 } TemplateTagColor { Colors [][]string `json:"colors"` // 颜色组合 diff --git a/service/repositories/image_handle.go b/service/repositories/image_handle.go index 7fbe4806..19a2c8c6 100644 --- a/service/repositories/image_handle.go +++ b/service/repositories/image_handle.go @@ -160,6 +160,7 @@ func (l *defaultImageHandle) LogoInfo(ctx context.Context, in *LogoInfoReq) (*Lo type ( LogoInfoSetReq struct { LogoUrl string `json:"logo_url"` + Version string `json:"version"` } LogoInfoSetRes struct { Res string `json:"res"` @@ -168,8 +169,9 @@ type ( func (l *defaultImageHandle) LogoInfoSet(ctx context.Context, in *LogoInfoSetReq) (*LogoInfoSetRes, error) { var resultBLM constants.BLMServiceUrlResult - postMap := make(map[string]string, 1) + postMap := make(map[string]string, 2) postMap["logo_url"] = in.LogoUrl + postMap["version"] = in.Version logc.Infof(ctx, "算法请求--LOGO基础信息--开始时间:%v", time.Now().UTC()) err := curl.NewClient(ctx, &curl.Config{ @@ -306,7 +308,7 @@ func (l *defaultImageHandle) LogoCombine(ctx context.Context, in *LogoCombineReq "color": in.TemplateTagColor.Color, "index": in.TemplateTagColor.Index, } - var postMap = make(map[string]interface{}, 2) + var postMap = make(map[string]interface{}, 3) postMap["module_data"] = moduleDataMap postMap["tag_data"] = in.ProductTemplateTagGroups postMap["param_data"] = combineParam diff --git a/service/repositories/order.go b/service/repositories/order.go index e9846d19..37c3a8ea 100644 --- a/service/repositories/order.go +++ b/service/repositories/order.go @@ -210,24 +210,27 @@ func (d *defaultOrder) CloseList(ctx context.Context, in *CloseListReq) (res *Cl for _, orderInfo := range orderList { var ntime = time.Now().UTC() var cptime = orderInfo.Ctime.UTC().Add(time.Minute * 30) - var dtime time.Time + var dtime time.Duration var dd = ntime.Unix() - cptime.Unix() if dd > 0 { - dtime = time.Now().Add(time.Second * 0) + dtime = time.Second * 0 } else { - dtime = time.Now().Add(time.Second * time.Duration(math.Abs(float64(dd)))) + dtime = time.Second * time.Duration(math.Abs(float64(dd))) } if in.Type == 1 { // 延时任务 - d.DelayQueue.AddTask(dtime, constants.QUEUE_NAME_ORDER, func(args ...interface{}) { + time.AfterFunc(dtime, func() { + orderSn := orderInfo.OrderSn + fmt.Println("延时任务: OrderSn--", orderSn) ctx := context.Background() - orderSn := args[0].(string) + logc.Infof(ctx, "order CloseList, orderSn: %s", orderSn) d.Close(ctx, &CloseReq{ - OrderSn: orderSn, + OrderSn: *orderSn, Type: 1, }) - }, []interface{}{*orderInfo.OrderSn}) + }) + } } return nil, nil @@ -687,7 +690,8 @@ func (d *defaultOrder) CreatePrePaymentByDeposit(ctx context.Context, in *Create ntimeTimeOut := ntime.Unix() // 测试超时支付不限制 - if ctimeTimeOut == ntimeTimeOut { + if ctimeTimeOut < ntimeTimeOut { + // if ctimeTimeOut == ntimeTimeOut { errorCode = *basic.CodeErrOrderCreatePrePaymentTimeout err = errors.New("order pay timeout") logc.Errorf(ctx, "create prePayment deposit failed, err: %v", err) @@ -740,7 +744,7 @@ func (d *defaultOrder) CreatePrePaymentByDeposit(ctx context.Context, in *Create var table = gmodel.NewAllModels(d.MysqlConn).FsOrder.TableName() var resUpdate *gorm.DB if in.DeliveryMethod == constants.DELIVERYMETHODDIRECTMAIL { - resUpdate = d.MysqlConn.Exec(fmt.Sprintf("UPDATE %s SET `order_address` = JSON_MERGE_PATCH(`order_address`,?),`status_link` = JSON_MERGE_PATCH(`status_link`,?), `delivery_method` = ? , `utime` = ? WHERE `id` = ?", table), orderAddressByte, statusLinkByte, in.DeliveryMethod, ntime, orderInfo.Id) + resUpdate = d.MysqlConn.Exec(fmt.Sprintf("UPDATE %s SET `delivery_method` = ?, `utime` = ?, `order_address` = JSON_MERGE_PATCH(`order_address`,?), `status_link` = JSON_MERGE_PATCH(`status_link`,?) WHERE `id` = ?", table), ntime, in.DeliveryMethod, orderAddressByte, statusLinkByte, orderInfo.Id) } else { resUpdate = d.MysqlConn.Exec(fmt.Sprintf("UPDATE %s SET `delivery_method` = ? , `utime` = ? WHERE `id` = ?", table), in.DeliveryMethod, ntime, orderInfo.Id) } @@ -807,11 +811,11 @@ func (d *defaultOrder) CreatePrePaymentByDeposit(ctx context.Context, in *Create func (d *defaultOrder) List(ctx context.Context, in *ListReq) (res *ListRes, err error) { var orderList []gmodel.FsOrder model := d.MysqlConn.Model(&gmodel.FsOrder{}).Where("is_del = ?", 0) + // model.Where("pay_status > ?", 0) if in.UserId != 0 { model.Where("user_id = ?", in.UserId) } - // Where("pay_status > ?", 0) if in.DeliveryMethod != 0 { model.Where("delivery_method = ?", in.DeliveryMethod) } @@ -1016,8 +1020,13 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe return errors.New("shoppingCartProductModel3d.StepPrice nil") } + var fittingPrice int64 + if shoppingCart.ShoppingCartProductModel3dFitting != nil { + fittingPrice = *shoppingCart.ShoppingCartProductModel3dFitting.Price + } + /* 计算价格 */ - productTotalPrice, productPrice, err := NewShoppingCart(tx, nil, nil).CaculateStepPrice(*shoppingCart.PurchaseQuantity, stepPriceJson, *shoppingCart.ShoppingCartProductModel3dFitting.Price) + productTotalPrice, productPrice, err := NewShoppingCart(tx, nil, nil).CaculateStepPrice(*shoppingCart.PurchaseQuantity, stepPriceJson, fittingPrice) if err != nil { errorCode = *basic.CodeErrOrderCreatProductPriceAbsent errorCode.Message = "create order failed, step price of product '" + shoppingCartSnapshot.ProductInfo.ProductName + "'is failed" @@ -1049,10 +1058,6 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe CurrentCurrency: in.CurrentCurrency, OriginalCurrency: in.OriginalCurrency, }), - ExpectedDelivery: &gmodel.ExpectedDelivery{ - Current: in.ExpectedDeliveryTime, - Initiate: in.ExpectedDeliveryTime, - }, PurchaseQuantity: &gmodel.PurchaseQuantity{ Current: *shoppingCart.PurchaseQuantity, Initiate: *shoppingCart.PurchaseQuantity, @@ -1077,6 +1082,8 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe }, }, IsHighlyCustomized: *shoppingCart.IsHighlyCustomized, + RenderImage: shoppingCartSnapshot.RenderImage, + CartId: shoppingCart.Id, } orderProductList = append(orderProductList, &productInter) shoppingProductSnapshotList = append(shoppingProductSnapshotList, shoppingCart.ShoppingCartProduct) @@ -1155,6 +1162,12 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe byteShoppingCartSnapshot, _ := json.Marshal(shoppingCartSnapshotList) byteShoppingProductSnapshot, _ := json.Marshal(shoppingProductSnapshotList) byteStatusLink, _ := json.Marshal(statusLink) + byteOrderMetadata, _ := json.Marshal(gmodel.OrderMetadata{ + ExpectedDeliveryTime: gmodel.ExpectedDelivery{ + Current: in.ExpectedDeliveryTime, + Initiate: in.ExpectedDeliveryTime, + }, + }) // 创建订单 resultCreate := tx.Create(&gmodel.FsOrder{ @@ -1170,6 +1183,7 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe Status: (*int64)(&status), PayStatus: (*int64)(&payStatus), Ctime: &nowTime, + Metadata: &byteOrderMetadata, }) if resultCreate.Error != nil { @@ -1336,12 +1350,19 @@ func (d *defaultOrder) OrderDetailHandler(ctx context.Context, orderInfo *gmodel return nil, err } } - var status = order.GetOrderStatusCurrent(statusLink, constants.OrderStatusCode(*orderInfo.Status)) - var orderDetail gmodel.OrderDetail - var orderMetadata map[string]interface{} + + var orderMetadata gmodel.OrderMetadata if orderInfo.Metadata != nil { json.Unmarshal(*orderInfo.Metadata, &orderMetadata) } + // 预计到货时间 + var expectedTime = orderMetadata.ExpectedDeliveryTime.Current + + var status = order.GetOrderStatusCurrent(statusLink, constants.OrderStatusCode(*orderInfo.Status)) + status.ExpectedTime = &expectedTime + + var orderDetail gmodel.OrderDetail + if original == 1 { orderDetail.DeliveryAddress = orderAddress orderDetail.OrderAmount = orderAmount @@ -1366,32 +1387,35 @@ func (d *defaultOrder) OrderDetailHandler(ctx context.Context, orderInfo *gmodel for _, productValue := range orderProduct { var shoppingCartSnapshotData gmodel.FsShoppingCartData for _, shoppingCartSnapshotValue := range shoppingCartSnapshot { - snapshot, err := d.OrderShoppingCartSnapshotHandler(ctx, shoppingCartSnapshotValue.Snapshot) - if err != nil { - logc.Errorf(ctx, "OrderDetailHandler OrderShoppingCartSnapshotHandler failed, err: %v", err) - return nil, err + if productValue.CartId == shoppingCartSnapshotValue.Id { + + snapshot, err := d.OrderShoppingCartSnapshotHandler(ctx, shoppingCartSnapshotValue.Snapshot) + if err != nil { + logc.Errorf(ctx, "OrderDetailHandler OrderShoppingCartSnapshotHandler failed, err: %v", err) + return nil, err + } + shoppingCartSnapshotData.Id = shoppingCartSnapshotValue.Id + shoppingCartSnapshotData.UserId = shoppingCartSnapshotValue.UserId + shoppingCartSnapshotData.ProductId = shoppingCartSnapshotValue.ProductId + shoppingCartSnapshotData.TemplateId = shoppingCartSnapshotValue.TemplateId + shoppingCartSnapshotData.ModelId = shoppingCartSnapshotValue.ModelId + shoppingCartSnapshotData.SizeId = shoppingCartSnapshotValue.SizeId + shoppingCartSnapshotData.LightId = shoppingCartSnapshotValue.LightId + shoppingCartSnapshotData.FittingId = shoppingCartSnapshotValue.FittingId + shoppingCartSnapshotData.PurchaseQuantity = shoppingCartSnapshotValue.PurchaseQuantity + shoppingCartSnapshotData.IsSelected = shoppingCartSnapshotValue.IsSelected + shoppingCartSnapshotData.IsSelected = shoppingCartSnapshotValue.IsSelected + shoppingCartSnapshotData.IsHighlyCustomized = shoppingCartSnapshotValue.IsHighlyCustomized + shoppingCartSnapshotData.Ctime = shoppingCartSnapshotValue.Ctime + shoppingCartSnapshotData.Utime = shoppingCartSnapshotValue.Utime + shoppingCartSnapshotData.Snapshot = &snapshot } - shoppingCartSnapshotData.Id = shoppingCartSnapshotValue.Id - shoppingCartSnapshotData.UserId = shoppingCartSnapshotValue.UserId - shoppingCartSnapshotData.ProductId = shoppingCartSnapshotValue.ProductId - shoppingCartSnapshotData.TemplateId = shoppingCartSnapshotValue.TemplateId - shoppingCartSnapshotData.ModelId = shoppingCartSnapshotValue.ModelId - shoppingCartSnapshotData.SizeId = shoppingCartSnapshotValue.SizeId - shoppingCartSnapshotData.LightId = shoppingCartSnapshotValue.LightId - shoppingCartSnapshotData.FittingId = shoppingCartSnapshotValue.FittingId - shoppingCartSnapshotData.PurchaseQuantity = shoppingCartSnapshotValue.PurchaseQuantity - shoppingCartSnapshotData.IsSelected = shoppingCartSnapshotValue.IsSelected - shoppingCartSnapshotData.IsSelected = shoppingCartSnapshotValue.IsSelected - shoppingCartSnapshotData.IsHighlyCustomized = shoppingCartSnapshotValue.IsHighlyCustomized - shoppingCartSnapshotData.Ctime = shoppingCartSnapshotValue.Ctime - shoppingCartSnapshotData.Utime = shoppingCartSnapshotValue.Utime - shoppingCartSnapshotData.Snapshot = &snapshot } orderProductItem := gmodel.OrderProduct{ TotalPrice: order.GetAmountInfoFormat(&productValue.TotalPrice), ItemPrice: order.GetAmountInfoFormat(&productValue.ItemPrice), - ExpectedDeliveryTime: &productValue.ExpectedDelivery.Current, + ExpectedDeliveryTime: &expectedTime, PurchaseQuantity: *productValue.PurchaseQuantity, ProductId: productValue.ProductId, ProductSn: productValue.ProductSn, @@ -1404,6 +1428,7 @@ func (d *defaultOrder) OrderDetailHandler(ctx context.Context, orderInfo *gmodel SizeInfo: productValue.SizeInfo, FittingInfo: productValue.FittingInfo, IsHighlyCustomized: productValue.IsHighlyCustomized, + RenderImage: productValue.RenderImage, } orderProductList = append(orderProductList, orderProductItem) diff --git a/service/repositories/shopping_cart.go b/service/repositories/shopping_cart.go index afc7e18f..ad6410ec 100644 --- a/service/repositories/shopping_cart.go +++ b/service/repositories/shopping_cart.go @@ -5,9 +5,10 @@ import ( "errors" "fusenapi/model/gmodel" "fusenapi/utils/hash" + "strings" + "github.com/aws/aws-sdk-go/aws/session" "gorm.io/gorm" - "strings" ) func NewShoppingCart(gormDB *gorm.DB, bLMServiceUrl *string, awsSession *session.Session) ShoppingCart { diff --git a/utils/curl/client_resty.go b/utils/curl/client_resty.go index abbfd46f..aa3a2311 100644 --- a/utils/curl/client_resty.go +++ b/utils/curl/client_resty.go @@ -86,7 +86,8 @@ type ( // PostJson请求 func (c *defaultClient) PostJson(jsonData interface{}, res interface{}) error { - //logc.Infof(c.ctx, "客户端名称 Client PostJson jsonData:%+v", jsonData) + //jsonDataB, _ := json.Marshal(jsonData) + //logc.Infof(c.ctx, "客户端名称 Client PostJson jsonData:%+v", string(jsonDataB)) logc.Infof(c.ctx, "客户端名称 请求开始时间:%+v", time.Now().UTC()) resp, err := c.client.