Files
p_ysk/app/chat/controller/GroupController.php
2025-12-05 18:24:33 +08:00

579 lines
18 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\exception\MyBusinessException;
use app\utils\Session;
use ba\Random;
use support\Log;
use support\Redis;
use support\Request;
use support\Response;
use support\think\Db;
class GroupController extends ApiController
{
/**
* 改群名
* @param Request $request
* @return Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function editTitle(Request $request): Response
{
$group_id = $request->post('group_id');
$title = $request->post('title');
if (empty($group_id) ||empty($title)) {
return $this->error('参数不存在');
}
// 验证是否是群主
$owner = Db::name('chat_group_member')->where([
'group_id' => $group_id,
'user_id' => $this->uid,
'role' => 1,
'quit_time' => null
])->find();
if (!$owner) {
return $this->error('无权修改');
}
$res = Db::name('chat_group')->where([
'id' => $group_id,
'owner_id' => $this->uid,
])->update([
'name' => $title
]);
if($res) {
// 删除群聊中的所有人的会话列表
$group_member = Db::name('chat_group_member')->where(['group_id' => $group_id])->select()->toArray();
foreach ($group_member as $k => $v) {
$role = $v['role']==1?2:1;
Redis::del('usermsg:list:' . $role . ':' . $v['user_id']);
}
return $this->success();
}else {
return $this->error('修改失败');
}
}
public function shopInfo(Request $request): Response
{
$group_id = $request->post('shop_id');
if (empty($group_id)) {
return $this->error('参数不存在');
}
$group_arr = Db::name('chat_group')->where(['shop_id' => $group_id])->select()->toArray();
if($group_arr) {
foreach ($group_arr as $k => $v) {
// 先判断在没在群里
$group_arr[$k]['is_th'] = 1;
$mute = Db::name('chat_group_mute')->where(['group_id' => $v['id'], 'user_id' => 0])->find();
$group_arr[$k]['is_mute'] = $mute?1:0;
}
}
return $this->success($group_arr);
}
public function info(Request $request): Response
{
$group_id = $request->post('group_id');
if (empty($group_id)) {
return $this->error('参数不存在');
}
$data = Db::name('chat_group')->where(['id' => $group_id])->find();
// 先判断在没在群里
$data['is_th'] = ChatGroup::isTh($group_id, $this->uid);
$mute = Db::name('chat_group_mute')->where(['group_id' => $group_id, 'user_id' => 0])->find();
$data['is_mute'] = $mute?1:0;
return $this->success($data);
}
/**
* 加群
*/
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('已在群内');
}
// 再次加入时
$z_exists = Db::name('chat_group_member')->where([
'group_id' => $group_id,
'user_id' => $this->uid,
'is_kicked' => 0
])->where('quit_time', 'not null')->find();
// 被踢用户不能重新加入(需群主邀请)
$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($z_exists) {
$insert_arr['quit_time'] = null;
$is_insert = false;
}
try {
Db::startTrans();
// 插入用户信息
if($this->user_type == 1) {
// 用户
$user = Db::name('tb_user_info')->where(['id' => $this->uid])->find();
if($user) {
$user_arr = [
'user_id' => $this->uid,
'nick_name' => $user['nick_name'],
'avatar' => $user['head_img'],
'type' => 1,
'created_time' => d(),
];
}else {
throw new MyBusinessException('用户信息不存在');
}
}elseif ($this->user_type == 2) {
// 商家
$user = Db::name('sys_user')->where(['id' => $this->uid])->find();
if($user) {
$user_arr = [
'user_id' => $this->uid,
'nick_name' => $user['nick_name'],
'avatar' => $user['avatar'],
'type' => 2,
'created_time' => d(),
];
}else {
throw new MyBusinessException('用户信息不存在');
}
}
if(!Db::name('chat_user')->where(['user_id' => $this->uid])->find()) {
Db::name('chat_user')->insert($user_arr);
}
// 加入群
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);
}
Db::commit();
if($res) {
Redis::del('usermsg:list:' . $this->user_type . ':' . $this->uid);
return $this->success();
}else {
return $this->error();
}
}catch (\Throwable $exception) {
Db::rollback();
return $this->error($exception->getMessage());
}
}
// 获取群邀请链接参数
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 tarsgroup(Request $request): Response
{
$group_id = $request->post('group_id');
$object_user_id = $request->post('object_user_id'); // 目标ID
if(empty($group_id) || empty($object_user_id)) {
return $this->error('group_id 或 object_id 不能为空');
}
// 判断当前人是不是群主
$owner = Db::name('chat_group_member')->where([
'group_id' => $group_id,
'user_id' => $this->uid,
'quit_time' => null,
'role' => 1
])->find();
if(!$owner) {
return $this->error('你当前不是群主,无法转让');
}
// 查询
$chat_user = Db::name('chat_user')->where([
'user_id' => $object_user_id,
'status' => 1,
'type' => 2,
])->find();
if(!$chat_user) {
return $this->error('目标用户不存在');
}
$res = Db::name('chat_group_member')->where([
'group_id' => $group_id,
'user_id' => $this->uid,
'quit_time' => null,
'role' => 1
])->update(['user_id' => $object_user_id, 'object_user_id' => $this->uid]);
Db::name('chat_group')->where([
'id' => $group_id,
])->update(['owner_id' => $object_user_id]);
if($res) {
return $this->success();
}
return $this->error();
}
/**
* 设置群公告(仅群主/管理员)
*/
public function setAnnouncement(Request $request): Response
{
$groupId = $request->post('group_id');
$announcement = $request->post('announcement');
if (!$groupId || !$announcement) {
return $this->error('缺少group_id或公共内容不能为空');
}
// 验证权限
$role = Db::name('chat_group_member')->where([
'group_id' => $groupId,
'user_id' => $this->uid,
'quit_time' => null,
'is_kicked' => 0
])->value('role');
if (!in_array($role, [1, 2])) { // 1=群主2=管理员
return $this->error('仅群主和管理员可设置群公告');
}
// 更新公告
Db::name('chat_group')->where('id', $groupId)->update([
'announcement' => $announcement,
'updated_time' => d()
]);
return $this->success();
}
/**
* 设置群免打扰
*/
public function setDoNotDisturb(Request $request): Response
{
$groupId = $request->post('group_id');
$status = $request->post('status'); // 0=关闭1=开启
if (!$groupId) {
return $this->error('缺少group_id');
}
// 验证是否在群内
$isMember = Db::name('chat_group_member')->where([
'group_id' => $groupId,
'user_id' => $this->uid,
'quit_time' => null,
'is_kicked' => 0
])->find();
if (!$isMember) {
return $this->error('不在群内');
}
$res = Db::name('chat_group_member')->where([
'group_id' => $groupId,
'user_id' => $this->uid,
])->update(['is_dist' => $status]);
if($res) {
return $this->success();
}
return $this->error();
}
/**
* 群禁言(仅群主/管理员)
*/
public function muteMember(Request $request): Response
{
$groupId = $request->post('group_id');
$targetUid = $request->post('target_uid')?:0;
$muteTime = $request->post('mute_time')?:0; // 默认时间
if (!$groupId || !isset($targetUid)) {
return json(['code' => 400, 'msg' => '缺少group_id或target_uid']);
}
// 验证操作人权限
$operatorRole = Db::name('chat_group_member')->where([
'group_id' => $groupId,
'user_id' => $this->uid,
'quit_time' => null,
'is_kicked' => 0
])->value('role');
if (!in_array($operatorRole, [1, 2])) {
return $this->error('仅群主和管理员可禁言');
}
$res = Db::name('chat_group_mute')->where(['group_id' => $groupId, 'user_id' => $targetUid])->find();
// // 验证被禁言用户是否在群内
// $targetIsMember = Db::name('chat_group_member')->where([
// 'group_id' => $groupId,
// 'user_id' => $targetUid,
// 'quit_time' => null,
// 'is_kicked' => 0
// ])->find();
// if (!$targetIsMember) {
// return $this->error('被禁言用户不在群内');
// }
// // 不能禁言群主
// $groupOwner = Db::name('chat_group')->where('id', $groupId)->value('owner_id');
// if ($targetUid == $groupOwner) {
// return $this->error('不能禁言群主');
// }
// // 不能禁言自己
// if ($targetUid == $this->uid) {
// return $this->error('不能禁言自己');
// }
// $now = time();
// $expireTime = $muteTime > 0 ? $now + $muteTime : null;
// 新增/更新禁言记录
if($res) {
return $this->success("已禁言无需操作");
}else {
Db::name('chat_group_mute')->insert([
'group_id' => $groupId,
'user_id' => $targetUid,
'operator_id' => $this->uid,
'created_time' => d()
]);
}
return $this->success("禁言成功");
}
/**
* 解除禁言(仅群主/管理员)
*/
public function unmuteMember(Request $request): Response
{
$groupId = $request->post('group_id');
$targetUid = $request->post('target_uid')?:0;
$muteTime = $request->post('mute_time')?:3600; // 默认禁言1小时
if (!$groupId || !isset($targetUid)) {
return json(['code' => 400, 'msg' => '缺少group_id或target_uid']);
}
// 验证操作人权限
$operatorRole = Db::name('chat_group_member')->where([
'group_id' => $groupId,
'user_id' => $this->uid,
'quit_time' => null,
'is_kicked' => 0
])->value('role');
if (!in_array($operatorRole, [1, 2])) {
return $this->error('仅群主和管理员可禁言');
}
Db::name('chat_group_mute')->where(['group_id' => $groupId, 'user_id' => $targetUid])->delete();
return $this->success();
}
/**
* 踢人(仅群主/管理员)
*/
public function kickMember(Request $request): Response
{
$groupId = $request->post('group_id');
$targetUid = $request->post('target_uid');
if (!$groupId || !$targetUid) {
return json(['code' => 400, 'msg' => '缺少group_id或target_uid']);
}
// 验证操作人权限
$operatorRole = Db::name('chat_group_member')->where([
'group_id' => $groupId,
'user_id' => $this->uid,
'quit_time' => null,
'is_kicked' => 0
])->value('role');
if (!in_array($operatorRole, [1, 2])) {
return $this->error('仅群主和管理员可踢人');
}
// 验证被踢用户是否在群内
$targetIsMember = Db::name('chat_group_member')->where([
'group_id' => $groupId,
'user_id' => $targetUid,
'quit_time' => null,
'is_kicked' => 0
])->find();
if (!$targetIsMember) {
return $this->error('被踢用户不在群内');
}
// 不能踢群主
$groupOwner = Db::name('chat_group')->where('id', $groupId)->value('owner_id');
if ($targetUid == $groupOwner) {
return $this->error( '不能踢群主');
}
// 不能踢自己
if ($targetUid == $this->uid) {
return $this->error('不能踢自己');
}
// 标记为被踢
Db::name('chat_group_member')->where([
'group_id' => $groupId,
'user_id' => $targetUid,
])->update([
'quit_time' => d(),
'is_kicked' => 1
]);
// 删除被踢用户的禁言记录
Db::name('chat_group_mute')->where([
'group_id' => $groupId,
'user_id' => $targetUid
])->delete();
return $this->success();
}
/**
* 获取群成员列表
*/
public function getMembers(Request $request): Response
{
$groupId = $request->post('group_id');
if (!$groupId) {
return $this->error('缺少group_id');
}
// 验证被踢用户是否在群内
$targetIsMember = Db::name('chat_group_member')->where([
'group_id' => $groupId,
'user_id' => $this->uid,
'quit_time' => null,
'is_kicked' => 0
])->find();
if (!$targetIsMember) {
return $this->error('用户不在群内');
}
// 获取成员列表
$data['user_list'] = Db::name('chat_group_member')->where([
'group_id' => $groupId,
'quit_time' => null,
'is_kicked' => 0,
])
->alias('member')
->leftJoin('chat_user user', 'member.user_id = user.user_id')
->field('member.id as id, user.user_id as user_id, role, nick_name, avatar')
->order('member.id', 'asc')
->select();
$data['grep_set'] = [
'is_not_disturb' => $targetIsMember['is_dist'],
'group_id' => $groupId
];
return $this->success($data);
}
}