TencentImGroupService.php 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. <?php
  2. namespace App\Services;
  3. use App\Exceptions\TencentImException;
  4. use App\Exceptions\TencentImGroupException;
  5. use App\Models\TencentImGroup;
  6. use App\Traits\TencentIm;
  7. use Carbon\Carbon;
  8. use Illuminate\Support\Facades\DB;
  9. use Illuminate\Support\Facades\Log;
  10. use phpDocumentor\Reflection\Types\Self_;
  11. class TencentImGroupService
  12. {
  13. use TencentIm;
  14. const TENCENT_REST_APIS = [
  15. 'createGroup' => 'v4/group_open_http_svc/create_group', //创建群组 支持同时创建多个
  16. 'getGroupList' => 'v4/group_open_http_svc/get_appid_group_list', //获取app中所有群组
  17. ];
  18. const IM_GROUP_RAW_TYPE_PUBLIC = 'Public'; //陌生人社交群
  19. const IM_GROUP_RAW_TYPE_Private = 'Private'; //即 Work,好友工作群
  20. const IM_GROUP_RAW_TYPE_ChatRoom = 'ChatRoom'; //即 Meeting,会议群
  21. const IM_GROUP_RAW_TYPE_AVChatRoom = 'AVChatRoom'; //直播群
  22. const IM_GROUP_RAW_TYPE_TIPS = [
  23. self::IM_GROUP_RAW_TYPE_PUBLIC => '陌生人交友群',
  24. self::IM_GROUP_RAW_TYPE_Private => '好友工作群',
  25. self::IM_GROUP_RAW_TYPE_ChatRoom => '会议群',
  26. self::IM_GROUP_RAW_TYPE_AVChatRoom => '直播群',
  27. ];
  28. /**
  29. * 获取所有 APP 中的群组
  30. * @param int $limit
  31. * @param int $next
  32. * @return \Psr\Http\Message\ResponseInterface
  33. * @throws \App\Exceptions\TencentImAccountException
  34. * @throws \App\Exceptions\TencentImException
  35. * @throws \GuzzleHttp\Exception\GuzzleException
  36. */
  37. public function getGroupList(int $limit = 10000, int $next = 0)
  38. {
  39. $this->restApiName = self::TENCENT_REST_APIS['getGroupList'];
  40. $baseApiHost = $this->getTencentImRestApiBaseHost();
  41. $params = [
  42. 'Limit' => $limit,
  43. 'Next' => $next
  44. ];
  45. $apiResult = $this->requestApi($baseApiHost, $params);
  46. self::verifyApiResult($apiResult);
  47. return $apiResult;
  48. }
  49. /**
  50. * 验证类型是否存在
  51. * @param string $groupType
  52. * @return bool
  53. * @throws TencentImGroupException
  54. */
  55. static public function verifyImGroupType(string $groupType)
  56. {
  57. if (!array_key_exists($groupType, TencentImGroup::IM_GROUP_RAW_TYPE_TIPS)) {
  58. throw new TencentImGroupException('群类型不存在');
  59. }
  60. return true;
  61. }
  62. /**
  63. * 验证当日建群上限,并返回当前可以添加的数量
  64. * @return int
  65. * @throws TencentImGroupException
  66. */
  67. static public function verifyToDayCreateCount()
  68. {
  69. if (TencentImGroup::getToDayCreateCount() >= TencentImGroup::IM_GROUP_CREATE_DAY_MAX) {
  70. throw new TencentImGroupException('单日新建群组上限为: ' . TencentImGroup::IM_GROUP_CREATE_DAY_MAX);
  71. }
  72. return (TencentImGroup::IM_GROUP_CREATE_DAY_MAX - TencentImGroup::getToDayCreateCount());
  73. }
  74. /**
  75. * 验证当月建群上限,并返回可以添加的数量
  76. * @return int
  77. * @throws TencentImGroupException
  78. */
  79. static public function verifyMonthCreateCount()
  80. {
  81. if (TencentImGroup::getMonthCreateCount() >= TencentImGroup::IM_GROUP_CREATE_MONTH_MAX) {
  82. throw new TencentImGroupException('单月新建群组上限为: ' . TencentImGroup::IM_GROUP_CREATE_MONTH_MAX);
  83. }
  84. return (TencentImGroup::IM_GROUP_CREATE_MONTH_MAX - TencentImGroup::getMonthCreateCount());
  85. }
  86. /**
  87. * 验证是否可以添加群
  88. * @param int $groupCount
  89. * @throws TencentImGroupException
  90. */
  91. static public function verifyIsCreateGroup(int $groupCount)
  92. {
  93. //验证单次最低
  94. if ($groupCount < TencentImGroup::IM_GROUP_ONCE_CREATE_MIN) {
  95. throw new TencentImGroupException('单次添加最低' . TencentImGroup::IM_GROUP_ONCE_CREATE_MIN . ' 个群');
  96. }
  97. //验证单次最多
  98. if ($groupCount > TencentImGroup::IM_GROUP_ONCE_CREATE_MAX) {
  99. throw new TencentImGroupException('单次添加最多' . TencentImGroup::IM_GROUP_ONCE_CREATE_MAX . ' 个群');
  100. }
  101. //验证当天添加群数量
  102. $canToDayCount = self::verifyToDayCreateCount();
  103. //验证当月添加上限
  104. $canMonthCount = self::verifyMonthCreateCount();
  105. if ($groupCount > $canToDayCount) {
  106. throw new TencentImGroupException('当前创建数量超过日上限,当日还可创建 ' . $canToDayCount . '个');
  107. }
  108. if ($groupCount > $canMonthCount) {
  109. throw new TencentImGroupException('当前创建数量超过月上限,当月还可创建 ' . $canMonthCount . '个');
  110. }
  111. return true;
  112. }
  113. /**
  114. *
  115. * @param int $groupCount
  116. * @param string $groupType
  117. * @throws TencentImGroupException
  118. * @throws \App\Exceptions\TencentImException
  119. */
  120. public function createGroups(int $groupCount, string $groupType = TencentImGroup::DEFAULT_IM_RAW_GROUP_TYPE)
  121. {
  122. try {
  123. //验证群类型是否存在
  124. self::verifyImGroupType($groupType);
  125. //是否可以创建群
  126. self::verifyIsCreateGroup($groupCount);
  127. DB::beginTransaction();
  128. $this->restApiName = self::TENCENT_REST_APIS['createGroup'];
  129. $baseApiHost = $this->getTencentImRestApiBaseHost();
  130. //TODO 做单点登录,避免并发
  131. $groupStartIndex = TencentImGroup::getGroupIndex();
  132. $groupEndIndex = $groupStartIndex + $groupCount;
  133. for ($i = $groupStartIndex; $i < $groupEndIndex; $i++) {
  134. $item = [
  135. //TODO 新建群默认群主为APP管理员
  136. 'Owner_Account' => config('im.identifier'),
  137. 'Type' => TencentImGroup::IM_GROUP_RAW_TYPE_ChatRoom,
  138. 'Name' => (string)$i,
  139. ];
  140. $apiResult = $this->requestApi($baseApiHost, $item);
  141. self::verifyApiResult($apiResult);
  142. $item['GroupId'] = $apiResult['GroupId'];
  143. $item['groupIndex'] = $i;
  144. $params[] = $item;
  145. }
  146. unset($item);
  147. if (count($params) != $groupCount) {
  148. throw new TencentImGroupException('添加群组失败!');
  149. }
  150. $params = array_map(function ($value) {
  151. return [
  152. 'group_name' => $value['Name'],
  153. 'im_group_raw_id' => $value['GroupId'] ?? $value['groupIndex'],
  154. 'group_owner_user_id' => null,
  155. 'im_group_owner_raw_user_id' => $value['Owner_Account'],
  156. 'group_type' => null,
  157. 'im_group_raw_type' => $value['Type'],
  158. 'is_use' => TencentImGroup::UN_USE,
  159. 'bind_system_im_group_id' => null,
  160. 'group_index' => $value['groupIndex'] ?? 0,
  161. 'created_at' => Carbon::now(),
  162. 'updated_at' => Carbon::now(),
  163. ];
  164. }, $params);
  165. if (!TencentImGroup::insert($params)) {
  166. Log::log(date('Y-m-d H:i:s', time()) . '创建IM群组,写入系统记录失败', $params);
  167. throw new TencentImGroupException('创建IM群写入系统记录失败,请联系管理员检查');
  168. }
  169. DB::commit();
  170. return true;
  171. } catch (TencentImGroupException $e) {
  172. DB::rollBack();
  173. return ['error' => $e->getMessage()];
  174. } catch (TencentImException $e) {
  175. DB::rollBack();
  176. dd($e);
  177. return ['error' => $e->getMessage()];
  178. } catch (\Exception $e) {
  179. DB::rollBack();
  180. dd($e);
  181. return ['error' => $e->getMessage()];
  182. }
  183. }
  184. public function createGroup(array $createData)
  185. {
  186. $this->restApiName = self::TENCENT_REST_APIS['createGroup'];
  187. $baseApiHost = $this->getTencentImRestApiBaseHost();
  188. //TODO 做单点登录,避免并发
  189. $params = [
  190. //TODO 新建群默认群主为APP管理员
  191. 'Owner_Account' => config('im.identifier'),
  192. 'Type' => TencentImGroup::IM_GROUP_RAW_TYPE_ChatRoom,
  193. 'Name' => TencentImGroup::getGroupIndex(),
  194. ];
  195. $apiResult = $this->requestApi($baseApiHost, $params);
  196. dd($apiResult);
  197. }
  198. /**
  199. * 构建添加群数组
  200. * @param int $groupCount
  201. * @return mixed
  202. */
  203. private function generateCreateGroupData(int $groupCount)
  204. {
  205. $groupStartIndex = TencentImGroup::getGroupIndex();
  206. $groupEndIndex = $groupStartIndex + $groupCount;
  207. for ($i = $groupStartIndex; $i < $groupEndIndex; $i++) {
  208. $item = [
  209. //TODO 新建群默认群主为APP管理员
  210. 'Owner_Account' => config('im.identifier'),
  211. 'Type' => TencentImGroup::IM_GROUP_RAW_TYPE_ChatRoom,
  212. 'Name' => $i,
  213. ];
  214. $this->createGroup($item);
  215. $params[] = $item;
  216. }
  217. unset($item);
  218. return $params;
  219. }
  220. }