feat: 添加待办完成状态的支持

This commit is contained in:
kuaifan 2025-08-01 12:26:58 +08:00
parent e792ab7b4d
commit 5fb1bd4175
5 changed files with 55 additions and 28 deletions

View File

@ -545,6 +545,7 @@ class DialogController extends AbstractController
//
if ($list->isNotEmpty()) {
$list->transform(function (WebSocketDialogMsg $item) {
$item->todo_done = $item->isTodoDone();
$item->next_id = 0;
$item->prev_id = 0;
return $item;
@ -2387,6 +2388,7 @@ class DialogController extends AbstractController
$msg->webSocketDialog?->pushMsg('update', [
'id' => $msg->id,
'todo' => $msg->todo,
'todo_done' => $msg->isTodoDone(true),
'dialog_id' => $msg->dialog_id,
]);
}

View File

@ -2,6 +2,7 @@
namespace App\Models;
use Cache;
use Carbon\Carbon;
use App\Module\Base;
use App\Module\Doo;
@ -315,6 +316,24 @@ class WebSocketDialogMsg extends AbstractModel
return Base::retSuccess('success', $resData);
}
/**
* 是否完成所有待办
* @param bool $noCache 是否禁止缓存
* @return int 1=已完成 0=未完成
*/
public function isTodoDone(?bool $noCache = false): int
{
if ($noCache) {
Cache::forget('todo_done_' . $this->id);
}
if ($this->todo <= 0) {
return 1;
}
return (int) Cache::remember('todo_done_' . $this->id, Carbon::now()->addDays(), function () {
return WebSocketDialogMsgTodo::whereMsgId($this->id)->whereDoneAt(null)->exists() ? 0 : 1;
});
}
/**
* 标注、取消标注
* @param int $sender 标注的会员ID
@ -367,23 +386,15 @@ class WebSocketDialogMsg extends AbstractModel
if (in_array($this->type, ['tag', 'todo', 'notice'])) {
return Base::retError('此消息不支持设待办');
}
$dialog = WebSocketDialog::find($this->dialog_id);
$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();
$upData = [
'id' => $this->id,
'todo' => $this->todo,
'dialog_id' => $this->dialog_id,
];
$dialog = WebSocketDialog::find($this->dialog_id);
//
$retData = [
'add' => [],
'update' => $upData
];
$addData = [];
if ($cancel) {
$res = self::sendMsg(null, $this->dialog_id, 'todo', [
'action' => 'remove',
@ -395,7 +406,7 @@ class WebSocketDialogMsg extends AbstractModel
]
], $sender);
if (Base::isSuccess($res)) {
$retData['add'][] = $res['data'];
$addData[] = $res['data'];
WebSocketDialogMsgTodo::whereMsgId($this->id)->whereIn('userid', $cancel)->delete();
}
}
@ -410,7 +421,7 @@ class WebSocketDialogMsg extends AbstractModel
]
], $sender);
if (Base::isSuccess($res)) {
$retData['add'][] = $res['data'];
$addData[] = $res['data'];
$useridList = $dialog->dialogUser->pluck('userid')->toArray();
foreach ($setup as $userid) {
if (!in_array($userid, $useridList)) {
@ -425,8 +436,18 @@ class WebSocketDialogMsg extends AbstractModel
}
}
//
$upData = [
'id' => $this->id,
'todo' => $this->todo,
'todo_done' => $this->isTodoDone(true),
'dialog_id' => $this->dialog_id,
];
$dialog->pushMsg('update', $upData);
return Base::retSuccess($this->todo ? '设置成功' : '取消成功', $retData);
//
return Base::retSuccess($this->todo ? '设置成功' : '取消成功', [
'add' => $addData,
'update' => $upData,
]);
}
/**
@ -1337,7 +1358,6 @@ class WebSocketDialogMsg extends AbstractModel
});
}
/**
* 将被@的人加入群
* @param WebSocketDialog $dialog 对话

View File

@ -14,15 +14,17 @@
"{{$A.getMsgSimpleDesc(source.msg.data)}}"
</div>
<div v-else-if="source.type === 'todo'" class="dialog-todo" @click="onViewTodo">
<div class="todo-user"><UserAvatar :userid="source.userid" :show-name="true" :show-icon="false"/></div>
{{$L(source.msg.action === 'remove' ? '取消待办' : (source.msg.action === 'done' ? '完成' : '设待办'))}}
"{{$A.getMsgSimpleDesc(source.msg.data)}}"
<div v-if="formatTodoUser(source.msg.data).length > 0" class="todo-users">
<span>{{$L('给')}}</span>
<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-else-if="index == 3" class="todo-user">+{{formatTodoUser(source.msg.data).length - 3}}</div>
</template>
<div class="no-dark-content">
<div class="todo-user"><UserAvatar :userid="source.userid" :show-name="true" :show-icon="false"/></div>
{{$L(source.msg.action === 'remove' ? '取消待办' : (source.msg.action === 'done' ? '完成' : '设待办'))}}
"{{$A.getMsgSimpleDesc(source.msg.data)}}"
<div v-if="formatTodoUser(source.msg.data).length > 0" class="todo-users">
<span>{{$L('给')}}</span>
<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-else-if="index == 3" class="todo-user">+{{formatTodoUser(source.msg.data).length - 3}}</div>
</template>
</div>
</div>
</div>
<div v-else-if="source.type === 'notice'" class="dialog-notice">

View File

@ -80,7 +80,7 @@
<i class="taskfont">&#xe61e;</i>
</div>
<!--待办-->
<div v-if="msgData.todo" class="todo" @click="openTodo">
<div v-if="msgData.todo" class="todo" :class="{'todo_done': msgData.todo_done}" @click="openTodo">
<EPopover
v-model="todoShow"
ref="todo"

View File

@ -1668,6 +1668,9 @@
.todo {
position: relative;
cursor: pointer;
&.todo_done {
color: $primary-color;
}
.common-loading {
margin: 0 3px 0 0;
}