578 lines
19 KiB
PHP
578 lines
19 KiB
PHP
<?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 support\Log;
|
||
use support\Request;
|
||
use support\Response;
|
||
use support\think\Db;
|
||
|
||
class GroupController extends ApiController
|
||
{
|
||
|
||
|
||
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();
|
||
// 先判断在没在群里
|
||
$group_user = Db::name('chat_group_member')->where(['group_id' => $group_id, 'user_id' => $this->uid, 'quit_time' => null, 'is_kicked' => 0])->find();
|
||
$data['is_th'] = 1;
|
||
if($group_user) {
|
||
$data['is_th'] = 0;
|
||
}
|
||
$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 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,
|
||
]);
|
||
$user = Db::name('chat_user')->where(['user_id' => $this->uid])->find();
|
||
$data = [
|
||
'group_info' => [
|
||
'id' => $group_id,
|
||
'name' => $name,
|
||
'avatar' => $avatar,
|
||
],
|
||
'member_info' => [
|
||
'user_id' => $this->uid,
|
||
'avatar' => $user['avatar'],
|
||
'nick_name' => $user['nick_name'],
|
||
]
|
||
];
|
||
Db::commit();
|
||
return $this->success($data);
|
||
}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('已在群内');
|
||
}
|
||
|
||
|
||
// 再次加入时
|
||
$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) {
|
||
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);
|
||
}
|
||
}
|
||
|
||
|