优化群聊操作

This commit is contained in:
kuaifan 2022-04-14 22:50:39 +08:00
parent fcd6b1ddec
commit 6ca13bf263
6 changed files with 205 additions and 52 deletions

View File

@ -305,7 +305,7 @@ class DialogController extends AbstractController
$fileData['thumb'] = Base::unFillUrl($fileData['thumb']);
$fileData['size'] *= 1024;
//
if ($dialog->type === 'group' && $dialog->group_type === 'task') { // 任务群保存文件
if ($dialog->type === 'group' && $dialog->group_type === 'task') { // 任务群保存文件
if ($image_attachment || !in_array($fileData['ext'], File::imageExt)) { // 如果是图片不保存
$task = ProjectTask::whereDialogId($dialog->id)->first();
if ($task) {
@ -552,15 +552,15 @@ class DialogController extends AbstractController
}
/**
* @api {get} api/dialog/group/add 15. 新增群
* @api {get} api/dialog/group/add 15. 新增群
*
* @apiDescription 需要token身份
* @apiVersion 1.0.0
* @apiGroup dialog
* @apiName group__add
*
* @apiParam {String} chat_name 群名
* @apiParam {Array} userids 群成员,格式: [userid1, userid2, userid3]
* @apiParam {String} chat_name 群名称
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
@ -570,8 +570,8 @@ class DialogController extends AbstractController
{
$user = User::auth();
//
$chatName = trim(Request::input('chat_name'));
$userids = Request::input('userids');
$chatName = trim(Request::input('chat_name'));
//
if (!is_array($userids)) {
return Base::retError('请选择群成员');
@ -586,7 +586,7 @@ class DialogController extends AbstractController
$array = [];
foreach ($userids as $userid) {
$array[] = User::userid2nickname($userid);
if (count($array) >= 8 || strlen(implode(", ", $array)) > 200) {
if (count($array) >= 8 || strlen(implode(", ", $array)) > 100) {
$array[] = "...";
break;
}
@ -595,11 +595,53 @@ class DialogController extends AbstractController
}
$dialog = WebSocketDialog::createGroup($chatName, $userids, 'user', $user->userid);
if (empty($dialog)) {
return Base::retError('创建群失败');
return Base::retError('创建群失败');
}
return Base::retSuccess('创建成功', $dialog);
}
/**
* @api {get} api/dialog/group/edit 16. 修改群组
*
* @apiDescription 需要token身份
* @apiVersion 1.0.0
* @apiGroup dialog
* @apiName group__edit
*
* @apiParam {Number} dialog_id 会话ID
* @apiParam {String} chat_name 群名称
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function group__edit()
{
$user = User::auth();
//
$dialog_id = intval(Request::input('dialog_id'));
$chatName = trim(Request::input('chat_name'));
//
if (mb_strlen($chatName) < 2) {
return Base::retError('群名称至少2个字');
}
if (mb_strlen($chatName) > 100) {
return Base::retError('群名称最长限制100个字');
}
//
$dialog = WebSocketDialog::checkDialog($dialog_id);
if ($dialog->owner_id != $user->userid) {
return Base::retError('仅限群主操作');
}
//
$dialog->name = $chatName;
$dialog->save();
return Base::retSuccess('修改成功', [
'id' => $dialog->id,
'name' => $dialog->name,
]);
}
/**
* @api {get} api/dialog/group/user 16. 获取群成员
*
@ -702,4 +744,33 @@ class DialogController extends AbstractController
$dialog->exitGroup($userids);
return Base::retSuccess($type === 'remove' ? '移出成功' : '退出成功');
}
/**
* @api {get} api/dialog/group/disband 16. 解散群组
*
* @apiDescription 需要token身份
* @apiVersion 1.0.0
* @apiGroup dialog
* @apiName group__disband
*
* @apiParam {Number} dialog_id 会话ID
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function group__disband()
{
$user = User::auth();
//
$dialog_id = intval(Request::input('dialog_id'));
//
$dialog = WebSocketDialog::checkDialog($dialog_id);
if ($dialog->owner_id != $user->userid) {
return Base::retError('仅限群主操作');
}
//
$dialog->disbandGroup();
return Base::retSuccess('解散成功');
}
}

View File

@ -84,7 +84,10 @@ class WebSocketDialog extends AbstractModel
public function joinGroup($userid)
{
if ($this->type !== 'group') {
return false;
throw new ApiException('此操作仅限群组');
}
if ($this->group_type !== 'user') {
throw new ApiException('此操作仅限个人群组');
}
AbstractModel::transaction(function () use ($userid) {
foreach (is_array($userid) ? $userid : [$userid] as $value) {
@ -106,6 +109,12 @@ class WebSocketDialog extends AbstractModel
*/
public function exitGroup($userid)
{
if ($this->type !== 'group') {
throw new ApiException('此操作仅限群组');
}
if ($this->group_type !== 'user') {
throw new ApiException('此操作仅限个人群组');
}
$builder = WebSocketDialogUser::whereDialogId($this->id);
if (is_array($userid)) {
$builder->whereIn('userid', $userid);
@ -125,6 +134,29 @@ class WebSocketDialog extends AbstractModel
return true;
}
/**
* 解散群组
* @return bool
*/
public function disbandGroup()
{
if ($this->type !== 'group') {
throw new ApiException('此操作仅限群组');
}
if ($this->group_type !== 'user') {
throw new ApiException('此操作仅限个人群组');
}
return AbstractModel::transaction(function() {
WebSocketDialogUser::whereDialogId($this->id)->chunkById(100, function($list) {
/** @var WebSocketDialogUser $item */
foreach ($list as $item) {
$item->delete();
}
});
return $this->delete();
});
}
/**
* 获取对话(同时检验对话身份)
* @param $dialog_id
@ -148,7 +180,7 @@ class WebSocketDialog extends AbstractModel
}
}
if (!WebSocketDialogUser::whereDialogId($dialog->id)->whereUserid($userid)->exists()) {
throw new ApiException('不在成员列表内');
throw new ApiException('不在成员列表内', ['dialog_id' => $dialog_id], -4003);
}
return $dialog;
}

View File

@ -16,20 +16,11 @@
clearable/>
</div>
<div v-if="dialogData.owner_id == userId" @click="openAdd" class="group-info-button">
<Icon type="md-add" />
<span>{{ $L("添加成员") }}</span>
</div>
<div v-else @click="onExit" class="group-info-button">
<Icon type="md-exit" />
<span>{{ $L("退出群聊") }}</span>
</div>
<div class="group-info-user">
<ul>
<li v-for="(item, index) in userList" :key="index">
<UserAvatar :userid="item.userid" :size="32" :user-result="userResult" showName tooltipDisabled/>
<Tag v-if="item.userid === dialogData.owner_id" color="primary">{{ $L("群主") }}</Tag>
<div v-if="item.userid === dialogData.owner_id" class="user-tag">{{ $L("群主") }}</div>
<Icon v-else-if="dialogData.owner_id == userId" class="user-exit" type="md-exit" @click="onExit(item)"/>
</li>
<li v-if="userList.length === 0" class="no">
@ -39,6 +30,14 @@
</ul>
</div>
<div v-if="dialogData.owner_id == userId" class="group-info-button">
<Button @click="openAdd" type="primary">{{ $L("添加成员") }}</Button>
<Button @click="onDisband" type="error" ghost>{{ $L("解散群组") }}</Button>
</div>
<div v-else class="group-info-button">
<Button @click="onExit" type="error" ghost>{{ $L("退出群组") }}</Button>
</div>
<!--添加成员-->
<Modal
v-model="addShow"
@ -129,8 +128,24 @@ export default {
},
methods: {
updateName() {
updateName(val, cb) {
if (!val) {
cb()
return;
}
this.$store.dispatch("call", {
url: 'dialog/group/edit',
data: {
dialog_id: this.dialogId,
chat_name: val
}
}).then(({data}) => {
this.$store.dispatch("saveDialog", data);
cb()
}).catch(({msg}) => {
$A.modalError(msg);
cb()
});
},
getDialogUser() {
@ -193,10 +208,10 @@ export default {
},
onExit(item) {
let content = "你确定要退出群吗?"
let content = "你确定要退出群吗?"
let userids = [];
if ($A.isJson(item)) {
content = `你确定要将【${item.nickname}】移出群吗?`
content = `你确定要将【${item.nickname}】移出群吗?`
userids = [item.userid];
}
$A.modalConfirm({
@ -212,7 +227,7 @@ export default {
}).then(({msg}) => {
this.$Modal.remove();
$A.messageSuccess(msg);
if (userids === "my") {
if (userids.length > 0) {
this.getDialogUser();
} else {
this.$store.dispatch("forgetDialog", this.dialogId);
@ -224,7 +239,31 @@ export default {
});
},
});
}
},
onDisband() {
$A.modalConfirm({
content: `你确定要解散【${this.dialogData.name}】群组吗?`,
loading: true,
okText: '解散',
onOk: () => {
this.$store.dispatch("call", {
url: 'dialog/group/disband',
data: {
dialog_id: this.dialogId,
}
}).then(({msg}) => {
this.$Modal.remove();
$A.messageSuccess(msg);
this.$store.dispatch("forgetDialog", this.dialogId);
this.goForward({name: 'manage-messenger'});
}).catch(({msg}) => {
$A.modalError(msg, 301);
this.$Modal.remove();
});
},
});
},
}
}
</script>

View File

@ -35,7 +35,7 @@
</template>
</div>
<template v-if="dialogData.type === 'group'">
<ETooltip v-if="dialogData.group_type === 'user'" placement="top" :content="$L('群设置')">
<ETooltip v-if="dialogData.group_type === 'user'" placement="top" :openDelay="600" :content="$L('群设置')">
<i class="taskfont dialog-create" @click="groupInfoShow = true">&#xe6e9;</i>
</ETooltip>
</template>
@ -127,10 +127,10 @@
</div>
</Modal>
<!--创建群-->
<!--创建群-->
<Modal
v-model="createGroupShow"
:title="$L('创建群')"
:title="$L('创建群')"
:mask-closable="false">
<Form :model="createGroupData" label-width="auto" @submit.native.prevent>
<FormItem prop="userids" :label="$L('群成员')">

View File

@ -191,6 +191,18 @@ body.dark-mode-reverse {
}
}
.dialog-group-info {
.group-info-user {
> ul {
> li {
.user-tag {
color: $primary-title-color;
}
}
}
}
}
.file-icon {
&:before {
background-image: url("../images/file/dark/other.svg");

View File

@ -24,29 +24,25 @@
overflow: visible;
white-space: normal;
}
.quick-input {
display: flex;
flex-direction: column;
}
}
.group-info-search {
margin: 18px 24px 0;
margin: 24px 24px 0;
}
.group-info-button {
display: flex;
align-items: center;
margin: 18px 24px 0;
justify-content: center;
margin: 18px 24px;
cursor: pointer;
> i {
display: flex;
align-items: center;
justify-content: center;
height: 32px;
width: 32px;
font-size: 18px;
margin-right: 8px;
border-radius: 50%;
color: #777;
border: 1px solid #ddd;
> button {
margin: 0 8px;
}
}
@ -87,14 +83,26 @@
}
}
.user-tag {
margin-left: 4px;
height: 22px;
line-height: 22px;
padding: 0 6px;
border-radius: 3px;
transform: scale(0.9);
transform-origin: right center;
color: #ffffff;
background-color: $primary-color;
}
.user-exit {
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
margin-left: 4px;
width: 20px;
height: 20px;
width: 22px;
height: 22px;
font-size: 12px;
color: #999999;
border: 1px solid #dddddd;
@ -103,15 +111,6 @@
transform: translateX(50%);
transition: all 0.2s;
}
.ivu-tag {
margin-left: 4px;
height: 20px;
line-height: 20px;
padding: 0 5px;
transform: scale(0.9);
transform-origin: right center;
}
}
}
}