diff --git a/app/chat/controller/CommonPhraseController.php b/app/chat/controller/CommonPhraseController.php new file mode 100644 index 0000000..e229499 --- /dev/null +++ b/app/chat/controller/CommonPhraseController.php @@ -0,0 +1,67 @@ +get('uid'); + return $this->success(Db::name('chat_common_phrase')->where('user_id', $uid) + ->order('sort', 'desc') + ->field(['id', 'content', 'sort', 'created_time']) + ->select()); + } + + /** + * 添加常用语 + */ + public function store(Request $request): Response + { + $uid = $request->post('uid'); + $content = $request->post('content', ''); + $sort = $request->post('sort', 0); + if (empty($content) || mb_strlen($content) > 500) { + return $this->error('常用语内容不能为空且长度≤500字'); + } + // 有重复的内容不给添加 + $msg = Db::name('chat_common_phrase')->where(['user_id' => $uid, 'content' => $content])->find(); + if($msg) { + return $this->error('此内容已经存在,不能重复添加'); + } + $res = Db::name('chat_common_phrase')->insert([ + 'user_id' => $uid, + 'content' => $content, + 'sort' => $sort, + 'created_time' => d(), + ]); + if($res) { + return $this->success(); + }else { + return $this->error(); + } + } + + /** + * 删除常用语 + */ + public function destroy(Request $request, int $id): Response + { + $uid = $request->uid; + $phrase = ChatCommonPhrase::where(['id' => $id, 'user_id' => $uid])->find(); + if (!$phrase) { + return json(['code' => 404, 'msg' => '常用语不存在']); + } + + $phrase->delete(); + return json(['code' => 200, 'msg' => '删除成功']); + } +} diff --git a/app/chat/controller/GroupController.php b/app/chat/controller/GroupController.php new file mode 100644 index 0000000..ef49f4f --- /dev/null +++ b/app/chat/controller/GroupController.php @@ -0,0 +1,418 @@ +uid; + $userType = $request->user_type; + + if ($userType != 2) { // 2=商家 + return json(['code' => 403, 'msg' => '仅商家可创建群聊']); + } + + $name = $request->post('name', ''); + $avatar = $request->post('avatar', ''); + $announcement = $request->post('announcement', ''); + $isPublic = $request->post('is_public', 0); + + if (empty($name)) { + return json(['code' => 400, 'msg' => '群名称不能为空']); + } + + $now = time(); + // 创建群 + $group = ChatGroup::create([ + 'name' => $name, + 'avatar' => $avatar, + 'owner_id' => $uid, + 'announcement' => $announcement, + 'is_public' => $isPublic, + 'created_at' => $now, + 'updated_at' => $now + ]); + + // 群主加入群 + ChatGroupMember::create([ + 'group_id' => $group->id, + 'user_id' => $uid, + 'role' => 1, // 1=群主 + 'join_time' => $now, + 'quit_time' => null, + 'is_kicked' => 0 + ]); + + return json([ + 'code' => 200, + 'msg' => '群创建成功', + 'data' => ['group_id' => $group->id] + ]); + } + + /** + * 加群 + */ + public function join(Request $request): Response + { + $uid = $request->uid; + $groupId = $request->post('group_id', 0); + + if (!$groupId) { + return json(['code' => 400, 'msg' => '缺少group_id']); + } + + // 验证群是否存在 + $group = ChatGroup::find($groupId); + if (!$group) { + return json(['code' => 404, 'msg' => '群不存在']); + } + + // 验证是否已在群内 + $exists = ChatGroupMember::where([ + 'group_id' => $groupId, + 'user_id' => $uid, + 'quit_time' => null, + 'is_kicked' => 0 + ])->exists(); + if ($exists) { + return json(['code' => 400, 'msg' => '已在群内']); + } + + // 被踢用户不能重新加入(需群主邀请) + $isKicked = ChatGroupMember::where([ + 'group_id' => $groupId, + 'user_id' => $uid, + 'is_kicked' => 1 + ])->exists(); + if ($isKicked) { + return json(['code' => 403, 'msg' => '你已被移出该群,无法重新加入']); + } + + // 加入群 + ChatGroupMember::create([ + 'group_id' => $groupId, + 'user_id' => $uid, + 'role' => 3, // 3=普通成员 + 'join_time' => time(), + 'quit_time' => null, + 'is_kicked' => 0 + ]); + + return json(['code' => 200, 'msg' => '加群成功']); + } + + /** + * 退群 + */ + public function quit(Request $request): Response + { + $uid = $request->uid; + $groupId = $request->post('group_id', 0); + + if (!$groupId) { + return json(['code' => 400, 'msg' => '缺少group_id']); + } + + // 验证是否是群主(群主不能退群,需转让) + $isOwner = ChatGroupMember::where([ + 'group_id' => $groupId, + 'user_id' => $uid, + 'role' => 1, + 'quit_time' => null + ])->exists(); + if ($isOwner) { + return json(['code' => 403, 'msg' => '群主不能退群,请先转让群主']); + } + + // 标记退出时间 + $member = ChatGroupMember::where([ + 'group_id' => $groupId, + 'user_id' => $uid, + 'quit_time' => null, + 'is_kicked' => 0 + ])->find(); + if (!$member) { + return json(['code' => 400, 'msg' => '不在群内']); + } + + $member->quit_time = time(); + $member->save(); + + return json(['code' => 200, 'msg' => '退群成功']); + } + + /** + * 设置群公告(仅群主/管理员) + */ + public function setAnnouncement(Request $request): Response + { + $uid = $request->uid; + $groupId = $request->post('group_id', 0); + $announcement = $request->post('announcement', ''); + + if (!$groupId) { + return json(['code' => 400, 'msg' => '缺少group_id']); + } + + // 验证权限 + $role = ChatGroupMember::where([ + 'group_id' => $groupId, + 'user_id' => $uid, + 'quit_time' => null, + 'is_kicked' => 0 + ])->value('role'); + if (!in_array($role, [1, 2])) { // 1=群主,2=管理员 + return json(['code' => 403, 'msg' => '仅群主和管理员可设置群公告']); + } + + // 更新公告 + ChatGroup::where('id', $groupId)->update([ + 'announcement' => $announcement, + 'updated_at' => time() + ]); + + return json(['code' => 200, 'msg' => '群公告设置成功']); + } + + /** + * 设置群免打扰 + */ + public function setDoNotDisturb(Request $request): Response + { + $uid = $request->uid; + $groupId = $request->post('group_id', 0); + $status = $request->post('status', 0); // 0=关闭,1=开启 + + if (!$groupId) { + return json(['code' => 400, 'msg' => '缺少group_id']); + } + + // 验证是否在群内 + $isMember = ChatGroupMember::where([ + 'group_id' => $groupId, + 'user_id' => $uid, + 'quit_time' => null, + 'is_kicked' => 0 + ])->exists(); + if (!$isMember) { + return json(['code' => 400, 'msg' => '不在群内']); + } + + // 生成会话ID + $sessionId = Session::generateSessionId(2, $uid, $groupId); + + // 更新免打扰状态 + ChatDoNotDisturb::updateOrCreate( + ['user_id' => $uid, 'session_id' => $sessionId], + ['status' => $status, 'updated_at' => time()] + ); + + return json(['code' => 200, 'msg' => $status ? '开启免打扰成功' : '关闭免打扰成功']); + } + + /** + * 群成员禁言(仅群主/管理员) + */ + public function muteMember(Request $request): Response + { + $uid = $request->uid; + $groupId = $request->post('group_id', 0); + $targetUid = $request->post('target_uid', 0); + $muteTime = $request->post('mute_time', 3600); // 默认禁言1小时 + + if (!$groupId || !$targetUid) { + return json(['code' => 400, 'msg' => '缺少group_id或target_uid']); + } + + // 验证操作人权限 + $operatorRole = ChatGroupMember::where([ + 'group_id' => $groupId, + 'user_id' => $uid, + 'quit_time' => null, + 'is_kicked' => 0 + ])->value('role'); + if (!in_array($operatorRole, [1, 2])) { + return json(['code' => 403, 'msg' => '仅群主和管理员可禁言']); + } + + // 验证被禁言用户是否在群内 + $targetIsMember = ChatGroupMember::where([ + 'group_id' => $groupId, + 'user_id' => $targetUid, + 'quit_time' => null, + 'is_kicked' => 0 + ])->exists(); + if (!$targetIsMember) { + return json(['code' => 400, 'msg' => '被禁言用户不在群内']); + } + + // 不能禁言群主 + $groupOwner = ChatGroup::where('id', $groupId)->value('owner_id'); + if ($targetUid == $groupOwner) { + return json(['code' => 403, 'msg' => '不能禁言群主']); + } + + // 不能禁言自己 + if ($targetUid == $uid) { + return json(['code' => 400, 'msg' => '不能禁言自己']); + } + + $now = time(); + $expireTime = $muteTime > 0 ? $now + $muteTime : null; + + // 新增/更新禁言记录 + ChatGroupMute::updateOrCreate( + ['group_id' => $groupId, 'user_id' => $targetUid], + [ + 'mute_time' => $muteTime, + 'expire_time' => $expireTime, + 'operator_id' => $uid, + 'created_at' => $now + ] + ); + + return json(['code' => 200, 'msg' => "禁言成功,时长{$muteTime}秒"]); + } + + /** + * 解除禁言(仅群主/管理员) + */ + public function unmuteMember(Request $request): Response + { + $uid = $request->uid; + $groupId = $request->post('group_id', 0); + $targetUid = $request->post('target_uid', 0); + + if (!$groupId || !$targetUid) { + return json(['code' => 400, 'msg' => '缺少group_id或target_uid']); + } + + // 验证操作人权限 + $operatorRole = ChatGroupMember::where([ + 'group_id' => $groupId, + 'user_id' => $uid, + 'quit_time' => null, + 'is_kicked' => 0 + ])->value('role'); + if (!in_array($operatorRole, [1, 2])) { + return json(['code' => 403, 'msg' => '仅群主和管理员可解除禁言']); + } + + // 删除禁言记录 + ChatGroupMute::where([ + 'group_id' => $groupId, + 'user_id' => $targetUid + ])->delete(); + + return json(['code' => 200, 'msg' => '解除禁言成功']); + } + + /** + * 踢人(仅群主/管理员) + */ + public function kickMember(Request $request): Response + { + $uid = $request->uid; + $groupId = $request->post('group_id', 0); + $targetUid = $request->post('target_uid', 0); + + if (!$groupId || !$targetUid) { + return json(['code' => 400, 'msg' => '缺少group_id或target_uid']); + } + + // 验证操作人权限 + $operatorRole = ChatGroupMember::where([ + 'group_id' => $groupId, + 'user_id' => $uid, + 'quit_time' => null, + 'is_kicked' => 0 + ])->value('role'); + if (!in_array($operatorRole, [1, 2])) { + return json(['code' => 403, 'msg' => '仅群主和管理员可踢人']); + } + + // 验证被踢用户是否在群内 + $targetMember = ChatGroupMember::where([ + 'group_id' => $groupId, + 'user_id' => $targetUid, + 'quit_time' => null, + 'is_kicked' => 0 + ])->find(); + if (!$targetMember) { + return json(['code' => 400, 'msg' => '被踢用户不在群内']); + } + + // 不能踢群主 + $groupOwner = ChatGroup::where('id', $groupId)->value('owner_id'); + if ($targetUid == $groupOwner) { + return json(['code' => 403, 'msg' => '不能踢群主']); + } + + // 不能踢自己 + if ($targetUid == $uid) { + return json(['code' => 400, 'msg' => '不能踢自己']); + } + + // 标记为被踢 + $targetMember->quit_time = time(); + $targetMember->is_kicked = 1; + $targetMember->save(); + + // 删除被踢用户的禁言记录 + ChatGroupMute::where([ + 'group_id' => $groupId, + 'user_id' => $targetUid + ])->delete(); + + return json(['code' => 200, 'msg' => '踢人成功']); + } + + /** + * 获取群成员列表 + */ + public function getMembers(Request $request): Response + { + $uid = $request->uid; + $groupId = $request->get('group_id', 0); + + if (!$groupId) { + return json(['code' => 400, 'msg' => '缺少group_id']); + } + + // 验证是否在群内 + $isMember = ChatGroupMember::where([ + 'group_id' => $groupId, + 'user_id' => $uid, + 'quit_time' => null, + 'is_kicked' => 0 + ])->exists(); + if (!$isMember) { + return json(['code' => 403, 'msg' => '不在群内,无法获取成员列表']); + } + + // 获取成员列表 + $members = ChatGroupMember::where([ + 'group_id' => $groupId, + 'quit_time' => null, + 'is_kicked' => 0 + ])->join('chat_user', 'chat_group_member.user_id', 'chat_user.id') + ->select([ + 'chat_group_member.user_id', 'chat_group_member.role', + 'chat_user.username', 'chat_user.avatar', 'chat_user.type' + ])->get()->toArray(); + + return json(['code' => 200, 'msg' => 'success', 'data' => $members]); + } +} diff --git a/app/chat/controller/MessageController.php b/app/chat/controller/MessageController.php new file mode 100644 index 0000000..6e46aa9 --- /dev/null +++ b/app/chat/controller/MessageController.php @@ -0,0 +1,260 @@ +uid; + $chatType = $request->get('chat_type', 1); // 1=单聊,2=群聊 + $toId = $request->get('to_id', 0); // 单聊=对方ID,群聊=群ID + $page = $request->get('page', 1); + $size = $request->get('size', 20); + + if (!$toId) { + return json(['code' => 400, 'msg' => '缺少to_id']); + } + + // 生成会话ID + $sessionId = Session::generateSessionId($chatType, $uid, $toId); + + // 构建查询条件 + $query = ChatMessage::where('session_id', $sessionId); + + // 群聊需验证是否在群内 + if ($chatType == 2) { + $isMember = app\chat\model\ChatGroupMember::where([ + 'group_id' => $toId, + 'user_id' => $uid, + 'quit_time' => null, + 'is_kicked' => 0 + ])->exists(); + if (!$isMember) { + return json(['code' => 403, 'msg' => '不在群内,无法获取历史消息']); + } + } + + // 分页查询(倒序取,再正序返回) + $total = $query->count(); + $messages = $query->orderBy('send_time', 'desc') + ->page($page, $size) + ->get() + ->toArray(); + $messages = array_reverse($messages); + + // 单聊自动标记已读 + if ($chatType == 1) { + ChatMessage::where([ + 'session_id' => $sessionId, + 'to_id' => $uid, + 'is_read' => 0 + ])->update(['is_read' => 1]); + + // 重置未读计数 + ChatUnreadCount::where([ + 'user_id' => $uid, + 'session_id' => $sessionId + ])->update(['count' => 0, 'updated_at' => time()]); + } + + return json([ + 'code' => 200, + 'msg' => 'success', + 'data' => [ + 'list' => $messages, + 'page' => $page, + 'size' => $size, + 'total' => $total + ] + ]); + } + + /** + * 标记消息已读(批量) + */ + public function markRead(Request $request): Response + { + $uid = $request->uid; + $msgIds = $request->post('msg_ids', []); + + if (empty($msgIds) || !is_array($msgIds)) { + return json(['code' => 400, 'msg' => '请传入有效消息ID数组']); + } + + // 标记已读(仅自己接收的消息) + $messages = ChatMessage::whereIn('id', $msgIds) + ->where('to_id', $uid) + ->where('is_read', 0) + ->get(); + + if (empty($messages)) { + return json(['code' => 200, 'msg' => '无未读消息可标记']); + } + + // 批量更新 + $sessionIds = $messages->pluck('session_id')->unique()->toArray(); + ChatMessage::whereIn('id', $msgIds)->where('to_id', $uid)->update(['is_read' => 1]); + + // 更新未读计数 + foreach ($sessionIds as $sessionId) { + $reduceNum = ChatMessage::whereIn('id', $msgIds) + ->where('session_id', $sessionId) + ->count(); + $unread = ChatUnreadCount::where(['user_id' => $uid, 'session_id' => $sessionId])->first(); + if ($unread) { + $newCount = max(0, $unread->count - $reduceNum); + $unread->count = $newCount; + $unread->updated_at = time(); + $unread->save(); + } + } + + return json(['code' => 200, 'msg' => '标记已读成功']); + } + + /** + * 标记会话全部已读 + */ + public function markReadAll(Request $request): Response + { + $uid = $request->uid; + $sessionId = $request->post('session_id', ''); + + if (empty($sessionId)) { + return json(['code' => 400, 'msg' => '缺少session_id']); + } + + // 标记该会话所有未读消息已读 + ChatMessage::where([ + 'session_id' => $sessionId, + 'to_id' => $uid, + 'is_read' => 0 + ])->update(['is_read' => 1]); + + // 重置未读计数 + ChatUnreadCount::where([ + 'user_id' => $uid, + 'session_id' => $sessionId + ])->update(['count' => 0, 'updated_at' => time()]); + + return json(['code' => 200, 'msg' => '标记全部已读成功']); + } + + /** + * 获取未读消息总数 + */ + public function getUnreadCount(Request $request): Response + { + $uid = $request->uid; + $total = ChatUnreadCount::where('user_id', $uid)->sum('count'); + + return json(['code' => 200, 'msg' => 'success', 'data' => ['total' => $total]]); + } + + /** + * 获取会话列表(含置顶、未读、最后消息) + */ + public function getSessionList(Request $request): Response + { + $uid = $request->uid; + + // 获取所有会话ID + $sessionIds = ChatMessage::where(function ($query) use ($uid) { + $query->where('from_id', $uid)->orWhere('to_id', $uid); + })->groupBy('session_id')->pluck('session_id')->toArray(); + + if (empty($sessionIds)) { + return json(['code' => 200, 'msg' => 'success', 'data' => ['list' => []]]); + } + + $sessionList = []; + foreach ($sessionIds as $sessionId) { + // 置顶状态 + $top = ChatTop::where(['user_id' => $uid, 'session_id' => $sessionId])->first(); + $isTop = $top && $top->status == 1 ? 1 : 0; + $sort = $top ? $top->sort : 0; + + // 未读计数 + $unread = ChatUnreadCount::where(['user_id' => $uid, 'session_id' => $sessionId])->first(); + $unreadCount = $unread ? $unread->count : 0; + + // 最后一条消息 + $lastMsg = ChatMessage::where('session_id', $sessionId) + ->orderBy('send_time', 'desc') + ->first([ + 'id', 'from_id', 'msg_type', 'content', 'image_url', + 'order_id', 'send_time', 'is_read' + ]); + + if (!$lastMsg) continue; + + // 会话类型(单聊/群聊) + $chatType = strpos($sessionId, 'group_') === 0 ? 2 : 1; + $targetInfo = []; + + if ($chatType == 1) { + // 单聊:解析对方ID + list($minId, $maxId) = explode('_', $sessionId); + $targetUid = $uid == $minId ? $maxId : $minId; + $targetUser = ChatUser::find($targetUid); + if ($targetUser) { + $targetInfo = [ + 'id' => $targetUser->id, + 'name' => $targetUser->username, + 'avatar' => $targetUser->avatar, + 'type' => $targetUser->type + ]; + } + } else { + // 群聊:解析群ID + $groupId = str_replace('group_', '', $sessionId); + $group = ChatGroup::find($groupId); + if ($group) { + $targetInfo = [ + 'id' => $group->id, + 'name' => $group->name, + 'avatar' => $group->avatar, + 'owner_id' => $group->owner_id + ]; + } + } + + $sessionList[] = [ + 'session_id' => $sessionId, + 'chat_type' => $chatType, + 'is_top' => $isTop, + 'sort' => $sort, + 'unread_count' => $unreadCount, + 'last_msg' => $lastMsg ? $lastMsg->toArray() : [], + 'target_info' => $targetInfo + ]; + } + + // 排序:置顶(按sort降序)→ 非置顶(按最后消息时间降序) + usort($sessionList, function ($a, $b) { + if ($a['is_top'] != $b['is_top']) { + return $b['is_top'] - $a['is_top']; + } + if ($a['is_top'] == 1) { + return $b['sort'] - $a['sort']; + } + $aTime = $a['last_msg']['send_time'] ?? 0; + $bTime = $b['last_msg']['send_time'] ?? 0; + return $bTime - $aTime; + }); + + return json(['code' => 200, 'msg' => 'success', 'data' => ['list' => $sessionList]]); + } +} diff --git a/app/chat/controller/UploadController.php b/app/chat/controller/UploadController.php new file mode 100644 index 0000000..41bc536 --- /dev/null +++ b/app/chat/controller/UploadController.php @@ -0,0 +1,56 @@ +file('image'); + if (!$file || !$file->isValid()) { + return json(['code' => 400, 'msg' => '图片上传失败']); + } + + // 校验配置 + $uploadConfig = config('process')['chat-gateway']['options']['upload'] ?? []; + $maxSize = $uploadConfig['image_size'] ?? 5 * 1024 * 1024; + $allowTypes = $uploadConfig['image_type'] ?? ['image/jpeg', 'image/png', 'image/gif']; + + // 校验类型和大小 + if (!in_array($file->getMimeType(), $allowTypes)) { + return json(['code' => 400, 'msg' => '仅支持JPG、PNG、GIF格式']); + } + if ($file->getSize() > $maxSize) { + return json(['code' => 400, 'msg' => "图片大小不能超过" . ($maxSize / 1024 / 1024) . "MB"]); + } + + // 保存路径 + $saveDir = public_path() . '/uploads/images/' . date('Ymd'); + if (!is_dir($saveDir)) { + mkdir($saveDir, 0755, true); + } + + // 生成文件名 + $ext = $file->getExtension(); + $filename = uniqid() . '.' . $ext; + $savePath = $saveDir . '/' . $filename; + + // 移动文件 + $file->moveTo($savePath); + + // 访问URL + $imageUrl = '/uploads/images/' . date('Ymd') . '/' . $filename; + + return json([ + 'code' => 200, + 'msg' => '上传成功', + 'data' => ['image_url' => $imageUrl] + ]); + } +} diff --git a/app/chat/model/BaseModel.php b/app/chat/model/BaseModel.php new file mode 100644 index 0000000..873a4d8 --- /dev/null +++ b/app/chat/model/BaseModel.php @@ -0,0 +1,9 @@ +header('token'); - // 基类 - if(empty($get_token)) { - throw new MyBusinessException('参数错误', 500); - } - if($get_token != self::$token) { - throw new MyBusinessException('参数错误', 500); - } - } + + public function success($data = []) + { + return json(['code' => 1, 'msg' => 'success', 'data' => $data]); + } + + public function error($msg = 'fail') + { + return json(['code' => 0, 'msg' => $msg]); + } + } \ No newline at end of file diff --git a/app/controller/YskController.php b/app/controller/YskController.php index 3fd3755..be7e8f1 100644 --- a/app/controller/YskController.php +++ b/app/controller/YskController.php @@ -12,38 +12,5 @@ use Webman\RedisQueue\Client; class YskController extends ApiController { - public function index(Request $request) - { - -// $url = 'http://192.168.1.31/market/admin/coupon/grant'; -// $res = http_post($url, [ -// 'userId' => 1, -// 'couponId' => 1, -// 'num' => 1, -// 'shopId' => 1, -// ]); -// p($res); - - -// $data = \app\model\MessagePushTask::send_push_msg(); -// $data = \app\model\MessagePushTask::send_sms_msg(); - } - - public function sendsms(Request $request) - { - - // 加入队列发送短信 -// $a = AlibabaSms::main([ -// 'templateCode' => 'SMS_244665149', -// 'templateParam' => json_encode(['code' => 1234]), -// 'phoneNumbers' => '15851408673', -// 'signName' => '陕西超掌柜科技', -// ]); -// p($a); - } - - - - } diff --git a/app/event/ChatEvent.php b/app/event/ChatEvent.php new file mode 100644 index 0000000..e69de29 diff --git a/app/functions.php b/app/functions.php index 2cd2985..f9ada1c 100644 --- a/app/functions.php +++ b/app/functions.php @@ -24,6 +24,26 @@ if (!function_exists('p')) { } } + +/** + * Here is your custom functions. + */ +if (!function_exists('d')) { + + /** + * 将数组 key 的命名方式转换为小写驼峰 + * @param array $array 被转换的数组 + * @param array $keys 要转换的 key,默认所有 + * @return array + */ + function d() + { + return date('Y-m-d H:i:s'); + } +} + + + /** * 多维数组去重并重新索引 * @param array $array 待处理的多维数组 diff --git a/app/middleware/JwtAuthMiddleware.php b/app/middleware/JwtAuthMiddleware.php new file mode 100644 index 0000000..acce0d7 --- /dev/null +++ b/app/middleware/JwtAuthMiddleware.php @@ -0,0 +1,28 @@ +header('token')); + if($uid) { + if($request->isGet()) { + $request->setGet('uid', $uid); + }elseif ($request->post()) { + $request->setPost('uid', $uid); + } + }else { + throw new MyBusinessException('请登录', 3000); + } + return $handler($request); + } +} diff --git a/app/utils/Redis.php b/app/utils/Redis.php new file mode 100644 index 0000000..e69de29 diff --git a/app/utils/Session.php b/app/utils/Session.php new file mode 100644 index 0000000..e69de29 diff --git a/config/route.php b/config/route.php index a5064fc..c0a7baa 100644 --- a/config/route.php +++ b/config/route.php @@ -15,6 +15,41 @@ use Webman\Route; +// 聊天模块路由分组 +Route::group('/api/chat', function () { + $jwt_middleware = app\middleware\JwtAuthMiddleware::class; + // 常用语管理 + Route::group('/common-phrase', function () { + Route::get('', app\chat\controller\CommonPhraseController::class . '@index'); // 列表 + Route::post('/add', app\chat\controller\CommonPhraseController::class . '@store'); // 添加 + Route::post('/del/{id}', app\chat\controller\CommonPhraseController::class . '@destroy'); // 删除 + })->middleware($jwt_middleware); + + // 群聊管理 + Route::group('/group', function () { + Route::post('/create', app\chat\controller\GroupController::class . '@create'); // 创建群(商家) + Route::post('/join', app\chat\controller\GroupController::class . '@join'); // 加群 + Route::post('/quit', app\chat\controller\GroupController::class . '@quit'); // 退群 + Route::post('/announcement', app\chat\controller\GroupController::class . '@setAnnouncement'); // 群公告 + Route::post('/do-not-disturb', app\chat\controller\GroupController::class . '@setDoNotDisturb'); // 免打扰 + Route::post('/mute', app\chat\controller\GroupController::class . '@muteMember'); // 禁言 + Route::post('/unmute', app\chat\controller\GroupController::class . '@unmuteMember'); // 解除禁言 + Route::post('/kick', app\chat\controller\GroupController::class . '@kickMember'); // 踢人 + Route::get('/members', app\chat\controller\GroupController::class . '@getMembers'); // 群成员列表 + })->middleware($jwt_middleware); + + // 消息管理 + Route::group('/message', function () { + Route::get('/history', app\chat\controller\MessageController::class . '@history'); // 历史消息 + Route::post('/mark-read', app\chat\controller\MessageController::class . '@markRead'); // 标记已读 + Route::post('/mark-read-all', app\chat\controller\MessageController::class . '@markReadAll'); // 全部已读 + Route::get('/unread-count', app\chat\controller\MessageController::class . '@getUnreadCount'); // 未读总数 + Route::get('/session-list', app\chat\controller\MessageController::class . '@getSessionList'); // 会话列表 + })->middleware($jwt_middleware); + + // 图片上传(相册/拍照) + Route::post('/upload/image', app\chat\controller\UploadController::class . '@image')->middleware($jwt_middleware); +}); diff --git a/extend/chat/model/Base.php b/extend/chat/model/Base.php new file mode 100644 index 0000000..f725653 --- /dev/null +++ b/extend/chat/model/Base.php @@ -0,0 +1,17 @@ + '参数不完整'])); + return; + } + call_user_func_array(['extend\chat\model\\' . $message['type'], $message['operate_type']], [$client_id, $message]); + } +} \ No newline at end of file diff --git a/extend/chat/model/OnbocChat.php b/extend/chat/model/OnbocChat.php new file mode 100644 index 0000000..a3280df --- /dev/null +++ b/extend/chat/model/OnbocChat.php @@ -0,0 +1,24 @@ +' . $str; break; + case 'chat': + $str = '【即时消息】-->' . $str; + break; } $flags = FILE_APPEND | LOCK_EX; // 追加内容并加锁 file_put_contents($file, date('Y-m-d H:i:s') . '------>' . $str . "\r\n", $flags); diff --git a/plugin/webman/gateway/Events.php b/plugin/webman/gateway/Events.php index 2c42bff..47c4190 100644 --- a/plugin/webman/gateway/Events.php +++ b/plugin/webman/gateway/Events.php @@ -101,6 +101,9 @@ class Events case 'pad': Base::add_log_file($m, 'pad', true); break; + case 'chat': + Base::add_log_file($m, 'chat', true); + break; default: Base::add_log_file($m, 'other', true); } @@ -108,6 +111,13 @@ class Events Gateway::sendToClient($client_id, json_encode(['msg' => 'ok', 'msg_id' => 'ping_interval'])); return; } + + // 即时聊天 手机端 + if(strstr($message['type'], 'Chat')) { + (new \extend\chat\model\Base)->handles($client_id, $message); + return; + } + $type = $message['type']; if(!empty($message['is_temporary']) && (empty($message['product_name']))) { Gateway::sendToClient($client_id, json_encode(['msg' => '临时菜请添加菜名']));