Order.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. <?php
  2. namespace addons\StarChain\common\models;
  3. use addons\StarChain\common\enums\StarChainOrderEnum;
  4. use common\models\order\OrderDetail;
  5. use common\models\order\OrderExpress;
  6. use Yii;
  7. use yii\helpers\Json;
  8. /**
  9. * This is the model class for table "{{%addons_star_chain_order}}".
  10. *
  11. * @property int $id
  12. * @property int|null $mall_id
  13. * @property int|null $user_id
  14. * @property int|null $order_id 商城订单ID
  15. * @property string|null $order_no 商城订单编号
  16. * @property string|null $sku_id sku_id
  17. * @property string|null $spu_id spu_id
  18. * @property int|null $num 下单数量
  19. * @property string|null $chain_order_sn 供应链端订单编号
  20. * @property string|null $chain_batch_order_sn 返回订单批次号batchOrderSn
  21. * @property float|null $chain_total_amount 订单总金额
  22. * @property float|null $chain_pay_amount 应付总金额
  23. * @property int|null $chain_order_status 10为已提交待付款,20为已付款待发货,30为已发货待收货,40为确认收货交易成功,50、60为已取消,70、80、90、100为已关闭
  24. * @property string|null $chain_deliver_list 物流
  25. * @property string|null $dot 下单请求数据
  26. * @property string|null $error 下单错误信息
  27. * @property int|null $status 0 未推送 1 下单成功 -1 下单失败
  28. * @property int|null $updated_at
  29. * @property int|null $created_at
  30. * @property array $items
  31. */
  32. class Order extends BaseModel
  33. {
  34. /**
  35. * {@inheritdoc}
  36. */
  37. public static function tableName()
  38. {
  39. return '{{%addons_star_chain_order}}';
  40. }
  41. /**
  42. * {@inheritdoc}
  43. */
  44. public function rules()
  45. {
  46. return [
  47. [['mall_id', 'user_id', 'order_id', 'num', 'chain_order_status', 'status', 'updated_at', 'created_at'], 'integer'],
  48. [['chain_total_amount', 'chain_pay_amount'], 'number'],
  49. [['chain_deliver_list', 'dot'], 'string'],
  50. [['order_no'], 'string', 'max' => 32],
  51. [['sku_id', 'spu_id', 'chain_order_sn', 'chain_batch_order_sn'], 'string', 'max' => 64],
  52. [['error'], 'string', 'max' => 255],
  53. ];
  54. }
  55. /**
  56. * {@inheritdoc}
  57. */
  58. public function attributeLabels()
  59. {
  60. return [
  61. 'id' => 'ID',
  62. 'mall_id' => 'Mall ID',
  63. 'user_id' => 'User ID',
  64. 'order_id' => 'Order ID',
  65. 'order_no' => 'Order No',
  66. 'sku_id' => 'Sku ID',
  67. 'spu_id' => 'Spu ID',
  68. 'num' => 'Num',
  69. 'chain_order_sn' => 'Chain Order Sn',
  70. 'chain_batch_order_sn' => 'Chain Batch Order Sn',
  71. 'chain_total_amount' => 'Chain Total Amount',
  72. 'chain_pay_amount' => 'Chain Pay Amount',
  73. 'chain_order_status' => 'Chain Order Status',
  74. 'chain_deliver_list' => 'Chain Deliver List',
  75. 'dot' => 'Dot',
  76. 'error' => 'Error',
  77. 'status' => 'Status',
  78. 'updated_at' => 'Updated At',
  79. 'created_at' => 'Created At',
  80. ];
  81. }
  82. /**
  83. * 获取商品详情
  84. *
  85. * @return ActiveQueryInterface
  86. */
  87. public function getGoods()
  88. {
  89. return $this->hasOne(Goods::class, ['spu_id' => 'spu_id']);
  90. }
  91. /**
  92. * 获取订单详情
  93. *
  94. * @return ActiveQueryInterface
  95. */
  96. public function getDetail()
  97. {
  98. return $this->hasOne(OrderDetail::class, ['order_id' => 'order_id']);
  99. }
  100. /**
  101. * 获取订单详情列表
  102. *
  103. * @return ActiveQueryInterface
  104. */
  105. public function getDetails()
  106. {
  107. return $this->hasMany(OrderDetail::class, ['order_id' => 'order_id']);
  108. }
  109. /**
  110. * 获取订单信息
  111. *
  112. * @return ActiveQueryInterface
  113. */
  114. public function getOrder()
  115. {
  116. return $this->hasOne(MallOrder::class, ['id' => 'order_id']);
  117. }
  118. /**
  119. * @return ActiveQueryInterface
  120. */
  121. public function getItem()
  122. {
  123. return $this->hasOne(OrderItem::class, ['order_id' => 'id']);
  124. }
  125. /**
  126. * @return ActiveQueryInterface the relational query object.
  127. */
  128. public function getItems()
  129. {
  130. return $this->hasMany(OrderItem::class, ['order_id' => 'id']);
  131. }
  132. /**
  133. * 新增订单
  134. *
  135. * @param array $data
  136. * @return boolean|Order
  137. */
  138. public static function addOrder($data)
  139. {
  140. $model = new self();
  141. if ($model->load($data, '') && $model->save()) {
  142. return $model;
  143. }
  144. return false;
  145. }
  146. /**
  147. * 创建订单
  148. *
  149. * @param MallOrder $order
  150. * @param array $dto
  151. * @param integer $status
  152. * @return boolean|Order
  153. * @throws Exception
  154. */
  155. public static function createOrder(MallOrder $order, array $dto, int $status = 0)
  156. {
  157. $model = new self();
  158. $model->mall_id = $order->mall_id;
  159. $model->user_id = $order->user_id;
  160. $model->order_id = $order->id;
  161. $model->order_no = $order->order_no;
  162. $model->sku_id = ''; // 使用item表 当前字段已遗弃
  163. $model->spu_id = ''; // 使用item表 当前字段已遗弃
  164. $model->num = 0; // 使用item表 当前字段已遗弃
  165. $model->dot = Json::encode($dto);
  166. $model->status = $status;
  167. if (!$model->save()) throw new \Exception('Order::createOrder 创建订单失败');
  168. // 添加子订单
  169. OrderItem::createOrderItem($model, $dto['goodsList']);
  170. return $model;
  171. }
  172. /**
  173. * 订单成功
  174. *
  175. * @param array $data
  176. * @return boolean
  177. */
  178. public function orderSuccess(array $data)
  179. {
  180. $first = reset($data);
  181. $this->chain_batch_order_sn = $first['batchOrderSn'];
  182. $this->chain_total_amount = $first['totalAmount'];
  183. $this->chain_pay_amount = $first['payAmount'];
  184. $this->chain_order_status = $first['orderStatus'];
  185. $this->status = 1;
  186. // 子订单完成
  187. OrderItem::editOrderItem($this->id, $data);
  188. return $this->save();
  189. }
  190. /**
  191. * 订单失败
  192. *
  193. * @param string $error
  194. * @return boolean
  195. */
  196. public function orderError($error)
  197. {
  198. $this->status = -1;
  199. $this->error = $error;
  200. return $this->save();
  201. }
  202. /**
  203. * 订单发货
  204. *
  205. * @return void
  206. */
  207. public function delivery($order_data)
  208. {
  209. $this->chain_deliver_list = Json::encode($order_data['deliverList']);
  210. $this->chain_order_status = StarChainOrderEnum::STATUS_30;
  211. $this->updated_at = time();
  212. $this->save();
  213. $params = $this->_getExpressParams(current(($order_data['deliverList'])));
  214. if (OrderExpress::delivery($params) === false) {
  215. throw new \Exception(
  216. sprintf('OrderExpress::delivery发货失败, params:%s msg: %s', json_encode($params), OrderExpress::getStaticError())
  217. );
  218. }
  219. }
  220. /**
  221. * 通过消息推送数据进行发货
  222. *
  223. * @param string $delivery_sn 消息推送过来的物流单号
  224. * @param string $delivery_corp_sn 消息推送过来的物流公司编号
  225. * @param array $sku_ids 消息推送过来的发货的商品id
  226. * @return void
  227. */
  228. public function deliveryByMsg(
  229. string $delivery_sn, string $delivery_corp_sn, array $sku_ids
  230. )
  231. {
  232. // 主订单设置发货状态
  233. $params = $this->_getExpressParamsByMsg($delivery_sn, $delivery_corp_sn, $sku_ids);
  234. $this->chain_order_status = StarChainOrderEnum::STATUS_30;
  235. $this->updated_at = time();
  236. $this->save();
  237. if (OrderExpress::delivery($params) === false) {
  238. Yii::$app->custom->logs(
  239. 'OrderExpress::deliveryByMsg发货失败',
  240. [
  241. 'params' => $params,
  242. 'msg' => OrderExpress::getStaticError(),
  243. ]
  244. );
  245. throw new \Exception(
  246. sprintf('OrderExpress::deliveryByMsg发货失败, params:%s msg: %s', json_encode($params), OrderExpress::getStaticError())
  247. );
  248. }
  249. }
  250. /**
  251. * 获取发货信息
  252. *
  253. * @param array $logistic
  254. * @return array
  255. */
  256. private function _getExpressParams($logistic)
  257. {
  258. $express = Express::getExpressByCode($logistic['deliveryCorpSn']);
  259. $express_no = $logistic['deliverySn'] ?? '';
  260. $params['id'] = $this->order_id;
  261. foreach ($this->details as $detail) {
  262. $params['order_detail_ids'][] = $detail->id;
  263. }
  264. $params['shipping_type'] = 0;
  265. if (!empty($express)) {
  266. $params['shipping_type'] = 1;
  267. $params['express_id'] = $express->express_id;
  268. $params['express_name'] = $express->name;
  269. $params['express_no'] = $express_no;
  270. }
  271. $params['mall_id'] = $this->mall_id;
  272. $params['mch_id'] = 0;
  273. $params['operator_id'] = 0;
  274. $params['operator_name'] = '怡亚通供应方';
  275. return $params;
  276. }
  277. /**
  278. * 获取发货信息(通过消息推送)
  279. *
  280. * @param string $delivery_sn
  281. * @param string $delivery_corp_sn
  282. * @return array
  283. */
  284. private function _getExpressParamsByMsg(string $delivery_sn, string $delivery_corp_sn, array $sku_ids)
  285. {
  286. $express = Express::getExpressByCode($delivery_corp_sn);
  287. $express_no = $delivery_sn;
  288. $params['id'] = $this->order_id;
  289. $params['order_detail_ids'] = $this->getDetailIdsBySkuIds($sku_ids);
  290. $params['shipping_type'] = 0;
  291. if (!empty($express)) {
  292. $params['shipping_type'] = 1;
  293. $params['express_id'] = $express->express_id;
  294. $params['express_name'] = $express->name;
  295. $params['express_no'] = $express_no;
  296. }
  297. $params['mall_id'] = $this->mall_id;
  298. $params['mch_id'] = 0;
  299. $params['operator_id'] = 0;
  300. $params['operator_name'] = '怡亚通供应方';
  301. return $params;
  302. }
  303. /**
  304. * 通过sku_id获取订单详情id
  305. *
  306. * @param array $sku_ids
  307. * @return array
  308. */
  309. public function getDetailIdsBySkuIds(array $sku_ids)
  310. {
  311. return OrderItem::getDetailIdsBySkuIds($this->id, $sku_ids);
  312. }
  313. /**
  314. * 查询未发货的订单
  315. *
  316. * @param int $mall_id
  317. * @param string|array $order_sn
  318. * @return array
  319. */
  320. public static function getUnDeliveryOrderByOrderSn($mall_id, $order_sn)
  321. {
  322. return static::find()->where(
  323. ['mall_id' => $mall_id, 'chain_order_status' => StarChainOrderEnum::STATUS_20, 'chain_order_sn' => $order_sn]
  324. )->all();
  325. }
  326. /**
  327. * 通过订单号查询订单
  328. *
  329. * @param integer $mall_id
  330. * @param string $order_sn
  331. * @return static|null
  332. */
  333. public static function getOrderByOrderSn(int $mall_id, string $order_sn)
  334. {
  335. return static::find()->where(
  336. ['mall_id' => $mall_id, 'chain_order_sn' => $order_sn]
  337. )->one();
  338. }
  339. /**
  340. * @param integer $mall_id
  341. * @param integer $order_id
  342. * @param array $fields
  343. * @return self|null
  344. */
  345. public static function getOrderAndItemByOrderId(
  346. int $mall_id,
  347. int $order_id,
  348. $fields = ['id', 'chain_order_sn', 'sku_id', 'chain_deliver_list']
  349. )
  350. {
  351. return static::find()
  352. ->where(['order_id' => $order_id, 'mall_id' => $mall_id])
  353. ->with(['items'])
  354. ->select($fields)
  355. ->one();
  356. }
  357. /**
  358. * @param integer $mall_id
  359. * @param integer $order_id
  360. * @param array $fields
  361. * @return self|null
  362. */
  363. public static function getOrderAndItemById(
  364. int $mall_id,
  365. int $id
  366. )
  367. {
  368. return static::find()
  369. ->where(['id' => $id, 'mall_id' => $mall_id])
  370. ->with(['items'])
  371. ->one();
  372. }
  373. /**
  374. * 迁移数据维护
  375. *
  376. * @return void
  377. */
  378. public static function maintainData()
  379. {
  380. $order_list = static::find()
  381. ->select('id, order_id, mall_id, sku_id, spu_id, num, created_at')
  382. ->with([
  383. 'detail' => function ($query) {
  384. $query->select('id, order_id, mall_id');
  385. },
  386. ])
  387. ->andWhere(['>', 'sku_id', 0])
  388. ->andWhere(['>', 'spu_id', 0])
  389. ->andWhere(['>', 'num', 0])
  390. ->all();
  391. $data = array_map(function ($item) {
  392. return [
  393. 'order_id' => $item->id,
  394. 'mall_id' => $item->mall_id,
  395. 'sku_id' => $item->sku_id,
  396. 'spu_id' => $item->spu_id,
  397. 'num' => $item->num,
  398. 'mall_order_id' => $item->order_id,
  399. 'order_detail_id' => $item->detail->id,
  400. 'updated_at' => $item->created_at,
  401. 'created_at' => $item->created_at,
  402. ];
  403. }, $order_list);
  404. OrderItem::batchInsert($data, false);
  405. }
  406. }