package com.alatus.mall.member.controller; import java.util.Arrays; import java.util.Map; import com.alatus.common.exception.BizCodeEnum; import com.alatus.mall.member.exception.PhoneExistException; import com.alatus.mall.member.exception.UsernameExistException; import com.alatus.mall.member.vo.MemberRegisterVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import com.alatus.mall.member.entity.MemberEntity; import com.alatus.mall.member.service.MemberService; import com.alatus.common.utils.PageUtils; import com.alatus.common.utils.R; /** * 会员 * * @author alatus * @email 1571345941@qq.com * @date 2024-03-12 13:40:22 */ @RestController @RequestMapping("member/member") public class MemberController { @Autowired private MemberService memberService; @PostMapping("register") public R register(@RequestBody MemberRegisterVo memberRegisterVo){ try{ memberService.register(memberRegisterVo); } catch (UsernameExistException e){ return R.error(BizCodeEnum.USER_EXIST_EXCEPTION.getCode(), BizCodeEnum.USER_EXIST_EXCEPTION.getMsg()); } catch (PhoneExistException e){ return R.error(BizCodeEnum.PHONE_EXIST_EXCEPTION.getCode(), BizCodeEnum.PHONE_EXIST_EXCEPTION.getMsg()); } return R.ok(); } /** * 列表 */ @RequestMapping("/list") public R list(@RequestParam Map<String, Object> params){ PageUtils page = memberService.queryPage(params); return R.ok().put("page", page); } /** * 验证手机号是否已被使用 */ @GetMapping("/checkPhone/{phone}") public R checkPhone(@PathVariable("phone")String phone){ try{ memberService.checkPhoneUnique(phone); } catch (PhoneExistException e){ return R.error(BizCodeEnum.PHONE_EXIST_EXCEPTION.getCode(), BizCodeEnum.PHONE_EXIST_EXCEPTION.getMsg()); } return R.ok(); } /** * 信息 */ @RequestMapping("/info/{id}") public R info(@PathVariable("id") Long id){ MemberEntity member = memberService.getById(id); return R.ok().put("member", member); } /** * 保存 */ @RequestMapping("/save") public R save(@RequestBody MemberEntity member){ memberService.save(member); return R.ok(); } /** * 修改 */ @RequestMapping("/update") public R update(@RequestBody MemberEntity member){ memberService.updateById(member); return R.ok(); } /** * 删除 */ @RequestMapping("/delete") public R delete(@RequestBody Long[] ids){ memberService.removeByIds(Arrays.asList(ids)); return R.ok(); } }
package com.alatus.mall.member.controller; import java.util.Arrays; import java.util.Map; import com.alatus.common.exception.BizCodeEnum; import com.alatus.mall.member.exception.PhoneExistException; import com.alatus.mall.member.exception.UsernameExistException; import com.alatus.mall.member.vo.MemberRegisterVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import com.alatus.mall.member.entity.MemberEntity; import com.alatus.mall.member.service.MemberService; import com.alatus.common.utils.PageUtils; import com.alatus.common.utils.R; /** * 会员 * * @author alatus * @email 1571345941@qq.com * @date 2024-03-12 13:40:22 */ @RestController @RequestMapping("member/member") public class MemberController { @Autowired private MemberService memberService; @PostMapping("register") public R register(@RequestBody MemberRegisterVo memberRegisterVo){ try{ memberService.register(memberRegisterVo); } catch (UsernameExistException e){ return R.error(BizCodeEnum.USER_EXIST_EXCEPTION.getCode(), BizCodeEnum.USER_EXIST_EXCEPTION.getMsg()); } catch (PhoneExistException e){ return R.error(BizCodeEnum.PHONE_EXIST_EXCEPTION.getCode(), BizCodeEnum.PHONE_EXIST_EXCEPTION.getMsg()); } return R.ok(); } /** * 列表 */ @RequestMapping("/list") public R list(@RequestParam Map<String, Object> params){ PageUtils page = memberService.queryPage(params); return R.ok().put("page", page); } /** * 验证手机号是否已被使用 */ @GetMapping("/checkPhone/{phone}") public R checkPhone(@PathVariable("phone")String phone){ try{ memberService.checkPhoneUnique(phone); } catch (PhoneExistException e){ return R.error(BizCodeEnum.PHONE_EXIST_EXCEPTION.getCode(), BizCodeEnum.PHONE_EXIST_EXCEPTION.getMsg()); } return R.ok(); } /** * 信息 */ @RequestMapping("/info/{id}") public R info(@PathVariable("id") Long id){ MemberEntity member = memberService.getById(id); return R.ok().put("member", member); } /** * 保存 */ @RequestMapping("/save") public R save(@RequestBody MemberEntity member){ memberService.save(member); return R.ok(); } /** * 修改 */ @RequestMapping("/update") public R update(@RequestBody MemberEntity member){ memberService.updateById(member); return R.ok(); } /** * 删除 */ @RequestMapping("/delete") public R delete(@RequestBody Long[] ids){ memberService.removeByIds(Arrays.asList(ids)); return R.ok(); } }
package com.alatus.mall.member.service; import com.alatus.mall.member.exception.PhoneExistException; import com.alatus.mall.member.exception.UsernameExistException; import com.alatus.mall.member.vo.MemberRegisterVo; import com.baomidou.mybatisplus.extension.service.IService; import com.alatus.common.utils.PageUtils; import com.alatus.mall.member.entity.MemberEntity; import java.util.Map; /** * 会员 * * @author alatus * @email 1571345941@qq.com * @date 2024-03-12 13:40:22 */ public interface MemberService extends IService<MemberEntity> { PageUtils queryPage(Map<String, Object> params); void register(MemberRegisterVo memberRegisterVo); void checkPhoneUnique(String phone) throws PhoneExistException; void checkUsernameUnique(String username) throws UsernameExistException; }
package com.alatus.mall.member.service; import com.alatus.mall.member.exception.PhoneExistException; import com.alatus.mall.member.exception.UsernameExistException; import com.alatus.mall.member.vo.MemberRegisterVo; import com.baomidou.mybatisplus.extension.service.IService; import com.alatus.common.utils.PageUtils; import com.alatus.mall.member.entity.MemberEntity; import java.util.Map; /** * 会员 * * @author alatus * @email 1571345941@qq.com * @date 2024-03-12 13:40:22 */ public interface MemberService extends IService<MemberEntity> { PageUtils queryPage(Map<String, Object> params); void register(MemberRegisterVo memberRegisterVo); void checkPhoneUnique(String phone) throws PhoneExistException; void checkUsernameUnique(String username) throws UsernameExistException; }
package com.alatus.mall.member.service.impl; import com.alatus.mall.member.entity.MemberLevelEntity; import com.alatus.mall.member.exception.PhoneExistException; import com.alatus.mall.member.exception.UsernameExistException; import com.alatus.mall.member.service.MemberLevelService; import com.alatus.mall.member.vo.MemberRegisterVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; import java.util.Map; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.alatus.common.utils.PageUtils; import com.alatus.common.utils.Query; import com.alatus.mall.member.dao.MemberDao; import com.alatus.mall.member.entity.MemberEntity; import com.alatus.mall.member.service.MemberService; @Service("memberService") public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService { @Autowired private MemberLevelService memberLevelService; @Override public PageUtils queryPage(Map<String, Object> params) { IPage<MemberEntity> page = this.page( new Query<MemberEntity>().getPage(params), new QueryWrapper<MemberEntity>() ); return new PageUtils(page); } @Override public void register(MemberRegisterVo memberRegisterVo) { // 检查用户名和手机号是否唯一(为了能让上层感知异常,我们这里抛出去)采用异常机制 checkPhoneUnique(memberRegisterVo.getPhone()); checkUsernameUnique(memberRegisterVo.getUsername()); MemberEntity memberEntity = new MemberEntity(); // 设置默认等级 MemberLevelEntity memberLevelEntity = memberLevelService.getDefaultLevel(); memberEntity.setLevelId(memberLevelEntity.getId()); // 密码绝对不能传递明文,一旦数据库泄露,就会导致所有数据曝光,我们应该存储MD5加密后的数据 // MD5任何长度大小的数据,算出的值都是固定的,源数据哪怕任何改动,得到的MD5值都会不同 // 百度网盘的秒传功能本质上就是MD5值相同,在这个情况下,不同文件就不需要再次上传,达到了秒传效果 // MD5的最大特点就说不可逆,无法通过MD5获取源数据的值 // MD5抗修改性意味着MD5的数据可以通过暴力算或者字典查的穷举法获得,网上有一大堆对应的彩虹表 // 因此MD5不能直接用来加密,必须加盐存储 // 使用Spring原生的加密器实现 BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); memberEntity.setPassword(passwordEncoder.encode(memberRegisterVo.getPassword())); // 用户名 memberEntity.setUsername(memberRegisterVo.getUsername()); // 手机号 memberEntity.setMobile(memberRegisterVo.getPhone()); this.baseMapper.insert(memberEntity); } @Override public void checkPhoneUnique(String phone) throws PhoneExistException{ Integer count = this.baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("mobile", phone)); if(count>0){ throw new PhoneExistException(); } } @Override public void checkUsernameUnique(String username) throws UsernameExistException{ Integer count = this.baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("username", username)); if(count>0){ throw new UsernameExistException(); } } }
package com.alatus.mall.member.service.impl; import com.alatus.mall.member.entity.MemberLevelEntity; import com.alatus.mall.member.exception.PhoneExistException; import com.alatus.mall.member.exception.UsernameExistException; import com.alatus.mall.member.service.MemberLevelService; import com.alatus.mall.member.vo.MemberRegisterVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; import java.util.Map; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.alatus.common.utils.PageUtils; import com.alatus.common.utils.Query; import com.alatus.mall.member.dao.MemberDao; import com.alatus.mall.member.entity.MemberEntity; import com.alatus.mall.member.service.MemberService; @Service("memberService") public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService { @Autowired private MemberLevelService memberLevelService; @Override public PageUtils queryPage(Map<String, Object> params) { IPage<MemberEntity> page = this.page( new Query<MemberEntity>().getPage(params), new QueryWrapper<MemberEntity>() ); return new PageUtils(page); } @Override public void register(MemberRegisterVo memberRegisterVo) { // 检查用户名和手机号是否唯一(为了能让上层感知异常,我们这里抛出去)采用异常机制 checkPhoneUnique(memberRegisterVo.getPhone()); checkUsernameUnique(memberRegisterVo.getUsername()); MemberEntity memberEntity = new MemberEntity(); // 设置默认等级 MemberLevelEntity memberLevelEntity = memberLevelService.getDefaultLevel(); memberEntity.setLevelId(memberLevelEntity.getId()); // 密码绝对不能传递明文,一旦数据库泄露,就会导致所有数据曝光,我们应该存储MD5加密后的数据 // MD5任何长度大小的数据,算出的值都是固定的,源数据哪怕任何改动,得到的MD5值都会不同 // 百度网盘的秒传功能本质上就是MD5值相同,在这个情况下,不同文件就不需要再次上传,达到了秒传效果 // MD5的最大特点就说不可逆,无法通过MD5获取源数据的值 // MD5抗修改性意味着MD5的数据可以通过暴力算或者字典查的穷举法获得,网上有一大堆对应的彩虹表 // 因此MD5不能直接用来加密,必须加盐存储 // 使用Spring原生的加密器实现 BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); memberEntity.setPassword(passwordEncoder.encode(memberRegisterVo.getPassword())); // 用户名 memberEntity.setUsername(memberRegisterVo.getUsername()); // 手机号 memberEntity.setMobile(memberRegisterVo.getPhone()); this.baseMapper.insert(memberEntity); } @Override public void checkPhoneUnique(String phone) throws PhoneExistException{ Integer count = this.baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("mobile", phone)); if(count>0){ throw new PhoneExistException(); } } @Override public void checkUsernameUnique(String username) throws UsernameExistException{ Integer count = this.baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("username", username)); if(count>0){ throw new UsernameExistException(); } } }
package com.alatus.common.exception; import lombok.AllArgsConstructor; import lombok.Getter; @AllArgsConstructor @Getter public enum BizCodeEnum { UNKNOW_EXCEPTION(10000,"系统未知异常"), VALID_EXCEPTION(10001,"参数校验失败"), SMS_CODE_EXCEPTION(10002,"短信验证码获取频率太高,请稍后再试"), USER_EXIST_EXCEPTION(15001,"用户名存在异常"), PHONE_EXIST_EXCEPTION(15002,"手机号存在异常"), PRODUCT_UP_EXCEPTION(11000,"商品上架异常"); private int code; private String msg; }
package com.alatus.common.exception; import lombok.AllArgsConstructor; import lombok.Getter; @AllArgsConstructor @Getter public enum BizCodeEnum { UNKNOW_EXCEPTION(10000,"系统未知异常"), VALID_EXCEPTION(10001,"参数校验失败"), SMS_CODE_EXCEPTION(10002,"短信验证码获取频率太高,请稍后再试"), USER_EXIST_EXCEPTION(15001,"用户名存在异常"), PHONE_EXIST_EXCEPTION(15002,"手机号存在异常"), PRODUCT_UP_EXCEPTION(11000,"商品上架异常"); private int code; private String msg; }
package com.alatus.mall.auth.app; import com.alatus.common.constant.AuthServerConstant; import com.alatus.common.exception.BizCodeEnum; import com.alatus.common.utils.R; import com.alatus.mall.auth.feign.MemberFeignService; import com.alatus.mall.auth.feign.ThirdPartFeignService; import com.alatus.mall.auth.vo.UserRegisterVo; import com.alibaba.fastjson.TypeReference; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import javax.validation.Valid; import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @Controller public class LoginController { @Autowired private ThirdPartFeignService thirdPartFeignService; @Autowired private StringRedisTemplate redisTemplate; @Autowired private MemberFeignService memberFeignService; @GetMapping("/sms/sendCode") @ResponseBody public R sendCode(@RequestParam("phone") String phone){ R checkPhone = memberFeignService.checkPhone(phone); if(checkPhone.getCode()==0){ // TODO 接口防刷 // 防止反复刷验证码 String value = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone); if(value!=null&&!StringUtils.isEmpty(value)){ long time = Long.parseLong(value.split("_")[1]); if(System.currentTimeMillis() - time < 60000){ // 60秒内不能再发 return R.error(BizCodeEnum.SMS_CODE_EXCEPTION.getCode(),BizCodeEnum.SMS_CODE_EXCEPTION.getMsg()); } } String code = UUID.randomUUID().toString().substring(0, 5); R sendCode = thirdPartFeignService.sendCode(phone, code); // 缓存验证码 redisTemplate.opsForValue().set(AuthServerConstant.SMS_CODE_CACHE_PREFIX+phone,code+"_"+System.currentTimeMillis(),10, TimeUnit.MINUTES); if(sendCode.getCode()==0){ return R.ok(); } else{ return R.error(); } } else{ return checkPhone; } } //RedirectAttributes redirectAttributes模拟重定向携带数据 // TODO 重定向携带数据,利用session原理,将数据放在session中 // 只要跳到下一个页面取出这个数据后,session的数据就被删掉了 // TODO 分布式Session问题解决!!! @PostMapping("/register") public String register(@Valid UserRegisterVo vo, BindingResult result, RedirectAttributes redirectAttributes){ if(result.hasErrors()){ // 收集错误信息返回 Map<String, String> collect = result.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField,FieldError::getDefaultMessage)); redirectAttributes.addFlashAttribute("errors",collect); // 原请求是post请求,当我们失败以后,在这里转发,转发是会保持请求方式不变的,但是路径访问默认是get // 就会出现错误 // 原理是使用了HttpSession的底层实现 return "redirect:http://auth.alatusmall.com/reg.html"; } else{ // 校验验证码 String code = vo.getCode(); String codeValue = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone()); if(codeValue!=null&&!StringUtils.isEmpty(codeValue)){ // 截串获取验证码信息 String redisCode = codeValue.split("_")[0]; if(redisCode.equals(code)){ // 验证码通过以后,删除验证码,令牌机制,验证码用过就不再可用了 redisTemplate.delete(AuthServerConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone()); // 调用远程服务进行注册 R register = memberFeignService.register(vo); if(register.getCode()==0){ return "redirect:http://auth.alatusmall.com/login.html"; } else{ Map<String,String> errors = new HashMap<>(); errors.put("msg",register.getData(new TypeReference<String>(){})); redirectAttributes.addFlashAttribute("errors",errors); return "redirect:http://auth.alatusmall.com/reg.html"; } } else{ // 验证码错误 return CodeError(redirectAttributes); } } else{ // 没有验证码 return CodeError(redirectAttributes); } } } private String CodeError(RedirectAttributes redirectAttributes){ Map<String,String> errors = new HashMap<>(); errors.put("code","验证码错误"); redirectAttributes.addFlashAttribute("errors",errors); return "redirect:http://auth.alatusmall.com/reg.html"; } }
package com.alatus.mall.auth.app; import com.alatus.common.constant.AuthServerConstant; import com.alatus.common.exception.BizCodeEnum; import com.alatus.common.utils.R; import com.alatus.mall.auth.feign.MemberFeignService; import com.alatus.mall.auth.feign.ThirdPartFeignService; import com.alatus.mall.auth.vo.UserRegisterVo; import com.alibaba.fastjson.TypeReference; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import javax.validation.Valid; import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @Controller public class LoginController { @Autowired private ThirdPartFeignService thirdPartFeignService; @Autowired private StringRedisTemplate redisTemplate; @Autowired private MemberFeignService memberFeignService; @GetMapping("/sms/sendCode") @ResponseBody public R sendCode(@RequestParam("phone") String phone){ R checkPhone = memberFeignService.checkPhone(phone); if(checkPhone.getCode()==0){ // TODO 接口防刷 // 防止反复刷验证码 String value = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone); if(value!=null&&!StringUtils.isEmpty(value)){ long time = Long.parseLong(value.split("_")[1]); if(System.currentTimeMillis() - time < 60000){ // 60秒内不能再发 return R.error(BizCodeEnum.SMS_CODE_EXCEPTION.getCode(),BizCodeEnum.SMS_CODE_EXCEPTION.getMsg()); } } String code = UUID.randomUUID().toString().substring(0, 5); R sendCode = thirdPartFeignService.sendCode(phone, code); // 缓存验证码 redisTemplate.opsForValue().set(AuthServerConstant.SMS_CODE_CACHE_PREFIX+phone,code+"_"+System.currentTimeMillis(),10, TimeUnit.MINUTES); if(sendCode.getCode()==0){ return R.ok(); } else{ return R.error(); } } else{ return checkPhone; } } //RedirectAttributes redirectAttributes模拟重定向携带数据 // TODO 重定向携带数据,利用session原理,将数据放在session中 // 只要跳到下一个页面取出这个数据后,session的数据就被删掉了 // TODO 分布式Session问题解决!!! @PostMapping("/register") public String register(@Valid UserRegisterVo vo, BindingResult result, RedirectAttributes redirectAttributes){ if(result.hasErrors()){ // 收集错误信息返回 Map<String, String> collect = result.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField,FieldError::getDefaultMessage)); redirectAttributes.addFlashAttribute("errors",collect); // 原请求是post请求,当我们失败以后,在这里转发,转发是会保持请求方式不变的,但是路径访问默认是get // 就会出现错误 // 原理是使用了HttpSession的底层实现 return "redirect:http://auth.alatusmall.com/reg.html"; } else{ // 校验验证码 String code = vo.getCode(); String codeValue = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone()); if(codeValue!=null&&!StringUtils.isEmpty(codeValue)){ // 截串获取验证码信息 String redisCode = codeValue.split("_")[0]; if(redisCode.equals(code)){ // 验证码通过以后,删除验证码,令牌机制,验证码用过就不再可用了 redisTemplate.delete(AuthServerConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone()); // 调用远程服务进行注册 R register = memberFeignService.register(vo); if(register.getCode()==0){ return "redirect:http://auth.alatusmall.com/login.html"; } else{ Map<String,String> errors = new HashMap<>(); errors.put("msg",register.getData(new TypeReference<String>(){})); redirectAttributes.addFlashAttribute("errors",errors); return "redirect:http://auth.alatusmall.com/reg.html"; } } else{ // 验证码错误 return CodeError(redirectAttributes); } } else{ // 没有验证码 return CodeError(redirectAttributes); } } } private String CodeError(RedirectAttributes redirectAttributes){ Map<String,String> errors = new HashMap<>(); errors.put("code","验证码错误"); redirectAttributes.addFlashAttribute("errors",errors); return "redirect:http://auth.alatusmall.com/reg.html"; } }
package com.alatus.mall.auth.feign; import com.alatus.common.utils.R; import com.alatus.mall.auth.vo.UserRegisterVo; import org.springframework.cloud.openfeign.FeignClient; 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.RequestBody; @FeignClient(name = "Mall-member") public interface MemberFeignService { @PostMapping("/member/member/register") R register(@RequestBody UserRegisterVo memberRegisterVo); @GetMapping("/checkPhone/{phone}") R checkPhone(@PathVariable("phone")String phone); }
package com.alatus.mall.auth.feign; import com.alatus.common.utils.R; import com.alatus.mall.auth.vo.UserRegisterVo; import org.springframework.cloud.openfeign.FeignClient; 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.RequestBody; @FeignClient(name = "Mall-member") public interface MemberFeignService { @PostMapping("/member/member/register") R register(@RequestBody UserRegisterVo memberRegisterVo); @GetMapping("/checkPhone/{phone}") R checkPhone(@PathVariable("phone")String phone); }