소스 검색

first commit

liuhairui 4 달 전
부모
커밋
9e084d9042

+ 225 - 0
src/api/ai/aiimg.js

@@ -0,0 +1,225 @@
+import axios from 'axios';
+
+const api = axios.create({
+  baseURL: 'http://20.0.16.53:9093',
+  timeout: 10000, 
+});
+
+//获取指定目录所有图片
+export const getPreviewimg = (data) => {
+  return api({
+    url: '/api/Ai_New/getPreviewimg',
+    method: 'post',
+    data
+  })
+}
+
+// 图片上传
+export const ImgUpload = (data) => {
+  return api({
+    url: '/api/Ai_New/ImgUpload',
+    method: 'post',
+    data
+  })
+}
+export const getUploadPath = (data) => {
+  return api({
+    url: '/api/Ai_New/getUploadPath',
+    method: 'get',
+    data
+  })
+}
+
+export const TemplateList = (params) => {
+  return api({
+    url: '/api/Ai_New/TemplateList',
+    method: 'get',
+    params
+  })
+}
+export const setActiveTemplate = (params) => {
+  return api({
+    url: '/api/Ai_New/setActiveTemplate',
+    method: 'get',
+    params
+  })
+}
+//
+export const Template = (params) => {
+  return api({
+    url: '/api/Ai_New/Template',
+    method: 'get',
+    params
+  })
+}
+export const Template_ids = (params) => {
+  return api({
+    url: '/api/Ai_New/Template_ids',
+    method: 'get',
+    params
+  })
+}
+
+export const updatetemplate = (data) => {
+  return api({
+    url: '/api/Ai_New/updatetemplate',
+    method: 'post',
+    data
+  })
+}
+
+
+// 获取原图目录名称
+export const getPreviewSubDirs = (params) => {
+  return api({
+    url: '/api/Ai_New/getPreviewSubDirs',
+    method: 'get',
+    params
+  })
+}
+//获取图片
+export const getlsit = (params) => {
+  return api({
+    url: '/api/Ai_New/getlsit',
+    method: 'get',
+    params
+  })
+}
+
+
+
+//出图接口
+export const imageToText = (data) => {
+  return api({
+    url: '/api/Ai_New/imageToText',
+    method: 'post',
+    data
+  })
+}
+//出图接口
+export const textToImage = (data) => {
+  return api({
+    url: '/api/Ai_New/textToImage',
+    method: 'post',
+    data
+  })
+}
+//压缩图片文件
+export const packImagess = (data) => {
+  return api({
+    url: '/api/Ai_New/packImagess',
+    method: 'post',
+    data
+  })
+}
+//查询总队列状态
+export const queueStats = (params) => {
+  return api({
+    url: '/api/Ai_New/queueStats',
+    method: 'get',
+    params
+  })
+}
+//清空队列
+export const stopQueueProcesses = (params) => {
+  return api({
+    url: '/api/Ai_New/stopQueueProcesses',
+    method: 'get',
+    params
+  })
+}
+
+//显示当前运行中的队列监听进程
+export const viewQueueStatus = (params) => {
+  return api({
+    url: '/api/Ai_New/viewQueueStatus',
+    method: 'get',
+    params
+  })
+}
+
+//查询队列列表
+export const get_queue_logs = (data) => {
+  return api({
+    url: '/api/Ai_New/get_queue_logs',
+    method: 'post',
+    data
+  })
+}
+//任务状态统计接口
+export const getTaskProgress = (params) => {
+  return api({
+    url: '/api/Ai_New/getTaskProgress',
+    method: 'get',
+    params
+  })
+}
+
+//通过店铺ID-查询对应店铺表数据
+export const PatternApi = (params) => {
+  return api({
+    url: '/api/Ai_New/PatternApi',
+    method: 'get',
+    params
+  })
+}
+
+
+export const sd_models = (params) => {
+  return api({
+    url: '/api/Ai_New/sd_models',
+    method: 'get',
+    params
+  })
+}
+
+
+
+export const getSide = (data) => {
+  return api({
+    url: '/api/Ai_New/getTab',
+    method: 'post',
+    data
+  })
+}
+export const getTable = (params) => {
+  return api({
+    url: '/api/Ai_New/getList',
+    method: 'get',
+    params
+  })
+}
+export const oversizedloss = (data) => {
+  return api({
+    url: '/api/Ai_New/oversizedloss',
+    method: 'post',
+    data
+  })
+}
+
+
+//获取文生图模型列表
+export const txttoimg_moxing = (params) => {
+  return api({
+    url: '/api/Ai_New/txttoimg_moxing',
+    method: 'get',
+    params
+  })
+}
+//修改默认文生图模型
+export const txttoimg_update = (data) => {
+  return api({
+    url: '/api/Ai_New/txttoimg_update',
+    method: 'post',
+    data
+  })
+}
+
+
+export const getPreviewFolders = (params) => {
+  return api({
+    url: '/api/Ai_New/getPreviewFolders',
+    method: 'get',
+    params
+  })
+}

+ 82 - 0
src/api/mes/job.js

@@ -1090,3 +1090,85 @@ export const SubOrderProgress = (params) => {
   })
 }
 
+//获取发货单发货数量
+export const Read_File = (params) => {
+  return service({
+    url: '/mes_server/work_order/Read_File',
+    method: 'get',
+    params
+  })
+}
+
+export const Read_Add = (data) => {
+  return service({
+    url: '/mes_server/work_order/Read_Add',
+    method: 'post',
+    data
+  })
+}
+
+export const Read_List = (params) => {
+  return service({
+    url: '/mes_server/work_order/Read_List',
+    method: 'get',
+    params
+  })
+}
+
+
+
+
+// 图片上传
+export const ImgUpload = (data) => {
+  return service({
+    url: '/mes_server/Facility/ImgUpload',
+    method: 'post',
+    data
+  })
+}
+export const getUploadPath = (data) => {
+  return service({
+    url: '/mes_server/Facility/getUploadPath',
+    method: 'get',
+    data
+  })
+}
+
+export const TemplateList = (params) => {
+  return service({
+    url: '/mes_server/Facility/TemplateList',
+    method: 'get',
+    params
+  })
+}
+export const setActiveTemplate = (params) => {
+  return service({
+    url: '/mes_server/Facility/setActiveTemplate',
+    method: 'get',
+    params
+  })
+}
+//
+export const Template = (params) => {
+  return service({
+    url: '/mes_server/Facility/Template',
+    method: 'get',
+    params
+  })
+}
+export const Template_ids = (params) => {
+  return service({
+    url: '/mes_server/Facility/Template_ids',
+    method: 'get',
+    params
+  })
+}
+
+export const updatetemplate = (data) => {
+  return service({
+    url: '/mes_server/Facility/updatetemplate',
+    method: 'post',
+    data
+  })
+}
+

+ 262 - 0
src/view/yunyin/shengchanguanli/AIFashionModelLibrary.vue

@@ -0,0 +1,262 @@
+<template>
+  <div class="page-container">
+    <el-descriptions :column="2" border class="queue-status-box">
+      <!-- 模版选择器 -->
+      <el-descriptions-item label="选择" :span="2">
+        <el-row :gutter="10" align="middle">
+			<el-col :span="6">
+			  <el-select v-model="path_selectedId" placeholder="请选择文件夹" @change="path_loadTemplateDetail">
+			    <el-option
+			      v-for="tpl in path_templateList"
+			      :key="tpl.path"
+			      :label="tpl.path"
+			      :value="tpl.path"
+			    />
+			  </el-select>
+			</el-col>
+			
+          <el-col :span="6">
+            <el-select v-model="selectedId" placeholder="请选择模版" @change="loadTemplateDetail">
+              <el-option
+                v-for="tpl in templateList"
+                :key="tpl.id"
+                :label="'模版 ' + tpl.id + (tpl.ids === 1 ? '(使用中)' : '')"
+                :value="tpl.id"
+              />
+            </el-select>
+          </el-col>
+          <el-col :span="3">
+            <el-button type="primary" @click="createNewTemplate">新增模版</el-button>
+          </el-col>
+          <el-col :span="4">
+            <el-button type="success" @click="onsetActive" :disabled="selectedId === usedId">设为当前使用模版</el-button>
+          </el-col>
+        </el-row>
+      </el-descriptions-item>
+
+      <!-- 图生文模版输入区域 -->
+      <el-descriptions-item label="图生文模版" :span="2">
+        <textarea
+          v-model="textareaContent"
+          placeholder="请输入提示词"
+          rows="10"
+          class="custom-textarea"
+          @keydown.tab.prevent="insertTab"
+        ></textarea>
+      </el-descriptions-item>
+
+      <!-- 文生文模版输入区域 -->
+      <el-descriptions-item label="文生文模版" :span="2">
+        <textarea
+          v-model="english_content"
+          placeholder="请输入提示词"
+          rows="10"
+          class="custom-textarea"
+          @keydown.tab.prevent="insertTab"
+        ></textarea>
+      </el-descriptions-item>
+
+      <!-- 出图尺寸输入区域 -->
+      <el-descriptions-item label="出图尺寸" :span="2">
+        <el-row :gutter="10" align="middle">
+          <el-col :span="4">
+            <el-input
+              v-model="width"
+              placeholder="宽度"
+              size="small"
+              type="number"
+              min="1"
+            />
+          </el-col>
+          <el-col :span="1" style="text-align: center;">×</el-col>
+          <el-col :span="4">
+            <el-input
+              v-model="height"
+              placeholder="高度"
+              size="small"
+              type="number"
+              min="1"
+            />
+          </el-col>
+        </el-row>
+      </el-descriptions-item>
+
+      <!-- 操作按钮 -->
+      <el-descriptions-item label="操作" :span="2">
+        <el-button type="primary" @click="saveTemplate" :loading="mb_isLoading">
+          保存模版
+        </el-button>
+      </el-descriptions-item>
+    </el-descriptions>
+  </div>
+</template>
+
+<script setup>
+import { ref, nextTick, onMounted } from 'vue'
+import axios from 'axios'
+import { ElMessage } from 'element-plus'
+import {
+  TemplateList,
+  Template,
+  updatetemplate,getPreviewFolders,
+  setActiveTemplate
+} from '@/api/ai/aiimg'
+
+// 模版状态数据
+const templateList = ref([])
+const selectedId = ref(null)
+const usedId = ref(null)
+
+const path_templateList = ref([])
+const path_selectedId = ref(null)
+
+// 模版内容
+const textareaContent = ref('')
+const english_content = ref('')
+const height = ref('')
+const width = ref('')
+const mb_isLoading = ref(false)
+
+//进入页面自动加载
+const loadTemplateList = async () => {
+	//文件夹列表
+	const getPreviewFolders_list = await getPreviewFolders()
+	path_templateList.value = getPreviewFolders_list.data.data.folders || []
+}
+
+//点击选择文件夹路径获取-》模版列表
+const path_loadTemplateDetail = async (path) => {
+	if(path){
+		const res = await TemplateList({path:path})
+		templateList.value = res.data.data.list || []
+		usedId.value = res.data.data.usedId
+		selectedId.value = usedId.value
+		await loadTemplateDetail(selectedId.value)
+	}
+}
+
+//获取模版列表后将默认模版显示
+const loadTemplateDetail = async (id) => {
+	if(id){
+		const res = await Template({ id })
+		textareaContent.value = res.data.data.content || ''
+		english_content.value = res.data.data.english_content || ''
+		width.value = res.data.data.width || ''
+		height.value = res.data.data.height || ''
+	}
+}
+
+// 创建新模版(清空内容)
+const createNewTemplate = () => {
+  selectedId.value = null
+  textareaContent.value = '请输入新增模版内容'
+  english_content.value = '请输入新增模版内容'
+  width.value = '1303'
+  height.value = '1024'
+}
+
+// 保存模版(新增或更新)
+const saveTemplate = async () => {
+	
+  if (!textareaContent.value || !width.value || !height.value) {
+    ElMessage.warning('请填写完整模版内容和尺寸')
+    return
+  }
+
+  mb_isLoading.value = true
+  const res = await updatetemplate({
+    id: selectedId.value,
+	path:path_selectedId.value,
+    textareaContent: textareaContent.value,
+    english_content: english_content.value,
+    width: width.value,
+    height: height.value
+  })
+  mb_isLoading.value = false
+
+  if (res.code === 0) {
+    ElMessage.success('模版保存成功')
+    loadTemplateList()
+  } else {
+    ElMessage.error('保存失败')
+  }
+}
+
+// 设为当前模版
+const onsetActive = async () => {
+  const res = await setActiveTemplate({ id: selectedId.value,path:path_selectedId.value })
+  if (res.code === 0) {
+    ElMessage.success('已设为当前使用模版')
+    await loadTemplateList()
+  } else {
+    ElMessage.error('设置失败')
+  }
+}
+
+// tab 缩进逻辑
+const insertTab = (event) => {
+  const textarea = event.target
+  const start = textarea.selectionStart
+  const end = textarea.selectionEnd
+  const isShift = event.shiftKey
+  const value = textareaContent.value
+  const before = value.substring(0, start)
+  const selected = value.substring(start, end)
+  const after = value.substring(end)
+
+  if (selected.includes('\n')) {
+    const lines = selected.split('\n')
+    const newText = lines
+      .map(line => (isShift
+        ? (line.startsWith('\t') ? line.substring(1) : line.startsWith('    ') ? line.substring(4) : line)
+        : '\t' + line))
+      .join('\n')
+    textareaContent.value = before + newText + after
+    const offset = newText.length - selected.length
+    nextTick(() => {
+      textarea.selectionStart = start
+      textarea.selectionEnd = end + offset
+    })
+  } else {
+    if (isShift && value.substring(start - 1, start) === '\t') {
+      textareaContent.value = before.slice(0, -1) + selected + after
+      nextTick(() => {
+        textarea.selectionStart = textarea.selectionEnd = start - 1
+      })
+    } else {
+      textareaContent.value = before + '\t' + selected + after
+      nextTick(() => {
+        textarea.selectionStart = textarea.selectionEnd = start + 1
+      })
+    }
+  }
+
+  event.preventDefault()
+}
+
+// 初始化加载
+onMounted(loadTemplateList)
+</script>
+
+<style scoped>
+.page-container {
+  padding: 20px;
+  background: #fff;
+}
+
+.custom-textarea {
+  width: 100%;
+  font-family: monospace;
+  font-size: 14px;
+  padding: 10px;
+  line-height: 1.6;
+  border: 1px solid #dcdfe6;
+  border-radius: 4px;
+  resize: vertical;
+  box-sizing: border-box;
+}
+
+:deep(.el-descriptions__body .el-descriptions__table.is-bordered .el-descriptions__cell) {
+  width: 100px;
+}
+</style>

+ 2007 - 172
src/view/yunyin/shengchanguanli/AIGeneratedvue.vue

@@ -1,201 +1,2036 @@
 <template>
-    <div>
-      <layout>
-        <layout-header>
-          <div class="">
-            <!--          按钮部分-->
-            <el-form ref="elSearchFormRef"   class="demo-form-inline" :rules="searchRule" >
-              <!-- <el-form-item>
-                <el-input v-model="searchInfo" placeholder="搜索工单编号" clearable style="width: 200px;margin: 5px"></el-input>
-                <el-button type="primary" class="bt" icon="download" @click="hzToExcel" >导出到Excel(汇总)</el-button>
-                <el-button type="primary" class="bt" icon="download" @click="mxToExcel" >导出到Excel(明细)</el-button>
-              </el-form-item> -->
-              <h3>页面正在建设中</h3>
-            </el-form>
-  
-        
-  
-          </div>
-        </layout-header>
-  
-        <layout>
-          <!--    左侧树侧形结构-->
-          <!-- <layout-sider :resize-directions="['right']" :width="190" style="margin-right: 10px;">
-            <div class="JKWTree-tree" style="height: 200px">
-              <h3>生产进程查询</h3>
-              <el-tree :data="treeData"  :props="defaultProps" @node-click="handleNodeClick" @node-expand="handleNodeExpand">
-              </el-tree>
-            </div>
-          </layout-sider>
-   -->
-          <!-- 右侧区域 -->
-          <layout-content >
-          <!-- <el-main>
-            <div class="gva-table-box">
-              <el-table ref="multipleTable" style="width: 100%;height: 33vh" tooltip-effect="dark"
-                        :row-style="{ height: '25px' }"  :header-cell-style="{ padding: '0px' }"
-                        :cell-style="{ padding: '0px' }" :header-row-style="{ height: '20px' }"
-                        :data="hztableData"  border row-key="ID"
-                        size="small"
-                        :cell-class-name="gxbgCellClass"
-                        highlight-current-row="true" @row-dblclick="updateCompanyFunc"
-                        @row-click="tableRowClick" :show-overflow-tooltip="true"
-                        @selection-change="handleSelectionChange">
-               <el-table-column  sortable align="center" label="设备编号" prop="工单编号"  width="120" />
-               <el-table-column  sortable align="center" label="设备名称" prop="印件代号"  width="120" />
-               <el-table-column   align="center" label="上月末主电表读数" prop="印件名称"  width="200" />
-               <el-table-column   align="center" label="本月末主电表读数" prop="联数"  width="200" />
-               <el-table-column   align="center" label="主电表耗电量" prop="投料大箱"  width="110" />
-               <el-table-column   align="center" label="上月末辅电表读数" prop="计划投料"  width="200" />
-               <el-table-column   align="center" label="本月末本电表读数" prop="工序1"  width="200" />
-               <el-table-column   align="center" label="辅电表耗电量" prop="工序2"  width="110" />
-              </el-table>
-  
-              <div class="gva-pagination">
-                <el-pagination layout="total" :current-page="page" :page-size="pageSize"
-                 :total="total" @current-change="handleCurrentChange" @size-change="handleSizeChange" />
-              </div>
-            </div>
-
-
-            <div class="gva-table-box">
-              <el-table ref="multipleTable" style="width: 100%;height: 45vh" tooltip-effect="dark"
-                        :row-style="{ height: '25px' }"  :header-cell-style="{ padding: '0px' }"
-                        :cell-style="{ padding: '0px' }" :header-row-style="{ height: '20px' }"
-                        :data="mxtableData"  border row-key="ID"
-                        size="small"
-                        :cell-class-name="gxbgCellClass"
-                        highlight-current-row="true" @row-dblclick="updateCompanyFunc"
-                        @row-click="tableRowClick" :show-overflow-tooltip="true"
-                        @selection-change="handleSelectionChange">
-               <el-table-column  sortable align="center" label="机台编号" prop="机台编号"  width="120" />
-               <el-table-column  sortable align="center" label="开工时间" prop="开工时间"  width="120" />
-               <el-table-column  sortable align="center" label="主电表" prop="主电表"  width="200" />
-               <el-table-column  sortable align="center" label="辅电表" prop="辅电表"  width="100" />
-              </el-table>
-  
-              <div class="gva-pagination">
-                <el-pagination layout="total" :current-page="page" :page-size="pageSize"
-                 :total="total" @current-change="handleCurrentChange" @size-change="handleSizeChange" />
-              </div>
-            </div>
-  
-          </el-main> -->
-        </layout-content>
-        </layout>
-      </layout>
-    </div>
-  </template>
-  <script setup>
-  // 全量引入格式化工具 请按需保留
-  import { Layout, LayoutSider, LayoutContent } from '@arco-design/web-vue';
-  
-  import {ref, reactive} from 'vue'
-  import { exportExcelFile } from '@/utils/excel'
-  import {ElMessage} from "element-plus";
-  defineOptions({name: 'Company'})
-  // =========== 获取左侧树侧形结构 ===========
-  
+  <div class="page-container">
+    <el-descriptions title="" :column="1" border>
+		<el-descriptions-item label="图片上传">
+		  <div class="upload-container">
+			<el-upload
+			  ref="uploadRef"
+			  class="upload-list"
+			  :action="uploadUrl"
+			  :http-request="customUpload"
+			  :headers="uploadHeaders"
+			  list-type="picture-card"
+			  :on-preview="handlePreview"
+			  :on-remove="handleRemove"
+			   :on-change="handleChange"
+			  :before-upload="beforeUpload"
+			  :on-success="handleSuccess"
+			  :on-error="handleError"
+			  :on-exceed="handleExceed"
+			  :limit="30"
+			  :multiple="true"
+			  accept="image/jpeg,image/png">
+			  <el-icon><Plus /></el-icon>
+			  <template #tip>
+				<div class="el-upload__tip">
+				  只能上传 <b>jpg/png</b> 文件,且 <b>不超过30张</b>
+				</div>
+			  </template>
+			  <template #file="{ file }">
+			  </template>
+			</el-upload>
+		  </div>
+		</el-descriptions-item>
+	</el-descriptions>
+	
+	<el-descriptions
+		title=""
+		column="7"
+		border
+		class="queue-status-box">
+		
+		<el-descriptions-item label="总任务数">
+			<el-tag type="info">{{ queuestats['总任务数'] }}</el-tag>
+		</el-descriptions-item>
 
-  
-  
+		<el-descriptions-item label="待处理">
+			<el-tag type="warning">{{ queuestats['待处理'] }}</el-tag>
+		</el-descriptions-item>
 
-  
+		<el-descriptions-item label="处理中">
+			<el-tag type="primary">{{ queuestats['处理中'] }}</el-tag>
+		</el-descriptions-item>
 
-  
+		<el-descriptions-item label="成功">
+			<el-tag type="success">{{ queuestats['成功'] }}</el-tag>
+		</el-descriptions-item>
 
-  
+		<el-descriptions-item label="失败">
+			<el-tag type="danger">{{ queuestats['失败'] }}</el-tag>
+		</el-descriptions-item>
 
+		<el-descriptions-item label="操作">
+			<el-button type="danger" size="small" @click="stopQueueclick" :loading="isLoading" :disabled="isLoading">全部停止处理</el-button>
+			<el-button type="primary" size="small" @click="handleViewQueue" :loading="isLoading">任务列表</el-button>
+		</el-descriptions-item>
+	</el-descriptions>
+		
+	<el-dialog
+	  v-model="queueDialogVisible"
+	  :before-close="queueDialog"
+	  title="队列任务详情"
+	  width="700px"
+	  destroy-on-close
+	>
+	  <div class="dialog-scroll-wrapper">
+	    <template v-if="queueData.tasks_preview && queueData.tasks_preview.length">
+	      <el-card
+	        v-for="(task, index) in queueData.tasks_preview"
+	        :key="task.id"
+	        class="task-card"
+	      >
+	        <div class="task-grid">
+	          <div><strong>任务 ID:</strong>{{ task.id }}</div>
+	          <div><strong>尝试次数:</strong>{{ task.attempts }}</div>
+	
+	          <div>
+	            <strong>状态:</strong>
+	            <el-tag :type="index === 0 ? 'success' : 'warning'">
+	              {{ index === 0 ? '处理中' : '待处理' }}
+	            </el-tag>
+	          </div>
+	
+	          <div class="task-image">
+	            <el-image
+	              style="width: 120px; height: 120px; border: 1px solid #ccc"
+	              :src="formatImageUrl(task.data.sourceDir + '/' + task.data.file_name)"
+	              fit="cover"
+	              :preview-src-list="[formatImageUrl(task.data.sourceDir + '/' + task.data.file_name)]"
+	            />
+	          </div>
+	        </div>
+	      </el-card>
+	    </template>
+	
+	    <template v-else>
+	      <div class="empty-queue">当前无任务在队列中。</div>
+	    </template>
+	  </div>
+	</el-dialog>
+
+	  
+	<br>
+	<el-table :data="tableData" border height="450" highlight-current-row="true" v-loading="loading">
+	  <el-table-column prop="id" label="ID" width="50" />
+	  <el-table-column prop="old_image_url" label="原图目录" width="360" />
+	  <el-table-column prop="new_image_url" label="出图目录" width="360" />
+	  <el-table-column prop="old_img_count" label="图片数量" width="90" />
+	  <el-table-column prop="new_image_count" label="总数量" width="80" />
+	  <el-table-column prop="queueLog_model_name" label="执行状态" width="100" />
+	  <el-table-column align="center" label="操作" width="230">
+	  <template #default="{ row, $index }" >
+	    <el-button @click="record_deleteRow(row,$index)" type="primary" size="small" 
+			 style="font-size: 16px;padding: 0px;width: 80px;">
+				查看详情
+		  </el-button>
+		  <el-button @click="packRow(row,$index)" type="primary" size="small"
+		  	 style="font-size: 16px;padding: 0px;width: 100px;">
+		  		打包压缩zip
+		    </el-button>
+	  </template>
+	  </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;">
+	    <!-- 左侧图片区域,自适应图片尺寸,可滚动查看完整图片 -->
+		
+		<div style="flex: 1; display: flex; align-items: start; justify-content: center; border: 1px solid #eee; overflow: auto; max-height: 80vh;">
+		  <template v-if="path_image_url">
+		    <el-image
+		        :src="formatImageUrl(path_image_url)"
+		        fit="contain"
+		        style="max-width: 100%; height: auto;"
+		        :preview-src-list="[formatImageUrl(path_image_url)]"
+		        :initial-index="0"
+		      />
+			  
+		    </template>
+		  <template v-else>
+			  <el-image
+			      :src="`https://chatapi.onechats.ai/mj/image/${taskId_ids}`"
+			      fit="contain"
+			      style="max-width: 100%; height: auto;"
+			      :preview-src-list="[`https://chatapi.onechats.ai/mj/image/${taskId_ids}`]"
+			      :initial-index="0"
+			    />
+		  </template>
+		</div>
+		
+	    <!-- <div style="flex: 1; display: flex; align-items: start; justify-content: center; border: 1px solid #eee; overflow: auto; max-height: 80vh;">
+	      <el-image
+	        :src="formatImageUrl(path_image_url)"
+	        fit="contain"
+	        style="max-width: 100%; height: auto;"
+	        :preview-src-list="[formatImageUrl(path_image_url)]"
+	        :initial-index="0"
+	      />
+	    </div> -->
+	
+		<!-- 图像描述弹窗内容区域 -->
+		<div style="width: 350px; white-space: pre-wrap; overflow-y: auto; max-height: 63vh; border: 1px solid #f0f0f0; padding: 10px;">
+		  <div v-html="activeDescription"></div>
+		</div>
+
+	  </div>
+	  
+	  <el-descriptions title="" :column="1" border>
+	      <el-descriptions-item v-if="img_id" label="ID">
+	          <span>{{ img_id }}</span>
+	      </el-descriptions-item>
+	  
+	      <el-descriptions-item v-if="img_id" label="模型">
+	          <span>{{ model }}</span>
+	      </el-descriptions-item>
+	  
+
+
+		<template v-if="path_image_url">
+	      <el-descriptions-item label="图片路径" width="50">
+	          <span>{{ path_image_url }}</span>
+	      </el-descriptions-item>
+		</template>
+		<template v-else>
+			<el-descriptions-item label="图片路径" width="50">
+			  <span>https://chatapi.onechats.ai/mj/image/{{taskId_ids}}</span>
+			</el-descriptions-item>
+		</template>
+
+
+	      
+		  
+		  <template v-if="path_image_url">
+		
+		  </template>
+		  <template v-else>
+			  <el-descriptions-item label="模型主图ID" width="50">
+			  <span>{{ taskId_ids }}</span>
+			  <!-- <el-button type="primary" @click="image_seed('1')" style="margin-left: 60px;">获取图一</el-button>
+			  <el-button type="primary" @click="image_seed('2')" style="margin-left: 10px;">获取图二</el-button>
+			  <el-button type="primary" @click="image_seed('3')" style="margin-left: 10px;">获取图三</el-button>
+			  <el-button type="primary" @click="image_seed('4')" style="margin-left: 10px;">获取图四</el-button> -->
+			  </el-descriptions-item>
+		  </template>
+		  
+	  </el-descriptions>
+	</el-dialog>
+	
+	<el-dialog
+	  v-model="TaskqueueVisible"
+	  :before-close="TaskqueueDialog"
+	  title=""
+	  width="95%"
+	  top="4vh"
+	  destroy-on-close
+	>
+		<el-table
+		  :data="table_Taskqueue"
+		  row-key="id"
+		  border
+		  style="width: 100%; height: 60vh;"
+		  v-loading="loading"
+		  highlight-current-row
+		  tooltip-effect="dark"
+		  :row-style="{ height: '40px' }"
+		  :cell-style="{ padding: '4px' }"
+		  :header-cell-style="{ padding: '4px' }"
+		  :header-row-style="{ height: '40px' }"
+		  @selection-change="SelectionChange"
+		  :show-overflow-tooltip="true"
+		>
+		<el-table-column type="selection" width="60" align="center" />
+		<el-table-column prop="id" label="任务ID" width="100" align="center" />
+		<el-table-column prop="task_id" label="子任务ID" width="100" align="center" />
+		<el-table-column prop="log" label="状态" width="160" align="center" />
+		</el-table>
+	</el-dialog>
+	
+	<!-- 模版页面 -->
+	<el-dialog v-model="ListTemplate_Visible"
+		  :before-close="ListTemplateDialog"
+		  title="" width="90%"
+		  style="height: 90%;margin: 2%;padding: 0px;"
+		  top="2vh" destroy-on-close>
+		  <div class="page-container">
+		    <el-descriptions :column="2" border class="queue-status-box">
+		      <!-- 模版选择器 -->
+		      <el-descriptions-item label="选择" :span="2">
+		        <el-row :gutter="10" align="middle">
+		  			
+		          <el-col :span="6">
+		            <el-select v-model="selectedId" placeholder="请选择模版" @change="loadTemplateDetail">
+		              <el-option
+		                v-for="tpl in templateList"
+		                :key="tpl.id"
+		                :label="'模版 ' + tpl.id + (tpl.ids === 1 ? '(使用中)' : '')"
+		                :value="tpl.id"
+		              />
+		            </el-select>
+		          </el-col>
+		          <el-col :span="3">
+		            <el-button type="primary" @click="createNewTemplate">新增模版</el-button>
+		          </el-col>
+		          <el-col :span="4">
+		            <el-button type="success" @click="onsetActive" :disabled="selectedId === usedId">设为当前使用模版</el-button>
+		          </el-col>
+		        </el-row>
+		      </el-descriptions-item>
+		  
+		      <!-- 图生文模版输入区域 -->
+		      <el-descriptions-item label="图生文模版" :span="2">
+		        <textarea
+		          v-model="textareaContent"
+		          placeholder="请输入提示词"
+		          rows="10"
+		          class="custom-textarea"
+		          @keydown.tab.prevent="insertTab"
+		        ></textarea>
+		      </el-descriptions-item>
+		  
+		      <!-- 文生文模版输入区域 -->
+		      <el-descriptions-item label="文生文模版" :span="2">
+		        <textarea
+		          v-model="english_content"
+		          placeholder="请输入提示词"
+		          rows="10"
+		          class="custom-textarea"
+		          @keydown.tab.prevent="insertTab"
+		        ></textarea>
+		      </el-descriptions-item>
+		  
+		      <!-- 出图尺寸输入区域 -->
+		      <el-descriptions-item label="出图尺寸" :span="2">
+		        <el-row :gutter="10" align="middle">
+		          <el-col :span="4">
+		            <el-input
+		              v-model="width"
+		              placeholder="宽度"
+		              size="small"
+		              type="number"
+		              min="1"
+		            />
+		          </el-col>
+		          <el-col :span="1" style="text-align: center;">×</el-col>
+		          <el-col :span="4">
+		            <el-input
+		              v-model="height"
+		              placeholder="高度"
+		              size="small"
+		              type="number"
+		              min="1"
+		            />
+		          </el-col>
+		        </el-row>
+		      </el-descriptions-item>
+		  
+		      <!-- 操作按钮 -->
+		      <el-descriptions-item label="操作" :span="2">
+		        <el-button type="primary" @click="saveTemplate" :loading="mb_isLoading">
+		          保存模版
+		        </el-button>
+				<el-button type="danger" title="" @click="ListTemplateDialog">关 闭</el-button>
+		      </el-descriptions-item>
+		    </el-descriptions>
+		  </div>
+	</el-dialog>
+
+	<!-- 查看详情页面 -->
+	<el-dialog v-model="mlinventoryVisible"
+	  :before-close="mlcloseDialog"
+	  title="" width="100%"
+	  style="height: 100%;margin: 0px;"
+	  top="2vh" destroy-on-close>
+	  <div class="dialog-body">
+		  
+	    <!-- 左侧-->
+	    <div class="dialog-left">
+	      <el-form ref="elSearchFormRef" class="demo-form-inline">
+	        <el-form-item>
+			  <el-button type="danger" title="" @click="details_close">关 闭</el-button>&nbsp;&nbsp;
+			  <el-button type="primary" title="" @click="Refresh_Status" :loading="isLoading">刷新执行状态</el-button>&nbsp;&nbsp;&nbsp;
+			  
+			  <el-button type="primary" title="" @click="ListTemplate_model" :loading="isLoading">查看模版</el-button>&nbsp;&nbsp;&nbsp;
+			  
+			  <span>选择状态:</span>
+	          <el-select
+	            v-model="filterStatus"
+	            placeholder="全部"
+	            @change="handleFilterChange"
+	            style="width: 120px;" >
+	            <el-option label="全部" value="全部" />
+				<el-option label="已出图" value="已出图" />
+	            <el-option label="未出图" value="未出图" />
+				<el-option label="已图生文" value="图生文" />
+				<el-option label="已文生文" value="文生文" />
+				<el-option label="已文生图" value="文生图" />
+				<el-option label="已图生图" value="图生图" />
+				<el-option label="已高清放大" value="高清放大" />
+				<el-option label="未图生文" value="未图生文" />
+				<el-option label="未文生文" value="未文生文" />
+				<el-option label="未文生图" value="未文生图" />
+				<el-option label="未图生图" value="未图生图" />
+	          </el-select>
+	        </el-form-item>
+	      </el-form>
+	
+	      <el-table
+	        :data="tableData_lsit"
+	        row-key="id"
+	        border
+	        style="width: 97%; height: 77vh;"
+	        v-loading="loading"
+	        highlight-current-row
+	        tooltip-effect="dark"
+	        :row-style="{ height: '0px' }"
+	        :cell-style="{ padding: '0px' }"
+	        :header-cell-style="{ padding: '0px' }"
+	        :header-row-style="{ height: '0px' }"
+	        @selection-change="SelectionChange"
+	        :show-overflow-tooltip="true"
+	        @row-click="handleRowClick"
+	      >
+	        <el-table-column type="selection" width="50" align="center" />
+	        <el-table-column prop="id" label="序号" width="59" align="center" />
+	        <el-table-column prop="ids" label="ID" width="70" align="center" />
+	      <el-table-column label="状态" width="83" align="center">
+	        <template #default="{ row }">
+	          <el-tag v-if="row.status === 1" type="success">已出图</el-tag>
+	          <el-tag v-else type="danger">未出图</el-tag>
+	        </template>
+	      </el-table-column>
+	        <el-table-column prop="status_name" label="操作" width="69" 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">
+	          <template #default="{ row }">
+	            <img
+	              :src="formatImageUrl(row.path)"
+	              style="width: 90px; height: 70px; object-fit: contain; cursor: pointer;"
+	              @click="showDescription(row, 'old')"
+	            />
+	          </template>
+	        </el-table-column>
+			
+			<el-table-column label="原图尺寸" width="120" align="center">
+			  <template #default="{ row }">
+			    {{ row.width }} x {{ row.height }}
+			  </template>
+			</el-table-column>
+	      </el-table>
+	
+	      <div class="gva-pagination">
+	        <el-pagination
+			style="margin-right: 40px;"
+	          @size-change="handleSizeChange"
+	          @current-change="handleCurrentChange"
+	          :current-page="page"
+	          :page-sizes="[10, 30, 50, 100, 500,1000]"
+	          :page-size="pageSize"
+	          layout="total, sizes, prev, pager, next"
+	          :total="total"
+	        />
+	      </div>
+	    </div>
+	
+	    <!-- 右侧 -->
+	    <div class="dialog-right">
+	      <div class="dialog-right-scroll">
+	        <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" :loading="isLoading" title="选择图片,执行图生文" @click="imgtotext" >图生文</el-button>
+						<el-button type="primary" :loading="isLoading" title="选择图片,执行文生文" @click="texttotxt" >文生文</el-button>
+						<el-button type="primary" :loading="isLoading" title="选择图片,执行执行文生图" @click="texttoimg" >文生图</el-button>
+						<el-button type="primary" :loading="isLoading" title="选择图片,执行图生图" @click="imgtoimg" >图生图</el-button>
+						<el-button type="primary" :loading="isLoading" title="选择图片,执行图像高清放大处理" @click="singleimg" >图像高清放大处理</el-button>
+						<el-button type="primary" :loading="isLoading" title="选中图片,执行顺序:图生文->文生文->文生图->图生图->高清放大" @click="handleSelected"  :disabled="isLoading">执选择任务</el-button>
+						<el-button type="primary" :loading="isLoading" title="执行当前所有图片,执行顺序:图生文->文生文->文生图->图生图->高清放大" @click="handleAll" >执行全部任务</el-button>
+					</el-descriptions-item>
+					
+					    <el-descriptions-item label="图生文模型">
+					      <div style="display: flex; align-items: center; gap: 20px;">
+					        <el-radio-group v-model="imgtotxtselectedModel" @change="handleModelChange">
+					          <el-radio 
+					            v-for="item in imgtotxt_modelList" 
+					            :key="item.id"
+					            :label="item.imgtotxt">
+					            {{ item.imgtotxt }} 
+					            <span v-if="item.id === usedIds.tushengwen" style="color: #67C23A; margin-left: 5px;">(默认使用)</span>
+					          </el-radio>
+					        </el-radio-group>
+					      </div>
+					      <el-button type="success" @click="setActive('tushengwen')" :disabled="!selectedIds.tushengwen || selectedIds.tushengwen === usedIds.tushengwen">
+					        设为默认使用模型
+					      </el-button>
+					    </el-descriptions-item>
+					
+					    <el-descriptions-item label="文生文模型">
+					      <div style="display: flex; align-items: center; gap: 20px;">
+					        <el-radio-group v-model="txttotxtselectedModel" @change="handleModelChange">
+					          <el-radio 
+					            v-for="item in txttotxt_modelList" 
+					            :key="item.id"
+					            :label="item.txttotxt">
+					            {{ item.txttotxt }} 
+					            <span v-if="item.id === usedIds.wenshengwen" style="color: #67C23A; margin-left: 5px;">(默认使用)</span>
+					          </el-radio>
+					        </el-radio-group>
+					      </div>
+					      <el-button type="success" @click="setActive('wenshengwen')" :disabled="!selectedIds.wenshengwen || selectedIds.wenshengwen === usedIds.wenshengwen">
+					        设为默认使用模型
+					      </el-button>
+					    </el-descriptions-item>
+					
+					    <el-descriptions-item label="文生图模型">
+					      <div style="display: flex; align-items: center; gap: 20px;">
+					        <el-radio-group v-model="txtimgselectedModel" @change="handleModelChange">
+					          <el-radio 
+					            v-for="item in txttoimg_modelList" 
+					            :key="item.id"
+					            :label="item.txttoimg">
+					            {{ item.txttoimg }} 
+					            <span v-if="item.id === usedIds.wenshengtu" style="color: #67C23A; margin-left: 5px;">(默认使用)</span>
+					          </el-radio>
+					        </el-radio-group>
+					      </div>
+					      <el-button type="success"  @click="setActive('wenshengtu')"  :disabled="!selectedIds.wenshengtu || selectedIds.wenshengtu === usedIds.wenshengtu">
+					        设为默认使用模型
+					      </el-button>
+					    </el-descriptions-item>
+					  
+					  
+					  <el-descriptions-item label="是否执行">
+					     <el-checkbox v-model="executeKeywords">
+					             执行几何图
+					     </el-checkbox>
+					   </el-descriptions-item>
+					  
+					
+					<el-descriptions-item label="出图预览">
+					<div style="display: flex; gap: 20px; align-items: flex-start;">
+					  <!-- 左侧:图片列表区域 -->
+					  <div style="flex: 1;">
+						  
+						  <div class="image-preview-wrap" style="height: 140px;">
+						    <template v-if="taskId_ids">
+						      <div 
+						        class="image-item" 
+								@click="showDescription('new',`https://chatapi.onechats.ai/mj/image/${taskId_ids}`)"
+						      >
+						        <el-image
+						          :src="`https://chatapi.onechats.ai/mj/image/${taskId_ids}`"
+						          fit="contain"
+						          style="max-width: 100%; height: auto;"
+						          :initial-index="0"
+						        />
+						        <span class="image-dimension">2048x2048</span>
+						      </div>
+						    </template>
+						    <template v-else>
+						      <div class="image-grid">
+						        <div
+						          v-for="(img, index) in imageList"
+						          :key="`image-item-${index}`"
+						          class="image-item"
+						          @click="showDescription(img, 'new')"
+						        >
+						          <img :src="formatImageUrl(img.new_image_url)"/>
+						          <span class="image-dimension">1024x1024</span>
+						        </div>
+						      </div>
+						    </template>
+						  </div>
+						  
+						<div class="image-preview-wrap" style="margin-top: 16px; height: 167px;">
+						  <div
+							v-for="(img, index) in imageList"
+							:key="'imgtoimg-' + index"
+							class="image-itemsimg"
+							@click="showDescription(img, 'san')"
+						  >
+							<img :src="formatImageUrl(img.imgtoimg_url)" />图生图</div>
+						</div>
+						
+						<div class="image-preview-wrap" style="margin-top: 16px; height: 140px;">
+						  <div
+							v-for="(img, index) in imageList"
+							:key="'custom-' + index"
+							class="image-items"
+							@click="showDescription(img, 'custom')"
+						  >
+							<img :src="formatImageUrl(img.custom_image_url)" />
+							高清放大
+						  </div>
+						</div>
+					  </div>
+		
+					  <!-- 右侧:文字描述区域 -->
+					  <div
+						style="
+						  width: 700px;
+						  white-space: pre-wrap;
+						  overflow-y: auto;
+						  max-height: 60vh;
+						  border: 1px solid #f0f0f0;
+						  padding: 10px 80px 10px 10px;
+						"
+					  >
+					  <p>第一段(文生图 文字修改区)</p>
+					  <el-input
+					    type="textarea"
+					    v-model="yi_activeDescription"
+					    :rows="6"
+					  />
+					  <p>第二段(文生图 风格修改区)</p>
+					  <el-input
+					    type="textarea"
+					    v-model="er_activeDescription"
+					    :rows="6"
+					  />
+					  <p>图片名称</p>
+					  <el-input
+					    type="textarea"
+					    v-model="name_activeDescription"
+					    :rows="2"
+					  />
+					  <el-button type="primary" @click="submitEdit" style="margin-top: 20px;">修改</el-button>
+					  </div>
+					</div>
+				  </el-descriptions-item>
+					
+	
+	              <el-descriptions-item label="出图尺寸">
+	                <div style="display: flex; align-items: center; flex-wrap: wrap; gap: 12px;">
+	                  <el-input v-model="width" placeholder="宽度" size="small" style="width: 80px;" type="number" min="1" />
+	                  <span style="font-weight: bold;">×</span>
+	                  <el-input v-model="height" placeholder="高度" size="small" style="width: 80px;" type="number" min="1" />
+	                </div>
+	              </el-descriptions-item>
+	
+	         <!--     <el-descriptions-item label="执行次数">
+	                <el-input-number v-model="num" :step="1" />
+	              </el-descriptions-item> -->
+				  
+				  <el-descriptions-item label="任务队列">
+				    <el-table 
+					  :data="table_queue" border
+					  :show-overflow-tooltip="true"
+					  v-loading="loading"
+					  tooltip-effect="dark"
+					  :row-style="{ height: '30px' }"
+					  :cell-style="{ padding: '2px' }"
+					  :header-cell-style="{ padding: '0px' }"
+					  :header-row-style="{ height: '30px' }"
+					  style="width: 100%; height: 21vh;"
+					 >
+				      <el-table-column prop="id" label="ID" width="50" />
+				      <el-table-column prop="status" label="状态" width="100" />
+				      <el-table-column prop="model" label="队列模型" width="170" />
+					  <el-table-column prop="model_name" label="队列模型" width="90" />
+					  <el-table-column prop="image_count" label="执行数量" width="90" />
+					  <el-table-column prop="排队中的数量" label="队列中" width="70" />
+					  <el-table-column prop="处理中数量" label="处理中" width="70" />
+					  <el-table-column prop="已完成数量" label="成功" width="70" />
+					  <el-table-column prop="失败数量" label="失败" width="70" />
+				    </el-table>
+				  </el-descriptions-item>
+				 
+	            </el-descriptions>
+	          </el-form>
+	        </el-card>
+	      </div>
+	    </div>
+	  
+	  
+	  </div>
+	</el-dialog>
+	
+  </div>
+</template>
+
+<script setup>
+import {ref,reactive,toRaw} from 'vue'
+import {ElMessage, ElMessageBox,ElLoading } from 'element-plus'
+import axios from 'axios'
+import {Plus,Delete,CircleCheck,CircleClose} from '@element-plus/icons-vue'
+import {getPreviewSubDirs,queueStats,stopQueueProcesses, viewQueueStatus,ImgUpload,getPreviewimg,getlsit,
+imageToText,txttoimg_moxing,txttoimg_update,
+textToImage,Template_ids,sd_models,getSide,
+TemplateList,
+Template,
+updatetemplate,getPreviewFolders,
+setActiveTemplate,
+packImagess,getUploadPath,get_queue_logs,getTaskProgress
+} from '@/api/ai/aiimg'
+import { useUserStore } from '@/pinia/modules/user';
+
+//获取登录用户信息
+const userStore = useUserStore()
+const _username = ref('')
+_username.value = userStore.userInfo.userName + '/' + userStore.userInfo.nickName
+
+//获取服务器地址
+const formatImageUrl = (path) => {
+  if (!path) return ''
+  const base = 'http://20.0.16.53:9093'
+  return `${base}/${path.replace(/^public\//, '')}`
+}
+
+// --------------------- 图片上传 ---------------------
+const tableData = ref([])
+const getPreviewSubDirslist = async () => {
+	const res = await getPreviewSubDirs()
+	console.log('getPreviewSubDirs',res.data.data)
+	const processedData = res.data.data.map(item => {
+	  return {
+	    ...item,
+	    new_image_url: `${item.new_image_url}${item.name}/`
+	  };
+	});
+	tableData.value = processedData;
+	console.log(tableData.value)
+}
+getPreviewSubDirslist()
+
+// 环境配置
+const basePath = import.meta.env.VITE_BASE_PATH || 'http://20.0.16.53'
+const uploadsPort = import.meta.env.VITE_UPLOADS_PORT || '9093'
+const uploadUrl = ref(`${basePath}:${uploadsPort}/api/Facility/ImgUpload`)
+const uploadHeaders = { 
+  'Content-Type': 'multipart/form-data',
+  'Authorization': 'Bearer ' + localStorage.getItem('token')
+}
+
+// 文件列表
+const fileList = ref([])
+const uploadRef = ref(null)
+
+// 获取本地文件URL
+const getObjectUrl = (file) => {
+  return URL.createObjectURL(file)
+}
+
+// 上传前校验
+const beforeUpload = (file) => {
+  const isImage = file.type === 'image/jpeg' || file.type === 'image/png'
+  const isLt5M = file.size / 1024 / 1024 < 5 // 限制5MB
   
-  
-  
-  
-  
-  </script>
-  
-  <style scoped>
-  .form-container {
-    display: flex;
-    flex-wrap: wrap;
+  if (!isImage) {
+    ElMessage.error('只能上传 JPG/PNG 格式的图片!')
+    return false
   }
   
-  .form-column {
-    /*flex: 1;*/
-    margin-right: 15px; /* 调整列之间的间距 */
+  if (!isLt5M) {
+    ElMessage.error('图片大小不能超过 5MB!')
+    return false
   }
   
-  /* 左侧输入框宽度调整 */
-  .form-column .el-form-item .el-input {
-    width: 150px; /* 调整左侧输入框的宽度 */
-  }
+  // 显示加载中
+  const loading = ElLoading.service({
+    lock: true,
+    text: '正在上传图片...',
+    background: 'rgba(0, 0, 0, 0.7)'
+  })
   
-  :deep(.hui-plan-usage-lows  div) {
-    color: #8c939d !important;
-  }
-  :deep(.lan-plan-usage-lows  div) {
-    color: blue !important;
-    font-weight: bold;
-  }
+  // 将loading实例附加到file对象上,以便后续关闭
+  file.loadingInstance = loading
   
+  return true
+}
+
+// 自定义上传逻辑
+const customUpload = async (options) => {
+  const { file, onProgress, onSuccess, onError } = options
+  try {
+    const formData = new FormData()
+    formData.append('image', file)
+    const response = await axios.post(uploadUrl.value, formData, {
+      headers: uploadHeaders,
+      onUploadProgress: (progressEvent) => {
+        const percent = Math.round(
+          (progressEvent.loaded * 100) / progressEvent.total
+        )
+        onProgress({ percent }, file)
+      },
+      timeout: 60000 // 60秒超时
+    })
 
-  /* 媒体查询,根据需要调整断点 */
-  @media screen and (max-width: 768px) {
-    .form-column {
-      flex: 1 0 100%; /* 在小屏幕下变成单列布局 */
-      margin-right: 0;
+  } catch (error) {
+    
+  } finally {
+    // 关闭加载中
+    if (file.loadingInstance) {
+      file.loadingInstance.close()
     }
   }
-  /*:deep(.el-table td .cell) {*/
-  /*  line-height: 30px !important;*/
-  /*}*/
-  .JKWTree-container {
-    display: flex;
+}
+
+// 预览图片
+const handlePreview = (file) => {
+  if (file.url) {
+    window.open(file.url, '_blank')
+  } else if (file.raw) {
+    const url = getObjectUrl(file.raw)
+    window.open(url, '_blank')
+    URL.revokeObjectURL(url) // 释放内存
   }
-  .JKWTree-tree {
-    /*width: 300px;*/
-    background-color: #fff;
-    padding: 10px;
-    margin-right: 20px;
+}
+
+// 上传成功
+const handleSuccess = (response, file, fileList) => {
+  getPreviewSubDirslist()
+  file.loadingInstance?.close()
+}
+
+// 上传失败
+const handleError = (error, file, fileList) => {
+  console.error('上传错误:', error)
+  ElMessage.error(`${file.name} 上传失败`)
+  file.loadingInstance?.close()
+}
+
+// 超出限制
+const handleExceed = (files, fileList) => {
+  ElMessage.warning(`最多只能上传 30 张图片,您已选择 ${files.length} 张,共 ${files.length + fileList.length} 张`)
+}
+
+
+// --------------------- 查看队列任务 ---------------------
+const queuestats = ref({
+  总任务数: 0,
+  待处理: 0,
+  处理中: 0,
+  成功: 0,
+  失败: 0
+})
+//队列状态
+const queueStats_list = async () => {
+	const res = await queueStats()
+	console.log(res)
+	if (res.code === 0) {
+	    queuestats.value = res.data
+	  }
+}
+queueStats_list()
+
+//停止处理
+const stopQueueLoading = ref(false)
+const stopQueueclick = async () => {
+  if (stopQueueLoading.value) return
+  try {
+    await ElMessageBox.confirm(
+      '确定要停止所有队列任务吗?',
+      '确认操作',
+      {
+        confirmButtonText: '清空队列',
+        cancelButtonText: '取消',
+        type: 'warning',
+      }
+    )
+    stopQueueLoading.value = true
+    const res = await stopQueueProcesses()
+    if (res.code === 0) {
+      ElMessage.success(res.msg || '已成功停止队列任务')
+    }
+  } catch (err) {
+    if (err !== 'cancel') {
+      ElMessage.error('操作失败,请稍后重试')
+    }
+  } finally {
+    stopQueueLoading.value = false
   }
-  .JKWTree-tree h3 {
-    font-size: 15px;
-    font-weight: 700;
-    margin: 10px 0;
+}
+
+//任务列表
+const queueDialogVisible = ref(false)
+// 队列数据
+const queueData = ref({
+  tasks_preview: [],
+  count: 0
+})
+const QueueStatusisLoading = ref(false)
+// 任务列表按钮
+const handleViewQueue = async () => {
+	queueStats_list()
+	getPreviewSubDirslist()
+	QueueStatusisLoading.value = true
+  try {
+    const res = await viewQueueStatus()
+    if (res.code === 0) {
+      queueData.value = res
+      queueDialogVisible.value = true
+    } else {
+      ElMessage.error(res.msg || '查询失败')
+    }
+  } catch (err) {
+    ElMessage.error('请求异常')
+  } finally {
+    QueueStatusisLoading.value = false
   }
-  .JKWTree-content {
-    flex: 1;
+}
+const queueDialog = async () => {
+	queueDialogVisible.value = false
+}
+
+// --------------------- 查看详情 ---------------------
+const fetchPreviewImages = async () => {
+  loading.value = true;
+  const params = {
+	sys_id:userStore.userInfo.nickName,
+    path: _resrow.value.old_image_url,
+    page: page.value,
+    limit: pageSize.value
+  };
+	
+  if (filterStatus.value === '已出图') {
+    params.status = 1
+  } else if (filterStatus.value === '未出图') {
+    params.status = 0
+  }else if(filterStatus.value === '图生文') {
+	  params.status_name = "图生文"
+  }else if(filterStatus.value === '未图生文') {
+	  params.status_name = "未图生文"
+  }else if(filterStatus.value === '文生文') {
+	  params.status_name = "文生文"
+  }else if(filterStatus.value === '未文生文') {
+	  params.status_name = "未文生文"
+  }else if(filterStatus.value === '文生图') {
+	  params.status_name = "文生图"
+  }else if(filterStatus.value === '未文生图') {
+	  params.status_name = "未文生图"
+  }else if(filterStatus.value === '图生图') {
+	  params.status_name = "图生图"
+  }else if(filterStatus.value === '未图生图') {
+	  params.status_name = "未图生图"
+  }else if(filterStatus.value === '高清放大') {
+	  params.status_name = "高清放大"
   }
+console.log("params",params)
+  // 获取分页数据
+  const res = await getPreviewimg(params);
+console.log("getPreviewimg",res.data.data)
+  if (res.data.code === 0) {
+    tableData_lsit.value = res.data.data;
+    total.value = res.data.total;
+  }
+  loading.value = false;
+};
+
+// 分页
+const page = ref(1)
+const total = ref(0)
+const pageSize = ref(50)
+// 页码变化
+const handleCurrentChange = (val) => {
+  page.value = val;
+  fetchPreviewImages();
+};
+
+// 每页数量变化
+const handleSizeChange = (val) => {
+  pageSize.value = val;
+  page.value = 1;
+  fetchPreviewImages();
+};
+
+//---------------选择框----------------
+const filterStatus = ref('全部')
+const handleFilterChange = () => {
+  // console.log('当前选择状态:', filterStatus.value);
+  page.value = 1;
+  fetchPreviewImages();
+};
+
+const mlinventoryVisible = ref(false)
+//关闭查看详情页面
+const details_close = async () => {
+	mlinventoryVisible.value = false;
+}
+
+const loading = ref(false)
+const width = ref('')
+const height = ref('')
+const mlformdata = ref({})
+const tableData_lsit = ref([])
+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 txttoimg_modelList = ref([]);
+const txtimgselectedModel = ref('');
+const imgtotxt_modelList = ref([]);
+const imgtotxtselectedModel = ref('');
+const txttotxt_modelList = ref([]);
+const txttotxtselectedModel = ref('');
+
+// 当前使用和选择的ID
+const usedIds = ref({
+  wenshengwen: null,
+  tushengwen: null,
+  wenshengtu: null
+});
+
+const selectedIds = ref({
+  wenshengwen: null,
+  tushengwen: null,
+  wenshengtu: null
+});
+
+
+//查看详情按钮
+const record_deleteRow = async (row) => {
+	//打开弹窗
+	mlinventoryVisible.value = true;
+	
+	//获取当前文件夹行信息
+	_resrow.value = row;
+	
+	//清空信息保持数据最新
+	imageList.value = []
+	img_id.value = '';
+	model.value = '';
+	new_image_url.value = '';
+	imgtoimg_url.value = '';
+	path_image_url.value = '';
+	activeDescription.value =  '';
+	yi_activeDescription.value =  '';
+	er_activeDescription.value =  '';
+	name_activeDescription.value =  '';
+	taskId_ids.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.data;
+	
+	//获取图出图自定义尺寸
+	const TemplateList_res = await TemplateList({path:row['old_image_url']})
+	
+	
+	const res = await Template_ids({path:row['old_image_url']});
+	height.value = res.data.data.height
+	width.value = res.data.data.width
+	
+	// 获取模型列表
+	const response = await txttoimg_moxing();
+	// 设置模型列表
+	imgtotxt_modelList.value = response.data.data.models.tushengwen;
+	txttotxt_modelList.value = response.data.data.models.wenshengwen;
+	txttoimg_modelList.value = response.data.data.models.wenshengtu;
+
+	// 设置当前使用的ID
+	usedIds.value = response.data.data.used_ids;
 
+	// 设置默认选中的模型
+	if (txttoimg_modelList.value.length > 0) {
+		const defaultModel = txttoimg_modelList.value.find(item => item.id === usedIds.value.wenshengtu);
+		if (defaultModel) {
+		  txtimgselectedModel.value = defaultModel.txttoimg;
+		  selectedIds.value.wenshengtu = defaultModel.id;
+		}
+	}
+
+	if (imgtotxt_modelList.value.length > 0) {
+		const defaultModel = imgtotxt_modelList.value.find(item => item.id === usedIds.value.tushengwen);
+		if (defaultModel) {
+		  imgtotxtselectedModel.value = defaultModel.imgtotxt;
+		  selectedIds.value.tushengwen = defaultModel.id;
+		}
+	}
+
+	if (txttotxt_modelList.value.length > 0) {
+		const defaultModel = txttotxt_modelList.value.find(item => item.id === usedIds.value.wenshengwen);
+		if (defaultModel) {
+		  txttotxtselectedModel.value = defaultModel.txttotxt;
+		  selectedIds.value.wenshengwen = defaultModel.id;
+		}
+	}
+
+	await fetchPreviewImages();
+}
+
+// 当选择模型变化时
+const handleModelChange = (modelName) => {
+  // 更新文生图模型选择
+    const txttoimg_model = txttoimg_modelList.value.find(item => item.txttoimg === modelName);
+    if (txttoimg_model) {
+      selectedIds.value.wenshengtu = txttoimg_model.id;
+    }
+    
+    // 更新图生文模型选择
+    const imgtotxt_model = imgtotxt_modelList.value.find(item => item.imgtotxt === modelName);
+    if (imgtotxt_model) {
+      selectedIds.value.tushengwen = imgtotxt_model.id;
+    }
+    
+    // 更新文生文模型选择
+    const txttotxt_model = txttotxt_modelList.value.find(item => item.txttotxt === modelName);
+    if (txttotxt_model) {
+      selectedIds.value.wenshengwen = txttotxt_model.id;
+    }
   
-  /* 选中某行时的背景色 */
-  :deep(.el-table__body tr.current-row) > td {
-    background: #ff80ff !important;
-  }
-  </style>
-  <style scoped>
-  :deep(.el-table td .cell) {
-    line-height: 20px !important;
+}
+//设置模型
+const setActive = async (type) => {
+  const id = selectedIds.value[type];
+    if (id) {
+      const result = await txttoimg_update({type:type,id: id});
+      if (result.code === 0) {
+        usedIds.value[type] = id;
+        ElMessage.success('设置成功');
+        
+        // 重新加载模型列表以更新状态
+        const response = await txttoimg_moxing();
+        usedIds.value = response.data.used_ids;
+      } else {
+        ElMessage.error('设置失败');
+      }
+    }
+}
+
+
+const record_queueRow = async (row) => {
+	TaskqueueVisible.value = true;
+	
+	console.log(row['id'])
+	const getTaskProgress_data = await getTaskProgress({ id: row['id'] });
+	table_Taskqueue.value = getTaskProgress_data.data.data;
+}
+
+const TaskqueueDialog = async (row) => {
+	TaskqueueVisible.value = false;
+}
+
+
+const imageList = ref([]);
+const _oldrow = ref('');
+const old_path = ref('');
+const ids = ref('');
+//点击当前行
+const handleRowClick = async (row) => {
+	imgtoimg_url.value = ''
+	activeDescription.value = ''
+	yi_activeDescription.value =  '';
+	er_activeDescription.value =  '';
+	name_activeDescription.value =  '';
+	// fetchPreviewImages();
+	
+	console.log("当前行信息",row)
+	
+	// 文本内容高亮处理
+	const zh = highlightKeywords(row['chinese_description'] || '');
+	const en = highlightKeywords(row['english_description'] || '');
+	const name = highlightKeywords(row['img_name'] || '');
+	
+	activeDescription.value = `第一段:\n${zh}\n\n第二段:\n${en}\n\n第三段:\n${name}`;
+	yi_activeDescription.value =  zh;
+	er_activeDescription.value =  en;
+	name_activeDescription.value =  name;
+	
+	_oldrow.value = row
+	taskId_ids.value = row['taskId']
+	old_path.value = row['path']
+	ids.value = row['ids']
+
+	const res = await getlsit({sys_id:userStore.userInfo.nickName, path: row['path'] });
+	if (res.data === null) {
+		imageList.value = [];
+	} else {
+		imageList.value = res.data.map(item => ({
+		  id: item.id,
+		  taskId: item.taskId,
+		  model: item.model,
+		  chinese_description: item.chinese_description,
+		  english_description: item.english_description,
+		  img_name: item.img_name,
+		  new_image_url: item.new_image_url,
+		  imgtoimg_url:item.imgtoimg_url,
+		  custom_image_url: item.custom_image_url,
+		  size: item.size
+		}));
+		const queue_logs = await get_queue_logs({ old_image_file: _resrow.value['old_image_url'] });
+		table_queue.value = queue_logs.data;
+	}
+};
+
+//关闭按钮
+const mlcloseDialog = () => {
+  mlinventoryVisible.value = false
+}
+
+const submitEdit = async () => {
+    const payload = {
+      id:ids.value,
+      chinese_description:yi_activeDescription.value,
+      english_description:er_activeDescription.value,
+      img_name:name_activeDescription.value
+    };
+    await getSide(payload);
+    ElMessage.success('修改成功');
+	Refresh_Status()
+};
+
+
+const ListTemplate_Visible = ref(false)
+// 模版状态数据
+const templateList = ref([])
+const selectedId = ref(null)
+const usedId = ref(null)
+
+const path_templateList = ref([])
+const path_selectedId = ref(null)
+
+// 模版内容
+const textareaContent = ref('')
+const english_content = ref('')
+// const height = ref('')
+// const width = ref('')
+const mb_isLoading = ref(false)
+
+const ListTemplate_model = async () => {
+	ListTemplate_Visible.value = true
+	console.log(_resrow.value['old_image_url'])
+	const res = await TemplateList({path:_resrow.value['old_image_url']})
+	console.log("TemplateList",res.data.data.list)
+	console.log("TemplateList",res.data.data.usedId)
+	templateList.value = res.data.data.list
+	usedId.value = res.data.data.usedId
+	selectedId.value = usedId.value
+	await loadTemplateDetail(selectedId.value)
+}
+//获取模版列表后将默认模版显示
+const loadTemplateDetail = async (id) => {
+	if(id){
+		const res = await Template({ id })
+		textareaContent.value = res.data.data.content
+		english_content.value = res.data.data.english_content
+		width.value = res.data.data.width
+		height.value = res.data.data.height
+	}
+}
+// 新增模版按钮
+const createNewTemplate = () => {
+  selectedId.value = null
+  textareaContent.value = '请输入新增模版内容'
+  english_content.value = '请输入新增模版内容'
+  width.value = '1303'
+  height.value = '1024'
+}
+
+// 保存模版(新增或更新)
+const saveTemplate = async () => {
+	
+  if (!textareaContent.value || !width.value || !height.value) {
+    ElMessage.warning('请填写完整模版内容和尺寸')
+    return
   }
-  :deep(.el-tabs__header){
-    margin-bottom: 0;
+
+  mb_isLoading.value = true
+  const res = await updatetemplate({
+    id: selectedId.value,
+	path:_resrow.value['old_image_url'],
+    textareaContent: textareaContent.value,
+    english_content: english_content.value,
+    width: width.value,
+    height: height.value
+  })
+  mb_isLoading.value = false
+
+  if (res.data.code === 0) {
+    ElMessage.success('模版保存成功')
+    loadTemplateList()
+  } else {
+    ElMessage.error('保存失败')
   }
-  .search{
-    margin-left: 0px !important;
-    margin-right: 10px !important;
+}
+
+// 设为当前模版
+const onsetActive = async () => {
+  const res = await setActiveTemplate({ id: selectedId.value,path:path_selectedId.value })
+  if (res.code === 0) {
+    ElMessage.success('已设为当前使用模版')
+    await loadTemplateList()
+  } else {
+    ElMessage.error('设置失败')
   }
-  .bt{
-    margin-left: 2px !important;
-    padding: 3px !important;
-    font-size: 12px;
+}
+
+// tab 缩进逻辑
+const insertTab = (event) => {
+  const textarea = event.target
+  const start = textarea.selectionStart
+  const end = textarea.selectionEnd
+  const isShift = event.shiftKey
+  const value = textareaContent.value
+  const before = value.substring(0, start)
+  const selected = value.substring(start, end)
+  const after = value.substring(end)
+
+  if (selected.includes('\n')) {
+    const lines = selected.split('\n')
+    const newText = lines
+      .map(line => (isShift
+        ? (line.startsWith('\t') ? line.substring(1) : line.startsWith('    ') ? line.substring(4) : line)
+        : '\t' + line))
+      .join('\n')
+    textareaContent.value = before + newText + after
+    const offset = newText.length - selected.length
+    nextTick(() => {
+      textarea.selectionStart = start
+      textarea.selectionEnd = end + offset
+    })
+  } else {
+    if (isShift && value.substring(start - 1, start) === '\t') {
+      textareaContent.value = before.slice(0, -1) + selected + after
+      nextTick(() => {
+        textarea.selectionStart = textarea.selectionEnd = start - 1
+      })
+    } else {
+      textareaContent.value = before + '\t' + selected + after
+      nextTick(() => {
+        textarea.selectionStart = textarea.selectionEnd = start + 1
+      })
+    }
   }
-  .el-tabs__header{
-    margin: 0px !important;
+
+  event.preventDefault()
+}
+//关闭按钮
+const ListTemplateDialog = () => {
+  ListTemplate_Visible.value = false
+}
+
+
+
+/**
+ * 点击图片查看显示
+*/
+const yi_activeDescription = ref('');
+const er_activeDescription = ref('');
+const name_activeDescription = ref('');
+const activeDescription = ref('');
+const path_image_url = ref('');
+const taskId_ids = ref('');
+const img_id = ref('');
+const model = ref('');
+const new_image_url = ref('');
+const imgtoimg_url = ref('');
+const showDescDialog = ref(false);
+// 高亮关键词为红色
+const highlightKeywords = (text) => {
+  const keywords = ['几何', 'geometry', 'geometric'];
+  keywords.forEach(word => {
+    const reg = new RegExp(word, 'gi');
+    text = text.replace(reg, match => `<span style="color:red">${match}</span>`);
+  });
+  return text;
+};
+
+// 显示图像描述
+const showDescription = async (img, type,url) => {
+	showDescDialog.value = true;
+	console.log(img)
+	//刷新任务队列-保持实时查看
+	Refresh_Status()
+
+	// 公共字段初始化
+	img_id.value = img.id || '';
+	model.value = img.model || '';
+	path_image_url.value = '';
+
+	// 文本内容高亮处理
+	const zh = highlightKeywords(img.chinese_description || '');
+	const en = highlightKeywords(img.english_description || '');
+	const name = highlightKeywords(img.img_name || '');
+
+	  
+  if (type === 'new') {
+	path_image_url.value = img.new_image_url || '';
+	activeDescription.value = `第一段:\n${zh}\n\n第二段:\n${en}\n\n第三段:\n${name}`;
+	imgtoimg_url.value = img.imgtoimg_url || '图片未生成';
+	taskId_ids.value = taskId_ids.value || '';
+	
+  } else if (type === 'custom') {
+	  
+    path_image_url.value = img.custom_image_url || '图片未生成';
+	activeDescription.value = `第一段:\n${zh}\n\n第二段:\n${en}\n\n第三段:\n${name}`;
+	imgtoimg_url.value = img.imgtoimg_url || '图片未生成';
+	// taskId_ids.value = '';
+	
+  }else if (type === 'san') {
+	  
+    path_image_url.value = img.imgtoimg_url || '图片未生成';
+	imgtoimg_url.value = img.imgtoimg_url || '图片未生成';
+	activeDescription.value =  '';
+	model.value =  '';
+	// taskId_ids.value = '';
+	
+  }else if (type === 'old') {
+	  
+    path_image_url.value = img.path || '暂无说明';
+	imgtoimg_url.value = '';
+	activeDescription.value = '';
+	// taskId_ids.value = '';
+	
+  } else {
+    // console.log('无效的类型');
   }
-  .gva-table-box{
-    padding: 0px !important;
+};
+
+const image_seed = async (label) => {
+	console.log(label);
+	console.log(ids.value);
+	console.log(taskId_ids.value);
+	console.log(old_path.value)
+}
+
+
+//复选框
+const _parh = ref('')
+const _queue_status = ref('')
+const SelectionChange = (rows) => {
+	_parh.value = rows.map(item => item.path);
+	_queue_status.value = rows.map(item => item.queue_status);
+};
+
+//查看详情右侧区域
+const isLoading = ref(false)
+//执行次数默认值
+const num = ref(1)
+
+//图生文模型(默认值)
+const imgtotxt_selectedOption = ref('gemini-2.5-flash-lite-preview-06-17')
+//文生文模型(默认值)
+const txttotxt_selectedOption = ref('gemini-2.0-flash')
+//文生图模型(默认值)
+const selectedOption = ref('')
+
+const executeKeywords = ref(false) // 默认未选择
+
+//刷新表格任务状态
+const Refresh_Status = async () => {
+	// 开始 loading
+	loading.value = true;
+	
+	fetchPreviewImages();
+	// 任务队列
+	const queue_logs = await get_queue_logs({ old_image_file: _resrow.value['old_image_url'] });
+	table_queue.value = queue_logs.data;
+	
+	// 延迟2秒再关闭loading
+	await new Promise(resolve => setTimeout(resolve, 3000));
+	isLoading.value = false;
+}
+
+//执行图生文
+const imgtotext = () => {
+	processImages(toRaw(_parh.value),'图生文');
+};
+//执行文生文
+const texttotxt = () => {
+	processImages(toRaw(_parh.value),'文生文');
+};
+//执行文生图
+const texttoimg = async() => {
+    const isProcessing = _queue_status.value.some(
+        status => status.includes("处理中") || status.includes("队列中")
+    );
+    
+    if (isProcessing) {
+		await ElMessageBox.confirm(
+		  '部分数据正在处理中,请稍后再操作!?',
+		  '文生图',
+		  {
+		    confirmButtonText: '确定',
+		    cancelButtonText: '取消',
+		    type: 'warning'
+		  }
+		);
+        return; // 阻止继续执行
+    }
+    
+    // 如果没有任务在执行,才允许调用
+    processImages(toRaw(_parh.value), '文生图');
+};
+//执行图生图
+const imgtoimg = () => {
+	processImages(toRaw(_parh.value),'图生图');
+};
+//执行高清放大
+const singleimg = () => {
+	processImages(toRaw(_parh.value),'高清放大');
+};
+//执行选择任务
+const handleSelected = () => {
+  processImages(toRaw(_parh.value),'');
+};
+//执行全部任务
+const allTableData = ref([]); // 全部数据缓存
+const handleAll = async () => {
+  try {
+    await ElMessageBox.confirm(
+      '确定要执行全部任务吗?',
+      '确认操作',
+      {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }
+    );
+
+    // 开始 loading
+    loading.value = true;
+
+    // 发起全量请求
+    const allParams = {
+	  sys_id:userStore.userInfo.nickName,
+      path: _resrow.value.old_image_url,
+      page: 1,
+      limit: 10000
+    };
+   const allRes = await getPreviewimg(allParams);
+   console.log(allRes);
+   
+   if (allRes.code === 0) {
+     // 全部原始数据
+     allTableData.value = allRes.data;
+   
+     // 只保留 status 为 0 且 status_name 为空的项
+     const filteredPaths = toRaw(allTableData.value)
+       .filter(item => item.status === 0 && !item.status_name)
+       .map(item => item.path);
+   
+     processImages(filteredPaths, '');
+   } else {
+     ElMessage.error(allRes.msg || '获取全部图片失败');
+   }
+
+  } catch (err) {
+    if (err !== 'cancel') {
+      ElMessage.error('操作取消');
+    }
+  } finally {
+    // 无论成功/失败/异常,最后关闭 loading
+    loading.value = false;
   }
-  .mab{
-    margin-bottom: 5px;
+};
+
+
+//操作 统一执行操作按钮处理方法
+const processImages = async (files,type) => {
+	if (!Array.isArray(files) || files.length === 0) {
+		ElMessage.warning('请选择要处理的图片')
+		return
+	}
+	
+	// console.log(imgtotxtselectedModel.value)
+	// console.log(txttotxtselectedModel.value)
+	// console.log(txtimgselectedModel.value)
+	
+	//加载开启
+	isLoading.value = true
+	
+	const failList = []
+	const payload = {
+		old_image_file:_resrow.value['old_image_url'],
+		type:type,
+		imgtotxt_selectedOption:imgtotxtselectedModel.value,
+		txttotxt_selectedOption:txttotxtselectedModel.value,
+		selectedOption:txtimgselectedModel.value,
+		batch:files,
+		num:num.value,
+		width: width.value,
+		height: height.value,
+		executeKeywords:executeKeywords.value,
+		sys_id:userStore.userInfo.nickName
+	}
+	
+	// 打印调试区域
+	// console.log(payload);
+	// await new Promise(resolve => setTimeout(resolve, 2000));
+	// isLoading.value = false;
+	// return;
+	
+	//提交
+	try {
+		const res = await imageToText(payload)
+	} catch (e) {
+		failList.push(`第 ${batchStart + i + 1} 张 第 ${j + 1} 次`)
+	}
+		ElMessage.success(`共处理 ${files.length} 张 * ${num.value} 次,共 ${files.length * num.value} 次`)
+	if (failList.length > 0) {
+		console.warn('失败列表:', failList)
+	}
+	
+	// 延迟2秒再关闭loading
+	await new Promise(resolve => setTimeout(resolve, 3000));
+	isLoading.value = false;
+	
+	//刷新执行状态
+	Refresh_Status()
+	
+	//任务队列刷新
+	const queue_logs = await get_queue_logs({ old_image_file: _resrow.value['old_image_url'] });
+	table_queue.value = queue_logs.data;
+	  
+
+}
+
+// --------------------- 打包zip ---------------------
+const zipview = ref(false)
+const ziprow = ref('')
+const zipselectedOption = ref('图生图') // 默认选中
+//点击打包按钮
+const packRow = async (row) => {
+	zipview.value = true;
+	
+	ziprow.value = row
+}
+
+//确定按钮
+const confirmPack = async () => {
+  isLoading.value = true;
+  // console.log(zipselectedOption.value)
+  // return;
+  try {
+    const res = await getPreviewimg({
+	  sys_id:userStore.userInfo.nickName,
+      path: ziprow.value.old_image_url,
+      page: 1,
+      limit: 10000
+    });
+
+    if (res.code !== 0 || !res.data || res.data.length === 0) {
+      ElMessage.warning('未找到出图记录');
+      return;
+    }
+
+    // 根据选择的选项筛选对应的图片路径
+    const imagePaths = res.data.flatMap(item => {
+      const paths = [];
+      
+      switch(zipselectedOption.value) {
+        case '1024x1024':
+          if (item.new_image_url?.trim()) {
+            paths.push({ type: 'new_image_url', path: item.new_image_url });
+          }
+          break;
+          
+        // case '1024x1303':
+        //   if (item.imgtoimg_url?.trim()) {
+        //     paths.push({ type: 'imgtoimg_url', path: item.imgtoimg_url });
+        //   }
+        //   break;
+          
+        case '高清放大':
+          if (item.custom_image_url?.trim()) {
+            paths.push({ type: 'custom_image_url', path: item.custom_image_url });
+          }
+          break;
+          
+        case '图生图':
+          // 如果图生图需要多个字段,可以在这里添加
+          if (item.imgtoimg_url?.trim()) {
+            paths.push({ type: 'imgtoimg_url', path: item.imgtoimg_url });
+          }
+          // 可以根据需要添加其他字段
+          break;
+          
+        default:
+          // 默认情况下,可以保留原来的逻辑或添加其他处理
+          break;
+      }
+      
+      return paths;
+    });
+
+    if (imagePaths.length === 0) {
+      ElMessage.warning(`没有找到${zipselectedOption.value}尺寸的图片`);
+      return;
+    }
+// console.log(imagePaths)
+// return;
+    const packRes = await packImagess({ paths: imagePaths });
+
+    if (packRes.code === 0 && packRes.download_url) {
+      ElMessage.success('打包成功,正在下载...');
+
+      // ✅ 替换为服务的真实 IP 和端口
+      const basePath = import.meta.env.VITE_BASE_PATH || 'http://20.0.16.53';
+      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;
+    zipview.value = false; // 关闭对话框
   }
-  </style>
-  
+};
+
+</script>
+<style scoped>
+.page-container {
+  padding: 20px;
+  background: #fff;
+}
+
+.input-container {
+  margin-bottom: 20px;
+}
+
+.gva-table-box {
+  padding-bottom: 20px;
+}
+
+.table-container {
+  margin-top: 20px;
+}
+
+/* 表格行高细节调整 */
+:deep(.el-table td .cell) {
+  line-height: 20px !important;
+}
+
+:deep(.el-tabs__header) {
+  margin-bottom: 0;
+}
+
+/* 选中高亮 */
+:deep(.el-table__body tr.current-row) > td {
+  background: #ff80ff !important;
+}
+
+
+
+/* 新增上传区域样式 */
+.upload-container {
+  margin: 20px 0;
+  padding: 20px;
+  border: 1px dashed #dcdfe6;
+  border-radius: 4px;
+  background-color: #f5f7fa;
+}
+
+.upload-list {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 10px;
+}
+
+.upload-item {
+  position: relative;
+  width: 100px;
+  height: 100px;
+  border-radius: 4px;
+  overflow: hidden;
+  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+}
+
+.upload-item-thumbnail {
+  width: 100%;
+  height: 100%;
+  object-fit: cover;
+}
+/* 修改上传卡片容器 */
+:deep(.el-upload--picture-card) {
+  --el-upload-picture-card-size: 100px;
+}
+
+:deep(.el-upload-list--picture-card) {
+  --el-upload-list-picture-card-size: 100px;
+}
+
+.upload-item-actions {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  padding: 8px;
+  background: rgba(0, 0, 0, 0.6);
+  color: white;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.upload-item-name {
+  flex: 1;
+  font-size: 12px;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  margin-right: 8px;
+}
+
+.upload-progress {
+  font-size: 12px;
+  color: #409eff;
+}
+
+.upload-item-status {
+  margin: 0 8px;
+}
+
+.success-icon {
+  color: #67c23a;
+}
+
+.error-icon {
+  color: #f56c6c;
+}
+
+.upload-item-delete {
+  cursor: pointer;
+  color: #f56c6c;
+}
+
+.upload-item-delete:hover {
+  color: #ff0000;
+}
+
+:deep(.desc-overlay) {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 120px;
+  height: 120px;
+  background: rgba(0, 0, 0, 0.75);
+  color: #fff;
+  font-size: 12px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 8px;
+  box-sizing: border-box;
+  border-radius: 8px;
+  text-align: center;
+  word-break: break-word;
+  line-height: 1.4;
+  z-index: 10;
+}
+
+:deep(.fade-enter-active,
+.fade-leave-active) {
+  transition: opacity 0.3s;
+}
+:deep(.fade-enter-from,
+.fade-leave-to) {
+  opacity: 0;
+}
+
+
+.dialog-scroll-wrapper {
+  max-height: 500px;
+  overflow-y: auto;
+  padding-right: 10px;
+}
+
+.task-card {
+  margin-bottom: 12px;
+}
+
+.task-grid {
+  display: grid;
+  grid-template-columns: 1fr;
+  row-gap: 6px;
+  font-size: 14px;
+  line-height: 1.6;
+}
+
+.task-prompt {
+  word-break: break-word;
+  white-space: pre-wrap;
+}
+
+.task-image {
+  margin-top: 8px;
+}
+.image-preview-overlay {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: rgba(0, 0, 0, 0.7);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  z-index: 9999;
+}
+
+.image-preview {
+  max-width: 90%;
+  max-height: 90%;
+  object-fit: contain;
+  cursor: pointer;
+}
+
+.dialog-body {
+  height: 93vh;
+  display: flex;
+  gap: 0px;
+  overflow: hidden;
+}
+
+/* 左侧表格区域 */
+.dialog-left {
+  flex: 1.4;
+  height: 100%;
+  overflow-y: auto;
+}
+
+/* 右侧详情区域 */
+.dialog-right {
+  flex: 2;
+  height: 100%;
+  overflow: hidden;
+  display: flex;
+  flex-direction: column;
+}
+
+.dialog-right-scroll {
+  flex: 1;
+  overflow-y: auto;
+  padding-right: 5px;
+}
+
+/* 按钮区域自动换行不拥挤 */
+.button-group {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 10px;
+  margin-top: 5px;
+}
+
+/* 图片容器 */
+.image-preview-wrap {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 16px;
+}
+.image-item {
+  position: relative;
+  text-align: center;
+  width: 110px;
+}
+.image-item img {
+  width: 120px;
+  height: 120px;
+  border: 1px solid #ccc;
+  object-fit: contain;
+}
+.image-item div {
+  margin-top: 4px;
+  font-size: 12px;
+  color: #666;
+}
+
+.image-items {
+  position: relative;
+  text-align: center;
+  width: 107px;
+}
+.image-items img {
+  width: 95px;
+  height: 120px;
+  border: 1px solid #ccc;
+  object-fit: contain;
+}
+.image-items div {
+  margin-top: 4px;
+  font-size: 12px;
+  color: #666;
+}
+
+.image-itemsimg {
+  position: relative;
+  text-align: center;
+  width: 110px;
+}
+.image-itemsimg img {
+  width: 118px;
+  height: 150px;
+  border: 1px solid #ccc;
+  object-fit: contain;
+}
+.image-itemsimg div {
+  margin-top: 4px;
+  font-size: 12px;
+  color: #666;
+}
+/* 模版样式 */
+.page-container {
+  padding: 20px;
+  background: #fff;
+}
+
+.custom-textarea {
+  width: 100%;
+  font-family: monospace;
+  font-size: 14px;
+  padding: 10px;
+  line-height: 1.6;
+  border: 1px solid #dcdfe6;
+  border-radius: 4px;
+  resize: vertical;
+  box-sizing: border-box;
+}
+
+:deep(.el-descriptions__body .el-descriptions__table.is-bordered .el-descriptions__cell) {
+  width: 100px;
+}
+</style>

+ 494 - 0
src/view/yunyin/shengchanguanli/AIPromptManagement.vue

@@ -0,0 +1,494 @@
+<template>
+  <div>
+    <!-- 搜索区域 -->
+    <el-form inline>
+      <el-form-item>
+        <el-input v-model="searchInfo" placeholder="搜索关键字" clearable style="width: 300px;" />
+        
+        <!-- 文件夹筛选下拉菜单 -->
+        <el-dropdown @command="handleFolderCommand" style="margin-right: 10px;">
+          <el-button  icon="search" title="文件夹筛选">
+            {{ selectedFolder || '文件夹筛选' }}<el-icon class="el-icon--right"><arrow-down /></el-icon>
+          </el-button>
+          <template #dropdown>
+            <el-dropdown-menu>
+              <el-dropdown-item command="">全部文件夹</el-dropdown-item>
+              <el-dropdown-item v-for="(folder, index) in folderList" :key="index" :command="folder">
+                {{ folder }}
+              </el-dropdown-item>
+            </el-dropdown-menu>
+          </template>
+        </el-dropdown>
+        
+        <el-button type="primary" icon="search" @click="onSubmit" title="搜索">查询</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-form-item>
+    </el-form>
+
+    <!-- 模型选择 -->
+    <el-descriptions column="1" border>
+      <el-descriptions-item label="文生图模型">
+        <div style="display: flex; align-items: center; gap: 20px;">
+          <el-radio-group 
+            v-model="txtimgselectedModel"
+            @change="handleModelChange"
+          >
+            <el-radio 
+              v-for="item in txttoimg_modelList" 
+              :key="item.id"
+              :label="item.txttoimg"
+            >
+              {{ item.txttoimg }} 
+              <span v-if="item.id === usedId" style="color: #67C23A; margin-left: 5px;">(当前使用)</span>
+            </el-radio>
+          </el-radio-group>
+        </div>
+      						
+		<el-button type="success" @click="setActive" :disabled="selectedId === usedId">设为当前使用模型</el-button>
+      </el-descriptions-item>
+    </el-descriptions>
+
+    <!-- 表格展示 -->
+    <el-table
+      ref="multipleTable"
+      style="width: 100%; height: 62vh;"
+      :row-style="{ height: '20px' }"
+      :header-cell-style="{ padding: '0px' }"
+      :cell-style="{ padding: '0px' }"
+      :header-row-style="{ height: '20px' }"
+      border tooltip-effect="dark"
+      :data="tableData1"
+      row-key="ID"
+      highlight-current-row
+      :cell-class-name="tableDataCellClass"
+      @selection-change="SelectionChange"
+      @row-dblclick="onRowDblClick"
+      :show-overflow-tooltip="true"
+    >
+      <el-table-column type="selection" width="55" />
+      <el-table-column label="ID" prop="id" width="70" />
+      <el-table-column label="第一段" prop="chinese_description" width="300" />
+      <el-table-column label="第二段" prop="english_description" width="300" />
+      <el-table-column label="图片名称" prop="img_name" width="300" />
+      <el-table-column label="原图" width="120">
+        <template #default="{ row }">
+          <el-image
+            :src="formatImageUrl(row.old_image_url)"
+            :preview-src-list="[formatImageUrl(row.old_image_url)]"
+            style="width: 90px; height: 70px;"
+            fit="contain"
+            preview-teleported
+          />
+        </template>
+      </el-table-column>
+	  
+	  
+	  <el-table-column
+	    v-if="tableData1.some(row => row.model === 'black-forest-labs/FLUX.1-kontext-pro')" 
+	    label="FLUX.1" 
+	    width="120">
+	    <template #default="{ row }">
+	      <el-image
+	        v-if="row.model === 'black-forest-labs/FLUX.1-kontext-pro'"
+	        :src="formatImageUrl(row.new_image_url)"
+	        :preview-src-list="[formatImageUrl(row.new_image_url)]"
+	        style="width: 90px; height: 70px;"
+	        fit="contain"
+	        preview-teleported
+	      />
+	      <span v-else>-</span>
+	    </template>
+	  </el-table-column>
+	  <el-table-column
+	    v-if="tableData1.some(row => row.model === 'dall-e-3')" 
+	    label="dall-e-3" 
+	    width="120">
+	    <template #default="{ row }">
+	      <el-image
+	        v-if="row.model === 'dall-e-3'"
+	        :src="formatImageUrl(row.new_image_url)"
+	        :preview-src-list="[formatImageUrl(row.new_image_url)]"
+	        style="width: 90px; height: 70px;"
+	        fit="contain"
+	        preview-teleported
+	      />
+	      <span v-else>-</span>
+	    </template>
+	  </el-table-column>
+	  <el-table-column 
+	    v-if="tableData1.some(row => row.model === 'gpt-image-1')" 
+	    label="gpt-image-1" 
+	    width="120">
+	    <template #default="{ row }">
+	      <el-image
+	        v-if="row.model === 'gpt-image-1'"
+	        :src="formatImageUrl(row.new_image_url)"
+	        :preview-src-list="[formatImageUrl(row.new_image_url)]"
+	        style="width: 90px; height: 70px;"
+	        fit="contain"
+	        preview-teleported
+	      />
+	      <span v-else>-</span>
+	    </template>
+	  </el-table-column>
+	  <el-table-column
+	    v-if="tableData1.some(row => row.model === 'MID_JOURNEY')" 
+	    label="MID_JOURNEY" 
+	    width="130">
+	    <template #default="{ row }">
+	      <el-image
+	        v-if="row.model === 'MID_JOURNEY'"
+	        :src="`https://chatapi.onechats.ai/mj/image/${row.taskId}`"  
+	        :preview-src-list="[`https://chatapi.onechats.ai/mj/image/${row.taskId}`]"
+	        style="width: 90px; height: 70px;"
+	        fit="contain"
+	        preview-teleported
+	      />
+	      <span v-else>-</span>
+	    </template>
+	  </el-table-column>
+	  
+	  <!-- <el-table-column label="文生图预览" width="120">
+	    <template #default="{ row }">
+	      <el-image
+	        :src="row.taskId ? `https://chatapi.onechats.ai/mj/image/${row.taskId}` : formatImageUrl(row.new_image_url)"
+	        :preview-src-list="[row.taskId ? `https://chatapi.onechats.ai/mj/image/${row.taskId}` : formatImageUrl(row.new_image_url)]"
+	        style="width: 90px; height: 70px;"
+	        fit="contain"
+	        preview-teleported
+	      />
+	    </template>
+	  </el-table-column> -->
+	  
+      <!-- <el-table-column label="文生图预览" width="120">
+        <template #default="{ row }">
+          <el-image
+            :src="formatImageUrl(row.new_image_url)"
+            :preview-src-list="[formatImageUrl(row.new_image_url)]"
+            style="width: 90px; height: 70px;"
+            fit="contain"
+            preview-teleported
+          />
+        </template>
+      </el-table-column> -->
+      
+      <el-table-column label="图生图预览" width="120">
+        <template #default="{ row }">
+          <el-image
+            :src="formatImageUrl(row.imgtoimg_url)"
+            :preview-src-list="[formatImageUrl(row.imgtoimg_url)]"
+            style="width: 90px; height: 70px;"
+            fit="contain"
+            preview-teleported
+          />
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 分页 -->
+    <div class="gva-pagination">
+      <el-pagination
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+        :current-page="page"
+        :page-sizes="[10, 30, 50, 100]"
+        :page-size="pageSize"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="total"
+      />
+    </div>
+
+    <el-dialog 
+      v-model="editDialogVisible" 
+      title="查看信息" 
+      style="width: 70%; height: 80%;top: -6%;" 
+      :modal="true">
+      <el-scrollbar style="max-height: 60vh; overflow-y: auto;">
+        <el-form :model="editFormData">
+          <el-form-item label="ID" label-width="80px">
+            <el-input v-model="editFormData.id" disabled />
+          </el-form-item>
+    
+          <el-form-item label="文生图路径">
+            <el-input v-model="editFormData.new_image_url" disabled />
+          </el-form-item>
+    
+          <el-form-item label="图生图路径">
+            <el-input v-model="editFormData.imgtoimg_url" disabled />
+          </el-form-item>
+    
+          <el-form-item label="第一段">
+            <el-input
+              type="textarea"
+              v-model="editFormData.chinese_description"
+              :rows="6"
+            />
+          </el-form-item>
+    
+          <el-form-item label="第二段">
+            <el-input
+              type="textarea"
+              v-model="editFormData.english_description"
+              :rows="6"
+            />
+          </el-form-item>
+    
+          <el-form-item label="图片名称">
+            <el-input v-model="editFormData.img_name" />
+          </el-form-item>
+        </el-form>
+      </el-scrollbar>
+    
+      <template #footer>
+        <el-button @click="editDialogVisible = false">取消</el-button>
+        <el-button type="primary" @click="submitEdit">确定</el-button>
+      </template>
+    </el-dialog>
+
+    <!-- 图片预览 -->
+    <el-dialog v-model="dialogVisible" title="图片预览" width="70%" top="5vh" destroy-on-close>
+      <div style="text-align: center;">
+        <el-image :src="currentImageUrl" style="max-width: 100%; max-height: 70vh;" fit="contain" />
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, toRaw, onMounted } from 'vue'
+import { ElMessage } from 'element-plus'
+import { getTable, imageToText, Template_ids,txttoimg_moxing,txttoimg_update, getSide } from '@/api/ai/aiimg'
+import { useUserStore } from '@/pinia/modules/user'
+import { ArrowDown } from '@element-plus/icons-vue'
+
+const userStore = useUserStore()
+const _username = ref(userStore.userInfo.userName + '/' + userStore.userInfo.nickName)
+
+const searchInfo = ref('')
+const tableData1 = ref([])
+const total = ref(0)
+const page = ref(1)
+const pageSize = ref(50)
+const dialogVisible = ref(false)
+const currentImageUrl = ref('')
+const width = ref('')
+const height = ref('')
+const isLoading = ref(false)
+const txttotxt_selectedOption = ref('gemini-2.0-flash')
+const selectedOption = ref('black-forest-labs/FLUX.1-kontext-pro')
+const num = ref(1)
+const _parh = ref([])
+const folderList = ref([])
+const selectedFolder = ref('')
+
+const editDialogVisible = ref(false)
+const editFormData = reactive({
+  id: '',
+  chinese_description: '',
+  english_description: '',
+  new_image_url: '',
+  imgtoimg_url: '',
+  img_name: ''
+})
+
+const formatImageUrl = (path) => {
+  if (!path) return ''
+  const base = 'http://20.0.16.53:9093'
+  return `${base}/${path.replace(/^public\//, '')}`
+}
+
+const txttoimg_modelList = ref([]); // 存储所有模型数据
+const txtimgselectedModel = ref(''); // 当前选中的模型名称
+const usedId = ref(null); // 当前使用的模型ID
+const selectedId = ref(null); // 用户选择的模型ID
+
+const getTableData = async () => {
+    const res = await getTable({
+      search: searchInfo.value,
+      limit: pageSize.value,
+      page: page.value,
+      folder: selectedFolder.value
+    })
+	console.log("getTable",res.data.data)
+    tableData1.value = res.data.data.list
+    total.value = res.data.data.total
+    
+    // 更新文件夹列表
+    if (res.data.data.folder) {
+      folderList.value = res.data.data.folder
+    }
+
+ //    const res_Template = await Template_ids()
+	// console.log("Template_ids",res_Template)
+ //    height.value = res_Template.data.data.height
+ //    width.value = res_Template.data.data.width
+	
+	//文生图模型列表
+	const response = await txttoimg_moxing();
+	txttoimg_modelList.value = response.data.list;
+	// 设置默认选中的模型(txttoimg_val为"1"的模型)
+	const defaultModel = response.data.data.list.find(item => item.txttoimg_val === "1");
+	if (defaultModel) {
+	  txtimgselectedModel.value = defaultModel.txttoimg;
+	  usedId.value = defaultModel.id;
+	  selectedId.value = defaultModel.id; 
+	  selectedOption.value = defaultModel.txttoimg;
+	}
+}
+
+// 当选择模型变化时
+const handleModelChange = (modelName) => {
+  const model = txttoimg_modelList.value.find(item => item.txttoimg === modelName);
+  if (model) {
+    selectedId.value = model.id;
+	selectedOption.value = model.txttoimg
+  }
+}
+//设置模型
+const setActive = async () => {
+  if (selectedId.value) {
+    const result = await txttoimg_update({id:selectedId.value});
+    console.log(result)
+    usedId.value = selectedId.value;
+    ElMessage.success(`设置成功`);
+  }
+}
+
+
+// 处理文件夹选择
+const handleFolderCommand = (command) => {
+  selectedFolder.value = command
+  onSubmit()
+}
+
+const onSubmit = () => {
+  page.value = 1
+  getTableData()
+}
+
+const handleCurrentChange = (val) => {
+  page.value = val
+  getTableData()
+}
+
+const handleSizeChange = (val) => {
+  pageSize.value = val
+  page.value = 1
+  getTableData()
+}
+
+const SelectionChange = (rows) => {
+  _parh.value = rows.map(item => item.old_image_url)
+}
+
+const texttoimg = () => {
+  processImages(toRaw(_parh.value), '文生图')
+}
+
+const imgtoimg = () => {
+  processImages(toRaw(_parh.value), '图生图')
+}
+
+const processImages = async (files, type) => {
+  if (!Array.isArray(files) || files.length === 0) {
+    ElMessage.warning('请选择要处理的图片')
+    return
+  }
+
+  const pathGroups = {}
+  _parh.value.forEach(path => {
+    const dir = path.replace(/\/[^\/]*$/, '')
+    if (!pathGroups[dir]) pathGroups[dir] = []
+    pathGroups[dir].push(path)
+  })
+
+  isLoading.value = true
+  const failList = []
+
+  for (const [dir, images] of Object.entries(pathGroups)) {
+    const payload = {
+      old_image_file: dir,
+      type,
+      selectedOption: selectedOption.value,
+      txttotxt_selectedOption: txttotxt_selectedOption.value,
+      batch: images,
+      num: num.value,
+      width: width.value,
+      height: height.value,
+	  executeKeywords:'',
+    }
+
+    try {
+      await imageToText(payload)
+      ElMessage.success(`处理目录:${dir},共 ${images.length} 张 * ${num.value} 次`)
+    } catch (e) {
+      console.warn('处理失败:', dir, e)
+      images.forEach((_, i) => failList.push(`目录 ${dir} 第 ${i + 1} 张`))
+    }
+  }
+
+  if (failList.length > 0) {
+    ElMessage.warning('部分图片处理失败,请查看控制台')
+  }
+
+  await new Promise(resolve => setTimeout(resolve, 3000))
+  isLoading.value = false
+}
+
+const previewImage = (url) => {
+  currentImageUrl.value = url
+  dialogVisible.value = true
+}
+
+const onRowDblClick = (row) => {
+  editFormData.id = row.id
+  editFormData.chinese_description = row.chinese_description
+  editFormData.english_description = row.english_description
+  editFormData.img_name = row.img_name
+  editFormData.new_image_url = row.new_image_url
+  editFormData.imgtoimg_url = row.imgtoimg_url
+  editDialogVisible.value = true
+}
+
+const submitEdit = async () => {
+  try {
+    const { id, chinese_description, english_description, img_name } = editFormData;
+
+    const payload = {
+      id,
+      chinese_description,
+      english_description,
+      img_name
+    };
+
+    await getSide(payload);
+    ElMessage.success('修改成功');
+    editDialogVisible.value = false;
+    getTableData();
+  } catch (error) {
+    console.error('修改失败:', error);
+    ElMessage.error('修改失败,请稍后重试');
+  }
+};
+
+onMounted(() => {
+  getTableData()
+})
+</script>
+
+<style scoped>
+:deep(.el-table td .cell) {
+  line-height: 22px !important;
+}
+:deep(.el-dialog__body) {
+  padding: 10px 20px;
+}
+.gva-pagination {
+  margin-top: 10px;
+  text-align: right;
+}
+:deep(.el-table__body tr.current-row) > td {
+  background: #ff80ff !important;
+}
+</style>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 176 - 55
src/view/yunyin/shengchanguanli/ShippingManagement.vue


+ 0 - 2
src/view/yunyin/shengchanguanli/components/luckyexcel.vue

@@ -139,8 +139,6 @@ const open = async (row) => {
 			} else {
 	
 				// 文件路径处理
-				// const excelPath = `/${row['url'].replace(/\\/g, "/")}`;
-				// const excelPath = "http://192.168.28.22:8082/"+row['url']
 				const excelPath = `${path}/${row['url']}`
 				console.log("url",excelPath);
 				const excelName = excelPath.split('/').pop();

+ 132 - 20
src/view/yunyin/shengchanguanli/gongdanziliao.vue

@@ -222,7 +222,7 @@
 				</el-tab-pane>
 
 
-				<el-tab-pane label="技术附件" name="fourth">
+				<el-tab-pane label="发货单附件" name="fourths">
 				  <el-table ref="multipleTable"
 					:row-style="{ height: '30px' }"
 					:cell-style="{ padding: '0px' }"
@@ -234,11 +234,11 @@
 					@row-dblclick="ExcelShow"
 					style="width: 100%;height: 36vh"
 					border tooltip-effect="dark"
-					:data="jstableData"
+					:data="fhdtableData"
 					row-key="ID"
-					@selection-change="fjSelectionChange">
-				
-					<el-table-column align="left" label="关联编号" prop="关联编号" width="115"/>
+					@selection-change="fhdSelectionChange">
+					<el-table-column align="left" label="发货单号" prop="rand_number" width="160"/>
+					<el-table-column align="left" label="订单编号" prop="关联编号" width="115"/>
 					<el-table-column align="left" label="附件备注" prop="附件备注" width="110"/>
 					<el-table-column align="left" label="文件类型" prop="附件类型" width="100"/>
 					<el-table-column align="left" label="版本号" prop="version" width="80"/>
@@ -246,10 +246,11 @@
 					<el-table-column align="left" label="建档时间" prop="sys_rq" width="160"/>
 					
 					<!-- 操作列,新增修改和删除按钮 -->
-					<el-table-column align="left" label="操作" width="230" fixed="right">
+					<el-table-column align="left" label="操作" width="330" fixed="right">
 					  <template #default="scope">
 						<!-- PDF预览按钮 -->
 						<el-button type="success" size="small" :data="ddtableData" @click="showPdf(scope.row)">PDF预览</el-button>
+						<el-button type="primary" size="small" @click="fahuodan(scope.row)">获取发货数量</el-button>
 						<!-- 删除按钮 -->
 						<el-button type="danger" size="small" @click="deleteItem(scope.row)">删除</el-button>
 					  </template>
@@ -1383,6 +1384,62 @@
 				  </div>
 				</template>
 			  </el-dialog>
+			  
+			  
+			  <!-- 发货单页面 -->
+  
+			  <el-dialog v-model="InvoiceVisible" :before-close="InvoiceDialog" title="AI获取发货单出货信息"
+						  style="margin-top: 40px" height="300px" width="1000px" destroy-on-close>
+						  
+					<h3 style="color:red;font-size: 24px;margin:-5px 0px 8px 12px;" >订单编号&nbsp;&nbsp;&nbsp;{{_ddhval}}</h3>
+					<el-table
+							ref="table" highlight-current-row
+							show-overflow-tooltip border
+							:data="InvoicetableData"
+							:row-style="{ height: '25px' }"
+							:cell-style="{ padding: '0px' }"
+							:header-row-style="{ height: '20px' }"
+							:header-cell-style="{ padding: '0px' }"
+							style="width: 100%;height: 65vh;" >
+			
+						<el-table-column label="子订单编号" prop="子订单编号" width="160"></el-table-column>
+						<el-table-column label="颜色" prop="颜色" width="110"></el-table-column>
+						<el-table-column label="尺码" prop="尺码" width="110"></el-table-column>
+						<el-table-column label="制单数量" prop="制单数量" width="110"></el-table-column>
+						<el-table-column label="发货箱数" prop="发货箱数" width="110">
+							<template #default="scope">
+								<el-input
+									v-model="scope.row.发货箱数"
+									size="mini"
+									@change="handleQuantityChange(scope.row)"
+									@blur="handleQuantityBlur(scope.row)"
+									placeholder="请输入数量"
+								/>
+							</template>
+						</el-table-column>
+							<el-table-column label="每箱件数" prop="每箱件数" width="110">
+							<template #default="scope">
+								<el-input
+									v-model="scope.row.每箱件数"
+									size="mini"
+									@change="handleQuantityChange(scope.row)"
+									@blur="handleQuantityBlur(scope.row)"
+									placeholder="请输入数量"
+								/>
+							</template>
+						</el-table-column>
+						<el-table-column label="发货数量" prop="发货数量" width="110"></el-table-column>
+					</el-table>
+					
+					<template #footer>
+						<br>
+					  <div class="dialog-footer">
+						<el-button @click="InvoiceDialog">取 消</el-button>
+						<el-button type="primary"  @click="InvoiceenterDialog">确 定</el-button>
+					  </div>
+					</template>
+			  </el-dialog>
+  
   
 			</el-main>
 		  </layout-content>
@@ -1427,7 +1484,7 @@
   import {Datalist,WorkOrderList,WorkOrderAdd,PrintListData,
   printDetailAdd,PrintDetailDel,orderDataDel,getWorkOrder,
   getSuborder,PrintDataEdit,WorkOrderEdit,gdAnnexAdd,upload,OrderAttachments,
-  getPonumber,FabricEdit,orderBomList,FabricDetail,fabricList,Bomdel,delfujian} from '@/api/mes/job'
+  getPonumber,FabricEdit,orderBomList,FabricDetail,fabricList,Bomdel,delfujian,Read_File,Read_Add} from '@/api/mes/job'
   import PrintPage from './components/print.vue'
   import luckyexcelPage from './components/luckyexcel.vue'
   import AddGongYi from './components/addGongYi.vue'  
@@ -1596,6 +1653,7 @@
 	  gytableData.splice(0, gytableData.length);
 	  ddtableData.splice(0, ddtableData.length);
 	  jstableData.splice(0, jstableData.length);
+	  fhdtableData.splice(0, fhdtableData.length);
 	  // 取消所有节点的颜色
 	  const allNodes = document.querySelectorAll('.treecolor .el-tree-node');
 		  allNodes.forEach(node => {
@@ -1613,18 +1671,67 @@
 	  _WorkList_page();
   };
   
+	const InvoiceVisible = ref(false)
+	const InvoicetableData = ref([])
+	const fahuodan = async(row)=>{
+	 const Read_Filelist = await Read_File({
+	     UniqId: row['UniqId'],
+	     order: row['关联编号'],
+	     url: path
+	 })
+	 if(Read_Filelist.code === 0){
+		 console.log(Read_Filelist)
+		 InvoiceVisible.value = true
+		 const PrintListDatas = await PrintListData({order:_Gd_gdbh.value})
+		 sizeDatas.splice(0,PrintListDatas.data.型号.length,...PrintListDatas.data.型号);
+		 InvoicetableData.value = Read_Filelist.data
+	 }
+	}
+	//取消
+	const InvoiceDialog = () => {
+		InvoiceVisible.value = false
+	}
+	
+	const InvoiceenterDialog = async() => {
+		console.log(InvoicetableData.value)
+		// InvoiceVisible.value = false
+		
+		const rawValueArray = InvoicetableData.value;
+		const formattedData = rawValueArray
+		.map(item => {
+				return {
+				  sys_id: _username.value,
+				  订单编号: item.订单编号,
+				  子订单编号: item.子订单编号,
+				  尺码: item.尺码,
+				  制单数量: item.制单数量,
+				  发货数量: item.发货数量,
+				  发货箱数: item.发货箱数,
+				  每箱件数: item.每箱件数
+				}
+		});
+		console.log(formattedData);
+		const Read_Addres = await Read_Add(formattedData)
+		console.log(Read_Addres)
+		if(Read_Addres.msg === '成功'){
+			ElMessage({type: 'success',message: '处理成功'})
+			InvoiceVisible.value = false
+		}
+	}
+
+	
   // 删除
   const deleteItem = async (row) => {
-	  console.log(_username.value.split('/')[1])
-	  console.log(row.sys_id.split('/')[1])
-  
-  const delfujian_del = await delfujian({UniqId:row['UniqId'],登录用户:_username.value.split('/')[1],建档用户:row.sys_id.split('/')[1]});
-		  if(delfujian_del.code === 0){
-			  ElMessage({type: 'success',message: '删除成功'})
-		  }else{
-			  ElMessage({type: 'error',message: '删除失败'})
-		  }
-		  tableRowClick (row)
+	console.log(_username.value.split('/')[1])
+	console.log(row.sys_id.split('/')[1])
+
+	const delfujian_del = await delfujian({UniqId:row['UniqId'],登录用户:_username.value.split('/')[1],建档用户:row.sys_id.split('/')[1]});
+	if(delfujian_del.code === 0){
+		ElMessage({type: 'success',message: '删除成功'})
+	}else{
+		ElMessage({type: 'error',message: '删除失败'})
+	}
+	tableRowClick (row)
   }
   
   const showPdf = async (row) => {
@@ -3048,6 +3155,8 @@ function Input_handle() {
   const ddtableData = reactive([])
   //技术附件
   const jstableData = reactive([])
+  
+  const fhdtableData = reactive([])
   //BOM附件
   const bomtableData = reactive([])
   //面料附件
@@ -3060,6 +3169,7 @@ function Input_handle() {
 	  ystableData.splice(0, ystableData.length);
 	  gytableData.splice(0, gytableData.length);
 	  ddtableData.splice(0, ddtableData.length);
+	  fhdtableData.splice(0, fhdtableData.length);
 	  jstableData.splice(0, jstableData.length);
 	  bomtableData.splice(0, bomtableData.length);
 	  mltableData.splice(0, mltableData.length);
@@ -3074,6 +3184,7 @@ function Input_handle() {
 	  const PrintListDatas = await PrintListData({order:_Gd_gdbh.value})
 	  const jsOrderAttachments = await OrderAttachments({order:_Gd_gdbh.value,desc:'技术附件'})
 	  const ddOrderAttachments = await OrderAttachments({order:_Gd_gdbh.value,desc:'订单资料附件'})
+	  const fhdOrderAttachments = await OrderAttachments({order:_Gd_gdbh.value,desc:'发货单附件'})
 	  
 	  const orderBomListdata = await orderBomList({ order: _Gd_gdbh.value });
 	  // console.log("orderBomListdata:", orderBomListdata); // 打印接口返回的数据
@@ -3117,6 +3228,10 @@ function Input_handle() {
 	  if(jsOrderAttachments.code === 0 && ddOrderAttachments.code === 0){
 		jstableData.splice(0,jsOrderAttachments.data.list.length,...jsOrderAttachments.data.list);
 		ddtableData.splice(0,ddOrderAttachments.data.list.length,...ddOrderAttachments.data.list);
+		if(_username.value === fhdOrderAttachments.data.list[0]['sys_id'] || _username.value === 'admin/超级管理员'){
+			fhdtableData.splice(0,fhdOrderAttachments.data.list.length,...fhdOrderAttachments.data.list);
+		}
+		
 	  }
   }
   
@@ -3690,8 +3805,5 @@ function Input_handle() {
       opacity: 1;
     }
   }
-  
-  
-  
   </style>
   

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.