diff --git a/pom.xml b/pom.xml
index 95016da..d355fbd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -100,6 +100,10 @@
org.aspectj
aspectjrt
+
+ cn.axzo.framework
+ axzo-common-domain
+
diff --git a/src/main/java/cn/axzo/pokonyan/util/KeysUtil.java b/src/main/java/cn/axzo/pokonyan/util/KeysUtil.java
new file mode 100644
index 0000000..452d4eb
--- /dev/null
+++ b/src/main/java/cn/axzo/pokonyan/util/KeysUtil.java
@@ -0,0 +1,48 @@
+package cn.axzo.pokonyan.util;
+
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * @author tanjie@axzo.cn
+ * @date 2023/11/17 18:04
+ */
+public class KeysUtil {
+
+ private static final String DEFAULT_SEPARATOR = "-";
+
+
+ public static String createKey(Object... keys) {
+ if (ArrayUtil.isEmpty(keys)) {
+ return StrUtil.EMPTY;
+ }
+ StringBuilder stringBuilder = new StringBuilder();
+ for (int i = 0; i < keys.length; i++) {
+ if (null == keys[i]) {
+ continue;
+ }
+ stringBuilder.append(keys[i]);
+ if (i != keys.length - 1) {
+ stringBuilder.append(DEFAULT_SEPARATOR);
+ }
+ }
+ return stringBuilder.toString();
+ }
+
+ public static String createKeyBySeparator(String separator,Object... keys) {
+ if (ArrayUtil.isEmpty(keys)) {
+ return StrUtil.EMPTY;
+ }
+ StringBuilder stringBuilder = new StringBuilder();
+ for (int i = 0; i < keys.length; i++) {
+ if (null == keys[i]) {
+ continue;
+ }
+ stringBuilder.append(keys[i]);
+ if (i != keys.length - 1) {
+ stringBuilder.append(separator);
+ }
+ }
+ return stringBuilder.toString();
+ }
+}
diff --git a/src/main/java/cn/axzo/pokonyan/util/RpcUtil.java b/src/main/java/cn/axzo/pokonyan/util/RpcUtil.java
new file mode 100644
index 0000000..ce8ce75
--- /dev/null
+++ b/src/main/java/cn/axzo/pokonyan/util/RpcUtil.java
@@ -0,0 +1,96 @@
+package cn.axzo.pokonyan.util;
+
+
+import cn.axzo.framework.domain.ServiceException;
+import cn.axzo.framework.domain.data.AssertUtil;
+import cn.axzo.framework.domain.web.result.ApiResult;
+import cn.azxo.framework.common.model.CommonResponse;
+import cn.hutool.core.date.StopWatch;
+import cn.hutool.core.lang.Assert;
+import cn.hutool.core.lang.TypeReference;
+import cn.hutool.http.HttpStatus;
+import cn.hutool.json.JSONUtil;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+/**
+ * 外部rpc接口 返回 CommonResponse
+ * @author tanjie@axzo.cn
+ * @date 2022/5/23 11:08
+ */
+@Slf4j
+public class RpcUtil {
+
+
+ /**
+ * 常用的RPC请求返回值解析,如果 被请求方 返回非200会抛出异常
+ *
+ */
+ public static T rpcCommonProcessor(Supplier> supplier, String operationType, Object... param) {
+
+ return rpcProcessorMayThrow(supplier, operationType, commonResponse -> {
+ throw new ServiceException(commonResponse.getMsg());
+ }, param);
+ }
+
+ public static T rpcApiResultProcessor(Supplier> supplier, String operationType, Object... param) {
+ log.info(operationType + "-Param: " + JSONUtil.toJsonStr(param));
+ ApiResult result = printLatency(supplier,operationType);
+ log.info(operationType + "-Result: " + JSONUtil.toJsonStr(result));
+ Assert.notNull(result, "服务调用异常");
+ Assert.isTrue(result.getCode() == 200, "服务调用异常:" + result.getMsg());
+ return result.getData();
+ }
+
+ /**
+ * 第三方发生异常时,自定义处理逻辑
+ *
+ * @param supplier
+ * @param operationType
+ * @param throwConsumer
+ * @param param
+ * @return
+ */
+ public static T rpcProcessorMayThrow(Supplier> supplier, String operationType, Consumer> throwConsumer, Object... param) {
+ Assert.notNull(throwConsumer, "自定义的异常处理不可为空");
+ log.info(operationType + "-Param: " + JSONUtil.toJsonStr(param));
+ CommonResponse result = printLatency(supplier, operationType);
+ log.info(operationType + "-Result: " + JSONUtil.toJsonStr(result));
+ Assert.notNull(result, "服务调用异常");
+ // 200自定义处理
+ if (HttpStatus.HTTP_OK != result.getCode()) {
+ throwConsumer.accept(result);
+ }
+ return result.getData();
+ }
+ public static R printLatency(Supplier< R> function,String optType) {
+ StopWatch stopWatch = new StopWatch(optType);
+ stopWatch.start(optType);
+ R r = function.get();
+ stopWatch.stop();
+ log.info(stopWatch.shortSummary(TimeUnit.MILLISECONDS));
+ return r;
+ }
+
+ @Data
+ public static class Response {
+ private Integer code;
+ private String msg;
+ private E data;
+
+ public static Response create(String data) {
+ return JSONUtil.toBean(data, Response.class);
+ }
+ }
+
+
+
+
+}