From d0ea6825db0c9e9cd5ff765ea46a31fe1059b361 Mon Sep 17 00:00:00 2001 From: zhangli <123879394@qq.com> Date: Sun, 27 Jul 2025 02:12:58 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E7=99=BB=E5=BD=95=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sczx/user/controller/AuthController.java | 48 ++++--- .../sczx/user/convert/UserInfoConvert.java | 18 +++ .../user/{model => dto}/LoginResponse.java | 8 +- src/main/java/com/sczx/user/dto/RegReq.java | 24 ++++ .../com/sczx/user/dto/SimpleUserInfoDTO.java | 9 ++ .../com/sczx/user/mapper/BaseUserMapper.java | 16 +++ .../java/com/sczx/user/po/BaseUserPO.java | 68 +++++++++ .../sczx/user/repository/BaseUserRepo.java | 16 +++ .../repository/impl/BaseUserRepoImpl.java | 20 +++ .../com/sczx/user/service/IUserService.java | 43 +++--- .../user/service/impl/UserServiceImpl.java | 97 +++++++++---- .../dto/WechatMiniProgramResponse.java | 12 ++ .../user/thirdpart/integ/WeichatInteg.java | 133 ++++++++++++++++++ src/main/java/com/sczx/user/util/JwtUtil.java | 32 +++++ src/main/resources/application.yml | 7 + src/main/resources/mapper/BaseUserMapper.xml | 5 + .../java/com/sczx/user/CodeGenerator.java | 6 +- 17 files changed, 486 insertions(+), 76 deletions(-) create mode 100644 src/main/java/com/sczx/user/convert/UserInfoConvert.java rename src/main/java/com/sczx/user/{model => dto}/LoginResponse.java (62%) create mode 100644 src/main/java/com/sczx/user/dto/RegReq.java create mode 100644 src/main/java/com/sczx/user/mapper/BaseUserMapper.java create mode 100644 src/main/java/com/sczx/user/po/BaseUserPO.java create mode 100644 src/main/java/com/sczx/user/repository/BaseUserRepo.java create mode 100644 src/main/java/com/sczx/user/repository/impl/BaseUserRepoImpl.java create mode 100644 src/main/java/com/sczx/user/thirdpart/dto/WechatMiniProgramResponse.java create mode 100644 src/main/java/com/sczx/user/thirdpart/integ/WeichatInteg.java create mode 100644 src/main/resources/mapper/BaseUserMapper.xml diff --git a/src/main/java/com/sczx/user/controller/AuthController.java b/src/main/java/com/sczx/user/controller/AuthController.java index a1c5c44..41ab28b 100644 --- a/src/main/java/com/sczx/user/controller/AuthController.java +++ b/src/main/java/com/sczx/user/controller/AuthController.java @@ -1,7 +1,8 @@ package com.sczx.user.controller; import com.sczx.user.common.Result; -import com.sczx.user.model.LoginRequest; +import com.sczx.user.dto.LoginResponse; +import com.sczx.user.dto.RegReq; import com.sczx.user.service.IUserService; import com.sczx.user.util.JwtUtil; import io.swagger.annotations.Api; @@ -19,22 +20,35 @@ public class AuthController { @Autowired private JwtUtil jwtUtil; - @ApiOperation(value = "微信小程序登录", notes = "通过微信code登录") - @PostMapping("/mini-program/wechat/login") - public Result wechatLogin(@RequestParam("code") String code) { - String token = userService.miniProgramLogin(code); - return Result.ok(token); + @ApiOperation(value = "获取微信openId", notes = "通过微信code注册") + @PostMapping("/mini-program/getWxOpenId") + public Result getWxOpenId(@RequestParam("code") String code) { + String openId= userService.getWxOpenId(code); + return Result.ok(openId); } - @ApiOperation(value = "微信小程序注册", notes = "通过微信code注册") - @PostMapping("/mini-program/wechat/register") - public Result wechatRegister( - @RequestParam("code") String code, - @RequestBody LoginRequest request) { - String token = userService.miniProgramRegister(code, request.getUsername(), request.getPassword()); - return Result.ok(token); + @ApiOperation(value = "获取微信手机号", notes = "通过微信code注册") + @PostMapping("/mini-program/getWxPhoneNumber") + public Result getWxPhoneNumber(@RequestParam("phoneCode") String phoneCode) { + String phoneNumber= userService.getWxPhoneNumber(phoneCode); + return Result.ok(phoneNumber); } + @ApiOperation(value = "小程序注册", notes = "注册") + @PostMapping("/mini-program/register") + public Result wechatRegister( + @RequestBody RegReq regReq) { + Boolean result = userService.miniProgramRegister(regReq.getOpenId(), regReq.getNickName(), regReq.getPhoneNumber(), regReq.getAvatarUrl()); + return Result.ok(result); + } + + @ApiOperation(value = "微信小程序登录", notes = "通过微信code登录") + @PostMapping("/mini-program/wechat/login") + public Result wechatLogin(@RequestParam("code") String code) { + return Result.ok(userService.miniProgramLogin(code)); + } + + @ApiOperation(value = "支付宝小程序登录", notes = "通过支付宝userId登录") @PostMapping("/mini-program/alipay/login") public Result alipayLogin(@RequestParam("userId") String userId) { @@ -42,12 +56,4 @@ public class AuthController { return Result.ok(token); } - @ApiOperation(value = "支付宝小程序注册", notes = "通过支付宝userId注册") - @PostMapping("/mini-program/alipay/register") - public Result alipayRegister( - @RequestParam("userId") String userId, - @RequestBody LoginRequest request) { - String token = userService.alipayMiniProgramRegister(userId, request.getUsername(), request.getPassword()); - return Result.ok(token); - } } diff --git a/src/main/java/com/sczx/user/convert/UserInfoConvert.java b/src/main/java/com/sczx/user/convert/UserInfoConvert.java new file mode 100644 index 0000000..3e8c625 --- /dev/null +++ b/src/main/java/com/sczx/user/convert/UserInfoConvert.java @@ -0,0 +1,18 @@ +package com.sczx.user.convert; + +import com.sczx.user.dto.SimpleUserInfoDTO; +import com.sczx.user.po.BaseUserPO; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface UserInfoConvert { + UserInfoConvert INSTANCE = Mappers.getMapper(UserInfoConvert.class); + @Mappings({ + @Mapping(source = "baseUserPO.id", target = "userId") + + }) + SimpleUserInfoDTO poToSimpleDTO(BaseUserPO baseUserPO); +} diff --git a/src/main/java/com/sczx/user/model/LoginResponse.java b/src/main/java/com/sczx/user/dto/LoginResponse.java similarity index 62% rename from src/main/java/com/sczx/user/model/LoginResponse.java rename to src/main/java/com/sczx/user/dto/LoginResponse.java index a774b6d..58cad94 100644 --- a/src/main/java/com/sczx/user/model/LoginResponse.java +++ b/src/main/java/com/sczx/user/dto/LoginResponse.java @@ -1,4 +1,4 @@ -package com.sczx.user.model; +package com.sczx.user.dto; import io.swagger.annotations.ApiModel; @@ -16,8 +16,6 @@ import lombok.Data; public class LoginResponse { @ApiModelProperty(value = "登录的token") private String token; - @ApiModelProperty(value = "登录的refreshToken") - private String refreshToken; - @ApiModelProperty(value = "登录用户的角色") - private String role; + @ApiModelProperty(value = "用户信息") + private SimpleUserInfoDTO userInfo; } \ No newline at end of file diff --git a/src/main/java/com/sczx/user/dto/RegReq.java b/src/main/java/com/sczx/user/dto/RegReq.java new file mode 100644 index 0000000..a141ca0 --- /dev/null +++ b/src/main/java/com/sczx/user/dto/RegReq.java @@ -0,0 +1,24 @@ +package com.sczx.user.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@ApiModel(value = "小程序注册请求") +@Slf4j +@Data +public class RegReq { + + @ApiModelProperty(value = "微信openId") + private String openId; + + @ApiModelProperty(value = "手机号") + private String phoneNumber; + + @ApiModelProperty(value = "nickName") + private String nickName; + + @ApiModelProperty(value = "头像") + private String avatarUrl; +} diff --git a/src/main/java/com/sczx/user/dto/SimpleUserInfoDTO.java b/src/main/java/com/sczx/user/dto/SimpleUserInfoDTO.java index 7a8c25b..7da5317 100644 --- a/src/main/java/com/sczx/user/dto/SimpleUserInfoDTO.java +++ b/src/main/java/com/sczx/user/dto/SimpleUserInfoDTO.java @@ -14,6 +14,15 @@ public class SimpleUserInfoDTO { @ApiModelProperty(value = "用户姓名") private String userName; + @ApiModelProperty(value = "手机号") + private String phoneNumber; + @ApiModelProperty(value = "角色id") private Integer roleId; + + @ApiModelProperty(value = "小程序类型") + private String miniProgramType; + + @ApiModelProperty("头像") + private String avatarUrl; } diff --git a/src/main/java/com/sczx/user/mapper/BaseUserMapper.java b/src/main/java/com/sczx/user/mapper/BaseUserMapper.java new file mode 100644 index 0000000..ceb9b14 --- /dev/null +++ b/src/main/java/com/sczx/user/mapper/BaseUserMapper.java @@ -0,0 +1,16 @@ +package com.sczx.user.mapper; + +import com.sczx.user.po.BaseUserPO; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 租车用户信息 Mapper 接口 + *

+ * + * @author zhangli + * @since 2025-07-27 01:06:25 + */ +public interface BaseUserMapper extends BaseMapper { + +} diff --git a/src/main/java/com/sczx/user/po/BaseUserPO.java b/src/main/java/com/sczx/user/po/BaseUserPO.java new file mode 100644 index 0000000..7f2d715 --- /dev/null +++ b/src/main/java/com/sczx/user/po/BaseUserPO.java @@ -0,0 +1,68 @@ +package com.sczx.user.po; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 租车用户信息 + *

+ * + * @author zhangli + * @since 2025-07-27 01:06:25 + */ +@Getter +@Setter +@TableName("zc_base_user") +@ApiModel(value = "BaseUserPO对象", description = "租车用户信息") +public class BaseUserPO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("用户id主键") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("用户名") + private String userName; + + @ApiModelProperty("头像") + private String avatarUrl; + + @ApiModelProperty("子订单编号") + private String password; + + @ApiModelProperty("手机号") + private String phoneNumber; + + @ApiModelProperty("角色id") + private Integer roleId; + + @ApiModelProperty("昵称") + private String nickName; + + @ApiModelProperty("微信小程序 openid") + private String wechatOpenid; + + @ApiModelProperty("支付宝小程序 userid") + private String alipayUserid; + + @ApiModelProperty("删除标志(0代表存在 2代表删除)") + private String delFlag; + + @ApiModelProperty("创建时间") + private LocalDateTime createTime; + + @ApiModelProperty("更新时间") + private LocalDateTime updateTime; + + +} diff --git a/src/main/java/com/sczx/user/repository/BaseUserRepo.java b/src/main/java/com/sczx/user/repository/BaseUserRepo.java new file mode 100644 index 0000000..ae82a2b --- /dev/null +++ b/src/main/java/com/sczx/user/repository/BaseUserRepo.java @@ -0,0 +1,16 @@ +package com.sczx.user.repository; + +import com.sczx.user.po.BaseUserPO; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 租车用户信息 服务类 + *

+ * + * @author zhangli + * @since 2025-07-27 01:06:25 + */ +public interface BaseUserRepo extends IService { + +} diff --git a/src/main/java/com/sczx/user/repository/impl/BaseUserRepoImpl.java b/src/main/java/com/sczx/user/repository/impl/BaseUserRepoImpl.java new file mode 100644 index 0000000..335f596 --- /dev/null +++ b/src/main/java/com/sczx/user/repository/impl/BaseUserRepoImpl.java @@ -0,0 +1,20 @@ +package com.sczx.user.repository.impl; + +import com.sczx.user.po.BaseUserPO; +import com.sczx.user.mapper.BaseUserMapper; +import com.sczx.user.repository.BaseUserRepo; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 租车用户信息 服务实现类 + *

+ * + * @author zhangli + * @since 2025-07-27 01:06:25 + */ +@Service +public class BaseUserRepoImpl extends ServiceImpl implements BaseUserRepo { + +} diff --git a/src/main/java/com/sczx/user/service/IUserService.java b/src/main/java/com/sczx/user/service/IUserService.java index d440a41..77ad33b 100644 --- a/src/main/java/com/sczx/user/service/IUserService.java +++ b/src/main/java/com/sczx/user/service/IUserService.java @@ -1,5 +1,6 @@ package com.sczx.user.service; +import com.sczx.user.dto.LoginResponse; import com.sczx.user.dto.SimpleUserInfoDTO; /** @@ -9,22 +10,37 @@ import com.sczx.user.dto.SimpleUserInfoDTO; */ public interface IUserService { + /** + * 根据code获取openId + * @param code + * @return + */ + String getWxOpenId(String code); + /** + * 根据code获取手机号 + * @param phoneCode + * @return + */ + String getWxPhoneNumber(String phoneCode); + + /** + * 小程序注册 + * @param openId + * @param userName + * @param phoneNumber + * @param avatarUrl + * @return + */ + Boolean miniProgramRegister(String openId, String userName,String phoneNumber,String avatarUrl); /** * 微信小程序登录 * @param code 微信登录code * @return token */ - String miniProgramLogin(String code); + LoginResponse miniProgramLogin(String code); + - /** - * 微信小程序注册 - * @param code 微信登录code - * @param username 用户名 - * @param password 密码 - * @return token - */ - String miniProgramRegister(String code, String username, String password); /** * 支付宝小程序登录 @@ -33,14 +49,7 @@ public interface IUserService { */ String alipayMiniProgramLogin(String userId); - /** - * 支付宝小程序注册 - * @param userId 支付宝用户ID - * @param username 用户名 - * @param password 密码 - * @return token - */ - String alipayMiniProgramRegister(String userId, String username, String password); + /** * 根据小程序ID获取用户信息 diff --git a/src/main/java/com/sczx/user/service/impl/UserServiceImpl.java b/src/main/java/com/sczx/user/service/impl/UserServiceImpl.java index 79dc6db..bc56284 100644 --- a/src/main/java/com/sczx/user/service/impl/UserServiceImpl.java +++ b/src/main/java/com/sczx/user/service/impl/UserServiceImpl.java @@ -1,9 +1,16 @@ package com.sczx.user.service.impl; +import com.alibaba.nacos.common.utils.MD5Utils; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.sczx.user.common.enums.MiniProgramTypeEnum; +import com.sczx.user.convert.UserInfoConvert; +import com.sczx.user.dto.LoginResponse; import com.sczx.user.dto.SimpleUserInfoDTO; import com.sczx.user.exception.BizException; +import com.sczx.user.po.BaseUserPO; +import com.sczx.user.repository.BaseUserRepo; import com.sczx.user.service.IUserService; +import com.sczx.user.thirdpart.integ.WeichatInteg; import com.sczx.user.util.JwtUtil; import com.sczx.user.util.RedisUtil; import lombok.extern.slf4j.Slf4j; @@ -12,6 +19,7 @@ import org.springframework.stereotype.Service; import java.util.HashMap; import java.util.Map; +import java.util.Objects; /** * @Author: 张黎 @@ -38,30 +46,60 @@ public class UserServiceImpl implements IUserService { @Autowired private RedisUtil redisUtil; + @Autowired + private BaseUserRepo baseUserRepo; + + @Autowired + private WeichatInteg weichatInteg; + @Override - public String miniProgramLogin(String code) { - String openid = WECHAT_CODE_TO_OPENID.get(code); + public String getWxOpenId(String code) { + return weichatInteg.getWechatOpenIdByCode(code); + } + + @Override + public String getWxPhoneNumber(String phoneCode) { + String accessToken = weichatInteg.getAccessToken(); + return weichatInteg.getPhoneNumber(accessToken, phoneCode); + } + + @Override + public Boolean miniProgramRegister(String openId, String nickName, String phoneNumber, String avatarUrl) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(BaseUserPO::getPhoneNumber, phoneNumber); + BaseUserPO baseUserPO = baseUserRepo.getOne(queryWrapper); + if(Objects.nonNull(baseUserPO)){ + throw new BizException("该手机号用户已注册"); + } + baseUserPO = new BaseUserPO(); + baseUserPO.setUserName(nickName); + baseUserPO.setNickName(nickName); + baseUserPO.setPhoneNumber(phoneNumber); + baseUserPO.setPassword(MD5Utils.md5Hex("88888888", "UTF-8")); + baseUserPO.setAvatarUrl(avatarUrl); + baseUserPO.setRoleId(1); + baseUserRepo.save(baseUserPO); + return true; + } + + @Override + public LoginResponse miniProgramLogin(String code) { + String openid = getWxOpenId(code); if (openid == null) { throw new BizException("无效的微信登录code"); } // 模拟登录逻辑 SimpleUserInfoDTO simpleUserInfoDTO = getUserInfoByProgramId(openid, MiniProgramTypeEnum.WECHAT.getType()); - return jwtUtil.generateToken(simpleUserInfoDTO, simpleUserInfoDTO.getUserName()); + String token = jwtUtil.generateToken(simpleUserInfoDTO, simpleUserInfoDTO.getUserName()); + + LoginResponse loginResponse = new LoginResponse(); + loginResponse.setToken(token); + loginResponse.setUserInfo(simpleUserInfoDTO); + return loginResponse; } - @Override - public String miniProgramRegister(String code, String username, String password) { - String openid = WECHAT_CODE_TO_OPENID.get(code); - if (openid == null) { - throw new BizException("无效的微信登录code"); - } - // 模拟注册逻辑 - SimpleUserInfoDTO simpleUserInfoDTO = getUserInfoByProgramId(openid, MiniProgramTypeEnum.WECHAT.getType()); - - return jwtUtil.generateToken(simpleUserInfoDTO, simpleUserInfoDTO.getUserName()); - } @Override public String alipayMiniProgramLogin(String userId) { @@ -75,25 +113,24 @@ public class UserServiceImpl implements IUserService { return jwtUtil.generateToken(simpleUserInfoDTO, simpleUserInfoDTO.getUserName()); } - @Override - public String alipayMiniProgramRegister(String userId, String username, String password) { - String realUserId = ALIPAY_ID_TO_USERID.get(userId); - if (realUserId == null) { - throw new BizException("无效的支付宝用户ID"); - } - // 模拟注册逻辑 - SimpleUserInfoDTO simpleUserInfoDTO = getUserInfoByProgramId(realUserId, MiniProgramTypeEnum.ALIPAY.getType()); - - return jwtUtil.generateToken(simpleUserInfoDTO, simpleUserInfoDTO.getUserName()); - } @Override public SimpleUserInfoDTO getUserInfoByProgramId(String programId, String programType) { //todo 根据小程序id和类型查询用户信息 - SimpleUserInfoDTO simpleUserInfoDTO = new SimpleUserInfoDTO(); - simpleUserInfoDTO.setUserId(1); - simpleUserInfoDTO.setUserName("张三"); - simpleUserInfoDTO.setRoleId(1); - return simpleUserInfoDTO; +// SimpleUserInfoDTO simpleUserInfoDTO = new SimpleUserInfoDTO(); +// simpleUserInfoDTO.setUserId(1); +// simpleUserInfoDTO.setUserName("张三"); +// simpleUserInfoDTO.setRoleId(1); +// return simpleUserInfoDTO; + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if(MiniProgramTypeEnum.WECHAT.getType().equalsIgnoreCase(programType)){ + queryWrapper.eq(BaseUserPO::getWechatOpenid, programId).last(" limit 1"); + }else { + queryWrapper.eq(BaseUserPO::getAlipayUserid, programId).last(" limit 1"); + } + + BaseUserPO baseUserPO = baseUserRepo.getOne(queryWrapper); + return UserInfoConvert.INSTANCE.poToSimpleDTO(baseUserPO); } } diff --git a/src/main/java/com/sczx/user/thirdpart/dto/WechatMiniProgramResponse.java b/src/main/java/com/sczx/user/thirdpart/dto/WechatMiniProgramResponse.java new file mode 100644 index 0000000..a5a2195 --- /dev/null +++ b/src/main/java/com/sczx/user/thirdpart/dto/WechatMiniProgramResponse.java @@ -0,0 +1,12 @@ +package com.sczx.user.thirdpart.dto; + +import lombok.Data; + +@Data +public class WechatMiniProgramResponse { + private String openid; + private String session_key; + private String unionid; + private Integer errcode; + private String errmsg; +} diff --git a/src/main/java/com/sczx/user/thirdpart/integ/WeichatInteg.java b/src/main/java/com/sczx/user/thirdpart/integ/WeichatInteg.java new file mode 100644 index 0000000..99a1cf1 --- /dev/null +++ b/src/main/java/com/sczx/user/thirdpart/integ/WeichatInteg.java @@ -0,0 +1,133 @@ +package com.sczx.user.thirdpart.integ; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.sczx.user.thirdpart.dto.WechatMiniProgramResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@Component +public class WeichatInteg { + + @Value("${wechat.miniapp.appid}") + private String appid; + + @Value("${wechat.miniapp.secret}") + private String secret; + + @Value("${wechat.miniapp.apiurl}") + private String apiurl; + + /** + * 通过微信code获取openid和session_key + * @param code 微信登录凭证 + * @return WechatMiniProgramResponse + */ + public WechatMiniProgramResponse getSessionInfoByCode(String code) { + String url = apiurl + "/sns/jscode2session?appid=" + appid + "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code"; + + try { + RestTemplate restTemplate = new RestTemplate(); + String response = restTemplate.getForObject(url, String.class); + + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.readValue(response, WechatMiniProgramResponse.class); + } catch (Exception e) { + log.error("获取微信session信息异常", e); + return null; + } + } + + /** + * 通过微信code获取openid(保持原有方法兼容性) + * @param code 微信登录凭证 + * @return openid + */ + public String getWechatOpenIdByCode(String code) { + WechatMiniProgramResponse response = getSessionInfoByCode(code); + if (response == null) { + return null; + } + + if (response.getErrcode() != null && response.getErrcode() != 0) { + log.error("微信接口调用失败,错误码:{},错误信息:{}", response.getErrcode(), response.getErrmsg()); + return null; + } + + return response.getOpenid(); + } + + /** + * 获取访问令牌(用于调用其他微信接口) + * @return access_token + */ + public String getAccessToken() { + String url = apiurl + "/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret; + + try { + RestTemplate restTemplate = new RestTemplate(); + String response = restTemplate.getForObject(url, String.class); + + ObjectMapper objectMapper = new ObjectMapper(); + Map resultMap = objectMapper.readValue(response, Map.class); + + if (resultMap.containsKey("errcode")) { + log.error("获取access_token失败,错误码:{},错误信息:{}", + resultMap.get("errcode"), resultMap.get("errmsg")); + return null; + } + + return (String) resultMap.get("access_token"); + } catch (Exception e) { + log.error("获取access_token异常", e); + return null; + } + } + + /** + * 通过手机号获取凭证获取用户手机号 + * @param accessToken 访问令牌 + * @param code 手机号获取凭证 + * @return 手机号信息 + */ + public String getPhoneNumber(String accessToken, String code) { + String url = apiurl + "/wxa/business/getuserphonenumber?access_token=" + accessToken; + + try { + RestTemplate restTemplate = new RestTemplate(); + + // 构造请求体 + Map requestBody = new HashMap<>(); + requestBody.put("code", code); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + HttpEntity> requestEntity = new HttpEntity<>(requestBody, headers); + + String response = restTemplate.postForObject(url, requestEntity, String.class); + + ObjectMapper objectMapper = new ObjectMapper(); + Map resultMap = objectMapper.readValue(response, Map.class); + + if (!"0".equals(resultMap.get("errcode").toString())) { + log.error("获取手机号失败,错误码:{},错误信息:{}", + resultMap.get("errcode"), resultMap.get("errmsg")); + return null; + } + Map phoneInfoMap = (Map) resultMap.get("phone_info"); + return (String) phoneInfoMap.get("purePhoneNumber"); + } catch (Exception e) { + log.error("获取手机号异常", e); + return null; + } + } +} diff --git a/src/main/java/com/sczx/user/util/JwtUtil.java b/src/main/java/com/sczx/user/util/JwtUtil.java index ed0aba5..f303984 100644 --- a/src/main/java/com/sczx/user/util/JwtUtil.java +++ b/src/main/java/com/sczx/user/util/JwtUtil.java @@ -10,8 +10,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; import javax.crypto.SecretKey; +import javax.servlet.http.HttpServletRequest; import java.util.Date; import java.util.Map; @@ -91,4 +94,33 @@ public class JwtUtil { } } + public HttpServletRequest getCurrentRequest() { + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + return attributes != null ? attributes.getRequest() : null; + } + + /** + * 获取当前请求的Authorization头内容 + * @return Authorization头的值,如果不存在则返回null + */ + public String getAuthorizationHeader() { + HttpServletRequest request = getCurrentRequest(); + return request != null ? request.getHeader("Authorization") : null; + } + + /** + * 从token中获取用户信息 + * @return 用户信息 + */ + public SimpleUserInfoDTO getUserInfoFromToken() { + String authHeader = getAuthorizationHeader(); + if (authHeader != null && authHeader.startsWith("Bearer ")) { + String token = authHeader.substring(7); + // 进行token验证等操作 + return getClaim(token, "userInfo", SimpleUserInfoDTO.class); + }else { + throw new RuntimeException("token不存在"); + } + } + } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index d6375fb..cfc2b03 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -63,3 +63,10 @@ mybatis-plus: auth: secret-key: his-is-a-very-long-and-secure-secret-key-for-jwt-signing-please-dont-use-short-keys token-expiration: 86400000 # 24小时 + +wechat: + miniapp: + apiurl: https://api.weixin.qq.com + appid: wx25e1ad1a70c326de + secret: your_secret + grantType: authorization_code \ No newline at end of file diff --git a/src/main/resources/mapper/BaseUserMapper.xml b/src/main/resources/mapper/BaseUserMapper.xml new file mode 100644 index 0000000..b3619d7 --- /dev/null +++ b/src/main/resources/mapper/BaseUserMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/test/java/com/sczx/user/CodeGenerator.java b/src/test/java/com/sczx/user/CodeGenerator.java index 16994ad..a2bbdd9 100644 --- a/src/test/java/com/sczx/user/CodeGenerator.java +++ b/src/test/java/com/sczx/user/CodeGenerator.java @@ -10,7 +10,7 @@ import java.util.Collections; public class CodeGenerator { - private static final String parentPackage = "com.sczx.store"; + private static final String parentPackage = "com.sczx.user"; private static final String jdbcUrl = "jdbc:mysql://115.190.8.52:3306/sczx?useUnicode=true&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&useSSL=false&serverTimezone=Asia/Shanghai"; private static final String username = "sczx_user"; private static final String password = "Sczx123@"; @@ -25,8 +25,8 @@ public class CodeGenerator { .dateType(DateType.TIME_PACK).commentDate("yyyy-MM-dd HH:mm:ss") .fileOverride()) // 包配置 - .packageConfig(builder -> builder.parent(parentPackage).entity("po.base").service("repository.base").serviceImpl("repository.impl.base").xml("") - .mapper("mapper.base").pathInfo(Collections.singletonMap(OutputFile.mapperXml, System.getProperty("user.dir") + "/src/main/resources/mapper/base"))) + .packageConfig(builder -> builder.parent(parentPackage).entity("po").service("repository").serviceImpl("repository.impl").xml("") + .mapper("mapper").pathInfo(Collections.singletonMap(OutputFile.mapperXml, System.getProperty("user.dir") + "/src/main/resources/mapper"))) // 策略配置 .strategyConfig((scanner, builder) -> builder.addInclude(scanner.apply("请输入表名:"))