feat: 添加分享到期时间显示功能

新增功能:
- 在分享列表表格中添加"到期时间"列,清晰显示每个分享的有效期
- 在分享创建成功后显示到期时间信息
- 添加友好的时间格式化显示(永久有效/今天过期/明天过期/X天后过期)
- 使用颜色区分不同状态:
  * 绿色: 永久有效
  * 蓝色: 正常有效期
  * 黄色: 即将过期(3天内)
  * 红色: 已过期

技术实现:
- frontend/app.html: 添加到期时间显示UI(表格列+分享结果)
- frontend/app.js: 添加3个辅助方法
  * formatExpireTime(): 格式化到期时间显示
  * isExpiringSoon(): 判断是否即将过期(3天内)
  * isExpired(): 判断是否已过期

改进用户体验:
- 用户可以直观看到分享何时过期
- 即将过期的分享会有醒目的黄色提醒
- 鼠标悬停显示完整的ISO时间戳
- 时间显示本地化,使用中文格式

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-14 12:23:41 +08:00
parent 70b03c3c6b
commit 692b495005
2 changed files with 70 additions and 0 deletions

View File

@@ -841,6 +841,14 @@
<div v-if="shareResult" class="alert alert-success" style="margin-top: 15px;">
<strong>分享链接:</strong><br>
<a :href="shareResult.share_url" target="_blank">{{ shareResult.share_url }}</a>
<div v-if="shareResult.expires_at" style="margin-top: 10px; padding-top: 10px; border-top: 1px solid #c3e6cb;">
<strong>到期时间:</strong>
<span :style="{color: isExpiringSoon(shareResult.expires_at) ? '#ffc107' : '#28a745'}"><i class="fas fa-clock"></i> {{ formatExpireTime(shareResult.expires_at) }}</span>
</div>
<div v-else style="margin-top: 10px; padding-top: 10px; border-top: 1px solid #c3e6cb;">
<strong>有效期:</strong>
<span style="color: #28a745;"><i class="fas fa-infinity"></i> 永久有效</span>
</div>
</div>
<div style="display: flex; gap: 10px; margin-top: 20px;">
<button class="btn btn-primary" @click="createShareAll()" style="flex: 1;">
@@ -878,6 +886,14 @@
<div v-if="shareResult" class="alert alert-success" style="margin-top: 15px;">
<strong>分享链接:</strong><br>
<a :href="shareResult.share_url" target="_blank">{{ shareResult.share_url }}</a>
<div v-if="shareResult.expires_at" style="margin-top: 10px; padding-top: 10px; border-top: 1px solid #c3e6cb;">
<strong>到期时间:</strong>
<span :style="{color: isExpiringSoon(shareResult.expires_at) ? '#ffc107' : '#28a745'}"><i class="fas fa-clock"></i> {{ formatExpireTime(shareResult.expires_at) }}</span>
</div>
<div v-else style="margin-top: 10px; padding-top: 10px; border-top: 1px solid #c3e6cb;">
<strong>有效期:</strong>
<span style="color: #28a745;"><i class="fas fa-infinity"></i> 永久有效</span>
</div>
</div>
<div style="display: flex; gap: 10px; margin-top: 20px;">
<button class="btn btn-primary" @click="createShareFile()" style="flex: 1;">
@@ -1146,6 +1162,7 @@
<th style="padding: 10px; text-align: left;">分享链接</th>
<th style="padding: 10px; text-align: center;">访问次数</th>
<th style="padding: 10px; text-align: center;">下载次数</th>
<th style="padding: 10px; text-align: center;">到期时间</th>
<th style="padding: 10px; text-align: center;">操作</th>
</tr>
</thead>
@@ -1157,6 +1174,10 @@
</td>
<td style="padding: 10px; text-align: center;">{{ share.view_count }}</td>
<td style="padding: 10px; text-align: center;">{{ share.download_count }}</td>
<td style="padding: 10px; text-align: center;">
<span v-if="!share.expires_at" style="color: #28a745;"><i class="fas fa-infinity"></i> 永久有效</span>
<span v-else :style="{color: isExpiringSoon(share.expires_at) ? '#ffc107' : isExpired(share.expires_at) ? '#dc3545' : '#667eea'}" :title="share.expires_at"><i class="fas fa-clock"></i> {{ formatExpireTime(share.expires_at) }}</span>
</td>
<td style="padding: 10px; text-align: center;">
<button class="btn" style="background: #dc3545; color: white;" @click="deleteShare(share.id)">
<i class="fas fa-trash"></i> 删除

View File

@@ -1307,6 +1307,55 @@ handleDragLeave(e) {
}
},
// 格式化到期时间显示
formatExpireTime(expiresAt) {
if (!expiresAt) return '永久有效';
const expireDate = new Date(expiresAt);
const now = new Date();
const diffMs = expireDate - now;
const diffDays = Math.ceil(diffMs / (1000 * 60 * 60 * 24));
// 格式化日期
const dateStr = expireDate.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit'
});
if (diffDays < 0) {
return `已过期 (${dateStr})`;
} else if (diffDays === 0) {
return `今天过期 (${dateStr})`;
} else if (diffDays === 1) {
return `明天过期 (${dateStr})`;
} else if (diffDays <= 7) {
return `${diffDays}天后过期 (${dateStr})`;
} else {
return dateStr;
}
},
// 判断是否即将过期3天内
isExpiringSoon(expiresAt) {
if (!expiresAt) return false;
const expireDate = new Date(expiresAt);
const now = new Date();
const diffMs = expireDate - now;
const diffDays = diffMs / (1000 * 60 * 60 * 24);
return diffDays > 0 && diffDays <= 3;
},
// 判断是否已过期
isExpired(expiresAt) {
if (!expiresAt) return false;
const expireDate = new Date(expiresAt);
const now = new Date();
return expireDate <= now;
},
copyShareLink(url) {
// 复制分享链接到剪贴板
if (navigator.clipboard && navigator.clipboard.writeText) {