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

View File

@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use Cache;
use Carbon\Carbon; use Carbon\Carbon;
use App\Module\Base; use App\Module\Base;
use App\Module\Doo; use App\Module\Doo;
@ -315,6 +316,24 @@ class WebSocketDialogMsg extends AbstractModel
return Base::retSuccess('success', $resData); 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 * @param int $sender 标注的会员ID
@ -367,23 +386,15 @@ 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('此消息不支持设待办');
} }
$dialog = WebSocketDialog::find($this->dialog_id);
$current = WebSocketDialogMsgTodo::whereMsgId($this->id)->pluck('userid')->toArray(); $current = WebSocketDialogMsgTodo::whereMsgId($this->id)->pluck('userid')->toArray();
$cancel = array_diff($current, $userids); $cancel = array_diff($current, $userids);
$setup = array_diff($userids, $current); $setup = array_diff($userids, $current);
// //
$this->todo = $setup || count($current) > count($cancel) ? $sender : 0; $this->todo = $setup || count($current) > count($cancel) ? $sender : 0;
$this->save(); $this->save();
$upData = [
'id' => $this->id,
'todo' => $this->todo,
'dialog_id' => $this->dialog_id,
];
$dialog = WebSocketDialog::find($this->dialog_id);
// //
$retData = [ $addData = [];
'add' => [],
'update' => $upData
];
if ($cancel) { if ($cancel) {
$res = self::sendMsg(null, $this->dialog_id, 'todo', [ $res = self::sendMsg(null, $this->dialog_id, 'todo', [
'action' => 'remove', 'action' => 'remove',
@ -395,7 +406,7 @@ class WebSocketDialogMsg extends AbstractModel
] ]
], $sender); ], $sender);
if (Base::isSuccess($res)) { if (Base::isSuccess($res)) {
$retData['add'][] = $res['data']; $addData[] = $res['data'];
WebSocketDialogMsgTodo::whereMsgId($this->id)->whereIn('userid', $cancel)->delete(); WebSocketDialogMsgTodo::whereMsgId($this->id)->whereIn('userid', $cancel)->delete();
} }
} }
@ -410,7 +421,7 @@ class WebSocketDialogMsg extends AbstractModel
] ]
], $sender); ], $sender);
if (Base::isSuccess($res)) { if (Base::isSuccess($res)) {
$retData['add'][] = $res['data']; $addData[] = $res['data'];
$useridList = $dialog->dialogUser->pluck('userid')->toArray(); $useridList = $dialog->dialogUser->pluck('userid')->toArray();
foreach ($setup as $userid) { foreach ($setup as $userid) {
if (!in_array($userid, $useridList)) { 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); $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 对话 * @param WebSocketDialog $dialog 对话

View File

@ -14,6 +14,7 @@
"{{$A.getMsgSimpleDesc(source.msg.data)}}" "{{$A.getMsgSimpleDesc(source.msg.data)}}"
</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="todo-user"><UserAvatar :userid="source.userid" :show-name="true" :show-icon="false"/></div> <div 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)}}"
@ -25,6 +26,7 @@
</template> </template>
</div> </div>
</div> </div>
</div>
<div v-else-if="source.type === 'notice'" class="dialog-notice"> <div v-else-if="source.type === 'notice'" class="dialog-notice">
{{source.msg.source === 'api' ? source.msg.notice : $L(source.msg.notice)}} {{source.msg.source === 'api' ? source.msg.notice : $L(source.msg.notice)}}
</div> </div>

View File

@ -80,7 +80,7 @@
<i class="taskfont">&#xe61e;</i> <i class="taskfont">&#xe61e;</i>
</div> </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 <EPopover
v-model="todoShow" v-model="todoShow"
ref="todo" ref="todo"

View File

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