Bladeren bron

益寿缘app-完善App发红包回显数据

cgp 5 dagen geleden
bovenliggende
commit
64e8fc2b78

+ 12 - 1
fs-service/src/main/java/com/fs/his/mapper/FsUserRewardsMapper.java

@@ -3,6 +3,8 @@ package com.fs.his.mapper;
 import com.fs.his.domain.FsUserRewards;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
 import java.util.List;
 
 /**
@@ -38,7 +40,16 @@ public interface FsUserRewardsMapper {
      * @return 用户活动奖品信息
      */
     public FsUserRewards selectByUserIdAndRewardsId(@Param("fsUserId") Long fsUserId, @Param("rewardsId") Long rewardsId);
-    
+
+    /**
+     * 根据用户ID和奖品id查询(加锁)
+     *
+     * @param fsUserId 用户ID
+     * @param rewardsId 奖品ID
+     * @return 用户活动奖品信息
+     */
+    @Select("SELECT * FROM fs_user_rewards WHERE fs_user_id = #{fsUserId} AND id = #{rewardsId} FOR UPDATE")
+    FsUserRewards selectByUserIdAndRewardsIdForUpdate(@Param("fsUserId") Long fsUserId, @Param("rewardsId") Long rewardsId);
     /**
      * 查询用户的所有活动记录
      *

+ 59 - 29
fs-service/src/main/java/com/fs/his/service/impl/AppUserRewardServiceImpl.java

@@ -42,7 +42,7 @@ public class AppUserRewardServiceImpl implements IAppUserRewardService {
 
     @Autowired
     private FsUserRewardsMapper rewardsMapper;
-    
+
     @Autowired
     private FsUserMapper fsUserMapper;
 
@@ -64,21 +64,22 @@ public class AppUserRewardServiceImpl implements IAppUserRewardService {
     @Autowired
     private FsCourseRedPacketLogMapper redPacketLogMapper;
 
-    private static final String APP_WATCH_COURSE_DAY_KEY ="app:watch:course:day:";
+    private static final String APP_WATCH_COURSE_DAY_KEY = "app:watch:course:day:";
 
-    private static final String LOCK_WATCH_REWARD_KEY ="lock:watch:reward:";
+    private static final String LOCK_WATCH_REWARD_KEY = "lock:watch:reward:";
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public R claimRewards(ClaimRewardsAddDTO claimRewardsAddDTO) {
-        Long fsUserId=claimRewardsAddDTO.getFsUserId();
-        Long rewardsId=claimRewardsAddDTO.getRewardsId();
-        FsUserRewards reward = rewardsMapper.selectByUserIdAndRewardsId(claimRewardsAddDTO.getFsUserId(), rewardsId);
-        if (reward==null){
+        Long fsUserId = claimRewardsAddDTO.getFsUserId();
+        Long rewardsId = claimRewardsAddDTO.getRewardsId();
+        FsUserRewards reward = rewardsMapper.selectByUserIdAndRewardsIdForUpdate(claimRewardsAddDTO.getFsUserId(), rewardsId);
+        if (reward == null) {
             log.info("用户:{}没有可领取的奖品:{}", fsUserId, rewardsId);
             return R.error("操作频繁,请稍后再试!");
         }
-        if (reward.getStatus()==1||reward.getStatus()==2){
-            log.info("用户:{}奖品已领取: rewardsId={}",fsUserId, rewardsId);
+        if (reward.getStatus() == 1 || reward.getStatus() == 2) {
+            log.info("用户:{}奖品已领取: rewardsId={}", fsUserId, rewardsId);
             return R.error("操作频繁,请稍后再试!");
         }
         // 校验是否过期(目前只有看课奖品需要校验过期)
@@ -98,11 +99,34 @@ public class AppUserRewardServiceImpl implements IAppUserRewardService {
             // 更新奖品状态
             rewardsMapper.updateStatus(rewardsId, 1, result.getOrderCode(), DateUtils.getNowDate());
             log.info("奖品领取成功: rewardsId={}, orderCode={}", rewardsId, result.getOrderCode());
-            if (reward.getRewardType()==1) return (R)result.getExtData();
-            return R.ok();
+            // 构建统一的返回对象
+            R response = R.ok();
+
+            // 如果是红包类型,从extData中提取需要的信息放入返回对象
+            //if (reward.getRewardType() == 1) return result.getExtData();
+            if (reward.getRewardType() == 1 && result.getExtData() != null) {
+                R extR = result.getExtData();
+                // 创建一个data对象存放特定字段
+                Map<String, Object> dataMap = new HashMap<>();
+
+                // 只提取需要的字段放入data
+                if (extR.containsKey("packageInfo")) {
+                    dataMap.put("packageInfo", extR.get("packageInfo"));
+                }
+                if (extR.containsKey("mchId")) {
+                    dataMap.put("mchId", extR.get("mchId"));
+                }
+                if (extR.containsKey("appId")) {
+                    dataMap.put("appId", extR.get("appId"));
+                }
+
+                // 将data放入response
+                response.put("data", dataMap);
+            }
+            return response;
         } else {
             log.error("奖品领取失败: rewardsId={}, reason={}", rewardsId, result.getMessage());
-            throw new CustomException(result.getMessage(),result.getCode());
+            throw new CustomException(result.getMessage(), result.getCode());
         }
     }
 
@@ -117,7 +141,7 @@ public class AppUserRewardServiceImpl implements IAppUserRewardService {
             return;
         }
         // 构建奖品记录
-        FsUserRewards reward = buildAppUserReward(fsUserId, activityType, appRoleConfig,null,null);
+        FsUserRewards reward = buildAppUserReward(fsUserId, activityType, appRoleConfig, null, null);
         try {
             // 插入奖品表
             int insertResult = rewardsMapper.insertFsUserRewards(reward);
@@ -146,8 +170,8 @@ public class AppUserRewardServiceImpl implements IAppUserRewardService {
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void addUserWatchCourseRewards(Long fsUserId,Long videoId) {
-        String watchCourseKey = APP_WATCH_COURSE_DAY_KEY  + fsUserId;
+    public void addUserWatchCourseRewards(Long fsUserId, Long videoId) {
+        String watchCourseKey = APP_WATCH_COURSE_DAY_KEY + fsUserId;
         Object cacheObject = redisCache.getCacheObject(watchCourseKey);
         if (cacheObject == null) {
             log.info("用户:{}今日无有效看课记录", fsUserId);
@@ -170,7 +194,7 @@ public class AppUserRewardServiceImpl implements IAppUserRewardService {
             log.info("获取分布式锁成功: userId={}, videoId={}, secret={}",
                     fsUserId, videoId, lock.getLockSecretValue());
 
-            String toDay=DateUtils.getDate();
+            String toDay = DateUtils.getDate();
             // 4. 双重检查:再次确认是否已发放过奖励(防止锁内重复)
             FsUserRewards existingReward = rewardsMapper.selectByUserIdAndVideoId(fsUserId, videoId, toDay);
             if (existingReward != null) {
@@ -189,7 +213,7 @@ public class AppUserRewardServiceImpl implements IAppUserRewardService {
             }
 
             // 构建奖品记录
-            FsUserRewards reward = buildAppUserReward(fsUserId, activityType, appRoleConfig, videoId,toDay);
+            FsUserRewards reward = buildAppUserReward(fsUserId, activityType, appRoleConfig, videoId, toDay);
 
             // 插入奖品表
             try {
@@ -225,11 +249,12 @@ public class AppUserRewardServiceImpl implements IAppUserRewardService {
 
     /**
      * 根据活动类型和角色配置,构建奖品记录
-     * @param fsUserId 用户ID
-     * @param activityType 活动类型
+     *
+     * @param fsUserId      用户ID
+     * @param activityType  活动类型
      * @param appRoleConfig 角色配置
      */
-    private FsUserRewards buildAppUserReward(Long fsUserId, String activityType, FsAppRole appRoleConfig,Long videoId,String toDay) {
+    private FsUserRewards buildAppUserReward(Long fsUserId, String activityType, FsAppRole appRoleConfig, Long videoId, String toDay) {
         FsUserRewards reward = new FsUserRewards();
         reward.setFsUserId(fsUserId);
         reward.setActivityType(activityType);
@@ -290,9 +315,10 @@ public class AppUserRewardServiceImpl implements IAppUserRewardService {
 
     /**
      * 计算奖励值(红包或积分)
+     *
      * @param appRoleConfig 角色配置
-     * @param targetDay 目标天数
-     * @param isRedPackage true-红包,false-积分
+     * @param targetDay     目标天数
+     * @param isRedPackage  true-红包,false-积分
      */
     private <T extends Number> T calculateRewardValue(FsAppRole appRoleConfig, Integer targetDay, boolean isRedPackage) {
         if (appRoleConfig.getCourseRewardRuleType() == 2) {
@@ -305,7 +331,8 @@ public class AppUserRewardServiceImpl implements IAppUserRewardService {
             try {
                 List<Map<String, Object>> rewardList = objectMapper.readValue(
                         courseRewardRule,
-                        new TypeReference<List<Map<String, Object>>>() {}
+                        new TypeReference<List<Map<String, Object>>>() {
+                        }
                 );
 
                 for (Map<String, Object> item : rewardList) {
@@ -379,7 +406,7 @@ public class AppUserRewardServiceImpl implements IAppUserRewardService {
 
     @Override
     public FsAppRole showFirstLoginRewardWindows(Long fsUserId) {
-        FsAppRole fsAppRole =new FsAppRole();
+        FsAppRole fsAppRole = new FsAppRole();
         // 1. 查用户表判断是否首次登录注册App
         FsUser fsUser = fsUserMapper.selectFsUserById(fsUserId);
         if (fsUser != null && fsUser.getFirstLoginTime() != null) {
@@ -502,7 +529,7 @@ public class AppUserRewardServiceImpl implements IAppUserRewardService {
 
     @Override
     public void recordUserWatchCourseDays(Long fsUserId) {
-        String watchCourseKey = APP_WATCH_COURSE_DAY_KEY  + fsUserId;
+        String watchCourseKey = APP_WATCH_COURSE_DAY_KEY + fsUserId;
 
         // 1. 检查Redis中是否有今日已记录的标记
         Object cacheObject = redisCache.getCacheObject(watchCourseKey);
@@ -539,10 +566,10 @@ public class AppUserRewardServiceImpl implements IAppUserRewardService {
     }
 
     //根据用户id、角色id获取配置的奖品信息(实物商品包含商品名称和图片)
-    private FsAppRole getAppRoleConfig(Long fsUserId){
+    private FsAppRole getAppRoleConfig(Long fsUserId) {
         //获取当前用户最高权重角色, "false"表示查询等级数字最大的权重角色
-        FsAppRole fsAppRole = appRoleMapper.selectHighestLevelAppRoleByUserId(fsUserId,"false");
-        if (fsAppRole==null){
+        FsAppRole fsAppRole = appRoleMapper.selectHighestLevelAppRoleByUserId(fsUserId, "false");
+        if (fsAppRole == null) {
             log.info("未找到用户:{}对应的角色配置", fsUserId);
             return null;
         }
@@ -564,11 +591,13 @@ public class AppUserRewardServiceImpl implements IAppUserRewardService {
 
         return Duration.between(now, endOfDay).getSeconds();
     }
+
     /**
      * 积分、商品是否过期的判断方法(红包需要另外方法计算)
+     *
      * @param reward: 奖品
      * @return true: 过期 false: 未过期
-     * */
+     */
     private boolean isExpired(FsUserRewards reward) {
         // 奖品产生时间
         Date rewardTime = reward.getCreateTime();
@@ -605,6 +634,7 @@ public class AppUserRewardServiceImpl implements IAppUserRewardService {
 
     /**
      * 用于计算奖品列表里面的单个奖品的剩余过期天数
+     *
      * @param reward 奖品实体
      * @return 剩余天数。null: 表示无有效期或查询失败;0: 今天过期或已过期;正数: 剩余天数
      */

+ 8 - 1
fs-service/src/main/java/com/fs/his/service/impl/FsStorePaymentServiceImpl.java

@@ -614,7 +614,14 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
         }
         result.put("mchId", config.getMchId());
         result.put("isNew", config.getIsNew());
-        logger.info("红包返回:{}", result);
+        result.put("appId", param.getAppId());
+        Object dataObj = result.get("data");
+        if (dataObj instanceof TransferBillsResult) {
+            TransferBillsResult transferResult = (TransferBillsResult) dataObj;
+            // 显式将 packageInfo 放到顶层,确保能被正确序列化
+            result.put("packageInfo", transferResult.getPackageInfo());
+        }
+        logger.info("app奖品红包返回:{}", result);
         return result;
     }
 

+ 3 - 2
fs-service/src/main/java/com/fs/his/strategy/RewardResult.java

@@ -1,5 +1,6 @@
 package com.fs.his.strategy;
 
+import com.fs.common.core.domain.R;
 import lombok.Data;
 
 /**
@@ -35,7 +36,7 @@ public class RewardResult {
     /**
      * 扩展数据(用于携带额外信息,如红包发送结果)
      */
-    private Object extData;
+    private R extData;
 
     /**
      * 成功静态工厂方法
@@ -58,7 +59,7 @@ public class RewardResult {
     /**
      * 成功并携带扩展数据
      */
-    public static RewardResult successWithExt(Object extData) {
+    public static RewardResult successWithExt(R extData) {
         RewardResult result = new RewardResult();
         result.setCode(200);
         result.setSuccess(true);

+ 1 - 1
fs-service/src/main/java/com/fs/his/strategy/impl/FirstLoginPointsStrategy.java

@@ -38,7 +38,7 @@ public class FirstLoginPointsStrategy  implements RewardStrategy {
 
         } catch (Exception e) {
             log.error("发送积分失败", e);
-            return RewardResult.fail("发送积分失败:" + e.getMessage());
+            throw new RuntimeException("首次注册红包发放失败", e);
         }
     }
     @Transactional(rollbackFor = Exception.class)

+ 1 - 1
fs-service/src/main/java/com/fs/his/strategy/impl/FirstLoginProductStrategy.java

@@ -90,7 +90,7 @@ public class FirstLoginProductStrategy implements RewardStrategy {
 
         } catch (Exception e) {
             log.error("商品订单创建异常", e);
-            return RewardResult.fail("订单创建失败:" + e.getMessage());
+            throw new RuntimeException("首次注册奖励商品订单创建失败", e);
         }
     }
 

+ 4 - 3
fs-service/src/main/java/com/fs/his/strategy/impl/FirstLoginRedPacketStrategy.java

@@ -47,8 +47,9 @@ public class FirstLoginRedPacketStrategy implements RewardStrategy {
                 WxSendRedPacketParam param=buildRedPacketParam(reward, fsUser);
                 //调用发送红包接口逻辑
                 R sendRedPacket = fsStorePaymentService.sendRedPacketAppReward(param);
-
+                log.info("首次登录红包发放结果:"+sendRedPacket);
                 if (sendRedPacket.get("code").equals(200)) {
+                    String packageInfo = (String) sendRedPacket.get("packageInfo");
                     FsAppRewardCourseRedPacketLog record=new FsAppRewardCourseRedPacketLog();
                     TransferBillsResult transferBillsResult;
                     if (sendRedPacket.get("isNew").equals(1)) {
@@ -60,7 +61,7 @@ public class FirstLoginRedPacketStrategy implements RewardStrategy {
                         record.setBatchId(sendRedPacket.get("batchId").toString());
                     }
                     record.setUpdateTime(new Date());
-                    Object aPackage = sendRedPacket.get("package");
+                    Object aPackage = sendRedPacket.get("packageInfo");
                     if (aPackage != null) {
                         record.setPackageInfo(aPackage.toString());
                     }
@@ -82,7 +83,7 @@ public class FirstLoginRedPacketStrategy implements RewardStrategy {
             }
             return RewardResult.fail("红包发放失败,用户不存在");
         } catch (Exception e) {
-            return RewardResult.fail("红包发放失败,请联系客服");
+            throw new RuntimeException("首次注册积分发放失败", e);
         }
     }
 

+ 1 - 1
fs-service/src/main/java/com/fs/his/strategy/impl/WatchCoursePointsStrategy.java

@@ -36,7 +36,7 @@ public class WatchCoursePointsStrategy  implements RewardStrategy {
 
         } catch (Exception e) {
             log.error("发送积分失败", e);
-            return RewardResult.fail("发送积分失败:" + e.getMessage());
+            throw new RuntimeException("看课积分发放失败", e);
         }
     }
 

+ 2 - 2
fs-service/src/main/java/com/fs/his/strategy/impl/WatchCourseProductStrategy.java

@@ -48,7 +48,7 @@ public class WatchCourseProductStrategy  implements RewardStrategy {
             }
             //互联网医院和商城要调用不同的订单创建逻辑
             R result;
-            String orderCode; // 统一在此处定义 orderCode
+            String orderCode;
             if (reward.getProductType() == 1) {
                 FsPackageOrderAddRewardsParam param = buildOrderCreateParam(reward, fsUser);
                 //创建套餐包订单
@@ -90,7 +90,7 @@ public class WatchCourseProductStrategy  implements RewardStrategy {
 
         } catch (Exception e) {
             log.error("商品订单创建异常", e);
-            return RewardResult.fail("订单创建失败:" + e.getMessage());
+            throw new RuntimeException("看课奖励商品订单创建失败", e);
         }
     }
 

+ 3 - 3
fs-service/src/main/java/com/fs/his/strategy/impl/WatchCourseRedPacketStrategy.java

@@ -64,7 +64,7 @@ public class WatchCourseRedPacketStrategy implements RewardStrategy {
                         record.setBatchId(sendRedPacket.get("batchId").toString());
                     }
                     record.setUpdateTime(new Date());
-                    Object aPackage = sendRedPacket.get("package");
+                    Object aPackage = sendRedPacket.get("packageInfo");
                     if (aPackage != null) {
                         record.setPackageInfo(aPackage.toString());
                     }
@@ -81,13 +81,13 @@ public class WatchCourseRedPacketStrategy implements RewardStrategy {
                     appRewardCourseRedPacketLogMapper.insert(record);
                     return RewardResult.successWithExt(sendRedPacket);
                 } else {
-                    return RewardResult.fail("红包发放失败,请联系客服");
+                    return RewardResult.fail("App看课奖励红包发放失败,请联系客服");
                 }
             }
             return RewardResult.success();
 
         } catch (Exception e) {
-            return RewardResult.fail("红包发放失败,请联系客服");
+            return RewardResult.fail("App看课奖励红包发放失败,请联系客服");
         }
     }
 

+ 4 - 0
fs-service/src/main/resources/mapper/his/FsUserRewardsMapper.xml

@@ -51,6 +51,10 @@
         where id = #{rewardsId} and fs_user_id = #{fsUserId}
     </select>
 
+<!--    <select id="selectByUserIdAndRewardsIdForUpdate" parameterType="map" resultType="com.fs.his.domain.FsUserRewards">-->
+<!--        SELECT * FROM fs_user_rewards WHERE fs_user_id = #{fsUserId} AND id = #{rewardsId} FOR UPDATE-->
+<!--    </select>-->
+
     <!-- 查询用户的所有活动记录 -->
     <select id="selectByUserId" parameterType="Long" resultMap="FsUserRewardsResult">
         <include refid="selectFsUserRewardsVo"/>

+ 1 - 1
fs-user-app/src/main/java/com/fs/app/controller/AppUserRewardController.java

@@ -107,7 +107,7 @@ public class AppUserRewardController  extends AppBaseController{
     @Login
     @ApiOperation("奖品列表用户领取奖励")
     @PostMapping("/claim")
-    @NoRepeatSubmit(expire = 10, message = "领取请求处理中,请勿重复提交")
+    @NoRepeatSubmit(expire = 5, message = "领取请求处理中,请勿重复提交")
     public R claimRewards(@RequestBody ClaimRewardsAddDTO claimRewardsAddDTO) {//领取商品时必传收货地址id
         String loginUserId = getUserId();
         if (StringUtils.isEmpty(loginUserId)){