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