Prechádzať zdrojové kódy

合并接口,开发了新的查询商户信息和入驻资料接口

jinshihui 2 týždňov pred
rodič
commit
333a551115

+ 34 - 13
nightFragrance-admin/src/main/java/com/ylx/web/controller/massage/MaTechnicianController.java

@@ -378,12 +378,19 @@ public class MaTechnicianController extends BaseController {
     /**
      * 技师状态切换
      *
-     * @param
+     * @param userId 商户ID
+     * @param forceConfirm 是否强制切换
+     * @return Result<?>
      */
     @GetMapping("/switchToOffline")
     @ApiOperation("技师状态切换")
     public Result switchToOffline(@RequestParam Long userId, @RequestParam Boolean forceConfirm) {
-        return maTechnicianService.switchToOffline(userId, forceConfirm);
+        try {
+            return maTechnicianService.switchToOffline(userId, forceConfirm);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
     }
 
     /**
@@ -396,13 +403,28 @@ public class MaTechnicianController extends BaseController {
     @ApiOperation("查询商户信息")
     public Result<?> getTechnician(@RequestParam String openid) {
         try {
-            LambdaQueryWrapper<MaTechnician> queryWrapper = new LambdaQueryWrapper<>();
-            queryWrapper.eq(MaTechnician::getCOpenid, openid);
-            MaTechnician maTechnician = maTechnicianService.getOne(queryWrapper);
-            return Result.ok(maTechnician);
+            MerchantAuditFile technicianInfo = maTechnicianService.getTechnicianInfo(openid);
+            return Result.ok(technicianInfo.getMerchant());
         } catch (Exception e) {
-            e.printStackTrace();
-            throw new RuntimeException(e);
+            log.error("查询商户信息失败", e);
+            return Result.error(e.getMessage());
+        }
+    }
+
+    /**
+     * 查询商户信息和入驻资料
+     *
+     * @param openid 微信openid
+     * @return Result<?>
+     */
+    @GetMapping("/getTechnicianInfo")
+    @ApiOperation("查询商户信息和入驻资料")
+    public Result<?> getTechnicianInfo(@RequestParam("openid") String openid) {
+        try {
+            return Result.ok(maTechnicianService.getTechnicianInfo(openid));
+        } catch (Exception e) {
+            log.error("查询商户信息和入驻资料失败", e);
+            return Result.error(e.getMessage());
         }
     }
 
@@ -775,15 +797,14 @@ public class MaTechnicianController extends BaseController {
     }
 
     /**
-     * 商户入信息
+     * 商户入信息
      *
      * @param userId
-     * @return
+     * @return Result<?>
      */
-
     @GetMapping("/getTechnicianList")
-    @ApiOperation("商户入信息")
-    public Result<?> getTechnicianList(@RequestParam(value = "userId") Long userId) {
+    @ApiOperation("商户入信息")
+    public Result<?> getTechnicianList(@RequestParam(value = "userId") Integer userId) {
         return Result.ok(maTechnicianService.getTechnicianList(userId));
     }
 

+ 1 - 1
nightFragrance-admin/src/main/resources/application-dev.yml

@@ -247,7 +247,7 @@ wechat:
   get-code-url: https://open.weixin.qq.com/connect/oauth2/authorize
   # 回调地址
   redirect-url: http://7tjvt8639914.vicp.fun/sq/getAccessToken
-  # 回调地址
+  # 网页授权用户access_token
   access-token-url: https://api.weixin.qq.com/sns/oauth2/access_token
   # 消息模版ID
   template-id-1: HU2LfMIes91Au9kxR3VEoNYuMayxZoPNsFRfWNCmKrQ

+ 1 - 1
nightFragrance-framework/src/main/java/com/ylx/framework/config/SecurityConfig.java

@@ -116,7 +116,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
                         "/wx/pay/query/order/{outTradeNo}","/api/products/**","/api/user/point/**","/userCenter/userApp/queryBind","/weChat/uuidLogin","/couponReceive/getShareVolutionDetail",
                         "/userCenter/ugit credential rejectserApp/bind/update","/serviceCategory/h5List","/api/lbt/v1/select","/sq/getTechnicianToken"
                         ,"/technician/technician/clientLogin","/technician/technician/wait/list","/technician/technician/getServiceCategoryList"
-                ,"/technician/technician/getTechnician" ,"/technician/technician/getSkillList","/technician/technician/getTechnicianList","/technician/technician/apply"
+                ,"/technician/technician/getTechnician" ,"/technician/technician/getTechnicianInfo","/technician/technician/getSkillList","/technician/technician/getTechnicianList","/technician/technician/apply"
                        ).permitAll()
                 // 静态资源,可匿名访问
                 .antMatchers(HttpMethod.GET, "/", "/*.txt", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()

+ 4 - 3
nightFragrance-massage/src/main/java/com/ylx/massage/domain/MaTechnician.java

@@ -104,7 +104,7 @@ public class MaTechnician extends BaseEntity {
     private String teAvatar;
 
     /**
-     * 服务标签
+     * 服务标签(1:按摩推拿 2:陪玩)
      */
     @TableField("service_tag")
     private Integer serviceTag;
@@ -233,10 +233,11 @@ public class MaTechnician extends BaseEntity {
      */
     @Excel(name = "商户管理状态: 0-正常, 1-限制接单, 2-冻结, 3-注销")
     private String merchantStatus;
+
     /**
-     * 商户状态(0休息中1在线接单)
+     * 商户接单状态(0休息中1在线接单)
      */
-    @Excel(name = "商户状态(0休息中1在线接单)")
+    @Excel(name = "商户接单状态(0休息中 1在线接单)")
     private Integer postState;
 
     /**

+ 1 - 0
nightFragrance-massage/src/main/java/com/ylx/massage/domain/MerchantApplyFile.java

@@ -76,6 +76,7 @@ public class MerchantApplyFile implements Serializable {
 
     //是否删除(0否1是)
     @TableField("is_delete")
+    @TableLogic
     private Integer isDelete;
 
 }

+ 14 - 4
nightFragrance-massage/src/main/java/com/ylx/massage/enums/TechnicianStatusEnum.java

@@ -2,18 +2,28 @@ package com.ylx.massage.enums;
 
 import lombok.Data;
 
-
+/**
+ * 商户接单状态枚举
+ */
 public enum TechnicianStatusEnum {
-    ONLINE(1,"接单中"),
-    RESTING(0,"休息中");
+    /**
+     * 休息中
+     */
+    RESTING(0, "休息中"),
+
+    /**
+     * 在线接单
+     */
+    ONLINE(1, "在线接单");
 
     private final Integer code;
     private final String desc;
 
-    TechnicianStatusEnum(Integer code,String desc) {
+    TechnicianStatusEnum(Integer code, String desc) {
         this.desc = desc;
         this.code = code;
     }
+
     public Integer getCode() {
         return code;
     }

+ 12 - 4
nightFragrance-massage/src/main/java/com/ylx/massage/service/IMaTechnicianService.java

@@ -278,12 +278,20 @@ public interface IMaTechnicianService extends IService<MaTechnician> {
     int applyForService(MaProjectSaveDto dto);
 
     /**
-     * 商户入住信息
+     * 根据微信openid查询商户信息和入驻资料。
      *
-     * @param userId
-     * @return
+     * @param openid 微信openid
+     * @return 商户信息和入驻资料附件
+     */
+    MerchantAuditFile getTechnicianInfo(String openid);
+
+    /**
+     * 商户入驻信息
+     *
+     * @param userId 商户ID
+     * @return 商户信息和入驻资料附件
      */
-    MerchantAuditFile getTechnicianList(Long userId);
+    MerchantAuditFile getTechnicianList(Integer userId);
 
     /**
      * 查询商户合同记录信息

+ 76 - 31
nightFragrance-massage/src/main/java/com/ylx/massage/service/impl/MaTechnicianServiceImpl.java

@@ -1038,25 +1038,68 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
     }
 
     /**
-     * 商户入住信息
+     * 根据微信openid查询商户信息和入驻资料。
      *
-     * @param userId
-     * @return
+     * @param openid 微信openid
+     * @return MerchantAuditFile
+     */
+    @Override
+    public MerchantAuditFile getTechnicianInfo(String openid) {
+        if (StringUtils.isBlank(openid)) {
+            throw new IllegalArgumentException("openid不能为空");
+        }
+        return buildMerchantAuditFile(findMerchantByOpenid(openid));
+    }
+
+    /**
+     * 商户入驻信息
+     *
+     * @param userId 商户ID
+     * @return MerchantAuditFile
      */
     @Override
-    public MerchantAuditFile getTechnicianList(Long userId) {
+    public MerchantAuditFile getTechnicianList(Integer userId) {
+        if (userId == null) {
+            throw new IllegalArgumentException("商户ID不能为空");
+        }
+        return buildMerchantAuditFile(findMerchantById(userId));
+    }
+
+    /**
+     * 根据微信openid查询商户信息
+     *
+     * @param openid
+     * @return MaTechnician
+     */
+    private MaTechnician findMerchantByOpenid(String openid) {
+        LambdaQueryWrapper<MaTechnician> query = new LambdaQueryWrapper<>();
+        query.eq(MaTechnician::getCOpenid, openid);
+        return maTechnicianMapper.selectOne(query);
+    }
+
+    private MaTechnician findMerchantById(Integer userId) {
         LambdaQueryWrapper<MaTechnician> query = new LambdaQueryWrapper<>();
         query.eq(MaTechnician::getId, userId);
-        MaTechnician merchant = maTechnicianMapper.selectOne(query);
-        LambdaQueryWrapper<MerchantApplyFile> query1 = new LambdaQueryWrapper<>();
-        query1.eq(MerchantApplyFile::getMerchantId, userId);
-        List<MerchantApplyFile> merchantApplyFile = merchantApplyFileMapper.selectList(query1);
+        return maTechnicianMapper.selectOne(query);
+    }
+
+    private MerchantAuditFile buildMerchantAuditFile(MaTechnician merchant) {
         MerchantAuditFile merchantAuditFile = new MerchantAuditFile();
         merchantAuditFile.setMerchant(merchant);
-        merchantAuditFile.setMerchantAuditFile(merchantApplyFile);
+        if (merchant != null && merchant.getId() != null) {
+            merchantAuditFile.setMerchantAuditFile(listMerchantApplyFiles(merchant.getId()));
+        } else {
+            merchantAuditFile.setMerchantAuditFile(Collections.emptyList());
+        }
         return merchantAuditFile;
     }
 
+    private List<MerchantApplyFile> listMerchantApplyFiles(Integer userId) {
+        LambdaQueryWrapper<MerchantApplyFile> query1 = new LambdaQueryWrapper<>();
+        query1.eq(MerchantApplyFile::getMerchantId, userId);
+        return merchantApplyFileMapper.selectList(query1);
+    }
+
     /**
      * 查询商户合同记录信息
      *
@@ -1178,7 +1221,7 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
      *
      * @param userId
      * @param forceConfirm
-     * @return
+     * @return Result
      */
     @Override
     public Result switchToOffline(Long userId, Boolean forceConfirm) {
@@ -1192,6 +1235,7 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
             // 这里通常会触发前端弹窗要求添加地址,或者直接阻断
             throw new RuntimeException("请完善家庭地址");
         }
+        // 服务标签:按摩推拿
         if (ProjectCategoryEnum.MASSAGE.getCode().equals(technician.getServiceTag())) {
             // 2. 状态判断逻辑 (对应流程图中间的菱形判断)
             // 只有处于“在线接单”状态才需要检查疲劳度/时长限制
@@ -1204,9 +1248,7 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
 
                 long minutesOnline = 0;
                 if (attendance != null && attendance.getAttendanceStartTime() != null) {
-                    LocalDateTime localDateTime = attendance.getAttendanceStartTime().toInstant()
-                            .atZone(ZoneId.systemDefault())
-                            .toLocalDateTime();
+                    LocalDateTime localDateTime = attendance.getAttendanceStartTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
                     //计算截止现在的时长,单位为分钟
                     minutesOnline = Duration.between(localDateTime, LocalDateTime.now()).toMinutes();
                     // 计算今日的累加在线时长
@@ -1220,14 +1262,16 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
                     long requiredMinutes = minutes.longValueExact();
                     // 判断是否超过了平台规定的在线时间 (X小时)
                     if (minutesOnline < requiredMinutes) {
-                        // 情况 A: 超时了,且用户还没有点击“确认下线”(forceConfirm=false)
+                        // 情况: 未满足在线时间,且用户还没有点击“确认下线”(forceConfirm=false)
                         if (!forceConfirm) {
                             // 返回特定错误码或数据结构,告诉前端弹出“我在想想/确认下线”的模态框
                             return Result.ok("平台对您的在线时间做了约定,每日在线需满足"
-                                    + (requiredMinutes / 60) + "小时,距离您下线时间还剩余" + ((requiredMinutes / 60) - minutesOnline) + "小时"
+                                    + (requiredMinutes / 60) + "小时,距离您下线时间还剩余" + ((requiredMinutes / 60) - minutesOnline/60) + "小时"
                                     + "不满足在线时间将收到平台处罚,是否确认下线?");
                         }
-                        // 情况 B: 超时了,但用户已经点击了“确认下线”,允许通过
+                    }else{
+                        // 情况: 已满足在线时间,且用户点击点击了“确认下线”,允许通过
+                        return Result.ok("状态已切换成功");
                     }
                 }
             }
@@ -1256,8 +1300,6 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
                             .set(MerchantDailyAttendance::getUpdateTime, DateUtils.getNowDate());
                     merchantDailyAttendanceMapper.update(update, updateWrapper);
                 }
-
-
             }
         } else {
             //更新状态为在线接单
@@ -1279,7 +1321,7 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
      * 获取今天商户的考勤记录
      *
      * @param userId 技师ID
-     * @return 考勤记录
+     * @return MerchantDailyAttendance 考勤记录
      */
     private MerchantDailyAttendance getTodayAttendance(Long userId) {
         LambdaQueryWrapper<MerchantDailyAttendance> wrapper = new LambdaQueryWrapper<>();
@@ -1287,7 +1329,6 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
                 .eq(MerchantDailyAttendance::getAttendanceDate, DateUtils.getNowDate())
                 .orderByDesc(MerchantDailyAttendance::getCreateTime)
                 .last("LIMIT 1");
-
         return merchantDailyAttendanceMapper.selectOne(wrapper);
     }
 
@@ -1325,14 +1366,13 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
     }
 
     /**
-     * 判断用户是否有生效中的技能
+     * 判断商户是否有开通的技能
      *
-     * @param userId 技师ID
-     * @return true: 有可用技能, false: 无
+     * @param userId 商户ID
+     * @return boolean true: 有可用技能, false: 无
      */
     public boolean hasActiveSkills(Long userId) {
         if (userId == null) return false;
-
         // 构建查询条件:用户ID匹配 AND 状态为已发布/生效中
         LambdaQueryWrapper<MaProject> wrapper = new LambdaQueryWrapper<>();
         wrapper.eq(MaProject::getMerchantId, userId)
@@ -1345,11 +1385,10 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
      * 判断用户是否有家庭地址(通常指设置为默认的地址)
      *
      * @param userId 技师ID
-     * @return true: 有地址, false: 无
+     * @return boolean true: 有地址, false: 无
      */
     public boolean hasHomeAddress(Long userId) {
         if (userId == null) return false;
-
         // 构建查询条件:用户ID匹配 AND 是默认地址(可选) AND 未删除
         LambdaQueryWrapper<TAddress> wrapper = new LambdaQueryWrapper<>();
         wrapper.eq(TAddress::getMerchantId, userId)
@@ -1361,22 +1400,28 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
         return count > 0;
     }
 
-    // 辅助方法:模拟获取用户
+    /**
+     * 获取商户信息
+     * @param userId 商户ID
+     * @return MaTechnician 商户信息
+     */
     private MaTechnician getTechnician(Long userId) {
-        // ... DB查询逻辑
         LambdaQueryWrapper<MaTechnician> query = new LambdaQueryWrapper<>();
         query.eq(MaTechnician::getId, userId);
         return maTechnicianMapper.selectOne(query);
     }
 
-    // 辅助方法:更新状态
+    /**
+     * 更新商户接单状态
+     *
+     * @param userId 商户ID
+     * @param status 商户接单状态枚举
+     */
     private void updateStatus(Long userId, TechnicianStatusEnum status) {
         LambdaUpdateWrapper<MaTechnician> update = new LambdaUpdateWrapper<>();
         update.eq(MaTechnician::getId, userId);
         update.set(MaTechnician::getPostState, status.getCode());
-        // ... DB Update逻辑,同时记录上线/下线时间
         maTechnicianMapper.update(null, update);
-
     }
 
     /**

+ 65 - 0
nightFragrance-massage/src/test/java/com/ylx/massage/service/impl/MaTechnicianServiceImplTest.java

@@ -8,6 +8,7 @@ import com.ylx.massage.domain.MaTechnician;
 import com.ylx.massage.domain.MerchantApplyFile;
 import com.ylx.massage.domain.dto.MerchantApplyFileDto;
 import com.ylx.massage.domain.dto.MerchantApplyFileRequestDto;
+import com.ylx.massage.domain.vo.MerchantAuditFile;
 import com.ylx.massage.mapper.MaTechnicianMapper;
 import com.ylx.massage.mapper.MerchantApplyFileMapper;
 import org.apache.ibatis.builder.MapperBuilderAssistant;
@@ -17,9 +18,11 @@ import org.mockito.ArgumentCaptor;
 import org.springframework.test.util.ReflectionTestUtils;
 
 import java.util.Arrays;
+import java.util.Collections;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.isNull;
@@ -114,6 +117,53 @@ public class MaTechnicianServiceImplTest {
         assertEquals(0, insertedFile.getIsDelete());
     }
 
+    @Test
+    public void getTechnicianInfoFindsMerchantByOpenidWithFiles() {
+        MaTechnicianMapper maTechnicianMapper = mock(MaTechnicianMapper.class);
+        MerchantApplyFileMapper merchantApplyFileMapper = mock(MerchantApplyFileMapper.class);
+        MaTechnician merchant = buildMerchant(7, "openid-7");
+        MerchantApplyFile file = buildApplyFile(7, "1");
+        when(maTechnicianMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(merchant);
+        when(merchantApplyFileMapper.selectList(any(LambdaQueryWrapper.class))).thenReturn(Collections.singletonList(file));
+        MaTechnicianServiceImpl service = buildService(maTechnicianMapper, merchantApplyFileMapper);
+
+        MerchantAuditFile result = service.getTechnicianInfo("openid-7");
+
+        assertEquals(merchant, result.getMerchant());
+        assertEquals(1, result.getMerchantAuditFile().size());
+        assertEquals(file, result.getMerchantAuditFile().get(0));
+    }
+
+    @Test
+    public void getTechnicianListFindsMerchantByUserIdWithFiles() {
+        MaTechnicianMapper maTechnicianMapper = mock(MaTechnicianMapper.class);
+        MerchantApplyFileMapper merchantApplyFileMapper = mock(MerchantApplyFileMapper.class);
+        MaTechnician merchant = buildMerchant(7, "openid-7");
+        MerchantApplyFile file = buildApplyFile(7, "1");
+        when(maTechnicianMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(merchant);
+        when(merchantApplyFileMapper.selectList(any(LambdaQueryWrapper.class))).thenReturn(Collections.singletonList(file));
+        MaTechnicianServiceImpl service = buildService(maTechnicianMapper, merchantApplyFileMapper);
+
+        MerchantAuditFile result = service.getTechnicianList(7);
+
+        assertEquals(merchant, result.getMerchant());
+        assertEquals(1, result.getMerchantAuditFile().size());
+        assertEquals(file, result.getMerchantAuditFile().get(0));
+        ArgumentCaptor<LambdaQueryWrapper<MerchantApplyFile>> fileQueryCaptor = ArgumentCaptor.forClass(LambdaQueryWrapper.class);
+        verify(merchantApplyFileMapper).selectList(fileQueryCaptor.capture());
+        String sqlSegment = fileQueryCaptor.getValue().getSqlSegment();
+        assertTrue(sqlSegment.contains("merchant_id"));
+    }
+
+    @Test
+    public void getTechnicianInfoRejectsBlankOpenid() {
+        MaTechnicianMapper maTechnicianMapper = mock(MaTechnicianMapper.class);
+        MerchantApplyFileMapper merchantApplyFileMapper = mock(MerchantApplyFileMapper.class);
+        MaTechnicianServiceImpl service = buildService(maTechnicianMapper, merchantApplyFileMapper);
+
+        assertThrows(IllegalArgumentException.class, () -> service.getTechnicianInfo(" "));
+    }
+
     private MaTechnicianServiceImpl buildService(MaTechnicianMapper maTechnicianMapper,
                                                  MerchantApplyFileMapper merchantApplyFileMapper) {
         MaTechnicianServiceImpl service = new MaTechnicianServiceImpl();
@@ -122,6 +172,21 @@ public class MaTechnicianServiceImplTest {
         return service;
     }
 
+    private MaTechnician buildMerchant(Integer id, String openid) {
+        MaTechnician merchant = new MaTechnician();
+        merchant.setId(id);
+        merchant.setCOpenid(openid);
+        merchant.setTeNickName("merchant-" + id);
+        return merchant;
+    }
+
+    private MerchantApplyFile buildApplyFile(Integer merchantId, String fileType) {
+        MerchantApplyFile file = new MerchantApplyFile();
+        file.setMerchantId(merchantId);
+        file.setFileType(fileType);
+        return file;
+    }
+
     private MerchantApplyFileDto buildFile(Integer merchantId, String fileType, String fileName, String fileUrl) {
         MerchantApplyFileDto file = new MerchantApplyFileDto();
         file.setMerchantId(merchantId);