todo_list
This commit is contained in:
@@ -35,6 +35,11 @@
|
||||
<i class="fas fa-file-image me-1"></i>内容管理
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if '/admin/todos' in request.url.path %}active{% endif %}" href="/admin/todos">
|
||||
<i class="fas fa-tasks me-1"></i>待办事项
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if '/admin/upload' in request.url.path %}active{% endif %}" href="/admin/upload">
|
||||
<i class="fas fa-upload me-1"></i>图片上传
|
||||
|
||||
@@ -100,20 +100,45 @@
|
||||
<div class="row">
|
||||
<div class="col-5">
|
||||
<div class="icon-big text-center">
|
||||
<i class="fas fa-play-circle"></i>
|
||||
<i class="fas fa-tasks"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-7">
|
||||
<div class="numbers">
|
||||
<p class="card-category">活跃内容</p>
|
||||
<h3 class="card-title">{{ active_content_count }}</h3>
|
||||
<p class="card-category">待办事项</p>
|
||||
<h3 class="card-title">{{ todo_count }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="stats">
|
||||
<i class="fas fa-chart-line"></i> 活跃率: {{ ((active_content_count / content_count * 100) | round(1) if content_count > 0 else 0) }}%
|
||||
<i class="fas fa-check-circle"></i> 完成率: {{ ((completed_todo_count / todo_count * 100) | round(1) if todo_count > 0 else 0) }}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xl-3 col-md-6 mb-4">
|
||||
<div class="card card-stats bg-danger text-white shadow-sm">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-5">
|
||||
<div class="icon-big text-center">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-7">
|
||||
<div class="numbers">
|
||||
<p class="card-category">待完成</p>
|
||||
<h3 class="card-title">{{ pending_todo_count }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="stats">
|
||||
<i class="fas fa-clock"></i> 待处理任务
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -172,36 +197,44 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 最近创建的内容 -->
|
||||
<!-- 最近待办事项 -->
|
||||
<div class="col-lg-6 mb-4">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header bg-white py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">
|
||||
<i class="fas fa-clock me-2"></i>最近创建的内容
|
||||
<i class="fas fa-tasks me-2"></i>最近待办事项
|
||||
</h6>
|
||||
<a href="/admin/contents" class="btn btn-sm btn-primary">
|
||||
<a href="/admin/todos" class="btn btn-sm btn-primary">
|
||||
<i class="fas fa-list me-1"></i>查看全部
|
||||
</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if recent_contents %}
|
||||
{% if recent_todos %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th><i class="fas fa-barcode me-1"></i>设备ID</th>
|
||||
<th><i class="fas fa-heading me-1"></i>标题</th>
|
||||
<th><i class="fas fa-code-branch me-1"></i>版本</th>
|
||||
<th><i class="fas fa-mobile-alt me-1"></i>设备</th>
|
||||
<th><i class="fas fa-check me-1"></i>状态</th>
|
||||
<th><i class="fas fa-calendar me-1"></i>创建时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for content in recent_contents %}
|
||||
{% for item in recent_todos %}
|
||||
{% set todo = item.todo %}
|
||||
{% set device = item.device %}
|
||||
<tr>
|
||||
<td><a href="/admin/devices/{{ content.device_id }}" class="text-decoration-none"><code>{{ content.device_id }}</code></a></td>
|
||||
<td><a href="/admin/devices/{{ content.device_id }}/contents/{{ content.version }}" class="text-decoration-none">{{ content.title }}</a></td>
|
||||
<td><span class="badge bg-info">v{{ content.version }}</span></td>
|
||||
<td>{{ content.created_at.strftime('%Y-%m-%d %H:%M') }}</td>
|
||||
<td><a href="/admin/todos/{{ todo.id }}" class="text-decoration-none">{{ todo.title }}</a></td>
|
||||
<td><a href="/admin/devices/{{ device.device_id }}" class="text-decoration-none">{{ device.name or device.device_id }}</a></td>
|
||||
<td>
|
||||
{% if todo.is_completed %}
|
||||
<span class="badge bg-success"><i class="fas fa-check me-1"></i>已完成</span>
|
||||
{% else %}
|
||||
<span class="badge bg-warning"><i class="fas fa-clock me-1"></i>待完成</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ todo.created_at.strftime('%Y-%m-%d %H:%M') }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
@@ -209,8 +242,8 @@
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="text-center py-4">
|
||||
<i class="fas fa-inbox fa-3x text-muted mb-3"></i>
|
||||
<p class="text-muted">暂无内容</p>
|
||||
<i class="fas fa-clipboard-list fa-3x text-muted mb-3"></i>
|
||||
<p class="text-muted">暂无待办事项</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -240,13 +273,13 @@
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<a href="/admin/upload" class="btn btn-success btn-lg btn-block">
|
||||
<i class="fas fa-upload me-2"></i> 上传图片
|
||||
<a href="/admin/todos/add" class="btn btn-warning btn-lg btn-block">
|
||||
<i class="fas fa-plus me-2"></i> 添加待办
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<a href="/admin/devices" class="btn btn-warning btn-lg btn-block">
|
||||
<i class="fas fa-tv me-2"></i> 设备管理
|
||||
<a href="/admin/todos" class="btn btn-success btn-lg btn-block">
|
||||
<i class="fas fa-tasks me-2"></i> 待办管理
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
108
templates/admin/todo_add.html
Normal file
108
templates/admin/todo_add.html
Normal file
@@ -0,0 +1,108 @@
|
||||
{% extends "admin/base.html" %}
|
||||
|
||||
{% block title %}添加待办事项{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h1 class="h2">
|
||||
<i class="fas fa-plus me-2"></i>添加待办事项
|
||||
</h1>
|
||||
<div class="btn-toolbar mb-2 mb-md-0">
|
||||
<div class="btn-group me-2">
|
||||
<a href="/admin/todos{% if device_id %}?device_id={{ device_id }}{% endif %}" class="btn btn-sm btn-outline-secondary">
|
||||
<i class="fas fa-arrow-left me-1"></i>返回列表
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="/admin">首页</a></li>
|
||||
<li class="breadcrumb-item"><a href="/admin/todos{% if device_id %}?device_id={{ device_id }}{% endif %}">待办事项管理</a></li>
|
||||
<li class="breadcrumb-item active">添加待办事项</li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-clipboard-list me-2"></i>待办事项信息
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="post" action="/admin/todos/add">
|
||||
<div class="mb-3">
|
||||
<label for="title" class="form-label">标题 <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" id="title" name="title" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="description" class="form-label">描述</label>
|
||||
<textarea class="form-control" id="description" name="description" rows="3"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="device_id" class="form-label">关联设备 <span class="text-danger">*</span></label>
|
||||
<select class="form-select" id="device_id" name="device_id" required>
|
||||
<option value="">请选择设备</option>
|
||||
{% for device in devices %}
|
||||
<option value="{{ device.device_id }}" {% if device_id and device.device_id == device_id %}selected{% endif %}>
|
||||
{{ device.name or device.device_id }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="due_date" class="form-label">截止时间</label>
|
||||
<input type="datetime-local" class="form-control" id="due_date" name="due_date">
|
||||
<div class="form-text">留空表示无截止时间</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="is_completed" name="is_completed">
|
||||
<label class="form-check-label" for="is_completed">
|
||||
标记为已完成
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between">
|
||||
<a href="/admin/todos{% if device_id %}?device_id={{ device_id }}{% endif %}" class="btn btn-secondary">
|
||||
<i class="fas fa-times me-1"></i>取消
|
||||
</a>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-save me-1"></i>保存
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-info-circle me-2"></i>帮助信息
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>创建一个新的待办事项:</p>
|
||||
<ul>
|
||||
<li><strong>标题:</strong>待办事项的简短描述</li>
|
||||
<li><strong>描述:</strong>待办事项的详细说明(可选)</li>
|
||||
<li><strong>关联设备:</strong>选择要显示此待办事项的设备</li>
|
||||
<li><strong>截止时间:</strong>设置待办事项的截止时间(可选)</li>
|
||||
<li><strong>状态:</strong>可以选择直接标记为已完成</li>
|
||||
</ul>
|
||||
<p class="text-muted">创建后,待办事项将发送到关联的设备,并可以在设备上标记完成状态。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
161
templates/admin/todo_detail.html
Normal file
161
templates/admin/todo_detail.html
Normal file
@@ -0,0 +1,161 @@
|
||||
{% extends "admin/base.html" %}
|
||||
|
||||
{% block title %}待办事项详情{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h1 class="h2">
|
||||
<i class="fas fa-tasks me-2"></i>待办事项详情
|
||||
</h1>
|
||||
<div class="btn-toolbar mb-2 mb-md-0">
|
||||
<div class="btn-group me-2">
|
||||
<a href="/admin/todos{% if todo.device_id %}?device_id={{ todo.device_id }}{% endif %}" class="btn btn-sm btn-outline-secondary">
|
||||
<i class="fas fa-arrow-left me-1"></i>返回列表
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="/admin">首页</a></li>
|
||||
<li class="breadcrumb-item"><a href="/admin/todos{% if todo.device_id %}?device_id={{ todo.device_id }}{% endif %}">待办事项管理</a></li>
|
||||
<li class="breadcrumb-item active">{{ todo.title }}</li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-clipboard-list me-2"></i>待办事项信息
|
||||
</h5>
|
||||
<span class="badge {% if todo.is_completed %}bg-success{% else %}bg-warning{% %} fs-6">
|
||||
{% if todo.is_completed %}已完成{% else %}未完成{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-3 fw-bold">标题:</div>
|
||||
<div class="col-sm-9">{{ todo.title }}</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-3 fw-bold">描述:</div>
|
||||
<div class="col-sm-9">{{ todo.description or '无' }}</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-3 fw-bold">关联设备:</div>
|
||||
<div class="col-sm-9">
|
||||
<a href="/admin/devices/{{ device.device_id }}" class="text-decoration-none">
|
||||
{{ device.name or device.device_id }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-3 fw-bold">截止时间:</div>
|
||||
<div class="col-sm-9">
|
||||
{% if todo.due_date %}
|
||||
{{ todo.due_date.strftime('%Y-%m-%d %H:%M') }}
|
||||
{% else %}
|
||||
无
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-3 fw-bold">创建时间:</div>
|
||||
<div class="col-sm-9">{{ todo.created_at.strftime('%Y-%m-%d %H:%M:%S') }}</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-3 fw-bold">更新时间:</div>
|
||||
<div class="col-sm-9">{{ todo.updated_at.strftime('%Y-%m-%d %H:%M:%S') }}</div>
|
||||
</div>
|
||||
|
||||
{% if todo.is_completed and todo.completed_at %}
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-3 fw-bold">完成时间:</div>
|
||||
<div class="col-sm-9">{{ todo.completed_at.strftime('%Y-%m-%d %H:%M:%S') }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="btn-group">
|
||||
<a href="/admin/todos/{{ todo.id }}/edit" class="btn btn-primary">
|
||||
<i class="fas fa-edit me-1"></i>编辑
|
||||
</a>
|
||||
<form method="post" action="/admin/todos/{{ todo.id }}/toggle" style="display: inline;">
|
||||
<button type="submit" class="btn {% if todo.is_completed %}btn-warning{% else %}btn-success{% %}">
|
||||
<i class="fas {% if todo.is_completed %}fa-undo{% else %}fa-check{% %} me-1"></i>
|
||||
{% if todo.is_completed %}标记为未完成{% else %}标记为已完成{% endif %}
|
||||
</button>
|
||||
</form>
|
||||
<form method="post" action="/admin/todos/{{ todo.id }}/delete" style="display: inline;" onsubmit="return confirm('确定要删除这个待办事项吗?');">
|
||||
<button type="submit" class="btn btn-danger">
|
||||
<i class="fas fa-trash me-1"></i>删除
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-info-circle me-2"></i>设备信息
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-4 fw-bold">设备ID:</div>
|
||||
<div class="col-sm-8">{{ device.device_id }}</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-4 fw-bold">设备名称:</div>
|
||||
<div class="col-sm-8">{{ device.name or '未设置' }}</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-4 fw-bold">设备类型:</div>
|
||||
<div class="col-sm-8">{{ device.device_type or '未知' }}</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-4 fw-bold">状态:</div>
|
||||
<div class="col-sm-8">
|
||||
{% if device.status == 'online' %}
|
||||
<span class="badge bg-success">在线</span>
|
||||
{% else %}
|
||||
<span class="badge bg-danger">离线</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-4 fw-bold">最后活跃:</div>
|
||||
<div class="col-sm-8">
|
||||
{% if device.last_seen %}
|
||||
{{ device.last_seen.strftime('%Y-%m-%d %H:%M:%S') }}
|
||||
{% else %}
|
||||
未知
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-3">
|
||||
<a href="/admin/devices/{{ device.device_id }}" class="btn btn-outline-primary btn-sm">
|
||||
<i class="fas fa-tv me-1"></i>查看设备详情
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
121
templates/admin/todo_edit.html
Normal file
121
templates/admin/todo_edit.html
Normal file
@@ -0,0 +1,121 @@
|
||||
{% extends "admin/base.html" %}
|
||||
|
||||
{% block title %}编辑待办事项{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h1 class="h2">
|
||||
<i class="fas fa-edit me-2"></i>编辑待办事项
|
||||
</h1>
|
||||
<div class="btn-toolbar mb-2 mb-md-0">
|
||||
<div class="btn-group me-2">
|
||||
<a href="/admin/todos/{{ todo.id }}" class="btn btn-sm btn-outline-secondary">
|
||||
<i class="fas fa-arrow-left me-1"></i>返回详情
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="/admin">首页</a></li>
|
||||
<li class="breadcrumb-item"><a href="/admin/todos{% if todo.device_id %}?device_id={{ todo.device_id }}{% endif %}">待办事项管理</a></li>
|
||||
<li class="breadcrumb-item"><a href="/admin/todos/{{ todo.id }}">{{ todo.title }}</a></li>
|
||||
<li class="breadcrumb-item active">编辑</li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-clipboard-list me-2"></i>待办事项信息
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="post" action="/admin/todos/{{ todo.id }}/edit">
|
||||
<div class="mb-3">
|
||||
<label for="title" class="form-label">标题 <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" id="title" name="title" value="{{ todo.title }}" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="description" class="form-label">描述</label>
|
||||
<textarea class="form-control" id="description" name="description" rows="3">{{ todo.description or '' }}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="device_id" class="form-label">关联设备 <span class="text-danger">*</span></label>
|
||||
<select class="form-select" id="device_id" name="device_id" required>
|
||||
{% for device in devices %}
|
||||
<option value="{{ device.device_id }}" {% if device.device_id == todo.device_id %}selected{% endif %}>
|
||||
{{ device.name or device.device_id }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="due_date" class="form-label">截止时间</label>
|
||||
<input type="datetime-local" class="form-control" id="due_date" name="due_date"
|
||||
{% if todo.due_date %}value="{{ todo.due_date.strftime('%Y-%m-%dT%H:%M') }}"{% endif %}>
|
||||
<div class="form-text">留空表示无截止时间</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="is_completed" name="is_completed"
|
||||
{% if todo.is_completed %}checked{% endif %}>
|
||||
<label class="form-check-label" for="is_completed">
|
||||
标记为已完成
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between">
|
||||
<a href="/admin/todos/{{ todo.id }}" class="btn btn-secondary">
|
||||
<i class="fas fa-times me-1"></i>取消
|
||||
</a>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-save me-1"></i>保存更改
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-info-circle me-2"></i>当前信息
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-4 fw-bold">创建时间:</div>
|
||||
<div class="col-sm-8">{{ todo.created_at.strftime('%Y-%m-%d %H:%M') }}</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-4 fw-bold">更新时间:</div>
|
||||
<div class="col-sm-8">{{ todo.updated_at.strftime('%Y-%m-%d %H:%M') }}</div>
|
||||
</div>
|
||||
|
||||
{% if todo.is_completed and todo.completed_at %}
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-4 fw-bold">完成时间:</div>
|
||||
<div class="col-sm-8">{{ todo.completed_at.strftime('%Y-%m-%d %H:%M') }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<hr>
|
||||
|
||||
<p class="text-muted">修改待办事项后,更新将发送到关联的设备。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
218
templates/admin/todos.html
Normal file
218
templates/admin/todos.html
Normal file
@@ -0,0 +1,218 @@
|
||||
{% extends "admin/base.html" %}
|
||||
|
||||
{% block title %}待办事项管理{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h1 class="h2">
|
||||
<i class="fas fa-tasks me-2"></i>待办事项管理
|
||||
{% if filtered %}
|
||||
<small class="text-muted">- {{ device.name or device.device_id }}</small>
|
||||
{% endif %}
|
||||
</h1>
|
||||
<div class="btn-toolbar mb-2 mb-md-0">
|
||||
<div class="btn-group me-2">
|
||||
<a href="/admin/todos/add{% if filtered %}?device_id={{ device.device_id }}{% endif %}" class="btn btn-sm btn-outline-secondary">
|
||||
<i class="fas fa-plus me-1"></i>添加待办事项
|
||||
</a>
|
||||
</div>
|
||||
{% if not filtered %}
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<i class="fas fa-filter me-1"></i>筛选设备
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
{% for device in devices %}
|
||||
<li><a class="dropdown-item" href="/admin/todos?device_id={{ device.device_id }}">{{ device.name or device.device_id }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if filtered %}
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="/admin/todos">所有待办事项</a></li>
|
||||
<li class="breadcrumb-item active">{{ device.name or device.device_id }}</li>
|
||||
</ol>
|
||||
</nav>
|
||||
{% endif %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
{% if filtered %}
|
||||
{% if todos %}
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fas fa-list me-2"></i>待办事项列表
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>标题</th>
|
||||
<th>描述</th>
|
||||
<th>截止时间</th>
|
||||
<th>状态</th>
|
||||
<th>创建时间</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for todo in todos %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/admin/todos/{{ todo.id }}" class="text-decoration-none">
|
||||
{{ todo.title }}
|
||||
</a>
|
||||
</td>
|
||||
<td>{{ todo.description or '-' }}</td>
|
||||
<td>
|
||||
{% if todo.due_date %}
|
||||
{{ todo.due_date.strftime('%Y-%m-%d %H:%M') }}
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if todo.is_completed %}
|
||||
<span class="badge bg-success">已完成</span>
|
||||
{% if todo.completed_at %}
|
||||
<small class="text-muted d-block">{{ todo.completed_at.strftime('%Y-%m-%d %H:%M') }}</small>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="badge bg-warning">未完成</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ todo.created_at.strftime('%Y-%m-%d %H:%M') }}</td>
|
||||
<td>
|
||||
<div class="btn-group btn-group-sm" role="group">
|
||||
<a href="/admin/todos/{{ todo.id }}" class="btn btn-outline-primary" title="查看详情">
|
||||
<i class="fas fa-eye"></i>
|
||||
</a>
|
||||
<form method="post" action="/admin/todos/{{ todo.id }}/toggle" style="display: inline;">
|
||||
<button type="submit" class="btn {% if todo.is_completed %}btn-outline-warning{% else %}btn-outline-success{% endif %}" title="{% if todo.is_completed %}标记为未完成{% else %}标记为已完成{% endif %}">
|
||||
<i class="fas {% if todo.is_completed %}fa-undo{% else %}fa-check{% endif %}"></i>
|
||||
</button>
|
||||
</form>
|
||||
<form method="post" action="/admin/todos/{{ todo.id }}/delete" style="display: inline;" onsubmit="return confirm('确定要删除这个待办事项吗?');">
|
||||
<button type="submit" class="btn btn-outline-danger" title="删除">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="card">
|
||||
<div class="card-body text-center py-5">
|
||||
<i class="fas fa-clipboard-list fa-3x text-muted mb-3"></i>
|
||||
<h5 class="text-muted">该设备暂无待办事项</h5>
|
||||
<p class="text-muted">点击上方按钮添加第一个待办事项</p>
|
||||
<a href="/admin/todos/add?device_id={{ device.device_id }}" class="btn btn-primary">
|
||||
<i class="fas fa-plus me-1"></i>添加待办事项
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if todo_list %}
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fas fa-list me-2"></i>所有待办事项
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>标题</th>
|
||||
<th>设备</th>
|
||||
<th>描述</th>
|
||||
<th>截止时间</th>
|
||||
<th>状态</th>
|
||||
<th>创建时间</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in todo_list %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/admin/todos/{{ item.todo.id }}" class="text-decoration-none">
|
||||
{{ item.todo.title }}
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="/admin/devices/{{ item.device.device_id }}" class="text-decoration-none">
|
||||
{{ item.device.name or item.device.device_id }}
|
||||
</a>
|
||||
</td>
|
||||
<td>{{ item.todo.description or '-' }}</td>
|
||||
<td>
|
||||
{% if item.todo.due_date %}
|
||||
{{ item.todo.due_date.strftime('%Y-%m-%d %H:%M') }}
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if item.todo.is_completed %}
|
||||
<span class="badge bg-success">已完成</span>
|
||||
{% if item.todo.completed_at %}
|
||||
<small class="text-muted d-block">{{ item.todo.completed_at.strftime('%Y-%m-%d %H:%M') }}</small>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="badge bg-warning">未完成</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ item.todo.created_at.strftime('%Y-%m-%d %H:%M') }}</td>
|
||||
<td>
|
||||
<div class="btn-group btn-group-sm" role="group">
|
||||
<a href="/admin/todos/{{ item.todo.id }}" class="btn btn-outline-primary" title="查看详情">
|
||||
<i class="fas fa-eye"></i>
|
||||
</a>
|
||||
<form method="post" action="/admin/todos/{{ item.todo.id }}/toggle" style="display: inline;">
|
||||
<button type="submit" class="btn {% if item.todo.is_completed %}btn-outline-warning{% else %}btn-outline-success{% endif %}" title="{% if item.todo.is_completed %}标记为未完成{% else %}标记为已完成{% endif %}">
|
||||
<i class="fas {% if item.todo.is_completed %}fa-undo{% else %}fa-check{% endif %}"></i>
|
||||
</button>
|
||||
</form>
|
||||
<form method="post" action="/admin/todos/{{ item.todo.id }}/delete" style="display: inline;" onsubmit="return confirm('确定要删除这个待办事项吗?');">
|
||||
<button type="submit" class="btn btn-outline-danger" title="删除">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="card">
|
||||
<div class="card-body text-center py-5">
|
||||
<i class="fas fa-clipboard-list fa-3x text-muted mb-3"></i>
|
||||
<h5 class="text-muted">暂无待办事项</h5>
|
||||
<p class="text-muted">点击上方按钮添加第一个待办事项</p>
|
||||
<a href="/admin/todos/add" class="btn btn-primary">
|
||||
<i class="fas fa-plus me-1"></i>添加待办事项
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user