初始化

main
gzydong 2020-11-27 19:48:41 +08:00
parent 0a4b140253
commit 77cd0103d7
11 changed files with 197 additions and 20 deletions

View File

@ -23,6 +23,8 @@ use App\Service\SocketFDService;
use App\Service\SocketRoomService; use App\Service\SocketRoomService;
/** /**
* 消息推送消费者队列
*
* @Consumer(name="聊天消息消费者",enable=true) * @Consumer(name="聊天消息消费者",enable=true)
*/ */
class ChatMessageConsumer extends ConsumerMessage class ChatMessageConsumer extends ConsumerMessage
@ -58,11 +60,24 @@ class ChatMessageConsumer extends ConsumerMessage
*/ */
private $socketRoomService; private $socketRoomService;
/**
* 推送的消息类型推送绑定事件方法
*/
const EVENTS = [ const EVENTS = [
// 聊天消息事件
'event_talk' => 'onConsumeTalk', 'event_talk' => 'onConsumeTalk',
// 键盘输入事件
'event_keyboard' => 'onConsumeKeyboard', 'event_keyboard' => 'onConsumeKeyboard',
// 用户在线状态事件
'event_online_status' => 'onConsumeOnlineStatus', 'event_online_status' => 'onConsumeOnlineStatus',
// 聊天消息推送事件
'event_revoke_talk' => 'onConsumeRevokeTalk', 'event_revoke_talk' => 'onConsumeRevokeTalk',
// 好友申请相关事件
'event_friend_apply' => 'onConsumeFriendApply'
]; ];
/** /**
@ -192,7 +207,7 @@ class ChatMessageConsumer extends ConsumerMessage
unset($notifyInfo, $userInfo, $membersIds); unset($notifyInfo, $userInfo, $membersIds);
break; break;
case 4://会话记录消息 case 4://会话记录消息
$forward = ['num' => 0,'list' => []]; $forward = ['num' => 0, 'list' => []];
$forwardInfo = ChatRecordsForward::where('record_id', $result->id)->first(['records_id', 'text']); $forwardInfo = ChatRecordsForward::where('record_id', $result->id)->first(['records_id', 'text']);
if ($forwardInfo) { if ($forwardInfo) {
@ -300,6 +315,7 @@ class ChatMessageConsumer extends ConsumerMessage
*/ */
public function onConsumeRevokeTalk(array $data, AMQPMessage $message) public function onConsumeRevokeTalk(array $data, AMQPMessage $message)
{ {
/** @var ChatRecord */
$record = ChatRecord::where('id', $data['data']['record_id'])->first(['id', 'source', 'user_id', 'receive_id']); $record = ChatRecord::where('id', $data['data']['record_id'])->first(['id', 'source', 'user_id', 'receive_id']);
$fds = []; $fds = [];
@ -329,4 +345,26 @@ class ChatMessageConsumer extends ConsumerMessage
return Result::ACK; return Result::ACK;
} }
/**
* 好友申请消息
*
* @param array $data
* @param AMQPMessage $message
*/
public function onConsumeFriendApply(array $data, AMQPMessage $message)
{
$fds = $this->socketFDService->findUserFds($data['data']['receive']);
$fds = array_unique($fds);
$server = server();
foreach ($fds as $fd) {
$fd = intval($fd);
if ($server->exist($fd)) {
$server->push($fd, json_encode(['event_friend_apply', $data['data']]));
}
}
return Result::ACK;
}
} }

View File

@ -18,7 +18,8 @@ class ChatMessageProducer extends ProducerMessage
'event_talk', 'event_talk',
'event_keyboard', 'event_keyboard',
'event_online_status', 'event_online_status',
'event_revoke_talk' 'event_revoke_talk',
'event_friend_apply'
]; ];
/** /**

View File

@ -23,6 +23,7 @@ class ServerStart extends ServerStartCallback
{ {
stdout_log()->info(sprintf('服务运行ID : %s', SERVER_RUN_ID)); stdout_log()->info(sprintf('服务运行ID : %s', SERVER_RUN_ID));
// 维护服务运行状态
$this->setTimeOut(); $this->setTimeOut();
Timer::tick(15000, function () { Timer::tick(15000, function () {
$this->setTimeOut(); $this->setTimeOut();

View File

@ -30,7 +30,7 @@ class ApplyNumCache
*/ */
public static function setInc(int $user_id) public static function setInc(int $user_id)
{ {
return redis()->hincrby(self::KEY, $user_id, 1); return redis()->hincrby(self::KEY, strval($user_id), 1);
} }
/** /**

View File

@ -4,12 +4,14 @@ declare(strict_types=1);
namespace App\Controller\Api\V1; namespace App\Controller\Api\V1;
use App\Service\ArticleService; use App\Service\ArticleService;
use App\Service\UploadService;
use App\Support\RedisLock; use App\Support\RedisLock;
use Hyperf\Di\Annotation\Inject; use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller; use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping; use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\HttpServer\Annotation\Middleware; use Hyperf\HttpServer\Annotation\Middleware;
use App\Middleware\JWTAuthMiddleware; use App\Middleware\JWTAuthMiddleware;
use Hyperf\Utils\Str;
/** /**
* Class ArticleController * Class ArticleController
@ -27,6 +29,12 @@ class ArticleController extends CController
*/ */
private $articleService; private $articleService;
/**
* @inject
* @var UploadService
*/
private $uploadService;
/** /**
* 获取笔记分类列表 * 获取笔记分类列表
* *
@ -313,7 +321,27 @@ class ArticleController extends CController
*/ */
public function uploadArticleImage() public function uploadArticleImage()
{ {
$file = $this->request->file('image');
if (!$file->isValid()) {
return $this->response->fail();
}
$ext = $file->getExtension();
if (!in_array($ext, ['jpg', 'png', 'jpeg', 'gif', 'webp'])) {
return $this->response->fail('图片格式错误目前仅支持jpg、png、jpeg、gif和webp');
}
//获取图片信息
$imgInfo = getimagesize($file->getRealPath());
$path = $this->uploadService->media($file, 'media/images/notes/', create_image_name($ext, $imgInfo[0], $imgInfo[1]));
if (!$path) {
return $this->response->fail();
}
return $this->response->success([
'save_path' => get_media_url($path)
]);
} }
/** /**
@ -409,8 +437,41 @@ class ArticleController extends CController
*/ */
public function uploadArticleAnnex() public function uploadArticleAnnex()
{ {
$params = $this->request->inputs(['article_id']);
$this->validate($params, [
'article_id' => 'required|integer|min:0'
]);
$file = $this->request->file('annex'); $file = $this->request->file('annex');
$file->isValid(); if (!$file->isValid()) {
return $this->response->fail('上传文件验证失败...');
}
$annex = [
'file_suffix' => $file->getExtension(),
'file_size' => $file->getSize(),
'save_dir' => '',
'original_name' => $file->getClientFilename()
];
$path = $this->uploadService->media($file,
'files/notes/' . date('Ymd'),
"[{$annex['file_suffix']}]" . uniqid() . Str::random(16) . '.' . 'tmp'
);
if (!$path) {
return $this->response->fail();
}
$annex['save_dir'] = $path;
$insId = $this->articleService->insertArticleAnnex($this->uid(), (int)$params['article_id'], $annex);
if (!$insId) {
return $this->response->fail('附件上传失败,请稍后再试...');
}
$annex['id'] = $insId;
return $this->response->success($annex, '笔记附件上传成功...');
} }
/** /**

View File

@ -183,7 +183,7 @@ class AuthController extends CController
/** /**
* 发送验证码 * 发送验证码
* *
* @RequestMapping(path="send-code", methods="post") * @RequestMapping(path="send-verify-code", methods="post")
* *
* @return \Psr\Http\Message\ResponseInterface * @return \Psr\Http\Message\ResponseInterface
*/ */

View File

@ -54,25 +54,32 @@ class GroupController extends CController
*/ */
public function create() public function create()
{ {
$params = $this->request->all(); $params = $this->request->inputs(['group_name', 'uids']);
$this->validate($params, [ $this->validate($params, [
'group_name' => 'required', 'group_name' => 'required',
'uids' => 'required', 'uids' => 'required',
]); ]);
$friend_ids = array_filter(explode(',', $params['uids'])); $friend_ids = array_filter(explode(',', $params['uids']));
$friend_ids = array_unique($friend_ids);
$user_id = $this->uid(); $user_id = $this->uid();
[$isTrue, $data] = $this->groupService->create($user_id, [ [$isTrue, $data] = $this->groupService->create($user_id, [
'name' => $params['group_name'], 'name' => $params['group_name'],
'avatar' => $params['avatar'] ?? '', 'avatar' => $params['avatar'] ?? '',
'profile' => $params['group_profile'] ?? '' 'profile' => $params['group_profile'] ?? ''
], array_unique($friend_ids)); ], $friend_ids);
if (!$isTrue) { if (!$isTrue) {
return $this->response->fail('创建群聊失败,请稍后再试...'); return $this->response->fail('创建群聊失败,请稍后再试...');
} }
// 加入聊天室
$friend_ids[] = $user_id;
foreach ($friend_ids as $uid) {
$this->socketRoomService->addRoomMember($uid, $data['group_id']);
}
// ...消息推送队列 // ...消息推送队列
$this->producer->produce( $this->producer->produce(
new ChatMessageProducer('event_talk', [ new ChatMessageProducer('event_talk', [
@ -134,7 +141,7 @@ class GroupController extends CController
return $this->response->fail('邀请好友加入群聊失败...'); return $this->response->fail('邀请好友加入群聊失败...');
} }
// 移出聊天室 // 加入聊天室
foreach ($uids as $uid) { foreach ($uids as $uid) {
$this->socketRoomService->addRoomMember($uid, $params['group_id']); $this->socketRoomService->addRoomMember($uid, $params['group_id']);
} }

View File

@ -18,6 +18,8 @@ use App\Support\SendEmailCode;
use App\Service\FriendService; use App\Service\FriendService;
use App\Service\UserService; use App\Service\UserService;
use App\Service\SocketFDService; use App\Service\SocketFDService;
use App\Amqp\Producer\ChatMessageProducer;
use Hyperf\Amqp\Producer;
/** /**
* Class UsersController * Class UsersController
@ -47,6 +49,12 @@ class UsersController extends CController
*/ */
private $socketFDService; private $socketFDService;
/**
* @Inject
* @var Producer
*/
private $producer;
/** /**
* 获取我的好友列表 * 获取我的好友列表
* *
@ -247,12 +255,27 @@ class UsersController extends CController
return $this->response->fail('用户不存在...'); return $this->response->fail('用户不存在...');
} }
if (!$this->friendService->addFriendApply($this->uid(), $params['friend_id'], $params['remarks'])) { $user_id = $this->uid();
if (!$this->friendService->addFriendApply($user_id, (int)$params['friend_id'], $params['remarks'])) {
return $this->response->fail('发送好友申请失败...'); return $this->response->fail('发送好友申请失败...');
} }
// 好友申请未读消息数自增
ApplyNumCache::setInc((int)$params['friend_id']);
//判断对方是否在线。如果在线发送消息通知 //判断对方是否在线。如果在线发送消息通知
// ... if ($this->socketFDService->isOnlineAll((int)$params['friend_id'])) {
$this->producer->produce(
new ChatMessageProducer('event_friend_apply', [
'sender' => $user_id,
'receive' => (int)$params['friend_id'],
'type' => 1,
'status' => 1,
'remark' => ''
])
);
}
return $this->response->success([], '发送好友申请成功...'); return $this->response->success([], '发送好友申请成功...');
} }
@ -270,15 +293,25 @@ class UsersController extends CController
'remarks' => 'present', 'remarks' => 'present',
]); ]);
$isTrue = $this->friendService->handleFriendApply($this->uid(), $params['apply_id'], $params['remarks']); $isTrue = $this->friendService->handleFriendApply($this->uid(), (int)$params['apply_id'], $params['remarks']);
//判断是否是同意添加好友 if (!$isTrue) {
if ($isTrue) { return $this->response->fail('处理失败...');
//... 推送处理消息
} }
return $isTrue //判断对方是否在线。如果在线发送消息通知
? $this->response->success([], '处理成功...') // if ($this->socketFDService->isOnlineAll((int)$params['friend_id'])) {
: $this->response->fail('处理失败...'); // $this->producer->produce(
// new ChatMessageProducer('event_friend_apply', [
// 'sender' => $user_id,
// 'receive' => (int)$params['friend_id'],
// 'type' => 1,
// 'status' => 1,
// 'remark' => ''
// ])
// );
// }
return $this->response->success([], '处理成功...');
} }
/** /**
@ -293,7 +326,7 @@ class UsersController extends CController
'apply_id' => 'required|integer', 'apply_id' => 'required|integer',
]); ]);
$isTrue = $this->friendService->delFriendApply($this->uid(), $params['apply_id']); $isTrue = $this->friendService->delFriendApply($this->uid(), (int)$params['apply_id']);
return $isTrue return $isTrue
? $this->response->success([], '删除成功...') ? $this->response->success([], '删除成功...')
: $this->response->fail('删除失败...'); : $this->response->fail('删除失败...');

View File

@ -35,7 +35,16 @@ class UsersFriend extends BaseModel
* *
* @var array * @var array
*/ */
protected $fillable = []; protected $fillable = [
'user1',
'user2',
'user1_remark',
'user2_remark',
'active',
'status',
'agree_time',
'created_at'
];
/** /**
* The attributes that should be cast to native types. * The attributes that should be cast to native types.

View File

@ -598,4 +598,31 @@ class ArticleService extends BaseService
return $info->delete(); return $info->delete();
} }
/**
* 添加笔记附件
*
* @param int $user_id 用户id
* @param int $article_id 笔记ID
* @param array $annex 笔记附件信息
* @return bool
*/
public function insertArticleAnnex(int $user_id, int $article_id, array $annex)
{
if (!Article::where('id', $article_id)->where('user_id', $user_id)->exists()) {
return false;
}
$result = ArticleAnnex::create([
'user_id' => $user_id,
'article_id' => $article_id,
'file_suffix' => $annex['file_suffix'],
'file_size' => $annex['file_size'],
'save_dir' => $annex['save_dir'],
'original_name' => $annex['original_name'],
'created_at' => date('Y-m-d H:i:s')
]);
return $result ? $result->id : false;
}
} }

View File

@ -39,7 +39,7 @@ class UploadService extends BaseService
public function media(UploadedFile $file, string $dir, string $filename) public function media(UploadedFile $file, string $dir, string $filename)
{ {
$save_dir = $this->driver($dir); $save_dir = $this->driver($dir);
$this->makeDirectory($dir); $this->makeDirectory($save_dir);
$file->moveTo(sprintf('%s/%s', $save_dir, $filename)); $file->moveTo(sprintf('%s/%s', $save_dir, $filename));
return $file->isMoved() ? sprintf('/%s/%s', trim($dir, '/'), $filename) : false; return $file->isMoved() ? sprintf('/%s/%s', trim($dir, '/'), $filename) : false;