90 lines
3.4 KiB
PHP
90 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Mini;
|
|
|
|
use App\Exceptions\RepositoryException;
|
|
use App\Models\NoticeModel;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Modules\AnnoRoute\Attribute\GetRoute;
|
|
use Modules\AnnoRoute\Attribute\PutRoute;
|
|
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
|
|
|
/**
|
|
* 小程序通知(本人通知 + 全员广播)
|
|
*
|
|
* 广播已读处理:user_id=0 的广播是全局共享记录,直接改 is_read 会影响其他用户,
|
|
* 因此标记已读时复制一条本人专属的已读记录(data.broadcast_from 记来源),
|
|
* 列表查询时排除已有已读副本的广播。
|
|
*/
|
|
#[RequestAttribute('/mini', 'mini', authGuard: 'users')]
|
|
class NoticeController extends BaseMiniController
|
|
{
|
|
/** 本人通知 + 全员广播(user_id in [0, 当前id]),分页 + unread_count */
|
|
#[GetRoute('/notice', authorize: true)]
|
|
public function index(Request $request): JsonResponse
|
|
{
|
|
$user = $this->currentUser($request);
|
|
|
|
// 本人已读过的广播来源ID(已读副本记录)
|
|
$readBroadcastIds = NoticeModel::query()
|
|
->where('user_id', $user->id)
|
|
->whereNotNull('data->broadcast_from')
|
|
->pluck('data->broadcast_from');
|
|
|
|
$query = NoticeModel::query()->where(function ($q) use ($user, $readBroadcastIds) {
|
|
$q->where('user_id', $user->id)
|
|
->orWhere(function ($broadcastQuery) use ($readBroadcastIds) {
|
|
$broadcastQuery->where('user_id', NoticeModel::BROADCAST_USER_ID);
|
|
if ($readBroadcastIds->isNotEmpty()) {
|
|
$broadcastQuery->whereNotIn('id', $readBroadcastIds->all());
|
|
}
|
|
});
|
|
});
|
|
|
|
$unreadCount = (clone $query)->where('is_read', NoticeModel::UNREAD)->count();
|
|
|
|
$data = $query->orderBy('id', 'desc')
|
|
->paginate((int) $request->input('pageSize', 10))
|
|
->toArray();
|
|
$data['unread_count'] = $unreadCount;
|
|
|
|
return $this->success($data);
|
|
}
|
|
|
|
/** 标记已读(广播 → 复制本人已读副本;个人通知 → 直接更新) */
|
|
#[PutRoute('/notice/{id}/read', authorize: true, where: ['id' => '[0-9]+'])]
|
|
public function read(int $id, Request $request): JsonResponse
|
|
{
|
|
$user = $this->currentUser($request);
|
|
|
|
$notice = NoticeModel::whereIn('user_id', [NoticeModel::BROADCAST_USER_ID, $user->id])->find($id);
|
|
if ($notice === null) {
|
|
throw new RepositoryException('通知不存在');
|
|
}
|
|
|
|
if ($notice->user_id === NoticeModel::BROADCAST_USER_ID) {
|
|
$exists = NoticeModel::where('user_id', $user->id)
|
|
->where('data->broadcast_from', $notice->id)
|
|
->exists();
|
|
if (! $exists) {
|
|
NoticeModel::create([
|
|
'user_id' => $user->id,
|
|
'type' => $notice->type,
|
|
'title' => $notice->title,
|
|
'content' => $notice->content,
|
|
'data' => ['broadcast_from' => $notice->id] + (array) $notice->data,
|
|
'is_read' => NoticeModel::READ,
|
|
'read_at' => now(),
|
|
]);
|
|
}
|
|
} elseif ($notice->is_read === NoticeModel::UNREAD) {
|
|
$notice->is_read = NoticeModel::READ;
|
|
$notice->read_at = now();
|
|
$notice->save();
|
|
}
|
|
|
|
return $this->success();
|
|
}
|
|
}
|