|
|
@@ -131,6 +131,26 @@
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+ <el-dialog v-model="zipview" title="请选择打包尺寸" width="500px" top="20%">
|
|
|
+ <el-radio-group v-model="zipselectedOption" size="medium">
|
|
|
+ <el-radio label="1024x1024">1024 x 1024</el-radio>
|
|
|
+ <el-radio label="1024x1303">1024 x 1303</el-radio>
|
|
|
+ <el-radio label="图生图">图生图</el-radio>
|
|
|
+ <el-radio label="高清放大">高清放大</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+
|
|
|
+ <template #footer>
|
|
|
+ <div style="text-align: right">
|
|
|
+ <el-button @click="zipview = false">取消</el-button>
|
|
|
+ <el-button type="primary" @click="confirmPack">确认打包</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
<el-dialog v-model="showDescDialog" title="" width="890px" top="0%">
|
|
|
<div style="display: flex; gap: 10px; max-height: 70vh; overflow: hidden;">
|
|
|
<!-- 左侧图片区域,自适应图片尺寸,可滚动查看完整图片 -->
|
|
|
@@ -227,6 +247,7 @@
|
|
|
<el-option label="文生文" value="文生文" />
|
|
|
<el-option label="文生图" value="文生图" />
|
|
|
<el-option label="图生图" value="图生图" />
|
|
|
+ <el-option label="高清放大" value="高清放大" />
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
@@ -256,7 +277,7 @@
|
|
|
<el-tag v-else type="danger">未出图</el-tag>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="status_name" label="操作模型" width="90" align="center" />
|
|
|
+ <el-table-column prop="status_name" label="操作" width="70" align="center" />
|
|
|
<el-table-column prop="queue_status" label="状态说明" width="140" align="center" />
|
|
|
<el-table-column prop="same_count" label="出图数量" width="90" align="center" />
|
|
|
<el-table-column label="原图预览" width="120">
|
|
|
@@ -292,17 +313,18 @@
|
|
|
<!-- 右侧详情 -->
|
|
|
<div class="dialog-right">
|
|
|
<div class="dialog-right-scroll">
|
|
|
- <el-card shadow="hover" body-style="padding: 20px;">
|
|
|
+ <el-card shadow="hover" body-style="padding: 0px;">
|
|
|
<el-form :model="mlformdata" label-position="top">
|
|
|
<el-descriptions column="1" border>
|
|
|
|
|
|
<el-descriptions-item label="操作">
|
|
|
- <el-button type="primary" title="执行选择中图片到队列中,图生文" @click="imgtotext" :loading="isLoading">执行图生文</el-button>
|
|
|
- <el-button type="primary" title="执行选择中图片到队列中,文生文" @click="texttotxt" :loading="isLoading">执行文生文</el-button>
|
|
|
- <el-button type="primary" title="执行选择中图片到队列中,文生图" @click="texttoimg" :loading="isLoading">执行文生图</el-button>
|
|
|
- <el-button type="primary" title="执行选中图片到队列中,执行顺序:图生文->文生文->文生图->图生图" @click="handleSelected" :loading="isLoading" :disabled="isLoading">执行选择任务</el-button>
|
|
|
- <el-button type="primary" title="执行当前所有图片到队列中,执行顺序:图生文->文生文->文生图->图生图" @click="handleAll" :loading="isLoading">执行全部任务</el-button>
|
|
|
- <el-button type="primary" title="执行选择中图片到队列中,图生图" @click="imgtoimg" :loading="isLoading">SD图生图</el-button>
|
|
|
+ <el-button type="primary" title="选择图片,图生文" @click="imgtotext" :loading="isLoading">图生文</el-button>
|
|
|
+ <el-button type="primary" title="选择图片,文生文" @click="texttotxt" :loading="isLoading">文生文</el-button>
|
|
|
+ <el-button type="primary" title="选择图片,文生图" @click="texttoimg" :loading="isLoading">文生图</el-button>
|
|
|
+ <el-button type="primary" title="选择图片,图生图" @click="imgtoimg" :loading="isLoading">图生图</el-button>
|
|
|
+ <el-button type="primary" title="选择图片,图像高清放大处理" @click="singleimg" :loading="isLoading">图像高清放大处理</el-button>
|
|
|
+ <el-button type="primary" title="选中图片,执行顺序:图生文->文生文->文生图->图生图" @click="handleSelected" :loading="isLoading" :disabled="isLoading">执选择任务</el-button>
|
|
|
+ <el-button type="primary" title="执行当前所有图片,执行顺序:图生文->文生文->文生图->图生图" @click="handleAll" :loading="isLoading">执行全部任务</el-button>
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="文生文模型">
|
|
|
@@ -314,10 +336,27 @@
|
|
|
|
|
|
<el-descriptions-item label="文生图模型">
|
|
|
<el-radio-group v-model="selectedOption">
|
|
|
+ <el-radio label="black-forest-labs/FLUX.1-kontext-pro">flux-pro</el-radio>
|
|
|
<el-radio label="dall-e-3">dall-e-3</el-radio>
|
|
|
<el-radio label="gpt-image-1">gpt-image-1</el-radio>
|
|
|
</el-radio-group>
|
|
|
</el-descriptions-item>
|
|
|
+
|
|
|
+ <!-- <el-descriptions-item label="图生图模型">
|
|
|
+ <el-select
|
|
|
+ v-model="selectedModel"
|
|
|
+ placeholder="请选择模型"
|
|
|
+ filterable
|
|
|
+ style="width: 100%"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="(model, index) in modelList"
|
|
|
+ :key="index"
|
|
|
+ :label="model.title"
|
|
|
+ :value="model.model_name"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-descriptions-item> -->
|
|
|
|
|
|
<el-descriptions-item label="出图预览">
|
|
|
<div style="display: flex; gap: 20px; align-items: flex-start;">
|
|
|
@@ -334,26 +373,28 @@
|
|
|
1024x1024
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="image-preview-wrap" style="margin-top: 16px; height: 145px;">
|
|
|
+
|
|
|
+ <div class="image-preview-wrap" style="margin-top: 16px; height: 167px;">
|
|
|
<div
|
|
|
v-for="(img, index) in imageList"
|
|
|
- :key="'custom-' + index"
|
|
|
- class="image-items"
|
|
|
- @click="showDescription(img, 'custom')"
|
|
|
+ :key="'imgtoimg-' + index"
|
|
|
+ class="image-itemsimg"
|
|
|
+ @click="showDescription(img, 'san')"
|
|
|
>
|
|
|
- <img :src="formatImageUrl(img.custom_image_url)" />
|
|
|
- {{ img.size }}
|
|
|
+ <img :src="formatImageUrl(img.imgtoimg_url)" />
|
|
|
+ 图生图
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="image-preview-wrap" style="margin-top: 16px; height: 145px;">
|
|
|
+
|
|
|
+ <div class="image-preview-wrap" style="margin-top: 16px; height: 140px;">
|
|
|
<div
|
|
|
v-for="(img, index) in imageList"
|
|
|
- :key="'imgtoimg-' + index"
|
|
|
- class="image-itemsimg"
|
|
|
- @click="showDescription(img, 'san')"
|
|
|
+ :key="'custom-' + index"
|
|
|
+ class="image-items"
|
|
|
+ @click="showDescription(img, 'custom')"
|
|
|
>
|
|
|
- <img :src="formatImageUrl(img.imgtoimg_url)" />
|
|
|
- 图生图 679x862
|
|
|
+ <img :src="formatImageUrl(img.custom_image_url)" />
|
|
|
+ 高清放大
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -383,9 +424,9 @@
|
|
|
</div>
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
- <el-descriptions-item label="执行次数">
|
|
|
+ <!-- <el-descriptions-item label="执行次数">
|
|
|
<el-input-number v-model="num" :step="1" />
|
|
|
- </el-descriptions-item>
|
|
|
+ </el-descriptions-item> -->
|
|
|
|
|
|
<el-descriptions-item label="任务队列">
|
|
|
<el-table
|
|
|
@@ -431,7 +472,7 @@ import axios from 'axios'
|
|
|
import {Plus,Delete,CircleCheck,CircleClose} from '@element-plus/icons-vue'
|
|
|
import {stopQueueProcesses, queueStats, viewQueueStatus,ImgUpload,getPreviewSubDirs,getPreviewimg,getlsit,
|
|
|
imageToText,
|
|
|
-textToImage,Template,
|
|
|
+textToImage,Template_ids,sd_models,
|
|
|
packImagess,getUploadPath,get_queue_logs,getTaskProgress
|
|
|
} from '@/api/mes/job'
|
|
|
|
|
|
@@ -657,6 +698,8 @@ const fetchPreviewImages = async () => {
|
|
|
params.status_name = "文生图"
|
|
|
}else if(filterStatus.value === '图生图') {
|
|
|
params.status_name = "图生图"
|
|
|
+ }else if(filterStatus.value === '高清放大') {
|
|
|
+ params.status_name = "高清放大"
|
|
|
}
|
|
|
|
|
|
// 获取分页数据
|
|
|
@@ -705,15 +748,20 @@ const _resrow = ref('')
|
|
|
const TaskqueueVisible = ref(false)
|
|
|
const table_queue = ref([])
|
|
|
const table_Taskqueue = ref([])
|
|
|
+
|
|
|
+//SD模型
|
|
|
+const selectedModel = ref('Realistic_Vision_V5.0-inpainting.safetensors [cf5d9eb09b]')
|
|
|
+const modelList = ref([])
|
|
|
+
|
|
|
+
|
|
|
//查看详情按钮
|
|
|
const record_deleteRow = async (row) => {
|
|
|
- // getPreviewSubDirslist()
|
|
|
- _resrow.value = row;
|
|
|
- // page.value = 1;
|
|
|
-
|
|
|
//打开弹窗
|
|
|
mlinventoryVisible.value = true;
|
|
|
|
|
|
+ //获取当前文件夹行信息
|
|
|
+ _resrow.value = row;
|
|
|
+
|
|
|
//清空信息保持数据最新
|
|
|
imageList.value = []
|
|
|
img_id.value = '';
|
|
|
@@ -723,12 +771,17 @@ const record_deleteRow = async (row) => {
|
|
|
path_image_url.value = '';
|
|
|
activeDescription.value = '';
|
|
|
|
|
|
+ // 获取 SD 模型列表
|
|
|
+ const sd_models_list = await sd_models();
|
|
|
+ modelList.value = sd_models_list.data
|
|
|
+
|
|
|
// 任务队列
|
|
|
const queue_logs = await get_queue_logs({ old_image_file: row['old_image_url'] });
|
|
|
table_queue.value = queue_logs.data;
|
|
|
|
|
|
// 出图尺寸
|
|
|
- const res = await Template();
|
|
|
+ const res = await Template_ids();
|
|
|
+ console.log(res)
|
|
|
height.value = res.data.height
|
|
|
width.value = res.data.width
|
|
|
|
|
|
@@ -816,10 +869,8 @@ const highlightKeywords = (text) => {
|
|
|
const showDescription = async (img, type) => {
|
|
|
showDescDialog.value = true;
|
|
|
|
|
|
- Refresh_Status()
|
|
|
// 任务队列
|
|
|
- const queue_logs = await get_queue_logs({ old_image_file: _resrow.value['old_image_url'] });
|
|
|
- table_queue.value = queue_logs.data;
|
|
|
+ Refresh_Status()
|
|
|
|
|
|
// 公共字段初始化
|
|
|
img_id.value = img.id || '';
|
|
|
@@ -849,6 +900,7 @@ const showDescription = async (img, type) => {
|
|
|
imgtoimg_url.value = img.imgtoimg_url || '图片未生成';
|
|
|
activeDescription.value = '';
|
|
|
model.value = '';
|
|
|
+
|
|
|
}else if (type === 'old') {
|
|
|
|
|
|
path_image_url.value = img.path || '暂无说明';
|
|
|
@@ -856,7 +908,7 @@ const showDescription = async (img, type) => {
|
|
|
activeDescription.value = '';
|
|
|
|
|
|
} else {
|
|
|
- console.log('无效的类型');
|
|
|
+ // console.log('无效的类型');
|
|
|
}
|
|
|
};
|
|
|
|
|
|
@@ -875,7 +927,7 @@ const num = ref(1)
|
|
|
//文生文模型下拉(默认值)
|
|
|
const txttotxt_selectedOption = ref('gemini-2.0-flash')
|
|
|
//文生图模型下拉(默认值)
|
|
|
-const selectedOption = ref('dall-e-3')
|
|
|
+const selectedOption = ref('black-forest-labs/FLUX.1-kontext-pro')
|
|
|
|
|
|
|
|
|
//刷新表格任务状态
|
|
|
@@ -909,6 +961,9 @@ const texttoimg = () => {
|
|
|
const imgtoimg = () => {
|
|
|
processImages(toRaw(_parh.value),'图生图');
|
|
|
};
|
|
|
+const singleimg = () => {
|
|
|
+ processImages(toRaw(_parh.value),'高清放大');
|
|
|
+};
|
|
|
|
|
|
//执行选择任务
|
|
|
const handleSelected = () => {
|
|
|
@@ -917,7 +972,6 @@ const handleSelected = () => {
|
|
|
|
|
|
//执行全部任务
|
|
|
const allTableData = ref([]); // 全部数据缓存
|
|
|
-
|
|
|
const handleAll = async () => {
|
|
|
try {
|
|
|
await ElMessageBox.confirm(
|
|
|
@@ -939,19 +993,6 @@ const handleAll = async () => {
|
|
|
page: 1,
|
|
|
limit: 10000
|
|
|
};
|
|
|
-
|
|
|
-
|
|
|
- // const allRes = await getPreviewimg(allParams);
|
|
|
- // console.log(allRes);
|
|
|
-
|
|
|
- // if (allRes.code === 0) {
|
|
|
- // allTableData.value = allRes.data;
|
|
|
- // const allPaths = toRaw(allTableData.value).map(item => item.path);
|
|
|
- // processImages(toRaw(allPaths),'');
|
|
|
- // } else {
|
|
|
- // ElMessage.error(allRes.msg || '获取全部图片失败');
|
|
|
- // }
|
|
|
-
|
|
|
const allRes = await getPreviewimg(allParams);
|
|
|
console.log(allRes);
|
|
|
|
|
|
@@ -981,21 +1022,20 @@ const handleAll = async () => {
|
|
|
};
|
|
|
|
|
|
|
|
|
-//队列操作 统一执行操作按钮处理方法
|
|
|
+//操作 统一执行操作按钮处理方法
|
|
|
const processImages = async (files,type) => {
|
|
|
-
|
|
|
+ //判断是否选择图片列表
|
|
|
if (!Array.isArray(files) || files.length === 0) {
|
|
|
ElMessage.warning('请选择要处理的图片')
|
|
|
return
|
|
|
}
|
|
|
- // 限制尺寸校验放外面更合理
|
|
|
- if (width.value >= 1024 || height.value >= 1024) {
|
|
|
- ElMessage.warning('尺寸不可超过1024')
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
+ //生成图片是1024,所有需要限制尺寸不可以超过原始尺寸
|
|
|
+ // if (width.value >= 1024 || height.value >= 1024) {
|
|
|
+ // ElMessage.warning('尺寸不可超过1024')
|
|
|
+ // return
|
|
|
+ // }
|
|
|
+ //加载开启
|
|
|
isLoading.value = true
|
|
|
- let successCount = 0
|
|
|
const failList = []
|
|
|
const payload = {
|
|
|
old_image_file:_resrow.value['old_image_url'],
|
|
|
@@ -1035,57 +1075,84 @@ const processImages = async (files,type) => {
|
|
|
}
|
|
|
|
|
|
// --------------------- 打包zip ---------------------
|
|
|
+const zipview = ref(false)
|
|
|
+const ziprow = ref('')
|
|
|
+const zipselectedOption = ref('1024x1303') // 默认选中
|
|
|
+//点击打包按钮
|
|
|
const packRow = async (row) => {
|
|
|
+ zipview.value = true;
|
|
|
+
|
|
|
+ ziprow.value = row
|
|
|
+}
|
|
|
+//确定按钮
|
|
|
+const confirmPack = async (row) => {
|
|
|
isLoading.value = true;
|
|
|
try {
|
|
|
- // 请求预览图接口获取图片路径
|
|
|
const res = await getPreviewimg({
|
|
|
- path: row.old_image_url,
|
|
|
+ path: ziprow.value.old_image_url,
|
|
|
page: 1,
|
|
|
limit: 10000
|
|
|
});
|
|
|
+
|
|
|
if (res.code !== 0 || !res.data || res.data.length === 0) {
|
|
|
ElMessage.warning('未找到出图记录');
|
|
|
- isLoading.value = false;
|
|
|
return;
|
|
|
}
|
|
|
- const imagePaths = res.data
|
|
|
- .map(item => item.custom_image_url)
|
|
|
- .filter(path => path && path.trim() !== '');
|
|
|
-
|
|
|
+ const imagePaths = res.data.flatMap(item => {
|
|
|
+ const paths = [];
|
|
|
+ if (item.custom_image_url?.trim()) {
|
|
|
+ paths.push({ type: 'custom_image_url', path: item.custom_image_url });
|
|
|
+ }
|
|
|
+ if (item.imgtoimg_url?.trim()) {
|
|
|
+ paths.push({ type: 'imgtoimg_url', path: item.imgtoimg_url });
|
|
|
+ }
|
|
|
+ return paths;
|
|
|
+ });
|
|
|
if (imagePaths.length === 0) {
|
|
|
ElMessage.warning('没有可打包的图片');
|
|
|
- isLoading.value = false;
|
|
|
return;
|
|
|
}
|
|
|
- // 发起打包请求
|
|
|
+
|
|
|
const packRes = await packImagess({ paths: imagePaths });
|
|
|
|
|
|
if (packRes.code === 0 && packRes.download_url) {
|
|
|
ElMessage.success('打包成功,正在下载...');
|
|
|
- // 自动触发浏览器下载 zip 文件
|
|
|
- let url = packRes.download_url.replace('127.0.0.1', '20.0.16.128');
|
|
|
- const link = document.createElement('a');
|
|
|
- link.href = url;
|
|
|
- link.setAttribute('download', '');
|
|
|
- document.body.appendChild(link);
|
|
|
- link.click();
|
|
|
- document.body.removeChild(link);
|
|
|
+
|
|
|
+ // ✅ 替换为服务的真实 IP 和端口
|
|
|
+ const basePath = import.meta.env.VITE_BASE_PATH || 'http://20.0.16.128';
|
|
|
+ const uploadsPort = import.meta.env.VITE_UPLOADS_PORT || '9093';
|
|
|
+
|
|
|
+ let url = packRes.download_url;
|
|
|
+
|
|
|
+ try {
|
|
|
+ const parsedUrl = new URL(url);
|
|
|
+ if (parsedUrl.hostname === '127.0.0.1' || parsedUrl.hostname === 'localhost') {
|
|
|
+ parsedUrl.hostname = new URL(basePath).hostname;
|
|
|
+ parsedUrl.port = uploadsPort;
|
|
|
+ url = parsedUrl.toString();
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.error('URL 解析失败:', e);
|
|
|
+ }
|
|
|
+
|
|
|
+ const link = document.createElement('a');
|
|
|
+ link.href = url;
|
|
|
+ link.setAttribute('download', '');
|
|
|
+ document.body.appendChild(link);
|
|
|
+ link.click();
|
|
|
+ document.body.removeChild(link);
|
|
|
} else {
|
|
|
ElMessage.error(`打包失败:${packRes.msg || '未知错误'}`);
|
|
|
}
|
|
|
} catch (err) {
|
|
|
ElMessage.error('打包请求异常');
|
|
|
console.error(err);
|
|
|
+ } finally {
|
|
|
+ isLoading.value = false;
|
|
|
}
|
|
|
- isLoading.value = false;
|
|
|
};
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
</script>
|
|
|
-
|
|
|
<style scoped>
|
|
|
.page-container {
|
|
|
padding: 20px;
|
|
|
@@ -1366,8 +1433,8 @@ const packRow = async (row) => {
|
|
|
width: 110px;
|
|
|
}
|
|
|
.image-itemsimg img {
|
|
|
- width: 95px;
|
|
|
- height: 120px;
|
|
|
+ width: 118px;
|
|
|
+ height: 150px;
|
|
|
border: 1px solid #ccc;
|
|
|
object-fit: contain;
|
|
|
}
|