MercMiniDeviceController.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. package com.xy.controller;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.util.StrUtil;
  4. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  5. import com.xy.annotate.RestMappingController;
  6. import com.xy.device.EnumDeviceActiveStatus;
  7. import com.xy.device.EnumDeviceFreezeStatus;
  8. import com.xy.device.EnumDeviceType;
  9. import com.xy.dto.DeviceBluetoothAuthDto;
  10. import com.xy.dto.DeviceInfoDto;
  11. import com.xy.dto.DeviceStatusDto;
  12. import com.xy.dto.MercMiniDeviceDto;
  13. import com.xy.dto.be.MercDto;
  14. import com.xy.dto.common.MercLineDto;
  15. import com.xy.dto.common.MercPlaceDto;
  16. import com.xy.dto.mini.MiniMercRegionDto;
  17. import com.xy.entity.DeviceBluetoothAuth;
  18. import com.xy.entity.DeviceInfo;
  19. import com.xy.entity.DeviceSysinfo;
  20. import com.xy.entity.DeviceTempRecords;
  21. import com.xy.enums.MercStatus;
  22. import com.xy.service.DeviceBluetoothAuthServiceImpl;
  23. import com.xy.service.DeviceInfoServiceImpl;
  24. import com.xy.service.DeviceSysinfoServiceImpl;
  25. import com.xy.service.DeviceTempRecordsServiceImpl;
  26. import com.xy.service.be.MercFeignService;
  27. import com.xy.service.common.MercLineService;
  28. import com.xy.service.common.MercPlaceService;
  29. import com.xy.service.factory.device.DeviceFactory;
  30. import com.xy.utils.*;
  31. import com.xy.utils.enums.DeviceActiveStateEnum;
  32. import com.xy.utils.enums.DeviceAuthCodeUseStatus;
  33. import com.xy.utils.enums.DeviceLockState;
  34. import com.xy.utils.enums.DeviceNetSateType;
  35. import io.swagger.annotations.Api;
  36. import io.swagger.annotations.ApiOperation;
  37. import lombok.AllArgsConstructor;
  38. import org.springframework.transaction.annotation.Transactional;
  39. import org.springframework.validation.annotation.Validated;
  40. import org.springframework.web.bind.annotation.PostMapping;
  41. import org.springframework.web.bind.annotation.RequestBody;
  42. import javax.validation.Valid;
  43. import java.time.LocalDateTime;
  44. import java.util.List;
  45. import java.util.Map;
  46. import java.util.Objects;
  47. import java.util.stream.Collectors;
  48. import static com.xy.utils.Beans.copy;
  49. /**
  50. * <p>
  51. * 小程序-设备
  52. * </p>
  53. *
  54. * @author hechunping
  55. * @since 2023/3/4
  56. */
  57. @RestMappingController("merc-mini/device")
  58. @AllArgsConstructor
  59. @Api(tags = "小程序-设备")
  60. public class MercMiniDeviceController {
  61. private final MercFeignService mercFeignService;
  62. private final DeviceInfoServiceImpl deviceInfoService;
  63. private final DeviceSysinfoServiceImpl deviceSysinfoService;
  64. private final MercPlaceService mercPlaceService;
  65. private final MercLineService mercLineService;
  66. private final DeviceBluetoothAuthServiceImpl deviceBluetoothAuthService;
  67. private final DeviceTempRecordsServiceImpl deviceTempRecordsService;
  68. @ApiOperation("商户设备首页统计")
  69. @PostMapping("mercHomeStatistical")
  70. public R<DeviceInfoDto.MercHomeStatisticalVO> mercHomeStatistical(@RequestBody @Valid DeviceInfoDto.MercHomeQueryDTO dto) {
  71. dto.setMercId(MercAuthUtils.getMercId());
  72. dto.setMyDeviceIds(getMyDevices());
  73. return deviceInfoService.mercHomeStatistical(dto);
  74. }
  75. @ApiOperation("设备列表-Id&Name")
  76. @PostMapping("listOfIdName")
  77. public R listOfIdName() {
  78. DeviceInfoDto.ListCommon listCommonDto = new DeviceInfoDto.ListCommon();
  79. DeviceInfoDto.Vo voDto = new DeviceInfoDto.Vo();
  80. voDto.setActiveState(Integer.valueOf(DeviceActiveStateEnum.TRUE.getCode()))
  81. .setMercId(MercAuthUtils.getMercId());
  82. listCommonDto.setVo(voDto);
  83. List<MercMiniDeviceDto.ListOfIdNameVo> copy = copy(MercMiniDeviceDto.ListOfIdNameVo.class, deviceInfoService.listCommon(listCommonDto).getData());
  84. return R.ok(copy);
  85. }
  86. @PostMapping("searchPage")
  87. @ApiOperation("小程序商户设备搜索")
  88. public R<PageBean<DeviceInfoDto.MerHomeSearchVO>> mercDeviceSearchPage(@RequestBody DeviceInfoDto.Page page) {
  89. page.setMercId(MercAuthUtils.getMercId());
  90. page.setMyDeviceIds(getMyDevices());
  91. return deviceInfoService.mercDeviceSearchPage(page);
  92. }
  93. @ApiOperation("小程序商户设备详情-设备信息")
  94. @PostMapping("detail")
  95. R<DeviceInfoDto.Vo> detail(@RequestBody DeviceInfoDto.Obj obj) {
  96. obj.setMercId(MercAuthUtils.getMercId());
  97. obj.setIsStatus(true);
  98. R<DeviceInfoDto.Vo> r = deviceInfoService.obj(obj);
  99. DeviceInfoDto.Vo vo = r.getData();
  100. if (vo != null) {
  101. //点位
  102. Long placeId = vo.getPlaceId();
  103. List<MercPlaceDto.Vo> merPlaceList = R.feignCheckData(mercPlaceService.list(new MercPlaceDto.ListDto().setIds(CollUtil.newArrayList(placeId))));
  104. MercPlaceDto.Vo mercPlace = CollUtil.isNotEmpty(merPlaceList) ? merPlaceList.get(0) : null;
  105. vo.setPlaceName(mercPlace == null ? StrUtil.EMPTY : mercPlace.getPlaceName());
  106. //线路
  107. Long placeLineId = vo.getPlaceLineId();
  108. Map<Long, String> placeLineMap = R.feignCheckData(mercLineService.getNameList(new MercLineDto.GetNameListDto().setIds(CollUtil.newArrayList(placeLineId))));
  109. vo.setPlaceLineName(CollUtil.isEmpty(placeLineMap) ? StrUtil.EMPTY : placeLineMap.get(placeLineId));
  110. //区域
  111. Long districtId = vo.getDistrictId();
  112. Map<Long, String> districtMap = R.feignCheckData(mercPlaceService.merReginId2Name(new MiniMercRegionDto.IdList().setIds(CollUtil.newArrayList(districtId))));
  113. vo.setDistrictName(CollUtil.isEmpty(districtMap) ? StrUtil.EMPTY : districtMap.get(districtId));
  114. DeviceStatusDto.Vo deviceStatus = vo.getDeviceStatus();
  115. vo.setNetStateName(deviceStatus == null ? StrUtil.EMPTY : DeviceNetSateType.getEnumByCode(deviceStatus.getNetState()).getDescription());
  116. if (deviceStatus != null) {
  117. Integer tempValue = deviceStatus.getTempValue();
  118. if (tempValue == null) {
  119. List<DeviceTempRecords> deviceTempRecords = deviceTempRecordsService
  120. .list(Wrappers.<DeviceTempRecords>lambdaQuery()
  121. .eq(DeviceTempRecords::getDeviceId, vo.getDeviceId()).orderByDesc(DeviceTempRecords::getCreateTime).last("limit 1")
  122. );
  123. if (CollUtil.isNotEmpty(deviceTempRecords)) {
  124. deviceStatus.setTempValue(deviceTempRecords.get(0).getTempValue());
  125. vo.setDeviceStatus(deviceStatus);
  126. } else {
  127. deviceStatus.setTempValue(0);
  128. vo.setDeviceStatus(deviceStatus);
  129. }
  130. }
  131. Integer deviceStateL = deviceStatus.getLockStateL();
  132. Integer deviceStateR = deviceStatus.getLockStateR();
  133. vo.setDeviceStateL(deviceStateL);
  134. vo.setDeviceStateR(deviceStateR);
  135. DeviceLockState deviceLockStateL = DeviceLockState.getEnumByCode(deviceStateL);
  136. DeviceLockState deviceLockStateR = DeviceLockState.getEnumByCode(deviceStateR);
  137. vo.setDeviceStateRName(deviceLockStateR == null ? "未知" : deviceLockStateR.getDescription());
  138. vo.setDeviceStateLName(deviceLockStateL == null ? "未知" : deviceLockStateL.getDescription());
  139. }
  140. }
  141. return R.ok(vo);
  142. }
  143. @ApiOperation("小程序商户设备详情-数据统计")
  144. @PostMapping("dataCount")
  145. R<DeviceInfoDto.DeviceDataCountVO> dataCount(@RequestBody DeviceInfoDto.DeviceDataCountDTO dto) {
  146. dto.setMercId(MercAuthUtils.getMercId());
  147. return deviceInfoService.dataCount(dto);
  148. }
  149. private R checkDeviceByMerc(DeviceInfo deviceInfo) {
  150. Long mercId = MercAuthUtils.getMercId();
  151. //商户是否已通过审核
  152. MercDto.Vo mercInfo = mercFeignService.obj(new MercDto.ListDTO().setId(mercId)).getData();
  153. if (!mercInfo.getStatus().equals(String.valueOf(MercStatus.APPROVED.getCode()))) {
  154. return R.fail("商户未通过审核");
  155. }
  156. //设备是否存在
  157. if (!Emptys.check(deviceInfo)) {
  158. return R.fail("机器不存在");
  159. }
  160. //机器是否已授权给该商户
  161. if (!deviceInfo.getMercId().equals(mercId)) {
  162. return R.fail("机器未授权给商户");
  163. }
  164. //机器是否冻结
  165. Integer freezeStatus = SysDictUtils.getValue(EnumDeviceFreezeStatus.Code.CODE.getCode(), EnumDeviceFreezeStatus.N_2.getCode(), Integer.class);
  166. if (deviceInfo.getFreezeStatus().equals(freezeStatus)) {
  167. return R.fail("机器已冻结");
  168. }
  169. return R.ok();
  170. }
  171. @PostMapping("isMerc")
  172. @ApiOperation("判断设备是否归属商户")
  173. public R isMerc(@RequestBody MercMiniDeviceDto.Active active) {
  174. DeviceInfo deviceInfo = deviceInfoService.getById(active.getDeviceId());
  175. R checkR = this.checkDeviceByMerc(deviceInfo);
  176. if (checkR.getCode() == R.Enum.SUCCESS.getCode()) {
  177. Integer activeState = SysDictUtils.getValue(EnumDeviceActiveStatus.Code.CODE.getCode(), EnumDeviceActiveStatus.N_1.getCode(), Integer.class);
  178. String refMercCode = deviceInfo.getMercCode();
  179. //非质检商户需要进行判断,质检商户跳过
  180. if (!"10001".equals(refMercCode) && !deviceInfo.getActiveState().equals(activeState)) {
  181. return R.fail("机器未激活");
  182. }
  183. return R.ok();
  184. }
  185. return checkR;
  186. }
  187. @PostMapping("getActiveInfo")
  188. @ApiOperation("激活设备前判断")
  189. public R getActiveInfo(@RequestBody MercMiniDeviceDto.Active active) {
  190. DeviceInfo deviceInfo = deviceInfoService.getById(active.getDeviceId());
  191. R checkR = this.checkDeviceByMerc(deviceInfo);
  192. if (checkR.getCode() == R.Enum.SUCCESS.getCode()) {
  193. Integer activeState = SysDictUtils.getValue(EnumDeviceActiveStatus.Code.CODE.getCode(), EnumDeviceActiveStatus.N_1.getCode(), Integer.class);
  194. if (deviceInfo.getActiveState().equals(activeState)) {
  195. return R.fail("机器已激活");
  196. }
  197. return R.ok();
  198. }
  199. return checkR;
  200. }
  201. @PostMapping("active")
  202. @ApiOperation("激活设备")
  203. @Transactional(rollbackFor = Exception.class)
  204. public R active(@RequestBody MercMiniDeviceDto.Active active) {
  205. DeviceInfo deviceInfo = deviceInfoService.getById(active.getDeviceId());
  206. int factory = deviceInfo.getDeviceType() == EnumDeviceType.N_5.getIntCode() ? 2 : 1;
  207. if (factory == 1) {
  208. R r = checkDeviceByMerc(deviceInfo);
  209. if (r.getCode() == R.Enum.FAIL.getCode()) {
  210. return r;
  211. }
  212. }
  213. return FactoryUtils.getServiceRoute(DeviceFactory.class, deviceInfo.getDeviceType()).active(active);
  214. }
  215. @ApiOperation("运营状态修改")
  216. @PostMapping("modifyBusyStage")
  217. public R modifyBusyStage(@RequestBody @Validated MercMiniDeviceDto.BusySate busySate) {
  218. Long mercId = MercAuthUtils.getMercId();
  219. DeviceInfo deviceInfo = deviceInfoService.getById(busySate.getDeviceId());
  220. return FactoryUtils.getServiceRoute(DeviceFactory.class, deviceInfo.getDeviceType()).busyStatus(busySate.setMercId(mercId));
  221. }
  222. @ApiOperation("修改设备信息、上传坐标等")
  223. @PostMapping("updateInfo")
  224. public R updateInfo(@RequestBody @Validated MercMiniDeviceDto.UpdateInfo dto) {
  225. DeviceInfo deviceInfo = deviceInfoService.getById(dto.getDeviceId());
  226. if (!Emptys.check(deviceInfo) || Objects.equals(deviceInfo.getDeviceId(), MercAuthUtils.getMercId())) {
  227. return R.fail("设备不存在");
  228. }
  229. DeviceInfoDto.Update update = copy(DeviceInfoDto.Update.class, dto);
  230. deviceInfoService.update(update);
  231. return R.ok();
  232. }
  233. @ApiOperation("当前登录用户拥有的设备")
  234. @PostMapping("myDevices")
  235. R<List<Long>> myDevices() {
  236. return R.ok(getMyDevices());
  237. }
  238. /**
  239. * 获取登录人的设备
  240. *
  241. * @return
  242. */
  243. List<Long> getMyDevices() {
  244. boolean mercAdmin = MercAuthUtils.isMercAdmin();
  245. Long mercId = MercAuthUtils.getMercId();
  246. if (mercAdmin) {
  247. List<DeviceInfo> deviceInfos = deviceInfoService.list(Wrappers.<DeviceInfo>lambdaQuery().eq(DeviceInfo::getMercId, mercId).eq(DeviceInfo::getActiveState, DeviceActiveStateEnum.TRUE.getCode()));
  248. if (CollUtil.isEmpty(deviceInfos)) {
  249. return CollUtil.newArrayList();
  250. }
  251. return deviceInfos.stream().map(DeviceInfo::getDeviceId).collect(Collectors.toList());
  252. } else {
  253. //成员设备
  254. List<Long> deviceIds = R.feignCheckData(mercFeignService.mercUserDevice());
  255. return deviceIds;
  256. }
  257. }
  258. @PostMapping("genCode")
  259. @ApiOperation("蓝牙开门-生成授权码")
  260. public R<Boolean> genCode(@RequestBody @Validated DeviceBluetoothAuthDto.GenCode dto) {
  261. String deviceSn = dto.getDeviceSn();
  262. DeviceSysinfo deviceSysinfo = deviceSysinfoService.getOne(Wrappers.<DeviceSysinfo>lambdaQuery().eq(DeviceSysinfo::getDeviceSn, deviceSn));
  263. if (deviceSysinfo == null) {
  264. return R.fail("设备不存在!");
  265. }
  266. Long deviceId = deviceSysinfo.getDeviceId();
  267. //用户输入的
  268. String authCode = dto.getAuthCode();
  269. List<Long> myDevices = getMyDevices();
  270. if (!myDevices.contains(deviceId)) {
  271. return R.fail("抱歉!您无权对此设备进行授权!");
  272. }
  273. Long mercId = MercAuthUtils.getMercId();
  274. DeviceBluetoothAuth deviceBluetoothAuth = deviceBluetoothAuthService.getOne(Wrappers.<DeviceBluetoothAuth>lambdaQuery()
  275. .eq(DeviceBluetoothAuth::getDeviceId, deviceId)
  276. .eq(DeviceBluetoothAuth::getMercId, mercId)
  277. .eq(DeviceBluetoothAuth::getUseStatus, DeviceAuthCodeUseStatus.UN_USED.getCode())
  278. );
  279. String cacheAuthCode = getCacheAuthCode(deviceId);
  280. if (deviceBluetoothAuth != null) {
  281. if (StrUtil.isNotEmpty(cacheAuthCode)) {
  282. return R.fail("此设备尚有未使用的授权码:【" + cacheAuthCode + "】,请使用后再来生成!");
  283. } else {
  284. //已失效了
  285. deviceBluetoothAuthService.saveOrUpdate(deviceBluetoothAuth.setUseStatus(DeviceAuthCodeUseStatus.TIME_OUT.getCode()));
  286. }
  287. }
  288. //缓存
  289. setCacheAuthCode(deviceId, authCode);
  290. DeviceBluetoothAuth saveInfo = new DeviceBluetoothAuth()
  291. .setDeviceId(deviceId)
  292. .setMercId(mercId)
  293. .setDeviceId(deviceId).setAuthCode(authCode);
  294. return R.ok(deviceBluetoothAuthService.save(saveInfo));
  295. }
  296. @PostMapping("verificationCode")
  297. @ApiOperation("蓝牙开门-校验并使用授权码")
  298. public R<Boolean> verificationCode(@RequestBody @Validated DeviceBluetoothAuthDto.VerificationCode dto) {
  299. String deviceSn = dto.getDeviceSn();
  300. DeviceSysinfo deviceSysinfo = deviceSysinfoService.getOne(Wrappers.<DeviceSysinfo>lambdaQuery().eq(DeviceSysinfo::getDeviceSn, deviceSn));
  301. if (deviceSysinfo == null) {
  302. return R.fail("设备不存在!");
  303. }
  304. Long deviceId = deviceSysinfo.getDeviceId();
  305. String authCode = dto.getAuthCode();
  306. String cacheAuthCode = getCacheAuthCode(deviceId);
  307. if (!authCode.equals(cacheAuthCode)) {
  308. return R.fail("您输入的授权码有误或者无效!");
  309. }
  310. //验证通过,缓存去掉授权码,并更新状态
  311. Long mercId = MercAuthUtils.getMercId();
  312. DeviceBluetoothAuth deviceBluetoothAuth = deviceBluetoothAuthService.getOne(Wrappers.<DeviceBluetoothAuth>lambdaQuery()
  313. .eq(DeviceBluetoothAuth::getDeviceId, deviceId)
  314. .eq(DeviceBluetoothAuth::getAuthCode, authCode)
  315. .eq(DeviceBluetoothAuth::getMercId, mercId)
  316. .eq(DeviceBluetoothAuth::getUseStatus, DeviceAuthCodeUseStatus.UN_USED.getCode())
  317. );
  318. if (deviceBluetoothAuth == null) {
  319. return R.fail("您输入的授权码无效!");
  320. }
  321. //缓存去掉授权码
  322. delCacheAuthCode(deviceId);
  323. deviceBluetoothAuth.setUseStatus(DeviceAuthCodeUseStatus.USED.getCode());
  324. deviceBluetoothAuth.setUseUser(AuthorizeUtils.getLoginId(Long.class));
  325. deviceBluetoothAuth.setUseTime(LocalDateTime.now());
  326. return R.ok(deviceBluetoothAuthService.saveOrUpdate(deviceBluetoothAuth));
  327. }
  328. /**
  329. * auth-code有效期30分钟,单位:s ,
  330. */
  331. public static final Integer AUTH_CODE_TIMEOUT = 1800;
  332. public static void setCacheAuthCode(Long deviceId, String code) {
  333. RedisService<String> redisService = SpringBeanUtils.getBean(RedisService.class);
  334. redisService.set("device:auth:code:" + deviceId, code, AUTH_CODE_TIMEOUT);
  335. }
  336. public static String getCacheAuthCode(Long deviceId) {
  337. RedisService<String> redisService = SpringBeanUtils.getBean(RedisService.class);
  338. return redisService.get("device:auth:code:" + deviceId);
  339. }
  340. public static void delCacheAuthCode(Long deviceId) {
  341. RedisService<String> redisService = SpringBeanUtils.getBean(RedisService.class);
  342. redisService.remove("device:auth:code:" + deviceId);
  343. }
  344. }