package ordersrv import ( "Cold_Logistic/internal/pkg/common/codex" "Cold_Logistic/internal/pkg/common/constant" "Cold_Logistic/internal/pkg/common/global" "Cold_Logistic/internal/server/domain/domainservice" "Cold_Logistic/internal/server/infra/dao" "Cold_Logistic/internal/server/infra/models" "context" "fmt" "gogs.baozhida.cn/Cold_Logistic_libs/pkg/contrib/errors" ) type OrderService struct { store *dao.DataStore } func NewOrderService(store *dao.DataStore) *OrderService { return &OrderService{store: store} } // PlaceOrder 下单 func (srv *OrderService) PlaceOrder(ctx context.Context, req PlaceOrderReqVO) (res PlaceOrderRespVO, err error) { order := models.ExpressOrder{ OrderStatus: constant.OrderStatusPending, CargoType: req.CargoType, TemperatureInterval: req.TemperatureInterval, CargoNumber: req.CargoNumber, DeliveryCondition: req.DeliveryCondition, DeliveryRemark: req.DeliveryRemark, TimeLimit: req.TimeLimit, PickupTime: req.PickupTime, IsWeekendPickup: req.IsWeekendPickup, IsInsuredValue: req.IsInsuredValue, } err = srv.store.InTx(ctx, func(ctx context.Context) error { var logistic models.LogisticCompany // 物流 if req.LogisticId == 0 { logistic, err = srv.processLogistic(ctx, req.LogisticId, req.LogisticPid, req.LogisticPidName) if err != nil { return errors.WithStackOnce(err) } } order.LogisticId = logistic.Id order.Pid = logistic.Pid // 寄/收件人地址 order.SenderAddressId, err = srv.processAddress(ctx, constant.AddressTypeSender, req.Sender) if err != nil { return errors.WithStackOnce(err) } order.ConsigneeAddressId, err = srv.processAddress(ctx, constant.AddressTypeConsignee, req.Consignee) if err != nil { return errors.WithStackOnce(err) } // 获取订单号 order.OrderNo, err = domainservice.GetOrderNo(ctx) if err != nil { return errors.WithStackOnce(err) } // 创建订单 if err = srv.store.ExpressOrder().Create(ctx, &order); err != nil { return errors.WithStackOnce(err) } return nil }) if err != nil { return res, errors.WithStackOnce(err) } res.OrderNo = order.OrderNo res.PlaceOrderTime = order.CreatedTime return res, nil } // AssignOrder 派单 func (srv *OrderService) AssignOrder(ctx context.Context, req AssignOrderReqVO) (res AssignOrderRespVO, err error) { tokenInfo := global.GetTokenInfoFromContext(ctx) order := models.ExpressOrder{} if err = srv.store.ExpressOrder().FirstById(ctx, &order, req.OrderId); err != nil { return res, errors.WithStackOnce(err) } if err = srv.checkCanAssign(ctx, order); err != nil { return res, errors.WithStackOnce(err) } _, err = domainservice.GetOrderSubNo(ctx, order.OrderNo) if err != nil { return res, errors.WithStackOnce(err) } log := models.OrderLogisticLog{ LogType: constant.LogisticLogTraffic, OrderId: order.Id, OrderNo: order.OrderNo, ContactPersonUuid: tokenInfo.AccountUuid, ContactPerson: tokenInfo.Name, ContactPhone: tokenInfo.Phone, Extend: fmt.Sprintf(constant.TemplateAssignOrder, req.Driver.Name), } err = srv.store.InTx(ctx, func(ctx context.Context) error { task := models.OrderTransportTask{ OrderId: order.Id, Status: constant.TaskStatusPending, Destination: req.Destination, } task.ExecutorAccountId, task.CarId, err = domainservice.ProcessDriver(ctx, 0, req.Driver) if err != nil { return errors.WithStackOnce(err) } if task.CarId == 0 { return errors.WithCode(codex.ErrParamValidate, "揽件司机未绑定车辆,请绑定后再派单") } if err = srv.store.OrderTransportTask().Create(ctx, &task); err != nil { return errors.WithStackOnce(err) } if err = srv.store.OrderLogisticLog().Create(ctx, &log); err != nil { return errors.WithStackOnce(err) } order.OrderStatus = constant.OrderStatusWaitCar order.LatestTaskId = task.Id if err = srv.store.ExpressOrder().UpdateById(ctx, &order); err != nil { return errors.WithStackOnce(err) } return nil }) if err != nil { return res, errors.WithStackOnce(err) } res.OrderId = order.Id return res, nil } func (srv *OrderService) processAddress(ctx context.Context, addressType string, req AddressVO) (int, error) { if req.AddressId > 0 { return req.AddressId, nil } address := models.AddressBook{ AddressType: addressType, Name: req.Name, Phone: req.Phone, ProvinceId: req.ProvinceId, ProvinceName: req.ProvinceName, CityId: req.CityId, CityName: req.CityName, RegionId: req.RegionId, RegionName: req.RegionName, Address: req.Address, IsDefault: req.IsDefault, } err := domainservice.AddMyselfAddressTx(ctx, &address) if err != nil { return 0, errors.WithStackOnce(err) } return address.Id, nil } func (srv *OrderService) processLogistic(ctx context.Context, logisticId, logisticPid int, logisticName string) (res models.LogisticCompany, err error) { if logisticId > 0 { if err = srv.store.LogisticCompany().FirstById(ctx, &res, logisticId); err != nil { return res, errors.WithStackOnce(err) } } else { res, err = srv.store.LogisticCompany().FindMyByPid(ctx, logisticPid) if err != nil { return res, errors.WithStackOnce(err) } if res.Id == 0 { res.Pid = logisticPid res.Name = logisticName if err = srv.store.LogisticCompany().Create(ctx, &res); err != nil { return res, errors.WithStackOnce(err) } } } return res, nil } func (srv *OrderService) checkCanAssign(ctx context.Context, order models.ExpressOrder) error { if order.OrderStatus == constant.OrderStatusReceived { return errors.New("订单已签收") } if order.LatestTaskId <= 0 { return nil } task := models.OrderTransportTask{} if err := srv.store.OrderTransportTask().FirstById(ctx, &task, order.LatestTaskId); err != nil { return errors.WithStackOnce(err) } if task.Status != constant.TaskStatusFinished { return errors.New("还有未处理步骤,无法再次派单") } return nil }