DeviceCreateIdsServiceImpl.java 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. package com.xy.service;
  2. import com.alibaba.excel.EasyExcel;
  3. import com.alibaba.excel.context.AnalysisContext;
  4. import com.alibaba.excel.read.listener.ReadListener;
  5. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  6. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  7. import com.baomidou.mybatisplus.core.metadata.IPage;
  8. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  9. import com.xy.annotation.Lock;
  10. import com.xy.collections.list.JArrayList;
  11. import com.xy.collections.list.JList;
  12. import com.xy.collections.map.JHashMap;
  13. import com.xy.collections.map.JMap;
  14. import com.xy.config.DeviceThreadPoolConfig;
  15. import com.xy.device.EnumDeviceQrCode;
  16. import com.xy.device.EnumDeviceType;
  17. import com.xy.dto.DeviceCreateIdsDto;
  18. import com.xy.dto.DeviceQualityDto;
  19. import com.xy.dto.MercDeviceQrConfigDto;
  20. import com.xy.dto.SysWorkUser.ListDto;
  21. import com.xy.dto.SysWorkUser.SysWorkVo;
  22. import com.xy.dto.be.MercDto;
  23. import com.xy.entity.DeviceCreateIds;
  24. import com.xy.entity.DeviceInfo;
  25. import com.xy.mapper.DeviceCreateIdsMapper;
  26. import com.xy.service.be.MercService;
  27. import com.xy.utils.*;
  28. import io.swagger.annotations.Api;
  29. import io.swagger.annotations.ApiOperation;
  30. import lombok.Data;
  31. import lombok.RequiredArgsConstructor;
  32. import lombok.SneakyThrows;
  33. import lombok.extern.slf4j.Slf4j;
  34. import org.springframework.stereotype.Service;
  35. import org.springframework.validation.annotation.Validated;
  36. import org.springframework.web.bind.annotation.PostMapping;
  37. import org.springframework.web.bind.annotation.RequestBody;
  38. import org.springframework.web.bind.annotation.RequestParam;
  39. import org.springframework.web.multipart.MultipartFile;
  40. import javax.servlet.http.HttpServletResponse;
  41. import java.io.IOException;
  42. import java.io.InputStream;
  43. import java.io.OutputStream;
  44. import java.time.LocalDate;
  45. import java.time.LocalDateTime;
  46. import java.util.ArrayList;
  47. import java.util.List;
  48. import static com.xy.utils.Beans.copy;
  49. import static com.xy.utils.PlusBeans.toIPage;
  50. import static com.xy.utils.PlusBeans.toPageBean;
  51. /**
  52. * <p>
  53. * 设备-机器ID号生成 服务实现类
  54. * </p>
  55. *
  56. * @author lijin
  57. * @since 2022-12-29
  58. */
  59. @Slf4j
  60. @Service
  61. @RequiredArgsConstructor
  62. @Api(tags = "设备-机器ID号生成")
  63. public class DeviceCreateIdsServiceImpl extends ServiceImpl<DeviceCreateIdsMapper, DeviceCreateIds> implements DeviceCreateIdsService {
  64. private final SysWorkUserService sysWorkUserService;
  65. private final MercDeviceQrConfigService mercDeviceQrConfigService;
  66. private final MercService mercService;
  67. private final DeviceInfoServiceImpl deviceInfoService;
  68. @SneakyThrows
  69. @PostMapping("save")
  70. @ApiOperation("添加")
  71. @Lock("device-create-ids-save")
  72. public R<JList<DeviceCreateIds>> save(@RequestBody @Validated DeviceCreateIdsDto.Save save) {
  73. LocalDate localDate = LocalDate.now();
  74. String year = String.valueOf(localDate.getYear());
  75. String month = String.valueOf(localDate.getMonthValue());
  76. String yearMonth = year.substring(2) + (month.length() == 1 ? "0" + month : month);
  77. String property = LambdaUtils.getProperty(DeviceCreateIds::getDeviceId);
  78. QueryWrapper<DeviceCreateIds> queryWrapper = new QueryWrapper<DeviceCreateIds>()
  79. .select(String.format("max(%s) as %s", StringTools.humpToLine(property), property))
  80. .eq(StringTools.humpToLine(LambdaUtils.getProperty(DeviceCreateIds::getIsCustom)), false);
  81. DeviceCreateIds deviceCreateIds = getOne(queryWrapper);
  82. JMap<Long, DeviceCreateIds> deviceCreateIdss = new JHashMap<>(save.getNum());
  83. Long loginId = AuthorizeUtils.getLoginId(Long.class);
  84. for (int i = 0; i < save.getNum(); i++) {
  85. String tail = null;
  86. if (deviceCreateIds != null) {
  87. String substring = String.valueOf(deviceCreateIds.getDeviceId()).substring(0, 4);
  88. if (substring.equals(yearMonth)) {
  89. tail = String.valueOf(deviceCreateIds.getDeviceId() + (i + 1)).substring(4);
  90. }
  91. }
  92. if (tail == null) {
  93. tail = String.valueOf((i + 1));
  94. int i0 = 6 - tail.length();
  95. for (int i1 = 0; i1 < i0; i1++) {
  96. tail = 0 + tail;
  97. }
  98. }
  99. Long deviceId = Long.valueOf(yearMonth + tail);
  100. DeviceCreateIds deviceCreateIdsInfo = copy(DeviceCreateIds.class, save)
  101. .setDeviceId(deviceId)
  102. .setCreateUserId(loginId)
  103. .setCreateTime(LocalDateTime.now());
  104. deviceCreateIdss.put(deviceId, deviceCreateIdsInfo);
  105. }
  106. //去重复
  107. weight(deviceCreateIdss, save.getNum());
  108. //添加
  109. JList<DeviceCreateIds> value = deviceCreateIdss.toList().value();
  110. JList<JList<DeviceCreateIds>> partition = value.partition(20);
  111. ThreadPoolUtils.Execute execute = ThreadPoolUtils.excPoll(DeviceThreadPoolConfig.DEVICE_COMMON_POLL, partition.size());
  112. partition.forEach(createIds -> execute.execute(() -> saveBatch(createIds)));
  113. execute.end();
  114. return R.ok(value);
  115. }
  116. @PostMapping("saveCustom")
  117. @ApiOperation("添加自定义机器号")
  118. @Lock("device-create-ids-save")
  119. public R saveCustom(@RequestBody @Validated DeviceCreateIdsDto.SaveCustom saveCustom) {
  120. DeviceCreateIds deviceCreateIds = getById(saveCustom.getDeviceId());
  121. if (deviceCreateIds != null) {
  122. return R.fail("机器号已存在");
  123. }
  124. DeviceCreateIds deviceCreateIdsInfo = copy(DeviceCreateIds.class, saveCustom)
  125. .setCreateUserId(AuthorizeUtils.getLoginId(Long.class))
  126. .setIsCustom(true)
  127. .setCreateTime(LocalDateTime.now());
  128. save(deviceCreateIdsInfo);
  129. return R.ok();
  130. }
  131. @PostMapping("page")
  132. @ApiOperation("分页查询")
  133. public R<PageBean<DeviceCreateIdsDto.Vo>> page(@RequestBody DeviceCreateIdsDto.Page page) {
  134. PageBean pageBean = page.getPage();
  135. LambdaQueryWrapper<DeviceCreateIds> lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(page, DeviceCreateIds.class)
  136. .ge(DeviceCreateIds::getCreateTime, page.getBeginCreateTime())
  137. .le(DeviceCreateIds::getCreateTime, page.getEndCreateTime())
  138. .ge(DeviceCreateIds::getBindTime, page.getBeginBindTime())
  139. .le(DeviceCreateIds::getBindTime, page.getEndBindTime())
  140. .build()
  141. .orderByDesc(!Emptys.check(pageBean.getOrders()), DeviceCreateIds::getCreateTime, DeviceCreateIds::getDeviceId);
  142. IPage<DeviceCreateIds> iPage = page(toIPage(pageBean), lambdaQueryWrapper);
  143. PageBean<DeviceCreateIdsDto.Vo> voPageBean = toPageBean(PlusBeans.copy(DeviceCreateIdsDto.Vo.class, iPage));
  144. List<DeviceCreateIdsDto.Vo> records = voPageBean.getRecords();
  145. JList<Long> createUserIds = new JArrayList<>(records).getProperty(DeviceCreateIdsDto.Vo::getCreateUserId);
  146. //查询创建人
  147. JMap<Long, SysWorkVo> sysWorkVoJMap;
  148. List<SysWorkVo> sysWorkVos = sysWorkUserService.list(new ListDto().setId(createUserIds)).getData();
  149. if (Emptys.check(sysWorkVos)) {
  150. sysWorkVoJMap = new JArrayList<>(sysWorkVos).toMap(SysWorkVo::getId).cover();
  151. } else {
  152. sysWorkVoJMap = new JHashMap<>();
  153. }
  154. //查询绑定商户
  155. JMap<Long, MercDto.Vo> mercsJMaps;
  156. JList<Long> mercIds = new JArrayList<>(records).filter().isNotNull(DeviceCreateIdsDto.Vo::getDeviceQrMercId).gt(DeviceCreateIdsDto.Vo::getDeviceQrMercId, 0).list().getProperty(DeviceCreateIdsDto.Vo::getDeviceQrMercId);
  157. if (Emptys.check(mercIds)) {
  158. List<MercDto.Vo> mercs = mercService.list(new MercDto.SelectList().setMercIds(mercIds)).getData();
  159. mercsJMaps = new JArrayList<>(mercs).toMap(MercDto.Vo::getId).cover();
  160. } else {
  161. mercsJMaps = new JHashMap<>();
  162. }
  163. records.forEach(vo -> {
  164. if (Emptys.check(sysWorkVoJMap)) {
  165. if (Emptys.check(vo.getCreateUserId())) {
  166. SysWorkVo sysWorkVo = sysWorkVoJMap.get(vo.getCreateUserId());
  167. if (sysWorkVo != null) {
  168. vo.setCreateUserName(sysWorkVo.getAccount());
  169. }
  170. }
  171. }
  172. if (Emptys.check(mercsJMaps)) {
  173. if (Emptys.check(vo.getDeviceQrMercId())) {
  174. MercDto.Vo mercVo = mercsJMaps.get(vo.getDeviceQrMercId());
  175. if (mercVo != null) {
  176. vo.setDeviceQrMercName(mercVo.getName());
  177. }
  178. }
  179. }
  180. });
  181. return R.ok(voPageBean);
  182. }
  183. @Override
  184. @ApiOperation("修改")
  185. public R update(DeviceCreateIdsDto.Update update) {
  186. DeviceCreateIds deviceCreateIds = copy(DeviceCreateIds.class, update);
  187. updateById(deviceCreateIds);
  188. return R.ok();
  189. }
  190. @Override
  191. @ApiOperation("批量修改")
  192. public R updateBatch(DeviceCreateIdsDto.UpdateBatch updateBatch) {
  193. List<Long> deviceIds = updateBatch.getDeviceIds();
  194. List<DeviceCreateIds> deviceCreateIdss = new ArrayList<>(deviceIds.size());
  195. deviceIds.forEach(deviceId -> {
  196. DeviceCreateIds deviceCreateIds = copy(DeviceCreateIds.class, updateBatch).setDeviceId(deviceId);
  197. deviceCreateIdss.add(deviceCreateIds);
  198. });
  199. updateBatchById(deviceCreateIdss);
  200. return R.ok();
  201. }
  202. @PostMapping("getQrCode")
  203. @ApiOperation("获取二维码")
  204. public R<List<String>> getQrCode(@RequestBody @Validated DeviceQualityDto.Qrcode qrcode) {
  205. //默认二维码
  206. String qrUrl = SysDictUtils.getValue(EnumDeviceQrCode.Code.CODE.getCode(), EnumDeviceQrCode.URL.getCode(), String.class);
  207. //查询商户特有二维码地址
  208. DeviceInfo deviceInfo = deviceInfoService.getById(qrcode.getDeviceId());
  209. if (Emptys.check(deviceInfo.getMercId())) {
  210. MercDeviceQrConfigDto.Vo mercDeviceQrConfig = mercDeviceQrConfigService.getQrUrl(new MercDeviceQrConfigDto.GetQrUrl().setMercId(deviceInfo.getMercId())).getData();
  211. if (Emptys.check(mercDeviceQrConfig)) {
  212. qrUrl = mercDeviceQrConfig.getQrUrl() + "?deviceId=";
  213. }
  214. }
  215. //验证是否是双门柜
  216. int deviceType = SysDictUtils.getValue(EnumDeviceType.Code.CODE.getCode(), EnumDeviceType.N_2.getCode(), Integer.class);
  217. String deviceId = qrcode.getDeviceId().toString();
  218. JList<String> deviceIds = new JArrayList<String>()
  219. .set(qrUrl + deviceId);
  220. JList<String> deviceIdInfos = new JArrayList<String>()
  221. .set(deviceId);
  222. DeviceCreateIds deviceCreateIds = getById(qrcode.getDeviceId());
  223. if (deviceCreateIds.getDeviceType() == deviceType) {
  224. deviceIds.clear();
  225. deviceIdInfos.clear();
  226. for (int i = 0; i < 2; i++) {
  227. deviceIds.add(String.format("%s%s&door=%d", qrUrl, deviceId, i));
  228. deviceIdInfos.add(String.format("%s-%d", deviceId, i));
  229. }
  230. }
  231. List<String> base64s = QRCodeUtils.create(deviceIds, 400, 400, "back1.png", deviceIdInfos).base64();
  232. return R.ok(base64s);
  233. }
  234. @PostMapping("exportQrCode")
  235. @ApiOperation("导出二维码")
  236. public void exportQrCode(@RequestBody @Validated DeviceCreateIdsDto.ExportQrCode exportQrCode) {
  237. String url = SysDictUtils.getValue(EnumDeviceQrCode.Code.CODE.getCode(), EnumDeviceQrCode.URL.getCode(), String.class);
  238. int deviceType = SysDictUtils.getValue(EnumDeviceType.Code.CODE.getCode(), EnumDeviceType.N_2.getCode(), Integer.class);
  239. LocalDateTime now = LocalDateTime.now();
  240. JList<String> deviceIds = new JArrayList<>();
  241. List<String> deviceIdInfos = new ArrayList<>();
  242. List<DeviceCreateIds> updateDeviceCreateIds = new ArrayList<>();
  243. JList<DeviceCreateIds> deviceCreateIdss = new JArrayList<>(listByIds(exportQrCode.getDeviceIds()));
  244. List<DeviceInfo> deviceInfos = deviceInfoService.listByIds(exportQrCode.getDeviceIds());
  245. JMap<Long, DeviceInfo> deviceInfoJMaps = new JArrayList<>(deviceInfos).toMap(DeviceInfo::getDeviceId).cover();
  246. //循环
  247. deviceCreateIdss.forEach(deviceCreateIds -> {
  248. String qrUrl = url;
  249. //查询商户特有二维码地址
  250. DeviceInfo deviceInfo = deviceInfoJMaps.get(deviceCreateIds.getDeviceId());
  251. if (Emptys.check(deviceInfo.getMercId())) {
  252. MercDeviceQrConfigDto.Vo mercDeviceQrConfig = mercDeviceQrConfigService.getQrUrl(new MercDeviceQrConfigDto.GetQrUrl().setMercId(deviceInfo.getMercId())).getData();
  253. if (Emptys.check(mercDeviceQrConfig)) {
  254. qrUrl = mercDeviceQrConfig.getQrUrl() + "?deviceId=";
  255. }
  256. }
  257. //验证是否是双门柜
  258. if (deviceCreateIds.getDeviceType() == deviceType) {
  259. for (int i = 0; i < 2; i++) {
  260. deviceIds.add(String.format("%s%s&door=%d", qrUrl, deviceCreateIds.getDeviceId(), i));
  261. deviceIdInfos.add(String.format("%s-%d", deviceCreateIds.getDeviceId(), i));
  262. }
  263. } else {
  264. deviceIds.add(qrUrl + deviceCreateIds.getDeviceId());
  265. deviceIdInfos.add(String.valueOf(deviceCreateIds.getDeviceId()));
  266. }
  267. updateDeviceCreateIds.add(deviceCreateIds.setLastExportQrCodeTime(now));
  268. });
  269. updateBatchById(updateDeviceCreateIds);
  270. QRCodeUtils.create(deviceIds, 400, 400, "back1.png", deviceIdInfos).download(deviceIdInfos);
  271. }
  272. @SneakyThrows
  273. @ApiOperation("下载自定义设备id模板")
  274. @PostMapping("downloadIdTemplet")
  275. public void downloadIdTemplet(HttpServletResponse response) {
  276. InputStream inputStream = IoUtils.inputStream("id_templet.xlsx").get();
  277. response.setHeader("Content-Disposition", "attachment; filename=" + "id_templet.xlsx");
  278. response.setContentType("application/xlsx");
  279. byte[] buffer = new byte[1024];
  280. int bytesRead;
  281. OutputStream outputStream = response.getOutputStream();
  282. while ((bytesRead = inputStream.read(buffer)) != -1) {
  283. outputStream.write(buffer, 0, bytesRead);
  284. }
  285. inputStream.close();
  286. outputStream.close();
  287. }
  288. @ApiOperation("批量添加自定义机器号")
  289. @PostMapping("uploadSaveCustom")
  290. public R uploadSaveCustom(@RequestParam("file") MultipartFile file) {
  291. ThreadPoolUtils.excPoll(DeviceThreadPoolConfig.DEVICE_COMMON_POLL, 1)
  292. .execute(() -> {
  293. try {
  294. EasyExcel.read(file.getInputStream(), UploadSaveCustom.class, new UploadSaveCustomListener(AuthorizeUtils.getLoginId(Long.class), this)).sheet().doRead();
  295. } catch (IOException e) {
  296. log.error("", e);
  297. }
  298. });
  299. return R.ok();
  300. }
  301. private void weight(JMap<Long, DeviceCreateIds> deviceCreateIdss, int num) {
  302. List<DeviceCreateIds> list = list(new LambdaQueryWrapper<DeviceCreateIds>().in(DeviceCreateIds::getDeviceId, deviceCreateIdss.toList().key()));
  303. if (Emptys.check(list)) {
  304. list.forEach(deviceCreateIdsInfo -> {
  305. //添加
  306. DeviceCreateIds deviceCreateIdsOld = deviceCreateIdss.get(deviceCreateIdsInfo.getDeviceId());
  307. Long deviceId = deviceCreateIdsOld.getDeviceId() + num;
  308. deviceCreateIdss.put(deviceId, copy(DeviceCreateIds.class, deviceCreateIdsOld).setDeviceId(deviceId));
  309. //删除
  310. deviceCreateIdss.remove(deviceCreateIdsInfo.getDeviceId());
  311. });
  312. weight(deviceCreateIdss, num);
  313. }
  314. }
  315. @Slf4j
  316. @RequiredArgsConstructor
  317. public static class UploadSaveCustomListener implements ReadListener<UploadSaveCustom> {
  318. private final Long loginId;
  319. private final DeviceCreateIdsServiceImpl deviceCreateIdsService;
  320. private JMap<Long, UploadSaveCustom> deviceIds = new JHashMap<>();
  321. /**
  322. * 这个每一条数据解析都会来调用
  323. *
  324. * @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}
  325. * @param context
  326. */
  327. @Override
  328. public void invoke(UploadSaveCustom data, AnalysisContext context) {
  329. String deviceType = data.getDeviceType();
  330. if (deviceType == null) {
  331. return;
  332. }
  333. Integer deviceTypeValue = deviceType.equals("动态视觉柜(单门)") ? 1
  334. : deviceType.equals("动态视觉柜(双门)") ? 2
  335. : deviceType.equals("重力柜(单门)") ? 3
  336. : deviceType.equals("重力柜(双门)") ? 4
  337. : deviceType.equals("支付宝视动态觉柜") ? 5
  338. : null;
  339. if (deviceTypeValue == null) {
  340. return;
  341. }
  342. if (!Emptys.check(data.getDevicePc())) {
  343. return;
  344. }
  345. data.setDeviceTypeValue(deviceTypeValue);
  346. deviceIds.put(data.getDeviceId(), data);
  347. }
  348. /**
  349. * 所有数据解析完成了 都会来调用
  350. *
  351. * @param context
  352. */
  353. @Override
  354. public void doAfterAllAnalysed(AnalysisContext context) {
  355. List<DeviceCreateIds> list = deviceCreateIdsService.list(new LambdaQueryWrapper<DeviceCreateIds>().in(DeviceCreateIds::getDeviceId, deviceIds.toList().key()));
  356. if (Emptys.check(list)) {
  357. list.forEach(deviceCreateIds -> {
  358. deviceIds.remove(deviceCreateIds.getDeviceId());
  359. log.info("重复的设备号:{}", deviceCreateIds.getDeviceId());
  360. });
  361. }
  362. if (Emptys.check(deviceIds)) {
  363. LocalDateTime now = LocalDateTime.now();
  364. List<DeviceCreateIds> saves = new ArrayList<>(deviceIds.size());
  365. deviceIds.forEach((deviceId, uploadSaveCustom) -> {
  366. DeviceCreateIds deviceCreateIdsInfo = new DeviceCreateIds()
  367. .setDeviceId(deviceId)
  368. .setDeviceType(uploadSaveCustom.getDeviceTypeValue())
  369. .setCreatePc(uploadSaveCustom.getDevicePc())
  370. .setCreateUserId(loginId)
  371. .setIsCustom(true)
  372. .setCreateTime(now);
  373. saves.add(deviceCreateIdsInfo);
  374. });
  375. deviceCreateIdsService.saveBatch(saves);
  376. log.info("批量添加自定义机器号完成,共{}条", saves.size());
  377. }
  378. }
  379. }
  380. @Data
  381. public static class UploadSaveCustom {
  382. /**
  383. * 设备id
  384. */
  385. private Long deviceId;
  386. /**
  387. * 设备类型
  388. */
  389. private String deviceType;
  390. /**
  391. * 批次号
  392. */
  393. private String devicePc;
  394. /**
  395. * 设备类型值
  396. */
  397. private Integer deviceTypeValue;
  398. }
  399. }