feat(notify): 支持批量授权记录及景区模板查询

- 新增批量授权记录接口,支持一次请求处理多个模板ID
- 新增查询景区通知模板及用户授权余额接口
- 修改授权记录请求体,将单个templateId改为templateIds列表
- 增加授权记录响应结构,区分成功与失败记录
- 新增通知授权工具类,封装常用授权检查与消费方法
- 使用JwtTokenUtil获取当前用户ID替代BaseContextHandler
- 移除过时的BaseContextHandler导入及相关代码依赖
This commit is contained in:
2025-10-15 09:41:18 +08:00
parent 86d5f8ceb1
commit c80086ba69
7 changed files with 520 additions and 59 deletions

View File

@@ -1,21 +1,24 @@
package com.ycwl.basic.controller.mobile.notify;
import com.ycwl.basic.constant.BaseContextHandler;
import com.ycwl.basic.model.mobile.notify.req.NotificationAuthRecordReq;
import com.ycwl.basic.model.mobile.notify.resp.NotificationAuthRecordResp;
import com.ycwl.basic.model.pc.notify.entity.UserNotificationAuthorizationEntity;
import com.ycwl.basic.model.mobile.notify.resp.ScenicTemplateAuthResp;
import com.ycwl.basic.service.UserNotificationAuthorizationService;
import com.ycwl.basic.utils.ApiResponse;
import com.ycwl.basic.utils.JwtTokenUtil;
import com.ycwl.basic.repository.ScenicRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.apache.commons.lang3.StringUtils;
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.List;
/**
* 用户通知授权记录Controller (移动端API)
* 只提供用户主动授权记录功能,其他检查和消费功能由系统内部调用
* 只提供用户主动授权记录功能,支持批量授权,其他检查和消费功能由系统内部调用
*
* @Author: System
* @Date: 2024/12/28
@@ -27,24 +30,60 @@ public class UserNotificationAuthController {
@Autowired
private UserNotificationAuthorizationService userNotificationAuthorizationService;
@Autowired
private ScenicRepository scenicRepository;
/**
* 记录用户通知授权
* 记录用户通知授权 - 支持批量授权
* 用户主动同意通知授权时调用
*/
@PostMapping("/record")
public ApiResponse<NotificationAuthRecordResp> recordAuthorization(
@Valid @RequestBody NotificationAuthRecordReq req) {
Long memberId = Long.parseLong(BaseContextHandler.getUserId());
log.info("记录用户通知授权: memberId={}, templateId={}, scenicId={}",
memberId, req.getTemplateId(), req.getScenicId());
@RequestBody NotificationAuthRecordReq req) {
log.info("记录用户通知授权: templateIds={}, scenicId={}", req.getTemplateIds(), req.getScenicId());
try {
UserNotificationAuthorizationEntity record = userNotificationAuthorizationService
.recordAuthorization(memberId, req.getTemplateId(), req.getScenicId());
// 获取当前用户ID
Long memberId = JwtTokenUtil.getWorker().getUserId();
// 调用批量授权记录方法
List<UserNotificationAuthorizationService.AuthorizationRecord> records =
userNotificationAuthorizationService.batchRecordAuthorization(
memberId, req.getTemplateIds(), req.getScenicId());
NotificationAuthRecordResp resp = new NotificationAuthRecordResp();
BeanUtils.copyProperties(record, resp);
// 转换响应数据
List<NotificationAuthRecordResp.AuthorizationRecord> successRecords = new ArrayList<>();
List<String> failedTemplateIds = new ArrayList<>();
List<String> failureReasons = new ArrayList<>();
for (UserNotificationAuthorizationService.AuthorizationRecord record : records) {
if (record.isSuccess()) {
NotificationAuthRecordResp.AuthorizationRecord successRecord =
new NotificationAuthRecordResp.AuthorizationRecord();
successRecord.setId(record.getId());
successRecord.setTemplateId(record.getTemplateId());
successRecord.setScenicId(record.getScenicId());
successRecord.setAuthorizationCount(record.getAuthorizationCount());
successRecord.setConsumedCount(record.getConsumedCount());
successRecord.setRemainingCount(record.getRemainingCount());
successRecord.setLastAuthorizedTime(record.getLastAuthorizedTime());
successRecord.setLastConsumedTime(record.getLastConsumedTime());
successRecord.setStatus(record.getStatus());
successRecord.setCreateTime(record.getCreateTime());
successRecords.add(successRecord);
} else {
failedTemplateIds.add(record.getTemplateId());
failureReasons.add(record.getFailureReason());
}
}
resp.setAllSuccess(CollectionUtils.isEmpty(failedTemplateIds));
resp.setSuccessRecords(successRecords);
resp.setFailedTemplateIds(failedTemplateIds);
resp.setFailureReasons(failureReasons);
return ApiResponse.success(resp);
} catch (Exception e) {
@@ -52,4 +91,86 @@ public class UserNotificationAuthController {
return ApiResponse.fail("记录授权失败: " + e.getMessage());
}
}
/**
* 获取景区通知模板ID及用户授权余额
* 复制AppWxNotifyController中的逻辑,并额外返回用户对应的授权余额
*/
@GetMapping("/{scenicId}/templates")
public ApiResponse<ScenicTemplateAuthResp> getScenicTemplatesWithAuth(@PathVariable("scenicId") Long scenicId) {
log.info("获取景区通知模板ID及用户授权余额: scenicId={}", scenicId);
try {
// 获取当前用户ID
Long memberId = JwtTokenUtil.getWorker().getUserId();
// 获取景区的所有模板ID(复制自AppWxNotifyController的逻辑)
List<String> templateIds = new ArrayList<>() {{
String videoGeneratedTemplateId = scenicRepository.getVideoGeneratedTemplateId(scenicId);
if (StringUtils.isNotBlank(videoGeneratedTemplateId)) {
add(videoGeneratedTemplateId);
}
String videoDownloadTemplateId = scenicRepository.getVideoDownloadTemplateId(scenicId);
if (StringUtils.isNotBlank(videoDownloadTemplateId)) {
add(videoDownloadTemplateId);
}
String videoPreExpireTemplateId = scenicRepository.getVideoPreExpireTemplateId(scenicId);
if (StringUtils.isNotBlank(videoPreExpireTemplateId)) {
add(videoPreExpireTemplateId);
}
}};
// 构建响应对象
ScenicTemplateAuthResp resp = new ScenicTemplateAuthResp();
resp.setScenicId(scenicId);
// 查询每个模板的授权余额信息
List<ScenicTemplateAuthResp.TemplateAuthInfo> templateAuthInfos = new ArrayList<>();
for (String templateId : templateIds) {
ScenicTemplateAuthResp.TemplateAuthInfo templateAuthInfo =
new ScenicTemplateAuthResp.TemplateAuthInfo();
templateAuthInfo.setTemplateId(templateId);
// 获取授权详情
try {
com.ycwl.basic.model.pc.notify.entity.UserNotificationAuthorizationEntity authEntity =
userNotificationAuthorizationService.checkAuthorization(memberId, templateId, scenicId);
if (authEntity != null) {
templateAuthInfo.setAuthorizationCount(authEntity.getAuthorizationCount());
templateAuthInfo.setConsumedCount(authEntity.getConsumedCount());
templateAuthInfo.setRemainingCount(authEntity.getRemainingCount());
templateAuthInfo.setHasAuthorization(authEntity.getRemainingCount() != null && authEntity.getRemainingCount() > 0);
} else {
// 没有授权记录
templateAuthInfo.setAuthorizationCount(0);
templateAuthInfo.setConsumedCount(0);
templateAuthInfo.setRemainingCount(0);
templateAuthInfo.setHasAuthorization(false);
}
} catch (Exception e) {
log.warn("获取模板授权信息失败: templateId={}, scenicId={}, memberId={}, error={}",
templateId, scenicId, memberId, e.getMessage());
// 获取失败时设置为无授权
templateAuthInfo.setAuthorizationCount(0);
templateAuthInfo.setConsumedCount(0);
templateAuthInfo.setRemainingCount(0);
templateAuthInfo.setHasAuthorization(false);
}
templateAuthInfos.add(templateAuthInfo);
}
resp.setTemplates(templateAuthInfos);
log.info("成功获取景区通知模板ID及用户授权余额: scenicId={}, templateCount={}, memberId={}",
scenicId, templateIds.size(), memberId);
return ApiResponse.success(resp);
} catch (Exception e) {
log.error("获取景区通知模板ID及用户授权余额失败: scenicId={}", scenicId, e);
return ApiResponse.fail("获取授权信息失败: " + e.getMessage());
}
}
}