Przeglądaj źródła

Merge branch 'sit' into uat-20260202

dujian 15 godzin temu
rodzic
commit
acf00f24f7

+ 25 - 0
alien-entity/src/main/java/shop/alien/entity/second/vo/SecondGoodsStatusVo.java

@@ -0,0 +1,25 @@
+package shop.alien.entity.second.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 二手商品状态查询(精简)
+ */
+@Data
+@ApiModel("二手商品状态")
+public class SecondGoodsStatusVo {
+
+    @ApiModelProperty("商品ID")
+    private Integer id;
+
+    @ApiModelProperty("商品状态 0草稿 1审核中 2审核失败 3已上架 4已下架 5已售出")
+    private Integer goodsStatus;
+
+    @ApiModelProperty("状态名称")
+    private String goodsStatusName;
+
+    @ApiModelProperty("审核失败原因(仅审核失败时有值)")
+    private String failedReason;
+}

+ 25 - 0
alien-second/src/main/java/shop/alien/second/controller/SecondGoodsController.java

@@ -10,6 +10,8 @@ import org.springframework.web.bind.annotation.*;
 import shop.alien.entity.SecondVideoTask;
 import shop.alien.entity.result.R;
 import shop.alien.entity.second.SecondGoods;
+import shop.alien.entity.second.enums.SecondGoodsStatusEnum;
+import shop.alien.entity.second.vo.SecondGoodsStatusVo;
 import shop.alien.entity.second.vo.SecondGoodsVo;
 import shop.alien.mapper.second.SecondGoodsAuditMapper;
 import shop.alien.second.service.SecondGoodsAuditService;
@@ -71,6 +73,29 @@ public class SecondGoodsController {
     }
 
     /**
+     * 根据商品ID查询商品状态
+     */
+    @GetMapping("/getGoodsStatusById")
+    @ApiOperation("根据商品ID查询商品状态(0草稿 1审核中 2审核失败 3已上架 4已下架 5已售出)")
+    public R<SecondGoodsStatusVo> getGoodsStatusById(@ApiParam("商品ID") @RequestParam Integer id) {
+        log.info("SecondGoodsController.getGoodsStatusById?id={}", id);
+        if (id == null) {
+            return R.fail("商品ID不能为空");
+        }
+        SecondGoods goods = secondGoodsService.getById(id);
+        if (goods == null) {
+            return R.fail("商品不存在");
+        }
+        SecondGoodsStatusVo vo = new SecondGoodsStatusVo();
+        vo.setId(goods.getId());
+        vo.setGoodsStatus(goods.getGoodsStatus());
+        SecondGoodsStatusEnum statusEnum = SecondGoodsStatusEnum.fromCode(goods.getGoodsStatus());
+        vo.setGoodsStatusName(statusEnum != null ? statusEnum.getDescription() : null);
+        vo.setFailedReason(goods.getFailedReason());
+        return R.data(vo, "查询成功");
+    }
+
+    /**
      * 添加二手商品
      */
     @PostMapping("/save")

+ 15 - 0
alien-second/src/main/java/shop/alien/second/controller/SecondTradeRecordController.java

@@ -218,4 +218,19 @@ public class SecondTradeRecordController {
         log.info("SecondTradeRecordController.locationShareHas?otherUserId={}", otherUserId);
         return R.data(secondTradeRecordService.locationShareHas(otherUserId));
     }
+
+    @ApiOperation("买家逻辑删除交易记录")
+    @ApiOperationSupport(order = 16)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "userId", value = "当前用户id(对应 buyer_id)", dataType = "Integer", paramType = "query", required = true),
+            @ApiImplicitParam(name = "tradeId", value = "交易记录主键id(second_trade_record.id)", dataType = "Integer", paramType = "query", required = true)
+    })
+    @GetMapping("/logicDeleteByBuyer")
+    public R<Boolean> logicDeleteByBuyer(@RequestParam Integer userId, @RequestParam Integer tradeId) {
+        log.info("SecondTradeRecordController.logicDeleteByBuyer?userId={}, tradeId={}", userId, tradeId);
+        if (secondTradeRecordService.logicDeleteByBuyerAndTradeId(userId, tradeId)) {
+            return R.success("删除成功");
+        }
+        return R.fail("记录不存在、已删除,或参数无效");
+    }
 }

+ 5 - 0
alien-second/src/main/java/shop/alien/second/service/SecondTradeRecordService.java

@@ -58,4 +58,9 @@ public interface SecondTradeRecordService extends IService<SecondTradeRecord> {
     void locationShareDel(Integer otherUserId) throws Exception;
 
     boolean locationShareHas(Integer otherUserId) throws Exception;
+
+    /**
+     * 买家按用户ID与主键 id 逻辑删除 second_trade_record(匹配 buyer_id、id)
+     */
+    boolean logicDeleteByBuyerAndTradeId(Integer userId, Integer tradeId);
 }

+ 11 - 0
alien-second/src/main/java/shop/alien/second/service/impl/SecondTradeRecordServiceImpl.java

@@ -1192,6 +1192,17 @@ public class SecondTradeRecordServiceImpl extends ServiceImpl<SecondTradeRecordM
         return false;
     }
 
+    @Override
+    public boolean logicDeleteByBuyerAndTradeId(Integer userId, Integer tradeId) {
+        if (userId == null || tradeId == null) {
+            return false;
+        }
+        LambdaQueryWrapper<SecondTradeRecord> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(SecondTradeRecord::getBuyerId, userId);
+        wrapper.eq(SecondTradeRecord::getId, tradeId);
+        return remove(wrapper);
+    }
+
     private String getKey(Integer userId, Integer otherUserId) {
         // 组合userId和otherUserId作为Redis的key
         // 使用排序方式确保key的一致性(较小的ID在前)

+ 58 - 33
alien-second/src/main/java/shop/alien/second/util/AiUserViolationUtils.java

@@ -21,6 +21,7 @@ import shop.alien.entity.store.LifeUserViolation;
 import shop.alien.entity.store.vo.LifeUserVo;
 import shop.alien.mapper.LifeMessageMapper;
 import shop.alien.mapper.LifeUserMapper;
+import shop.alien.mapper.LifeUserViolationMapper;
 import shop.alien.mapper.second.SecondGoodsMapper;
 
 import java.text.SimpleDateFormat;
@@ -48,12 +49,14 @@ public class AiUserViolationUtils {
     @Value("${third-party-pass-word.base-url:123456}")
     private String passWord;
 
-    @Value("${third-party-userComplaintRecordUrl.base-url}")
+    @Value("${third-party-ai.report-review.base-url}")
     private String userComplaintRecordUrl;
 
-    @Value("${third-party-goodsComplaintRecordUrl.base-url:${third-party-userComplaintRecordUrl.base-url}}")
+    @Value("${third-party-ai.report-review.base-url}")
     private String goodsComplaintRecordUrl;
 
+    private final LifeUserViolationMapper lifeUserViolationMapper;
+
     /**
      * 登录 AI 服务,获取 token
      *
@@ -112,37 +115,36 @@ public class AiUserViolationUtils {
         analyzeHeaders.set("Authorization", "Bearer " + accessToken);
 
         Map<String, Object> analyzeRequest = new HashedMap<>();
-        // 对应参数
-        if (1 == lifeuserViolation.getDictId()){
-            analyzeRequest.put("complaint_type", "用户违规");
-        } else if (2 == lifeuserViolation.getDictId()){
-            analyzeRequest.put("complaint_type", "色情低俗");
-        } else if (3 == lifeuserViolation.getDictId()){
-            analyzeRequest.put("complaint_type", "违法违规");
-        } else if (4 == lifeuserViolation.getDictId()){
-            analyzeRequest.put("complaint_type", "谩骂嘲讽、煽动对立");
-        } else if (5 == lifeuserViolation.getDictId()){
-            analyzeRequest.put("complaint_type", "涉嫌诈骗");
-        } else if (6 == lifeuserViolation.getDictId()){
-            analyzeRequest.put("complaint_type", "人身攻击");
-        } else if (7 == lifeuserViolation.getDictId()){
-            analyzeRequest.put("complaint_type", "种族歧视");
-        } else if (8 == lifeuserViolation.getDictId()){
-            analyzeRequest.put("complaint_type", "政治敏感");
-        } else if (9 == lifeuserViolation.getDictId()){
-            analyzeRequest.put("complaint_type", "虚假、不实内容");
-        } else if (10 == lifeuserViolation.getDictId()){
-            analyzeRequest.put("complaint_type", "违反公德秩序");
-        } else if (11 == lifeuserViolation.getDictId()){
-            analyzeRequest.put("complaint_type", "危害人身安全");
-        } else if (12 == lifeuserViolation.getDictId()){
-            analyzeRequest.put("complaint_type", "网络暴力");
-        } else {
-            analyzeRequest.put("complaint_type", "其他");
-        }
-
-        analyzeRequest.put("reporter_user_id", lifeuserViolation.getReportingUserId());
-        analyzeRequest.put("reported_user_id", lifeuserViolation.getReportedUserId());
+//        // 对应参数
+//        if (1 == lifeuserViolation.getDictId()){
+//            analyzeRequest.put("complaint_type", "用户违规");
+//        } else if (2 == lifeuserViolation.getDictId()){
+//            analyzeRequest.put("complaint_type", "色情低俗");
+//        } else if (3 == lifeuserViolation.getDictId()){
+//            analyzeRequest.put("complaint_type", "违法违规");
+//        } else if (4 == lifeuserViolation.getDictId()){
+//            analyzeRequest.put("complaint_type", "谩骂嘲讽、煽动对立");
+//        } else if (5 == lifeuserViolation.getDictId()){
+//            analyzeRequest.put("complaint_type", "涉嫌诈骗");
+//        } else if (6 == lifeuserViolation.getDictId()){
+//            analyzeRequest.put("complaint_type", "人身攻击");
+//        } else if (7 == lifeuserViolation.getDictId()){
+//            analyzeRequest.put("complaint_type", "种族歧视");
+//        } else if (8 == lifeuserViolation.getDictId()){
+//            analyzeRequest.put("complaint_type", "政治敏感");
+//        } else if (9 == lifeuserViolation.getDictId()){
+//            analyzeRequest.put("complaint_type", "虚假、不实内容");
+//        } else if (10 == lifeuserViolation.getDictId()){
+//            analyzeRequest.put("complaint_type", "违反公德秩序");
+//        } else if (11 == lifeuserViolation.getDictId()){
+//            analyzeRequest.put("complaint_type", "危害人身安全");
+//        } else if (12 == lifeuserViolation.getDictId()){
+//            analyzeRequest.put("complaint_type", "网络暴力");
+//        } else {
+//            analyzeRequest.put("complaint_type", "其他");
+//        }
+        analyzeRequest.put("id", lifeuserViolation.getId());
+        analyzeRequest.put("type", lifeuserViolation.getReportContextType());
 
         //举报人
         String reporterUserId = lifeuserViolation.getReportingUserId();
@@ -204,6 +206,16 @@ public class AiUserViolationUtils {
                 R.fail("提交用户投诉审核任务返回record_id为空");
                 return  null;
             }
+            // 解析AI审核结果
+            String processingStatus = JSONObject.parseObject(analyzeResp.getBody()).getJSONObject("data").getJSONObject("result").getString("processing_status");
+            boolean success = "1".equals(processingStatus);
+
+            LifeUserViolation lifeUserViolation = lifeUserViolationMapper.selectById(lifeuserViolation.getId());
+
+            // 更新举报处理状态
+            lifeUserViolation.setProcessingStatus(processingStatus);
+            lifeUserViolation.setProcessingTime(new Date());
+            lifeUserViolationMapper.updateById(lifeUserViolation);
             return taskId;
         } else {
             if (analyzeResp != null) {
@@ -305,6 +317,9 @@ public class AiUserViolationUtils {
 
         analyzeRequest.put("evidence_images", lifeuserViolation.getImgUrl());
 
+        analyzeRequest.put("id", lifeuserViolation.getId());
+        analyzeRequest.put("type", lifeuserViolation.getReportContextType());
+
         HttpEntity<Map<String, Object>> analyzeEntity = new HttpEntity<>(analyzeRequest, analyzeHeaders);
 
         ResponseEntity<String> analyzeResp = null;
@@ -331,6 +346,16 @@ public class AiUserViolationUtils {
             }
 
             String taskId = dataJsonObj.getString("task_id");
+            // 解析AI审核结果
+            String processingStatus = JSONObject.parseObject(analyzeResp.getBody()).getJSONObject("data").getJSONObject("result").getString("processing_status");
+            boolean success = "1".equals(processingStatus);
+
+            LifeUserViolation lifeUserViolation = lifeUserViolationMapper.selectById(lifeuserViolation.getId());
+
+            // 更新举报处理状态
+            lifeUserViolation.setProcessingStatus(processingStatus);
+            lifeUserViolation.setProcessingTime(new Date());
+            lifeUserViolationMapper.updateById(lifeUserViolation);
             if (taskId == null) {
                 log.error("提交商品举报审核任务返回task_id为空");
                 return null;

+ 1 - 1
alien-store/src/main/java/shop/alien/store/controller/CommonRatingController.java

@@ -85,7 +85,7 @@ public class CommonRatingController {
             storeId = "#{#commonRating.businessId}",
             targetType = "STORE"
     )
-    @ApiOperation(value = "新增评价", notes = "0:成功(包括审核通过和审核不通过但允许创建的情况), 1:失败, 2:内容审核不通过(直接拒绝)。注意:小票审核和打卡审核不通过时,允许创建评论但审核状态设为不通过并记录审核原因;打卡未通过且小票未通过(含未上传有效消费凭证),将推送「评价审核失败通知」并含店铺名、失败原因与参与指引")
+    @ApiOperation(value = "新增评价", notes = "0:成功(包括审核通过和审核不通过但允许创建的情况), 1:失败, 2:内容审核不通过(直接拒绝)。注意:小票审核不通过时,允许创建评论但审核状态设为不通过并记录原因;打卡仅要求在该店铺有删除的打卡记录(不校验打卡内容是否审核通过)。若未在该店铺打卡且小票未通过(含未上传有效消费凭证),将推送「评价审核失败通知」并含店铺名、失败原因与参与指引")
     @PostMapping("/addRating")
     public R<Integer> add(@RequestBody CommonRating commonRating) {
         log.info("CommonRatingController.add?commonRating={}", commonRating);

+ 5 - 9
alien-store/src/main/java/shop/alien/store/service/impl/CommonRatingServiceImpl.java

@@ -191,22 +191,19 @@ public class CommonRatingServiceImpl extends ServiceImpl<CommonRatingMapper, Com
             // 4. 内容审核通过后,检查是否满足以下条件之一(满足任意一个即可):
             // 条件1:当前用户必须在这个店铺打过卡
             // 条件2:当前用户上传的图片中包含该店铺的小票(调用AI审核)
-            // 注意:小票审核和打卡审核不通过时,允许创建评论,但审核状态设为不通过并记录审核原因
+            // 注意:小票审核不通过时,允许创建评论,但审核状态设为不通过并记录审核原因(打卡仅要求存在记录,不校验审核状态)
             
             boolean condition1Passed = false; // 条件1:打过卡
             boolean condition2Passed = false; // 条件2:有小票
             String auditReason = null; // 审核原因
             
-            // 检查条件1:用户是否在该店铺打过卡(只统计审核通过的打卡)
-            // checkFlag: 0-未审核, 1-审核中, 2-审核通过, 3-审核拒绝
-            // 只有审核通过的打卡(checkFlag=2)才算成功打卡
+            // 检查条件1:用户是否在该店铺有过打卡(未删除即可,不区分打卡内容审核是否通过)
             try {
                 long clockQueryStart = System.currentTimeMillis();
                 LambdaQueryWrapper<StoreClockIn> clockInWrapper = new LambdaQueryWrapper<>();
                 clockInWrapper.eq(StoreClockIn::getUserId, commonRating.getUserId())
                         .eq(StoreClockIn::getStoreId, commonRating.getBusinessId())
                         .eq(StoreClockIn::getDeleteFlag, 0)
-                        .eq(StoreClockIn::getCheckFlag, 2) // 只统计审核通过的打卡(2-审核通过)
                         .last("LIMIT 1");
                 Integer clockInCount = storeClockInMapper.selectCount(clockInWrapper);
                 long clockQueryMs = System.currentTimeMillis() - clockQueryStart;
@@ -217,12 +214,11 @@ public class CommonRatingServiceImpl extends ServiceImpl<CommonRatingMapper, Com
                 }
                 condition1Passed = clockInCount != null && clockInCount > 0;
                 if (condition1Passed) {
-                    log.info("评论审核条件1通过:用户在该店铺有审核通过的打卡记录,userId={}, storeId={}", 
+                    log.info("评论审核条件1通过:用户在该店铺有打卡记录,userId={}, storeId={}", 
                             commonRating.getUserId(), commonRating.getBusinessId());
                 } else {
-                    // 打卡审核不通过,记录审核原因
-                    auditReason = "用户未在该店铺打过卡或打卡审核未通过";
-                    log.info("评论审核条件1未通过:用户未在该店铺有审核通过的打卡记录,userId={}, storeId={}", 
+                    auditReason = "用户未在该店铺打过卡";
+                    log.info("评论审核条件1未通过:用户未在该店铺有打卡记录,userId={}, storeId={}", 
                             commonRating.getUserId(), commonRating.getBusinessId());
                 }
             } catch (Exception e) {

+ 1 - 1
alien-store/src/main/java/shop/alien/store/util/ai/AiReportReviewUtil.java

@@ -39,7 +39,7 @@ public class AiReportReviewUtil {
     private final AiAuthTokenUtil aiAuthTokenUtil;
     private final RestTemplate restTemplate;
 
-    @Value("${third-party-ai.report-review.base-url:http://124.93.18.180:9000/ai/auto-review/api/v1/merchant_dynamic_violation_audit_task/submit}")
+    @Value("${third-party-ai.report-review.base-url}")
     private String aiReportReviewUrl;
 
     private final LifeUserViolationMapper lifeUserViolationMapper;