|
@@ -18,13 +18,19 @@
|
|
</template>
|
|
</template>
|
|
<template v-else>
|
|
<template v-else>
|
|
<div class="body-head details-head">
|
|
<div class="body-head details-head">
|
|
- <h3 style="visibility: hidden">场景管理</h3>
|
|
|
|
|
|
+ <h3 style="visibility: hidden">绘图管理</h3>
|
|
<div>
|
|
<div>
|
|
<template v-if="isDraw">
|
|
<template v-if="isDraw">
|
|
- <el-button type="primary" @click="gotoDraw(BoardType.map, -1)">
|
|
|
|
|
|
+ <!-- <el-button type="primary" @click="gotoDraw(BoardType.map, -1)">
|
|
|
|
+ 创建{{ BoardTypeDesc[BoardType.map] }}
|
|
|
|
+ </el-button> -->
|
|
|
|
+ <el-button type="primary" @click="openMapDialog">
|
|
创建{{ BoardTypeDesc[BoardType.map] }}
|
|
创建{{ BoardTypeDesc[BoardType.map] }}
|
|
</el-button>
|
|
</el-button>
|
|
- <el-button type="primary" @click="gotoDraw(BoardType.scene, -1)">
|
|
|
|
|
|
+ <!-- <el-button type="primary" @click="gotoDraw(BoardType.scene, -1)">
|
|
|
|
+ 创建{{ BoardTypeDesc[BoardType.scene] }}
|
|
|
|
+ </el-button> -->
|
|
|
|
+ <el-button type="primary" @click="openOverView()">
|
|
创建{{ BoardTypeDesc[BoardType.scene] }}
|
|
创建{{ BoardTypeDesc[BoardType.scene] }}
|
|
</el-button>
|
|
</el-button>
|
|
</template>
|
|
</template>
|
|
@@ -33,8 +39,7 @@
|
|
</el-button>
|
|
</el-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
-
|
|
|
|
- <el-table
|
|
|
|
|
|
+ <!-- <el-table
|
|
:data="files"
|
|
:data="files"
|
|
class="table-list"
|
|
class="table-list"
|
|
tooltip-effect="dark"
|
|
tooltip-effect="dark"
|
|
@@ -87,7 +92,141 @@
|
|
</span>
|
|
</span>
|
|
<span class="oper-span delBtn" @click="del(row)"> 删除 </span>
|
|
<span class="oper-span delBtn" @click="del(row)"> 删除 </span>
|
|
</el-table-column>
|
|
</el-table-column>
|
|
- </el-table>
|
|
|
|
|
|
+ </el-table> -->
|
|
|
|
+
|
|
|
|
+ <!-- 卡片网格布局 -->
|
|
|
|
+ <div class="file-grid-container">
|
|
|
|
+ <div
|
|
|
|
+ class="file-card"
|
|
|
|
+ v-for="(file, index) in files"
|
|
|
|
+ :key="file.filesId"
|
|
|
|
+ >
|
|
|
|
+ <!-- 卡片图片容器 -->
|
|
|
|
+ <div class="card-image-container">
|
|
|
|
+ <el-image
|
|
|
|
+ ref="imageRef"
|
|
|
|
+ :src="file.type === 'old' ? file.filesUrl : file.listCover"
|
|
|
|
+ :preview-src-list="srcList"
|
|
|
|
+ :initial-index="index"
|
|
|
|
+ fit="cover"
|
|
|
|
+ class="card-image"
|
|
|
|
+ :hide-on-click-modal="true"
|
|
|
|
+ :preview-teleported="true"
|
|
|
|
+ >
|
|
|
|
+ <template #error>
|
|
|
|
+ <div class="image-error">
|
|
|
|
+ <el-icon size="40" color="#c0c4cc">
|
|
|
|
+ <Document />
|
|
|
|
+ </el-icon>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+ </el-image>
|
|
|
|
+
|
|
|
|
+ <!-- 悬浮操作按钮 -->
|
|
|
|
+ <div class="card-overlay">
|
|
|
|
+ <div class="card-actions">
|
|
|
|
+ <el-button
|
|
|
|
+ class="card-overlay-btn"
|
|
|
|
+ size="default"
|
|
|
|
+ circle
|
|
|
|
+ @click.stop="previewImage(index)"
|
|
|
|
+ title="查看"
|
|
|
|
+ >
|
|
|
|
+ <el-icon :size="20"><View /></el-icon>
|
|
|
|
+ </el-button>
|
|
|
|
+ <!-- 编辑按钮:old 类型不显示,其他类型显示 -->
|
|
|
|
+ <el-button
|
|
|
|
+ class="card-overlay-btn"
|
|
|
|
+ size="default"
|
|
|
|
+ circle
|
|
|
|
+ @click.stop="handleEdit(file)"
|
|
|
|
+ v-if="file.type !== 'old'"
|
|
|
|
+ title="编辑"
|
|
|
|
+ >
|
|
|
|
+ <el-icon :size="20"><Edit /></el-icon>
|
|
|
|
+ </el-button>
|
|
|
|
+ <!-- 对于 old 类型,保留原来的编辑逻辑 -->
|
|
|
|
+ <!-- <el-button
|
|
|
|
+ class="card-overlay-btn"
|
|
|
|
+ size="default"
|
|
|
|
+ circle
|
|
|
|
+ @click.stop="gotoDraw(file.imgType!, file.filesId)"
|
|
|
|
+ v-if="file.type === 'old' && file.imgType !== null"
|
|
|
|
+ title="编辑"
|
|
|
|
+ >
|
|
|
|
+ <el-icon :size="20"><Edit /></el-icon>
|
|
|
|
+ </el-button> -->
|
|
|
|
+ <el-button
|
|
|
|
+ class="card-overlay-btn"
|
|
|
|
+ size="default"
|
|
|
|
+ circle
|
|
|
|
+ @click.stop="del(file)"
|
|
|
|
+ title="删除"
|
|
|
|
+ >
|
|
|
|
+ <el-icon :size="20"><Delete /></el-icon>
|
|
|
|
+ </el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <!-- 卡片底部:文件名 -->
|
|
|
|
+ <div class="card-footer">
|
|
|
|
+ <div class="file-title">
|
|
|
|
+ <span v-if="!inputCaseTitles.includes(file)" class="title-text">
|
|
|
|
+ {{ file.type === 'old' ? file.filesTitle : file.title }}
|
|
|
|
+ <el-icon class="edit-title" @click="inputCaseTitles.push(file)">
|
|
|
|
+ <EditPen />
|
|
|
|
+ </el-icon>
|
|
|
|
+ </span>
|
|
|
|
+ <template v-else>
|
|
|
|
+ <ElInput
|
|
|
|
+ v-if="file.type === 'old'"
|
|
|
|
+ v-model="file.filesTitle"
|
|
|
|
+ placeholder="请输入文件名"
|
|
|
|
+ focus
|
|
|
|
+ :maxlength="50"
|
|
|
|
+ size="default"
|
|
|
|
+ class="edit-input"
|
|
|
|
+ >
|
|
|
|
+ <template #append>
|
|
|
|
+ <el-button type="primary" plain @click="updateFileTitle(file)">
|
|
|
|
+ 确定
|
|
|
|
+ </el-button>
|
|
|
|
+ </template>
|
|
|
|
+ </ElInput>
|
|
|
|
+ <ElInput
|
|
|
|
+ v-else
|
|
|
|
+ v-model="file.title"
|
|
|
|
+ placeholder="请输入文件名"
|
|
|
|
+ focus
|
|
|
|
+ :maxlength="50"
|
|
|
|
+ size="default"
|
|
|
|
+ class="edit-input"
|
|
|
|
+ >
|
|
|
|
+ <template #append>
|
|
|
|
+ <el-button type="primary" plain @click="updateFileTitle(file)">
|
|
|
|
+ 确定
|
|
|
|
+ </el-button>
|
|
|
|
+ </template>
|
|
|
|
+ </ElInput>
|
|
|
|
+ </template>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <el-image-viewer
|
|
|
|
+ v-if="showPreview"
|
|
|
|
+ :url-list="srcList"
|
|
|
|
+ :initial-index="currentPreviewIndex"
|
|
|
|
+ @close="showPreview = false"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <!-- 地图选择弹窗 -->
|
|
|
|
+ <CreatMap
|
|
|
|
+ v-model="showMapDialog"
|
|
|
|
+ :caseId="caseId"
|
|
|
|
+ @confirm="handleMapConfirm"
|
|
|
|
+ />
|
|
</template>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
@@ -108,12 +247,15 @@ import {
|
|
delCaseFile,
|
|
delCaseFile,
|
|
BoardType,
|
|
BoardType,
|
|
} from "@/store/caseFile";
|
|
} from "@/store/caseFile";
|
|
-import { getCaseInfo, updateCaseInfo } from "@/store/case";
|
|
|
|
|
|
+import { getCaseInfo, updateCaseInfo, getCaseTabulationList, getCaseOverviewList, updateCaseTabulation, updateCaseOverview, delCaseTabulation, delCaseOverview } from "@/store/case";
|
|
import { appConstant } from "@/app";
|
|
import { appConstant } from "@/app";
|
|
-import { ElIcon, ElInput, ElMessage } from "element-plus";
|
|
|
|
|
|
+import { ElIcon, ElInput, ElMessage, ElImage, ElButton } from "element-plus";
|
|
|
|
+import { EditPen, Document, View, Edit, Delete } from "@element-plus/icons-vue";
|
|
import Photos from "./photos/index.vue";
|
|
import Photos from "./photos/index.vue";
|
|
import Records from "./records/index.vue";
|
|
import Records from "./records/index.vue";
|
|
import Manifest from "./records/manifest.vue";
|
|
import Manifest from "./records/manifest.vue";
|
|
|
|
+import CreatMap from "./drawMap/creatMap.vue";
|
|
|
|
+import { user } from "@/store/user";
|
|
|
|
|
|
const props = defineProps<{
|
|
const props = defineProps<{
|
|
caseId?: number;
|
|
caseId?: number;
|
|
@@ -133,14 +275,71 @@ const caseInfoData = ref<any>();
|
|
|
|
|
|
const inputCaseTitles = ref<CaseFile[]>([]);
|
|
const inputCaseTitles = ref<CaseFile[]>([]);
|
|
|
|
|
|
|
|
+// 处理标题输入事件
|
|
|
|
+const handleTitleInput = (file: CaseFile, value: string) => {
|
|
|
|
+ if (file.type === 'old') {
|
|
|
|
+ file.filesTitle = value;
|
|
|
|
+ } else {
|
|
|
|
+ file.title = value;
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
const updateFileTitle = async (caseFile: CaseFile) => {
|
|
const updateFileTitle = async (caseFile: CaseFile) => {
|
|
- if (!caseFile.filesTitle.trim()) {
|
|
|
|
- return ElMessage.error("卷宗标题不能为空!");
|
|
|
|
|
|
+ // 根据文件类型检查不同的标题字段
|
|
|
|
+ const title = caseFile.type === 'old' ? caseFile.filesTitle : caseFile.title;
|
|
|
|
+ if (!title || !title.trim()) {
|
|
|
|
+ ElMessage.error("标题不能为空!");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ // 根据文件类型调用不同的更新接口
|
|
|
|
+ if (caseFile.type === 'old') {
|
|
|
|
+ await updateCaseInfo(caseFile);
|
|
|
|
+ } else if (caseFile.type === 'tabulation') {
|
|
|
|
+ // updateCaseTabulation 参数:id, caseId, store, viewport, cover, paperKey, overviewId, isAutoGen, listCover, mapUrl, high, width
|
|
|
|
+ await updateCaseTabulation({
|
|
|
|
+ id: caseFile.id,
|
|
|
|
+ caseId: caseFile.caseId,
|
|
|
|
+ store: caseFile.store,
|
|
|
|
+ viewport: caseFile.viewport,
|
|
|
|
+ cover: caseFile.cover,
|
|
|
|
+ paperKey: caseFile.paperKey,
|
|
|
|
+ overviewId: caseFile.overviewId,
|
|
|
|
+ isAutoGen: caseFile.isAutoGen,
|
|
|
|
+ listCover: caseFile.listCover,
|
|
|
|
+ mapUrl: caseFile.mapUrl,
|
|
|
|
+ high: caseFile.high,
|
|
|
|
+ width: caseFile.width,
|
|
|
|
+ title: title // 使用最新输入的 title
|
|
|
|
+ });
|
|
|
|
+ } else if (caseFile.type === 'overview') {
|
|
|
|
+ // updateCaseOverview 参数:id, caseId, store, title, cover, mapUrl, listCover, high, width, kankanCover
|
|
|
|
+ await updateCaseOverview({
|
|
|
|
+ id: caseFile.id,
|
|
|
|
+ caseId: caseFile.caseId,
|
|
|
|
+ store: caseFile.store,
|
|
|
|
+ title: title, // 使用最新输入的 title
|
|
|
|
+ cover: caseFile.cover,
|
|
|
|
+ mapUrl: caseFile.mapUrl,
|
|
|
|
+ listCover: caseFile.listCover,
|
|
|
|
+ high: caseFile.high,
|
|
|
|
+ width: caseFile.width,
|
|
|
|
+ kankanCover: caseFile.kankanCover
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ inputCaseTitles.value = inputCaseTitles.value.filter(
|
|
|
|
+ (item) => item !== caseFile
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ // 更新成功后刷新列表
|
|
|
|
+ refresh();
|
|
|
|
+ ElMessage.success("更新成功!");
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('更新失败:', error);
|
|
|
|
+ ElMessage.error("更新失败!");
|
|
}
|
|
}
|
|
- await updateCaseInfo(caseFile);
|
|
|
|
- inputCaseTitles.value = inputCaseTitles.value.filter(
|
|
|
|
- (item) => item !== caseFile
|
|
|
|
- );
|
|
|
|
};
|
|
};
|
|
|
|
|
|
const currentTypeId = ref<number>();
|
|
const currentTypeId = ref<number>();
|
|
@@ -169,11 +368,96 @@ watchEffect(() => {
|
|
const isDraw = computed(() => currentTypeId.value === FileDrawType);
|
|
const isDraw = computed(() => currentTypeId.value === FileDrawType);
|
|
|
|
|
|
const files = ref<CaseFile[]>([]);
|
|
const files = ref<CaseFile[]>([]);
|
|
-const refresh = async () => {
|
|
|
|
- files.value = await getCaseFiles({
|
|
|
|
- caseId: caseId.value!,
|
|
|
|
- filesTypeId: currentTypeId.value,
|
|
|
|
|
|
+
|
|
|
|
+// 计算预览图片列表
|
|
|
|
+const srcList = computed(() => {
|
|
|
|
+ return files.value.map(file => {
|
|
|
|
+ // 根据文件类型返回对应的图片URL
|
|
|
|
+ return file.type === 'old' ? file.filesUrl : (file.listCover || file.filesUrl);
|
|
});
|
|
});
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+// 预览图片方法
|
|
|
|
+const imageRef = ref()
|
|
|
|
+const showPreview = ref(false)
|
|
|
|
+const currentPreviewIndex = ref(0)
|
|
|
|
+const previewImage = (index: number) => {
|
|
|
|
+ console.log(index)
|
|
|
|
+ const file = files.value[index];
|
|
|
|
+
|
|
|
|
+ // 设置当前预览图片的索引
|
|
|
|
+ currentPreviewIndex.value = index;
|
|
|
|
+
|
|
|
|
+ // 根据文件类型处理查看逻辑
|
|
|
|
+ if (file.type === 'old') {
|
|
|
|
+ // old 类型使用原来的查看逻辑
|
|
|
|
+ const ext = file.filesUrl
|
|
|
|
+ .substring(file.filesUrl.lastIndexOf("."))
|
|
|
|
+ .toLocaleLowerCase();
|
|
|
|
+
|
|
|
|
+ // 如果是图片文件,让 el-image 的预览功能自动处理
|
|
|
|
+ const imageExts = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg'];
|
|
|
|
+ if (imageExts.includes(ext)) {
|
|
|
|
+ showPreview.value = true
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 如果是其他文件类型,使用原来的查看逻辑
|
|
|
|
+ const appId = import.meta.env.VITE_APP_APP || 'fire';
|
|
|
|
+ if ([".raw", ".dcm"].includes(ext)) {
|
|
|
|
+ window.open(
|
|
|
|
+ `/${appId}/xfile-viewer/index.html?file=${file.filesUrl}&name=${file.filesTitle}&time=` +
|
|
|
|
+ Date.now()
|
|
|
|
+ );
|
|
|
|
+ } else {
|
|
|
|
+ window.open(file.filesUrl + "?time=" + Date.now());
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ // tabulation 和 overview 类型的查看逻辑
|
|
|
|
+ if (file.listCover) {
|
|
|
|
+ // 如果有封面图,显示预览
|
|
|
|
+ showPreview.value = true
|
|
|
|
+ } else {
|
|
|
|
+ // 否则直接打开文件
|
|
|
|
+ window.open(file.filesUrl + "?time=" + Date.now());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const refresh = async () => {
|
|
|
|
+ try {
|
|
|
|
+ // 并行调用三个接口
|
|
|
|
+ const [tabulationRes, overviewRes, caseFilesRes] = await Promise.all([
|
|
|
|
+ getCaseTabulationList(caseId.value!),
|
|
|
|
+ getCaseOverviewList(caseId.value!),
|
|
|
|
+ getCaseFiles({
|
|
|
|
+ caseId: caseId.value!,
|
|
|
|
+ filesTypeId: currentTypeId.value,
|
|
|
|
+ })
|
|
|
|
+ ]);
|
|
|
|
+
|
|
|
|
+ // 提取数据并为每种类型添加标记
|
|
|
|
+ const tabulationList = (tabulationRes?.data || []).map(item => ({
|
|
|
|
+ ...item,
|
|
|
|
+ title: item.title || '方位图',
|
|
|
|
+ type: 'tabulation' as const
|
|
|
|
+ }));
|
|
|
|
+ const overviewList = (overviewRes?.data || []).map(item => ({
|
|
|
|
+ ...item,
|
|
|
|
+ title: item.title || '平面图',
|
|
|
|
+ type: 'overview' as const
|
|
|
|
+ }));
|
|
|
|
+ const caseFiles = (caseFilesRes || []).map(item => ({
|
|
|
|
+ ...item,
|
|
|
|
+ type: 'old' as const
|
|
|
|
+ }));
|
|
|
|
+
|
|
|
|
+ files.value = [...tabulationList, ...overviewList, ...caseFiles];
|
|
|
|
+ console.log(files.value)
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('获取文件列表失败:', error);
|
|
|
|
+ files.value = [];
|
|
|
|
+ }
|
|
};
|
|
};
|
|
watchEffect(() => caseId.value && currentTypeId.value && refresh());
|
|
watchEffect(() => caseId.value && currentTypeId.value && refresh());
|
|
|
|
|
|
@@ -193,8 +477,25 @@ const query = (file: CaseFile) => {
|
|
};
|
|
};
|
|
const del = async (file: CaseFile) => {
|
|
const del = async (file: CaseFile) => {
|
|
if (await confirm("确定要删除此数据?")) {
|
|
if (await confirm("确定要删除此数据?")) {
|
|
- await delCaseFile({ caseId: caseId.value!, filesId: file.filesId });
|
|
|
|
- refresh();
|
|
|
|
|
|
+ try {
|
|
|
|
+ // 根据文件类型调用不同的删除接口
|
|
|
|
+ if (file.type === 'old') {
|
|
|
|
+ // old 类型的删除逻辑不变
|
|
|
|
+ await delCaseFile({ caseId: caseId.value!, filesId: file.filesId });
|
|
|
|
+ } else if (file.type === 'tabulation') {
|
|
|
|
+ // tabulation 类型调用 /fusion/caseTabulation/del
|
|
|
|
+ await delCaseTabulation({ id: file.id! });
|
|
|
|
+ } else if (file.type === 'overview') {
|
|
|
|
+ // overview 类型调用 /fusion/caseOverview/del
|
|
|
|
+ await delCaseOverview({ id: file.id! });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ refresh();
|
|
|
|
+ ElMessage.success("删除成功!");
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('删除失败:', error);
|
|
|
|
+ ElMessage.error("删除失败!");
|
|
|
|
+ }
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
@@ -210,6 +511,51 @@ const gotoDraw = (type: BoardType, id: number) => {
|
|
});
|
|
});
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+// 处理不同类型的编辑逻辑
|
|
|
|
+const handleEdit = (file: CaseFile) => {
|
|
|
|
+ if (file.type === 'tabulation') {
|
|
|
|
+ // tabulation 类型的编辑链接
|
|
|
|
+ window.open(`http://test-mix3d.4dkankan.com/draw/index.html#/tabulation?caseId=${caseId.value}&tabulationId=${file.id}&token=${user.value.token}`, '_blank');
|
|
|
|
+ } else if (file.type === 'overview') {
|
|
|
|
+ // overview 类型的编辑链接
|
|
|
|
+ window.open(`http://test-mix3d.4dkankan.com/draw/index.html#/overview?caseId=${caseId.value!}&overviewId=${file.id}&token=${user.value.token}`, '_blank');
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+// 地图弹窗相关
|
|
|
|
+const showMapDialog = ref(false)
|
|
|
|
+
|
|
|
|
+// 打开地图选择弹窗,新版本地图选择
|
|
|
|
+const openMapDialog = () => {
|
|
|
|
+ showMapDialog.value = true
|
|
|
|
+}
|
|
|
|
+// 创建现场图
|
|
|
|
+const openOverView = () => {
|
|
|
|
+ window.open(`http://test-mix3d.4dkankan.com/draw/index.html#/overview?caseId=${caseId.value!}&token=${user.value.token}`, '_blank')
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 处理地图选择确认
|
|
|
|
+const handleMapConfirm = async (location: any) => {
|
|
|
|
+ console.log('选择的地图位置:', location)
|
|
|
|
+ // 这里可以将位置信息保存到案件中,或者创建地图绘图
|
|
|
|
+ try {
|
|
|
|
+ // 可以调用相关API保存位置信息
|
|
|
|
+ // 或者直接跳转到绘图页面
|
|
|
|
+ await router.push({
|
|
|
|
+ name: RouteName.drawCaseFile,
|
|
|
|
+ params: {
|
|
|
|
+ caseId: caseId.value!,
|
|
|
|
+ type: BoardType.map,
|
|
|
|
+ id: -1
|
|
|
|
+ },
|
|
|
|
+ query: {
|
|
|
|
+ location: JSON.stringify(location)
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('处理地图位置失败:', error)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
onMounted(async () => {
|
|
onMounted(async () => {
|
|
try {
|
|
try {
|
|
types.value = await getCaseFileTypes();
|
|
types.value = await getCaseFileTypes();
|
|
@@ -282,9 +628,142 @@ onUnmounted(() => {
|
|
align-items: flex-start;
|
|
align-items: flex-start;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
.edit-title {
|
|
.edit-title {
|
|
cursor: pointer;
|
|
cursor: pointer;
|
|
margin-left: 10px;
|
|
margin-left: 10px;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+// 卡片网格布局样式
|
|
|
|
+.file-grid-container {
|
|
|
|
+ display: grid;
|
|
|
|
+ grid-template-columns: repeat(auto-fill, 387px);
|
|
|
|
+ gap: 16px;
|
|
|
|
+ padding: 16px 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.file-card {
|
|
|
|
+ background: #ffffff;
|
|
|
|
+ // transition: all 0.3s ease;
|
|
|
|
+ width: 387px;
|
|
|
|
+ height: 303px;
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: column;
|
|
|
|
+
|
|
|
|
+ &:hover {
|
|
|
|
+ // box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
|
|
+ // transform: translateY(-2px);
|
|
|
|
+
|
|
|
|
+ .card-overlay {
|
|
|
|
+ opacity: 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.card-image-container {
|
|
|
|
+ position: relative;
|
|
|
|
+ flex: 1;
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ border: 1px solid #e4e7ed;
|
|
|
|
+ border-radius: 8px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.card-image {
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 100%;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.image-error {
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 100%;
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ background: #f5f7fa;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.card-overlay {
|
|
|
|
+ position: absolute;
|
|
|
|
+ top: 0;
|
|
|
|
+ left: 0;
|
|
|
|
+ right: 0;
|
|
|
|
+ bottom: 0;
|
|
|
|
+ background: rgba(0, 0, 0, 0.4);
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ opacity: 0;
|
|
|
|
+ transition: opacity 0.3s ease;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.card-actions {
|
|
|
|
+ display: flex;
|
|
|
|
+ gap: 12px;
|
|
|
|
+ .card-overlay-btn{
|
|
|
|
+ background: transparent;
|
|
|
|
+ border: none;
|
|
|
|
+ color: #F2F2F2;
|
|
|
|
+ padding: 0;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.card-footer {
|
|
|
|
+ padding: 12px 0;
|
|
|
|
+ background: #ffffff;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.file-title {
|
|
|
|
+ .title-text {
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ font-weight: 500;
|
|
|
|
+ color: #303133;
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ align-items: center;
|
|
|
|
+ word-break: break-all;
|
|
|
|
+ line-height: 1.4;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .edit-input {
|
|
|
|
+ :deep(.el-input__wrapper) {
|
|
|
|
+ height: 30px;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ :deep(.el-input-group__append) {
|
|
|
|
+ .el-button {
|
|
|
|
+ height: 30px;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.file-time {
|
|
|
|
+ font-size: 12px;
|
|
|
|
+ color: #909399;
|
|
|
|
+ margin-top: 4px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 响应式设计
|
|
|
|
+@media (max-width: 1200px) {
|
|
|
|
+ .file-grid-container {
|
|
|
|
+ grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+@media (max-width: 768px) {
|
|
|
|
+ .file-grid-container {
|
|
|
|
+ grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
|
|
|
|
+ gap: 12px;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .file-card {
|
|
|
|
+ height: 240px;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .card-footer {
|
|
|
|
+ padding: 8px 0;
|
|
|
|
+ }
|
|
|
|
+}
|
|
</style>
|
|
</style>
|
|
|
|
|