前言:
目前我们生成的是6位包含数字和大小写字母的随机邀请码, 并且代码中已经有了处理冲突的机制确保了邀请码的唯一性如(①生成随机邀请码后会检查数据库中是否已存在②如果存在冲突,会尝试最多10次重新生成③如果多次尝试仍失败,会使用"U"+用户ID派生的备选方案), 所以您不用担心会有两个用户拥有完全相同的邀请码的情况,系统已经设计了防止这种情况发生的机制。
理论容量:
- 可用字符集:26个小写字母 + 26个大写字母 + 10个数字 = 62个字符
- 6位组合的可能性:62^6 = 56,800,235,584种可能组合,绝对的量大管饱.
1. askController.java
import java.util.Map;
import java.util.HashMap;
/**
* 随机生成邀请码
* 如果用户已经有邀请码,则直接返回已有的邀请码
* 如果用户没有邀请码,则生成新的邀请码并保存
*
* @param userId 用户ID
* @return 用户的邀请码
*/
@GetMapping("/random/{userId}")
public Map<String, Object> generateRandomCode(@PathVariable Long userId) {
Map<String, Object> result = new HashMap<>();
if (userId == null || userId <= 0) {
result.put("code", 400);
result.put("message", "用户ID不能为空");
return result;
}
try {
String invitationCode = askService.generateInvitationCode(userId);
result.put("code", 200);
result.put("message", "获取邀请码成功");
result.put("data", invitationCode);
} catch (Exception e) {
result.put("code", 500);
result.put("message", "获取邀请码失败:" + e.getMessage());
}
return result;
}
2. askService.java
/**
* 生成并保存邀请码
*
* @param userId 用户ID
* @return 生成的邀请码
*/
String generateInvitationCode(Long userId);
3. askServiceImpl.java
/**
* 生成并保存邀请码
*
* @param userId 用户ID
* @return 生成的邀请码
*/
@Override
public String generateInvitationCode(Long userId) {
// 先检查该用户是否已有邀请码(注意此处根据自己实际情况填写)
GJSJQKTX gjsjqktx = askMapper.getByUserId(userId);
// 如果用户已有邀请码且不为空,则直接返回已有的邀请码
if (gjsjqktx != null && gjsjqktx.getPzProxyInvite() != null && !gjsjqktx.getPzProxyInvite().isEmpty()) {
return gjsjqktx.getPzProxyInvite();
}
// 否则生成新的邀请码
String invitationCode = "";//用来存储最终生成的邀请码
boolean isUnique = false; //用来指示生成的邀请码是否在数据库中唯一
int maxAttempts = 10; //最大尝试次数,避免无限循环
int attempts = 0;//这是计数器,记录已经尝试生成随机邀请码的次数
while (!isUnique && attempts < maxAttempts) {
// 使用随机字符串生成器生成6位随机码
invitationCode = generateRandomString(6);
// 检查邀请码是否已存在
isUnique = !askMapper.checkInvitationCodeExists(invitationCode);
attempts++;
}
if (!isUnique) {
// 如果尝试多次后仍无法生成唯一邀请码,使用userId作为前缀
invitationCode = "U" + String.format("%05d", userId % 100000);
// 确保这个也不存在
if (askMapper.checkInvitationCodeExists(invitationCode)) {
// 如果还存在,则添加一个随机后缀
invitationCode = invitationCode.substring(0, 5) + generateRandomString(1);
}
}
// 更新用户邀请码
askMapper.updateInvitationCode(userId, invitationCode);
return invitationCode;
}
/**
* 生成指定长度的随机字符串,包含数字和大小写字母
*
* @param length 字符串长度
* @return 随机字符串
*/
private String generateRandomString(int length) {
String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
StringBuilder result = new StringBuilder(length);
Random random = new Random();
for (int i = 0; i < length; i++) {
result.append(characters.charAt(random.nextInt(characters.length())));
}
return result.toString();
}
4. askMapper.java
/**
* 先检查该用户是否已有邀请码(注意此处根据自己实际情况填写)
*
*/
gjsjqktx getEscortInfoByUserId(Long userId);
/**
* 检查邀请码是否已存在
*
* @param invitationCode 邀请码
* @return 如果存在返回true,否则返回false
*/
boolean checkInvitationCodeExists(@Param("invitationCode") String invitationCode);
/**
* 更新用户的邀请码
*
* @param userId 用户ID
* @param invitationCode 邀请码
* @return 影响的行数
*/
int updateInvitationCode(@Param("userId") Long userId, @Param("invitationCode") String invitationCode);
5. askMapper.xml
<!-- 先检查该用户是否已有邀请码(注意此处根据自己实际情况填写) -->
<select id="getEscortInfoByUserId" parameterType="Long" resultMap="PzPatientEscortResult">
select * from 表名 WHERE user_id = #{userId}
</select>
<!-- 检查邀请码是否已存在(注意此处根据自己实际情况填写) -->
<select id="checkInvitationCodeExists" resultType="boolean">
SELECT COUNT(*) > 0 FROM 表名 WHERE pz_proxy_invite = #{invitationCode}
</select>
<!-- 更新用户的邀请码(注意此处根据自己实际情况填写) -->
<update id="updateInvitationCode">
UPDATE 表名 SET pz_proxy_invite = #{invitationCode} WHERE user_id = #{userId}
</update>
1054

被折叠的 条评论
为什么被折叠?



