{
+ @Select("SELECT MAX(CAST(code AS UNSIGNED)) FROM app_application")
+ Integer getMaxCode();
+}
diff --git a/backend/src/main/java/com/stdproject/mapper/ModuleMapper.java b/backend/src/main/java/com/stdproject/mapper/ModuleMapper.java
new file mode 100644
index 0000000..734c0bf
--- /dev/null
+++ b/backend/src/main/java/com/stdproject/mapper/ModuleMapper.java
@@ -0,0 +1,17 @@
+package com.stdproject.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import com.stdproject.entity.Module;
+/**
+ *
+ * 应用_系统模块 Mapper 接口
+ *
+ *
+ * @author zhengsl
+ * @since 2025-03-25
+ */
+@Mapper
+public interface ModuleMapper extends BaseMapper {
+
+}
diff --git a/backend/src/main/java/com/stdproject/service/CustomUserDetailsService.java b/backend/src/main/java/com/stdproject/service/CustomUserDetailsService.java
new file mode 100644
index 0000000..d48b2fc
--- /dev/null
+++ b/backend/src/main/java/com/stdproject/service/CustomUserDetailsService.java
@@ -0,0 +1,147 @@
+package com.stdproject.service;
+
+import com.stdproject.entity.LoginUser;
+import com.stdproject.entity.Menu;
+import com.stdproject.entity.Role;
+import com.stdproject.entity.User;
+import com.stdproject.mapper.MenuMapper;
+import com.stdproject.mapper.RoleMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * 自定义用户详情服务
+ * 实现Spring Security的UserDetailsService接口
+ *
+ * @author StdProject
+ */
+@Slf4j
+@Service
+public class CustomUserDetailsService implements UserDetailsService {
+
+ @Autowired
+ private IUserService appUserService;
+
+
+ @Autowired
+ private IMenuService appMenuService;
+
+ @Autowired
+ private RoleMapper roleMapper;
+
+ @Autowired
+ private MenuMapper menuMapper;
+
+ @Override
+ public UserDetails loadUserByUsername(String username) {
+ User appUser = appUserService.findByUsername(username);
+ if (appUser == null) {
+ throw new UsernameNotFoundException("用户不存在: " + username);
+ }
+ Collection authorities = buildUserAuthorities(appUser);
+ LoginUser loginUser = new LoginUser(appUser,authorities);
+ return loginUser;
+
+ }
+
+ /**
+ * 构建用户权限
+ *
+ * @param appUser 用户信息
+ * @return 权限集合
+ */
+ private Collection buildUserAuthorities(User appUser) {
+ Set authorities = new HashSet<>();
+
+ try {
+ // 根据用户类型添加基本角色权限
+ if ("0".equals(appUser.getUsertype())) {
+ authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
+ } else {
+ authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
+ }
+
+ // 使用RoleMapper直接查询用户的角色信息
+ List roles = roleMapper.getRoleByUserId(appUser.getId());
+
+ if (!roles.isEmpty()) {
+ // 处理角色权限
+ for (Role role : roles) {
+ if ("1".equals(role.getIsvaild())) {
+ // 添加角色权限,格式:ROLE_角色编码
+ if (StringUtils.hasText(role.getRolecode())) {
+ authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getRolecode().toUpperCase()));
+ }
+ }
+ }
+ // 获取角色ID列表
+ List roleIds = roles.stream()
+ .map(Role::getId)
+ .collect(Collectors.toList());
+
+ // 处理每个角色的菜单权限
+ for (String roleId : roleIds) {
+ // 使用MenuMapper直接查询角色关联的菜单ID
+ List menuIds = menuMapper.selectMenuByRoleId(appUser.getAppId(), roleId);
+
+ if (!menuIds.isEmpty()) {
+ // 查询菜单信息并添加菜单权限
+ List