|
@@ -94,6 +94,7 @@ public class AuthService {
|
|
|
// 3. 更新登录信息
|
|
// 3. 更新登录信息
|
|
|
user.setLastLoginTime(LocalDateTime.now());
|
|
user.setLastLoginTime(LocalDateTime.now());
|
|
|
user.setLastLoginIp(ip);
|
|
user.setLastLoginIp(ip);
|
|
|
|
|
+ user.setLoginSource("PC");
|
|
|
userMapper.updateById(user);
|
|
userMapper.updateById(user);
|
|
|
|
|
|
|
|
// 4. 生成Token
|
|
// 4. 生成Token
|
|
@@ -130,6 +131,7 @@ public class AuthService {
|
|
|
if (user != null && user.getPhone() != null) {
|
|
if (user != null && user.getPhone() != null) {
|
|
|
user.setLastLoginTime(LocalDateTime.now());
|
|
user.setLastLoginTime(LocalDateTime.now());
|
|
|
user.setLastLoginIp(ip);
|
|
user.setLastLoginIp(ip);
|
|
|
|
|
+ user.setLoginSource("PC");
|
|
|
userMapper.updateById(user);
|
|
userMapper.updateById(user);
|
|
|
return buildLoginResponse(user);
|
|
return buildLoginResponse(user);
|
|
|
}
|
|
}
|
|
@@ -211,6 +213,7 @@ public class AuthService {
|
|
|
existUser.setWechatUnionId(unionId);
|
|
existUser.setWechatUnionId(unionId);
|
|
|
existUser.setLastLoginTime(LocalDateTime.now());
|
|
existUser.setLastLoginTime(LocalDateTime.now());
|
|
|
existUser.setLastLoginIp(ip);
|
|
existUser.setLastLoginIp(ip);
|
|
|
|
|
+ existUser.setLoginSource("PC");
|
|
|
userMapper.updateById(existUser);
|
|
userMapper.updateById(existUser);
|
|
|
|
|
|
|
|
// 删除旧的微信用户
|
|
// 删除旧的微信用户
|
|
@@ -219,7 +222,7 @@ public class AuthService {
|
|
|
} else if (existUser == null) {
|
|
} else if (existUser == null) {
|
|
|
// 绑定手机号到微信用户(首次完成注册)
|
|
// 绑定手机号到微信用户(首次完成注册)
|
|
|
wechatUser.setPhone(request.getPhone());
|
|
wechatUser.setPhone(request.getPhone());
|
|
|
- wechatUser.setLoginSource("WECHAT");
|
|
|
|
|
|
|
+ wechatUser.setLoginSource("PC");
|
|
|
wechatUser.setLastLoginTime(LocalDateTime.now());
|
|
wechatUser.setLastLoginTime(LocalDateTime.now());
|
|
|
wechatUser.setLastLoginIp(ip);
|
|
wechatUser.setLastLoginIp(ip);
|
|
|
userMapper.updateById(wechatUser);
|
|
userMapper.updateById(wechatUser);
|
|
@@ -234,12 +237,7 @@ public class AuthService {
|
|
|
return buildLoginResponse(wechatUser);
|
|
return buildLoginResponse(wechatUser);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * 心跳保活(零DB查询,仅一次blind UPDATE,高性能)
|
|
|
|
|
- * <p>
|
|
|
|
|
- * 不递增 tokenVersion(同一设备续期),使用 JWT 中已有信息签发新 Token。
|
|
|
|
|
- * 过滤层已校验 tokenVersion 和用户存在性,这里直接签发。
|
|
|
|
|
- */
|
|
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 外部系统换取小程序 Token(供小程序后台按手机号签发)
|
|
* 外部系统换取小程序 Token(供小程序后台按手机号签发)
|
|
|
* <p>查找或自动注册用户,不递增 tokenVersion,不踢 PC。
|
|
* <p>查找或自动注册用户,不递增 tokenVersion,不踢 PC。
|
|
@@ -252,9 +250,23 @@ public class AuthService {
|
|
|
boolean isNewUser = false;
|
|
boolean isNewUser = false;
|
|
|
if (user == null) {
|
|
if (user == null) {
|
|
|
isNewUser = true;
|
|
isNewUser = true;
|
|
|
|
|
+ // 优先级:nickname > username > 手机号生成
|
|
|
|
|
+ String nickname = (request.getNickname() != null && !request.getNickname().isBlank())
|
|
|
|
|
+ ? request.getNickname()
|
|
|
|
|
+ : (request.getUsername() != null && !request.getUsername().isBlank())
|
|
|
|
|
+ ? request.getUsername()
|
|
|
|
|
+ : "用户" + request.getPhone().substring(request.getPhone().length() - 4);
|
|
|
user = User.builder()
|
|
user = User.builder()
|
|
|
.phone(request.getPhone())
|
|
.phone(request.getPhone())
|
|
|
- .nickname("用户" + request.getPhone().substring(request.getPhone().length() - 4))
|
|
|
|
|
|
|
+ .nickname(nickname)
|
|
|
|
|
+ .pharmacyName(request.getPharmacyName())
|
|
|
|
|
+ .province(request.getProvince())
|
|
|
|
|
+ .city(request.getCity())
|
|
|
|
|
+ .district(request.getDistrict())
|
|
|
|
|
+ .pharmacyAddress(request.getPharmacyAddress())
|
|
|
|
|
+ .contactPerson(request.getContactPerson())
|
|
|
|
|
+ .contactPhone(request.getContactPhone())
|
|
|
|
|
+ .businessLicenseNo(request.getBusinessLicenseNo())
|
|
|
.membershipLevel(MembershipLevel.PLUS)
|
|
.membershipLevel(MembershipLevel.PLUS)
|
|
|
.loginSource("MINIAPP")
|
|
.loginSource("MINIAPP")
|
|
|
.status(1)
|
|
.status(1)
|
|
@@ -265,6 +277,38 @@ public class AuthService {
|
|
|
eventPublisher.publishEvent(
|
|
eventPublisher.publishEvent(
|
|
|
new UserRegisteredEvent(this, user.getId(), request.getInviteCode()));
|
|
new UserRegisteredEvent(this, user.getId(), request.getInviteCode()));
|
|
|
}
|
|
}
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 已存在用户:更新第三方传入的信息(非空字段才覆盖,避免清空已有数据)
|
|
|
|
|
+ // username 优先级高于 nickname,都保存到 nickname 字段
|
|
|
|
|
+ if (request.getUsername() != null && !request.getUsername().isBlank()) {
|
|
|
|
|
+ user.setNickname(request.getUsername());
|
|
|
|
|
+ } else if (request.getNickname() != null && !request.getNickname().isBlank()) {
|
|
|
|
|
+ user.setNickname(request.getNickname());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (request.getPharmacyName() != null && !request.getPharmacyName().isBlank()) {
|
|
|
|
|
+ user.setPharmacyName(request.getPharmacyName());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (request.getProvince() != null && !request.getProvince().isBlank()) {
|
|
|
|
|
+ user.setProvince(request.getProvince());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (request.getCity() != null && !request.getCity().isBlank()) {
|
|
|
|
|
+ user.setCity(request.getCity());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (request.getDistrict() != null && !request.getDistrict().isBlank()) {
|
|
|
|
|
+ user.setDistrict(request.getDistrict());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (request.getPharmacyAddress() != null && !request.getPharmacyAddress().isBlank()) {
|
|
|
|
|
+ user.setPharmacyAddress(request.getPharmacyAddress());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (request.getContactPerson() != null && !request.getContactPerson().isBlank()) {
|
|
|
|
|
+ user.setContactPerson(request.getContactPerson());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (request.getContactPhone() != null && !request.getContactPhone().isBlank()) {
|
|
|
|
|
+ user.setContactPhone(request.getContactPhone());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (request.getBusinessLicenseNo() != null && !request.getBusinessLicenseNo().isBlank()) {
|
|
|
|
|
+ user.setBusinessLicenseNo(request.getBusinessLicenseNo());
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
user.setLoginSource("MINIAPP");
|
|
user.setLoginSource("MINIAPP");
|
|
@@ -288,12 +332,14 @@ public class AuthService {
|
|
|
User user = userMapper.selectById(userId);
|
|
User user = userMapper.selectById(userId);
|
|
|
currentVersion = user != null && user.getTokenVersion() != null
|
|
currentVersion = user != null && user.getTokenVersion() != null
|
|
|
? user.getTokenVersion() : 0L;
|
|
? user.getTokenVersion() : 0L;
|
|
|
- if (user != null) tokenVersionCache.putVersion(userId, false, currentVersion);
|
|
|
|
|
|
|
+ if (user != null) {
|
|
|
|
|
+ tokenVersionCache.putVersion(userId, false, currentVersion);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
String newAccessToken = jwtUtil.generateAccessToken(
|
|
String newAccessToken = jwtUtil.generateAccessToken(
|
|
|
userId, roleCode, loginSource, currentVersion);
|
|
userId, roleCode, loginSource, currentVersion);
|
|
|
- String newRefreshToken = jwtUtil.generateRefreshToken(userId);
|
|
|
|
|
|
|
+ String newRefreshToken = jwtUtil.generateRefreshToken(userId, loginSource);
|
|
|
|
|
|
|
|
User updateUser = new User();
|
|
User updateUser = new User();
|
|
|
updateUser.setId(userId);
|
|
updateUser.setId(userId);
|
|
@@ -332,8 +378,7 @@ public class AuthService {
|
|
|
java.util.Map<String, Object> quota = buildQuotaSummary(userId);
|
|
java.util.Map<String, Object> quota = buildQuotaSummary(userId);
|
|
|
java.util.List<?> platforms = getPlatformBindings(userId);
|
|
java.util.List<?> platforms = getPlatformBindings(userId);
|
|
|
|
|
|
|
|
- java.util.Map<String, Object> result = new java.util.LinkedHashMap<>();
|
|
|
|
|
- result.putAll(toMap(userInfo));
|
|
|
|
|
|
|
+ java.util.Map<String, Object> result = new java.util.LinkedHashMap<>(toMap(userInfo));
|
|
|
result.put("gate", gate);
|
|
result.put("gate", gate);
|
|
|
result.put("quota", quota);
|
|
result.put("quota", quota);
|
|
|
result.put("platformBindings", platforms);
|
|
result.put("platformBindings", platforms);
|
|
@@ -426,7 +471,7 @@ public class AuthService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 5. 签发正式 Token
|
|
// 5. 签发正式 Token
|
|
|
- LoginResponse response = buildLoginResponse(user);
|
|
|
|
|
|
|
+ LoginResponse response = buildMiniAppLoginResponse(user);
|
|
|
auditLogService.logSuccess(user.getId(), user.getNickname(), "USER",
|
|
auditLogService.logSuccess(user.getId(), user.getNickname(), "USER",
|
|
|
OperationType.USER_REGISTER, "USER:" + user.getId(), user.getId());
|
|
OperationType.USER_REGISTER, "USER:" + user.getId(), user.getId());
|
|
|
return response;
|
|
return response;
|
|
@@ -491,7 +536,6 @@ public class AuthService {
|
|
|
}).toList();
|
|
}).toList();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
|
|
private java.util.Map<String, Object> toMap(UserInfoResponse info) {
|
|
private java.util.Map<String, Object> toMap(UserInfoResponse info) {
|
|
|
// 简单反射转 Map,避免引入额外依赖
|
|
// 简单反射转 Map,避免引入额外依赖
|
|
|
java.util.Map<String, Object> map = new java.util.LinkedHashMap<>();
|
|
java.util.Map<String, Object> map = new java.util.LinkedHashMap<>();
|
|
@@ -570,10 +614,11 @@ public class AuthService {
|
|
|
user.setRefreshTokenStatus("USED");
|
|
user.setRefreshTokenStatus("USED");
|
|
|
String roleCode = "USER";
|
|
String roleCode = "USER";
|
|
|
long currentVersion = user.getTokenVersion() != null ? user.getTokenVersion() : 0L;
|
|
long currentVersion = user.getTokenVersion() != null ? user.getTokenVersion() : 0L;
|
|
|
|
|
+ String loginSource = jwtUtil.getLoginSource(refreshToken);
|
|
|
|
|
|
|
|
String newAccessToken = jwtUtil.generateAccessToken(
|
|
String newAccessToken = jwtUtil.generateAccessToken(
|
|
|
- user.getId(), roleCode, currentVersion);
|
|
|
|
|
- String newRefreshToken = jwtUtil.generateRefreshToken(user.getId());
|
|
|
|
|
|
|
+ user.getId(), roleCode, loginSource, currentVersion);
|
|
|
|
|
+ String newRefreshToken = jwtUtil.generateRefreshToken(user.getId(), loginSource);
|
|
|
|
|
|
|
|
// 存储新 Refresh Token 哈希
|
|
// 存储新 Refresh Token 哈希
|
|
|
user.setRefreshTokenHash(JwtUtil.hashToken(newRefreshToken));
|
|
user.setRefreshTokenHash(JwtUtil.hashToken(newRefreshToken));
|
|
@@ -596,18 +641,17 @@ public class AuthService {
|
|
|
/** PC 端构建登录响应:
|
|
/** PC 端构建登录响应:
|
|
|
* 递增 tokenVersion,踢掉旧 PC */
|
|
* 递增 tokenVersion,踢掉旧 PC */
|
|
|
private LoginResponse buildLoginResponse(User user) {
|
|
private LoginResponse buildLoginResponse(User user) {
|
|
|
- return buildLoginResponseInternal(user, true);
|
|
|
|
|
|
|
+ return buildLoginResponseInternal(user, true, "PC");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/** 小程序构建登录响应:不递增 tokenVersion,不踢 PC */
|
|
/** 小程序构建登录响应:不递增 tokenVersion,不踢 PC */
|
|
|
private LoginResponse buildMiniAppLoginResponse(User user) {
|
|
private LoginResponse buildMiniAppLoginResponse(User user) {
|
|
|
- return buildLoginResponseInternal(user, false);
|
|
|
|
|
|
|
+ return buildLoginResponseInternal(user, false, "MINIAPP");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private LoginResponse buildLoginResponseInternal(User user, boolean incrementVersion) {
|
|
|
|
|
|
|
+ private LoginResponse buildLoginResponseInternal(User user, boolean incrementVersion, String loginSource) {
|
|
|
MDC.put("uid", String.valueOf(user.getId()));
|
|
MDC.put("uid", String.valueOf(user.getId()));
|
|
|
String roleCode = "USER";
|
|
String roleCode = "USER";
|
|
|
- String loginSource = user.getLoginSource() != null ? user.getLoginSource() : "UNKNOWN";
|
|
|
|
|
|
|
|
|
|
long version;
|
|
long version;
|
|
|
if (incrementVersion) {
|
|
if (incrementVersion) {
|
|
@@ -621,7 +665,7 @@ public class AuthService {
|
|
|
|
|
|
|
|
String accessToken = jwtUtil.generateAccessToken(
|
|
String accessToken = jwtUtil.generateAccessToken(
|
|
|
user.getId(), "USER", loginSource, version);
|
|
user.getId(), "USER", loginSource, version);
|
|
|
- String refreshToken = jwtUtil.generateRefreshToken(user.getId());
|
|
|
|
|
|
|
+ String refreshToken = jwtUtil.generateRefreshToken(user.getId(), loginSource);
|
|
|
|
|
|
|
|
user.setRefreshTokenHash(JwtUtil.hashToken(refreshToken));
|
|
user.setRefreshTokenHash(JwtUtil.hashToken(refreshToken));
|
|
|
user.setRefreshTokenStatus("ACTIVE");
|
|
user.setRefreshTokenStatus("ACTIVE");
|
|
@@ -732,6 +776,7 @@ public class AuthService {
|
|
|
// 5. 更新登录信息
|
|
// 5. 更新登录信息
|
|
|
user.setLastLoginTime(LocalDateTime.now());
|
|
user.setLastLoginTime(LocalDateTime.now());
|
|
|
user.setLastLoginIp(ip);
|
|
user.setLastLoginIp(ip);
|
|
|
|
|
+ user.setLoginSource("PC");
|
|
|
userMapper.updateById(user);
|
|
userMapper.updateById(user);
|
|
|
|
|
|
|
|
// 6. 生成Token
|
|
// 6. 生成Token
|
|
@@ -1038,4 +1083,4 @@ public class AuthService {
|
|
|
log.warn("外部系统注册失败(不阻断主流程): userId={}", user.getId(), e);
|
|
log.warn("外部系统注册失败(不阻断主流程): userId={}", user.getId(), e);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-}
|
|
|
|
|
|
|
+}
|