perf: 个人群支持转让群主

This commit is contained in:
kuaifan 2022-11-19 20:25:03 +08:00
parent c1275bac56
commit cd56e3ec6f
5 changed files with 237 additions and 64 deletions

View File

@ -1314,7 +1314,7 @@ class DialogController extends AbstractController
* @apiName group__adduser * @apiName group__adduser
* *
* @apiParam {Number} dialog_id 会话ID * @apiParam {Number} dialog_id 会话ID
* @apiParam {Array} userids 移出的群成员,格式: [userid1, userid2, userid3] * @apiParam {Array} [userids] 移出的群成员,格式: [userid1, userid2, userid3]
* - 留空表示自己退出 * - 留空表示自己退出
* - 有值表示移出,仅限群主操作 * - 有值表示移出,仅限群主操作
* *
@ -1347,6 +1347,50 @@ class DialogController extends AbstractController
return Base::retSuccess($type === 'remove' ? '移出成功' : '退出成功'); return Base::retSuccess($type === 'remove' ? '移出成功' : '退出成功');
} }
/**
* @api {get} api/dialog/group/transfer 31. 转让群组
*
* @apiDescription 需要token身份
* - 只有群主且是个人类型群可以解散
* @apiVersion 1.0.0
* @apiGroup dialog
* @apiName group__transfer
*
* @apiParam {Number} dialog_id 会话ID
* @apiParam {Number} userid 新的群主
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function group__transfer()
{
$user = User::auth();
//
$dialog_id = intval(Request::input('dialog_id'));
$userid = intval(Request::input('userid'));
//
if ($userid === $user->userid) {
return Base::retError('你已经是群主');
}
if (!User::whereUserid($userid)->exists()) {
return Base::retError('请选择有效的新群主');
}
//
$dialog = WebSocketDialog::checkDialog($dialog_id, true);
//
$dialog->checkGroup('user');
$dialog->owner_id = $userid;
if ($dialog->save()) {
$dialog->joinGroup($userid, 0);
$dialog->pushMsg("groupUpdate", [
'id' => $dialog->id,
'owner_id' => $dialog->owner_id,
]);
}
return Base::retSuccess('转让成功');
}
/** /**
* @api {get} api/dialog/group/disband 31. 解散群组 * @api {get} api/dialog/group/disband 31. 解散群组
* *

View File

@ -144,26 +144,32 @@ class WebSocketDialog extends AbstractModel
* 加入聊天室 * 加入聊天室
* @param int|array $userid 加入的会员ID或会员ID组 * @param int|array $userid 加入的会员ID或会员ID组
* @param int $inviter 邀请人 * @param int $inviter 邀请人
* @param bool $important 重要人员 * @param bool|null $important 重要人员(null不修改、bool修改)
* @return bool * @return bool
*/ */
public function joinGroup($userid, $inviter, $important = false) public function joinGroup($userid, $inviter, $important = null)
{ {
AbstractModel::transaction(function () use ($important, $inviter, $userid) { AbstractModel::transaction(function () use ($important, $inviter, $userid) {
foreach (is_array($userid) ? $userid : [$userid] as $value) { foreach (is_array($userid) ? $userid : [$userid] as $value) {
if ($value > 0) { if ($value > 0) {
$updateData = [
'inviter' => $inviter,
];
if (is_bool($important)) {
$updateData['important'] = $important ? 1 : 0;
}
$isInsert = false;
WebSocketDialogUser::updateInsert([ WebSocketDialogUser::updateInsert([
'dialog_id' => $this->id, 'dialog_id' => $this->id,
'userid' => $value, 'userid' => $value,
], [ ], $updateData, [], $isInsert);
'inviter' => $inviter, if ($isInsert) {
'important' => $important ? 1 : 0,
]);
WebSocketDialogMsg::sendMsg(null, $this->id, 'notice', [ WebSocketDialogMsg::sendMsg(null, $this->id, 'notice', [
'notice' => User::userid2nickname($value) . " 已加入群组" 'notice' => User::userid2nickname($value) . " 已加入群组"
], $inviter, true, true); ], $inviter, true, true);
} }
} }
}
}); });
$this->pushMsg("groupUpdate", [ $this->pushMsg("groupUpdate", [
'id' => $this->id, 'id' => $this->id,

View File

@ -33,11 +33,7 @@
</div> </div>
<div v-if="dialogData.group_type !== 'all'" class="group-info-button"> <div v-if="dialogData.group_type !== 'all'" class="group-info-button">
<Button v-if="dialogData.owner_id == userId || dialogData.owner_id == 0" @click="openAdd" type="primary">{{ $L("添加成员") }}</Button> <Button v-if="dialogData.owner_id == userId || dialogData.owner_id == 0" @click="openAdd" type="primary" icon="md-add">{{ $L("添加成员") }}</Button>
<template v-if="dialogData.owner_id == userId">
<Button v-if="dialogData.group_type !== 'department'" @click="onDisband" type="error" ghost>{{ $L("解散群组") }}</Button>
</template>
<Button v-else @click="onExit" type="error" ghost>{{ $L("退出群组") }}</Button>
</div> </div>
<!--添加成员--> <!--添加成员-->
@ -247,30 +243,6 @@ export default {
}); });
}, },
onDisband() {
$A.modalConfirm({
content: `你确定要解散【${this.dialogData.name}】群组吗?`,
loading: true,
okText: '解散',
onOk: () => {
return new Promise((resolve, reject) => {
this.$store.dispatch("call", {
url: 'dialog/group/disband',
data: {
dialog_id: this.dialogId,
}
}).then(({msg}) => {
resolve(msg);
this.$store.dispatch("forgetDialog", this.dialogId);
this.goForward({name: 'manage-messenger'});
}).catch(({msg}) => {
reject(msg);
});
})
},
});
},
openUser(userid) { openUser(userid) {
if (this.openIng) { if (this.openIng) {
return return

View File

@ -65,18 +65,33 @@
</div> </div>
</div> </div>
<template v-if="dialogData.type === 'group'"> <EDropdown
<ETooltip trigger="click"
placement="top" class="dialog-menu"
:disabled="windowSmall" @command="onDialogMenu">
:openDelay="600" <i class="taskfont dialog-menu-icon">&#xe6e9;</i>
:content="$L('群设置')"> <EDropdownMenu slot="dropdown">
<i class="taskfont dialog-create" @click="groupInfoShow = true">&#xe6e9;</i> <EDropdownItem v-if="dialogData.type === 'user'" command="openCreate">
</ETooltip> <div>{{$L('创建群组')}}</div>
</EDropdownItem>
<template v-else>
<EDropdownItem command="groupInfo">
<div>{{$L('群组设置')}}</div>
</EDropdownItem>
<EDropdownItem v-if="dialogData.owner_id != userId" command="exit">
<div style="color:#f00">{{$L('退出群组')}}</div>
</EDropdownItem>
<template v-else-if="dialogData.group_type === 'user'">
<EDropdownItem command="transfer">
<div>{{$L('转让群主')}}</div>
</EDropdownItem>
<EDropdownItem command="disband">
<div style="color:#f00">{{$L('解散群组')}}</div>
</EDropdownItem>
</template> </template>
<ETooltip v-else-if="dialogData.type === 'user' && !isMyDialog" placement="top" :disabled="windowSmall" :content="$L('创建群组')"> </template>
<i class="taskfont dialog-create" @click="openCreateGroup">&#xe646;</i> </EDropdownMenu>
</ETooltip> </EDropdown>
</div> </div>
</slot> </slot>
</div> </div>
@ -351,6 +366,22 @@
<DialogGroupInfo v-if="groupInfoShow" :dialogId="dialogId" @on-close="groupInfoShow=false"/> <DialogGroupInfo v-if="groupInfoShow" :dialogId="dialogId" @on-close="groupInfoShow=false"/>
</DrawerOverlay> </DrawerOverlay>
<!--群转让-->
<Modal
v-model="groupTransferShow"
:title="$L('转让群主身份')"
:mask-closable="false">
<Form :model="groupTransferData" label-width="auto" @submit.native.prevent>
<FormItem prop="userid" :label="$L('新的群主')">
<UserInput v-model="groupTransferData.userid" :disabledChoice="groupTransferData.disabledChoice" :multiple-max="1" max-hidden-select :placeholder="$L('选择新的群主')"/>
</FormItem>
</Form>
<div slot="footer" class="adaption">
<Button type="default" @click="groupTransferShow=false">{{$L('取消')}}</Button>
<Button type="primary" :loading="groupTransferLoad > 0" @click="onDialogMenu('transferConfirm')">{{$L('确定转让')}}</Button>
</div>
</Modal>
<!--回复列表--> <!--回复列表-->
<DrawerOverlay <DrawerOverlay
v-model="replyListShow" v-model="replyListShow"
@ -474,6 +505,13 @@ export default {
dialogDrag: false, dialogDrag: false,
groupInfoShow: false, groupInfoShow: false,
groupTransferShow: false,
groupTransferLoad: 0,
groupTransferData: {
userid: [],
disabledChoice: []
},
navStyle: {}, navStyle: {},
operateVisible: false, operateVisible: false,
@ -1470,12 +1508,111 @@ export default {
}).catch(() => {}) }).catch(() => {})
}, },
openCreateGroup() { onDialogMenu(cmd) {
this.createGroupData = { switch (cmd) {
userids: this.dialogData.dialog_user ? [this.userId, this.dialogData.dialog_user.userid] : [this.userId], case "openCreate":
uncancelable: [this.userId] const userids = [this.userId]
}; if (this.dialogData.dialog_user && this.userId != this.dialogData.dialog_user.userid) {
this.createGroupShow = true; userids.push(this.dialogData.dialog_user.userid)
}
this.createGroupData = {userids, uncancelable: [this.userId]}
this.createGroupShow = true
break;
case "groupInfo":
this.groupInfoShow = true
break;
case "transfer":
this.groupTransferData = {
dialog_id: this.dialogId,
userid: [],
disabledChoice: [this.userId]
}
this.groupTransferShow = true
break;
case "transferConfirm":
this.onTransferGroup()
break;
case "disband":
this.onDisbandGroup()
break;
case "exit":
this.onExitGroup()
break;
}
},
onTransferGroup() {
if (this.groupTransferData.userid.length === 0) {
$A.messageError("请选择新的群主");
return
}
this.groupTransferLoad++;
this.$store.dispatch("call", {
url: 'dialog/group/transfer',
data: {
dialog_id: this.dialogId,
userid: this.groupTransferData.userid[0]
}
}).then(({data, msg}) => {
$A.messageSuccess(msg);
this.$store.dispatch("saveDialog", data);
}).catch(({msg}) => {
$A.modalError(msg);
}).finally(_ => {
this.groupTransferLoad--;
});
},
onDisbandGroup() {
$A.modalConfirm({
content: `你确定要解散【${this.dialogData.name}】群组吗?`,
loading: true,
okText: '解散',
onOk: () => {
return new Promise((resolve, reject) => {
this.$store.dispatch("call", {
url: 'dialog/group/disband',
data: {
dialog_id: this.dialogId,
}
}).then(({msg}) => {
resolve(msg);
this.$store.dispatch("forgetDialog", this.dialogId);
this.goForward({name: 'manage-messenger'});
}).catch(({msg}) => {
reject(msg);
});
})
},
});
},
onExitGroup() {
$A.modalConfirm({
content: "你确定要退出群组吗?",
loading: true,
onOk: () => {
return new Promise((resolve, reject) => {
this.$store.dispatch("call", {
url: 'dialog/group/deluser',
data: {
dialog_id: this.dialogId,
}
}).then(({msg}) => {
resolve(msg);
this.$store.dispatch("forgetDialog", this.dialogId);
this.goForward({name: 'manage-messenger'});
}).catch(({msg}) => {
reject(msg);
});
})
},
});
}, },
onCreateGroup() { onCreateGroup() {

View File

@ -296,15 +296,24 @@
} }
.dialog-back, .dialog-back,
.dialog-create { .dialog-menu {
cursor: pointer;
margin-left: 24px;
font-size: 22px; font-size: 22px;
color: $primary-text-color; color: $primary-text-color;
} }
.dialog-menu {
margin-right: -22px;
.dialog-menu-icon {
cursor: pointer;
margin: 0 22px;
font-size: 22px;
color: $primary-text-color;
}
}
.dialog-back { .dialog-back {
display: none; display: none;
cursor: pointer;
} }
} }
} }
@ -1500,17 +1509,22 @@
} }
.dialog-back, .dialog-back,
.dialog-create { .dialog-menu {
position: absolute; position: absolute;
top: 0; top: 0;
bottom: 0; bottom: 0;
right: 0; right: 0;
margin: 0;
width: 52px; width: 52px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.dialog-menu {
margin: 0;
.dialog-menu-icon {
margin: 0;
}
}
.dialog-back { .dialog-back {
padding-right: 6px; padding-right: 6px;
right: auto; right: auto;