feat(web): 增加账号最后登陆时间
This commit is contained in:
@@ -48,7 +48,7 @@ export function horizontalFormOptions() {
|
|||||||
mode: 'horizontal',
|
mode: 'horizontal',
|
||||||
canAccessSuperData: false,
|
canAccessSuperData: false,
|
||||||
horizontal: {
|
horizontal: {
|
||||||
left: 2,
|
left: 3,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,6 +83,41 @@ export function paginationTemplate(perPage = 20, maxButtons = 5) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function copyField(field, tips = '复制', ignoreLength = 0, extra = undefined) {
|
||||||
|
let tpl = ignoreLength === 0 ? `\${${field}}` : `\${TRUNCATE(${field}, ${ignoreLength})}`
|
||||||
|
let content = extra
|
||||||
|
? {
|
||||||
|
type: 'action',
|
||||||
|
level: 'link',
|
||||||
|
label: `\${${field}}`,
|
||||||
|
className: 'text-current underline',
|
||||||
|
size: 'xs',
|
||||||
|
...extra,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
type: 'tpl',
|
||||||
|
className: 'mr-1',
|
||||||
|
tpl: tpl,
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type: 'wrapper',
|
||||||
|
size: 'none',
|
||||||
|
body: [
|
||||||
|
content,
|
||||||
|
{
|
||||||
|
type: 'action',
|
||||||
|
level: 'link',
|
||||||
|
label: '',
|
||||||
|
icon: 'fa fa-copy',
|
||||||
|
size: 'xs',
|
||||||
|
actionType: 'copy',
|
||||||
|
content: `\$${field}`,
|
||||||
|
tooltip: `${tips}`,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export 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>`,
|
||||||
|
|||||||
@@ -1,10 +1,63 @@
|
|||||||
import {apiGet, horizontalFormOptions, mappingField, userRoleMapping, userStateMapping} from "../constants.js";
|
import {apiGet, horizontalFormOptions, mappingField, userRoleMapping, userStateMapping} from "../constants.js";
|
||||||
|
|
||||||
|
const dialogBody = [
|
||||||
|
{
|
||||||
|
type: 'input-email',
|
||||||
|
name: 'username',
|
||||||
|
label: '邮箱',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'control',
|
||||||
|
name: 'role',
|
||||||
|
label: '角色',
|
||||||
|
body: [
|
||||||
|
mappingField('role', userRoleMapping),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'control',
|
||||||
|
name: 'state',
|
||||||
|
label: '账号状态',
|
||||||
|
body: [
|
||||||
|
mappingField('state', userStateMapping)
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input-datetime',
|
||||||
|
name: 'createTime',
|
||||||
|
label: '创建时间',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export function userDetailDialog() {
|
||||||
|
return {
|
||||||
|
actionType: 'dialog',
|
||||||
|
dialog: {
|
||||||
|
title: '账号详情',
|
||||||
|
actions: [],
|
||||||
|
body: {
|
||||||
|
type: 'form',
|
||||||
|
initApi: apiGet('${base}/user_management/detail/${username}'),
|
||||||
|
...horizontalFormOptions(),
|
||||||
|
static: true,
|
||||||
|
body: [
|
||||||
|
...dialogBody,
|
||||||
|
{
|
||||||
|
type: 'input-datetime',
|
||||||
|
name: 'lastLoginTime',
|
||||||
|
label: '上次登陆时间',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function userCheckDialog() {
|
export function userCheckDialog() {
|
||||||
return {
|
return {
|
||||||
actionType: 'dialog',
|
actionType: 'dialog',
|
||||||
dialog: {
|
dialog: {
|
||||||
title: '用户注册',
|
title: '账号审核',
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'action',
|
type: 'action',
|
||||||
@@ -22,39 +75,7 @@ export function userCheckDialog() {
|
|||||||
initApi: apiGet('${base}/user_management/detail/${username}'),
|
initApi: apiGet('${base}/user_management/detail/${username}'),
|
||||||
...horizontalFormOptions(),
|
...horizontalFormOptions(),
|
||||||
static: true,
|
static: true,
|
||||||
body: [
|
body: dialogBody,
|
||||||
{
|
|
||||||
type: 'input-email',
|
|
||||||
name: 'username',
|
|
||||||
label: '邮箱',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'control',
|
|
||||||
name: 'role',
|
|
||||||
label: '角色',
|
|
||||||
body: [
|
|
||||||
mappingField('role', userRoleMapping),
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'control',
|
|
||||||
name: 'state',
|
|
||||||
label: '账号状态',
|
|
||||||
body: [
|
|
||||||
mappingField('state', userStateMapping)
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input-datetime',
|
|
||||||
name: 'createTime',
|
|
||||||
label: '创建时间',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input-datetime',
|
|
||||||
name: 'updateTime',
|
|
||||||
label: '更新时间',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ import {apiGet, useAmis} from '../../components/constants.js'
|
|||||||
import {userChangePasswordDialog} from "../../components/user/dialog-user-change-password.js";
|
import {userChangePasswordDialog} from "../../components/user/dialog-user-change-password.js";
|
||||||
import {tabUser} from "./tab-user.js";
|
import {tabUser} from "./tab-user.js";
|
||||||
import {tabOverview} from "./tab-overview.js";
|
import {tabOverview} from "./tab-overview.js";
|
||||||
|
import {tabMarket} from "./tab-market.js";
|
||||||
|
import {tabData} from "./tab-data.js";
|
||||||
|
import {tabLog} from "./tab-log.js";
|
||||||
|
|
||||||
useAmis(information => {
|
useAmis(information => {
|
||||||
return {
|
return {
|
||||||
@@ -55,7 +58,10 @@ useAmis(information => {
|
|||||||
tabsMode: 'vertical',
|
tabsMode: 'vertical',
|
||||||
tabs: [
|
tabs: [
|
||||||
tabOverview(),
|
tabOverview(),
|
||||||
|
tabMarket(),
|
||||||
|
tabData(),
|
||||||
tabUser(),
|
tabUser(),
|
||||||
|
tabLog(),
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
9
gringotts-frontend/pages/index/tab-data.js
Normal file
9
gringotts-frontend/pages/index/tab-data.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export function tabData() {
|
||||||
|
return {
|
||||||
|
title: '数据管理',
|
||||||
|
icon: 'fa fa-database',
|
||||||
|
body: [
|
||||||
|
'hello world'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
10
gringotts-frontend/pages/index/tab-log.js
Normal file
10
gringotts-frontend/pages/index/tab-log.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export function tabLog() {
|
||||||
|
return {
|
||||||
|
visibleOn: '${role === "ADMINISTRATOR"}',
|
||||||
|
title: '系统日志',
|
||||||
|
icon: 'fa fa-file',
|
||||||
|
body: [
|
||||||
|
'hello world'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
9
gringotts-frontend/pages/index/tab-market.js
Normal file
9
gringotts-frontend/pages/index/tab-market.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export function tabMarket() {
|
||||||
|
return {
|
||||||
|
title: '数据市场',
|
||||||
|
icon: 'fa fa-store',
|
||||||
|
body: [
|
||||||
|
'hello world'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,12 @@
|
|||||||
import {apiGet, crudCommonOptions, mappingField, userRoleMapping, userStateMapping} from '../../components/constants.js'
|
import {
|
||||||
import {userCheckDialog} from "../../components/user/dialog-user-check.js";
|
apiGet,
|
||||||
|
copyField,
|
||||||
|
crudCommonOptions,
|
||||||
|
mappingField,
|
||||||
|
userRoleMapping,
|
||||||
|
userStateMapping
|
||||||
|
} from '../../components/constants.js'
|
||||||
|
import {userCheckDialog, userDetailDialog} from "../../components/user/dialog-user-check.js";
|
||||||
import {userAdministratorRegisterDialog} from "../../components/user/dialog-user-register.js";
|
import {userAdministratorRegisterDialog} from "../../components/user/dialog-user-register.js";
|
||||||
|
|
||||||
export function tabUser() {
|
export function tabUser() {
|
||||||
@@ -26,28 +33,38 @@ export function tabUser() {
|
|||||||
{
|
{
|
||||||
name: 'username',
|
name: 'username',
|
||||||
label: '邮箱',
|
label: '邮箱',
|
||||||
|
...copyField(
|
||||||
|
'username',
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
userDetailDialog(),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '角色',
|
label: '角色',
|
||||||
width: 120,
|
width: 120,
|
||||||
|
align: 'center',
|
||||||
...mappingField('role', userRoleMapping)
|
...mappingField('role', userRoleMapping)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '账号状态',
|
label: '账号状态',
|
||||||
width: 80,
|
width: 80,
|
||||||
|
align: 'center',
|
||||||
...mappingField('state', userStateMapping)
|
...mappingField('state', userStateMapping)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '创建时间',
|
label: '创建时间',
|
||||||
width: 150,
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
type: 'tpl',
|
type: 'tpl',
|
||||||
tpl: '${DATETOSTR(createTime)}'
|
tpl: "${IF(createTime, DATETOSTR(createTime), '-')}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '更新时间',
|
label: '上次登陆时间',
|
||||||
width: 150,
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
type: 'tpl',
|
type: 'tpl',
|
||||||
tpl: '${DATETOSTR(updateTime)}'
|
tpl: "${IF(lastLoginTime, DATETOSTR(lastLoginTime), '-')}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '操作',
|
label: '操作',
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ public class User {
|
|||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
private State state = State.CHECKING;
|
private State state = State.CHECKING;
|
||||||
|
private LocalDateTime lastLoginTime;
|
||||||
@CreatedDate
|
@CreatedDate
|
||||||
private LocalDateTime createTime;
|
private LocalDateTime createTime;
|
||||||
@LastModifiedDate
|
@LastModifiedDate
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ public class UserService {
|
|||||||
throw new LoginFailureException();
|
throw new LoginFailureException();
|
||||||
} else {
|
} else {
|
||||||
StpUtil.login(user.getId());
|
StpUtil.login(user.getId());
|
||||||
|
user.setLastLoginTime(LocalDateTime.now());
|
||||||
|
userRepository.save(user);
|
||||||
return new UserInformation(user, StpUtil.getTokenInfo());
|
return new UserInformation(user, StpUtil.getTokenInfo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -232,16 +234,16 @@ public class UserService {
|
|||||||
private String username;
|
private String username;
|
||||||
private User.Role role;
|
private User.Role role;
|
||||||
private User.State state;
|
private User.State state;
|
||||||
|
private LocalDateTime lastLoginTime;
|
||||||
private LocalDateTime createTime;
|
private LocalDateTime createTime;
|
||||||
private LocalDateTime updateTime;
|
|
||||||
|
|
||||||
public UserListItem(User user) {
|
public UserListItem(User user) {
|
||||||
this.id = user.getId();
|
this.id = user.getId();
|
||||||
this.username = user.getUsername();
|
this.username = user.getUsername();
|
||||||
this.role = user.getRole();
|
this.role = user.getRole();
|
||||||
this.state = user.getState();
|
this.state = user.getState();
|
||||||
|
this.lastLoginTime = user.getLastLoginTime();
|
||||||
this.createTime = user.getCreateTime();
|
this.createTime = user.getCreateTime();
|
||||||
this.updateTime = user.getUpdateTime();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,15 +252,15 @@ public class UserService {
|
|||||||
private String username;
|
private String username;
|
||||||
private User.Role role;
|
private User.Role role;
|
||||||
private User.State state;
|
private User.State state;
|
||||||
|
private LocalDateTime lastLoginTime;
|
||||||
private LocalDateTime createTime;
|
private LocalDateTime createTime;
|
||||||
private LocalDateTime updateTime;
|
|
||||||
|
|
||||||
public UserDetail(User user) {
|
public UserDetail(User user) {
|
||||||
this.username = user.getUsername();
|
this.username = user.getUsername();
|
||||||
this.role = user.getRole();
|
this.role = user.getRole();
|
||||||
this.state = user.getState();
|
this.state = user.getState();
|
||||||
|
this.lastLoginTime = user.getLastLoginTime();
|
||||||
this.createTime = user.getCreateTime();
|
this.createTime = user.getCreateTime();
|
||||||
this.updateTime = user.getUpdateTime();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user