优化代码

main
gzydong 2021-07-06 23:32:14 +08:00
parent cad36f0d41
commit 47862ee115
11 changed files with 148 additions and 170 deletions

View File

@ -57,10 +57,15 @@ ALTER TABLE `lar_chat_records_invite` RENAME `lar_talk_records_invite`;
ALTER TABLE `lar_chat_records_file` RENAME `lar_talk_records_file`;
# lar_users_friends 数据表同步SQL
ALTER TABLE `lar_users_friends` MODIFY `active` tinyint(3) unsigned DEFAULT '1' COMMENT '主动好友申请方[1:user1;2:user2;]';
ALTER TABLE `lar_users_friends` MODIFY `status` tinyint(3) DEFAULT '0' COMMENT '好友状态 [-1:双方均解除好友关系;0:正常;1:user1 已删除对方;2:user2 已删除对方;]';
ALTER TABLE `lar_users_friends` CHANGE `agree_time` `updated_at` datetime DEFAULT NULL COMMENT '更新时间';
UPDATE `lar_users_friends` SET `status` = CASE WHEN `status` = 0 THEN -1 WHEN `status` = 1 THEN 0 ELSE `status` END;
DELETE from `lar_users_friends` where `status` = 0;
ALTER TABLE `lar_users_friends` CHANGE `user1` `user_id` int(11) unsigned DEFAULT '0' COMMENT '用户id';
ALTER TABLE `lar_users_friends` CHANGE `user2` `friend_id` int(11) unsigned DEFAULT '0' COMMENT '好友id';
ALTER TABLE `lar_users_friends` CHANGE `user1_remark` `remark` varchar(20) DEFAULT '' COMMENT '好友的备注';
ALTER TABLE `lar_users_friends` MODIFY `status` tinyint(3) unsigned DEFAULT '0' COMMENT '好友状态 [0:否;1:是]';
ALTER TABLE `lar_users_friends` MODIFY `created_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间';
ALTER TABLE `lar_users_friends` CHANGE `agree_time` `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间';
ALTER TABLE `lar_users_friends` DROP COLUMN `active`;
ALTER TABLE `lar_users_friends` DROP COLUMN `user2_remark`;
# lar_users_friends_apply 数据表同步SQL
ALTER TABLE `lar_users_friends_apply` MODIFY `status` tinyint(4) unsigned DEFAULT '0' COMMENT '申请状态[0:等待处理;1:已同意;2:已拒绝;]';

View File

@ -23,6 +23,7 @@ use App\Constants\FileMediaType;
use App\Model\Group\Group;
use App\Model\Group\GroupMember;
use App\Model\TalkList;
use App\Model\UsersFriend;
use App\Service\TalkService;
use Hyperf\Command\Command as HyperfCommand;
use Hyperf\Command\Annotation\Command;
@ -177,5 +178,19 @@ class TestCommand extends HyperfCommand
//var_dump(FriendRemark::getInstance());
//var_dump(Group::isManager(2054,116));
UsersFriend::where('id', '<=', UsersFriend::max('id'))->chunk(100, function ($rows) {
foreach ($rows as $row) {
UsersFriend::create([
'user_id' => $row->friend_id,
'friend_id' => $row->user_id,
'remark' => $row->user2_remark,
'status' => 1,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
]);
}
});
}
}

View File

@ -10,6 +10,7 @@
namespace App\Controller\Api\V1;
use App\Model\UsersFriend;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
@ -56,11 +57,11 @@ class ContactsController extends CController
*/
public function getContacts()
{
$rows = $this->contactsService->getContacts($this->uid());
$rows = UsersFriend::getUserFriends($this->uid());
if ($rows) {
$runArr = ServerRunID::getInstance()->getServerRunIdAll();
foreach ($rows as $row) {
$row->is_online = $this->socketClientService->isOnlineAll($row->id, $runArr);
foreach ($rows as $k => $row) {
$rows[$k]['is_online'] = $this->socketClientService->isOnlineAll($row['id'], $runArr);
}
}

View File

@ -39,11 +39,11 @@ class EmoticonController extends CController
/**
* 获取用户表情包列表
* @RequestMapping(path="user-emoticon", methods="get")
* @RequestMapping(path="list", methods="get")
*
* @return ResponseInterface
*/
public function getUserEmoticon()
public function list()
{
$emoticonList = [];
$user_id = $this->uid();
@ -74,11 +74,11 @@ class EmoticonController extends CController
/**
* 获取系统表情包
* @RequestMapping(path="system-emoticon", methods="get")
* @RequestMapping(path="system", methods="get")
*
* @return ResponseInterface
*/
public function getSystemEmoticon()
public function system()
{
$items = Emoticon::get(['id', 'name', 'icon'])->toArray();
if ($items) {
@ -142,12 +142,12 @@ class EmoticonController extends CController
/**
* 自定义上传表情包
* @RequestMapping(path="upload-emoticon", methods="post")
* @RequestMapping(path="upload", methods="post")
*
* @param Filesystem $filesystem
* @return ResponseInterface
*/
public function uploadEmoticon(Filesystem $filesystem)
public function upload(Filesystem $filesystem)
{
$file = $this->request->file('emoticon');
if (!$file->isValid()) {

View File

@ -14,6 +14,7 @@ use App\Cache\LastMessage;
use App\Cache\UnreadTalk;
use App\Constants\TalkMsgType;
use App\Constants\TalkType;
use App\Support\UserRelation;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
@ -22,7 +23,6 @@ use App\Middleware\JWTAuthMiddleware;
use Psr\Http\Message\ResponseInterface;
use App\Model\User;
use App\Model\TalkList;
use App\Model\UsersFriend;
use App\Model\Group\Group;
use App\Service\TalkService;
@ -41,25 +41,6 @@ class TalkController extends CController
*/
public $talkService;
/**
* 判断是否是好友或者群成员关系
*
* @param int $user_id 用户ID
* @param int $receiver_id 接收者ID
* @param int $talk_type 对话类型
* @return bool
*/
private function isFriendOrGroupMember(int $user_id, int $receiver_id, int $talk_type)
{
if ($talk_type == TalkType::PRIVATE_CHAT) {
return UsersFriend::isFriend($user_id, $receiver_id, true);
} else if ($talk_type == TalkType::GROUP_CHAT) {
return Group::isMember($receiver_id, $user_id);
}
return false;
}
/**
* 获取用户对话列表
* @RequestMapping(path="list", methods="get")
@ -93,14 +74,12 @@ class TalkController extends CController
]);
$user_id = $this->uid();
if (!$this->isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) {
if (!UserRelation::isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) {
return $this->response->fail('暂不属于好友关系或群聊成员,无法进行聊天!');
}
$result = TalkList::addItem($user_id, $params['receiver_id'], $params['talk_type']);
if (!$result) {
return $this->response->fail('创建失败!');
}
if (!$result) return $this->response->fail('创建失败!');
$data = [
'id' => $result['id'],
@ -234,7 +213,7 @@ class TalkController extends CController
]);
$user_id = $this->uid();
if (!$this->isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) {
if (!UserRelation::isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) {
return $this->response->fail('暂不属于好友关系或群聊成员,无法查看聊天记录!');
}
@ -289,7 +268,7 @@ class TalkController extends CController
]);
$user_id = $this->uid();
if (!$this->isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) {
if (!UserRelation::isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) {
return $this->response->fail('暂不属于好友关系或群聊成员,无法查看聊天记录!');
}

View File

@ -10,8 +10,7 @@ use App\Constants\TalkMsgType;
use App\Constants\TalkType;
use App\Model\EmoticonItem;
use App\Model\FileSplitUpload;
use App\Model\Group\Group;
use App\Model\UsersFriend;
use App\Support\UserRelation;
use App\Service\EmoticonService;
use App\Service\TalkService;
use Hyperf\Di\Annotation\Inject;
@ -36,25 +35,6 @@ class TalkMessageController extends CController
*/
public $talkService;
/**
* 判断是否是好友或者群成员关系
*
* @param int $user_id 用户ID
* @param int $receiver_id 接收者ID
* @param int $talk_type 对话类型
* @return bool
*/
private function isFriendOrGroupMember(int $user_id, int $receiver_id, int $talk_type)
{
if ($talk_type == TalkType::PRIVATE_CHAT) {
return UsersFriend::isFriend($user_id, $receiver_id, true);
} else if ($talk_type == TalkType::GROUP_CHAT) {
return Group::isMember($receiver_id, $user_id);
}
return false;
}
/**
* 发送代码块消息
* @RequestMapping(path="code", methods="post")
@ -70,7 +50,7 @@ class TalkMessageController extends CController
]);
$user_id = $this->uid();
if (!$this->isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) {
if (!UserRelation::isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) {
return $this->response->fail('暂不属于好友关系或群聊成员,无法发送聊天消息!');
}
@ -85,9 +65,7 @@ class TalkMessageController extends CController
'code' => $params['code']
]);
if (!$record_id) {
return $this->response->fail('消息发送失败!');
}
if (!$record_id) return $this->response->fail('消息发送失败!');
// 消息推送队列
push_amqp(new ChatMessageProducer(SocketConstants::EVENT_TALK, [
@ -118,7 +96,7 @@ class TalkMessageController extends CController
]);
$user_id = $this->uid();
if (!$this->isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) {
if (!UserRelation::isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) {
return $this->response->fail('暂不属于好友关系或群聊成员,无法发送聊天消息!');
}
@ -153,9 +131,7 @@ class TalkMessageController extends CController
'original_name' => $file->getClientFilename(),
]);
if (!$record_id) {
return $this->response->fail('图片上传失败!');
}
if (!$record_id) return $this->response->fail('图片上传失败!');
// 消息推送队列
push_amqp(new ChatMessageProducer(SocketConstants::EVENT_TALK, [
@ -187,7 +163,7 @@ class TalkMessageController extends CController
]);
$user_id = $this->uid();
if (!$this->isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) {
if (!UserRelation::isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) {
return $this->response->fail('暂不属于好友关系或群聊成员,无法发送聊天消息!');
}
@ -217,9 +193,7 @@ class TalkMessageController extends CController
'save_dir' => $save_dir,
]);
if (!$record_id) {
return $this->response->fail('表情发送失败!');
}
if (!$record_id) return $this->response->fail('表情发送失败!');
// 消息推送队列
push_amqp(new ChatMessageProducer(SocketConstants::EVENT_TALK, [
@ -260,7 +234,7 @@ class TalkMessageController extends CController
]);
$user_id = $this->uid();
if (!$this->isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) {
if (!UserRelation::isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) {
return $this->response->fail('暂不属于好友关系或群聊成员,无法发送聊天消息!');
}
@ -268,9 +242,7 @@ class TalkMessageController extends CController
'url', 'file_suffix', 'file_size'
]);
if (!$emoticon) {
return $this->response->fail('表情不存在!');
}
if (!$emoticon) return $this->response->fail('表情不存在!');
$record_id = $this->talkService->createEmoticonMessage([
'talk_type' => $params['talk_type'],
@ -285,9 +257,7 @@ class TalkMessageController extends CController
'original_name' => '图片表情',
]);
if (!$record_id) {
return $this->response->fail('表情发送失败!');
}
if (!$record_id) return $this->response->fail('表情发送失败!');
// 消息推送队列
push_amqp(new ChatMessageProducer(SocketConstants::EVENT_TALK, [
@ -341,9 +311,7 @@ class TalkMessageController extends CController
$ids = $this->talkService->mergeForwardRecords($user_id, $params['receiver_id'], $params['talk_type'], $params['records_ids'], $items);
}
if (!$ids) {
return $this->response->fail('转发失败!');
}
if (!$ids) return $this->response->fail('转发失败!');
if ($receive_user_ids) {
foreach ($receive_user_ids as $v) {
@ -396,15 +364,13 @@ class TalkMessageController extends CController
]);
[$isTrue, $message,] = $this->talkService->revokeRecord($this->uid(), $params['record_id']);
if ($isTrue) {
if (!$isTrue) return $this->response->fail($message);
push_amqp(new ChatMessageProducer(SocketConstants::EVENT_REVOKE_TALK, [
'record_id' => $params['record_id']
]));
}
return $isTrue
? $this->response->success([], $message)
: $this->response->fail($message);
return $this->response->success([], $message);
}
/**

View File

@ -23,6 +23,8 @@ class TalkList extends BaseModel
{
protected $table = 'talk_list';
public $timestamps = true;
protected $fillable = [
'talk_type',
'user_id',

View File

@ -4,20 +4,16 @@ declare (strict_types=1);
namespace App\Model;
use Hyperf\DbConnection\Db;
/**
* 表情包收藏数据表模型
*
* @property int $id
* @property int $user1 用户1ID
* @property int $user2 用户2ID
* @property string $user1_remark 用户1好友备注
* @property string $user2_remark 用户2好友备注
* @property int $active 主动邀请方[1:user1;2:user2;]
* @property int $status 好友状态[1:好友状态;0:已解除好友关系]
* @property string $agree_time 成为好友时间
* @property int $user_id 用户ID
* @property int $friend_id 好友ID
* @property string $remark 好友备注
* @property int $status 好友状态
* @property string $created_at 创建时间
* @property string $updated_at 更新时间
* @package App\Model
*/
class UsersFriend extends BaseModel
@ -25,74 +21,58 @@ class UsersFriend extends BaseModel
protected $table = 'users_friends';
protected $fillable = [
'user1',
'user2',
'user1_remark',
'user2_remark',
'active',
'user_id',
'friend_id',
'status',
'agree_time',
'created_at'
'created_at',
'updated_at',
];
protected $casts = [
'id' => 'integer',
'user1' => 'integer',
'user2' => 'integer',
'active' => 'integer',
'user_id' => 'integer',
'friend_id' => 'integer',
'status' => 'integer',
'created_at' => 'datetime'
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
/**
* 获取用户所有好友
*
* @param int $uid 用户ID
* @return mixed
* @param int $user_id 用户ID
* @return array
*/
public static function getUserFriends(int $uid)
public static function getUserFriends(int $user_id)
{
$prefix = config('databases.default.prefix');
$sql = <<<SQL
SELECT users.id,users.nickname,users.avatar,users.motto,users.gender,tmp_table.friend_remark from {$prefix}users users
INNER join
(
SELECT id as rid,user2 as uid,user1_remark as friend_remark from {$prefix}users_friends where user1 = {$uid} and `status` = 0
UNION all
SELECT id as rid,user1 as uid,user2_remark as friend_remark from {$prefix}users_friends where user2 = {$uid} and `status` = 0
) tmp_table on tmp_table.uid = users.id
SQL;
$rows = Db::select($sql);
array_walk($rows, function (&$item) {
$item = (array)$item;
});
return $rows;
return UsersFriend::leftJoin('users', 'users.id', '=', 'users_friends.friend_id')
->where('user_id', $user_id)->where('users_friends.status', 1)
->get([
'users.id',
'users.nickname',
'users.avatar',
'users.motto',
'users.gender',
'users_friends.remark as friend_remark',
])->toArray();
}
/**
* 判断用户之间是否存在好友关系
*
* @param int $user_id1 用户1
* @param int $user_id2 用户2
* @param bool $cache 是否读取缓存
* @param int $user_id 用户ID
* @param int $friend_id 好友ID
* @param bool $is_cache 是否允许读取缓存
* @return bool
*/
public static function isFriend(int $user_id1, int $user_id2, bool $cache = false)
public static function isFriend(int $user_id, int $friend_id, bool $is_cache = false)
{
// 比较大小交换位置
if ($user_id1 > $user_id2) {
[$user_id1, $user_id2] = [$user_id2, $user_id1];
}
$cacheKey = "good_friends:{$user_id1}_$user_id2";
if ($cache && redis()->get($cacheKey)) {
$cacheKey = "good_friends:{$user_id}_{$friend_id}";
if ($is_cache && redis()->get($cacheKey)) {
return true;
}
$isTrue = self::query()->where('user1', $user_id1)->where('user2', $user_id2)->where('status', 0)->exists();
$isTrue = self::query()->where('user_id', $user_id)->where('friend_id', $friend_id)->where('status', 1)->exists();
if ($isTrue) {
redis()->setex($cacheKey, 60 * 5, 1);
}
@ -108,10 +88,6 @@ SQL;
*/
public static function getFriendIds(int $user_id)
{
$prefix = config('databases.default.prefix');
$sql = "SELECT user2 as uid from {$prefix}users_friends where user1 = {$user_id} and `status` = 0 UNION all SELECT user1 as uid from {$prefix}users_friends where user2 = {$user_id} and `status` = 0";
return array_map(function ($item) {
return $item->uid;
}, Db::select($sql));
return UsersFriend::where('user_id', $user_id)->where('status', 1)->pluck('friend_id')->toArray();
}
}

View File

@ -35,6 +35,8 @@ class ContactsService extends BaseService
*/
public function getContacts(int $user_id): array
{
$prefix = config('databases.default.prefix');
$sql = <<<SQL
SELECT users.id,users.nickname,users.avatar,users.motto,users.gender,tmp_table.friend_remark from {$prefix}users users

View File

@ -26,6 +26,24 @@ class TalkService extends BaseService
{
use PagingTrait;
/**
* 获取好友备注
*
* @param int $user_id 用户ID
* @param int $friend_id 好友ID
* @return string
*/
public function getFriendRemark(int $user_id, int $friend_id)
{
$remark = FriendRemark::getInstance()->read($user_id, $friend_id);
if ($remark) return $remark;
$remark = UsersFriend::where('user_id', $user_id)->where('friend_id', $friend_id)->value('remark');
if ($remark) FriendRemark::getInstance()->save($user_id, $friend_id, $remark);
return (string)$remark;
}
/**
* 获取用户的聊天列表
*
@ -70,27 +88,14 @@ class TalkService extends BaseService
$data['is_top'] = $item['is_top'];
$data['is_disturb'] = $item['is_disturb'];
$data['msg_text'] = '......';
$data['updated_at'] = $item['updated_at'];
$data['updated_at'] = $item['updated_at'] ?: '2020-01-01 00:00:00';
if ($item['talk_type'] == TalkType::PRIVATE_CHAT) {
$data['name'] = $item['nickname'];
$data['avatar'] = $item['user_avatar'];
$data['unread_num'] = UnreadTalk::getInstance()->read($item['receiver_id'], $user_id);
$data['is_online'] = $socketFDService->isOnlineAll($item['receiver_id'], $runIdAll);
$remark = FriendRemark::getInstance()->read($user_id, $item['receiver_id']);
if ($remark) {
$data['remark_name'] = $remark;
} else {
$info = UsersFriend::select('user1', 'user2', 'user1_remark', 'user2_remark')
->where('user1', ($user_id < $item['receiver_id']) ? $user_id : $item['receiver_id'])
->where('user2', ($user_id < $item['receiver_id']) ? $item['receiver_id'] : $user_id)->first();
if ($info) {
$data['remark_name'] = $info->user1 == $item['receiver_id'] ? $info->user2_remark : $info->user1_remark;
FriendRemark::getInstance()->save($user_id, (int)$item['receiver_id'], $data['remark_name']);
}
}
$data['remark_name'] = $this->getFriendRemark($user_id, (int)$item['receiver_id']);
} else {
$data['name'] = strval($item['group_name']);
$data['avatar'] = $item['group_avatar'];
@ -100,8 +105,6 @@ class TalkService extends BaseService
if ($records) {
$data['msg_text'] = $records['text'];
$data['updated_at'] = $records['created_at'];
} else {
$data['updated_at'] = '2020-01-01 00:00:00';
}
return $data;

View File

@ -0,0 +1,29 @@
<?php
namespace App\Support;
use App\Constants\TalkType;
use App\Model\Group\Group;
use App\Model\UsersFriend;
class UserRelation
{
/**
* 判断是否是好友或者群成员关系
*
* @param int $user_id 用户ID
* @param int $receiver_id 接收者ID
* @param int $talk_type 对话类型
* @return bool
*/
public static function isFriendOrGroupMember(int $user_id, int $receiver_id, int $talk_type)
{
if ($talk_type == TalkType::PRIVATE_CHAT) {
return UsersFriend::isFriend($user_id, $receiver_id, true);
} else if ($talk_type == TalkType::GROUP_CHAT) {
return Group::isMember($receiver_id, $user_id);
}
return false;
}
}