package com.xy.service;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
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.device.EnumSimConfig;
import com.xy.dto.DeviceSimChargeDto;
import com.xy.dto.MercFeeConfigDto;
import com.xy.dto.OrderMercManageDto;
import com.xy.dto.be.MercDto;
import com.xy.entity.DeviceSim;
import com.xy.entity.DeviceSimCharge;
import com.xy.entity.SysDictRedis;
import com.xy.mapper.DeviceSimChargeMapper;
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.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static com.xy.utils.Beans.copy;
import static com.xy.utils.PlusBeans.toIPage;
import static com.xy.utils.PlusBeans.toPageBean;
/**
*
* 设备流量卡充值表 服务实现类
*
*
* @author lijin
* @since 2023-10-16
*/
@Service
@AllArgsConstructor
@Api(tags = "设备流量卡充值表")
public class DeviceSimChargeServiceImpl extends ServiceImpl implements DeviceSimChargeService {
private OrderMercManageService orderMercManageService;
private MercService mercService;
private DeviceChargingHistoryServiceImpl deviceChargingHistoryService;
private HttpServletResponse response;
private FileConfig fileConfig;
private MercFeeConfigService mercFeeConfigService;
private DeviceSimServiceImpl deviceSimService;
@PostMapping("page")
@ApiOperation("分页查询")
public R> page(@RequestBody DeviceSimChargeDto.Page page) {
PageBean pageBean = page.getPage();
LambdaQueryWrapper lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(page, DeviceSimCharge.class)
.ge(DeviceSimCharge::getCreateTime, page.getBeginCreateTime())
.le(DeviceSimCharge::getCreateTime, page.getEndCreateTime())
.build()
.orderByDesc(!Emptys.check(pageBean.getOrders()), DeviceSimCharge::getCreateTime);
IPage iPage = page(toIPage(pageBean), lambdaQueryWrapper);
PageBean voPageBean = toPageBean(DeviceSimChargeDto.Vo.class, iPage);
List records = voPageBean.getRecords();
if (Emptys.check(records)) {
copy(records)
.target(() -> orderMercManageService.list(new OrderMercManageDto.SelectList().setId(new JArrayList<>(records).getProperty(DeviceSimChargeDto.Vo::getOrderId))).getData()
, DeviceSimChargeDto.Vo::getOrderId, DeviceSimChargeDto.Vo::getFiles, OrderMercManageDto.Vo::getId, OrderMercManageDto.Vo::getFiles
).target(() -> mercService.list(new MercDto.SelectList().setMercIds(new JArrayList<>(records).getProperty(DeviceSimChargeDto.Vo::getMercId).comparing())).getData()
, DeviceSimChargeDto.Vo::getMercId, DeviceSimChargeDto.Vo::getMercName, MercDto.Vo::getId, MercDto.Vo::getName)
.builder();
}
return R.ok(voPageBean);
}
public R> pageByTopMerc(DeviceSimChargeDto.PageByTopMerc page) {
Long curMercId = page.getCurMercId();
Long chooseMercId = page.getChooseMercId();
List mercIds = new ArrayList<>();
if (chooseMercId == null) {
mercIds = R.feignCheckData(mercService.getChildMercIds(new MercDto.QuerySubDTO().setParentMercID(curMercId)));
} else {
// 指定商户ID
mercIds.add(chooseMercId);
}
if (CollUtil.isEmpty(mercIds)) {
return R.ok();
}
PageBean pageBean = page.getPage();
LambdaQueryWrapper lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(page, DeviceSimCharge.class)
.ge(DeviceSimCharge::getCreateTime, page.getBeginCreateTime())
.le(DeviceSimCharge::getCreateTime, page.getEndCreateTime())
.in(DeviceSimCharge::getMercId, mercIds)
.build()
.orderByDesc(!Emptys.check(pageBean.getOrders()), DeviceSimCharge::getCreateTime);
IPage iPage = page(toIPage(pageBean), lambdaQueryWrapper);
PageBean voPageBean = toPageBean(DeviceSimChargeDto.PageByTopMercVO.class, iPage);
List records = voPageBean.getRecords();
if (Emptys.check(records)) {
// 佣金配置查询
List feeConfigByMercVOS = R.feignCheckData(mercFeeConfigService.listFeeConfigByMerc(new MercFeeConfigDto.ListFeeConfigByMercDTO().setMercId(curMercId)));
Map configByMercVOMap = MapUtil.newHashMap();
if (CollUtil.isNotEmpty(feeConfigByMercVOS)) {
configByMercVOMap = feeConfigByMercVOS.stream().collect(Collectors.toMap(MercFeeConfigDto.ListFeeConfigByMercVO::getMercId, f -> f));
}
copy(records)
.target(() -> orderMercManageService.list(new OrderMercManageDto.SelectList().setId(new JArrayList<>(records).getProperty(DeviceSimChargeDto.PageByTopMercVO::getOrderId))).getData()
, DeviceSimChargeDto.PageByTopMercVO::getOrderId, DeviceSimChargeDto.PageByTopMercVO::getFiles, OrderMercManageDto.Vo::getId, OrderMercManageDto.Vo::getFiles
).target(() -> mercService.list(new MercDto.SelectList().setMercIds(new JArrayList<>(records).getProperty(DeviceSimChargeDto.PageByTopMercVO::getMercId).comparing())).getData()
, DeviceSimChargeDto.PageByTopMercVO::getMercId, DeviceSimChargeDto.PageByTopMercVO::getMercName, MercDto.Vo::getId, MercDto.Vo::getName)
.builder();
List simIds = records.stream().map(DeviceSimChargeDto.PageByTopMercVO::getSimId).collect(Collectors.toList());
List deviceSims = deviceSimService.listByIds(simIds);
Map deviceSimMap = MapUtil.newHashMap();
if (CollUtil.isNotEmpty(deviceSims)) {
deviceSimMap = deviceSims.stream().collect(Collectors.toMap(DeviceSim::getId, ds -> ds));
}
Map simConfig = SysDictUtils.get(EnumSimConfig.Code.CODE.getCode());
Integer value = Integer.valueOf(simConfig.get(EnumSimConfig.N_200.getCode()).getValue());
for (DeviceSimChargeDto.PageByTopMercVO record : records) {
Long mercId = record.getMercId();
String simId = record.getSimId();
// 佣金初始化
Integer extraMoney = 0;
MercFeeConfigDto.ListFeeConfigByMercVO listFeeConfigByMercVO = configByMercVOMap.get(mercId);
if (listFeeConfigByMercVO != null) {
extraMoney = listFeeConfigByMercVO.getFeeConfig().getFeeSimcard();
record.setAgentMoney(extraMoney);
}
DeviceSim sim = deviceSimMap.get(simId);
// 封装过期状态说明
if (Emptys.check(sim)) {
LocalDateTime timeout = sim.getTimeout();
if (timeout == null) {
record.setTimeoutStatus("未初始化");
} else {
String timeoutStatus;
long s = DataTime.diff(LocalDateTime.now(), timeout, "s");
if (s <= 0) {
timeoutStatus = "欠费(" + (~(s / 86400 - 1)) + "天)";
} else {
timeoutStatus = s <= value * 86400 ? "即将到期(" + s / 86400 + "天)" : "正常(" + s / 86400 + "天)";
}
record.setTimeoutStatus(timeoutStatus);
}
record.setTimeout(timeout);
}
}
}
return R.ok(voPageBean);
}
/**
* 财务管理-支出管理-流量卡费明细
*
* @param page
* @return
*/
public R> mySpendPage(DeviceSimChargeDto.PageByTopMerc page) {
Long curMercId = page.getCurMercId();
List mercIds = new ArrayList<>();
// 指定商户ID
mercIds.add(curMercId);
PageBean pageBean = page.getPage();
LambdaQueryWrapper lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(page, DeviceSimCharge.class)
.ge(DeviceSimCharge::getCreateTime, page.getBeginCreateTime())
.le(DeviceSimCharge::getCreateTime, page.getEndCreateTime())
.in(DeviceSimCharge::getMercId, mercIds)
.build()
.orderByDesc(!Emptys.check(pageBean.getOrders()), DeviceSimCharge::getCreateTime);
IPage iPage = page(toIPage(pageBean), lambdaQueryWrapper);
PageBean voPageBean = toPageBean(DeviceSimChargeDto.MySpendPageVO.class, iPage);
List records = voPageBean.getRecords();
if (Emptys.check(records)) {
copy(records)
.target(() -> orderMercManageService.list(new OrderMercManageDto.SelectList().setId(new JArrayList<>(records).getProperty(DeviceSimChargeDto.MySpendPageVO::getOrderId))).getData()
, DeviceSimChargeDto.MySpendPageVO::getOrderId, DeviceSimChargeDto.MySpendPageVO::getFiles, OrderMercManageDto.Vo::getId, OrderMercManageDto.Vo::getFiles
).target(() -> mercService.list(new MercDto.SelectList().setMercIds(new JArrayList<>(records).getProperty(DeviceSimChargeDto.MySpendPageVO::getMercId).comparing())).getData()
, DeviceSimChargeDto.MySpendPageVO::getMercId, DeviceSimChargeDto.MySpendPageVO::getMercName, MercDto.Vo::getId, MercDto.Vo::getName)
.builder();
List simIds = records.stream().map(DeviceSimChargeDto.MySpendPageVO::getSimId).collect(Collectors.toList());
List deviceSims = deviceSimService.listByIds(simIds);
Map deviceSimMap = MapUtil.newHashMap();
if (CollUtil.isNotEmpty(deviceSims)) {
deviceSimMap = deviceSims.stream().collect(Collectors.toMap(DeviceSim::getId, ds -> ds));
}
Map simConfig = SysDictUtils.get(EnumSimConfig.Code.CODE.getCode());
Integer value = Integer.valueOf(simConfig.get(EnumSimConfig.N_200.getCode()).getValue());
for (DeviceSimChargeDto.MySpendPageVO record : records) {
Long mercId = record.getMercId();
String simId = record.getSimId();
DeviceSim sim = deviceSimMap.get(simId);
// 封装过期状态说明
if (Emptys.check(sim)) {
LocalDateTime timeout = sim.getTimeout();
if (timeout == null) {
record.setTimeoutStatus("未初始化");
} else {
String timeoutStatus;
long s = DataTime.diff(LocalDateTime.now(), timeout, "s");
if (s <= 0) {
timeoutStatus = "欠费(" + (~(s / 86400 - 1)) + "天)";
} else {
timeoutStatus = s <= value * 86400 ? "即将到期(" + s / 86400 + "天)" : "正常(" + s / 86400 + "天)";
}
record.setTimeoutStatus(timeoutStatus);
}
record.setTimeout(timeout);
}
}
}
return R.ok(voPageBean);
}
@ApiOperation("月统计分页")
@PostMapping("moonCountPage")
public R> moonCountPage(@RequestBody DeviceSimChargeDto.MoonCountPage moonCountPage) {
JList moonCountVos = new JArrayList<>();
// 查询数据
List attrNames = Arrays.asList(
LambdaUtils.getUnderlineCaseName(DeviceSimCharge::getMercId)
);
List selectNames = Arrays.asList(
attrNames.get(0),
String.format("count(*) %s", LambdaUtils.getProperty(DeviceSimCharge::getSize)),
String.format("sum(%s) %s", LambdaUtils.getUnderlineCaseName(DeviceSimCharge::getMoney), LambdaUtils.getProperty(DeviceSimCharge::getMoney))
);
QueryWrapper queryWrapper = new QueryWrapper()
.select(selectNames.toArray(new String[selectNames.size()]))
.in(Emptys.check(moonCountPage.getMercIds()), attrNames.get(0), moonCountPage.getMercIds())
.between("DATE_FORMAT(" + LambdaUtils.getUnderlineCaseName(DeviceSimCharge::getCreateTime) + ", '%Y-%m-%d')", moonCountPage.getBeginDate(), moonCountPage.getEndDate())
.groupBy(attrNames);
IPage iPage = page(toIPage(moonCountPage.getPage()), queryWrapper);
List records = iPage.getRecords();
if (!Emptys.check(records)) {
return R.ok(new PageBean<>());
}
String date = String.format("%s~%s", moonCountPage.getBeginDate(), moonCountPage.getEndDate());
records.forEach(deviceSimCharge -> {
DeviceSimChargeDto.MoonCountVo moonCountVo = new DeviceSimChargeDto.MoonCountVo()
.setDate(date)
.setMercId(deviceSimCharge.getMercId())
.setSimSize(deviceSimCharge.getSize())
.setMoney(deviceSimCharge.getMoney());
moonCountVos.add(moonCountVo);
});
// 翻译商户名称
Beans.copy(moonCountVos).target(() -> mercService.list(new MercDto.SelectList().setMercIds(moonCountVos.getProperty(DeviceSimChargeDto.MoonCountVo::getMercId).comparing())).getData(),
DeviceSimChargeDto.MoonCountVo::getMercId, DeviceSimChargeDto.MoonCountVo::getMercName, MercDto.Vo::getId, MercDto.Vo::getName)
.builder();
PageBean pageBean = new PageBean()
.setCurrent(iPage.getCurrent())
.setSize(iPage.getSize())
.setTotal(iPage.getTotal())
.setRecords(moonCountVos);
return R.ok(pageBean);
}
@ApiOperation("月统计")
@PostMapping("moonCount")
public R> moonCount(@RequestBody DeviceSimChargeDto.MoonCount moonCount) {
JList moonCountVos = new JArrayList<>();
// 查询数据
List attrNames = Arrays.asList(
LambdaUtils.getUnderlineCaseName(DeviceSimCharge::getMercId),
"DATE_FORMAT(" + LambdaUtils.getUnderlineCaseName(DeviceSimCharge::getCreateTime) + ", '%Y-%m')"
);
List selectNames = Arrays.asList(
attrNames.get(0),
attrNames.get(1) + " " + LambdaUtils.getProperty(DeviceSimCharge::getNote),
String.format("count(*) %s", LambdaUtils.getProperty(DeviceSimCharge::getSize)),
String.format("sum(%s) %s", LambdaUtils.getUnderlineCaseName(DeviceSimCharge::getMoney), LambdaUtils.getProperty(DeviceSimCharge::getMoney))
);
List dateDifference = deviceChargingHistoryService.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 deviceSimCharges = list(queryWrapper);
deviceSimCharges.forEach(deviceSimCharge -> {
DeviceSimChargeDto.MoonCountVo moonCountVo = new DeviceSimChargeDto.MoonCountVo()
.setDate(deviceSimCharge.getNote())
.setMercId(deviceSimCharge.getMercId())
.setSimSize(deviceSimCharge.getSize())
.setMoney(deviceSimCharge.getMoney());
moonCountVos.add(moonCountVo);
});
}));
execute.end();
// 翻译商户名称
Beans.copy(moonCountVos).target(() -> mercService.list(new MercDto.SelectList().setMercIds(moonCountVos.getProperty(DeviceSimChargeDto.MoonCountVo::getMercId).comparing())).getData(),
DeviceSimChargeDto.MoonCountVo::getMercId, DeviceSimChargeDto.MoonCountVo::getMercName, MercDto.Vo::getId, MercDto.Vo::getName)
.builder();
return R.ok(moonCountVos.desc(DeviceSimChargeDto.MoonCountVo::getDate));
}
@SneakyThrows
@ApiOperation("月统计导出")
@PostMapping("moonCountDownload")
public void moonCountDownload(@RequestBody DeviceSimChargeDto.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();
}
@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 simSize;
@ColumnWidth(25)
@ExcelProperty(value = "续费金额")
private Integer money;
}
}