From 175583ca516415e929826a45df4a42003b24f44a Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Fri, 16 Jun 2023 18:24:31 +0800 Subject: [PATCH] fix --- constants/delivery.go | 7 + constants/order.go | 69 +++++++ model/gmodel/fs_pay_gen.go | 31 +-- model/gmodel/fs_pay_logic.go | 7 + .../internal/logic/getorderdetaillogic.go | 189 +++++++++++++++++- server/orders/internal/types/types.go | 59 +++++- server_api/orders.api | 54 ++++- utils/order/order_status.go | 30 +++ 8 files changed, 427 insertions(+), 19 deletions(-) create mode 100644 constants/delivery.go create mode 100644 constants/order.go create mode 100644 utils/order/order_status.go diff --git a/constants/delivery.go b/constants/delivery.go new file mode 100644 index 00000000..5b442bcc --- /dev/null +++ b/constants/delivery.go @@ -0,0 +1,7 @@ +package constants + +// 发货到地址方式 +const DELIVERY_METHOD_ADDRESS = 1 + +// 发货到云仓方式 +const DELIVERY_METHOD_CLOUD = 2 diff --git a/constants/order.go b/constants/order.go new file mode 100644 index 00000000..896c98ff --- /dev/null +++ b/constants/order.go @@ -0,0 +1,69 @@ +package constants + +// 新版订单状态-后台所有 +// 未支付 +const STATUS_NEW_NOT_PAY = 0 + +// 首款已付,尾款待付 +const STATUS_NEW_PART_PAY = 1 + +// 全款已付 +const STATUS_NEW_PAY_COMPLETED = 2 + +// 订单已确认 +const STATUS_NEW_SURE = 3 + +// 订单生产中 +const STATUS_NEW_PRODUTING = 4 + +// 订单生产完成 +const STATUS_NEW_PRODUT_COMPLETED = 5 + +// 订单已到库 +const STATUS_NEW_ARRIVAL = 6 + +// 已发货 +const STATUS_NEW_DELIVER = 7 + +// UPS提货 +const STATUS_NEW_UPS = 8 + +// 已完成 +const STATUS_NEW_COMPLETED = 9 + +// 取消订单 +const STATUS_NEW_CANCEL = 10 + +// 退款中 +const STATUS_NEW_REFUNDING = 11 + +// 退款完成 +const STATUS_NEW_REFUNDED = 12 + +// 订单删除 +const STATUS_NEW_DELETE = 13 + +// 订单关闭 +const STATUS_NEW_CLOSE = 14 + +// 前台订单 +// 已支付 +const STATUS_FONT_PAID = 1 + +// 生产中 +const STATUS_FONT_PRODUCTION = 2 + +// 运输中 +const STATUS_FONT_SHIPPED = 3 + +// 到达云仓 +const STATUS_FONT_INVENTORY = 4 + +// 订单完成 +const STATUS_FONT_COMPLETED = 5 + +// 订单关闭 +const STATUS_FONT_CLOSED = 7 + +// 云仓完成 +const STATUS_FONT_COMPLETED_CLOUD = 8 diff --git a/model/gmodel/fs_pay_gen.go b/model/gmodel/fs_pay_gen.go index 2260bd6f..5b02ea6d 100644 --- a/model/gmodel/fs_pay_gen.go +++ b/model/gmodel/fs_pay_gen.go @@ -5,22 +5,23 @@ import ( ) type FsPay struct { - Id int64 `gorm:"primary_key" json:"id"` // - UserId *int64 `gorm:"-" json:"user_id"` // 用户id - OrderNumber *string `gorm:"-" json:"order_number"` // 订单编号 - TradeNo *string `gorm:"-" json:"trade_no"` // 第三方支付编号 - PayAmount *int64 `gorm:"-" json:"pay_amount"` // 支付金额 (分) - PayStatus *int64 `gorm:"-" json:"pay_status"` // 支付状态 0 不成功 1 成功 - IsRefund *int64 `gorm:"-" json:"is_refund"` // 是否退款 0 未退款 1退款 - PaymentMethod *int64 `gorm:"-" json:"payment_method"` // 支付方式 1 stripe 2 paypal - PayStage *int64 `gorm:"-" json:"pay_stage"` // 支付阶段 1首付 2尾款 - OrderSource *int64 `gorm:"-" json:"order_source"` // 订单来源 1pc - PayTime *int64 `gorm:"-" json:"pay_time"` // 支付时间 - CreatedAt *int64 `gorm:"-" json:"created_at"` // 创建时间 - UpdatedAt *int64 `gorm:"-" json:"updated_at"` // 更新时间 - CardNo *string `gorm:"-" json:"card_no"` // 卡后4位 - Brand *string `gorm:"-" json:"brand"` // 银行品牌 + Id int64 `gorm:"primary_key;" json:"id"` + UserId *int64 `gorm:"default:0" json:"user_id"` // 用户id + OrderNumber *string `gorm:"default:''" json:"order_number"` // 订单编号 + TradeNo *string `gorm:"default:''" json:"trade_no"` // 第三方支付编号 + PayAmount *int64 `gorm:"default:0" json:"pay_amount"` // 支付金额 (分) + PayStatus *int64 `gorm:"default:0" json:"pay_status"` // 支付状态 0 不成功 1 成功 + IsRefund *int64 `gorm:"default:0" json:"is_refund"` // 是否退款 0 未退款 1退款 + PaymentMethod *int64 `gorm:"default:0" json:"payment_method"` // 支付方式 1 stripe 2 paypal + PayStage *int64 `gorm:"default:0" json:"pay_stage"` // 支付阶段 1首付 2尾款 + OrderSource *int64 `gorm:"default:1" json:"order_source"` // 订单来源 1pc + PayTime *int64 `gorm:"" json:"pay_time"` // 支付时间 + CreatedAt *int64 `gorm:"default:0" json:"created_at"` // 创建时间 + UpdatedAt *int64 `gorm:"default:0" json:"updated_at"` // 更新时间 + CardNo *string `gorm:"default:''" json:"card_no"` // 卡后4位 + Brand *string `gorm:"default:''" json:"brand"` // 银行品牌 } + type FsPayModel struct{ db *gorm.DB } func NewFsPayModel(db *gorm.DB) *FsPayModel { return &FsPayModel{db} } diff --git a/model/gmodel/fs_pay_logic.go b/model/gmodel/fs_pay_logic.go index afb6f9ef..30cdfa2b 100644 --- a/model/gmodel/fs_pay_logic.go +++ b/model/gmodel/fs_pay_logic.go @@ -9,3 +9,10 @@ func (p *FsPayModel) GetListByOrderNumber(ctx context.Context, sn string) (resp } return resp, nil } +func (p *FsPayModel) GetOrderPayList(ctx context.Context, sn string, payStatus int64, isRefund int64) (resp []FsPay, err error) { + err = p.db.WithContext(ctx).Model(&FsPay{}).Where("`order_number` = ? and `pay_status` = ? and `is_refund` = ?", sn, payStatus, isRefund).Find(&resp).Error + if err != nil { + return nil, err + } + return resp, nil +} diff --git a/server/orders/internal/logic/getorderdetaillogic.go b/server/orders/internal/logic/getorderdetaillogic.go index 09223955..e0bdda4c 100644 --- a/server/orders/internal/logic/getorderdetaillogic.go +++ b/server/orders/internal/logic/getorderdetaillogic.go @@ -1,8 +1,14 @@ package logic import ( + "fmt" + "fusenapi/constants" + "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" + "fusenapi/utils/order" + "strings" + "time" "context" @@ -28,6 +34,185 @@ func NewGetOrderDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Ge func (l *GetOrderDetailLogic) GetOrderDetail(req *types.GetOrderDetailReq, userinfo *auth.UserInfo) (resp *basic.Response) { //查询订单信息 - //orderModel := gmodel.NewFsOrderModel(l.svcCtx.MysqlConn) - return resp.SetStatus(basic.CodeOK) + orderModel := gmodel.NewFsOrderModel(l.svcCtx.MysqlConn) + orderInfo, err := orderModel.FindOneBySn(l.ctx, userinfo.UserId, req.Sn) + if err != nil { + logx.Error(err) + return resp.SetStatus(basic.CodeServiceErr, "failed to get order info") + } + if orderInfo.Id == 0 { + return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "the order is not exists") + } + address := types.Address{} + //直接邮寄才有地址信息 + if *orderInfo.DeliveryMethod == constants.DELIVERY_METHOD_ADDRESS { + addressInfo, err := gmodel.NewFsAddressModel(l.svcCtx.MysqlConn).GetOne(l.ctx, *orderInfo.AddressId, userinfo.UserId) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get address info") + } + if addressInfo.Id == 0 { + return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "address not exists") + } + address.Id = addressInfo.Id + address.UserId = *addressInfo.UserId + address.Name = *addressInfo.Name + address.FirstName = *addressInfo.FirstName + address.LastName = *addressInfo.LastName + address.Mobile = *addressInfo.Mobile + address.Street = *addressInfo.Street + address.Suite = *addressInfo.Suite + address.City = *addressInfo.City + address.State = *addressInfo.State + address.Country = *addressInfo.Country + address.ZipCode = *addressInfo.ZipCode + address.Status = *addressInfo.Status + address.IsDefault = *addressInfo.IsDefault + } + //获取订单详情 + orderDetailModel := gmodel.NewFsOrderDetailModel(l.svcCtx.MysqlConn) + orderDetails, err := orderDetailModel.GetOrderDetailsByOrderId(l.ctx, orderInfo.Id) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get order details") + } + if len(orderDetails) == 0 { + return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order details is empty") + } + optionalIds := make([]int64, 0, len(orderDetails)) + productIds := make([]int64, 0, len(orderDetails)) + orderDetailTemplateIds := make([]int64, 0, len(orderDetails)) + for _, v := range orderDetails { + optionalIds = append(optionalIds, *v.OptionalId) + productIds = append(productIds, *v.ProductId) + orderDetailTemplateIds = append(orderDetailTemplateIds, *v.OrderDetailTemplateId) + } + //获取配件列表 + productModel3dModel := gmodel.NewFsProductModel3dModel(l.svcCtx.MysqlConn) + productModel3dList, err := productModel3dModel.GetAllByIds(l.ctx, optionalIds) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product 3d models") + } + mapModel3d := make(map[int64]int) + for k, v := range productModel3dList { + mapModel3d[v.Id] = k + } + //获取产品列表 + productModel := gmodel.NewFsProductModel(l.svcCtx.MysqlConn) + productList, err := productModel.GetProductListByIds(l.ctx, productIds, "") + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get order product list") + } + mapProduct := make(map[int64]int) + for k, v := range productList { + mapProduct[v.Id] = k + } + //获取模板列表 + orderDetailTemplateModel := gmodel.NewFsOrderDetailTemplateModel(l.svcCtx.MysqlConn) + detailTemplateList, err := orderDetailTemplateModel.GetListByIds(l.ctx, orderDetailTemplateIds) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get order detail template list") + } + sizeIds := make([]int64, 0, len(detailTemplateList)) + mapDetailTemplate := make(map[int64]int) + for k, v := range detailTemplateList { + sizeIds = append(sizeIds, *v.SizeId) + mapDetailTemplate[v.Id] = k + } + //获取尺寸信息 + productSizeModel := gmodel.NewFsProductSizeModel(l.svcCtx.MysqlConn) + productSizeList, err := productSizeModel.GetAllByIds(l.ctx, sizeIds, "") + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product size list") + } + mapProductSize := make(map[int64]int) + for k, v := range productSizeList { + mapProductSize[v.Id] = k + } + //获取支付信息 + payModel := gmodel.NewFsPayModel(l.svcCtx.MysqlConn) + payList, err := payModel.GetOrderPayList(l.ctx, *orderInfo.Sn, 1, 0) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get pay records") + } + mapPay := make(map[int64]int) //pay_stat作为索引 + for k, v := range payList { + mapPay[*v.PayStage] = k + } + //处理订单状态 + orderStatus := order.GetOrderStatus(*orderInfo.Status, *orderInfo.DeliveryMethod) + //组装 + productListRsp := make([]types.Product, 0, len(orderDetails)) + for _, v := range orderDetails { + cover := *v.Cover + if req.Size >= 200 { + coverSlice := strings.Split(".", *v.Cover) + if len(coverSlice) >= 2 { + cover = fmt.Sprintf("%s_%d.%s", coverSlice[0], req.Size, coverSlice[1]) + } + } + Fitting := "" + if model3dIndex, ok := mapModel3d[*v.OptionalId]; ok { + Fitting = *productModel3dList[model3dIndex].Title + } + pcBox := int64(0) + Size := "" + if detailTemplateIndex, ok := mapDetailTemplate[*v.OrderDetailTemplateId]; ok { + pcBox = *v.BuyNum / *detailTemplateList[detailTemplateIndex].EachBoxNum + if sizeIndex, ok := mapProductSize[*detailTemplateList[detailTemplateIndex].SizeId]; ok { + Size = *productSizeList[sizeIndex].Capacity + } + } + Title := "" + if productIndex, ok := mapProduct[*v.ProductId]; ok { + Title = *productList[productIndex].Title + } + productListRsp = append(productListRsp, types.Product{ + Cover: cover, + Fitting: Fitting, + OptionPrice: *v.OptionPrice, + OrderDetailTemplateId: *v.OrderDetailTemplateId, + OrderId: *v.OrderId, + Pcs: *v.BuyNum, + PcsBox: pcBox, + Price: *v.Amount, + ProductId: *v.ProductId, + Size: Size, + Title: Title, + }) + } + data := types.GetOrderDetailRsp{ + Id: orderInfo.Id, + TotalAmount: *orderInfo.TotalAmount, + Deposit: *orderInfo.TotalAmount / 2, + Remaining: *orderInfo.TotalAmount - *orderInfo.TotalAmount/2, + IsPayCompleted: *orderInfo.IsPayCompleted, + DeliveryMethod: *orderInfo.DeliveryMethod, + Sn: *orderInfo.Sn, + Status: orderStatus, + Ctime: time.Unix(*orderInfo.Ctime, 0).Format("2006-01-02 15:04:05"), + PayInfo: types.PayInfo{}, + Address: address, + ProductList: productListRsp, + } + //首款 + if payIndex, ok := mapPay[1]; ok { + data.PayInfo.Deposit = types.Deposit{ + Method: *payList[payIndex].Brand, + TransNo: *payList[payIndex].TradeNo, + } + } + //尾款 + if payIndex, ok := mapPay[2]; ok { + data.PayInfo.Final = types.Deposit{ + Method: *payList[payIndex].Brand, + TransNo: *payList[payIndex].TradeNo, + } + } + return resp.SetStatusWithMessage(basic.CodeOK, "success", data) } diff --git a/server/orders/internal/types/types.go b/server/orders/internal/types/types.go index 1488de87..32f24095 100644 --- a/server/orders/internal/types/types.go +++ b/server/orders/internal/types/types.go @@ -16,7 +16,64 @@ type GetOrderInvoiceRsp struct { } type GetOrderDetailReq struct { - Sn string `form:"sn"` + Sn string `form:"sn"` + Size int64 `form:"size, optional"` +} + +type GetOrderDetailRsp struct { + Id int64 `json:"id"` + TotalAmount int64 `json:"total_amount"` + Deposit int64 `json:"deposit"` + Remaining int64 `json:"remaining"` + IsPayCompleted int64 `json:"is_pay_completed"` + DeliveryMethod int64 `json:"delivery_method"` + Sn string `json:"sn"` + Status int64 `json:"status"` + Ctime string `json:"ctime"` + PayInfo PayInfo `json:"pay_info"` + Address Address `json:"address"` + ProductList []Product `json:"productList"` +} + +type Product struct { + Cover string `json:"cover"` + Fitting string `json:"fitting"` + OptionPrice int64 `json:"option_price"` + OrderDetailTemplateId int64 `json:"order_detail_template_id"` + OrderId int64 `json:"order_id"` + Pcs int64 `json:"pcs"` + PcsBox int64 `json:"pcs_box"` + Price int64 `json:"price"` + ProductId int64 `json:"product_id"` + Size string `json:"size"` + Title string `json:"title"` +} + +type Address struct { + Id int64 `json:"id"` + UserId int64 `json:"user_id"` + Name string `json:"name"` + FirstName string `json:"first_name"` + LastName string `json:"last_name"` + Mobile string `json:"mobile"` + Street string `json:"street"` + Suite string `json:"suite"` + City string `json:"city"` + State string `json:"state"` + Country string `json:"country"` + ZipCode string `json:"zip_code"` + Status int64 `json:"status"` + IsDefault int64 `json:"is_default"` +} + +type PayInfo struct { + Deposit Deposit `json:"Deposit"` + Final Deposit `json:"Final"` +} + +type Deposit struct { + Method string `json:"method"` + TransNo string `json:"trans_no"` } type Response struct { diff --git a/server_api/orders.api b/server_api/orders.api index 1961a174..b447744a 100644 --- a/server_api/orders.api +++ b/server_api/orders.api @@ -27,5 +27,57 @@ type GetOrderInvoiceRsp { } //获取订单详情 type GetOrderDetailReq { - Sn string `form:"sn"` + Sn string `form:"sn"` + Size int64 `form:"size, optional"` +} +type GetOrderDetailRsp { + Id int64 `json:"id"` + TotalAmount int64 `json:"total_amount"` + Deposit int64 `json:"deposit"` + Remaining int64 `json:"remaining"` + IsPayCompleted int64 `json:"is_pay_completed"` + DeliveryMethod int64 `json:"delivery_method"` + Sn string `json:"sn"` + Status int64 `json:"status"` + Ctime string `json:"ctime"` + PayInfo PayInfo `json:"pay_info"` + Address Address `json:"address"` + ProductList []Product `json:"productList"` +} +type Product { + Cover string `json:"cover"` + Fitting string `json:"fitting"` + OptionPrice int64 `json:"option_price"` + OrderDetailTemplateId int64 `json:"order_detail_template_id"` + OrderId int64 `json:"order_id"` + Pcs int64 `json:"pcs"` + PcsBox int64 `json:"pcs_box"` + Price int64 `json:"price"` + ProductId int64 `json:"product_id"` + Size string `json:"size"` + Title string `json:"title"` +} +type Address { + Id int64 `json:"id"` + UserId int64 `json:"user_id"` + Name string `json:"name"` + FirstName string `json:"first_name"` + LastName string `json:"last_name"` + Mobile string `json:"mobile"` + Street string `json:"street"` + Suite string `json:"suite"` + City string `json:"city"` + State string `json:"state"` + Country string `json:"country"` + ZipCode string `json:"zip_code"` + Status int64 `json:"status"` + IsDefault int64 `json:"is_default"` +} +type PayInfo { + Deposit Deposit `json:"Deposit"` + Final Deposit `json:"Final"` +} +type Deposit { + Method string `json:"method"` + TransNo string `json:"trans_no"` } \ No newline at end of file diff --git a/utils/order/order_status.go b/utils/order/order_status.go new file mode 100644 index 00000000..f45322e3 --- /dev/null +++ b/utils/order/order_status.go @@ -0,0 +1,30 @@ +package order + +import "fusenapi/constants" + +// 获取订单生产状态 +func GetOrderStatus(orderStatus int64, deliveryMethod int64) int64 { + switch orderStatus { + //已支付 + case constants.STATUS_NEW_PART_PAY, constants.STATUS_NEW_PAY_COMPLETED, constants.STATUS_NEW_SURE: + return constants.STATUS_FONT_PAID + //生产中 + case constants.STATUS_NEW_PRODUTING, constants.STATUS_NEW_PRODUT_COMPLETED: + return constants.STATUS_FONT_PRODUCTION + //运输中-直邮单 + case constants.STATUS_NEW_DELIVER, constants.STATUS_NEW_UPS: + return constants.STATUS_FONT_SHIPPED + //到达-云仓 + case constants.STATUS_NEW_ARRIVAL: + return constants.STATUS_FONT_INVENTORY + //订单完成 + case constants.STATUS_NEW_COMPLETED: + if deliveryMethod == constants.DELIVERY_METHOD_CLOUD { + return constants.STATUS_FONT_COMPLETED_CLOUD + } + return constants.STATUS_FONT_COMPLETED + //订单关闭 + default: + return constants.STATUS_FONT_CLOSED + } +}