mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2026-06-15 09:57:27 +00:00
fix(frontend): improve directory and timestamp display
This commit is contained in:
@@ -511,6 +511,7 @@
|
|||||||
|
|
||||||
files.forEach(file => {
|
files.forEach(file => {
|
||||||
const item = document.createElement('div');
|
const item = document.createElement('div');
|
||||||
|
const metaText = fileMetaText(file);
|
||||||
|
|
||||||
if (file.fileType === 'folder') {
|
if (file.fileType === 'folder') {
|
||||||
// 文件夹
|
// 文件夹
|
||||||
@@ -520,9 +521,7 @@
|
|||||||
<i class="fas fa-folder"></i>
|
<i class="fas fa-folder"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="item-name">${file.fileName || '未命名文件夹'}</div>
|
<div class="item-name">${file.fileName || '未命名文件夹'}</div>
|
||||||
<div class="item-meta">
|
${metaText ? `<div class="item-meta">${metaText}</div>` : ''}
|
||||||
${file.sizeStr || '0B'} · ${formatDate(file.createTime)}
|
|
||||||
</div>
|
|
||||||
`;
|
`;
|
||||||
folderCount++;
|
folderCount++;
|
||||||
|
|
||||||
@@ -541,9 +540,7 @@
|
|||||||
<i class="fas ${fileTypeInfo.icon}"></i>
|
<i class="fas ${fileTypeInfo.icon}"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="item-name">${file.fileName}</div>
|
<div class="item-name">${file.fileName}</div>
|
||||||
<div class="item-meta">
|
${metaText ? `<div class="item-meta">${metaText}</div>` : ''}
|
||||||
${file.sizeStr || '0B'} · ${formatDate(file.createTime)}
|
|
||||||
</div>
|
|
||||||
`;
|
`;
|
||||||
fileCount++;
|
fileCount++;
|
||||||
|
|
||||||
@@ -675,19 +672,65 @@
|
|||||||
renderBreadcrumb();
|
renderBreadcrumb();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 文件元信息
|
||||||
|
function fileMetaText(file) {
|
||||||
|
const parts = [];
|
||||||
|
if (file.fileType !== 'folder') {
|
||||||
|
parts.push(file.sizeStr || '0B');
|
||||||
|
}
|
||||||
|
const dateText = formatDate(file.createTime);
|
||||||
|
if (dateText) {
|
||||||
|
parts.push(dateText);
|
||||||
|
}
|
||||||
|
return parts.join(' · ');
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasValidTime(value) {
|
||||||
|
if (value === null || value === undefined) return false;
|
||||||
|
if (typeof value !== 'string') return true;
|
||||||
|
const trimmedValue = value.trim();
|
||||||
|
return trimmedValue !== '' && trimmedValue !== 'null' && trimmedValue !== 'undefined';
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDateOnly(yearValue, monthValue, dayValue) {
|
||||||
|
const year = Number(yearValue);
|
||||||
|
const month = Number(monthValue);
|
||||||
|
const day = Number(dayValue);
|
||||||
|
const date = new Date(year, month - 1, day);
|
||||||
|
if (
|
||||||
|
date.getFullYear() !== year ||
|
||||||
|
date.getMonth() !== month - 1 ||
|
||||||
|
date.getDate() !== day
|
||||||
|
) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return `${yearValue}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
|
||||||
|
}
|
||||||
|
|
||||||
// 格式化日期
|
// 格式化日期
|
||||||
function formatDate(dateString) {
|
function formatDate(dateString) {
|
||||||
if (!dateString) return '未知日期';
|
if (!hasValidTime(dateString)) return '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const date = new Date(dateString);
|
const value = typeof dateString === 'string' ? dateString.trim() : dateString;
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
const dateOnly = value.match(/^(\d{4})[-/](\d{1,2})[-/](\d{1,2})$/);
|
||||||
|
if (dateOnly) {
|
||||||
|
return formatDateOnly(dateOnly[1], dateOnly[2], dateOnly[3]);
|
||||||
|
}
|
||||||
|
const cnDateOnly = value.match(/^(\d{4})年\s*(\d{1,2})月\s*(\d{1,2})日$/);
|
||||||
|
if (cnDateOnly) {
|
||||||
|
return formatDateOnly(cnDateOnly[1], cnDateOnly[2], cnDateOnly[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const date = new Date(value);
|
||||||
return isNaN(date.getTime())
|
return isNaN(date.getTime())
|
||||||
? '未知日期'
|
? ''
|
||||||
: `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`;
|
: `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`;
|
||||||
} catch {
|
} catch {
|
||||||
return '未知日期';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -32,8 +32,8 @@
|
|||||||
<i :class="getFileIcon(file)"></i>
|
<i :class="getFileIcon(file)"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="file-name">{{ file.fileName }}</div>
|
<div class="file-name">{{ file.fileName }}</div>
|
||||||
<div class="file-meta">
|
<div v-if="fileMetaText(file)" class="file-meta">
|
||||||
<template v-if="file.fileType !== 'folder'">{{ file.sizeStr || '0B' }} · </template>{{ formatDate(file.createTime) }}
|
{{ fileMetaText(file) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!loading && (!currentFileList || currentFileList.length === 0)" class="empty-state">
|
<div v-if="!loading && (!currentFileList || currentFileList.length === 0)" class="empty-state">
|
||||||
@@ -168,7 +168,8 @@
|
|||||||
<div v-if="selectedNode.fileType !== 'folder'" class="file-detail-meta">
|
<div v-if="selectedNode.fileType !== 'folder'" class="file-detail-meta">
|
||||||
<p>类型: {{ getFileTypeClass(selectedNode) }}</p>
|
<p>类型: {{ getFileTypeClass(selectedNode) }}</p>
|
||||||
<p>大小: {{ selectedNode.sizeStr || '0B' }}</p>
|
<p>大小: {{ selectedNode.sizeStr || '0B' }}</p>
|
||||||
<p v-if="selectedNode.createTime">创建时间: {{ formatDate(selectedNode.createTime) }}</p>
|
<p v-if="formatDate(selectedNode.createTime)">创建时间: {{ formatDate(selectedNode.createTime) }}</p>
|
||||||
|
<p v-if="formatDate(selectedNode.updateTime)">更新时间: {{ formatDate(selectedNode.updateTime) }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="file-detail-actions">
|
<div class="file-detail-actions">
|
||||||
<el-button v-if="selectedNode.parserUrl" size="small" @click="previewFile(selectedNode)">
|
<el-button v-if="selectedNode.parserUrl" size="small" @click="previewFile(selectedNode)">
|
||||||
@@ -244,7 +245,8 @@
|
|||||||
<div v-if="selectedNode.fileType !== 'folder'" class="file-detail-meta">
|
<div v-if="selectedNode.fileType !== 'folder'" class="file-detail-meta">
|
||||||
<p>类型: {{ getFileTypeClass(selectedNode) }}</p>
|
<p>类型: {{ getFileTypeClass(selectedNode) }}</p>
|
||||||
<p>大小: {{ selectedNode.sizeStr || '0B' }}</p>
|
<p>大小: {{ selectedNode.sizeStr || '0B' }}</p>
|
||||||
<p v-if="selectedNode.createTime">创建时间: {{ formatDate(selectedNode.createTime) }}</p>
|
<p v-if="formatDate(selectedNode.createTime)">创建时间: {{ formatDate(selectedNode.createTime) }}</p>
|
||||||
|
<p v-if="formatDate(selectedNode.updateTime)">更新时间: {{ formatDate(selectedNode.updateTime) }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="file-detail-actions">
|
<div class="file-detail-actions">
|
||||||
<el-button v-if="selectedNode.parserUrl" size="small" @click="previewFile(selectedNode)">
|
<el-button v-if="selectedNode.parserUrl" size="small" @click="previewFile(selectedNode)">
|
||||||
@@ -314,8 +316,9 @@
|
|||||||
<div class="file-dialog-content">
|
<div class="file-dialog-content">
|
||||||
<p><strong>{{ selectedFile?.fileName || '未命名文件' }}</strong></p>
|
<p><strong>{{ selectedFile?.fileName || '未命名文件' }}</strong></p>
|
||||||
<p class="file-info">
|
<p class="file-info">
|
||||||
大小: {{ selectedFile?.sizeStr || '0B' }}<br>
|
<template v-for="(line, index) in selectedFileInfoLines" :key="index">
|
||||||
创建时间: {{ formatDate(selectedFile?.createTime) }}
|
{{ line }}<br v-if="index < selectedFileInfoLines.length - 1">
|
||||||
|
</template>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -444,6 +447,19 @@ export default {
|
|||||||
if (this.batchProgress.failed > 0) return 'exception'
|
if (this.batchProgress.failed > 0) return 'exception'
|
||||||
if (this.batchProgress.current >= this.batchProgress.total && this.batchProgress.total > 0) return 'success'
|
if (this.batchProgress.current >= this.batchProgress.total && this.batchProgress.total > 0) return 'success'
|
||||||
return ''
|
return ''
|
||||||
|
},
|
||||||
|
selectedFileInfoLines() {
|
||||||
|
if (!this.selectedFile) return []
|
||||||
|
const lines = [`大小: ${this.selectedFile.sizeStr || '0B'}`]
|
||||||
|
const createTime = this.formatDate(this.selectedFile.createTime)
|
||||||
|
const updateTime = this.formatDate(this.selectedFile.updateTime)
|
||||||
|
if (createTime) {
|
||||||
|
lines.push(`创建时间: ${createTime}`)
|
||||||
|
}
|
||||||
|
if (updateTime) {
|
||||||
|
lines.push(`更新时间: ${updateTime}`)
|
||||||
|
}
|
||||||
|
return lines
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -815,11 +831,54 @@ export default {
|
|||||||
document.body.removeChild(a)
|
document.body.removeChild(a)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
hasValidTime(value) {
|
||||||
|
if (value === null || value === undefined) return false
|
||||||
|
if (typeof value !== 'string') return true
|
||||||
|
const trimmedValue = value.trim()
|
||||||
|
return trimmedValue !== '' && trimmedValue !== 'null' && trimmedValue !== 'undefined'
|
||||||
|
},
|
||||||
|
formatDateOnly(yearValue, monthValue, dayValue) {
|
||||||
|
const year = Number(yearValue)
|
||||||
|
const month = Number(monthValue)
|
||||||
|
const day = Number(dayValue)
|
||||||
|
const date = new Date(year, month - 1, day)
|
||||||
|
if (
|
||||||
|
date.getFullYear() !== year ||
|
||||||
|
date.getMonth() !== month - 1 ||
|
||||||
|
date.getDate() !== day
|
||||||
|
) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
return `${yearValue}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`
|
||||||
|
},
|
||||||
formatDate(timestamp) {
|
formatDate(timestamp) {
|
||||||
if (!timestamp) return '未知时间'
|
if (!this.hasValidTime(timestamp)) return ''
|
||||||
const date = new Date(timestamp)
|
const value = typeof timestamp === 'string' ? timestamp.trim() : timestamp
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
const dateOnly = value.match(/^(\d{4})[-/](\d{1,2})[-/](\d{1,2})$/)
|
||||||
|
if (dateOnly) {
|
||||||
|
return this.formatDateOnly(dateOnly[1], dateOnly[2], dateOnly[3])
|
||||||
|
}
|
||||||
|
const cnDateOnly = value.match(/^(\d{4})年\s*(\d{1,2})月\s*(\d{1,2})日$/)
|
||||||
|
if (cnDateOnly) {
|
||||||
|
return this.formatDateOnly(cnDateOnly[1], cnDateOnly[2], cnDateOnly[3])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const date = new Date(value)
|
||||||
|
if (Number.isNaN(date.getTime())) return ''
|
||||||
return date.toLocaleString('zh-CN')
|
return date.toLocaleString('zh-CN')
|
||||||
},
|
},
|
||||||
|
fileMetaText(file) {
|
||||||
|
const parts = []
|
||||||
|
if (file.fileType !== 'folder') {
|
||||||
|
parts.push(file.sizeStr || '0B')
|
||||||
|
}
|
||||||
|
const timeText = this.formatDate(file.createTime)
|
||||||
|
if (timeText) {
|
||||||
|
parts.push(timeText)
|
||||||
|
}
|
||||||
|
return parts.join(' · ')
|
||||||
|
},
|
||||||
checkTheme() {
|
checkTheme() {
|
||||||
this.isDarkTheme = document.documentElement.classList.contains('dark')
|
this.isDarkTheme = document.documentElement.classList.contains('dark')
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -238,8 +238,8 @@
|
|||||||
storage: 'hash'
|
storage: 'hash'
|
||||||
},
|
},
|
||||||
'ctfile': {
|
'ctfile': {
|
||||||
reg: /((?:https?:\/\/)?(?:[a-zA-Z\d-.]+)?(?:ctfile|545c|u062|ghpym|474b)\.com\/\w+\/[a-zA-Z\d-]+)/,
|
reg: /((?:https?:\/\/)?(?:[a-zA-Z\d-.]+)?(?:ctfile|545c|u062|ghpym|474b)\.com\/(?:f(?:ile)?|d)\/[a-zA-Z\d_-]+\/?(?:\?[^#\s]*)?)/,
|
||||||
host: /(?:[a-zA-Z\d-.]+)?(?:ctfile|545c|u062|474b)\.com/,
|
host: /(?:[a-zA-Z\d-.]+)?(?:ctfile|545c|u062|ghpym|474b)\.com/,
|
||||||
input: ['#passcode'],
|
input: ['#passcode'],
|
||||||
button: ['.card-body button'],
|
button: ['.card-body button'],
|
||||||
name: '城通网盘',
|
name: '城通网盘',
|
||||||
|
|||||||
@@ -83,9 +83,9 @@ function registerTypeDefinitions(monaco) {
|
|||||||
clearHeaders(): JsHttpClient;
|
clearHeaders(): JsHttpClient;
|
||||||
getHeaders(): Record<string, string>;
|
getHeaders(): Record<string, string>;
|
||||||
setTimeout(seconds: number): JsHttpClient;
|
setTimeout(seconds: number): JsHttpClient;
|
||||||
sendForm(data: Record<string, any>): JsHttpResponse;
|
sendForm(url: string, data: Record<string, any>): JsHttpResponse;
|
||||||
sendMultipartForm(url: string, data: Record<string, any>): JsHttpResponse;
|
sendMultipartForm(url: string, data: Record<string, any>): JsHttpResponse;
|
||||||
sendJson(data: any): JsHttpResponse;
|
sendJson(url: string, data: any): JsHttpResponse;
|
||||||
urlEncode(str: string): string;
|
urlEncode(str: string): string;
|
||||||
urlDecode(str: string): string;
|
urlDecode(str: string): string;
|
||||||
}
|
}
|
||||||
@@ -244,17 +244,17 @@ function registerCompletionProvider(monaco) {
|
|||||||
range
|
range
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'http.sendForm(data)',
|
label: 'http.sendForm(url, data)',
|
||||||
kind: monaco.languages.CompletionItemKind.Method,
|
kind: monaco.languages.CompletionItemKind.Method,
|
||||||
insertText: 'http.sendForm(${1:data})',
|
insertText: 'http.sendForm(${1:url}, ${2:data})',
|
||||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||||
documentation: '发送表单数据',
|
documentation: '发送表单数据',
|
||||||
range
|
range
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'http.sendJson(data)',
|
label: 'http.sendJson(url, data)',
|
||||||
kind: monaco.languages.CompletionItemKind.Method,
|
kind: monaco.languages.CompletionItemKind.Method,
|
||||||
insertText: 'http.sendJson(${1:data})',
|
insertText: 'http.sendJson(${1:url}, ${2:data})',
|
||||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||||
documentation: '发送JSON数据',
|
documentation: '发送JSON数据',
|
||||||
range
|
range
|
||||||
|
|||||||
Reference in New Issue
Block a user