DeviceSimServiceImpl.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. package com.xy.service;
  2. import com.alibaba.excel.EasyExcel;
  3. import com.alibaba.excel.annotation.ExcelProperty;
  4. import com.alibaba.excel.annotation.write.style.ColumnWidth;
  5. import com.alibaba.excel.context.AnalysisContext;
  6. import com.alibaba.excel.read.listener.ReadListener;
  7. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  8. import com.baomidou.mybatisplus.core.metadata.IPage;
  9. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  10. import com.github.yitter.idgen.YitIdHelper;
  11. import com.xy.collections.list.JArrayList;
  12. import com.xy.collections.list.JList;
  13. import com.xy.collections.map.JMap;
  14. import com.xy.config.DeviceThreadPoolConfig;
  15. import com.xy.config.FileConfig;
  16. import com.xy.device.EnumSimConfig;
  17. import com.xy.dto.DeviceSimDto;
  18. import com.xy.entity.DeviceSim;
  19. import com.xy.entity.DeviceSimCharge;
  20. import com.xy.entity.SysDictRedis;
  21. import com.xy.mapper.DeviceSimMapper;
  22. import com.xy.util.ExcelUtils;
  23. import com.xy.utils.*;
  24. import io.swagger.annotations.Api;
  25. import io.swagger.annotations.ApiOperation;
  26. import lombok.AllArgsConstructor;
  27. import lombok.Data;
  28. import lombok.RequiredArgsConstructor;
  29. import lombok.SneakyThrows;
  30. import lombok.extern.slf4j.Slf4j;
  31. import org.springframework.stereotype.Service;
  32. import org.springframework.validation.annotation.Validated;
  33. import org.springframework.web.bind.annotation.PostMapping;
  34. import org.springframework.web.bind.annotation.RequestBody;
  35. import org.springframework.web.bind.annotation.RequestParam;
  36. import org.springframework.web.multipart.MultipartFile;
  37. import javax.servlet.http.HttpServletResponse;
  38. import java.io.File;
  39. import java.io.IOException;
  40. import java.io.InputStream;
  41. import java.io.OutputStream;
  42. import java.time.LocalDateTime;
  43. import java.util.ArrayList;
  44. import java.util.List;
  45. import java.util.Map;
  46. import static com.xy.utils.PlusBeans.toIPage;
  47. import static com.xy.utils.PlusBeans.toPageBean;
  48. /**
  49. * <p>
  50. * 设备流量卡 服务实现类
  51. * </p>
  52. *
  53. * @author lijin
  54. * @since 2023-10-16
  55. */
  56. @Service
  57. @AllArgsConstructor
  58. @Api(tags = "设备流量卡")
  59. public class DeviceSimServiceImpl extends ServiceImpl<DeviceSimMapper, DeviceSim> implements DeviceSimService {
  60. private DeviceSimChargeServiceImpl deviceSimChargeService;
  61. private HttpServletResponse response;
  62. private FileConfig fileConfig;
  63. @Override
  64. @ApiOperation("购买")
  65. public R pay(DeviceSimDto.Pay pay) {
  66. LocalDateTime now = LocalDateTime.now();
  67. List<DeviceSimDto.Pay.DeviceSimCharge> deviceSimCharges = pay.getDeviceSimCharges();
  68. List<DeviceSimCharge> deviceSimChargess = new ArrayList<>(deviceSimCharges.size());
  69. deviceSimCharges.forEach(deviceSimCharge -> {
  70. DeviceSimCharge deviceSimChargeInfo = new DeviceSimCharge()
  71. .setId(YitIdHelper.nextId())
  72. .setOrderId(pay.getOrderId())
  73. .setSimId(deviceSimCharge.getSimId())
  74. .setMercId(pay.getMercId())
  75. .setMoney(deviceSimCharge.getMoney())
  76. .setSize(deviceSimCharge.getSize())
  77. .setPayType(pay.getPayType())
  78. .setNote(pay.getNote())
  79. .setCreateTime(now)
  80. .setUpdateTime(now);
  81. deviceSimChargess.add(deviceSimChargeInfo);
  82. });
  83. deviceSimChargeService.saveBatch(deviceSimChargess);
  84. return R.ok();
  85. }
  86. @Override
  87. @ApiOperation("购买回调")
  88. public R payNotice(DeviceSimDto.PayNotice payNotice) {
  89. //查询设备流量卡充值表
  90. List<DeviceSimCharge> list = deviceSimChargeService.list(new LambdaQueryWrapper<DeviceSimCharge>().eq(DeviceSimCharge::getOrderId, payNotice.getOrderId()));
  91. if (!Emptys.check(list)) {
  92. return R.ok();
  93. }
  94. //查询设备流量卡
  95. JList<DeviceSimCharge> deviceSimCharges = new JArrayList<>(list);
  96. JMap<String, DeviceSimCharge> deviceSimChargesJMaps = deviceSimCharges.toMap(DeviceSimCharge::getSimId).cover();
  97. List<DeviceSim> deviceSims = listByIds(deviceSimCharges.getProperty(DeviceSimCharge::getSimId));
  98. //循环处理
  99. LocalDateTime now = LocalDateTime.now();
  100. deviceSims.forEach(deviceSim -> {
  101. DeviceSimCharge deviceSimCharge = deviceSimChargesJMaps.get(deviceSim.getId());
  102. String newTimeout = deviceSimCharge.getPayType() == 100 ? DataTime.getStringAround(0, 0, deviceSimCharge.getSize(), 0, 0, 0)
  103. : DataTime.getStringAround(deviceSimCharge.getSize(), 0, 0, 0, 0, 0);
  104. long d = DataTime.diff(now, deviceSim.getTimeout(), "d");
  105. if (d > 0) {
  106. newTimeout = DataTime.getStringAround(0, 0, (int) d, 0, 0, 0, newTimeout);
  107. }
  108. deviceSim.setTimeout(DataTime.toLocal(newTimeout))
  109. .setLastRenewalTime(now)
  110. .setUpdateTime(now);
  111. });
  112. updateBatchById(deviceSims);
  113. return R.ok();
  114. }
  115. @PostMapping("page")
  116. @ApiOperation("分页查询")
  117. public R<PageBean<DeviceSimDto.PageVo>> page(@RequestBody @Validated DeviceSimDto.Page page) {
  118. Map<String, SysDictRedis> simConfig = SysDictUtils.get(EnumSimConfig.Code.CODE.getCode());
  119. Integer value = Integer.valueOf(simConfig.get(EnumSimConfig.N_200.getCode()).getValue());
  120. String theTime = DataTime.getStringAround(0, 0, value, 0, 0, 0);
  121. page.setThisTime(LocalDateTime.now()).setTheTime(DataTime.toLocal(theTime));
  122. IPage<DeviceSimDto.PageVo> iPage = baseMapper.page(toIPage(page.getPage()), page);
  123. List<DeviceSimDto.PageVo> records = iPage.getRecords();
  124. if (Emptys.check(records)) {
  125. String name = simConfig.get(EnumSimConfig.name.getCode()).getValue();
  126. Integer money = Integer.valueOf(simConfig.get(EnumSimConfig.money.getCode()).getValue());
  127. records.forEach(record -> {
  128. //封装过期状态说明
  129. DeviceSimDto.Vo sim = record.getSim();
  130. if (Emptys.check(sim)) {
  131. String timeoutStatus;
  132. LocalDateTime timeout = sim.getTimeout();
  133. long s = DataTime.diff(page.getThisTime(), timeout, "s");
  134. if (s <= 0) {
  135. timeoutStatus = "欠费(" + (~(s / 86400 - 1)) + "天)";
  136. } else {
  137. timeoutStatus = s <= value * 86400 ? "即将到期(" + s / 86400 + "天)" : "正常(" + s / 86400 + "天)";
  138. }
  139. record.getSim().setTimeoutStatus(timeoutStatus);
  140. }
  141. //封装计费标准
  142. record.setChargingName(name).setChargingMoney(money);
  143. });
  144. }
  145. return R.ok(toPageBean(iPage));
  146. }
  147. @PostMapping("pageCount")
  148. @ApiOperation("分页数量查询")
  149. public R<DeviceSimDto.PageCountVo> pageCount(@RequestBody @Validated DeviceSimDto.PageCount pageCount) {
  150. Map<String, SysDictRedis> simConfig = SysDictUtils.get(EnumSimConfig.Code.CODE.getCode());
  151. Integer value = Integer.valueOf(simConfig.get(EnumSimConfig.N_200.getCode()).getValue());
  152. String theTime = DataTime.getStringAround(0, 0, value, 0, 0, 0);
  153. //并行数据
  154. DeviceSimDto.PageCountVo pageCountVo = new DeviceSimDto.PageCountVo();
  155. ThreadPoolUtils.excPoll(DeviceThreadPoolConfig.DEVICE_COMMON_POLL, 4)
  156. .execute(() -> {
  157. //即将过期
  158. DeviceSimDto.PageCount paramsObj = Beans.copy(DeviceSimDto.PageCount.class, pageCount)
  159. .setChargingStatus(1)
  160. .setThisTime(LocalDateTime.now())
  161. .setTheTime(DataTime.toLocal(theTime));
  162. int count = baseMapper.pageCount(paramsObj);
  163. pageCountVo.setBeTimeoutCount(count);
  164. })
  165. .execute(() -> {
  166. //已过期
  167. DeviceSimDto.PageCount paramsObj = Beans.copy(DeviceSimDto.PageCount.class, pageCount)
  168. .setChargingStatus(2)
  169. .setThisTime(LocalDateTime.now())
  170. .setTheTime(DataTime.toLocal(theTime));
  171. int count = baseMapper.pageCount(paramsObj);
  172. pageCountVo.setTimeoutCount(count);
  173. })
  174. .execute(() -> {
  175. //已激活
  176. DeviceSimDto.PageCount paramsObj = Beans.copy(DeviceSimDto.PageCount.class, pageCount)
  177. .setIsActivate(true);
  178. int count = baseMapper.pageCount(paramsObj);
  179. pageCountVo.setIsActivate(count);
  180. })
  181. .execute(() -> {
  182. //未激活
  183. DeviceSimDto.PageCount paramsObj = Beans.copy(DeviceSimDto.PageCount.class, pageCount)
  184. .setIsActivate(false);
  185. int count = baseMapper.pageCount(paramsObj);
  186. pageCountVo.setIsNotActivate(count);
  187. })
  188. .end();
  189. return R.ok(pageCountVo);
  190. }
  191. @SneakyThrows
  192. @ApiOperation("导出流量卡数据")
  193. @PostMapping("download")
  194. public void download(@RequestBody DeviceSimDto.Page page) {
  195. //生成excel
  196. String name = YitIdHelper.nextId() + ".xlsx";
  197. String path = fileConfig.getPath() + File.separator + name;
  198. ExcelUtils.SheetAndData<UploadSim> sheetAndData = ExcelUtils.create(path, UploadSim.class);
  199. sheetAndData.sheet("流量卡数据", () -> {
  200. Map<String, SysDictRedis> simConfig = SysDictUtils.get(EnumSimConfig.Code.CODE.getCode());
  201. Integer value = Integer.valueOf(simConfig.get(EnumSimConfig.N_200.getCode()).getValue());
  202. String theTime = DataTime.getStringAround(0, 0, value, 0, 0, 0);
  203. page.setThisTime(LocalDateTime.now()).setTheTime(DataTime.toLocal(theTime));
  204. List<DeviceSimDto.PageVo> pageVos = baseMapper.page(page);
  205. List<UploadSim> uploadSims = new ArrayList<>();
  206. pageVos.forEach(pageVo -> {
  207. UploadSim uploadSim = new UploadSim();
  208. uploadSim.setSimId(pageVo.getSimIccid());
  209. DeviceSimDto.Vo sim = pageVo.getSim();
  210. if (sim != null) {
  211. uploadSim.setType(sim.getType());
  212. uploadSim.setActivateTime(DataTime.toString(sim.getActivateTime()));
  213. uploadSim.setTimeout(DataTime.toString(sim.getTimeout()));
  214. }
  215. uploadSims.add(uploadSim);
  216. });
  217. return uploadSims;
  218. }).builder();
  219. //下载文件
  220. InputStream inputStream = IoUtils.inputStream(path).get();
  221. response.setHeader("Content-Disposition", "attachment; filename=" + "sim_data.xlsx");
  222. response.setContentType("application/xlsx");
  223. byte[] buffer = new byte[1024];
  224. int bytesRead;
  225. OutputStream outputStream = response.getOutputStream();
  226. while ((bytesRead = inputStream.read(buffer)) != -1) {
  227. outputStream.write(buffer, 0, bytesRead);
  228. }
  229. inputStream.close();
  230. outputStream.close();
  231. //删除文件
  232. new File(path).delete();
  233. }
  234. @ApiOperation("导入流量卡号数据")
  235. @PostMapping("uploadSim")
  236. public R uploadSim(@RequestParam("file") MultipartFile file) {
  237. ThreadPoolUtils.excPoll(DeviceThreadPoolConfig.DEVICE_COMMON_POLL, 1)
  238. .execute(() -> {
  239. try {
  240. EasyExcel.read(file.getInputStream(), UploadSim.class, new UploadSimListener(this)).sheet().doRead();
  241. } catch (IOException e) {
  242. log.error("", e);
  243. }
  244. });
  245. return R.ok();
  246. }
  247. @Slf4j
  248. @RequiredArgsConstructor
  249. public static class UploadSimListener implements ReadListener<UploadSim> {
  250. private final DeviceSimServiceImpl deviceSimService;
  251. private JList<UploadSim> sims = new JArrayList<>();
  252. /**
  253. * 这个每一条数据解析都会来调用
  254. *
  255. * @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}
  256. * @param context
  257. */
  258. @Override
  259. public void invoke(UploadSim data, AnalysisContext context) {
  260. sims.add(data);
  261. }
  262. /**
  263. * 所有数据解析完成了 都会来调用
  264. *
  265. * @param context
  266. */
  267. @Override
  268. public void doAfterAllAnalysed(AnalysisContext context) {
  269. LocalDateTime now = LocalDateTime.now();
  270. JList<DeviceSim> saveDeviceSims = new JArrayList<>();
  271. sims.forEach(uploadSim -> {
  272. DeviceSim deviceSim = new DeviceSim()
  273. .setId(uploadSim.getSimId().trim().replace("\"", "").replace("'", ""))
  274. .setType(uploadSim.getType())
  275. .setActivateTime(DataTime.toLocal(uploadSim.getActivateTime()))
  276. .setTimeout(DataTime.toLocal(uploadSim.getTimeout()))
  277. .setCreateTime(now)
  278. .setUpdateTime(now);
  279. deviceSim.setLastRenewalTime(deviceSim.getActivateTime());
  280. saveDeviceSims.add(deviceSim);
  281. });
  282. deviceSimService.saveOrUpdateBatch(saveDeviceSims);
  283. }
  284. }
  285. @Data
  286. public static class UploadSim {
  287. @ColumnWidth(25)
  288. @ExcelProperty(value = "流量卡号")
  289. private String simId;
  290. @ColumnWidth(25)
  291. @ExcelProperty(value = "类型")
  292. private String type;
  293. @ColumnWidth(50)
  294. @ExcelProperty(value = "激活时间")
  295. private String activateTime;
  296. @ColumnWidth(50)
  297. @ExcelProperty(value = "过期时间")
  298. private String timeout;
  299. }
  300. }