Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
b38ba50e
authored
Dec 27, 2023
by
CaIon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
用户注销后禁止再次注册
parent
b5b6fcef
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
99 additions
and
53 deletions
+99
-53
controller/user.go
+16
-1
model/user.go
+46
-21
web/src/components/UsersTable.js
+37
-31
No files found.
controller/user.go
View file @
b38ba50e
...
...
@@ -152,6 +152,21 @@ func Register(c *gin.Context) {
return
}
}
exist
,
err
:=
model
.
CheckUserExistOrDeleted
(
user
.
Username
,
user
.
Email
)
if
err
!=
nil
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
false
,
"message"
:
err
.
Error
(),
})
return
}
if
exist
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
false
,
"message"
:
"用户名已存在,或已注销"
,
})
return
}
affCode
:=
user
.
AffCode
// this code is the inviter's code, not the user's own code
inviterId
,
_
:=
model
.
GetUserIdByAffCode
(
affCode
)
cleanUser
:=
model
.
User
{
...
...
@@ -525,7 +540,7 @@ func DeleteUser(c *gin.Context) {
})
return
}
err
=
model
.
DeleteUserById
(
id
)
err
=
model
.
Hard
DeleteUserById
(
id
)
if
err
!=
nil
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
true
,
...
...
model/user.go
View file @
b38ba50e
...
...
@@ -11,26 +11,43 @@ import (
// User if you add sensitive fields, don't forget to clean them in setupLogin function.
// Otherwise, the sensitive information will be saved on local storage in plain text!
type
User
struct
{
Id
int
`json:"id"`
Username
string
`json:"username" gorm:"unique;index" validate:"max=12"`
Password
string
`json:"password" gorm:"not null;" validate:"min=8,max=20"`
DisplayName
string
`json:"display_name" gorm:"index" validate:"max=20"`
Role
int
`json:"role" gorm:"type:int;default:1"`
// admin, common
Status
int
`json:"status" gorm:"type:int;default:1"`
// enabled, disabled
Email
string
`json:"email" gorm:"index" validate:"max=50"`
GitHubId
string
`json:"github_id" gorm:"column:github_id;index"`
WeChatId
string
`json:"wechat_id" gorm:"column:wechat_id;index"`
VerificationCode
string
`json:"verification_code" gorm:"-:all"`
// this field is only for Email verification, don't save it to database!
AccessToken
string
`json:"access_token" gorm:"type:char(32);column:access_token;uniqueIndex"`
// this token is for system management
Quota
int
`json:"quota" gorm:"type:int;default:0"`
UsedQuota
int
`json:"used_quota" gorm:"type:int;default:0;column:used_quota"`
// used quota
RequestCount
int
`json:"request_count" gorm:"type:int;default:0;"`
// request number
Group
string
`json:"group" gorm:"type:varchar(32);default:'default'"`
AffCode
string
`json:"aff_code" gorm:"type:varchar(32);column:aff_code;uniqueIndex"`
AffCount
int
`json:"aff_count" gorm:"type:int;default:0;column:aff_count"`
AffQuota
int
`json:"aff_quota" gorm:"type:int;default:0;column:aff_quota"`
// 邀请剩余额度
AffHistoryQuota
int
`json:"aff_history_quota" gorm:"type:int;default:0;column:aff_history"`
// 邀请历史额度
InviterId
int
`json:"inviter_id" gorm:"type:int;column:inviter_id;index"`
Id
int
`json:"id"`
Username
string
`json:"username" gorm:"unique;index" validate:"max=12"`
Password
string
`json:"password" gorm:"not null;" validate:"min=8,max=20"`
DisplayName
string
`json:"display_name" gorm:"index" validate:"max=20"`
Role
int
`json:"role" gorm:"type:int;default:1"`
// admin, common
Status
int
`json:"status" gorm:"type:int;default:1"`
// enabled, disabled
Email
string
`json:"email" gorm:"index" validate:"max=50"`
GitHubId
string
`json:"github_id" gorm:"column:github_id;index"`
WeChatId
string
`json:"wechat_id" gorm:"column:wechat_id;index"`
VerificationCode
string
`json:"verification_code" gorm:"-:all"`
// this field is only for Email verification, don't save it to database!
AccessToken
string
`json:"access_token" gorm:"type:char(32);column:access_token;uniqueIndex"`
// this token is for system management
Quota
int
`json:"quota" gorm:"type:int;default:0"`
UsedQuota
int
`json:"used_quota" gorm:"type:int;default:0;column:used_quota"`
// used quota
RequestCount
int
`json:"request_count" gorm:"type:int;default:0;"`
// request number
Group
string
`json:"group" gorm:"type:varchar(32);default:'default'"`
AffCode
string
`json:"aff_code" gorm:"type:varchar(32);column:aff_code;uniqueIndex"`
AffCount
int
`json:"aff_count" gorm:"type:int;default:0;column:aff_count"`
AffQuota
int
`json:"aff_quota" gorm:"type:int;default:0;column:aff_quota"`
// 邀请剩余额度
AffHistoryQuota
int
`json:"aff_history_quota" gorm:"type:int;default:0;column:aff_history"`
// 邀请历史额度
InviterId
int
`json:"inviter_id" gorm:"type:int;column:inviter_id;index"`
DeletedAt
gorm
.
DeletedAt
`json:"deleted_at" gorm:"index"`
}
// CheckUserExistOrDeleted check if user exist or deleted, if not exist, return false, nil, if deleted or exist, return true, nil
func
CheckUserExistOrDeleted
(
username
string
,
email
string
)
(
bool
,
error
)
{
var
user
User
err
:=
DB
.
Unscoped
()
.
First
(
&
user
,
"username = ? or email = ?"
,
username
,
email
)
.
Error
if
err
!=
nil
{
if
errors
.
Is
(
err
,
gorm
.
ErrRecordNotFound
)
{
// not exist, return false, nil
return
false
,
nil
}
// other error, return false, err
return
false
,
err
}
// exist, return true, nil
return
true
,
nil
}
func
GetMaxUserId
()
int
{
...
...
@@ -40,7 +57,7 @@ func GetMaxUserId() int {
}
func
GetAllUsers
(
startIdx
int
,
num
int
)
(
users
[]
*
User
,
err
error
)
{
err
=
DB
.
Order
(
"id desc"
)
.
Limit
(
num
)
.
Offset
(
startIdx
)
.
Omit
(
"password"
)
.
Find
(
&
users
)
.
Error
err
=
DB
.
Unscoped
()
.
Order
(
"id desc"
)
.
Limit
(
num
)
.
Offset
(
startIdx
)
.
Omit
(
"password"
)
.
Find
(
&
users
)
.
Error
return
users
,
err
}
...
...
@@ -80,6 +97,14 @@ func DeleteUserById(id int) (err error) {
return
user
.
Delete
()
}
func
HardDeleteUserById
(
id
int
)
error
{
if
id
==
0
{
return
errors
.
New
(
"id 为空!"
)
}
err
:=
DB
.
Unscoped
()
.
Delete
(
&
User
{},
"id = ?"
,
id
)
.
Error
return
err
}
func
inviteUser
(
inviterId
int
)
(
err
error
)
{
user
,
err
:=
GetUserById
(
inviterId
,
true
)
if
err
!=
nil
{
...
...
web/src/components/UsersTable.js
View file @
b38ba50e
...
...
@@ -72,32 +72,49 @@ const UsersTable = () => {
},
{
title
:
'状态'
,
dataIndex
:
'status'
,
render
:
(
text
,
record
,
index
)
=>
{
return
(
<
div
>
{
renderStatus
(
text
)}
{
re
cord
.
deleted_at
!==
null
?
<
Tag
color
=
'red'
>
已注销
<
/Tag> : re
nderStatus
(
text
)
}
<
/div>
)
;
},
},
{
title
:
''
,
dataIndex
:
'operate'
,
render
:
(
text
,
record
,
index
)
=>
(
<
div
>
<
Popconfirm
title
=
"确定?"
okType
=
{
'warning'
}
onConfirm
=
{()
=>
{
manageUser
(
record
.
username
,
'promote'
,
record
)
}}
>
<
Button
theme
=
'light'
type
=
'warning'
style
=
{{
marginRight
:
1
}}
>
提升
<
/Button
>
<
/Popconfirm
>
<
Popconfirm
title
=
"确定?"
okType
=
{
'warning'
}
onConfirm
=
{()
=>
{
manageUser
(
record
.
username
,
'demote'
,
record
)
}}
>
<
Button
theme
=
'light'
type
=
'secondary'
style
=
{{
marginRight
:
1
}}
>
降级
<
/Button
>
<
/Popconfirm
>
{
record
.
deleted_at
!==
null
?
<><
/>
:
<>
<
Popconfirm
title
=
"确定?"
okType
=
{
'warning'
}
onConfirm
=
{()
=>
{
manageUser
(
record
.
username
,
'promote'
,
record
)
}}
>
<
Button
theme
=
'light'
type
=
'warning'
style
=
{{
marginRight
:
1
}}
>
提升
<
/Button
>
<
/Popconfirm
>
<
Popconfirm
title
=
"确定?"
okType
=
{
'warning'
}
onConfirm
=
{()
=>
{
manageUser
(
record
.
username
,
'demote'
,
record
)
}}
>
<
Button
theme
=
'light'
type
=
'secondary'
style
=
{{
marginRight
:
1
}}
>
降级
<
/Button
>
<
/Popconfirm
>
{
record
.
status
===
1
?
<
Button
theme
=
'light'
type
=
'warning'
style
=
{{
marginRight
:
1
}}
onClick
=
{
async
()
=>
{
manageUser
(
record
.
username
,
'disable'
,
record
)
}}
>
禁用
<
/Button>
:
<
Button
theme
=
'light'
type
=
'secondary'
style
=
{{
marginRight
:
1
}}
onClick
=
{
async
()
=>
{
manageUser
(
record
.
username
,
'enable'
,
record
);
}}
disabled
=
{
record
.
status
===
3
}
>
启用
<
/Button>
}
<
Button
theme
=
'light'
type
=
'tertiary'
style
=
{{
marginRight
:
1
}}
onClick
=
{()
=>
{
setEditingUser
(
record
);
setShowEditUser
(
true
);
}}
>
编辑
<
/Button
>
<
/
>
}
<
Popconfirm
title
=
"确定是否要删除此用户?"
content
=
"此修改将不可逆"
content
=
"
硬删除,
此修改将不可逆"
okType
=
{
'danger'
}
position
=
{
'left'
}
onConfirm
=
{()
=>
{
...
...
@@ -108,17 +125,6 @@ const UsersTable = () => {
>
<
Button
theme
=
'light'
type
=
'danger'
style
=
{{
marginRight
:
1
}}
>
删除
<
/Button
>
<
/Popconfirm
>
{
record
.
status
===
1
?
<
Button
theme
=
'light'
type
=
'warning'
style
=
{{
marginRight
:
1
}}
onClick
=
{
async
()
=>
{
manageUser
(
record
.
username
,
'disable'
,
record
)
}}
>
禁用
<
/Button>
:
<
Button
theme
=
'light'
type
=
'secondary'
style
=
{{
marginRight
:
1
}}
onClick
=
{
async
()
=>
{
manageUser
(
record
.
username
,
'enable'
,
record
);
}}
disabled
=
{
record
.
status
===
3
}
>
启用
<
/Button>
}
<
Button
theme
=
'light'
type
=
'tertiary'
style
=
{{
marginRight
:
1
}}
onClick
=
{()
=>
{
setEditingUser
(
record
);
setShowEditUser
(
true
);
}}
>
编辑
<
/Button
>
<
/div>
)
,
},];
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment