diff --git a/base-commons/common-core/pom.xml b/base-commons/common-core/pom.xml index 64761b6..afb78a4 100644 --- a/base-commons/common-core/pom.xml +++ b/base-commons/common-core/pom.xml @@ -67,8 +67,12 @@ cn.hutool hutool-crypto - - + + org.slf4j + slf4j-api + + + diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/Dto/DeviceDto.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/Dto/DeviceDto.java new file mode 100644 index 0000000..716a286 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/Dto/DeviceDto.java @@ -0,0 +1,44 @@ +package com.evotech.hd.common.core.Dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName:DeviceDto + * @date: 2025年04月21日 14:36 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ + +@Data +@Schema(name = "运营商信息-> 站端信息-> 设备信息") +public class DeviceDto { + + @Schema(description = "id") + private String id; + @Schema(description = "父级Id") + private String parentId; + @Schema(description = "名称") + private String name; + @Schema(description = "设备ID") + private String deviceId; + @Schema(description = "通道ID") + private String channelId; + @Schema(description = "子集信息") + List childList; + + public DeviceDto() { + } + + public DeviceDto(String id, String parentId, String name, String deviceId, String channelId, List childList) { + this.id = id; + this.parentId = parentId; + this.name = name; + this.deviceId = deviceId; + this.channelId = channelId; + this.childList = childList; + } +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/constant/HDConstant.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/constant/HDConstant.java index 7dfd1ef..6a7ad8e 100644 --- a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/constant/HDConstant.java +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/constant/HDConstant.java @@ -2,7 +2,31 @@ package com.evotech.hd.common.core.constant; public interface HDConstant { - public static final class PermissionConstant{ + /*** + * 大华设备相关CONSTANT + */ + final class DHConstant{ + //redis accessToken的key + public static final String DH_ACCESS_TOKEN_KEY = "accessToken"; + //redis accessToken的获取时间的key + public static final String DH_ACCESS_TOKEN_TIME_KEY = "accessTokenGetTime"; + //redis accessToken的过期时间的key + public static final String DH_ACCESS_TOKEN_EXPIRE_TIME_KEY = "accessTokenExpireTime"; + //redis accessToken的过期时间从新获取的临界值, 默认1小时, 秒级 + public static final long DH_REACQUIRE_ACCESS_TOKEN_CRITICAL_VALUE = 1*60*60; + + public static final String SUCCESS_CODE = "1000"; + + public static final String LIVE_EXISTS_CODE = "MP130007"; + + + } + + + /*** + * 权限相关CONSTANT + */ + final class PermissionConstant{ /** * 当前登录用户的UID */ diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStation.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStation.java index 78633d1..b9cb49e 100644 --- a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStation.java +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStation.java @@ -1,24 +1,16 @@ package com.evotech.hd.common.core.entity.cloud; -import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.evotech.hd.common.core.entity.BaseEntity; -import com.fasterxml.jackson.annotation.JsonFormat; - -import java.io.Serializable; -import java.util.Date; -import java.util.List; - -import lombok.EqualsAndHashCode; -import org.springframework.format.annotation.DateTimeFormat; - -import io.swagger.v3.oas.annotations.Hidden; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; import jakarta.validation.constraints.NotBlank; import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.List; /** * @author zrb @@ -133,4 +125,10 @@ public class BatteryStation extends BaseEntity implements Serializable { @Schema(description = "营业止时间") private String runEndTime; + + @Schema(description = "场地id--DH") + private String storeId; + + @Schema(description = "场地Code--DH") + private String orgCode; } diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/utils/Collections.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/utils/Collections.java new file mode 100644 index 0000000..e67ef4c --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/utils/Collections.java @@ -0,0 +1,310 @@ +package com.evotech.hd.common.core.utils; + + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Serializable; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @DES 集合类型工具类 + * @author andy.shi + * @createDate 2020年12月25日下午2:16:13 + * @typeName Collections + */ +public class Collections implements Serializable{ + + static Logger log = LoggerFactory.getLogger(Collections.class); + + /** + * + */ + private static final long serialVersionUID = -611031509912595162L; + + /** + * + * @param ts + * @return + */ + public static boolean isEmpty(T[] ts) { + return ts == null || ts.length == 0; + } + + /** + * + * @param ts + * @return + */ + public static boolean isNotEmpty(T[] ts) { + return ! isEmpty(ts); + } + +/************************ 以上为公共方法 以下为list ************************************************/ + /** + * @DES 检查集合为空 + * @author andy.shi + * @company 龙腾工作室 + * @createDate 2020年12月25日下午2:14:43 + * @methodName Collections.isEmpty + * @param list + * @return + * @returnType boolean + */ + public static boolean isEmpty(Collection list) { + return list == null || list.size() == 0; + } + + /** + * @DES 检查集合不为空 + * @author andy.shi + * @company 龙腾工作室 + * @createDate 2020年12月25日下午2:15:07 + * @methodName Collections.isNotEmpty + * @param collection + * @return + * @returnType boolean + */ + public static boolean isNotEmpty(Collection collection) { + return ! (isEmpty(collection)); + } + + /** + * 将list进行分页 + * @author Andy.shi + * @company 龙腾工作室 + * @date 2020年9月15日上午9:37:07 + * @param 泛型, 根据传入的对对象类型,返回类型 + * @param list 需要分组的集合 + * @param pageNum 当前页数 + * @param pageSize 每页显示的条数 + * @return + */ + public static List pageList(List list, Integer pageNum, Integer pageSize){ + if(isEmpty(list)) { + log.warn(String.format("[info " + Collections.class.getName() + " 执行信息] : list info: [%s] 为空", new Object[]{list})); + return list; + } + try { + //如果当前页为0, 更改为1 + if(pageNum == 0) + pageNum = 1; + //计算formIndex + Integer fromIndex = ((pageNum-1)*pageSize); + //计算toIndex + Integer toIndex = fromIndex + pageSize; + //防止下标越界 + if(toIndex > list.size()) + toIndex = list.size(); + log.info(String.format("[info " + Collections.class.getName() + " 执行信息] : list info: [%s] and pageNum info:[%s] and pageSize info: [%s]", new Object[]{list, pageNum, pageSize})); + return list.subList(fromIndex, toIndex); + } catch (Exception e) { + // TODO Auto-generated catch block + log.error(String.format("Class {%s}, Method {%s}", new Object[]{Collections.class.getName(), "pageList"}),e); + throw new RuntimeException(String.format("EntityInfo --- " + Collections.class.getName() + " error: list info: [%s] and pageNum info:[%s] and pageSize info: [%s] ", new Object[]{list, pageNum, pageSize}), e); + } + } + + /** + * 创建对象 + * @author Andy.shi + * @company 龙腾工作室 + * @date 2020年9月15日上午9:37:07 + * @param + * @return + */ + public static List emptyList() { + return new LinkedList(); + } + + /** + * @DES 数组转对象 + * @author andy.shi + * @company 龙腾工作室 + * @createDate 2020年12月25日下午2:09:14 + * @methodName Collections.asList + * @param objs + * @return + * @returnType List + */ + public static List asList(T... objs) { + if (isEmpty(objs)) + return emptyList(); + + List list = emptyList(); + for (T obj : objs) + list.add(obj); + + return list; + } + + /** + * + * @param objs + * @return + */ + public static List asList(Collection objs) { + if (isEmpty(objs)) + return emptyList(); + + List list = emptyList(); + list.addAll(objs); + + return list; + } + + /** + * 去除集合的重复项 + * @author Andy.shi + * @company 龙腾工作室 + * @date 2020年9月24日上午9:09:07 + * @param 泛型,字段的类型, 如果是对象, 请重写hashCode() 和 equals() + * @param list1 去重的集合1 + * @param list2 去重的集合2 + * @return list 去重后的对象 + */ + @SuppressWarnings("unchecked") + public static List removeDuplicatesList(List list1, List list2){ + return removeDuplicatesList(new List[] {list1, list2}); + } + + /** + * 去除集合的重复项 + * @author Andy.shi + * @company 龙腾工作室 + * @date 2020年9月24日上午9:13:09 + * @param 泛型,字段的类型, 如果是对象, 请重写hashCode() 和 equals() + * @param listArray 去重的集合数组 + * @return list 去重后的对象 + */ + @SuppressWarnings("unchecked") + public static List removeDuplicatesList(List... listArray){ + try { + List listAll = emptyList(); + if(listArray == null || listArray.length == 0) { + log.warn("[info " + Collections.class.getName() + " 执行信息] : 数据集合为空, 返回空对象 "); + return emptyList(); + } + for (List list : listArray) { + if(isNotEmpty(list)) { + listAll.addAll(list); + } + } + return (List) listAll.stream().distinct().collect(Collectors.toList()); + } catch (Exception e) { + // TODO Auto-generated catch block + log.error(String.format("Class {%s}, Method {%s}", new Object[]{Collections.class.getName(), "removeDuplicatesList"}),e); + throw new RuntimeException(String.format("EntityInfo --- " + Collections.class.getName() + " error: listArray info: [%s] 去除重复数据异常; ", new Object[]{listArray}), e); + } + } + + + /** + * 获取重复数据 + * @author Andy.shi + * @company 龙腾工作室 + * @date 2020年9月24日上午9:46:03 + * @param 泛型,字段的类型, 如果是对象, 请重写hashCode() 和 equals() + * @param list1 查重的集合1 + * @param list2 查重的集合1 + * @return 并集的数据集合 + */ + @SuppressWarnings("unchecked") + public static List findDuplicatesList(List list1, List list2){ + return findDuplicatesList(new List[] {list1, list2}); + } + /** + * 获取重复数据 + * @author Andy.shi + * @company 龙腾工作室 + * @date 2020年9月24日上午9:44:30 + * @param 泛型,字段的类型, 如果是对象, 请重写hashCode() 和 equals() + * @param listArray 需要查重的集合数组 + * @return 并集的数据集合 + */ + public static List findDuplicatesList(List... listArray){ + try { + if(listArray == null || listArray.length == 0) { + log.warn("[info " + Collections.class.getName() + " 执行信息] : 数据集合为空, 返回空对象 "); + return emptyList(); + } + + if(listArray.length == 1) { + log.warn("[info " + Collections.class.getName() + " 执行信息] : 集合数组只有一个, 不存在重复数据 "); + return listArray[0]; + } + List firstList = listArray[0]; + + for (int i = 1; i < listArray.length; i++) { + firstList.retainAll(listArray[i]); + } + return firstList; + } catch (Exception e) { + // TODO Auto-generated catch block + log.error(String.format("Class {%s}, Method {%s}", new Object[]{Collections.class.getName(), "findDuplicatesList"}),e); + throw new RuntimeException(String.format("EntityInfo --- " + Collections.class.getName() + " error: listArray info: [%s] 获取重复数据异常; ", new Object[]{listArray}), e); + } + } + +/********************** 以上操作list 以下操作map **************************************/ + /** + * + * @param map + * @return + */ + public static boolean isNotEmpty(Map map) { + return ! isEmpty(map); + } + + /** + * @param map + * @return + */ + public static boolean isEmpty(Map map) { + return map == null || map.size() == 0; + } + /** + * @DES 创建空的map对象 + * @author andy.shi + * @company 龙腾工作室 + * @createDate 2020年12月25日下午1:36:35 + * @methodName MapLists.emptyMap + * @return + * @returnType Map + */ + public static final Map emptyMap() { + return new LinkedHashMap(); + } + + + /** + * @DES 组装map数据对象 + * @author andy.shi + * @company 龙腾工作室 + * @createDate 2020年12月25日下午1:37:05 + * @methodName MapLists.createMap + * @param args + * @return + * @returnType Map + */ + @SuppressWarnings("unchecked") + public static Map asMap(Object... args) { + Map map = emptyMap(); + if (args == null || args.length == 0) { + log.warn(String.format("[info " + Collections.class.getName() + " 执行信息] : params的参数不为偶数; args length: [%s]; args info: [%s] ", new Object[]{args.length, args})); + return map; + } else if (args.length % 2 != 0) { + throw new RuntimeException(String.format("EntityInfo --- " + Collections.class.getName() + " error: args must completely match: even param is key, odd param is value, please check your arguments. args length [%s]; args info: [%s]; ", new Object[]{args.length, args})); + } + for (int i=0; ijunit test + + com.alibaba + fastjson + 1.2.58 + diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/dh/DHController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/dh/DHController.java new file mode 100644 index 0000000..35d0d09 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/dh/DHController.java @@ -0,0 +1,41 @@ +package com.evotech.hd.cloud.controller.dh; + +import com.evotech.hd.cloud.service.DHDeviceService; +import com.evotech.hd.common.core.Dto.DeviceDto; +import com.evotech.hd.common.core.entity.Result; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 大华接口 + * @ClassName:DHController + * @date: 2025年04月21日 13:13 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +@Tag(name = "大华设备") +@ApiSupport(order = 48) +@RestController +@RequestMapping("/dh") +public class DHController { + + @Resource + private DHDeviceService dhDeviceService; + + @GetMapping("/device/list") + public Result> deviceList() { + return new Result().success(dhDeviceService.findList()); + } + + + @PostMapping("/device/live") + public Result live(@RequestParam String deviceId, @RequestParam String channelId) { + return new Result().success(dhDeviceService.live(deviceId, channelId)); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/test/TestController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/test/TestController.java new file mode 100644 index 0000000..f52f7a2 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/test/TestController.java @@ -0,0 +1,122 @@ +package com.evotech.hd.cloud.controller.test; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.RandomUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.evotech.hd.cloud.dao.BatteryStationDao; +import com.evotech.hd.cloud.dao.OrderSwapBatteryPreDao; +import com.evotech.hd.cloud.dao.VehicleWechatUserRelationDao; +import com.evotech.hd.cloud.device.dh.DHRequestUtil; +import com.evotech.hd.cloud.utils.components.SwapOrderBasicFeeComponent; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStation; +import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery; +import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre; +import com.evotech.hd.common.core.utils.Collections; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; + +import java.util.Date; +import java.util.List; + +/** + * @desc: + * @ClassName:TestController + * @date: 2025年04月18日 14:40 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +@RestController +@RequestMapping("/test") +public class TestController { + + @Resource + private BatteryStationDao batteryStationDao; + private VehicleWechatUserRelationDao vehicleWechatUserRelationDao; + @Resource + private OrderSwapBatteryPreDao orderSwapBatteryPreDao; + @Resource + private SwapOrderBasicFeeComponent orderBasicFeeComponent; + + @GetMapping("/station") + public Result list() { + System.out.println("======>>开始......"); + BatteryStation station = batteryStationDao.selectOne(new LambdaQueryWrapper().eq(BatteryStation::getCode,"FD12795455")); + // 查这天,这个站的预约 + List orderPreList = orderSwapBatteryPreDao.selectList(new QueryWrapper().eq("station_code", station.getCode()).eq("status", 1).eq("ucode","e2fb21b6447e10006f19a23e06b67914")); + // 根据预约生成订单 + if (orderPreList.isEmpty()) { + System.out.println("没有预约单"); + } + OrderSwapBatteryPre orderPre = orderPreList.get(0); + OrderSwapBattery order = new OrderSwapBattery(); + order.setOrderType(1); + order.setCtime(new Date()); + order.setCreater("TEST"); + order.setOrderPreId(orderPre.getPkId()); + order.setOrderPreUid(orderPre.getUcode()); + order.setOrderPreUname(orderPre.getUname()); + order.setOrderPrePhone(orderPre.getPhone()); + order.setOrderTime(new Date()); + order.setOrderNo(orderNo(station.getCode(), order.getOrderTime())); + order.setPlateNum(orderPre.getPlateNum()); + + order.setStationCode(orderPre.getStationCode()); + order.setStationName(orderPre.getStationName()); + order.setStatus(1); + order.setFeeType(3); + order.setDelFlag(0); + order.setRemark("测试用的"); + order.setChangeMode(1); + order.setChangeLane(1); + // 加上费用标准 + order = orderBasicFeeComponent.orderBasicFee(order); + + System.out.println(JSONUtil.toJsonStr(order)); + return new Result().success(order); + } + + + private String orderNo(String stationCode, Date d) { + String orderNoPrefix = "YTSO"; + String orderNoMiddle1 = stationCode.length() <= 8?stationCode : stationCode.substring(stationCode.length() - 8); + String orderNoMiddle2 = DateUtil.format(d, DatePattern.PURE_DATETIME_MS_FORMATTER); + String orderNoSuffix = RandomUtil.randomNumbers(2) + RandomUtil.randomChar("ABCDEF"); + return orderNoPrefix + orderNoMiddle1 + orderNoMiddle2 + orderNoSuffix; + } + + @PostMapping("/device/live") + public Result deviceLive(@RequestParam String deviceId, @RequestParam String channelId) { + return new Result().success(DHRequestUtil.live(deviceId, channelId)); + } + + @PostMapping("/device/liveInfo") + public Result deviceLiveInfo(@RequestParam String deviceId, @RequestParam String channelId) { + return new Result().success(DHRequestUtil.liveInfo(deviceId, channelId)); + } + + @PostMapping("/device/delLive") + public Result delLive(@RequestParam String liveToken) { + return new Result().success(DHRequestUtil.delLive(liveToken)); + } + + @PostMapping("/device/list") + public Result deviceList(@RequestParam Integer page, @RequestParam Integer pageSize) { + return new Result().success(DHRequestUtil.deviceList(Collections.asMap("pageNum", page, "pageSize", pageSize))); + } + + @PostMapping("/device/createDeviceStreamUrl") + public Result createDeviceStreamUrl(@RequestParam String deviceId, @RequestParam String channelId) { + return new Result().success(DHRequestUtil.createDeviceStreamUrl(deviceId, channelId)); + } + + @PostMapping("/store/list") + public Result storeList(@RequestParam Integer page, @RequestParam Integer pageSize) { + return new Result().success(DHRequestUtil.storeList(page, pageSize)); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/device/dh/DHProperties.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/device/dh/DHProperties.java new file mode 100644 index 0000000..2d8354c --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/device/dh/DHProperties.java @@ -0,0 +1,34 @@ +package com.evotech.hd.cloud.device.dh; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * 大华的参数信息 + * @ClassName:DHProperties + * @date: 2025年04月19日 13:28 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +@ConfigurationProperties(prefix = "dh", ignoreUnknownFields = true) +@Data +@Component +public class DHProperties { + + private String url; + + private String clientId; + + private String clientSecret; + + private String contentType; + + private String acceptLanguage; + + private String orgCode; + + private String orgId; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/device/dh/DHRequestUtil.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/device/dh/DHRequestUtil.java new file mode 100644 index 0000000..6c876dc --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/device/dh/DHRequestUtil.java @@ -0,0 +1,308 @@ +package com.evotech.hd.cloud.device.dh; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.evotech.hd.cloud.exception.DHException; +import com.evotech.hd.common.core.constant.HDConstant; +import com.evotech.hd.common.core.utils.Collections; +import com.evotech.hd.common.permission.util.SpringUtil; +import com.evotech.hd.common.redis.utils.RedisUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.util.EntityUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Date; +import java.util.Iterator; +import java.util.Map; + +/** + * 大华的请求接口 + * @ClassName:DHRequestUtil + * @date: 2025年04月21日 9:14 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +@Slf4j +@Component +public class DHRequestUtil { + + static DHProperties dhProperties; + + @Autowired + public DHRequestUtil(DHProperties dhProperties) { + this.dhProperties = dhProperties; + } + + /*** + * 查询场所列表 + * @return + */ + public static JSONObject storeList(Integer page, Integer pageSize) { + String path = "membership/api/store/page"; + return getResultData(execute(Collections.asMap("pageNum", page, "pageSize",pageSize), getHeadersMap(), path,"GET")); + } + + /*** + * 添加场所 + * @return + */ + public static JSONObject addStore(Map params) { + String path = "membership/api/store/add"; + //处理上级信息 + params.put("orgCode", dhProperties.getOrgCode()); + return getResultData(execute(params, getHeadersMap(), path)); + } + + /*** + * 获取设备列表 + * @return + */ + public static JSONObject deviceList(Map params) { + String path = "device/api/page"; + return getResultData(execute(params, getHeadersMap(), path)); + } + + /*** + * 获取设备信息 + * @param deviceId + * @return + */ + private static JSONObject deviceInfo(String deviceId) { + String path = "device/api/deviceInfo"; + return getResultData(execute(Collections.asMap("deviceId", deviceId), getHeadersMap(), path)); + } + + /*** + * 创建设备直播地址 + * @param deviceId + * @param channelId + * @return + */ + public static JSONObject live(String deviceId, String channelId) { + String path = "videobussiness/api/device/live"; + return getResultData(execute(Collections.asMap("deviceId", deviceId,"channelId", channelId), getHeadersMap(), path)); + } + + /*** + * 创建设备直播地址 + * @param deviceId + * @param channelId + * @return + */ + public static JSONObject delLive(String liveToken) { + String path = "videobussiness/api/unLive"; + return getResultData(execute(Collections.asMap("liveToken", liveToken), getHeadersMap(), path)); + } + + /*** + * 查询hls直播地址和直播状态 + * @param deviceId + * @param channelId + * @return + */ + public static JSONObject liveInfo(String deviceId, String channelId) { + String path = "videobussiness/api/device/liveInfo"; + return getResultData(execute(Collections.asMap("deviceId", deviceId,"channelId", channelId), getHeadersMap(), path)); + } + + /*** + * 创建设备流地址 + * @param deviceId + * @param channelId + * @return + */ + public static JSONObject createDeviceStreamUrl(String deviceId, String channelId) { + String path = "videobussiness/api/createDeviceStreamUrl"; + return getResultData(execute(Collections.asMap("deviceId", deviceId,"channelId", channelId,"businessType","real","encryptMode","0"), getHeadersMap(), path)); + } + + + + + + + + + /** + * @description: + * @author: andy.shi + * @contact: 17330188597 + * @date: 2025/4/21 + * @param json: 请求的数据信息 + * @return: com.alibaba.fastjson.JSONObject + */ + private static JSONObject getResultData(JSONObject json){ + if(json == null || !json.getString("code").equals("0")){ + return json; + } + log.info("返回结果==={}", json.getJSONObject("data")); + return json.getJSONObject("data"); + } + + private static JSONObject execute(Map paramsMap, Map headersMap, String path) { + return execute(paramsMap, headersMap,path, null); + } + + + private static JSONObject execute(Map paramsMap, Map headersMap, String path, String method) { + // 返回json + if("auth/oauth/token".equals(method)){ + return HttpUtils.sendPost(dhProperties.getUrl() + path, paramsMap, headersMap); + }else{ + if("GET".equals(method)){ + return doGet(dhProperties.getUrl() + path, paramsMap, headersMap); + }else{ + return doPost(dhProperties.getUrl() + path, paramsMap, headersMap); + } + } + } + + private static Map getHeadersMap(){ + return Collections.asMap("Content-Type", dhProperties.getContentType(),"Accept-Language", dhProperties.getAcceptLanguage(), "Authorization", getRedisAccessToken()); + } + + private static JSONObject doPost(String url, Map map, Map headersMap) { + log.info("doPost请求== 请求接口 ===={}", url); + String json = JSON.toJSONString(map); + log.info("doPost请求== 请求参数 ===={}", json); + log.info("doPost请求== 请求headers ===={}", JSON.toJSONString(headersMap)); + HttpClient client = new DefaultHttpClient(); + HttpPost post = new HttpPost(url); + JSONObject jsonObject = new JSONObject(); + try { + StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON); + post.setEntity(entity); + Iterator keyIterator = headersMap.keySet().iterator(); + while (keyIterator.hasNext()){ + String key = keyIterator.next();; + post.setHeader(key, headersMap.get(key)); + } + + String result = EntityUtils.toString(client.execute(post).getEntity(), "UTF-8"); + jsonObject = com.alibaba.fastjson.JSONObject.parseObject(result); + } catch (Exception e) { + e.printStackTrace(); + } finally { + post.releaseConnection(); + } + return jsonObject; + } + + private static JSONObject doGet(String url, Map map, Map headersMap) { + log.info("doPost请求== 请求接口 ===={}", url); + String json = JSON.toJSONString(map); + log.info("doPost请求== 请求参数 ===={}", json); + log.info("doPost请求== 请求headers ===={}", JSON.toJSONString(headersMap)); + // 拼接参数请求 + if(Collections.isNotEmpty(map)){ + StringBuffer sb = new StringBuffer(url).append("?"); + Integer maxParams = map.size(); + Integer i = 1; + for (String key : map.keySet()) { + sb.append(key).append("=").append(map.get(key)); + if(i< maxParams){ + sb.append("&"); + } + } + //转换url + url = sb.toString(); + } + HttpClient client = new DefaultHttpClient(); + HttpGet get = new HttpGet(url); + JSONObject jsonObject = new JSONObject(); + try { + Iterator keyIterator = headersMap.keySet().iterator(); + while (keyIterator.hasNext()){ + String key = keyIterator.next();; + get.setHeader(key, headersMap.get(key)); + } + + String result = EntityUtils.toString(client.execute(get).getEntity(), "UTF-8"); + jsonObject = com.alibaba.fastjson.JSONObject.parseObject(result); + } catch (Exception e) { + e.printStackTrace(); + } finally { + get.releaseConnection(); + } + return jsonObject; + } + + + + private static RedisUtil getRedisUtil(){ + return SpringUtil.getBean(RedisUtil.class); + } + + /** + * @description: 获取redis数据库存储的token + * @author: andy.shi + * @contact: 17330188597 + * @date: 2022/4/2 15:39 + * @return: java.lang.String + */ + private static String getRedisAccessToken(){ + RedisUtil redisUtil = getRedisUtil(); + //获取获取accessToken + String accessToken = redisUtil.getStringValue(HDConstant.DHConstant.DH_ACCESS_TOKEN_KEY); + if(StringUtils.isNotEmpty(accessToken) && accessToken.indexOf("null") < 0){ + //获取accessToken的获取时间 + Long accessTokenGetTime = Long.valueOf(redisUtil.getStringValue(HDConstant.DHConstant.DH_ACCESS_TOKEN_TIME_KEY)); + //获取过期时间 秒 + Long accessTokenExpireTime = Long.valueOf(redisUtil.getStringValue(HDConstant.DHConstant.DH_ACCESS_TOKEN_EXPIRE_TIME_KEY)); + //获取当前时间的时间戳 + Long currentTime = new Date().getTime(); + //计算是否过期 + if(((currentTime-accessTokenGetTime)/1000) > (accessTokenExpireTime - HDConstant.DHConstant.DH_REACQUIRE_ACCESS_TOKEN_CRITICAL_VALUE)){ + //如果过期, 重新调取大华接口, 重新生成, 并更新key + accessToken = createAccessToken(); + } + }else{ + //如果redis数据库不存在当前key, 直接获取大华的接口生成, 然后存储 + accessToken = createAccessToken(); + } + return accessToken; + } + + + /** + * @description: 调取大华接口 生成Token + * @author: andy.shi + * @contact: 17330188597 + * @date: 2022/4/2 15:38 + * @return: java.lang.String + */ + private static String createAccessToken(){ + try { + RedisUtil redisUtil = getRedisUtil(); + Date loadData = new Date(); + String path = "auth/oauth/token"; + JSONObject json = execute(Collections.asMap("client_id", dhProperties.getClientId(), "client_secret", dhProperties.getClientSecret(), "grant_type", "client_credentials", "scope", "server"), Collections.asMap("Content-Type","application/x-www-form-urlencoded") ,path); + if(ObjectUtils.isEmpty(json) || json.isEmpty() || !json.containsKey("access_token")){ + throw new DHException(String.format("token获取异常, 数据结果{%s}", json.toJSONString())); + } + //过期时间 + Long expireTime = json.getLong("expires_in"); + //accessTokne, 拼接大华的验证信息 + String token = "Bearer " + json.getString("access_token"); + //记录获取时间的时间戳 + redisUtil.set(HDConstant.DHConstant.DH_ACCESS_TOKEN_TIME_KEY, String.valueOf(loadData.getTime())); + redisUtil.set(HDConstant.DHConstant.DH_ACCESS_TOKEN_EXPIRE_TIME_KEY, String.valueOf(expireTime)); + redisUtil.set(HDConstant.DHConstant.DH_ACCESS_TOKEN_KEY, token); + return token; + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("token获取异常",e); + } + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/device/dh/HttpUtils.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/device/dh/HttpUtils.java new file mode 100644 index 0000000..dbdf5e5 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/device/dh/HttpUtils.java @@ -0,0 +1,257 @@ +package com.evotech.hd.cloud.device.dh; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.evotech.hd.common.core.utils.Collections; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.CookieStore; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicCookieStore; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.cookie.BasicClientCookie; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * @desc: + * @ClassName:HttpUtils + * @date: 2022年03月10日 16:25 + * @company: 茹臣科技 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ + +@Slf4j +public class HttpUtils { + + public static String sendGet(String url) { + return sendGet(url,null,null); + } + + public static String sendGetParams(String url, Map params) { + return sendGet(url,params,null); + } + + public static String sendGetHeaders(String url, Map headers) { + return sendGet(url,null,headers); + } + + public static String sendGet(String url, Map params, Map headers) { + return sendGetCookies(url,params,headers, null); + } + + public static String sendGetCookies(String url, Map params, Map headers, List cookies) { + log.info("sendGetCookies请求 接口地址====================={}", url); + if(Collections.isNotEmpty(params)){ + log.info("sendGetCookies请求 传入参数====================={}", params.toString().trim()); + } + if(Collections.isNotEmpty(headers)){ + log.info("sendGetCookies请求 传入header====================={}", headers.toString().trim()); + } + + // 拼接参数请求 + if(Collections.isNotEmpty(params)){ + StringBuffer sb = new StringBuffer(url).append("?"); + Integer maxParams = params.size(); + Integer i = 1; + for (String key : params.keySet()) { + sb.append(key).append("=").append(params.get(key)); + if(i< maxParams){ + sb.append("&"); + } + } + //转换url + url = sb.toString(); + } + //设置get请求 + HttpGet get = new HttpGet(url); + + //添加请求头参数 + if(Collections.isNotEmpty(headers)){ + for (String key: headers.keySet()) { + get.addHeader(key,headers.get(key)); + } + } + try { + CloseableHttpClient client = null; + if(Collections.isNotEmpty(cookies)){ + //存储cookies信息变量 + CookieStore store = new BasicCookieStore(); + for (String cookie : cookies) { + String[] c = cookie.split("="); + store.addCookie(new BasicClientCookie(c[0],c[1])); + } + client = HttpClients.custom().setDefaultCookieStore(store).build(); + }else{ + client = HttpClients.createDefault(); + } + if(client != null){ + //启动执行请求,并获得返回值 + CloseableHttpResponse response = client.execute(get); + //得到返回的entity对象 + HttpEntity entity = response.getEntity(); + //把实体对象转换为string + return EntityUtils.toString(entity, "UTF-8"); + } + + return ""; + + } catch (Exception e1) { + e1.printStackTrace(); + } + return ""; + } + + public static JSONObject sendPost(String url) throws Exception { + return sendPost(url, null, null); + } + + public static JSONObject sendPostParams(String url, Map params) { + return sendPost(url, params, null); + } + + public static JSONObject sendPostHeaders(String url, Map headers){ + return sendPost(url, null, headers); + } + + public static JSONObject sendPost(String url, Map params, Map headers) { + return sendPostCookie(url, params, headers, null); + } + + public static JSONObject sendPostCookie(String url, Map params, Map headers,List cookies) { + log.info("sendPostCookie请求 接口地址======{}", url); + if(Collections.isNotEmpty(params)){ + log.info("sendPostCookie请求 传入参数======{}", params.toString().trim()); + } + if(Collections.isNotEmpty(headers)){ + log.info("sendPostCookie请求 传入header======{}", headers.toString().trim()); + } + //创建post请求对象 + HttpPost post = new HttpPost(url); + try { + //添加请求参数 + if(Collections.isNotEmpty(params)){ + //创建参数集合 + List list = new ArrayList(); + for (String key: params.keySet()) { + list.add(new BasicNameValuePair(key, String.valueOf(params.get(key)))); + } + // 把参数放入请求对象,,post发送的参数list,指定格式 + post.setEntity(new UrlEncodedFormEntity(list, "UTF-8")); + } + //添加请求头参数 + if(Collections.isNotEmpty(headers)){ + for (String key: headers.keySet()) { + post.addHeader(key,String.valueOf(headers.get(key))); + } + } + + CloseableHttpClient client = null; + if(Collections.isNotEmpty(cookies)){ + //存储cookies信息变量 + CookieStore store = new BasicCookieStore(); + for (String cookie : cookies) { + String[] c = cookie.split("="); + store.addCookie(new BasicClientCookie(c[0],c[1])); + } + client = HttpClients.custom().setDefaultCookieStore(store).build(); + }else{ + client = HttpClients.createDefault(); + } + if(client != null){ + //启动执行请求,并获得返回值 + CloseableHttpResponse response = client.execute(post); + //得到返回的entity对象 + HttpEntity entity = response.getEntity(); + //把实体对象转换为string +// return EntityUtils.toString(entity, "UTF-8"); + JSONObject result = JSONObject.parseObject(EntityUtils.toString(entity, "UTF-8")); + log.info("请求接口:{}======返回结果信息{}", url, result.toJSONString()); + return result; + } + return new JSONObject(); + } catch (Exception e1) { + e1.printStackTrace(); + + } + return new JSONObject(); + } + + + public static JSONObject doPost(String url, Map map, Map headersMap,List cookies) { + log.info("doPost 接口地址======{}", url); + if(Collections.isNotEmpty(map)){ + log.info("doPost 传入参数======{}", map.toString().trim()); + } + if(Collections.isNotEmpty(headersMap)){ + log.info("doPost 传入header======{}", headersMap.toString().trim()); + } + if(Collections.isNotEmpty(cookies)){ + log.info("doPost 传入cookies======{}", cookies.toString().trim()); + } + + HttpPost post = new HttpPost(url); + JSONObject jsonObject = new JSONObject(); + try { + String json = JSON.toJSONString(map); + StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON); + post.setEntity(entity); + Iterator keyIterator = headersMap.keySet().iterator(); + while (keyIterator.hasNext()){ + String key = keyIterator.next();; + post.setHeader(key, String.valueOf(headersMap.get(key))); + } + + HttpClient client = null; + if(Collections.isNotEmpty(cookies)){ + //存储cookies信息变量 + CookieStore store = new BasicCookieStore(); + for (String cookie : cookies) { + String[] c = cookie.split("="); + store.addCookie(new BasicClientCookie(c[0],c[1])); + } + client = HttpClients.custom().setDefaultCookieStore(store).build(); + }else{ + client = HttpClients.createDefault(); + } + //启动执行请求,并获得返回值 + HttpResponse response = client.execute(post); + //得到返回的entity对象 + HttpEntity entity1 = response.getEntity(); + + String result = EntityUtils.toString(entity1, "UTF-8"); + jsonObject = JSONObject.parseObject(result); + } catch (Exception e) { + e.printStackTrace(); + } finally { + post.releaseConnection(); + } + return jsonObject; + } + + + public static boolean isAjax(ServletRequest request){ + String header = ((HttpServletRequest) request).getHeader("X-Requested-With"); + if("XMLHttpRequest".equalsIgnoreCase(header)){ + return Boolean.TRUE; + } + return Boolean.FALSE; + } +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/exception/DHException.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/exception/DHException.java new file mode 100644 index 0000000..92ee154 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/exception/DHException.java @@ -0,0 +1,26 @@ +package com.evotech.hd.cloud.exception; + +import lombok.extern.slf4j.Slf4j; + +/** + * @ClassName:DHException + * @date: 2025年04月21日 14:15 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ + +@Slf4j +public class DHException extends Exception{ + + public DHException() { + super(); + } + + public DHException(String message) { + super(message); + log.error("大华(DH)异常============{}", message); + } + + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationService.java index b0b955a..dabbfe9 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationService.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationService.java @@ -34,4 +34,6 @@ public interface BatteryStationService { public BaseResponse> resourceList(String pkIds); + List deviceList(String proxyCode); + } diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/DHDeviceService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/DHDeviceService.java new file mode 100644 index 0000000..a80dc5c --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/DHDeviceService.java @@ -0,0 +1,22 @@ +package com.evotech.hd.cloud.service; + +import com.evotech.hd.common.core.Dto.DeviceDto; +import com.evotech.hd.common.core.entity.Result; + +import java.util.List; + +/** + * 大华设备信息接口 + * @ClassName:DHDeviceService + * @date: 2025年04月21日 14:33 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ + +public interface DHDeviceService { + + Result> findList(); + + Result live(String deviceId, String channelId); +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationServiceImpl.java index a4e5f6b..fe7f319 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationServiceImpl.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationServiceImpl.java @@ -5,14 +5,17 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.IoUtil; import cn.hutool.crypto.KeyUtil; import cn.hutool.crypto.asymmetric.AsymmetricAlgorithm; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.evotech.hd.cloud.dao.BatteryStationDao; import com.evotech.hd.cloud.dao.BatteryStationSecretKeyDao; import com.evotech.hd.cloud.dao.VehicleInfoDao; +import com.evotech.hd.cloud.device.dh.DHRequestUtil; import com.evotech.hd.cloud.entity.BatteryStationSecretKey; import com.evotech.hd.cloud.entity.request.PageListBatteryStationRequest; +import com.evotech.hd.cloud.exception.DHException; import com.evotech.hd.cloud.service.BatteryStationService; import com.evotech.hd.cloud.service.rpc.WechatService; import com.evotech.hd.common.core.Dto.BaseResponse; @@ -21,9 +24,12 @@ import com.evotech.hd.common.core.entity.cloud.BatteryStation; import com.evotech.hd.common.core.entity.cloud.VehicleInfo; import com.evotech.hd.common.core.entity.cloud.vo.BatteryStationVO; import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.common.core.utils.Collections; import jakarta.annotation.Resource; import jakarta.servlet.ServletOutputStream; import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ObjectUtils; import org.springframework.beans.BeanUtils; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; @@ -37,8 +43,9 @@ import java.security.KeyPair; import java.util.*; @Service +@Slf4j public class BatteryStationServiceImpl implements BatteryStationService { - + @Resource private BatteryStationDao batteryStationDao; @Resource @@ -59,11 +66,42 @@ public class BatteryStationServiceImpl implements BatteryStationService { } int n = batteryStationDao.insert(bs); if (n == 1) { + addStore(bs); return new Result().success(n); } return new Result().error("添加换电站出错!"); } + + private void addStore(BatteryStation station){ + try { + JSONObject json = DHRequestUtil.addStore(Collections.asMap("storeName", station.getName(),"managerName", station.getContacts(), "managerMobile", station.getPhone(), "address", address(station.getAddress()))); + if(ObjectUtils.isNotEmpty(json) && !json.isEmpty() && json.getBoolean("success")){ + JSONObject jsonData = json.getJSONObject("data"); + if(ObjectUtils.isNotEmpty(jsonData) && !jsonData.isEmpty()){ + station.setStoreId(jsonData.getString("storeId")); + station.setOrgCode(jsonData.getString("thisOrgCode")); + batteryStationDao.updateById(station); + } + }else{ + throw new DHException(json != null ? json.getString("errMsg") : " 大华接口请求失败"); + } + } catch (Exception e) { + log.error("创建大华设备场所失败:{}", e.getMessage()); + } + } + + private String address(String address){ + if(org.apache.commons.lang3.StringUtils.isNotEmpty(address)){ + if(address.length() > 150){ + address = address.substring(0,149); + } + } + return address; + } + + + @Override @Transactional public Result delete(Integer id) { @@ -93,7 +131,7 @@ public class BatteryStationServiceImpl implements BatteryStationService { if (list.isEmpty()) { return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); } - + // page = batteryStationDao.selectPage(page, new QueryWrapper() // .eq(StringUtils.hasText(plbsr.getProxyId()), "proxy_id", plbsr.getProxyId()) // .like(StringUtils.hasText(plbsr.getCode()), "code", plbsr.getCode()) @@ -165,7 +203,7 @@ public class BatteryStationServiceImpl implements BatteryStationService { BeanUtils.copyProperties(i, vo); return vo; }).toList(); - + if (StringUtils.hasText(plateNum)) { VehicleInfo vi = vehicleInfoDao.selectOne(new QueryWrapper() .eq("del_flag", 0) @@ -183,7 +221,7 @@ public class BatteryStationServiceImpl implements BatteryStationService { .sorted(Comparator.comparing(BatteryStationVO::getIsSuitable)) .toList(); } - + return new Result>().success(res); } @@ -209,7 +247,7 @@ public class BatteryStationServiceImpl implements BatteryStationService { } finally { IoUtil.close(out); } - + } @Override @@ -234,7 +272,7 @@ public class BatteryStationServiceImpl implements BatteryStationService { } finally { IoUtil.close(out); } - + } @Override @@ -277,4 +315,9 @@ public class BatteryStationServiceImpl implements BatteryStationService { return new BaseResponse>().success(batteryStationDao.selectList(new LambdaQueryWrapper().eq((pkIdArray != null && pkIdArray.length > 0), BatteryStation::getPkId, Arrays.asList(pkIdArray)).eq(BatteryStation::getStatus, 1).eq(BatteryStation::getDelFlag, 0).select(BatteryStation::getPkId, BatteryStation::getCode))); } + @Override + public List deviceList(String proxyCode) { + return batteryStationDao.selectList(new LambdaQueryWrapper().eq(BatteryStation::getProxyId, proxyCode).select(BatteryStation::getPkId, BatteryStation::getName, BatteryStation::getStoreId, BatteryStation::getOrgCode)); + } + } diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/DHDeviceServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/DHDeviceServiceImpl.java new file mode 100644 index 0000000..60a9801 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/DHDeviceServiceImpl.java @@ -0,0 +1,150 @@ +package com.evotech.hd.cloud.service.impl; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.evotech.hd.cloud.device.dh.DHRequestUtil; +import com.evotech.hd.cloud.service.BatteryStationService; +import com.evotech.hd.cloud.service.DHDeviceService; +import com.evotech.hd.cloud.service.rpc.ResourceService; +import com.evotech.hd.common.core.Dto.BaseResponse; +import com.evotech.hd.common.core.Dto.DeviceDto; +import com.evotech.hd.common.core.constant.HDConstant; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.ProxyOperater; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.common.core.utils.Collections; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; + +/** + * 大华设备处理 + * @ClassName:DHDeviceServiceImpl + * @date: 2025年04月21日 14:42 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ + +@Slf4j +@Service +public class DHDeviceServiceImpl implements DHDeviceService { + + @Resource + ResourceService resourceService; + @Resource + BatteryStationService batteryStationService; + @Override + public Result> findList() { + List result = new ArrayList<>(); + BaseResponse> proxyResult = resourceService.deviceList(); + if(CodeMsg.SUCCESS.getCode().equals(proxyResult.getCode())){ + proxyResult.getData().forEach(proxy ->{ + result.add(new DeviceDto(proxy.getPocode(),"0", proxy.getPoname(),"","", buildStation(proxy.getPocode()))); + }); + } + return new Result>().success(result); + } + + @Override + public Result live(String deviceId, String channelId) { + AtomicReference url = new AtomicReference<>(""); + JSONObject liveJSON = DHRequestUtil.live(deviceId,channelId); + JSONArray urlArray = null; + if(HDConstant.DHConstant.LIVE_EXISTS_CODE.equals(liveJSON.getString("code"))){ + JSONObject liveInfoJSON = DHRequestUtil.liveInfo(deviceId,channelId); + urlArray = liveInfoJSON.getJSONArray("streams"); + }else{ + //如果不包含code, 则成功了, 直接获取就行 + urlArray = liveJSON.getJSONArray("streams"); + } + + if(urlArray != null){ + urlArray.stream().forEach( urlJSON ->{ + JSONObject urlObj = (JSONObject)urlJSON; + // 码流类型(0:高清;1:标清) + if("1".equals(urlObj.getString("streamId")) && urlObj.getString("hls").contains("proto=https")){ + url.set(urlObj.getString("hls")); + } + }); + } + return (StringUtils.isNotEmpty(url.get()) ? new Result().success("成功", url.get()) : new Result().error("未找到设备直播地址")); + } + + + public List buildStation(String code){ + return batteryStationService.deviceList(code).stream().map(station ->{ + return new DeviceDto(station.getStoreId(), code, station.getName(), "","", buildDevice(station.getStoreId())); + }).collect(Collectors.toList()); + } + + public List buildDevice(String storeId){ + Boolean findList = true; + Integer page = 1; + List result = Collections.emptyList(); + while (findList){ + JSONObject jsonObject = DHRequestUtil.deviceList(Collections.asMap("pageNum", page, "pageSize", 200, "storeId",storeId)); + if(HDConstant.DHConstant.SUCCESS_CODE.equals(jsonObject.getString("code"))){ + JSONObject jsonData = jsonObject.getJSONObject("data"); + Long totalRows = jsonData.getLong("totalRows"); + //如果totalRows.compareTo(page*pageSize) <= 0 则证明数据已经抓取完 + if(totalRows.compareTo(new BigDecimal(page).multiply(new BigDecimal(200)).longValue()) <= 0){ + findList = false; + } + JSONArray pageData = jsonData.getJSONArray("pageData"); + if(pageData != null && !pageData.isEmpty()){ + pageData.stream().forEach(pData ->{ + JSONObject pj = (JSONObject)pData; + DeviceDto device = new DeviceDto(); + device.setId(pj.getString("deviceId")); + device.setParentId(storeId); + device.setName(pj.getString("name")); + device.setDeviceId(device.getId()); + device.setChannelId(""); + device.setChildList(buildChannel(pj, device.getId())); + result.add(device); + + }); + } + page = page + 1; + }else{ + findList = false; + log.error("大华(DH)异常============{}", jsonObject.getString("msg")); + } + } + return result; + } + + public List buildChannel(JSONObject json, String parentId){ + List result = Collections.emptyList(); + JSONArray channelData = json.getJSONArray("channelList"); + if(channelData != null && !channelData.isEmpty()){ + channelData.stream().forEach(pData ->{ + JSONObject pj = (JSONObject)pData; + DeviceDto device = new DeviceDto(); + device.setId(parentId +"_"+pj.getString("channelId")); + device.setParentId(parentId); + device.setName(pj.getString("channelName")); + device.setDeviceId(parentId); + device.setChannelId(pj.getString("channelId")); + device.setChildList(Collections.emptyList()); + result.add(device); + }); + } + return result; + } + + + public static void main(String[] args) { + System.out.println(Long.valueOf(201).compareTo(new BigDecimal(2).multiply(new BigDecimal(200)).longValue())); + } + + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/rpc/ResourceService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/rpc/ResourceService.java index 7f5a8cb..5f1c7ec 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/rpc/ResourceService.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/rpc/ResourceService.java @@ -1,6 +1,8 @@ package com.evotech.hd.cloud.service.rpc; +import com.evotech.hd.common.core.Dto.BaseResponse; import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.ProxyOperater; import com.evotech.hd.common.core.entity.resource.dict.Dict; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.http.MediaType; @@ -16,5 +18,9 @@ public interface ResourceService { @GetMapping(value = "/dict/listdict", consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE}) public Result> listDict(@RequestParam String typeCode); + + @GetMapping(value = "/proxyoperater/device/list", + consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE}) + public BaseResponse> deviceList(); } diff --git a/cloud-manage-server/src/main/resources/mapper/BatteryStationMapper.xml b/cloud-manage-server/src/main/resources/mapper/BatteryStationMapper.xml index 666ffc5..525ca09 100644 --- a/cloud-manage-server/src/main/resources/mapper/BatteryStationMapper.xml +++ b/cloud-manage-server/src/main/resources/mapper/BatteryStationMapper.xml @@ -30,6 +30,8 @@ + + diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/AuthorizationManager.java b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/AuthorizationManager.java index 235d3f4..df7abdb 100644 --- a/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/AuthorizationManager.java +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/AuthorizationManager.java @@ -29,6 +29,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; +import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -181,13 +182,24 @@ public class AuthorizationManager implements ReactiveAuthorizationManager notPermissionUrlList = Arrays.asList(notPermissionUrl.split(";")); //已授权接口,和无需授权接口 - if (!permList.contains(path) && !Arrays.asList(notPermissionUrl.split(";")).contains(path)) { - throw new OAuth2AuthorizationException(new OAuth2Error(CodeMsg.ACCESS_DENY.getCode(), CodeMsg.ACCESS_DENY.getMsg(), uri)); + if (!permList.contains(path) && !notPermissionUrlList.contains(path)) { + Boolean notPermission = true; + for (String notPermissionUrl : notPermissionUrlList) + if(Pattern.compile(notPermissionUrl).matcher("/cloud/test/123/asd").find()){ + notPermission = false; + break; + } + //验证正则匹配是否通过 + if(notPermission){ + throw new OAuth2AuthorizationException(new OAuth2Error(CodeMsg.ACCESS_DENY.getCode(), CodeMsg.ACCESS_DENY.getMsg(), uri)); + } } return true; } - + } diff --git a/resource-server/src/main/java/com/evotech/hd/resource/controller/ProxyOperaterController.java b/resource-server/src/main/java/com/evotech/hd/resource/controller/ProxyOperaterController.java index 18cf23f..7f7f75f 100644 --- a/resource-server/src/main/java/com/evotech/hd/resource/controller/ProxyOperaterController.java +++ b/resource-server/src/main/java/com/evotech/hd/resource/controller/ProxyOperaterController.java @@ -1,5 +1,6 @@ package com.evotech.hd.resource.controller; +import com.evotech.hd.common.core.Dto.BaseResponse; import com.evotech.hd.common.core.entity.Result; import com.evotech.hd.common.core.entity.resource.ProxyOperater; import com.evotech.hd.resource.entity.request.PageListProxyOperaterRequest; @@ -56,6 +57,11 @@ public class ProxyOperaterController { return proxyOperaterService.list(plpor); } - + @Operation(summary = "查询") + @GetMapping("/device/list") + @ApiOperationSupport(order = 4) + public BaseResponse> deviceList() { + return proxyOperaterService.deviceList(); + } } diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/ProxyOperaterService.java b/resource-server/src/main/java/com/evotech/hd/resource/service/ProxyOperaterService.java index f2dbdfb..cb9635d 100644 --- a/resource-server/src/main/java/com/evotech/hd/resource/service/ProxyOperaterService.java +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/ProxyOperaterService.java @@ -1,11 +1,12 @@ package com.evotech.hd.resource.service; -import java.util.List; - +import com.evotech.hd.common.core.Dto.BaseResponse; import com.evotech.hd.common.core.entity.Result; import com.evotech.hd.common.core.entity.resource.ProxyOperater; import com.evotech.hd.resource.entity.request.PageListProxyOperaterRequest; +import java.util.List; + public interface ProxyOperaterService { public Result add(ProxyOperater po); @@ -16,4 +17,5 @@ public interface ProxyOperaterService { public Result> list(PageListProxyOperaterRequest plpor); + public BaseResponse> deviceList(); } diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/ProxyOperaterServiceImpl.java b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/ProxyOperaterServiceImpl.java index 2992253..f77416c 100644 --- a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/ProxyOperaterServiceImpl.java +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/ProxyOperaterServiceImpl.java @@ -1,22 +1,22 @@ package com.evotech.hd.resource.service.impl; -import java.util.Date; -import java.util.List; - -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.StringUtils; - +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.common.core.Dto.BaseResponse; import com.evotech.hd.common.core.dao.resource.ProxyOperaterDao; import com.evotech.hd.common.core.entity.Result; import com.evotech.hd.common.core.entity.resource.ProxyOperater; import com.evotech.hd.common.core.enums.CodeMsg; import com.evotech.hd.resource.entity.request.PageListProxyOperaterRequest; import com.evotech.hd.resource.service.ProxyOperaterService; - import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; + +import java.util.Date; +import java.util.List; @Service public class ProxyOperaterServiceImpl implements ProxyOperaterService { @@ -71,4 +71,9 @@ public class ProxyOperaterServiceImpl implements ProxyOperaterService { return new Result>().success(page); } + @Override + public BaseResponse> deviceList() { + return new BaseResponse>().success(proxyOperaterDao.selectList(new LambdaQueryWrapper().eq(ProxyOperater::getStatus, 1).eq(ProxyOperater::getDelFlag, 0).select(ProxyOperater::getPkId, ProxyOperater::getPoname,ProxyOperater::getPocode))); + } + } diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/OrderServiceImpl.java b/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/OrderServiceImpl.java index ea2e59f..99bf7e1 100644 --- a/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/OrderServiceImpl.java +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/OrderServiceImpl.java @@ -66,7 +66,7 @@ public class OrderServiceImpl implements OrderService { public Result walletPay(String orderNo, String wuid, String uname) { if (!wuid.equals(request.getHeader(HDConstant.WECHAT_SERVER_AUTHORIZATION_KEY))) { - log.error("当前参数的wuid:{}=== 请求中的wuid:{}", wuid, request.getHeader(HDConstant.WECHAT_SERVER_AUTHORIZATION_KEY)); + log.error("walletPay: 当前参数的wuid:{}=== 请求中的wuid:{}", wuid, request.getHeader(HDConstant.WECHAT_SERVER_AUTHORIZATION_KEY)); return new Result().error("账号错误"); } return cloudService.walletPay(orderNo, wuid, uname); diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/WechatUserServiceImpl.java b/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/WechatUserServiceImpl.java index 46e1bfc..0d1f78b 100644 --- a/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/WechatUserServiceImpl.java +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/WechatUserServiceImpl.java @@ -93,7 +93,7 @@ public class WechatUserServiceImpl implements WechatUserService { @Override public Result> listWallet(String wuid, HttpServletRequest request) { if (wuid == null || !wuid.equals(request.getHeader(HDConstant.WECHAT_SERVER_AUTHORIZATION_KEY))) { - log.error("当前参数的wuid:{}=== 请求中的wuid:{}", wuid, request.getHeader(HDConstant.WECHAT_SERVER_AUTHORIZATION_KEY)); + log.error("listWallet: 当前参数的wuid:{}=== 请求中的wuid:{}", wuid, request.getHeader(HDConstant.WECHAT_SERVER_AUTHORIZATION_KEY)); return new Result>().error("账号错误"); }