mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
feat: 模型列表
This commit is contained in:
parent
a1acfdc2be
commit
367e92c414
|
|
@ -73,11 +73,8 @@ const postChatOpen: (data: ApplicationFormType) => Promise<Result<any>> = (data)
|
|||
"message": "string",
|
||||
}
|
||||
*/
|
||||
const postChatMessage: (chat_id: string, message: string) => Promise<Result<any>> = (
|
||||
chat_id,
|
||||
message
|
||||
) => {
|
||||
return postStream(`${prefix}/chat_message/${chat_id}`, { message })
|
||||
const postChatMessage: (chat_id: string, message: string) => Promise<any> = (chat_id, message) => {
|
||||
return postStream(`/api/${prefix}/chat_message/${chat_id}`, { message })
|
||||
}
|
||||
export default {
|
||||
getAllAppilcation,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Result } from '@/request/Result'
|
||||
import { get, post, del, put } from '@/request/index'
|
||||
import { type Ref } from 'vue'
|
||||
import type { modelRequest, Provider } from '@/api/type/model'
|
||||
import type { modelRequest, Provider, ListModelRequest, Model } from '@/api/type/model'
|
||||
const prefix = '/model'
|
||||
const prefix_provider = '/provider'
|
||||
|
||||
|
|
@ -9,9 +9,13 @@ const prefix_provider = '/provider'
|
|||
* 获得模型列表
|
||||
* @params 参数 name, model_type, model_name
|
||||
*/
|
||||
const getModel: (data?: modelRequest) => Promise<Result<any>> = (data) => {
|
||||
return get(`${prefix}`, data)
|
||||
const getModel: (
|
||||
request: ListModelRequest,
|
||||
loading?: Ref<boolean>
|
||||
) => Promise<Result<Array<Model>>> = (data, loading) => {
|
||||
return get(`${prefix}`, data, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得供应商列表
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { store } from '@/stores'
|
||||
interface modelRequest {
|
||||
name: string
|
||||
model_type: string
|
||||
|
|
@ -19,4 +20,49 @@ interface Provider {
|
|||
icon: string
|
||||
}
|
||||
|
||||
export type { modelRequest, Provider }
|
||||
interface ListModelRequest {
|
||||
/**
|
||||
* 模型名称
|
||||
*/
|
||||
name?: string
|
||||
/**
|
||||
* 模型类型
|
||||
*/
|
||||
model_type?: string
|
||||
/**
|
||||
* 基础模型名称
|
||||
*/
|
||||
model_name?: string
|
||||
/**
|
||||
* 供应商
|
||||
*/
|
||||
provider?: string
|
||||
}
|
||||
|
||||
interface Model {
|
||||
/**
|
||||
* 主键id
|
||||
*/
|
||||
id: String
|
||||
/**
|
||||
* 模型名
|
||||
*/
|
||||
name: string
|
||||
/**
|
||||
* 模型类型
|
||||
*/
|
||||
model_type: string
|
||||
/**
|
||||
* 基础模型
|
||||
*/
|
||||
model_name: string
|
||||
/**
|
||||
* 认证信息
|
||||
*/
|
||||
credential: any
|
||||
/**
|
||||
* 供应商
|
||||
*/
|
||||
provider: string
|
||||
}
|
||||
export type { modelRequest, Provider, ListModelRequest, Model }
|
||||
|
|
|
|||
|
|
@ -128,22 +128,19 @@ function chatHandle() {
|
|||
}
|
||||
|
||||
function chatMessage(chatId: string) {
|
||||
applicationApi
|
||||
.postChatMessage(chatId, inputValue.value)
|
||||
.then((response) => {
|
||||
console.log(response.data)
|
||||
response.data.on('data', (chunk) => {
|
||||
console.log(chunk)
|
||||
// 处理流数据的逻辑
|
||||
})
|
||||
|
||||
// response.data.on('end', () => {
|
||||
// // 数据接收完成的逻辑
|
||||
// })
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
applicationApi.postChatMessage(chatId, inputValue.value).then(async (response) => {
|
||||
const reader = response.body.getReader()
|
||||
while (true) {
|
||||
const { done, value } = await reader.read()
|
||||
if (done) {
|
||||
loading.value = false
|
||||
break
|
||||
}
|
||||
const decoder = new TextDecoder('utf-8')
|
||||
const str = decoder.decode(value, { stream: true })
|
||||
console.log('value', JSON.parse(str.replace('data:', '')))
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@
|
|||
<div class="card-header">
|
||||
<slot name="header">
|
||||
<div class="title flex align-center">
|
||||
<AppAvatar class="mr-12" shape="square" :size="32" v-if="showIcon">
|
||||
<AppAvatar v-if="!slots.icon && showIcon" class="mr-12" shape="square" :size="32">
|
||||
<img src="@/assets/icon_document.svg" style="width: 58%" alt="" />
|
||||
</AppAvatar>
|
||||
<slot v-else name="icon"> </slot>
|
||||
<h4 class="ellipsis-1">{{ title }}</h4>
|
||||
</div>
|
||||
</slot>
|
||||
|
|
@ -23,22 +24,27 @@
|
|||
</el-card>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { ref, useSlots } from 'vue'
|
||||
|
||||
const slots = useSlots()
|
||||
defineOptions({ name: 'CardBox' })
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: '标题'
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
showIcon: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
})
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
title?: string
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
description?: string
|
||||
/**
|
||||
* 是否展示icon
|
||||
*/
|
||||
showIcon?: boolean
|
||||
}>(),
|
||||
{ title: '标题', description: '', showIcon: true }
|
||||
)
|
||||
|
||||
const show = ref(false)
|
||||
function cardEnter() {
|
||||
|
|
|
|||
|
|
@ -2,10 +2,18 @@
|
|||
<div class="common-list">
|
||||
<el-scrollbar>
|
||||
<ul v-if="data.length > 0">
|
||||
<li
|
||||
v-if="slots.prefix"
|
||||
@click="clickHandle()"
|
||||
:class="modelValue === undefined || modelValue === null ? 'active' : ''"
|
||||
class="cursor"
|
||||
>
|
||||
<slot name="prefix"> </slot>
|
||||
</li>
|
||||
<template v-for="(item, index) in data" :key="index">
|
||||
<li
|
||||
@click.prevent="clickHandle(item, index)"
|
||||
:class="current === index ? 'active' : ''"
|
||||
@click.prevent="clickHandle(item)"
|
||||
:class="modelValue === item ? 'active' : ''"
|
||||
class="cursor"
|
||||
>
|
||||
<slot :row="item" :index="index"> </slot>
|
||||
|
|
@ -17,22 +25,27 @@
|
|||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { ref, watch, useSlots } from 'vue'
|
||||
|
||||
const slots = useSlots()
|
||||
defineOptions({ name: 'CommonList' })
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array<any>,
|
||||
default: () => []
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
modelValue?: any
|
||||
|
||||
data: Array<any>
|
||||
}>(),
|
||||
{
|
||||
data: () => []
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
const emit = defineEmits(['click'])
|
||||
const emit = defineEmits(['click', 'update:modelValue'])
|
||||
|
||||
const current = ref(0)
|
||||
|
||||
function clickHandle(row: any, index: number) {
|
||||
current.value = index
|
||||
function clickHandle(row?: any) {
|
||||
emit('click', row)
|
||||
emit('update:modelValue', row)
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
|||
|
|
@ -242,5 +242,71 @@ export const iconMap: any = {
|
|||
)
|
||||
])
|
||||
}
|
||||
},
|
||||
'app-all-menu': {
|
||||
iconReader: () => {
|
||||
return h('i', [
|
||||
h(
|
||||
'svg',
|
||||
{
|
||||
style: { height: '100%', width: '100%' },
|
||||
viewBox: '0 0 20 20',
|
||||
version: '1.1',
|
||||
xmlns: 'http://www.w3.org/2000/svg'
|
||||
},
|
||||
[
|
||||
h('path', {
|
||||
d: 'M2.91683 2.0835H8.3335C8.79373 2.0835 9.16683 2.45659 9.16683 2.91683V8.3335C9.16683 8.79373 8.79373 9.16683 8.3335 9.16683H2.91683C2.45659 9.16683 2.0835 8.79373 2.0835 8.3335V2.91683C2.0835 2.45659 2.45659 2.0835 2.91683 2.0835ZM3.75016 3.75016V7.50016H7.50016V3.75016H3.75016Z',
|
||||
fill: 'currentColor'
|
||||
}),
|
||||
h('path', {
|
||||
d: 'M2.91683 10.8335H8.3335C8.79373 10.8335 9.16683 11.2066 9.16683 11.6668V17.0835C9.16683 17.5437 8.79373 17.9168 8.3335 17.9168H2.91683C2.45659 17.9168 2.0835 17.5437 2.0835 17.0835V11.6668C2.0835 11.2066 2.45659 10.8335 2.91683 10.8335ZM3.75016 16.2502H7.50016V12.5002H3.75016V16.2502Z',
|
||||
fill: 'currentColor'
|
||||
}),
|
||||
h('path', {
|
||||
d: 'M11.6668 2.0835H17.0835C17.5437 2.0835 17.9168 2.45659 17.9168 2.91683V8.3335C17.9168 8.79373 17.5437 9.16683 17.0835 9.16683H11.6668C11.2066 9.16683 10.8335 8.79373 10.8335 8.3335V2.91683C10.8335 2.45659 11.2066 2.0835 11.6668 2.0835ZM12.5002 7.50016H16.2502V3.75016H12.5002V7.50016Z',
|
||||
fill: 'currentColor'
|
||||
}),
|
||||
h('path', {
|
||||
d: 'M11.6668 10.8335H17.0835C17.5437 10.8335 17.9168 11.2066 17.9168 11.6668V17.0835C17.9168 17.5437 17.5437 17.9168 17.0835 17.9168H11.6668C11.2066 17.9168 10.8335 17.5437 10.8335 17.0835V11.6668C10.8335 11.2066 11.2066 10.8335 11.6668 10.8335ZM12.5002 12.5002V16.2502H16.2502V12.5002H12.5002Z',
|
||||
fill: 'currentColor'
|
||||
})
|
||||
]
|
||||
)
|
||||
])
|
||||
}
|
||||
},
|
||||
'app-all-menu-active': {
|
||||
iconReader: () => {
|
||||
return h('i', [
|
||||
h(
|
||||
'svg',
|
||||
{
|
||||
style: { height: '100%', width: '100%' },
|
||||
viewBox: '0 0 20 20',
|
||||
version: '1.1',
|
||||
xmlns: 'http://www.w3.org/2000/svg'
|
||||
},
|
||||
[
|
||||
h('path', {
|
||||
d: 'M8.33317 1.6665H2.49984C2.0396 1.6665 1.6665 2.0396 1.6665 2.49984V8.33317C1.6665 8.79341 2.0396 9.1665 2.49984 9.1665H8.33317C8.79341 9.1665 9.1665 8.79341 9.1665 8.33317V2.49984C9.1665 2.0396 8.79341 1.6665 8.33317 1.6665Z',
|
||||
fill: 'currentColor'
|
||||
}),
|
||||
h('path', {
|
||||
d: 'M8.33317 10.8332H2.49984C2.0396 10.8332 1.6665 11.2063 1.6665 11.6665V17.4998C1.6665 17.9601 2.0396 18.3332 2.49984 18.3332H8.33317C8.79341 18.3332 9.1665 17.9601 9.1665 17.4998V11.6665C9.1665 11.2063 8.79341 10.8332 8.33317 10.8332Z',
|
||||
fill: 'currentColor'
|
||||
}),
|
||||
h('path', {
|
||||
d: 'M17.4998 1.6665H11.6665C11.2063 1.6665 10.8332 2.0396 10.8332 2.49984V8.33317C10.8332 8.79341 11.2063 9.1665 11.6665 9.1665H17.4998C17.9601 9.1665 18.3332 8.79341 18.3332 8.33317V2.49984C18.3332 2.0396 17.9601 1.6665 17.4998 1.6665Z',
|
||||
fill: 'currentColor'
|
||||
}),
|
||||
h('path', {
|
||||
d: 'M17.4508 10.8332H11.7155C11.2282 10.8332 10.8332 11.2282 10.8332 11.7155V17.4508C10.8332 17.9381 11.2282 18.3332 11.7155 18.3332H17.4508C17.9381 18.3332 18.3332 17.9381 18.3332 17.4508V11.7155C18.3332 11.2282 17.9381 10.8332 17.4508 10.8332Z',
|
||||
fill: 'currentColor'
|
||||
})
|
||||
]
|
||||
)
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ instance.interceptors.request.use(
|
|||
//设置响应拦截器
|
||||
instance.interceptors.response.use(
|
||||
(response: any) => {
|
||||
console.log('instance_response', response)
|
||||
if (response.data) {
|
||||
if (response.status !== 200 && !(response.data instanceof Blob)) {
|
||||
MsgError(response.data.message)
|
||||
|
|
@ -163,13 +164,27 @@ export const del: (
|
|||
return promise(request({ url: url, method: 'delete', params, data }), loading)
|
||||
}
|
||||
|
||||
export const postStream: (
|
||||
url: string,
|
||||
data?: unknown,
|
||||
params?: unknown,
|
||||
loading?: NProgress | Ref<boolean>
|
||||
) => Promise<Result<any> | any> = (url, data, params, loading) => {
|
||||
return request({ url: url, method: 'post', data, params, responseType: 'stream' })
|
||||
/**
|
||||
* 流处理
|
||||
* @param url url地址
|
||||
* @param data 请求body
|
||||
* @returns
|
||||
*/
|
||||
export const postStream: (url: string, data?: unknown) => Promise<Result<any> | any> = (
|
||||
url,
|
||||
data
|
||||
) => {
|
||||
const { user } = useStore()
|
||||
const token = user.getToken()
|
||||
const headers: HeadersInit = { 'Content-Type': 'application/json' }
|
||||
if (token) {
|
||||
headers['AUTHORIZATION'] = `${token}`
|
||||
}
|
||||
return fetch(url, {
|
||||
method: 'POST',
|
||||
body: data ? JSON.stringify(data) : undefined,
|
||||
headers: headers
|
||||
})
|
||||
}
|
||||
|
||||
export const exportExcel: (
|
||||
|
|
|
|||
|
|
@ -3,7 +3,22 @@
|
|||
<div class="template-manage flex main-calc-height">
|
||||
<div class="template-manage__left p-8 border-r">
|
||||
<h4 class="p-16">供应商</h4>
|
||||
<common-list :data="provider_list" class="mt-8" v-loading="loading" @click="clickHandle">
|
||||
<common-list
|
||||
v-model="active_provider"
|
||||
:data="provider_list"
|
||||
class="mt-8"
|
||||
v-loading="loading"
|
||||
>
|
||||
<template #prefix>
|
||||
<div class="flex">
|
||||
<AppIcon
|
||||
style="height: 24px; width: 24px"
|
||||
class="mr-8"
|
||||
:iconName="active_provider ? 'app-all-menu' : 'app-all-menu-active'"
|
||||
></AppIcon>
|
||||
<span>全部模型</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<div class="flex">
|
||||
<span :innerHTML="row.icon" alt="" style="height: 24px; width: 24px" class="mr-8" />
|
||||
|
|
@ -14,7 +29,22 @@
|
|||
</div>
|
||||
<div class="template-manage__right p-24">
|
||||
<h4>全部模型</h4>
|
||||
<Demo></Demo>
|
||||
<card-box :title="model.name" v-for="model in model_list">
|
||||
<template #icon>
|
||||
<AppAvatar
|
||||
class="mr-12"
|
||||
shape="square"
|
||||
style="--el-avatar-bg-color: rgba(255, 255, 255, 0)"
|
||||
:size="32"
|
||||
>
|
||||
<span style="height: 24px; width: 24px" :innerHTML="get_model_icon(model)"></span
|
||||
></AppAvatar>
|
||||
</template>
|
||||
<template #description>
|
||||
{{ model.model_type }}
|
||||
{{ model.model_name }}
|
||||
</template>
|
||||
</card-box>
|
||||
</div>
|
||||
</div>
|
||||
</LayoutContainer>
|
||||
|
|
@ -23,16 +53,33 @@
|
|||
<script lang="ts" setup>
|
||||
import { onMounted, ref, reactive, watch } from 'vue'
|
||||
import ModelApi from '@/api/model'
|
||||
import type { Provider } from '@/api/type/model'
|
||||
import type { Provider, Model } from '@/api/type/model'
|
||||
import AppIcon from '@/components/icons/AppIcon.vue'
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
const active_provider = ref<Provider>()
|
||||
|
||||
const provider_list = ref<Array<Provider>>([])
|
||||
|
||||
function clickHandle(row: any) {}
|
||||
|
||||
const get_model_icon = (model: Model) => {
|
||||
return provider_list.value.find((p) => p.provider === model.provider)?.icon
|
||||
}
|
||||
const model_list = ref<Array<Model>>([])
|
||||
watch(
|
||||
active_provider,
|
||||
() => {
|
||||
ModelApi.getModel(
|
||||
active_provider.value ? { provider: active_provider.value.provider } : {}
|
||||
).then((ok) => {
|
||||
model_list.value = ok.data
|
||||
})
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
)
|
||||
onMounted(() => {
|
||||
ModelApi.getProvider(loading).then((ok) => {
|
||||
provider_list.value = ok.data
|
||||
provider_list.value = [...ok.data]
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Reference in New Issue