package com.xy.controller; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.xy.alipay.AliPay; import com.xy.annotate.RestMappingController; import com.xy.dto.DeviceBluetoothAuthDto; import com.xy.dto.DeviceInfoDto; import com.xy.dto.DeviceStatusDto; import com.xy.dto.MercMiniDeviceDto; import com.xy.dto.be.MercDto; import com.xy.dto.common.MercLineDto; import com.xy.dto.common.MercPlaceDto; import com.xy.dto.mini.MiniMercRegionDto; import com.xy.entity.*; import com.xy.enums.MercStatus; import com.xy.service.DeviceBluetoothAuthServiceImpl; import com.xy.service.DeviceChargingServiceImpl; import com.xy.service.DeviceInfoServiceImpl; import com.xy.service.DeviceSysinfoServiceImpl; import com.xy.service.be.MercFeignService; import com.xy.service.common.MercLineService; import com.xy.service.common.MercPlaceService; import com.xy.utils.*; import com.xy.utils.enums.*; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import javax.validation.Valid; import java.time.LocalDateTime; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; import static com.xy.utils.Beans.copy; /** *

* 小程序-设备 *

* * @author hechunping * @since 2023/3/4 */ @RestMappingController("merc-mini/device") @AllArgsConstructor @Api(tags = "小程序-设备") public class MercMiniDeviceController { private final MercFeignService mercFeignService; private final DeviceInfoServiceImpl deviceInfoService; private final DeviceSysinfoServiceImpl deviceSysinfoService; private final MercPlaceService mercPlaceService; private final MercLineService mercLineService; private final DeviceBluetoothAuthServiceImpl deviceBluetoothAuthService; private final DeviceChargingServiceImpl deviceChargingService; @ApiOperation("商户设备首页统计") @PostMapping("mercHomeStatistical") public R mercHomeStatistical(@RequestBody @Valid DeviceInfoDto.MercHomeQueryDTO dto) { dto.setMercId(MercAuthUtils.getMercId()); dto.setMyDeviceIds(getMyDevices()); return deviceInfoService.mercHomeStatistical(dto); } @PostMapping("searchPage") @ApiOperation("小程序商户设备搜索") public R> mercDeviceSearchPage(@RequestBody DeviceInfoDto.Page page) { page.setMercId(MercAuthUtils.getMercId()); page.setMyDeviceIds(getMyDevices()); return deviceInfoService.mercDeviceSearchPage(page); } @ApiOperation("小程序商户设备详情-设备信息") @PostMapping("detail") R detail(@RequestBody DeviceInfoDto.Obj obj) { obj.setMercId(MercAuthUtils.getMercId()); obj.setIsStatus(true); R r = deviceInfoService.obj(obj); DeviceInfoDto.Vo vo = r.getData(); if (vo != null) { //点位 Long placeId = vo.getPlaceId(); List merPlaceList = R.feignCheckData(mercPlaceService.list(new MercPlaceDto.ListDto().setIds(CollUtil.newArrayList(placeId)))); MercPlaceDto.Vo mercPlace = CollUtil.isNotEmpty(merPlaceList) ? merPlaceList.get(0) : null; vo.setPlaceName(mercPlace == null ? StrUtil.EMPTY : mercPlace.getPlaceName()); //线路 Long placeLineId = vo.getPlaceLineId(); Map placeLineMap = R.feignCheckData(mercLineService.getNameList(new MercLineDto.GetNameListDto().setIds(CollUtil.newArrayList(placeLineId)))); vo.setPlaceLineName(CollUtil.isEmpty(placeLineMap) ? StrUtil.EMPTY : placeLineMap.get(placeLineId)); //区域 Long districtId = vo.getDistrictId(); Map districtMap = R.feignCheckData(mercPlaceService.merReginId2Name(new MiniMercRegionDto.IdList().setIds(CollUtil.newArrayList(districtId)))); vo.setDistrictName(CollUtil.isEmpty(districtMap) ? StrUtil.EMPTY : districtMap.get(districtId)); DeviceStatusDto.Vo deviceStatus = vo.getDeviceStatus(); vo.setNetStateName(deviceStatus == null ? StrUtil.EMPTY : DeviceNetSateType.getEnumByCode(deviceStatus.getNetState()).getDescription()); Integer deviceStateL = deviceStatus.getLockStateL(); Integer deviceStateR = deviceStatus.getLockStateR(); vo.setDeviceStateL(deviceStateL); vo.setDeviceStateR(deviceStateR); DeviceLockState deviceLockStateL = DeviceLockState.getEnumByCode(deviceStateL); DeviceLockState deviceLockStateR = DeviceLockState.getEnumByCode(deviceStateR); vo.setDeviceStateRName(deviceLockStateR == null ? "未知" : deviceLockStateR.getDescription()); vo.setDeviceStateLName(deviceLockStateL == null ? "未知" : deviceLockStateL.getDescription()); } return R.ok(vo); } @ApiOperation("小程序商户设备详情-数据统计") @PostMapping("dataCount") R dataCount(@RequestBody DeviceInfoDto.DeviceDataCountDTO dto) { dto.setMercId(MercAuthUtils.getMercId()); return deviceInfoService.dataCount(dto); } private R checkDeviceByMerc(DeviceInfo deviceInfo) { Long mercId = MercAuthUtils.getMercId(); //商户是否已通过审核 MercDto.Vo mercInfo = mercFeignService.obj(new MercDto.ListDTO().setId(mercId)).getData(); if (!mercInfo.getStatus().equals(String.valueOf(MercStatus.APPROVED.getCode()))) { return R.fail("商户未通过审核"); } //设备是否存在 if (!Emptys.check(deviceInfo)) { return R.fail("机器不存在"); } //机器是否已授权给该商户 if (!deviceInfo.getMercId().equals(mercId)) { return R.fail("机器未授权给商户"); } //机器是否冻结 if (deviceInfo.getFreezeStatus().equals(Integer.valueOf(DictSonEnum.DEVICE_FREEZE_STATUS_2.getKey()))) { return R.fail("机器已冻结"); } return R.ok(); } @PostMapping("isMerc") @ApiOperation("判断设备是否归属商户") public R isMerc(@RequestBody MercMiniDeviceDto.Active active) { DeviceInfo deviceInfo = deviceInfoService.getById(active.getDeviceId()); R checkR = this.checkDeviceByMerc(deviceInfo); if (checkR.getCode() == R.Enum.SUCCESS.getCode()) { if (!deviceInfo.getActiveState().equals(Integer.valueOf(DictSonEnum.DEVICE_ACTIVE_STATUS_1.getKey()))) { return R.fail("机器未激活"); } return R.ok(); } return checkR; } @PostMapping("getActiveInfo") @ApiOperation("激活设备前判断") public R getActiveInfo(@RequestBody MercMiniDeviceDto.Active active) { DeviceInfo deviceInfo = deviceInfoService.getById(active.getDeviceId()); R checkR = this.checkDeviceByMerc(deviceInfo); if (checkR.getCode() == R.Enum.SUCCESS.getCode()) { if (deviceInfo.getActiveState().equals(Integer.valueOf(DictSonEnum.DEVICE_ACTIVE_STATUS_1.getKey()))) { return R.fail("机器已激活"); } return R.ok(); } return checkR; } @PostMapping("active") @ApiOperation("激活设备") @Transactional(rollbackFor = Exception.class) public R active(@RequestBody MercMiniDeviceDto.Active active) { R activeInfo = this.getActiveInfo(active); //激活设备 if (activeInfo.getCode() == R.Enum.SUCCESS.getCode()) { DeviceInfo deviceInfo = deviceInfoService.getById(active.getDeviceId()); DeviceInfo updateDeviceInfo = new DeviceInfo() .setDeviceId(active.getDeviceId()) .setActiveState(Integer.valueOf(DictSonEnum.DEVICE_ACTIVE_STATUS_1.getKey())) .setBusyState(Integer.valueOf(DictSonEnum.DEVICE_BUSY_STATUS_1.getKey())) .setActiveTime(LocalDateTime.now()) .setShowStatus(true); //首次激活可使用x天 if (!deviceInfo.getIsChargingX()) { SysDictRedis sysDictRedis = SysDictUtils.get(DictEnum.DEVICE_CHARGING.getKey(), DictSonEnum.DEVICE_CHARGING_X.getKey()); updateDeviceInfo.setIsChargingX(true) .setChargingX(Integer.valueOf(sysDictRedis.getValue())); } deviceInfoService.updateById(updateDeviceInfo); //添加设备计费 DeviceCharging deviceCharging = deviceChargingService.getById(deviceInfo.getDeviceId()); if (deviceCharging == null) { LocalDateTime now = LocalDateTime.now(); deviceChargingService.save(new DeviceCharging() .setDeviceId(deviceInfo.getDeviceId()) .setDeviceType(deviceInfo.getDeviceType()) .setTimeout(now) .setCreateTime(now) .setUpdateTime(now) ); } return R.ok(); } else { return activeInfo; } } @ApiOperation("运营状态修改") @PostMapping("modifyBusyStage") @AliPay(AliPay.Type.BUSY_STATE) public R modifyBusyStage(@RequestBody @Validated MercMiniDeviceDto.BusySate busySate) { Long mercId = MercAuthUtils.getMercId(); Long deviceId = busySate.getDeviceId(); DeviceInfo updateDeviceInfo = new DeviceInfo() .setDeviceId(deviceId) .setMercId(mercId) .setBusyState(busySate.getBusyState()); deviceInfoService.updateById(updateDeviceInfo); return R.ok(); } @ApiOperation("修改设备信息、上传坐标等") @PostMapping("updateInfo") public R updateInfo(@RequestBody @Validated MercMiniDeviceDto.UpdateInfo dto) { DeviceInfo deviceInfo = deviceInfoService.getById(dto.getDeviceId()); if (!Emptys.check(deviceInfo) || Objects.equals(deviceInfo.getDeviceId(), MercAuthUtils.getMercId())) { return R.fail("设备不存在"); } DeviceInfoDto.Update update = copy(DeviceInfoDto.Update.class, dto); deviceInfoService.update(update); return R.ok(); } @ApiOperation("当前登录用户拥有的设备") @PostMapping("myDevices") R> myDevices() { return R.ok(getMyDevices()); } /** * 获取登录人的设备 * * @return */ List getMyDevices() { boolean mercAdmin = MercAuthUtils.isMercAdmin(); Long mercId = MercAuthUtils.getMercId(); if (mercAdmin) { List deviceInfos = deviceInfoService.list(Wrappers.lambdaQuery().eq(DeviceInfo::getMercId, mercId).eq(DeviceInfo::getActiveState, DeviceActiveStateEnum.TRUE.getCode())); if (CollUtil.isEmpty(deviceInfos)) { return CollUtil.newArrayList(); } return deviceInfos.stream().map(DeviceInfo::getDeviceId).collect(Collectors.toList()); } else { //成员设备 List deviceIds = R.feignCheckData(mercFeignService.mercUserDevice()); return deviceIds; } } @PostMapping("genCode") @ApiOperation("蓝牙开门-生成授权码") public R genCode(@RequestBody @Validated DeviceBluetoothAuthDto.GenCode dto) { String deviceSn = dto.getDeviceSn(); DeviceSysinfo deviceSysinfo = deviceSysinfoService.getOne(Wrappers.lambdaQuery().eq(DeviceSysinfo::getDeviceSn, deviceSn)); if (deviceSysinfo == null) { return R.fail("设备不存在!"); } Long deviceId = deviceSysinfo.getDeviceId(); //用户输入的 String authCode = dto.getAuthCode(); List myDevices = getMyDevices(); if (!myDevices.contains(deviceId)) { return R.fail("抱歉!您无权对此设备进行授权!"); } Long mercId = MercAuthUtils.getMercId(); DeviceBluetoothAuth deviceBluetoothAuth = deviceBluetoothAuthService.getOne(Wrappers.lambdaQuery() .eq(DeviceBluetoothAuth::getDeviceId, deviceId) .eq(DeviceBluetoothAuth::getMercId, mercId) .eq(DeviceBluetoothAuth::getUseStatus, DeviceAuthCodeUseStatus.UN_USED.getCode()) ); String cacheAuthCode = getCacheAuthCode(deviceId); if (deviceBluetoothAuth != null) { if (StrUtil.isNotEmpty(cacheAuthCode)) { return R.fail("此设备尚有未使用的授权码:【" + cacheAuthCode + "】,请使用后再来生成!"); } else { //已失效了 deviceBluetoothAuthService.saveOrUpdate(deviceBluetoothAuth.setUseStatus(DeviceAuthCodeUseStatus.TIME_OUT.getCode())); } } //缓存 setCacheAuthCode(deviceId, authCode); DeviceBluetoothAuth saveInfo = new DeviceBluetoothAuth() .setDeviceId(deviceId) .setMercId(mercId) .setDeviceId(deviceId).setAuthCode(authCode); return R.ok(deviceBluetoothAuthService.save(saveInfo)); } @PostMapping("verificationCode") @ApiOperation("蓝牙开门-校验并使用授权码") public R verificationCode(@RequestBody @Validated DeviceBluetoothAuthDto.VerificationCode dto) { String deviceSn = dto.getDeviceSn(); DeviceSysinfo deviceSysinfo = deviceSysinfoService.getOne(Wrappers.lambdaQuery().eq(DeviceSysinfo::getDeviceSn, deviceSn)); if (deviceSysinfo == null) { return R.fail("设备不存在!"); } Long deviceId = deviceSysinfo.getDeviceId(); String authCode = dto.getAuthCode(); String cacheAuthCode = getCacheAuthCode(deviceId); if (!authCode.equals(cacheAuthCode)) { return R.fail("您输入的授权码有误或者无效!"); } //验证通过,缓存去掉授权码,并更新状态 Long mercId = MercAuthUtils.getMercId(); DeviceBluetoothAuth deviceBluetoothAuth = deviceBluetoothAuthService.getOne(Wrappers.lambdaQuery() .eq(DeviceBluetoothAuth::getDeviceId, deviceId) .eq(DeviceBluetoothAuth::getAuthCode, authCode) .eq(DeviceBluetoothAuth::getMercId, mercId) .eq(DeviceBluetoothAuth::getUseStatus, DeviceAuthCodeUseStatus.UN_USED.getCode()) ); if (deviceBluetoothAuth == null) { return R.fail("您输入的授权码无效!"); } //缓存去掉授权码 delCacheAuthCode(deviceId); deviceBluetoothAuth.setUseStatus(DeviceAuthCodeUseStatus.USED.getCode()); deviceBluetoothAuth.setUseUser(AuthorizeUtils.getLoginId(Long.class)); deviceBluetoothAuth.setUseTime(LocalDateTime.now()); return R.ok(deviceBluetoothAuthService.saveOrUpdate(deviceBluetoothAuth)); } /** * auth-code有效期30分钟,单位:s , */ public static final Integer AUTH_CODE_TIMEOUT = 1800; public static void setCacheAuthCode(Long deviceId, String code) { RedisService redisService = SpringBeanUtils.getBean(RedisService.class); redisService.set("device:auth:code:" + deviceId, code, AUTH_CODE_TIMEOUT); } public static String getCacheAuthCode(Long deviceId) { RedisService redisService = SpringBeanUtils.getBean(RedisService.class); return redisService.get("device:auth:code:" + deviceId); } public static void delCacheAuthCode(Long deviceId) { RedisService redisService = SpringBeanUtils.getBean(RedisService.class); redisService.remove("device:auth:code:" + deviceId); } }