|
|
|
@ -84,20 +84,16 @@
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</el-card>
|
|
|
|
</el-card>
|
|
|
|
|
|
|
|
|
|
|
|
<el-dialog
|
|
|
|
<FilePreviewDialog
|
|
|
|
v-model="previewVisible"
|
|
|
|
:visible="previewVisible"
|
|
|
|
:title="$t('btn.preview')"
|
|
|
|
:blob-url="previewUrl"
|
|
|
|
width="80%"
|
|
|
|
:blob="previewBlob"
|
|
|
|
top="5vh"
|
|
|
|
:file-name="previewName"
|
|
|
|
destroy-on-close
|
|
|
|
:file-type="previewType"
|
|
|
|
:before-close="closePreview"
|
|
|
|
@update:visible="(v) => (previewVisible = v)"
|
|
|
|
>
|
|
|
|
@close="cleanupPreview"
|
|
|
|
<iframe
|
|
|
|
@download="onPreviewDownload"
|
|
|
|
v-if="previewUrl"
|
|
|
|
/>
|
|
|
|
:src="previewUrl"
|
|
|
|
|
|
|
|
class="preview-iframe"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
@ -108,6 +104,7 @@ import { ElMessage } from "element-plus";
|
|
|
|
import dayjs from "dayjs";
|
|
|
|
import dayjs from "dayjs";
|
|
|
|
import { useI18n } from "vue-i18n";
|
|
|
|
import { useI18n } from "vue-i18n";
|
|
|
|
import { getAdminHospitals, getUploadFile } from "@/service/modular/admin";
|
|
|
|
import { getAdminHospitals, getUploadFile } from "@/service/modular/admin";
|
|
|
|
|
|
|
|
import FilePreviewDialog from "@/components/FilePreviewDialog.vue";
|
|
|
|
|
|
|
|
|
|
|
|
const { t: $t } = useI18n();
|
|
|
|
const { t: $t } = useI18n();
|
|
|
|
const router = useRouter();
|
|
|
|
const router = useRouter();
|
|
|
|
@ -171,27 +168,77 @@ const goAdd = () => router.push("/admin/hospitals/edit");
|
|
|
|
|
|
|
|
|
|
|
|
const previewVisible = ref(false);
|
|
|
|
const previewVisible = ref(false);
|
|
|
|
const previewUrl = ref("");
|
|
|
|
const previewUrl = ref("");
|
|
|
|
|
|
|
|
const previewBlob = ref(null);
|
|
|
|
|
|
|
|
const previewName = ref("");
|
|
|
|
|
|
|
|
const previewType = ref(""); // 'pdf' | 'image' | ''
|
|
|
|
|
|
|
|
|
|
|
|
const cleanupPreviewUrl = () => {
|
|
|
|
const cleanupPreview = () => {
|
|
|
|
if (previewUrl.value) {
|
|
|
|
if (previewUrl.value) {
|
|
|
|
URL.revokeObjectURL(previewUrl.value);
|
|
|
|
URL.revokeObjectURL(previewUrl.value);
|
|
|
|
previewUrl.value = "";
|
|
|
|
previewUrl.value = "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
previewBlob.value = null;
|
|
|
|
|
|
|
|
previewName.value = "";
|
|
|
|
|
|
|
|
previewType.value = "";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const closePreview = () => {
|
|
|
|
// 从路径中提取最后的文件名(含扩展名)作为下载名
|
|
|
|
previewVisible.value = false;
|
|
|
|
const getFileNameFromPath = (path) => {
|
|
|
|
cleanupPreviewUrl();
|
|
|
|
if (!path) return "";
|
|
|
|
|
|
|
|
return String(path).replace(/\\/g, "/").split("/").filter(Boolean).pop() || "";
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 根据文件名/扩展名+blob 的 mime 判断文件类型
|
|
|
|
|
|
|
|
const getFileType = (fileName, blob) => {
|
|
|
|
|
|
|
|
const name = String(fileName || "");
|
|
|
|
|
|
|
|
const ext = name.split(".").pop()?.toLowerCase() || "";
|
|
|
|
|
|
|
|
const mime = blob?.type || "";
|
|
|
|
|
|
|
|
if (ext === "pdf" || mime === "application/pdf") return "pdf";
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
|
|
|
["jpg", "jpeg", "png", "gif", "bmp", "webp", "svg"].includes(ext) ||
|
|
|
|
|
|
|
|
(mime && mime.startsWith("image/"))
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
return "image";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return "other";
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 浏览器直接下载 blob(指定文件名)
|
|
|
|
|
|
|
|
const downloadBlob = (blob, fileName) => {
|
|
|
|
|
|
|
|
const url = URL.createObjectURL(blob);
|
|
|
|
|
|
|
|
const a = document.createElement("a");
|
|
|
|
|
|
|
|
a.href = url;
|
|
|
|
|
|
|
|
a.download = fileName || "download";
|
|
|
|
|
|
|
|
document.body.appendChild(a);
|
|
|
|
|
|
|
|
a.click();
|
|
|
|
|
|
|
|
document.body.removeChild(a);
|
|
|
|
|
|
|
|
setTimeout(() => URL.revokeObjectURL(url), 0);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// FilePreviewDialog 下载按钮回调
|
|
|
|
|
|
|
|
const onPreviewDownload = ({ blob, fileName }) => {
|
|
|
|
|
|
|
|
if (!blob) return;
|
|
|
|
|
|
|
|
downloadBlob(blob, fileName);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const viewReport = async (attachmentPath) => {
|
|
|
|
const viewReport = async (attachmentPath) => {
|
|
|
|
if (!attachmentPath) return;
|
|
|
|
if (!attachmentPath) return;
|
|
|
|
const fileName = String(attachmentPath);
|
|
|
|
const path = String(attachmentPath);
|
|
|
|
|
|
|
|
const downloadName = getFileNameFromPath(path) || path;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const blob = await getUploadFile(fileName);
|
|
|
|
const blob = await getUploadFile(path);
|
|
|
|
cleanupPreviewUrl();
|
|
|
|
const type = getFileType(downloadName, blob);
|
|
|
|
previewUrl.value = URL.createObjectURL(blob);
|
|
|
|
// PDF / 图片走预览弹窗(PDF 走 vue-pdf-embed),其他格式直接下载
|
|
|
|
previewVisible.value = true;
|
|
|
|
if (type === "pdf" || type === "image") {
|
|
|
|
|
|
|
|
cleanupPreview();
|
|
|
|
|
|
|
|
previewBlob.value = blob;
|
|
|
|
|
|
|
|
previewUrl.value = URL.createObjectURL(blob);
|
|
|
|
|
|
|
|
previewName.value = downloadName;
|
|
|
|
|
|
|
|
previewType.value = type;
|
|
|
|
|
|
|
|
previewVisible.value = true;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
downloadBlob(blob, downloadName);
|
|
|
|
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
} catch (e) {
|
|
|
|
ElMessage.error(e?.message || $t('msg.failed'));
|
|
|
|
ElMessage.error(e?.message || $t('msg.failed'));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|