|
@ -20,7 +20,7 @@ const currentCate = ref("all"); |
|
|
|
|
|
|
|
|
const showDetail = ref(false); |
|
|
const showDetail = ref(false); |
|
|
const detailModel = ref("") |
|
|
const detailModel = ref("") |
|
|
let downloadAbort:any = {}; |
|
|
let downloadAbort: any = {}; |
|
|
onMounted(async () => { |
|
|
onMounted(async () => { |
|
|
await modelStore.getList(); |
|
|
await modelStore.getList(); |
|
|
}); |
|
|
}); |
|
@ -31,10 +31,10 @@ async function showCate(name: any) { |
|
|
async function showSearch() { |
|
|
async function showSearch() { |
|
|
await modelStore.getLabelSearch(searchKey.value); |
|
|
await modelStore.getLabelSearch(searchKey.value); |
|
|
} |
|
|
} |
|
|
function downAddUpdate(val:any) { |
|
|
function downAddUpdate(val: any) { |
|
|
downAdd.value = val; |
|
|
downAdd.value = val; |
|
|
} |
|
|
} |
|
|
async function downLabel(modelData:any, labelData:any) { |
|
|
async function downLabel(modelData: any, labelData: any) { |
|
|
labelData = toRaw(labelData); |
|
|
labelData = toRaw(labelData); |
|
|
modelData = toRaw(modelData); |
|
|
modelData = toRaw(modelData); |
|
|
//console.log(modelData, labelData) |
|
|
//console.log(modelData, labelData) |
|
@ -61,7 +61,7 @@ async function saveBox(modelData: any) { |
|
|
} |
|
|
} |
|
|
downLabel(modelData, labelData); |
|
|
downLabel(modelData, labelData); |
|
|
} |
|
|
} |
|
|
async function download(saveData:any) { |
|
|
async function download(saveData: any) { |
|
|
saveData = toRaw(saveData); |
|
|
saveData = toRaw(saveData); |
|
|
saveData.info = toRaw(saveData.info); |
|
|
saveData.info = toRaw(saveData.info); |
|
|
//saveData.url = toRaw(saveData.url); |
|
|
//saveData.url = toRaw(saveData.url); |
|
@ -74,7 +74,7 @@ async function download(saveData:any) { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
//console.log(saveData); |
|
|
//console.log(saveData); |
|
|
const downUrl = config.apiUrl + "/ai/download"; |
|
|
const downUrl = config.aiUrl + "/ai/download"; |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
const completion = await fetch(downUrl, { |
|
|
const completion = await fetch(downUrl, { |
|
@ -92,7 +92,7 @@ async function download(saveData:any) { |
|
|
saveData.progress = 0; |
|
|
saveData.progress = 0; |
|
|
modelStore.addDownload(saveData); |
|
|
modelStore.addDownload(saveData); |
|
|
await handleDown(saveData, completion); |
|
|
await handleDown(saveData, completion); |
|
|
} catch (error:any) { |
|
|
} catch (error: any) { |
|
|
notifyError(error.message); |
|
|
notifyError(error.message); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -104,7 +104,7 @@ function cancelDownload(model: string) { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
async function handleDown(modelData:any, completion:any) { |
|
|
async function handleDown(modelData: any, completion: any) { |
|
|
const reader: any = completion.body?.getReader(); |
|
|
const reader: any = completion.body?.getReader(); |
|
|
if (!reader) { |
|
|
if (!reader) { |
|
|
notifyError(t("common.cantStream")); |
|
|
notifyError(t("common.cantStream")); |
|
@ -125,7 +125,7 @@ async function handleDown(modelData:any, completion:any) { |
|
|
//console.log(rawjson); |
|
|
//console.log(rawjson); |
|
|
const msg = modelStore.parseMsg(rawjson); |
|
|
const msg = modelStore.parseMsg(rawjson); |
|
|
//console.log(msg) |
|
|
//console.log(msg) |
|
|
if(msg.message && msg.code) { |
|
|
if (msg.message && msg.code) { |
|
|
notifyError(msg.message); |
|
|
notifyError(msg.message); |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
@ -135,9 +135,9 @@ async function handleDown(modelData:any, completion:any) { |
|
|
modelData.status = msg.status; |
|
|
modelData.status = msg.status; |
|
|
|
|
|
|
|
|
if (msg.total && msg.completed && msg.total > 0) { |
|
|
if (msg.total && msg.completed && msg.total > 0) { |
|
|
if(msg.total == msg.completed){ |
|
|
if (msg.total == msg.completed) { |
|
|
msg.status = "success" |
|
|
msg.status = "success" |
|
|
}else{ |
|
|
} else { |
|
|
modelData.isLoading = 1; |
|
|
modelData.isLoading = 1; |
|
|
modelData.progress = Math.ceil((msg.completed / msg.total) * 100); |
|
|
modelData.progress = Math.ceil((msg.completed / msg.total) * 100); |
|
|
} |
|
|
} |
|
@ -171,7 +171,7 @@ async function deleteModel(modelData: any) { |
|
|
method: "POST", |
|
|
method: "POST", |
|
|
body: JSON.stringify(modelData.info), |
|
|
body: JSON.stringify(modelData.info), |
|
|
}; |
|
|
}; |
|
|
const delUrl = config.apiUrl + "/ai/delete"; |
|
|
const delUrl = config.aiUrl + "/ai/delete"; |
|
|
const completion = await fetch(delUrl, postData); |
|
|
const completion = await fetch(delUrl, postData); |
|
|
if (completion.status === 404) { |
|
|
if (completion.status === 404) { |
|
|
notifyError(completion.statusText); |
|
|
notifyError(completion.statusText); |
|
@ -180,12 +180,12 @@ async function deleteModel(modelData: any) { |
|
|
if (completion.status === 200) { |
|
|
if (completion.status === 200) { |
|
|
notifySuccess("success!"); |
|
|
notifySuccess("success!"); |
|
|
} |
|
|
} |
|
|
} catch (error:any) { |
|
|
} catch (error: any) { |
|
|
console.log(error); |
|
|
console.log(error); |
|
|
notifyError(error.message); |
|
|
notifyError(error.message); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
function labelShow(val:any) { |
|
|
function labelShow(val: any) { |
|
|
labelId.value = val; |
|
|
labelId.value = val; |
|
|
labelEditor.value = true; |
|
|
labelEditor.value = true; |
|
|
} |
|
|
} |
|
@ -202,10 +202,10 @@ async function delLabel(id: number) { |
|
|
} |
|
|
} |
|
|
function getModelStatus(model: string) { |
|
|
function getModelStatus(model: string) { |
|
|
let name = t('model.noDown'); |
|
|
let name = t('model.noDown'); |
|
|
if (modelStore.modelList.find((item:any) => item.model === model)) { |
|
|
if (modelStore.modelList.find((item: any) => item.model === model)) { |
|
|
name = t('model.hasDown'); |
|
|
name = t('model.hasDown'); |
|
|
} |
|
|
} |
|
|
if (modelStore.downList.find((item:any) => item.model === model)) { |
|
|
if (modelStore.downList.find((item: any) => item.model === model)) { |
|
|
name = t('model.downloading'); |
|
|
name = t('model.downloading'); |
|
|
} |
|
|
} |
|
|
return name; |
|
|
return name; |
|
@ -214,56 +214,42 @@ function showModel(model: string) { |
|
|
detailModel.value = model; |
|
|
detailModel.value = model; |
|
|
showDetail.value = true; |
|
|
showDetail.value = true; |
|
|
} |
|
|
} |
|
|
|
|
|
async function refreshOllama() { |
|
|
|
|
|
try { |
|
|
|
|
|
await modelStore.refreshOllama(); |
|
|
|
|
|
notifySuccess(t('model.refreshSuccess')); |
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
notifyError(t('model.refreshFail')); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
</script> |
|
|
</script> |
|
|
<template> |
|
|
<template> |
|
|
<el-dialog v-model="showDetail" width="600" append-to-body> |
|
|
<el-dialog v-model="showDetail" width="600" append-to-body> |
|
|
<DownModelInfo :model="detailModel" /> |
|
|
<DownModelInfo :model="detailModel" /> |
|
|
</el-dialog> |
|
|
</el-dialog> |
|
|
<div class="app-container"> |
|
|
<div class="app-container"> |
|
|
<el-drawer |
|
|
<el-drawer v-model="downLeft" direction="ltr" :show-close="false" :with-header="false" :size="300"> |
|
|
v-model="downLeft" |
|
|
|
|
|
direction="ltr" |
|
|
|
|
|
:show-close="false" |
|
|
|
|
|
:with-header="false" |
|
|
|
|
|
:size="300" |
|
|
|
|
|
> |
|
|
|
|
|
<div> |
|
|
<div> |
|
|
<el-tag size="large" style="margin-bottom: 10px">{{ t('model.downloading') }}</el-tag> |
|
|
<el-tag size="large" style="margin-bottom: 10px">{{ t('model.downloading') }}</el-tag> |
|
|
<div class="pa-2"> |
|
|
<div class="pa-2"> |
|
|
<Vue3Lottie |
|
|
<Vue3Lottie animationLink="/bot/search.json" :height="200" :width="200" |
|
|
animationLink="/bot/search.json" |
|
|
v-if="modelStore.downList.length < 1" /> |
|
|
:height="200" |
|
|
|
|
|
:width="200" |
|
|
|
|
|
v-if="modelStore.downList.length < 1" |
|
|
|
|
|
/> |
|
|
|
|
|
<el-space direction="vertical" v-else> |
|
|
<el-space direction="vertical" v-else> |
|
|
<el-card |
|
|
<el-card v-for="(val, key) in modelStore.downList" :key="key" class="box-card" style="width: 250px"> |
|
|
v-for="(val, key) in modelStore.downList" |
|
|
|
|
|
:key="key" |
|
|
|
|
|
class="box-card" |
|
|
|
|
|
style="width: 250px" |
|
|
|
|
|
> |
|
|
|
|
|
<div class="card-header"> |
|
|
<div class="card-header"> |
|
|
<span>{{ val.model }}</span> |
|
|
<span>{{ val.model }}</span> |
|
|
</div> |
|
|
</div> |
|
|
<div class="text item" v-if="val.progress && val.isLoading > 0"> |
|
|
<div class="text item" v-if="val.progress && val.isLoading > 0"> |
|
|
<el-progress |
|
|
<el-progress :text-inside="true" :stroke-width="15" :percentage="val.progress" /> |
|
|
:text-inside="true" |
|
|
|
|
|
:stroke-width="15" |
|
|
|
|
|
:percentage="val.progress" |
|
|
|
|
|
/> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
<div class="drawer-model-actions" style="margin-top: 10px"> |
|
|
<div class="drawer-model-actions" style="margin-top: 10px"> |
|
|
<el-tag size="small" v-if="val.isLoading > 0">{{ val.status }}</el-tag> |
|
|
<el-tag size="small" v-if="val.isLoading > 0">{{ val.status }}</el-tag> |
|
|
<el-icon :size="18" color="red" @click="cancelDownload(val.model)"> |
|
|
<el-icon :size="18" color="red" @click="cancelDownload(val.model)"> |
|
|
<Delete /> |
|
|
<Delete /> |
|
|
</el-icon> |
|
|
</el-icon> |
|
|
<el-icon |
|
|
<el-icon :size="18" color="blue" v-if="val.isLoading < 1 && val.status != 'success'" |
|
|
:size="18" |
|
|
@click="download(toRaw(val))"> |
|
|
color="blue" |
|
|
|
|
|
v-if="val.isLoading < 1 && val.status != 'success'" |
|
|
|
|
|
@click="download(toRaw(val))" |
|
|
|
|
|
> |
|
|
|
|
|
<VideoPlay /> |
|
|
<VideoPlay /> |
|
|
</el-icon> |
|
|
</el-icon> |
|
|
</div> |
|
|
</div> |
|
@ -272,31 +258,17 @@ function showModel(model: string) { |
|
|
</div> |
|
|
</div> |
|
|
<el-tag size="large" style="margin: 10px auto">{{ t('model.hasDown') }}</el-tag> |
|
|
<el-tag size="large" style="margin: 10px auto">{{ t('model.hasDown') }}</el-tag> |
|
|
<div class="pa-2"> |
|
|
<div class="pa-2"> |
|
|
<div |
|
|
<div class="list-item" v-for="(item, index) in modelStore.modelList" :key="index"> |
|
|
class="list-item" |
|
|
|
|
|
v-for="(item, index) in modelStore.modelList" |
|
|
|
|
|
:key="index" |
|
|
|
|
|
> |
|
|
|
|
|
<div class="list-title" @click="showModel(item.model)"> |
|
|
<div class="list-title" @click="showModel(item.model)"> |
|
|
{{ item.model }} |
|
|
{{ item.model }} |
|
|
</div> |
|
|
</div> |
|
|
<el-button |
|
|
<el-button class="delete-btn" icon="Delete" size="small" @click.stop="deleteModel(item)" circle></el-button> |
|
|
class="delete-btn" |
|
|
|
|
|
icon="Delete" |
|
|
|
|
|
size="small" |
|
|
|
|
|
@click.stop="deleteModel(item)" |
|
|
|
|
|
circle |
|
|
|
|
|
></el-button> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</el-drawer> |
|
|
</el-drawer> |
|
|
<el-dialog v-model="labelEditor" width="600" :title="t('model.modelLabel')"> |
|
|
<el-dialog v-model="labelEditor" width="600" :title="t('model.modelLabel')"> |
|
|
<down-labeleditor |
|
|
<down-labeleditor @closeFn="closeLabel" @refreshFn="refreshList" :labelId="labelId" /> |
|
|
@closeFn="closeLabel" |
|
|
|
|
|
@refreshFn="refreshList" |
|
|
|
|
|
:labelId="labelId" |
|
|
|
|
|
/> |
|
|
|
|
|
</el-dialog> |
|
|
</el-dialog> |
|
|
<el-dialog v-model="downAdd" width="600" :title="t('model.modelDown')"> |
|
|
<el-dialog v-model="downAdd" width="600" :title="t('model.modelDown')"> |
|
|
<down-addbox @closeFn="downAddUpdate" @saveFn="saveBox" /> |
|
|
<down-addbox @closeFn="downAddUpdate" @saveFn="saveBox" /> |
|
@ -306,33 +278,16 @@ function showModel(model: string) { |
|
|
<div></div> |
|
|
<div></div> |
|
|
</template> |
|
|
</template> |
|
|
<template #content> |
|
|
<template #content> |
|
|
<el-button |
|
|
<el-button @click.stop="downLeft = !downLeft" icon="Menu" circle /> |
|
|
@click.stop="downLeft = !downLeft" |
|
|
<el-button @click.stop="downAdd = true" icon="Plus" circle /> |
|
|
icon="Menu" |
|
|
<el-button @click.stop="labelShow(0)" icon="CollectionTag" circle /> |
|
|
circle |
|
|
<el-button @click.stop="refreshOllama" icon="RefreshRight" circle /> |
|
|
/> |
|
|
|
|
|
<el-button @click.stop="downAdd = true" icon="Plus" circle /> |
|
|
|
|
|
<el-button |
|
|
|
|
|
@click.stop="labelShow(0)" |
|
|
|
|
|
icon="CollectionTag" |
|
|
|
|
|
circle |
|
|
|
|
|
/> |
|
|
|
|
|
<el-button |
|
|
|
|
|
@click.stop="modelStore.refreshOllama" |
|
|
|
|
|
icon="RefreshRight" |
|
|
|
|
|
circle |
|
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
|
|
</template> |
|
|
</template> |
|
|
<template #extra> |
|
|
<template #extra> |
|
|
<el-space class="mr-10"> |
|
|
<el-space class="mr-10"> |
|
|
<el-input |
|
|
<el-input :placeholder="t('model.search')" v-model="searchKey" v-on:keydown.enter="showSearch" |
|
|
:placeholder="t('model.search')" |
|
|
style="width: 200px" :suffix-icon="Search" /> |
|
|
v-model="searchKey" |
|
|
|
|
|
v-on:keydown.enter="showSearch" |
|
|
|
|
|
style="width: 200px" |
|
|
|
|
|
:suffix-icon="Search" |
|
|
|
|
|
/> |
|
|
|
|
|
</el-space> |
|
|
</el-space> |
|
|
</template> |
|
|
</template> |
|
|
</el-page-header> |
|
|
</el-page-header> |
|
@ -340,22 +295,13 @@ function showModel(model: string) { |
|
|
<div class="flex-fill ml-10 mr-10"> |
|
|
<div class="flex-fill ml-10 mr-10"> |
|
|
<el-tabs v-model="currentCate" @tab-click="showCate"> |
|
|
<el-tabs v-model="currentCate" @tab-click="showCate"> |
|
|
<el-tab-pane :label="t('model.all')" name="all" /> |
|
|
<el-tab-pane :label="t('model.all')" name="all" /> |
|
|
<el-tab-pane |
|
|
<el-tab-pane :label="t('model.' + item)" :name="item" v-for="(item, key) in modelStore.cateList" :key="key" /> |
|
|
:label="t('model.' + item)" |
|
|
|
|
|
:name="item" |
|
|
|
|
|
v-for="(item, key) in modelStore.cateList" |
|
|
|
|
|
:key="key" |
|
|
|
|
|
/> |
|
|
|
|
|
</el-tabs> |
|
|
</el-tabs> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<el-scrollbar class="scrollbarHeightList"> |
|
|
<el-scrollbar class="scrollbarHeightList"> |
|
|
<div class="model-list"> |
|
|
<div class="model-list"> |
|
|
<div |
|
|
<div v-for="item in modelStore.labelList" :key="item.name" class="model-item flex align-center pa-5"> |
|
|
v-for="item in modelStore.labelList" |
|
|
|
|
|
:key="item.name" |
|
|
|
|
|
class="model-item flex align-center pa-5" |
|
|
|
|
|
> |
|
|
|
|
|
<div class="flex-fill mx-5"> |
|
|
<div class="flex-fill mx-5"> |
|
|
<div class="font-weight-bold"> |
|
|
<div class="font-weight-bold"> |
|
|
{{ item.name }} |
|
|
{{ item.name }} |
|
@ -371,13 +317,8 @@ function showModel(model: string) { |
|
|
<el-button icon="Download" circle /> |
|
|
<el-button icon="Download" circle /> |
|
|
</template> |
|
|
</template> |
|
|
<template #default> |
|
|
<template #default> |
|
|
<div |
|
|
<div v-for="(el, index) in item.models" :key="index" :value="el.model" @click="downLabel(el, item)" |
|
|
v-for="(el, index) in item.models" |
|
|
class="list-column"> |
|
|
:key="index" |
|
|
|
|
|
:value="el.model" |
|
|
|
|
|
@click="downLabel(el, item)" |
|
|
|
|
|
class="list-column" |
|
|
|
|
|
> |
|
|
|
|
|
<div class="list-column-title"> |
|
|
<div class="list-column-title"> |
|
|
{{ el.model }} |
|
|
{{ el.model }} |
|
|
<el-tag size="small" type="info">{{ |
|
|
<el-tag size="small" type="info">{{ |
|
@ -393,12 +334,7 @@ function showModel(model: string) { |
|
|
</template> |
|
|
</template> |
|
|
</el-popover> |
|
|
</el-popover> |
|
|
<el-button icon="Edit" circle @click="labelShow(item.id)" /> |
|
|
<el-button icon="Edit" circle @click="labelShow(item.id)" /> |
|
|
<el-button |
|
|
<el-button @click.stop="delLabel(item.id)" icon="Delete" v-if="item.models.length === 0" circle /> |
|
|
@click.stop="delLabel(item.id)" |
|
|
|
|
|
icon="Delete" |
|
|
|
|
|
v-if="item.models.length === 0" |
|
|
|
|
|
circle |
|
|
|
|
|
/> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|