service.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. package ordersrv
  2. import (
  3. "Cold_Logistic/internal/pkg/common/codex"
  4. "Cold_Logistic/internal/pkg/common/constant"
  5. "Cold_Logistic/internal/pkg/common/global"
  6. "Cold_Logistic/internal/server/domain/domainservice"
  7. "Cold_Logistic/internal/server/infra/dao"
  8. "Cold_Logistic/internal/server/infra/models"
  9. "context"
  10. "fmt"
  11. "gogs.baozhida.cn/Cold_Logistic_libs/pkg/contrib/errors"
  12. )
  13. type OrderService struct {
  14. store *dao.DataStore
  15. }
  16. func NewOrderService(store *dao.DataStore) *OrderService {
  17. return &OrderService{store: store}
  18. }
  19. // PlaceOrder 下单
  20. func (srv *OrderService) PlaceOrder(ctx context.Context, req PlaceOrderReqVO) (res PlaceOrderRespVO, err error) {
  21. order := models.ExpressOrder{
  22. OrderStatus: constant.OrderStatusPending,
  23. CargoType: req.CargoType,
  24. TemperatureInterval: req.TemperatureInterval,
  25. CargoNumber: req.CargoNumber,
  26. DeliveryCondition: req.DeliveryCondition,
  27. DeliveryRemark: req.DeliveryRemark,
  28. TimeLimit: req.TimeLimit,
  29. PickupTime: req.PickupTime,
  30. IsWeekendPickup: req.IsWeekendPickup,
  31. IsInsuredValue: req.IsInsuredValue,
  32. }
  33. err = srv.store.InTx(ctx, func(ctx context.Context) error {
  34. var logistic models.LogisticCompany
  35. // 物流
  36. if req.LogisticId == 0 {
  37. logistic, err = srv.processLogistic(ctx, req.LogisticId, req.LogisticPid, req.LogisticPidName)
  38. if err != nil {
  39. return errors.WithStackOnce(err)
  40. }
  41. }
  42. order.LogisticId = logistic.Id
  43. order.Pid = logistic.Pid
  44. // 寄/收件人地址
  45. order.SenderAddressId, err = srv.processAddress(ctx, constant.AddressTypeSender, req.Sender)
  46. if err != nil {
  47. return errors.WithStackOnce(err)
  48. }
  49. order.ConsigneeAddressId, err = srv.processAddress(ctx, constant.AddressTypeConsignee, req.Consignee)
  50. if err != nil {
  51. return errors.WithStackOnce(err)
  52. }
  53. // 获取订单号
  54. order.OrderNo, err = domainservice.GetOrderNo(ctx)
  55. if err != nil {
  56. return errors.WithStackOnce(err)
  57. }
  58. // 创建订单
  59. if err = srv.store.ExpressOrder().Create(ctx, &order); err != nil {
  60. return errors.WithStackOnce(err)
  61. }
  62. return nil
  63. })
  64. if err != nil {
  65. return res, errors.WithStackOnce(err)
  66. }
  67. res.OrderNo = order.OrderNo
  68. res.PlaceOrderTime = order.CreatedTime
  69. return res, nil
  70. }
  71. // AssignOrder 派单
  72. func (srv *OrderService) AssignOrder(ctx context.Context, req AssignOrderReqVO) (res AssignOrderRespVO, err error) {
  73. tokenInfo := global.GetTokenInfoFromContext(ctx)
  74. order := models.ExpressOrder{}
  75. if err = srv.store.ExpressOrder().FirstById(ctx, &order, req.OrderId); err != nil {
  76. return res, errors.WithStackOnce(err)
  77. }
  78. if err = srv.checkCanAssign(ctx, order); err != nil {
  79. return res, errors.WithStackOnce(err)
  80. }
  81. _, err = domainservice.GetOrderSubNo(ctx, order.OrderNo)
  82. if err != nil {
  83. return res, errors.WithStackOnce(err)
  84. }
  85. log := models.OrderLogisticLog{
  86. LogType: constant.LogisticLogTraffic,
  87. OrderId: order.Id,
  88. OrderNo: order.OrderNo,
  89. ContactPersonUuid: tokenInfo.AccountUuid,
  90. ContactPerson: tokenInfo.Name,
  91. ContactPhone: tokenInfo.Phone,
  92. Extend: fmt.Sprintf(constant.TemplateAssignOrder, req.Driver.Name),
  93. }
  94. err = srv.store.InTx(ctx, func(ctx context.Context) error {
  95. task := models.OrderTransportTask{
  96. OrderId: order.Id,
  97. Status: constant.TaskStatusPending,
  98. Destination: req.Destination,
  99. }
  100. task.ExecutorAccountId, task.CarId, err = domainservice.ProcessDriver(ctx, 0, req.Driver)
  101. if err != nil {
  102. return errors.WithStackOnce(err)
  103. }
  104. if task.CarId == 0 {
  105. return errors.WithCode(codex.ErrParamValidate, "揽件司机未绑定车辆,请绑定后再派单")
  106. }
  107. if err = srv.store.OrderTransportTask().Create(ctx, &task); err != nil {
  108. return errors.WithStackOnce(err)
  109. }
  110. if err = srv.store.OrderLogisticLog().Create(ctx, &log); err != nil {
  111. return errors.WithStackOnce(err)
  112. }
  113. order.OrderStatus = constant.OrderStatusWaitCar
  114. order.LatestTaskId = task.Id
  115. if err = srv.store.ExpressOrder().UpdateById(ctx, &order); err != nil {
  116. return errors.WithStackOnce(err)
  117. }
  118. return nil
  119. })
  120. if err != nil {
  121. return res, errors.WithStackOnce(err)
  122. }
  123. res.OrderId = order.Id
  124. return res, nil
  125. }
  126. func (srv *OrderService) processAddress(ctx context.Context, addressType string, req AddressVO) (int, error) {
  127. if req.AddressId > 0 {
  128. return req.AddressId, nil
  129. }
  130. address := models.AddressBook{
  131. AddressType: addressType,
  132. Name: req.Name,
  133. Phone: req.Phone,
  134. ProvinceId: req.ProvinceId,
  135. ProvinceName: req.ProvinceName,
  136. CityId: req.CityId,
  137. CityName: req.CityName,
  138. RegionId: req.RegionId,
  139. RegionName: req.RegionName,
  140. Address: req.Address,
  141. IsDefault: req.IsDefault,
  142. }
  143. err := domainservice.AddMyselfAddressTx(ctx, &address)
  144. if err != nil {
  145. return 0, errors.WithStackOnce(err)
  146. }
  147. return address.Id, nil
  148. }
  149. func (srv *OrderService) processLogistic(ctx context.Context, logisticId, logisticPid int, logisticName string) (res models.LogisticCompany, err error) {
  150. if logisticId > 0 {
  151. if err = srv.store.LogisticCompany().FirstById(ctx, &res, logisticId); err != nil {
  152. return res, errors.WithStackOnce(err)
  153. }
  154. } else {
  155. res, err = srv.store.LogisticCompany().FindMyByPid(ctx, logisticPid)
  156. if err != nil {
  157. return res, errors.WithStackOnce(err)
  158. }
  159. if res.Id == 0 {
  160. res.Pid = logisticPid
  161. res.Name = logisticName
  162. if err = srv.store.LogisticCompany().Create(ctx, &res); err != nil {
  163. return res, errors.WithStackOnce(err)
  164. }
  165. }
  166. }
  167. return res, nil
  168. }
  169. func (srv *OrderService) checkCanAssign(ctx context.Context, order models.ExpressOrder) error {
  170. if order.OrderStatus == constant.OrderStatusReceived {
  171. return errors.New("订单已签收")
  172. }
  173. if order.LatestTaskId <= 0 {
  174. return nil
  175. }
  176. task := models.OrderTransportTask{}
  177. if err := srv.store.OrderTransportTask().FirstById(ctx, &task, order.LatestTaskId); err != nil {
  178. return errors.WithStackOnce(err)
  179. }
  180. if task.Status != constant.TaskStatusFinished {
  181. return errors.New("还有未处理步骤,无法再次派单")
  182. }
  183. return nil
  184. }