package com.zsElectric.boot.business.service.impl; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.zsElectric.boot.business.mapper.FirmInfoMapper; import com.zsElectric.boot.business.mapper.UserAccountMapper; import com.zsElectric.boot.business.mapper.UserFirmMapper; import com.zsElectric.boot.business.model.entity.FirmInfo; import com.zsElectric.boot.business.model.entity.UserAccount; import com.zsElectric.boot.business.model.entity.UserFirm; import com.zsElectric.boot.business.model.vo.applet.AppUserInfoVO; import com.zsElectric.boot.security.util.SecurityUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.zsElectric.boot.business.mapper.UserInfoMapper; import com.zsElectric.boot.business.service.UserInfoService; import com.zsElectric.boot.business.model.entity.UserInfo; import com.zsElectric.boot.business.model.form.UserInfoForm; import com.zsElectric.boot.business.model.query.UserInfoQuery; import com.zsElectric.boot.business.model.vo.UserInfoVO; import com.zsElectric.boot.business.converter.UserInfoConverter; import java.math.BigDecimal; import java.util.Arrays; import java.util.List; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; /** * 个人用户信息服务实现类 * * @author zsElectric * @since 2025-12-12 10:27 */ @Service @RequiredArgsConstructor @Slf4j public class UserInfoServiceImpl extends ServiceImpl implements UserInfoService { private final UserInfoConverter userInfoConverter; private final UserAccountMapper userAccountMapper; private final FirmInfoMapper firmInfoMapper; private final UserFirmMapper userFirmMapper; /** * 获取个人用户信息分页列表 * * @param queryParams 查询参数 * @return {@link IPage} 个人用户信息分页列表 */ @Override public IPage getUserInfoPage(UserInfoQuery queryParams) { Page pageVO = this.baseMapper.getUserInfoPage( new Page<>(queryParams.getPageNum(), queryParams.getPageSize()), queryParams ); return pageVO; } /** * 获取个人用户信息表单数据 * * @param id 个人用户信息ID * @return 个人用户信息表单数据 */ @Override public UserInfoForm getUserInfoFormData(Long id) { UserInfo entity = this.getById(id); return userInfoConverter.toForm(entity); } /** * 新增个人用户信息 * * @param formData 个人用户信息表单对象 * @return 是否新增成功 */ @Override public boolean saveUserInfo(UserInfoForm formData) { UserInfo entity = userInfoConverter.toEntity(formData); return this.save(entity); } /** * 更新个人用户信息 * * @param id 个人用户信息ID * @param formData 个人用户信息表单对象 * @return 是否修改成功 */ @Override public boolean updateUserInfo(Long id,UserInfoForm formData) { UserInfo entity = userInfoConverter.toEntity(formData); return this.updateById(entity); } /** * 删除个人用户信息 * * @param ids 个人用户信息ID,多个以英文逗号(,)分割 * @return 是否删除成功 */ @Override public boolean deleteUserInfos(String ids) { Assert.isTrue(StrUtil.isNotBlank(ids), "删除的个人用户信息数据为空"); // 逻辑删除 List idList = Arrays.stream(ids.split(",")) .map(Long::parseLong) .toList(); return this.removeByIds(idList); } /** * 获取当前登录用户信息(小程序用) *

* 根据当前登录用户的userId获取用户信息 * 注意:小程序登录后,token中的userId就是c_user_info表的ID * * @return 当前用户信息 */ @Override public AppUserInfoVO getAppletUserInfo() { // 从 Spring Security 上下文获取当前登录用户的ID 注意:小程序用户token中的userId就是c_user_info表的ID Long userId = SecurityUtils.getUserId(); if(ObjectUtil.isNotNull(userId)) { return this.baseMapper.getAppletUserInfo(userId); } return null; } @Override public Boolean userBinding(Long userId, Long firmId) { UserInfo userInfo = this.getById(userId); FirmInfo firmInfo = firmInfoMapper.selectById(firmId); if (ObjectUtil.isNotNull(userInfo) && ObjectUtil.isNotNull(firmInfo)) { //删除用户旧绑定信息 userFirmMapper.delete(Wrappers.lambdaQuery(UserFirm.class).eq(UserFirm::getUserId, userId)); UserFirm userFirm = new UserFirm(); userFirm.setUserId(userId); userFirm.setPhone(userInfo.getPhone()); userFirm.setFirmId(firmId); userFirm.setType(1); int insert = userFirmMapper.insert(userFirm); if(insert > 0) { return Boolean.TRUE; } return Boolean.FALSE; } log.info("用户不存在或企业不存在"); return Boolean.FALSE; } /** * 根据openid获取用户信息 * * @param openid 手机号 * @return 用户信息,不存在返回null */ @Override public UserInfo getUserInfoByOpenid(String openid) { if (StrUtil.isBlank(openid)) { return null; } return this.getOne( new LambdaQueryWrapper() .eq(UserInfo::getOpenid, openid) ); } /** * 根据openid获取用户信息 * * @param phone 手机号 * @return 用户信息,不存在返回null */ @Override public UserInfo getUserInfoByPhone(String phone) { if (StrUtil.isBlank(phone)) { return null; } return this.getOne( new LambdaQueryWrapper() .eq(UserInfo::getPhone, phone) ); } /** * 根据手机号注册或更新用户(小程序用) *

* 如果用户不存在则创建,存在则更新openid * * @param phone 手机号 * @param openId 微信openid(可为null) * @return 用户信息 */ @Override public UserInfo registerOrUpdateUserByPhone(String phone, String openId) { if (StrUtil.isBlank(phone)) { log.warn("注册用户失败:手机号为空"); return null; } // 查询用户是否已存在 UserInfo existingUser = getUserInfoByOpenid(openId); if (existingUser != null) { log.info("用户已存在,ID: {}, 手机号: {},openid: {}", existingUser.getId(), phone,openId); // 如果提供了phone且与现有phone不同,则更新 if (StrUtil.isNotBlank(phone) && !phone.equals(existingUser.getPhone())) { log.info("更新用户phone,ID: {}", existingUser.getId()); existingUser.setPhone(phone); this.updateById(existingUser); } return existingUser; } UserInfo existingUser2 = getUserInfoByPhone(phone); if (existingUser2 != null) { log.info("用户已存在,ID: {}, 手机号: {},openid: {}", existingUser2.getId(), phone,openId); // 如果提供了phone且与现有phone不同,则更新 if (StrUtil.isNotBlank(openId) && !openId.equals(existingUser2.getOpenid())) { log.info("更新用户phone,ID: {}", existingUser2.getId()); existingUser2.setOpenid(openId); this.updateById(existingUser2); } return existingUser2; } // 用户不存在,创建新用户 log.info("创建新用户,手机号: {}, openId: {}", phone, openId); UserInfo newUser = new UserInfo(); newUser.setPhone(phone); newUser.setOpenid(openId); newUser.setNickName("微信用户_" + phone.substring(phone.length() - 4)); boolean saved = this.save(newUser); if (!saved) { log.error("保存用户失败,手机号: {}", phone); return null; } log.info("用户创建成功,ID: {}, 手机号: {}", newUser.getId(), phone); //创建用户账户 UserAccount userAccount = new UserAccount(); userAccount.setUserId(newUser.getId()); userAccount.setBalance(BigDecimal.ZERO); userAccountMapper.insert(userAccount); return newUser; } /** * 根据订单和账户数据恢复被物理删除的用户信息 *

* 查找在 UserOrderInfo 或 UserAccount 中存在但在 UserInfo 中不存在的用户,并重新创建其数据 * * @return 恢复的用户数量 */ @Override public int restoreDeletedUsersByOrderAndAccount() { // 查询在订单或账户中存在但UserInfo表中不存在的用户信息 List missingUsers = this.baseMapper.selectMissingUserInfoFromOrderAndAccount(); if (missingUsers == null || missingUsers.isEmpty()) { log.info("没有需要恢复的用户数据"); return 0; } log.info("找到 {} 个需要恢复的用户", missingUsers.size()); int restoredCount = 0; for (UserInfo userInfo : missingUsers) { try { // 插入恢复的用户信息 int inserted = this.baseMapper.insertUserInfoWithId(userInfo); if (inserted > 0) { restoredCount++; log.info("成功恢复用户,ID: {}, openid: {}", userInfo.getId(), userInfo.getOpenid()); } } catch (Exception e) { log.error("恢复用户失败,ID: {}, 错误: {}", userInfo.getId(), e.getMessage()); } } log.info("成功恢复 {} 个用户数据", restoredCount); return restoredCount; } }