Browse Source

feat(second): 实现商品下架功能并优化上架逻辑- 将商品下架逻辑从控制器移至服务层,提高代码复用性- 添加事务注解确保下架操作的原子性
- 完善上架逻辑异常处理与补偿机制
- 配置Feign客户端使用配置文件中的URL
- 下架时发送系统通知给用户

wxd 2 months ago
parent
commit
ce90471876

+ 1 - 1
alien-job/src/main/java/shop/alien/job/feign/SecondGoodsFeign.java

@@ -4,7 +4,7 @@ import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 
-@FeignClient(name = "alien-second", url = "http://localhost:9999")
+@FeignClient(name = "alien-second", url = "${feign.alienSecond.url}")
 public interface SecondGoodsFeign {
     
     /**

+ 2 - 7
alien-second/src/main/java/shop/alien/second/controller/SecondGoodsController.java

@@ -117,13 +117,8 @@ public class SecondGoodsController {
     @NoRepeatSubmit(expireTime = 3, message = "请勿重复提交下架商品请求")
     public R<Void> shelveSecondGoods(@ApiParam("下架二手商品") @RequestBody SecondGoodsVo secondGoods) {
         log.info("SecondGoodsController.shelveSecondGoods?secondGoods={}", secondGoods.toString());
-        // 修改商品状态为4 - 已下架
-        secondGoods.setGoodsStatus(4);
-        boolean updateResult = secondGoodsService.updateById(secondGoods);
-        if (updateResult) {
-            // 获取最新的商品信息并记录操作历史
-            SecondGoods updatedGoods = secondGoodsService.getById(secondGoods.getId());
-            secondGoodsService.recordGoodsOperation(updatedGoods,"下架商品");
+        boolean shelveResult = secondGoodsService.shelveSecondGoods(secondGoods);
+        if (shelveResult) {
             return R.success("下架成功");
         } else {
             return R.fail("下架失败");

+ 7 - 0
alien-second/src/main/java/shop/alien/second/service/SecondGoodsService.java

@@ -189,6 +189,13 @@ public interface SecondGoodsService extends IService<SecondGoods> {
     SecondGoodsRecordDetailVo getAdminGoodsRecordDetail(Integer recordId);
 
     /**
+     * 下架商品
+     * @param secondGoods 商品信息
+     * @return 是否下架成功
+     */
+    boolean shelveSecondGoods(SecondGoodsVo secondGoods);
+
+    /**
      * 处理商品信息(管理后台使用)
      * @param goodsId 商品ID
      * @return 处理后的商品详情信息

+ 102 - 19
alien-second/src/main/java/shop/alien/second/service/impl/SecondGoodsServiceImpl.java

@@ -18,6 +18,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StringUtils;
 import shop.alien.entity.SecondVideoTask;
 import shop.alien.entity.second.*;
@@ -634,27 +635,40 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
      * 创建商品审核记录
      * @param goods 商品信息
      */
+//    @Transactional(rollbackFor = Exception.class)
     private void approveAndListGoods(SecondGoods goods) {
-        // 如果所有审核都通过,设置为上架状态
-        goods.setGoodsStatus(SecondGoodsStatusEnum.LISTED.getCode()); // 上架
-        goods.setFailedReason("");
-        goods.setReleaseTime(new Date()); // 上架时间
-        updateById(goods);
-        // 插入审核记录
-        createGoodsAudit(goods, "", Constants.AuditStatus.PASSED);
-        // 发送审核成功消息
-        sendMessage(goods);
-        // 上架 记录商品操作历史
-        String operationName = "";
-        QueryWrapper<SecondGoodsRecord> queryWrapper = new QueryWrapper<>();
-        queryWrapper.eq("goods_id", goods.getId());
-        List<SecondGoodsRecord> recordList = secondGoodsRecordMapper.selectList(queryWrapper);
-        if (CollectionUtil.isNotEmpty(recordList)){
-            operationName = "重新发布";
-        }else {
-            operationName = "首次发布";
+        boolean isNotified = false;
+        try {
+            // 如果所有审核都通过,设置为上架状态
+            goods.setGoodsStatus(SecondGoodsStatusEnum.LISTED.getCode()); // 上架
+            goods.setFailedReason("");
+            goods.setReleaseTime(new Date()); // 上架时间
+            updateById(goods);
+            // 插入审核记录
+            createGoodsAudit(goods, "", Constants.AuditStatus.PASSED);
+            // 发送审核成功消息
+            sendMessage(goods);
+            isNotified = true; // 标记通知已发送
+            // 上架 记录商品操作历史
+            String operationName = "";
+            QueryWrapper<SecondGoodsRecord> queryWrapper = new QueryWrapper<>();
+            queryWrapper.eq("goods_id", goods.getId());
+            List<SecondGoodsRecord> recordList = secondGoodsRecordMapper.selectList(queryWrapper);
+            if (CollectionUtil.isNotEmpty(recordList)){
+                operationName = "重新发布";
+            }else {
+                operationName = "首次发布";
+            }
+            recordGoodsOperation(goods, operationName);
+        } catch (Exception e) {
+            log.error("商品上架过程中发生异常,执行回滚", e);
+            // 如果通知已发送但后续操作失败,需要补偿
+            if (isNotified) {
+                // 发送补偿消息,比如撤销通知或标记为异常状态
+//                sendCompensationMessage(goods);
+            }
+            throw e;
         }
-        recordGoodsOperation(goods, operationName);
     }
 
     /**
@@ -1765,4 +1779,73 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
         
         return result;
     }
+
+    /**
+     * 下架商品
+     * @param secondGoods 商品信息
+     * @return 是否下架成功
+     */
+    @Override
+    public boolean shelveSecondGoods(SecondGoodsVo secondGoods) {
+        log.info("SecondGoodsServiceImpl.shelveSecondGoods?secondGoods={}", secondGoods.toString());
+        // 修改商品状态为4 - 已下架
+        secondGoods.setGoodsStatus(4);
+        boolean updateResult = updateById(secondGoods);
+        if (updateResult) {
+            // 获取最新的商品信息并记录操作历史
+            SecondGoods updatedGoods = getById(secondGoods.getId());
+            recordGoodsOperation(updatedGoods, "下架商品");
+            // 发送系统通知
+            sendShelveMessage(updatedGoods);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+
+    /**
+     * 发送商品下架消息
+     * @param goods 商品信息
+     */
+    private void sendShelveMessage(SecondGoods goods) {
+        try {
+            // 根据 goods.getUserId() 获取用户信息
+            LifeUser lifeUser = lifeUserMapper.selectById(goods.getUserId());
+            String phone = lifeUser.getUserPhone();
+            // 调取feign接口 发送消息 life_notice表
+            LifeNotice lifeNotice = new LifeNotice();
+            lifeNotice.setSenderId("system");
+            lifeNotice.setReceiverId("user_"+ phone);
+            lifeNotice.setBusinessId(goods.getId());
+            lifeNotice.setTitle("商品下架通知");
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put("goodsId", goods.getId());
+//            jsonObject.put("status", "true");
+            jsonObject.put("message", "您的商品:"+ goods.getTitle() + "已下架");
+            lifeNotice.setContext(jsonObject.toJSONString());
+            lifeNotice.setNoticeType(Constants.Notice.SYSTEM_NOTICE); // 系统通知
+            lifeNotice.setIsRead(0);
+            lifeNoticeMapper.insert(lifeNotice);
+            sendShelveNotice("user_"+ phone, lifeNotice);
+        } catch (Exception e) {
+            log.error("发送消息通知失败,goods: {}", goods, e);
+        }
+    }
+
+    private void sendShelveNotice(String receiverId, LifeNotice lifeNotice) {
+        try {
+            WebSocketVo webSocketVo = new WebSocketVo();
+            webSocketVo.setSenderId("system");
+            webSocketVo.setReceiverId(receiverId);
+            webSocketVo.setCategory("notice");
+            webSocketVo.setNoticeType("1");
+            webSocketVo.setIsRead(0);
+            webSocketVo.setText(JSONObject.from(lifeNotice).toJSONString());
+            alienStoreFeign.sendMsgToClientByPhoneId(receiverId, JSONObject.from(webSocketVo).toJSONString());
+        } catch (Exception e) {
+            log.error("发送消息通知失败,receiverId: {}", receiverId, e);
+        }
+    }
+
 }