Files
ai-app-database/app/templates/user/resources.html
T
huty f3bd3f68a5
CI — Docker Build & Push / Build & Push Image (push) Failing after 10m15s
新增文件夹功能
2026-04-23 15:45:28 +09:00

210 lines
8.2 KiB
HTML

{% extends 'base.html' %}
{% block title %}我的资源{% endblock %}
{% block breadcrumb %}
<ol class="breadcrumb mb-0">
<li class="breadcrumb-item">
<a href="{{ url_for('resources.list_resources') }}">我的资源</a>
</li>
{% for crumb in breadcrumb %}
<li class="breadcrumb-item {% if loop.last %}active{% endif %}">
{% if loop.last %}
<i class="bi bi-folder2-open me-1"></i>{{ crumb.name }}
{% else %}
<a href="{{ url_for('resources.list_resources', folder_id=crumb.id) }}">{{ crumb.name }}</a>
{% endif %}
</li>
{% endfor %}
{% if not breadcrumb %}
<li class="breadcrumb-item active">全部资源</li>
{% endif %}
</ol>
{% endblock %}
{% block content %}
<!-- 顶部操作栏 -->
<div class="d-flex flex-wrap gap-2 justify-content-between align-items-center mb-3">
<h4 class="mb-0">
{% if current_folder %}
<i class="bi bi-folder2-open text-warning me-2"></i>{{ current_folder.name }}
{% else %}
<i class="bi bi-grid me-2"></i>我的资源
{% endif %}
</h4>
<a href="{{ url_for('resources.upload') }}" class="btn btn-primary">
<i class="bi bi-plus-lg me-1"></i>添加资源
</a>
</div>
<!-- 当前文件夹操作栏 -->
{% if current_folder %}
<div class="d-flex align-items-center gap-2 mb-3 p-2 bg-light rounded border">
<nav aria-label="breadcrumb" class="flex-grow-1 mb-0">
<ol class="breadcrumb mb-0 small">
<li class="breadcrumb-item"><a href="{{ url_for('resources.list_resources') }}">根目录</a></li>
{% for crumb in breadcrumb %}
<li class="breadcrumb-item {% if loop.last %}active fw-medium{% endif %}">
{% if loop.last %}{{ crumb.name }}
{% else %}<a href="{{ url_for('resources.list_resources', folder_id=crumb.id) }}">{{ crumb.name }}</a>
{% endif %}
</li>
{% endfor %}
</ol>
</nav>
<div class="d-flex gap-1 flex-shrink-0">
<button class="btn btn-sm btn-outline-secondary"
onclick="openRename({{ current_folder.id }},'{{ current_folder.name }}')">
<i class="bi bi-pencil me-1"></i>重命名
</button>
<button class="btn btn-sm btn-outline-danger"
onclick="deleteFolder({{ current_folder.id }},'{{ current_folder.name }}')">
<i class="bi bi-trash me-1"></i>删除文件夹
</button>
</div>
</div>
{% endif %}
<!-- 统计徽章 -->
<div class="d-flex flex-wrap gap-2 mb-3">
{% for t, label, color in [('','全部','secondary'),('text','文本','light'),
('image','图片','success'),('audio','音频','warning'),
('video','视频','danger')] %}
<a href="{{ url_for('resources.list_resources', type=t, q=q, folder_id=folder_id or '') }}"
class="badge text-decoration-none badge-filter
{{ 'bg-primary' if rtype == t else 'bg-' + color + (' text-dark' if color in ['light','warning'] else '') }}">
{{ label }}
<span class="ms-1">{{ counts[t if t else 'total'] }}</span>
</a>
{% endfor %}
</div>
<!-- 搜索 -->
<form method="GET" class="mb-4">
<input type="hidden" name="type" value="{{ rtype }}">
{% if folder_id %}<input type="hidden" name="folder_id" value="{{ folder_id }}">{% endif %}
<div class="input-group" style="max-width:480px">
<input type="text" name="q" value="{{ q }}" class="form-control"
placeholder="搜索标题、描述、标签…">
<button class="btn btn-outline-secondary" type="submit">
<i class="bi bi-search"></i>
</button>
{% if q %}
<a href="{{ url_for('resources.list_resources', type=rtype, folder_id=folder_id or '') }}"
class="btn btn-outline-danger"><i class="bi bi-x"></i></a>
{% endif %}
</div>
</form>
<!-- 资源卡片网格 -->
{% if pagination.items %}
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-xl-4 g-4 mb-4">
{% for res in pagination.items %}
<div class="col">
<div class="card resource-card h-100 shadow-sm border-0">
<!-- 缩略图 / 类型图标区 -->
<div class="resource-thumb d-flex align-items-center justify-content-center
bg-{{ res.type_badge_color }}-subtle position-relative">
{% if res.resource_type == 'image' and res.file_path and res.download_status != 'downloading' %}
<img src="{{ url_for('static', filename=res.file_path) }}"
class="resource-thumb-img" alt="{{ res.title }}" loading="lazy">
{% else %}
<i class="bi bi-{{ res.type_icon }} text-{{ res.type_badge_color }}" style="font-size:3rem"></i>
{% endif %}
<!-- 下载状态徽章 -->
{% if res.download_status in ('pending','downloading') %}
<span class="badge bg-info position-absolute top-0 end-0 m-2">
<i class="bi bi-arrow-down-circle me-1"></i>下载中 {{ res.download_progress }}%
</span>
{% elif res.download_status == 'failed' %}
<span class="badge bg-danger position-absolute top-0 end-0 m-2">
<i class="bi bi-exclamation-triangle me-1"></i>失败
</span>
{% endif %}
</div>
<div class="card-body d-flex flex-column p-3">
<h6 class="card-title text-truncate mb-1" title="{{ res.title }}">{{ res.title }}</h6>
<div class="d-flex gap-1 mb-2 flex-wrap">
<span class="badge bg-{{ res.type_badge_color }}">{{ res.resource_type }}</span>
<span class="badge bg-light text-dark border">{{ res.source_type }}</span>
{% if res.file_size %}
<span class="badge bg-light text-muted border">{{ res.file_size | filesize }}</span>
{% endif %}
{% if res.folder and not folder_id %}
<span class="badge bg-light text-secondary border" title="{{ res.folder.name }}">
<i class="bi bi-folder me-1"></i>{{ res.folder.name | truncate(12, True) }}
</span>
{% endif %}
</div>
{% if res.description %}
<p class="card-text text-muted small text-truncate mb-2">{{ res.description }}</p>
{% endif %}
<div class="mt-auto d-flex gap-2">
<a href="{{ url_for('resources.detail', resource_id=res.id) }}"
class="btn btn-sm btn-outline-primary flex-grow-1">
<i class="bi bi-eye me-1"></i>查看
</a>
<form action="{{ url_for('resources.delete', resource_id=res.id) }}"
method="POST" class="d-inline"
onsubmit="return confirm('确认删除「{{ res.title }}」?')">
{{ csrf_token_input() }}
<button class="btn btn-sm btn-outline-danger" title="删除">
<i class="bi bi-trash"></i>
</button>
</form>
</div>
</div>
<div class="card-footer text-muted small py-1 px-3">
{{ res.created_at | datetime_fmt }}
</div>
</div>
</div>
{% endfor %}
</div>
<!-- 分页 -->
{% if pagination.pages > 1 %}
<nav class="d-flex justify-content-center">
<ul class="pagination">
{% if pagination.has_prev %}
<li class="page-item">
<a class="page-link"
href="?page={{ pagination.prev_num }}&q={{ q }}&type={{ rtype }}{% if folder_id %}&folder_id={{ folder_id }}{% endif %}">«</a>
</li>
{% endif %}
{% for p in pagination.iter_pages() %}
{% if p %}
<li class="page-item {{ 'active' if p == pagination.page else '' }}">
<a class="page-link"
href="?page={{ p }}&q={{ q }}&type={{ rtype }}{% if folder_id %}&folder_id={{ folder_id }}{% endif %}">{{ p }}</a>
</li>
{% else %}
<li class="page-item disabled"><span class="page-link"></span></li>
{% endif %}
{% endfor %}
{% if pagination.has_next %}
<li class="page-item">
<a class="page-link"
href="?page={{ pagination.next_num }}&q={{ q }}&type={{ rtype }}{% if folder_id %}&folder_id={{ folder_id }}{% endif %}">»</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="text-center py-5 text-muted">
<i class="bi bi-inbox" style="font-size:4rem"></i>
<h5 class="mt-3">暂无资源</h5>
{% if current_folder %}
<p>此文件夹还没有资源,点击「添加资源」开始上传</p>
{% else %}
<p>点击右上角「添加资源」开始添加</p>
{% endif %}
<a href="{{ url_for('resources.upload') }}" class="btn btn-primary">
<i class="bi bi-plus-lg me-1"></i>添加资源
</a>
</div>
{% endif %}
{% endblock %}