|
@@ -3,13 +3,15 @@ package com.zxyj.service;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.zxyj.config.JwtConfig;
|
|
import com.zxyj.config.JwtConfig;
|
|
|
import com.zxyj.dto.*;
|
|
import com.zxyj.dto.*;
|
|
|
|
|
+import com.zxyj.dto.RegisterWithIdCardDTO;
|
|
|
import com.zxyj.entity.Child;
|
|
import com.zxyj.entity.Child;
|
|
|
import com.zxyj.entity.Family;
|
|
import com.zxyj.entity.Family;
|
|
|
import com.zxyj.entity.User;
|
|
import com.zxyj.entity.User;
|
|
|
import com.zxyj.mapper.ChildMapper;
|
|
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 org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
|
|
+import com.zxyj.service.VerificationCodeService;
|
|
|
|
|
+import javax.annotation.Resource;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.util.DigestUtils;
|
|
import org.springframework.util.DigestUtils;
|
|
|
|
|
|
|
@@ -21,17 +23,20 @@ import java.util.UUID;
|
|
|
@Service
|
|
@Service
|
|
|
public class UserService {
|
|
public class UserService {
|
|
|
|
|
|
|
|
- @Autowired
|
|
|
|
|
- private UserMapper userMapper;
|
|
|
|
|
|
|
+@Resource
|
|
|
|
|
+private UserMapper userMapper;
|
|
|
|
|
|
|
|
- @Autowired
|
|
|
|
|
- private FamilyMapper familyMapper;
|
|
|
|
|
|
|
+@Resource
|
|
|
|
|
+private FamilyMapper familyMapper;
|
|
|
|
|
|
|
|
- @Autowired
|
|
|
|
|
- private ChildMapper childMapper;
|
|
|
|
|
|
|
+@Resource
|
|
|
|
|
+private ChildMapper childMapper;
|
|
|
|
|
|
|
|
- @Autowired
|
|
|
|
|
- private JwtConfig jwtConfig;
|
|
|
|
|
|
|
+@Resource
|
|
|
|
|
+private JwtConfig jwtConfig;
|
|
|
|
|
+
|
|
|
|
|
+@Resource
|
|
|
|
|
+private VerificationCodeService verificationCodeService;
|
|
|
|
|
|
|
|
public LoginResultDTO wechatLogin(WechatLoginDTO dto) {
|
|
public LoginResultDTO wechatLogin(WechatLoginDTO dto) {
|
|
|
// 模拟微信登录,实际需要调用微信API获取openid
|
|
// 模拟微信登录,实际需要调用微信API获取openid
|
|
@@ -82,13 +87,17 @@ public class UserService {
|
|
|
public LoginResultDTO phoneLogin(PhoneLoginDTO dto) {
|
|
public LoginResultDTO phoneLogin(PhoneLoginDTO dto) {
|
|
|
// 使用手机号作为唯一标识
|
|
// 使用手机号作为唯一标识
|
|
|
String phone = dto.getPhone();
|
|
String phone = dto.getPhone();
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 查询用户是否存在
|
|
// 查询用户是否存在
|
|
|
User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
|
|
User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
|
|
|
.eq(User::getOpenid, "phone:" + phone));
|
|
.eq(User::getOpenid, "phone:" + phone));
|
|
|
|
|
|
|
|
|
|
+ boolean isNewUser = false;
|
|
|
|
|
+
|
|
|
if (user == null) {
|
|
if (user == null) {
|
|
|
- // 新用户,创建家庭和用户
|
|
|
|
|
|
|
+ // 新用户,创建新家庭和用户
|
|
|
|
|
+ isNewUser = true;
|
|
|
|
|
+
|
|
|
Family family = new Family();
|
|
Family family = new Family();
|
|
|
family.setName("我的家庭");
|
|
family.setName("我的家庭");
|
|
|
family.setInviteCode(generateInviteCode());
|
|
family.setInviteCode(generateInviteCode());
|
|
@@ -100,9 +109,13 @@ public class UserService {
|
|
|
user.setOpenid("phone:" + phone);
|
|
user.setOpenid("phone:" + phone);
|
|
|
user.setUnionid("");
|
|
user.setUnionid("");
|
|
|
user.setFamilyId(family.getId());
|
|
user.setFamilyId(family.getId());
|
|
|
- user.setRole("parent");
|
|
|
|
|
|
|
+ // 默认角色为家长,可以被覆盖
|
|
|
|
|
+ user.setRole(dto.getRole() != null ? dto.getRole() : "parent");
|
|
|
user.setNickname(dto.getNickname() != null ? dto.getNickname() : "用户" + phone.substring(7));
|
|
user.setNickname(dto.getNickname() != null ? dto.getNickname() : "用户" + phone.substring(7));
|
|
|
user.setAvatar(dto.getAvatar());
|
|
user.setAvatar(dto.getAvatar());
|
|
|
|
|
+ user.setPhone(phone);
|
|
|
|
|
+ user.setBirthday(dto.getBirthday());
|
|
|
|
|
+ user.setGender(dto.getGender());
|
|
|
user.setPassword("");
|
|
user.setPassword("");
|
|
|
user.setCreatedAt(new Date());
|
|
user.setCreatedAt(new Date());
|
|
|
user.setUpdatedAt(new Date());
|
|
user.setUpdatedAt(new Date());
|
|
@@ -118,6 +131,7 @@ public class UserService {
|
|
|
result.setRole(user.getRole());
|
|
result.setRole(user.getRole());
|
|
|
result.setFamilyId(user.getFamilyId());
|
|
result.setFamilyId(user.getFamilyId());
|
|
|
result.setNickname(user.getNickname());
|
|
result.setNickname(user.getNickname());
|
|
|
|
|
+ result.setIsNewUser(isNewUser);
|
|
|
|
|
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
@@ -156,6 +170,109 @@ public class UserService {
|
|
|
return mode;
|
|
return mode;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 家长切换到指定孩子身份
|
|
|
|
|
+ */
|
|
|
|
|
+ public Long switchToChild(Long userId, Long childId) {
|
|
|
|
|
+ User user = userMapper.selectById(userId);
|
|
|
|
|
+ if (user == null || !"parent".equals(user.getRole())) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Child child = childMapper.selectById(childId);
|
|
|
|
|
+ if (child == null || !child.getFamilyId().equals(user.getFamilyId())) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 保存原用户ID到会话中,后续可以切回
|
|
|
|
|
+ // 这里用简单的机制:存储到用户的 extended 字段或者新表
|
|
|
|
|
+ // 为简化,先返回 childId,实际切换通过 setRole 实现
|
|
|
|
|
+
|
|
|
|
|
+ // 实际切换角色为 child
|
|
|
|
|
+ user.setRole("child");
|
|
|
|
|
+ user.setUpdatedAt(new Date());
|
|
|
|
|
+ userMapper.updateById(user);
|
|
|
|
|
+
|
|
|
|
|
+ return childId;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 孩子切换回家长身份
|
|
|
|
|
+ */
|
|
|
|
|
+ public boolean switchBackToParent(Long userId) {
|
|
|
|
|
+ User user = userMapper.selectById(userId);
|
|
|
|
|
+ if (user == null || !"child".equals(user.getRole())) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ user.setRole("parent");
|
|
|
|
|
+ user.setUpdatedAt(new Date());
|
|
|
|
|
+ userMapper.updateById(user);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public LoginResultDTO registerWithIdCard(RegisterWithIdCardDTO dto) {
|
|
|
|
|
+ // 验证验证码
|
|
|
|
|
+ boolean valid = verificationCodeService.verifyCode(dto.getPhone(), dto.getCode(), "login");
|
|
|
|
|
+ if (!valid) {
|
|
|
|
|
+ throw new RuntimeException("验证码错误或已过期");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 通过身份证查找是否已有注册的用户
|
|
|
|
|
+ User existingUser = userMapper.selectOne(new LambdaQueryWrapper<User>()
|
|
|
|
|
+ .eq(User::getIdCard, dto.getIdCard()));
|
|
|
|
|
+
|
|
|
|
|
+ Family family;
|
|
|
|
|
+ User user;
|
|
|
|
|
+
|
|
|
|
|
+ if (existingUser != null) {
|
|
|
|
|
+ // 如果存在相同身份证的用户,加入其家庭
|
|
|
|
|
+ user = existingUser;
|
|
|
|
|
+ family = familyMapper.selectById(user.getFamilyId());
|
|
|
|
|
+
|
|
|
|
|
+ // 更新用户信息(昵称和头像可以更新)
|
|
|
|
|
+ user.setNickname(dto.getNickname());
|
|
|
|
|
+ user.setAvatar(dto.getAvatar());
|
|
|
|
|
+ // 手机号也可以更新(如果需要)
|
|
|
|
|
+ user.setOpenid("phone:" + dto.getPhone());
|
|
|
|
|
+ user.setUpdatedAt(new Date());
|
|
|
|
|
+ userMapper.updateById(user);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 创建新家庭和用户
|
|
|
|
|
+ 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:" + dto.getPhone());
|
|
|
|
|
+ user.setUnionid("");
|
|
|
|
|
+ user.setFamilyId(family.getId());
|
|
|
|
|
+ user.setRole("parent");
|
|
|
|
|
+ user.setNickname(dto.getNickname());
|
|
|
|
|
+ user.setAvatar(dto.getAvatar());
|
|
|
|
|
+ user.setIdCard(dto.getIdCard());
|
|
|
|
|
+ user.setRealName(dto.getRealName());
|
|
|
|
|
+ user.setPassword(""); // 初始密码为空,需要后续设置
|
|
|
|
|
+ user.setCreatedAt(new Date());
|
|
|
|
|
+ user.setUpdatedAt(new Date());
|
|
|
|
|
+ userMapper.insert(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());
|
|
|
|
|
+
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
public ChildInfoDTO createChild(Long userId, CreateChildDTO dto) {
|
|
public ChildInfoDTO createChild(Long userId, CreateChildDTO dto) {
|
|
|
User user = userMapper.selectById(userId);
|
|
User user = userMapper.selectById(userId);
|
|
|
if (user == null) {
|
|
if (user == null) {
|
|
@@ -167,6 +284,8 @@ public class UserService {
|
|
|
child.setFamilyId(user.getFamilyId());
|
|
child.setFamilyId(user.getFamilyId());
|
|
|
child.setNickname(dto.getNickname());
|
|
child.setNickname(dto.getNickname());
|
|
|
child.setAge(dto.getAge());
|
|
child.setAge(dto.getAge());
|
|
|
|
|
+ child.setBirthday(dto.getBirthday());
|
|
|
|
|
+ child.setGender(dto.getGender());
|
|
|
child.setDanLevel(dto.getDanLevel());
|
|
child.setDanLevel(dto.getDanLevel());
|
|
|
// 根据年龄设置扣分开关:6岁以下默认关闭,6岁及以上默认开启
|
|
// 根据年龄设置扣分开关:6岁以下默认关闭,6岁及以上默认开启
|
|
|
child.setPenaltyEnabled(dto.getAge() >= 6 ? 1 : 0);
|
|
child.setPenaltyEnabled(dto.getAge() >= 6 ? 1 : 0);
|
|
@@ -234,6 +353,8 @@ public class UserService {
|
|
|
dto.setId(child.getId());
|
|
dto.setId(child.getId());
|
|
|
dto.setNickname(child.getNickname());
|
|
dto.setNickname(child.getNickname());
|
|
|
dto.setAge(child.getAge());
|
|
dto.setAge(child.getAge());
|
|
|
|
|
+ dto.setBirthday(child.getBirthday());
|
|
|
|
|
+ dto.setGender(child.getGender());
|
|
|
dto.setDanLevel(child.getDanLevel());
|
|
dto.setDanLevel(child.getDanLevel());
|
|
|
dto.setPenaltyEnabled(child.getPenaltyEnabled());
|
|
dto.setPenaltyEnabled(child.getPenaltyEnabled());
|
|
|
dto.setTheme(child.getTheme());
|
|
dto.setTheme(child.getTheme());
|
|
@@ -242,4 +363,72 @@ public class UserService {
|
|
|
dto.setFocusRemaining(child.getFocusRemaining());
|
|
dto.setFocusRemaining(child.getFocusRemaining());
|
|
|
return dto;
|
|
return dto;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 更新用户信息
|
|
|
|
|
+ */
|
|
|
|
|
+ public boolean updateUserInfo(Long userId, UpdateUserDTO dto) {
|
|
|
|
|
+ User user = userMapper.selectById(userId);
|
|
|
|
|
+ if (user == null) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (dto.getNickname() != null) {
|
|
|
|
|
+ user.setNickname(dto.getNickname());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (dto.getAvatar() != null) {
|
|
|
|
|
+ user.setAvatar(dto.getAvatar());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (dto.getRealName() != null) {
|
|
|
|
|
+ user.setRealName(dto.getRealName());
|
|
|
|
|
+ }
|
|
|
|
|
+ user.setUpdatedAt(new Date());
|
|
|
|
|
+ userMapper.updateById(user);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 通过邀请码加入家庭
|
|
|
|
|
+ */
|
|
|
|
|
+ public boolean joinFamily(Long userId, String inviteCode) {
|
|
|
|
|
+ if (inviteCode == null || inviteCode.isEmpty()) {
|
|
|
|
|
+ throw new RuntimeException("邀请码不能为空");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 查找家庭
|
|
|
|
|
+ Family family = familyMapper.selectOne(new LambdaQueryWrapper<Family>()
|
|
|
|
|
+ .eq(Family::getInviteCode, inviteCode));
|
|
|
|
|
+ if (family == null) {
|
|
|
|
|
+ throw new RuntimeException("邀请码无效");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 更新用户的家庭ID
|
|
|
|
|
+ User user = userMapper.selectById(userId);
|
|
|
|
|
+ if (user == null) {
|
|
|
|
|
+ throw new RuntimeException("用户不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+ user.setFamilyId(family.getId());
|
|
|
|
|
+ user.setUpdatedAt(new Date());
|
|
|
|
|
+ userMapper.updateById(user);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 为用户创建新家庭
|
|
|
|
|
+ */
|
|
|
|
|
+ public Long createFamilyForUser(Long userId, String familyName) {
|
|
|
|
|
+ User user = userMapper.selectById(userId);
|
|
|
|
|
+ if (user == null) {
|
|
|
|
|
+ throw new RuntimeException("用户不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 创建新家庭
|
|
|
|
|
+ Family family = new Family();
|
|
|
|
|
+ family.setName(familyName);
|
|
|
|
|
+ family.setInviteCode(generateInviteCode());
|
|
|
|
|
+ family.setCreatedAt(new Date());
|
|
|
|
|
+ family.setUpdatedAt(new Date());
|
|
|
|
|
+ familyMapper.insert(family);
|
|
|
|
|
+ // 更新用户的家庭ID
|
|
|
|
|
+ user.setFamilyId(family.getId());
|
|
|
|
|
+ user.setUpdatedAt(new Date());
|
|
|
|
|
+ userMapper.updateById(user);
|
|
|
|
|
+ return family.getId();
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|