diff --git a/src/main/java/com/yolo/keyborad/controller/UserController.java b/src/main/java/com/yolo/keyborad/controller/UserController.java index cb747fb..ed03069 100644 --- a/src/main/java/com/yolo/keyborad/controller/UserController.java +++ b/src/main/java/com/yolo/keyborad/controller/UserController.java @@ -8,19 +8,19 @@ import com.yolo.keyborad.model.dto.AppleLoginReq; import com.yolo.keyborad.model.dto.user.*; import com.yolo.keyborad.model.entity.KeyboardFeedback; import com.yolo.keyborad.model.entity.KeyboardUser; +import com.yolo.keyborad.model.entity.KeyboardUserInviteCodes; +import com.yolo.keyborad.model.vo.user.InviteCodeRespVO; import com.yolo.keyborad.model.vo.user.KeyboardUserInfoRespVO; import com.yolo.keyborad.model.vo.user.KeyboardUserRespVO; import com.yolo.keyborad.service.IAppleService; +import com.yolo.keyborad.service.KeyboardUserInviteCodesService; import com.yolo.keyborad.service.UserService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; -import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.BeanUtils; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.text.SimpleDateFormat; @@ -46,6 +46,9 @@ public class UserController { @Resource private com.yolo.keyborad.service.KeyboardFeedbackService feedbackService; + @Resource + private KeyboardUserInviteCodesService inviteCodesService; + /** * 苹果登录 * @@ -130,5 +133,13 @@ public class UserController { return ResultUtils.success(feedbackService.save(feedback)); } + @GetMapping("/inviteCode") + @Operation(summary = "查询邀请码", description = "查询用户自己的邀请码") + public BaseResponse getInviteCode() { + long userId = StpUtil.getLoginIdAsLong(); + KeyboardUserInviteCodes inviteCode = inviteCodesService.getUserInviteCode(userId); + InviteCodeRespVO respVO = BeanUtil.copyProperties(inviteCode, InviteCodeRespVO.class); + return ResultUtils.success(respVO); + } } \ No newline at end of file diff --git a/src/main/java/com/yolo/keyborad/mapper/KeyboardUserInviteCodesMapper.java b/src/main/java/com/yolo/keyborad/mapper/KeyboardUserInviteCodesMapper.java new file mode 100644 index 0000000..0f43cd3 --- /dev/null +++ b/src/main/java/com/yolo/keyborad/mapper/KeyboardUserInviteCodesMapper.java @@ -0,0 +1,12 @@ +package com.yolo.keyborad.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.yolo.keyborad.model.entity.KeyboardUserInviteCodes; + +/* +* @author: ziin +* @date: 2025/12/18 16:26 +*/ + +public interface KeyboardUserInviteCodesMapper extends BaseMapper { +} \ No newline at end of file diff --git a/src/main/java/com/yolo/keyborad/model/entity/KeyboardUserInviteCodes.java b/src/main/java/com/yolo/keyborad/model/entity/KeyboardUserInviteCodes.java new file mode 100644 index 0000000..2f444ab --- /dev/null +++ b/src/main/java/com/yolo/keyborad/model/entity/KeyboardUserInviteCodes.java @@ -0,0 +1,78 @@ +package com.yolo.keyborad.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.Date; +import lombok.Data; + +/* +* @author: ziin +* @date: 2025/12/18 16:26 +*/ + +/** + * 用户生成的邀请码表,用于邀请新用户注册/安装并建立邀请关系 + */ +@Schema(description="用户生成的邀请码表,用于邀请新用户注册/安装并建立邀请关系") +@Data +@TableName(value = "keyboard_user_invite_codes") +public class KeyboardUserInviteCodes { + /** + * 邀请码主键ID + */ + @TableId(value = "id", type = IdType.AUTO) + @Schema(description="邀请码主键ID") + private Long id; + + /** + * 邀请码字符串,对外展示,唯一 + */ + @TableField(value = "code") + @Schema(description="邀请码字符串,对外展示,唯一") + private String code; + + /** + * 邀请码所属用户ID(邀请人) + */ + @TableField(value = "owner_user_id") + @Schema(description="邀请码所属用户ID(邀请人)") + private Long ownerUserId; + + /** + * 邀请码状态:1=启用,0=停用 + */ + @TableField(value = "\"status\"") + @Schema(description="邀请码状态:1=启用,0=停用") + private Short status; + + /** + * 邀请码创建时间 + */ + @TableField(value = "created_at") + @Schema(description="邀请码创建时间") + private Date createdAt; + + /** + * 邀请码过期时间,NULL表示永久有效 + */ + @TableField(value = "expires_at") + @Schema(description="邀请码过期时间,NULL表示永久有效") + private Date expiresAt; + + /** + * 邀请码最大可使用次数,NULL表示不限次数 + */ + @TableField(value = "max_uses") + @Schema(description="邀请码最大可使用次数,NULL表示不限次数") + private Integer maxUses; + + /** + * 邀请码已使用次数 + */ + @TableField(value = "used_count") + @Schema(description="邀请码已使用次数") + private Integer usedCount; +} \ No newline at end of file diff --git a/src/main/java/com/yolo/keyborad/model/vo/user/InviteCodeRespVO.java b/src/main/java/com/yolo/keyborad/model/vo/user/InviteCodeRespVO.java new file mode 100644 index 0000000..f9c155f --- /dev/null +++ b/src/main/java/com/yolo/keyborad/model/vo/user/InviteCodeRespVO.java @@ -0,0 +1,29 @@ +package com.yolo.keyborad.model.vo.user; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.Date; + +/** + * 邀请码响应VO + */ +@Data +@Schema(description = "邀请码信息") +public class InviteCodeRespVO { + + @Schema(description = "邀请码") + private String code; + + @Schema(description = "邀请码状态:1=启用,0=停用") + private Short status; + + @Schema(description = "已使用次数") + private Integer usedCount; + + @Schema(description = "最大可使用次数") + private Integer maxUses; + + @Schema(description = "过期时间") + private Date expiresAt; +} diff --git a/src/main/java/com/yolo/keyborad/service/KeyboardUserInviteCodesService.java b/src/main/java/com/yolo/keyborad/service/KeyboardUserInviteCodesService.java new file mode 100644 index 0000000..12df1df --- /dev/null +++ b/src/main/java/com/yolo/keyborad/service/KeyboardUserInviteCodesService.java @@ -0,0 +1,26 @@ +package com.yolo.keyborad.service; + +import com.yolo.keyborad.model.entity.KeyboardUserInviteCodes; +import com.baomidou.mybatisplus.extension.service.IService; + /* +* @author: ziin +* @date: 2025/12/18 16:26 +*/ + +public interface KeyboardUserInviteCodesService extends IService{ + + /** + * 获取用户的邀请码 + * @param userId 用户ID + * @return 邀请码实体 + */ + KeyboardUserInviteCodes getUserInviteCode(Long userId); + + /** + * 为用户创建邀请码 + * @param userId 用户ID + * @return 创建的邀请码实体 + */ + KeyboardUserInviteCodes createInviteCode(Long userId); + +} diff --git a/src/main/java/com/yolo/keyborad/service/impl/KeyboardUserInviteCodesServiceImpl.java b/src/main/java/com/yolo/keyborad/service/impl/KeyboardUserInviteCodesServiceImpl.java new file mode 100644 index 0000000..4256c23 --- /dev/null +++ b/src/main/java/com/yolo/keyborad/service/impl/KeyboardUserInviteCodesServiceImpl.java @@ -0,0 +1,66 @@ +package com.yolo.keyborad.service.impl; + +import cn.hutool.core.util.RandomUtil; +import org.springframework.stereotype.Service; +import org.springframework.beans.factory.annotation.Autowired; +import java.util.Date; +import java.util.List; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.yolo.keyborad.mapper.KeyboardUserInviteCodesMapper; +import com.yolo.keyborad.model.entity.KeyboardUserInviteCodes; +import com.yolo.keyborad.service.KeyboardUserInviteCodesService; +/* +* @author: ziin +* @date: 2025/12/18 16:26 +*/ + +@Service +public class KeyboardUserInviteCodesServiceImpl extends ServiceImpl implements KeyboardUserInviteCodesService{ + + @Override + public KeyboardUserInviteCodes getUserInviteCode(Long userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("owner_user_id", userId); + return this.getOne(queryWrapper); + } + + @Override + public KeyboardUserInviteCodes createInviteCode(Long userId) { + // 生成唯一的邀请码 + String code; + int maxRetries = 10; + int retryCount = 0; + + do { + // 生成8位字母数字组合的邀请码 + code = RandomUtil.randomString(8).toUpperCase(); + + // 检查邀请码是否已存在 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("code", code); + KeyboardUserInviteCodes existingCode = this.getOne(queryWrapper); + + if (existingCode == null) { + break; + } + + retryCount++; + } while (retryCount < maxRetries); + + // 创建邀请码实体 + KeyboardUserInviteCodes inviteCode = new KeyboardUserInviteCodes(); + inviteCode.setCode(code); + inviteCode.setOwnerUserId(userId); + inviteCode.setStatus((short) 1); // 启用状态 + inviteCode.setCreatedAt(new Date()); + inviteCode.setExpiresAt(null); // 永久有效 + inviteCode.setMaxUses(null); // 不限次数 + inviteCode.setUsedCount(0); // 初始使用次数为0 + + // 保存到数据库 + this.save(inviteCode); + + return inviteCode; + } +} diff --git a/src/main/java/com/yolo/keyborad/service/impl/UserServiceImpl.java b/src/main/java/com/yolo/keyborad/service/impl/UserServiceImpl.java index f87d943..563c9f3 100644 --- a/src/main/java/com/yolo/keyborad/service/impl/UserServiceImpl.java +++ b/src/main/java/com/yolo/keyborad/service/impl/UserServiceImpl.java @@ -62,6 +62,9 @@ public class UserServiceImpl extends ServiceImpl + + + + + + + + + + + + + + + + + id, code, owner_user_id, "status", created_at, expires_at, max_uses, used_count + + \ No newline at end of file