package com.example.mybatisplus.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
//import cn.hutool.core.util.StrUtil;
//import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.example.mybatisplus.domain.dto.PageDTO;
import com.example.mybatisplus.domain.po.Address;
import com.example.mybatisplus.domain.po.User;
import com.example.mybatisplus.domain.query.UserQuery;
import com.example.mybatisplus.domain.vo.AddressVO;
import com.example.mybatisplus.domain.vo.UserVO;
import com.example.mybatisplus.enums.UserStatus;
import com.example.mybatisplus.mapper.UserMapper;
import com.example.mybatisplus.service.IUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class IUserServiceImpl extends ServiceImpl<UserMapper,User> implements IUserService {
@Override
@Transactional //抛出异常之后,事务会自动回滚,数据不会插入到数据库中(只能应用到 public 方法或者类上才有效)
public void deductBalance(Long id, Double money) {
// 1.查询用户
User user = this.getById(id);
// 2.校验用户状态
if(user == null || user.getStatus() == UserStatus.FROZEN){
throw new RuntimeException("用户不存在或状态异常");
}
// 3.校验余额
if(user.getBalance() < money){
throw new RuntimeException("余额不足");
}
// 4.扣款
// baseMapper.deductBalance(id,money);
double remainBalance = user.getBalance() - money;
lambdaUpdate()
.set(User::getBalance,remainBalance)
.set(remainBalance == 0,User::getStatus,UserStatus.FROZEN)
.eq(User::getId,id)
.eq(User::getBalance,user.getBalance())//乐观锁
.update();
}
/**
* 根据多个条件查询用户
* @param minBalance maxBalance name status
* @return List<User>
*/
@Override
public List<User> queryUsers(Integer maxBalance, Integer minBalance, String name, Integer status) {
return lambdaQuery()
.like(name != null,User::getUsername,name)
.le(maxBalance != null,User::getBalance,maxBalance)//小于等于
.ge(minBalance != null,User::getBalance,minBalance)//大于等于
.eq(status != null,User::getStatus,status)//等于
.list();
}
@Override
public UserVO getUserAndAddressById(Long id) {
//1.查询用户
User user = this.getById(id);
if(user == null || user.getStatus() == UserStatus.FROZEN){
throw new RuntimeException("用户不存在或状态异常");
}
//2.查询用户地址
List<Address> addresses = Db.lambdaQuery(Address.class).eq(Address::getUserId, user.getId()).list();
// 3.封装VO
// 3.1 转UserPO为VO
UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);
// 3.2 转地址VO
if(CollUtil.isNotEmpty(addresses)) {
userVO.setAddresses(BeanUtil.copyToList(addresses, AddressVO.class));
}
return userVO;
}
@Override
public List<UserVO> getUserAndAddressByIds(List<Long> ids) {
// 1.查询用户
List<User> users = listByIds(ids);
if(CollUtil.isEmpty(users)){//用户不存在,换回空集合
return Collections.emptyList();
}
// 2. 查询用户地址
// 2.1 获取已查询用户id
List<Long> collect = users.stream().map(User::getId).collect(Collectors.toList());
// 2.2 查询用户地址
List<Address> addresses = Db.lambdaQuery(Address.class).in(Address::getUserId, collect).list();
// 2.3 转换成地址VO
List<AddressVO> addressVOList = BeanUtil.copyToList(addresses, AddressVO.class);
// 2.4 用户地址集合分组处理,相同用户放入一个集合(组)中
Map<Long, List<AddressVO>> listMap = new HashMap<>(0);
if(CollUtil.isNotEmpty(addressVOList)){
listMap = addressVOList.stream().collect(Collectors.groupingBy(AddressVO::getUserId));
}
// 3. 封装VO返回
List<UserVO> userVOS = new ArrayList<>(users.size());
for (User user : users) {
// 3.1 转UserPO为VO
UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);
// 3.2 获取用户地址
userVO.setAddresses(listMap.get(user.getId()));
// 3.3 添加到集合中
userVOS.add(userVO);
}
return userVOS;
}
@Override//分页
public PageDTO<UserVO> queryUserPage(UserQuery userQuery) {
String name = userQuery.getName();
Integer status = userQuery.getStatus();
// Integer pageNo = userQuery.getPageNo();
// Integer pageSize = userQuery.getPageSize();
// String sortBy = userQuery.getSortBy();
// Boolean isAsc = userQuery.getIsAsc();
// 1.构建查询条件
// Page<User> page = Page.of(pageNo, pageSize);
// if(StrUtil.isNotBlank(sortBy) && isAsc != null) {
// page.addOrder(new OrderItem().setAsc(isAsc).setColumn(sortBy));
// }else {
// // 默认按照更新时间排序
// page.addOrder(new OrderItem().setAsc(false).setColumn("update_time"));
// }
Page<User> page = userQuery.toMpPageDefaultSortByUpdateTimeDesc();
// 2.分页查询
Page<User> userPage = lambdaQuery().like(name != null, User::getUsername, name)
.eq(status != null, User::getStatus, status)
.page(page);
//3.封装VO
// PageDTO<UserVO> dto = new PageDTO<>();
// dto.setTotal(userPage.getTotal());// 总条数
// dto.setPages(userPage.getPages());// 总页数
// List<User> records = userPage.getRecords();// 当前页数据
// if(CollUtil.isEmpty(records)){
// dto.setList(Collections.emptyList());
// return dto;
// }
// dto.setList(BeanUtil.copyToList(records, UserVO.class));
// // 4.返回
// return dto;
// return PageDTO.of(userPage,UserVO.class);
return PageDTO.of(userPage, user -> {
//1.拷贝基础属性
UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);
//2.处理特殊逻辑(如隐藏名字后两位)
userVO.setUsername(user.getUsername().substring(0, user.getUsername().length() - 2) + "**");
return userVO;
});
};
}