package com.xy.service;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yitter.idgen.YitIdHelper;
import com.xy.collections.list.JArrayList;
import com.xy.collections.list.JList;
import com.xy.config.DeviceThreadPoolConfig;
import com.xy.config.FileConfig;
import com.xy.dto.DeviceChargingHistoryDto;
import com.xy.dto.OrderMercManageDto;
import com.xy.dto.be.MercDto;
import com.xy.entity.DeviceChargingHistory;
import com.xy.mapper.DeviceChargingHistoryMapper;
import com.xy.service.be.MercService;
import com.xy.util.ExcelUtils;
import com.xy.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.SneakyThrows;
import lombok.experimental.Accessors;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.YearMonth;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static com.xy.utils.Beans.copy;
import static com.xy.utils.PlusBeans.toPageBean;
/**
*
* 设备计费历史表 服务实现类
*
*
* @author lijin
* @since 2023-04-14
*/
@Service
@AllArgsConstructor
@Api(tags = "设备计费历史表")
public class DeviceChargingHistoryServiceImpl extends ServiceImpl implements DeviceChargingHistoryService {
private OrderMercManageService orderMercManageService;
private MercService mercService;
private HttpServletResponse response;
private FileConfig fileConfig;
@Override
@ApiOperation("分页查询")
public R> page(DeviceChargingHistoryDto.Page page) {
LambdaQueryWrapper lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(page, DeviceChargingHistory.class)
.build()
.orderByDesc(DeviceChargingHistory::getCreateTime);
IPage iPage = page(PlusBeans.toIPage(page.getPage()), lambdaQueryWrapper);
PageBean pageBean = toPageBean(DeviceChargingHistoryDto.Vo.class, iPage);
List records = pageBean.getRecords();
if (Emptys.check(records)) {
copy(records)
.target(() -> orderMercManageService.list(new OrderMercManageDto.SelectList().setId(new JArrayList<>(records).getProperty(DeviceChargingHistoryDto.Vo::getOrderId))).getData()
, DeviceChargingHistoryDto.Vo::getOrderId, DeviceChargingHistoryDto.Vo::getFiles, OrderMercManageDto.Vo::getId, OrderMercManageDto.Vo::getFiles
)
.target(() -> mercService.list(new MercDto.SelectList().setMercIds(new JArrayList<>(records).getProperty(DeviceChargingHistoryDto.Vo::getMercId).comparing())).getData(),
DeviceChargingHistoryDto.Vo::getMercId, DeviceChargingHistoryDto.Vo::getMercName, MercDto.Vo::getId, MercDto.Vo::getName)
.builder();
}
return R.ok(pageBean);
}
@ApiOperation("月统计")
@PostMapping("moonCount")
public R> moonCount(@RequestBody DeviceChargingHistoryDto.MoonCount moonCount) {
JList moonCountVos = new JArrayList<>();
//查询数据
List attrNames = Arrays.asList(
LambdaUtils.getUnderlineCaseName(DeviceChargingHistory::getMercId),
"DATE_FORMAT(" + LambdaUtils.getUnderlineCaseName(DeviceChargingHistory::getCreateTime) + ", '%Y-%m')"
);
List selectNames = Arrays.asList(
attrNames.get(0),
attrNames.get(1) + " " + LambdaUtils.getProperty(DeviceChargingHistory::getNote),
String.format("count(*) %s", LambdaUtils.getProperty(DeviceChargingHistory::getChargingSize)),
String.format("sum(%s) %s", LambdaUtils.getUnderlineCaseName(DeviceChargingHistory::getChargingMoney), LambdaUtils.getProperty(DeviceChargingHistory::getChargingMoney))
);
List dateDifference = getDateDifference(moonCount.getBeginDate(), moonCount.getEndDate());
ThreadPoolUtils.Execute execute = ThreadPoolUtils.excPoll(DeviceThreadPoolConfig.DEVICE_COMMON_POLL, dateDifference.size());
dateDifference.forEach(date -> execute.execute(() -> {
QueryWrapper queryWrapper = new QueryWrapper()
.select(selectNames.get(0), selectNames.get(1), selectNames.get(2), selectNames.get(3))
.in(Emptys.check(moonCount.getMercIds()), attrNames.get(0), moonCount.getMercIds())
.eq(attrNames.get(1), date)
.groupBy(attrNames.get(0), attrNames.get(1));
List deviceChargingHistories = list(queryWrapper);
deviceChargingHistories.forEach(deviceChargingHistory -> {
DeviceChargingHistoryDto.MoonCountVo moonCountVo = new DeviceChargingHistoryDto.MoonCountVo()
.setDate(deviceChargingHistory.getNote())
.setMercId(deviceChargingHistory.getMercId())
.setDeviceSize(deviceChargingHistory.getChargingSize())
.setChargingMoney(deviceChargingHistory.getChargingMoney());
moonCountVos.add(moonCountVo);
});
}));
execute.end();
//翻译商户名称
Beans.copy(moonCountVos).target(() -> mercService.list(new MercDto.SelectList().setMercIds(moonCountVos.getProperty(DeviceChargingHistoryDto.MoonCountVo::getMercId).comparing())).getData(),
DeviceChargingHistoryDto.MoonCountVo::getMercId, DeviceChargingHistoryDto.MoonCountVo::getMercName, MercDto.Vo::getId, MercDto.Vo::getName)
.builder();
return R.ok(moonCountVos.asc(DeviceChargingHistoryDto.MoonCountVo::getDate));
}
@SneakyThrows
@ApiOperation("月统计导出")
@PostMapping("moonCountDownload")
public void moonCountDownload(@RequestBody DeviceChargingHistoryDto.MoonCount moonCount) {
//生成excel
String name = YitIdHelper.nextId() + ".xlsx";
String path = fileConfig.getPath() + File.separator + name;
ExcelUtils.SheetAndData sheetAndData = ExcelUtils.create(path, MoonCountData.class);
sheetAndData.sheet("设备管理费月统计数据", () -> {
List data = moonCount(moonCount).getData();
if (!Emptys.check(data)) {
return null;
}
return Beans.copy(MoonCountData.class, data);
}).builder();
//下载文件
InputStream inputStream = IoUtils.inputStream(path).get();
response.setHeader("Content-Disposition", "attachment; filename=" + "设备管理费月统计数据.xlsx");
response.setContentType("application/xlsx");
byte[] buffer = new byte[1024];
int bytesRead;
OutputStream outputStream = response.getOutputStream();
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outputStream.close();
//删除文件
new File(path).delete();
}
public List getDateDifference(String date1, String date2) {
List dateDifference = new ArrayList<>();
// 解析日期字符串
YearMonth yearMonth1 = YearMonth.parse(date1);
YearMonth yearMonth2 = YearMonth.parse(date2);
// 计算日期差异
long monthsDiff = ChronoUnit.MONTHS.between(yearMonth1, yearMonth2);
// 将差异的每个月添加到集合中
YearMonth temp = yearMonth1;
for (int i = 0; i <= monthsDiff; i++) {
dateDifference.add(temp.toString());
temp = temp.plusMonths(1);
}
return dateDifference;
}
@Data
@Accessors(chain = true)
public static class MoonCountData {
@ColumnWidth(25)
@ExcelProperty(value = "统计时间 yyyy-MM")
private String date;
@ColumnWidth(25)
@ExcelProperty(value = "商户id")
private Long mercId;
@ColumnWidth(25)
@ExcelProperty(value = "商户名称")
private String mercName;
@ColumnWidth(25)
@ExcelProperty(value = "设备数")
private Integer deviceSize;
@ColumnWidth(25)
@ExcelProperty(value = "续费金额")
private Integer chargingMoney;
}
}