“mitao”
2026-04-30 aeb9818e02480af6055479aa798457b8ddfec7a4
feat:极光推送联调接口
4个文件已添加
3个文件已修改
318 ■■■■■ 已修改文件
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/config/SaTokenWebConfig.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/system/controller/JpushManualPushController.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/system/dto/JpushManualPushRequest.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/system/service/JpushManualPushAppService.java 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/system/vo/JpushManualPushVO.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/utils/JGPushUtil.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tcm-training-admin-backend/src/main/resources/application.yml 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/config/SaTokenWebConfig.java
@@ -70,11 +70,22 @@
    private boolean isPublicAdminApi(String requestPath) {
        return "/api/auth/login".equals(requestPath)
                || "/api/auth/captcha".equals(requestPath)
                || isJpushManualPushApi(requestPath)
                || requestPath.startsWith("/api/open/")
                || requestPath.startsWith("/api/v1/open/");
    }
    /**
     * 判断当前后台路由是否属于极光手动推送联调接口。
     */
    private boolean isJpushManualPushApi(String requestPath) {
        return "/api/jpush/manual-push".equals(requestPath)
                || "/api/v1/jpush/manual-push".equals(requestPath)
                || requestPath.startsWith("/api/jpush/manual-push/")
                || requestPath.startsWith("/api/v1/jpush/manual-push/");
    }
    /**
     * 将本地上传目录映射为静态资源,可通过 /uploads/** 访问。
     */
    @Override
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/system/controller/JpushManualPushController.java
New file
@@ -0,0 +1,76 @@
package com.tcm.training.admin.system.controller;
import com.tcm.training.admin.common.ApiResponse;
import com.tcm.training.admin.system.dto.JpushManualPushRequest;
import com.tcm.training.admin.system.service.JpushManualPushAppService;
import com.tcm.training.admin.system.vo.JpushManualPushVO;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
/**
 * 极光手动推送联调接口。
 */
@Validated
@RestController
@RequestMapping({"/api/v1", "/api"})
public class JpushManualPushController {
    private final JpushManualPushAppService jpushManualPushAppService;
    public JpushManualPushController(JpushManualPushAppService jpushManualPushAppService) {
        this.jpushManualPushAppService = jpushManualPushAppService;
    }
    /**
     * 按APP用户ID推送固定联调消息。
     */
    @PostMapping("/jpush/manual-push")
    public ApiResponse<JpushManualPushVO> push(@Valid @RequestBody JpushManualPushRequest request) {
        return ApiResponse.ok(jpushManualPushAppService.push(request));
    }
    /**
     * 生成会员到期提醒测试通知并推送。
     */
    @PostMapping("/jpush/manual-push/member-expire-remind")
    public ApiResponse<JpushManualPushVO> pushMemberExpireRemind(@Valid @RequestBody JpushManualPushRequest request) {
        return ApiResponse.ok(jpushManualPushAppService.pushMemberExpireRemind(request));
    }
    /**
     * 生成直播提醒测试通知并推送。
     */
    @PostMapping("/jpush/manual-push/live-remind")
    public ApiResponse<JpushManualPushVO> pushLiveRemind(@Valid @RequestBody JpushManualPushRequest request) {
        return ApiResponse.ok(jpushManualPushAppService.pushLiveRemind(request));
    }
    /**
     * 生成活动通知测试通知并推送。
     */
    @PostMapping("/jpush/manual-push/activity-notice")
    public ApiResponse<JpushManualPushVO> pushActivityNotice(@Valid @RequestBody JpushManualPushRequest request) {
        return ApiResponse.ok(jpushManualPushAppService.pushActivityNotice(request));
    }
    /**
     * 生成订单状态更新测试通知并推送。
     */
    @PostMapping("/jpush/manual-push/order-status-update")
    public ApiResponse<JpushManualPushVO> pushOrderStatusUpdate(@Valid @RequestBody JpushManualPushRequest request) {
        return ApiResponse.ok(jpushManualPushAppService.pushOrderStatusUpdate(request));
    }
    /**
     * 生成课程更新测试通知并推送。
     */
    @PostMapping("/jpush/manual-push/course-update-notice")
    public ApiResponse<JpushManualPushVO> pushCourseUpdateNotice(@Valid @RequestBody JpushManualPushRequest request) {
        return ApiResponse.ok(jpushManualPushAppService.pushCourseUpdateNotice(request));
    }
}
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/system/dto/JpushManualPushRequest.java
New file
@@ -0,0 +1,18 @@
package com.tcm.training.admin.system.dto;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotNull;
/**
 * 极光手动推送联调请求。
 */
@Getter
@Setter
public class JpushManualPushRequest {
    /** 推送目标APP用户ID。 */
    @NotNull(message = "请选择推送用户")
    private Long appUserId;
}
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/system/service/JpushManualPushAppService.java
New file
@@ -0,0 +1,163 @@
package com.tcm.training.admin.system.service;
import com.tcm.training.admin.app.notice.entity.AppSystemNotice;
import com.tcm.training.admin.app.notice.service.AppSystemNoticeDispatchCommand;
import com.tcm.training.admin.app.notice.service.AppSystemNoticeDispatchService;
import com.tcm.training.admin.app.notice.service.AppSystemNoticeType;
import com.tcm.training.admin.system.dto.JpushManualPushRequest;
import com.tcm.training.admin.system.vo.JpushManualPushVO;
import com.tcm.training.admin.utils.JGPushUtil;
import org.springframework.stereotype.Service;
import java.util.LinkedHashMap;
import java.util.Map;
/**
 * 极光手动推送联调应用服务。
 */
@Service
public class JpushManualPushAppService {
    private static final String TEST_TITLE = "极光推送联调";
    private static final String TEST_CONTENT = "这是一条极光推送联调测试消息";
    private static final String TEST_SCENE = "JPUSH_MANUAL_TEST";
    private static final String MANUAL_NOTICE_TEST_SCENE = "MANUAL_NOTICE_TEST";
    private static final String PUSH_STATUS_SUCCESS = "SUCCESS";
    private final JGPushUtil jgPushUtil;
    private final AppSystemNoticeDispatchService appSystemNoticeDispatchService;
    public JpushManualPushAppService(JGPushUtil jgPushUtil,
                                     AppSystemNoticeDispatchService appSystemNoticeDispatchService) {
        this.jgPushUtil = jgPushUtil;
        this.appSystemNoticeDispatchService = appSystemNoticeDispatchService;
    }
    /**
     * 按APP用户ID发起固定内容的极光推送联调。
     */
    public JpushManualPushVO push(JpushManualPushRequest request) {
        String alias = String.valueOf(request.getAppUserId());
        Map<String, String> payload = new LinkedHashMap<String, String>();
        payload.put("scene", TEST_SCENE);
        payload.put("appUserId", alias);
        // 极光APP端alias约定为APP用户ID字符串,用于验证设备绑定与推送链路。
        jgPushUtil.push(TEST_CONTENT, TEST_TITLE, payload, alias);
        JpushManualPushVO result = new JpushManualPushVO();
        result.setAppUserId(request.getAppUserId());
        result.setAlias(alias);
        result.setTitle(TEST_TITLE);
        result.setContent(TEST_CONTENT);
        result.setPushed(true);
        return result;
    }
    /**
     * 生成会员到期提醒测试通知并尝试极光推送。
     */
    public JpushManualPushVO pushMemberExpireRemind(JpushManualPushRequest request) {
        return pushNoticeType(request,
                AppSystemNoticeType.MEMBER_EXPIRE_REMIND,
                "会员到期提醒",
                "您的会员有效期将于测试日期到期",
                false);
    }
    /**
     * 生成直播提醒测试通知并尝试极光推送。
     */
    public JpushManualPushVO pushLiveRemind(JpushManualPushRequest request) {
        return pushNoticeType(request,
                AppSystemNoticeType.LIVE_REMIND,
                "直播提醒",
                "测试直播课程 即将开播",
                true);
    }
    /**
     * 生成活动通知测试通知并尝试极光推送。
     */
    public JpushManualPushVO pushActivityNotice(JpushManualPushRequest request) {
        return pushNoticeType(request,
                AppSystemNoticeType.ACTIVITY_NOTICE,
                "活动通知",
                "这是一条活动通知联调测试消息",
                true);
    }
    /**
     * 生成订单状态更新测试通知并尝试极光推送。
     */
    public JpushManualPushVO pushOrderStatusUpdate(JpushManualPushRequest request) {
        return pushNoticeType(request,
                AppSystemNoticeType.ORDER_STATUS_UPDATE,
                "订单状态更新",
                "您的礼品兑换订单状态已更新",
                true);
    }
    /**
     * 生成课程更新测试通知并尝试极光推送。
     */
    public JpushManualPushVO pushCourseUpdateNotice(JpushManualPushRequest request) {
        return pushNoticeType(request,
                AppSystemNoticeType.COURSE_UPDATE_NOTICE,
                "课程更新通知",
                "测试课程 已更新新章节",
                true);
    }
    /**
     * 按指定通知类型生成系统通知,并复用现有通知推送开关和极光推送链路。
     */
    private JpushManualPushVO pushNoticeType(JpushManualPushRequest request,
                                             String noticeTypeCode,
                                             String title,
                                             String content,
                                             boolean requireUserSetting) {
        Long referenceId = System.currentTimeMillis();
        AppSystemNoticeDispatchCommand command = new AppSystemNoticeDispatchCommand();
        command.setAppUserId(request.getAppUserId());
        command.setNoticeTypeCode(noticeTypeCode);
        command.setTitle(title);
        command.setContent(content);
        command.setReferenceType("MANUAL_TEST_" + noticeTypeCode);
        command.setReferenceId(referenceId);
        command.setRequireUserSetting(requireUserSetting);
        command.setPayload(buildManualNoticePayload(request.getAppUserId(), noticeTypeCode, referenceId));
        AppSystemNotice notice = appSystemNoticeDispatchService.createAndPush(command);
        return toNoticePushVO(notice);
    }
    /**
     * 构造手动通知测试透传参数,便于APP端区分联调消息。
     */
    private Map<String, String> buildManualNoticePayload(Long appUserId, String noticeTypeCode, Long referenceId) {
        Map<String, String> payload = new LinkedHashMap<String, String>();
        payload.put("scene", MANUAL_NOTICE_TEST_SCENE);
        payload.put("noticeTypeCode", noticeTypeCode);
        payload.put("appUserId", String.valueOf(appUserId));
        payload.put("referenceId", String.valueOf(referenceId));
        return payload;
    }
    /**
     * 转换系统通知推送结果为联调接口响应。
     */
    private JpushManualPushVO toNoticePushVO(AppSystemNotice notice) {
        JpushManualPushVO result = new JpushManualPushVO();
        result.setNoticeId(notice.getId());
        result.setAppUserId(notice.getAppUserId());
        result.setNoticeTypeCode(notice.getNoticeTypeCode());
        result.setAlias(String.valueOf(notice.getAppUserId()));
        result.setTitle(notice.getTitle());
        result.setContent(notice.getContent());
        result.setPushStatus(notice.getPushStatus());
        result.setPushErrorMessage(notice.getPushErrorMessage());
        result.setPushedAt(notice.getPushedAt());
        result.setPushed(PUSH_STATUS_SUCCESS.equals(notice.getPushStatus()));
        return result;
    }
}
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/system/vo/JpushManualPushVO.java
New file
@@ -0,0 +1,44 @@
package com.tcm.training.admin.system.vo;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
/**
 * 极光手动推送联调结果。
 */
@Getter
@Setter
public class JpushManualPushVO {
    /** 系统通知ID。 */
    private Long noticeId;
    /** 推送目标APP用户ID。 */
    private Long appUserId;
    /** 通知类型编码。 */
    private String noticeTypeCode;
    /** 极光推送别名。 */
    private String alias;
    /** 推送标题。 */
    private String title;
    /** 推送内容。 */
    private String content;
    /** 推送状态。 */
    private String pushStatus;
    /** 推送错误信息。 */
    private String pushErrorMessage;
    /** 推送完成时间。 */
    private LocalDateTime pushedAt;
    /** 是否推送成功。 */
    private Boolean pushed;
}
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/utils/JGPushUtil.java
@@ -50,7 +50,7 @@
                .setPlatform(Platform.all())//设置推送平台为全部平台
                .setAudience(Audience.alias(tags))//通过别名的方式发送(user_id)
                .setNotification(Notification.android(content, title, map))
                .setNotification(Notification.ios(content, map))
                // .setNotification(Notification.ios(content, map))
                // .setNotification(Notification.winphone(content, map))
                .build();
    }
tcm-training-admin-backend/src/main/resources/application.yml
@@ -124,8 +124,8 @@
    # 邀请二维码默认指向线上下载页,开发环境可在 application-local.yml 覆盖。
    landing-base-url: https://haizhentong.com/app-download/
jpush:
  appKey: d2c5362f73af203f25704b8d
  masterSecret: c6996db56be1a93ae16fc1b0
  appKey: b5aed7d076638a0d835786bd
  masterSecret: e17305459be4f0011ca15c9e
logging:
  level: