- Expanded CourseResourceType to include "resource" and "temp". - Renamed ICourseResource to IResource and updated its properties for consistency. - Introduced ICreateResource type for resource creation. - Modified ICourseSection and ICourseChapter interfaces to use the new IResource type and updated property names for camelCase. - Implemented uploadFile function in file API for handling file uploads. - Created ResourceUploader component for uploading resources with validation and feedback. - Developed Card component for displaying course class details and managing student enrollment. - Added AlertDialog components for consistent alert dialog UI. - Enhanced table components for better data presentation and management. - Implemented preview page for displaying various resource types based on file extension.
145 lines
3.6 KiB
Vue
145 lines
3.6 KiB
Vue
<script lang="ts" setup>
|
|
import { toast } from "vue-sonner";
|
|
import { editResource } from "~/api/course";
|
|
import type { IResource } from "~/types";
|
|
|
|
const props = defineProps<{
|
|
resource: IResource;
|
|
}>();
|
|
|
|
const emit = defineEmits<{
|
|
refresh: [];
|
|
"delete-resource": [resourceId: number];
|
|
}>();
|
|
|
|
const resourceIcon = computed(() => {
|
|
switch (props.resource.resourceName?.split(".").pop()) {
|
|
case "mp4":
|
|
case "avi":
|
|
case "mov":
|
|
return "tabler:video";
|
|
case "jpg":
|
|
case "jpeg":
|
|
case "png":
|
|
case "gif":
|
|
case "webp":
|
|
return "tabler:photo";
|
|
case "ppt":
|
|
case "pptx":
|
|
return "tabler:file-type-ppt";
|
|
case "doc":
|
|
case "docx":
|
|
case "txt":
|
|
case "pdf":
|
|
case "xls":
|
|
case "xlsx":
|
|
case "csv":
|
|
return "tabler:file-type-doc";
|
|
|
|
default:
|
|
return "tabler:file";
|
|
}
|
|
});
|
|
|
|
const onAllowDownloadSwitch = () => {
|
|
toast.promise(
|
|
editResource({
|
|
...props.resource,
|
|
allowDownload: !props.resource.allowDownload,
|
|
}),
|
|
{
|
|
loading: "正在修改资源下载权限...",
|
|
success: () => {
|
|
return `已${props.resource.allowDownload ? "禁止" : "允许"}下载资源`;
|
|
},
|
|
error: () => {
|
|
return "修改资源下载权限失败";
|
|
},
|
|
finally: () => {
|
|
emit("refresh");
|
|
},
|
|
}
|
|
);
|
|
};
|
|
|
|
const onDeleteResource = () => {
|
|
const confirmDelete = confirm(
|
|
"将从课程中移除该资源,文件仍可在资源库中找到,是否继续?"
|
|
);
|
|
if (!confirmDelete) return;
|
|
emit("delete-resource", props.resource.id);
|
|
};
|
|
|
|
const onPreviewResource = (url: string) => {
|
|
window.open(`/preview/${btoa(url)}`, "xmts_resource_preview");
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
class="px-4 pl-8 py-1 flex justify-between group/resource hover:bg-muted/50"
|
|
>
|
|
<div class="flex items-center gap-2 relative text-muted-foreground">
|
|
<div
|
|
class="absolute inset-y-0 top-3 left-1.5 w-4 h-[1px] bg-gray-300 dark:bg-gray-700 z-0"
|
|
/>
|
|
<div class="w-[7px] h-[7px] rounded-full bg-foreground/50 z-10" />
|
|
<Icon :name="resourceIcon" class="ml-6" size="20px" />
|
|
<span class="text-ellipsis line-clamp-1 text-xs font-medium">
|
|
{{ resource.resourceName }}
|
|
</span>
|
|
</div>
|
|
<div
|
|
class="flex items-center gap-2 mr-8 opacity-0 group-hover/resource:opacity-100"
|
|
>
|
|
<Button
|
|
variant="link"
|
|
size="xs"
|
|
class="flex items-center gap-1 text-muted-foreground"
|
|
@click="onPreviewResource(resource.resourceUrl)"
|
|
>
|
|
<Icon name="tabler:eye" size="16px" />
|
|
<span>预览</span>
|
|
</Button>
|
|
<Button
|
|
variant="link"
|
|
size="xs"
|
|
class="flex items-center gap-1 text-muted-foreground"
|
|
:class="{
|
|
'text-amber-500': resource.allowDownload,
|
|
}"
|
|
@click="onAllowDownloadSwitch"
|
|
>
|
|
<Icon
|
|
:name="
|
|
resource.allowDownload ? 'tabler:download-off' : 'tabler:download'
|
|
"
|
|
size="16px"
|
|
/>
|
|
<span>
|
|
{{ resource.allowDownload ? "关闭下载" : "开启下载" }}
|
|
</span>
|
|
</Button>
|
|
<!-- <Tooltip :delay-duration="0">
|
|
<TooltipTrigger>
|
|
|
|
</TooltipTrigger>
|
|
<TooltipContent>
|
|
{{ `当前${resource.allow_download ? "允许" : "禁止"}下载` }}
|
|
</TooltipContent>
|
|
</Tooltip> -->
|
|
<Button
|
|
variant="link"
|
|
size="xs"
|
|
class="flex items-center gap-1 text-red-500"
|
|
@click="onDeleteResource"
|
|
>
|
|
<Icon name="tabler:trash" size="16px" />
|
|
<span>删除</span>
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped></style>
|