package logic import ( "errors" "fmt" "fusenapi/constants" "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" "fusenapi/utils/configs" "fusenapi/utils/image" "strings" "fusenapi/utils/format" "fusenapi/utils/order" "math" "time" "context" "fusenapi/server/home-user-auth/internal/svc" "fusenapi/server/home-user-auth/internal/types" "github.com/zeromicro/go-zero/core/logx" "gorm.io/gorm" ) type UserOrderListLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewUserOrderListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserOrderListLogic { return &UserOrderListLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } func (l *UserOrderListLogic) UserOrderList(req *types.UserOrderListReq, userinfo *auth.UserInfo) (resp *basic.Response) { // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null size := req.Size if size > 0 { size = int64(image.GetCurrentSize(uint32(size))) } orderDetailModel := gmodel.NewFsOrderDetailModel(l.svcCtx.MysqlConn) orderDetailTemplateModel := gmodel.NewFsOrderDetailTemplateModel(l.svcCtx.MysqlConn) fsProductDesignModel := gmodel.NewFsProductDesignModel(l.svcCtx.MysqlConn) orderModel := gmodel.NewFsOrderModel(l.svcCtx.MysqlConn) rowBuilder := orderModel.RowSelectBuilder(nil) if userinfo == nil || userinfo.UserId == 0 { return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order not found") } // 查询条件 var page = req.Page var pageSize = req.PageSize var listRes []*gmodel.FsOrderRel rowBuilder = rowBuilder.Where("user_id =?", userinfo.UserId).Where("status <> ?", constants.STATUS_NEW_NOT_PAY).Where("status <>?", constants.STATUS_NEW_DELETE) // 根据时间来查询不同范围的订单 switch req.Time { case 1: rowBuilder = rowBuilder.Where("ctime >?", time.Now().AddDate(0, -1, 0).Unix()) case 2: rowBuilder = rowBuilder.Where("ctime >?", time.Now().AddDate(0, -3, 0).Unix()) case 3: rowBuilder = rowBuilder.Where("ctime >?", time.Now().AddDate(0, -6, 0).Unix()) case 4: rowBuilder = rowBuilder.Where("ctime >?", time.Now().AddDate(-1, 0, 0).Unix()) default: } //按照订单状态查询不同的订单 if req.Status != -1 { switch req.Status { case 1: rowBuilder = rowBuilder.Where("status in ?", [3]constants.Order{constants.STATUS_NEW_PART_PAY, constants.STATUS_NEW_PAY_COMPLETED, constants.STATUS_NEW_SURE}) case 2: rowBuilder = rowBuilder.Where("status in ?", [2]constants.Order{constants.STATUS_NEW_PRODUTING, constants.STATUS_NEW_PRODUT_COMPLETED}) case 3: rowBuilder = rowBuilder.Where("status in ?", [2]constants.Order{constants.STATUS_NEW_DELIVER, constants.STATUS_NEW_UPS}) case 4: rowBuilder = rowBuilder.Where("status =?", constants.STATUS_NEW_ARRIVAL) case 5: rowBuilder = rowBuilder.Where("status =?", constants.STATUS_NEW_COMPLETED).Where("delivery_method =?", constants.DELIVERY_METHOD_ADDRESS) case 7: rowBuilder = rowBuilder.Where("status in ?", [3]constants.Order{constants.STATUS_NEW_CANCEL, constants.STATUS_NEW_REFUNDED, constants.STATUS_NEW_REFUNDING}) case 8: rowBuilder = rowBuilder.Where("status =?", constants.STATUS_NEW_COMPLETED).Where("delivery_method =?", constants.DELIVERY_METHOD_CLOUD) } } // 查询总数 total, err := orderModel.FindCount(l.ctx, rowBuilder, nil) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order not found") } logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get order info") } // 查询数据 if total > 0 { rowBuilder = rowBuilder.Preload("FsOrderAffiliateInfo").Preload("FsOrderDetails", func(dbPreload *gorm.DB) *gorm.DB { return dbPreload.Table(orderDetailModel.TableName()).Preload("FsOrderDetailTemplateInfo", func(dbPreload *gorm.DB) *gorm.DB { return dbPreload.Table(orderDetailTemplateModel.TableName()).Preload("FsProductDesignInfo", func(dbPreload *gorm.DB) *gorm.DB { return dbPreload.Table(fsProductDesignModel.TableName()).Preload("OptionData").Preload("TemplateData") }).Preload("FsProductSizeInfo") }).Preload("FsProductInfo") }) listRes, err = orderModel.FindPageListByPage(l.ctx, rowBuilder, &page, &pageSize, nil, "") } if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order not found") } logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get order info") } listResLen := len(listRes) var respList []types.Items if listResLen > 0 { // 获取订单时间配置 orderTimeConfig, err := configs.GetOrderTimeConfig(l.ctx, l.svcCtx.MysqlConn) if err != nil { return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get config time info") } // 数据处理 for _, item := range listRes { var pbData types.Items pbData.ID = item.Id pbData.Sn = *item.Sn pbData.UserID = *item.UserId pbData.TotalAmount = *item.TotalAmount pbData.Ctime = format.TimeIntToFormat(*item.Ctime) pbData.Status = *item.Status pbData.DeliveryMethod = *item.DeliveryMethod pbData.TsTime = format.TimeToFormat(*item.TsTime) pbData.IsPayCompleted = *item.IsPayCompleted pbData.DeliverSn = *item.DeliverSn var pcsBox int64 var pcs int64 var productList []types.Product var surplusAt int64 //如果是部分支付状态,那么取消订单倒计时2天 if *item.Status == int64(constants.STATUS_NEW_PART_PAY) { surplusAt = (*item.Ctime + int64(constants.CANCLE_ORDER_EXPIRE)) - time.Now().UTC().Unix() if surplusAt < 0 { surplusAt = 0 } } fsOrderAffiliateInfo := item.FsOrderAffiliateInfo var sureTime int64 var productTime int64 var ProductEndtime int64 var deliverTime int64 var upsDeliverTime int64 var upsTime int64 var arrivalTime int64 var recevieTime int64 if fsOrderAffiliateInfo.Id > 0 { sureTime = *fsOrderAffiliateInfo.SureTime productTime = *fsOrderAffiliateInfo.ProductTime ProductEndtime = *fsOrderAffiliateInfo.ProductEndtime deliverTime = *fsOrderAffiliateInfo.DeliverTime upsDeliverTime = *fsOrderAffiliateInfo.UpsDeliverTime upsTime = *fsOrderAffiliateInfo.UpsTime arrivalTime = *fsOrderAffiliateInfo.ArrivalTime recevieTime = *fsOrderAffiliateInfo.RecevieTime } var getOrderStatusAndLogisticsReq = order.GetOrderStatusAndLogisticsReq{ OrderStatus: constants.Order(*item.Status), DeliveryMethod: constants.DeliveryMethod(*item.DeliveryMethod), IsPayCompleted: *item.IsAllProductCompleted, OrderCtime: *item.Ctime, SureTime: sureTime, ProductTime: productTime, ProductEndtime: ProductEndtime, DeliverTime: deliverTime, UpsDeliverTime: upsDeliverTime, UpsTime: upsTime, ArrivalTime: arrivalTime, RecevieTime: recevieTime, WebSetTimeInfo: orderTimeConfig, } statusAndLogisticsRes := order.GetOrderStatusAndLogistics(getOrderStatusAndLogisticsReq) // 流程控制 var statusTime []types.StatusTime for _, itemTimes := range statusAndLogisticsRes.Times { statusTime = append(statusTime, types.StatusTime{ Key: itemTimes.Key, Time: itemTimes.Time, }) } pbData.StatusTimes = statusTime pbData.LogisticsStatus = int64(statusAndLogisticsRes.LogisticsStatus) pbData.Status = int64(statusAndLogisticsRes.OrderStatus) var isStopMax int64 if len(item.FsOrderDetails) > 0 { for _, fsOrderDetailItem := range item.FsOrderDetails { fsOrderDetailBuyNum := *fsOrderDetailItem.FsOrderDetail.BuyNum fsOrderDetailEachBoxNum := *fsOrderDetailItem.FsOrderDetailTemplateInfo.EachBoxNum pcs = pcs + fsOrderDetailBuyNum pcsBoxNum := fsOrderDetailBuyNum / fsOrderDetailEachBoxNum var csBoxNumF int64 if (fsOrderDetailBuyNum % fsOrderDetailEachBoxNum) > 0 { csBoxNumF = 1 } pcsBox = pcsBox + pcsBoxNum + csBoxNumF productCover := *fsOrderDetailItem.Cover // 尺寸 if size >= 200 { coverArr := strings.Split(*fsOrderDetailItem.Cover, ".") if len(coverArr) < 2 { return resp.SetStatusWithMessage(basic.CodeServiceErr, "cover split slice item count is less than 2") } productCover = fmt.Sprintf("%s_%d.%s", coverArr[0], req.Size, coverArr[1]) } // 判断stop var isStop int64 if fsOrderDetailItem.FsOrderDetailTemplateInfo.FsProductDesignInfo.OptionData.Id != 0 { // 尺寸或者模板下架 if fsOrderDetailItem.FsOrderDetailTemplateInfo.FsProductDesignInfo.Id != 0 { isStop = 1 } else { isStop = 3 } } else { if fsOrderDetailItem.FsOrderDetailTemplateInfo.FsProductDesignInfo.Id != 0 { isStop = 1 } } // 判断产品是否下架 if *fsOrderDetailItem.FsProductInfo.IsShelf == 0 || *fsOrderDetailItem.FsProductInfo.IsDel == 1 { isStop = 2 } if isStop > isStopMax { isStopMax = isStop } productList = append(productList, types.Product{ Cover: productCover, Fitting: *fsOrderDetailItem.OptionalTitle, OptionPrice: *fsOrderDetailItem.OptionPrice, OrderDetailTemplateId: *fsOrderDetailItem.OrderDetailTemplateId, OrderId: *fsOrderDetailItem.OrderId, Pcs: fsOrderDetailBuyNum, PcsBox: pcsBox, Price: *fsOrderDetailItem.FsOrderDetail.Amount, ProductId: *fsOrderDetailItem.OptionPrice, Title: *fsOrderDetailItem.FsProductInfo.Title, Size: *fsOrderDetailItem.FsOrderDetailTemplateInfo.FsProductSizeInfo.Capacity, IsStop: isStop, }) } pbData.ProductList = productList } pbData.IsStop = isStopMax pbData.PcsBox = pcsBox pbData.Pcs = pcs pbData.SurplusAt = surplusAt pbData.Deposit = *item.TotalAmount / 2 pbData.Remaining = pbData.Deposit respList = append(respList, pbData) } } return resp.SetStatusWithMessage(basic.CodeOK, "success", types.UserOrderListRsp{ Items: respList, Meta: types.Meta{ TotalCount: total, PageCount: int64(math.Ceil(float64(total) / float64(pageSize))), CurrentPage: int(page), PerPage: int(pageSize), }, }) }