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.

355 lines
11 KiB

  1. <?php
  2. namespace api\logic;
  3. use antgoods\goods\models\ars\Goods;
  4. use antgoods\goods\models\ars\GoodsSku;
  5. use common\models\ars\Address;
  6. use common\models\ars\Cart;
  7. use common\models\ars\Order;
  8. use common\models\ars\OrderGoods;
  9. use common\models\ars\TakingSite;
  10. use yii\base\Component;
  11. use Yii;
  12. use yii\db\ActiveRecord;
  13. use yii\web\BadRequestHttpException;
  14. use yii\web\NotFoundHttpException;
  15. use yii\web\ServerErrorHttpException;
  16. /**
  17. * @author iron
  18. * @email weiriron@gmail.com
  19. * Class CartLogic
  20. * @package api\logic
  21. */
  22. class OrderLogic extends Component
  23. {
  24. public $viewAction = 'view';
  25. /*创建途径类型*/
  26. const TYPE_ADD_GOODS_PURCHASE = 1;
  27. const TYPE_ADD_GOODS_CART = 2;
  28. /*订单操作类型*/
  29. const TYPE_CONFIRM = 1;
  30. const TYPE_CANCEL = 2;
  31. const TYPE_TAKE = 3;
  32. const TYPE_CHANGE_SHIPPING_TYPE = 4;
  33. const TYPE_CHANGE_ADDRESS = 5;
  34. const TYPE_CHANGE_TAKING_SITE = 6;
  35. /*仓库类型*/
  36. const TYPE_ADD_STOCK = 1;
  37. const TYPE_SUB_STOCK = -1;
  38. /**
  39. * @param $data
  40. * @return bool|\Exception|\yii\base\Exception
  41. */
  42. public function update($data)
  43. {
  44. $type = Yii::$app->request->getQueryParam('type');
  45. $order = $this->findOrder();
  46. $tra = Yii::$app->db->beginTransaction();
  47. try {
  48. switch ($type) {
  49. case self::TYPE_CONFIRM :
  50. $this->confirm($order, $data);
  51. break;
  52. case self::TYPE_CANCEL:
  53. $this->cancel($order);
  54. break;
  55. case self::TYPE_TAKE:
  56. $this->take($order);
  57. break;
  58. case self::TYPE_CHANGE_SHIPPING_TYPE:
  59. $this->updateShippingType($order, $data);
  60. break;
  61. case self::TYPE_CHANGE_ADDRESS:
  62. $this->changeAddress($order, $data);
  63. break;
  64. case self::TYPE_CHANGE_TAKING_SITE:
  65. $this->changeTakingSite($order, $data);
  66. break;
  67. }
  68. if (!$order->save()) {
  69. throw new ServerErrorHttpException('服务器更新订单失败');
  70. }
  71. $tra->commit();
  72. return true;
  73. } catch (\yii\base\Exception $e) {
  74. $tra->rollBack();
  75. return $e;
  76. }
  77. }
  78. /**
  79. * @param Order $order
  80. * @param array $data
  81. * @throws BadRequestHttpException
  82. * @throws NotFoundHttpException
  83. */
  84. private function changeAddress($order, $data)
  85. {
  86. if (!isset($data['address_id'])) {
  87. throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS);
  88. }
  89. if ($order->shipping_type !== Order::SHIPPING_TYPE_EXPRESS) {
  90. throw new BadRequestHttpException('配送方式异常');
  91. }
  92. $address = Address::find()
  93. ->where(['id' => $data['address_id'], 'user_id' => Yii::$app->user->getId()])
  94. ->one();
  95. if (!$address) {
  96. throw new NotFoundHttpException('收货地址未找到');
  97. }
  98. $order->consignee = $address->consignee;
  99. $order->phone = $address->phone;
  100. $order->city = $address->city;
  101. $order->area = $address->area;
  102. $order->province = $address->province;
  103. $order->address = $address->address;
  104. }
  105. /**
  106. * @param Order $order
  107. * @param array $data
  108. * @throws BadRequestHttpException
  109. * @throws NotFoundHttpException
  110. */
  111. private function changeTakingSite($order, $data)
  112. {
  113. if (!isset($data['taking_site_id']) || empty($data['taking_site_id'])) {
  114. throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS);
  115. }
  116. if ($order->shipping_type !== Order::SHIPPING_TYPE_PICKED_UP) {
  117. throw new BadRequestHttpException('配送方式异常');
  118. }
  119. $site = TakingSite::findOne($data['taking_site_id']);
  120. if (!$site) {
  121. throw new NotFoundHttpException('自提点未找到');
  122. }
  123. $order->taking_site = $data['taking_site_id'];
  124. }
  125. /**
  126. * @param Order $order
  127. * @param array $data
  128. * @throws BadRequestHttpException
  129. */
  130. private function updateShippingType($order, $data)
  131. {
  132. if (!isset($data['shipping_type'])) {
  133. throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS);
  134. }
  135. if ($order->status !== Order::STATUS_UNCONFIRMED) {
  136. throw new BadRequestHttpException('订单状态异常');
  137. }
  138. $order->shipping_type = $data['shipping_type'];
  139. }
  140. /**
  141. * @param Order $order
  142. * @param array $data
  143. * @throws BadRequestHttpException
  144. * @throws NotFoundHttpException
  145. * @throws ServerErrorHttpException
  146. */
  147. private function confirm($order, $data)
  148. {
  149. if ($order->status !== Order::STATUS_UNCONFIRMED) {
  150. throw new BadRequestHttpException('订单状态异常');
  151. }
  152. if ($order->shipping_type === Order::SHIPPING_TYPE_PICKED_UP) {
  153. if (!isset($data['consignee']) || !isset($data['phone'])
  154. || empty($data['consignee']) || empty($data['phone'])) {
  155. throw new BadRequestHttpException('(联系人)参数无效');
  156. }
  157. $order->consignee = $data['consignee'];
  158. $order->phone = $data['phone'];
  159. }
  160. if (empty($order->consignee)) {
  161. throw new BadRequestHttpException('需先填写收件人信息');
  162. }
  163. if (isset($data['remarks'])) {
  164. $order->remarks = $data['remarks'];
  165. }
  166. $order->status = Order::STATUS_NONPAYMENT;
  167. $this->updateStock($order, self::TYPE_SUB_STOCK);
  168. }
  169. /**
  170. * @param Order $order
  171. * @throws BadRequestHttpException
  172. * @throws NotFoundHttpException
  173. * @throws ServerErrorHttpException
  174. */
  175. private function cancel($order)
  176. {
  177. if ($order->status !== Order::STATUS_NONPAYMENT) {
  178. throw new BadRequestHttpException('订单状态异常');
  179. }
  180. $order->status = Order::STATUS_CANCEL;
  181. $this->updateStock($order, self::TYPE_ADD_STOCK);
  182. }
  183. /**
  184. * @param Order $order
  185. * @throws BadRequestHttpException
  186. */
  187. private function take($order)
  188. {
  189. if ($order->status !== Order::STATUS_SHIPMENT_ALL) {
  190. throw new BadRequestHttpException('订单状态异常');
  191. }
  192. $order->status = Order::STATUS_FINISH;
  193. }
  194. /**
  195. * @param $id
  196. * @param $type
  197. * @throws BadRequestHttpException
  198. * @throws NotFoundHttpException
  199. * @throws ServerErrorHttpException
  200. */
  201. private function updateStock($id, $type)
  202. {
  203. $allOrderGoods = $this->findOrderGoods($id);
  204. foreach ($allOrderGoods as $orderGoods) {
  205. /*检查库存*/
  206. Helper::checkStock($orderGoods->goods_id, $orderGoods->goods_count, $orderGoods->sku_id);
  207. if ($orderGoods->sku_id) {
  208. $goods = GoodsSku::findOne($orderGoods->sku_id);
  209. } else {
  210. $goods = Goods::findOne($orderGoods->goods_id);
  211. }
  212. if ($type) {
  213. $count = $orderGoods->goods_count;
  214. } else {
  215. $count = -$orderGoods->goods_count;
  216. }
  217. if (!$goods->updateCounters(['stock' => $count])) {
  218. throw new ServerErrorHttpException('更新库存失败');
  219. }
  220. }
  221. }
  222. /**
  223. * @param $originId
  224. * @param $count
  225. * @param $skuId
  226. * @return bool
  227. * @throws BadRequestHttpException
  228. * @throws NotFoundHttpException
  229. * 创建订单并添加商品
  230. */
  231. public function create($originId, $count, $skuId)
  232. {
  233. $type = Yii::$app->request->getQueryParam('type');
  234. if (empty($type) || ($type == self::TYPE_ADD_GOODS_CART && empty($originId)) ||
  235. ($type == self::TYPE_ADD_GOODS_PURCHASE && (empty($count) || empty($originId)))) {
  236. throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS);
  237. }
  238. if ($type == self::TYPE_ADD_GOODS_PURCHASE) {
  239. $goodsId = $originId;
  240. } else {
  241. $cart = Cart::findOne($originId);
  242. if (!$cart) {
  243. throw new NotFoundHttpException('购物车未找到');
  244. }
  245. $goodsId = $cart->goods_id;
  246. $skuId = $cart->sku_id;
  247. $count = $cart->goods_count;
  248. }
  249. /*检查库存*/
  250. Helper::checkStock($goodsId, $count, $skuId);
  251. $tra = Yii::$app->db->beginTransaction();
  252. try {
  253. $order = new Order();
  254. // $order->user_id = Yii::$app->user->getId();
  255. $order->user_id = 1;
  256. $order->type = Order::TYPE_SHOPPING;
  257. if (!$order->save()) {
  258. throw new ServerErrorHttpException('服务器创建订单失败');
  259. }
  260. $this->addGoods($order->id, $goodsId, $skuId, $count);/*创建订单商品*/
  261. $this->saveGoodsInfo($order);/*保存订单商品信息*/
  262. $tra->commit();
  263. Helper::createdResponse($order, $this->viewAction);
  264. return $order;
  265. } catch (\Exception $e) {
  266. $tra->rollBack();
  267. throw $e;
  268. }
  269. }
  270. /**
  271. * @param Order $order
  272. * @throws ServerErrorHttpException
  273. */
  274. private function saveGoodsInfo($order)
  275. {
  276. $orderGoods = $this->findOrderGoods($order->id);
  277. foreach ($orderGoods as $goods) {
  278. $order->goods_amount += $goods->price;
  279. $order->goods_count += $goods->goods_count;
  280. }
  281. if (!$order->save()) {
  282. throw new ServerErrorHttpException('服务器创建订单失败');
  283. }
  284. }
  285. /**
  286. * @param int $id
  287. * @param int $goodsId
  288. * @param int $skuId
  289. * @param int $count
  290. * @throws NotFoundHttpException
  291. * @throws ServerErrorHttpException
  292. * 创建订单商品
  293. */
  294. private function addGoods($id, $goodsId, $skuId, $count)
  295. {
  296. $goods = Goods::findOne($goodsId);
  297. if (!$goods) {
  298. throw new NotFoundHttpException('商品未找到');
  299. }
  300. $orderGoods = new OrderGoods();
  301. $orderGoods->order_id = $id;
  302. $orderGoods->goods_id = $goodsId;
  303. $orderGoods->sku_id = $skuId ?: 0;
  304. $orderGoods->sku_value = Helper::skuValue($skuId);
  305. $orderGoods->goods_count = $count;
  306. $orderGoods->goods_img = $goods->image;
  307. $orderGoods->goods_name = $goods->name;
  308. $orderGoods->price = Helper::countPrice($goodsId, $skuId);
  309. if (!$orderGoods->save()) {
  310. throw new ServerErrorHttpException('服务器添加订单商品失败');
  311. }
  312. }
  313. /**
  314. * @return array|Order|null
  315. * 获取订单
  316. */
  317. private function findOrder()
  318. {
  319. $id = Yii::$app->request->getQueryParam('id');
  320. return Order::find()
  321. ->where(['id' => $id])
  322. ->andWhere(['user_id' => Yii::$app->user->getId()])
  323. ->one();
  324. }
  325. /**
  326. * @param $id
  327. * @return array|ActiveRecord[]|OrderGoods[]
  328. */
  329. private function findOrderGoods($id)
  330. {
  331. return OrderGoods::find()
  332. ->where(['order_id' => $id])
  333. ->all();
  334. }
  335. }