|
|
@@ -7,17 +7,19 @@
|
|
|
<div class="w-1/3 p-2 border-r">示意图</div>
|
|
|
<!-- 中间 Table -->
|
|
|
<div class="w-1/3 p-2 border-r table-container">
|
|
|
- <el-radio-group v-model="screenNum" @change="screenChange">
|
|
|
- <el-radio-button label="第一屏" value="1" v-if="splitScreen !== 4" />
|
|
|
- <el-radio-button label="第二屏" value="2" v-if="splitScreen !== 4" />
|
|
|
- <el-radio-button label="第三屏" value="3" v-if="splitScreen === 3" />
|
|
|
- <el-radio-button label="播放框" value="4" v-if="splitScreen === 4" />
|
|
|
+ <el-radio-group v-model="screenNum" @change="screenChange" :key="splitScreen">
|
|
|
+ <el-radio-button label="第一屏" :key="'screen1'" value="1" v-if="splitScreen !== 4" />
|
|
|
+ <el-radio-button label="第二屏" :key="'screen2'" value="2" v-if="splitScreen !== 4" />
|
|
|
+ <el-radio-button label="第三屏" :key="'screen3'" value="3" v-if="splitScreen === 3" />
|
|
|
+ <el-radio-button label="播放框" :key="'screen4'" value="4" v-if="splitScreen === 4" />
|
|
|
</el-radio-group>
|
|
|
- <el-table :data="minioDataList" ref="minioTable"
|
|
|
- @selection-change="handleSelectionFile"
|
|
|
- @select="handleSelect"
|
|
|
- @select-all="handleSelectAll"
|
|
|
- style="margin-top: 20px">
|
|
|
+ <el-skeleton :rows="5" animated style="margin-top: 20px" v-show="loadingFileList">
|
|
|
+ <template #template>
|
|
|
+ <el-skeleton-item variant="text" style="height: 40px; margin-bottom: 10px" v-for="i in 5" :key="i" />
|
|
|
+ </template>
|
|
|
+ </el-skeleton>
|
|
|
+ <el-table :data="minioDataList" ref="minioTable" @selection-change="handleSelectionFile" @select="handleSelect"
|
|
|
+ @select-all="handleSelectAll" style="margin-top: 20px" v-show="!loadingFileList">
|
|
|
<el-table-column type="selection" width="55" align="center" />
|
|
|
<el-table-column label="原名" align="left" prop="originalName" width="150" :show-overflow-tooltip="true" />
|
|
|
<el-table-column label="类型" align="center" prop="type" width="80">
|
|
|
@@ -29,7 +31,9 @@
|
|
|
<el-table-column label="时长" align="center" prop="duration" />
|
|
|
<el-table-column label="截图" align="center" prop="screenshot">
|
|
|
<template #default="scope">
|
|
|
- <image-preview :src="scope.row.screenshot" style="width: 40px; height: 40px; cursor: pointer" />
|
|
|
+ <template v-if="scope.row.screenshot">
|
|
|
+ <image-preview :src="scope.row.screenshot" style="width: 40px; height: 40px; cursor: pointer" />
|
|
|
+ </template>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
@@ -39,68 +43,116 @@
|
|
|
<!-- 右侧内容 -->
|
|
|
<div class="w-1/3 p-2">
|
|
|
<div v-if="screenNum === '1'" class="table-container">
|
|
|
- <div class="draggable-header" style="display: flex; align-items: center; background: #fafafa; border-bottom: 1px solid #eee; min-height: 48px; font-weight: bold">
|
|
|
+ <div class="draggable-header"
|
|
|
+ style="display: flex; align-items: center; background: #fafafa; border-bottom: 1px solid #eee; min-height: 48px; font-weight: bold">
|
|
|
<span style="width: 80px; text-align: center">排序</span>
|
|
|
<span style="flex: 1">文件名</span>
|
|
|
<span style="width: 120px; margin-left: 8px">播放时长</span>
|
|
|
</div>
|
|
|
- <draggable v-model="selectedFiles1" item-key="id" @end="onSelectedFilesDragEnd('1')" :animation="200" tag="div">
|
|
|
+ <draggable v-model="selectedFiles1" item-key="id" @end="onSelectedFilesDragEnd('1')" :animation="200"
|
|
|
+ tag="div">
|
|
|
<template #item="{ element, index }">
|
|
|
- <div class="draggable-row" :draggable="true" style="display: flex; align-items: center; border-bottom: 1px solid #eee; min-height: 48px; cursor: move">
|
|
|
+ <div class="draggable-row" :draggable="true" :key="String(element.id)"
|
|
|
+ style="display: flex; align-items: center; border-bottom: 1px solid #eee; min-height: 48px; cursor: move">
|
|
|
<span class="order-number" style="width: 80px; text-align: center">{{ index + 1 }}</span>
|
|
|
- <span style="flex: 1; max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: inline-block; vertical-align: middle;">{{ element.name }}</span>
|
|
|
- <el-input-number v-model="element.duration" :min="1" :max="300" style="width: 120px; margin-left: 8px" />
|
|
|
+ <span style="
|
|
|
+ flex: 1;
|
|
|
+ max-width: 240px;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ display: inline-block;
|
|
|
+ vertical-align: middle;
|
|
|
+ ">{{ element.name }}</span>
|
|
|
+ <el-input-number v-model="element.duration" :min="1" :max="300"
|
|
|
+ style="width: 120px; margin-left: 8px" />
|
|
|
</div>
|
|
|
</template>
|
|
|
</draggable>
|
|
|
<div v-if="selectedFiles1.length === 0" style="text-align: center; color: #999; padding: 16px 0">暂无数据</div>
|
|
|
</div>
|
|
|
<div v-if="screenNum === '2'" class="table-container">
|
|
|
- <div class="draggable-header" style="display: flex; align-items: center; background: #fafafa; border-bottom: 1px solid #eee; min-height: 48px; font-weight: bold">
|
|
|
+ <div class="draggable-header"
|
|
|
+ style="display: flex; align-items: center; background: #fafafa; border-bottom: 1px solid #eee; min-height: 48px; font-weight: bold">
|
|
|
<span style="width: 80px; text-align: center">排序</span>
|
|
|
<span style="flex: 1">文件名</span>
|
|
|
<span style="width: 120px; margin-left: 8px">播放时长</span>
|
|
|
</div>
|
|
|
- <draggable v-model="selectedFiles2" item-key="id" @end="onSelectedFilesDragEnd('2')" :animation="200" tag="div">
|
|
|
+ <draggable v-model="selectedFiles2" item-key="id" @end="onSelectedFilesDragEnd('2')" :animation="200"
|
|
|
+ tag="div">
|
|
|
<template #item="{ element, index }">
|
|
|
- <div class="draggable-row" :draggable="true" style="display: flex; align-items: center; border-bottom: 1px solid #eee; min-height: 48px; cursor: move">
|
|
|
+ <div class="draggable-row" :draggable="true"
|
|
|
+ style="display: flex; align-items: center; border-bottom: 1px solid #eee; min-height: 48px; cursor: move">
|
|
|
<span class="order-number" style="width: 80px; text-align: center">{{ index + 1 }}</span>
|
|
|
- <span style="flex: 1; max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: inline-block; vertical-align: middle;">{{ element.name }}</span>
|
|
|
- <el-input-number v-model="element.duration" :min="1" :max="300" style="width: 120px; margin-left: 8px" />
|
|
|
+ <span style="
|
|
|
+ flex: 1;
|
|
|
+ max-width: 240px;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ display: inline-block;
|
|
|
+ vertical-align: middle;
|
|
|
+ ">{{ element.name }}</span>
|
|
|
+ <el-input-number v-model="element.duration" :min="1" :max="300"
|
|
|
+ style="width: 120px; margin-left: 8px" />
|
|
|
</div>
|
|
|
</template>
|
|
|
</draggable>
|
|
|
<div v-if="selectedFiles2.length === 0" style="text-align: center; color: #999; padding: 16px 0">暂无数据</div>
|
|
|
</div>
|
|
|
<div v-if="screenNum === '3'" class="table-container">
|
|
|
- <div class="draggable-header" style="display: flex; align-items: center; background: #fafafa; border-bottom: 1px solid #eee; min-height: 48px; font-weight: bold">
|
|
|
+ <div class="draggable-header"
|
|
|
+ style="display: flex; align-items: center; background: #fafafa; border-bottom: 1px solid #eee; min-height: 48px; font-weight: bold">
|
|
|
<span style="width: 80px; text-align: center">排序</span>
|
|
|
<span style="flex: 1">文件名</span>
|
|
|
<span style="width: 120px; margin-left: 8px">播放时长</span>
|
|
|
</div>
|
|
|
- <draggable v-model="selectedFiles3" item-key="id" @end="onSelectedFilesDragEnd('3')" :animation="200" tag="div">
|
|
|
+ <draggable v-model="selectedFiles3" item-key="id" @end="onSelectedFilesDragEnd('3')" :animation="200"
|
|
|
+ tag="div">
|
|
|
<template #item="{ element, index }">
|
|
|
- <div class="draggable-row" :draggable="true" style="display: flex; align-items: center; border-bottom: 1px solid #eee; min-height: 48px; cursor: move">
|
|
|
+ <div class="draggable-row" :draggable="true"
|
|
|
+ style="display: flex; align-items: center; border-bottom: 1px solid #eee; min-height: 48px; cursor: move">
|
|
|
<span class="order-number" style="width: 80px; text-align: center">{{ index + 1 }}</span>
|
|
|
- <span style="flex: 1; max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: inline-block; vertical-align: middle;">{{ element.name }}</span>
|
|
|
- <el-input-number v-model="element.duration" :min="1" :max="300" style="width: 120px; margin-left: 8px" />
|
|
|
+ <span style="
|
|
|
+ flex: 1;
|
|
|
+ max-width: 240px;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ display: inline-block;
|
|
|
+ vertical-align: middle;
|
|
|
+ ">{{ element.name }}</span>
|
|
|
+ <el-input-number v-model="element.duration" :min="1" :max="300"
|
|
|
+ style="width: 120px; margin-left: 8px" />
|
|
|
</div>
|
|
|
</template>
|
|
|
</draggable>
|
|
|
<div v-if="selectedFiles3.length === 0" style="text-align: center; color: #999; padding: 16px 0">暂无数据</div>
|
|
|
</div>
|
|
|
<div v-if="screenNum === '4'" class="table-container">
|
|
|
- <div class="draggable-header" style="display: flex; align-items: center; background: #fafafa; border-bottom: 1px solid #eee; min-height: 48px; font-weight: bold">
|
|
|
+ <div class="draggable-header"
|
|
|
+ style="display: flex; align-items: center; background: #fafafa; border-bottom: 1px solid #eee; min-height: 48px; font-weight: bold">
|
|
|
<span style="width: 80px; text-align: center">排序</span>
|
|
|
<span style="flex: 1">文件名</span>
|
|
|
<span style="width: 120px; margin-left: 8px">播放时长</span>
|
|
|
</div>
|
|
|
- <draggable v-model="selectedFiles4" item-key="id" @end="onSelectedFilesDragEnd('4')" :animation="200" tag="div">
|
|
|
+ <draggable v-model="selectedFiles4" item-key="id" @end="onSelectedFilesDragEnd('4')" :animation="200"
|
|
|
+ tag="div">
|
|
|
<template #item="{ element, index }">
|
|
|
- <div class="draggable-row" :draggable="true" style="display: flex; align-items: center; border-bottom: 1px solid #eee; min-height: 48px; cursor: move">
|
|
|
+ <div class="draggable-row" :draggable="true"
|
|
|
+ style="display: flex; align-items: center; border-bottom: 1px solid #eee; min-height: 48px; cursor: move">
|
|
|
<span class="order-number" style="width: 80px; text-align: center">{{ index + 1 }}</span>
|
|
|
- <span style="flex: 1; max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: inline-block; vertical-align: middle;">{{ element.name }}</span>
|
|
|
- <el-input-number v-model="element.duration" :min="1" :max="300" style="width: 120px; margin-left: 8px" />
|
|
|
+ <span style="
|
|
|
+ flex: 1;
|
|
|
+ max-width: 240px;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ display: inline-block;
|
|
|
+ vertical-align: middle;
|
|
|
+ ">{{ element.name }}</span>
|
|
|
+ <el-input-number v-model="element.duration" :min="1" :max="300"
|
|
|
+ style="width: 120px; margin-left: 8px" />
|
|
|
</div>
|
|
|
</template>
|
|
|
</draggable>
|
|
|
@@ -145,6 +197,7 @@ const dialogData = reactive<DialogPageData<MinioDataQuery>>({
|
|
|
}
|
|
|
});
|
|
|
const minioDataList = ref<MinioDataVO[]>([]);
|
|
|
+const loadingFileList = ref(false); // 控制骨架屏显示
|
|
|
const screenNum = ref<string>();
|
|
|
const itemSplitVo = ref<ItemSplitScreenVO>();
|
|
|
const splitScreen = ref(0);
|
|
|
@@ -161,19 +214,19 @@ const uploadForm = reactive<SplitUploadForm>({
|
|
|
});
|
|
|
|
|
|
const screenChange = () => {
|
|
|
- console.log(screenNum.value);
|
|
|
+ getFileList();
|
|
|
// minioTable.value.clearSelection();
|
|
|
};
|
|
|
|
|
|
const getParamItemId = () => {
|
|
|
itemId.value = route.params.itemId as string;
|
|
|
- console.log(itemId.value);
|
|
|
+
|
|
|
getItemInfo();
|
|
|
};
|
|
|
|
|
|
const getItemInfo = async () => {
|
|
|
const res = await splitItemInfo(itemId.value);
|
|
|
- console.log(res.data);
|
|
|
+
|
|
|
itemSplitVo.value = res.data;
|
|
|
splitScreen.value = res.data.splitScreen;
|
|
|
if (splitScreen.value === 4) {
|
|
|
@@ -181,6 +234,37 @@ const getItemInfo = async () => {
|
|
|
} else {
|
|
|
screenNum.value = '1';
|
|
|
}
|
|
|
+ // 回显每个分屏的已选文件
|
|
|
+ await restoreSelectedFiles();
|
|
|
+ // 查询第一页文件资源
|
|
|
+ await getFileList();
|
|
|
+};
|
|
|
+
|
|
|
+const restoreSelectedFiles = async () => {
|
|
|
+ // 针对 fileIdList1~4 分别处理
|
|
|
+ for (let n = 1; n <= 4; n++) {
|
|
|
+ const fileIdList = itemSplitVo.value?.[`fileIdList${n}`];
|
|
|
+ const selectedFilesRef = [null, selectedFiles1, selectedFiles2, selectedFiles3, selectedFiles4][n];
|
|
|
+ if (Array.isArray(fileIdList) && fileIdList.length) {
|
|
|
+ const fileRes = await listMinioData({ ids: fileIdList });
|
|
|
+ selectedFilesRef.value = fileIdList
|
|
|
+ .map((id: string | number, idx: number) => {
|
|
|
+ const file = fileRes.rows.find((f: any) => String(f.id) === String(id));
|
|
|
+ return file
|
|
|
+ ? {
|
|
|
+ id: file.id,
|
|
|
+ name: file.originalName,
|
|
|
+ type: file.type,
|
|
|
+ duration: file.type === 1 ? 10 : Number(file.duration),
|
|
|
+ order: idx + 1
|
|
|
+ }
|
|
|
+ : null;
|
|
|
+ })
|
|
|
+ .filter(Boolean);
|
|
|
+ } else {
|
|
|
+ selectedFilesRef.value = [];
|
|
|
+ }
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
// 多选框选中文件数据(与 index.vue 保持一致,支持增量、去重、排序)
|
|
|
@@ -238,21 +322,26 @@ const handleSelectAll = (selection: MinioDataVO[]) => {
|
|
|
};
|
|
|
/** 查询文件资源列表 */
|
|
|
const getFileList = async () => {
|
|
|
- const res = await listMinioData(dialogQueryParams.value);
|
|
|
- minioDataList.value = res.rows.map((data) => ({
|
|
|
- ...data,
|
|
|
- size: (parseFloat(data.size) / 1024).toFixed(3) + 'MB'
|
|
|
- }));
|
|
|
- fileTotal.value = res.total;
|
|
|
- // 加载后自动恢复选中(与 index.vue 保持一致)
|
|
|
- nextTick(() => {
|
|
|
+ loadingFileList.value = true;
|
|
|
+ try {
|
|
|
+ const res = await listMinioData(dialogQueryParams.value);
|
|
|
+ minioDataList.value = res.rows.map((data) => ({
|
|
|
+ ...data,
|
|
|
+ size: (parseFloat(data.size) / 1024).toFixed(3) + 'MB'
|
|
|
+ }));
|
|
|
+ fileTotal.value = res.total;
|
|
|
+ } catch (e) {
|
|
|
+ console.error('文件列表加载失败', e);
|
|
|
+ } finally {
|
|
|
+ loadingFileList.value = false;
|
|
|
+ await nextTick();
|
|
|
+ // 高亮当前分屏
|
|
|
let selectedFilesRef;
|
|
|
if (screenNum.value === '1') selectedFilesRef = selectedFiles1;
|
|
|
if (screenNum.value === '2') selectedFilesRef = selectedFiles2;
|
|
|
if (screenNum.value === '3') selectedFilesRef = selectedFiles3;
|
|
|
if (screenNum.value === '4') selectedFilesRef = selectedFiles4;
|
|
|
- if (!selectedFilesRef) return;
|
|
|
- if (selectedFilesRef.value?.length) {
|
|
|
+ if (selectedFilesRef?.value?.length) {
|
|
|
const selectedIds = new Set(selectedFilesRef.value.map((f) => f.id));
|
|
|
minioDataList.value.forEach((row) => {
|
|
|
if (selectedIds.has(row.id)) {
|
|
|
@@ -260,7 +349,7 @@ const getFileList = async () => {
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
- });
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
/** 提交按钮 */
|
|
|
@@ -293,7 +382,6 @@ const onSelectedFilesDragEnd = (screen: string) => () => {
|
|
|
|
|
|
onMounted(() => {
|
|
|
getParamItemId();
|
|
|
- getFileList();
|
|
|
});
|
|
|
</script>
|
|
|
<style scoped>
|