ImMessageSaveJob.php 4.8 KB
<?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' => '其他消息'];
        }
    }
}