4 Комити 42dea99323 ... 53e561b842

Аутор SHA1 Порука Датум
  jinshihui 53e561b842 Merge remote-tracking branch 'origin/dev' into dev пре 6 дана
  jinshihui 9c6328d002 优化代码 пре 6 дана
  jinshihui a2258f96f3 Merge remote-tracking branch 'origin/dev' into dev пре 6 дана
  jinshihui bf9c8ff91c 优化代码 пре 6 дана

+ 70 - 319
nightFragrance-admin/src/main/java/com/ylx/web/controller/massage/MaTechnicianController.java

@@ -1,42 +1,28 @@
 package com.ylx.web.controller.massage;
 
-import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Pattern;
-import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.ylx.common.core.domain.model.aliyun.SMSVerificationCode;
-import com.ylx.common.core.domain.model.aliyun.SendSmsComponents;
-import com.ylx.common.core.domain.model.aliyun.SendSmsEnum;
-import com.ylx.common.utils.StringUtils;
-import com.ylx.massage.domain.MaProject;
-import com.ylx.massage.domain.dto.MaProjectSaveDto;
-import com.ylx.massage.domain.dto.MaProjectUpdateDto;
-import com.ylx.massage.domain.vo.MaProjectGetVo;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ylx.common.core.domain.R;
+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.Result;
-import com.ylx.massage.domain.vo.ThirdPartyLoginsVo;
-import com.ylx.massage.service.IMaProjectService;
-import com.ylx.project.domain.Project;
-import com.ylx.servicecategory.domain.ServiceCategory;
-import com.ylx.servicecategory.service.ServiceCategoryService;
+import com.ylx.massage.domain.vo.MaTechnicianMerchantDetailVO;
+import com.ylx.massage.domain.vo.MaTechnicianMerchantListVO;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import org.apache.commons.lang3.ObjectUtils;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
 import com.ylx.common.annotation.Log;
 import com.ylx.common.core.controller.BaseController;
 import com.ylx.common.core.domain.AjaxResult;
@@ -58,194 +44,6 @@ import com.ylx.common.core.page.TableDataInfo;
 public class MaTechnicianController extends BaseController {
     @Autowired
     private IMaTechnicianService maTechnicianService;
-    @Autowired
-    private StringRedisTemplate redisTemplate;
-
-    @Autowired
-    private SendSmsComponents sendSms;
-    @Autowired
-    private ServiceCategoryService serviceCategoryService;
-    @Autowired
-    private IMaProjectService maProjectService;
-
-    public static final String PHONE_THREEUSERPARTCLIENT_CODE_KEY = "sys:threeUserPartClient:phone:";
-
-    @GetMapping("/sendMsg")
-    @ApiOperation(value = "短信发送", notes = "短信发送")
-    public Result sendMsg(@RequestParam String phone, HttpServletRequest request) {
-        if (org.apache.commons.lang3.StringUtils.isEmpty(phone)) {
-            return Result.error("手机号不能为空");
-        }
-        Random rand = new Random();
-        // randNumber 将被赋值为一个 MIN 和 MAX 范围内的随机数
-        int randNumber = rand.nextInt(9999 - 1000 + 1) + 1000;
-        // 保存验证码到redis
-        redisTemplate.opsForValue()
-                .set("userH5:order:phone:" + phone, String.valueOf(randNumber), 5L
-                        , TimeUnit.MINUTES);
-        try {
-            SMSVerificationCode smsVerificationCode = new SMSVerificationCode(String.valueOf(randNumber));
-            String jsonString = JSON.toJSONString(smsVerificationCode);
-            sendSms.sendSms(phone, SendSmsEnum.SMS_220650024, jsonString);
-            return Result.ok("发送成功");
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        return Result.ok("发送失败");
-    }
-
-    /**
-     * 商户登录接口
-     *
-     * @param thirdPartyLoginsVo
-     * @return
-     */
-    @ApiOperation(value = "商户登录", notes = "商户登录")
-    @PostMapping(value = "/clientLogin")
-    @Transactional
-    public Result<JSONObject> login(@RequestBody ThirdPartyLoginsVo thirdPartyLoginsVo) throws Exception {
-        // 获取登录用户信息
-        Result<JSONObject> result = new Result<>();
-
-        // 校验手机号是否为空
-        if (StringUtils.isEmpty(thirdPartyLoginsVo.getPhone())) {
-            return result.error500("请输入手机号");
-        }
-
-        // 校验用户是否存在且有效
-        LambdaQueryWrapper<MaTechnician> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(MaTechnician::getTePhone, thirdPartyLoginsVo.getPhone());
-        MaTechnician maTechnician = maTechnicianService.getBaseMapper().selectOne(queryWrapper);
-        // 校验用户是否有效
-        if (ObjectUtils.isEmpty(maTechnician)) {
-            return result.error500("商户不存在,请先注册");
-
-        }
-
-        if (thirdPartyLoginsVo.getCodeSwitch()) {
-            // 短信验证
-            String msg = redisTemplate.opsForValue().get(PHONE_THREEUSERPARTCLIENT_CODE_KEY + thirdPartyLoginsVo.getPhone());
-            if (StringUtils.isEmpty(msg)) {
-                return Result.error("验证码已失效");
-            }
-
-            if (!thirdPartyLoginsVo.getPhoneMsg().equals(msg)) {
-                return Result.error("短信验证码不正确");
-            }
-        } else {
-            if (!thirdPartyLoginsVo.getPassWord().equals(maTechnician.getTePassword())) {
-                return Result.error("密码错误");
-            }
-
-        }
-
-        // 登录成功删除验证码
-        redisTemplate.delete(PHONE_THREEUSERPARTCLIENT_CODE_KEY + thirdPartyLoginsVo.getPhone());
-        result.success("登录成功");
-        return result;
-    }
-
-    /**
-     * 商户忘记密码接口
-     */
-    @PostMapping("/resetPassword")
-    public Result<?> resetPassword(@RequestBody ThirdPartyLoginsVo thirdPartyLoginsVo) {
-        // 核心正则表达式:
-        // ^ 表示开头,$ 表示结尾
-        // [a-zA-Z0-9] 表示只能是字母或数字
-        // {8,20} 表示长度必须在8到20之间
-        String regex = "^[a-zA-Z0-9]{8,20}$";
-        boolean isMatch = Pattern.matches(regex, thirdPartyLoginsVo.getPhoneMsg());
-        if (!isMatch) {
-            // 根据需求返回指定的异常提示
-            return Result.error("请输入8-20位数字/字母组合");
-        }
-        // 短信验证
-        String msg = redisTemplate.opsForValue().get(PHONE_THREEUSERPARTCLIENT_CODE_KEY + thirdPartyLoginsVo.getPhone());
-        if (StringUtils.isEmpty(msg)) {
-            return Result.error("验证码已失效");
-        }
-        if (!thirdPartyLoginsVo.getPhoneMsg().equals(msg)) {
-            return Result.error("短信验证码不正确");
-        }
-        // 重置密码逻辑
-        LambdaUpdateWrapper<MaTechnician> updateWrapper = new LambdaUpdateWrapper<>();
-        updateWrapper.eq(MaTechnician::getTePhone, thirdPartyLoginsVo.getPhone());
-        updateWrapper.set(MaTechnician::getTePassword, thirdPartyLoginsVo.getPassWord());
-        maTechnicianService.update(updateWrapper);
-        redisTemplate.delete(PHONE_THREEUSERPARTCLIENT_CODE_KEY + thirdPartyLoginsVo.getPhone());
-        return Result.ok("重置密码成功");
-    }
-
-    /**
-     * 商户入驻申请接口
-     */
-    @PostMapping("/apply")
-    public Result<?> apply(@RequestBody MaTechnicianAppAddVo req) {
-        // 1. 基础参数校验
-        if (StringUtils.isAnyBlank(req.getTeName(), req.getTePhone(), req.getTeAddress(), req.getTeAvatar(), req.getLifePhotos(), req.getTeBrief(), req.getAvatar(), req.getIdCard())) {
-            return Result.error("必填项不能为空");
-        }
-        // 2. 调用业务层处理入驻申请
-        maTechnicianService.apply(req);
-        return Result.ok("提交成功,进入审核流程");
-    }
-
-    /**
-     * 查询商户信息接口
-     */
-    @GetMapping("/getTechnician")
-    public Result<?> getTechnician(@RequestParam String phone) {
-        LambdaQueryWrapper<MaTechnician> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(MaTechnician::getTePhone, phone);
-        MaTechnician maTechnician = maTechnicianService.getBaseMapper().selectOne(queryWrapper);
-        return Result.ok(maTechnician);
-    }
-
-    /**
-     * 修改和上传商户信息接口
-     */
-    @PostMapping("/updateTechnician")
-    public Result<?> updateTechnician(@RequestBody MaTechnicianAppAddVo req) {
-        if (req.getAuditStatus() == 0 || req.getAuditStatus() == 3) {
-            //修改基本信息
-            updateMaTechnician(req);
-        } else if (req.getAuditStatus() == 1 || req.getAuditStatus() == 2) {
-            //上传商户资料信息
-            extractedUpdate(req);
-        }
-        return Result.ok("修改成功");
-    }
-
-    private void extractedUpdate(MaTechnicianAppAddVo req) {
-        LambdaUpdateWrapper<MaTechnician> updateWrapper = new LambdaUpdateWrapper<>();
-        updateWrapper.eq(MaTechnician::getId, req.getId());
-        updateWrapper.set(MaTechnician::getTeAvatar, req.getTeAvatar());
-        updateWrapper.set(MaTechnician::getTeNickName, req.getTeNickName());
-        updateWrapper.set(MaTechnician::getTeBrief, req.getTeBrief());
-        updateWrapper.set(MaTechnician::getLifePhotos, req.getLifePhotos());
-        updateWrapper.set(MaTechnician::getIdCard, req.getIdCard());
-        updateWrapper.set(MaTechnician::getHealthCertificate, req.getHealthCertificate());
-        updateWrapper.set(MaTechnician::getQualificationCertificate, req.getQualificationCertificate());
-        updateWrapper.set(MaTechnician::getNoCrimeRecord, req.getNoCrimeRecord());
-        updateWrapper.set(MaTechnician::getPromoVideo, req.getPromoVideo());
-        updateWrapper.set(MaTechnician::getCommitmentAudio, req.getCommitmentAudio());
-        updateWrapper.set(MaTechnician::getCommitmentPdf, req.getCommitmentPdf());
-        updateWrapper.set(MaTechnician::getCommitmentVideo, req.getCommitmentVideo());
-        maTechnicianService.update(updateWrapper);
-    }
-
-    private void updateMaTechnician(MaTechnicianAppAddVo req) {
-        LambdaUpdateWrapper<MaTechnician> updateWrapper = new LambdaUpdateWrapper<>();
-        updateWrapper.eq(MaTechnician::getId, req.getId());
-        updateWrapper.set(MaTechnician::getTePhone, req.getTePhone());
-        updateWrapper.set(MaTechnician::getTeName, req.getTeName());
-        updateWrapper.set(MaTechnician::getOpenService, req.getOpenService());
-        updateWrapper.set(MaTechnician::getTeAddress, req.getTeAddress());
-        updateWrapper.set(MaTechnician::getTeAge, req.getTeAge());
-        updateWrapper.set(MaTechnician::getAvatar, req.getAvatar());
-        maTechnicianService.update(updateWrapper);
-    }
 
     /**
      * 查询技师列表
@@ -291,126 +89,79 @@ public class MaTechnicianController extends BaseController {
     }
 
     /**
-     * 修改技师
-     */
-    @PreAuthorize("@ss.hasPermi('technician:technician:edit')")
-    @Log(title = "技师", businessType = BusinessType.UPDATE)
-    @PutMapping
-    public AjaxResult edit(@RequestBody MaTechnicianAppAddVo maTechnicianAppAddVo) {
-        return toAjax(maTechnicianService.updateMaTechnician(maTechnicianAppAddVo));
-    }
-
-    /**
-     * 删除技师
-     */
-    @PreAuthorize("@ss.hasPermi('technician:technician:remove')")
-    @Log(title = "技师", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{ids}")
-    public AjaxResult remove(@PathVariable Long[] ids) {
-        return toAjax(maTechnicianService.deleteMaTechnicianByIds(ids));
-    }
-
-    /**
-     * 1. 获取服务类目列表 (对应图1、图3)
-     */
-    @GetMapping("/getServiceCategoryList")
-    public AjaxResult getServiceCategoryList() {
-        List<ServiceCategory> list = serviceCategoryService.listH5ServiceCategory();
-        return AjaxResult.success(list);
-    }
-
-    /**
-     * 1. 获取技能列表 (对应图1、图3)
-     * 支持 Tab 切换:all(全部), active(已开通), applying(申请中), rejected(驳回)
+     * 后台新增商户
+     *
+     * @param dto 商户新增DTO
+     * @return AjaxResult 结果
      */
-    @PostMapping("/getSkillList")
-    public TableDataInfo getSkillList(@RequestBody MaProjectGetVo req) {
-        startPage();
-        List<MaProject> list = maTechnicianService.selectMaTechnicianListBy(req.getUserId(), req.getAuditStatus());
-        if (ObjectUtils.isEmpty(list)) {
-            List<Project> projectslist = maTechnicianService.selectTechnicianListBy(req.getTypeId());
-            return getDataTable(projectslist);
-        } else {
-            return getDataTable(list);
+    @ApiOperation("后台新增商户")
+    @PreAuthorize("@ss.hasPermi('technician:technician:add')")
+    @Log(title = "商户", businessType = BusinessType.INSERT)
+    @PostMapping("/merchant")
+    public AjaxResult addMerchant(@RequestBody MaTechnicianMerchantAddDTO dto) {
+        try {
+            LoginUser loginUser = getLoginUser();
+            return toAjax(maTechnicianService.insertMerchant(dto, loginUser));
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
         }
     }
 
     /**
-     * 查询未开通的服务项目列表
+     * 查询商户列表
      *
-     * @param req
-     * @return
+     * @param page  分页参数
+     * @param dto 商户查询DTO
+     * @return Page 商户分页列表
      */
-    @PostMapping("/getNotApplyList")
-    public Result<?> getNotApplyList(@RequestBody MaProjectGetVo req) {
-
-        return Result.ok(maTechnicianService.getNotApplyList(req.getUserId(), req.getTypeId()));
-
+    @ApiOperation("后台查询商户列表")
+    @PreAuthorize("@ss.hasPermi('technician:technician:list')")
+    @GetMapping("/merchant/list")
+    public R<Page<MaTechnicianMerchantListVO>> merchantList(Page<MaTechnicianMerchantListVO> page, MaTechnicianMerchantQueryDTO dto) {
+        try {
+            return R.ok(maTechnicianService.selectMerchantList(page, dto));
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
     }
 
     /**
-     * 申请开通新服务
+     * 查询商户详情
+     *
+     * @param id 商户ID
+     * @return R<MaTechnicianMerchantDetailVO> 商户详情
      */
-    @PostMapping("/applyForService")
-    public AjaxResult applyForService(@RequestBody MaProjectSaveDto dto) {
-
-        return toAjax(maTechnicianService.applyForService(dto));
+    @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);
+        }
     }
 
     /**
-     * 重新申请开通新服务
-     *
-     * @param req
-     * @return
+     * 修改技师
      */
-    @PostMapping("/updateApply")
-    public Result<?> updateApply(@RequestBody MaProjectUpdateDto req) {
-        if (StringUtils.isNotEmpty(req.getProjectId()) && StringUtils.isNotEmpty(req.getApplyReason())) {
-            LambdaUpdateWrapper<MaProject> updateWrapper = new LambdaUpdateWrapper<>();
-            updateWrapper.eq(MaProject::getId, req.getProjectId());
-            updateWrapper.set(MaProject::getApplyReason, req.getApplyReason());
-            updateWrapper.set(MaProject::getAuditStatus, 0);
-            maProjectService.update(updateWrapper);
-        }
-        return Result.ok("重新申请成功,提交到审核阶段");
-
+    @PreAuthorize("@ss.hasPermi('technician:technician:edit')")
+    @Log(title = "技师", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody MaTechnicianAppAddVo maTechnicianAppAddVo) {
+        return toAjax(maTechnicianService.updateMaTechnician(maTechnicianAppAddVo));
     }
 
     /**
-     * 申请下架,删除服务项目,编辑售价价格
-     *
-     * @param req
-     * @return
+     * 删除技师
      */
-    @PostMapping("/updateMaProject")
-    public Result<?> updateMaProject(@RequestBody MaProjectUpdateDto req) {
-        String message = "";
-        if (StringUtils.isNotEmpty(req.getProjectId())) {
-            if (req.getIsDelete()) {
-                LambdaUpdateWrapper<MaProject> updateWrapper = new LambdaUpdateWrapper<>();
-                updateWrapper.eq(MaProject::getId, req.getProjectId());
-                updateWrapper.set(MaProject::getIsDelete, 1);
-                maProjectService.update(updateWrapper);
-                message = "删除成功";
-            }
-            if (req.getIsPass()) {
-                LambdaUpdateWrapper<MaProject> updateWrapper = new LambdaUpdateWrapper<>();
-                updateWrapper.eq(MaProject::getId, req.getProjectId());
-                updateWrapper.set(MaProject::getProjectIsEnable, 1);
-                maProjectService.update(updateWrapper);
-                message = "申请下架成功";
-            }
-            if (req.getProjectCurrentPrice() != null) {
-
-                LambdaUpdateWrapper<MaProject> updateWrapper = new LambdaUpdateWrapper<>();
-                updateWrapper.eq(MaProject::getId, req.getProjectId());
-                updateWrapper.set(MaProject::getProjectCurrentPrice, req.getProjectCurrentPrice());
-                maProjectService.update(updateWrapper);
-                message = "修改价格完成";
-
-            }
-        }
-        return Result.ok(message);
+    @PreAuthorize("@ss.hasPermi('technician:technician:remove')")
+    @Log(title = "技师", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids) {
+        return toAjax(maTechnicianService.deleteMaTechnicianByIds(ids));
     }
-
 }

+ 1 - 1
nightFragrance-admin/src/main/java/com/ylx/web/controller/massage/WeSqController.java

@@ -180,7 +180,7 @@ public class WeSqController extends BaseController {
                     user.setTeNickName(nickName);
                     user.setTeAvatar(avatarUrl);
                     user.setTePhone(phoneNumber);
-                    user.setOpenService(-1);
+                    user.setOpenService("-1");
                     maTechnicianService.save(user);
                     //异步 添加新人优惠卷
                     //                threadPoolTaskExecutor.submit(() -> couponReceiveService.submit(new CouponReceive().setOpenid(finalUser.getcOpenid()).setCouponId("1")));

+ 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.MassageProjectRecommendVo;
 import com.ylx.massage.domain.vo.MerchantVo;
@@ -79,5 +80,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);
 }

+ 32 - 66
nightFragrance-massage/src/main/java/com/ylx/massage/service/IMaTechnicianService.java

@@ -5,17 +5,14 @@ import java.util.List;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ylx.common.core.domain.model.LoginUser;
-import com.ylx.massage.domain.MaProject;
 import com.ylx.massage.domain.MaTechnician;
-import com.ylx.massage.domain.dto.MaProjectSaveDto;
+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;
-import com.ylx.project.domain.Project;
-import com.ylx.massage.domain.dto.MassageMerchantRecommendDto;
-
 
 /**
  * 技师Service接口
@@ -24,13 +21,6 @@ import com.ylx.massage.domain.dto.MassageMerchantRecommendDto;
  * @date 2024-03-22
  */
 public interface IMaTechnicianService extends IService<MaTechnician> {
-    /**
-     * 商户入驻申请
-     *
-     * @param req 申请参数
-     */
-    void apply(MaTechnicianAppAddVo req);
-
     /**
      * 查询技师
      *
@@ -50,93 +40,69 @@ public interface IMaTechnicianService extends IService<MaTechnician> {
     /**
      * 新增技师
      *
-     * @param maTechnicianAppAddVo
+     * @param maTechnician 技师
      * @return 结果
      */
     public int insertMaTechnician(MaTechnicianAppAddVo maTechnicianAppAddVo);
 
     /**
-     * 修改技师
+     * 后台新增商户
      *
-     * @param
+     * @param dto       新增商户参数
+     * @param loginUser 当前登录用户
      * @return 结果
      */
-    public int updateMaTechnician(MaTechnicianAppAddVo maTechnicianAppAddVo);
+    public int insertMerchant(MaTechnicianMerchantAddDTO dto, LoginUser loginUser);
 
     /**
-     * 批量删除技师
+     * 后台查询商户列表
      *
-     * @param ids 需要删除的技师主键集合
-     * @return 结果
+     * @param page 分页参数
+     * @param dto  查询条件
+     * @return 商户分页列表
      */
-    public int deleteMaTechnicianByIds(Long[] ids);
+    public Page<MaTechnicianMerchantListVO> selectMerchantList(Page<MaTechnicianMerchantListVO> page,
+                                                               MaTechnicianMerchantQueryDTO dto);
 
     /**
-     * 删除技师信息
+     * 后台查询商户详情
      *
-     * @param id 技师主键
-     * @return 结果
+     * @param id 商户ID
+     * @return 商户详情
      */
-    public int deleteMaTechnicianById(Long id);
+    public MaTechnicianMerchantDetailVO selectMerchantDetail(Long id);
 
     /**
-     * 根据商户id查询技师列表
+     * 修改技师
      *
-     * @param userId 商户id
-     * @return 技师列表
+     * @param maTechnician 技师
+     * @return 结果
      */
-    public List<MaProject> selectMaTechnicianListBy(String userId, String type);
+    public int updateMaTechnician(MaTechnicianAppAddVo maTechnicianAppAddVo);
 
     /**
-     * 根据服务类型id查询服务列表
+     * 批量删除技师
      *
-     * @param typeId 服务类型id
-     * @return 服务列表
+     * @param ids 需要删除的技师主键集合
+     * @return 结果
      */
-    public List<Project> selectTechnicianListBy(String typeId);
+    public int deleteMaTechnicianByIds(Long[] ids);
 
     /**
-     * 获取未申请服务列表
+     * 删除技师信息
      *
-     * @param userId
-     * @param typeId
-     * @return
+     * @param id 技师主键
+     * @return 结果
      */
-    List<Project> getNotApplyList(String userId, String typeId);
+    public int deleteMaTechnicianById(Long id);
 
-    /**
-     * 申请服务
-     *
-     * @param dto
-     * @return
-     */
-    int applyForService(MaProjectSaveDto dto);
     /**
      * 首页选中的城市是否有开通服务
+     *
      * @param areaCode
      * @return
      */
-    public  Boolean isHasMerchantCity(String areaCode);
-
-    public List<MerchantVo> getMerchantRecommend(MassageMerchantRecommendDto dto);
-
-    /**
-     * 后台新增商户
-     *
-     * @param dto 新增商户参数
-     * @param loginUser 当前登录用户
-     * @return 结果
-     */
-    public int insertMerchant(MaTechnicianMerchantAddDTO dto, LoginUser loginUser);
-
-    /**
-     * 后台查询商户列表
-     *
-     * @param page 分页参数
-     * @param dto 查询条件
-     * @return 商户分页列表
-     */
-    public Page<MaTechnicianMerchantListVO> selectMerchantList(Page<MaTechnicianMerchantListVO> page,
-                                                               MaTechnicianMerchantQueryDTO dto);
+    Boolean isHasMerchantCity(String areaCode);
 
+    List<MerchantVo> getMerchantRecommend(MassageMerchantRecommendDto dto);
 }

+ 162 - 247
nightFragrance-massage/src/main/java/com/ylx/massage/service/impl/MaTechnicianServiceImpl.java

@@ -1,30 +1,30 @@
 package com.ylx.massage.service.impl;
 
-import java.util.*;
+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.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 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.MaProjectSaveDto;
 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;
-import lombok.Data;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -33,8 +33,6 @@ import com.ylx.massage.domain.MaTechnician;
 import com.ylx.massage.service.IMaTechnicianService;
 import org.springframework.transaction.annotation.Transactional;
 
-import javax.annotation.Resource;
-
 /**
  * 技师Service业务层处理
  *
@@ -43,14 +41,6 @@ import javax.annotation.Resource;
  */
 @Service
 public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaTechnician> implements IMaTechnicianService {
-    @Autowired
-    private MaTechnicianMapper maTechnicianMapper;
-    @Autowired
-    private MaProjectMapper maProjectMapper;
-    @Autowired
-    private ProjectMapper projectMapper;
-    @Resource
-    private MaTeProjectMapper maTeProjectMapper;
     private static final int SERVICE_STATE_AVAILABLE = 1;
     private static final int POST_STATE_OFFLINE = 0;
     private static final int ENABLED = 1;
@@ -60,35 +50,67 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
     private static final int DEFAULT_STAT_VALUE = 0;
     private static final long NOT_DELETED = 0L;
     private static final String MERCHANT_STATUS_NORMAL = "0";
+
+    @Autowired
+    private MaTechnicianMapper maTechnicianMapper;
+
+    @Autowired
+    private MaTeProjectMapper maTeProjectMapper;
+
+    @Autowired
+    private ProjectMapper projectMapper;
+
+    /**
+     * 查询技师
+     *
+     * @param id 技师主键
+     * @return 技师
+     */
+    @Override
+    public MaTechnician selectMaTechnicianById(Long id) {
+        return maTechnicianMapper.selectMaTechnicianById(id);
+    }
+
     /**
-     * 商户入驻申请注册
+     * 查询技师列表
      *
-     * @param req 申请参数
+     * @param maTechnician 技师
+     * @return 技师
+     */
+    @Override
+    public List<MaTechnician> selectMaTechnicianList(MaTechnician maTechnician) {
+        return maTechnicianMapper.selectMaTechnicianList(maTechnician);
+    }
+
+    /**
+     * 新增技师
+     *
+     * @param maTechnicianAppAddVo 技师
+     * @return 结果
      */
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void apply(MaTechnicianAppAddVo req) {
-        String phone = req.getTePhone();
-        //商户入住前置条件校验
-        getMaTechnician(req, phone);
+    public int insertMaTechnician(MaTechnicianAppAddVo maTechnicianAppAddVo) {
         MaTechnician maTechnician = new MaTechnician();
-        BeanUtils.copyProperties(req, maTechnician);
-        //技师类型默认为真实商户
-        maTechnician.setTechType(0);
-        maTechnicianMapper.insert(maTechnician);
-
+        BeanUtils.copyProperties(maTechnicianAppAddVo, maTechnician);
+        int rows = maTechnicianMapper.insertMaTechnician(maTechnician);
+        if (maTechnicianAppAddVo.getProjectIds() != null && !maTechnicianAppAddVo.getProjectIds().isEmpty()) {
+            insertProjectRelations(maTechnician.getId(), new LinkedHashSet<>(maTechnicianAppAddVo.getProjectIds()));
+        }
+        return rows;
     }
+
     /**
      * 后台新增商户
      *
-     * @param dto 新增商户参数
+     * @param dto       新增商户参数
      * @param loginUser 当前登录用户
      * @return 结果
      */
     @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();
@@ -96,15 +118,8 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
         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(), "是否推荐"));
@@ -129,7 +144,7 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
         if (rows <= 0) {
             throw new ServiceException("新增商户失败");
         }
-        insertProjectRelations(maTechnician.getId(), projectIds);
+        insertProjectRelations(maTechnician.getId(), selection.getProjectIds());
         return rows;
     }
 
@@ -137,7 +152,7 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
      * 后台查询商户列表
      *
      * @param page 分页参数
-     * @param dto 查询条件
+     * @param dto  查询条件
      * @return 商户分页列表
      */
     @Override
@@ -146,102 +161,23 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
         Page<MaTechnicianMerchantListVO> pageParam = page == null ? new Page<>(1, 10) : page;
         return maTechnicianMapper.selectMerchantList(pageParam, dto);
     }
-    /**
-     * 商户入住前置条件校验
-     *
-     * @param req
-     * @param phone
-     */
-    private void getMaTechnician(MaTechnicianAppAddVo req, String phone) {
-        // 1. 判断当前用户是否已入驻
-        MaTechnician userProfile = getMaTechnician(req);
-        if (userProfile != null) {
-            throw new RuntimeException("当前用户已入驻,请勿重复提交");
-        }
-
-        // 2. 判断手机号是否已存在
-        LambdaQueryWrapper<MaTechnician> queryPhoneWrapper = new LambdaQueryWrapper<>();
-        queryPhoneWrapper.eq(MaTechnician::getTePhone, phone);
-        queryPhoneWrapper.eq(MaTechnician::getIsDelete, 0);
-        MaTechnician maTechnicianPhone = maTechnicianMapper.selectOne(queryPhoneWrapper);
-        if (maTechnicianPhone != null) {
-            throw new RuntimeException("手机号已存在,请更换手机号");
-        }
-        //3、判断手机号是否已绑定其他用户
-        LambdaQueryWrapper<MaTechnician> queryTePhoneWrapper = new LambdaQueryWrapper<>();
-        queryTePhoneWrapper.eq(MaTechnician::getTePhone, phone);
-        queryTePhoneWrapper.eq(MaTechnician::getIsDelete, 0);
-        queryTePhoneWrapper.eq(MaTechnician::getAuditStatus, 2);
-        MaTechnician maTechnicianTePhone = maTechnicianMapper.selectOne(queryTePhoneWrapper);
-        if (maTechnicianPhone != null) {
-            throw new RuntimeException("手机号已被其他用户绑定,请更换手机号");
-        }
-
-    }
 
     /**
-     * 判断当前用户是否已入驻
+     * 后台查询商户详情
      *
-     * @return
-     */
-    private MaTechnician getMaTechnician(MaTechnicianAppAddVo req) {
-        LambdaQueryWrapper<MaTechnician> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(MaTechnician::getTePhone, req.getTePhone());
-        queryWrapper.eq(MaTechnician::getIsDelete, 0);
-        queryWrapper.eq(MaTechnician::getAuditStatus, 2);
-        queryWrapper.eq(MaTechnician::getOpenService, req.getOpenService());
-        MaTechnician userProfile = maTechnicianMapper.selectOne(queryWrapper);
-        return userProfile;
-    }
-
-    /**
-     * 查询技师
-     *
-     * @param id 技师主键
-     * @return 技师
-     */
-    @Override
-    public MaTechnician selectMaTechnicianById(Long id) {
-        return maTechnicianMapper.selectMaTechnicianById(id);
-    }
-
-    /**
-     * 查询技师列表
-     *
-     * @param maTechnician 技师
-     * @return 技师
+     * @param id 商户ID
+     * @return 商户详情
      */
     @Override
-    public List<MaTechnician> selectMaTechnicianList(MaTechnician maTechnician) {
-        return maTechnicianMapper.selectMaTechnicianList(maTechnician);
-    }
-
-    /**
-     * 新增技师
-     *
-     * @param maTechnicianAppAddVo 技师
-     * @return 结果
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public int insertMaTechnician(MaTechnicianAppAddVo maTechnicianAppAddVo) {
-
-        MaTechnician maTechnician = new MaTechnician();
-        BeanUtils.copyProperties(maTechnicianAppAddVo, maTechnician);
-        int i = maTechnicianMapper.insert(maTechnician);
-        // maTechnicianMapper.insertMaTechnician(maTechnician);
-        if (!maTechnicianAppAddVo.getProjectIds().isEmpty()) {
-//            ArrayList<MaTeProject> objects = Lists.newArrayList();
-//            ArrayList<Long> projectIds = maTechnicianAppAddVo.getProjectIds();
-//            projectIds.forEach(id->{
-//                MaTeProject maTeProject = new MaTeProject();
-//                maTeProject.setTeId(maTechnician.getId());
-//                maTeProject.setProjectId(id);
-//                objects.add(maTeProject);
-//            });
-//            i = maTeProjectMapper.insertBatch(objects);
+    public MaTechnicianMerchantDetailVO selectMerchantDetail(Long id) {
+        if (id == null) {
+            throw new ServiceException("商户ID不能为空");
+        }
+        MaTechnicianMerchantDetailVO detail = maTechnicianMapper.selectMerchantDetailById(id);
+        if (detail == null) {
+            throw new ServiceException("商户不存在或已删除");
         }
-        return i;
+        return detail;
     }
 
     /**
@@ -256,7 +192,7 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
         MaTechnician maTechnician = new MaTechnician();
         BeanUtils.copyProperties(maTechnicianAppAddVo, maTechnician);
 
-        return maTechnicianMapper.updateById(maTechnician);
+        return maTechnicianMapper.updateMaTechnician(maTechnician);
     }
 
     /**
@@ -282,99 +218,30 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
     }
 
     /**
-     * 查询商户技能
+     * 首页选中的城市是否有开通服务
      *
-     * @param userId
+     * @param areaCode
      * @return
      */
     @Override
-    public List<MaProject> selectMaTechnicianListBy(String userId, String type) {
-        LambdaQueryWrapper<MaProject> query = new LambdaQueryWrapper<>();
-        query.eq(MaProject::getUserId, userId);
-        query.eq(MaProject::getAuditStatus, type);
-        return maProjectMapper.selectList(query);
-
+    public Boolean isHasMerchantCity(String areaCode) {
+        LambdaQueryWrapper<MaTechnician> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(MaTechnician::getTeAreaCode, areaCode);
+        return maTechnicianMapper.selectCount(queryWrapper) > 0;
     }
 
     /**
-     * 查询技能
+     * 首页按摩推荐
      *
-     * @param typeId
-     * @return
-     */
-    @Override
-    public List<Project> selectTechnicianListBy(String typeId) {
-        LambdaQueryWrapper<Project> query = new LambdaQueryWrapper<>();
-        query.eq(Project::getType, typeId);
-        query.eq(Project::getStatus, 0);
-        List<Project> projectList = projectMapper.selectList(query);
-        return projectList;
-
-    }
-    /**
-     * 获取未申请技能列表
-     * @param userId
-     * @param typeId
-     * @return
-     */
-    @Override
-    public List<Project> getNotApplyList(String userId, String typeId){
-        LambdaQueryWrapper<MaProject> query = new LambdaQueryWrapper<>();
-        query.eq(MaProject::getUserId, userId);
-        query.eq(MaProject::getMerchantType, typeId);
-        List<MaProject> maProjectList = maProjectMapper.selectList(query);
-        // 获取已申请技能ID集合
-        List<String> projectIdList = maProjectList.stream().map(MaProject::getProjectId).collect(Collectors.toList());
-        LambdaQueryWrapper<Project> query1 = new LambdaQueryWrapper<>();
-        query1.eq(Project::getType, typeId);
-        query1.notIn(Project::getId, projectIdList);
-        return projectMapper.selectList(query1);
-    }
-    /**
-     * 申请开通服务
      * @param dto
      * @return
      */
     @Override
-    @Transactional(rollbackFor = Exception.class)
-    public int applyForService(MaProjectSaveDto dto) {
-        if (Objects.isNull(dto)) {
-            return 0;
-        }
-        if (dto.getProjectIdList().size() > 0) {
-            // 插入商户技能
-            extracted(dto);
-        }else{
-            return 0;
-        }
-        return 1;
+    public List<MerchantVo> getMerchantRecommend(MassageMerchantRecommendDto dto) {
+        return maTechnicianMapper.getMerchantRecommend(dto);
     }
 
-    /**
-     * 插入商户技能
-     * @param dto
-     */
-    private void extracted(MaProjectSaveDto dto) {
-        LambdaQueryWrapper<Project> query = new LambdaQueryWrapper<>();
-        query.in(Project::getId, dto.getProjectIdList());
-        List<Project> projectList = projectMapper.selectList(query);
-        for (Project project : projectList) {
-            MaProject maProject = new MaProject();
-            maProject.setProjectId(project.getId().toString());
-            maProject.setProjectName(project.getTitle());
-            maProject.setProjectDescribe(project.getDetail());
-            maProject.setProjectDuration(project.getStandardDuration());
-            maProject.setProjectOriginalPrice(project.getPrice());
-            maProject.setProjectMaxPrice(project.getPriceMax());
-            maProject.setProjectLowestPrice(project.getPriceMin());
-            maProject.setCreateBy(dto.getUserId());
-            maProject.setUserId(dto.getUserId());
-            maProject.setApplyTime((Data) new Date());
-            maProject.setMerchantPhone(dto.getMerchantPhone());
-            maProjectMapper.insert(maProject);
-        }
-    }
-    private Set<Long> checkMerchantAddParam(MaTechnicianMerchantAddDTO dto) {
+    private MerchantProjectSelection checkMerchantAddParam(MaTechnicianMerchantAddDTO dto) {
         if (dto == null) {
             throw new ServiceException("商户参数不能为空");
         }
@@ -382,16 +249,12 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
         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) {
@@ -425,10 +288,12 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
 
     /**
      * 校验服务项目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("服务项目不能为空");
         }
@@ -441,17 +306,64 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
             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.getCategoryId() == null) {
+                throw new ServiceException("服务项目类目不能为空");
+            }
+            if (!categoryIds.contains(project.getCategoryId())) {
+                throw new ServiceException("服务项目不属于所选服务类目");
             }
+            projectCategoryIds.add(project.getCategoryId());
         }
-        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(","));
     }
 
     /**
@@ -477,25 +389,28 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
             throw new ServiceException("新增商户服务项目失败");
         }
     }
-    /**
-     * 首页选中的城市是否有开通服务
-     * @param areaCode
-     * @return
-     */
-    @Override
-    public Boolean isHasMerchantCity(String areaCode) {
-        LambdaQueryWrapper<MaTechnician> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(MaTechnician::getTeAreaCode, areaCode);
-        return maTechnicianMapper.selectCount(queryWrapper) > 0;
-    }
 
-    /**
-     * 首页按摩推荐
-     * @param dto
-     * @return
-     */
-    @Override
-    public List<MerchantVo> getMerchantRecommend(MassageMerchantRecommendDto dto) {
-        return maTechnicianMapper.getMerchantRecommend(dto);
+    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;
+        }
     }
 }

+ 2 - 2
nightFragrance-massage/src/main/java/com/ylx/project/domain/Project.java

@@ -22,7 +22,7 @@ public class Project extends BaseEntity {
      */
     @ApiModelProperty("id")
     @TableId(value = "id", type = IdType.AUTO)
-    private Long id;
+    private Integer id;
 
     /**
      * 服务标签
@@ -34,7 +34,7 @@ public class Project extends BaseEntity {
      * 服务类目ID
      */
     @ApiModelProperty("服务类目ID")
-    private Long categoryId;
+    private Integer categoryId;
 
     /**
      * 标题。

+ 69 - 3
nightFragrance-massage/src/main/resources/mapper/massage/MaTechnicianMapper.xml

@@ -33,8 +33,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="techType"    column="tech_type"    />
         <result property="teIsEnable"    column="te_is_enable"    />
         <result property="auditStatus"    column="audit_status"    />
-        <result property="createUser"    column="create_user"    />
-        <result property="updateUser"    column="update_user"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="updateBy"    column="update_by"    />
         <result property="createTime"    column="create_time"    />
         <result property="updateTime"    column="update_time"    />
         <result property="isDelete"    column="is_delete"    />
@@ -215,6 +215,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,
@@ -276,7 +293,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 != ''">
@@ -311,6 +328,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