Files
p_ysk/app/chat/controller/GroupController.php
2025-11-18 13:38:05 +08:00

460 lines
14 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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\common\controller\ApiController;
use app\utils\Session;
use support\Request;
use support\Response;
use support\think\Db;
class GroupController extends ApiController
{
/**
* 创建群(仅商家可创建)
*/
public function create(Request $request): Response
{
if ($this->user_type == 1) { // 2=商家
return $this->error('仅商家可创建群聊');
}
$shop_id = $request->post('shop_id', 0);
if(empty($shop_id)) {
return $this->error('参数不完整');
}
$shop = Db::name('tb_shop_info')->where(['id' => $shop_id])->find();
if(empty($shop)) {
return $this->error('店铺不存在');
}
// 查找群数量
$count = Db::name('chat_group')->where(['shop_id' => $shop_id])->count();
$name = $request->post('name')?:$shop['shop_name'] . '粉丝福利' . $count + 1 . '群';
$avatar = $request->post('avatar')?:$shop['logo'];
$announcement = $request->post('announcement', '');
$isPublic = $request->post('is_public', 0);
$now = d();
try {
Db::startTrans();
// 创建群
$group_id = Db::name('chat_group')->insertGetId([
'name' => $name,
'shop_id' => $shop_id,
'avatar' => $avatar,
'owner_id' => $this->uid,
'announcement' => $announcement,
'is_public' => $isPublic,
'created_time' => $now,
]);
// 群主加入群
Db::name('chat_group_member')->insert([
'group_id' => $group_id,
'user_id' => $this->uid,
'role' => 1, // 1=群主
'join_time' => $now,
]);
Db::commit();
return $this->success(['group_id' => $group_id]);
}catch (\Throwable $exception) {
Db::rollback();
return $this->error($exception->getMessage());
}
}
/**
* 加群
*/
public function join(Request $request): Response
{
$group_id = $request->post('group_id');
$invite = $request->post('invite');
if (!$group_id) {
return $this->error('缺少group_id');
}
// 验证群是否存在
$group = Db::name('chat_group')->where(['id' => $group_id])->find();
if (!$group) {
return $this->error('群不存在');
}
// 验证是否已在群内
$exists = Db::name('chat_group_member')->where([
'group_id' => $group_id,
'user_id' => $this->uid,
'quit_time' => null,
'is_kicked' => 0
])->find();
if ($exists) {
return $this->error('已在群内');
}
// 被踢用户不能重新加入(需群主邀请)
$isKicked = Db::name('chat_group_member')->where([
'group_id' => $group_id,
'user_id' => $this->uid,
'is_kicked' => 1
])->find();
// 如果不是邀请
if(empty($invite) && $isKicked) {
return $this->error('你已被移出该群,无法重新加入');
}
$insert_arr = [
'group_id' => $group_id,
'user_id' => $this->uid,
'role' => 3,
'join_time' => d(),
];
$is_insert = true;
if($invite) {
// 验证邀请参数是否正常
$decryptedText = simple_decrypt($invite, config('cons.sercer_key'));
$decryptedText_arr = json_decode($decryptedText, true);
if($isKicked) {
$is_insert = false;
$insert_arr['is_kicked'] = 0;
}
$insert_arr['pid'] = $decryptedText_arr['pid'];
$insert_arr['group_id'] = $decryptedText_arr['group_id'];
$group_id = $decryptedText_arr['group_id'];
}
// 加入群
if($is_insert) {
$res = Db::name('chat_group_member')->insert($insert_arr);
}else {
$res = Db::name('chat_group_member')->where(['user_id' => $this->uid, 'group_id' => $group_id])->update($insert_arr);
}
if($res) {
return $this->success();
}else {
return $this->error();
}
}
// 获取群邀请链接参数
public function getgrepurl(Request $request): Response
{
$group_id = $request->post('group_id');
if (!$group_id) {
return $this->error('缺少group_id');
}
if($this->user_type == 1) {
return $this->error('角色有误');
}
$data = [
'pid' => $this->uid,
'group_id' => $group_id
];
return $this->success(simple_encrypt(json_encode($data), config('cons.sercer_key')));
}
/**
* 退群
*/
public function quit(Request $request): Response
{
$groupId = $request->post('group_id')?:0;
if (!$groupId) {
return $this->error('缺少group_id');
}
// 验证是否是群主(群主不能退群,需转让)
$owner = Db::name('chat_group_member')->where([
'group_id' => $groupId,
'user_id' => $this->uid,
'quit_time' => null
])->find();
if ($owner) {
if($owner['role'] == 1) {
return $this->error('群主不能退群,请先转让群');
}
}else {
return $this->error('不在群内');
}
$res = Db::name('chat_group_member')->where([
'group_id' => $groupId,
'user_id' => $this->uid,
])->update(['quit_time' => d()]);
if($res) {
return $this->success();
}
return $this->error();
}
/**
* 设置群公告(仅群主/管理员)
*/
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]);
}
}