WechatMiniProgramShop.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. <?php
  2. namespace addons\shopro\library\easywechatPlus;
  3. use addons\shopro\exception\ShoproException;
  4. use addons\shopro\service\order\shippingInfo\OrderShippingInfo;
  5. use addons\shopro\service\order\shippingInfo\TradeOrderShippingInfo;
  6. use app\admin\model\shopro\data\WechatExpress;
  7. /**
  8. * 补充 小程序购物订单
  9. */
  10. class WechatMiniProgramShop extends EasywechatPlus
  11. {
  12. /**
  13. * 上送订单信息
  14. *
  15. * @param object|array $order
  16. * @return void
  17. */
  18. public function uploadShippingInfos($order, $express = null, $type = 'send')
  19. {
  20. try {
  21. $orderShippingInfo = new OrderShippingInfo($order);
  22. if ($type == 'change') {
  23. $uploadParams = $orderShippingInfo->getChangeShippingParams($express);
  24. } else {
  25. $uploadParams = $orderShippingInfo->getShippingParams();
  26. }
  27. // 设置消息跳转地址
  28. $this->setMessageJumpPath();
  29. $length = count($uploadParams);
  30. foreach ($uploadParams as $key => $params) {
  31. $params['delivery_mode'] = 1;
  32. $params['is_all_delivered'] = true;
  33. if ($params['logistics_type'] == 1 && count($params['shipping_list']) > 1) {
  34. // 快递物流,并且
  35. $params['delivery_mode'] = 2;
  36. }
  37. if ($length > 1) {
  38. if ($key == ($length - 1)) {
  39. // 最后一条
  40. $params['is_all_delivered'] = true; // 发货完成
  41. } else {
  42. $params['is_all_delivered'] = false; // 发货未完成
  43. }
  44. }
  45. $params['upload_time'] = date(DATE_RFC3339);
  46. \think\Log::error('发货信息录入' . json_encode($params));
  47. $result = $this->uploadShippingInfo($params);
  48. if ($result['errcode'] != 0) {
  49. throw new ShoproException('获取失败: errcode:' . $result['errcode'] . '; errmsg:' . $result['errmsg']);
  50. }
  51. }
  52. } catch (\Exception $e) {
  53. format_log_error($e, 'upload_shipping_info', '发货信息录入错误');
  54. }
  55. }
  56. /**
  57. * trade 订单上送订单信息
  58. *
  59. * @param object|array $order
  60. * @return void
  61. */
  62. public function tradeUploadShippingInfos($order)
  63. {
  64. try {
  65. $orderShippingInfo = new TradeOrderShippingInfo($order);
  66. $uploadParams = $orderShippingInfo->getShippingParams();
  67. // 将确认收货跳转地址设置为空,trade 商城系统不需要确认收货
  68. $this->setMessageJumpPath(true, '');
  69. $length = count($uploadParams);
  70. foreach ($uploadParams as $key => $params) {
  71. $params['delivery_mode'] = 1;
  72. $params['is_all_delivered'] = true;
  73. $params['upload_time'] = date(DATE_RFC3339);
  74. \think\Log::error('发货信息录入' . json_encode($params));
  75. $result = $this->uploadShippingInfo($params);
  76. if ($result['errcode'] != 0) {
  77. throw new ShoproException('获取失败: errcode:' . $result['errcode'] . '; errmsg:' . $result['errmsg']);
  78. }
  79. }
  80. } catch (\Exception $e) {
  81. format_log_error($e, 'trade_upload_shipping_info', '发货信息录入错误');
  82. }
  83. }
  84. /**
  85. * 将发货信息提交给微信
  86. *
  87. * @param array $params 上送参数
  88. * @return void
  89. */
  90. private function uploadShippingInfo($params)
  91. {
  92. $access_token = $this->getAccessToken();
  93. $add_template_url = "https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info";
  94. $result = \addons\shopro\facade\HttpClient::request('post', $add_template_url, [
  95. 'body' => json_encode($params, JSON_UNESCAPED_UNICODE),
  96. 'query' => ["access_token" => $access_token['access_token']],
  97. 'headers' => ['Content-Type' => 'application/json']
  98. ]);
  99. $result = $result->getBody()->getContents();
  100. return json_decode($result, true);
  101. }
  102. /**
  103. * 检测并且设置微信消息跳转地址
  104. *
  105. * @param boolean $exception
  106. * @param boolean $is_force
  107. * @return boolean
  108. */
  109. public function checkAndSetMessageJumpPath($exception = false, $is_force = false)
  110. {
  111. try {
  112. // 查询是否又微信发货管理权限
  113. if ($this->isTradeManaged($is_force)) {
  114. // 有权限,设置消息跳转地址
  115. $this->setMessageJumpPath($is_force);
  116. }
  117. return true;
  118. } catch (\Exception $e) {
  119. format_log_error($e, 'checkAndSetMessageJumpPath', '自动设置微信小程序发货信息管理消息跳转路径失败');
  120. if ($exception) {
  121. // 抛出异常
  122. throw new ShoproException($e->getMessage());
  123. }
  124. }
  125. return false;
  126. }
  127. /**
  128. * 查询是否有微信发货信息管理权限 (48001 时当没有权限处理,不抛出异常)
  129. *
  130. * @param boolean $is_force
  131. * @return boolean
  132. */
  133. public function isTradeManaged($is_force = false)
  134. {
  135. $key = 'wechat:is_trade_managed';
  136. if (!$is_force && redis_cache('?' . $key)) {
  137. return redis_cache($key); // 直接返回是否有权限
  138. }
  139. $access_token = $this->getAccessToken();
  140. $add_template_url = "https://api.weixin.qq.com/wxa/sec/order/is_trade_managed";
  141. $mini_appid = sheep_config('shop.platform.WechatMiniProgram.app_id');
  142. if (!$mini_appid) {
  143. // 没有配置微信小程序参数
  144. throw new ShoproException('微信小程序发货管理查询失败,没有配置微信小程序');
  145. }
  146. $params = [
  147. 'appid' => $mini_appid
  148. ];
  149. $result = \addons\shopro\facade\HttpClient::request('post', $add_template_url, [
  150. 'body' => json_encode($params, JSON_UNESCAPED_UNICODE),
  151. 'query' => ["access_token" => $access_token['access_token']],
  152. 'headers' => ['Content-Type' => 'application/json']
  153. ]);
  154. $result = $result->getBody()->getContents();
  155. $result = json_decode($result, true);
  156. if ($result['errcode'] != 0 && $result['errcode'] != '48001') {
  157. // 48001 时不抛出异常,当没有权限处理
  158. throw new ShoproException('查询是否有微信发货信息管理权限失败: errcode:' . $result['errcode'] . '; errmsg:' . $result['errmsg']);
  159. }
  160. $is_trade_managed = isset($result['is_trade_managed']) ? intval($result['is_trade_managed']) : 0;
  161. redis_cache($key, $is_trade_managed, 7200); // 缓存结果,两小时
  162. return $is_trade_managed;
  163. }
  164. /**
  165. * 设置微信消息跳转路径
  166. *
  167. * @param boolean $is_force
  168. * @return void
  169. */
  170. public function setMessageJumpPath($is_force = false, $path = 'pages/order/detail?comein_type=wechat')
  171. {
  172. if (!$is_force && redis_cache('?wechat:set_message_jump_path')) {
  173. // 已经设置过了,无需再次设置
  174. return true;
  175. }
  176. $access_token = $this->getAccessToken();
  177. $add_template_url = "https://api.weixin.qq.com/wxa/sec/order/set_msg_jump_path";
  178. $params = [
  179. 'path' => $path
  180. ];
  181. $result = \addons\shopro\facade\HttpClient::request('post', $add_template_url, [
  182. 'body' => json_encode($params, JSON_UNESCAPED_UNICODE),
  183. 'query' => ["access_token" => $access_token['access_token']],
  184. 'headers' => ['Content-Type' => 'application/json']
  185. ]);
  186. $result = $result->getBody()->getContents();
  187. $result = json_decode($result, true);
  188. if ($result['errcode'] != 0) {
  189. throw new ShoproException('设置微信发货消息跳转地址失败: errcode:' . $result['errcode'] . '; errmsg:' . $result['errmsg']);
  190. }
  191. if ($is_force) {
  192. // 充值订单发货时,清掉缓存
  193. redis_cache('wechat:set_message_jump_path', null); // 清除缓存
  194. } else {
  195. redis_cache('wechat:set_message_jump_path', time()); // 永久有效
  196. }
  197. return $result;
  198. }
  199. /**
  200. * 获取微信delivery数据
  201. *
  202. * @param boolean $is_force
  203. * @return void
  204. */
  205. public function getDelivery($is_force = false)
  206. {
  207. if (!$is_force && redis_cache('?wechat:get_delivery_list')) {
  208. // 已经设置过了,无需再次设置
  209. return true;
  210. }
  211. $access_token = $this->getAccessToken();
  212. $get_delivery_url = "https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/get_delivery_list";
  213. $result = \addons\shopro\facade\HttpClient::request('post', $get_delivery_url, [
  214. 'body' => '{}',
  215. 'query' => ["access_token" => $access_token['access_token']],
  216. 'headers' => ['Content-Type' => 'application/json']
  217. ]);
  218. $result = $result->getBody()->getContents();
  219. $result = json_decode($result, true);
  220. if ($result['errcode'] != 0) {
  221. throw new ShoproException('获取微信 delivery 列表失败: errcode:' . $result['errcode'] . '; errmsg:' . $result['errmsg']);
  222. }
  223. // 存库
  224. $datas = $result['delivery_list'];
  225. foreach ($datas as $data) {
  226. $wechatExpress = WechatExpress::where('code', $data['delivery_id'])->find();
  227. $current = [
  228. 'name' => $data['delivery_name'] ?? '',
  229. 'code' => $data['delivery_id'] ?? '',
  230. ];
  231. if (!$wechatExpress) {
  232. $wechatExpress = new WechatExpress();
  233. }
  234. $wechatExpress->save($current);
  235. }
  236. redis_cache('wechat:get_delivery_list', time()); // 永久有效
  237. return $result;
  238. }
  239. /**
  240. * 方法转发到 easywechat
  241. *
  242. * @param string $funcname
  243. * @param array $arguments
  244. * @return void
  245. */
  246. public function __call($funcname, $arguments)
  247. {
  248. // if ($funcname == 'deletePrivateTemplate') {
  249. // return $this->app->template_message->{$funcname}(...$arguments);
  250. // }
  251. return $this->app->{$funcname}(...$arguments);
  252. }
  253. }