MiniProgramService.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace crmeb\services\app;
  12. use crmeb\exceptions\AdminException;
  13. use crmeb\services\SystemConfigService;
  14. use app\services\pay\PayNotifyServices;
  15. use crmeb\services\easywechat\Application;
  16. use EasyWeChat\Payment\Order;
  17. use think\facade\Route as Url;
  18. use crmeb\utils\Hook;
  19. use think\facade\Cache;
  20. /**
  21. * 微信小程序接口
  22. * Class WechatMinService
  23. * @package service
  24. */
  25. class MiniProgramService
  26. {
  27. const MSG_CODE = [
  28. '1' => '未创建直播间',
  29. '1003' => '商品id不存在',
  30. '47001' => '入参格式不符合规范',
  31. '200002' => '入参错误',
  32. '300001' => '禁止创建/更新商品 或 禁止编辑&更新房间',
  33. '300002' => '名称长度不符合规则',
  34. '300006' => '图片上传失败',
  35. '300022' => '此房间号不存在',
  36. '300023' => '房间状态 拦截',
  37. '300024' => '商品不存在',
  38. '300025' => '商品审核未通过',
  39. '300026' => '房间商品数量已经满额',
  40. '300027' => '导入商品失败',
  41. '300028' => '房间名称违规',
  42. '300029' => '主播昵称违规',
  43. '300030' => '主播微信号不合法',
  44. '300031' => '直播间封面图不合规',
  45. '300032' => '直播间分享图违规',
  46. '300033' => '添加商品超过直播间上限',
  47. '300034' => '主播微信昵称长度不符合要求',
  48. '300035' => '主播微信号不存在',
  49. '300036' => '主播微信号未实名认证',
  50. '300037' => '购物直播频道封面图不合规',
  51. '300038' => '未在小程序管理后台配置客服',
  52. '9410000' => '直播间列表为空',
  53. '9410001' => '获取房间失败',
  54. '9410002' => '获取商品失败',
  55. '9410003' => '获取回放失败',
  56. '300003' => '价格输入不合规',
  57. '300004' => '商品名称存在违规违法内容',
  58. '300005' => '商品图片存在违规违法内容',
  59. '300007' => '线上小程序版本不存在该链接',
  60. '300008' => '添加商品失败',
  61. '300009' => '商品审核撤回失败',
  62. '300010' => '商品审核状态不对',
  63. '300011' => '操作非法',
  64. '300012' => '没有提审额度',
  65. '300013' => '提审失败',
  66. '300014' => '审核中,无法删除',
  67. '300017' => '商品未提审',
  68. '300018' => '图片尺寸不符合要求',
  69. '300021' => '商品添加成功,审核失败',
  70. '40001' => 'AppSecret错误或者AppSecret不属于这个小程序,请确认AppSecret 的正确性',
  71. '40002' => '请确保grant_type字段值为client_credential',
  72. '40013' => '不合法的AppID,请检查AppID的正确性,避免异常字符,注意大小写',
  73. '40125' => '小程序配置无效,请检查配置',
  74. '41002' => '缺少appid参数',
  75. '41004' => '缺少secret参数',
  76. '43104' => 'appid与openid不匹配',
  77. '48001' => '微信接口暂无权限,请先去获取',
  78. '-1' => '系统错误',
  79. ];
  80. /**
  81. * @var Application
  82. */
  83. protected static $instance;
  84. /**
  85. * @return array
  86. */
  87. public static function options()
  88. {
  89. $wechat = SystemConfigService::more(['wechat_app_appsecret', 'wechat_app_appid', 'site_url', 'routine_appId', 'routine_appsecret']);
  90. $payment = SystemConfigService::more(['pay_weixin_mchid', 'pay_weixin_key', 'pay_weixin_client_cert', 'pay_weixin_client_key', 'pay_weixin_open','pay_new_weixin_open','pay_new_weixin_mchid']);
  91. $config = [];
  92. if (request()->isApp()) {
  93. $appId = isset($wechat['wechat_app_appid']) ? trim($wechat['wechat_app_appid']) : '';
  94. $appsecret = isset($wechat['wechat_app_appsecret']) ? trim($wechat['wechat_app_appsecret']) : '';
  95. } else {
  96. $appId = isset($wechat['routine_appId']) ? trim($wechat['routine_appId']) : '';
  97. $appsecret = isset($wechat['routine_appsecret']) ? trim($wechat['routine_appsecret']) : '';
  98. }
  99. $config['mini_program'] = [
  100. 'app_id' => $appId,
  101. 'secret' => $appsecret,
  102. 'token' => isset($wechat['wechat_token']) ? trim($wechat['wechat_token']) : '',
  103. 'aes_key' => isset($wechat['wechat_encodingaeskey']) ? trim($wechat['wechat_encodingaeskey']) : ''
  104. ];
  105. $config['payment'] = [
  106. 'app_id' => $appId,
  107. 'merchant_id' => empty($payment['pay_new_weixin_open']) ? trim($payment['pay_weixin_mchid']) : trim($payment['pay_new_weixin_mchid']),
  108. 'key' => trim($payment['pay_weixin_key']),
  109. 'cert_path' => public_path() . $payment['pay_weixin_client_cert'],
  110. 'key_path' => public_path() . $payment['pay_weixin_client_key'],
  111. 'notify_url' => trim($wechat['site_url']) . Url::buildUrl('/api/routine/notify')
  112. ];
  113. return $config;
  114. }
  115. /**
  116. * 初始化
  117. * @param bool $cache
  118. * @return Application
  119. */
  120. public static function application($cache = false)
  121. {
  122. (self::$instance === null || $cache === true) && (self::$instance = new Application(self::options()));
  123. return self::$instance;
  124. }
  125. /**
  126. * 小程序接口
  127. * @return \EasyWeChat\MiniProgram\MiniProgram
  128. */
  129. public static function miniprogram()
  130. {
  131. return self::application()->mini_program;
  132. }
  133. /**
  134. * 获得用户信息 根据code 获取session_key
  135. * @param array|string $openid
  136. * @return $userInfo
  137. */
  138. public static function getUserInfo($code)
  139. {
  140. try {
  141. return self::miniprogram()->sns->getSessionKey($code);
  142. } catch (\Throwable $e) {
  143. throw new AdminException($e->getMessage());
  144. }
  145. }
  146. /**
  147. * 加密数据解密
  148. * @param $sessionKey
  149. * @param $iv
  150. * @param $encryptData
  151. * @return $userInfo
  152. */
  153. public static function encryptor($sessionKey, $iv, $encryptData)
  154. {
  155. return self::miniprogram()->encryptor->decryptData($sessionKey, $iv, $encryptData);
  156. }
  157. /**
  158. * 上传临时素材接口
  159. * @return \EasyWeChat\Material\Temporary
  160. */
  161. public static function materialTemporaryService()
  162. {
  163. return self::miniprogram()->material_temporary;
  164. }
  165. /**
  166. * 客服消息接口
  167. * @param null $to
  168. * @param null $message
  169. */
  170. public static function staffService()
  171. {
  172. return self::miniprogram()->staff;
  173. }
  174. /**
  175. * 微信小程序二维码生成接口
  176. * @return \EasyWeChat\QRCode\QRCode
  177. */
  178. public static function qrcodeService()
  179. {
  180. return self::miniprogram()->qrcode;
  181. }
  182. /**微信小程序二维码生成接口不限量永久
  183. * @param $scene
  184. * @param null $page
  185. * @param null $width
  186. * @param null $autoColor
  187. * @param array $lineColor
  188. * @return \Psr\Http\Message\StreamInterface
  189. */
  190. public static function appCodeUnlimitService($scene, $page = null, $width = 430, $autoColor = false, $lineColor = ['r' => 0, 'g' => 0, 'b' => 0])
  191. {
  192. return self::qrcodeService()->appCodeUnlimit($scene, $page, $width, $autoColor, $lineColor);
  193. }
  194. /**
  195. * 模板消息接口
  196. * @return \EasyWeChat\Notice\Notice
  197. */
  198. public static function noticeService()
  199. {
  200. return self::miniprogram()->notice;
  201. }
  202. /**
  203. * 订阅模板消息接口
  204. * @return \crmeb\services\subscribe\ProgramSubscribe
  205. */
  206. public static function SubscribenoticeService()
  207. {
  208. return self::miniprogram()->now_notice;
  209. }
  210. /**
  211. * 发送订阅消息
  212. * @param string $touser 接收者(用户)的 openid
  213. * @param string $templateId 所需下发的订阅模板id
  214. * @param array $data 模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } }
  215. * @param string $link 击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。
  216. * @return \EasyWeChat\Support\Collection|null
  217. * @throws \EasyWeChat\Core\Exceptions\HttpException
  218. * @throws \EasyWeChat\Core\Exceptions\InvalidArgumentException
  219. */
  220. public static function sendSubscribeTemlate(string $touser, string $templateId, array $data, string $link = '')
  221. {
  222. return self::SubscribenoticeService()->to($touser)->template($templateId)->andData($data)->withUrl($link)->send();
  223. }
  224. /**
  225. * 添加订阅消息模版
  226. * @param string $tid
  227. * @param array $kidList
  228. * @param string $sceneDesc
  229. * @return mixed
  230. */
  231. public static function addSubscribeTemplate(string $tid, array $kidList, string $sceneDesc = '')
  232. {
  233. try {
  234. $res = self::SubscribenoticeService()->addTemplate($tid, $kidList, $sceneDesc);
  235. if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['priTmplId'])) {
  236. return $res['priTmplId'];
  237. } else {
  238. throw new AdminException($res['errmsg']);
  239. }
  240. } catch (\Throwable $e) {
  241. throw new AdminException($e);
  242. }
  243. }
  244. /**
  245. * 获取模版标题的关键词列表
  246. * @param string $tid
  247. * @return mixed
  248. */
  249. public static function getSubscribeTemplateKeyWords(string $tid)
  250. {
  251. try {
  252. $res = self::SubscribenoticeService()->getPublicTemplateKeywords($tid);
  253. if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['data'])) {
  254. return $res['data'];
  255. } else {
  256. throw new AdminException($res['errmsg']);
  257. }
  258. } catch (\Throwable $e) {
  259. throw new AdminException($e);
  260. }
  261. }
  262. /**
  263. * 支付
  264. * @return \EasyWeChat\Payment\Payment
  265. */
  266. public static function paymentService()
  267. {
  268. return self::application()->payment;
  269. }
  270. /**
  271. * 生成支付订单对象
  272. * @param $openid
  273. * @param $out_trade_no
  274. * @param $total_fee
  275. * @param $attach
  276. * @param $body
  277. * @param string $detail
  278. * @param string $trade_type
  279. * @param array $options
  280. * @return Order
  281. */
  282. protected static function paymentOrder($openid, $out_trade_no, $total_fee, $attach, $body, $detail = '', $trade_type = 'JSAPI', $options = [])
  283. {
  284. $total_fee = bcmul($total_fee, 100, 0);
  285. $order = array_merge(compact('openid', 'out_trade_no', 'total_fee', 'attach', 'body', 'detail', 'trade_type'), $options);
  286. if ($order['detail'] == '') unset($order['detail']);
  287. return new Order($order);
  288. }
  289. /**
  290. * 获得下单ID
  291. * @param $openid
  292. * @param $out_trade_no
  293. * @param $total_fee
  294. * @param $attach
  295. * @param $body
  296. * @param string $detail
  297. * @param string $trade_type
  298. * @param array $options
  299. * @return mixed
  300. */
  301. public static function paymentPrepare($openid, $out_trade_no, $total_fee, $attach, $body, $detail = '', $trade_type = 'JSAPI', $options = [])
  302. {
  303. $key = 'pay_' . $out_trade_no;
  304. $result = Cache::get($key);
  305. if ($result) {
  306. return $result;
  307. } else {
  308. $order = self::paymentOrder($openid, $out_trade_no, $total_fee, $attach, $body, $detail, $trade_type, $options);
  309. $result = self::paymentService()->prepare($order);
  310. if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS') {
  311. Cache::set($key, $result->prepay_id, 7000);
  312. return $result->prepay_id;
  313. } else {
  314. if ($result->return_code == 'FAIL') {
  315. exception('微信支付错误返回:' . $result->return_msg);
  316. } else if (isset($result->err_code)) {
  317. exception('微信支付错误返回:' . $result->err_code_des);
  318. } else {
  319. exception('没有获取微信支付的预支付ID,请重新发起支付!');
  320. }
  321. exit;
  322. }
  323. }
  324. }
  325. /**
  326. * 获得下单ID
  327. * @param $openid
  328. * @param $out_trade_no
  329. * @param $total_fee
  330. * @param $attach
  331. * @param $body
  332. * @param string $detail
  333. * @param string $trade_type
  334. * @param array $options
  335. * @return mixed
  336. */
  337. public static function newPaymentPrepare($openid, $out_trade_no, $total_fee, $attach, $body, $detail = '', $options = [])
  338. {
  339. $key = 'pay_' . $out_trade_no;
  340. $result = Cache::get($key);
  341. if ($result) {
  342. return $result;
  343. } else {
  344. $order = self::paymentOrder($openid, $out_trade_no, $total_fee, $attach, $body, $detail, $options);
  345. $result = self::application()->minipay->createorder($order);
  346. if ($result->errcode === 0) {
  347. Cache::set($key, $result->payment_params, 7000);
  348. return $result->payment_params;
  349. } else {
  350. exception('微信支付错误返回:'.'['.$result->errcode.']'. $result->errmsg);
  351. exit;
  352. }
  353. }
  354. }
  355. /**
  356. * 获得jsSdk支付参数
  357. * @param $openid
  358. * @param $out_trade_no
  359. * @param $total_fee
  360. * @param $attach
  361. * @param $body
  362. * @param string $detail
  363. * @param string $trade_type
  364. * @param array $options
  365. * @return array|string
  366. */
  367. public static function jsPay($openid, $out_trade_no, $total_fee, $attach, $body, $detail = '', $trade_type = 'JSAPI', $options = [])
  368. {
  369. return self::paymentService()->configForJSSDKPayment(self::paymentPrepare($openid, $out_trade_no, $total_fee, $attach, $body, $detail, $trade_type, $options));
  370. }
  371. /**
  372. * 获得jsSdk支付参数
  373. * @param $openid
  374. * @param $out_trade_no
  375. * @param $total_fee
  376. * @param $attach
  377. * @param $body
  378. * @param string $detail
  379. * @param string $trade_type
  380. * @param array $options
  381. * @return array|string
  382. */
  383. public static function newJsPay($openid, $out_trade_no, $total_fee, $attach, $body, $detail = '', $options = [])
  384. {
  385. $config = self::newPaymentPrepare($openid, $out_trade_no, $total_fee, $attach, $body, $detail, $options);
  386. $config['timestamp'] = $config['timeStamp'];
  387. unset($config['timeStamp']);
  388. return $config;
  389. }
  390. /**
  391. * 获得App支付参数
  392. * @param $openid
  393. * @param $out_trade_no
  394. * @param $total_fee
  395. * @param $attach
  396. * @param $body
  397. * @param string $detail
  398. * @param string $trade_type
  399. * @param array $options
  400. * @return array|string
  401. */
  402. public static function appPay($openid, $out_trade_no, $total_fee, $attach, $body, $detail = '', $trade_type = Order::APP, $options = [])
  403. {
  404. return self::paymentService()->configForAppPayment(self::paymentPrepare($openid, $out_trade_no, $total_fee, $attach, $body, $detail, $trade_type, $options));
  405. }
  406. /**
  407. * 使用商户订单号退款
  408. * @param $orderNo
  409. * @param $refundNo
  410. * @param $totalFee
  411. * @param null $refundFee
  412. * @param null $opUserId
  413. * @param string $refundReason
  414. * @param string $type
  415. * @param string $refundAccount
  416. */
  417. public static function refund($orderNo, $refundNo, $totalFee, $refundFee = null, $opUserId = null, $refundReason = '', $type = 'out_trade_no', $refundAccount = 'REFUND_SOURCE_UNSETTLED_FUNDS')
  418. {
  419. $totalFee = floatval($totalFee);
  420. $refundFee = floatval($refundFee);
  421. if ($type == 'out_trade_no') {
  422. return self::paymentService()->refund($orderNo, $refundNo, $totalFee, $refundFee, $opUserId, $type, $refundAccount, $refundReason);
  423. } else {
  424. return self::paymentService()->refundByTransactionId($orderNo, $refundNo, $totalFee, $refundFee, $opUserId, $refundAccount, $refundReason);
  425. }
  426. }
  427. /**
  428. * 使用商户订单号退款
  429. * @param $orderNo
  430. * @param $refundNo
  431. * @param $totalFee
  432. * @param null $refundFee
  433. * @param null $opUserId
  434. * @param string $refundReason
  435. * @param string $type
  436. * @param string $refundAccount
  437. */
  438. public static function miniRefund($orderNo, $totalFee, $refundFee = null, $opt)
  439. {
  440. $totalFee = floatval($totalFee);
  441. $refundFee = floatval($refundFee);
  442. $order = [
  443. 'openid' => $opt['open_id'],
  444. 'trade_no'=>$opt['order_id'],
  445. 'transaction_id'=>$opt['trade_no'],
  446. 'refund_no'=>$opt['refund_no'],
  447. 'total_amount'=>$totalFee,
  448. 'refund_amount'=>$refundFee,
  449. ];
  450. return self::application()->minipay->refundorder($order);
  451. }
  452. /** 根据订单号退款
  453. * @param $orderNo
  454. * @param array $opt
  455. * @return bool
  456. */
  457. public static function payOrderRefund($orderNo, array $opt)
  458. {
  459. if (!isset($opt['pay_price'])) throw new AdminException(400730);
  460. if (sys_config('pay_weixin_client_key') == '' || sys_config('pay_weixin_client_cert') == '') throw new AdminException(400739);
  461. $totalFee = floatval(bcmul($opt['pay_price'], 100, 0));
  462. $refundFee = isset($opt['refund_price']) ? floatval(bcmul($opt['refund_price'], 100, 0)) : null;
  463. $refundReason = $opt['desc'] ?? '';
  464. $refundNo = $opt['refund_id'] ?? $orderNo;
  465. $opUserId = $opt['op_user_id'] ?? null;
  466. $type = $opt['type'] ?? 'out_trade_no';
  467. /*仅针对老资金流商户使用
  468. REFUND_SOURCE_UNSETTLED_FUNDS---未结算资金退款(默认使用未结算资金退款)
  469. REFUND_SOURCE_RECHARGE_FUNDS---可用余额退款*/
  470. $refundAccount = $opt['refund_account'] ?? 'REFUND_SOURCE_UNSETTLED_FUNDS';
  471. try {
  472. $res = (self::refund($orderNo, $refundNo, $totalFee, $refundFee, $opUserId, $refundReason, $type, $refundAccount));
  473. if ($res->return_code == 'FAIL') throw new AdminException(400731, ['msg' => $res->return_msg]);
  474. if (isset($res->err_code)) throw new AdminException(400731, ['msg' => $res->err_code_des]);
  475. } catch (\Exception $e) {
  476. throw new AdminException($e->getMessage());
  477. }
  478. return true;
  479. }
  480. /**
  481. * 微信支付成功回调接口
  482. * @return \Symfony\Component\HttpFoundation\Response
  483. * @throws \EasyWeChat\Core\Exceptions\FaultException
  484. */
  485. public static function handleNotify()
  486. {
  487. return self::paymentService()->handleNotify(function ($notify, $successful) {
  488. if ($successful && isset($notify->out_trade_no)) {
  489. if (isset($notify->attach) && $notify->attach) {
  490. if (($count = strpos($notify->out_trade_no, '_')) !== false) {
  491. $notify->out_trade_no = substr($notify->out_trade_no, $count + 1);
  492. }
  493. (new Hook(PayNotifyServices::class, 'wechat'))->listen($notify->attach, $notify->out_trade_no, $notify->transaction_id);
  494. }
  495. return false;
  496. }
  497. });
  498. }
  499. /**
  500. * 作为客服消息发送
  501. * @param $to
  502. * @param $message
  503. * @return bool
  504. */
  505. public static function staffTo($to, $message)
  506. {
  507. $staff = self::staffService();
  508. $staff = is_callable($message) ? $staff->message($message()) : $staff->message($message);
  509. $res = $staff->to($to)->send();
  510. return $res;
  511. }
  512. /**
  513. * 获取直播列表
  514. * @param int $page
  515. * @param int $limit
  516. * @return array
  517. */
  518. public static function getLiveInfo(int $page = 1, int $limit = 10)
  519. {
  520. try {
  521. $res = self::miniprogram()->wechat_live->getLiveInfo($page, $limit);
  522. if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['room_info']) && $res['room_info']) {
  523. return $res['room_info'];
  524. } else {
  525. return [];
  526. }
  527. } catch (\Throwable $e) {
  528. return [];
  529. }
  530. }
  531. /**
  532. * 获取直播回放
  533. * @param int $room_id
  534. * @param int $page
  535. * @param int $limit
  536. * @return mixed
  537. */
  538. public static function getLivePlayback(int $room_id, int $page = 1, int $limit = 10)
  539. {
  540. try {
  541. $res = self::miniprogram()->wechat_live->getLivePlayback($room_id, $page, $limit);
  542. if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['live_replay'])) {
  543. return $res['live_replay'];
  544. } else {
  545. throw new AdminException($res['errmsg']);
  546. }
  547. } catch (\Throwable $e) {
  548. throw new AdminException(self::getValidMessgae($e));
  549. }
  550. }
  551. /**
  552. * 创建直播间
  553. * @param array $data
  554. * @return mixed
  555. */
  556. public static function createLiveRoom(array $data)
  557. {
  558. try {
  559. $res = self::miniprogram()->wechat_live->createRoom($data);
  560. if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['roomId'])) {
  561. unset($res['errcode']);
  562. return $res;
  563. } else {
  564. throw new AdminException($res['errmsg']);
  565. }
  566. } catch (\Throwable $e) {
  567. throw new AdminException(self::getValidMessgae($e));
  568. }
  569. }
  570. /**
  571. * 直播间添加商品
  572. * @param int $roomId
  573. * @param $ids
  574. * @return bool
  575. */
  576. public static function roomAddGoods(int $roomId, $ids)
  577. {
  578. try {
  579. $res = self::miniprogram()->wechat_live->roomAddGoods($roomId, $ids);
  580. if (isset($res['errcode']) && $res['errcode'] == 0) {
  581. return true;
  582. } else {
  583. throw new AdminException($res['errmsg']);
  584. }
  585. } catch (\Throwable $e) {
  586. throw new AdminException(self::getValidMessgae($e));
  587. }
  588. }
  589. /**
  590. * 获取商品列表
  591. * @param int $status
  592. * @param int $page
  593. * @param int $limit
  594. * @return mixed
  595. */
  596. public static function getGoodsList(int $status = 2, int $page = 1, int $limit = 10)
  597. {
  598. try {
  599. $res = self::miniprogram()->wechat_live->getGoodsList($status, $page, $limit);
  600. if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['goods'])) {
  601. return $res['goods'];
  602. } else {
  603. throw new AdminException($res['errmsg']);
  604. }
  605. } catch (\Throwable $e) {
  606. throw new AdminException(self::getValidMessgae($e));
  607. }
  608. }
  609. /**
  610. * 获取商品详情
  611. * @param $goods_ids
  612. * @return mixed
  613. */
  614. public static function getGooodsInfo($goods_ids)
  615. {
  616. try {
  617. $res = self::miniprogram()->wechat_live->getGooodsInfo($goods_ids);
  618. if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['goods'])) {
  619. return $res['goods'];
  620. } else {
  621. throw new AdminException($res['errmsg']);
  622. }
  623. } catch (\Throwable $e) {
  624. throw new AdminException(self::getValidMessgae($e));
  625. }
  626. }
  627. /**
  628. * 添加商品
  629. * @param string $coverImgUrl
  630. * @param string $name
  631. * @param int $priceType
  632. * @param string $url
  633. * @param $price
  634. * @param string $price2
  635. * @return mixed
  636. */
  637. public static function addGoods(string $coverImgUrl, string $name, int $priceType, string $url, $price, $price2 = '')
  638. {
  639. try {
  640. $res = self::miniprogram()->wechat_live->addGoods($coverImgUrl, $name, $priceType, $url, $price, $price2);
  641. if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['goodsId'])) {
  642. unset($res['errcode']);
  643. return $res;
  644. } else {
  645. throw new AdminException($res['errmsg']);
  646. }
  647. } catch (\Throwable $e) {
  648. throw new AdminException(self::getValidMessgae($e));
  649. }
  650. }
  651. /**
  652. * 商品撤回审核
  653. * @param int $goodsId
  654. * @param $auditId
  655. * @return bool
  656. */
  657. public static function resetauditGoods(int $goodsId, $auditId)
  658. {
  659. try {
  660. $res = self::miniprogram()->wechat_live->resetauditGoods($goodsId, $auditId);
  661. if (isset($res['errcode']) && $res['errcode'] == 0) {
  662. return true;
  663. } else {
  664. throw new AdminException($res['errmsg']);
  665. }
  666. } catch (\Throwable $e) {
  667. throw new AdminException(self::getValidMessgae($e));
  668. }
  669. }
  670. /**
  671. * 商品重新提交审核
  672. * @param int $goodsId
  673. * @return mixed
  674. */
  675. public static function auditGoods(int $goodsId)
  676. {
  677. try {
  678. $res = self::miniprogram()->wechat_live->auditGoods($goodsId);
  679. if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['auditId'])) {
  680. return $res['auditId'];
  681. } else {
  682. throw new AdminException($res['errmsg']);
  683. }
  684. } catch (\Throwable $e) {
  685. throw new AdminException(self::getValidMessgae($e));
  686. }
  687. }
  688. /**
  689. * 删除商品
  690. * @param int $goodsId
  691. * @return bool
  692. */
  693. public static function deleteGoods(int $goodsId)
  694. {
  695. try {
  696. $res = self::miniprogram()->wechat_live->deleteGoods($goodsId);
  697. if (isset($res['errcode']) && $res['errcode'] == 0) {
  698. return true;
  699. } else {
  700. throw new AdminException($res['errmsg']);
  701. }
  702. } catch (\Throwable $e) {
  703. throw new AdminException(self::getValidMessgae($e));
  704. }
  705. }
  706. /**
  707. * 更新商品
  708. * @param int $goodsId
  709. * @param string $coverImgUrl
  710. * @param string $name
  711. * @param int $priceType
  712. * @param string $url
  713. * @param $price
  714. * @param string $price2
  715. * @return bool
  716. */
  717. public static function updateGoods(int $goodsId, string $coverImgUrl, string $name, int $priceType, string $url, $price, $price2 = '')
  718. {
  719. try {
  720. $res = self::miniprogram()->wechat_live->updateGoods($goodsId, $coverImgUrl, $name, $priceType, $url, $price, $price2);
  721. if (isset($res['errcode']) && $res['errcode'] == 0) {
  722. return true;
  723. } else {
  724. throw new AdminException($res['errmsg']);
  725. }
  726. } catch (\Throwable $e) {
  727. throw new AdminException(self::getValidMessgae($e));
  728. }
  729. }
  730. /**
  731. * 更新商品
  732. * @param int $goodsId
  733. * @param string $coverImgUrl
  734. * @param string $name
  735. * @param int $priceType
  736. * @param string $url
  737. * @param $price
  738. * @param string $price2
  739. * @return bool
  740. */
  741. public static function getRoleList($role = 2, int $page = 0, int $limit = 30, $keyword = '')
  742. {
  743. try {
  744. $res = self::miniprogram()->wechat_live->getRoleList($role, $page, $limit, $keyword);
  745. if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['list'])) {
  746. return $res['list'];
  747. } else {
  748. throw new AdminException($res['errmsg']);
  749. }
  750. } catch (\Throwable $e) {
  751. throw new AdminException(self::getValidMessgae($e));
  752. }
  753. }
  754. public static function getValidMessgae(\Throwable $e)
  755. {
  756. $message = '';
  757. if (!isset(self::MSG_CODE[$e->getCode()]) && strstr($e->getMessage(), 'Request AccessToken fail') !== false) {
  758. $message = str_replace('Request AccessToken fail. response:', '', $e->getMessage());
  759. $message = json_decode($message, true) ?: [];
  760. $errcode = $message['errcode'] ?? false;
  761. if ($errcode) {
  762. $message = self::MSG_CODE[$errcode] ?? $message;
  763. }
  764. }
  765. return $message ?: self::MSG_CODE[$e->getCode()] ?? $e->getMessage();
  766. }
  767. }