|
@@ -0,0 +1,400 @@
|
|
|
+package edu.travel.service.impl;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import edu.travel.dto.BabyInfoDTO;
|
|
|
+import edu.travel.dto.BabyQueryDTO;
|
|
|
+import edu.travel.entity.BtBabyInfo;
|
|
|
+import edu.travel.entity.BtBabyUserRelation;
|
|
|
+import edu.travel.entity.MtRelativeRole;
|
|
|
+import edu.travel.enumm.BloodType;
|
|
|
+import edu.travel.exception.BaseException;
|
|
|
+import edu.travel.mapper.BtBabyInfoMapper;
|
|
|
+import edu.travel.mapper.BtBabyUserRelationMapper;
|
|
|
+import edu.travel.mapper.MtRelativeRoleMapper;
|
|
|
+import edu.travel.service.BtBabyInfoService;
|
|
|
+import edu.travel.util.ConstellationUtil;
|
|
|
+import edu.travel.vo.BabyDetailVO;
|
|
|
+import edu.travel.vo.BabyInfoVO;
|
|
|
+import edu.travel.vo.BabyListItemVO;
|
|
|
+import edu.travel.vo.PageResult;
|
|
|
+import lombok.AllArgsConstructor;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.Period;
|
|
|
+import java.time.ZoneId;
|
|
|
+import java.time.temporal.ChronoUnit;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author Survive
|
|
|
+ * @date 2025/3/13
|
|
|
+ * @description TODO
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class BtBabyInfoServiceImpl extends ServiceImpl<BtBabyInfoMapper, BtBabyInfo> implements BtBabyInfoService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private BtBabyUserRelationMapper relationMapper;
|
|
|
+ @Autowired
|
|
|
+ private BtBabyInfoMapper babyInfoMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private MtRelativeRoleMapper relativeRoleMapper;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询所有宝宝信息
|
|
|
+ * @param dto
|
|
|
+ * @param currentUserId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public PageResult<BabyListItemVO> listBabiesByPage(BabyQueryDTO dto, Long currentUserId) {
|
|
|
+ // 1. 构建分页参数
|
|
|
+ int pageNum = dto.getPageNum() != null ? dto.getPageNum() : 1;
|
|
|
+ int pageSize = dto.getPageSize() != null ? dto.getPageSize() : 10;
|
|
|
+ Page<BtBabyInfo> page = new Page<>(pageNum, pageSize);
|
|
|
+
|
|
|
+ // 2. 构建查询条件
|
|
|
+ QueryWrapper<BtBabyInfo> wrapper = new QueryWrapper<>();
|
|
|
+ buildQueryConditions(wrapper, dto, currentUserId);
|
|
|
+ handleSorting(wrapper, dto);
|
|
|
+
|
|
|
+ // 3. 执行分页查询
|
|
|
+ Page<BtBabyInfo> resultPage = babyInfoMapper.selectPage(page, wrapper);
|
|
|
+
|
|
|
+ // 4. 转换为VO
|
|
|
+ List<BabyListItemVO> voList = convertToVOList(resultPage.getRecords());
|
|
|
+
|
|
|
+ return new PageResult<>(
|
|
|
+ voList,
|
|
|
+ resultPage.getTotal(),
|
|
|
+ resultPage.getCurrent(),
|
|
|
+ resultPage.getSize()
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ private void buildQueryConditions(QueryWrapper<BtBabyInfo> wrapper, BabyQueryDTO dto, Long userId) {
|
|
|
+ // 基础条件
|
|
|
+ wrapper.eq("delete_flag", 0);
|
|
|
+
|
|
|
+ // 权限过滤
|
|
|
+ wrapper.inSql("id",
|
|
|
+ "SELECT baby_id FROM bt_baby_user_relation " +
|
|
|
+ "WHERE user_id = " + userId + " AND delete_flag = 0");
|
|
|
+
|
|
|
+ // 筛选条件
|
|
|
+ if (StringUtils.isNotBlank(dto.getName())) {
|
|
|
+ wrapper.like("name", dto.getName().trim());
|
|
|
+ }
|
|
|
+ if (dto.getGender() != null) {
|
|
|
+ wrapper.eq("gender", dto.getGender());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void handleSorting(QueryWrapper<BtBabyInfo> wrapper, BabyQueryDTO dto) {
|
|
|
+ String safeSortField = Arrays.asList("create_time", "birthday_new")
|
|
|
+ .contains(dto.getSortField()) ? dto.getSortField() : "create_time";
|
|
|
+
|
|
|
+ wrapper.orderBy(true, "asc".equalsIgnoreCase(dto.getSortOrder()),
|
|
|
+ safeSortField + (dto.getSortField().equals("birthday_new") ? " DESC" : ""));
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<BabyListItemVO> convertToVOList(List<BtBabyInfo> records) {
|
|
|
+ return records.stream().map(baby -> {
|
|
|
+ BabyListItemVO vo = new BabyListItemVO();
|
|
|
+ BeanUtils.copyProperties(baby, vo);
|
|
|
+ vo.setBirth(baby.getBirthdayNew());
|
|
|
+ vo.setAge(calculateAge(baby.getBirthdayNew()));
|
|
|
+ vo.setGender(baby.getGender() == 1 ? "男" : "女");
|
|
|
+ vo.setBloodType(BloodType.getDescriptionByCode(baby.getBloodType()));
|
|
|
+ return vo;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private String calculateAge(Date birthday) {
|
|
|
+ LocalDate birthDate = birthday.toInstant()
|
|
|
+ .atZone(ZoneId.systemDefault())
|
|
|
+ .toLocalDate();
|
|
|
+ LocalDate now = LocalDate.now();
|
|
|
+
|
|
|
+ // 处理未来日期
|
|
|
+ if (birthDate.isAfter(now)) {
|
|
|
+ return "未出生";
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算年月
|
|
|
+ Period period = Period.between(birthDate, now);
|
|
|
+
|
|
|
+ // 计算剩余天数
|
|
|
+ LocalDate tempDate = birthDate.plusYears(period.getYears())
|
|
|
+ .plusMonths(period.getMonths());
|
|
|
+ long days = ChronoUnit.DAYS.between(tempDate, now);
|
|
|
+
|
|
|
+ return formatAge(birthDate,now,period.getYears(), period.getMonths(), days);
|
|
|
+ }
|
|
|
+
|
|
|
+ private String formatAge(LocalDate birthDate, LocalDate now, int years, int months, long days) {
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ if (years > 0) sb.append(years).append("岁");
|
|
|
+ if (months > 0) sb.append(months).append("个月");
|
|
|
+ if (days > 0) sb.append(days).append("天");
|
|
|
+
|
|
|
+ // 处理全零情况
|
|
|
+ if (sb.length() == 0) {
|
|
|
+ long totalDays = ChronoUnit.DAYS.between(birthDate, now);
|
|
|
+ return totalDays + "天";
|
|
|
+ }
|
|
|
+
|
|
|
+ return sb.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 新增宝宝信息
|
|
|
+ * @param dto
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public BabyInfoVO addBaby(BabyInfoDTO dto, Long currentUserId) {
|
|
|
+ // 根据角色名称查询角色ID
|
|
|
+ String name = dto.getRoleName();
|
|
|
+ if (StringUtils.isBlank(name) && name.equals("")) {
|
|
|
+ throw new BaseException(400, "角色类型不能为空");
|
|
|
+ }
|
|
|
+ QueryWrapper<MtRelativeRole> queryWrapper = new QueryWrapper<>();
|
|
|
+ queryWrapper.eq(StringUtils.checkValNotNull(name), "role_name", name);
|
|
|
+ MtRelativeRole role = relativeRoleMapper.selectOne(queryWrapper);
|
|
|
+
|
|
|
+ if (role == null && role.getId() == null) {
|
|
|
+ throw new BaseException(400, "角色类型不存在");
|
|
|
+ }
|
|
|
+ Long relativeRoleId = role.getId();
|
|
|
+
|
|
|
+
|
|
|
+ // 校验亲属角色
|
|
|
+ MtRelativeRole role1 = relativeRoleMapper.selectById(relativeRoleId);
|
|
|
+ if (role1 == null || role1.getDeleteFlag() != 0) {
|
|
|
+ throw new BaseException("亲属角色不存在或已删除");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 保存宝宝信息
|
|
|
+ BtBabyInfo baby = new BtBabyInfo();
|
|
|
+ BeanUtils.copyProperties(dto, baby);
|
|
|
+ //星座计算
|
|
|
+ baby.setConstellation(ConstellationUtil.getConstellation(dto.getBirthdayNew()));
|
|
|
+ baby.setCreateTime(new Date());
|
|
|
+// 登录传来的userId
|
|
|
+ baby.setCreateUserId(String.valueOf(currentUserId));
|
|
|
+ baby.setUpdateTime(new Date());
|
|
|
+ baby.setUpdateUserId(String.valueOf(currentUserId));
|
|
|
+ baby.setDeleteFlag(0);
|
|
|
+ babyInfoMapper.insert(baby);
|
|
|
+
|
|
|
+ // 保存关联关系
|
|
|
+ BtBabyUserRelation relation = new BtBabyUserRelation();
|
|
|
+ relation.setUserId(currentUserId);
|
|
|
+ relation.setBabyId(baby.getId());
|
|
|
+// relation.setRelativeRoleId(dto.getRelativeRoleId());
|
|
|
+ relation.setRelativeRoleId(relativeRoleId);
|
|
|
+ relation.setIsFounder(1);
|
|
|
+ relation.setProject(dto.getProject());
|
|
|
+ relation.setCreateTime(new Date());
|
|
|
+ relation.setCreateUserId(currentUserId);
|
|
|
+ relation.setCreateUserId(currentUserId);
|
|
|
+ relation.setUpdateTime(new Date());
|
|
|
+ relation.setUpdateUserId(currentUserId);
|
|
|
+ relation.setDeleteFlag(0);
|
|
|
+ relationMapper.insert(relation);
|
|
|
+
|
|
|
+ return convertToVO(baby);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询宝宝信息
|
|
|
+ * @param babyId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public BabyDetailVO getBabyInfoDetail(Long babyId) {
|
|
|
+ // 获取基础信息
|
|
|
+ BtBabyInfo babyInfo = getValidBabyInfo(babyId);
|
|
|
+
|
|
|
+ // 权限校验
|
|
|
+ verifyAccessPermission(babyId);
|
|
|
+
|
|
|
+ // 组装详细信息
|
|
|
+ return assembleDetailVO(babyInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String deleteBabyWithValidation(Long babyId, Long l) {
|
|
|
+ //权限校验 只有创建人有权限删除 删除时需要校验是否为 is_founder == 1?
|
|
|
+
|
|
|
+ BtBabyUserRelation btBabyUserRelation = relativeRoleMapper.selectByBabyIdAndDeleteFlag(babyId);
|
|
|
+ if (btBabyUserRelation.getIsFounder() == 0) {
|
|
|
+ throw new BaseException("无删除权限");
|
|
|
+ }
|
|
|
+
|
|
|
+ //执行逻辑删除逻辑
|
|
|
+ BtBabyInfo entity = new BtBabyInfo();
|
|
|
+ entity.setDeleteFlag(1);
|
|
|
+ entity.setUpdateTime(new Date());
|
|
|
+ entity.setUpdateUserId(String.valueOf(l));
|
|
|
+ UpdateWrapper<BtBabyInfo> updateBabyWrapper = new UpdateWrapper<>();
|
|
|
+ updateBabyWrapper.eq("id", babyId)
|
|
|
+ .set("delete_flag", 1);
|
|
|
+ int rows = babyInfoMapper.update(entity, updateBabyWrapper);
|
|
|
+ if (rows != 1) {
|
|
|
+ throw new BaseException("宝宝信息删除失败");
|
|
|
+ }
|
|
|
+ //逻辑删除关联关系
|
|
|
+ LambdaUpdateWrapper<BtBabyUserRelation> updateWrapper = new LambdaUpdateWrapper<>();
|
|
|
+ updateWrapper.set(BtBabyUserRelation::getDeleteFlag, 1)
|
|
|
+ .set(BtBabyUserRelation::getUpdateTime, new Date())
|
|
|
+// .set(BtBabyUserRelation::getUpdateUserId, SecurityUtils.getCurrentUserId())
|
|
|
+ .set(BtBabyUserRelation::getUpdateUserId,l)
|
|
|
+ .eq(BtBabyUserRelation::getBabyId, babyId);
|
|
|
+
|
|
|
+ int affectRows = relationMapper.update(null, updateWrapper);
|
|
|
+
|
|
|
+ return "删除成功";
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private BtBabyInfo getValidBabyInfo(Long babyId) {
|
|
|
+ BtBabyInfo baby = babyInfoMapper.selectById(babyId);
|
|
|
+ if (baby == null || baby.getDeleteFlag() == 1) {
|
|
|
+ throw new BaseException("宝宝信息不存在");
|
|
|
+ }
|
|
|
+ return baby;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void verifyAccessPermission(Long babyId) {
|
|
|
+ LambdaQueryWrapper<BtBabyUserRelation> query = new LambdaQueryWrapper<>();
|
|
|
+ query.eq(BtBabyUserRelation::getBabyId, babyId.toString())
|
|
|
+ .eq(BtBabyUserRelation::getDeleteFlag, 0);
|
|
|
+ if (relationMapper.selectCount(query) == 0) {
|
|
|
+ throw new BaseException("无访问权限");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private BabyDetailVO assembleDetailVO(BtBabyInfo baby) {
|
|
|
+ BabyDetailVO vo = new BabyDetailVO();
|
|
|
+ BeanUtils.copyProperties(baby, vo);
|
|
|
+ // 转换基础字段
|
|
|
+ vo.setGender(baby.getGender() == 0 ? "男" : "女");
|
|
|
+ vo.setBirthdayNew(new SimpleDateFormat("yyyy-MM-dd").format(baby.getBirthdayNew()));
|
|
|
+ vo.setBloodType(BloodType.getDescriptionByCode(baby.getBloodType()));
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 修改宝宝信息
|
|
|
+ * @param dto
|
|
|
+ * @param currentUserId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public BabyInfoVO updateBabyInfo(BabyInfoDTO dto, Long currentUserId) {
|
|
|
+ // 1. 校验宝宝是否存在
|
|
|
+ BtBabyInfo existBaby = babyInfoMapper.selectById(dto.getId());
|
|
|
+ if (existBaby == null || existBaby.getDeleteFlag() == 1) {
|
|
|
+ throw new BaseException("宝宝信息不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 校验修改权限
|
|
|
+ checkUpdatePermission(existBaby.getId(), currentUserId);
|
|
|
+
|
|
|
+ // 3. 构建更新实体
|
|
|
+ BtBabyInfo updateBaby = new BtBabyInfo();
|
|
|
+ BeanUtils.copyProperties(dto, updateBaby);
|
|
|
+ updateBaby.setUpdateTime(new Date());
|
|
|
+ updateBaby.setUpdateUserId(String.valueOf(currentUserId));
|
|
|
+ updateBaby.setId(existBaby.getId());
|
|
|
+ updateBaby.setConstellation(ConstellationUtil.getConstellation(dto.getBirthdayNew()));
|
|
|
+ // 防止全表更新
|
|
|
+ UpdateWrapper<BtBabyInfo> wrapper = new UpdateWrapper<>();
|
|
|
+ wrapper.eq("id", dto.getId())
|
|
|
+ .eq("delete_flag", 0);
|
|
|
+ int rows =babyInfoMapper.update(updateBaby, wrapper);
|
|
|
+ // 4. 执行更新
|
|
|
+// int rows = babyInfoMapper.updateById(updateBaby);
|
|
|
+ if (rows != 1) {
|
|
|
+ throw new BaseException("更新失败,请稍后重试");
|
|
|
+ }
|
|
|
+
|
|
|
+ return getBabyDetail(existBaby.getId());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 新增宝宝信息 baby实体转换为VO
|
|
|
+ * @param baby
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private BabyInfoVO convertToVO(BtBabyInfo baby) {
|
|
|
+ BabyInfoVO vo = new BabyInfoVO();
|
|
|
+ BeanUtils.copyProperties(baby, vo);
|
|
|
+ vo.setBirthdayNew(new SimpleDateFormat("yyyy-MM-dd").format(baby.getBirthdayNew()));
|
|
|
+ vo.setGender(baby.getGender() == 0 ? "男" : "女");
|
|
|
+ // 血型映射逻辑...
|
|
|
+ // 血型映射
|
|
|
+ vo.setBloodType(BloodType.getDescriptionByCode(baby.getBloodType()));
|
|
|
+ vo.setCreateTime(baby.getCreateTime());
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新宝宝信息 权限校验 是否为创建人
|
|
|
+ * @param babyId
|
|
|
+ * @param userId
|
|
|
+ */
|
|
|
+ private void checkUpdatePermission(Long babyId, Long userId) {
|
|
|
+ LambdaQueryWrapper<BtBabyUserRelation> query = new LambdaQueryWrapper<>();
|
|
|
+ query.eq(BtBabyUserRelation::getBabyId, babyId.toString())
|
|
|
+// .eq(BtBabyUserRelation::getUserId, userId.toString())
|
|
|
+ .eq(BtBabyUserRelation::getIsFounder, 1);
|
|
|
+
|
|
|
+ if (relationMapper.selectCount(query) == 0) {
|
|
|
+ throw new BaseException("无修改权限");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private BabyInfoVO getBabyDetail(Long babyId) {
|
|
|
+ BtBabyInfo baby = babyInfoMapper.selectById(babyId);
|
|
|
+ return convertToVO(baby);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查用户是否有权限修改宝宝信息
|
|
|
+ */
|
|
|
+ private void checkFounderPermission(Long babyId) {
|
|
|
+ QueryWrapper<BtBabyUserRelation> queryWrapper = new QueryWrapper<>();
|
|
|
+ queryWrapper
|
|
|
+// .eq("user_id", userId)
|
|
|
+ .eq("baby_id", babyId)
|
|
|
+ .eq("is_founder", 1);
|
|
|
+
|
|
|
+ BtBabyUserRelation relation = relationMapper.selectOne(queryWrapper);
|
|
|
+ if (relation == null) {
|
|
|
+ throw new BaseException("仅创建人可修改宝宝信息");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|