refactor(notify):重构通知授权模块,移除外部接口

- 移除用户通知授权检查、消费和记录查询的外部接口
- 废弃相关请求和响应 DTO 类文件
- 将授权检查和统计功能迁移至内部服务调用
- 新增批量检查授权方法 batchCheckAuthorization- 新增获取用户授权统计信息方法 getAuthorizationStats
- 更新 UserNotificationAuthorizationService 接口定义- 优化 ServiceImpl 中的数据处理逻辑和引入 Collectors 工具类
This commit is contained in:
2025-10-14 23:18:49 +08:00
parent 44b20890d5
commit ff708a3fc3
8 changed files with 111 additions and 355 deletions

View File

@@ -1,30 +1,21 @@
package com.ycwl.basic.controller.mobile.notify;
import com.ycwl.basic.config.JwtInfo;
import com.ycwl.basic.model.mobile.notify.req.NotificationAuthCheckReq;
import com.ycwl.basic.model.mobile.notify.req.NotificationAuthConsumeReq;
import com.ycwl.basic.model.mobile.notify.req.NotificationAuthRecordReq;
import com.ycwl.basic.model.mobile.notify.req.NotificationAuthRecordsReq;
import com.ycwl.basic.model.mobile.notify.resp.NotificationAuthCheckResp;
import com.ycwl.basic.model.mobile.notify.resp.NotificationAuthConsumeResp;
import com.ycwl.basic.model.mobile.notify.resp.NotificationAuthRecordResp;
import com.ycwl.basic.model.pc.notify.entity.UserNotificationAuthorizationEntity;
import com.ycwl.basic.service.UserNotificationAuthorizationService;
import com.ycwl.basic.utils.ResponseData;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.validation.Valid;
/**
* 用户通知授权记录Controller (移动端API)
* 只提供用户主动授权记录功能,其他检查和消费功能由系统内部调用
*
* @Author: System
* @Date: 2024/12/28
@@ -37,48 +28,9 @@ public class UserNotificationAuthController {
@Autowired
private UserNotificationAuthorizationService userNotificationAuthorizationService;
/**
* 检查用户通知授权状态
*/
@PostMapping("/check")
public ResponseData<NotificationAuthCheckResp> checkAuthorization(
@JwtInfo Long memberId,
@Valid @RequestBody NotificationAuthCheckReq req) {
log.info("检查用户通知授权状态: memberId={}, templateId={}, scenicId={}",
memberId, req.getTemplateId(), req.getScenicId());
try {
UserNotificationAuthorizationEntity record = userNotificationAuthorizationService
.checkAuthorization(memberId, req.getTemplateId(), req.getScenicId());
NotificationAuthCheckResp resp = new NotificationAuthCheckResp();
if (record != null) {
resp.setHasAuthorization(true);
resp.setRemainingCount(record.getRemainingCount());
resp.setAuthorizationCount(record.getAuthorizationCount());
resp.setConsumedCount(record.getConsumedCount());
resp.setLastAuthorizedTime(record.getLastAuthorizedTime());
resp.setLastConsumedTime(record.getLastConsumedTime());
resp.setTemplateId(record.getTemplateId());
resp.setScenicId(record.getScenicId());
} else {
resp.setHasAuthorization(false);
resp.setRemainingCount(0);
resp.setAuthorizationCount(0);
resp.setConsumedCount(0);
resp.setTemplateId(req.getTemplateId());
resp.setScenicId(req.getScenicId());
}
return ResponseData.success(resp);
} catch (Exception e) {
log.error("检查用户通知授权状态失败", e);
return ResponseData.fail("检查授权状态失败: " + e.getMessage());
}
}
/**
* 记录用户通知授权
* 用户主动同意通知授权时调用
*/
@PostMapping("/record")
public ResponseData<NotificationAuthRecordResp> recordAuthorization(
@@ -100,138 +52,4 @@ public class UserNotificationAuthController {
return ResponseData.fail("记录授权失败: " + e.getMessage());
}
}
/**
* 消费通知授权
*/
@PostMapping("/consume")
public ResponseData<NotificationAuthConsumeResp> consumeAuthorization(
@JwtInfo Long memberId,
@Valid @RequestBody NotificationAuthConsumeReq req) {
log.info("消费通知授权: memberId={}, templateId={}, scenicId={}",
memberId, req.getTemplateId(), req.getScenicId());
try {
boolean consumeSuccess = userNotificationAuthorizationService
.consumeAuthorization(memberId, req.getTemplateId(), req.getScenicId());
NotificationAuthConsumeResp resp = new NotificationAuthConsumeResp();
resp.setConsumeSuccess(consumeSuccess);
if (consumeSuccess) {
Integer remainingCount = userNotificationAuthorizationService
.getRemainingCount(memberId, req.getTemplateId(), req.getScenicId());
resp.setRemainingCount(remainingCount);
} else {
resp.setFailReason("授权次数不足或授权记录不存在");
resp.setRemainingCount(0);
}
return ResponseData.success(resp);
} catch (Exception e) {
log.error("消费通知授权失败", e);
return ResponseData.fail("消费授权失败: " + e.getMessage());
}
}
/**
* 查询用户通知授权记录
*/
@GetMapping("/records")
public ResponseData<List<NotificationAuthRecordResp>> getUserAuthorizationRecords(
@JwtInfo Long memberId,
@Valid NotificationAuthRecordsReq req) {
log.info("查询用户通知授权记录: memberId={}, templateId={}", memberId, req.getTemplateId());
try {
List<UserNotificationAuthorizationEntity> records;
if (req.getTemplateId() != null && !req.getTemplateId().trim().isEmpty()) {
records = userNotificationAuthorizationService
.getUserAuthorizationsByTemplate(memberId, req.getTemplateId());
} else {
records = userNotificationAuthorizationService.getUserAuthorizations(memberId);
}
List<NotificationAuthRecordResp> respList = new ArrayList<>();
if (!CollectionUtils.isEmpty(records)) {
for (UserNotificationAuthorizationEntity record : records) {
NotificationAuthRecordResp resp = new NotificationAuthRecordResp();
BeanUtils.copyProperties(record, resp);
// TODO: 可以在这里添加景区名称查询
respList.add(resp);
}
}
return ResponseData.success(respList);
} catch (Exception e) {
log.error("查询用户通知授权记录失败", e);
return ResponseData.fail("查询授权记录失败: " + e.getMessage());
}
}
/**
* 获取用户授权统计信息
*/
@GetMapping("/stats")
public ResponseData<AuthorizationStats> getAuthorizationStats(@JwtInfo Long memberId) {
log.info("获取用户授权统计信息: memberId={}", memberId);
try {
List<UserNotificationAuthorizationEntity> records = userNotificationAuthorizationService
.getUserAuthorizations(memberId);
int totalTemplates = records.size();
int totalAuthorizations = records.stream()
.mapToInt(UserNotificationAuthorizationEntity::getAuthorizationCount)
.sum();
int totalConsumed = records.stream()
.mapToInt(UserNotificationAuthorizationEntity::getConsumedCount)
.sum();
int totalRemaining = totalAuthorizations - totalConsumed;
// 创建统计信息对象
AuthorizationStats stats = new AuthorizationStats();
stats.totalTemplates = totalTemplates;
stats.totalAuthorizations = totalAuthorizations;
stats.totalConsumed = totalConsumed;
stats.totalRemaining = totalRemaining;
stats.queryTime = new Date();
return ResponseData.success(stats);
} catch (Exception e) {
log.error("获取用户授权统计信息失败", e);
return ResponseData.fail("获取统计信息失败: " + e.getMessage());
}
}
/**
* 授权统计信息DTO
*/
@Data
public static class AuthorizationStats {
/**
* 总模板数
*/
private int totalTemplates;
/**
* 总授权次数
*/
private int totalAuthorizations;
/**
* 总消费次数
*/
private int totalConsumed;
/**
* 剩余授权次数
*/
private int totalRemaining;
/**
* 查询时间
*/
private Date queryTime;
}
}

View File

@@ -1,28 +1,2 @@
package com.ycwl.basic.model.mobile.notify.req;
import lombok.Data;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
/**
* 通知授权检查请求
*
* @Author: System
* @Date: 2024/12/28
*/
@Data
public class NotificationAuthCheckReq {
/**
* 通知模板ID
*/
@NotBlank(message = "模板ID不能为空")
private String templateId;
/**
* 景区ID
*/
@NotNull(message = "景区ID不能为空")
private Long scenicId;
}
// 该文件已废弃 - 检查授权功能改为内部服务调用
// 请使用 com.ycwl.basic.utils.NotificationAuthUtils 工具类

View File

@@ -1,28 +1,2 @@
package com.ycwl.basic.model.mobile.notify.req;
import lombok.Data;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
/**
* 通知授权消费请求
*
* @Author: System
* @Date: 2024/12/28
*/
@Data
public class NotificationAuthConsumeReq {
/**
* 通知模板ID
*/
@NotBlank(message = "模板ID不能为空")
private String templateId;
/**
* 景区ID
*/
@NotNull(message = "景区ID不能为空")
private Long scenicId;
}
// 该文件已废弃 - 消费授权功能改为内部服务调用
// 请使用 com.ycwl.basic.utils.NotificationAuthUtils 工具类

View File

@@ -1,28 +1,2 @@
package com.ycwl.basic.model.mobile.notify.req;
import lombok.Data;
/**
* 通知授权记录查询请求
*
* @Author: System
* @Date: 2024/12/28
*/
@Data
public class NotificationAuthRecordsReq {
/**
* 模板ID(可选)
*/
private String templateId;
/**
* 页码
*/
private Integer page = 1;
/**
* 每页大小
*/
private Integer size = 10;
}
// 该文件已废弃 - 查询授权记录功能改为内部服务调用
// 请使用 com.ycwl.basic.utils.NotificationAuthUtils 工具类

View File

@@ -1,55 +1,2 @@
package com.ycwl.basic.model.mobile.notify.resp;
import lombok.Data;
import java.util.Date;
/**
* 通知授权检查响应
*
* @Author: System
* @Date: 2024/12/28
*/
@Data
public class NotificationAuthCheckResp {
/**
* 是否有授权
*/
private Boolean hasAuthorization;
/**
* 剩余授权次数
*/
private Integer remainingCount;
/**
* 总授权次数
*/
private Integer authorizationCount;
/**
* 已消费次数
*/
private Integer consumedCount;
/**
* 最后授权时间
*/
private Date lastAuthorizedTime;
/**
* 最后消费时间
*/
private Date lastConsumedTime;
/**
* 模板ID
*/
private String templateId;
/**
* 景区ID
*/
private Long scenicId;
}
// 该文件已废弃 - 检查授权响应功能改为内部服务调用
// 请使用 com.ycwl.basic.utils.NotificationAuthUtils 工具类

View File

@@ -1,28 +1,2 @@
package com.ycwl.basic.model.mobile.notify.resp;
import lombok.Data;
/**
* 通知授权消费响应
*
* @Author: System
* @Date: 2024/12/28
*/
@Data
public class NotificationAuthConsumeResp {
/**
* 是否消费成功
*/
private Boolean consumeSuccess;
/**
* 剩余授权次数
*/
private Integer remainingCount;
/**
* 消费失败原因
*/
private String failReason;
}
// 该文件已废弃 - 消费授权响应功能改为内部服务调用
// 请使用 com.ycwl.basic.utils.NotificationAuthUtils 工具类

View File

@@ -2,7 +2,9 @@ package com.ycwl.basic.service;
import com.ycwl.basic.model.pc.notify.entity.UserNotificationAuthorizationEntity;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 用户通知授权记录Service接口
@@ -84,4 +86,46 @@ public interface UserNotificationAuthorizationService {
* @return 授权记录
*/
UserNotificationAuthorizationEntity getById(Long id);
/**
* 批量检查多个模板的授权状态
*
* @param memberId 用户ID
* @param templateIds 模板ID列表
* @param scenicId 景区ID
* @return 授权记录映射
*/
Map<String, UserNotificationAuthorizationEntity> batchCheckAuthorization(
Long memberId, List<String> templateIds, Long scenicId);
/**
* 获取用户授权统计信息
*
* @param memberId 用户ID
* @return 统计信息
*/
AuthorizationStats getAuthorizationStats(Long memberId);
/**
* 授权统计信息DTO
*/
class AuthorizationStats {
private int totalTemplates; // 总模板数
private int totalAuthorizations; // 总授权次数
private int totalConsumed; // 总消费次数
private int totalRemaining; // 剩余授权次数
private Date queryTime; // 查询时间
// getters and setters
public int getTotalTemplates() { return totalTemplates; }
public void setTotalTemplates(int totalTemplates) { this.totalTemplates = totalTemplates; }
public int getTotalAuthorizations() { return totalAuthorizations; }
public void setTotalAuthorizations(int totalAuthorizations) { this.totalAuthorizations = totalAuthorizations; }
public int getTotalConsumed() { return totalConsumed; }
public void setTotalConsumed(int totalConsumed) { this.totalConsumed = totalConsumed; }
public int getTotalRemaining() { return totalRemaining; }
public void setTotalRemaining(int totalRemaining) { this.totalRemaining = totalRemaining; }
public Date getQueryTime() { return queryTime; }
public void setQueryTime(Date queryTime) { this.queryTime = queryTime; }
}
}

View File

@@ -1,6 +1,5 @@
package com.ycwl.basic.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ycwl.basic.mapper.UserNotificationAuthorizationMapper;
import com.ycwl.basic.model.pc.notify.entity.UserNotificationAuthorizationEntity;
import com.ycwl.basic.service.UserNotificationAuthorizationService;
@@ -9,8 +8,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
* 用户通知授权记录Service实现类
@@ -135,4 +134,56 @@ public class UserNotificationAuthorizationServiceImpl implements UserNotificatio
log.debug("根据ID查询授权记录: id={}", id);
return userNotificationAuthorizationMapper.selectById(id);
}
@Override
public Map<String, UserNotificationAuthorizationEntity> batchCheckAuthorization(
Long memberId, List<String> templateIds, Long scenicId) {
log.debug("批量检查用户授权: memberId={}, templateIds={}, scenicId={}", memberId, templateIds, scenicId);
Map<String, UserNotificationAuthorizationEntity> result = new HashMap<>();
if (templateIds == null || templateIds.isEmpty()) {
return result;
}
// 查询用户在该景区的所有授权记录
List<UserNotificationAuthorizationEntity> userRecords = getUserAuthorizations(memberId);
// 过滤出指定景区和模板的记录
Map<String, UserNotificationAuthorizationEntity> recordMap = userRecords.stream()
.filter(record -> scenicId.equals(record.getScenicId()))
.filter(record -> templateIds.contains(record.getTemplateId()))
.collect(Collectors.toMap(
UserNotificationAuthorizationEntity::getTemplateId,
record -> record,
(existing, replacement) -> existing
));
// 为每个模板ID填充结果
for (String templateId : templateIds) {
result.put(templateId, recordMap.get(templateId));
}
return result;
}
@Override
public AuthorizationStats getAuthorizationStats(Long memberId) {
log.debug("获取用户授权统计信息: memberId={}", memberId);
List<UserNotificationAuthorizationEntity> records = getUserAuthorizations(memberId);
AuthorizationStats stats = new AuthorizationStats();
stats.setTotalTemplates(records.size());
stats.setTotalAuthorizations(records.stream()
.mapToInt(UserNotificationAuthorizationEntity::getAuthorizationCount)
.sum());
stats.setTotalConsumed(records.stream()
.mapToInt(UserNotificationAuthorizationEntity::getConsumedCount)
.sum());
stats.setTotalRemaining(stats.getTotalAuthorizations() - stats.getTotalConsumed());
stats.setQueryTime(new Date());
return stats;
}
}