mirror of
https://github.com/continew-org/continew-admin.git
synced 2025-09-08 22:57:12 +08:00
build: continew-starter 2.10.0 => 2.11.0
1.SaToken 升级适配 2.DictField 注解 => DictModel 3.BaseIdResp => IdResp 4.CRUD 删除接口由 URL 传参重构为请求体传参 5.访问日志打印问题修复等
This commit is contained in:
10
README.md
10
README.md
@@ -4,7 +4,7 @@
|
||||
<img src="https://img.shields.io/badge/SNAPSHOT-v3.6.0-%23ff3f59.svg" alt="Release" />
|
||||
</a>
|
||||
<a href="https://github.com/continew-org/continew-starter" title="ContiNew Starter" target="_blank">
|
||||
<img src="https://img.shields.io/badge/ContiNew Starter-2.10.0-%236CB52D.svg" alt="ContiNew Starter" />
|
||||
<img src="https://img.shields.io/badge/ContiNew Starter-2.11.0-%236CB52D.svg" alt="ContiNew Starter" />
|
||||
</a>
|
||||
<a href="https://spring.io/projects/spring-boot" title="Spring Boot" target="_blank">
|
||||
<img src="https://img.shields.io/badge/Spring Boot-3.3.9-%236CB52D.svg?logo=Spring-Boot" alt="Spring Boot" />
|
||||
@@ -225,16 +225,16 @@ public class DeptController extends BaseController<DeptService, DeptResp, DeptDe
|
||||
|
||||
## 核心技术栈
|
||||
|
||||
| 名称 | 版本 | 简介 |
|
||||
| :----------------------------------------------------------- | :----------- | :----------------------------------------------------------- |
|
||||
| 名称 | 版本 | 简介 |
|
||||
| :----------------------------------------------------------- |:-------------| :----------------------------------------------------------- |
|
||||
| <a href="https://vuejs.org/" target="_blank">Vue</a> | 3.5.4 | 渐进式 JavaScript 框架,易学易用,性能出色,适用场景丰富的 Web 前端框架。 |
|
||||
| <a href="https://arco.design/vue/docs/start" target="_blank">Arco Design</a> | 2.57.0 | 字节跳动推出的前端 UI 框架,年轻化的色彩和组件设计。 |
|
||||
| <a href="https://www.typescriptlang.org/zh/" target="_blank">TypeScript</a> | 5.0.4 | TypeScript 是微软开发的一个开源的编程语言,通过在 JavaScript 的基础上添加静态类型定义构建而成。 |
|
||||
| <a href="https://vite.dev/" target="_blank">Vite</a> | 5.1.5 | 下一代的前端工具链,为开发提供极速响应。 |
|
||||
| [ContiNew Starter](https://github.com/continew-org/continew-starter) | 2.10.0 | ContiNew Starter 包含了一系列经过企业实践优化的依赖包(如 MyBatis-Plus、SaToken),可轻松集成到应用中,为开发人员减少手动引入依赖及配置的麻烦,为 Spring Boot Web 项目的灵活快速构建提供支持。 |
|
||||
| [ContiNew Starter](https://github.com/continew-org/continew-starter) | 2.11.0 | ContiNew Starter 包含了一系列经过企业实践优化的依赖包(如 MyBatis-Plus、SaToken),可轻松集成到应用中,为开发人员减少手动引入依赖及配置的麻烦,为 Spring Boot Web 项目的灵活快速构建提供支持。 |
|
||||
| <a href="https://spring.io/projects/spring-boot" target="_blank">Spring Boot</a> | 3.3.9 | 简化 Spring 应用的初始搭建和开发过程,基于“约定优于配置”的理念,使开发人员不再需要定义样板化的配置。(Spring Boot 3.0 开始,要求 Java 17 作为最低版本) |
|
||||
| <a href="https://undertow.io/" target="_blank">Undertow</a> | 2.3.18.Final | 采用 Java 开发的灵活的高性能 Web 服务器,提供包括阻塞和基于 NIO 的非堵塞机制。 |
|
||||
| <a href="https://sa-token.dev33.cn/" target="_blank">Sa-Token + JWT</a> | 1.40.0 | 轻量级 Java 权限认证框架,让鉴权变得简单、优雅。 |
|
||||
| <a href="https://sa-token.dev33.cn/" target="_blank">Sa-Token + JWT</a> | 1.41.0 | 轻量级 Java 权限认证框架,让鉴权变得简单、优雅。 |
|
||||
| <a href="https://baomidou.com/" target="_blank">MyBatis Plus</a> | 3.5.8 | MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,简化开发、提高效率。 |
|
||||
| <a href="https://www.kancloud.cn/tracy5546/dynamic-datasource/2264611" target="_blank">dynamic-datasource-spring-boot-starter</a> | 4.3.1 | 基于 Spring Boot 的快速集成多数据源的启动器。 |
|
||||
| Hikari | 5.1.0 | JDBC 连接池,号称 “史上最快连接池”,SpringBoot 在 2.0 之后,采用的默认数据库连接池就是 Hikari。 |
|
||||
|
@@ -16,8 +16,8 @@
|
||||
|
||||
package top.continew.admin.auth;
|
||||
|
||||
import cn.dev33.satoken.stp.SaLoginModel;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
@@ -38,7 +38,7 @@ import top.continew.admin.system.service.RoleService;
|
||||
import top.continew.admin.system.service.UserService;
|
||||
import top.continew.starter.core.validation.CheckUtils;
|
||||
import top.continew.starter.core.validation.Validator;
|
||||
import top.continew.starter.web.util.SpringWebUtils;
|
||||
import top.continew.starter.web.util.ServletUtils;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -101,16 +101,16 @@ public abstract class AbstractLoginHandler<T extends LoginReq> implements LoginH
|
||||
.join(), passwordExpirationDaysFuture.join());
|
||||
BeanUtil.copyProperties(user, userContext);
|
||||
// 设置登录配置参数
|
||||
SaLoginModel model = new SaLoginModel();
|
||||
model.setActiveTimeout(client.getActiveTimeout());
|
||||
model.setTimeout(client.getTimeout());
|
||||
model.setDevice(client.getClientType());
|
||||
SaLoginParameter loginParameter = new SaLoginParameter();
|
||||
loginParameter.setActiveTimeout(client.getActiveTimeout());
|
||||
loginParameter.setTimeout(client.getTimeout());
|
||||
loginParameter.setDeviceType(client.getClientType());
|
||||
userContext.setClientType(client.getClientType());
|
||||
model.setExtra(CLIENT_ID, client.getClientId());
|
||||
loginParameter.setExtra(CLIENT_ID, client.getClientId());
|
||||
userContext.setClientId(client.getClientId());
|
||||
// 登录并缓存用户信息
|
||||
StpUtil.login(userContext.getId(), model.setExtraData(BeanUtil.beanToMap(new UserExtraContext(SpringWebUtils
|
||||
.getRequest()))));
|
||||
StpUtil.login(userContext.getId(), loginParameter.setExtraData(BeanUtil
|
||||
.beanToMap(new UserExtraContext(ServletUtils.getRequest()))));
|
||||
UserContextHolder.setContext(userContext);
|
||||
return StpUtil.getTokenValue();
|
||||
}
|
||||
|
@@ -23,7 +23,6 @@ import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.ReUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.xkcoding.justauth.AuthRequestFactory;
|
||||
import com.xkcoding.justauth.autoconfigure.JustAuthProperties;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
@@ -108,7 +107,7 @@ public class SocialLoginHandler extends AbstractLoginHandler<SocialLoginReq> {
|
||||
user = new UserDO();
|
||||
user.setUsername(username);
|
||||
user.setNickname(nickname);
|
||||
if(Objects.nonNull(authUser.getGender())) {
|
||||
if (Objects.nonNull(authUser.getGender())) {
|
||||
user.setGender(GenderEnum.valueOf(authUser.getGender().name()));
|
||||
}
|
||||
user.setAvatar(authUser.getAvatar());
|
||||
@@ -157,11 +156,7 @@ public class SocialLoginHandler extends AbstractLoginHandler<SocialLoginReq> {
|
||||
private AuthRequest getAuthRequest(String source) {
|
||||
try {
|
||||
AuthConfig authConfig = authProperties.getType().get(source.toUpperCase());
|
||||
return AuthRequestBuilder
|
||||
.builder()
|
||||
.source(source)
|
||||
.authConfig(authConfig)
|
||||
.build();
|
||||
return AuthRequestBuilder.builder().source(source).authConfig(authConfig).build();
|
||||
} catch (Exception e) {
|
||||
throw new BadRequestException("暂不支持 [%s] 平台账号登录".formatted(source));
|
||||
}
|
||||
|
@@ -56,6 +56,7 @@ public class FileRecorderImpl implements FileRecorder {
|
||||
|
||||
/**
|
||||
* 文件信息存储
|
||||
*
|
||||
* @param fileInfo 文件信息对象
|
||||
* @return 是否保存成功
|
||||
*/
|
||||
@@ -67,8 +68,8 @@ public class FileRecorderImpl implements FileRecorder {
|
||||
fileInfo.setId(String.valueOf(id.longValue()));
|
||||
String originalFilename = EscapeUtil.unescape(fileInfo.getOriginalFilename());
|
||||
file.setName(StrUtil.contains(originalFilename, StringConstants.DOT)
|
||||
? StrUtil.subBefore(originalFilename, StringConstants.DOT, true)
|
||||
: originalFilename);
|
||||
? StrUtil.subBefore(originalFilename, StringConstants.DOT, true)
|
||||
: originalFilename);
|
||||
StorageDO storage = (StorageDO)fileInfo.getAttr().get(ClassUtil.getClassName(StorageDO.class, false));
|
||||
String domain = StrUtil.appendIfMissing(storage.getDomain(), StringConstants.SLASH);
|
||||
// 处理fileInfo中存储的地址
|
||||
|
@@ -18,7 +18,7 @@ package top.continew.admin.system.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import top.continew.starter.extension.crud.annotation.DictField;
|
||||
import top.continew.starter.extension.crud.annotation.DictModel;
|
||||
import top.continew.admin.common.model.entity.BaseDO;
|
||||
|
||||
import java.io.Serial;
|
||||
@@ -30,7 +30,7 @@ import java.io.Serial;
|
||||
* @since 2023/9/11 21:29
|
||||
*/
|
||||
@Data
|
||||
@DictField(valueKey = "code")
|
||||
@DictModel(valueKey = "code")
|
||||
@TableName("sys_dict")
|
||||
public class DictDO extends BaseDO {
|
||||
|
||||
|
@@ -19,8 +19,8 @@ package top.continew.admin.system.model.entity;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import top.continew.admin.common.enums.DataScopeEnum;
|
||||
import top.continew.starter.extension.crud.annotation.DictField;
|
||||
import top.continew.admin.common.model.entity.BaseDO;
|
||||
import top.continew.starter.extension.crud.annotation.DictModel;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
@@ -31,7 +31,7 @@ import java.io.Serial;
|
||||
* @since 2023/2/8 22:54
|
||||
*/
|
||||
@Data
|
||||
@DictField
|
||||
@DictModel
|
||||
@TableName("sys_role")
|
||||
public class RoleDO extends BaseDO {
|
||||
|
||||
|
@@ -23,7 +23,7 @@ import lombok.Data;
|
||||
import top.continew.admin.common.config.mybatis.BCryptEncryptor;
|
||||
import top.continew.admin.common.enums.DisEnableStatusEnum;
|
||||
import top.continew.admin.common.enums.GenderEnum;
|
||||
import top.continew.starter.extension.crud.annotation.DictField;
|
||||
import top.continew.starter.extension.crud.annotation.DictModel;
|
||||
import top.continew.admin.common.model.entity.BaseDO;
|
||||
import top.continew.starter.security.crypto.annotation.FieldEncrypt;
|
||||
|
||||
@@ -37,7 +37,7 @@ import java.time.LocalDateTime;
|
||||
* @since 2022/12/21 20:42
|
||||
*/
|
||||
@Data
|
||||
@DictField(labelKey = "nickname", extraKeys = {"username"})
|
||||
@DictModel(labelKey = "nickname", extraKeys = {"username"})
|
||||
@TableName("sys_user")
|
||||
public class UserDO extends BaseDO {
|
||||
|
||||
|
@@ -80,9 +80,6 @@ public class MessageUserServiceImpl implements MessageUserService {
|
||||
|
||||
@Override
|
||||
public void readMessage(List<Long> ids) {
|
||||
if (CollUtil.isEmpty(ids)) {
|
||||
return;
|
||||
}
|
||||
baseMapper.lambdaUpdate()
|
||||
.set(MessageUserDO::getIsRead, true)
|
||||
.set(MessageUserDO::getReadTime, LocalDateTime.now())
|
||||
|
@@ -57,7 +57,7 @@ export function update${classNamePrefix}(data: any, id: string) {
|
||||
|
||||
/** @desc 删除${businessName} */
|
||||
export function delete${classNamePrefix}(id: string) {
|
||||
return http.del(`${'$'}{BASE_URL}/${'$'}{id}`)
|
||||
return http.del(`${'$'}{BASE_URL}/`, { ids: [id] })
|
||||
}
|
||||
|
||||
/** @desc 导出${businessName} */
|
||||
|
@@ -16,6 +16,7 @@
|
||||
|
||||
package top.continew.admin.open.sign;
|
||||
|
||||
import cn.dev33.satoken.secure.SaSecureUtil;
|
||||
import cn.dev33.satoken.sign.SaSignTemplate;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -71,6 +72,6 @@ public class OpenApiSignTemplate extends SaSignTemplate {
|
||||
// 移除 sign 参数
|
||||
paramMap.remove(sign);
|
||||
// 计算签名
|
||||
return super.abstractStr(super.joinParamsDictSort(paramMap));
|
||||
return SaSecureUtil.md5(super.joinParamsDictSort(paramMap));
|
||||
}
|
||||
}
|
||||
|
@@ -116,11 +116,7 @@ public class AuthController {
|
||||
private AuthRequest getAuthRequest(String source) {
|
||||
try {
|
||||
AuthConfig authConfig = authProperties.getType().get(source.toUpperCase());
|
||||
return AuthRequestBuilder
|
||||
.builder()
|
||||
.source(source)
|
||||
.authConfig(authConfig)
|
||||
.build();
|
||||
return AuthRequestBuilder.builder().source(source).authConfig(authConfig).build();
|
||||
} catch (Exception e) {
|
||||
throw new BadRequestException("暂不支持 [%s] 平台账号登录".formatted(source));
|
||||
}
|
||||
|
@@ -30,11 +30,10 @@ import top.continew.admin.system.model.resp.message.MessageUnreadResp;
|
||||
import top.continew.admin.system.service.MessageService;
|
||||
import top.continew.admin.system.service.MessageUserService;
|
||||
import top.continew.starter.extension.crud.model.query.PageQuery;
|
||||
import top.continew.starter.extension.crud.model.req.IdsReq;
|
||||
import top.continew.starter.extension.crud.model.resp.PageResp;
|
||||
import top.continew.starter.log.annotation.Log;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 消息管理 API
|
||||
*
|
||||
@@ -58,24 +57,28 @@ public class MessageController {
|
||||
}
|
||||
|
||||
@Operation(summary = "删除数据", description = "删除数据")
|
||||
@Parameter(name = "ids", description = "ID 列表", example = "1,2", in = ParameterIn.PATH)
|
||||
@DeleteMapping("/{ids}")
|
||||
public void delete(@PathVariable List<Long> ids) {
|
||||
baseService.delete(ids);
|
||||
@DeleteMapping
|
||||
public void delete(@Validated @RequestBody IdsReq req) {
|
||||
baseService.delete(req.getIds());
|
||||
}
|
||||
|
||||
@Operation(summary = "标记已读", description = "将消息标记为已读状态")
|
||||
@Parameter(name = "ids", description = "消息ID列表", example = "1,2", in = ParameterIn.QUERY)
|
||||
@PatchMapping("/read")
|
||||
public void readMessage(@RequestParam(required = false) List<Long> ids) {
|
||||
messageUserService.readMessage(ids);
|
||||
public void read(@Validated @RequestBody IdsReq req) {
|
||||
messageUserService.readMessage(req.getIds());
|
||||
}
|
||||
|
||||
@Operation(summary = "全部已读", description = "将所有消息标记为已读状态")
|
||||
@PatchMapping("/readAll")
|
||||
public void readAll() {
|
||||
messageUserService.readMessage(null);
|
||||
}
|
||||
|
||||
@Log(ignore = true)
|
||||
@Operation(summary = "查询未读消息数量", description = "查询当前用户的未读消息数量")
|
||||
@Parameter(name = "isDetail", description = "是否查询详情", example = "true", in = ParameterIn.QUERY)
|
||||
@GetMapping("/unread")
|
||||
public MessageUnreadResp countUnreadMessage(@RequestParam(required = false) Boolean detail) {
|
||||
public MessageUnreadResp countUnread(@RequestParam(required = false) Boolean detail) {
|
||||
return messageUserService.countUnreadMessageByUserId(UserContextHolder.getUserId(), detail);
|
||||
}
|
||||
}
|
@@ -29,8 +29,8 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import top.continew.admin.common.controller.BaseController;
|
||||
import top.continew.admin.common.constant.RegexConstants;
|
||||
import top.continew.admin.common.controller.BaseController;
|
||||
import top.continew.admin.common.util.SecureUtils;
|
||||
import top.continew.admin.system.model.query.UserQuery;
|
||||
import top.continew.admin.system.model.req.user.UserImportReq;
|
||||
@@ -46,7 +46,7 @@ import top.continew.starter.core.util.ExceptionUtils;
|
||||
import top.continew.starter.core.validation.ValidationUtils;
|
||||
import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
|
||||
import top.continew.starter.extension.crud.enums.Api;
|
||||
import top.continew.starter.extension.crud.model.resp.BaseIdResp;
|
||||
import top.continew.starter.extension.crud.model.resp.IdResp;
|
||||
import top.continew.starter.extension.crud.validation.CrudValidationGroup;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -67,7 +67,7 @@ public class UserController extends BaseController<UserService, UserResp, UserDe
|
||||
|
||||
@Override
|
||||
@Operation(summary = "新增数据", description = "新增数据")
|
||||
public BaseIdResp<Long> create(@Validated(CrudValidationGroup.Create.class) @RequestBody UserReq req) {
|
||||
public IdResp<Long> create(@Validated(CrudValidationGroup.Create.class) @RequestBody UserReq req) {
|
||||
String rawPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(req.getPassword()));
|
||||
ValidationUtils.throwIfNull(rawPassword, "密码解密失败");
|
||||
ValidationUtils.throwIf(!ReUtil
|
||||
|
@@ -5,5 +5,5 @@
|
||||
\____|\___/ |_| |_| \__||_||_| \_| \___| \_/\_/ /_/ \_\\__,_||_| |_| |_||_||_| |_|
|
||||
|
||||
:: ${project.name} :: v${project.version}
|
||||
:: ContiNew Starter :: v2.10.0
|
||||
:: ContiNew Starter :: v2.11.0
|
||||
:: Spring Boot :: v${spring-boot.version}
|
||||
|
Reference in New Issue
Block a user