fix(notice): 发送事务包裹与软删过滤加固

This commit is contained in:
augushong
2026-10-12 14:39:17 +00:00
parent 710ce97473
commit 77e75fcc0b
3 changed files with 76 additions and 21 deletions

View File

@@ -61,12 +61,15 @@ class NoticeBase extends AdminController
->withJoin('notice', 'LEFT')
->where('system_notice_target.admin_id', $adminId)
->where('system_notice_target.channel', NoticeService::CHANNEL_INMAIL)
// 软删通知不进个人域(管理页删除后此处消失)
->where('system_notice.delete_time', 0)
->where($where)
->count();
$list = $this->model
->withJoin('notice', 'LEFT')
->where('system_notice_target.admin_id', $adminId)
->where('system_notice_target.channel', NoticeService::CHANNEL_INMAIL)
->where('system_notice.delete_time', 0)
->where($where)
->page($page, $limit)
->order($this->sort)
@@ -95,6 +98,8 @@ class NoticeBase extends AdminController
->withJoin('notice', 'LEFT')
->where('system_notice_target.id', (int) $id)
->where('system_notice_target.admin_id', $adminId)
// 软删通知不进个人域(管理页删除后详情不可打开)
->where('system_notice.delete_time', 0)
->find();
if (empty($row)) {
$this->error('消息不存在或无权查看');

View File

@@ -109,33 +109,39 @@ class NoticeServiceBase
}
if ($adminIds === 'all') {
$adminIds = Db::name('system_admin')->where('status', 1)->column('id');
// delete_time=0 过滤软删管理员,与 sceneOverview 的 SystemAdmin 模型口径对齐
$adminIds = Db::name('system_admin')->where('status', 1)->where('delete_time', 0)->column('id');
} else {
$adminIds = array_values(array_unique(array_map('intval', (array) $adminIds)));
}
$now = time();
$notice = SystemNotice::create([
'scene' => $scene,
'title' => $title,
'content' => $content,
'biz_id' => (string) ($options['biz_id'] ?? ''),
'send_admin_id' => (int) ($options['send_admin_id'] ?? 0),
]);
$noticeId = (int) $notice->id;
// 主体创建与投递展开同事务:insertAll 中途异常时回滚,不残留零投递主体
[$notice, $targets] = Db::transaction(function () use ($adminIds, $channels, $content, $now, $options, $registered, $scene, $title) {
$notice = SystemNotice::create([
'scene' => $scene,
'title' => $title,
'content' => $content,
'biz_id' => (string) ($options['biz_id'] ?? ''),
'send_admin_id' => (int) ($options['send_admin_id'] ?? 0),
]);
$noticeId = (int) $notice->id;
$targets = [];
if ($adminIds !== []) {
$targets = static::buildTargets($noticeId, $adminIds, $scene, $channels, $registered, $now);
if ($targets !== []) {
Db::name('system_notice_target')->insertAll($targets);
$targets = [];
if ($adminIds !== []) {
$targets = static::buildTargets($noticeId, $adminIds, $scene, $channels, $registered, $now);
if ($targets !== []) {
Db::name('system_notice_target')->insertAll($targets);
}
}
}
return [$notice, $targets];
});
Event::trigger('NoticeSended', [$notice, $targets]);
return $noticeId;
return (int) $notice->id;
}
/**
@@ -240,14 +246,18 @@ class NoticeServiceBase
/**
* 未读站内信数(channel=inmail AND read_time=0 AND status=2,走复合索引).
* JOIN 过滤软删通知:与个人域 mine/read 口径一致,管理页删除后未读数同步下降.
*/
public static function unreadCount(int $adminId): int
{
return Db::name('system_notice_target')
->where('admin_id', $adminId)
->where('channel', self::CHANNEL_INMAIL)
->where('read_time', 0)
->where('status', SystemNoticeTargetBase::STATUS_SUCCESS)
->alias('target')
->join('system_notice notice', 'notice.id = target.notice_id')
->where('target.admin_id', $adminId)
->where('target.channel', self::CHANNEL_INMAIL)
->where('target.read_time', 0)
->where('target.status', SystemNoticeTargetBase::STATUS_SUCCESS)
->where('notice.delete_time', 0)
->count();
}