feat(config): 接入 Nacos 配置中心
- 新增 AppConfig、NacosAppConfigCenter 动态配置类 - 将 userRegisterProperties 的默认值改为运行时从 Nacos 读取 - 注册/创建用户时免费配额改为动态配置获取 - 增加 nacos-client 依赖并配置 dev 环境连接信息
This commit is contained in:
24
src/main/java/com/yolo/keyborad/config/AppConfig.java
Normal file
24
src/main/java/com/yolo/keyborad/config/AppConfig.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package com.yolo.keyborad.config;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/*
|
||||
* @author: ziin
|
||||
* @date: 2025/12/16 21:18
|
||||
*/
|
||||
@Data
|
||||
public class AppConfig {
|
||||
|
||||
private UserRegisterProperties userRegisterProperties = new UserRegisterProperties();
|
||||
|
||||
|
||||
@Data
|
||||
public static class UserRegisterProperties {
|
||||
|
||||
/**
|
||||
* 新用户注册时的免费使用次数
|
||||
*/
|
||||
private Integer freeTrialQuota = 5;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.yolo.keyborad.config;
|
||||
|
||||
import com.alibaba.nacos.api.NacosFactory;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.listener.Listener;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class NacosAppConfigCenter {
|
||||
|
||||
private final ObjectMapper yamlMapper = new ObjectMapper(new YAMLFactory())
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
|
||||
@Bean
|
||||
public ConfigService nacosConfigService(
|
||||
@Value("${nacos.config.server-addr}") String serverAddr
|
||||
) throws NacosException {
|
||||
Properties p = new Properties();
|
||||
p.put("serverAddr", serverAddr);
|
||||
return NacosFactory.createConfigService(p);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DynamicAppConfig dynamicAppConfig(
|
||||
ConfigService configService,
|
||||
@Value("${nacos.config.group}") String group,
|
||||
@Value("${nacos.config.data-id}") String dataId
|
||||
) throws Exception {
|
||||
|
||||
DynamicAppConfig holder = new DynamicAppConfig();
|
||||
|
||||
// 启动先拉一次
|
||||
String content = configService.getConfig(dataId, group, 3000);
|
||||
if (content != null && !content.isBlank()) {
|
||||
holder.ref.set(parse(content));
|
||||
log.info("Loaded nacos config: dataId={}, group={}", dataId, group);
|
||||
} else {
|
||||
log.warn("Empty nacos config: dataId={}, group={}", dataId, group);
|
||||
}
|
||||
|
||||
// 监听热更新
|
||||
configService.addListener(dataId, group, new Listener() {
|
||||
@Override public Executor getExecutor() { return null; }
|
||||
@Override public void receiveConfigInfo(String configInfo) {
|
||||
try {
|
||||
AppConfig newCfg = parse(configInfo);
|
||||
holder.ref.set(newCfg);
|
||||
log.info("Refreshed nacos config: dataId={}, group={}", dataId, group);
|
||||
log.info("New config: {}", newCfg.toString());
|
||||
} catch (Exception e) {
|
||||
// 解析失败不覆盖旧配置
|
||||
log.error("Failed to refresh nacos config: dataId={}, keep old config.", dataId, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return holder;
|
||||
}
|
||||
|
||||
private AppConfig parse(String yaml) throws Exception {
|
||||
if (yaml == null || yaml.isBlank()) return new AppConfig();
|
||||
return yamlMapper.readValue(yaml, AppConfig.class);
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static class DynamicAppConfig {
|
||||
private final AtomicReference<AppConfig> ref = new AtomicReference<>(new AppConfig());
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,6 @@ public class UserRegisterProperties {
|
||||
/**
|
||||
* 新用户注册时的免费使用次数
|
||||
*/
|
||||
private Integer freeTrialQuota = 5;
|
||||
private Integer freeTrialQuota;
|
||||
|
||||
}
|
||||
|
||||
@@ -94,8 +94,7 @@ public class UserController {
|
||||
@PostMapping("/register")
|
||||
@Operation(summary = "用户注册",description = "用户注册接口")
|
||||
public BaseResponse<Boolean> register(@RequestBody UserRegisterDTO userRegisterDTO) {
|
||||
userService.userRegister(userRegisterDTO);
|
||||
return ResultUtils.success(true);
|
||||
return ResultUtils.success(userService.userRegister(userRegisterDTO));
|
||||
}
|
||||
|
||||
@PostMapping("/sendVerifyMail")
|
||||
|
||||
@@ -8,16 +8,16 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yolo.keyborad.common.ErrorCode;
|
||||
import com.yolo.keyborad.config.AppConfig;
|
||||
import com.yolo.keyborad.config.NacosAppConfigCenter;
|
||||
import com.yolo.keyborad.config.UserRegisterProperties;
|
||||
import com.yolo.keyborad.exception.BusinessException;
|
||||
import com.yolo.keyborad.mapper.KeyboardUserMapper;
|
||||
import com.yolo.keyborad.model.dto.user.*;
|
||||
import com.yolo.keyborad.model.entity.KeyboardUser;
|
||||
import com.yolo.keyborad.model.entity.KeyboardUserWallet;
|
||||
import com.yolo.keyborad.model.vo.user.KeyboardUserRespVO;
|
||||
import com.yolo.keyborad.service.KeyboardCharacterService;
|
||||
import com.yolo.keyborad.service.KeyboardUserLoginLogService;
|
||||
import com.yolo.keyborad.service.KeyboardUserWalletService;
|
||||
import com.yolo.keyborad.service.UserService;
|
||||
import com.yolo.keyborad.service.*;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import com.yolo.keyborad.utils.RedisUtil;
|
||||
import com.yolo.keyborad.utils.SendMailUtils;
|
||||
@@ -61,10 +61,16 @@ public class UserServiceImpl extends ServiceImpl<KeyboardUserMapper, KeyboardUse
|
||||
private KeyboardUserLoginLogService loginLogService;
|
||||
|
||||
@Resource
|
||||
private com.yolo.keyborad.service.KeyboardUserQuotaTotalService quotaTotalService;
|
||||
private KeyboardUserQuotaTotalService quotaTotalService;
|
||||
|
||||
@Resource
|
||||
private com.yolo.keyborad.config.UserRegisterProperties userRegisterProperties;
|
||||
private UserRegisterProperties userRegisterProperties;
|
||||
|
||||
private final NacosAppConfigCenter.DynamicAppConfig cfgHolder;
|
||||
|
||||
public UserServiceImpl(NacosAppConfigCenter.DynamicAppConfig cfgHolder) {
|
||||
this.cfgHolder = cfgHolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyboardUser selectUserWithSubjectId(String sub) {
|
||||
@@ -97,7 +103,8 @@ public class UserServiceImpl extends ServiceImpl<KeyboardUserMapper, KeyboardUse
|
||||
com.yolo.keyborad.model.entity.KeyboardUserQuotaTotal quotaTotal =
|
||||
new com.yolo.keyborad.model.entity.KeyboardUserQuotaTotal();
|
||||
quotaTotal.setUserId(keyboardUser.getId());
|
||||
quotaTotal.setTotalQuota(userRegisterProperties.getFreeTrialQuota());
|
||||
AppConfig appConfig = cfgHolder.getRef().get();
|
||||
quotaTotal.setTotalQuota(appConfig.getUserRegisterProperties().getFreeTrialQuota());
|
||||
quotaTotal.setUsedQuota(0);
|
||||
quotaTotal.setVersion(0);
|
||||
quotaTotal.setCreatedAt(new Date());
|
||||
@@ -105,7 +112,7 @@ public class UserServiceImpl extends ServiceImpl<KeyboardUserMapper, KeyboardUse
|
||||
quotaTotalService.save(quotaTotal);
|
||||
|
||||
log.info("User registered with Apple Sign-In, userId={}, freeQuota={}",
|
||||
keyboardUser.getId(), userRegisterProperties.getFreeTrialQuota());
|
||||
keyboardUser.getId(), appConfig.getUserRegisterProperties().getFreeTrialQuota());
|
||||
|
||||
return keyboardUser;
|
||||
}
|
||||
@@ -235,7 +242,8 @@ public class UserServiceImpl extends ServiceImpl<KeyboardUserMapper, KeyboardUse
|
||||
com.yolo.keyborad.model.entity.KeyboardUserQuotaTotal quotaTotal =
|
||||
new com.yolo.keyborad.model.entity.KeyboardUserQuotaTotal();
|
||||
quotaTotal.setUserId(keyboardUser.getId());
|
||||
quotaTotal.setTotalQuota(userRegisterProperties.getFreeTrialQuota());
|
||||
AppConfig appConfig = cfgHolder.getRef().get();
|
||||
quotaTotal.setTotalQuota(appConfig.getUserRegisterProperties().getFreeTrialQuota());
|
||||
quotaTotal.setUsedQuota(0);
|
||||
quotaTotal.setVersion(0);
|
||||
quotaTotal.setCreatedAt(new Date());
|
||||
@@ -243,7 +251,7 @@ public class UserServiceImpl extends ServiceImpl<KeyboardUserMapper, KeyboardUse
|
||||
quotaTotalService.save(quotaTotal);
|
||||
|
||||
log.info("User registered with email, userId={}, email={}, freeQuota={}",
|
||||
keyboardUser.getId(), keyboardUser.getEmail(), userRegisterProperties.getFreeTrialQuota());
|
||||
keyboardUser.getId(), keyboardUser.getEmail(), appConfig.getUserRegisterProperties().getFreeTrialQuota());
|
||||
}
|
||||
return insertCount > 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user