jinshihui 6 днів тому
батько
коміт
bf9c8ff91c

+ 19 - 0
nightFragrance-admin/src/main/java/com/ylx/web/controller/massage/MaTechnicianController.java

@@ -9,6 +9,7 @@ import com.ylx.common.core.domain.model.LoginUser;
 import com.ylx.massage.domain.dto.MaTechnicianMerchantAddDTO;
 import com.ylx.massage.domain.dto.MaTechnicianMerchantQueryDTO;
 import com.ylx.massage.domain.vo.MaTechnicianAppAddVo;
+import com.ylx.massage.domain.vo.MaTechnicianMerchantDetailVO;
 import com.ylx.massage.domain.vo.MaTechnicianMerchantListVO;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -126,6 +127,24 @@ public class MaTechnicianController extends BaseController {
         }
     }
 
+    /**
+     * 查询商户详情
+     *
+     * @param id 商户ID
+     * @return R<MaTechnicianMerchantDetailVO> 商户详情
+     */
+    @ApiOperation("后台查询商户详情")
+    @PreAuthorize("@ss.hasPermi('technician:technician:query')")
+    @GetMapping("/merchant/detail/{id}")
+    public R<MaTechnicianMerchantDetailVO> merchantDetail(@PathVariable("id") Long id) {
+        try {
+            return R.ok(maTechnicianService.selectMerchantDetail(id));
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
+    }
+
     /**
      * 修改技师
      */

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

@@ -104,12 +104,13 @@ public class MaTechnician extends BaseEntity {
     @Excel(name = "头像")
     @TableField("te_avatar")
     private String teAvatar;
+
     /**
-     * 开通服务:1-上门按摩 2-同城玩乐
+     * 开通服务类目ID
      */
-    @Excel(name = "开通服务:1-上门按摩 2-同城玩乐")
+    @Excel(name = "开通服务类目ID")
     @TableField("openService")
-    private Integer openService;
+    private String openService;
 
     /**
      * 可服务项目

+ 3 - 3
nightFragrance-massage/src/main/java/com/ylx/massage/domain/dto/MaTechnicianMerchantAddDTO.java

@@ -38,10 +38,10 @@ public class MaTechnicianMerchantAddDTO {
     private String tePhone;
 
     /**
-     * 商户开通的服务类目:1-上门按摩,2-陪玩
+     * 商户开通的服务类目ID集合。
      */
-    @ApiModelProperty("服务类目:1-上门按摩 2-陪玩")
-    private Integer openService;
+    @ApiModelProperty("服务类目ID集合")
+    private List<Integer> openService;
 
     /**
      * 商户开通的服务项目ID集合。

+ 2 - 2
nightFragrance-massage/src/main/java/com/ylx/massage/domain/dto/MaTechnicianMerchantQueryDTO.java

@@ -24,9 +24,9 @@ public class MaTechnicianMerchantQueryDTO {
     private String teNickName;
 
     /**
-     * 服务类目:1-上门按摩,2-同城玩乐。
+     * 服务类目ID
      */
-    @ApiModelProperty("服务类目:1-上门按摩 2-同城玩乐")
+    @ApiModelProperty("服务类目ID")
     private Integer openService;
 
     /**

+ 97 - 0
nightFragrance-massage/src/main/java/com/ylx/massage/domain/vo/MaTechnicianMerchantDetailVO.java

@@ -0,0 +1,97 @@
+package com.ylx.massage.domain.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 后台商户详情展示对象
+ */
+@ApiModel(value = "MaTechnicianMerchantDetailVO", description = "后台商户详情展示对象")
+@Data
+public class MaTechnicianMerchantDetailVO {
+
+    /**
+     * 商户唯一标识。
+     */
+    @ApiModelProperty("商户ID")
+    private Long merchantId;
+
+    /**
+     * 商户真实姓名。
+     */
+    @ApiModelProperty("姓名")
+    private String teName;
+
+    /**
+     * 商户在平台对外展示的昵称。
+     */
+    @ApiModelProperty("昵称")
+    private String teNickName;
+
+    /**
+     * 商户性别编码:0-女,1-男。
+     */
+    @ApiModelProperty("性别:0-女 1-男")
+    private Integer teSex;
+
+    /**
+     * 商户性别展示名称。
+     */
+    @ApiModelProperty("性别名称")
+    private String teSexName;
+
+    /**
+     * 商户联系电话。
+     */
+    @ApiModelProperty("电话")
+    private String tePhone;
+
+    /**
+     * 商户开通的服务类目ID,多个用英文逗号分隔。
+     */
+    @ApiModelProperty("服务类目ID集合,逗号分隔")
+    private String openService;
+
+    /**
+     * 商户开通的服务类目名称。
+     */
+    @ApiModelProperty("服务类目")
+    private String serviceCategoryName;
+
+    /**
+     * 商户开通的服务项目ID,多个用英文逗号分隔。
+     */
+    @ApiModelProperty("服务项目ID集合,逗号分隔")
+    private String projectIds;
+
+    /**
+     * 商户开通的服务项目名称,多个用斜杠分隔。
+     */
+    @ApiModelProperty("服务项目")
+    private String serviceProjectName;
+
+    /**
+     * 商户类型编码:0-正式商户,1-虚拟商户。
+     */
+    @ApiModelProperty("商户类型:0-正式商户 1-虚拟商户")
+    private Integer techType;
+
+    /**
+     * 商户类型展示名称。
+     */
+    @ApiModelProperty("商户类型名称")
+    private String techTypeName;
+
+    /**
+     * 首页是否推荐:0-否,1-是。
+     */
+    @ApiModelProperty("是否推荐:0-否 1-是")
+    private Integer isRecommend;
+
+    /**
+     * 首页是否推荐展示名称。
+     */
+    @ApiModelProperty("是否推荐名称")
+    private String isRecommendName;
+}

+ 9 - 0
nightFragrance-massage/src/main/java/com/ylx/massage/mapper/MaTechnicianMapper.java

@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ylx.massage.domain.MaTechnician;
 import com.ylx.massage.domain.dto.MaTechnicianMerchantQueryDTO;
 import com.ylx.massage.domain.dto.MassageMerchantRecommendDto;
+import com.ylx.massage.domain.vo.MaTechnicianMerchantDetailVO;
 import com.ylx.massage.domain.vo.MaTechnicianMerchantListVO;
 import com.ylx.massage.domain.vo.MerchantVo;
 import org.apache.ibatis.annotations.Param;
@@ -76,5 +77,13 @@ public interface MaTechnicianMapper extends BaseMapper<MaTechnician> {
     Page<MaTechnicianMerchantListVO> selectMerchantList(Page<MaTechnicianMerchantListVO> page,
                                                         @Param("dto") MaTechnicianMerchantQueryDTO dto);
 
+    /**
+     * 后台查询商户详情
+     *
+     * @param id 商户ID
+     * @return 商户详情
+     */
+    MaTechnicianMerchantDetailVO selectMerchantDetailById(@Param("id") Long id);
+
     List<MerchantVo> getMerchantRecommend(@Param("dto") MassageMerchantRecommendDto dto);
 }

+ 9 - 0
nightFragrance-massage/src/main/java/com/ylx/massage/service/IMaTechnicianService.java

@@ -8,6 +8,7 @@ import com.ylx.massage.domain.dto.MassageMerchantRecommendDto;
 import com.ylx.massage.domain.dto.MaTechnicianMerchantAddDTO;
 import com.ylx.massage.domain.dto.MaTechnicianMerchantQueryDTO;
 import com.ylx.massage.domain.vo.MaTechnicianAppAddVo;
+import com.ylx.massage.domain.vo.MaTechnicianMerchantDetailVO;
 import com.ylx.massage.domain.vo.MaTechnicianMerchantListVO;
 import com.ylx.massage.domain.vo.MerchantVo;
 
@@ -62,6 +63,14 @@ public interface IMaTechnicianService
     public Page<MaTechnicianMerchantListVO> selectMerchantList(Page<MaTechnicianMerchantListVO> page,
                                                                MaTechnicianMerchantQueryDTO dto);
 
+    /**
+     * 后台查询商户详情
+     *
+     * @param id 商户ID
+     * @return 商户详情
+     */
+    public MaTechnicianMerchantDetailVO selectMerchantDetail(Long id);
+
     /**
      * 修改技师
      *

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

@@ -3,24 +3,25 @@ package com.ylx.massage.service.impl;
 import java.util.ArrayList;
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
-import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ylx.common.core.domain.model.LoginUser;
 import com.ylx.common.exception.ServiceException;
 import com.ylx.common.utils.DateUtils;
 import com.ylx.common.utils.StringUtils;
-import com.ylx.massage.domain.MaProject;
 import com.ylx.massage.domain.MaTeProject;
 import com.ylx.massage.domain.dto.MaTechnicianMerchantAddDTO;
 import com.ylx.massage.domain.dto.MaTechnicianMerchantQueryDTO;
 import com.ylx.massage.domain.dto.MassageMerchantRecommendDto;
 import com.ylx.massage.domain.vo.MaTechnicianAppAddVo;
+import com.ylx.massage.domain.vo.MaTechnicianMerchantDetailVO;
 import com.ylx.massage.domain.vo.MaTechnicianMerchantListVO;
 import com.ylx.massage.domain.vo.MerchantVo;
-import com.ylx.massage.mapper.MaProjectMapper;
 import com.ylx.massage.mapper.MaTeProjectMapper;
 import com.ylx.project.domain.Project;
 import com.ylx.project.mapper.ProjectMapper;
@@ -113,7 +114,7 @@ public class MaTechnicianServiceImpl implements IMaTechnicianService
     @Override
     @Transactional(rollbackFor = Exception.class)
     public int insertMerchant(MaTechnicianMerchantAddDTO dto, LoginUser loginUser) {
-        Set<Long> projectIds = checkMerchantAddParam(dto);
+        MerchantProjectSelection selection = checkMerchantAddParam(dto);
         String userName = loginUser.getUser().getUserName();
 
         MaTechnician maTechnician = new MaTechnician();
@@ -121,15 +122,8 @@ public class MaTechnicianServiceImpl implements IMaTechnicianService
         maTechnician.setTeNickName(dto.getTeNickName().trim());
         maTechnician.setTeSex(dto.getTeSex());
         maTechnician.setTePhone(dto.getTePhone().trim());
-        maTechnician.setOpenService(dto.getOpenService());
-        dto.getProjectIds().forEach(projectId -> {
-            Project project = projectMapper.selectById(projectId);
-            if (project != null) {
-                maTechnician.setTeProject(project.getTitle() + ",");
-            }
-        });
-        //移除末尾的逗号
-        maTechnician.setTeProject(StrUtil.removeSuffix(maTechnician.getTeProject(), ","));
+        maTechnician.setOpenService(joinIds(selection.getCategoryIds()));
+        maTechnician.setTeProject(joinProjectTitles(selection.getProjectIds(), selection.getProjectMap()));
 
         maTechnician.setTechType(dto.getTechType());
         maTechnician.setIsRecommend(normalizeSwitchValue(dto.getIsRecommend(), "是否推荐"));
@@ -154,7 +148,7 @@ public class MaTechnicianServiceImpl implements IMaTechnicianService
         if (rows <= 0) {
             throw new ServiceException("新增商户失败");
         }
-        insertProjectRelations(maTechnician.getId(), projectIds);
+        insertProjectRelations(maTechnician.getId(), selection.getProjectIds());
         return rows;
     }
 
@@ -172,6 +166,24 @@ public class MaTechnicianServiceImpl implements IMaTechnicianService
         return maTechnicianMapper.selectMerchantList(pageParam, dto);
     }
 
+    /**
+     * 后台查询商户详情
+     *
+     * @param id 商户ID
+     * @return 商户详情
+     */
+    @Override
+    public MaTechnicianMerchantDetailVO selectMerchantDetail(Long id) {
+        if (id == null) {
+            throw new ServiceException("商户ID不能为空");
+        }
+        MaTechnicianMerchantDetailVO detail = maTechnicianMapper.selectMerchantDetailById(id);
+        if (detail == null) {
+            throw new ServiceException("商户不存在或已删除");
+        }
+        return detail;
+    }
+
     /**
      * 修改技师
      *
@@ -234,7 +246,7 @@ public class MaTechnicianServiceImpl implements IMaTechnicianService
         return maTechnicianMapper.getMerchantRecommend(dto);
     }
 
-    private Set<Long> checkMerchantAddParam(MaTechnicianMerchantAddDTO dto) {
+    private MerchantProjectSelection checkMerchantAddParam(MaTechnicianMerchantAddDTO dto) {
         if (dto == null) {
             throw new ServiceException("商户参数不能为空");
         }
@@ -242,16 +254,12 @@ public class MaTechnicianServiceImpl implements IMaTechnicianService
         checkRequiredText(dto.getTeNickName(), "昵称", 10);
         checkRequiredText(dto.getTePhone(), "电话", 11);
         checkEnumValue(dto.getTeSex(), "性别", 0, 1);
-        //checkEnumValue(dto.getOpenService(), "服务类目", 1, 2);
-        //校验服务类名不能为空
-        if (dto.getOpenService() == null) {
-            throw new ServiceException("服务类目不能为空");
-        }
+        Set<Integer> categoryIds = checkOpenServiceIds(dto.getOpenService());
         checkEnumValue(dto.getTechType(), "商户类型", 0, 1);
         if (dto.getIsRecommend() != null) {
             checkEnumValue(dto.getIsRecommend(), "是否推荐", 0, 1);
         }
-        return checkProjectIds(dto.getProjectIds());
+        return checkProjectIds(dto.getProjectIds(), categoryIds);
     }
 
     private void checkRequiredText(String value, String fieldName, int maxLength) {
@@ -285,10 +293,12 @@ public class MaTechnicianServiceImpl implements IMaTechnicianService
 
     /**
      * 校验服务项目ID集合
-     * @param projectIds
+     *
+     * @param projectIds 服务项目ID集合
+     * @param categoryIds 服务类目ID集合
      * @return 有效服务项目ID集合
      */
-    private Set<Long> checkProjectIds(List<Long> projectIds) {
+    private MerchantProjectSelection checkProjectIds(List<Long> projectIds, Set<Integer> categoryIds) {
         if (projectIds == null || projectIds.isEmpty()) {
             throw new ServiceException("服务项目不能为空");
         }
@@ -301,17 +311,64 @@ public class MaTechnicianServiceImpl implements IMaTechnicianService
             distinctProjectIds.add(projectId);
         }
 
-        /*int validCount = 0;
+        List<Project> projects = projectMapper.selectList(new LambdaQueryWrapper<Project>()
+                .in(Project::getId, distinctProjectIds)
+                .eq(Project::getIsDelete, 0));
+        if (projects.size() != distinctProjectIds.size()) {
+            throw new ServiceException("服务项目不存在或已删除");
+        }
+
+        Map<Long, Project> projectMap = projects.stream()
+                .collect(Collectors.toMap(project -> project.getId().longValue(), Function.identity(), (left, right) -> left));
+        Set<Integer> projectCategoryIds = new LinkedHashSet<>();
         for (Long projectId : distinctProjectIds) {
-            MaProject project = maProjectMapper.selectMaProjectById(projectId);
-            if (project != null && (project.getIsDelete() == null || project.getIsDelete() != 1)) {
-                validCount++;
+            Project project = projectMap.get(projectId);
+            if (project == null || project.getType() == null) {
+                throw new ServiceException("服务项目类目不能为空");
             }
+            if (!categoryIds.contains(project.getType())) {
+                throw new ServiceException("服务项目不属于所选服务类目");
+            }
+            projectCategoryIds.add(project.getType());
         }
-        if (validCount != distinctProjectIds.size()) {
-            throw new ServiceException("服务项目不存在或已删除");
-        }*/
-        return distinctProjectIds;
+        if (!projectCategoryIds.containsAll(categoryIds)) {
+            throw new ServiceException("每个服务类目至少选择一个服务项目");
+        }
+        return new MerchantProjectSelection(categoryIds, distinctProjectIds, projectMap);
+    }
+
+    /**
+     * 校验服务类目ID集合
+     *
+     * @param openService 服务类目ID集合
+     * @return 去重后的服务类目ID集合
+     */
+    private Set<Integer> checkOpenServiceIds(List<Integer> openService) {
+        if (openService == null || openService.isEmpty()) {
+            throw new ServiceException("服务类目不能为空");
+        }
+        Set<Integer> categoryIds = new LinkedHashSet<>();
+        for (Integer categoryId : openService) {
+            if (categoryId == null) {
+                throw new ServiceException("服务类目ID不能为空");
+            }
+            categoryIds.add(categoryId);
+        }
+        return categoryIds;
+    }
+
+    private String joinIds(Set<Integer> ids) {
+        return ids.stream()
+                .map(String::valueOf)
+                .collect(Collectors.joining(","));
+    }
+
+    private String joinProjectTitles(Set<Long> projectIds, Map<Long, Project> projectMap) {
+        return projectIds.stream()
+                .map(projectMap::get)
+                .map(Project::getTitle)
+                .filter(StringUtils::isNotBlank)
+                .collect(Collectors.joining(","));
     }
 
     /**
@@ -337,4 +394,28 @@ public class MaTechnicianServiceImpl implements IMaTechnicianService
             throw new ServiceException("新增商户服务项目失败");
         }
     }
+
+    private static class MerchantProjectSelection {
+        private final Set<Integer> categoryIds;
+        private final Set<Long> projectIds;
+        private final Map<Long, Project> projectMap;
+
+        private MerchantProjectSelection(Set<Integer> categoryIds, Set<Long> projectIds, Map<Long, Project> projectMap) {
+            this.categoryIds = categoryIds;
+            this.projectIds = projectIds;
+            this.projectMap = projectMap;
+        }
+
+        private Set<Integer> getCategoryIds() {
+            return categoryIds;
+        }
+
+        private Set<Long> getProjectIds() {
+            return projectIds;
+        }
+
+        private Map<Long, Project> getProjectMap() {
+            return projectMap;
+        }
+    }
 }

+ 67 - 1
nightFragrance-massage/src/main/resources/mapper/massage/MaTechnicianMapper.xml

@@ -207,6 +207,23 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="createTime" column="create_time"/>
     </resultMap>
 
+    <resultMap type="com.ylx.massage.domain.vo.MaTechnicianMerchantDetailVO" id="MaTechnicianMerchantDetailResult">
+        <result property="merchantId" column="merchant_id"/>
+        <result property="teName" column="te_name"/>
+        <result property="teNickName" column="te_nick_name"/>
+        <result property="teSex" column="te_sex"/>
+        <result property="teSexName" column="te_sex_name"/>
+        <result property="tePhone" column="te_phone"/>
+        <result property="openService" column="openService"/>
+        <result property="serviceCategoryName" column="service_category_name"/>
+        <result property="projectIds" column="project_ids"/>
+        <result property="serviceProjectName" column="service_project_name"/>
+        <result property="techType" column="tech_type"/>
+        <result property="techTypeName" column="tech_type_name"/>
+        <result property="isRecommend" column="is_recommend"/>
+        <result property="isRecommendName" column="is_recommend_name"/>
+    </resultMap>
+
     <select id="selectMerchantList" resultMap="MaTechnicianMerchantListResult">
         SELECT
             t.id AS merchant_id,
@@ -268,7 +285,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 </if>
                 <!-- 服务类目 -->
                 <if test="dto.openService != null">
-                    AND t.openService = #{dto.openService}
+                    AND FIND_IN_SET(#{dto.openService}, t.openService)
                 </if>
                 <!-- 手机号 -->
                 <if test="dto.tePhone != null and dto.tePhone != ''">
@@ -303,6 +320,55 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         ORDER BY t.create_time DESC
     </select>
 
+    <select id="selectMerchantDetailById" resultMap="MaTechnicianMerchantDetailResult">
+        SELECT
+            t.id AS merchant_id,
+            t.te_name,
+            t.te_nick_name,
+            t.te_sex,
+            CASE t.te_sex
+                WHEN 0 THEN '女'
+                WHEN 1 THEN '男'
+                ELSE ''
+            END AS te_sex_name,
+            t.te_phone,
+            t.openService,
+            COALESCE(project_data.service_category_name, (
+                SELECT GROUP_CONCAT(DISTINCT sc.name ORDER BY sc.sort, sc.id SEPARATOR '/')
+                FROM service_category sc
+                WHERE FIND_IN_SET(sc.id, t.openService)
+                  AND sc.is_delete = 0
+            ), '') AS service_category_name,
+            project_data.project_ids,
+            COALESCE(project_data.service_project_name, t.te_project, '') AS service_project_name,
+            t.tech_type,
+            CASE t.tech_type
+                WHEN 0 THEN '正式商户'
+                WHEN 1 THEN '虚拟商户'
+                ELSE ''
+            END AS tech_type_name,
+            t.is_recommend,
+            CASE t.is_recommend
+                WHEN 1 THEN '是'
+                WHEN 0 THEN '否'
+                ELSE ''
+            END AS is_recommend_name
+        FROM ma_technician t
+        LEFT JOIN (
+            SELECT
+                mtp.te_id,
+                GROUP_CONCAT(DISTINCT p.id ORDER BY p.id SEPARATOR ',') AS project_ids,
+                GROUP_CONCAT(DISTINCT p.title ORDER BY p.id SEPARATOR '/') AS service_project_name,
+                GROUP_CONCAT(DISTINCT sc2.name ORDER BY sc2.sort, sc2.id SEPARATOR '/') AS service_category_name
+            FROM ma_te_project mtp
+            LEFT JOIN project p ON p.id = mtp.project_id AND p.is_delete = 0
+            LEFT JOIN service_category sc2 ON sc2.id = p.type AND sc2.is_delete = 0
+            GROUP BY mtp.te_id
+        ) project_data ON project_data.te_id = t.id
+        WHERE t.is_delete = 0
+          AND t.id = #{id}
+    </select>
+
      <!-- 首页按摩商户推荐列表-->
     <select id="getMerchantRecommend" resultType="com.ylx.massage.domain.vo.MerchantVo">
         SELECT