feat: merge todo done notices and render done_userids

This commit is contained in:
kuaifan 2025-12-18 23:03:11 +00:00
parent df9d291f98
commit ad9dd6330f
3 changed files with 81 additions and 13 deletions

View File

@ -2429,6 +2429,7 @@ class DialogController extends AbstractController
$id = intval(Request::input("id")); $id = intval(Request::input("id"));
// //
$add = []; $add = [];
$update = [];
$todo = WebSocketDialogMsgTodo::whereId($id)->whereUserid($user->userid)->first(); $todo = WebSocketDialogMsgTodo::whereId($id)->whereUserid($user->userid)->first();
if ($todo && empty($todo->done_at)) { if ($todo && empty($todo->done_at)) {
$todo->done_at = Carbon::now(); $todo->done_at = Carbon::now();
@ -2436,17 +2437,46 @@ class DialogController extends AbstractController
// //
$msg = WebSocketDialogMsg::find($todo->msg_id); $msg = WebSocketDialogMsg::find($todo->msg_id);
if ($msg) { if ($msg) {
$doneUserIds = WebSocketDialogMsgTodo::whereMsgId($msg->id)
->whereNotNull('done_at')
->orderBy('done_at')
->orderBy('id')
->pluck('userid')
->toArray();
//
$lastMsg = WebSocketDialogMsg::whereDialogId($todo->dialog_id)->orderByDesc('id')->first();
if ($lastMsg && $lastMsg->type === 'todo') {
$lastMsgData = $lastMsg->msg;
$lastData = $lastMsgData['data'] ?? [];
if (($lastMsgData['action'] ?? '') === 'done' && intval($lastData['id'] ?? 0) === $msg->id) {
$lastData['done_userids'] = $doneUserIds;
$lastMsgData['data'] = $lastData;
$lastMsg->updateInstance(['msg' => $lastMsgData]);
$lastMsg->save();
$update = [
'id' => $lastMsg->id,
'dialog_id' => $lastMsg->dialog_id,
'type' => $lastMsg->type,
'msg' => $lastMsgData,
];
$lastMsg->webSocketDialog?->pushMsg('update', $update);
}
}
//
if (empty($update)) {
$res = WebSocketDialogMsg::sendMsg(null, $todo->dialog_id, 'todo', [ $res = WebSocketDialogMsg::sendMsg(null, $todo->dialog_id, 'todo', [
'action' => 'done', 'action' => 'done',
'data' => [ 'data' => [
'id' => $msg->id, 'id' => $msg->id,
'type' => $msg->type, 'type' => $msg->type,
'msg' => $msg->quoteTextMsg(), 'msg' => $msg->quoteTextMsg(),
'done_userids' => $doneUserIds,
] ]
]); ]);
if (Base::isSuccess($res)) { if (Base::isSuccess($res)) {
$add = $res['data']; $add = $res['data'];
} }
}
// //
$msg->webSocketDialog?->pushMsg('update', [ $msg->webSocketDialog?->pushMsg('update', [
'id' => $msg->id, 'id' => $msg->id,
@ -2458,7 +2488,8 @@ class DialogController extends AbstractController
} }
// //
return Base::retSuccess("待办已完成", [ return Base::retSuccess("待办已完成", [
'add' => $add ?: null 'add' => $add ?: null,
'update' => $update ?: null,
]); ]);
} }

View File

@ -15,10 +15,19 @@
</div> </div>
<div v-else-if="source.type === 'todo'" class="dialog-todo" @click="onViewTodo"> <div v-else-if="source.type === 'todo'" class="dialog-todo" @click="onViewTodo">
<div class="no-dark-content"> <div class="no-dark-content">
<div class="todo-user"><UserAvatar :userid="source.userid" :show-name="true" :show-icon="false"/></div> <div v-if="source.msg.action === 'done' && todoDoneDisplayList(source.msg.data).length > 0" class="todo-users">
<div
v-for="(item, index) in todoDoneDisplayList(source.msg.data)"
:key="`todo-done-${item.type}-${item.value}-${index}`"
class="todo-user">
<UserAvatar v-if="item.type === 'user'" :userid="item.value" :show-name="true" :show-icon="false"/>
<span v-else>{{item.value}}</span>
</div>
</div>
<div v-else class="todo-user"><UserAvatar :userid="source.userid" :show-name="true" :show-icon="false"/></div>
{{$L(source.msg.action === 'remove' ? '取消待办' : (source.msg.action === 'done' ? '完成' : '设待办'))}} {{$L(source.msg.action === 'remove' ? '取消待办' : (source.msg.action === 'done' ? '完成' : '设待办'))}}
"{{$A.getMsgSimpleDesc(source.msg.data)}}" "{{$A.getMsgSimpleDesc(source.msg.data)}}"
<div v-if="formatTodoUser(source.msg.data).length > 0" class="todo-users"> <div v-if="source.msg.action === 'add' && formatTodoUser(source.msg.data).length > 0" class="todo-users">
<span>{{$L('给')}}</span> <span>{{$L('给')}}</span>
<template v-for="(item, index) in formatTodoUser(source.msg.data)"> <template v-for="(item, index) in formatTodoUser(source.msg.data)">
<div v-if="index < 3" class="todo-user"><UserAvatar :userid="item" :show-name="true" :show-icon="false"/></div> <div v-if="index < 3" class="todo-user"><UserAvatar :userid="item" :show-name="true" :show-icon="false"/></div>
@ -200,6 +209,31 @@ export default {
return [] return []
}, },
formatTodoDoneUser(data) {
if ($A.isJson(data) && $A.isArray(data.done_userids)) {
return data.done_userids
}
return []
},
todoDoneDisplayList(data) {
const userIds = this.formatTodoDoneUser(data)
if (userIds.length === 0) {
return []
}
const list = userIds.slice(0, 3).map(userid => ({
type: 'user',
value: userid,
}))
if (userIds.length > 3) {
list.push({
type: 'extra',
value: `+${userIds.length - 3}`,
})
}
return list
},
onViewTag() { onViewTag() {
this.onViewReply({ this.onViewReply({
msg_id: this.source.id, msg_id: this.source.id,

View File

@ -2268,6 +2268,9 @@ export default {
if (data.add) { if (data.add) {
this.sendSuccess(data.add) this.sendSuccess(data.add)
} }
if (data.update) {
this.sendSuccess(data.update, 0, true)
}
if (this.todoList.length === 0) { if (this.todoList.length === 0) {
this.$store.dispatch("getDialogTodo", this.dialogId) this.$store.dispatch("getDialogTodo", this.dialogId)
} }