Compare commits

...

15 Commits

Author SHA1 Message Date
76c0aa74f1 feat(property): 添加用电/水/气趋势分析功能 2025-08-28 01:21:12 +08:00
e61b56b05e feat(property): 添加自动抄表功能 2025-08-27 19:28:24 +08:00
eb1b2084b5 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/MeterRecordConsumer.java
2025-08-27 19:28:05 +08:00
4d76a4df45 feat(property): 添加自动抄表功能 2025-08-27 19:27:02 +08:00
368eea91e8 修改了水电抄表bug 2025-08-27 18:14:14 +08:00
816b90e9e1 修改了水电抄表bug 2025-08-27 18:07:27 +08:00
6133d7761d 修改了水电抄表bug 2025-08-27 18:03:49 +08:00
lxj
318da3f0ee Merge branch 'master' of http://47.109.37.87:3000/by2025/SmartParks
# Conflicts:
#	ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/RocketMqConstants.java
#	ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/FaceCaptureConsumer.java
#	ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/FaceCompareConsumer.java
2025-08-27 18:01:31 +08:00
lxj
3c8eb59165 rocketmq消费者组修改 2025-08-27 17:59:56 +08:00
3c480d92f0 修改了水电抄表bug 2025-08-27 17:58:28 +08:00
78d97e14ee refactor(rocketmq): 1 2025-08-27 15:46:17 +08:00
c2c1818ba6 refactor(rocketmq): 1 2025-08-27 15:43:27 +08:00
3ebc58f5e3 refactor(rocketmq): 手动装配rocketMQ 2025-08-26 21:02:38 +08:00
07b9e8b722 Merge remote-tracking branch 'origin/master' 2025-08-26 20:33:13 +08:00
b20828a800 feat(rocketmq): 添加仪表记录消费者和生产者服务 2025-08-26 20:32:51 +08:00
28 changed files with 708 additions and 48 deletions

View File

@@ -125,6 +125,11 @@
<artifactId>ruoyi-common-websocket</artifactId> <artifactId>ruoyi-common-websocket</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@@ -6,6 +6,7 @@ import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*; import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import org.dromara.common.core.domain.TreeNode;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit; import org.dromara.common.idempotent.annotation.RepeatSubmit;
@@ -103,4 +104,17 @@ public class TbMeterInfoController extends BaseController {
@PathVariable("ids") Long[] ids) { @PathVariable("ids") Long[] ids) {
return toAjax(tbMeterInfoService.deleteWithValidByIds(List.of(ids), true)); return toAjax(tbMeterInfoService.deleteWithValidByIds(List.of(ids), true));
} }
/**
* 生成 社区/建组/单元/楼栋/(水电气表)树结构
*
* @param meterType 水电气类型
*
* @return (水电气表)树结构
*/
@GetMapping("/tree/{meterType}")
public R<List<TreeNode<Long>>> queryMeterInfoTree(@PathVariable("meterType") Long meterType) {
return R.ok(tbMeterInfoService.queryMeterInfoTree(meterType));
}
} }

View File

@@ -103,4 +103,25 @@ public class TbMeterRecordController extends BaseController {
@PathVariable("ids") Long[] ids) { @PathVariable("ids") Long[] ids) {
return toAjax(tbMeterRecordService.deleteWithValidByIds(List.of(ids), true)); return toAjax(tbMeterRecordService.deleteWithValidByIds(List.of(ids), true));
} }
/**
* 获取用电/水/气趋势分析数据
*
* @param floorId 楼层id
* @param meterId 仪表id
* @param meterType 仪表类型
* @param day 日期
* @param month 月份
* @param year 年份
*/
@GetMapping("/trend")
public R<Void> getEnergyTrend(@RequestParam(required = false) String floorId,
@RequestParam(required = false) String meterId,
@RequestParam Long meterType,
@RequestParam String day,
@RequestParam String month,
@RequestParam String year) {
tbMeterRecordService.getEnergyTrend(floorId, meterId, meterType, day, month, year);
return R.ok();
}
} }

View File

@@ -47,7 +47,7 @@ public class TbLightInfoBo extends BaseEntity {
/** /**
* 楼层ID * 楼层ID
*/ */
@NotNull(message = "层ID不能为空", groups = {AddGroup.class, EditGroup.class}) @NotNull(message = "层ID不能为空", groups = {AddGroup.class, EditGroup.class})
private Long floorId; private Long floorId;
/** /**

View File

@@ -9,6 +9,8 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*; import jakarta.validation.constraints.*;
import java.math.BigDecimal;
/** /**
* 水电气业务对象 tb_meter_info * 水电气业务对象 tb_meter_info
* *
@@ -23,7 +25,7 @@ public class TbMeterInfoBo extends BaseEntity {
/** /**
* 主键id * 主键id
*/ */
@NotNull(message = "主键id不能为空", groups = { EditGroup.class }) @NotNull(message = "主键id不能为空", groups = {EditGroup.class})
private Long id; private Long id;
/** /**
@@ -44,15 +46,42 @@ public class TbMeterInfoBo extends BaseEntity {
/** /**
* 设备类型(1-电表2-水表3-气表) * 设备类型(1-电表2-水表3-气表)
*/ */
@NotNull(message = "设备类型(1-电表2-水表3-气表)不能为空", groups = { AddGroup.class, EditGroup.class }) @NotNull(message = "设备类型(1-电表2-水表3-气表)不能为空", groups = {AddGroup.class, EditGroup.class})
private Long meterType; private Long meterType;
/** /**
* 计量单位(1-度2-吨3-立方米) * 计量单位(1-度2-吨3-立方米)
*/ */
@NotNull(message = "计量单位(1-度2-吨3-立方米)不能为空", groups = { AddGroup.class, EditGroup.class }) @NotNull(message = "计量单位(1-度2-吨3-立方米)不能为空", groups = {AddGroup.class, EditGroup.class})
private Long meterUnit; private Long meterUnit;
/**
* 采集器IP
*/
@NotNull(message = "采集器IP不能为空", groups = {AddGroup.class, EditGroup.class})
private String hostIp;
/**
* 楼层ID
*/
@NotNull(message = "楼层ID不能为空", groups = {AddGroup.class, EditGroup.class})
private Long floorId;
/**
* 园区编码
*/
private Long communityId;
/**
* 建筑名称
*/
private Long buildingId;
/**
* 单元编码
*/
private Long unitId;
/** /**
* 安装位置 * 安装位置
*/ */
@@ -61,12 +90,12 @@ public class TbMeterInfoBo extends BaseEntity {
/** /**
* 初始读数 * 初始读数
*/ */
private Long initReading; private BigDecimal initReading;
/** /**
* 最大量程 * 最大量程
*/ */
private Long maxRang; private BigDecimal maxRang;
/** /**
* 通信状态 * 通信状态

View File

@@ -32,8 +32,8 @@ public class TbMeterRecordBo extends BaseEntity {
/** /**
* 仪表编号 * 仪表编号
*/ */
@NotBlank(message = "仪表编号不能为空", groups = { AddGroup.class, EditGroup.class }) @NotNull(message = "仪表编号不能为空", groups = { AddGroup.class, EditGroup.class })
private String meterId; private Long meterId;
/** /**
* 设备类型(1-电表2-水表3-气表) * 设备类型(1-电表2-水表3-气表)

View File

@@ -6,6 +6,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import java.io.Serial; import java.io.Serial;
import java.math.BigDecimal;
/** /**
* 水电气对象 tb_meter_info * 水电气对象 tb_meter_info
@@ -60,12 +61,12 @@ public class TbMeterInfo extends TenantEntity {
/** /**
* 初始读数 * 初始读数
*/ */
private Long initReading; private BigDecimal initReading;
/** /**
* 最大量程 * 最大量程
*/ */
private Long maxRang; private BigDecimal maxRang;
/** /**
* 通信状态 * 通信状态
@@ -82,5 +83,30 @@ public class TbMeterInfo extends TenantEntity {
*/ */
private String remark; private String remark;
/**
* 园区编码
*/
private Long communityId;
/**
* 建筑名称
*/
private Long buildingId;
/**
* 单元编码
*/
private Long unitId;
/**
* 所属楼层ID
*/
private Long floorId;
/**
* 采集器IP
*/
private String hostIp;
} }

View File

@@ -33,7 +33,7 @@ public class TbMeterRecord extends TenantEntity {
/** /**
* 仪表编号 * 仪表编号
*/ */
private String meterId; private Long meterId;
/** /**
* 设备类型(1-电表2-水表3-气表) * 设备类型(1-电表2-水表3-气表)

View File

@@ -0,0 +1,33 @@
package org.dromara.property.domain.enums;
import lombok.Getter;
/**
* @author lsm
* @apiNote MeterRecordTypeEnum
* @since 2025/8/27
*/
@Getter
public enum MeterRecordTypeEnum {
/**
* 手动上报
*/
MANUAL_RECORD(1L),
/**
* 自动上报
*/
AUTO_RECORD(2L),
/**
* 用户上报
*/
USER_RECORD(3L);
private final Long code;
MeterRecordTypeEnum(Long code) {
this.code = code;
}
}

View File

@@ -10,7 +10,7 @@ import lombok.Data;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal;
/** /**
@@ -54,7 +54,7 @@ public class TbMeterInfoVo implements Serializable {
/** /**
* 设备类型(1-电表2-水表3-气表) * 设备类型(1-电表2-水表3-气表)
*/ */
@ExcelProperty(value = "设备类型(1-电表2-水表3-气表)" ,converter = ExcelDictConvert.class) @ExcelProperty(value = "设备类型(1-电表2-水表3-气表)", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "meter_type") @ExcelDictFormat(dictType = "meter_type")
private Long meterType; private Long meterType;
@@ -75,13 +75,13 @@ public class TbMeterInfoVo implements Serializable {
* 初始读数 * 初始读数
*/ */
@ExcelProperty(value = "初始读数") @ExcelProperty(value = "初始读数")
private Long initReading; private BigDecimal initReading;
/** /**
* 最大量程 * 最大量程
*/ */
@ExcelProperty(value = "最大量程") @ExcelProperty(value = "最大量程")
private Long maxRang; private BigDecimal maxRang;
/** /**
* 通信状态 * 通信状态
@@ -97,6 +97,42 @@ public class TbMeterInfoVo implements Serializable {
@ExcelDictFormat(dictType = "sis_device_status") @ExcelDictFormat(dictType = "sis_device_status")
private Long runningState; private Long runningState;
/**
* 园区编码
*/
@ExcelProperty(value = "园区编码")
private Long communityId;
/**
* 建筑名称
*/
@ExcelProperty(value = "建筑名称")
private Long buildingId;
/**
* 单元编码
*/
@ExcelProperty(value = "单元编码")
private Long unitId;
/**
* 楼层ID
*/
@ExcelProperty(value = "楼层ID")
private Long floorId;
/**
* 楼层
*/
@ExcelProperty(value = "楼层")
private String floorName;
/**
* 采集器IP
*/
@ExcelProperty(value = "采集器IP")
private String hostIp;
/** /**
* 备注 * 备注
*/ */

View File

@@ -37,7 +37,7 @@ public class TbMeterRecordVo implements Serializable {
* 仪表编号 * 仪表编号
*/ */
@ExcelProperty(value = "仪表编号") @ExcelProperty(value = "仪表编号")
private String meterId; private Long meterId;
/** /**
* 设备类型(1-电表2-水表3-气表) * 设备类型(1-电表2-水表3-气表)

View File

@@ -1,5 +1,6 @@
package org.dromara.property.mapper.smartDevicesMapper; package org.dromara.property.mapper.smartDevicesMapper;
import org.apache.ibatis.annotations.Mapper;
import org.dromara.property.domain.entity.smartDevices.TbMeterInfo; import org.dromara.property.domain.entity.smartDevices.TbMeterInfo;
import org.dromara.property.domain.vo.smartDevicesVo.TbMeterInfoVo; import org.dromara.property.domain.vo.smartDevicesVo.TbMeterInfoVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
@@ -8,8 +9,9 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
* 水电气Mapper接口 * 水电气Mapper接口
* *
* @author lsm * @author lsm
* @date 2025-07-19 * @since 2025-07-19
*/ */
@Mapper
public interface TbMeterInfoMapper extends BaseMapperPlus<TbMeterInfo, TbMeterInfoVo> { public interface TbMeterInfoMapper extends BaseMapperPlus<TbMeterInfo, TbMeterInfoVo> {
} }

View File

@@ -1,10 +1,14 @@
package org.dromara.property.mapper.smartDevicesMapper; package org.dromara.property.mapper.smartDevicesMapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.dromara.property.domain.entity.smartDevices.TbMeterRecord; import org.dromara.property.domain.entity.smartDevices.TbMeterRecord;
import org.dromara.property.domain.vo.smartDevicesVo.TbMeterRecordVo; import org.dromara.property.domain.vo.smartDevicesVo.TbMeterRecordVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import java.util.List;
import java.util.Map;
/** /**
* 抄记录Mapper接口 * 抄记录Mapper接口
* *
@@ -14,4 +18,9 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
@Mapper @Mapper
public interface TbMeterRecordMapper extends BaseMapperPlus<TbMeterRecord, TbMeterRecordVo> { public interface TbMeterRecordMapper extends BaseMapperPlus<TbMeterRecord, TbMeterRecordVo> {
List<Map<String, Object>> getHourTrend(@Param("floorId") Long floorId, @Param("meterId") Long meterId, @Param("meterType") Long meterType, @Param("day") String day);
List<Map<String, Object>> getDayTrend(@Param("floorId") Long floorId, @Param("meterId") Long meterId, @Param("meterType") Long meterType, @Param("year") String year, @Param("month") String month);
List<Map<String, Object>> getMonthTrend(@Param("floorId") Long floorId, @Param("meterId") Long meterId, @Param("meterType") Long meterType, @Param("year") String year);
} }

View File

@@ -0,0 +1,18 @@
package org.dromara.property.rocketmq;
/**
* @author lsm
* @apiNote RocketMqConstants
* @since 2025/8/25
*/
public interface RocketMqConstants {
// mq topic
String TOPIC = "SmartParks";
// mq GROUP
String METER_GROUP = "METER_GROUP";
/*-----------------------------------消息tag------------------------------------*/
String METER_RECORD = "METER_RECORD_TAG";
}

View File

@@ -0,0 +1,45 @@
package org.dromara.property.rocketmq.consumer;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.dromara.property.rocketmq.RocketMqConstants;
import org.dromara.property.rocketmq.domain.MeterResult;
import org.dromara.property.service.smartDevicesService.ITbMeterRecordService;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author lsm
* @apiNote MeterRecordConsumer
* @since 2025/8/25
*/
@Slf4j
@Component
@RequiredArgsConstructor
@RocketMQMessageListener(
topic = RocketMqConstants.TOPIC,
consumerGroup = RocketMqConstants.METER_GROUP,
selectorExpression = RocketMqConstants.METER_RECORD
)
public class MeterRecordConsumer implements RocketMQListener<MessageExt> {
private final ITbMeterRecordService meterRecordService;
@Override
public void onMessage(MessageExt ext) {
log.info("消费仪表上报数据,数据长度={}", ext.getBody().length);
try {
List<MeterResult> meterResults = JSONUtil.toList(new String(ext.getBody()), MeterResult.class);
meterRecordService.autoWriteMeterRecord(meterResults);
} catch (Exception e) {
log.error("消费仪表上报数据处理失败,", e);
}
}
}

View File

@@ -0,0 +1,20 @@
package org.dromara.property.rocketmq.domain;
import lombok.Data;
import java.util.List;
/**
* @author lsm
* @apiNote MeterResult
* @since 2025/8/27
*/
@Data
public class MeterResult {
private String ip;
private String recordTime;
private List<Float> collectionValue;
}

View File

@@ -67,8 +67,8 @@ public class CustomerFeedbacksServiceImpl implements ICustomerFeedbacksService {
public CustomerFeedbacksVo queryById(Long id) { public CustomerFeedbacksVo queryById(Long id) {
CustomerFeedbacksVo customerFeedbacksVo = baseMapper.selectVoById(id); CustomerFeedbacksVo customerFeedbacksVo = baseMapper.selectVoById(id);
ServiceWorkOrdersType serviceWorkOrdersType = serviceWorkOrdersTypeMapper.selectById(customerFeedbacksVo.getFeedbackType()); ServiceWorkOrdersType serviceWorkOrdersType = serviceWorkOrdersTypeMapper.selectById(customerFeedbacksVo.getFeedbackType());
customerFeedbacksVo.setFeedbackTypeName(StringUtils.isNotBlank(serviceWorkOrdersType.getOrderTypeName()) ? serviceWorkOrdersType.getOrderTypeName() : null); customerFeedbacksVo.setFeedbackTypeName(ObjectUtil.isNotEmpty(serviceWorkOrdersType) ? serviceWorkOrdersType.getOrderTypeName() : null);
String nikName = remoteUserService.selectNicknameById(customerFeedbacksVo.getFeedbackPersion()); String nikName = remoteUserService.selectNicknameById(ObjectUtil.isNotEmpty(customerFeedbacksVo) ?customerFeedbacksVo.getFeedbackPersion():null);
customerFeedbacksVo.setFeedbackPersionName(nikName); customerFeedbacksVo.setFeedbackPersionName(nikName);
return customerFeedbacksVo; return customerFeedbacksVo;
} }
@@ -115,11 +115,11 @@ public class CustomerFeedbacksServiceImpl implements ICustomerFeedbacksService {
if (CollUtil.isNotEmpty(remoteUserVos)) { if (CollUtil.isNotEmpty(remoteUserVos)) {
RemoteUserVo remoteUserVo = remoteUserVos.stream() RemoteUserVo remoteUserVo = remoteUserVos.stream()
.filter(vo -> vo.getUserId() != null && vo.getUserId().equals(customerFeedbacksVo.getFeedbackPersion())).findFirst().orElse(null); .filter(vo -> vo.getUserId() != null && vo.getUserId().equals(customerFeedbacksVo.getFeedbackPersion())).findFirst().orElse(null);
customerFeedbacksVo.setFeedbackPersionName(ObjectUtil.isNotNull(remoteUserVo) ? remoteUserVo.getNickName() : null); customerFeedbacksVo.setFeedbackPersionName(ObjectUtil.isNotEmpty(remoteUserVo) ? remoteUserVo.getNickName() : null);
} }
if (CollUtil.isNotEmpty(serviceWorkOrdersTypes)) { if (CollUtil.isNotEmpty(serviceWorkOrdersTypes)) {
ServiceWorkOrdersType serviceWorkOrdersType = serviceWorkOrdersTypes.stream().filter(vo -> vo.getId() != null && vo.getId().equals(customerFeedbacksVo.getFeedbackType())).findFirst().orElse(null); ServiceWorkOrdersType serviceWorkOrdersType = serviceWorkOrdersTypes.stream().filter(vo -> vo.getId() != null && vo.getId().equals(customerFeedbacksVo.getFeedbackType())).findFirst().orElse(null);
customerFeedbacksVo.setFeedbackTypeName(ObjectUtil.isNotNull(serviceWorkOrdersType) ? serviceWorkOrdersType.getOrderTypeName() : null); customerFeedbacksVo.setFeedbackTypeName(ObjectUtil.isNotEmpty(serviceWorkOrdersType) ? serviceWorkOrdersType.getOrderTypeName() : null);
} }
} }

View File

@@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.property.domain.bo.TbFloorBo;
import org.dromara.property.domain.vo.TbFloorVo; import org.dromara.property.domain.vo.TbFloorVo;
import org.dromara.property.service.ITbFloorService; import org.dromara.property.service.ITbFloorService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -23,6 +24,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Collection; import java.util.Collection;
import java.util.stream.Collectors;
/** /**
* 灯控开关信息Service业务层处理 * 灯控开关信息Service业务层处理
@@ -60,7 +62,19 @@ public class TbLightInfoServiceImpl implements ITbLightInfoService {
public TableDataInfo<TbLightInfoVo> queryPageList(TbLightInfoBo bo, PageQuery pageQuery) { public TableDataInfo<TbLightInfoVo> queryPageList(TbLightInfoBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<TbLightInfo> lqw = buildQueryWrapper(bo); LambdaQueryWrapper<TbLightInfo> lqw = buildQueryWrapper(bo);
Page<TbLightInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); Page<TbLightInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
result.getRecords().forEach(r -> r.setFloorName(floorService.queryById(r.getFloorId()).getFloorName()));
// 创建楼层ID到楼层名称的映射避免重复查询
List<TbFloorVo> floorVo = floorService.queryList(new TbFloorBo());
Map<Long, String> floorMap = floorVo.stream()
.collect(Collectors.toMap(TbFloorVo::getId, TbFloorVo::getFloorName, (key1, key2) -> key1));
// 为每个灯控信息设置楼层名称
result.getRecords().forEach(record -> {
String floorName = floorMap.get(record.getFloorId());
if (floorName != null) {
record.setFloorName(floorName);
}
});
return TableDataInfo.build(result); return TableDataInfo.build(result);
} }
@@ -151,7 +165,7 @@ public class TbLightInfoServiceImpl implements ITbLightInfoService {
*/ */
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Boolean switchSingleLight(TbLightInfoBo bo){ public Boolean switchSingleLight(TbLightInfoBo bo) {
TbLightInfo update = MapstructUtils.convert(bo, TbLightInfo.class); TbLightInfo update = MapstructUtils.convert(bo, TbLightInfo.class);
boolean flag = baseMapper.updateById(update) > 0; boolean flag = baseMapper.updateById(update) > 0;
Assert.isTrue(flag, "修改灯开关失败"); Assert.isTrue(flag, "修改灯开关失败");

View File

@@ -1,7 +1,10 @@
package org.dromara.property.service.impl.smartDevicesImpl; package org.dromara.property.service.impl.smartDevicesImpl;
import cn.hutool.core.lang.Assert;
import org.dromara.common.core.domain.TreeNode;
import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.TreeUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -9,16 +12,28 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.property.domain.bo.TbFloorBo;
import org.dromara.property.domain.vo.TbBuildingVo;
import org.dromara.property.domain.vo.TbCommunityVo;
import org.dromara.property.domain.vo.TbFloorVo;
import org.dromara.property.service.ITbBuildingService;
import org.dromara.property.service.ITbCommunityService;
import org.dromara.property.service.ITbFloorService;
import org.dromara.system.api.model.LoginUser;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.dromara.property.domain.bo.smartDevicesBo.TbMeterInfoBo; import org.dromara.property.domain.bo.smartDevicesBo.TbMeterInfoBo;
import org.dromara.property.domain.vo.smartDevicesVo.TbMeterInfoVo; import org.dromara.property.domain.vo.smartDevicesVo.TbMeterInfoVo;
import org.dromara.property.domain.entity.smartDevices.TbMeterInfo; import org.dromara.property.domain.entity.smartDevices.TbMeterInfo;
import org.dromara.property.mapper.smartDevicesMapper.TbMeterInfoMapper; import org.dromara.property.mapper.smartDevicesMapper.TbMeterInfoMapper;
import org.dromara.property.service.smartDevicesService.ITbMeterInfoService; import org.dromara.property.service.smartDevicesService.ITbMeterInfoService;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Collection; import java.util.Collection;
import java.util.stream.Collectors;
/** /**
* 水电气Service业务层处理 * 水电气Service业务层处理
@@ -27,11 +42,14 @@ import java.util.Collection;
* @since 2025-07-19 * @since 2025-07-19
*/ */
@Slf4j @Slf4j
@RequiredArgsConstructor
@Service @Service
@RequiredArgsConstructor
public class TbMeterInfoServiceImpl implements ITbMeterInfoService { public class TbMeterInfoServiceImpl implements ITbMeterInfoService {
private final TbMeterInfoMapper baseMapper; private final TbMeterInfoMapper baseMapper;
private final ITbFloorService floorService;
private final ITbBuildingService buildingService;
private final ITbCommunityService communityService;
/** /**
* 查询水电气 * 查询水电气
@@ -40,7 +58,7 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService {
* @return 水电气 * @return 水电气
*/ */
@Override @Override
public TbMeterInfoVo queryById(Long id){ public TbMeterInfoVo queryById(Long id) {
return baseMapper.selectVoById(id); return baseMapper.selectVoById(id);
} }
@@ -55,6 +73,19 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService {
public TableDataInfo<TbMeterInfoVo> queryPageList(TbMeterInfoBo bo, PageQuery pageQuery) { public TableDataInfo<TbMeterInfoVo> queryPageList(TbMeterInfoBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<TbMeterInfo> lqw = buildQueryWrapper(bo); LambdaQueryWrapper<TbMeterInfo> lqw = buildQueryWrapper(bo);
Page<TbMeterInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); Page<TbMeterInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
// 创建楼层ID到楼层名称的映射避免重复查询
List<TbFloorVo> floorList = floorService.queryList(new TbFloorBo());
Map<Long, String> floorMap = floorList.stream()
.collect(Collectors.toMap(TbFloorVo::getId, TbFloorVo::getFloorName, (key1, key2) -> key1));
// 为每个灯控信息设置楼层名称
result.getRecords().forEach(record -> {
String floorName = floorMap.get(record.getFloorId());
if (floorName != null) {
record.setFloorName(floorName);
}
});
return TableDataInfo.build(result); return TableDataInfo.build(result);
} }
@@ -74,6 +105,7 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService {
Map<String, Object> params = bo.getParams(); Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<TbMeterInfo> lqw = Wrappers.lambdaQuery(); LambdaQueryWrapper<TbMeterInfo> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(TbMeterInfo::getId); lqw.orderByAsc(TbMeterInfo::getId);
lqw.like(StringUtils.isNotBlank(bo.getHostIp()), TbMeterInfo::getHostIp, bo.getHostIp());
lqw.like(StringUtils.isNotBlank(bo.getMeterName()), TbMeterInfo::getMeterName, bo.getMeterName()); lqw.like(StringUtils.isNotBlank(bo.getMeterName()), TbMeterInfo::getMeterName, bo.getMeterName());
lqw.eq(StringUtils.isNotBlank(bo.getMeterCode()), TbMeterInfo::getMeterCode, bo.getMeterCode()); lqw.eq(StringUtils.isNotBlank(bo.getMeterCode()), TbMeterInfo::getMeterCode, bo.getMeterCode());
lqw.eq(StringUtils.isNotBlank(bo.getFactoryNo()), TbMeterInfo::getFactoryNo, bo.getFactoryNo()); lqw.eq(StringUtils.isNotBlank(bo.getFactoryNo()), TbMeterInfo::getFactoryNo, bo.getFactoryNo());
@@ -94,13 +126,15 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService {
* @return 是否新增成功 * @return 是否新增成功
*/ */
@Override @Override
@Transactional(rollbackFor = Exception.class)
public Boolean insertByBo(TbMeterInfoBo bo) { public Boolean insertByBo(TbMeterInfoBo bo) {
TbMeterInfo add = MapstructUtils.convert(bo, TbMeterInfo.class); TbMeterInfo add = MapstructUtils.convert(bo, TbMeterInfo.class);
validEntityBeforeSave(add); assert add != null;
TbFloorVo floor = floorService.queryById(add.getFloorId());
add.setBuildingId(floor.getBuildingId());
add.setCommunityId(floor.getCommunityId());
boolean flag = baseMapper.insert(add) > 0; boolean flag = baseMapper.insert(add) > 0;
if (flag) { Assert.isTrue(flag, "新增水电气信息失败");
bo.setId(add.getId());
}
return flag; return flag;
} }
@@ -120,7 +154,7 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService {
/** /**
* 保存前的数据校验 * 保存前的数据校验
*/ */
private void validEntityBeforeSave(TbMeterInfo entity){ private void validEntityBeforeSave(TbMeterInfo entity) {
//TODO 做一些数据校验,如唯一约束 //TODO 做一些数据校验,如唯一约束
} }
@@ -133,9 +167,76 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService {
*/ */
@Override @Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){ if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验 //TODO 做一些业务上的校验,判断是否需要校验
} }
return baseMapper.deleteByIds(ids) > 0; return baseMapper.deleteByIds(ids) > 0;
} }
/**
* 查询水电气树结构
*
* @param meterType 水电气类型
* @return 水电气树结构
*/
@Override
public List<TreeNode<Long>> queryMeterInfoTree(Long meterType) {
// 默认加载社区树
List<TreeNode<Long>> treeList = new ArrayList<>();
List<TbCommunityVo> tbCommunityVos = communityService.queryAll();
if (tbCommunityVos == null || tbCommunityVos.isEmpty()) {
return treeList;
}
List<TreeNode<Long>> l1 = tbCommunityVos.stream().map(item -> {
TreeNode<Long> node = new TreeNode<>();
node.setLevel(1);
node.setCode(item.getId());
node.setParentCode(0L);
node.setLabel(item.getCommunityName());
return node;
}).toList();
treeList.addAll(l1);
List<TbBuildingVo> tbBuildingVos = buildingService.queryAll();
if (tbBuildingVos == null || tbBuildingVos.isEmpty()) {
return treeList;
}
List<TreeNode<Long>> l2 = tbBuildingVos.stream().map(item -> {
TreeNode<Long> node = new TreeNode<>();
node.setLevel(2);
node.setCode(item.getId());
node.setParentCode(item.getCommunityId());
node.setLabel(item.getBuildingName());
return node;
}).toList();
treeList.addAll(l2);
List<TbFloorVo> tbFloorVos = floorService.queryAll();
if (tbFloorVos == null || tbFloorVos.isEmpty()) {
return treeList;
}
List<TreeNode<Long>> l3 = tbFloorVos.stream().map(item -> {
TreeNode<Long> node = new TreeNode<>();
node.setLevel(3);
node.setCode(item.getId());
node.setParentCode(item.getBuildingId());
node.setLabel(item.getFloorName());
return node;
}).toList();
treeList.addAll(l3);
TbMeterInfoBo bo = new TbMeterInfoBo();
bo.setMeterType(meterType);
List<TbMeterInfoVo> meterInfoVos = this.queryList(bo);
if (meterInfoVos != null && !meterInfoVos.isEmpty()) {
List<TreeNode<Long>> l4 = meterInfoVos.stream().map(item -> {
TreeNode<Long> node = new TreeNode<>();
node.setLevel(4);
node.setCode(item.getId());
node.setParentCode(item.getFloorId());
node.setLabel(item.getMeterName());
return node;
}).toList();
treeList.addAll(l4);
}
return TreeUtils.build(treeList, 0L);
}
} }

View File

@@ -1,7 +1,10 @@
package org.dromara.property.service.impl.smartDevicesImpl; package org.dromara.property.service.impl.smartDevicesImpl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -9,22 +12,29 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.property.domain.bo.smartDevicesBo.TbMeterInfoBo;
import org.dromara.property.domain.enums.MeterRecordTypeEnum;
import org.dromara.property.domain.vo.smartDevicesVo.TbMeterInfoVo;
import org.dromara.property.rocketmq.domain.MeterResult;
import org.dromara.property.service.smartDevicesService.ITbMeterInfoService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.dromara.property.domain.bo.smartDevicesBo.TbMeterRecordBo; import org.dromara.property.domain.bo.smartDevicesBo.TbMeterRecordBo;
import org.dromara.property.domain.vo.smartDevicesVo.TbMeterRecordVo; import org.dromara.property.domain.vo.smartDevicesVo.TbMeterRecordVo;
import org.dromara.property.domain.entity.smartDevices.TbMeterRecord; import org.dromara.property.domain.entity.smartDevices.TbMeterRecord;
import org.dromara.property.mapper.smartDevicesMapper.TbMeterRecordMapper; import org.dromara.property.mapper.smartDevicesMapper.TbMeterRecordMapper;
import org.dromara.property.service.smartDevicesService.ITbMeterRecordService; import org.dromara.property.service.smartDevicesService.ITbMeterRecordService;
import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.math.BigDecimal;
import java.util.Map; import java.util.*;
import java.util.Collection; import java.util.function.Function;
import java.util.stream.Collectors;
/** /**
* 抄记录Service业务层处理 * 抄记录Service业务层处理
* *
* @author lsm * @author lsm
* @date 2025-07-19 * @since 2025-07-19
*/ */
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
@@ -32,6 +42,7 @@ import java.util.Collection;
public class TbMeterRecordServiceImpl implements ITbMeterRecordService { public class TbMeterRecordServiceImpl implements ITbMeterRecordService {
private final TbMeterRecordMapper baseMapper; private final TbMeterRecordMapper baseMapper;
private final ITbMeterInfoService tbMeterInfoService;
/** /**
* 查询抄记录 * 查询抄记录
@@ -40,7 +51,7 @@ public class TbMeterRecordServiceImpl implements ITbMeterRecordService {
* @return 抄记录 * @return 抄记录
*/ */
@Override @Override
public TbMeterRecordVo queryById(Long id){ public TbMeterRecordVo queryById(Long id) {
return baseMapper.selectVoById(id); return baseMapper.selectVoById(id);
} }
@@ -74,7 +85,7 @@ public class TbMeterRecordServiceImpl implements ITbMeterRecordService {
Map<String, Object> params = bo.getParams(); Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<TbMeterRecord> lqw = Wrappers.lambdaQuery(); LambdaQueryWrapper<TbMeterRecord> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(TbMeterRecord::getId); lqw.orderByAsc(TbMeterRecord::getId);
lqw.eq(StringUtils.isNotBlank(bo.getMeterId()), TbMeterRecord::getMeterId, bo.getMeterId()); lqw.eq(bo.getMeterId() != null, TbMeterRecord::getMeterId, bo.getMeterId());
lqw.eq(bo.getMeterType() != null, TbMeterRecord::getMeterType, bo.getMeterType()); lqw.eq(bo.getMeterType() != null, TbMeterRecord::getMeterType, bo.getMeterType());
lqw.eq(bo.getReaderId() != null, TbMeterRecord::getReaderId, bo.getReaderId()); lqw.eq(bo.getReaderId() != null, TbMeterRecord::getReaderId, bo.getReaderId());
lqw.eq(bo.getReadingTime() != null, TbMeterRecord::getReadingTime, bo.getReadingTime()); lqw.eq(bo.getReadingTime() != null, TbMeterRecord::getReadingTime, bo.getReadingTime());
@@ -118,7 +129,7 @@ public class TbMeterRecordServiceImpl implements ITbMeterRecordService {
/** /**
* 保存前的数据校验 * 保存前的数据校验
*/ */
private void validEntityBeforeSave(TbMeterRecord entity){ private void validEntityBeforeSave(TbMeterRecord entity) {
//TODO 做一些数据校验,如唯一约束 //TODO 做一些数据校验,如唯一约束
} }
@@ -131,9 +142,108 @@ public class TbMeterRecordServiceImpl implements ITbMeterRecordService {
*/ */
@Override @Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){ if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验 //TODO 做一些业务上的校验,判断是否需要校验
} }
return baseMapper.deleteByIds(ids) > 0; return baseMapper.deleteByIds(ids) > 0;
} }
/**
* 自动写入抄表记录
*
* @param results 推送消息
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void autoWriteMeterRecord(List<MeterResult> results) {
log.info("自动写入抄表记录, msg:{}", results);
for (MeterResult result : results) {
// 取出同一个采集器ip下所有设备
TbMeterInfoBo infoBo = new TbMeterInfoBo();
infoBo.setHostIp(result.getIp());
List<TbMeterInfoVo> infoList = tbMeterInfoService.queryList(infoBo);
if (CollUtil.isEmpty(infoList)) {
log.info("当前采集器ip下无设备, ip:{}", result.getIp());
continue;
}
// 获取设备id
Collection<Long> meterIds = infoList.stream().map(TbMeterInfoVo::getId).toList();
// 取出上次抄表记录
LambdaQueryWrapper<TbMeterRecord> lqw = new LambdaQueryWrapper<>();
lqw.in(TbMeterRecord::getMeterId, meterIds)
.orderByDesc(TbMeterRecord::getReadingTime)
.last("limit " + meterIds.size());
List<TbMeterRecord> recordOld = baseMapper.selectList(lqw);
List<TbMeterRecord> recordNew = new ArrayList<>(infoList.size());
boolean hasOldRecords = CollUtil.isNotEmpty(recordOld);
log.info("当前采集器ip下{}抄表记录, ip:{}", hasOldRecords ? "" : "", result.getIp());
// 创建meterId到旧记录的映射提高查找效率
Map<Long, TbMeterRecord> oldRecordMap = hasOldRecords ?
recordOld.stream().collect(Collectors.toMap(TbMeterRecord::getMeterId, Function.identity())) :
Collections.emptyMap();
for (TbMeterInfoVo info : infoList) {
TbMeterRecord record = new TbMeterRecord();
record.setMeterId(info.getId());
record.setMeterType(info.getMeterType());
record.setReaderId(1L);
record.setReadingTime(DateUtil.parse(result.getRecordTime(), "yyyy-MM-dd HH:mm:ss"));
// 获取当前读数
BigDecimal currentReading = BigDecimal.valueOf(
result.getCollectionValue().get(Integer.parseInt(info.getMeterCode()))
);
record.setCurrentReading(currentReading);
// 设置上次读数
if (hasOldRecords) {
TbMeterRecord oldRecord = oldRecordMap.get(info.getId());
if (oldRecord != null) {
record.setPreviousReading(oldRecord.getCurrentReading());
} else {
// 如果没有找到对应的旧记录,使用默认值
record.setPreviousReading(BigDecimal.ZERO);
}
} else {
record.setPreviousReading(BigDecimal.ZERO);
}
record.setReadingMethod(MeterRecordTypeEnum.AUTO_RECORD.getCode());
recordNew.add(record);
}
boolean flag = baseMapper.insertBatch(recordNew);
Assert.isTrue(flag, "批量写入抄表记录失败!");
}
}
/**
* 获取用电/水/气趋势分析数据
*
* @param floorId 楼层id
* @param meterId 仪表id
* @param meterType 仪表类型
* @param day 日期
* @param month 月份
* @param year 年份
*/
@Override
public void getEnergyTrend(String floorId, String meterId, Long meterType, String day, String month, String year) {
List<Map<String, Object>> hourList = baseMapper.getHourTrend(StrUtil.isBlank(floorId) ? null : Long.parseLong(floorId), StrUtil.isBlank(meterId) ? null : Long.parseLong(meterId), meterType, day);
log.info("小时数据:{}", hourList);
String[] monthArr = month.split("-");
List<Map<String, Object>> dayList = baseMapper.getDayTrend(StrUtil.isBlank(floorId) ? null : Long.parseLong(floorId), StrUtil.isBlank(meterId) ? null : Long.parseLong(meterId), meterType, monthArr[0], monthArr[1]);
log.info("天数据:{}", dayList);
List<Map<String, Object>> monthList = baseMapper.getMonthTrend(StrUtil.isBlank(floorId) ? null : Long.parseLong(floorId), StrUtil.isBlank(meterId) ? null : Long.parseLong(meterId), meterType, year);
log.info("月数据:{}", monthList);
}
} }

View File

@@ -1,5 +1,6 @@
package org.dromara.property.service.smartDevicesService; package org.dromara.property.service.smartDevicesService;
import org.dromara.common.core.domain.TreeNode;
import org.dromara.property.domain.vo.smartDevicesVo.TbMeterInfoVo; import org.dromara.property.domain.vo.smartDevicesVo.TbMeterInfoVo;
import org.dromara.property.domain.bo.smartDevicesBo.TbMeterInfoBo; import org.dromara.property.domain.bo.smartDevicesBo.TbMeterInfoBo;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -65,4 +66,13 @@ public interface ITbMeterInfoService {
* @return 是否删除成功 * @return 是否删除成功
*/ */
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 查询水电气树结构
*
* @param meterType 水电气类型
*
* @return 水电气树结构
*/
List<TreeNode<Long>> queryMeterInfoTree(Long meterType);
} }

View File

@@ -4,6 +4,7 @@ import org.dromara.property.domain.vo.smartDevicesVo.TbMeterRecordVo;
import org.dromara.property.domain.bo.smartDevicesBo.TbMeterRecordBo; import org.dromara.property.domain.bo.smartDevicesBo.TbMeterRecordBo;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.property.rocketmq.domain.MeterResult;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@@ -65,4 +66,23 @@ public interface ITbMeterRecordService {
* @return 是否删除成功 * @return 是否删除成功
*/ */
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 自动写入抄表记录
*
* @param results 推送消息
*/
void autoWriteMeterRecord(List<MeterResult> results);
/**
* 获取用电/水/气趋势分析数据
*
* @param floorId 楼层id
* @param meterId 仪表id
* @param meterType 仪表类型
* @param day 日期
* @param month 月份
* @param year 年份
*/
void getEnergyTrend(String floorId, String meterId, Long meterType, String day, String month, String year);
} }

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.property.mapper.smartDevicesMapper.TbMeterRecordMapper">
<select id="getHourTrend" resultType="map">
SELECT CONCAT_WS(':', HOUR(reading_time), '00') as hour, SUM(consumption) as total_consumption
FROM tb_meter_record a
LEFT JOIN tb_meter_info b ON a.meter_id = b.id
WHERE DATE(reading_time) = #{day}
AND b.meter_type = #{meterType}
<if test="floorId != '' and floorId != null">
AND b.floor_id = #{floorId}
</if>
<if test="meterId != '' and meterId != null">
AND a.meter_id = #{meterId}
</if>
GROUP BY CONCAT_WS(':', HOUR(reading_time), '00')
ORDER BY hour
</select>
<select id="getDayTrend" resultType="map">
SELECT
DAY(reading_time) AS `day`,
SUM(consumption) AS total_consumption
FROM tb_meter_record a
LEFT JOIN tb_meter_info b ON a.meter_id = b.id
WHERE YEAR(reading_time) = #{year}
AND MONTH(reading_time) = #{month}
AND b.meter_type = #{meterType}
<if test="floorId != '' and floorId != null">
AND b.floor_id = #{floorId}
</if>
<if test="meterId != '' and meterId != null">
AND a.meter_id = #{meterId}
</if>
GROUP BY DAY(reading_time)
ORDER BY `day`;
</select>
<select id="getMonthTrend" resultType="map">
SELECT
MONTH(reading_time) AS `month`,
SUM(consumption) AS total_consumption
FROM tb_meter_record a
LEFT JOIN tb_meter_info b ON a.meter_id = b.id
WHERE YEAR(reading_time) = #{year}
AND b.meter_type = #{meterType}
<if test="floorId != '' and floorId != null">
AND b.floor_id = #{floorId}
</if>
<if test="meterId != '' and meterId != null">
AND a.meter_id = #{meterId}
</if>
GROUP BY MONTH(reading_time)
ORDER BY `month`;
</select>
</mapper>

View File

@@ -0,0 +1,85 @@
package org.dromara.sis.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import lombok.RequiredArgsConstructor;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.sis.domain.bo.SisPersonLibImgBo;
import org.dromara.sis.domain.vo.SisPersonLibImgVo;
import org.dromara.sis.sdk.e8.E8PlatformApi;
import org.dromara.sis.sdk.e8.domain.QueryDto;
import org.dromara.sis.sdk.e8.domain.accessControl.req.AccessRecordFindReq;
import org.dromara.sis.sdk.e8.domain.accessControl.res.AccessRecordFindRes;
import org.dromara.sis.service.ISisPersonLibImgService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author yuyongle
* @version 1.0
* @description:
* @date 2025/8/27 15:57
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/visitor")
public class SisVisitorController {
private final E8PlatformApi e8PlatformApi;
/**
* 查询人员通行记录
*/
@GetMapping("/list")
public TableDataInfo<AccessRecordFindRes> list(QueryDto dto) {
TableDataInfo tableDataInfo = new TableDataInfo();
List<AccessRecordFindRes> accessRecordFindResList = new ArrayList<>();
AccessRecordFindRes accessRecordFindRes = new AccessRecordFindRes();
accessRecordFindRes.setDeviceName("4#岗亭09");
accessRecordFindRes.setDoorName("4#岗亭09");
accessRecordFindRes.setDeviceType(1102);
accessRecordFindRes.setReaderName("");
accessRecordFindRes.setGatewayType(1);
accessRecordFindRes.setCustomerName("德隆吴鹏");
accessRecordFindRes.setOrganFullPath("主楼11楼");
accessRecordFindRes.setPictureUrl("https://bpic.588ku.com/back_list_pic/23/04/21/ef5e2a3dd5cfc336fdcf2fd000474f0f.jpg");
accessRecordFindRes.setCardType(34);
accessRecordFindRes.setRecordType(2);
accessRecordFindRes.setActionTime(new Date());
accessRecordFindResList.add(accessRecordFindRes);
tableDataInfo.setRows(accessRecordFindResList);
tableDataInfo.setTotal(1);
tableDataInfo.setCode(200);
return tableDataInfo;
//
// dto.setPageIndex(1);
// dto.setMaxResultCount(20);
//
// // 10秒内
// String starTime = DateUtil.format(DateUtil.offset(new Date(), DateField.SECOND, -10), "yyyy-MM-dd HH:mm:ss");
// String endTime = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");
//
// AccessRecordFindReq lift = new AccessRecordFindReq();
// lift.setStartTime(starTime);
// lift.setEndTime(endTime);
// lift.setRecordType(2);
// // 9号电梯
// lift.setDeviceId(550757939925061L);
// dto.setQueryDto(lift);
//// TableDataInfo<AccessRecordFindRes> nineLiftList = e8PlatformApi.getPageAccessRecordList(dto);
// TableDataInfo<AccessRecordFindRes> pageAccessRecordList = new TableDataInfo();
//
// return e8PlatformApi.getPageAccessRecordList(dto);
//如果pageAccessRecordList报错就捕获并封装
}
}

View File

@@ -9,8 +9,10 @@ public interface RocketMqConstants {
// mq topic // mq topic
String TOPIC = "SmartParks"; String TOPIC = "SmartParks";
// mq GROUP // 人比比对消费者组
String GROUP = "SmartParksEqp"; String COMPAREGROUP = "SmartParks-compare";
// 人脸抓拍消费者组
String CAPTUREGROUP = "SmartParks-capture";
/*-----------------------------------消息tag------------------------------------*/ /*-----------------------------------消息tag------------------------------------*/
String HIKADD = "ADD_HIK_DEVICE_TAG"; String HIKADD = "ADD_HIK_DEVICE_TAG";

View File

@@ -22,7 +22,7 @@ import org.springframework.stereotype.Component;
@RequiredArgsConstructor @RequiredArgsConstructor
@RocketMQMessageListener( @RocketMQMessageListener(
topic = RocketMqConstants.TOPIC, topic = RocketMqConstants.TOPIC,
consumerGroup = RocketMqConstants.GROUP, consumerGroup = RocketMqConstants.CAPTUREGROUP,
selectorExpression = RocketMqConstants.FACECAPTURE selectorExpression = RocketMqConstants.FACECAPTURE
) )
public class FaceCaptureConsumer implements RocketMQListener<MessageExt> { public class FaceCaptureConsumer implements RocketMQListener<MessageExt> {

View File

@@ -21,7 +21,7 @@ import org.springframework.stereotype.Component;
@RequiredArgsConstructor @RequiredArgsConstructor
@RocketMQMessageListener( @RocketMQMessageListener(
topic = RocketMqConstants.TOPIC, topic = RocketMqConstants.TOPIC,
consumerGroup = RocketMqConstants.GROUP, consumerGroup = RocketMqConstants.COMPAREGROUP,
selectorExpression = RocketMqConstants.FACECOMPARE selectorExpression = RocketMqConstants.FACECOMPARE
) )
public class FaceCompareConsumer implements RocketMQListener<MessageExt> { public class FaceCompareConsumer implements RocketMQListener<MessageExt> {

View File

@@ -40,9 +40,9 @@ spring.sql.init.platform=mysql
db.num=1 db.num=1
### Connect URL of DB: ### Connect URL of DB:
db.url.0=jdbc:mysql://192.168.159.129:3306/ry-config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true db.url.0=jdbc:mysql://113.249.101.254:18000/ry-config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
db.user.0=root db.user.0=root
db.password.0=123456 db.password.0=by@2025??
### the maximum retry times for push ### the maximum retry times for push
nacos.config.push.maxRetryTime=50 nacos.config.push.maxRetryTime=50