405 lines
14 KiB
Plaintext

<!--pages/list/list.wxml-->
<view class="container">
<!-- 顶部标题区域 -->
<view class="header-section">
<view class="header-content">
<text class="header-title">任务清单</text>
<view class="header-actions">
<view class="add-button" bind:tap="showAddSheet">
<t-icon name="add" size="18" color="white" />
</view>
</view>
</view>
<text class="header-subtitle">管理你的所有任务</text>
</view>
<!-- 统计概览卡片 -->
<view class="stats-card">
<view class="stats-row">
<view class="stat-item">
<text class="stat-number">{{stats.total}}</text>
<text class="stat-label">总任务</text>
</view>
<view class="stat-item">
<text class="stat-number">{{stats.completed}}</text>
<text class="stat-label">已完成</text>
</view>
<view class="stat-item">
<text class="stat-number">{{stats.pending}}</text>
<text class="stat-label">待完成</text>
</view>
<view class="stat-item">
<text class="stat-number">{{stats.completionRate}}%</text>
<text class="stat-label">完成率</text>
</view>
</view>
</view>
<!-- 搜索和筛选工具栏 -->
<view class="toolbar-section">
<view class="search-box">
<t-input
placeholder="搜索任务..."
value="{{searchText}}"
bind:change="onSearchInput"
prefix-icon="search"
class="search-input"
/>
</view>
<view class="filter-tabs">
<view
class="filter-tab {{filterStatus === 'all' ? 'active' : ''}}"
bind:tap="onStatusFilterChange"
data-value="all"
>
<text>全部</text>
<text class="tab-count">{{filteredTodos.length}}</text>
</view>
<view
class="filter-tab {{filterStatus === 'pending' ? 'active' : ''}}"
bind:tap="onStatusFilterChange"
data-value="pending"
>
<text>待完成</text>
<text class="tab-count">{{pendingCount}}</text>
</view>
<view
class="filter-tab {{filterStatus === 'completed' ? 'active' : ''}}"
bind:tap="onStatusFilterChange"
data-value="completed"
>
<text>已完成</text>
<text class="tab-count">{{completedCount}}</text>
</view>
</view>
</view>
<!-- 排序和筛选选项 -->
<view class="sort-section">
<view class="sort-options">
<view
class="sort-option {{sortBy === 'createdAt' ? 'active' : ''}}"
bind:tap="onSortChange"
data-value="createdAt"
>
<t-icon name="time" size="14" />
<text>时间</text>
</view>
<view
class="sort-option {{sortBy === 'priority' ? 'active' : ''}}"
bind:tap="onSortChange"
data-value="priority"
>
<t-icon name="star" size="14" />
<text>优先级</text>
</view>
<view
class="sort-option {{sortBy === 'text' ? 'active' : ''}}"
bind:tap="onSortChange"
data-value="text"
>
<t-icon name="text" size="14" />
<text>名称</text>
</view>
</view>
<view class="priority-filter">
<view
class="priority-filter-item {{filterPriority === 'all' ? 'active' : ''}}"
bind:tap="onPriorityFilterChange"
data-value="all"
>
<text>全部</text>
</view>
<view
class="priority-filter-item {{filterPriority === 'high' ? 'active' : ''}}"
bind:tap="onPriorityFilterChange"
data-value="high"
>
<view class="priority-dot high"></view>
<text>高</text>
</view>
<view
class="priority-filter-item {{filterPriority === 'medium' ? 'active' : ''}}"
bind:tap="onPriorityFilterChange"
data-value="medium"
>
<view class="priority-dot medium"></view>
<text>中</text>
</view>
<view
class="priority-filter-item {{filterPriority === 'low' ? 'active' : ''}}"
bind:tap="onPriorityFilterChange"
data-value="low"
>
<view class="priority-dot low"></view>
<text>低</text>
</view>
</view>
</view>
<!-- 任务列表 -->
<scroll-view class="todo-list-scroll" scroll-y type="list">
<view class="todo-list">
<view wx:if="{{filteredTodos.length === 0}}" class="empty-state">
<t-icon name="search" size="32" color="#ccc" />
<text wx:if="{{searchText || filterStatus !== 'all' || filterPriority !== 'all'}}" class="empty-text">
没有找到匹配的任务
</text>
<text wx:else class="empty-text">还没有任务,添加一个吧!</text>
</view>
<view wx:else>
<view wx:for="{{filteredTodos}}" wx:key="id" class="todo-item {{item.completed ? 'completed' : ''}}">
<view class="todo-main">
<view class="todo-checkbox">
<t-checkbox
checked="{{item.completed}}"
bind:change="toggleTodo"
data-id="{{item.id}}"
icon="{{ item.completed ? ['check-circle-filled', 'circle'] : ['circle', 'check-circle-filled'] }}"
/>
</view>
<view class="todo-content">
<view class="todo-header">
<text class="todo-text {{item.completed ? 'completed' : ''}}">{{item.text}}</text>
<view class="todo-priority">
<t-tag
theme="{{item.priority === 'high' ? 'danger' : item.priority === 'medium' ? 'warning' : 'primary'}}"
size="small"
variant="light"
>
{{item.priority === 'high' ? '高' : item.priority === 'medium' ? '中' : '低'}}
</t-tag>
</view>
</view>
<view class="todo-meta">
<view class="meta-left">
<text class="todo-time">{{formatTime(item.createdAt)}}</text>
<text wx:if="{{item.category}}" class="todo-category">
{{item.category === 'work' ? '工作' : item.category === 'personal' ? '个人' : item.category === 'study' ? '学习' : '生活'}}
</text>
<text wx:if="{{item.deadline}}" class="todo-deadline {{item.deadline < Date.now() && !item.completed ? 'overdue' : ''}}">
{{formatDateTime(item.deadline)}}
</text>
</view>
<view class="meta-right">
<text wx:if="{{item.completed}}" class="completed-time">
完成于 {{formatTime(item.completedAt)}}
</text>
</view>
</view>
<text wx:if="{{item.note}}" class="todo-note">{{item.note}}</text>
</view>
</view>
<view class="todo-actions">
<view class="action-btn" bind:tap="editTodo" data-id="{{item.id}}">
<t-icon name="edit" size="16" color="#666" />
</view>
<view class="action-btn" bind:tap="deleteTodo" data-id="{{item.id}}">
<t-icon name="delete" size="16" color="#e34d59" />
</view>
</view>
</view>
</view>
</view>
</scroll-view>
<!-- 底部操作栏 -->
<view class="bottom-actions">
<view class="action-group">
<t-button
theme="light"
size="small"
bind:tap="clearCompleted"
class="clear-btn"
>
清空已完成
</t-button>
<t-button
theme="light"
size="small"
bind:tap="exportData"
class="export-btn"
>
导出数据
</t-button>
</view>
<text class="task-summary">
共 {{filteredTodos.length}} 个任务,完成率 {{completionRate}}%
</text>
</view>
<!-- 添加任务半屏 -->
<view class="add-task-sheet {{showAddSheet ? 'show' : ''}}" bind:tap="hideAddSheet">
<view class="sheet-content" catch:tap="stopPropagation">
<view class="sheet-header">
<view class="sheet-handle"></view>
<text class="sheet-title">添加新任务</text>
<view class="sheet-close" bind:tap="hideAddSheet">
<t-icon name="close" size="20" color="#999" />
</view>
</view>
<view class="sheet-body">
<!-- 任务内容输入 -->
<view class="input-section">
<view class="input-label">任务内容</view>
<t-input
placeholder="请输入要完成的任务..."
value="{{newTodoText}}"
bind:change="onNewTodoInput"
class="task-input"
autoFocus="{{showAddSheet}}"
maxlength="100"
/>
</view>
<!-- 优先级选择 -->
<view class="input-section">
<view class="input-label">优先级</view>
<view class="priority-selector">
<view
class="priority-item {{newTodoPriority === 'high' ? 'active' : ''}}"
bind:tap="onPriorityChange"
data-value="high"
>
<view class="priority-dot high"></view>
<text class="priority-text">高优先级</text>
</view>
<view
class="priority-item {{newTodoPriority === 'medium' ? 'active' : ''}}"
bind:tap="onPriorityChange"
data-value="medium"
>
<view class="priority-dot medium"></view>
<text class="priority-text">中优先级</text>
</view>
<view
class="priority-item {{newTodoPriority === 'low' ? 'active' : ''}}"
bind:tap="onPriorityChange"
data-value="low"
>
<view class="priority-dot low"></view>
<text class="priority-text">低优先级</text>
</view>
</view>
</view>
<!-- 分类选择 -->
<view class="input-section">
<view class="input-label">分类</view>
<view class="category-selector">
<view
class="category-item {{newTodoCategory === 'work' ? 'active' : ''}}"
bind:tap="onCategoryChange"
data-value="work"
>
<t-icon name="business" size="16" />
<text>工作</text>
</view>
<view
class="category-item {{newTodoCategory === 'personal' ? 'active' : ''}}"
bind:tap="onCategoryChange"
data-value="personal"
>
<t-icon name="user" size="16" />
<text>个人</text>
</view>
<view
class="category-item {{newTodoCategory === 'study' ? 'active' : ''}}"
bind:tap="onCategoryChange"
data-value="study"
>
<t-icon name="education" size="16" />
<text>学习</text>
</view>
<view
class="category-item {{newTodoCategory === 'life' ? 'active' : ''}}"
bind:tap="onCategoryChange"
data-value="life"
>
<t-icon name="home" size="16" />
<text>生活</text>
</view>
</view>
</view>
<!-- 截止时间 -->
<view class="input-section">
<view class="input-label">截止时间(可选)</view>
<view class="datetime-picker" bind:tap="showDateTimePicker">
<t-icon name="time" size="16" color="#666" />
<text class="datetime-text {{newTodoDeadline ? '' : 'placeholder'}}">
{{newTodoDeadline ? formatDateTime(newTodoDeadline) : '点击选择截止时间'}}
</text>
<t-icon name="chevron-right" size="16" color="#ccc" />
</view>
<view wx:if="{{newTodoDeadline}}" class="datetime-clear" bind:tap="clearDeadline">
<text class="clear-text">清除截止时间</text>
</view>
</view>
<!-- 备注 -->
<view class="input-section">
<view class="input-label">备注(可选)</view>
<t-input
placeholder="添加备注信息..."
value="{{newTodoNote}}"
bind:change="onNewTodoNoteInput"
class="note-input"
type="textarea"
maxlength="200"
/>
</view>
</view>
<view class="sheet-footer">
<t-button
theme="light"
size="large"
bind:tap="hideAddSheet"
class="cancel-btn"
>
取消
</t-button>
<t-button
theme="primary"
size="large"
bind:tap="addTodo"
class="confirm-btn"
disabled="{{newTodoText === '' || newTodoText.length === 0}}"
>
添加任务
</t-button>
</view>
</view>
</view>
<!-- 日期时间选择器 -->
<picker
wx:if="{{showDateTimePicker}}"
mode="multiSelector"
range="{{dateTimeRange}}"
value="{{dateTimeValue}}"
bind:change="onDateTimeChange"
bind:cancel="hideDateTimePicker"
>
<view></view>
</picker>
<!-- 自定义标签栏 -->
<t-tab-bar value="{{activeTab}}" bind:change="onTabChange" t-class="custom-tab-bar">
<t-tab-bar-item value="home" icon="home" aria-label="首页">首页</t-tab-bar-item>
<t-tab-bar-item value="list" icon="bulletpoint" aria-label="任务">任务</t-tab-bar-item>
<t-tab-bar-item value="statistics" icon="chart" aria-label="统计">统计</t-tab-bar-item>
<t-tab-bar-item value="settings" icon="setting" aria-label="设置">设置</t-tab-bar-item>
</t-tab-bar>
</view>