You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

301 lines
10 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. <?php
  2. namespace App\Controller\v3;
  3. use App\Constants\v3\ErrorCode;
  4. use App\Constants\v3\LogLabel;
  5. use App\Constants\v3\OrderState;
  6. use App\Controller\BaseController;
  7. use App\Exception\ErrorCodeException;
  8. use App\Model\v3\Market;
  9. use App\Model\v3\OrderMain;
  10. use App\Request\v3\OrderOnlineDetailRequest;
  11. use App\Request\v3\OrderOnlineRequest;
  12. use App\Request\v3\OrderOnlineStateRequest;
  13. use App\Request\v3\UserRequest;
  14. use App\Service\v3\Implementations\PaymentService;
  15. use App\Service\v3\Interfaces\CouponRecServiceInterface;
  16. use App\Service\v3\Interfaces\DistributionPriceServiceInterface;
  17. use App\Service\v3\Interfaces\LocationServiceInterface;
  18. use App\Service\v3\Interfaces\SeparateAccountsServiceInterface;
  19. use App\Service\v3\Interfaces\ShopCartServiceInterface;
  20. use Hyperf\DbConnection\Db;
  21. use Hyperf\Di\Annotation\Inject;
  22. use App\Service\v3\Interfaces\OrderOnlineServiceInterface;
  23. use App\Service\v3\Interfaces\UserBindTelServiceInterface;
  24. use App\Service\v3\Interfaces\AppointmentTimeServiceInterface;
  25. use Psr\Http\Message\ResponseInterface;
  26. use App\Model\v3\UserAddress;
  27. class OrderOnlineController extends BaseController
  28. {
  29. /**
  30. * @Inject
  31. * @var UserBindTelServiceInterface
  32. */
  33. protected $userBindTelService;
  34. /**
  35. * @Inject
  36. * @var CouponRecServiceInterface
  37. */
  38. protected $couponRecService;
  39. /**
  40. * @Inject
  41. * @var AppointmentTimeServiceInterface
  42. */
  43. protected $appointmentTimeService;
  44. /**
  45. * @Inject
  46. * @var OrderOnlineServiceInterface
  47. */
  48. protected $orderOnlineService;
  49. /**
  50. * @Inject
  51. * @var ShopCartServiceInterface
  52. */
  53. protected $shopCartService;
  54. /**
  55. * @Inject
  56. * @var SeparateAccountsServiceInterface
  57. */
  58. protected $separateAccountsService;
  59. /**
  60. * @Inject
  61. * @var LocationServiceInterface
  62. */
  63. protected $locationService;
  64. /**
  65. * @Inject
  66. * @var DistributionPriceServiceInterface
  67. */
  68. protected $distributionPriceService;
  69. /*
  70. * 如果没有绑手机号去绑定页面
  71. * 收货地址接口
  72. * 返回预约送达时间
  73. * 商品数据接口
  74. * 红包独立接口
  75. * 配送费独立接口 可根据距离动态计算费用
  76. * 增值服务接口
  77. * */
  78. public function review(UserRequest $request)
  79. {
  80. $userId = $this->request->input('user_id','');
  81. $marketId = $this->request->input('market_id','');
  82. $shopcartIds = $this->request->input('shopcart_ids','');
  83. //判断用户有没有绑定手机
  84. $telExists = $this->userBindTelService->check($userId);
  85. if(!$telExists){
  86. throw new ErrorCodeException(ErrorCode::NOT_BIND_TEL_ERROR);
  87. }
  88. //获取用户收货地址
  89. $address = UserAddress::query()
  90. ->where('user_id',$userId)
  91. //->where('is_default',1)
  92. ->orderByDesc('is_default')
  93. ->orderByDesc('updated_at')
  94. ->first();
  95. $market = Market::find($marketId);
  96. $distance = 0;
  97. if(!empty($address->lng) && !empty($address->lat)){
  98. $distance = $this->locationService->getDistanceByTencent($market->lng,$market->lat,$address->lng,$address->lat);
  99. }
  100. $deliveryDistance = config('distance.delivery_distance');
  101. if(isset($distance) && $distance < $deliveryDistance){
  102. if($distance >= 1000){
  103. $distance_text = '距你收货地址 ' . bcdiv($distance,1000,2) . 'km';
  104. }else{
  105. $distance_text = '距你收货地址 ' . $distance . 'm';
  106. }
  107. $distributionPrice = $this->distributionPriceService->do($distance);
  108. $res['location'] = [
  109. 'address' => $address,
  110. 'distribution_price' => $distributionPrice,
  111. 'distance' => $distance,
  112. 'within' => true,
  113. // 'distribution_text' => '¥ '.$distributionPrice .'(' .$distance_text .')'
  114. 'distribution_text' => $distance_text
  115. ];
  116. }else{
  117. $res['location'] = [
  118. 'address' => '',
  119. 'distribution_price' => 3.5,
  120. 'distance' => $distance,
  121. 'within' => false,
  122. 'distribution_text' => '¥ 3.5'
  123. ];
  124. }
  125. //返回预约送达时间 数组
  126. $ret = $retSelfTake = $this->appointmentTimeService->get($shopcartIds);
  127. array_unshift($ret,['title'=>'尽快送达','value'=>'尽快送达']);
  128. $res['appointment_time'] = $ret;
  129. array_unshift($retSelfTake,['title'=>'尽快取货','value'=>'尽快取货']);
  130. $res['appointment_time_self_take'] = $retSelfTake;
  131. $res['store_list'] = $this->shopCartService->getGoodsByShopcartId($shopcartIds);
  132. //获取用户优惠券
  133. $coupons = $this->couponRecService->allForOnlineOrderAvailable($userId, $marketId);
  134. $res['coupon'] = [
  135. 'available' => [],
  136. 'not_available' => [],
  137. ];
  138. foreach ($coupons as $key => &$item) {
  139. foreach ($item as $k => &$rec) {
  140. for ($i=0; $i<$rec->number_remain; $i++) {
  141. if ($key == 'available') {
  142. $res['coupon']['available'][] = $rec;
  143. } elseif ($key == 'not_available') {
  144. $res['coupon']['not_available'][] = $rec;
  145. }
  146. }
  147. }
  148. }
  149. // $res['coupon'] = $coupons;
  150. //增值服务接口
  151. $res['value_added_service'] = [
  152. 'text' => '增值服务包含洗菜、切菜、打包等所产生的人工成本费及包装费。',
  153. 'select' => 0,
  154. 'price' => 0,
  155. 'original_price' => 3.5
  156. ];
  157. $total = 0;
  158. foreach ($res['store_list'] as $store)
  159. {
  160. $total = bcadd($total,$store['subtotal'],2);
  161. }
  162. $total = bcadd($total,$res['value_added_service']['price'],2);
  163. $total = bcadd($total,$res['location']['distribution_price'],2);
  164. $res['total'] = $total;
  165. // 新增返回市场信息
  166. $res['market'] = $market;
  167. return $this->success($res);
  168. }
  169. /**
  170. * 订单详情
  171. * 1、主订单信息,用户配送信息(地址、姓名、电话、配送时间、配送类型)、基础信息(订单ID、订单编号、下单时间、订单金额、付款时间、支付方式、红包优惠、服务站电话、增值服务费)
  172. * 2、子订单以及订单商品,按商户分组,有商户信息(ID、商户名、商户logo),商品信息(id、名字、封面、规格、tag、原价、售价、库存、总销、月销、是否失效、失效原因)
  173. * @param OrderOnlineDetailRequest $request
  174. * @return ResponseInterface
  175. */
  176. public function detailByUser(OrderOnlineDetailRequest $request)
  177. {
  178. $params = $request->validated();
  179. return $this->success(['detail' => $this->orderOnlineService->detailByUser($params['global_order_id'], $params['user_id'])]);
  180. }
  181. /**
  182. * 下单并进行支付,返回支付参数
  183. * 1、用户传参,用户地址ID,用于获取用户地址经纬度来计算配送费
  184. * 2、用户传参,购物车IDs,去获取购物车里的商品详情
  185. * 3、预约送达时间
  186. * 4、优惠券IDs
  187. * 5、订单总金额,用于校验比对
  188. * 6、下单成功,请求支付
  189. * @param OrderOnlineRequest $request
  190. * @return ResponseInterface
  191. */
  192. public function add(OrderOnlineRequest $request){
  193. // 下单
  194. $params = $request->validated();
  195. $couponIds = isset($params['coupon_ids'])&&$params['coupon_ids'] ? explode(',', $params['coupon_ids']) : [];
  196. $data = $this->orderOnlineService->do(
  197. $params['market_id'],
  198. $params['user_id'],
  199. ($params['user_address_id'] ?? 0),
  200. json_decode($params['store_list']),
  201. $params['total_money'],
  202. $params['delivery_time_note'],
  203. ($params['service_money'] ?? 0),
  204. $couponIds,
  205. $params['plat'] ?: '',
  206. ($params['self_take'] ?? 0)
  207. );
  208. return $this->success(['data' => $data]);
  209. }
  210. /**
  211. * 待支付订单重新发起支付
  212. * 1、用户id、订单id
  213. * 2、发起支付
  214. * @param OrderOnlineStateRequest $request
  215. * @return ResponseInterface
  216. */
  217. public function pay(OrderOnlineStateRequest $request)
  218. {
  219. $params = $request->validated();
  220. $data = $this->orderOnlineService->doPay($params['global_order_id'], $params['user_id']);
  221. return $this->success(['data' => $data]);
  222. }
  223. /**
  224. * 取消订单
  225. * @param OrderOnlineStateRequest $request
  226. * @return ResponseInterface
  227. */
  228. public function cancel(OrderOnlineStateRequest $request)
  229. {
  230. $params = $request->validated();
  231. $this->orderOnlineService->undo($params['global_order_id'], $params['user_id']);
  232. return $this->success([]);
  233. }
  234. /**
  235. * 删除订单
  236. * @param OrderOnlineStateRequest $request
  237. * @return ResponseInterface
  238. */
  239. public function del(OrderOnlineStateRequest $request)
  240. {
  241. $params = $request->validated();
  242. $this->orderOnlineService->doDel($params['global_order_id'], $params['user_id']);
  243. return $this->success([]);
  244. }
  245. /**
  246. * 申请退款
  247. * @param OrderOnlineStateRequest $request
  248. * @return ResponseInterface
  249. */
  250. public function applyRefund(OrderOnlineStateRequest $request)
  251. {
  252. $params = $request->validated();
  253. $this->orderOnlineService->doApplyRefund($params['global_order_id'], $params['user_id']);
  254. return $this->success([]);
  255. }
  256. /**
  257. * 完成订单
  258. * @param OrderOnlineStateRequest $request
  259. * @return ResponseInterface
  260. */
  261. public function complete(OrderOnlineStateRequest $request)
  262. {
  263. Db::beginTransaction();
  264. try {
  265. $params = $request->validated();
  266. $this->orderOnlineService->doComplete($params['global_order_id'], $params['user_id']);
  267. $this->separateAccountsService->orderOnlineCompleted($params['global_order_id'], $params['user_id']);
  268. Db::commit();
  269. return $this->success([]);
  270. } catch (\Exception $e) {
  271. Db::rollBack();
  272. $this->log->event(LogLabel::ORDER_COMPLETE_LOG, ['exception' => $e->getMessage()]);
  273. throw new ErrorCodeException(ErrorCode::ORDER_COMPLETE_FAIL);
  274. }
  275. }
  276. }