提交 6411c95b 作者: 涂茂林

feat:围栏报警数据推送记录

上级 e54fde30
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.constant.alarm;
import com.yiring.app.vo.CodeNameVo;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
/**
* 接受状态枚举
* @author tml
* @version 1.0
* @date 2022/5/18 9:37
*/
public enum ReceiveStatusEnum {
/**
* 成功
*/
SUCCESS(1, "成功"),
/**
* 失败
*/
FAIL(2, "失败");
private static final List<CodeNameVo> LIST;
static {
LIST = new ArrayList<>();
for (ReceiveStatusEnum item : values()) {
LIST.add(new CodeNameVo(item.getCode(), item.name));
}
}
@Getter
private final int code;
@Getter
private final String name;
ReceiveStatusEnum(Integer code, String name) {
this.code = code;
this.name = name;
}
public static String getByCode(int code) {
for (ReceiveStatusEnum item : values()) {
if (item.code == code) {
return item.getName();
}
}
return "未知状态";
}
public static List<CodeNameVo> findAll() {
return LIST;
}
}
/* (C) 2022 YiRing, Inc. */ /* (C) 2022 YiRing, Inc. */
package com.yiring.app.design.strategy; package com.yiring.app.design.strategy;
import com.yiring.app.domain.location.LocationFenceAlarm;
import com.yiring.app.param.location.fence.LocationFenceJobParam; import com.yiring.app.param.location.fence.LocationFenceJobParam;
import com.yiring.app.vo.location.fence.LocationFenceJobVo; import com.yiring.app.vo.location.fence.LocationFenceJobVo;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.util.CollectionUtils;
/** /**
* 扫描是否满足报警策略 * 扫描是否满足报警策略
...@@ -18,4 +23,27 @@ public interface IScanAlarmStrategy { ...@@ -18,4 +23,27 @@ public interface IScanAlarmStrategy {
* @return 需要报警的报警信息 * @return 需要报警的报警信息
*/ */
LocationFenceJobVo scanAlarm(LocationFenceJobParam param); LocationFenceJobVo scanAlarm(LocationFenceJobParam param);
/**
* 将两个集合不相交的部分筛选出来,并封装到结果集
* @param newAlarms 集合1
* @param oldAlarms 集合2
* @param jobVo 结果集
*/
static void notIntersect(
List<LocationFenceAlarm> newAlarms,
List<LocationFenceAlarm> oldAlarms,
LocationFenceJobVo jobVo
) {
if (!CollectionUtils.isEmpty(oldAlarms)) {
Set<Long> newSet = newAlarms.stream().map(e -> e.getTag().getId()).collect(Collectors.toSet());
Set<Long> oldSet = oldAlarms.stream().map(e -> e.getTag().getId()).collect(Collectors.toSet());
newAlarms =
newAlarms.stream().filter(e -> !oldSet.contains(e.getTag().getId())).collect(Collectors.toList());
oldAlarms =
oldAlarms.stream().filter(e -> !newSet.contains(e.getTag().getId())).collect(Collectors.toList());
}
jobVo.setAddAlarm(newAlarms);
jobVo.setModifyAlarm(oldAlarms);
}
} }
...@@ -37,6 +37,7 @@ public class AllowEntranceStrategy implements IParamInitStrategy<LocationFenceRu ...@@ -37,6 +37,7 @@ public class AllowEntranceStrategy implements IParamInitStrategy<LocationFenceRu
public AllowEntranceStrategy() { public AllowEntranceStrategy() {
Integer relevanceParam = RelevanceParamEnum.ALLOW_ENTRANCE.getCode(); Integer relevanceParam = RelevanceParamEnum.ALLOW_ENTRANCE.getCode();
LocationFenceRuleContext.register(relevanceParam, this); LocationFenceRuleContext.register(relevanceParam, this);
ScanAlarmContext.register(relevanceParam, this);
} }
@Override @Override
...@@ -90,7 +91,7 @@ public class AllowEntranceStrategy implements IParamInitStrategy<LocationFenceRu ...@@ -90,7 +91,7 @@ public class AllowEntranceStrategy implements IParamInitStrategy<LocationFenceRu
.stream() .stream()
.filter(e -> !uuids.contains(e.getUser().getUuid())) .filter(e -> !uuids.contains(e.getUser().getUuid()))
.map(e -> { .map(e -> {
LocationFence fence = LocationFence.builder().id(fenceId).build(); LocationFence fence = LocationFence.builder().id(fenceId).name(param.getFenceName()).build();
AlarmType alarmType = AlarmType.builder().id(alarmTypeId).build(); AlarmType alarmType = AlarmType.builder().id(alarmTypeId).build();
return LocationFenceAlarm return LocationFenceAlarm
.builder() .builder()
...@@ -106,16 +107,7 @@ public class AllowEntranceStrategy implements IParamInitStrategy<LocationFenceRu ...@@ -106,16 +107,7 @@ public class AllowEntranceStrategy implements IParamInitStrategy<LocationFenceRu
}) })
.collect(Collectors.toList()); .collect(Collectors.toList());
//取两个集合没有相交的部分,newAlarms不重合的部分代表需要添加的报警,oldAlarms不重合的部分代表需要结束的报警 //取两个集合没有相交的部分,newAlarms不重合的部分代表需要添加的报警,oldAlarms不重合的部分代表需要结束的报警
if (!CollectionUtils.isEmpty(oldAlarms)) { IScanAlarmStrategy.notIntersect(newAlarms, oldAlarms, jobVo);
Set<Long> newSet = newAlarms.stream().map(e -> e.getTag().getId()).collect(Collectors.toSet());
Set<Long> oldSet = oldAlarms.stream().map(e -> e.getTag().getId()).collect(Collectors.toSet());
newAlarms =
newAlarms.stream().filter(e -> !oldSet.contains(e.getTag().getId())).collect(Collectors.toList());
oldAlarms =
oldAlarms.stream().filter(e -> !newSet.contains(e.getTag().getId())).collect(Collectors.toList());
}
jobVo.setAddAlarm(newAlarms);
jobVo.setModifyAlarm(oldAlarms);
return jobVo; return jobVo;
} }
} }
...@@ -107,7 +107,7 @@ public class MaxPeopleNumberStrategy implements IParamInitStrategy<LocationFence ...@@ -107,7 +107,7 @@ public class MaxPeopleNumberStrategy implements IParamInitStrategy<LocationFence
//记录触发报警的信息(例如最大人数是3,那么前三个员工进入的不会记录) //记录触发报警的信息(例如最大人数是3,那么前三个员工进入的不会记录)
for (int i = 0; i < exceed; i++) { for (int i = 0; i < exceed; i++) {
LocationTurnover turnover = turnoverList.get(i); LocationTurnover turnover = turnoverList.get(i);
LocationFence fence = LocationFence.builder().id(fenceId).build(); LocationFence fence = LocationFence.builder().id(fenceId).name(param.getFenceName()).build();
AlarmType alarmType = AlarmType.builder().id(alarmTypeId).build(); AlarmType alarmType = AlarmType.builder().id(alarmTypeId).build();
LocationFenceAlarm locationFenceAlarm = LocationFenceAlarm LocationFenceAlarm locationFenceAlarm = LocationFenceAlarm
.builder() .builder()
...@@ -123,16 +123,7 @@ public class MaxPeopleNumberStrategy implements IParamInitStrategy<LocationFence ...@@ -123,16 +123,7 @@ public class MaxPeopleNumberStrategy implements IParamInitStrategy<LocationFence
newAlarms.add(locationFenceAlarm); newAlarms.add(locationFenceAlarm);
} }
//取两个集合没有相交的部分,newAlarms不重合的部分代表需要添加的报警,oldAlarms不重合的部分代表需要结束的报警 //取两个集合没有相交的部分,newAlarms不重合的部分代表需要添加的报警,oldAlarms不重合的部分代表需要结束的报警
if (!CollectionUtils.isEmpty(oldAlarms)) { IScanAlarmStrategy.notIntersect(newAlarms, oldAlarms, jobVo);
Set<Long> newSet = newAlarms.stream().map(e -> e.getTag().getId()).collect(Collectors.toSet());
Set<Long> oldSet = oldAlarms.stream().map(e -> e.getTag().getId()).collect(Collectors.toSet());
newAlarms =
newAlarms.stream().filter(e -> !oldSet.contains(e.getTag().getId())).collect(Collectors.toList());
oldAlarms =
oldAlarms.stream().filter(e -> !newSet.contains(e.getTag().getId())).collect(Collectors.toList());
}
jobVo.setAddAlarm(newAlarms);
jobVo.setModifyAlarm(oldAlarms);
return jobVo; return jobVo;
} }
} }
...@@ -40,6 +40,7 @@ public class MinPeopleNumberStrategy implements IParamInitStrategy<LocationFence ...@@ -40,6 +40,7 @@ public class MinPeopleNumberStrategy implements IParamInitStrategy<LocationFence
public MinPeopleNumberStrategy() { public MinPeopleNumberStrategy() {
Integer relevanceParam = RelevanceParamEnum.MIN_PEOPLE_NUMBER.getCode(); Integer relevanceParam = RelevanceParamEnum.MIN_PEOPLE_NUMBER.getCode();
LocationFenceRuleContext.register(relevanceParam, this); LocationFenceRuleContext.register(relevanceParam, this);
ScanAlarmContext.register(relevanceParam, this);
} }
@Override @Override
...@@ -92,11 +93,11 @@ public class MinPeopleNumberStrategy implements IParamInitStrategy<LocationFence ...@@ -92,11 +93,11 @@ public class MinPeopleNumberStrategy implements IParamInitStrategy<LocationFence
//少的人数 //少的人数
int missing = timeAndNumberParam.getNumber() - tagSet.size(); int missing = timeAndNumberParam.getNumber() - tagSet.size();
List<LocationFenceAlarm> newAlarms = new ArrayList<>(); List<LocationFenceAlarm> newAlarms = new ArrayList<>();
//查询出这个围栏的信息 //查询员工’出‘这个围栏的进出信息
String beginTime = timeAndNumberParam.getBeginTime(); String beginTime = timeAndNumberParam.getBeginTime();
String endTime = timeAndNumberParam.getEndTime(); String endTime = timeAndNumberParam.getEndTime();
List<LocationTurnover> turnoverList = locationTurnoverRepository.withinFence(fenceId, false); List<LocationTurnover> turnoverList = locationTurnoverRepository.withinFence(fenceId, false);
//筛选出在配置时间段内这个围栏的进出信息 //筛选出在配置时间段内’出‘这个围栏的进出信息
turnoverList = turnoverList =
turnoverList turnoverList
.stream() .stream()
...@@ -106,7 +107,7 @@ public class MinPeopleNumberStrategy implements IParamInitStrategy<LocationFence ...@@ -106,7 +107,7 @@ public class MinPeopleNumberStrategy implements IParamInitStrategy<LocationFence
//记录触发报警的信息(例如最小人数是3,这段时间一开始有6个人在围栏,然后出去的4个,那么只有第四个人出去才会记录) //记录触发报警的信息(例如最小人数是3,这段时间一开始有6个人在围栏,然后出去的4个,那么只有第四个人出去才会记录)
for (int i = 0; i < missing; i++) { for (int i = 0; i < missing; i++) {
LocationTurnover turnover = turnoverList.get(i); LocationTurnover turnover = turnoverList.get(i);
LocationFence fence = LocationFence.builder().id(fenceId).build(); LocationFence fence = LocationFence.builder().id(fenceId).name(param.getFenceName()).build();
AlarmType alarmType = AlarmType.builder().id(alarmTypeId).build(); AlarmType alarmType = AlarmType.builder().id(alarmTypeId).build();
LocationFenceAlarm locationFenceAlarm = LocationFenceAlarm LocationFenceAlarm locationFenceAlarm = LocationFenceAlarm
.builder() .builder()
...@@ -122,16 +123,7 @@ public class MinPeopleNumberStrategy implements IParamInitStrategy<LocationFence ...@@ -122,16 +123,7 @@ public class MinPeopleNumberStrategy implements IParamInitStrategy<LocationFence
newAlarms.add(locationFenceAlarm); newAlarms.add(locationFenceAlarm);
} }
//取两个集合没有相交的部分,newAlarms不重合的部分代表需要添加的报警,oldAlarms不重合的部分代表需要结束的报警 //取两个集合没有相交的部分,newAlarms不重合的部分代表需要添加的报警,oldAlarms不重合的部分代表需要结束的报警
if (!CollectionUtils.isEmpty(oldAlarms)) { IScanAlarmStrategy.notIntersect(newAlarms, oldAlarms, jobVo);
Set<Long> newSet = newAlarms.stream().map(e -> e.getTag().getId()).collect(Collectors.toSet());
Set<Long> oldSet = oldAlarms.stream().map(e -> e.getTag().getId()).collect(Collectors.toSet());
newAlarms =
newAlarms.stream().filter(e -> !oldSet.contains(e.getTag().getId())).collect(Collectors.toList());
oldAlarms =
oldAlarms.stream().filter(e -> !newSet.contains(e.getTag().getId())).collect(Collectors.toList());
}
jobVo.setAddAlarm(newAlarms);
jobVo.setModifyAlarm(oldAlarms);
return jobVo; return jobVo;
} }
} }
...@@ -40,6 +40,7 @@ public class NotAllowLeaveStrategy implements IParamInitStrategy<LocationFenceRu ...@@ -40,6 +40,7 @@ public class NotAllowLeaveStrategy implements IParamInitStrategy<LocationFenceRu
public NotAllowLeaveStrategy() { public NotAllowLeaveStrategy() {
Integer relevanceParam = RelevanceParamEnum.NOT_ALLOW_LEAVE.getCode(); Integer relevanceParam = RelevanceParamEnum.NOT_ALLOW_LEAVE.getCode();
LocationFenceRuleContext.register(relevanceParam, this); LocationFenceRuleContext.register(relevanceParam, this);
ScanAlarmContext.register(relevanceParam, this);
} }
@Override @Override
...@@ -104,7 +105,7 @@ public class NotAllowLeaveStrategy implements IParamInitStrategy<LocationFenceRu ...@@ -104,7 +105,7 @@ public class NotAllowLeaveStrategy implements IParamInitStrategy<LocationFenceRu
.stream() .stream()
.filter(e -> uuids.contains(e.getTag().getUser().getUuid())) .filter(e -> uuids.contains(e.getTag().getUser().getUuid()))
.map(e -> { .map(e -> {
LocationFence fence = LocationFence.builder().id(fenceId).build(); LocationFence fence = LocationFence.builder().id(fenceId).name(param.getFenceName()).build();
AlarmType alarmType = AlarmType.builder().id(alarmTypeId).build(); AlarmType alarmType = AlarmType.builder().id(alarmTypeId).build();
return LocationFenceAlarm return LocationFenceAlarm
.builder() .builder()
...@@ -120,16 +121,7 @@ public class NotAllowLeaveStrategy implements IParamInitStrategy<LocationFenceRu ...@@ -120,16 +121,7 @@ public class NotAllowLeaveStrategy implements IParamInitStrategy<LocationFenceRu
}) })
.collect(Collectors.toList()); .collect(Collectors.toList());
//取两个集合没有相交的部分,newAlarms不重合的部分代表需要添加的报警,oldAlarms不重合的部分代表需要结束的报警 //取两个集合没有相交的部分,newAlarms不重合的部分代表需要添加的报警,oldAlarms不重合的部分代表需要结束的报警
if (!CollectionUtils.isEmpty(oldAlarms)) { IScanAlarmStrategy.notIntersect(newAlarms, oldAlarms, jobVo);
Set<Long> newSet = newAlarms.stream().map(e -> e.getTag().getId()).collect(Collectors.toSet());
Set<Long> oldSet = oldAlarms.stream().map(e -> e.getTag().getId()).collect(Collectors.toSet());
newAlarms =
newAlarms.stream().filter(e -> !oldSet.contains(e.getTag().getId())).collect(Collectors.toList());
oldAlarms =
oldAlarms.stream().filter(e -> !newSet.contains(e.getTag().getId())).collect(Collectors.toList());
}
jobVo.setAddAlarm(newAlarms);
jobVo.setModifyAlarm(oldAlarms);
return jobVo; return jobVo;
} }
} }
...@@ -19,7 +19,6 @@ import java.util.Set; ...@@ -19,7 +19,6 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
/** /**
* 滞留时长相关策略 * 滞留时长相关策略
...@@ -36,6 +35,7 @@ public class RetentionDurationStrategy implements IParamInitStrategy<LocationFen ...@@ -36,6 +35,7 @@ public class RetentionDurationStrategy implements IParamInitStrategy<LocationFen
public RetentionDurationStrategy() { public RetentionDurationStrategy() {
Integer relevanceParam = RelevanceParamEnum.RETENTION_DURATION.getCode(); Integer relevanceParam = RelevanceParamEnum.RETENTION_DURATION.getCode();
LocationFenceRuleContext.register(relevanceParam, this); LocationFenceRuleContext.register(relevanceParam, this);
ScanAlarmContext.register(relevanceParam, this);
} }
@Override @Override
...@@ -67,7 +67,7 @@ public class RetentionDurationStrategy implements IParamInitStrategy<LocationFen ...@@ -67,7 +67,7 @@ public class RetentionDurationStrategy implements IParamInitStrategy<LocationFen
.stream() .stream()
.filter(e -> e.getTime().isBefore(time)) .filter(e -> e.getTime().isBefore(time))
.map(e -> { .map(e -> {
LocationFence fence = LocationFence.builder().id(fenceId).build(); LocationFence fence = LocationFence.builder().id(fenceId).name(param.getFenceName()).build();
AlarmType alarmType = AlarmType.builder().id(alarmTypeId).build(); AlarmType alarmType = AlarmType.builder().id(alarmTypeId).build();
return LocationFenceAlarm return LocationFenceAlarm
.builder() .builder()
...@@ -83,16 +83,7 @@ public class RetentionDurationStrategy implements IParamInitStrategy<LocationFen ...@@ -83,16 +83,7 @@ public class RetentionDurationStrategy implements IParamInitStrategy<LocationFen
}) })
.collect(Collectors.toList()); .collect(Collectors.toList());
//取两个集合没有相交的部分,newAlarms不重合的部分代表需要添加的报警,oldAlarms不重合的部分代表需要结束的报警 //取两个集合没有相交的部分,newAlarms不重合的部分代表需要添加的报警,oldAlarms不重合的部分代表需要结束的报警
if (!CollectionUtils.isEmpty(oldAlarms)) { IScanAlarmStrategy.notIntersect(newAlarms, oldAlarms, jobVo);
Set<Long> newSet = newAlarms.stream().map(e -> e.getTag().getId()).collect(Collectors.toSet());
Set<Long> oldSet = oldAlarms.stream().map(e -> e.getTag().getId()).collect(Collectors.toSet());
newAlarms =
newAlarms.stream().filter(e -> !oldSet.contains(e.getTag().getId())).collect(Collectors.toList());
oldAlarms =
oldAlarms.stream().filter(e -> !newSet.contains(e.getTag().getId())).collect(Collectors.toList());
}
jobVo.setAddAlarm(newAlarms);
jobVo.setModifyAlarm(oldAlarms);
return jobVo; return jobVo;
} }
} }
...@@ -20,7 +20,6 @@ import java.util.List; ...@@ -20,7 +20,6 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
/** /**
* 静止时长相关策略 * 静止时长相关策略
...@@ -34,6 +33,7 @@ public class StaticDurationStrategy implements IParamInitStrategy<LocationFenceR ...@@ -34,6 +33,7 @@ public class StaticDurationStrategy implements IParamInitStrategy<LocationFenceR
public StaticDurationStrategy() { public StaticDurationStrategy() {
Integer relevanceParam = RelevanceParamEnum.STATIC_DURATION.getCode(); Integer relevanceParam = RelevanceParamEnum.STATIC_DURATION.getCode();
LocationFenceRuleContext.register(relevanceParam, this); LocationFenceRuleContext.register(relevanceParam, this);
ScanAlarmContext.register(relevanceParam, this);
} }
@Override @Override
...@@ -65,7 +65,7 @@ public class StaticDurationStrategy implements IParamInitStrategy<LocationFenceR ...@@ -65,7 +65,7 @@ public class StaticDurationStrategy implements IParamInitStrategy<LocationFenceR
.filter(LocationTag::getSilent) .filter(LocationTag::getSilent)
.filter(e -> e.getTime().isBefore(time)) .filter(e -> e.getTime().isBefore(time))
.map(e -> { .map(e -> {
LocationFence fence = LocationFence.builder().id(fenceId).build(); LocationFence fence = LocationFence.builder().id(fenceId).name(param.getFenceName()).build();
AlarmType alarmType = AlarmType.builder().id(alarmTypeId).build(); AlarmType alarmType = AlarmType.builder().id(alarmTypeId).build();
return LocationFenceAlarm return LocationFenceAlarm
.builder() .builder()
...@@ -81,16 +81,7 @@ public class StaticDurationStrategy implements IParamInitStrategy<LocationFenceR ...@@ -81,16 +81,7 @@ public class StaticDurationStrategy implements IParamInitStrategy<LocationFenceR
}) })
.collect(Collectors.toList()); .collect(Collectors.toList());
//取两个集合没有相交的部分,newAlarms不重合的部分代表需要添加的报警,oldAlarms不重合的部分代表需要结束的报警 //取两个集合没有相交的部分,newAlarms不重合的部分代表需要添加的报警,oldAlarms不重合的部分代表需要结束的报警
if (!CollectionUtils.isEmpty(oldAlarms)) { IScanAlarmStrategy.notIntersect(newAlarms, oldAlarms, jobVo);
Set<Long> newSet = newAlarms.stream().map(e -> e.getTag().getId()).collect(Collectors.toSet());
Set<Long> oldSet = oldAlarms.stream().map(e -> e.getTag().getId()).collect(Collectors.toSet());
newAlarms =
newAlarms.stream().filter(e -> !oldSet.contains(e.getTag().getId())).collect(Collectors.toList());
oldAlarms =
oldAlarms.stream().filter(e -> !newSet.contains(e.getTag().getId())).collect(Collectors.toList());
}
jobVo.setAddAlarm(newAlarms);
jobVo.setModifyAlarm(oldAlarms);
return jobVo; return jobVo;
} }
} }
...@@ -23,7 +23,6 @@ import java.util.stream.Collectors; ...@@ -23,7 +23,6 @@ import java.util.stream.Collectors;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Geometry;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
/** /**
* 触发报警距离相关策略 * 触发报警距离相关策略
...@@ -40,6 +39,7 @@ public class TriggerAlarmDistanceStrategy implements IParamInitStrategy<Location ...@@ -40,6 +39,7 @@ public class TriggerAlarmDistanceStrategy implements IParamInitStrategy<Location
public TriggerAlarmDistanceStrategy() { public TriggerAlarmDistanceStrategy() {
Integer relevanceParam = RelevanceParamEnum.TRIGGER_ALARM_DISTANCE.getCode(); Integer relevanceParam = RelevanceParamEnum.TRIGGER_ALARM_DISTANCE.getCode();
LocationFenceRuleContext.register(relevanceParam, this); LocationFenceRuleContext.register(relevanceParam, this);
ScanAlarmContext.register(relevanceParam, this);
} }
@Override @Override
...@@ -70,7 +70,7 @@ public class TriggerAlarmDistanceStrategy implements IParamInitStrategy<Location ...@@ -70,7 +70,7 @@ public class TriggerAlarmDistanceStrategy implements IParamInitStrategy<Location
List<LocationFenceAlarm> newAlarms = locationTags List<LocationFenceAlarm> newAlarms = locationTags
.stream() .stream()
.map(e -> { .map(e -> {
LocationFence fence = LocationFence.builder().id(fenceId).build(); LocationFence fence = LocationFence.builder().id(fenceId).name(param.getFenceName()).build();
AlarmType alarmType = AlarmType.builder().id(alarmTypeId).build(); AlarmType alarmType = AlarmType.builder().id(alarmTypeId).build();
return LocationFenceAlarm return LocationFenceAlarm
.builder() .builder()
...@@ -86,16 +86,7 @@ public class TriggerAlarmDistanceStrategy implements IParamInitStrategy<Location ...@@ -86,16 +86,7 @@ public class TriggerAlarmDistanceStrategy implements IParamInitStrategy<Location
}) })
.collect(Collectors.toList()); .collect(Collectors.toList());
//取两个集合没有相交的部分,newAlarms不重合的部分代表需要添加的报警,oldAlarms不重合的部分代表需要结束的报警 //取两个集合没有相交的部分,newAlarms不重合的部分代表需要添加的报警,oldAlarms不重合的部分代表需要结束的报警
if (!CollectionUtils.isEmpty(oldAlarms)) { IScanAlarmStrategy.notIntersect(newAlarms, oldAlarms, jobVo);
Set<Long> newSet = newAlarms.stream().map(e -> e.getTag().getId()).collect(Collectors.toSet());
Set<Long> oldSet = oldAlarms.stream().map(e -> e.getTag().getId()).collect(Collectors.toSet());
newAlarms =
newAlarms.stream().filter(e -> !oldSet.contains(e.getTag().getId())).collect(Collectors.toList());
oldAlarms =
oldAlarms.stream().filter(e -> !newSet.contains(e.getTag().getId())).collect(Collectors.toList());
}
jobVo.setAddAlarm(newAlarms);
jobVo.setModifyAlarm(oldAlarms);
return jobVo; return jobVo;
} }
} }
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.domain.location;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.yiring.auth.domain.user.User;
import com.yiring.common.domain.BasicEntity;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import lombok.*;
import lombok.experimental.FieldNameConstants;
import org.hibernate.annotations.Comment;
/**
* @author tml
* @version 1.0
* @date 2022/5/18 9:25
*/
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
@FieldNameConstants
@Entity
@Table(name = "BS_FENCE_ALARM_PUSH_LOG")
@Comment("围栏报警推送记录")
public class FenceAlarmPushLog extends BasicEntity implements Serializable {
@Serial
private static final long serialVersionUID = 7859768330784835564L;
@ManyToOne
@JoinColumn(name = "fence_alarm_id")
@JsonIgnore
@Comment("围栏报警记录")
private LocationFenceAlarm fenceAlarm;
@Comment("通知方式")
private Integer informManner;
@Comment("接收状态")
private Integer status;
@Comment("接收时间")
private LocalDateTime time;
@ManyToOne
@JoinColumn(name = "user_id")
@JsonIgnore
@Comment("报警接收人")
User user;
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.domain.location;
import java.io.Serializable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
/**
* @author tml
* @version 1.0
* @date 2022/5/18 10:29
*/
@Repository
public interface FenceAlarmPushLogRepository
extends JpaRepository<FenceAlarmPushLog, Serializable>, JpaSpecificationExecutor<FenceAlarmPushLog> {}
...@@ -13,6 +13,7 @@ import lombok.experimental.FieldNameConstants; ...@@ -13,6 +13,7 @@ import lombok.experimental.FieldNameConstants;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import org.hibernate.annotations.Comment; import org.hibernate.annotations.Comment;
import org.hibernate.annotations.Where; import org.hibernate.annotations.Where;
import org.springframework.util.CollectionUtils;
/** /**
* @author tml * @author tml
...@@ -62,4 +63,20 @@ public class LocationAlarmRule extends BasicEntity implements Serializable { ...@@ -62,4 +63,20 @@ public class LocationAlarmRule extends BasicEntity implements Serializable {
@Comment(value = "是否删除") @Comment(value = "是否删除")
@Column(nullable = false) @Column(nullable = false)
Boolean deleted; Boolean deleted;
/**
* 判断本实体类的报警类型集是否包含搞报警类型
* @param alarmType 报警类型
* @return true:包含 false:不包含
*/
public boolean typesContains(AlarmType alarmType) {
if (!CollectionUtils.isEmpty(alarmTypes)) {
for (AlarmType item : alarmTypes) {
if (item.getId().equals(alarmType.getId())) {
return true;
}
}
}
return false;
}
} }
...@@ -2,8 +2,11 @@ ...@@ -2,8 +2,11 @@
package com.yiring.app.domain.location; package com.yiring.app.domain.location;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
/** /**
...@@ -13,4 +16,15 @@ import org.springframework.stereotype.Repository; ...@@ -13,4 +16,15 @@ import org.springframework.stereotype.Repository;
*/ */
@Repository @Repository
public interface LocationAlarmRuleRepository public interface LocationAlarmRuleRepository
extends JpaRepository<LocationAlarmRule, Serializable>, JpaSpecificationExecutor<LocationAlarmRule> {} extends JpaRepository<LocationAlarmRule, Serializable>, JpaSpecificationExecutor<LocationAlarmRule> {
/**
* 根据多个围栏id查询
* @param fenceIds 围栏id
* @return 规则
*/
@Query(
value = "SELECT * FROM BS_LOCATION_ALARM_RULE WHERE deleted = false AND fence_id IN (?1)",
nativeQuery = true
)
List<LocationAlarmRule> findAllByFenceIds(Collection<Long> fenceIds);
}
...@@ -7,6 +7,8 @@ import com.yiring.common.domain.BasicEntity; ...@@ -7,6 +7,8 @@ import com.yiring.common.domain.BasicEntity;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.*; import javax.persistence.*;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
...@@ -71,8 +73,10 @@ public class LocationFenceAlarm extends BasicEntity implements Serializable { ...@@ -71,8 +73,10 @@ public class LocationFenceAlarm extends BasicEntity implements Serializable {
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
Status status; Status status;
// 推送记录集合(含接收状态) @Builder.Default
// TODO @OneToMany(mappedBy = "fenceAlarm")
@Comment("推送记录")
List<FenceAlarmPushLog> pushLogs = new ArrayList<>();
@SuppressWarnings({ "unused" }) @SuppressWarnings({ "unused" })
public enum Status { public enum Status {
......
...@@ -8,6 +8,7 @@ import com.yiring.app.domain.location.LocationFenceAlarm; ...@@ -8,6 +8,7 @@ import com.yiring.app.domain.location.LocationFenceAlarm;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
...@@ -28,37 +29,43 @@ public class FenceAlarmExcel implements Serializable { ...@@ -28,37 +29,43 @@ public class FenceAlarmExcel implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 4526095986813965381L; private static final long serialVersionUID = 4526095986813965381L;
@ExcelColumn(title = "地图名称") @ExcelColumn(title = "地图名称", width = 10)
private String mapName; private String mapName;
@ExcelColumn(title = "围栏名称") @ExcelColumn(title = "围栏名称", width = 10)
private String fenceName; private String fenceName;
@ExcelColumn(title = "围栏类别") @ExcelColumn(title = "围栏类别", width = 10)
private String fenceTypeName; private String fenceTypeName;
@ExcelColumn(title = "报警人员") @ExcelColumn(title = "报警人员", width = 10)
private String realName; private String realName;
@ExcelColumn(title = "标签号") @ExcelColumn(title = "标签号", width = 10)
private String tagId; private String tagId;
@ExcelColumn(title = "报警开始时间") @ExcelColumn(title = "报警开始时间", width = 15)
private LocalDateTime startTime; private LocalDateTime startTime;
@ExcelColumn(title = "报警结束时间") @ExcelColumn(title = "报警结束时间", width = 15)
private LocalDateTime endTime; private LocalDateTime endTime;
@ExcelColumn(title = "报警类型") @ExcelColumn(title = "报警类型", width = 10)
private String alarmTypeName; private String alarmTypeName;
@ExcelColumn(title = "接收人") @ExcelColumn(title = "接收人", width = 15)
private String recipient; private String recipient;
@ExcelColumn(title = "报警状态") @ExcelColumn(title = "报警状态", width = 10)
private String statusName; private String statusName;
public static FenceAlarmExcel transform(LocationFenceAlarm fenceAlarm) { public static FenceAlarmExcel transform(LocationFenceAlarm fenceAlarm) {
String recipient = fenceAlarm
.getPushLogs()
.stream()
.map(e -> e.getUser().getRealName())
.distinct()
.collect(Collectors.joining(", "));
return FenceAlarmExcel return FenceAlarmExcel
.builder() .builder()
.fenceName(fenceAlarm.getFence().getName()) .fenceName(fenceAlarm.getFence().getName())
...@@ -68,8 +75,7 @@ public class FenceAlarmExcel implements Serializable { ...@@ -68,8 +75,7 @@ public class FenceAlarmExcel implements Serializable {
.startTime(fenceAlarm.getStartTime()) .startTime(fenceAlarm.getStartTime())
.endTime(fenceAlarm.getEndTime()) .endTime(fenceAlarm.getEndTime())
.alarmTypeName(fenceAlarm.getType().getName()) .alarmTypeName(fenceAlarm.getType().getName())
//todo .recipient(recipient)
//.recipient()
.statusName(fenceAlarm.getStatus().text()) .statusName(fenceAlarm.getStatus().text())
.build(); .build();
} }
......
...@@ -2,12 +2,15 @@ ...@@ -2,12 +2,15 @@
package com.yiring.app.job; package com.yiring.app.job;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.xxl.job.core.handler.annotation.XxlJob; import com.xxl.job.core.handler.annotation.XxlJob;
import com.yiring.app.design.strategy.rule.ScanAlarmContext; import com.yiring.app.design.strategy.rule.ScanAlarmContext;
import com.yiring.app.domain.location.*; import com.yiring.app.domain.location.*;
import com.yiring.app.param.location.fence.LocationFenceJobParam; import com.yiring.app.param.location.fence.LocationFenceJobParam;
import com.yiring.app.param.location.rule.RuleParam; import com.yiring.app.param.location.rule.RuleParam;
import com.yiring.app.service.location.fence.FenceAlarmService;
import com.yiring.app.vo.location.fence.LocationFenceJobVo; import com.yiring.app.vo.location.fence.LocationFenceJobVo;
import com.yiring.auth.domain.user.User;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
...@@ -34,6 +37,15 @@ public class FenceAlarmJob { ...@@ -34,6 +37,15 @@ public class FenceAlarmJob {
@Resource @Resource
private LocationFenceAlarmRepository locationFenceAlarmRepository; private LocationFenceAlarmRepository locationFenceAlarmRepository;
@Resource
private LocationAlarmRuleRepository locationAlarmRuleRepository;
@Resource
private FenceAlarmPushLogRepository fenceAlarmPushLogRepository;
@Resource
private FenceAlarmService fenceAlarmService;
@XxlJob("ScanAlarmHandler") @XxlJob("ScanAlarmHandler")
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void scanAlarmHandler() { public void scanAlarmHandler() {
...@@ -60,6 +72,7 @@ public class FenceAlarmJob { ...@@ -60,6 +72,7 @@ public class FenceAlarmJob {
.builder() .builder()
.rule(ruleParam) .rule(ruleParam)
.fenceId(fence.getId()) .fenceId(fence.getId())
.fenceName(fence.getName())
.alarmTypeId(fenceRule.getAlarmType().getId()) .alarmTypeId(fenceRule.getAlarmType().getId())
.tagSet(fence.getTags()) .tagSet(fence.getTags())
.mapId(fence.getMapId()) .mapId(fence.getMapId())
...@@ -73,6 +86,8 @@ public class FenceAlarmJob { ...@@ -73,6 +86,8 @@ public class FenceAlarmJob {
jobVo.merge(locationFenceJobVo); jobVo.merge(locationFenceJobVo);
} }
} }
//异步将新添加的报警信息推送给前端
fenceAlarmService.alarmPushWeb(jobVo.getAddAlarm());
//添加报警和关闭报警 //添加报警和关闭报警
locationFenceAlarmRepository.saveAllAndFlush(jobVo.getAddAlarm()); locationFenceAlarmRepository.saveAllAndFlush(jobVo.getAddAlarm());
List<Long> ids = jobVo.getModifyAlarm().stream().map(LocationFenceAlarm::getId).collect(Collectors.toList()); List<Long> ids = jobVo.getModifyAlarm().stream().map(LocationFenceAlarm::getId).collect(Collectors.toList());
...@@ -82,5 +97,39 @@ public class FenceAlarmJob { ...@@ -82,5 +97,39 @@ public class FenceAlarmJob {
JSON.toJSONString(jobVo.getAddAlarm()), JSON.toJSONString(jobVo.getAddAlarm()),
JSON.toJSONString(jobVo.getModifyAlarm()) JSON.toJSONString(jobVo.getModifyAlarm())
); );
//todo 推送报警信息
//添加报警推送记录,可以考虑异步执行
Set<Long> fenceIds = jobVo.getAddAlarm().stream().map(e -> e.getFence().getId()).collect(Collectors.toSet());
List<LocationAlarmRule> locationAlarmRuleList = locationAlarmRuleRepository.findAllByFenceIds(fenceIds);
List<FenceAlarmPushLog> pushLogList = new ArrayList<>();
for (LocationFenceAlarm fenceAlarm : jobVo.getAddAlarm()) {
//筛选出该条报警记录对应的报警规则
locationAlarmRuleList =
locationAlarmRuleList
.stream()
.filter(e -> fenceAlarm.getFence().getId().equals(e.getLocationFence().getId()))
.filter(e -> e.typesContains(fenceAlarm.getType()))
.collect(Collectors.toList());
//一条报警记录可能对应多个报警规则(报警给谁的规则),报警规则的接收人和通知方式用笛卡尔积存到数据库
for (LocationAlarmRule alarmRule : locationAlarmRuleList) {
List<Integer> informManners = JSONArray.parseArray(alarmRule.getInformManner(), Integer.class);
for (User user : alarmRule.getUsers()) {
for (Integer informManner : informManners) {
FenceAlarmPushLog pushLog = FenceAlarmPushLog
.builder()
.fenceAlarm(fenceAlarm)
.informManner(informManner)
.user(user)
.build();
pushLogList.add(pushLog);
}
}
}
}
//落库
fenceAlarmPushLogRepository.saveAllAndFlush(pushLogList);
log.info("FenceAlarmJob.scanAlarmHandler: 生成的推送记录:[{}]", JSON.toJSONString(pushLogList));
} }
} }
...@@ -35,12 +35,12 @@ public class FenceAlarmConditionParam implements Serializable { ...@@ -35,12 +35,12 @@ public class FenceAlarmConditionParam implements Serializable {
@ApiModelProperty(value = "报警人员真名", example = "张三") @ApiModelProperty(value = "报警人员真名", example = "张三")
private String realName; private String realName;
@ApiModelProperty(value = "报警状态", example = "true|false") @ApiModelProperty(value = "报警状态", example = "true")
private Boolean status; private Boolean status;
@ApiModelProperty(value = "报警开始时间", example = "2022-05-06 14:00:00") @ApiModelProperty(value = "报警开始时间", example = "2022-05-06 14:00:00")
private LocalDateTime beginTime; private LocalDateTime beginTime;
@ApiModelProperty(value = "报警结束时间", example = "2022-05-7 14:00:00") @ApiModelProperty(value = "报警结束时间", example = "2022-05-07 14:00:00")
private LocalDateTime endTime; private LocalDateTime endTime;
} }
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.param.location.fence;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serial;
import java.io.Serializable;
import java.util.Set;
import javax.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author tml
* @version 1.0
* @date 2022/5/18 10:08
*/
@ApiModel("围栏报警推送记录")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class FenceAlarmPushLogConditionParam implements Serializable {
@Serial
private static final long serialVersionUID = -3348481008334535142L;
@ApiModelProperty(value = "围栏报警记录id", example = "1")
@NotNull(message = "围栏报警记录id不能为空")
private Long fenceAlarmId;
@ApiModelProperty(value = "通知方式: 1-app消息 2-短信通知 3-电话通知", example = "[1,2,3]", dataType = "array")
private Set<Integer> informManner;
@ApiModelProperty(value = "接受状态: 1-成功 2-失败", example = "1")
private Integer status;
@ApiModelProperty(value = "联系电话", example = "18283943672")
private String phone;
}
...@@ -40,6 +40,11 @@ public class LocationFenceJobParam implements Serializable { ...@@ -40,6 +40,11 @@ public class LocationFenceJobParam implements Serializable {
private Long fenceId; private Long fenceId;
/** /**
* 围栏名称
*/
private String fenceName;
/**
* 报警类别id * 报警类别id
*/ */
private Long alarmTypeId; private Long alarmTypeId;
......
...@@ -4,8 +4,10 @@ package com.yiring.app.service.analysis.history; ...@@ -4,8 +4,10 @@ package com.yiring.app.service.analysis.history;
import com.yiring.app.param.analysis.history.HistoryRouteConditionParam; import com.yiring.app.param.analysis.history.HistoryRouteConditionParam;
import com.yiring.app.vo.analysis.history.HistoryRouteVo; import com.yiring.app.vo.analysis.history.HistoryRouteVo;
import com.yiring.common.core.Result; import com.yiring.common.core.Result;
import com.yiring.common.param.PageParam;
import com.yiring.common.vo.PageVo; import com.yiring.common.vo.PageVo;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
/** /**
* @author tml * @author tml
...@@ -21,6 +23,14 @@ public interface HistoryRouteService { ...@@ -21,6 +23,14 @@ public interface HistoryRouteService {
Result<PageVo<HistoryRouteVo>> findByCondition(HistoryRouteConditionParam param); Result<PageVo<HistoryRouteVo>> findByCondition(HistoryRouteConditionParam param);
/** /**
* 分页条件查询
* @param param 条件
* @param pageParam 分页参数
* @return 历史轨迹信息
*/
Result<PageVo<HistoryRouteVo>> findByPage(@Valid HistoryRouteConditionParam param, @Valid PageParam pageParam);
/**
* 导出历史轨迹信息 * 导出历史轨迹信息
* @param param 地图、员工和时间条件 * @param param 地图、员工和时间条件
* @param response 历史轨迹信息 * @param response 历史轨迹信息
......
...@@ -12,6 +12,7 @@ import com.yiring.app.vo.analysis.history.HistoryRouteVo; ...@@ -12,6 +12,7 @@ import com.yiring.app.vo.analysis.history.HistoryRouteVo;
import com.yiring.app.vo.map.MapVo; import com.yiring.app.vo.map.MapVo;
import com.yiring.common.core.Result; import com.yiring.common.core.Result;
import com.yiring.common.core.Status; import com.yiring.common.core.Status;
import com.yiring.common.param.PageParam;
import com.yiring.common.vo.PageVo; import com.yiring.common.vo.PageVo;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.URLEncoder; import java.net.URLEncoder;
...@@ -25,6 +26,7 @@ import javax.persistence.criteria.Predicate; ...@@ -25,6 +26,7 @@ import javax.persistence.criteria.Predicate;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
...@@ -63,6 +65,27 @@ public class HistoryRouteServiceImpl implements HistoryRouteService { ...@@ -63,6 +65,27 @@ public class HistoryRouteServiceImpl implements HistoryRouteService {
} }
@Override @Override
public Result<PageVo<HistoryRouteVo>> findByPage(HistoryRouteConditionParam param, PageParam pageParam) {
Pageable pageable = PageParam.toPageable(pageParam);
Specification<LocationLog> specification = getSpecification(param);
ArrayList<MapVo.MapVoReuslt> list1 = new ArrayList<>();
List<LocationLog> list = locationLogRepository
.findAll(specification, pageable)
.stream()
.collect(Collectors.toList());
List<HistoryRouteVo> voList = list
.stream()
.map(e -> {
HistoryRouteVo routeVo = HistoryRouteVo.transform(e);
routeVo.setMapName(mapUtil.getMapName(e.getAreaId().intValue()));
return routeVo;
})
.collect(Collectors.toList());
PageVo<HistoryRouteVo> pageVo = PageVo.build(voList, voList.size());
return Result.ok(pageVo);
}
@Override
public void exportHistoryRoute(HistoryRouteConditionParam param, HttpServletResponse response) { public void exportHistoryRoute(HistoryRouteConditionParam param, HttpServletResponse response) {
Result<PageVo<HistoryRouteVo>> result = findByCondition(param); Result<PageVo<HistoryRouteVo>> result = findByCondition(param);
if (Status.OK.value() != result.getStatus()) { if (Status.OK.value() != result.getStatus()) {
......
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.service.location.fence;
import com.yiring.app.param.location.fence.FenceAlarmPushLogConditionParam;
import com.yiring.app.vo.location.fence.FenceAlarmPushLogVo;
import com.yiring.common.core.Result;
import com.yiring.common.param.PageParam;
import com.yiring.common.vo.PageVo;
import javax.validation.Valid;
/**
* @author tml
* @version 1.0
* @date 2022/5/18 10:26
*/
public interface FenceAlarmPushLogService {
/**
* 查询围栏报警推送记录列表
* @param conditionParam 条件参数
* @param pageParam 分页参数
* @return 推送记录
*/
Result<PageVo<FenceAlarmPushLogVo>> findList(
@Valid FenceAlarmPushLogConditionParam conditionParam,
@Valid PageParam pageParam
);
}
/* (C) 2022 YiRing, Inc. */ /* (C) 2022 YiRing, Inc. */
package com.yiring.app.service.location.fence; package com.yiring.app.service.location.fence;
import com.yiring.app.domain.location.LocationFenceAlarm;
import com.yiring.app.param.location.fence.FenceAlarmConditionParam; import com.yiring.app.param.location.fence.FenceAlarmConditionParam;
import com.yiring.app.vo.IdNameVo; import com.yiring.app.vo.IdNameVo;
import com.yiring.app.vo.location.fence.FenceAlarmVo; import com.yiring.app.vo.location.fence.FenceAlarmVo;
import com.yiring.common.core.Result; import com.yiring.common.core.Result;
import com.yiring.common.param.PageParam; import com.yiring.common.param.PageParam;
import com.yiring.common.vo.PageVo; import com.yiring.common.vo.PageVo;
import java.util.List;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
/** /**
...@@ -34,4 +36,10 @@ public interface FenceAlarmService { ...@@ -34,4 +36,10 @@ public interface FenceAlarmService {
* @param param 查询条件 * @param param 查询条件
*/ */
void export(FenceAlarmConditionParam param, HttpServletResponse response); void export(FenceAlarmConditionParam param, HttpServletResponse response);
/**
* 推送报警信息给前端
* @param newAlarm 新生成的报警信息
*/
void alarmPushWeb(List<LocationFenceAlarm> newAlarm);
} }
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.service.location.fence.impl;
import com.yiring.app.domain.location.FenceAlarmPushLog;
import com.yiring.app.domain.location.FenceAlarmPushLogRepository;
import com.yiring.app.param.location.fence.FenceAlarmPushLogConditionParam;
import com.yiring.app.service.location.fence.FenceAlarmPushLogService;
import com.yiring.app.vo.location.fence.FenceAlarmPushLogVo;
import com.yiring.auth.domain.user.User;
import com.yiring.common.core.Result;
import com.yiring.common.param.PageParam;
import com.yiring.common.vo.PageVo;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.persistence.criteria.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @author tml
* @version 1.0
* @date 2022/5/18 10:27
*/
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class FenceAlarmPushLogServiceImpl implements FenceAlarmPushLogService {
@Resource
private FenceAlarmPushLogRepository fenceAlarmPushLogRepository;
@Override
public Result<PageVo<FenceAlarmPushLogVo>> findList(
FenceAlarmPushLogConditionParam conditionParam,
PageParam pageParam
) {
Pageable pageable = PageParam.toPageable(pageParam);
Specification<FenceAlarmPushLog> specification = (root, query, criteriaBuilder) -> {
ArrayList<Predicate> list = new ArrayList<>();
if (conditionParam.getFenceAlarmId() != null) {
list.add(
criteriaBuilder.equal(
root.get(FenceAlarmPushLog.Fields.fenceAlarm),
conditionParam.getFenceAlarmId()
)
);
}
if (conditionParam.getInformManner() != null) {
CriteriaBuilder.In<Object> in = criteriaBuilder.in(root.get(FenceAlarmPushLog.Fields.informManner));
for (Integer item : conditionParam.getInformManner()) {
in.value(item);
}
list.add(in);
}
if (conditionParam.getStatus() != null) {
list.add(criteriaBuilder.equal(root.get(FenceAlarmPushLog.Fields.status), conditionParam.getStatus()));
}
if (conditionParam.getPhone() != null) {
Join<Object, Object> join = root.join(FenceAlarmPushLog.Fields.user, JoinType.LEFT);
list.add(criteriaBuilder.like(join.get(User.Fields.mobile), "%" + conditionParam.getPhone() + "%"));
}
Predicate[] array = list.toArray(new Predicate[0]);
return criteriaBuilder.and(array);
};
Page<FenceAlarmPushLog> page = fenceAlarmPushLogRepository.findAll(specification, pageable);
List<FenceAlarmPushLogVo> voList = page.get().map(FenceAlarmPushLogVo::transform).collect(Collectors.toList());
PageVo<FenceAlarmPushLogVo> pageVo = PageVo.build(voList, voList.size());
return Result.ok(pageVo);
}
}
/* (C) 2022 YiRing, Inc. */ /* (C) 2022 YiRing, Inc. */
package com.yiring.app.service.location.fence.impl; package com.yiring.app.service.location.fence.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.liaochong.myexcel.core.DefaultStreamExcelBuilder; import com.github.liaochong.myexcel.core.DefaultStreamExcelBuilder;
import com.yiring.app.domain.location.LocationFence; import com.yiring.app.domain.location.LocationFence;
import com.yiring.app.domain.location.LocationFenceAlarm; import com.yiring.app.domain.location.LocationFenceAlarm;
...@@ -33,6 +35,8 @@ import org.apache.poi.ss.usermodel.Workbook; ...@@ -33,6 +35,8 @@ import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
...@@ -53,6 +57,9 @@ public class FenceAlarmServiceImpl implements FenceAlarmService { ...@@ -53,6 +57,9 @@ public class FenceAlarmServiceImpl implements FenceAlarmService {
private LocationFenceRepository locationFenceRepository; private LocationFenceRepository locationFenceRepository;
@Resource @Resource
SimpMessagingTemplate simpMessagingTemplate;
@Resource
private MapUtil mapUtil; private MapUtil mapUtil;
@Override @Override
...@@ -126,6 +133,24 @@ public class FenceAlarmServiceImpl implements FenceAlarmService { ...@@ -126,6 +133,24 @@ public class FenceAlarmServiceImpl implements FenceAlarmService {
} }
} }
@Async
@Override
public void alarmPushWeb(List<LocationFenceAlarm> newAlarm) {
JSONArray jsonArray = new JSONArray();
for (LocationFenceAlarm item : newAlarm) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("fence", item.getFence().getName());
jsonObject.put("map", mapUtil.getMapName(item.getAreaId().intValue()));
jsonObject.put("user", item.getUser().getRealName());
jsonObject.put("tagId", item.getTag().getId());
jsonObject.put("startTime", item.getStartTime());
jsonObject.put("AlarmType", item.getType().getName());
jsonObject.put("status", item.getStatus().text());
jsonArray.add(jsonObject);
}
simpMessagingTemplate.convertAndSend("/topic/position", jsonArray.toJSONString());
}
private Specification<LocationFenceAlarm> getSpecification(FenceAlarmConditionParam param) { private Specification<LocationFenceAlarm> getSpecification(FenceAlarmConditionParam param) {
return (root, query, criteriaBuilder) -> { return (root, query, criteriaBuilder) -> {
ArrayList<Predicate> list = new ArrayList<>(); ArrayList<Predicate> list = new ArrayList<>();
...@@ -138,7 +163,7 @@ public class FenceAlarmServiceImpl implements FenceAlarmService { ...@@ -138,7 +163,7 @@ public class FenceAlarmServiceImpl implements FenceAlarmService {
} }
if (param.getRealName() != null) { if (param.getRealName() != null) {
Join<Object, Object> join = root.join(LocationFenceAlarm.Fields.user, JoinType.LEFT); Join<Object, Object> join = root.join(LocationFenceAlarm.Fields.user, JoinType.LEFT);
list.add(criteriaBuilder.equal(join.get(User.Fields.realName), param.getRealName())); list.add(criteriaBuilder.like(join.get(User.Fields.realName), "%" + param.getRealName() + "%"));
} }
if (param.getStatus() != null) { if (param.getStatus() != null) {
list.add( list.add(
...@@ -158,7 +183,7 @@ public class FenceAlarmServiceImpl implements FenceAlarmService { ...@@ -158,7 +183,7 @@ public class FenceAlarmServiceImpl implements FenceAlarmService {
} }
if (param.getEndTime() != null) { if (param.getEndTime() != null) {
list.add( list.add(
criteriaBuilder.lessThanOrEqualTo(root.get(LocationFenceAlarm.Fields.endTime), param.getEndTime()) criteriaBuilder.lessThanOrEqualTo(root.get(LocationFenceAlarm.Fields.startTime), param.getEndTime())
); );
} }
Predicate[] array = list.toArray(new Predicate[0]); Predicate[] array = list.toArray(new Predicate[0]);
......
...@@ -28,28 +28,26 @@ public class TimeUtil { ...@@ -28,28 +28,26 @@ public class TimeUtil {
int beginWeek = transform(beginTime.charAt(2)); int beginWeek = transform(beginTime.charAt(2));
int endWeek = transform(endTime.charAt(2)); int endWeek = transform(endTime.charAt(2));
int nowWeek = transform(source.charAt(1)); int nowWeek = transform(source.charAt(1));
if (nowWeek < beginWeek || nowWeek > endWeek) {
return false; String beginHour = beginTime.substring(4, 6);
} String endHour = endTime.substring(4, 6);
int beginHour = Integer.parseInt(beginTime.substring(4, 6)); String nowHour = source.substring(3, 5);
int endHour = Integer.parseInt(endTime.substring(4, 6));
int nowHour = Integer.parseInt(beginTime.substring(3, 5)); String beginMinute = beginTime.substring(7, 9);
if (nowHour < beginHour || nowHour > endHour) { String endMinute = endTime.substring(7, 9);
return false; String nowMinute = source.substring(6, 8);
}
int beginMinute = Integer.parseInt(beginTime.substring(7, 9)); String beginSecond = beginTime.substring(10);
int endMinute = Integer.parseInt(endTime.substring(7, 9)); String endSecond = endTime.substring(10);
int nowMinute = Integer.parseInt(beginTime.substring(6, 8)); String nowSecond = source.substring(9);
if (nowMinute < beginMinute || nowHour > endMinute) {
return false; String beginString = beginWeek + beginHour + beginMinute + beginSecond;
} String endString = endWeek + endHour + endMinute + endSecond;
int beginSecond = Integer.parseInt(beginTime.substring(10)); String nowString = nowWeek + nowHour + nowMinute + nowSecond;
int endSecond = Integer.parseInt(endTime.substring(10)); int begin = Integer.parseInt(beginString);
int nowSecond = Integer.parseInt(beginTime.substring(9)); int end = Integer.parseInt(endString);
if (nowSecond < beginSecond || nowSecond > endSecond) { int now = Integer.parseInt(nowString);
return false; return now >= begin && now <= end;
}
return true;
} }
private static int transform(char source) { private static int transform(char source) {
......
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.vo.location.fence;
import com.yiring.app.constant.alarm.InformMannerEnum;
import com.yiring.app.constant.alarm.ReceiveStatusEnum;
import com.yiring.app.domain.location.FenceAlarmPushLog;
import io.swagger.annotations.ApiModel;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Comment;
/**
* @author tml
* @version 1.0
* @date 2022/5/18 9:56
*/
@ApiModel("围栏报警推送记录")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class FenceAlarmPushLogVo implements Serializable {
@Serial
private static final long serialVersionUID = 4628469269093052929L;
@Comment("报警接受人")
private String name;
@Comment("联系电话")
private String phone;
@Comment("通知方式: 1-app消息 2-短信通知 3-电话通知")
private String informManner;
@Comment("通知状态: 1-成功 2-失败")
private String status;
@Comment("接受时间")
private LocalDateTime time;
public static FenceAlarmPushLogVo transform(FenceAlarmPushLog pushLog) {
return FenceAlarmPushLogVo
.builder()
.name(pushLog.getUser().getRealName() + "(" + pushLog.getUser().getDepartment().getName() + ")")
.phone(pushLog.getUser().getMobile())
.informManner(InformMannerEnum.getByCode(pushLog.getInformManner()))
.status(ReceiveStatusEnum.getByCode(pushLog.getStatus()))
.time(pushLog.getTime())
.build();
}
}
...@@ -4,12 +4,14 @@ package com.yiring.app.vo.location.fence; ...@@ -4,12 +4,14 @@ package com.yiring.app.vo.location.fence;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.yiring.app.constant.alarm.FenceTypeEnum; import com.yiring.app.constant.alarm.FenceTypeEnum;
import com.yiring.app.constant.alarm.InformMannerEnum;
import com.yiring.app.domain.location.LocationFenceAlarm; import com.yiring.app.domain.location.LocationFenceAlarm;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
...@@ -70,7 +72,22 @@ public class FenceAlarmVo implements Serializable { ...@@ -70,7 +72,22 @@ public class FenceAlarmVo implements Serializable {
@ApiModelProperty(value = "报警状态", example = "报警中") @ApiModelProperty(value = "报警状态", example = "报警中")
private String statusName; private String statusName;
@ApiModelProperty(value = "通知方式", example = "app消息, 短信, 电话")
private String informManner;
public static FenceAlarmVo transform(LocationFenceAlarm fenceAlarm) { public static FenceAlarmVo transform(LocationFenceAlarm fenceAlarm) {
String recipient = fenceAlarm
.getPushLogs()
.stream()
.map(e -> e.getUser().getRealName())
.distinct()
.collect(Collectors.joining(", "));
String informManner = fenceAlarm
.getPushLogs()
.stream()
.map(e -> InformMannerEnum.getByCode(e.getInformManner()))
.distinct()
.collect(Collectors.joining(", "));
return FenceAlarmVo return FenceAlarmVo
.builder() .builder()
.id(fenceAlarm.getId()) .id(fenceAlarm.getId())
...@@ -83,9 +100,9 @@ public class FenceAlarmVo implements Serializable { ...@@ -83,9 +100,9 @@ public class FenceAlarmVo implements Serializable {
.startTime(fenceAlarm.getStartTime()) .startTime(fenceAlarm.getStartTime())
.endTime(fenceAlarm.getEndTime()) .endTime(fenceAlarm.getEndTime())
.alarmTypeName(fenceAlarm.getType().getName()) .alarmTypeName(fenceAlarm.getType().getName())
//todo .recipient(recipient)
//.recipient()
.statusName(fenceAlarm.getStatus().text()) .statusName(fenceAlarm.getStatus().text())
.informManner(informManner)
.build(); .build();
} }
} }
...@@ -4,6 +4,7 @@ package com.yiring.app.web.alarm; ...@@ -4,6 +4,7 @@ package com.yiring.app.web.alarm;
import com.yiring.app.constant.alarm.FenceTypeEnum; import com.yiring.app.constant.alarm.FenceTypeEnum;
import com.yiring.app.constant.alarm.RelevanceParamEnum; import com.yiring.app.constant.alarm.RelevanceParamEnum;
import com.yiring.app.domain.alarm.AlarmType; import com.yiring.app.domain.alarm.AlarmType;
import com.yiring.app.job.FenceAlarmJob;
import com.yiring.app.param.alarm.AlarmConditionParam; import com.yiring.app.param.alarm.AlarmConditionParam;
import com.yiring.app.param.alarm.AlarmTypeAddParam; import com.yiring.app.param.alarm.AlarmTypeAddParam;
import com.yiring.app.param.alarm.AlarmTypeModifyParam; import com.yiring.app.param.alarm.AlarmTypeModifyParam;
...@@ -45,6 +46,9 @@ public class AlarmTypeController { ...@@ -45,6 +46,9 @@ public class AlarmTypeController {
@Resource @Resource
private AlarmService alarmService; private AlarmService alarmService;
@Resource
private FenceAlarmJob fenceAlarmJob;
@ApiOperation(value = "添加报警类型") @ApiOperation(value = "添加报警类型")
@PostMapping("/addAlarmType") @PostMapping("/addAlarmType")
public Result<String> addAlarmType(@Valid AlarmTypeAddParam param) { public Result<String> addAlarmType(@Valid AlarmTypeAddParam param) {
...@@ -101,4 +105,10 @@ public class AlarmTypeController { ...@@ -101,4 +105,10 @@ public class AlarmTypeController {
public void exportAlarmType(@Valid AlarmConditionParam conditionParam, HttpServletResponse response) { public void exportAlarmType(@Valid AlarmConditionParam conditionParam, HttpServletResponse response) {
alarmService.exportAlarmType(conditionParam, response); alarmService.exportAlarmType(conditionParam, response);
} }
@ApiOperation(value = "test")
@PostMapping("/test")
public void test() {
fenceAlarmJob.scanAlarmHandler();
}
} }
...@@ -5,6 +5,7 @@ import com.yiring.app.param.analysis.history.HistoryRouteConditionParam; ...@@ -5,6 +5,7 @@ import com.yiring.app.param.analysis.history.HistoryRouteConditionParam;
import com.yiring.app.service.analysis.history.HistoryRouteService; import com.yiring.app.service.analysis.history.HistoryRouteService;
import com.yiring.app.vo.analysis.history.HistoryRouteVo; import com.yiring.app.vo.analysis.history.HistoryRouteVo;
import com.yiring.common.core.Result; import com.yiring.common.core.Result;
import com.yiring.common.param.PageParam;
import com.yiring.common.vo.PageVo; import com.yiring.common.vo.PageVo;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
...@@ -13,6 +14,7 @@ import javax.servlet.http.HttpServletResponse; ...@@ -13,6 +14,7 @@ import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid; import javax.validation.Valid;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
...@@ -39,6 +41,15 @@ public class HistoryRouteController { ...@@ -39,6 +41,15 @@ public class HistoryRouteController {
return historyRouteService.findByCondition(param); return historyRouteService.findByCondition(param);
} }
@ApiOperation("分页查询历史轨迹")
@GetMapping("/findByPage")
public Result<PageVo<HistoryRouteVo>> findByPage(
@Valid HistoryRouteConditionParam param,
@Valid PageParam pageParam
) {
return historyRouteService.findByPage(param, pageParam);
}
@ApiOperation(value = "导出历史轨迹", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) @ApiOperation(value = "导出历史轨迹", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
@PostMapping("/exportHistoryRoute") @PostMapping("/exportHistoryRoute")
public void exportHistoryRoute(@Valid HistoryRouteConditionParam param, HttpServletResponse response) { public void exportHistoryRoute(@Valid HistoryRouteConditionParam param, HttpServletResponse response) {
......
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.web.location.fence;
import com.yiring.app.param.location.fence.FenceAlarmPushLogConditionParam;
import com.yiring.app.service.location.fence.FenceAlarmPushLogService;
import com.yiring.app.vo.location.fence.FenceAlarmPushLogVo;
import com.yiring.common.core.Result;
import com.yiring.common.param.PageParam;
import com.yiring.common.vo.PageVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import javax.annotation.Resource;
import javax.validation.Valid;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author tml
* @version 1.0
* @date 2022/5/18 10:21
*/
@Api(tags = "围栏报警推送记录")
@RestController
@RequestMapping("/push/log")
public class FenceAlarmPushLogController {
@Resource
private FenceAlarmPushLogService fenceAlarmPushLogService;
@ApiOperation(value = "查询推送记录列表")
@GetMapping("/findList")
public Result<PageVo<FenceAlarmPushLogVo>> findList(
@Valid FenceAlarmPushLogConditionParam conditionParam,
@Valid PageParam pageParam
) {
return fenceAlarmPushLogService.findList(conditionParam, pageParam);
}
}
...@@ -33,7 +33,7 @@ import org.springframework.web.bind.annotation.*; ...@@ -33,7 +33,7 @@ import org.springframework.web.bind.annotation.*;
@Validated @Validated
@SuppressWarnings({ "deprecation" }) @SuppressWarnings({ "deprecation" })
@Api(tags = "报警规则", description = "AlarmRule") @Api(tags = "报警规则:报警给谁", description = "AlarmRule")
@RestController @RestController
@RequestMapping("/alarm/rule") @RequestMapping("/alarm/rule")
public class LocationAlarmRuleController { public class LocationAlarmRuleController {
......
...@@ -27,7 +27,7 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -27,7 +27,7 @@ import org.springframework.web.bind.annotation.RestController;
@Validated @Validated
@SuppressWarnings({ "deprecation" }) @SuppressWarnings({ "deprecation" })
@Api(tags = "电子围栏报警规则", description = "FenceRule") @Api(tags = "报警规则:什么情况报警", description = "FenceRule")
@RestController @RestController
@RequestMapping("/location/rule") @RequestMapping("/location/rule")
public class LocationFenceRuleController { public class LocationFenceRuleController {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论