From 5e503d671ed9944f1243b138bc52e07178437280 Mon Sep 17 00:00:00 2001 From: wood Date: Thu, 16 Nov 2023 05:02:34 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E7=82=B9=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controller/token.go | 2 +- controller/user.go | 66 ++++++++++++++++++++++++++++- model/redemption.go | 2 +- web/src/components/ChannelsTable.js | 2 +- web/src/components/Header.js | 19 +++++++-- web/src/components/LogsTable.js | 11 ++++- web/src/components/TokensTable.js | 3 +- web/src/components/UsersTable.js | 4 +- web/src/index.css | 43 +++++++++++++------ web/src/pages/Token/EditToken.js | 7 +-- web/src/pages/User/EditUser.js | 33 ++++++++------- 11 files changed, 150 insertions(+), 42 deletions(-) diff --git a/controller/token.go b/controller/token.go index e44170cc..78fc26e8 100644 --- a/controller/token.go +++ b/controller/token.go @@ -174,7 +174,7 @@ func UpdateToken(c *gin.Context) { if len(token.Name) > 30 { c.JSON(http.StatusOK, gin.H{ "success": false, - "message": "Key名称过长", + "message": "Key名称过长,不能超过30位", }) return } diff --git a/controller/user.go b/controller/user.go index edbfc371..aaf42ae2 100644 --- a/controller/user.go +++ b/controller/user.go @@ -553,6 +553,7 @@ func CreateUser(c *gin.Context) { type ManageRequest struct { Username string `json:"username"` + Action string `json:"action"` NewGroup string `json:"newGroup"` } @@ -591,8 +592,68 @@ func ManageUser(c *gin.Context) { return } - // 更新用户分组 - user.Group = req.NewGroup + switch req.Action { + case "disable": + user.Status = common.UserStatusDisabled + if user.Role == common.RoleRootUser { + c.JSON(http.StatusOK, gin.H{ + "success": false, + "message": "无法禁用超级管理员用户", + }) + return + } + case "enable": + user.Status = common.UserStatusEnabled + case "delete": + if user.Role == common.RoleRootUser { + c.JSON(http.StatusOK, gin.H{ + "success": false, + "message": "无法删除超级管理员用户", + }) + return + } + if err := user.Delete(); err != nil { + c.JSON(http.StatusOK, gin.H{ + "success": false, + "message": err.Error(), + }) + return + } + case "promote": + if myRole != common.RoleRootUser { + c.JSON(http.StatusOK, gin.H{ + "success": false, + "message": "普通管理员用户无法提升其他用户为管理员", + }) + return + } + if user.Role >= common.RoleAdminUser { + c.JSON(http.StatusOK, gin.H{ + "success": false, + "message": "该用户已经是管理员", + }) + return + } + user.Role = common.RoleAdminUser + case "demote": + if user.Role == common.RoleRootUser { + c.JSON(http.StatusOK, gin.H{ + "success": false, + "message": "无法降级超级管理员用户", + }) + return + } + if user.Role == common.RoleCommonUser { + c.JSON(http.StatusOK, gin.H{ + "success": false, + "message": "该用户已经是普通用户", + }) + return + } + user.Role = common.RoleCommonUser + case "changeGroup": + user.Group = req.NewGroup + } if err := user.Update(false); err != nil { c.JSON(http.StatusOK, gin.H{ @@ -617,6 +678,7 @@ func ManageUser(c *gin.Context) { } + func EmailBind(c *gin.Context) { email := c.Query("email") code := c.Query("code") diff --git a/model/redemption.go b/model/redemption.go index c2201b09..ba75f08d 100644 --- a/model/redemption.go +++ b/model/redemption.go @@ -86,7 +86,7 @@ func Redeem(key string, userId int) (quota int, upgradedToVIP bool, err error) { } // 检查是否需要升级为 VIP - if user.Group != "vip" && user.Quota >= 5*500000 { + if user.Group != "vip" && user.Group != "svip" && user.Quota >= 5*500000 { // 升级用户到 VIP err = DB.Model(&User{}).Where("id = ?", userId).Update("group", "vip").Error if err != nil { diff --git a/web/src/components/ChannelsTable.js b/web/src/components/ChannelsTable.js index dc146345..114fbef9 100644 --- a/web/src/components/ChannelsTable.js +++ b/web/src/components/ChannelsTable.js @@ -466,7 +466,7 @@ const ChannelsTable = () => { manageChannel(channel.id, 'delete', idx); }} > - 删除渠道 {channel.name} + 确认删除 {channel.name} diff --git a/web/src/components/Header.js b/web/src/components/Header.js index d2607583..dd410626 100644 --- a/web/src/components/Header.js +++ b/web/src/components/Header.js @@ -6,6 +6,8 @@ import { Button, Container, Dropdown, Icon, Menu, Segment } from 'semantic-ui-re import { API, getLogo, getSystemName, isAdmin, isMobile, showSuccess } from '../helpers'; import '../index.css'; + + // Header Buttons let headerButtons = [ { @@ -83,6 +85,8 @@ const Header = () => { const [showSidebar, setShowSidebar] = useState(false); const systemName = getSystemName(); const logo = getLogo(); + const [activeItem, setActiveItem] = useState(null); + async function logout() { setShowSidebar(false); @@ -100,6 +104,7 @@ const Header = () => { const renderButtons = (isMobile) => { return headerButtons.map((button) => { if (button.admin && !isAdmin()) return <>; + const isActive = activeItem === button.name; if (isMobile) { return ( { ); } return ( - - - {button.name} + setActiveItem(button.name)} + > +
+ {button.icon && } + {button.name} +
); }); }; + if (isMobile()) { return ( <> diff --git a/web/src/components/LogsTable.js b/web/src/components/LogsTable.js index 9ce8ca09..1fdeb463 100644 --- a/web/src/components/LogsTable.js +++ b/web/src/components/LogsTable.js @@ -158,7 +158,12 @@ const LogsTable = () => { const getLogStat = async () => { let localStartTimestamp = Date.parse(start_timestamp) / 1000; let localEndTimestamp = Date.parse(end_timestamp) / 1000; - let res = await API.get(`/api/log/stat?type=${logType}&username=${username}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}&channel=${channel}`); + let url = `/api/log/stat?type=${logType}&username=${username}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}&channel=${channel}`; + let res = await API.get(url); + if (!res || !res.data) { + showError('No response or response data'); + return; + } const { success, message, data } = res.data; if (success) { setStat(data); @@ -185,6 +190,10 @@ const LogsTable = () => { url = `/api/log/self/?p=${startIdx}&type=${logType}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`; } const res = await API.get(url); + if (!res || !res.data) { + showError('No response or response data'); + return; + } const { success, message, data } = res.data; if (success) { if (startIdx === 0) { diff --git a/web/src/components/TokensTable.js b/web/src/components/TokensTable.js index 0ec94484..3df7f967 100644 --- a/web/src/components/TokensTable.js +++ b/web/src/components/TokensTable.js @@ -365,7 +365,8 @@ const TokensTable = () => { manageToken(token.id, 'delete', idx); }} style={{ backgroundColor: 'var(--czl-error-color)', borderColor: 'var(--czl-error-color)' }} - /> + > + 确认删除key: {token.name}