package org.dromara.util; import cn.hutool.core.date.DateField; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; import cn.hutool.core.thread.ThreadUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpRequest; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSON; import org.apache.xmlbeans.impl.xb.xsdschema.Public; import org.dromara.common.core.domain.R; import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.redis.utils.CacheUtils; import org.dromara.common.redis.utils.RedisUtils; import org.dromara.system.domain.GpsData; import org.dromara.system.domain.TblCarInfo; import org.dromara.system.domain.bo.*; import org.dromara.system.domain.vo.*; import org.dromara.system.service.ISysDictDataService; import org.dromara.system.service.ISysUserService; import org.dromara.system.service.ITblBagService; import org.dromara.system.service.ITblExpressStaticsService; import org.dromara.system.service.impl.TblCarInfoServiceImpl; import org.dromara.system.service.impl.TblCarScheduleServiceImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import tech.powerjob.worker.core.processor.ProcessResult; import tech.powerjob.worker.core.processor.TaskContext; import tech.powerjob.worker.core.processor.sdk.BasicProcessor; import javax.crypto.Cipher; import java.io.UnsupportedEncodingException; import java.security.Key; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.time.format.DateTimeFormatter; import java.util.*; @Component public class CabinetUtil implements BasicProcessor { private final static String appid = "bw_open_express_A8C848769E5C04E0"; private final static String appkey = "5AFC6E07CFCF4A359B775D1416A9799A"; private final static String hosts = "https://open.bestwond.com"; public final static String CABINET_INFO = "cabinet_info"; public final static String CABINET_BOXS = "cabinet_boxs"; private static final Logger log = LoggerFactory.getLogger(CabinetUtil.class); private static String byteArr2HexStr(byte[] arrB) throws Exception { int iLen = arrB.length; // 每个byte用两个字符才能表示,所以字符串的长度是数组长度的两倍 StringBuffer sb = new StringBuffer(iLen * 2); for (int i = 0; i < iLen; i++) { int intTmp = arrB[i]; // 把负数转换为正数 while (intTmp < 0) { intTmp = intTmp + 256; } // 小于0F的数需要在前面补0 if (intTmp < 16) { sb.append("0"); } sb.append(Integer.toString(intTmp, 16)); } return sb.toString(); } private static String encrypt(String strIn) throws Exception { return byteArr2HexStr(encrypt(strIn.getBytes("UTF-8"))); } private static byte[] encrypt(byte[] arrB) throws Exception { Key key = getKey(appkey.getBytes("UTF-8")); Cipher encryptCipher = Cipher.getInstance("DES"); encryptCipher.init(Cipher.ENCRYPT_MODE, key); return encryptCipher.doFinal(arrB); } private static Key getKey(byte[] arrBTmp) throws Exception { // 创建一个空的8位字节数组(默认值为0) byte[] arrB = new byte[8]; // 将原始字节数组转换为8位 for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) { arrB[i] = arrBTmp[i]; } // 生成密钥 Key key = new javax.crypto.spec.SecretKeySpec(arrB, "DES"); return key; } // private static String getQJM(String phone) throws Exception { // String text = SpringUtils.getBean(ISysConfigService.class).selectConfigByKey("sys.cabinet.account"); // // } @Scheduled(cron = "0 10 0 ? * ? ") // @Scheduled(cron = "0/10 * * * * * ") private void getExpressStatic() { SysUserBo sysUserBo = new SysUserBo(); sysUserBo.setRoleId(1763484881548447746L); List userlist = SpringUtils.getBean(ISysUserService.class).getUserList(sysUserBo); log.info(String.valueOf(userlist.size())); for(SysUserVo vo:userlist){ if(vo!=null && vo.getPhonenumber()!=null && !vo.getPhonenumber().isEmpty() && vo.getPhonenumber() != null){ log.info("----------------------快递员{}开始同步----------------------",vo.getNickName()); try{ String month = getLastMonth(); TblExpressStaticsBo bo = new TblExpressStaticsBo(); bo.setMonth(month); bo.setUserId(vo.getUserId()); bo.setData(CabinetUtil.getExpressDeliveryStatistics(vo.getPhonenumber(),month)); Thread.sleep(10000); TblExpressStaticsBo query = new TblExpressStaticsBo(); query.setMonth(month); query.setUserId(vo.getUserId()); List list = SpringUtils.getBean(ITblExpressStaticsService.class).queryList(query); if(list.size() > 0){ bo.setId(list.get(0).getId()); SpringUtils.getBean(ITblExpressStaticsService.class).updateByBo(bo); }else{ SpringUtils.getBean(ITblExpressStaticsService.class).insertByBo(bo); } log.info("----------------------快递员{}结束同步----------------------",vo.getNickName()); }catch (Exception e){ } } } } @Scheduled(fixedRate = 5*60*1000) private void genScheduleList(){ TblCarScheduleBo bo =new TblCarScheduleBo(); bo.getParams().put("scheduleDate",DateUtil.format(DateUtil.date(),"yyyy-MM-dd")); List scheduleVos = SpringUtils.getBean(TblCarScheduleServiceImpl.class).queryList(bo); TblCarScheduleBo bo2 =new TblCarScheduleBo(); bo2.getParams().put("scheduleDate",DateUtil.format(DateUtil.date().offset(DateField.DAY_OF_MONTH,1),"yyyy-MM-dd")); List scheduleVos2 = SpringUtils.getBean(TblCarScheduleServiceImpl.class).queryList(bo2); Map map=new HashMap<>(); scheduleVos2.forEach(scheduleVo2->{ map.put(scheduleVo2.getCarNum()+DateUtil.format(scheduleVo2.getScheduleDate(),DatePattern.NORM_DATETIME_PATTERN),scheduleVo2); }); for (TblCarScheduleVo scheduleVo : scheduleVos) { if(StrUtil.isNotEmpty(scheduleVo.getExt2())){ try{ if(JSONUtil.parseObj(scheduleVo.getExt2()).getBool("isauto") && map.get(scheduleVo.getCarNum()+DateUtil.format( DateUtil.date(scheduleVo.getScheduleDate()).offset(DateField.DAY_OF_MONTH,1),DatePattern.NORM_DATETIME_PATTERN))==null){ //copy TblCarScheduleBo bo1 =new TblCarScheduleBo(); bo1.setCarNum(scheduleVo.getCarNum()); bo1.setScheduleDate(DateUtil.offset(scheduleVo.getScheduleDate(),DateField.DAY_OF_MONTH,1)); bo1.setPathInfo(scheduleVo.getPathInfo()); bo1.setCreateTime(DateUtil.date()); bo1.setExt2(scheduleVo.getExt2()); bo1.setCreateDept(103100L); SpringUtils.getBean(TblCarScheduleServiceImpl.class).insertByBo(bo1); } }catch (Exception e){ } } } } @Scheduled(fixedRate = 5*60*1000) private void getGpsList(){ List carInfoVos = SpringUtils.getBean(TblCarInfoServiceImpl.class).queryList(new TblCarInfoBo()); for (TblCarInfoVo car : carInfoVos) { if(StrUtil.isNotEmpty(car.getDeviceInfos())){ JSONUtil.parseArray(car.getDeviceInfos()).forEach(item->{ JSONObject c = (JSONObject)item; try { if (c.getStr("type").equals("gps")) { GpsData gpsData = RedisUtils.getCacheObject(StringUtils.format("gps_{}", c.getStr("code"))); //1小时就离线 Map map = new HashMap<>(); if (gpsData.getTs() == null) { gpsData.setTs(DateUtil.date()); } if (DateUtil.current() - gpsData.getTs().getTime() > 1000 * 60 * 60) { map.put("code", c.getStr("code")); map.put("time", DatePattern.NORM_DATETIME_FORMAT.format(gpsData.getTs())); map.put("station", car.getCarNum()); CacheUtils.put("offline", c.getStr("code"), map); } else { CacheUtils.put("offline", c.getStr("code"), map); } } }catch (Exception e){} }); } } } @Scheduled(fixedRate = 5*60*1000) private void getList(){ //获取所有gps 判断是否离线 List> cabinetList = new ArrayList<>(); SysDictDataBo bo =new SysDictDataBo(); bo.setDictType("tbl_sites"); List list = SpringUtils.getBean(ISysDictDataService.class).selectDictDataList(bo); try { list.forEach(item->{ if(StrUtil.isNotEmpty(item.getRemark())){ JSONArray jsonArray = JSONUtil.parseArray(item.getRemark()); jsonArray.forEach(item2->{ if(((JSONObject)item2).getStr("type").equals("cabinet")){ cabinetList.add( List.of(item.getDictLabel(),((JSONObject)item2).getStr("code"))); } }); } }); }catch (Exception e){ } if(cabinetList!=null && cabinetList.size()>0){ cabinetList.forEach(item->{ try { Thread.sleep(1000); String details= CabinetUtil.getCabinetInfo(item.get(1)); CacheUtils.put(CABINET_INFO,item.get(1),details); // log.info(StrUtil.format("获取到柜子信息:{},{}",item.get(1),details)); Thread.sleep(1000); //获取柜子状态 String boxs= CabinetUtil.getCabinetBoxs(item.get(1)); CacheUtils.put(CABINET_BOXS,item.get(1),boxs); // log.info(StrUtil.format("获取到柜子箱子信息:{},{}",item.get(1),boxs)); try{ Integer obline = JSONUtil.parseObj(details).getJSONObject("data").getInt("device_line"); Map map=new HashMap<>(); if(obline==0){ map.put("code",item.get(1)); map.put("time",DateUtil.now()); map.put("station",item.get(0)); //离线告警 CacheUtils.put("offline",item.get(1),map); }else{ CacheUtils.put("offline",item.get(1),map); } }catch(Exception e){ log.error("快递柜信息解析错误"); } try{ Map map=new HashMap<>(); map.put("total",JSONUtil.parseObj(boxs).getJSONObject("data").getJSONObject("page").getInt("total_count")); JSONUtil.parseObj(boxs).getJSONObject("data").getJSONArray("list").forEach(item2->{ if(((JSONObject)item2).getInt("box_use_status")==1){ map.put("used",map.get("used")==null?1:map.get("used")+1); }else{ map.put("unuse",map.get("unuse")==null?1:map.get("unuse")+1); } }); if(map.get("used")==null) map.put("used",0); if(map.get("unuse")==null) map.put("unuse",0); CacheUtils.put(CABINET_INFO,item.get(1)+"_box",map); }catch(Exception e){ log.error("快递柜box解析错误"); } } catch (Exception e) { throw new RuntimeException(e); } }); } } // @Scheduled(fixedRate = 2*60*60*1000) public void getExpressHistory() throws UnsupportedEncodingException { Map cabinetMap2 = new HashMap<>(); //获取所有快递柜的快递信息 Map cabinetMap = new HashMap<>(); SysDictDataBo bo =new SysDictDataBo(); bo.setDictType("tbl_sites"); List list = SpringUtils.getBean(ISysDictDataService.class).selectDictDataList(bo); try { list.forEach(item->{ if(StrUtil.isNotEmpty(item.getRemark())){ JSONArray jsonArray = JSONUtil.parseArray(item.getRemark()); jsonArray.forEach(item2->{ if(((JSONObject)item2).getStr("type").equals("cabinet")){ ((JSONObject) item2).put("location",item.getDictValue()); cabinetMap.put( item.getDictLabel(),(JSONObject)item2); cabinetMap2.put(((JSONObject) item2).getStr("cabinetType"),(JSONObject)item2); } }); } }); }catch (Exception e){ } //获取历史 try { // TblBagBo bo1 =new TblBagBo(); // bo1.getParams().put("remark",""); // List bagList = SpringUtils.getBean(ITblBagService.class).queryList(bo1); // List jsonObjectList1 = new ArrayList<>(); // List sysd = new ArrayList<>(); // if(bagList!=null && bagList.size()>0) { // bagList.forEach(item->{ // if(cabinetMap2.containsKey(item.getDeviceId().toString())){ // JSONObject json = new JSONObject(); // json.put("deviceId",item.getDeviceId()); // json.put("cpCode",item.getCpCode()); // json.put("waybillNo",item.getWaybillNo()); // json.put("scTime",item.getScTime()); // json.put("scType",item.getScType()); // jsonObjectList1.add(json); // sysd.add(item); // } // // }); // // SPlatUtils.pushExpressInfo(jsonObjectList1); // if(sysd!=null && sysd.size()>0) { // sysd.forEach(item -> { // item.setRemark("已同步"); // TblBagBo item1 = new TblBagBo(); // BeanUtils.copyProperties(item, item1); // SpringUtils.getBean(ITblBagService.class).updateByBo(item1); // }); // } // } Map map = new HashMap<>(); map.put("start_ctime ", DateUtil.format( DateUtil.offsetHour(DateUtil.date(),-2), "yyyy-MM-dd HH:mm:ss")); map.put("end_ctime ", DateUtil.format( DateUtil.date(), "yyyy-MM-dd HH:mm:ss")); map.put("page_size", "10000"); String data = CabinetUtil.getExpressHistory(map); List jsonObjectList = new ArrayList<>(); JSONArray jsonArray = JSONUtil.parseObj(data).getJSONObject("data").getJSONArray("list"); for (JSONObject jsonObject1 : jsonArray.toList(JSONObject.class)) { JSONObject json = new JSONObject(); json.put("deviceId",jsonObject1.getStr("device_number")); json.put("cpCode",jsonObject1.getStr("product_type")); json.put("waybillNo",jsonObject1.getStr("order_number")); if(jsonObject1.getInt("used_status")==3||jsonObject1.getInt("used_status")==4){ if(jsonObject1.getInt("used_status")==3){ json.put("scTime",jsonObject1.getStr("save_end_time")); json.put("scType",1); } if(jsonObject1.getInt("used_status")==4){ json.put("scType",2); json.put("scTime",jsonObject1.getStr("get_end_time")); } } jsonObjectList.add(json); } SPlatUtils.pushExpressInfo(jsonObjectList); }catch (Exception e){ } if(cabinetMap!=null && cabinetMap.size()>0) { try { List cabinetList = new ArrayList<>(); cabinetMap.keySet().forEach(i->{ JSONObject c = cabinetMap.get(i); if(c.getStr("location")!=null&&c.getStr("wdcode")!=null){ c.put("deviceId", c.getStr("code")); c.put("stationId", c.getStr("wdcode")); c.put("deviceType", "cabinet"); cabinetList.add(c); } } ); SPlatUtils.SysDevice(cabinetList); }catch (Exception e){ } } } @Scheduled(fixedRate = 5*60*1000) private void resetStationLed() throws UnsupportedEncodingException { //获取所有站点led SysDictDataBo bo =new SysDictDataBo(); bo.setDictType("tbl_sites"); List allstations = SpringUtils.getBean(ISysDictDataService.class).selectDictDataList(bo); for (SysDictDataVo station:allstations) { //获取led if(StringUtils.isNotEmpty(station.getRemark())) { List devicedatas = JSONUtil.parseArray(station.getRemark()).toList(JSONObject.class); for (JSONObject i :devicedatas) { if(i.getStr("type").equals("led")){ //查询缓存是否播放过 Object time = RedisUtils.getCacheMapValue("station_led",station.getDictLabel()); try { if (time != null && DateUtil.current() - Long.parseLong(time.toString()) < 1000 *60* 5) { continue; } }catch (Exception e){} MessageUtils.sendLed(i.getStr("code"),StringUtils.isNotEmpty( station.getCssClass())? station.getCssClass(): StringUtils.format("{}快梯柜",station.getDictLabel())); } } } } } @Scheduled(fixedRate = 60*60*1000) public R getData() { try{ String month = getLastMonth(); TblExpressStaticsBo bo = new TblExpressStaticsBo(); bo.setMonth(month); bo.setUserId(1L); bo.setData(getExpressDeliveryStatistics("19559316717",month)); TblExpressStaticsBo query = new TblExpressStaticsBo(); query.setMonth(month); query.setUserId(1L); List list = SpringUtils.getBean(ITblExpressStaticsService.class).queryList(query); if(list.size() > 0){ bo.setId(list.get(0).getId()); SpringUtils.getBean(ITblExpressStaticsService.class).updateByBo(bo); }else{ SpringUtils.getBean(ITblExpressStaticsService.class).insertByBo(bo); } return R.ok(bo); }catch (Exception e){ return R.fail(e.toString()); } } // 获取柜子信息 public static String getCabinetInfo(String cabinetCode) throws Exception { int times = (int) (DateUtil.date().getTime()/1000); String str_sign = appid + "=" + times + "=" + appid; str_sign = encrypt(str_sign); String result3= HttpRequest.post(hosts+"/kd/api/v2/action/device_info/").body(JSON.toJSONString(Map.of("device_number",cabinetCode))) .addHeaders(Map.of("timestamp",times+"","Content-Type","application/json","appid",appid,"sign",str_sign)) .execute().body(); return result3; } // 获取柜子统计 public static String getCabinetStatistics(String cabinetCode,String startTime,String endTime) throws Exception { int times = (int) (DateUtil.date().getTime()/1000); String str_sign = appid + "=" + times + "=" + appid; str_sign = encrypt(str_sign); String result3= HttpRequest.post(hosts + "/kd/api/v2/action/deliver_statistics/").body(JSON.toJSONString(Map.of("device_number",cabinetCode,"strat_time",startTime,"end_time",endTime))) .addHeaders(Map.of("timestamp",times+"","Content-Type","application/json","appid",appid,"sign",str_sign)) .execute().body(); return result3; } //或者快递柜子使用情况 // public static String getBoxUs(String courierMobile,String month) throws Exception { // int times = (int) (DateUtil.date().getTime()/1000); // String str_sign = appid + "=" + times + "=" + appid; // str_sign = encrypt(str_sign); // String result3= HttpRequest.post(hosts + "/api/v2/search/express_delivery_statistics/").body(JSON.toJSONString(Map.of("courier_mobile",courierMobile,"market_id","2638","search_month",month))) // .addHeaders(Map.of("timestamp",times+"","Content-Type","application/json","appid",appid,"sign",str_sign)) // .execute().body(); // return result3; // } //或者快递柜使用情况 public static String getExpressDeliveryStatistics(String courierMobile,String month) throws Exception { int times = (int) (DateUtil.date().getTime()/1000); String str_sign = appid + "=" + times + "=" + appid; str_sign = encrypt(str_sign); log.info(JSON.toJSONString(Map.of("timestamp",times+"","Content-Type","application/json","appid",appid,"sign",str_sign))); log.info(JSON.toJSONString(Map.of("courier_mobile",courierMobile,"market_id",3219,"search_month",month))); String result3= HttpRequest.post(hosts + "/kd/api/v2/search/express_delivery_statistics/").body(JSON.toJSONString(Map.of("courier_mobile",courierMobile,"market_id",3219,"search_month",month))) .addHeaders(Map.of("timestamp",times+"","Content-Type","application/json","appid",appid,"sign",str_sign)) .execute().body(); return result3; } public static String getLastMonth() { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM"); Date date = new Date(); Calendar calendar = Calendar.getInstance(); // 设置为当前时间 calendar.setTime(date); calendar.add(Calendar.DAY_OF_MONTH,-1); // 设置为上一个月 //calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1); date = calendar.getTime(); return format.format(date); } // public static void main(String args[]) throws Exception { // log.info(getExpressDeliveryStatistics("19559316717","2025-01")); // } // 获取柜子盒子 public static String getCabinetBoxs(String cabinetCode) throws Exception { int times = (int) (DateUtil.date().getTime()/1000); String str_sign = appid + "=" + times + "=" + appid; str_sign = encrypt(str_sign); String result3= HttpRequest.post(hosts + "/kd/api/v2/action/box_info_list/").body(JSON.toJSONString(Map.of("device_number",cabinetCode,"page_size",1000))) .addHeaders(Map.of("timestamp",times+"","Content-Type","application/json","appid",appid,"sign",str_sign)) .execute().body(); return result3; } // 开柜 public static String openCabinetBoxs(String cabinetCode,String lookAddr) throws Exception { int times = (int) (DateUtil.date().getTime()/1000); String str_sign = appid + "=" + times + "=" + appid; str_sign = encrypt(str_sign); String result3= HttpRequest.post(hosts + "/kd/api/v2/action/open_box/").body(JSON.toJSONString(Map.of("device_number",cabinetCode,"lock_address",lookAddr))) .addHeaders(Map.of("timestamp",times+"","Content-Type","application/json","appid",appid,"sign",str_sign)) .execute().body(); return result3; } // 开所有柜 public static String openCabinetBoxAll(String cabinetCode) throws Exception { int times = (int) (DateUtil.date().getTime()/1000); String str_sign = appid + "=" + times + "=" + appid; str_sign = encrypt(str_sign); String result3= HttpRequest.post(hosts + "/kd/api/v2/action/open_box_all/").body(JSON.toJSONString(Map.of("device_number",cabinetCode))) .addHeaders(Map.of("timestamp",times+"","Content-Type","application/json","appid",appid,"sign",str_sign)) .execute().body(); return result3; } //清理格子(不开启) public static String clearCabinetBox(String cabinetCode,String boxUUId) throws Exception { int times = (int) (DateUtil.date().getTime()/1000); String str_sign = appid + "=" + times + "=" + appid; str_sign = encrypt(str_sign); String result3= HttpRequest.post(hosts + "/kd/api/v2/action/clear_box/").body(JSON.toJSONString(Map.of("device_number",cabinetCode,"box_uid",boxUUId))) .addHeaders(Map.of("timestamp",times+"","Content-Type","application/json","appid",appid,"sign",str_sign)) .execute().body(); return result3; } //清理格子(开启) public static String clearCabinetBoxOpen(String cabinetCode,String boxUUId) throws Exception { int times = (int) (DateUtil.date().getTime()/1000); String str_sign = appid + "=" + times + "=" + appid; str_sign = encrypt(str_sign); String result3= HttpRequest.post(hosts + "/kd/api/v2/action/clear_box_open/").body(JSON.toJSONString(Map.of("device_number",cabinetCode,"box_uid",boxUUId))) .addHeaders(Map.of("timestamp",times+"","Content-Type","application/json","appid",appid,"sign",str_sign)) .execute().body(); return result3; } // 获取取件码 public static String getQJM(String phone) throws Exception { int times = (int) (DateUtil.date().getTime()/1000); String str_sign = appid + "=" + times + "=" + appid; str_sign = encrypt(str_sign); String result3= HttpRequest.post(hosts + "/kd/api/v2/query/pick_code_by_user_mobile/").body(JSON.toJSONString(Map.of("get_user_mobile",phone))) .addHeaders(Map.of("timestamp",times+"","Content-Type","application/json","appid",appid,"sign",str_sign)) .execute().body(); return result3; } //获取快递历史信息 public static String getExpressHistory(Map body) throws Exception{ int times = (int) (DateUtil.date().getTime()/1000); String str_sign = appid + "=" + times + "=" + appid; str_sign = encrypt(str_sign); String result3= HttpRequest.post(hosts + "/kd/api/v2/search/record_query/").body(JSON.toJSONString(body)) .addHeaders(Map.of("timestamp",times+"","Content-Type","application/json","appid",appid,"sign",str_sign)).execute().body(); return result3; } @Override public ProcessResult process(TaskContext taskContext) throws Exception { getExpressHistory(); return new ProcessResult(true, "定时任务执行成功"); } }