OrderCallbackService.php 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  1. <?php
  2. namespace addons\WechatVideoShop\common\service;
  3. use addons\WechatVideoShop\common\enums\WechatVideoShopDeliveryTypeEnums;
  4. use addons\WechatVideoShop\common\enums\WechatVideoShopEnums;
  5. use addons\WechatVideoShop\common\enums\WechatVideoShopOrderUpdateEnums;
  6. use addons\WechatVideoShop\common\expand\sdk\weixin\src\model\order\OrderInfoModel;
  7. use addons\WechatVideoShop\common\expand\sdk\weixin\src\model\sharer\SharerOrderListModel;
  8. use addons\WechatVideoShop\common\expand\sdk\weixin\src\request\order\OrderInfoRequest;
  9. use addons\WechatVideoShop\common\expand\sdk\weixin\src\request\sharer\SharerOrderListRequest;
  10. use addons\WechatVideoShop\common\helper\WechatRequestHelper;
  11. use addons\WechatVideoShop\common\logic\WeChatCallbackLogic;
  12. use addons\WechatVideoShop\common\models\WechatVideoShopExpressCompany;
  13. use addons\WechatVideoShop\common\models\WechatVideoShopOrder;
  14. use addons\WechatVideoShop\common\models\WechatVideoShopRegion;
  15. use common\enums\AppEnum;
  16. use common\enums\OrderStatusEnum;
  17. use common\enums\StatusEnum;
  18. use common\helpers\FormatHelper;
  19. use common\logic\order\OrderFormLogic;
  20. use common\logic\order\OrderInitDataLogic;
  21. use common\logic\order\OrderMarketingLogic;
  22. use common\models\cart\Cart;
  23. use common\models\goods\GoodsAttr;
  24. use common\models\order\Order;
  25. use common\models\order\OrderDetail;
  26. use common\models\order\OrderExpress;
  27. use common\models\user\User;
  28. use common\models\user\UserAddress;
  29. use common\models\user\UserInfo;
  30. use yii\db\Exception;
  31. use yii\helpers\Json;
  32. class OrderCallbackService extends AbstractService
  33. {
  34. const OPERATOR_NAME = '微信视频小店';
  35. /**
  36. * 创建订单
  37. * @param array $event
  38. * @param string $event_key
  39. * @return void
  40. * @throws \Exception
  41. */
  42. public function create(array $event, string $event_key = 'order_info')
  43. {
  44. // 创建本地订单
  45. $resp = $this->getOrderInfo($event[$event_key]['order_id']);
  46. \Yii::error(__CLASS__ . " resp-> " . var_export($resp, true));
  47. // 判断是否已经记录当前订单
  48. if (WechatVideoShopOrder::getOne([
  49. ['third_order_id' => $event[$event_key]['order_id']]
  50. ])) return true;
  51. // 本地订单已经存在那么就不在处理
  52. // 如果有分销员,那么就需要判断是否作为其下级,以及判断当前用户是否存在,不存在则需要注册
  53. // 创建订单
  54. if (!empty($resp['order'])) {
  55. $w_order = $resp['order'];
  56. $w_order_openid = $w_order['openid'] ?? ''; // 买家身份标识
  57. $w_order_unionid = $w_order['unionid'] ?? ''; // 买家在开放平台的唯一标识符,若当前视频号小店已绑定到微信开放平台帐号下会返回,详见UnionID 机制说明
  58. $w_order_id = $w_order['order_id']; // 订单号
  59. $w_order_status = $w_order['status']; // 订单状态,枚举值见OrderStatus
  60. $w_order_detail = $w_order['order_detail']; // 订单详细数据信息
  61. $w_order_aftersale_detail = $w_order['aftersale_detail']; // 售后信息
  62. $w_goods = $w_order_detail['product_infos'];
  63. $w_pay_info = $w_order_detail['pay_info'] ?? [];
  64. $w_price_info = $w_order_detail['price_info'] ?? [];
  65. $w_delivery_info = $w_order_detail['delivery_info'] ?? [];
  66. $w_address_info = $w_delivery_info['address_info'] ?? [];
  67. $w_delivery_product_info = $w_delivery_info['delivery_product_info'] ?? [];
  68. $w_coupon_info = $w_order_detail['coupon_info'] ?? [];
  69. $w_ext_info = $w_order_detail['ext_info'] ?? [];
  70. $w_sharer_info = $w_order_detail['sharer_info'] ?? [];
  71. $w_settle_info = $w_order_detail['settle_info'] ?? [];
  72. $w_aftersale_order_list = $w_order_aftersale_detail['aftersale_order_list'] ?? [];
  73. $w_on_aftersale_order_cnt= $w_order_aftersale_detail['on_aftersale_order_cnt'] ?? 0;
  74. // 查找用户 - 如果没有用户那么就需要注册用户
  75. // 如果没有取到分销员,那么就放入延迟队列进行处理
  76. // 因为微信小店下架了分销,所以订单不需要对分销员进行操作
  77. /*if (empty($w_sharer_info) && !empty(WechatVideoShopEnums::CUSTOMER_DELAY[$this->customer_num])) {
  78. // 这里需要入列
  79. \Yii::$app->services->rabbitMq->delay(WechatVideoShopEnums::CUSTOMER_DELAY[$this->customer_num],
  80. ['mall_id' => $this->mall_id, 'shop_id' => $this->shop_id,
  81. 'customer_num' => $this->customer_num + 1, 'data' => $event], WeChatCallbackLogic::class, 'channels_ec_order_new');
  82. return;
  83. }*/
  84. $t = \Yii::$app->db->beginTransaction();
  85. try {
  86. // 获取用户
  87. [$userInfo, $share_user_id] = $this->getUser($w_order_unionid, $w_order_openid, $w_order, $w_sharer_info);
  88. // 收货地址
  89. $addr = $this->getAddress($w_address_info, $userInfo->user_id);
  90. // 购物车
  91. $sku_ids = $this->setCart($w_goods, $userInfo->user_id);
  92. // 生成平台订单 - 这里应该是独立的事务
  93. $order = $this->getOrder($userInfo->user_id, [
  94. 'data' => [
  95. 'address_id' => $addr->id,
  96. 'attr_ids' => $sku_ids
  97. ],
  98. 'type' => 'cart', // 走购物车
  99. ]);
  100. $order_ids = explode(",", $order['transaction']['order_ids']);
  101. $orders = Order::lists([
  102. 'where' => [
  103. ['id' => $order_ids]
  104. ]
  105. ]);
  106. // 设置为视频号订单
  107. Order::updateAll(['order_source' => WechatVideoShopEnums::ADDONS_NAME,
  108. 'marketing_type' => WechatVideoShopEnums::ADDONS_NAME], ['in', 'id', $order_ids]);
  109. $insert_order = [];
  110. foreach ($orders as $item) {
  111. $insert_order[] = [
  112. 'created_at' => time(),
  113. 'updated_at' => time(),
  114. 'mall_id' => $this->mall_id,
  115. 'user_id' => $userInfo->user_id,
  116. 'order_no' => $item['order_no'],
  117. 'content' => Json::encode($w_order),
  118. 'shop_id' => $this->shop_id,
  119. 'order_id' => $item['id'],
  120. 'third_order_id' => $w_order_id,
  121. 'third_order_status'=> $w_order_status,
  122. 'parent_id' => $share_user_id, // 没有分享人的时候不给分佣
  123. ];
  124. }
  125. if (!empty($insert_order)) { // 插入订单
  126. WechatVideoShopOrder::find()->createCommand()
  127. ->batchInsert(WechatVideoShopOrder::tableName(),
  128. array_keys($insert_order[0]), $insert_order)->execute();
  129. }
  130. // 插件订单
  131. // $wechatOrderModel = new WechatVideoShopOrder();
  132. // $wechatOrderModel->mall_id = $this->mall_id;
  133. // $wechatOrderModel->user_id = $userInfo->user_id;
  134. // $wechatOrderModel->order_id = $order['transaction']['order_ids']; // 有可能会有多个
  135. // $wechatOrderModel->order_no = $order_no;
  136. // $wechatOrderModel->third_order_id = $w_order_id;
  137. // $wechatOrderModel->content = $w_order;
  138. // $wechatOrderModel->third_order_status = $w_order_status;
  139. // $wechatOrderModel->shop_id = $this->shop_id;
  140. // if (!$wechatOrderModel->save()) throw new \Exception($wechatOrderModel->getErrorMessage());
  141. $t->commit();
  142. } catch (\Exception $e) {
  143. $t->rollBack();
  144. \Yii::error(FormatHelper::exception($e, __METHOD__));
  145. throw new \Exception($e->getMessage());
  146. }
  147. }
  148. }
  149. /**
  150. * 订单取消
  151. * @param array $event
  152. * @param string $event_key
  153. * @return void
  154. * @throws \Exception
  155. */
  156. public function cancel(array $event, string $event_key = 'order_info')
  157. {
  158. $orders = $this->getByThirdOrderId($event[$event_key]['order_id'], $event, 'channels_ec_order_cancel');
  159. if (is_string($orders)) {
  160. return true;
  161. }
  162. foreach ($orders as $order) {
  163. // 取消订单
  164. $params['mall_id'] = $this->mall_id;
  165. $params['user_id'] = $order['user_id'];
  166. $params['operator_id'] = 0;
  167. $params['operator_name'] = self::OPERATOR_NAME;
  168. $params['id'] = $order['order_id'];
  169. $params['order_status'] = OrderStatusEnum::REPEAL;
  170. $res = Order::close($params);
  171. if (!$res) throw new \Exception(Order::getStaticError());
  172. }
  173. }
  174. /**
  175. * 订单支付
  176. * @param array $event
  177. * @param string $event_key
  178. * @return void
  179. * @throws Exception
  180. * @throws \Exception
  181. */
  182. public function paid(array $event, string $event_key = 'order_info')
  183. {
  184. $orders = $this->getByThirdOrderId($event[$event_key]['order_id'], $event, 'channels_ec_order_pay');
  185. if (is_string($orders)) {
  186. return true;
  187. }
  188. foreach ($orders as $order) {
  189. $res = Order::pay($order['order'], 1, ''); // 默认为微信支付
  190. if($res === false) throw new Exception(Order::getStaticError());
  191. // 本地订单也需要修改为支付状态
  192. }
  193. $order_ids = array_column($orders, 'id');
  194. if (!empty($order_ids)) {
  195. WechatVideoShopOrder::updateAll(['is_pay' => StatusEnum::ENABLED], ['and', ['in', 'id', $order_ids]]);
  196. }
  197. }
  198. /**
  199. * 发货
  200. * @param array $event
  201. * @param string $event_key
  202. * @return void
  203. * @throws \Exception
  204. */
  205. public function ship(array $event, string $event_key = 'order_info')
  206. {
  207. $orders = $this->getByThirdOrderId($event[$event_key]['order_id'], $event, 'channels_ec_order_deliver');
  208. if (is_string($orders)) {
  209. return true;
  210. }
  211. $resp = $this->getOrderInfo($event[$event_key]['order_id']);
  212. if (empty($resp['order'])) throw new \Exception('订单获取失败');
  213. $delivery_product_info = $resp['order']['order_detail']['delivery_info']['delivery_product_info'][0] ?? [];
  214. if (empty($delivery_product_info)) throw new \Exception("发货记录不存在");
  215. $delivery_product_infos = $delivery_product_info['product_infos'] ?? [];
  216. foreach ($orders as $order) {
  217. $params['mall_id'] = $this->mall_id;
  218. $params['mch_id'] = 0;
  219. $params['operator_id'] = 0;
  220. $params['operator_name'] = self::OPERATOR_NAME;
  221. $params['id'] = $order['order_id'];
  222. $shipping_skus = array_column($delivery_product_infos, 'sku_id');
  223. $shipping_local_skus = array_column($resp['order']['order_detail']['product_infos'], 'out_sku_id', 'sku_id');
  224. switch ($delivery_product_info['']) {
  225. case WechatVideoShopDeliveryTypeEnums::DELIVERY_TYPE_SELF_SHIP:
  226. case WechatVideoShopDeliveryTypeEnums::DELIVERY_TYPE_SIGN_CONTRACT:
  227. case WechatVideoShopDeliveryTypeEnums::DELIVERY_TYPE_ONLINE:
  228. $params['shipping_type'] = StatusEnum::ENABLED; // 物流
  229. break;
  230. case WechatVideoShopDeliveryTypeEnums::DELIVERY_TYPE_VIRTUAL_SHIP:
  231. $params['shipping_type'] = StatusEnum::DISABLED; // 无需物流
  232. break;
  233. }
  234. // 取出快递公司
  235. $expressCompany = WechatVideoShopExpressCompany::getOne([
  236. ['delivery_id' => $delivery_product_info['delivery_id']]
  237. ]);
  238. // 默认为其他快递公司
  239. $express_id = 10000;
  240. $express_name = '其他';
  241. if (!empty($expressCompany)) {
  242. $express_id = $expressCompany->company_id;
  243. $express_name = $expressCompany->delivery_name;
  244. }
  245. $order_detail_ids = OrderDetail::find()->where(['mall_id' => $this->mall_id])
  246. ->andWhere(['order_id' => $params['id']])
  247. ->andWhere(['goods_attr_id' => $shipping_local_skus])->select('id')->column();
  248. $params['order_detail_ids'] = $order_detail_ids;
  249. $params['express_id'] = $express_id;
  250. $params['express_name'] = $express_name;
  251. $params['customer_name'] = '';
  252. $params['express_no'] = $delivery_product_info['waybill_id'];
  253. $params['memo'] = '';
  254. if (empty($params['shipping_change'])) {
  255. $res = OrderExpress::delivery($params); // 发货
  256. } else {
  257. $res = OrderExpress::shippingChange($params);// 修改物流
  258. }
  259. if (!$res) throw new \Exception(OrderExpress::getStaticError());
  260. }
  261. }
  262. /**
  263. * 签收
  264. * @param array $event
  265. * @param string $event_key
  266. * @return void
  267. * @throws \Exception
  268. */
  269. public function sing(array $event, string $event_key = 'order_info')
  270. {
  271. $orders = $this->getByThirdOrderId($event[$event_key]['order_id'], $event, 'channels_ec_order_confirm');
  272. if (is_string($orders)) {
  273. return true;
  274. }
  275. foreach ($orders as $order) {
  276. $params['mall_id'] = $this->mall_id;
  277. $params['user_id'] = $order['user_id'];
  278. $params['operator_id'] = 0;
  279. $params['operator_name'] = self::OPERATOR_NAME;
  280. $params['id'] = $order['order_id'];
  281. $res = Order::takeDelivery($params);
  282. if (!$res) throw new \Exception(Order::getStaticError());
  283. }
  284. }
  285. /**
  286. * 结算
  287. * @param array $event
  288. * @param string $event_key
  289. * @return void
  290. * @throws \Exception
  291. */
  292. public function settlement(array $event, string $event_key = 'order_info')
  293. {
  294. $orders = $this->getByThirdOrderId($event[$event_key]['order_id'], $event, 'channels_ec_order_settle');
  295. if (is_string($orders)) {
  296. return true;
  297. }
  298. WechatVideoShopOrder::updateAll(['is_settle' => StatusEnum::ENABLED, 'settle_at' => time()],
  299. ['and', ['third_order_id' => $event[$event_key]['order_id']],
  300. ['is_pay' => OrderStatusEnum::PAY], ['in', 'order_status', [OrderStatusEnum::SING, OrderStatusEnum::ACCOMPLISH]]]);
  301. }
  302. /**
  303. * 其他信息更新
  304. * @param array $event
  305. * @param string $event_key
  306. * @return void
  307. * @throws \Exception
  308. */
  309. public function update(array $event, string $event_key = 'order_info')
  310. {
  311. $orders = $this->getByThirdOrderId($event[$event_key]['order_id'], $event, 'channels_ec_order_ext_info_update');
  312. if (is_string($orders)) {
  313. return true;
  314. }
  315. $resp = $this->getOrderInfo($event[$event_key]['order_id']);
  316. switch ($event[$event_key]['type']) {
  317. case WechatVideoShopOrderUpdateEnums::Order_UPDATE_TYPE_COMMISSION: // 联盟佣金
  318. break;
  319. case WechatVideoShopOrderUpdateEnums::Order_UPDATE_TYPE_ADDRESS: // 地址修改
  320. // 收货地址
  321. foreach ($orders as $order) {
  322. $w_order_detail = $resp['order']['order_detail']; // 订单详细数据信息
  323. $w_delivery_info = $w_order_detail['delivery_info'] ?? [];
  324. $w_address_info = $w_delivery_info['address_info'] ?? [];
  325. $addr = $this->getAddress($w_address_info, $order['user_id']);
  326. $params['receiver_name'] = $addr->name;
  327. $params['mobile'] = $addr->mobile;
  328. $params['province'] = $addr->province;
  329. $params['city'] = $addr->city;
  330. $params['area'] = $addr->district;
  331. $params['address'] = $addr->detail;
  332. $params['region_name'] = "{$addr->province} {$addr->city} {$addr->district}";
  333. $params['mall_id'] = $this->mall_id;
  334. $params['mch_id'] = 0;
  335. $params['operator_id'] = 0;
  336. $params['operator_name'] = self::OPERATOR_NAME;
  337. $params['id'] = $order['order_id'];
  338. if (!Order::changeAddress($params)) throw new \Exception(Order::getStaticError());
  339. }
  340. break;
  341. case WechatVideoShopOrderUpdateEnums::Order_UPDATE_TYPE_SELLER_REMARK: // 商家备注
  342. foreach ($orders as $order) {
  343. $params['mall_id'] = $this->mall_id;
  344. $params['mch_id'] = 0;
  345. $params['operator_id'] = 0;
  346. $params['operator_name'] = self::OPERATOR_NAME;
  347. $params['seller_remark'] = $resp['order']['ext_info']['merchant_notes'] ?? ''; // 商家备注
  348. $params['remark'] = $resp['order']['ext_info']['customer_notes'] ?? ''; // 买家备注
  349. $params['id'] = $order['order_id'];
  350. if (!Order::remark($params)) throw new \Exception(Order::getStaticError());
  351. }
  352. break;
  353. case WechatVideoShopOrderUpdateEnums::Order_UPDATE_TYPE_VIRTUAL_NUMBER: // 虚拟号码
  354. break;
  355. }
  356. }
  357. /**
  358. * 获取多个订单
  359. * @param $third_order_id
  360. * @param $event
  361. * @param $method
  362. * @return mixed
  363. * @throws \Exception
  364. */
  365. protected function getByThirdOrderId($third_order_id, $event, $method)
  366. {
  367. $orders = WechatVideoShopOrder::lists([
  368. 'where' => [
  369. ['third_order_id' => $third_order_id]
  370. ],
  371. 'with' => ['order' => function($query) {
  372. $query->with(['detail']);
  373. }, 'user' => function($query) {
  374. $query->select('id, nickname');
  375. }]
  376. ]);
  377. // $orders = WechatVideoShopOrder::getOne([
  378. // ['third_order_id' => $third_order_id]
  379. // ], true, ['order' => function($query) {
  380. // $query->with(['detail']);
  381. // }, 'user' => function($query) {
  382. // $query->select('id, nickname');
  383. // }]);
  384. if (empty($orders)) {
  385. // 延时队列
  386. // 如果没有取到分销员,那么就放入延迟队列进行处理
  387. $is_delay = '未延时';
  388. $sec = WechatVideoShopEnums::CUSTOMER_DELAY[$this->customer_num] ?? 0;
  389. if (!empty($sec)) {
  390. // 这里需要入列
  391. \Yii::$app->services->rabbitMq->delay($sec,
  392. ['mall_id' => $this->mall_id, 'shop_id' => $this->shop_id,
  393. 'customer_num' => $this->customer_num + 1, 'data' => $event], WeChatCallbackLogic::class, $method);
  394. $is_delay = "延时 $sec 秒, 操作方法为: $method";
  395. }
  396. // throw new \Exception("记录不存在, $is_delay");
  397. \Yii::error(__METHOD__ . " --> 记录不存在, $is_delay -> $third_order_id");
  398. return "";
  399. }
  400. return $orders;
  401. }
  402. /**
  403. * 通过第三方订单编号获取订单信息
  404. * @param $third_order_id
  405. * @return mixed|null
  406. * @throws \Exception
  407. */
  408. protected function findByThirdOrderId($third_order_id)
  409. {
  410. $order = WechatVideoShopOrder::getOne([
  411. ['third_order_id' => $third_order_id]
  412. ], true, ['order' => function($query) {
  413. $query->with(['detail']);
  414. }, 'user' => function($query) {
  415. $query->select('id, nickname');
  416. }]);
  417. if (empty($order)) throw new \Exception("记录不存在");
  418. return $order;
  419. }
  420. /**
  421. * @param $w_order_unionid
  422. * @param $w_order_openid
  423. * @param array $order
  424. * @param array $share_info
  425. * @return array
  426. * @throws Exception
  427. * @throws \Exception
  428. */
  429. protected function getUser($w_order_unionid, $w_order_openid, array $order, array $share_info = [])
  430. {
  431. $ui_where = [
  432. ['mall_id' => $this->mall_id],
  433. ['platform' => User::PLATFORM_WECHAT_VIDEO_SHOP],
  434. ];
  435. $is_find_by_unionid = false;
  436. if (!empty($w_order_unionid)) {
  437. $is_find_by_unionid = true;
  438. $ui_where[] = ['unionid' => $w_order_unionid];
  439. } else {
  440. $ui_where[] = ['openid' => $w_order_openid];
  441. }
  442. $userInfo = UserInfo::getOne($ui_where);
  443. // 判断当前用户
  444. // 判断当前用户之前是否有订单 - 且是否有上级,如果有的话那么就直接将奖励分给旧的分销员
  445. if (!empty($userInfo)) {
  446. $o_Order = WechatVideoShopOrder::getOne([
  447. ['user_id' => $userInfo->user_id],
  448. ['>', 'parent_id', StatusEnum::DISABLED]
  449. ], false, [], 'id asc', 'parent_id');
  450. if (!empty($o_Order) && !empty($o_Order->parent_id)) {
  451. $sUserInfo = UserInfo::getOne([
  452. ['mall_id' => $this->mall_id],
  453. ['user_id' => $o_Order->parent_id],
  454. ]);
  455. }
  456. }
  457. /* 因为微信小店下架了分销,所以去除分享员信息
  458. if (!empty($share_info) && empty($sUserInfo)) { // 分销员不为空并且之前的分销员为空
  459. // 不能用OR,因为如果当前用户有注册过那么当前的openid就写不进去了
  460. $sUserInfo = $this->getShareUserInfo($share_info);
  461. if (empty($sUserInfo)) { // 如果分销员不存在,那么就为其注册一个用户 - 分销员注册
  462. $sUser = User::setDataByNoTransaction([
  463. 'mall_id' => $this->mall_id,
  464. 'parent_id' => StatusEnum::DELETE,
  465. 'nickname' => '微信视频小店用户',
  466. 'source' => User::SOURCE_WECHAT_VIDEO_SHOP,
  467. 'platform' => User::TYPE_WECHAT_VIDEO_SHOP,
  468. ]);
  469. if (!$sUser) throw new \Exception(User::getStaticError());
  470. // 需要创建用户?
  471. $sUserInfo = UserInfo::setData([
  472. 'openid' => $share_info['sharer_openid'],
  473. 'unionid' => $share_info['sharer_unionid'],
  474. 'platform' => User::PLATFORM_WECHAT_VIDEO_SHOP,
  475. 'mall_id' => $this->mall_id,
  476. 'user_id' => $sUser->id
  477. ]);
  478. }
  479. }*/
  480. if (empty($userInfo)) {
  481. // 注册用户id
  482. $user = User::setDataByNoTransaction([
  483. 'mall_id' => $this->mall_id,
  484. 'parent_id' => !empty($sUserInfo) ? $sUserInfo->user_id : StatusEnum::DELETE,
  485. 'nickname' => '微信视频小店用户',
  486. 'source' => User::SOURCE_WECHAT_VIDEO_SHOP,
  487. 'platform' => User::TYPE_WECHAT_VIDEO_SHOP,
  488. ]);
  489. if (!$user) throw new \Exception(User::getStaticError());
  490. // 需要注册
  491. $userInfo = UserInfo::setData([
  492. 'openid' => $w_order_openid,
  493. 'unionid' => $w_order_unionid,
  494. 'platform' => User::PLATFORM_WECHAT_VIDEO_SHOP,
  495. 'mall_id' => $this->mall_id,
  496. 'user_id' => $user->id
  497. ]);
  498. if (!$userInfo) throw new \Exception(UserInfo::getStaticError());
  499. } else {
  500. // 如果使用的unionid取出来的用户数据那么就需要判断openid是否已经添加,如果没有添加那么就需要添加一行数据
  501. if ($is_find_by_unionid && empty(UserInfo::getOne([
  502. ['mall_id' => $this->mall_id],
  503. ['platform' => User::PLATFORM_WECHAT_VIDEO_SHOP],
  504. ['openid' => $w_order_openid]
  505. ]))) { // 如果是通过unionid查询的,那么判断是否有openid的记录
  506. $userInfo = UserInfo::setData([
  507. 'openid' => $w_order_openid,
  508. 'unionid' => $w_order_unionid,
  509. 'platform' => User::PLATFORM_WECHAT_VIDEO_SHOP,
  510. 'mall_id' => $this->mall_id,
  511. 'user_id' => $userInfo->user_id
  512. ]);
  513. if (!$userInfo) throw new \Exception(UserInfo::getStaticError());
  514. }
  515. }
  516. return [$userInfo, !empty($sUserInfo) ? $sUserInfo->user_id : 0];
  517. }
  518. /**
  519. * 获取分享人ID
  520. * @param array $share_info
  521. * @return mixed|null
  522. * @throws \Exception
  523. */
  524. protected function getShareUserInfo(array $share_info)
  525. {
  526. $sui_where = [
  527. ['mall_id' => $this->mall_id],
  528. ];
  529. $is_find_by_unionid = false;
  530. if (!empty($share_info['sharer_unionid'])) {
  531. $is_find_by_unionid = true;
  532. $sui_where[] = ['unionid' => $share_info['sharer_unionid']];
  533. } else {
  534. $sui_where[] = ['openid' => $share_info['sharer_openid']];
  535. }
  536. $userInfo = UserInfo::getOne($sui_where);
  537. // 如果是通过unionid获取的那么就需要判断当前openid是否已经添加
  538. if ($is_find_by_unionid && !empty($userInfo) && empty(UserInfo::getOne([
  539. ['mall_id' => $this->mall_id],
  540. ['platform' => User::PLATFORM_WECHAT_VIDEO_SHOP],
  541. ['openid' => $share_info['sharer_openid']]
  542. ]))) {
  543. $userInfo = UserInfo::setData([
  544. 'openid' => $share_info['sharer_openid'],
  545. 'unionid' => $share_info['sharer_unionid'],
  546. 'platform' => User::PLATFORM_WECHAT_VIDEO_SHOP,
  547. 'mall_id' => $this->mall_id,
  548. 'user_id' => $userInfo->user_id
  549. ]);
  550. if (!$userInfo) throw new \Exception(UserInfo::getStaticError());
  551. }
  552. // 分销员用户信息
  553. return $userInfo;
  554. }
  555. /**
  556. * 创建平台订单
  557. * @param int $user_id
  558. * @param array $params
  559. * @return array
  560. * @throws \Exception
  561. */
  562. protected function getOrder(int $user_id, array $params)
  563. {
  564. $orderFormLogic = new OrderFormLogic();
  565. $form = $orderFormLogic->getDefaultform($this->mall_id, $user_id);
  566. $form->attributes = $params;
  567. $form['action'] = AppEnum::ACTION_CREATE;
  568. // 初始化订单数据
  569. $orderInitDataLogic = new OrderInitDataLogic();
  570. $form = $orderInitDataLogic->execute($form, $form->type);
  571. if ($form === false) throw new \Exception($orderInitDataLogic->getError());
  572. $orderMarketingLogic = new OrderMarketingLogic();
  573. $form = $orderMarketingLogic->run($form, true);
  574. if ($form === false) throw new \Exception($orderMarketingLogic->getError());
  575. $res = Order::createOrder($form);
  576. if ($res === false) throw new \Exception(Order::getStaticError());
  577. return $res;
  578. }
  579. /**
  580. * @param array $addr
  581. * @param int $user_id
  582. * @return mixed|null
  583. * @throws \Exception
  584. */
  585. protected function getAddress(array $addr, int $user_id)
  586. {
  587. // 取出数据
  588. $region = WechatVideoShopRegion::getOne([
  589. ['level' => 3],
  590. ['name' => $addr['county_name']],
  591. ['level_one_name' => $addr['province_name']],
  592. ['level_two_name' => $addr['city_name']],
  593. ]);
  594. if (empty($region)) throw new \Exception("地区 [{$addr['county_name']}] 不存在");
  595. $address = UserAddress::getOne([
  596. ['user_id' => $user_id],
  597. ['name' => $addr['user_name']],
  598. ['province_id' => $region->local_one_id],
  599. ['city_id' => $region->local_two_id],
  600. ['district_id' => $region->id],
  601. ['detail' => $addr['detail_info']],
  602. ['mobile' => $addr['tel_number']],
  603. ]);
  604. if (empty($address)) {
  605. $address = UserAddress::setData([
  606. 'user_id' => $user_id,
  607. 'name' => $addr['user_name'],
  608. 'province_id' => $region['local_one_id'],
  609. 'province' => $region['local_one_name'],
  610. 'city_id' => $region['local_two_id'],
  611. 'city' => $region['local_two_name'],
  612. 'district_id' => $region['id'],
  613. 'district' => $region['name'],
  614. 'mobile' => $addr['tel_number'],
  615. 'detail' => $addr['detail_info'],
  616. ]);
  617. if (!$address) throw new \Exception(UserAddress::getStaticError());
  618. }
  619. return $address;
  620. }
  621. /**
  622. * 加入购物车
  623. * @param array $goods
  624. * @param int $user_id
  625. * @return array
  626. * @throws \Exception
  627. */
  628. protected function setCart(array $goods, int $user_id)
  629. {
  630. $sku_ids = array_column($goods, 'out_sku_id');
  631. $goods_ids = GoodsAttr::lists([
  632. 'where' => [
  633. ['id' => $sku_ids]
  634. ],
  635. 'select' => 'id, goods_id',
  636. 'index' => 'id'
  637. ]);
  638. foreach ($goods as $good) {
  639. Cart::addCart([
  640. 'num' => $good['sku_cnt'],
  641. 'mch_id' => 0,
  642. 'mall_id' => $this->mall_id,
  643. 'user_id' => $user_id,
  644. 'attr_id' => $good['out_sku_id'],
  645. 'goods_id' => $goods_ids[$good['out_sku_id']],
  646. 'buy_limit_nums' => 0,
  647. 'buy_limit_total_num' => 0,
  648. ]);
  649. }
  650. return $sku_ids;
  651. }
  652. /**
  653. * 获取订单详情
  654. * @param $order_id
  655. * @return array
  656. * @throws \Exception
  657. */
  658. protected function getOrderInfo($order_id)
  659. {
  660. $orderInfoModel = new OrderInfoModel();
  661. $orderInfoModel->order_id = $order_id;
  662. return WechatRequestHelper::accessTokenAndToArray(new OrderInfoRequest($this->config), $orderInfoModel);
  663. }
  664. }