mirror of
https://github.com/continew-org/continew-admin.git
synced 2025-09-11 06:57:12 +08:00
chore: continew-starter 2.4.0 => 2.5.0
1.continew-starter-log-httptrace-pro => continew-starter-log-interceptor 2.移除 WebMvcConfiguration 配置(已迁移到 Starter 项目) 3.Starter 全局响应(新)适配,自定义异常拦截调整到 Admin 项目 4.部分 API 调整
This commit is contained in:
@@ -13,7 +13,7 @@
|
|||||||
<img src="https://sonarcloud.io/api/project_badges/measure?project=Charles7c_continew-admin&metric=alert_status" alt="Sonar Status" />
|
<img src="https://sonarcloud.io/api/project_badges/measure?project=Charles7c_continew-admin&metric=alert_status" alt="Sonar Status" />
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/continew-org/continew-starter" target="_blank">
|
<a href="https://github.com/continew-org/continew-starter" target="_blank">
|
||||||
<img src="https://img.shields.io/badge/ContiNew Starter-2.4.0-%236CB52D.svg" alt="ContiNew Starter" />
|
<img src="https://img.shields.io/badge/ContiNew Starter-2.5.0-%236CB52D.svg" alt="ContiNew Starter" />
|
||||||
</a>
|
</a>
|
||||||
<a href="https://spring.io/projects/spring-boot" target="_blank">
|
<a href="https://spring.io/projects/spring-boot" target="_blank">
|
||||||
<img src="https://img.shields.io/badge/Spring Boot-3.2.7-%236CB52D.svg?logo=Spring-Boot" alt="Spring Boot" />
|
<img src="https://img.shields.io/badge/Spring Boot-3.2.7-%236CB52D.svg?logo=Spring-Boot" alt="Spring Boot" />
|
||||||
@@ -210,13 +210,13 @@ public class DeptController extends BaseController<DeptService, DeptResp, DeptDe
|
|||||||
|
|
||||||
## 核心技术栈
|
## 核心技术栈
|
||||||
|
|
||||||
| 名称 | 版本 | 简介 |
|
| 名称 | 版本 | 简介 |
|
||||||
| :----------------------------------------------------------- | :----------- | :----------------------------------------------------------- |
|
| :----------------------------------------------------------- |:-------------| :----------------------------------------------------------- |
|
||||||
| <a href="https://cn.vuejs.org/" target="_blank">Vue</a> | 3.4.21 | 渐进式 JavaScript 框架,易学易用,性能出色,适用场景丰富的 Web 前端框架。 |
|
| <a href="https://cn.vuejs.org/" target="_blank">Vue</a> | 3.4.21 | 渐进式 JavaScript 框架,易学易用,性能出色,适用场景丰富的 Web 前端框架。 |
|
||||||
| <a href="https://arco.design/vue/docs/start" target="_blank">Arco Design</a> | 2.55.0 | 字节跳动推出的前端 UI 框架,年轻化的色彩和组件设计。 |
|
| <a href="https://arco.design/vue/docs/start" target="_blank">Arco Design</a> | 2.55.0 | 字节跳动推出的前端 UI 框架,年轻化的色彩和组件设计。 |
|
||||||
| <a href="https://www.typescriptlang.org/zh/" target="_blank">TypeScript</a> | 5.0.4 | TypeScript 是微软开发的一个开源的编程语言,通过在 JavaScript 的基础上添加静态类型定义构建而成。 |
|
| <a href="https://www.typescriptlang.org/zh/" target="_blank">TypeScript</a> | 5.0.4 | TypeScript 是微软开发的一个开源的编程语言,通过在 JavaScript 的基础上添加静态类型定义构建而成。 |
|
||||||
| <a href="https://cn.vitejs.dev/" target="_blank">Vite</a> | 5.1.5 | 下一代的前端工具链,为开发提供极速响应。 |
|
| <a href="https://cn.vitejs.dev/" target="_blank">Vite</a> | 5.1.5 | 下一代的前端工具链,为开发提供极速响应。 |
|
||||||
| [ContiNew Starter](https://github.com/continew-org/continew-starter) | 2.4.0 | ContiNew Starter 包含了一系列经过企业实践优化的依赖包(如 MyBatis-Plus、SaToken),可轻松集成到应用中,为开发人员减少手动引入依赖及配置的麻烦,为 Spring Boot Web 项目的灵活快速构建提供支持。 |
|
| [ContiNew Starter](https://github.com/continew-org/continew-starter) | 2.5.0 | ContiNew Starter 包含了一系列经过企业实践优化的依赖包(如 MyBatis-Plus、SaToken),可轻松集成到应用中,为开发人员减少手动引入依赖及配置的麻烦,为 Spring Boot Web 项目的灵活快速构建提供支持。 |
|
||||||
| <a href="https://spring.io/projects/spring-boot" target="_blank">Spring Boot</a> | 3.2.7 | 简化 Spring 应用的初始搭建和开发过程,基于“约定优于配置”的理念,使开发人员不再需要定义样板化的配置。(Spring Boot 3.0 开始,要求 Java 17 作为最低版本) |
|
| <a href="https://spring.io/projects/spring-boot" target="_blank">Spring Boot</a> | 3.2.7 | 简化 Spring 应用的初始搭建和开发过程,基于“约定优于配置”的理念,使开发人员不再需要定义样板化的配置。(Spring Boot 3.0 开始,要求 Java 17 作为最低版本) |
|
||||||
| <a href="https://undertow.io/" target="_blank">Undertow</a> | 2.3.13.Final | 采用 Java 开发的灵活的高性能 Web 服务器,提供包括阻塞和基于 NIO 的非堵塞机制。 |
|
| <a href="https://undertow.io/" target="_blank">Undertow</a> | 2.3.13.Final | 采用 Java 开发的灵活的高性能 Web 服务器,提供包括阻塞和基于 NIO 的非堵塞机制。 |
|
||||||
| <a href="https://sa-token.dev33.cn/" target="_blank">Sa-Token + JWT</a> | 1.38.0 | 轻量级 Java 权限认证框架,让鉴权变得简单、优雅。 |
|
| <a href="https://sa-token.dev33.cn/" target="_blank">Sa-Token + JWT</a> | 1.38.0 | 轻量级 Java 权限认证框架,让鉴权变得简单、优雅。 |
|
||||||
|
@@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* 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 top.continew.admin.common.config;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
|
||||||
import org.springframework.http.converter.HttpMessageConverter;
|
|
||||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
|
||||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Web MVC 配置
|
|
||||||
*
|
|
||||||
* @author Charles7c
|
|
||||||
* @since 2022/12/11 19:40
|
|
||||||
*/
|
|
||||||
@EnableWebMvc
|
|
||||||
@Configuration
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class WebMvcConfiguration implements WebMvcConfigurer {
|
|
||||||
|
|
||||||
private final MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 解决 Jackson2ObjectMapperBuilderCustomizer 配置不生效的问题
|
|
||||||
* <p>
|
|
||||||
* MappingJackson2HttpMessageConverter 对象在程序启动时创建了多个,移除多余的,保证只有一个
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
|
|
||||||
converters.removeIf(MappingJackson2HttpMessageConverter.class::isInstance);
|
|
||||||
if (Objects.isNull(mappingJackson2HttpMessageConverter)) {
|
|
||||||
converters.add(0, new MappingJackson2HttpMessageConverter());
|
|
||||||
} else {
|
|
||||||
converters.add(0, mappingJackson2HttpMessageConverter);
|
|
||||||
}
|
|
||||||
// 自定义 converters 时,需要手动在最前面添加 ByteArrayHttpMessageConverter
|
|
||||||
// 否则 Spring Doc OpenAPI 的 /*/api-docs/**(例如:/v3/api-docs/default)接口响应内容会变为 Base64 编码后的内容,最终导致接口文档解析失败
|
|
||||||
// 详情请参阅:https://github.com/springdoc/springdoc-openapi/issues/2143
|
|
||||||
converters.add(0, new ByteArrayHttpMessageConverter());
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* 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 top.continew.admin.common.config.exception;
|
||||||
|
|
||||||
|
import cn.hutool.core.text.CharSequenceUtil;
|
||||||
|
import cn.hutool.core.util.NumberUtil;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
import org.springframework.web.multipart.MultipartException;
|
||||||
|
import top.continew.starter.core.exception.BadRequestException;
|
||||||
|
import top.continew.starter.core.exception.BusinessException;
|
||||||
|
import top.continew.starter.web.model.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局异常处理器
|
||||||
|
*
|
||||||
|
* @author Charles7c
|
||||||
|
* @since 2024/8/7 20:21
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Order(99)
|
||||||
|
@RestControllerAdvice
|
||||||
|
public class GlobalExceptionHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拦截业务异常
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(BusinessException.class)
|
||||||
|
public R handleBusinessException(BusinessException e, HttpServletRequest request) {
|
||||||
|
log.error("请求地址 [{}],发生业务异常。", request.getRequestURI(), e);
|
||||||
|
return R.fail(String.valueOf(HttpStatus.INTERNAL_SERVER_ERROR.value()), e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拦截自定义验证异常-错误请求
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(BadRequestException.class)
|
||||||
|
public R handleBadRequestException(BadRequestException e, HttpServletRequest request) {
|
||||||
|
log.warn("请求地址 [{}],自定义验证失败。", request.getRequestURI(), e);
|
||||||
|
return R.fail(String.valueOf(HttpStatus.BAD_REQUEST.value()), e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拦截文件上传异常-超过上传大小限制
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(MultipartException.class)
|
||||||
|
public R handleRequestTooBigException(MultipartException e, HttpServletRequest request) {
|
||||||
|
String msg = e.getMessage();
|
||||||
|
R defaultFail = R.fail(String.valueOf(HttpStatus.BAD_REQUEST.value()), msg);
|
||||||
|
if (CharSequenceUtil.isBlank(msg)) {
|
||||||
|
return defaultFail;
|
||||||
|
}
|
||||||
|
String sizeLimit;
|
||||||
|
Throwable cause = e.getCause();
|
||||||
|
if (null != cause) {
|
||||||
|
msg = msg.concat(cause.getMessage().toLowerCase());
|
||||||
|
}
|
||||||
|
if (msg.contains("size") && msg.contains("exceed")) {
|
||||||
|
sizeLimit = CharSequenceUtil.subBetween(msg, "the maximum size ", " for");
|
||||||
|
} else if (msg.contains("larger than")) {
|
||||||
|
sizeLimit = CharSequenceUtil.subAfter(msg, "larger than ", true);
|
||||||
|
} else {
|
||||||
|
return defaultFail;
|
||||||
|
}
|
||||||
|
String errorMsg = "请上传小于 %sKB 的文件".formatted(NumberUtil.parseLong(sizeLimit) / 1024);
|
||||||
|
log.warn("请求地址 [{}],上传文件失败,文件大小超过限制。", request.getRequestURI(), e);
|
||||||
|
return R.fail(String.valueOf(HttpStatus.BAD_REQUEST.value()), errorMsg);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* 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 top.continew.admin.common.config.exception;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.exception.NotLoginException;
|
||||||
|
import cn.dev33.satoken.exception.NotPermissionException;
|
||||||
|
import cn.dev33.satoken.exception.NotRoleException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
import top.continew.starter.web.model.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局 SaToken 异常处理器
|
||||||
|
*
|
||||||
|
* @author Charles7c
|
||||||
|
* @since 2024/8/7 20:21
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Order(99)
|
||||||
|
@RestControllerAdvice
|
||||||
|
public class GlobalSaTokenExceptionHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 认证异常-登录认证
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(NotLoginException.class)
|
||||||
|
public R handleNotLoginException(NotLoginException e, HttpServletRequest request) {
|
||||||
|
log.error("请求地址 [{}],认证失败,无法访问系统资源。", request.getRequestURI(), e);
|
||||||
|
String errorMsg = switch (e.getType()) {
|
||||||
|
case NotLoginException.KICK_OUT -> "您已被踢下线。";
|
||||||
|
case NotLoginException.BE_REPLACED_MESSAGE -> "您已被顶下线。";
|
||||||
|
default -> "您的登录状态已过期,请重新登录。";
|
||||||
|
};
|
||||||
|
return R.fail(String.valueOf(HttpStatus.UNAUTHORIZED.value()), errorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 认证异常-权限认证
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(NotPermissionException.class)
|
||||||
|
public R handleNotPermissionException(NotPermissionException e, HttpServletRequest request) {
|
||||||
|
log.error("请求地址 [{}],权限码校验失败。", request.getRequestURI(), e);
|
||||||
|
return R.fail(String.valueOf(HttpStatus.FORBIDDEN.value()), "没有访问权限,请联系管理员授权");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 认证异常-角色认证
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(NotRoleException.class)
|
||||||
|
public R handleNotRoleException(NotRoleException e, HttpServletRequest request) {
|
||||||
|
log.error("请求地址 [{}],角色权限校验失败。", request.getRequestURI(), e);
|
||||||
|
return R.fail(String.valueOf(HttpStatus.FORBIDDEN.value()), "没有访问权限,请联系管理员授权");
|
||||||
|
}
|
||||||
|
}
|
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package top.continew.admin.generator.service;
|
package top.continew.admin.generator.service;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import top.continew.admin.generator.model.entity.FieldConfigDO;
|
import top.continew.admin.generator.model.entity.FieldConfigDO;
|
||||||
import top.continew.admin.generator.model.entity.GenConfigDO;
|
import top.continew.admin.generator.model.entity.GenConfigDO;
|
||||||
@@ -86,8 +85,7 @@ public interface GeneratorService {
|
|||||||
* 生成代码
|
* 生成代码
|
||||||
*
|
*
|
||||||
* @param tableNames 表明层
|
* @param tableNames 表明层
|
||||||
* @param request 请求对象
|
|
||||||
* @param response 响应对象
|
* @param response 响应对象
|
||||||
*/
|
*/
|
||||||
void generate(List<String> tableNames, HttpServletRequest request, HttpServletResponse response);
|
void generate(List<String> tableNames, HttpServletResponse response);
|
||||||
}
|
}
|
||||||
|
@@ -27,7 +27,6 @@ import cn.hutool.core.util.ZipUtil;
|
|||||||
import cn.hutool.db.meta.Column;
|
import cn.hutool.db.meta.Column;
|
||||||
import cn.hutool.system.SystemUtil;
|
import cn.hutool.system.SystemUtil;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -281,7 +280,7 @@ public class GeneratorServiceImpl implements GeneratorService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generate(List<String> tableNames, HttpServletRequest request, HttpServletResponse response) {
|
public void generate(List<String> tableNames, HttpServletResponse response) {
|
||||||
try {
|
try {
|
||||||
String tempDir = SystemUtil.getUserInfo().getTempDir();
|
String tempDir = SystemUtil.getUserInfo().getTempDir();
|
||||||
// 删除旧代码
|
// 删除旧代码
|
||||||
@@ -296,7 +295,7 @@ public class GeneratorServiceImpl implements GeneratorService {
|
|||||||
File tempDirFile = new File(tempDir, projectProperties.getAppName());
|
File tempDirFile = new File(tempDir, projectProperties.getAppName());
|
||||||
String zipFilePath = tempDirFile.getPath() + jodd.io.ZipUtil.ZIP_EXT;
|
String zipFilePath = tempDirFile.getPath() + jodd.io.ZipUtil.ZIP_EXT;
|
||||||
ZipUtil.zip(tempDirFile.getPath(), zipFilePath);
|
ZipUtil.zip(tempDirFile.getPath(), zipFilePath);
|
||||||
FileUploadUtils.download(request, response, new File(zipFilePath), true);
|
FileUploadUtils.download(response, new File(zipFilePath));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Generate code of table '{}' occurred an error. {}", tableNames, e.getMessage(), e);
|
log.error("Generate code of table '{}' occurred an error. {}", tableNames, e.getMessage(), e);
|
||||||
throw new BusinessException("代码生成失败,请手动清理生成文件");
|
throw new BusinessException("代码生成失败,请手动清理生成文件");
|
||||||
|
@@ -20,12 +20,14 @@ import cn.dev33.satoken.stp.StpUtil;
|
|||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.img.ImgUtil;
|
import cn.hutool.core.img.ImgUtil;
|
||||||
import cn.hutool.core.io.IoUtil;
|
|
||||||
import cn.hutool.core.io.file.FileNameUtil;
|
import cn.hutool.core.io.file.FileNameUtil;
|
||||||
import cn.hutool.core.io.resource.ResourceUtil;
|
import cn.hutool.core.io.resource.ResourceUtil;
|
||||||
import cn.hutool.core.lang.UUID;
|
import cn.hutool.core.lang.UUID;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.util.*;
|
import cn.hutool.core.util.CharsetUtil;
|
||||||
|
import cn.hutool.core.util.EnumUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.extra.validation.ValidationUtil;
|
import cn.hutool.extra.validation.ValidationUtil;
|
||||||
import cn.hutool.http.ContentType;
|
import cn.hutool.http.ContentType;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
@@ -77,6 +79,7 @@ import top.continew.starter.extension.crud.model.query.SortQuery;
|
|||||||
import top.continew.starter.extension.crud.model.resp.PageResp;
|
import top.continew.starter.extension.crud.model.resp.PageResp;
|
||||||
import top.continew.starter.extension.crud.service.CommonUserService;
|
import top.continew.starter.extension.crud.service.CommonUserService;
|
||||||
import top.continew.starter.extension.crud.service.impl.BaseServiceImpl;
|
import top.continew.starter.extension.crud.service.impl.BaseServiceImpl;
|
||||||
|
import top.continew.starter.web.util.FileUploadUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
@@ -129,13 +132,8 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserRes
|
|||||||
@Override
|
@Override
|
||||||
public void downloadImportUserTemplate(HttpServletResponse response) throws IOException {
|
public void downloadImportUserTemplate(HttpServletResponse response) throws IOException {
|
||||||
try {
|
try {
|
||||||
byte[] bytes = ResourceUtil.readBytes("templates/import/userImportTemplate.xlsx");
|
FileUploadUtils.download(response, ResourceUtil
|
||||||
response.setHeader("Content-Disposition", "attachment;filename=" + URLUtil.encode("用户导入模板.xlsx"));
|
.getStream("templates/import/userImportTemplate.xlsx"), "用户导入模板.xlsx");
|
||||||
response.addHeader("Content-Length", String.valueOf(bytes.length));
|
|
||||||
response.setHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
|
|
||||||
response.setContentType("application/octet-stream;charset=UTF-8");
|
|
||||||
IoUtil.write(response.getOutputStream(), true, bytes);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("下载用户导入模板失败:", e);
|
log.error("下载用户导入模板失败:", e);
|
||||||
response.setCharacterEncoding(CharsetUtil.UTF_8);
|
response.setCharacterEncoding(CharsetUtil.UTF_8);
|
||||||
|
@@ -25,10 +25,10 @@
|
|||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- ContiNew Starter 日志模块 - HttpTracePro(Spring Boot Actuator HttpTrace 定制增强版) -->
|
<!-- ContiNew Starter 日志模块 - 拦截器版(Spring Boot Actuator HttpTrace 增强版) -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>top.continew</groupId>
|
<groupId>top.continew</groupId>
|
||||||
<artifactId>continew-starter-log-httptrace-pro</artifactId>
|
<artifactId>continew-starter-log-interceptor</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 系统管理模块(存放系统管理模块相关功能,例如:部门管理、角色管理、用户管理等) -->
|
<!-- 系统管理模块(存放系统管理模块相关功能,例如:部门管理、角色管理、用户管理等) -->
|
||||||
|
@@ -35,7 +35,7 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import top.continew.starter.core.autoconfigure.project.ProjectProperties;
|
import top.continew.starter.core.autoconfigure.project.ProjectProperties;
|
||||||
import top.continew.starter.extension.crud.annotation.EnableCrudRestController;
|
import top.continew.starter.extension.crud.annotation.EnableCrudRestController;
|
||||||
import top.continew.starter.web.annotation.EnableGlobalExceptionHandler;
|
import top.continew.starter.web.annotation.EnableGlobalResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启动程序
|
* 启动程序
|
||||||
@@ -44,13 +44,13 @@ import top.continew.starter.web.annotation.EnableGlobalExceptionHandler;
|
|||||||
* @since 2022/12/8 23:15
|
* @since 2022/12/8 23:15
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
|
||||||
@EnableFileStorage
|
@EnableFileStorage
|
||||||
|
@EnableMethodCache(basePackages = "top.continew.admin")
|
||||||
|
@EnableGlobalResponse
|
||||||
|
@EnableCrudRestController
|
||||||
|
@RestController
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@EnableCrudRestController
|
|
||||||
@EnableGlobalExceptionHandler
|
|
||||||
@EnableMethodCache(basePackages = "top.continew.admin")
|
|
||||||
public class ContiNewAdminApplication implements ApplicationRunner {
|
public class ContiNewAdminApplication implements ApplicationRunner {
|
||||||
|
|
||||||
private final ProjectProperties projectProperties;
|
private final ProjectProperties projectProperties;
|
||||||
|
@@ -21,7 +21,7 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import top.continew.admin.system.mapper.LogMapper;
|
import top.continew.admin.system.mapper.LogMapper;
|
||||||
import top.continew.admin.system.service.UserService;
|
import top.continew.admin.system.service.UserService;
|
||||||
import top.continew.starter.log.core.dao.LogDao;
|
import top.continew.starter.log.core.dao.LogDao;
|
||||||
import top.continew.starter.log.httptracepro.autoconfigure.ConditionalOnEnabledLog;
|
import top.continew.starter.log.interceptor.autoconfigure.ConditionalOnEnabledLog;
|
||||||
import top.continew.starter.web.autoconfigure.trace.TraceProperties;
|
import top.continew.starter.web.autoconfigure.trace.TraceProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -43,7 +43,6 @@ import top.continew.admin.system.service.UserService;
|
|||||||
import top.continew.starter.cache.redisson.util.RedisUtils;
|
import top.continew.starter.cache.redisson.util.RedisUtils;
|
||||||
import top.continew.starter.core.util.ExceptionUtils;
|
import top.continew.starter.core.util.ExceptionUtils;
|
||||||
import top.continew.starter.core.util.validate.ValidationUtils;
|
import top.continew.starter.core.util.validate.ValidationUtils;
|
||||||
import top.continew.starter.web.model.R;
|
|
||||||
import top.continew.starter.log.core.annotation.Log;
|
import top.continew.starter.log.core.annotation.Log;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -69,7 +68,7 @@ public class AuthController {
|
|||||||
@SaIgnore
|
@SaIgnore
|
||||||
@Operation(summary = "账号登录", description = "根据账号和密码进行登录认证")
|
@Operation(summary = "账号登录", description = "根据账号和密码进行登录认证")
|
||||||
@PostMapping("/account")
|
@PostMapping("/account")
|
||||||
public R<LoginResp> accountLogin(@Validated @RequestBody AccountLoginReq loginReq, HttpServletRequest request) {
|
public LoginResp accountLogin(@Validated @RequestBody AccountLoginReq loginReq, HttpServletRequest request) {
|
||||||
String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + loginReq.getUuid();
|
String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + loginReq.getUuid();
|
||||||
String captcha = RedisUtils.get(captchaKey);
|
String captcha = RedisUtils.get(captchaKey);
|
||||||
ValidationUtils.throwIfBlank(captcha, CAPTCHA_EXPIRED);
|
ValidationUtils.throwIfBlank(captcha, CAPTCHA_EXPIRED);
|
||||||
@@ -79,13 +78,13 @@ public class AuthController {
|
|||||||
String rawPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(loginReq.getPassword()));
|
String rawPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(loginReq.getPassword()));
|
||||||
ValidationUtils.throwIfBlank(rawPassword, "密码解密失败");
|
ValidationUtils.throwIfBlank(rawPassword, "密码解密失败");
|
||||||
String token = loginService.accountLogin(loginReq.getUsername(), rawPassword, request);
|
String token = loginService.accountLogin(loginReq.getUsername(), rawPassword, request);
|
||||||
return R.ok(LoginResp.builder().token(token).build());
|
return LoginResp.builder().token(token).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SaIgnore
|
@SaIgnore
|
||||||
@Operation(summary = "手机号登录", description = "根据手机号和验证码进行登录认证")
|
@Operation(summary = "手机号登录", description = "根据手机号和验证码进行登录认证")
|
||||||
@PostMapping("/phone")
|
@PostMapping("/phone")
|
||||||
public R<LoginResp> phoneLogin(@Validated @RequestBody PhoneLoginReq loginReq) {
|
public LoginResp phoneLogin(@Validated @RequestBody PhoneLoginReq loginReq) {
|
||||||
String phone = loginReq.getPhone();
|
String phone = loginReq.getPhone();
|
||||||
String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + phone;
|
String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + phone;
|
||||||
String captcha = RedisUtils.get(captchaKey);
|
String captcha = RedisUtils.get(captchaKey);
|
||||||
@@ -93,13 +92,13 @@ public class AuthController {
|
|||||||
ValidationUtils.throwIfNotEqualIgnoreCase(loginReq.getCaptcha(), captcha, CAPTCHA_ERROR);
|
ValidationUtils.throwIfNotEqualIgnoreCase(loginReq.getCaptcha(), captcha, CAPTCHA_ERROR);
|
||||||
RedisUtils.delete(captchaKey);
|
RedisUtils.delete(captchaKey);
|
||||||
String token = loginService.phoneLogin(phone);
|
String token = loginService.phoneLogin(phone);
|
||||||
return R.ok(LoginResp.builder().token(token).build());
|
return LoginResp.builder().token(token).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SaIgnore
|
@SaIgnore
|
||||||
@Operation(summary = "邮箱登录", description = "根据邮箱和验证码进行登录认证")
|
@Operation(summary = "邮箱登录", description = "根据邮箱和验证码进行登录认证")
|
||||||
@PostMapping("/email")
|
@PostMapping("/email")
|
||||||
public R<LoginResp> emailLogin(@Validated @RequestBody EmailLoginReq loginReq) {
|
public LoginResp emailLogin(@Validated @RequestBody EmailLoginReq loginReq) {
|
||||||
String email = loginReq.getEmail();
|
String email = loginReq.getEmail();
|
||||||
String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + email;
|
String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + email;
|
||||||
String captcha = RedisUtils.get(captchaKey);
|
String captcha = RedisUtils.get(captchaKey);
|
||||||
@@ -107,35 +106,35 @@ public class AuthController {
|
|||||||
ValidationUtils.throwIfNotEqualIgnoreCase(loginReq.getCaptcha(), captcha, CAPTCHA_ERROR);
|
ValidationUtils.throwIfNotEqualIgnoreCase(loginReq.getCaptcha(), captcha, CAPTCHA_ERROR);
|
||||||
RedisUtils.delete(captchaKey);
|
RedisUtils.delete(captchaKey);
|
||||||
String token = loginService.emailLogin(email);
|
String token = loginService.emailLogin(email);
|
||||||
return R.ok(LoginResp.builder().token(token).build());
|
return LoginResp.builder().token(token).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "用户退出", description = "注销用户的当前登录")
|
@Operation(summary = "用户退出", description = "注销用户的当前登录")
|
||||||
@Parameter(name = "Authorization", description = "令牌", required = true, example = "Bearer xxxx-xxxx-xxxx-xxxx", in = ParameterIn.HEADER)
|
@Parameter(name = "Authorization", description = "令牌", required = true, example = "Bearer xxxx-xxxx-xxxx-xxxx", in = ParameterIn.HEADER)
|
||||||
@PostMapping("/logout")
|
@PostMapping("/logout")
|
||||||
public R<Object> logout() {
|
public Object logout() {
|
||||||
Object loginId = StpUtil.getLoginId(-1L);
|
Object loginId = StpUtil.getLoginId(-1L);
|
||||||
StpUtil.logout();
|
StpUtil.logout();
|
||||||
return R.ok(loginId);
|
return loginId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Log(ignore = true)
|
@Log(ignore = true)
|
||||||
@Operation(summary = "获取用户信息", description = "获取登录用户信息")
|
@Operation(summary = "获取用户信息", description = "获取登录用户信息")
|
||||||
@GetMapping("/user/info")
|
@GetMapping("/user/info")
|
||||||
public R<UserInfoResp> getUserInfo() {
|
public UserInfoResp getUserInfo() {
|
||||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||||
UserDetailResp userDetailResp = userService.get(loginUser.getId());
|
UserDetailResp userDetailResp = userService.get(loginUser.getId());
|
||||||
UserInfoResp userInfoResp = BeanUtil.copyProperties(userDetailResp, UserInfoResp.class);
|
UserInfoResp userInfoResp = BeanUtil.copyProperties(userDetailResp, UserInfoResp.class);
|
||||||
userInfoResp.setPermissions(loginUser.getPermissions());
|
userInfoResp.setPermissions(loginUser.getPermissions());
|
||||||
userInfoResp.setRoles(loginUser.getRoleCodes());
|
userInfoResp.setRoles(loginUser.getRoleCodes());
|
||||||
userInfoResp.setPwdExpired(loginUser.isPasswordExpired());
|
userInfoResp.setPwdExpired(loginUser.isPasswordExpired());
|
||||||
return R.ok(userInfoResp);
|
return userInfoResp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Log(ignore = true)
|
@Log(ignore = true)
|
||||||
@Operation(summary = "获取路由信息", description = "获取登录用户的路由信息")
|
@Operation(summary = "获取路由信息", description = "获取登录用户的路由信息")
|
||||||
@GetMapping("/route")
|
@GetMapping("/route")
|
||||||
public R<List<RouteResp>> listRoute() {
|
public List<RouteResp> listRoute() {
|
||||||
return R.ok(loginService.buildRouteTree(LoginHelper.getUserId()));
|
return loginService.buildRouteTree(LoginHelper.getUserId());
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -36,7 +36,6 @@ import top.continew.admin.auth.service.LoginService;
|
|||||||
import top.continew.starter.core.exception.BadRequestException;
|
import top.continew.starter.core.exception.BadRequestException;
|
||||||
import top.continew.starter.core.util.validate.ValidationUtils;
|
import top.continew.starter.core.util.validate.ValidationUtils;
|
||||||
import top.continew.starter.log.core.annotation.Log;
|
import top.continew.starter.log.core.annotation.Log;
|
||||||
import top.continew.starter.web.model.R;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 三方账号认证 API
|
* 三方账号认证 API
|
||||||
@@ -58,17 +57,17 @@ public class SocialAuthController {
|
|||||||
@Operation(summary = "三方账号登录授权", description = "三方账号登录授权")
|
@Operation(summary = "三方账号登录授权", description = "三方账号登录授权")
|
||||||
@Parameter(name = "source", description = "来源", example = "gitee", in = ParameterIn.PATH)
|
@Parameter(name = "source", description = "来源", example = "gitee", in = ParameterIn.PATH)
|
||||||
@GetMapping("/{source}")
|
@GetMapping("/{source}")
|
||||||
public R<SocialAuthAuthorizeResp> authorize(@PathVariable String source) {
|
public SocialAuthAuthorizeResp authorize(@PathVariable String source) {
|
||||||
AuthRequest authRequest = this.getAuthRequest(source);
|
AuthRequest authRequest = this.getAuthRequest(source);
|
||||||
return R.ok(SocialAuthAuthorizeResp.builder()
|
return SocialAuthAuthorizeResp.builder()
|
||||||
.authorizeUrl(authRequest.authorize(AuthStateUtils.createState()))
|
.authorizeUrl(authRequest.authorize(AuthStateUtils.createState()))
|
||||||
.build());
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "三方账号登录", description = "三方账号登录")
|
@Operation(summary = "三方账号登录", description = "三方账号登录")
|
||||||
@Parameter(name = "source", description = "来源", example = "gitee", in = ParameterIn.PATH)
|
@Parameter(name = "source", description = "来源", example = "gitee", in = ParameterIn.PATH)
|
||||||
@PostMapping("/{source}")
|
@PostMapping("/{source}")
|
||||||
public R<LoginResp> login(@PathVariable String source, @RequestBody AuthCallback callback) {
|
public LoginResp login(@PathVariable String source, @RequestBody AuthCallback callback) {
|
||||||
if (StpUtil.isLogin()) {
|
if (StpUtil.isLogin()) {
|
||||||
StpUtil.logout();
|
StpUtil.logout();
|
||||||
}
|
}
|
||||||
@@ -77,7 +76,7 @@ public class SocialAuthController {
|
|||||||
ValidationUtils.throwIf(!response.ok(), response.getMsg());
|
ValidationUtils.throwIf(!response.ok(), response.getMsg());
|
||||||
AuthUser authUser = response.getData();
|
AuthUser authUser = response.getData();
|
||||||
String token = loginService.socialLogin(authUser);
|
String token = loginService.socialLogin(authUser);
|
||||||
return R.ok(LoginResp.builder().token(token).build());
|
return LoginResp.builder().token(token).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private AuthRequest getAuthRequest(String source) {
|
private AuthRequest getAuthRequest(String source) {
|
||||||
|
@@ -90,33 +90,33 @@ public class CaptchaController {
|
|||||||
@Log(ignore = true)
|
@Log(ignore = true)
|
||||||
@Operation(summary = "获取行为验证码", description = "获取行为验证码(Base64编码)")
|
@Operation(summary = "获取行为验证码", description = "获取行为验证码(Base64编码)")
|
||||||
@GetMapping("/behavior")
|
@GetMapping("/behavior")
|
||||||
public R<Object> getBehaviorCaptcha(CaptchaVO captchaReq, HttpServletRequest request) {
|
public Object getBehaviorCaptcha(CaptchaVO captchaReq, HttpServletRequest request) {
|
||||||
captchaReq.setBrowserInfo(JakartaServletUtil.getClientIP(request) + request.getHeader(HttpHeaders.USER_AGENT));
|
captchaReq.setBrowserInfo(JakartaServletUtil.getClientIP(request) + request.getHeader(HttpHeaders.USER_AGENT));
|
||||||
ResponseModel responseModel = behaviorCaptchaService.get(captchaReq);
|
ResponseModel responseModel = behaviorCaptchaService.get(captchaReq);
|
||||||
CheckUtils.throwIf(() -> !StrUtil.equals(RepCodeEnum.SUCCESS.getCode(), responseModel
|
CheckUtils.throwIf(() -> !StrUtil.equals(RepCodeEnum.SUCCESS.getCode(), responseModel
|
||||||
.getRepCode()), responseModel.getRepMsg());
|
.getRepCode()), responseModel.getRepMsg());
|
||||||
return R.ok(responseModel.getRepData());
|
return responseModel.getRepData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Log(ignore = true)
|
@Log(ignore = true)
|
||||||
@Operation(summary = "校验行为验证码", description = "校验行为验证码")
|
@Operation(summary = "校验行为验证码", description = "校验行为验证码")
|
||||||
@PostMapping("/behavior")
|
@PostMapping("/behavior")
|
||||||
public R<Object> checkBehaviorCaptcha(@RequestBody CaptchaVO captchaReq, HttpServletRequest request) {
|
public Object checkBehaviorCaptcha(@RequestBody CaptchaVO captchaReq, HttpServletRequest request) {
|
||||||
captchaReq.setBrowserInfo(JakartaServletUtil.getClientIP(request) + request.getHeader(HttpHeaders.USER_AGENT));
|
captchaReq.setBrowserInfo(JakartaServletUtil.getClientIP(request) + request.getHeader(HttpHeaders.USER_AGENT));
|
||||||
return R.ok(behaviorCaptchaService.check(captchaReq));
|
return behaviorCaptchaService.check(captchaReq);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Log(ignore = true)
|
@Log(ignore = true)
|
||||||
@Operation(summary = "获取图片验证码", description = "获取图片验证码(Base64编码,带图片格式:data:image/gif;base64)")
|
@Operation(summary = "获取图片验证码", description = "获取图片验证码(Base64编码,带图片格式:data:image/gif;base64)")
|
||||||
@GetMapping("/image")
|
@GetMapping("/image")
|
||||||
public R<CaptchaResp> getImageCaptcha() {
|
public CaptchaResp getImageCaptcha() {
|
||||||
String uuid = IdUtil.fastUUID();
|
String uuid = IdUtil.fastUUID();
|
||||||
String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + uuid;
|
String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + uuid;
|
||||||
Captcha captcha = graphicCaptchaService.getCaptcha();
|
Captcha captcha = graphicCaptchaService.getCaptcha();
|
||||||
long expireTime = LocalDateTimeUtil.toEpochMilli(LocalDateTime.now()
|
long expireTime = LocalDateTimeUtil.toEpochMilli(LocalDateTime.now()
|
||||||
.plusMinutes(captchaProperties.getExpirationInMinutes()));
|
.plusMinutes(captchaProperties.getExpirationInMinutes()));
|
||||||
RedisUtils.set(captchaKey, captcha.text(), Duration.ofMinutes(captchaProperties.getExpirationInMinutes()));
|
RedisUtils.set(captchaKey, captcha.text(), Duration.ofMinutes(captchaProperties.getExpirationInMinutes()));
|
||||||
return R.ok(CaptchaResp.builder().uuid(uuid).img(captcha.toBase64()).expireTime(expireTime).build());
|
return CaptchaResp.builder().uuid(uuid).img(captcha.toBase64()).expireTime(expireTime).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -140,7 +140,7 @@ public class CaptchaController {
|
|||||||
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX + "DAY'", key = "#email + ':' + T(cn.hutool.extra.spring.SpringUtil).getProperty('captcha.mail.templatePath')", rate = 20, interval = 24, unit = RateIntervalUnit.HOURS, message = "获取验证码操作太频繁,请稍后再试"),
|
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX + "DAY'", key = "#email + ':' + T(cn.hutool.extra.spring.SpringUtil).getProperty('captcha.mail.templatePath')", rate = 20, interval = 24, unit = RateIntervalUnit.HOURS, message = "获取验证码操作太频繁,请稍后再试"),
|
||||||
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX, key = "#email", rate = 100, interval = 24, unit = RateIntervalUnit.HOURS, message = "获取验证码操作太频繁,请稍后再试"),
|
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX, key = "#email", rate = 100, interval = 24, unit = RateIntervalUnit.HOURS, message = "获取验证码操作太频繁,请稍后再试"),
|
||||||
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX, key = "#email", rate = 30, interval = 1, unit = RateIntervalUnit.MINUTES, type = LimitType.IP, message = "获取验证码操作太频繁,请稍后再试")})
|
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX, key = "#email", rate = 30, interval = 1, unit = RateIntervalUnit.MINUTES, type = LimitType.IP, message = "获取验证码操作太频繁,请稍后再试")})
|
||||||
public R<Void> getMailCaptcha(@NotBlank(message = "邮箱不能为空") @Pattern(regexp = RegexPool.EMAIL, message = "邮箱格式错误") String email) throws MessagingException {
|
public R getMailCaptcha(@NotBlank(message = "邮箱不能为空") @Pattern(regexp = RegexPool.EMAIL, message = "邮箱格式错误") String email) throws MessagingException {
|
||||||
// 生成验证码
|
// 生成验证码
|
||||||
CaptchaProperties.CaptchaMail captchaMail = captchaProperties.getMail();
|
CaptchaProperties.CaptchaMail captchaMail = captchaProperties.getMail();
|
||||||
String captcha = RandomUtil.randomNumbers(captchaMail.getLength());
|
String captcha = RandomUtil.randomNumbers(captchaMail.getLength());
|
||||||
@@ -182,8 +182,8 @@ public class CaptchaController {
|
|||||||
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX + "DAY'", key = "#phone + ':' + T(cn.hutool.extra.spring.SpringUtil).getProperty('captcha.sms.templateId')", rate = 20, interval = 24, unit = RateIntervalUnit.HOURS, message = "获取验证码操作太频繁,请稍后再试"),
|
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX + "DAY'", key = "#phone + ':' + T(cn.hutool.extra.spring.SpringUtil).getProperty('captcha.sms.templateId')", rate = 20, interval = 24, unit = RateIntervalUnit.HOURS, message = "获取验证码操作太频繁,请稍后再试"),
|
||||||
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX, key = "#phone", rate = 100, interval = 24, unit = RateIntervalUnit.HOURS, message = "获取验证码操作太频繁,请稍后再试"),
|
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX, key = "#phone", rate = 100, interval = 24, unit = RateIntervalUnit.HOURS, message = "获取验证码操作太频繁,请稍后再试"),
|
||||||
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX, key = "#phone", rate = 30, interval = 1, unit = RateIntervalUnit.MINUTES, type = LimitType.IP, message = "获取验证码操作太频繁,请稍后再试")})
|
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX, key = "#phone", rate = 30, interval = 1, unit = RateIntervalUnit.MINUTES, type = LimitType.IP, message = "获取验证码操作太频繁,请稍后再试")})
|
||||||
public R<Void> getSmsCaptcha(@NotBlank(message = "手机号不能为空") @Pattern(regexp = RegexPool.MOBILE, message = "手机号格式错误") String phone,
|
public R getSmsCaptcha(@NotBlank(message = "手机号不能为空") @Pattern(regexp = RegexPool.MOBILE, message = "手机号格式错误") String phone,
|
||||||
CaptchaVO captchaReq) {
|
CaptchaVO captchaReq) {
|
||||||
// 行为验证码校验
|
// 行为验证码校验
|
||||||
ResponseModel verificationRes = behaviorCaptchaService.verification(captchaReq);
|
ResponseModel verificationRes = behaviorCaptchaService.verification(captchaReq);
|
||||||
ValidationUtils.throwIfNotEqual(verificationRes.getRepCode(), RepCodeEnum.SUCCESS.getCode(), verificationRes
|
ValidationUtils.throwIfNotEqual(verificationRes.getRepCode(), RepCodeEnum.SUCCESS.getCode(), verificationRes
|
||||||
|
@@ -43,7 +43,6 @@ import top.continew.starter.core.util.validate.ValidationUtils;
|
|||||||
import top.continew.starter.extension.crud.model.query.SortQuery;
|
import top.continew.starter.extension.crud.model.query.SortQuery;
|
||||||
import top.continew.starter.extension.crud.model.resp.LabelValueResp;
|
import top.continew.starter.extension.crud.model.resp.LabelValueResp;
|
||||||
import top.continew.starter.log.core.annotation.Log;
|
import top.continew.starter.log.core.annotation.Log;
|
||||||
import top.continew.starter.web.model.R;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -71,49 +70,49 @@ public class CommonController {
|
|||||||
|
|
||||||
@Operation(summary = "上传文件", description = "上传文件")
|
@Operation(summary = "上传文件", description = "上传文件")
|
||||||
@PostMapping("/file")
|
@PostMapping("/file")
|
||||||
public R<FileUploadResp> upload(@NotNull(message = "文件不能为空") MultipartFile file) {
|
public FileUploadResp upload(@NotNull(message = "文件不能为空") MultipartFile file) {
|
||||||
ValidationUtils.throwIf(projectProperties.isProduction(), "演示环境不支持上传文件");
|
ValidationUtils.throwIf(projectProperties.isProduction(), "演示环境不支持上传文件");
|
||||||
ValidationUtils.throwIf(file::isEmpty, "文件不能为空");
|
ValidationUtils.throwIf(file::isEmpty, "文件不能为空");
|
||||||
FileInfo fileInfo = fileService.upload(file);
|
FileInfo fileInfo = fileService.upload(file);
|
||||||
return R.ok(FileUploadResp.builder().url(fileInfo.getUrl()).build());
|
return FileUploadResp.builder().url(fileInfo.getUrl()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "查询部门树", description = "查询树结构的部门列表")
|
@Operation(summary = "查询部门树", description = "查询树结构的部门列表")
|
||||||
@GetMapping("/tree/dept")
|
@GetMapping("/tree/dept")
|
||||||
public R<List<Tree<Long>>> listDeptTree(DeptQuery query, SortQuery sortQuery) {
|
public List<Tree<Long>> listDeptTree(DeptQuery query, SortQuery sortQuery) {
|
||||||
return R.ok(deptService.tree(query, sortQuery, true));
|
return deptService.tree(query, sortQuery, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "查询菜单树", description = "查询树结构的菜单列表")
|
@Operation(summary = "查询菜单树", description = "查询树结构的菜单列表")
|
||||||
@GetMapping("/tree/menu")
|
@GetMapping("/tree/menu")
|
||||||
public R<List<Tree<Long>>> listMenuTree(MenuQuery query, SortQuery sortQuery) {
|
public List<Tree<Long>> listMenuTree(MenuQuery query, SortQuery sortQuery) {
|
||||||
return R.ok(menuService.tree(query, sortQuery, true));
|
return menuService.tree(query, sortQuery, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "查询角色字典", description = "查询角色字典列表")
|
@Operation(summary = "查询角色字典", description = "查询角色字典列表")
|
||||||
@GetMapping("/dict/role")
|
@GetMapping("/dict/role")
|
||||||
public R<List<LabelValueResp>> listRoleDict(RoleQuery query, SortQuery sortQuery) {
|
public List<LabelValueResp> listRoleDict(RoleQuery query, SortQuery sortQuery) {
|
||||||
return R.ok(roleService.listDict(query, sortQuery));
|
return roleService.listDict(query, sortQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "查询字典", description = "查询字典列表")
|
@Operation(summary = "查询字典", description = "查询字典列表")
|
||||||
@Parameter(name = "code", description = "字典编码", example = "notice_type", in = ParameterIn.PATH)
|
@Parameter(name = "code", description = "字典编码", example = "notice_type", in = ParameterIn.PATH)
|
||||||
@GetMapping("/dict/{code}")
|
@GetMapping("/dict/{code}")
|
||||||
public R<List<LabelValueResp>> listDict(@PathVariable String code) {
|
public List<LabelValueResp> listDict(@PathVariable String code) {
|
||||||
return R.ok(dictItemService.listByDictCode(code));
|
return dictItemService.listByDictCode(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SaIgnore
|
@SaIgnore
|
||||||
@Operation(summary = "查询参数字典", description = "查询参数字典")
|
@Operation(summary = "查询参数字典", description = "查询参数字典")
|
||||||
@GetMapping("/dict/option")
|
@GetMapping("/dict/option")
|
||||||
@Cached(key = "#category", name = CacheConstants.OPTION_KEY_PREFIX)
|
@Cached(key = "#category", name = CacheConstants.OPTION_KEY_PREFIX)
|
||||||
public R<List<LabelValueResp<String>>> listOptionDict(@NotBlank(message = "类别不能为空") @RequestParam String category) {
|
public List<LabelValueResp<String>> listOptionDict(@NotBlank(message = "类别不能为空") String category) {
|
||||||
OptionQuery optionQuery = new OptionQuery();
|
OptionQuery optionQuery = new OptionQuery();
|
||||||
optionQuery.setCategory(category);
|
optionQuery.setCategory(category);
|
||||||
return R.ok(optionService.list(optionQuery)
|
return optionService.list(optionQuery)
|
||||||
.stream()
|
.stream()
|
||||||
.map(option -> new LabelValueResp<>(option.getCode(), StrUtil.nullToDefault(option.getValue(), option
|
.map(option -> new LabelValueResp<>(option.getCode(), StrUtil.nullToDefault(option.getValue(), option
|
||||||
.getDefaultValue())))
|
.getDefaultValue())))
|
||||||
.toList());
|
.toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -38,7 +38,6 @@ import top.continew.admin.system.model.resp.DashboardTotalResp;
|
|||||||
import top.continew.admin.system.service.DashboardService;
|
import top.continew.admin.system.service.DashboardService;
|
||||||
import top.continew.admin.system.model.resp.DashboardNoticeResp;
|
import top.continew.admin.system.model.resp.DashboardNoticeResp;
|
||||||
import top.continew.starter.core.util.validate.ValidationUtils;
|
import top.continew.starter.core.util.validate.ValidationUtils;
|
||||||
import top.continew.starter.web.model.R;
|
|
||||||
import top.continew.starter.log.core.annotation.Log;
|
import top.continew.starter.log.core.annotation.Log;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -61,8 +60,8 @@ public class DashboardController {
|
|||||||
|
|
||||||
@Operation(summary = "查询总计信息", description = "查询总计信息")
|
@Operation(summary = "查询总计信息", description = "查询总计信息")
|
||||||
@GetMapping("/total")
|
@GetMapping("/total")
|
||||||
public R<DashboardTotalResp> getTotal() {
|
public DashboardTotalResp getTotal() {
|
||||||
return R.ok(dashboardService.getTotal());
|
return dashboardService.getTotal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "查询访问趋势信息", description = "查询访问趋势信息")
|
@Operation(summary = "查询访问趋势信息", description = "查询访问趋势信息")
|
||||||
@@ -71,26 +70,26 @@ public class DashboardController {
|
|||||||
@CachePenetrationProtect
|
@CachePenetrationProtect
|
||||||
@CacheRefresh(refresh = 7200)
|
@CacheRefresh(refresh = 7200)
|
||||||
@Cached(key = "#days", name = CacheConstants.DASHBOARD_KEY_PREFIX, cacheType = CacheType.BOTH, syncLocal = true)
|
@Cached(key = "#days", name = CacheConstants.DASHBOARD_KEY_PREFIX, cacheType = CacheType.BOTH, syncLocal = true)
|
||||||
public R<List<DashboardAccessTrendResp>> listAccessTrend(@PathVariable Integer days) {
|
public List<DashboardAccessTrendResp> listAccessTrend(@PathVariable Integer days) {
|
||||||
ValidationUtils.throwIf(7 != days && 30 != days, "仅支持查询近 7/30 天访问趋势信息");
|
ValidationUtils.throwIf(7 != days && 30 != days, "仅支持查询近 7/30 天访问趋势信息");
|
||||||
return R.ok(dashboardService.listAccessTrend(days));
|
return dashboardService.listAccessTrend(days);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "查询热门模块列表", description = "查询热门模块列表")
|
@Operation(summary = "查询热门模块列表", description = "查询热门模块列表")
|
||||||
@GetMapping("/popular/module")
|
@GetMapping("/popular/module")
|
||||||
public R<List<DashboardPopularModuleResp>> listPopularModule() {
|
public List<DashboardPopularModuleResp> listPopularModule() {
|
||||||
return R.ok(dashboardService.listPopularModule());
|
return dashboardService.listPopularModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "查询访客地域分布信息", description = "查询访客地域分布信息")
|
@Operation(summary = "查询访客地域分布信息", description = "查询访客地域分布信息")
|
||||||
@GetMapping("/geo/distribution")
|
@GetMapping("/geo/distribution")
|
||||||
public R<DashboardGeoDistributionResp> getGeoDistribution() {
|
public DashboardGeoDistributionResp getGeoDistribution() {
|
||||||
return R.ok(dashboardService.getGeoDistribution());
|
return dashboardService.getGeoDistribution();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "查询公告列表", description = "查询公告列表")
|
@Operation(summary = "查询公告列表", description = "查询公告列表")
|
||||||
@GetMapping("/notice")
|
@GetMapping("/notice")
|
||||||
public R<List<DashboardNoticeResp>> listNotice() {
|
public List<DashboardNoticeResp> listNotice() {
|
||||||
return R.ok(dashboardService.listNotice());
|
return dashboardService.listNotice();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -35,7 +35,6 @@ import top.continew.admin.auth.service.OnlineUserService;
|
|||||||
import top.continew.starter.core.util.validate.CheckUtils;
|
import top.continew.starter.core.util.validate.CheckUtils;
|
||||||
import top.continew.starter.extension.crud.model.query.PageQuery;
|
import top.continew.starter.extension.crud.model.query.PageQuery;
|
||||||
import top.continew.starter.extension.crud.model.resp.PageResp;
|
import top.continew.starter.extension.crud.model.resp.PageResp;
|
||||||
import top.continew.starter.web.model.R;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在线用户 API
|
* 在线用户 API
|
||||||
@@ -54,18 +53,17 @@ public class OnlineUserController {
|
|||||||
@Operation(summary = "分页查询列表", description = "分页查询列表")
|
@Operation(summary = "分页查询列表", description = "分页查询列表")
|
||||||
@SaCheckPermission("monitor:online:list")
|
@SaCheckPermission("monitor:online:list")
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public R<PageResp<OnlineUserResp>> page(OnlineUserQuery query, @Validated PageQuery pageQuery) {
|
public PageResp<OnlineUserResp> page(OnlineUserQuery query, @Validated PageQuery pageQuery) {
|
||||||
return R.ok(baseService.page(query, pageQuery));
|
return baseService.page(query, pageQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "强退在线用户", description = "强退在线用户")
|
@Operation(summary = "强退在线用户", description = "强退在线用户")
|
||||||
@Parameter(name = "token", description = "令牌", example = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjEsInJuU3RyIjoiTUd6djdyOVFoeHEwdVFqdFAzV3M5YjVJRzh4YjZPSEUifQ.7q7U3ouoN7WPhH2kUEM7vPe5KF3G_qavSG-vRgIxKvE", in = ParameterIn.PATH)
|
@Parameter(name = "token", description = "令牌", example = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjEsInJuU3RyIjoiTUd6djdyOVFoeHEwdVFqdFAzV3M5YjVJRzh4YjZPSEUifQ.7q7U3ouoN7WPhH2kUEM7vPe5KF3G_qavSG-vRgIxKvE", in = ParameterIn.PATH)
|
||||||
@SaCheckPermission("monitor:online:kickout")
|
@SaCheckPermission("monitor:online:kickout")
|
||||||
@DeleteMapping("/{token}")
|
@DeleteMapping("/{token}")
|
||||||
public R<Void> kickout(@PathVariable String token) {
|
public void kickout(@PathVariable String token) {
|
||||||
String currentToken = StpUtil.getTokenValue();
|
String currentToken = StpUtil.getTokenValue();
|
||||||
CheckUtils.throwIfEqual(token, currentToken, "不能强退自己");
|
CheckUtils.throwIfEqual(token, currentToken, "不能强退自己");
|
||||||
StpUtil.kickoutByTokenValue(token);
|
StpUtil.kickoutByTokenValue(token);
|
||||||
return R.ok("强退成功");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,7 +32,6 @@ import top.continew.admin.job.service.JobService;
|
|||||||
import top.continew.starter.extension.crud.model.resp.PageResp;
|
import top.continew.starter.extension.crud.model.resp.PageResp;
|
||||||
import top.continew.starter.extension.crud.util.ValidateGroup;
|
import top.continew.starter.extension.crud.util.ValidateGroup;
|
||||||
import top.continew.starter.log.core.annotation.Log;
|
import top.continew.starter.log.core.annotation.Log;
|
||||||
import top.continew.starter.web.model.R;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -55,54 +54,53 @@ public class JobController {
|
|||||||
@Operation(summary = "分页查询任务列表", description = "分页查询任务列表")
|
@Operation(summary = "分页查询任务列表", description = "分页查询任务列表")
|
||||||
@SaCheckPermission("schedule:job:list")
|
@SaCheckPermission("schedule:job:list")
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public R<PageResp<JobResp>> page(JobQuery query) {
|
public PageResp<JobResp> page(JobQuery query) {
|
||||||
return R.ok(baseService.page(query));
|
return baseService.page(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "新增任务", description = "新增任务")
|
@Operation(summary = "新增任务", description = "新增任务")
|
||||||
@SaCheckPermission("schedule:job:add")
|
@SaCheckPermission("schedule:job:add")
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public R<Void> add(@Validated(ValidateGroup.Crud.Add.class) @RequestBody JobReq req) {
|
public void add(@Validated(ValidateGroup.Crud.Add.class) @RequestBody JobReq req) {
|
||||||
return baseService.add(req) ? R.ok() : R.fail();
|
baseService.add(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "修改任务", description = "修改任务")
|
@Operation(summary = "修改任务", description = "修改任务")
|
||||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||||
@SaCheckPermission("schedule:job:update")
|
@SaCheckPermission("schedule:job:update")
|
||||||
@PutMapping("/{id}")
|
@PutMapping("/{id}")
|
||||||
public R<Void> update(@Validated(ValidateGroup.Crud.Update.class) @RequestBody JobReq req, @PathVariable Long id) {
|
public void update(@Validated(ValidateGroup.Crud.Update.class) @RequestBody JobReq req, @PathVariable Long id) {
|
||||||
return baseService.update(req, id) ? R.ok() : R.fail();
|
baseService.update(req, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "修改任务状态", description = "修改任务状态")
|
@Operation(summary = "修改任务状态", description = "修改任务状态")
|
||||||
@SaCheckPermission("schedule:job:update")
|
@SaCheckPermission("schedule:job:update")
|
||||||
@PatchMapping("/{id}/status")
|
@PatchMapping("/{id}/status")
|
||||||
public R<Void> updateStatus(@Validated @RequestBody JobStatusReq req, @PathVariable Long id) {
|
public void updateStatus(@Validated @RequestBody JobStatusReq req, @PathVariable Long id) {
|
||||||
return baseService.updateStatus(req, id) ? R.ok() : R.fail();
|
baseService.updateStatus(req, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "删除任务", description = "删除任务")
|
@Operation(summary = "删除任务", description = "删除任务")
|
||||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||||
@SaCheckPermission("schedule:job:delete")
|
@SaCheckPermission("schedule:job:delete")
|
||||||
@DeleteMapping("/{id}")
|
@DeleteMapping("/{id}")
|
||||||
public R<Void> delete(@PathVariable Long id) {
|
public void delete(@PathVariable Long id) {
|
||||||
return baseService.delete(id) ? R.ok() : R.fail();
|
baseService.delete(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "执行任务", description = "执行任务")
|
@Operation(summary = "执行任务", description = "执行任务")
|
||||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||||
@SaCheckPermission("schedule:job:trigger")
|
@SaCheckPermission("schedule:job:trigger")
|
||||||
@PostMapping("/trigger/{id}")
|
@PostMapping("/trigger/{id}")
|
||||||
public R<Void> trigger(@PathVariable Long id) {
|
public void trigger(@PathVariable Long id) {
|
||||||
return baseService.trigger(id) ? R.ok() : R.fail();
|
baseService.trigger(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Log(ignore = true)
|
@Log(ignore = true)
|
||||||
@Operation(summary = "查询任务分组列表", description = "查询任务分组列表")
|
@Operation(summary = "查询任务分组列表", description = "查询任务分组列表")
|
||||||
@SaCheckPermission("schedule:job:list")
|
@SaCheckPermission("schedule:job:list")
|
||||||
@GetMapping("/group")
|
@GetMapping("/group")
|
||||||
public R<List<String>> listGroup() {
|
public List<String> listGroup() {
|
||||||
List<String> groupList = baseService.listGroup();
|
return baseService.listGroup();
|
||||||
return R.ok(groupList);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,7 +32,6 @@ import top.continew.admin.job.model.resp.JobLogResp;
|
|||||||
import top.continew.admin.job.model.resp.JobInstanceResp;
|
import top.continew.admin.job.model.resp.JobInstanceResp;
|
||||||
import top.continew.admin.job.service.JobLogService;
|
import top.continew.admin.job.service.JobLogService;
|
||||||
import top.continew.starter.extension.crud.model.resp.PageResp;
|
import top.continew.starter.extension.crud.model.resp.PageResp;
|
||||||
import top.continew.starter.web.model.R;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -55,37 +54,37 @@ public class JobLogController {
|
|||||||
@Operation(summary = "分页查询任务日志列表", description = "分页查询任务日志列表")
|
@Operation(summary = "分页查询任务日志列表", description = "分页查询任务日志列表")
|
||||||
@SaCheckPermission("schedule:log:list")
|
@SaCheckPermission("schedule:log:list")
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public R<PageResp<JobLogResp>> page(JobLogQuery query) {
|
public PageResp<JobLogResp> page(JobLogQuery query) {
|
||||||
return R.ok(baseService.page(query));
|
return baseService.page(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "停止任务", description = "停止任务")
|
@Operation(summary = "停止任务", description = "停止任务")
|
||||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||||
@SaCheckPermission("schedule:log:stop")
|
@SaCheckPermission("schedule:log:stop")
|
||||||
@PostMapping("/stop/{id}")
|
@PostMapping("/stop/{id}")
|
||||||
public R<Void> stop(@PathVariable Long id) {
|
public void stop(@PathVariable Long id) {
|
||||||
return baseService.stop(id) ? R.ok() : R.fail();
|
baseService.stop(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "重试任务", description = "重试任务")
|
@Operation(summary = "重试任务", description = "重试任务")
|
||||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||||
@SaCheckPermission("schedule:log:retry")
|
@SaCheckPermission("schedule:log:retry")
|
||||||
@PostMapping("/retry/{id}")
|
@PostMapping("/retry/{id}")
|
||||||
public R<Void> retry(@PathVariable Long id) {
|
public void retry(@PathVariable Long id) {
|
||||||
return baseService.retry(id) ? R.ok() : R.fail();
|
baseService.retry(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "查询任务实例列表", description = "查询任务实例列表")
|
@Operation(summary = "查询任务实例列表", description = "查询任务实例列表")
|
||||||
@SaCheckPermission("schedule:log:list")
|
@SaCheckPermission("schedule:log:list")
|
||||||
@GetMapping("/instance")
|
@GetMapping("/instance")
|
||||||
public R<List<JobInstanceResp>> listInstance(JobInstanceQuery query) {
|
public List<JobInstanceResp> listInstance(JobInstanceQuery query) {
|
||||||
return R.ok(baseService.listInstance(query));
|
return baseService.listInstance(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "分页查询任务实例日志列表", description = "分页查询任务实例日志列表")
|
@Operation(summary = "分页查询任务实例日志列表", description = "分页查询任务实例日志列表")
|
||||||
@SaCheckPermission("schedule:log:list")
|
@SaCheckPermission("schedule:log:list")
|
||||||
@GetMapping("/instance/log")
|
@GetMapping("/instance/log")
|
||||||
public R<JobInstanceLogPageResult> pageInstanceLog(JobInstanceLogQuery query) {
|
public JobInstanceLogPageResult pageInstanceLog(JobInstanceLogQuery query) {
|
||||||
return R.ok(baseService.pageInstanceLog(query));
|
return baseService.pageInstanceLog(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -30,7 +30,6 @@ import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
|
|||||||
import top.continew.starter.extension.crud.controller.BaseController;
|
import top.continew.starter.extension.crud.controller.BaseController;
|
||||||
import top.continew.starter.extension.crud.enums.Api;
|
import top.continew.starter.extension.crud.enums.Api;
|
||||||
import top.continew.starter.log.core.annotation.Log;
|
import top.continew.starter.log.core.annotation.Log;
|
||||||
import top.continew.starter.web.model.R;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件管理 API
|
* 文件管理 API
|
||||||
@@ -48,7 +47,7 @@ public class FileController extends BaseController<FileService, FileResp, FileRe
|
|||||||
@Operation(summary = "查询文件资源统计", description = "查询文件资源统计")
|
@Operation(summary = "查询文件资源统计", description = "查询文件资源统计")
|
||||||
@SaCheckPermission("system:file:list")
|
@SaCheckPermission("system:file:list")
|
||||||
@GetMapping("/statistics")
|
@GetMapping("/statistics")
|
||||||
public R<FileStatisticsResp> statistics() {
|
public FileStatisticsResp statistics() {
|
||||||
return R.ok(baseService.statistics());
|
return baseService.statistics();
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -17,6 +17,7 @@
|
|||||||
package top.continew.admin.controller.system;
|
package top.continew.admin.controller.system;
|
||||||
|
|
||||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||||
|
import com.feiniaojin.gracefulresponse.api.ExcludeFromGracefulResponse;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||||
@@ -35,7 +36,6 @@ import top.continew.admin.system.service.LogService;
|
|||||||
import top.continew.starter.extension.crud.model.query.PageQuery;
|
import top.continew.starter.extension.crud.model.query.PageQuery;
|
||||||
import top.continew.starter.extension.crud.model.query.SortQuery;
|
import top.continew.starter.extension.crud.model.query.SortQuery;
|
||||||
import top.continew.starter.extension.crud.model.resp.PageResp;
|
import top.continew.starter.extension.crud.model.resp.PageResp;
|
||||||
import top.continew.starter.web.model.R;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统日志 API
|
* 系统日志 API
|
||||||
@@ -54,18 +54,19 @@ public class LogController {
|
|||||||
@Operation(summary = "分页查询列表", description = "分页查询列表")
|
@Operation(summary = "分页查询列表", description = "分页查询列表")
|
||||||
@SaCheckPermission("monitor:log:list")
|
@SaCheckPermission("monitor:log:list")
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public R<PageResp<LogResp>> page(LogQuery query, @Validated PageQuery pageQuery) {
|
public PageResp<LogResp> page(LogQuery query, @Validated PageQuery pageQuery) {
|
||||||
return R.ok(baseService.page(query, pageQuery));
|
return baseService.page(query, pageQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "查询详情", description = "查询详情")
|
@Operation(summary = "查询详情", description = "查询详情")
|
||||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||||
@SaCheckPermission("monitor:log:list")
|
@SaCheckPermission("monitor:log:list")
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
public R<LogDetailResp> get(@PathVariable Long id) {
|
public LogDetailResp get(@PathVariable Long id) {
|
||||||
return R.ok(baseService.get(id));
|
return baseService.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExcludeFromGracefulResponse
|
||||||
@Operation(summary = "导出登录日志", description = "导出登录日志")
|
@Operation(summary = "导出登录日志", description = "导出登录日志")
|
||||||
@SaCheckPermission("monitor:log:export")
|
@SaCheckPermission("monitor:log:export")
|
||||||
@GetMapping("/export/login")
|
@GetMapping("/export/login")
|
||||||
@@ -73,6 +74,7 @@ public class LogController {
|
|||||||
baseService.exportLoginLog(query, sortQuery, response);
|
baseService.exportLoginLog(query, sortQuery, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExcludeFromGracefulResponse
|
||||||
@Operation(summary = "导出操作日志", description = "导出操作日志")
|
@Operation(summary = "导出操作日志", description = "导出操作日志")
|
||||||
@SaCheckPermission("monitor:log:export")
|
@SaCheckPermission("monitor:log:export")
|
||||||
@GetMapping("/export/operation")
|
@GetMapping("/export/operation")
|
||||||
|
@@ -33,8 +33,8 @@ import top.continew.starter.core.util.validate.ValidationUtils;
|
|||||||
import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
|
import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
|
||||||
import top.continew.starter.extension.crud.controller.BaseController;
|
import top.continew.starter.extension.crud.controller.BaseController;
|
||||||
import top.continew.starter.extension.crud.enums.Api;
|
import top.continew.starter.extension.crud.enums.Api;
|
||||||
|
import top.continew.starter.extension.crud.model.resp.BaseIdResp;
|
||||||
import top.continew.starter.extension.crud.util.ValidateGroup;
|
import top.continew.starter.extension.crud.util.ValidateGroup;
|
||||||
import top.continew.starter.web.model.R;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 菜单管理 API
|
* 菜单管理 API
|
||||||
@@ -48,15 +48,15 @@ import top.continew.starter.web.model.R;
|
|||||||
public class MenuController extends BaseController<MenuService, MenuResp, MenuResp, MenuQuery, MenuReq> {
|
public class MenuController extends BaseController<MenuService, MenuResp, MenuResp, MenuQuery, MenuReq> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R<Long> add(@Validated(ValidateGroup.Crud.Add.class) @RequestBody MenuReq req) {
|
public BaseIdResp<Long> add(@Validated(ValidateGroup.Crud.Add.class) @RequestBody MenuReq req) {
|
||||||
this.checkPath(req);
|
this.checkPath(req);
|
||||||
return super.add(req);
|
return super.add(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R<Void> update(@Validated(ValidateGroup.Crud.Update.class) @RequestBody MenuReq req, @PathVariable Long id) {
|
public void update(@Validated(ValidateGroup.Crud.Update.class) @RequestBody MenuReq req, @PathVariable Long id) {
|
||||||
this.checkPath(req);
|
this.checkPath(req);
|
||||||
return super.update(req, id);
|
super.update(req, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -32,7 +32,6 @@ import top.continew.admin.system.service.MessageUserService;
|
|||||||
import top.continew.starter.extension.crud.model.query.PageQuery;
|
import top.continew.starter.extension.crud.model.query.PageQuery;
|
||||||
import top.continew.starter.extension.crud.model.resp.PageResp;
|
import top.continew.starter.extension.crud.model.resp.PageResp;
|
||||||
import top.continew.starter.log.core.annotation.Log;
|
import top.continew.starter.log.core.annotation.Log;
|
||||||
import top.continew.starter.web.model.R;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -53,32 +52,30 @@ public class MessageController {
|
|||||||
|
|
||||||
@Operation(summary = "分页查询列表", description = "分页查询列表")
|
@Operation(summary = "分页查询列表", description = "分页查询列表")
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public R<PageResp<MessageResp>> page(MessageQuery query, @Validated PageQuery pageQuery) {
|
public PageResp<MessageResp> page(MessageQuery query, @Validated PageQuery pageQuery) {
|
||||||
query.setUserId(LoginHelper.getUserId());
|
query.setUserId(LoginHelper.getUserId());
|
||||||
return R.ok(baseService.page(query, pageQuery));
|
return baseService.page(query, pageQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "删除数据", description = "删除数据")
|
@Operation(summary = "删除数据", description = "删除数据")
|
||||||
@Parameter(name = "ids", description = "ID 列表", example = "1,2", in = ParameterIn.PATH)
|
@Parameter(name = "ids", description = "ID 列表", example = "1,2", in = ParameterIn.PATH)
|
||||||
@DeleteMapping("/{ids}")
|
@DeleteMapping("/{ids}")
|
||||||
public R<Void> delete(@PathVariable List<Long> ids) {
|
public void delete(@PathVariable List<Long> ids) {
|
||||||
baseService.delete(ids);
|
baseService.delete(ids);
|
||||||
return R.ok("删除成功");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "标记已读", description = "将消息标记为已读状态")
|
@Operation(summary = "标记已读", description = "将消息标记为已读状态")
|
||||||
@Parameter(name = "ids", description = "消息ID列表", example = "1,2", in = ParameterIn.QUERY)
|
@Parameter(name = "ids", description = "消息ID列表", example = "1,2", in = ParameterIn.QUERY)
|
||||||
@PatchMapping("/read")
|
@PatchMapping("/read")
|
||||||
public R<Void> readMessage(@RequestParam(required = false) List<Long> ids) {
|
public void readMessage(@RequestParam(required = false) List<Long> ids) {
|
||||||
messageUserService.readMessage(ids);
|
messageUserService.readMessage(ids);
|
||||||
return R.ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Log(ignore = true)
|
@Log(ignore = true)
|
||||||
@Operation(summary = "查询未读消息数量", description = "查询当前用户的未读消息数量")
|
@Operation(summary = "查询未读消息数量", description = "查询当前用户的未读消息数量")
|
||||||
@Parameter(name = "isDetail", description = "是否查询详情", example = "true", in = ParameterIn.QUERY)
|
@Parameter(name = "isDetail", description = "是否查询详情", example = "true", in = ParameterIn.QUERY)
|
||||||
@GetMapping("/unread")
|
@GetMapping("/unread")
|
||||||
public R<MessageUnreadResp> countUnreadMessage(@RequestParam(required = false) Boolean detail) {
|
public MessageUnreadResp countUnreadMessage(@RequestParam(required = false) Boolean detail) {
|
||||||
return R.ok(messageUserService.countUnreadMessageByUserId(LoginHelper.getUserId(), detail));
|
return messageUserService.countUnreadMessageByUserId(LoginHelper.getUserId(), detail);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -30,8 +30,8 @@ import top.continew.starter.core.util.validate.ValidationUtils;
|
|||||||
import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
|
import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
|
||||||
import top.continew.starter.extension.crud.controller.BaseController;
|
import top.continew.starter.extension.crud.controller.BaseController;
|
||||||
import top.continew.starter.extension.crud.enums.Api;
|
import top.continew.starter.extension.crud.enums.Api;
|
||||||
|
import top.continew.starter.extension.crud.model.resp.BaseIdResp;
|
||||||
import top.continew.starter.extension.crud.util.ValidateGroup;
|
import top.continew.starter.extension.crud.util.ValidateGroup;
|
||||||
import top.continew.starter.web.model.R;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@@ -47,16 +47,15 @@ import java.time.LocalDateTime;
|
|||||||
public class NoticeController extends BaseController<NoticeService, NoticeResp, NoticeDetailResp, NoticeQuery, NoticeReq> {
|
public class NoticeController extends BaseController<NoticeService, NoticeResp, NoticeDetailResp, NoticeQuery, NoticeReq> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R<Long> add(@Validated(ValidateGroup.Crud.Add.class) @RequestBody NoticeReq req) {
|
public BaseIdResp<Long> add(@Validated(ValidateGroup.Crud.Add.class) @RequestBody NoticeReq req) {
|
||||||
this.checkTime(req);
|
this.checkTime(req);
|
||||||
return super.add(req);
|
return super.add(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R<Void> update(@Validated(ValidateGroup.Crud.Update.class) @RequestBody NoticeReq req,
|
public void update(@Validated(ValidateGroup.Crud.Update.class) @RequestBody NoticeReq req, @PathVariable Long id) {
|
||||||
@PathVariable Long id) {
|
|
||||||
this.checkTime(req);
|
this.checkTime(req);
|
||||||
return super.update(req, id);
|
super.update(req, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -28,7 +28,6 @@ import top.continew.admin.system.model.req.OptionReq;
|
|||||||
import top.continew.admin.system.model.req.OptionResetValueReq;
|
import top.continew.admin.system.model.req.OptionResetValueReq;
|
||||||
import top.continew.admin.system.model.resp.OptionResp;
|
import top.continew.admin.system.model.resp.OptionResp;
|
||||||
import top.continew.admin.system.service.OptionService;
|
import top.continew.admin.system.service.OptionService;
|
||||||
import top.continew.starter.web.model.R;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -50,23 +49,21 @@ public class OptionController {
|
|||||||
@Operation(summary = "查询参数列表", description = "查询参数列表")
|
@Operation(summary = "查询参数列表", description = "查询参数列表")
|
||||||
@SaCheckPermission("system:config:list")
|
@SaCheckPermission("system:config:list")
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public R<List<OptionResp>> list(@Validated OptionQuery query) {
|
public List<OptionResp> list(@Validated OptionQuery query) {
|
||||||
return R.ok(baseService.list(query));
|
return baseService.list(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "修改参数", description = "修改参数")
|
@Operation(summary = "修改参数", description = "修改参数")
|
||||||
@SaCheckPermission("system:config:update")
|
@SaCheckPermission("system:config:update")
|
||||||
@PutMapping
|
@PutMapping
|
||||||
public R<Void> update(@Valid @RequestBody List<OptionReq> options) {
|
public void update(@Valid @RequestBody List<OptionReq> options) {
|
||||||
baseService.update(options);
|
baseService.update(options);
|
||||||
return R.ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "重置参数", description = "重置参数")
|
@Operation(summary = "重置参数", description = "重置参数")
|
||||||
@SaCheckPermission("system:config:reset")
|
@SaCheckPermission("system:config:reset")
|
||||||
@PatchMapping("/value")
|
@PatchMapping("/value")
|
||||||
public R<Void> resetValue(@Validated @RequestBody OptionResetValueReq req) {
|
public void resetValue(@Validated @RequestBody OptionResetValueReq req) {
|
||||||
baseService.resetValue(req);
|
baseService.resetValue(req);
|
||||||
return R.ok();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -31,9 +31,9 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import top.continew.admin.common.constant.CacheConstants;
|
import top.continew.admin.common.constant.CacheConstants;
|
||||||
import top.continew.admin.system.enums.SocialSourceEnum;
|
|
||||||
import top.continew.admin.common.util.SecureUtils;
|
import top.continew.admin.common.util.SecureUtils;
|
||||||
import top.continew.admin.common.util.helper.LoginHelper;
|
import top.continew.admin.common.util.helper.LoginHelper;
|
||||||
|
import top.continew.admin.system.enums.SocialSourceEnum;
|
||||||
import top.continew.admin.system.model.entity.UserSocialDO;
|
import top.continew.admin.system.model.entity.UserSocialDO;
|
||||||
import top.continew.admin.system.model.req.UserBasicInfoUpdateReq;
|
import top.continew.admin.system.model.req.UserBasicInfoUpdateReq;
|
||||||
import top.continew.admin.system.model.req.UserEmailUpdateRequest;
|
import top.continew.admin.system.model.req.UserEmailUpdateRequest;
|
||||||
@@ -46,7 +46,6 @@ import top.continew.admin.system.service.UserSocialService;
|
|||||||
import top.continew.starter.cache.redisson.util.RedisUtils;
|
import top.continew.starter.cache.redisson.util.RedisUtils;
|
||||||
import top.continew.starter.core.util.ExceptionUtils;
|
import top.continew.starter.core.util.ExceptionUtils;
|
||||||
import top.continew.starter.core.util.validate.ValidationUtils;
|
import top.continew.starter.core.util.validate.ValidationUtils;
|
||||||
import top.continew.starter.web.model.R;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -72,22 +71,21 @@ public class UserCenterController {
|
|||||||
|
|
||||||
@Operation(summary = "修改头像", description = "用户修改个人头像")
|
@Operation(summary = "修改头像", description = "用户修改个人头像")
|
||||||
@PostMapping("/avatar")
|
@PostMapping("/avatar")
|
||||||
public R<AvatarResp> updateAvatar(@NotNull(message = "头像不能为空") MultipartFile avatarFile) throws IOException {
|
public AvatarResp updateAvatar(@NotNull(message = "头像不能为空") MultipartFile avatarFile) throws IOException {
|
||||||
ValidationUtils.throwIf(avatarFile::isEmpty, "头像不能为空");
|
ValidationUtils.throwIf(avatarFile::isEmpty, "头像不能为空");
|
||||||
String newAvatar = userService.updateAvatar(avatarFile, LoginHelper.getUserId());
|
String newAvatar = userService.updateAvatar(avatarFile, LoginHelper.getUserId());
|
||||||
return R.ok("修改成功", AvatarResp.builder().avatar(newAvatar).build());
|
return AvatarResp.builder().avatar(newAvatar).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "修改基础信息", description = "修改用户基础信息")
|
@Operation(summary = "修改基础信息", description = "修改用户基础信息")
|
||||||
@PatchMapping("/basic/info")
|
@PatchMapping("/basic/info")
|
||||||
public R<Void> updateBasicInfo(@Validated @RequestBody UserBasicInfoUpdateReq req) {
|
public void updateBasicInfo(@Validated @RequestBody UserBasicInfoUpdateReq req) {
|
||||||
userService.updateBasicInfo(req, LoginHelper.getUserId());
|
userService.updateBasicInfo(req, LoginHelper.getUserId());
|
||||||
return R.ok("修改成功");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "修改密码", description = "修改用户登录密码")
|
@Operation(summary = "修改密码", description = "修改用户登录密码")
|
||||||
@PatchMapping("/password")
|
@PatchMapping("/password")
|
||||||
public R<Void> updatePassword(@Validated @RequestBody UserPasswordUpdateReq updateReq) {
|
public void updatePassword(@Validated @RequestBody UserPasswordUpdateReq updateReq) {
|
||||||
String rawOldPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateReq
|
String rawOldPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateReq
|
||||||
.getOldPassword()));
|
.getOldPassword()));
|
||||||
ValidationUtils.throwIfNull(rawOldPassword, DECRYPT_FAILED);
|
ValidationUtils.throwIfNull(rawOldPassword, DECRYPT_FAILED);
|
||||||
@@ -95,12 +93,11 @@ public class UserCenterController {
|
|||||||
.getNewPassword()));
|
.getNewPassword()));
|
||||||
ValidationUtils.throwIfNull(rawNewPassword, "新密码解密失败");
|
ValidationUtils.throwIfNull(rawNewPassword, "新密码解密失败");
|
||||||
userService.updatePassword(rawOldPassword, rawNewPassword, LoginHelper.getUserId());
|
userService.updatePassword(rawOldPassword, rawNewPassword, LoginHelper.getUserId());
|
||||||
return R.ok("修改成功,请牢记你的新密码");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "修改手机号", description = "修改手机号")
|
@Operation(summary = "修改手机号", description = "修改手机号")
|
||||||
@PatchMapping("/phone")
|
@PatchMapping("/phone")
|
||||||
public R<Void> updatePhone(@Validated @RequestBody UserPhoneUpdateReq updateReq) {
|
public void updatePhone(@Validated @RequestBody UserPhoneUpdateReq updateReq) {
|
||||||
String rawOldPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateReq
|
String rawOldPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateReq
|
||||||
.getOldPassword()));
|
.getOldPassword()));
|
||||||
ValidationUtils.throwIfBlank(rawOldPassword, DECRYPT_FAILED);
|
ValidationUtils.throwIfBlank(rawOldPassword, DECRYPT_FAILED);
|
||||||
@@ -110,12 +107,11 @@ public class UserCenterController {
|
|||||||
ValidationUtils.throwIfNotEqualIgnoreCase(updateReq.getCaptcha(), captcha, "验证码错误");
|
ValidationUtils.throwIfNotEqualIgnoreCase(updateReq.getCaptcha(), captcha, "验证码错误");
|
||||||
RedisUtils.delete(captchaKey);
|
RedisUtils.delete(captchaKey);
|
||||||
userService.updatePhone(updateReq.getPhone(), rawOldPassword, LoginHelper.getUserId());
|
userService.updatePhone(updateReq.getPhone(), rawOldPassword, LoginHelper.getUserId());
|
||||||
return R.ok("修改成功");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "修改邮箱", description = "修改用户邮箱")
|
@Operation(summary = "修改邮箱", description = "修改用户邮箱")
|
||||||
@PatchMapping("/email")
|
@PatchMapping("/email")
|
||||||
public R<Void> updateEmail(@Validated @RequestBody UserEmailUpdateRequest updateReq) {
|
public void updateEmail(@Validated @RequestBody UserEmailUpdateRequest updateReq) {
|
||||||
String rawOldPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateReq
|
String rawOldPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateReq
|
||||||
.getOldPassword()));
|
.getOldPassword()));
|
||||||
ValidationUtils.throwIfBlank(rawOldPassword, DECRYPT_FAILED);
|
ValidationUtils.throwIfBlank(rawOldPassword, DECRYPT_FAILED);
|
||||||
@@ -125,40 +121,36 @@ public class UserCenterController {
|
|||||||
ValidationUtils.throwIfNotEqualIgnoreCase(updateReq.getCaptcha(), captcha, "验证码错误");
|
ValidationUtils.throwIfNotEqualIgnoreCase(updateReq.getCaptcha(), captcha, "验证码错误");
|
||||||
RedisUtils.delete(captchaKey);
|
RedisUtils.delete(captchaKey);
|
||||||
userService.updateEmail(updateReq.getEmail(), rawOldPassword, LoginHelper.getUserId());
|
userService.updateEmail(updateReq.getEmail(), rawOldPassword, LoginHelper.getUserId());
|
||||||
return R.ok("修改成功");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "查询绑定的三方账号", description = "查询绑定的三方账号")
|
@Operation(summary = "查询绑定的三方账号", description = "查询绑定的三方账号")
|
||||||
@GetMapping("/social")
|
@GetMapping("/social")
|
||||||
public R<List<UserSocialBindResp>> listSocialBind() {
|
public List<UserSocialBindResp> listSocialBind() {
|
||||||
List<UserSocialDO> userSocialList = userSocialService.listByUserId(LoginHelper.getUserId());
|
List<UserSocialDO> userSocialList = userSocialService.listByUserId(LoginHelper.getUserId());
|
||||||
List<UserSocialBindResp> userSocialBindList = userSocialList.stream().map(userSocial -> {
|
return userSocialList.stream().map(userSocial -> {
|
||||||
String source = userSocial.getSource();
|
String source = userSocial.getSource();
|
||||||
UserSocialBindResp userSocialBind = new UserSocialBindResp();
|
UserSocialBindResp userSocialBind = new UserSocialBindResp();
|
||||||
userSocialBind.setSource(source);
|
userSocialBind.setSource(source);
|
||||||
userSocialBind.setDescription(SocialSourceEnum.valueOf(source).getDescription());
|
userSocialBind.setDescription(SocialSourceEnum.valueOf(source).getDescription());
|
||||||
return userSocialBind;
|
return userSocialBind;
|
||||||
}).toList();
|
}).toList();
|
||||||
return R.ok(userSocialBindList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "绑定三方账号", description = "绑定三方账号")
|
@Operation(summary = "绑定三方账号", description = "绑定三方账号")
|
||||||
@Parameter(name = "source", description = "来源", example = "gitee", in = ParameterIn.PATH)
|
@Parameter(name = "source", description = "来源", example = "gitee", in = ParameterIn.PATH)
|
||||||
@PostMapping("/social/{source}")
|
@PostMapping("/social/{source}")
|
||||||
public R<Void> bindSocial(@PathVariable String source, @RequestBody AuthCallback callback) {
|
public void bindSocial(@PathVariable String source, @RequestBody AuthCallback callback) {
|
||||||
AuthRequest authRequest = authRequestFactory.get(source);
|
AuthRequest authRequest = authRequestFactory.get(source);
|
||||||
AuthResponse<AuthUser> response = authRequest.login(callback);
|
AuthResponse<AuthUser> response = authRequest.login(callback);
|
||||||
ValidationUtils.throwIf(!response.ok(), response.getMsg());
|
ValidationUtils.throwIf(!response.ok(), response.getMsg());
|
||||||
AuthUser authUser = response.getData();
|
AuthUser authUser = response.getData();
|
||||||
userSocialService.bind(authUser, LoginHelper.getUserId());
|
userSocialService.bind(authUser, LoginHelper.getUserId());
|
||||||
return R.ok("绑定成功");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "解绑三方账号", description = "解绑三方账号")
|
@Operation(summary = "解绑三方账号", description = "解绑三方账号")
|
||||||
@Parameter(name = "source", description = "来源", example = "gitee", in = ParameterIn.PATH)
|
@Parameter(name = "source", description = "来源", example = "gitee", in = ParameterIn.PATH)
|
||||||
@DeleteMapping("/social/{source}")
|
@DeleteMapping("/social/{source}")
|
||||||
public R<Void> unbindSocial(@PathVariable String source) {
|
public void unbindSocial(@PathVariable String source) {
|
||||||
userSocialService.deleteBySourceAndUserId(source, LoginHelper.getUserId());
|
userSocialService.deleteBySourceAndUserId(source, LoginHelper.getUserId());
|
||||||
return R.ok("解绑成功");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -43,8 +43,8 @@ import top.continew.starter.core.util.validate.ValidationUtils;
|
|||||||
import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
|
import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
|
||||||
import top.continew.starter.extension.crud.controller.BaseController;
|
import top.continew.starter.extension.crud.controller.BaseController;
|
||||||
import top.continew.starter.extension.crud.enums.Api;
|
import top.continew.starter.extension.crud.enums.Api;
|
||||||
|
import top.continew.starter.extension.crud.model.resp.BaseIdResp;
|
||||||
import top.continew.starter.extension.crud.util.ValidateGroup;
|
import top.continew.starter.extension.crud.util.ValidateGroup;
|
||||||
import top.continew.starter.web.model.R;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ public class UserController extends BaseController<UserService, UserResp, UserDe
|
|||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R<Long> add(@Validated(ValidateGroup.Crud.Add.class) @RequestBody UserReq req) {
|
public BaseIdResp<Long> add(@Validated(ValidateGroup.Crud.Add.class) @RequestBody UserReq req) {
|
||||||
String rawPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(req.getPassword()));
|
String rawPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(req.getPassword()));
|
||||||
ValidationUtils.throwIfNull(rawPassword, "密码解密失败");
|
ValidationUtils.throwIfNull(rawPassword, "密码解密失败");
|
||||||
ValidationUtils.throwIf(!ReUtil
|
ValidationUtils.throwIf(!ReUtil
|
||||||
@@ -83,38 +83,36 @@ public class UserController extends BaseController<UserService, UserResp, UserDe
|
|||||||
@Operation(summary = "解析用户导入数据", description = "解析用户导入数据")
|
@Operation(summary = "解析用户导入数据", description = "解析用户导入数据")
|
||||||
@SaCheckPermission("system:user:import")
|
@SaCheckPermission("system:user:import")
|
||||||
@PostMapping(value = "parseImportUser")
|
@PostMapping(value = "parseImportUser")
|
||||||
public R<UserImportParseResp> parseImportUser(@NotNull(message = "文件不能为空") MultipartFile file) {
|
public UserImportParseResp parseImportUser(@NotNull(message = "文件不能为空") MultipartFile file) {
|
||||||
ValidationUtils.throwIf(file::isEmpty, "文件不能为空");
|
ValidationUtils.throwIf(file::isEmpty, "文件不能为空");
|
||||||
return R.ok(userService.parseImportUser(file));
|
return userService.parseImportUser(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "导入用户", description = "导入用户")
|
@Operation(summary = "导入用户", description = "导入用户")
|
||||||
@SaCheckPermission("system:user:import")
|
@SaCheckPermission("system:user:import")
|
||||||
@PostMapping(value = "import")
|
@PostMapping(value = "import")
|
||||||
public R<UserImportResp> importUser(@Validated @RequestBody UserImportReq req) {
|
public UserImportResp importUser(@Validated @RequestBody UserImportReq req) {
|
||||||
return R.ok(userService.importUser(req));
|
return userService.importUser(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "重置密码", description = "重置用户登录密码")
|
@Operation(summary = "重置密码", description = "重置用户登录密码")
|
||||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||||
@SaCheckPermission("system:user:resetPwd")
|
@SaCheckPermission("system:user:resetPwd")
|
||||||
@PatchMapping("/{id}/password")
|
@PatchMapping("/{id}/password")
|
||||||
public R<Void> resetPassword(@Validated @RequestBody UserPasswordResetReq req, @PathVariable Long id) {
|
public void resetPassword(@Validated @RequestBody UserPasswordResetReq req, @PathVariable Long id) {
|
||||||
String rawNewPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(req.getNewPassword()));
|
String rawNewPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(req.getNewPassword()));
|
||||||
ValidationUtils.throwIfNull(rawNewPassword, "新密码解密失败");
|
ValidationUtils.throwIfNull(rawNewPassword, "新密码解密失败");
|
||||||
ValidationUtils.throwIf(!ReUtil
|
ValidationUtils.throwIf(!ReUtil
|
||||||
.isMatch(RegexConstants.PASSWORD, rawNewPassword), "密码长度为 8-32 个字符,支持大小写字母、数字、特殊字符,至少包含字母和数字");
|
.isMatch(RegexConstants.PASSWORD, rawNewPassword), "密码长度为 8-32 个字符,支持大小写字母、数字、特殊字符,至少包含字母和数字");
|
||||||
req.setNewPassword(rawNewPassword);
|
req.setNewPassword(rawNewPassword);
|
||||||
baseService.resetPassword(req, id);
|
baseService.resetPassword(req, id);
|
||||||
return R.ok("重置密码成功");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "分配角色", description = "为用户新增或移除角色")
|
@Operation(summary = "分配角色", description = "为用户新增或移除角色")
|
||||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||||
@SaCheckPermission("system:user:updateRole")
|
@SaCheckPermission("system:user:updateRole")
|
||||||
@PatchMapping("/{id}/role")
|
@PatchMapping("/{id}/role")
|
||||||
public R<Void> updateRole(@Validated @RequestBody UserRoleUpdateReq updateReq, @PathVariable Long id) {
|
public void updateRole(@Validated @RequestBody UserRoleUpdateReq updateReq, @PathVariable Long id) {
|
||||||
baseService.updateRole(updateReq, id);
|
baseService.updateRole(updateReq, id);
|
||||||
return R.ok("分配成功");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,7 +21,6 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@@ -35,7 +34,6 @@ import top.continew.admin.generator.model.resp.TableResp;
|
|||||||
import top.continew.admin.generator.service.GeneratorService;
|
import top.continew.admin.generator.service.GeneratorService;
|
||||||
import top.continew.starter.extension.crud.model.query.PageQuery;
|
import top.continew.starter.extension.crud.model.query.PageQuery;
|
||||||
import top.continew.starter.extension.crud.model.resp.PageResp;
|
import top.continew.starter.extension.crud.model.resp.PageResp;
|
||||||
import top.continew.starter.web.model.R;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -58,8 +56,8 @@ public class GeneratorController {
|
|||||||
@Operation(summary = "分页查询数据表", description = "分页查询数据表")
|
@Operation(summary = "分页查询数据表", description = "分页查询数据表")
|
||||||
@SaCheckPermission("tool:generator:list")
|
@SaCheckPermission("tool:generator:list")
|
||||||
@GetMapping("/table")
|
@GetMapping("/table")
|
||||||
public R<PageResp<TableResp>> pageTable(TableQuery query, @Validated PageQuery pageQuery) throws SQLException {
|
public PageResp<TableResp> pageTable(TableQuery query, @Validated PageQuery pageQuery) throws SQLException {
|
||||||
return R.ok(baseService.pageTable(query, pageQuery));
|
return baseService.pageTable(query, pageQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "查询字段配置列表", description = "查询字段配置列表")
|
@Operation(summary = "查询字段配置列表", description = "查询字段配置列表")
|
||||||
@@ -67,43 +65,40 @@ public class GeneratorController {
|
|||||||
@Parameter(name = "requireSync", description = "是否需要同步", example = "false", in = ParameterIn.QUERY)
|
@Parameter(name = "requireSync", description = "是否需要同步", example = "false", in = ParameterIn.QUERY)
|
||||||
@SaCheckPermission("tool:generator:list")
|
@SaCheckPermission("tool:generator:list")
|
||||||
@GetMapping("/field/{tableName}")
|
@GetMapping("/field/{tableName}")
|
||||||
public R<List<FieldConfigDO>> listFieldConfig(@PathVariable String tableName,
|
public List<FieldConfigDO> listFieldConfig(@PathVariable String tableName,
|
||||||
@RequestParam(required = false, defaultValue = "false") Boolean requireSync) {
|
@RequestParam(required = false, defaultValue = "false") Boolean requireSync) {
|
||||||
return R.ok(baseService.listFieldConfig(tableName, requireSync));
|
return baseService.listFieldConfig(tableName, requireSync);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "查询生成配置信息", description = "查询生成配置信息")
|
@Operation(summary = "查询生成配置信息", description = "查询生成配置信息")
|
||||||
@Parameter(name = "tableName", description = "表名称", required = true, example = "sys_user", in = ParameterIn.PATH)
|
@Parameter(name = "tableName", description = "表名称", required = true, example = "sys_user", in = ParameterIn.PATH)
|
||||||
@SaCheckPermission("tool:generator:list")
|
@SaCheckPermission("tool:generator:list")
|
||||||
@GetMapping("/config/{tableName}")
|
@GetMapping("/config/{tableName}")
|
||||||
public R<GenConfigDO> getGenConfig(@PathVariable String tableName) throws SQLException {
|
public GenConfigDO getGenConfig(@PathVariable String tableName) throws SQLException {
|
||||||
return R.ok(baseService.getGenConfig(tableName));
|
return baseService.getGenConfig(tableName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "保存配置信息", description = "保存配置信息")
|
@Operation(summary = "保存配置信息", description = "保存配置信息")
|
||||||
@Parameter(name = "tableName", description = "表名称", required = true, example = "sys_user", in = ParameterIn.PATH)
|
@Parameter(name = "tableName", description = "表名称", required = true, example = "sys_user", in = ParameterIn.PATH)
|
||||||
@SaCheckPermission("tool:generator:list")
|
@SaCheckPermission("tool:generator:list")
|
||||||
@PostMapping("/config/{tableName}")
|
@PostMapping("/config/{tableName}")
|
||||||
public R<Void> saveConfig(@Validated @RequestBody GenConfigReq req, @PathVariable String tableName) {
|
public void saveConfig(@Validated @RequestBody GenConfigReq req, @PathVariable String tableName) {
|
||||||
baseService.saveConfig(req, tableName);
|
baseService.saveConfig(req, tableName);
|
||||||
return R.ok("保存成功");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "生成预览", description = "预览生成代码")
|
@Operation(summary = "生成预览", description = "预览生成代码")
|
||||||
@Parameter(name = "tableName", description = "表名称", required = true, example = "sys_user", in = ParameterIn.PATH)
|
@Parameter(name = "tableName", description = "表名称", required = true, example = "sys_user", in = ParameterIn.PATH)
|
||||||
@SaCheckPermission("tool:generator:list")
|
@SaCheckPermission("tool:generator:list")
|
||||||
@GetMapping("/preview/{tableName}")
|
@GetMapping("/preview/{tableName}")
|
||||||
public R<List<GeneratePreviewResp>> preview(@PathVariable String tableName) {
|
public List<GeneratePreviewResp> preview(@PathVariable String tableName) {
|
||||||
return R.ok(baseService.preview(tableName));
|
return baseService.preview(tableName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "生成代码", description = "生成代码")
|
@Operation(summary = "生成代码", description = "生成代码")
|
||||||
@Parameter(name = "tableName", description = "表名称", required = true, example = "sys_user", in = ParameterIn.PATH)
|
@Parameter(name = "tableName", description = "表名称", required = true, example = "sys_user", in = ParameterIn.PATH)
|
||||||
@SaCheckPermission("tool:generator:list")
|
@SaCheckPermission("tool:generator:list")
|
||||||
@PostMapping("/{tableNames}")
|
@PostMapping("/{tableNames}")
|
||||||
public void generate(@PathVariable List<String> tableNames,
|
public void generate(@PathVariable List<String> tableNames, HttpServletResponse response) {
|
||||||
HttpServletRequest request,
|
baseService.generate(tableNames, response);
|
||||||
HttpServletResponse response) {
|
|
||||||
baseService.generate(tableNames, request, response);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,5 +5,5 @@
|
|||||||
\____|\___/ |_| |_| \__||_||_| \_| \___| \_/\_/ /_/ \_\\__,_||_| |_| |_||_||_| |_|
|
\____|\___/ |_| |_| \__||_||_| \_| \___| \_/\_/ /_/ \_\\__,_||_| |_| |_||_||_| |_|
|
||||||
|
|
||||||
:: ${project.name} :: v${project.version}
|
:: ${project.name} :: v${project.version}
|
||||||
:: ContiNew Starter :: v2.4.0
|
:: ContiNew Starter :: v2.5.0
|
||||||
:: Spring Boot :: v${spring-boot.version}
|
:: Spring Boot :: v${spring-boot.version}
|
||||||
|
@@ -48,6 +48,20 @@ continew-starter.web:
|
|||||||
pattern: '[$spanId][$traceId]'
|
pattern: '[$spanId][$traceId]'
|
||||||
mdc-enable: false
|
mdc-enable: false
|
||||||
|
|
||||||
|
--- ### 全局响应配置
|
||||||
|
continew-starter.web:
|
||||||
|
response:
|
||||||
|
# 是否开启国际化(默认:false)
|
||||||
|
i18n: false
|
||||||
|
# 自定义成功响应码(默认:0)
|
||||||
|
default-success-code: 0
|
||||||
|
# 自定义成功提示(默认:ok)
|
||||||
|
default-success-msg: ok
|
||||||
|
# 自定义失败响应码(默认:1)
|
||||||
|
default-error-code: 1
|
||||||
|
# 自定义失败提示(默认:error)
|
||||||
|
default-error-msg: error
|
||||||
|
|
||||||
--- ### 接口文档配置
|
--- ### 接口文档配置
|
||||||
springdoc:
|
springdoc:
|
||||||
# 设置对象型参数的展示形式(设为 true 表示将对象型参数平展开,即对象内的属性直接作为参数展示而不是嵌套在对象内,默认 false)
|
# 设置对象型参数的展示形式(设为 true 表示将对象型参数平展开,即对象内的属性直接作为参数展示而不是嵌套在对象内,默认 false)
|
||||||
|
2
pom.xml
2
pom.xml
@@ -13,7 +13,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>top.continew</groupId>
|
<groupId>top.continew</groupId>
|
||||||
<artifactId>continew-starter</artifactId>
|
<artifactId>continew-starter</artifactId>
|
||||||
<version>2.4.0</version>
|
<version>2.5.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>top.continew</groupId>
|
<groupId>top.continew</groupId>
|
||||||
|
Reference in New Issue
Block a user