diff --git a/frontend/src/api.js b/frontend/src/api.js
index 131d44e..4689f42 100644
--- a/frontend/src/api.js
+++ b/frontend/src/api.js
@@ -38,6 +38,9 @@ export default {
UserResetPassword(data) {
return ajax('user/password', 'post', { data })
},
+ UserResetEmail(data) {
+ return ajax('user/email', 'post', { data })
+ },
UserVerifyRequest() {
return ajax(`user/verify`, 'post', {})
},
diff --git a/frontend/src/views/users/Settings.vue b/frontend/src/views/users/Settings.vue
index df10d5a..af14269 100644
--- a/frontend/src/views/users/Settings.vue
+++ b/frontend/src/views/users/Settings.vue
@@ -22,16 +22,17 @@
修改邮箱
-
-
+
+
-
-
+
+
-
+
+
+ @click="resetEmailModifyStatus = false" />
@@ -74,8 +75,11 @@ const userProfile = ref({})
const verifyRequesting = ref(false)
-const emailModifyStatus = ref(false)
-const emailModifyValue = ref('')
+const resetEmailModifyStatus = ref(false)
+const resetEmailRequesting = ref(false)
+const resetEmailData = ref({
+ email: ''
+})
const resetPasswordRequesting = ref(false)
const resetPasswordData = ref({
@@ -87,7 +91,7 @@ const resetPasswordData = ref({
const getProfile = () => {
api.GetUserProfile().then((res) => {
userProfile.value = res.data.data.result
- emailModifyValue.value = userProfile.value.email
+ resetEmailData.value.email = userProfile.value.email
console.log(userProfile.value)
}).catch((err) => {
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(() => {
getProfile()
})
diff --git a/libs/utils/email.go b/libs/utils/email.go
new file mode 100644
index 0000000..4bdc9a6
--- /dev/null
+++ b/libs/utils/email.go
@@ -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
+}
diff --git a/routers/api/v1/admin/users/modify.go b/routers/api/v1/admin/users/modify.go
index 8e4c955..4935e3b 100644
--- a/routers/api/v1/admin/users/modify.go
+++ b/routers/api/v1/admin/users/modify.go
@@ -1,6 +1,7 @@
package users
import (
+ "megrez/libs/utils"
"megrez/models"
"megrez/routers/api/v1/middleware"
"megrez/services/database"
@@ -9,6 +10,7 @@ import (
)
type modifyReqStruct struct {
+ Email *string `json:"email"`
Password *string `json:"password"`
Role *int `json:"role"`
Verify *bool `json:"verify"`
@@ -46,6 +48,12 @@ func modifyHandler(ctx iris.Context) {
return
}
+ if req.Email != nil {
+ if *req.Email != "" && utils.EmailFormat(*req.Email) {
+ user.Email = *req.Email
+ }
+ }
+
if req.Password != nil {
if *req.Password != "" {
user.Password = user.PasswordHash(*req.Password)
diff --git a/routers/api/v1/middleware/code.go b/routers/api/v1/middleware/code.go
index df74601..7f54802 100644
--- a/routers/api/v1/middleware/code.go
+++ b/routers/api/v1/middleware/code.go
@@ -14,6 +14,11 @@ const (
CodeUserNotExist ResCode = 1002
CodeRegisterRequestError ResCode = 1003
CodeRegisterError ResCode = 1004
+ CodeEmailFormatError ResCode = 1005
+ CodeUserAlreadyVerified ResCode = 1006
+ CodeUserVerifyInvalid ResCode = 1007
+ CodePasswordNotMatch ResCode = 1008
+
CodeInternalCreateError ResCode = 1010
CodeInstanceDeleteError ResCode = 1011
CodeInstanceQueryError ResCode = 1012
@@ -42,10 +47,6 @@ const (
CodeAdminUserDeleteError ResCode = 2013
CodeAdminUserInstanceNoEmpty ResCode = 2014
CodeAdminUserModifyError ResCode = 2015
-
- CodeUserAlreadyVerified ResCode = 3001
- CodeUserVerifyInvalid ResCode = 3002
- CodePasswordNotMatch ResCode = 3003
)
var codeMsgMap = map[ResCode]string{
@@ -60,6 +61,11 @@ var codeMsgMap = map[ResCode]string{
CodeUserNotExist: "user not exist",
CodeRegisterRequestError: "register request error",
CodeRegisterError: "username or email exist",
+ CodeEmailFormatError: "email format error",
+ CodeUserAlreadyVerified: "user already verified",
+ CodeUserVerifyInvalid: "email verify error",
+ CodePasswordNotMatch: "password not match",
+
CodeInternalCreateError: "create error",
CodeInstanceDeleteError: "delete instance error",
CodeInstanceStatusError: "instance status error",
@@ -88,8 +94,4 @@ var codeMsgMap = map[ResCode]string{
CodeAdminUserDeleteError: "delete user error",
CodeAdminUserModifyError: "modify user error",
CodeAdminUserInstanceNoEmpty: "user instances not empty",
-
- CodeUserAlreadyVerified: "user already verified",
- CodeUserVerifyInvalid: "email verify error",
- CodePasswordNotMatch: "password not match",
}
diff --git a/routers/api/v1/user/register.go b/routers/api/v1/user/register.go
index 6ca6334..503701d 100644
--- a/routers/api/v1/user/register.go
+++ b/routers/api/v1/user/register.go
@@ -1,6 +1,7 @@
package user
import (
+ "megrez/libs/utils"
"megrez/models"
"megrez/routers/api/v1/middleware"
"megrez/services/config"
@@ -29,6 +30,11 @@ func registerHandler(ctx iris.Context) {
return
}
+ if !utils.EmailFormat(userReq.Email) {
+ middleware.Error(ctx, middleware.CodeEmailFormatError, iris.StatusBadRequest)
+ return
+ }
+
user := models.Users{
Username: userReq.Username,
Email: userReq.Email,
diff --git a/routers/api/v1/user/resetEmail.go b/routers/api/v1/user/resetEmail.go
new file mode 100644
index 0000000..f2f3a6a
--- /dev/null
+++ b/routers/api/v1/user/resetEmail.go
@@ -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)
+}
diff --git a/routers/api/v1/user/routers.go b/routers/api/v1/user/routers.go
index 3e33087..0c01102 100644
--- a/routers/api/v1/user/routers.go
+++ b/routers/api/v1/user/routers.go
@@ -25,6 +25,7 @@ func InitUser(party router.Party) {
party.Post("/register", registerHandler)
party.Get("/profile", middleware.AuthCheck, profileHandler)
party.Post("/password", middleware.AuthCheck, resetPasswordHandler)
+ party.Post("/email", middleware.AuthCheck, resetEmailHandler)
party.Get("/verify/{code:string}", verifyHandler)
party.Post("/verify", middleware.AuthCheck, verifySendHandler)