From c45cdf03a9090b32400afcf2adefa3c28af6fdc0 Mon Sep 17 00:00:00 2001 From: lanyuanxiaoyao Date: Wed, 20 Nov 2024 11:58:25 +0800 Subject: [PATCH] =?UTF-8?q?feat(web):=20=E5=A2=9E=E5=8A=A0=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E4=BA=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/user/dialog-user-check.js | 77 ++++++++++++++++--- gringotts-frontend/pages/index/tab-user.js | 2 +- .../web/domain/entity/SuperEntity.java | 50 ++++++++++++ .../domain/resource/entity/ApiResource.java | 1 - .../domain/resource/entity/DataResource.java | 19 +++-- ...DatasetResource.java => FileResource.java} | 7 +- .../controller/UserManagementController.java | 6 ++ .../web/domain/user/entity/User.java | 30 ++++---- .../web/domain/user/service/UserService.java | 69 +++++++++++++++-- 9 files changed, 210 insertions(+), 51 deletions(-) create mode 100644 gringotts-web/src/main/java/com/eshore/gringotts/web/domain/entity/SuperEntity.java rename gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/{DatasetResource.java => FileResource.java} (51%) diff --git a/gringotts-frontend/components/user/dialog-user-check.js b/gringotts-frontend/components/user/dialog-user-check.js index ab5abf4..20245dc 100644 --- a/gringotts-frontend/components/user/dialog-user-check.js +++ b/gringotts-frontend/components/user/dialog-user-check.js @@ -7,25 +7,70 @@ const dialogBody = [ label: '邮箱', }, { - type: 'control', - name: 'role', - label: '角色', + type: 'group', body: [ - mappingField('role', userRoleMapping), + { + type: 'control', + name: 'role', + label: '角色', + body: [ + mappingField('role', userRoleMapping), + ] + }, + { + type: 'control', + name: 'state', + label: '账号状态', + body: [ + mappingField('state', userStateMapping) + ] + }, ] }, { - type: 'control', - name: 'state', - label: '账号状态', + type: 'group', body: [ - mappingField('state', userStateMapping) + { + type: 'input-text', + name: 'createdUsername', + label: '创建人', + }, + { + type: 'input-datetime', + name: 'createdTime', + label: '创建时间', + }, ] }, { - type: 'input-datetime', - name: 'createTime', - label: '创建时间', + type: 'group', + body: [ + { + type: 'input-text', + name: 'modifiedUsername', + label: '最后修改人', + }, + { + type: 'input-datetime', + name: 'modifiedTime', + label: '最后修改时间', + }, + ] + }, + { + type: 'group', + body: [ + { + type: 'input-text', + name: 'checkedUsername', + label: '审核人', + }, + { + type: 'input-datetime', + name: 'checkedTime', + label: '审核时间', + }, + ] }, ] @@ -35,10 +80,14 @@ export function userDetailDialog() { dialog: { title: '账号详情', actions: [], + size: 'md', body: { type: 'form', initApi: apiGet('${base}/user_management/detail/${username}'), ...horizontalFormOptions(), + horizontal: { + left: 2, + }, static: true, body: [ ...dialogBody, @@ -64,16 +113,20 @@ export function userCheckDialog() { label: '同意', level: 'primary', actionType: 'ajax', - api: apiGet('${base}/user_management/enable/${username}'), + api: apiGet('${base}/user_management/check/${username}'), confirmTitle: '审核通过', confirmText: '确认通过账号为${username}通过审核吗?审核通过后将无法撤销。', reload: '9200849e-a8e9-4752-b4fc-ae52dc46a205', }, ], + size: 'md', body: { type: 'form', initApi: apiGet('${base}/user_management/detail/${username}'), ...horizontalFormOptions(), + horizontal: { + left: 2, + }, static: true, body: dialogBody, } diff --git a/gringotts-frontend/pages/index/tab-user.js b/gringotts-frontend/pages/index/tab-user.js index 6ff675a..c1bbd42 100644 --- a/gringotts-frontend/pages/index/tab-user.js +++ b/gringotts-frontend/pages/index/tab-user.js @@ -57,7 +57,7 @@ export function tabUser() { width: 150, align: 'center', type: 'tpl', - tpl: "${IF(createTime, DATETOSTR(createTime), '-')}" + tpl: "${IF(createdTime, DATETOSTR(createdTime), '-')}" }, { label: '上次登陆时间', diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/entity/SuperEntity.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/entity/SuperEntity.java new file mode 100644 index 0000000..fa07ff7 --- /dev/null +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/entity/SuperEntity.java @@ -0,0 +1,50 @@ +package com.eshore.gringotts.web.domain.entity; + +import com.eshore.gringotts.web.domain.user.entity.User; +import java.time.LocalDateTime; +import javax.persistence.ConstraintMode; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.MappedSuperclass; +import javax.persistence.OneToOne; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.hibernate.annotations.GenericGenerator; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +/** + * 实体类公共字段 + * + * @author lanyuanxiaoyao + * @date 2024-11-20 + */ +@Getter +@Setter +@ToString +@MappedSuperclass +@EntityListeners(AuditingEntityListener.class) +public class SuperEntity { + @Id + @GeneratedValue(generator = "snowflake") + @GenericGenerator(name = "snowflake", strategy = "com.eshore.gringotts.web.configuration.SnowflakeIdGenerator") + private Long id; + @CreatedDate + private LocalDateTime createdTime; + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(nullable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) + @ToString.Exclude + private User createdUser; + @LastModifiedDate + private LocalDateTime modifiedTime; + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(nullable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) + @ToString.Exclude + private User modifiedUser; +} diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/ApiResource.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/ApiResource.java index acceae4..244341c 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/ApiResource.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/ApiResource.java @@ -13,7 +13,6 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; @Setter @ToString @Entity -@EntityListeners(AuditingEntityListener.class) @Table(name = Constants.TABLE_PREFIX + "data_resource_api") public class ApiResource extends DataResource { private String url; diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/DataResource.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/DataResource.java index f3ee7ac..d87ced4 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/DataResource.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/DataResource.java @@ -1,12 +1,18 @@ package com.eshore.gringotts.web.domain.resource.entity; import com.eshore.gringotts.core.Constants; +import com.eshore.gringotts.web.domain.entity.SuperEntity; +import com.eshore.gringotts.web.domain.user.entity.User; import java.time.LocalDateTime; import javax.persistence.Column; -import javax.persistence.DiscriminatorColumn; +import javax.persistence.ConstraintMode; +import javax.persistence.ForeignKey; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import org.hibernate.annotations.DynamicUpdate; import org.hibernate.annotations.GenericGenerator; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; @@ -24,18 +30,11 @@ import javax.persistence.Table; @ToString @Entity @EntityListeners(AuditingEntityListener.class) +@DynamicUpdate @Table(name = Constants.TABLE_PREFIX + "data_resource") @Inheritance(strategy = InheritanceType.JOINED) -public class DataResource { - @Id - @GeneratedValue(generator = "snowflake") - @GenericGenerator(name = "snowflake", strategy = "com.eshore.gringotts.web.configuration.SnowflakeIdGenerator") - private Long id; +public class DataResource extends SuperEntity { @Column(nullable = false) private String name; private String description; - @CreatedDate - private LocalDateTime createTime; - @LastModifiedDate - private LocalDateTime updateTime; } diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/DatasetResource.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/FileResource.java similarity index 51% rename from gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/DatasetResource.java rename to gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/FileResource.java index 5276968..eb64da6 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/DatasetResource.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/resource/entity/FileResource.java @@ -2,19 +2,16 @@ package com.eshore.gringotts.web.domain.resource.entity; import com.eshore.gringotts.core.Constants; import javax.persistence.Entity; -import javax.persistence.EntityListeners; import javax.persistence.Table; import lombok.Getter; import lombok.Setter; import lombok.ToString; -import org.springframework.data.jpa.domain.support.AuditingEntityListener; @Getter @Setter @ToString @Entity -@EntityListeners(AuditingEntityListener.class) -@Table(name = Constants.TABLE_PREFIX + "data_resource_dataset") -public class DatasetResource extends DataResource{ +@Table(name = Constants.TABLE_PREFIX + "data_resource_file") +public class FileResource extends DataResource{ private String path; } diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/controller/UserManagementController.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/controller/UserManagementController.java index 09b5e10..1ea62bf 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/controller/UserManagementController.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/controller/UserManagementController.java @@ -65,6 +65,12 @@ public class UserManagementController { return AmisResponse.responseSuccess(); } + @GetMapping("/check/{username}") + public AmisResponse check(@PathVariable String username) { + userService.check(username); + return AmisResponse.responseSuccess(); + } + @Data public static final class ChangePasswordRequest { private String oldPassword; diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/entity/User.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/entity/User.java index 3c05ccd..ce57f45 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/entity/User.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/entity/User.java @@ -1,22 +1,23 @@ package com.eshore.gringotts.web.domain.user.entity; import com.eshore.gringotts.core.Constants; -import com.eshore.gringotts.web.configuration.SnowflakeIdGenerator; +import com.eshore.gringotts.web.domain.entity.SuperEntity; import java.time.LocalDateTime; import javax.persistence.Column; +import javax.persistence.ConstraintMode; import javax.persistence.Entity; import javax.persistence.EntityListeners; import javax.persistence.EnumType; import javax.persistence.Enumerated; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; import javax.persistence.Table; import lombok.Getter; import lombok.Setter; import lombok.ToString; -import org.hibernate.annotations.GenericGenerator; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.LastModifiedDate; +import org.hibernate.annotations.DynamicUpdate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; /** @@ -29,13 +30,9 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; @Setter @ToString @Entity -@EntityListeners(AuditingEntityListener.class) +@DynamicUpdate @Table(name = Constants.TABLE_PREFIX + "user") -public class User { - @Id - @GeneratedValue(generator = "snowflake") - @GenericGenerator(name = "snowflake", strategy = "com.eshore.gringotts.web.configuration.SnowflakeIdGenerator") - private Long id; +public class User extends SuperEntity { @Column(unique = true, nullable = false) private String username; @Column(nullable = false) @@ -47,10 +44,11 @@ public class User { @Enumerated(EnumType.STRING) private State state = State.CHECKING; private LocalDateTime lastLoginTime; - @CreatedDate - private LocalDateTime createTime; - @LastModifiedDate - private LocalDateTime updateTime; + private LocalDateTime checkedTime; + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) + @ToString.Exclude + private User checkedUser; public enum State { /** diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/service/UserService.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/service/UserService.java index 76e26d6..b9cd657 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/service/UserService.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/user/service/UserService.java @@ -3,6 +3,7 @@ package com.eshore.gringotts.web.domain.user.service; import cn.dev33.satoken.exception.NotLoginException; import cn.dev33.satoken.stp.SaTokenInfo; import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; import com.eshore.gringotts.web.domain.user.entity.User; @@ -15,6 +16,7 @@ import org.eclipse.collections.api.list.ImmutableList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; /** * User服务 @@ -47,6 +49,10 @@ public class UserService { user.setPassword(encryptPassword("administrator")); user.setRole(User.Role.ADMINISTRATOR); user.setState(User.State.NORMAL); + user.setCheckedUser(user); + user.setCheckedTime(LocalDateTime.now()); + user.setCreatedUser(user); + user.setModifiedUser(user); userRepository.save(user); } } @@ -66,6 +72,14 @@ public class UserService { } } + public User currentLoginUser() { + return userRepository.findById(StpUtil.getLoginIdAsLong()).orElseThrow(LoginNotFoundException::new); + } + + private User findUserByUsername(String username) { + return userRepository.findByUsername(username).orElseThrow(UserNotFoundException::new); + } + /** * 登陆操作 */ @@ -104,6 +118,8 @@ public class UserService { user.setUsername(username); user.setPassword(encryptPassword(password)); user.setRole(role); + user.setCreatedUser(user); + user.setModifiedUser(user); userRepository.save(user); } @@ -112,11 +128,17 @@ public class UserService { * 直接成功 */ public void registerFromAdministrator(String username, String password, User.Role role) { + User loginUser = currentLoginUser(); + User user = new User(); user.setUsername(username); user.setPassword(encryptPassword(password)); user.setRole(role); user.setState(User.State.NORMAL); + user.setCheckedUser(loginUser); + user.setCheckedTime(LocalDateTime.now()); + user.setCreatedUser(loginUser); + user.setModifiedUser(loginUser); userRepository.save(user); } @@ -130,15 +152,36 @@ public class UserService { /** * 禁用账号 */ + @Transactional public void disable(String username) { - userRepository.updateStateByUsername(username, User.State.DISABLED); + User loginUser = currentLoginUser(); + User user = findUserByUsername(username); + user.setState(User.State.DISABLED); + user.setModifiedUser(loginUser); + userRepository.save(user); } /** * 启用账号 */ + @Transactional public void enable(String username) { - userRepository.updateStateByUsername(username, User.State.NORMAL); + User loginUser = currentLoginUser(); + User user = findUserByUsername(username); + user.setState(User.State.NORMAL); + user.setModifiedUser(loginUser); + userRepository.save(user); + } + + @Transactional + public void check(String username) { + User loginUser = currentLoginUser(); + User user = findUserByUsername(username); + user.setState(User.State.NORMAL); + user.setCheckedUser(loginUser); + user.setCheckedTime(LocalDateTime.now()); + user.setModifiedUser(loginUser); + userRepository.save(user); } public ImmutableList list() { @@ -147,11 +190,13 @@ public class UserService { .collect(UserListItem::new); } + @Transactional public void changePassword(String oldPassword, String newPassword) { long id = StpUtil.getLoginIdAsLong(); User user = userRepository.findById(id).orElseThrow(LoginNotFoundException::new); if (StrUtil.equals(encryptPassword(oldPassword), user.getPassword())) { user.setPassword(encryptPassword(newPassword)); + user.setModifiedUser(user); userRepository.save(user); } else { throw new ChangePasswordFailureException(); @@ -235,7 +280,7 @@ public class UserService { private User.Role role; private User.State state; private LocalDateTime lastLoginTime; - private LocalDateTime createTime; + private LocalDateTime createdTime; public UserListItem(User user) { this.id = user.getId(); @@ -243,7 +288,7 @@ public class UserService { this.role = user.getRole(); this.state = user.getState(); this.lastLoginTime = user.getLastLoginTime(); - this.createTime = user.getCreateTime(); + this.createdTime = user.getCreatedTime(); } } @@ -253,14 +298,26 @@ public class UserService { private User.Role role; private User.State state; private LocalDateTime lastLoginTime; - private LocalDateTime createTime; + private LocalDateTime createdTime; + private String createdUsername; + private LocalDateTime modifiedTime; + private String modifiedUsername; + private LocalDateTime checkedTime; + private String checkedUsername; public UserDetail(User user) { this.username = user.getUsername(); this.role = user.getRole(); this.state = user.getState(); this.lastLoginTime = user.getLastLoginTime(); - this.createTime = user.getCreateTime(); + this.createdTime = user.getCreatedTime(); + this.createdUsername = user.getCreatedUser().getUsername(); + this.modifiedTime = user.getModifiedTime(); + this.modifiedUsername = user.getModifiedUser().getUsername(); + if (ObjectUtil.isNotNull(user.getCheckedUser())) { + this.checkedTime = user.getCheckedTime(); + this.checkedUsername = user.getCheckedUser().getUsername(); + } } } }