package com.ruoyi.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
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.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.dto.asset.AssetAdDTO;
import com.ruoyi.system.mapper.AssetAdMapper;
import com.ruoyi.system.mapper.AssetAdRentalRecordMapper;
import com.ruoyi.system.model.AssetAd;
import com.ruoyi.system.model.AssetAdRentalRecord;
import com.ruoyi.system.query.AssetAdQuery;
import com.ruoyi.system.service.AssetAdService;
import com.ruoyi.system.service.AssetTypeService;
import com.ruoyi.system.vo.asset.AssetAdDetailVO;
import com.ruoyi.system.vo.asset.AssetAdRentalRecordVO;
import com.ruoyi.system.vo.asset.AssetAdVO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
*
* 广告无形资产表 服务实现类
*
*
* @author WuGuanFengYue
* @since 2025-09-15
*/
@Service
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class AssetAdServiceImpl extends ServiceImpl implements AssetAdService {
private final AssetTypeService assetTypeService;
private final AssetAdRentalRecordMapper rentalRecordMapper;
@Override
public void addAssetAd(AssetAdDTO dto) {
AssetAd assetAd = BeanUtil.copyProperties(dto, AssetAd.class);
assetAd.setAssetTypeId(2);
assetAd.setAssetCode(generateCode());
assetAd.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
save(assetAd);
}
private String generateCode() {
// 根据资产类型ID获取资产编码前缀
String typeCodePrefix = assetTypeService.getAssetCodePrefix(2);
LocalDate today = LocalDate.now();
String dateStr = today.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
String prefix = typeCodePrefix + dateStr + "-";
// 查询当天该类型资产的数量
Long count = this.lambdaQuery()
.like(AssetAd::getAssetCode, prefix)
.ge(AssetAd::getCreateTime, today.atStartOfDay())
.lt(AssetAd::getCreateTime, today.plusDays(1).atStartOfDay())
.count();
int sequence = (count != null ? count.intValue() : 0) + 1;
String sequenceStr = String.format("%04d", sequence);
return prefix + sequenceStr;
}
@Override
public void editAssetAd(AssetAdDTO dto) {
AssetAd assetAd = BeanUtil.copyProperties(dto, AssetAd.class);
assetAd.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName());
updateById(assetAd);
}
@Override
public IPage getPageList(AssetAdQuery query) {
// 1. 分页查询 AssetAd
Page page = new Page<>(query.getPageNum(), query.getPageSize());
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper()
.like(StringUtils.isNotBlank(query.getKeyword()), AssetAd::getAssetName, query.getKeyword())
.or()
.like(StringUtils.isNotBlank(query.getKeyword()), AssetAd::getAssetCode, query.getKeyword())
.orderByDesc(AssetAd::getCreateTime);
Page assetPage = this.page(page, queryWrapper);
// 2. 如果没有数据,返回空分页
if (assetPage.getRecords().isEmpty()) {
return new Page<>(query.getPageNum(), query.getPageSize());
}
// 3. 获取所有资产ID
List assetAdIds = assetPage.getRecords().stream()
.map(AssetAd::getId)
.collect(Collectors.toList());
// 4. 查询相关租赁记录
LocalDate today = LocalDate.now();
List allRentalRecords = rentalRecordMapper.selectList(
new LambdaQueryWrapper()
.in(AssetAdRentalRecord::getAssetAdId, assetAdIds)
.ge(AssetAdRentalRecord::getStartDate, today)
.le(AssetAdRentalRecord::getEndDate,today)
.orderByDesc(AssetAdRentalRecord::getCreateTime)
);
// 5. 转换为Map
Map currentRentalMap = allRentalRecords.stream()
.collect(Collectors.toMap(AssetAdRentalRecord::getAssetAdId, Function.identity()));
// 6. 组装VO数据
List voList = new ArrayList<>();
for (AssetAd asset : assetPage.getRecords()) {
AssetAdVO vo = BeanUtil.copyProperties(asset, AssetAdVO.class);
// 设置租赁相关信息
AssetAdRentalRecord currentRental = currentRentalMap.get(asset.getId());
if (currentRental != null) {
vo.setCurrentUseBy(currentRental.getUseBy());
vo.setRentalPrice(currentRental.getRentalPrice());
vo.setUseDuration(calculateUseDuration(currentRental.getStartDate(), currentRental.getEndDate()));
}
voList.add(vo);
}
// 7. 返回分页结果
Page resultPage = new Page<>(query.getPageNum(), query.getPageSize());
resultPage.setRecords(voList);
resultPage.setTotal(assetPage.getTotal());
resultPage.setSize(assetPage.getSize());
resultPage.setCurrent(assetPage.getCurrent());
resultPage.setPages(assetPage.getPages());
return resultPage;
}
/**
* 计算使用期限(月)
*/
private Integer calculateUseDuration(LocalDate startDate, LocalDate endDate) {
if (startDate == null || endDate == null) {
return null;
}
// 计算月份差值
long months = ChronoUnit.MONTHS.between(startDate, endDate);
return (int) months;
}
@Override
public AssetAdDetailVO getDetail(Integer id) {
// 1. 查询资产基础信息
AssetAd assetAd = getById(id);
if (assetAd == null) {
return null;
}
// 2. 查询租赁记录
List rentalRecords = rentalRecordMapper.selectList(
new LambdaQueryWrapper()
.eq(AssetAdRentalRecord::getAssetAdId, id)
.orderByDesc(AssetAdRentalRecord::getStartDate)
);
// 3. 转换为AssetAdDetailVO
AssetAdDetailVO detailVO = BeanUtil.copyProperties(assetAd, AssetAdDetailVO.class);
// 4. 转换租赁记录为VO列表
List rentalRecordVOList = BeanUtil.copyToList(rentalRecords, AssetAdRentalRecordVO.class);
detailVO.setRentalRecordVOList(rentalRecordVOList);
return detailVO;
}
@Override
public void importAssetAd(List list) {
List collect = list.stream().map(item -> {
AssetAd assetAd = BeanUtil.copyProperties(item, AssetAd.class);
assetAd.setAssetTypeId(2);
assetAd.setAssetCode(generateCode());
assetAd.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
return assetAd;
}).collect(Collectors.toList());
saveBatch(collect);
}
}