package com.xy.controller; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.xy.annotate.RestMappingController; import com.xy.collections.list.JArrayList; import com.xy.collections.map.JMap; import com.xy.device.EnumDeviceActiveStatus; import com.xy.device.EnumDeviceFreezeStatus; import com.xy.dto.*; 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.*; import com.xy.service.be.MercFeignService; import com.xy.service.common.MercLineService; import com.xy.service.common.MercPlaceService; import com.xy.service.factory.device.DeviceFactory; import com.xy.utils.*; import com.xy.utils.Enum.AlgorithmTypeEnum; import com.xy.utils.enums.DeviceActiveStateEnum; import com.xy.utils.enums.DeviceAuthCodeUseStatus; import com.xy.utils.enums.DeviceLockState; import com.xy.utils.enums.DeviceNetSateType; import com.xy.vo.DeviceDetailVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; 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 DeviceTempRecordsServiceImpl deviceTempRecordsService; private final AlipayDeviceService alipayDeviceService; private final DeviceStatusServiceImpl deviceStatusService; private final DeviceConfigServiceImpl deviceConfigService; private final DeviceTempSetServiceImpl deviceTempSetService; @ApiOperation("解绑商户") @PostMapping("unBindMercDevice") R unBindMercDevice(@RequestBody @Validated DeviceInfoDto.MercDeviceUnBindDto dto) { MercAuthUtils.MercAuth.Merc merc = MercAuthUtils.getMercAuth().getMerc(); dto.setMercId(merc.getId()); dto.setMercCode(merc.getMercCode()); dto.setMercName(merc.getName()); return R.ok(deviceInfoService.unBindDeviceByMerc(dto)); } @ApiOperation("商户设备授权") @PostMapping("deviceAuth") public R mercDeviceAuth(@RequestBody @Validated DeviceInfoDto.MercDeviceAuthDto auth) { String mercCode = auth.getMercCode(); MercDto.Vo merc = R.feignCheckData(mercFeignService.obj(new MercDto.ListDTO().setMercCode(mercCode))); // MercAuthUtils.MercAuth.Merc merc = MercAuthUtils.getMercAuth().getMerc(); auth.setMercCode(mercCode); auth.setMercId(merc.getId()); auth.setParentId(merc.getParentId()); auth.setMercName(merc.getName()); auth.setAlgorithmId(merc.getAlgorithmId()); auth.setMercOperate(true); //设备服务授权处理 R r = R.feignCheck(deviceInfoService.mercDeviceAuth(auth)); return R.ok(r.getData()); } @ApiOperation("设备分页-管理员") @PostMapping("pageByAdminName") public R> pageByAdminName(@RequestBody @Validated DeviceInfoDto.PageByAdminNameDto dto) { dto.setMercId(MercAuthUtils.getMercId()); dto.setDeviceIdList(getMyDevices()); dto.setPage(dto.getPage().setOrders(null)); return deviceInfoService.pageByAdminName(dto); } @ApiOperation("设备分页-商户") @PostMapping("pageByMerc") public R> pageByMerc(@RequestBody @Validated DeviceInfoDto.PageByMercDto dto) { List deviceIds = dto.getDeviceIds(); dto.setMercId(MercAuthUtils.getMercId()); Boolean choosed = dto.getChoosed(); if (BooleanUtil.isTrue(choosed)) { //查询已选择,为前端传入 deviceIds dto.setDeviceIds(deviceIds); } dto.setMyDeviceIds(getMyDevices()); return R.ok(deviceInfoService.pageByMerc(dto)); } @ApiOperation("商户设备列表分页-穿梭框用") @PostMapping("myDeviceList") public R> myDeviceList(@RequestBody @Validated DeviceInfoDto.MyDeviceDTO dto) { dto.setMercId(MercAuthUtils.getMercId()); return deviceInfoService.myDeviceList(dto); } @ApiOperation("设备列表带卡包数") @PostMapping("algorithmChargingDevice") public R> algorithmChargingDevice(@RequestBody @Validated DeviceInfoDto.AlgorithmCharging algorithmCharging) { algorithmCharging.setMercId(MercAuthUtils.getMercId()); return deviceInfoService.algorithmChargingDevice(algorithmCharging); } @ApiOperation("商户设备首页统计") @PostMapping("mercHomeStatistical") public R mercHomeStatistical(@RequestBody @Valid DeviceInfoDto.MercHomeQueryDTO dto) { dto.setMercId(MercAuthUtils.getMercId()); dto.setMyDeviceIds(getMyDevices()); return deviceInfoService.mercHomeStatistical(dto); } @ApiOperation("设备列表-Id&Name") @PostMapping("listOfIdName") public R listOfIdName() { DeviceInfoDto.ListCommon listCommonDto = new DeviceInfoDto.ListCommon(); DeviceInfoDto.Vo voDto = new DeviceInfoDto.Vo(); voDto.setActiveState(Integer.valueOf(DeviceActiveStateEnum.TRUE.getCode())) .setMercId(MercAuthUtils.getMercId()); listCommonDto.setVo(voDto); List copy = copy(MercMiniDeviceDto.ListOfIdNameVo.class, deviceInfoService.listCommon(listCommonDto).getData()); return R.ok(copy); } @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 algorithmId = vo.getAlgorithmId(); //点位 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()); if (deviceStatus != null) { Integer tempValue = deviceStatus.getTempValue(); if (tempValue == null) { List deviceTempRecords = deviceTempRecordsService .list(Wrappers.lambdaQuery() .eq(DeviceTempRecords::getDeviceId, vo.getDeviceId()).orderByDesc(DeviceTempRecords::getCreateTime).last("limit 1") ); if (CollUtil.isNotEmpty(deviceTempRecords)) { deviceStatus.setTempValue(deviceTempRecords.get(0).getTempValue()); vo.setDeviceStatus(deviceStatus); } else { deviceStatus.setTempValue(0); vo.setDeviceStatus(deviceStatus); } } Integer deviceStateL = deviceStatus.getLockStateL(); Integer deviceStateR = deviceStatus.getLockStateR(); Boolean isUseBattery = deviceStatus.getIsUseBattery(); if (BooleanUtil.isTrue(isUseBattery)) { //使用电池。即断电状态 vo.setSysPower(2); } else { vo.setSysPower(1); } 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()); if (AlgorithmTypeEnum.ALIPAY.getId() == algorithmId) { String deviceId = String.valueOf(vo.getDeviceId()); //主动查询一次温度、音量 温度:TEMP 音量:VOL alipayDeviceService.queryAttributes(new DeviceQueryAttr().setTerminalId(deviceId).setType("VOL")); alipayDeviceService.queryAttributes(new DeviceQueryAttr().setTerminalId(deviceId).setType("TEMP")); //支付宝状态实时返回 DeviceDetailVO deviceDetailVO = alipayDeviceService.queryDetail(new DeviceDetailDTO().setTerminalId(String.valueOf(vo.getDeviceId()))); Boolean online = deviceDetailVO.getOnline(); Integer netState = BooleanUtil.isTrue(online) ? DeviceNetSateType.CONNECTED.getCode() : DeviceNetSateType.DISCONNECT.getCode(); if (!ObjectUtil.equals(netState, deviceStatus.getNetState())) { //存在差异更新设备状态表 deviceStatusService.updateById(new DeviceStatus().setDeviceId(vo.getDeviceId()).setNetState(netState)); } deviceStatus.setNetState(netState); vo.setDeviceStatus(deviceStatus); } } //工作温度设置 DeviceTempSetDto.Vo lastTempset = R.feignCheckData(deviceTempSetService.getLastOne(new DeviceTempSetDto.GetLastOneDto().setDeviceId(vo.getDeviceId()))); vo.setJobTempSetValue(lastTempset == null ? null : lastTempset.getTempValue()); } DeviceConfig deviceConfig = deviceConfigService.getById(obj.getDeviceId()); vo.setTempSetInfo(BeanUtil.copyProperties(deviceConfig, DeviceInfoDto.TempSetInfo.class)); 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("机器未授权给商户"); } //机器是否冻结 Integer freezeStatus = SysDictUtils.getValue(EnumDeviceFreezeStatus.Code.CODE.getCode(), EnumDeviceFreezeStatus.N_2.getCode(), Integer.class); if (deviceInfo.getFreezeStatus().equals(freezeStatus)) { 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()) { Integer activeState = SysDictUtils.getValue(EnumDeviceActiveStatus.Code.CODE.getCode(), EnumDeviceActiveStatus.N_1.getCode(), Integer.class); String refMercCode = deviceInfo.getMercCode(); //非质检商户需要进行判断,质检商户跳过 if (!"10001".equals(refMercCode) && !deviceInfo.getActiveState().equals(activeState)) { 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()) { Integer activeState = SysDictUtils.getValue(EnumDeviceActiveStatus.Code.CODE.getCode(), EnumDeviceActiveStatus.N_1.getCode(), Integer.class); if (deviceInfo.getActiveState().equals(activeState)) { return R.fail("机器已激活"); } return R.ok(); } return checkR; } @PostMapping("active") @ApiOperation("激活设备") public R active(@RequestBody MercMiniDeviceDto.Active2 active) { List deviceIds = active.getDeviceId(); List list = deviceInfoService.list(new LambdaQueryWrapper() .in(DeviceInfo::getDeviceId, deviceIds) ); JMap cover = new JArrayList<>(list).toMap(DeviceInfo::getDeviceType).cover(); if (cover.size() > 1) { return R.fail("批量激活设备类型必须一致"); } for (DeviceInfo deviceInfo : list) { R checkR = this.checkDeviceByMerc(deviceInfo); if (checkR.getCode() == R.Enum.FAIL.getCode()) { return checkR; } } return FactoryUtils.getServiceRoute(DeviceFactory.class, list.get(0).getDeviceType()).active(active); } @ApiOperation("运营状态修改") @PostMapping("modifyBusyStage") public R modifyBusyStage(@RequestBody @Validated MercMiniDeviceDto.BusySate busySate) { Long mercId = MercAuthUtils.getMercId(); DeviceInfo deviceInfo = deviceInfoService.getById(busySate.getDeviceId()); return FactoryUtils.getServiceRoute(DeviceFactory.class, deviceInfo.getDeviceType()).busyStatus(busySate.setMercId(mercId)); } @ApiOperation("修改设备信息、上传坐标等") @PostMapping("updateInfo") public R updateInfo(@RequestBody @Validated MercMiniDeviceDto.UpdateInfo dto) { DeviceInfo deviceInfo = deviceInfoService.getById(dto.getDeviceId()); if (!Emptys.check(deviceInfo) || !Objects.equals(deviceInfo.getMercId(), 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); } }