Commit f2b381e7 f2b381e7646a817596e7b6c078c42c8ced1e0964 by 杨俊

feat(master): 初始化

1 parent a4671c53
<?php
namespace App\Exceptions;
use Exception;
class TestCallbackException extends Exception
{
//
}
......@@ -2,13 +2,12 @@
namespace App\Helpers;
use Arr;
use GuzzleHttp\Promise\PromiseInterface;
use Illuminate\Http\Client\Response;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Str;
use Illuminate\Support\Str;
use Tencent\TLSSigAPIv2;
class IMHelper
......@@ -76,7 +75,7 @@ public static function send(string $uri, array $data): PromiseInterface|Response
$result = Http::asJson()->post($host, $data);
Log::channel('jpush')->info('IM ' . $uri . ' status[' . $result->json('ActionStatus') . ']:', [
Log::channel('im')->info('IM ' . $uri . ' status[' . $result->json('ActionStatus') . ']:', [
'uri' => $uri, 'data' => $data, 'result' => $result->json()
]);
......@@ -89,7 +88,7 @@ public static function send(string $uri, array $data): PromiseInterface|Response
*/
public static function userKeyToAccount(int|string $userId): string
{
return (App::isProduction() ? '' : 'test') . $userId;
return config('services.im.prefix') . $userId;
}
/**
......@@ -98,7 +97,7 @@ public static function userKeyToAccount(int|string $userId): string
*/
public static function accountToUserKey(string $account): string
{
return Str::replace('test', '', $account);
return Str::replace(config('services.im.prefix'), '', $account);
}
/**
......@@ -200,7 +199,7 @@ public static function rollbackChatMessage(string $form, string $to, string $msg
*/
public static function checkAccount(array $account): PromiseInterface|Response
{
return self::send('/v4/im_open_login_svc/account_check ', [
return self::send('v4/im_open_login_svc/account_check ', [
'CheckItem' => Arr::map($account, static fn($item) => ['UserID' => self::userKeyToAccount($item)])
]);
}
......@@ -211,7 +210,7 @@ public static function checkAccount(array $account): PromiseInterface|Response
*/
public static function importSingleAccount(string $userId, string|array $name, string $avatar = ''): PromiseInterface|Response
{
return self::send('/v4/im_open_login_svc/account_import', [
return self::send('v4/im_open_login_svc/account_import', [
'UserID' => self::userKeyToAccount($userId),
'Nick' => is_array($name) ? json_encode($name, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE) : $name,
'FaceUrl' => $avatar
......@@ -225,4 +224,38 @@ public static function updateSingleAccountInfo(string $userId, array $profileIte
{
return self::send('v4/profile/portrait_set', ['From_Account' => self::userKeyToAccount($userId), 'ProfileItem' => $profileItem]);
}
/**
* @throws \Exception
*/
public static function createGroup(string $userId, array $data = []): PromiseInterface|Response
{
return self::send('v4/group_open_http_svc/create_group', [
'Type' => 'Public',
'GroupId' => config('services.im.prefix') . now()->format('YmdHisu'),
'Owner_Account' => self::userKeyToAccount($userId),
...$data
]);
}
/**
* @throws \Random\RandomException
* @throws \Exception
*/
public static function sendGroupMessage(string $groupId, array $data): PromiseInterface|Response
{
return self::send('v4/group_open_http_svc/send_group_msg', ["GroupId" => $groupId, "Random" => random_int(0, 4294967295),] + $data);
}
/**
* @param string $groupId
* @return \GuzzleHttp\Promise\PromiseInterface|\Illuminate\Http\Client\Response
* @throws \Exception
*/
public static function deleteGroup(string $groupId): PromiseInterface|Response
{
return self::send('v4/group_open_http_svc/destroy_group', ['GroupId' => $groupId]);
}
}
......
<?php
namespace App\Jobs;
use App\Helpers\IMHelper;
use Arr;
use Carbon\Carbon;
use DB;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ImMessageSaveJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public array $data;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct(array $data)
{
$this->data = $data;
}
/**
* Execute the job.
*
* @return void
* @throws \JsonException
*/
public function handle(): void
{
$data = [];
$fromIm = $this->data['From_Account'];
$from = IMHelper::accountToUserKey($fromIm);
$toIm = $this->data['To_Account'];
$to = IMHelper::accountToUserKey($this->data['To_Account']);
$time = Carbon::createFromTimestamp($this->data['MsgTime'])->toDateTimeString();
foreach ($this->data['MsgBody'] as $value) {
if ($value['MsgType'] === 'TIMCustomElem') {
$value['MsgContent']['Data'] = json_decode($value['MsgContent']['Data'], true, 512, JSON_THROW_ON_ERROR);
}
$data[] = array_merge([
'from' => $from, 'from_im' => $fromIm, 'to' => $to, 'to_im' => $toIm, 'created_at' => $time, 'updated_at' => $time,
'msg_key' => Arr::get($this->data, 'MsgKey', ''),
'content' => json_encode($value, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
], $this->formatMsg($value));
}
DB::table('im_messags')->insert($data);
}
/**
* @param array{MsgType:string,MsgContent:array} $msgItem
* @return array{type:int,value:string}
*/
public function formatMsg(array $msgItem): array
{
return match ($msgItem['MsgType']) {
'TIMTextElem' => ['type' => 1, 'value' => Arr::get($msgItem, 'MsgContent.Text', '')],
'TIMImageElem' => ['type' => 2, 'value' => Arr::get($msgItem, 'MsgContent.ImageInfoArray.0.URL', '')],
'TIMVideoFileElem' => ['type' => 3, 'value' => Arr::get($msgItem, 'MsgContent.VideoUrl', '')],
'TIMFileElem' => ['type' => 4, 'value' => Arr::get($msgItem, 'MsgContent.Url', '')],
'TIMCustomElem' => $this->formatMsgCustomData($msgItem['MsgContent']['Data']),
'TIMFaceElem' => ['type' => 17, 'value' => Arr::get($msgItem, 'MsgContent')],
default => ['type' => 18, 'value' => '其他消息'],
};
}
/**
* @param array $data
* @return array
*/
public function formatMsgCustomData(array $data): array
{
switch ($data['businessID']) {
case 'invite_team':
return ['type' => 5, 'value' => '邀请入队'];
case 'apply_team':
return ['type' => 6, 'value' => '申请入队'];
case 'custom_song':
return ['type' => 9, 'value' => Arr::get($data, 'id', 0)];
case 'exit_team':
return ['type' => 10, 'value' => '成员退出团队申请'];
case 'invite_brand':
return ['type' => 19, 'value' => '邀请成员加入厂牌'];
case 'exit_brand':
return ['type' => 23, 'value' => '成员申请退出厂牌'];
case 'system_notice':
return ['type' => 24, 'value' => '系统消息'];
case 'invite_tip':
if (in_array($data['tipStatus'], [1, 6], false)) {
return ['type' => 7, 'value' => '同意邀请或申请'];
}
return match ($data['tipStatus']) {
'3' => ['type' => 11, 'value' => '队长同意成员退出'],
'8' => ['type' => 12, 'value' => '到期自动退出团队'],
'5' => ['type' => 13, 'value' => '队长将成员从团队移出'],
'2' => ['type' => 14, 'value' => '拒绝团队邀请'],
'4' => ['type' => 15, 'value' => '取消退出团队'],
'7' => ['type' => 16, 'value' => '拒绝用户申请'],
'12' => ['type' => 20, 'value' => '同意厂牌邀请'],
'13' => ['type' => 21, 'value' => '拒绝厂牌邀请'],
'11' => ['type' => 22, 'value' => '将成员移出厂牌'],
'9' => ['type' => 24, 'value' => '成员取消退出厂牌'],
'10' => ['type' => 25, 'value' => '厂牌管理员同意退出'],
default => ['type' => 18, 'value' => '其他消息']
};
default:
return ['type' => 18, 'value' => '其他消息'];
}
}
}