mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-12 19:35:50 +00:00
perf: 支持修改消息待办
This commit is contained in:
parent
80fe978454
commit
2bda6bf668
@ -1765,7 +1765,9 @@ class DialogController extends AbstractController
|
||||
* @apiParam {String} type 设待办对象
|
||||
* - all: 会话全部成员(默认)
|
||||
* - user: 会话指定成员
|
||||
* @apiParam {Array} userids 会员ID组(type=user有效,格式: [userid1, userid2, userid3])
|
||||
* @apiParam {Array} userids 会员ID组
|
||||
* - type=user 有效,格式: [userid1, userid2, userid3]
|
||||
* - 可通过 type=user 及 userids:[] 一起使用来清除所有人的待办
|
||||
*
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
@ -1773,26 +1775,24 @@ class DialogController extends AbstractController
|
||||
*/
|
||||
public function msg__todo()
|
||||
{
|
||||
Base::checkClientVersion('0.37.18');
|
||||
$user = User::auth();
|
||||
//
|
||||
$msg_id = intval(Request::input("msg_id"));
|
||||
$type = trim(Request::input("type", "all"));
|
||||
$userids = Request::input('userids');
|
||||
//
|
||||
if ($type === 'user') {
|
||||
if (empty($userids)) {
|
||||
return Base::retError("选择指定成员");
|
||||
}
|
||||
} else {
|
||||
$userids = [];
|
||||
}
|
||||
//
|
||||
$msg = WebSocketDialogMsg::whereId($msg_id)->first();
|
||||
if (empty($msg)) {
|
||||
return Base::retError("消息不存在或已被删除");
|
||||
}
|
||||
WebSocketDialog::checkDialog($msg->dialog_id);
|
||||
$dialog = WebSocketDialog::checkDialog($msg->dialog_id);
|
||||
//
|
||||
if ($type === 'all') {
|
||||
$userids = $dialog->dialogUser->pluck('userid')->toArray();
|
||||
} else {
|
||||
$userids = is_array($userids) ? $userids : [];
|
||||
}
|
||||
return $msg->toggleTodoMsg($user->userid, $userids);
|
||||
}
|
||||
|
||||
|
||||
@ -320,41 +320,54 @@ class WebSocketDialogMsg extends AbstractModel
|
||||
if (in_array($this->type, ['tag', 'todo', 'notice'])) {
|
||||
return Base::retError('此消息不支持设待办');
|
||||
}
|
||||
if ($this->todo && $this->todo != $sender) {
|
||||
return Base::retError('仅支持设此待办人员【' . User::userid2nickname($this->todo) . '】取消');
|
||||
}
|
||||
$before = $this->todo;
|
||||
$this->todo = $before ? 0 : $sender;
|
||||
$current = WebSocketDialogMsgTodo::whereMsgId($this->id)->pluck('userid')->toArray();
|
||||
$cancel = array_diff($current, $userids);
|
||||
$setup = array_diff($userids, $current);
|
||||
//
|
||||
$this->todo = $setup || count($current) > count($cancel) ? $sender : 0;
|
||||
$this->save();
|
||||
$resData = [
|
||||
$upData = [
|
||||
'id' => $this->id,
|
||||
'todo' => $this->todo,
|
||||
'dialog_id' => $this->dialog_id,
|
||||
];
|
||||
$dialog = WebSocketDialog::find($this->dialog_id);
|
||||
$dialog->pushMsg('update', $upData);
|
||||
//
|
||||
$data = [
|
||||
'update' => $resData
|
||||
$retData = [
|
||||
'add' => [],
|
||||
'update' => $upData
|
||||
];
|
||||
$res = self::sendMsg(null, $this->dialog_id, 'todo', [
|
||||
'action' => $this->todo ? 'add' : 'remove',
|
||||
'data' => [
|
||||
'id' => $this->id,
|
||||
'type' => $this->type,
|
||||
'msg' => $this->quoteTextMsg(),
|
||||
'userids' => implode(",", $userids),
|
||||
]
|
||||
], $sender);
|
||||
if (Base::isSuccess($res)) {
|
||||
$data['add'] = $res['data'];
|
||||
$dialog = WebSocketDialog::find($this->dialog_id);
|
||||
$dialog->pushMsg('update', array_merge($resData, ['dialog_id' => $this->dialog_id]));
|
||||
//
|
||||
if ($this->todo) {
|
||||
if ($cancel) {
|
||||
$res = self::sendMsg(null, $this->dialog_id, 'todo', [
|
||||
'action' => 'remove',
|
||||
'data' => [
|
||||
'id' => $this->id,
|
||||
'type' => $this->type,
|
||||
'msg' => $this->quoteTextMsg(),
|
||||
'userids' => implode(",", $cancel),
|
||||
]
|
||||
], $sender);
|
||||
if (Base::isSuccess($res)) {
|
||||
$retData['add'][] = $res['data'];
|
||||
WebSocketDialogMsgTodo::whereMsgId($this->id)->whereIn('userid', $cancel)->delete();
|
||||
}
|
||||
}
|
||||
if ($setup) {
|
||||
$res = self::sendMsg(null, $this->dialog_id, 'todo', [
|
||||
'action' => 'add',
|
||||
'data' => [
|
||||
'id' => $this->id,
|
||||
'type' => $this->type,
|
||||
'msg' => $this->quoteTextMsg(),
|
||||
'userids' => implode(",", $setup),
|
||||
]
|
||||
], $sender);
|
||||
if (Base::isSuccess($res)) {
|
||||
$retData['add'][] = $res['data'];
|
||||
$useridList = $dialog->dialogUser->pluck('userid')->toArray();
|
||||
foreach ($useridList as $userid) {
|
||||
if ($userids && !in_array($userid, $userids)) {
|
||||
continue;
|
||||
}
|
||||
if (empty($userid)) {
|
||||
foreach ($setup as $userid) {
|
||||
if (!in_array($userid, $useridList)) {
|
||||
continue;
|
||||
}
|
||||
WebSocketDialogMsgTodo::createInstance([
|
||||
@ -363,15 +376,10 @@ class WebSocketDialogMsg extends AbstractModel
|
||||
'userid' => $userid,
|
||||
])->saveOrIgnore();
|
||||
}
|
||||
} else {
|
||||
WebSocketDialogMsgTodo::whereMsgId($this->id)->delete();
|
||||
}
|
||||
} else {
|
||||
$this->todo = $before;
|
||||
$this->save();
|
||||
}
|
||||
//
|
||||
return Base::retSuccess($this->todo ? '设置成功' : '取消成功', $data);
|
||||
return Base::retSuccess($this->todo ? '设置成功' : '取消成功', $retData);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -53,6 +53,7 @@
|
||||
@on-reply-list="onReplyList"
|
||||
@on-error="onError"
|
||||
@on-emoji="onEmoji"
|
||||
@on-other="onOther"
|
||||
@on-show-emoji-user="onShowEmojiUser"/>
|
||||
</template>
|
||||
</div>
|
||||
@ -258,6 +259,10 @@ export default {
|
||||
this.dispatch("on-emoji", data)
|
||||
},
|
||||
|
||||
onOther(data) {
|
||||
this.dispatch("on-other", data)
|
||||
},
|
||||
|
||||
onShowEmojiUser(data) {
|
||||
this.dispatch("on-show-emoji-user", data)
|
||||
},
|
||||
|
||||
@ -196,7 +196,10 @@
|
||||
:placement="isRightMsg ? 'bottom-end' : 'bottom-start'">
|
||||
<div class="read-poptip-content">
|
||||
<Scrollbar class-name="read">
|
||||
<div class="read-title"><em>{{ todoDoneList.length }}</em>{{ $L('完成') }}</div>
|
||||
<div class="read-title">
|
||||
<em>{{ todoDoneList.length }}</em>
|
||||
{{ $L('完成') }}
|
||||
</div>
|
||||
<ul>
|
||||
<li v-for="item in todoDoneList">
|
||||
<UserAvatar :userid="item.userid" :size="26" showName/>
|
||||
@ -204,7 +207,12 @@
|
||||
</ul>
|
||||
</Scrollbar>
|
||||
<Scrollbar class-name="unread">
|
||||
<div class="read-title"><em>{{ todoUndoneList.length }}</em>{{ $L('待办') }}</div>
|
||||
<div class="read-title">
|
||||
<em>{{ todoUndoneList.length }}</em>
|
||||
{{ $L('待办') }}
|
||||
<span class="space"></span>
|
||||
<Button type="primary" size="small" @click="handleTodoAdd">{{ $L('添加') }}</Button>
|
||||
</div>
|
||||
<ul>
|
||||
<li v-for="item in todoUndoneList">
|
||||
<UserAvatar :userid="item.userid" :size="26" showName/>
|
||||
@ -240,7 +248,10 @@
|
||||
:placement="isRightMsg ? 'bottom-end' : 'bottom-start'">
|
||||
<div class="read-poptip-content">
|
||||
<Scrollbar class-name="read">
|
||||
<div class="read-title"><em>{{ readList.length }}</em>{{ $L('已读') }}</div>
|
||||
<div class="read-title">
|
||||
<em>{{ readList.length }}</em>
|
||||
{{ $L('已读') }}
|
||||
</div>
|
||||
<ul>
|
||||
<li v-for="item in readList">
|
||||
<UserAvatar :userid="item.userid" :size="26" showName/>
|
||||
@ -248,7 +259,10 @@
|
||||
</ul>
|
||||
</Scrollbar>
|
||||
<Scrollbar class-name="unread">
|
||||
<div class="read-title"><em>{{ unreadList.length }}</em>{{ $L('未读') }}</div>
|
||||
<div class="read-title">
|
||||
<em>{{ unreadList.length }}</em>
|
||||
{{ $L('未读') }}
|
||||
</div>
|
||||
<ul>
|
||||
<li v-for="item in unreadList">
|
||||
<UserAvatar :userid="item.userid" :size="26" showName/>
|
||||
@ -488,6 +502,17 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
handleTodoAdd() {
|
||||
this.$refs.todo.doClose();
|
||||
this.$emit("on-other", {
|
||||
event: 'todoAdd',
|
||||
data: {
|
||||
msg_id: this.msgData.id,
|
||||
userids: this.todoList.map(({userid}) => userid)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
openReadPercentage() {
|
||||
if (this.percentageLoad > 0) {
|
||||
return;
|
||||
|
||||
@ -200,6 +200,7 @@
|
||||
@on-reply-list="onReplyList"
|
||||
@on-error="onError"
|
||||
@on-emoji="onEmoji"
|
||||
@on-other="onOther"
|
||||
@on-show-emoji-user="onShowEmojiUser">
|
||||
<template #header v-if="!isChildComponent">
|
||||
<div class="dialog-item head-box">
|
||||
@ -486,6 +487,7 @@
|
||||
@on-view-file="onViewFile"
|
||||
@on-down-file="onDownFile"
|
||||
@on-emoji="onEmoji"
|
||||
@on-other="onOther"
|
||||
simpleView/>
|
||||
</Scrollbar>
|
||||
</div>
|
||||
@ -554,6 +556,15 @@
|
||||
<Button type="primary" :loading="todoSettingLoad > 0" @click="onTodo('submit')">{{$L('确定')}}</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
<UserSelect
|
||||
v-if="todoSpecifyShow"
|
||||
ref="todoSpecifySelect"
|
||||
v-model="todoSpecifyData.userids"
|
||||
:dialog-id="dialogId"
|
||||
:title="$L('选择指定成员')"
|
||||
module
|
||||
border
|
||||
:before-submit="onTodoSpecify"/>
|
||||
|
||||
<!--群设置-->
|
||||
<DrawerOverlay
|
||||
@ -629,6 +640,7 @@
|
||||
@on-view-file="onViewFile"
|
||||
@on-down-file="onDownFile"
|
||||
@on-emoji="onEmoji"
|
||||
@on-other="onOther"
|
||||
simpleView/>
|
||||
<Button class="original-button" icon="md-exit" type="text" :loading="todoViewPosLoad" @click="onPosTodo">{{ $L("回到原文") }}</Button>
|
||||
</template>
|
||||
@ -806,6 +818,11 @@ export default {
|
||||
userids: [],
|
||||
quick_value: [],
|
||||
},
|
||||
todoSpecifyShow: false,
|
||||
todoSpecifyData: {
|
||||
type: 'user',
|
||||
userids: [],
|
||||
},
|
||||
|
||||
todoViewLoad: false,
|
||||
todoViewPosLoad: false,
|
||||
@ -3395,6 +3412,19 @@ export default {
|
||||
this.respondShow = true
|
||||
},
|
||||
|
||||
onOther({event, data}) {
|
||||
if (this.operateVisible) {
|
||||
return
|
||||
}
|
||||
if (event === 'todoAdd') {
|
||||
this.todoSpecifyData = Object.assign(this.todoSpecifyData, data)
|
||||
this.todoSpecifyShow = true
|
||||
this.$nextTick(_ => {
|
||||
this.$refs.todoSpecifySelect.onSelection()
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
onTag() {
|
||||
if (this.operateVisible) {
|
||||
return
|
||||
@ -3460,45 +3490,61 @@ export default {
|
||||
this.todoSettingLoad--
|
||||
})
|
||||
} else {
|
||||
const quickList = {}
|
||||
quickList[this.userId] = this.userId
|
||||
const userid = this.dialogData.dialog_user?.userid
|
||||
if (userid && userid != this.userId && !this.dialogData.bot) {
|
||||
quickList[userid] = userid
|
||||
}
|
||||
if (this.operateItem.type === 'text') {
|
||||
const atReg = /<span class="mention user" data-id="(\d+)">([^<]+)<\/span>/g
|
||||
const atList = this.operateItem.msg.text.match(atReg)
|
||||
if (atList) {
|
||||
atList.forEach(item => {
|
||||
const userid = parseInt(item.replace(atReg, '$1'))
|
||||
if (userid && userid != this.userId) {
|
||||
quickList[userid] = userid
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
this.todoSettingData = {
|
||||
type: 'all',
|
||||
userids: [],
|
||||
msg_id: this.operateItem.id,
|
||||
quick_value: [],
|
||||
quick_list: Object.values(quickList),
|
||||
}
|
||||
if (this.operateItem.todo) {
|
||||
$A.modalConfirm({
|
||||
content: "你确定取消待办吗?",
|
||||
cancelText: '取消',
|
||||
okText: '确定',
|
||||
loading: true,
|
||||
onOk: () => this.onTodoSubmit(this.todoSettingData)
|
||||
onOk: () => this.onTodoSubmit({
|
||||
type: 'user',
|
||||
userids: [],
|
||||
msg_id: this.operateItem.id,
|
||||
})
|
||||
});
|
||||
} else {
|
||||
const quickList = {}
|
||||
quickList[this.userId] = this.userId
|
||||
const userid = this.dialogData.dialog_user?.userid
|
||||
if (userid && userid != this.userId && !this.dialogData.bot) {
|
||||
quickList[userid] = userid
|
||||
}
|
||||
if (this.operateItem.type === 'text') {
|
||||
const atReg = /<span class="mention user" data-id="(\d+)">([^<]+)<\/span>/g
|
||||
const atList = this.operateItem.msg.text.match(atReg)
|
||||
if (atList) {
|
||||
atList.forEach(item => {
|
||||
const userid = parseInt(item.replace(atReg, '$1'))
|
||||
if (userid && userid != this.userId) {
|
||||
quickList[userid] = userid
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
this.todoSettingData = {
|
||||
type: 'all',
|
||||
userids: [],
|
||||
msg_id: this.operateItem.id,
|
||||
quick_value: [],
|
||||
quick_list: Object.values(quickList),
|
||||
}
|
||||
this.todoSettingShow = true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onTodoSpecify() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.onTodoSubmit(this.todoSpecifyData).then(msg => {
|
||||
$A.messageSuccess(msg)
|
||||
resolve()
|
||||
}).catch(e => {
|
||||
$A.messageError(e)
|
||||
reject()
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
onTodoSubmit(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.$store.dispatch("setLoad", {
|
||||
@ -3506,6 +3552,7 @@ export default {
|
||||
delay: 600
|
||||
})
|
||||
this.$store.dispatch("call", {
|
||||
method: 'post',
|
||||
url: 'dialog/msg/todo',
|
||||
data,
|
||||
}).then(({data, msg}) => {
|
||||
|
||||
@ -2068,12 +2068,22 @@ body:not(.window-touch) {
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
> em {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
padding-right: 6px;
|
||||
}
|
||||
> span.space {
|
||||
flex: 1;
|
||||
height: 1px;
|
||||
}
|
||||
> button {
|
||||
transform: scale(0.96);
|
||||
transform-origin: right center;
|
||||
}
|
||||
}
|
||||
|
||||
ul > li {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user