diff --git a/keyboard-server/src/main/java/com/yolo/keyboard/api/invitecode/UserInviteCodeApiImpl.java b/keyboard-server/src/main/java/com/yolo/keyboard/api/invitecode/UserInviteCodeApiImpl.java new file mode 100644 index 0000000..74c1df7 --- /dev/null +++ b/keyboard-server/src/main/java/com/yolo/keyboard/api/invitecode/UserInviteCodeApiImpl.java @@ -0,0 +1,55 @@ +package com.yolo.keyboard.api.invitecode; + +import cn.hutool.core.util.RandomUtil; +import com.yolo.keyboard.dal.dataobject.userinvitecodes.KeyboardUserInviteCodesDO; +import com.yolo.keyboard.dal.mysql.userinvitecodes.KeyboardUserInviteCodesMapper; +import com.yolo.keyboard.module.system.api.invitecode.UserInviteCodeApi; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; + +/** + * 用户邀请码 API 实现类 + * + * @author ziin + */ +@Service +public class UserInviteCodeApiImpl implements UserInviteCodeApi { + + @Resource + private KeyboardUserInviteCodesMapper userInviteCodesMapper; + + @Override + public String createInviteCodeForAgent(Long userId, Long tenantId) { + String inviteCode = generateUniqueInviteCode(); + KeyboardUserInviteCodesDO inviteCodeDO = KeyboardUserInviteCodesDO.builder() + .code(inviteCode) + .ownerSystemUserId(userId) + .ownerTenantId(tenantId) + .status((short) 1) + .createdAt(LocalDateTime.now()) + .usedCount(0) + .inviteType("AGENT") + .build(); + userInviteCodesMapper.insert(inviteCodeDO); + return inviteCode; + } + + /** + * 生成唯一的6位邀请码(字母和数字混合) + */ + private String generateUniqueInviteCode() { + String code; + int maxAttempts = 100; + int attempt = 0; + do { + code = RandomUtil.randomString("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 6); + attempt++; + if (attempt >= maxAttempts) { + throw new RuntimeException("无法生成唯一的邀请码,请稍后重试"); + } + } while (userInviteCodesMapper.selectOne(KeyboardUserInviteCodesDO::getCode, code) != null); + return code; + } +} diff --git a/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/userinvitecodes/vo/KeyboardUserInviteCodesPageReqVO.java b/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/userinvitecodes/vo/KeyboardUserInviteCodesPageReqVO.java index dc6ae7e..7c9505e 100644 --- a/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/userinvitecodes/vo/KeyboardUserInviteCodesPageReqVO.java +++ b/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/userinvitecodes/vo/KeyboardUserInviteCodesPageReqVO.java @@ -41,7 +41,7 @@ public class KeyboardUserInviteCodesPageReqVO extends PageParam { private Long ownerTenantId; @Schema(description = "邀请码所属系统用户", example = "772") - private Long owenrSystemUserId; + private Long ownerSystemUserId; @Schema(description = "邀请码类型", example = "1") private String inviteType; diff --git a/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/userinvitecodes/vo/KeyboardUserInviteCodesRespVO.java b/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/userinvitecodes/vo/KeyboardUserInviteCodesRespVO.java index 76819c6..aeeb7a1 100644 --- a/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/userinvitecodes/vo/KeyboardUserInviteCodesRespVO.java +++ b/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/userinvitecodes/vo/KeyboardUserInviteCodesRespVO.java @@ -54,7 +54,7 @@ public class KeyboardUserInviteCodesRespVO { @Schema(description = "邀请码所属系统用户", example = "772") @ExcelProperty("邀请码所属系统用户") - private Long owenrSystemUserId; + private Long ownerSystemUserId; @Schema(description = "邀请码类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @ExcelProperty("邀请码类型") diff --git a/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/userinvitecodes/vo/KeyboardUserInviteCodesSaveReqVO.java b/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/userinvitecodes/vo/KeyboardUserInviteCodesSaveReqVO.java index 6bee6fa..f080ea0 100644 --- a/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/userinvitecodes/vo/KeyboardUserInviteCodesSaveReqVO.java +++ b/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/userinvitecodes/vo/KeyboardUserInviteCodesSaveReqVO.java @@ -47,7 +47,7 @@ public class KeyboardUserInviteCodesSaveReqVO { private Long ownerTenantId; @Schema(description = "邀请码所属系统用户", example = "772") - private Long owenrSystemUserId; + private Long ownerSystemUserId; @Schema(description = "邀请码类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @NotEmpty(message = "邀请码类型不能为空") diff --git a/keyboard-server/src/main/java/com/yolo/keyboard/dal/dataobject/userinvitecodes/KeyboardUserInviteCodesDO.java b/keyboard-server/src/main/java/com/yolo/keyboard/dal/dataobject/userinvitecodes/KeyboardUserInviteCodesDO.java index 5c60a18..510ca83 100644 --- a/keyboard-server/src/main/java/com/yolo/keyboard/dal/dataobject/userinvitecodes/KeyboardUserInviteCodesDO.java +++ b/keyboard-server/src/main/java/com/yolo/keyboard/dal/dataobject/userinvitecodes/KeyboardUserInviteCodesDO.java @@ -14,7 +14,7 @@ import com.yolo.keyboard.framework.mybatis.core.dataobject.BaseDO; * @author ziin */ @TableName("keyboard_user_invite_codes") -@KeySequence("keyboard_user_invite_codes_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@KeySequence("invite_codes_id_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data @ToString(callSuper = true) @Builder @@ -67,7 +67,7 @@ public class KeyboardUserInviteCodesDO { /** * 邀请码所属系统用户 */ - private Long owenrSystemUserId; + private Long ownerSystemUserId; /** * 邀请码类型 */ diff --git a/keyboard-server/src/main/java/com/yolo/keyboard/dal/mysql/userinvitecodes/KeyboardUserInviteCodesMapper.java b/keyboard-server/src/main/java/com/yolo/keyboard/dal/mysql/userinvitecodes/KeyboardUserInviteCodesMapper.java index 45777c1..b7fdcc3 100644 --- a/keyboard-server/src/main/java/com/yolo/keyboard/dal/mysql/userinvitecodes/KeyboardUserInviteCodesMapper.java +++ b/keyboard-server/src/main/java/com/yolo/keyboard/dal/mysql/userinvitecodes/KeyboardUserInviteCodesMapper.java @@ -28,7 +28,7 @@ public interface KeyboardUserInviteCodesMapper extends BaseMapperX redisTemplate; + @Override public Long createThemes(KeyboardThemesSaveReqVO createReqVO) { // 插入 KeyboardThemesDO themes = BeanUtils.toBean(createReqVO, KeyboardThemesDO.class); themesMapper.insert(themes); + // 同步更新 Redis 缓存 + refreshThemeStyleCache(themes.getThemeStyle()); + // 返回 return themes.getId(); } @@ -47,25 +54,57 @@ public class KeyboardThemesServiceImpl implements KeyboardThemesService { @Override public void updateThemes(KeyboardThemesSaveReqVO updateReqVO) { // 校验存在 + KeyboardThemesDO oldTheme = themesMapper.selectById(updateReqVO.getId()); validateThemesExists(updateReqVO.getId()); + // 更新 KeyboardThemesDO updateObj = BeanUtils.toBean(updateReqVO, KeyboardThemesDO.class); themesMapper.updateById(updateObj); + + // 同步更新 Redis 缓存(如果风格变更,需要刷新新旧两个风格的缓存) + refreshThemeStyleCache(updateReqVO.getThemeStyle()); + if (oldTheme != null && oldTheme.getThemeStyle() != null + && !oldTheme.getThemeStyle().equals(updateReqVO.getThemeStyle())) { + refreshThemeStyleCache(oldTheme.getThemeStyle()); + } } @Override public void deleteThemes(Long id) { // 校验存在 + KeyboardThemesDO theme = themesMapper.selectById(id); validateThemesExists(id); + // 删除 themesMapper.deleteById(id); + + // 同步更新 Redis 缓存 + if (theme != null && theme.getThemeStyle() != null) { + refreshThemeStyleCache(theme.getThemeStyle()); + } } @Override - public void deleteThemesListByIds(List ids) { + public void deleteThemesListByIds(List ids) { + // 获取要删除的主题列表,记录其风格 + List themes = themesMapper.selectBatchIds(ids); + Set styleIds = new HashSet<>(); + if (CollUtil.isNotEmpty(themes)) { + for (KeyboardThemesDO theme : themes) { + if (theme.getThemeStyle() != null) { + styleIds.add(theme.getThemeStyle()); + } + } + } + // 删除 themesMapper.deleteByIds(ids); + + // 同步更新 Redis 缓存 + for (Long styleId : styleIds) { + refreshThemeStyleCache(styleId); } + } private void validateThemesExists(Long id) { @@ -84,4 +123,32 @@ public class KeyboardThemesServiceImpl implements KeyboardThemesService { return themesMapper.selectPage(pageReqVO); } + /** + * 刷新主题风格缓存 + * + * @param styleId 风格ID + */ + private void refreshThemeStyleCache(Long styleId) { + if (styleId == null) { + return; + } + + // 1. 刷新指定风格的缓存 + String styleKey = THEME_STYLE_KEY_PREFIX + styleId; + List themesByStyle = themesMapper.selectList(KeyboardThemesDO::getThemeStyle, styleId); + if (CollUtil.isNotEmpty(themesByStyle)) { + redisTemplate.opsForValue().set(styleKey, themesByStyle); + } else { + redisTemplate.delete(styleKey); + } + + // 2. 刷新全部主题缓存(theme:style:all) + List allThemes = themesMapper.selectList(); + if (CollUtil.isNotEmpty(allThemes)) { + redisTemplate.opsForValue().set(THEME_STYLE_ALL_KEY, allThemes); + } else { + redisTemplate.delete(THEME_STYLE_ALL_KEY); + } + } + } \ No newline at end of file diff --git a/yolo-module-system/src/main/java/com/yolo/keyboard/module/system/api/invitecode/UserInviteCodeApi.java b/yolo-module-system/src/main/java/com/yolo/keyboard/module/system/api/invitecode/UserInviteCodeApi.java new file mode 100644 index 0000000..1029e89 --- /dev/null +++ b/yolo-module-system/src/main/java/com/yolo/keyboard/module/system/api/invitecode/UserInviteCodeApi.java @@ -0,0 +1,19 @@ +package com.yolo.keyboard.module.system.api.invitecode; + +/** + * 用户邀请码 API 接口 + * + * @author ziin + */ +public interface UserInviteCodeApi { + + /** + * 为代理租户创建邀请码 + * + * @param userId 系统用户ID + * @param tenantId 租户ID + * @return 生成的邀请码 + */ + String createInviteCodeForAgent(Long userId, Long tenantId); + +} diff --git a/yolo-module-system/src/main/java/com/yolo/keyboard/module/system/service/tenant/TenantServiceImpl.java b/yolo-module-system/src/main/java/com/yolo/keyboard/module/system/service/tenant/TenantServiceImpl.java index 1f3250e..311ce47 100644 --- a/yolo-module-system/src/main/java/com/yolo/keyboard/module/system/service/tenant/TenantServiceImpl.java +++ b/yolo-module-system/src/main/java/com/yolo/keyboard/module/system/service/tenant/TenantServiceImpl.java @@ -21,6 +21,7 @@ import com.yolo.keyboard.module.system.dal.dataobject.permission.RoleDO; import com.yolo.keyboard.module.system.dal.dataobject.tenant.TenantDO; import com.yolo.keyboard.module.system.dal.dataobject.tenant.TenantPackageDO; import com.yolo.keyboard.module.system.dal.mysql.tenant.TenantMapper; +import com.yolo.keyboard.module.system.api.invitecode.UserInviteCodeApi; import com.yolo.keyboard.module.system.enums.permission.RoleCodeEnum; import com.yolo.keyboard.module.system.enums.permission.RoleTypeEnum; import com.yolo.keyboard.module.system.service.permission.MenuService; @@ -75,6 +76,9 @@ public class TenantServiceImpl implements TenantService { @Resource private PermissionService permissionService; + @Autowired(required = false) + private UserInviteCodeApi userInviteCodeApi; + @Override public List getTenantIdList() { List tenants = tenantMapper.selectList(); @@ -135,6 +139,10 @@ public class TenantServiceImpl implements TenantService { Long userId = createUser(roleId, createReqVO); // 修改租户的管理员 tenantMapper.updateById(new TenantDO().setId(tenant.getId()).setContactUserId(userId)); + // 为代理租户创建邀请码 + if ("代理".equals(createReqVO.getTenantType()) && userInviteCodeApi != null) { + userInviteCodeApi.createInviteCodeForAgent(userId, tenant.getId()); + } }); return tenant.getId(); }