Преглед изворни кода

广誉源商户端-登录-我的技能,城市管理,状态切换,我的资料

jinwenhai пре 2 дана
родитељ
комит
31be37ab25
17 измењених фајлова са 809 додато и 479 уклоњено
  1. 521 441
      nightFragrance-admin/src/main/java/com/ylx/web/controller/massage/MaTechnicianController.java
  2. 1 0
      nightFragrance-admin/src/main/java/com/ylx/web/controller/massage/WeChatController.java
  3. 6 5
      nightFragrance-admin/src/main/java/com/ylx/web/controller/massage/WeSqController.java
  4. 9 8
      nightFragrance-admin/src/main/java/com/ylx/web/controller/system/SysDictDataController.java
  5. 1 1
      nightFragrance-common/src/main/java/com/ylx/common/core/domain/model/aliyun/SendSmsEnum.java
  6. 2 1
      nightFragrance-framework/src/main/java/com/ylx/framework/config/SecurityConfig.java
  7. 5 0
      nightFragrance-massage/src/main/java/com/ylx/massage/domain/MerchantApplyFile.java
  8. 13 0
      nightFragrance-massage/src/main/java/com/ylx/massage/domain/dto/AcceptOrderReqDTO.java
  9. 10 0
      nightFragrance-massage/src/main/java/com/ylx/massage/domain/dto/MerchantApplyFileRequestDto.java
  10. 13 0
      nightFragrance-massage/src/main/java/com/ylx/massage/domain/dto/ValidateCaptchaDto.java
  11. 23 0
      nightFragrance-massage/src/main/java/com/ylx/massage/domain/dto/WaitOrderDTO.java
  12. 12 0
      nightFragrance-massage/src/main/java/com/ylx/massage/domain/dto/WaitOrderQueryDTO.java
  13. 15 12
      nightFragrance-massage/src/main/java/com/ylx/massage/domain/vo/MaTechnicianAppAddVo.java
  14. 2 1
      nightFragrance-massage/src/main/java/com/ylx/massage/domain/vo/ThirdPartyLoginsVo.java
  15. 16 1
      nightFragrance-massage/src/main/java/com/ylx/massage/service/IMaTechnicianService.java
  16. 159 8
      nightFragrance-massage/src/main/java/com/ylx/massage/service/impl/MaTechnicianServiceImpl.java
  17. 1 1
      nightFragrance-massage/src/main/java/com/ylx/massage/utils/WeChatUtil.java

+ 521 - 441
nightFragrance-admin/src/main/java/com/ylx/web/controller/massage/MaTechnicianController.java

@@ -1,64 +1,64 @@
 package com.ylx.web.controller.massage;
 
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Objects;
-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 cn.hutool.json.JSONObject;
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ylx.common.annotation.Log;
+import com.ylx.common.constant.CacheConstants;
+import com.ylx.common.constant.Constants;
+import com.ylx.common.core.controller.BaseController;
+import com.ylx.common.core.domain.AjaxResult;
 import com.ylx.common.core.domain.R;
 import com.ylx.common.core.domain.model.LoginUser;
 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.core.page.TableDataInfo;
+import com.ylx.common.core.redis.RedisCache;
+import com.ylx.common.enums.BusinessType;
+import com.ylx.common.exception.user.CaptchaException;
+import com.ylx.common.exception.user.CaptchaExpireException;
+import com.ylx.common.utils.MessageUtils;
 import com.ylx.common.utils.StringUtils;
+import com.ylx.common.utils.poi.ExcelUtil;
+import com.ylx.framework.manager.AsyncManager;
+import com.ylx.framework.manager.factory.AsyncFactory;
 import com.ylx.massage.domain.MaProject;
+import com.ylx.massage.domain.MaTechnician;
 import com.ylx.massage.domain.dto.*;
-import com.ylx.massage.domain.dto.MaProjectSaveDto;
-import com.ylx.massage.domain.dto.MaProjectUpdateDto;
-import com.ylx.massage.domain.dto.MaTechnicianAuditQueryDTO;
-import com.ylx.massage.domain.dto.MaTechnicianAuditSubmitDTO;
-import com.ylx.massage.domain.dto.MaTechnicianMerchantAddDTO;
-import com.ylx.massage.domain.dto.MaTechnicianMerchantQueryDTO;
-import com.ylx.massage.domain.dto.MaTechnicianPendingAuditSubmitDTO;
 import com.ylx.massage.domain.vo.*;
 import com.ylx.massage.service.IMaProjectService;
+import com.ylx.massage.service.IMaTechnicianService;
 import com.ylx.project.domain.Project;
 import com.ylx.servicecategory.domain.ServiceCategory;
 import com.ylx.servicecategory.service.ServiceCategoryService;
-import io.swagger.annotations.Api;
+import com.ylx.system.service.ISysConfigService;
 import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.ObjectUtils;
 import org.springframework.web.bind.annotation.*;
-import com.ylx.common.annotation.Log;
-import com.ylx.common.core.controller.BaseController;
-import com.ylx.common.core.domain.AjaxResult;
-import com.ylx.common.enums.BusinessType;
-import com.ylx.massage.domain.MaTechnician;
-import com.ylx.massage.service.IMaTechnicianService;
-import com.ylx.common.utils.poi.ExcelUtil;
-import com.ylx.common.core.page.TableDataInfo;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+import java.util.Objects;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
+
 /**
  * 技师Controller
  *
  * @author ylx
  * @date 2024-03-22
  */
-@Api("技师管理")
 @RestController
 @RequestMapping("/technician/technician")
 public class MaTechnicianController extends BaseController {
@@ -74,8 +74,13 @@ public class MaTechnicianController extends BaseController {
     private ServiceCategoryService serviceCategoryService;
     @Autowired
     private IMaProjectService maProjectService;
+    @Autowired
+    private ISysConfigService configService;
+    @Autowired
+    private RedisCache redisCache;
 
-    public static final String PHONE_THREEUSERPARTCLIENT_CODE_KEY = "sys:threeUserPartClient:phone:";
+
+    public static final String PHONE_THREEUSERPARTCLIENT_CODE_KEY = "sys:clientLogin:phone:";
 
     @GetMapping("/sendMsg")
     @ApiOperation(value = "短信发送", notes = "短信发送")
@@ -98,7 +103,7 @@ public class MaTechnicianController extends BaseController {
         } catch (Exception e) {
             e.printStackTrace();
         }
-        return Result.ok("发送失败");
+        return Result.ok("发送成功");
     }
 
     /**
@@ -140,470 +145,545 @@ public class MaTechnicianController extends BaseController {
                 return Result.error("短信验证码不正确");
             }
         } else {
-            if (!thirdPartyLoginsVo.getPassWord().equals(maTechnician.getTePassword())) {
-                return Result.error("密码错误");
+            // 初始化加密工具
+            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
+            // 验证:比对是否匹配
+            boolean isOk = encoder.matches(thirdPartyLoginsVo.getPassWord(),maTechnician.getTePassword());
+                if (!isOk) {
+                    return Result.error("密码错误");
+                }
+
+
             }
 
+            // 登录成功删除验证码
+            redisTemplate.delete(PHONE_THREEUSERPARTCLIENT_CODE_KEY + thirdPartyLoginsVo.getPhone());
+            result.success("登录成功");
+            return result;
         }
 
-        // 登录成功删除验证码
-        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("/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.getPassWord().trim());
+            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 (msg != null && msg.startsWith("\"") && msg.endsWith("\"")) {
+                msg = msg.substring(1, msg.length() - 1);
+            }
+            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.getAvatar())) {
-            return Result.error("必填项不能为空");
-        }
-        //校验性别不能为空
-        if(Objects.isNull(req.getTeSex())){
-            return Result.error("性别不能为空");
-        }
-        // 2. 调用业务层处理入驻申请
-        maTechnicianService.apply(req);
-        return Result.ok("提交成功,进入审核流程");
-    }
-    /**
-     * 申请技师文件
-     * @param req
-     */
-    @PostMapping("/applyFile")
-    public  Result applyFile(MerchantApplyFileDto req){
-        maTechnicianService.applyFile(req);
-        return Result.ok("上传成功");
-    }
-    /**
-     * 技师状态切换
-     *
-     * @param
-     */
-    @GetMapping("/switchToOffline")
-    public Result switchToOffline(@RequestParam Long userId, @RequestParam Boolean forceConfirm){
-        return maTechnicianService.switchToOffline(userId, forceConfirm);
-    }
-    /**
-     * 查询商户信息接口
-     */
-    @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("/getValidateCaptcha")
+        public Result<?> getValidateCaptcha (@RequestBody ValidateCaptchaDto req){
+            validateCaptcha(req.getPhone(), req.getCode(), req.getUuid());
+            return Result.ok("校验成功");
+        }
+        /**
+         * 商户入驻申请接口
+         */
+        @PostMapping("/apply")
+        public Result<?> apply (@RequestBody MaTechnicianAppAddVo req){
+            // 1. 基础参数校验
+            if (StringUtils.isAnyBlank(req.getTeName(), req.getTePhone(), req.getTeAddress(), req.getAvatar())) {
+                return Result.error("必填项不能为空");
+            }
+            //校验性别不能为空
+            if (Objects.isNull(req.getTeSex())) {
+                return Result.error("性别不能为空");
+            }
+            // 短信验证
+            String msg = redisTemplate.opsForValue().get(PHONE_THREEUSERPARTCLIENT_CODE_KEY + req.getTePhone());
+//            if (StringUtils.isEmpty(msg)) {
+//                return Result.error("验证码已失效");
+//            }
+//            if (msg != null && msg.startsWith("\"") && msg.endsWith("\"")) {
+//                msg = msg.substring(1, msg.length() - 1);
+//            }
+//            if (!req.getPhoneMsg().equals(msg)) {
+//                return Result.error("短信验证码不正确");
+//            }
+            if (StringUtils.isNotEmpty(req.getPhoneImgMsg())) {
+                validateCaptcha(req.getTeName(), req.getPhoneImgMsg(), req.getUuid());
+            }
+            // 2. 调用业务层处理入驻申请
+            maTechnicianService.apply(req);
+            return Result.ok("提交成功,进入审核流程");
+        }
+        /**
+         * 校验验证码
+         *
+         * @param username 用户名
+         * @param code     验证码
+         * @param uuid     唯一标识
+         * @return 结果
+         */
+        public void validateCaptcha (String username, String code, String uuid){
+            boolean captchaEnabled = configService.selectCaptchaEnabled();
+            if (captchaEnabled) {
+                String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
+                String captcha = redisCache.getCacheObject(verifyKey);
+                redisCache.deleteObject(verifyKey);
+                if (captcha == null) {
+                    AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
+                    throw new CaptchaExpireException();
+                }
+                if (!code.equalsIgnoreCase(captcha)) {
+                    AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
+                    throw new CaptchaException();
+                }
+            }
+        }
 
-    /**
-     * 修改和上传商户信息接口
-     */
-    @PostMapping("/updateTechnician")
-    public Result<?> updateTechnician(@RequestBody MaTechnicianAppAddVo req) {
-        if (req.getAuditStatus() == 0 || req.getAuditStatus() == 3) {
-            //修改基本信息
-            updateMaTechnician(req);
+        /**
+         * 申请技师文件
+         * @param req
+         */
+        @PostMapping("/applyFile")
+        public Result applyFile (@RequestBody MerchantApplyFileRequestDto req) {
+            maTechnicianService.applyFile(req);
+            return Result.ok("上传成功");
+        }
+        /**
+         * 获取待接单列表:前端传技师实时经纬度筛选订单
+         */
+        @GetMapping("/wait/list")
+        public Result<List<WaitOrderDTO>> getWaitOrder (WaitOrderQueryDTO query){
+            List<WaitOrderDTO> list = maTechnicianService.listWaitOrder(query);
+            return Result.ok(list);
         }
-        return Result.ok("修改成功");
-    }
 
+        /**
+         * 技师状态切换
+         *
+         * @param
+         */
+        @GetMapping("/switchToOffline")
+        public Result switchToOffline (@RequestParam Long userId, @RequestParam Boolean forceConfirm){
+            return maTechnicianService.switchToOffline(userId, forceConfirm);
+        }
+        /**
+         * 查询商户信息接口
+         */
+        @GetMapping("/getTechnician")
+        public Result<?> getTechnician (@RequestParam String openid){
+            LambdaQueryWrapper<MaTechnician> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(MaTechnician::getCOpenid, openid);
+            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);
+            }
+            return Result.ok("修改成功");
+        }
 
-    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);
-    }
 
-    /**
-     * 查询技师列表
-     */
-    @PreAuthorize("@ss.hasPermi('technician:technician:list')")
-    @GetMapping("/list")
-    public TableDataInfo list(MaTechnician maTechnician) {
-        startPage();
-        List<MaTechnician> list = maTechnicianService.selectMaTechnicianList(maTechnician);
-        return getDataTable(list);
-    }
+        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.getServiceTag());
+            updateWrapper.set(MaTechnician::getTeAddress, req.getTeAddress());
+            updateWrapper.set(MaTechnician::getTeAge, req.getTeAge());
+            updateWrapper.set(MaTechnician::getAvatar, req.getAvatar());
+            updateWrapper.set(MaTechnician::getTeBrief, req.getTeBrief());
+            maTechnicianService.update(updateWrapper);
+        }
 
-    /**
-     * 导出技师列表
-     */
-    @PreAuthorize("@ss.hasPermi('technician:technician:export')")
-    @Log(title = "技师", businessType = BusinessType.EXPORT)
-    @PostMapping("/export")
-    public void export(HttpServletResponse response, MaTechnician maTechnician) {
-        List<MaTechnician> list = maTechnicianService.selectMaTechnicianList(maTechnician);
-        ExcelUtil<MaTechnician> util = new ExcelUtil<MaTechnician>(MaTechnician.class);
-        util.exportExcel(response, list, "技师数据");
-    }
+        /**
+         * 查询技师列表
+         */
+        @PreAuthorize("@ss.hasPermi('technician:technician:list')")
+        @GetMapping("/list")
+        public TableDataInfo list (MaTechnician maTechnician){
+            startPage();
+            List<MaTechnician> list = maTechnicianService.selectMaTechnicianList(maTechnician);
+            return getDataTable(list);
+        }
 
-    /**
-     * 获取技师详细信息
-     */
-    @PreAuthorize("@ss.hasPermi('technician:technician:query')")
-    @GetMapping(value = "/{id}")
-    public AjaxResult getInfo(@PathVariable("id") Long id) {
-        return success(maTechnicianService.selectMaTechnicianById(id));
-    }
+        /**
+         * 导出技师列表
+         */
+        @PreAuthorize("@ss.hasPermi('technician:technician:export')")
+        @Log(title = "技师", businessType = BusinessType.EXPORT)
+        @PostMapping("/export")
+        public void export (HttpServletResponse response, MaTechnician maTechnician){
+            List<MaTechnician> list = maTechnicianService.selectMaTechnicianList(maTechnician);
+            ExcelUtil<MaTechnician> util = new ExcelUtil<MaTechnician>(MaTechnician.class);
+            util.exportExcel(response, list, "技师数据");
+        }
 
-    /**
-     * 新增技师
-     */
-    @ApiOperation("技师入驻")
-    @PreAuthorize("@ss.hasPermi('technician:technician:add')")
-    @Log(title = "技师", businessType = BusinessType.INSERT)
-    @PostMapping
-    public AjaxResult add(@RequestBody MaTechnicianAppAddVo maTechnicianAppAddVo) {
-        return toAjax(maTechnicianService.insertMaTechnician(maTechnicianAppAddVo));
-    }
+        /**
+         * 获取技师详细信息
+         */
+        @PreAuthorize("@ss.hasPermi('technician:technician:query')")
+        @GetMapping(value = "/{id}")
+        public AjaxResult getInfo (@PathVariable("id") Long id){
+            return success(maTechnicianService.selectMaTechnicianById(id));
+        }
 
-    /**
-     * 后台新增商户
-     *
-     * @param dto 商户新增DTO
-     * @return AjaxResult 结果
-     */
-    @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);
+        /**
+         * 新增技师
+         */
+        @ApiOperation("技师入驻")
+        @PreAuthorize("@ss.hasPermi('technician:technician:add')")
+        @Log(title = "技师", businessType = BusinessType.INSERT)
+        @PostMapping
+        public AjaxResult add (@RequestBody MaTechnicianAppAddVo maTechnicianAppAddVo){
+            return toAjax(maTechnicianService.insertMaTechnician(maTechnicianAppAddVo));
         }
-    }
 
-    /**
-     * 后台编辑商户
-     *
-     * @param id  商户ID
-     * @param dto 商户编辑DTO
-     * @return AjaxResult 结果
-     */
-    @ApiOperation("后台编辑商户")
-    @PreAuthorize("@ss.hasPermi('technician:technician:edit')")
-    @Log(title = "商户", businessType = BusinessType.UPDATE)
-    @PutMapping("/merchant/{id}")
-    public AjaxResult editMerchant(@PathVariable("id") Integer id, @RequestBody MaTechnicianMerchantAddDTO dto) {
-        try {
-            LoginUser loginUser = getLoginUser();
-            return toAjax(maTechnicianService.updateMerchant(id, dto, loginUser));
-        } catch (Exception e) {
-            e.printStackTrace();
-            throw new RuntimeException(e);
+        /**
+         * 后台新增商户
+         *
+         * @param dto 商户新增DTO
+         * @return AjaxResult 结果
+         */
+        @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 id   商户ID
-     * @param file 合同文件
-     * @return AjaxResult 上传结果
-     */
-    @ApiOperation("后台上传商户合同文件")
-    @PreAuthorize("@ss.hasPermi('technician:technician:edit')")
-    @Log(title = "商户合同", businessType = BusinessType.UPDATE)
-    @PostMapping("/merchant/{id}/contract")
-    public AjaxResult uploadMerchantContract(@PathVariable("id") Integer id, @RequestParam("file") MultipartFile file) {
-        try {
-            LoginUser loginUser = getLoginUser();
-            return maTechnicianService.uploadMerchantContract(id, file, loginUser);
-        } catch (Exception e) {
-            e.printStackTrace();
-            throw new RuntimeException(e);
+        /**
+         * 后台编辑商户
+         *
+         * @param id  商户ID
+         * @param dto 商户编辑DTO
+         * @return AjaxResult 结果
+         */
+        @ApiOperation("后台编辑商户")
+        @PreAuthorize("@ss.hasPermi('technician:technician:edit')")
+        @Log(title = "商户", businessType = BusinessType.UPDATE)
+        @PutMapping("/merchant/{id}")
+        public AjaxResult editMerchant (@PathVariable("id") Integer id, @RequestBody MaTechnicianMerchantAddDTO dto){
+            try {
+                LoginUser loginUser = getLoginUser();
+                return toAjax(maTechnicianService.updateMerchant(id, dto, loginUser));
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new RuntimeException(e);
+            }
         }
-    }
 
-    /**
-     * 查询商户入驻审核列表
-     *
-     * @param page 分页参数
-     * @param dto  查询条件
-     * @return Page 商户入驻审核分页列表
-     */
-    @ApiOperation("后台查询商户入驻审核列表")
-    @PreAuthorize("@ss.hasPermi('technician:technician:list')")
-    @GetMapping("/merchant/audit/list")
-    public R<Page<MaTechnicianAuditListVO>> merchantAuditList(Page<MaTechnicianAuditListVO> page, MaTechnicianAuditQueryDTO dto) {
-        try {
-            return R.ok(maTechnicianService.selectMerchantAuditList(page, dto));
-        } catch (Exception e) {
-            e.printStackTrace();
-            throw new RuntimeException(e);
+        /**
+         * 后台上传商户合同文件
+         *
+         * @param id   商户ID
+         * @param file 合同文件
+         * @return AjaxResult 上传结果
+         */
+        @ApiOperation("后台上传商户合同文件")
+        @PreAuthorize("@ss.hasPermi('technician:technician:edit')")
+        @Log(title = "商户合同", businessType = BusinessType.UPDATE)
+        @PostMapping("/merchant/{id}/contract")
+        public AjaxResult uploadMerchantContract (@PathVariable("id") Integer id, @RequestParam("file") MultipartFile
+        file){
+            try {
+                LoginUser loginUser = getLoginUser();
+                return maTechnicianService.uploadMerchantContract(id, file, loginUser);
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new RuntimeException(e);
+            }
         }
-    }
 
-    /**
-     * 商户入驻审核
-     *
-     * @param id  商户ID
-     * @param dto 审核提交参数
-     * @return AjaxResult 结果
-     */
-    @ApiOperation("商户入驻审核")
-    @PreAuthorize("@ss.hasPermi('technician:technician:edit')")
-    @Log(title = "商户入驻审核", businessType = BusinessType.UPDATE)
-    @PutMapping("/merchant/audit/{id}/submit")
-    public AjaxResult submitMerchantAudit(@PathVariable("id") Integer id, @RequestBody MaTechnicianAuditSubmitDTO dto) {
-        try {
-            LoginUser loginUser = getLoginUser();
-            return toAjax(maTechnicianService.submitMerchantAudit(id, dto, loginUser));
-        } catch (Exception e) {
-            e.printStackTrace();
-            throw new RuntimeException(e);
+        /**
+         * 查询商户入驻审核列表
+         *
+         * @param page 分页参数
+         * @param dto  查询条件
+         * @return Page 商户入驻审核分页列表
+         */
+        @ApiOperation("后台查询商户入驻审核列表")
+        @PreAuthorize("@ss.hasPermi('technician:technician:list')")
+        @GetMapping("/merchant/audit/list")
+        public R<Page<MaTechnicianAuditListVO>> merchantAuditList
+        (Page < MaTechnicianAuditListVO > page, MaTechnicianAuditQueryDTO dto){
+            try {
+                return R.ok(maTechnicianService.selectMerchantAuditList(page, dto));
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new RuntimeException(e);
+            }
         }
-    }
 
-    /**
-     * 待审核页面审核通过商户
-     *
-     * @param id  商户ID
-     * @param dto 待审核通过参数
-     * @return AjaxResult 结果
-     */
-    @ApiOperation("待审核页面审核通过商户")
-    @PreAuthorize("@ss.hasPermi('technician:technician:edit')")
-    @Log(title = "商户待审核通过", businessType = BusinessType.UPDATE)
-    @PutMapping("/merchant/audit/{id}/approve")
-    public AjaxResult approvePendingMerchantAudit(@PathVariable("id") Integer id,
-                                                  @RequestBody MaTechnicianPendingAuditSubmitDTO dto) {
-        try {
-            LoginUser loginUser = getLoginUser();
-            return toAjax(maTechnicianService.approvePendingMerchantAudit(id, dto, loginUser));
-        } catch (Exception e) {
-            e.printStackTrace();
-            throw new RuntimeException(e);
+        /**
+         * 商户入驻审核
+         *
+         * @param id  商户ID
+         * @param dto 审核提交参数
+         * @return AjaxResult 结果
+         */
+        @ApiOperation("商户入驻审核")
+        @PreAuthorize("@ss.hasPermi('technician:technician:edit')")
+        @Log(title = "商户入驻审核", businessType = BusinessType.UPDATE)
+        @PutMapping("/merchant/audit/{id}/submit")
+        public AjaxResult submitMerchantAudit (@PathVariable("id") Integer id, @RequestBody MaTechnicianAuditSubmitDTO
+        dto){
+            try {
+                LoginUser loginUser = getLoginUser();
+                return toAjax(maTechnicianService.submitMerchantAudit(id, dto, loginUser));
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new RuntimeException(e);
+            }
         }
-    }
 
-    /**
-     * 查询商户列表
-     *
-     * @param page 分页参数
-     * @param dto  商户查询DTO
-     * @return Page 商户分页列表
-     */
-    @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
+         * @param dto 待审核通过参数
+         * @return AjaxResult 结果
+         */
+        @ApiOperation("待审核页面审核通过商户")
+        @PreAuthorize("@ss.hasPermi('technician:technician:edit')")
+        @Log(title = "商户待审核通过", businessType = BusinessType.UPDATE)
+        @PutMapping("/merchant/audit/{id}/approve")
+        public AjaxResult approvePendingMerchantAudit (@PathVariable("id") Integer id,
+                                                                                           @RequestBody MaTechnicianPendingAuditSubmitDTO
+        dto){
+            try {
+                LoginUser loginUser = getLoginUser();
+                return toAjax(maTechnicianService.approvePendingMerchantAudit(id, dto, loginUser));
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new RuntimeException(e);
+            }
         }
-    }
 
-    /**
-     * 查询商户详情
-     *
-     * @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);
+        /**
+         * 查询商户列表
+         *
+         * @param page 分页参数
+         * @param dto  商户查询DTO
+         * @return Page 商户分页列表
+         */
+        @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<MaTechnicianCertificateVO> 商户证照
-     */
-    @ApiOperation("后台查看商户证照")
-    @PreAuthorize("@ss.hasPermi('technician:technician:query')")
-    @GetMapping("/merchant/{id}/certificate")
-    public R<MaTechnicianCertificateVO> merchantCertificate(@PathVariable("id") Integer id) {
-        try {
-            return R.ok(maTechnicianService.selectMerchantCertificate(id));
-        } catch (Exception e) {
-            e.printStackTrace();
-            throw new RuntimeException(e);
+        /**
+         * 查询商户详情
+         *
+         * @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);
+            }
         }
-    }
 
-    /**
-     * 修改技师
-     */
-    @PreAuthorize("@ss.hasPermi('technician:technician:edit')")
-    @Log(title = "技师", businessType = BusinessType.UPDATE)
-    @PutMapping
-    public AjaxResult edit(@RequestBody MaTechnicianAppAddVo maTechnicianAppAddVo) {
-        return toAjax(maTechnicianService.updateMaTechnician(maTechnicianAppAddVo));
-    }
+        /**
+         * 查看商户证照
+         *
+         * @param id 商户ID
+         * @return R<MaTechnicianCertificateVO> 商户证照
+         */
+        @ApiOperation("后台查看商户证照")
+        @PreAuthorize("@ss.hasPermi('technician:technician:query')")
+        @GetMapping("/merchant/{id}/certificate")
+        public R<MaTechnicianCertificateVO> merchantCertificate (@PathVariable("id") Integer id){
+            try {
+                return R.ok(maTechnicianService.selectMerchantCertificate(id));
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new RuntimeException(e);
+            }
+        }
 
-    /**
-     * 删除技师
-     */
-    @PreAuthorize("@ss.hasPermi('technician:technician:remove')")
-    @Log(title = "技师", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{ids}")
-    public AjaxResult remove(@PathVariable Long[] ids) {
-        return toAjax(maTechnicianService.deleteMaTechnicianByIds(ids));
-    }
+        /**
+         * 修改技师
+         */
+        @PreAuthorize("@ss.hasPermi('technician:technician:edit')")
+        @Log(title = "技师", businessType = BusinessType.UPDATE)
+        @PutMapping
+        public AjaxResult edit (@RequestBody MaTechnicianAppAddVo maTechnicianAppAddVo){
+            return toAjax(maTechnicianService.updateMaTechnician(maTechnicianAppAddVo));
+        }
 
-    /**
-     * 1. 获取服务类目列表 (对应图1、图3)
-     */
-    @GetMapping("/getServiceCategoryList")
-    public AjaxResult getServiceCategoryList() {
-        List<ServiceCategory> list = serviceCategoryService.listH5ServiceCategory();
-        return AjaxResult.success(list);
-    }
+        /**
+         * 删除技师
+         */
+        @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)
-     * 支持 Tab 切换:all(全部), active(已开通), applying(申请中), rejected(驳回)
-     */
-    @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);
+        /**
+         * 1. 获取服务类目列表 (对应图1、图3)
+         */
+        @GetMapping("/getServiceCategoryList")
+        public AjaxResult getServiceCategoryList () {
+            List<ServiceCategory> list = serviceCategoryService.listH5ServiceCategory();
+            return AjaxResult.success(list);
         }
-    }
 
-    /**
-     * 查询未开通的服务项目列表
-     *
-     * @param req
-     * @return
-     */
-    @PostMapping("/getNotApplyList")
-    public Result<?> getNotApplyList(@RequestBody MaProjectGetVo req) {
+        /**
+         * 1. 获取技能列表 (对应图1、图3)
+         * 支持 Tab 切换:all(全部), active(已开通), applying(申请中), rejected(驳回)
+         */
+        @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);
+            }
+        }
 
-        return Result.ok(maTechnicianService.getNotApplyList(req.getUserId(), req.getTypeId()));
+        /**
+         * 查询未开通的服务项目列表
+         *
+         * @param req
+         * @return
+         */
+        @PostMapping("/getNotApplyList")
+        public Result<?> getNotApplyList (@RequestBody MaProjectGetVo req){
 
-    }
+            return Result.ok(maTechnicianService.getNotApplyList(req.getUserId(), req.getTypeId()));
 
-    /**
-     * 申请开通新服务
-     */
-    @PostMapping("/applyForService")
-    public AjaxResult applyForService(@RequestBody MaProjectSaveDto dto) {
+        }
 
-        return toAjax(maTechnicianService.applyForService(dto));
-    }
+        /**
+         * 申请开通新服务
+         */
+        @PostMapping("/applyForService")
+        public AjaxResult applyForService (@RequestBody MaProjectSaveDto dto){
 
-    /**
-     * 重新申请开通新服务
-     *
-     * @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 toAjax(maTechnicianService.applyForService(dto));
         }
-        return Result.ok("重新申请成功,提交到审核阶段");
 
-    }
-
-    /**
-     * 申请下架,删除服务项目,编辑售价价格
-     *
-     * @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()) {
+        /**
+         * 重新申请开通新服务
+         *
+         * @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::getProjectIsEnable, 1);
+                updateWrapper.set(MaProject::getApplyReason, req.getApplyReason());
+                updateWrapper.set(MaProject::getAuditStatus, 0);
                 maProjectService.update(updateWrapper);
-                message = "申请下架成功";
             }
-            if (req.getProjectCurrentPrice() != null) {
+            return Result.ok("重新申请成功,提交到审核阶段");
 
-                LambdaUpdateWrapper<MaProject> updateWrapper = new LambdaUpdateWrapper<>();
-                updateWrapper.eq(MaProject::getId, req.getProjectId());
-                updateWrapper.set(MaProject::getProjectCurrentPrice, req.getProjectCurrentPrice());
-                maProjectService.update(updateWrapper);
-                message = "修改价格完成";
+        }
 
+        /**
+         * 申请下架,删除服务项目,编辑售价价格
+         *
+         * @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);
+        }
+        /**
+         * 商户入住信息
+         *
+         * @param userId
+         * @return
+         */
+
+        @GetMapping("/getTechnicianList")
+        public Result<?> getTechnicianList (@RequestParam(value = "userId") Long userId){
+            return Result.ok(maTechnicianService.getTechnicianList(userId));
         }
-        return Result.ok(message);
-    }
 
-    @GetMapping("/getTechnicianList")
-    public Result<?> getTechnicianList(@RequestParam(value = "userId") Long userId) {
-        return Result.ok(maTechnicianService.getTechnicianList(userId));
     }
-
-}

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

@@ -362,6 +362,7 @@ public class WeChatController extends BaseController {
         objectLambdaQueryWrapper.eq(TWxUser::getcOpenid, openid);
         TWxUser user = wxUserService.getOne(objectLambdaQueryWrapper);
         if (user == null || StringUtils.isEmpty(user.getcNickName())) {
+            user = new TWxUser();
             user.setcOpenid(openid);
             user.setcNickName(jsonObject.get("nickname").toString());
             user.setcIcon(jsonObject.get("headimgurl").toString());

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

@@ -42,7 +42,7 @@ import java.util.concurrent.TimeUnit;
  * @author b16mt
  */
 @Slf4j
-@Controller
+@RestController
 @Api(tags = {"微信公众号sq"})
 @RequestMapping("/sq")
 public class WeSqController extends BaseController {
@@ -167,7 +167,7 @@ public class WeSqController extends BaseController {
             //log.info("公众号网页登录:{}", jsonObject);
             String nickName = jsonObject.get("nickname").toString();
             String avatarUrl = jsonObject.get("headimgurl").toString();
-            String phoneNumber = jsonObject.get("phoneNumber").toString();
+
 
             // 将用户信息保存到数据库中
             LambdaQueryWrapper<MaTechnician> objectLambdaQueryWrapper = new LambdaQueryWrapper<>();
@@ -178,9 +178,10 @@ public class WeSqController extends BaseController {
                     user = new MaTechnician();
                     user.setCOpenid(openid);
                     user.setTeNickName(nickName);
-                    user.setTeAvatar(avatarUrl);
-                    user.setTePhone(phoneNumber);
-                    user.setOpenService("-1");
+                    user.setCSessionKey(refreshToken);
+                    user.setAuditStatus(-1);
+                    user.setCreateBy(nickName);
+                    user.setUpdateBy(nickName);
                     maTechnicianService.save(user);
                     //异步 添加新人优惠卷
                     //                threadPoolTaskExecutor.submit(() -> couponReceiveService.submit(new CouponReceive().setOpenid(finalUser.getcOpenid()).setCouponId("1")));

+ 9 - 8
nightFragrance-admin/src/main/java/com/ylx/web/controller/system/SysDictDataController.java

@@ -7,14 +7,7 @@ import javax.servlet.http.HttpServletResponse;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 import com.ylx.common.annotation.Log;
 import com.ylx.common.core.controller.BaseController;
 import com.ylx.common.core.domain.AjaxResult;
@@ -77,6 +70,14 @@ public class SysDictDataController extends BaseController {
         }
         return success(data);
     }
+    @GetMapping(value = "/type")
+    public AjaxResult dictTypes(@RequestParam(required = true) String dictType) {
+        List<SysDictData> data = dictTypeService.selectDictDataByType(dictType);
+        if (StringUtils.isNull(data)) {
+            data = new ArrayList<SysDictData>();
+        }
+        return success(data);
+    }
 
     /**
      * 新增字典类型

+ 1 - 1
nightFragrance-common/src/main/java/com/ylx/common/core/domain/model/aliyun/SendSmsEnum.java

@@ -7,7 +7,7 @@ import lombok.Getter;
 @AllArgsConstructor
 public enum SendSmsEnum {
 
-    SMS_220650024("SMS_220650024", "山西掌柜鼎科技", "验证码短信");
+    SMS_220650024("SMS_220650023", "山西掌柜鼎科技", "验证码短信");
 
     private final String code;
 

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

@@ -114,7 +114,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
                         "/wx/pay/payNotify", "/wx/pay/refundNotify", "/weChat/getAccessToken","/weChat/phoneLogin","/weChat/sendMsg", "/weChat/getCode", "/weChat/verifyToken", "/sq/getAccessToken",
                         "/area/select", "/system/dept/list", "/api/xiangmu/v1/wx/recommend", "/product/category/create","/area/code","/area/city","/product/category/list",
                         "/wx/pay/query/order/{outTradeNo}","/api/products/**","/api/user/point/**","/userCenter/userApp/queryBind","/weChat/uuidLogin","/couponReceive/getShareVolutionDetail",
-                        "/userCenter/userApp/bind/update","/serviceCategory/h5List","/api/lbt/v1/select").permitAll()
+                        "/userCenter/userApp/bind/update","/serviceCategory/h5List","/api/lbt/v1/select","/sq/getTechnicianToken"
+                        ,"/technician/technician/clientLogin").permitAll()
                 // 静态资源,可匿名访问
                 .antMatchers(HttpMethod.GET, "/", "/*.txt", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
                 .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()

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

@@ -47,6 +47,11 @@ public class MerchantApplyFile implements Serializable {
     //文件MIME类型,如 image/jpeg
     @TableField("content_type")
     private String contentType;
+    //审核状态//1-审核通过,2-审核未通过
+    private Integer auditStatus;
+    //审核备注
+    @TableField("audit_remark")
+    private String  auditRemark;
     //创建人
     @TableField("create_by")
     private String createBy;

+ 13 - 0
nightFragrance-massage/src/main/java/com/ylx/massage/domain/dto/AcceptOrderReqDTO.java

@@ -0,0 +1,13 @@
+package com.ylx.massage.domain.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class AcceptOrderReqDTO {
+    private Long techId;
+    private Long orderId;
+    private BigDecimal techLat;
+    private BigDecimal techLng;
+}

+ 10 - 0
nightFragrance-massage/src/main/java/com/ylx/massage/domain/dto/MerchantApplyFileRequestDto.java

@@ -0,0 +1,10 @@
+package com.ylx.massage.domain.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class MerchantApplyFileRequestDto {
+    private List<MerchantApplyFileDto> req;
+}

+ 13 - 0
nightFragrance-massage/src/main/java/com/ylx/massage/domain/dto/ValidateCaptchaDto.java

@@ -0,0 +1,13 @@
+package com.ylx.massage.domain.dto;
+
+import lombok.Data;
+
+@Data
+public class ValidateCaptchaDto {
+    //用户名
+    private String phone;
+    //验证码的uuid标识
+    private String uuid;
+    //验证码输入值
+    private String code;
+}

+ 23 - 0
nightFragrance-massage/src/main/java/com/ylx/massage/domain/dto/WaitOrderDTO.java

@@ -0,0 +1,23 @@
+package com.ylx.massage.domain.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+@Data
+public class WaitOrderDTO {
+    private Long orderId;
+    private String projectName;
+    private String customerType;
+    private Date orderCreateTime;
+    private LocalDateTime appointTime;
+    private String targetAddress;
+    private String distanceDesc;
+    // 订单地址经纬度
+    private BigDecimal orderLat;
+    private BigDecimal orderLng;
+    // 实际距离(米,用于排序)
+    private BigDecimal distanceMeter;
+}

+ 12 - 0
nightFragrance-massage/src/main/java/com/ylx/massage/domain/dto/WaitOrderQueryDTO.java

@@ -0,0 +1,12 @@
+package com.ylx.massage.domain.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class WaitOrderQueryDTO {
+    // 技师坐标,接单前无绑定订单,不用techId过滤订单
+    private BigDecimal techLat;
+    private BigDecimal techLng;
+}

+ 15 - 12
nightFragrance-massage/src/main/java/com/ylx/massage/domain/vo/MaTechnicianAppAddVo.java

@@ -1,6 +1,7 @@
 package com.ylx.massage.domain.vo;
 
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonProperty;
 import com.ylx.common.annotation.Excel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
@@ -41,7 +42,17 @@ public class MaTechnicianAppAddVo {
      */
     @Excel(name = "密码")
     private String tePassword;
-
+    @ApiModelProperty(value = "验证码")
+    private String phoneMsg;
+    @ApiModelProperty(value = "图形验证码")
+    private String phoneImgMsg;
+    @ApiModelProperty("用户的openId")
+    @JsonProperty("cOpenid")
+    private String cOpenid;
+    /**
+     * 唯一标识
+     */
+    private String uuid;
     /**
      * 性别(0女1男)
      */
@@ -49,11 +60,6 @@ public class MaTechnicianAppAddVo {
     @ApiModelProperty("性别(0女1男)")
     private Integer teSex;
 
-    /**
-     * 开通服务:1-上门按摩 2-同城玩乐
-     */
-    @Excel(name = "开通服务:1-上门按摩 2-同城玩乐")
-    private BigInteger openService;
     /**
      * 电话
      */
@@ -67,6 +73,8 @@ public class MaTechnicianAppAddVo {
     @Excel(name = "合作意向城市")
     @ApiModelProperty("合作意向城市")
     private String teAddress;
+    @ApiModelProperty("合作意向城市Code")
+    private String teAreaCode;
 
     /**
      * 服务标签(1:按摩推拿 2:陪玩)
@@ -87,12 +95,7 @@ public class MaTechnicianAppAddVo {
     @ApiModelProperty("头像")
     private String teAvatar;
 
-//    /**
-//     * 生活照
-//     */
-//    @Excel(name = "生活照")
-//    @ApiModelProperty("生活照")
-//    private String lifePhotos;
+
 
     /**
      * 简介

+ 2 - 1
nightFragrance-massage/src/main/java/com/ylx/massage/domain/vo/ThirdPartyLoginsVo.java

@@ -15,7 +15,8 @@ public class ThirdPartyLoginsVo implements Serializable {
     private Boolean codeSwitch;
     @ApiModelProperty(value = "验证码")
     private String phoneMsg;
-
+    @ApiModelProperty(value = "图形验证码")
+    private String phoneImgMsg;
     @ApiModelProperty(value = "密码")
     private String passWord;
 

+ 16 - 1
nightFragrance-massage/src/main/java/com/ylx/massage/service/IMaTechnicianService.java

@@ -182,17 +182,29 @@ public interface IMaTechnicianService extends IService<MaTechnician> {
      * @param req
      */
     void apply(MaTechnicianAppAddVo req);
+
     /**
      * 申请技师文件
+     *
      * @param req
      */
-    void applyFile(MerchantApplyFileDto req);
+    void applyFile(MerchantApplyFileRequestDto req);
+
     /**
      * 技师状态切换
      *
      * @param
      */
     Result switchToOffline(Long userId, Boolean forceConfirm);
+
+    /**
+     * 技师待处理订单列表
+     *
+     * @param query
+     * @return
+     */
+    List<WaitOrderDTO> listWaitOrder(WaitOrderQueryDTO query);
+
     /**
      * 技师列表
      *
@@ -221,12 +233,15 @@ public interface IMaTechnicianService extends IService<MaTechnician> {
 
     /**
      * 申请开通新服务
+     *
      * @param dto
      * @return
      */
     int applyForService(MaProjectSaveDto dto);
+
     /**
      * 商户入住信息
+     *
      * @param userId
      * @return
      */

+ 159 - 8
nightFragrance-massage/src/main/java/com/ylx/massage/service/impl/MaTechnicianServiceImpl.java

@@ -1,6 +1,7 @@
 package com.ylx.massage.service.impl;
 
 import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
 import java.time.Duration;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
@@ -47,15 +48,20 @@ import com.ylx.massage.mapper.ContractRecordMapper;
 import com.ylx.massage.mapper.MaProjectMapper;
 import com.ylx.massage.mapper.MaTeProjectMapper;
 import com.ylx.massage.service.TbFileService;
+import com.ylx.order.domain.TOrder;
+import com.ylx.order.mapper.TOrderMapper;
 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.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.stereotype.Service;
 import com.ylx.massage.service.IMaTechnicianService;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
 import org.springframework.web.multipart.MultipartFile;
+import com.ylx.massage.enums.OrderStatusEnum;
 
 import javax.annotation.Resource;
 
@@ -82,6 +88,7 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
     private static final int DEFAULT_STAT_VALUE = 0;
     private static final Integer NOT_DELETED = 0;
     private static final String MERCHANT_STATUS_NORMAL = "0";
+    private static final String PASSWORD = "123456";
 
     @Resource
     private MaTechnicianMapper maTechnicianMapper;
@@ -107,6 +114,9 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
     private TAddressMapper addressMapper;
     @Resource
     private MerchantApplyFileMapper merchantApplyFileMapper;
+    @Resource
+    private TOrderMapper orderMapper;
+
 
 
     /**
@@ -117,6 +127,8 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void apply(MaTechnicianAppAddVo req) {
+        // 初始化加密工具
+        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
         String phone = req.getTePhone();
         //商户入住前置条件校验
         getMaTechnician(req, phone);
@@ -125,7 +137,17 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
         //技师类型默认为真实商户
         maTechnician.setTechType(0);
         maTechnician.setCreateBy("admin");
-        maTechnicianMapper.insert(maTechnician);
+        maTechnician.setAuditStatus(AUDIT_WAIT_ENTER);
+        maTechnician.setTePassword(encoder.encode(PASSWORD));
+        LambdaQueryWrapper<MaTechnician> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(MaTechnician::getCOpenid, req.getCOpenid());
+        MaTechnician maTechnician1 = maTechnicianMapper.selectOne(queryWrapper);
+        if (maTechnician1 == null) {
+           throw new RuntimeException("商户不存在");
+        }
+        LambdaUpdateWrapper<MaTechnician> updateWrapper = new LambdaUpdateWrapper<>();
+        updateWrapper.eq(MaTechnician::getId, maTechnician1.getId());
+        maTechnicianMapper.update(maTechnician, updateWrapper);
 
     }
 
@@ -135,12 +157,28 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
      * @param req
      */
     @Override
-    public void applyFile(MerchantApplyFileDto req) {
-        MerchantApplyFile maTechnician = new MerchantApplyFile();
-        BeanUtils.copyProperties(req, maTechnician);
-        maTechnician.setCreateBy(req.getMerchantId().toString());
-        maTechnician.setUpdateBy(req.getMerchantId().toString());
-        merchantApplyFileMapper.insert(maTechnician);
+    public void applyFile(MerchantApplyFileRequestDto req) {
+        if (req == null || req.getReq().isEmpty()) {
+        }
+        for (MerchantApplyFileDto re : req.getReq()) {
+            LambdaQueryWrapper<MerchantApplyFile> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(MerchantApplyFile::getMerchantId, re.getMerchantId());
+            queryWrapper.eq(MerchantApplyFile::getFileType, re.getFileType());
+            MerchantApplyFile merchantApplyFile = merchantApplyFileMapper.selectOne(queryWrapper);
+            if (merchantApplyFile != null) {
+                // 删除原有文件
+                merchantApplyFileMapper.deleteById(merchantApplyFile);
+            } else {
+                //插入文件信息
+                MerchantApplyFile maTechnician = new MerchantApplyFile();
+                BeanUtils.copyProperties(re, maTechnician);
+                maTechnician.setCreateBy(re.getMerchantId().toString());
+                maTechnician.setUpdateBy(re.getMerchantId().toString());
+                merchantApplyFileMapper.insert(maTechnician);
+            }
+
+
+        }
     }
 
     /**
@@ -945,10 +983,14 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
             // 3. 执行状态更新 (更新为休息中状态)
             updateStatus(userId, TechnicianStatusEnum.RESTING);
             if (!forceConfirm) {
+                // 格式化成 yyyy-MM-dd 纯日期字符串
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+                String today = sdf.format(new Date());
+
                 // 查询商户今日的最近考勤记录
                 LambdaQueryWrapper<MerchantDailyAttendance> query = new LambdaQueryWrapper<>();
                 query.eq(MerchantDailyAttendance::getMerchantId, userId)
-                        .eq(MerchantDailyAttendance::getAttendanceDate, DateUtils.getNowDate())
+                        .eq(MerchantDailyAttendance::getAttendanceDate, today)
                         .orderByDesc(MerchantDailyAttendance::getCreateTime);
                 MerchantDailyAttendance update = merchantDailyAttendanceMapper.selectOne(query);
                 if (update != null) {
@@ -1162,4 +1204,113 @@ public class MaTechnicianServiceImpl extends ServiceImpl<MaTechnicianMapper, MaT
             throw new ServiceException(fieldName + "不能早于当前日期");
         }
     }
+
+    /**
+     * 技师待处理订单列表
+     *
+     * @param query
+     * @return
+     */
+    @Override
+    public List<WaitOrderDTO> listWaitOrder(WaitOrderQueryDTO query) {
+        LambdaQueryWrapper<TOrder> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(TOrder::getStatus, OrderStatusEnum.WAIT_JD.getCode());
+        // 1.查询所有待派未接单订单(status=待接单)
+        List<TOrder> allWaitOrder = orderMapper.selectList(queryWrapper);
+        if(CollectionUtils.isEmpty(allWaitOrder)){
+            return Collections.emptyList();
+        }
+
+        BigDecimal techLat = query.getTechLat();
+        BigDecimal techLng = query.getTechLng();
+
+        // 2.逐个计算两点距离(Haversine公式)
+        List<WaitOrderDTO> dtoList = allWaitOrder.stream().map(order -> {
+            WaitOrderDTO dto = new WaitOrderDTO();
+            dto.setOrderId(order.getId());
+            dto.setProjectName(getShortProjectName(order.getProjectName()));
+            dto.setCustomerType("新客户");//无历史绑定默认新客,接单后再统计老客
+            dto.setOrderCreateTime(order.getCreateTime());
+            dto.setAppointTime(order.getAppointmentStartTime());
+            dto.setTargetAddress(order.getContactAddressInfo());
+            dto.setOrderLat(order.getUserLatitude());
+            dto.setOrderLng(order.getUserLongitude());
+
+            // 计算两点距离 单位:米
+            BigDecimal disMeter = calcDistance(techLat, techLng, order.getUserLatitude(), order.getUserLongitude());
+            dto.setDistanceMeter(disMeter);
+            dto.setDistanceDesc(formatDistance(disMeter));
+            return dto;
+        }).collect(Collectors.toList());
+
+        // 3.距离升序:近的排在最前面
+        return dtoList.stream()
+                       .sorted(Comparator.comparing(WaitOrderDTO::getDistanceMeter))
+                       .collect(Collectors.toList());
+    }
+    // =================工具方法=================
+    /** Haversine 计算经纬度距离 返回米 */
+    private BigDecimal calcDistance(BigDecimal lat1, BigDecimal lng1, BigDecimal lat2, BigDecimal lng2){
+        // 球面距离计算公式,地球半径6371000米
+        // 可使用BigDecimal三角函数或数据库函数优化
+        double latRad1 = Math.toRadians(lat1.doubleValue());
+        double latRad2 = Math.toRadians(lat2.doubleValue());
+        double lngRad1 = Math.toRadians(lng1.doubleValue());
+        double lngRad2 = Math.toRadians(lng2.doubleValue());
+
+        double dLat = latRad2 - latRad1;
+        double dLng = lngRad2 - lngRad1;
+        double a = Math.pow(Math.sin(dLat/2),2)
+                           + Math.cos(latRad1)*Math.cos(latRad2)
+                                     * Math.pow(Math.sin(dLng/2),2);
+        double dis = 2 * 6371000 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
+        return BigDecimal.valueOf(dis).setScale(2,BigDecimal.ROUND_HALF_UP);
+    }
+
+    private String getShortProjectName(String name){
+        if(name != null && name.length()>10){
+            return name.substring(0,8)+"...";
+        }
+        return name;
+    }
+
+    private String formatDistance(BigDecimal distanceMeter){
+        BigDecimal km = distanceMeter.divide(new BigDecimal(1000),2,BigDecimal.ROUND_HALF_UP);
+        if(km.compareTo(BigDecimal.ONE)>0){
+            return km+"km";
+        }else{
+            return distanceMeter.intValue()+"m";
+        }
+    }
+
+    /** 校验技师已有订单时间冲突(只查该技师已接单数据) */
+    private boolean checkOrderTimeConflict(Long techId, TOrder newOrder){
+        LambdaQueryWrapper<TOrder> query = new LambdaQueryWrapper<>();
+        query.eq(TOrder::getMerchantId, techId);
+        query.eq(TOrder::getStatus, OrderStatusEnum.RECEIVED_ORDER.getCode());
+        query.eq(TOrder::getStartTime, newOrder.getStartTime());
+
+        List<TOrder> acceptedOrders = orderMapper.selectList(query);
+        LocalDate newOrderDate = newOrder.getStartTime().toLocalDate();
+        LocalDateTime newStart = newOrder.getStartTime();
+        for(TOrder old:acceptedOrders){
+            if(!newOrderDate.isEqual(old.getCompletedTime().toLocalDate())){
+                continue;
+            }
+            LocalDateTime oldEnd = old.getCompletedTime();
+            if(newStart.isBefore(oldEnd) || newStart.isEqual(oldEnd)){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /** 接单:给订单赋值技师ID */
+    private void doAcceptOrder(Long techId, Long orderId){
+        TOrder update = new TOrder();
+        update.setId(orderId);
+        update.setMerchantId(techId);
+        update.setStatus(OrderStatusEnum.RECEIVED_ORDER.getCode());
+        orderMapper.updateById(update);
+    }
 }

+ 1 - 1
nightFragrance-massage/src/main/java/com/ylx/massage/utils/WeChatUtil.java

@@ -86,7 +86,7 @@ public class WeChatUtil {
      * @return Map<?, ?> 返回包含微信AccessToken的Map
      */
     public Map<?, ?> getAccessToken(String code) {
-        StringBuffer url = new StringBuffer();
+         StringBuffer url = new StringBuffer();
         url.append(wxPayProperties.getAccessTokenUrl())
                 .append("?appid=").append(wxPayProperties.getMpAppId())
                 .append("&secret=").append(wxPayProperties.getMpAppSecret())