feat: 统一资源管理
This commit is contained in:
@@ -88,17 +88,17 @@ export async function loadDiagramData(examId?: string): Promise<DiagramData> {
|
||||
// 如果提供了examId,优先从API加载实验的diagram
|
||||
if (examId) {
|
||||
try {
|
||||
const examClient = AuthManager.createAuthenticatedExamClient();
|
||||
const resourceClient = AuthManager.createAuthenticatedResourceClient();
|
||||
|
||||
// 获取diagram类型的资源列表
|
||||
const resources = await examClient.getExamResourceList(examId, 'canvas');
|
||||
const resources = await resourceClient.getResourceList(examId, 'canvas', 'template');
|
||||
|
||||
if (resources && resources.length > 0) {
|
||||
// 获取第一个diagram资源
|
||||
const diagramResource = resources[0];
|
||||
|
||||
// 使用动态API获取资源文件内容
|
||||
const response = await examClient.getExamResourceById(diagramResource.id);
|
||||
const response = await resourceClient.getResourceById(diagramResource.id);
|
||||
|
||||
if (response && response.data) {
|
||||
const text = await response.data.text();
|
||||
|
||||
@@ -6,8 +6,6 @@ import hljs from 'highlight.js';
|
||||
import 'highlight.js/styles/github.css'; // 亮色主题
|
||||
// 导入主题存储
|
||||
import { useThemeStore } from '@/stores/theme';
|
||||
// 导入ExamClient用于获取图片资源
|
||||
import { ExamClient } from '@/APIClient';
|
||||
import { AuthManager } from '@/utils/AuthManager';
|
||||
|
||||
const props = defineProps({
|
||||
@@ -36,8 +34,8 @@ const imageResourceCache = ref<Map<string, string>>(new Map());
|
||||
// 获取图片资源ID的函数
|
||||
async function getImageResourceId(examId: string, imagePath: string): Promise<string | null> {
|
||||
try {
|
||||
const client = AuthManager.createAuthenticatedExamClient();
|
||||
const resources = await client.getExamResourceList(examId, 'images');
|
||||
const client = AuthManager.createAuthenticatedResourceClient();
|
||||
const resources = await client.getResourceList(examId, 'images', 'template');
|
||||
|
||||
// 查找匹配的图片资源
|
||||
const imageResource = resources.find(r => r.name === imagePath || r.name.endsWith(imagePath));
|
||||
@@ -52,8 +50,8 @@ async function getImageResourceId(examId: string, imagePath: string): Promise<st
|
||||
// 通过资源ID获取图片数据URL
|
||||
async function getImageDataUrl(resourceId: string): Promise<string | null> {
|
||||
try {
|
||||
const client = AuthManager.createAuthenticatedExamClient();
|
||||
const response = await client.getExamResourceById(parseInt(resourceId));
|
||||
const client = AuthManager.createAuthenticatedResourceClient();
|
||||
const response = await client.getResourceById(parseInt(resourceId));
|
||||
|
||||
if (response && response.data) {
|
||||
return URL.createObjectURL(response.data);
|
||||
|
||||
@@ -127,12 +127,13 @@ onMounted(async () => {
|
||||
let thumbnail: string | undefined;
|
||||
|
||||
try {
|
||||
// 获取实验的封面资源
|
||||
const resourceList = await client.getExamResourceList(exam.id, 'cover');
|
||||
// 获取实验的封面资源(模板资源)
|
||||
const resourceClient = AuthManager.createAuthenticatedResourceClient();
|
||||
const resourceList = await resourceClient.getResourceList(exam.id, 'cover', 'template');
|
||||
if (resourceList && resourceList.length > 0) {
|
||||
// 使用第一个封面资源
|
||||
const coverResource = resourceList[0];
|
||||
const fileResponse = await client.getExamResourceById(coverResource.id);
|
||||
const fileResponse = await resourceClient.getResourceById(coverResource.id);
|
||||
// 创建Blob URL作为缩略图
|
||||
thumbnail = URL.createObjectURL(fileResponse.data);
|
||||
}
|
||||
|
||||
@@ -75,8 +75,8 @@ import { useDialogStore } from "@/stores/dialog";
|
||||
import { isNull, isUndefined } from "lodash";
|
||||
|
||||
interface Props {
|
||||
uploadEvent?: (file: File) => Promise<boolean>;
|
||||
downloadEvent?: () => Promise<boolean>;
|
||||
uploadEvent?: (file: File, examId: string) => Promise<number | null>;
|
||||
downloadEvent?: (bitstreamId: number) => Promise<boolean>;
|
||||
maxMemory?: number;
|
||||
examId?: string; // 新增examId属性
|
||||
}
|
||||
@@ -127,9 +127,9 @@ async function loadAvailableBitstreams() {
|
||||
}
|
||||
|
||||
try {
|
||||
const examClient = AuthManager.createAuthenticatedExamClient();
|
||||
// 使用新的API获取比特流资源列表
|
||||
const resources = await examClient.getExamResourceList(props.examId, 'bitstream');
|
||||
const resourceClient = AuthManager.createAuthenticatedResourceClient();
|
||||
// 使用新的ResourceClient API获取比特流模板资源列表
|
||||
const resources = await resourceClient.getResourceList(props.examId, 'bitstream', 'template');
|
||||
availableBitstreams.value = resources.map(r => ({ id: r.id, name: r.name })) || [];
|
||||
} catch (error) {
|
||||
console.error('加载比特流列表失败:', error);
|
||||
@@ -143,10 +143,10 @@ async function downloadExampleBitstream(bitstream: {id: number, name: string}) {
|
||||
|
||||
isDownloading.value = true;
|
||||
try {
|
||||
const examClient = AuthManager.createAuthenticatedExamClient();
|
||||
const resourceClient = AuthManager.createAuthenticatedResourceClient();
|
||||
|
||||
// 使用动态API获取资源文件
|
||||
const response = await examClient.getExamResourceById(bitstream.id);
|
||||
// 使用新的ResourceClient API获取资源文件
|
||||
const response = await resourceClient.getResourceById(bitstream.id);
|
||||
|
||||
if (response && response.data) {
|
||||
// 创建下载链接
|
||||
@@ -173,37 +173,21 @@ async function downloadExampleBitstream(bitstream: {id: number, name: string}) {
|
||||
|
||||
// 直接烧录示例比特流
|
||||
async function programExampleBitstream(bitstream: {id: number, name: string}) {
|
||||
if (isProgramming.value || !props.uploadEvent) return;
|
||||
if (isProgramming.value) return;
|
||||
|
||||
isProgramming.value = true;
|
||||
try {
|
||||
const examClient = AuthManager.createAuthenticatedExamClient();
|
||||
|
||||
// 使用动态API获取比特流文件数据
|
||||
const response = await examClient.getExamResourceById(bitstream.id);
|
||||
|
||||
if (!response || !response.data) {
|
||||
throw new Error('获取比特流文件失败');
|
||||
}
|
||||
|
||||
const file = new File([response.data], response.fileName || bitstream.name, { type: response.data.type });
|
||||
|
||||
// 调用上传事件
|
||||
const uploadSuccess = await props.uploadEvent(file);
|
||||
if (uploadSuccess) {
|
||||
// 如果有下载事件(烧录),则执行
|
||||
if (props.downloadEvent) {
|
||||
const downloadSuccess = await props.downloadEvent();
|
||||
if (downloadSuccess) {
|
||||
dialog.info("示例比特流烧录成功");
|
||||
} else {
|
||||
dialog.error("烧录失败");
|
||||
}
|
||||
const resourceClient = AuthManager.createAuthenticatedResourceClient();
|
||||
|
||||
if (props.downloadEvent) {
|
||||
const downloadSuccess = await props.downloadEvent(bitstream.id);
|
||||
if (downloadSuccess) {
|
||||
dialog.info("示例比特流烧录成功");
|
||||
} else {
|
||||
dialog.info("示例比特流上传成功");
|
||||
dialog.error("烧录失败");
|
||||
}
|
||||
} else {
|
||||
dialog.error("上传失败");
|
||||
dialog.info("示例比特流props.downloadEvent未定义 无法烧录");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('烧录示例比特流失败:', error);
|
||||
@@ -234,6 +218,7 @@ function checkFile(file: File): boolean {
|
||||
}
|
||||
|
||||
async function handleClick(event: Event): Promise<void> {
|
||||
console.log("上传按钮被点击");
|
||||
if (isNull(bitstream.value) || isUndefined(bitstream.value)) {
|
||||
dialog.error(`未选择文件`);
|
||||
return;
|
||||
@@ -246,19 +231,21 @@ async function handleClick(event: Event): Promise<void> {
|
||||
}
|
||||
|
||||
isUploading.value = true;
|
||||
let uploadedBitstreamId: number | null = null;
|
||||
try {
|
||||
const ret = await props.uploadEvent(bitstream.value);
|
||||
console.log("开始上传比特流文件:", bitstream.value.name);
|
||||
const bitstreamId = await props.uploadEvent(bitstream.value, props.examId || '');
|
||||
console.log("上传结果,ID:", bitstreamId);
|
||||
if (isUndefined(props.downloadEvent)) {
|
||||
if (ret) {
|
||||
dialog.info("上传成功");
|
||||
emits("finishedUpload", bitstream.value);
|
||||
} else dialog.error("上传失败");
|
||||
return;
|
||||
}
|
||||
if (!ret) {
|
||||
console.log("上传成功,下载未定义");
|
||||
isUploading.value = false;
|
||||
return;
|
||||
}
|
||||
if (bitstreamId === null || bitstreamId === undefined) {
|
||||
isUploading.value = false;
|
||||
return;
|
||||
}
|
||||
uploadedBitstreamId = bitstreamId;
|
||||
} catch (e) {
|
||||
dialog.error("上传失败");
|
||||
console.error(e);
|
||||
@@ -267,9 +254,14 @@ async function handleClick(event: Event): Promise<void> {
|
||||
|
||||
// Download
|
||||
try {
|
||||
const ret = await props.downloadEvent();
|
||||
if (ret) dialog.info("下载成功");
|
||||
else dialog.error("下载失败");
|
||||
console.log("开始下载比特流,ID:", uploadedBitstreamId);
|
||||
if (uploadedBitstreamId === null || uploadedBitstreamId === undefined) {
|
||||
dialog.error("uploadedBitstreamId is null or undefined");
|
||||
} else {
|
||||
const ret = await props.downloadEvent(uploadedBitstreamId);
|
||||
if (ret) dialog.info("下载成功");
|
||||
else dialog.error("下载失败");
|
||||
}
|
||||
} catch (e) {
|
||||
dialog.error("下载失败");
|
||||
console.error(e);
|
||||
|
||||
@@ -22,8 +22,9 @@
|
||||
</div>
|
||||
<div class="divider"></div>
|
||||
<UploadCard
|
||||
:exam-id="props.examId"
|
||||
:upload-event="eqps.jtagUploadBitstream"
|
||||
:download-event="eqps.jtagDownloadBitstream"
|
||||
:download-event="handleDownloadBitstream"
|
||||
:bitstream-file="eqps.jtagBitstream"
|
||||
@update:bitstream-file="handleBitstreamChange"
|
||||
>
|
||||
@@ -127,6 +128,11 @@ function handleBitstreamChange(file: File | undefined) {
|
||||
eqps.jtagBitstream = file;
|
||||
}
|
||||
|
||||
async function handleDownloadBitstream(bitstreamId: number): Promise<boolean> {
|
||||
console.log("开始下载比特流,ID:", bitstreamId);
|
||||
return await eqps.jtagDownloadBitstream(bitstreamId);
|
||||
}
|
||||
|
||||
function handleSelectJtagSpeed(event: Event) {
|
||||
const target = event.target as HTMLSelectElement;
|
||||
eqps.jtagSetSpeed(target.selectedIndex);
|
||||
|
||||
Reference in New Issue
Block a user