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