Files
xin-procurement/app/Http/Controllers/Mini/NoticeController.php
T
2026-07-23 20:41:25 +08:00

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();
}
}