模型列表换接口

This commit is contained in:
WangHui 2026-10-20 18:07:06 +08:00
parent 0ee332fcb6
commit f940890f3a
9 changed files with 115 additions and 75 deletions

View File

@ -1,5 +1,49 @@
import { get, getApiBaseURL, post } from '../utlis/request'
import type { TextToTextParams } from '@/types/model'
import type {
AiModelItem,
AiModelType,
AllModelResponse,
Model,
TextToTextParams,
} from '@/types/model'
// 获取可用模型列表原始接口 (model_type: all/t2i/t2v/i2v)
export const getAiModelsRaw = (params?: { model_type?: AiModelType }): Promise<{ code: number; message: string; data: AiModelItem[] | null }> =>
get('/v2/ai/models', params)
/**
* 兼容旧 AllModel 返回结构的模型列表获取
* - 将新接口 /v2/ai/models 的返回适配为 { status, data: Model[] }
* - 现有页面逻辑(input_fields、价格、参数构造)无需改动
*/
export const getAiModels = async (modelType: AiModelType): Promise<AllModelResponse> => {
const res = await getAiModelsRaw({ model_type: modelType })
const list: Model[] = Array.isArray(res?.data)
? res.data.map((item): Model => ({
id: String(item.id ?? item.model ?? ''),
name: String(item.name ?? item.model ?? ''),
model: String(item.model ?? item.name ?? ''),
description: String(item.description ?? ''),
llmcatelogid: String(item.llmcatelogid ?? modelType),
iconid: String(item.iconid ?? ''),
upappid: String(item.upappid ?? ''),
apiname: String(item.apiname ?? item.model ?? ''),
providerid: String(item.providerid ?? ''),
ownerid: String(item.ownerid ?? ''),
enabled_date: String(item.enabled_date ?? ''),
expired_date: String(item.expired_date ?? ''),
query_apiname: String(item.query_apiname ?? ''),
query_period: Number(item.query_period ?? 0),
ppid: String(item.ppid ?? ''),
input_fields: Array.isArray(item.input_fields) ? (item.input_fields as Model['input_fields']) : [],
}))
: []
return {
status: res?.code === 0 ? 'ok' : 'error',
data: list,
}
}
// 文生视频
export const textvideo = <T,D>(data:D):Promise<T> =>post('/llmage/vidu_inference.dspy',data)

View File

@ -136,9 +136,8 @@
</template>
<script setup lang="ts">
import { AllModel, queryModelPrice, texttoimage } from '@/apis/Model';
import { getAiModels, queryModelPrice, texttoimage } from '@/apis/Model';
import type {
AllModelResponse,
InputField,
Model,
PriceQueryParams,
@ -247,15 +246,10 @@ const onModelChange = () => {
};
const loadImageToImageModels = async () => {
interface ModelParams {
llmcatelogid: string;
}
modelLoading.value = true;
try {
const res = await AllModel<AllModelResponse, ModelParams>({
llmcatelogid: 'i2i',
});
// 图生图在新接口中归入 t2i 类型
const res = await getAiModels('t2i');
if (res.status === 'ok' && res.data?.length) {
models.value = res.data;

View File

@ -148,9 +148,8 @@
</template>
<script setup lang="ts">
import { AllModel, queryModelPrice, texttoimage } from '@/apis/Model';
import { getAiModels, queryModelPrice, texttoimage } from '@/apis/Model';
import type {
AllModelResponse,
InputField,
Model,
PriceQueryParams,
@ -264,15 +263,10 @@ const onModelChange = () => {
};
const loadReferenceImageModels = async () => {
interface ModelParams {
llmcatelogid: string;
}
modelLoading.value = true;
try {
const res = await AllModel<AllModelResponse, ModelParams>({
llmcatelogid: 'ref2i',
});
// 参考生图在新接口中归入 t2i 类型
const res = await getAiModels('t2i');
if (res.status === 'ok' && res.data?.length) {
models.value = res.data;

View File

@ -116,9 +116,8 @@
</template>
<script setup lang="ts">
import { AllModel, queryModelPrice, texttoimage } from '@/apis/Model';
import { getAiModels, queryModelPrice, texttoimage } from '@/apis/Model';
import type {
AllModelResponse,
InputField,
Model,
PriceQueryParams,
@ -223,15 +222,9 @@ const isQuantityName = (name: string) => {
}
const loadTextToImageModels = async () => {
interface ModelParams {
llmcatelogid: string;
}
modelLoading.value = true;
try {
const res = await AllModel<AllModelResponse, ModelParams>({
llmcatelogid: 't2i',
});
const res = await getAiModels('t2i');
if (res.status === 'ok' && res.data?.length) {
models.value = res.data;

View File

@ -239,14 +239,12 @@ import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue';
import { ElMessage } from 'element-plus';
import { Delete, Plus, ZoomIn } from '@element-plus/icons-vue';
import type { UploadFile } from 'element-plus';
import { imagetovideo, AllModel, queryModelPrice } from '../../apis/Model';
import { imagetovideo, getAiModels, queryModelPrice } from '../../apis/Model';
import type {
Model,
AllModelResponse,
PriceQueryParams,
PriceQueryResponse,
TextVideoResponse,
ModelParams,
} from '../../types/model';
// ==================== 组件事件定义 ====================
@ -582,8 +580,7 @@ const checkRequiredFields = (): boolean => {
const loadModels = async () => {
modelLoading.value = true;
try {
const params: ModelParams = { llmcatelogid: 'i2v' };
const res = await AllModel<AllModelResponse, ModelParams>(params);
const res = await getAiModels('i2v');
if (res.status === 'ok' && Array.isArray(res.data)) {
models.value = res.data;
if (models.value.length > 0) {

View File

@ -325,12 +325,10 @@
import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue';
import { ElMessage } from 'element-plus';
import { Delete, ZoomIn } from '@element-plus/icons-vue';
import { referencevideo, AllModel, queryModelPrice } from '../../apis/Model';
import { referencevideo, getAiModels, queryModelPrice } from '../../apis/Model';
import type {
AllModelResponse,
InputField,
Model,
ModelParams,
PriceQueryParams,
PriceQueryResponse,
TextVideoResponse,
@ -700,23 +698,19 @@ const fetchPrice = () => {
}, 500);
};
// 加载模型列表:
// 优先尝试“参考生视频”,如果没有,再兼容回退“图生视频”
// 加载模型列表
// 参考生视频在新接口中归入 i2v 类型
const loadModels = async () => {
const candidateTypes: ModelParams['llmcatelogid'][] = ['r2v'];
modelLoading.value = true;
try {
for (const llmcatelogid of candidateTypes) {
const res = await AllModel<AllModelResponse, ModelParams>({ llmcatelogid });
if (res.status === 'ok' && Array.isArray(res.data) && res.data.length > 0) {
models.value = res.data.map(normalizeModel);
currentModelId.value = models.value[0].id;
currentModel.value = models.value[0];
initFormData();
fetchPrice();
return;
}
const res = await getAiModels('i2v');
if (res.status === 'ok' && Array.isArray(res.data) && res.data.length > 0) {
models.value = res.data.map(normalizeModel);
currentModelId.value = models.value[0].id;
currentModel.value = models.value[0];
initFormData();
fetchPrice();
return;
}
ElMessage.error('获取模型列表失败');

View File

@ -201,15 +201,13 @@
<script setup lang="ts">
import { ref, computed, onMounted, onBeforeUnmount, watch } from 'vue';
import { ElMessage } from 'element-plus';
import { textvideo, AllModel, queryModelPrice } from '../../apis/Model';
import { textvideo, getAiModels, queryModelPrice } from '../../apis/Model';
import type {
Model,
AllModelResponse,
PriceQueryParams,
PriceQueryResponse,
TextVideoParams,
TextVideoResponse,
ModelParams,
} from '../../types/model';
// ==================== 事件定义 ====================
@ -478,13 +476,9 @@ const fetchPrice = () => {
// ==================== 模型加载 ====================
const loadModels = async () => {
const Props = {
llmcatelogid:'t2v'
}
modelLoading.value = true;
try {
const res = await AllModel<AllModelResponse,ModelParams>(Props);
const res = await getAiModels('t2v');
if (res.status === 'ok' && Array.isArray(res.data)) {
models.value = res.data;
if (models.value.length > 0) {

View File

@ -38,7 +38,7 @@ export interface ModelResult{
};
export interface Model {
type: string;
type?: string;
}
@ -307,3 +307,36 @@ export interface HistoryRecordParams {
pageSize: number;
llmcatelogid: string;
}
/**
* 可用模型查询类型: all/t2i/t2v/i2v
*/
export type AiModelType = 'all' | 't2i' | 't2v' | 'i2v'
/**
* 获取可用模型列表请求参数
*/
export interface AiModelsParams {
model_type?: AiModelType;
}
/**
* 可用模型项(具体字段以后端返回为准)
*/
export interface AiModelItem {
id?: string;
name?: string;
model?: string;
model_type?: string;
description?: string;
[key: string]: unknown;
}
/**
* 获取可用模型列表响应
*/
export interface AiModelsResponse {
code: number;
message: string;
data: AiModelItem[] | null;
}

View File

@ -101,10 +101,10 @@
<script setup lang="ts">
import { AllModel, textToTextStream } from '@/apis/Model';
import { getAiModels, textToTextStream } from '@/apis/Model';
import LoginPrompt from '@/components/LoginPrompt/LoginPrompt.vue';
import { useLoginStore } from '@/store/LoginStore';
import type { AllModelResponse, TextToTextParams } from '@/types/model';
import type { TextToTextParams } from '@/types/model';
import { ElMessage } from 'element-plus';
import { computed, nextTick, onMounted, ref, watch } from 'vue';
@ -137,22 +137,19 @@ const promptExamples = [
// 获取模型
type AiModelType = 'all' | 't2i' | 't2v' | 'i2v';
const getModel = async () => {
interface ModelParams {
llmcatelogid: string;
// 文生文在新接口中暂无对应类型,使用 'all' 获取全部模型
const modelType: AiModelType = 'all';
const res = await getAiModels(modelType);
if (res.status === 'ok' && res.data?.length) {
modelOptions.value = res.data.map((item) => ({
label: item.model || item.name,
value: item.model,
}));
selectedModel.value = modelOptions.value[0]?.value || selectedModel.value;
}
const Props: ModelParams = {
llmcatelogid:'t2t'
}
const res = await AllModel<AllModelResponse, ModelParams>(Props);
if(res.status === 'ok' && res.data?.length) {
modelOptions.value = res.data.map((item) => ({
label: item.model || item.name,
value: item.model,
}));
selectedModel.value = modelOptions.value[0]?.value || selectedModel.value;
}
}
}
onMounted(() => {
getModel();