2025-08-05 18:00:45 +08:00
|
|
|
<template>
|
|
|
|
|
<a-modal
|
|
|
|
|
v-model:open="visible"
|
|
|
|
|
:title="file?.filename || '文件详情'"
|
|
|
|
|
width="1200px"
|
|
|
|
|
:footer="null"
|
2025-09-19 11:52:50 +08:00
|
|
|
wrap-class-name="file-detail"
|
2025-08-05 18:00:45 +08:00
|
|
|
@after-open-change="afterOpenChange"
|
2025-09-19 11:52:50 +08:00
|
|
|
:bodyStyle="{ height: '80vh', padding: '0' }"
|
2025-08-05 18:00:45 +08:00
|
|
|
>
|
|
|
|
|
<div class="file-detail-content" v-if="file">
|
|
|
|
|
<div class="file-content-section" v-if="file.lines && file.lines.length > 0">
|
2025-09-19 11:52:50 +08:00
|
|
|
<MarkdownContentViewer :chunks="file.lines" />
|
2025-08-05 18:00:45 +08:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div v-else-if="loading" class="loading-container">
|
|
|
|
|
<a-spin />
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div v-else class="empty-content">
|
|
|
|
|
<p>暂无文件内容</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</a-modal>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
import { computed } from 'vue';
|
|
|
|
|
import { useDatabaseStore } from '@/stores/database';
|
|
|
|
|
|
|
|
|
|
const store = useDatabaseStore();
|
|
|
|
|
|
|
|
|
|
const visible = computed({
|
|
|
|
|
get: () => store.state.fileDetailModalVisible,
|
|
|
|
|
set: (value) => store.state.fileDetailModalVisible = value
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const file = computed(() => store.selectedFile);
|
|
|
|
|
const loading = computed(() => store.state.fileDetailLoading);
|
|
|
|
|
|
|
|
|
|
const afterOpenChange = (open) => {
|
|
|
|
|
if (!open) {
|
|
|
|
|
store.selectedFile = null;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 导入工具函数
|
|
|
|
|
import { getStatusText, formatStandardTime } from '@/utils/file_utils';
|
2025-09-19 11:52:50 +08:00
|
|
|
import MarkdownContentViewer from './MarkdownContentViewer.vue';
|
2025-08-05 18:00:45 +08:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
.file-detail-content {
|
|
|
|
|
height: 100%;
|
2025-09-19 11:52:50 +08:00
|
|
|
overflow-y: auto;
|
2025-08-05 18:00:45 +08:00
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.file-content-section h4 {
|
|
|
|
|
margin-bottom: 12px;
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.loading-container {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
|
|
|
|
height: 200px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.empty-content {
|
|
|
|
|
text-align: center;
|
|
|
|
|
padding: 40px 0;
|
|
|
|
|
color: #999;
|
|
|
|
|
}
|
2025-09-19 11:52:50 +08:00
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
<style lang="less">
|
|
|
|
|
.file-detail {
|
|
|
|
|
.ant-modal {
|
|
|
|
|
top: 20px;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-08-05 18:00:45 +08:00
|
|
|
</style>
|