|
@@ -11,14 +11,14 @@ import com.zxyj.mapper.ChildMapper;
|
|
|
import com.zxyj.mapper.FamilyMapper;
|
|
import com.zxyj.mapper.FamilyMapper;
|
|
|
import com.zxyj.mapper.UserMapper;
|
|
import com.zxyj.mapper.UserMapper;
|
|
|
import com.zxyj.service.VerificationCodeService;
|
|
import com.zxyj.service.VerificationCodeService;
|
|
|
|
|
+import com.zxyj.service.WechatService;
|
|
|
import javax.annotation.Resource;
|
|
import javax.annotation.Resource;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.util.DigestUtils;
|
|
import org.springframework.util.DigestUtils;
|
|
|
|
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.nio.charset.StandardCharsets;
|
|
|
-import java.util.Date;
|
|
|
|
|
-import java.util.List;
|
|
|
|
|
-import java.util.UUID;
|
|
|
|
|
|
|
+import java.util.*;
|
|
|
|
|
+
|
|
|
|
|
|
|
|
@Service
|
|
@Service
|
|
|
public class UserService {
|
|
public class UserService {
|
|
@@ -38,6 +38,9 @@ private JwtConfig jwtConfig;
|
|
|
@Resource
|
|
@Resource
|
|
|
private VerificationCodeService verificationCodeService;
|
|
private VerificationCodeService verificationCodeService;
|
|
|
|
|
|
|
|
|
|
+@Resource
|
|
|
|
|
+private WechatService wechatService;
|
|
|
|
|
+
|
|
|
public LoginResultDTO wechatLogin(WechatLoginDTO dto) {
|
|
public LoginResultDTO wechatLogin(WechatLoginDTO dto) {
|
|
|
// 模拟微信登录,实际需要调用微信API获取openid
|
|
// 模拟微信登录,实际需要调用微信API获取openid
|
|
|
String openid = "mock_openid_" + dto.getCode();
|
|
String openid = "mock_openid_" + dto.getCode();
|
|
@@ -81,45 +84,131 @@ private VerificationCodeService verificationCodeService;
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * 手机号验证码登录
|
|
|
|
|
+ */
|
|
|
|
|
+public LoginResultDTO phoneLogin(PhoneLoginDTO dto) {
|
|
|
|
|
+ // 使用手机号作为唯一标识
|
|
|
|
|
+ String phone = dto.getPhone();
|
|
|
|
|
+
|
|
|
|
|
+ // 先通过手机号查找用户(更准确的判断)
|
|
|
|
|
+ User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
|
|
|
|
|
+ .eq(User::getPhone, phone));
|
|
|
|
|
+
|
|
|
|
|
+ boolean isNewUser = false;
|
|
|
|
|
+
|
|
|
|
|
+ if (user == null) {
|
|
|
|
|
+ // 新用户,创建新家庭和用户
|
|
|
|
|
+ isNewUser = true;
|
|
|
|
|
+
|
|
|
|
|
+ Family family = new Family();
|
|
|
|
|
+ family.setName("我的家庭");
|
|
|
|
|
+ family.setInviteCode(generateInviteCode());
|
|
|
|
|
+ family.setCreatedAt(new Date());
|
|
|
|
|
+ family.setUpdatedAt(new Date());
|
|
|
|
|
+ familyMapper.insert(family);
|
|
|
|
|
+
|
|
|
|
|
+ user = new User();
|
|
|
|
|
+ user.setOpenid("phone:" + phone);
|
|
|
|
|
+ user.setUnionid("");
|
|
|
|
|
+ user.setFamilyId(family.getId());
|
|
|
|
|
+ // 默认角色为家长,可以被覆盖
|
|
|
|
|
+ user.setRole(dto.getRole() != null ? dto.getRole() : "parent");
|
|
|
|
|
+ user.setNickname(dto.getNickname() != null ? dto.getNickname() : "用户" + phone.substring(7));
|
|
|
|
|
+ user.setAvatar(dto.getAvatar());
|
|
|
|
|
+ user.setPhone(phone);
|
|
|
|
|
+ user.setBirthday(dto.getBirthday());
|
|
|
|
|
+ user.setGender(dto.getGender());
|
|
|
|
|
+ user.setPassword("");
|
|
|
|
|
+ user.setCreatedAt(new Date());
|
|
|
|
|
+ user.setUpdatedAt(new Date());
|
|
|
|
|
+ userMapper.insert(user);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 老用户,更新信息(如果提供了)
|
|
|
|
|
+ if (dto.getNickname() != null && !dto.getNickname().isEmpty()) {
|
|
|
|
|
+ user.setNickname(dto.getNickname());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (dto.getAvatar() != null && !dto.getAvatar().isEmpty()) {
|
|
|
|
|
+ user.setAvatar(dto.getAvatar());
|
|
|
|
|
+ }
|
|
|
|
|
+ user.setUpdatedAt(new Date());
|
|
|
|
|
+ userMapper.updateById(user);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 生成token
|
|
|
|
|
+ String token = jwtConfig.generateToken(user.getId(), user.getRole());
|
|
|
|
|
+
|
|
|
|
|
+ LoginResultDTO result = new LoginResultDTO();
|
|
|
|
|
+ result.setToken(token);
|
|
|
|
|
+ result.setUserId(user.getId());
|
|
|
|
|
+ result.setRole(user.getRole());
|
|
|
|
|
+ result.setFamilyId(user.getFamilyId());
|
|
|
|
|
+ result.setNickname(user.getNickname());
|
|
|
|
|
+ result.setIsNewUser(isNewUser);
|
|
|
|
|
+
|
|
|
|
|
+ return result;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
- * 手机号验证码登录
|
|
|
|
|
|
|
+ * 微信手机号登录(正确获取openid和手机号)
|
|
|
*/
|
|
*/
|
|
|
- public LoginResultDTO phoneLogin(PhoneLoginDTO dto) {
|
|
|
|
|
- // 使用手机号作为唯一标识
|
|
|
|
|
- String phone = dto.getPhone();
|
|
|
|
|
|
|
+ public LoginResultDTO wechatPhoneLogin(WechatPhoneLoginDTO dto) {
|
|
|
|
|
+ // 1. 通过code获取openid
|
|
|
|
|
+ Map<String, String> sessionData = wechatService.code2Session(dto.getCode());
|
|
|
|
|
+ String openid = sessionData.get("openid");
|
|
|
|
|
+ String unionid = sessionData.get("unionid");
|
|
|
|
|
|
|
|
- // 查询用户是否存在
|
|
|
|
|
|
|
+ // 2. 通过手机号code获取真实手机号
|
|
|
|
|
+ String phone = wechatService.getPhoneNumber(dto.getPhoneCode());
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 先通过openid查找用户
|
|
|
User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
|
|
User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
|
|
|
- .eq(User::getOpenid, "phone:" + phone));
|
|
|
|
|
|
|
+ .eq(User::getOpenid, openid));
|
|
|
|
|
|
|
|
boolean isNewUser = false;
|
|
boolean isNewUser = false;
|
|
|
|
|
|
|
|
if (user == null) {
|
|
if (user == null) {
|
|
|
- // 新用户,创建新家庭和用户
|
|
|
|
|
- isNewUser = true;
|
|
|
|
|
-
|
|
|
|
|
- Family family = new Family();
|
|
|
|
|
- family.setName("我的家庭");
|
|
|
|
|
- family.setInviteCode(generateInviteCode());
|
|
|
|
|
- family.setCreatedAt(new Date());
|
|
|
|
|
- family.setUpdatedAt(new Date());
|
|
|
|
|
- familyMapper.insert(family);
|
|
|
|
|
-
|
|
|
|
|
- user = new User();
|
|
|
|
|
- user.setOpenid("phone:" + phone);
|
|
|
|
|
- user.setUnionid("");
|
|
|
|
|
- user.setFamilyId(family.getId());
|
|
|
|
|
- // 默认角色为家长,可以被覆盖
|
|
|
|
|
- user.setRole(dto.getRole() != null ? dto.getRole() : "parent");
|
|
|
|
|
- user.setNickname(dto.getNickname() != null ? dto.getNickname() : "用户" + phone.substring(7));
|
|
|
|
|
- user.setAvatar(dto.getAvatar());
|
|
|
|
|
- user.setPhone(phone);
|
|
|
|
|
- user.setBirthday(dto.getBirthday());
|
|
|
|
|
- user.setGender(dto.getGender());
|
|
|
|
|
- user.setPassword("");
|
|
|
|
|
- user.setCreatedAt(new Date());
|
|
|
|
|
- user.setUpdatedAt(new Date());
|
|
|
|
|
- userMapper.insert(user);
|
|
|
|
|
|
|
+ // 4. openid不存在,通过手机号查找
|
|
|
|
|
+ user = userMapper.selectOne(new LambdaQueryWrapper<User>()
|
|
|
|
|
+ .eq(User::getPhone, phone));
|
|
|
|
|
+
|
|
|
|
|
+ if (user == null) {
|
|
|
|
|
+ // 5. 全新用户,创建新家庭和用户
|
|
|
|
|
+ isNewUser = true;
|
|
|
|
|
+
|
|
|
|
|
+ Family family = new Family();
|
|
|
|
|
+ family.setName("我的家庭");
|
|
|
|
|
+ family.setInviteCode(generateInviteCode());
|
|
|
|
|
+ family.setCreatedAt(new Date());
|
|
|
|
|
+ family.setUpdatedAt(new Date());
|
|
|
|
|
+ familyMapper.insert(family);
|
|
|
|
|
+
|
|
|
|
|
+ user = new User();
|
|
|
|
|
+ user.setOpenid(openid);
|
|
|
|
|
+ user.setUnionid(unionid);
|
|
|
|
|
+ user.setFamilyId(family.getId());
|
|
|
|
|
+ user.setRole("parent");
|
|
|
|
|
+ user.setNickname(dto.getNickname() != null ? dto.getNickname() : "用户" + phone.substring(7));
|
|
|
|
|
+ user.setAvatar(dto.getAvatar());
|
|
|
|
|
+ user.setPhone(phone);
|
|
|
|
|
+ user.setPassword("");
|
|
|
|
|
+ user.setCreatedAt(new Date());
|
|
|
|
|
+ user.setUpdatedAt(new Date());
|
|
|
|
|
+ userMapper.insert(user);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 6. 手机号已存在但openid不同,绑定openid
|
|
|
|
|
+ user.setOpenid(openid);
|
|
|
|
|
+ user.setUnionid(unionid);
|
|
|
|
|
+ user.setUpdatedAt(new Date());
|
|
|
|
|
+ userMapper.updateById(user);
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 7. openid已存在,更新手机号(如果手机号变了)
|
|
|
|
|
+ if (phone != null && !phone.equals(user.getPhone())) {
|
|
|
|
|
+ user.setPhone(phone);
|
|
|
|
|
+ user.setUpdatedAt(new Date());
|
|
|
|
|
+ userMapper.updateById(user);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 生成token
|
|
// 生成token
|
|
@@ -132,6 +221,64 @@ private VerificationCodeService verificationCodeService;
|
|
|
result.setFamilyId(user.getFamilyId());
|
|
result.setFamilyId(user.getFamilyId());
|
|
|
result.setNickname(user.getNickname());
|
|
result.setNickname(user.getNickname());
|
|
|
result.setIsNewUser(isNewUser);
|
|
result.setIsNewUser(isNewUser);
|
|
|
|
|
+ result.setOpenid(openid);
|
|
|
|
|
+
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 微信openid静默登录(用户再次打开小程序时自动登录)
|
|
|
|
|
+ */
|
|
|
|
|
+ public LoginResultDTO silentLogin(String code) {
|
|
|
|
|
+ // 1. 通过code获取openid
|
|
|
|
|
+ Map<String, String> sessionData = wechatService.code2Session(code);
|
|
|
|
|
+ String openid = sessionData.get("openid");
|
|
|
|
|
+ String unionid = sessionData.get("unionid");
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 查找用户
|
|
|
|
|
+ User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
|
|
|
|
|
+ .eq(User::getOpenid, openid));
|
|
|
|
|
+
|
|
|
|
|
+ if (user == null) {
|
|
|
|
|
+ throw new RuntimeException("用户不存在,请先登录");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 生成token
|
|
|
|
|
+ String token = jwtConfig.generateToken(user.getId(), user.getRole());
|
|
|
|
|
+
|
|
|
|
|
+ LoginResultDTO result = new LoginResultDTO();
|
|
|
|
|
+ result.setToken(token);
|
|
|
|
|
+ result.setUserId(user.getId());
|
|
|
|
|
+ result.setRole(user.getRole());
|
|
|
|
|
+ result.setFamilyId(user.getFamilyId());
|
|
|
|
|
+ result.setNickname(user.getNickname());
|
|
|
|
|
+ result.setIsNewUser(false);
|
|
|
|
|
+ result.setOpenid(openid);
|
|
|
|
|
+
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 通过openid自动登录(前端已缓存openid时调用)
|
|
|
|
|
+ */
|
|
|
|
|
+ public LoginResultDTO autoLoginByOpenid(String openid) {
|
|
|
|
|
+ User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
|
|
|
|
|
+ .eq(User::getOpenid, openid));
|
|
|
|
|
+
|
|
|
|
|
+ if (user == null) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ String token = jwtConfig.generateToken(user.getId(), user.getRole());
|
|
|
|
|
+
|
|
|
|
|
+ LoginResultDTO result = new LoginResultDTO();
|
|
|
|
|
+ result.setToken(token);
|
|
|
|
|
+ result.setUserId(user.getId());
|
|
|
|
|
+ result.setRole(user.getRole());
|
|
|
|
|
+ result.setFamilyId(user.getFamilyId());
|
|
|
|
|
+ result.setNickname(user.getNickname());
|
|
|
|
|
+ result.setIsNewUser(false);
|
|
|
|
|
+ result.setOpenid(openid);
|
|
|
|
|
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
@@ -164,12 +311,139 @@ private VerificationCodeService verificationCodeService;
|
|
|
if (user == null) {
|
|
if (user == null) {
|
|
|
return null;
|
|
return null;
|
|
|
}
|
|
}
|
|
|
|
|
+ // 验证用户是否拥有该角色
|
|
|
|
|
+ if (!hasRole(user, mode)) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
user.setRole(mode);
|
|
user.setRole(mode);
|
|
|
user.setUpdatedAt(new Date());
|
|
user.setUpdatedAt(new Date());
|
|
|
userMapper.updateById(user);
|
|
userMapper.updateById(user);
|
|
|
return mode;
|
|
return mode;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 切换用户当前角色 (支持 parent/child/teacher)
|
|
|
|
|
+ * 用户需要先拥有该角色才能切换
|
|
|
|
|
+ */
|
|
|
|
|
+ public String switchRole(Long userId, String targetRole) {
|
|
|
|
|
+ User user = userMapper.selectById(userId);
|
|
|
|
|
+ if (user == null) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 验证用户是否拥有该角色
|
|
|
|
|
+ if (!hasRole(user, targetRole)) {
|
|
|
|
|
+ throw new RuntimeException("您没有该角色权限");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 检查目标角色是否有效
|
|
|
|
|
+ if (!isValidRole(targetRole)) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ user.setRole(targetRole);
|
|
|
|
|
+ user.setUpdatedAt(new Date());
|
|
|
|
|
+ userMapper.updateById(user);
|
|
|
|
|
+ return targetRole;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取用户所有角色列表
|
|
|
|
|
+ */
|
|
|
|
|
+ public List<String> getUserRoles(Long userId) {
|
|
|
|
|
+ User user = userMapper.selectById(userId);
|
|
|
|
|
+ if (user == null) {
|
|
|
|
|
+ return new ArrayList<>();
|
|
|
|
|
+ }
|
|
|
|
|
+ return parseRoles(user.getRoles());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 检查用户是否拥有指定角色
|
|
|
|
|
+ */
|
|
|
|
|
+ public boolean hasRole(Long userId, String role) {
|
|
|
|
|
+ User user = userMapper.selectById(userId);
|
|
|
|
|
+ if (user == null) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ return hasRole(user, role);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 添加角色到用户 (用于用户注册成为老师时)
|
|
|
|
|
+ */
|
|
|
|
|
+ public boolean addRole(Long userId, String newRole) {
|
|
|
|
|
+ User user = userMapper.selectById(userId);
|
|
|
|
|
+ if (user == null || !isValidRole(newRole)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 如果用户还没有roles字段,设置默认值
|
|
|
|
|
+ if (user.getRoles() == null || user.getRoles().isEmpty()) {
|
|
|
|
|
+ user.setRoles(user.getRole()); // 当前角色作为第一个角色
|
|
|
|
|
+ }
|
|
|
|
|
+ // 检查是否已拥有该角色
|
|
|
|
|
+ if (hasRole(user, newRole)) {
|
|
|
|
|
+ return true; // 已有该角色
|
|
|
|
|
+ }
|
|
|
|
|
+ // 添加新角色
|
|
|
|
|
+ List<String> roleList = parseRoles(user.getRoles());
|
|
|
|
|
+ roleList.add(newRole);
|
|
|
|
|
+ user.setRoles(joinRoles(roleList));
|
|
|
|
|
+ user.setUpdatedAt(new Date());
|
|
|
|
|
+ userMapper.updateById(user);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 检查用户是否拥有指定角色 (内部方法)
|
|
|
|
|
+ */
|
|
|
|
|
+ private boolean hasRole(User user, String role) {
|
|
|
|
|
+ List<String> roles = parseRoles(user.getRoles());
|
|
|
|
|
+ return roles.contains(role);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 解析角色字符串为列表
|
|
|
|
|
+ */
|
|
|
|
|
+ private List<String> parseRoles(String rolesStr) {
|
|
|
|
|
+ List<String> result = new ArrayList<>();
|
|
|
|
|
+ if (rolesStr == null || rolesStr.isEmpty()) {
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 支持JSON数组格式或逗号分隔格式
|
|
|
|
|
+ if (rolesStr.startsWith("[")) {
|
|
|
|
|
+ // JSON格式解析
|
|
|
|
|
+ rolesStr = rolesStr.replace("[", "").replace("]", "")
|
|
|
|
|
+ .replace("\"", "").replace(" ", "");
|
|
|
|
|
+ String[] arr = rolesStr.split(",");
|
|
|
|
|
+ for (String r : arr) {
|
|
|
|
|
+ if (!r.isEmpty()) {
|
|
|
|
|
+ result.add(r.trim());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 逗号分隔格式
|
|
|
|
|
+ String[] arr = rolesStr.split(",");
|
|
|
|
|
+ for (String r : arr) {
|
|
|
|
|
+ if (!r.trim().isEmpty()) {
|
|
|
|
|
+ result.add(r.trim());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 将角色列表转换为字符串
|
|
|
|
|
+ */
|
|
|
|
|
+ private String joinRoles(List<String> roles) {
|
|
|
|
|
+ return String.join(",", roles);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 检查角色是否有效
|
|
|
|
|
+ */
|
|
|
|
|
+ private boolean isValidRole(String role) {
|
|
|
|
|
+ return "parent".equals(role) || "child".equals(role) || "teacher".equals(role);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 家长切换到指定孩子身份
|
|
* 家长切换到指定孩子身份
|
|
|
*/
|
|
*/
|
|
@@ -381,11 +655,73 @@ private VerificationCodeService verificationCodeService;
|
|
|
if (dto.getRealName() != null) {
|
|
if (dto.getRealName() != null) {
|
|
|
user.setRealName(dto.getRealName());
|
|
user.setRealName(dto.getRealName());
|
|
|
}
|
|
}
|
|
|
|
|
+ // 更新角色
|
|
|
|
|
+ if (dto.getRole() != null) {
|
|
|
|
|
+ user.setRole(dto.getRole());
|
|
|
|
|
+ }
|
|
|
|
|
+ // 更新性别
|
|
|
|
|
+ if (dto.getGender() != null) {
|
|
|
|
|
+ user.setGender(dto.getGender());
|
|
|
|
|
+ }
|
|
|
|
|
+ // 更新生日(将字符串转换为Date)
|
|
|
|
|
+ if (dto.getBirthday() != null && !dto.getBirthday().isEmpty()) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
|
|
|
|
|
+ user.setBirthday(sdf.parse(dto.getBirthday()));
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ // 忽略解析错误
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ // 更新身份证号
|
|
|
|
|
+ if (dto.getIdCard() != null && !dto.getIdCard().isEmpty()) {
|
|
|
|
|
+ user.setIdCard(dto.getIdCard());
|
|
|
|
|
+ // 如果没有手动设置生日,尝试从身份证号提取
|
|
|
|
|
+ if (user.getBirthday() == null) {
|
|
|
|
|
+ String birthdayFromIdCard = extractBirthdayFromIdCard(dto.getIdCard());
|
|
|
|
|
+ if (birthdayFromIdCard != null) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
|
|
|
|
|
+ user.setBirthday(sdf.parse(birthdayFromIdCard));
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ // 忽略解析错误
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
user.setUpdatedAt(new Date());
|
|
user.setUpdatedAt(new Date());
|
|
|
userMapper.updateById(user);
|
|
userMapper.updateById(user);
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 从身份证号提取生日
|
|
|
|
|
+ * 15位:1985年07月08日 -> 1985-07-08
|
|
|
|
|
+ * 18位:1985年07月08日 -> 1985-07-08
|
|
|
|
|
+ */
|
|
|
|
|
+ private String extractBirthdayFromIdCard(String idCard) {
|
|
|
|
|
+ if (idCard == null || idCard.isEmpty()) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (idCard.length() == 15) {
|
|
|
|
|
+ // 15位身份证:出生日期在第6-12位
|
|
|
|
|
+ String year = "19" + idCard.substring(6, 8);
|
|
|
|
|
+ String month = idCard.substring(8, 10);
|
|
|
|
|
+ String day = idCard.substring(10, 12);
|
|
|
|
|
+ return String.format("%s-%s-%s", year, month, day);
|
|
|
|
|
+ } else if (idCard.length() == 18) {
|
|
|
|
|
+ // 18位身份证:出生日期在第6-14位
|
|
|
|
|
+ String year = idCard.substring(6, 10);
|
|
|
|
|
+ String month = idCard.substring(10, 12);
|
|
|
|
|
+ String day = idCard.substring(12, 14);
|
|
|
|
|
+ return String.format("%s-%s-%s", year, month, day);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ // 忽略解析异常
|
|
|
|
|
+ }
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 通过邀请码加入家庭
|
|
* 通过邀请码加入家庭
|
|
|
*/
|
|
*/
|