| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374 |
- package com.zxyj.service;
- import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
- import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
- import com.zxyj.dto.CreateRewardDTO;
- import com.zxyj.dto.RewardDTO;
- import com.zxyj.entity.Child;
- import com.zxyj.entity.PointsLog;
- import com.zxyj.entity.Reward;
- import com.zxyj.entity.User;
- import com.zxyj.mapper.ChildMapper;
- import com.zxyj.mapper.PointsLogMapper;
- import com.zxyj.mapper.RewardMapper;
- import com.zxyj.mapper.UserMapper;
- import com.zxyj.service.api.RewardServiceInterface;
- import javax.annotation.Resource;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import java.util.Arrays;
- import java.util.Date;
- import java.util.List;
- import java.util.Map;
- import java.util.stream.Collectors;
- @Slf4j
- @Service
- public class RewardService implements RewardServiceInterface {
- @Resource
- private RewardMapper rewardMapper;
- @Resource
- private ChildMapper childMapper;
- @Resource
- private PointsLogMapper pointsLogMapper;
- @Resource
- private UserService userService;
- @Resource
- private UserMapper userMapper;
- /**
- * REWARD-001A: 孩子创建心愿单
- * 孩子添加想要的奖励到心愿单,状态为 pending_approval(待家长填写积分)
- */
- @Transactional
- public Long createWishlist(Long childId, CreateRewardDTO dto) {
- Child child = childMapper.selectById(childId);
- if (child == null) {
- throw new IllegalArgumentException("孩子不存在");
- }
- Reward reward = new Reward();
- reward.setFamilyId(child.getFamilyId());
- reward.setChildId(childId);
- reward.setTitle(dto.getTitle());
- reward.setCategory(dto.getCategory());
- // 孩子创建心愿时积分为0,等待家长填写
- reward.setPointsRequired(0);
- reward.setStatus("pending_approval"); // 待家长审批填写积分
- reward.setIsTemplate(0);
- reward.setCreatedAt(new Date());
- reward.setUpdatedAt(new Date());
- rewardMapper.insert(reward);
- log.info("孩子{}创建心愿: {}", childId, dto.getTitle());
- return reward.getId();
- }
- /**
- * REWARD-001A: 家长填写积分,心愿进入奖励库
- * 家长审批并填写所需积分后,心愿转为可兑换状态
- */
- @Transactional
- public boolean approveWishlist(Long rewardId, Long parentId, Integer pointsRequired) {
- Reward reward = rewardMapper.selectById(rewardId);
- if (reward == null) {
- return false;
- }
- // 验证家长权限:必须是同一家庭的家长
- User parent = userMapper.selectById(parentId);
- if (parent == null || !parent.getFamilyId().equals(reward.getFamilyId())) {
- log.warn("家长{}无权操作奖励{}", parentId, rewardId);
- return false;
- }
- // 验证状态:只有待审批的心愿可以填写积分
- if (!"pending_approval".equals(reward.getStatus())) {
- log.warn("奖励{}状态不是待审批: {}", rewardId, reward.getStatus());
- return false;
- }
- // 更新积分和状态
- reward.setPointsRequired(pointsRequired);
- reward.setStatus("available"); // 进入奖励库,可兑换
- reward.setUpdatedAt(new Date());
- rewardMapper.updateById(reward);
- log.info("家长{}审批心愿{},设置积分: {}", parentId, rewardId, pointsRequired);
- return true;
- }
- /**
- * 创建奖励(原有功能:家长直接创建奖励)
- */
- @Transactional
- public Long createReward(Long userId, CreateRewardDTO dto) {
- // 参数校验
- if (dto.getTitle() == null || dto.getTitle().trim().isEmpty()) {
- throw new IllegalArgumentException("请填写心愿名称");
- }
- if (dto.getPointsRequired() == null || dto.getPointsRequired() < 1) {
- throw new IllegalArgumentException("请填写有效的积分值");
- }
- // 获取用户信息并验证家庭归属
- User user = userService.getUserInfo(userId);
- if (user == null || user.getFamilyId() == null) {
- throw new IllegalArgumentException("用户必须属于某个家庭");
- }
- Reward reward = new Reward();
- reward.setFamilyId(user.getFamilyId()); // 强制关联家庭
- reward.setChildId(dto.getChildId());
- reward.setTitle(dto.getTitle().trim());
- reward.setPointsRequired(dto.getPointsRequired());
- reward.setCategory(dto.getCategory());
- reward.setStatus("available");
- reward.setIsTemplate(0);
- reward.setCreatedAt(new Date());
- reward.setUpdatedAt(new Date());
- rewardMapper.insert(reward);
- return reward.getId();
- }
- public List<RewardDTO> getWishlist(Long childId) {
- // 获取孩子信息以验证家庭归属
- Child child = childMapper.selectById(childId);
- if (child == null) {
- return null;
- }
-
- // 按家庭ID和孩子ID筛选奖励,确保奖励必须关联家庭
- List<Reward> rewards = rewardMapper.selectList(new LambdaQueryWrapper<Reward>()
- .eq(Reward::getFamilyId, child.getFamilyId())
- .eq(Reward::getChildId, childId)
- .eq(Reward::getStatus, "available")
- .orderByAsc(Reward::getPointsRequired));
-
- final int currentPoints = child != null ? child.getTotalPoints() : 0;
-
- return rewards.stream().map(r -> {
- RewardDTO dto = new RewardDTO();
- dto.setId(r.getId());
- dto.setTitle(r.getTitle());
- dto.setPointsRequired(r.getPointsRequired());
- dto.setCategory(r.getCategory());
- dto.setStatus(r.getStatus());
- dto.setExchangeApproved(r.getExchangeApproved());
- dto.setProgress(currentPoints);
- return dto;
- }).collect(Collectors.toList());
- }
- @Transactional
- public Map<String, Object> exchangeReward(Long rewardId, Long childId) {
- Reward reward = rewardMapper.selectById(rewardId);
- if (reward == null || !reward.getChildId().equals(childId)) {
- return null;
- }
- if (!"available".equals(reward.getStatus())) {
- return null;
- }
- Child child = childMapper.selectById(childId);
- if (child.getTotalPoints() < reward.getPointsRequired()) {
- return null; // 积分不足
- }
- // 扣除积分
- child.setTotalPoints(child.getTotalPoints() - reward.getPointsRequired());
- child.setUpdatedAt(new Date());
- childMapper.updateById(child);
- // 记录积分消耗
- PointsLog log = new PointsLog();
- log.setChildId(childId);
- log.setAmount(-reward.getPointsRequired());
- log.setType("spend");
- log.setDescription("兑换奖励: " + reward.getTitle());
- log.setCreatedAt(new Date());
- pointsLogMapper.insert(log);
- // 更新奖励状态
- reward.setStatus("pending"); // 待审批
- reward.setUpdatedAt(new Date());
- rewardMapper.updateById(reward);
- Map<String, Object> result = new java.util.HashMap<>();
- result.put("success", true);
- result.put("newBalance", child.getTotalPoints());
- return result;
- }
- @Transactional
- public boolean approveReward(Long rewardId, boolean approved) {
- Reward reward = rewardMapper.selectById(rewardId);
- if (reward == null) {
- return false;
- }
- if (approved) {
- reward.setStatus("exchanged");
- reward.setExchangeApproved(1);
- reward.setExchangedAt(new Date());
- } else {
- // 拒绝,返还积分
- Child child = childMapper.selectById(reward.getChildId());
- child.setTotalPoints(child.getTotalPoints() + reward.getPointsRequired());
- child.setUpdatedAt(new Date());
- childMapper.updateById(child);
- // 记录积分退还
- PointsLog log = new PointsLog();
- log.setChildId(reward.getChildId());
- log.setAmount(reward.getPointsRequired());
- log.setType("refund");
- log.setDescription("奖励兑换被拒绝,积分退还");
- log.setCreatedAt(new Date());
- pointsLogMapper.insert(log);
- reward.setStatus("rejected");
- reward.setExchangeApproved(0);
- }
- reward.setUpdatedAt(new Date());
- rewardMapper.updateById(reward);
- return true;
- }
- public List<Reward> getTemplates() {
- // 模板也必须关联家庭,这里返回所有家庭的模板(family_id > 0)
- return rewardMapper.selectList(new LambdaQueryWrapper<Reward>()
- .eq(Reward::getIsTemplate, 1)
- .gt(Reward::getFamilyId, 0)); // 确保模板关联到具体家庭
- }
- public Page<Reward> getExchangeHistory(Long childId, Integer page, Integer size) {
- Page<Reward> pageParam = new Page<>(page, size);
- return rewardMapper.selectPage(pageParam, new LambdaQueryWrapper<Reward>()
- .eq(Reward::getChildId, childId)
- .in(Reward::getStatus, Arrays.asList("exchanged", "rejected"))
- .orderByDesc(Reward::getExchangedAt));
- }
- /**
- * REWARD-002A: 获取家庭奖励库
- * 返回家庭所有可用的奖励(不含模板),多家长可查看
- */
- public List<RewardDTO> getFamilyRewardLibrary(Long familyId) {
- List<Reward> rewards = rewardMapper.selectList(new LambdaQueryWrapper<Reward>()
- .eq(Reward::getFamilyId, familyId)
- .eq(Reward::getIsTemplate, 0)
- .in(Reward::getStatus, Arrays.asList("available", "pending_approval"))
- .orderByAsc(Reward::getPointsRequired));
- return rewards.stream().map(r -> {
- RewardDTO dto = new RewardDTO();
- dto.setId(r.getId());
- dto.setTitle(r.getTitle());
- dto.setPointsRequired(r.getPointsRequired());
- dto.setCategory(r.getCategory());
- dto.setStatus(r.getStatus());
- dto.setChildId(r.getChildId());
- dto.setExchangeApproved(r.getExchangeApproved());
- return dto;
- }).collect(Collectors.toList());
- }
- /**
- * REWARD-002A: 家长修改奖励积分(多家长可调整)
- * 只有同一家庭的家长可以修改
- */
- @Transactional
- public boolean updateRewardPoints(Long rewardId, Long parentId, Integer newPoints) {
- Reward reward = rewardMapper.selectById(rewardId);
- if (reward == null) {
- return false;
- }
- // 验证家长权限
- User parent = userMapper.selectById(parentId);
- if (parent == null || !parent.getFamilyId().equals(reward.getFamilyId())) {
- log.warn("家长{}无权修改奖励{}", parentId, rewardId);
- return false;
- }
- // 只有可用状态或待审批状态可以修改
- if (!"available".equals(reward.getStatus()) && !"pending_approval".equals(reward.getStatus())) {
- log.warn("奖励{}状态不可修改: {}", rewardId, reward.getStatus());
- return false;
- }
- reward.setPointsRequired(newPoints);
- reward.setUpdatedAt(new Date());
- rewardMapper.updateById(reward);
- log.info("家长{}修改奖励{}积分为: {}", parentId, rewardId, newPoints);
- return true;
- }
- /**
- * REWARD-002B: 获取孩子的待审批心愿单(按孩子隔离)
- * 只返回指定孩子的心愿,不包含其他孩子
- */
- public List<RewardDTO> getChildPendingWishlists(Long childId) {
- Child child = childMapper.selectById(childId);
- if (child == null) {
- return null;
- }
- List<Reward> rewards = rewardMapper.selectList(new LambdaQueryWrapper<Reward>()
- .eq(Reward::getFamilyId, child.getFamilyId())
- .eq(Reward::getChildId, childId)
- .eq(Reward::getStatus, "pending_approval")
- .orderByDesc(Reward::getCreatedAt));
- return rewards.stream().map(r -> {
- RewardDTO dto = new RewardDTO();
- dto.setId(r.getId());
- dto.setTitle(r.getTitle());
- dto.setPointsRequired(r.getPointsRequired());
- dto.setCategory(r.getCategory());
- dto.setStatus(r.getStatus());
- dto.setChildId(r.getChildId());
- return dto;
- }).collect(Collectors.toList());
- }
- /**
- * REWARD-002B: 获取家长待处理的心愿审批列表(所有孩子)
- * 家长可以看到所有孩子的待审批心愿
- */
- public List<RewardDTO> getPendingApprovalList(Long familyId) {
- List<Reward> rewards = rewardMapper.selectList(new LambdaQueryWrapper<Reward>()
- .eq(Reward::getFamilyId, familyId)
- .eq(Reward::getStatus, "pending_approval")
- .eq(Reward::getIsTemplate, 0)
- .orderByDesc(Reward::getCreatedAt));
- return rewards.stream().map(r -> {
- RewardDTO dto = new RewardDTO();
- dto.setId(r.getId());
- dto.setTitle(r.getTitle());
- dto.setPointsRequired(r.getPointsRequired());
- dto.setCategory(r.getCategory());
- dto.setStatus(r.getStatus());
- dto.setChildId(r.getChildId());
- // 获取孩子昵称
- Child child = childMapper.selectById(r.getChildId());
- if (child != null) {
- dto.setChildName(child.getNickname());
- }
- return dto;
- }).collect(Collectors.toList());
- }
- }
|