Wxapp.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <?php
  2. namespace app\data\controller\api;
  3. use app\data\service\UserAdminService;
  4. use think\admin\Controller;
  5. use think\exception\HttpResponseException;
  6. use think\Response;
  7. use WeMini\Crypt;
  8. use WeMini\Live;
  9. use WeMini\Qrcode;
  10. /**
  11. * 微信小程序入口
  12. * Class Wxapp
  13. * @package app\data\controller\api
  14. */
  15. class Wxapp extends Controller
  16. {
  17. /**
  18. * 接口认证类型
  19. * @var string
  20. */
  21. private $type = UserAdminService::API_TYPE_WXAPP;
  22. /**
  23. * 唯一绑定字段
  24. * @var string
  25. */
  26. private $field;
  27. /**
  28. * 小程序配置参数
  29. * @var array
  30. */
  31. private $config;
  32. /**
  33. * 接口服务初始化
  34. * @throws \think\db\exception\DataNotFoundException
  35. * @throws \think\db\exception\DbException
  36. * @throws \think\db\exception\ModelNotFoundException
  37. */
  38. protected function initialize()
  39. {
  40. $this->config = [
  41. 'appid' => sysconf('data.wxapp_appid'),
  42. 'appsecret' => sysconf('data.wxapp_appkey'),
  43. 'cache_path' => $this->app->getRootPath() . 'runtime' . DIRECTORY_SEPARATOR . 'wechat',
  44. ];
  45. if (empty(UserAdminService::TYPES[$this->type]['auth'])) {
  46. $this->error("接口类型[{$this->type}]没有定义规则");
  47. } else {
  48. $this->field = UserAdminService::TYPES[$this->type]['auth'];
  49. }
  50. }
  51. /**
  52. * 授权Code换取会话信息
  53. * @throws \think\admin\Exception
  54. * @throws \think\db\exception\DbException
  55. */
  56. public function session()
  57. {
  58. $input = $this->_vali(['code.require' => '登录凭证CODE不能为空!']);
  59. [$openid, $unionid, $session] = $this->_getSessionKey($input['code']);
  60. $map = UserAdminService::instance()->getUserUniMap($this->field, $openid, $unionid);
  61. $data = [$this->field => $openid, 'session_key' => $session];
  62. if (!empty($unionid)) $data['unionid'] = $unionid;
  63. $this->success('授权换取成功!', UserAdminService::instance()->set($map, $data, $this->type, true));
  64. }
  65. /**
  66. * 小程序数据解密
  67. */
  68. public function decode()
  69. {
  70. try {
  71. $input = $this->_vali([
  72. 'iv.require' => '解密向量不能为空!',
  73. 'code.require' => '授权CODE不能为空!',
  74. 'encrypted.require' => '加密内容不能为空!',
  75. ]);
  76. [$openid, $unionid, $input['session_key']] = $this->_getSessionKey($input['code']);
  77. $result = Crypt::instance($this->config)->decode($input['iv'], $input['session_key'], $input['encrypted']);
  78. if (is_array($result) && isset($result['avatarUrl']) && isset($result['nickName'])) {
  79. $data = [$this->field => $openid, 'nickname' => $result['nickName'], 'headimg' => $result['avatarUrl']];
  80. $data['base_sex'] = ['-', '男', '女'][$result['gender']] ?? '-';
  81. if (!empty($unionid)) $data['unionid'] = $unionid;
  82. $map = UserAdminService::instance()->getUserUniMap($this->field, $openid, $unionid);
  83. $this->success('数据解密成功!', UserAdminService::instance()->set($map, $data, $this->type, true));
  84. } elseif (is_array($result)) {
  85. $this->success('数据解密成功!', $result);
  86. } else {
  87. $this->error('数据处理失败,请稍候再试!');
  88. }
  89. } catch (HttpResponseException $exception) {
  90. throw $exception;
  91. } catch (\Exception $exception) {
  92. $this->error("数据处理失败,{$exception->getMessage()}");
  93. }
  94. }
  95. /**
  96. * 授权CODE换取会话信息
  97. * @param string $code 换取授权CODE
  98. * @return array [openid, sessionkey]
  99. */
  100. private function _getSessionKey(string $code): array
  101. {
  102. try {
  103. $cache = $this->app->cache->get($code, []);
  104. if (isset($cache['openid']) && isset($cache['session_key'])) {
  105. return [$cache['openid'], $cache['unionid'] ?? '', $cache['session_key']];
  106. }
  107. $result = Crypt::instance($this->config)->session($code);
  108. if (isset($result['openid']) && isset($result['session_key'])) {
  109. $this->app->cache->set($code, $result, 60);
  110. return [$result['openid'], $result['unionid'] ?? '', $result['session_key']];
  111. } elseif (isset($result['errmsg'])) {
  112. $this->error($result['errmsg']);
  113. } else {
  114. $this->error("授权换取失败,请稍候再试!");
  115. }
  116. } catch (HttpResponseException $exception) {
  117. throw $exception;
  118. } catch (\Exception $exception) {
  119. $this->error("授权换取失败,{$exception->getMessage()}");
  120. }
  121. }
  122. /**
  123. * 获取小程序码
  124. */
  125. public function qrcode(): Response
  126. {
  127. try {
  128. $data = $this->_vali([
  129. 'size.default' => 430,
  130. 'type.default' => 'base64',
  131. 'path.require' => '跳转路径不能为空!',
  132. ]);
  133. $result = Qrcode::instance($this->config)->createMiniPath($data['path'], $data['size']);
  134. if ($data['type'] === 'base64') {
  135. $this->success('生成小程序码成功!', [
  136. 'base64' => 'data:image/png;base64,' . base64_encode($result),
  137. ]);
  138. } else {
  139. return response($result)->contentType('image/png');
  140. }
  141. } catch (HttpResponseException $exception) {
  142. throw $exception;
  143. } catch (\Exception $exception) {
  144. $this->error($exception->getMessage());
  145. }
  146. }
  147. /**
  148. * 获取直播列表
  149. */
  150. public function getLiveList()
  151. {
  152. try {
  153. $data = $this->_vali(['start.default' => 0, 'limit.default' => 10]);
  154. $list = Live::instance($this->config)->getLiveList($data['start'], $data['limit']);
  155. $this->success('获取直播列表成功!', $list);
  156. } catch (HttpResponseException $exception) {
  157. throw $exception;
  158. } catch (\Exception $exception) {
  159. $this->error($exception->getMessage());
  160. }
  161. }
  162. /**
  163. * 获取回放源视频
  164. */
  165. public function getLiveInfo()
  166. {
  167. try {
  168. $data = $this->_vali([
  169. 'start.default' => 0,
  170. 'limit.default' => 10,
  171. 'action.default' => 'get_replay',
  172. 'room_id.require' => '直播间不能为空',
  173. ]);
  174. $result = Live::instance($this->config)->getLiveInfo($data);
  175. $this->success('获取回放视频成功!', $result);
  176. } catch (HttpResponseException $exception) {
  177. throw $exception;
  178. } catch (\Exception $exception) {
  179. $this->error($exception->getMessage());
  180. }
  181. }
  182. }