feat(ui): 添加系统管理菜单功能并优化模型相关文案
- 新增系统管理菜单,包含用户管理、资源授权和系统设置功能 - 实现资源授权下拉菜单,支持应用、知识库、工具和模型的授权管理 - 实现系统设置下拉菜单,支持邮件设置等功能 - 将模型相关文案中的"供应商"统一修改为"模型",提升表述准确性 - 更新模型表单和API中的字段名称和提示信息 - 修复前端国际化文件中模型相关的翻译内容v3.2
parent
b70a4c5825
commit
0546b773db
|
|
@ -134,8 +134,8 @@ class BaseExecField(BaseField):
|
|||
:param label: 提示
|
||||
:param text_field: 文本字段
|
||||
:param value_field: 值字段
|
||||
:param provider: 指定供应商
|
||||
:param method: 执行供应商函数 method
|
||||
:param provider: 指定模型
|
||||
:param method: 执行模型函数 method
|
||||
:param required: 是否必填
|
||||
:param default_value: 默认值
|
||||
:param relation_show_field_dict: {field:field_value_list} 表示在 field有值 ,并且值在field_value_list中才显示
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class Model(AppModelMixin):
|
|||
|
||||
user = models.ForeignKey(User, on_delete=models.SET_NULL, db_constraint=False, blank=True, null=True)
|
||||
|
||||
provider = models.CharField(max_length=128, verbose_name='供应商', db_index=True)
|
||||
provider = models.CharField(max_length=128, verbose_name='模型', db_index=True)
|
||||
|
||||
credential = models.CharField(max_length=102400, verbose_name="模型认证信息")
|
||||
|
||||
|
|
|
|||
|
|
@ -3272,7 +3272,7 @@ msgstr "基础模型"
|
|||
#: apps/shared/api/shared_model.py:39
|
||||
#: apps/shared/serializers/shared_model.py:114
|
||||
msgid "provider"
|
||||
msgstr "供应商"
|
||||
msgstr "模型"
|
||||
|
||||
#: apps/models_provider/api/model.py:65
|
||||
#: apps/models_provider/serializers/model_serializer.py:322
|
||||
|
|
@ -5115,7 +5115,7 @@ msgstr "重新排序文档"
|
|||
#: apps/models_provider/views/provide.py:22
|
||||
#: apps/models_provider/views/provide.py:23
|
||||
msgid "Get a list of model suppliers"
|
||||
msgstr "获取模型供应商列表"
|
||||
msgstr "获取模型模型列表"
|
||||
|
||||
#: apps/models_provider/views/provide.py:43
|
||||
#: apps/models_provider/views/provide.py:44
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class Migration(migrations.Migration):
|
|||
('status', models.CharField(choices=[('SUCCESS', '成功'), ('ERROR', '失败'), ('DOWNLOAD', '下载中'), ('PAUSE_DOWNLOAD', '暂停下载')], db_index=True, default='SUCCESS', max_length=20, verbose_name='设置类型')),
|
||||
('model_type', models.CharField(db_index=True, max_length=128, verbose_name='模型类型')),
|
||||
('model_name', models.CharField(db_index=True, max_length=128, verbose_name='模型名称')),
|
||||
('provider', models.CharField(db_index=True, max_length=128, verbose_name='供应商')),
|
||||
('provider', models.CharField(db_index=True, max_length=128, verbose_name='模型')),
|
||||
('credential', models.CharField(max_length=102400, verbose_name='模型认证信息')),
|
||||
('meta', models.JSONField(default=dict, verbose_name='模型元数据,用于存储下载,或者错误信息')),
|
||||
('model_params_form', models.JSONField(default=list, verbose_name='模型参数配置')),
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class Model(AppModelMixin):
|
|||
|
||||
user = models.ForeignKey(User, on_delete=models.SET_NULL, db_constraint=False, blank=True, null=True)
|
||||
|
||||
provider = models.CharField(max_length=128, verbose_name='供应商', db_index=True)
|
||||
provider = models.CharField(max_length=128, verbose_name='模型', db_index=True)
|
||||
|
||||
credential = models.CharField(max_length=102400, verbose_name="模型认证信息")
|
||||
|
||||
|
|
|
|||
|
|
@ -24,12 +24,12 @@ from models_provider.constants.model_provider_constants import ModelProvideConst
|
|||
def get_model_(provider, model_type, model_name, credential, model_id, use_local=False, **kwargs):
|
||||
"""
|
||||
获取模型实例
|
||||
@param provider: 供应商
|
||||
@param provider: 模型
|
||||
@param model_type: 模型类型
|
||||
@param model_name: 模型名称
|
||||
@param credential: 认证信息
|
||||
@param model_id: 模型id
|
||||
@param use_local: 是否调用本地模型 只适用于本地供应商
|
||||
@param use_local: 是否调用本地模型 只适用于本地模型
|
||||
@return: 模型实例
|
||||
"""
|
||||
model = get_provider(provider).get_model(model_type, model_name,
|
||||
|
|
@ -52,9 +52,9 @@ def get_model(model, **kwargs):
|
|||
|
||||
def get_provider(provider):
|
||||
"""
|
||||
获取供应商实例
|
||||
@param provider: 供应商字符串
|
||||
@return: 供应商实例
|
||||
获取模型实例
|
||||
@param provider: 模型字符串
|
||||
@return: 模型实例
|
||||
"""
|
||||
return ModelProvideConstants[provider].value
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ def get_provider(provider):
|
|||
def get_model_list(provider, model_type):
|
||||
"""
|
||||
获取模型列表
|
||||
@param provider: 供应商字符串
|
||||
@param provider: 模型字符串
|
||||
@param model_type: 模型类型
|
||||
@return: 模型列表
|
||||
"""
|
||||
|
|
@ -72,7 +72,7 @@ def get_model_list(provider, model_type):
|
|||
def get_model_credential(provider, model_type, model_name):
|
||||
"""
|
||||
获取模型认证实例
|
||||
@param provider: 供应商字符串
|
||||
@param provider: 模型字符串
|
||||
@param model_type: 模型类型
|
||||
@param model_name: 模型名称
|
||||
@return: 认证实例对象
|
||||
|
|
@ -83,7 +83,7 @@ def get_model_credential(provider, model_type, model_name):
|
|||
def get_model_type_list(provider):
|
||||
"""
|
||||
获取模型类型列表
|
||||
@param provider: 供应商字符串
|
||||
@param provider: 模型字符串
|
||||
@return: 模型类型列表
|
||||
"""
|
||||
return get_provider(provider).get_model_type_list()
|
||||
|
|
@ -93,7 +93,7 @@ def is_valid_credential(provider, model_type, model_name, model_credential: Dict
|
|||
raise_exception=False):
|
||||
"""
|
||||
校验模型认证参数
|
||||
@param provider: 供应商字符串
|
||||
@param provider: 模型字符串
|
||||
@param model_type: 模型类型
|
||||
@param model_name: 模型名称
|
||||
@param model_credential: 模型认证数据
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -7,14 +7,14 @@ import type {KeyValue} from '../type/common'
|
|||
|
||||
const prefix_provider = '/provider'
|
||||
/**
|
||||
* 获得供应商列表
|
||||
* 获得模型列表
|
||||
*/
|
||||
const getProvider: (loading?: Ref<boolean>) => Promise<Result<Array<Provider>>> = (loading) => {
|
||||
return get(`${prefix_provider}`, {}, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得供应商列表
|
||||
* 获得模型列表
|
||||
*/
|
||||
const getProviderByModelType: (
|
||||
model_type: string,
|
||||
|
|
@ -42,7 +42,7 @@ const getModelCreateForm: (
|
|||
|
||||
/**
|
||||
* 获取模型类型列表
|
||||
* @param provider 供应商
|
||||
* @param provider 模型
|
||||
* @param loading 加载器
|
||||
* @returns 模型类型列表
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -7,15 +7,15 @@ interface modelRequest {
|
|||
|
||||
interface Provider {
|
||||
/**
|
||||
* 供应商代号
|
||||
* 模型代号
|
||||
*/
|
||||
provider: string
|
||||
/**
|
||||
* 供应商名称
|
||||
* 模型名称
|
||||
*/
|
||||
name: string
|
||||
/**
|
||||
* 供应商icon
|
||||
* 模型icon
|
||||
*/
|
||||
icon: string
|
||||
}
|
||||
|
|
@ -34,7 +34,7 @@ interface ListModelRequest {
|
|||
*/
|
||||
model_name?: string
|
||||
/**
|
||||
* 供应商
|
||||
* 模型
|
||||
*/
|
||||
provider?: string
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ interface Model {
|
|||
*/
|
||||
credential: any
|
||||
/**
|
||||
* 供应商
|
||||
* 模型
|
||||
*/
|
||||
provider: string
|
||||
/**
|
||||
|
|
@ -100,7 +100,7 @@ interface CreateModelRequest {
|
|||
*/
|
||||
credential: any
|
||||
/**
|
||||
* 供应商
|
||||
* 模型
|
||||
*/
|
||||
provider: string
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ interface FormField {
|
|||
*/
|
||||
option_list?: Array<any>
|
||||
/**
|
||||
* 供应商
|
||||
* 模型
|
||||
*/
|
||||
provider?: string
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -5,9 +5,10 @@
|
|||
<h1 style="font-size: 18px; font-weight: 600; margin: 0;">AI-RAG</h1>
|
||||
</div>
|
||||
|
||||
<!-- 一级业务菜单 -->
|
||||
<!-- 业务菜单或系统管理菜单 -->
|
||||
<div style="padding: 0 16px;">
|
||||
<div style="display: flex; flex-direction: column; gap: 8px;">
|
||||
<!-- 业务菜单 -->
|
||||
<div v-if="!isSystemManagement" style="display: flex; flex-direction: column; gap: 8px;">
|
||||
<router-link to="/application" style="display: block; padding: 10px 16px; border-radius: 8px; text-decoration: none; color: #333; font-size: 14px;" :style="activeMainMenu === '/application' ? { backgroundColor: '#e6f0ff', color: '#1890ff' } : {}">
|
||||
应用
|
||||
</router-link>
|
||||
|
|
@ -21,6 +22,48 @@
|
|||
模型
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<!-- 系统管理菜单 -->
|
||||
<div v-else style="display: flex; flex-direction: column; gap: 8px;">
|
||||
<router-link to="/system/user" style="display: block; padding: 10px 16px; border-radius: 8px; text-decoration: none; color: #333; font-size: 14px;" :style="activeSystemMenu === '/system/user' ? { backgroundColor: '#e6f0ff', color: '#1890ff' } : {}">
|
||||
用户管理
|
||||
</router-link>
|
||||
|
||||
<!-- 资源授权(下拉展开) -->
|
||||
<div>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; padding: 10px 16px; border-radius: 8px; cursor: pointer;" :style="activeSystemMenu.startsWith('/system/authorization') ? { backgroundColor: '#e6f0ff', color: '#1890ff' } : {}" @click="toggleResourceAuth">
|
||||
<span>资源授权</span>
|
||||
<span>{{ resourceAuthExpanded ? '▼' : '▶' }}</span>
|
||||
</div>
|
||||
<div v-if="resourceAuthExpanded" style="padding-left: 32px; margin-top: 4px; display: flex; flex-direction: column; gap: 4px;">
|
||||
<router-link to="/system/authorization/application" style="display: block; padding: 8px 16px; border-radius: 8px; text-decoration: none; color: #666; font-size: 13px;" :style="activeSystemMenu === '/system/authorization/application' ? { backgroundColor: '#e6f0ff', color: '#1890ff' } : {}">
|
||||
应用
|
||||
</router-link>
|
||||
<router-link to="/system/authorization/knowledge" style="display: block; padding: 8px 16px; border-radius: 8px; text-decoration: none; color: #666; font-size: 13px;" :style="activeSystemMenu === '/system/authorization/knowledge' ? { backgroundColor: '#e6f0ff', color: '#1890ff' } : {}">
|
||||
知识库
|
||||
</router-link>
|
||||
<router-link to="/system/authorization/tool" style="display: block; padding: 8px 16px; border-radius: 8px; text-decoration: none; color: #666; font-size: 13px;" :style="activeSystemMenu === '/system/authorization/tool' ? { backgroundColor: '#e6f0ff', color: '#1890ff' } : {}">
|
||||
工具
|
||||
</router-link>
|
||||
<router-link to="/system/authorization/model" style="display: block; padding: 8px 16px; border-radius: 8px; text-decoration: none; color: #666; font-size: 13px;" :style="activeSystemMenu === '/system/authorization/model' ? { backgroundColor: '#e6f0ff', color: '#1890ff' } : {}">
|
||||
模型
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 系统设置(下拉展开) -->
|
||||
<div>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; padding: 10px 16px; border-radius: 8px; cursor: pointer;" :style="activeSystemMenu.startsWith('/system/email') ? { backgroundColor: '#e6f0ff', color: '#1890ff' } : {}" @click="toggleSystemSettings">
|
||||
<span>系统设置</span>
|
||||
<span>{{ systemSettingsExpanded ? '▼' : '▶' }}</span>
|
||||
</div>
|
||||
<div v-if="systemSettingsExpanded" style="padding-left: 32px; margin-top: 4px; display: flex; flex-direction: column; gap: 4px;">
|
||||
<router-link to="/system/email" style="display: block; padding: 8px 16px; border-radius: 8px; text-decoration: none; color: #666; font-size: 13px;" :style="activeSystemMenu === '/system/email' ? { backgroundColor: '#e6f0ff', color: '#1890ff' } : {}">
|
||||
邮件设置
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部用户信息区 -->
|
||||
|
|
@ -31,12 +74,19 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import UserAvatar from '@/layout/layout-header/avatar/index.vue'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
// 判断是否在系统管理页面
|
||||
const isSystemManagement = computed(() => {
|
||||
const path = route.path
|
||||
return path.startsWith('/system')
|
||||
})
|
||||
|
||||
// 业务菜单激活状态
|
||||
const activeMainMenu = computed(() => {
|
||||
const path = route.path
|
||||
if (path.startsWith('/application')) return '/application'
|
||||
|
|
@ -46,6 +96,34 @@ const activeMainMenu = computed(() => {
|
|||
return '/application'
|
||||
})
|
||||
|
||||
// 系统管理菜单激活状态
|
||||
const activeSystemMenu = computed(() => {
|
||||
const path = route.path
|
||||
if (path.startsWith('/system/user')) return '/system/user'
|
||||
if (path.startsWith('/system/authorization')) return path
|
||||
if (path.startsWith('/system/email')) return path
|
||||
return '/system/user'
|
||||
})
|
||||
|
||||
// 资源授权下拉菜单展开状态
|
||||
const resourceAuthExpanded = ref(false)
|
||||
// 系统设置下拉菜单展开状态
|
||||
const systemSettingsExpanded = ref(false)
|
||||
|
||||
// 切换资源授权下拉菜单
|
||||
const toggleResourceAuth = () => {
|
||||
resourceAuthExpanded.value = !resourceAuthExpanded.value
|
||||
// 关闭其他下拉菜单
|
||||
systemSettingsExpanded.value = false
|
||||
}
|
||||
|
||||
// 切换系统设置下拉菜单
|
||||
const toggleSystemSettings = () => {
|
||||
systemSettingsExpanded.value = !systemSettingsExpanded.value
|
||||
// 关闭其他下拉菜单
|
||||
resourceAuthExpanded.value = false
|
||||
}
|
||||
|
||||
const activeSubMenu = computed(() => {
|
||||
const path = route.path
|
||||
return path
|
||||
|
|
|
|||
|
|
@ -1,36 +1,16 @@
|
|||
<template>
|
||||
<div class="app-top-bar-container border-b flex-center">
|
||||
<div class="logo mt-4">
|
||||
<LogoFull />
|
||||
</div>
|
||||
|
||||
<div class="flex-between w-full align-center">
|
||||
<h4><el-divider class="ml-16 mr-16" direction="vertical" />{{ $t('views.system.title') }}</h4>
|
||||
<div class="flex align-center mr-8">
|
||||
<TopAbout></TopAbout>
|
||||
<el-divider class="ml-8 mr-8" direction="vertical" />
|
||||
<el-button
|
||||
link
|
||||
@click="router.push({ path: '/' })"
|
||||
style="color: var(--el-text-color-primary)"
|
||||
v-if="
|
||||
hasPermission(
|
||||
[
|
||||
RoleConst.USER.getWorkspaceRole,
|
||||
RoleConst.EXTENDS_USER.getWorkspaceRole,
|
||||
RoleConst.EXTENDS_WORKSPACE_MANAGE.getWorkspaceRole,
|
||||
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||
],
|
||||
'OR',
|
||||
)
|
||||
"
|
||||
>
|
||||
<AppIcon class="mr-8" iconName="app-workspace" style="font-size: 16px"></AppIcon>
|
||||
{{ $t('views.workspace.toWorkspace') }}</el-button
|
||||
>
|
||||
<div class="flex-between w-full align-center" style="padding: 0 16px;">
|
||||
<div style="display: flex; align-items: center;">
|
||||
<h1 style="font-size: 18px; font-weight: 600; margin: 0;">AI-RAG | 系统管理</h1>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center;">
|
||||
<router-link to="/application" style="display: flex; align-items: center; padding: 6px 12px; border-radius: 6px; text-decoration: none; color: #1890ff; border: 1px solid #1890ff;">
|
||||
<span style="margin-right: 4px;">←</span>
|
||||
返回工作空间
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<Avatar></Avatar>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { computed } from 'vue'
|
|||
import Sidebar from '@/layout/components/sidebar/index.vue'
|
||||
import AppMain from '@/layout/app-main/index.vue'
|
||||
import LayoutContainer from '@/components/layout-container/index.vue'
|
||||
import UserAvatar from '@/layout/layout-header/avatar/index.vue'
|
||||
import useStore from '@/stores'
|
||||
import { useRoute } from 'vue-router'
|
||||
const route = useRoute()
|
||||
|
|
@ -19,6 +20,30 @@ const isShared = computed(() => {
|
|||
route.path.includes('resource-management')
|
||||
)
|
||||
})
|
||||
|
||||
// 判断是否在系统管理页面
|
||||
const isSystemManagement = computed(() => {
|
||||
const path = route.path
|
||||
return path.startsWith('/system')
|
||||
})
|
||||
|
||||
// 页面标题
|
||||
const pageTitle = computed(() => {
|
||||
return 'AI-RAG'
|
||||
})
|
||||
|
||||
// 当前系统页面
|
||||
const currentSystemPage = computed(() => {
|
||||
const path = route.path
|
||||
if (path.startsWith('/system/user')) {
|
||||
return '用户管理'
|
||||
} else if (path.startsWith('/system/resource')) {
|
||||
return '资源授权'
|
||||
} else if (path.startsWith('/system/settings')) {
|
||||
return '系统设置'
|
||||
}
|
||||
return '用户管理'
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -28,7 +53,22 @@ const isShared = computed(() => {
|
|||
<template #left>
|
||||
<Sidebar />
|
||||
</template>
|
||||
<AppMain />
|
||||
<div>
|
||||
<!-- 顶部功能区(仅系统管理模式显示) -->
|
||||
<div v-if="isSystemManagement" style="display: flex; justify-content: space-between; align-items: center; padding: 16px; border-bottom: 1px solid #e5e7eb;">
|
||||
<div style="display: flex; align-items: center;">
|
||||
<h2 style="font-size: 18px; font-weight: 600; margin: 0;">AI-RAG | 系统管理</h2>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center;">
|
||||
<router-link to="/application" style="display: flex; align-items: center; padding: 6px 12px; border-radius: 6px; text-decoration: none; color: #1890ff; border: 1px solid #1890ff;">
|
||||
<span style="margin-right: 4px;">←</span>
|
||||
返回工作空间
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<AppMain />
|
||||
</div>
|
||||
</LayoutContainer>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
export default {
|
||||
title: '模型',
|
||||
provider: '供应商',
|
||||
providerPlaceholder: '选择供应商',
|
||||
provider: '模型',
|
||||
providerPlaceholder: '选择模型',
|
||||
addModel: '添加模型',
|
||||
delete: {
|
||||
confirmTitle: '是否删除:',
|
||||
|
|
|
|||
Loading…
Reference in New Issue