提交bug修复,新增文件下载界面

This commit is contained in:
2025-11-20 09:55:25 +08:00
parent 4f5f5c9d1b
commit 6f9c5dc008
4 changed files with 666 additions and 1685 deletions

View File

@@ -0,0 +1,283 @@
<template>
<div class="download-container">
<div class="selection-section">
<div class="selection-item">
<label class="selection-label">项目选择</label>
<el-select v-model="selectedProjectGuid"
placeholder="请选择项目"
filterable
clearable
size="large"
style="width: 300px;"
@change="handleProjectChange">
<el-option v-for="project in projectOptions"
:key="project.guid"
:label="project.hotel_name"
:value="project.guid" />
</el-select>
</div>
<div class="selection-item">
<label class="selection-label">房型选择</label>
<el-select v-model="selectedRoomTypeGuid"
placeholder="请选择房型"
filterable
clearable
size="large"
style="width: 300px;"
:disabled="!selectedProjectGuid"
@change="handleRoomTypeChange">
<el-option v-for="roomType in roomTypeOptions"
:key="roomType.guid"
:label="roomType.room_name"
:value="roomType.guid" />
</el-select>
</div>
</div>
<div class="table-section">
<el-table v-loading="loading"
:data="panelListData"
style="width: 100%; margin-top: 20px;"
stripe
border>
<el-table-column prop="panel_list_name" label="面板组名称" min-width="200" show-overflow-tooltip />
<el-table-column prop="gang_series" label="系列" min-width="120" />
<!--<el-table-column prop="model_type" label="类型" min-width="120" />-->
<!--<el-table-column prop="panel_count" label="面板数量" width="100" align="center" />-->
<el-table-column prop="cdr_filename" label="CDR文件名" min-width="300" show-overflow-tooltip />
<el-table-column prop="created_at" label="生成时间" min-width="160">
<template #default="{ row }">
{{ row.created_at.replace(/[T]/g, ' ') }}
</template>
</el-table-column>
<el-table-column label="操作" width="150" align="center">
<template #default="{ row }">
<el-button size="small"
type="primary"
icon="Download"
@click="downloadCDRFile(row)"
:disabled="!row.cdr_filename">
下载
</el-button>
</template>
</el-table-column>
</el-table>
<div v-if="panelListData.length === 0 && !loading" class="no-data">
暂无数据请先选择项目和房型
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, watch, computed, inject } from 'vue';
import { createAxiosInstance } from '../../axios.js'
import { ElMessage, ElLoading } from 'element-plus'
import { Download, Document } from '@element-plus/icons-vue'
const cloudHttp = inject('cloudHttp')
const localHttp = inject('localHttp')
const config = inject('config')
// 数据加载状态
const loading = ref(false);
// 项目选择
const selectedProjectGuid = ref('');
const projectOptions = ref([]);
// 房型选择
const selectedRoomTypeGuid = ref('');
const allRoomTypes = ref([]);
const roomTypeOptions = computed(() => {
if (!selectedProjectGuid.value) {
return [];
}
// 查找选中的项目
const selectedProject = projectOptions.value.find(project => project.guid === selectedProjectGuid.value);
if (!selectedProject || !selectedProject.room_data_json) {
return [];
}
// 解析项目的room_data_json可能是字符串或数组
const roomTypeGuids = typeof selectedProject.room_data_json === 'string'
? JSON.parse(selectedProject.room_data_json)
: selectedProject.room_data_json;
// 根据项目的room_data_json过滤房型
return allRoomTypes.value.filter(roomType =>
roomTypeGuids.includes(roomType.guid)
);
});
// 面板组数据
const panelListData = ref([]);
/**
* 获取数据
*/
const fetchData = async (endpoint, query = {}) => {
try {
const rs = await localHttp.post(endpoint, JSON.stringify(query));
return rs.data.isok && rs.data.response ? JSON.parse(rs.data.response) : [];
} catch (error) {
console.error(`获取${endpoint}数据失败:`, error);
ElMessage.error(`获取数据失败: ${error.message}`);
return [];
}
};
/**
* 获取所有项目
*/
const loadProjects = async () => {
loading.value = true;
try {
const projects = await fetchData('PanelSelection/WebProjectQuery');
projectOptions.value = projects;
} finally {
loading.value = false;
}
};
/**
* 获取所有房型
*/
const loadRoomTypes = async () => {
loading.value = true;
try {
const roomTypes = await fetchData('PanelSelection/WebRoomTypeQuery');
allRoomTypes.value = roomTypes;
} finally {
loading.value = false;
}
};
/**
* 获取面板组数据
*/
const loadPanelList = async () => {
if (!selectedProjectGuid.value || !selectedRoomTypeGuid.value) {
panelListData.value = [];
return;
}
loading.value = true;
try {
const panelLists = await fetchData('PanelSelection/WebPanelListQuery');
// 查找选中的房型
const selectedRoomType = allRoomTypes.value.find(roomType => roomType.guid === selectedRoomTypeGuid.value);
if (!selectedRoomType || !selectedRoomType.panel_group_count) {
panelListData.value = [];
return;
}
// 解析房型的panel_group_count可能是字符串或数组
const panelGuids = typeof selectedRoomType.panel_group_count === 'string'
? JSON.parse(selectedRoomType.panel_group_count)
: selectedRoomType.panel_group_count;
// 根据房型的panel_group_count过滤面板组
panelListData.value = panelLists.filter(panel =>
panelGuids.includes(panel.guid)
);
} finally {
loading.value = false;
}
};
/**
* 项目选择变化
*/
const handleProjectChange = () => {
selectedRoomTypeGuid.value = '';
panelListData.value = [];
// 可以根据需要添加根据项目加载特定房型的逻辑
};
/**
* 房型选择变化
*/
const handleRoomTypeChange = () => {
loadPanelList();
};
/**
* 下载CDR文件
*/
const downloadCDRFile = (row) => {
if (!row.cdr_filename) {
ElMessage.warning('该面板组尚未生成CDR文件');
return;
}
try {
// 构建文件URL
const fileUrl = config.PicAds + row.cdr_filename;
// 创建a标签并模拟点击下载
const link = document.createElement('a');
link.href = fileUrl;
link.target = '_blank';
// 从文件名中提取不带路径的文件名
const fileName = row.cdr_filename.split('/').pop();
link.download = fileName || 'panel.cdr';
// 将a标签添加到页面触发点击然后移除
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
ElMessage.success('CDR文件下载已开始');
} catch (error) {
console.error('下载CDR文件失败:', error);
ElMessage.error('下载CDR文件失败: ' + error.message);
}
};
/**
* 页面挂载时加载数据
*/
onMounted(async () => {
await Promise.all([
loadProjects(),
loadRoomTypes()
]);
});
</script>
<style scoped>
.download-container {
padding: 20px;
min-height: calc(100vh - 120px);
}
.selection-section {
display: flex;
gap: 20px;
margin-bottom: 20px;
flex-wrap: wrap;
}
.selection-item {
display: flex;
align-items: center;
gap: 10px;
}
.selection-label {
font-weight: 600;
font-size: 14px;
min-width: 80px;
}
.table-section {
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
min-height: 400px;
}
.no-data {
text-align: center;
padding: 60px 0;
color: #909399;
font-size: 14px;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,33 @@
<template> <template>
<div class="container"> <div class="container">
<!-- 复制面板对话框 -->
<el-dialog v-model="showCopyPanelDialog"
title="复制面板"
width="400px"
:close-on-click-modal="false">
<el-select v-model="selectedCopyProjectId"
placeholder="请选择项目"
filterable
clearable
size="small"
style="width: 100%; margin-bottom: 20px;"
@change="handleCopyProjectChange">
<el-option v-for="project in projectList"
:key="project.id"
:label="project.projectName"
:value="project.id" />
</el-select>
<template #footer>
<div class="dialog-footer">
<el-button size="small" @click="showCopyPanelDialog = false">取消</el-button>
<el-button type="primary" size="small" @click="confirmCopyPanel">确认</el-button>
</div>
</template>
</el-dialog>
<!-- 左侧区域 --> <!-- 左侧区域 -->
<div class="left-panel"> <div class="left-panel">
<div class="left-top"> <div class="left-top">
<span style="font-weight:bold;">项目</span>
<el-select ref="projectSelect" <el-select ref="projectSelect"
v-model="selectedProjectId" v-model="selectedProjectId"
placeholder="请选择项目" placeholder="请选择项目"
@@ -11,7 +36,7 @@
size="small" size="small"
@change="handleProjectChangeApp" @change="handleProjectChangeApp"
@visible-change="onSelectVisibleChange" @visible-change="onSelectVisibleChange"
style="width: 100%; margin: 0px;" style="width: 70%; margin: 0px;"
:disabled="isProjectLocked"> :disabled="isProjectLocked">
<el-option v-for="project in projectList" <el-option v-for="project in projectList"
:key="project.id" :key="project.id"
@@ -95,7 +120,7 @@
label="面板单元名称" label="面板单元名称"
min-width="180" min-width="180"
show-overflow-tooltip /> show-overflow-tooltip />
<el-table-column label="操作" width="120" align="center"> <el-table-column label="操作" width="180" align="center">
<template #default="{ row }"> <template #default="{ row }">
<el-button size="small" <el-button size="small"
link link
@@ -106,6 +131,38 @@
<el-button size="small" link type="danger" @click.stop="deletePanelUnit(row)"> <el-button size="small" link type="danger" @click.stop="deletePanelUnit(row)">
删除 删除
</el-button> </el-button>
<el-button size="small" link type="success" @click.stop="copyPanelUnit(row)">
复制面板
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
<div class="left-bottom-dynamic-list">
<div class="section-header">
<span>生成记录</span>
</div>
<div class="table-content">
<el-table :data="generationHistory" style="width: 100%; height:100%" size="small">
<el-table-column prop="name" label="项目" min-width="90" show-overflow-tooltip />
<el-table-column prop="type" label="类型" min-width="55" align="center" />
<el-table-column prop="status" label="状态" min-width="60" align="center">
<template #default="{ row }">
<el-tag :type="row.status === GenerationStatus.IN_PROGRESS ? 'warning' : (row.status === GenerationStatus.COMPLETED ? 'success' : 'danger')">
{{ row.status }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="progress" label="进度" min-width="90" align="center">
<template #default="{ row }">
<el-progress :percentage="row.progress" :show-text="true" size="small" />
</template>
</el-table-column>
<el-table-column prop="duration" label="总耗时" min-width="50" align="center">
<template #default="{ row }">
{{ row.duration !== null ? row.duration + '秒' : '-' }}
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@@ -313,16 +370,15 @@
<!-- 右侧表格宽度缩小 --> <!-- 右侧表格宽度缩小 -->
<div class="table-content" style="width: 70%; height: 39.8vh;"> <div class="table-content" style="width: 70%; height: 39.8vh;">
<el-table <el-table ref="mergedPanelUnitTable"
ref="mergedPanelUnitTable" :data="mergedPanelUnitForm"
:data="mergedPanelUnitForm" border
border style="width: 100%; height:100%"
style="width: 100%; height:100%" size="small"
size="small" highlight-current-row
highlight-current-row @current-change="handleMergedPanelUnitRowChange"
@current-change="handleMergedPanelUnitRowChange" @row-click="handleMergedPanelUnitRowClick"
@row-click="handleMergedPanelUnitRowClick" @change="handleUserEdit">
@change="handleUserEdit">
<!-- 表格列保持不变 --> <!-- 表格列保持不变 -->
<el-table-column label="位置" min-width="60" align="center"> <el-table-column label="位置" min-width="60" align="center">
<template #default="{ row }"> <template #default="{ row }">
@@ -770,7 +826,7 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted, nextTick, inject, computed, watch, onUnmounted } from 'vue'; import { ref, onMounted, nextTick, inject, computed, watch, onUnmounted } from 'vue';
import { createAxiosInstance } from '../../axios.js'; import { createAxiosInstance } from '../../axios.js';
import { ElMessage, ElMessageBox, ElLoading } from 'element-plus'; import { ElMessage, ElMessageBox, ElLoading } from 'element-plus';
import { Picture } from '@element-plus/icons-vue'; import { Picture } from '@element-plus/icons-vue';
@@ -844,9 +900,14 @@ import { ref, onMounted, nextTick, inject, computed, watch, onUnmounted } from '
const currentEditPanelUnit = ref(null); const currentEditPanelUnit = ref(null);
// 面板修改列表变量 // 面板修改列表变量
const mergedPanelUnitForm = ref([]); const mergedPanelUnitForm = ref([]);
const currentMergedPanelUnitRow = ref(null); // 当前选中的mergedPanelUnitForm表格行 const currentMergedPanelUnitRow = ref(null); // 当前选中的mergedPanelUnitForm表格行
const mergedPanelUnitTable = ref(null); // 表格引用 // 复制面板相关变量
const iconDialogVisible = ref(false); const showCopyPanelDialog = ref(false);
const copyPanelUnitRow = ref(null);
const selectedCopyProjectId = ref(null);
const selectedCopyProjectGuid = ref(null);
const mergedPanelUnitTable = ref(null); // 表格引用
const iconDialogVisible = ref(false);
const chineseDialogVisible = ref(false); const chineseDialogVisible = ref(false);
const englishDialogVisible = ref(false); const englishDialogVisible = ref(false);
const currentEditingLocation = ref(null); const currentEditingLocation = ref(null);
@@ -866,9 +927,27 @@ const iconDialogVisible = ref(false);
const currentPanelUnit = ref(null); const currentPanelUnit = ref(null);
const panelUnitForm = ref([]); const panelUnitForm = ref([]);
const fontList = ref([]); const fontList = ref([]);
// 生成历史记录
const generationHistory = ref([]);
// 生成状态枚举
const GenerationStatus = {
IN_PROGRESS: '生成中',
COMPLETED: '已完成',
ERROR: '生成错误'
};
// 生成类型枚举
const GenerationType = {
PREVIEW: '预览组合',
CDR: 'CDR文件',
SINGLE_PANEL: '面板预览'
};
const allModelsForUnit = ref([]); const allModelsForUnit = ref([]);
const selectedModelForUnit = ref(null); const selectedModelForUnit = ref(null);
// 进度更新相关变量
const progressIntervals = ref(new Map()); // 存储每个生成任务的进度更新间隔ID
// 图片预览相关变量 // 图片预览相关变量
const selectedSeriesPreview = ref(''); const selectedSeriesPreview = ref('');
const singlePanelPreview = ref(''); const singlePanelPreview = ref('');
@@ -889,14 +968,6 @@ const iconDialogVisible = ref(false);
remarks: '', remarks: '',
logo_json: "{}" logo_json: "{}"
}); });
const predefineColors = ref([
'#F19947', // 默认背光颜色
'#FFFFFF', // 白色
'#FF8C00', // 橙色
'#FFD700', // 金色
'#ADFF2F', // 绿色
'#1E90FF', // 蓝色
]);
// 加载遮罩实例 // 加载遮罩实例
let loadingInstance = null; let loadingInstance = null;
// 轮询相关变量 // 轮询相关变量
@@ -909,9 +980,12 @@ const iconDialogVisible = ref(false);
// ==================== 计算属性 ==================== // ==================== 计算属性 ====================
// 检查是否有生成中的元素 // 检查是否有生成中的元素
const hasGeneratingItems = computed(() => { const hasGeneratingItems = computed(() => {
// 检查generationHistory中是否有正在生成的记录
const hasGeneratingHistory = generationHistory.value.some(record => record.status === GenerationStatus.IN_PROGRESS);
// 保留原有检查逻辑以确保兼容性
const hasPanelGroupGenerating = currentPanelNode.value?.panelInfo?.thumbnail_small === '生成中'; const hasPanelGroupGenerating = currentPanelNode.value?.panelInfo?.thumbnail_small === '生成中';
const hasPanelUnitGenerating = currentPanelUnitObj.value && currentPanelUnitObj.value.design_status === '生成中'; const hasPanelUnitGenerating = currentPanelUnitObj.value && currentPanelUnitObj.value.design_status === '生成中';
return hasPanelGroupGenerating || hasPanelUnitGenerating; return hasGeneratingHistory || hasPanelGroupGenerating || hasPanelUnitGenerating;
}); });
/** /**
* 获取当前选中的面板单元对象 * 获取当前选中的面板单元对象
@@ -1171,9 +1245,9 @@ const iconDialogVisible = ref(false);
if (shouldPoll && !isPollingActive.value) { if (shouldPoll && !isPollingActive.value) {
startPolling(); startPolling();
} else if (!shouldPoll && isPollingActive.value) { } /*else if (!shouldPoll && isPollingActive.value) {
stopPolling(); stopPolling();
} }*/
}; };
/** /**
* 启动轮询检查生成状态 * 启动轮询检查生成状态
@@ -1186,8 +1260,13 @@ const iconDialogVisible = ref(false);
pollingInterval.value = setInterval(async () => { pollingInterval.value = setInterval(async () => {
await checkGeneratingStatus(); await checkGeneratingStatus();
await refreshPanelUnitPreview(); if (!singlePanelPreview.value){
}, 3000); // 轮询一次 await refreshPanelUnitPreview();
}
if (!panelGroupPreview.value) {
await refreshPanelGroupPreview();
}
}, 1688); // 轮询一次
}; };
/** /**
@@ -1212,10 +1291,14 @@ const iconDialogVisible = ref(false);
let hasUpdates = false; let hasUpdates = false;
// 检查面板组生成状态 // 检查面板组生成状态
if (currentPanelNode.value?.panelInfo?.thumbnail_small === '生成中') { // 遍历所有需要轮询的面板组GUID
const panelListGuid = currentPanelNode.value.panelGuid; for (const panelListGuid of pollingItems.value.panelLists) {
const updated = await checkPanelListStatus(panelListGuid); try {
if (updated) hasUpdates = true; const updated = await checkPanelListStatus(panelListGuid);
if (updated) hasUpdates = true;
} catch (error) {
console.error(`检查面板组 ${panelListGuid} 状态失败:`, error);
}
} }
// 检查面板单元生成状态 // 检查面板单元生成状态
@@ -1249,12 +1332,10 @@ const iconDialogVisible = ref(false);
try { try {
const rs = await localHttp.post('PanelSelection/WebPanelListQueryByGuid', const rs = await localHttp.post('PanelSelection/WebPanelListQueryByGuid',
JSON.stringify({ GUID: panelListGuid })); JSON.stringify({ GUID: panelListGuid }));
if (rs.data.isok && rs.data.response) { if (rs.data.isok && rs.data.response) {
const data = JSON.parse(rs.data.response); const data = JSON.parse(rs.data.response);
if (data.length > 0) { if (data.length > 0) {
const panelInfo = data[0]; const panelInfo = data[0];
// 检查是否仍然在生成中 // 检查是否仍然在生成中
if (panelInfo.thumbnail_small !== '生成中') { if (panelInfo.thumbnail_small !== '生成中') {
// 更新当前面板组信息 // 更新当前面板组信息
@@ -1264,8 +1345,60 @@ const iconDialogVisible = ref(false);
// 更新树节点中的面板组信息 // 更新树节点中的面板组信息
updatePanelNodeInTree(panelListGuid, panelInfo); updatePanelNodeInTree(panelListGuid, panelInfo);
// 更新生成历史记录
const recordIndex = generationHistory.value.findIndex(record => record.guid === panelListGuid);
if (recordIndex !== -1) {
const record = generationHistory.value[recordIndex];
let updatedRecord;
if (panelInfo.thumbnail_small !== '生成中') {
const endTime = Date.now();
const duration = record.startTime ? Math.round(((endTime - record.startTime) / 1000) * 10) / 10 : null;
if (record.type === GenerationType.CDR) {
// CDR生成完成
updatedRecord = {
...record,
status: GenerationStatus.COMPLETED,
progress: 100,
progressText: 'CDR生成完成',
completedAt: formatDate(new Date()),
duration: duration
};
} else {
// 图片生成完成
updatedRecord = {
...record,
status: GenerationStatus.COMPLETED,
progress: 100,
progressText: '图片生成完成',
completedAt: formatDate(new Date()),
duration: duration
};
}
}
// 使用splice确保响应式更新
generationHistory.value.splice(recordIndex, 1, updatedRecord);
// 停止进度间隔
if (progressIntervals.value.has(record.guid)) {
clearInterval(progressIntervals.value.get(record.guid));
progressIntervals.value.delete(record.guid);
}
// 将面板组GUID从轮询列表中移除
pollingItems.value.panelLists.delete(record.guid);
}
// 显示不同的成功消息
const msgRecordIndex = generationHistory.value.findIndex(record => record.guid === panelListGuid);
if (msgRecordIndex !== -1) {
const record = generationHistory.value[msgRecordIndex];
if (record.type === GenerationType.CDR) {
ElMessage.success('CDR文件生成完成');
} else {
ElMessage.success('面板组预览图生成完成!');
}
} else {
ElMessage.success('生成完成!');
}
ElMessage.success('面板组预览图生成完成!');
return true; // 返回true表示有更新 return true; // 返回true表示有更新
} }
} }
@@ -1289,7 +1422,7 @@ const iconDialogVisible = ref(false);
const data = JSON.parse(rs.data.response); const data = JSON.parse(rs.data.response);
if (data.length > 0) { if (data.length > 0) {
const panelUnit = data[0]; const panelUnit = data[0];
console.log('面板单元状态:', panelUnit);
// 检查是否仍然在生成中 // 检查是否仍然在生成中
if (panelUnit.design_status !== '生成中') { if (panelUnit.design_status !== '生成中') {
// 更新面板单元列表 // 更新面板单元列表
@@ -1304,6 +1437,34 @@ const iconDialogVisible = ref(false);
currentPanelUnit.value = panelUnitGuid; currentPanelUnit.value = panelUnitGuid;
} }
// 更新生成历史记录
const recordIndex = generationHistory.value.findIndex(record => record.guid === panelUnitGuid);
if (recordIndex !== -1) {
const record = generationHistory.value[recordIndex];
const endTime = Date.now();
const duration = record.startTime ? Math.round(((endTime - record.startTime) / 1000) * 10) / 10 : null;
let updatedRecord;
if (panelUnit.design_status !== '生成中') {
// 生成成功
updatedRecord = {
...record,
status: GenerationStatus.COMPLETED,
progress: 100,
progressText: '生成完成',
completedAt: formatDate(new Date()),
duration: duration
};
}
// 使用splice确保响应式更新
generationHistory.value.splice(recordIndex, 1, updatedRecord);
// 停止进度间隔
if (progressIntervals.value.has(record.guid)) {
clearInterval(progressIntervals.value.get(record.guid));
progressIntervals.value.delete(record.guid);
}
}
ElMessage.success('单面板预览图生成完成!'); ElMessage.success('单面板预览图生成完成!');
return true; // 返回true表示有更新 return true; // 返回true表示有更新
} }
@@ -1349,7 +1510,7 @@ const iconDialogVisible = ref(false);
loadingInstance = ElLoading.service({ loadingInstance = ElLoading.service({
lock: true, lock: true,
text: text, text: text,
background: 'rgba(0, 0, 0, 0.7)', background: 'rgba(0, 0, 0, 0)',
}); });
}; };
@@ -1479,6 +1640,65 @@ const iconDialogVisible = ref(false);
} }
}; };
/**
* 打开复制面板对话框
*/
const copyPanelUnit = (row) => {
copyPanelUnitRow.value = row;
selectedCopyProjectId.value = null;
selectedCopyProjectGuid.value = null;
showCopyPanelDialog.value = true;
};
/**
* 处理复制项目选择变化
*/
const handleCopyProjectChange = async (projectId) => {
const selectedProject = projectList.value.find(project => project.id === projectId);
if (selectedProject) {
const webProject = await getWebProjectByHotelName(selectedProject.projectName);
selectedCopyProjectGuid.value = webProject ? webProject.guid : null;
} else {
selectedCopyProjectGuid.value = null;
}
};
/**
* 确认复制面板
*/
const confirmCopyPanel = async () => {
if (!selectedCopyProjectId.value) {
ElMessage.warning('请选择目标项目');
return;
}
if (!copyPanelUnitRow.value || !copyPanelUnitRow.value.guid) {
ElMessage.error('无效的面板数据');
return;
}
try {
// 调用后端API复制面板
const rs = await localHttp.post('PanelSelection/CopyPanelUnitWithNewFields', {
OriginalGuid: copyPanelUnitRow.value.guid,
NewOwner: getCurrentUser(),
NewProjectGuid: selectedCopyProjectGuid.value
});
if (rs.data.isok) {
ElMessage.success('面板复制成功');
showCopyPanelDialog.value = false;
// 刷新面板单元列表
//await loadPanelUnitsByProject(copyPanelUnitRow.value.project_guid);
} else {
ElMessage.error('面板复制失败: ' + rs.data.message);
}
} catch (error) {
console.error('复制面板失败:', error);
ElMessage.error('复制面板失败');
}
};
/** /**
* 等待辅助函数: 轮询直到 predicate 返回 true 或超时 * 等待辅助函数: 轮询直到 predicate 返回 true 或超时
*/ */
@@ -1867,8 +2087,8 @@ const iconDialogVisible = ref(false);
// 检查是否是切换到不同的面板组 // 检查是否是切换到不同的面板组
const isDifferentPanel = currentPanelNode.value && const isDifferentPanel = currentPanelNode.value &&
data.type === 'panel' && data.type === 'panel' &&
currentPanelNode.value.panelGuid !== data.panelGuid; currentPanelNode.value.panelGuid !== data.panelGuid;
// 只有切换到不同的面板组时才清空右侧配置表格,但不清空面板单元数据 // 只有切换到不同的面板组时才清空右侧配置表格,但不清空面板单元数据
if (isDifferentPanel || data.type !== 'panel') { if (isDifferentPanel || data.type !== 'panel') {
@@ -1877,7 +2097,7 @@ const iconDialogVisible = ref(false);
patternsList.value = []; patternsList.value = [];
// 不清空currentPanelUnit.value保留用户的选择状态 // 不清空currentPanelUnit.value保留用户的选择状态
// currentPanelUnit.value = null; // 注释掉这行,保留选择状态 // currentPanelUnit.value = null; // 注释掉这行,保留选择状态
panelUnitForm.value = []; //panelUnitForm.value = [];
} }
if (data.type === 'panel') { if (data.type === 'panel') {
@@ -2669,7 +2889,7 @@ const iconDialogVisible = ref(false);
// panelUnitForm.value = []; // panelUnitForm.value = [];
// singlePanelPreview.value = ''; // 新增:清除单面板预览图 // singlePanelPreview.value = ''; // 新增:清除单面板预览图
ElMessage.success('面板配置加载成功'); //ElMessage.success('面板配置加载成功');
} catch (error) { } catch (error) {
console.error('加载面板配置失败:', error); console.error('加载面板配置失败:', error);
ElMessage.error('加载面板配置失败'); ElMessage.error('加载面板配置失败');
@@ -2938,19 +3158,6 @@ const iconDialogVisible = ref(false);
const panelInfo = await getPanelInfoByGuid(currentPanelNode.value.panelGuid); const panelInfo = await getPanelInfoByGuid(currentPanelNode.value.panelGuid);
let previewObject = null; let previewObject = null;
/*if (panelInfo && panelInfo.remarks) {
try {
const savedConfig = JSON.parse(panelInfo.remarks);
if (savedConfig.structureData) {
previewObject = savedConfig.structureData;
// 更新Process类型
previewObject.Process = ProcessType;
}
} catch (e) {
console.warn('从remark字段读取面板组配置失败重新生成:', e);
}
}*/
// 如果没有从remark读取到则重新生成 // 如果没有从remark读取到则重新生成
if (!previewObject) { if (!previewObject) {
previewObject = await generatePanelGroupStructureData(true); previewObject = await generatePanelGroupStructureData(true);
@@ -2973,33 +3180,52 @@ const iconDialogVisible = ref(false);
if (rs.data.isok) { if (rs.data.isok) {
const rsv = rs.data.response; const rsv = rs.data.response;
if (rsv) { if (rsv) {
// 更新面板组信息 // 更新面板组信息
if (panelInfo) { if (panelInfo) {
const updateData = { const updateData = {
...panelInfo, ...panelInfo,
thumbnail_small: "生成中" remarks: JSON.stringify({
structureData: previewObject,
savedAt: new Date().toISOString(),
version: '1.0',
lastGenerated: Date.now()
})
}; };
if (ProcessType === 0) {
// 图片生成
updateData.thumbnail_small = "生成中";
} else {
// CDR生成
updateData.thumbnail_small = "生成中";
}
await updateDatabase('PanelSelection/WebPanelListUpdate', updateData); await updateDatabase('PanelSelection/WebPanelListUpdate', updateData);
// 将生成的完整previewObject保存到remark字段
try {
const saveData = {
...panelInfo,
remarks: JSON.stringify({
structureData: previewObject,
savedAt: new Date().toISOString(),
version: '1.0',
lastGenerated: Date.now()
})
};
await updateDatabase('PanelSelection/WebPanelListUpdate', saveData);
} catch (saveError) {
console.error('保存面板组预览对象到remark字段失败:', saveError);
}
} }
// 添加生成记录到历史
const project = projectList.value.find(p => p.id === selectedProjectId.value);
const startTime = new Date();
const record = {
id: Date.now() + Math.random().toString(36).substr(2, 9),
guid: currentPanelNode.value.panelGuid,
name: `${project?.projectName || ''}_${currentPanelNode.value.panelInfo.panel_list_name || ''}`,
type: ProcessType === 0 ? GenerationType.PREVIEW : GenerationType.CDR,
status: GenerationStatus.IN_PROGRESS,
progress: 0,
progressText: ProcessType === 0 ? '正在生成预览图...' : '正在生成CDR文件...',
createdAt: formatDate(startTime),
startTime: startTime.getTime(),
completedAt: null,
duration: null
};
generationHistory.value.unshift(record);
// 将面板组GUID添加到轮询列表
pollingItems.value.panelLists.add(record.guid);
const MIN_EXECUTION_TIME = 555; const MIN_EXECUTION_TIME = 555;
const elapsedTime = performance.now() - startTime; const elapsedTime = performance.now() - startTime;
const remainingTime = MIN_EXECUTION_TIME - elapsedTime; const remainingTime = MIN_EXECUTION_TIME - elapsedTime;
@@ -3044,24 +3270,10 @@ const iconDialogVisible = ref(false);
try { try {
// 从remark字段读取已保存的previewObject // 从remark字段读取已保存的previewObject
const panelUnits = await fetchData('PanelSelection/WebPanelUnitQuery'); const panelUnits = await fetchData('PanelSelection/WebPanelUnitQueryByGuid', { GUID: currentPanelUnit.value });
const panelUnit = panelUnits.find(p => p.guid === currentPanelUnit.value); const panelUnit = panelUnits[0];
let previewObject = null; let previewObject = null;
/* if (panelUnit && panelUnit.remarks) {
try {
const savedConfig = JSON.parse(panelUnit.remarks);
if (savedConfig.previewObject) {
previewObject = savedConfig.previewObject;
// 更新Process为生成图片
previewObject.Process = 0;
}
} catch (e) {
console.warn('从remark字段读取单个面板配置失败重新生成:', e);
}
} */
// 如果没有从remark读取到则重新生成 // 如果没有从remark读取到则重新生成
if (!previewObject) { if (!previewObject) {
previewObject = await generateSinglePanelPreviewObject(true); previewObject = await generateSinglePanelPreviewObject(true);
@@ -3084,16 +3296,11 @@ const iconDialogVisible = ref(false);
if (rs.data.isok) { if (rs.data.isok) {
const rsv = rs.data.response; const rsv = rs.data.response;
if (rsv) { if (rsv) {
// 更新面板单元的缩略图
await updateDatabase('PanelSelection/WebPanelUnitUpdate', {
...panelUnit,
design_status: "生成中"
});
// 将生成的完整previewObject保存到remark字段 // 将生成的完整previewObject保存到remark字段
try { try {
const saveData = { const saveData = {
...panelUnit, ...panelUnit,
design_status: "生成中",
remarks: JSON.stringify({ remarks: JSON.stringify({
previewObject: previewObject, previewObject: previewObject,
savedAt: new Date().toISOString(), savedAt: new Date().toISOString(),
@@ -3101,12 +3308,29 @@ const iconDialogVisible = ref(false);
lastGenerated: Date.now() lastGenerated: Date.now()
}) })
}; };
await updateDatabase('PanelSelection/WebPanelUnitUpdate', saveData); await updateDatabase('PanelSelection/WebPanelUnitUpdate', saveData);
console.log('单个面板预览对象已保存到remark字段');
} catch (saveError) { } catch (saveError) {
console.error('保存单个面板预览对象到remark字段失败:', saveError); console.error('保存单个面板预览对象到remark字段失败:', saveError);
} }
// 添加生成记录到历史
const project = projectList.value.find(p => p.id === selectedProjectId.value);
const startTime = new Date();
const record = {
id: Date.now() + Math.random().toString(36).substr(2, 9),
guid: currentPanelUnit.value,
name: `${project?.projectName || ''}_${panelUnit.panel_name || ''}`,
type: GenerationType.SINGLE_PANEL,
status: GenerationStatus.IN_PROGRESS,
progress: 0,
progressText: '正在生成单个面板预览图...',
createdAt: formatDate(startTime),
startTime: startTime.getTime(),
completedAt: null,
duration: null
};
generationHistory.value.unshift(record);
// 更新本地数据 // 更新本地数据
const unitIndex = unitTableData.value.findIndex(u => u.guid === currentPanelUnit.value); const unitIndex = unitTableData.value.findIndex(u => u.guid === currentPanelUnit.value);
@@ -3261,9 +3485,9 @@ const iconDialogVisible = ref(false);
if (!panelUnitGuid) return false; if (!panelUnitGuid) return false;
try { try {
const panelUnits = await fetchData('PanelSelection/WebPanelUnitQuery'); const panelUnits = await fetchData('PanelSelection/WebPanelUnitQueryByGuid', { GUID: panelUnitGuid });
const panelUnit = panelUnits.find(p => p.guid === panelUnitGuid && p.is_valid); const panelUnit = panelUnits[0];
return !!panelUnit; return !!panelUnit && panelUnit.is_valid;
} catch (error) { } catch (error) {
console.error('检查面板单元存在性失败:', error); console.error('检查面板单元存在性失败:', error);
return false; return false;
@@ -3275,9 +3499,8 @@ const iconDialogVisible = ref(false);
*/ */
const loadSavedPanelUnitConfig = async (panelUnitGuid) => { const loadSavedPanelUnitConfig = async (panelUnitGuid) => {
try { try {
const panelUnits = await fetchData('PanelSelection/WebPanelUnitQuery'); const panelUnits = await fetchData('PanelSelection/WebPanelUnitQueryByGuid', { GUID: panelUnitGuid });
const panelUnit = panelUnits.find(p => p.guid === panelUnitGuid); const panelUnit = panelUnits[0];
if (panelUnit) { if (panelUnit) {
// 检查 elements_json 是否为空或无效 // 检查 elements_json 是否为空或无效
if (!panelUnit.elements_json || panelUnit.elements_json === 'null' || panelUnit.elements_json === '[]' || panelUnit.elements_json === '{}') { if (!panelUnit.elements_json || panelUnit.elements_json === 'null' || panelUnit.elements_json === '[]' || panelUnit.elements_json === '{}') {
@@ -3349,9 +3572,8 @@ const iconDialogVisible = ref(false);
currentPanelUnit.value = panelUnitGuid; currentPanelUnit.value = panelUnitGuid;
// 获取面板单元详细信息 // 获取面板单元详细信息
const panelUnits = await fetchData('PanelSelection/WebPanelUnitQuery'); const panelUnits = await fetchData('PanelSelection/WebPanelUnitQueryByGuid', { GUID: panelUnitGuid });
const panelUnit = panelUnits.find(p => p.guid === panelUnitGuid); const panelUnit = panelUnits[0];
if (!panelUnit) { if (!panelUnit) {
ElMessage.error('未找到面板单元信息'); ElMessage.error('未找到面板单元信息');
return; return;
@@ -3445,7 +3667,7 @@ const iconDialogVisible = ref(false);
// 更新树节点中的面板组信息 // 更新树节点中的面板组信息
updatePanelNodeInTree(currentPanelNode.value.panelGuid, panelInfo); updatePanelNodeInTree(currentPanelNode.value.panelGuid, panelInfo);
if (panelInfo.thumbnail_large && panelInfo.thumbnail_large !== '生成中') { if (panelInfo.thumbnail_large && panelInfo.thumbnail_small !== '生成中') {
panelGroupPreview.value = config.PicAds + panelInfo.thumbnail_large; panelGroupPreview.value = config.PicAds + panelInfo.thumbnail_large;
ElMessage.success('面板组预览图刷新成功'); ElMessage.success('面板组预览图刷新成功');
} else { } else {
@@ -3590,8 +3812,8 @@ const iconDialogVisible = ref(false);
// 如果没有任何数据,保存空数组 // 如果没有任何数据,保存空数组
const elementsToSave = flatData.length > 0 ? flatData : []; const elementsToSave = flatData.length > 0 ? flatData : [];
const panelUnits = await fetchData('PanelSelection/WebPanelUnitQuery'); const panelUnits = await fetchData('PanelSelection/WebPanelUnitQueryByGuid', { GUID: currentPanelUnit.value });
const panelUnit = panelUnits.find(p => p.guid === currentPanelUnit.value); const panelUnit = panelUnits[0];
if (panelUnit) { if (panelUnit) {
let projectGuid = ''; let projectGuid = '';
@@ -3613,11 +3835,9 @@ const iconDialogVisible = ref(false);
element_count: elementsToSave.length, element_count: elementsToSave.length,
// 清空预览相关字段 // 清空预览相关字段
thumbnail_large: '', thumbnail_large: '',
thumbnail_small: '', cdr_filename: ''
cdr_filename: '',
design_status: '空闲'
}; };
console.log('updateData', updateData);
await updateDatabase('PanelSelection/WebPanelUnitUpdate', updateData); await updateDatabase('PanelSelection/WebPanelUnitUpdate', updateData);
// 保存成功后刷新面板单元列表 // 保存成功后刷新面板单元列表
@@ -3988,9 +4208,7 @@ const iconDialogVisible = ref(false);
// 清空预览相关字段 // 清空预览相关字段
elements_json: '[]', elements_json: '[]',
thumbnail_large: '', thumbnail_large: '',
thumbnail_small: '', cdr_filename: ''
cdr_filename: '',
design_status: '空闲'
}; };
await updateDatabase('PanelSelection/WebPanelUnitUpdate', updateData); await updateDatabase('PanelSelection/WebPanelUnitUpdate', updateData);
@@ -4398,9 +4616,8 @@ const iconDialogVisible = ref(false);
} }
// 获取当前面板单元信息 // 获取当前面板单元信息
const panelUnits = await fetchData('PanelSelection/WebPanelUnitQuery'); const panelUnits = await fetchData('PanelSelection/WebPanelUnitQueryByGuid', { GUID: currentPanelUnit.value });
const panelUnit = panelUnits.find(p => p.guid === currentPanelUnit.value); const panelUnit = panelUnits[0];
if (panelUnit) { if (panelUnit) {
// 准备保存的数据 // 准备保存的数据
const saveData = { const saveData = {
@@ -4502,9 +4719,8 @@ const iconDialogVisible = ref(false);
const pictureNum = `Unit_${projectName}_${pictureNumSuffix}`; const pictureNum = `Unit_${projectName}_${pictureNumSuffix}`;
// 获取当前面板单元信息 // 获取当前面板单元信息
const panelUnits = await fetchData('PanelSelection/WebPanelUnitQuery'); const panelUnits = await fetchData('PanelSelection/WebPanelUnitQueryByGuid', { GUID: currentPanelUnit.value });
const panelUnit = panelUnits.find(p => p.guid === currentPanelUnit.value); const panelUnit = panelUnits[0];
if (!panelUnit) return null; if (!panelUnit) return null;
let materialLibraryName = ''; let materialLibraryName = '';
@@ -4721,9 +4937,9 @@ const iconDialogVisible = ref(false);
} }
// 2. 重新获取面板单元数据 // 2. 重新获取面板单元数据
const latestPanelUnits = await fetchData('PanelSelection/WebPanelUnitQuery'); /* const latestPanelUnits = await fetchData('PanelSelection/WebPanelUnitQuery');
// 更新availablePanelUnits // 更新unitTableDataavailablePanelUnits会自动计算
availablePanelUnits.value = latestPanelUnits.filter(unit => unit.is_valid); unitTableData.value = latestPanelUnits;*/
// 3. 重新初始化面板配置表格,确保数据是最新的 // 3. 重新初始化面板配置表格,确保数据是最新的
initPanelConfigTable(currentPanelNode.value); initPanelConfigTable(currentPanelNode.value);
@@ -5386,9 +5602,6 @@ const iconDialogVisible = ref(false);
watch([currentPanelNode, currentPanelUnitObj], () => { watch([currentPanelNode, currentPanelUnitObj], () => {
managePolling(); managePolling();
}, { deep: true }); }, { deep: true });
watch(selectedProjectId, () => {
stopPolling();
});
// 持久化 selectedProjectId 到 localStorage // 持久化 selectedProjectId 到 localStorage
watch(selectedProjectId, (val) => { watch(selectedProjectId, (val) => {
try { try {
@@ -5536,7 +5749,7 @@ const iconDialogVisible = ref(false);
} }
.left-bottom-bottom { .left-bottom-bottom {
height: 52%; height: 50%;
overflow: hidden; overflow: hidden;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -5554,8 +5767,28 @@ const iconDialogVisible = ref(false);
overflow: auto; overflow: auto;
} }
.left-bottom-dynamic-list {
height: 30%;
overflow: hidden;
display: flex;
flex-direction: column;
}
.left-bottom-dynamic-list .section-header {
padding: 0px;
border-bottom: 1px solid #e0e0e0;
background: #f8f9fa;
margin: 0;
}
.left-bottom-dynamic-list .table-content {
flex: 1;
padding: 0px;
overflow: auto;
}
.left-bottom-top { .left-bottom-top {
height: 48%; height: 77%;
overflow: hidden; overflow: hidden;
} }

View File

@@ -9,6 +9,7 @@ import SwitchSelection from '../pages/switchselection/index.vue';
import PanelSelection from '../pages/panelselection/index.vue'; import PanelSelection from '../pages/panelselection/index.vue';
import Log from '../pages/log/index.vue'; import Log from '../pages/log/index.vue';
import DicManage from '../pages/dicmanage/index.vue'; import DicManage from '../pages/dicmanage/index.vue';
import DownLoad from '../pages/download/index.vue';
const routes = [ const routes = [
@@ -75,10 +76,16 @@ const routes = [
}, },
{ {
path: '/panelselection', path: '/panelselection',
name: '开关选型', name: '面板选型',
component: PanelSelection, component: PanelSelection,
meta: { requiresAuth: true } // 需要认证的路由 meta: { requiresAuth: true } // 需要认证的路由
}, },
{
path: '/download',
name: '文件下载',
component: DownLoad,
meta: { requiresAuth: false } // 不需要认证的路由
},
{ {
path: '/:pathMatch(.*)*', path: '/:pathMatch(.*)*',
name: '404错误', name: '404错误',