diff --git a/pom.xml b/pom.xml index c02788d..1bd9e4a 100644 --- a/pom.xml +++ b/pom.xml @@ -222,6 +222,7 @@ ruoyi-generator ruoyi-common ruoyi-api + ruoyi-plus-api pom diff --git a/ruoyi-api/pom.xml b/ruoyi-api/pom.xml index a6f8e6b..ed4bf74 100644 --- a/ruoyi-api/pom.xml +++ b/ruoyi-api/pom.xml @@ -37,6 +37,7 @@ 4.1.1 1.2.0.Final 3.5.0 + 3.2.0 @@ -122,12 +123,12 @@ com.baomidou mybatis-plus-boot-starter - 3.1.2 + ${mybatis-plus-boot-starter.version} com.baomidou - mybatis-plus-generate - ${mybatis-plus.version} + mybatis-plus-generator + ${mybatis-plus-boot-starter.version} org.apache.velocity diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/api/ApiCode.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/api/ApiCode.java new file mode 100644 index 0000000..724ab51 --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/api/ApiCode.java @@ -0,0 +1,77 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.app.common.api; + +/** + *

+ * REST API 响应码 + *

+ * + * @author geekidea + * @since 2018-11-08 + */ +public enum ApiCode { + + SUCCESS(200, "操作成功"), + + UNAUTHORIZED(401, "非法访问"), + + NOT_PERMISSION(403, "没有权限"), + + NOT_FOUND(404, "你请求的路径不存在"), + + FAIL(500, "操作失败"), + + SYSTEM_EXCEPTION(5000,"系统异常!"), + + PARAMETER_EXCEPTION(5001,"请求参数校验异常"), + + PARAMETER_PARSE_EXCEPTION(5002,"请求参数解析异常"), + + HTTP_MEDIA_TYPE_EXCEPTION(5003,"HTTP Media 类型异常"), + + SYSTEM_LOGIN_EXCEPTION(5005,"系统登录异常") + + ; + + private final int code; + private final String msg; + + ApiCode(final int code, final String msg) { + this.code = code; + this.msg = msg; + } + + public static ApiCode getApiCode(int code) { + ApiCode[] ecs = ApiCode.values(); + for (ApiCode ec : ecs) { + if (ec.getCode() == code) { + return ec; + } + } + return SUCCESS; + } + + public int getCode() { + return code; + } + + public String getMsg() { + return msg; + } + +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/api/ApiController.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/api/ApiController.java new file mode 100644 index 0000000..71a1280 --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/api/ApiController.java @@ -0,0 +1,69 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.app.common.api; + +import lombok.extern.slf4j.Slf4j; + +/** + *

+ * ApiResultEST API 公共控制器 + *

+ * + * @author geekidea + * @since 2018-11-08 + */ +@Slf4j +public class ApiController { + + /** + *

+ * 请求成功 + *

+ * + * @param data 数据内容 + * @param 对象泛型 + * @return + */ + protected ApiResult ok(T data) { + return ApiResult.ok(data); + } + + /** + *

+ * 请求失败 + *

+ * + * @param msg 提示内容 + * @return + */ + protected ApiResult fail(String msg) { + return ApiResult.fail(msg); + } + + /** + *

+ * 请求失败 + *

+ * + * @param apiCode 请求错误码 + * @return + */ + protected ApiResult fail(ApiCode apiCode) { + return ApiResult.fail(apiCode); + } + +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/api/ApiResult.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/api/ApiResult.java new file mode 100644 index 0000000..18f7bfc --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/api/ApiResult.java @@ -0,0 +1,125 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.app.common.api; + +import com.alibaba.fastjson.annotation.JSONField; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.experimental.Accessors; +import org.apache.commons.lang3.StringUtils; + +import java.io.Serializable; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + *

+ * REST API 返回结果 + *

+ * + * @author geekidea + * @since 2018-11-08 + */ +@Data +@Accessors(chain = true) +@Builder +@AllArgsConstructor +public class ApiResult implements Serializable { + + private int code; + + private T data; + + private String msg; + + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date time; + + public ApiResult() { + + } + + public static ApiResult result(boolean flag){ + if (flag){ + return ok(); + } + return fail(""); + } + + public static ApiResult result(ApiCode apiCode){ + return result(apiCode,null); + } + + public static ApiResult result(ApiCode apiCode,Object data){ + return result(apiCode,null,data); + } + + public static ApiResult result(ApiCode apiCode,String msg,Object data){ + String message = apiCode.getMsg(); + if (StringUtils.isNotBlank(msg)){ + message = msg; + } + return ApiResult.builder() + .code(apiCode.getCode()) + .msg(message) + .data(data) + .time(new Date()) + .build(); + } + + public static ApiResult ok(){ + return ok(null); + } + + public static ApiResult ok(Object data){ + return result(ApiCode.SUCCESS,data); + } + + public static ApiResult ok(String key,Object value){ + Map map = new HashMap<>(); + map.put(key,value); + return ok(map); + } + + public static ApiResult fail(ApiCode apiCode){ + return result(apiCode,null); + } + + public static ApiResult fail(String msg){ + return result(ApiCode.FAIL,msg,null); + + } + + public static ApiResult fail(ApiCode apiCode,Object data){ + if (ApiCode.SUCCESS == apiCode){ + throw new RuntimeException("失败结果状态码不能为" + ApiCode.SUCCESS.getCode()); + } + return result(apiCode,data); + + } + + public static ApiResult fail(String key,Object value){ + Map map = new HashMap<>(); + map.put(key,value); + return result(ApiCode.FAIL,map); + } + +} \ No newline at end of file diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/api/Assert.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/api/Assert.java new file mode 100644 index 0000000..99e16e2 --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/api/Assert.java @@ -0,0 +1,180 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.app.common.api; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.api.IErrorCode; +import com.baomidou.mybatisplus.extension.exceptions.ApiException; + +import java.util.Collection; +import java.util.Map; + +/** + *

+ * REST API 业务断言
+ * 参考:org.junit.Assert + *

+ * + * @author geekidea + * @since 2018-11-08 + */ +public class Assert { + + protected Assert() { + // to do noting + } + + /** + * 大于O + */ + public static void gtZero(Integer num, IErrorCode errorCode) { + if (num == null || num <= 0) { + Assert.fail(errorCode); + } + } + + /** + * 大于等于O + */ + public static void geZero(Integer num, IErrorCode errorCode) { + if (num == null || num < 0) { + Assert.fail(errorCode); + } + } + + /** + * num1大于num2 + */ + public static void gt(Integer num1, Integer num2, IErrorCode errorCode) { + if (num1 <= num2) { + Assert.fail(errorCode); + } + } + + /** + * num1大于等于num2 + */ + public static void ge(Integer num1, Integer num2, IErrorCode errorCode) { + if (num1 < num2) { + Assert.fail(errorCode); + } + } + + /** + * obj1 eq obj2 + */ + public static void eq(Object obj1, Object obj2, IErrorCode errorCode) { + if (!obj1.equals(obj2)) { + Assert.fail(errorCode); + } + } + + public static void isTrue(boolean condition, IErrorCode errorCode) { + if (!condition) { + Assert.fail(errorCode); + } + } + + public static void isFalse(boolean condition, IErrorCode errorCode) { + if (condition) { + Assert.fail(errorCode); + } + } + + public static void isNull(IErrorCode errorCode, Object... conditions) { + if (ObjectUtils.isNotNull(conditions)) { + Assert.fail(errorCode); + } + } + + public static void notNull(IErrorCode errorCode, Object... conditions) { + if (ObjectUtils.isNull(conditions)) { + Assert.fail(errorCode); + } + } + + /** + *

+ * 失败结果 + *

+ * + * @param errorCode 异常错误码 + */ + public static void fail(IErrorCode errorCode) { + throw new ApiException(errorCode); + } + + public static void fail(boolean condition, IErrorCode errorCode) { + if (condition) { + Assert.fail(errorCode); + } + } + + public static void fail(String message) { + throw new ApiException(message); + } + + public static void fail(boolean condition, String message) { + if (condition) { + Assert.fail(message); + } + } + + public static void notEmpty(Object[] array, IErrorCode errorCode) { + if (ObjectUtils.isEmpty(array)) { + Assert.fail(errorCode); + } + } + + public static void noNullElements(Object[] array, IErrorCode errorCode) { + if (array != null) { + for (Object element : array) { + if (element == null) { + Assert.fail(errorCode); + } + } + } + } + + public static void notEmpty(Collection collection, IErrorCode errorCode) { + if (CollectionUtils.isNotEmpty(collection)) { + Assert.fail(errorCode); + } + } + + public static void notEmpty(Map map, IErrorCode errorCode) { + if (ObjectUtils.isEmpty(map)) { + Assert.fail(errorCode); + } + } + + public static void isInstanceOf(Class type, Object obj, IErrorCode errorCode) { + Assert.notNull(errorCode, type); + if (!type.isInstance(obj)) { + Assert.fail(errorCode); + } + } + + public static void isAssignable(Class superType, Class subType, IErrorCode errorCode) { + Assert.notNull(errorCode, superType); + if (subType == null || !superType.isAssignableFrom(subType)) { + Assert.fail(errorCode); + } + } + +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/constant/CacheKey.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/constant/CacheKey.java new file mode 100644 index 0000000..e35ce4f --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/constant/CacheKey.java @@ -0,0 +1,22 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.app.common.constant; + + +public interface CacheKey { + +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/constant/CommonConstant.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/constant/CommonConstant.java new file mode 100644 index 0000000..8ef7392 --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/constant/CommonConstant.java @@ -0,0 +1,66 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.app.common.constant; + +/** + * 常量 + * @author geekidea + * @date 2018-11-08 + */ +public interface CommonConstant { + + /** + * 默认页码为1 + */ + Integer DEFAULT_PAGE_INDEX = 1; + + /** + * 默认页大小为10 + */ + Integer DEFAULT_PAGE_SIZE = 10; + + /** + * 登录用户 + */ + String LOGIN_SYS_USER = "loginSysUser"; + + /** + * 登陆token + */ + String TOKEN = "token"; + /** + * 刷新token + */ + String REFRESH_TOKEN = "refresh_token"; + + /** + * 初始密码 + */ + String INIT_PWD = "123456"; + + /** + * 默认头像 + */ + String DEFAULT_HEAD_URL = ""; + + /** + * 管理员角色名称 + */ + String ADMIN_ROLE_NAME = "管理员"; + + String ADMIN_LOGIN = "adminLogin"; +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/constant/CommonRedisKey.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/constant/CommonRedisKey.java new file mode 100644 index 0000000..4689653 --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/constant/CommonRedisKey.java @@ -0,0 +1,37 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.app.common.constant; + +/** + *

+ * redis key 常量 + *

+ * @author geekidea + * @date 2019-05-23 + **/ +public interface CommonRedisKey { + + /** + * 系统登录用户 + */ + String LOGIN_SYS_USER = "login:sys:user:%s"; + /** + * 系统登录token + */ + String LOGIN_TOKEN = "login:token"; + +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/constant/DatePattern.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/constant/DatePattern.java new file mode 100644 index 0000000..2c3ecc2 --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/constant/DatePattern.java @@ -0,0 +1,57 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.app.common.constant; + +/** + *

+ * 日期格式常量 + *

+ * @author geekidea + * @date 2018-11-08 + */ +public interface DatePattern { + + /** + * 年-月-日 + */ + String yyyy_MM_dd = "yyyy-MM-dd"; + /** + * 年-月-日 时:分 + */ + String yyyy_MM_dd_HH_mm = "yyyy-MM-dd HH:mm"; + /** + * 年-月-日 时:分:秒 + */ + String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss"; + /** + * 年-月-日 时:分:秒:毫秒 + */ + String yyyy_MM_dd_HH_mm_ss_S = "yyyy-MM-dd HH:mm:ss.S"; + + /** + * 时:分 + */ + String HH_mm = "HH:mm"; + /** + * 时:分:秒 + */ + String HH_mm_ss = "HH:mm:ss"; + /** + * 时:分:秒:毫秒 + */ + String HH_mm_ss_S = "HH:mm:ss:S"; +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/entity/BaseEntity.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/entity/BaseEntity.java new file mode 100644 index 0000000..bec52c6 --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/entity/BaseEntity.java @@ -0,0 +1,14 @@ + +package com.ruoyi.app.common.entity; + +import io.swagger.annotations.ApiModel; + +import java.io.Serializable; + +/** + * @author geekidea + * @date 2018-11-08 + */ +@ApiModel("BaseEntity") +public abstract class BaseEntity implements Serializable{ +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/service/impl/BaseServiceImpl.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/service/impl/BaseServiceImpl.java index 004bc46..8b07e4d 100644 --- a/ruoyi-api/src/main/java/com/ruoyi/app/common/service/impl/BaseServiceImpl.java +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/service/impl/BaseServiceImpl.java @@ -21,6 +21,8 @@ import com.baomidou.mybatisplus.core.metadata.OrderItem; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.app.common.service.BaseService; +import com.ruoyi.app.common.web.param.OrderQueryParam; +import com.ruoyi.app.common.web.param.QueryParam; import org.apache.commons.collections.CollectionUtils; import java.util.Arrays; @@ -32,7 +34,33 @@ import java.util.List; */ public abstract class BaseServiceImpl, T> extends ServiceImpl implements BaseService { + protected Page setPageParam(QueryParam queryParam) { + return setPageParam(queryParam,null); + } + protected Page setPageParam(QueryParam queryParam, OrderItem defaultOrder) { + Page page = new Page(); + // 设置当前页码 + page.setCurrent(queryParam.getCurrent()); + // 设置页大小 + page.setSize(queryParam.getSize()); + /** + * 如果是queryParam是OrderQueryParam,并且不为空,则使用前端排序 + * 否则使用默认排序 + */ + if (queryParam instanceof OrderQueryParam){ + OrderQueryParam orderQueryParam = (OrderQueryParam) queryParam; + List orderItems = orderQueryParam.getOrders(); + if (CollectionUtils.isEmpty(orderItems)){ + page.setOrders(Arrays.asList(defaultOrder)); + }else{ + page.setOrders(orderItems); + } + }else{ + page.setOrders(Arrays.asList(defaultOrder)); + } + return page; + } } diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/web/controller/ApiDocController.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/controller/ApiDocController.java new file mode 100644 index 0000000..f54ff91 --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/controller/ApiDocController.java @@ -0,0 +1,45 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.app.common.web.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import springfox.documentation.annotations.ApiIgnore; + +/** + *

+ * Api文档 + *

+ * + * @author geekidea + * @date 2018-11-08 + */ +@Controller +@RequestMapping("/docs") +@ApiIgnore +public class ApiDocController extends BaseController { + + /** + * swaggerUI + */ + @GetMapping("") + public String swaggerUI(){ + return "redirect:/swagger-ui.html"; + } + +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/web/controller/BaseController.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/controller/BaseController.java new file mode 100644 index 0000000..de5d98b --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/controller/BaseController.java @@ -0,0 +1,50 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.app.common.web.controller; + +import com.ruoyi.app.common.api.ApiController; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author geekidea + * @date 2018-11-08 + */ +@Slf4j +public abstract class BaseController extends ApiController { + + /** + * 获取当前请求 + * + * @return request + */ + public HttpServletRequest getRequest() { + return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + } + /** + * 获取当前请求 + * + * @return response + */ + public HttpServletResponse getResponse() { + return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); + } +} \ No newline at end of file diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/web/controller/IndexController.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/controller/IndexController.java new file mode 100644 index 0000000..5f3d56f --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/controller/IndexController.java @@ -0,0 +1,42 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.app.common.web.controller; + +import com.ruoyi.app.common.api.ApiResult; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import springfox.documentation.annotations.ApiIgnore; + +/** + *

+ * 项目根路径提示信息 + *

+ * @author geekidea + * @date 2018/11/12 + */ +@RestController +@ApiIgnore +@Slf4j +public class IndexController { + + @RequestMapping("/index") + public ApiResult index(){ + log.debug("index..."); + return ApiResult.ok("Welcome to Spring Boot Plus Project..."); + } +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/web/param/IdParam.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/param/IdParam.java new file mode 100644 index 0000000..d5ec1f4 --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/param/IdParam.java @@ -0,0 +1,36 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.app.common.web.param; + +import io.swagger.annotations.ApiModel; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + * @author geekidea + * @date 2018-11-08 + */ +@Data +@ApiModel("ID参数") +public class IdParam implements Serializable { + private static final long serialVersionUID = -5353973980674510450L; + + @NotBlank(message="ID不能为空") + private String id; +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/web/param/IdStatusParam.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/param/IdStatusParam.java new file mode 100644 index 0000000..f917ba3 --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/param/IdStatusParam.java @@ -0,0 +1,61 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.app.common.web.param; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + +/** + * @author geekidea + * @date 2018-11-08 + */ +@ApiModel("主键状态VO") +public class IdStatusParam implements Serializable { + private static final long serialVersionUID = -7581307955242965701L; + + @ApiModelProperty("主键ID") + private String id; + + @ApiModelProperty("状态,1:启用 0:禁用") + private Integer status; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + @Override + public String toString() { + return "IdStatusVo{" + + "id='" + id + '\'' + + ", status=" + status + + '}'; + } +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/web/param/NameParam.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/param/NameParam.java new file mode 100644 index 0000000..af81547 --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/param/NameParam.java @@ -0,0 +1,50 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.app.common.web.param; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + +/** + * 名称参数 + * @author geekidea + * @date 2018-11-08 + */ +@ApiModel("名称参数") +public class NameParam implements Serializable { + private static final long serialVersionUID = -3710501706034574149L; + + @ApiModelProperty("名称") + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "NameParam{" + + "name='" + name + '\'' + + '}'; + } +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/web/param/OrderQueryParam.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/param/OrderQueryParam.java new file mode 100644 index 0000000..2746d84 --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/param/OrderQueryParam.java @@ -0,0 +1,54 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.app.common.web.param; + +import com.baomidou.mybatisplus.core.metadata.OrderItem; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.collections.CollectionUtils; + +import java.util.Arrays; +import java.util.List; + +/** + * 可排序查询参数对象 + * @author geekidea + * @since 2019-08-04 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ApiModel("可排序查询参数对象") +public abstract class OrderQueryParam extends QueryParam{ + private static final long serialVersionUID = 57714391204790143L; + + @ApiModelProperty(value = "排序") + private List orders; + + public void defaultOrder(OrderItem orderItem){ + this.defaultOrders(Arrays.asList(orderItem)); + } + + public void defaultOrders(List orderItems){ + if (CollectionUtils.isEmpty(orderItems)){ + return; + } + this.orders = orderItems; + } + +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/web/param/QueryParam.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/param/QueryParam.java new file mode 100644 index 0000000..d0c28d6 --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/param/QueryParam.java @@ -0,0 +1,59 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.app.common.web.param; + +import com.ruoyi.app.common.constant.CommonConstant; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * 查询参数 + * @author geekidea + * @since 2018-11-08 + */ +@Data +@ApiModel("查询参数对象") +public abstract class QueryParam implements Serializable{ + private static final long serialVersionUID = -3263921252635611410L; + + @ApiModelProperty(value = "页码,默认为1") + private Integer current = CommonConstant.DEFAULT_PAGE_INDEX; + @ApiModelProperty(value = "页大小,默认为10") + private Integer size = CommonConstant.DEFAULT_PAGE_SIZE; + @ApiModelProperty(value = "搜索字符串") + private String keyword; + + public void setCurrent(Integer current) { + if (current == null || current <= 0){ + this.current = CommonConstant.DEFAULT_PAGE_INDEX; + }else{ + this.current = current; + } + } + + public void setSize(Integer size) { + if (size == null || size <= 0){ + this.size = CommonConstant.DEFAULT_PAGE_SIZE; + }else{ + this.size = size; + } + } + +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/web/vo/CommonIdName.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/vo/CommonIdName.java new file mode 100644 index 0000000..a900020 --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/vo/CommonIdName.java @@ -0,0 +1,80 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.app.common.web.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + *

+ * 公共ID-NAME-VO对象 + *

+ * @author geekidea + * @since 2018-11-08 + */ +@ApiModel("ID-NAME-VO") +public class CommonIdName { + + @ApiModelProperty("id") + private String id; + + @ApiModelProperty("名称") + private String name; + + + public String getId() { + return id; + } + + + public void setId(String id) { + this.id = id; + } + + + public String getName() { + return name; + } + + + public void setName(String name) { + this.name = name; + } + + + public CommonIdName(String id, String name) { + super(); + this.id = id; + this.name = name; + + } + + + public CommonIdName() { + super(); + } + + + @Override + public String toString() { + return "CommonIdName [id=" + id + ", name=" + name + "]"; + } + + + + +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/web/vo/Paging.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/vo/Paging.java new file mode 100644 index 0000000..b7c045a --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/web/vo/Paging.java @@ -0,0 +1,78 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.app.common.web.vo; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +/** + * @author geekidea + * @date 2018-11-08 + */ +@ApiModel("分页") +public class Paging implements Serializable { + private static final long serialVersionUID = -1683800405530086022L; + + @ApiModelProperty("总行数") + @JSONField(name = "total") + @JsonProperty("total") + private long total = 0; + + @ApiModelProperty("数据列表") + @JSONField(name = "records") + @JsonProperty("records") + private List records = Collections.emptyList(); + + public Paging() { + } + + public Paging(IPage page) { + this.total = page.getTotal(); + this.records = page.getRecords(); + } + + public long getTotal() { + return total; + } + + public void setTotal(long total) { + this.total = total; + } + + public List getRecords() { + return records; + } + + public void setRecords(List records) { + this.records = records; + } + + @Override + public String toString() { + return "Paging{" + + "total=" + total + + ", records=" + records + + '}'; + } +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/entity/StoreSubstitute.java b/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/entity/StoreSubstitute.java new file mode 100644 index 0000000..7470cd0 --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/entity/StoreSubstitute.java @@ -0,0 +1,55 @@ +package com.ruoyi.app.modular.distribution.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import java.util.Date; +import com.baomidou.mybatisplus.annotation.TableId; +import com.ruoyi.app.common.entity.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + *

+ * 代发货表 + *

+ * + * @author hupeng + * @since 2019-09-30 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ApiModel(value="StoreSubstitute对象", description="代发货表") +public class StoreSubstitute extends BaseEntity { + + private static final long serialVersionUID = 1L; + +@TableId(value = "id", type = IdType.AUTO) +private Long id; + +@ApiModelProperty(value = "用户id") +private Integer userId; + +@ApiModelProperty(value = "收货人姓名") +private String username; + +@ApiModelProperty(value = "收货手机号") +private String phone; + +@ApiModelProperty(value = "城市信息") +private String cityInfo; + +@ApiModelProperty(value = "收货详细地址") +private String address; + +@ApiModelProperty(value = "产品明细") +private String productInfo; + +@ApiModelProperty(value = "创建时间") +private Integer createTime; + +private Date updatedAt; + +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/mapper/StoreSubstituteMapper.java b/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/mapper/StoreSubstituteMapper.java new file mode 100644 index 0000000..21340dc --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/mapper/StoreSubstituteMapper.java @@ -0,0 +1,40 @@ +package com.ruoyi.app.modular.distribution.mapper; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.app.modular.distribution.entity.StoreSubstitute; +import com.ruoyi.app.distribution.web.param.StoreSubstituteQueryParam; +import com.ruoyi.app.distribution.web.vo.StoreSubstituteQueryVo; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.io.Serializable; + +/** + *

+ * 代发货表 Mapper 接口 + *

+ * + * @author hupeng + * @since 2019-09-30 + */ +@Repository +public interface StoreSubstituteMapper extends BaseMapper { + + /** + * 根据ID获取查询对象 + * @param id + * @return + */ + StoreSubstituteQueryVo getStoreSubstituteById(Serializable id); + + /** + * 获取分页对象 + * @param page + * @param storeSubstituteQueryParam + * @return + */ + IPage getStoreSubstitutePageList(@Param("page") Page page, @Param("param") StoreSubstituteQueryParam storeSubstituteQueryParam); + +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/service/StoreSubstituteService.java b/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/service/StoreSubstituteService.java new file mode 100644 index 0000000..ad6ca4d --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/service/StoreSubstituteService.java @@ -0,0 +1,35 @@ +package com.ruoyi.app.modular.distribution.service; + +import com.ruoyi.app.modular.distribution.entity.StoreSubstitute; +import com.ruoyi.app.common.service.BaseService; +import com.ruoyi.app.distribution.web.param.StoreSubstituteQueryParam; +import com.ruoyi.app.distribution.web.vo.StoreSubstituteQueryVo; +import com.ruoyi.app.common.web.vo.Paging; + +import java.io.Serializable; + +/** + *

+ * 代发货表 服务类 + *

+ * + * @author hupeng + * @since 2019-09-30 + */ +public interface StoreSubstituteService extends BaseService { + + /** + * 根据ID获取查询对象 + * @param id + * @return + */ + StoreSubstituteQueryVo getStoreSubstituteById(Serializable id) throws Exception; + + /** + * 获取分页对象 + * @param storeSubstituteQueryParam + * @return + */ + Paging getStoreSubstitutePageList(StoreSubstituteQueryParam storeSubstituteQueryParam) throws Exception; + +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/service/impl/StoreSubstituteServiceImpl.java b/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/service/impl/StoreSubstituteServiceImpl.java new file mode 100644 index 0000000..daa663a --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/service/impl/StoreSubstituteServiceImpl.java @@ -0,0 +1,49 @@ +package com.ruoyi.app.modular.distribution.service.impl; + +import com.ruoyi.app.modular.distribution.entity.StoreSubstitute; +import com.ruoyi.app.modular.distribution.mapper.StoreSubstituteMapper; +import com.ruoyi.app.modular.distribution.service.StoreSubstituteService; +import com.ruoyi.app.distribution.web.param.StoreSubstituteQueryParam; +import com.ruoyi.app.distribution.web.vo.StoreSubstituteQueryVo; +import com.ruoyi.app.common.service.impl.BaseServiceImpl; +import com.ruoyi.app.common.web.vo.Paging; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.beans.factory.annotation.Autowired; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.metadata.OrderItem; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import java.io.Serializable; + + +/** + *

+ * 代发货表 服务实现类 + *

+ * + * @author hupeng + * @since 2019-09-30 + */ +@Slf4j +@Service +@Transactional(rollbackFor = Exception.class) +public class StoreSubstituteServiceImpl extends BaseServiceImpl implements StoreSubstituteService { + + @Autowired + private StoreSubstituteMapper storeSubstituteMapper; + + @Override + public StoreSubstituteQueryVo getStoreSubstituteById(Serializable id) throws Exception{ + return storeSubstituteMapper.getStoreSubstituteById(id); + } + + @Override + public Paging getStoreSubstitutePageList(StoreSubstituteQueryParam storeSubstituteQueryParam) throws Exception{ + Page page = setPageParam(storeSubstituteQueryParam,OrderItem.desc("create_time")); + IPage iPage = storeSubstituteMapper.getStoreSubstitutePageList(page,storeSubstituteQueryParam); + return new Paging(iPage); + } + +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/web/controller/StoreSubstituteController.java b/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/web/controller/StoreSubstituteController.java new file mode 100644 index 0000000..34cee0c --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/web/controller/StoreSubstituteController.java @@ -0,0 +1,91 @@ +package com.ruoyi.app.modular.distribution.web.controller; + +import com.ruoyi.app.modular.distribution.entity.StoreSubstitute; +import com.ruoyi.app.modular.distribution.service.StoreSubstituteService; +import com.ruoyi.app.distribution.web.param.StoreSubstituteQueryParam; +import com.ruoyi.app.distribution.web.vo.StoreSubstituteQueryVo; +import com.ruoyi.app.common.web.controller.BaseController; +import com.ruoyi.app.common.api.ApiResult; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +import com.ruoyi.app.common.web.vo.Paging; +import com.ruoyi.app.common.web.param.IdParam; + +/** + *

+ * 代发货表 前端控制器 + *

+ * + * @author hupeng + * @since 2019-09-30 + */ +@Slf4j +@RestController +@RequestMapping("/storeSubstitute") +@Api("代发货表 API") +public class StoreSubstituteController extends BaseController { + + @Autowired + private StoreSubstituteService storeSubstituteService; + + /** + * 添加代发货表 + */ + @PostMapping("/add") + @ApiOperation(value = "添加StoreSubstitute对象",notes = "添加代发货表",response = ApiResult.class) + public ApiResult addStoreSubstitute(@Valid @RequestBody StoreSubstitute storeSubstitute) throws Exception{ + boolean flag = storeSubstituteService.save(storeSubstitute); + return ApiResult.result(flag); + } + + /** + * 修改代发货表 + */ + @PostMapping("/update") + @ApiOperation(value = "修改StoreSubstitute对象",notes = "修改代发货表",response = ApiResult.class) + public ApiResult updateStoreSubstitute(@Valid @RequestBody StoreSubstitute storeSubstitute) throws Exception{ + boolean flag = storeSubstituteService.updateById(storeSubstitute); + return ApiResult.result(flag); + } + + /** + * 删除代发货表 + */ + @PostMapping("/delete") + @ApiOperation(value = "删除StoreSubstitute对象",notes = "删除代发货表",response = ApiResult.class) + public ApiResult deleteStoreSubstitute(@Valid @RequestBody IdParam idParam) throws Exception{ + boolean flag = storeSubstituteService.removeById(idParam.getId()); + return ApiResult.result(flag); + } + + /** + * 获取代发货表 + */ + @PostMapping("/info") + @ApiOperation(value = "获取StoreSubstitute对象详情",notes = "查看代发货表",response = StoreSubstituteQueryVo.class) + public ApiResult getStoreSubstitute(@Valid @RequestBody IdParam idParam) throws Exception{ + StoreSubstituteQueryVo storeSubstituteQueryVo = storeSubstituteService.getStoreSubstituteById(idParam.getId()); + return ApiResult.ok(storeSubstituteQueryVo); + } + + /** + * 代发货表分页列表 + */ + @PostMapping("/getPageList") + @ApiOperation(value = "获取StoreSubstitute分页列表",notes = "代发货表分页列表",response = StoreSubstituteQueryVo.class) + public ApiResult> getStoreSubstitutePageList(@Valid @RequestBody(required = false) StoreSubstituteQueryParam storeSubstituteQueryParam) throws Exception{ + Paging paging = storeSubstituteService.getStoreSubstitutePageList(storeSubstituteQueryParam); + return ApiResult.ok(paging); + } + +} + diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/web/param/StoreSubstituteQueryParam.java b/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/web/param/StoreSubstituteQueryParam.java new file mode 100644 index 0000000..fcd69a9 --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/web/param/StoreSubstituteQueryParam.java @@ -0,0 +1,22 @@ +package com.ruoyi.app.distribution.web.param; + +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import com.ruoyi.app.common.web.param.QueryParam; + +/** + *

+ * 代发货表 查询参数对象 + *

+ * + * @author hupeng + * @date 2019-09-30 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ApiModel(value="StoreSubstituteQueryParam对象", description="代发货表查询参数") +public class StoreSubstituteQueryParam extends QueryParam { + private static final long serialVersionUID = 1L; +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/web/vo/StoreSubstituteQueryVo.java b/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/web/vo/StoreSubstituteQueryVo.java new file mode 100644 index 0000000..4050fb5 --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/modular/distribution/web/vo/StoreSubstituteQueryVo.java @@ -0,0 +1,48 @@ +package com.ruoyi.app.distribution.web.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +import java.util.Date; + +/** + *

+ * 代发货表 查询结果对象 + *

+ * + * @author hupeng + * @date 2019-09-30 + */ +@Data +@ApiModel(value="StoreSubstituteQueryVo对象", description="代发货表查询参数") +public class StoreSubstituteQueryVo implements Serializable{ + private static final long serialVersionUID = 1L; + +private Long id; + +@ApiModelProperty(value = "用户id") +private Integer userId; + +@ApiModelProperty(value = "收货人姓名") +private String username; + +@ApiModelProperty(value = "收货手机号") +private String phone; + +@ApiModelProperty(value = "城市信息") +private String cityInfo; + +@ApiModelProperty(value = "收货详细地址") +private String address; + +@ApiModelProperty(value = "产品明细") +private String productInfo; + +@ApiModelProperty(value = "创建时间") +private Integer createTime; + +private Date updatedAt; + +} \ No newline at end of file diff --git a/ruoyi-api/src/main/resources/mapper/distribution/StoreSubstituteMapper.xml b/ruoyi-api/src/main/resources/mapper/distribution/StoreSubstituteMapper.xml new file mode 100644 index 0000000..d5ab6b3 --- /dev/null +++ b/ruoyi-api/src/main/resources/mapper/distribution/StoreSubstituteMapper.xml @@ -0,0 +1,18 @@ + + + + + + + id, user_id, username, phone, city_info, address, product_info, create_time, updated_at + + + + + + + diff --git a/ruoyi-api/src/main/resources/mapper/modular.distribution/StoreSubstituteMapper.xml b/ruoyi-api/src/main/resources/mapper/modular.distribution/StoreSubstituteMapper.xml new file mode 100644 index 0000000..70c93ac --- /dev/null +++ b/ruoyi-api/src/main/resources/mapper/modular.distribution/StoreSubstituteMapper.xml @@ -0,0 +1,18 @@ + + + + + + + id, user_id, username, phone, city_info, address, product_info, create_time, updated_at + + + + + + + diff --git a/ruoyi-api/src/test/java/com/ruoyi/generator/EntityGenerator.java b/ruoyi-api/src/test/java/com/ruoyi/generator/EntityGenerator.java index cf22227..98ab5ff 100644 --- a/ruoyi-api/src/test/java/com/ruoyi/generator/EntityGenerator.java +++ b/ruoyi-api/src/test/java/com/ruoyi/generator/EntityGenerator.java @@ -1,92 +1,92 @@ -package com.ruoyi.generator; - - -import com.baomidou.mybatisplus.generator.AutoGenerator; -import com.baomidou.mybatisplus.generator.AutoGenerator; -import com.baomidou.mybatisplus.generator.InjectionConfig; -import com.baomidou.mybatisplus.generator.config.DataSourceConfig; -import com.baomidou.mybatisplus.generator.config.GlobalConfig; -import com.baomidou.mybatisplus.generator.config.PackageConfig; -import com.baomidou.mybatisplus.generator.config.StrategyConfig; -import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert; -import com.baomidou.mybatisplus.generator.config.rules.DbColumnType; - -import com.baomidou.mybatisplus.generator.config.rules.DbType; -import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; -import org.junit.Test; - -import java.util.HashMap; -import java.util.Map; - -/** - * 自动生成 - */ -public class EntityGenerator { - - @Test - public void entityGenerator() { - AutoGenerator mpg = new AutoGenerator(); - - // 全局配置 - GlobalConfig gc = new GlobalConfig(); - gc.setOutputDir("E:\\java\\Supply\\ruoyi-api\\src\\main\\java");//这里写你自己的java目录 - gc.setFileOverride(true);//是否覆盖 - gc.setActiveRecord(true); - gc.setEnableCache(false);// XML 二级缓存 - gc.setBaseResultMap(true);// XML ResultMap - gc.setBaseColumnList(false);// XML columList - gc.setAuthor("hupeng"); - mpg.setGlobalConfig(gc); - - // 数据源配置 - DataSourceConfig dsc = new DataSourceConfig(); - dsc.setDbType(DbType.MYSQL); - dsc.setTypeConvert(new MySqlTypeConvert() { - // 自定义数据库表字段类型转换【可选】 - @Override - public DbColumnType processTypeConvert(String fieldType) { - return super.processTypeConvert(fieldType); - } - }); - dsc.setDriverName("com.mysql.jdbc.Driver"); - dsc.setUsername("root"); - dsc.setPassword("root"); - dsc.setUrl("jdbc:mysql://127.0.0.1:3306/ruoyi?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8"); - mpg.setDataSource(dsc); - - // 策略配置 - StrategyConfig strategy = new StrategyConfig(); - //strategy.setTablePrefix(new String[]{"_"});// 此处可以修改为您的表前缀 - strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略 - strategy.setInclude(new String[]{"store_order",}); - mpg.setStrategy(strategy); - - // 包配置 - PackageConfig pc = new PackageConfig(); - pc.setParent(null); - pc.setEntity("com.ruoyi.app.common.persistence.model"); - pc.setMapper("com.ruoyi.app.common.persistence.dao"); - pc.setXml("com.ruoyi.app.common.persistence.dao.mapping"); - pc.setService("TTT"); //本项目没用,生成之后删掉 - pc.setServiceImpl("TTT"); //本项目没用,生成之后删掉 - pc.setController("TTT"); //本项目没用,生成之后删掉 - mpg.setPackageInfo(pc); - - // 注入自定义配置,可以在 VM 中使用 cfg.abc 设置的值 - InjectionConfig cfg = new InjectionConfig() { - @Override - public void initMap() { - Map map = new HashMap<>(); - map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp"); - this.setMap(map); - } - }; - mpg.setCfg(cfg); - - // 执行生成 - mpg.execute(); - - // 打印注入设置 - System.err.println(mpg.getCfg().getMap().get("abc")); - } -} +//package com.ruoyi.generator; +// +// +//import com.baomidou.mybatisplus.generator.AutoGenerator; +//import com.baomidou.mybatisplus.generator.AutoGenerator; +//import com.baomidou.mybatisplus.generator.InjectionConfig; +//import com.baomidou.mybatisplus.generator.config.DataSourceConfig; +//import com.baomidou.mybatisplus.generator.config.GlobalConfig; +//import com.baomidou.mybatisplus.generator.config.PackageConfig; +//import com.baomidou.mybatisplus.generator.config.StrategyConfig; +//import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert; +//import com.baomidou.mybatisplus.generator.config.rules.DbColumnType; +// +//import com.baomidou.mybatisplus.generator.config.rules.DbType; +//import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; +//import org.junit.Test; +// +//import java.util.HashMap; +//import java.util.Map; +// +///** +// * 自动生成 +// */ +//public class EntityGenerator { +// +// @Test +// public void entityGenerator() { +// AutoGenerator mpg = new AutoGenerator(); +// +// // 全局配置 +// GlobalConfig gc = new GlobalConfig(); +// gc.setOutputDir("E:\\java\\Supply\\ruoyi-api\\src\\main\\java");//这里写你自己的java目录 +// gc.setFileOverride(true);//是否覆盖 +// gc.setActiveRecord(true); +// gc.setEnableCache(false);// XML 二级缓存 +// gc.setBaseResultMap(true);// XML ResultMap +// gc.setBaseColumnList(false);// XML columList +// gc.setAuthor("hupeng"); +// mpg.setGlobalConfig(gc); +// +// // 数据源配置 +// DataSourceConfig dsc = new DataSourceConfig(); +// dsc.setDbType(DbType.MYSQL); +// dsc.setTypeConvert(new MySqlTypeConvert() { +// // 自定义数据库表字段类型转换【可选】 +// @Override +// public DbColumnType processTypeConvert(String fieldType) { +// return super.processTypeConvert(fieldType); +// } +// }); +// dsc.setDriverName("com.mysql.jdbc.Driver"); +// dsc.setUsername("root"); +// dsc.setPassword("root"); +// dsc.setUrl("jdbc:mysql://127.0.0.1:3306/ruoyi?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8"); +// mpg.setDataSource(dsc); +// +// // 策略配置 +// StrategyConfig strategy = new StrategyConfig(); +// //strategy.setTablePrefix(new String[]{"_"});// 此处可以修改为您的表前缀 +// strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略 +// strategy.setInclude(new String[]{"store_order",}); +// mpg.setStrategy(strategy); +// +// // 包配置 +// PackageConfig pc = new PackageConfig(); +// pc.setParent(null); +// pc.setEntity("com.ruoyi.app.common.persistence.model"); +// pc.setMapper("com.ruoyi.app.common.persistence.dao"); +// pc.setXml("com.ruoyi.app.common.persistence.dao.mapping"); +// pc.setService("TTT"); //本项目没用,生成之后删掉 +// pc.setServiceImpl("TTT"); //本项目没用,生成之后删掉 +// pc.setController("TTT"); //本项目没用,生成之后删掉 +// mpg.setPackageInfo(pc); +// +// // 注入自定义配置,可以在 VM 中使用 cfg.abc 设置的值 +// InjectionConfig cfg = new InjectionConfig() { +// @Override +// public void initMap() { +// Map map = new HashMap<>(); +// map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp"); +// this.setMap(map); +// } +// }; +// mpg.setCfg(cfg); +// +// // 执行生成 +// mpg.execute(); +// +// // 打印注入设置 +// System.err.println(mpg.getCfg().getMap().get("abc")); +// } +//} diff --git a/ruoyi-api/src/test/java/com/ruoyi/plus/test/BaseTest.java b/ruoyi-api/src/test/java/com/ruoyi/plus/test/BaseTest.java new file mode 100644 index 0000000..53e0b56 --- /dev/null +++ b/ruoyi-api/src/test/java/com/ruoyi/plus/test/BaseTest.java @@ -0,0 +1,12 @@ + +package com.ruoyi.plus.test; + +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class BaseTest { + +} diff --git a/ruoyi-api/src/test/java/com/ruoyi/plus/test/CodeGenerator.java b/ruoyi-api/src/test/java/com/ruoyi/plus/test/CodeGenerator.java new file mode 100644 index 0000000..8e90a5c --- /dev/null +++ b/ruoyi-api/src/test/java/com/ruoyi/plus/test/CodeGenerator.java @@ -0,0 +1,212 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.test; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.core.toolkit.StringPool; +import com.baomidou.mybatisplus.generator.AutoGenerator; +import com.baomidou.mybatisplus.generator.InjectionConfig; +import com.baomidou.mybatisplus.generator.config.*; +import com.baomidou.mybatisplus.generator.config.po.TableInfo; +import com.baomidou.mybatisplus.generator.config.rules.DateType; +import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * spring-boot-plus代码生成器入口类 + * @author geekidea + * @date 2018-11-08 + */ +public class CodeGenerator { + + private static final String USER_NAME = "root"; + private static final String PASSWORD = "root"; + private static final String DRIVER_NAME = "com.mysql.jdbc.Driver"; + private static final String DRIVER_URL = "jdbc:mysql://127.0.0.1:3306/ruoyi?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8"; + + private static final String PARENT_PACKAGE = "com.ruoyi.app"; + private static final String SUPER_ENTITY = PARENT_PACKAGE + ".common.entity.BaseEntity"; + private static final String[] SUPER_ENTITY_COMMON_COLUMNS = new String[]{}; + private static final String SUPER_CONTROLLER = PARENT_PACKAGE + ".common.web.controller.BaseController"; + private static final String SUPER_SERVICE = PARENT_PACKAGE + ".common.service.BaseService"; + private static final String SUPER_SERVICE_IMPL = PARENT_PACKAGE + ".common.service.impl.BaseServiceImpl"; + + private static final String PROJECT_PACKAGE_PATH = "com/ruoyi/app"; + + + // ############################ 配置部分 start ############################ + // 模块名称 + private static final String MODULE_NAME = "distribution"; + // 作者 + private static final String AUTHOR = "hupeng"; + // 生成的表名称 + private static final String TABLE_NAME = "store_substitute"; + // 主键数据库列名称 + private static final String PK_ID_COLUMN_NAME = "id"; + // 代码生成策略 true:All/false:SIMPLE + private static final boolean GENERATOR_STRATEGY = true; + // 分页列表查询是否排序 true:有排序参数/false:无 + private static final boolean PAGE_LIST_ORDER = false; + // ############################ 配置部分 end ############################ + + + public static void main(String[] args) { + // 代码生成器 + AutoGenerator mpg = new AutoGenerator(); + + // 全局配置 + GlobalConfig gc = new GlobalConfig(); + String projectPath = System.getProperty("user.dir"); + gc.setOutputDir(projectPath + "/ruoyi-api/src/main/java"); + gc.setAuthor(AUTHOR); + gc.setOpen(true); // 是否打开输出目录 + gc.setSwagger2(true); // 启用swagger注解 + gc.setIdType(IdType.ID_WORKER); // 主键类型:ID_WORKER + gc.setServiceName("%sService"); // 自定义文件命名,注意 %s 会自动填充表实体属性! + gc.setFileOverride(true); // 是否覆盖已有文件 + gc.setDateType(DateType.ONLY_DATE); // 设置日期类型为Date + + mpg.setGlobalConfig(gc); + + // 数据源配置 + DataSourceConfig dsc = new DataSourceConfig(); + dsc.setUrl(DRIVER_URL); + // dsc.setSchemaName("public"); + dsc.setDriverName(DRIVER_NAME); + dsc.setUsername(USER_NAME); + dsc.setPassword(PASSWORD); + mpg.setDataSource(dsc); + + // 包配置 + PackageConfig pc = new PackageConfig(); + pc.setModuleName(MODULE_NAME); + pc.setParent("com.ruoyi.app.modular"); + pc.setController("web.controller"); + + mpg.setPackageInfo(pc); + + // 自定义配置 + InjectionConfig cfg = new InjectionConfig() { + @Override + public void initMap() { + Map map = new HashMap(); + map.put("customField", "Hello " + this.getConfig().getGlobalConfig().getAuthor()); + // 查询参数包路径 + map.put("queryParamPath",PARENT_PACKAGE + StringPool.DOT + pc.getModuleName() + ".web.param." + underlineToPascal(TABLE_NAME) + "QueryParam"); + // 查询参数共公包路径 + map.put("queryParamCommonPath",PARENT_PACKAGE + StringPool.DOT + "common.web.param." + "QueryParam"); + // 查询参数共公包路径 + map.put("idParamPath",PARENT_PACKAGE + StringPool.DOT + "common.web.param." + "IdParam"); + // 响应结果包路径 + map.put("queryVoPath",PARENT_PACKAGE + StringPool.DOT + pc.getModuleName() + ".web.vo." + underlineToPascal(TABLE_NAME) + "QueryVo"); + // 实体对象名称 + map.put("entityObjectName",underlineToCamel(TABLE_NAME)); + // service对象名称 + map.put("serviceObjectName",underlineToCamel(TABLE_NAME) + "Service"); + // mapper对象名称 + map.put("mapperObjectName",underlineToCamel(TABLE_NAME) + "Mapper"); + // 主键ID列名 + map.put("pkIdColumnName",PK_ID_COLUMN_NAME); + // 主键ID驼峰名称 + map.put("pkIdCamelName",underlineToCamel(PK_ID_COLUMN_NAME)); + // 导入分页类 + map.put("paging",PARENT_PACKAGE + ".common.web.vo.Paging"); + // 导入排序枚举 + map.put("orderEnum",PARENT_PACKAGE + ".common.enums.OrderEnum"); + // 分页列表查询是否排序 + map.put("pageListOrder",PAGE_LIST_ORDER); + // 导入排序查询参数类 + map.put("orderQueryParamPath",PARENT_PACKAGE + StringPool.DOT + "common.web.param." + "OrderQueryParam"); + // 代码生成策略 + map.put("generatorStrategy",GENERATOR_STRATEGY); + this.setMap(map); + } + }; + List focList = new ArrayList<>(); + focList.add(new FileOutConfig("/templates/mapper.xml.vm") { + @Override + public String outputFile(TableInfo tableInfo) { + // 自定义输入文件名称 + return projectPath + "/ruoyi-api/src/main/resources/mapper/" + pc.getModuleName() + + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; + } + }); + + // 自定义queryParam模板 + focList.add(new FileOutConfig("/templates/queryParam.java.vm") { + @Override + public String outputFile(TableInfo tableInfo) { + return projectPath + "/ruoyi-api/src/main/java/"+ PROJECT_PACKAGE_PATH +"/modular/" + pc.getModuleName() + "/web/param/" + tableInfo.getEntityName() + "QueryParam" + StringPool.DOT_JAVA; + } + }); + + // 自定义queryVo模板 + focList.add(new FileOutConfig("/templates/queryVo.java.vm") { + @Override + public String outputFile(TableInfo tableInfo) { + return projectPath + "/ruoyi-api/src/main/java/"+ PROJECT_PACKAGE_PATH +"/modular/" + pc.getModuleName() + "/web/vo/" + tableInfo.getEntityName() + "QueryVo" + StringPool.DOT_JAVA; + } + }); + + + cfg.setFileOutConfigList(focList); + mpg.setCfg(cfg); + mpg.setTemplate(new TemplateConfig().setXml(null)); + + // 策略配置 + StrategyConfig strategy = new StrategyConfig(); + strategy.setNaming(NamingStrategy.underline_to_camel); + strategy.setColumnNaming(NamingStrategy.underline_to_camel); + strategy.setSuperEntityClass(SUPER_ENTITY); + strategy.setEntityLombokModel(true); + strategy.setRestControllerStyle(true); + strategy.setSuperControllerClass(SUPER_CONTROLLER); + strategy.setSuperServiceClass(SUPER_SERVICE); + strategy.setSuperServiceImplClass(SUPER_SERVICE_IMPL); + strategy.setInclude(TABLE_NAME); + strategy.setSuperEntityColumns(SUPER_ENTITY_COMMON_COLUMNS); + strategy.setControllerMappingHyphenStyle(true); + /** + * 注意,根据实际情况,进行设置 + * 当表名称的前缀和模块名称一样时,会去掉表的前缀 + * 比如模块名称为user,表明为user_info,则生成的实体名称是Info.java,一定要注意 + */ + //strategy.setTablePrefix(pc.getModuleName() + "_"); + mpg.setStrategy(strategy); + mpg.execute(); + } + + public static String underlineToCamel(String underline){ + if (StringUtils.isNotBlank(underline)){ + return NamingStrategy.underlineToCamel(underline); + } + return null; + } + + public static String underlineToPascal(String underline){ + if (StringUtils.isNotBlank(underline)){ + return NamingStrategy.capitalFirst(NamingStrategy.underlineToCamel(underline)); + } + return null; + } + +} diff --git a/ruoyi-api/src/test/java/com/ruoyi/plus/test/IpTest.java b/ruoyi-api/src/test/java/com/ruoyi/plus/test/IpTest.java new file mode 100644 index 0000000..d4a9269 --- /dev/null +++ b/ruoyi-api/src/test/java/com/ruoyi/plus/test/IpTest.java @@ -0,0 +1,8 @@ +package com.ruoyi.plus.test; + +/** + * @author geekidea + * @date 2019/8/4 + */ +public class IpTest { +} diff --git a/ruoyi-api/src/test/resources/templates/controller.java.vm b/ruoyi-api/src/test/resources/templates/controller.java.vm new file mode 100644 index 0000000..f04160d --- /dev/null +++ b/ruoyi-api/src/test/resources/templates/controller.java.vm @@ -0,0 +1,114 @@ +package ${package.Controller}; + +import ${package.Entity}.${entity}; +import ${package.Service}.${table.serviceName}; +import ${cfg.queryParamPath}; +import ${cfg.queryVoPath}; +#if(${superControllerClassPackage}) +import ${superControllerClassPackage}; +#end +import com.ruoyi.app.common.api.ApiResult; + #if(${swagger2}) +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +#end +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +#if(${restControllerStyle}) +import org.springframework.web.bind.annotation.RestController; +#else +import org.springframework.stereotype.Controller; +#end + +import javax.validation.Valid; + +import ${cfg.paging}; +import ${cfg.idParamPath}; + +/** + *

+ * $!{table.comment} 前端控制器 + *

+ * + * @author ${author} + * @since ${date} + */ +@Slf4j +#if(${restControllerStyle}) +@RestController +#else +@Controller +#end +@RequestMapping("/${cfg.entityObjectName}") +@Api("$!{table.comment} API") +#if(${kotlin}) +class ${table.controllerName}#if(${superControllerClass}) : ${superControllerClass}()#end + +#else +#if(${superControllerClass}) +public class ${table.controllerName} extends ${superControllerClass} { +#else +public class ${table.controllerName} { +#end + + @Autowired + private ${table.serviceName} ${cfg.serviceObjectName}; + +#if(${cfg.generatorStrategy}) + /** + * 添加$!{table.comment} + */ + @PostMapping("/add") + @ApiOperation(value = "添加${entity}对象",notes = "添加$!{table.comment}",response = ApiResult.class) + public ApiResult add${entity}(@Valid @RequestBody ${entity} ${cfg.entityObjectName}) throws Exception{ + boolean flag = ${cfg.serviceObjectName}.save(${cfg.entityObjectName}); + return ApiResult.result(flag); + } + + /** + * 修改$!{table.comment} + */ + @PostMapping("/update") + @ApiOperation(value = "修改${entity}对象",notes = "修改$!{table.comment}",response = ApiResult.class) + public ApiResult update${entity}(@Valid @RequestBody ${entity} ${cfg.entityObjectName}) throws Exception{ + boolean flag = ${cfg.serviceObjectName}.updateById(${cfg.entityObjectName}); + return ApiResult.result(flag); + } + + /** + * 删除$!{table.comment} + */ + @PostMapping("/delete") + @ApiOperation(value = "删除${entity}对象",notes = "删除$!{table.comment}",response = ApiResult.class) + public ApiResult delete${entity}(@Valid @RequestBody IdParam idParam) throws Exception{ + boolean flag = ${cfg.serviceObjectName}.removeById(idParam.getId()); + return ApiResult.result(flag); + } + + /** + * 获取$!{table.comment} + */ + @PostMapping("/info") + @ApiOperation(value = "获取${entity}对象详情",notes = "查看$!{table.comment}",response = ${entity}QueryVo.class) + public ApiResult<${entity}QueryVo> get${entity}(@Valid @RequestBody IdParam idParam) throws Exception{ + ${entity}QueryVo ${cfg.entityObjectName}QueryVo = ${cfg.serviceObjectName}.get${entity}ById(idParam.getId()); + return ApiResult.ok(${cfg.entityObjectName}QueryVo); + } + + /** + * $!{table.comment}分页列表 + */ + @PostMapping("/getPageList") + @ApiOperation(value = "获取${entity}分页列表",notes = "$!{table.comment}分页列表",response = ${entity}QueryVo.class) + public ApiResult> get${entity}PageList(@Valid @RequestBody(required = false) ${entity}QueryParam ${cfg.entityObjectName}QueryParam) throws Exception{ + Paging<${entity}QueryVo> paging = ${cfg.entityObjectName}Service.get${entity}PageList(${cfg.entityObjectName}QueryParam); + return ApiResult.ok(paging); + } +#end + +} + +#end \ No newline at end of file diff --git a/ruoyi-api/src/test/resources/templates/entity.java.vm b/ruoyi-api/src/test/resources/templates/entity.java.vm new file mode 100644 index 0000000..61c3326 --- /dev/null +++ b/ruoyi-api/src/test/resources/templates/entity.java.vm @@ -0,0 +1,161 @@ +package ${package.Entity}; + +#foreach($pkg in ${table.importPackages}) +import ${pkg}; +#end +#if(${swagger2}) +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +#end +#if(${entityLombokModel}) +import lombok.Data; +import lombok.EqualsAndHashCode; +## import lombok.experimental.Accessors; +#end + +import java.util.Date; + +/** + *

+ * $!{table.comment} + *

+ * + * @author ${author} + * @since ${date} + */ +#if(${entityLombokModel}) +@Data +#if(${superEntityClass}) +@EqualsAndHashCode(callSuper = true) +#else +@EqualsAndHashCode(callSuper = false) +#end +## @Accessors(chain = true) +#end +#if(${table.convert}) +@TableName("${table.name}") +#end +#if(${swagger2}) +@ApiModel(value="${entity}对象", description="$!{table.comment}") +#end +#if(${superEntityClass}) +public class ${entity} extends ${superEntityClass}#if(${activeRecord})<${entity}>#end { +#elseif(${activeRecord}) +public class ${entity} extends Model<${entity}> { +#else +public class ${entity} implements Serializable { +#end + + private static final long serialVersionUID = 1L; +## ---------- BEGIN 字段循环遍历 ---------- +#foreach($field in ${table.fields}) +## 自定义属性,是否是主键 +#set($custom_is_pk=false) + +#if(${field.keyFlag}) +#set($keyPropertyName=${field.propertyName}) +#end +#if("$!field.comment" != "") + #if(${swagger2}) +@ApiModelProperty(value = "${field.comment}") + #else +/** + * ${field.comment} + */ + #end +#end +#if(${field.keyFlag}) +## 主键 +#if(${field.keyIdentityFlag}) +@TableId(value = "${field.name}", type = IdType.AUTO) +#elseif(!$null.isNull(${idType}) && "$!idType" != "") +## 设置主键注解 +@TableId(value = "${field.name}", type = IdType.${idType}) +## 是主键类型 +#set($custom_is_pk=true) +#elseif(${field.convert}) +@TableId("${field.name}") +#end +## 普通字段 +#elseif(${field.fill}) +## ----- 存在字段填充设置 ----- +#if(${field.convert}) + @TableField(value = "${field.name}", fill = FieldFill.${field.fill}) +#else + @TableField(fill = FieldFill.${field.fill}) +#end +#elseif(${field.convert}) + @TableField("${field.name}") +#end +## 乐观锁注解 +#if(${versionFieldName}==${field.name}) + @Version +#end +## 逻辑删除注解 +#if(${logicDeleteFieldName}==${field.name}) + @TableLogic +#end +#if(${custom_is_pk}) + private ${field.propertyType} ${field.propertyName}; +#else +private ${field.propertyType} ${field.propertyName}; +#end +#end +## ---------- END 字段循环遍历 ---------- +#if(!${entityLombokModel}) +#foreach($field in ${table.fields}) +#if(${field.propertyType.equals("boolean")}) +#set($getprefix="is") +#else +#set($getprefix="get") +#end + + public ${field.propertyType} ${getprefix}${field.capitalName}() { + return ${field.propertyName}; + } + +#if(${entityBuilderModel}) + public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) { +#else + public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) { +#end + this.${field.propertyName} = ${field.propertyName}; +#if(${entityBuilderModel}) + return this; +#end + } +#end +#end + +#if(${entityColumnConstant}) +#foreach($field in ${table.fields}) + public static final String ${field.name.toUpperCase()} = "${field.name}"; + +#end +#end +#if(${activeRecord}) + @Override + protected Serializable pkVal() { +#if(${keyPropertyName}) + return this.${keyPropertyName}; +#else + return null; +#end + } + +#end +#if(!${entityLombokModel}) + @Override + public String toString() { + return "${entity}{" + +#foreach($field in ${table.fields}) +#if($!{foreach.index}==0) + "${field.propertyName}=" + ${field.propertyName} + +#else + ", ${field.propertyName}=" + ${field.propertyName} + +#end +#end + "}"; + } +#end +} diff --git a/ruoyi-api/src/test/resources/templates/mapper.java.vm b/ruoyi-api/src/test/resources/templates/mapper.java.vm new file mode 100644 index 0000000..207c1cb --- /dev/null +++ b/ruoyi-api/src/test/resources/templates/mapper.java.vm @@ -0,0 +1,46 @@ +package ${package.Mapper}; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import ${superMapperClassPackage}; +import ${package.Entity}.${entity}; +import ${cfg.queryParamPath}; +import ${cfg.queryVoPath}; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.io.Serializable; + +/** + *

+ * $!{table.comment} Mapper 接口 + *

+ * + * @author ${author} + * @since ${date} + */ +#if(${kotlin}) +interface ${table.mapperName} : ${superMapperClass}<${entity}> +#else +@Repository +public interface ${table.mapperName} extends ${superMapperClass}<${entity}> { +#if(${cfg.generatorStrategy}) + + /** + * 根据ID获取查询对象 + * @param id + * @return + */ + ${entity}QueryVo get${entity}ById(Serializable id); + + /** + * 获取分页对象 + * @param page + * @param ${cfg.entityObjectName}QueryParam + * @return + */ + IPage<${entity}QueryVo> get${entity}PageList(@Param("page") Page page, @Param("param") ${entity}QueryParam ${cfg.entityObjectName}QueryParam); +#end + +} +#end diff --git a/ruoyi-api/src/test/resources/templates/mapper.xml.vm b/ruoyi-api/src/test/resources/templates/mapper.xml.vm new file mode 100644 index 0000000..b3829d3 --- /dev/null +++ b/ruoyi-api/src/test/resources/templates/mapper.xml.vm @@ -0,0 +1,47 @@ + + + + +#if(${enableCache}) + + + +#end +#if(${baseResultMap}) + + +#foreach($field in ${table.fields}) +#if(${field.keyFlag})##生成主键排在第一位 + +#end +#end +#foreach($field in ${table.commonFields})##生成公共字段 + +#end +#foreach($field in ${table.fields}) +#if(!${field.keyFlag})##生成普通字段 + +#end +#end + + +#end + + +#foreach($field in ${table.commonFields}) + ${field.name}, +#end + ${table.fieldNames} + +#if(${cfg.generatorStrategy}) + + + + + +#end + diff --git a/ruoyi-api/src/test/resources/templates/queryParam.java.vm b/ruoyi-api/src/test/resources/templates/queryParam.java.vm new file mode 100644 index 0000000..8508501 --- /dev/null +++ b/ruoyi-api/src/test/resources/templates/queryParam.java.vm @@ -0,0 +1,30 @@ +package com.ruoyi.app.${package.ModuleName}.web.param; + +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +#if(${cfg.pageListOrder}) +import ${cfg.orderQueryParamPath}; +#else +import ${cfg.queryParamCommonPath}; +#end + +/** + *

+ * $!{table.comment} 查询参数对象 + *

+ * + * @author ${author} + * @date ${date} + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ApiModel(value="${entity}QueryParam对象", description="$!{table.comment}查询参数") +#if(${cfg.pageListOrder}) +public class ${entity}QueryParam extends OrderQueryParam { +#else +public class ${entity}QueryParam extends QueryParam { +#end + private static final long serialVersionUID = 1L; +} diff --git a/ruoyi-api/src/test/resources/templates/queryVo.java.vm b/ruoyi-api/src/test/resources/templates/queryVo.java.vm new file mode 100644 index 0000000..7cb0ede --- /dev/null +++ b/ruoyi-api/src/test/resources/templates/queryVo.java.vm @@ -0,0 +1,124 @@ +package com.ruoyi.app.${package.ModuleName}.web.vo; + +#if(${swagger2}) +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +#end +#if(${entityLombokModel}) +import lombok.Data; +#end +import java.io.Serializable; + +import java.util.Date; + +/** + *

+ * $!{table.comment} 查询结果对象 + *

+ * + * @author ${author} + * @date ${date} + */ +#if(${entityLombokModel}) +@Data +#end +#if(${table.convert}) +@TableName("${table.name}") +#end +@ApiModel(value="${entity}QueryVo对象", description="$!{table.comment}查询参数") +public class ${entity}QueryVo implements Serializable{ + private static final long serialVersionUID = 1L; +## ---------- BEGIN 字段循环遍历 ---------- +#foreach($field in ${table.fields}) + +#if(${field.keyFlag}) +#set($keyPropertyName=${field.propertyName}) +#end +#if("$!field.comment" != "") + #if(${swagger2}) +@ApiModelProperty(value = "${field.comment}") + #else +/** + * ${field.comment} + */ + #end +#end +#if(${field.keyFlag}) +## 普通字段 +#elseif(${field.fill}) +## ----- 存在字段填充设置 ----- +#if(${field.convert}) + @TableField(value = "${field.name}", fill = FieldFill.${field.fill}) +#else + @TableField(fill = FieldFill.${field.fill}) +#end +#elseif(${field.convert}) + @TableField("${field.name}") +#end +## 乐观锁注解 +#if(${versionFieldName}==${field.name}) + @Version +#end +## 逻辑删除注解 +#if(${logicDeleteFieldName}==${field.name}) + @TableLogic +#end +private ${field.propertyType} ${field.propertyName}; +#end +## ---------- END 字段循环遍历 ---------- +#if(!${entityLombokModel}) +#foreach($field in ${table.fields}) +#if(${field.propertyType.equals("boolean")}) +#set($getprefix="is") +#else +#set($getprefix="get") +#end + + public ${field.propertyType} ${getprefix}${field.capitalName}() { + return ${field.propertyName}; + } + +#if(${entityBuilderModel}) + public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) { +#else + public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) { +#end + this.${field.propertyName} = ${field.propertyName}; +#if(${entityBuilderModel}) + return this; +#end + } +#end +#end + +#if(${entityColumnConstant}) +#foreach($field in ${table.fields}) + public static final String ${field.name.toUpperCase()} = "${field.name}"; + +#end +#end +#if(${activeRecord}) + @Override + protected Serializable pkVal() { +#if(${keyPropertyName}) + return this.${keyPropertyName}; +#else + return null; +#end + } +#end +#if(!${entityLombokModel}) + @Override + public String toString() { + return "${entity}{" + +#foreach($field in ${table.fields}) +#if($!{foreach.index}==0) + "${field.propertyName}=" + ${field.propertyName} + +#else + ", ${field.propertyName}=" + ${field.propertyName} + +#end +#end + "}"; + } +#end +} \ No newline at end of file diff --git a/ruoyi-api/src/test/resources/templates/service.java.vm b/ruoyi-api/src/test/resources/templates/service.java.vm new file mode 100644 index 0000000..9009d5c --- /dev/null +++ b/ruoyi-api/src/test/resources/templates/service.java.vm @@ -0,0 +1,41 @@ +package ${package.Service}; + +import ${package.Entity}.${entity}; +import ${superServiceClassPackage}; +import ${cfg.queryParamPath}; +import ${cfg.queryVoPath}; +import ${cfg.paging}; + +import java.io.Serializable; + +/** + *

+ * $!{table.comment} 服务类 + *

+ * + * @author ${author} + * @since ${date} + */ +#if(${kotlin}) +interface ${table.serviceName} : ${superServiceClass}<${entity}> +#else +public interface ${table.serviceName} extends ${superServiceClass}<${entity}> { +#if(${cfg.generatorStrategy}) + + /** + * 根据ID获取查询对象 + * @param id + * @return + */ + ${entity}QueryVo get${entity}ById(Serializable id) throws Exception; + + /** + * 获取分页对象 + * @param ${cfg.entityObjectName}QueryParam + * @return + */ + Paging<${entity}QueryVo> get${entity}PageList(${entity}QueryParam ${cfg.entityObjectName}QueryParam) throws Exception; +#end + +} +#end diff --git a/ruoyi-api/src/test/resources/templates/serviceImpl.java.vm b/ruoyi-api/src/test/resources/templates/serviceImpl.java.vm new file mode 100644 index 0000000..648f327 --- /dev/null +++ b/ruoyi-api/src/test/resources/templates/serviceImpl.java.vm @@ -0,0 +1,57 @@ +package ${package.ServiceImpl}; + +import ${package.Entity}.${entity}; +import ${package.Mapper}.${table.mapperName}; +import ${package.Service}.${table.serviceName}; +import ${cfg.queryParamPath}; +import ${cfg.queryVoPath}; +import ${superServiceImplClassPackage}; +import ${cfg.paging}; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.beans.factory.annotation.Autowired; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.metadata.OrderItem; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import java.io.Serializable; + + +/** + *

+ * $!{table.comment} 服务实现类 + *

+ * + * @author ${author} + * @since ${date} + */ +@Slf4j +@Service +@Transactional(rollbackFor = Exception.class) +#if(${kotlin}) +open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} { + +} +#else +public class ${table.serviceImplName} extends BaseServiceImpl<${table.mapperName}, ${entity}> implements ${table.serviceName} { + + @Autowired + private ${table.mapperName} ${cfg.mapperObjectName}; +#if(${cfg.generatorStrategy}) + + @Override + public ${entity}QueryVo get${entity}ById(Serializable id) throws Exception{ + return ${cfg.mapperObjectName}.get${entity}ById(id); + } + + @Override + public Paging<${entity}QueryVo> get${entity}PageList(${entity}QueryParam ${cfg.entityObjectName}QueryParam) throws Exception{ + Page page = setPageParam(${cfg.entityObjectName}QueryParam,OrderItem.desc("create_time")); + IPage<${entity}QueryVo> iPage = ${cfg.mapperObjectName}.get${entity}PageList(page,${cfg.entityObjectName}QueryParam); + return new Paging(iPage); + } +#end + +} +#end diff --git a/ruoyi-plus-api/pom.xml b/ruoyi-plus-api/pom.xml new file mode 100644 index 0000000..8d67582 --- /dev/null +++ b/ruoyi-plus-api/pom.xml @@ -0,0 +1,447 @@ + + + + ruoyi + com.ruoyi + 4.0.0 + + 4.0.0 + jar + ruoyi-plus-api + + + UTF-8 + ${utf8} + ${utf8} + ${parent.version} + 1.8 + 2.1.8.RELEASE + 3.2.0 + 1.2.60 + 2.6.1 + 3.9 + 4.4 + 1.7 + 5.1.47 + 1.1.20 + 2.6 + 0.9.11 + 1.13 + 3.6 + 1.18 + 1.18.8 + 2.7.0 + 0.9.1 + 2.1.6 + 4.6.4 + 4.12 + + 3.8.1 + 3.1.0 + 2.22.2 + 3.1.1 + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.boot + spring-boot-starter-tomcat + + + org.springframework.boot + spring-boot-starter-jdbc + + + org.springframework.boot + spring-boot-starter-data-redis + + + org.springframework.boot + spring-boot-starter-json + + + org.springframework.boot + spring-boot-starter-validation + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus-boot-starter.version} + + + com.baomidou + mybatis-plus-generator + ${mybatis-plus-boot-starter.version} + + + org.apache.velocity + velocity + ${velocity.version} + provided + + + mysql + mysql-connector-java + ${mysql.version} + + + + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + com.alibaba + fastjson + ${fastjson.version} + + + + + + io.springfox + springfox-swagger2 + 2.9.2 + + + io.swagger + swagger-annotations + 1.5.21 + + + io.swagger + swagger-models + 1.5.21 + + + io.springfox + springfox-swagger-ui + ${swagger2.version} + + + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + + commons-io + commons-io + ${commons-io.version} + + + commons-codec + commons-codec + ${commons-codec.version} + + + commons-net + commons-net + ${commons-net.version} + + + org.apache.commons + commons-pool2 + ${commons-pool2.version} + + + + + org.reflections + reflections + ${reflections.version} + + + + org.fusesource.jansi + jansi + ${jansi.version} + + + + org.projectlombok + lombok + ${lombok.version} + compile + + + + org.yaml + snakeyaml + + + + io.jsonwebtoken + jjwt + ${jwt.version} + + + + cn.hutool + hutool-all + ${hutool.version} + + + + + de.codecentric + spring-boot-admin-starter-server + ${spring-boot-admin.version} + + + de.codecentric + spring-boot-admin-starter-client + ${spring-boot-admin.version} + + + + + junit + junit + ${junit.version} + test + + + + + + spring-boot-plus + + + + + src/main/resources + true + + config/** + + + + + + src/main/resources/config + true + config + + application.yml + application-${profileActive}.yml + banner.txt + logback.xml + *.properties + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + io.geekidea.springbootplus.SpringBootPlusApplication + + + + + repackage + + + + + + + org.apache.maven.plugins + maven-resources-plugin + ${maven-resources-plugin.version} + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${java.version} + ${java.version} + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + true + true + + + + + + maven-assembly-plugin + 3.1.0 + + ${project.build.finalName}-server + + src/main/assembly/assembly.xml + + + + + make-assembly + package + + single + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + + -Xdoclint:none + + + + + attach-javadocs + + jar + + + + + + + + + + + + + + + + local + + local + + + true + + + + dev + + dev + + + false + + + + test + + test + + + false + + + + uat + + uat + + + false + + + + prod + + prod + + + false + + + + + + + + + aliyun + aliyun-maven + http://maven.aliyun.com/nexus/content/groups/public/ + + + spring-milestones + Spring Milestones + https://maven.aliyun.com/repository/spring + + + central + maven-central + http://central.maven.org/maven2/ + + + + + \ No newline at end of file diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/SpringBootPlusApplication.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/SpringBootPlusApplication.java new file mode 100644 index 0000000..cb9da06 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/SpringBootPlusApplication.java @@ -0,0 +1,52 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus; + +import de.codecentric.boot.admin.server.config.EnableAdminServer; +import com.ruoyi.plus.util.PrintApplicationInfo; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +/** + * spring-boot-plus 项目启动入口 + * @author geekidea + * @since 2018-11-08 + */ +@EnableAsync +//@EnableScheduling +@EnableTransactionManagement +@EnableConfigurationProperties +//@EnableAdminServer +@MapperScan({"com.ruoyi.plus.**.mapper"}) +@SpringBootApplication +public class SpringBootPlusApplication { + + public static void main(String[] args) { + // 启动spring-boot-plus + ConfigurableApplicationContext context = SpringApplication.run(SpringBootPlusApplication.class, args); + // 打印项目信息 + PrintApplicationInfo.print(context); + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/aop/LogAop.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/aop/LogAop.java new file mode 100644 index 0000000..4e78dc4 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/aop/LogAop.java @@ -0,0 +1,292 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.aop; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.ruoyi.plus.common.api.ApiCode; +import com.ruoyi.plus.common.api.ApiResult; +import com.ruoyi.plus.util.AnsiUtil; +import com.ruoyi.plus.util.DateUtil; +import com.ruoyi.plus.util.IpUtil; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.fusesource.jansi.Ansi; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + *

+ * Controller Aop + * 获取响应结果信息 + *

+ * + * @author geekidea + * @date 2018-11-08 + */ +@Data +@Slf4j +@Aspect +public class LogAop { + + /** + * 切点 + */ + private static final String POINTCUT = "execution(public * io.geekidea.springbootplus.*.web.controller..*.*(..))"; + /** + * 默认的请求内容类型,表单提交 + **/ + private static final String APPLICATION_X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded"; + /** + * JSON请求内容类型 + **/ + private static final String APPLICATION_JSON = "application/json"; + /** + * GET请求 + **/ + private static final String GET = "GET"; + /** + * POST请求 + **/ + private static final String POST = "POST"; + + /** + * 请求日志是否格式化输出 + */ + private boolean requestLogFormat; + + /** + * 响应日期是否格式化输出 + */ + private boolean responseLogFormat; + + @Around(POINTCUT) + public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { + + // 获取请求相关信息 + try { + // 获取当前的HttpServletRequest对象 + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + HttpServletRequest request = attributes.getRequest(); + + + Map map = new LinkedHashMap<>(); + + // 获取请求类名和方法名称 + Signature signature = joinPoint.getSignature(); + + // 获取真实的方法对象 + MethodSignature methodSignature = (MethodSignature) signature; + Method method = methodSignature.getMethod(); + + // 请求全路径 + String url = request.getRequestURI(); + map.put("path",url); + // IP地址 + String ip = IpUtil.getRequestIp(); + map.put("ip",ip); + + // 获取请求方式 + String requestMethod = request.getMethod(); + map.put("requestMethod",requestMethod); + + // 获取请求内容类型 + String contentType = request.getContentType(); + map.put("contentType",contentType); + + // 判断控制器方法参数中是否有RequestBody注解 + Annotation[][] annotations = method.getParameterAnnotations(); + boolean isRequestBody = isRequestBody(annotations); + map.put("isRequestBody",isRequestBody); + // 设置请求参数 + Object requestParamJson = getRequestParamJsonString(joinPoint, request, requestMethod, contentType, isRequestBody); + map.put("param",requestParamJson); + map.put("time", DateUtil.getYYYYMMDDHHMMSS(new Date())); + + // 获取请求头token + map.put("x-auth-token",request.getHeader("x-auth-token")); + + String requestInfo = null; + try { + if (requestLogFormat){ + requestInfo = "\n" + JSON.toJSONString(map,true); + }else{ + requestInfo = JSON.toJSONString(map); + } + } catch (Exception e) { + + } + log.info(AnsiUtil.getAnsi(Ansi.Color.GREEN,"requestInfo:" + requestInfo)); + + } catch (Exception e) { + e.printStackTrace(); + } + + + + // 执行目标方法,获得返回值 + Object result = joinPoint.proceed(); + try{ + if (result != null && result instanceof ApiResult){ + ApiResult apiResult = (ApiResult) result; + int code = apiResult.getCode(); + String responseResultInfo = "responseResult:"; + if (responseLogFormat){ + responseResultInfo += "\n" + JSON.toJSONString(apiResult,true); + }else{ + responseResultInfo += JSON.toJSONString(apiResult); + } + if (code == ApiCode.SUCCESS.getCode()){ + log.info(AnsiUtil.getAnsi(Ansi.Color.BLUE,responseResultInfo)); + }else{ + log.error(AnsiUtil.getAnsi(Ansi.Color.RED,responseResultInfo)); + } + + } + }catch (Exception e){ + log.error("处理响应结果异常",e); + } + return result; + } + + + + /** + * 获取请求参数JSON字符串 + * + * @param joinPoint + * @param request + * @param requestMethod + * @param contentType + * @param isRequestBody + */ + private Object getRequestParamJsonString(ProceedingJoinPoint joinPoint, HttpServletRequest request, String requestMethod, String contentType, boolean isRequestBody) { + /** + * 判断请求内容类型 + * 通常有3中请求内容类型 + * 1.发送get请求时,contentType为null + * 2.发送post请求时,contentType为application/x-www-form-urlencoded + * 3.发送post json请求,contentType为application/json + * 4.发送post json请求并有RequestBody注解,contentType为application/json + */ + Object paramObject = null; + int requestType = 0; + if (GET.equals(requestMethod)) { + requestType = 1; + } else if (POST.equals(requestMethod)) { + if (contentType == null) { + requestType = 5; + } else if (contentType.startsWith(APPLICATION_X_WWW_FORM_URLENCODED)) { + requestType = 2; + } else if (contentType.startsWith(APPLICATION_JSON)) { + if (isRequestBody) { + requestType = 4; + } else { + requestType = 3; + } + } + } + + // 1,2,3中类型时,获取getParameterMap中所有的值,处理后序列化成JSON字符串 + if (requestType == 1 || requestType == 2 || requestType == 3 || requestType == 5) { + Map paramsMap = request.getParameterMap(); + paramObject = getJsonForParamMap(paramsMap); + } else if (requestType == 4) { // POST,application/json,RequestBody的类型,简单判断,然后序列化成JSON字符串 + Object[] args = joinPoint.getArgs(); + paramObject = argsArrayToJsonString(args); + } + + return paramObject; + } + + /** + * 判断控制器方法参数中是否有RequestBody注解 + * + * @param annotations + * @return + */ + private boolean isRequestBody(Annotation[][] annotations) { + boolean isRequestBody = false; + for (Annotation[] annotationArray : annotations) { + for (Annotation annotation : annotationArray) { + if (annotation instanceof RequestBody) { + isRequestBody = true; + } + } + } + return isRequestBody; + } + + /** + * 请求参数拼装 + * + * @param args + * @return + */ + private Object argsArrayToJsonString(Object[] args) { + if (args == null) { + return null; + } + if (args.length == 1) { + return args[0]; + } else { + return args; + } + } + + + /** + * 获取参数Map的JSON字符串 + * + * @param paramsMap + * @return + */ + public JSONObject getJsonForParamMap(Map paramsMap) { + int paramSize = paramsMap.size(); + if (paramsMap == null || paramSize == 0) { + return null; + } + JSONObject jsonObject = new JSONObject(); + for (Map.Entry kv : paramsMap.entrySet()) { + String key = kv.getKey(); + String[] values = kv.getValue(); + if (values == null) { // 没有值 + jsonObject.put(key, null); + } else if (values.length == 1) { // 一个值 + jsonObject.put(key, values[0]); + } else { // 多个值 + jsonObject.put(key, values); + } + } + return jsonObject; + } + + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/api/ApiCode.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/api/ApiCode.java new file mode 100644 index 0000000..d004742 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/api/ApiCode.java @@ -0,0 +1,77 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.api; + +/** + *

+ * REST API 响应码 + *

+ * + * @author geekidea + * @since 2018-11-08 + */ +public enum ApiCode { + + SUCCESS(200, "操作成功"), + + UNAUTHORIZED(401, "非法访问"), + + NOT_PERMISSION(403, "没有权限"), + + NOT_FOUND(404, "你请求的路径不存在"), + + FAIL(500, "操作失败"), + + SYSTEM_EXCEPTION(5000,"系统异常!"), + + PARAMETER_EXCEPTION(5001,"请求参数校验异常"), + + PARAMETER_PARSE_EXCEPTION(5002,"请求参数解析异常"), + + HTTP_MEDIA_TYPE_EXCEPTION(5003,"HTTP Media 类型异常"), + + SYSTEM_LOGIN_EXCEPTION(5005,"系统登录异常") + + ; + + private final int code; + private final String msg; + + ApiCode(final int code, final String msg) { + this.code = code; + this.msg = msg; + } + + public static ApiCode getApiCode(int code) { + ApiCode[] ecs = ApiCode.values(); + for (ApiCode ec : ecs) { + if (ec.getCode() == code) { + return ec; + } + } + return SUCCESS; + } + + public int getCode() { + return code; + } + + public String getMsg() { + return msg; + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/api/ApiController.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/api/ApiController.java new file mode 100644 index 0000000..2343d38 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/api/ApiController.java @@ -0,0 +1,69 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.api; + +import lombok.extern.slf4j.Slf4j; + +/** + *

+ * ApiResultEST API 公共控制器 + *

+ * + * @author geekidea + * @since 2018-11-08 + */ +@Slf4j +public class ApiController { + + /** + *

+ * 请求成功 + *

+ * + * @param data 数据内容 + * @param 对象泛型 + * @return + */ + protected ApiResult ok(T data) { + return ApiResult.ok(data); + } + + /** + *

+ * 请求失败 + *

+ * + * @param msg 提示内容 + * @return + */ + protected ApiResult fail(String msg) { + return ApiResult.fail(msg); + } + + /** + *

+ * 请求失败 + *

+ * + * @param apiCode 请求错误码 + * @return + */ + protected ApiResult fail(ApiCode apiCode) { + return ApiResult.fail(apiCode); + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/api/ApiResult.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/api/ApiResult.java new file mode 100644 index 0000000..41bc1f5 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/api/ApiResult.java @@ -0,0 +1,125 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.api; + +import com.alibaba.fastjson.annotation.JSONField; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.experimental.Accessors; +import org.apache.commons.lang3.StringUtils; + +import java.io.Serializable; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + *

+ * REST API 返回结果 + *

+ * + * @author geekidea + * @since 2018-11-08 + */ +@Data +@Accessors(chain = true) +@Builder +@AllArgsConstructor +public class ApiResult implements Serializable { + + private int code; + + private T data; + + private String msg; + + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date time; + + public ApiResult() { + + } + + public static ApiResult result(boolean flag){ + if (flag){ + return ok(); + } + return fail(""); + } + + public static ApiResult result(ApiCode apiCode){ + return result(apiCode,null); + } + + public static ApiResult result(ApiCode apiCode,Object data){ + return result(apiCode,null,data); + } + + public static ApiResult result(ApiCode apiCode,String msg,Object data){ + String message = apiCode.getMsg(); + if (StringUtils.isNotBlank(msg)){ + message = msg; + } + return ApiResult.builder() + .code(apiCode.getCode()) + .msg(message) + .data(data) + .time(new Date()) + .build(); + } + + public static ApiResult ok(){ + return ok(null); + } + + public static ApiResult ok(Object data){ + return result(ApiCode.SUCCESS,data); + } + + public static ApiResult ok(String key,Object value){ + Map map = new HashMap<>(); + map.put(key,value); + return ok(map); + } + + public static ApiResult fail(ApiCode apiCode){ + return result(apiCode,null); + } + + public static ApiResult fail(String msg){ + return result(ApiCode.FAIL,msg,null); + + } + + public static ApiResult fail(ApiCode apiCode,Object data){ + if (ApiCode.SUCCESS == apiCode){ + throw new RuntimeException("失败结果状态码不能为" + ApiCode.SUCCESS.getCode()); + } + return result(apiCode,data); + + } + + public static ApiResult fail(String key,Object value){ + Map map = new HashMap<>(); + map.put(key,value); + return result(ApiCode.FAIL,map); + } + +} \ No newline at end of file diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/api/Assert.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/api/Assert.java new file mode 100644 index 0000000..f5576c5 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/api/Assert.java @@ -0,0 +1,180 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.api; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.api.IErrorCode; +import com.baomidou.mybatisplus.extension.exceptions.ApiException; + +import java.util.Collection; +import java.util.Map; + +/** + *

+ * REST API 业务断言
+ * 参考:org.junit.Assert + *

+ * + * @author geekidea + * @since 2018-11-08 + */ +public class Assert { + + protected Assert() { + // to do noting + } + + /** + * 大于O + */ + public static void gtZero(Integer num, IErrorCode errorCode) { + if (num == null || num <= 0) { + Assert.fail(errorCode); + } + } + + /** + * 大于等于O + */ + public static void geZero(Integer num, IErrorCode errorCode) { + if (num == null || num < 0) { + Assert.fail(errorCode); + } + } + + /** + * num1大于num2 + */ + public static void gt(Integer num1, Integer num2, IErrorCode errorCode) { + if (num1 <= num2) { + Assert.fail(errorCode); + } + } + + /** + * num1大于等于num2 + */ + public static void ge(Integer num1, Integer num2, IErrorCode errorCode) { + if (num1 < num2) { + Assert.fail(errorCode); + } + } + + /** + * obj1 eq obj2 + */ + public static void eq(Object obj1, Object obj2, IErrorCode errorCode) { + if (!obj1.equals(obj2)) { + Assert.fail(errorCode); + } + } + + public static void isTrue(boolean condition, IErrorCode errorCode) { + if (!condition) { + Assert.fail(errorCode); + } + } + + public static void isFalse(boolean condition, IErrorCode errorCode) { + if (condition) { + Assert.fail(errorCode); + } + } + + public static void isNull(IErrorCode errorCode, Object... conditions) { + if (ObjectUtils.isNotNull(conditions)) { + Assert.fail(errorCode); + } + } + + public static void notNull(IErrorCode errorCode, Object... conditions) { + if (ObjectUtils.isNull(conditions)) { + Assert.fail(errorCode); + } + } + + /** + *

+ * 失败结果 + *

+ * + * @param errorCode 异常错误码 + */ + public static void fail(IErrorCode errorCode) { + throw new ApiException(errorCode); + } + + public static void fail(boolean condition, IErrorCode errorCode) { + if (condition) { + Assert.fail(errorCode); + } + } + + public static void fail(String message) { + throw new ApiException(message); + } + + public static void fail(boolean condition, String message) { + if (condition) { + Assert.fail(message); + } + } + + public static void notEmpty(Object[] array, IErrorCode errorCode) { + if (ObjectUtils.isEmpty(array)) { + Assert.fail(errorCode); + } + } + + public static void noNullElements(Object[] array, IErrorCode errorCode) { + if (array != null) { + for (Object element : array) { + if (element == null) { + Assert.fail(errorCode); + } + } + } + } + + public static void notEmpty(Collection collection, IErrorCode errorCode) { + if (CollectionUtils.isNotEmpty(collection)) { + Assert.fail(errorCode); + } + } + + public static void notEmpty(Map map, IErrorCode errorCode) { + if (ObjectUtils.isEmpty(map)) { + Assert.fail(errorCode); + } + } + + public static void isInstanceOf(Class type, Object obj, IErrorCode errorCode) { + Assert.notNull(errorCode, type); + if (!type.isInstance(obj)) { + Assert.fail(errorCode); + } + } + + public static void isAssignable(Class superType, Class subType, IErrorCode errorCode) { + Assert.notNull(errorCode, superType); + if (subType == null || !superType.isAssignableFrom(subType)) { + Assert.fail(errorCode); + } + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constant/CacheKey.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constant/CacheKey.java new file mode 100644 index 0000000..7edde2d --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constant/CacheKey.java @@ -0,0 +1,22 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.constant; + + +public interface CacheKey { + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constant/CommonConstant.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constant/CommonConstant.java new file mode 100644 index 0000000..4945a4d --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constant/CommonConstant.java @@ -0,0 +1,66 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.constant; + +/** + * 常量 + * @author geekidea + * @date 2018-11-08 + */ +public interface CommonConstant { + + /** + * 默认页码为1 + */ + Integer DEFAULT_PAGE_INDEX = 1; + + /** + * 默认页大小为10 + */ + Integer DEFAULT_PAGE_SIZE = 10; + + /** + * 登录用户 + */ + String LOGIN_SYS_USER = "loginSysUser"; + + /** + * 登陆token + */ + String TOKEN = "token"; + /** + * 刷新token + */ + String REFRESH_TOKEN = "refresh_token"; + + /** + * 初始密码 + */ + String INIT_PWD = "123456"; + + /** + * 默认头像 + */ + String DEFAULT_HEAD_URL = ""; + + /** + * 管理员角色名称 + */ + String ADMIN_ROLE_NAME = "管理员"; + + String ADMIN_LOGIN = "adminLogin"; +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constant/CommonRedisKey.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constant/CommonRedisKey.java new file mode 100644 index 0000000..3ab832b --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constant/CommonRedisKey.java @@ -0,0 +1,37 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.constant; + +/** + *

+ * redis key 常量 + *

+ * @author geekidea + * @date 2019-05-23 + **/ +public interface CommonRedisKey { + + /** + * 系统登录用户 + */ + String LOGIN_SYS_USER = "login:sys:user:%s"; + /** + * 系统登录token + */ + String LOGIN_TOKEN = "login:token"; + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constant/DatePattern.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constant/DatePattern.java new file mode 100644 index 0000000..635f6ba --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constant/DatePattern.java @@ -0,0 +1,57 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.constant; + +/** + *

+ * 日期格式常量 + *

+ * @author geekidea + * @date 2018-11-08 + */ +public interface DatePattern { + + /** + * 年-月-日 + */ + String yyyy_MM_dd = "yyyy-MM-dd"; + /** + * 年-月-日 时:分 + */ + String yyyy_MM_dd_HH_mm = "yyyy-MM-dd HH:mm"; + /** + * 年-月-日 时:分:秒 + */ + String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss"; + /** + * 年-月-日 时:分:秒:毫秒 + */ + String yyyy_MM_dd_HH_mm_ss_S = "yyyy-MM-dd HH:mm:ss.S"; + + /** + * 时:分 + */ + String HH_mm = "HH:mm"; + /** + * 时:分:秒 + */ + String HH_mm_ss = "HH:mm:ss"; + /** + * 时:分:秒:毫秒 + */ + String HH_mm_ss_S = "HH:mm:ss:S"; +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/Email.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/Email.java new file mode 100644 index 0000000..40b11d0 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/Email.java @@ -0,0 +1,45 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.constraints; + + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * 自定义系统内的枚举验证注解 + * @author geekidea + * @date 2018-11-08 + */ +@Documented +@Constraint(validatedBy = { EmailValidator.class }) +@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) +@Retention(RUNTIME) +public @interface Email { + String message() default "请输入有效的邮箱"; + + Class[] groups() default { }; + + Class[] payload() default { }; + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/EmailValidator.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/EmailValidator.java new file mode 100644 index 0000000..045cd6c --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/EmailValidator.java @@ -0,0 +1,43 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.constraints; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.regex.Pattern; + +/** + * 自定义邮箱验证注解实现类 + * @author geekidea + * @date 2018-11-08 + */ +public class EmailValidator implements ConstraintValidator { + private static final String REG_EX = "^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\\.[a-zA-Z0-9]{2,6}$"; + private static final Pattern PATTERN = Pattern.compile(REG_EX); + + @Override + public void initialize(Email parameters) { + } + + @Override + public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) { + if (value ==null){ + return true; + } + return PATTERN.matcher(value).matches(); + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/EnumType.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/EnumType.java new file mode 100644 index 0000000..e2f0085 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/EnumType.java @@ -0,0 +1,48 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.constraints; + +import com.ruoyi.plus.common.enums.BaseTypeStateEnum; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * 自定义邮箱正则验证注解 + * @author geekidea + * @date 2018-11-08 + */ +@Documented +@Constraint(validatedBy = { EnumTypeValidator.class }) +@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) +@Retention(RUNTIME) +public @interface EnumType { + String message() default "请输入正确的类型值"; + + Class type(); + + Class[] groups() default { }; + + Class[] payload() default { }; + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/EnumTypeValidator.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/EnumTypeValidator.java new file mode 100644 index 0000000..083fb6e --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/EnumTypeValidator.java @@ -0,0 +1,36 @@ + + +package com.ruoyi.plus.common.constraints; + +import com.ruoyi.plus.common.enums.BaseTypeStateEnum; +import com.ruoyi.plus.common.exception.BusinessException; +import com.ruoyi.plus.util.EnumUtil; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +/** + * 自定义系统内的枚举验证注解实现类 + * @author geekidea + * @date 2018-11-08 + */ +public class EnumTypeValidator implements ConstraintValidator { + + private Class baseTypeStateEnum; + + @Override + public void initialize(EnumType parameters) { + baseTypeStateEnum = parameters.type(); + if (baseTypeStateEnum == null){ + throw new BusinessException("请传入枚举类型类"); + } + } + + @Override + public boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) { + if (value ==null){ + return true; + } + return EnumUtil.exists(baseTypeStateEnum,value); + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/IdCard.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/IdCard.java new file mode 100644 index 0000000..8a9ee6b --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/IdCard.java @@ -0,0 +1,44 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.constraints; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * 自定义身份证号码正则验证注解 + * @author geekidea + * @date 2018-11-08 + */ +@Documented +@Constraint(validatedBy = { IdCardValidator.class }) +@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) +@Retention(RUNTIME) +public @interface IdCard { + String message() default "请输入有效的身份证号码"; + + Class[] groups() default { }; + + Class[] payload() default { }; + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/IdCardValidator.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/IdCardValidator.java new file mode 100644 index 0000000..d17dc3c --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/IdCardValidator.java @@ -0,0 +1,43 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.constraints; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.regex.Pattern; + +/** + * 自定义身份证号码验证注解实现类 + * @author geekidea + * @date 2018-11-08 + */ +public class IdCardValidator implements ConstraintValidator { + private static final String REG_EX = "(^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{2}[0-9Xx]$)|(^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}[0-9Xx]$)"; + private static final Pattern PATTERN = Pattern.compile(REG_EX); + + @Override + public void initialize(IdCard parameters) { + } + + @Override + public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) { + if (value ==null){ + return true; + } + return PATTERN.matcher(value).matches(); + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/Phone.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/Phone.java new file mode 100644 index 0000000..3e78ebb --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/Phone.java @@ -0,0 +1,44 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.constraints; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * 自定义手机号码正则验证注解 + * @author geekidea + * @date 2018-11-08 + */ +@Documented +@Constraint(validatedBy = { PhoneValidator.class }) +@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) +@Retention(RUNTIME) +public @interface Phone { + String message() default "请输入有效的手机号码"; + + Class[] groups() default { }; + + Class[] payload() default { }; + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/PhoneValidator.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/PhoneValidator.java new file mode 100644 index 0000000..3c8ef75 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/constraints/PhoneValidator.java @@ -0,0 +1,44 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.constraints; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.regex.Pattern; + +/** + * 自定义手机号码验证注解实现类 + * @author geekidea + * @date 2018-11-08 + */ +public class PhoneValidator implements ConstraintValidator { + + private static final String REG_EX = "^1[3,4,5,6,7,8,9]\\d{9}$"; + private static final Pattern PATTERN = Pattern.compile(REG_EX); + + @Override + public void initialize(Phone parameters) { + } + + @Override + public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) { + if (value ==null){ + return true; + } + return PATTERN.matcher(value).matches(); + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/entity/BaseEntity.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/entity/BaseEntity.java new file mode 100644 index 0000000..d4259af --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/entity/BaseEntity.java @@ -0,0 +1,29 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.entity; + +import io.swagger.annotations.ApiModel; + +import java.io.Serializable; + +/** + * @author geekidea + * @date 2018-11-08 + */ +@ApiModel("BaseEntity") +public abstract class BaseEntity implements Serializable{ +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/enums/BaseTypeStateEnum.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/enums/BaseTypeStateEnum.java new file mode 100644 index 0000000..5d2d290 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/enums/BaseTypeStateEnum.java @@ -0,0 +1,30 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.enums; + +/** + * @author geekidea + * @date 2018-11-08 + */ +public interface BaseTypeStateEnum { + + Integer getKey(); + + String getValue(); + + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/exception/BusinessException.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/exception/BusinessException.java new file mode 100644 index 0000000..1e3dedc --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/exception/BusinessException.java @@ -0,0 +1,47 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.exception; + +import org.apache.commons.lang3.StringUtils; + +/** + * 业务异常 + * @author geekidea + * @date 2018-11-08 + */ +public class BusinessException extends RuntimeException{ + private Integer code; + public BusinessException() { + } + + public BusinessException(String message) { + super(message); + } + + public BusinessException(Integer code ,String message){ + this(StringUtils.isBlank(message)?String.valueOf(code):message); + this.code=code; + } + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/exception/GlobalErrorController.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/exception/GlobalErrorController.java new file mode 100644 index 0000000..e5b02cd --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/exception/GlobalErrorController.java @@ -0,0 +1,51 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.exception; + +import com.ruoyi.plus.common.api.ApiCode; +import com.ruoyi.plus.common.api.ApiResult; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.web.servlet.error.ErrorController; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import springfox.documentation.annotations.ApiIgnore; + + +/** + * 全局Error/404处理 + * @author geekidea + * @date 2018-11-08 + */ +@ApiIgnore +@RestController +@Slf4j +public class GlobalErrorController implements ErrorController { + + private static final String ERROR_PATH = "/error"; + + @RequestMapping(ERROR_PATH) + public ApiResult handleError(){ + log.error("404 NOT FOUND"); + return ApiResult.fail(ApiCode.NOT_FOUND); + } + + @Override + public String getErrorPath() { + log.error("errorPath...."); + return ERROR_PATH; + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/exception/GlobalExceptionHandler.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..aabdf7b --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/exception/GlobalExceptionHandler.java @@ -0,0 +1,115 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.exception; + +import com.alibaba.fastjson.JSON; +import com.ruoyi.plus.common.api.ApiCode; +import com.ruoyi.plus.common.api.ApiResult; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.validation.BindingResult; +import org.springframework.validation.FieldError; +import org.springframework.web.HttpMediaTypeException; +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.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author geekidea + * @date 2018-11-08 + */ +@ControllerAdvice +@RestController +@Slf4j +public class GlobalExceptionHandler { + + /** + * 非法参数验证异常 + * @param ex + * @return + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + @ResponseStatus(value = HttpStatus.OK) + public ApiResult handleMethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException ex) { + BindingResult bindingResult = ex.getBindingResult(); + List list = new ArrayList<>(); + List fieldErrors = bindingResult.getFieldErrors(); + for (FieldError fieldError : fieldErrors) { + list.add(fieldError.getDefaultMessage()); + } + Collections.sort(list); + log.error("fieldErrors"+ JSON.toJSONString(list)); + return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION,list); + } + + /** + * 系统登录异常处理 + * @param exception + * @return + */ + @ExceptionHandler(value = SysLoginException.class) + @ResponseStatus(HttpStatus.OK) + public ApiResult sysLoginExceptionHandler(SysLoginException exception) { + log.warn("系统登录异常:" + exception.getMessage()); + return ApiResult.fail(ApiCode.SYSTEM_LOGIN_EXCEPTION); + } + + + /** + * HTTP解析请求参数异常 + * @param exception + * @return + */ + @ExceptionHandler(value = HttpMessageNotReadableException.class) + @ResponseStatus(HttpStatus.OK) + public ApiResult httpMessageNotReadableException(HttpMessageNotReadableException exception) { + log.error("httpMessageNotReadableException:",exception); + return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, ApiCode.PARAMETER_PARSE_EXCEPTION); + } + + /** + * HTTP + * @param exception + * @return + */ + @ExceptionHandler(value = HttpMediaTypeException.class) + @ResponseStatus(HttpStatus.OK) + public ApiResult httpMediaTypeException(HttpMediaTypeException exception) { + log.error("httpMediaTypeException:",exception); + return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, ApiCode.HTTP_MEDIA_TYPE_EXCEPTION); + } + + /** + * 默认的异常处理 + * @param exception + * @return + */ + @ExceptionHandler(value = Exception.class) + @ResponseStatus(HttpStatus.OK) + public ApiResult exceptionHandler(Exception exception) { + log.error("exception:",exception); + return ApiResult.fail(ApiCode.SYSTEM_EXCEPTION); + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/exception/SysLoginException.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/exception/SysLoginException.java new file mode 100644 index 0000000..4f2480c --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/exception/SysLoginException.java @@ -0,0 +1,47 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.exception; + +import org.apache.commons.lang3.StringUtils; + +/** + * 系统登录异常 + * @author geekidea + * @date 2019-08-04 + */ +public class SysLoginException extends RuntimeException{ + private Integer code; + public SysLoginException() { + } + + public SysLoginException(String message) { + super(message); + } + + public SysLoginException(Integer code , String message){ + this(StringUtils.isBlank(message)?String.valueOf(code):message); + this.code=code; + } + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/package-info.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/package-info.java new file mode 100644 index 0000000..efcb621 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/package-info.java @@ -0,0 +1,22 @@ +/** + * 公共部分 + * @author geekidea + * @date 2018-11-08 + */ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common; \ No newline at end of file diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/service/BaseService.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/service/BaseService.java new file mode 100644 index 0000000..0ba059a --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/service/BaseService.java @@ -0,0 +1,27 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * @author geekidea + * @date 2018-11-08 + */ +public interface BaseService extends IService { + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/service/impl/BaseServiceImpl.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/service/impl/BaseServiceImpl.java new file mode 100644 index 0000000..6ce3565 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/service/impl/BaseServiceImpl.java @@ -0,0 +1,66 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.service.impl; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.OrderItem; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.plus.common.service.BaseService; +import com.ruoyi.plus.common.web.param.OrderQueryParam; +import com.ruoyi.plus.common.web.param.QueryParam; +import org.apache.commons.collections.CollectionUtils; + +import java.util.Arrays; +import java.util.List; + +/** + * @author geekidea + * @date 2018-11-08 + */ +public abstract class BaseServiceImpl, T> extends ServiceImpl implements BaseService { + + protected Page setPageParam(QueryParam queryParam) { + return setPageParam(queryParam,null); + } + + protected Page setPageParam(QueryParam queryParam, OrderItem defaultOrder) { + Page page = new Page(); + // 设置当前页码 + page.setCurrent(queryParam.getCurrent()); + // 设置页大小 + page.setSize(queryParam.getSize()); + /** + * 如果是queryParam是OrderQueryParam,并且不为空,则使用前端排序 + * 否则使用默认排序 + */ + if (queryParam instanceof OrderQueryParam){ + OrderQueryParam orderQueryParam = (OrderQueryParam) queryParam; + List orderItems = orderQueryParam.getOrders(); + if (CollectionUtils.isEmpty(orderItems)){ + page.setOrders(Arrays.asList(defaultOrder)); + }else{ + page.setOrders(orderItems); + } + }else{ + page.setOrders(Arrays.asList(defaultOrder)); + } + + return page; + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/controller/ApiDocController.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/controller/ApiDocController.java new file mode 100644 index 0000000..cdbecb1 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/controller/ApiDocController.java @@ -0,0 +1,45 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.web.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import springfox.documentation.annotations.ApiIgnore; + +/** + *

+ * Api文档 + *

+ * + * @author geekidea + * @date 2018-11-08 + */ +@Controller +@RequestMapping("/docs") +@ApiIgnore +public class ApiDocController extends BaseController { + + /** + * swaggerUI + */ + @GetMapping("") + public String swaggerUI(){ + return "redirect:/swagger-ui.html"; + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/controller/BaseController.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/controller/BaseController.java new file mode 100644 index 0000000..0ea8a21 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/controller/BaseController.java @@ -0,0 +1,50 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.web.controller; + +import com.ruoyi.plus.common.api.ApiController; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author geekidea + * @date 2018-11-08 + */ +@Slf4j +public abstract class BaseController extends ApiController { + + /** + * 获取当前请求 + * + * @return request + */ + public HttpServletRequest getRequest() { + return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + } + /** + * 获取当前请求 + * + * @return response + */ + public HttpServletResponse getResponse() { + return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); + } +} \ No newline at end of file diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/controller/IndexController.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/controller/IndexController.java new file mode 100644 index 0000000..747f16a --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/controller/IndexController.java @@ -0,0 +1,42 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.web.controller; + +import com.ruoyi.plus.common.api.ApiResult; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import springfox.documentation.annotations.ApiIgnore; + +/** + *

+ * 项目根路径提示信息 + *

+ * @author geekidea + * @date 2018/11/12 + */ +@RestController +@ApiIgnore +@Slf4j +public class IndexController { + + @RequestMapping("/index") + public ApiResult index(){ + log.debug("index..."); + return ApiResult.ok("Welcome to Spring Boot Plus Project..."); + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/filter/CrossDomainFilter.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/filter/CrossDomainFilter.java new file mode 100644 index 0000000..1d13a8a --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/filter/CrossDomainFilter.java @@ -0,0 +1,73 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.web.filter; + +import com.alibaba.fastjson.JSON; +import com.ruoyi.plus.common.api.ApiResult; +import lombok.extern.slf4j.Slf4j; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +/** + * 设置允许跨域 + * @author geekidea + * @date 2018-11-08 + */ +@Slf4j +public class CrossDomainFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse; + httpServletResponse.setHeader("Access-Control-Allow-Origin", "*"); + httpServletResponse.setHeader("Access-Control-Allow-Methods", "*"); + httpServletResponse.setHeader("Access-Control-Allow-Headers", "*"); + httpServletResponse.setHeader("Access-Control-Request-Headers","*"); + httpServletResponse.setHeader("Access-Control-Allow-Headers", "content-type,x-auth-token"); + httpServletResponse.setHeader("Access-Control-Expose-Headers", "*"); + + HttpServletRequest request = (HttpServletRequest) servletRequest; + String method = request.getMethod(); + if ("OPTIONS".equals(method)){ + HttpServletResponse response = (HttpServletResponse) servletResponse; + response.setCharacterEncoding("UTF-8"); + PrintWriter w = response.getWriter(); + ApiResult apiResult = new ApiResult(); + apiResult.setCode(200); + apiResult.setMsg("ok..."); + w.append(JSON.toJSONString(apiResult)); + return; + } + + filterChain.doFilter(servletRequest, httpServletResponse); + + } + + @Override + public void destroy() { + + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/filter/RequestPathFilter.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/filter/RequestPathFilter.java new file mode 100644 index 0000000..c83efab --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/filter/RequestPathFilter.java @@ -0,0 +1,74 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.web.filter; + +import lombok.extern.slf4j.Slf4j; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * 请求路径过滤器 + * @author geekidea + * @date 2018-11-08 + */ +@Slf4j +public class RequestPathFilter implements Filter { + + private static List excludes = new ArrayList<>(); + + static { + // 控制台日志忽略spring boot admin访问路径 + excludes.add("/actuator"); + excludes.add("/instances"); + excludes.add("/logfile"); + excludes.add("/sba-settings.js"); + excludes.add("/assets/img/favicon.png"); + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletRequest req = (HttpServletRequest) request; + String path = req.getServletPath(); + String url = req.getRequestURL().toString(); + + boolean isOut = true; + for (String p : excludes){ + if (path.startsWith(p)){ + isOut = false; + break; + } + } + if (isOut){ + log.debug("requestURL:"+url); + } + chain.doFilter(req,response); + } + + @Override + public void destroy() { + + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/interceptor/PermissionInterceptor.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/interceptor/PermissionInterceptor.java new file mode 100644 index 0000000..9d70555 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/interceptor/PermissionInterceptor.java @@ -0,0 +1,47 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.web.interceptor; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 权限拦截器 + * + * @author geekidea + * @since 2018-11-08 + */ +@Slf4j +public class PermissionInterceptor extends HandlerInterceptorAdapter { + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws Exception { + log.info(request.getRequestURI()); + log.info("\n\nPermissionInterceptor...\n\n"); + return true; + } + + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { + } + +} \ No newline at end of file diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/interceptor/TokenTimeoutInterceptor.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/interceptor/TokenTimeoutInterceptor.java new file mode 100644 index 0000000..e46f860 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/interceptor/TokenTimeoutInterceptor.java @@ -0,0 +1,79 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.web.interceptor; + +import com.ruoyi.plus.common.constant.CommonConstant; +import com.ruoyi.plus.util.LoginUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.concurrent.TimeUnit; + +/** + * Token超时拦截器 + * + * @author geekidea + * @date 2018-11-08 + */ +@Slf4j +public class TokenTimeoutInterceptor extends HandlerInterceptorAdapter { + + @Autowired + private RedisTemplate redisTemplate; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws Exception { + + // 如果访问的不是控制器,则跳出,继续执行下一个拦截器 + if (!(handler instanceof HandlerMethod)) { + return true; + } + + // 获取token + String token = request.getHeader(CommonConstant.TOKEN); + boolean hastoken = false; + if (StringUtils.isNotBlank(token)){ + hastoken = true; + } + if (hastoken == false){ + token = request.getParameter(CommonConstant.TOKEN); + if (StringUtils.isNotBlank(token)){ + hastoken = true; + } + } + + // TODO 排除自动刷新的路径 + if (hastoken == true){ + // 如果有token,延长时间 + redisTemplate.expire(token,LoginUtil.TOKEN_VALID_TIME_MINUTE, TimeUnit.MINUTES); + } + + return true; + } + + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { + } +} \ No newline at end of file diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/param/IdParam.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/param/IdParam.java new file mode 100644 index 0000000..5d796c3 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/param/IdParam.java @@ -0,0 +1,36 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.web.param; + +import io.swagger.annotations.ApiModel; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + * @author geekidea + * @date 2018-11-08 + */ +@Data +@ApiModel("ID参数") +public class IdParam implements Serializable { + private static final long serialVersionUID = -5353973980674510450L; + + @NotBlank(message="ID不能为空") + private String id; +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/param/IdStatusParam.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/param/IdStatusParam.java new file mode 100644 index 0000000..673ceaf --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/param/IdStatusParam.java @@ -0,0 +1,61 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.web.param; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + +/** + * @author geekidea + * @date 2018-11-08 + */ +@ApiModel("主键状态VO") +public class IdStatusParam implements Serializable { + private static final long serialVersionUID = -7581307955242965701L; + + @ApiModelProperty("主键ID") + private String id; + + @ApiModelProperty("状态,1:启用 0:禁用") + private Integer status; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + @Override + public String toString() { + return "IdStatusVo{" + + "id='" + id + '\'' + + ", status=" + status + + '}'; + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/param/NameParam.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/param/NameParam.java new file mode 100644 index 0000000..068692c --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/param/NameParam.java @@ -0,0 +1,50 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.web.param; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + +/** + * 名称参数 + * @author geekidea + * @date 2018-11-08 + */ +@ApiModel("名称参数") +public class NameParam implements Serializable { + private static final long serialVersionUID = -3710501706034574149L; + + @ApiModelProperty("名称") + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "NameParam{" + + "name='" + name + '\'' + + '}'; + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/param/OrderQueryParam.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/param/OrderQueryParam.java new file mode 100644 index 0000000..39e702d --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/param/OrderQueryParam.java @@ -0,0 +1,54 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.web.param; + +import com.baomidou.mybatisplus.core.metadata.OrderItem; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.collections.CollectionUtils; + +import java.util.Arrays; +import java.util.List; + +/** + * 可排序查询参数对象 + * @author geekidea + * @since 2019-08-04 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ApiModel("可排序查询参数对象") +public abstract class OrderQueryParam extends QueryParam{ + private static final long serialVersionUID = 57714391204790143L; + + @ApiModelProperty(value = "排序") + private List orders; + + public void defaultOrder(OrderItem orderItem){ + this.defaultOrders(Arrays.asList(orderItem)); + } + + public void defaultOrders(List orderItems){ + if (CollectionUtils.isEmpty(orderItems)){ + return; + } + this.orders = orderItems; + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/param/QueryParam.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/param/QueryParam.java new file mode 100644 index 0000000..8f619aa --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/param/QueryParam.java @@ -0,0 +1,59 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.web.param; + +import com.ruoyi.plus.common.constant.CommonConstant; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * 查询参数 + * @author geekidea + * @since 2018-11-08 + */ +@Data +@ApiModel("查询参数对象") +public abstract class QueryParam implements Serializable{ + private static final long serialVersionUID = -3263921252635611410L; + + @ApiModelProperty(value = "页码,默认为1") + private Integer current = CommonConstant.DEFAULT_PAGE_INDEX; + @ApiModelProperty(value = "页大小,默认为10") + private Integer size = CommonConstant.DEFAULT_PAGE_SIZE; + @ApiModelProperty(value = "搜索字符串") + private String keyword; + + public void setCurrent(Integer current) { + if (current == null || current <= 0){ + this.current = CommonConstant.DEFAULT_PAGE_INDEX; + }else{ + this.current = current; + } + } + + public void setSize(Integer size) { + if (size == null || size <= 0){ + this.size = CommonConstant.DEFAULT_PAGE_SIZE; + }else{ + this.size = size; + } + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/vo/CommonIdName.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/vo/CommonIdName.java new file mode 100644 index 0000000..704d95b --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/vo/CommonIdName.java @@ -0,0 +1,80 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.web.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + *

+ * 公共ID-NAME-VO对象 + *

+ * @author geekidea + * @since 2018-11-08 + */ +@ApiModel("ID-NAME-VO") +public class CommonIdName { + + @ApiModelProperty("id") + private String id; + + @ApiModelProperty("名称") + private String name; + + + public String getId() { + return id; + } + + + public void setId(String id) { + this.id = id; + } + + + public String getName() { + return name; + } + + + public void setName(String name) { + this.name = name; + } + + + public CommonIdName(String id, String name) { + super(); + this.id = id; + this.name = name; + + } + + + public CommonIdName() { + super(); + } + + + @Override + public String toString() { + return "CommonIdName [id=" + id + ", name=" + name + "]"; + } + + + + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/vo/Paging.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/vo/Paging.java new file mode 100644 index 0000000..e143c29 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/common/web/vo/Paging.java @@ -0,0 +1,78 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.common.web.vo; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +/** + * @author geekidea + * @date 2018-11-08 + */ +@ApiModel("分页") +public class Paging implements Serializable { + private static final long serialVersionUID = -1683800405530086022L; + + @ApiModelProperty("总行数") + @JSONField(name = "total") + @JsonProperty("total") + private long total = 0; + + @ApiModelProperty("数据列表") + @JSONField(name = "records") + @JsonProperty("records") + private List records = Collections.emptyList(); + + public Paging() { + } + + public Paging(IPage page) { + this.total = page.getTotal(); + this.records = page.getRecords(); + } + + public long getTotal() { + return total; + } + + public void setTotal(long total) { + this.total = total; + } + + public List getRecords() { + return records; + } + + public void setRecords(List records) { + this.records = records; + } + + @Override + public String toString() { + return "Paging{" + + "total=" + total + + ", records=" + records + + '}'; + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/FilterConfig.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/FilterConfig.java new file mode 100644 index 0000000..7b96b35 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/FilterConfig.java @@ -0,0 +1,65 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config; + +import com.ruoyi.plus.common.web.filter.CrossDomainFilter; +import com.ruoyi.plus.common.web.filter.RequestPathFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; + +import javax.servlet.Filter; + + +/** + * @author geekidea + * @date 2018-11-08 + */ +@Configuration +public class FilterConfig { + + + @Bean + public Filter crossDomainFilter(){ + return new CrossDomainFilter(); + } + + @Bean + public Filter requestPathFilter(){ + return new RequestPathFilter(); + } + + @Bean + @Order(1) + public FilterRegistrationBean requestPathFilterBean() { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setFilter(requestPathFilter()); + registration.addUrlPatterns("/*"); + return registration; + } + + @Bean + @Order(2) + public FilterRegistrationBean crossDomainFilterBean() { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setFilter(crossDomainFilter()); + registration.addUrlPatterns("/*"); + return registration; + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/MultipartConfig.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/MultipartConfig.java new file mode 100644 index 0000000..8c68f81 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/MultipartConfig.java @@ -0,0 +1,51 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config; + +import org.springframework.boot.web.servlet.MultipartConfigFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.unit.DataSize; +import org.springframework.util.unit.DataUnit; + +import javax.servlet.MultipartConfigElement; + +/** + * 文件上传配置 + * @author geekidea + * @since 2018-11-08 + */ +@Configuration +public class MultipartConfig { + + /** + * 文件上传配置 + * @return + */ + @Bean + public MultipartConfigElement multipartConfigElement() { + MultipartConfigFactory factory = new MultipartConfigFactory(); + //单个文件最大 + //factory.setMaxFileSize("100MB"); //KB,MB + factory.setMaxFileSize(DataSize.of(100, DataUnit.MEGABYTES)); + ///设置总上传数据总大小 +// factory.setMaxRequestSize("100MB"); + factory.setMaxRequestSize(DataSize.of(100,DataUnit.MEGABYTES)); + return factory.createMultipartConfig(); + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/MybatisPlusConfig.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/MybatisPlusConfig.java new file mode 100644 index 0000000..619b8d0 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/MybatisPlusConfig.java @@ -0,0 +1,41 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config; + +import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + *

+ * MybatisPlus配置 + *

+ * @author geekidea + * @since 2018-11-08 + */ +@Configuration +public class MybatisPlusConfig { + + /** + * mybatis-plus分页插件
+ */ + @Bean + public PaginationInterceptor paginationInterceptor() { + return new PaginationInterceptor(); + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/RedisCacheConfig.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/RedisCacheConfig.java new file mode 100644 index 0000000..2c52eca --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/RedisCacheConfig.java @@ -0,0 +1,85 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config; + +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.CachingConfigurerSupport; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cache.interceptor.KeyGenerator; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.cache.RedisCacheManager; +import org.springframework.data.redis.connection.RedisConnectionFactory; + +import java.time.Duration; +import java.util.*; + +/** + *

+ * Redis Cache配置 + *

+ * @author geekidea + * @date 2018-11-08 + */ +@Configuration +@EnableCaching +public class RedisCacheConfig extends CachingConfigurerSupport { + + @Bean + @Override + public KeyGenerator keyGenerator() { + return (target, method, params) -> { + StringBuffer redisKey = new StringBuffer(); + redisKey.append(target.getClass().getName()).append("-"); + redisKey.append(method.getName()); + if (params.length > 0) { + redisKey.append("-").append(Arrays.deepToString(params)); + } + return redisKey.toString(); + }; + } + + + @Bean + public CacheManager cacheManager(RedisConnectionFactory factory) { + // 生成一个默认配置,通过config对象即可对缓存进行自定义配置 + RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig(); + // 设置缓存的默认过期时间,也是使用Duration设置 + config = config.entryTtl(Duration.ofMinutes(5)); // 过期时间5分钟 + //.disableCachingNullValues(); // 不缓存空值 + + // 设置一个初始化的缓存空间set集合 + Set cacheNames = new HashSet<>(); + cacheNames.add("my-redis-cache1"); + cacheNames.add("my-redis-cache2"); + + // 对每个缓存空间应用不同的配置 + Map configMap = new HashMap<>(); + configMap.put("my-redis-cache1", config); + configMap.put("my-redis-cache2", config.entryTtl(Duration.ofSeconds(120))); + + // 使用自定义的缓存配置初始化一个cacheManager + RedisCacheManager cacheManager = RedisCacheManager.builder(factory) + .initialCacheNames(cacheNames) // 注意这两句的调用顺序,一定要先调用该方法设置初始化的缓存名,再初始化相关的配置 + .withInitialCacheConfigurations(configMap) + .build(); + + return cacheManager; + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/RedisTemplateConfig.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/RedisTemplateConfig.java new file mode 100644 index 0000000..9ec19e6 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/RedisTemplateConfig.java @@ -0,0 +1,62 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config; + +import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + *

+ * Redis Template 配置 + *

+ * @author geekidea + * @date 2018-11-08 + */ +@Configuration +public class RedisTemplateConfig { + + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(redisConnectionFactory); + + // 自定义的string序列化器和fastjson序列化器 + StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); + + // jackson 序列化器 +// GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); + + // fastjson 序列化器 + GenericFastJsonRedisSerializer jsonRedisSerializer = new GenericFastJsonRedisSerializer(); + + // kv 序列化 + redisTemplate.setKeySerializer(stringRedisSerializer); + redisTemplate.setValueSerializer(jsonRedisSerializer); + + // hash 序列化 + redisTemplate.setHashKeySerializer(stringRedisSerializer); + redisTemplate.setHashValueSerializer(jsonRedisSerializer); + + redisTemplate.afterPropertiesSet(); + + return redisTemplate; + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/RestTemplateConfig.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/RestTemplateConfig.java new file mode 100644 index 0000000..c061c66 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/RestTemplateConfig.java @@ -0,0 +1,44 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; + +/** + * @author geekidea + * @date 2018-11-08 + */ +@Configuration +public class RestTemplateConfig { + + @Bean + public RestTemplate restTemplate(ClientHttpRequestFactory factory){ + return new RestTemplate(factory); + } + + @Bean + public ClientHttpRequestFactory simpleClientHttpRequestFactory(){ + SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); + factory.setReadTimeout(5000);//单位为ms + factory.setConnectTimeout(5000);//单位为ms + return factory; + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/Swagger2Config.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/Swagger2Config.java new file mode 100644 index 0000000..96d4fa4 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/Swagger2Config.java @@ -0,0 +1,123 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.ParameterBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.schema.ModelRef; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.service.Parameter; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import java.util.ArrayList; +import java.util.List; + +/** + * Swagger2全局配置 + * @author geekidea + * @date 2018-11-08 + */ +@Configuration +@EnableSwagger2 +public class Swagger2Config { + + /** + * 标题 + */ + @Value("${swagger.title}") + private String title; + + /** + * 基本包 + */ + @Value("${swagger.base.package}") + private String basePackage; + + /** + * 描述 + */ + @Value("${swagger.description}") + private String description; + + /** + * URL + */ + @Value("${swagger.url}") + private String url; + + /** + * 作者 + */ + @Value("${swagger.contact.name}") + private String contactName; + + /** + * 作者网址 + */ + @Value("${swagger.contact.url}") + private String contactUrl; + + /** + * 作者邮箱 + */ + @Value("${swagger.contact.email}") + private String contactEmail; + + /** + * 版本 + */ + @Value("${swagger.version}") + private String version; + + @Bean + public Docket createRestApi() { + return new Docket(DocumentationType.SWAGGER_2) + .apiInfo(apiInfo()) + .select() + .apis(RequestHandlerSelectors.basePackage(basePackage)) + .paths(PathSelectors.any()) + .build() + .globalOperationParameters(setHeaderToken()); + } + private ApiInfo apiInfo() { + return new ApiInfoBuilder() + .title(title) + .description(description) + .termsOfServiceUrl(url) + .contact(new Contact(contactName,contactUrl,contactEmail)) + .version(version) + .build(); + } + private List setHeaderToken() { + List pars = new ArrayList<>(); + + // TODO 测试token值,上线关闭 + String testTokenValue = ""; + ParameterBuilder tokenPar = new ParameterBuilder(); + Parameter tokenParameter = tokenPar.name("token").description("token").modelRef(new ModelRef("string")).parameterType("header").required(false).defaultValue(testTokenValue).build(); + pars.add(tokenParameter); + return pars; + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/ConverterConfig.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/ConverterConfig.java new file mode 100644 index 0000000..eb6521c --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/ConverterConfig.java @@ -0,0 +1,48 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config.converter; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.convert.converter.Converter; + +import java.util.Date; + +/** + * 转换器配置 + * @author geekidea + * @date 2018-11-08 + */ +@Configuration +public class ConverterConfig { + + @Bean + public Converter stringToDateConverter() { + return new StringToDateConverter(); + } + + @Bean + public Converter stringToIntegerConverter() { + return new StringToIntegerConverter(); + } + + @Bean + public Converter stringToDoubleConverter() { + return new StringToDoubleConverter(); + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/StringToDateConverter.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/StringToDateConverter.java new file mode 100644 index 0000000..ba7b233 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/StringToDateConverter.java @@ -0,0 +1,36 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config.converter; + +import org.springframework.core.convert.converter.Converter; + +import java.util.Date; + +/** + * + * 日期转换器,将请求参数的日期字符串转换成java.util.Date类型 + * + * @author geekidea + * @date 2018-11-08 + */ +public class StringToDateConverter implements Converter { + + @Override + public Date convert(String source) { + return StringToDateUtil.convert(source); + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/StringToDateUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/StringToDateUtil.java new file mode 100644 index 0000000..af5692c --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/StringToDateUtil.java @@ -0,0 +1,103 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config.converter; + +import org.apache.commons.lang3.StringUtils; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * + *
+ * 日期转换器,将请求参数的日期字符串转换成java.util.Date类型
+ * 日期格式顺序:
+ * 	1.yyyy-MM-dd HH:mm:ss:S
+ * 	2.yyyy-MM-dd HH:mm:ss
+ * 	3.yyyy-MM-dd HH:mm
+ * 	4.yyyy-MM-dd HH
+ *	5.yyyy-MM-dd
+ * 
+ *
+ * @author geekidea + * @date 2018-11-08 + */ +public class StringToDateUtil{ + /** + * 日期格式化数组 + */ + private static DateFormat[] dateFormats = { + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:S"), + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), + new SimpleDateFormat("yyyy-MM-dd HH:mm"), + new SimpleDateFormat("yyyy-MM-dd HH"), + new SimpleDateFormat("yyyy-MM-dd"), + new SimpleDateFormat("yyyy-MM") + }; + + /** + * + *
+	 * 1.如果日期字符串为空,则直接返回空
+	 * 2.使用格式化组进行格式化,如果解析成功,则直接返回
+	 * 4.否则,抛出非法参数异常
+	 * @param source 请求的日期参数
+	 * @return 解析后的日期类型:java.util.Date
+	 * @exception IllegalArgumentException 非法参数异常
+	 * 
+ *
+ */ + public static Date convert(String source) { + if (StringUtils.isBlank(source)){ + return null; + } + source = source.trim(); + + try{ + int timeLength = source.length(); + Long time = Long.parseLong(source); + if (timeLength == 10){ + time = time * 1000; + } + Date date = new Date(time); + return date; + }catch (Exception e){ + + } + + Date date = null; + boolean flag = false; + for (DateFormat dateFormat : dateFormats) { + try { + date = dateFormat.parse(source); + flag = true; + break; + } catch (ParseException e) { + // e.printStackTrace(); + } + } + + if (flag) { + return date; + }else{ + throw new IllegalArgumentException("不能解析日期:" + source); + } + + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/StringToDoubleConverter.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/StringToDoubleConverter.java new file mode 100644 index 0000000..3e8f57d --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/StringToDoubleConverter.java @@ -0,0 +1,34 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config.converter; + +import org.springframework.core.convert.converter.Converter; + +/** + * + * + * + * @author geekidea + * @date 2018-11-08 + */ +public class StringToDoubleConverter implements Converter { + + @Override + public Double convert(String source) { + return StringToDoubleUtil.convert(source); + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/StringToDoubleUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/StringToDoubleUtil.java new file mode 100644 index 0000000..45a64ed --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/StringToDoubleUtil.java @@ -0,0 +1,40 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config.converter; + +import org.apache.commons.lang.StringUtils; + +/** + * + *
+ * 空字符串("")转换成Double的null
+ *
+ * 
+ *
+ * @author geekidea + * @date 2018-11-08 + */ +public class StringToDoubleUtil { + + public static Double convert(String source) { + if (StringUtils.isBlank(source)){ + return null; + } + Double d = Double.parseDouble(source); + return d; + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/StringToIntegerConverter.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/StringToIntegerConverter.java new file mode 100644 index 0000000..eaefb4b --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/StringToIntegerConverter.java @@ -0,0 +1,34 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config.converter; + +import org.springframework.core.convert.converter.Converter; + +/** + * + * + * + * @author geekidea + * @date 2018-11-08 + */ +public class StringToIntegerConverter implements Converter { + + @Override + public Integer convert(String source) { + return StringToIntegerUtil.convert(source); + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/StringToIntegerUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/StringToIntegerUtil.java new file mode 100644 index 0000000..b06f35e --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/converter/StringToIntegerUtil.java @@ -0,0 +1,40 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config.converter; + +import org.apache.commons.lang3.StringUtils; + +/** + * + *
+ * 空字符串("")转换成Integer的null
+ *
+ * 
+ *
+ * @author geekidea + * @date 2018-11-08 + */ +public class StringToIntegerUtil { + + public static Integer convert(String source) { + if (StringUtils.isBlank(source)){ + return null; + } + Integer i = Integer.parseInt(source); + return i; + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/fastjson/FastJsonMvcConfig.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/fastjson/FastJsonMvcConfig.java new file mode 100644 index 0000000..6562772 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/fastjson/FastJsonMvcConfig.java @@ -0,0 +1,81 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config.json.fastjson; + +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.serializer.ToStringSerializer; +import com.alibaba.fastjson.support.config.FastJsonConfig; +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.math.BigInteger; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; + +/** + * @author geekidea + * @date 2018-11-08 + */ +//@Configuration +public class FastJsonMvcConfig implements WebMvcConfigurer { + + private static final String DEFAULT_CHARSET = "UTF-8"; + private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; + + + @Override + public void extendMessageConverters(List> converters) { + FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter(); + + List mediaTypes = new ArrayList<>(); + mediaTypes.add(MediaType.APPLICATION_JSON); + mediaTypes.add(MediaType.APPLICATION_JSON_UTF8); + mediaTypes.add(MediaType.TEXT_HTML); + mediaTypes.add(new MediaType("application", "xml")); + mediaTypes.add(new MediaType("text", "xml")); + mediaTypes.add(new MediaType("application", "*+xml")); + mediaTypes.add(MediaType.ALL); + fastJsonHttpMessageConverter.setSupportedMediaTypes(mediaTypes); + + FastJsonConfig fastJsonConfig = new FastJsonConfig(); + fastJsonConfig.setCharset(Charset.forName(DEFAULT_CHARSET)); + fastJsonConfig.setDateFormat(DEFAULT_DATE_FORMAT); + SerializerFeature[] serializerFeatures = new SerializerFeature[]{ + SerializerFeature.PrettyFormat, // 格式化 + SerializerFeature.WriteMapNullValue, // 输出空值 + SerializerFeature.WriteNullListAsEmpty, // 空集合输出[] + SerializerFeature.WriteDateUseDateFormat // 日期格式化 + }; + fastJsonConfig.setSerializerFeatures(serializerFeatures); + + + SerializeConfig serializeConfig = SerializeConfig.globalInstance; + serializeConfig.put(BigInteger.class, ToStringSerializer.instance); + serializeConfig.put(Long.class, ToStringSerializer.instance); + serializeConfig.put(Long.TYPE, ToStringSerializer.instance); + fastJsonConfig.setSerializeConfig(serializeConfig); + + fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig); + + converters.add(0,fastJsonHttpMessageConverter); + + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/JacksonConfig.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/JacksonConfig.java new file mode 100644 index 0000000..985bda1 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/JacksonConfig.java @@ -0,0 +1,95 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config.json.jackson; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; +import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; +import com.ruoyi.plus.common.constant.DatePattern; +import com.ruoyi.plus.config.json.jackson.deserializer.JacksonDateDeserializer; +import com.ruoyi.plus.config.json.jackson.deserializer.JacksonDoubleDeserializer; +import com.ruoyi.plus.config.json.jackson.serializer.JacksonDateSerializer; +import com.ruoyi.plus.config.json.jackson.serializer.JacksonIntegerDeserializer; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.Date; +import java.util.List; + +/** + * + * @author geekidea + * @author 2018-11-08 + */ +@Configuration +public class JacksonConfig implements WebMvcConfigurer { + + @Override + public void extendMessageConverters(List> converters) { + MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(); + + ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper(); + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE); + + SimpleModule simpleModule = new SimpleModule(); + // Long类型序列化成字符串,避免Long精度丢失 + simpleModule.addSerializer(Long.class, ToStringSerializer.instance); + simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); + + // Date + simpleModule.addSerializer(Date.class,new JacksonDateSerializer()); + simpleModule.addDeserializer(Date.class,new JacksonDateDeserializer()); + + simpleModule.addDeserializer(Integer.class,new JacksonIntegerDeserializer()); + simpleModule.addDeserializer(Double.class,new JacksonDoubleDeserializer()); + + // jdk8日期序列化和反序列化设置 + JavaTimeModule javaTimeModule = new JavaTimeModule(); + javaTimeModule.addSerializer(LocalDateTime.class,new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.yyyy_MM_dd_HH_mm_ss))); + javaTimeModule.addDeserializer(LocalDateTime.class,new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.yyyy_MM_dd_HH_mm_ss))); + + javaTimeModule.addSerializer(LocalDate.class,new LocalDateSerializer(DateTimeFormatter.ofPattern(DatePattern.yyyy_MM_dd))); + javaTimeModule.addDeserializer(LocalDate.class,new LocalDateDeserializer(DateTimeFormatter.ofPattern(DatePattern.yyyy_MM_dd))); + + javaTimeModule.addSerializer(LocalTime.class,new LocalTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.HH_mm_ss))); + javaTimeModule.addDeserializer(LocalTime.class,new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.HH_mm_ss))); + + objectMapper.registerModule(simpleModule).registerModule(javaTimeModule).registerModule(new ParameterNamesModule()); + + jackson2HttpMessageConverter.setObjectMapper(objectMapper); + + //放到第一个 + converters.add(0,jackson2HttpMessageConverter); + } +} \ No newline at end of file diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/deserializer/JacksonDateDeserializer.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/deserializer/JacksonDateDeserializer.java new file mode 100644 index 0000000..11ea601 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/deserializer/JacksonDateDeserializer.java @@ -0,0 +1,42 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config.json.jackson.deserializer; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.ruoyi.plus.config.converter.StringToDateUtil; + +import java.io.IOException; +import java.util.Date; + +/** + *

+ * Jackson Date序列化器 + *

+ * @author geekidea + * @date 2018-11-08 + */ +public class JacksonDateDeserializer extends JsonDeserializer { + @Override + public Date deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + String date = jp.getText(); + return StringToDateUtil.convert(date); + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/deserializer/JacksonDoubleDeserializer.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/deserializer/JacksonDoubleDeserializer.java new file mode 100644 index 0000000..4dcdbd4 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/deserializer/JacksonDoubleDeserializer.java @@ -0,0 +1,38 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config.json.jackson.deserializer; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.ruoyi.plus.config.converter.StringToDoubleUtil; + +import java.io.IOException; + +/** + * @author geekidea + * @date 2018-11-08 + */ +public class JacksonDoubleDeserializer extends JsonDeserializer { + + @Override + public Double deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + String string = jsonParser.getText(); + return StringToDoubleUtil.convert(string); + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/deserializer/JacksonLocalDateTimeDeserializer.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/deserializer/JacksonLocalDateTimeDeserializer.java new file mode 100644 index 0000000..73cda89 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/deserializer/JacksonLocalDateTimeDeserializer.java @@ -0,0 +1,47 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config.json.jackson.deserializer; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.ruoyi.plus.common.constant.DatePattern; +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + *

+ * Jackson LocaDateTime反序列化器 + *

+ * @author geekidea + * @date 2018-11-08 + */ +public class JacksonLocalDateTimeDeserializer extends JsonDeserializer { + + @Override + public LocalDateTime deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + String string = jp.getText(); + if (StringUtils.isBlank(string)){ + return null; + } + return LocalDateTime.parse(string, DateTimeFormatter.ofPattern(DatePattern.yyyy_MM_dd_HH_mm_ss)); + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/serializer/JacksonDateSerializer.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/serializer/JacksonDateSerializer.java new file mode 100644 index 0000000..25830ff --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/serializer/JacksonDateSerializer.java @@ -0,0 +1,43 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config.json.jackson.serializer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.ruoyi.plus.util.DateUtil; + +import java.io.IOException; +import java.util.Date; + +/** + *

+ * Jackson Date反序列化器 + *

+ * @author geekidea + * @date 2018-11-08 + */ +public class JacksonDateSerializer extends JsonSerializer { + @Override + public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { + if (date != null){ + String dateString = DateUtil.getYYYYMMDDHHMMSS(date); + jsonGenerator.writeString(dateString); + } + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/serializer/JacksonIntegerDeserializer.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/serializer/JacksonIntegerDeserializer.java new file mode 100644 index 0000000..f886e50 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/serializer/JacksonIntegerDeserializer.java @@ -0,0 +1,38 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config.json.jackson.serializer; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.ruoyi.plus.config.converter.StringToIntegerUtil; + +import java.io.IOException; + +/** + * @author geekidea + * @date 2018-11-08 + */ +public class JacksonIntegerDeserializer extends JsonDeserializer { + + @Override + public Integer deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + String string = jsonParser.getText(); + return StringToIntegerUtil.convert(string); + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/serializer/JacksonLocalDateTimeSerializer.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/serializer/JacksonLocalDateTimeSerializer.java new file mode 100644 index 0000000..4b1b5df --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/json/jackson/serializer/JacksonLocalDateTimeSerializer.java @@ -0,0 +1,46 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config.json.jackson.serializer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.ruoyi.plus.common.constant.DatePattern; + +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + *

+ * Jackson LocalDateTime 自定义序列化器 + *

+ * @author geekidea + * @date 2018/11/8 + */ +public class JacksonLocalDateTimeSerializer extends JsonSerializer { + + @Override + public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { + if (localDateTime != null){ + String string = localDateTime.format(DateTimeFormatter.ofPattern(DatePattern.yyyy_MM_dd_HH_mm_ss)); + jsonGenerator.writeString(string); + } + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/package-info.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/package-info.java new file mode 100644 index 0000000..a6413c5 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/config/package-info.java @@ -0,0 +1,22 @@ +/** + * 公共配置 + * @author geekidea + * @date 2018-11-08 + */ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.config; \ No newline at end of file diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/core/SpringBootPlusConfig.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/core/SpringBootPlusConfig.java new file mode 100644 index 0000000..bd2e1c4 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/core/SpringBootPlusConfig.java @@ -0,0 +1,113 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.ruoyi.plus.core; + +import com.ruoyi.plus.common.aop.LogAop; +import com.ruoyi.plus.common.web.interceptor.*; +import com.ruoyi.plus.resource.web.interceptor.DownloadInterceptor; +import com.ruoyi.plus.resource.web.interceptor.ResourceInterceptor; +import com.ruoyi.plus.resource.web.interceptor.UploadInterceptor; +import com.ruoyi.plus.security.interceptor.JwtInterceptor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * spring-boot-plus配置 + * @author geekidea + * @date 2019/8/4 + * @since 1.2.0-RELEASE + */ +@Slf4j +@Configuration +@EnableConfigurationProperties({SpringBootPlusProperties.class}) +public class SpringBootPlusConfig { + + /** + * 配置日志AOP + * @param springBootPlusProperties + * @return + */ + @Bean + public LogAop logAop(SpringBootPlusProperties springBootPlusProperties){ + LogAop logAop = new LogAop(); + logAop.setRequestLogFormat(springBootPlusProperties.isRequestLogFormat()); + logAop.setResponseLogFormat(springBootPlusProperties.isResponseLogFormat()); + log.info("init LogAop success"); + return logAop; + } + + /** + * JWT TOKEN验证拦截器 + * @return + */ + @Bean + public JwtInterceptor jwtInterceptor(){ + JwtInterceptor jwtInterceptor = new JwtInterceptor(); + return jwtInterceptor; + } + + /** + * 权限拦截器 + * @return + */ + @Bean + public PermissionInterceptor permissionInterceptor(){ + PermissionInterceptor permissionInterceptor = new PermissionInterceptor(); + return permissionInterceptor; + } + + /** + * TOKEN超时拦截器 + * @return + */ + @Bean + public TokenTimeoutInterceptor tokenTimeoutInterceptor(){ + TokenTimeoutInterceptor tokenTimeoutInterceptor = new TokenTimeoutInterceptor(); + return tokenTimeoutInterceptor; + } + + /** + * 上传拦截器 + * @return + */ + @Bean + public UploadInterceptor uploadInterceptor(){ + UploadInterceptor uploadInterceptor = new UploadInterceptor(); + return uploadInterceptor; + } + + /** + * 资源拦截器 + * @return + */ + @Bean + public ResourceInterceptor resourceInterceptor(){ + ResourceInterceptor resourceInterceptor = new ResourceInterceptor(); + return resourceInterceptor; + } + + /** + * 下载拦截器 + * @return + */ + @Bean + public DownloadInterceptor downloadInterceptor(){ + DownloadInterceptor downloadInterceptor = new DownloadInterceptor(); + return downloadInterceptor; + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/core/SpringBootPlusInterceptorConfig.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/core/SpringBootPlusInterceptorConfig.java new file mode 100644 index 0000000..bdf1479 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/core/SpringBootPlusInterceptorConfig.java @@ -0,0 +1,83 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.core; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + * @author liujixiang + * @date 2019/8/5 + */ +@Data +@Accessors(chain = true) +public class SpringBootPlusInterceptorConfig implements Serializable { + private static final long serialVersionUID = -2738042100246082469L; + + /** + * JWT拦截器排除路径 + */ + private InterceptorConfig jwtConfig; + + /** + * TOKEN超时拦截器排除路径 + */ + private InterceptorConfig tokenTimeoutConfig; + + /** + * 权限拦截器排除路径 + */ + private InterceptorConfig permissionConfig; + + /** + * 资源拦截器 + */ + private InterceptorConfig resourceConfig; + + /** + * 上传拦截器 + */ + private InterceptorConfig uploadConfig; + + /** + * 下载拦截器 + */ + private InterceptorConfig downloadConfig; + + @Data + public static class InterceptorConfig { + + /** + * 是否启用 + */ + private boolean enabled; + + /** + * 排除路径 + */ + private String[] excludePath; + + /** + * 包含的路径 + */ + private String[] includePath; + + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/core/SpringBootPlusProperties.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/core/SpringBootPlusProperties.java new file mode 100644 index 0000000..713e891 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/core/SpringBootPlusProperties.java @@ -0,0 +1,89 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.core; + +import lombok.Data; +import lombok.experimental.Accessors; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; + +import java.util.List; + +/** + * spring-boot-plus属性配置信息 + * @author geekidea + * @date 2019-08-04 + * @since 1.2.0-RELEASE + */ +@Data +@Accessors(chain = true) +@ConfigurationProperties(prefix = "spring-boot-plus") +public class SpringBootPlusProperties { + + /** + * 是否启用ansi控制台输出有颜色的字体,local环境建议开启,服务器环境设置为false + */ + private boolean enableAnsi; + + /** + * 请求日志在控制台是否格式化输出,local环境建议开启,服务器环境设置为false + */ + private boolean requestLogFormat; + + /** + * 响应日志在控制台是否格式化输出,local环境建议开启,服务器环境设置为false + */ + private boolean responseLogFormat; + + /** + * 登录token失效时间,单位分钟,默认60分钟失效 + */ + private Integer tokenValidTime = 60; + + /** + * 拦截器配置 + */ + @NestedConfigurationProperty + private SpringBootPlusInterceptorConfig interceptorConfig; + + /** + * 上传目录 + */ + private String uploadPath; + /** + * 资源访问路径,前端访问 + */ + private String resourceAccessPath; + /** + * 资源访问路径,后段配置,资源映射/拦截器使用 + */ + private String resourceAccessPatterns; + /** + * 资源访问全路径 + */ + private String resourceAccessUrl; + + /** + * 允许上传的文件后缀集合 + */ + private List allowUploadFileExtensions; + /** + * 允许下载的文件后缀集合 + */ + private List allowDownloadFileExtensions; + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/core/SpringBootPlusWebMvcConfig.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/core/SpringBootPlusWebMvcConfig.java new file mode 100644 index 0000000..8de2dce --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/core/SpringBootPlusWebMvcConfig.java @@ -0,0 +1,126 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.core; + +import com.alibaba.fastjson.JSON; +import com.ruoyi.plus.common.web.interceptor.PermissionInterceptor; +import com.ruoyi.plus.common.web.interceptor.TokenTimeoutInterceptor; +import com.ruoyi.plus.resource.web.interceptor.DownloadInterceptor; +import com.ruoyi.plus.resource.web.interceptor.ResourceInterceptor; +import com.ruoyi.plus.resource.web.interceptor.UploadInterceptor; +import com.ruoyi.plus.security.interceptor.JwtInterceptor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import javax.annotation.PostConstruct; + +/** + * WebMvc配置 + * @author geekidea + * @date 2018-11-08 + */ +@Configuration +@Slf4j +public class SpringBootPlusWebMvcConfig implements WebMvcConfigurer { + + @Autowired + private SpringBootPlusProperties springBootPlusProperties; + + @Autowired + private JwtInterceptor jwtInterceptor; + + @Autowired + private PermissionInterceptor permissionInterceptor; + + @Autowired + private TokenTimeoutInterceptor tokenTimeoutInterceptor; + + @Autowired + private ResourceInterceptor resourceInterceptor; + + @Autowired + private UploadInterceptor uploadInterceptor; + + @Autowired + private DownloadInterceptor downloadInterceptor; + + @PostConstruct + public void init(){ + // 打印SpringBootPlusProperties配置信息 + log.info("SpringBootPlusProperties:{}", JSON.toJSONString(springBootPlusProperties)); + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + SpringBootPlusInterceptorConfig interceptorConfig = springBootPlusProperties.getInterceptorConfig(); + + // 上传拦截器 + registry.addInterceptor(uploadInterceptor) + .addPathPatterns(interceptorConfig.getUploadConfig().getIncludePath()); + + // 资源拦截器注册 + registry.addInterceptor(resourceInterceptor) + .addPathPatterns(interceptorConfig.getResourceConfig().getIncludePath()); + + // 下载拦截器注册 + registry.addInterceptor(downloadInterceptor) + .addPathPatterns(interceptorConfig.getDownloadConfig().getIncludePath()); + + if (interceptorConfig.getJwtConfig().isEnabled()){ + // JWT拦截器注册 + registry.addInterceptor(jwtInterceptor) + .addPathPatterns(interceptorConfig.getJwtConfig().getIncludePath()) + .excludePathPatterns(interceptorConfig.getJwtConfig().getExcludePath()); + } + + if (interceptorConfig.getTokenTimeoutConfig().isEnabled()){ + // TOKEN超时拦截器注册 + registry.addInterceptor(tokenTimeoutInterceptor) + .addPathPatterns(interceptorConfig.getTokenTimeoutConfig().getIncludePath()) + .excludePathPatterns(interceptorConfig.getTokenTimeoutConfig().getExcludePath()); + } + + if (interceptorConfig.getPermissionConfig().isEnabled()){ + // 权限拦截器注册 + registry.addInterceptor(permissionInterceptor) + .addPathPatterns(interceptorConfig.getPermissionConfig().getIncludePath()) + .excludePathPatterns(interceptorConfig.getPermissionConfig().getExcludePath()); + } + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + // 设置项目静态资源访问 + registry.addResourceHandler("/static/**") + .addResourceLocations("classpath:/static/"); + registry.addResourceHandler("/templates/**") + .addResourceLocations("classpath:/templates/"); + // 设置swagger静态资源访问 + registry.addResourceHandler("swagger-ui.html") + .addResourceLocations("classpath:/META-INF/resources/"); + registry.addResourceHandler("/webjars/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/"); + // 设置上传文件访问路径 + registry.addResourceHandler(springBootPlusProperties.getResourceAccessPatterns()) + .addResourceLocations("file:" + springBootPlusProperties.getUploadPath()); + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/package-info.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/package-info.java new file mode 100644 index 0000000..3f13341 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/package-info.java @@ -0,0 +1 @@ +package com.ruoyi.plus.resource; \ No newline at end of file diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/web/controller/DownloadController.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/web/controller/DownloadController.java new file mode 100644 index 0000000..20c9c4f --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/web/controller/DownloadController.java @@ -0,0 +1,71 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.resource.web.controller; + +import com.ruoyi.plus.common.api.ApiResult; +import com.ruoyi.plus.core.SpringBootPlusProperties; +import com.ruoyi.plus.util.DownloadUtil; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 下载控制器 + * @author geekidea + * @date 2019/8/20 + * @since 1.2.1-RELEASE + */ +@Slf4j +@Controller +@RequestMapping("/download") +public class DownloadController { + + @Autowired + private SpringBootPlusProperties springBootPlusProperties; + + /** + * 下载文件 + */ + @RequestMapping("/{downloadFileName}") + @ApiOperation(value = "下载文件",notes = "下载文件",response = ApiResult.class) + public void download(@PathVariable(required = true) String downloadFileName, HttpServletResponse response) throws Exception{ + // 下载目录,既是上传目录 + String downloadDir = springBootPlusProperties.getUploadPath(); + // 允许下载的文件后缀 + List allowFileExtensions = springBootPlusProperties.getAllowDownloadFileExtensions(); + // 文件下载,使用默认下载处理器 +// DownloadUtil.download(downloadDir,downloadFileName,allowFileExtensions,response); + // 文件下载,使用自定义下载处理器 + DownloadUtil.download(downloadDir,downloadFileName,allowFileExtensions,response, (dir, fileName, file, fileExtension, contentType, length) -> { + // 下载自定义处理,返回true:执行下载,false:取消下载 + log.info("dir = " + dir); + log.info("fileName = " + fileName); + log.info("file = " + file); + log.info("fileExtension = " + fileExtension); + log.info("contentType = " + contentType); + log.info("length = " + length); + return true; + }); + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/web/controller/ResourceController.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/web/controller/ResourceController.java new file mode 100644 index 0000000..252cc6d --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/web/controller/ResourceController.java @@ -0,0 +1,55 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.resource.web.controller; + +import com.ruoyi.plus.common.api.ApiResult; +import com.ruoyi.plus.core.SpringBootPlusProperties; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; + +/** + * 图片等文件资源访问控制器 + * /api/resource 访问路径 用于区分 文件访问虚拟目录映射 /resource + * @author geekidea + * @date 2019/8/20 + * @since 1.2.1-RELEASE + */ +@Slf4j +@Controller +@RequestMapping("/api/resource") +public class ResourceController { + + @Autowired + private SpringBootPlusProperties springBootPlusProperties; + + /** + * 访问图片 + */ + @GetMapping("/image/{imageFileName}") + @ApiOperation(value = "访问图片",notes = "访问图片",response = ApiResult.class) + public void getImage(@PathVariable(required = true) String imageFileName, HttpServletResponse response) throws Exception{ + log.info("imageFileName:{}",imageFileName); + // 重定向到图片访问路径 + response.sendRedirect(springBootPlusProperties.getResourceAccessPath() + imageFileName); + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/web/controller/UploadController.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/web/controller/UploadController.java new file mode 100644 index 0000000..ebdbafc --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/web/controller/UploadController.java @@ -0,0 +1,81 @@ + + +package com.ruoyi.plus.resource.web.controller; + +import com.ruoyi.plus.common.api.ApiResult; +import com.ruoyi.plus.common.web.param.IdParam; +import com.ruoyi.plus.core.SpringBootPlusProperties; +import com.ruoyi.plus.system.web.vo.SysLogQueryVo; +import com.ruoyi.plus.util.UploadUtil; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FilenameUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.validation.Valid; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * 上传控制器 + * @author geekidea + * @date 2019/8/20 + * @since 1.2.1-RELEASE + */ +@Slf4j +@RestController +@RequestMapping("/upload") +public class UploadController { + + @Autowired + private SpringBootPlusProperties springBootPlusProperties; + + @GetMapping("/hello") + public ApiResult hello(){ + log.info("hello..."); + return ApiResult.ok(); + } + + /** + * 获取系统日志 + */ + @PostMapping("/info") + @ApiOperation(value = "获取SysLog对象详情",notes = "查看系统日志",response = SysLogQueryVo.class) + public ApiResult getSysUser(@Valid @RequestBody IdParam idParam) throws Exception{ + log.info("idParam = " + idParam); + return ApiResult.ok(); + } + + /** + * 上传单个文件 + */ + @PostMapping("/") + @ApiOperation(value = "上传单个文件",notes = "上传单个文件",response = ApiResult.class) + public ApiResult upload(@RequestParam("img") MultipartFile multipartFile) throws Exception{ + log.info("multipartFile = " + multipartFile); + log.info("ContentType = " + multipartFile.getContentType()); + log.info("OriginalFilename = " + multipartFile.getOriginalFilename()); + log.info("Name = " + multipartFile.getName()); + log.info("Size = " + multipartFile.getSize()); + + // 上传文件,返回保存的文件名称 + String saveFileName = UploadUtil.upload(springBootPlusProperties.getUploadPath(), multipartFile, originalFilename -> { + // 文件后缀 + String fileExtension= FilenameUtils.getExtension(originalFilename); + // 这里可自定义文件名称,比如按照业务类型/文件格式/日期 + String dateString = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssS")); + String fileName = dateString + "." +fileExtension; + return fileName; + }); + + // 上传成功之后,返回访问路径,请根据实际情况设置 + + String fileAccessPath = springBootPlusProperties.getResourceAccessUrl() + saveFileName; + log.info("fileAccessPath:{}",fileAccessPath); + + return ApiResult.ok(fileAccessPath); + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/web/interceptor/DownloadInterceptor.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/web/interceptor/DownloadInterceptor.java new file mode 100644 index 0000000..1cc52f1 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/web/interceptor/DownloadInterceptor.java @@ -0,0 +1,78 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.resource.web.interceptor; + +import com.ruoyi.plus.common.api.ApiResult; +import com.ruoyi.plus.core.SpringBootPlusProperties; +import com.ruoyi.plus.util.HttpServletResponseUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 下载拦截器 + * @author geekidea + * @date 2019/8/21 + * @since 1.2.2-RELEASE + */ +@Slf4j +public class DownloadInterceptor extends HandlerInterceptorAdapter { + + @Autowired + private SpringBootPlusProperties springBootPlusProperties; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + // 如果访问的不是控制器,则跳出,继续执行下一个拦截器 + if (!(handler instanceof HandlerMethod)) { + return true; + } + // 访问路径 + String url = request.getRequestURI(); + // 访问全路径 + String fullUrl = request.getRequestURL().toString(); + + // 未启用资源访问时,返回错误消息 + if (!springBootPlusProperties.getInterceptorConfig().getDownloadConfig().isEnabled()){ + log.error("下载已关闭,非法下载:{}",fullUrl); + HttpServletResponseUtil.printJSON(response, ApiResult.fail("非法下载")); + return false; + } + + // 下载拦截器,业务处理代码 + log.info("DownloadInterceptor..."); + + // 访问token,如果需要,可以设置参数,进行鉴权 + String token = request.getParameter("token"); + + log.info("url:{}",url); + log.info("fullUrl:{}",fullUrl); + log.info("token:{}",token); + + return true; + } + + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { + // 记录实际下载日志... + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/web/interceptor/ResourceInterceptor.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/web/interceptor/ResourceInterceptor.java new file mode 100644 index 0000000..7e67a99 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/web/interceptor/ResourceInterceptor.java @@ -0,0 +1,78 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.resource.web.interceptor; + +import com.ruoyi.plus.common.api.ApiResult; +import com.ruoyi.plus.core.SpringBootPlusProperties; +import com.ruoyi.plus.util.HttpServletResponseUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 资源拦截器 + * @author geekidea + * @date 2019/8/20 + * @since 1.2.1-RELEASE + */ +@Slf4j +public class ResourceInterceptor extends HandlerInterceptorAdapter { + + @Autowired + private SpringBootPlusProperties springBootPlusProperties; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + // 如果访问的控制器,则跳出,继续执行下一个拦截器 + if (handler instanceof HandlerMethod) { + return true; + } + // 访问路径 + String url = request.getRequestURI(); + // 访问全路径 + String fullUrl = request.getRequestURL().toString(); + + // 未启用资源访问时,返回错误消息 + if (!springBootPlusProperties.getInterceptorConfig().getResourceConfig().isEnabled()){ + log.error("资源访问已关闭,非法访问:{}",fullUrl); + HttpServletResponseUtil.printJSON(response,ApiResult.fail("非法访问")); + return false; + } + + // 资源拦截器,业务处理代码 + log.info("ResourceInterceptor..."); + + // 访问token,如果需要,可以设置参数,进行鉴权 + String token = request.getParameter("token"); + + log.info("url:{}",url); + log.info("fullUrl:{}",fullUrl); + log.info("token:{}",token); + + return true; + } + + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { + // 记录实际访问图片日志... + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/web/interceptor/UploadInterceptor.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/web/interceptor/UploadInterceptor.java new file mode 100644 index 0000000..433f07b --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/resource/web/interceptor/UploadInterceptor.java @@ -0,0 +1,76 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.resource.web.interceptor; + +import com.ruoyi.plus.common.api.ApiResult; +import com.ruoyi.plus.core.SpringBootPlusProperties; +import com.ruoyi.plus.util.HttpServletResponseUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 上传拦截器 + * @author geekidea + * @date 2019/8/22 + * @since 1.2.2-RELEASE + */ +@Slf4j +public class UploadInterceptor extends HandlerInterceptorAdapter { + + @Autowired + private SpringBootPlusProperties springBootPlusProperties; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + // 如果访问的不是控制器,则跳出,继续执行下一个拦截器 + if (!(handler instanceof HandlerMethod)) { + return true; + } + + // 访问路径 + String url = request.getRequestURI(); + // 访问全路径 + String fullUrl = request.getRequestURL().toString(); + if (!springBootPlusProperties.getInterceptorConfig().getUploadConfig().isEnabled()){ + log.error("上传功能已关闭,非法上传:{}",fullUrl); + HttpServletResponseUtil.printJSON(response, ApiResult.fail("非法上传")); + return false; + } + + // 上传拦截器,业务处理代码 + log.info("UploadInterceptor..."); + // 访问token,如果需要,可以设置参数,进行鉴权 + String token = request.getParameter("token"); + + log.info("url:{}",url); + log.info("fullUrl:{}",fullUrl); + log.info("token:{}",token); + + return true; + } + + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { + // 记录实际上传日志... + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/config/JwtProperties.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/config/JwtProperties.java new file mode 100644 index 0000000..50e29dd --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/config/JwtProperties.java @@ -0,0 +1,65 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.security.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + *

+ * Jwt配置属性 + *

+ * @author geekidea + * @date 2019-05-22 + **/ +@Data +@Component +@ConfigurationProperties(prefix = "spring-boot-plus.jwt") +public class JwtProperties { + + /** + * 密码 + */ +// @Value("spring-boot-plus.jwt.secret:spring-boot-plus") + private String secret; + + /** + * 签发人 + */ +// @Value("spring-boot-plus.jwt.issuer:spring-boot-plus") + private String issuer; + + /** + * 主题 + */ +// @Value("spring-boot-plus.jwt.subject:spring-boot-plus-jwt") + private String subject; + + /** + * 签发的目标 + */ +// @Value("spring-boot-plus.jwt.audience:web") + private String audience; + + /** + * token失效时间,默认30分钟 + */ +// @Value("spring-boot-plus.jwt.default.expire.minutes:30") + private Integer expireMinutes; + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/controller/LoginController.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/controller/LoginController.java new file mode 100644 index 0000000..50bd4cc --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/controller/LoginController.java @@ -0,0 +1,54 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.security.controller; + +import com.ruoyi.plus.common.api.ApiCode; +import com.ruoyi.plus.common.api.ApiResult; +import com.ruoyi.plus.common.web.controller.BaseController; +import com.ruoyi.plus.security.param.LoginParam; +import com.ruoyi.plus.security.service.LoginService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +/** + *

+ * + *

+ * @author geekidea + * @date 2019-05-15 + **/ +@Slf4j +@RestController +@RequestMapping("/login") +public class LoginController extends BaseController { + + @Autowired + private LoginService loginService; + + @PostMapping("") + public ApiResult login(@Validated @RequestBody LoginParam loginParam) throws Exception{ + return loginService.login(loginParam); + } + + @GetMapping("/non") + public ApiResult nonLogin() throws Exception{ + log.info("nonLogin...."); + return ApiResult.fail(ApiCode.UNAUTHORIZED); + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/interceptor/JwtInterceptor.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/interceptor/JwtInterceptor.java new file mode 100644 index 0000000..334d217 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/interceptor/JwtInterceptor.java @@ -0,0 +1,89 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.security.interceptor; + +import com.ruoyi.plus.common.api.ApiCode; +import com.ruoyi.plus.common.api.ApiResult; +import com.ruoyi.plus.security.service.LoginService; +import com.ruoyi.plus.security.util.JwtUtil; +import com.ruoyi.plus.util.HttpServletResponseUtil; +import com.ruoyi.plus.util.LoginUtil; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jws; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + *

+ * 判断jwt token是否有效 + *

+ * @author geekidea + * @date 2019-05-22 + **/ +@Slf4j +public class JwtInterceptor extends HandlerInterceptorAdapter { + + @Autowired + private LoginService loginService; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + // 如果访问的不是控制器,则跳出,继续执行下一个拦截器 + if (!(handler instanceof HandlerMethod)) { + return true; + } + + // 获取token + String token = LoginUtil.getToken(request); + + // 如果token为空,则s输出提示并返回 + if (StringUtils.isBlank(token)){ + ApiResult apiResult = ApiResult.result(ApiCode.UNAUTHORIZED); + log.error("token is empty"); + HttpServletResponseUtil.printJSON(response,apiResult); + return false; + } + + log.debug("token:{}",token); + + // 验证token是否有效 + Jws jws = JwtUtil.verify(token); + log.debug("token verify:{}",jws); + if (jws == null){ + ApiResult apiResult = ApiResult.result(ApiCode.UNAUTHORIZED); + log.error("token verify failed"); + HttpServletResponseUtil.printJSON(response,apiResult); + return false; + } + + // 刷新token + loginService.refreshToken(response, jws); + + // 存储jws对象到request对象中 + request.setAttribute("jws",jws); + + log.debug("token verify success"); + return true; + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/param/LoginParam.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/param/LoginParam.java new file mode 100644 index 0000000..9cd769f --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/param/LoginParam.java @@ -0,0 +1,47 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.security.param; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + *

+ * 登录参数 + *

+ * @author geekidea + * @date 2019-05-15 + **/ +@Data +@ApiModel("登录参数") +public class LoginParam { + + @NotBlank(message = "请输入账号") + @ApiModelProperty("账号") + private String userName; + + @NotBlank(message = "请输入密码") + @ApiModelProperty("密码") + private String pwd; + + @ApiModelProperty("验证码") + private String code; + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/service/LoginService.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/service/LoginService.java new file mode 100644 index 0000000..c9e1982 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/service/LoginService.java @@ -0,0 +1,39 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.security.service; + +import com.ruoyi.plus.common.api.ApiResult; +import com.ruoyi.plus.security.param.LoginParam; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jws; + +import javax.servlet.http.HttpServletResponse; + +/** + *

+ * 登录服务接口 + *

+ * @author geekidea + * @date 2019-05-23 + **/ +public interface LoginService { + + ApiResult login(LoginParam loginParam); + + void refreshToken(HttpServletResponse response, Jws jws); + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/service/impl/LoginServiceImpl.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/service/impl/LoginServiceImpl.java new file mode 100644 index 0000000..60332b6 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/service/impl/LoginServiceImpl.java @@ -0,0 +1,186 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.security.service.impl; + +import com.alibaba.fastjson.JSON; +import com.ruoyi.plus.common.api.ApiResult; +import com.ruoyi.plus.common.constant.CommonConstant; +import com.ruoyi.plus.common.constant.CommonRedisKey; +import com.ruoyi.plus.security.param.LoginParam; +import com.ruoyi.plus.security.service.LoginService; +import com.ruoyi.plus.security.util.JwtUtil; +import com.ruoyi.plus.security.vo.ClientInfo; +import com.ruoyi.plus.security.vo.JwtTokenRedisVo; +import com.ruoyi.plus.security.vo.LoginSysUserRedisVo; +import com.ruoyi.plus.security.vo.LoginSysUserVo; +import com.ruoyi.plus.util.ClientInfoUtil; +import com.ruoyi.plus.util.HttpServletRequestUtil; +import com.ruoyi.plus.util.MapUtil; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jws; +import io.swagger.annotations.Api; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang3.time.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + +/** + *

+ * 登录服务实现类 + *

+ * @author geekidea + * @date 2019-05-23 + **/ +@Api +@Slf4j +@Service +public class LoginServiceImpl implements LoginService { + + @Autowired + private RedisTemplate redisTemplate; + + + @Override + public ApiResult login(LoginParam loginParam) { + log.info("loginParam = " + loginParam); + + // 数据库校验账号密码 + + Long userId = 1L; + String userName = "admin"; + + LoginSysUserVo loginSysUserVo = new LoginSysUserVo(); + loginSysUserVo.setId(userId); + loginSysUserVo.setUserName(userName); + + // token过期时间 + Date expireDate = DateUtils.addMinutes(new Date(), 30); + // 创建token + String token = JwtUtil.create(expireDate,null,null); + // token md5,方便使用 + String tokenMd5 = DigestUtils.md5Hex(token); + // login redis处理 + loginRedis(userId, loginSysUserVo, expireDate, token, tokenMd5); + // 响应数据 + Map map = MapUtil.builder() + .put("token",token) + .put("loginSysUser",loginSysUserVo) + .build(); + + return ApiResult.ok(map); + } + + /** + * jwt生成的token携带用户id和账号,uuid唯一标识,返回token + * redis存储当前登录对象的详细信息 hash + * key: login.sys.user.token的md5值 + * value : LoginSysUserRedisVo + * redis hash + * key: login.sys.user.用户ID + * value: token md5值 + * @param userId + * @param loginSysUserVo + * @param expireDate + * @param token + * @param tokenMd5 + */ + private void loginRedis(Long userId, LoginSysUserVo loginSysUserVo, Date expireDate, String token, String tokenMd5) { + String loginTokenRedisKey = CommonRedisKey.LOGIN_TOKEN; + + // 获取用户客户端信息 + HttpServletRequest request = HttpServletRequestUtil.getRequest(); + String userAgent = request.getHeader("User-Agent"); + ClientInfo clientInfo = ClientInfoUtil.get(userAgent); + log.info("clientInfo = " + JSON.toJSONString(clientInfo,true)); + + // jwt token对象 + JwtTokenRedisVo jwtTokenRedisVo = new JwtTokenRedisVo(); + jwtTokenRedisVo.setToken(token); + jwtTokenRedisVo.setTokenMd5(tokenMd5); + jwtTokenRedisVo.setCreateDate(new Date()); + jwtTokenRedisVo.setExpiredDate(expireDate); + + // loginUser redis缓存信息 + LoginSysUserRedisVo loginSysUserRedisVo = new LoginSysUserRedisVo(); + loginSysUserRedisVo.setClientInfo(clientInfo); // 设置用户客户端信息 + loginSysUserRedisVo.setLoginSysUserVo(loginSysUserVo); // 设置系统登录用户对象 + loginSysUserRedisVo.setJwtTokenRedisVo(jwtTokenRedisVo); // 设置系统登录用户token对象 + + // token hash cache + redisTemplate.opsForHash().put(loginTokenRedisKey,tokenMd5,loginSysUserRedisVo); + + // user hash cache + String loginUserRedisKey = String.format(CommonRedisKey.LOGIN_SYS_USER,userId); + + // 支持一个账号多次登录 + redisTemplate.opsForHash().put(loginUserRedisKey,tokenMd5,jwtTokenRedisVo); + + // 单个登录,始终以最后一个有效 +// String oneLoginUserRedisKey = "login:sys:user"; +// redisTemplate.opsForHash().put(oneLoginUserRedisKey,String.valueOf(userId),jwtTokenRedisVo); + + + } + + + /** + * 刷新token + * @param response + * @param jws + */ + @Override + public void refreshToken(HttpServletResponse response, Jws jws) { + Date expiredDate = jws.getBody().getExpiration(); + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String string = dateFormat.format(expiredDate); + log.info("expiredDate = " + string); + + // 如果token还有1分钟要过期,则重新生成token,并响应到response头中 + Date beforeExpiredDate = DateUtils.addMinutes(expiredDate,-1); + long beforeExpiredTime = beforeExpiredDate.getTime(); + + Date currentDate = new Date(System.currentTimeMillis()); + long currentTime = currentDate.getTime(); + + log.info("beforeExpiredTime = " + beforeExpiredTime); + log.info("currentTime = " + currentTime); + + log.info("beforeExpiredDate = " + dateFormat.format(beforeExpiredDate)); + log.info("currentDate = " + dateFormat.format(currentDate)); + + log.info((beforeExpiredTime <= currentTime)+""); + log.info((beforeExpiredTime - currentTime)+""); + + + if (beforeExpiredTime <= currentTime){ + log.info("====>>>>>"); + response.setHeader(CommonConstant.REFRESH_TOKEN,"123456"); + } + + } + + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/util/JwtUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/util/JwtUtil.java new file mode 100644 index 0000000..aaaab2f --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/util/JwtUtil.java @@ -0,0 +1,124 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.security.util; + +import com.alibaba.fastjson.JSON; +import com.ruoyi.plus.security.config.JwtProperties; +import com.ruoyi.plus.util.UUIDUtil; +import io.jsonwebtoken.*; +import io.jsonwebtoken.impl.DefaultJwsHeader; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.time.DateUtils; +import org.springframework.stereotype.Component; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + *

+ * jwt工具类 + *

+ * @author geekidea + * @date 2019-05-15 + **/ +@Slf4j +@Component +public class JwtUtil { + + private static final String UTF8 = "UTF-8"; + + private static JwtProperties jwtProperties; + + public JwtUtil(JwtProperties jwtProperties){ + JwtUtil.jwtProperties = jwtProperties; + log.info(JSON.toJSONString(JwtUtil.jwtProperties)); + } + + public static String create() { + return create(null,null,null); + } + + /** + * 生成jwt token + * @param expireDate token过期时间 + * @param headerClaims header数据 + * @param payloadClaims body数据 + * @return jwt token + */ + public static String create(Date expireDate,Map headerClaims, Map payloadClaims) { + try { + // 默认过期时间为1小时 + if (expireDate == null) { + expireDate = DateUtils.addMinutes(new Date(), jwtProperties.getExpireMinutes()); + } + log.debug("expireDate:{}", expireDate); + + if (MapUtils.isEmpty(headerClaims)) { + headerClaims = new HashMap<>(); + } + log.debug("headerClaims:{}", headerClaims); + + if (MapUtils.isEmpty(payloadClaims)) { + payloadClaims = new HashMap<>(); + } + log.debug("payloadClaims:{}", payloadClaims); + + Header header = new DefaultJwsHeader(); + header.setContentType(Header.CONTENT_TYPE); + header.setType(Header.JWT_TYPE); + headerClaims.putAll(header); + + // 构建token + String token = Jwts.builder() + .setHeader(headerClaims) + .setClaims(payloadClaims) + .setId(UUIDUtil.getUUID()) // jwt唯一id + .setIssuer(jwtProperties.getIssuer()) // 签发人 + .setSubject(jwtProperties.getSubject()) // 主题 + .setAudience(jwtProperties.getAudience()) // 签发的目标 + .setIssuedAt(new Date()) // 签名时间 + .setExpiration(expireDate) // token过期时间 + // 签名 + .signWith(SignatureAlgorithm.HS256, jwtProperties.getSecret().getBytes(UTF8)) + .compact(); + return token; + } catch (Exception e) { + log.error("create token exception",e); + } + return null; + } + + /** + * 验证jwt token + * @param token jwt token + * @return Jws对象 + */ + public static Jws verify(String token) { + try { + Jws jws = Jwts.parser() + .setSigningKey(jwtProperties.getSecret().getBytes(UTF8)) + .parseClaimsJws(token); + return jws; + } catch (Exception e) { + log.error("verify token exception",e); + } + return null; + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/vo/ClientInfo.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/vo/ClientInfo.java new file mode 100644 index 0000000..100f53d --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/vo/ClientInfo.java @@ -0,0 +1,90 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.security.vo; + +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 用户客户端信息对象 + *

+ * @author geekidea + * @date 2019-05-23 + **/ +@Data +public class ClientInfo implements Serializable { + + private static final long serialVersionUID = -5549531244606897514L; + + /** + * ip + */ + private String ip; + + /** + * ip对应的地址 + */ + private String addree; + + /** + * 浏览器名称 + */ + private String browserName; + + /** + * 浏览器版本 + */ + private String browserversion; + + /** + * 浏览器引擎名称 + */ + private String engineName; + + /** + * 浏览器引擎版本 + */ + private String engineVersion; + + /** + * 系统名称 + */ + private String osName; + + /** + * 平台名称 + */ + private String platformName; + + /** + * 是否是手机 + */ + private boolean mobile; + + /** + * 移动端设备型号 + */ + private String deviceName; + + /** + * 移动端设备型号 + */ + private String deviceModel; + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/vo/DeviceInfo.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/vo/DeviceInfo.java new file mode 100644 index 0000000..8cba35c --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/vo/DeviceInfo.java @@ -0,0 +1,43 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.security.vo; + +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备信息 + *

+ * @author geekidea + * @date 2019-05-24 + **/ +@Data +public class DeviceInfo implements Serializable { + private static final long serialVersionUID = -5912785220335057555L; + + /** + * 设备名称 + */ + private String name; + + /** + * 设备型号 + */ + private String model; +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/vo/JwtTokenRedisVo.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/vo/JwtTokenRedisVo.java new file mode 100644 index 0000000..96adbf6 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/vo/JwtTokenRedisVo.java @@ -0,0 +1,54 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.security.vo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * + *

+ * @author geekidea + * @date 2019-05-23 + **/ +@Data +public class JwtTokenRedisVo implements Serializable { + private static final long serialVersionUID = 5631646796482815114L; + + /** + * 登录token + */ + private String token; + + /** + * 登录token md5 + */ + private String tokenMd5; + + /** + * 创建时间 + */ + private Date createDate; + + /** + * 过期时间 + */ + private Date expiredDate; +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/vo/LoginSysUserRedisVo.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/vo/LoginSysUserRedisVo.java new file mode 100644 index 0000000..b94dc2c --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/vo/LoginSysUserRedisVo.java @@ -0,0 +1,57 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.security.vo; + +import io.swagger.annotations.ApiModel; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 登录用户redis对象,后台使用 + *

+ * @author geekidea + * @date 2019-05-15 + **/ +@Data +@ApiModel("系统用户登录值对象") +public class LoginSysUserRedisVo implements Serializable { + + private static final long serialVersionUID = -4497185071769175695L; + + /** + * 登录对象vo + */ + private LoginSysUserVo loginSysUserVo; + + /** + * jwt token对象 + */ + private JwtTokenRedisVo jwtTokenRedisVo; + + /** + * 唯一标识 + */ + private String uuid; + + /** + * 登录ip + */ + private ClientInfo clientInfo; + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/vo/LoginSysUserVo.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/vo/LoginSysUserVo.java new file mode 100644 index 0000000..5a53e3a --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/security/vo/LoginSysUserVo.java @@ -0,0 +1,39 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.security.vo; + +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 登录用户对象,响应给前端 + *

+ * @author geekidea + * @date 2019-05-15 + **/ +@Data +public class LoginSysUserVo implements Serializable { + + private static final long serialVersionUID = -1758338570596088158L; + + private Long id; + + private String userName; + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/entity/Ip.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/entity/Ip.java new file mode 100644 index 0000000..993ec5f --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/entity/Ip.java @@ -0,0 +1,48 @@ +package com.ruoyi.plus.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.ruoyi.plus.common.entity.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * IP地址 + *

+ * + * @author geekidea + * @since 2019-08-04 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ApiModel(value="Ip对象", description="IP地址") +public class Ip extends BaseEntity { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "ip开始地址") + private String ipStart; + + @ApiModelProperty(value = "ip结束地址") + private String ipEnd; + + @ApiModelProperty(value = "区域") + private String area; + + @ApiModelProperty(value = "运营商") + private String operator; + + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.ID_WORKER) + private Long id; + + @ApiModelProperty(value = "ip开始地址数字") + private Long ipStartNum; + + @ApiModelProperty(value = "ip结束地址数字") + private Long ipEndNum; + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/entity/SysLog.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/entity/SysLog.java new file mode 100644 index 0000000..a057a6b --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/entity/SysLog.java @@ -0,0 +1,44 @@ +package com.ruoyi.plus.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.ruoyi.plus.common.entity.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + *

+ * 系统日志 + *

+ * + * @author geekidea + * @since 2019-08-04 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ApiModel(value="SysLog对象", description="系统日志") +public class SysLog extends BaseEntity { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + @TableId(value = "log_id", type = IdType.ID_WORKER) + private Long logId; + + @ApiModelProperty(value = "类型") + private Boolean type; + + @ApiModelProperty(value = "内容") + private String content; + + @ApiModelProperty(value = "创建人ID") + private Long createId; + + @ApiModelProperty(value = "创建时间") + private Date createTime; + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/entity/SysUser.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/entity/SysUser.java new file mode 100644 index 0000000..04c826d --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/entity/SysUser.java @@ -0,0 +1,51 @@ +package com.ruoyi.plus.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import java.util.Date; +import com.baomidou.mybatisplus.annotation.TableId; +import com.ruoyi.plus.common.entity.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + *

+ * SystemUser + *

+ * + * @author geekidea + * @since 2019-08-26 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ApiModel(value="SysUser对象", description="SystemUser") +public class SysUser extends BaseEntity { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @TableId(value = "id", type = IdType.ID_WORKER) + private Long id; + + @ApiModelProperty(value = "name") + private String name; + + @ApiModelProperty(value = "account") + private String account; + + @ApiModelProperty(value = "password") + private String pwd; + + @ApiModelProperty(value = "remark") + private String remark; + + @ApiModelProperty(value = "create time") + private Date createTime; + + @ApiModelProperty(value = "update time") + private Date updateTime; + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/mapper/IpMapper.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/mapper/IpMapper.java new file mode 100644 index 0000000..0432691 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/mapper/IpMapper.java @@ -0,0 +1,18 @@ +package com.ruoyi.plus.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.plus.system.entity.Ip; +import org.springframework.stereotype.Repository; + +/** + *

+ * IP地址 Mapper 接口 + *

+ * + * @author geekidea + * @since 2019-08-04 + */ +@Repository +public interface IpMapper extends BaseMapper { + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/mapper/SysLogMapper.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/mapper/SysLogMapper.java new file mode 100644 index 0000000..e7875eb --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/mapper/SysLogMapper.java @@ -0,0 +1,40 @@ +package com.ruoyi.plus.system.mapper; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.plus.system.entity.SysLog; +import com.ruoyi.plus.system.web.param.SysLogQueryParam; +import com.ruoyi.plus.system.web.vo.SysLogQueryVo; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.io.Serializable; + +/** + *

+ * 系统日志 Mapper 接口 + *

+ * + * @author geekidea + * @since 2019-08-04 + */ +@Repository +public interface SysLogMapper extends BaseMapper { + + /** + * 根据ID获取查询对象 + * @param id + * @return + */ + SysLogQueryVo getSysLogById(Serializable id); + + /** + * 获取分页对象 + * @param page + * @param sysLogQueryParam + * @return + */ + IPage getSysLogPageList(@Param("page") Page page, @Param("param") SysLogQueryParam sysLogQueryParam); + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/mapper/SysUserMapper.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/mapper/SysUserMapper.java new file mode 100644 index 0000000..976d79f --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/mapper/SysUserMapper.java @@ -0,0 +1,40 @@ +package com.ruoyi.plus.system.mapper; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.plus.system.entity.SysUser; +import com.ruoyi.plus.system.web.param.SysUserQueryParam; +import com.ruoyi.plus.system.web.vo.SysUserQueryVo; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.io.Serializable; + +/** + *

+ * SystemUser Mapper 接口 + *

+ * + * @author geekidea + * @since 2019-08-26 + */ +@Repository +public interface SysUserMapper extends BaseMapper { + + /** + * 根据ID获取查询对象 + * @param id + * @return + */ + SysUserQueryVo getSysUserById(Serializable id); + + /** + * 获取分页对象 + * @param page + * @param sysUserQueryParam + * @return + */ + IPage getSysUserPageList(@Param("page") Page page, @Param("param") SysUserQueryParam sysUserQueryParam); + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/service/IpService.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/service/IpService.java new file mode 100644 index 0000000..061f822 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/service/IpService.java @@ -0,0 +1,17 @@ +package com.ruoyi.plus.system.service; + +import com.ruoyi.plus.common.service.BaseService; +import com.ruoyi.plus.system.entity.Ip; + +/** + *

+ * IP地址 服务类 + *

+ * + * @author geekidea + * @since 2019-08-04 + */ +public interface IpService extends BaseService { + + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/service/SysLogService.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/service/SysLogService.java new file mode 100644 index 0000000..b542521 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/service/SysLogService.java @@ -0,0 +1,35 @@ +package com.ruoyi.plus.system.service; + +import com.ruoyi.plus.system.entity.SysLog; +import com.ruoyi.plus.common.service.BaseService; +import com.ruoyi.plus.system.web.param.SysLogQueryParam; +import com.ruoyi.plus.system.web.vo.SysLogQueryVo; +import com.ruoyi.plus.common.web.vo.Paging; + +import java.io.Serializable; + +/** + *

+ * 系统日志 服务类 + *

+ * + * @author geekidea + * @since 2019-08-04 + */ +public interface SysLogService extends BaseService { + + /** + * 根据ID获取查询对象 + * @param id + * @return + */ + SysLogQueryVo getSysLogById(Serializable id) throws Exception; + + /** + * 获取分页对象 + * @param sysLogQueryParam + * @return + */ + Paging getSysLogPageList(SysLogQueryParam sysLogQueryParam) throws Exception; + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/service/SysUserService.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/service/SysUserService.java new file mode 100644 index 0000000..bef9d5e --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/service/SysUserService.java @@ -0,0 +1,35 @@ +package com.ruoyi.plus.system.service; + +import com.ruoyi.plus.system.entity.SysUser; +import com.ruoyi.plus.common.service.BaseService; +import com.ruoyi.plus.system.web.param.SysUserQueryParam; +import com.ruoyi.plus.system.web.vo.SysUserQueryVo; +import com.ruoyi.plus.common.web.vo.Paging; + +import java.io.Serializable; + +/** + *

+ * SystemUser 服务类 + *

+ * + * @author geekidea + * @since 2019-08-26 + */ +public interface SysUserService extends BaseService { + + /** + * 根据ID获取查询对象 + * @param id + * @return + */ + SysUserQueryVo getSysUserById(Serializable id) throws Exception; + + /** + * 获取分页对象 + * @param sysUserQueryParam + * @return + */ + Paging getSysUserPageList(SysUserQueryParam sysUserQueryParam) throws Exception; + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/service/impl/IpServiceImpl.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/service/impl/IpServiceImpl.java new file mode 100644 index 0000000..ab9c143 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/service/impl/IpServiceImpl.java @@ -0,0 +1,30 @@ +package com.ruoyi.plus.system.service.impl; + +import com.ruoyi.plus.common.service.impl.BaseServiceImpl; +import com.ruoyi.plus.system.entity.Ip; +import com.ruoyi.plus.system.mapper.IpMapper; +import com.ruoyi.plus.system.service.IpService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + + +/** + *

+ * IP地址 服务实现类 + *

+ * + * @author geekidea + * @since 2019-08-04 + */ +@Service +@Transactional(rollbackFor = Exception.class) +@Slf4j +public class IpServiceImpl extends BaseServiceImpl implements IpService { + + @Autowired + private IpMapper ipMapper; + + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/service/impl/SysLogServiceImpl.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/service/impl/SysLogServiceImpl.java new file mode 100644 index 0000000..4d8c438 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/service/impl/SysLogServiceImpl.java @@ -0,0 +1,49 @@ +package com.ruoyi.plus.system.service.impl; + +import com.ruoyi.plus.system.entity.SysLog; +import com.ruoyi.plus.system.mapper.SysLogMapper; +import com.ruoyi.plus.system.service.SysLogService; +import com.ruoyi.plus.system.web.param.SysLogQueryParam; +import com.ruoyi.plus.system.web.vo.SysLogQueryVo; +import com.ruoyi.plus.common.service.impl.BaseServiceImpl; +import com.ruoyi.plus.common.web.vo.Paging; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.beans.factory.annotation.Autowired; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.metadata.OrderItem; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import java.io.Serializable; + + +/** + *

+ * 系统日志 服务实现类 + *

+ * + * @author geekidea + * @since 2019-08-04 + */ +@Slf4j +@Service +@Transactional(rollbackFor = Exception.class) +public class SysLogServiceImpl extends BaseServiceImpl implements SysLogService { + + @Autowired + private SysLogMapper sysLogMapper; + + @Override + public SysLogQueryVo getSysLogById(Serializable id) throws Exception{ + return sysLogMapper.getSysLogById(id); + } + + @Override + public Paging getSysLogPageList(SysLogQueryParam sysLogQueryParam) throws Exception{ + Page page = setPageParam(sysLogQueryParam,OrderItem.desc("create_time")); + IPage iPage = sysLogMapper.getSysLogPageList(page,sysLogQueryParam); + return new Paging(iPage); + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/service/impl/SysUserServiceImpl.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/service/impl/SysUserServiceImpl.java new file mode 100644 index 0000000..63bd7e5 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/service/impl/SysUserServiceImpl.java @@ -0,0 +1,49 @@ +package com.ruoyi.plus.system.service.impl; + +import com.ruoyi.plus.system.entity.SysUser; +import com.ruoyi.plus.system.mapper.SysUserMapper; +import com.ruoyi.plus.system.service.SysUserService; +import com.ruoyi.plus.system.web.param.SysUserQueryParam; +import com.ruoyi.plus.system.web.vo.SysUserQueryVo; +import com.ruoyi.plus.common.service.impl.BaseServiceImpl; +import com.ruoyi.plus.common.web.vo.Paging; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.beans.factory.annotation.Autowired; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.metadata.OrderItem; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import java.io.Serializable; + + +/** + *

+ * SystemUser 服务实现类 + *

+ * + * @author geekidea + * @since 2019-08-26 + */ +@Slf4j +@Service +@Transactional(rollbackFor = Exception.class) +public class SysUserServiceImpl extends BaseServiceImpl implements SysUserService { + + @Autowired + private SysUserMapper sysUserMapper; + + @Override + public SysUserQueryVo getSysUserById(Serializable id) throws Exception{ + return sysUserMapper.getSysUserById(id); + } + + @Override + public Paging getSysUserPageList(SysUserQueryParam sysUserQueryParam) throws Exception{ + Page page = setPageParam(sysUserQueryParam,OrderItem.desc("create_time")); + IPage iPage = sysUserMapper.getSysUserPageList(page,sysUserQueryParam); + return new Paging(iPage); + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/controller/SysLogController.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/controller/SysLogController.java new file mode 100644 index 0000000..5cf0152 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/controller/SysLogController.java @@ -0,0 +1,90 @@ +package com.ruoyi.plus.system.web.controller; + +import com.ruoyi.plus.common.api.ApiResult; +import com.ruoyi.plus.common.web.controller.BaseController; +import com.ruoyi.plus.common.web.param.IdParam; +import com.ruoyi.plus.common.web.vo.Paging; +import com.ruoyi.plus.system.entity.SysLog; +import com.ruoyi.plus.system.service.SysLogService; +import com.ruoyi.plus.system.web.param.SysLogQueryParam; +import com.ruoyi.plus.system.web.vo.SysLogQueryVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +/** + *

+ * 系统日志 前端控制器 + *

+ * + * @author geekidea + * @since 2019-08-04 + */ +@Slf4j +@RestController +@RequestMapping("/sysLog") +@Api("系统日志 API") +public class SysLogController extends BaseController { + + @Autowired + private SysLogService sysLogService; + + /** + * 添加系统日志 + */ + @PostMapping("/add") + @ApiOperation(value = "添加SysLog对象",notes = "添加系统日志",response = ApiResult.class) + public ApiResult addSysUser(@Valid @RequestBody SysLog sysLog) throws Exception{ + boolean flag = sysLogService.save(sysLog); + return ApiResult.result(flag); + } + + /** + * 修改系统日志 + */ + @PostMapping("/update") + @ApiOperation(value = "修改SysLog对象",notes = "修改系统日志",response = ApiResult.class) + public ApiResult updateSysUser(@Valid @RequestBody SysLog sysLog) throws Exception{ + boolean flag = sysLogService.updateById(sysLog); + return ApiResult.result(flag); + } + + /** + * 删除系统日志 + */ + @PostMapping("/delete") + @ApiOperation(value = "删除SysLog对象",notes = "删除系统日志",response = ApiResult.class) + public ApiResult deleteSysUser(@Valid @RequestBody IdParam idParam) throws Exception{ + boolean flag = sysLogService.removeById(idParam.getId()); + return ApiResult.result(flag); + } + + /** + * 获取系统日志 + */ + @PostMapping("/info") + @ApiOperation(value = "获取SysLog对象详情",notes = "查看系统日志",response = SysLogQueryVo.class) + public ApiResult getSysUser(@Valid @RequestBody IdParam idParam) throws Exception{ + SysLogQueryVo sysLogQueryVo = sysLogService.getSysLogById(idParam.getId()); + return ApiResult.ok(sysLogQueryVo); + } + + /** + * 系统日志分页列表 + */ + @PostMapping("/getPageList") + @ApiOperation(value = "获取SysLog分页列表",notes = "系统日志分页列表",response = SysLogQueryVo.class) + public ApiResult> getSysLogPageList(@Valid @RequestBody(required = false) SysLogQueryParam sysLogQueryParam) throws Exception{ + Paging paging = sysLogService.getSysLogPageList(sysLogQueryParam); + return ApiResult.ok(paging); + } + +} + diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/controller/SysUserController.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/controller/SysUserController.java new file mode 100644 index 0000000..280ec5d --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/controller/SysUserController.java @@ -0,0 +1,91 @@ +package com.ruoyi.plus.system.web.controller; + +import com.ruoyi.plus.system.entity.SysUser; +import com.ruoyi.plus.system.service.SysUserService; +import com.ruoyi.plus.system.web.param.SysUserQueryParam; +import com.ruoyi.plus.system.web.vo.SysUserQueryVo; +import com.ruoyi.plus.common.web.controller.BaseController; +import com.ruoyi.plus.common.api.ApiResult; + import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +import com.ruoyi.plus.common.web.vo.Paging; +import com.ruoyi.plus.common.web.param.IdParam; + +/** + *

+ * SystemUser 前端控制器 + *

+ * + * @author geekidea + * @since 2019-08-26 + */ +@Slf4j +@RestController +@RequestMapping("/sysUser") +@Api("SystemUser API") +public class SysUserController extends BaseController { + + @Autowired + private SysUserService sysUserService; + + /** + * Save SystemUser + */ + @PostMapping("/add") + @ApiOperation(value = "Save SysUser",notes = "Save SystemUser",response = ApiResult.class) + public ApiResult addSysUser(@Valid @RequestBody SysUser sysUser) throws Exception{ + boolean flag = sysUserService.save(sysUser); + return ApiResult.result(flag); + } + + /** + * Update SystemUser + */ + @PostMapping("/update") + @ApiOperation(value = "Update SysUser",notes = "Update SystemUser",response = ApiResult.class) + public ApiResult updateSysUser(@Valid @RequestBody SysUser sysUser) throws Exception{ + boolean flag = sysUserService.updateById(sysUser); + return ApiResult.result(flag); + } + + /** + * Delete SystemUser + */ + @PostMapping("/delete") + @ApiOperation(value = "Delete SysUser",notes = "Delete SystemUser",response = ApiResult.class) + public ApiResult deleteSysUser(@Valid @RequestBody IdParam idParam) throws Exception{ + boolean flag = sysUserService.removeById(idParam.getId()); + return ApiResult.result(flag); + } + + /** + * Get SystemUser + */ + @PostMapping("/info") + @ApiOperation(value = "Get SysUser Detail",notes = "SystemUser Info",response = SysUserQueryVo.class) + public ApiResult getSysUser(@Valid @RequestBody IdParam idParam) throws Exception{ + SysUserQueryVo sysUserQueryVo = sysUserService.getSysUserById(idParam.getId()); + return ApiResult.ok(sysUserQueryVo); + } + + /** + * SystemUser Pagination + */ + @PostMapping("/getPageList") + @ApiOperation(value = "Get SysUserPagination",notes = "SystemUser Pagination",response = SysUserQueryVo.class) + public ApiResult> getSysUserPageList(@Valid @RequestBody(required = false) SysUserQueryParam sysUserQueryParam) throws Exception{ + Paging paging = sysUserService.getSysUserPageList(sysUserQueryParam); + return ApiResult.ok(paging); + } + +} + diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/param/SysLogQueryParam.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/param/SysLogQueryParam.java new file mode 100644 index 0000000..acc10fa --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/param/SysLogQueryParam.java @@ -0,0 +1,22 @@ +package com.ruoyi.plus.system.web.param; + +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import com.ruoyi.plus.common.web.param.QueryParam; + +/** + *

+ * 系统日志 查询参数对象 + *

+ * + * @author geekidea + * @date 2019-08-04 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ApiModel(value="SysLogQueryParam对象", description="系统日志查询参数") +public class SysLogQueryParam extends QueryParam { + private static final long serialVersionUID = 1L; +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/param/SysUserQueryParam.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/param/SysUserQueryParam.java new file mode 100644 index 0000000..05db1c0 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/param/SysUserQueryParam.java @@ -0,0 +1,22 @@ +package com.ruoyi.plus.system.web.param; + +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import com.ruoyi.plus.common.web.param.QueryParam; + +/** + *

+ * SystemUser 查询参数对象 + *

+ * + * @author geekidea + * @date 2019-08-26 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ApiModel(value="SysUserQueryParam对象", description="SystemUser查询参数") +public class SysUserQueryParam extends QueryParam { + private static final long serialVersionUID = 1L; +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/vo/IpQueryVo.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/vo/IpQueryVo.java new file mode 100644 index 0000000..cf6c805 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/vo/IpQueryVo.java @@ -0,0 +1,44 @@ +package com.ruoyi.plus.system.web.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * IP地址 查询结果对象 + *

+ * + * @author geekidea + * @date 2019-08-04 + */ +@Data +@ApiModel(value="IpQueryVo对象", description="IP地址查询参数") +public class IpQueryVo implements Serializable{ + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "ip开始地址") + private String ipStart; + + @ApiModelProperty(value = "ip结束地址") + private String ipEnd; + + @ApiModelProperty(value = "区域") + private String area; + + @ApiModelProperty(value = "运营商") + private String operator; + + @ApiModelProperty(value = "主键") + private Long id; + + @ApiModelProperty(value = "ip开始地址数字") + private Long ipStartNum; + + @ApiModelProperty(value = "ip结束地址数字") + private Long ipEndNum; + +} \ No newline at end of file diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/vo/SysLogQueryVo.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/vo/SysLogQueryVo.java new file mode 100644 index 0000000..16126ac --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/vo/SysLogQueryVo.java @@ -0,0 +1,38 @@ +package com.ruoyi.plus.system.web.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +import java.util.Date; + +/** + *

+ * 系统日志 查询结果对象 + *

+ * + * @author geekidea + * @date 2019-08-04 + */ +@Data +@ApiModel(value="SysLogQueryVo对象", description="系统日志查询参数") +public class SysLogQueryVo implements Serializable{ + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + private Long logId; + + @ApiModelProperty(value = "类型") + private Boolean type; + + @ApiModelProperty(value = "内容") + private String content; + + @ApiModelProperty(value = "创建人ID") + private Long createId; + + @ApiModelProperty(value = "创建时间") + private Date createTime; + +} \ No newline at end of file diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/vo/SysUserQueryVo.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/vo/SysUserQueryVo.java new file mode 100644 index 0000000..fb0041f --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/system/web/vo/SysUserQueryVo.java @@ -0,0 +1,44 @@ +package com.ruoyi.plus.system.web.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +import java.util.Date; + +/** + *

+ * SystemUser 查询结果对象 + *

+ * + * @author geekidea + * @date 2019-08-26 + */ +@Data +@ApiModel(value="SysUserQueryVo对象", description="SystemUser查询参数") +public class SysUserQueryVo implements Serializable{ + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + private Long id; + + @ApiModelProperty(value = "name") + private String name; + + @ApiModelProperty(value = "account") + private String account; + + @ApiModelProperty(value = "password") + private String pwd; + + @ApiModelProperty(value = "remark") + private String remark; + + @ApiModelProperty(value = "create time") + private Date createTime; + + @ApiModelProperty(value = "update time") + private Date updateTime; + +} \ No newline at end of file diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/AnsiUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/AnsiUtil.java new file mode 100644 index 0000000..217041b --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/AnsiUtil.java @@ -0,0 +1,58 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +import lombok.extern.slf4j.Slf4j; +import org.fusesource.jansi.Ansi; +import org.springframework.core.env.Environment; + +/** + * @author geekidea + * @date 2018-11-08 + */ +@Slf4j +public class AnsiUtil { + + private static boolean enableAnsi; + + static { + Boolean value = false; + try { + Environment environment = SpringContextUtil.getBean(Environment.class); + value = environment.getProperty("spring-boot-plus.enable-ansi",boolean.class); + value = value == null ? false : value; + } catch (Exception e) { + e.printStackTrace(); + } + enableAnsi = value; + } + + public static String getAnsi(Ansi.Color color,String text){ + + if (enableAnsi){ + return Ansi.ansi().eraseScreen().fg(color).a(text).reset().toString(); + } + return text; + } + + public static String getAnsi(Ansi.Color color,String text,boolean flag){ + if (flag){ + return Ansi.ansi().eraseScreen().fg(color).a(text).reset().toString(); + } + return text; + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/BrowserUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/BrowserUtil.java new file mode 100644 index 0000000..c3ae182 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/BrowserUtil.java @@ -0,0 +1,88 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +import javax.servlet.http.HttpServletRequest; + +/** + * + * 浏览器工具类
+ * 1.获取当前浏览器名称 + * 2.判断当前用户的浏览器 + *
+ * + * @author geekidea + * @since 2018-11-08 + */ +public final class BrowserUtil { + public static final String IE = "msie"; + public static final String FIREFOX = "firefox"; + public static final String CHROME = "chrome"; + private BrowserUtil(){ + throw new AssertionError(); + } + + /** + * 获取当前浏览器名称 + * + * @param request + * @return 返回浏览器名称 + */ + public static String getCurrent(HttpServletRequest request) { + String userAgent = request.getHeader("USER-AGENT").toLowerCase(); + if (userAgent != null && !userAgent.trim().equals("")) { + if (userAgent.indexOf(CHROME) >= 0) { + return CHROME; + } else if (userAgent.indexOf(FIREFOX) >= 0) { + return FIREFOX; + } else if (userAgent.indexOf(IE) >= 0) { + return IE; + } + } + return null; + } + + /** + * 是否是IE浏览器 + * + * @param request + * @return + */ + public static boolean isIE(HttpServletRequest request) { + return IE.equals(getCurrent(request)); + } + + /** + * 是否是Firefox浏览器 + * + * @param request + * @return + */ + public static boolean isFirefox(HttpServletRequest request) { + return FIREFOX.equals(getCurrent(request)); + } + + /** + * 是否是Chrome浏览器 + * + * @param request + * @return + */ + public static boolean isChrome(HttpServletRequest request) { + return CHROME.equals(getCurrent(request)); + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/ClientInfoUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/ClientInfoUtil.java new file mode 100644 index 0000000..f56d673 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/ClientInfoUtil.java @@ -0,0 +1,106 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +import cn.hutool.http.useragent.UserAgent; +import cn.hutool.http.useragent.UserAgentUtil; +import com.ruoyi.plus.security.vo.ClientInfo; +import com.ruoyi.plus.security.vo.DeviceInfo; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + *

+ * 用户客户端信息工具类 + *

+ * @author geekidea + * @date 2019-05-24 + **/ +public class ClientInfoUtil { + + /** + * 获取用户客户端信息 + * @param userAgentString + * @return + */ + public static ClientInfo get(String userAgentString){ + ClientInfo clientInfo = new ClientInfo(); + + UserAgent userAgent = UserAgentUtil.parse(userAgentString); + + // 浏览器名称 + clientInfo.setBrowserName(userAgent.getBrowser().getName()); + // 浏览器版本 + clientInfo.setBrowserversion(userAgent.getVersion()); + // 浏览器引擎名称 + clientInfo.setEngineName(userAgent.getEngine().getName()); + // 浏览器引擎版本 + clientInfo.setEngineVersion(userAgent.getEngineVersion()); + // 用户操作系统名称 + clientInfo.setOsName(userAgent.getOs().getName()); + // 用户操作平台名称 + clientInfo.setPlatformName(userAgent.getPlatform().getName()); + // 是否是手机 + clientInfo.setMobile(userAgent.isMobile()); + + // 获取移动设备名称和机型 + DeviceInfo deviceInfo = getDeviceInfo(userAgentString); + // 设置移动设备名称和机型 + clientInfo.setDeviceName(deviceInfo.getName()); + clientInfo.setDeviceModel(deviceInfo.getModel()); + + // ip + clientInfo.setIp(IpUtil.getRequestIp()); + + return clientInfo; + } + + /** + * 获取移动端用户设备的名称和机型 + * @param userAgentString + * @return + */ + public static DeviceInfo getDeviceInfo(String userAgentString){ + DeviceInfo deviceInfo = new DeviceInfo(); + try { + Pattern pattern = Pattern.compile(";\\s?(\\S*?\\s?\\S*?)\\s?Build/(\\S*?)[;)]"); + Matcher matcher = pattern.matcher(userAgentString); + String model = null; + String name = null; + + if (matcher.find()) { + model = matcher.group(1); + name = matcher.group(2); + } + + if (model == null && name == null){ + pattern = Pattern.compile(";\\s?(\\S*?\\s?\\S*?)\\s?\\)"); + matcher = pattern.matcher(userAgentString); + if (matcher.find()) { + model = matcher.group(1); + } + } + + deviceInfo.setName(name); + deviceInfo.setModel(model); + } catch (Exception e) { + e.printStackTrace(); + } + return deviceInfo; + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/ContentTypeUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/ContentTypeUtil.java new file mode 100644 index 0000000..5b8de2f --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/ContentTypeUtil.java @@ -0,0 +1,88 @@ +package com.ruoyi.plus.util; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.support.PropertiesLoaderUtils; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Properties; + +/** + * 获取文件的内容类型 + * mime-type参考:https://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?revision=1752884&view=co + * @author geekidea + * @date 2019/08/20 + * @since + */ +@Slf4j +public final class ContentTypeUtil { + + private static String MIME_TYPE_CONFIG_FILE = "config/mime-type.properties"; + + private static String DEFAULT_MIME_TYPE = "application/octet-stream"; + + private static Properties properties; + + static { + try { + properties = PropertiesLoaderUtils.loadProperties(new ClassPathResource(MIME_TYPE_CONFIG_FILE)); + } catch (IOException e) { + log.error("读取配置文件" + MIME_TYPE_CONFIG_FILE + "异常",e); + } + log.info(MIME_TYPE_CONFIG_FILE + " = " + properties); + } + + /** + * 获取文件内容类型 + * @param file + * @return + */ + public static String getContentType(File file){ + if (file == null){ + return null; + } + Path path = Paths.get(file.toURI()); + if (path == null){ + return null; + } + String contentType = null; + try { + contentType = Files.probeContentType(path); + } catch (IOException e) { + log.error("获取文件ContentType异常",e); + } + if (contentType == null){ + // 读取拓展的自定义配置 + contentType = getContentTypeByExtension(file); + } + // 设置默认的内容类型 + if (contentType == null){ + contentType = DEFAULT_MIME_TYPE; + } + return contentType; + } + + /** + * 根据文件后缀获取自定义配置的文件mime-type + * @param file + * @return + */ + private static String getContentTypeByExtension(File file){ + if (properties == null){ + return null; + } + String extension = FilenameUtils.getExtension(file.getName()); + if (StringUtils.isBlank(extension)){ + return null; + } + String contentType = properties.getProperty(extension); + return contentType; + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/DateUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/DateUtil.java new file mode 100644 index 0000000..8c57805 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/DateUtil.java @@ -0,0 +1,46 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * @author geekidea + * @date 2018-11-08 + */ +public class DateUtil { + + public static final String formatStr_yyyyMMddHHmmssS_ = "yyyyMMddHHmmss"; + public static final String formatStr_yyyyMMddHHmmssS = "yyyy-MM-dd HH:mm:ss.S"; + public static final String formatStr_yyyyMMddHHmmss = "yyyy-MM-dd HH:mm:ss"; + public static final String formatStr_yyyyMMddHHmm = "yyyy-MM-dd HH:mm"; + public static final String formatStr_yyyyMMddHH = "yyyy-MM-dd HH"; + public static final String formatStr_yyyyMMdd = "yyyy-MM-dd"; + public static final String formatStr_yyyy = "yyyy"; + public static final String formatStr_yyyy_MM_dd = "yyyyMMdd"; + public static final String formatStr_yyyyMMddDelimiter = "-"; + + public static String getYYYYMMDDHHMMSS(Date date){ + if (date == null){ + return null; + } + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String dateString = simpleDateFormat.format(date); + return dateString; + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/DownloadUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/DownloadUtil.java new file mode 100644 index 0000000..2f395ec --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/DownloadUtil.java @@ -0,0 +1,142 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.util.Base64Utils; +import org.springframework.util.CollectionUtils; +import org.springframework.util.FileCopyUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.net.URLEncoder; +import java.util.List; + +/** + * 文件下载工具类 + * @author geekidea + * @date 2019/8/21 + * @since 1.2.1-RELEASE + */ +@Slf4j +public final class DownloadUtil { + + /** + * 下载文件,使用默认下载处理器 + * @param downloadDir + * @param downloadFileName + * @param allowFileExtensions + * @param response + * @throws Exception + */ + public static void download( String downloadDir, String downloadFileName, List allowFileExtensions, HttpServletResponse response) throws Exception{ + download(downloadDir,downloadFileName,allowFileExtensions,response,new DefaultDownloadHandler()); + } + + /** + * 下载文件,使用自定义下载处理器 + * @param downloadDir 文件目录 + * @param downloadFileName 文件名称 + * @throws Exception + */ + public static void download( String downloadDir, String downloadFileName, List allowFileExtensions, HttpServletResponse response,DownloadHandler downloadHandler) throws Exception { + log.info("downloadDir:{}",downloadDir); + log.info("downloadFileName:{}",downloadFileName); + + if (StringUtils.isBlank(downloadDir)){ + throw new IOException("文件目录不能为空"); + } + if (StringUtils.isBlank(downloadFileName)){ + throw new IOException("文件名称不能为空"); + } + // 安全判断,防止../情况,防止出现类似非法文件名称:../../hello/123.txt + if (downloadFileName.contains("..")||downloadFileName.contains("../")){ + throw new IOException("非法的文件名称"); + } + // 允许下载的文件后缀判断 + if (CollectionUtils.isEmpty(allowFileExtensions)){ + throw new IllegalArgumentException("请设置允许下载的文件后缀"); + } + // 获取文件名称 + String fileExtension = FilenameUtils.getExtension(downloadFileName); + + // 从服务器读取文件,然后输出 + File downloadFile = new File(downloadDir,downloadFileName); + if (!downloadFile.exists()){ + throw new IOException("文件不存在"); + } + + // 判断文件类型,输出对应ContentType,如果没有对应的内容类型,可在config/mime-type.properties配置 + String contentType = ContentTypeUtil.getContentType(downloadFile); + log.info("contentType:{}",contentType); + // 文件大小 + long length = downloadFile.length(); + log.info("length:{}",length); + + // 下载回调处理 + if (downloadHandler == null){ + // 使用默认下载处理器 + downloadHandler = new DefaultDownloadHandler(); + } + boolean flag = downloadHandler.handle(downloadDir,downloadFileName,downloadFile,fileExtension,contentType,length); + if (!flag){ + log.info("下载自定义校验失败,取消下载"); + return; + } + + // 下载文件名称编码,Firefox中文乱码处理 + String encodeDownFileName; + + HttpServletRequest request = HttpServletRequestUtil.getRequest(); + + String browser = BrowserUtil.getCurrent(request); + if(BrowserUtil.FIREFOX.equals(browser)) { + encodeDownFileName = "=?UTF-8?B?" + (new String(Base64Utils.encodeToString(downloadFileName.getBytes("UTF-8")))) + "?="; + } else { + encodeDownFileName = URLEncoder.encode(downloadFileName,"utf-8").replaceAll("\\+", "%20"); + } + log.info("encodeDownFileName:{}",encodeDownFileName); + + log.info("下载文件:" + downloadFile.getAbsolutePath()); + + response.reset(); + // 设置Content-Disposition响应头 + response.setHeader("Content-Disposition", "attachment;fileName=\"" + encodeDownFileName + "\""); + // 设置响应Content-Type + response.setContentType(contentType); + // 设置响应文件大小 + response.setContentLengthLong(length); + + // 文件下载 + InputStream in = new BufferedInputStream(new FileInputStream(downloadFile)); + FileCopyUtils.copy(in, response.getOutputStream()); + } + + public static interface DownloadHandler{ + boolean handle(String dir, String fileName, File file, String fileExtension, String contentType, long length) throws Exception; + } + public static class DefaultDownloadHandler implements DownloadHandler{ + @Override + public boolean handle(String dir, String fileName, File file, String fileExtension, String contentType, long length) throws Exception { + return false; + } + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/EnumUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/EnumUtil.java new file mode 100644 index 0000000..f625f7e --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/EnumUtil.java @@ -0,0 +1,78 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +import org.apache.commons.lang3.StringUtils; + +import java.lang.reflect.Method; + +/** + * 枚举工具类 + * @author geekidea + * @date 2018-11-08 + */ +public class EnumUtil { + + /** + * 通过key获取name + * @param clazz + * @param key + * @return + */ + public static String getEnum(Class clazz,Integer key){ + try{ + Object[] objects = clazz.getEnumConstants(); + Method keyMethod = clazz.getDeclaredMethod("getKey"); + Method valueMethod = clazz.getDeclaredMethod("getValue"); + for (Object object : objects) { + Integer k = (Integer) keyMethod.invoke(object); + if (k.equals(key)){ + String value = (String) valueMethod.invoke(object); + return value; + } + } + }catch (Exception e){ + e.printStackTrace(); + } + return null; + } + + /** + * 判断key在枚举中是否存在 + * @param clazz + * @param key + * @return + */ + public static boolean exists(Class clazz,Integer key){ + String name = getEnum(clazz,key); + if (StringUtils.isBlank(name)){ + return false; + } + return true; + } + + /** + * 判断key在枚举中是否不存在 + * @param clazz + * @param key + * @return + */ + public static boolean notExists(Class clazz,Integer key){ + return !exists(clazz,key); + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/HttpServletRequestUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/HttpServletRequestUtil.java new file mode 100644 index 0000000..c7659ef --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/HttpServletRequestUtil.java @@ -0,0 +1,34 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; + +/** + * 获取当前请求的HttpServletRequest对象 + * @author geekidea + * @date 2018-11-08 + */ +public class HttpServletRequestUtil { + + public static HttpServletRequest getRequest() { + return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/HttpServletResponseUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/HttpServletResponseUtil.java new file mode 100644 index 0000000..2b5bf50 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/HttpServletResponseUtil.java @@ -0,0 +1,45 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +import com.alibaba.fastjson.JSON; + +import javax.servlet.http.HttpServletResponse; +import java.io.PrintWriter; + +/** + * @author geekidea + * @date 2018-11-08 + */ +public final class HttpServletResponseUtil { + + private static String UTF8 = "UTF-8"; + private static String CONTENT_TYPE = "application/json"; + + private HttpServletResponseUtil(){ + throw new AssertionError(); + } + + public static void printJSON(HttpServletResponse response, Object object) throws Exception{ + response.setCharacterEncoding(UTF8); + response.setContentType(CONTENT_TYPE); + PrintWriter printWriter = response.getWriter(); + printWriter.write(JSON.toJSONString(object)); + printWriter.flush(); + printWriter.close(); + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/IpUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/IpUtil.java new file mode 100644 index 0000000..6787426 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/IpUtil.java @@ -0,0 +1,77 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * 获取IP地址工具类 + * @author geekidea + * @date 2018-11-08 + */ +public final class IpUtil { + private IpUtil(){ + throw new AssertionError(); + } + + /** + * 获取请求用户的IP地址 + * @return + */ + public static String getRequestIp() { + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + HttpServletRequest request = attributes.getRequest(); + return getRequestIp(request); + } + + /** + * 获取请求用户的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.getRemoteAddr(); + } + + if ("0:0:0:0:0:0:0:1".equals(ip)){ + ip = getLocalhostIp(); + } + return ip; + } + + public static String getLocalhostIp(){ + try { + return InetAddress.getLocalHost().getHostAddress(); + } catch (UnknownHostException e) { + } + return null; + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/LoginUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/LoginUtil.java new file mode 100644 index 0000000..6d03d01 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/LoginUtil.java @@ -0,0 +1,117 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +import com.ruoyi.plus.common.constant.CommonConstant; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.env.Environment; + +import javax.servlet.http.HttpServletRequest; + + +/** + * @author geekidea + * @date 2018-11-08 + */ +@Slf4j +public class LoginUtil { + + /** + * TOKEN有效时间,单位分钟 + */ + public static Integer TOKEN_VALID_TIME_MINUTE; + + static { + Environment environment = SpringContextUtil.getBean(Environment.class); + String time = environment.getProperty("spring-boot-plus.login.token-valid-time"); + TOKEN_VALID_TIME_MINUTE = Integer.valueOf(time); + log.info("TOKEN_VALID_TIME_MINUTE:{}",TOKEN_VALID_TIME_MINUTE); + } + + /** + * 从请求头或者请求参数中 + * @param request + * @return + */ + public static String getToken(HttpServletRequest request){ + // 从请求头中获取token + String token = request.getHeader(CommonConstant.TOKEN); + if (StringUtils.isBlank(token)){ + // 从请求参数中获取token + token = request.getParameter(CommonConstant.TOKEN); + } + return token; + } + +// /** +// * 获取当前登陆用户对象 +// * @return +// */ +// public static LoginSysUserVo getLoginSysUser(){ +// LoginSysUserVo loginSysUserVo = (LoginSysUserVo) HttpServletRequestUtil.getRequest().getAttribute(CommonConstant.LOGIN_SYS_USER); +// return loginSysUserVo; +// } +// +// /** +// * 获取当前登陆用户的ID +// * @return +// */ +// public static String getUserId(){ +// LoginSysUserVo loginSysUserVo = getLoginSysUser(); +// if (loginSysUserVo !=null){ +// return loginSysUserVo.getUserId(); +// } +// return null; +// } +// +// /** +// * 获取当前登陆用户的账号 +// * @return +// */ +// public static String getAccount(){ +// LoginSysUserVo loginSysUserVo = getLoginSysUser(); +// if (loginSysUserVo !=null){ +// return loginSysUserVo.getAccount(); +// } +// return null; +// } +// +// /** +// * 获取当前登陆用户的名称 +// * @return +// */ +// public static String getUserName(){ +// LoginSysUserVo loginSysUserVo = getLoginSysUser(); +// if (loginSysUserVo !=null){ +// return loginSysUserVo.getUserName(); +// } +// return null; +// } +// +// /** +// * 判断是否是管理员,true:是,false:否 +// * @return +// */ +// public static Boolean isAdmin() { +// LoginSysUserVo loginSysUserVo = getLoginSysUser(); +// if (loginSysUserVo !=null){ +// return loginSysUserVo.getAdmin(); +// } +// return null; +// } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/MapUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/MapUtil.java new file mode 100644 index 0000000..db0f841 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/MapUtil.java @@ -0,0 +1,50 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +import java.util.HashMap; +import java.util.Map; + +/** + *

+ * Map构建工具类 + *

+ * @author geekidea + * @date 2019-05-23 + **/ +public class MapUtil { + + private Map map; + + private MapUtil(){ + map = new HashMap<>(); + } + + public static MapUtil builder(){ + return new MapUtil(); + } + + public MapUtil put(String key,Object value){ + this.map.put(key,value); + return this; + } + + public Map build(){ + return this.map; + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/PasswordUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/PasswordUtil.java new file mode 100644 index 0000000..9f9173a --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/PasswordUtil.java @@ -0,0 +1,43 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang3.StringUtils; + +/** + * 密码加密工具类 + * @author geekidea + * @date 2018-11-08 + */ +@Slf4j +public class PasswordUtil { + private static final String KEY = "com.ruoyi.plus.springbootplus.pwd.key"; + public static String encrypt(String pwd){ + if (StringUtils.isBlank(pwd)){ + return null; + } + pwd = pwd + KEY; + String newPwd = DigestUtils.sha256Hex(pwd) + DigestUtils.md5Hex(pwd); + return newPwd; + } + + public static void main(String[] args) { + log.debug(encrypt("7c4a8d09ca3762af61e59520943dc26494f8941b")); + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/PrintApplicationInfo.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/PrintApplicationInfo.java new file mode 100644 index 0000000..83e5619 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/PrintApplicationInfo.java @@ -0,0 +1,93 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +import lombok.extern.slf4j.Slf4j; +import org.fusesource.jansi.Ansi; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.ConfigurableEnvironment; + +/** + *

+ * 打印项目信息 + *

+ * @author geekidea + * @date 2019-05-08 + **/ +@Slf4j +public class PrintApplicationInfo { + + + /** + * 执行之前,打印前置条件提示 + */ + public static void printTip(){ + StringBuffer tip = new StringBuffer(); + tip.append("======================================================================================\n"); + tip.append(" \n"); + tip.append(" !!!准备工作!!! \n"); + tip.append(" 1.请先在MySQL中创建数据库,默认数据库名称为:spring_boot_plus \n"); + tip.append(" 2.数据库脚本在项目docs/mysql_spring_boot_plus.sql \n"); + tip.append(" 3.请先启动redis服务 \n"); + tip.append(" 4.更多注意事项:请查看: https://springboot.plus \n"); + tip.append(" \n"); + tip.append("======================================================================================\n"); + log.info("\n{}",Ansi.ansi().eraseScreen().fg(Ansi.Color.YELLOW).a(tip.toString()).reset().toString()); + } + + /** + * 启动成功之后,打印项目信息 + */ + public static void print(ConfigurableApplicationContext context){ + ConfigurableEnvironment environment = context.getEnvironment(); + + // 项目名称 + String projectFinalName = environment.getProperty("info.project-finalName"); + // 项目版本 + String projectVersion = environment.getProperty("info.project-version"); + // 项目profile + String profileActive = environment.getProperty("spring.profiles.active"); + // 项目路径 + String contextPath = environment.getProperty("server.servlet.context-path"); + // 项目端口 + String port = environment.getProperty("server.port"); + + log.info("projectFinalName : {}",projectFinalName); + log.info("projectVersion : {}",projectVersion); + log.info("profileActive : {}",profileActive); + log.info("contextPath : {}",contextPath); + log.info("port : {}",port); + + String startSuccess = " ____ __ __ ____ \n" + + "/\\ _`\\ /\\ \\__ /\\ \\__ /\\ _`\\ \n" + + "\\ \\,\\L\\_\\ \\ ,_\\ __ _ __\\ \\ ,_\\ \\ \\,\\L\\_\\ __ __ ___ ___ __ ____ ____ \n" + + " \\/_\\__ \\\\ \\ \\/ /'__`\\ /\\`'__\\ \\ \\/ \\/_\\__ \\ /\\ \\/\\ \\ /'___\\ /'___\\ /'__`\\ /',__\\ /',__\\ \n" + + " /\\ \\L\\ \\ \\ \\_/\\ \\L\\.\\_\\ \\ \\/ \\ \\ \\_ /\\ \\L\\ \\ \\ \\_\\ \\/\\ \\__//\\ \\__//\\ __//\\__, `\\/\\__, `\\\n" + + " \\ `\\____\\ \\__\\ \\__/.\\_\\\\ \\_\\ \\ \\__\\ \\ `\\____\\ \\____/\\ \\____\\ \\____\\ \\____\\/\\____/\\/\\____/\n" + + " \\/_____/\\/__/\\/__/\\/_/ \\/_/ \\/__/ \\/_____/\\/___/ \\/____/\\/____/\\/____/\\/___/ \\/___/ \n" + + " \n" + + " "; + + String homeUrl = "http://" + IpUtil.getLocalhostIp() + ":" + port + contextPath; + String swaggerUrl = "http://" + IpUtil.getLocalhostIp() + ":" + port + contextPath + "docs"; + log.info("home:{}",homeUrl); + log.info("docs:{}",swaggerUrl); + log.info("spring-boot-plus project start success..........."); + log.info("\n{}",AnsiUtil.getAnsi(Ansi.Color.BLUE,startSuccess)); + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/RedisCacheUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/RedisCacheUtil.java new file mode 100644 index 0000000..04ae942 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/RedisCacheUtil.java @@ -0,0 +1,46 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +/** + * @author geekidea + * @date 2018-11-08 + */ +@Component +@Slf4j +public class RedisCacheUtil { + + private static RedisCacheUtil redisCacheUtil; + + @Autowired + private RedisTemplate redisTemplate; + + /** + * 将当前对象赋值给静态对象,调用spring组件: redisCacheUtil.redisTemplate.xxx() + */ + @PostConstruct + public void init(){ + redisCacheUtil = this; + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/RedisKey.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/RedisKey.java new file mode 100644 index 0000000..37a8930 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/RedisKey.java @@ -0,0 +1,25 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +/** + * @author geekidea + * @date 2018-11-08 + */ +public interface RedisKey { + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/SpringContextUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/SpringContextUtil.java new file mode 100644 index 0000000..b0b1805 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/SpringContextUtil.java @@ -0,0 +1,56 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +/** + * Spring工具类,获取Spring上下文对象等 + * @author geekidea + * @date 2018-11-08 + */ +@Component +public class SpringContextUtil implements ApplicationContextAware { + + private static ApplicationContext applicationContext = null; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + if(SpringContextUtil.applicationContext == null){ + SpringContextUtil.applicationContext = applicationContext; + } + } + + public static ApplicationContext getApplicationContext() { + return applicationContext; + } + + public static Object getBean(String name){ + return getApplicationContext().getBean(name); + } + + public static T getBean(Class clazz){ + return getApplicationContext().getBean(clazz); + } + + public static T getBean(String name,Class clazz){ + return getApplicationContext().getBean(name, clazz); + } +} \ No newline at end of file diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/StorageDB.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/StorageDB.java new file mode 100644 index 0000000..3f075cc --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/StorageDB.java @@ -0,0 +1,26 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + + +/** + * @author geekidea + * @date 2018-11-08 + */ +public class StorageDB { + + } diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/TokenUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/TokenUtil.java new file mode 100644 index 0000000..95f0201 --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/TokenUtil.java @@ -0,0 +1,51 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +/** + * @author geekidea + * @date 2018-11-08 + */ +public class TokenUtil { + + /** + * 生成token + * @return + */ + public static String generatetoken(){ + String token = "x-auth-token:" + UUIDUtil.getUUID(); + return token; + } + + /** + * 生成token + * @return + */ + public static String generateFirstLoginRestPwdToken(){ + String token = "first-login-rest-pwd-token:" + UUIDUtil.getUUID(); + return token; + } + + /** + * 生成验证码token + * @return + */ + public static String generateVerificationCodeToken(){ + String token = "verification-code-token:" + UUIDUtil.getUUID(); + return token; + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/UUIDUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/UUIDUtil.java new file mode 100644 index 0000000..558b0ae --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/UUIDUtil.java @@ -0,0 +1,32 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +import java.util.UUID; + +/** + * @author geekidea + * @date 2018-11-08 + */ +public class UUIDUtil { + + public static String getUUID(){ + String uuid = UUID.randomUUID().toString().replaceAll("-", ""); + return uuid; + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/UploadUtil.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/UploadUtil.java new file mode 100644 index 0000000..ba6d48d --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/UploadUtil.java @@ -0,0 +1,104 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.InputStream; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * 文件上传工具类 + * @author geekidea + * @date 2019/8/21 + * @since 1.2.1-RELEASE + */ +@Slf4j +public final class UploadUtil { + + /** + * 上传文件,默认文件名格式,yyyyMMddHHmmssS + * @param uploadPath + * @param multipartFile + * @return + * @throws Exception + */ + public static String upload(String uploadPath, MultipartFile multipartFile) throws Exception { + return upload(uploadPath,multipartFile,new DefaultUploadFileNameHandleImpl()); + } + + /** + * 上传文件 + * @param uploadPath 上传目录 + * @param multipartFile 上传文件 + * @param uploadFileNameHandle 回调 + * @return + * @throws Exception + */ + public static String upload(String uploadPath, MultipartFile multipartFile,UploadFileNameHandle uploadFileNameHandle) throws Exception { + // 获取输入流 + InputStream inputStream = multipartFile.getInputStream(); + // 文件保存目录 + File saveDir = new File(uploadPath); + // 判断目录是否存在,不存在,则创建,如创建失败,则抛出异常 + if (!saveDir.exists()){ + boolean flag = saveDir.mkdirs(); + if (!flag){ + throw new RuntimeException("创建" +saveDir + "目录失败!"); + } + } + + String originalFilename = multipartFile.getOriginalFilename(); + String saveFileName; + if (uploadFileNameHandle == null){ + saveFileName = new DefaultUploadFileNameHandleImpl().handle(originalFilename); + }else{ + saveFileName = uploadFileNameHandle.handle(originalFilename); + } + log.info("saveFileName = " + saveFileName); + + File saveFile = new File(saveDir,saveFileName); + // 保存文件到服务器指定路径 + FileUtils.copyToFile(inputStream,saveFile); + return saveFileName; + } + + + public static interface UploadFileNameHandle{ + String handle(String originalFilename); + } + + public static class DefaultUploadFileNameHandleImpl implements UploadFileNameHandle{ + + @Override + public String handle(String originalFilename) { + // 文件后缀 + String fileExtension= FilenameUtils.getExtension(originalFilename); + // 这里可自定义文件名称,比如按照业务类型/文件格式/日期 + // 此处按照文件日期存储 + String dateString = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssS")); + String fileName = dateString + "." +fileExtension; + return fileName; + } + } + +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/VerificationCode.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/VerificationCode.java new file mode 100644 index 0000000..cff9e1d --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/VerificationCode.java @@ -0,0 +1,154 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.Random; + +/** + * @author geekidea + * @date 2018-11-08 + */ +public class VerificationCode { + private int weight = 110; //验证码图片的长和宽 + private int height = 38; + private String text; //用来保存验证码的文本内容 + private Random r = new Random(); //获取随机数对象 + private String[] fontNames = {"宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312"}; //字体数组 + private String codes = "23456789acdefghjkmnopqrstuvwxyzACDEFGHJKMNPQRSTUVWXYZ"; //验证码数组 + + /** + * 获取随机的颜色 + */ + private Color randomColor() { + //这里为什么是150,因为当r,g,b都为255时,即为白色,为了好辨认,需要颜色深一点。 + int r = this.r.nextInt(150); + int g = this.r.nextInt(150); + int b = this.r.nextInt(150); + //返回一个随机颜色 + return new Color(r, g, b); + } + + /** + * 获取随机字体 + */ + private Font randomFont() { + //获取随机的字体 + int index = r.nextInt(fontNames.length); + String fontName = fontNames[index]; + //随机获取字体的样式,0是无样式,1是加粗,2是斜体,3是加粗加斜体 + int style = r.nextInt(4); + //随机获取字体的大小 + int size = r.nextInt(5) + 24; + //返回一个随机的字体 + return new Font(fontName, style, size); + } + + /** + * 获取随机字符 + */ + private char randomChar() { + int index = r.nextInt(codes.length()); + return codes.charAt(index); + } + + /** + * 画干扰线,验证码干扰线用来防止计算机解析图片 + */ + private void drawLine(BufferedImage image) { + int num = 155; + //定义干扰线的数量 + Graphics2D g = (Graphics2D) image.getGraphics(); + for (int i = 0; i < num; i++) { + int x = r.nextInt(weight); + int y = r.nextInt(height); + int xl = r.nextInt(weight); + int yl = r.nextInt(height); + g.setColor(getRandColor(160, 200)); + g.drawLine(x, y, x + xl, y + yl); + } + } + + /** + * 创建图片的方法 + */ + private BufferedImage createImage() { + //创建图片缓冲区 + BufferedImage image = new BufferedImage(weight, height, BufferedImage.TYPE_INT_RGB); + //获取画笔 + Graphics2D g = (Graphics2D) image.getGraphics(); + // 设定图像背景色(因为是做背景,所以偏淡) + g.setColor(getRandColor(200, 250)); + g.fillRect(0, 0, weight, height); + //返回一个图片 + return image; + } + + /** + * 获取验证码图片的方法 + */ + public BufferedImage getImage() { + BufferedImage image = createImage(); + //获取画笔 + Graphics2D g = (Graphics2D) image.getGraphics(); + StringBuilder sb = new StringBuilder(); + drawLine(image); + //画四个字符即可 + for (int i = 0; i < 4; i++) { + //随机生成字符,因为只有画字符串的方法,没有画字符的方法,所以需要将字符变成字符串再画 + String s = randomChar() + ""; + //添加到StringBuilder里面 + sb.append(s); + //定义字符的x坐标 + float x = i * 1.0F * weight / 4; + //设置字体,随机 + g.setFont(randomFont()); + //设置颜色,随机 + g.setColor(randomColor()); + g.drawString(s, x, height - 5); + } + this.text = sb.toString(); + return image; + } + + /** + * 给定范围获得随机颜色 + */ + Color getRandColor(int fc, int bc) { + Random random = new Random(); + if (fc > 255) { + fc = 255; + } + + if (bc > 255) { + bc = 255; + } + + int r = fc + random.nextInt(bc - fc); + int g = fc + random.nextInt(bc - fc); + int b = fc + random.nextInt(bc - fc); + return new Color(r, g, b); + } + + /** + * 获取验证码文本的方法 + */ + public String getText() { + return text; + } +} diff --git a/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/package-info.java b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/package-info.java new file mode 100644 index 0000000..1f7fa8f --- /dev/null +++ b/ruoyi-plus-api/src/main/java/com/ruoyi/plus/util/package-info.java @@ -0,0 +1,22 @@ +/** + * 公共工具包 + * @author geekidea + * @date 2018-11-08 + */ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.util; \ No newline at end of file diff --git a/ruoyi-plus-api/src/main/resources/config/application-dev.yml b/ruoyi-plus-api/src/main/resources/config/application-dev.yml new file mode 100644 index 0000000..e3271ea --- /dev/null +++ b/ruoyi-plus-api/src/main/resources/config/application-dev.yml @@ -0,0 +1,32 @@ +spring-boot-plus: + # 是否启用ansi控制台输出有颜色的字体,local环境建议开启,服务器环境设置为false + enable-ansi: true + # 请求日志在控制台是否格式化输出,local环境建议开启,服务器环境设置为false + request-log-format: true + # 响应日志在控制台是否格式化输出,local环境建议开启,服务器环境设置为false + response-log-format: true + # 登录设置 + login: + token-valid-time: 60 # 登录token失效时间,单位分钟 + +server: + port: 8888 + servlet: + context-path: / +spring: + datasource: + url: jdbc:mysql://localhost:3306/plus?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true + username: root + password: root + + # Redis配置 + redis: + database: 0 + host: localhost + password: + port: 6379 + +# 方便Spring Boot Admin页面上实时查看日志 +# logback.xml中有详细的日志配置 +logging: + file: logs/spring-boot-plus-log.log diff --git a/ruoyi-plus-api/src/main/resources/config/application-local.yml b/ruoyi-plus-api/src/main/resources/config/application-local.yml new file mode 100644 index 0000000..657310f --- /dev/null +++ b/ruoyi-plus-api/src/main/resources/config/application-local.yml @@ -0,0 +1,48 @@ +spring-boot-plus: + # 是否启用ansi控制台输出有颜色的字体,local环境建议开启,服务器环境设置为false + enable-ansi: true + # 请求日志在控制台是否格式化输出,local环境建议开启,服务器环境设置为false + request-log-format: true + # 响应日志在控制台是否格式化输出,local环境建议开启,服务器环境设置为false + response-log-format: true + # 登录设置 + login: + token-valid-time: 60 # 登录token失效时间,单位分钟 + + # 拦截器配置 + interceptor-config: + resource-config: + include-path: ${spring-boot-plus.resource-access-patterns} + # 文件上传下载配置 + upload-path: /opt/upload/ + # 资源访问路径 + resource-access-path: /resource/ + # 资源访问路径匹配:/resource/** + resource-access-patterns: ${spring-boot-plus.resource-access-path}** + # 资源访问全路径前缀:http://localhost:8888/resource/ + resource-access-url: http://localhost:${server.port}${server.servlet.context-path}${spring-boot-plus.resource-access-path} + + +server: + port: 8888 + servlet: + context-path: / +spring: + datasource: + url: jdbc:mysql://localhost:3306/ruoyi?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true + username: root + password: root + +# Redis配置 + redis: + database: 0 + host: localhost + password: + port: 6379 + + +# logback.xml中有详细的日志配置 +logging: + config: classpath:config/logback.xml + # 方便Spring Boot Admin页面上实时查看日志 + file: logs/spring-boot-plus.log diff --git a/ruoyi-plus-api/src/main/resources/config/application-prod.yml b/ruoyi-plus-api/src/main/resources/config/application-prod.yml new file mode 100644 index 0000000..53c101f --- /dev/null +++ b/ruoyi-plus-api/src/main/resources/config/application-prod.yml @@ -0,0 +1,32 @@ +spring-boot-plus: + # 是否启用ansi控制台输出有颜色的字体,local环境建议开启,服务器环境设置为false + enable-ansi: false + # 请求日志在控制台是否格式化输出,local环境建议开启,服务器环境设置为false + request-log-format: false + # 响应日志在控制台是否格式化输出,local环境建议开启,服务器环境设置为false + response-log-format: false + # 登录设置 + login: + token-valid-time: 60 # 登录token失效时间,单位分钟 + +server: + port: 8888 + servlet: + context-path: / +spring: + datasource: + url: jdbc:mysql://localhost:3306/ruoyi?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true + username: root + password: root + + # Redis配置 + redis: + database: 0 + host: localhost + password: + port: 6379 + +# 方便Spring Boot Admin页面上实时查看日志 +# logback.xml中有详细的日志配置 +logging: + file: logs/spring-boot-plus-log.log diff --git a/ruoyi-plus-api/src/main/resources/config/application-test.yml b/ruoyi-plus-api/src/main/resources/config/application-test.yml new file mode 100644 index 0000000..f2fd591 --- /dev/null +++ b/ruoyi-plus-api/src/main/resources/config/application-test.yml @@ -0,0 +1,32 @@ +spring-boot-plus: + # 是否启用ansi控制台输出有颜色的字体,local环境建议开启,服务器环境设置为false + enable-ansi: false + # 请求日志在控制台是否格式化输出,local环境建议开启,服务器环境设置为false + request-log-format: true + # 响应日志在控制台是否格式化输出,local环境建议开启,服务器环境设置为false + response-log-format: true + # 登录设置 + login: + token-valid-time: 60 # 登录token失效时间,单位分钟 + +server: + port: 8888 + servlet: + context-path: / +spring: + datasource: + url: jdbc:mysql://localhost:3306/ruoyi?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true + username: root + password: Springbootplus666! + + # Redis配置 + redis: + database: 0 + host: localhost + password: + port: 6379 + +# 方便Spring Boot Admin页面上实时查看日志 +# logback.xml中有详细的日志配置 +logging: + file: logs/spring-boot-plus-log.log diff --git a/ruoyi-plus-api/src/main/resources/config/application-uat.yml b/ruoyi-plus-api/src/main/resources/config/application-uat.yml new file mode 100644 index 0000000..53c101f --- /dev/null +++ b/ruoyi-plus-api/src/main/resources/config/application-uat.yml @@ -0,0 +1,32 @@ +spring-boot-plus: + # 是否启用ansi控制台输出有颜色的字体,local环境建议开启,服务器环境设置为false + enable-ansi: false + # 请求日志在控制台是否格式化输出,local环境建议开启,服务器环境设置为false + request-log-format: false + # 响应日志在控制台是否格式化输出,local环境建议开启,服务器环境设置为false + response-log-format: false + # 登录设置 + login: + token-valid-time: 60 # 登录token失效时间,单位分钟 + +server: + port: 8888 + servlet: + context-path: / +spring: + datasource: + url: jdbc:mysql://localhost:3306/ruoyi?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true + username: root + password: root + + # Redis配置 + redis: + database: 0 + host: localhost + password: + port: 6379 + +# 方便Spring Boot Admin页面上实时查看日志 +# logback.xml中有详细的日志配置 +logging: + file: logs/spring-boot-plus-log.log diff --git a/ruoyi-plus-api/src/main/resources/config/application.yml b/ruoyi-plus-api/src/main/resources/config/application.yml new file mode 100644 index 0000000..9c3666a --- /dev/null +++ b/ruoyi-plus-api/src/main/resources/config/application.yml @@ -0,0 +1,210 @@ +# spring-boot-plus Common Config + +############################# 访问路径、端口tomcat start ############################ +server: + port: 8888 + servlet: + context-path: /api + tomcat: + max-threads: 1000 + min-spare-threads: 30 + uri-encoding: UTF-8 +############################# 访问路径、端口tomcat end ############################## + + +################################ spring config start ############################### +spring: + application: + name: spring-boot-plus + http: + encoding: + charset: UTF-8 + enabled: true + force: true + jackson: + date-format: yyy-MM-dd HH:mm:ss + time-zone: GMT+8 + banner: + charset: UTF-8 + location: classpath:config/banner.txt + +# 当前项目maven激活环境,例如:local/dev/test,对应pom.xml中profile设置值 +--- +spring: + profiles: + active: '@profileActive@' +################################ spring config end ################################ + + +############################## spring-boot-plus start ############################# +spring-boot-plus: + # jwt配置 + jwt: + header: token + secret: 666666 + issuer: spring-boot-plus + subject: spring-boot-plus-jwt + audience: web + expire-minutes: 2 + # 拦截器配置 + interceptor-config: + jwt-config: + enabled: true + include-path: /** + exclude-path: /swagger-resources/**,/api-docs/**,/v2/api-docs/**,/login,/verificationCode,/doc/**,/error/**,/docs,/test/**,/resource/** + permission-config: + enabled: false + include-path: /** + exclude-path: /swagger-resources/**,/api-docs/**,/v2/api-docs/**,/adminLogin,/sysLogin,/login.html,/verificationCode,/doc/**,/error/**,/docs,/resource/** + token-timeout-config: + enabled: false + include-path: /** + exclude-path: /swagger-resources/**,/api-docs/**,/v2/api-docs/**,/docs,/resource/** + resource-config: + enabled: true + include-path: ${spring-boot-plus.resource-access-patterns} + upload-config: + enabled: true + include-path: /upload/** + download-config: + enabled: true + include-path: /download/** + # 文件上传下载配置 + # 上传路径配置 + upload-path: /opt/upload/ + # 资源访问路径 + resource-access-path: /resource/ + # 资源访问路径匹配:/resource/** + resource-access-patterns: ${spring-boot-plus.resource-access-path}** + # 资源访问全路径前缀:http://localhost:8888/resource/ + resource-access-url: http://localhost:${server.port}${server.servlet.context-path}${spring-boot-plus.resource-access-path} + # 全局允许上传的类型 + allow-upload-file-extensions: jpg,png,docx,xlsx,pptx,pdf + allow-download-file-extensions: jpg,png,docx,xlsx,pptx,pdf +############################### spring-boot-plus end ############################### + + +############################### mybatis-plus start ################################# +mybatis-plus: + check-config-location: true + configuration: + map-underscore-to-camel-case: true + global-config: + db-config: + id-type: id_worker + logic-delete-value: 0 + logic-not-delete-value: 1 + mapper-locations: classpath*:mapper/**/*Mapper.xml +################################ mybatis-plus end ################################# + + +############################### DRUID数据源配置 start ############################## +--- +spring: + datasource: + driver-class-name: com.mysql.jdbc.Driver + druid: + filter: + slf4j: + enabled: true + stat: + log-slow-sql: true + merge-sql: true + slow-sql-millis: 3000 + wall: + config: + delete-allow: true + drop-table-allow: false + enabled: true + filters: stat,wall,slf4j + initial-size: 10 + max-active: 100 + max-pool-prepared-statement-per-connection-size: 20 + max-wait: 60000 + min-evictable-idle-time-millis: 300000 + min-idle: 10 + pool-prepared-statements: true + stat-view-servlet: + enabled: true + login-password: druid123 + login-username: druid + url-pattern: /druid/* + test-on-borrow: false + test-on-return: false + test-while-idle: true + time-between-eviction-runs-millis: 60000 + validation-query: SELECT 1 FROM DUAL + type: com.alibaba.druid.pool.DruidDataSource +############################### DRUID数据源配置 end ################################ + + +############################### Redis 公共配置 start ############################### +--- +spring: + redis: + jedis: + pool: + max-active: 2000 + max-wait: -1ms + min-idle: 8 + max-idle: 200 + timeout: 10s + lettuce: + pool: + max-active: 200 + max-idle: 8 + max-wait: 10s + min-idle: 2 + shutdown-timeout: 3s +############################### Redis 公共配置 end ################################## + + +#################################### Swagger start #################################### +# swagger配置 +swagger: + base: + package: io.geekidea.springbootplus + contact: + email: geekidea@qq.com + name: geekidea + url: '' + description: '' + title: spring-boot-plus + url: '' + version: 1.0 +#################################### Swagger end ##################################### + + +################################ Spring boot admin start ################################ +--- +spring: + boot: + admin: + client: + url: http://localhost:${server.port}/${server.servlet.context-path} + +# 开启和暴露所有端点 +management: + endpoints: + web: + exposure: + include: "*" + endpoint: + health: + show-details: ALWAYS + logfile: + enabled: true #可在线查看日志 + +# 自定义项目信息,Spring Boot Admin展示使用 +info: + project-groupId: '@project.groupId@' + project-artifactId: '@project.artifactId@' + project-name: '@project.name@' + project-finalName: '@project.build.finalName@' + project-author: ${swagger.contact.name} + project-description: '@project.description@' + project-sourceEncoding: '@project.build.sourceEncoding@' + project-spring-boot-version: '@spring-boot.version@' + project-mybatis-plus-version: '@mybatis-plus-boot-starter.version@' + project-version: '@project.version@' +################################ Spring boot admin end ################################# diff --git a/ruoyi-plus-api/src/main/resources/config/banner.txt b/ruoyi-plus-api/src/main/resources/config/banner.txt new file mode 100644 index 0000000..dcc3fd7 --- /dev/null +++ b/ruoyi-plus-api/src/main/resources/config/banner.txt @@ -0,0 +1,14 @@ +${AnsiColor.BLUE} + _ _ _ _ + (_) | | | | | | + ___ _ __ _ __ _ _ __ __ _ ______| |__ ___ ___ | |_ ______ _ __ | |_ _ ___ + / __| '_ \| '__| | '_ \ / _` |______| '_ \ / _ \ / _ \| __|______| '_ \| | | | / __| + \__ \ |_) | | | | | | | (_| | | |_) | (_) | (_) | |_ | |_) | | |_| \__ \ + |___/ .__/|_| |_|_| |_|\__, | |_.__/ \___/ \___/ \__| | .__/|_|\__,_|___/ + | | __/ | | | + |_| |___/ |_| + +${AnsiColor.YELLOW} :: Spring Boot :: ${AnsiColor.WHITE}(v${spring-boot.version}) +${AnsiColor.YELLOW} :: Spring Boot Plus :: ${AnsiColor.WHITE}(v${project.version}) +${AnsiColor.YELLOW} :: spring-boot-plus :: ${AnsiColor.WHITE}https://springboot.plus + diff --git a/ruoyi-plus-api/src/main/resources/config/logback.xml b/ruoyi-plus-api/src/main/resources/config/logback.xml new file mode 100644 index 0000000..29d0d94 --- /dev/null +++ b/ruoyi-plus-api/src/main/resources/config/logback.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + ${CONTEXT_NAME} + + + + + + + + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + + + + + + + ${FILE_LOG_PATTERN} + + ${LOG_PATH}/spring-boot-plus.log + + ${LOG_PATH}/spring-boot-plus-%d{yyyy-MM-dd}.%i.log + ${MAX_FILE_SIZE} + ${MAX_HISTORY} + + + + + + + ${FILE_LOG_PATTERN} + + ${LOG_PATH}/spring-boot-plus-error.log + + ${LOG_PATH}/spring-boot-plus-error-%d{yyyy-MM-dd}.%i.log + ${MAX_FILE_SIZE} + ${MAX_HISTORY} + + + ERROR + ACCEPT + DENY + + + + + + 0 + 1024 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ruoyi-plus-api/src/main/resources/config/mime-type.properties b/ruoyi-plus-api/src/main/resources/config/mime-type.properties new file mode 100644 index 0000000..70bf2e3 --- /dev/null +++ b/ruoyi-plus-api/src/main/resources/config/mime-type.properties @@ -0,0 +1,3 @@ +# 扩展mime-type +# 参考:https://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?revision=1752884&view=co +md=text/markdown \ No newline at end of file diff --git a/ruoyi-plus-api/src/main/resources/mapper/system/IpMapper.xml b/ruoyi-plus-api/src/main/resources/mapper/system/IpMapper.xml new file mode 100644 index 0000000..d47212f --- /dev/null +++ b/ruoyi-plus-api/src/main/resources/mapper/system/IpMapper.xml @@ -0,0 +1,11 @@ + + + + + + + ip_start, ip_end, area, operator, id, ip_start_num, ip_end_num + + + + diff --git a/ruoyi-plus-api/src/main/resources/mapper/system/SysLogMapper.xml b/ruoyi-plus-api/src/main/resources/mapper/system/SysLogMapper.xml new file mode 100644 index 0000000..479b9a3 --- /dev/null +++ b/ruoyi-plus-api/src/main/resources/mapper/system/SysLogMapper.xml @@ -0,0 +1,18 @@ + + + + + + + log_id, type, content, create_id, create_time + + + + + + + diff --git a/ruoyi-plus-api/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-plus-api/src/main/resources/mapper/system/SysUserMapper.xml new file mode 100644 index 0000000..6843024 --- /dev/null +++ b/ruoyi-plus-api/src/main/resources/mapper/system/SysUserMapper.xml @@ -0,0 +1,18 @@ + + + + + + + id, name, account, pwd, remark, create_time, update_time + + + + + + + diff --git a/ruoyi-plus-api/src/main/resources/static/welcome.html b/ruoyi-plus-api/src/main/resources/static/welcome.html new file mode 100644 index 0000000..3a547f2 --- /dev/null +++ b/ruoyi-plus-api/src/main/resources/static/welcome.html @@ -0,0 +1,19 @@ + + + + + Welcome to spring-boot-plus + + +

Welcome to spring-boot-plus

+

+ GITHUB +

+

+ GITEE +

+

+ springboot.plus +

+ + \ No newline at end of file diff --git a/ruoyi-plus-api/src/main/resources/templates/springbootplus.html b/ruoyi-plus-api/src/main/resources/templates/springbootplus.html new file mode 100644 index 0000000..d0f97a1 --- /dev/null +++ b/ruoyi-plus-api/src/main/resources/templates/springbootplus.html @@ -0,0 +1,12 @@ + + + + + spring-boot-plus + + +

+ spring-boot-plus +

+ + \ No newline at end of file diff --git a/ruoyi-plus-api/src/test/java/com/ruoyi/plus/test/BaseTest.java b/ruoyi-plus-api/src/test/java/com/ruoyi/plus/test/BaseTest.java new file mode 100644 index 0000000..53e0b56 --- /dev/null +++ b/ruoyi-plus-api/src/test/java/com/ruoyi/plus/test/BaseTest.java @@ -0,0 +1,12 @@ + +package com.ruoyi.plus.test; + +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class BaseTest { + +} diff --git a/ruoyi-plus-api/src/test/java/com/ruoyi/plus/test/CodeGenerator.java b/ruoyi-plus-api/src/test/java/com/ruoyi/plus/test/CodeGenerator.java new file mode 100644 index 0000000..ecff97b --- /dev/null +++ b/ruoyi-plus-api/src/test/java/com/ruoyi/plus/test/CodeGenerator.java @@ -0,0 +1,212 @@ +/** + * Copyright 2019-2029 geekidea(https://github.com/geekidea) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ruoyi.plus.test; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.core.toolkit.StringPool; +import com.baomidou.mybatisplus.generator.AutoGenerator; +import com.baomidou.mybatisplus.generator.InjectionConfig; +import com.baomidou.mybatisplus.generator.config.*; +import com.baomidou.mybatisplus.generator.config.po.TableInfo; +import com.baomidou.mybatisplus.generator.config.rules.DateType; +import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * spring-boot-plus代码生成器入口类 + * @author geekidea + * @date 2018-11-08 + */ +public class CodeGenerator { + + private static final String USER_NAME = "root"; + private static final String PASSWORD = "root"; + private static final String DRIVER_NAME = "com.mysql.jdbc.Driver"; + private static final String DRIVER_URL = "jdbc:mysql://localhost:3306/spring_boot_plus?useUnicode=true&characterEncoding=UTF-8&useSSL=false"; + + private static final String PARENT_PACKAGE = "io.geekidea.springbootplus"; + private static final String SUPER_ENTITY = PARENT_PACKAGE + ".common.entity.BaseEntity"; + private static final String[] SUPER_ENTITY_COMMON_COLUMNS = new String[]{}; + private static final String SUPER_CONTROLLER = PARENT_PACKAGE + ".common.web.controller.BaseController"; + private static final String SUPER_SERVICE = PARENT_PACKAGE + ".common.service.BaseService"; + private static final String SUPER_SERVICE_IMPL = PARENT_PACKAGE + ".common.service.impl.BaseServiceImpl"; + + private static final String PROJECT_PACKAGE_PATH = "io/geekidea/springbootplus"; + + + // ############################ 配置部分 start ############################ + // 模块名称 + private static final String MODULE_NAME = "system"; + // 作者 + private static final String AUTHOR = "geekidea"; + // 生成的表名称 + private static final String TABLE_NAME = "sys_user"; + // 主键数据库列名称 + private static final String PK_ID_COLUMN_NAME = "id"; + // 代码生成策略 true:All/false:SIMPLE + private static final boolean GENERATOR_STRATEGY = true; + // 分页列表查询是否排序 true:有排序参数/false:无 + private static final boolean PAGE_LIST_ORDER = false; + // ############################ 配置部分 end ############################ + + + public static void main(String[] args) { + // 代码生成器 + AutoGenerator mpg = new AutoGenerator(); + + // 全局配置 + GlobalConfig gc = new GlobalConfig(); + String projectPath = System.getProperty("user.dir"); + gc.setOutputDir(projectPath + "/src/main/java"); + gc.setAuthor(AUTHOR); + gc.setOpen(false); // 是否打开输出目录 + gc.setSwagger2(true); // 启用swagger注解 + gc.setIdType(IdType.ID_WORKER); // 主键类型:ID_WORKER + gc.setServiceName("%sService"); // 自定义文件命名,注意 %s 会自动填充表实体属性! + gc.setFileOverride(true); // 是否覆盖已有文件 + gc.setDateType(DateType.ONLY_DATE); // 设置日期类型为Date + + mpg.setGlobalConfig(gc); + + // 数据源配置 + DataSourceConfig dsc = new DataSourceConfig(); + dsc.setUrl(DRIVER_URL); + // dsc.setSchemaName("public"); + dsc.setDriverName(DRIVER_NAME); + dsc.setUsername(USER_NAME); + dsc.setPassword(PASSWORD); + mpg.setDataSource(dsc); + + // 包配置 + PackageConfig pc = new PackageConfig(); + pc.setModuleName(MODULE_NAME); + pc.setParent(PARENT_PACKAGE); + pc.setController("web.controller"); + + mpg.setPackageInfo(pc); + + // 自定义配置 + InjectionConfig cfg = new InjectionConfig() { + @Override + public void initMap() { + Map map = new HashMap(); + map.put("customField", "Hello " + this.getConfig().getGlobalConfig().getAuthor()); + // 查询参数包路径 + map.put("queryParamPath",PARENT_PACKAGE + StringPool.DOT + pc.getModuleName() + ".web.param." + underlineToPascal(TABLE_NAME) + "QueryParam"); + // 查询参数共公包路径 + map.put("queryParamCommonPath",PARENT_PACKAGE + StringPool.DOT + "common.web.param." + "QueryParam"); + // 查询参数共公包路径 + map.put("idParamPath",PARENT_PACKAGE + StringPool.DOT + "common.web.param." + "IdParam"); + // 响应结果包路径 + map.put("queryVoPath",PARENT_PACKAGE + StringPool.DOT + pc.getModuleName() + ".web.vo." + underlineToPascal(TABLE_NAME) + "QueryVo"); + // 实体对象名称 + map.put("entityObjectName",underlineToCamel(TABLE_NAME)); + // service对象名称 + map.put("serviceObjectName",underlineToCamel(TABLE_NAME) + "Service"); + // mapper对象名称 + map.put("mapperObjectName",underlineToCamel(TABLE_NAME) + "Mapper"); + // 主键ID列名 + map.put("pkIdColumnName",PK_ID_COLUMN_NAME); + // 主键ID驼峰名称 + map.put("pkIdCamelName",underlineToCamel(PK_ID_COLUMN_NAME)); + // 导入分页类 + map.put("paging",PARENT_PACKAGE + ".common.web.vo.Paging"); + // 导入排序枚举 + map.put("orderEnum",PARENT_PACKAGE + ".common.enums.OrderEnum"); + // 分页列表查询是否排序 + map.put("pageListOrder",PAGE_LIST_ORDER); + // 导入排序查询参数类 + map.put("orderQueryParamPath",PARENT_PACKAGE + StringPool.DOT + "common.web.param." + "OrderQueryParam"); + // 代码生成策略 + map.put("generatorStrategy",GENERATOR_STRATEGY); + this.setMap(map); + } + }; + List focList = new ArrayList<>(); + focList.add(new FileOutConfig("/templates/mapper.xml.vm") { + @Override + public String outputFile(TableInfo tableInfo) { + // 自定义输入文件名称 + return projectPath + "/src/main/resources/mapper/" + pc.getModuleName() + + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; + } + }); + + // 自定义queryParam模板 + focList.add(new FileOutConfig("/templates/queryParam.java.vm") { + @Override + public String outputFile(TableInfo tableInfo) { + return projectPath + "/src/main/java/"+ PROJECT_PACKAGE_PATH +"/" + pc.getModuleName() + "/web/param/" + tableInfo.getEntityName() + "QueryParam" + StringPool.DOT_JAVA; + } + }); + + // 自定义queryVo模板 + focList.add(new FileOutConfig("/templates/queryVo.java.vm") { + @Override + public String outputFile(TableInfo tableInfo) { + return projectPath + "/src/main/java/"+ PROJECT_PACKAGE_PATH +"/" + pc.getModuleName() + "/web/vo/" + tableInfo.getEntityName() + "QueryVo" + StringPool.DOT_JAVA; + } + }); + + + cfg.setFileOutConfigList(focList); + mpg.setCfg(cfg); + mpg.setTemplate(new TemplateConfig().setXml(null)); + + // 策略配置 + StrategyConfig strategy = new StrategyConfig(); + strategy.setNaming(NamingStrategy.underline_to_camel); + strategy.setColumnNaming(NamingStrategy.underline_to_camel); + strategy.setSuperEntityClass(SUPER_ENTITY); + strategy.setEntityLombokModel(true); + strategy.setRestControllerStyle(true); + strategy.setSuperControllerClass(SUPER_CONTROLLER); + strategy.setSuperServiceClass(SUPER_SERVICE); + strategy.setSuperServiceImplClass(SUPER_SERVICE_IMPL); + strategy.setInclude(TABLE_NAME); + strategy.setSuperEntityColumns(SUPER_ENTITY_COMMON_COLUMNS); + strategy.setControllerMappingHyphenStyle(true); + /** + * 注意,根据实际情况,进行设置 + * 当表名称的前缀和模块名称一样时,会去掉表的前缀 + * 比如模块名称为user,表明为user_info,则生成的实体名称是Info.java,一定要注意 + */ + //strategy.setTablePrefix(pc.getModuleName() + "_"); + mpg.setStrategy(strategy); + mpg.execute(); + } + + public static String underlineToCamel(String underline){ + if (StringUtils.isNotBlank(underline)){ + return NamingStrategy.underlineToCamel(underline); + } + return null; + } + + public static String underlineToPascal(String underline){ + if (StringUtils.isNotBlank(underline)){ + return NamingStrategy.capitalFirst(NamingStrategy.underlineToCamel(underline)); + } + return null; + } + +} diff --git a/ruoyi-plus-api/src/test/java/com/ruoyi/plus/test/IpTest.java b/ruoyi-plus-api/src/test/java/com/ruoyi/plus/test/IpTest.java new file mode 100644 index 0000000..d4a9269 --- /dev/null +++ b/ruoyi-plus-api/src/test/java/com/ruoyi/plus/test/IpTest.java @@ -0,0 +1,8 @@ +package com.ruoyi.plus.test; + +/** + * @author geekidea + * @date 2019/8/4 + */ +public class IpTest { +} diff --git a/ruoyi-plus-api/src/test/resources/templates/controller.java.vm b/ruoyi-plus-api/src/test/resources/templates/controller.java.vm new file mode 100644 index 0000000..4f81d86 --- /dev/null +++ b/ruoyi-plus-api/src/test/resources/templates/controller.java.vm @@ -0,0 +1,114 @@ +package ${package.Controller}; + +import ${package.Entity}.${entity}; +import ${package.Service}.${table.serviceName}; +import ${cfg.queryParamPath}; +import ${cfg.queryVoPath}; +#if(${superControllerClassPackage}) +import ${superControllerClassPackage}; +#end +import io.geekidea.springbootplus.common.api.ApiResult; + #if(${swagger2}) +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +#end +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +#if(${restControllerStyle}) +import org.springframework.web.bind.annotation.RestController; +#else +import org.springframework.stereotype.Controller; +#end + +import javax.validation.Valid; + +import ${cfg.paging}; +import ${cfg.idParamPath}; + +/** + *

+ * $!{table.comment} 前端控制器 + *

+ * + * @author ${author} + * @since ${date} + */ +@Slf4j +#if(${restControllerStyle}) +@RestController +#else +@Controller +#end +@RequestMapping("/${cfg.entityObjectName}") +@Api("$!{table.comment} API") +#if(${kotlin}) +class ${table.controllerName}#if(${superControllerClass}) : ${superControllerClass}()#end + +#else +#if(${superControllerClass}) +public class ${table.controllerName} extends ${superControllerClass} { +#else +public class ${table.controllerName} { +#end + + @Autowired + private ${table.serviceName} ${cfg.serviceObjectName}; + +#if(${cfg.generatorStrategy}) + /** + * 添加$!{table.comment} + */ + @PostMapping("/add") + @ApiOperation(value = "添加${entity}对象",notes = "添加$!{table.comment}",response = ApiResult.class) + public ApiResult add${entity}(@Valid @RequestBody ${entity} ${cfg.entityObjectName}) throws Exception{ + boolean flag = ${cfg.serviceObjectName}.save(${cfg.entityObjectName}); + return ApiResult.result(flag); + } + + /** + * 修改$!{table.comment} + */ + @PostMapping("/update") + @ApiOperation(value = "修改${entity}对象",notes = "修改$!{table.comment}",response = ApiResult.class) + public ApiResult update${entity}(@Valid @RequestBody ${entity} ${cfg.entityObjectName}) throws Exception{ + boolean flag = ${cfg.serviceObjectName}.updateById(${cfg.entityObjectName}); + return ApiResult.result(flag); + } + + /** + * 删除$!{table.comment} + */ + @PostMapping("/delete") + @ApiOperation(value = "删除${entity}对象",notes = "删除$!{table.comment}",response = ApiResult.class) + public ApiResult delete${entity}(@Valid @RequestBody IdParam idParam) throws Exception{ + boolean flag = ${cfg.serviceObjectName}.removeById(idParam.getId()); + return ApiResult.result(flag); + } + + /** + * 获取$!{table.comment} + */ + @PostMapping("/info") + @ApiOperation(value = "获取${entity}对象详情",notes = "查看$!{table.comment}",response = ${entity}QueryVo.class) + public ApiResult<${entity}QueryVo> get${entity}(@Valid @RequestBody IdParam idParam) throws Exception{ + ${entity}QueryVo ${cfg.entityObjectName}QueryVo = ${cfg.serviceObjectName}.get${entity}ById(idParam.getId()); + return ApiResult.ok(${cfg.entityObjectName}QueryVo); + } + + /** + * $!{table.comment}分页列表 + */ + @PostMapping("/getPageList") + @ApiOperation(value = "获取${entity}分页列表",notes = "$!{table.comment}分页列表",response = ${entity}QueryVo.class) + public ApiResult> get${entity}PageList(@Valid @RequestBody(required = false) ${entity}QueryParam ${cfg.entityObjectName}QueryParam) throws Exception{ + Paging<${entity}QueryVo> paging = ${cfg.entityObjectName}Service.get${entity}PageList(${cfg.entityObjectName}QueryParam); + return ApiResult.ok(paging); + } +#end + +} + +#end \ No newline at end of file diff --git a/ruoyi-plus-api/src/test/resources/templates/entity.java.vm b/ruoyi-plus-api/src/test/resources/templates/entity.java.vm new file mode 100644 index 0000000..61c3326 --- /dev/null +++ b/ruoyi-plus-api/src/test/resources/templates/entity.java.vm @@ -0,0 +1,161 @@ +package ${package.Entity}; + +#foreach($pkg in ${table.importPackages}) +import ${pkg}; +#end +#if(${swagger2}) +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +#end +#if(${entityLombokModel}) +import lombok.Data; +import lombok.EqualsAndHashCode; +## import lombok.experimental.Accessors; +#end + +import java.util.Date; + +/** + *

+ * $!{table.comment} + *

+ * + * @author ${author} + * @since ${date} + */ +#if(${entityLombokModel}) +@Data +#if(${superEntityClass}) +@EqualsAndHashCode(callSuper = true) +#else +@EqualsAndHashCode(callSuper = false) +#end +## @Accessors(chain = true) +#end +#if(${table.convert}) +@TableName("${table.name}") +#end +#if(${swagger2}) +@ApiModel(value="${entity}对象", description="$!{table.comment}") +#end +#if(${superEntityClass}) +public class ${entity} extends ${superEntityClass}#if(${activeRecord})<${entity}>#end { +#elseif(${activeRecord}) +public class ${entity} extends Model<${entity}> { +#else +public class ${entity} implements Serializable { +#end + + private static final long serialVersionUID = 1L; +## ---------- BEGIN 字段循环遍历 ---------- +#foreach($field in ${table.fields}) +## 自定义属性,是否是主键 +#set($custom_is_pk=false) + +#if(${field.keyFlag}) +#set($keyPropertyName=${field.propertyName}) +#end +#if("$!field.comment" != "") + #if(${swagger2}) +@ApiModelProperty(value = "${field.comment}") + #else +/** + * ${field.comment} + */ + #end +#end +#if(${field.keyFlag}) +## 主键 +#if(${field.keyIdentityFlag}) +@TableId(value = "${field.name}", type = IdType.AUTO) +#elseif(!$null.isNull(${idType}) && "$!idType" != "") +## 设置主键注解 +@TableId(value = "${field.name}", type = IdType.${idType}) +## 是主键类型 +#set($custom_is_pk=true) +#elseif(${field.convert}) +@TableId("${field.name}") +#end +## 普通字段 +#elseif(${field.fill}) +## ----- 存在字段填充设置 ----- +#if(${field.convert}) + @TableField(value = "${field.name}", fill = FieldFill.${field.fill}) +#else + @TableField(fill = FieldFill.${field.fill}) +#end +#elseif(${field.convert}) + @TableField("${field.name}") +#end +## 乐观锁注解 +#if(${versionFieldName}==${field.name}) + @Version +#end +## 逻辑删除注解 +#if(${logicDeleteFieldName}==${field.name}) + @TableLogic +#end +#if(${custom_is_pk}) + private ${field.propertyType} ${field.propertyName}; +#else +private ${field.propertyType} ${field.propertyName}; +#end +#end +## ---------- END 字段循环遍历 ---------- +#if(!${entityLombokModel}) +#foreach($field in ${table.fields}) +#if(${field.propertyType.equals("boolean")}) +#set($getprefix="is") +#else +#set($getprefix="get") +#end + + public ${field.propertyType} ${getprefix}${field.capitalName}() { + return ${field.propertyName}; + } + +#if(${entityBuilderModel}) + public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) { +#else + public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) { +#end + this.${field.propertyName} = ${field.propertyName}; +#if(${entityBuilderModel}) + return this; +#end + } +#end +#end + +#if(${entityColumnConstant}) +#foreach($field in ${table.fields}) + public static final String ${field.name.toUpperCase()} = "${field.name}"; + +#end +#end +#if(${activeRecord}) + @Override + protected Serializable pkVal() { +#if(${keyPropertyName}) + return this.${keyPropertyName}; +#else + return null; +#end + } + +#end +#if(!${entityLombokModel}) + @Override + public String toString() { + return "${entity}{" + +#foreach($field in ${table.fields}) +#if($!{foreach.index}==0) + "${field.propertyName}=" + ${field.propertyName} + +#else + ", ${field.propertyName}=" + ${field.propertyName} + +#end +#end + "}"; + } +#end +} diff --git a/ruoyi-plus-api/src/test/resources/templates/mapper.java.vm b/ruoyi-plus-api/src/test/resources/templates/mapper.java.vm new file mode 100644 index 0000000..207c1cb --- /dev/null +++ b/ruoyi-plus-api/src/test/resources/templates/mapper.java.vm @@ -0,0 +1,46 @@ +package ${package.Mapper}; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import ${superMapperClassPackage}; +import ${package.Entity}.${entity}; +import ${cfg.queryParamPath}; +import ${cfg.queryVoPath}; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.io.Serializable; + +/** + *

+ * $!{table.comment} Mapper 接口 + *

+ * + * @author ${author} + * @since ${date} + */ +#if(${kotlin}) +interface ${table.mapperName} : ${superMapperClass}<${entity}> +#else +@Repository +public interface ${table.mapperName} extends ${superMapperClass}<${entity}> { +#if(${cfg.generatorStrategy}) + + /** + * 根据ID获取查询对象 + * @param id + * @return + */ + ${entity}QueryVo get${entity}ById(Serializable id); + + /** + * 获取分页对象 + * @param page + * @param ${cfg.entityObjectName}QueryParam + * @return + */ + IPage<${entity}QueryVo> get${entity}PageList(@Param("page") Page page, @Param("param") ${entity}QueryParam ${cfg.entityObjectName}QueryParam); +#end + +} +#end diff --git a/ruoyi-plus-api/src/test/resources/templates/mapper.xml.vm b/ruoyi-plus-api/src/test/resources/templates/mapper.xml.vm new file mode 100644 index 0000000..b3829d3 --- /dev/null +++ b/ruoyi-plus-api/src/test/resources/templates/mapper.xml.vm @@ -0,0 +1,47 @@ + + + + +#if(${enableCache}) + + + +#end +#if(${baseResultMap}) + + +#foreach($field in ${table.fields}) +#if(${field.keyFlag})##生成主键排在第一位 + +#end +#end +#foreach($field in ${table.commonFields})##生成公共字段 + +#end +#foreach($field in ${table.fields}) +#if(!${field.keyFlag})##生成普通字段 + +#end +#end + + +#end + + +#foreach($field in ${table.commonFields}) + ${field.name}, +#end + ${table.fieldNames} + +#if(${cfg.generatorStrategy}) + + + + + +#end + diff --git a/ruoyi-plus-api/src/test/resources/templates/queryParam.java.vm b/ruoyi-plus-api/src/test/resources/templates/queryParam.java.vm new file mode 100644 index 0000000..15357e7 --- /dev/null +++ b/ruoyi-plus-api/src/test/resources/templates/queryParam.java.vm @@ -0,0 +1,30 @@ +package io.geekidea.springbootplus.${package.ModuleName}.web.param; + +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +#if(${cfg.pageListOrder}) +import ${cfg.orderQueryParamPath}; +#else +import ${cfg.queryParamCommonPath}; +#end + +/** + *

+ * $!{table.comment} 查询参数对象 + *

+ * + * @author ${author} + * @date ${date} + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ApiModel(value="${entity}QueryParam对象", description="$!{table.comment}查询参数") +#if(${cfg.pageListOrder}) +public class ${entity}QueryParam extends OrderQueryParam { +#else +public class ${entity}QueryParam extends QueryParam { +#end + private static final long serialVersionUID = 1L; +} diff --git a/ruoyi-plus-api/src/test/resources/templates/queryVo.java.vm b/ruoyi-plus-api/src/test/resources/templates/queryVo.java.vm new file mode 100644 index 0000000..4ccd4ce --- /dev/null +++ b/ruoyi-plus-api/src/test/resources/templates/queryVo.java.vm @@ -0,0 +1,124 @@ +package io.geekidea.springbootplus.${package.ModuleName}.web.vo; + +#if(${swagger2}) +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +#end +#if(${entityLombokModel}) +import lombok.Data; +#end +import java.io.Serializable; + +import java.util.Date; + +/** + *

+ * $!{table.comment} 查询结果对象 + *

+ * + * @author ${author} + * @date ${date} + */ +#if(${entityLombokModel}) +@Data +#end +#if(${table.convert}) +@TableName("${table.name}") +#end +@ApiModel(value="${entity}QueryVo对象", description="$!{table.comment}查询参数") +public class ${entity}QueryVo implements Serializable{ + private static final long serialVersionUID = 1L; +## ---------- BEGIN 字段循环遍历 ---------- +#foreach($field in ${table.fields}) + +#if(${field.keyFlag}) +#set($keyPropertyName=${field.propertyName}) +#end +#if("$!field.comment" != "") + #if(${swagger2}) +@ApiModelProperty(value = "${field.comment}") + #else +/** + * ${field.comment} + */ + #end +#end +#if(${field.keyFlag}) +## 普通字段 +#elseif(${field.fill}) +## ----- 存在字段填充设置 ----- +#if(${field.convert}) + @TableField(value = "${field.name}", fill = FieldFill.${field.fill}) +#else + @TableField(fill = FieldFill.${field.fill}) +#end +#elseif(${field.convert}) + @TableField("${field.name}") +#end +## 乐观锁注解 +#if(${versionFieldName}==${field.name}) + @Version +#end +## 逻辑删除注解 +#if(${logicDeleteFieldName}==${field.name}) + @TableLogic +#end +private ${field.propertyType} ${field.propertyName}; +#end +## ---------- END 字段循环遍历 ---------- +#if(!${entityLombokModel}) +#foreach($field in ${table.fields}) +#if(${field.propertyType.equals("boolean")}) +#set($getprefix="is") +#else +#set($getprefix="get") +#end + + public ${field.propertyType} ${getprefix}${field.capitalName}() { + return ${field.propertyName}; + } + +#if(${entityBuilderModel}) + public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) { +#else + public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) { +#end + this.${field.propertyName} = ${field.propertyName}; +#if(${entityBuilderModel}) + return this; +#end + } +#end +#end + +#if(${entityColumnConstant}) +#foreach($field in ${table.fields}) + public static final String ${field.name.toUpperCase()} = "${field.name}"; + +#end +#end +#if(${activeRecord}) + @Override + protected Serializable pkVal() { +#if(${keyPropertyName}) + return this.${keyPropertyName}; +#else + return null; +#end + } +#end +#if(!${entityLombokModel}) + @Override + public String toString() { + return "${entity}{" + +#foreach($field in ${table.fields}) +#if($!{foreach.index}==0) + "${field.propertyName}=" + ${field.propertyName} + +#else + ", ${field.propertyName}=" + ${field.propertyName} + +#end +#end + "}"; + } +#end +} \ No newline at end of file diff --git a/ruoyi-plus-api/src/test/resources/templates/service.java.vm b/ruoyi-plus-api/src/test/resources/templates/service.java.vm new file mode 100644 index 0000000..9009d5c --- /dev/null +++ b/ruoyi-plus-api/src/test/resources/templates/service.java.vm @@ -0,0 +1,41 @@ +package ${package.Service}; + +import ${package.Entity}.${entity}; +import ${superServiceClassPackage}; +import ${cfg.queryParamPath}; +import ${cfg.queryVoPath}; +import ${cfg.paging}; + +import java.io.Serializable; + +/** + *

+ * $!{table.comment} 服务类 + *

+ * + * @author ${author} + * @since ${date} + */ +#if(${kotlin}) +interface ${table.serviceName} : ${superServiceClass}<${entity}> +#else +public interface ${table.serviceName} extends ${superServiceClass}<${entity}> { +#if(${cfg.generatorStrategy}) + + /** + * 根据ID获取查询对象 + * @param id + * @return + */ + ${entity}QueryVo get${entity}ById(Serializable id) throws Exception; + + /** + * 获取分页对象 + * @param ${cfg.entityObjectName}QueryParam + * @return + */ + Paging<${entity}QueryVo> get${entity}PageList(${entity}QueryParam ${cfg.entityObjectName}QueryParam) throws Exception; +#end + +} +#end diff --git a/ruoyi-plus-api/src/test/resources/templates/serviceImpl.java.vm b/ruoyi-plus-api/src/test/resources/templates/serviceImpl.java.vm new file mode 100644 index 0000000..648f327 --- /dev/null +++ b/ruoyi-plus-api/src/test/resources/templates/serviceImpl.java.vm @@ -0,0 +1,57 @@ +package ${package.ServiceImpl}; + +import ${package.Entity}.${entity}; +import ${package.Mapper}.${table.mapperName}; +import ${package.Service}.${table.serviceName}; +import ${cfg.queryParamPath}; +import ${cfg.queryVoPath}; +import ${superServiceImplClassPackage}; +import ${cfg.paging}; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.beans.factory.annotation.Autowired; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.metadata.OrderItem; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import java.io.Serializable; + + +/** + *

+ * $!{table.comment} 服务实现类 + *

+ * + * @author ${author} + * @since ${date} + */ +@Slf4j +@Service +@Transactional(rollbackFor = Exception.class) +#if(${kotlin}) +open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} { + +} +#else +public class ${table.serviceImplName} extends BaseServiceImpl<${table.mapperName}, ${entity}> implements ${table.serviceName} { + + @Autowired + private ${table.mapperName} ${cfg.mapperObjectName}; +#if(${cfg.generatorStrategy}) + + @Override + public ${entity}QueryVo get${entity}ById(Serializable id) throws Exception{ + return ${cfg.mapperObjectName}.get${entity}ById(id); + } + + @Override + public Paging<${entity}QueryVo> get${entity}PageList(${entity}QueryParam ${cfg.entityObjectName}QueryParam) throws Exception{ + Page page = setPageParam(${cfg.entityObjectName}QueryParam,OrderItem.desc("create_time")); + IPage<${entity}QueryVo> iPage = ${cfg.mapperObjectName}.get${entity}PageList(page,${cfg.entityObjectName}QueryParam); + return new Paging(iPage); + } +#end + +} +#end