WechatMiniProgramShop.php 9.0 KB

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