From c8796352a49cfebabe742d72209e09d3b2afbf7c Mon Sep 17 00:00:00 2001 From: wangxulei <727869402@qq.com> Date: Mon, 23 Dec 2024 17:28:28 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=B0=8F=E7=BA=A2=E4=B9=A6?= =?UTF-8?q?=E7=99=BB=E9=99=86=E6=B3=A8=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/dd/admin/business/api/AuthApi.java | 47 +++---------- .../com/dd/admin/business/api/LoginApi.java | 68 +++++++++++++++++++ .../business/api/domain/PhoneLoginDto.java | 13 ++++ .../business/api/service/LoginService.java | 9 +++ .../api/service/impl/LoginServiceImpl.java | 52 ++++++++++++++ .../admin/business/author/entity/Author.java | 3 +- .../author/service/AuthorService.java | 4 ++ .../service/impl/AuthorServiceImpl.java | 36 ++++++++++ .../{CorsConfig.java => GolbalConfig.java} | 10 ++- .../security/interceptor/ApiInterceptor.java | 66 +++++------------- .../common/security/jwt/JwtTokenUtil.java | 5 ++ .../security/jwt/config/SecurityConfig.java | 6 -- .../utils/RandomXiaohongshuAuthorName.java | 10 ++- 13 files changed, 231 insertions(+), 98 deletions(-) create mode 100644 src/main/java/com/dd/admin/business/api/LoginApi.java create mode 100644 src/main/java/com/dd/admin/business/api/domain/PhoneLoginDto.java create mode 100644 src/main/java/com/dd/admin/business/api/service/LoginService.java create mode 100644 src/main/java/com/dd/admin/business/api/service/impl/LoginServiceImpl.java rename src/main/java/com/dd/admin/common/config/{CorsConfig.java => GolbalConfig.java} (86%) diff --git a/src/main/java/com/dd/admin/business/api/AuthApi.java b/src/main/java/com/dd/admin/business/api/AuthApi.java index 348f5ed..9bbbbe2 100644 --- a/src/main/java/com/dd/admin/business/api/AuthApi.java +++ b/src/main/java/com/dd/admin/business/api/AuthApi.java @@ -1,14 +1,10 @@ package com.dd.admin.business.api; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.dd.admin.business.note.domain.NoteDto; -import com.dd.admin.business.note.domain.NoteVo; +import com.dd.admin.business.author.entity.Author; +import com.dd.admin.business.author.service.AuthorService; import com.dd.admin.common.aop.operationLog.aop.OperLog; import com.dd.admin.common.aop.operationLog.aop.OperType; -import com.dd.admin.common.exception.ApiException; import com.dd.admin.common.model.result.ResultBean; -import com.dd.admin.common.utils.RedisUtil; -import com.dd.admin.common.utils.StringUtil; import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; @@ -17,41 +13,14 @@ import org.springframework.web.bind.annotation.RestController; @RestController public class AuthApi { - @Autowired - RedisUtil redisUtil; + AuthorService authorService; - @ApiOperation(value = "获取验证码") + @ApiOperation(value = "获取博主信息") @ApiOperationSupport(order = 1) - @GetMapping("/api/auth/getCode") - @OperLog(operModule = "获取验证码",operType = OperType.QUERY,operDesc = "获取验证码") - public ResultBean page(String phoneNumber) { - String code = sendSmsCode(phoneNumber); - return ResultBean.success(code); + @GetMapping("/api/auth/getMine") + @OperLog(operModule = "获取博主信息",operType = OperType.QUERY,operDesc = "获取博主信息") + public ResultBean getMine() { + return ResultBean.success(); } - - - - public String sendSmsCode(String phoneNumber) { - String redisKey = "SMS_CODE" + phoneNumber; - String smsCode = String.valueOf(redisUtil.get(redisKey)); - if(StringUtil.isNotEmpty(smsCode)){ - throw new ApiException("验证码已发送,请稍后再试" + smsCode); - } - String code = StringUtil.createCode(4); - //设置有效时间 -// String json = JavaSmsApi.tplSingleSend(phoneNumber,CODE_TPL_ID, BeanUtil.beanToMap(new SmsCode(code))); - -// Map dataMap = (Map) JSON.parse(json); -// if(dataMap.get("msg").equals("发送成功")){ - if(true){ - System.out.println(code); - redisUtil.set(redisKey,code,120); - return code; - }else{ - throw new ApiException("发送失败"); -// throw new ApiException("发送失败,"+dataMap.get("msg")); - } - } - } diff --git a/src/main/java/com/dd/admin/business/api/LoginApi.java b/src/main/java/com/dd/admin/business/api/LoginApi.java new file mode 100644 index 0000000..1ef5834 --- /dev/null +++ b/src/main/java/com/dd/admin/business/api/LoginApi.java @@ -0,0 +1,68 @@ +package com.dd.admin.business.api; + +import cn.hutool.jwt.JWT; +import cn.hutool.jwt.JWTUtil; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.dd.admin.business.api.domain.PhoneLoginDto; +import com.dd.admin.business.api.service.LoginService; +import com.dd.admin.business.author.entity.Author; +import com.dd.admin.business.author.service.AuthorService; +import com.dd.admin.business.note.domain.NoteDto; +import com.dd.admin.business.note.domain.NoteVo; +import com.dd.admin.common.aop.operationLog.aop.OperLog; +import com.dd.admin.common.aop.operationLog.aop.OperType; +import com.dd.admin.common.exception.ApiException; +import com.dd.admin.common.model.result.ResultBean; +import com.dd.admin.common.security.jwt.JwtTokenUtil; +import com.dd.admin.common.utils.RedisUtil; +import com.dd.admin.common.utils.StringUtil; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class LoginApi { + + @Autowired + LoginService loginService; + @Autowired + AuthorService authorService; + @Autowired + private JwtTokenUtil jwtTokenUtil; + + @ApiOperation(value = "获取验证码") + @ApiOperationSupport(order = 1) + @GetMapping("/api/getCode") + @OperLog(operModule = "获取验证码",operType = OperType.QUERY,operDesc = "获取验证码") + public ResultBean getCode(String phoneNumber) { + String code = loginService.sendSmsCode(phoneNumber); + return ResultBean.success(code); + } + + @ApiOperation(value = "验证码登陆") + @ApiOperationSupport(order = 1) + @PostMapping("/api/checkCode") + @Transactional + @OperLog(operModule = "获取验证码",operType = OperType.OTHER,operDesc = "验证码登陆") + public ResultBean checkCode(@RequestBody PhoneLoginDto phoneLoginDto) { + loginService.checkCode(phoneLoginDto); + //验证后登陆 + Author author = authorService.selectAuthorByPhoneNumber(phoneLoginDto.getPhoneNumber()); + if(author==null){ + author = authorService.createNewAuthor(phoneLoginDto.getPhoneNumber()); + } + //根据用户id生成token + final String token = jwtTokenUtil.generateTokenByUserId(author.getAuthorId()); + author.setToken(token); + return ResultBean.success(author); + } + + + + +} diff --git a/src/main/java/com/dd/admin/business/api/domain/PhoneLoginDto.java b/src/main/java/com/dd/admin/business/api/domain/PhoneLoginDto.java new file mode 100644 index 0000000..5f7aceb --- /dev/null +++ b/src/main/java/com/dd/admin/business/api/domain/PhoneLoginDto.java @@ -0,0 +1,13 @@ +package com.dd.admin.business.api.domain; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class PhoneLoginDto { + @NotBlank(message = "手机号不能为空") + private String phoneNumber; + @NotBlank(message = "验证码不能为空") + private String code; +} diff --git a/src/main/java/com/dd/admin/business/api/service/LoginService.java b/src/main/java/com/dd/admin/business/api/service/LoginService.java new file mode 100644 index 0000000..90d02b0 --- /dev/null +++ b/src/main/java/com/dd/admin/business/api/service/LoginService.java @@ -0,0 +1,9 @@ +package com.dd.admin.business.api.service; + + +import com.dd.admin.business.api.domain.PhoneLoginDto; + +public interface LoginService { + public String sendSmsCode(String phoneNumber); + public void checkCode(PhoneLoginDto phoneLoginDto); +} diff --git a/src/main/java/com/dd/admin/business/api/service/impl/LoginServiceImpl.java b/src/main/java/com/dd/admin/business/api/service/impl/LoginServiceImpl.java new file mode 100644 index 0000000..094d830 --- /dev/null +++ b/src/main/java/com/dd/admin/business/api/service/impl/LoginServiceImpl.java @@ -0,0 +1,52 @@ +package com.dd.admin.business.api.service.impl; + +import com.dd.admin.business.api.domain.PhoneLoginDto; +import com.dd.admin.business.api.service.LoginService; +import com.dd.admin.business.author.entity.Author; +import com.dd.admin.common.exception.ApiException; +import com.dd.admin.common.utils.RedisUtil; +import com.dd.admin.common.utils.StringUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class LoginServiceImpl implements LoginService { + + @Autowired + RedisUtil redisUtil; + + @Override + public String sendSmsCode(String phoneNumber) { + String redisKey = "SMS_CODE" + phoneNumber; + String smsCode = String.valueOf(redisUtil.get(redisKey)); + if (StringUtil.isNotEmpty(smsCode)) { + throw new ApiException("验证码已发送,请稍后再试" + smsCode); + } + String code = StringUtil.createCode(4); + //设置有效时间 +// String json = JavaSmsApi.tplSingleSend(phoneNumber,CODE_TPL_ID, BeanUtil.beanToMap(new SmsCode(code))); + +// Map dataMap = (Map) JSON.parse(json); +// if(dataMap.get("msg").equals("发送成功")){ + if (true) { + System.out.println(code); + redisUtil.set(redisKey, code, 120); + return code; + } else { + throw new ApiException("发送失败"); +// throw new ApiException("发送失败,"+dataMap.get("msg")); + } + } + + @Override + public void checkCode(PhoneLoginDto phoneLogin) { + String code = phoneLogin.getCode(); + String phoneNumber = phoneLogin.getPhoneNumber(); + String smsCode = String.valueOf(redisUtil.get("SMS_CODE" + phoneNumber)); + //验证验证码是否正确 + if(!code.matches(smsCode)){ + throw new ApiException("验证码有误"); + } + } + +} diff --git a/src/main/java/com/dd/admin/business/author/entity/Author.java b/src/main/java/com/dd/admin/business/author/entity/Author.java index 7b2bfe9..66ef5c4 100644 --- a/src/main/java/com/dd/admin/business/author/entity/Author.java +++ b/src/main/java/com/dd/admin/business/author/entity/Author.java @@ -140,5 +140,6 @@ public class Author implements Serializable { @TableField("PHONE_NUMBER") private String phoneNumber; - + @TableField(exist = false) + private String token; } diff --git a/src/main/java/com/dd/admin/business/author/service/AuthorService.java b/src/main/java/com/dd/admin/business/author/service/AuthorService.java index dcd68ed..b89854c 100644 --- a/src/main/java/com/dd/admin/business/author/service/AuthorService.java +++ b/src/main/java/com/dd/admin/business/author/service/AuthorService.java @@ -23,4 +23,8 @@ public interface AuthorService extends IService { //作者(博主)-列表 List selectAuthorList(AuthorDto authorDto); + Author selectAuthorByPhoneNumber(String phoneNumber); + + Author createNewAuthor(String phoneNumber); + } diff --git a/src/main/java/com/dd/admin/business/author/service/impl/AuthorServiceImpl.java b/src/main/java/com/dd/admin/business/author/service/impl/AuthorServiceImpl.java index 1bf2644..9799e74 100644 --- a/src/main/java/com/dd/admin/business/author/service/impl/AuthorServiceImpl.java +++ b/src/main/java/com/dd/admin/business/author/service/impl/AuthorServiceImpl.java @@ -1,5 +1,6 @@ package com.dd.admin.business.author.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.dd.admin.common.model.PageFactory; @@ -7,9 +8,16 @@ import com.dd.admin.business.author.entity.Author; import com.dd.admin.business.author.mapper.AuthorMapper; import com.dd.admin.business.author.service.AuthorService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.dd.admin.common.utils.AddressUtils; +import com.dd.admin.common.utils.IPUtils; +import com.dd.admin.common.utils.RandomXiaohongshuAuthorName; +import com.dd.admin.common.utils.StringUtil; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.dd.admin.business.author.domain.AuthorVo; import com.dd.admin.business.author.domain.AuthorDto; + +import javax.servlet.http.HttpServletRequest; import java.util.List; /** @@ -23,6 +31,9 @@ import java.util.List; @Service public class AuthorServiceImpl extends ServiceImpl implements AuthorService { + @Autowired + HttpServletRequest request; + @Override public IPage selectAuthorPage(AuthorDto authorDto) { Page page = PageFactory.defaultPage(); @@ -33,4 +44,29 @@ public class AuthorServiceImpl extends ServiceImpl impleme public List selectAuthorList(AuthorDto authorDto) { return baseMapper.selectAuthorList(authorDto); } + + @Override + public Author selectAuthorByPhoneNumber(String phoneNumber) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(Author::getPhoneNumber,phoneNumber); + Author author = baseMapper.selectOne(queryWrapper); + return author; + } + + @Override + public Author createNewAuthor(String phoneNumber) { + Author author = new Author(); + author.setPhoneNumber(phoneNumber); + //随机生成昵称 + author.setAuthorName(RandomXiaohongshuAuthorName.generateAuthorName()); + author.setAuthorNo(StringUtil.getDateStringNow() + StringUtil.createCode(4)); + author.setDescription("我是" + author.getAuthorName()); + //生成随机头像因为没有点击上传所有没有头像id + author.setAvatarUrl("http://8.146.211.120:8080/upload/avatar/avatar ("+ StringUtil.createCode(1) +").jpg"); + author.setBackGroundUrl("http://8.146.211.120:8080/upload/notes/note (6).jpg"); + author.setIpAddress(IPUtils.getIpAddr(request)); // 请求IP + author.setIpRealAddress(AddressUtils.getRealAddress(author.getIpAddress())); //ip真实地址 + this.save(author); + return author; + } } diff --git a/src/main/java/com/dd/admin/common/config/CorsConfig.java b/src/main/java/com/dd/admin/common/config/GolbalConfig.java similarity index 86% rename from src/main/java/com/dd/admin/common/config/CorsConfig.java rename to src/main/java/com/dd/admin/common/config/GolbalConfig.java index 1f1387c..fa533db 100644 --- a/src/main/java/com/dd/admin/common/config/CorsConfig.java +++ b/src/main/java/com/dd/admin/common/config/GolbalConfig.java @@ -1,5 +1,6 @@ package com.dd.admin.common.config; +import com.dd.admin.common.security.interceptor.ApiInterceptor; import com.dd.admin.common.utils.ToolUtil; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; @@ -9,6 +10,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -24,7 +26,7 @@ import java.util.List; * @date 2021/7/6 */ @Configuration -public class CorsConfig implements WebMvcConfigurer { +public class GolbalConfig implements WebMvcConfigurer { @Value("${dd.uploadPath}") @@ -59,6 +61,12 @@ public class CorsConfig implements WebMvcConfigurer { } + // 注册拦截器的方法 + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new ApiInterceptor()) + .addPathPatterns("/api/auth/**"); // 拦截/api下所有请求路径 + } // @Bean diff --git a/src/main/java/com/dd/admin/common/security/interceptor/ApiInterceptor.java b/src/main/java/com/dd/admin/common/security/interceptor/ApiInterceptor.java index 5347d59..d46c3a7 100644 --- a/src/main/java/com/dd/admin/common/security/interceptor/ApiInterceptor.java +++ b/src/main/java/com/dd/admin/common/security/interceptor/ApiInterceptor.java @@ -1,62 +1,32 @@ +package com.dd.admin.common.security.interceptor; + import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; + +import cn.hutool.core.util.StrUtil; +import com.dd.admin.common.exception.ApiException; +import com.dd.admin.common.security.jwt.service.JwtUserDetailsService; +import com.dd.admin.common.utils.RedisUtil; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jws; +import io.swagger.annotations.Api; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; - +@Component public class ApiInterceptor implements HandlerInterceptor { - private final JwtUserDetailsService jwtUserDetailsService; - - public ApiInterceptor(JwtUserDetailsService jwtUserDetailsService) { - this.jwtUserDetailsService = jwtUserDetailsService; - } - @Override - public boolean preIntercept(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - // 获取请求路径,判断是否是以/api开头 - String requestUri = request.getRequestURI(); - if (requestUri.startsWith("/api")) { - // 在这里编写验证手机号和验证码的逻辑,比如从请求参数或者请求头中获取相关信息进行验证 - // 假设从请求参数中获取手机号和验证码,示例代码如下(实际情况可能需要根据具体业务从合适的地方获取) - String phone = request.getParameter("phone"); - String verificationCode = request.getParameter("verificationCode"); - if (isPhoneValid(phone) && isVerificationCodeValid(verificationCode)) { - // 根据验证通过的手机号等信息获取对应的用户详情(这里假设你的用户详情是通过JwtUserDetailsService来获取,实际可能需要根据具体业务调整) - UserDetails userDetails = jwtUserDetailsService.loadUserByUsername(phone); - // 创建认证对象,将用户详情放入其中,这里假设认证方式是基于用户名密码形式(可根据实际调整) - Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); - // 将认证对象放入SecurityContextHolder中,模拟用户已认证的状态 - SecurityContextHolder.getContext().setAuthentication(authentication); - return true; // 验证通过,放行请求 - } else { - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 设置未授权状态码 - return false; // 验证不通过,拦截请求 - } + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + String token = request.getHeader("Authorization"); + if (StrUtil.isBlank(token)) { + throw new ApiException("请登录后访问"); } - return true; // 如果不是/api开头的请求,直接放行 - } - private boolean isPhoneValid(String phone) { - // 这里编写手机号验证的具体逻辑,比如正则表达式验证手机号格式是否正确等 - return true; // 示例先返回true,实际需完善逻辑 + return true; } - - private boolean isVerificationCodeValid(String verificationCode) { - // 这里编写验证码验证的具体逻辑,比如和后台存储的验证码进行比对等 - return true; // 示例先返回true,实际需完善逻辑 - } - - @Override - public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { - HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); - } - - @Override - public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { - HandlerInterceptor.super.afterCompletion(request, response, handler, ex); - } -} \ No newline at end of file +} diff --git a/src/main/java/com/dd/admin/common/security/jwt/JwtTokenUtil.java b/src/main/java/com/dd/admin/common/security/jwt/JwtTokenUtil.java index cdc7f10..e5c20af 100644 --- a/src/main/java/com/dd/admin/common/security/jwt/JwtTokenUtil.java +++ b/src/main/java/com/dd/admin/common/security/jwt/JwtTokenUtil.java @@ -57,6 +57,11 @@ public class JwtTokenUtil implements Serializable { return doGenerateToken(claims, filterKey + userDetails.getUsername()); } + public String generateTokenByUserId(String userId) { + Map claims = new HashMap<>(); + return doGenerateToken(claims, userId); + } + //while creating the token - //1. Define claims of the token, like Issuer, Expiration, Subject, and the ID //2. Sign the JWT using the HS512 algorithm and secret key. diff --git a/src/main/java/com/dd/admin/common/security/jwt/config/SecurityConfig.java b/src/main/java/com/dd/admin/common/security/jwt/config/SecurityConfig.java index 4ca09c3..367a7ef 100644 --- a/src/main/java/com/dd/admin/common/security/jwt/config/SecurityConfig.java +++ b/src/main/java/com/dd/admin/common/security/jwt/config/SecurityConfig.java @@ -87,10 +87,4 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { } - // 注册拦截器的方法 - @Override - public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(new ApiInterceptor()) - .addPathPatterns("/api/**"); // 拦截/api下所有请求路径 - } } diff --git a/src/main/java/com/dd/admin/common/utils/RandomXiaohongshuAuthorName.java b/src/main/java/com/dd/admin/common/utils/RandomXiaohongshuAuthorName.java index 9d1b653..bd977b7 100644 --- a/src/main/java/com/dd/admin/common/utils/RandomXiaohongshuAuthorName.java +++ b/src/main/java/com/dd/admin/common/utils/RandomXiaohongshuAuthorName.java @@ -3,9 +3,13 @@ package com.dd.admin.common.utils; import java.util.Random; public class RandomXiaohongshuAuthorName { + + // 增加更多风格各异的形容词 + private static final String[] ADJECTIVES = {"甜系", "酷盖", "元气", "文艺", "清新", "时尚", "复古", "个性", "慵懒", "灵动","甜系", "萌趣", "清新", "元气", "梦幻", "文艺", "优雅", "酷盖", "潮流", "时尚", "复古", "治愈", "俏皮", "灵动", "简约", "精致", "浪漫", "神秘", "个性", "森系"}; + // 丰富名词列表 + private static final String[] NOUNS = {"喵星人", "星辰", "云朵", "花田", "森林", "梦境", "清风", "暖阳", "微光", "小确幸","小熊", "兔子", "云朵", "星辰", "花朵", "森林", "海风", "咖啡", "画笔", "月光", "糖果", "蛋糕", "风铃", "泡泡", "琉璃", "蝴蝶"}; + // 定义一些风格词汇数组 - private static final String[] ADJECTIVES = {"甜系", "酷盖", "元气", "文艺", "清新", "时尚", "复古", "个性", "慵懒", "灵动"}; - private static final String[] NOUNS = {"喵星人", "星辰", "云朵", "花田", "森林", "梦境", "清风", "暖阳", "微光", "小确幸"}; public static void main(String[] args) { String authorName = generateAuthorName(); @@ -25,4 +29,4 @@ public class RandomXiaohongshuAuthorName { return adjective + noun + number; } -} \ No newline at end of file +}