Selaa lähdekoodia

重构注册接口

tsurumure 7 kuukautta sitten
vanhempi
commit
ee412bcc19

+ 3 - 1
db/sys_user.sql

@@ -13,7 +13,9 @@ CREATE TABLE `sys_user` (
     `phone_area_code` INT COMMENT '手机区号/国家码',
     `password` VARCHAR(100) NOT NULL COMMENT '密码',
     UNIQUE KEY (`username`),
-    INDEX `idx_username` (`username`)
+    UNIQUE KEY (`phone`),
+    INDEX `idx_username` (`username`),
+    INDEX `idx_phone` (`phone`)
 ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='系统用户表';
 
 # 原始密码:123456

+ 0 - 1
db/sys_user_info.sql

@@ -25,7 +25,6 @@ CREATE TABLE `sys_user_info` (
     `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
     `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
     `del_flag` TINYINT(1) DEFAULT '-1' COMMENT '删除标志 (-1未删除, 1删除)',
-    UNIQUE KEY (`nickname`),
     INDEX `idx_nickname` (`nickname`),
     INDEX `idx_email` (`email`)
 ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='系统用户表';

+ 4 - 4
src/main/java/com/backendsys/aspect/RateLimiting.java

@@ -10,10 +10,10 @@ import java.lang.annotation.Target;
 public @interface RateLimiting {
     // 缓存key
     String key() default "RateLimiting";
-    // 限流时间 (秒)
+    // 限流时间 (秒) (默认1秒)
     int duration() default 1;
-    // 限流次数 (默认1秒3次比较合理)
-    int limit() default 3;
-    // 锁定时长 (秒)
+    // 限流次数 (默认1秒5次)
+    int limit() default 5;
+    // 锁定时长 (秒) (5秒)
     int lockDuration() default 5;
 }

+ 8 - 0
src/main/java/com/backendsys/aspect/RateLimitingAspect.java

@@ -17,6 +17,11 @@ import org.springframework.stereotype.Component;
 import java.lang.reflect.Method;
 import java.util.concurrent.TimeUnit;
 
+/**
+ * 限流
+ * @RateLimiting(key = "systemLoginWithPhone")
+ * @RateLimiting(key = "systemLoginWithPhone", duration = 2, limit = 10)
+ */
 @Slf4j
 @Aspect
 @Component
@@ -30,11 +35,14 @@ public class RateLimitingAspect {
 
     /**
      * 带有注解的方法之前执行
+     * - duration: 限流周期 (秒) (默认1秒内)
+     * - limit: 限流次数 (默认1秒5次)
      */
     @SuppressWarnings("unchecked")
     @Before("@annotation(rateLimiting)")
     public void doBefore(RateLimiting rateLimiting) {
 
+        // 限流标识: 方法名-IP-用户ID
         String key = "ratelimit-" + rateLimiting.key() + "-" + httpRequestUtil.getIpAddr() + '-' + httpRequestUtil.getUserId();
         String lockKey = "lock-" + key;
 

+ 16 - 16
src/main/java/com/backendsys/controller/Systems/SysAuthController.java

@@ -57,23 +57,23 @@ public class SysAuthController {
 //    public Result systemLogin(HttpServletRequest request, @Validated(SysUserDTO.Login.class) @RequestBody SysUserDTO sysUserDTO) {
 //        return Result.success(sysAuthService.login(request, sysUserDTO));
 //    }
-    /**
-     * 登录 (手机号码)
-     */
-    @PostMapping(value = "/api/system/auth/loginWithPhone")
-    @RateLimiting(key = "systemLoginWithPhone", limit = 5)
-    public Result systemLoginWithPhone(HttpServletRequest request, @Validated(SysUserDTO.LoginWithPhone.class) @RequestBody SysUserDTO sysUserDTO) {
-        return Result.success(sysAuthService.loginWithPhone(request, sysUserDTO));
-    }
+//    /**
+//     * 登录 (手机号码)
+//     */
+//    @PostMapping(value = "/api/system/auth/loginWithPhone")
+//    @RateLimiting(key = "systemLoginWithPhone", limit = 5)
+//    public Result systemLoginWithPhone(HttpServletRequest request, @Validated(SysUserDTO.LoginWithPhone.class) @RequestBody SysUserDTO sysUserDTO) {
+//        return Result.success(sysAuthService.loginWithPhone(request, sysUserDTO));
+//    }
 
-    /**
-     * 注册系统用户 (用户名 和 手机号码 必填)
-     */
-    @PostMapping("/api/public/system/user/registerUser")
-    @RateLimiting(key = "registerUser", limit = 5)
-    public Result registerUser(HttpServletRequest request, @Validated(SysUserDTO.Register.class) @RequestBody SysUserDTO sysUserDTO) {
-        return Result.success(sysAuthService.registerUser(request, sysUserDTO), "注册成功");
-    }
+//    /**
+//     * 注册系统用户 (用户名 和 手机号码 必填)
+//     */
+//    @PostMapping("/api/public/system/user/registerUser")
+//    @RateLimiting(key = "registerUser", limit = 5)
+//    public Result registerUser(HttpServletRequest request, @Validated(SysUserDTO.Register.class) @RequestBody SysUserDTO sysUserDTO) {
+//        return Result.success(sysAuthService.registerUser(request, sysUserDTO), "注册成功");
+//    }
 
     /**
      * 忘记密码

+ 25 - 12
src/main/java/com/backendsys/modules/system/controller/SysAuthV2Controller.java

@@ -1,12 +1,13 @@
 package com.backendsys.modules.system.controller;
 
 import com.backendsys.aspect.RateLimiting;
-import com.backendsys.entity.System.SysUserDTO;
 import com.backendsys.modules.common.aspect.SysLog;
+import com.backendsys.modules.common.config.security.annotations.Anonymous;
 import com.backendsys.modules.common.utils.Result;
 import com.backendsys.modules.system.entity.SysAuth;
 import com.backendsys.modules.system.entity.SysAuthPhone;
 import com.backendsys.modules.system.entity.SysMobileArea;
+import com.backendsys.modules.system.entity.SysUserDTO;
 import com.backendsys.modules.system.service.SysAuthV2Service;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -29,11 +30,20 @@ public class SysAuthV2Controller {
     @Autowired
     private SysAuthV2Service sysAuthV2Service;
 
+    // -------------------------------------------------------------------------------------------------
+
     @Operation(summary = "获取图形验证码")
     @GetMapping("/api/system/auth/getCaptcha")
     public void getCaptcha(HttpServletResponse response) throws IOException {
         sysAuthV2Service.renderCaptcha(response);
     }
+    @SysLog("系统用户登录 (用户名)")
+    @Operation(summary = "系统用户登录 (用户名)")
+    @PostMapping(value = "/api/system/auth/login")
+    public Result systemLogin(@Validated(SysAuth.Login.class) @RequestBody SysAuth sysAuth) {
+        return Result.success().put("data", sysAuthV2Service.login(sysAuth));
+    }
+    // -------------------------------------------------------------------------------------------------
 
     @Operation(summary = "获取手机号地区列表")
     @RateLimiting(key = "getMobileAreaCode")
@@ -41,21 +51,24 @@ public class SysAuthV2Controller {
     public Result getMobileAreaCode(@Validated SysMobileArea sysMobileArea) {
         return Result.success().put("data", sysAuthV2Service.getMobileAreaList(sysMobileArea));
     }
-
-    @SysLog("系统用户登录 (用户名)")
-    @Operation(summary = "系统用户登录 (用户名)")
-    @PostMapping(value = "/api/system/auth/login")
-    public Result systemLogin(@Validated(SysAuth.Login.class) @RequestBody SysAuth sysAuth) {
-        return Result.success().put("data", sysAuthV2Service.login(sysAuth));
+    @Operation(summary = "系统用户登录 (手机号码)")
+    @PostMapping(value = "/api/v2/system/auth/loginWithPhone")
+    @RateLimiting(key = "systemLoginWithPhone")
+    public Result systemLoginWithPhone(@Validated(SysAuthPhone.Login.class) @RequestBody SysAuthPhone sysAuthPhone) {
+        return Result.success().put("data", sysAuthV2Service.loginWithPhone(sysAuthPhone));
     }
 
+    // -------------------------------------------------------------------------------------------------
+
     /**
-     * 登录 (手机号码)
+     * 注册系统用户 (用户名 和 手机号码 必填)
      */
-    @PostMapping(value = "/api/v2/system/auth/loginWithPhone")
-//    @RateLimiting(key = "systemLoginWithPhone", limit = 5)
-    public Result systemLoginWithPhone(@Validated(SysAuthPhone.Login.class) @RequestBody SysAuthPhone sysAuthPhone) {
-        return Result.success().put("data", sysAuthV2Service.loginWithPhone(sysAuthPhone));
+    @Anonymous
+    @Operation(summary = "系统用户注册")
+    @PostMapping("/api/system/auth/register")
+    @RateLimiting(key = "registerUser", limit = 5)
+    public Result register(@Validated(SysUserDTO.Register.class) @RequestBody SysUserDTO sysUserDTO) {
+        return Result.success().put("data", sysAuthV2Service.register(sysUserDTO));
     }
 
 }

+ 3 - 5
src/main/java/com/backendsys/modules/system/entity/SysAuth.java

@@ -1,6 +1,5 @@
 package com.backendsys.modules.system.entity;
 
-import com.backendsys.entity.System.SysUserDTO;
 import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.Size;
 import lombok.Data;
@@ -11,13 +10,12 @@ public class SysAuth {
     public static interface Login{}
     public static interface Register{}
 
-
     private Long user_id;
-    @NotEmpty(message="用户名不能为空", groups = { Login.class })
-    @Size(min = 2, max = 20, message = "用户名长度在 {min}-{max} 字符", groups = { Login.class })
+    @NotEmpty(message="用户名不能为空", groups = { Login.class, Register.class })
+    @Size(min = 2, max = 20, message = "用户名长度在 {min}-{max} 字符", groups = { Login.class, Register.class })
     private String username;
 
-    @NotEmpty(message="密码不能为空", groups = { Login.class })
+    @NotEmpty(message="密码不能为空", groups = { Login.class, Register.class })
     private String password;
 
     @NotEmpty(message="验证码不能为空", groups = { Login.class, Register.class })

+ 4 - 4
src/main/java/com/backendsys/modules/system/service/SysAuthV2Service.java

@@ -1,9 +1,6 @@
 package com.backendsys.modules.system.service;
 
-import com.backendsys.modules.system.entity.SysAuth;
-import com.backendsys.modules.system.entity.SysAuthPhone;
-import com.backendsys.modules.system.entity.SysMobileArea;
-import com.backendsys.modules.system.entity.SysUserInfo;
+import com.backendsys.modules.system.entity.*;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 
@@ -15,7 +12,10 @@ public interface SysAuthV2Service {
 
     void renderCaptcha(HttpServletResponse response) throws IOException;
     List<SysMobileArea> getMobileAreaList(SysMobileArea sysMobileArea);
+
     SysUserInfo login(SysAuth sysAuth);
+    Map<String, Object> register(SysUserDTO sysUserDTO);
+
     SysUserInfo loginWithPhone(SysAuthPhone sysAuthPhone);
 
 }

+ 105 - 27
src/main/java/com/backendsys/modules/system/service/impl/SysAuthV2ServiceImpl.java

@@ -2,6 +2,7 @@ package com.backendsys.modules.system.service.impl;
 
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.json.JSONUtil;
+import com.backendsys.config.Kaptcha.KaptchaUtil;
 import com.backendsys.exception.CustException;
 import com.backendsys.modules.common.config.redis.utils.RedisUtil;
 import com.backendsys.modules.common.config.security.entity.SecurityUserInfo;
@@ -30,20 +31,17 @@ import javax.imageio.ImageIO;
 import java.awt.image.BufferedImage;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
+import java.util.*;
 import java.util.concurrent.TimeUnit;
 
 @Service
 public class SysAuthV2ServiceImpl implements SysAuthV2Service {
 
-    @Autowired
-    private RedisUtil redisUtil;
     @Autowired
     private JwtUtil jwtUtil;
     @Autowired
+    private RedisUtil redisUtil;
+    @Autowired
     private HttpRequestUtil httpRequestUtil;
     @Autowired
     private CountUtilV2 countUtilV2;
@@ -68,6 +66,13 @@ public class SysAuthV2ServiceImpl implements SysAuthV2Service {
     @Value("${TOKEN_DURATION_SYSTEM}")
     private Integer TOKEN_DURATION_SYSTEM;
 
+    @Value("${spring.application.name}")
+    private String APPLICATION_NAME;
+    private String redisKeyOfLogin = APPLICATION_NAME + "-sms-login";
+    private String redisKeyOfRegister = APPLICATION_NAME + "-sms-register";
+    private String redisKeyOfLoginFail = APPLICATION_NAME + "-login-error";
+    private String redisKeyOfRegisterFail = APPLICATION_NAME + "-register-error";
+
     @Override
     public void renderCaptcha(HttpServletResponse response) throws IOException {
         byte[] captchaChallengeAsJpeg;
@@ -103,9 +108,10 @@ public class SysAuthV2ServiceImpl implements SysAuthV2Service {
 
     // [方法] 登录失败 (errMsg: 错误提示文本, username: 用户名, intercept: 是否拦截)
     private void loginFail(String errMsg, String username, Boolean isIntercept) {
+        // 删除图形验证码
         redisUtil.delete(httpRequestUtil.getKaptchaKey());
         // 添加登录错误的冻结标记
-        if (isIntercept) countUtilV2.setErrorCount("login-error", username);
+        if (isIntercept) countUtilV2.setErrorCount(redisKeyOfLoginFail, username);
         throw new CustException(errMsg, ResultEnum.INVALID_CREDENTIALS.getCode());
     }
 
@@ -116,7 +122,7 @@ public class SysAuthV2ServiceImpl implements SysAuthV2Service {
         SysUserInfo sysUserInfo = sysUserV2Service.selectUserInfo(user_id);
 
         // 清除缓存
-        redisUtil.delete(httpRequestUtil.getKaptchaKey());                       // 作废验证码密钥
+        redisUtil.delete(httpRequestUtil.getKaptchaKey());                       // 删除图形验证码
         redisUtil.delete("token:id:" + sysUserInfo.getLast_login_uuid());   // 删除旧的登录缓存 (Redis)
 
         // 判断用户是否审核
@@ -154,6 +160,9 @@ public class SysAuthV2ServiceImpl implements SysAuthV2Service {
         return sysUserInfo;
     }
 
+    /**
+     * 登录 (用户名)
+     */
     @Override
     @Transactional
     public SysUserInfo login(SysAuth sysAuth) {
@@ -163,17 +172,17 @@ public class SysAuthV2ServiceImpl implements SysAuthV2Service {
         String captcha = sysAuth.getCaptcha();
 
         // 判断是否处于登录错误的冻结状态 (2分钟内错误5次,则出现冻结提示)
-        countUtilV2.checkErrorStatus("login-error", username);
+        countUtilV2.checkErrorStatus(redisKeyOfLoginFail, username);
 
-        // [Method] 判断验证码是否正确 (RedisKey: (ua + ip))
+        // 判断图形验证码是否正确
         if (!captchaUtil.isCaptchaValid(captcha, httpRequestUtil.getKaptchaKey())) {
             loginFail("验证码错误", username, false);
             return null;
         }
 
         // [Method] 判断 用户 是否存在 && 密码是否正确
-        SysUser sysUserSimple = sysUserDao.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
-        if (sysUserSimple == null) {
+        SysUser sysUser = sysUserDao.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
+        if (sysUser == null) {
             // [登录失败] 用户不存在
             loginFail("用户名或密码错误", username, true);
             return null;
@@ -181,16 +190,86 @@ public class SysAuthV2ServiceImpl implements SysAuthV2Service {
 
             // [登录失败] 密码不正确
             BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
-            if (!encoder.matches(password, sysUserSimple.getPassword())) {
+            if (!encoder.matches(password, sysUser.getPassword())) {
                 loginFail("用户名或密码错误", username, true);
             }
 
             // [登录成功]
-            return loginSuccess(sysUserSimple.getId(), sysAuth.getIs_remember());
+            return loginSuccess(sysUser.getId(), sysAuth.getIs_remember());
         }
 
     }
 
+    @Override
+    @Transactional
+    public Map<String, Object> register(SysUserDTO sysUserDTO) {
+
+        String username = sysUserDTO.getUsername();
+        String password = sysUserDTO.getPassword();
+        String captcha = sysUserDTO.getCaptcha();
+
+        String phone = sysUserDTO.getPhone();
+        Integer phoneAreaCode = sysUserDTO.getPhone_area_code();
+        Integer phoneValidCode = sysUserDTO.getPhone_valid_code();
+
+        // -- 参数校验 --------------------------------------------------------------
+
+        // 判断是否处于登录错误的冻结状态 (2分钟内错误5次,则出现冻结提示)
+        countUtilV2.checkErrorStatus(redisKeyOfRegisterFail, username);
+        countUtilV2.checkErrorStatus(redisKeyOfRegisterFail, phone);
+
+        // 判断图形验证码是否正确
+        if (!captchaUtil.isCaptchaValid(captcha, httpRequestUtil.getKaptchaKey())) {
+            loginFail("验证码错误", username, false);
+            return null;
+        }
+
+
+        // [查询] 判断用户名是否存在
+        SysUser sysUser1 = sysUserDao.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
+        if (sysUser1 != null) throw new CustException("用户名 (" + username + ") 已被注册");
+        
+        // 判断短信验证码是否正确
+        String redisKey = redisKeyOfLogin + "-" + phone;
+        Integer smsCode = redisUtil.getCacheObject(redisKey);
+        // 判断是否发送验证码
+        if ("false".equals(SMS_DEBUG) && smsCode == null) throw new CustException("请先发送验证码");
+        // 判断短信验证码是否错误
+        if ("false".equals(SMS_DEBUG) && !smsCode.equals(phoneValidCode)) loginFail("短信验证码错误", phone, true);
+
+
+        // [查询] 判断手机号是否存在
+        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(SysUser::getPhone, phone).eq(SysUser::getPhone_area_code, phoneAreaCode);
+        SysUser sysUser2 = sysUserDao.selectOne(queryWrapper);
+        if (sysUser2 != null) throw new CustException("手机号码 (+" + phoneAreaCode + " " + phone + ") 已被注册");
+        
+        // -- 通过校验 --------------------------------------------------------------
+
+        // 密码二次加密
+        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
+        String encodedPassword = encoder.encode(password);
+        sysUserDTO.setPassword(encodedPassword);
+
+        // 注册
+        SysUserDTO registerEntity = new SysUserDTO();
+        registerEntity.setUsername(sysUserDTO.getUsername());
+        registerEntity.setPhone(sysUserDTO.getPhone());
+        registerEntity.setPhone_area_code(sysUserDTO.getPhone_area_code());
+        registerEntity.setPassword(sysUserDTO.getPassword());
+        // 注册时,默认使用 游客 2L 权限
+        registerEntity.setRole_id(Arrays.asList(2L));
+        registerEntity.setInvite_code(sysUserDTO.getInvite_code());
+        // 注册时,状态为禁用
+        registerEntity.setStatus(-1);
+
+        sysUserDao.insertUser(registerEntity);
+        return Map.of("user_id", registerEntity.getId());
+    }
+
+    /**
+     * 登录 (手机号码)
+     */
     @Override
     @Transactional
     public SysUserInfo loginWithPhone(SysAuthPhone sysAuthPhone) {
@@ -200,30 +279,29 @@ public class SysAuthV2ServiceImpl implements SysAuthV2Service {
         Integer phoneValidCode = sysAuthPhone.getPhone_valid_code();
 
         // 判断是否处于登录错误的冻结状态 (2分钟内错误5次,则出现冻结提示)
-        countUtilV2.checkErrorStatus("login-error", sysAuthPhone.getPhone());
+        countUtilV2.checkErrorStatus(redisKeyOfLoginFail, phone);
 
-        // [Redis] 验证码缓存
-        String redisKey = "sms-login-" + phone;
+        // 判断短信验证码是否正确
+        String redisKey = redisKeyOfLogin + "-" + phone;
         Integer smsCode = redisUtil.getCacheObject(redisKey);
-
         // 判断是否发送验证码
-        if ("false".equals(SMS_DEBUG) &&smsCode == null) throw new CustException("请先发送验证码");
+        if ("false".equals(SMS_DEBUG) && smsCode == null) throw new CustException("请先发送验证码");
         // 判断短信验证码是否错误
         if ("false".equals(SMS_DEBUG) && !smsCode.equals(phoneValidCode)) loginFail("短信验证码错误", phone, true);
 
-        // [Method] 判断手机号是否存在
-        SysUser sysUserSimple = sysUserDao.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhone, phone));
-        if (sysUserSimple == null) {
-            // [登录失败] 用户不存在
+        // 判断手机号是否存在
+        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(SysUser::getPhone, phone).eq(SysUser::getPhone_area_code, phoneAreaCode);
+        SysUser sysUser = sysUserDao.selectOne(queryWrapper);
+        if (sysUser == null) {
+            // [登录失败] 用户不存在 (并不会销毁短信验证码)
             loginFail("手机号码不存在", phone, true);
             return null;
         } else {
-
-            // 登录成功,销毁 smsCode
+            // 登录成功,销毁短信验证码
             redisUtil.delete(redisKey);
-
             // [登录成功]
-            return loginSuccess(sysUserSimple.getId(), sysAuthPhone.getIs_remember());
+            return loginSuccess(sysUser.getId(), sysAuthPhone.getIs_remember());
         }
 
     }

+ 17 - 4
src/main/java/com/backendsys/modules/system/service/impl/SysUserV2ServiceImpl.java

@@ -196,10 +196,23 @@ public class SysUserV2ServiceImpl extends ServiceImpl<SysUserDao, SysUser> imple
         RLock lock = redissonClient.getLock("insertUser");
         try { lock.tryLock(3, TimeUnit.SECONDS);
 
-            // 判断手机号码是否存在
-            if (sysUserDTO.getPhone() != null) {
-                SysUser sysUser = sysUserDao.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhone, sysUserDTO.getPhone()));
-                if (sysUser != null) throw new CustException("手机号码已存在");
+            String phone = sysUserDTO.getPhone();
+            Integer phoneAreaCode = sysUserDTO.getPhone_area_code();
+            String username = sysUserDTO.getUsername();
+
+            // [查询] 判断用户名是否存在
+            if (username != null) {
+                SysUser sysUser1 = sysUserDao.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
+                if (sysUser1 != null) throw new CustException("用户名 (" + username + ") 已存在");
+            }
+
+            // [查询] 判断手机号是否存在
+            if (phone != null) {
+                LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
+                queryWrapper.eq(SysUser::getPhone, phone);
+                queryWrapper.eq(SysUser::getPhone_area_code, phoneAreaCode);
+                SysUser sysUser2 = sysUserDao.selectOne(queryWrapper);
+                if (sysUser2 != null) throw new CustException("手机号码 (+" + phoneAreaCode + " " + phone + ") 已存在");
             }
 
             // 密码二次加密

+ 2 - 0
src/main/resources/application-local.yml

@@ -21,6 +21,8 @@ log-stream:
   exec: 'powershell -Command "Get-Content -Path D:\CodeJava\QuickLaunchSpring\BackendSys\logs\backendsys.log -Wait"'
 
 spring:
+  application:
+    name: backendsys
   config:
     name: application-local
   datasource:

+ 2 - 0
src/main/resources/application-prod.yml

@@ -21,6 +21,8 @@ log-stream:
   exec: 'tail -f /logs/backendsys.log'
 
 spring:
+  application:
+    name: backendsys
   config:
     name: application-prod
   datasource: