feat(微信用户): 实现微信用户自动创建及信息获取功能

新增微信昵称生成器工具类,用于生成随机昵称
在WxUserApplicationService中添加getOrCreateUserByOpenid方法,实现用户不存在时自动创建
修改WxController的mpCodeToOpenId接口返回完整用户信息
新增getWxUserByOpenid接口用于获取用户信息
This commit is contained in:
dzq 2025-11-06 10:11:37 +08:00
parent 03b50542fa
commit 147194a116
4 changed files with 125 additions and 3 deletions

View File

@ -1,3 +1,4 @@
{
"java.jdt.ls.vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx2G -Xms100m -Xlog:disable"
"java.jdt.ls.vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx2G -Xms100m -Xlog:disable",
"java.compile.nullAnalysis.mode": "automatic"
}

View File

@ -6,11 +6,15 @@ import com.agileboot.common.core.dto.ResponseDTO;
import com.agileboot.common.exception.ApiException;
import com.agileboot.common.exception.error.ErrorCode;
import com.agileboot.domain.wx.WxService;
import com.agileboot.domain.wx.user.WxUserApplicationService;
import com.agileboot.domain.wx.user.dto.WxUserDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestClientException;
@ -25,6 +29,8 @@ import java.util.Map;
public class WxController {
private final WxService wxService;
private final WxUserApplicationService wxUserApplicationService;
/**
* 获取小程序用户OpenID
* @param code 微信授权码
@ -32,14 +38,40 @@ public class WxController {
* @throws ApiException 当code无效或微信接口调用失败时抛出
*/
@GetMapping("/mpCodeToOpenId")
public ResponseDTO<String> mpCodeToOpenId(String code) {
public ResponseDTO<WxUserDTO> mpCodeToOpenId(String code) {
try {
String openid = wxService.getSmallOpenid(code);
// 校验openid是否为空
if (StringUtils.isBlank(openid)) {
throw new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, "根据code获取openid失败");
}
return ResponseDTO.ok(openid);
return ResponseDTO.ok(wxUserApplicationService.getOrCreateUserByOpenid(openid));
} catch (Exception e) {
log.error("获取openid失败", e);
return ResponseDTO.fail(new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, e.getMessage()));
}
}
/**
* 根据openid获取微信用户信息
* @param openid 微信用户openid
* @return 微信用户信息
* @throws ApiException 当openid无效或用户不存在时抛出
*/
@GetMapping("/getWxUserByOpenid")
public ResponseDTO<WxUserDTO> getWxUserByOpenid(@RequestParam("openid") String openid) {
try {
WxUserDTO wxUserDTO = wxUserApplicationService.getUserDetailByOpenid(openid);
if (wxUserDTO == null) {
return ResponseDTO.fail(new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, "用户不存在"));
}
return ResponseDTO.ok(wxUserDTO);
} catch (Exception e) {
log.error("获取微信用户信息失败", e);
return ResponseDTO.fail(new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, e.getMessage()));
}
}
}

View File

@ -2,6 +2,7 @@ package com.agileboot.domain.wx.user;
import com.agileboot.common.core.page.PageDTO;
import com.agileboot.domain.common.command.BulkOperationCommand;
import com.agileboot.domain.wx.utils.WxNicknameGenerator;
import com.agileboot.domain.wx.user.command.AddWxUserCommand;
import com.agileboot.domain.wx.user.command.UpdateWxUserCommand;
import com.agileboot.domain.wx.user.db.SearchWxUserDO;
@ -166,4 +167,39 @@ public class WxUserApplicationService {
// 更新
model.updateById();
}
/**
* 根据openid获取或创建微信用户
* 如果openid对应数据不存在则创建一条新数据到数据库
*
* @param openid 微信openid
* @return 微信用户信息
*/
@Transactional(rollbackFor = Exception.class)
public WxUserDTO getOrCreateUserByOpenid(String openid) {
// 先尝试查询用户
WxUserDTO userDTO = getUserDetailByOpenid(openid);
// 如果用户不存在则创建新用户
if (userDTO == null) {
AddWxUserCommand command = new AddWxUserCommand();
command.setOpenid(openid);
command.setNickName(WxNicknameGenerator.generateRandomNickname()); // 使用昵称生成器生成随机昵称
// 保存新用户
WxUserModel model = modelFactory.create();
model.loadAddWxUserCommand(command);
// 业务校验只校验openid唯一性因为是新用户其他字段有默认值
model.checkOpenidIsUnique();
// 保存
model.insert();
// 返回新创建的用户信息
userDTO = getUserDetailByOpenid(openid);
}
return userDTO;
}
}

View File

@ -0,0 +1,53 @@
package com.agileboot.domain.wx.utils;
import java.security.SecureRandom;
/**
* 微信昵称生成器
* 生成格式固定前缀_随机6位大小写字母数字
*
* @author your-name
* @since 2025-01-01
*/
public class WxNicknameGenerator {
private static final String PREFIX = "微信用户";
private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
private static final int RANDOM_LENGTH = 6;
private static final SecureRandom random = new SecureRandom();
/**
* 生成随机昵称
* 格式微信用户_XXXXXX其中XXXXXX为6位随机大小写字母数字
*
* @return 生成的昵称
*/
public static String generateRandomNickname() {
StringBuilder randomPart = new StringBuilder(RANDOM_LENGTH);
for (int i = 0; i < RANDOM_LENGTH; i++) {
int index = random.nextInt(CHARACTERS.length());
randomPart.append(CHARACTERS.charAt(index));
}
return PREFIX + "_" + randomPart.toString();
}
/**
* 生成指定前缀的随机昵称
* 格式{前缀}_XXXXXX其中XXXXXX为6位随机大小写字母数字
*
* @param prefix 自定义前缀
* @return 生成的昵称
*/
public static String generateRandomNickname(String prefix) {
StringBuilder randomPart = new StringBuilder(RANDOM_LENGTH);
for (int i = 0; i < RANDOM_LENGTH; i++) {
int index = random.nextInt(CHARACTERS.length());
randomPart.append(CHARACTERS.charAt(index));
}
return prefix + "_" + randomPart.toString();
}
}