This commit is contained in:
2025-11-18 09:37:05 +08:00
parent 61b2ccf106
commit a3e5568f93
27 changed files with 1055 additions and 46 deletions

View File

@@ -0,0 +1,418 @@
<?php
namespace app\chat\controller;
use app\chat\model\ChatGroup;
use app\chat\model\ChatGroupMember;
use app\chat\model\ChatGroupMute;
use app\chat\model\ChatDoNotDisturb;
use app\utils\Session;
use support\Request;
use support\Response;
class GroupController
{
/**
* 创建群(仅商家可创建)
*/
public function create(Request $request): Response
{
$uid = $request->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]);
}
}