|
- {% extends "./layout.html" %}
-
- {% block title %}控制台{% endblock %}
-
- {% block css %}
- <style>
- .stat-cards{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:16px;}
- .stat-card{
- background:var(--white);border-radius:var(--radius);box-shadow:var(--shadow);
- padding:20px;display:flex;flex-wrap:wrap;align-items:flex-start;gap:14px;
- position:relative;overflow:hidden;transition:.2s;
- }
- .stat-card:hover{transform:translateY(-2px);box-shadow:0 4px 16px rgba(0,0,0,.1);}
- .stat-icon{
- width:48px;height:48px;border-radius:10px;display:flex;
- align-items:center;justify-content:center;flex-shrink:0;
- }
- .stat-icon svg{width:24px;height:24px;}
- .stat-info{flex:1;min-width:0;}
- .stat-value{font-size:26px;font-weight:700;color:var(--text);font-family:var(--font-en);line-height:1.2;}
- .stat-label{font-size:12px;color:var(--text-secondary);margin-top:4px;}
- .stat-footer{
- width:100%;padding-top:12px;margin-top:4px;border-top:1px solid var(--border-light);
- font-size:12px;color:var(--text-secondary);
- }
- .stat-up{color:var(--success);font-weight:500;}
- .stat-down{color:var(--danger);font-weight:500;}
-
- .dashboard-row{display:flex;gap:16px;}
-
- .shortcuts{display:grid;grid-template-columns:repeat(2,1fr);gap:10px;}
- .shortcut-item{
- display:flex;flex-direction:column;align-items:center;gap:8px;
- padding:14px 8px;border-radius:var(--radius);transition:.15s;cursor:pointer;
- text-decoration:none;
- }
- .shortcut-item:hover{background:var(--bg);}
- .shortcut-icon{
- width:40px;height:40px;border-radius:10px;display:flex;
- align-items:center;justify-content:center;
- }
- .shortcut-icon svg{width:20px;height:20px;}
- .shortcut-item span{font-size:12px;color:var(--text-regular);}
-
- .todo-list{display:flex;flex-direction:column;gap:0;}
- .todo-item{
- display:flex;align-items:center;gap:10px;padding:10px 0;
- border-bottom:1px solid var(--border-light);font-size:13px;color:var(--text-regular);
- }
- .todo-item:last-child{border-bottom:none;}
- .todo-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0;}
- .todo-text{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
-
- @media(max-width:1200px){
- .stat-cards{grid-template-columns:repeat(2,1fr);}
- .dashboard-row{flex-direction:column;}
- .dashboard-row>div:last-child{width:100%;}
- }
- </style>
- {% endblock %}
-
- {% block content %}
- <!-- 统计卡片 -->
- <div class="stat-cards">
- <div class="stat-card">
- <div class="stat-icon" style="background:rgba(232,117,26,.1);color:var(--primary);">
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
- </div>
- <div class="stat-info">
- <div class="stat-value">{{ stats.contentCount or 0 }}</div>
- <div class="stat-label">内容总数</div>
- </div>
- <div class="stat-footer"><span class="stat-up">↑ 12%</span> 较上月</div>
- </div>
- <div class="stat-card">
- <div class="stat-icon" style="background:rgba(230,162,60,.1);color:var(--warning);">
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
- </div>
- <div class="stat-info">
- <div class="stat-value">{{ stats.pendingCount or 0 }}</div>
- <div class="stat-label">待审核</div>
- </div>
- <div class="stat-footer"><span class="stat-down">↓ 3</span> 较昨日</div>
- </div>
- <div class="stat-card">
- <div class="stat-icon" style="background:rgba(103,194,58,.1);color:var(--success);">
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
- </div>
- <div class="stat-info">
- <div class="stat-value">{{ stats.visitCount or '0' }}</div>
- <div class="stat-label">本月访问</div>
- </div>
- <div class="stat-footer"><span class="stat-up">↑ 28%</span> 较上月</div>
- </div>
- <div class="stat-card">
- <div class="stat-icon" style="background:rgba(26,53,80,.1);color:var(--blue);">
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></svg>
- </div>
- <div class="stat-info">
- <div class="stat-value">¥{{ stats.donationTotal or '0' }}</div>
- <div class="stat-label">累计捐赠</div>
- </div>
- <div class="stat-footer"><span class="stat-up">↑ 5.2%</span> 较上季</div>
- </div>
- </div>
-
- <!-- 下方两列 -->
- <div class="dashboard-row">
- <!-- 最近更新 -->
- <div class="card" style="flex:1;">
- <div class="card-header">
- <span class="card-title">最近更新</span>
- <button class="el-btn el-btn-sm">查看全部</button>
- </div>
- <table class="el-table">
- <thead>
- <tr>
- <th>标题</th>
- <th>栏目</th>
- <th>状态</th>
- <th>更新时间</th>
- </tr>
- </thead>
- <tbody>
- {% if recentList and recentList.length %}
- {% for item in recentList %}
- <tr>
- <td>{{ item.title }}</td>
- <td>{{ item.column_name }}</td>
- <td>
- {% if item.status == 1 %}
- <span class="el-tag el-tag-success">已发布</span>
- {% else %}
- <span class="el-tag el-tag-warning">待审核</span>
- {% endif %}
- </td>
- <td>{{ item.update_time }}</td>
- </tr>
- {% endfor %}
- {% else %}
- <tr>
- <td colspan="4" style="text-align:center;color:var(--text-secondary);">暂无数据</td>
- </tr>
- {% endif %}
- </tbody>
- </table>
- </div>
-
- <!-- 快捷操作 & 待办 -->
- <div style="width:320px;display:flex;flex-direction:column;gap:16px;">
- <!-- 快捷操作 -->
- <div class="card">
- <div class="card-header">
- <span class="card-title">快捷操作</span>
- </div>
- <div class="shortcuts">
- <a href="/admin/content/article-edit.html" class="shortcut-item">
- <div class="shortcut-icon" style="background:rgba(232,117,26,.1);color:var(--primary);">
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
- </div>
- <span>发布文章</span>
- </a>
- <a href="/admin/content/image.html" class="shortcut-item">
- <div class="shortcut-icon" style="background:rgba(103,194,58,.1);color:var(--success);">
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>
- </div>
- <span>上传图片</span>
- </a>
- <a href="/admin/data/medicine.html" class="shortcut-item">
- <div class="shortcut-icon" style="background:rgba(26,53,80,.1);color:var(--blue);">
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></svg>
- </div>
- <span>录入数据</span>
- </a>
- <a href="#" class="shortcut-item">
- <div class="shortcut-icon" style="background:rgba(230,162,60,.1);color:var(--warning);">
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
- </div>
- <span>审核内容</span>
- </a>
- </div>
- </div>
-
- <!-- 待办事项 -->
- <div class="card">
- <div class="card-header">
- <span class="card-title">待办事项</span>
- </div>
- <div class="todo-list">
- {% if todoList and todoList.length %}
- {% for item in todoList %}
- <div class="todo-item">
- <span class="todo-dot" style="background:var(--warning);"></span>
- <span class="todo-text">{{ item.title }}</span>
- </div>
- {% endfor %}
- {% else %}
- <div class="todo-item">
- <span class="todo-dot" style="background:var(--success);"></span>
- <span class="todo-text">暂无待办事项</span>
- </div>
- {% endif %}
- </div>
- </div>
- </div>
- </div>
- {% endblock %}
|