diff --git a/pom.xml b/pom.xml index 317a38dd..e1d95bd4 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 2.5.1 2020.0.3 2021.1 - 1.1.4 + 2.0.2 2.4.1 2.1.4 3.0.0 @@ -245,7 +245,8 @@ ruoyi-visual ruoyi-modules ruoyi-api - ruoyi-common + ruoyi-common + xhpc-modules pom diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/GetIpAndPort.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/GetIpAndPort.java new file mode 100644 index 00000000..72fff468 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/GetIpAndPort.java @@ -0,0 +1,60 @@ +package com.ruoyi.common.core.utils; + +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import java.net.Inet4Address; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.Enumeration; + + +public class GetIpAndPort { + + private static String ip; + + //获取ip + public static String getLocalIP() { + if (ip==null) { + String localIP = "127.0.0.1"; + try { + OK: + for (Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); interfaces.hasMoreElements(); ) { + NetworkInterface networkInterface = interfaces.nextElement(); + if (networkInterface.isLoopback() || networkInterface.isVirtual() || !networkInterface.isUp()) { + continue; + } + Enumeration addresses = networkInterface.getInetAddresses(); + while (addresses.hasMoreElements()) { + InetAddress address = addresses.nextElement(); + if (address instanceof Inet4Address) { + localIP = address.getHostAddress(); + break OK; + } + } + } + } catch (SocketException e) { + e.printStackTrace(); + } + ip = localIP; + } + return ip; + } + + //通过request获取ip + public static String getIp() { + return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getServerName(); + } + + //通过request获取端口 + public static String getLocalPort() { + return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getServerPort() + ""; + } + + + public static String getIpAndPort() { + return getLocalIP() + "#" + getLocalPort(); + } + +} diff --git a/xhpc-modules/pom.xml b/xhpc-modules/pom.xml new file mode 100644 index 00000000..3db504d5 --- /dev/null +++ b/xhpc-modules/pom.xml @@ -0,0 +1,22 @@ + + + + com.ruoyi + ruoyi + 3.0.0 + + 4.0.0 + + + xhpc-power-pole + + + xhpc-modules + pom + + + 充电业务模块 + + + diff --git a/xhpc-modules/xhpc-power-pole/pom.xml b/xhpc-modules/xhpc-power-pole/pom.xml new file mode 100644 index 00000000..66a555ef --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/pom.xml @@ -0,0 +1,97 @@ + + + + com.ruoyi + xhpc-modules + 3.0.0 + + 4.0.0 + + xhpc-power-pole + + + 充电桩服务 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-starter-web + + + + + mysql + mysql-connector-java + + + + + com.ruoyi + ruoyi-common-datasource + + + + + com.ruoyi + ruoyi-common-datascope + + + + org.quickserver + quickserver + 2.0.0 + + + + commons-pool + commons-pool + 1.6 + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/XhpcPPApplication.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/XhpcPPApplication.java new file mode 100644 index 00000000..1e66ce38 --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/XhpcPPApplication.java @@ -0,0 +1,29 @@ +package com.xhpc.pp; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; + +/** + * 充电桩服务 + * + * @author zz + */ +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class }) +public class XhpcPPApplication +{ + public static void main(String[] args) { + + SpringApplication.run(XhpcPPApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 充电桩服务模块启动成功 ლ(´ڡ`ლ)゙ \n" + + " .-------. ____ __ \n" + + " | _ _ \\ \\ \\ / / \n" + + " | ( ' ) | \\ _. / ' \n" + + " |(_ o _) / _( )_ .' \n" + + " | (_,_).' __ ___(_ o _)' \n" + + " | |\\ \\ | || |(_,_)' \n" + + " | | \\ `' /| `-' / \n" + + " | | \\ / \\ / \n" + + " ''-' `'-' `-..-' "); + } +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/config/EarlierBeanConf.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/config/EarlierBeanConf.java new file mode 100644 index 00000000..e30d774c --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/config/EarlierBeanConf.java @@ -0,0 +1,26 @@ +package com.xhpc.pp.config; + +import com.xhpc.pp.tx.logic.ServiceLogic; +import com.xhpc.pp.utils.SpringContextHolder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +public class EarlierBeanConf { + + final + SpringContextHolder springContextHolder; + + public EarlierBeanConf(SpringContextHolder springContextHolder) { + this.springContextHolder = springContextHolder; + } + + @Bean + public Map serviceLogics() { + + return new HashMap<>(); + } +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/controller/TestController.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/controller/TestController.java new file mode 100644 index 00000000..d1374af6 --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/controller/TestController.java @@ -0,0 +1,29 @@ +package com.xhpc.pp.controller; + +import com.alibaba.nacos.api.NacosFactory; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.naming.NamingService; +import com.alibaba.nacos.api.naming.pojo.Instance; +import com.ruoyi.common.core.utils.GetIpAndPort; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +public class TestController { + + @GetMapping("test") + public String test() throws NacosException { + + String serverIp = "127.0.0.1"; + int serverPort = 8848; + String serverAddr = serverIp + ":" + serverPort; + + NamingService namingService = NacosFactory.createNamingService(serverAddr); + List ppInstances = namingService.getAllInstances("xhpc-power-pole"); + String ipAndPort = GetIpAndPort.getIpAndPort(); + + return ipAndPort; + } +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/domain/ServiceField.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/domain/ServiceField.java new file mode 100644 index 00000000..f40a46cb --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/domain/ServiceField.java @@ -0,0 +1,94 @@ +package com.xhpc.pp.domain; + +public class ServiceField { + private Long id; + + private String serviceName; + + private String version; + + private String name; + + private String code; + + private Integer len; + + private Integer seq; + + private String remark; + + private String dataType; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getServiceName() { + return serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public Integer getLen() { + return len; + } + + public void setLen(Integer len) { + this.len = len; + } + + public Integer getSeq() { + return seq; + } + + public void setSeq(Integer seq) { + this.seq = seq; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getDataType() { + return dataType; + } + + public void setDataType(String dataType) { + this.dataType = dataType; + } + +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/mapper/ServiceFieldMapper.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/mapper/ServiceFieldMapper.java new file mode 100644 index 00000000..18139597 --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/mapper/ServiceFieldMapper.java @@ -0,0 +1,23 @@ +package com.xhpc.pp.mapper; + +import com.xhpc.pp.domain.ServiceField; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; +import java.util.Map; + +@Mapper +public interface ServiceFieldMapper { + + int deleteByPrimaryKey(Long id); + + int insert(ServiceField record); + + ServiceField selectByPrimaryKey(Long id); + + List query(Map query); + + int updateByPrimaryKey(ServiceField record); + + List> querySQL(Map query); +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/server/PPPBinaryHandler.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/server/PPPBinaryHandler.java new file mode 100644 index 00000000..d679aac8 --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/server/PPPBinaryHandler.java @@ -0,0 +1,169 @@ +package com.xhpc.pp.server; + +import com.xhpc.pp.domain.ServiceField; +import com.xhpc.pp.service.FieldService; +import com.xhpc.pp.service.ServiceMainLogic; +import com.xhpc.pp.tx.ServiceParameter; +import com.xhpc.pp.tx.ServiceResult; +import com.xhpc.pp.tx.TxException; +import com.xhpc.pp.utils.SpringContextHolder; +import com.xhpc.pp.utils.security.CRCCalculator; +import com.xhpc.pp.utils.security.HexUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.quickserver.net.server.ClientBinaryHandler; +import org.quickserver.net.server.ClientHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.*; + +public class PPPBinaryHandler implements ClientBinaryHandler { + + private static final Logger log = LoggerFactory.getLogger(PPPBinaryHandler.class); + + private static final String SERVICE_REGISTER = "1001"; + private static final String SERVICE_LOGOUT = "1002"; + + private static final String DATA_TYPE_STRING = "string"; + private static final String DATA_TYPE_INT = "int"; + private static final String DATA_TYPE_LONG = "long"; + // private static final String DATA_TYPE_HEX = "hex"; + + private ServiceMainLogic servicemainLogic; + + public PPPBinaryHandler() { + servicemainLogic = SpringContextHolder.getBean("ServiceMainLogic"); + } + + @Override + public void handleBinary(ClientHandler handler, byte[] data) throws IOException { + String dataStr = HexUtils.toHex(data); + String poleNo = PPPServer.getPoleNo(handler); + if (poleNo==null) { + log.info("received message <<<< {}, len[{}]", dataStr, data.length); + } else if (!dataStr.startsWith("00101005000100040000000000000000")) { + log.info("received pole [{}] message <<<< {}, len[{}]", poleNo, dataStr, data.length); + } + try { + // CRC校验和 + byte[] data2 = Arrays.copyOfRange(data, 2, data.length-2); + String crc1 = CRCCalculator.ModbusCRC(data2, data2.length); + // 检验长度 + if (data.length <= 2) { + log.error("input data invalid. " + data); + return; + } + int len = HexUtils.toInteger(data, 1, 2); + if (data.length < len) { + log.error("input data length. " + data.length); + return; + } + + // 处理粘包 + List dataList = parseDataList(data); + + for (byte[] d : dataList) { + process(handler, d); + } + + } catch (TxException e) { + log.error(e.getMessage(), e); + } + + } + + // + private void process(ClientHandler handler, byte[] data) throws TxException, IOException { + + String serviceName = HexUtils.toHex(data, 5, 6); + String version = PPPServer.getVersion(handler.getName()); + String poleNo = PPPServer.getPoleNo(handler); + Map req = analysis(data, serviceName, version); +// log.info("pole [{}] status: |{}|", StringUtils.isNotBlank(poleNo) ? poleNo : "null", req.get("status") != null ? MQPole.PoleStatus.toString((Long) req.get("status")) : "N/A"); + ServiceParameter sp = new ServiceParameter(serviceName, poleNo, req); + +// try { +// log.info("serviceLogic: |{}|", servicemainLogic.getServiceLogic(serviceName).getClass().getName()); +// } catch (Exception e) { +// e.printStackTrace(); +// } + //service 主逻辑中解析参数为对应的服务 + ServiceResult result = servicemainLogic.process(sp); + + // 结果不为空的直接回写 + if (result.getBinary() != null) { + log.info("server send msg >>>> [{}] |{}|", poleNo, HexUtils.toHex(result.getBinary())); + handler.sendClientBinary(result.getBinary()); + } + + // 注册成功后需要将当前handler与设备关联 + if (SERVICE_REGISTER.equals(serviceName)) { + PPPServer.putHandler((String) req.get("poleNo"), handler); + PPPServer.putVersion(handler.getName(), (String) req.get("version")); + } + + // 注销后将桩号对应关系解除 + if (SERVICE_LOGOUT.equals(serviceName)) { + PPPServer.removeHandler(poleNo); + } + + } + + private List parseDataList(byte[] data) { + List dataList = new ArrayList<>(); + + int len = HexUtils.toInteger(data, 1, 2); + int start = 0; + while (start < data.length) { + if (len > data.length) { + log.error("input data[{}] len[{}]", data, data.length); + break; + } + dataList.add(ArrayUtils.subarray(data, start, len)); + start = len; + len = len + HexUtils.toInteger(data, start, start + 2); + } + + if (dataList.size() > 1) { + log.info("detection stick package size[{}]", dataList.size()); + } + + return dataList; + } + + private Map analysis(byte[] data, String service, String ver) throws TxException { + + List fieldList = FieldService.fieldList(ver, service); + if (fieldList == null || fieldList.isEmpty()) + throw TxException.INNER_ERROR("field mapper not found"); + + Map result = new HashMap(); + int pos = 4; + // TODO 终止充电详情原因 + for (ServiceField field : fieldList) { + // 判断长度 某些报文不同版本长度不同 + if (pos >= data.length || pos + field.getLen() > data.length) + break; + + switch (field.getDataType()) { + case DATA_TYPE_STRING: + result.put(field.getCode(), HexUtils.toString(data, pos, pos + field.getLen())); + break; + case DATA_TYPE_INT: + result.put(field.getCode(), HexUtils.byte2int(ArrayUtils.subarray(data, pos, pos + field.getLen()))); + break; + case DATA_TYPE_LONG: + result.put(field.getCode(), HexUtils.byte2Long(ArrayUtils.subarray(data, pos, pos + field.getLen()))); + break; + default: + result.put(field.getCode(), HexUtils.toHex(data, pos, pos + field.getLen())); + } + pos += field.getLen(); + } + // 原始报文 + result.put("hex", HexUtils.toHex(data)); + return result; + } + +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/server/PPPCommandHandler.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/server/PPPCommandHandler.java new file mode 100644 index 00000000..6234612c --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/server/PPPCommandHandler.java @@ -0,0 +1,26 @@ +package com.xhpc.pp.server; + +import org.quickserver.net.server.ClientCommandHandler; +import org.quickserver.net.server.ClientHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Repository; + +import java.io.IOException; +import java.net.SocketTimeoutException; + +@Repository +public class PPPCommandHandler implements ClientCommandHandler { + + private static final Logger log = LoggerFactory.getLogger(PPPCommandHandler.class); + + public PPPCommandHandler() { + } + + @Override + public void handleCommand(ClientHandler handler, String appData) throws SocketTimeoutException, IOException { + log.info("handleCommand <====" + appData); + + } + +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/server/PPPEventHandler.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/server/PPPEventHandler.java new file mode 100644 index 00000000..284f72ec --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/server/PPPEventHandler.java @@ -0,0 +1,43 @@ +package com.xhpc.pp.server; + +import org.quickserver.net.server.ClientEventHandler; +import org.quickserver.net.server.ClientHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.net.SocketTimeoutException; + +@Lazy(false) +@Component +public class PPPEventHandler implements ClientEventHandler { + private static final Logger log = LoggerFactory.getLogger(PPPEventHandler.class); + + public PPPEventHandler() { + } + + @Override + public void gotConnected(ClientHandler handler) throws SocketTimeoutException, IOException { + log.info("got connected -> " + handler.getName() + " <-" + handler.getSocket().getRemoteSocketAddress().toString()); + // TODO 连接时获取终端唯一标示,断开连接时根据唯一标示绑定的桩号更新桩状态 + // 请求注册 + } + + @Override + public void lostConnection(ClientHandler handler) { + String poleNo = PPPServer.getPoleNo(handler); + log.info("lost connection -> [{}] {} <- {}", + poleNo, handler.getName(), handler.getSocket().getRemoteSocketAddress().toString()); + if (poleNo != null) { + PPPServer.removeHandler(poleNo); + } + } + + @Override + public void closingConnection(ClientHandler handler) throws IOException { + log.info("closing connection -> " + handler.getName() + " <-"); + } + +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/server/PPPServer.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/server/PPPServer.java new file mode 100644 index 00000000..f3329e92 --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/server/PPPServer.java @@ -0,0 +1,132 @@ +package com.xhpc.pp.server; + +import com.xhpc.pp.utils.security.HexUtils; +import org.quickserver.net.server.ClientHandler; +import org.quickserver.net.server.DataMode; +import org.quickserver.net.server.DataType; +import org.quickserver.net.server.QuickServer; +import org.quickserver.util.xmlreader.DefaultDataMode; +import org.quickserver.util.xmlreader.QuickServerConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + + +/** + * 充电桩服务器 + */ +@Lazy(false) +@Component +public class PPPServer { + + public static final String default_version = "0A"; + private static final Logger log = LoggerFactory.getLogger(PPPServer.class); + private static Map handlerMapper = new HashMap<>(); + private static Map versionMapper = new HashMap<>(); + private static Map poleMapper = new HashMap<>(); + private QuickServer server; + + @Autowired + public PPPServer(@Value("${ppsvc.server}") String host, @Value("${ppsvc.port}") int port) { + try { + QuickServerConfig config; + server = new QuickServer(); + server.setDefaultDataMode(DataMode.BINARY, DataType.IN); + config = new QuickServerConfig(); + DefaultDataMode mode = new DefaultDataMode(); + mode.setDataMode(DataMode.BINARY, DataType.IN); + mode.setDataMode(DataMode.BINARY, DataType.OUT); + config.setDefaultDataMode(mode); + config.setClientEventHandler(PPPEventHandler.class.getName()); + config.setClientCommandHandler(PPPCommandHandler.class.getName()); + config.setClientBinaryHandler(PPPBinaryHandler.class.getName()); + config.getServerMode().setBlocking(true); + config.setPort(port); + config.setBindAddr(host); + config.setTimeout(60 * 1000 * 5); + server.initService(config); + server.startServer(); + log.info("pp svc started at {}:{} ....", host, port); + } catch (Exception e) { + e.printStackTrace(); + log.error("pp svc start error: " + e); + } + } + + public static void putHandler(String poleNo, ClientHandler handler) { + poleNo = HexUtils.toIntString(poleNo, 4); + handlerMapper.put(poleNo, handler); + poleMapper.put(handler.getName(), poleNo); + } + + public static void removeHandler(String poleNo) { + ClientHandler handler = handlerMapper.remove(poleNo); + if (handler != null) { + log.info("remove hanlder [{}], poleNo[{}]", handler.getName(), poleNo); + poleMapper.remove(handler.getName()); + versionMapper.remove(handler.getName()); + } + } + + public static void sendClientMsg(String poleNo, byte[] msg) { + //TODO 采集服务器充电桩 协议0x100A + if (!HexUtils.toHex(msg).startsWith("00101005")) { + log.info("server send msg >>>> [{}] |{}|", poleNo, HexUtils.toHex(msg)); + } + if (poleNo.length() < 16) { + poleNo = "0000000000000000" + poleNo; + poleNo = poleNo.substring(poleNo.length() - 16); + } + + ClientHandler handler = handlerMapper.get(poleNo); + + if (handler == null || !handler.isOpen()) { + log.error("send message failed. [{}] connection lost", poleNo); + removeHandler(poleNo); + return; + } + + try { + handler.sendClientBinary(msg); + } catch (IOException e) { + log.error("send message failed. " + e.getMessage(), e); + } + + return; + } + + public static void putVersion(String handler, String version) { + versionMapper.put(handler, version); + } + + public static String getVersion(String handler) { + String version = versionMapper.get(handler); + if (version == null) + version =default_version; + return version; + } + + public static ClientHandler getHandler(String poleNo) { + return handlerMapper.get(poleNo); + } + + public static String getPoleNo(ClientHandler handler) { + return poleMapper.get(handler.getName()); + } + + public void shutDown() { + try { + if (server != null) + server.stopServer(); + } catch (Exception e) { + log.error("Server could not stop: " + e); + } + } +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/service/FieldService.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/service/FieldService.java new file mode 100644 index 00000000..28bee365 --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/service/FieldService.java @@ -0,0 +1,74 @@ +package com.xhpc.pp.service; + +import com.xhpc.pp.domain.ServiceField; +import com.xhpc.pp.mapper.ServiceFieldMapper; +import com.xhpc.pp.server.PPPServer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +@Lazy +@Component +public class FieldService { + + // 版本->协议字段表 + private static Map>> versionMapFields; + private static ServiceFieldMapper fieldMapper; + + @Autowired + public FieldService(ServiceFieldMapper fieldMapper) { + FieldService.fieldMapper = fieldMapper; + FieldService.refreshCache(); + } + + public static void refreshCache() { + versionMapFields.clear(); + init(); + } + + public static void init() { + + versionMapFields = new HashMap<>(); + List list = fieldMapper.query(null); + for (ServiceField field : list) { + String version = field.getVersion(); + String service = field.getServiceName(); + Map> versionMap = versionMapFields.computeIfAbsent(version, k -> new HashMap<>()); + List fields = versionMap.computeIfAbsent(service, k -> new ArrayList<>()); + fields.add(field); + } + } + + public static List fieldList(String version, String service) { + Map> vermap = versionMapFields.get(version); + + // 充电桩上送的版本未维护,使用默认版本 + if (vermap == null) + vermap = versionMapFields.get(PPPServer.default_version); + + if (vermap == null) + return null; + + // 上送的版本当前接口未维护,使用默认版本 + List fieldList = vermap.get(service); + if (fieldList == null || fieldList.isEmpty()) { + vermap = versionMapFields.get(PPPServer.default_version); + fieldList = vermap.get(service); + } + + return fieldList; + } + + public List> querySQL(String sql) { + Map query = new HashMap<>(); + query.put("sql", sql); + return fieldMapper.querySQL(query); + } + +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/service/ServiceMainLogic.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/service/ServiceMainLogic.java new file mode 100644 index 00000000..1607015c --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/service/ServiceMainLogic.java @@ -0,0 +1,117 @@ +package com.xhpc.pp.service; + +import com.xhpc.pp.tx.ServiceParameter; +import com.xhpc.pp.tx.ServiceResult; +import com.xhpc.pp.tx.TxException; +import com.xhpc.pp.tx.logic.ServiceLogic; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Map; + +@Component("ServiceMainLogic") +public class ServiceMainLogic { + protected Log log = LogFactory.getLog(getClass()); + + // 结构:Map + @Resource + private Map serviceLogics; + + public ServiceResult process(ServiceParameter param) { + ServiceResult result; + try { + + // 调用具体业务逻辑的创建逻辑 + ServiceLogic logic = getServiceLogic(param.getServiceName()); + // 开启事务 + startTransaction(param); + + // 开始服务 + result = logic.service(param); + + // 提交事务 + commitTransaction(param); + } catch (TxException e) { + log.error("服务请求失败:错误码[" + e.getReturnCode() + "],错误:{" + e.getMessage() + "}"); + + // 记录错误日志 +// saveErrorLog(param, e); + + try { + // 回滚事务 + terminateTransaction(param); + result = new ServiceResult(e.getReturnCode(), e.getMessage()); + } catch (Exception e1) { + result = new ServiceResult(null, e1.getMessage()); + } + } catch (Exception e) { + e.printStackTrace(); + result = new ServiceResult(null, e.getMessage()); + } + + // 处理结果 + return result; + } + +// private void saveErrorLog(ServiceParameter param, TxException e) { +// Map params = param.getParameters(); +// String customerId = params.get("customerId"); +// if (customerId == null || e.getMessage() == null) +// return; +// +// SysLog log = new SysLog(); +// log.setSystemlogid(sequenceService.nextLogId()); +// log.setCustomerid(Integer.parseInt(customerId)); +// log.setLogtime(new Date()); +// log.setOperationdescription(e.getMessage()); +// log.setCreatetime(new Date()); +// log.setUpdatetime(new Date()); +// +// logService.save(log); +// } + + /** + * 创建事务对象,设置事务状态(已开始) 记录日志 + * + * @param param + */ + private void startTransaction(ServiceParameter param) throws Exception { + + // + } + + /** + * 设置事务状态(已完成),保存到数据库 + * + * @param param + */ + private void commitTransaction(ServiceParameter param) throws Exception { + + } + + /** + * 设置事务状态(已失败),保存到数据库 + * + * @param param + */ + private void terminateTransaction(ServiceParameter param) throws Exception { + + } + + public ServiceLogic getServiceLogic(String serviceName) throws Exception { + if (serviceName == null || "".equals(serviceName)) + throw new TxException("0101", "请求参数错误"); + + log.debug("获取ServiceCommandLogic,serviceName:" + serviceName); + + ServiceLogic logic = serviceLogics.get(serviceName); + + if (logic == null) + throw new TxException("0102", "请求的业务类型错误," + serviceName); + + return logic; + } + +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/tx/ServiceController.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/tx/ServiceController.java new file mode 100644 index 00000000..442cbc17 --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/tx/ServiceController.java @@ -0,0 +1,43 @@ +package com.xhpc.pp.tx; + +import com.xhpc.pp.service.ServiceMainLogic; +import com.xhpc.pp.utils.JSONUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.io.IOException; +import java.util.Map; + + +@Controller +@RequestMapping +public class ServiceController { + + private static final String SESSIONID = "poleNo"; + private static final String SERVICE_NAME = "serviceName"; + + @Autowired + private ServiceMainLogic servicemainLogic; + + @RequestMapping(value = "/api") + @ResponseBody + public String index(@RequestBody Map req) throws IOException { + String poleNo = (String) req.get(SESSIONID); + String serviceName = (String) req.get(SERVICE_NAME); + + ServiceParameter serviceParameter = new ServiceParameter(serviceName, poleNo, req); + ServiceResult result = servicemainLogic.process(serviceParameter); + + if (result.getJson() != null) { + String body = JSONUtil.toJSONString(result.getJson()); + return body; + } else { + return ""; + } + + } + +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/tx/ServiceParameter.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/tx/ServiceParameter.java new file mode 100644 index 00000000..db246a57 --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/tx/ServiceParameter.java @@ -0,0 +1,56 @@ +package com.xhpc.pp.tx; + +import java.io.Serializable; +import java.util.Map; + +public class ServiceParameter implements Serializable { + + private static final long serialVersionUID = 1L; + + private String serviceName; + + private String poleNo; + + private String version; + + private Map parameters; + + public ServiceParameter(String serviceName, String poleNo, Map parameters) { + this.serviceName = serviceName; + this.parameters = parameters; + this.poleNo = poleNo; + } + + public String getServiceName() { + return serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public Map getParameters() { + return parameters; + } + + public void setParameters(Map parameters) { + this.parameters = parameters; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getPoleNo() { + return poleNo; + } + + public void setPoleNo(String poleNo) { + this.poleNo = poleNo; + } + +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/tx/ServiceResult.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/tx/ServiceResult.java new file mode 100644 index 00000000..25170584 --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/tx/ServiceResult.java @@ -0,0 +1,52 @@ +package com.xhpc.pp.tx; + +import java.util.HashMap; +import java.util.Map; + +public class ServiceResult { + + public static final String RESULT_OK = "0000"; + + private byte[] binary; + + private Object json; + + public ServiceResult(String code, String body) { + Map map = new HashMap(); + String messageCode = "0101"; + if (code != null && code.trim().length() > 0) { + messageCode = code; + } + map.put("ErrCode", messageCode); + map.put("ErrMsg", body); + this.json = map; + } + + public ServiceResult(Map json) { + this.json = json; + } + + public ServiceResult(Object json) { + this.json = json; + } + + public ServiceResult() { + } + + public ServiceResult(byte[] binary) { + this.binary = binary; + } + + public Object getJson() { + return json; + } + + public void setJson(Map json) { + this.json = json; + } + + public byte[] getBinary() { + return binary; + } + +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/tx/TxException.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/tx/TxException.java new file mode 100644 index 00000000..8f72772a --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/tx/TxException.java @@ -0,0 +1,57 @@ +package com.xhpc.pp.tx; + +public class TxException extends Exception { + /** + * 缺少参数 + */ + public static final TxException INVALID_PARAMETER = new TxException("1101", "缺少必要参数"); + public static final TxException REGISTER_FAIL = new TxException("0103", "注册失败"); + public static final TxException LOGIN_FAIL = new TxException("0104", "用户名或密码错误"); + public static final TxException LOGIN_FAIL_NON_REG = new TxException("0105", "非APP注册用户,请先注册后再登录"); + public static final TxException LOGIN_FAIL_FREEZE = new TxException("0106", "用户处于冻结状态,暂不可用,请联系系统管理人员"); + public static final TxException LOGIN_FAIL_SMS_CODE = new TxException("0107", "短信验证码不正确"); + public static final TxException USER_NO_EXIST = new TxException("0108", "用户不存在"); + public static final TxException SESSION_INVALID = new TxException("0001", "用户未登录或过期,请重新登录"); + public static final TxException USER_BALANCE_LOCKED = new TxException("3001", "余额锁定,当前有未结束的充电操作。"); + public static final TxException NO_DATA = new TxException("0002", "无数据"); + private static final long serialVersionUID = 1L; + private String returnCode; + + public TxException(String rtnCode, Throwable reason) { + super(rtnCode, reason); + this.returnCode = rtnCode; + } + + public TxException(String rtnCode, String msg) { + super(msg); + this.returnCode = rtnCode; + } + + public TxException(String rtnCode) { + this.returnCode = rtnCode; + } + + public static TxException SERVICE_CALL_FIAL(String code, String error) { + + return new TxException(code, error); + } + + /** + * 参数错误 + */ + public static TxException PARAMETER_INVALID(String error) { + return new TxException("1101", error); + } + + /** + * 内部错误 + */ + public static TxException INNER_ERROR(String msg) { + return new TxException("1111", msg); + } + + public String getReturnCode() { + return returnCode; + } + +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/tx/logic/ServiceLogic.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/tx/logic/ServiceLogic.java new file mode 100644 index 00000000..04bf96ab --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/tx/logic/ServiceLogic.java @@ -0,0 +1,15 @@ +package com.xhpc.pp.tx.logic; + +import com.xhpc.pp.tx.ServiceParameter; +import com.xhpc.pp.tx.ServiceResult; + +public interface ServiceLogic { + + /** + * 实现具体服务 + * + * @return + */ + ServiceResult service(ServiceParameter param) throws Exception; + +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/FileUploadUtils.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/FileUploadUtils.java new file mode 100644 index 00000000..cafc8422 --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/FileUploadUtils.java @@ -0,0 +1,197 @@ +package com.xhpc.pp.utils; + +import com.ruoyi.common.core.exception.file.FileNameLengthLimitExceededException; +import com.ruoyi.common.core.exception.file.FileSizeLimitExceededException; +import com.ruoyi.common.core.exception.file.InvalidExtensionException; +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.IdUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.file.MimeTypeUtils; +import org.apache.commons.io.FilenameUtils; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; + +/** + * 文件上传工具类 + * + * @author ruoyi + */ +public class FileUploadUtils +{ + /** + * 默认大小 50M + */ + public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024; + + /** + * 默认的文件名最大长度 100 + */ + public static final int DEFAULT_FILE_NAME_LENGTH = 100; + + /** + * 根据文件路径上传 + * + * @param baseDir 相对应用的基目录 + * @param file 上传的文件 + * @return 文件名称 + * @throws IOException + */ + public static final String upload(String baseDir, MultipartFile file) throws IOException + { + try + { + return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + } + catch (Exception e) + { + throw new IOException(e.getMessage(), e); + } + } + + /** + * 文件上传 + * + * @param baseDir 相对应用的基目录 + * @param file 上传的文件 + * @param allowedExtension 上传文件类型 + * @return 返回上传成功的文件名 + * @throws FileSizeLimitExceededException 如果超出最大大小 + * @throws FileNameLengthLimitExceededException 文件名太长 + * @throws IOException 比如读写文件出错时 + * @throws InvalidExtensionException 文件校验异常 + */ + public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension) + throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException, + InvalidExtensionException + { + int fileNamelength = file.getOriginalFilename().length(); + if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) + { + throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH); + } + + assertAllowed(file, allowedExtension); + + String fileName = extractFilename(file); + + File desc = getAbsoluteFile(baseDir, fileName); + file.transferTo(desc); + String pathFileName = getPathFileName(fileName); + return pathFileName; + } + + /** + * 编码文件名 + */ + public static final String extractFilename(MultipartFile file) + { + String fileName = file.getOriginalFilename(); + String extension = getExtension(file); + fileName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension; + return fileName; + } + + private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException + { + File desc = new File(uploadDir + File.separator + fileName); + + if (!desc.exists()) + { + if (!desc.getParentFile().exists()) + { + desc.getParentFile().mkdirs(); + } + } + return desc.isAbsolute() ? desc : desc.getAbsoluteFile(); + } + + private static final String getPathFileName(String fileName) throws IOException + { + String pathFileName = "/" + fileName; + return pathFileName; + } + + /** + * 文件大小校验 + * + * @param file 上传的文件 + * @throws FileSizeLimitExceededException 如果超出最大大小 + * @throws InvalidExtensionException 文件校验异常 + */ + public static final void assertAllowed(MultipartFile file, String[] allowedExtension) + throws FileSizeLimitExceededException, InvalidExtensionException + { + long size = file.getSize(); + if (DEFAULT_MAX_SIZE != -1 && size > DEFAULT_MAX_SIZE) + { + throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024); + } + + String fileName = file.getOriginalFilename(); + String extension = getExtension(file); + if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)) + { + if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION) + { + throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION) + { + throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION) + { + throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION) + { + throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension, + fileName); + } + else + { + throw new InvalidExtensionException(allowedExtension, extension, fileName); + } + } + } + + /** + * 判断MIME类型是否是允许的MIME类型 + * + * @param extension 上传文件类型 + * @param allowedExtension 允许上传文件类型 + * @return true/false + */ + public static final boolean isAllowedExtension(String extension, String[] allowedExtension) + { + for (String str : allowedExtension) + { + if (str.equalsIgnoreCase(extension)) + { + return true; + } + } + return false; + } + + /** + * 获取文件名的后缀 + * + * @param file 表单文件 + * @return 后缀名 + */ + public static final String getExtension(MultipartFile file) + { + String extension = FilenameUtils.getExtension(file.getOriginalFilename()); + if (StringUtils.isEmpty(extension)) + { + extension = MimeTypeUtils.getExtension(file.getContentType()); + } + return extension; + } +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/JSONUtil.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/JSONUtil.java new file mode 100644 index 00000000..9f596bba --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/JSONUtil.java @@ -0,0 +1,135 @@ +package com.xhpc.pp.utils; + +import com.alibaba.fastjson.JSON; +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.net.MalformedURLException; +import java.net.URL; + +public class JSONUtil { + + private static ObjectMapper mapper = new ObjectMapper(); + + public static String toJSONString(Object o) throws JsonProcessingException { + /*return JSONObject.toJSONString(o);*/ + return mapper.writeValueAsString(o); + } + + public static T readValue(String url, Class clz) { + try { + URL u = new URL(url); + return mapper.readValue(u, clz); + + } catch (JsonParseException e) { + e.printStackTrace(); + } catch (JsonMappingException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + public static T readValue(String url, String params, Class clz) { + try { + String param = "?params=" + params; + URL u = new URL(url + param); + return mapper.readValue(u, clz); + + } catch (JsonParseException e) { + e.printStackTrace(); + } catch (JsonMappingException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + public static JavaType getCollectionType(Class collectionClass, Class... elementClasses) { + return mapper.getTypeFactory().constructParametricType(collectionClass, elementClasses); + } + + public static void writeTo(PrintWriter writer, Object value) { + try { + mapper.writeValue(writer, value); + } catch (JsonGenerationException e) { + e.printStackTrace(); + } catch (JsonMappingException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + public static T readParams(String params, Class clz) { + try { + return mapper.readValue(params, clz); + } catch (JsonParseException e) { + e.printStackTrace(); + } catch (JsonMappingException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + public static T readParams(String params, JavaType collectionType) { + try { + return mapper.readValue(params, collectionType); + } catch (JsonParseException e) { + e.printStackTrace(); + } catch (JsonMappingException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + + public static T readValue(InputStream content, Class type) throws Exception { + return mapper.readValue(content, type); + } + + public static T readValue(String url, JavaType type) { + try { + return mapper.readValue(new URL(url), type); + } catch (JsonParseException e) { + e.printStackTrace(); + } catch (JsonMappingException e) { + e.printStackTrace(); + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 将一个对象转换成目标对象 + * + * @param src + * @param dest + * @return + */ + public static T copyProperties(Object src, Class dest) throws Exception { + return JSON.parseObject(JSON.toJSONString(src), dest); + } + + public static T copyProperties(Object src, JavaType type) throws Exception { + return JSON.parseObject(JSON.toJSONString(src), type); + } + +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/SpringContextHolder.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/SpringContextHolder.java new file mode 100644 index 00000000..3aca1536 --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/SpringContextHolder.java @@ -0,0 +1,83 @@ +package com.xhpc.pp.utils; + +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; + + +/** + * 以静态变量保存Spring ApplicationContext, 可在任何代码任何地方任何时候取出ApplicaitonContext. + */ +@Service +@Lazy(false) +public class SpringContextHolder implements ApplicationContextAware, DisposableBean { + + private static ApplicationContext applicationContext = null; + + private static Logger logger = LoggerFactory.getLogger(SpringContextHolder.class); + + /** + * 取得存储在静态变量中的ApplicationContext. + */ + public static ApplicationContext getApplicationContext() { + assertContextInjected(); + return applicationContext; + } + + /** + * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. + */ + @SuppressWarnings("unchecked") + public static T getBean(String name) { + assertContextInjected(); + return (T) applicationContext.getBean(name); + } + + /** + * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. + */ + public static T getBean(Class requiredType) { + assertContextInjected(); + return applicationContext.getBean(requiredType); + } + + /** + * 清除SpringContextHolder中的ApplicationContext为Null. + */ + public static void clearHolder() { + if (logger.isDebugEnabled()){ + logger.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext); + } + applicationContext = null; + } + + + /** + * 实现ApplicationContextAware接口, 注入Context到静态变量中. + */ + @Override + public void setApplicationContext(ApplicationContext applicationContext) { + SpringContextHolder.applicationContext = applicationContext; + } + + + /** + * 实现DisposableBean接口, 在Context关闭时清理静态变量. + */ + @Override + public void destroy() throws Exception { + SpringContextHolder.clearHolder(); + } + + /** + * 检查ApplicationContext不为空. + */ + private static void assertContextInjected() { + Validate.validState(applicationContext != null, "applicaitonContext属性未注入, 请在applicationContext.xml中定义SpringContextHolder."); + } +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/security/Base64Utils.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/security/Base64Utils.java new file mode 100644 index 00000000..a832c907 --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/security/Base64Utils.java @@ -0,0 +1,148 @@ +package com.xhpc.pp.utils.security; + +import com.ruoyi.common.core.utils.sign.Base64; + +import java.io.*; + + +/** */ + +/** + *

+ * BASE64编码解码工具包 + *

+ *

+ * 依赖javabase64-1.3.1.jar + *

+ * + * @author IceWee + * @version 1.0 + * @date 2012-5-19 + */ +public class Base64Utils { + + /** */ + /** + * 文件读取缓冲区大小 + */ + private static final int CACHE_SIZE = 1024; + + /** */ + /** + *

+ * BASE64字符串解码为二进制数据 + *

+ * + * @param base64 + * @return + * @throws Exception + */ + public static byte[] decode(String base64) throws Exception { + return Base64.decode(base64); + } + + /** */ + /** + *

+ * 二进制数据编码为BASE64字符串 + *

+ * + * @param bytes + * @return + * @throws Exception + */ + public static String encode(byte[] bytes) throws Exception { + return new String(Base64.encode(bytes)); + } + + /** */ + /** + *

+ * 将文件编码为BASE64字符串 + *

+ *

+ * 大文件慎用,可能会导致内存溢出 + *

+ * + * @param filePath 文件绝对路径 + * @return + * @throws Exception + */ + public static String encodeFile(String filePath) throws Exception { + byte[] bytes = fileToByte(filePath); + return encode(bytes); + } + + /** */ + /** + *

+ * BASE64字符串转回文件 + *

+ * + * @param filePath 文件绝对路径 + * @param base64 编码字符串 + * @throws Exception + */ + public static void decodeToFile(String filePath, String base64) throws Exception { + byte[] bytes = decode(base64); + byteArrayToFile(bytes, filePath); + } + + /** */ + /** + *

+ * 文件转换为二进制数组 + *

+ * + * @param filePath 文件路径 + * @return + * @throws Exception + */ + public static byte[] fileToByte(String filePath) throws Exception { + byte[] data = new byte[0]; + File file = new File(filePath); + if (file.exists()) { + FileInputStream in = new FileInputStream(file); + ByteArrayOutputStream out = new ByteArrayOutputStream(2048); + byte[] cache = new byte[CACHE_SIZE]; + int nRead = 0; + while ((nRead = in.read(cache)) != -1) { + out.write(cache, 0, nRead); + out.flush(); + } + out.close(); + in.close(); + data = out.toByteArray(); + } + return data; + } + + /** */ + /** + *

+ * 二进制数据写文件 + *

+ * + * @param bytes 二进制数据 + * @param filePath 文件生成目录 + */ + public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception { + InputStream in = new ByteArrayInputStream(bytes); + File destFile = new File(filePath); + if (!destFile.getParentFile().exists()) { + destFile.getParentFile().mkdirs(); + } + destFile.createNewFile(); + OutputStream out = new FileOutputStream(destFile); + byte[] cache = new byte[CACHE_SIZE]; + int nRead = 0; + while ((nRead = in.read(cache)) != -1) { + out.write(cache, 0, nRead); + out.flush(); + } + out.close(); + in.close(); + } + + +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/security/CRCCalculator.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/security/CRCCalculator.java new file mode 100644 index 00000000..e384c9f8 --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/security/CRCCalculator.java @@ -0,0 +1,76 @@ +package com.xhpc.pp.utils.security; + +public class CRCCalculator { + + public static String ModbusCRC(byte[] pData, int len) { + int crc = 0xFFFF; + for (int pos = 0; pos < len; pos++) { + crc ^= (int)pData[pos] & 0xFF; // XOR byte into least sig. byte of crc + for (int i = 8; i != 0; i--) { // Loop over each bit + if ((crc & 0x0001) != 0) { // If the LSB is set + crc >>= 1; // Shift right and XOR 0xA001 + crc ^= 0xA001; + } + else // Else LSB is not set + crc >>= 1; // Just shift right + } + } + // Revert hi-lo + crc = ((crc & 0xFF00) >> 8) | ((crc & 0x00FF) << 8); + return String.format("%04X", crc); + } + + public static int byteArrayToInt(byte[] b) { + return b[3] & 0xFF | + (b[2] & 0xFF) << 8 | + (b[1] & 0xFF) << 16 | + (b[0] & 0xFF) << 24; + } + + public static byte[] intToByteArray(int a) { + return new byte[]{ + (byte) ((a >> 24) & 0xFF), + (byte) ((a >> 16) & 0xFF), + (byte) ((a >> 8) & 0xFF), + (byte) (a & 0xFF) + }; + } + + private static byte[] hi = { + (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, + (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, + (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, + (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, + (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, + (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, + (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, + (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, + (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, + (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, + (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, + (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, + (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, + (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, + (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, + (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40 + }; + + private static byte lo[] = { + (byte) 0x00, (byte) 0xC0, (byte) 0xC1, (byte) 0x01, (byte) 0xC3, (byte) 0x03, (byte) 0x02, (byte) 0xC2, (byte) 0xC6, (byte) 0x06, (byte) 0x07, (byte) 0xC7, (byte) 0x05, (byte) 0xC5, (byte) 0xC4, (byte) 0x04, + (byte) 0xCC, (byte) 0x0C, (byte) 0x0D, (byte) 0xCD, (byte) 0x0F, (byte) 0xCF, (byte) 0xCE, (byte) 0x0E, (byte) 0x0A, (byte) 0xCA, (byte) 0xCB, (byte) 0x0B, (byte) 0xC9, (byte) 0x09, (byte) 0x08, (byte) 0xC8, + (byte) 0xD8, (byte) 0x18, (byte) 0x19, (byte) 0xD9, (byte) 0x1B, (byte) 0xDB, (byte) 0xDA, (byte) 0x1A, (byte) 0x1E, (byte) 0xDE, (byte) 0xDF, (byte) 0x1F, (byte) 0xDD, (byte) 0x1D, (byte) 0x1C, (byte) 0xDC, + (byte) 0x14, (byte) 0xD4, (byte) 0xD5, (byte) 0x15, (byte) 0xD7, (byte) 0x17, (byte) 0x16, (byte) 0xD6, (byte) 0xD2, (byte) 0x12, (byte) 0x13, (byte) 0xD3, (byte) 0x11, (byte) 0xD1, (byte) 0xD0, (byte) 0x10, + (byte) 0xF0, (byte) 0x30, (byte) 0x31, (byte) 0xF1, (byte) 0x33, (byte) 0xF3, (byte) 0xF2, (byte) 0x32, (byte) 0x36, (byte) 0xF6, (byte) 0xF7, (byte) 0x37, (byte) 0xF5, (byte) 0x35, (byte) 0x34, (byte) 0xF4, + (byte) 0x3C, (byte) 0xFC, (byte) 0xFD, (byte) 0x3D, (byte) 0xFF, (byte) 0x3F, (byte) 0x3E, (byte) 0xFE, (byte) 0xFA, (byte) 0x3A, (byte) 0x3B, (byte) 0xFB, (byte) 0x39, (byte) 0xF9, (byte) 0xF8, (byte) 0x38, + (byte) 0x28, (byte) 0xE8, (byte) 0xE9, (byte) 0x29, (byte) 0xEB, (byte) 0x2B, (byte) 0x2A, (byte) 0xEA, (byte) 0xEE, (byte) 0x2E, (byte) 0x2F, (byte) 0xEF, (byte) 0x2D, (byte) 0xED, (byte) 0xEC, (byte) 0x2C, + (byte) 0xE4, (byte) 0x24, (byte) 0x25, (byte) 0xE5, (byte) 0x27, (byte) 0xE7, (byte) 0xE6, (byte) 0x26, (byte) 0x22, (byte) 0xE2, (byte) 0xE3, (byte) 0x23, (byte) 0xE1, (byte) 0x21, (byte) 0x20, (byte) 0xE0, + (byte) 0xA0, (byte) 0x60, (byte) 0x61, (byte) 0xA1, (byte) 0x63, (byte) 0xA3, (byte) 0xA2, (byte) 0x62, (byte) 0x66, (byte) 0xA6, (byte) 0xA7, (byte) 0x67, (byte) 0xA5, (byte) 0x65, (byte) 0x64, (byte) 0xA4, + (byte) 0x6C, (byte) 0xAC, (byte) 0xAD, (byte) 0x6D, (byte) 0xAF, (byte) 0x6F, (byte) 0x6E, (byte) 0xAE, (byte) 0xAA, (byte) 0x6A, (byte) 0x6B, (byte) 0xAB, (byte) 0x69, (byte) 0xA9, (byte) 0xA8, (byte) 0x68, + (byte) 0x78, (byte) 0xB8, (byte) 0xB9, (byte) 0x79, (byte) 0xBB, (byte) 0x7B, (byte) 0x7A, (byte) 0xBA, (byte) 0xBE, (byte) 0x7E, (byte) 0x7F, (byte) 0xBF, (byte) 0x7D, (byte) 0xBD, (byte) 0xBC, (byte) 0x7C, + (byte) 0xB4, (byte) 0x74, (byte) 0x75, (byte) 0xB5, (byte) 0x77, (byte) 0xB7, (byte) 0xB6, (byte) 0x76, (byte) 0x72, (byte) 0xB2, (byte) 0xB3, (byte) 0x73, (byte) 0xB1, (byte) 0x71, (byte) 0x70, (byte) 0xB0, + (byte) 0x50, (byte) 0x90, (byte) 0x91, (byte) 0x51, (byte) 0x93, (byte) 0x53, (byte) 0x52, (byte) 0x92, (byte) 0x96, (byte) 0x56, (byte) 0x57, (byte) 0x97, (byte) 0x55, (byte) 0x95, (byte) 0x94, (byte) 0x54, + (byte) 0x9C, (byte) 0x5C, (byte) 0x5D, (byte) 0x9D, (byte) 0x5F, (byte) 0x9F, (byte) 0x9E, (byte) 0x5E, (byte) 0x5A, (byte) 0x9A, (byte) 0x9B, (byte) 0x5B, (byte) 0x99, (byte) 0x59, (byte) 0x58, (byte) 0x98, + (byte) 0x88, (byte) 0x48, (byte) 0x49, (byte) 0x89, (byte) 0x4B, (byte) 0x8B, (byte) 0x8A, (byte) 0x4A, (byte) 0x4E, (byte) 0x8E, (byte) 0x8F, (byte) 0x4F, (byte) 0x8D, (byte) 0x4D, (byte) 0x4C, (byte) 0x8C, + (byte) 0x44, (byte) 0x84, (byte) 0x85, (byte) 0x45, (byte) 0x87, (byte) 0x47, (byte) 0x46, (byte) 0x86, (byte) 0x82, (byte) 0x42, (byte) 0x43, (byte) 0x83, (byte) 0x41, (byte) 0x81, (byte) 0x80, (byte) 0x40 + }; +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/security/DES.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/security/DES.java new file mode 100644 index 00000000..aaa4382c --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/security/DES.java @@ -0,0 +1,5 @@ +package com.xhpc.pp.utils.security; + +public class DES { + +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/security/HexUtils.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/security/HexUtils.java new file mode 100644 index 00000000..4fd993f2 --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/security/HexUtils.java @@ -0,0 +1,168 @@ +package com.xhpc.pp.utils.security; + +import org.apache.commons.lang3.ArrayUtils; + +public class HexUtils { + + /** + * 字节数据转字符串专用集合 + */ + private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', + 'F'}; + + public static String toHex(byte[] data) { + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < data.length; i++) { + // 取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右移 + stringBuilder.append(HEX_CHAR[(data[i] & 0xf0) >>> 4]); + // 取出字节的低四位 作为索引得到相应的十六进制标识符 + stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]); + } + + return stringBuilder.toString(); + + } + + public static String toHex(byte[] data, int start, int end) { + if (data == null || data.length < end) + return ""; + + return toHex(ArrayUtils.subarray(data, start, end)); + } + + public static String toString(byte[] data) { + return new String(data); + } + + public static String toString(byte[] data, int start, int end) { + if (data == null || data.length < end) + return ""; + + return toString(ArrayUtils.subarray(data, start, end)); + } + + public static int toInteger(byte[] data, int start, int end) { + if (data == null || data.length < end) + return 0; + + return Integer.decode("0x" + toHex(data, start, end)); + } + + public static byte[] toBytes(String hex) { + hex = hex.trim(); + if (hex == null || hex.length() == 0 || hex.length() % 2 != 0) + return null; + + byte[] b = new byte[hex.length() / 2]; + + for (int i = 0; i < hex.length(); i = i + 2) { + b[i / 2] = Integer.decode("0x" + hex.substring(i, i + 2)).byteValue(); + } + + return b; + } + + public static byte[] stringToBytes(String str, int len) { + byte[] data = str.getBytes(); + if (data.length > len) + return data; + + for (int i = data.length; i < len; i++) + data = ArrayUtils.add(data, (byte) 0); + + return data; + } + + + public static String toIntString(String hex) { + return toIntString(hex, 4); + } + + public static String toIntString(String hex, int len) { + if (hex == null || hex.length() == 0 || hex.length() % len != 0) + return null; + + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < hex.length(); i = i + len) { + sb.append(String.format("%0" + len + "d", byte2int(toBytes(hex.substring(i, i + len))))); + } + + return sb.toString(); + } + + public static byte[] toIntBytes(String num, int len) { + if (num == null || num.length() == 0 || num.length() % len != 0) + return null; + + byte[] result = new byte[0]; + + for (int i = 0; i < num.length(); i = i + len) { + int n = Integer.parseInt(num.substring(i, i + len)); + + result = ArrayUtils.addAll(result, toIntBytes(n, len / 2)); + } + + return result; + } + + public static byte[] toIntBytes(int n, int len) { + byte[] b = new byte[len]; + + for (int i = 0; i < len; i++) { + b[i] = (byte) (n >> i * 8 & 0xff); + } + return b; + + } + + public static int byte2int(byte[] b) { + int res = 0; + int bLen = b.length; + + if (bLen < 5) {// int 最大到4个字节 + for (int i = 0; i < bLen; i++) { + res += (b[i] & 0xFF) << (8 * i); + } + } + + return res; + } + + public static byte[] toLongBytes(long n) { + byte[] b = new byte[4]; + + for (int i = 0; i < 4; i++) { + b[i] = (byte) ((n >> i * 8) & 0xff); + } + return b; + + } + + // 使用小端 字节index 0 对应 int 的最后一个字节 + public static long byte2Long(byte[] b) { + long res = 0; + int bLen = b.length; +// int 最大到4个字节 + if (bLen < 9) { + for (int i = 0; i < bLen; i++) { + res += (b[i] & 0xFFL) << 8 * i; + } + } + + return res; + } + + public static void main(String[] args) { + System.out.println(toIntString("E80373000E02E903", 4)); + System.out.println(toHex(toIntBytes("1000011505261001", 4))); + System.out.println(toIntBytes("0016537797330272", 4)); +// System.out.println(toIntString("32FFD505484B323441260443AAAAAAAA",8)); + System.out.println(toHex(toLongBytes(1000000L))); + System.out.println(byte2Long(toBytes("20090080"))); + + System.out.println(0x80 & 0xff); + System.out.println(String.format("%032d", 123456)); + } + + +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/security/MD5.java b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/security/MD5.java new file mode 100644 index 00000000..da68c268 --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/java/com/xhpc/pp/utils/security/MD5.java @@ -0,0 +1,118 @@ +package com.xhpc.pp.utils.security; + +import org.apache.commons.codec.digest.DigestUtils; + +import java.io.UnsupportedEncodingException; +import java.security.SignatureException; +import java.util.*; + +public class MD5 { + + /** + * 签名字符串 + * + * @param text 需要签名的字符串 + * @param key 密钥 + * @param input_charset 编码格式 + * @return 签名结果 + */ + public static String sign(String text, String key, String input_charset) { + text = text + key; + return DigestUtils.md5Hex(getContentBytes(text, input_charset)); + } + + public static String sign(String text, String key) { + return sign(text, key, "utf-8").toUpperCase(); + } + + /** + * 签名字符串 + * + * @param text 需要签名的字符串 + * @param sign 签名结果 + * @param key 密钥 + * @return 签名结果 + */ + public static boolean verify(String text, String sign, String key) { + text = text + key; + String mysign = DigestUtils.md5Hex(getContentBytes(text, "UTF-8")); + if (mysign.equals(sign)) { + return true; + } else { + return false; + } + } + + /** + * @param content + * @param charset + * @return + * @throws SignatureException + * @throws UnsupportedEncodingException + */ + private static byte[] getContentBytes(String content, String charset) { + if (charset == null || "".equals(charset)) { + return content.getBytes(); + } + try { + return content.getBytes(charset); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset); + } + } + + /** + * 除去数组中的空值和签名参数 + * + * @param sArray 签名参数组 + * @return 去掉空值与签名参数后的新签名参数组 + */ + public static Map paraFilter(Map sArray) { + + Map result = new HashMap(); + + if (sArray == null || sArray.size() <= 0) { + return result; + } + + for (String key : sArray.keySet()) { + String value = sArray.get(key); + if (value == null || value.equals("") || key.equalsIgnoreCase("sign") + || key.equalsIgnoreCase("sign_type")) { + continue; + } + result.put(key, value); + } + + return result; + } + + /** + * 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串 + * + * @param params 需要排序并参与字符拼接的参数组 + * @return 拼接后字符串 + */ + public static String createLinkString(Map params) { + + List keys = new ArrayList(params.keySet()); + Collections.sort(keys); + + String prestr = ""; + + for (int i = 0; i < keys.size(); i++) { + String key = keys.get(i); + String value = params.get(key); + + if (i == keys.size() - 1) {//拼接时,不包括最后一个&字符 + prestr = prestr + key + "=" + value; + } else { + prestr = prestr + key + "=" + value + "&"; + } + } + + return prestr; + } + + +} diff --git a/xhpc-modules/xhpc-power-pole/src/main/resources/banner.txt b/xhpc-modules/xhpc-power-pole/src/main/resources/banner.txt new file mode 100644 index 00000000..27cacb9c --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/resources/banner.txt @@ -0,0 +1,10 @@ +Spring Boot Version: ${spring-boot.version} +Spring Application Name: ${spring.application.name} + _ __ _ _ + (_) / _|(_)| | + _ __ _ _ ___ _ _ _ ______ | |_ _ | | ___ +| '__|| | | | / _ \ | | | || ||______|| _|| || | / _ \ +| | | |_| || (_) || |_| || | | | | || || __/ +|_| \__,_| \___/ \__, ||_| |_| |_||_| \___| + __/ | + |___/ \ No newline at end of file diff --git a/xhpc-modules/xhpc-power-pole/src/main/resources/bootstrap.yml b/xhpc-modules/xhpc-power-pole/src/main/resources/bootstrap.yml new file mode 100644 index 00000000..24c288c0 --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/resources/bootstrap.yml @@ -0,0 +1,29 @@ +ppsvc: + server: 0.0.0.0 + port: 8886 + +# Tomcat +server: + port: ${random.int(1300,1400)} + +# Spring +spring: + application: + # 应用名称 + name: xhpc-power-pole + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 127.0.0.1:8848 + config: + # 配置中心地址 + server-addr: 127.0.0.1:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} diff --git a/xhpc-modules/xhpc-power-pole/src/main/resources/logback.xml b/xhpc-modules/xhpc-power-pole/src/main/resources/logback.xml new file mode 100644 index 00000000..7161a262 --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/resources/logback.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + diff --git a/xhpc-modules/xhpc-power-pole/src/main/resources/mapper/ServiceFieldMapper.xml b/xhpc-modules/xhpc-power-pole/src/main/resources/mapper/ServiceFieldMapper.xml new file mode 100644 index 00000000..7f2859e0 --- /dev/null +++ b/xhpc-modules/xhpc-power-pole/src/main/resources/mapper/ServiceFieldMapper.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + id + , service_name, version, name, code, len, seq, remark, data_type + + + + + + + + delete + from service_field + where id = #{id,jdbcType=BIGINT} + + + + insert into service_field (id, service_name, version, + name, code, len, seq, + remark) + values (#{id,jdbcType=BIGINT}, #{serviceName,jdbcType=VARCHAR}, #{version,jdbcType=VARCHAR}, + #{name,jdbcType=VARCHAR}, #{code,jdbcType=VARCHAR}, #{len,jdbcType=INTEGER}, #{seq,jdbcType=INTEGER}, + #{remark,jdbcType=VARCHAR}) + + + + update service_field + + + service_name = #{serviceName,jdbcType=VARCHAR}, + + + version = #{version,jdbcType=VARCHAR}, + + + name = #{name,jdbcType=VARCHAR}, + + + code = #{code,jdbcType=VARCHAR}, + + + len = #{len,jdbcType=INTEGER}, + + + seq = #{seq,jdbcType=INTEGER}, + + + remark = #{remark,jdbcType=VARCHAR}, + + + where id = #{id,jdbcType=BIGINT} + + + +