feat(master): 初始化
Showing
4 changed files
with
172 additions
and
8 deletions
app/Exceptions/TestCallbackException.php
0 → 100644
| ... | @@ -2,13 +2,12 @@ | ... | @@ -2,13 +2,12 @@ |
| 2 | 2 | ||
| 3 | namespace App\Helpers; | 3 | namespace App\Helpers; |
| 4 | 4 | ||
| 5 | use Arr; | ||
| 6 | use GuzzleHttp\Promise\PromiseInterface; | 5 | use GuzzleHttp\Promise\PromiseInterface; |
| 7 | use Illuminate\Http\Client\Response; | 6 | use Illuminate\Http\Client\Response; |
| 8 | use Illuminate\Support\Facades\App; | 7 | use Illuminate\Support\Arr; |
| 9 | use Illuminate\Support\Facades\Http; | 8 | use Illuminate\Support\Facades\Http; |
| 10 | use Illuminate\Support\Facades\Log; | 9 | use Illuminate\Support\Facades\Log; |
| 11 | use Str; | 10 | use Illuminate\Support\Str; |
| 12 | use Tencent\TLSSigAPIv2; | 11 | use Tencent\TLSSigAPIv2; |
| 13 | 12 | ||
| 14 | class IMHelper | 13 | class IMHelper |
| ... | @@ -76,7 +75,7 @@ public static function send(string $uri, array $data): PromiseInterface|Response | ... | @@ -76,7 +75,7 @@ public static function send(string $uri, array $data): PromiseInterface|Response |
| 76 | $result = Http::asJson()->post($host, $data); | 75 | $result = Http::asJson()->post($host, $data); |
| 77 | 76 | ||
| 78 | 77 | ||
| 79 | Log::channel('jpush')->info('IM ' . $uri . ' status[' . $result->json('ActionStatus') . ']:', [ | 78 | Log::channel('im')->info('IM ' . $uri . ' status[' . $result->json('ActionStatus') . ']:', [ |
| 80 | 'uri' => $uri, 'data' => $data, 'result' => $result->json() | 79 | 'uri' => $uri, 'data' => $data, 'result' => $result->json() |
| 81 | ]); | 80 | ]); |
| 82 | 81 | ||
| ... | @@ -89,7 +88,7 @@ public static function send(string $uri, array $data): PromiseInterface|Response | ... | @@ -89,7 +88,7 @@ public static function send(string $uri, array $data): PromiseInterface|Response |
| 89 | */ | 88 | */ |
| 90 | public static function userKeyToAccount(int|string $userId): string | 89 | public static function userKeyToAccount(int|string $userId): string |
| 91 | { | 90 | { |
| 92 | return (App::isProduction() ? '' : 'test') . $userId; | 91 | return config('services.im.prefix') . $userId; |
| 93 | } | 92 | } |
| 94 | 93 | ||
| 95 | /** | 94 | /** |
| ... | @@ -98,7 +97,7 @@ public static function userKeyToAccount(int|string $userId): string | ... | @@ -98,7 +97,7 @@ public static function userKeyToAccount(int|string $userId): string |
| 98 | */ | 97 | */ |
| 99 | public static function accountToUserKey(string $account): string | 98 | public static function accountToUserKey(string $account): string |
| 100 | { | 99 | { |
| 101 | return Str::replace('test', '', $account); | 100 | return Str::replace(config('services.im.prefix'), '', $account); |
| 102 | } | 101 | } |
| 103 | 102 | ||
| 104 | /** | 103 | /** |
| ... | @@ -200,7 +199,7 @@ public static function rollbackChatMessage(string $form, string $to, string $msg | ... | @@ -200,7 +199,7 @@ public static function rollbackChatMessage(string $form, string $to, string $msg |
| 200 | */ | 199 | */ |
| 201 | public static function checkAccount(array $account): PromiseInterface|Response | 200 | public static function checkAccount(array $account): PromiseInterface|Response |
| 202 | { | 201 | { |
| 203 | return self::send('/v4/im_open_login_svc/account_check ', [ | 202 | return self::send('v4/im_open_login_svc/account_check ', [ |
| 204 | 'CheckItem' => Arr::map($account, static fn($item) => ['UserID' => self::userKeyToAccount($item)]) | 203 | 'CheckItem' => Arr::map($account, static fn($item) => ['UserID' => self::userKeyToAccount($item)]) |
| 205 | ]); | 204 | ]); |
| 206 | } | 205 | } |
| ... | @@ -211,7 +210,7 @@ public static function checkAccount(array $account): PromiseInterface|Response | ... | @@ -211,7 +210,7 @@ public static function checkAccount(array $account): PromiseInterface|Response |
| 211 | */ | 210 | */ |
| 212 | public static function importSingleAccount(string $userId, string|array $name, string $avatar = ''): PromiseInterface|Response | 211 | public static function importSingleAccount(string $userId, string|array $name, string $avatar = ''): PromiseInterface|Response |
| 213 | { | 212 | { |
| 214 | return self::send('/v4/im_open_login_svc/account_import', [ | 213 | return self::send('v4/im_open_login_svc/account_import', [ |
| 215 | 'UserID' => self::userKeyToAccount($userId), | 214 | 'UserID' => self::userKeyToAccount($userId), |
| 216 | 'Nick' => is_array($name) ? json_encode($name, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE) : $name, | 215 | 'Nick' => is_array($name) ? json_encode($name, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE) : $name, |
| 217 | 'FaceUrl' => $avatar | 216 | 'FaceUrl' => $avatar |
| ... | @@ -225,4 +224,38 @@ public static function updateSingleAccountInfo(string $userId, array $profileIte | ... | @@ -225,4 +224,38 @@ public static function updateSingleAccountInfo(string $userId, array $profileIte |
| 225 | { | 224 | { |
| 226 | return self::send('v4/profile/portrait_set', ['From_Account' => self::userKeyToAccount($userId), 'ProfileItem' => $profileItem]); | 225 | return self::send('v4/profile/portrait_set', ['From_Account' => self::userKeyToAccount($userId), 'ProfileItem' => $profileItem]); |
| 227 | } | 226 | } |
| 227 | |||
| 228 | |||
| 229 | /** | ||
| 230 | * @throws \Exception | ||
| 231 | */ | ||
| 232 | public static function createGroup(string $userId, array $data = []): PromiseInterface|Response | ||
| 233 | { | ||
| 234 | return self::send('v4/group_open_http_svc/create_group', [ | ||
| 235 | 'Type' => 'Public', | ||
| 236 | 'GroupId' => config('services.im.prefix') . now()->format('YmdHisu'), | ||
| 237 | 'Owner_Account' => self::userKeyToAccount($userId), | ||
| 238 | ...$data | ||
| 239 | ]); | ||
| 240 | } | ||
| 241 | |||
| 242 | |||
| 243 | /** | ||
| 244 | * @throws \Random\RandomException | ||
| 245 | * @throws \Exception | ||
| 246 | */ | ||
| 247 | public static function sendGroupMessage(string $groupId, array $data): PromiseInterface|Response | ||
| 248 | { | ||
| 249 | return self::send('v4/group_open_http_svc/send_group_msg', ["GroupId" => $groupId, "Random" => random_int(0, 4294967295),] + $data); | ||
| 250 | } | ||
| 251 | |||
| 252 | /** | ||
| 253 | * @param string $groupId | ||
| 254 | * @return \GuzzleHttp\Promise\PromiseInterface|\Illuminate\Http\Client\Response | ||
| 255 | * @throws \Exception | ||
| 256 | */ | ||
| 257 | public static function deleteGroup(string $groupId): PromiseInterface|Response | ||
| 258 | { | ||
| 259 | return self::send('v4/group_open_http_svc/destroy_group', ['GroupId' => $groupId]); | ||
| 260 | } | ||
| 228 | } | 261 | } | ... | ... |
This diff is collapsed.
Click to expand it.
app/Jobs/ImMessageSaveJob.php
0 → 100644
| 1 | <?php | ||
| 2 | |||
| 3 | namespace App\Jobs; | ||
| 4 | |||
| 5 | use App\Helpers\IMHelper; | ||
| 6 | use Arr; | ||
| 7 | use Carbon\Carbon; | ||
| 8 | use DB; | ||
| 9 | use Illuminate\Bus\Queueable; | ||
| 10 | use Illuminate\Contracts\Queue\ShouldQueue; | ||
| 11 | use Illuminate\Foundation\Bus\Dispatchable; | ||
| 12 | use Illuminate\Queue\InteractsWithQueue; | ||
| 13 | use Illuminate\Queue\SerializesModels; | ||
| 14 | |||
| 15 | class ImMessageSaveJob implements ShouldQueue | ||
| 16 | { | ||
| 17 | use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; | ||
| 18 | |||
| 19 | public array $data; | ||
| 20 | |||
| 21 | /** | ||
| 22 | * Create a new job instance. | ||
| 23 | * | ||
| 24 | * @return void | ||
| 25 | */ | ||
| 26 | public function __construct(array $data) | ||
| 27 | { | ||
| 28 | $this->data = $data; | ||
| 29 | } | ||
| 30 | |||
| 31 | /** | ||
| 32 | * Execute the job. | ||
| 33 | * | ||
| 34 | * @return void | ||
| 35 | * @throws \JsonException | ||
| 36 | */ | ||
| 37 | public function handle(): void | ||
| 38 | { | ||
| 39 | $data = []; | ||
| 40 | $fromIm = $this->data['From_Account']; | ||
| 41 | $from = IMHelper::accountToUserKey($fromIm); | ||
| 42 | $toIm = $this->data['To_Account']; | ||
| 43 | $to = IMHelper::accountToUserKey($this->data['To_Account']); | ||
| 44 | $time = Carbon::createFromTimestamp($this->data['MsgTime'])->toDateTimeString(); | ||
| 45 | |||
| 46 | foreach ($this->data['MsgBody'] as $value) { | ||
| 47 | if ($value['MsgType'] === 'TIMCustomElem') { | ||
| 48 | $value['MsgContent']['Data'] = json_decode($value['MsgContent']['Data'], true, 512, JSON_THROW_ON_ERROR); | ||
| 49 | } | ||
| 50 | |||
| 51 | $data[] = array_merge([ | ||
| 52 | 'from' => $from, 'from_im' => $fromIm, 'to' => $to, 'to_im' => $toIm, 'created_at' => $time, 'updated_at' => $time, | ||
| 53 | 'msg_key' => Arr::get($this->data, 'MsgKey', ''), | ||
| 54 | 'content' => json_encode($value, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), | ||
| 55 | ], $this->formatMsg($value)); | ||
| 56 | } | ||
| 57 | |||
| 58 | DB::table('im_messags')->insert($data); | ||
| 59 | } | ||
| 60 | |||
| 61 | /** | ||
| 62 | * @param array{MsgType:string,MsgContent:array} $msgItem | ||
| 63 | * @return array{type:int,value:string} | ||
| 64 | */ | ||
| 65 | public function formatMsg(array $msgItem): array | ||
| 66 | { | ||
| 67 | return match ($msgItem['MsgType']) { | ||
| 68 | 'TIMTextElem' => ['type' => 1, 'value' => Arr::get($msgItem, 'MsgContent.Text', '')], | ||
| 69 | 'TIMImageElem' => ['type' => 2, 'value' => Arr::get($msgItem, 'MsgContent.ImageInfoArray.0.URL', '')], | ||
| 70 | 'TIMVideoFileElem' => ['type' => 3, 'value' => Arr::get($msgItem, 'MsgContent.VideoUrl', '')], | ||
| 71 | 'TIMFileElem' => ['type' => 4, 'value' => Arr::get($msgItem, 'MsgContent.Url', '')], | ||
| 72 | 'TIMCustomElem' => $this->formatMsgCustomData($msgItem['MsgContent']['Data']), | ||
| 73 | 'TIMFaceElem' => ['type' => 17, 'value' => Arr::get($msgItem, 'MsgContent')], | ||
| 74 | default => ['type' => 18, 'value' => '其他消息'], | ||
| 75 | }; | ||
| 76 | } | ||
| 77 | |||
| 78 | /** | ||
| 79 | * @param array $data | ||
| 80 | * @return array | ||
| 81 | */ | ||
| 82 | public function formatMsgCustomData(array $data): array | ||
| 83 | { | ||
| 84 | switch ($data['businessID']) { | ||
| 85 | case 'invite_team': | ||
| 86 | return ['type' => 5, 'value' => '邀请入队']; | ||
| 87 | case 'apply_team': | ||
| 88 | return ['type' => 6, 'value' => '申请入队']; | ||
| 89 | case 'custom_song': | ||
| 90 | return ['type' => 9, 'value' => Arr::get($data, 'id', 0)]; | ||
| 91 | case 'exit_team': | ||
| 92 | return ['type' => 10, 'value' => '成员退出团队申请']; | ||
| 93 | case 'invite_brand': | ||
| 94 | return ['type' => 19, 'value' => '邀请成员加入厂牌']; | ||
| 95 | case 'exit_brand': | ||
| 96 | return ['type' => 23, 'value' => '成员申请退出厂牌']; | ||
| 97 | case 'system_notice': | ||
| 98 | return ['type' => 24, 'value' => '系统消息']; | ||
| 99 | case 'invite_tip': | ||
| 100 | if (in_array($data['tipStatus'], [1, 6], false)) { | ||
| 101 | return ['type' => 7, 'value' => '同意邀请或申请']; | ||
| 102 | } | ||
| 103 | return match ($data['tipStatus']) { | ||
| 104 | '3' => ['type' => 11, 'value' => '队长同意成员退出'], | ||
| 105 | '8' => ['type' => 12, 'value' => '到期自动退出团队'], | ||
| 106 | '5' => ['type' => 13, 'value' => '队长将成员从团队移出'], | ||
| 107 | '2' => ['type' => 14, 'value' => '拒绝团队邀请'], | ||
| 108 | '4' => ['type' => 15, 'value' => '取消退出团队'], | ||
| 109 | '7' => ['type' => 16, 'value' => '拒绝用户申请'], | ||
| 110 | '12' => ['type' => 20, 'value' => '同意厂牌邀请'], | ||
| 111 | '13' => ['type' => 21, 'value' => '拒绝厂牌邀请'], | ||
| 112 | '11' => ['type' => 22, 'value' => '将成员移出厂牌'], | ||
| 113 | '9' => ['type' => 24, 'value' => '成员取消退出厂牌'], | ||
| 114 | '10' => ['type' => 25, 'value' => '厂牌管理员同意退出'], | ||
| 115 | default => ['type' => 18, 'value' => '其他消息'] | ||
| 116 | }; | ||
| 117 | default: | ||
| 118 | return ['type' => 18, 'value' => '其他消息']; | ||
| 119 | } | ||
| 120 | } | ||
| 121 | } |
-
Please register or sign in to post a comment