PointsOrder.php 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\controller\api\store\order;
  12. use app\common\repositories\delivery\DeliveryOrderRepository;
  13. use app\common\repositories\store\order\PointsOrderCreateRepository;
  14. use app\common\repositories\store\order\StoreOrderCreateRepository;
  15. use app\common\repositories\store\order\StoreOrderReceiptRepository;
  16. use app\validate\api\UserReceiptValidate;
  17. use crmeb\basic\BaseController;
  18. use app\common\repositories\store\order\StoreCartRepository;
  19. use app\common\repositories\store\order\StoreGroupOrderRepository;
  20. use app\common\repositories\store\order\StoreOrderRepository;
  21. use crmeb\services\ExpressService;
  22. use crmeb\services\LockService;
  23. use think\App;
  24. use think\exception\ValidateException;
  25. use think\facade\Log;
  26. /**
  27. * Class StoreOrder
  28. * @package app\controller\api\store\order
  29. * @author xaboy
  30. * @day 2020/6/10
  31. */
  32. class PointsOrder extends BaseController
  33. {
  34. /**
  35. * @var StoreOrderRepository
  36. */
  37. protected $repository;
  38. /**
  39. * StoreOrder constructor.
  40. * @param App $app
  41. * @param StoreOrderRepository $repository
  42. */
  43. public function __construct(App $app, StoreOrderRepository $repository)
  44. {
  45. parent::__construct($app);
  46. $this->repository = $repository;
  47. }
  48. /**
  49. * 在确认订单前进行购物车检查
  50. * 该方法主要用于在用户提交订单前,验证购物车中的商品是否有效,以及处理相关的优惠券和积分使用等逻辑。
  51. *
  52. * @param StoreCartRepository $cartRepository 购物车仓库对象,用于操作购物车数据。
  53. *
  54. * @return json 返回一个包含订单信息的JSON对象,如果数据无效,则返回错误信息。
  55. */
  56. public function beforCheck(StoreCartRepository $cartRepository)
  57. {
  58. // 获取请求中的购物车ID、收货地址ID、是否使用积分以及优惠券ID和代金券ID
  59. $cartId = (array)$this->request->param('cart_id', []);
  60. $addressId = (int)$this->request->param('address_id');
  61. $useIntegral = (bool)$this->request->param('use_integral', true);
  62. $params['couponIds'] = (array)$this->request->param('use_coupon', []);
  63. $params['takes'] = (array)$this->request->param('takes', []);
  64. // 获取当前请求的用户信息
  65. $user = $this->request->userInfo();
  66. // 验证购物车ID的数量是否有效,并检查购物车ID是否与用户ID匹配
  67. if (!($count = count($cartId)) || $count != count($cartRepository->validIntersection($cartId, $user->uid)))
  68. return app('json')->fail('数据无效');
  69. // 调用订单创建仓库的check方法,检查订单是否可以创建,并返回订单信息
  70. $orderInfo = app()->make(PointsOrderCreateRepository::class)->check($user, $cartId, $addressId, $useIntegral, $params);
  71. // 返回订单信息的JSON对象
  72. return app('json')->success($orderInfo);
  73. }
  74. /**
  75. * 创建订单
  76. *
  77. * 本函数负责根据用户购物车信息、收货地址、支付方式等创建订单。
  78. * 它处理了PC端和移动端的不同支付方式,并对订单创建过程进行了事务处理,确保数据一致性。
  79. *
  80. * @param StoreCartRepository $cartRepository 购物车仓库,用于获取和验证购物车项。
  81. * @return mixed 返回创建的订单信息,可能是一个支付成功的提示,或者是支付接口的跳转信息。
  82. */
  83. public function createOrder(StoreCartRepository $cartRepository)
  84. {
  85. // 获取购物车ID、收货地址ID、是否使用积分、标记和支付方式
  86. $cartId = (array)$this->request->param('cart_id', []);
  87. $addressId = (int)$this->request->param('address_id');
  88. $useIntegral = (bool)$this->request->param('use_integral', true);
  89. $mark = $this->request->param('mark', '');
  90. $payType = $this->request->param('pay_type');
  91. // 判断是否为PC端支付,PC端默认支付方式为余额支付
  92. $isPc = $payType === 'pc';
  93. if ($isPc) $payType = 'balance';
  94. // 检查支付方式是否有效
  95. if (!in_array($payType, StoreOrderRepository::PAY_TYPE, true))
  96. return app('json')->fail('请选择正确的支付方式');
  97. // 获取用户ID
  98. $uid = $this->request->uid();
  99. // 验证购物车ID的有效性
  100. if (!($count = count($cartId)) || $count != count($cartRepository->validIntersection($cartId, $uid)))
  101. return app('json')->fail('数据无效');
  102. // 使用锁服务,确保并发下的数据一致性
  103. $make = app()->make(LockService::class);
  104. // 通过积分创建订单,使用事务处理确保数据一致性
  105. $groupOrder = $make->exec('points.order.create', function () use ($mark, $cartId, $payType, $useIntegral, $addressId) {
  106. return app()->make(PointsOrderCreateRepository::class)->createOrder($this->request->userInfo(),$cartId,$addressId,$useIntegral,$mark,array_search($payType, StoreOrderRepository::PAY_TYPE));
  107. });
  108. // 如果订单支付价格为0,表示订单已支付成功
  109. if ($groupOrder['pay_price'] == 0) {
  110. $this->repository->paySuccess($groupOrder);
  111. return app('json')->status('success', '支付成功', ['order_id' => $groupOrder['group_order_id']]);
  112. }
  113. // PC端直接返回订单ID
  114. if ($isPc) {
  115. return app('json')->success(['order_id' => $groupOrder->group_order_id]);
  116. }
  117. // 移动端调用支付接口进行支付
  118. try {
  119. return $this->repository->pay($payType, $this->request->userInfo(), $groupOrder, $this->request->param('return_url'), $this->request->isApp(), false);
  120. } catch (\Exception $e) {
  121. // 支付过程中出现异常,返回错误信息和订单ID
  122. return app('json')->status('error', $e->getMessage(), ['order_id' => $groupOrder->group_order_id]);
  123. }
  124. }
  125. /**
  126. * 积分商品订单
  127. * @param StoreOrderRepository $storeOrderRepository
  128. * @return \think\response\Json
  129. * @author Qinii
  130. * @day 2023/4/23
  131. */
  132. public function lst(StoreOrderRepository $storeOrderRepository)
  133. {
  134. [$page, $limit] = $this->getPage();
  135. $where = $this->request->params(['pay_type','paid','status']);
  136. $where['activity_type'] = 20;
  137. $where['uid'] = $this->request->uid();
  138. return app('json')->success($storeOrderRepository->pointsOrderList($where,$page, $limit));
  139. }
  140. /**
  141. * 查询积分订单详情
  142. *
  143. * 本函数用于根据订单ID查询积分订单的详细信息。它首先尝试根据提供的ID和当前用户的UID来获取订单。
  144. * 如果订单不存在,则返回一个失败的JSON响应;如果订单存在,则返回订单的详细信息。
  145. *
  146. * @param int $id 积分订单的ID
  147. * @param StoreOrderRepository $storeOrderRepository 积分订单仓库对象,用于查询订单
  148. * @return mixed 返回一个失败的JSON响应或者包含订单详情的JSON响应
  149. */
  150. public function detail($id, StoreOrderRepository $storeOrderRepository)
  151. {
  152. // 根据订单ID和当前用户UID查询积分订单详情
  153. $order = $storeOrderRepository->pointsDetail((int)$id, $this->request->uid());
  154. // 如果订单不存在,则返回一个失败的JSON响应
  155. if (!$order)
  156. return app('json')->fail('订单不存在');
  157. // 如果订单存在,则返回包含订单详情的JSON响应
  158. return app('json')->success($order->toArray());
  159. }
  160. /**
  161. * 确认订单收货
  162. *
  163. * 本函数用于处理订单的收货确认操作。当用户确认收货时,此函数将被调用。
  164. * 它通过调用仓库接口的takeOrder方法,标记订单为已收货,并传递订单ID和用户信息。
  165. *
  166. * @param int $id 订单ID,用于标识待确认收货的订单。
  167. * @return \Illuminate\Http\JsonResponse 返回一个JSON响应,指示确认收货操作成功。
  168. */
  169. public function take($id)
  170. {
  171. // 调用仓库 repository 的 takeOrder 方法,处理订单收货确认
  172. $this->repository->takeOrder($id, $this->request->userInfo());
  173. // 返回一个成功的JSON响应,告知用户收货确认已成功
  174. return app('json')->success('确认收货成功');
  175. }
  176. /**
  177. * 删除用户
  178. *
  179. * 本函数用于执行用户删除操作。它接收一个用户ID作为参数,
  180. * 并调用仓库层的用户删除方法来执行实际的删除操作。删除操作
  181. * 是基于当前请求的用户ID执行的,确保了操作的安全性和审计
  182. * 能力。函数在成功执行删除操作后,会返回一个表示删除成功
  183. * 的JSON响应。
  184. *
  185. * @param int $id 用户ID,指定要删除的用户
  186. * @return \Illuminate\Http\JsonResponse 删除成功的JSON响应
  187. */
  188. public function del($id)
  189. {
  190. // 调用仓库层的方法,删除指定ID的用户,同时传入当前请求的用户ID作为安全校验
  191. $this->repository->userDel($id, $this->request->uid());
  192. // 返回一个表示删除成功的JSON响应
  193. return app('json')->success('删除成功');
  194. }
  195. }