123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491 |
- package com.ebei.screen.common.util;
- import cn.hutool.core.collection.CollUtil;
- import cn.hutool.core.date.DatePattern;
- import cn.hutool.core.date.LocalDateTimeUtil;
- import cn.hutool.core.map.MapUtil;
- import cn.hutool.crypto.SecureUtil;
- import cn.hutool.http.HttpRequest;
- import cn.hutool.setting.dialect.Props;
- import cn.hutool.setting.dialect.PropsUtil;
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.JSONArray;
- import com.alibaba.fastjson.JSONObject;
- import com.ebei.screen.common.constants.CommonConstants;
- import com.ebei.screen.common.constants.ParkExceptionType;
- import com.ebei.screen.common.constants.ParkType;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.lang3.StringUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.mongodb.core.MongoTemplate;
- import org.springframework.data.mongodb.core.query.Criteria;
- import org.springframework.data.mongodb.core.query.Query;
- import org.springframework.data.mongodb.core.query.Update;
- import org.springframework.stereotype.Component;
- import java.time.Duration;
- import java.time.LocalDateTime;
- import java.util.*;
- import java.util.concurrent.TimeUnit;
- import java.util.stream.Collectors;
- /**
- * 车场大屏工具类
- *
- * @author Levi.u
- * @date 2021/1/13 21:03
- */
- @Slf4j
- @Component
- public class ParkUtils {
- private static MongoTemplate mongoTemplate;
- private static final String pno = "JYTDSY";
- private static final String secret = "d52ee6b8a5ed4060a1d1654a3d31e247";
- private static final String BASE_URL = "http://jhtdc.jslife.com.cn/api";
- private static final String LOGIN_URL = BASE_URL + "/login";
- private static final String IMAGE_URL = BASE_URL + "/pic/picSearch";
- public static String token;
- @Autowired
- public void setMongoTemplate(MongoTemplate mongoTemplate) {
- ParkUtils.mongoTemplate = mongoTemplate;
- }
- public static List<Map> getEmptyTemplate() {
- List<Map> dayList = new ArrayList<>();
- for (int c = 0; c <= 23; c++) {
- dayList.add(Levi.by("hour", c).set("data", new ArrayList<>()).set("count", 0));
- }
- return dayList;
- }
- public static JSONObject getEmptyHourTemplate() {
- List<String> hours = Arrays.asList("1", "3", "6", "9", "12");
- JSONObject result = new JSONObject();
- hours.forEach(x -> result.put(x, new ArrayList<>()));
- return result;
- }
- /**
- * 用于存储数据 精确到天
- *
- * @param obj 插入的对象
- * @param pkId 区分键
- * @param collectionName 集合名字
- * @param flag true 覆盖原有数据只保留一条最新的 false追加原有数据
- * @param orderKey 排序的时间key
- * @param other 要插入的其他字段
- * @return
- */
- public static List<Map> setDataField(Object obj, String pkId, String collectionName, boolean flag, String orderKey, Levi<String, String> other) {
- LocalDateTime now = LocalDateTime.now();
- int hour = now.getHour();
- String format = LocalDateTimeUtil.format(now, DatePattern.PURE_DATE_PATTERN);
- Map dayMap = mongoTemplate.findById(pkId + "_" + format, Map.class, collectionName);
- if (MapUtil.isEmpty(dayMap)) {
- dayMap = Levi.by("_id", pkId + "_" + format).set("data", getEmptyTemplate());
- }
- List<Map> hourList = (List<Map>) dayMap.get("data");
- Map hourMap = hourList.get(hour);
- List<Map> dataList = (List<Map>) hourMap.get("data");
- List<Map> result = LeviUtils.deepCopy((List<Map>) obj);
- int size = result.size();
- if (CollUtil.isNotEmpty(dataList) && !flag) {
- result.addAll(dataList);
- }
- hourMap.put("count", result.size());
- hourMap.put("data", StringUtils.isNotBlank(orderKey) ? sortDateList(result, orderKey, true) : result);
- // 按小时存入数据用于统计
- Query query = new Query();
- query.addCriteria(Criteria.where("_id").is(pkId + "_" + format));
- Update update = new Update();
- update.set("data", hourList);
- // 统计数字
- if (dayMap.get("count") != null) {
- int count = Integer.parseInt(dayMap.get("count").toString());
- update.set("count", count + size);
- } else {
- update.set("count", size);
- }
- if (other != null) {
- other.keySet().forEach(x -> update.set(x, other.get(x)));
- }
- mongoTemplate.upsert(query, update, collectionName);
- return hourList;
- }
- /**
- * 获取封装后的结果集
- *
- * @param params
- * @param image 如果要查询图片 则传入 空不查
- * @return
- */
- public static Map<String, List<Map>> getInsertMap(Map params, String image) {
- List<Map> dataItems = JSON.parseObject((String) params.get("dataItems"), List.class);
- if (CollUtil.isEmpty(dataItems)) {
- return null;
- }
- Map<String, List<Map>> result = new HashMap<>(16);
- dataItems.forEach(x -> {
- String parkCode = x.get("parkCode").toString();
- List<Map> maps = new ArrayList<>();
- if (result.containsKey(parkCode)) {
- maps = result.get(parkCode);
- }
- maps.add(x);
- maps.forEach(y -> {
- y.put("sn", params.get("sn").toString());
- y.put("homra", LocalDateTimeUtil.format(LocalDateTime.now(), "HH"));
- });
- result.put(parkCode, maps);
- });
- return result;
- }
- public static Map<String, List<Map>> getInsertMap(Map params) {
- return getInsertMap(params, null);
- }
- /**
- * 初始化入场或出场数据
- *
- * @param params 参数
- * @param type 类型 入场或出场
- */
- public static void parkInOrOut(Map params, ParkType type) {
- Map<String, List<Map>> insertMap = ParkUtils.getInsertMap(params, type.getImage());
- String pno = params.get("pno").toString();
- if (MapUtil.isNotEmpty(insertMap)) {
- insertMap.keySet().forEach(key -> {
- // 按小时存入数据用于统计
- ParkUtils.setDataField(insertMap.get(key), key, type.getCode(), false, type.getSort(), Levi.by("pno", pno).set("ts", params.get("ts")));
- // 按车场存入数据 实时统计当前车场内所有车辆信息
- Query query = new Query();
- query.addCriteria(Criteria.where("_id").is(key));
- JSONObject obj = mongoTemplate.findById(key, JSONObject.class, "parkCarList");
- JSONArray data = obj != null ? obj.getJSONArray("data") : new JSONArray();
- List<Map> maps = data.toJavaList(Map.class);
- if (type.getNo().equals(1)) {
- // 入场
- maps.addAll(insertMap.get(key));
- } else if (type.getNo().equals(2)) {
- // 出场
- List<Map> listMaps = insertMap.get(key);
- if (CollUtil.isNotEmpty(listMaps)) {
- List<String> itemIds = listMaps.stream().map(x -> x.get("itemId").toString()).collect(Collectors.toList());
- maps = maps.stream().filter(x -> !itemIds.contains(x.get("itemId").toString())).collect(Collectors.toList());
- }
- }
- Update update = new Update();
- update.set("data", sortDateList(maps, "inTime", true));
- update.set("pno", pno);
- update.set("ts", params.get("ts"));
- update.set("count", maps.size());
- mongoTemplate.upsert(query, update, "parkCarList");
- // 校验是否存在异常数据
- insertException(key, insertMap.get(key), type.getNo().toString());
- });
- }
- }
- /**
- * 获取今日停车时长统计对象
- *
- * @param subList 分类完成后的集合
- * @param obj 当前mongo中查询出的对象
- * @return
- */
- public static JSONObject sortHourList(List<Map> subList, JSONObject obj) {
- JSONObject result = new JSONObject();
- JSONObject data = obj != null ? obj.getJSONObject("data") : getEmptyHourTemplate();
- subList.forEach(x -> {
- String key = calcHour(x);
- JSONArray array = data.getJSONArray(key);
- array.add(x);
- data.put(key, array);
- });
- result.put("data", data);
- data.keySet().forEach(x -> result.put("count" + x, data.getJSONArray(x).size()));
- return result;
- }
- /**
- * 获取停车时长归属时间段
- *
- * @param map
- * @return
- */
- public static String calcHour(Map map) {
- long second = Long.parseLong(map.get("serviceFeeTime") != null ? map.get("serviceFeeTime").toString() : "0");
- Long hour = TimeUnit.SECONDS.toHours(second);
- List<String> hours = Arrays.asList("1", "3", "6", "9", "12");
- return hours.get((hour.intValue() / 3) > hours.size() ? hours.size() - 1 : (hour.intValue() / 3));
- }
- /**
- * 根据时间对集合进行排序 yyyy-MM-dd HH:mm:ss
- *
- * @param jsonArray jsonArray集合
- * @param sortKey 排序的key
- * @param flag true正序 false倒序
- * @return
- */
- public static List<Map> sortDateList(JSONArray jsonArray, String sortKey, boolean flag) {
- List<Map> maps = jsonArray.toJavaList(Map.class);
- return sortDateList(maps, sortKey, flag);
- }
- /**
- * 根据时间对集合进行排序 yyyy-MM-dd HH:mm:ss
- *
- * @param maps list集合
- * @param sortKey 排序的key
- * @param flag true正序 false倒序
- * @return
- */
- public static List<Map> sortDateList(List<Map> maps, String sortKey, boolean flag) {
- if (CollUtil.isEmpty(maps)) {
- return new ArrayList<>();
- }
- int i = flag ? 1 : -1;
- if (sortKey.equals(ParkType.EXCEPTION.getSort())) {
- Collections.sort(maps, (m1, m2) -> ((m1.get(sortKey) == null ? 0 : Integer.parseInt(m1.get(sortKey).toString())) > (m2.get(sortKey) == null ? 0 : Integer.parseInt(m2.get(sortKey).toString()))) ? 1 * i : -1 * i);
- return maps;
- }
- if (StringUtils.isNotBlank(sortKey)) {
- Collections.sort(maps, (m1, m2) -> (m1.get(sortKey) == null ? LocalDateTime.now() : LocalDateTimeUtil.parse(m1.get(sortKey).toString(), DatePattern.NORM_DATETIME_PATTERN)).isAfter(m2.get(sortKey) == null ? LocalDateTime.now() : LocalDateTimeUtil.parse(m2.get(sortKey).toString(), DatePattern.NORM_DATETIME_PATTERN)) ? 1 * i : -1 * i);
- }
- return maps;
- }
- /**
- * 获取当前所有的停车场编号
- *
- * @return
- */
- public static List<String> getParkCodeList() {
- Levi<String, String> results = initParkCodeList();
- return results.keySet().stream().collect(Collectors.toList());
- }
- /**
- * 初始化内置的停车场信息
- *
- * @return
- */
- public static Levi<String, String> initParkCodeList() {
- Props prop = PropsUtil.get("parkName");
- Levi<String, String> result = Levi.create();
- prop.keySet().stream().forEach(x -> result.set(x.toString(), prop.get(x).toString()));
- JSONObject obj = mongoTemplate.findById("parkInfo", JSONObject.class, "parkInfo");
- if (obj != null && obj.getJSONArray("data") != null) {
- List<Map> maps = obj.getJSONArray("data").toJavaList(Map.class);
- maps.forEach(x -> result.set(x.get("parkCode").toString(), x.get("parkName").toString()));
- }
- Query query = new Query();
- query.addCriteria(Criteria.where("_id").is("parkCodeList"));
- Update update = new Update();
- update.set("data", result);
- mongoTemplate.upsert(query, update, "parkCodeList");
- return result;
- }
- /**
- * 给车场项目排序
- *
- * @param list
- * @return
- */
- public static List<Map> sortList(List<Map> list) {
- JSONObject obj = mongoTemplate.findById(CommonConstants.PARK_ORDER, JSONObject.class, CommonConstants.PARK_ORDER);
- List<String> crmIds = obj != null ? obj.getJSONArray("data").toJavaList(String.class) : new JSONArray().toJavaList(String.class);
- Collections.sort(list, Comparator.comparingInt(o -> crmIds.indexOf(o.get("projectId").toString())));
- return list.stream().filter(x -> x.get("projectName") != null).collect(Collectors.toList());
- }
- /**
- * 获取登录token
- *
- * @return
- */
- public static String getLoginToken() {
- String str = HttpRequest.post(LOGIN_URL)
- .header("content-type", "application/json")
- .body(JSON.toJSONString(Levi.by("pno", pno).set("secret", secret)))
- .execute().body();
- String token = JSON.parseObject(str).getString("tn");
- if (StringUtils.isNotBlank(token)) {
- ParkUtils.token = token;
- return token;
- }
- return null;
- }
- /**
- * 传入业务参数获取封装后的参数
- *
- * @param param
- * @return
- */
- public static String getCommonParams(Levi param) {
- String ts = LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_MS_PATTERN);
- String dataItems = JSON.toJSONString(Arrays.asList(param));
- // sn=md5(secret+ts+dataItems)
- String sn = SecureUtil.md5(secret + ts + dataItems).toUpperCase();
- return JSON.toJSONString(Levi.by("pno", pno).set("tn", token).set("ts", ts).set("ve", "1.0").set("sn", sn).set("dataItems", dataItems));
- }
- /**
- * 根据图片路径获取图片外链
- *
- * @param photo
- * @return
- */
- public static String getImgUrlById(String photo) {
- String str = HttpRequest.post(IMAGE_URL)
- .header("content-type", "application/json")
- .body(getCommonParams(Levi.by("filePath", photo)))
- .execute().body();
- JSONArray dataItems = JSON.parseObject(str).getJSONArray("dataItems");
- System.out.println("getImgUrlById:" + dataItems);
- if (dataItems != null) {
- String image = dataItems.toJavaList(Map.class).get(0).get("image").toString();
- return image;
- }
- return null;
- }
- /**
- * 判断数据是否存在异常 并插入异常信息
- *
- * @param params
- */
- public static void insertException(String parkCode, List<Map> params, String type) {
- String format = LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.PURE_DATE_PATTERN);
- Query query = new Query();
- query.addCriteria(Criteria.where("_id").is(parkCode + "_" + format));
- Update update = new Update();
- JSONObject obj = mongoTemplate.findById(parkCode + "_" + format, JSONObject.class, ParkType.EXCEPTION.getCode());
- JSONObject data = obj != null ? obj.getJSONObject("data") : new JSONObject();
- if (CommonConstants.SERVICE_IN.equals(type)) {
- // 车牌无法识别
- List<Map> list = params.stream().filter(x -> x.get("carNumber").toString().startsWith("无")).collect(Collectors.toList());
- List<Map> maps = data.getJSONArray(ParkExceptionType.A.getCode()) == null ? new ArrayList<>() : data.getJSONArray(ParkExceptionType.A.getCode()).toJavaList(Map.class);
- maps.addAll(list);
- System.out.println("异常处理之前:" + JSON.toJSONString(maps));
- List<Map> feesTime = ParkUtils.sortDateList(maps, ParkType.IN.getSort(), true);
- if (CollUtil.isNotEmpty(feesTime)) {
- feesTime.forEach(x -> {
- x.put("imageUrl", x.get(ParkType.IN.getImage()));
- x.put("operator", x.get("inOperator"));
- });
- }
- System.out.println("异常处理之后:" + JSON.toJSONString(feesTime));
- data.put(ParkExceptionType.A.getCode(), feesTime);
- update.set("data", data);
- update.set(ParkExceptionType.A.getCode() + "Count", feesTime.size());
- mongoTemplate.upsert(query, update, ParkType.EXCEPTION.getCode());
- } else if (CommonConstants.SERVICE_OUT.equals(type)) {
- // 车牌无法识别
- List<Map> list = params.stream().filter(x -> x.get("carNumber").toString().startsWith("无")).collect(Collectors.toList());
- List<Map> maps = data.getJSONArray(ParkExceptionType.A.getCode()) == null ? new ArrayList<>() : data.getJSONArray(ParkExceptionType.A.getCode()).toJavaList(Map.class);
- maps.addAll(list);
- List<Map> feesTime = ParkUtils.sortDateList(maps, ParkType.OUT.getSort(), true);
- if (CollUtil.isNotEmpty(feesTime)) {
- feesTime.forEach(x -> {
- x.put("imageUrl", x.get(ParkType.OUT.getImage()));
- x.put("operator", x.get("outOperator"));
- x.put("equipName", x.get("outEquipName"));
- });
- }
- data.put(ParkExceptionType.A.getCode(), feesTime);
- // 支付时间过长
- String now = LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.NORM_DATETIME_PATTERN);
- List<Map> list2 = params.stream().filter(x -> getDimSS(x.get("outTime") == null ? now : x.get("outTime").toString(), x.get("openDoor") == null ? now : x.get("openDoor").toString()) > 60
- ).collect(Collectors.toList());
- List<Map> maps2 = data.getJSONArray(ParkExceptionType.B.getCode()) == null ? new ArrayList<>() : data.getJSONArray(ParkExceptionType.B.getCode()).toJavaList(Map.class);
- maps2.addAll(list2);
- List<Map> feesTime2 = ParkUtils.sortDateList(maps2, ParkType.OUT.getSort(), true);
- if (CollUtil.isNotEmpty(feesTime2)) {
- feesTime2.forEach(x -> {
- x.put("imageUrl", x.get(ParkType.OUT.getImage()));
- x.put("operator", x.get("outOperator"));
- x.put("equipName", x.get("outEquipName"));
- });
- }
- data.put(ParkExceptionType.B.getCode(), feesTime2);
- // 判断是否撞杆
- List<Map> list3 = params.stream().filter(x -> x.get("remark") != null && x.get("remark").toString().contains("撞杆")).collect(Collectors.toList());
- List<Map> maps3 = data.getJSONArray(ParkExceptionType.D.getCode()) == null ? new ArrayList<>() : data.getJSONArray(ParkExceptionType.D.getCode()).toJavaList(Map.class);
- maps3.addAll(list3);
- List<Map> feesTime3 = ParkUtils.sortDateList(maps3, ParkType.OUT.getSort(), true);
- if (CollUtil.isNotEmpty(feesTime3)) {
- feesTime3.forEach(x -> {
- x.put("imageUrl", x.get(ParkType.OUT.getImage()));
- x.put("operator", x.get("outOperator"));
- x.put("equipName", x.get("outEquipName"));
- });
- }
- data.put(ParkExceptionType.D.getCode(), feesTime3);
- update.set("data", data);
- update.set(ParkExceptionType.B.getCode() + "Count", feesTime2.size());
- update.set(ParkExceptionType.D.getCode() + "Count", feesTime3.size());
- mongoTemplate.upsert(query, update, ParkType.EXCEPTION.getCode());
- } else if (CommonConstants.SERVICE_INFO.equals(type)) {
- // 月卡过期
- List<Map> list = params.stream().filter(x ->
- Duration.between(LocalDateTime.now(), x.get("endTime") == null ? LocalDateTime.now() : LocalDateTimeUtil.parse(x.get("endTime").toString(), DatePattern.NORM_DATETIME_PATTERN)).getSeconds() < 0
- ).collect(Collectors.toList());
- List<Map> maps = data.getJSONArray(ParkExceptionType.C.getCode()) == null ? new ArrayList<>() : data.getJSONArray(ParkExceptionType.C.getCode()).toJavaList(Map.class);
- maps.addAll(list);
- List<Map> feesTime = ParkUtils.sortDateList(maps, "operateTime", true);
- data.put(ParkExceptionType.C.getCode(), feesTime);
- if (CollUtil.isNotEmpty(feesTime)) {
- feesTime.forEach(x -> {
- x.put("operator", x.get("operateName"));
- x.put("equipName", x.get("cardTypeName"));
- });
- }
- update.set("data", data);
- update.set(ParkExceptionType.C.getCode() + "Count", feesTime.size());
- mongoTemplate.upsert(query, update, ParkType.EXCEPTION.getCode());
- }
- }
- /**
- * 计算两个时间相差秒数
- *
- * @param s1 yyyy-MM-dd HH:mm:ss
- * @param s2 yyyy-MM-dd HH:mm:ss
- * @return
- */
- public static Integer getDimSS(String s1, String s2) {
- LocalDateTime s1Time = LocalDateTimeUtil.parse(s1, DatePattern.NORM_DATETIME_PATTERN);
- LocalDateTime s2Time = LocalDateTimeUtil.parse(s2, DatePattern.NORM_DATETIME_PATTERN);
- Duration dur = Duration.between(s1Time, s2Time);
- Long abs = Math.abs(dur.getSeconds());
- return abs.intValue();
- }
- /**
- * 获取某个时间点的异常信息
- *
- * @param dataList
- * @param timeIndex
- * @return
- */
- public static List<Map> getExceptionDataListByHour(List<Map> dataList, Integer timeIndex) {
- if (CollUtil.isEmpty(dataList)) {
- return new ArrayList<>();
- }
- String format = String.format("%02d", timeIndex);
- return dataList.stream().filter(x -> (x.get("homra") == null ? "" : x.get("homra").toString()).equals(format)).collect(Collectors.toList());
- }
- }
|