mirror of
https://github.com/FatttSnake/Pinnacle-OA.git
synced 2026-04-04 22:41:24 +08:00
Added login, logout and getUserinfo (Include ui and server)
This commit is contained in:
@@ -14,6 +14,11 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
|||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
|
import org.springframework.web.cors.CorsConfigurationSource;
|
||||||
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class SecurityConfig {
|
public class SecurityConfig {
|
||||||
@@ -42,7 +47,7 @@ public class SecurityConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
AuthenticationManager authenticationManager(HttpSecurity httpSecurity, PasswordEncoder passwordEncoder) throws Exception {
|
public AuthenticationManager authenticationManager(HttpSecurity httpSecurity, PasswordEncoder passwordEncoder) throws Exception {
|
||||||
return httpSecurity.getSharedObject(AuthenticationManagerBuilder.class)
|
return httpSecurity.getSharedObject(AuthenticationManagerBuilder.class)
|
||||||
.userDetailsService(userDetailsService)
|
.userDetailsService(userDetailsService)
|
||||||
.passwordEncoder(passwordEncoder)
|
.passwordEncoder(passwordEncoder)
|
||||||
@@ -50,22 +55,38 @@ public class SecurityConfig {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public CorsConfigurationSource corsConfigurationSource(){
|
||||||
|
CorsConfiguration corsConfiguration = new CorsConfiguration();
|
||||||
|
corsConfiguration.setAllowedMethods(List.of("*"));
|
||||||
|
corsConfiguration.setAllowedHeaders(List.of("*"));
|
||||||
|
corsConfiguration.setMaxAge(3600L);
|
||||||
|
corsConfiguration.setAllowedOrigins(List.of("*"));
|
||||||
|
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||||
|
source.registerCorsConfiguration("/**",corsConfiguration);
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
|
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
|
||||||
return httpSecurity
|
return httpSecurity
|
||||||
// Disable CSRF
|
// Disable CSRF
|
||||||
.csrf().disable()
|
.csrf()
|
||||||
|
.disable()
|
||||||
|
|
||||||
// Do not get SecurityContent by Session
|
// Do not get SecurityContent by Session
|
||||||
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
.sessionManagement()
|
||||||
|
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||||
.and()
|
.and()
|
||||||
|
|
||||||
// Allow anonymous access
|
// Allow anonymous access
|
||||||
.authorizeHttpRequests()
|
.authorizeHttpRequests()
|
||||||
.requestMatchers("/login").anonymous()
|
.requestMatchers("/login")
|
||||||
|
.anonymous()
|
||||||
|
|
||||||
// Authentication required
|
// Authentication required
|
||||||
.anyRequest().authenticated()
|
.anyRequest()
|
||||||
|
.authenticated()
|
||||||
.and()
|
.and()
|
||||||
|
|
||||||
.logout()
|
.logout()
|
||||||
@@ -75,6 +96,10 @@ public class SecurityConfig {
|
|||||||
.authenticationEntryPoint(authenticationEntryPointHandler)
|
.authenticationEntryPoint(authenticationEntryPointHandler)
|
||||||
.and()
|
.and()
|
||||||
|
|
||||||
|
.cors()
|
||||||
|
.configurationSource(corsConfigurationSource())
|
||||||
|
.and()
|
||||||
|
|
||||||
.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
|
.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
package com.cfive.pinnacle.controller.permission;
|
package com.cfive.pinnacle.controller.permission;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.cfive.pinnacle.entity.common.ResponseResult;
|
||||||
|
import com.cfive.pinnacle.entity.permission.Element;
|
||||||
|
import com.cfive.pinnacle.service.permission.IElementService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 页面元素 前端控制器
|
* 页面元素 前端控制器
|
||||||
@@ -14,5 +23,26 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/element")
|
@RequestMapping("/element")
|
||||||
public class ElementController {
|
public class ElementController {
|
||||||
|
private IElementService elementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void setElementService(IElementService elementService) {
|
||||||
|
this.elementService = elementService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public ResponseResult getAllElement() {
|
||||||
|
List<Element> elements = elementService.list();
|
||||||
|
|
||||||
|
return ResponseResult.databaseSelectSuccess(elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public ResponseResult getElement(@PathVariable long id) {
|
||||||
|
LambdaQueryWrapper<Element> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.eq(Element::getId, id);
|
||||||
|
Element element = elementService.getOne(wrapper);
|
||||||
|
|
||||||
|
return ResponseResult.databaseSelectSuccess(element);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
package com.cfive.pinnacle.controller.permission;
|
package com.cfive.pinnacle.controller.permission;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.cfive.pinnacle.entity.common.ResponseResult;
|
||||||
|
import com.cfive.pinnacle.entity.permission.File;
|
||||||
|
import com.cfive.pinnacle.service.permission.IFileService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 文件 前端控制器
|
* 文件 前端控制器
|
||||||
@@ -14,5 +23,26 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/file")
|
@RequestMapping("/file")
|
||||||
public class FileController {
|
public class FileController {
|
||||||
|
private IFileService fileService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void setFileService(IFileService fileService) {
|
||||||
|
this.fileService = fileService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public ResponseResult getAllFile() {
|
||||||
|
List<File> files = fileService.list();
|
||||||
|
|
||||||
|
return ResponseResult.databaseSelectSuccess(files);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public ResponseResult getFile(@PathVariable int id) {
|
||||||
|
LambdaQueryWrapper<File> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.eq(File::getId, id);
|
||||||
|
File file = fileService.getOne(wrapper);
|
||||||
|
|
||||||
|
return ResponseResult.databaseSelectSuccess(file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ import com.cfive.pinnacle.entity.common.ResponseCode;
|
|||||||
import com.cfive.pinnacle.entity.common.ResponseResult;
|
import com.cfive.pinnacle.entity.common.ResponseResult;
|
||||||
import com.cfive.pinnacle.service.permission.ILoginService;
|
import com.cfive.pinnacle.service.permission.ILoginService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
|
@CrossOrigin
|
||||||
public class LoginController {
|
public class LoginController {
|
||||||
|
|
||||||
private ILoginService loginService;
|
private ILoginService loginService;
|
||||||
@@ -37,4 +37,11 @@ public class LoginController {
|
|||||||
return ResponseResult.build(ResponseCode.LOGOUT_FAILED, "Logout Failed", null);
|
return ResponseResult.build(ResponseCode.LOGOUT_FAILED, "Logout Failed", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/userInfo")
|
||||||
|
public ResponseResult getUserInfo() {
|
||||||
|
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
Object principal = authentication.getPrincipal();
|
||||||
|
return ResponseResult.success(principal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
package com.cfive.pinnacle.controller.permission;
|
package com.cfive.pinnacle.controller.permission;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.cfive.pinnacle.entity.common.ResponseResult;
|
||||||
|
import com.cfive.pinnacle.entity.permission.Menu;
|
||||||
|
import com.cfive.pinnacle.service.permission.IMenuService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 菜单 前端控制器
|
* 菜单 前端控制器
|
||||||
@@ -14,5 +23,26 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/menu")
|
@RequestMapping("/menu")
|
||||||
public class MenuController {
|
public class MenuController {
|
||||||
|
private IMenuService menuService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void setMenuService(IMenuService menuService) {
|
||||||
|
this.menuService = menuService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public ResponseResult getAllMenu() {
|
||||||
|
List<Menu> menus = menuService.list();
|
||||||
|
|
||||||
|
return ResponseResult.databaseSelectSuccess(menus);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public ResponseResult getMenu(@PathVariable int id) {
|
||||||
|
LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.eq(Menu::getId, id);
|
||||||
|
Menu menu = menuService.getOne(wrapper);
|
||||||
|
|
||||||
|
return ResponseResult.databaseSelectSuccess(menu);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
package com.cfive.pinnacle.controller.permission;
|
package com.cfive.pinnacle.controller.permission;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.cfive.pinnacle.entity.common.ResponseResult;
|
||||||
|
import com.cfive.pinnacle.entity.permission.Operation;
|
||||||
|
import com.cfive.pinnacle.service.permission.IOperationService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 功能 前端控制器
|
* 功能 前端控制器
|
||||||
@@ -14,5 +23,26 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/operation")
|
@RequestMapping("/operation")
|
||||||
public class OperationController {
|
public class OperationController {
|
||||||
|
private IOperationService operationService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void setOperationService(IOperationService operationService) {
|
||||||
|
this.operationService = operationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public ResponseResult getAllOperation() {
|
||||||
|
List<Operation> operations = operationService.list();
|
||||||
|
|
||||||
|
return ResponseResult.databaseSelectSuccess(operations);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public ResponseResult getOperation(@PathVariable int id) {
|
||||||
|
LambdaQueryWrapper<Operation> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.eq(Operation::getId, id);
|
||||||
|
Operation operation = operationService.getOne(wrapper);
|
||||||
|
|
||||||
|
return ResponseResult.databaseSelectSuccess(operation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
package com.cfive.pinnacle.controller.permission;
|
package com.cfive.pinnacle.controller.permission;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.cfive.pinnacle.entity.common.ResponseResult;
|
||||||
|
import com.cfive.pinnacle.entity.permission.OperationLog;
|
||||||
|
import com.cfive.pinnacle.service.permission.IOperationLogService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 操作日志 前端控制器
|
* 操作日志 前端控制器
|
||||||
@@ -14,5 +23,26 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/operationLog")
|
@RequestMapping("/operationLog")
|
||||||
public class OperationLogController {
|
public class OperationLogController {
|
||||||
|
private IOperationLogService operationLogService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void setOperationLogService(IOperationLogService operationLogService) {
|
||||||
|
this.operationLogService = operationLogService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public ResponseResult getAllOperationLog() {
|
||||||
|
List<OperationLog> operationLogs = operationLogService.list();
|
||||||
|
|
||||||
|
return ResponseResult.databaseSelectSuccess(operationLogs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public ResponseResult getOperationLog(@PathVariable int id) {
|
||||||
|
LambdaQueryWrapper<OperationLog> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.eq(OperationLog::getId, id);
|
||||||
|
OperationLog operationLog = operationLogService.getOne(wrapper);
|
||||||
|
|
||||||
|
return ResponseResult.databaseSelectSuccess(operationLog);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
package com.cfive.pinnacle.controller.permission;
|
package com.cfive.pinnacle.controller.permission;
|
||||||
|
|
||||||
|
import com.cfive.pinnacle.entity.common.ResponseResult;
|
||||||
|
import com.cfive.pinnacle.entity.permission.PowerSet;
|
||||||
|
import com.cfive.pinnacle.service.permission.IPowerService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@@ -14,5 +19,17 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/power")
|
@RequestMapping("/power")
|
||||||
public class PowerController {
|
public class PowerController {
|
||||||
|
private IPowerService powerService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void setPowerService(IPowerService powerService) {
|
||||||
|
this.powerService = powerService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public ResponseResult getAllPower() {
|
||||||
|
PowerSet powerSet = powerService.getAllPower();
|
||||||
|
|
||||||
|
return ResponseResult.databaseSelectSuccess(powerSet);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.cfive.pinnacle.controller.permission;
|
package com.cfive.pinnacle.controller.permission;
|
||||||
|
|
||||||
import com.cfive.pinnacle.entity.common.ResponseCode;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.cfive.pinnacle.entity.common.ResponseResult;
|
import com.cfive.pinnacle.entity.common.ResponseResult;
|
||||||
import com.cfive.pinnacle.entity.permission.*;
|
import com.cfive.pinnacle.entity.permission.*;
|
||||||
import com.cfive.pinnacle.service.permission.*;
|
import com.cfive.pinnacle.service.permission.*;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@@ -22,16 +22,25 @@ import java.util.List;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/powerType")
|
@RequestMapping("/powerType")
|
||||||
public class PowerTypeController {
|
public class PowerTypeController {
|
||||||
IPowerService powerTypeService;
|
IPowerTypeService powerTypeService;
|
||||||
|
|
||||||
@Autowired
|
public void setPowerTypeService(IPowerTypeService powerTypeService) {
|
||||||
public void setPowerTypeService(IPowerService powerTypeService) {
|
|
||||||
this.powerTypeService = powerTypeService;
|
this.powerTypeService = powerTypeService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public ResponseResult getAllPowerType() {
|
public ResponseResult getAllPowerType() {
|
||||||
List<Power> powerTypes = powerTypeService.list();
|
List<PowerType> powerTypes = powerTypeService.list();
|
||||||
return ResponseResult.build(ResponseCode.DATABASE_SELECT_OK, "success", powerTypes);
|
|
||||||
|
return ResponseResult.databaseSelectSuccess(powerTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public ResponseResult getPowerType(@PathVariable int id) {
|
||||||
|
LambdaQueryWrapper<PowerType> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.eq(PowerType::getId, id);
|
||||||
|
PowerType powerType = powerTypeService.getOne(wrapper);
|
||||||
|
|
||||||
|
return ResponseResult.databaseSelectSuccess(powerType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,4 +55,20 @@ public class ResponseResult implements Serializable {
|
|||||||
public static ResponseResult fail(String msg, Object data) {
|
public static ResponseResult fail(String msg, Object data) {
|
||||||
return build(ResponseCode.SYSTEM_ERROR, msg, data);
|
return build(ResponseCode.SYSTEM_ERROR, msg, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ResponseResult databaseSelectSuccess(Object object) {
|
||||||
|
return build(ResponseCode.DATABASE_SELECT_OK, "success", object);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResponseResult databaseSaveSuccess(Object object) {
|
||||||
|
return build(ResponseCode.DATABASE_SAVE_OK, "success", object);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResponseResult databaseUpdateSuccess(Object object) {
|
||||||
|
return build(ResponseCode.DATABASE_UPDATE_OK, "success", object);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResponseResult databaseDeleteSuccess() {
|
||||||
|
return build(ResponseCode.DATABASE_DELETE_OK, "success", null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.cfive.pinnacle.entity.permission;
|
package com.cfive.pinnacle.entity.permission;
|
||||||
|
|
||||||
import com.cfive.pinnacle.entity.User;
|
import com.cfive.pinnacle.entity.User;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@@ -14,102 +15,46 @@ import java.util.Collection;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class LoginUser implements UserDetails {
|
public class LoginUser implements UserDetails {
|
||||||
private User user;
|
private User user;
|
||||||
private Collection<? extends GrantedAuthority> authorities;
|
|
||||||
private String password;
|
|
||||||
private String username;
|
|
||||||
private Boolean accountNonExpired = true;
|
|
||||||
private Boolean accountNonLocked = true;
|
|
||||||
private Boolean credentialsNonExpired = true;
|
|
||||||
private Boolean enabled = true;
|
|
||||||
|
|
||||||
public LoginUser(User user) {
|
|
||||||
this.user = user;
|
|
||||||
this.username = user.getUsername();
|
|
||||||
this.password = user.getPasswd();
|
|
||||||
this.enabled = user.getEnable() == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public User getUser() {
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUser(User user) {
|
|
||||||
this.user = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||||
return authorities;
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuthorities(Collection<? extends GrantedAuthority> authorities) {
|
|
||||||
this.authorities = authorities;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
public String getPassword() {
|
public String getPassword() {
|
||||||
return password;
|
return user.getPasswd();
|
||||||
}
|
|
||||||
|
|
||||||
public void setPassword(String password) {
|
|
||||||
this.password = password;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
public String getUsername() {
|
public String getUsername() {
|
||||||
return username;
|
return user.getUsername();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
@Override
|
@Override
|
||||||
public boolean isAccountNonExpired() {
|
public boolean isAccountNonExpired() {
|
||||||
return this.accountNonExpired;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
@Override
|
@Override
|
||||||
public boolean isAccountNonLocked() {
|
public boolean isAccountNonLocked() {
|
||||||
return this.accountNonLocked;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
@Override
|
@Override
|
||||||
public boolean isCredentialsNonExpired() {
|
public boolean isCredentialsNonExpired() {
|
||||||
return this.credentialsNonExpired;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return this.enabled;
|
return user.getEnable() == 1;
|
||||||
}
|
|
||||||
|
|
||||||
public void setUsername(String username) {
|
|
||||||
this.username = username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean getAccountNonExpired() {
|
|
||||||
return accountNonExpired;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAccountNonExpired(Boolean accountNonExpired) {
|
|
||||||
this.accountNonExpired = accountNonExpired;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean getAccountNonLocked() {
|
|
||||||
return accountNonLocked;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAccountNonLocked(Boolean accountNonLocked) {
|
|
||||||
this.accountNonLocked = accountNonLocked;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean getCredentialsNonExpired() {
|
|
||||||
return credentialsNonExpired;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCredentialsNonExpired(Boolean credentialsNonExpired) {
|
|
||||||
this.credentialsNonExpired = credentialsNonExpired;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean getEnabled() {
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEnabled(Boolean enabled) {
|
|
||||||
this.enabled = enabled;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,12 +45,6 @@ public class Operation implements Serializable {
|
|||||||
@TableField("code")
|
@TableField("code")
|
||||||
private String code;
|
private String code;
|
||||||
|
|
||||||
/**
|
|
||||||
* URL 前缀
|
|
||||||
*/
|
|
||||||
@TableField("url_prefix")
|
|
||||||
private String urlPrefix;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 权限ID
|
* 权限ID
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.cfive.pinnacle.entity.permission;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class PowerSet implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private List<Operation> operationList;
|
||||||
|
|
||||||
|
private List<Menu> menuList;
|
||||||
|
|
||||||
|
private List<Element> elementList;
|
||||||
|
|
||||||
|
private List<File> fileList;
|
||||||
|
}
|
||||||
@@ -49,7 +49,7 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
|||||||
if (Objects.isNull(loginUser)) {
|
if (Objects.isNull(loginUser)) {
|
||||||
throw new RuntimeException("Not logged in");
|
throw new RuntimeException("Not logged in");
|
||||||
}
|
}
|
||||||
|
// Todo 权限
|
||||||
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, null);
|
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, null);
|
||||||
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
|
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.cfive.pinnacle.service.permission;
|
|||||||
|
|
||||||
import com.cfive.pinnacle.entity.permission.Power;
|
import com.cfive.pinnacle.entity.permission.Power;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.cfive.pinnacle.entity.permission.PowerSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -12,5 +13,5 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
|||||||
* @since 2023-04-30
|
* @since 2023-04-30
|
||||||
*/
|
*/
|
||||||
public interface IPowerService extends IService<Power> {
|
public interface IPowerService extends IService<Power> {
|
||||||
|
PowerSet getAllPower();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ public class LoginServiceImpl implements ILoginService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
|
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
|
||||||
|
loginUser.getUser().setPasswd("");
|
||||||
String userId = loginUser.getUser().getId().toString();
|
String userId = loginUser.getUser().getId().toString();
|
||||||
String jwt = JwtUtil.createJWT(userId);
|
String jwt = JwtUtil.createJWT(userId);
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
package com.cfive.pinnacle.service.permission.impl;
|
package com.cfive.pinnacle.service.permission.impl;
|
||||||
|
|
||||||
import com.cfive.pinnacle.entity.permission.Power;
|
import com.cfive.pinnacle.entity.permission.*;
|
||||||
import com.cfive.pinnacle.mapper.permission.PowerMapper;
|
import com.cfive.pinnacle.mapper.permission.PowerMapper;
|
||||||
import com.cfive.pinnacle.service.permission.IPowerService;
|
import com.cfive.pinnacle.service.permission.*;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 权限 服务实现类
|
* 权限 服务实现类
|
||||||
@@ -16,5 +19,38 @@ import org.springframework.stereotype.Service;
|
|||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class PowerServiceImpl extends ServiceImpl<PowerMapper, Power> implements IPowerService {
|
public class PowerServiceImpl extends ServiceImpl<PowerMapper, Power> implements IPowerService {
|
||||||
|
private IOperationService operationService;
|
||||||
|
private IMenuService menuService;
|
||||||
|
private IElementService elementService;
|
||||||
|
private IFileService fileService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void setOperationService(IOperationService operationService) {
|
||||||
|
this.operationService = operationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void setMenuService(IMenuService menuService) {
|
||||||
|
this.menuService = menuService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void setElementService(IElementService elementService) {
|
||||||
|
this.elementService = elementService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void setFileService(IFileService fileService) {
|
||||||
|
this.fileService = fileService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PowerSet getAllPower() {
|
||||||
|
List<Operation> operationList = operationService.list();
|
||||||
|
List<Menu> menuList = menuService.list();
|
||||||
|
List<Element> elementList = elementService.list();
|
||||||
|
List<File> fileList = fileService.list();
|
||||||
|
|
||||||
|
return new PowerSet(operationList, menuList, elementList, fileList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ public class UserDetailsServiceImpl implements UserDetailsService {
|
|||||||
if (Objects.isNull(user)) {
|
if (Objects.isNull(user)) {
|
||||||
throw new UsernameNotFoundException("Username not found in database");
|
throw new UsernameNotFoundException("Username not found in database");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Todo 权限
|
||||||
|
|
||||||
return new LoginUser(user);
|
return new LoginUser(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.cfive.pinnacle.service;
|
package com.cfive.pinnacle.service;
|
||||||
|
|
||||||
|
import com.cfive.pinnacle.entity.User;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
@@ -18,4 +19,19 @@ class IUserServiceTest {
|
|||||||
void getBCy(@Autowired PasswordEncoder passwordEncoder) {
|
void getBCy(@Autowired PasswordEncoder passwordEncoder) {
|
||||||
System.out.println(passwordEncoder.encode("123"));
|
System.out.println(passwordEncoder.encode("123"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void addUser(@Autowired IUserService userService, @Autowired PasswordEncoder passwordEncoder) {
|
||||||
|
User user = new User();
|
||||||
|
user.setUsername("ggb");
|
||||||
|
user.setPasswd(passwordEncoder.encode("123"));
|
||||||
|
user.setDepartmentId(1652713919467151362L);
|
||||||
|
user.setEnable(1);
|
||||||
|
userService.save(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void removeUser(@Autowired IUserService userService) {
|
||||||
|
userService.removeById(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
60
sql/Insert.sql
Normal file
60
sql/Insert.sql
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
SET FOREIGN_KEY_CHECKS=0;
|
||||||
|
|
||||||
|
truncate t_menu;
|
||||||
|
truncate t_element;
|
||||||
|
truncate t_file;
|
||||||
|
truncate t_operation_log;
|
||||||
|
truncate t_operation;
|
||||||
|
truncate t_power;
|
||||||
|
truncate t_power_type;
|
||||||
|
|
||||||
|
insert into t_power_type (id, name)
|
||||||
|
values (1, 'operation'),
|
||||||
|
(2, 'menu'),
|
||||||
|
(3, 'element'),
|
||||||
|
(4, 'file');
|
||||||
|
|
||||||
|
begin;
|
||||||
|
insert into t_power (type_id)
|
||||||
|
values (1);
|
||||||
|
insert into t_operation (name, code, power_id, parent_id)
|
||||||
|
values ('Select All Power Type', 'system:power_type:all', last_insert_id(), null);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
|
||||||
|
begin;
|
||||||
|
insert into t_power (type_id)
|
||||||
|
values (1);
|
||||||
|
insert into t_operation (name, code, power_id, parent_id)
|
||||||
|
values ('Select All Power', 'system:power:all', last_insert_id(), null);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
begin;
|
||||||
|
insert into t_power (type_id)
|
||||||
|
values (1);
|
||||||
|
insert into t_operation (name, code, power_id, parent_id)
|
||||||
|
values ('Select All User', 'system:operation:all', last_insert_id(), null);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
begin;
|
||||||
|
insert into t_power (type_id)
|
||||||
|
values (1);
|
||||||
|
insert into t_operation (name, code, power_id, parent_id)
|
||||||
|
values ('Select All User', 'system:menu:all', last_insert_id(), null);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
begin;
|
||||||
|
insert into t_power (type_id)
|
||||||
|
values (1);
|
||||||
|
insert into t_operation (name, code, power_id, parent_id)
|
||||||
|
values ('Select All User', 'system:element:all', last_insert_id(), null);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
begin;
|
||||||
|
insert into t_power (type_id)
|
||||||
|
values (1);
|
||||||
|
insert into t_operation (name, code, power_id, parent_id)
|
||||||
|
values ('Select All User', 'system:file:all', last_insert_id(), null);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
SET FOREIGN_KEY_CHECKS=1;
|
||||||
31
sql/init.sql
31
sql/init.sql
@@ -69,7 +69,6 @@ create table `t_operation`
|
|||||||
`id` bigint not null primary key auto_increment,
|
`id` bigint not null primary key auto_increment,
|
||||||
`name` varchar(50) not null comment '功能名',
|
`name` varchar(50) not null comment '功能名',
|
||||||
`code` varchar(50) null comment '功能编码',
|
`code` varchar(50) null comment '功能编码',
|
||||||
`url_prefix` varchar(100) null comment 'URL 前缀',
|
|
||||||
`power_id` bigint not null comment '权限ID',
|
`power_id` bigint not null comment '权限ID',
|
||||||
`parent_id` bigint null comment '父ID',
|
`parent_id` bigint null comment '父ID',
|
||||||
constraint t_operation_power_id_fk foreign key (power_id) references t_power (id)
|
constraint t_operation_power_id_fk foreign key (power_id) references t_power (id)
|
||||||
@@ -298,32 +297,4 @@ create table `t_attendance`
|
|||||||
`version` int not null default 0,
|
`version` int not null default 0,
|
||||||
constraint t_attendance_user_id_fk foreign key (user_id) references t_user (id),
|
constraint t_attendance_user_id_fk foreign key (user_id) references t_user (id),
|
||||||
constraint t_attendance_modify_id_fk foreign key (modify_id) references t_user (id)
|
constraint t_attendance_modify_id_fk foreign key (modify_id) references t_user (id)
|
||||||
) comment '考勤';
|
) comment '考勤';
|
||||||
|
|
||||||
insert into t_power_type (id, name)
|
|
||||||
values (1, 'operation'),
|
|
||||||
(2, 'menu'),
|
|
||||||
(3, 'element'),
|
|
||||||
(4, 'file');
|
|
||||||
|
|
||||||
begin;
|
|
||||||
insert into t_power (type_id)
|
|
||||||
values (1);
|
|
||||||
insert into t_operation (name, code, url_prefix, power_id, parent_id)
|
|
||||||
values ('Select All Power Type', 'select_all_power_type', 'GET:/powerType', last_insert_id(), null);
|
|
||||||
commit;
|
|
||||||
|
|
||||||
|
|
||||||
begin;
|
|
||||||
insert into t_power (type_id)
|
|
||||||
values (1);
|
|
||||||
insert into t_operation (name, code, url_prefix, power_id, parent_id)
|
|
||||||
values ('Select All Power Type', 'select_all_power_type', 'GET:/powerType', last_insert_id(), null);
|
|
||||||
commit;
|
|
||||||
|
|
||||||
begin;
|
|
||||||
insert into t_power (type_id)
|
|
||||||
values (1);
|
|
||||||
insert into t_operation (name, code, url_prefix, power_id, parent_id)
|
|
||||||
values ('Select All User', 'select_all_user', 'GET:/user', last_insert_id(), null);
|
|
||||||
commit;
|
|
||||||
@@ -22,7 +22,7 @@ module.exports = {
|
|||||||
rules: {
|
rules: {
|
||||||
"no-cond-assign": "error",
|
"no-cond-assign": "error",
|
||||||
"eqeqeq": "error",
|
"eqeqeq": "error",
|
||||||
"indent": ["error", 4],
|
"indent": ["error", 4, {"SwitchCase": 1}],
|
||||||
"prettier/prettier": [
|
"prettier/prettier": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
|
|||||||
2
ui/src/assets/svg/back-shape.svg
Normal file
2
ui/src/assets/svg/back-shape.svg
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="473.5501403808594" height="514.205810546875"
|
||||||
|
viewBox="0 0 473.5501403808594 514.205810546875"><g style="mix-blend-mode:passthrough"><g style="mix-blend-mode:passthrough" transform="matrix(-0.09544334560632706,-0.9953708648681641,0.9953532218933105,-0.09562418609857559,-475.4320658580816,596.4368332676222)"><path d="M207.21426391601562,514.205810546875L357.9022639160156,845.999810546875L56.52586391601562,845.999810546875L207.21426391601562,514.205810546875Z" fill="#5495F1" fill-opacity="1"/></g><g style="mix-blend-mode:passthrough" transform="matrix(0.6958200931549072,-0.7182161211967468,0.7182161211967468,0.6958200931549072,-42.65635399221446,124.80157307758964)"><path d="M204.50979614257812,112.7599334716797L272.49279614257813,317.36393347167973L136.52679614257812,317.36393347167973L204.50979614257812,112.7599334716797Z" fill="#FFFFFF" fill-opacity="0.6000000238418579"/></g></g></svg>
|
||||||
|
After Width: | Height: | Size: 964 B |
2
ui/src/assets/svg/password.svg
Normal file
2
ui/src/assets/svg/password.svg
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="27.428573608398438" height="32.000003814697266"
|
||||||
|
viewBox="0 0 27.428573608398438 32.000003814697266"><g><path d="M22.8571,10.6667L25.9048,10.6667C26.7463,10.6667,27.4286,11.3489,27.4286,12.1905L27.4286,30.4762C27.4286,31.3178,26.7463,32,25.9048,32L1.52381,32C0.682233,32,0,31.3178,0,30.4762L0,12.1905C0,11.3489,0.682233,10.6667,1.52381,10.6667L4.57143,10.6667L4.57143,9.14286C4.57143,4.0934,8.66483,0,13.7143,0C18.7637,0,22.8571,4.0934,22.8571,9.14286L22.8571,10.6667ZM19.8095,10.6667L19.8095,9.14286C19.8095,5.77655,17.0806,3.04762,13.7143,3.04762C10.348,3.04762,7.61905,5.77655,7.61905,9.14286L7.61905,10.6667L19.8095,10.6667ZM12.1905,19.8095L12.1905,22.8571L15.2381,22.8571L15.2381,19.8095L12.1905,19.8095ZM6.09524,19.8095L6.09524,22.8571L9.14286,22.8571L9.14286,19.8095L6.09524,19.8095ZM18.2857,19.8095L18.2857,22.8571L21.3333,22.8571L21.3333,19.8095L18.2857,19.8095Z" fill-opacity="1"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 966 B |
@@ -1,4 +1,5 @@
|
|||||||
const PRODUCTION_NAME = 'Pinnacle OA'
|
const PRODUCTION_NAME = 'Pinnacle OA'
|
||||||
|
const TOKEN_NAME = 'JWT_TOKEN'
|
||||||
const COLOR_PRODUCTION = '#00D4FF'
|
const COLOR_PRODUCTION = '#00D4FF'
|
||||||
const COLOR_BACKGROUND = '#D8D8D8'
|
const COLOR_BACKGROUND = '#D8D8D8'
|
||||||
const COLOR_FONT_MAIN = '#4D4D4D'
|
const COLOR_FONT_MAIN = '#4D4D4D'
|
||||||
@@ -11,6 +12,7 @@ const SIZE_ICON_XL = '64px'
|
|||||||
|
|
||||||
export {
|
export {
|
||||||
PRODUCTION_NAME,
|
PRODUCTION_NAME,
|
||||||
|
TOKEN_NAME,
|
||||||
COLOR_PRODUCTION,
|
COLOR_PRODUCTION,
|
||||||
COLOR_BACKGROUND,
|
COLOR_BACKGROUND,
|
||||||
COLOR_FONT_MAIN,
|
COLOR_FONT_MAIN,
|
||||||
|
|||||||
@@ -5,18 +5,6 @@ import router from '@/router'
|
|||||||
import '@/assets/css/base.css'
|
import '@/assets/css/base.css'
|
||||||
import '@/assets/css/common.css'
|
import '@/assets/css/common.css'
|
||||||
|
|
||||||
/*
|
|
||||||
router.beforeEach((to, from, next) => {
|
|
||||||
if (to.matched.length === 0) {
|
|
||||||
from.path ? next({ path: from.path }) : next('/')
|
|
||||||
} else {
|
|
||||||
if (to.meta.title) {
|
|
||||||
document.title = PRODUCTION_NAME + ' - ' + to.meta.title
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
*/
|
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
|
|
||||||
app.use(router).mount('#app')
|
app.use(router).mount('#app')
|
||||||
|
|||||||
273
ui/src/pages/Login.vue
Normal file
273
ui/src/pages/Login.vue
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
<template>
|
||||||
|
<div class="background" @keyup.enter="login">
|
||||||
|
<div class="card-back">
|
||||||
|
<div class="production-name">
|
||||||
|
<span class="emphasize">{{ PRODUCTION_NAME() }}</span>
|
||||||
|
<br />
|
||||||
|
<span>自动化办公系统</span>
|
||||||
|
</div>
|
||||||
|
<img class="back-shape" :src="backShape" alt="back-shape" />
|
||||||
|
</div>
|
||||||
|
<div class="card-front">
|
||||||
|
<div class="login-title">登录</div>
|
||||||
|
<div class="input-box user-name-box">
|
||||||
|
<div class="center-box" style="padding: 10px">
|
||||||
|
<el-icon size="18">
|
||||||
|
<icon-pinnacle-user />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
<label for="user-name"></label
|
||||||
|
><input
|
||||||
|
type="text"
|
||||||
|
name="user-name"
|
||||||
|
id="user-name"
|
||||||
|
v-model="userName"
|
||||||
|
@keyup="userName = userName.replace(/\s+/g, '')"
|
||||||
|
placeholder="用户名"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-box password-box">
|
||||||
|
<div class="center-box" style="padding: 10px">
|
||||||
|
<el-icon size="18">
|
||||||
|
<icon-pinnacle-password />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
<label for="password"></label
|
||||||
|
><input
|
||||||
|
type="password"
|
||||||
|
name="password"
|
||||||
|
id="password"
|
||||||
|
v-model="password"
|
||||||
|
@keyup="password = password.replace(/\s+/g, '')"
|
||||||
|
placeholder="密码"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="captcha-set">
|
||||||
|
<div class="captcha-box">
|
||||||
|
<div class="input-box" style="height: 100%">
|
||||||
|
<label for="captcha"></label
|
||||||
|
><input
|
||||||
|
type="text"
|
||||||
|
name="captcha"
|
||||||
|
id="captcha"
|
||||||
|
v-model="captcha"
|
||||||
|
placeholder="验证码"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<img :src="captchaSrc" alt="Captcha" @click="getNewCaptcha" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ElButton
|
||||||
|
size="large"
|
||||||
|
type="primary"
|
||||||
|
:disabled="loggingIn"
|
||||||
|
id="login-bt"
|
||||||
|
@click="login"
|
||||||
|
>
|
||||||
|
<template #default
|
||||||
|
><span style="font-size: clamp(2em, 1.5vw, 2.8em)"
|
||||||
|
>登  录</span
|
||||||
|
></template
|
||||||
|
>
|
||||||
|
</ElButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { getCaptchaSrc, login, verifyCaptcha } from '@/utils/auth'
|
||||||
|
import backShape from '@/assets/svg/back-shape.svg'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import 'element-plus/theme-chalk/el-message.css'
|
||||||
|
import { PRODUCTION_NAME } from '@/constants/Common.constants'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'LoginPage',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
backShape,
|
||||||
|
captchaSrc: getCaptchaSrc(),
|
||||||
|
userName: '',
|
||||||
|
password: '',
|
||||||
|
captcha: '',
|
||||||
|
loggingIn: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
PRODUCTION_NAME() {
|
||||||
|
return PRODUCTION_NAME
|
||||||
|
},
|
||||||
|
getNewCaptcha() {
|
||||||
|
this.captchaSrc = getCaptchaSrc()
|
||||||
|
},
|
||||||
|
async login() {
|
||||||
|
if (!this.userName) {
|
||||||
|
ElMessage.error({
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
|
message: '<strong>用户名</strong> 为空'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!this.password) {
|
||||||
|
ElMessage.error({
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
|
message: '<strong>密码</strong> 为空'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!this.captcha) {
|
||||||
|
ElMessage.error({
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
|
message: '<strong>验证码</strong> 为空'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!verifyCaptcha(this.captcha)) {
|
||||||
|
ElMessage.error({
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
|
message: '<strong>验证码</strong> 错误'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (await login(this.userName, this.password)) {
|
||||||
|
ElMessage.success({
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
|
message: '<strong>登录成功</strong>'
|
||||||
|
})
|
||||||
|
this.loggingIn = true
|
||||||
|
const _this = this
|
||||||
|
setTimeout(function () {
|
||||||
|
_this.$router.push('/')
|
||||||
|
}, 1500)
|
||||||
|
} else {
|
||||||
|
ElMessage.error({
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
|
message: '<strong>用户名</strong> 或 <strong>密码</strong> 错误'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.background {
|
||||||
|
width: 100vw;
|
||||||
|
min-width: 900px;
|
||||||
|
height: 100vh;
|
||||||
|
min-height: 500px;
|
||||||
|
background: linear-gradient(to right, #5495f1, #82b5ff);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-back {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
width: 65vw;
|
||||||
|
min-width: 800px;
|
||||||
|
height: 25vw;
|
||||||
|
min-height: 350px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: rgba(255, 255, 255, 0.6);
|
||||||
|
transform: translateX(-50%) translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.production-name {
|
||||||
|
position: absolute;
|
||||||
|
left: 6%;
|
||||||
|
top: 8%;
|
||||||
|
font-size: clamp(2em, 2vw, 2.8em);
|
||||||
|
color: var(--font-main-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.production-name .emphasize {
|
||||||
|
font-size: 2em;
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--main-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-shape {
|
||||||
|
position: absolute;
|
||||||
|
height: 80%;
|
||||||
|
left: 30%;
|
||||||
|
top: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-front {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
width: 25vw;
|
||||||
|
min-width: 350px;
|
||||||
|
height: 35vw;
|
||||||
|
min-height: 500px;
|
||||||
|
border-radius: 15px;
|
||||||
|
background-color: white;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-title {
|
||||||
|
margin-top: 10%;
|
||||||
|
margin-left: 10%;
|
||||||
|
font-size: clamp(2.8em, 2.8vw, 4em);
|
||||||
|
letter-spacing: 0.25em;
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--main-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-box {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-box input {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 1.6em;
|
||||||
|
background-color: transparent;
|
||||||
|
padding-right: 10px;
|
||||||
|
color: var(--font-main-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-name-box,
|
||||||
|
.password-box {
|
||||||
|
margin: 10% auto -2% auto;
|
||||||
|
height: 10%;
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.captcha-set {
|
||||||
|
display: flex;
|
||||||
|
margin: 15% auto 12% auto;
|
||||||
|
height: 10%;
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.captcha-set img {
|
||||||
|
height: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.captcha-box {
|
||||||
|
flex: 1;
|
||||||
|
padding-right: 10px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.captcha-box input {
|
||||||
|
padding: 0 10px;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#login-bt {
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 80%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -106,7 +106,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="user-info">
|
<div class="user-info">
|
||||||
<div class="user-name">
|
<div class="user-name">
|
||||||
<span>用户名</span>
|
<span>{{ username }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="user-desc">
|
<div class="user-desc">
|
||||||
<span>用户介绍</span>
|
<span>用户介绍</span>
|
||||||
@@ -120,7 +120,7 @@
|
|||||||
<el-button style="width: 100%">个人档案</el-button>
|
<el-button style="width: 100%">个人档案</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<el-button style="width: 100%">退出</el-button>
|
<el-button @click="logout" style="width: 100%">退出</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -155,9 +155,17 @@ import {
|
|||||||
SIZE_ICON_SM
|
SIZE_ICON_SM
|
||||||
} from '@/constants/Common.constants.js'
|
} from '@/constants/Common.constants.js'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
import { getUsername, logout } from '@/utils/auth'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MainFrame',
|
name: 'MainFrame',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
routes: _.filter(_.get(this.$router, 'options.routes[0].children'), 'meta.title'),
|
||||||
|
isCollapsed: false,
|
||||||
|
username: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
SIZE_ICON_LG() {
|
SIZE_ICON_LG() {
|
||||||
return SIZE_ICON_LG
|
return SIZE_ICON_LG
|
||||||
@@ -176,16 +184,16 @@ export default {
|
|||||||
},
|
},
|
||||||
COLOR_FONT_MAIN() {
|
COLOR_FONT_MAIN() {
|
||||||
return COLOR_FONT_MAIN
|
return COLOR_FONT_MAIN
|
||||||
}
|
},
|
||||||
},
|
logout() {
|
||||||
data() {
|
logout()
|
||||||
return {
|
this.$router.push({ name: 'Login' })
|
||||||
routes: _.filter(_.get(this.$router, 'options.routes[0].children'), 'meta.title'),
|
|
||||||
isCollapsed: false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
console.log(this.routes)
|
getUsername().then((res) => {
|
||||||
|
this.username = res.toString()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
|
import { PRODUCTION_NAME } from '@/constants/Common.constants'
|
||||||
|
import { getLoginStatus } from '@/utils/auth'
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(import.meta.env.BASE_URL),
|
history: createWebHistory(import.meta.env.BASE_URL),
|
||||||
@@ -23,8 +25,41 @@ const router = createRouter({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/login',
|
||||||
|
component: async () => await import('@/pages/Login.vue'),
|
||||||
|
name: 'Login',
|
||||||
|
meta: {
|
||||||
|
title: '登录'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
if (to.matched.length === 0) {
|
||||||
|
from.path !== '' ? next({ path: from.path }) : next('/')
|
||||||
|
} else {
|
||||||
|
if (to.meta.title !== '') {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||||
|
document.title = `${PRODUCTION_NAME} - ${to.meta.title}`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getLoginStatus()) {
|
||||||
|
if (to.name === 'Login') {
|
||||||
|
next('/')
|
||||||
|
} else {
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (to.name === 'Login') {
|
||||||
|
next()
|
||||||
|
} else {
|
||||||
|
next('/login')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import axios, { type AxiosError } from 'axios'
|
||||||
|
import { getToken, removeToken } from '@/utils/common'
|
||||||
|
import router from '@/router'
|
||||||
|
|
||||||
|
const service = axios.create({
|
||||||
|
baseURL: 'http://localhost:8621',
|
||||||
|
timeout: 10000,
|
||||||
|
withCredentials: false
|
||||||
|
})
|
||||||
|
|
||||||
|
service.interceptors.request.use(
|
||||||
|
(config) => {
|
||||||
|
const token = getToken()
|
||||||
|
if (token != null) {
|
||||||
|
config.headers.set('token', token)
|
||||||
|
}
|
||||||
|
return config
|
||||||
|
},
|
||||||
|
async (error) => {
|
||||||
|
return await Promise.reject(error)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
service.interceptors.response.use(
|
||||||
|
(response) => {
|
||||||
|
return response
|
||||||
|
},
|
||||||
|
async (error) => {
|
||||||
|
if (error.response != null) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||||
|
console.log(`request error: ${error.response.code} - ${error.response.msg}`)
|
||||||
|
switch (error.response.code) {
|
||||||
|
case 30010:
|
||||||
|
removeToken()
|
||||||
|
await router.push({ name: 'Login' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return await Promise.reject(error?.response?.data)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const request = {
|
||||||
|
async get<T = any>(url: string, data?: any): Promise<T> {
|
||||||
|
return await request.request('GET', url, { params: data })
|
||||||
|
},
|
||||||
|
async post<T = any>(url: string, data?: any): Promise<T> {
|
||||||
|
return await request.request('POST', url, { data })
|
||||||
|
},
|
||||||
|
async put<T = any>(url: string, data?: any): Promise<T> {
|
||||||
|
return await request.request('PUT', url, { data })
|
||||||
|
},
|
||||||
|
async delete<T = any>(url: string, data?: any): Promise<T> {
|
||||||
|
return await request.request('DELETE', url, { params: data })
|
||||||
|
},
|
||||||
|
async request<T = any>(method = 'GET', url: string, data?: any): Promise<T> {
|
||||||
|
return await new Promise((resolve, reject) => {
|
||||||
|
service({ method, url, ...data })
|
||||||
|
.then((res) => {
|
||||||
|
resolve(res as unknown as Promise<T>)
|
||||||
|
})
|
||||||
|
.catch((e: Error | AxiosError) => {
|
||||||
|
reject(e)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default request
|
||||||
|
|||||||
61
ui/src/utils/auth.ts
Normal file
61
ui/src/utils/auth.ts
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import type { Captcha } from './common'
|
||||||
|
import {
|
||||||
|
getCaptcha,
|
||||||
|
getLocalStorage,
|
||||||
|
getToken,
|
||||||
|
removeLocalStorage,
|
||||||
|
setLocalStorage,
|
||||||
|
setToken
|
||||||
|
} from './common'
|
||||||
|
import { TOKEN_NAME } from '@/constants/Common.constants'
|
||||||
|
import _ from 'lodash'
|
||||||
|
import request from '@/services'
|
||||||
|
|
||||||
|
let captcha: Captcha
|
||||||
|
|
||||||
|
async function login(username: string, passwd: string): Promise<boolean> {
|
||||||
|
removeLocalStorage('username')
|
||||||
|
await request.post('/login', { username, passwd }).then((res: any) => {
|
||||||
|
const response = res.data
|
||||||
|
if (response.code === 20010) {
|
||||||
|
setToken(response.data.token)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return !_.isEmpty(getToken())
|
||||||
|
}
|
||||||
|
|
||||||
|
function logout(): void {
|
||||||
|
removeLocalStorage(TOKEN_NAME)
|
||||||
|
removeLocalStorage('username')
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLoginStatus(): boolean {
|
||||||
|
return getLocalStorage(TOKEN_NAME) != null
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getUsername(): Promise<string | null> {
|
||||||
|
if (!_.isEmpty(getLocalStorage('username'))) {
|
||||||
|
return getLocalStorage('username')
|
||||||
|
}
|
||||||
|
|
||||||
|
let username = ''
|
||||||
|
|
||||||
|
await request.get('/userInfo').then((res) => {
|
||||||
|
username = res.data.data.user.username
|
||||||
|
})
|
||||||
|
|
||||||
|
setLocalStorage('username', username)
|
||||||
|
return username
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCaptchaSrc(): string {
|
||||||
|
captcha = getCaptcha(300, 150, 4)
|
||||||
|
return captcha.base64Src
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyCaptcha(value: string): boolean {
|
||||||
|
return captcha.value === value.replace(/\s*/g, '').toUpperCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
export { login, logout, getLoginStatus, getUsername, getCaptchaSrc, verifyCaptcha }
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
import { TOKEN_NAME } from '@/constants/Common.constants'
|
||||||
|
|
||||||
|
interface Captcha {
|
||||||
|
value: string
|
||||||
|
base64Src: string
|
||||||
|
}
|
||||||
|
|
||||||
|
function getQueryVariable(variable: string): string | null {
|
||||||
|
const query = window.location.search.substring(1)
|
||||||
|
const vars = query.split('&')
|
||||||
|
for (let i = 0; i < vars.length; i++) {
|
||||||
|
const pair = vars[i].split('=')
|
||||||
|
if (pair[0] === variable) {
|
||||||
|
return decodeURIComponent(pair[1].replace(/\+/g, ' '))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCookie(
|
||||||
|
name: string,
|
||||||
|
value: string,
|
||||||
|
daysToLive: number | null,
|
||||||
|
path: string | null
|
||||||
|
): void {
|
||||||
|
let cookie = name + '=' + encodeURIComponent(value)
|
||||||
|
|
||||||
|
if (typeof daysToLive === 'number') {
|
||||||
|
cookie = `${cookie}; max-age=${daysToLive * 24 * 60 * 60}`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof path === 'string') {
|
||||||
|
cookie += '; path=' + path
|
||||||
|
}
|
||||||
|
|
||||||
|
document.cookie = cookie
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLocalStorage(name: string, value: string): void {
|
||||||
|
localStorage.setItem(name, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
function setToken(token: string): void {
|
||||||
|
setLocalStorage(TOKEN_NAME, token)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCookie(name: string): string | null {
|
||||||
|
const cookieArr = document.cookie.split(';')
|
||||||
|
|
||||||
|
for (let i = 0; i < cookieArr.length; i++) {
|
||||||
|
const cookiePair = cookieArr[i].split('=')
|
||||||
|
if (name === cookiePair[0].trim()) {
|
||||||
|
return decodeURIComponent(cookiePair[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLocalStorage(name: string): string | null {
|
||||||
|
return localStorage.getItem(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getToken(): string | null {
|
||||||
|
return getLocalStorage(TOKEN_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeCookie(name: string): void {
|
||||||
|
document.cookie = name + '=; max-age=0'
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeLocalStorage(name: string): void {
|
||||||
|
localStorage.removeItem(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeToken(): void {
|
||||||
|
removeLocalStorage(TOKEN_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
|
function randomInt(start: number, end: number): number {
|
||||||
|
if (start > end) {
|
||||||
|
const t = start
|
||||||
|
start = end
|
||||||
|
end = t
|
||||||
|
}
|
||||||
|
start = Math.ceil(start)
|
||||||
|
end = Math.floor(end)
|
||||||
|
return start + Math.floor(Math.random() * (end - start))
|
||||||
|
}
|
||||||
|
|
||||||
|
function randomFloat(start: number, end: number): number {
|
||||||
|
return start + Math.random() * (end - start)
|
||||||
|
}
|
||||||
|
|
||||||
|
function randomColor(start: number, end: number): string {
|
||||||
|
return `rgb(${randomInt(start, end)},${randomInt(start, end)},${randomInt(start, end)})`
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCaptcha(width: number, high: number, num: number): Captcha {
|
||||||
|
const CHARTS = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ'.split('')
|
||||||
|
|
||||||
|
const canvas = document.createElement('canvas')
|
||||||
|
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D
|
||||||
|
|
||||||
|
ctx.rect(0, 0, width, high)
|
||||||
|
ctx.clip()
|
||||||
|
|
||||||
|
ctx.fillStyle = randomColor(200, 250)
|
||||||
|
ctx.fillRect(0, 0, width, high)
|
||||||
|
|
||||||
|
for (let i = 0.05 * width * high; i > 0; i--) {
|
||||||
|
ctx.fillStyle = randomColor(0, 256)
|
||||||
|
ctx.fillRect(randomInt(0, width), randomInt(0, high), 1, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.font = `${high - 4}px Consolas`
|
||||||
|
ctx.fillStyle = randomColor(160, 200)
|
||||||
|
let value = ''
|
||||||
|
for (let i = 0; i < num; i++) {
|
||||||
|
const x = ((width - 10) / num) * i + 5
|
||||||
|
const y = high - 12
|
||||||
|
const r = Math.PI * randomFloat(-0.12, 0.12)
|
||||||
|
const ch = CHARTS[randomInt(0, CHARTS.length)]
|
||||||
|
value += ch
|
||||||
|
ctx.translate(x, y)
|
||||||
|
ctx.rotate(r)
|
||||||
|
ctx.fillText(ch, 0, 0)
|
||||||
|
ctx.rotate(-r)
|
||||||
|
ctx.translate(-x, -y)
|
||||||
|
}
|
||||||
|
|
||||||
|
const base64Src = canvas.toDataURL('image/jpg')
|
||||||
|
return {
|
||||||
|
value,
|
||||||
|
base64Src
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { Captcha }
|
||||||
|
|
||||||
|
export {
|
||||||
|
getQueryVariable,
|
||||||
|
getCookie,
|
||||||
|
getLocalStorage,
|
||||||
|
getToken,
|
||||||
|
setCookie,
|
||||||
|
setLocalStorage,
|
||||||
|
setToken,
|
||||||
|
removeCookie,
|
||||||
|
removeLocalStorage,
|
||||||
|
removeToken,
|
||||||
|
getCaptcha
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user