初始化
parent
7515097a33
commit
93a50abb3a
|
@ -77,7 +77,7 @@ class ChatMessageConsumer extends ConsumerMessage
|
|||
|
||||
$server = server();
|
||||
foreach ($server->connections as $fd) {
|
||||
if ($server->isEstablished($fd)) {
|
||||
if ($server->exist($fd) && $server->isEstablished($fd)) {
|
||||
$server->push($fd, "Recv: 我是后台进程 [{$data['message']}]");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,25 @@ use Hyperf\HttpServer\Annotation\Controller;
|
|||
use Hyperf\HttpServer\Annotation\RequestMapping;
|
||||
use Hyperf\HttpServer\Annotation\Middleware;
|
||||
use Phper666\JWTAuth\Middleware\JWTAuthMiddleware;
|
||||
use App\Constants\ResponseCode;
|
||||
use App\Helper\Hash;
|
||||
use App\Model\User;
|
||||
use App\Model\UsersChatList;
|
||||
use App\Model\UsersFriend;
|
||||
use App\Service\SmsCodeService;
|
||||
use App\Support\SendEmailCode;
|
||||
use App\Service\FriendService;
|
||||
use App\Service\UserService;
|
||||
use App\Service\SocketFDService;
|
||||
|
||||
/**
|
||||
* Class UsersController
|
||||
*
|
||||
* @Controller(path="/api/v1/users")
|
||||
* @Middleware(JWTAuthMiddleware::class)
|
||||
*
|
||||
* @package App\Controller\Api\V1
|
||||
*/
|
||||
class UsersController extends CController
|
||||
{
|
||||
/**
|
||||
|
@ -25,107 +41,284 @@ class UsersController extends CController
|
|||
protected $userService;
|
||||
|
||||
/**
|
||||
* @inject
|
||||
* @var SocketFDService
|
||||
*/
|
||||
private $socketFDService;
|
||||
|
||||
/**
|
||||
* 获取我的好友列表
|
||||
*
|
||||
* @RequestMapping(path="friends", methods="get")
|
||||
*/
|
||||
public function getUserFriends()
|
||||
{
|
||||
$rows = UsersFriend::getUserFriends($this->uid());
|
||||
|
||||
$runArr = $this->socketFDService->getServerRunIdAll();
|
||||
foreach ($rows as $k => $row) {
|
||||
$rows[$k]['online'] = $this->socketFDService->isOnlineAll($row['id'], $runArr);
|
||||
}
|
||||
|
||||
return $this->response->success($rows);
|
||||
}
|
||||
|
||||
/**
|
||||
* @RequestMapping(path="remove-friend", methods="get")
|
||||
* 解除好友关系
|
||||
*
|
||||
* @RequestMapping(path="remove-friend", methods="post")
|
||||
*/
|
||||
public function removeFriend()
|
||||
{
|
||||
$params = $this->request->all();
|
||||
$this->validate($params, [
|
||||
'friend_id' => 'required|integer'
|
||||
]);
|
||||
|
||||
$user_id = $this->uid();
|
||||
if (!$this->friendService->removeFriend($user_id, $params['friend_id'])) {
|
||||
return $this->response->fail('好友关系解除成功...');
|
||||
}
|
||||
|
||||
//删除好友会话列表
|
||||
UsersChatList::delItem($user_id, $params['friend_id'], 2);
|
||||
UsersChatList::delItem($params['friend_id'], $user_id, 2);
|
||||
|
||||
return $this->response->success([], '好友关系解除成功...');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户群聊列表
|
||||
*
|
||||
* @RequestMapping(path="user-groups", methods="get")
|
||||
*/
|
||||
public function getUserGroups()
|
||||
{
|
||||
|
||||
return $this->response->success(
|
||||
$this->userService->getUserChatGroups($this->uid())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取我的信息
|
||||
*
|
||||
* @RequestMapping(path="detail", methods="get")
|
||||
*/
|
||||
public function getUserDetail()
|
||||
{
|
||||
|
||||
$userInfo = $this->userService->findById($this->uid(), ['mobile', 'nickname', 'avatar', 'motto', 'email', 'gender']);
|
||||
return $this->response->success([
|
||||
'mobile' => $userInfo->mobile,
|
||||
'nickname' => $userInfo->nickname,
|
||||
'avatar' => $userInfo->avatar,
|
||||
'motto' => $userInfo->motto,
|
||||
'email' => $userInfo->email,
|
||||
'gender' => $userInfo->gender
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户相关设置
|
||||
*
|
||||
* @RequestMapping(path="setting", methods="get")
|
||||
*/
|
||||
public function getUserSetting()
|
||||
{
|
||||
|
||||
$userInfo = $this->userService->findById($this->uid(), ['id', 'nickname', 'avatar', 'motto', 'gender']);
|
||||
return $this->response->success([
|
||||
'user_info' => [
|
||||
'uid' => $userInfo->id,
|
||||
'nickname' => $userInfo->nickname,
|
||||
'avatar' => $userInfo->avatar,
|
||||
'motto' => $userInfo->motto,
|
||||
'gender' => $userInfo->gender,
|
||||
],
|
||||
'setting' => [
|
||||
'theme_mode' => '',
|
||||
'theme_bag_img' => '',
|
||||
'theme_color' => '',
|
||||
'notify_cue_tone' => '',
|
||||
'keyboard_event_notify' => ''
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @RequestMapping(path="edit-user-detail", methods="get")
|
||||
* 编辑我的信息
|
||||
*
|
||||
* @RequestMapping(path="edit-user-detail", methods="post")
|
||||
*/
|
||||
public function editUserDetail()
|
||||
{
|
||||
$params = $this->request->inputs(['nickname', 'avatar', 'motto', 'gender']);
|
||||
$this->validate($params, [
|
||||
'nickname' => 'required',
|
||||
'motto' => 'present|integer',
|
||||
'gender' => 'required|integer',
|
||||
'avatar' => 'url'
|
||||
]);
|
||||
|
||||
$isTrue = User::where('id', $this->uid())->update($params);
|
||||
|
||||
return $isTrue
|
||||
? $this->response->success([], '个人信息修改成功...')
|
||||
: $this->response->fail('个人信息修改失败...');
|
||||
}
|
||||
|
||||
/**
|
||||
* @RequestMapping(path="edit-avatar", methods="get")
|
||||
* 修改用户头像
|
||||
*
|
||||
* @RequestMapping(path="edit-avatar", methods="post")
|
||||
*/
|
||||
public function editAvatar()
|
||||
{
|
||||
$params = $this->request->inputs(['avatar']);
|
||||
$this->validate($params, [
|
||||
'avatar' => 'required|url'
|
||||
]);
|
||||
|
||||
$isTrue = User::where('id', $this->uid())->update(['avatar' => $params['avatar']]);
|
||||
return $isTrue
|
||||
? $this->response->success([], '头像修改成功...')
|
||||
: $this->response->fail('头像修改失败...');
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过手机号查找用户
|
||||
*
|
||||
* @RequestMapping(path="search-user", methods="get")
|
||||
*/
|
||||
public function searchUserInfo()
|
||||
{
|
||||
$params = $this->request->inputs(['user_id', 'mobile']);
|
||||
$this->validate($params, [
|
||||
'user_id' => 'present|integer',
|
||||
'mobile' => "present|regex:/^1[345789][0-9]{9}$/",
|
||||
]);
|
||||
|
||||
if (!empty($params['user_id'])) {
|
||||
$where['uid'] = $params['user_id'];
|
||||
} else if (!empty($params['mobile'])) {
|
||||
$where['mobile'] = $params['mobile'];
|
||||
} else {
|
||||
return $this->response->fail('请求参数不正确...', [], ResponseCode::VALIDATION_ERROR);
|
||||
}
|
||||
|
||||
if ($data = $this->userService->searchUserInfo($where, $this->uid())) {
|
||||
return $this->response->success($data);
|
||||
}
|
||||
|
||||
return $this->response->fail('查询失败...');
|
||||
}
|
||||
|
||||
/**
|
||||
* @RequestMapping(path="edit-friend-remark", methods="get")
|
||||
* 编辑好友备注信息
|
||||
*
|
||||
* @RequestMapping(path="edit-friend-remark", methods="post")
|
||||
*/
|
||||
public function editFriendRemark()
|
||||
{
|
||||
$params = $this->request->inputs(['friend_id', 'remarks']);
|
||||
$this->validate($params, [
|
||||
'friend_id' => 'required|integer',
|
||||
'remarks' => "required",
|
||||
]);
|
||||
|
||||
$isTrue = $this->friendService->editFriendRemark($this->uid(), $params['friend_id'], $params['remarks']);
|
||||
return $isTrue
|
||||
? $this->response->success([], '备注修改成功...')
|
||||
: $this->response->fail('备注修改失败...');
|
||||
}
|
||||
|
||||
/**
|
||||
* @RequestMapping(path="send-friend-apply", methods="get")
|
||||
* 发送添加好友申请
|
||||
*
|
||||
* @RequestMapping(path="send-friend-apply", methods="post")
|
||||
*/
|
||||
public function sendFriendApply()
|
||||
{
|
||||
$params = $this->request->inputs(['friend_id', 'remarks']);
|
||||
$this->validate($params, [
|
||||
'friend_id' => 'required|integer',
|
||||
'remarks' => 'present',
|
||||
]);
|
||||
|
||||
$user = $this->userService->findById($params['friend_id']);
|
||||
if (!$user) {
|
||||
return $this->response->fail('用户不存在...');
|
||||
}
|
||||
|
||||
if (!$this->friendService->addFriendApply($this->uid(), $params['friend_id'], $params['remarks'])) {
|
||||
return $this->response->fail('发送好友申请失败...');
|
||||
}
|
||||
|
||||
//判断对方是否在线。如果在线发送消息通知
|
||||
// ...
|
||||
|
||||
return $this->response->success([], '发送好友申请成功...');
|
||||
}
|
||||
|
||||
/**
|
||||
* @RequestMapping(path="handle-friend-apply", methods="get")
|
||||
* 处理好友的申请
|
||||
*
|
||||
* @RequestMapping(path="handle-friend-apply", methods="post")
|
||||
*/
|
||||
public function handleFriendApply()
|
||||
{
|
||||
$params = $this->request->inputs(['apply_id', 'remarks']);
|
||||
$this->validate($params, [
|
||||
'apply_id' => 'required|integer',
|
||||
'remarks' => 'present',
|
||||
]);
|
||||
|
||||
$isTrue = $this->friendService->handleFriendApply($this->uid(), $params['apply_id'], $params['remarks']);
|
||||
//判断是否是同意添加好友
|
||||
if ($isTrue) {
|
||||
//... 推送处理消息
|
||||
}
|
||||
|
||||
return $isTrue
|
||||
? $this->response->success([], '处理成功...')
|
||||
: $this->response->fail('处理失败...');
|
||||
}
|
||||
|
||||
/**
|
||||
* @RequestMapping(path="delete-friend-apply", methods="get")
|
||||
* 删除好友申请记录
|
||||
*
|
||||
* @RequestMapping(path="delete-friend-apply", methods="post")
|
||||
*/
|
||||
public function deleteFriendApply()
|
||||
{
|
||||
$params = $this->request->inputs(['apply_id']);
|
||||
$this->validate($params, [
|
||||
'apply_id' => 'required|integer',
|
||||
]);
|
||||
|
||||
$isTrue = $this->friendService->delFriendApply($this->uid(), $params['apply_id']);
|
||||
return $isTrue
|
||||
? $this->response->success([], '删除成功...')
|
||||
: $this->response->fail('删除失败...');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取我的好友申请记录
|
||||
*
|
||||
* @RequestMapping(path="friend-apply-records", methods="get")
|
||||
*/
|
||||
public function getFriendApplyRecords()
|
||||
{
|
||||
$params = $this->request->inputs(['page', 'page_size']);
|
||||
$this->validate($params, [
|
||||
'page' => 'present|integer',
|
||||
'page_size' => 'present|integer',
|
||||
]);
|
||||
|
||||
$page = $this->request->input('page', 1);
|
||||
$page_size = $this->request->input('page_size', 10);
|
||||
$user_id = $this->uid();
|
||||
|
||||
$data = $this->friendService->findApplyRecords($user_id, $page, $page_size);
|
||||
return $this->response->success($data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -137,42 +330,156 @@ class UsersController extends CController
|
|||
}
|
||||
|
||||
/**
|
||||
* @RequestMapping(path="change-password", methods="get")
|
||||
* 修改我的密码
|
||||
*
|
||||
* @RequestMapping(path="change-password", methods="post")
|
||||
*/
|
||||
public function editUserPassword()
|
||||
{
|
||||
$params = $this->request->inputs(['old_password', 'new_password']);
|
||||
$this->validate($params, [
|
||||
'old_password' => 'required',
|
||||
'new_password' => 'required',
|
||||
]);
|
||||
|
||||
$userInfo = $this->userService->findById($this->uid(), ['id', 'password', 'mobile']);
|
||||
|
||||
// 验证密码是否正确
|
||||
if (!Hash::check($this->request->post('old_password'), $userInfo->password)) {
|
||||
return $this->response->fail('旧密码验证失败...');
|
||||
}
|
||||
|
||||
$isTrue = $this->userService->resetPassword($userInfo->mobile, $params['new_password']);
|
||||
return $isTrue
|
||||
? $this->response->success([], '密码修改成功...')
|
||||
: $this->response->fail('密码修改失败...');
|
||||
}
|
||||
|
||||
/**
|
||||
* @RequestMapping(path="change-mobile", methods="get")
|
||||
* 更换用户手机号
|
||||
*
|
||||
* @RequestMapping(path="change-mobile", methods="post")
|
||||
*
|
||||
* @param SmsCodeService $smsCodeService
|
||||
* @return \Psr\Http\Message\ResponseInterface
|
||||
*/
|
||||
public function editUserMobile()
|
||||
public function editUserMobile(SmsCodeService $smsCodeService)
|
||||
{
|
||||
$params = $this->request->inputs(['mobile', 'password', 'sms_code']);
|
||||
$this->validate($params, [
|
||||
'mobile' => 'required',
|
||||
'password' => 'required',
|
||||
'sms_code' => 'required|integer',
|
||||
]);
|
||||
|
||||
if (!$smsCodeService->check('change_mobile', $params['mobile'], $params['sms_code'])) {
|
||||
return $this->response->fail('验证码填写错误...');
|
||||
}
|
||||
|
||||
$user_id = $this->uid();
|
||||
if (!Hash::check($params['password'], User::where('id', $user_id)->value('password'))) {
|
||||
return $this->response->fail('账号密码验证失败...');
|
||||
}
|
||||
|
||||
[$isTrue,] = $this->userService->changeMobile($user_id, $params['mobile']);
|
||||
if (!$isTrue) {
|
||||
return $this->response->fail('手机号更换失败...');
|
||||
}
|
||||
|
||||
// 清除缓存信息
|
||||
$smsCodeService->delCode('change_mobile', $params['mobile']);
|
||||
return $this->response->success([], '手机号更换成功...');
|
||||
}
|
||||
|
||||
/**
|
||||
* @RequestMapping(path="change-email", methods="get")
|
||||
* 修改用户邮箱接口
|
||||
*
|
||||
* @RequestMapping(path="change-email", methods="post")
|
||||
*/
|
||||
public function editUserEmail()
|
||||
{
|
||||
$params = $this->request->inputs(['email', 'password', 'email_code']);
|
||||
$this->validate($params, [
|
||||
'email' => 'required',
|
||||
'password' => 'required',
|
||||
'email_code' => 'required|integer',
|
||||
]);
|
||||
|
||||
$sendEmailCode = new SendEmailCode();
|
||||
if (!$sendEmailCode->check(SendEmailCode::CHANGE_EMAIL, $params['email'], $params['email_code'])) {
|
||||
return $this->response->fail('验证码填写错误...');
|
||||
}
|
||||
|
||||
$uid = $this->uid();
|
||||
$user_password = User::where('id', $uid)->value('password');
|
||||
if (!Hash::check($params['password'], $user_password)) {
|
||||
return $this->response->fail('账号密码验证失败...');
|
||||
}
|
||||
|
||||
$isTrue = User::where('id', $uid)->update(['email' => $params['email']]);
|
||||
if (!$isTrue) {
|
||||
return $this->response->fail('邮箱设置失败...');
|
||||
}
|
||||
|
||||
$sendEmailCode->delCode(SendEmailCode::CHANGE_EMAIL, $params['email']);
|
||||
return $this->response->success([], '邮箱设置成功...');
|
||||
}
|
||||
|
||||
/**
|
||||
* @RequestMapping(path="send-mobile-code", methods="get")
|
||||
* 修改手机号发送验证码
|
||||
*
|
||||
* @RequestMapping(path="send-mobile-code", methods="post")
|
||||
*
|
||||
* @param SmsCodeService $smsCodeService
|
||||
* @return \Psr\Http\Message\ResponseInterface
|
||||
*/
|
||||
public function sendMobileCode()
|
||||
public function sendMobileCode(SmsCodeService $smsCodeService)
|
||||
{
|
||||
$params = $this->request->inputs(['mobile']);
|
||||
$this->validate($params, [
|
||||
'mobile' => "present|regex:/^1[345789][0-9]{9}$/",
|
||||
]);
|
||||
|
||||
$user_id = $this->uid();
|
||||
if (in_array($user_id, [2054, 2055])) {
|
||||
return $this->response->fail('测试账号不支持修改手机号...');
|
||||
}
|
||||
|
||||
if (User::where('mobile', $params['mobile'])->exists()) {
|
||||
return $this->response->fail('手机号已被他人注册...');
|
||||
}
|
||||
|
||||
$data = ['is_debug' => true];
|
||||
[$isTrue, $result] = $smsCodeService->send('change_mobile', $params['mobile']);
|
||||
if ($isTrue) {
|
||||
$data['sms_code'] = $result['data']['code'];
|
||||
} else {
|
||||
// ... 处理发送失败逻辑,当前默认发送成功
|
||||
}
|
||||
|
||||
return $this->response->success($data, '验证码发送成功...');
|
||||
}
|
||||
|
||||
/**
|
||||
* @RequestMapping(path="send-change-email-code", methods="get")
|
||||
* 发送绑定邮箱的验证码
|
||||
*
|
||||
* @RequestMapping(path="send-change-email-code", methods="post")
|
||||
*
|
||||
* @param SendEmailCode $sendEmailCode
|
||||
* @return \Psr\Http\Message\ResponseInterface
|
||||
*/
|
||||
public function sendChangeEmailCode()
|
||||
public function sendChangeEmailCode(SendEmailCode $sendEmailCode)
|
||||
{
|
||||
$params = $this->request->inputs(['email']);
|
||||
$this->validate($params, [
|
||||
'email' => "required|email",
|
||||
]);
|
||||
|
||||
$isTrue = $sendEmailCode->send(SendEmailCode::CHANGE_EMAIL, '绑定邮箱', $params['email']);
|
||||
if (!$isTrue) {
|
||||
return $this->response->fail('验证码发送失败...');
|
||||
}
|
||||
|
||||
return $this->response->success([], '验证码发送成功...');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ class WebSocketController implements OnMessageInterface, OnOpenInterface, OnClos
|
|||
$token = $request->get['token'] ?? '';
|
||||
$userInfo = $this->jwt->getParserData($token);
|
||||
stdout_log()->notice("用户连接信息 : user_id:{$userInfo['user_id']} | fd:{$request->fd} | data:" . Json::encode($userInfo));
|
||||
stdout_log()->notice('连接时间:' . date('Y-m-d H:i:s'));
|
||||
|
||||
// 绑定fd与用户关系
|
||||
$this->socketFDService->bindRelation($request->fd, $userInfo['user_id']);
|
||||
|
@ -85,10 +86,18 @@ class WebSocketController implements OnMessageInterface, OnOpenInterface, OnClos
|
|||
$user_id = $this->socketFDService->findFdUserId($fd);
|
||||
|
||||
stdout_log()->notice("客户端FD:{$fd} 已关闭连接,用户ID为【{$user_id}】");
|
||||
stdout_log()->notice('关闭时间:' . date('Y-m-d H:i:s'));
|
||||
|
||||
// 解除fd关系
|
||||
$this->socketFDService->removeRelation($fd);
|
||||
|
||||
// ... 包装推送消息至队列
|
||||
// 判断是否存在异地登录
|
||||
$isOnline = $this->socketFDService->isOnlineAll(intval($user_id));
|
||||
if (!$isOnline) {
|
||||
// ... 不存在异地登录,推送下线通知消息
|
||||
// ... 包装推送消息至队列
|
||||
} else {
|
||||
stdout_log()->notice("用户:{$user_id} 存在异地登录...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ class Hash
|
|||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function make($value)
|
||||
public static function make($value)
|
||||
{
|
||||
return password_hash($value, PASSWORD_DEFAULT);
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ class Hash
|
|||
* @param string $hashedValue
|
||||
* @return bool
|
||||
*/
|
||||
public function check($value, $hashedValue)
|
||||
public static function check($value, $hashedValue)
|
||||
{
|
||||
return password_verify($value, $hashedValue);
|
||||
}
|
||||
|
|
|
@ -48,4 +48,99 @@ class UsersChatList extends BaseModel
|
|||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime'
|
||||
];
|
||||
|
||||
/**
|
||||
* 创建聊天列表记录
|
||||
*
|
||||
* @param int $user_id 用户ID
|
||||
* @param int $receive_id 接收者ID
|
||||
* @param int $type 创建类型 1:私聊 2:群聊
|
||||
* @return array
|
||||
*/
|
||||
public static function addItem(int $user_id, int $receive_id, int $type)
|
||||
{
|
||||
$result = self::where('uid', $user_id)->where('type', $type)->where($type == 1 ? 'friend_id' : 'group_id', $receive_id)->first();
|
||||
if ($result) {
|
||||
$result->status = 1;
|
||||
$result->updated_at = date('Y-m-d H:i:s');
|
||||
$result->save();
|
||||
|
||||
return [
|
||||
'id'=>$result->id,
|
||||
'type'=>$result->type,
|
||||
'friend_id'=>$result->friend_id,
|
||||
'group_id'=>$result->group_id,
|
||||
];
|
||||
}
|
||||
|
||||
if (!$result = self::create([
|
||||
'type' => $type,
|
||||
'uid' => $user_id,
|
||||
'status' => 1,
|
||||
'friend_id' => $type == 1 ? $receive_id : 0,
|
||||
'group_id' => $type == 2 ? $receive_id : 0,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
'id'=>$result->id,
|
||||
'type'=>$result->type,
|
||||
'friend_id'=>$result->friend_id,
|
||||
'group_id'=>$result->group_id,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 聊天对话列表置顶操作
|
||||
*
|
||||
* @param int $user_id 用户ID
|
||||
* @param int $list_id 对话列表ID
|
||||
* @param bool $is_top 是否置顶(true:是 false:否)
|
||||
* @return bool
|
||||
*/
|
||||
public static function topItem(int $user_id, int $list_id, $is_top = true)
|
||||
{
|
||||
return (bool)self::where('id', $list_id)->where('uid', $user_id)->update(['is_top' => $is_top ? 1 : 0, 'updated_at' => date('Y-m-d H:i:s')]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除聊天列表
|
||||
*
|
||||
* @param int $user_id 用户ID
|
||||
* @param int $id 聊天列表ID、好友ID或群聊ID
|
||||
* @param int $type ID类型 (1:聊天列表ID 2:好友ID 3:群聊ID)
|
||||
* @return bool
|
||||
*/
|
||||
public static function delItem(int $user_id, int $id, $type = 1)
|
||||
{
|
||||
if ($type == 1) {
|
||||
return (bool)self::where('id', $id)->where('uid', $user_id)->update(['status' => 0, 'updated_at' => date('Y-m-d H:i:s')]);
|
||||
} else if ($type == 2) {
|
||||
return (bool)self::where('uid', $user_id)->where('friend_id', $id)->update(['status' => 0, 'updated_at' => date('Y-m-d H:i:s')]);
|
||||
} else {
|
||||
return (bool)self::where('uid', $user_id)->where('group_id', $id)->update(['status' => 0, 'updated_at' => date('Y-m-d H:i:s')]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置消息免打扰
|
||||
*
|
||||
* @param int $user_id 用户ID
|
||||
* @param int $receive_id 接收者ID
|
||||
* @param int $type 接收者类型(1:好友 2:群组)
|
||||
* @param int $not_disturb 是否免打扰
|
||||
* @return boolean
|
||||
*/
|
||||
public static function notDisturbItem(int $user_id, int $receive_id, int $type, int $not_disturb)
|
||||
{
|
||||
$result = self::where('uid', $user_id)->where($type == 1 ? 'friend_id' : 'group_id', $receive_id)->where('status', 1)->first(['id', 'not_disturb']);
|
||||
if (!$result || $not_disturb == $result->not_disturb) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool)self::where('id', $result->id)->update(['not_disturb' => $not_disturb]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace App\Model;
|
||||
|
||||
/**
|
||||
|
@ -26,7 +27,14 @@ class UsersFriendsApply extends BaseModel
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [];
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'friend_id',
|
||||
'status',
|
||||
'remarks',
|
||||
'created_at',
|
||||
'updated_at'
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
|
|
|
@ -3,7 +3,205 @@
|
|||
namespace App\Service;
|
||||
|
||||
|
||||
use App\Model\User;
|
||||
use App\Model\UsersFriend;
|
||||
use App\Model\UsersFriendsApply;
|
||||
use App\Traits\PagingTrait;
|
||||
use Hyperf\DbConnection\Db;
|
||||
|
||||
class FriendService extends BaseService
|
||||
{
|
||||
use PagingTrait;
|
||||
|
||||
|
||||
/**
|
||||
* 创建好友的申请
|
||||
*
|
||||
* @param int $user_id 用户ID
|
||||
* @param int $friend_id 好友ID
|
||||
* @param string $remarks 好友申请备注
|
||||
* @return bool
|
||||
*/
|
||||
public function addFriendApply(int $user_id, int $friend_id, string $remarks)
|
||||
{
|
||||
// 判断是否是好友关系
|
||||
if (UsersFriend::isFriend($user_id, $friend_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$result = UsersFriendsApply::where('user_id', $user_id)->where('friend_id', $friend_id)->orderBy('id', 'desc')->first();
|
||||
if (!$result) {
|
||||
$result = UsersFriendsApply::create([
|
||||
'user_id' => $user_id,
|
||||
'friend_id' => $friend_id,
|
||||
'status' => 0,
|
||||
'remarks' => $remarks,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
return $result ? true : false;
|
||||
} else if ($result->status == 0) {
|
||||
$result->remarks = $remarks;
|
||||
$result->updated_at = date('Y-m-d H:i:s');
|
||||
$result->save();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除好友申请记录
|
||||
*
|
||||
* @param int $user_id 用户ID
|
||||
* @param int $apply_id 好友申请ID
|
||||
* @return mixed
|
||||
*/
|
||||
public function delFriendApply(int $user_id, int $apply_id)
|
||||
{
|
||||
return (bool)UsersFriendsApply::where('id', $apply_id)->where('friend_id', $user_id)->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理好友的申请
|
||||
*
|
||||
* @param int $user_id 当前用户ID
|
||||
* @param int $apply_id 申请记录ID
|
||||
* @param string $remarks 备注信息
|
||||
* @return bool
|
||||
*/
|
||||
public function handleFriendApply(int $user_id, int $apply_id, $remarks = '')
|
||||
{
|
||||
$info = UsersFriendsApply::where('id', $apply_id)->where('friend_id', $user_id)->where('status', 0)->orderBy('id', 'desc')->first(['user_id', 'friend_id']);
|
||||
if (!$info) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Db::beginTransaction();
|
||||
try {
|
||||
$res = UsersFriendsApply::where('id', $apply_id)->update(['status' => 1, 'updated_at' => date('Y-m-d H:i:s')]);
|
||||
if (!$res) {
|
||||
throw new \Exception('更新好友申请表信息失败');
|
||||
}
|
||||
|
||||
$user1 = $info->user_id;
|
||||
$user2 = $info->friend_id;
|
||||
if ($info->user_id > $info->friend_id) {
|
||||
[$user1, $user2] = [$info->friend_id, $info->user_id];
|
||||
}
|
||||
|
||||
//查询是否存在好友记录
|
||||
$friendResult = UsersFriend::select('id', 'user1', 'user2', 'active', 'status')->where('user1', '=', $user1)->where('user2', '=', $user2)->first();
|
||||
if ($friendResult) {
|
||||
$active = ($friendResult->user1 == $info->user_id && $friendResult->user2 == $info->friend_id) ? 1 : 2;
|
||||
if (!UsersFriend::where('id', $friendResult->id)->update(['active' => $active, 'status' => 1])) {
|
||||
throw new \Exception('更新好友关系信息失败');
|
||||
}
|
||||
} else {
|
||||
//好友昵称
|
||||
$friend_nickname = User::where('id', $info->friend_id)->value('nickname');
|
||||
$insRes = UsersFriend::create([
|
||||
'user1' => $user1,
|
||||
'user2' => $user2,
|
||||
'user1_remark' => $user1 == $user_id ? $remarks : $friend_nickname,
|
||||
'user2_remark' => $user2 == $user_id ? $remarks : $friend_nickname,
|
||||
'active' => $user1 == $user_id ? 2 : 1,
|
||||
'status' => 1,
|
||||
'agree_time' => date('Y-m-d H:i:s'),
|
||||
'created_at' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
if (!$insRes) {
|
||||
throw new \Exception('创建好友关系失败');
|
||||
}
|
||||
}
|
||||
|
||||
Db::commit();
|
||||
} catch (\Exception $e) {
|
||||
Db::rollBack();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解除好友关系
|
||||
*
|
||||
* @param int $user_id 用户ID
|
||||
* @param int $friend_id 好友ID
|
||||
* @return bool
|
||||
*/
|
||||
public function removeFriend(int $user_id, int $friend_id)
|
||||
{
|
||||
if (!UsersFriend::isFriend($user_id, $friend_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = ['status' => 0];
|
||||
|
||||
// 用户ID比大小交换位置
|
||||
if ($user_id > $friend_id) {
|
||||
[$user_id, $friend_id] = [$friend_id, $user_id];
|
||||
}
|
||||
|
||||
return (bool)UsersFriend::where('user1', $user_id)->where('user2', $friend_id)->update($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户好友申请记录
|
||||
*
|
||||
* @param int $user_id 用户ID
|
||||
* @param int $page 分页数
|
||||
* @param int $page_size 分页大小
|
||||
* @return array
|
||||
*/
|
||||
public function findApplyRecords(int $user_id, $page = 1, $page_size = 30)
|
||||
{
|
||||
$rowsSqlObj = UsersFriendsApply::select([
|
||||
'users_friends_apply.id',
|
||||
'users_friends_apply.status',
|
||||
'users_friends_apply.remarks',
|
||||
'users.nickname',
|
||||
'users.avatar',
|
||||
'users.mobile',
|
||||
'users_friends_apply.user_id',
|
||||
'users_friends_apply.friend_id',
|
||||
'users_friends_apply.created_at'
|
||||
]);
|
||||
|
||||
$rowsSqlObj->leftJoin('users', 'users.id', '=', 'users_friends_apply.user_id');
|
||||
$rowsSqlObj->where('users_friends_apply.friend_id', $user_id);
|
||||
|
||||
$count = $rowsSqlObj->count();
|
||||
$rows = [];
|
||||
if ($count > 0) {
|
||||
$rows = $rowsSqlObj->orderBy('users_friends_apply.id', 'desc')->forPage($page, $page_size)->get()->toArray();
|
||||
}
|
||||
|
||||
return $this->getPagingRows($rows, $count, $page, $page_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑好友备注信息
|
||||
*
|
||||
* @param int $user_id 用户ID
|
||||
* @param int $friend_id 朋友ID
|
||||
* @param string $remarks 好友备注名称
|
||||
* @return bool
|
||||
*/
|
||||
public function editFriendRemark(int $user_id, int $friend_id, string $remarks)
|
||||
{
|
||||
$data = [];
|
||||
if ($user_id > $friend_id) {
|
||||
[$user_id, $friend_id] = [$friend_id, $user_id];
|
||||
$data['user2_remark'] = $remarks;
|
||||
} else {
|
||||
$data['user1_remark'] = $remarks;
|
||||
}
|
||||
|
||||
return (bool)UsersFriend::where('user1', $user_id)->where('user2', $friend_id)->update($data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ class SocketFDService
|
|||
{
|
||||
if (empty($run_ids)) $run_ids = $this->getServerRunIdAll();
|
||||
|
||||
foreach ($run_ids as $run_id) {
|
||||
foreach ($run_ids as $run_id => $time) {
|
||||
if ($this->isOnline($user_id, $run_id)) return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,12 +2,29 @@
|
|||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Helper\Hash;
|
||||
use App\Model\Group\UsersGroupMember;
|
||||
use App\Model\User;
|
||||
use App\Model\ArticleClass;
|
||||
use App\Model\Article\ArticleClass;
|
||||
use App\Model\UsersChatList;
|
||||
use App\Model\UsersFriend;
|
||||
use App\Model\UsersFriendsApply;
|
||||
use Hyperf\DbConnection\Db;
|
||||
|
||||
class UserService extends BaseService
|
||||
{
|
||||
/**
|
||||
* 获取用户信息
|
||||
*
|
||||
* @param int $user_id 用户ID
|
||||
* @param array $field 查询字段
|
||||
* @return mixed
|
||||
*/
|
||||
public function findById(int $user_id, $field = ['*'])
|
||||
{
|
||||
return User::where('id', $user_id)->first($field);
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录逻辑
|
||||
*
|
||||
|
@ -15,14 +32,15 @@ class UserService extends BaseService
|
|||
* @param string $password 登录密码
|
||||
* @return array|bool
|
||||
*/
|
||||
public function login(string $mobile,string $password){
|
||||
$user = User::where('mobile',$mobile)->first();
|
||||
public function login(string $mobile, string $password)
|
||||
{
|
||||
$user = User::where('mobile', $mobile)->first();
|
||||
|
||||
if(!$user){
|
||||
if (!$user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!password_verify($password,$user->password)){
|
||||
if (!password_verify($password, $user->password)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -43,6 +61,7 @@ class UserService extends BaseService
|
|||
|
||||
$result = User::create($data);
|
||||
|
||||
|
||||
// 创建用户的默认笔记分类
|
||||
ArticleClass::create([
|
||||
'user_id' => $result->id,
|
||||
|
@ -57,4 +76,116 @@ class UserService extends BaseService
|
|||
|
||||
return $result ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 账号重置密码
|
||||
*
|
||||
* @param string $mobile 用户手机好
|
||||
* @param string $password 新密码
|
||||
* @return mixed
|
||||
*/
|
||||
public function resetPassword(string $mobile, string $password)
|
||||
{
|
||||
return User::where('mobile', $mobile)->update(['password' => Hash::make($password)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改绑定的手机号
|
||||
*
|
||||
* @param int $user_id 用户ID
|
||||
* @param string $mobile 换绑手机号
|
||||
* @return array|bool
|
||||
*/
|
||||
public function changeMobile(int $user_id, string $mobile)
|
||||
{
|
||||
$uid = User::where('mobile', $mobile)->value('id');
|
||||
if ($uid) {
|
||||
return [false, '手机号已被他人绑定'];
|
||||
}
|
||||
|
||||
$isTrue = (bool)User::where('id', $user_id)->update(['mobile' => $mobile]);
|
||||
return [$isTrue, null];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户所在的群聊
|
||||
*
|
||||
* @param int $user_id 用户ID
|
||||
* @return mixed
|
||||
*/
|
||||
public function getUserChatGroups(int $user_id)
|
||||
{
|
||||
$items = UsersGroupMember::select(['users_group.id', 'users_group.group_name', 'users_group.avatar', 'users_group.group_profile', 'users_group.user_id as group_user_id'])
|
||||
->join('users_group', 'users_group.id', '=', 'users_group_member.group_id')
|
||||
->where([
|
||||
['users_group_member.user_id', '=', $user_id],
|
||||
['users_group_member.status', '=', 0]
|
||||
])
|
||||
->orderBy('id', 'desc')->get()->toarray();
|
||||
|
||||
foreach ($items as $key => $item) {
|
||||
// 判断当前用户是否是群主
|
||||
$items[$key]['isGroupLeader'] = $item['group_user_id'] == $user_id;
|
||||
|
||||
//删除无关字段
|
||||
unset($items[$key]['group_user_id']);
|
||||
|
||||
// 是否消息免打扰
|
||||
$items[$key]['not_disturb'] = UsersChatList::where([
|
||||
['uid', '=', $user_id],
|
||||
['type', '=', 2],
|
||||
['group_id', '=', $item['id']]
|
||||
])->value('not_disturb');
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过手机号查找用户
|
||||
*
|
||||
* @param array $where 查询条件
|
||||
* @param int $user_id 当前登录用户的ID
|
||||
* @return array
|
||||
*/
|
||||
public function searchUserInfo(array $where, int $user_id)
|
||||
{
|
||||
$info = User::select(['id', 'mobile', 'nickname', 'avatar', 'gender', 'motto']);
|
||||
if (isset($where['uid'])) {
|
||||
$info->where('id', $where['uid']);
|
||||
}
|
||||
|
||||
if (isset($where['mobile'])) {
|
||||
$info->where('mobile', $where['mobile']);
|
||||
}
|
||||
|
||||
$info = $info->first();
|
||||
$info = $info ? $info->toArray() : [];
|
||||
if ($info) {
|
||||
$info['friend_status'] = 0;//朋友关系状态 0:本人 1:陌生人 2:朋友
|
||||
$info['nickname_remark'] = '';
|
||||
$info['friend_apply'] = 0;
|
||||
|
||||
// 判断查询信息是否是自己
|
||||
if ($info['id'] != $user_id) {
|
||||
$friend_id = $info['id'];
|
||||
|
||||
$friendInfo = UsersFriend::select('id', 'user1', 'user2', 'active', 'user1_remark', 'user2_remark')->where(function ($query) use ($friend_id, $user_id) {
|
||||
$query->where('user1', '=', $user_id)->where('user2', '=', $friend_id)->where('status', 1);
|
||||
})->orWhere(function ($query) use ($friend_id, $user_id) {
|
||||
$query->where('user1', '=', $friend_id)->where('user2', '=', $user_id)->where('status', 1);
|
||||
})->first();
|
||||
|
||||
$info['friend_status'] = $friendInfo ? 2 : 1;
|
||||
if ($friendInfo) {
|
||||
$info['nickname_remark'] = ($friendInfo->user1 == $friend_id) ? $friendInfo->user2_remark : $friendInfo->user1_remark;
|
||||
} else {
|
||||
$res = UsersFriendsApply::where('user_id', $user_id)->where('friend_id', $info['id'])->where('status', 0)->orderBy('id', 'desc')->exists();
|
||||
$info['friend_apply'] = $res ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
namespace App\Support;
|
||||
|
||||
|
||||
class SendEmailCode
|
||||
{
|
||||
const FORGET_PASSWORD = 'forget_password';
|
||||
const CHANGE_MOBILE = 'change_mobile';
|
||||
const CHANGE_REGISTER = 'user_register';
|
||||
const CHANGE_EMAIL = 'change_email';
|
||||
|
||||
/**
|
||||
* 获取缓存key
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $mobile
|
||||
* @return string
|
||||
*/
|
||||
private function getKey(string $type, string $mobile)
|
||||
{
|
||||
return "email_code:{$type}:{$mobile}";
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测验证码是否正确
|
||||
*
|
||||
* @param string $type 发送类型
|
||||
* @param string $email 手机号
|
||||
* @param string $code 验证码
|
||||
* @return bool
|
||||
*/
|
||||
public function check(string $type, string $email, string $code)
|
||||
{
|
||||
$sms_code = redis()->get($this->getKey($type, $email));
|
||||
if (!$sms_code) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $sms_code == $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送邮件验证码
|
||||
*
|
||||
* @param string $type 类型
|
||||
* @param string $title 邮件标题
|
||||
* @param string $email 邮箱地址
|
||||
* @return boolean
|
||||
*/
|
||||
public function send(string $type, string $title, string $email)
|
||||
{
|
||||
$key = $this->getKey($type, $email);
|
||||
if (!$sms_code = $this->getCode($key)) {
|
||||
$sms_code = mt_rand(100000, 999999);
|
||||
}
|
||||
|
||||
$this->setCode($key, $sms_code);
|
||||
|
||||
// ...执行发送
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存的验证码
|
||||
*
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCode(string $key)
|
||||
{
|
||||
return redis()->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置验证码缓存
|
||||
*
|
||||
* @param string $key 缓存key
|
||||
* @param string $sms_code 验证码
|
||||
* @param float|int $exp 过期时间
|
||||
* @return mixed
|
||||
*/
|
||||
public function setCode(string $key, string $sms_code, $exp = 60 * 15)
|
||||
{
|
||||
return redis()->setex($key, $exp, $sms_code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除验证码缓存
|
||||
*
|
||||
* @param string $type 类型
|
||||
* @param string $email 邮箱地址
|
||||
* @return mixed
|
||||
*/
|
||||
public function delCode(string $type, string $email)
|
||||
{
|
||||
return redis()->del($this->getKey($type, $email));
|
||||
}
|
||||
}
|
|
@ -37,6 +37,11 @@ return [
|
|||
SwooleEvent::ON_MESSAGE => [Hyperf\WebSocketServer\Server::class, 'onMessage'],
|
||||
SwooleEvent::ON_CLOSE => [Hyperf\WebSocketServer\Server::class, 'onClose'],
|
||||
],
|
||||
'settings'=>[
|
||||
//设置心跳检测
|
||||
'heartbeat_idle_time' => 70,
|
||||
'heartbeat_check_interval' => 30,
|
||||
]
|
||||
],
|
||||
],
|
||||
'settings' => [
|
||||
|
@ -50,10 +55,6 @@ return [
|
|||
'socket_buffer_size' => 3 * 1024 * 1024,
|
||||
'buffer_output_size' => 3 * 1024 * 1024,
|
||||
'package_max_length'=> 10 * 1024 * 1024,
|
||||
|
||||
//设置心跳检测
|
||||
'heartbeat_idle_time' => 150,
|
||||
'heartbeat_check_interval' => 60,
|
||||
],
|
||||
'callbacks' => [
|
||||
//自定义启动前事件
|
||||
|
|
Loading…
Reference in New Issue