feat: ✨ 新增用户模型查询
This commit is contained in:
parent
3ab287536c
commit
4b39bbb2a5
7
src/api/model/index.ts
Normal file
7
src/api/model/index.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import type { GetSessionListVO } from './types';
|
||||||
|
import { get } from '@/utils/request';
|
||||||
|
|
||||||
|
// 获取当前用户的模型列表
|
||||||
|
export function getModelList() {
|
||||||
|
return get<GetSessionListVO[]>('/system/model/modelList');
|
||||||
|
}
|
||||||
14
src/api/model/types.ts
Normal file
14
src/api/model/types.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// 查询用户模型列表返回的数据结构
|
||||||
|
export interface GetSessionListVO {
|
||||||
|
id?: number;
|
||||||
|
category?: string;
|
||||||
|
modelName?: string;
|
||||||
|
modelDescribe?: string;
|
||||||
|
modelPrice?: number;
|
||||||
|
modelType?: string;
|
||||||
|
modelShow?: string;
|
||||||
|
systemPrompt?: string;
|
||||||
|
apiHost?: string;
|
||||||
|
apiKey?: string;
|
||||||
|
remark?: string;
|
||||||
|
}
|
||||||
1
src/assets/icons/svg/models.svg
Normal file
1
src/assets/icons/svg/models.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1748367817456" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10388" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M800 1008V720l224-112v288zM576 576l192-96 32-16 192 96-224 112z m-32-304l224-112v256L544 528V272zM288 112L512 0l224 112-224 112z m192 416L256 416V160l224 112v256z m-256 480L0 896V608l224 112v288z m32 16h-0.352 0.672z m0-352L32 560l192-96 32 16 192 96z m224 240l-192 96V720l192-96v288z m256 96l-192-96V624l192 96v288z m32 16h-0.352 0.672z" p-id="10389"></path></svg>
|
||||||
|
After Width: | Height: | Size: 699 B |
116
src/components/ModelSelect/index.vue
Normal file
116
src/components/ModelSelect/index.vue
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
<!-- 切换模型 -->
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { GetSessionListVO } from '@/api/model/types';
|
||||||
|
import Popover from '@/components/Popover/index.vue';
|
||||||
|
import SvgIcon from '@/components/SvgIcon/index.vue';
|
||||||
|
import { useModelStore } from '@/stores/modules/model';
|
||||||
|
|
||||||
|
const modelStore = useModelStore();
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await modelStore.requestModelList();
|
||||||
|
// 设置默认模型
|
||||||
|
if (
|
||||||
|
modelStore.modelList.length > 0
|
||||||
|
&& (!modelStore.currentModelInfo || !modelStore.currentModelInfo.modelName)
|
||||||
|
) {
|
||||||
|
modelStore.setCurrentModelInfo(modelStore.modelList[0]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const currentModelName = computed(
|
||||||
|
() => modelStore.currentModelInfo && modelStore.currentModelInfo.modelName,
|
||||||
|
);
|
||||||
|
const popoverList = computed(() => modelStore.modelList);
|
||||||
|
|
||||||
|
/* 弹出面板 开始 */
|
||||||
|
const popoverStyle = ref({
|
||||||
|
width: '200px',
|
||||||
|
padding: '4px',
|
||||||
|
height: 'fit-content',
|
||||||
|
});
|
||||||
|
const popoverRef = ref();
|
||||||
|
|
||||||
|
// 显示
|
||||||
|
async function showPopover() {
|
||||||
|
// 获取最新的模型列表
|
||||||
|
await modelStore.requestModelList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击
|
||||||
|
function handleClick(item: GetSessionListVO) {
|
||||||
|
modelStore.setCurrentModelInfo(item);
|
||||||
|
popoverRef.value.hide();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="model-switch">
|
||||||
|
<Popover
|
||||||
|
ref="popoverRef"
|
||||||
|
position="top-start"
|
||||||
|
:offset="[-14, 14]"
|
||||||
|
:trigger-style="{ cursor: 'pointer' }"
|
||||||
|
popover-class="popover-content"
|
||||||
|
:popover-style="popoverStyle"
|
||||||
|
@show="showPopover"
|
||||||
|
>
|
||||||
|
<!-- 触发元素插槽 -->
|
||||||
|
<template #trigger>
|
||||||
|
<div
|
||||||
|
class="model-switch-box select-none flex items-center gap-4px px-10px py-8px rounded-15px cursor-pointer font-size-12px"
|
||||||
|
>
|
||||||
|
<div class="model-switch-box-icon">
|
||||||
|
<SvgIcon name="models" size="12" />
|
||||||
|
</div>
|
||||||
|
<div class="model-switch-box-text font-size-12px">
|
||||||
|
{{ currentModelName }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="popover-content-box">
|
||||||
|
<div v-for="item in popoverList" :key="item.id" class="popover-content-box-items h-full">
|
||||||
|
<el-tooltip
|
||||||
|
popper-class="rounded-tooltip"
|
||||||
|
effect="dark"
|
||||||
|
placement="right"
|
||||||
|
trigger="hover"
|
||||||
|
:offset="10"
|
||||||
|
:show-arrow="false"
|
||||||
|
>
|
||||||
|
<template #content>
|
||||||
|
<div class="popover-content-box-item-text text-wrap max-w-200px rounded-lg">
|
||||||
|
{{ item.remark }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div
|
||||||
|
class="popover-content-box-item select-none transition-all transition-duration-300 flex items-center h-full gap-8px p-8px pl-10px pr-12px rounded-lg hover:cursor-pointer hover:bg-[rgba(0,0,0,.04)]"
|
||||||
|
:class="{ 'bg-[rgba(0,0,0,.04)] is-select': item.modelName === currentModelName }"
|
||||||
|
@click="handleClick(item)"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="popover-content-box-item-text font-size-12px text-overflow max-h-120px line-height-snug"
|
||||||
|
>
|
||||||
|
{{ item.modelName }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Popover>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.model-switch-box {
|
||||||
|
color: var(--el-color-primary, #409eff);
|
||||||
|
border: 1px solid var(--el-color-primary, #409eff);
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover-content-box-item.is-select {
|
||||||
|
color: var(--el-color-primary, #409eff);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,5 +1,6 @@
|
|||||||
<!-- 默认消息列表页 -->
|
<!-- 默认消息列表页 -->
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import ModelSelect from '@/components/ModelSelect/index.vue';
|
||||||
import WelecomeText from '@/components/WelecomeText/index.vue';
|
import WelecomeText from '@/components/WelecomeText/index.vue';
|
||||||
import { useUserStore } from '@/stores';
|
import { useUserStore } from '@/stores';
|
||||||
import { useChatStore } from '@/stores/modules/chat';
|
import { useChatStore } from '@/stores/modules/chat';
|
||||||
@ -45,6 +46,8 @@ function setIsDeepThinking() {
|
|||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<div class="flex-1 flex items-center gap-8px flex-none w-fit overflow-hidden">
|
<div class="flex-1 flex items-center gap-8px flex-none w-fit overflow-hidden">
|
||||||
|
<ModelSelect />
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="flex items-center gap-4px px-12px py-8px rounded-15px cursor-pointer font-size-12px border-1px border-gray border-solid hover:bg-[rgba(0,0,0,.04)]"
|
class="flex items-center gap-4px px-12px py-8px rounded-15px cursor-pointer font-size-12px border-1px border-gray border-solid hover:bg-[rgba(0,0,0,.04)]"
|
||||||
>
|
>
|
||||||
|
|||||||
35
src/stores/modules/model.ts
Normal file
35
src/stores/modules/model.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import type { GetSessionListVO } from '@/api/model/types';
|
||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { getModelList } from '@/api/model/index';
|
||||||
|
|
||||||
|
// 模型管理
|
||||||
|
export const useModelStore = defineStore('model', () => {
|
||||||
|
// 当前模型
|
||||||
|
const currentModelInfo = ref<GetSessionListVO>({});
|
||||||
|
|
||||||
|
// 设置当前模型
|
||||||
|
const setCurrentModelInfo = (modelInfo: GetSessionListVO) => {
|
||||||
|
currentModelInfo.value = modelInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 模型菜单列表
|
||||||
|
const modelList = ref<GetSessionListVO[]>([]);
|
||||||
|
// 请求模型菜单列表
|
||||||
|
const requestModelList = async () => {
|
||||||
|
try {
|
||||||
|
const res = await getModelList();
|
||||||
|
modelList.value = res.data;
|
||||||
|
console.log('模型列表', res.data);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error('requestModelList错误', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
currentModelInfo,
|
||||||
|
setCurrentModelInfo,
|
||||||
|
modelList,
|
||||||
|
requestModelList,
|
||||||
|
};
|
||||||
|
});
|
||||||
@ -19,3 +19,11 @@
|
|||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rounded-tooltip
|
||||||
|
.rounded-tooltip {
|
||||||
|
border-radius: 10px !important;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: fit-content;
|
||||||
|
}
|
||||||
|
|||||||
4
types/components.d.ts
vendored
4
types/components.d.ts
vendored
@ -3,7 +3,7 @@
|
|||||||
// Generated by unplugin-vue-components
|
// Generated by unplugin-vue-components
|
||||||
// Read more: https://github.com/vuejs/core/pull/3399
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
// biome-ignore lint: disable
|
// biome-ignore lint: disable
|
||||||
export {}
|
export {};
|
||||||
|
|
||||||
/* prettier-ignore */
|
/* prettier-ignore */
|
||||||
declare module 'vue' {
|
declare module 'vue' {
|
||||||
@ -21,8 +21,10 @@ declare module 'vue' {
|
|||||||
ElImage: typeof import('element-plus/es')['ElImage']
|
ElImage: typeof import('element-plus/es')['ElImage']
|
||||||
ElInput: typeof import('element-plus/es')['ElInput']
|
ElInput: typeof import('element-plus/es')['ElInput']
|
||||||
ElMain: typeof import('element-plus/es')['ElMain']
|
ElMain: typeof import('element-plus/es')['ElMain']
|
||||||
|
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
||||||
IconSelect: typeof import('./../src/components/IconSelect/index.vue')['default']
|
IconSelect: typeof import('./../src/components/IconSelect/index.vue')['default']
|
||||||
LoginDialog: typeof import('./../src/components/LoginDialog/index.vue')['default']
|
LoginDialog: typeof import('./../src/components/LoginDialog/index.vue')['default']
|
||||||
|
ModelSelect: typeof import('./../src/components/ModelSelect/index.vue')['default']
|
||||||
Popover: typeof import('./../src/components/Popover/index.vue')['default']
|
Popover: typeof import('./../src/components/Popover/index.vue')['default']
|
||||||
QrCodeLogin: typeof import('./../src/components/LoginDialog/components/QrCodeLogin/index.vue')['default']
|
QrCodeLogin: typeof import('./../src/components/LoginDialog/components/QrCodeLogin/index.vue')['default']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user