mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-17 16:56:38 +08:00
refactor: 完成管理后台的系统设置页面重构
This commit is contained in:
parent
935c6caf96
commit
af3f7ac810
@ -137,8 +137,7 @@ func authorizeMiddleware(s *AppServer) gin.HandlerFunc {
|
|||||||
if c.Request.URL.Path == "/api/user/login" ||
|
if c.Request.URL.Path == "/api/user/login" ||
|
||||||
c.Request.URL.Path == "/api/admin/login" ||
|
c.Request.URL.Path == "/api/admin/login" ||
|
||||||
c.Request.URL.Path == "/api/user/register" ||
|
c.Request.URL.Path == "/api/user/register" ||
|
||||||
c.Request.URL.Path == "/api/apikey/add" ||
|
c.Request.URL.Path == "/api/config/get" {
|
||||||
c.Request.URL.Path == "/api/apikey/list" {
|
|
||||||
c.Next()
|
c.Next()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,4 @@ type SystemConfig struct {
|
|||||||
UserInitCalls int `json:"user_init_calls"` // 新用户注册默认总送多少次调用
|
UserInitCalls int `json:"user_init_calls"` // 新用户注册默认总送多少次调用
|
||||||
}
|
}
|
||||||
|
|
||||||
var GptModels = []string{"gpt-3.5-turbo", "gpt-3.5-turbo-16k", "gpt-3.5-turbo-0613", "gpt-3.5-turbo-16k-0613", "gpt-4", "gpt-4-0613", "gpt-4-32k", "gpt-4-32k-0613"}
|
|
||||||
|
|
||||||
const UserInitCalls = 1000
|
const UserInitCalls = 1000
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package handler
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"chatplus/core"
|
"chatplus/core"
|
||||||
"chatplus/core/types"
|
"chatplus/core/types"
|
||||||
|
"chatplus/handler"
|
||||||
"chatplus/store/model"
|
"chatplus/store/model"
|
||||||
"chatplus/utils"
|
"chatplus/utils"
|
||||||
"chatplus/utils/resp"
|
"chatplus/utils/resp"
|
||||||
@ -12,14 +13,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ConfigHandler struct {
|
type ConfigHandler struct {
|
||||||
BaseHandler
|
handler.BaseHandler
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConfigHandler(app *core.AppServer, db *gorm.DB) *ConfigHandler {
|
func NewConfigHandler(app *core.AppServer, db *gorm.DB) *ConfigHandler {
|
||||||
handler := ConfigHandler{db: db}
|
h := ConfigHandler{db: db}
|
||||||
handler.App = app
|
h.App = app
|
||||||
return &handler
|
return &h
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *ConfigHandler) Update(c *gin.Context) {
|
func (h *ConfigHandler) Update(c *gin.Context) {
|
||||||
@ -71,8 +72,3 @@ func (h *ConfigHandler) Get(c *gin.Context) {
|
|||||||
|
|
||||||
resp.SUCCESS(c, m)
|
resp.SUCCESS(c, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AllGptModels 获取所有的 GPT 模型
|
|
||||||
func (h *ConfigHandler) AllGptModels(c *gin.Context) {
|
|
||||||
resp.SUCCESS(c, types.GptModels)
|
|
||||||
}
|
|
@ -85,7 +85,7 @@ func main() {
|
|||||||
fx.Provide(handler.NewChatRoleHandler),
|
fx.Provide(handler.NewChatRoleHandler),
|
||||||
fx.Provide(handler.NewUserHandler),
|
fx.Provide(handler.NewUserHandler),
|
||||||
fx.Provide(handler.NewChatHandler),
|
fx.Provide(handler.NewChatHandler),
|
||||||
fx.Provide(handler.NewConfigHandler),
|
fx.Provide(admin.NewConfigHandler),
|
||||||
|
|
||||||
fx.Provide(admin.NewAdminHandler),
|
fx.Provide(admin.NewAdminHandler),
|
||||||
fx.Provide(admin.NewApiKeyHandler),
|
fx.Provide(admin.NewApiKeyHandler),
|
||||||
@ -117,13 +117,13 @@ func main() {
|
|||||||
group.GET("tokens", h.Tokens)
|
group.GET("tokens", h.Tokens)
|
||||||
group.GET("stop", h.StopGenerate)
|
group.GET("stop", h.StopGenerate)
|
||||||
}),
|
}),
|
||||||
fx.Invoke(func(s *core.AppServer, h *handler.ConfigHandler) {
|
|
||||||
group := s.Engine.Group("/api/config/")
|
//
|
||||||
|
fx.Invoke(func(s *core.AppServer, h *admin.ConfigHandler) {
|
||||||
|
group := s.Engine.Group("/api/admin/config/")
|
||||||
group.POST("update", h.Update)
|
group.POST("update", h.Update)
|
||||||
group.GET("get", h.Get)
|
group.GET("get", h.Get)
|
||||||
group.GET("models", h.AllGptModels)
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
fx.Invoke(func(s *core.AppServer, h *admin.ManagerHandler) {
|
fx.Invoke(func(s *core.AppServer, h *admin.ManagerHandler) {
|
||||||
group := s.Engine.Group("/api/admin/")
|
group := s.Engine.Group("/api/admin/")
|
||||||
group.POST("login", h.Login)
|
group.POST("login", h.Login)
|
||||||
|
@ -200,7 +200,8 @@ import {
|
|||||||
Close,
|
Close,
|
||||||
Delete,
|
Delete,
|
||||||
Edit,
|
Edit,
|
||||||
Plus, Promotion,
|
Plus,
|
||||||
|
Promotion,
|
||||||
RefreshRight,
|
RefreshRight,
|
||||||
Search,
|
Search,
|
||||||
Tools,
|
Tools,
|
||||||
@ -270,7 +271,7 @@ if (!user.value) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 加载系统配置
|
// 加载系统配置
|
||||||
httpGet('/api/config/get?key=system').then(res => {
|
httpGet('/api/admin/config/get?key=system').then(res => {
|
||||||
title.value = res.data.title;
|
title.value = res.data.title;
|
||||||
models.value = res.data.models;
|
models.value = res.data.models;
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
@ -731,8 +732,10 @@ $borderColor = #4676d0;
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
// left side
|
// left side
|
||||||
|
|
||||||
.el-aside {
|
.el-aside {
|
||||||
background-color: $sideBgColor;
|
background-color: $sideBgColor;
|
||||||
|
|
||||||
.title-box {
|
.title-box {
|
||||||
padding: 6px 10px;
|
padding: 6px 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -94,16 +94,15 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {computed, defineComponent, onMounted, ref} from 'vue'
|
import {computed, onMounted, ref} from 'vue'
|
||||||
import {Fold, Menu} from "@element-plus/icons-vue"
|
import {Fold, Menu} from "@element-plus/icons-vue"
|
||||||
import XWelcome from "@/views/admin/Welcome.vue";
|
import XWelcome from "@/views/admin/Welcome.vue";
|
||||||
import SysConfig from "@/views/admin/SysConfig.vue";
|
import SysConfig from "@/views/admin/SysConfig.vue";
|
||||||
import {arrayContains, removeArrayItem} from "@/utils/libs";
|
import {arrayContains, removeArrayItem} from "@/utils/libs";
|
||||||
import UserList from "@/views/admin/UserList.vue";
|
import UserList from "@/views/admin/UserList.vue";
|
||||||
import RoleList from "@/views/admin/RoleList.vue";
|
import RoleList from "@/views/admin/RoleList.vue";
|
||||||
import {httpGet, httpPost} from "@/utils/http";
|
import {httpGet} from "@/utils/http";
|
||||||
import {ElMessage} from "element-plus";
|
import {ElMessage} from "element-plus";
|
||||||
import {setLoginUser} from "@/utils/storage";
|
|
||||||
import {useRouter} from "vue-router";
|
import {useRouter} from "vue-router";
|
||||||
|
|
||||||
const title = ref('Chat-Plus 控制台')
|
const title = ref('Chat-Plus 控制台')
|
||||||
@ -118,7 +117,7 @@ const navs = ref([
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
title: '口令管理',
|
title: '用户管理',
|
||||||
tab: 'user',
|
tab: 'user',
|
||||||
active: false,
|
active: false,
|
||||||
},
|
},
|
||||||
@ -151,9 +150,17 @@ onMounted(() => {
|
|||||||
winHeight.value = window.innerHeight
|
winHeight.value = window.innerHeight
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 获取会话信息
|
||||||
httpGet("/api/admin/session").catch(() => {
|
httpGet("/api/admin/session").catch(() => {
|
||||||
router.push('/admin/login')
|
router.push('/admin/login')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 加载系统配置
|
||||||
|
httpGet('/api/admin/config/get?key=system').then(res => {
|
||||||
|
title.value = res.data['admin_title'];
|
||||||
|
}).catch(e => {
|
||||||
|
ElMessage.error("加载系统配置失败: " + e.message)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const logout = function () {
|
const logout = function () {
|
||||||
@ -286,6 +293,7 @@ $borderColor = #4676d0;
|
|||||||
|
|
||||||
.nav-footer {
|
.nav-footer {
|
||||||
flex-direction column
|
flex-direction column
|
||||||
|
|
||||||
div {
|
div {
|
||||||
padding 10px 20px;
|
padding 10px 20px;
|
||||||
font-size 14px;
|
font-size 14px;
|
||||||
@ -311,7 +319,6 @@ $borderColor = #4676d0;
|
|||||||
.el-main {
|
.el-main {
|
||||||
--el-main-padding: 0;
|
--el-main-padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background-image url("~@/assets/img/bg_01.jpeg")
|
|
||||||
|
|
||||||
.main-container {
|
.main-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -325,6 +332,10 @@ $borderColor = #4676d0;
|
|||||||
height 35px
|
height 35px
|
||||||
line-height 35px
|
line-height 35px
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-tabs__content {
|
||||||
|
padding 10px 20px 20px 20px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -332,5 +343,4 @@ $borderColor = #4676d0;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,213 +1,183 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="system-config" v-loading="loading">
|
<div class="system-config" v-loading="loading">
|
||||||
<el-form :model="form" label-width="120px">
|
<div class="container">
|
||||||
<el-form-item label="应用标题">
|
<el-divider content-position="center">基本设置</el-divider>
|
||||||
<el-input v-model="form['title']"/>
|
<el-form :model="system" label-width="120px" label-position="left" ref="systemFormRef" :rules="rules">
|
||||||
|
<el-form-item label="网站标题" prop="title">
|
||||||
|
<el-input v-model="system['title']"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="控制台标题">
|
<el-form-item label="控制台标题" prop="admin_title">
|
||||||
<el-input v-model="form['console_title']"/>
|
<el-input v-model="system['admin_title']"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="代理地址">
|
<el-form-item label="注册赠送次数" prop="init_calls">
|
||||||
<el-input v-model="form['proxy_url']" placeholder="多个地址之间用逗号隔开"/>
|
<el-input v-model.number="system['init_calls']" placeholder="新用户注册赠送对话次数"/>
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item label="微信群聊二维码">
|
|
||||||
<el-input v-model="form['img_url']['wechat_group']" placeholder="群聊二维码地址"/>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item label="个人微信名片">
|
|
||||||
<el-input v-model="form['img_url']['wechat_card']" placeholder="名片二维码地址"/>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-divider content-position="center">聊天设置</el-divider>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<div class="grid-content">
|
|
||||||
<el-form-item label="GPT模型">
|
|
||||||
<el-input v-model="form['model']" placeholder="gpt-3/gpt-3.5-turbo/gpt-4"/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-alert type="info" show-icon :closable="false">
|
||||||
|
<p>在这里维护前端聊天页面可用的 GPT 模型列表</p>
|
||||||
|
</el-alert>
|
||||||
|
<el-form-item label="GPT 模型" prop="models">
|
||||||
|
<div class="models">
|
||||||
|
<el-tag
|
||||||
|
v-for="item in system.models"
|
||||||
|
:key="item"
|
||||||
|
@close="removeModel(item)"
|
||||||
|
round
|
||||||
|
closable
|
||||||
|
>
|
||||||
|
{{ item }}
|
||||||
|
</el-tag>
|
||||||
|
<el-button type="success" :icon="Plus" @click="addModel" size="small" circle/>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<div class="grid-content">
|
|
||||||
<el-form-item label="模型温度">
|
|
||||||
<el-input v-model="form['temperature']" placeholder="0-1之间的小数"/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<div class="grid-content">
|
|
||||||
<el-form-item label="Max Tokens">
|
|
||||||
<el-input v-model="form['max_tokens']" placeholder="回复的最大字数,最大4096"/>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12">
|
|
||||||
<div class="grid-content">
|
|
||||||
<el-form-item label="上下文超时">
|
|
||||||
<el-input v-model="form['chat_context_expire_time']" placeholder="单位:秒"/>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-form-item label="对话上下文">
|
|
||||||
<el-switch v-model="form['enable_context']"/>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="saveConfig">保存</el-button>
|
<el-button type="primary" @click="save('system')">保存</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<el-divider content-position="center">API KEY 管理</el-divider>
|
<el-divider content-position="center">聊天设置</el-divider>
|
||||||
<el-row class="api-key-box">
|
<el-alert type="info" show-icon :closable="false">
|
||||||
<el-input
|
<p>以下配置为新用户注册默认初始化的聊天参数,用户登录后还可以自己修改参数。</p>
|
||||||
v-model="apiKey"
|
</el-alert>
|
||||||
placeholder="输入 API KEY"
|
<el-form :model="chat" label-position="left" label-width="120px">
|
||||||
class="input-with-select"
|
<el-form-item label="OpenAI API 地址">
|
||||||
>
|
<el-input v-model="chat['api_url']" placeholder="gpt-3/gpt-3.5-turbo/gpt-4"/>
|
||||||
<template #prepend>
|
</el-form-item>
|
||||||
<el-button type="primary">
|
<el-form-item label="默认模型">
|
||||||
<el-icon>
|
<el-input v-model="chat['model']" placeholder="用户默认使用的 GPT 模型"/>
|
||||||
<Plus/>
|
</el-form-item>
|
||||||
</el-icon>
|
<el-form-item label="模型温度">
|
||||||
</el-button>
|
<el-input v-model="chat['temperature']" placeholder="0-1之间的小数"/>
|
||||||
</template>
|
</el-form-item>
|
||||||
<template #append>
|
<el-form-item label="Max Tokens">
|
||||||
<el-button class="new-proxy" @click="addApiKey">新增</el-button>
|
<el-input v-model="chat['max_tokens']" placeholder="回复的最大字数,最大4096"/>
|
||||||
</template>
|
</el-form-item>
|
||||||
</el-input>
|
<el-form-item label="开启聊天上下文">
|
||||||
</el-row>
|
<el-switch v-model="chat['enable_context']"/>
|
||||||
|
</el-form-item>
|
||||||
<el-row>
|
<el-form-item label="保存聊天记录">
|
||||||
<el-table :data="apiKeys" style="width: 100%">
|
<el-switch v-model="chat['enable_history']"/>
|
||||||
<el-table-column prop="value" label="API-KEY"/>
|
</el-form-item>
|
||||||
<el-table-column prop="last_used" label="最后使用" width="180">
|
|
||||||
<template #default="scope">
|
|
||||||
<span v-if="scope.row['last_used'] > 0">{{ dateFormat(scope.row['last_used']) }}</span>
|
|
||||||
<el-tag v-else>未使用</el-tag>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="操作" width="180">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-popconfirm
|
|
||||||
width="220"
|
|
||||||
confirm-button-text="确定"
|
|
||||||
cancel-button-text="取消"
|
|
||||||
title="确定删除该记录吗?"
|
|
||||||
:hide-after="0"
|
|
||||||
@confirm="removeApiKey(scope.row.value)"
|
|
||||||
>
|
|
||||||
<template #reference>
|
|
||||||
<el-button
|
|
||||||
size="small"
|
|
||||||
type="danger">删除
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
</el-popconfirm>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
|
<el-form-item style="text-align: right">
|
||||||
|
<el-button type="primary" @click="save('chat')">保存</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import {defineComponent, nextTick} from "vue";
|
import {nextTick, onMounted, reactive, ref} from "vue";
|
||||||
import {Plus} from "@element-plus/icons-vue";
|
|
||||||
import {httpGet, httpPost} from "@/utils/http";
|
import {httpGet, httpPost} from "@/utils/http";
|
||||||
import {ElMessage} from "element-plus";
|
import {ElMessage, ElMessageBox} from "element-plus";
|
||||||
import {dateFormat, removeArrayItem} from "@/utils/libs";
|
import {Plus} from "@element-plus/icons-vue";
|
||||||
|
import {removeArrayItem} from "@/utils/libs";
|
||||||
|
|
||||||
export default defineComponent({
|
const system = ref({models: []})
|
||||||
name: 'SysConfig',
|
const chat = ref({})
|
||||||
components: {Plus},
|
const loading = ref(true)
|
||||||
data() {
|
const systemFormRef = ref(null)
|
||||||
return {
|
const tempModel = ref('')
|
||||||
apiKey: '',
|
const models = ref([])
|
||||||
form: {img_url: {}},
|
|
||||||
apiKeys: [],
|
onMounted(() => {
|
||||||
loading: true
|
// 加载系统配置
|
||||||
}
|
httpGet('/api/admin/config/get?key=system').then(res => {
|
||||||
},
|
system.value = res.data
|
||||||
mounted() {
|
system.value['models'].forEach(model => {
|
||||||
// 获取系统配置
|
models.value.push({
|
||||||
httpGet('/api/admin/config/get').then((res) => {
|
name: model,
|
||||||
this.form = res.data;
|
edit: false
|
||||||
}).catch(() => {
|
})
|
||||||
ElMessage.error('获取系统配置失败')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// 获取 API KEYS
|
}).catch(e => {
|
||||||
httpPost('api/admin/apikey/list').then((res) => {
|
ElMessage.error("加载系统配置失败: " + e.message)
|
||||||
this.apiKeys = res.data
|
})
|
||||||
}).catch(() => {
|
|
||||||
ElMessage.error('获取 API KEY 失败')
|
// 加载聊天配置
|
||||||
|
httpGet('/api/admin/config/get?key=chat').then(res => {
|
||||||
|
chat.value = res.data
|
||||||
|
}).catch(e => {
|
||||||
|
ElMessage.error("加载聊天配置失败: " + e.message)
|
||||||
})
|
})
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
this.loading = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
dateFormat() {
|
|
||||||
return dateFormat
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
saveConfig: function () {
|
|
||||||
this.form['temperature'] = parseFloat(this.form.temperature)
|
|
||||||
this.form['chat_context_expire_time'] = parseInt(this.form.chat_context_expire_time)
|
|
||||||
this.form['max_tokens'] = parseInt(this.form.max_tokens)
|
|
||||||
httpPost("/api/admin/config/set", this.form).then(() => {
|
|
||||||
ElMessage.success("保存成功");
|
|
||||||
}).catch((e) => {
|
|
||||||
console.log(e.message);
|
|
||||||
ElMessage.error("保存失败");
|
|
||||||
})
|
})
|
||||||
},
|
|
||||||
|
|
||||||
addApiKey: function () {
|
const rules = reactive({
|
||||||
if (this.apiKey.trim() === '') {
|
title: [{required: true, message: '请输入网站标题', trigger: 'blur',}],
|
||||||
ElMessage.error('请输入 API KEY')
|
admin_title: [{required: true, message: '请输入控制台标题', trigger: 'blur',}],
|
||||||
return
|
init_calls: [{required: true, message: '必须填入大于0的数组', trigger: 'blur',}],
|
||||||
}
|
models: [{required: true, message: '至少保留一个 GPT 模型', trigger: 'blur',}],
|
||||||
|
|
||||||
httpPost('api/admin/apikey/add', {api_key: this.apiKey.trim()}).then(() => {
|
|
||||||
ElMessage.success('添加成功')
|
|
||||||
this.apiKeys.unshift({value: this.apiKey, last_used: 0})
|
|
||||||
this.apiKey = ''
|
|
||||||
}).catch((e) => {
|
|
||||||
ElMessage.error('添加失败,' + e.message)
|
|
||||||
})
|
})
|
||||||
},
|
const save = function (key) {
|
||||||
|
systemFormRef.value.validate((valid) => {
|
||||||
removeApiKey: function (key) {
|
if (valid) {
|
||||||
httpPost('api/admin/apikey/remove', {api_key: key}).then(() => {
|
const data = key === 'system' ? system.value : chat.value
|
||||||
ElMessage.success('删除成功')
|
httpPost('/api/admin/config/update', {key: key, config: data}).then(() => {
|
||||||
this.apiKeys = removeArrayItem(this.apiKeys, key, function (v1, v2) {
|
ElMessage.success("操作成功!")
|
||||||
return v1.value === v2
|
}).catch(e => {
|
||||||
})
|
ElMessage.error("操作失败:" + e.message)
|
||||||
}).catch((e) => {
|
|
||||||
ElMessage.error('删除失败,' + e.message)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const removeModel = function (model) {
|
||||||
|
system.value.models = removeArrayItem(system.value.models, model, (v1, v2) => {
|
||||||
|
return v1 === v2
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 增加 GPT 模型
|
||||||
|
const addModel = function () {
|
||||||
|
ElMessageBox.prompt('请输入 GPT 模型名称', '新增模型', {
|
||||||
|
confirmButtonText: '保存',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
inputPattern:
|
||||||
|
/[\w+]/,
|
||||||
|
inputErrorMessage: '请输入模型名称',
|
||||||
|
|
||||||
|
}).then(({value}) => {
|
||||||
|
system.value.models.push(value)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.system-config {
|
.system-config {
|
||||||
|
display flex
|
||||||
|
justify-content center
|
||||||
|
|
||||||
.api-key-box {
|
.container {
|
||||||
padding-bottom: 10px;
|
width 100%
|
||||||
|
max-width 800px;
|
||||||
|
|
||||||
|
.el-form {
|
||||||
|
.el-form-item__content {
|
||||||
|
.models {
|
||||||
|
.el-tag {
|
||||||
|
margin-right 10px;
|
||||||
|
|
||||||
|
.el-input {
|
||||||
|
max-width 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-button--small {
|
||||||
|
font-size 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-alert {
|
||||||
|
margin-bottom 15px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="user-list" v-loading="loading">
|
<div class="user-list" v-loading="loading">
|
||||||
<el-row class="opt-box">
|
|
||||||
<el-button type="primary" @click="showUserDialog = true">
|
|
||||||
<el-icon>
|
|
||||||
<Plus/>
|
|
||||||
</el-icon>
|
|
||||||
新增口令
|
|
||||||
</el-button>
|
|
||||||
|
|
||||||
<el-button type="success" @click="showBatchAddUserDialog = true">
|
|
||||||
<el-icon>
|
|
||||||
<Plus/>
|
|
||||||
</el-icon>
|
|
||||||
批量生成口令
|
|
||||||
</el-button>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-table :data="users">
|
<el-table :data="users">
|
||||||
<el-table-column prop="name" label="口令名称"/>
|
<el-table-column prop="name" label="口令名称"/>
|
||||||
@ -258,7 +242,6 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {nextTick, onMounted, reactive, ref} from "vue";
|
import {nextTick, onMounted, reactive, ref} from "vue";
|
||||||
import {Plus} from "@element-plus/icons-vue";
|
|
||||||
import {httpPost} from "@/utils/http";
|
import {httpPost} from "@/utils/http";
|
||||||
import {ElMessage} from "element-plus";
|
import {ElMessage} from "element-plus";
|
||||||
import {arrayContains, removeArrayItem} from "@/utils/libs";
|
import {arrayContains, removeArrayItem} from "@/utils/libs";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="welcome" :style="{ height: winHeight + 'px' }">
|
<div class="welcome" :style="{ height: winHeight + 'px' }">
|
||||||
<h1>Chat-Plus 控制台</h1>
|
<h1>ChatGPT-PLUS 控制台</h1>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user