Commit a3f9b5f1 by 朱海

[chg]顾客批次,店内区域匹配修改逻辑

1 parent 351cd534
package com.viontech.keliu.dao;
import com.viontech.keliu.entity.DPersonBatch;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
/**
* Created with IntelliJ IDEA.
*
* @author: zhuhai
* Date: 2024-05-30
* Time: 18:04
*/
@Repository
public class DPersonBatchDao {
@Resource
private JdbcTemplate jdbcTemplate;
public List<DPersonBatch> getPersonBatchList(Long mallId, Date countDate) {
String sql = "select * from d_person_batch where mall_id = ? and count_date = ?";
return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(DPersonBatch.class), mallId, countDate);
}
}
......@@ -52,7 +52,7 @@ public class FaceRecognitionDao {
}
public List<Person> queryFaceRecognitionList(Long mallId, Date countDate) {
String sql = "select account_id,mall_id,gate_id,person_unid,direction,countdate as countDate,person_type,age,gender," +
String sql = "select account_id,mall_id,gate_id,person_unid,direction,track_time,countdate as countDate,person_type,age,gender," +
"counttime as countTime from d_face_recognition where mall_id = ? and countdate = ? " +
"and direction in(-1,1,6) order by person_unid asc, counttime asc;";
......
package com.viontech.keliu.entity;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* Created with IntelliJ IDEA.
* 接待详情表
* @author: zhuhai
* Date: 2023-12-20
* Time: 16:23
*/
@Data
public class DPersonBatch implements Serializable {
private static final long serialVersionUID = -8440383229421767268L;
private Long id;
private Long accountId;
private Long mallId;
private String personUnid;
/**
* 进店时间
*/
private Date arriveTime;
/**
* 离店时间
*/
private Date leaveTime;
private Date countDate;
private String batchId;
}
\ No newline at end of file
......@@ -24,5 +24,6 @@ public class Person {
private Integer direction;
private Integer age;
private Integer gender;
private Integer trackTime;
}
\ No newline at end of file
package com.viontech.keliu.service.impl;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Matcher;
import com.alibaba.fastjson.JSON;
import com.viontech.keliu.dao.BGateDao;
import com.viontech.keliu.dao.ConfigParamDao;
import com.viontech.keliu.dao.DPersonBatchDao;
import com.viontech.keliu.dao.DPersonReceptionDao;
import com.viontech.keliu.dao.DPersonRecordDao;
import com.viontech.keliu.dao.DPersonTrackDetailDao;
import com.viontech.keliu.dao.FaceRecognitionDao;
import com.viontech.keliu.entity.DPersonBatch;
import com.viontech.keliu.entity.DPersonReception;
import com.viontech.keliu.entity.DPersonRecord;
import com.viontech.keliu.entity.DPersonTrackDetail;
......@@ -19,6 +22,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.ArrayList;
......@@ -59,9 +63,17 @@ public class PersonRecordServiceImpl implements PersonRecordService {
@Resource
private DPersonTrackDetailDao dPersonTrackDetailDao;
@Resource
private DPersonBatchDao dPersonBatchDao;
@Value("${attention.time.threshold:30}")
private Long attentionThreshold;
@Value("${reid.person.batch.mall:}")
private List<Long> personBatchMallIds;
@Override
public void handlePersonRecord(Long mallId, Date countDate) {
......@@ -136,10 +148,14 @@ public class PersonRecordServiceImpl implements PersonRecordService {
//按进店时间排序
List<PersonInOutDetail> inOutDetailList = personInOutDetailList.stream().sorted(Comparator.comparing(PersonInOutDetail::getArriveTime)).collect(Collectors.toList());
//处理分组信息
inOutDetailList = personGroupCompute(mallId, inOutDetailList);
List<DPersonRecord> dPersonRecordList = handlePersonRecordData(inOutDetailList);
List<PersonInOutDetail> customerList = inOutDetailList.stream().filter(p -> p.getPersonType() == 0).collect(Collectors.toList());
//处理顾客分组信息
customerList = personGroupCompute(mallId, customerList, countDate);
List<PersonInOutDetail> staffList = inOutDetailList.stream().filter(p -> p.getPersonType() == 1).collect(Collectors.toList());
List<PersonInOutDetail> allList = new ArrayList<>();
allList.addAll(customerList);
allList.addAll(staffList);
List<DPersonRecord> dPersonRecordList = handlePersonRecordData(allList);
for (DPersonRecord dPersonRecord : dPersonRecordList) {
dPersonRecordDao.createDPersonRecordBatch(Collections.singletonList(dPersonRecord));
if (CollectionUtils.isNotEmpty(dPersonRecord.getPersonTrackDetailList())) {
......@@ -158,40 +174,60 @@ public class PersonRecordServiceImpl implements PersonRecordService {
* @param personList
* @return
*/
private List<PersonInOutDetail> personGroupCompute(Long mallId, List<PersonInOutDetail> personList) {
private List<PersonInOutDetail> personGroupCompute(Long mallId, List<PersonInOutDetail> personList, Date countDate) {
List<PersonInOutDetail> resultList = new ArrayList<>();
//获取分组间隔配置
String configValue = configParamDao.getConfigParamByMallIdAndConfigKey(mallId, "personGroupInterval");
if (configValue == null) {
return personList;
}
long interval = Long.parseLong(configValue);
for (int i = 0; i < personList.size() - 1; ++i) {
PersonInOutDetail pvo1 = personList.get(i);
PersonInOutDetail pvo2 = personList.get(i + 1);
Long time1 = pvo1.getArriveTime().getTime();
Long time2 = pvo2.getArriveTime().getTime();
long seconds = (time2 - time1) / 1000L;
//同一组顾客
if (seconds < interval) {
if (pvo1.getGroupUnid() == null) {
pvo1.setGroupUnid(UUID.randomUUID().toString());
}
pvo2.setGroupUnid(pvo1.getGroupUnid());
} else {
//不是同一组顾客
if (pvo1.getGroupUnid() == null) {
pvo1.setGroupUnid(UUID.randomUUID().toString());
if (CollectionUtils.isNotEmpty(personBatchMallIds) && personBatchMallIds.contains(mallId)) {
//先判断是否从全天分析获取了批次信息,如果有,使用全天分析的批次结果
List<DPersonBatch> personBatchList = dPersonBatchDao.getPersonBatchList(mallId, countDate);
if (CollectionUtils.isNotEmpty(personBatchList)) {
Map<String, String> batchMap = personBatchList.stream().collect(Collectors.toMap(v -> v.getPersonUnid() + DateUtil.formatDateTime(v.getArriveTime()), DPersonBatch::getBatchId, (v1, v2) -> v1));
for (PersonInOutDetail personInOutDetail : personList) {
String key = personInOutDetail.getPersonUnid() + DateUtil.formatDateTime(personInOutDetail.getArriveTime());
String batchId = batchMap.get(key);
if (StringUtils.hasLength(batchId)) {
personInOutDetail.setGroupUnid(batchId);
} else {
personInOutDetail.setGroupUnid(UUID.randomUUID().toString());
}
resultList.add(personInOutDetail);
}
pvo2.setGroupUnid(UUID.randomUUID().toString());
}
resultList.add(pvo1);
if (i == personList.size() - 2) {
resultList.add(pvo2);
return resultList;
}
}
if (CollectionUtils.isEmpty(resultList)) {
long interval = Long.parseLong(configValue);
for (int i = 0; i < personList.size() - 1; ++i) {
PersonInOutDetail pvo1 = personList.get(i);
PersonInOutDetail pvo2 = personList.get(i + 1);
Long time1 = pvo1.getArriveTime().getTime();
Long time2 = pvo2.getArriveTime().getTime();
long seconds = (time2 - time1) / 1000L;
//同一组顾客
if (seconds < interval) {
if (pvo1.getGroupUnid() == null) {
pvo1.setGroupUnid(UUID.randomUUID().toString());
}
pvo2.setGroupUnid(pvo1.getGroupUnid());
} else {
//不是同一组顾客
if (pvo1.getGroupUnid() == null) {
pvo1.setGroupUnid(UUID.randomUUID().toString());
}
pvo2.setGroupUnid(UUID.randomUUID().toString());
}
resultList.add(pvo1);
if (i == personList.size() - 2) {
resultList.add(pvo2);
}
}
}
return resultList;
}
......@@ -303,21 +339,61 @@ public class PersonRecordServiceImpl implements PersonRecordService {
}
//进出匹配的
if (person.getDirection() == -1 && arrivePerson != null) {
DPersonTrackDetail personTrackDetail = new DPersonTrackDetail();
personTrackDetail.setAccountId(person.getAccountId());
personTrackDetail.setMallId(person.getMallId());
personTrackDetail.setGateId(person.getGateId());
personTrackDetail.setPersonUnid(person.getPersonUnid());
personTrackDetail.setGroupUnid(groupUnid);
personTrackDetail.setArriveTime(arrivePerson.getCountTime());
personTrackDetail.setLeaveTime(person.getCountTime());
long milli = personTrackDetail.getLeaveTime().getTime() - personTrackDetail.getArriveTime().getTime();
personTrackDetail.setVisitDuration(milli);
personTrackDetail.setIsEngage(isEngage);
personTrackDetail.setEngageTime(engageTime);
personTrackDetail.setCountDate(person.getCountDate());
Date arriveTime = arrivePerson.getCountTime();
Date leaveTime = person.getCountTime();
long milli = leaveTime.getTime() - arriveTime.getTime();
//停留时长超过5分钟,需要将改匹配对进行拆分
if (milli >= 300000L && personBatchMallIds.contains(person.getMallId())) {
log.info("personUnid:{},在区域内停留时间超过5分钟,进行拆分", person.getPersonUnid());
Integer inTrackTime = arrivePerson.getTrackTime();
if (inTrackTime != null && inTrackTime > 0) {
DPersonTrackDetail personTrackDetail = new DPersonTrackDetail();
personTrackDetail.setAccountId(person.getAccountId());
personTrackDetail.setMallId(person.getMallId());
personTrackDetail.setGateId(person.getGateId());
personTrackDetail.setPersonUnid(person.getPersonUnid());
personTrackDetail.setGroupUnid(groupUnid);
personTrackDetail.setArriveTime(arriveTime);
personTrackDetail.setLeaveTime(DateUtil.offsetSecond(arriveTime, inTrackTime));
personTrackDetail.setVisitDuration(personTrackDetail.getLeaveTime().getTime() - personTrackDetail.getArriveTime().getTime());
personTrackDetail.setIsEngage(isEngage);
personTrackDetail.setEngageTime(engageTime);
personTrackDetail.setCountDate(person.getCountDate());
dPersonTrackDetailList.add(personTrackDetail);
}
Integer outTrackTime = person.getTrackTime();
if (outTrackTime != null && outTrackTime > 0) {
DPersonTrackDetail personTrackDetail = new DPersonTrackDetail();
personTrackDetail.setAccountId(person.getAccountId());
personTrackDetail.setMallId(person.getMallId());
personTrackDetail.setGateId(person.getGateId());
personTrackDetail.setPersonUnid(person.getPersonUnid());
personTrackDetail.setGroupUnid(groupUnid);
personTrackDetail.setArriveTime(DateUtil.offsetSecond(leaveTime, -outTrackTime));
personTrackDetail.setLeaveTime(leaveTime);
personTrackDetail.setVisitDuration(personTrackDetail.getLeaveTime().getTime() - personTrackDetail.getArriveTime().getTime());
personTrackDetail.setIsEngage(isEngage);
personTrackDetail.setEngageTime(engageTime);
personTrackDetail.setCountDate(person.getCountDate());
dPersonTrackDetailList.add(personTrackDetail);
}
} else {
DPersonTrackDetail personTrackDetail = new DPersonTrackDetail();
personTrackDetail.setAccountId(person.getAccountId());
personTrackDetail.setMallId(person.getMallId());
personTrackDetail.setGateId(person.getGateId());
personTrackDetail.setPersonUnid(person.getPersonUnid());
personTrackDetail.setGroupUnid(groupUnid);
personTrackDetail.setArriveTime(arriveTime);
personTrackDetail.setLeaveTime(leaveTime);
personTrackDetail.setVisitDuration(personTrackDetail.getLeaveTime().getTime() - personTrackDetail.getArriveTime().getTime());
personTrackDetail.setIsEngage(isEngage);
personTrackDetail.setEngageTime(engageTime);
personTrackDetail.setCountDate(person.getCountDate());
dPersonTrackDetailList.add(personTrackDetail);
}
arrivePerson = null;
dPersonTrackDetailList.add(personTrackDetail);
}
isEngage = 0;
engageTime = null;
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!