package com.zxyj.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zxyj.config.JwtConfig; import com.zxyj.dto.*; import com.zxyj.dto.RegisterWithIdCardDTO; import com.zxyj.entity.Child; import com.zxyj.entity.Family; import com.zxyj.entity.User; import com.zxyj.mapper.ChildMapper; import com.zxyj.mapper.FamilyMapper; import com.zxyj.mapper.UserMapper; import com.zxyj.service.VerificationCodeService; import javax.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.util.DigestUtils; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.List; import java.util.UUID; @Service public class UserService { @Resource private UserMapper userMapper; @Resource private FamilyMapper familyMapper; @Resource private ChildMapper childMapper; @Resource private JwtConfig jwtConfig; @Resource private VerificationCodeService verificationCodeService; public LoginResultDTO wechatLogin(WechatLoginDTO dto) { // 模拟微信登录,实际需要调用微信API获取openid String openid = "mock_openid_" + dto.getCode(); // 查询用户是否存在 User user = userMapper.selectOne(new LambdaQueryWrapper() .eq(User::getOpenid, openid)); if (user == null) { // 新用户,创建家庭和用户 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(""); user.setFamilyId(family.getId()); user.setRole("parent"); user.setNickname(dto.getNickname()); user.setAvatar(dto.getAvatar()); 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 LoginResultDTO phoneLogin(PhoneLoginDTO dto) { // 使用手机号作为唯一标识 String phone = dto.getPhone(); // 查询用户是否存在 User user = userMapper.selectOne(new LambdaQueryWrapper() .eq(User::getOpenid, "phone:" + 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); } // 生成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; } public boolean setPassword(Long userId, String password) { User user = userMapper.selectById(userId); if (user == null) { return false; } user.setPassword(encryptPassword(password)); user.setUpdatedAt(new Date()); userMapper.updateById(user); return true; } public boolean verifyPassword(Long userId, String password) { User user = userMapper.selectById(userId); if (user == null || user.getPassword() == null) { return false; } return user.getPassword().equals(encryptPassword(password)); } public User getUserInfo(Long userId) { return userMapper.selectById(userId); } public String switchMode(Long userId, String mode) { User user = userMapper.selectById(userId); if (user == null) { return null; } user.setRole(mode); user.setUpdatedAt(new Date()); userMapper.updateById(user); 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() .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) { User user = userMapper.selectById(userId); if (user == null) { return null; } Child child = new Child(); child.setUserId(userId); child.setFamilyId(user.getFamilyId()); child.setNickname(dto.getNickname()); child.setAge(dto.getAge()); child.setBirthday(dto.getBirthday()); child.setGender(dto.getGender()); child.setDanLevel(dto.getDanLevel()); // 根据年龄设置扣分开关:6岁以下默认关闭,6岁及以上默认开启 child.setPenaltyEnabled(dto.getAge() >= 6 ? 1 : 0); child.setTheme("default"); child.setTotalPoints(0); child.setStreakDays(0); child.setFocusMaxDaily(3); child.setFocusRemaining(3); child.setFocusResetDate(new Date()); child.setCreatedAt(new Date()); child.setUpdatedAt(new Date()); childMapper.insert(child); return toChildInfoDTO(child); } public List getChildren(Long userId) { User user = userMapper.selectById(userId); if (user == null) { return null; } List children = childMapper.selectList(new LambdaQueryWrapper() .eq(Child::getFamilyId, user.getFamilyId())); return children.stream().map(this::toChildInfoDTO).collect(java.util.stream.Collectors.toList()); } public boolean updateChild(Long childId, UpdateChildDTO dto) { Child child = childMapper.selectById(childId); if (child == null) { return false; } if (dto.getNickname() != null) { child.setNickname(dto.getNickname()); } if (dto.getAge() != null) { child.setAge(dto.getAge()); } if (dto.getDanLevel() != null) { child.setDanLevel(dto.getDanLevel()); } if (dto.getPenaltyEnabled() != null) { child.setPenaltyEnabled(dto.getPenaltyEnabled()); } if (dto.getTheme() != null) { child.setTheme(dto.getTheme()); } child.setUpdatedAt(new Date()); childMapper.updateById(child); return true; } private String encryptPassword(String password) { return DigestUtils.md5DigestAsHex(("xzyj_salt_" + password).getBytes(StandardCharsets.UTF_8)); } private String generateInviteCode() { return UUID.randomUUID().toString().substring(0, 8).toUpperCase(); } private ChildInfoDTO toChildInfoDTO(Child child) { ChildInfoDTO dto = new ChildInfoDTO(); dto.setId(child.getId()); dto.setNickname(child.getNickname()); dto.setAge(child.getAge()); dto.setBirthday(child.getBirthday()); dto.setGender(child.getGender()); dto.setDanLevel(child.getDanLevel()); dto.setPenaltyEnabled(child.getPenaltyEnabled()); dto.setTheme(child.getTheme()); dto.setTotalPoints(child.getTotalPoints()); dto.setStreakDays(child.getStreakDays()); dto.setFocusRemaining(child.getFocusRemaining()); 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() .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(); } }