feat(web): 使用模块化js 增加账号改密、注销
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package com.eshore.gringotts.web;
|
package com.eshore.gringotts.web;
|
||||||
|
|
||||||
import com.blinkfox.fenix.EnableFenix;
|
import com.blinkfox.fenix.EnableFenix;
|
||||||
|
import com.eshore.gringotts.web.domain.user.service.UserService;
|
||||||
import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
|
import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
|
||||||
import org.springframework.boot.ApplicationArguments;
|
import org.springframework.boot.ApplicationArguments;
|
||||||
import org.springframework.boot.ApplicationRunner;
|
import org.springframework.boot.ApplicationRunner;
|
||||||
@@ -25,12 +26,19 @@ import org.springframework.scheduling.annotation.EnableAsync;
|
|||||||
@EnableConfigurationProperties
|
@EnableConfigurationProperties
|
||||||
@EnableEncryptableProperties
|
@EnableEncryptableProperties
|
||||||
public class WebApplication implements ApplicationRunner {
|
public class WebApplication implements ApplicationRunner {
|
||||||
|
private final UserService userService;
|
||||||
|
|
||||||
|
public WebApplication(UserService userService) {
|
||||||
|
this.userService = userService;
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(WebApplication.class, args);
|
SpringApplication.run(WebApplication.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(ApplicationArguments args) throws Exception {
|
public void run(ApplicationArguments args) throws Exception {
|
||||||
// Test Something
|
// 初始化系统管理员
|
||||||
|
userService.initial();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ package com.eshore.gringotts.web.configuration;
|
|||||||
|
|
||||||
import cn.dev33.satoken.interceptor.SaInterceptor;
|
import cn.dev33.satoken.interceptor.SaInterceptor;
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
@@ -11,11 +14,18 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|||||||
* @author lanyuanxiaoyao
|
* @author lanyuanxiaoyao
|
||||||
* @date 2024-11-14
|
* @date 2024-11-14
|
||||||
*/
|
*/
|
||||||
// @Configuration
|
@Configuration
|
||||||
public class SaTokenConfiguration implements WebMvcConfigurer {
|
public class SaTokenConfiguration implements WebMvcConfigurer {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(SaTokenConfiguration.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addInterceptors(InterceptorRegistry registry) {
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
registry.addInterceptor(new SaInterceptor(handler -> StpUtil.checkLogin()))
|
registry.addInterceptor(
|
||||||
|
new SaInterceptor(handler -> {
|
||||||
|
logger.info("Handler {}", handler);
|
||||||
|
StpUtil.checkLogin();
|
||||||
|
})
|
||||||
|
)
|
||||||
.addPathPatterns("/**")
|
.addPathPatterns("/**")
|
||||||
.excludePathPatterns("/*.html")
|
.excludePathPatterns("/*.html")
|
||||||
.excludePathPatterns("/assets/**")
|
.excludePathPatterns("/assets/**")
|
||||||
|
|||||||
@@ -41,19 +41,18 @@ public class UserController {
|
|||||||
@PostMapping("/register")
|
@PostMapping("/register")
|
||||||
public void register(@RequestBody RegisterRequest request) {
|
public void register(@RequestBody RegisterRequest request) {
|
||||||
logger.info("Register request: {}", request);
|
logger.info("Register request: {}", request);
|
||||||
userService.register(request);
|
userService.register(request.username, request.password, request.role);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/login")
|
@PostMapping("/login")
|
||||||
public AmisResponse<UserService.UserInformation> login(@RequestBody LoginRequest request) {
|
public AmisResponse<UserService.UserInformation> login(@RequestBody LoginRequest request) {
|
||||||
logger.info("Login request: {}", request);
|
logger.info("Login request: {}", request);
|
||||||
return AmisResponse.responseSuccess(userService.login(request));
|
return AmisResponse.responseSuccess(userService.login(request.username, request.password));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/logout/{username}")
|
@GetMapping("/logout")
|
||||||
public void logout(@PathVariable("username") String username) {
|
public void logout() {
|
||||||
logger.info("Logout request: {}", username);
|
userService.logout();
|
||||||
userService.logout(username);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/exists_username/{username}")
|
@GetMapping("/exists_username/{username}")
|
||||||
@@ -64,14 +63,14 @@ public class UserController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class LoginRequest {
|
public static final class LoginRequest {
|
||||||
private String username;
|
private String username;
|
||||||
private String password;
|
private String password;
|
||||||
private String checkCode;
|
private String checkCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class RegisterRequest {
|
public static final class RegisterRequest {
|
||||||
private String username;
|
private String username;
|
||||||
private String password;
|
private String password;
|
||||||
private User.Role role;
|
private User.Role role;
|
||||||
|
|||||||
@@ -3,10 +3,13 @@ package com.eshore.gringotts.web.domain.user.controller;
|
|||||||
import com.eshore.gringotts.web.configuration.amis.AmisListResponse;
|
import com.eshore.gringotts.web.configuration.amis.AmisListResponse;
|
||||||
import com.eshore.gringotts.web.configuration.amis.AmisResponse;
|
import com.eshore.gringotts.web.configuration.amis.AmisResponse;
|
||||||
import com.eshore.gringotts.web.domain.user.service.UserService;
|
import com.eshore.gringotts.web.domain.user.service.UserService;
|
||||||
|
import lombok.Data;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
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.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
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;
|
||||||
|
|
||||||
@@ -32,6 +35,17 @@ public class UserManagementController {
|
|||||||
return AmisListResponse.responseListData(userService.list());
|
return AmisListResponse.responseListData(userService.list());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/detail/{username}")
|
||||||
|
public AmisResponse<UserService.UserDetail> detail(@PathVariable String username) {
|
||||||
|
return AmisResponse.responseSuccess(userService.detail(username));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/change_password")
|
||||||
|
public AmisResponse<Object> changePassword(@RequestBody ChangePasswordRequest request) {
|
||||||
|
userService.changePassword(request.oldPassword, request.newPassword);
|
||||||
|
return AmisResponse.responseSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/disable/{username}")
|
@GetMapping("/disable/{username}")
|
||||||
public AmisResponse<Object> disable(@PathVariable String username) {
|
public AmisResponse<Object> disable(@PathVariable String username) {
|
||||||
userService.disable(username);
|
userService.disable(username);
|
||||||
@@ -43,4 +57,10 @@ public class UserManagementController {
|
|||||||
userService.enable(username);
|
userService.enable(username);
|
||||||
return AmisResponse.responseSuccess();
|
return AmisResponse.responseSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static final class ChangePasswordRequest {
|
||||||
|
private String oldPassword;
|
||||||
|
private String newPassword;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import cn.dev33.satoken.stp.SaTokenInfo;
|
|||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.crypto.SecureUtil;
|
import cn.hutool.crypto.SecureUtil;
|
||||||
import com.eshore.gringotts.web.domain.user.controller.UserController;
|
|
||||||
import com.eshore.gringotts.web.domain.user.entity.User;
|
import com.eshore.gringotts.web.domain.user.entity.User;
|
||||||
import com.eshore.gringotts.web.domain.user.repository.UserRepository;
|
import com.eshore.gringotts.web.domain.user.repository.UserRepository;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@@ -33,11 +32,33 @@ public class UserService {
|
|||||||
this.userRepository = userRepository;
|
this.userRepository = userRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String encryptPassword(String password) {
|
||||||
|
String salt = "tY2gNdkt7x%%HcCAFc";
|
||||||
|
return SecureUtil.sha256(StrUtil.format("{}{}", salt, password));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当数据库里没有用户的时候,增加一个默认的系统管理员
|
||||||
|
*/
|
||||||
|
public void initial() {
|
||||||
|
if (userRepository.count() == 0) {
|
||||||
|
User user = new User();
|
||||||
|
user.setUsername("administrator@eshore.com");
|
||||||
|
user.setPassword(encryptPassword("administrator"));
|
||||||
|
user.setRole(User.Role.ADMINISTRATOR);
|
||||||
|
user.setState(User.State.NORMAL);
|
||||||
|
userRepository.save(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前登陆账号状态
|
||||||
|
*/
|
||||||
public UserInformation state() {
|
public UserInformation state() {
|
||||||
try {
|
try {
|
||||||
// long id = StpUtil.getLoginIdAsLong();
|
long id = StpUtil.getLoginIdAsLong();
|
||||||
// User user = userRepository.findById(id).orElseThrow(LoginNotFoundException::new);
|
User user = userRepository.findById(id).orElseThrow(LoginNotFoundException::new);
|
||||||
User user = userRepository.findByUsername("lanyuanxiaoyao@qq.com").orElseThrow(LoginNotFoundException::new);
|
// User user = userRepository.findByUsername("administrator@eshore.com").orElseThrow(LoginNotFoundException::new);
|
||||||
StpUtil.login(user.getId());
|
StpUtil.login(user.getId());
|
||||||
return new UserInformation(user, StpUtil.getTokenInfo());
|
return new UserInformation(user, StpUtil.getTokenInfo());
|
||||||
} catch (NotLoginException e) {
|
} catch (NotLoginException e) {
|
||||||
@@ -45,13 +66,16 @@ public class UserService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserInformation login(UserController.LoginRequest request) {
|
/**
|
||||||
User user = userRepository.findByUsername(request.getUsername()).orElseThrow(LoginFailureException::new);
|
* 登陆操作
|
||||||
|
*/
|
||||||
|
public UserInformation login(String username, String password) {
|
||||||
|
User user = userRepository.findByUsername(username).orElseThrow(LoginFailureException::new);
|
||||||
if (user.getState() == User.State.CHECKING) {
|
if (user.getState() == User.State.CHECKING) {
|
||||||
throw new LoginFailureByCheckingException();
|
throw new LoginFailureByCheckingException();
|
||||||
} else if (user.getState() == User.State.DISABLED) {
|
} else if (user.getState() == User.State.DISABLED) {
|
||||||
throw new LoginFailureByDisabledException();
|
throw new LoginFailureByDisabledException();
|
||||||
} else if (!StrUtil.equals(encryptPassword(request.getPassword()), user.getPassword())) {
|
} else if (!StrUtil.equals(encryptPassword(password), user.getPassword())) {
|
||||||
throw new LoginFailureException();
|
throw new LoginFailureException();
|
||||||
} else {
|
} else {
|
||||||
StpUtil.login(user.getId());
|
StpUtil.login(user.getId());
|
||||||
@@ -59,23 +83,41 @@ public class UserService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void logout(String username) {
|
/**
|
||||||
User user = userRepository.findByUsername(username).orElseThrow(LogoutFailureException::new);
|
* 登出操作
|
||||||
StpUtil.login(user.getId());
|
*/
|
||||||
|
public void logout() {
|
||||||
|
StpUtil.logout();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void register(UserController.RegisterRequest request) {
|
/**
|
||||||
userRepository.save(toUser(request));
|
* 注册操作
|
||||||
|
*/
|
||||||
|
public void register(String username, String password, User.Role role) {
|
||||||
|
User user = new User();
|
||||||
|
user.setUsername(username);
|
||||||
|
user.setPassword(encryptPassword(password));
|
||||||
|
user.setRole(role);
|
||||||
|
userRepository.save(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否存在用户名
|
||||||
|
*/
|
||||||
public boolean exitsUsername(String username) {
|
public boolean exitsUsername(String username) {
|
||||||
return userRepository.existsByUsername(username);
|
return userRepository.existsByUsername(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 禁用账号
|
||||||
|
*/
|
||||||
public void disable(String username) {
|
public void disable(String username) {
|
||||||
userRepository.updateStateByUsername(username, User.State.DISABLED);
|
userRepository.updateStateByUsername(username, User.State.DISABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用账号
|
||||||
|
*/
|
||||||
public void enable(String username) {
|
public void enable(String username) {
|
||||||
userRepository.updateStateByUsername(username, User.State.NORMAL);
|
userRepository.updateStateByUsername(username, User.State.NORMAL);
|
||||||
}
|
}
|
||||||
@@ -86,17 +128,26 @@ public class UserService {
|
|||||||
.collect(UserListItem::new);
|
.collect(UserListItem::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String encryptPassword(String password) {
|
public void changePassword(String oldPassword, String newPassword) {
|
||||||
String salt = "tY2gNdkt7x%%HcCAFc";
|
long id = StpUtil.getLoginIdAsLong();
|
||||||
return SecureUtil.sha256(StrUtil.format("{}{}", salt, password));
|
User user = userRepository.findById(id).orElseThrow(LoginNotFoundException::new);
|
||||||
|
if (StrUtil.equals(encryptPassword(oldPassword), user.getPassword())) {
|
||||||
|
user.setPassword(encryptPassword(newPassword));
|
||||||
|
userRepository.save(user);
|
||||||
|
} else {
|
||||||
|
throw new ChangePasswordFailureException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private User toUser(UserController.RegisterRequest request) {
|
public UserDetail detail(String username) {
|
||||||
User user = new User();
|
User user = userRepository.findByUsername(username).orElseThrow(UserNotFoundException::new);
|
||||||
user.setUsername(request.getUsername());
|
return new UserDetail(user);
|
||||||
user.setPassword(encryptPassword(request.getPassword()));
|
}
|
||||||
user.setRole(request.getRole());
|
|
||||||
return user;
|
public static class UserNotFoundException extends RuntimeException {
|
||||||
|
public UserNotFoundException() {
|
||||||
|
super("账号不存在");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class LoginFailureException extends RuntimeException {
|
public static class LoginFailureException extends RuntimeException {
|
||||||
@@ -133,6 +184,12 @@ public class UserService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class ChangePasswordFailureException extends RuntimeException {
|
||||||
|
public ChangePasswordFailureException() {
|
||||||
|
super("原密码不正确");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class UserInformation {
|
public static class UserInformation {
|
||||||
private String username;
|
private String username;
|
||||||
@@ -164,4 +221,23 @@ public class UserService {
|
|||||||
this.updateTime = user.getUpdateTime();
|
this.updateTime = user.getUpdateTime();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class UserDetail {
|
||||||
|
private Long id;
|
||||||
|
private String username;
|
||||||
|
private User.Role role;
|
||||||
|
private User.State state;
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
|
public UserDetail(User user) {
|
||||||
|
this.id = user.getId();
|
||||||
|
this.username = user.getUsername();
|
||||||
|
this.role = user.getRole();
|
||||||
|
this.state = user.getState();
|
||||||
|
this.createTime = user.getCreateTime();
|
||||||
|
this.updateTime = user.getUpdateTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
function crudCommonOptions() {
|
export function crudCommonOptions() {
|
||||||
return {
|
return {
|
||||||
affixHeader: false,
|
affixHeader: false,
|
||||||
stopAutoRefreshWhenModalIsOpen: true,
|
stopAutoRefreshWhenModalIsOpen: true,
|
||||||
@@ -8,7 +8,7 @@ function crudCommonOptions() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function readOnlyDialogOptions() {
|
export function readOnlyDialogOptions() {
|
||||||
return {
|
return {
|
||||||
actions: [],
|
actions: [],
|
||||||
showCloseButton: false,
|
showCloseButton: false,
|
||||||
@@ -18,7 +18,17 @@ function readOnlyDialogOptions() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function paginationCommonOptions(perPage = true, maxButtons = 5) {
|
export function horizontalFormOptions() {
|
||||||
|
return {
|
||||||
|
mode: 'horizontal',
|
||||||
|
canAccessSuperData: false,
|
||||||
|
horizontal: {
|
||||||
|
left: 2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function paginationCommonOptions(perPage = true, maxButtons = 5) {
|
||||||
let option = {
|
let option = {
|
||||||
type: 'pagination',
|
type: 'pagination',
|
||||||
layout: [
|
layout: [
|
||||||
@@ -34,7 +44,7 @@ function paginationCommonOptions(perPage = true, maxButtons = 5) {
|
|||||||
return option
|
return option
|
||||||
}
|
}
|
||||||
|
|
||||||
function paginationTemplate(perPage = 20, maxButtons = 5) {
|
export function paginationTemplate(perPage = 20, maxButtons = 5) {
|
||||||
return {
|
return {
|
||||||
perPage: perPage,
|
perPage: perPage,
|
||||||
headerToolbar: [
|
headerToolbar: [
|
||||||
@@ -48,7 +58,7 @@ function paginationTemplate(perPage = 20, maxButtons = 5) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mappingField(field, mapping) {
|
export function mappingField(field, mapping) {
|
||||||
let mapData = {
|
let mapData = {
|
||||||
'*': `<span class='label bg-gray-300'>\${${field}}</span>`,
|
'*': `<span class='label bg-gray-300'>\${${field}}</span>`,
|
||||||
}
|
}
|
||||||
@@ -70,97 +80,33 @@ function mappingItem(label, value, color = 'bg-info') {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const userRoleMapping = [
|
export const userRoleMapping = [
|
||||||
mappingItem('数据提供方', 'PROVIDER', 'bg-blue-500'),
|
mappingItem('数据提供方', 'PROVIDER', 'bg-blue-500'),
|
||||||
mappingItem('数据使用方', 'CUSTOMER', 'bg-purple-500'),
|
mappingItem('数据使用方', 'CUSTOMER', 'bg-purple-500'),
|
||||||
mappingItem('审核监管方', 'CHECKER', 'bg-cyan-500'),
|
mappingItem('审核监管方', 'CHECKER', 'bg-cyan-500'),
|
||||||
mappingItem('系统管理员', 'ADMINISTRATOR', 'bg-green-500'),
|
mappingItem('系统管理员', 'ADMINISTRATOR', 'bg-green-500'),
|
||||||
]
|
]
|
||||||
|
|
||||||
const userStateMapping = [
|
export const userStateMapping = [
|
||||||
mappingItem('审查中', 'CHECKING', 'bg-warning'),
|
mappingItem('审查中', 'CHECKING', 'bg-warning'),
|
||||||
mappingItem('正常', 'NORMAL', 'bg-success'),
|
mappingItem('正常', 'NORMAL', 'bg-success'),
|
||||||
mappingItem('禁用', 'DISABLED', 'bg-danger'),
|
mappingItem('禁用', 'DISABLED', 'bg-danger'),
|
||||||
]
|
]
|
||||||
|
|
||||||
function userAddDialog() {
|
function api(method, url) {
|
||||||
return {
|
return {
|
||||||
actionType: 'dialog',
|
method: method,
|
||||||
dialog: {
|
url: url,
|
||||||
title: '新用户注册',
|
headers: {
|
||||||
actions: [
|
token: '${token|default:undefined}',
|
||||||
{
|
|
||||||
type: 'reset',
|
|
||||||
label: '清空',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'submit',
|
|
||||||
label: '注册',
|
|
||||||
level: 'primary',
|
|
||||||
}
|
|
||||||
],
|
|
||||||
body: {
|
|
||||||
type: 'form',
|
|
||||||
api: '${base}/user/register',
|
|
||||||
mode: 'horizontal',
|
|
||||||
canAccessSuperData: false,
|
|
||||||
horizontal: {
|
|
||||||
left: 2,
|
|
||||||
},
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'input-email',
|
|
||||||
name: 'username',
|
|
||||||
label: '邮箱',
|
|
||||||
placeholder: '请输入邮箱',
|
|
||||||
required: true,
|
|
||||||
clearable: true,
|
|
||||||
clearValueOnEmpty: true,
|
|
||||||
validateApi: '${base}/user/exists_username/${username}'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input-password',
|
|
||||||
name: 'password',
|
|
||||||
label: '密码',
|
|
||||||
placeholder: '请输入密码',
|
|
||||||
required: true,
|
|
||||||
clearable: true,
|
|
||||||
clearValueOnEmpty: true,
|
|
||||||
validations: {
|
|
||||||
matchRegexp: /^(?=.*\d)(?!.*(\d)\1{2})(?!.*(012|123|234|345|456|567|678|789|987|876|765|654|543|432|321|210))(?=.*[a-zA-Z])(?=.*[^\da-zA-Z\s]).{8,16}$/
|
|
||||||
},
|
|
||||||
validationErrors: {
|
|
||||||
matchRegexp: '密码至少包含字母、数字、特殊字符,8-16位,并且不能连续出现3个大小连续或相同的数字',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input-password',
|
|
||||||
name: 'confirm-password',
|
|
||||||
label: '确认密码',
|
|
||||||
placeholder: '请再次输入密码',
|
|
||||||
required: true,
|
|
||||||
clearable: true,
|
|
||||||
validations: {
|
|
||||||
equalsField: 'password'
|
|
||||||
},
|
|
||||||
validationErrors: {
|
|
||||||
equalsField: '两次输入密码不一致',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'radios',
|
|
||||||
name: 'role',
|
|
||||||
label: '角色',
|
|
||||||
required: true,
|
|
||||||
selectFirst: true,
|
|
||||||
options: [
|
|
||||||
{label: '数据提供方', value: 'PROVIDER'},
|
|
||||||
{label: '数据使用方', value: 'CUSTOMER'},
|
|
||||||
{label: '审查监管方', value: 'CHECKER'},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function apiGet(url) {
|
||||||
|
return api('get', url)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function apiPost(url) {
|
||||||
|
return api('post', url)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
const information = {
|
export const information = {
|
||||||
debug: false,
|
debug: true,
|
||||||
baseUrl: 'http://127.0.0.1:20080',
|
baseUrl: '',
|
||||||
|
// baseUrl: 'http://127.0.0.1:20080',
|
||||||
title: '可信供给中心',
|
title: '可信供给中心',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
function overviewTab() {
|
export function tabOverview() {
|
||||||
return {
|
return {
|
||||||
title: '概览',
|
title: '概览',
|
||||||
icon: 'fa fa-house',
|
icon: 'fa fa-house',
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
function userTab() {
|
import {userRegisterDialog} from './user/dialog-user-register.js'
|
||||||
|
import {apiGet, crudCommonOptions, mappingField, userRoleMapping, userStateMapping} from '../common.js'
|
||||||
|
|
||||||
|
export function tabUser() {
|
||||||
return {
|
return {
|
||||||
title: '用户管理',
|
title: '用户管理',
|
||||||
icon: 'fa fa-user',
|
icon: 'fa fa-user',
|
||||||
body: [
|
body: [
|
||||||
{
|
{
|
||||||
type: 'crud',
|
type: 'crud',
|
||||||
api: {
|
api: apiGet('${base}/user_management/list'),
|
||||||
method: 'get',
|
|
||||||
url: '${base}/user_management/list'
|
|
||||||
},
|
|
||||||
...crudCommonOptions(),
|
...crudCommonOptions(),
|
||||||
headerToolbar: [
|
headerToolbar: [
|
||||||
'reload',
|
'reload',
|
||||||
@@ -16,8 +16,8 @@ function userTab() {
|
|||||||
type: 'action',
|
type: 'action',
|
||||||
icon: 'fa fa-plus',
|
icon: 'fa fa-plus',
|
||||||
tooltip: '新增账号',
|
tooltip: '新增账号',
|
||||||
...userAddDialog(),
|
...userRegisterDialog(),
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
@@ -61,7 +61,7 @@ function userTab() {
|
|||||||
size: 'xs',
|
size: 'xs',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
visibleOn: "${state === 'NORMAL'}",
|
visibleOn: "${state === 'NORMAL' && role !== 'ADMINISTRATOR'}",
|
||||||
label: '禁用',
|
label: '禁用',
|
||||||
icon: 'fa fa-ban',
|
icon: 'fa fa-ban',
|
||||||
level: 'danger',
|
level: 'danger',
|
||||||
@@ -73,7 +73,7 @@ function userTab() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
visibleOn: "${state === 'DISABLED'}",
|
visibleOn: "${state === 'DISABLED' && role !== 'ADMINISTRATOR'}",
|
||||||
label: '启用',
|
label: '启用',
|
||||||
icon: 'fa fa-check',
|
icon: 'fa fa-check',
|
||||||
level: 'success',
|
level: 'success',
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
import {horizontalFormOptions, apiPost} from '../../common.js'
|
||||||
|
|
||||||
|
export function userChangePasswordDialog() {
|
||||||
|
return {
|
||||||
|
actionType: 'dialog',
|
||||||
|
dialog: {
|
||||||
|
title: '修改密码',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
type: 'reset',
|
||||||
|
label: '清空',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'submit',
|
||||||
|
label: '修改',
|
||||||
|
level: 'primary',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
body: {
|
||||||
|
type: 'form',
|
||||||
|
api: apiPost('${base}/user_management/change_password'),
|
||||||
|
...horizontalFormOptions(),
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'input-password',
|
||||||
|
name: 'oldPassword',
|
||||||
|
label: '旧密码',
|
||||||
|
placeholder: '请输入旧密码',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input-password',
|
||||||
|
name: 'newPassword',
|
||||||
|
label: '新密码',
|
||||||
|
placeholder: '请输入新密码',
|
||||||
|
required: true,
|
||||||
|
clearable: true,
|
||||||
|
clearValueOnEmpty: true,
|
||||||
|
validations: {
|
||||||
|
matchRegexp: /^(?=.*\d)(?!.*(\d)\1{2})(?!.*(012|123|234|345|456|567|678|789|987|876|765|654|543|432|321|210))(?=.*[a-zA-Z])(?=.*[^\da-zA-Z\s]).{8,16}$/
|
||||||
|
},
|
||||||
|
validationErrors: {
|
||||||
|
matchRegexp: '密码至少包含字母、数字、特殊字符,8-16位,并且不能连续出现3个大小连续或相同的数字',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input-password',
|
||||||
|
name: 'confirmNewPassword',
|
||||||
|
label: '确认新密码',
|
||||||
|
placeholder: '请再次输入新密码',
|
||||||
|
required: true,
|
||||||
|
clearable: true,
|
||||||
|
validations: {
|
||||||
|
equalsField: 'newPassword'
|
||||||
|
},
|
||||||
|
validationErrors: {
|
||||||
|
equalsField: '两次输入密码不一致',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import {horizontalFormOptions} from "../../common.js";
|
||||||
|
|
||||||
|
export function userDetailDialog() {
|
||||||
|
return {
|
||||||
|
actionType: 'dialog',
|
||||||
|
dialog: {
|
||||||
|
title: '用户注册',
|
||||||
|
actions: [],
|
||||||
|
body: {
|
||||||
|
type: 'form',
|
||||||
|
api: '${base}/user_management/detail/${username}',
|
||||||
|
...horizontalFormOptions(),
|
||||||
|
static: true,
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'input-email',
|
||||||
|
name: 'username',
|
||||||
|
label: '邮箱',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input-password',
|
||||||
|
name: 'password',
|
||||||
|
label: '密码',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'radios',
|
||||||
|
name: 'role',
|
||||||
|
label: '角色',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import {horizontalFormOptions} from "../../common.js";
|
||||||
|
|
||||||
|
export function userRegisterDialog() {
|
||||||
|
return {
|
||||||
|
actionType: 'dialog',
|
||||||
|
dialog: {
|
||||||
|
title: '用户注册',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
type: 'reset',
|
||||||
|
label: '清空',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'submit',
|
||||||
|
label: '注册',
|
||||||
|
level: 'primary',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
body: {
|
||||||
|
type: 'form',
|
||||||
|
api: '${base}/user/register',
|
||||||
|
...horizontalFormOptions(),
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'input-email',
|
||||||
|
name: 'username',
|
||||||
|
label: '邮箱',
|
||||||
|
placeholder: '请输入邮箱',
|
||||||
|
required: true,
|
||||||
|
clearable: true,
|
||||||
|
clearValueOnEmpty: true,
|
||||||
|
validateApi: '${base}/user/exists_username/${username}'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input-password',
|
||||||
|
name: 'password',
|
||||||
|
label: '密码',
|
||||||
|
placeholder: '请输入密码',
|
||||||
|
required: true,
|
||||||
|
clearable: true,
|
||||||
|
clearValueOnEmpty: true,
|
||||||
|
validations: {
|
||||||
|
matchRegexp: /^(?=.*\d)(?!.*(\d)\1{2})(?!.*(012|123|234|345|456|567|678|789|987|876|765|654|543|432|321|210))(?=.*[a-zA-Z])(?=.*[^\da-zA-Z\s]).{8,16}$/
|
||||||
|
},
|
||||||
|
validationErrors: {
|
||||||
|
matchRegexp: '密码至少包含字母、数字、特殊字符,8-16位,并且不能连续出现3个大小连续或相同的数字',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input-password',
|
||||||
|
name: 'confirm-password',
|
||||||
|
label: '确认密码',
|
||||||
|
placeholder: '请再次输入密码',
|
||||||
|
required: true,
|
||||||
|
clearable: true,
|
||||||
|
validations: {
|
||||||
|
equalsField: 'password'
|
||||||
|
},
|
||||||
|
validationErrors: {
|
||||||
|
equalsField: '两次输入密码不一致',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'radios',
|
||||||
|
name: 'role',
|
||||||
|
label: '角色',
|
||||||
|
required: true,
|
||||||
|
selectFirst: true,
|
||||||
|
options: [
|
||||||
|
{label: '数据提供方', value: 'PROVIDER'},
|
||||||
|
{label: '数据使用方', value: 'CUSTOMER'},
|
||||||
|
{label: '审查监管方', value: 'CHECKER'},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,23 +23,20 @@
|
|||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
</body>
|
</body>
|
||||||
<script src="assets/sdk/sdk.js"></script>
|
<script src="assets/sdk/sdk.js"></script>
|
||||||
<script src="assets/component/constants.js"></script>
|
<script type="module">
|
||||||
<script src="assets/component/common.js"></script>
|
import {information} from './assets/component/constants.js'
|
||||||
<script src="assets/component/pages/overview-tab.js"></script>
|
import {userChangePasswordDialog} from './assets/component/pages/user/dialog-user-change-password'
|
||||||
<script src="assets/component/pages/user-tab.js"></script>
|
import {tabUser} from './assets/component/pages/tab-user.js'
|
||||||
<script>
|
import {tabOverview} from './assets/component/pages/tab-overview.js'
|
||||||
|
import {apiGet} from "./assets/component/common.js";
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
let amis = amisRequire('amis/embed')
|
let amis = amisRequire('amis/embed')
|
||||||
let amisJSON = {
|
let amisJSON = {
|
||||||
|
id: 'header-service',
|
||||||
className: 'h-full',
|
className: 'h-full',
|
||||||
type: 'service',
|
type: 'service',
|
||||||
api: {
|
api: apiGet('${base}/user/state'),
|
||||||
method: 'get',
|
|
||||||
url: '${base}/user/state',
|
|
||||||
headers: {
|
|
||||||
token: '${token}'
|
|
||||||
},
|
|
||||||
},
|
|
||||||
onEvent: {
|
onEvent: {
|
||||||
fetchInited: {
|
fetchInited: {
|
||||||
actions: [
|
actions: [
|
||||||
@@ -48,6 +45,7 @@
|
|||||||
actionType: 'url',
|
actionType: 'url',
|
||||||
args: {
|
args: {
|
||||||
url: '/login.html',
|
url: '/login.html',
|
||||||
|
blank: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -66,10 +64,14 @@
|
|||||||
trigger: 'hover',
|
trigger: 'hover',
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
label: '个人资料',
|
label: '修改密码',
|
||||||
|
...userChangePasswordDialog(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '退出登陆',
|
label: '退出登陆',
|
||||||
|
actionType: 'ajax',
|
||||||
|
api: apiGet('${base}/user/logout'),
|
||||||
|
reload: 'header-service',
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -80,14 +82,13 @@
|
|||||||
type: 'tabs',
|
type: 'tabs',
|
||||||
tabsMode: 'vertical',
|
tabsMode: 'vertical',
|
||||||
tabs: [
|
tabs: [
|
||||||
userTab(),
|
tabOverview(),
|
||||||
overviewTab(),
|
tabUser(),
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
let debug = false
|
|
||||||
amis.embed(
|
amis.embed(
|
||||||
'#root',
|
'#root',
|
||||||
amisJSON,
|
amisJSON,
|
||||||
@@ -98,10 +99,10 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
theme: 'antd',
|
theme: 'antd',
|
||||||
enableAMISDebug: debug,
|
enableAMISDebug: information.debug,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (debug) {
|
if (information.debug) {
|
||||||
console.log('Source', amisJSON)
|
console.log('Source', amisJSON)
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
|||||||
@@ -23,9 +23,11 @@
|
|||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
</body>
|
</body>
|
||||||
<script src="assets/sdk/sdk.js"></script>
|
<script src="assets/sdk/sdk.js"></script>
|
||||||
<script src="assets/component/constants.js"></script>
|
|
||||||
<script src="assets/component/common.js"></script>
|
<script src="assets/component/common.js"></script>
|
||||||
<script>
|
<script type="module">
|
||||||
|
import {information} from './assets/component/constants.js'
|
||||||
|
import {userRegisterDialog} from './assets/component/pages/user/dialog-user-register'
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
let amis = amisRequire('amis/embed')
|
let amis = amisRequire('amis/embed')
|
||||||
let amisJSON = {
|
let amisJSON = {
|
||||||
@@ -53,11 +55,14 @@
|
|||||||
api: '${base}/user/login',
|
api: '${base}/user/login',
|
||||||
redirect: '/index.html?token=${token}',
|
redirect: '/index.html?token=${token}',
|
||||||
mode: 'horizontal',
|
mode: 'horizontal',
|
||||||
|
horizontal: {
|
||||||
|
left: 2,
|
||||||
|
},
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'action',
|
type: 'action',
|
||||||
label: '注册',
|
label: '注册',
|
||||||
...userAddDialog(),
|
...userRegisterDialog(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'action',
|
type: 'action',
|
||||||
|
|||||||
Reference in New Issue
Block a user