mirror of
https://gitee.com/ccnetcore/Yi
synced 2026-03-20 08:26:37 +08:00
feat: 路由动态权限控制、图片广场优化
This commit is contained in:
@@ -12,10 +12,17 @@ import {
|
||||
ZoomIn,
|
||||
} from '@element-plus/icons-vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import { getSelectableTokenInfo } from '@/api';
|
||||
import { generateImage, getImageModels, getTaskStatus } from '@/api/aiImage';
|
||||
|
||||
const props = defineProps({
|
||||
isActive: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['task-created']);
|
||||
|
||||
// State
|
||||
@@ -41,6 +48,19 @@ const canGenerate = computed(() => {
|
||||
return selectedModelId.value && prompt.value && !generating.value;
|
||||
});
|
||||
|
||||
// Watch isActive to manage polling
|
||||
watch(() => props.isActive, (active) => {
|
||||
if (active) {
|
||||
// Resume polling if we have a processing task
|
||||
if (currentTaskId.value && currentTask.value?.taskStatus === 'Processing') {
|
||||
startPolling(currentTaskId.value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
stopPolling();
|
||||
}
|
||||
});
|
||||
|
||||
// Methods
|
||||
async function fetchTokens() {
|
||||
tokenLoading.value = true;
|
||||
@@ -197,6 +217,12 @@ function startPolling(taskId: string) {
|
||||
}
|
||||
|
||||
async function pollStatus(taskId: string) {
|
||||
// Double check active status before polling (though timer should be cleared)
|
||||
if (!props.isActive) {
|
||||
stopPolling();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await getTaskStatus(taskId);
|
||||
// Handle response structure if needed
|
||||
@@ -257,7 +283,8 @@ async function downloadImage() {
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
window.URL.revokeObjectURL(url);
|
||||
} catch (e) {
|
||||
}
|
||||
catch (e) {
|
||||
console.error('Download failed', e);
|
||||
// Fallback
|
||||
window.open(currentTask.value.storeUrl, '_blank');
|
||||
@@ -324,14 +351,15 @@ onUnmounted(() => {
|
||||
配置
|
||||
</h2>
|
||||
|
||||
<!-- Token & Model -->
|
||||
<div class="bg-gray-50 p-4 rounded-lg space-y-4">
|
||||
<el-form-item label="API密钥" class="mb-0">
|
||||
<el-form label-position="top" class="space-y-2" label-width="auto">
|
||||
<!-- Token -->
|
||||
<el-form-item label="API密钥 (可选)">
|
||||
<el-select
|
||||
v-model="selectedTokenId"
|
||||
placeholder="请选择API密钥"
|
||||
class="w-full"
|
||||
:loading="tokenLoading"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="token in tokenOptions"
|
||||
@@ -343,7 +371,8 @@ onUnmounted(() => {
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="模型" class="mb-0">
|
||||
<!-- Model -->
|
||||
<el-form-item label="模型" required>
|
||||
<el-select
|
||||
v-model="selectedModelId"
|
||||
placeholder="请选择模型"
|
||||
@@ -363,57 +392,59 @@ onUnmounted(() => {
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<!-- Prompt -->
|
||||
<div class="space-y-2">
|
||||
<div class="flex justify-between items-center">
|
||||
<label class="text-sm font-medium text-gray-700">提示词</label>
|
||||
<el-button link type="primary" size="small" @click="clearPrompt">
|
||||
<el-icon class="mr-1">
|
||||
<Delete />
|
||||
</el-icon>清空
|
||||
</el-button>
|
||||
</div>
|
||||
<el-input
|
||||
v-model="prompt"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 8, maxRows: 15 }"
|
||||
placeholder="描述你想要生成的画面,例如:一只在太空中飞行的赛博朋克风格的猫..."
|
||||
maxlength="2000"
|
||||
show-word-limit
|
||||
class="custom-textarea"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Reference Image -->
|
||||
<div class="space-y-2">
|
||||
<label class="text-sm font-medium text-gray-700">参考图 (可选)</label>
|
||||
<div class="bg-gray-50 p-4 rounded-lg border border-dashed border-gray-300 hover:border-blue-400 transition-colors">
|
||||
<el-upload
|
||||
v-model:file-list="fileList"
|
||||
action="#"
|
||||
list-type="picture-card"
|
||||
:auto-upload="false"
|
||||
:limit="2"
|
||||
:on-change="handleFileChange"
|
||||
:on-remove="handleRemove"
|
||||
accept=".jpg,.jpeg,.png,.bmp,.webp"
|
||||
:class="{ 'hide-upload-btn': fileList.length >= 2 }"
|
||||
>
|
||||
<div class="flex flex-col items-center justify-center text-gray-400">
|
||||
<el-icon class="text-2xl mb-2">
|
||||
<Plus />
|
||||
</el-icon>
|
||||
<span class="text-xs">点击上传</span>
|
||||
<!-- Prompt -->
|
||||
<el-form-item label="提示词" required class="prompt-form-item ">
|
||||
<template #label>
|
||||
<div class="flex justify-between items-center w-full ">
|
||||
<span>提示词</span>
|
||||
<el-button link type="primary" size="small" @click="clearPrompt">
|
||||
<el-icon class="mr-1">
|
||||
<Delete />
|
||||
</el-icon>清空
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<el-input
|
||||
v-model="prompt"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 8, maxRows: 8 }"
|
||||
placeholder="描述你想要生成的画面,例如:一只在太空中飞行的赛博朋克风格的猫..."
|
||||
maxlength="2000"
|
||||
show-word-limit
|
||||
class="custom-textarea"
|
||||
resize="vertical"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- Reference Image -->
|
||||
<el-form-item label="参考图 (可选)">
|
||||
<div class="w-full bg-gray-50 p-4 rounded-lg border border-dashed border-gray-300 hover:border-blue-400 transition-colors">
|
||||
<el-upload
|
||||
v-model:file-list="fileList"
|
||||
action="#"
|
||||
list-type="picture-card"
|
||||
:auto-upload="false"
|
||||
:limit="2"
|
||||
:on-change="handleFileChange"
|
||||
:on-remove="handleRemove"
|
||||
accept=".jpg,.jpeg,.png,.bmp,.webp"
|
||||
:class="{ 'hide-upload-btn': fileList.length >= 2 }"
|
||||
>
|
||||
<div class="flex flex-col items-center justify-center text-gray-400">
|
||||
<el-icon class="text-2xl mb-2">
|
||||
<Plus />
|
||||
</el-icon>
|
||||
<span class="text-xs">点击上传</span>
|
||||
</div>
|
||||
</el-upload>
|
||||
<div class="text-xs text-gray-400 mt-2 flex justify-between items-center flex-wrap gap-2">
|
||||
<span>最多2张,< 5MB (支持 JPG/PNG/WEBP)</span>
|
||||
<el-checkbox v-model="compressImage" label="压缩图片" size="small" />
|
||||
</div>
|
||||
</el-upload>
|
||||
<div class="text-xs text-gray-400 mt-2 flex justify-between items-center flex-wrap gap-2">
|
||||
<span>最多2张,< 5MB (支持 JPG/PNG/WEBP)</span>
|
||||
<el-checkbox v-model="compressImage" label="压缩图片" size="small" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="mt-auto pt-4">
|
||||
@@ -450,7 +481,7 @@ onUnmounted(() => {
|
||||
<div class="absolute bottom-4 right-4 opacity-0 group-hover:opacity-100 transition-opacity flex gap-2 z-10">
|
||||
<el-button circle type="primary" :icon="ZoomIn" @click="showViewer = true" />
|
||||
<el-button circle type="primary" :icon="Download" @click="downloadImage" />
|
||||
<el-button circle type="info" :icon="Refresh" title="新任务" @click="currentTask = null" />
|
||||
<el-button circle type="success" :icon="Refresh" title="重新生成" @click="handleGenerate" />
|
||||
</div>
|
||||
|
||||
<el-image-viewer
|
||||
@@ -563,4 +594,8 @@ onUnmounted(() => {
|
||||
:deep(.hide-upload-btn .el-upload--picture-card) {
|
||||
display: none;
|
||||
}
|
||||
/* 隐藏默认的标签 */
|
||||
:deep(.prompt-form-item .el-form-item__label){
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user