From 3bc7d53106c1a7b4d467e6b7617ff24a0160eb0d Mon Sep 17 00:00:00 2001
From: cjh <18505142974@163.com>
Date: Fri, 30 May 2025 10:53:21 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9vlog?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../content/controller/CommentController.java | 8 +-
.../content/controller/FansController.java | 14 +-
.../content/controller/FileController.java | 6 +-
.../content/controller/MsgController.java | 8 +-
.../controller/PassportController.java | 28 +-
.../content/controller/RabbitMQConsumer.java | 14 +-
.../controller/UserInfoController.java | 22 +-
.../content/controller/VlogController.java | 16 +-
.../intercepter/PassportInterceptor.java | 10 +-
.../intercepter/UserTokenInterceptor.java | 9 +-
ruoyi-modules/ruoyi-content/pom.xml | 28 +
.../domain/base/BaseInfoProperties.java | 64 ++
.../content/domain/base/RabbitMQConfig.java | 55 ++
.../domain/exceptions/GraceException.java | 14 +
.../exceptions/GraceExceptionHandler.java | 58 ++
.../domain/exceptions/MyCustomException.java | 28 +
.../soopin/content/domain/mo/MessageMO.java | 15 +-
.../domain/result/GraceJSONResult.java | 153 ++++
.../domain/result/IMOOCJSONResult.java | 135 ++++
.../domain/result/ResponseStatusEnum.java | 108 +++
.../soopin/content/enums/FileTypeEnum.java | 17 +
.../wzj/soopin/content/enums/MessageEnum.java | 22 +
.../com/wzj/soopin/content/enums/Sex.java | 18 +
.../content/enums/UserInfoModifyType.java | 35 +
.../com/wzj/soopin/content/enums/YesOrNo.java | 17 +
.../com/wzj/soopin/content/idworker/Code.java | 35 +
.../wzj/soopin/content/idworker/DayCode.java | 19 +
.../com/wzj/soopin/content/idworker/Id.java | 29 +
.../wzj/soopin/content/idworker/IdWorker.java | 91 +++
.../content/idworker/InvalidSystemClock.java | 7 +
.../content/idworker/RandomCodeStrategy.java | 11 +
.../com/wzj/soopin/content/idworker/Sid.java | 64 ++
.../com/wzj/soopin/content/idworker/Test.java | 12 +
.../content/idworker/WorkerIdStrategy.java | 9 +
.../strategy/DayPrefixRandomCodeStrategy.java | 41 ++
.../strategy/DefaultRandomCodeStrategy.java | 197 +++++
.../strategy/DefaultWorkerIdStrategy.java | 205 ++++++
.../content/idworker/strategy/FileLock.java | 132 ++++
.../content/idworker/utils/HttpReq.java | 115 +++
.../content/idworker/utils/IPv4Utils.java | 1 +
.../wzj/soopin/content/idworker/utils/Ip.java | 50 ++
.../soopin/content/idworker/utils/Props.java | 70 ++
.../content/idworker/utils/Serializes.java | 118 +++
.../soopin/content/idworker/utils/Utils.java | 114 +++
.../content/result/GraceJSONResult.java | 153 ++++
.../content/result/IMOOCJSONResult.java | 135 ++++
.../content/result/ResponseStatusEnum.java | 108 +++
.../soopin/content/service/FansService.java | 2 +-
.../soopin/content/service/MsgService.java | 1 +
.../soopin/content/service/UserService.java | 13 +-
.../soopin/content/service/VlogService.java | 1 +
.../service/impl/CommentServiceImpl.java | 28 +-
.../content/service/impl/MsgServiceImpl.java | 1 +
.../content/service/impl/VlogServiceImpl.java | 1 +
.../com/wzj/soopin/content/utils/Code.java | 35 +
.../wzj/soopin/content/utils/DateUtil.java | 680 ++++++++++++++++++
.../com/wzj/soopin/content/utils/DayCode.java | 19 +
.../utils/DayPrefixRandomCodeStrategy.java | 41 ++
.../utils/DefaultRandomCodeStrategy.java | 196 +++++
.../utils/DefaultWorkerIdStrategy.java | 205 ++++++
.../content/utils/DesensitizationUtil.java | 77 ++
.../wzj/soopin/content/utils/FileLock.java | 132 ++++
.../wzj/soopin/content/utils/GsonUtil.java | 24 +
.../com/wzj/soopin/content/utils/IPUtil.java | 38 +
.../java/com/wzj/soopin/content/utils/Id.java | 29 +
.../wzj/soopin/content/utils/IdWorker.java | 91 +++
.../content/utils/InvalidSystemClock.java | 7 +
.../wzj/soopin/content/utils/JsonUtils.java | 74 ++
.../com/wzj/soopin/content/utils/MyInfo.java | 9 +
.../soopin/content/utils/PagedGridResult.java | 49 ++
.../content/utils/RandomCodeStrategy.java | 11 +
.../soopin/content/utils/RedisOperator.java | 309 ++++++++
.../wzj/soopin/content/utils/SMSUtils.java | 74 ++
.../com/wzj/soopin/content/utils/Sid.java | 63 ++
.../content/utils/TencentCloudProperties.java | 23 +
.../com/wzj/soopin/content/utils/Test.java | 12 +
.../content/utils/WorkerIdStrategy.java | 9 +
77 files changed, 4777 insertions(+), 95 deletions(-)
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/base/BaseInfoProperties.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/base/RabbitMQConfig.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/exceptions/GraceException.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/exceptions/GraceExceptionHandler.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/exceptions/MyCustomException.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/result/GraceJSONResult.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/result/IMOOCJSONResult.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/result/ResponseStatusEnum.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/FileTypeEnum.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/MessageEnum.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/Sex.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/UserInfoModifyType.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/YesOrNo.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/Code.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/DayCode.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/Id.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/IdWorker.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/InvalidSystemClock.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/RandomCodeStrategy.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/Sid.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/Test.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/WorkerIdStrategy.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/strategy/DayPrefixRandomCodeStrategy.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/strategy/DefaultRandomCodeStrategy.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/strategy/DefaultWorkerIdStrategy.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/strategy/FileLock.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/HttpReq.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/IPv4Utils.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/Ip.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/Props.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/Serializes.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/Utils.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/result/GraceJSONResult.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/result/IMOOCJSONResult.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/result/ResponseStatusEnum.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/Code.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DateUtil.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DayCode.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DayPrefixRandomCodeStrategy.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DefaultRandomCodeStrategy.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DefaultWorkerIdStrategy.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DesensitizationUtil.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/FileLock.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/GsonUtil.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/IPUtil.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/Id.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/IdWorker.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/InvalidSystemClock.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/JsonUtils.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/MyInfo.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/PagedGridResult.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/RandomCodeStrategy.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/RedisOperator.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/SMSUtils.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/Sid.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/TencentCloudProperties.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/Test.java
create mode 100644 ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/WorkerIdStrategy.java
diff --git a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/CommentController.java b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/CommentController.java
index 106c50b60..18b95b576 100644
--- a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/CommentController.java
+++ b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/CommentController.java
@@ -1,8 +1,12 @@
package com.wzj.soopin.consumer.content.controller;
+import com.wzj.soopin.content.domain.base.BaseInfoProperties;
import com.wzj.soopin.content.domain.bo.CommentBO;
+import com.wzj.soopin.content.domain.po.Comment;
+import com.wzj.soopin.content.domain.po.Vlog;
import com.wzj.soopin.content.domain.vo.CommentVO;
+import com.wzj.soopin.content.enums.MessageEnum;
import com.wzj.soopin.content.service.CommentService;
import com.wzj.soopin.content.service.MsgService;
import com.wzj.soopin.content.service.VlogService;
@@ -18,11 +22,13 @@ import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
+
+
@Slf4j
@Api(tags = "CommentController 评论模块的接口")
@RequestMapping("comment")
@RestController
-public class CommentController extends BaseController {
+public class CommentController extends BaseInfoProperties {
@Autowired
private CommentService commentService;
diff --git a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/FansController.java b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/FansController.java
index bfc51a1ec..4ea440dc6 100644
--- a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/FansController.java
+++ b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/FansController.java
@@ -3,13 +3,13 @@ package com.wzj.soopin.consumer.content.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.imooc.base.BaseInfoProperties;
-import com.imooc.grace.result.GraceJSONResult;
-import com.imooc.grace.result.ResponseStatusEnum;
-import com.imooc.pojo.Users;
-import com.imooc.service.FansService;
-import com.imooc.service.UserService;
-import io.swagger.annotations.Api;
+
+import com.wzj.soopin.content.domain.base.BaseInfoProperties;
+import com.wzj.soopin.content.domain.po.Users;
+import com.wzj.soopin.content.result.GraceJSONResult;
+import com.wzj.soopin.content.result.ResponseStatusEnum;
+import com.wzj.soopin.content.service.FansService;
+import com.wzj.soopin.content.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/FileController.java b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/FileController.java
index aa47fb9b6..fa4b2c91c 100644
--- a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/FileController.java
+++ b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/FileController.java
@@ -1,9 +1,9 @@
package com.wzj.soopin.consumer.content.controller;
-import com.imooc.config.MinIOConfig;
-import com.imooc.grace.result.GraceJSONResult;
-import io.swagger.annotations.Api;
+
+import com.wzj.soopin.consumer.content.config.MinIOConfig;
+import com.wzj.soopin.content.result.GraceJSONResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
diff --git a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/MsgController.java b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/MsgController.java
index b074e2916..086d8a7f9 100644
--- a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/MsgController.java
+++ b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/MsgController.java
@@ -1,9 +1,9 @@
package com.wzj.soopin.consumer.content.controller;
-import com.imooc.base.BaseInfoProperties;
-import com.imooc.grace.result.GraceJSONResult;
-import com.imooc.mo.MessageMO;
-import com.imooc.service.MsgService;
+import com.wzj.soopin.content.domain.base.BaseInfoProperties;
+import com.wzj.soopin.content.domain.mo.MessageMO;
+import com.wzj.soopin.content.result.GraceJSONResult;
+import com.wzj.soopin.content.service.MsgService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/PassportController.java b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/PassportController.java
index cacd9a533..b8a9062d1 100644
--- a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/PassportController.java
+++ b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/PassportController.java
@@ -1,17 +1,20 @@
package com.wzj.soopin.consumer.content.controller;
-import com.imooc.base.BaseInfoProperties;
-import com.imooc.bo.LoginWithPasswordBO;
-import com.imooc.bo.RegistLoginBO;
-import com.imooc.grace.result.GraceJSONResult;
-import com.imooc.grace.result.ResponseStatusEnum;
-import com.imooc.pojo.Users;
-import com.imooc.service.UserService;
-import com.imooc.utils.GsonUtil;
-import com.imooc.utils.IPUtil;
-import com.imooc.utils.SMSUtils;
-import com.imooc.vo.UsersVO;
+
+import com.wzj.soopin.content.domain.base.BaseInfoProperties;
+import com.wzj.soopin.content.domain.bo.LoginWithPasswordBO;
+import com.wzj.soopin.content.domain.bo.RegistLoginBO;
+import com.wzj.soopin.content.domain.po.Users;
+import com.wzj.soopin.content.domain.vo.UsersVO;
+import com.wzj.soopin.content.result.GraceJSONResult;
+import com.wzj.soopin.content.result.ResponseStatusEnum;
+import com.wzj.soopin.content.service.UserService;
+import com.wzj.soopin.content.utils.GsonUtil;
+import com.wzj.soopin.content.utils.IPUtil;
+import com.wzj.soopin.content.utils.SMSUtils;
import io.swagger.annotations.Api;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
@@ -19,8 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
-import javax.servlet.http.HttpServletRequest;
-import javax.validation.Valid;
+
import java.util.Optional;
import java.util.UUID;
diff --git a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/RabbitMQConsumer.java b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/RabbitMQConsumer.java
index ea3cd50c9..52402edd1 100644
--- a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/RabbitMQConsumer.java
+++ b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/RabbitMQConsumer.java
@@ -1,12 +1,12 @@
package com.wzj.soopin.consumer.content.controller;
-import com.imooc.base.RabbitMQConfig;
-import com.imooc.enums.MessageEnum;
-import com.imooc.exceptions.GraceException;
-import com.imooc.grace.result.ResponseStatusEnum;
-import com.imooc.mo.MessageMO;
-import com.imooc.service.MsgService;
-import com.imooc.utils.JsonUtils;
+
+import com.wzj.soopin.content.domain.base.RabbitMQConfig;
+import com.wzj.soopin.content.domain.exceptions.GraceException;
+import com.wzj.soopin.content.domain.mo.MessageMO;
+import com.wzj.soopin.content.enums.MessageEnum;
+import com.wzj.soopin.content.service.MsgService;
+import com.wzj.soopin.content.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
diff --git a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/UserInfoController.java b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/UserInfoController.java
index 0433cf7db..00364ae24 100644
--- a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/UserInfoController.java
+++ b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/UserInfoController.java
@@ -1,16 +1,16 @@
package com.wzj.soopin.consumer.content.controller;
-import com.imooc.base.BaseInfoProperties;
-import com.imooc.bo.UpdatedUserBO;
-import com.imooc.config.MinIOConfig;
-import com.imooc.enums.FileTypeEnum;
-import com.imooc.enums.UserInfoModifyType;
-import com.imooc.grace.result.GraceJSONResult;
-import com.imooc.grace.result.ResponseStatusEnum;
-import com.imooc.pojo.Users;
-import com.imooc.service.UserService;
-import com.imooc.utils.MinIOUtils;
-import com.imooc.vo.UsersVO;
+
+import com.wzj.soopin.consumer.content.config.MinIOConfig;
+import com.wzj.soopin.content.domain.base.BaseInfoProperties;
+import com.wzj.soopin.content.domain.bo.UpdatedUserBO;
+import com.wzj.soopin.content.domain.po.Users;
+import com.wzj.soopin.content.domain.vo.UsersVO;
+import com.wzj.soopin.content.enums.FileTypeEnum;
+import com.wzj.soopin.content.enums.UserInfoModifyType;
+import com.wzj.soopin.content.result.GraceJSONResult;
+import com.wzj.soopin.content.result.ResponseStatusEnum;
+import com.wzj.soopin.content.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
diff --git a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/VlogController.java b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/VlogController.java
index 2c8c41c67..b30f450aa 100644
--- a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/VlogController.java
+++ b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/VlogController.java
@@ -1,20 +1,18 @@
package com.wzj.soopin.consumer.content.controller;
-import com.imooc.base.BaseInfoProperties;
-import com.imooc.bo.VlogBO;
-import com.imooc.config.MinIOConfig;
-import com.imooc.enums.YesOrNo;
-import com.imooc.grace.result.GraceJSONResult;
-import com.imooc.service.VlogService;
-import com.imooc.utils.PagedGridResult;
-import com.imooc.utils.QcCloud;
+
+import com.wzj.soopin.consumer.content.config.MinIOConfig;
+import com.wzj.soopin.content.domain.base.BaseInfoProperties;
+import com.wzj.soopin.content.domain.bo.VlogBO;
+import com.wzj.soopin.content.result.GraceJSONResult;
+import com.wzj.soopin.content.service.VlogService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.cloud.context.config.annotation.RefreshScope;
+
import org.springframework.web.bind.annotation.*;
import java.util.List;
diff --git a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/intercepter/PassportInterceptor.java b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/intercepter/PassportInterceptor.java
index e636282e8..a6446b1c4 100644
--- a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/intercepter/PassportInterceptor.java
+++ b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/intercepter/PassportInterceptor.java
@@ -1,15 +1,13 @@
package com.wzj.soopin.consumer.content.intercepter;
-import com.imooc.base.BaseInfoProperties;
-import com.imooc.exceptions.GraceException;
-import com.imooc.grace.result.ResponseStatusEnum;
-import com.imooc.utils.IPUtil;
+
+import com.wzj.soopin.content.domain.base.BaseInfoProperties;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
@Slf4j
public class PassportInterceptor extends BaseInfoProperties implements HandlerInterceptor {
diff --git a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/intercepter/UserTokenInterceptor.java b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/intercepter/UserTokenInterceptor.java
index 382ca5075..c195b5b5b 100644
--- a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/intercepter/UserTokenInterceptor.java
+++ b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/intercepter/UserTokenInterceptor.java
@@ -1,15 +1,14 @@
package com.wzj.soopin.consumer.content.intercepter;
-import com.imooc.base.BaseInfoProperties;
-import com.imooc.exceptions.GraceException;
-import com.imooc.grace.result.ResponseStatusEnum;
+
+import com.wzj.soopin.content.domain.base.BaseInfoProperties;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
@Slf4j
public class UserTokenInterceptor extends BaseInfoProperties implements HandlerInterceptor {
diff --git a/ruoyi-modules/ruoyi-content/pom.xml b/ruoyi-modules/ruoyi-content/pom.xml
index e4545e86d..e73cf50d0 100644
--- a/ruoyi-modules/ruoyi-content/pom.xml
+++ b/ruoyi-modules/ruoyi-content/pom.xml
@@ -14,6 +14,23 @@
+
+ org.springframework.boot
+ spring-boot-starter-amqp
+
+
+
+ com.tencentcloudapi
+ tencentcloud-sdk-java
+ 3.1.270
+
+
+
+
+ com.qcloud
+ vod_api
+ 2.1.5
+
org.dromara
@@ -97,6 +114,17 @@
org.dromara
ruoyi-common-sse
+
+ com.github.pagehelper
+ pagehelper
+ 5.3.2
+ compile
+
+
+ com.squareup.okhttp3
+ okhttp
+ 4.12.0
+
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/base/BaseInfoProperties.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/base/BaseInfoProperties.java
new file mode 100644
index 000000000..d355e136f
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/base/BaseInfoProperties.java
@@ -0,0 +1,64 @@
+package com.wzj.soopin.content.domain.base;
+
+
+
+
+import com.github.pagehelper.PageInfo;
+import com.wzj.soopin.content.utils.PagedGridResult;
+import com.wzj.soopin.content.utils.RedisOperator;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.List;
+
+public class BaseInfoProperties {
+
+ @Autowired
+ public RedisOperator redis;
+
+ public static final Integer COMMON_START_PAGE = 1;
+ public static final Integer COMMON_START_PAGE_ZERO = 0;
+ public static final Integer COMMON_PAGE_SIZE = 10;
+
+ public static final String MOBILE_SMSCODE = "mobile:smscode";
+ public static final String REDIS_USER_TOKEN = "redis_user_token";
+ public static final String REDIS_USER_INFO = "redis_user_info";
+
+ // 短视频的评论总数
+ public static final String REDIS_VLOG_COMMENT_COUNTS = "redis_vlog_comment_counts";
+ // 短视频的评论喜欢数量
+ public static final String REDIS_VLOG_COMMENT_LIKED_COUNTS = "redis_vlog_comment_liked_counts";
+ // 用户点赞评论
+ public static final String REDIS_USER_LIKE_COMMENT = "redis_user_like_comment";
+
+
+ //我的关注总数
+ public static final String REDIS_MY_FOLLOWS_COUNTS = "redis_my_follows_counts";
+ // 我的粉丝总数
+ public static final String REDIS_MY_FANS_COUNTS = "redis_my_fans_counts";
+
+ // 视频和发布者获赞数
+ public static final String REDIS_VLOG_BE_LIKED_COUNTS = "redis_vlog_be_liked_counts";
+ public static final String REDIS_VLOGER_BE_LIKED_COUNTS = "redis_vloger_be_liked_counts";
+
+ // 博主和粉丝的关联关系,用于判断他们是否互粉
+ public static final String REDIS_FANS_AND_VLOGGER_RELATIONSHIP = "redis_fans_and_vlogger_relationship";
+ // 拉黑
+ public static final String REDIS_USER_BLOCK = "redis_user_block";
+ // 举报视频
+ public static final String REDIS_VIDEO_BLOCK = "redis_video_block";
+
+
+ // 用户是否喜欢/点赞视频,取代数据库的关联关系,1:喜欢,0:不喜欢(默认) redis_user_like_vlog:{userId}:{vlogId}
+ public static final String REDIS_USER_LIKE_VLOG = "redis_user_like_vlog";
+
+ public PagedGridResult setterPagedGrid(List> list, Integer page) {
+ PageInfo> pageList = new PageInfo<>(list);
+ PagedGridResult gridResult = new PagedGridResult();
+ gridResult.setRows(list);
+ gridResult.setPage(page);
+ gridResult.setRecords(pageList.getTotal());
+ gridResult.setTotal(pageList.getPages());
+ return gridResult;
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/base/RabbitMQConfig.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/base/RabbitMQConfig.java
new file mode 100644
index 000000000..61d58ec07
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/base/RabbitMQConfig.java
@@ -0,0 +1,55 @@
+package com.wzj.soopin.content.domain.base;//package com.imooc;
+
+
+import org.springframework.amqp.core.*;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+
+
+@Configuration
+public class RabbitMQConfig {
+
+ /**
+ * 根据模型编写代码:
+ * 1. 定义交换机
+ * 2. 定义队列
+ * 3. 创建交换机
+ * 4. 创建队列
+ * 5. 队列和交换机的绑定
+ */
+
+ public static final String EXCHANGE_MSG = "exchange_msg";
+
+ public static final String QUEUE_SYS_MSG = "queue_sys_msg";
+
+ @Bean(EXCHANGE_MSG)
+ public Exchange exchange() {
+ return ExchangeBuilder // 构建交换机
+ .topicExchange(EXCHANGE_MSG) // 使用topic类型,参考:https://www.rabbitmq.com/getstarted.html
+ .durable(true) // 设置持久化,重启mq后依然存在
+ .build();
+ }
+
+ @Bean(QUEUE_SYS_MSG)
+ public Queue queue() {
+ return new Queue(QUEUE_SYS_MSG);
+ }
+
+ @Bean
+ public Binding binding(@Qualifier(EXCHANGE_MSG) Exchange exchange,
+ @Qualifier(QUEUE_SYS_MSG) Queue queue) {
+
+ return BindingBuilder
+ .bind(queue)
+ .to(exchange)
+ .with("sys.msg.*") // 定义路由规则(requestMapping)
+ .noargs();
+
+ // FIXME: * 和 # 分别代表什么意思?
+ }
+
+
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/exceptions/GraceException.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/exceptions/GraceException.java
new file mode 100644
index 000000000..0d3e52bf2
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/exceptions/GraceException.java
@@ -0,0 +1,14 @@
+package com.wzj.soopin.content.domain.exceptions;
+
+import com.imooc.grace.result.ResponseStatusEnum;
+
+/**
+ * 优雅的处理异常,统一封装
+ */
+public class GraceException {
+
+ public static void display(ResponseStatusEnum responseStatusEnum) {
+ throw new MyCustomException(responseStatusEnum);
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/exceptions/GraceExceptionHandler.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/exceptions/GraceExceptionHandler.java
new file mode 100644
index 000000000..735a04d93
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/exceptions/GraceExceptionHandler.java
@@ -0,0 +1,58 @@
+package com.wzj.soopin.content.domain.exceptions;
+
+import com.imooc.grace.result.GraceJSONResult;
+import com.imooc.grace.result.ResponseStatusEnum;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.FieldError;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MaxUploadSizeExceededException;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 统一异常拦截处理
+ * 可以针对异常的类型进行捕获,然后返回json信息到前端
+ */
+@ControllerAdvice
+public class GraceExceptionHandler {
+
+ @ExceptionHandler(MyCustomException.class)
+ @ResponseBody
+ public GraceJSONResult returnMyException(MyCustomException e) {
+ //e.printStackTrace();
+ return GraceJSONResult.exception(e.getResponseStatusEnum());
+ }
+
+ @ExceptionHandler(MethodArgumentNotValidException.class)
+ @ResponseBody
+ public GraceJSONResult returnMethodArgumentNotValid(MethodArgumentNotValidException e) {
+ BindingResult result = e.getBindingResult();
+ Map map = getErrors(result);
+ return GraceJSONResult.errorMap(map);
+ }
+
+ @ExceptionHandler(MaxUploadSizeExceededException.class)
+ @ResponseBody
+ public GraceJSONResult returnMaxUploadSize(MaxUploadSizeExceededException e) {
+// e.printStackTrace();
+ return GraceJSONResult.errorCustom(ResponseStatusEnum.FILE_MAX_SIZE_2MB_ERROR);
+ }
+
+ public Map getErrors(BindingResult result) {
+ Map map = new HashMap<>();
+ List errorList = result.getFieldErrors();
+ for (FieldError ff : errorList) {
+ // 错误所对应的属性字段名
+ String field = ff.getField();
+ // 错误的信息
+ String msg = ff.getDefaultMessage();
+ map.put(field, msg);
+ }
+ return map;
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/exceptions/MyCustomException.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/exceptions/MyCustomException.java
new file mode 100644
index 000000000..c8d9ac898
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/exceptions/MyCustomException.java
@@ -0,0 +1,28 @@
+package com.wzj.soopin.content.domain.exceptions;
+
+import com.imooc.grace.result.ResponseStatusEnum;
+
+/**
+ * 自定义异常
+ * 目的:统一处理异常信息
+ * 便于解耦,拦截器、service与controller 异常错误的解耦,
+ * 不会被service返回的类型而限制
+ */
+public class MyCustomException extends RuntimeException {
+
+ private ResponseStatusEnum responseStatusEnum;
+
+ public MyCustomException(ResponseStatusEnum responseStatusEnum) {
+ super("异常状态码为:" + responseStatusEnum.status()
+ + ";具体异常信息为:" + responseStatusEnum.msg());
+ this.responseStatusEnum = responseStatusEnum;
+ }
+
+ public ResponseStatusEnum getResponseStatusEnum() {
+ return responseStatusEnum;
+ }
+
+ public void setResponseStatusEnum(ResponseStatusEnum responseStatusEnum) {
+ this.responseStatusEnum = responseStatusEnum;
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/mo/MessageMO.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/mo/MessageMO.java
index a4a00d416..f7c4ac514 100644
--- a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/mo/MessageMO.java
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/mo/MessageMO.java
@@ -1,5 +1,6 @@
package com.wzj.soopin.content.domain.mo;
+import com.baomidou.mybatisplus.annotation.TableField;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -19,21 +20,21 @@ public class MessageMO {
@Id
private String id; // 消息主键id
- @Field("fromUserId")
+ @TableField("fromUserId")
private String fromUserId; // 消息来自的用户id
- @Field("fromNickname")
+ @TableField("fromNickname")
private String fromNickname; // 消息来自的用户昵称
- @Field("fromFace")
+ @TableField("fromFace")
private String fromFace; // 消息来自的用户头像
- @Field("toUserId")
+ @TableField("toUserId")
private String toUserId; // 消息发送到某对象的用户id
- @Field("msgType")
+ @TableField("msgType")
private Integer msgType; // 消息类型 枚举
- @Field("msgContent")
+ @TableField("msgContent")
private Map msgContent; // 消息内容
- @Field("createTime")
+ @TableField("createTime")
private Date createTime; // 消息创建时间
}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/result/GraceJSONResult.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/result/GraceJSONResult.java
new file mode 100644
index 000000000..28a8e0309
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/result/GraceJSONResult.java
@@ -0,0 +1,153 @@
+package com.wzj.soopin.content.domain.result;
+
+import java.util.Map;
+
+/**
+ * 自定义响应数据类型枚举升级版本
+ *
+ * @Title: IMOOCJSONResult.java
+ * @Package com.imooc.utils
+ * @Description: 自定义响应数据结构
+ * 本类可提供给 H5/ios/安卓/公众号/小程序 使用
+ * 前端接受此类数据(json object)后,可自行根据业务去实现相关功能
+ *
+ * @Copyright: Copyright (c) 2020
+ * @Company: www.imooc.com
+ * @author 慕课网 - 风间影月
+ * @version V2.0
+ */
+public class GraceJSONResult {
+
+ // 响应业务状态码
+ private Integer status;
+
+ // 响应消息
+ private String msg;
+
+ // 是否成功
+ private Boolean success;
+
+ // 响应数据,可以是Object,也可以是List或Map等
+ private Object data;
+
+ /**
+ * 成功返回,带有数据的,直接往OK方法丢data数据即可
+ * @param data
+ * @return
+ */
+ public static GraceJSONResult ok(Object data) {
+ return new GraceJSONResult(data);
+ }
+ /**
+ * 成功返回,不带有数据的,直接调用ok方法,data无须传入(其实就是null)
+ * @return
+ */
+ public static GraceJSONResult ok() {
+ return new GraceJSONResult(ResponseStatusEnum.SUCCESS);
+ }
+ public GraceJSONResult(Object data) {
+ this.status = ResponseStatusEnum.SUCCESS.status();
+ this.msg = ResponseStatusEnum.SUCCESS.msg();
+ this.success = ResponseStatusEnum.SUCCESS.success();
+ this.data = data;
+ }
+
+
+ /**
+ * 错误返回,直接调用error方法即可,当然也可以在ResponseStatusEnum中自定义错误后再返回也都可以
+ * @return
+ */
+ public static GraceJSONResult error() {
+ return new GraceJSONResult(ResponseStatusEnum.FAILED);
+ }
+
+ /**
+ * 错误返回,map中包含了多条错误信息,可以用于表单验证,把错误统一的全部返回出去
+ * @param map
+ * @return
+ */
+ public static GraceJSONResult errorMap(Map map) {
+ return new GraceJSONResult(ResponseStatusEnum.FAILED, map);
+ }
+
+ /**
+ * 错误返回,直接返回错误的消息
+ * @param msg
+ * @return
+ */
+ public static GraceJSONResult errorMsg(String msg) {
+ return new GraceJSONResult(ResponseStatusEnum.FAILED, msg);
+ }
+
+ /**
+ * 错误返回,token异常,一些通用的可以在这里统一定义
+ * @return
+ */
+ public static GraceJSONResult errorTicket() {
+ return new GraceJSONResult(ResponseStatusEnum.TICKET_INVALID);
+ }
+
+ /**
+ * 自定义错误范围,需要传入一个自定义的枚举,可以到[ResponseStatusEnum.java[中自定义后再传入
+ * @param responseStatus
+ * @return
+ */
+ public static GraceJSONResult errorCustom(ResponseStatusEnum responseStatus) {
+ return new GraceJSONResult(responseStatus);
+ }
+ public static GraceJSONResult exception(ResponseStatusEnum responseStatus) {
+ return new GraceJSONResult(responseStatus);
+ }
+
+ public GraceJSONResult(ResponseStatusEnum responseStatus) {
+ this.status = responseStatus.status();
+ this.msg = responseStatus.msg();
+ this.success = responseStatus.success();
+ }
+ public GraceJSONResult(ResponseStatusEnum responseStatus, Object data) {
+ this.status = responseStatus.status();
+ this.msg = responseStatus.msg();
+ this.success = responseStatus.success();
+ this.data = data;
+ }
+ public GraceJSONResult(ResponseStatusEnum responseStatus, String msg) {
+ this.status = responseStatus.status();
+ this.msg = msg;
+ this.success = responseStatus.success();
+ }
+
+ public GraceJSONResult() {
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public void setStatus(Integer status) {
+ this.status = status;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ public Object getData() {
+ return data;
+ }
+
+ public void setData(Object data) {
+ this.data = data;
+ }
+
+ public Boolean getSuccess() {
+ return success;
+ }
+
+ public void setSuccess(Boolean success) {
+ this.success = success;
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/result/IMOOCJSONResult.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/result/IMOOCJSONResult.java
new file mode 100644
index 000000000..cb7018f5c
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/result/IMOOCJSONResult.java
@@ -0,0 +1,135 @@
+package com.wzj.soopin.content.domain.result;
+
+/**
+ *
+ * @Title: IMOOCJSONResult.java
+ * @Package com.imooc.utils
+ * @Description: 自定义响应数据结构
+ * 本类可提供给 H5/ios/安卓/公众号/小程序 使用
+ * 前端接受此类数据(json object)后,可自行根据业务去实现相关功能
+ *
+ * 200:表示成功
+ * 500:表示错误,错误信息在msg字段中
+ * 501:bean验证错误,不管多少个错误都以map形式返回
+ * 502:拦截器拦截到用户token出错
+ * 555:异常抛出信息
+ * 556: 用户qq校验异常
+ * 557: 校验用户是否在CAS登录,用户门票的校验
+ * @Copyright: Copyright (c) 2020
+ * @Company: www.imooc.com
+ * @author 慕课网 - 风间影月
+ * @version V1.0
+ */
+public class IMOOCJSONResult {
+
+ // 响应业务状态
+ private Integer status;
+
+ // 响应消息
+ private String msg;
+
+ // 响应中的数据
+ private Object data;
+
+ private String ok; // 不使用
+
+ public static IMOOCJSONResult build(Integer status, String msg, Object data) {
+ return new IMOOCJSONResult(status, msg, data);
+ }
+
+ public static IMOOCJSONResult build(Integer status, String msg, Object data, String ok) {
+ return new IMOOCJSONResult(status, msg, data, ok);
+ }
+
+ public static IMOOCJSONResult ok(Object data) {
+ return new IMOOCJSONResult(data);
+ }
+
+ public static IMOOCJSONResult ok() {
+ return new IMOOCJSONResult(null);
+ }
+
+ public static IMOOCJSONResult errorMsg(String msg) {
+ return new IMOOCJSONResult(500, msg, null);
+ }
+
+ public static IMOOCJSONResult errorUserTicket(String msg) {
+ return new IMOOCJSONResult(557, msg, null);
+ }
+
+ public static IMOOCJSONResult errorMap(Object data) {
+ return new IMOOCJSONResult(501, "error", data);
+ }
+
+ public static IMOOCJSONResult errorTokenMsg(String msg) {
+ return new IMOOCJSONResult(502, msg, null);
+ }
+
+ public static IMOOCJSONResult errorException(String msg) {
+ return new IMOOCJSONResult(555, msg, null);
+ }
+
+ public static IMOOCJSONResult errorUserQQ(String msg) {
+ return new IMOOCJSONResult(556, msg, null);
+ }
+
+ public IMOOCJSONResult() {
+
+ }
+
+ public IMOOCJSONResult(Integer status, String msg, Object data) {
+ this.status = status;
+ this.msg = msg;
+ this.data = data;
+ }
+
+ public IMOOCJSONResult(Integer status, String msg, Object data, String ok) {
+ this.status = status;
+ this.msg = msg;
+ this.data = data;
+ this.ok = ok;
+ }
+
+ public IMOOCJSONResult(Object data) {
+ this.status = 200;
+ this.msg = "OK";
+ this.data = data;
+ }
+
+ public Boolean isOK() {
+ return this.status == 200;
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public void setStatus(Integer status) {
+ this.status = status;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ public Object getData() {
+ return data;
+ }
+
+ public void setData(Object data) {
+ this.data = data;
+ }
+
+ public String getOk() {
+ return ok;
+ }
+
+ public void setOk(String ok) {
+ this.ok = ok;
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/result/ResponseStatusEnum.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/result/ResponseStatusEnum.java
new file mode 100644
index 000000000..14dbb5638
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/domain/result/ResponseStatusEnum.java
@@ -0,0 +1,108 @@
+package com.wzj.soopin.content.domain.result;
+
+/**
+ * 响应结果枚举,用于提供给GraceJSONResult返回给前端的
+ * 本枚举类中包含了很多的不同的状态码供使用,可以自定义
+ * 便于更优雅的对状态码进行管理,一目了然
+ */
+public enum ResponseStatusEnum {
+
+ SUCCESS(200, true, "操作成功!"),
+ FAILED(500, false, "操作失败!"),
+ ON_BLOCK(201,false,"用户已被拉黑"),
+ // 50x
+ UN_LOGIN(501,false,"请登录后再继续操作!"),
+ TICKET_INVALID(502,false,"会话失效,请重新登录!"),
+ NO_AUTH(503,false,"您的权限不足,无法继续操作!"),
+ MOBILE_ERROR(504,false,"短信发送失败,请稍后重试!"),
+ SMS_NEED_WAIT_ERROR(505,false,"短信发送太快啦~请稍后再试!"),
+ SMS_CODE_ERROR(506,false,"验证码过期或不匹配,请稍后再试!"),
+ USER_FROZEN(507,false,"用户已被冻结,请联系管理员!"),
+ USER_UPDATE_ERROR(508,false,"用户信息更新失败,请联系管理员!"),
+ USER_INACTIVE_ERROR(509,false,"请前往[账号设置]修改信息激活后再进行后续操作!"),
+ USER_INFO_UPDATED_ERROR(5091,false,"用户信息修改失败!"),
+ USER_INFO_UPDATED_NICKNAME_EXIST_ERROR(5092,false,"昵称已经存在!"),
+ FANS_INFO_UPDATED_ISFAN_EXIST_ERROR(5092,false,"已关注"),
+ FANS_INFO_UPDATED_ISFLOW_EXIST_ERROR(5092,false,"未关注"),
+ USER_INFO_UPDATED_IMOOCNUM_EXIST_ERROR(5092,false,"视频号已经存在!"),
+ USER_INFO_CANT_UPDATED_IMOOCNUM_ERROR(5092,false,"视频号无法修改!"),
+ FILE_UPLOAD_NULL_ERROR(510,false,"文件不能为空,请选择一个文件再上传!"),
+ FILE_UPLOAD_FAILD(511,false,"文件上传失败!"),
+ FILE_FORMATTER_FAILD(512,false,"文件图片格式不支持!"),
+ FILE_MAX_SIZE_500KB_ERROR(5131,false,"仅支持500kb大小以下的图片上传!"),
+ FILE_MAX_SIZE_2MB_ERROR(5132,false,"仅支持2MB大小以下的图片上传!"),
+ FILE_NOT_EXIST_ERROR(514,false,"你所查看的文件不存在!"),
+ USER_STATUS_ERROR(515,false,"用户状态参数出错!"),
+ USER_NOT_EXIST_ERROR(516,false,"用户不存在!"),
+ USER_PASSWORD_ERROR(517,false,"密码错误!"),
+
+ // 自定义系统级别异常 54x
+ SYSTEM_INDEX_OUT_OF_BOUNDS(541, false, "系统错误,数组越界!"),
+ SYSTEM_ARITHMETIC_BY_ZERO(542, false, "系统错误,无法除零!"),
+ SYSTEM_NULL_POINTER(543, false, "系统错误,空指针!"),
+ SYSTEM_NUMBER_FORMAT(544, false, "系统错误,数字转换异常!"),
+ SYSTEM_PARSE(545, false, "系统错误,解析异常!"),
+ SYSTEM_IO(546, false, "系统错误,IO输入输出异常!"),
+ SYSTEM_FILE_NOT_FOUND(547, false, "系统错误,文件未找到!"),
+ SYSTEM_CLASS_CAST(548, false, "系统错误,类型强制转换错误!"),
+ SYSTEM_PARSER_ERROR(549, false, "系统错误,解析出错!"),
+ SYSTEM_DATE_PARSER_ERROR(550, false, "系统错误,日期解析出错!"),
+
+ // admin 管理系统 56x
+ ADMIN_USERNAME_NULL_ERROR(561, false, "管理员登录名不能为空!"),
+ ADMIN_USERNAME_EXIST_ERROR(562, false, "管理员登录名已存在!"),
+ ADMIN_NAME_NULL_ERROR(563, false, "管理员负责人不能为空!"),
+ ADMIN_PASSWORD_ERROR(564, false, "密码不能为空后者两次输入不一致!"),
+ ADMIN_CREATE_ERROR(565, false, "添加管理员失败!"),
+ ADMIN_PASSWORD_NULL_ERROR(566, false, "密码不能为空!"),
+ ADMIN_NOT_EXIT_ERROR(567, false, "管理员不存在或密码错误!"),
+ ADMIN_FACE_NULL_ERROR(568, false, "人脸信息不能为空!"),
+ ADMIN_FACE_LOGIN_ERROR(569, false, "人脸识别失败,请重试!"),
+ CATEGORY_EXIST_ERROR(570, false, "文章分类已存在,请换一个分类名!"),
+
+ // 媒体中心 相关错误 58x
+ ARTICLE_COVER_NOT_EXIST_ERROR(580, false, "文章封面不存在,请选择一个!"),
+ ARTICLE_CATEGORY_NOT_EXIST_ERROR(581, false, "请选择正确的文章领域!"),
+ ARTICLE_CREATE_ERROR(582, false, "创建文章失败,请重试或联系管理员!"),
+ ARTICLE_QUERY_PARAMS_ERROR(583, false, "文章列表查询参数错误!"),
+ ARTICLE_DELETE_ERROR(584, false, "文章删除失败!"),
+ ARTICLE_WITHDRAW_ERROR(585, false, "文章撤回失败!"),
+ ARTICLE_REVIEW_ERROR(585, false, "文章审核出错!"),
+ ARTICLE_ALREADY_READ_ERROR(586, false, "文章重复阅读!"),
+
+ // 人脸识别错误代码
+ FACE_VERIFY_TYPE_ERROR(600, false, "人脸比对验证类型不正确!"),
+ FACE_VERIFY_LOGIN_ERROR(601, false, "人脸登录失败!"),
+
+ // 系统错误,未预期的错误 555
+ SYSTEM_ERROR(555, false, "系统繁忙,请稍后再试!"),
+ SYSTEM_OPERATION_ERROR(556, false, "操作失败,请重试或联系管理员"),
+ SYSTEM_RESPONSE_NO_INFO(557, false, ""),
+ SYSTEM_ERROR_GLOBAL(558, false, "全局降级:系统繁忙,请稍后再试!"),
+ SYSTEM_ERROR_FEIGN(559, false, "客户端Feign降级:系统繁忙,请稍后再试!"),
+ SYSTEM_ERROR_ZUUL(560, false, "请求系统过于繁忙,请稍后再试!");
+
+
+ // 响应业务状态
+ private Integer status;
+ // 调用是否成功
+ private Boolean success;
+ // 响应消息,可以为成功或者失败的消息
+ private String msg;
+
+ ResponseStatusEnum(Integer status, Boolean success, String msg) {
+ this.status = status;
+ this.success = success;
+ this.msg = msg;
+ }
+
+ public Integer status() {
+ return status;
+ }
+ public Boolean success() {
+ return success;
+ }
+ public String msg() {
+ return msg;
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/FileTypeEnum.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/FileTypeEnum.java
new file mode 100644
index 000000000..14379f4da
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/FileTypeEnum.java
@@ -0,0 +1,17 @@
+package com.wzj.soopin.content.enums;
+
+/**
+ * @Desc: 文件类型 枚举
+ */
+public enum FileTypeEnum {
+ BGIMG(1, "用户背景图"),
+ FACE(2, "用户头像");
+
+ public final Integer type;
+ public final String value;
+
+ FileTypeEnum(Integer type, String value) {
+ this.type = type;
+ this.value = value;
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/MessageEnum.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/MessageEnum.java
new file mode 100644
index 000000000..32a0f7386
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/MessageEnum.java
@@ -0,0 +1,22 @@
+package com.wzj.soopin.content.enums;
+
+/**
+ * @Desc: 消息类型
+ */
+public enum MessageEnum {
+ FOLLOW_YOU(1, "关注", "follow"),
+ LIKE_VLOG(2, "点赞视频", "likeVideo"),
+ COMMENT_VLOG(3, "评论视频", "comment"),
+ REPLY_YOU(4, "回复评论", "replay"),
+ LIKE_COMMENT(5, "点赞评论", "likeComment");
+
+ public final Integer type;
+ public final String value;
+ public final String enValue;
+
+ MessageEnum(Integer type, String value, String enValue) {
+ this.type = type;
+ this.value = value;
+ this.enValue = enValue;
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/Sex.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/Sex.java
new file mode 100644
index 000000000..1e1d33831
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/Sex.java
@@ -0,0 +1,18 @@
+package com.wzj.soopin.content.enums;
+
+/**
+ * @Desc: 性别 枚举
+ */
+public enum Sex {
+ woman(0, "女"),
+ man(1, "男"),
+ secret(2, "保密");
+
+ public final Integer type;
+ public final String value;
+
+ Sex(Integer type, String value) {
+ this.type = type;
+ this.value = value;
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/UserInfoModifyType.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/UserInfoModifyType.java
new file mode 100644
index 000000000..ae29d469a
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/UserInfoModifyType.java
@@ -0,0 +1,35 @@
+package com.wzj.soopin.content.enums;
+
+import com.imooc.exceptions.GraceException;
+import com.imooc.grace.result.ResponseStatusEnum;
+
+/**
+ * @Desc: 修改用户信息类型 枚举
+ */
+public enum UserInfoModifyType {
+ NICKNAME(1, "昵称"),
+ IMOOCNUM(2, "慕课号"),
+ SEX(3, "性别"),
+ BIRTHDAY(4, "生日"),
+ LOCATION(5, "所在地"),
+ DESC(6, "简介");
+
+ public final Integer type;
+ public final String value;
+
+ UserInfoModifyType(Integer type, String value) {
+ this.type = type;
+ this.value = value;
+ }
+
+ public static void checkUserInfoTypeIsRight(Integer type) {
+ if (type != UserInfoModifyType.NICKNAME.type &&
+ type != UserInfoModifyType.IMOOCNUM.type &&
+ type != UserInfoModifyType.SEX.type &&
+ type != UserInfoModifyType.BIRTHDAY.type &&
+ type != UserInfoModifyType.LOCATION.type &&
+ type != UserInfoModifyType.DESC.type) {
+ GraceException.display(ResponseStatusEnum.USER_INFO_UPDATED_ERROR);
+ }
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/YesOrNo.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/YesOrNo.java
new file mode 100644
index 000000000..4d0a0d643
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/enums/YesOrNo.java
@@ -0,0 +1,17 @@
+package com.wzj.soopin.content.enums;
+
+/**
+ * @Desc: 是否 枚举
+ */
+public enum YesOrNo {
+ NO(0, "否"),
+ YES(1, "是");
+
+ public final Integer type;
+ public final String value;
+
+ YesOrNo(Integer type, String value) {
+ this.type = type;
+ this.value = value;
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/Code.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/Code.java
new file mode 100644
index 000000000..13cc01c81
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/Code.java
@@ -0,0 +1,35 @@
+package com.wzj.soopin.content.idworker;
+
+import org.n3r.idworker.strategy.DefaultRandomCodeStrategy;
+
+public class Code {
+ private static RandomCodeStrategy strategy;
+
+ static {
+ RandomCodeStrategy strategy = new DefaultRandomCodeStrategy();
+ strategy.init();
+ configure(strategy);
+ }
+
+ public static synchronized void configure(RandomCodeStrategy custom) {
+ if (strategy == custom) return;
+ if (strategy != null) strategy.release();
+
+ strategy = custom;
+ }
+
+ /**
+ * Next Unique code.
+ * The max length will be 1024-Integer.MAX-Integer.MAX(2147483647) which has 4+10+10+2*1=26 characters.
+ * The min length will be 0-0.
+ *
+ * @return unique string code.
+ */
+ public static synchronized String next() {
+ long workerId = Id.getWorkerId();
+ int prefix = strategy.prefix();
+ int next = strategy.next();
+
+ return String.format("%d-%03d-%06d", workerId, prefix, next);
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/DayCode.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/DayCode.java
new file mode 100644
index 000000000..f9170b651
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/DayCode.java
@@ -0,0 +1,19 @@
+package com.wzj.soopin.content.idworker;
+
+import org.n3r.idworker.strategy.DayPrefixRandomCodeStrategy;
+
+public class DayCode {
+ static RandomCodeStrategy strategy;
+
+ static {
+ DayPrefixRandomCodeStrategy dayPrefixCodeStrategy = new DayPrefixRandomCodeStrategy("yyMM");
+ dayPrefixCodeStrategy.setMinRandomSize(7);
+ dayPrefixCodeStrategy.setMaxRandomSize(7);
+ strategy = dayPrefixCodeStrategy;
+ strategy.init();
+ }
+
+ public static synchronized String next() {
+ return String.format("%d-%04d-%07d", Id.getWorkerId(), strategy.prefix(), strategy.next());
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/Id.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/Id.java
new file mode 100644
index 000000000..9368a15c0
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/Id.java
@@ -0,0 +1,29 @@
+package com.wzj.soopin.content.idworker;
+
+import org.n3r.idworker.strategy.DefaultWorkerIdStrategy;
+
+public class Id {
+ private static WorkerIdStrategy workerIdStrategy;
+ private static IdWorker idWorker;
+
+ static {
+ configure(DefaultWorkerIdStrategy.instance);
+ }
+
+ public static synchronized void configure(WorkerIdStrategy custom) {
+ if (workerIdStrategy == custom) return;
+
+ if (workerIdStrategy != null) workerIdStrategy.release();
+ workerIdStrategy = custom;
+ workerIdStrategy.initialize();
+ idWorker = new IdWorker(workerIdStrategy.availableWorkerId());
+ }
+
+ public static long next() {
+ return idWorker.nextId();
+ }
+
+ public static long getWorkerId() {
+ return idWorker.getWorkerId();
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/IdWorker.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/IdWorker.java
new file mode 100644
index 000000000..235b1a314
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/IdWorker.java
@@ -0,0 +1,91 @@
+package com.wzj.soopin.content.idworker;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.security.SecureRandom;
+
+public class IdWorker {
+ protected long epoch = 1288834974657L;
+// protected long epoch = 1387886498127L; // 2013-12-24 20:01:38.127
+
+
+ protected long workerIdBits = 10L;
+ protected long maxWorkerId = -1L ^ (-1L << workerIdBits);
+ protected long sequenceBits = 11L;
+
+ protected long workerIdShift = sequenceBits;
+ protected long timestampLeftShift = sequenceBits + workerIdBits;
+ protected long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+ protected long lastMillis = -1L;
+
+ protected final long workerId;
+ protected long sequence = 0L;
+ protected Logger logger = LoggerFactory.getLogger(IdWorker.class);
+
+ public IdWorker(long workerId) {
+ this.workerId = checkWorkerId(workerId);
+
+ logger.debug("worker starting. timestamp left shift {}, worker id {}", timestampLeftShift, workerId);
+ }
+
+ public long getEpoch() {
+ return epoch;
+ }
+
+ private long checkWorkerId(long workerId) {
+ // sanity check for workerId
+ if (workerId > maxWorkerId || workerId < 0) {
+ int rand = new SecureRandom().nextInt((int) maxWorkerId + 1);
+ logger.warn("worker Id can't be greater than {} or less than 0, use a random {}", maxWorkerId, rand);
+ return rand;
+ }
+
+ return workerId;
+ }
+
+ public synchronized long nextId() {
+ long timestamp = millisGen();
+
+ if (timestamp < lastMillis) {
+ logger.error("clock is moving backwards. Rejecting requests until {}.", lastMillis);
+ throw new InvalidSystemClock(String.format(
+ "Clock moved backwards. Refusing to generate id for {} milliseconds", lastMillis - timestamp));
+ }
+
+ if (lastMillis == timestamp) {
+ sequence = (sequence + 1) & sequenceMask;
+ if (sequence == 0)
+ timestamp = tilNextMillis(lastMillis);
+ } else {
+ sequence = 0;
+ }
+
+ lastMillis = timestamp;
+ long diff = timestamp - getEpoch();
+ return (diff << timestampLeftShift) |
+ (workerId << workerIdShift) |
+ sequence;
+ }
+
+ protected long tilNextMillis(long lastMillis) {
+ long millis = millisGen();
+ while (millis <= lastMillis)
+ millis = millisGen();
+
+ return millis;
+ }
+
+ protected long millisGen() {
+ return System.currentTimeMillis();
+ }
+
+ public long getLastMillis() {
+ return lastMillis;
+ }
+
+ public long getWorkerId() {
+ return workerId;
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/InvalidSystemClock.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/InvalidSystemClock.java
new file mode 100644
index 000000000..f83465a20
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/InvalidSystemClock.java
@@ -0,0 +1,7 @@
+package com.wzj.soopin.content.idworker;
+
+public class InvalidSystemClock extends RuntimeException {
+ public InvalidSystemClock(String message) {
+ super(message);
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/RandomCodeStrategy.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/RandomCodeStrategy.java
new file mode 100644
index 000000000..6a25fbeb0
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/RandomCodeStrategy.java
@@ -0,0 +1,11 @@
+package com.wzj.soopin.content.idworker;
+
+public interface RandomCodeStrategy {
+ void init();
+
+ int prefix();
+
+ int next();
+
+ void release();
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/Sid.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/Sid.java
new file mode 100644
index 000000000..de0a5329f
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/Sid.java
@@ -0,0 +1,64 @@
+package com.wzj.soopin.content.idworker;
+
+import org.n3r.idworker.strategy.DefaultWorkerIdStrategy;
+import org.n3r.idworker.utils.Utils;
+import org.springframework.stereotype.Component;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+@Component
+public class Sid {
+ private static WorkerIdStrategy workerIdStrategy;
+ private static IdWorker idWorker;
+
+ static {
+ configure(DefaultWorkerIdStrategy.instance);
+ }
+
+
+ public static synchronized void configure(WorkerIdStrategy custom) {
+ if (workerIdStrategy != null) {
+ workerIdStrategy.release();
+ }
+ workerIdStrategy = custom;
+ idWorker = new IdWorker(workerIdStrategy.availableWorkerId()) {
+ @Override
+ public long getEpoch() {
+ return Utils.midnightMillis();
+ }
+ };
+ }
+
+ /**
+ * 一天最大毫秒86400000,最大占用27比特
+ * 27+10+11=48位 最大值281474976710655(15字),YK0XXHZ827(10字)
+ * 6位(YYMMDD)+15位,共21位
+ *
+ * @return 固定21位数字字符串
+ */
+
+ public static String next() {
+ long id = idWorker.nextId();
+ String yyMMdd = new SimpleDateFormat("yyMMdd").format(new Date());
+ return yyMMdd + String.format("%014d", id);
+ }
+
+
+ /**
+ * 返回固定16位的字母数字混编的字符串。
+ */
+ public String nextShort() {
+ long id = idWorker.nextId();
+ String yyMMdd = new SimpleDateFormat("yyMMdd").format(new Date());
+ return yyMMdd + Utils.padLeft(Utils.encode(id), 10, '0');
+ }
+
+ public static void main(String[] args) {
+ String aa = new Sid().nextShort();
+ String bb = new Sid().next();
+
+ System.out.println(aa);
+ System.out.println(bb);
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/Test.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/Test.java
new file mode 100644
index 000000000..cd6f73523
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/Test.java
@@ -0,0 +1,12 @@
+package com.wzj.soopin.content.idworker;
+
+public class Test {
+
+ public static void main(String[] args) {
+
+ for (int i = 0 ; i < 1000 ; i ++) {
+// System.out.println(Sid.nextShort());
+ }
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/WorkerIdStrategy.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/WorkerIdStrategy.java
new file mode 100644
index 000000000..6bd66ff3b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/WorkerIdStrategy.java
@@ -0,0 +1,9 @@
+package com.wzj.soopin.content.idworker;
+
+public interface WorkerIdStrategy {
+ void initialize();
+
+ long availableWorkerId();
+
+ void release();
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/strategy/DayPrefixRandomCodeStrategy.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/strategy/DayPrefixRandomCodeStrategy.java
new file mode 100644
index 000000000..7f1981afe
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/strategy/DayPrefixRandomCodeStrategy.java
@@ -0,0 +1,41 @@
+package com.wzj.soopin.content.idworker.strategy;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class DayPrefixRandomCodeStrategy extends DefaultRandomCodeStrategy {
+ private final String dayFormat;
+ private String lastDay;
+
+ public DayPrefixRandomCodeStrategy(String dayFormat) {
+ this.dayFormat = dayFormat;
+ }
+
+ @Override
+ public void init() {
+ String day = createDate();
+ if (day.equals(lastDay))
+ throw new RuntimeException("init failed for day unrolled");
+
+ lastDay = day;
+
+ availableCodes.clear();
+ release();
+
+ prefixIndex = Integer.parseInt(lastDay);
+ if (tryUsePrefix()) return;
+
+ throw new RuntimeException("prefix is not available " + prefixIndex);
+ }
+
+ private String createDate() {
+ return new SimpleDateFormat(dayFormat).format(new Date());
+ }
+
+ @Override
+ public int next() {
+ if (!lastDay.equals(createDate())) init();
+
+ return super.next();
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/strategy/DefaultRandomCodeStrategy.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/strategy/DefaultRandomCodeStrategy.java
new file mode 100644
index 000000000..f903942cb
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/strategy/DefaultRandomCodeStrategy.java
@@ -0,0 +1,197 @@
+package com.wzj.soopin.content.idworker.strategy;
+
+import org.n3r.idworker.Id;
+import org.n3r.idworker.RandomCodeStrategy;
+import org.n3r.idworker.utils.Utils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.SecureRandom;
+import java.util.ArrayDeque;
+import java.util.BitSet;
+import java.util.Queue;
+
+public class DefaultRandomCodeStrategy implements RandomCodeStrategy {
+ public static final int MAX_BITS = 1000000;
+
+ Logger log = LoggerFactory.getLogger(DefaultRandomCodeStrategy.class);
+
+ File idWorkerHome = Utils.createIdWorkerHome();
+ volatile FileLock fileLock;
+ BitSet codesFilter;
+
+ int prefixIndex = -1;
+ File codePrefixIndex;
+
+ int minRandomSize = 6;
+ int maxRandomSize = 6;
+
+ public DefaultRandomCodeStrategy() {
+ destroyFileLockWhenShutdown();
+ }
+
+ @Override
+ public void init() {
+ release();
+
+ while (++prefixIndex < 1000) {
+ if (tryUsePrefix()) return;
+ }
+
+ throw new RuntimeException("all prefixes are used up, the world maybe ends!");
+ }
+
+ public DefaultRandomCodeStrategy setMinRandomSize(int minRandomSize) {
+ this.minRandomSize = minRandomSize;
+ return this;
+ }
+
+ public DefaultRandomCodeStrategy setMaxRandomSize(int maxRandomSize) {
+ this.maxRandomSize = maxRandomSize;
+ return this;
+ }
+
+ protected boolean tryUsePrefix() {
+ codePrefixIndex = new File(idWorkerHome, Id.getWorkerId() + ".code.prefix." + prefixIndex);
+
+ if (!createPrefixIndexFile()) return false;
+ if (!createFileLock()) return false;
+ if (!createBloomFilter()) return false;
+
+ log.info("get available prefix index file {}", codePrefixIndex);
+
+ return true;
+ }
+
+ private boolean createFileLock() {
+ if (fileLock != null) fileLock.destroy();
+ fileLock = new FileLock(codePrefixIndex);
+ return fileLock.tryLock();
+ }
+
+ private boolean createBloomFilter() {
+ codesFilter = fileLock.readObject();
+ if (codesFilter == null) {
+ log.info("create new bloom filter");
+ codesFilter = new BitSet(MAX_BITS); // 2^24
+ } else {
+ int size = codesFilter.cardinality();
+ if (size >= MAX_BITS) {
+ log.warn("bloom filter with prefix file {} is already full", codePrefixIndex);
+ return false;
+ }
+ log.info("recreate bloom filter with cardinality {}", size);
+ }
+
+ return true;
+ }
+
+ private void destroyFileLockWhenShutdown() {
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ release();
+ }
+ });
+ }
+
+ private boolean createPrefixIndexFile() {
+ try {
+ codePrefixIndex.createNewFile();
+ return codePrefixIndex.exists();
+ } catch (IOException e) {
+ e.printStackTrace();
+ log.warn("create file {} error {}", codePrefixIndex, e.getMessage());
+ }
+ return false;
+ }
+
+ @Override
+ public int prefix() {
+ return prefixIndex;
+ }
+
+ static final int CACHE_CODES_NUM = 1000;
+
+ SecureRandom secureRandom = new SecureRandom();
+ Queue availableCodes = new ArrayDeque(CACHE_CODES_NUM);
+
+ @Override
+ public int next() {
+ if (availableCodes.isEmpty()) generate();
+
+ return availableCodes.poll();
+ }
+
+ @Override
+ public synchronized void release() {
+ if (fileLock != null) {
+ fileLock.writeObject(codesFilter);
+ fileLock.destroy();
+ fileLock = null;
+ }
+ }
+
+ private void generate() {
+ for (int i = 0; i < CACHE_CODES_NUM; ++i)
+ availableCodes.add(generateOne());
+
+ fileLock.writeObject(codesFilter);
+ }
+
+ private int generateOne() {
+ while (true) {
+ int code = secureRandom.nextInt(max(maxRandomSize));
+ boolean existed = contains(code);
+
+ code = !existed ? add(code) : tryFindAvailableCode(code);
+ if (code >= 0) return code;
+
+ init();
+ }
+ }
+
+ private int tryFindAvailableCode(int code) {
+ int next = codesFilter.nextClearBit(code);
+ if (next != -1 && next < max(maxRandomSize)) return add(next);
+
+ next = codesFilter.previousClearBit(code);
+ if (next != -1) return add(next);
+
+ return -1;
+ }
+
+ private int add(int code) {
+ codesFilter.set(code);
+ return code;
+ }
+
+ private boolean contains(int code) {
+ return codesFilter.get(code);
+ }
+
+
+ private int max(int size) {
+ switch (size) {
+ case 1: // fall through
+ case 2: // fall through
+ case 3: // fall through
+ case 4:
+ return 10000;
+ case 5:
+ return 100000;
+ case 6:
+ return 1000000;
+ case 7:
+ return 10000000;
+ case 8:
+ return 100000000;
+ case 9:
+ return 1000000000;
+ default:
+ return Integer.MAX_VALUE;
+ }
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/strategy/DefaultWorkerIdStrategy.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/strategy/DefaultWorkerIdStrategy.java
new file mode 100644
index 000000000..b0372941c
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/strategy/DefaultWorkerIdStrategy.java
@@ -0,0 +1,205 @@
+package com.wzj.soopin.content.idworker.strategy;
+
+import org.n3r.idworker.WorkerIdStrategy;
+import org.n3r.idworker.utils.HttpReq;
+import org.n3r.idworker.utils.Ip;
+import org.n3r.idworker.utils.Props;
+import org.n3r.idworker.utils.Utils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.SecureRandom;
+import java.util.Properties;
+import java.util.Random;
+
+public class DefaultWorkerIdStrategy implements WorkerIdStrategy {
+ static long workerIdBits = 10L;
+ static long maxWorkerId = -1L ^ (-1L << workerIdBits);
+ static Random random = new SecureRandom();
+
+ public static final WorkerIdStrategy instance = new DefaultWorkerIdStrategy();
+
+ private final Properties props =
+ Props.tryProperties("idworker-client.properties", Utils.DOT_IDWORKERS);
+ private final String idWorkerServerUrl =
+ props.getProperty("server.address", "http://id.worker.server:18001");
+
+ String userName = System.getProperty("user.name");
+
+ String ipDotUsername = Ip.ip + "." + userName;
+ String ipudotlock = ipDotUsername + ".lock.";
+ int workerIdIndex = ipudotlock.length();
+ long workerId;
+ FileLock fileLock;
+
+ Logger logger = LoggerFactory.getLogger(DefaultWorkerIdStrategy.class);
+ private boolean inited;
+
+
+ private void init() {
+ workerId = findAvailWorkerId();
+ if (workerId >= 0) {
+ destroyFileLockWhenShutdown();
+ startSyncThread();
+ } else {
+ syncWithWorkerIdServer();
+ workerId = findAvailWorkerId();
+ if (workerId < 0) workerId = increaseWithWorkerIdServer();
+ }
+
+ if (workerId < 0) workerId = tryToCreateOnIp();
+ if (workerId < 0) {
+ logger.warn("DANGEROUS!!! Try to use random worker id.");
+ workerId = tryToRandomOnIp(); // Try avoiding! it could cause duplicated
+ }
+
+ if (workerId < 0) {
+ logger.warn("the world may be ended!");
+ throw new RuntimeException("the world may be ended");
+ }
+ }
+
+ private void destroyFileLockWhenShutdown() {
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ fileLock.destroy();
+ }
+ });
+ }
+
+ private void startSyncThread() {
+ new Thread() {
+ @Override
+ public void run() {
+ syncWithWorkerIdServer();
+ }
+ }.start();
+ }
+
+ private long increaseWithWorkerIdServer() {
+ String incId = HttpReq.get(idWorkerServerUrl)
+ .req("/inc")
+ .param("ipu", ipDotUsername)
+ .exec();
+ if (incId == null || incId.trim().isEmpty()) return -1L;
+
+ long lid = Long.parseLong(incId);
+
+ return checkAvail(lid);
+ }
+
+ private long tryToCreateOnIp() {
+ long wid = Ip.lip & maxWorkerId;
+
+ return checkAvail(wid);
+ }
+
+ private long tryToRandomOnIp() {
+ long avaiWorkerId = -1L;
+ long tryTimes = -1;
+
+ while (avaiWorkerId < 0 && ++tryTimes < maxWorkerId) {
+ long wid = Ip.lip & random.nextInt((int) maxWorkerId);
+
+ avaiWorkerId = checkAvail(wid);
+ }
+ return avaiWorkerId;
+ }
+
+ private long checkAvail(long wid) {
+ long availWorkerId = -1L;
+ try {
+ File idWorkerHome = Utils.createIdWorkerHome();
+ new File(idWorkerHome, ipudotlock + String.format("%04d", wid)).createNewFile();
+ availWorkerId = findAvailWorkerId();
+ } catch (IOException e) {
+ logger.warn("checkAvail error", e);
+ }
+
+ return availWorkerId;
+ }
+
+ private void syncWithWorkerIdServer() {
+ String syncIds = HttpReq.get(idWorkerServerUrl).req("/sync")
+ .param("ipu", ipDotUsername).param("ids", buildWorkerIdsOfCurrentIp())
+ .exec();
+ if (syncIds == null || syncIds.trim().isEmpty()) return;
+
+ String[] syncIdsArr = syncIds.split(",");
+ File idWorkerHome = Utils.createIdWorkerHome();
+ for (String syncId : syncIdsArr) {
+ try {
+ new File(idWorkerHome, ipudotlock + syncId).createNewFile();
+ } catch (IOException e) {
+ logger.warn("create workerid lock file error", e);
+ }
+ }
+ }
+
+ private String buildWorkerIdsOfCurrentIp() {
+ StringBuilder sb = new StringBuilder();
+ File idWorkerHome = Utils.createIdWorkerHome();
+ for (File lockFile : idWorkerHome.listFiles()) {
+ // check the format like 10.142.1.151.lock.0001
+ if (!lockFile.getName().startsWith(ipudotlock)) continue;
+
+ String workerId = lockFile.getName().substring(workerIdIndex);
+ if (!workerId.matches("\\d\\d\\d\\d")) continue;
+
+ if (sb.length() > 0) sb.append(',');
+ sb.append(workerId);
+ }
+
+ return sb.toString();
+ }
+
+
+ /**
+ * Find the local available worker id.
+ *
+ * @return -1 when N/A
+ */
+ private long findAvailWorkerId() {
+ File idWorkerHome = Utils.createIdWorkerHome();
+
+ for (File lockFile : idWorkerHome.listFiles()) {
+ // check the format like 10.142.1.151.lock.0001
+ if (!lockFile.getName().startsWith(ipudotlock)) continue;
+
+ String workerId = lockFile.getName().substring(workerIdIndex);
+ if (!workerId.matches("\\d\\d\\d\\d")) continue;
+
+ FileLock fileLock = new FileLock(lockFile);
+ if (!fileLock.tryLock()) {
+ fileLock.destroy();
+ continue;
+ }
+
+ this.fileLock = fileLock;
+ return Long.parseLong(workerId);
+ }
+
+ return -1;
+ }
+
+ @Override
+ public void initialize() {
+ if (inited) return;
+ init();
+ this.inited = true;
+ }
+
+ @Override
+ public long availableWorkerId() {
+ return workerId;
+ }
+
+ @Override
+ public void release() {
+ if (fileLock != null) fileLock.destroy();
+ inited = false;
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/strategy/FileLock.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/strategy/FileLock.java
new file mode 100644
index 000000000..04017ab84
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/strategy/FileLock.java
@@ -0,0 +1,132 @@
+package com.wzj.soopin.content.idworker.strategy;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.nio.channels.Channels;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.OverlappingFileLockException;
+
+/**
+ * A file lock a la flock/funlock
+ *
+ * The given path will be created and opened if it doesn't exist.
+ */
+public class FileLock {
+ private final File file;
+ private FileChannel channel;
+ private java.nio.channels.FileLock flock = null;
+ Logger logger = LoggerFactory.getLogger(FileLock.class);
+
+ public FileLock(File file) {
+ this.file = file;
+
+ try {
+ file.createNewFile(); // create the file if it doesn't exist
+ channel = new RandomAccessFile(file, "rw").getChannel();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ /**
+ * Lock the file or throw an exception if the lock is already held
+ */
+ public void lock() {
+ try {
+ synchronized (this) {
+ logger.trace("Acquiring lock on {}", file.getAbsolutePath());
+ flock = channel.lock();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Try to lock the file and return true if the locking succeeds
+ */
+ public boolean tryLock() {
+ synchronized (this) {
+ logger.trace("Acquiring lock on {}", file.getAbsolutePath());
+ try {
+ // weirdly this method will return null if the lock is held by another
+ // process, but will throw an exception if the lock is held by this process
+ // so we have to handle both cases
+ flock = channel.tryLock();
+ return flock != null;
+ } catch (OverlappingFileLockException e) {
+ return false;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * Unlock the lock if it is held
+ */
+ public void unlock() {
+ synchronized (this) {
+ logger.trace("Releasing lock on {}", file.getAbsolutePath());
+ if (flock == null) return;
+ try {
+ flock.release();
+ } catch (ClosedChannelException e) {
+ // Ignore
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * Destroy this lock, closing the associated FileChannel
+ */
+ public void destroy() {
+ synchronized (this) {
+ unlock();
+ if (!channel.isOpen()) return;
+
+ try {
+ channel.close();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public T readObject() {
+ try {
+ InputStream is = Channels.newInputStream(channel);
+ ObjectInputStream objectReader = new ObjectInputStream(is);
+ return (T) objectReader.readObject();
+ } catch (EOFException e) {
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ return null;
+ }
+
+
+ public synchronized boolean writeObject(Object object) {
+ if (!channel.isOpen()) return false;
+
+ try {
+ channel.position(0);
+ OutputStream out = Channels.newOutputStream(channel);
+ ObjectOutputStream objectOutput = new ObjectOutputStream(out);
+ objectOutput.writeObject(object);
+ return true;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/HttpReq.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/HttpReq.java
new file mode 100644
index 000000000..5218ae0e3
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/HttpReq.java
@@ -0,0 +1,115 @@
+package com.wzj.soopin.content.idworker.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+
+public class HttpReq {
+ private final String baseUrl;
+ private String req;
+ private StringBuilder params = new StringBuilder();
+ Logger logger = LoggerFactory.getLogger(HttpReq.class);
+
+ public HttpReq(String baseUrl) {
+ this.baseUrl = baseUrl;
+ }
+
+ public static HttpReq get(String baseUrl) {
+ return new HttpReq(baseUrl);
+ }
+
+ public HttpReq req(String req) {
+ this.req = req;
+ return this;
+ }
+
+ public HttpReq param(String name, String value) {
+ if (params.length() > 0) params.append('&');
+ try {
+ params.append(name).append('=').append(URLEncoder.encode(value, "UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+
+ return this;
+ }
+
+ public String exec() {
+ HttpURLConnection http = null;
+ try {
+ http = (HttpURLConnection) new URL(baseUrl
+ + (req == null ? "" : req)
+ + (params.length() > 0 ? ("?" + params) : "")).openConnection();
+ http.setRequestProperty("Accept-Charset", "UTF-8");
+ HttpURLConnection.setFollowRedirects(false);
+ http.setConnectTimeout(5 * 1000);
+ http.setReadTimeout(5 * 1000);
+ http.connect();
+
+ int status = http.getResponseCode();
+ String charset = getCharset(http.getHeaderField("Content-Type"));
+
+ if (status == 200) {
+ return readResponseBody(http, charset);
+ } else {
+ logger.warn("non 200 respoonse :" + readErrorResponseBody(http, status, charset));
+ return null;
+ }
+ } catch (Exception e) {
+ logger.error("exec error {}", e.getMessage());
+ return null;
+ } finally {
+ if (http != null) http.disconnect();
+ }
+
+ }
+
+ private static String readErrorResponseBody(HttpURLConnection http, int status, String charset) throws IOException {
+ InputStream errorStream = http.getErrorStream();
+ if (errorStream != null) {
+ String error = toString(charset, errorStream);
+ return ("STATUS CODE =" + status + "\n\n" + error);
+ } else {
+ return ("STATUS CODE =" + status);
+ }
+ }
+
+ private static String readResponseBody(HttpURLConnection http, String charset) throws IOException {
+ InputStream inputStream = http.getInputStream();
+
+ return toString(charset, inputStream);
+ }
+
+ private static String toString(String charset, InputStream inputStream) throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+
+ int length;
+ while ((length = inputStream.read(buffer)) != -1) {
+ baos.write(buffer, 0, length);
+ }
+
+ return new String(baos.toByteArray(), charset);
+ }
+
+ private static String getCharset(String contentType) {
+ if (contentType == null) return "UTF-8";
+
+ String charset = null;
+ for (String param : contentType.replace(" ", "").split(";")) {
+ if (param.startsWith("charset=")) {
+ charset = param.split("=", 2)[1];
+ break;
+ }
+ }
+
+ return charset == null ? "UTF-8" : charset;
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/IPv4Utils.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/IPv4Utils.java
new file mode 100644
index 000000000..32f57f5ae
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/IPv4Utils.java
@@ -0,0 +1 @@
+package com.wzj.soopin.content.idworker.utils;
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/Ip.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/Ip.java
new file mode 100644
index 000000000..cafaf0cc9
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/Ip.java
@@ -0,0 +1,50 @@
+package com.wzj.soopin.content.idworker.utils;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Enumeration;
+
+public class Ip {
+ static Logger logger = LoggerFactory.getLogger(Ip.class);
+
+ public static String ip;
+ public static long lip;
+
+ static {
+ try {
+ InetAddress localHostLANAddress = getFirstNonLoopbackAddress();
+ ip = localHostLANAddress.getHostAddress();
+
+ byte[] address = localHostLANAddress.getAddress();
+ lip = ((address [0] & 0xFFL) << (3*8)) +
+ ((address [1] & 0xFFL) << (2*8)) +
+ ((address [2] & 0xFFL) << (1*8)) +
+ (address [3] & 0xFFL);
+ } catch (Exception e) {
+ logger.error("get ipv4 failed ", e);
+ }
+ }
+
+ private static InetAddress getFirstNonLoopbackAddress() throws SocketException {
+ Enumeration en = NetworkInterface.getNetworkInterfaces();
+ while (en.hasMoreElements()) {
+ NetworkInterface i = (NetworkInterface) en.nextElement();
+ for (Enumeration en2 = i.getInetAddresses(); en2.hasMoreElements(); ) {
+ InetAddress addr = (InetAddress) en2.nextElement();
+ if (addr.isLoopbackAddress()) continue;
+
+ if (addr instanceof Inet4Address) {
+ return addr;
+ }
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/Props.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/Props.java
new file mode 100644
index 000000000..16c869e66
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/Props.java
@@ -0,0 +1,70 @@
+package com.wzj.soopin.content.idworker.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.util.Properties;
+
+import static java.io.File.separator;
+import static org.n3r.idworker.utils.Serializes.closeQuietly;
+
+public class Props {
+ static Logger log = LoggerFactory.getLogger(Props.class);
+
+ public static Properties tryProperties(String propertiesFileName, String userHomeBasePath) {
+ Properties properties = new Properties();
+ InputStream is = null;
+ try {
+ is = Props.tryResource(propertiesFileName, userHomeBasePath, Silent.ON);
+ if (is != null) properties.load(is);
+ } catch (IOException e) {
+ log.error("load properties error: {}", e.getMessage());
+ } finally {
+ closeQuietly(is);
+ }
+
+ return properties;
+ }
+
+
+ enum Silent {ON, OFF}
+
+ public static InputStream tryResource(String propertiesFileName, String userHomeBasePath, Silent silent) {
+ InputStream is = currentDirResource(new File(propertiesFileName));
+ if (is != null) return is;
+
+ is = userHomeResource(propertiesFileName, userHomeBasePath);
+ if (is != null) return is;
+
+ is = classpathResource(propertiesFileName);
+ if (is != null || silent == Silent.ON) return is;
+
+ throw new RuntimeException("fail to find " + propertiesFileName + " in current dir or classpath");
+ }
+
+ private static InputStream userHomeResource(String pathname, String appHome) {
+ String filePath = System.getProperty("user.home") + separator + appHome;
+ File dir = new File(filePath);
+ if (!dir.exists()) return null;
+
+ return currentDirResource(new File(dir, pathname));
+ }
+
+ private static InputStream currentDirResource(File file) {
+ if (!file.exists()) return null;
+
+ try {
+ return new FileInputStream(file);
+ } catch (FileNotFoundException e) {
+ // This should not happened
+ log.error("read file {} error", file, e);
+ return null;
+ }
+ }
+
+ public static InputStream classpathResource(String resourceName) {
+ return Props.class.getClassLoader().getResourceAsStream(resourceName);
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/Serializes.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/Serializes.java
new file mode 100644
index 000000000..3b78ee548
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/Serializes.java
@@ -0,0 +1,118 @@
+package com.wzj.soopin.content.idworker.utils;
+
+import java.io.*;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.List;
+
+public class Serializes {
+
+ @SuppressWarnings("unchecked")
+ public static List readObjects(File file) {
+ ArrayList objects = new ArrayList();
+ ObjectInputStream objectReader = null;
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(file);
+ objectReader = new ObjectInputStream(fis);
+ while (true)
+ objects.add((T) objectReader.readObject());
+
+ } catch (EOFException e) {
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ closeQuietly(objectReader);
+ closeQuietly(fis);
+ }
+
+ return objects;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public static T readObject(File file) {
+ ObjectInputStream objectReader = null;
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(file);
+ objectReader = new ObjectInputStream(fis);
+ return (T) objectReader.readObject();
+
+ } catch (EOFException e) {
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ closeQuietly(objectReader);
+ closeQuietly(fis);
+ }
+
+ return null;
+ }
+
+ public static void writeObject(File file, Object object) {
+ ObjectOutputStream objectOutput = null;
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(file);
+ objectOutput = new ObjectOutputStream(fos);
+ objectOutput.writeObject(object);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ closeQuietly(objectOutput);
+ closeQuietly(fos);
+ }
+ }
+
+ public static void writeObject(FileOutputStream fos, Object object) {
+ FileChannel channel = fos.getChannel();
+ if (!channel.isOpen()) throw new RuntimeException("channel is closed");
+
+ try {
+ channel.position(0);
+ ObjectOutputStream objectOutput = new ObjectOutputStream(fos);
+ objectOutput.writeObject(object);
+ fos.flush();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ }
+ }
+
+ public static void writeObjects(File file, Object... objects) {
+ ObjectOutputStream objectOutput = null;
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(file);
+ objectOutput = new ObjectOutputStream(fos);
+
+ for (Object object : objects)
+ objectOutput.writeObject(object);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ closeQuietly(objectOutput);
+ closeQuietly(fos);
+ }
+
+ }
+
+ public static void closeQuietly(OutputStream os) {
+ if (os != null) try {
+ os.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+
+
+ public static void closeQuietly(InputStream is) {
+ if (is != null) try {
+ is.close();
+ } catch (IOException e) {
+ // ignore
+ }
+
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/Utils.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/Utils.java
new file mode 100644
index 000000000..eca2fa470
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/idworker/utils/Utils.java
@@ -0,0 +1,114 @@
+package com.wzj.soopin.content.idworker.utils;
+
+import java.io.*;
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+
+public class Utils {
+
+ public static final String DOT_IDWORKERS = ".idworkers";
+
+ public static ClassLoader getClassLoader() {
+ ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+ return contextClassLoader != null ? contextClassLoader : Utils.class.getClassLoader();
+ }
+
+
+ public static InputStream classResourceToStream(String resourceName) {
+ return getClassLoader().getResourceAsStream(resourceName);
+ }
+
+
+ public static String firstLine(String classResourceName) {
+ InputStream inputStream = null;
+ try {
+ inputStream = classResourceToStream(classResourceName);
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
+
+ return bufferedReader.readLine();
+ } catch (IOException e) {
+ return null;
+ } finally {
+ if (inputStream != null) try {
+ inputStream.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+
+ public static String checkNotEmpty(String param, String name) {
+ if (param == null || param.isEmpty())
+ throw new IllegalArgumentException(name + " is empty");
+
+ return param;
+ }
+
+
+ public static long midnightMillis() {
+ // today
+ Calendar date = Calendar.getInstance();
+ // reset hour, minutes, seconds and millis
+ date.set(Calendar.HOUR_OF_DAY, 0);
+ date.set(Calendar.MINUTE, 0);
+ date.set(Calendar.SECOND, 0);
+ date.set(Calendar.MILLISECOND, 0);
+
+ return date.getTimeInMillis();
+ }
+
+ public static void main(String[] args) {
+ // 2013-12-25 00:00:00.000
+ System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Timestamp(midnightMillis())));
+ System.out.println(encode(281474976710655L));
+ }
+
+ public static long decode(String s, String symbols) {
+ final int B = symbols.length();
+ long num = 0;
+ for (char ch : s.toCharArray()) {
+ num *= B;
+ num += symbols.indexOf(ch);
+ }
+ return num;
+ }
+
+ public static String encode(long num) {
+ return encode(num, defaultRange);
+ }
+
+ public static String encode(long num, String symbols) {
+ final int B = symbols.length();
+ StringBuilder sb = new StringBuilder();
+ while (num != 0) {
+ sb.append(symbols.charAt((int) (num % B)));
+ num /= B;
+ }
+ return sb.reverse().toString();
+ }
+
+ // all un-clearly-recognized letters are skiped.
+ static String defaultRange = "0123456789ABCDFGHKMNPRSTWXYZ";
+
+ public static String padLeft(String str, int size, char padChar) {
+ if (str.length() >= size) return str;
+
+ StringBuilder s = new StringBuilder();
+ for (int i = size - str.length(); i > 0; --i) {
+ s.append(padChar);
+ }
+ s.append(str);
+
+ return s.toString();
+ }
+
+ public static File createIdWorkerHome() {
+ String userHome = System.getProperty("user.home");
+ File idWorkerHome = new File(userHome + File.separator + DOT_IDWORKERS);
+ idWorkerHome.mkdirs();
+ if (idWorkerHome.isDirectory()) return idWorkerHome;
+
+ throw new RuntimeException("failed to create .idworkers at user home");
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/result/GraceJSONResult.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/result/GraceJSONResult.java
new file mode 100644
index 000000000..d9e4f8630
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/result/GraceJSONResult.java
@@ -0,0 +1,153 @@
+package com.wzj.soopin.content.result;
+
+import java.util.Map;
+
+/**
+ * 自定义响应数据类型枚举升级版本
+ *
+ * @Title: IMOOCJSONResult.java
+ * @Package com.imooc.utils
+ * @Description: 自定义响应数据结构
+ * 本类可提供给 H5/ios/安卓/公众号/小程序 使用
+ * 前端接受此类数据(json object)后,可自行根据业务去实现相关功能
+ *
+ * @Copyright: Copyright (c) 2020
+ * @Company: www.imooc.com
+ * @author 慕课网 - 风间影月
+ * @version V2.0
+ */
+public class GraceJSONResult {
+
+ // 响应业务状态码
+ private Integer status;
+
+ // 响应消息
+ private String msg;
+
+ // 是否成功
+ private Boolean success;
+
+ // 响应数据,可以是Object,也可以是List或Map等
+ private Object data;
+
+ /**
+ * 成功返回,带有数据的,直接往OK方法丢data数据即可
+ * @param data
+ * @return
+ */
+ public static GraceJSONResult ok(Object data) {
+ return new GraceJSONResult(data);
+ }
+ /**
+ * 成功返回,不带有数据的,直接调用ok方法,data无须传入(其实就是null)
+ * @return
+ */
+ public static GraceJSONResult ok() {
+ return new GraceJSONResult(ResponseStatusEnum.SUCCESS);
+ }
+ public GraceJSONResult(Object data) {
+ this.status = ResponseStatusEnum.SUCCESS.status();
+ this.msg = ResponseStatusEnum.SUCCESS.msg();
+ this.success = ResponseStatusEnum.SUCCESS.success();
+ this.data = data;
+ }
+
+
+ /**
+ * 错误返回,直接调用error方法即可,当然也可以在ResponseStatusEnum中自定义错误后再返回也都可以
+ * @return
+ */
+ public static GraceJSONResult error() {
+ return new GraceJSONResult(ResponseStatusEnum.FAILED);
+ }
+
+ /**
+ * 错误返回,map中包含了多条错误信息,可以用于表单验证,把错误统一的全部返回出去
+ * @param map
+ * @return
+ */
+ public static GraceJSONResult errorMap(Map map) {
+ return new GraceJSONResult(ResponseStatusEnum.FAILED, map);
+ }
+
+ /**
+ * 错误返回,直接返回错误的消息
+ * @param msg
+ * @return
+ */
+ public static GraceJSONResult errorMsg(String msg) {
+ return new GraceJSONResult(ResponseStatusEnum.FAILED, msg);
+ }
+
+ /**
+ * 错误返回,token异常,一些通用的可以在这里统一定义
+ * @return
+ */
+ public static GraceJSONResult errorTicket() {
+ return new GraceJSONResult(ResponseStatusEnum.TICKET_INVALID);
+ }
+
+ /**
+ * 自定义错误范围,需要传入一个自定义的枚举,可以到[ResponseStatusEnum.java[中自定义后再传入
+ * @param responseStatus
+ * @return
+ */
+ public static GraceJSONResult errorCustom(ResponseStatusEnum responseStatus) {
+ return new GraceJSONResult(responseStatus);
+ }
+ public static GraceJSONResult exception(ResponseStatusEnum responseStatus) {
+ return new GraceJSONResult(responseStatus);
+ }
+
+ public GraceJSONResult(ResponseStatusEnum responseStatus) {
+ this.status = responseStatus.status();
+ this.msg = responseStatus.msg();
+ this.success = responseStatus.success();
+ }
+ public GraceJSONResult(ResponseStatusEnum responseStatus, Object data) {
+ this.status = responseStatus.status();
+ this.msg = responseStatus.msg();
+ this.success = responseStatus.success();
+ this.data = data;
+ }
+ public GraceJSONResult(ResponseStatusEnum responseStatus, String msg) {
+ this.status = responseStatus.status();
+ this.msg = msg;
+ this.success = responseStatus.success();
+ }
+
+ public GraceJSONResult() {
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public void setStatus(Integer status) {
+ this.status = status;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ public Object getData() {
+ return data;
+ }
+
+ public void setData(Object data) {
+ this.data = data;
+ }
+
+ public Boolean getSuccess() {
+ return success;
+ }
+
+ public void setSuccess(Boolean success) {
+ this.success = success;
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/result/IMOOCJSONResult.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/result/IMOOCJSONResult.java
new file mode 100644
index 000000000..4617b88c0
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/result/IMOOCJSONResult.java
@@ -0,0 +1,135 @@
+package com.wzj.soopin.content.result;
+
+/**
+ *
+ * @Title: IMOOCJSONResult.java
+ * @Package com.imooc.utils
+ * @Description: 自定义响应数据结构
+ * 本类可提供给 H5/ios/安卓/公众号/小程序 使用
+ * 前端接受此类数据(json object)后,可自行根据业务去实现相关功能
+ *
+ * 200:表示成功
+ * 500:表示错误,错误信息在msg字段中
+ * 501:bean验证错误,不管多少个错误都以map形式返回
+ * 502:拦截器拦截到用户token出错
+ * 555:异常抛出信息
+ * 556: 用户qq校验异常
+ * 557: 校验用户是否在CAS登录,用户门票的校验
+ * @Copyright: Copyright (c) 2020
+ * @Company: www.imooc.com
+ * @author 慕课网 - 风间影月
+ * @version V1.0
+ */
+public class IMOOCJSONResult {
+
+ // 响应业务状态
+ private Integer status;
+
+ // 响应消息
+ private String msg;
+
+ // 响应中的数据
+ private Object data;
+
+ private String ok; // 不使用
+
+ public static IMOOCJSONResult build(Integer status, String msg, Object data) {
+ return new IMOOCJSONResult(status, msg, data);
+ }
+
+ public static IMOOCJSONResult build(Integer status, String msg, Object data, String ok) {
+ return new IMOOCJSONResult(status, msg, data, ok);
+ }
+
+ public static IMOOCJSONResult ok(Object data) {
+ return new IMOOCJSONResult(data);
+ }
+
+ public static IMOOCJSONResult ok() {
+ return new IMOOCJSONResult(null);
+ }
+
+ public static IMOOCJSONResult errorMsg(String msg) {
+ return new IMOOCJSONResult(500, msg, null);
+ }
+
+ public static IMOOCJSONResult errorUserTicket(String msg) {
+ return new IMOOCJSONResult(557, msg, null);
+ }
+
+ public static IMOOCJSONResult errorMap(Object data) {
+ return new IMOOCJSONResult(501, "error", data);
+ }
+
+ public static IMOOCJSONResult errorTokenMsg(String msg) {
+ return new IMOOCJSONResult(502, msg, null);
+ }
+
+ public static IMOOCJSONResult errorException(String msg) {
+ return new IMOOCJSONResult(555, msg, null);
+ }
+
+ public static IMOOCJSONResult errorUserQQ(String msg) {
+ return new IMOOCJSONResult(556, msg, null);
+ }
+
+ public IMOOCJSONResult() {
+
+ }
+
+ public IMOOCJSONResult(Integer status, String msg, Object data) {
+ this.status = status;
+ this.msg = msg;
+ this.data = data;
+ }
+
+ public IMOOCJSONResult(Integer status, String msg, Object data, String ok) {
+ this.status = status;
+ this.msg = msg;
+ this.data = data;
+ this.ok = ok;
+ }
+
+ public IMOOCJSONResult(Object data) {
+ this.status = 200;
+ this.msg = "OK";
+ this.data = data;
+ }
+
+ public Boolean isOK() {
+ return this.status == 200;
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public void setStatus(Integer status) {
+ this.status = status;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ public Object getData() {
+ return data;
+ }
+
+ public void setData(Object data) {
+ this.data = data;
+ }
+
+ public String getOk() {
+ return ok;
+ }
+
+ public void setOk(String ok) {
+ this.ok = ok;
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/result/ResponseStatusEnum.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/result/ResponseStatusEnum.java
new file mode 100644
index 000000000..47527b3ed
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/result/ResponseStatusEnum.java
@@ -0,0 +1,108 @@
+package com.wzj.soopin.content.result;
+
+/**
+ * 响应结果枚举,用于提供给GraceJSONResult返回给前端的
+ * 本枚举类中包含了很多的不同的状态码供使用,可以自定义
+ * 便于更优雅的对状态码进行管理,一目了然
+ */
+public enum ResponseStatusEnum {
+
+ SUCCESS(200, true, "操作成功!"),
+ FAILED(500, false, "操作失败!"),
+ ON_BLOCK(201,false,"用户已被拉黑"),
+ // 50x
+ UN_LOGIN(501,false,"请登录后再继续操作!"),
+ TICKET_INVALID(502,false,"会话失效,请重新登录!"),
+ NO_AUTH(503,false,"您的权限不足,无法继续操作!"),
+ MOBILE_ERROR(504,false,"短信发送失败,请稍后重试!"),
+ SMS_NEED_WAIT_ERROR(505,false,"短信发送太快啦~请稍后再试!"),
+ SMS_CODE_ERROR(506,false,"验证码过期或不匹配,请稍后再试!"),
+ USER_FROZEN(507,false,"用户已被冻结,请联系管理员!"),
+ USER_UPDATE_ERROR(508,false,"用户信息更新失败,请联系管理员!"),
+ USER_INACTIVE_ERROR(509,false,"请前往[账号设置]修改信息激活后再进行后续操作!"),
+ USER_INFO_UPDATED_ERROR(5091,false,"用户信息修改失败!"),
+ USER_INFO_UPDATED_NICKNAME_EXIST_ERROR(5092,false,"昵称已经存在!"),
+ FANS_INFO_UPDATED_ISFAN_EXIST_ERROR(5092,false,"已关注"),
+ FANS_INFO_UPDATED_ISFLOW_EXIST_ERROR(5092,false,"未关注"),
+ USER_INFO_UPDATED_IMOOCNUM_EXIST_ERROR(5092,false,"视频号已经存在!"),
+ USER_INFO_CANT_UPDATED_IMOOCNUM_ERROR(5092,false,"视频号无法修改!"),
+ FILE_UPLOAD_NULL_ERROR(510,false,"文件不能为空,请选择一个文件再上传!"),
+ FILE_UPLOAD_FAILD(511,false,"文件上传失败!"),
+ FILE_FORMATTER_FAILD(512,false,"文件图片格式不支持!"),
+ FILE_MAX_SIZE_500KB_ERROR(5131,false,"仅支持500kb大小以下的图片上传!"),
+ FILE_MAX_SIZE_2MB_ERROR(5132,false,"仅支持2MB大小以下的图片上传!"),
+ FILE_NOT_EXIST_ERROR(514,false,"你所查看的文件不存在!"),
+ USER_STATUS_ERROR(515,false,"用户状态参数出错!"),
+ USER_NOT_EXIST_ERROR(516,false,"用户不存在!"),
+ USER_PASSWORD_ERROR(517,false,"密码错误!"),
+
+ // 自定义系统级别异常 54x
+ SYSTEM_INDEX_OUT_OF_BOUNDS(541, false, "系统错误,数组越界!"),
+ SYSTEM_ARITHMETIC_BY_ZERO(542, false, "系统错误,无法除零!"),
+ SYSTEM_NULL_POINTER(543, false, "系统错误,空指针!"),
+ SYSTEM_NUMBER_FORMAT(544, false, "系统错误,数字转换异常!"),
+ SYSTEM_PARSE(545, false, "系统错误,解析异常!"),
+ SYSTEM_IO(546, false, "系统错误,IO输入输出异常!"),
+ SYSTEM_FILE_NOT_FOUND(547, false, "系统错误,文件未找到!"),
+ SYSTEM_CLASS_CAST(548, false, "系统错误,类型强制转换错误!"),
+ SYSTEM_PARSER_ERROR(549, false, "系统错误,解析出错!"),
+ SYSTEM_DATE_PARSER_ERROR(550, false, "系统错误,日期解析出错!"),
+
+ // admin 管理系统 56x
+ ADMIN_USERNAME_NULL_ERROR(561, false, "管理员登录名不能为空!"),
+ ADMIN_USERNAME_EXIST_ERROR(562, false, "管理员登录名已存在!"),
+ ADMIN_NAME_NULL_ERROR(563, false, "管理员负责人不能为空!"),
+ ADMIN_PASSWORD_ERROR(564, false, "密码不能为空后者两次输入不一致!"),
+ ADMIN_CREATE_ERROR(565, false, "添加管理员失败!"),
+ ADMIN_PASSWORD_NULL_ERROR(566, false, "密码不能为空!"),
+ ADMIN_NOT_EXIT_ERROR(567, false, "管理员不存在或密码错误!"),
+ ADMIN_FACE_NULL_ERROR(568, false, "人脸信息不能为空!"),
+ ADMIN_FACE_LOGIN_ERROR(569, false, "人脸识别失败,请重试!"),
+ CATEGORY_EXIST_ERROR(570, false, "文章分类已存在,请换一个分类名!"),
+
+ // 媒体中心 相关错误 58x
+ ARTICLE_COVER_NOT_EXIST_ERROR(580, false, "文章封面不存在,请选择一个!"),
+ ARTICLE_CATEGORY_NOT_EXIST_ERROR(581, false, "请选择正确的文章领域!"),
+ ARTICLE_CREATE_ERROR(582, false, "创建文章失败,请重试或联系管理员!"),
+ ARTICLE_QUERY_PARAMS_ERROR(583, false, "文章列表查询参数错误!"),
+ ARTICLE_DELETE_ERROR(584, false, "文章删除失败!"),
+ ARTICLE_WITHDRAW_ERROR(585, false, "文章撤回失败!"),
+ ARTICLE_REVIEW_ERROR(585, false, "文章审核出错!"),
+ ARTICLE_ALREADY_READ_ERROR(586, false, "文章重复阅读!"),
+
+ // 人脸识别错误代码
+ FACE_VERIFY_TYPE_ERROR(600, false, "人脸比对验证类型不正确!"),
+ FACE_VERIFY_LOGIN_ERROR(601, false, "人脸登录失败!"),
+
+ // 系统错误,未预期的错误 555
+ SYSTEM_ERROR(555, false, "系统繁忙,请稍后再试!"),
+ SYSTEM_OPERATION_ERROR(556, false, "操作失败,请重试或联系管理员"),
+ SYSTEM_RESPONSE_NO_INFO(557, false, ""),
+ SYSTEM_ERROR_GLOBAL(558, false, "全局降级:系统繁忙,请稍后再试!"),
+ SYSTEM_ERROR_FEIGN(559, false, "客户端Feign降级:系统繁忙,请稍后再试!"),
+ SYSTEM_ERROR_ZUUL(560, false, "请求系统过于繁忙,请稍后再试!");
+
+
+ // 响应业务状态
+ private Integer status;
+ // 调用是否成功
+ private Boolean success;
+ // 响应消息,可以为成功或者失败的消息
+ private String msg;
+
+ ResponseStatusEnum(Integer status, Boolean success, String msg) {
+ this.status = status;
+ this.success = success;
+ this.msg = msg;
+ }
+
+ public Integer status() {
+ return status;
+ }
+ public Boolean success() {
+ return success;
+ }
+ public String msg() {
+ return msg;
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/FansService.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/FansService.java
index b3c99f4d1..9387c0fff 100644
--- a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/FansService.java
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/FansService.java
@@ -1,6 +1,6 @@
package com.wzj.soopin.content.service;
-import com.imooc.utils.PagedGridResult;
+
import com.wzj.soopin.content.domain.vo.FansVO;
import org.dromara.common.mybatis.core.page.TableDataInfo;
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/MsgService.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/MsgService.java
index 151e0dcfb..61553e207 100644
--- a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/MsgService.java
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/MsgService.java
@@ -1,6 +1,7 @@
package com.wzj.soopin.content.service;
import com.imooc.mo.MessageMO;
+import com.wzj.soopin.content.domain.mo.MessageMO;
import java.util.List;
import java.util.Map;
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/UserService.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/UserService.java
index b4d894ca1..e3cebb2bd 100644
--- a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/UserService.java
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/UserService.java
@@ -1,9 +1,10 @@
package com.wzj.soopin.content.service;
-import com.imooc.bo.UpdatedUserBO;
-import com.imooc.mo.Token;
-import com.imooc.pojo.Users;
-import com.imooc.vo.UsersVO;
+
+import com.wzj.soopin.content.domain.bo.UpdatedUserBO;
+import com.wzj.soopin.content.domain.mo.Token;
+import com.wzj.soopin.content.domain.po.Users;
+import com.wzj.soopin.content.domain.vo.UsersVO;
import java.util.List;
import java.util.Map;
@@ -25,8 +26,8 @@ public interface UserService {
public Users createUser(String mobile);
/**
- * 根据用户主键查询用户信息
- */
+ * 根据用户主键查询用户信息
+ */
public Users getUser(String userId);
/**
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/VlogService.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/VlogService.java
index 99e14250d..473d5fd9c 100644
--- a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/VlogService.java
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/VlogService.java
@@ -4,6 +4,7 @@ import com.imooc.bo.VlogBO;
import com.imooc.pojo.Vlog;
import com.imooc.utils.PagedGridResult;
import com.imooc.vo.IndexVlogVO;
+import com.wzj.soopin.content.domain.po.Vlog;
public interface VlogService {
/**
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/impl/CommentServiceImpl.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/impl/CommentServiceImpl.java
index 0b60d41e8..0899f0fd8 100644
--- a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/impl/CommentServiceImpl.java
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/impl/CommentServiceImpl.java
@@ -1,21 +1,19 @@
package com.wzj.soopin.content.service.impl;
-import com.github.pagehelper.PageHelper;
-import com.imooc.base.BaseInfoProperties;
-import com.imooc.bo.CommentBO;
-import com.imooc.enums.MessageEnum;
-import com.imooc.enums.YesOrNo;
-import com.imooc.mapper.CommentMapper;
-import com.imooc.mapper.CommentMapperCustom;
-import com.imooc.pojo.Comment;
-import com.imooc.pojo.Vlog;
-import com.imooc.service.CommentService;
-import com.imooc.service.MsgService;
-import com.imooc.service.VlogService;
-import com.imooc.utils.PagedGridResult;
-import com.imooc.vo.CommentVO;
+
+
+import com.wzj.soopin.content.domain.base.BaseInfoProperties;
+import com.wzj.soopin.content.domain.bo.CommentBO;
+import com.wzj.soopin.content.domain.po.Comment;
+import com.wzj.soopin.content.domain.po.Vlog;
+import com.wzj.soopin.content.domain.vo.CommentVO;
+import com.wzj.soopin.content.mapper.mapper.CommentMapper;
+import com.wzj.soopin.content.mapper.mapper.CommentMapperCustom;
+import com.wzj.soopin.content.service.CommentService;
+import com.wzj.soopin.content.service.MsgService;
+import com.wzj.soopin.content.service.VlogService;
import org.apache.commons.lang3.StringUtils;
-import org.n3r.idworker.Sid;
+
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/impl/MsgServiceImpl.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/impl/MsgServiceImpl.java
index f310fd9df..eba7629be 100644
--- a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/impl/MsgServiceImpl.java
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/impl/MsgServiceImpl.java
@@ -7,6 +7,7 @@ import com.imooc.pojo.Users;
import com.imooc.repository.MessageRepository;
import com.imooc.service.MsgService;
import com.imooc.service.UserService;
+import com.wzj.soopin.content.domain.mo.MessageMO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/impl/VlogServiceImpl.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/impl/VlogServiceImpl.java
index 5f537d368..dce694650 100644
--- a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/impl/VlogServiceImpl.java
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/service/impl/VlogServiceImpl.java
@@ -18,6 +18,7 @@ import com.imooc.service.MsgService;
import com.imooc.service.VlogService;
import com.imooc.utils.PagedGridResult;
import com.imooc.vo.IndexVlogVO;
+import com.wzj.soopin.content.domain.po.Vlog;
import org.apache.commons.lang3.StringUtils;
import org.n3r.idworker.Sid;
import org.springframework.beans.BeanUtils;
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/Code.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/Code.java
new file mode 100644
index 000000000..214143882
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/Code.java
@@ -0,0 +1,35 @@
+package com.wzj.soopin.content.utils;
+
+
+
+public class Code {
+ private static RandomCodeStrategy strategy;
+
+ static {
+ RandomCodeStrategy strategy = new DefaultRandomCodeStrategy();
+ strategy.init();
+ configure(strategy);
+ }
+
+ public static synchronized void configure(RandomCodeStrategy custom) {
+ if (strategy == custom) return;
+ if (strategy != null) strategy.release();
+
+ strategy = custom;
+ }
+
+ /**
+ * Next Unique code.
+ * The max length will be 1024-Integer.MAX-Integer.MAX(2147483647) which has 4+10+10+2*1=26 characters.
+ * The min length will be 0-0.
+ *
+ * @return unique string code.
+ */
+ public static synchronized String next() {
+ long workerId = Id.getWorkerId();
+ int prefix = strategy.prefix();
+ int next = strategy.next();
+
+ return String.format("%d-%03d-%06d", workerId, prefix, next);
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DateUtil.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DateUtil.java
new file mode 100644
index 000000000..1ad38601a
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DateUtil.java
@@ -0,0 +1,680 @@
+package com.wzj.soopin.content.utils;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+public class DateUtil {
+
+ /**
+ * Base ISO 8601 Date format yyyyMMdd i.e., 20021225 for the 25th day of December in the year 2002
+ */
+ public static final String ISO_DATE_FORMAT = "yyyyMMdd";
+
+ /**
+ * Expanded ISO 8601 Date format yyyy-MM-dd i.e., 2002-12-25 for the 25th day of December in the year 2002
+ */
+ public static final String ISO_EXPANDED_DATE_FORMAT = "yyyy-MM-dd";
+
+ /**
+ * yyyy-MM-dd hh:mm:ss
+ */
+ public static String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
+ public static String DATE_PATTERN = "yyyyMMddHHmmss";
+
+ /**
+ * 则个
+ */
+ private static boolean LENIENT_DATE = false;
+
+
+ private static Random random = new Random();
+ private static final int ID_BYTES = 10;
+
+ public synchronized static String generateId() {
+ StringBuffer result = new StringBuffer();
+ result = result.append(System.currentTimeMillis());
+ for (int i = 0; i < ID_BYTES; i++) {
+ result = result.append(random.nextInt(10));
+ }
+ return result.toString();
+ }
+
+ protected static final float normalizedJulian(float JD) {
+
+ float f = Math.round(JD + 0.5f) - 0.5f;
+
+ return f;
+ }
+
+ /**
+ * Returns the Date from a julian. The Julian date will be converted to noon GMT,
+ * such that it matches the nearest half-integer (i.e., a julian date of 1.4 gets
+ * changed to 1.5, and 0.9 gets changed to 0.5.)
+ *
+ * @param JD the Julian date
+ * @return the Gregorian date
+ */
+ public static final Date toDate(float JD) {
+
+ /* To convert a Julian Day Number to a Gregorian date, assume that it is for 0 hours, Greenwich time (so
+ * that it ends in 0.5). Do the following calculations, again dropping the fractional part of all
+ * multiplicatons and divisions. Note: This method will not give dates accurately on the
+ * Gregorian Proleptic Calendar, i.e., the calendar you get by extending the Gregorian
+ * calendar backwards to years earlier than 1582. using the Gregorian leap year
+ * rules. In particular, the method fails if Y<400. */
+ float Z = (normalizedJulian(JD)) + 0.5f;
+ float W = (int) ((Z - 1867216.25f) / 36524.25f);
+ float X = (int) (W / 4f);
+ float A = Z + 1 + W - X;
+ float B = A + 1524;
+ float C = (int) ((B - 122.1) / 365.25);
+ float D = (int) (365.25f * C);
+ float E = (int) ((B - D) / 30.6001);
+ float F = (int) (30.6001f * E);
+ int day = (int) (B - D - F);
+ int month = (int) (E - 1);
+
+ if (month > 12) {
+ month = month - 12;
+ }
+
+ int year = (int) (C - 4715); //(if Month is January or February) or C-4716 (otherwise)
+
+ if (month > 2) {
+ year--;
+ }
+
+ Calendar c = Calendar.getInstance();
+ c.set(Calendar.YEAR, year);
+ c.set(Calendar.MONTH, month - 1); // damn 0 offsets
+ c.set(Calendar.DATE, day);
+
+ return c.getTime();
+ }
+
+ /**
+ * Returns the days between two dates. Positive values indicate that
+ * the second date is after the first, and negative values indicate, well,
+ * the opposite. Relying on specific times is problematic.
+ *
+ * @param early the "first date"
+ * @param late the "second date"
+ * @return the days between the two dates
+ */
+ public static final int daysBetween(Date early, Date late) {
+
+ Calendar c1 = Calendar.getInstance();
+ Calendar c2 = Calendar.getInstance();
+ c1.setTime(early);
+ c2.setTime(late);
+
+ return daysBetween(c1, c2);
+ }
+
+ /**
+ * Returns the days between two dates. Positive values indicate that
+ * the second date is after the first, and negative values indicate, well,
+ * the opposite.
+ *
+ * @param early
+ * @param late
+ * @return the days between two dates.
+ */
+ public static final int daysBetween(Calendar early, Calendar late) {
+
+ return (int) (toJulian(late) - toJulian(early));
+ }
+
+ /**
+ * 计算时间差
+ * @param startDate
+ * @param endDate
+ * @return
+ */
+ public static final String timeBetween(Date startDate, Date endDate) {
+ long nd = 1000 * 24 * 60 * 60;
+ long nh = 1000 * 60 * 60;
+ long nm = 1000 * 60;
+ // long ns = 1000;
+ // 获得两个时间的毫秒时间差异
+ long diff = endDate.getTime() - startDate.getTime();
+ // 计算差多少天
+ long day = diff / nd;
+ // 计算差多少小时
+ long hour = diff % nd / nh;
+ // 计算差多少分钟
+ long min = diff % nd % nh / nm;
+ // 计算差多少秒//输出结果
+ // long sec = diff % nd % nh % nm / ns;
+ return day + "天" + hour + "小时" + min + "分钟";
+ }
+
+ /**
+ * Return a Julian date based on the input parameter. This is
+ * based from calculations found at
+ * Julian Day Calculations
+ * (Gregorian Calendar), provided by Bill Jeffrys.
+ * @param c a calendar instance
+ * @return the julian day number
+ */
+ public static final float toJulian(Calendar c) {
+
+ int Y = c.get(Calendar.YEAR);
+ int M = c.get(Calendar.MONTH);
+ int D = c.get(Calendar.DATE);
+ int A = Y / 100;
+ int B = A / 4;
+ int C = 2 - A + B;
+ float E = (int) (365.25f * (Y + 4716));
+ float F = (int) (30.6001f * (M + 1));
+ float JD = C + D + E + F - 1524.5f;
+
+ return JD;
+ }
+
+ /**
+ * Return a Julian date based on the input parameter. This is
+ * based from calculations found at
+ * Julian Day Calculations
+ * (Gregorian Calendar), provided by Bill Jeffrys.
+ * @param date
+ * @return the julian day number
+ */
+ public static final float toJulian(Date date) {
+
+ Calendar c = Calendar.getInstance();
+ c.setTime(date);
+
+ return toJulian(c);
+ }
+
+ /**
+ * @param isoString
+ * @param fmt
+ * @param field Calendar.YEAR/Calendar.MONTH/Calendar.DATE
+ * @param amount
+ * @return
+ * @throws ParseException
+ */
+ public static final String dateIncrease(String isoString, String fmt,
+ int field, int amount) {
+
+ try {
+ Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone(
+ "GMT"));
+ cal.setTime(stringToDate(isoString, fmt, true));
+ cal.add(field, amount);
+
+ return dateToString(cal.getTime(), fmt);
+
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+ /**
+ * Time Field Rolling function.
+ * Rolls (up/down) a single unit of time on the given time field.
+ *
+ * @param isoString
+ * @param field the time field.
+ * @param up Indicates if rolling up or rolling down the field value.
+ * @param expanded use formating char's
+ * @exception ParseException if an unknown field value is given.
+ */
+ public static final String roll(String isoString, String fmt, int field,
+ boolean up) throws ParseException {
+
+ Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone(
+ "GMT"));
+ cal.setTime(stringToDate(isoString, fmt));
+ cal.roll(field, up);
+
+ return dateToString(cal.getTime(), fmt);
+ }
+
+ /**
+ * Time Field Rolling function.
+ * Rolls (up/down) a single unit of time on the given time field.
+ *
+ * @param isoString
+ * @param field the time field.
+ * @param up Indicates if rolling up or rolling down the field value.
+ * @exception ParseException if an unknown field value is given.
+ */
+ public static final String roll(String isoString, int field, boolean up) throws
+ ParseException {
+
+ return roll(isoString, DATETIME_PATTERN, field, up);
+ }
+
+ /**
+ * java.util.Date
+ * @param dateText
+ * @param format
+ * @param lenient
+ * @return
+ */
+ public static Date stringToDate(String dateText, String format,
+ boolean lenient) {
+
+ if (dateText == null) {
+
+ return null;
+ }
+
+ DateFormat df = null;
+
+ try {
+
+ if (format == null) {
+ df = new SimpleDateFormat();
+ } else {
+ df = new SimpleDateFormat(format);
+ }
+
+ // setLenient avoids allowing dates like 9/32/2001
+ // which would otherwise parse to 10/2/2001
+ df.setLenient(false);
+
+ return df.parse(dateText);
+ } catch (ParseException e) {
+
+ return null;
+ }
+ }
+
+ /**
+ * @return Timestamp
+ */
+ public static java.sql.Timestamp getCurrentTimestamp() {
+ return new java.sql.Timestamp(new Date().getTime());
+ }
+
+ /** java.util.Date
+ * @param dateText
+ * @param format
+ * @return
+ */
+ public static Date stringToDate(String dateString, String format) {
+
+ return stringToDate(dateString, format, LENIENT_DATE);
+ }
+
+ /**
+ * java.util.Date
+ * @param dateText
+ */
+ public static Date stringToDate(String dateString) {
+ return stringToDate(dateString, ISO_EXPANDED_DATE_FORMAT, LENIENT_DATE);
+ }
+
+ /**
+ * @return
+ * @param pattern
+ * @param date
+ */
+ public static String dateToString(Date date, String pattern) {
+
+ if (date == null) {
+
+ return null;
+ }
+
+ try {
+
+ SimpleDateFormat sfDate = new SimpleDateFormat(pattern);
+ sfDate.setLenient(false);
+
+ return sfDate.format(date);
+ } catch (Exception e) {
+
+ return null;
+ }
+ }
+
+ /**
+ * yyyy-MM-dd
+ * @param date
+ * @return
+ */
+ public static String dateToString(Date date) {
+ return dateToString(date, ISO_EXPANDED_DATE_FORMAT);
+ }
+
+ /**
+ * @return
+ */
+ public static Date getCurrentDateTime() {
+ Calendar calNow = Calendar.getInstance();
+ Date dtNow = calNow.getTime();
+
+ return dtNow;
+ }
+
+ /**
+ *
+ * @param pattern
+ * @return
+ */
+ public static String getCurrentDateString(String pattern) {
+ return dateToString(getCurrentDateTime(), pattern);
+ }
+
+ /**
+ * yyyy-MM-dd
+ * @return
+ */
+ public static String getCurrentDateString() {
+ return dateToString(getCurrentDateTime(), ISO_EXPANDED_DATE_FORMAT);
+ }
+
+ /**
+ * 返回固定格式的当前时间
+ * yyyy-MM-dd hh:mm:ss
+ * @param date
+ * @return
+ */
+ public static String dateToStringWithTime( ) {
+
+ return dateToString(new Date(), DATETIME_PATTERN);
+ }
+
+
+ /**
+ * yyyy-MM-dd hh:mm:ss
+ * @param date
+ * @return
+ */
+ public static String dateToStringWithTime(Date date) {
+
+ return dateToString(date, DATETIME_PATTERN);
+ }
+
+ /**
+ *
+ * @param date
+ * @param days
+ * @return java.util.Date
+ */
+ public static Date dateIncreaseByDay(Date date, int days) {
+
+ Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone(
+ "GMT"));
+ cal.setTime(date);
+ cal.add(Calendar.DATE, days);
+
+ return cal.getTime();
+ }
+
+ /**
+ *
+ * @param date
+ * @param days
+ * @return java.util.Date
+ */
+ public static Date dateIncreaseByMonth(Date date, int mnt) {
+
+ Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone(
+ "GMT"));
+ cal.setTime(date);
+ cal.add(Calendar.MONTH, mnt);
+
+ return cal.getTime();
+ }
+
+ /**
+ *
+ * @param date
+ * @param mnt
+ * @return java.util.Date
+ */
+ public static Date dateIncreaseByYear(Date date, int mnt) {
+
+ Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone(
+ "GMT"));
+ cal.setTime(date);
+ cal.add(Calendar.YEAR, mnt);
+
+ return cal.getTime();
+ }
+
+ /**
+ *
+ * @param date yyyy-MM-dd
+ * @param days
+ * @return yyyy-MM-dd
+ */
+ public static String dateIncreaseByDay(String date, int days) {
+ return dateIncreaseByDay(date, ISO_DATE_FORMAT, days);
+ }
+
+ /**
+ * @param date
+ * @param fmt
+ * @param days
+ * @return
+ */
+ public static String dateIncreaseByDay(String date, String fmt, int days) {
+ return dateIncrease(date, fmt, Calendar.DATE, days);
+ }
+
+ /**
+ *
+ * @param src
+ * @param srcfmt
+ * @param desfmt
+ * @return
+ */
+ public static String stringToString(String src, String srcfmt,
+ String desfmt) {
+ return dateToString(stringToDate(src, srcfmt), desfmt);
+ }
+
+ /**
+ *
+ * @param date
+ * @return string
+ */
+ public static String getYear(Date date) {
+ SimpleDateFormat formater = new SimpleDateFormat(
+ "yyyy");
+ String cur_year = formater.format(date);
+ return cur_year;
+ }
+
+ /**
+ *
+ * @param date
+ * @return string
+ */
+ public static String getMonth(Date date) {
+ SimpleDateFormat formater = new SimpleDateFormat(
+ "MM");
+ String cur_month = formater.format(date);
+ return cur_month;
+ }
+
+ /**
+ * @param date
+ * @return string
+ */
+ public static String getDay(Date date) {
+ SimpleDateFormat formater = new SimpleDateFormat(
+ "dd");
+ String cur_day = formater.format(date);
+ return cur_day;
+ }
+
+ public static int getDayInt(Date date) {
+ SimpleDateFormat formater = new SimpleDateFormat(
+ "dd");
+ String cur_day = formater.format(date);
+ return Integer.valueOf(cur_day);
+ }
+
+ /**
+ * @param date
+ * @return string
+ */
+ public static String getHour(Date date) {
+ SimpleDateFormat formater = new SimpleDateFormat(
+ "HH");
+ String cur_day = formater.format(date);
+ return cur_day;
+ }
+
+ public static int getMinsFromDate(Date dt) {
+ GregorianCalendar cal = new GregorianCalendar();
+ cal.setTime(dt);
+ int hour = cal.get(Calendar.HOUR_OF_DAY);
+ int min = cal.get(Calendar.MINUTE);
+ return ((hour * 60) + min);
+ }
+
+ /**
+ * Function to convert String to Date Object. If invalid input then current or next day date
+ * is returned (Added by Ali Naqvi on 2006-5-16).
+ * @param str String input in YYYY-MM-DD HH:MM[:SS] format.
+ * @param isExpiry boolean if set and input string is invalid then next day date is returned
+ * @return Date
+ */
+ public static Date convertToDate(String str, boolean isExpiry) {
+ SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+ Date dt = null;
+ try {
+ dt = fmt.parse(str);
+ } catch (ParseException ex) {
+ Calendar cal = Calendar.getInstance();
+ if (isExpiry) {
+ cal.add(Calendar.DAY_OF_MONTH, 1);
+ cal.set(Calendar.HOUR_OF_DAY, 23);
+ cal.set(Calendar.MINUTE, 59);
+ } else {
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ cal.set(Calendar.MINUTE, 0);
+ }
+ dt = cal.getTime();
+ }
+ return dt;
+ }
+
+ public static Date convertToDate(String str) {
+ SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd hh:mm");
+ Date dt = null;
+ try {
+ dt = fmt.parse(str);
+ } catch (ParseException ex) {
+ dt = new Date();
+ }
+ return dt;
+ }
+
+ public static String dateFromat(Date date, int minute) {
+ String dateFormat = null;
+ int year = Integer.parseInt(getYear(date));
+ int month = Integer.parseInt(getMonth(date));
+ int day = Integer.parseInt(getDay(date));
+ int hour = minute / 60;
+ int min = minute % 60;
+ dateFormat = String.valueOf(year)
+ +
+ (month > 9 ? String.valueOf(month) :
+ "0" + String.valueOf(month))
+ +
+ (day > 9 ? String.valueOf(day) : "0" + String.valueOf(day))
+ + " "
+ +
+ (hour > 9 ? String.valueOf(hour) : "0" + String.valueOf(hour))
+ +
+ (min > 9 ? String.valueOf(min) : "0" + String.valueOf(min))
+ + "00";
+ return dateFormat;
+ }
+
+ public static String sDateFormat() {
+ return new SimpleDateFormat(DATE_PATTERN).format(Calendar.getInstance().getTime());
+ }
+
+ /**
+ *
+ * @Description: 获得本月的第一天日期
+ * @return
+ *
+ * @author leechenxiang
+ * @date 2017年5月31日 下午1:37:34
+ */
+ public static String getFirstDateOfThisMonth() {
+
+ SimpleDateFormat format = new SimpleDateFormat(ISO_EXPANDED_DATE_FORMAT);
+
+ Calendar calendarFirst = Calendar.getInstance();
+ calendarFirst = Calendar.getInstance();
+ calendarFirst.add(Calendar.MONTH, 0);
+ calendarFirst.set(Calendar.DAY_OF_MONTH, 1);
+ String firstDate = format.format(calendarFirst.getTime());
+
+ return firstDate;
+ }
+
+ /**
+ *
+ * @Description: 获得本月的最后一天日期
+ * @return
+ *
+ * @author leechenxiang
+ * @date 2017年5月31日 下午1:37:50
+ */
+ public static String getLastDateOfThisMonth() {
+ SimpleDateFormat format = new SimpleDateFormat(ISO_EXPANDED_DATE_FORMAT);
+
+ Calendar calendarLast = Calendar.getInstance();
+ calendarLast.setTime(new Date());
+ calendarLast.getActualMaximum(Calendar.DAY_OF_MONTH);
+
+ String lastDate = format.format(calendarLast.getTime());
+ return lastDate;
+ }
+
+ /**
+ * @Description: 判断字符串日期是否匹配指定的格式化日期
+ */
+ public static boolean isValidDate(String strDate, String formatter) {
+ SimpleDateFormat sdf = null;
+ ParsePosition pos = new ParsePosition(0);
+
+ if (StringUtils.isBlank(strDate) || StringUtils.isBlank(formatter)) {
+ return false;
+ }
+ try {
+ sdf = new SimpleDateFormat(formatter);
+ sdf.setLenient(false);
+ Date date = sdf.parse(strDate, pos);
+ if (date == null) {
+ return false;
+ } else {
+ if (pos.getIndex() > sdf.format(date).length()) {
+ return false;
+ }
+ return true;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public static void main(String[] args)
+ {
+// String timeDir=DateUtil.dateToString(new Date(),DateUtil.ISO_EXPANDED_DATE_FORMAT);
+// System.out.println(timeDir);
+ boolean flag = DateUtil.isValidDate("1990-10-32", DateUtil.ISO_EXPANDED_DATE_FORMAT);
+ System.out.println(flag);
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DayCode.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DayCode.java
new file mode 100644
index 000000000..59b892cc9
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DayCode.java
@@ -0,0 +1,19 @@
+package com.wzj.soopin.content.utils;
+
+
+
+public class DayCode {
+ static RandomCodeStrategy strategy;
+
+ static {
+ DayPrefixRandomCodeStrategy dayPrefixCodeStrategy = new DayPrefixRandomCodeStrategy("yyMM");
+ dayPrefixCodeStrategy.setMinRandomSize(7);
+ dayPrefixCodeStrategy.setMaxRandomSize(7);
+ strategy = dayPrefixCodeStrategy;
+ strategy.init();
+ }
+
+ public static synchronized String next() {
+ return String.format("%d-%04d-%07d", Id.getWorkerId(), strategy.prefix(), strategy.next());
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DayPrefixRandomCodeStrategy.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DayPrefixRandomCodeStrategy.java
new file mode 100644
index 000000000..9867626dd
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DayPrefixRandomCodeStrategy.java
@@ -0,0 +1,41 @@
+package com.wzj.soopin.content.utils;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class DayPrefixRandomCodeStrategy extends DefaultRandomCodeStrategy {
+ private final String dayFormat;
+ private String lastDay;
+
+ public DayPrefixRandomCodeStrategy(String dayFormat) {
+ this.dayFormat = dayFormat;
+ }
+
+ @Override
+ public void init() {
+ String day = createDate();
+ if (day.equals(lastDay))
+ throw new RuntimeException("init failed for day unrolled");
+
+ lastDay = day;
+
+ availableCodes.clear();
+ release();
+
+ prefixIndex = Integer.parseInt(lastDay);
+ if (tryUsePrefix()) return;
+
+ throw new RuntimeException("prefix is not available " + prefixIndex);
+ }
+
+ private String createDate() {
+ return new SimpleDateFormat(dayFormat).format(new Date());
+ }
+
+ @Override
+ public int next() {
+ if (!lastDay.equals(createDate())) init();
+
+ return super.next();
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DefaultRandomCodeStrategy.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DefaultRandomCodeStrategy.java
new file mode 100644
index 000000000..9310ad59f
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DefaultRandomCodeStrategy.java
@@ -0,0 +1,196 @@
+package com.wzj.soopin.content.utils;
+
+
+import com.wzj.soopin.content.idworker.utils.Utils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.SecureRandom;
+import java.util.ArrayDeque;
+import java.util.BitSet;
+import java.util.Queue;
+
+public class DefaultRandomCodeStrategy implements RandomCodeStrategy {
+ public static final int MAX_BITS = 1000000;
+
+ Logger log = LoggerFactory.getLogger(DefaultRandomCodeStrategy.class);
+
+ File idWorkerHome = Utils.createIdWorkerHome();
+ volatile FileLock fileLock;
+ BitSet codesFilter;
+
+ int prefixIndex = -1;
+ File codePrefixIndex;
+
+ int minRandomSize = 6;
+ int maxRandomSize = 6;
+
+ public DefaultRandomCodeStrategy() {
+ destroyFileLockWhenShutdown();
+ }
+
+ @Override
+ public void init() {
+ release();
+
+ while (++prefixIndex < 1000) {
+ if (tryUsePrefix()) return;
+ }
+
+ throw new RuntimeException("all prefixes are used up, the world maybe ends!");
+ }
+
+ public DefaultRandomCodeStrategy setMinRandomSize(int minRandomSize) {
+ this.minRandomSize = minRandomSize;
+ return this;
+ }
+
+ public DefaultRandomCodeStrategy setMaxRandomSize(int maxRandomSize) {
+ this.maxRandomSize = maxRandomSize;
+ return this;
+ }
+
+ protected boolean tryUsePrefix() {
+ codePrefixIndex = new File(idWorkerHome, Id.getWorkerId() + ".code.prefix." + prefixIndex);
+
+ if (!createPrefixIndexFile()) return false;
+ if (!createFileLock()) return false;
+ if (!createBloomFilter()) return false;
+
+ log.info("get available prefix index file {}", codePrefixIndex);
+
+ return true;
+ }
+
+ private boolean createFileLock() {
+ if (fileLock != null) fileLock.destroy();
+ fileLock = new FileLock(codePrefixIndex);
+ return fileLock.tryLock();
+ }
+
+ private boolean createBloomFilter() {
+ codesFilter = fileLock.readObject();
+ if (codesFilter == null) {
+ log.info("create new bloom filter");
+ codesFilter = new BitSet(MAX_BITS); // 2^24
+ } else {
+ int size = codesFilter.cardinality();
+ if (size >= MAX_BITS) {
+ log.warn("bloom filter with prefix file {} is already full", codePrefixIndex);
+ return false;
+ }
+ log.info("recreate bloom filter with cardinality {}", size);
+ }
+
+ return true;
+ }
+
+ private void destroyFileLockWhenShutdown() {
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ release();
+ }
+ });
+ }
+
+ private boolean createPrefixIndexFile() {
+ try {
+ codePrefixIndex.createNewFile();
+ return codePrefixIndex.exists();
+ } catch (IOException e) {
+ e.printStackTrace();
+ log.warn("create file {} error {}", codePrefixIndex, e.getMessage());
+ }
+ return false;
+ }
+
+ @Override
+ public int prefix() {
+ return prefixIndex;
+ }
+
+ static final int CACHE_CODES_NUM = 1000;
+
+ SecureRandom secureRandom = new SecureRandom();
+ Queue availableCodes = new ArrayDeque(CACHE_CODES_NUM);
+
+ @Override
+ public int next() {
+ if (availableCodes.isEmpty()) generate();
+
+ return availableCodes.poll();
+ }
+
+ @Override
+ public synchronized void release() {
+ if (fileLock != null) {
+ fileLock.writeObject(codesFilter);
+ fileLock.destroy();
+ fileLock = null;
+ }
+ }
+
+ private void generate() {
+ for (int i = 0; i < CACHE_CODES_NUM; ++i)
+ availableCodes.add(generateOne());
+
+ fileLock.writeObject(codesFilter);
+ }
+
+ private int generateOne() {
+ while (true) {
+ int code = secureRandom.nextInt(max(maxRandomSize));
+ boolean existed = contains(code);
+
+ code = !existed ? add(code) : tryFindAvailableCode(code);
+ if (code >= 0) return code;
+
+ init();
+ }
+ }
+
+ private int tryFindAvailableCode(int code) {
+ int next = codesFilter.nextClearBit(code);
+ if (next != -1 && next < max(maxRandomSize)) return add(next);
+
+ next = codesFilter.previousClearBit(code);
+ if (next != -1) return add(next);
+
+ return -1;
+ }
+
+ private int add(int code) {
+ codesFilter.set(code);
+ return code;
+ }
+
+ private boolean contains(int code) {
+ return codesFilter.get(code);
+ }
+
+
+ private int max(int size) {
+ switch (size) {
+ case 1: // fall through
+ case 2: // fall through
+ case 3: // fall through
+ case 4:
+ return 10000;
+ case 5:
+ return 100000;
+ case 6:
+ return 1000000;
+ case 7:
+ return 10000000;
+ case 8:
+ return 100000000;
+ case 9:
+ return 1000000000;
+ default:
+ return Integer.MAX_VALUE;
+ }
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DefaultWorkerIdStrategy.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DefaultWorkerIdStrategy.java
new file mode 100644
index 000000000..6e331ee91
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DefaultWorkerIdStrategy.java
@@ -0,0 +1,205 @@
+package com.wzj.soopin.content.utils;
+
+
+import com.wzj.soopin.content.idworker.utils.HttpReq;
+import com.wzj.soopin.content.idworker.utils.Ip;
+import com.wzj.soopin.content.idworker.utils.Props;
+import com.wzj.soopin.content.idworker.utils.Utils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.SecureRandom;
+import java.util.Properties;
+import java.util.Random;
+
+public class DefaultWorkerIdStrategy implements WorkerIdStrategy {
+ static long workerIdBits = 10L;
+ static long maxWorkerId = -1L ^ (-1L << workerIdBits);
+ static Random random = new SecureRandom();
+
+ public static final WorkerIdStrategy instance = new DefaultWorkerIdStrategy();
+
+ private final Properties props =
+ Props.tryProperties("idworker-client.properties", Utils.DOT_IDWORKERS);
+ private final String idWorkerServerUrl =
+ props.getProperty("server.address", "http://id.worker.server:18001");
+
+ String userName = System.getProperty("user.name");
+
+ String ipDotUsername = Ip.ip + "." + userName;
+ String ipudotlock = ipDotUsername + ".lock.";
+ int workerIdIndex = ipudotlock.length();
+ long workerId;
+ FileLock fileLock;
+
+ Logger logger = LoggerFactory.getLogger(DefaultWorkerIdStrategy.class);
+ private boolean inited;
+
+
+ private void init() {
+ workerId = findAvailWorkerId();
+ if (workerId >= 0) {
+ destroyFileLockWhenShutdown();
+ startSyncThread();
+ } else {
+ syncWithWorkerIdServer();
+ workerId = findAvailWorkerId();
+ if (workerId < 0) workerId = increaseWithWorkerIdServer();
+ }
+
+ if (workerId < 0) workerId = tryToCreateOnIp();
+ if (workerId < 0) {
+ logger.warn("DANGEROUS!!! Try to use random worker id.");
+ workerId = tryToRandomOnIp(); // Try avoiding! it could cause duplicated
+ }
+
+ if (workerId < 0) {
+ logger.warn("the world may be ended!");
+ throw new RuntimeException("the world may be ended");
+ }
+ }
+
+ private void destroyFileLockWhenShutdown() {
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ fileLock.destroy();
+ }
+ });
+ }
+
+ private void startSyncThread() {
+ new Thread() {
+ @Override
+ public void run() {
+ syncWithWorkerIdServer();
+ }
+ }.start();
+ }
+
+ private long increaseWithWorkerIdServer() {
+ String incId = HttpReq.get(idWorkerServerUrl)
+ .req("/inc")
+ .param("ipu", ipDotUsername)
+ .exec();
+ if (incId == null || incId.trim().isEmpty()) return -1L;
+
+ long lid = Long.parseLong(incId);
+
+ return checkAvail(lid);
+ }
+
+ private long tryToCreateOnIp() {
+ long wid = Ip.lip & maxWorkerId;
+
+ return checkAvail(wid);
+ }
+
+ private long tryToRandomOnIp() {
+ long avaiWorkerId = -1L;
+ long tryTimes = -1;
+
+ while (avaiWorkerId < 0 && ++tryTimes < maxWorkerId) {
+ long wid = Ip.lip & random.nextInt((int) maxWorkerId);
+
+ avaiWorkerId = checkAvail(wid);
+ }
+ return avaiWorkerId;
+ }
+
+ private long checkAvail(long wid) {
+ long availWorkerId = -1L;
+ try {
+ File idWorkerHome = Utils.createIdWorkerHome();
+ new File(idWorkerHome, ipudotlock + String.format("%04d", wid)).createNewFile();
+ availWorkerId = findAvailWorkerId();
+ } catch (IOException e) {
+ logger.warn("checkAvail error", e);
+ }
+
+ return availWorkerId;
+ }
+
+ private void syncWithWorkerIdServer() {
+ String syncIds = HttpReq.get(idWorkerServerUrl).req("/sync")
+ .param("ipu", ipDotUsername).param("ids", buildWorkerIdsOfCurrentIp())
+ .exec();
+ if (syncIds == null || syncIds.trim().isEmpty()) return;
+
+ String[] syncIdsArr = syncIds.split(",");
+ File idWorkerHome = Utils.createIdWorkerHome();
+ for (String syncId : syncIdsArr) {
+ try {
+ new File(idWorkerHome, ipudotlock + syncId).createNewFile();
+ } catch (IOException e) {
+ logger.warn("create workerid lock file error", e);
+ }
+ }
+ }
+
+ private String buildWorkerIdsOfCurrentIp() {
+ StringBuilder sb = new StringBuilder();
+ File idWorkerHome = Utils.createIdWorkerHome();
+ for (File lockFile : idWorkerHome.listFiles()) {
+ // check the format like 10.142.1.151.lock.0001
+ if (!lockFile.getName().startsWith(ipudotlock)) continue;
+
+ String workerId = lockFile.getName().substring(workerIdIndex);
+ if (!workerId.matches("\\d\\d\\d\\d")) continue;
+
+ if (sb.length() > 0) sb.append(',');
+ sb.append(workerId);
+ }
+
+ return sb.toString();
+ }
+
+
+ /**
+ * Find the local available worker id.
+ *
+ * @return -1 when N/A
+ */
+ private long findAvailWorkerId() {
+ File idWorkerHome = Utils.createIdWorkerHome();
+
+ for (File lockFile : idWorkerHome.listFiles()) {
+ // check the format like 10.142.1.151.lock.0001
+ if (!lockFile.getName().startsWith(ipudotlock)) continue;
+
+ String workerId = lockFile.getName().substring(workerIdIndex);
+ if (!workerId.matches("\\d\\d\\d\\d")) continue;
+
+ FileLock fileLock = new FileLock(lockFile);
+ if (!fileLock.tryLock()) {
+ fileLock.destroy();
+ continue;
+ }
+
+ this.fileLock = fileLock;
+ return Long.parseLong(workerId);
+ }
+
+ return -1;
+ }
+
+ @Override
+ public void initialize() {
+ if (inited) return;
+ init();
+ this.inited = true;
+ }
+
+ @Override
+ public long availableWorkerId() {
+ return workerId;
+ }
+
+ @Override
+ public void release() {
+ if (fileLock != null) fileLock.destroy();
+ inited = false;
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DesensitizationUtil.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DesensitizationUtil.java
new file mode 100644
index 000000000..468096238
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/DesensitizationUtil.java
@@ -0,0 +1,77 @@
+package com.wzj.soopin.content.utils;
+
+/**
+ * 通用脱敏工具类
+ * 可用于:
+ * 用户名
+ * 手机号
+ * 邮箱
+ * 地址等
+ */
+public class DesensitizationUtil {
+
+ private static final int SIZE = 6;
+ private static final String SYMBOL = "*";
+
+ public static void main(String[] args) {
+ String name = commonDisplay("慕课网");
+ String mobile = commonDisplay("13900000000");
+ String mail = commonDisplay("admin@imooc.com");
+ String address = commonDisplay("北京大运河东路888号");
+
+ System.out.println(name);
+ System.out.println(mobile);
+ System.out.println(mail);
+ System.out.println(address);
+ }
+
+ /**
+ * 通用脱敏方法
+ * @param value
+ * @return
+ */
+ public static String commonDisplay(String value) {
+ if (null == value || "".equals(value)) {
+ return value;
+ }
+ int len = value.length();
+ int pamaone = len / 2;
+ int pamatwo = pamaone - 1;
+ int pamathree = len % 2;
+ StringBuilder stringBuilder = new StringBuilder();
+ if (len <= 2) {
+ if (pamathree == 1) {
+ return SYMBOL;
+ }
+ stringBuilder.append(SYMBOL);
+ stringBuilder.append(value.charAt(len - 1));
+ } else {
+ if (pamatwo <= 0) {
+ stringBuilder.append(value.substring(0, 1));
+ stringBuilder.append(SYMBOL);
+ stringBuilder.append(value.substring(len - 1, len));
+
+ } else if (pamatwo >= SIZE / 2 && SIZE + 1 != len) {
+ int pamafive = (len - SIZE) / 2;
+ stringBuilder.append(value.substring(0, pamafive));
+ for (int i = 0; i < SIZE; i++) {
+ stringBuilder.append(SYMBOL);
+ }
+ if ((pamathree == 0 && SIZE / 2 == 0) || (pamathree != 0 && SIZE % 2 != 0)) {
+ stringBuilder.append(value.substring(len - pamafive, len));
+ } else {
+ stringBuilder.append(value.substring(len - (pamafive + 1), len));
+ }
+ } else {
+ int pamafour = len - 2;
+ stringBuilder.append(value.substring(0, 1));
+ for (int i = 0; i < pamafour; i++) {
+ stringBuilder.append(SYMBOL);
+ }
+ stringBuilder.append(value.substring(len - 1, len));
+ }
+ }
+ return stringBuilder.toString();
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/FileLock.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/FileLock.java
new file mode 100644
index 000000000..f7066080b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/FileLock.java
@@ -0,0 +1,132 @@
+package com.wzj.soopin.content.utils;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.nio.channels.Channels;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.OverlappingFileLockException;
+
+/**
+ * A file lock a la flock/funlock
+ *
+ * The given path will be created and opened if it doesn't exist.
+ */
+public class FileLock {
+ private final File file;
+ private FileChannel channel;
+ private java.nio.channels.FileLock flock = null;
+ Logger logger = LoggerFactory.getLogger(FileLock.class);
+
+ public FileLock(File file) {
+ this.file = file;
+
+ try {
+ file.createNewFile(); // create the file if it doesn't exist
+ channel = new RandomAccessFile(file, "rw").getChannel();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ /**
+ * Lock the file or throw an exception if the lock is already held
+ */
+ public void lock() {
+ try {
+ synchronized (this) {
+ logger.trace("Acquiring lock on {}", file.getAbsolutePath());
+ flock = channel.lock();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Try to lock the file and return true if the locking succeeds
+ */
+ public boolean tryLock() {
+ synchronized (this) {
+ logger.trace("Acquiring lock on {}", file.getAbsolutePath());
+ try {
+ // weirdly this method will return null if the lock is held by another
+ // process, but will throw an exception if the lock is held by this process
+ // so we have to handle both cases
+ flock = channel.tryLock();
+ return flock != null;
+ } catch (OverlappingFileLockException e) {
+ return false;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * Unlock the lock if it is held
+ */
+ public void unlock() {
+ synchronized (this) {
+ logger.trace("Releasing lock on {}", file.getAbsolutePath());
+ if (flock == null) return;
+ try {
+ flock.release();
+ } catch (ClosedChannelException e) {
+ // Ignore
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * Destroy this lock, closing the associated FileChannel
+ */
+ public void destroy() {
+ synchronized (this) {
+ unlock();
+ if (!channel.isOpen()) return;
+
+ try {
+ channel.close();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public T readObject() {
+ try {
+ InputStream is = Channels.newInputStream(channel);
+ ObjectInputStream objectReader = new ObjectInputStream(is);
+ return (T) objectReader.readObject();
+ } catch (EOFException e) {
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ return null;
+ }
+
+
+ public synchronized boolean writeObject(Object object) {
+ if (!channel.isOpen()) return false;
+
+ try {
+ channel.position(0);
+ OutputStream out = Channels.newOutputStream(channel);
+ ObjectOutputStream objectOutput = new ObjectOutputStream(out);
+ objectOutput.writeObject(object);
+ return true;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/GsonUtil.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/GsonUtil.java
new file mode 100644
index 000000000..416dd77d2
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/GsonUtil.java
@@ -0,0 +1,24 @@
+package com.wzj.soopin.content.utils;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+public class GsonUtil {
+
+ private static Gson gson = null;
+
+ private GsonUtil() {
+ }
+
+ static {
+ gson = new GsonBuilder().create();
+ }
+
+ public static String beanToJson(Object value) {
+ return gson.toJson(value);
+ }
+
+ public static T jsonToBean(String content, Class valueType) {
+ return gson.fromJson(content, valueType);
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/IPUtil.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/IPUtil.java
new file mode 100644
index 000000000..bb967961a
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/IPUtil.java
@@ -0,0 +1,38 @@
+package com.wzj.soopin.content.utils;
+
+
+import jakarta.servlet.http.HttpServletRequest;
+
+/**
+ * 用户获得用户ip的工具类
+ */
+public class IPUtil {
+
+ /**
+ * 获取请求IP:
+ * 用户的真实IP不能使用request.getRemoteAddr()
+ * 这是因为可能会使用一些代理软件,这样ip获取就不准确了
+ * 此外我们如果使用了多级(LVS/Nginx)反向代理的话,ip需要从X-Forwarded-For中获得第一个非unknown的IP才是用户的有效ip。
+ * @param request
+ * @return
+ */
+ public static String getRequestIp(HttpServletRequest request) {
+ String ip = request.getHeader("x-forwarded-for");
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("Proxy-Client-IP");
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("WL-Proxy-Client-IP");
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("HTTP_CLIENT_IP");
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getRemoteAddr();
+ }
+ return ip;
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/Id.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/Id.java
new file mode 100644
index 000000000..1fad2bcf1
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/Id.java
@@ -0,0 +1,29 @@
+package com.wzj.soopin.content.utils;
+
+
+
+public class Id {
+ private static WorkerIdStrategy workerIdStrategy;
+ private static IdWorker idWorker;
+
+ static {
+ configure(DefaultWorkerIdStrategy.instance);
+ }
+
+ public static synchronized void configure(WorkerIdStrategy custom) {
+ if (workerIdStrategy == custom) return;
+
+ if (workerIdStrategy != null) workerIdStrategy.release();
+ workerIdStrategy = custom;
+ workerIdStrategy.initialize();
+ idWorker = new IdWorker(workerIdStrategy.availableWorkerId());
+ }
+
+ public static long next() {
+ return idWorker.nextId();
+ }
+
+ public static long getWorkerId() {
+ return idWorker.getWorkerId();
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/IdWorker.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/IdWorker.java
new file mode 100644
index 000000000..c22aaea60
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/IdWorker.java
@@ -0,0 +1,91 @@
+package com.wzj.soopin.content.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.security.SecureRandom;
+
+public class IdWorker {
+ protected long epoch = 1288834974657L;
+// protected long epoch = 1387886498127L; // 2013-12-24 20:01:38.127
+
+
+ protected long workerIdBits = 10L;
+ protected long maxWorkerId = -1L ^ (-1L << workerIdBits);
+ protected long sequenceBits = 11L;
+
+ protected long workerIdShift = sequenceBits;
+ protected long timestampLeftShift = sequenceBits + workerIdBits;
+ protected long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+ protected long lastMillis = -1L;
+
+ protected final long workerId;
+ protected long sequence = 0L;
+ protected Logger logger = LoggerFactory.getLogger(IdWorker.class);
+
+ public IdWorker(long workerId) {
+ this.workerId = checkWorkerId(workerId);
+
+ logger.debug("worker starting. timestamp left shift {}, worker id {}", timestampLeftShift, workerId);
+ }
+
+ public long getEpoch() {
+ return epoch;
+ }
+
+ private long checkWorkerId(long workerId) {
+ // sanity check for workerId
+ if (workerId > maxWorkerId || workerId < 0) {
+ int rand = new SecureRandom().nextInt((int) maxWorkerId + 1);
+ logger.warn("worker Id can't be greater than {} or less than 0, use a random {}", maxWorkerId, rand);
+ return rand;
+ }
+
+ return workerId;
+ }
+
+ public synchronized long nextId() {
+ long timestamp = millisGen();
+
+ if (timestamp < lastMillis) {
+ logger.error("clock is moving backwards. Rejecting requests until {}.", lastMillis);
+ throw new InvalidSystemClock(String.format(
+ "Clock moved backwards. Refusing to generate id for {} milliseconds", lastMillis - timestamp));
+ }
+
+ if (lastMillis == timestamp) {
+ sequence = (sequence + 1) & sequenceMask;
+ if (sequence == 0)
+ timestamp = tilNextMillis(lastMillis);
+ } else {
+ sequence = 0;
+ }
+
+ lastMillis = timestamp;
+ long diff = timestamp - getEpoch();
+ return (diff << timestampLeftShift) |
+ (workerId << workerIdShift) |
+ sequence;
+ }
+
+ protected long tilNextMillis(long lastMillis) {
+ long millis = millisGen();
+ while (millis <= lastMillis)
+ millis = millisGen();
+
+ return millis;
+ }
+
+ protected long millisGen() {
+ return System.currentTimeMillis();
+ }
+
+ public long getLastMillis() {
+ return lastMillis;
+ }
+
+ public long getWorkerId() {
+ return workerId;
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/InvalidSystemClock.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/InvalidSystemClock.java
new file mode 100644
index 000000000..e93df8d95
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/InvalidSystemClock.java
@@ -0,0 +1,7 @@
+package com.wzj.soopin.content.utils;
+
+public class InvalidSystemClock extends RuntimeException {
+ public InvalidSystemClock(String message) {
+ super(message);
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/JsonUtils.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/JsonUtils.java
new file mode 100644
index 000000000..0019482a6
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/JsonUtils.java
@@ -0,0 +1,74 @@
+package com.wzj.soopin.content.utils;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.util.List;
+
+/**
+ *
+ * @Title: JsonUtils.java
+ * @Package com.imooc.utils
+ * @Description: json转换类
+ * Copyright: Copyright (c)
+ * Company: www.imooc.com
+ *
+ * @author imooc
+ */
+public class JsonUtils {
+
+ // 定义jackson对象
+ private static final ObjectMapper MAPPER = new ObjectMapper();
+
+ /**
+ * 将对象转换成json字符串。
+ * @param data
+ * @return
+ */
+ public static String objectToJson(Object data) {
+ try {
+ String string = MAPPER.writeValueAsString(data);
+ return string;
+ } catch (JsonProcessingException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 将json结果集转化为对象
+ *
+ * @param jsonData json数据
+ * @param beanType 对象中的object类型
+ * @return
+ */
+ public static T jsonToPojo(String jsonData, Class beanType) {
+ try {
+ T t = MAPPER.readValue(jsonData, beanType);
+ return t;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 将json数据转换成pojo对象list
+ * @param jsonData
+ * @param beanType
+ * @return
+ */
+ public static List jsonToList(String jsonData, Class beanType) {
+ JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
+ try {
+ List list = MAPPER.readValue(jsonData, javaType);
+ return list;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/MyInfo.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/MyInfo.java
new file mode 100644
index 000000000..2d6d5d0ba
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/MyInfo.java
@@ -0,0 +1,9 @@
+package com.wzj.soopin.content.utils;
+
+public class MyInfo {
+
+ public static String getMobile() {
+ return "";
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/PagedGridResult.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/PagedGridResult.java
new file mode 100644
index 000000000..782ccc962
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/PagedGridResult.java
@@ -0,0 +1,49 @@
+package com.wzj.soopin.content.utils;
+
+import java.util.List;
+
+/**
+ *
+ * @Title: PagedGridResult.java
+ * @Package com.imooc.utils
+ * @Description: 用来返回分页Grid的数据格式
+ * Copyright: Copyright (c) 2021
+ */
+public class PagedGridResult {
+
+ private int page; // 当前页数
+ private long total; // 总页数
+ private long records; // 总记录数
+ private List> rows; // 每行显示的内容
+
+ public int getPage() {
+ return page;
+ }
+ public void setPage(int page) {
+ this.page = page;
+ }
+
+ public long getTotal() {
+ return total;
+ }
+
+ public void setTotal(long total) {
+ this.total = total;
+ }
+
+ public void setTotal(int total) {
+ this.total = total;
+ }
+ public long getRecords() {
+ return records;
+ }
+ public void setRecords(long records) {
+ this.records = records;
+ }
+ public List> getRows() {
+ return rows;
+ }
+ public void setRows(List> rows) {
+ this.rows = rows;
+ }
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/RandomCodeStrategy.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/RandomCodeStrategy.java
new file mode 100644
index 000000000..c79313596
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/RandomCodeStrategy.java
@@ -0,0 +1,11 @@
+package com.wzj.soopin.content.utils;
+
+public interface RandomCodeStrategy {
+ void init();
+
+ int prefix();
+
+ int next();
+
+ void release();
+}
diff --git a/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/RedisOperator.java b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/RedisOperator.java
new file mode 100644
index 000000000..20ed89ff0
--- /dev/null
+++ b/ruoyi-modules/ruoyi-content/src/main/java/com/wzj/soopin/content/utils/RedisOperator.java
@@ -0,0 +1,309 @@
+package com.wzj.soopin.content.utils;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataAccessException;
+import org.springframework.data.redis.connection.RedisConnection;
+import org.springframework.data.redis.connection.StringRedisConnection;
+import org.springframework.data.redis.core.RedisCallback;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @Title: Redis 工具类
+ * @author 风间影月
+ */
+@Component
+public class RedisOperator {
+
+ @Autowired
+ private StringRedisTemplate redisTemplate;
+
+ // Key(键),简单的key-value操作
+
+ /**
+ * 判断key是否存在
+ * @param key
+ * @return
+ */
+ public boolean keyIsExist(String key) {
+ return redisTemplate.hasKey(key);
+ }
+
+ /**
+ * 实现命令:TTL key,以秒为单位,返回给定 key的剩余生存时间(TTL, time to live)。
+ *
+ * @param key
+ * @return
+ */
+ public long ttl(String key) {
+ return redisTemplate.getExpire(key);
+ }
+
+ /**
+ * 实现命令:expire 设置过期时间,单位秒
+ *
+ * @param key
+ * @return
+ */
+ public void expire(String key, long timeout) {
+ redisTemplate.expire(key, timeout, TimeUnit.SECONDS);
+ }
+
+ /**
+ * 实现命令:increment key,增加key一次
+ *
+ * @param key
+ * @return
+ */
+ public long increment(String key, long delta) {
+ return redisTemplate.opsForValue().increment(key, delta);
+ }
+
+ /**
+ * 累加,使用hash
+ */
+ public long incrementHash(String name, String key, long delta) {
+ return redisTemplate.opsForHash().increment(name, key, delta);
+ }
+
+ /**
+ * 累减,使用hash
+ */
+ public long decrementHash(String name, String key, long delta) {
+ delta = delta * (-1);
+ return redisTemplate.opsForHash().increment(name, key, delta);
+ }
+
+ /**
+ * hash 设置value
+ */
+ public void setHashValue(String name, String key, String value) {
+ redisTemplate.opsForHash().put(name, key, value);
+ }
+
+ /**
+ * hash 获得value
+ */
+ public String getHashValue(String name, String key) {
+ return (String)redisTemplate.opsForHash().get(name, key);
+ }
+
+ /**
+ * 实现命令:decrement key,减少key一次
+ *
+ * @param key
+ * @return
+ */
+ public long decrement(String key, long delta) {
+ return redisTemplate.opsForValue().decrement(key, delta);
+ }
+
+ /**
+ * 实现命令:KEYS pattern,查找所有符合给定模式 pattern的 key
+ */
+ public Set keys(String pattern) {
+ return redisTemplate.keys(pattern);
+ }
+
+ /**
+ * 实现命令:DEL key,删除一个key
+ *
+ * @param key
+ */
+ public void del(String key) {
+ redisTemplate.delete(key);
+ }
+
+ // String(字符串)
+
+ /**
+ * 实现命令:SET key value,设置一个key-value(将字符串值 value关联到 key)
+ *
+ * @param key
+ * @param value
+ */
+ public void set(String key, String value) {
+ redisTemplate.opsForValue().set(key, value);
+ }
+
+ /**
+ * 实现命令:SET key value EX seconds,设置key-value和超时时间(秒)
+ *
+ * @param key
+ * @param value
+ * @param timeout
+ * (以秒为单位)
+ */
+ public void set(String key, String value, long timeout) {
+ redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
+ }
+
+ /**
+ * 如果key不存在,则设置,如果存在,则报错
+ * @param key
+ * @param value
+ */
+ public void setnx60s(String key, String value) {
+ redisTemplate.opsForValue().setIfAbsent(key, value, 60, TimeUnit.SECONDS);
+ }
+
+ /**
+ * 如果key不存在,则设置,如果存在,则报错
+ * @param key
+ * @param value
+ */
+ public void setnx(String key, String value) {
+ redisTemplate.opsForValue().setIfAbsent(key, value);
+ }
+
+ /**
+ * 实现命令:GET key,返回 key所关联的字符串值。
+ *
+ * @param key
+ * @return value
+ */
+ public String get(String key) {
+ return (String)redisTemplate.opsForValue().get(key);
+ }
+
+ /**
+ * 批量查询,对应mget
+ * @param keys
+ * @return
+ */
+ public List mget(List keys) {
+ return redisTemplate.opsForValue().multiGet(keys);
+ }
+
+ /**
+ * 批量查询,管道pipeline
+ * @param keys
+ * @return
+ */
+ public List