package com.xy.service;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
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.collections.map.JMap;
import com.xy.config.DeviceThreadPoolConfig;
import com.xy.config.FileConfig;
import com.xy.device.EnumDeviceChargingHistoryStatus;
import com.xy.device.EnumSimConfig;
import com.xy.dto.DeviceSimDto;
import com.xy.entity.DeviceSim;
import com.xy.entity.DeviceSimCharge;
import com.xy.entity.SysDictRedis;
import com.xy.mapper.DeviceSimMapper;
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.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
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 DeviceSimServiceImpl extends ServiceImpl implements DeviceSimService {
private DeviceSimChargeServiceImpl deviceSimChargeService;
private HttpServletResponse response;
private FileConfig fileConfig;
@PostMapping("countWaitHandle")
@ApiOperation("抄送流量卡-运营首页概况")
public R countWaitHandle() {
long count = count(Wrappers.lambdaQuery().eq(DeviceSim::getWaitHandle, true));
return R.ok(count);
}
@Override
@ApiOperation("购买")
public R pay(DeviceSimDto.Pay pay) {
LocalDateTime now = LocalDateTime.now();
List deviceSimCharges = pay.getDeviceSimCharges();
List deviceSimChargess = new ArrayList<>(deviceSimCharges.size());
deviceSimCharges.forEach(deviceSimCharge -> {
DeviceSimCharge deviceSimChargeInfo = new DeviceSimCharge()
.setId(YitIdHelper.nextId())
.setOrderId(pay.getOrderId())
.setSimId(deviceSimCharge.getSimId())
.setMercId(pay.getMercId())
.setMoney(deviceSimCharge.getMoney())
.setSize(deviceSimCharge.getSize())
.setPayType(pay.getPayType())
.setNote(pay.getNote())
.setCreateTime(now)
.setUpdateTime(now);
deviceSimChargess.add(deviceSimChargeInfo);
});
deviceSimChargeService.saveBatch(deviceSimChargess);
return R.ok();
}
@Override
@ApiOperation("购买回调")
public R payNotice(DeviceSimDto.PayNotice payNotice) {
//查询设备流量卡充值表
List list = deviceSimChargeService.list(new LambdaQueryWrapper().eq(DeviceSimCharge::getOrderId, payNotice.getOrderId()));
if (!Emptys.check(list)) {
return R.ok();
}
//查询设备流量卡
JList deviceSimCharges = new JArrayList<>(list);
JMap deviceSimChargesJMaps = deviceSimCharges.toMap(DeviceSimCharge::getSimId).cover();
List deviceSims = listByIds(deviceSimCharges.getProperty(DeviceSimCharge::getSimId));
//循环处理
LocalDateTime now = LocalDateTime.now();
deviceSims.forEach(deviceSim -> {
DeviceSimCharge deviceSimCharge = deviceSimChargesJMaps.get(deviceSim.getId());
String newTimeout = deviceSimCharge.getPayType() == 100 ? DataTime.getStringAround(0, 0, deviceSimCharge.getSize(), 0, 0, 0)
: DataTime.getStringAround(deviceSimCharge.getSize(), 0, 0, 0, 0, 0);
long d = DataTime.diff(now, deviceSim.getTimeout(), "d");
if (d > 0) {
newTimeout = DataTime.getStringAround(0, 0, (int) d, 0, 0, 0, newTimeout);
}
deviceSim.setTimeout(DataTime.toLocal(newTimeout))
.setWaitHandle(true)
.setLastRenewalTime(now)
.setUpdateTime(now);
});
//修改设备流量卡信息
updateBatchById(deviceSims);
//修改设备流量卡充值
Integer status = SysDictUtils.getValue(EnumDeviceChargingHistoryStatus.Code.CODE.getCode(), EnumDeviceChargingHistoryStatus.N_2.getCode(), Integer.class);
deviceSimCharges.forEach(deviceSimCharge -> deviceSimCharge.setStatus(status).setUpdateTime(now));
deviceSimChargeService.updateBatchById(deviceSimCharges);
return R.ok();
}
@Override
@ApiOperation("查询过期条数")
public R deviceSimTimeoutCount(DeviceSimDto.DeviceSimTimeoutCount deviceSimTimeoutCount) {
String now = DataTime.getSring();
int day = SysDictUtils.getValue(EnumSimConfig.Code.CODE.getCode(), EnumSimConfig.N_200.getCode(), Integer.class);
String end1 = DataTime.getStringAround(0, 0, day, 0, 0, 0, now);
deviceSimTimeoutCount.setBegin1(now)
.setEnd1(end1)
.setEnd2(now);
DeviceSimDto.DeviceSimTimeoutCountVo deviceSimTimeoutCountVo = baseMapper.deviceSimTimeoutCount(deviceSimTimeoutCount);
return R.ok(deviceSimTimeoutCountVo);
}
@PostMapping("page")
@ApiOperation("分页查询")
public R> page(@RequestBody @Validated DeviceSimDto.Page page) {
Map simConfig = SysDictUtils.get(EnumSimConfig.Code.CODE.getCode());
Integer value = Integer.valueOf(simConfig.get(EnumSimConfig.N_200.getCode()).getValue());
String theTime = DataTime.getStringAround(0, 0, value, 0, 0, 0);
page.setThisTime(LocalDateTime.now()).setTheTime(DataTime.toLocal(theTime));
IPage iPage = baseMapper.page(toIPage(page.getPage()), page);
List records = iPage.getRecords();
if (Emptys.check(records)) {
String name = simConfig.get(EnumSimConfig.name.getCode()).getValue();
Integer money = Integer.valueOf(simConfig.get(EnumSimConfig.money.getCode()).getValue());
records.forEach(record -> {
//封装过期状态说明
DeviceSimDto.Vo sim = record.getSim();
if (Emptys.check(sim)) {
String timeoutStatus;
LocalDateTime timeout = sim.getTimeout();
long s = DataTime.diff(page.getThisTime(), timeout, "s");
if (s <= 0) {
timeoutStatus = "欠费(" + (~(s / 86400 - 1)) + "天)";
} else {
timeoutStatus = s <= value * 86400 ? "即将到期(" + s / 86400 + "天)" : "正常(" + s / 86400 + "天)";
}
record.getSim().setTimeoutStatus(timeoutStatus);
}
//封装计费标准
record.setChargingName(name).setChargingMoney(money);
});
}
return R.ok(toPageBean(iPage));
}
@PostMapping("pageByNotInit")
@ApiOperation("未初始化分页查询")
public R> pageByNotInit(@RequestBody DeviceSimDto.Page page) {
Map simConfig = SysDictUtils.get(EnumSimConfig.Code.CODE.getCode());
IPage iPage = baseMapper.page2(toIPage(page.getPage()), page);
List records = iPage.getRecords();
if (Emptys.check(records)) {
String name = simConfig.get(EnumSimConfig.name.getCode()).getValue();
Integer money = Integer.valueOf(simConfig.get(EnumSimConfig.money.getCode()).getValue());
records.forEach(record -> {
//封装计费标准
record.setChargingName(name).setChargingMoney(money);
});
}
return R.ok(toPageBean(iPage));
}
@PostMapping("pageCount")
@ApiOperation("分页数量查询")
public R pageCount(@RequestBody @Validated DeviceSimDto.PageCount pageCount) {
Map simConfig = SysDictUtils.get(EnumSimConfig.Code.CODE.getCode());
Integer value = Integer.valueOf(simConfig.get(EnumSimConfig.N_200.getCode()).getValue());
String theTime = DataTime.getStringAround(0, 0, value, 0, 0, 0);
//并行数据
DeviceSimDto.PageCountVo pageCountVo = new DeviceSimDto.PageCountVo();
ThreadPoolUtils.excPoll(DeviceThreadPoolConfig.DEVICE_COMMON_POLL, 6)
.execute(() -> {
//全部
DeviceSimDto.PageCount paramsObj = Beans.copy(DeviceSimDto.PageCount.class, pageCount);
int count = baseMapper.pageCount(paramsObj);
pageCountVo.setAllCount(count);
})
.execute(() -> {
//即将过期
DeviceSimDto.PageCount paramsObj = Beans.copy(DeviceSimDto.PageCount.class, pageCount)
.setChargingStatus(1)
.setThisTime(LocalDateTime.now())
.setTheTime(DataTime.toLocal(theTime));
int count = baseMapper.pageCount(paramsObj);
pageCountVo.setBeTimeoutCount(count);
})
.execute(() -> {
//已过期
DeviceSimDto.PageCount paramsObj = Beans.copy(DeviceSimDto.PageCount.class, pageCount)
.setChargingStatus(2)
.setThisTime(LocalDateTime.now())
.setTheTime(DataTime.toLocal(theTime));
int count = baseMapper.pageCount(paramsObj);
pageCountVo.setTimeoutCount(count);
})
.execute(() -> {
//已激活
DeviceSimDto.PageCount paramsObj = Beans.copy(DeviceSimDto.PageCount.class, pageCount)
.setIsActivate(true);
int count = baseMapper.pageCount(paramsObj);
pageCountVo.setIsActivate(count);
})
.execute(() -> {
//未激活
DeviceSimDto.PageCount paramsObj = Beans.copy(DeviceSimDto.PageCount.class, pageCount)
.setIsActivate(false);
int count = baseMapper.pageCount(paramsObj);
pageCountVo.setIsNotActivate(count);
})
.execute(() -> {
//未初始化
DeviceSimDto.PageCount paramsObj = Beans.copy(DeviceSimDto.PageCount.class, pageCount);
int count = baseMapper.pageCount2(paramsObj);
pageCountVo.setNotInitCount(count);
})
.end();
return R.ok(pageCountVo);
}
@SneakyThrows
@ApiOperation("导出流量卡数据")
@PostMapping("download")
public void download(@RequestBody DeviceSimDto.Download download) {
//生成excel
String name = YitIdHelper.nextId() + ".xlsx";
String path = fileConfig.getPath() + File.separator + name;
ExcelUtils.SheetAndData sheetAndData = ExcelUtils.create(path, UploadSim.class);
sheetAndData.sheet("流量卡数据", () -> {
//生成导出数据
List pageVos;
if (download.getIsNotInit()) {
pageVos = baseMapper.page2(download);
} else {
Map simConfig = SysDictUtils.get(EnumSimConfig.Code.CODE.getCode());
Integer value = Integer.valueOf(simConfig.get(EnumSimConfig.N_200.getCode()).getValue());
String theTime = DataTime.getStringAround(0, 0, value, 0, 0, 0);
download.setThisTime(LocalDateTime.now()).setTheTime(DataTime.toLocal(theTime));
pageVos = baseMapper.page(download);
}
List uploadSims = new ArrayList<>();
pageVos.forEach(pageVo -> {
UploadSim uploadSim = new UploadSim();
uploadSim.setSimId(pageVo.getSimIccid());
DeviceSimDto.Vo sim = pageVo.getSim();
if (sim != null) {
uploadSim.setType(sim.getType());
uploadSim.setActivateTime(Emptys.check(sim.getActivateTime()) ? DataTime.toString(sim.getActivateTime(), "yyyy-MM-dd") : null);
uploadSim.setTimeout(Emptys.check(sim.getTimeout()) ? DataTime.toString(sim.getTimeout(), "yyyy-MM-dd") : null);
uploadSim.setLastRenewalTime(Emptys.check(sim.getLastRenewalTime()) ? DataTime.toString(sim.getLastRenewalTime(), "yyyy-MM-dd") : null);
uploadSim.setBatchNo(sim.getBatchNo());
uploadSim.setIsTest(Emptys.check(sim.getIsTest()) && sim.getIsTest() ? "是" : "否");
}
uploadSims.add(uploadSim);
});
//修改批次号
String updateBatchNo = download.getUpdateBatchNo();
Boolean isUpdateBatchNo = download.getIsUpdateBatchNo();
if (Emptys.check(updateBatchNo) && Emptys.check(isUpdateBatchNo) && isUpdateBatchNo) {
LocalDateTime now = LocalDateTime.now();
List deviceSims = new ArrayList<>(uploadSims.size());
uploadSims.forEach(uploadSim -> {
DeviceSim deviceSim = new DeviceSim()
.setId(uploadSim.getSimId())
.setBatchNo(updateBatchNo)
.setWaitHandle(false)
.setUpdateTime(now);
deviceSims.add(deviceSim);
});
updateBatchById(deviceSims);
}
return uploadSims;
}).builder();
//下载文件
InputStream inputStream = IoUtils.inputStream(path).get();
response.setHeader("Content-Disposition", "attachment; filename=" + "sim_data.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();
}
@ApiOperation("导入流量卡号数据")
@PostMapping("uploadSim")
public R uploadSim(@RequestParam("file") MultipartFile file) {
ThreadPoolUtils.excPoll(DeviceThreadPoolConfig.DEVICE_COMMON_POLL, 1)
.execute(() -> {
try {
EasyExcel.read(file.getInputStream(), UploadSim.class, new UploadSimListener(this)).sheet().doRead();
} catch (IOException e) {
log.error("", e);
}
});
return R.ok();
}
@PostMapping("update")
@ApiOperation("修改流量卡信息")
public void update(@RequestBody @Validated DeviceSimDto.Update update) {
List ids = update.getId();
LocalDateTime now = LocalDateTime.now();
List deviceSims = new ArrayList<>(ids.size());
ids.forEach(id -> {
DeviceSim deviceSim = new DeviceSim()
.setId(id)
.setType(update.getType())
.setActivateTime(update.getActivateTime())
.setTimeout(update.getTimeout())
.setLastRenewalTime(update.getLastRenewalTime())
.setBatchNo(update.getBatchNo())
.setUpdateTime(now)
.setIsTest(update.getIsTest());
deviceSims.add(deviceSim);
});
updateBatchById(deviceSims);
}
@Slf4j
@RequiredArgsConstructor
public static class UploadSimListener implements ReadListener {
private final DeviceSimServiceImpl deviceSimService;
private JList sims = new JArrayList<>();
/**
* 这个每一条数据解析都会来调用
*
* @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}
* @param context
*/
@Override
public void invoke(UploadSim data, AnalysisContext context) {
sims.add(data);
}
/**
* 所有数据解析完成了 都会来调用
*
* @param context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
LocalDateTime now = LocalDateTime.now();
JList saveDeviceSims = new JArrayList<>();
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
sims.forEach(uploadSim -> {
DeviceSim deviceSim = new DeviceSim()
.setId(uploadSim.getSimId().trim().replace("\"", "").replace("'", ""))
.setType(uploadSim.getType())
.setActivateTime(Emptys.check(uploadSim.getActivateTime()) ? LocalDate.parse(uploadSim.getActivateTime(), df).atTime(0, 0, 0) : null)
.setTimeout(Emptys.check(uploadSim.getTimeout()) ? LocalDate.parse(uploadSim.getTimeout(), df).atTime(0, 0, 0) : null)
.setLastRenewalTime(Emptys.check(uploadSim.getLastRenewalTime()) ? LocalDate.parse(uploadSim.getLastRenewalTime(), df).atTime(0, 0, 0) : null)
.setCreateTime(now)
.setUpdateTime(now)
.setIsTest(Emptys.check(uploadSim.getIsTest()) && uploadSim.getIsTest().equals("是") ? true : false);
saveDeviceSims.add(deviceSim);
});
deviceSimService.saveOrUpdateBatch(saveDeviceSims);
}
}
@Data
public static class UploadSim {
@ColumnWidth(25)
@ExcelProperty(value = "流量卡号")
private String simId;
@ColumnWidth(25)
@ExcelProperty(value = "类型")
private String type;
@ColumnWidth(25)
@ExcelProperty(value = "批次号")
private String batchNo;
@ColumnWidth(50)
@ExcelProperty(value = "激活时间")
private String activateTime;
@ColumnWidth(50)
@ExcelProperty(value = "过期时间")
private String timeout;
@ColumnWidth(50)
@ExcelProperty(value = "最后续费时间")
private String lastRenewalTime;
@ColumnWidth(25)
@ExcelProperty(value = "是否测试卡")
private String isTest;
}
}