MercMiniDeviceController.java 16 KB

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