改点样式
This commit is contained in:
parent
05ee4d5977
commit
5e503d671e
@ -174,7 +174,7 @@ func UpdateToken(c *gin.Context) {
|
|||||||
if len(token.Name) > 30 {
|
if len(token.Name) > 30 {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"success": false,
|
"success": false,
|
||||||
"message": "Key名称过长",
|
"message": "Key名称过长,不能超过30位",
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -553,6 +553,7 @@ func CreateUser(c *gin.Context) {
|
|||||||
|
|
||||||
type ManageRequest struct {
|
type ManageRequest struct {
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
|
Action string `json:"action"`
|
||||||
NewGroup string `json:"newGroup"`
|
NewGroup string `json:"newGroup"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -591,8 +592,68 @@ func ManageUser(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新用户分组
|
switch req.Action {
|
||||||
user.Group = req.NewGroup
|
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 {
|
if err := user.Update(false); err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
@ -617,6 +678,7 @@ func ManageUser(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func EmailBind(c *gin.Context) {
|
func EmailBind(c *gin.Context) {
|
||||||
email := c.Query("email")
|
email := c.Query("email")
|
||||||
code := c.Query("code")
|
code := c.Query("code")
|
||||||
|
@ -86,7 +86,7 @@ func Redeem(key string, userId int) (quota int, upgradedToVIP bool, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否需要升级为 VIP
|
// 检查是否需要升级为 VIP
|
||||||
if user.Group != "vip" && user.Quota >= 5*500000 {
|
if user.Group != "vip" && user.Group != "svip" && user.Quota >= 5*500000 {
|
||||||
// 升级用户到 VIP
|
// 升级用户到 VIP
|
||||||
err = DB.Model(&User{}).Where("id = ?", userId).Update("group", "vip").Error
|
err = DB.Model(&User{}).Where("id = ?", userId).Update("group", "vip").Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -466,7 +466,7 @@ const ChannelsTable = () => {
|
|||||||
manageChannel(channel.id, 'delete', idx);
|
manageChannel(channel.id, 'delete', idx);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
删除渠道 {channel.name}
|
确认删除 {channel.name}
|
||||||
</Button>
|
</Button>
|
||||||
</Popup>
|
</Popup>
|
||||||
|
|
||||||
|
@ -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 { API, getLogo, getSystemName, isAdmin, isMobile, showSuccess } from '../helpers';
|
||||||
import '../index.css';
|
import '../index.css';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Header Buttons
|
// Header Buttons
|
||||||
let headerButtons = [
|
let headerButtons = [
|
||||||
{
|
{
|
||||||
@ -83,6 +85,8 @@ const Header = () => {
|
|||||||
const [showSidebar, setShowSidebar] = useState(false);
|
const [showSidebar, setShowSidebar] = useState(false);
|
||||||
const systemName = getSystemName();
|
const systemName = getSystemName();
|
||||||
const logo = getLogo();
|
const logo = getLogo();
|
||||||
|
const [activeItem, setActiveItem] = useState(null);
|
||||||
|
|
||||||
|
|
||||||
async function logout() {
|
async function logout() {
|
||||||
setShowSidebar(false);
|
setShowSidebar(false);
|
||||||
@ -100,6 +104,7 @@ const Header = () => {
|
|||||||
const renderButtons = (isMobile) => {
|
const renderButtons = (isMobile) => {
|
||||||
return headerButtons.map((button) => {
|
return headerButtons.map((button) => {
|
||||||
if (button.admin && !isAdmin()) return <></>;
|
if (button.admin && !isAdmin()) return <></>;
|
||||||
|
const isActive = activeItem === button.name;
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
return (
|
return (
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
@ -113,14 +118,22 @@ const Header = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Menu.Item key={button.name} as={Link} to={button.to}>
|
<Menu.Item
|
||||||
<Icon name={button.icon} />
|
key={button.name}
|
||||||
{button.name}
|
as={Link}
|
||||||
|
to={button.to}
|
||||||
|
onClick={() => setActiveItem(button.name)}
|
||||||
|
>
|
||||||
|
<div className={isActive ? 'active-menu-item' : ''}>
|
||||||
|
{button.icon && <Icon name={button.icon} />}
|
||||||
|
{button.name}
|
||||||
|
</div>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
if (isMobile()) {
|
if (isMobile()) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -158,7 +158,12 @@ const LogsTable = () => {
|
|||||||
const getLogStat = async () => {
|
const getLogStat = async () => {
|
||||||
let localStartTimestamp = Date.parse(start_timestamp) / 1000;
|
let localStartTimestamp = Date.parse(start_timestamp) / 1000;
|
||||||
let localEndTimestamp = Date.parse(end_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;
|
const { success, message, data } = res.data;
|
||||||
if (success) {
|
if (success) {
|
||||||
setStat(data);
|
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}`;
|
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);
|
const res = await API.get(url);
|
||||||
|
if (!res || !res.data) {
|
||||||
|
showError('No response or response data');
|
||||||
|
return;
|
||||||
|
}
|
||||||
const { success, message, data } = res.data;
|
const { success, message, data } = res.data;
|
||||||
if (success) {
|
if (success) {
|
||||||
if (startIdx === 0) {
|
if (startIdx === 0) {
|
||||||
|
@ -365,7 +365,8 @@ const TokensTable = () => {
|
|||||||
manageToken(token.id, 'delete', idx);
|
manageToken(token.id, 'delete', idx);
|
||||||
}}
|
}}
|
||||||
style={{ backgroundColor: 'var(--czl-error-color)', borderColor: 'var(--czl-error-color)' }}
|
style={{ backgroundColor: 'var(--czl-error-color)', borderColor: 'var(--czl-error-color)' }}
|
||||||
/>
|
>
|
||||||
|
确认删除key: {token.name}</Button>
|
||||||
</Popup>
|
</Popup>
|
||||||
<Button
|
<Button
|
||||||
size={'small'}
|
size={'small'}
|
||||||
|
@ -319,7 +319,9 @@ const UsersTable = () => {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
manageUser(user.username, 'delete', idx);
|
manageUser(user.username, 'delete', idx);
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
|
确认删除{user.username}
|
||||||
|
</Button>
|
||||||
</Popup>
|
</Popup>
|
||||||
<Button
|
<Button
|
||||||
size={'small'}
|
size={'small'}
|
||||||
|
@ -188,7 +188,7 @@ body::-webkit-scrollbar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
font-family: "CZL",source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
|
font-family: "CZL", source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-content {
|
.main-content {
|
||||||
@ -199,24 +199,43 @@ code {
|
|||||||
font-size: 1em !important;
|
font-size: 1em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-footer {
|
/* .custom-footer {
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
}
|
} */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@media only screen and (max-width: 600px) {
|
@media only screen and (max-width: 600px) {
|
||||||
.hide-on-mobile {
|
.hide-on-mobile {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@media only screen and (min-width: 1600px){
|
|
||||||
.main-content {
|
@media only screen and (min-width: 1200px) {
|
||||||
width: 1300px !important;
|
.main-content {
|
||||||
}
|
width: 1300px !important;
|
||||||
.ui.menu .ui.container {
|
}
|
||||||
width: 1608px !important; /* 或者你想要设置的宽度 */
|
|
||||||
/* padding: 0 !important; */
|
.ui.menu .ui.container {
|
||||||
}
|
height: 80px;
|
||||||
|
font-size: 1em;
|
||||||
|
width: 90% !important;
|
||||||
|
/* 或者你想要设置的宽度 */
|
||||||
|
/* padding: 0 !important; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui.menu .item>img:not(.ui) {
|
||||||
|
width: 4.5rem !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.active-menu-item {
|
||||||
|
background-color: var(--czl-grayD) !important;
|
||||||
|
color: white !important;
|
||||||
|
border-radius: 16px !important;
|
||||||
|
padding: 10px 16px !important;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
@ -10,7 +10,7 @@ const EditToken = () => {
|
|||||||
const isEdit = tokenId !== undefined;
|
const isEdit = tokenId !== undefined;
|
||||||
const [loading, setLoading] = useState(isEdit);
|
const [loading, setLoading] = useState(isEdit);
|
||||||
const originInputs = {
|
const originInputs = {
|
||||||
name: '',
|
name: '默认key',
|
||||||
remain_quota: isEdit ? 0 : 100,
|
remain_quota: isEdit ? 0 : 100,
|
||||||
expired_time: -1,
|
expired_time: -1,
|
||||||
unlimited_quota: false
|
unlimited_quota: false
|
||||||
@ -86,11 +86,12 @@ const EditToken = () => {
|
|||||||
const { success, message } = res.data;
|
const { success, message } = res.data;
|
||||||
if (success) {
|
if (success) {
|
||||||
if (isEdit) {
|
if (isEdit) {
|
||||||
showSuccess('Key更新成功!');
|
showSuccess('Key更新成功');
|
||||||
} else {
|
} else {
|
||||||
showSuccess('Key创建成功,请在列表页面点击复制获取Key!');
|
showSuccess('Key创建成功');
|
||||||
setInputs(originInputs);
|
setInputs(originInputs);
|
||||||
}
|
}
|
||||||
|
navigate("/token"); // 在这里添加导航到 "/token"
|
||||||
} else {
|
} else {
|
||||||
showError(message);
|
showError(message);
|
||||||
}
|
}
|
||||||
|
@ -91,6 +91,16 @@ const EditUser = () => {
|
|||||||
<Segment loading={loading}>
|
<Segment loading={loading}>
|
||||||
<Header as='h3'>更新用户信息</Header>
|
<Header as='h3'>更新用户信息</Header>
|
||||||
<Form autoComplete='new-password'>
|
<Form autoComplete='new-password'>
|
||||||
|
<Form.Field>
|
||||||
|
<Form.Input
|
||||||
|
label='昵称'
|
||||||
|
name='display_name'
|
||||||
|
placeholder={'请输入新的昵称'}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
value={display_name}
|
||||||
|
autoComplete='new-password'
|
||||||
|
/>
|
||||||
|
</Form.Field>
|
||||||
<Form.Field>
|
<Form.Field>
|
||||||
<Form.Input
|
<Form.Input
|
||||||
label='用户名'
|
label='用户名'
|
||||||
@ -112,16 +122,7 @@ const EditUser = () => {
|
|||||||
autoComplete='new-password'
|
autoComplete='new-password'
|
||||||
/>
|
/>
|
||||||
</Form.Field>
|
</Form.Field>
|
||||||
<Form.Field>
|
|
||||||
<Form.Input
|
|
||||||
label='显示名称'
|
|
||||||
name='display_name'
|
|
||||||
placeholder={'请输入新的显示名称'}
|
|
||||||
onChange={handleInputChange}
|
|
||||||
value={display_name}
|
|
||||||
autoComplete='new-password'
|
|
||||||
/>
|
|
||||||
</Form.Field>
|
|
||||||
{
|
{
|
||||||
userId && <>
|
userId && <>
|
||||||
<Form.Field>
|
<Form.Field>
|
||||||
@ -153,7 +154,7 @@ const EditUser = () => {
|
|||||||
</Form.Field>
|
</Form.Field>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
<Form.Field>
|
{/* <Form.Field>
|
||||||
<Form.Input
|
<Form.Input
|
||||||
label='已绑定的 GitHub 账户'
|
label='已绑定的 GitHub 账户'
|
||||||
name='github_id'
|
name='github_id'
|
||||||
@ -162,8 +163,8 @@ const EditUser = () => {
|
|||||||
placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改'
|
placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改'
|
||||||
readOnly
|
readOnly
|
||||||
/>
|
/>
|
||||||
</Form.Field>
|
</Form.Field> */}
|
||||||
<Form.Field>
|
{/* <Form.Field>
|
||||||
<Form.Input
|
<Form.Input
|
||||||
label='已绑定的微信账户'
|
label='已绑定的微信账户'
|
||||||
name='wechat_id'
|
name='wechat_id'
|
||||||
@ -172,8 +173,8 @@ const EditUser = () => {
|
|||||||
placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改'
|
placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改'
|
||||||
readOnly
|
readOnly
|
||||||
/>
|
/>
|
||||||
</Form.Field>
|
</Form.Field> */}
|
||||||
<Form.Field>
|
{/* <Form.Field>
|
||||||
<Form.Input
|
<Form.Input
|
||||||
label='已绑定的邮箱账户'
|
label='已绑定的邮箱账户'
|
||||||
name='email'
|
name='email'
|
||||||
@ -182,7 +183,7 @@ const EditUser = () => {
|
|||||||
placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改'
|
placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改'
|
||||||
readOnly
|
readOnly
|
||||||
/>
|
/>
|
||||||
</Form.Field>
|
</Form.Field> */}
|
||||||
<Button onClick={handleCancel}>取消</Button>
|
<Button onClick={handleCancel}>取消</Button>
|
||||||
<Button positive onClick={submit}>提交</Button>
|
<Button positive onClick={submit}>提交</Button>
|
||||||
</Form>
|
</Form>
|
||||||
|
Loading…
Reference in New Issue
Block a user