feat(core): 新增项目及相关功能的数据访问层和权限控制切面
- 添加多个Mapper接口及XML文件支持项目、成员、里程碑、任务、风险、资源、 文件附件等模块的数据操作和查询功能,支持复杂查询与统计 - 新增Sa-Token权限配置,集成统一认证管理 - 引入权限常量类,定义系统角色、项目角色及权限编码标准 - 新增项目权限校验切面,实现基于注解的项目权限和角色校验逻辑 - 更新配置文件和依赖,集成MyBatis Plus、MinIO、Spring AI及文档解析相关库 - 调整MyBatis配置的类型别名包路径,统一领域实体引用路径
This commit is contained in:
6
pom.xml
6
pom.xml
@@ -40,6 +40,12 @@
|
|||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring AOP(包含 AspectJ,支持 @Aspect 切面) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!--hutool all-->
|
<!--hutool all-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package cn.yinlihupo.common.aspect;
|
|||||||
|
|
||||||
import cn.yinlihupo.common.annotation.RequireProjectPermission;
|
import cn.yinlihupo.common.annotation.RequireProjectPermission;
|
||||||
import cn.yinlihupo.common.annotation.RequireProjectRole;
|
import cn.yinlihupo.common.annotation.RequireProjectRole;
|
||||||
|
import cn.yinlihupo.common.enums.ErrorCode;
|
||||||
import cn.yinlihupo.common.exception.BusinessException;
|
import cn.yinlihupo.common.exception.BusinessException;
|
||||||
import cn.yinlihupo.common.util.SecurityUtils;
|
import cn.yinlihupo.common.util.SecurityUtils;
|
||||||
import cn.yinlihupo.service.system.ProjectPermissionService;
|
import cn.yinlihupo.service.system.ProjectPermissionService;
|
||||||
@@ -41,7 +42,7 @@ public class ProjectPermissionAspect {
|
|||||||
|
|
||||||
Long userId = SecurityUtils.getCurrentUserId();
|
Long userId = SecurityUtils.getCurrentUserId();
|
||||||
if (userId == null) {
|
if (userId == null) {
|
||||||
throw new BusinessException(403, "用户未登录");
|
throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR, "用户未登录");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 管理员直接放行
|
// 管理员直接放行
|
||||||
@@ -52,7 +53,7 @@ public class ProjectPermissionAspect {
|
|||||||
// 获取项目ID
|
// 获取项目ID
|
||||||
Long projectId = extractProjectId(joinPoint, annotation.projectIdParam());
|
Long projectId = extractProjectId(joinPoint, annotation.projectIdParam());
|
||||||
if (projectId == null) {
|
if (projectId == null) {
|
||||||
throw new BusinessException(400, "无法获取项目ID");
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "无法获取项目ID");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 校验权限
|
// 校验权限
|
||||||
@@ -61,7 +62,7 @@ public class ProjectPermissionAspect {
|
|||||||
|
|
||||||
if (!hasPermission) {
|
if (!hasPermission) {
|
||||||
log.warn("用户 [{}] 没有项目 [{}] 的权限 [{}]", userId, projectId, requiredPermission);
|
log.warn("用户 [{}] 没有项目 [{}] 的权限 [{}]", userId, projectId, requiredPermission);
|
||||||
throw new BusinessException(403, annotation.message());
|
throw new BusinessException(ErrorCode.FORBIDDEN_ERROR, annotation.message());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +77,7 @@ public class ProjectPermissionAspect {
|
|||||||
|
|
||||||
Long userId = SecurityUtils.getCurrentUserId();
|
Long userId = SecurityUtils.getCurrentUserId();
|
||||||
if (userId == null) {
|
if (userId == null) {
|
||||||
throw new BusinessException(403, "用户未登录");
|
throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR, "用户未登录");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 管理员直接放行(如果允许)
|
// 管理员直接放行(如果允许)
|
||||||
@@ -87,13 +88,13 @@ public class ProjectPermissionAspect {
|
|||||||
// 获取项目ID
|
// 获取项目ID
|
||||||
Long projectId = extractProjectId(joinPoint, annotation.projectIdParam());
|
Long projectId = extractProjectId(joinPoint, annotation.projectIdParam());
|
||||||
if (projectId == null) {
|
if (projectId == null) {
|
||||||
throw new BusinessException(400, "无法获取项目ID");
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "无法获取项目ID");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取用户项目角色
|
// 获取用户项目角色
|
||||||
String userRole = projectPermissionService.getUserProjectRole(userId, projectId);
|
String userRole = projectPermissionService.getUserProjectRole(userId, projectId);
|
||||||
if (userRole == null) {
|
if (userRole == null) {
|
||||||
throw new BusinessException(403, "您不是该项目的成员");
|
throw new BusinessException(ErrorCode.FORBIDDEN_ERROR, "您不是该项目的成员");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 校验角色
|
// 校验角色
|
||||||
@@ -109,7 +110,7 @@ public class ProjectPermissionAspect {
|
|||||||
if (!hasRole) {
|
if (!hasRole) {
|
||||||
log.warn("用户 [{}] 在项目 [{}] 中的角色 [{}] 不符合要求 {}",
|
log.warn("用户 [{}] 在项目 [{}] 中的角色 [{}] 不符合要求 {}",
|
||||||
userId, projectId, userRole, requiredRoles);
|
userId, projectId, userRole, requiredRoles);
|
||||||
throw new BusinessException(403, annotation.message());
|
throw new BusinessException(ErrorCode.FORBIDDEN_ERROR, annotation.message());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,20 +16,6 @@ spring:
|
|||||||
idle-timeout: 300000
|
idle-timeout: 300000
|
||||||
connection-timeout: 20000
|
connection-timeout: 20000
|
||||||
|
|
||||||
# MyBatis Plus 配置
|
|
||||||
mybatis-plus:
|
|
||||||
mapper-locations: classpath*:/mapper/**/*.xml
|
|
||||||
type-aliases-package: cn.yinlihupo.domain.entity
|
|
||||||
configuration:
|
|
||||||
map-underscore-to-camel-case: true
|
|
||||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
|
||||||
global-config:
|
|
||||||
db-config:
|
|
||||||
id-type: auto
|
|
||||||
logic-delete-field: deleted
|
|
||||||
logic-delete-value: 1
|
|
||||||
logic-not-delete-value: 0
|
|
||||||
|
|
||||||
ai:
|
ai:
|
||||||
openai:
|
openai:
|
||||||
api-key: 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
|
api-key: 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
|
||||||
@@ -45,9 +31,23 @@ minio:
|
|||||||
secret-key: minioadmin
|
secret-key: minioadmin
|
||||||
bucket-name: ylhp-files
|
bucket-name: ylhp-files
|
||||||
|
|
||||||
|
# MyBatis Plus 配置
|
||||||
|
mybatis-plus:
|
||||||
|
mapper-locations: classpath*:/mapper/**/*.xml
|
||||||
|
type-aliases-package: cn.yinlihupo.domain.entity
|
||||||
|
configuration:
|
||||||
|
map-underscore-to-camel-case: true
|
||||||
|
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||||
|
global-config:
|
||||||
|
db-config:
|
||||||
|
id-type: auto
|
||||||
|
logic-delete-field: deleted
|
||||||
|
logic-delete-value: 1
|
||||||
|
logic-not-delete-value: 0
|
||||||
|
|
||||||
# 日志配置
|
# 日志配置
|
||||||
logging:
|
logging:
|
||||||
level:
|
level:
|
||||||
root: INFO
|
root: INFO
|
||||||
cn.yinlihupo.ylhpaiprojectmanager: DEBUG
|
cn.yinlihupo: DEBUG
|
||||||
org.springframework.web: DEBUG
|
org.springframework.web: DEBUG
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ spring:
|
|||||||
|
|
||||||
# 公共配置
|
# 公共配置
|
||||||
server:
|
server:
|
||||||
port: 8080
|
port: 8088
|
||||||
|
|
||||||
# Sa-Token 配置
|
# Sa-Token 配置
|
||||||
sa-token:
|
sa-token:
|
||||||
@@ -19,7 +19,7 @@ sa-token:
|
|||||||
# Token 有效期(单位:秒)默认30天,-1代表永不过期
|
# Token 有效期(单位:秒)默认30天,-1代表永不过期
|
||||||
timeout: 2592000
|
timeout: 2592000
|
||||||
# Token 临时有效期(指定时间内无操作就视为token过期)单位:秒
|
# Token 临时有效期(指定时间内无操作就视为token过期)单位:秒
|
||||||
activity-timeout: -1
|
active-timeout: -1
|
||||||
# 是否允许同一账号并发登录(为true时允许一起登录,为false时新登录挤掉旧登录)
|
# 是否允许同一账号并发登录(为true时允许一起登录,为false时新登录挤掉旧登录)
|
||||||
is-concurrent: true
|
is-concurrent: true
|
||||||
# 在多人登录同一账号时,是否共用一个token(为true时所有登录共用一个token,为false时每次登录新建一个token)
|
# 在多人登录同一账号时,是否共用一个token(为true时所有登录共用一个token,为false时每次登录新建一个token)
|
||||||
|
|||||||
Reference in New Issue
Block a user