405 lines
14 KiB
Plaintext
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>
|
|
|