重新修改了用户权限关联模块功能
This commit is contained in:
parent
90ca2cef2a
commit
c6e7657e62
@ -142,6 +142,13 @@
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.8.8</version>
|
||||
</dependency>
|
||||
|
||||
<!-- fastjson -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.83</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.stdproject.entity.AppOptLog;
|
||||
import com.stdproject.service.IAppOptLogService;
|
||||
import com.stdproject.utils.JwtUtils;
|
||||
import com.stdproject.utils.commonUtils;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
@ -92,8 +93,8 @@ public class OperationLogAspect {
|
||||
optLog.setModule(operationLog.module());
|
||||
optLog.setDescription(operationLog.description());
|
||||
optLog.setMethod(request.getMethod() + " " + request.getRequestURI());
|
||||
optLog.setRequestip(getIpAddress(request));
|
||||
optLog.setBrowser(getBrowser(request));
|
||||
optLog.setRequestip(commonUtils.getIpAddress(request));
|
||||
optLog.setBrowser(commonUtils.getBrowser(request));
|
||||
optLog.setLogtime(LocalDateTime.now());
|
||||
|
||||
// 设置操作用户
|
||||
@ -150,32 +151,5 @@ public class OperationLogAspect {
|
||||
}
|
||||
}
|
||||
|
||||
public static String getBrowser(HttpServletRequest request) {
|
||||
UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
|
||||
Browser browser = userAgent.getBrowser();
|
||||
return browser.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户端IP地址
|
||||
*/
|
||||
private String getIpAddress(HttpServletRequest request) {
|
||||
String ip = request.getHeader("X-Forwarded-For");
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_CLIENT_IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
}
|
||||
|
@ -1,197 +0,0 @@
|
||||
package com.stdproject.config;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.stdproject.entity.User;
|
||||
import com.stdproject.service.IMenuService;
|
||||
import com.stdproject.service.IRoleService;
|
||||
import com.stdproject.service.IUserService;
|
||||
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.List;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 自定义用户详情服务
|
||||
* 实现Spring Security的UserDetailsService接口
|
||||
*
|
||||
* @author StdProject
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class CustomUserDetailsService implements UserDetailsService {
|
||||
|
||||
@Autowired
|
||||
private IUserService appUserService;
|
||||
|
||||
@Autowired
|
||||
private IRoleService appRoleService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private IMenuService appMenuService;
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
log.debug("加载用户信息: {}", username);
|
||||
User appUser = appUserService.findByUsername(username);
|
||||
if (appUser == null) {
|
||||
log.warn("用户不存在: {}", username);
|
||||
throw new UsernameNotFoundException("用户不存在: " + username);
|
||||
}
|
||||
|
||||
// 检查用户状态
|
||||
if (!"1".equals(appUser.getStatus())) {
|
||||
log.warn("用户已被禁用: {}", username);
|
||||
throw new UsernameNotFoundException("用户已被禁用: " + username);
|
||||
}
|
||||
|
||||
// 构建用户权限
|
||||
Collection<GrantedAuthority> authorities = buildUserAuthorities(appUser);
|
||||
|
||||
return org.springframework.security.core.userdetails.User.builder()
|
||||
.username(appUser.getUsername())
|
||||
.password(appUser.getPassword())
|
||||
.authorities(authorities)
|
||||
.accountExpired(false)
|
||||
.accountLocked(isAccountLocked(appUser))
|
||||
.credentialsExpired(isCredentialsExpired(appUser))
|
||||
.disabled(!"1".equals(appUser.getStatus()))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建用户权限
|
||||
*
|
||||
* @param appUser 用户信息
|
||||
* @return 权限集合
|
||||
*/
|
||||
private Collection<GrantedAuthority> buildUserAuthorities(User appUser) {
|
||||
Set<GrantedAuthority> authorities = new HashSet<>();
|
||||
|
||||
try {
|
||||
// 根据用户类型添加基本角色权限
|
||||
if ("0".equals(appUser.getUsertype())) {
|
||||
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
|
||||
} else {
|
||||
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
|
||||
}
|
||||
|
||||
// 查询用户的角色
|
||||
// QueryWrapper<RoleUser> roleUserQuery = new QueryWrapper<>();
|
||||
// roleUserQuery.eq("userid", appUser.getId());
|
||||
// List<RoleUser> roleUsers = appRoleUserService.list(roleUserQuery);
|
||||
//
|
||||
// if (!roleUsers.isEmpty()) {
|
||||
// // 获取角色ID列表
|
||||
// List<String> roleIds = roleUsers.stream()
|
||||
// .map(AppRoleUser::getRoleid)
|
||||
// .collect(Collectors.toList());
|
||||
//
|
||||
// // 查询角色信息并添加角色权限
|
||||
// List<AppRole> roles = appRoleService.listByIds(roleIds);
|
||||
// for (AppRole role : roles) {
|
||||
// if ("1".equals(role.getIsvaild())) {
|
||||
// // 添加角色权限,格式:ROLE_角色编码
|
||||
// if (StringUtils.hasText(role.getRolecode())) {
|
||||
// authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getRolecode().toUpperCase()));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 查询角色关联的菜单权限
|
||||
// QueryWrapper<AppRoleMenu> roleMenuQuery = new QueryWrapper<>();
|
||||
// roleMenuQuery.in("roleid", roleIds);
|
||||
// List<AppRoleMenu> roleMenus = appRoleMenuService.list(roleMenuQuery);
|
||||
//
|
||||
// if (!roleMenus.isEmpty()) {
|
||||
// // 获取菜单ID列表
|
||||
// List<String> menuIds = roleMenus.stream()
|
||||
// .map(AppRoleMenu::getMenuid)
|
||||
// .distinct()
|
||||
// .collect(Collectors.toList());
|
||||
//
|
||||
// // 查询菜单信息并添加菜单权限
|
||||
// List<AppMenu> menus = appMenuService.listByIds(menuIds);
|
||||
// for (AppMenu menu : menus) {
|
||||
// if ("1".equals(menu.getIsdisplay()) && StringUtils.hasText(menu.getCode())) {
|
||||
// // 添加菜单权限,格式:菜单编码
|
||||
// authorities.add(new SimpleGrantedAuthority(menu.getCode()));
|
||||
//
|
||||
// // 根据菜单类型添加操作权限
|
||||
// String menuCode = menu.getCode();
|
||||
// if (StringUtils.hasText(menuCode)) {
|
||||
// // 为每个菜单添加基本操作权限
|
||||
// authorities.add(new SimpleGrantedAuthority(menuCode + ":list"));
|
||||
// authorities.add(new SimpleGrantedAuthority(menuCode + ":detail"));
|
||||
//
|
||||
// // 管理员拥有所有操作权限
|
||||
// if ("0".equals(appUser.getUsertype())) {
|
||||
// authorities.add(new SimpleGrantedAuthority(menuCode + ":add"));
|
||||
// authorities.add(new SimpleGrantedAuthority(menuCode + ":edit"));
|
||||
// authorities.add(new SimpleGrantedAuthority(menuCode + ":delete"));
|
||||
// authorities.add(new SimpleGrantedAuthority(menuCode + ":permission"));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
log.debug("用户 {} 的权限列表: {}", appUser.getUsername(),
|
||||
authorities.stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()));
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("构建用户权限失败: {}", e.getMessage(), e);
|
||||
// 发生异常时,至少保证基本角色权限
|
||||
authorities.clear();
|
||||
if ("0".equals(appUser.getUsertype())) {
|
||||
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
|
||||
} else {
|
||||
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
|
||||
}
|
||||
}
|
||||
|
||||
return authorities;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查账户是否被锁定
|
||||
*
|
||||
* @param appUser 用户信息
|
||||
* @return 是否被锁定
|
||||
*/
|
||||
private boolean isAccountLocked(User appUser) {
|
||||
// 检查登录失败锁定时间
|
||||
if (appUser.getFailedlocktime() != null) {
|
||||
// 如果锁定时间还未过期,则账户被锁定
|
||||
return appUser.getFailedlocktime().isAfter(java.time.LocalDateTime.now());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查凭证是否过期
|
||||
*
|
||||
* @param appUser 用户信息
|
||||
* @return 是否过期
|
||||
*/
|
||||
private boolean isCredentialsExpired(User appUser) {
|
||||
// 检查密码是否过期
|
||||
if (appUser.getPwdresettime() != null && appUser.getPwdvalidperiod() != null) {
|
||||
java.time.LocalDateTime expireTime = appUser.getPwdresettime().plusDays(appUser.getPwdvalidperiod());
|
||||
return expireTime.isBefore(java.time.LocalDateTime.now());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.stdproject.config;
|
||||
|
||||
import com.stdproject.service.CustomUserDetailsService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@ -11,11 +12,9 @@ import org.springframework.security.config.annotation.method.configuration.Enabl
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.CorsConfigurationSource;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
|
@ -28,6 +28,10 @@ public class WebConfig implements WebMvcConfigurer {
|
||||
return CacheUtil.newTimedCache(jwtExpirationMs);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Cache<String, String> loginuserCache() {
|
||||
return CacheUtil.newLRUCache(200);//用户登录缓存数 缺省200
|
||||
}
|
||||
/**
|
||||
* 静态资源处理
|
||||
*/
|
||||
|
@ -60,7 +60,7 @@ public class MenuController {
|
||||
return ResponseResult.error("没有菜单ID");
|
||||
}
|
||||
//填写 当前用户名称
|
||||
menu.setLastmodifier(AuthUtils.getUser().getUserId().toString());
|
||||
// menu.setLastmodifier(AuthUtils.getUser().getUserId().toString());
|
||||
//填写 当前日期
|
||||
menu.setLastmodifydate(LocalDateTime.now());
|
||||
boolean isOk = menuService.updateById(menu);
|
||||
@ -82,8 +82,9 @@ public class MenuController {
|
||||
***********************************/
|
||||
@PostMapping("/getMenuTree")
|
||||
@ResponseBody
|
||||
public List<Map<String, Object>> getMenuTree(String appId, String name, String isdisplay) {
|
||||
return menuService.getMenuTree(appId, name, isdisplay);
|
||||
public ResponseResult getMenuTree(String appId, String name, String isdisplay) {
|
||||
List<Map<String, Object>> list= menuService.getMenuTree(appId, name, isdisplay);
|
||||
return ResponseResult.successData(list);
|
||||
}
|
||||
|
||||
|
||||
@ -133,7 +134,7 @@ public class MenuController {
|
||||
//根据id 修改是否显示 ,最近修改人,最近修改时间
|
||||
updateWrapper.eq("id", id)
|
||||
.set("isdisplay", isdisplay)
|
||||
.set("lastmodifier", AuthUtils.getUser().getUserId().toString())
|
||||
// .set("lastmodifier", AuthUtils.getUser().getUserId().toString())
|
||||
.set("lastmodifydate", new Timestamp(System.currentTimeMillis()));
|
||||
boolean ok = menuService.update(updateWrapper);
|
||||
if (ok) {
|
||||
@ -157,7 +158,7 @@ public class MenuController {
|
||||
//根据id 修改关联模块ID ,最近修改人,最近修改时间
|
||||
updateWrapper.eq("id", id)
|
||||
.set("module_id", moduleId)
|
||||
.set("lastmodifier", AuthUtils.getUser().getUserId().toString())
|
||||
// .set("lastmodifier", AuthUtils.getUser().getUserId().toString())
|
||||
.set("lastmodifydate", new Timestamp(System.currentTimeMillis()));
|
||||
boolean ok = menuService.update(updateWrapper);
|
||||
if (ok) {
|
||||
@ -176,8 +177,8 @@ public class MenuController {
|
||||
***********************************/
|
||||
@PostMapping("/permissionAssignment")
|
||||
@ResponseBody
|
||||
public List<Map<String, Object>> permissionAssignment(String appId, String roleId) {
|
||||
|
||||
return menuService.permissionAssignment(appId,roleId);
|
||||
public ResponseResult permissionAssignment(String appId, String roleId) {
|
||||
List<Map<String, Object>> list=menuService.permissionAssignment(appId,roleId);
|
||||
return ResponseResult.successData( list);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,60 @@
|
||||
package com.stdproject.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.stdproject.config.ResponseResult;
|
||||
import com.stdproject.entity.Module;
|
||||
import com.stdproject.service.IModuleService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 应用_系统模块 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author zhengsl
|
||||
* @since 2025-03-25
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/module")
|
||||
public class ModuleController {
|
||||
// 添加Service注入
|
||||
@Resource
|
||||
private IModuleService moduleService;
|
||||
|
||||
// 分页查询模块列表
|
||||
@GetMapping("/list")
|
||||
public ResponseResult page(@RequestParam String appId) {
|
||||
QueryWrapper<Module> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("app_id",appId);
|
||||
wrapper.orderByAsc("pid","sort"); // 按编码倒序排列
|
||||
List<Map<String, Object>> list = moduleService.listMaps(wrapper);
|
||||
return ResponseResult.successData(list);
|
||||
}
|
||||
|
||||
// 删除模块
|
||||
@DeleteMapping("/{id}")
|
||||
public ResponseResult remove(@PathVariable String id) {
|
||||
return ResponseResult.successData(moduleService.removeById(id));
|
||||
}
|
||||
|
||||
// 获取模块详情
|
||||
@GetMapping("/{id}")
|
||||
public ResponseResult getById(@PathVariable String id) {
|
||||
Map<String, Object> moduleMap=null;
|
||||
try {
|
||||
LambdaQueryWrapper<Module> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(Module::getId, id);
|
||||
moduleMap = moduleService.getMap(wrapper);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ResponseResult.successData(moduleMap);
|
||||
}
|
||||
|
||||
}
|
@ -69,7 +69,7 @@ public class OrganizationController {
|
||||
return ResponseResult.error("组织信息不能为空");
|
||||
}
|
||||
//填写 最近修改者
|
||||
organization.setLastmodifier(AuthUtils.getUser().getUserId().toString());
|
||||
// organization.setLastmodifier(AuthUtils.getUser().getUserId().toString());
|
||||
//填写 最近修改时间
|
||||
organization.setLastmodifydate(LocalDateTime.now());
|
||||
//根据id 修改系统组织
|
||||
@ -93,8 +93,9 @@ public class OrganizationController {
|
||||
***********************************/
|
||||
@PostMapping("/getOrganizations")
|
||||
@ResponseBody
|
||||
public List<Map<String, Object>> getOrganizations(String appId, String orgtype, String parentid, String orgName) {
|
||||
return organizationService.getOrganizations(appId,orgtype, parentid, orgName);
|
||||
public ResponseResult getOrganizations(String appId, String orgtype, String parentid, String orgName) {
|
||||
List<Map<String, Object>> list=organizationService.getOrganizations(appId,orgtype, parentid, orgName);
|
||||
return ResponseResult.successData(list);
|
||||
}
|
||||
|
||||
/***********************************
|
||||
@ -156,7 +157,7 @@ public class OrganizationController {
|
||||
UpdateWrapper<Organization> updateWrapper = new UpdateWrapper<>();
|
||||
updateWrapper.eq("id", id)
|
||||
.set("isvaild", isvaild)
|
||||
.set("lastmodifier", AuthUtils.getUser().getUserId().toString())
|
||||
// .set("lastmodifier", AuthUtils.getUser().getUserId().toString())
|
||||
.set("lastmodifydate", LocalDateTime.now());
|
||||
boolean isOk = organizationService.update(updateWrapper);
|
||||
if (isOk) {
|
||||
|
@ -63,7 +63,7 @@ public class RoleController {
|
||||
return ResponseResult.error("需要提交角色ID!");
|
||||
}
|
||||
//更新最近修改人
|
||||
role.setLastmodifier(AuthUtils.getUser().getUserId().toString());
|
||||
// role.setLastmodifier(AuthUtils.getUser().getUserId().toString());
|
||||
//更新最近修改时间
|
||||
role.setLastmodifydate(LocalDateTime.now());
|
||||
//根据id更新角色信息
|
||||
@ -84,8 +84,9 @@ public class RoleController {
|
||||
***********************************/
|
||||
@PostMapping("/listRole")
|
||||
@ResponseBody
|
||||
public List<Role> listRole(String appId, String rolename) {
|
||||
return roleService.listRole(appId,rolename);
|
||||
public ResponseResult listRole(String appId, String rolename) {
|
||||
List<Role> list=roleService.listRole(appId,rolename);
|
||||
return ResponseResult.successData( list);
|
||||
}
|
||||
|
||||
/***********************************
|
||||
@ -152,7 +153,7 @@ public class RoleController {
|
||||
//根据id 更新业务范围,最近修改人,最近修改时间
|
||||
updateWrapper.eq("id", id)
|
||||
.set("isvaild", isvaild)
|
||||
.set("lastmodifier", AuthUtils.getUser().getUserId().toString())
|
||||
// .set("lastmodifier", AuthUtils.getUser().getUserId().toString())
|
||||
.set("lastmodifydate",LocalDateTime.now());
|
||||
boolean ok = roleService.update(updateWrapper);
|
||||
if (ok) {
|
||||
|
@ -1,16 +1,42 @@
|
||||
package com.stdproject.controller;
|
||||
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.hutool.jwt.JWTUtil;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.stdproject.config.ResponseResult;
|
||||
import com.stdproject.config.WebConfig;
|
||||
import com.stdproject.entity.AppOptLog;
|
||||
import com.stdproject.entity.LoginUser;
|
||||
import com.stdproject.entity.User;
|
||||
import com.stdproject.service.IAppOptLogService;
|
||||
import com.stdproject.service.IUserService;
|
||||
import com.stdproject.utils.JwtUtils;
|
||||
import com.stdproject.utils.RsaUtils;
|
||||
import com.stdproject.utils.commonUtils;
|
||||
import io.micrometer.common.util.StringUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.DisabledException;
|
||||
import org.springframework.security.authentication.LockedException;
|
||||
import org.springframework.security.authentication.AccountExpiredException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@ -28,6 +54,18 @@ public class UserController {
|
||||
|
||||
@Resource
|
||||
private IUserService userService;
|
||||
@Value("${spring.security.rsa.private-key}")
|
||||
private String privateKey;
|
||||
@Value("${spring.security.jwt.expiration-ms}")
|
||||
private Long jwtExpirationMs;
|
||||
@Autowired
|
||||
private AuthenticationManager authenticationManager;
|
||||
@Autowired
|
||||
private WebConfig webConfig;
|
||||
@Resource
|
||||
private IAppOptLogService sysLogService;
|
||||
@Autowired
|
||||
private JwtUtils jwtUtils;
|
||||
|
||||
/***********************************
|
||||
* 用途说明:新增系统用户
|
||||
@ -70,7 +108,7 @@ public class UserController {
|
||||
***********************************/
|
||||
@GetMapping("/queryUsers")
|
||||
@ResponseBody
|
||||
public ResponseResult queryUsers(String orgid,String appId, String nickname, Page<User> page) {
|
||||
public ResponseResult queryUsers(String orgid, String appId, String nickname, Page<User> page) {
|
||||
Page<Map<String, Object>> mapPage = userService.queryUsers(orgid, appId, nickname, page);
|
||||
return ResponseResult.successData(mapPage);
|
||||
}
|
||||
@ -115,7 +153,6 @@ public class UserController {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************
|
||||
* 用途说明:设置账号状态(管理员)
|
||||
* 参数说明
|
||||
@ -125,7 +162,7 @@ public class UserController {
|
||||
************************************/
|
||||
@PostMapping("/setStatus")
|
||||
@ResponseBody
|
||||
public ResponseResult setStatus(@RequestParam String id,@RequestParam String status) {
|
||||
public ResponseResult setStatus(@RequestParam String id, @RequestParam String status) {
|
||||
if (StringUtils.isEmpty(id)) {
|
||||
return ResponseResult.error("用户ID为空");
|
||||
}
|
||||
@ -159,22 +196,91 @@ public class UserController {
|
||||
return ResponseResult.error();
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/login")
|
||||
@ResponseBody
|
||||
public ResponseResult login(String appid,String username, String password) {
|
||||
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
|
||||
return ResponseResult.error("用户名称或者密码不能为空!");
|
||||
public ResponseResult login(String username, String password) throws Exception {
|
||||
try {
|
||||
// 密码解密
|
||||
String encrypt_password = RsaUtils.decryptByPrivateKey(privateKey, password);
|
||||
//如果认证通过了,使用userId生成token token存入ResponseResult返回
|
||||
UsernamePasswordAuthenticationToken authenticationToken =
|
||||
new UsernamePasswordAuthenticationToken(username,
|
||||
encrypt_password);
|
||||
Authentication authenticate =
|
||||
authenticationManager.authenticate(authenticationToken);
|
||||
LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
|
||||
// 获取请求信息
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
HttpServletRequest request = attributes.getRequest();
|
||||
AppOptLog sysLog = new AppOptLog();
|
||||
sysLog.setUsercode(username);
|
||||
sysLog.setUsername(loginUser.getUser().getNickname());
|
||||
sysLog.setRequestip(commonUtils.getIpAddress(request));
|
||||
sysLog.setBrowser(commonUtils.getBrowser(request));
|
||||
sysLog.setOpttype("登录(login)");
|
||||
sysLog.setModule("用户登录");
|
||||
String className = this.getClass().getName();
|
||||
String method =
|
||||
Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||
sysLog.setMethod(className + "." + method + "()");
|
||||
//sysLog.setParams(user.toString());
|
||||
sysLog.setDescription(loginUser.getUser().getNickname() + "登录系统!");
|
||||
sysLog.setLogtime(LocalDateTime.now());
|
||||
sysLogService.save(sysLog);
|
||||
String userId = loginUser.getUser().getId();
|
||||
long expireTime = System.currentTimeMillis() + jwtExpirationMs;
|
||||
Map<String, Object> map = new HashMap();
|
||||
map.put("userid", userId);
|
||||
map.put("username", loginUser.getUsername());
|
||||
map.put("expire_time", expireTime);
|
||||
String token = jwtUtils.generateToken(loginUser.getUsername(), userId);
|
||||
map.put("token", token);
|
||||
//把完整的用户信息存入到HuTool缓存中,userId作为key
|
||||
String jsonStr = JSONUtil.toJsonStr(loginUser);
|
||||
webConfig.loginuserCache().put("login:" + userId, jsonStr);
|
||||
return ResponseResult.successData(map);
|
||||
}
|
||||
// 根据用户名查询用户
|
||||
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
|
||||
User user = userService.getOne(queryWrapper.eq("app_id",appid).eq("username", username));
|
||||
if (ObjUtil.isEmpty( user)) {
|
||||
return ResponseResult.error(String.format("%s您输入的用户账号不存在!", username));
|
||||
}
|
||||
if(password.equals(user.getPassword())){
|
||||
return ResponseResult.successData(user);
|
||||
}else{
|
||||
return ResponseResult.error("您输入的密码错误!");
|
||||
catch (BadCredentialsException e) {
|
||||
// 账号密码验证错误
|
||||
return ResponseResult.error("账号或密码错误,请检查!");
|
||||
} catch (DisabledException e) {
|
||||
// 账号已停用
|
||||
return ResponseResult.error("账号已停用,不能登录!");
|
||||
} catch (LockedException e) {
|
||||
// 账号被锁定
|
||||
return ResponseResult.error("账号被锁定,不能登录!");
|
||||
} catch (AccountExpiredException e) {
|
||||
// 账号已过期
|
||||
return ResponseResult.error("账号密码已过有效期,不能登录!");
|
||||
} catch (AuthenticationException e) {
|
||||
// 捕获其他认证异常
|
||||
return ResponseResult.error("认证失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
@PostMapping("/logout")
|
||||
@ResponseBody
|
||||
public ResponseResult logout() {
|
||||
//获取SecurityContextHolder中的用户id
|
||||
UsernamePasswordAuthenticationToken authentication =
|
||||
(UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
||||
LoginUser loginuser = (LoginUser) authentication.getPrincipal();
|
||||
String userId = loginuser.getUser().getId();
|
||||
//删除redis中的登陆用户信息
|
||||
webConfig.loginuserCache().remove("login:" + userId);
|
||||
//记录退出日志
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
HttpServletRequest request = attributes.getRequest();
|
||||
AppOptLog sysLog = new AppOptLog();
|
||||
sysLog.setUsercode(loginuser.getUsername());
|
||||
sysLog.setUsername(loginuser.getUser().getNickname());
|
||||
sysLog.setRequestip(commonUtils.getIpAddress(request));
|
||||
sysLog.setBrowser(commonUtils.getBrowser(request));
|
||||
sysLog.setOpttype("其他(other)");
|
||||
sysLog.setModule("注销退出");
|
||||
sysLog.setDescription("注销退出系统!");
|
||||
sysLog.setLogtime(LocalDateTime.now());
|
||||
sysLogService.save(sysLog);
|
||||
return ResponseResult.success();
|
||||
}
|
||||
}
|
||||
|
109
backend/src/main/java/com/stdproject/entity/Application.java
Normal file
109
backend/src/main/java/com/stdproject/entity/Application.java
Normal file
@ -0,0 +1,109 @@
|
||||
package com.stdproject.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 应用系统
|
||||
* </p>
|
||||
*
|
||||
* @author zhengsl
|
||||
* @since 2025-03-24
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("app_application")
|
||||
public class Application implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 应用类型 01-数据展示分析
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 应用编号 自动生成:000001
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 应用名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 应用简称
|
||||
*/
|
||||
private String simplename;
|
||||
|
||||
/**
|
||||
* 创建日期
|
||||
*/
|
||||
private LocalDateTime createdate;
|
||||
|
||||
/**
|
||||
* 应用描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 应用图片 base64存储
|
||||
*/
|
||||
private String image;
|
||||
|
||||
/**
|
||||
* 应用配置 JSON格式存储其他配置相关信息
|
||||
*/
|
||||
private String appconfig;
|
||||
|
||||
/**
|
||||
* 数据库配置 JSON格式存储数据库信息配置(数据库用于存储此应用系统的所有配置数据)
|
||||
*/
|
||||
private String dbconfig;
|
||||
|
||||
/**
|
||||
* 用户单位 使用这个应用系统的组织单位
|
||||
*/
|
||||
private String organization;
|
||||
|
||||
/**
|
||||
* 状态 01-初始创建 02-正常运行 09-已停用
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 最近修改者
|
||||
*/
|
||||
private String lastmodifier;
|
||||
|
||||
/**
|
||||
* 最近修改日期
|
||||
*/
|
||||
private LocalDateTime lastmodifydate;
|
||||
|
||||
/**
|
||||
* 备用1
|
||||
*/
|
||||
private String custom1;
|
||||
|
||||
/**
|
||||
* 备用2
|
||||
*/
|
||||
private String custom2;
|
||||
|
||||
/**
|
||||
* 备用3
|
||||
*/
|
||||
private String custom3;
|
||||
}
|
178
backend/src/main/java/com/stdproject/entity/Module.java
Normal file
178
backend/src/main/java/com/stdproject/entity/Module.java
Normal file
@ -0,0 +1,178 @@
|
||||
package com.stdproject.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 应用_系统模块
|
||||
* </p>
|
||||
*
|
||||
* @author zhengsl
|
||||
* @since 2025-03-25
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("app_module")
|
||||
public class Module implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 应用ID 关联应用系统
|
||||
*/
|
||||
private String appId;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 父级ID 父级模块
|
||||
*/
|
||||
@TableField(value = "pid", jdbcType = JdbcType.VARCHAR)
|
||||
private String pid;
|
||||
|
||||
/**
|
||||
* 层级
|
||||
*/
|
||||
private Integer level;
|
||||
|
||||
/**
|
||||
* 节点类型 01-目录 02-模块
|
||||
*/
|
||||
private String nodeType;
|
||||
|
||||
/**
|
||||
* 类型 01-数据大屏 02-数据看板 03-弹窗页面 04-填报页面 06-移动端界面 09-自定义页面
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 样式数据
|
||||
*/
|
||||
@TableField(value = "canvas_style_data", jdbcType = JdbcType.VARCHAR)
|
||||
private String canvasStyleData;
|
||||
|
||||
/**
|
||||
* 组件数据
|
||||
*/
|
||||
@TableField(value = "component_data", jdbcType = JdbcType.VARCHAR)
|
||||
private String componentData;
|
||||
|
||||
/**
|
||||
* 状态 0-未发布 1-已发布
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 是否单独打开水印 0-关闭 1-开启
|
||||
*/
|
||||
private Integer selfWatermarkStatus;
|
||||
|
||||
/**
|
||||
* 排序 目录内的排序号
|
||||
*/
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 更新人
|
||||
*/
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 数据来源
|
||||
*/
|
||||
private String source;
|
||||
|
||||
/**
|
||||
* 删除标志
|
||||
*/
|
||||
private Byte deleteFlag;
|
||||
|
||||
/**
|
||||
* 删除时间
|
||||
*/
|
||||
private LocalDateTime deleteTime;
|
||||
|
||||
/**
|
||||
* 删除人
|
||||
*/
|
||||
private String deleteBy;
|
||||
|
||||
/**
|
||||
* 可视化资源版本
|
||||
*/
|
||||
private Integer version;
|
||||
|
||||
/**
|
||||
* 内容标识
|
||||
*/
|
||||
private String contentId;
|
||||
|
||||
/**
|
||||
* 内容检查标识
|
||||
*/
|
||||
private String checkVersion;
|
||||
|
||||
/**
|
||||
* 备用1
|
||||
*/
|
||||
private String custom1;
|
||||
|
||||
/**
|
||||
* 备用2
|
||||
*/
|
||||
private String custom2;
|
||||
|
||||
/**
|
||||
* 备用3
|
||||
*/
|
||||
private String custom3;
|
||||
|
||||
public Module(String appId, String name, String pid, Integer level, String nodeType, String type, Integer status, Integer sort, LocalDateTime createTime, String createBy){
|
||||
|
||||
this.appId = appId;
|
||||
this.name = name;
|
||||
this.pid = pid;
|
||||
this.level = level;
|
||||
this.nodeType = nodeType;
|
||||
this.type = type;
|
||||
this.status = status;
|
||||
this.sort = sort;
|
||||
this.createTime = createTime;
|
||||
this.createBy = createBy;
|
||||
};
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.stdproject.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
import com.stdproject.entity.Application;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 应用系统 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author zhengsl
|
||||
* @since 2025-03-24
|
||||
*/
|
||||
@Mapper
|
||||
public interface ApplicationMapper extends BaseMapper<Application> {
|
||||
@Select("SELECT MAX(CAST(code AS UNSIGNED)) FROM app_application")
|
||||
Integer getMaxCode();
|
||||
}
|
@ -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;
|
||||
/**
|
||||
* <p>
|
||||
* 应用_系统模块 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author zhengsl
|
||||
* @since 2025-03-25
|
||||
*/
|
||||
@Mapper
|
||||
public interface ModuleMapper extends BaseMapper<Module> {
|
||||
|
||||
}
|
@ -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<GrantedAuthority> authorities = buildUserAuthorities(appUser);
|
||||
LoginUser loginUser = new LoginUser(appUser,authorities);
|
||||
return loginUser;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建用户权限
|
||||
*
|
||||
* @param appUser 用户信息
|
||||
* @return 权限集合
|
||||
*/
|
||||
private Collection<GrantedAuthority> buildUserAuthorities(User appUser) {
|
||||
Set<GrantedAuthority> authorities = new HashSet<>();
|
||||
|
||||
try {
|
||||
// 根据用户类型添加基本角色权限
|
||||
if ("0".equals(appUser.getUsertype())) {
|
||||
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
|
||||
} else {
|
||||
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
|
||||
}
|
||||
|
||||
// 使用RoleMapper直接查询用户的角色信息
|
||||
List<Role> 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<String> roleIds = roles.stream()
|
||||
.map(Role::getId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 处理每个角色的菜单权限
|
||||
for (String roleId : roleIds) {
|
||||
// 使用MenuMapper直接查询角色关联的菜单ID
|
||||
List<String> menuIds = menuMapper.selectMenuByRoleId(appUser.getAppId(), roleId);
|
||||
|
||||
if (!menuIds.isEmpty()) {
|
||||
// 查询菜单信息并添加菜单权限
|
||||
List<Menu> menus = appMenuService.listByIds(menuIds);
|
||||
for (Menu menu : menus) {
|
||||
if ("1".equals(menu.getIsdisplay()) && StringUtils.hasText(menu.getCode())) {
|
||||
// 添加菜单权限,格式:菜单编码
|
||||
authorities.add(new SimpleGrantedAuthority(menu.getCode()));
|
||||
|
||||
// 根据菜单类型添加操作权限
|
||||
String menuCode = menu.getCode();
|
||||
if (StringUtils.hasText(menuCode)) {
|
||||
// 为每个菜单添加基本操作权限
|
||||
authorities.add(new SimpleGrantedAuthority(menuCode + ":list"));
|
||||
authorities.add(new SimpleGrantedAuthority(menuCode + ":detail"));
|
||||
|
||||
// 管理员拥有所有操作权限
|
||||
if ("0".equals(appUser.getUsertype())) {
|
||||
authorities.add(new SimpleGrantedAuthority(menuCode + ":add"));
|
||||
authorities.add(new SimpleGrantedAuthority(menuCode + ":edit"));
|
||||
authorities.add(new SimpleGrantedAuthority(menuCode + ":delete"));
|
||||
authorities.add(new SimpleGrantedAuthority(menuCode + ":permission"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.debug("用户 {} 的权限列表: {}", appUser.getUsername(),
|
||||
authorities.stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()));
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("构建用户权限失败: {}", e.getMessage(), e);
|
||||
// 发生异常时,至少保证基本角色权限
|
||||
authorities.clear();
|
||||
if ("0".equals(appUser.getUsertype())) {
|
||||
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
|
||||
} else {
|
||||
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
|
||||
}
|
||||
}
|
||||
|
||||
return authorities;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.stdproject.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.stdproject.entity.Application;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 应用系统 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author zhengsl
|
||||
* @since 2025-03-24
|
||||
*/
|
||||
public interface IApplicationService extends IService<Application> {
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.stdproject.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.stdproject.entity.Module;
|
||||
/**
|
||||
* <p>
|
||||
* 应用_系统模块 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author zhengsl
|
||||
* @since 2025-03-25
|
||||
*/
|
||||
public interface IModuleService extends IService<Module> {
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.stdproject.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.stdproject.entity.Application;
|
||||
import com.stdproject.mapper.ApplicationMapper;
|
||||
import com.stdproject.service.IApplicationService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 应用系统 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author zhengsl
|
||||
* @since 2025-03-24
|
||||
*/
|
||||
@Service
|
||||
public class ApplicationServiceImpl extends ServiceImpl<ApplicationMapper, Application> implements IApplicationService {
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.stdproject.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.stdproject.entity.Module;
|
||||
import com.stdproject.mapper.ModuleMapper;
|
||||
import com.stdproject.service.IModuleService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 应用_系统模块 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author zhengsl
|
||||
* @since 2025-03-25
|
||||
*/
|
||||
@Service
|
||||
public class ModuleServiceImpl extends ServiceImpl<ModuleMapper, Module> implements IModuleService {
|
||||
|
||||
|
||||
}
|
@ -166,7 +166,7 @@ public class OrganizationServiceImpl extends ServiceImpl<OrganizationMapper, Org
|
||||
//填写 编号
|
||||
organization.setOrgcode(code);
|
||||
//填写 当前用户名称
|
||||
organization.setLastmodifier(AuthUtils.getUser().getUserId().toString());
|
||||
// organization.setLastmodifier(AuthUtils.getUser().getUserId().toString());
|
||||
//填写 当前日期
|
||||
organization.setLastmodifydate(LocalDateTime.now());
|
||||
|
||||
|
@ -77,7 +77,7 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR
|
||||
role.setIsvaild("1");
|
||||
}
|
||||
//添加最近修改者
|
||||
role.setLastmodifier(AuthUtils.getUser().getUserId().toString());
|
||||
// role.setLastmodifier(AuthUtils.getUser().getUserId().toString());
|
||||
//添加最近修改时间
|
||||
role.setLastmodifydate(LocalDateTime.now());
|
||||
return this.save(role);
|
||||
|
@ -12,6 +12,7 @@ import com.stdproject.entity.User; // 确保 User 类存在并路径正确
|
||||
import com.stdproject.mapper.RoleMapper;
|
||||
import com.stdproject.mapper.UserMapper;
|
||||
import com.stdproject.service.IUserService; // 确保接口存在
|
||||
import com.stdproject.utils.EncryptUtils;
|
||||
import io.gisbi.utils.AuthUtils;
|
||||
import io.gisbi.utils.RsaUtils;
|
||||
import io.micrometer.common.util.StringUtils;
|
||||
@ -64,12 +65,12 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU
|
||||
Map<String, String> result = new HashMap<>();
|
||||
//普通用户
|
||||
//设置缺省密码
|
||||
String cryptPassword = RsaUtils.encryptStr(PASSWORD_VALID);
|
||||
String cryptPassword = EncryptUtils.md5(PASSWORD_VALID);;
|
||||
user.setPassword(cryptPassword);
|
||||
//最近修改日期
|
||||
user.setLastmodifydate(LocalDateTime.now());
|
||||
//最近修改者
|
||||
user.setLastmodifier(AuthUtils.getUser().getUserId().toString());
|
||||
// user.setLastmodifier(AuthUtils.getUser().getUserId().toString());
|
||||
//账号有效 状态 1-有效 0-停用
|
||||
user.setStatus(DEFAULT_IS_VALID);
|
||||
//判断注册的登录账号是否存在
|
||||
@ -274,8 +275,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU
|
||||
String cryptPassword = PASSWORD_VALID;
|
||||
updateWrapper.eq("id", id).set("password", cryptPassword)
|
||||
.set("pwdresettime", LocalDateTime.now())
|
||||
.set("lastmodifydate", LocalDateTime.now())
|
||||
.set("lastmodifier", AuthUtils.getUser().getUserId().toString());
|
||||
.set("lastmodifydate", LocalDateTime.now());
|
||||
// .set("lastmodifier", AuthUtils.getUser().getUserId().toString());
|
||||
//是否修改成功
|
||||
isOk = this.update(updateWrapper);
|
||||
return isOk;
|
||||
@ -295,8 +296,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU
|
||||
//根据id修改用户状态,最近修改人,最近修改时间
|
||||
updateWrapper.eq("id", id)
|
||||
.set("status", status)
|
||||
.set("lastmodifydate", LocalDateTime.now())
|
||||
.set("lastmodifier", AuthUtils.getUser().getUserId().toString());
|
||||
.set("lastmodifydate", LocalDateTime.now());
|
||||
// .set("lastmodifier", AuthUtils.getUser().getUserId().toString());
|
||||
//是否修改成功
|
||||
isOk = this.update(updateWrapper);
|
||||
return isOk;
|
||||
|
183
backend/src/main/java/com/stdproject/utils/RsaUtils.java
Normal file
183
backend/src/main/java/com/stdproject/utils/RsaUtils.java
Normal file
@ -0,0 +1,183 @@
|
||||
package com.stdproject.utils;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.security.*;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
/**
|
||||
* @author https://www.cnblogs.com/nihaorz/p/10690643.html
|
||||
* @description Rsa 工具类,公钥私钥生成,加解密
|
||||
* @date 2020-05-18
|
||||
**/
|
||||
public class RsaUtils {
|
||||
|
||||
private static final String SRC = "123456";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("\n");
|
||||
RsaKeyPair keyPair = generateKeyPair();
|
||||
System.out.println("公钥:" + keyPair.getPublicKey());
|
||||
System.out.println("私钥:" + keyPair.getPrivateKey());
|
||||
System.out.println("\n");
|
||||
test1(keyPair);
|
||||
System.out.println("\n");
|
||||
test2(keyPair);
|
||||
System.out.println("\n");
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 公钥加密私钥解密
|
||||
*/
|
||||
private static void test1(RsaKeyPair keyPair) throws Exception {
|
||||
System.out.println("***************** 公钥加密私钥解密开始 *****************");
|
||||
String text1 = encryptByPublicKey(keyPair.getPublicKey(), RsaUtils.SRC);
|
||||
String text2 = decryptByPrivateKey(keyPair.getPrivateKey(), text1);
|
||||
System.out.println("加密前:" + RsaUtils.SRC);
|
||||
System.out.println("加密后:" + text1);
|
||||
System.out.println("解密后:" + text2);
|
||||
if (RsaUtils.SRC.equals(text2)) {
|
||||
System.out.println("解密字符串和原始字符串一致,解密成功");
|
||||
} else {
|
||||
System.out.println("解密字符串和原始字符串不一致,解密失败");
|
||||
}
|
||||
System.out.println("***************** 公钥加密私钥解密结束 *****************");
|
||||
}
|
||||
|
||||
/**
|
||||
* 私钥加密公钥解密
|
||||
* @throws Exception /
|
||||
*/
|
||||
private static void test2(RsaKeyPair keyPair) throws Exception {
|
||||
System.out.println("***************** 私钥加密公钥解密开始 *****************");
|
||||
String text1 = encryptByPrivateKey(keyPair.getPrivateKey(), RsaUtils.SRC);
|
||||
String text2 = decryptByPublicKey(keyPair.getPublicKey(), text1);
|
||||
System.out.println("加密前:" + RsaUtils.SRC);
|
||||
System.out.println("加密后:" + text1);
|
||||
System.out.println("解密后:" + text2);
|
||||
if (RsaUtils.SRC.equals(text2)) {
|
||||
System.out.println("解密字符串和原始字符串一致,解密成功");
|
||||
} else {
|
||||
System.out.println("解密字符串和原始字符串不一致,解密失败");
|
||||
}
|
||||
System.out.println("***************** 私钥加密公钥解密结束 *****************");
|
||||
}
|
||||
|
||||
/**
|
||||
* 公钥解密
|
||||
*
|
||||
* @param publicKeyText 公钥
|
||||
* @param text 待解密的信息
|
||||
* @return /
|
||||
* @throws Exception /
|
||||
*/
|
||||
public static String decryptByPublicKey(String publicKeyText, String text) throws Exception {
|
||||
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText));
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.DECRYPT_MODE, publicKey);
|
||||
byte[] result = cipher.doFinal(Base64.decodeBase64(text));
|
||||
return new String(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 私钥加密
|
||||
*
|
||||
* @param privateKeyText 私钥
|
||||
* @param text 待加密的信息
|
||||
* @return /
|
||||
* @throws Exception /
|
||||
*/
|
||||
public static String encryptByPrivateKey(String privateKeyText, String text) throws Exception {
|
||||
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText));
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
|
||||
byte[] result = cipher.doFinal(text.getBytes());
|
||||
return Base64.encodeBase64String(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 私钥解密
|
||||
*
|
||||
* @param privateKeyText 私钥
|
||||
* @param text 待解密的文本
|
||||
* @return /
|
||||
* @throws Exception /
|
||||
*/
|
||||
public static String decryptByPrivateKey(String privateKeyText, String text) throws Exception {
|
||||
PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText));
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
byte[] result = cipher.doFinal(Base64.decodeBase64(text));
|
||||
return new String(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 公钥加密
|
||||
*
|
||||
* @param publicKeyText 公钥
|
||||
* @param text 待加密的文本
|
||||
* @return /
|
||||
*/
|
||||
public static String encryptByPublicKey(String publicKeyText, String text) throws Exception {
|
||||
X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText));
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||
byte[] result = cipher.doFinal(text.getBytes());
|
||||
return Base64.encodeBase64String(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建RSA密钥对
|
||||
*
|
||||
* @return /
|
||||
* @throws NoSuchAlgorithmException /
|
||||
*/
|
||||
public static RsaKeyPair generateKeyPair() throws NoSuchAlgorithmException {
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
||||
keyPairGenerator.initialize(1024);
|
||||
KeyPair keyPair = keyPairGenerator.generateKeyPair();
|
||||
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
|
||||
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
|
||||
String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded());
|
||||
String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
|
||||
return new RsaKeyPair(publicKeyString, privateKeyString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* RSA密钥对对象
|
||||
*/
|
||||
public static class RsaKeyPair {
|
||||
|
||||
private final String publicKey;
|
||||
private final String privateKey;
|
||||
|
||||
public RsaKeyPair(String publicKey, String privateKey) {
|
||||
this.publicKey = publicKey;
|
||||
this.privateKey = privateKey;
|
||||
}
|
||||
|
||||
public String getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
public String getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
38
backend/src/main/java/com/stdproject/utils/commonUtils.java
Normal file
38
backend/src/main/java/com/stdproject/utils/commonUtils.java
Normal file
@ -0,0 +1,38 @@
|
||||
package com.stdproject.utils;
|
||||
|
||||
import cn.hutool.http.useragent.Browser;
|
||||
import cn.hutool.http.useragent.UserAgent;
|
||||
import cn.hutool.http.useragent.UserAgentUtil;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
public class commonUtils {
|
||||
|
||||
public static String getBrowser(HttpServletRequest request) {
|
||||
UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
|
||||
Browser browser = userAgent.getBrowser();
|
||||
return browser.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户端IP地址
|
||||
*/
|
||||
public static String getIpAddress(HttpServletRequest request) {
|
||||
String ip = request.getHeader("X-Forwarded-For");
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_CLIENT_IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
}
|
@ -12,4 +12,7 @@ JWT_EXPIRATION=86400000
|
||||
SPRING_PROFILES_ACTIVE=dev
|
||||
|
||||
# CORS配置
|
||||
CORS_ALLOWED_ORIGINS=https://your-frontend.com
|
||||
CORS_ALLOWED_ORIGINS=https://your-frontend.com
|
||||
|
||||
# RSA密钥
|
||||
RSA_PRIVATE_KEY = MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A==
|
@ -46,6 +46,8 @@ spring:
|
||||
secret: ${JWT_SECRET:YourJWTSecretKeyForStdProjectBackendApplicationWhichIsVeryLongAndSecure2024!@#$%^&*()}
|
||||
expiration-ms: ${JWT_EXPIRATION:86400000} # Token 过期时间 (例如: 24小时)
|
||||
refresh-expiration-ms: ${JWT_REFRESH_EXPIRATION:604800000} # 刷新Token过期时间 (例如: 7天)
|
||||
rsa:
|
||||
private-key: ${RSA_PRIVATE_KEY:MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A==}
|
||||
|
||||
mybatis-plus:
|
||||
mapper-locations: classpath*:/mapper/**/*.xml # MyBatis Mapper XML文件位置
|
||||
|
44
frontend/components.d.ts
vendored
44
frontend/components.d.ts
vendored
@ -9,55 +9,11 @@ export {}
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
export interface GlobalComponents {
|
||||
ElBreadcrumb: typeof import('element-plus-secondary/es')['ElBreadcrumb']
|
||||
ElBreadcrumbItem: typeof import('element-plus-secondary/es')['ElBreadcrumbItem']
|
||||
ElButton: typeof import('element-plus-secondary/es')['ElButton']
|
||||
ElCard: typeof import('element-plus-secondary/es')['ElCard']
|
||||
ElCheckbox: typeof import('element-plus-secondary/es')['ElCheckbox']
|
||||
ElCheckboxGroup: typeof import('element-plus-secondary/es')['ElCheckboxGroup']
|
||||
ElCol: typeof import('element-plus-secondary/es')['ElCol']
|
||||
ElCollapse: typeof import('element-plus-secondary/es')['ElCollapse']
|
||||
ElCollapseItem: typeof import('element-plus-secondary/es')['ElCollapseItem']
|
||||
ElColorPicker: typeof import('element-plus-secondary/es')['ElColorPicker']
|
||||
ElContainer: typeof import('element-plus-secondary/es')['ElContainer']
|
||||
ElDatePicker: typeof import('element-plus-secondary/es')['ElDatePicker']
|
||||
ElDialog: typeof import('element-plus-secondary/es')['ElDialog']
|
||||
ElDivider: typeof import('element-plus-secondary/es')['ElDivider']
|
||||
ElDropdown: typeof import('element-plus-secondary/es')['ElDropdown']
|
||||
ElDropdownItem: typeof import('element-plus-secondary/es')['ElDropdownItem']
|
||||
ElDropdownMenu: typeof import('element-plus-secondary/es')['ElDropdownMenu']
|
||||
ElEmpty: typeof import('element-plus-secondary/es')['ElEmpty']
|
||||
ElForm: typeof import('element-plus-secondary/es')['ElForm']
|
||||
ElFormItem: typeof import('element-plus-secondary/es')['ElFormItem']
|
||||
ElHeader: typeof import('element-plus-secondary/es')['ElHeader']
|
||||
ElIcon: typeof import('element-plus-secondary/es')['ElIcon']
|
||||
ElInput: typeof import('element-plus-secondary/es')['ElInput']
|
||||
ElInputNumber: typeof import('element-plus-secondary/es')['ElInputNumber']
|
||||
ElMain: typeof import('element-plus-secondary/es')['ElMain']
|
||||
ElOption: typeof import('element-plus-secondary/es')['ElOption']
|
||||
ElOptionGroup: typeof import('element-plus-secondary/es')['ElOptionGroup']
|
||||
ElPopover: typeof import('element-plus-secondary/es')['ElPopover']
|
||||
ElRadio: typeof import('element-plus-secondary/es')['ElRadio']
|
||||
ElRadioGroup: typeof import('element-plus-secondary/es')['ElRadioGroup']
|
||||
ElRow: typeof import('element-plus-secondary/es')['ElRow']
|
||||
ElScrollbar: typeof import('element-plus-secondary/es')['ElScrollbar']
|
||||
ElSelect: typeof import('element-plus-secondary/es')['ElSelect']
|
||||
ElSelectV2: typeof import('element-plus-secondary/es')['ElSelectV2']
|
||||
ElSpace: typeof import('element-plus-secondary/es')['ElSpace']
|
||||
ElSwitch: typeof import('element-plus-secondary/es')['ElSwitch']
|
||||
ElTabPane: typeof import('element-plus-secondary/es')['ElTabPane']
|
||||
ElTabs: typeof import('element-plus-secondary/es')['ElTabs']
|
||||
ElTimeline: typeof import('element-plus-secondary/es')['ElTimeline']
|
||||
ElTimelineItem: typeof import('element-plus-secondary/es')['ElTimelineItem']
|
||||
ElTimePicker: typeof import('element-plus-secondary/es')['ElTimePicker']
|
||||
ElTooltip: typeof import('element-plus-secondary/es')['ElTooltip']
|
||||
ElTree: typeof import('element-plus-secondary/es')['ElTree']
|
||||
ElTreeSelect: typeof import('element-plus-secondary/es')['ElTreeSelect']
|
||||
ElUpload: typeof import('element-plus-secondary/es')['ElUpload']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
}
|
||||
export interface ComponentCustomProperties {
|
||||
vLoading: typeof import('element-plus-secondary/es')['ElLoadingDirective']
|
||||
}
|
||||
}
|
||||
|
@ -11,63 +11,65 @@
|
||||
"format": "prettier --write src/"
|
||||
},
|
||||
"dependencies": {
|
||||
"video.js": "^7.21.6",
|
||||
"@videojs-player/vue": "^1.0.0",
|
||||
"@vueuse/core": "^9.13.0",
|
||||
"@npkg/tinymce-plugins": "^0.0.7",
|
||||
"dayjs": "^1.11.9",
|
||||
"flv.js": "^1.6.2",
|
||||
"html2canvas": "^1.4.1",
|
||||
"jspdf": "^2.5.1",
|
||||
"html-to-image": "^1.11.11",
|
||||
"echarts": "^5.5.1",
|
||||
"file-saver": "^2.0.5",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash-es": "^4.17.21",
|
||||
"mathjs": "^11.6.0",
|
||||
"@antv/g2plot": "^2.4.29",
|
||||
"@antv/l7": "^2.22.0",
|
||||
"@antv/l7plot": "^0.5.5",
|
||||
"@antv/s2": "^1.49.0",
|
||||
"vue-i18n": "^9.2.2",
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"@form-create/designer": "^1.1.9",
|
||||
"@form-create/element-ui": "^3.2.22",
|
||||
"@form-create/vant": "^3.2.24",
|
||||
"@turf/centroid": "^7.0.0",
|
||||
"@npkg/tinymce-plugins": "^0.0.7",
|
||||
"@tinymce/tinymce-vue": "^5.1.0",
|
||||
"tinymce": "^5.8.2",
|
||||
"@turf/centroid": "^7.0.0",
|
||||
"@videojs-player/vue": "^1.0.0",
|
||||
"@vueuse/core": "^9.13.0",
|
||||
"axios": "^1.6.0",
|
||||
"consola": "^3.4.2",
|
||||
"dayjs": "^1.11.9",
|
||||
"echarts": "^5.5.1",
|
||||
"element-plus": "^2.4.4",
|
||||
"element-plus-secondary": "^0.6.8",
|
||||
"element-resize-detector": "^1.2.4",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"exceljs": "^4.4.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"flv.js": "^1.6.2",
|
||||
"html-to-image": "^1.11.11",
|
||||
"html2canvas": "^1.4.1",
|
||||
"js-base64": "^3.7.5",
|
||||
"jsencrypt": "^3.3.2",
|
||||
"jspdf": "^2.5.1",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash-es": "^4.17.21",
|
||||
"mathjs": "^11.6.0",
|
||||
"mitt": "^3.0.0",
|
||||
"path": "^0.12.7",
|
||||
"pinia": "^2.1.7",
|
||||
"qs": "^6.11.0",
|
||||
"screenfull": "^6.0.2",
|
||||
"snowflake-id": "^1.1.0",
|
||||
"tinymce": "^5.8.2",
|
||||
"vant": "^4.9.19",
|
||||
"video.js": "^7.21.6",
|
||||
"vue": "^3.3.4",
|
||||
"vue-i18n": "^9.2.2",
|
||||
"vue-router": "^4.2.5",
|
||||
"web-storage-cache": "^1.1.1",
|
||||
"vue-types": "^5.0.2"
|
||||
"vue-types": "^5.0.2",
|
||||
"vue3-sfc-loader": "^0.9.5",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"web-storage-cache": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
"@intlify/unplugin-vue-i18n": "^0.8.2",
|
||||
"@rushstack/eslint-patch": "^1.3.3",
|
||||
"@vitejs/plugin-vue": "^4.5.2",
|
||||
"@vitejs/plugin-vue-jsx": "^4.2.0",
|
||||
"@vue/eslint-config-prettier": "^8.0.0",
|
||||
"less": "^4.1.3",
|
||||
"jquery": "^3.6.4",
|
||||
"consola": "^2.15.3",
|
||||
"eslint": "^8.49.0",
|
||||
"eslint-plugin-vue": "^9.17.0",
|
||||
"jquery": "^3.6.4",
|
||||
"less": "^4.1.3",
|
||||
"prettier": "^3.0.3",
|
||||
"sass": "^1.89.0",
|
||||
"sass-loader": "^16.0.5",
|
||||
@ -76,7 +78,6 @@
|
||||
"unplugin-vue-components-secondary": "^0.24.6",
|
||||
"vite": "^5.0.8",
|
||||
"vite-plugin-style-import-secondary": "^2.0.0",
|
||||
"consola": "^2.15.3",
|
||||
"vite-svg-loader": "^5.1.0"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -54,7 +54,7 @@ export default defineConfig({
|
||||
cors: true,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://192.168.1.38:8100',
|
||||
target: 'http://192.168.1.58:8080',
|
||||
changeOrigin: true,
|
||||
secure: false,
|
||||
rewrite: path => path.replace(/^\/api/, '')
|
||||
|
Loading…
Reference in New Issue
Block a user