diff --git a/controller/user.go b/controller/user.go index 3060edd4..935ac327 100644 --- a/controller/user.go +++ b/controller/user.go @@ -3,12 +3,13 @@ package controller import ( "encoding/json" "fmt" - "github.com/gin-contrib/sessions" - "github.com/gin-gonic/gin" "net/http" "one-api/common" "one-api/model" "strconv" + + "github.com/gin-contrib/sessions" + "github.com/gin-gonic/gin" ) type LoginRequest struct { @@ -477,6 +478,16 @@ func DeleteUser(c *gin.Context) { func DeleteSelf(c *gin.Context) { id := c.GetInt("id") + user, _ := model.GetUserById(id, false) + + if user.Role == common.RoleRootUser { + c.JSON(http.StatusOK, gin.H{ + "success": false, + "message": "无权删除超级管理员", + }) + return + } + err := model.DeleteUserById(id) if err != nil { c.JSON(http.StatusOK, gin.H{ diff --git a/router/api-router.go b/router/api-router.go index 79ed5e4b..9036341b 100644 --- a/router/api-router.go +++ b/router/api-router.go @@ -37,7 +37,7 @@ func SetApiRouter(router *gin.Engine) { { selfRoute.GET("/self", controller.GetSelf) selfRoute.PUT("/self", controller.UpdateSelf) - selfRoute.DELETE("/self", controller.DeleteSelf) + selfRoute.DELETE("/self", middleware.TurnstileCheck(), controller.DeleteSelf) selfRoute.GET("/token", controller.GenerateAccessToken) selfRoute.GET("/aff", controller.GetAffCode) selfRoute.POST("/topup", controller.TopUp) diff --git a/web/src/components/PersonalSetting.js b/web/src/components/PersonalSetting.js index 0bc01ed3..157a87a9 100644 --- a/web/src/components/PersonalSetting.js +++ b/web/src/components/PersonalSetting.js @@ -1,18 +1,24 @@ -import React, { useEffect, useState } from 'react'; -import { Button, Divider, Form, Header, Image, Message, Modal } from 'semantic-ui-react'; -import { Link } from 'react-router-dom'; +import React, { useEffect, useState, useContext } from 'react'; +import { Button, Divider, Form, Header, Image, Message, Modal, Label } from 'semantic-ui-react'; +import { Link, useNavigate } from 'react-router-dom'; import { API, copy, showError, showInfo, showNotice, showSuccess } from '../helpers'; import Turnstile from 'react-turnstile'; +import { UserContext } from '../context/User'; const PersonalSetting = () => { + const [userDispatch] = useContext(UserContext); + let navigate = useNavigate(); + const [inputs, setInputs] = useState({ wechat_verification_code: '', email_verification_code: '', email: '', + self_account_deletion_confirmation: '', }); const [status, setStatus] = useState({}); const [showWeChatBindModal, setShowWeChatBindModal] = useState(false); const [showEmailBindModal, setShowEmailBindModal] = useState(false); + const [showAccountDeleteModal, setShowAccountDeleteModal] = useState(false); const [turnstileEnabled, setTurnstileEnabled] = useState(false); const [turnstileSiteKey, setTurnstileSiteKey] = useState(''); const [turnstileToken, setTurnstileToken] = useState(''); @@ -57,6 +63,26 @@ const PersonalSetting = () => { } }; + const deleteAccount = async () => { + if (inputs.self_account_deletion_confirmation !== 'CONFIRM') { + showError('请确认您要删除账户!'); + return; + } + + const res = await API.delete('/api/user/self'); + const { success, message } = res.data; + + if (success) { + showSuccess('账户已删除!'); + await API.get('/api/user/logout'); + userDispatch({ type: 'logout' }); + localStorage.removeItem('user'); + navigate('/login'); + } else { + showError(message); + } + } + const bindWeChat = async () => { if (inputs.wechat_verification_code === '') return; const res = await API.get( @@ -129,6 +155,9 @@ const PersonalSetting = () => { +
账号绑定
{ @@ -241,6 +270,48 @@ const PersonalSetting = () => { + setShowAccountDeleteModal(false)} + onOpen={() => setShowAccountDeleteModal(true)} + open={showAccountDeleteModal} + size={'tiny'} + style={{ maxWidth: '450px' }} + > + 您是否确认删除自己的帐户? + + +
+ + {turnstileEnabled ? ( + { + setTurnstileToken(token); + }} + /> + ) : ( + <> + )} + + +
+
+
); };