mirror of
https://github.com/XShengTech/MEGREZ.git
synced 2026-05-03 13:02:38 +00:00
[Feat] ✨ Reset Email API & Pages #15
This commit is contained in:
@@ -38,6 +38,9 @@ export default {
|
|||||||
UserResetPassword(data) {
|
UserResetPassword(data) {
|
||||||
return ajax('user/password', 'post', { data })
|
return ajax('user/password', 'post', { data })
|
||||||
},
|
},
|
||||||
|
UserResetEmail(data) {
|
||||||
|
return ajax('user/email', 'post', { data })
|
||||||
|
},
|
||||||
UserVerifyRequest() {
|
UserVerifyRequest() {
|
||||||
return ajax(`user/verify`, 'post', {})
|
return ajax(`user/verify`, 'post', {})
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -22,16 +22,17 @@
|
|||||||
<div class="font-semibold text-xl">修改邮箱</div>
|
<div class="font-semibold text-xl">修改邮箱</div>
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<label for="email">邮箱</label>
|
<label for="email">邮箱</label>
|
||||||
<InputText v-if="!emailModifyStatus" v-model="userProfile.email" type="text" disabled />
|
<InputText v-if="!resetEmailModifyStatus" v-model="userProfile.email" type="text" disabled />
|
||||||
<InputText v-else v-model="emailModifyValue" type="text" />
|
<InputText v-else v-model="resetEmailData.email" type="text" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!emailModifyStatus" class="mt-2">
|
<div v-if="!resetEmailModifyStatus" class="mt-2">
|
||||||
<Button label="修改" style="width: 5.6rem; float: right;" @click="emailModifyStatus = true" />
|
<Button label="修改" style="width: 5.6rem; float: right;" @click="resetEmailModifyStatus = true" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<Button label="保存" style="width: 5.6rem; float: right;" />
|
<Button v-if="!resetEmailRequesting" label="保存" style="width: 5.6rem; float: right;" @click="resetEmail" />
|
||||||
|
<Button v-else label="保存中" icon="pi pi-spin pi-spinner" disabled style="width: 7.2rem; float: right;" />
|
||||||
<Button class="mr-2" label="取消" severity="secondary" style="width: 5.6rem; float: right;"
|
<Button class="mr-2" label="取消" severity="secondary" style="width: 5.6rem; float: right;"
|
||||||
@click="emailModifyStatus = false" />
|
@click="resetEmailModifyStatus = false" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -74,8 +75,11 @@ const userProfile = ref({})
|
|||||||
|
|
||||||
const verifyRequesting = ref(false)
|
const verifyRequesting = ref(false)
|
||||||
|
|
||||||
const emailModifyStatus = ref(false)
|
const resetEmailModifyStatus = ref(false)
|
||||||
const emailModifyValue = ref('')
|
const resetEmailRequesting = ref(false)
|
||||||
|
const resetEmailData = ref({
|
||||||
|
email: ''
|
||||||
|
})
|
||||||
|
|
||||||
const resetPasswordRequesting = ref(false)
|
const resetPasswordRequesting = ref(false)
|
||||||
const resetPasswordData = ref({
|
const resetPasswordData = ref({
|
||||||
@@ -87,7 +91,7 @@ const resetPasswordData = ref({
|
|||||||
const getProfile = () => {
|
const getProfile = () => {
|
||||||
api.GetUserProfile().then((res) => {
|
api.GetUserProfile().then((res) => {
|
||||||
userProfile.value = res.data.data.result
|
userProfile.value = res.data.data.result
|
||||||
emailModifyValue.value = userProfile.value.email
|
resetEmailData.value.email = userProfile.value.email
|
||||||
console.log(userProfile.value)
|
console.log(userProfile.value)
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
toast.add({ severity: 'error', summary: '获取用户信息失败', detail: err.response.data.msg, life: 3000 })
|
toast.add({ severity: 'error', summary: '获取用户信息失败', detail: err.response.data.msg, life: 3000 })
|
||||||
@@ -144,6 +148,27 @@ const resetPassword = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const resetEmail = () => {
|
||||||
|
resetEmailRequesting.value = true
|
||||||
|
|
||||||
|
if (resetEmailData.value.email == '') {
|
||||||
|
toast.add({ severity: 'error', summary: '邮箱不能为空', detail: '请重新输入', life: 3000 })
|
||||||
|
resetEmailRequesting.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
api.UserResetEmail(resetEmailData.value).then((res) => {
|
||||||
|
toast.add({ severity: 'success', summary: '修改成功', detail: '请重新登录', life: 3000 })
|
||||||
|
resetEmailRequesting.value = false
|
||||||
|
resetEmailModifyStatus.value = false
|
||||||
|
getProfile()
|
||||||
|
}).catch((err) => {
|
||||||
|
toast.add({ severity: 'error', summary: '修改失败', detail: err.response.data.msg, life: 3000 })
|
||||||
|
resetEmailRequesting.value = false
|
||||||
|
console.error(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getProfile()
|
getProfile()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func EmailFormat(email string) bool {
|
||||||
|
pattern := `^\w+(-+.\w+)*@\w+(-.\w+)*.\w+(-.\w+)*$`
|
||||||
|
match, err := regexp.MatchString(pattern, email)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return match
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package users
|
package users
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"megrez/libs/utils"
|
||||||
"megrez/models"
|
"megrez/models"
|
||||||
"megrez/routers/api/v1/middleware"
|
"megrez/routers/api/v1/middleware"
|
||||||
"megrez/services/database"
|
"megrez/services/database"
|
||||||
@@ -9,6 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type modifyReqStruct struct {
|
type modifyReqStruct struct {
|
||||||
|
Email *string `json:"email"`
|
||||||
Password *string `json:"password"`
|
Password *string `json:"password"`
|
||||||
Role *int `json:"role"`
|
Role *int `json:"role"`
|
||||||
Verify *bool `json:"verify"`
|
Verify *bool `json:"verify"`
|
||||||
@@ -46,6 +48,12 @@ func modifyHandler(ctx iris.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if req.Email != nil {
|
||||||
|
if *req.Email != "" && utils.EmailFormat(*req.Email) {
|
||||||
|
user.Email = *req.Email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if req.Password != nil {
|
if req.Password != nil {
|
||||||
if *req.Password != "" {
|
if *req.Password != "" {
|
||||||
user.Password = user.PasswordHash(*req.Password)
|
user.Password = user.PasswordHash(*req.Password)
|
||||||
|
|||||||
@@ -14,6 +14,11 @@ const (
|
|||||||
CodeUserNotExist ResCode = 1002
|
CodeUserNotExist ResCode = 1002
|
||||||
CodeRegisterRequestError ResCode = 1003
|
CodeRegisterRequestError ResCode = 1003
|
||||||
CodeRegisterError ResCode = 1004
|
CodeRegisterError ResCode = 1004
|
||||||
|
CodeEmailFormatError ResCode = 1005
|
||||||
|
CodeUserAlreadyVerified ResCode = 1006
|
||||||
|
CodeUserVerifyInvalid ResCode = 1007
|
||||||
|
CodePasswordNotMatch ResCode = 1008
|
||||||
|
|
||||||
CodeInternalCreateError ResCode = 1010
|
CodeInternalCreateError ResCode = 1010
|
||||||
CodeInstanceDeleteError ResCode = 1011
|
CodeInstanceDeleteError ResCode = 1011
|
||||||
CodeInstanceQueryError ResCode = 1012
|
CodeInstanceQueryError ResCode = 1012
|
||||||
@@ -42,10 +47,6 @@ const (
|
|||||||
CodeAdminUserDeleteError ResCode = 2013
|
CodeAdminUserDeleteError ResCode = 2013
|
||||||
CodeAdminUserInstanceNoEmpty ResCode = 2014
|
CodeAdminUserInstanceNoEmpty ResCode = 2014
|
||||||
CodeAdminUserModifyError ResCode = 2015
|
CodeAdminUserModifyError ResCode = 2015
|
||||||
|
|
||||||
CodeUserAlreadyVerified ResCode = 3001
|
|
||||||
CodeUserVerifyInvalid ResCode = 3002
|
|
||||||
CodePasswordNotMatch ResCode = 3003
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var codeMsgMap = map[ResCode]string{
|
var codeMsgMap = map[ResCode]string{
|
||||||
@@ -60,6 +61,11 @@ var codeMsgMap = map[ResCode]string{
|
|||||||
CodeUserNotExist: "user not exist",
|
CodeUserNotExist: "user not exist",
|
||||||
CodeRegisterRequestError: "register request error",
|
CodeRegisterRequestError: "register request error",
|
||||||
CodeRegisterError: "username or email exist",
|
CodeRegisterError: "username or email exist",
|
||||||
|
CodeEmailFormatError: "email format error",
|
||||||
|
CodeUserAlreadyVerified: "user already verified",
|
||||||
|
CodeUserVerifyInvalid: "email verify error",
|
||||||
|
CodePasswordNotMatch: "password not match",
|
||||||
|
|
||||||
CodeInternalCreateError: "create error",
|
CodeInternalCreateError: "create error",
|
||||||
CodeInstanceDeleteError: "delete instance error",
|
CodeInstanceDeleteError: "delete instance error",
|
||||||
CodeInstanceStatusError: "instance status error",
|
CodeInstanceStatusError: "instance status error",
|
||||||
@@ -88,8 +94,4 @@ var codeMsgMap = map[ResCode]string{
|
|||||||
CodeAdminUserDeleteError: "delete user error",
|
CodeAdminUserDeleteError: "delete user error",
|
||||||
CodeAdminUserModifyError: "modify user error",
|
CodeAdminUserModifyError: "modify user error",
|
||||||
CodeAdminUserInstanceNoEmpty: "user instances not empty",
|
CodeAdminUserInstanceNoEmpty: "user instances not empty",
|
||||||
|
|
||||||
CodeUserAlreadyVerified: "user already verified",
|
|
||||||
CodeUserVerifyInvalid: "email verify error",
|
|
||||||
CodePasswordNotMatch: "password not match",
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package user
|
package user
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"megrez/libs/utils"
|
||||||
"megrez/models"
|
"megrez/models"
|
||||||
"megrez/routers/api/v1/middleware"
|
"megrez/routers/api/v1/middleware"
|
||||||
"megrez/services/config"
|
"megrez/services/config"
|
||||||
@@ -29,6 +30,11 @@ func registerHandler(ctx iris.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !utils.EmailFormat(userReq.Email) {
|
||||||
|
middleware.Error(ctx, middleware.CodeEmailFormatError, iris.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
user := models.Users{
|
user := models.Users{
|
||||||
Username: userReq.Username,
|
Username: userReq.Username,
|
||||||
Email: userReq.Email,
|
Email: userReq.Email,
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"megrez/libs/utils"
|
||||||
|
"megrez/models"
|
||||||
|
"megrez/routers/api/v1/middleware"
|
||||||
|
"megrez/services/database"
|
||||||
|
|
||||||
|
"github.com/kataras/iris/v12"
|
||||||
|
)
|
||||||
|
|
||||||
|
type resetEmailStruct struct {
|
||||||
|
Email string `json:"email"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func resetEmailHandler(ctx iris.Context) {
|
||||||
|
l.SetFunction("resetEmailHandler")
|
||||||
|
|
||||||
|
userId, err := ctx.Values().GetInt("userId")
|
||||||
|
if err != nil {
|
||||||
|
middleware.Error(ctx, middleware.CodeBadRequest, iris.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var req resetEmailStruct
|
||||||
|
if err := ctx.ReadJSON(&req); err != nil {
|
||||||
|
middleware.Error(ctx, middleware.CodeBadRequest, iris.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.Email == "" {
|
||||||
|
middleware.Error(ctx, middleware.CodeBadRequest, iris.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !utils.EmailFormat(req.Email) {
|
||||||
|
middleware.Error(ctx, middleware.CodeEmailFormatError, iris.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
user := models.Users{
|
||||||
|
ID: uint(userId),
|
||||||
|
}
|
||||||
|
result := database.DB.First(&user)
|
||||||
|
if result.Error != nil {
|
||||||
|
l.Error("get user error: %v", result.Error)
|
||||||
|
middleware.Error(ctx, middleware.CodeUserNotExist, iris.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
result = database.DB.Model(&user).Update("email", req.Email).Update("verify", false)
|
||||||
|
if result.Error != nil {
|
||||||
|
l.Error("save user error: %v", result.Error)
|
||||||
|
middleware.Error(ctx, middleware.CodeInternalPatchError, iris.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
middleware.Success(ctx)
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@ func InitUser(party router.Party) {
|
|||||||
party.Post("/register", registerHandler)
|
party.Post("/register", registerHandler)
|
||||||
party.Get("/profile", middleware.AuthCheck, profileHandler)
|
party.Get("/profile", middleware.AuthCheck, profileHandler)
|
||||||
party.Post("/password", middleware.AuthCheck, resetPasswordHandler)
|
party.Post("/password", middleware.AuthCheck, resetPasswordHandler)
|
||||||
|
party.Post("/email", middleware.AuthCheck, resetEmailHandler)
|
||||||
party.Get("/verify/{code:string}", verifyHandler)
|
party.Get("/verify/{code:string}", verifyHandler)
|
||||||
party.Post("/verify", middleware.AuthCheck, verifySendHandler)
|
party.Post("/verify", middleware.AuthCheck, verifySendHandler)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user