2026-03-27 22:20:25 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<div class="student-homework-page">
|
|
|
|
|
|
<a-card class="mb-4">
|
|
|
|
|
|
<template #title>我的作业</template>
|
|
|
|
|
|
</a-card>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 搜索表单 -->
|
|
|
|
|
|
<a-form
|
|
|
|
|
|
:model="searchParams"
|
|
|
|
|
|
layout="inline"
|
|
|
|
|
|
class="search-form"
|
|
|
|
|
|
@finish="handleSearch"
|
|
|
|
|
|
>
|
|
|
|
|
|
<a-form-item label="作业名称">
|
|
|
|
|
|
<a-input
|
|
|
|
|
|
v-model:value="searchParams.name"
|
|
|
|
|
|
placeholder="请输入作业名称"
|
|
|
|
|
|
allow-clear
|
|
|
|
|
|
style="width: 200px"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
<a-form-item>
|
|
|
|
|
|
<a-button type="primary" html-type="submit">
|
|
|
|
|
|
<template #icon><SearchOutlined /></template>
|
|
|
|
|
|
搜索
|
|
|
|
|
|
</a-button>
|
|
|
|
|
|
<a-button style="margin-left: 8px" @click="handleReset">
|
|
|
|
|
|
<template #icon><ReloadOutlined /></template>
|
|
|
|
|
|
重置
|
|
|
|
|
|
</a-button>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
</a-form>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 数据表格 -->
|
|
|
|
|
|
<a-table
|
|
|
|
|
|
:columns="columns"
|
|
|
|
|
|
:data-source="dataSource"
|
|
|
|
|
|
:loading="loading"
|
|
|
|
|
|
:pagination="pagination"
|
|
|
|
|
|
row-key="id"
|
|
|
|
|
|
@change="handleTableChange"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #bodyCell="{ column, record }">
|
|
|
|
|
|
<template v-if="column.key === 'name'">
|
|
|
|
|
|
{{ record.name }}
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<template v-else-if="column.key === 'status'">
|
|
|
|
|
|
<a-tag :color="record.submission ? 'success' : 'warning'">
|
|
|
|
|
|
{{ record.submission ? "已提交" : "待提交" }}
|
|
|
|
|
|
</a-tag>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<template v-else-if="column.key === 'submitTime'">
|
|
|
|
|
|
<div>
|
|
|
|
|
|
{{ formatDateTime(record.submitStartTime) }} ~
|
|
|
|
|
|
{{ formatDateTime(record.submitEndTime) }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<template v-else-if="column.key === 'action'">
|
|
|
|
|
|
<a-button type="link" size="small" @click="handleViewDetail(record)">
|
|
|
|
|
|
详情
|
|
|
|
|
|
</a-button>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</a-table>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 作业详情侧边弹框 -->
|
|
|
|
|
|
<a-drawer
|
|
|
|
|
|
v-model:open="detailModalVisible"
|
|
|
|
|
|
title="作业详情"
|
|
|
|
|
|
placement="right"
|
|
|
|
|
|
width="500px"
|
|
|
|
|
|
destroy-on-close
|
|
|
|
|
|
:footer-style="{ textAlign: 'right' }"
|
|
|
|
|
|
>
|
|
|
|
|
|
<a-spin :spinning="detailLoading">
|
|
|
|
|
|
<!-- 作业信息 -->
|
|
|
|
|
|
<div class="section-title">作业信息</div>
|
|
|
|
|
|
<a-descriptions :column="1" size="small" bordered class="mb-4">
|
|
|
|
|
|
<a-descriptions-item label="作业名称">
|
|
|
|
|
|
{{ currentHomework?.name }}
|
|
|
|
|
|
</a-descriptions-item>
|
|
|
|
|
|
<a-descriptions-item label="提交时间">
|
|
|
|
|
|
{{ formatDateTime(currentHomework?.submitStartTime) }} ~
|
|
|
|
|
|
{{ formatDateTime(currentHomework?.submitEndTime) }}
|
|
|
|
|
|
</a-descriptions-item>
|
|
|
|
|
|
<a-descriptions-item label="作业描述">
|
|
|
|
|
|
<div class="homework-content" v-html="formatContent(currentHomework?.content)"></div>
|
|
|
|
|
|
</a-descriptions-item>
|
|
|
|
|
|
<a-descriptions-item label="附件下载" v-if="homeworkAttachments.length > 0">
|
|
|
|
|
|
<div class="attachment-list">
|
|
|
|
|
|
<a
|
|
|
|
|
|
v-for="(att, index) in homeworkAttachments"
|
|
|
|
|
|
:key="index"
|
|
|
|
|
|
:href="att.fileUrl"
|
|
|
|
|
|
target="_blank"
|
|
|
|
|
|
class="attachment-item"
|
|
|
|
|
|
>
|
|
|
|
|
|
<DownloadOutlined />
|
|
|
|
|
|
{{ att.fileName }}
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</a-descriptions-item>
|
|
|
|
|
|
</a-descriptions>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 作业提交 -->
|
|
|
|
|
|
<div class="section-title">作业提交</div>
|
|
|
|
|
|
<a-result
|
|
|
|
|
|
v-if="isExpired && !currentSubmission"
|
|
|
|
|
|
status="warning"
|
|
|
|
|
|
title="提交已截止"
|
|
|
|
|
|
sub-title="很抱歉,作业提交时间已过"
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<a-form
|
|
|
|
|
|
v-else
|
|
|
|
|
|
ref="formRef"
|
|
|
|
|
|
:model="submitForm"
|
|
|
|
|
|
:rules="currentSubmission ? {} : formRules"
|
|
|
|
|
|
layout="vertical"
|
|
|
|
|
|
>
|
|
|
|
|
|
<a-form-item label="作品名称" name="workName">
|
|
|
|
|
|
<a-input
|
|
|
|
|
|
v-model:value="submitForm.workName"
|
|
|
|
|
|
placeholder="请输入作品名称"
|
|
|
|
|
|
:disabled="!!currentSubmission"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
<a-form-item label="作品介绍" name="workDescription">
|
|
|
|
|
|
<a-textarea
|
|
|
|
|
|
v-model:value="submitForm.workDescription"
|
|
|
|
|
|
placeholder="请输入作品介绍"
|
|
|
|
|
|
:rows="4"
|
|
|
|
|
|
:disabled="!!currentSubmission"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
<a-form-item label="上传作品" name="files">
|
|
|
|
|
|
<template v-if="currentSubmission">
|
|
|
|
|
|
<!-- 已提交:显示已上传的文件 -->
|
|
|
|
|
|
<div class="file-list" v-if="submissionFiles.length > 0">
|
|
|
|
|
|
<a
|
|
|
|
|
|
v-for="(file, index) in submissionFiles"
|
|
|
|
|
|
:key="index"
|
|
|
|
|
|
:href="file.fileUrl"
|
|
|
|
|
|
target="_blank"
|
|
|
|
|
|
class="file-item"
|
|
|
|
|
|
>
|
|
|
|
|
|
<FileOutlined />
|
|
|
|
|
|
{{ file.fileName }}
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<span v-else class="text-gray">暂无附件</span>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<template v-else>
|
|
|
|
|
|
<!-- 未提交:显示上传组件 -->
|
|
|
|
|
|
<a-upload
|
|
|
|
|
|
v-model:file-list="submitForm.fileList"
|
|
|
|
|
|
:before-upload="beforeUpload"
|
|
|
|
|
|
:custom-request="customUpload"
|
|
|
|
|
|
>
|
|
|
|
|
|
<a-button>
|
|
|
|
|
|
<template #icon><UploadOutlined /></template>
|
|
|
|
|
|
上传附件
|
|
|
|
|
|
</a-button>
|
|
|
|
|
|
</a-upload>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
<!-- 已提交显示得分 -->
|
|
|
|
|
|
<a-form-item v-if="currentSubmission && currentSubmission.totalScore !== null && currentSubmission.totalScore !== undefined" label="得分">
|
|
|
|
|
|
<a-tag color="blue" style="font-size: 16px;">
|
|
|
|
|
|
{{ currentSubmission.totalScore }}分
|
|
|
|
|
|
</a-tag>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
</a-form>
|
|
|
|
|
|
</a-spin>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 底部按钮 -->
|
|
|
|
|
|
<template #footer>
|
|
|
|
|
|
<a-space>
|
|
|
|
|
|
<a-button @click="detailModalVisible = false">取消</a-button>
|
|
|
|
|
|
<a-button
|
|
|
|
|
|
v-if="!currentSubmission && !isExpired"
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
:loading="submitting"
|
|
|
|
|
|
@click="handleSubmit"
|
|
|
|
|
|
>
|
|
|
|
|
|
确定提交
|
|
|
|
|
|
</a-button>
|
|
|
|
|
|
</a-space>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</a-drawer>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
|
import { ref, reactive, computed, onMounted } from "vue"
|
|
|
|
|
|
import { useRoute } from "vue-router"
|
|
|
|
|
|
import { message } from "ant-design-vue"
|
|
|
|
|
|
import type { FormInstance, UploadProps } from "ant-design-vue"
|
|
|
|
|
|
import {
|
|
|
|
|
|
SearchOutlined,
|
|
|
|
|
|
ReloadOutlined,
|
|
|
|
|
|
DownloadOutlined,
|
|
|
|
|
|
FileOutlined,
|
|
|
|
|
|
UploadOutlined,
|
|
|
|
|
|
} from "@ant-design/icons-vue"
|
|
|
|
|
|
import { useListRequest } from "@/composables/useListRequest"
|
|
|
|
|
|
import {
|
|
|
|
|
|
homeworksApi,
|
|
|
|
|
|
submissionsApi,
|
|
|
|
|
|
type Homework,
|
|
|
|
|
|
type QueryHomeworkParams,
|
|
|
|
|
|
type HomeworkSubmission,
|
|
|
|
|
|
type HomeworkAttachment,
|
|
|
|
|
|
} from "@/api/homework"
|
|
|
|
|
|
import { uploadApi } from "@/api/upload"
|
|
|
|
|
|
import dayjs from "dayjs"
|
|
|
|
|
|
|
|
|
|
|
|
const route = useRoute()
|
|
|
|
|
|
|
|
|
|
|
|
// 使用列表请求组合函数 - 只获取已发布的作业
|
|
|
|
|
|
const {
|
|
|
|
|
|
loading,
|
|
|
|
|
|
dataSource,
|
|
|
|
|
|
pagination,
|
|
|
|
|
|
searchParams,
|
|
|
|
|
|
fetchList,
|
|
|
|
|
|
resetSearch,
|
|
|
|
|
|
search,
|
|
|
|
|
|
handleTableChange,
|
|
|
|
|
|
} = useListRequest<Homework, QueryHomeworkParams>({
|
|
|
|
|
|
requestFn: (params) => homeworksApi.getMyList({ ...params, status: 'published' }),
|
|
|
|
|
|
defaultSearchParams: {} as QueryHomeworkParams,
|
|
|
|
|
|
defaultPageSize: 10,
|
|
|
|
|
|
errorMessage: "获取作业列表失败",
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 表格列定义
|
|
|
|
|
|
const columns = [
|
|
|
|
|
|
{
|
|
|
|
|
|
title: "序号",
|
|
|
|
|
|
key: "index",
|
|
|
|
|
|
width: 60,
|
|
|
|
|
|
customRender: ({ index }: { index: number }) => index + 1,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: "作业名称",
|
|
|
|
|
|
key: "name",
|
|
|
|
|
|
dataIndex: "name",
|
|
|
|
|
|
width: 250,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: "状态",
|
|
|
|
|
|
key: "status",
|
|
|
|
|
|
width: 100,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: "提交时间",
|
|
|
|
|
|
key: "submitTime",
|
|
|
|
|
|
width: 350,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: "操作",
|
|
|
|
|
|
key: "action",
|
|
|
|
|
|
width: 100,
|
|
|
|
|
|
fixed: "right" as const,
|
|
|
|
|
|
},
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
// 格式化日期时间
|
|
|
|
|
|
const formatDateTime = (dateStr?: string) => {
|
|
|
|
|
|
if (!dateStr) return "-"
|
|
|
|
|
|
return dayjs(dateStr).format("YYYY-MM-DD HH:mm:ss")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 格式化内容(保留换行)
|
|
|
|
|
|
const formatContent = (content?: string) => {
|
|
|
|
|
|
if (!content) return ""
|
|
|
|
|
|
return content.replace(/\n/g, "<br/>")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 搜索
|
|
|
|
|
|
const handleSearch = () => {
|
|
|
|
|
|
search()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 重置搜索
|
|
|
|
|
|
const handleReset = () => {
|
|
|
|
|
|
resetSearch()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// =============== 详情弹框相关 ===============
|
|
|
|
|
|
const detailModalVisible = ref(false)
|
|
|
|
|
|
const detailLoading = ref(false)
|
|
|
|
|
|
const currentHomework = ref<Homework | null>(null)
|
|
|
|
|
|
const currentSubmission = ref<HomeworkSubmission | null>(null)
|
|
|
|
|
|
const submitting = ref(false)
|
|
|
|
|
|
const formRef = ref<FormInstance>()
|
|
|
|
|
|
|
|
|
|
|
|
// 解析作业附件
|
|
|
|
|
|
const homeworkAttachments = computed<HomeworkAttachment[]>(() => {
|
|
|
|
|
|
if (!currentHomework.value?.attachments) return []
|
|
|
|
|
|
if (typeof currentHomework.value.attachments === "string") {
|
|
|
|
|
|
try {
|
|
|
|
|
|
return JSON.parse(currentHomework.value.attachments)
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
return []
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return currentHomework.value.attachments as HomeworkAttachment[]
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 解析提交的文件
|
|
|
|
|
|
const submissionFiles = computed<HomeworkAttachment[]>(() => {
|
|
|
|
|
|
if (!currentSubmission.value?.files) return []
|
|
|
|
|
|
if (typeof currentSubmission.value.files === "string") {
|
|
|
|
|
|
try {
|
|
|
|
|
|
return JSON.parse(currentSubmission.value.files)
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
return []
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return currentSubmission.value.files as HomeworkAttachment[]
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 是否过期
|
|
|
|
|
|
const isExpired = computed(() => {
|
|
|
|
|
|
if (!currentHomework.value) return false
|
|
|
|
|
|
return dayjs().isAfter(dayjs(currentHomework.value.submitEndTime))
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 提交表单
|
|
|
|
|
|
const submitForm = reactive<{
|
|
|
|
|
|
workName: string
|
|
|
|
|
|
workDescription: string
|
|
|
|
|
|
fileList: any[]
|
|
|
|
|
|
}>({
|
|
|
|
|
|
workName: "",
|
|
|
|
|
|
workDescription: "",
|
|
|
|
|
|
fileList: [],
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const formRules = {
|
|
|
|
|
|
workName: [{ required: true, message: "请输入作品名称" }],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 查看详情
|
|
|
|
|
|
const handleViewDetail = async (record: Homework) => {
|
|
|
|
|
|
// 重置状态
|
|
|
|
|
|
currentHomework.value = null
|
|
|
|
|
|
currentSubmission.value = null
|
|
|
|
|
|
detailLoading.value = true
|
|
|
|
|
|
detailModalVisible.value = true
|
|
|
|
|
|
|
|
|
|
|
|
// 重置表单
|
|
|
|
|
|
submitForm.workName = ""
|
|
|
|
|
|
submitForm.workDescription = ""
|
|
|
|
|
|
submitForm.fileList = []
|
|
|
|
|
|
|
|
|
|
|
|
// 加载作业详情
|
|
|
|
|
|
try {
|
|
|
|
|
|
const detail = await homeworksApi.getDetail(record.id)
|
|
|
|
|
|
currentHomework.value = detail
|
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
|
message.error(error?.response?.data?.message || "获取作业详情失败")
|
|
|
|
|
|
detailLoading.value = false
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取我的提交记录(404 是正常情况,不提示错误)
|
|
|
|
|
|
try {
|
|
|
|
|
|
const mySubmission = await submissionsApi.getMySubmission(record.id)
|
|
|
|
|
|
currentSubmission.value = mySubmission
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
// 未找到提交记录是正常情况,不提示错误
|
|
|
|
|
|
currentSubmission.value = null
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
detailLoading.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 文件上传
|
|
|
|
|
|
const beforeUpload: UploadProps["beforeUpload"] = () => {
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const customUpload = async ({ file, onSuccess, onError }: any) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const formData = new FormData()
|
|
|
|
|
|
formData.append("file", file)
|
2026-04-08 15:19:43 +08:00
|
|
|
|
const result = await uploadApi.upload(formData, "homework/attachment")
|
2026-03-27 22:20:25 +08:00
|
|
|
|
file.url = result.url
|
|
|
|
|
|
onSuccess(result)
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
onError(error)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 提交作业
|
|
|
|
|
|
const handleSubmit = async () => {
|
|
|
|
|
|
if (!currentHomework.value) return
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
await formRef.value?.validate()
|
|
|
|
|
|
submitting.value = true
|
|
|
|
|
|
|
|
|
|
|
|
const files = submitForm.fileList.map((file) => ({
|
|
|
|
|
|
fileName: file.name,
|
|
|
|
|
|
fileUrl: file.url || file.response?.url,
|
|
|
|
|
|
size: file.size?.toString(),
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
|
|
await submissionsApi.submit({
|
|
|
|
|
|
homeworkId: currentHomework.value.id,
|
|
|
|
|
|
workName: submitForm.workName,
|
|
|
|
|
|
workDescription: submitForm.workDescription,
|
|
|
|
|
|
files,
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
message.success("提交成功")
|
|
|
|
|
|
detailModalVisible.value = false
|
|
|
|
|
|
// 刷新列表
|
|
|
|
|
|
fetchList()
|
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
|
if (error?.errorFields) return
|
|
|
|
|
|
message.error(error?.response?.data?.message || "提交失败")
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
submitting.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
fetchList()
|
|
|
|
|
|
})
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.search-form {
|
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.mb-4 {
|
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.section-title {
|
|
|
|
|
|
font-size: 15px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
margin-bottom: 12px;
|
|
|
|
|
|
padding-left: 8px;
|
|
|
|
|
|
border-left: 3px solid #1890ff;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.homework-content {
|
|
|
|
|
|
white-space: pre-wrap;
|
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
|
color: #666;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.attachment-list {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.attachment-item {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 6px;
|
|
|
|
|
|
color: #1890ff;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.attachment-item:hover {
|
|
|
|
|
|
text-decoration: underline;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.file-list {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.file-item {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 6px;
|
|
|
|
|
|
color: #1890ff;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.file-item:hover {
|
|
|
|
|
|
text-decoration: underline;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|