feat: 模型删除修改
This commit is contained in:
parent
b71ce75b3a
commit
4c164a49de
@ -21,8 +21,8 @@ from users.models import User
|
|||||||
class Application(AppModelMixin):
|
class Application(AppModelMixin):
|
||||||
id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid1, editable=False, verbose_name="主键id")
|
id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid1, editable=False, verbose_name="主键id")
|
||||||
name = models.CharField(max_length=128, verbose_name="应用名称")
|
name = models.CharField(max_length=128, verbose_name="应用名称")
|
||||||
desc = models.CharField(max_length=128, verbose_name="引用描述")
|
desc = models.CharField(max_length=128, verbose_name="引用描述", default="")
|
||||||
prologue = models.CharField(max_length=1024, verbose_name="开场白")
|
prologue = models.CharField(max_length=1024, verbose_name="开场白", default="")
|
||||||
example = ArrayField(verbose_name="示例列表", base_field=models.CharField(max_length=256, blank=True))
|
example = ArrayField(verbose_name="示例列表", base_field=models.CharField(max_length=256, blank=True))
|
||||||
dialogue_number = models.IntegerField(default=0, verbose_name="会话数量")
|
dialogue_number = models.IntegerField(default=0, verbose_name="会话数量")
|
||||||
status = models.BooleanField(default=True, verbose_name="是否发布")
|
status = models.BooleanField(default=True, verbose_name="是否发布")
|
||||||
|
|||||||
@ -62,10 +62,10 @@ class ApplicationSerializerModel(serializers.ModelSerializer):
|
|||||||
|
|
||||||
class ApplicationSerializer(serializers.Serializer):
|
class ApplicationSerializer(serializers.Serializer):
|
||||||
name = serializers.CharField(required=True)
|
name = serializers.CharField(required=True)
|
||||||
desc = serializers.CharField(required=True)
|
desc = serializers.CharField(required=False)
|
||||||
model_id = serializers.CharField(required=True)
|
model_id = serializers.CharField(required=True)
|
||||||
multiple_rounds_dialogue = serializers.BooleanField(required=True)
|
multiple_rounds_dialogue = serializers.BooleanField(required=True)
|
||||||
prologue = serializers.CharField(required=True)
|
prologue = serializers.CharField(required=False)
|
||||||
example = serializers.ListSerializer(required=False, child=serializers.CharField(required=True))
|
example = serializers.ListSerializer(required=False, child=serializers.CharField(required=True))
|
||||||
dataset_id_list = serializers.ListSerializer(required=False, child=serializers.UUIDField(required=True))
|
dataset_id_list = serializers.ListSerializer(required=False, child=serializers.UUIDField(required=True))
|
||||||
|
|
||||||
|
|||||||
@ -49,6 +49,49 @@ class ModelSerializer(serializers.Serializer):
|
|||||||
|
|
||||||
return [ModelSerializer.model_to_dict(model) for model in model_query_set.filter(**query_params)]
|
return [ModelSerializer.model_to_dict(model) for model in model_query_set.filter(**query_params)]
|
||||||
|
|
||||||
|
class Edit(serializers.Serializer):
|
||||||
|
user_id = serializers.CharField(required=False)
|
||||||
|
|
||||||
|
name = serializers.CharField(required=False)
|
||||||
|
|
||||||
|
model_type = serializers.CharField(required=False)
|
||||||
|
|
||||||
|
model_name = serializers.CharField(required=False)
|
||||||
|
|
||||||
|
credential = serializers.DictField(required=False)
|
||||||
|
|
||||||
|
def is_valid(self, model=None, raise_exception=False):
|
||||||
|
super().is_valid(raise_exception=True)
|
||||||
|
filter_params = {'user_id': self.data.get('user_id')}
|
||||||
|
if 'name' in self.data and self.data.get('name') is not None:
|
||||||
|
filter_params['name'] = self.data.get('name')
|
||||||
|
if QuerySet(Model).exclude(id=model.id).filter(**filter_params).exists():
|
||||||
|
raise AppApiException(500, f'模型名称【{self.data.get("name")}】已存在')
|
||||||
|
|
||||||
|
ModelSerializer.model_to_dict(model)
|
||||||
|
|
||||||
|
provider = model.provider
|
||||||
|
model_type = self.data.get('model_type')
|
||||||
|
model_name = self.data.get(
|
||||||
|
'model_name')
|
||||||
|
credential = self.data.get('credential')
|
||||||
|
|
||||||
|
model_credential = ModelProvideConstants[provider].value.get_model_credential(model_type,
|
||||||
|
model_name)
|
||||||
|
source_model_credential = json.loads(decrypt(model.credential))
|
||||||
|
source_encryption_model_credential = model_credential.encryption_dict(source_model_credential)
|
||||||
|
if credential is not None:
|
||||||
|
for k in source_encryption_model_credential.keys():
|
||||||
|
if credential[k] == source_encryption_model_credential[k]:
|
||||||
|
credential[k] = source_model_credential[k]
|
||||||
|
# 校验模型认证数据
|
||||||
|
model_credential.is_valid(
|
||||||
|
model_type,
|
||||||
|
model_name,
|
||||||
|
credential,
|
||||||
|
raise_exception=True)
|
||||||
|
return credential
|
||||||
|
|
||||||
class Create(serializers.Serializer):
|
class Create(serializers.Serializer):
|
||||||
user_id = serializers.CharField(required=True)
|
user_id = serializers.CharField(required=True)
|
||||||
|
|
||||||
@ -89,7 +132,7 @@ class ModelSerializer(serializers.Serializer):
|
|||||||
credential=encrypt(model_credential_str),
|
credential=encrypt(model_credential_str),
|
||||||
provider=provider, model_type=model_type, model_name=model_name)
|
provider=provider, model_type=model_type, model_name=model_name)
|
||||||
model.save()
|
model.save()
|
||||||
return ModelSerializer.Operate(data={'id': model.id}).one(user_id, with_valid=True)
|
return ModelSerializer.Operate(data={'id': model.id, 'user_id': user_id}).one(with_valid=True)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def model_to_dict(model: Model):
|
def model_to_dict(model: Model):
|
||||||
@ -103,12 +146,46 @@ class ModelSerializer(serializers.Serializer):
|
|||||||
class Operate(serializers.Serializer):
|
class Operate(serializers.Serializer):
|
||||||
id = serializers.UUIDField(required=True)
|
id = serializers.UUIDField(required=True)
|
||||||
|
|
||||||
def one(self, user_id, with_valid=False):
|
user_id = serializers.UUIDField(required=True)
|
||||||
|
|
||||||
|
def is_valid(self, *, raise_exception=False):
|
||||||
|
super().is_valid(raise_exception=True)
|
||||||
|
model = QuerySet(Model).filter(id=self.data.get("id"), user_id=self.data.get("user_id")).first()
|
||||||
|
if model is None:
|
||||||
|
raise AppApiException(500, '模型不存在')
|
||||||
|
|
||||||
|
def one(self, with_valid=False):
|
||||||
if with_valid:
|
if with_valid:
|
||||||
self.is_valid(raise_exception=True)
|
self.is_valid(raise_exception=True)
|
||||||
model = QuerySet(Model).get(id=self.data.get('id'), user_id=user_id)
|
model = QuerySet(Model).get(id=self.data.get('id'), user_id=self.data.get('user_id'))
|
||||||
return ModelSerializer.model_to_dict(model)
|
return ModelSerializer.model_to_dict(model)
|
||||||
|
|
||||||
|
def delete(self, with_valid=True):
|
||||||
|
if with_valid:
|
||||||
|
self.is_valid(raise_exception=True)
|
||||||
|
QuerySet(Model).filter(id=self.data.get('id')).delete()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def edit(self, instance: Dict, user_id: str, with_valid=True):
|
||||||
|
if with_valid:
|
||||||
|
self.is_valid(raise_exception=True)
|
||||||
|
model = QuerySet(Model).filter(id=self.data.get('id')).first()
|
||||||
|
|
||||||
|
if model is None:
|
||||||
|
raise AppApiException(500, '不存在的id')
|
||||||
|
else:
|
||||||
|
credential = ModelSerializer.Edit(data={**instance, 'user_id': user_id}).is_valid(model=model)
|
||||||
|
update_keys = ['credential', 'name', 'model_type', 'model_name']
|
||||||
|
for update_key in update_keys:
|
||||||
|
if update_key in instance and instance.get(update_key) is not None:
|
||||||
|
if update_key == 'credential':
|
||||||
|
model_credential_str = json.dumps(credential)
|
||||||
|
model.__setattr__(update_key, encrypt(model_credential_str))
|
||||||
|
else:
|
||||||
|
model.__setattr__(update_key, instance.get(update_key))
|
||||||
|
model.save()
|
||||||
|
return self.one(with_valid=False)
|
||||||
|
|
||||||
|
|
||||||
class ProviderSerializer(serializers.Serializer):
|
class ProviderSerializer(serializers.Serializer):
|
||||||
provider = serializers.CharField(required=True)
|
provider = serializers.CharField(required=True)
|
||||||
|
|||||||
@ -35,6 +35,30 @@ class ModelQueryApi(ApiMixin):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ModelEditApi(ApiMixin):
|
||||||
|
@staticmethod
|
||||||
|
def get_request_body_api():
|
||||||
|
return openapi.Schema(type=openapi.TYPE_OBJECT,
|
||||||
|
title="调用函数所需要的参数",
|
||||||
|
description="调用函数所需要的参数",
|
||||||
|
required=['provide', 'model_info'],
|
||||||
|
properties={
|
||||||
|
'name': openapi.Schema(type=openapi.TYPE_STRING,
|
||||||
|
title="模型名称",
|
||||||
|
description="模型名称"),
|
||||||
|
'model_type': openapi.Schema(type=openapi.TYPE_STRING,
|
||||||
|
title="供应商",
|
||||||
|
description="供应商"),
|
||||||
|
'model_name': openapi.Schema(type=openapi.TYPE_STRING,
|
||||||
|
title="供应商",
|
||||||
|
description="供应商"),
|
||||||
|
'credential': openapi.Schema(type=openapi.TYPE_OBJECT,
|
||||||
|
title="模型证书信息",
|
||||||
|
description="模型证书信息")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ModelCreateApi(ApiMixin):
|
class ModelCreateApi(ApiMixin):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
@ -15,5 +15,6 @@ urlpatterns = [
|
|||||||
path('provider/model_form', views.Provide.ModelForm.as_view(),
|
path('provider/model_form', views.Provide.ModelForm.as_view(),
|
||||||
name="provider/model_form"),
|
name="provider/model_form"),
|
||||||
path('model', views.Model.as_view(), name='model'),
|
path('model', views.Model.as_view(), name='model'),
|
||||||
|
path('model/<str:model_id>', views.Model.Operate.as_view(), name='model/operate')
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|||||||
@ -17,7 +17,7 @@ from common.response import result
|
|||||||
from common.util.common import query_params_to_single_dict
|
from common.util.common import query_params_to_single_dict
|
||||||
from setting.models_provider.constants.model_provider_constants import ModelProvideConstants
|
from setting.models_provider.constants.model_provider_constants import ModelProvideConstants
|
||||||
from setting.serializers.provider_serializers import ProviderSerializer, ModelSerializer
|
from setting.serializers.provider_serializers import ProviderSerializer, ModelSerializer
|
||||||
from setting.swagger_api.provide_api import ProvideApi, ModelCreateApi, ModelQueryApi
|
from setting.swagger_api.provide_api import ProvideApi, ModelCreateApi, ModelQueryApi, ModelEditApi
|
||||||
|
|
||||||
|
|
||||||
class Model(APIView):
|
class Model(APIView):
|
||||||
@ -46,9 +46,43 @@ class Model(APIView):
|
|||||||
data={**query_params_to_single_dict(request.query_params), 'user_id': request.user.id}).list(
|
data={**query_params_to_single_dict(request.query_params), 'user_id': request.user.id}).list(
|
||||||
with_valid=True))
|
with_valid=True))
|
||||||
|
|
||||||
|
class Operate(APIView):
|
||||||
|
authentication_classes = [TokenAuth]
|
||||||
|
|
||||||
|
@action(methods=['PUT'], detail=False)
|
||||||
|
@swagger_auto_schema(operation_summary="修改模型",
|
||||||
|
operation_id="修改模型",
|
||||||
|
request_body=ModelEditApi.get_request_body_api()
|
||||||
|
, tags=["模型"])
|
||||||
|
@has_permissions(PermissionConstants.MODEL_CREATE)
|
||||||
|
def put(self, request: Request, model_id: str):
|
||||||
|
return result.success(
|
||||||
|
ModelSerializer.Operate(data={'id': model_id, 'user_id': request.user.id}).edit(request.data,
|
||||||
|
str(request.user.id)))
|
||||||
|
|
||||||
|
@action(methods=['DELETE'], detail=False)
|
||||||
|
@swagger_auto_schema(operation_summary="删除模型",
|
||||||
|
operation_id="删除模型",
|
||||||
|
responses=result.get_default_response()
|
||||||
|
, tags=["模型"])
|
||||||
|
@has_permissions(PermissionConstants.MODEL_DELETE)
|
||||||
|
def delete(self, request: Request, model_id: str):
|
||||||
|
return result.success(
|
||||||
|
ModelSerializer.Operate(data={'id': model_id, 'user_id': request.user.id}).delete())
|
||||||
|
|
||||||
|
@action(methods=['GET'], detail=False)
|
||||||
|
@swagger_auto_schema(operation_summary="查询模型详细信息",
|
||||||
|
operation_id="查询模型详细信息",
|
||||||
|
tags=["模型"])
|
||||||
|
@has_permissions(PermissionConstants.MODEL_READ)
|
||||||
|
def get(self, request: Request, model_id: str):
|
||||||
|
return result.success(
|
||||||
|
ModelSerializer.Operate(data={'id': model_id, 'user_id': request.user.id}).one(with_valid=True))
|
||||||
|
|
||||||
|
|
||||||
class Provide(APIView):
|
class Provide(APIView):
|
||||||
authentication_classes = [TokenAuth]
|
authentication_classes = [TokenAuth]
|
||||||
|
|
||||||
class Exec(APIView):
|
class Exec(APIView):
|
||||||
authentication_classes = [TokenAuth]
|
authentication_classes = [TokenAuth]
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,8 @@ import type {
|
|||||||
ListModelRequest,
|
ListModelRequest,
|
||||||
Model,
|
Model,
|
||||||
BaseModel,
|
BaseModel,
|
||||||
CreateModelRequest
|
CreateModelRequest,
|
||||||
|
EditModelRequest
|
||||||
} from '@/api/type/model'
|
} from '@/api/type/model'
|
||||||
import type { FormField } from '@/components/dynamics-form/type'
|
import type { FormField } from '@/components/dynamics-form/type'
|
||||||
import type { KeyValue } from './type/common'
|
import type { KeyValue } from './type/common'
|
||||||
@ -84,11 +85,33 @@ const listBaseModel: (
|
|||||||
* @param loading 加载器
|
* @param loading 加载器
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const createModel: (request: CreateModelRequest, loading?: Ref<boolean>) => Promise<Model> = (
|
const createModel: (
|
||||||
request,
|
request: CreateModelRequest,
|
||||||
|
loading?: Ref<boolean>
|
||||||
|
) => Promise<Result<Model>> = (request, loading) => {
|
||||||
|
return post(`${prefix}`, request, {}, loading)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改模型
|
||||||
|
* @param request 請求對象
|
||||||
|
* @param loading 加載器
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const updateModel: (
|
||||||
|
model_id: string,
|
||||||
|
request: EditModelRequest,
|
||||||
|
loading?: Ref<boolean>
|
||||||
|
) => Promise<Result<Model>> = (model_id, request, loading) => {
|
||||||
|
console.log(request)
|
||||||
|
return put(`${prefix}/${model_id}`, request, {}, loading)
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteModel: (model_id: string, loading?: Ref<boolean>) => Promise<Result<boolean>> = (
|
||||||
|
model_id,
|
||||||
loading
|
loading
|
||||||
) => {
|
) => {
|
||||||
return post(`${prefix}`, request, {}, loading)
|
return del(`${prefix}/${model_id}`, {}, loading)
|
||||||
}
|
}
|
||||||
export default {
|
export default {
|
||||||
getModel,
|
getModel,
|
||||||
@ -96,5 +119,7 @@ export default {
|
|||||||
getModelCreateForm,
|
getModelCreateForm,
|
||||||
listModelType,
|
listModelType,
|
||||||
listBaseModel,
|
listBaseModel,
|
||||||
createModel
|
createModel,
|
||||||
|
updateModel,
|
||||||
|
deleteModel
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,7 +43,7 @@ interface Model {
|
|||||||
/**
|
/**
|
||||||
* 主键id
|
* 主键id
|
||||||
*/
|
*/
|
||||||
id: String
|
id: string
|
||||||
/**
|
/**
|
||||||
* 模型名
|
* 模型名
|
||||||
*/
|
*/
|
||||||
@ -88,6 +88,25 @@ interface CreateModelRequest {
|
|||||||
provider: string
|
provider: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface EditModelRequest {
|
||||||
|
/**
|
||||||
|
* 模型名
|
||||||
|
*/
|
||||||
|
name: string
|
||||||
|
/**
|
||||||
|
* 模型类型
|
||||||
|
*/
|
||||||
|
model_type: string
|
||||||
|
/**
|
||||||
|
* 基础模型
|
||||||
|
*/
|
||||||
|
model_name: string
|
||||||
|
/**
|
||||||
|
* 认证信息
|
||||||
|
*/
|
||||||
|
credential: any
|
||||||
|
}
|
||||||
|
|
||||||
interface BaseModel {
|
interface BaseModel {
|
||||||
/**
|
/**
|
||||||
* 基础模型名称
|
* 基础模型名称
|
||||||
@ -102,4 +121,12 @@ interface BaseModel {
|
|||||||
*/
|
*/
|
||||||
model_type: string
|
model_type: string
|
||||||
}
|
}
|
||||||
export type { modelRequest, Provider, ListModelRequest, Model, BaseModel, CreateModelRequest }
|
export type {
|
||||||
|
modelRequest,
|
||||||
|
Provider,
|
||||||
|
ListModelRequest,
|
||||||
|
Model,
|
||||||
|
BaseModel,
|
||||||
|
CreateModelRequest,
|
||||||
|
EditModelRequest
|
||||||
|
}
|
||||||
|
|||||||
@ -104,9 +104,13 @@ const change = (field: FormField, value: any) => {
|
|||||||
formValue.value[field.field] = value
|
formValue.value[field.field] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(formValue.value, () => {
|
watch(
|
||||||
emit('update:modelValue', formValue.value)
|
formValue,
|
||||||
})
|
() => {
|
||||||
|
emit('update:modelValue', formValue.value)
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 触发器,用户获取子表单 或者 下拉选项
|
* 触发器,用户获取子表单 或者 下拉选项
|
||||||
@ -150,10 +154,13 @@ const initDefaultData = (formField: FormField) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
render(props.render_data)
|
render(props.render_data, {})
|
||||||
})
|
})
|
||||||
|
|
||||||
const render = (render_data: string | Array<FormField> | Promise<Result<Array<FormField>>>) => {
|
const render = (
|
||||||
|
render_data: string | Array<FormField> | Promise<Result<Array<FormField>>>,
|
||||||
|
data?: Dict<any>
|
||||||
|
) => {
|
||||||
if (typeof render_data == 'string') {
|
if (typeof render_data == 'string') {
|
||||||
triggerApi.get(render_data, {}, loading).then((ok) => {
|
triggerApi.get(render_data, {}, loading).then((ok) => {
|
||||||
formFieldList.value = ok.data
|
formFieldList.value = ok.data
|
||||||
@ -165,6 +172,10 @@ const render = (render_data: string | Array<FormField> | Promise<Result<Array<Fo
|
|||||||
formFieldList.value = ok.data
|
formFieldList.value = ok.data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if (data) {
|
||||||
|
console.log(data)
|
||||||
|
formValue.value = data
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 校验函数
|
* 校验函数
|
||||||
|
|||||||
@ -12,8 +12,8 @@ import AppTable from './app-table/index.vue'
|
|||||||
import ReadWrite from './read-write/index.vue'
|
import ReadWrite from './read-write/index.vue'
|
||||||
import TagEllipsis from './tag-ellipsis/index.vue'
|
import TagEllipsis from './tag-ellipsis/index.vue'
|
||||||
import CommonList from './common-list/index.vue'
|
import CommonList from './common-list/index.vue'
|
||||||
import dynamicsForm from './dynamics-form/index.vue'
|
|
||||||
import MarkdownRenderer from './markdown-renderer/index.vue'
|
import MarkdownRenderer from './markdown-renderer/index.vue'
|
||||||
|
import dynamicsForm from './dynamics-form'
|
||||||
export default {
|
export default {
|
||||||
install(app: App) {
|
install(app: App) {
|
||||||
app.component(AppIcon.name, AppIcon)
|
app.component(AppIcon.name, AppIcon)
|
||||||
@ -29,7 +29,7 @@ export default {
|
|||||||
app.component(ReadWrite.name, ReadWrite)
|
app.component(ReadWrite.name, ReadWrite)
|
||||||
app.component(TagEllipsis.name, TagEllipsis)
|
app.component(TagEllipsis.name, TagEllipsis)
|
||||||
app.component(CommonList.name, CommonList)
|
app.component(CommonList.name, CommonList)
|
||||||
app.component(dynamicsForm.name, dynamicsForm)
|
app.use(dynamicsForm)
|
||||||
app.component(MarkdownRenderer.name, MarkdownRenderer)
|
app.component(MarkdownRenderer.name, MarkdownRenderer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-loading="loading"
|
|
||||||
v-model="dialogVisible"
|
v-model="dialogVisible"
|
||||||
width="600px"
|
width="600px"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
@ -72,7 +71,7 @@
|
|||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="close">取消</el-button>
|
<el-button @click="close">取消</el-button>
|
||||||
<el-button type="primary" @click="submit"> 添加 </el-button>
|
<el-button type="primary" @click="submit" :loading="loading"> 添加 </el-button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@ -116,7 +115,12 @@ const credential_form_data = ref<Dict<any>>({})
|
|||||||
|
|
||||||
const form_data = computed({
|
const form_data = computed({
|
||||||
get: () => {
|
get: () => {
|
||||||
return { ...base_form_data.value, ...credential_form_data.value }
|
return {
|
||||||
|
...credential_form_data.value,
|
||||||
|
name: base_form_data.value.name,
|
||||||
|
model_type: base_form_data.value.model_type,
|
||||||
|
model_name: base_form_data.value.model_name
|
||||||
|
}
|
||||||
},
|
},
|
||||||
set: (event: any) => {
|
set: (event: any) => {
|
||||||
credential_form_data.value = event
|
credential_form_data.value = event
|
||||||
@ -132,7 +136,7 @@ const getModelForm = (model_name: string) => {
|
|||||||
).then((ok) => {
|
).then((ok) => {
|
||||||
model_form_field.value = ok.data
|
model_form_field.value = ok.data
|
||||||
// 渲染动态表单
|
// 渲染动态表单
|
||||||
dynamicsFormRef.value?.render(model_form_field.value)
|
dynamicsFormRef.value?.render(model_form_field.value, undefined)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,6 +175,7 @@ const submit = () => {
|
|||||||
},
|
},
|
||||||
loading
|
loading
|
||||||
).then((ok) => {
|
).then((ok) => {
|
||||||
|
close()
|
||||||
MsgSuccess('创建模型成功')
|
MsgSuccess('创建模型成功')
|
||||||
emit('submit')
|
emit('submit')
|
||||||
})
|
})
|
||||||
|
|||||||
211
ui/src/views/template/component/EditModel.vue
Normal file
211
ui/src/views/template/component/EditModel.vue
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
v-model="dialogVisible"
|
||||||
|
width="600px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:close-on-press-escape="false"
|
||||||
|
:destroy-on-close="true"
|
||||||
|
:before-close="close"
|
||||||
|
>
|
||||||
|
<template #header="{ close, titleId, titleClass }">
|
||||||
|
<el-breadcrumb separator=">">
|
||||||
|
<el-breadcrumb-item
|
||||||
|
><span class="active-breadcrumb">{{
|
||||||
|
`修改 ${providerValue?.name} 模型`
|
||||||
|
}}</span></el-breadcrumb-item
|
||||||
|
>
|
||||||
|
</el-breadcrumb>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<DynamicsForm
|
||||||
|
v-model="form_data"
|
||||||
|
:render_data="model_form_field"
|
||||||
|
:model="form_data"
|
||||||
|
ref="dynamicsFormRef"
|
||||||
|
>
|
||||||
|
<template #default>
|
||||||
|
<el-form-item label="模型名称" prop="name" :rules="base_form_data_rule.name">
|
||||||
|
<el-input v-model="base_form_data.name" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="模型类型" prop="model_type" :rules="base_form_data_rule.model_type">
|
||||||
|
<el-select
|
||||||
|
v-loading="model_type_loading"
|
||||||
|
@change="list_base_model($event)"
|
||||||
|
style="width: 100%"
|
||||||
|
v-model="base_form_data.model_type"
|
||||||
|
class="m-2"
|
||||||
|
placeholder="请选择模型类型"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in model_type_list"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.key"
|
||||||
|
:value="item.value"
|
||||||
|
></el-option
|
||||||
|
></el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="基础模型" prop="model_name" :rules="base_form_data_rule.model_name">
|
||||||
|
<el-select
|
||||||
|
@change="getModelForm($event)"
|
||||||
|
v-loading="base_model_loading"
|
||||||
|
style="width: 100%"
|
||||||
|
v-model="base_form_data.model_name"
|
||||||
|
class="m-2"
|
||||||
|
placeholder="请选择模型类型"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in base_model_list"
|
||||||
|
:key="item.name"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.name"
|
||||||
|
></el-option
|
||||||
|
></el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</DynamicsForm>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="close">取消</el-button>
|
||||||
|
<el-button type="primary" @click="submit" :loading="loading"> 修改 </el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed } from 'vue'
|
||||||
|
import type { Provider, BaseModel, Model } from '@/api/type/model'
|
||||||
|
import type { Dict, KeyValue } from '@/api/type/common'
|
||||||
|
import ModelApi from '@/api/model'
|
||||||
|
import type { FormField } from '@/components/dynamics-form/type'
|
||||||
|
import DynamicsForm from '@/components/dynamics-form/index.vue'
|
||||||
|
import type { FormRules } from 'element-plus'
|
||||||
|
import { MsgSuccess } from '@/utils/message'
|
||||||
|
const providerValue = ref<Provider>()
|
||||||
|
const dynamicsFormRef = ref<InstanceType<typeof DynamicsForm>>()
|
||||||
|
const emit = defineEmits(['change', 'submit'])
|
||||||
|
const loading = ref<boolean>(false)
|
||||||
|
const model_type_loading = ref<boolean>(false)
|
||||||
|
const base_model_loading = ref<boolean>(false)
|
||||||
|
const model_type_list = ref<Array<KeyValue<string, string>>>([])
|
||||||
|
const modelValue = ref<Model>()
|
||||||
|
const base_model_list = ref<Array<BaseModel>>([])
|
||||||
|
const model_form_field = ref<Array<FormField>>([])
|
||||||
|
const dialogVisible = ref<boolean>(false)
|
||||||
|
|
||||||
|
const base_form_data_rule = ref<FormRules>({
|
||||||
|
name: { required: true, trigger: 'blur', message: '模型名不能为空' },
|
||||||
|
model_type: { required: true, trigger: 'change', message: '模型类型不能为空' },
|
||||||
|
model_name: { required: true, trigger: 'change', message: '基础模型不能为空' }
|
||||||
|
})
|
||||||
|
|
||||||
|
const base_form_data = ref<{
|
||||||
|
name: string
|
||||||
|
|
||||||
|
model_type: string
|
||||||
|
|
||||||
|
model_name: string
|
||||||
|
}>({ name: '', model_type: '', model_name: '' })
|
||||||
|
|
||||||
|
const credential_form_data = ref<Dict<any>>({})
|
||||||
|
|
||||||
|
const form_data = computed({
|
||||||
|
get: () => {
|
||||||
|
return { ...credential_form_data.value, ...base_form_data.value }
|
||||||
|
},
|
||||||
|
set: (event: any) => {
|
||||||
|
credential_form_data.value = event
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const getModelForm = (model_name: string) => {
|
||||||
|
if (providerValue.value) {
|
||||||
|
ModelApi.getModelCreateForm(
|
||||||
|
providerValue.value.provider,
|
||||||
|
form_data.value.model_type,
|
||||||
|
model_name
|
||||||
|
).then((ok) => {
|
||||||
|
model_form_field.value = ok.data
|
||||||
|
if (modelValue.value) {
|
||||||
|
console.log(modelValue.value.credential)
|
||||||
|
// 渲染动态表单
|
||||||
|
dynamicsFormRef.value?.render(model_form_field.value, modelValue.value.credential)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const list_base_model = (model_type: any) => {
|
||||||
|
if (providerValue.value) {
|
||||||
|
ModelApi.listBaseModel(providerValue.value.provider, model_type, base_model_loading).then(
|
||||||
|
(ok) => {
|
||||||
|
base_model_list.value = ok.data
|
||||||
|
if (!base_model_list.value.some((item) => item.name === form_data.value.model_name)) {
|
||||||
|
form_data.value.model_name = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const open = (provider: Provider, model: Model) => {
|
||||||
|
modelValue.value = model
|
||||||
|
ModelApi.listModelType(model.provider, model_type_loading).then((ok) => {
|
||||||
|
model_type_list.value = ok.data
|
||||||
|
list_base_model(model.model_type)
|
||||||
|
})
|
||||||
|
|
||||||
|
providerValue.value = provider
|
||||||
|
|
||||||
|
base_form_data.value = {
|
||||||
|
name: model.name,
|
||||||
|
model_type: model.model_type,
|
||||||
|
model_name: model.model_name
|
||||||
|
}
|
||||||
|
form_data.value = model.credential
|
||||||
|
getModelForm(model.model_name)
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
base_form_data.value = { name: '', model_type: '', model_name: '' }
|
||||||
|
credential_form_data.value = {}
|
||||||
|
dialogVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const submit = () => {
|
||||||
|
dynamicsFormRef.value?.validate().then(() => {
|
||||||
|
if (modelValue.value) {
|
||||||
|
ModelApi.updateModel(
|
||||||
|
modelValue.value.id,
|
||||||
|
{
|
||||||
|
...base_form_data.value,
|
||||||
|
credential: credential_form_data.value
|
||||||
|
},
|
||||||
|
loading
|
||||||
|
).then((ok) => {
|
||||||
|
MsgSuccess('修改模型成功')
|
||||||
|
close()
|
||||||
|
emit('submit')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ open, close })
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.select-provider {
|
||||||
|
font-size: 16px;
|
||||||
|
color: rgba(100, 106, 115, 1);
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.active-breadcrumb {
|
||||||
|
font-size: 16px;
|
||||||
|
color: rgba(31, 35, 41, 1);
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -28,16 +28,50 @@
|
|||||||
>
|
>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</template>
|
</template>
|
||||||
|
<template #mouseEnter>
|
||||||
|
<el-tooltip effect="dark" content="修改" placement="top">
|
||||||
|
<el-button text @click.stop="openEditModel" class="edit-button">
|
||||||
|
<el-icon><Edit /></el-icon> </el-button
|
||||||
|
></el-tooltip>
|
||||||
|
<el-tooltip effect="dark" content="删除" placement="top">
|
||||||
|
<el-button text @click.stop="deleteModel" class="delete-button">
|
||||||
|
<el-icon><Delete /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
<EditModel ref="eidtModelRef" @submit="emit('change')"></EditModel>
|
||||||
</card-box>
|
</card-box>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { Provider, Model } from '@/api/type/model'
|
import type { Provider, Model } from '@/api/type/model'
|
||||||
import { computed } from 'vue'
|
import ModelApi from '@/api/model'
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
|
import EditModel from '@/views/template/component/EditModel.vue'
|
||||||
|
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
model: Model
|
model: Model
|
||||||
provider_list: Array<Provider>
|
provider_list: Array<Provider>
|
||||||
}>()
|
}>()
|
||||||
|
const emit = defineEmits(['change'])
|
||||||
|
const eidtModelRef = ref<InstanceType<typeof EditModel>>()
|
||||||
|
const deleteModel = () => {
|
||||||
|
MsgConfirm(`删除模型 `, `是否删除模型:${props.model.name} ?`, {
|
||||||
|
confirmButtonText: '删除',
|
||||||
|
confirmButtonClass: 'danger'
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
ModelApi.deleteModel(props.model.id).then(() => {
|
||||||
|
emit('change')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
}
|
||||||
|
const openEditModel = () => {
|
||||||
|
const provider = props.provider_list.find((p) => p.provider === props.model.provider)
|
||||||
|
if (provider) {
|
||||||
|
eidtModelRef.value?.open(provider, props.model)
|
||||||
|
}
|
||||||
|
}
|
||||||
const icon = computed(() => {
|
const icon = computed(() => {
|
||||||
return props.provider_list.find((p) => p.provider === props.model.provider)?.icon
|
return props.provider_list.find((p) => p.provider === props.model.provider)?.icon
|
||||||
})
|
})
|
||||||
@ -47,4 +81,16 @@ const icon = computed(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
.delete-button {
|
||||||
|
position: absolute;
|
||||||
|
right: 12px;
|
||||||
|
top: 18px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.edit-button {
|
||||||
|
position: absolute;
|
||||||
|
right: 30px;
|
||||||
|
top: 18px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -43,16 +43,14 @@
|
|||||||
|
|
||||||
<el-row :gutter="15" v-for="row in model_split_list">
|
<el-row :gutter="15" v-for="row in model_split_list">
|
||||||
<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" class="mt-8" v-for="model in row">
|
<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" class="mt-8" v-for="model in row">
|
||||||
<ModelVue :model="model" :provider_list="provider_list"> </ModelVue>
|
<ModelVue @change="list_model" :model="model" :provider_list="provider_list">
|
||||||
|
</ModelVue>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<CreateModel
|
<CreateModel ref="createModelRef" @submit="list_model"></CreateModel>
|
||||||
ref="createModelRef"
|
|
||||||
@submit="list_model"
|
|
||||||
@change="openCreateModel()"
|
|
||||||
></CreateModel>
|
|
||||||
<SelectProvider ref="selectProviderRef" @change="openCreateModel($event)"></SelectProvider>
|
<SelectProvider ref="selectProviderRef" @change="openCreateModel($event)"></SelectProvider>
|
||||||
</LayoutContainer>
|
</LayoutContainer>
|
||||||
</template>
|
</template>
|
||||||
@ -61,6 +59,7 @@
|
|||||||
import { onMounted, ref, computed, watch } from 'vue'
|
import { onMounted, ref, computed, watch } from 'vue'
|
||||||
import ModelApi from '@/api/model'
|
import ModelApi from '@/api/model'
|
||||||
import type { Provider, Model } from '@/api/type/model'
|
import type { Provider, Model } from '@/api/type/model'
|
||||||
|
|
||||||
import AppIcon from '@/components/icons/AppIcon.vue'
|
import AppIcon from '@/components/icons/AppIcon.vue'
|
||||||
import ModelVue from '@/views/template/component/Model.vue'
|
import ModelVue from '@/views/template/component/Model.vue'
|
||||||
import { splitArray } from '@/utils/common'
|
import { splitArray } from '@/utils/common'
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user