Commit 23ed153f by 朱海

[chg]d_person_record表按照店内停留时间和是否看车进行过滤

1 parent 7b1527d1
package com.viontech.keliu.dao; package com.viontech.keliu.dao;
import com.viontech.keliu.entity.SConfigParam; import com.viontech.keliu.entity.SConfigParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
...@@ -17,6 +19,7 @@ import java.util.stream.Collectors; ...@@ -17,6 +19,7 @@ import java.util.stream.Collectors;
* Time: 14:29 * Time: 14:29
*/ */
@Repository @Repository
@Slf4j
public class ConfigParamDao { public class ConfigParamDao {
@Resource @Resource
...@@ -24,7 +27,12 @@ public class ConfigParamDao { ...@@ -24,7 +27,12 @@ public class ConfigParamDao {
public String getConfigParamByMallIdAndConfigKey(Long mallId, String configKey) { public String getConfigParamByMallIdAndConfigKey(Long mallId, String configKey) {
String sql = "select mall_id, config_key, config_value from s_config_params where (mall_id = ? or mall_id is null) and config_key = ? order by mall_id asc limit 1;"; String sql = "select mall_id, config_key, config_value from s_config_params where (mall_id = ? or mall_id is null) and config_key = ? order by mall_id asc limit 1;";
SConfigParam configParam = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(SConfigParam.class), mallId, configKey); SConfigParam configParam = null;
try {
configParam = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(SConfigParam.class), mallId, configKey);
} catch (Exception e) {
log.error("获取配置异常", e);
}
return configParam == null ? null : configParam.getConfigValue(); return configParam == null ? null : configParam.getConfigValue();
} }
......
...@@ -64,7 +64,7 @@ public class FaceRecognitionDao { ...@@ -64,7 +64,7 @@ public class FaceRecognitionDao {
DateTimeParam dateTimeParam = dateTimeParamService.getDateTimeParam(mallId, countDate); DateTimeParam dateTimeParam = dateTimeParamService.getDateTimeParam(mallId, countDate);
String sql = "select account_id,mall_id,gate_id,person_unid,direction,track_time,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 = :mallId and countdate between :startDate and :endDate and counttime >= :startTime and counttime < :endTime " + "counttime as countTime from d_face_recognition where mall_id = :mallId and countdate between :startDate and :endDate and counttime >= :startTime and counttime < :endTime " +
"and direction in(-1,1,6) order by person_unid asc, counttime asc;"; "and direction in(-1,1,6) and person_type = 0 order by person_unid asc, counttime asc;";
Map<String, Object> queryMap = new HashMap<>(); Map<String, Object> queryMap = new HashMap<>();
queryMap.put("mallId", mallId); queryMap.put("mallId", mallId);
queryMap.put("startDate", dateTimeParam.getStartDate()); queryMap.put("startDate", dateTimeParam.getStartDate());
......
package com.viontech.keliu.entity;
import lombok.Data;
import java.util.Date;
/**
* Created with IntelliJ IDEA.
*
* @author: zhuhai
* Date: 2023-03-28
* Time: 11:25
*/
@Data
public class CustomerGroupResult {
private Long gateId;
private Date countTime;
private long singleGroup; // 单人组
private long doubleGroup; // 双人组
private long doubleFamilyGroup; // 双人家庭组
private long doubleLoverGroup; // 双人情侣组
private long doublePartnerGroup; // 双人伙伴组
private long multipleGroup; // 多人组
private long multipleFamilyGroup; // 多人家庭组
private long multiplePartnerGroup; // 多人伙伴组
public long getGroupNum() {
return singleGroup + doubleGroup + multipleGroup;
}
}
\ No newline at end of file \ No newline at end of file
package com.viontech.keliu.entity;
import lombok.Data;
import java.util.Date;
/**
* Created with IntelliJ IDEA.
*
* @author: zhuhai
* Date: 2024-08-13
* Time: 18:12
*/
@Data
public class DMallDayFaceRecognitionSta {
private Long mallId;
private Long personCount;
private Long customCount;
private Long maleCount;
private Long femaleCount;
private String maleStage;
private String femaleStage;
private Date counttime;
private int[] maleStageArr;
private int[] femaleStageArr;
private Date countdate;
private Long groupNum;
private Long singleGroupNum;
private Long doubleGroupNum;
private Long multipleGroupNum;
private Long familyGroupNum;
/**
* 情侣组
*/
private Long loverGroupNum;
/**
* 伙伴组
*/
private Long partnerGroupNum;
private Long staffCount;
}
\ No newline at end of file \ No newline at end of file
...@@ -2,7 +2,6 @@ package com.viontech.keliu.service.impl; ...@@ -2,7 +2,6 @@ package com.viontech.keliu.service.impl;
import cn.hutool.core.collection.ListUtil; import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Matcher;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.viontech.keliu.dao.BGateDao; import com.viontech.keliu.dao.BGateDao;
import com.viontech.keliu.dao.ConfigParamDao; import com.viontech.keliu.dao.ConfigParamDao;
...@@ -11,6 +10,8 @@ import com.viontech.keliu.dao.DPersonReceptionDao; ...@@ -11,6 +10,8 @@ import com.viontech.keliu.dao.DPersonReceptionDao;
import com.viontech.keliu.dao.DPersonRecordDao; import com.viontech.keliu.dao.DPersonRecordDao;
import com.viontech.keliu.dao.DPersonTrackDetailDao; import com.viontech.keliu.dao.DPersonTrackDetailDao;
import com.viontech.keliu.dao.FaceRecognitionDao; import com.viontech.keliu.dao.FaceRecognitionDao;
import com.viontech.keliu.entity.CustomerGroupResult;
import com.viontech.keliu.entity.DMallDayFaceRecognitionSta;
import com.viontech.keliu.entity.DPersonBatch; import com.viontech.keliu.entity.DPersonBatch;
import com.viontech.keliu.entity.DPersonReception; import com.viontech.keliu.entity.DPersonReception;
import com.viontech.keliu.entity.DPersonRecord; import com.viontech.keliu.entity.DPersonRecord;
...@@ -20,12 +21,16 @@ import com.viontech.keliu.entity.PersonInOutDetail; ...@@ -20,12 +21,16 @@ import com.viontech.keliu.entity.PersonInOutDetail;
import com.viontech.keliu.service.PersonRecordService; import com.viontech.keliu.service.PersonRecordService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date; import java.util.Date;
...@@ -71,8 +76,8 @@ public class PersonRecordServiceImpl implements PersonRecordService { ...@@ -71,8 +76,8 @@ public class PersonRecordServiceImpl implements PersonRecordService {
@Value("${reid.person.batch.mall:}") @Value("${reid.person.batch.mall:}")
private List<Long> personBatchMallIds; private List<Long> personBatchMallIds;
@Autowired
private JdbcTemplate jdbcTemplate;
@Override @Override
...@@ -83,6 +88,9 @@ public class PersonRecordServiceImpl implements PersonRecordService { ...@@ -83,6 +88,9 @@ public class PersonRecordServiceImpl implements PersonRecordService {
if (CollectionUtils.isEmpty(personList)) { if (CollectionUtils.isEmpty(personList)) {
return; return;
} }
Long excludePersonTime = getExcludePersonTime(mallId);
Integer filterAttention = getFilterAttention(mallId);
//出入口gateId //出入口gateId
List<Long> gateIds = bGateDao.getMallInOutGateIds(mallId); List<Long> gateIds = bGateDao.getMallInOutGateIds(mallId);
//按personUnid分组 //按personUnid分组
...@@ -135,6 +143,7 @@ public class PersonRecordServiceImpl implements PersonRecordService { ...@@ -135,6 +143,7 @@ public class PersonRecordServiceImpl implements PersonRecordService {
personInOutDetail.setPersonType(inPerson.getPersonType()); personInOutDetail.setPersonType(inPerson.getPersonType());
personInOutDetail.setInsidePersonList(inSidePersonList); personInOutDetail.setInsidePersonList(inSidePersonList);
personInOutDetailList.add(personInOutDetail); personInOutDetailList.add(personInOutDetail);
} }
log.info("personUnid:{}, inSidePersonList:{}", inPerson.getPersonUnid(), JSON.toJSON(inSidePersonList)); log.info("personUnid:{}, inSidePersonList:{}", inPerson.getPersonUnid(), JSON.toJSON(inSidePersonList));
...@@ -148,21 +157,63 @@ public class PersonRecordServiceImpl implements PersonRecordService { ...@@ -148,21 +157,63 @@ public class PersonRecordServiceImpl implements PersonRecordService {
//按进店时间排序 //按进店时间排序
List<PersonInOutDetail> inOutDetailList = personInOutDetailList.stream().sorted(Comparator.comparing(PersonInOutDetail::getArriveTime)).collect(Collectors.toList()); List<PersonInOutDetail> inOutDetailList = personInOutDetailList.stream().sorted(Comparator.comparing(PersonInOutDetail::getArriveTime)).collect(Collectors.toList());
List<PersonInOutDetail> customerList = inOutDetailList.stream().filter(p -> p.getPersonType() != 1).collect(Collectors.toList()); //List<PersonInOutDetail> customerList = inOutDetailList.stream().filter(p -> p.getPersonType() != 1).collect(Collectors.toList());
//处理顾客分组信息 //处理顾客分组信息
customerList = personGroupCompute(mallId, customerList, countDate); inOutDetailList = personGroupCompute(mallId, inOutDetailList, countDate);
List<PersonInOutDetail> staffList = inOutDetailList.stream().filter(p -> p.getPersonType() == 1).collect(Collectors.toList()); //List<PersonInOutDetail> staffList = inOutDetailList.stream().filter(p -> p.getPersonType() == 1).collect(Collectors.toList());
List<PersonInOutDetail> allList = new ArrayList<>(); //List<PersonInOutDetail> allList = new ArrayList<>();
allList.addAll(customerList); //allList.addAll(customerList);
allList.addAll(staffList); //allList.addAll(staffList);
List<DPersonRecord> dPersonRecordList = handlePersonRecordData(allList); List<DPersonRecord> dPersonRecordList = handlePersonRecordData(inOutDetailList);
for (DPersonRecord dPersonRecord : dPersonRecordList) { //同一批次,只要有一个人被接待,则这个批次所有人都被接待
List<DPersonRecord> recordList = new ArrayList<>();
//List<DPersonRecord> staffRecordList = dPersonRecordList.stream().filter(dPersonRecord -> dPersonRecord.getPersonType() != 0).collect(Collectors.toList());
//recordList.addAll(staffRecordList);
//先顾客分组
Map<String, List<DPersonRecord>> customRecordMap = dPersonRecordList.stream().filter(dPersonRecord -> dPersonRecord.getPersonType() == 0).collect(Collectors.groupingBy(DPersonRecord::getGroupUnid));
customRecordMap.forEach((k, v) -> {
//所有没有被接待的
List<DPersonRecord> noList = v.stream().filter(dPersonRecord -> dPersonRecord.getReceptionCount() == 0).collect(Collectors.toList());
//被接待的
List<DPersonRecord> yesList = v.stream().filter(dPersonRecord -> dPersonRecord.getReceptionCount() > 0).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(noList)) {
//找出该组中被接待的一条记录
DPersonRecord dPersonRecord1 = yesList.stream().min(Comparator.comparing(DPersonRecord::getReceptionTime)).orElse(null);
if (dPersonRecord1 != null) {
noList.forEach(dPersonRecord -> {
dPersonRecord.setReceptionCount(1);
Date receptionTime = dPersonRecord1.getReceptionTime();
if (receptionTime.before(dPersonRecord.getArriveTime())) {
receptionTime = DateUtil.offsetSecond(dPersonRecord.getArriveTime(), 1);
}
dPersonRecord.setReceptionTime(receptionTime);
dPersonRecord.setReceptionDuration(dPersonRecord1.getReceptionDuration());
});
}
}
recordList.addAll(yesList);
recordList.addAll(noList);
});
List<DPersonRecord> personRecordList = new ArrayList<>();
for (DPersonRecord dPersonRecord : recordList) {
//排除掉短时间在店内的记录
if (dPersonRecord.getLeaveTime() != null && dPersonRecord.getVisitDuration() < excludePersonTime * 60 * 1000) {
continue;
}
//判断是否看车
if (filterAttention == 1 && dPersonRecord.getAttentionCount() == 0) {
continue;
}
personRecordList.add(dPersonRecord);
dPersonRecordDao.createDPersonRecordBatch(Collections.singletonList(dPersonRecord)); dPersonRecordDao.createDPersonRecordBatch(Collections.singletonList(dPersonRecord));
if (CollectionUtils.isNotEmpty(dPersonRecord.getPersonTrackDetailList())) { if (CollectionUtils.isNotEmpty(dPersonRecord.getPersonTrackDetailList())) {
dPersonTrackDetailDao.createDPersonTrackDetailBatch(dPersonRecord.getPersonTrackDetailList()); dPersonTrackDetailDao.createDPersonTrackDetailBatch(dPersonRecord.getPersonTrackDetailList());
} }
} }
//修改统计数据
updateFaceRecognitionSta(mallId, countDate, personRecordList);
...@@ -272,7 +323,6 @@ public class PersonRecordServiceImpl implements PersonRecordService { ...@@ -272,7 +323,6 @@ public class PersonRecordServiceImpl implements PersonRecordService {
dPersonRecord.setReceptionTime(startTime); dPersonRecord.setReceptionTime(startTime);
dPersonRecord.setReceptionDuration(personReceptionList.stream().mapToLong(DPersonReception::getDuration).sum()); dPersonRecord.setReceptionDuration(personReceptionList.stream().mapToLong(DPersonReception::getDuration).sum());
} }
//进出匹配的人在店内的抓拍记录 //进出匹配的人在店内的抓拍记录
List<Person> insidePersonList = personInOutDetail.getInsidePersonList(); List<Person> insidePersonList = personInOutDetail.getInsidePersonList();
if (CollectionUtils.isEmpty(insidePersonList)) { if (CollectionUtils.isEmpty(insidePersonList)) {
...@@ -415,4 +465,128 @@ public class PersonRecordServiceImpl implements PersonRecordService { ...@@ -415,4 +465,128 @@ public class PersonRecordServiceImpl implements PersonRecordService {
} }
private Long getExcludePersonTime(Long mallId) {
String excludePersonTime = configParamDao.getConfigParamByMallIdAndConfigKey(mallId, "excludePersonTime");
return excludePersonTime == null ? 0L : Long.parseLong(excludePersonTime);
}
private Integer getFilterAttention(Long mallId) {
String filterAttention = configParamDao.getConfigParamByMallIdAndConfigKey(mallId, "filterAttention");
return filterAttention == null ? 0 : Integer.parseInt(filterAttention);
}
private void updateFaceRecognitionSta(Long mallId, Date countDate, List<DPersonRecord> personRecords) {
Map<String, DPersonRecord> personRecordMap = personRecords.stream().collect(Collectors.toMap(DPersonRecord::getPersonUnid, dPersonRecord -> dPersonRecord, (k1, k2) -> k1));
//顾客总人数
long customerCount = personRecordMap.keySet().size();
//男性顾客人数
List<DPersonRecord> malePersonList = personRecordMap.values().stream().filter(personRecord -> personRecord.getGender() == 1).collect(Collectors.toList());
long maleCount = malePersonList.size();
//女性顾客人数
List<DPersonRecord> femalePersonList = personRecordMap.values().stream().filter(personRecord -> personRecord.getGender() == 0).collect(Collectors.toList());
long femaleCount = femalePersonList.size();
//男性年龄
Map<Integer, Long> maleStageMap = malePersonList.stream().collect(Collectors.groupingBy(DPersonRecord::getAge, Collectors.counting()));
//女性年龄
Map<Integer, Long> femaleStageMap = femalePersonList.stream().collect(Collectors.groupingBy(DPersonRecord::getAge, Collectors.counting()));
String sql = "select mall_id,countdate,counttime,person_count,staff_count,female_stage,male_stage from d_mall_day_face_recognition_sta where mall_id = ? and countdate = ?;";
List<DMallDayFaceRecognitionSta> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(DMallDayFaceRecognitionSta.class), mallId, countDate);
if (CollectionUtils.isNotEmpty(list)) {
DMallDayFaceRecognitionSta dMallDayFaceRecognitionSta = list.get(0);
long newPersonCount = dMallDayFaceRecognitionSta.getStaffCount() + customerCount;
String femaleStage = dMallDayFaceRecognitionSta.getFemaleStage();
String maleStage = dMallDayFaceRecognitionSta.getMaleStage();
DMallDayFaceRecognitionSta updateSta = new DMallDayFaceRecognitionSta();
updateSta.setCountdate(countDate);
updateSta.setPersonCount(newPersonCount);
updateSta.setCustomCount(customerCount);
updateSta.setMaleCount(maleCount);
updateSta.setFemaleCount(femaleCount);
String[] maleStageArry = maleStage.split(",");
Long[] maleStages = strArry2LongArry(maleStageArry);
maleStageMap.forEach((k,v) -> {
maleStages[k] = v;
});
String[] femaleStageArry = femaleStage.split(",");
Long[] femaleStages = strArry2LongArry(femaleStageArry);
femaleStageMap.forEach((k,v) -> {
femaleStages[k] = v;
});
String maleStageStr = arraysToString(maleStages);
String femaleStageStr = arraysToString(femaleStages);
updateSta.setMaleStage(maleStageStr);
updateSta.setFemaleStage(femaleStageStr);
CustomerGroupResult customerGroupResult = new CustomerGroupResult();
Map<String, List<DPersonRecord>> groupMap = personRecords.stream().collect(Collectors.groupingBy(DPersonRecord::getGroupUnid));
groupMap.forEach((k,v) -> {
calGroup(1, customerGroupResult, v);
});
updateSta.setGroupNum(customerGroupResult.getGroupNum());
updateSta.setSingleGroupNum(customerGroupResult.getSingleGroup());
updateSta.setDoubleGroupNum(customerGroupResult.getDoubleGroup());
updateSta.setMultipleGroupNum(customerGroupResult.getMultipleGroup());
updateSta.setFamilyGroupNum(customerGroupResult.getDoubleFamilyGroup() + customerGroupResult.getMultipleFamilyGroup());
updateSta.setLoverGroupNum(customerGroupResult.getDoubleLoverGroup());
updateSta.setPartnerGroupNum(customerGroupResult.getDoublePartnerGroup() + customerGroupResult.getMultiplePartnerGroup());
String updateSql = "update d_mall_day_face_recognition_sta set person_count = ?,custom_count = ?,male_count = ?,female_count = ?,male_stage = ?, female_stage = ?, group_num = ?, single_group_num = ?, double_group_num = ?, multiple_group_num = ?, family_group_num = ?, lover_group_num = ?, partner_group_num = ? where mall_id = ? and countdate = ?;";
jdbcTemplate.update(updateSql, updateSta.getPersonCount(), updateSta.getCustomCount(), updateSta.getMaleCount(), updateSta.getFemaleCount(), updateSta.getMaleStage(), updateSta.getFemaleStage(), updateSta.getGroupNum(), updateSta.getSingleGroupNum(), updateSta.getDoubleGroupNum(), updateSta.getMultipleGroupNum(), updateSta.getFamilyGroupNum(), updateSta.getLoverGroupNum(), updateSta.getPartnerGroupNum(), mallId, countDate);
}
}
public String arraysToString(Long[] arrays) {
return Arrays.toString(arrays).substring(1, Arrays.toString(arrays).length() - 1);
}
public Long[] strArry2LongArry(String[] arrays) {
Long[] intArrays = new Long[arrays.length];
for (int i = 0; i < arrays.length; i++) {
intArrays[i] = Long.parseLong(arrays[i].trim());
}
return intArrays;
}
public void calGroup(int add, CustomerGroupResult result, List<DPersonRecord> records) {
if (CollectionUtils.isEmpty(records)) {
return;
}
if (records.size() == 1) {
result.setSingleGroup(result.getSingleGroup() + add);
} else if (records.size() == 2) {
result.setDoubleGroup(result.getDoubleGroup() + add);
if (records.stream().anyMatch(df -> df.getAge() <= 18 || df.getAge() >= 50)) {
result.setDoubleFamilyGroup(result.getDoubleFamilyGroup() + add);
} else if (records.stream().map(DPersonRecord::getGender).collect(Collectors.toSet()).size() == 2) {
result.setDoubleLoverGroup(result.getDoubleLoverGroup() + add);
} else {
result.setDoublePartnerGroup(result.getDoublePartnerGroup() + add);
}
} else {
result.setMultipleGroup(result.getMultipleGroup() + add);
if (records.stream().anyMatch(df -> df.getAge() <= 18 || df.getAge() >= 50)) {
result.setMultipleFamilyGroup(result.getMultipleFamilyGroup() + add);
} else {
result.setMultiplePartnerGroup(result.getMultiplePartnerGroup() + add);
}
}
}
} }
\ No newline at end of file \ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!