Commit f2b381e7 f2b381e7646a817596e7b6c078c42c8ced1e0964 by 杨俊

feat(master): 初始化

1 parent a4671c53
1 <?php
2
3 namespace App\Exceptions;
4
5 use Exception;
6
7 class TestCallbackException extends Exception
8 {
9 //
10 }
...@@ -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 }
......
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 }