map = new HashMap<>(1);
+ map.put("code", "1234");
+ SmsTemplate smsTemplate = new AliyunSmsTemplate(smsProperties);
+ Object send = smsTemplate.send("15706259078", "SMS_146125046", map);
+ log.info("短信发送结果:" + send);
+ }
+
+ @Test
+ public void test3(){
+ String content = "test中文";
+ AES aes = SecureUtil.aes(key.getBytes());
+ byte[] encrypt = aes.encrypt(content);
+ byte[] decrypt = aes.decrypt(encrypt);
+ String encryptHex = aes.encryptHex(content);
+ System.out.println("加密后16进制:" + encryptHex);
+ String decryptStr = aes.decryptStr(encryptHex, CharsetUtil.CHARSET_UTF_8);
+ System.out.println("解密:" + decryptStr);
+ }
}
diff --git a/ruoyi-admin/src/test/java/com/fjp/lc/test/service/WechatTest.java b/ruoyi-admin/src/test/java/com/fjp/lc/test/service/WechatTest.java
index a8ebdf0..cb462a3 100644
--- a/ruoyi-admin/src/test/java/com/fjp/lc/test/service/WechatTest.java
+++ b/ruoyi-admin/src/test/java/com/fjp/lc/test/service/WechatTest.java
@@ -1,7 +1,7 @@
package com.fjp.lc.test.service;
import com.cyl.h5.pojo.vo.form.WechatLoginForm;
-import com.cyl.ums.service.MemberWechatService;
+import com.cyl.manager.ums.service.MemberWechatService;
import com.ruoyi.RuoYiApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml
index 4afb743..4d43a46 100644
--- a/ruoyi-common/pom.xml
+++ b/ruoyi-common/pom.xml
@@ -130,6 +130,12 @@
javax.servlet-api
+
+
+ com.aliyun
+ dysmsapi20170525
+ true
+
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/config/SmsConfig.java b/ruoyi-common/src/main/java/com/ruoyi/common/config/SmsConfig.java
new file mode 100644
index 0000000..b540ddf
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/config/SmsConfig.java
@@ -0,0 +1,34 @@
+package com.ruoyi.common.config;
+
+import com.ruoyi.common.config.properties.SmsProperties;
+import com.ruoyi.common.core.sms.AliyunSmsTemplate;
+import com.ruoyi.common.core.sms.SmsTemplate;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
+
+/**
+ * 短信配置类
+ *
+ * @author Lion Li
+ * @version 4.2.0
+ */
+@EnableConfigurationProperties(SmsProperties.class)
+public class SmsConfig {
+
+ @Configuration
+ @ConditionalOnProperty(value = "sms.enabled", havingValue = "true")
+ @ConditionalOnClass(com.aliyun.dysmsapi20170525.Client.class)
+ static class AliyunSmsConfig {
+
+ @Bean
+ public SmsTemplate aliyunSmsTemplate(SmsProperties smsProperties) {
+ return new AliyunSmsTemplate(smsProperties);
+ }
+
+ }
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/config/properties/SmsProperties.java b/ruoyi-common/src/main/java/com/ruoyi/common/config/properties/SmsProperties.java
new file mode 100644
index 0000000..2c93b39
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/config/properties/SmsProperties.java
@@ -0,0 +1,46 @@
+package com.ruoyi.common.config.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * SMS短信 配置属性
+ *
+ * @author Lion Li
+ * @version 4.2.0
+ */
+@Data
+@ConfigurationProperties(prefix = "sms")
+@Component
+public class SmsProperties {
+
+ private Boolean enabled;
+
+ /**
+ * 配置节点
+ * 阿里云 dysmsapi.aliyuncs.com
+ */
+ private String endpoint;
+
+ /**
+ * key
+ */
+ private String accessKeyId;
+
+ /**
+ * 密匙
+ */
+ private String accessKeySecret;
+
+ /*
+ * 短信签名
+ */
+ private String signName;
+
+ /**
+ * 短信应用ID (腾讯专属)
+ */
+ private String sdkAppId;
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
index f41bf11..33e4af3 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
@@ -68,6 +68,8 @@ public class Constants
* 登录用户 redis key
*/
public static final String LOGIN_TOKEN_KEY = "login_tokens:";
+ public static final String LOGIN_MEMBER_TOKEN_KEY = "login_member_tokens:";
+ public static final String MEMBER_INFO = "member_info";
/**
* 防重提交 redis key
@@ -98,6 +100,7 @@ public class Constants
* 令牌前缀
*/
public static final String LOGIN_USER_KEY = "login_user_key";
+ public static final String LOGIN_MEMBER_KEY = "login_member_key";
/**
* 用户ID
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginMember.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginMember.java
new file mode 100644
index 0000000..50b4ebc
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginMember.java
@@ -0,0 +1,13 @@
+package com.ruoyi.common.core.domain.model;
+
+import lombok.Data;
+
+@Data
+public class LoginMember {
+
+ private Long memberId;
+ private String token;
+ private Long loginTime;
+ private Long expireTime;
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/SmsResult.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/SmsResult.java
new file mode 100644
index 0000000..a273374
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/SmsResult.java
@@ -0,0 +1,35 @@
+package com.ruoyi.common.core.domain.model;
+
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * 上传返回体
+ *
+ * @author Lion Li
+ */
+@Data
+@Builder
+public class SmsResult {
+
+ /**
+ * 是否成功
+ */
+ private boolean isSuccess;
+
+ /**
+ * 响应消息
+ */
+ private String message;
+
+ /**
+ * 实际响应体
+ *
+ * 可自行转换为 SDK 对应的 SendSmsResponse
+ */
+ private String response;
+ /**
+ * uuid
+ */
+ private String uuid;
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisService.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisService.java
index a314cd5..739e798 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisService.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisService.java
@@ -1,5 +1,6 @@
package com.ruoyi.common.core.redis;
+import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -22,7 +23,51 @@ public class RedisService {
return redisCache.getCacheList(key);
}
+ public String getAddressList() {
+ String key = RedisKeys.ADDRESS_LIST_KEY;
+ return redisCache.getCacheObject(key);
+ }
+
+ public void setAddressList(String list) {
+ String key = RedisKeys.ADDRESS_LIST_KEY;
+ redisCache.setCacheObject(key,list);
+ }
+
interface RedisKeys {
String MATCH_LIST_OF = "MATCH_LIST_OF_";
+ String ADDRESS_LIST_KEY = "ADDRESS_LIST_KEY_";
+ }
+
+ /**
+ * redis实现分布式锁 --- 上锁
+ *
+ * @param key
+ * @param jobInfo
+ * @param lockSecond
+ * @return
+ * @throws Exception
+ */
+ public void lock(String key, String jobInfo, Integer lockSecond) throws Exception {
+ String existJobInfo = redisCache.getCacheObject(key);
+ if (StringUtils.isNotEmpty(existJobInfo)) {
+ throw new Exception(String.format("获取锁失败: redisKey: %s, existJobInfo: %s", key, existJobInfo));
+ }
+ redisCache.setCacheObject(key, jobInfo, lockSecond, TimeUnit.SECONDS);
+ }
+
+ /**
+ * redis实现分布式锁 --- 解锁
+ *
+ * @param key
+ * @param jobInfo
+ * @throws Exception
+ */
+ public void unLock(String key, String jobInfo) throws Exception {
+ String existJobInfo = redisCache.getCacheObject(key);
+ if (jobInfo.equals(existJobInfo)) {
+ redisCache.deleteObject(key);
+ } else {
+ throw new Exception(String.format("释放锁异常: redisKey: %s, existJobInfo: %s, jobInfo: %s", key, existJobInfo, jobInfo));
+ }
}
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/sms/AliyunSmsTemplate.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/sms/AliyunSmsTemplate.java
new file mode 100644
index 0000000..a795ffa
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/sms/AliyunSmsTemplate.java
@@ -0,0 +1,71 @@
+package com.ruoyi.common.core.sms;
+
+import com.aliyun.dysmsapi20170525.Client;
+import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
+import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
+import com.aliyun.teaopenapi.models.Config;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.ruoyi.common.config.properties.SmsProperties;
+import com.ruoyi.common.core.domain.model.SmsResult;
+import com.ruoyi.common.exception.sms.SmsException;
+import com.ruoyi.common.utils.JsonUtils;
+import com.ruoyi.common.utils.StringUtils;
+import lombok.SneakyThrows;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * Aliyun 短信模板
+ *
+ * @author Lion Li
+ * @version 4.2.0
+ */
+public class AliyunSmsTemplate implements SmsTemplate {
+
+ @Autowired
+ private SmsProperties properties;
+
+ private Client client;
+
+ @SneakyThrows(Exception.class)
+ public AliyunSmsTemplate(SmsProperties smsProperties) {
+ this.properties = smsProperties;
+ Config config = new Config()
+ // 您的AccessKey ID
+ .setAccessKeyId(smsProperties.getAccessKeyId())
+ // 您的AccessKey Secret
+ .setAccessKeySecret(smsProperties.getAccessKeySecret())
+ // 访问的域名
+ .setEndpoint(smsProperties.getEndpoint());
+ this.client = new Client(config);
+ }
+
+ @Override
+ public SmsResult send(String phones, String templateId, Map param) {
+ if (StringUtils.isBlank(phones)) {
+ throw new SmsException("手机号不能为空");
+ }
+ if (StringUtils.isBlank(templateId)) {
+ throw new SmsException("模板ID不能为空");
+ }
+ SendSmsRequest req = new SendSmsRequest()
+ .setPhoneNumbers(phones)
+ .setSignName(properties.getSignName())
+ .setTemplateCode(templateId)
+ .setTemplateParam(JsonUtils.toJsonString(param));
+ try {
+ SendSmsResponse resp = client.sendSms(req);
+ return SmsResult.builder()
+ .isSuccess("OK".equals(resp.getBody().getCode()))
+ .message(resp.getBody().getMessage())
+ .response(JsonUtils.toJsonString(resp))
+ .build();
+ } catch (Exception e) {
+ throw new SmsException(e.getMessage());
+ }
+ }
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/sms/SmsTemplate.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/sms/SmsTemplate.java
new file mode 100644
index 0000000..ee6064b
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/sms/SmsTemplate.java
@@ -0,0 +1,26 @@
+package com.ruoyi.common.core.sms;
+
+import com.ruoyi.common.core.domain.model.SmsResult;
+
+import java.util.Map;
+
+/**
+ * 短信模板
+ *
+ * @author Lion Li
+ * @version 4.2.0
+ */
+public interface SmsTemplate {
+
+ /**
+ * 发送短信
+ *
+ * @param phones 电话号(多个逗号分割)
+ * @param templateId 模板id
+ * @param param 模板对应参数
+ * 阿里 需使用 模板变量名称对应内容 例如: code=1234
+ * 腾讯 需使用 模板变量顺序对应内容 例如: 1=1234, 1为模板内第一个参数
+ */
+ SmsResult send(String phones, String templateId, Map param);
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/sms/SmsException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/sms/SmsException.java
new file mode 100644
index 0000000..9d66156
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/sms/SmsException.java
@@ -0,0 +1,17 @@
+package com.ruoyi.common.exception.sms;
+
+
+/**
+ * Sms异常类
+ *
+ * @author Lion Li
+ */
+public class SmsException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ public SmsException(String msg) {
+ super(msg);
+ }
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/AesCryptoUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/AesCryptoUtils.java
new file mode 100644
index 0000000..e509e42
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/AesCryptoUtils.java
@@ -0,0 +1,28 @@
+package com.ruoyi.common.utils;
+
+import cn.hutool.core.util.CharsetUtil;
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.symmetric.AES;
+
+/**
+ * aes加密工具
+ */
+public class AesCryptoUtils {
+
+ public static String encrypt(String key, String content){
+ if (StringUtils.isBlank(key) || StringUtils.isBlank(content)){
+ throw new RuntimeException("错误");
+ }
+ AES aes = SecureUtil.aes(key.getBytes());
+ byte[] encrypt = aes.encrypt(content);
+ return aes.encryptHex(content);
+ }
+
+ public static String decrypt(String key, String content){
+ if (StringUtils.isBlank(key) || StringUtils.isBlank(content)){
+ throw new RuntimeException("错误");
+ }
+ AES aes = SecureUtil.aes(key.getBytes());
+ return aes.decryptStr(content, CharsetUtil.CHARSET_UTF_8);
+ }
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/IDGenerator.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/IDGenerator.java
new file mode 100644
index 0000000..133ce2e
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/IDGenerator.java
@@ -0,0 +1,104 @@
+package com.ruoyi.common.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Created by yangyincong on 15/8/16.
+ * ID生成器 workId (1~4)
+ */
+public class IDGenerator {
+ private final static Logger logger = LoggerFactory.getLogger(IDGenerator.class);
+ private final static long twepoch = 1361753741828L;
+ private final static long workerIdBits = 4L;
+ private final static long maxWorkerId = -1L ^ -1L << workerIdBits;
+ private final static long sequenceBits = 10L;
+ private long workerId;
+ private long sequence = 0L;
+
+ private final static long workerIdShift = sequenceBits;
+ private final static long timestampLeftShift = sequenceBits + workerIdBits;
+ private final static long sequenceMask = -1L ^ -1L << sequenceBits;
+
+ private long lastTimestamp = -1L;
+
+ private IDGenerator(final long workerId) {
+ super();
+ this.workerId = workerId;
+ }
+
+ public static long generateMinId(int wid, long time) {
+ return (time - twepoch << timestampLeftShift) | (wid << workerIdShift);
+ }
+
+ public synchronized long nextId() {
+ long timestamp = this.timeGen();
+ if (this.lastTimestamp == timestamp) {
+ this.sequence = (this.sequence + 1) & sequenceMask;
+ if (this.sequence == 0) {
+ timestamp = this.tilNextMillis(this.lastTimestamp);
+ }
+ } else {
+ this.sequence = 0;
+ }
+ if (timestamp < this.lastTimestamp) {
+ try {
+ throw new Exception(
+ String.format(
+ "Clock moved backwards. Refusing to generate id for %d milliseconds",
+ this.lastTimestamp - timestamp));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ this.lastTimestamp = timestamp;
+ long nextId = ((timestamp - twepoch << timestampLeftShift))
+ | (this.workerId << workerIdShift) | (this.sequence);
+ return nextId;
+ }
+
+ public static long generateMaxId(long wid, long time) {
+ return (time - twepoch << timestampLeftShift) | (wid << workerIdShift) | sequenceMask;
+ }
+
+ private long tilNextMillis(final long lastTimestamp) {
+ long timestamp = this.timeGen();
+ while (timestamp <= lastTimestamp) {
+ timestamp = this.timeGen();
+ }
+ return timestamp;
+ }
+
+ private long timeGen() {
+ return System.currentTimeMillis();
+ }
+
+ private static IDGenerator generator;
+
+ public static synchronized void init(Long workerId) throws Exception {
+ workerId = workerId % maxWorkerId;
+ logger.info("程序中init的workid为:{}", workerId);
+ if (workerId > maxWorkerId || workerId < 0) {
+ throw new IllegalArgumentException(String.format(
+ "worker Id can't be greater than %d or less than 0",
+ IDGenerator.maxWorkerId));
+ }
+ generator = new IDGenerator(workerId);
+ }
+
+ public static Long generateId() {
+ if (null == generator) {
+ synchronized (IDGenerator.class) {
+ if (null == generator) {
+ try {
+ init(2L);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ return generator.nextId();
+ }
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/JsonUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/JsonUtils.java
new file mode 100644
index 0000000..e5c471e
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/JsonUtils.java
@@ -0,0 +1,112 @@
+package com.ruoyi.common.utils;
+
+import cn.hutool.core.lang.Dict;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.exc.MismatchedInputException;
+import com.ruoyi.common.utils.spring.SpringUtils;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * JSON 工具类
+ *
+ * @author 芋道源码
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class JsonUtils {
+
+ private static final ObjectMapper OBJECT_MAPPER = SpringUtils.getBean(ObjectMapper.class);
+
+ public static ObjectMapper getObjectMapper() {
+ return OBJECT_MAPPER;
+ }
+
+ public static String toJsonString(Object object) {
+ if (ObjectUtil.isNull(object)) {
+ return null;
+ }
+ try {
+ return OBJECT_MAPPER.writeValueAsString(object);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static T parseObject(String text, Class clazz) {
+ if (StringUtils.isEmpty(text)) {
+ return null;
+ }
+ try {
+ return OBJECT_MAPPER.readValue(text, clazz);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static T parseObject(byte[] bytes, Class clazz) {
+ if (ArrayUtil.isEmpty(bytes)) {
+ return null;
+ }
+ try {
+ return OBJECT_MAPPER.readValue(bytes, clazz);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static T parseObject(String text, TypeReference typeReference) {
+ if (StringUtils.isBlank(text)) {
+ return null;
+ }
+ try {
+ return OBJECT_MAPPER.readValue(text, typeReference);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Dict parseMap(String text) {
+ if (StringUtils.isBlank(text)) {
+ return null;
+ }
+ try {
+ return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructType(Dict.class));
+ } catch (MismatchedInputException e) {
+ // 类型不匹配说明不是json
+ return null;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static List parseArrayMap(String text) {
+ if (StringUtils.isBlank(text)) {
+ return null;
+ }
+ try {
+ return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, Dict.class));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static List parseArray(String text, Class clazz) {
+ if (StringUtils.isEmpty(text)) {
+ return new ArrayList<>();
+ }
+ try {
+ return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/PhoneUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/PhoneUtils.java
new file mode 100644
index 0000000..f2fd5bd
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/PhoneUtils.java
@@ -0,0 +1,14 @@
+package com.ruoyi.common.utils;
+
+/**
+ * 手机号工具类
+ */
+public class PhoneUtils {
+
+ public static String hidePhone(String phone){
+ if (StringUtils.isEmpty(phone) || phone.length() < 11){
+ throw new RuntimeException("手机号格式错误");
+ }
+ return phone.substring(0, 3) + "****" + phone.substring(7, 11);
+ }
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ResponseUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ResponseUtils.java
new file mode 100644
index 0000000..692ed61
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ResponseUtils.java
@@ -0,0 +1,26 @@
+package com.ruoyi.common.utils;
+
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.MultiValueMap;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ResponseUtils {
+
+ private static final String MESSAGE = "msg";
+ private static final String CODE = "code";
+ private static final String DATA = "data";
+
+ private ResponseUtils(){}
+
+ private static ResponseEntity