feat: 模型列表
This commit is contained in:
parent
a1acfdc2be
commit
367e92c414
@ -73,11 +73,8 @@ const postChatOpen: (data: ApplicationFormType) => Promise<Result<any>> = (data)
|
|||||||
"message": "string",
|
"message": "string",
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
const postChatMessage: (chat_id: string, message: string) => Promise<Result<any>> = (
|
const postChatMessage: (chat_id: string, message: string) => Promise<any> = (chat_id, message) => {
|
||||||
chat_id,
|
return postStream(`/api/${prefix}/chat_message/${chat_id}`, { message })
|
||||||
message
|
|
||||||
) => {
|
|
||||||
return postStream(`${prefix}/chat_message/${chat_id}`, { message })
|
|
||||||
}
|
}
|
||||||
export default {
|
export default {
|
||||||
getAllAppilcation,
|
getAllAppilcation,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { Result } from '@/request/Result'
|
import { Result } from '@/request/Result'
|
||||||
import { get, post, del, put } from '@/request/index'
|
import { get, post, del, put } from '@/request/index'
|
||||||
import { type Ref } from 'vue'
|
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 = '/model'
|
||||||
const prefix_provider = '/provider'
|
const prefix_provider = '/provider'
|
||||||
|
|
||||||
@ -9,9 +9,13 @@ const prefix_provider = '/provider'
|
|||||||
* 获得模型列表
|
* 获得模型列表
|
||||||
* @params 参数 name, model_type, model_name
|
* @params 参数 name, model_type, model_name
|
||||||
*/
|
*/
|
||||||
const getModel: (data?: modelRequest) => Promise<Result<any>> = (data) => {
|
const getModel: (
|
||||||
return get(`${prefix}`, data)
|
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 {
|
interface modelRequest {
|
||||||
name: string
|
name: string
|
||||||
model_type: string
|
model_type: string
|
||||||
@ -19,4 +20,49 @@ interface Provider {
|
|||||||
icon: string
|
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) {
|
function chatMessage(chatId: string) {
|
||||||
applicationApi
|
applicationApi.postChatMessage(chatId, inputValue.value).then(async (response) => {
|
||||||
.postChatMessage(chatId, inputValue.value)
|
const reader = response.body.getReader()
|
||||||
.then((response) => {
|
while (true) {
|
||||||
console.log(response.data)
|
const { done, value } = await reader.read()
|
||||||
response.data.on('data', (chunk) => {
|
if (done) {
|
||||||
console.log(chunk)
|
loading.value = false
|
||||||
// 处理流数据的逻辑
|
break
|
||||||
})
|
}
|
||||||
|
const decoder = new TextDecoder('utf-8')
|
||||||
// response.data.on('end', () => {
|
const str = decoder.decode(value, { stream: true })
|
||||||
// // 数据接收完成的逻辑
|
console.log('value', JSON.parse(str.replace('data:', '')))
|
||||||
// })
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
|
||||||
loading.value = false
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -3,9 +3,10 @@
|
|||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<slot name="header">
|
<slot name="header">
|
||||||
<div class="title flex align-center">
|
<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="" />
|
<img src="@/assets/icon_document.svg" style="width: 58%" alt="" />
|
||||||
</AppAvatar>
|
</AppAvatar>
|
||||||
|
<slot v-else name="icon"> </slot>
|
||||||
<h4 class="ellipsis-1">{{ title }}</h4>
|
<h4 class="ellipsis-1">{{ title }}</h4>
|
||||||
</div>
|
</div>
|
||||||
</slot>
|
</slot>
|
||||||
@ -23,22 +24,27 @@
|
|||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch } from 'vue'
|
import { ref, useSlots } from 'vue'
|
||||||
|
|
||||||
|
const slots = useSlots()
|
||||||
defineOptions({ name: 'CardBox' })
|
defineOptions({ name: 'CardBox' })
|
||||||
const props = defineProps({
|
const props = withDefaults(
|
||||||
title: {
|
defineProps<{
|
||||||
type: String,
|
/**
|
||||||
default: '标题'
|
* 标题
|
||||||
},
|
*/
|
||||||
description: {
|
title?: string
|
||||||
type: String,
|
/**
|
||||||
default: ''
|
* 描述
|
||||||
},
|
*/
|
||||||
showIcon: {
|
description?: string
|
||||||
type: Boolean,
|
/**
|
||||||
default: true
|
* 是否展示icon
|
||||||
}
|
*/
|
||||||
})
|
showIcon?: boolean
|
||||||
|
}>(),
|
||||||
|
{ title: '标题', description: '', showIcon: true }
|
||||||
|
)
|
||||||
|
|
||||||
const show = ref(false)
|
const show = ref(false)
|
||||||
function cardEnter() {
|
function cardEnter() {
|
||||||
|
|||||||
@ -2,10 +2,18 @@
|
|||||||
<div class="common-list">
|
<div class="common-list">
|
||||||
<el-scrollbar>
|
<el-scrollbar>
|
||||||
<ul v-if="data.length > 0">
|
<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">
|
<template v-for="(item, index) in data" :key="index">
|
||||||
<li
|
<li
|
||||||
@click.prevent="clickHandle(item, index)"
|
@click.prevent="clickHandle(item)"
|
||||||
:class="current === index ? 'active' : ''"
|
:class="modelValue === item ? 'active' : ''"
|
||||||
class="cursor"
|
class="cursor"
|
||||||
>
|
>
|
||||||
<slot :row="item" :index="index"> </slot>
|
<slot :row="item" :index="index"> </slot>
|
||||||
@ -17,22 +25,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch } from 'vue'
|
import { ref, watch, useSlots } from 'vue'
|
||||||
|
|
||||||
|
const slots = useSlots()
|
||||||
defineOptions({ name: 'CommonList' })
|
defineOptions({ name: 'CommonList' })
|
||||||
const props = defineProps({
|
|
||||||
data: {
|
withDefaults(
|
||||||
type: Array<any>,
|
defineProps<{
|
||||||
default: () => []
|
modelValue?: any
|
||||||
|
|
||||||
|
data: Array<any>
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
data: () => []
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
|
|
||||||
const emit = defineEmits(['click'])
|
const emit = defineEmits(['click', 'update:modelValue'])
|
||||||
|
|
||||||
const current = ref(0)
|
function clickHandle(row?: any) {
|
||||||
|
|
||||||
function clickHandle(row: any, index: number) {
|
|
||||||
current.value = index
|
|
||||||
emit('click', row)
|
emit('click', row)
|
||||||
|
emit('update:modelValue', row)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<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(
|
instance.interceptors.response.use(
|
||||||
(response: any) => {
|
(response: any) => {
|
||||||
|
console.log('instance_response', response)
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
if (response.status !== 200 && !(response.data instanceof Blob)) {
|
if (response.status !== 200 && !(response.data instanceof Blob)) {
|
||||||
MsgError(response.data.message)
|
MsgError(response.data.message)
|
||||||
@ -163,13 +164,27 @@ export const del: (
|
|||||||
return promise(request({ url: url, method: 'delete', params, data }), loading)
|
return promise(request({ url: url, method: 'delete', params, data }), loading)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const postStream: (
|
/**
|
||||||
url: string,
|
* 流处理
|
||||||
data?: unknown,
|
* @param url url地址
|
||||||
params?: unknown,
|
* @param data 请求body
|
||||||
loading?: NProgress | Ref<boolean>
|
* @returns
|
||||||
) => Promise<Result<any> | any> = (url, data, params, loading) => {
|
*/
|
||||||
return request({ url: url, method: 'post', data, params, responseType: 'stream' })
|
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: (
|
export const exportExcel: (
|
||||||
|
|||||||
@ -3,7 +3,22 @@
|
|||||||
<div class="template-manage flex main-calc-height">
|
<div class="template-manage flex main-calc-height">
|
||||||
<div class="template-manage__left p-8 border-r">
|
<div class="template-manage__left p-8 border-r">
|
||||||
<h4 class="p-16">供应商</h4>
|
<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 }">
|
<template #default="{ row }">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<span :innerHTML="row.icon" alt="" style="height: 24px; width: 24px" class="mr-8" />
|
<span :innerHTML="row.icon" alt="" style="height: 24px; width: 24px" class="mr-8" />
|
||||||
@ -14,7 +29,22 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="template-manage__right p-24">
|
<div class="template-manage__right p-24">
|
||||||
<h4>全部模型</h4>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</LayoutContainer>
|
</LayoutContainer>
|
||||||
@ -23,16 +53,33 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref, reactive, watch } from 'vue'
|
import { onMounted, ref, reactive, watch } from 'vue'
|
||||||
import ModelApi from '@/api/model'
|
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 loading = ref<boolean>(false)
|
||||||
|
|
||||||
|
const active_provider = ref<Provider>()
|
||||||
|
|
||||||
const provider_list = ref<Array<Provider>>([])
|
const provider_list = ref<Array<Provider>>([])
|
||||||
|
const get_model_icon = (model: Model) => {
|
||||||
function clickHandle(row: any) {}
|
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(() => {
|
onMounted(() => {
|
||||||
ModelApi.getProvider(loading).then((ok) => {
|
ModelApi.getProvider(loading).then((ok) => {
|
||||||
provider_list.value = ok.data
|
provider_list.value = [...ok.data]
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user