From 2b5be16ad70d8723ee12fd0f1caeec83ac8894e8 Mon Sep 17 00:00:00 2001 From: Timi Date: Sat, 29 Aug 2026 00:49:50 +0800 Subject: [PATCH] fix notify delete --- .../common/controller/NotifyController.java | 4 +-- .../modules/common/entity/NotifyDetail.java | 5 +++ .../common/mapper/NotifyDetailMapper.java | 22 +++++++------ .../common/service/NotifyDetailService.java | 4 +-- .../NotifyDetailServiceImplement.java | 6 ++-- .../gao/controller/GaoNotifyController.java | 32 +++++++++++++++---- .../api/modules/gao/mapper/GaoUserMapper.java | 6 ++++ .../modules/gao/service/GaoUserService.java | 8 +++++ .../implement/GaoUserServiceImplement.java | 10 ++++++ .../V44__add_notify_detail_hidden_at.sql | 4 +++ .../mapper/timi-server/gao/GaoUserMapper.xml | 22 +++++++++++++ 11 files changed, 99 insertions(+), 24 deletions(-) create mode 100644 src/main/resources/db/migration/timiserver/V44__add_notify_detail_hidden_at.sql diff --git a/src/main/java/com/imyeyu/api/modules/common/controller/NotifyController.java b/src/main/java/com/imyeyu/api/modules/common/controller/NotifyController.java index 8e11c24..605e2f8 100644 --- a/src/main/java/com/imyeyu/api/modules/common/controller/NotifyController.java +++ b/src/main/java/com/imyeyu/api/modules/common/controller/NotifyController.java @@ -176,14 +176,14 @@ public class NotifyController { return detail; } - /// 删除当前用户的一条站内通知 + /// 隐藏当前用户的一条站内通知 /// /// @param id 通知详情 ID @RequireCorePermission(CorePermissionCode.NOTIFY_READ) @RequiredToken @PostMapping("/internal/delete") public void deleteInternal(@RequestParam String id) { - detailService.deleteInternalByUserId(id, userLoginService.getRequireLoginUserId()); + detailService.hideInternalByUserId(id, userLoginService.getRequireLoginUserId()); } /// 查询当前用户未读通知数量 diff --git a/src/main/java/com/imyeyu/api/modules/common/entity/NotifyDetail.java b/src/main/java/com/imyeyu/api/modules/common/entity/NotifyDetail.java index ac1fdce..700a5e5 100644 --- a/src/main/java/com/imyeyu/api/modules/common/entity/NotifyDetail.java +++ b/src/main/java/com/imyeyu/api/modules/common/entity/NotifyDetail.java @@ -1,5 +1,6 @@ package com.imyeyu.api.modules.common.entity; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonView; import com.fasterxml.jackson.databind.JsonNode; import com.imyeyu.api.TimiServerAPI; @@ -157,6 +158,10 @@ public class NotifyDetail extends UUIDEntity { @JsonView(ResponseView.Public.class) private Long readAt; + /// 收件人隐藏时间,仅站内通知生效 + @JsonIgnore + private Long hiddenAt; + @Transient protected Notify notify; diff --git a/src/main/java/com/imyeyu/api/modules/common/mapper/NotifyDetailMapper.java b/src/main/java/com/imyeyu/api/modules/common/mapper/NotifyDetailMapper.java index c7d4103..85515a3 100644 --- a/src/main/java/com/imyeyu/api/modules/common/mapper/NotifyDetailMapper.java +++ b/src/main/java/com/imyeyu/api/modules/common/mapper/NotifyDetailMapper.java @@ -16,35 +16,37 @@ import java.util.List; */ public interface NotifyDetailMapper extends BaseMapper { + String NOT_HIDDEN = " AND `hidden_at` IS NULL"; + /** 查询用户的站内通知 */ - @Select("SELECT * FROM `notify_detail` WHERE `msg_type` = 'INTERNAL' AND `send_to` = #{userId} AND `send_at` < " + UNIX_TIME + NOT_DELETE + " ORDER BY `created_at` DESC LIMIT #{offset}, #{limit}") + @Select("SELECT * FROM `notify_detail` WHERE `msg_type` = 'INTERNAL' AND `send_to` = #{userId} AND `send_at` < " + UNIX_TIME + NOT_HIDDEN + NOT_DELETE + " ORDER BY `created_at` DESC LIMIT #{offset}, #{limit}") List selectSiteByUserId(@Param("userId") String userId, @Param("offset") long offset, @Param("limit") long limit); /** 查询用户的未读站内通知 */ - @Select("SELECT * FROM `notify_detail` WHERE `msg_type` = 'INTERNAL' AND `send_to` = #{userId} AND `send_at` < " + UNIX_TIME + " AND `read_at` IS NULL " + NOT_DELETE + " ORDER BY `created_at` DESC LIMIT #{offset}, #{limit}") + @Select("SELECT * FROM `notify_detail` WHERE `msg_type` = 'INTERNAL' AND `send_to` = #{userId} AND `send_at` < " + UNIX_TIME + " AND `read_at` IS NULL " + NOT_HIDDEN + NOT_DELETE + " ORDER BY `created_at` DESC LIMIT #{offset}, #{limit}") List selectUnreadSiteByUserId(@Param("userId") String userId, @Param("offset") long offset, @Param("limit") long limit); /** 统计用户的站内通知数量 */ - @Select("SELECT COUNT(*) FROM `notify_detail` WHERE `msg_type` = 'INTERNAL' AND `send_to` = #{userId} AND `send_at` < " + UNIX_TIME + NOT_DELETE) + @Select("SELECT COUNT(*) FROM `notify_detail` WHERE `msg_type` = 'INTERNAL' AND `send_to` = #{userId} AND `send_at` < " + UNIX_TIME + NOT_HIDDEN + NOT_DELETE) long countSiteByUserId(@Param("userId") String userId); /** 统计用户的未读站内通知数量 */ - @Select("SELECT COUNT(*) FROM `notify_detail` WHERE `msg_type` = 'INTERNAL' AND `send_to` = #{userId} AND `send_at` < " + UNIX_TIME + " AND `read_at` IS NULL " + NOT_DELETE) + @Select("SELECT COUNT(*) FROM `notify_detail` WHERE `msg_type` = 'INTERNAL' AND `send_to` = #{userId} AND `send_at` < " + UNIX_TIME + " AND `read_at` IS NULL " + NOT_HIDDEN + NOT_DELETE) long countUnreadSiteByUserId(@Param("userId") String userId); /** 查询用户拥有的站内通知 */ - @Select("SELECT * FROM `notify_detail` WHERE `id` = #{detailId} AND `msg_type` = 'INTERNAL' AND `send_to` = #{userId} AND `send_at` < " + UNIX_TIME + NOT_DELETE + " LIMIT 1") + @Select("SELECT * FROM `notify_detail` WHERE `id` = #{detailId} AND `msg_type` = 'INTERNAL' AND `send_to` = #{userId} AND `send_at` < " + UNIX_TIME + NOT_HIDDEN + NOT_DELETE + " LIMIT 1") NotifyDetail selectSiteByIdAndUserId(@Param("detailId") String detailId, @Param("userId") String userId); - /** 删除用户的站内通知 */ - @Update("UPDATE `notify_detail` SET `deleted_at` = " + UNIX_TIME + ", `updated_at` = " + UNIX_TIME + " WHERE `id` = #{detailId} AND `msg_type` = 'INTERNAL' AND `send_to` = #{userId} AND `send_at` < " + UNIX_TIME + NOT_DELETE) - int deleteSiteByIdAndUserId(@Param("detailId") String detailId, @Param("userId") String userId); + /** 隐藏用户的站内通知 */ + @Update("UPDATE `notify_detail` SET `hidden_at` = " + UNIX_TIME + ", `updated_at` = " + UNIX_TIME + " WHERE `id` = #{detailId} AND `msg_type` = 'INTERNAL' AND `send_to` = #{userId} AND `send_at` < " + UNIX_TIME + NOT_HIDDEN + NOT_DELETE) + int hideSiteByIdAndUserId(@Param("detailId") String detailId, @Param("userId") String userId); /** 标记站内通知已读 */ - @Update("UPDATE `notify_detail` SET `read_at` = #{readAt}, `updated_at` = " + UNIX_TIME + " WHERE `id` = #{detailId} AND `msg_type` = 'INTERNAL' AND `send_to` = #{userId} AND `send_at` < " + UNIX_TIME + " AND `read_at` IS NULL " + NOT_DELETE) + @Update("UPDATE `notify_detail` SET `read_at` = #{readAt}, `updated_at` = " + UNIX_TIME + " WHERE `id` = #{detailId} AND `msg_type` = 'INTERNAL' AND `send_to` = #{userId} AND `send_at` < " + UNIX_TIME + " AND `read_at` IS NULL " + NOT_HIDDEN + NOT_DELETE) int markSiteRead(@Param("detailId") String detailId, @Param("userId") String userId, @Param("readAt") long readAt); /** 标记用户全部站内通知已读 */ - @Update("UPDATE `notify_detail` SET `read_at` = #{readAt}, `updated_at` = " + UNIX_TIME + " WHERE `msg_type` = 'INTERNAL' AND `send_to` = #{userId} AND `send_at` < " + UNIX_TIME + " AND `read_at` IS NULL " + NOT_DELETE) + @Update("UPDATE `notify_detail` SET `read_at` = #{readAt}, `updated_at` = " + UNIX_TIME + " WHERE `msg_type` = 'INTERNAL' AND `send_to` = #{userId} AND `send_at` < " + UNIX_TIME + " AND `read_at` IS NULL " + NOT_HIDDEN + NOT_DELETE) int markAllSiteRead(@Param("userId") String userId, @Param("readAt") long readAt); } diff --git a/src/main/java/com/imyeyu/api/modules/common/service/NotifyDetailService.java b/src/main/java/com/imyeyu/api/modules/common/service/NotifyDetailService.java index 0380a52..a6ee10e 100644 --- a/src/main/java/com/imyeyu/api/modules/common/service/NotifyDetailService.java +++ b/src/main/java/com/imyeyu/api/modules/common/service/NotifyDetailService.java @@ -41,11 +41,11 @@ public interface NotifyDetailService extends BaseService { /// @return 通知详情 NotifyDetail getInternalByUserId(String detailId, String userId); - /// 删除当前用户拥有的站内通知详情 + /// 隐藏当前用户拥有的站内通知详情 /// /// @param detailId 通知详情 ID /// @param userId 用户 ID - void deleteInternalByUserId(String detailId, String userId); + void hideInternalByUserId(String detailId, String userId); /// 查询用户未读站内通知数量 /// diff --git a/src/main/java/com/imyeyu/api/modules/common/service/implement/NotifyDetailServiceImplement.java b/src/main/java/com/imyeyu/api/modules/common/service/implement/NotifyDetailServiceImplement.java index 8fc55c9..8e5c05b 100644 --- a/src/main/java/com/imyeyu/api/modules/common/service/implement/NotifyDetailServiceImplement.java +++ b/src/main/java/com/imyeyu/api/modules/common/service/implement/NotifyDetailServiceImplement.java @@ -202,16 +202,16 @@ public class NotifyDetailServiceImplement extends AbstractEntityService recipientList(@RequestBody Page page) { TimiException.required(page, "未找到分页参数"); GaoUser example = TimiJava.defaultIfNull(page.getEqualsExample(), new GaoUser()); - example.setEnabled(true); if (storeScopeService.hasGlobalScope()) { if (TimiJava.isNotEmpty(example.getStoreId())) { storeScopeService.checkStoreId(example.getStoreId()); @@ -74,14 +78,14 @@ public class GaoNotifyController { } page.setEqualsExample(example); - PageResult result = gaoUserService.page(page); + PageResult result = gaoUserService.pageRecipients(page); fillUser(result.getList()); return result; } /// 创建 GAO 站内通知 /// - /// 只允许发送站内通知,并逐个校验接收用户是否属于当前操作人的门店范围。 + /// 只允许发送站内通知,并逐个校验接收用户是否属于当前操作人的门店范围;当前用户可以接收自己发送的通知。 /// /// @param notify 通知及通知详情 /// @return 创建后的通知 @@ -116,8 +120,12 @@ public class GaoNotifyController { }).collect(Collectors.toSet()); TimiException.requiredTrue(recipientIdSet.size() == detailList.size(), "通知接收用户不能重复"); - Map gaoUserMap = gaoUserService.mapByUserIdList(recipientIdSet); - TimiException.requiredTrue(gaoUserMap.size() == recipientIdSet.size(), "包含无效的通知接收用户"); + String loginUserId = userLoginService.getRequireLoginUserId(); + Set gaoRecipientIdSet = recipientIdSet.stream() + .filter(recipientId -> !loginUserId.equals(recipientId)) + .collect(Collectors.toSet()); + Map gaoUserMap = gaoUserService.mapByUserIdList(gaoRecipientIdSet); + TimiException.requiredTrue(gaoUserMap.size() == gaoRecipientIdSet.size(), "包含无效的通知接收用户"); for (GaoUser gaoUser : gaoUserMap.values()) { TimiException.requiredTrue(Boolean.TRUE.equals(gaoUser.getEnabled()), "通知接收用户已停用"); storeScopeService.checkStoreId(gaoUser.getStoreId()); @@ -133,8 +141,18 @@ public class GaoNotifyController { } List userIdList = gaoUserList.stream().map(GaoUser::getUserId).toList(); Map userMap = userService.mapByIdList(userIdList); + Map> attachmentMap = attachmentService.mapByBizIdList( + Attachment.BizType.USER, + userIdList, + User.AttachType.AVATAR.toString() + ); for (GaoUser gaoUser : gaoUserList) { - gaoUser.setUser(userMap.get(gaoUser.getUserId())); + User user = userMap.get(gaoUser.getUserId()); + if (user == null) { + continue; + } + user.setAttachmentList(attachmentMap.getOrDefault(user.getId(), List.of())); + gaoUser.setUser(user); } } } diff --git a/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoUserMapper.java b/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoUserMapper.java index 21e4662..9ad780e 100644 --- a/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoUserMapper.java +++ b/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoUserMapper.java @@ -1,7 +1,9 @@ package com.imyeyu.api.modules.gao.mapper; import com.imyeyu.api.modules.gao.entity.GaoUser; +import com.imyeyu.spring.bean.Page; import com.imyeyu.spring.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; import java.util.Collection; import java.util.List; @@ -14,4 +16,8 @@ import java.util.List; public interface GaoUserMapper extends BaseMapper { List selectByUserIdList(Collection userIdList); + + List selectRecipientPage(@Param("page") Page page); + + long countRecipients(@Param("page") Page page); } diff --git a/src/main/java/com/imyeyu/api/modules/gao/service/GaoUserService.java b/src/main/java/com/imyeyu/api/modules/gao/service/GaoUserService.java index 327c004..538d7a1 100644 --- a/src/main/java/com/imyeyu/api/modules/gao/service/GaoUserService.java +++ b/src/main/java/com/imyeyu/api/modules/gao/service/GaoUserService.java @@ -1,6 +1,8 @@ package com.imyeyu.api.modules.gao.service; import com.imyeyu.api.modules.gao.entity.GaoUser; +import com.imyeyu.spring.bean.Page; +import com.imyeyu.spring.bean.PageResult; import com.imyeyu.spring.service.BaseService; import java.util.Collection; @@ -28,4 +30,10 @@ public interface GaoUserService extends BaseService { /// @param userIdList 核心用户 ID 列表 /// @return GAO 用户映射 Map mapByUserIdList(Collection userIdList); + + /// 查询可作为通知接收人的启用用户 + /// + /// @param page 分页参数 + /// @return 接收用户分页结果 + PageResult pageRecipients(Page page); } diff --git a/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoUserServiceImplement.java b/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoUserServiceImplement.java index 4affc95..187ecec 100644 --- a/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoUserServiceImplement.java +++ b/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoUserServiceImplement.java @@ -13,6 +13,8 @@ import com.imyeyu.java.TimiJava; import com.imyeyu.java.bean.timi.TimiCode; import com.imyeyu.java.bean.timi.TimiException; import com.imyeyu.spring.mapper.BaseMapper; +import com.imyeyu.spring.bean.Page; +import com.imyeyu.spring.bean.PageResult; import com.imyeyu.spring.service.AbstractEntityService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -174,4 +176,12 @@ public class GaoUserServiceImplement extends AbstractEntityService pageRecipients(Page page) { + PageResult result = new PageResult<>(); + result.setTotal(mapper.countRecipients(page)); + result.setList(mapper.selectRecipientPage(page)); + return result; + } } diff --git a/src/main/resources/db/migration/timiserver/V44__add_notify_detail_hidden_at.sql b/src/main/resources/db/migration/timiserver/V44__add_notify_detail_hidden_at.sql new file mode 100644 index 0000000..c7b7361 --- /dev/null +++ b/src/main/resources/db/migration/timiserver/V44__add_notify_detail_hidden_at.sql @@ -0,0 +1,4 @@ +ALTER TABLE `notify_detail` + ADD COLUMN `hidden_at` BIGINT(20) COMMENT '收件人隐藏时间' AFTER `read_at`, + DROP INDEX `idx_internal_user_send_at`, + ADD INDEX `idx_internal_user_send_at`(`msg_type` ASC, `send_to` ASC, `hidden_at` ASC, `send_at` ASC, `deleted_at` ASC) USING BTREE; diff --git a/src/main/resources/mapper/timi-server/gao/GaoUserMapper.xml b/src/main/resources/mapper/timi-server/gao/GaoUserMapper.xml index 8d24732..18e84a3 100644 --- a/src/main/resources/mapper/timi-server/gao/GaoUserMapper.xml +++ b/src/main/resources/mapper/timi-server/gao/GaoUserMapper.xml @@ -12,4 +12,26 @@ AND `deleted_at` IS NULL + + + +