Jelajahi Sumber

feat(store): 新增洗浴设施及服务的商户端查询功能

- 实现商户端分页查询洗浴设施及服务列表
- 支持根据ID查询洗浴设施及服务详情
- 提供按分类汇总的设备信息查询接口
- 完善商户端设备分类统计逻辑
- 优化设备图片查询与展示逻辑
- 增加通知发送功能至用户举报处理流程
- 增加通知发送功能至差评申诉处理流程
- 引入必要的Mapper和实体类依赖
fcw 1 Minggu lalu
induk
melakukan
548a77df4c

+ 18 - 2
alien-job/src/main/java/shop/alien/job/second/AiUserViolationJob.java

@@ -18,8 +18,9 @@ import org.springframework.util.StringUtils;
 import org.springframework.web.client.RestTemplate;
 import shop.alien.entity.result.R;
 import shop.alien.entity.second.SecondGoods;
-import shop.alien.entity.store.LifeUserViolation;
-import shop.alien.entity.store.SecondAiTask;
+import shop.alien.entity.store.*;
+import shop.alien.mapper.LifeNoticeMapper;
+import shop.alien.mapper.LifeUserMapper;
 import shop.alien.mapper.LifeUserViolationMapper;
 
 import java.util.ArrayList;
@@ -33,6 +34,10 @@ public class AiUserViolationJob {
     private final RestTemplate restTemplate;
     private final LifeUserViolationMapper lifeUserViolationMapper;
 
+    private final LifeUserMapper lifeUserMapper;
+
+    private final LifeNoticeMapper lifeNoticeMapper;
+
     @Value("${third-party-user-name.base-url}")
     private String userName;
 
@@ -146,6 +151,17 @@ public class AiUserViolationJob {
                         }
                     }
 
+                    // 发送通知
+                    LifeNotice lifeMessage = new LifeNotice();
+                    LifeUser lifeUser = lifeUserMapper.selectById(task.getReportingUserId());
+                    lifeMessage.setReceiverId("user_" + lifeUser.getUserPhone());
+                    String text = "您的举报用户结果为" + (aiTask.getProcessingStatus().equals("1") ? "违规" : "未违规");
+                    lifeMessage.setContext(text);
+                    lifeMessage.setSenderId("system");
+                    lifeMessage.setIsRead(0);
+                    lifeMessage.setNoticeType(1);
+                    lifeNoticeMapper.insert(lifeMessage);
+
                     QueryWrapper<LifeUserViolation> queryWrapper = new QueryWrapper<>();
                     queryWrapper.eq("ai_task_id", taskId);
                     LifeUserViolation lifeUserViolation = lifeUserViolationMapper.selectOne(queryWrapper);

+ 18 - 2
alien-job/src/main/java/shop/alien/job/store/BadReviewAppealJob.java

@@ -2,6 +2,7 @@ package shop.alien.job.store;
 
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.xxl.job.core.context.XxlJobHelper;
 import com.xxl.job.core.handler.annotation.XxlJob;
 import lombok.RequiredArgsConstructor;
@@ -18,11 +19,12 @@ import org.springframework.util.LinkedMultiValueMap;
 import org.springframework.util.MultiValueMap;
 import org.springframework.util.StringUtils;
 import org.springframework.web.client.RestTemplate;
-import shop.alien.entity.store.StoreComment;
-import shop.alien.entity.store.StoreCommentAppeal;
+import shop.alien.entity.store.*;
 import shop.alien.entity.result.R;
+import shop.alien.mapper.LifeNoticeMapper;
 import shop.alien.mapper.StoreCommentAppealMapper;
 import shop.alien.mapper.StoreCommentMapper;
+import shop.alien.mapper.StoreUserMapper;
 
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -48,6 +50,8 @@ public class BadReviewAppealJob {
     private final StoreCommentAppealMapper storeCommentAppealMapper;
 
     private final StoreCommentMapper storeCommentMapper;
+    private final StoreUserMapper storeUserMapper;
+    private final LifeNoticeMapper lifeNoticeMapper;
 
 //    @Value("${third-party-login.base-url}")
 //    private String loginUrl;
@@ -172,6 +176,18 @@ public class BadReviewAppealJob {
                     storeCommentAppealMapper.updateByRecordId(appeal.getRecordId(),
                             sCommentAppeal.getAppealStatus(),
                             sCommentAppeal.getFinalResult());
+
+                    // 发送通知
+                    LifeNotice lifeMessage = new LifeNotice();
+                    StoreUser storeUser = storeUserMapper.selectOne(new QueryWrapper<StoreUser>().eq("store_id", appeal.getStoreId()));
+                    lifeMessage.setReceiverId("store_" + storeUser.getPhone());
+                    String text = "您的评论申诉结果为" + sCommentAppeal.getFinalResult();
+                    lifeMessage.setContext(text);
+                    lifeMessage.setSenderId("system");
+                    lifeMessage.setIsRead(0);
+                    lifeMessage.setNoticeType(1);
+                    lifeNoticeMapper.insert(lifeMessage);
+
                 } else {
                     if (analyzeResp != null) {
                         log.error("调用差评申述置信度分析接口失败, http状态: {}", analyzeResp.getStatusCode());

+ 46 - 0
alien-store/src/main/java/shop/alien/store/controller/BathFacilityServiceController.java

@@ -164,5 +164,51 @@ public class BathFacilityServiceController {
         log.info("BathFacilityServiceController.getCategorySummary?storeId={}", storeId);
         return R.data(facilityServiceService.getCategorySummary(storeId));
     }
+
+
+    @ApiOperation("分页查询洗浴设施及服务列表(商户端)")
+    @ApiOperationSupport(order = 8)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "pageNum", value = "页码", dataType = "int", paramType = "query", required = true, defaultValue = "1"),
+            @ApiImplicitParam(name = "pageSize", value = "页大小", dataType = "int", paramType = "query", required = true, defaultValue = "10"),
+            @ApiImplicitParam(name = "storeId", value = "门店ID", dataType = "int", paramType = "query", required = true),
+            @ApiImplicitParam(name = "facilityCategory", value = "设施分类(1:洗浴区, 2:汗蒸区, 3:休闲区, 4:餐饮区)", dataType = "int", paramType = "query")
+    })
+    @GetMapping("/storePage")
+    public R<IPage<BathFacilityServiceVo>> getStorePageList(
+            @RequestParam(defaultValue = "1") Integer pageNum,
+            @RequestParam(defaultValue = "10") Integer pageSize,
+            @RequestParam Integer storeId,
+            @RequestParam(required = false) Integer facilityCategory) {
+        log.info("BathFacilityServiceController.getStorePageList?pageNum={},pageSize={},storeId={},facilityCategory={}",
+                pageNum, pageSize, storeId, facilityCategory);
+        return R.data(facilityServiceService.getStorePageList(pageNum, pageSize, storeId, facilityCategory));
+    }
+
+    @ApiOperation("根据ID查询洗浴设施及服务详情(商户端)")
+    @ApiOperationSupport(order = 9)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键ID", dataType = "int", paramType = "query", required = true)
+    })
+    @GetMapping("/storeDetail")
+    public R<BathFacilityServiceVo> getStoreDetail(@RequestParam Integer id) {
+        log.info("BathFacilityServiceController.getStoreDetail?id={}", id);
+        BathFacilityServiceVo vo = facilityServiceService.getStoreDetail(id);
+        if (vo == null) {
+            return R.fail("数据不存在");
+        }
+        return R.data(vo);
+    }
+
+    @ApiOperation("查询指定店铺按分类汇总的设备信息(包含设备数量、设备列表和图片)(商户端)")
+    @ApiOperationSupport(order = 7)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "storeId", value = "门店ID", dataType = "int", paramType = "query", required = true)
+    })
+    @GetMapping("/storeCategorySummary")
+    public R<List<BathFacilityServiceCategoryVo>> getStoreCategorySummary(@RequestParam Integer storeId) {
+        log.info("BathFacilityServiceController.getStoreCategorySummary?storeId={}", storeId);
+        return R.data(facilityServiceService.getStoreCategorySummary(storeId));
+    }
 }
 

+ 6 - 0
alien-store/src/main/java/shop/alien/store/service/BathFacilityServiceService.java

@@ -78,5 +78,11 @@ public interface BathFacilityServiceService extends IService<BathFacilityService
      * @return List<BathFacilityServiceCategoryVo>
      */
     List<BathFacilityServiceCategoryVo> getCategorySummary(Integer storeId);
+
+    IPage<BathFacilityServiceVo> getStorePageList(Integer pageNum, Integer pageSize, Integer storeId, Integer facilityCategory);
+
+    BathFacilityServiceVo getStoreDetail(Integer id);
+
+    List<BathFacilityServiceCategoryVo> getStoreCategorySummary(Integer storeId);
 }
 

+ 75 - 0
alien-store/src/main/java/shop/alien/store/service/impl/BathFacilityServiceServiceImpl.java

@@ -254,5 +254,80 @@ public class BathFacilityServiceServiceImpl extends ServiceImpl<BathFacilityServ
         
         return result;
     }
+
+    @Override
+    public IPage<BathFacilityServiceVo> getStorePageList(Integer pageNum, Integer pageSize, Integer storeId, Integer facilityCategory) {
+        Page<BathFacilityService> page = new Page<>(pageNum, pageSize);
+        LambdaQueryWrapper<BathFacilityService> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(BathFacilityService::getStoreId, storeId);
+        if (facilityCategory != null) {
+            queryWrapper.eq(BathFacilityService::getFacilityCategory, facilityCategory);
+        }
+        queryWrapper.orderByDesc(BathFacilityService::getCreatedTime);
+        IPage<BathFacilityService> facilityServicePage = facilityServiceMapper.selectPage(page, queryWrapper);
+        return facilityServicePage.convert(this::convertToVo);
+    }
+
+    @Override
+    public BathFacilityServiceVo getStoreDetail(Integer id) {
+        BathFacilityService facilityService = facilityServiceMapper.selectById(id);
+        if (facilityService == null) {
+            return null;
+        }
+        return convertToVo(facilityService);
+    }
+
+    @Override
+    public List<BathFacilityServiceCategoryVo> getStoreCategorySummary(Integer storeId) {
+        List<BathFacilityServiceCategoryVo> result = new ArrayList<>();
+
+        // 遍历所有分类(1:洗浴区, 2:汗蒸区, 3:休闲区, 4:餐饮区)
+        for (int category = 1; category < FACILITY_CATEGORY_NAMES.length; category++) {
+            BathFacilityServiceCategoryVo categoryVo = new BathFacilityServiceCategoryVo();
+            categoryVo.setFacilityCategory(category);
+            categoryVo.setFacilityCategoryName(FACILITY_CATEGORY_NAMES[category]);
+
+            // 查询该分类下的设备列表(不分页)
+            LambdaQueryWrapper<BathFacilityService> facilityWrapper = new LambdaQueryWrapper<>();
+            facilityWrapper.eq(BathFacilityService::getStoreId, storeId)
+                    .eq(BathFacilityService::getFacilityCategory, category);
+            facilityWrapper.orderByDesc(BathFacilityService::getCreatedTime);
+            List<BathFacilityService> facilityServiceList = facilityServiceMapper.selectList(facilityWrapper);
+
+            // 设置设备数量
+            categoryVo.setFacilityCount(facilityServiceList != null ? facilityServiceList.size() : 0);
+
+            // 查询该分类的代表图片(从第一个设备的第一张图片获取)
+            if (!CollectionUtils.isEmpty(facilityServiceList)) {
+                BathFacilityService firstFacility = facilityServiceList.get(0);
+                // 查询该设备的第一张图片
+                LambdaQueryWrapper<StoreImg> imageWrapper = new LambdaQueryWrapper<>();
+                imageWrapper.eq(StoreImg::getStoreId, storeId)
+                        .eq(StoreImg::getBusinessId, firstFacility.getId())
+                        .eq(StoreImg::getImgType, IMG_TYPE_BATH_FACILITY);
+                imageWrapper.orderByAsc(StoreImg::getImgSort);
+                imageWrapper.last("LIMIT 1");
+                StoreImg firstImage = storeImgMapper.selectOne(imageWrapper);
+                if (firstImage != null) {
+                    categoryVo.setCategoryImage(firstImage.getImgUrl());
+                }
+            }
+
+            // 转换为VO列表(包含设备信息和图片)
+            List<BathFacilityServiceVo> facilityVoList = new ArrayList<>();
+            if (!CollectionUtils.isEmpty(facilityServiceList)) {
+                for (BathFacilityService facilityService : facilityServiceList) {
+                    // 使用现有的convertToVo方法,它会自动查询图片
+                    BathFacilityServiceVo vo = convertToVo(facilityService);
+                    facilityVoList.add(vo);
+                }
+            }
+            categoryVo.setFacilityList(facilityVoList);
+
+            result.add(categoryVo);
+        }
+
+        return result;
+    }
 }