package com.xy.service; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; import cn.hutool.core.text.StrBuilder; import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xy.collections.list.JArrayList; import com.xy.collections.list.JList; import com.xy.config.DeviceThreadPoolConfig; import com.xy.consts.DictConsts; import com.xy.dto.*; import com.xy.entity.*; import com.xy.enums.FileExportType; import com.xy.error.CommRuntimeException; import com.xy.mapper.DeviceInfoMapper; import com.xy.mapper.entity.DeviceInfoQueryPage; import com.xy.util.ExcelUtils; import com.xy.util.FileUtils; import com.xy.utils.*; import com.xy.utils.enums.DeviceActiveStateEnum; import com.xy.utils.enums.DeviceNetSateType; import com.xy.utils.enums.DictEnum; import com.xy.utils.enums.DictSonEnum; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import jodd.introspector.MapperFunction; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; 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.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.io.IOException; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; import static com.xy.utils.PlusBeans.*; /** *

* 设备-信息 服务实现类 *

* * @author lijin * @since 2022-12-23 */ @Service @RequiredArgsConstructor @Api(tags = "设备-信息") public class DeviceInfoServiceImpl extends ServiceImpl implements DeviceInfoService { private final DeviceSysinfoServiceImpl deviceSysinfoService; private final DeviceStatusServiceImpl deviceStatusService; private final DeviceRegisterServiceImpl deviceRegisterService; private final DeviceErrorsRecordServiceImpl deviceErrorsRecordService; private final DeviceDataServiceImpl deviceDataService; private final DeviceTempRecordsServiceImpl deviceTempRecordsService; private final DeviceNetRecordServiceImpl deviceNetRecordService; private final GoodsDeviceService goodsDeviceService; private final FileExportService fileExportService; private final RedisService redisService; private final String keyPrefix = "device:history:"; private final FileUtils fileUtils; @Override @ApiOperation("对象查询") public R obj(DeviceInfoDto.Obj obj) { //设备信息 LambdaQueryWrapper lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(obj, DeviceInfo.class).build(); List list = list(lambdaQueryWrapper); if (!Emptys.check(list)) { return R.ok(); } DeviceInfoDto.Vo deviceInfo = copy(DeviceInfoDto.Vo.class, list.get(0)); int num = 0; if (obj.getIsSysinfo()) { num++; } if (obj.getIsStatus()) { num++; } if (obj.getIsRegister()) { num++; } if (num > 0) { ThreadPoolUtils.Execute execute = ThreadPoolUtils.excPoll(DeviceThreadPoolConfig.DEVICE_COMMON_POLL, num); if (obj.getIsSysinfo()) { execute.execute(() -> { //系统信息 DeviceSysinfoDto.Vo deviceSysinfo = deviceSysinfoService.get(new DeviceSysinfoDto.Vo().setDeviceId(deviceInfo.getDeviceId())).getData(); deviceInfo.setDeviceSysinfo(deviceSysinfo); }); } if (obj.getIsStatus()) { execute.execute(() -> { //状态信息 DeviceStatusDto.Vo deviceStatus = deviceStatusService.obj(new DeviceStatusDto.Vo().setDeviceId(deviceInfo.getDeviceId())).getData(); deviceInfo.setDeviceStatus(deviceStatus); }); } if (obj.getIsRegister()) { execute.execute(() -> { //注册信息 DeviceRegisterDto.Vo deviceRegister = deviceRegisterService.obj(new DeviceRegisterDto.Vo().setDeviceId(deviceInfo.getDeviceId())).getData(); deviceInfo.setDeviceRegister(deviceRegister); }); } execute.end(); } return R.ok(deviceInfo); } @ApiOperation("反显设备名称") @Override public R> getDeviceNameList(DeviceInfoDto.DeviceIdDto dto) { LambdaQueryWrapper lqw = new LambdaQueryWrapper() .in(DeviceInfo::getDeviceId, dto.getDeviceId()) .select(DeviceInfo::getDeviceId, DeviceInfo::getDeviceName); List deviceInfoList = list(lqw); return R.ok(deviceInfoList.stream().collect(Collectors.toMap(DeviceInfo::getDeviceId, i -> Optional.ofNullable(i.getDeviceName()).orElse("")))); } @Override public R getDeviceSysinfo(DeviceSysinfoDto.DeviceSysInfo dto) { String dtoDeviceSN = dto.getDeviceSN(); DeviceSysinfo one = deviceSysinfoService.getOne(Wrappers.lambdaQuery().eq(DeviceSysinfo::getDeviceSn, dtoDeviceSN)); return R.ok(BeanUtil.copyProperties(one, DeviceSysinfoDto.Vo.class)); } @Override @ApiOperation("设备访问历史添加") public R history(DeviceInfoDto.Obj obj) { //获取字典 SysDictRedis sysDictRedis = SysDictUtils.get(DictEnum.DATA_CLEAR_SIZE.getKey(), "device_history_twig"); Integer value = Integer.valueOf(sysDictRedis.getValue()); //获取redis String key = keyPrefix + AuthorizeUtils.getLoginId(Long.class); List list = redisService.getList(key); list.add(0, String.valueOf(obj.getDeviceId())); //去重 List redisList = new ArrayList<>(); JList comparing = new JArrayList<>(list).comparing(); if (comparing.size() > value) { for (int i = 0; i < value; i++) { redisList.add(comparing.get(i)); } } else { redisList = comparing; } redisService.removeList(key); redisService.setList(key, redisList); return R.ok(); } @Override @ApiOperation("开门检测") public R checkOpenDoor(DeviceInfoDto.Obj obj) { DeviceInfoDto.Vo deviceInfo = obj(new DeviceInfoDto.Obj() .setDeviceId(obj.getDeviceId()) .setIsStatus(true) ).getData(); if (deviceInfo == null) { return R.fail("设备不存在"); } DeviceStatusDto.Vo deviceStatus = deviceInfo.getDeviceStatus(); check(deviceInfo.getFreezeStatus(), 2, "设备已冻结"); SysDictRedis sysDictRedis = SysDictUtils.get(DictEnum.DEVICE_FAULT_LEVEL_PAY_THRESHOLD.getKey(), DictSonEnum.DEVICE_FAULT_LEVEL_PAY_THRESHOLD_NOT_PAY.getKey()); if (deviceInfo.getFaultLevel() >= Integer.valueOf(sysDictRedis.getValue())) { return R.fail("设备故障"); } check(deviceStatus.getNetState(), 2, "设备已离线"); check(obj.getDoor() != null && obj.getDoor() == 1 ? deviceStatus.getDoorStateR() : deviceStatus.getDoorStateL(), 1, "设备正在使用中,请稍后"); check(obj.getDoor() != null && obj.getDoor() == 1 ? deviceStatus.getLockStateR() : deviceStatus.getLockStateL(), 2, "设备已锁机"); return R.ok(deviceInfo); } @PostMapping("historyList") @ApiOperation("设备访问历史查询") public R> historyList() { //获取redis String key = keyPrefix + AuthorizeUtils.getLoginId(Long.class); List deviceIds = redisService.getList(key); if (!Emptys.check(deviceIds)) { return R.ok(); } //查询数据库 List list = list(new LambdaQueryWrapper().in(DeviceInfo::getDeviceId, deviceIds)); return R.ok(copy(DeviceInfoDto.Vo.class, list)); } @ApiOperation("修改") @PostMapping("update") public R update(@RequestBody @Validated DeviceInfoDto.Update update) { DeviceInfo deviceInfo = copy(DeviceInfo.class, update); updateById(deviceInfo); return R.ok(); } @ApiOperation("批量修改") @PostMapping("updateBatch") public R updateBatch(@RequestBody List updates) { List deviceInfos = new ArrayList<>(updates.size()); updates.forEach(update -> deviceInfos.add(copy(DeviceInfo.class, update))); updateBatchById(deviceInfos); return R.ok(); } @Override @ApiOperation("更新商户线路") public R updateLine(@RequestBody @Validated DeviceInfoDto.UpdateLine updateLine) { LambdaUpdateWrapper luw = new LambdaUpdateWrapper().eq(DeviceInfo::getMercId, updateLine.getMercId()); //绑定线路,更换线路 if (DeviceInfoDto.UPDATE.equals(updateLine.getType())) { DeviceInfo deviceInfo = new DeviceInfo(); deviceInfo.setPlaceLineId(updateLine.getPlaceLineId()); luw.in(DeviceInfo::getDeviceId, updateLine.getDeviceIds()); baseMapper.update(deviceInfo, luw); } //删除线路 if (DeviceInfoDto.DEL.equals(updateLine.getType())) { luw.eq(DeviceInfo::getPlaceLineId, updateLine.getWherePlaceLineId()); luw.set(DeviceInfo::getPlaceLineId, null); baseMapper.update(null, luw); } //解绑线路 设置线路ID为null if (DeviceInfoDto.CLEAR.equals(updateLine.getType())) { luw.in(DeviceInfo::getDeviceId, updateLine.getDeviceIds()); luw.set(DeviceInfo::getPlaceLineId, null); baseMapper.update(null, luw); } return R.ok(); } @Override @ApiOperation("更新商户点位") public R updatePlace(@RequestBody @Validated DeviceInfoDto.UpdatePlace updatePlace) { LambdaUpdateWrapper luw = new LambdaUpdateWrapper().eq(DeviceInfo::getMercId, updatePlace.getMercId()); //绑定点位,更换点位 if (DeviceInfoDto.UPDATE.equals(updatePlace.getType())) { DeviceInfo deviceInfo = new DeviceInfo(); deviceInfo.setPlaceId(updatePlace.getPlaceId()); luw.in(DeviceInfo::getDeviceId, updatePlace.getDeviceIds()); baseMapper.update(deviceInfo, luw); } //删除点位 if (DeviceInfoDto.DEL.equals(updatePlace.getType())) { luw.eq(DeviceInfo::getPlaceId, updatePlace.getWherePlaceId()); luw.set(DeviceInfo::getPlaceId, null); baseMapper.update(null, luw); } //解绑点位 设置点位ID为null if (DeviceInfoDto.CLEAR.equals(updatePlace.getType())) { luw.in(DeviceInfo::getDeviceId, updatePlace.getDeviceIds()); luw.set(DeviceInfo::getPlaceId, null); baseMapper.update(null, luw); } return R.ok(); } @PostMapping("page") @ApiOperation("分页查询") public R> page(@RequestBody DeviceInfoDto.Page page) { return R.ok(queryPage(page)); } @ApiOperation("导出设备列表") @PostMapping("exportDevices") public void exportDevices(HttpServletResponse response, @RequestBody @Valid DeviceInfoDto.Page page) throws IOException { PageBean pageBean = queryPage(page); List records = pageBean.getRecords(); List deviceExcelVOS = BeanUtil.copyToList(records, DeviceInfoDto.DeviceExcelVO.class); // 输出 ExcelUtils.write(response, "设备列表.xls", "设备列表", DeviceInfoDto.DeviceExcelVO.class, deviceExcelVOS); } @ApiOperation("导出设备(异步)") @PostMapping("exportDevices/async") public void exportDevicesAsync(@RequestBody @Validated DeviceInfoDto.Page page) { PageBean pageBean = queryPage(page); List records = pageBean.getRecords(); List deviceExcelVOS = BeanUtil.copyToList(records, DeviceInfoDto.DeviceExcelVO.class); //异步导出参数封装 ExcelDTO excelDTO = new ExcelDTO<>(); excelDTO.setData(deviceExcelVOS); excelDTO.setHead(DeviceInfoDto.DeviceExcelVO.class); excelDTO.setSheetName(FileExportType.DEVICE_INFO.getDescription()); excelDTO.setFileExportType(FileExportType.DEVICE_INFO); //执行导出 fileExportService.exportExcelAsync(excelDTO); } @PostMapping("nearbyPage") @ApiOperation("附近设备分页查询") public R> nearbyPage(@RequestBody DeviceInfoDto.Page page) { if (!Emptys.check(page.getLon()) || !Emptys.check(page.getLat())) { throw new CommRuntimeException("经纬度不能为空"); } return R.ok(queryPage(page)); } @ApiOperation(value = "商户设备授权", hidden = true) @Override @Transactional(rollbackFor = Exception.class) public R mercDeviceAuth(DeviceInfoDto.MercDeviceAuthDto auth) { Long mercId = auth.getMercId(); String mercCode = auth.getMercCode(); Long algorithmId = auth.getAlgorithmId(); String mercName = auth.getMercName(); //商户最终设备列表 List deviceIds = auth.getDeviceIds(); List devices = getDevicesByMercId(mercId); //取消商户设备授权 if (CollUtil.isEmpty(deviceIds)) { if (CollUtil.isEmpty(devices)) { return R.ok(Boolean.TRUE); } } //更新商户设备授权 List deviceInfos = this.listByIds(deviceIds); for (DeviceInfo deviceInfo : deviceInfos) { int refMercId = deviceInfo.getMercId().intValue(); // 只有解绑后,才能给顶级商户授权 if (refMercId != -1 && refMercId != mercId.intValue()) { StrBuilder sb = StrBuilder.create(); String errMsg = sb.append("设备[") .append(deviceInfo.getDeviceId()) .append("]") .append("已被商户[") .append(deviceInfo.getMercName()) .append("]绑定,请先进行解绑!") .toString(); //已关联别商户 return R.fail(errMsg, Boolean.FALSE); } //绑定关系 deviceInfo.setMercId(mercId).setMercCode(mercCode).setAlgorithmId(algorithmId).setMercName(mercName); } saveOrUpdateBatch(deviceInfos); // //原来存在的设备关系,不在最终设备列表中的移除 // if (CollUtil.isNotEmpty(devices)) { // List oldIds = new ArrayList<>(); // List removeIds = new ArrayList<>(); // devices.forEach(device -> oldIds.add(device.getDeviceId())); // oldIds.forEach(deviceId -> { // //不在最终设备列表中的待移除 // if (!deviceIds.contains(deviceId)) { // removeIds.add(deviceId); // } // }); // if (CollUtil.isNotEmpty(removeIds)) { // List removeList = this.listByIds(removeIds); // removeMerRefDevices(removeList, parentId); // } // } return R.ok(Boolean.TRUE); } /** * 解绑机器 回收 * * @param dto * @return */ @Override public R unBindMercDevice(DeviceInfoDto.MercDeviceUnBindDto dto) { List deviceInfos = this.listByIds(dto.getDeviceIds()); return R.ok(removeMerRefDevicesToTopMerc(deviceInfos)); } /** * 回收机器 * * @param deviceInfos * @return */ private Boolean removeMerRefDevicesToTopMerc(List deviceInfos) { if (CollUtil.isNotEmpty(deviceInfos)) { deviceInfos.forEach(deviceInfo -> { //回收 deviceInfo.setMercId(-1L); deviceInfo.setMercDeviceCode(StrUtil.EMPTY); deviceInfo.setMercName(StrUtil.EMPTY); deviceInfo.setMercCode(StrUtil.EMPTY); }); //批量更新 return updateBatchById(deviceInfos); } return Boolean.FALSE; } /** * 批量移除商户设备绑定关系 * * @param deviceInfos * @return */ private Boolean removeMerRefDevices(List deviceInfos, Long parentId) { if (CollUtil.isNotEmpty(deviceInfos) && parentId != null) { deviceInfos.forEach(deviceInfo -> { //非顶级兴元商户,解绑后,机器归父商户 if (parentId != 1) { deviceInfo.setMercId(parentId); } //一级商户,解绑后,直接释放 if (parentId == 0) { //兴元等级 0 释放关系 deviceInfo.setMercId(-1L); } deviceInfo.setMercName(StrUtil.EMPTY); deviceInfo.setMercCode(StrUtil.EMPTY); }); //批量更新 return updateBatchById(deviceInfos); } return Boolean.FALSE; } @ApiOperation("集合查询") @Override public R> list(DeviceInfoDto.ListDto dto) { List list = list(new LambdaQueryWrapper().in(CollUtil.isNotEmpty(dto.getDeviceIds()), DeviceInfo::getDeviceId, dto.getDeviceIds())); return R.ok(copy(DeviceInfoDto.Vo.class, list)); } @Override @ApiOperation("通用集合查询") public R> listCommon(DeviceInfoDto.ListCommon dto) { String deviceSearch = dto.getDeviceSearch(); DeviceInfoDto.Vo vo = dto.getVo(); QueryWrapper queryWrapper = new MybatisPlusQuery().eqWrapper(vo == null ? new DeviceInfoDto.Vo() : vo, DeviceInfo.class).buildQW(); List placeLineIds = dto.getPlaceLineIds(); List deviceIds = dto.getDeviceIds(); List columnList = dto.getColumnList(); if (CollUtil.isNotEmpty(placeLineIds)) { queryWrapper.in(LambdaUtils.getUnderlineCaseName(DeviceInfo::getPlaceLineId), placeLineIds); } if (StrUtil.isNotEmpty(deviceSearch)) { queryWrapper.and(wrapper -> wrapper.likeRight(LambdaUtils.getUnderlineCaseName(DeviceInfo::getDeviceName), deviceSearch).or() .eq(LambdaUtils.getUnderlineCaseName(DeviceInfo::getMercDeviceCode), deviceSearch)); } if (CollUtil.isNotEmpty(columnList)) { queryWrapper.select(columnList.stream().toArray(String[]::new)); } if (CollUtil.isNotEmpty(deviceIds)) { queryWrapper.in(LambdaUtils.getUnderlineCaseName(DeviceInfo::getDeviceId), deviceIds); } return R.ok(copy(DeviceInfoDto.Vo.class, list(queryWrapper))); } @Override @ApiOperation("商户设备算法列表") public R> mercAlgorithmIdList(DeviceInfoDto.MercAlgorithmIdListDto dto) { String algorithmIdStr = LambdaUtils.getProperty(DeviceInfo::getAlgorithmId); String mercStr = StringTools.humpToLine(LambdaUtils.getProperty(DeviceInfo::getMercId)); QueryWrapper lqw = new QueryWrapper() .isNotNull(StringTools.humpToLine(algorithmIdStr)) .eq(mercStr, dto.getMercId()) .select(String.format("DISTINCT (%s) as %s", StringTools.humpToLine(algorithmIdStr), algorithmIdStr)); List list = listObjs(lqw, (MapperFunction) o -> (Long) o); return R.ok(list); } @Override @ApiOperation("小程序-商户设备首页统计") public R mercHomeStatistical(DeviceInfoDto.MercHomeQueryDTO dto) { Long mercId = dto.getMercId(); List myDeviceIds = dto.getMyDeviceIds(); //初始化数据 DeviceInfoDto.MercHomeStatisticalVO mercHomeStatisticalVO = new DeviceInfoDto.MercHomeStatisticalVO() .setClosedNum(0).setOfflineNum(0) .setOnlineNum(0).setOperatingNum(0).setNeedToFillNum(0); if (CollUtil.isEmpty(myDeviceIds)) { return R.ok(mercHomeStatisticalVO); } List mercDevices = listByIds(myDeviceIds); if (CollUtil.isEmpty(mercDevices)) { return R.ok(mercHomeStatisticalVO); } //在线、离线 List deviceStatuses = deviceStatusService.listByIds(myDeviceIds); //分组统计 Map countNetstateMap = deviceStatuses.stream().collect(Collectors .groupingBy(DeviceStatus::getNetState, Collectors.counting())); Integer onlineDictValue = SysDictUtils.getValue(DictEnum.DEVICE_ONLINE_STATUS.getKey(), DictSonEnum.DEVICE_ONLINE_STATUS_CONNECTED.getKey(), Integer.class); Integer offlineDictValue = SysDictUtils.getValue(DictEnum.DEVICE_ONLINE_STATUS.getKey(), DictSonEnum.DEVICE_ONLINE_STATUS_DISCONNECT.getKey(), Integer.class); int onlineNum = countNetstateMap.get(onlineDictValue) == null ? 0 : countNetstateMap.get(onlineDictValue).intValue(); int offlineNum = countNetstateMap.get(offlineDictValue) == null ? 0 : countNetstateMap.get(offlineDictValue).intValue(); mercHomeStatisticalVO.setOnlineNum(onlineNum); mercHomeStatisticalVO.setOfflineNum(offlineNum); //运营、停业 Map countBusyStateMap = mercDevices.stream().collect(Collectors .groupingBy(DeviceInfo::getBusyState, Collectors.counting())); Integer busyState1 = SysDictUtils.getValue(DictEnum.DEVICE_BUSY_STATUS.getKey(), DictSonEnum.DEVICE_BUSY_STATUS1.getKey(), Integer.class); Integer busyState2 = SysDictUtils.getValue(DictEnum.DEVICE_BUSY_STATUS.getKey(), DictSonEnum.DEVICE_BUSY_STATUS2.getKey(), Integer.class); int operatingNum = countBusyStateMap.get(busyState1) == null ? 0 : countBusyStateMap.get(busyState1).intValue(); int closedNum = countBusyStateMap.get(busyState2) == null ? 0 : countBusyStateMap.get(busyState2).intValue(); mercHomeStatisticalVO.setOperatingNum(operatingNum); mercHomeStatisticalVO.setClosedNum(closedNum); //待补货 //TODO: 此逻辑需要确认 return R.ok(mercHomeStatisticalVO); } @Override @ApiOperation("小程序-商户设备首页列表") public R> mercHomeList(DeviceInfoDto.MercHomeQueryDTO dto) { Long mercId = dto.getMercId(); String deviceName = dto.getDeviceName(); Long deviceId = dto.getDeviceId(); List list = this.baseMapper.merHomeCountList(dto); if (CollUtil.isEmpty(list)) { return R.ok(Collections.emptyList()); } List dataList = new ArrayList<>(list.size()); LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); lqw.eq(DeviceInfo::getActiveState, DeviceActiveStateEnum.TRUE.getCode()); lqw.eq(mercId != null, DeviceInfo::getMercId, mercId); lqw.eq(deviceId != null, DeviceInfo::getDeviceId, deviceId); lqw.like(StrUtil.isNotEmpty(deviceName), DeviceInfo::getDeviceName, deviceName); List deviceInfoList = this.list(lqw); //未分配线路的设置默认值 deviceInfoList.stream().filter(s -> s.getPlaceLineId() == null).forEach(s -> s.setPlaceLineId(-1L)); //根据线路id分组 Map> deviceMap = deviceInfoList.stream().collect(Collectors.groupingBy(DeviceInfo::getPlaceLineId)); for (DeviceInfoDto.MercHomeCountVO v : list) { DeviceInfoDto.MercHomeListVO vo = new DeviceInfoDto.MercHomeListVO(); Long placeLineId = v.getPlaceLineId(); vo.setDeviceNum(v.getDeviceNum()); vo.setPlaceLineId(v.getPlaceLineId()); //线路下的设备列表 List deviceInfos = BeanUtil.copyToList(deviceMap.get(placeLineId), DeviceInfoDto.MercHomeDeviceVo.class); if (CollUtil.isEmpty(deviceInfos)) { continue; } //设备销售统计 String todayDate = DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN); List deviceIds = deviceInfos.stream().map(DeviceInfoDto.MercHomeDeviceVo::getDeviceId).collect(Collectors.toList()); //统计条件:当天 DeviceDataDto.ListDTO deviceDataListDTO = new DeviceDataDto.ListDTO() .setDeviceIds(deviceIds).setType(DictSonEnum.DEVICE_DATA_TYPE_DAY.getKey()).setDateValue(Integer.valueOf(todayDate)).setMercId(mercId); List deviceDataList = deviceDataService.list(deviceDataListDTO); Map dataMap = new HashMap<>(); if (CollUtil.isNotEmpty(deviceDataList)) { dataMap = deviceDataList.stream().collect(Collectors.toMap(DeviceDataDto.Vo::getDeviceId, d -> d)); } //设备状态查询 List deviceStatusList = deviceStatusService.list(new DeviceStatusDto.SelectList().setDeviceIds(deviceIds)).getData(); Map datdeviceStatusMap = new HashMap<>(); if (CollUtil.isNotEmpty(deviceStatusList)) { datdeviceStatusMap = deviceStatusList.stream().collect(Collectors.toMap(DeviceStatusDto.Vo::getDeviceId, d -> d)); } for (DeviceInfoDto.MercHomeDeviceVo device : deviceInfos) { Long dId = device.getDeviceId(); //设备类型 反显 SysDictRedis dictDeviceType = SysDictUtils.get(DictConsts.DEVICE_TYPE, String.valueOf(device.getDeviceType())); device.setDeviceTypeName(dictDeviceType.getMsg()); //运营状态 反显 SysDictRedis dictBusyState = SysDictUtils.get(DictConsts.DEVICE_BUSY_STATUS, String.valueOf(device.getBusyState())); device.setBusyStateName(dictBusyState.getMsg()); DeviceDataDto.Vo deviceData = dataMap.get(dId); //今日销售、库存情况 反显 device.setDayOrderNum(deviceData != null ? deviceData.getSalesCount() : 0); device.setDaySalesPrice(deviceData != null ? deviceData.getSalesMoney() : 0); DeviceStatusDto.Vo deviceStatus = datdeviceStatusMap.get(device.getDeviceId()); Integer stock = Emptys.check(deviceStatus.getStock()) ? deviceStatus.getStock() : 0; device.setOnSaleNum(stock); Integer afterFillStock = Emptys.check(deviceStatus.getAfterFillStock()) ? deviceStatus.getAfterFillStock() : 0; device.setFillNum(afterFillStock); //联网状态 Integer netState = deviceStatus == null ? DeviceNetSateType.DISCONNECT.getCode() : deviceStatus.getNetState(); device.setNetState(netState); if (netState == null) { device.setNetStateName(StrUtil.EMPTY); } else { device.setNetStateName(DeviceNetSateType.getEnumByCode(deviceStatus.getNetState()).getDescription()); } } //在线排序 if (CollUtil.isNotEmpty(deviceInfos)) { deviceInfos = ListUtil.sortByProperty(deviceInfos, LambdaUtils.getProperty(DeviceInfoDto.MercHomeDeviceVo::getNetState)); } vo.setDeviceInfos(deviceInfos); dataList.add(vo); } return R.ok(dataList); } /** * 获取商户设备列表 * * @param mercId * @return */ private List getDevicesByMercId(Long mercId) { return list(Wrappers.lambdaQuery().eq(DeviceInfo::getMercId, mercId).eq(DeviceInfo::getActiveState, DeviceActiveStateEnum.TRUE.getCode())); } /** * 小程序商户设备搜索 * * @param page * @return */ @Override public R> mercDeviceSearchPage(@RequestBody DeviceInfoDto.Page page) { PageBean pageData = new PageBean<>(); //小程序独有查询字段 缺货状态:stockStatus ,是否查故障设备:fault Boolean fault = page.getFault(); Long mercId = page.getMercId(); List myDeviceIds = page.getDeviceIdList(); if (CollUtil.isEmpty(myDeviceIds)) { //无设备 return R.ok(pageData); } if (BooleanUtil.isTrue(fault)) { //查询故障设备 List deviceErrorsRecords = deviceErrorsRecordService.list(Wrappers.lambdaQuery() .eq(mercId != null, DeviceErrorsRecord::getMercId, page.getMercId()) .in(DeviceErrorsRecord::getDeviceId, myDeviceIds)); List deviceIdList = deviceErrorsRecords.stream().map(DeviceErrorsRecord::getDeviceId).collect(Collectors.toList()); if (CollUtil.isEmpty(deviceIdList)) { return R.ok(new PageBean<>()); } page.setDeviceIdList(deviceIdList); } else { page.setDeviceIdList(myDeviceIds); } PageBean pageBean = queryPage(page); List records = pageBean.getRecords(); if (CollUtil.isEmpty(records)) { return R.ok(pageData); } List merHomeSearchRecords = new ArrayList<>(); List deviceIds = records.stream().map(DeviceInfoDto.Vo2::getDeviceId).collect(Collectors.toList()); String type = SysDictUtils.getValue(DictEnum.DEVICE_DATA_TYPE.getKey(), DictSonEnum.DEVICE_DATA_TYPE_DAY.getKey(), String.class); String todayDate = DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN); //查询当天 DeviceDataDto.ListDTO dto = new DeviceDataDto.ListDTO() .setDeviceIds(deviceIds).setType(type).setDateValue(Integer.valueOf(todayDate)).setMercId(mercId); BeanUtil.copyProperties(pageBean, pageData); List deviceDataList = deviceDataService.list(dto); if (CollUtil.isNotEmpty(deviceDataList)) { //统计数据反显 Map dataMap = deviceDataList.stream().collect(Collectors.toMap(DeviceDataDto.Vo::getDeviceId, d -> d)); records.forEach(v -> { DeviceInfoDto.MerHomeSearchVO merHomeSearchVO = new DeviceInfoDto.MerHomeSearchVO(); Long deviceId = v.getDeviceId(); DeviceDataDto.Vo vo = dataMap.get(deviceId); //今日订单数 v.setDayOrderNum(vo != null ? vo.getSalesCount() : 0); v.setDaySalesPrice(vo != null ? vo.getSalesMoney() : 0); DeviceSysinfoDto.Vo deviceSysinfo = v.getDeviceSysinfo(); DeviceStatusDto.Vo deviceStatus = v.getDeviceStatus(); BeanUtil.copyProperties(vo, merHomeSearchVO); merHomeSearchVO.setAppUpmVersion(deviceSysinfo.getAppUpmVersion()); merHomeSearchVO.setTempValue(deviceStatus.getTempValue()); merHomeSearchVO.setNetDbm(deviceStatus.getNetDbm()); merHomeSearchRecords.add(merHomeSearchVO); }); pageData.setRecords(merHomeSearchRecords); } return R.ok(pageData); } /** * 小程序商户设备详情-数据统计 * * @param dto * @return */ @Override public R dataCount(@RequestBody DeviceInfoDto.DeviceDataCountDTO dto) { // 统计类型(1=经营数据,2=经营图表,3=温度图表,4=信号图表,5=商品管理) Integer type = dto.getType(); switch (type) { case 1: //经营数据 return R.ok(dataCount1(dto)); case 2: //经营图表 return R.ok(dataCount2(dto)); case 3: //温度图表 return R.ok(dataCount3(dto)); case 4: //信号图表 return R.ok(dataCount4(dto)); case 5: //商品管理 return R.ok(dataCount5(dto)); default: break; } return R.ok(); } /** * 经营数据 * * @param dto * @return */ private DeviceInfoDto.DeviceDataCountVO dataCount1(DeviceInfoDto.DeviceDataCountDTO dto) { Long deviceId = dto.getDeviceId(); Long mercId = dto.getMercId(); DeviceInfoDto.DeviceDataCountVO vo = new DeviceInfoDto.DeviceDataCountVO(); //当天 DeviceDataDto.Vo dayData = deviceDataService.getByDay(deviceId, mercId, DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN)); //当月 DeviceDataDto.Vo monthData = deviceDataService.getByMonth(deviceId, mercId, DateUtil.format(new Date(), DatePattern.SIMPLE_MONTH_PATTERN)); vo.setDayBusinessData(copy(DeviceInfoDto.BusinessData.class, dayData)); vo.setMonthBusinessData(copy(DeviceInfoDto.BusinessData.class, monthData)); return vo; } /** * 经营图表 * * @param dto * @return */ private DeviceInfoDto.DeviceDataCountVO dataCount2(DeviceInfoDto.DeviceDataCountDTO dto) { Long deviceId = dto.getDeviceId(); //近一个月 (销售额,订单数,退款金额,退款数) DeviceInfoDto.DeviceDataCountVO vo = new DeviceInfoDto.DeviceDataCountVO(); DeviceInfoDto.BusinessChart businessChart = new DeviceInfoDto.BusinessChart(); List categories = DataTime.dayListByLastDay(30); List dateList = new ArrayList<>(30); businessChart.setCategories(categories); categories.forEach(d -> { dateList.add(Integer.valueOf(d.replaceAll(StrUtil.DASHED, StrUtil.EMPTY))); }); Integer startDay = dateList.get(0); Integer endDay = dateList.get(categories.size() - 1); List listByDay = deviceDataService.getListByDay(deviceId, startDay, endDay); if (CollUtil.isEmpty(listByDay)) { return vo; } //每天的数据 Map dataDayMap = listByDay.stream().collect(Collectors.toMap(DeviceDataDto.Vo::getDateValue, i -> i)); List series = new ArrayList<>(); String[] names = {"销售额", "订单数", "退款金额", "退款数"}; for (int i = 0; i < names.length; i++) { DeviceInfoDto.MyChartSeries3 myChartSeries = new DeviceInfoDto.MyChartSeries3(); //某个类型每天的数据 List data = new ArrayList<>(); if (i == 0) { //销售额 dateList.forEach(d -> { //每日数据填充 DeviceDataDto.Vo deviceData = dataDayMap.get(d); if (deviceData == null) { data.add(String.valueOf(BigDecimal.ZERO)); } else { Integer salesMoney = deviceData.getSalesMoney() == null ? 0 : deviceData.getSalesMoney(); BigDecimal day = BigDecimal.valueOf(salesMoney).divide(BigDecimal.valueOf(100)); data.add(String.valueOf(day)); } }); } else if (i == 1) { //订单数 dateList.forEach(d -> { //每日数据填充 DeviceDataDto.Vo deviceData = dataDayMap.get(d); String value = "0"; if (deviceData == null) { data.add(value); } else { data.add(deviceData == null ? value : String.valueOf(deviceData.getSalesCount())); } }); } else if (i == 2) { //退款金额 dateList.forEach(d -> { //每日数据填充 DeviceDataDto.Vo deviceData = dataDayMap.get(d); if (deviceData == null) { data.add(String.valueOf(BigDecimal.ZERO)); } else { Integer refundMoney = deviceData.getRefundMoney() == null ? 0 : deviceData.getRefundMoney(); BigDecimal day = BigDecimal.valueOf(refundMoney).divide(BigDecimal.valueOf(100)); data.add(String.valueOf(day)); } }); } else if (i == 3) { //退款数 dateList.forEach(d -> { //每日数据填充 DeviceDataDto.Vo deviceData = dataDayMap.get(d); if (deviceData == null) { data.add("0"); } else { data.add(deviceData == null ? "0" : String.valueOf(deviceData.getRefundCount())); } }); } myChartSeries.setName(names[i]); myChartSeries.setData(data); series.add(myChartSeries); } businessChart.setSeries(series); vo.setBusinessChart(businessChart); return vo; } /** * 温度图表 * * @param dto * @return */ private DeviceInfoDto.DeviceDataCountVO dataCount3(DeviceInfoDto.DeviceDataCountDTO dto) { DeviceInfoDto.DeviceDataCountVO vo = new DeviceInfoDto.DeviceDataCountVO(); Long deviceId = dto.getDeviceId(); String choosDate = dto.getChoosDate(); if (StrUtil.isEmpty(choosDate)) { choosDate = DateUtil.formatDate(new Date()); } String startTime = choosDate + " 00:00:00"; String endTime = choosDate + " 23:59:59"; //查询选定日期的温度数据 List deviceTempRecords = deviceTempRecordsService.list(Wrappers.lambdaQuery() .eq(DeviceTempRecords::getDeviceId, deviceId).between(DeviceTempRecords::getCreateTime, startTime, endTime) .orderBy(true, true, DeviceTempRecords::getCreateTime)); if (CollUtil.isEmpty(deviceTempRecords)) { return vo; } DeviceInfoDto.TemperatureChart temperatureChart = new DeviceInfoDto.TemperatureChart(); List categories = new ArrayList<>(); String name = "温度"; List series = new ArrayList<>(); List data = new ArrayList<>(); deviceTempRecords.forEach(d -> { String tempValue = d.getTempValue(); LocalDateTime createTime = d.getCreateTime(); String time = DateUtil.format(createTime, "HH:mm:ss"); categories.add(time); data.add(NumberUtil.toBigDecimal(tempValue)); }); DeviceInfoDto.MyChartSeries2 myChartSeries = new DeviceInfoDto.MyChartSeries2(); myChartSeries.setName(name); myChartSeries.setData(data); series.add(myChartSeries); temperatureChart.setSeries(series); temperatureChart.setCategories(categories); vo.setTemperatureChart(temperatureChart); return vo; } /** * 信号图表 * * @param dto * @return */ private DeviceInfoDto.DeviceDataCountVO dataCount4(DeviceInfoDto.DeviceDataCountDTO dto) { DeviceInfoDto.DeviceDataCountVO vo = new DeviceInfoDto.DeviceDataCountVO(); Long deviceId = dto.getDeviceId(); String choosDate = dto.getChoosDate(); if (StrUtil.isEmpty(choosDate)) { choosDate = DateUtil.formatDate(new Date()); } String startTime = choosDate + " 00:00:00"; String endTime = choosDate + " 23:59:59"; //查询选定日期的温度数据 List deviceNetRecords = deviceNetRecordService.list(Wrappers.lambdaQuery() .eq(DeviceNetRecord::getDeviceId, deviceId).between(DeviceNetRecord::getCreateTime, startTime, endTime) .orderBy(true, true, DeviceNetRecord::getCreateTime)); if (CollUtil.isEmpty(deviceNetRecords)) { return vo; } DeviceInfoDto.SignalChart signalChart = new DeviceInfoDto.SignalChart(); List categories = new ArrayList<>(); String name = "信号"; List series = new ArrayList<>(); List data = new ArrayList<>(); deviceNetRecords.forEach(d -> { Integer value = d.getSimDbm(); LocalDateTime createTime = d.getCreateTime(); String time = DateUtil.format(createTime, "HH:mm:ss"); categories.add(time); data.add(value); }); DeviceInfoDto.MyChartSeries myChartSeries = new DeviceInfoDto.MyChartSeries(); myChartSeries.setName(name); myChartSeries.setData(data); series.add(myChartSeries); signalChart.setSeries(series); signalChart.setCategories(categories); vo.setSignalChart(signalChart); return vo; } /** * 商品管理 * * @param dto * @return */ private DeviceInfoDto.DeviceDataCountVO dataCount5(DeviceInfoDto.DeviceDataCountDTO dto) { Long deviceId = dto.getDeviceId(); DeviceInfoDto.DeviceDataCountVO vo = new DeviceInfoDto.DeviceDataCountVO(); DeviceStatus deviceStatus = deviceStatusService.getById(dto.getDeviceId()); DeviceInfoDto.GoodsData goodsData = copy(DeviceInfoDto.GoodsData.class, deviceStatus); //在售商品种类 //根据设备ID查商品id GoodsDeviceDto.SelectList selectList = new GoodsDeviceDto.SelectList(); selectList.setDeviceIds(CollUtil.newArrayList(deviceId)); R> r = R.feignCheck(goodsDeviceService.list(selectList)); List goodsDeviceList = r.getData(); goodsData.setCategoryNum(CollUtil.isNotEmpty(goodsDeviceList) ? goodsDeviceList.size() : 0); vo.setGoodsData(goodsData); return vo; } public PageBean queryPage(DeviceInfoDto.Page page) { IPage iPage = baseMapper.queryPage(toIPage(page.getPage()), page); return toPageBean(DeviceInfoDto.Vo2.class, iPage); } private void check(T value, T value2, String msg) { if (value.toString().equals(value2.toString())) { throw new CommRuntimeException(msg); } } }