diff --git a/.gitignore b/.gitignore index 9608b9af..c9f5f8d6 100644 --- a/.gitignore +++ b/.gitignore @@ -44,4 +44,6 @@ shared-state *.zip -vendor \ No newline at end of file +vendor + +grpc_server/gen \ No newline at end of file diff --git a/model/gmodel/fs_address_logic.go b/model/gmodel/fs_address_logic.go index 08b747f2..7440e159 100755 --- a/model/gmodel/fs_address_logic.go +++ b/model/gmodel/fs_address_logic.go @@ -2,17 +2,19 @@ package gmodel import ( "context" + "time" + "github.com/zeromicro/go-zero/core/logx" "gorm.io/gorm" ) -func (a *FsAddressModel) GetOne(ctx context.Context, id int64, userId int64) (resp *FsAddress, err error) { - err = a.db.WithContext(ctx).Model(&FsAddress{}).Where("`id` = ? and `user_id` = ? and `status` = ? ", id, userId, 1).Take(&resp).Error +func (a *FsAddressModel) GetOne(ctx context.Context, addressId int64, userId int64) (resp *FsAddress, err error) { + err = a.db.WithContext(ctx).Model(&FsAddress{}).Where("`address_id` = ? and `user_id` = ? and `status` = ? ", addressId, userId, 1).Take(&resp).Error return resp, err } func (a *FsAddressModel) GetUserAllAddress(ctx context.Context, userId int64) (resp []FsAddress, err error) { - err = a.db.WithContext(ctx).Model(&FsAddress{}).Where("`user_id` = ? and `status` = ?", userId, 1).Order("`id` DESC").Find(&resp).Error + err = a.db.WithContext(ctx).Model(&FsAddress{}).Where("`user_id` = ? and `status` = ?", userId, 1).Order("`ltime` DESC").Find(&resp).Error if err != nil { return nil, err } @@ -21,8 +23,8 @@ func (a *FsAddressModel) GetUserAllAddress(ctx context.Context, userId int64) (r func (a *FsAddressModel) CreateOne(ctx context.Context, address *FsAddress) (result *FsAddress, err error) { - err = a.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { - // now := time.Now().UTC().Unix() + err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error { + now := time.Now().UTC() result = &FsAddress{ UserId: address.UserId, AddressName: address.AddressName, @@ -37,9 +39,26 @@ func (a *FsAddressModel) CreateOne(ctx context.Context, address *FsAddress) (res ZipCode: address.ZipCode, Status: address.Status, IsDefault: address.IsDefault, + Ctime: &now, + Utime: &now, + Ltime: &now, } - return tx.Create(result).Error + // lastOne := &FsAddress{} + // err = tx.Where("user_id = ?", lastOne.UserId).Order("ltime ASC").Take(&lastOne).Error + // if err == gorm.ErrRecordNotFound { + // result.Ltime = &now + // return tx.Model(&FsAddress{}).Create(result).Error + // } + // if err != nil { + // return err + // } + + // // 根据lastOne处理时间 + + // ltime := (*lastOne.Ltime).Add(-time.Second) + // result.Ltime = <ime + return tx.Model(&FsAddress{}).Create(result).Error }) if err != nil { @@ -50,14 +69,48 @@ func (a *FsAddressModel) CreateOne(ctx context.Context, address *FsAddress) (res } func (a *FsAddressModel) UpdateAddAddress(ctx context.Context, address *FsAddress) (err error) { - err = a.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { - if *address.IsDefault > 0 { - err = tx.Model(&FsAddress{}).Where("user_id = ? and is_default = 1 ", address.UserId).Update("is_default", 0).Error - if err != nil { - return err - } + err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error { + err = tx. + Where("user_id = ? and address_id = ? and status = 1 ", address.UserId, address.AddressId). + Updates(address).Error + if err != nil { + return err } - return tx.Model(&FsAddress{}).Where("id = ? and user_id = ?", address.AddressId, address.UserId).Omit("id", "user_id").Updates(address).Error + return err }) return err } + +func (a *FsAddressModel) SettingUserDefaultAddress(ctx context.Context, userId int64, addressId int64) (err error) { + + err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error { + + now := time.Now().UTC() + + err = tx.Model(&FsAddress{}).Where(" `user_id` = ? and `status` = ? and `address_id = ?` ", userId, 1, addressId). + UpdateColumn("ltime", now.Add(time.Hour*24*365*100)). + UpdateColumn("utime", now).Error + if err != nil { + return err + } + + err = tx.Where(" `user_id` = ? and `status` = ? and `address_id != ? and `ltime` > ?` ", userId, 1, addressId, now.Add(time.Hour*24*365)). + UpdateColumn("ltime", now).Error + if err != nil { + logx.Error(err) + } + + return nil + }) + + return +} + +func (a *FsAddressModel) DeleteOne(ctx context.Context, addressId int64, userId int64) (err error) { + address := &FsAddress{ + AddressId: addressId, + UserId: &userId, + } + err = a.db.WithContext(ctx).Model(&FsAddress{}).Where("`address_id` = ? and `user_id` = ? and `status` = ? ", addressId, userId, 1).Delete(address).Error + return err +} diff --git a/model/gmodel/fs_product_model3d_logic.go b/model/gmodel/fs_product_model3d_logic.go index f7a7f3b3..9b01334a 100755 --- a/model/gmodel/fs_product_model3d_logic.go +++ b/model/gmodel/fs_product_model3d_logic.go @@ -12,8 +12,7 @@ type StepPriceJsonStruct struct { EndQuantity int64 `json:"end_quantity"` StartQuantity int64 `json:"start_quantity"` } `json:"price_range"` - MinBuyUnitsNum int64 `json:"min_buy_units_num"` - StepBuyUnitsNum int64 `json:"step_buy_units_num"` + MinBuyUnitsNum int64 `json:"min_buy_units_num"` } func (d *FsProductModel3dModel) FindOne(ctx context.Context, id int64, fields ...string) (resp *FsProductModel3d, err error) { diff --git a/server/info/internal/handler/addressaddhandler.go b/server/info/internal/handler/addressaddhandler.go index 0e02dc4b..e13163fb 100644 --- a/server/info/internal/handler/addressaddhandler.go +++ b/server/info/internal/handler/addressaddhandler.go @@ -14,7 +14,7 @@ import ( func AddressAddHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var req types.AddressNameRequest + var req types.AddressRequest userinfo, err := basic.RequestParse(w, r, svcCtx, &req) if err != nil { return diff --git a/server/info/internal/handler/addresslisthandler.go b/server/info/internal/handler/addresslisthandler.go new file mode 100644 index 00000000..c496bee7 --- /dev/null +++ b/server/info/internal/handler/addresslisthandler.go @@ -0,0 +1,35 @@ +package handler + +import ( + "net/http" + "reflect" + + "fusenapi/utils/basic" + + "fusenapi/server/info/internal/logic" + "fusenapi/server/info/internal/svc" + "fusenapi/server/info/internal/types" +) + +func AddressListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var req types.Request + userinfo, err := basic.RequestParse(w, r, svcCtx, &req) + if err != nil { + return + } + + // 创建一个业务逻辑层实例 + l := logic.NewAddressListLogic(r.Context(), svcCtx) + + rl := reflect.ValueOf(l) + basic.BeforeLogic(w, r, rl) + + resp := l.AddressList(&req, userinfo) + + if !basic.AfterLogic(w, r, rl, resp) { + basic.NormalAfterLogic(w, r, resp) + } + } +} diff --git a/server/info/internal/handler/addressupdatehandler.go b/server/info/internal/handler/addressupdatehandler.go index 9f12456c..8bf03f24 100644 --- a/server/info/internal/handler/addressupdatehandler.go +++ b/server/info/internal/handler/addressupdatehandler.go @@ -14,7 +14,7 @@ import ( func AddressUpdateHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var req types.AddressObjectRequest + var req types.AddressRequest userinfo, err := basic.RequestParse(w, r, svcCtx, &req) if err != nil { return diff --git a/server/info/internal/handler/routes.go b/server/info/internal/handler/routes.go index c259faea..82d01e1c 100644 --- a/server/info/internal/handler/routes.go +++ b/server/info/internal/handler/routes.go @@ -2,6 +2,7 @@ package handler import ( + "net/http" "fusenapi/server/info/internal/svc" @@ -10,6 +11,7 @@ import ( ) func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { + server.AddRoutes( []rest.Route{ { @@ -37,6 +39,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/api/info/address/delete", Handler: AddressDeleteHandler(serverCtx), }, + { + Method: http.MethodGet, + Path: "/api/info/address/list", + Handler: AddressListHandler(serverCtx), + }, }, ) } diff --git a/server/info/internal/logic/addressaddlogic.go b/server/info/internal/logic/addressaddlogic.go index 9527b89c..61599266 100644 --- a/server/info/internal/logic/addressaddlogic.go +++ b/server/info/internal/logic/addressaddlogic.go @@ -1,6 +1,7 @@ package logic import ( + "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" @@ -30,11 +31,60 @@ func NewAddressAddLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Addres // func (l *AddressAddLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { // } -func (l *AddressAddLogic) AddressAdd(req *types.AddressNameRequest, userinfo *auth.UserInfo) (resp *basic.Response) { +func (l *AddressAddLogic) AddressAdd(req *types.AddressRequest, userinfo *auth.UserInfo) (resp *basic.Response) { // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null - return resp.SetStatus(basic.CodeOK) + if !userinfo.IsUser() { + return resp.SetStatus(basic.CodeUnAuth) + } + + // 确认这个IsDefault的值范围 + if !auth.CheckValueRange(req.IsDefault, 0, 1) { + return resp.SetStatus(basic.CodeSafeValueRangeErr) // IsDefault值超出范围, 返回安全值范围错误 + } + + m := l.svcCtx.AllModels.FsAddress // 创建地址模型 + + // 如果ID为0, 表示新增地址 + + var ( + country string = "USA" // 国家默认为美国 + isDefautl int64 = 1 // 默认地址为1 + status int64 = 1 // 默认地址状态为1(正常) + ) + + createOne := &gmodel.FsAddress{ // 构建FsAddress结构体 + AddressName: &req.AddressName, + FirstName: &req.FirstName, + LastName: &req.LastName, + Mobile: &req.Mobile, + Street: &req.Street, + Suite: &req.Suite, + City: &req.City, + State: &req.State, + Country: &country, + Status: &status, + UserId: &userinfo.UserId, + ZipCode: &req.ZipCode, + IsDefault: &isDefautl, + } + _, err := m.CreateOne(l.ctx, createOne) // 新增地址 + if err != nil { + logx.Error(err) // 日志记录错误 + return resp.SetStatus(basic.CodeDbCreateErr) // 返回数据库创建错误 + } + + addresses, err := m.GetUserAllAddress(l.ctx, userinfo.UserId) + if err != nil { + logx.Error(err) + return resp.SetStatus(basic.CodeDbSqlErr) // 返回数据库创建错误 + } + + return resp.SetStatus(basic.CodeOK, map[string]any{ + "address_list": addresses, + }) // 返回成功并返回地址ID + } // 处理逻辑后 w,r 如:重定向, resp 必须重新处理 diff --git a/server/info/internal/logic/addressdefaultlogic.go b/server/info/internal/logic/addressdefaultlogic.go index c7ad7067..440dde95 100644 --- a/server/info/internal/logic/addressdefaultlogic.go +++ b/server/info/internal/logic/addressdefaultlogic.go @@ -34,6 +34,15 @@ func (l *AddressDefaultLogic) AddressDefault(req *types.AddressIdRequest, userin // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null + if !userinfo.IsUser() { + return resp.SetStatus(basic.CodeUnAuth) + } + + err := l.svcCtx.AllModels.FsAddress.SettingUserDefaultAddress(l.ctx, userinfo.UserId, req.AddressId) + if err != nil { + return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error()) + } + return resp.SetStatus(basic.CodeOK) } diff --git a/server/info/internal/logic/addressdeletelogic.go b/server/info/internal/logic/addressdeletelogic.go index 59f37f85..b2a398ff 100644 --- a/server/info/internal/logic/addressdeletelogic.go +++ b/server/info/internal/logic/addressdeletelogic.go @@ -34,6 +34,15 @@ func (l *AddressDeleteLogic) AddressDelete(req *types.AddressIdRequest, userinfo // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null + if !userinfo.IsUser() { + return resp.SetStatus(basic.CodeUnAuth) + } + + err := l.svcCtx.AllModels.FsAddress.DeleteOne(l.ctx, req.AddressId, userinfo.UserId) + if err != nil { + return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error()) + } + return resp.SetStatus(basic.CodeOK) } diff --git a/server/info/internal/logic/addresslistlogic.go b/server/info/internal/logic/addresslistlogic.go new file mode 100644 index 00000000..31891b26 --- /dev/null +++ b/server/info/internal/logic/addresslistlogic.go @@ -0,0 +1,56 @@ +package logic + +import ( + "fusenapi/utils/auth" + "fusenapi/utils/basic" + + "context" + + "fusenapi/server/info/internal/svc" + "fusenapi/server/info/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type AddressListLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewAddressListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddressListLogic { + return &AddressListLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +// 处理进入前逻辑w,r +// func (l *AddressListLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { +// } + +func (l *AddressListLogic) AddressList(req *types.Request, userinfo *auth.UserInfo) (resp *basic.Response) { + // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) + // userinfo 传入值时, 一定不为null + + if !userinfo.IsUser() { + return resp.SetStatus(basic.CodeUnAuth) + } + + m := l.svcCtx.AllModels.FsAddress // 创建地址模型 + result, err := m.GetUserAllAddress(l.ctx, userinfo.UserId) + if err != nil { + logx.Error(err) // 日志记录错误 + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, err.Error()) // 返回数据库创建错误 + } + + return resp.SetStatus(basic.CodeOK, map[string]any{ + "address_list": result, + }) +} + +// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 +// func (l *AddressListLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { +// // httpx.OkJsonCtx(r.Context(), w, resp) +// } diff --git a/server/info/internal/logic/addressupdatelogic.go b/server/info/internal/logic/addressupdatelogic.go index 8cdac113..cf0a1580 100644 --- a/server/info/internal/logic/addressupdatelogic.go +++ b/server/info/internal/logic/addressupdatelogic.go @@ -1,8 +1,10 @@ package logic import ( + "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" + "time" "context" @@ -30,10 +32,38 @@ func NewAddressUpdateLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Add // func (l *AddressUpdateLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { // } -func (l *AddressUpdateLogic) AddressUpdate(req *types.AddressObjectRequest, userinfo *auth.UserInfo) (resp *basic.Response) { +func (l *AddressUpdateLogic) AddressUpdate(req *types.AddressRequest, userinfo *auth.UserInfo) (resp *basic.Response) { // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null + if !userinfo.IsUser() { + return resp.SetStatus(basic.CodeUnAuth) + } + + now := time.Now().UTC() + + address := gmodel.FsAddress{ + AddressId: req.AddressId, + UserId: &userinfo.UserId, + IsDefault: &req.IsDefault, + AddressName: &req.AddressName, + FirstName: &req.FirstName, + LastName: &req.LastName, + Mobile: &req.Mobile, + ZipCode: &req.ZipCode, + Street: &req.Street, + Suite: &req.Suite, + City: &req.City, + State: &req.State, + Utime: &now, + Ltime: &now, + } + + err := l.svcCtx.AllModels.FsAddress.UpdateAddAddress(l.ctx, &address) + if err != nil { + return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error()) + } + return resp.SetStatus(basic.CodeOK) } diff --git a/server/info/internal/types/types.go b/server/info/internal/types/types.go index 3b42e0a9..c3ca47c3 100644 --- a/server/info/internal/types/types.go +++ b/server/info/internal/types/types.go @@ -10,8 +10,8 @@ type UserInfoRequest struct { } type AddressObjectRequest struct { - AddressId int64 `json:"address_id"` // 地址id - Address string `json:"address"` // 地址 + AddressId int64 `json:"address_id"` // 地址id + AddressName string `json:"address_name"` // 地址 } type AddressIdRequest struct { @@ -19,7 +19,21 @@ type AddressIdRequest struct { } type AddressNameRequest struct { - Address string `json:"address"` // 地址 + AddressName string `json:"address_name"` // 地址 +} + +type AddressRequest struct { + AddressId int64 `json:"address_id,omitempty"` + IsDefault int64 `json:"is_default"` //是否默认 + AddressName string `json:"address_name"` //收货人 + FirstName string `json:"first_name"` //first_name + LastName string `json:"last_name"` //last_name + Mobile string `json:"mobile"` //手机 + ZipCode string `json:"zip_code"` //邮编 + Street string `json:"street"` //街道 + Suite string `json:"suite"` //房号 + City string `json:"city"` //城市 + State string `json:"state"` //州 } type Request struct { diff --git a/server/product/internal/handler/getproductsteppricehandler.go b/server/product/internal/handler/getproductsteppricehandler.go new file mode 100644 index 00000000..62b59e23 --- /dev/null +++ b/server/product/internal/handler/getproductsteppricehandler.go @@ -0,0 +1,35 @@ +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 GetProductStepPriceHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var req types.GetProductStepPriceReq + userinfo, err := basic.RequestParse(w, r, svcCtx, &req) + if err != nil { + return + } + + // 创建一个业务逻辑层实例 + l := logic.NewGetProductStepPriceLogic(r.Context(), svcCtx) + + rl := reflect.ValueOf(l) + basic.BeforeLogic(w, r, rl) + + resp := l.GetProductStepPrice(&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 0a73ed56..260422e3 100644 --- a/server/product/internal/handler/routes.go +++ b/server/product/internal/handler/routes.go @@ -72,6 +72,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/api/product/get_price_by_pid", Handler: GetPriceByPidHandler(serverCtx), }, + { + Method: http.MethodGet, + Path: "/api/product/get_product_step_price", + Handler: GetProductStepPriceHandler(serverCtx), + }, { Method: http.MethodGet, Path: "/api/product/get_size_by_pid", diff --git a/server/product/internal/logic/getpricebypidlogic.go b/server/product/internal/logic/getpricebypidlogic.go index 546533c5..025a9c33 100644 --- a/server/product/internal/logic/getpricebypidlogic.go +++ b/server/product/internal/logic/getpricebypidlogic.go @@ -34,6 +34,7 @@ func NewGetPriceByPidLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Get svcCtx: svcCtx, } } + func (l *GetPriceByPidLogic) GetPriceByPid(req *types.GetPriceByPidReq, userinfo *auth.UserInfo) (resp *basic.Response) { req.Pid = strings.Trim(req.Pid, " ") if req.Pid == "" { diff --git a/server/product/internal/logic/getproductsteppricelogic.go b/server/product/internal/logic/getproductsteppricelogic.go new file mode 100644 index 00000000..e30b39bd --- /dev/null +++ b/server/product/internal/logic/getproductsteppricelogic.go @@ -0,0 +1,130 @@ +package logic + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "fusenapi/constants" + "fusenapi/model/gmodel" + "fusenapi/utils/auth" + "fusenapi/utils/basic" + "fusenapi/utils/format" + "gorm.io/gorm" + + "fusenapi/server/product/internal/svc" + "fusenapi/server/product/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetProductStepPriceLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewGetProductStepPriceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetProductStepPriceLogic { + return &GetProductStepPriceLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +// 处理进入前逻辑w,r +// func (l *GetProductStepPriceLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { +// } + +func (l *GetProductStepPriceLogic) GetProductStepPrice(req *types.GetProductStepPriceReq, userinfo *auth.UserInfo) (resp *basic.Response) { + if req.ProductId <= 0 { + return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "err param:product id") + } + //获取产品信息(只是获取id) + _, err := l.svcCtx.AllModels.FsProduct.FindOne(l.ctx, req.ProductId, "id") + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "the product is not exists") + } + logx.Error(err) + 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") + 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) + } + } + //查询配件价格列表 + fittingPriceList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllByIdsTag(l.ctx, fittingIds, constants.TAG_PARTS, "id,price,packed_unit") + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get fitting price list") + } + mapFitting := make(map[int64]gmodel.FsProductModel3d) + for _, v := range fittingPriceList { + mapFitting[v.Id] = v + } + //遍历处理模型价格 + mapRsp := make(map[string]interface{}) + for _, modelPriceInfo := range modelPriceList { + var stepPrice gmodel.StepPriceJsonStruct + if err = json.Unmarshal(*modelPriceInfo.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)) + } + //最小单价 + minPrice := stepPrice.PriceRange[rangeLen-1].Price + //最大单价 + maxPrice := stepPrice.PriceRange[0].Price + //购买数步进基数 + stepPurchaseQuantity := *modelPriceInfo.PackedUnit + //购买数步进基数描述 + stepPurchaseQuantityDescription := "主体装箱数为步进基数" + 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)) + } + //最小价格要加配件 + minPrice += *fittingPriceInfo.Price + //如果配件装箱基数比主体大,则基数以配件为主 + if *fittingPriceInfo.PackedUnit > stepPurchaseQuantity { + stepPurchaseQuantity = *fittingPriceInfo.PackedUnit + stepPurchaseQuantityDescription = "配件装箱数为步进基数" + } + } + stepRange := make([]interface{}, 0, rangeLen) + for _, rangeInfo := range stepPrice.PriceRange { + stepRange = append(stepRange, map[string]interface{}{ + "start_quantity": rangeInfo.StartQuantity, + "end_quantity": rangeInfo.EndQuantity, + "item_price": format.CentitoDollar(rangeInfo.Price, 3), + }) + } + 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, + } + } + return resp.SetStatusWithMessage(basic.CodeOK, "success", mapRsp) +} + +// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 +// func (l *GetProductStepPriceLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { +// // httpx.OkJsonCtx(r.Context(), w, resp) +// } diff --git a/server/product/internal/types/types.go b/server/product/internal/types/types.go index f5d96bd6..b9b96864 100644 --- a/server/product/internal/types/types.go +++ b/server/product/internal/types/types.go @@ -331,6 +331,10 @@ type PriceItem struct { Price int64 `json:"price"` } +type GetProductStepPriceReq struct { + ProductId int64 `form:"product_id"` +} + type GetSizeByPidReq struct { Pid string `form:"pid"` TemplateTag string `form:"template_tag"` diff --git a/server_api/info.api b/server_api/info.api index ce28f486..dfadc0b2 100644 --- a/server_api/info.api +++ b/server_api/info.api @@ -24,6 +24,9 @@ service info { @handler AddressDeleteHandler post /api/info/address/delete(AddressIdRequest) returns (response); + + @handler AddressListHandler + get /api/info/address/list(request) returns (response); } type ( @@ -32,8 +35,8 @@ type ( } AddressObjectRequest { - AddressId int64 `json:"address_id"` // 地址id - AddressName string `json:"address_name"` // 地址 + AddressId int64 `json:"address_id"` // 地址id + AddressName string `json:"address_name"` // 地址 } AddressIdRequest { @@ -43,4 +46,18 @@ type ( AddressNameRequest { AddressName string `json:"address_name"` // 地址 } + + AddressRequest { + AddressId int64 `json:"address_id,omitempty"` + IsDefault int64 `json:"is_default"` //是否默认 + AddressName string `json:"address_name"` //收货人 + FirstName string `json:"first_name"` //first_name + LastName string `json:"last_name"` //last_name + Mobile string `json:"mobile"` //手机 + ZipCode string `json:"zip_code"` //邮编 + Street string `json:"street"` //街道 + Suite string `json:"suite"` //房号 + City string `json:"city"` //城市 + State string `json:"state"` //州 + } ) \ No newline at end of file diff --git a/server_api/product.api b/server_api/product.api index 95346d07..94715b66 100644 --- a/server_api/product.api +++ b/server_api/product.api @@ -47,6 +47,9 @@ service product { //获取产品阶梯价格列表 @handler GetPriceByPidHandler get /api/product/get_price_by_pid(GetPriceByPidReq) returns (response); + //获取产品阶梯价格信息 + @handler GetProductStepPriceHandler + get /api/product/get_product_step_price(GetProductStepPriceReq) returns (response); //获取产品尺寸列表 @handler GetSizeByPidHandler get /api/product/get_size_by_pid(GetSizeByPidReq) returns (response); @@ -376,6 +379,10 @@ type PriceItem { TotalNum int64 `json:"total_num"` Price int64 `json:"price"` } +//获取产品阶梯价格信息 +type GetProductStepPriceReq { + ProductId int64 `form:"product_id"` +} //获取产品尺寸列表 type GetSizeByPidReq { Pid string `form:"pid"`