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.

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