吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 18519|回复: 514
上一主题 下一主题
收起左侧

[其他原创] 9.12更新 每周/日工作待办事项V2.1(提升用户体验)

    [复制链接]
跳转到指定楼层
楼主
bdxs2019 发表于 2025-8-24 21:38 回帖奖励
本帖最后由 bdxs2019 于 2025-9-14 14:11 编辑

2025.9.12更新内容:
1、调整导出日/周报和数据备份的菜单,结构更清晰;
2、优化导出日报默认导出当天逻辑;
3、调整任务进度条,更加直观
4、再次小优化语音与弹窗提醒功能(可能存在浏览器兼容性问题,语音播报和弹窗不及时)
5、增强了部分功能稳定性

9月12日更新-每周/日工作待办事项V2.1 源码下载: 每周工作待办事项V2.1(9.12更新).zip (347.92 KB, 下载次数: 712)

9月1日每周工作待办事项V2.0 源码下载:https://www.52pojie.cn/forum.php ... 33&pid=53782829
初始版本下载(旧版): 每日工作待办.zip (20.98 KB, 下载次数: 1856)
按月视图待办事项帖子:https://www.52pojie.cn/thread-2056057-1-1.html


一、简介:
每周/日工作待办管理工具(基于Excel表格思路开发)
这是一个简洁高效的每日工作计划管理工具,专为提升工作效率而设计。
二、主要核心功能:
1、带上一周、下一周等功能(全年自动计算)
2、语音与弹窗提醒功能(需要浏览器给通知权限,设置里可以开启和关闭对应功能)
3、支持所有周/日数据备份,导出CSV和导入CSV即可,重复自动过滤(注:非专业请勿直接编辑CSV文件)
4、上午、下午、晚上三个时段(设置里可以隐藏晚上时段,和隐藏显示时间范围)
5、周六、周日六计划任务功能(设置里可以隐藏周六、周日)
6、拖拽操作 - 直观的拖拽排序和任务调度(任务卡片可以随意拖动到对应的时间段)
7、添加任务后,点击任务卡卡片可以编辑或右上角 X 删除
8、自适应PC端和手机端(手机端建议用手机浏览器打开使用,避免微信限制数据导出功能)
三、核心特色
零依赖纯前端 离线运行,无需安装任何软件,打开浏览器即可使用
所有数据保存在本地浏览器,隐私安全有保障
四、适用场景
个人工作计划管理
团队任务分配跟踪
学习计划制定执行
五、快速上手
1、可点击任意表格空白处创建任务
2、拖拽任务卡片调整时间安排
3、点击任务编辑详细信息
4、使用CSV导出功能备份数据/也可以再次导入





[HTML] 纯文本查看 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>每日工作计划备忘录</title>
    <meta name="description" content="零依赖的每日工作计划管理工具,支持拖拽排序、Excel导入导出、离线使用">
    
    <!-- PWA配置 -->
    <link rel="manifest" href="./manifest.json">
    <meta name="theme-color" content="#0078f5">
    
    <!-- 任务提醒系统配置 -->
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="default">
    
    <link rel="stylesheet" href="styles.css">
    
    
    <!-- SheetJS库用于Excel导出 -->
    <script src="./xlsx.full.min.js"></script>

</head>
<body>
    <div class="container">
        <header class="header">
            <div class="header-info">
                <div class="date-display" id="currentDate"></div>
                <div class="week-info" id="weekInfo"></div>
            </div>
            <div class="week-navigation">
                <button class="btn btn-outline week-nav-btn" title="上一周">
                    <span class="nav-arrow">&#8249;</span>
                    <span class="nav-text">上一周</span>
                </button>
                <button class="btn btn-outline week-nav-btn" title="下一周">
                    <span class="nav-text">下一周</span>
                    <span class="nav-arrow">&#8250;</span>
                </button>
                <button class="btn btn-secondary week-nav-btn" title="回到本周">
                    <span class="nav-text">本周</span>
                </button>
            </div>
            <div class="controls">
                <button class="btn btn-primary">+ 添加任务</button>
                <button class="btn btn-secondary">清空本周</button>
                <div class="export-dropdown">
                    <button class="btn btn-primary dropdown-toggle"><span class="icon icon-chart"></span> 导出日/周报</button>
                    <div class="dropdown-menu" id="exportDropdown">
                        <button class="dropdown-item"><span class="icon icon-chart"></span> 导出日报</button>
                        <button class="dropdown-item"><span class="icon icon-chart"></span> 导出周报</button>
                    </div>
                </div>
                <div class="backup-dropdown">
                    <button class="btn btn-secondary dropdown-toggle"><span class="icon icon-database"></span> 数据备份</button>
                    <div class="dropdown-menu" id="backupDropdown">
                        <button class="dropdown-item"><span class="icon icon-export"></span>导出CSV备份</button>
                        <button class="dropdown-item"><span class="icon icon-import"></span>导入CSV还原</button>
                    </div>
                </div>
                <button class="btn btn-outline"><span class="icon icon-settings"></span> 设置</button>
            </div>
        </header>

        <!-- 任务进度条 -->
        <div class="progress-container" id="progressContainer">
            <div class="progress-header">
                <span class="progress-title"><span class="icon icon-chart"></span> 本周任务进度</span>
                <span class="progress-stats">
                    <span class="progress-completed">0</span>/<span class="progress-total">0</span> 任务完成
                </span>
            </div>
            <div class="progress-content">
                <div class="progress-bar-wrapper">
                    <div class="progress-bar">
                        <div class="progress-fill"></div>
                    </div>
                </div>
                <div class="progress-percentage">0%</div>
            </div>
        </div>

        <main class="main-content">
            <div class="table-title-container">
                <h1 class="table-title" id="tableTitle">每周工作计划表</h1>
                <input type="text" class="table-title-input" id="tableTitleInput" style="display: none;">
            </div>
            <div class="weekly-grid" id="weeklyGrid">
                <div class="time-slot-header"><span class="desktop-text">时间</span><span class="mobile-text">时间</span></div>
                <div class="day-header" data-day="1">
                    <span class="desktop-text">周一</span>
                    <span class="mobile-text">
                        上午
                        <span class="mobile-time-range" id="mobileTimeRangeAM">08:00-12:00</span>
                    </span>
                </div>
                <div class="day-header" data-day="2">
                    <span class="desktop-text">周二</span>
                    <span class="mobile-text">
                        下午
                        <span class="mobile-time-range" id="mobileTimeRangePM">13:00-18:00</span>
                    </span>
                </div>
                <div class="day-header" data-day="3">
                    <span class="desktop-text">周三</span>
                    <span class="mobile-text">
                        晚上
                        <span class="mobile-time-range" id="mobileTimeRangeEVENING">19:00-23:00</span>
                    </span>
                </div>
                <div class="day-header" data-day="4">周四</div>
                <div class="day-header" data-day="5">周五</div>
                <div class="day-header" data-day="6">周六</div>
                <div class="day-header" data-day="7">周日</div>

                <div class="time-label" data-mobile-day="1"><span class="desktop-text">上午<br>08:00-12:00</span><span class="mobile-text">周一</span></div>
                <div class="task-cell" data-day="1" data-slot="AM"></div>
                <div class="task-cell" data-day="2" data-slot="AM"></div>
                <div class="task-cell" data-day="3" data-slot="AM"></div>
                <div class="task-cell" data-day="4" data-slot="AM"></div>
                <div class="task-cell" data-day="5" data-slot="AM"></div>
                <div class="task-cell" data-day="6" data-slot="AM"></div>
                <div class="task-cell" data-day="7" data-slot="AM"></div>

                <div class="time-label" data-mobile-day="2"><span class="desktop-text">下午<br>13:00-18:00</span><span class="mobile-text">周二</span></div>
                <div class="task-cell" data-day="1" data-slot="PM"></div>
                <div class="task-cell" data-day="2" data-slot="PM"></div>
                <div class="task-cell" data-day="3" data-slot="PM"></div>
                <div class="task-cell" data-day="4" data-slot="PM"></div>
                <div class="task-cell" data-day="5" data-slot="PM"></div>
                <div class="task-cell" data-day="6" data-slot="PM"></div>
                <div class="task-cell" data-day="7" data-slot="PM"></div>

                <div class="time-label" data-mobile-day="3"><span class="desktop-text">晚上<br>19:00-23:00</span><span class="mobile-text">周三</span></div>
                <div class="task-cell" data-day="1" data-slot="EVENING"></div>
                <div class="task-cell" data-day="2" data-slot="EVENING"></div>
                <div class="task-cell" data-day="3" data-slot="EVENING"></div>
                <div class="task-cell" data-day="4" data-slot="EVENING"></div>
                <div class="task-cell" data-day="5" data-slot="EVENING"></div>
                <div class="task-cell" data-day="6" data-slot="EVENING"></div>
                <div class="task-cell" data-day="7" data-slot="EVENING"></div>
                
                <!-- 手机端额外的时间标签 -->
                <div class="time-label mobile-only" data-mobile-day="4"><span class="mobile-text">周四</span></div>
                <div class="time-label mobile-only" data-mobile-day="5"><span class="mobile-text">周五</span></div>
                <div class="time-label mobile-only" data-mobile-day="6"><span class="mobile-text">周六</span></div>
                <div class="time-label mobile-only" data-mobile-day="7"><span class="mobile-text">周日</span></div>
            </div>
        </main>

        <!-- 删除右侧面板 -->
        <!-- <aside class="properties-panel">
            <h3>任务详情</h3>
            <div id="taskProperties">
                <p style="color: var(--text-light); text-align: center;">选择任务查看详情</p>
            </div>
        </aside> -->
    </div>

    <!-- 任务编辑模态框 -->
    <div class="modal" id="taskModal">
        <div class="modal-content">
            <div class="modal-header">
                <h3 id="modalTitle">添加任务</h3>
                <button class="close-btn">×</button>
            </div>
            <form id="taskForm">
                <div class="form-group">
                    <label>任务标题</label>
                    <input type="text" class="form-control" id="taskTitle" required>
                </div>
                <div class="form-group" style="display: flex; gap: 15px;">
                    <div style="flex: 1;">
                        <label>开始时间</label>
                        <input type="time" class="form-control" id="taskStart" required>
                    </div>
                    <div style="flex: 1;">
                        <label>结束时间</label>
                        <input type="time" class="form-control" id="taskEnd" required>
                    </div>
                </div>
                <div style="font-size: 12px; color: #666; margin-top: 5px; margin-bottom: 10px;">
                    <span class="icon icon-chart"></span> 提示:可以直接手动输入时间,格式为 HH:MM
                </div>

                <div class="form-group">
                    <label>优先级</label>
                    <div class="priority-selector">
                        <button type="button" class="priority-btn" data-priority="3">低</button>
                        <button type="button" class="priority-btn" data-priority="2">中</button>
                        <button type="button" class="priority-btn" data-priority="1">高</button>
                    </div>
                </div>
                <div class="form-group">
                    <label>星期选择</label>
                    <div class="weekday-selector">
                        <button type="button" class="weekday-btn" data-day="1">周一</button>
                        <button type="button" class="weekday-btn" data-day="2">周二</button>
                        <button type="button" class="weekday-btn" data-day="3">周三</button>
                        <button type="button" class="weekday-btn" data-day="4">周四</button>
                        <button type="button" class="weekday-btn" data-day="5">周五</button>
                        <button type="button" class="weekday-btn" data-day="6">周六</button>
                        <button type="button" class="weekday-btn" data-day="7">周日</button>
                        <button type="button" class="weekday-btn" data-day="all">每天</button>
                    </div>
                </div>
                <div class="form-group">
                    <label>备注</label>
                    <textarea class="form-control" id="taskNote" rows="3"></textarea>
                </div>
                <div style="display: flex; gap: 10px; justify-content: flex-end;">
                    <button type="button" class="btn btn-secondary">取消</button>
                    <button type="submit" class="btn btn-primary">保存</button>
                </div>
            </form>
        </div>
    </div>

    <!-- 导入模态框 -->
    <div class="modal" id="importModal">
        <div class="modal-content">
            <div class="modal-header">
                <h3>
                        <span class="icon icon-import"></span>CSV任务导入
                    </h3>
                <button class="close-btn">×</button>
            </div>
            
            <div class="modal-body">
                <!-- 文件上传区域 -->
                <div class="import-upload-area">
                    <div class="upload-icon"></div>
                    <h4>拖拽文件到此处或点击选择</h4>
                    <p>支持CSV格式文件,文件大小不超过5MB</p>
                    <input type="file" id="fileInput" accept=".csv">
                    <button type="button" class="btn btn-primary">
                        <span class="icon icon-folder"></span> 选择CSV文件
                    </button>
                </div>

                <!-- 文件信息 -->
                <div id="fileInfo" style="display: none; margin-bottom: 20px; padding: 15px; background: #f8f9ff; border-radius: 8px;">
                    <div style="display: flex; align-items: center; justify-content: space-between;">
                        <div>
                            <strong id="fileName" style="color: var(--text-color);"></strong>
                            <span id="fileSize" style="color: var(--text-light); margin-left: 10px; font-size: 12px;"></span>
                        </div>
                        <button style="background: none; border: none; color: var(--text-light); cursor: pointer; font-size: 18px;">×</button>
                    </div>
                </div>

                <!-- 预览区域 -->
                <div id="importPreview" style="display: none;">
                    <div style="display: flex; align-items: center; margin-bottom: 15px; padding: 15px; background: linear-gradient(135deg, #e8f5e8, #f0f8f0); border-radius: 8px;">
                        <div style="font-size: 24px; margin-right: 12px;">
                            <span class="icon icon-check" style="width: 24px; height: 24px; display: inline-block;"></span>
                        </div>
                        <div>
                            <h4 style="margin: 0 0 5px 0; color: var(--text-color);">
                                找到 <span id="taskCount" style="color: var(--primary-color); font-weight: bold;">0</span> 个有效任务
                            </h4>
                            <p style="margin: 0; color: var(--text-light); font-size: 14px;">请确认导入内容是否正确</p>
                        </div>
                    </div>
                    
                    <div style="max-height: 300px; overflow-y: auto; border: 1px solid var(--border-color); border-radius: 8px; background: white;">
                        <div id="previewList" style="padding: 0;"></div>
                    </div>
                </div>

                <!-- 导入说明 -->
                <div class="import-instructions">
                    <h5><span class="icon icon-chart"></span> CSV文件格式说明</h5>
                    <p>请确保CSV文件包含以下列:<strong>星期,时段,标题,开始时间,结束时间,优先级,备注</strong></p>
                    <p>例如:周一,上午,团队会议,09:00,10:00,高,讨论项目进度</p>
                    <div class="encoding-tip">
                        <h6><span class="icon icon-warning"></span> 编码提示</h6>
                        <p>如果导入后出现乱码,请将CSV文件保存为UTF-8编码格式。在Excel中:另存为 → CSV UTF-8格式</p>
                    </div>
                    <a href="weekly_template.csv" class="download-template" download="每周任务模板.csv">
                        <span class="icon icon-download"></span> 下载CSV模板文件
                    </a>
                </div>
            </div>
            
            <div class="modal-footer">
                <button class="btn btn-secondary">取消</button>
                <button class="btn btn-primary" id="confirmImportBtn" disabled>
                    确认导入
                </button>
            </div>
        </div>
            </div>
        </div>
    </div>

    <!-- 设置模态框 -->
    <div class="modal" id="settingsModal">
        <div class="modal-content">
            <div class="modal-header">
                <h3>设置</h3>
                <button class="close-btn">×</button>
            </div>
            <div class="form-group">
                <label>主题</label>
                <div class="theme-selector">
                    <button type="button" class="theme-btn" style="background: white; border: 1px solid #ddd;" title="浅色"></button>
                    <button type="button" class="theme-btn" style="background: #1a1a1a;" title="深色"></button>
                    <button type="button" class="theme-btn" style="background: #f0f8f0;" title="护眼绿"></button>
                </div>
            </div>
            <div class="form-group">
                <label>显示设置</label>
                <div style="margin-bottom: 12px; border: 1px solid var(--border-color); padding: 12px; border-radius: 8px;">
                    <div style="display: flex; gap: 20px; margin-bottom: 8px;">
                        <label style="font-size: 14px; margin: 0; display: flex; align-items: center;">
                            <input type="checkbox" id="hideSaturday" style="margin-right: 8px;">
                            隐藏周六
                        </label>
                        <label style="font-size: 14px; margin: 0; display: flex; align-items: center;">
                            <input type="checkbox" id="hideSunday" style="margin-right: 8px;">
                            隐藏周日
                        </label>
                    </div>
                    <div style="font-size: 12px; color: #666;">
                        可以根据需要选择隐藏周六或周日列,适合灵活安排工作时间的用户
                    </div>
                </div>
            </div>
            <div class="form-group">
                <label>时段设置</label>
                <div style="background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 4px; padding: 8px; margin-bottom: 12px; font-size: 13px; color: #856404;">
                    <span class="icon icon-chart"></span> 提示:上午时段和下午时段为必选,不可取消显示
                </div>
                
                <!-- 手机端时间范围显示设置 -->
                <div class="time-range-config">
                    <label>
                        <input type="checkbox" id="showTimeRange" checked style="margin-right: 8px;">
                        显示时间范围
                    </label>
                    <div class="config-description">
                        控制PC端和手机端是否显示时间段的具体时间范围
                    </div>
                </div>
                
                <!-- 上午时段设置 -->
                <div class="time-slot-config">
                    <div class="time-slot-header">
                        <label>
                            <input type="checkbox" id="showMorning" checked style="margin-right: 8px;" disabled>
                            显示上午时段 (必选)
                        </label>
                    </div>
                    <div class="time-controls">
                        <select class="form-control" id="morningStart" style="width: 100px;">
                            <option value="01:00">01:00</option>
                            <option value="01:30">01:30</option>
                            <option value="02:00">02:00</option>
                            <option value="02:30">02:30</option>
                            <option value="03:00">03:00</option>
                            <option value="03:30">03:30</option>
                            <option value="04:00">04:00</option>
                            <option value="04:30">04:30</option>
                            <option value="05:00">05:00</option>
                            <option value="05:30">05:30</option>
                            <option value="06:00">06:00</option>
                            <option value="06:30">06:30</option>
                            <option value="07:00">07:00</option>
                            <option value="07:30">07:30</option>
                            <option value="08:00" selected>08:00</option>
                            <option value="08:30">08:30</option>
                            <option value="09:00">09:00</option>
                            <option value="09:30">09:30</option>
                            <option value="10:00">10:00</option>
                            <option value="10:30">10:30</option>
                            <option value="11:00">11:00</option>
                            <option value="11:30">11:30</option>
                        </select>
                        <span>至</span>
                        <select class="form-control" id="morningEnd" style="width: 100px;">
                            <option value="01:00">01:00</option>
                            <option value="01:30">01:30</option>
                            <option value="02:00">02:00</option>
                            <option value="02:30">02:30</option>
                            <option value="03:00">03:00</option>
                            <option value="03:30">03:30</option>
                            <option value="04:00">04:00</option>
                            <option value="04:30">04:30</option>
                            <option value="05:00">05:00</option>
                            <option value="05:30">05:30</option>
                            <option value="06:00">06:00</option>
                            <option value="06:30">06:30</option>
                            <option value="07:00">07:00</option>
                            <option value="07:30">07:30</option>
                            <option value="08:00">08:00</option>
                            <option value="08:30">08:30</option>
                            <option value="09:00">09:00</option>
                            <option value="09:30">09:30</option>
                            <option value="10:00">10:00</option>
                            <option value="10:30">10:30</option>
                            <option value="11:00">11:00</option>
                            <option value="11:30">11:30</option>
                            <option value="12:00" selected>12:00</option>
                            <option value="12:30">12:30</option>
                            <option value="13:00">13:00</option>
                            <option value="13:30">13:30</option>
                            <option value="14:00">14:00</option>
                            <option value="14:30">14:30</option>
                            <option value="15:00">15:00</option>
                            <option value="15:30">15:30</option>
                            <option value="16:00">16:00</option>
                            <option value="16:30">16:30</option>
                            <option value="17:00">17:00</option>
                            <option value="17:30">17:30</option>
                            <option value="18:00">18:00</option>
                            <option value="18:30">18:30</option>
                            <option value="19:00">19:00</option>
                            <option value="19:30">19:30</option>
                            <option value="20:00">20:00</option>
                            <option value="20:30">20:30</option>
                            <option value="21:00">21:00</option>
                            <option value="21:30">21:30</option>
                            <option value="22:00">22:00</option>
                            <option value="22:30">22:30</option>
                            <option value="23:00">23:00</option>
                            <option value="23:30">23:30</option>
                            <option value="24:00">24:00</option>
                        </select>
                    </div>
                </div>

                <!-- 下午时段设置 -->
                <div class="time-slot-config">
                    <div class="time-slot-header">
                        <label>
                            <input type="checkbox" id="showAfternoon" checked style="margin-right: 8px;" disabled>
                            显示下午时段 (必选)
                        </label>
                    </div>
                    <div class="time-controls">
                        <select class="form-control" id="afternoonStart" style="width: 100px;">
                            <option value="12:00">12:00</option>
                            <option value="12:30">12:30</option>
                            <option value="13:00" selected>13:00</option>
                            <option value="13:30">13:30</option>
                            <option value="14:00">14:00</option>
                            <option value="14:30">14:30</option>
                            <option value="15:00">15:00</option>
                            <option value="15:30">15:30</option>
                        </select>
                        <span>至</span>
                        <select class="form-control" id="afternoonEnd" style="width: 100px;">
                            <option value="16:00">16:00</option>
                            <option value="16:30">16:30</option>
                            <option value="17:00">17:00</option>
                            <option value="17:30">17:30</option>
                            <option value="18:00" selected>18:00</option>
                            <option value="18:30">18:30</option>
                            <option value="19:00">19:00</option>
                            <option value="19:30">19:30</option>
                            <option value="20:00">20:00</option>
                            <option value="20:30">20:30</option>
                        </select>
                    </div>
                </div>

                <!-- 晚上时段设置 -->
                <div class="time-slot-config">
                    <div class="time-slot-header">
                        <label>
                            <input type="checkbox" id="showEvening" checked style="margin-right: 8px;">
                            显示晚上时段
                        </label>
                    </div>
                    <div class="time-controls">
                        <select class="form-control" id="eveningStart" style="width: 100px;">
                            <option value="18:00">18:00</option>
                            <option value="18:30">18:30</option>
                            <option value="19:00" selected>19:00</option>
                            <option value="19:30">19:30</option>
                            <option value="20:00">20:00</option>
                            <option value="20:30">20:30</option>
                            <option value="21:00">21:00</option>
                            <option value="21:30">21:30</option>
                        </select>
                        <span>至</span>
                        <select class="form-control" id="eveningEnd" style="width: 100px;">
                            <option value="21:00">21:00</option>
                            <option value="21:30">21:30</option>
                            <option value="22:00">22:00</option>
                            <option value="22:30">22:30</option>
                            <option value="23:00" selected>23:00</option>
                            <option value="23:30">23:30</option>
                            <option value="24:00">24:00</option>
                        </select>
                    </div>
                </div>
            </div>
            
            <!-- 任务提醒系统设置 -->
            <div class="form-group">
                <label>任务提醒设置</label>
                <div style="background: #e3f2fd; border: 1px solid #bbdefb; border-radius: 4px; padding: 8px; margin-bottom: 12px; font-size: 13px; color: #1976d2;">
                    <span class="icon icon-chart"></span> 任务提醒系统:在任务开始和结束时间自动提醒,支持语音播报和弹窗通知
                </div>
                
                <div style="margin-bottom: 12px; border: 1px solid var(--border-color); padding: 12px; border-radius: 8px;">
                    <label style="font-size: 14px; margin: 0; display: flex; align-items: center;">
                        <input type="checkbox" id="enableTaskReminders" checked style="margin-right: 8px;">
                        启用任务提醒系统
                    </label>
                    <div style="font-size: 12px; color: #666; margin-top: 4px;">
                        启用后将在任务开始和结束时间自动提醒
                    </div>
                </div>
                
                <div style="margin-bottom: 12px; border: 1px solid var(--border-color); padding: 12px; border-radius: 8px;">
                    <label style="font-size: 14px; margin: 0; display: flex; align-items: center;">
                        <input type="checkbox" id="enableVoiceReminders" checked style="margin-right: 8px;">
                        启用语音提醒
                    </label>
                    <div style="font-size: 12px; color: #666; margin-top: 4px;">
                        启用语音播报提醒(需要浏览器支持)
                    </div>
                </div>
                
                <div style="margin-bottom: 12px; border: 1px solid var(--border-color); padding: 12px; border-radius: 8px;">
                    <label style="font-size: 14px; margin: 0; display: flex; align-items: center;">
                        <input type="checkbox" id="enablePopupReminders" checked style="margin-right: 8px;">
                        启用弹窗提醒
                    </label>
                    <div style="font-size: 12px; color: #666; margin-top: 4px;">
                        启用弹窗通知提醒(支持后台提醒)
                    </div>
                </div>
                
                <div style="margin-bottom: 12px; border: 1px solid var(--border-color); padding: 12px; border-radius: 8px;">
                    <label style="font-size: 14px; margin: 0; display: flex; align-items: center;">
                        <input type="checkbox" id="enableBackgroundReminders" checked style="margin-right: 8px;">
                        启用后台提醒
                    </label>
                    <div style="font-size: 12px; color: #666; margin-top: 4px;">
                        即使浏览器标签页不活跃也能收到提醒
                    </div>
                </div>
                
                <!-- 测试提醒功能 -->
                <div style="margin-bottom: 12px; border: 1px solid var(--border-color); padding: 12px; border-radius: 8px; text-align: center;">
                    <div style="font-size: 14px; margin-bottom: 10px; color: #666;">测试提醒功能</div>
                    <div style="display: flex; gap: 10px; justify-content: center; flex-wrap: wrap;">
                        <button type="button" class="btn btn-primary" style="font-size: 12px; padding: 8px 15px;">
                            测试开始提醒
                        </button>
                        <button type="button" class="btn btn-success" style="font-size: 12px; padding: 8px 15px;">
                            测试结束提醒
                        </button>
                        <button type="button" class="btn btn-warning" style="font-size: 12px; padding: 8px 15px;">
                            测试语音播报
                        </button>
                    </div>
                    <div style="font-size: 11px; color: #999; margin-top: 8px;">
                        点击按钮测试语音和弹窗提醒功能
                    </div>
                </div>
            </div>
            
            <div style="display: flex; gap: 10px; justify-content: flex-end;">
                <button class="btn btn-primary">保存设置</button>
            </div>
        </div>
    </div>

    <!-- 日报导出模态框 -->
    <div class="modal" id="dailyExportModal">
        <div class="modal-content" style="max-width: 500px;">
            <div class="modal-header">
                <h3 style="margin: 0; color: var(--primary-color);">
                    <span class="icon icon-chart"></span> 导出日报
                </h3>
                <button class="close-btn">×</button>
            </div>
            <div class="modal-body" style="padding: 30px;">
                <div class="form-group">
                    <label style="font-size: 16px; font-weight: 500; margin-bottom: 15px; display: block;">选择要导出的日期:</label>
                    <div class="weekday-selector" style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px;">
                        <button type="button" class="export-day-btn" data-day="1">周一</button>
                        <button type="button" class="export-day-btn" data-day="2">周二</button>
                        <button type="button" class="export-day-btn" data-day="3">周三</button>
                        <button type="button" class="export-day-btn" data-day="4">周四</button>
                        <button type="button" class="export-day-btn" data-day="5">周五</button>
                        <button type="button" class="export-day-btn" data-day="6">周六</button>
                        <button type="button" class="export-day-btn" data-day="7">周日</button>
                    </div>
                </div>
                <div style="background: #f8f9fa; border-radius: 8px; padding: 15px; margin-top: 20px;">
                    <p style="margin: 0; font-size: 14px; color: #666;">
                        <strong><span class="icon icon-chart"></span> 导出说明:</strong><br>
                        &#8226; 将导出选定日期的所有时段任务<br>
                        &#8226; 文件格式:Excel (.xlsx)<br>
                        &#8226; 包含任务标题、时间、优先级等信息
                    </p>
                </div>
            </div>
            <div class="modal-footer" style="padding: 20px 30px; border-top: 1px solid var(--border-color); display: flex; justify-content: flex-end; gap: 12px;">
                <button class="btn btn-secondary">取消</button>
                <button class="btn btn-primary" id="exportDailyBtn" disabled>
                    <span class="icon icon-chart"></span> 导出日报
                </button>
            </div>
        </div>
    </div>

    <!-- 提示消息 -->
    <div class="toast" id="toast"></div>

    <!-- 删除确认模态框 -->
    <div class="modal" id="deleteConfirmModal">
        <div class="modal-content" style="max-width: 400px; text-align: center;">
            <div class="modal-header" style="border-bottom: none; padding-bottom: 10px;">
                <h3 style="margin: 0; color: var(--primary-color); font-size: 18px;">
                    <span class="icon icon-warning"></span> 确认删除
                </h3>
            </div>
            <div class="modal-body" style="padding: 20px 30px;">
                <p style="margin: 0; font-size: 16px; color: var(--text-color); line-height: 1.5;">
                    确定要删除这个任务吗?
                </p>
                <p style="margin: 10px 0 0 0; font-size: 14px; color: #666;">
                    此操作无法撤销
                </p>
            </div>
            <div class="modal-footer" style="padding: 20px 30px; border-top: 1px solid var(--border-color); display: flex; justify-content: center; gap: 15px;">
                <button class="btn btn-secondary" style="min-width: 80px;">取消</button>
                <button class="btn btn-danger" style="min-width: 80px; background: #dc3545; border-color: #dc3545;">删除</button>
            </div>
        </div>
    </div>

    <!-- 任务提醒模态框 -->
    <div class="reminder-modal" id="reminderModal">
        <div class="reminder-content">
            <div class="reminder-header">
                <div class="reminder-title" id="reminderTitle">任务提醒</div>
                <div class="reminder-subtitle" id="reminderSubtitle">您有新的任务提醒</div>
                <button class="close-btn" style="position: absolute; top: 15px; right: 15px; background: none; border: none; font-size: 24px; cursor: pointer; color: #666;">×</button>
            </div>
            
            <div class="reminder-task-info">
                <div class="reminder-task-title" id="reminderTaskTitle">任务标题</div>
                <div class="reminder-task-time" id="reminderTaskTime">时间信息</div>
                <div class="reminder-task-note" id="reminderTaskNote">备注信息</div>
            </div>
            
            <div class="reminder-actions" id="reminderActions">
                <!-- 开始时间提醒的按钮 -->
                <button class="reminder-btn reminder-btn-primary" id="startReminderBtn" style="display: none;">确认</button>
                
                <!-- 结束时间提醒的按钮 -->
                <button class="reminder-btn reminder-btn-success" id="endReminderConfirmBtn" style="display: none;">确认完成</button>
                <button class="reminder-btn reminder-btn-secondary" id="endReminderDelayBtn" style="display: none;">5分钟后再提醒</button>
            </div>
            
            <div class="reminder-settings">
                <label>
                    <input type="checkbox" id="reminderVoiceCheckbox" checked> 启用语音提醒
                </label>
                <label>
                    <input type="checkbox" id="reminderPopupCheckbox" checked> 启用弹窗提醒
                </label>
            </div>
        </div>
    </div>

    <script>
        // 全局变量
        let tasks = [];
        let currentEditingTask = null;
        let draggedTask = null;
        let importedData = null;
        
        // 周导航相关变量
        let currentWeekOffset = 0; // 相对于当前周的偏移量,0表示本周,-1表示上周,1表示下周
        let currentDisplayDate = new Date(); // 当前显示的日期

        // 任务提醒系统相关变量
        let reminderSystem = {
            enabled: true,
            voiceEnabled: true,
            popupEnabled: true,
            backgroundEnabled: true,
            currentReminder: null,
            reminderTimeouts: new Map(),
            speechSynthesis: null,
            notificationPermission: 'default',
            // 新增:提醒记录,防止重复提醒
            reminderHistory: new Map(), // 格式: 'taskId-type-date' -> timestamp
            lastCheckTime: null, // 记录上次检查的时间
            // 页面可见性相关
            isPageVisible: true, // 页面是否可见
            visibilityChangeHandlers: [], // 页面可见性变化处理器
            // 新增:自动确认定时器
            autoConfirmTimeout: null // 30秒自动确认定时器
        };
        
        // 初始化Page Visibility API
        function initPageVisibility() {
            // 检查浏览器支持
            let hidden, visibilityChange;
            if (typeof document.hidden !== "undefined") {
                hidden = "hidden";
                visibilityChange = "visibilitychange";
            } else if (typeof document.msHidden !== "undefined") {
                hidden = "msHidden";
                visibilityChange = "msvisibilitychange";
            } else if (typeof document.webkitHidden !== "undefined") {
                hidden = "webkitHidden";
                visibilityChange = "webkitvisibilitychange";
            }
            
            if (typeof document[hidden] !== "undefined") {
                // 初始状态
                reminderSystem.isPageVisible = !document[hidden];
                
                // 监听可见性变化
                document.addEventListener(visibilityChange, function() {
                    const wasVisible = reminderSystem.isPageVisible;
                    reminderSystem.isPageVisible = !document[hidden];
                    
                    console.log(`页面可见性变化: ${wasVisible ? '可见' : '隐藏'} -> ${reminderSystem.isPageVisible ? '可见' : '隐藏'}`);
                    
                    // 触发处理器
                    reminderSystem.visibilityChangeHandlers.forEach(handler => {
                        try {
                            handler(reminderSystem.isPageVisible, wasVisible);
                        } catch (error) {
                            console.error('页面可见性变化处理器错误:', error);
                        }
                    });
                }, false);
                
                console.log('Page Visibility API 初始化成功');
            } else {
                console.warn('浏览器不支持 Page Visibility API');
            }
        }

        // 初始化语音合成
        function initSpeechSynthesis() {
            console.log('=== 初始化语音合成 ===');
            if ('speechSynthesis' in window) {
                reminderSystem.speechSynthesis = window.speechSynthesis;
                console.log('语音合成对象已设置');
                
                // 语音列表可能需要时间加载,设置监听器
                const loadVoices = () => {
                    const voices = reminderSystem.speechSynthesis.getVoices();
                    console.log('语音列表加载完成,可用语音数量:', voices.length);
                    
                    if (voices.length > 0) {
                        console.log('可用语音:', voices.map(v => `${v.name} (${v.lang})`));
                        
                        // 尝试找到中文语音
                        const chineseVoice = voices.find(voice => 
                            voice.lang.includes('zh') || voice.lang.includes('cmn')
                        );
                        if (chineseVoice) {
                            console.log('找到中文语音:', chineseVoice.name);
                            reminderSystem.speechSynthesis.defaultVoice = chineseVoice;
                        } else {
                            console.log('未找到中文语音,将使用默认语音');
                        }
                    } else {
                        console.log('暂无可用语音,可能还在加载中');
                    }
                };
                
                // 立即尝试加载
                loadVoices();
                
                // 监听语音变化事件(某些浏览器需要)
                if (reminderSystem.speechSynthesis.onvoiceschanged !== undefined) {
                    reminderSystem.speechSynthesis.onvoiceschanged = loadVoices;
                }
                
                console.log('语音合成初始化完成');
            } else {
                console.warn('浏览器不支持语音合成功能');
            }
        }

        // 语音播报
        function speakMessage(message, forceSpeak = false) {
            console.log('=== 语音播报调试信息 ===');
            console.log('消息:', message);
            console.log('强制播放:', forceSpeak);
            console.log('语音启用状态:', reminderSystem.voiceEnabled);
            console.log('语音合成对象:', reminderSystem.speechSynthesis);
            console.log('页面可见状态:', reminderSystem.isPageVisible);
            
            if (!reminderSystem.voiceEnabled) {
                console.log('语音提醒已禁用');
                return;
            }
            
            if (!reminderSystem.speechSynthesis) {
                console.log('语音合成不可用');
                return;
            }
            
            // 移除页面可见性检查,允许在后台播放语音
            // 现代浏览器的语音合成API支持在后台标签页播放
            console.log('执行语音播报(支持后台播放)');
            
            try {
                console.log('开始执行语音播报...');
                
                // 停止当前播放的语音
                if (reminderSystem.speechSynthesis.speaking) {
                    console.log('停止当前播放的语音');
                    reminderSystem.speechSynthesis.cancel();
                }
                
                // 等待一小段时间确保cancel完成
                setTimeout(() => {
                    const utterance = new SpeechSynthesisUtterance(message);
                    utterance.lang = 'zh-CN';
                    utterance.rate = 0.9;
                    utterance.pitch = 1.0;
                    utterance.volume = 1.0;
                    
                    // 获取可用语音
                    const voices = reminderSystem.speechSynthesis.getVoices();
                    console.log('可用语音数量:', voices.length);
                    
                    // 如果有中文语音,使用中文语音
                    const chineseVoice = voices.find(voice => 
                        voice.lang.includes('zh') || voice.lang.includes('cmn')
                    );
                    if (chineseVoice) {
                        console.log('使用中文语音:', chineseVoice.name);
                        utterance.voice = chineseVoice;
                    } else {
                        console.log('未找到中文语音,使用默认语音');
                    }
                    
                    utterance.onstart = () => {
                        console.log('&#9989; 语音播报开始:', message);
                    };
                    
                    utterance.onend = () => {
                        console.log('&#9989; 语音播报完成');
                    };
                    
                    utterance.onerror = (error) => {
                        console.error('&#10060; 语音播报错误:', error);
                        // 如果语音播报失败,尝试重新播放一次
                        if (!error.error || error.error !== 'interrupted') {
                            console.log('尝试重新播放语音...');
                            setTimeout(() => {
                                reminderSystem.speechSynthesis.speak(utterance);
                            }, 500);
                        }
                    };
                    
                    console.log('调用speechSynthesis.speak()');
                    reminderSystem.speechSynthesis.speak(utterance);
                    console.log('speak()调用完成');
                }, 100);
                
            } catch (error) {
                console.error('&#10060; 语音播报失败:', error);
            }
        }

        // 显示弹窗提醒
        function showPopupReminder(task, type) {
            if (!reminderSystem.popupEnabled) {
                console.log('弹窗提醒已禁用');
                return;
            }
            
            try {
                const modal = document.getElementById('reminderModal');
                if (!modal) {
                    console.error('找不到提醒模态框元素');
                    return;
                }
                
                // 如果已经有提醒在显示,先关闭
                if (reminderSystem.currentReminder) {
                    console.log('已有提醒在显示,关闭当前提醒');
                    modal.style.display = 'none';
                    // 清除之前的自动确认定时器
                    if (reminderSystem.autoConfirmTimeout) {
                        clearTimeout(reminderSystem.autoConfirmTimeout);
                        reminderSystem.autoConfirmTimeout = null;
                    }
                }
                
                const title = document.getElementById('reminderTitle');
                const subtitle = document.getElementById('reminderSubtitle');
                const taskTitle = document.getElementById('reminderTaskTitle');
                const taskTime = document.getElementById('reminderTaskTime');
                const taskNote = document.getElementById('reminderTaskNote');
                const startBtn = document.getElementById('startReminderBtn');
                const endConfirmBtn = document.getElementById('endReminderConfirmBtn');
                const endDelayBtn = document.getElementById('endReminderDelayBtn');
                
                // 验证所有必需的元素
                if (!title || !subtitle || !taskTitle || !taskTime || !taskNote || !startBtn || !endConfirmBtn || !endDelayBtn) {
                    console.error('提醒模态框元素不完整');
                    return;
                }
                
                // 设置任务信息
                taskTitle.textContent = task.title || '未命名任务';
                taskTime.textContent = task.start && task.end ? `${task.start} - ${task.end}` : '无时间设置';
                taskNote.textContent = task.note || '无备注';
                
                // 设置提醒类型
                if (type === 'start') {
                    title.textContent = '任务开始提醒';
                    subtitle.textContent = '任务时间到了,请开始执行';
                    startBtn.style.display = 'inline-block';
                    endConfirmBtn.style.display = 'none';
                    endDelayBtn.style.display = 'none';
                } else if (type === 'end') {
                    title.textContent = '任务结束提醒';
                    subtitle.textContent = '任务时间到了,您完成了任务了吗?';
                    startBtn.style.display = 'none';
                    endConfirmBtn.style.display = 'inline-block';
                    endDelayBtn.style.display = 'inline-block';
                }
                
                // 存储当前提醒的任务信息
                reminderSystem.currentReminder = { task, type, timestamp: Date.now() };
                
                // 显示模态框
                modal.style.display = 'block';
                
                // 自动聚焦到确认按钮
                setTimeout(() => {
                    try {
                        if (type === 'start' && startBtn) {
                            startBtn.focus();
                        } else if (type === 'end' && endConfirmBtn) {
                            endConfirmBtn.focus();
                        }
                    } catch (focusError) {
                        console.warn('聚焦按钮失败:', focusError);
                    }
                }, 100);
                
                // 设置30秒自动确认
                reminderSystem.autoConfirmTimeout = setTimeout(() => {
                    if (reminderSystem.currentReminder && 
                        reminderSystem.currentReminder.task.id === task.id &&
                        reminderSystem.currentReminder.type === type) {
                        
                        console.log(`30秒无操作,自动确认${type === 'start' ? '开始' : '结束'}提醒: ${task.title}`);
                        
                        if (type === 'start') {
                            confirmStartReminder();
                        } else if (type === 'end') {
                            confirmEndReminder();
                        }
                    }
                }, 30000); // 30秒后自动确认
                
                console.log(`弹窗提醒已显示: ${task.title} (${type})`);
            } catch (error) {
                console.error('显示弹窗提醒时发生错误:', error);
            }
        }

        // 确认开始提醒
        function confirmStartReminder() {
            if (reminderSystem.currentReminder) {
                const { task } = reminderSystem.currentReminder;
                showToast(`已确认开始执行任务:${task.title}`, 'success');
                document.getElementById('reminderModal').style.display = 'none';
                reminderSystem.currentReminder = null;
            }
        }

        // 确认结束提醒
        function confirmEndReminder() {
            if (reminderSystem.currentReminder) {
                const { task } = reminderSystem.currentReminder;
                // 标记任务为完成
                task.done = true;
                task.doneAt = new Date().toISOString();
                renderTasks();
                saveToLocalStorage();
                showToast(`任务已完成:${task.title}`, 'success');
                document.getElementById('reminderModal').style.display = 'none';
                reminderSystem.currentReminder = null;
            }
        }

        // 延迟结束提醒
        function delayEndReminder() {
            if (reminderSystem.currentReminder) {
                const { task } = reminderSystem.currentReminder;
                showToast(`5分钟后将再次提醒任务:${task.title}`, 'info');
                document.getElementById('reminderModal').style.display = 'none';
                
                // 5分钟后再次提醒
                const timeoutId = setTimeout(() => {
                    if (reminderSystem.enabled) {
                        // 延迟提醒不受历史记录限制
                        showTaskReminder(task, 'end');
                    }
                }, 5 * 60 * 1000);
                
                // 存储延迟提醒的超时ID
                reminderSystem.reminderTimeouts.set(`${task.id}-delay-end`, timeoutId);
                
                reminderSystem.currentReminder = null;
            }
        }
        
        // 清理过期的提醒记录
        function cleanupReminderHistory() {
            const now = new Date();
            const currentDateStr = now.toDateString();
            
            // 删除不是今天的提醒记录
            for (const [key, timestamp] of reminderSystem.reminderHistory.entries()) {
                const recordDate = new Date(timestamp).toDateString();
                if (recordDate !== currentDateStr) {
                    reminderSystem.reminderHistory.delete(key);
                }
            }
        }
        
        // 重置提醒历史记录(用于测试或手动重置)
        function resetReminderHistory() {
            reminderSystem.reminderHistory.clear();
            reminderSystem.lastCheckTime = null;
            console.log('提醒历史记录已重置');
        }

        // 显示任务提醒
        function showTaskReminder(task, type) {
            if (!reminderSystem.enabled) {
                console.log('提醒系统已禁用,跳过提醒');
                return;
            }
            
            // 验证任务数据
            if (!task || !task.id || !task.title) {
                console.error('无效的任务数据:', task);
                return;
            }
            
            // 如果任务已完成,跳过结束提醒
            if (type === 'end' && task.done) {
                console.log(`任务 ${task.title} 已完成,跳过结束提醒`);
                return;
            }
            
            // 记录实际提醒时间
            const actualTime = new Date().toLocaleTimeString('zh-CN', { hour12: false });
            console.log(`显示${type === 'start' ? '开始' : '结束'}提醒: ${task.title} (${actualTime})`);
            
            try {
                // 检查页面是否可见,决定提醒方式
                const isPageVisible = reminderSystem.isPageVisible;
                console.log(`页面可见状态: ${isPageVisible ? '可见' : '隐藏'}`);
                
                // 语音提醒和弹窗提醒同时进行(同步执行)
                // 1. 先播放语音
                if (reminderSystem.voiceEnabled) {
                    if (type === 'start') {
                        speakMessage(`${task.title}开始执行`, true); // 强制播放
                    } else if (type === 'end') {
                        speakMessage(`${task.title}任务时间到了,您完成了任务了吗?`, true); // 强制播放
                    }
                }
                
                // 2. 同时显示弹窗提醒(无论页面是否可见)
                if (reminderSystem.popupEnabled) {
                    showPopupReminder(task, type);
                }
                
                // 页面不可见时的补充处理
                if (!isPageVisible) {
                    console.log('页面不可见,使用浏览器通知作为补充提醒');
                }
                
                // 浏览器通知(页面不可见时强制使用,可见时作为补充)
                if ((reminderSystem.backgroundEnabled || !isPageVisible) && 'Notification' in window && reminderSystem.notificationPermission === 'granted') {
                    try {
                        const notificationTitle = type === 'start' ? '&#128197; 任务开始提醒' : '&#9200; 任务结束提醒';
                        const notificationBody = type === 'start' 
                            ? `${task.title} - 现在开始执行` 
                            : `${task.title} - 任务时间到了,您完成了吗?`;
                        
                        const notification = new Notification(notificationTitle, {
                            body: notificationBody,
                            icon: '/favicon.ico',
                            tag: `task-${task.id}-${type}`,
                            requireInteraction: true,
                            silent: false, // 确保有声音提示
                            badge: '/favicon.ico',
                            timestamp: Date.now(),
                            actions: type === 'end' ? [
                                { action: 'complete', title: '标记完成' },
                                { action: 'delay', title: '延迟5分钟' }
                            ] : []
                        });
                        
                        // 点击通知时的处理
                        notification.onclick = function() {
                            console.log('用户点击了通知');
                            window.focus();
                            this.close();
                            
                            // 如果页面现在可见,显示弹窗
                            if (reminderSystem.isPageVisible && reminderSystem.popupEnabled) {
                                showPopupReminder(task, type);
                            }
                        };
                        
                        // 处理通知操作
                        if ('serviceWorker' in navigator && navigator.serviceWorker.controller) {
                            navigator.serviceWorker.addEventListener('message', function(event) {
                                if (event.data.action === 'complete' && event.data.taskId === task.id) {
                                    markTaskComplete(task.id);
                                } else if (event.data.action === 'delay' && event.data.taskId === task.id) {
                                    delayEndReminder(task);
                                }
                            });
                        }
                        
                        // 自动关闭通知(如果页面变为可见)
                        const closeOnVisible = (isVisible) => {
                            if (isVisible && notification) {
                                notification.close();
                                // 移除监听器
                                const index = reminderSystem.visibilityChangeHandlers.indexOf(closeOnVisible);
                                if (index > -1) {
                                    reminderSystem.visibilityChangeHandlers.splice(index, 1);
                                }
                            }
                        };
                        reminderSystem.visibilityChangeHandlers.push(closeOnVisible);
                        
                        console.log(`发送${isPageVisible ? '补充' : '后台'}通知: ${notificationTitle}`);
                    } catch (error) {
                        console.error('浏览器通知失败:', error);
                        
                        // 如果通知失败且页面不可见,尝试其他方式
                        if (!isPageVisible) {
                            console.log('通知失败,尝试使用标题闪烁提醒');
                            flashPageTitle(task, type);
                        }
                    }
                } else if (!isPageVisible) {
                    // 如果没有通知权限但页面不可见,使用标题闪烁
                    console.log('无通知权限,使用标题闪烁提醒');
                    flashPageTitle(task, type);
                }
            } catch (error) {
                console.error('显示任务提醒时发生错误:', error);
            }
        }

        // 检查任务是否需要提醒
        function checkTaskReminders() {
            if (!reminderSystem.enabled) return;
            
            const now = new Date();
            const currentTime = now.toTimeString().slice(0, 5); // HH:MM 格式
            const currentDay = now.getDay() || 7; // 转换为1-7格式
            const currentDateStr = now.toDateString(); // 获取当前日期字符串
            const currentTimeWithSeconds = now.toTimeString().slice(0, 8); // HH:MM:SS 格式,用于精确记录
            
            // 获取当前小时和分钟
            const currentHour = now.getHours();
            const currentMinute = now.getMinutes();
            
            console.log(`检查提醒 - 当前时间: ${currentTimeWithSeconds}, 星期: ${currentDay}`);
            
            tasks.forEach(task => {
                if (task.done || !task.start || !task.end || !task.weekday) return;
                
                // 只检查今天的任务
                if (task.weekday !== currentDay) return;
                
                const taskId = task.id;
                
                // 解析任务开始时间
                const [startHour, startMin] = task.start.split(':').map(Number);
                const [endHour, endMin] = task.end.split(':').map(Number);
                
                // 检查开始时间提醒(允许1分钟内的误差)
                if (startHour === currentHour && 
                    (startMin === currentMinute || startMin === currentMinute - 1)) {
                    const reminderKey = `${taskId}-start-${currentDateStr}`;
                    
                    // 检查今天是否已经提醒过
                    if (!reminderSystem.reminderHistory.has(reminderKey)) {
                        console.log(`触发开始提醒: ${task.title} at ${currentTime}`);
                        reminderSystem.reminderHistory.set(reminderKey, now.getTime());
                        showTaskReminder(task, 'start');
                    }
                }
                
                // 检查结束时间提醒(允许1分钟内的误差)
                if (endHour === currentHour && 
                    (endMin === currentMinute || endMin === currentMinute - 1)) {
                    const reminderKey = `${taskId}-end-${currentDateStr}`;
                    
                    // 检查今天是否已经提醒过
                    if (!reminderSystem.reminderHistory.has(reminderKey)) {
                        console.log(`触发结束提醒: ${task.title} at ${currentTime}`);
                        reminderSystem.reminderHistory.set(reminderKey, now.getTime());
                        showTaskReminder(task, 'end');
                    }
                }
            });
            
            // 清理过期的提醒记录(保留今天的记录)
            cleanupReminderHistory();
        }

        // 请求通知权限
        async function requestNotificationPermission() {
            if ('Notification' in window && reminderSystem.notificationPermission === 'default') {
                try {
                    const permission = await Notification.requestPermission();
                    reminderSystem.notificationPermission = permission;
                    if (permission === 'granted') {
                        showToast('已获得通知权限,支持后台提醒', 'success');
                    }
                } catch (error) {
                    console.error('请求通知权限失败:', error);
                }
            }
        }

        // 加载提醒系统设置
        function loadReminderSettings() {
            reminderSystem.enabled = localStorage.getItem('enableTaskReminders') !== 'false';
            reminderSystem.voiceEnabled = localStorage.getItem('enableVoiceReminders') !== 'false';
            reminderSystem.popupEnabled = localStorage.getItem('enablePopupReminders') !== 'false';
            reminderSystem.backgroundEnabled = localStorage.getItem('enableBackgroundReminders') !== 'false';
            
            // 更新设置界面
            document.getElementById('enableTaskReminders').checked = reminderSystem.enabled;
            document.getElementById('enableVoiceReminders').checked = reminderSystem.voiceEnabled;
            document.getElementById('enablePopupReminders').checked = reminderSystem.popupEnabled;
            document.getElementById('enableBackgroundReminders').checked = reminderSystem.backgroundEnabled;
            
            // 更新提醒模态框中的复选框
            const reminderVoiceCheckbox = document.getElementById('reminderVoiceCheckbox');
            const reminderPopupCheckbox = document.getElementById('reminderPopupCheckbox');
            if (reminderVoiceCheckbox) {
                reminderVoiceCheckbox.checked = reminderSystem.voiceEnabled;
            }
            if (reminderPopupCheckbox) {
                reminderPopupCheckbox.checked = reminderSystem.popupEnabled;
            }
        }

        // 保存提醒系统设置
        function saveReminderSettings() {
            reminderSystem.enabled = document.getElementById('enableTaskReminders').checked;
            reminderSystem.voiceEnabled = document.getElementById('enableVoiceReminders').checked;
            reminderSystem.popupEnabled = document.getElementById('enablePopupReminders').checked;
            reminderSystem.backgroundEnabled = document.getElementById('enableBackgroundReminders').checked;
            
            localStorage.setItem('enableTaskReminders', reminderSystem.enabled);
            localStorage.setItem('enableVoiceReminders', reminderSystem.voiceEnabled);
            localStorage.setItem('enablePopupReminders', reminderSystem.popupEnabled);
            localStorage.setItem('enableBackgroundReminders', reminderSystem.backgroundEnabled);
            
            showToast('提醒设置已保存', 'success');
        }

        // 工具函数
        function generateId() {
            return Math.random().toString(36).substr(2, 9);
        }

        function showToast(message, type = 'success') {
            const toast = document.getElementById('toast');
            toast.textContent = message;
            toast.style.background = type === 'error' ? 'var(--danger-color)' : 'var(--success-color)';
            toast.classList.add('show');
            setTimeout(() => toast.classList.remove('show'), 3000);
        }

        function saveToLocalStorage(taskData = null) {
            const dataToSave = taskData || tasks;
            const weekKey = getWeekKey(currentDisplayDate);
            
            // 获取所有周的数据
            let allWeeksData = {};
            try {
                const saved = localStorage.getItem('allWeeklyTasks');
                if (saved) {
                    allWeeksData = JSON.parse(saved);
                }
            } catch (error) {
                console.error('解析多周数据失败:', error);
                allWeeksData = {};
            }
            
            // 保存当前周的数据
            allWeeksData[weekKey] = dataToSave;
            localStorage.setItem('allWeeklyTasks', JSON.stringify(allWeeksData));
            
            // 兼容旧版本:如果是本周,也保存到旧的存储位置
            if (currentWeekOffset === 0) {
                localStorage.setItem('weeklyTasks', JSON.stringify(dataToSave));
            }
            
            if (taskData === null) {
                showToast('已自动保存到本地');
            }
        }

        function loadFromLocalStorage() {
            const saved = localStorage.getItem('weeklyTasks');
            if (saved) {
                try {
                    const parsed = JSON.parse(saved);
                    tasks = Array.isArray(parsed) ? parsed : [];
                    return tasks;
                } catch (error) {
                    console.error('解析本地存储数据失败:', error);
                    tasks = [];
                    return [];
                }
            }
            tasks = [];
            return [];
        }

        function loadWeekTasks() {
            const weekKey = getWeekKey(currentDisplayDate);
            
            // 尝试从多周数据中加载
            try {
                const allWeeksData = localStorage.getItem('allWeeklyTasks');
                if (allWeeksData) {
                    const parsed = JSON.parse(allWeeksData);
                    if (parsed[weekKey]) {
                        tasks = Array.isArray(parsed[weekKey]) ? parsed[weekKey] : [];
                        return tasks;
                    }
                }
            } catch (error) {
                console.error('解析多周数据失败:', error);
            }
            
            // 如果是本周且多周数据中没有,尝试从旧版本数据加载
            if (currentWeekOffset === 0) {
                return loadFromLocalStorage();
            }
            
            // 其他周没有数据,返回空数组
            tasks = [];
            return [];
        }

        // 周导航相关函数
        function getWeekStartDate(date, weekOffset = 0) {
            const targetDate = new Date(date);
            targetDate.setDate(targetDate.getDate() + (weekOffset * 7));
            const startOfWeek = new Date(targetDate);
            startOfWeek.setDate(targetDate.getDate() - targetDate.getDay() + 1);
            return startOfWeek;
        }

        function getWeekEndDate(startDate) {
            const endDate = new Date(startDate);
            endDate.setDate(startDate.getDate() + 6);
            return endDate;
        }

        function getWeekNumber(date) {
            const start = new Date(date.getFullYear(), 0, 1);
            const days = Math.floor((date - start) / (24 * 60 * 60 * 1000));
            return Math.ceil((days + start.getDay() + 1) / 7);
        }

        function getWeekKey(date) {
            const startOfWeek = getWeekStartDate(date);
            return `${startOfWeek.getFullYear()}-W${getWeekNumber(startOfWeek)}`;
        }

        function navigateWeek(direction) {
            currentWeekOffset += direction;
            currentDisplayDate = getWeekStartDate(new Date(), currentWeekOffset);
            updateDateDisplay();
            loadWeekTasks();
            renderTasks();
        }

        function navigateToCurrentWeek() {
            currentWeekOffset = 0;
            currentDisplayDate = new Date();
            updateDateDisplay();
            loadWeekTasks();
            renderTasks();
        }

        function updateDateDisplay() {
            const now = new Date();
            const displayDate = currentWeekOffset === 0 ? now : currentDisplayDate;
            
            // 显示当前日期(如果是本周)或显示周信息
            if (currentWeekOffset === 0) {
                const options = { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long' };
                document.getElementById('currentDate').textContent = now.toLocaleDateString('zh-CN', options);
            } else {
                const startOfWeek = getWeekStartDate(new Date(), currentWeekOffset);
                const options = { year: 'numeric', month: 'long', day: 'numeric' };
                document.getElementById('currentDate').textContent = `${startOfWeek.toLocaleDateString('zh-CN', options)} 的周`;
            }
            
            const startOfWeek = getWeekStartDate(new Date(), currentWeekOffset);
            const endOfWeek = getWeekEndDate(startOfWeek);
            
            const weekNumber = getWeekNumber(startOfWeek);
            const weekPrefix = currentWeekOffset === 0 ? '第' : 
                              currentWeekOffset < 0 ? '第' : '第';
            const weekSuffix = currentWeekOffset === 0 ? '周 (本周)' : 
                              currentWeekOffset < 0 ? '周 (过去)' : '周 (未来)';
            
            document.getElementById('weekInfo').textContent = `${weekPrefix}${weekNumber}${weekSuffix} ${startOfWeek.getMonth()+1}/${startOfWeek.getDate()}-${endOfWeek.getMonth()+1}/${endOfWeek.getDate()}`;
            
            // 高亮今天(只在本周时高亮)
            const today = now.getDay() || 7;
            document.querySelectorAll('.day-header').forEach(header => {
                header.classList.remove('today');
                if (currentWeekOffset === 0 && parseInt(header.dataset.day) === today && today !== 7) {
                    header.classList.add('today');
                }
            });
        }

        // 更新任务进度条
        function updateProgressBar() {
            const totalTasks = tasks.length;
            const completedTasks = tasks.filter(task => task.done).length;
            const percentage = totalTasks > 0 ? Math.round((completedTasks / totalTasks) * 100) : 0;
            
            // 更新进度条显示
            const progressContainer = document.getElementById('progressContainer');
            if (progressContainer) {
                const totalElement = progressContainer.querySelector('.progress-total');
                const completedElement = progressContainer.querySelector('.progress-completed');
                const percentageElement = progressContainer.querySelector('.progress-percentage');
                const progressFill = progressContainer.querySelector('.progress-fill');
                
                if (totalElement) totalElement.textContent = totalTasks;
                if (completedElement) completedElement.textContent = completedTasks;
                if (percentageElement) percentageElement.textContent = `${percentage}%`;
                if (progressFill) {
                    progressFill.style.width = `${percentage}%`;
                    // 根据完成度设置颜色
                    if (percentage === 100) {
                        progressFill.style.background = 'linear-gradient(90deg, #4CAF50, #66BB6A)';
                    } else if (percentage >= 70) {
                        progressFill.style.background = 'linear-gradient(90deg, #2196F3, #42A5F5)';
                    } else if (percentage >= 30) {
                        progressFill.style.background = 'linear-gradient(90deg, #FF9800, #FFB74D)';
                    } else {
                        progressFill.style.background = 'linear-gradient(90deg, #F44336, #EF5350)';
                    }
                }
            }
        }

        function renderTasks() {
            // 清空所有任务显示
            document.querySelectorAll('.task-card').forEach(card => card.remove());
            document.querySelectorAll('#taskPool .task-card').forEach(card => card.remove());

            // 获取显示/隐藏设置
            const showMorning = localStorage.getItem('showMorning') !== 'false';
            const showAfternoon = localStorage.getItem('showAfternoon') !== 'false';
            const showEvening = localStorage.getItem('showEvening') !== 'false';

            tasks.forEach(task => {
                const taskElement = createTaskElement(task);
                
                if (task.slot === 'POOL') {
                    document.getElementById('taskPool').appendChild(taskElement);
                } else {
                    // 检查时段是否被隐藏
                    let shouldShow = true;
                    if (task.slot === '上午' && !showMorning) shouldShow = false;
                    if (task.slot === '下午' && !showAfternoon) shouldShow = false;
                    if (task.slot === '晚上' && !showEvening) shouldShow = false;
                    
                    if (shouldShow) {
                        const cell = document.querySelector(`[data-day="${task.weekday}"][data-slot="${task.slot}"]`);
                        if (cell) {
                            cell.appendChild(taskElement);
                        }
                    } else {
                        // 如果时段被隐藏,将任务移到任务池
                        task.slot = 'POOL';
                        task.weekday = null;
                        document.getElementById('taskPool').appendChild(taskElement);
                    }
                }
            });
            
            // 更新任务进度条
            updateProgressBar();
        }

        function createTaskElement(task) {
            const div = document.createElement('div');
            div.className = `task-card ${task.done ? 'done' : ''} ${getPriorityClass(task.priority)}`;
            div.draggable = true;
            div.dataset.taskId = task.id;
            
            div.innerHTML = `
                <div style="display: flex; align-items: flex-start; gap: 5px;">
                    <input type="checkbox" class="task-checkbox" ${task.done ? 'checked' : ''} 
                          >
                    <div style="flex: 1;">
                        <div class="task-title">${task.title}</div>
                        ${task.start && task.end ? `<div class="task-time">${task.start}-${task.end}</div>` : ''}
                        ${task.note ? `<div class="task-note">${task.note}</div>` : ''}
                    </div>
                </div>
                <div class="task-actions">
                    <button class="delete-btn">×</button>
                </div>
            `;

            div.addEventListener('dragstart', (e) => {
                draggedTask = task;
                e.dataTransfer.effectAllowed = 'move';
                setTimeout(() => div.classList.add('dragging'), 0);
            });

            div.addEventListener('dragend', () => {
                div.classList.remove('dragging');
                draggedTask = null;
            });

            // 添加触摸拖拽支持
            let touchStartX, touchStartY, isDragging = false, touchTarget = null;
            
            div.addEventListener('touchstart', (e) => {
                if (e.target.classList.contains('task-checkbox') || e.target.classList.contains('delete-btn')) {
                    return;
                }
                touchStartX = e.touches[0].clientX;
                touchStartY = e.touches[0].clientY;
                isDragging = false;
                touchTarget = null;
            }, { passive: false });
            
            div.addEventListener('touchmove', (e) => {
                if (e.target.classList.contains('task-checkbox') || e.target.classList.contains('delete-btn')) {
                    return;
                }
                e.preventDefault();
                
                const touch = e.touches[0];
                const deltaX = Math.abs(touch.clientX - touchStartX);
                const deltaY = Math.abs(touch.clientY - touchStartY);
                
                if (!isDragging && (deltaX > 10 || deltaY > 10)) {
                    isDragging = true;
                    draggedTask = task;
                    div.classList.add('dragging');
                    div.style.position = 'fixed';
                    div.style.zIndex = '1000';
                    div.style.pointerEvents = 'none';
                    div.style.opacity = '0.8';
                }
                
                if (isDragging) {
                    div.style.left = (touch.clientX - 50) + 'px';
                    div.style.top = (touch.clientY - 25) + 'px';
                    
                    // 查找触摸点下的目标元素
                    const elementBelow = document.elementFromPoint(touch.clientX, touch.clientY);
                    if (elementBelow) {
                        const taskCell = elementBelow.closest('.task-cell');
                        if (taskCell && taskCell !== touchTarget) {
                            if (touchTarget) {
                                touchTarget.classList.remove('drag-over');
                            }
                            touchTarget = taskCell;
                            taskCell.classList.add('drag-over');
                        } else if (!taskCell && touchTarget) {
                            touchTarget.classList.remove('drag-over');
                            touchTarget = null;
                        }
                    }
                }
            }, { passive: false });
            
            div.addEventListener('touchend', (e) => {
                if (isDragging) {
                    e.preventDefault();
                    
                    // 重置样式
                    div.style.position = '';
                    div.style.zIndex = '';
                    div.style.pointerEvents = '';
                    div.style.opacity = '';
                    div.style.left = '';
                    div.style.top = '';
                    div.classList.remove('dragging');
                    
                    if (touchTarget) {
                        touchTarget.classList.remove('drag-over');
                        
                        // 执行拖放操作
                        const fakeEvent = {
                            preventDefault: () => {},
                            dataTransfer: {
                                getData: () => task.id
                            }
                        };
                        drop(fakeEvent, 'grid', touchTarget);
                        touchTarget = null;
                    }
                    
                    draggedTask = null;
                    isDragging = false;
                } else if (!isDragging) {
                    // 如果没有拖拽,则处理点击事件
                    if (!e.target.classList.contains('task-checkbox') && !e.target.classList.contains('delete-btn')) {
                        console.log('点击任务,准备编辑:', task);
                        editTask(task);
                    }
                }
            }, { passive: false });

            // 确保任务卡片可点击(桌面端)
            div.style.cursor = 'pointer';
            div.addEventListener('click', (e) => {
                if (isDragging) return; // 如果正在拖拽,忽略点击
                e.stopPropagation();
                if (!e.target.classList.contains('task-checkbox') && !e.target.classList.contains('delete-btn')) {
                    console.log('点击任务,准备编辑:', task);
                    editTask(task);
                }
            });

            return div;
        }

        function getPriorityClass(priority) {
            switch (priority) {
                case 1: return 'high-priority';
                case 2: return 'medium-priority';
                case 3: return 'low-priority';
                default: return '';
            }
        }

        function allowDrop(ev) {
            ev.preventDefault();
        }

        function drop(ev, targetType, targetElement = null) {
            ev.preventDefault();
            
            if (!draggedTask) return;

            if (targetType === 'pool') {
                // 拖到任务池,只更新位置,不清除原任务
                draggedTask.slot = 'POOL';
                draggedTask.weekday = null;
            } else {
                const cell = targetElement || ev.target.closest('.task-cell');
                if (cell) {
                    if (draggedTask.slot === 'POOL') {
                        // 从任务池拖到网格,创建副本
                        const newTask = {
                            ...draggedTask,
                            id: generateId(),
                            weekday: parseInt(cell.dataset.day),
                            slot: cell.dataset.slot,
                            order: Date.now()
                        };
                        tasks.push(newTask);
                    } else {
                        // 网格间移动,直接更新位置
                        draggedTask.weekday = parseInt(cell.dataset.day);
                        draggedTask.slot = cell.dataset.slot;
                    }
                }
            }

            renderTasks();
            saveToLocalStorage();
        }

        function addTask(day, slot) {
            currentEditingTask = null;
            document.getElementById('modalTitle').textContent = '添加任务';
            document.getElementById('taskForm').reset();
            
            // 设置默认时间
            if (slot) {
                const morningRange = localStorage.getItem('morningRange') || '08:00-12:00';
                const afternoonRange = localStorage.getItem('afternoonRange') || '13:00-18:00';
                const eveningRange = localStorage.getItem('eveningRange') || '19:00-23:00';
                
                let startTime, endTime;
                if (slot === 'AM') {
                    const times = morningRange.split('-');
                    startTime = times[0];
                    endTime = times[1];
                } else if (slot === 'PM') {
                    const times = afternoonRange.split('-');
                    startTime = times[0];
                    endTime = times[1];
                } else if (slot === 'EVENING') {
                    const times = eveningRange.split('-');
                    startTime = times[0];
                    endTime = times[1];
                }
                
                if (startTime && endTime) {
                    document.getElementById('taskStart').value = startTime;
                    document.getElementById('taskEnd').value = endTime;
                }
            }

            // 设置默认优先级
            selectPriority(2);

            // 清除所有星期选择状态
                document.querySelectorAll('.weekday-btn[data-day="1"], .weekday-btn[data-day="2"], .weekday-btn[data-day="3"], .weekday-btn[data-day="4"], .weekday-btn[data-day="5"], .weekday-btn[data-day="6"], .weekday-btn[data-day="7"], .weekday-btn[data-day="all"]').forEach(btn => {
                    btn.classList.remove('active');
                });
                
            // 设置默认星期几
            if (day) {
                // 如果指定了具体星期,选中对应的星期
                const weekdayBtn = document.querySelector(`.weekday-btn[data-day="${day}"]`);
                if (weekdayBtn) {
                    weekdayBtn.classList.add('active');
                }
            } else {
                // 如果没有指定星期(从顶部按钮添加任务),自动选择当前星期几
                const today = new Date();
                const currentDay = today.getDay(); // 0是周日,1-6是周一到周六
                const dayToSelect = currentDay === 0 ? 7 : currentDay; // 转换为1-7的格式
                
                const weekdayBtn = document.querySelector(`.weekday-btn[data-day="${dayToSelect}"]`);
                if (weekdayBtn) {
                    weekdayBtn.classList.add('active');
                }
            }

            document.getElementById('taskModal').style.display = 'block';
            
            // 存储临时位置信息
            window.tempTaskLocation = { day, slot };
        }

        function addTaskToPool() {
            // 获取当前时间
            const now = new Date();
            const currentHour = now.getHours();
            const currentMinute = now.getMinutes();
            const currentTime = currentHour * 60 + currentMinute; // 转换为分钟数便于比较
            
            // 获取时间段设置
            const morningRange = localStorage.getItem('morningRange') || '08:00-12:00';
            const afternoonRange = localStorage.getItem('afternoonRange') || '13:00-18:00';
            const eveningRange = localStorage.getItem('eveningRange') || '19:00-23:00';
            
            // 解析时间范围
            function parseTimeRange(range) {
                const [start, end] = range.split('-');
                const [startHour, startMin] = start.split(':').map(Number);
                const [endHour, endMin] = end.split(':').map(Number);
                return {
                    start: startHour * 60 + startMin,
                    end: endHour * 60 + endMin
                };
            }
            
            const morning = parseTimeRange(morningRange);
            const afternoon = parseTimeRange(afternoonRange);
            const evening = parseTimeRange(eveningRange);
            
            // 判断当前时间属于哪个时间段
            let targetSlot = null;
            
            if (currentTime >= morning.start && currentTime <= morning.end) {
                targetSlot = 'AM';
            } else if (currentTime >= afternoon.start && currentTime <= afternoon.end) {
                targetSlot = 'PM';
            } else if (currentTime >= evening.start && currentTime <= evening.end) {
                targetSlot = 'EVENING';
            } else {
                // 如果不在任何时间段内,根据最接近的时间段来判断
                const distanceToMorning = Math.min(
                    Math.abs(currentTime - morning.start),
                    Math.abs(currentTime - morning.end)
                );
                const distanceToAfternoon = Math.min(
                    Math.abs(currentTime - afternoon.start),
                    Math.abs(currentTime - afternoon.end)
                );
                const distanceToEvening = Math.min(
                    Math.abs(currentTime - evening.start),
                    Math.abs(currentTime - evening.end)
                );
                
                const minDistance = Math.min(distanceToMorning, distanceToAfternoon, distanceToEvening);
                
                if (minDistance === distanceToMorning) {
                    targetSlot = 'AM';
                } else if (minDistance === distanceToAfternoon) {
                    targetSlot = 'PM';
                } else {
                    targetSlot = 'EVENING';
                }
            }
            
            // 获取当前星期几(如果是本周)或默认选择周一(如果是其他周)
            let dayToSelect;
            if (currentWeekOffset === 0) {
                // 本周:使用实际的当前星期几
                const today = new Date();
                const currentDay = today.getDay(); // 0是周日,1-6是周一到周六
                dayToSelect = currentDay === 0 ? 7 : currentDay; // 转换为1-7的格式
            } else {
                // 其他周:默认选择周一
                dayToSelect = 1;
            }
            
            // 调用addTask函数,传入选择的星期几和自动判断的时间段
            addTask(dayToSelect, targetSlot);
        }

        function editTask(task) {
            console.log('开始编辑任务:', task);
            if (!task) {
                console.error('任务对象为空');
                return;
            }
            currentEditingTask = task;
            document.getElementById('modalTitle').textContent = '编辑任务';
            document.getElementById('taskTitle').value = task.title;
            document.getElementById('taskStart').value = task.start || '';
            document.getElementById('taskEnd').value = task.end || '';
            document.getElementById('taskNote').value = task.note || '';
            selectPriority(task.priority || 2);
            
            // 重置星期选择
            document.querySelectorAll('.weekday-btn[data-day="1"], .weekday-btn[data-day="2"], .weekday-btn[data-day="3"], .weekday-btn[data-day="4"], .weekday-btn[data-day="5"], .weekday-btn[data-day="6"], .weekday-btn[data-day="7"], .weekday-btn[data-day="all"]').forEach(btn => {
                btn.classList.remove('active');
            });
            
            // 如果任务有星期信息,选中对应的星期
            if (task.weekday) {
                const weekdayBtn = document.querySelector(`.weekday-btn[data-day="${task.weekday}"]`);
                if (weekdayBtn) {
                    weekdayBtn.classList.add('active');
                }
            }
            
            console.log('打开模态框');
            const modal = document.getElementById('taskModal');
            modal.style.display = 'block';
            modal.style.zIndex = '10000'; // 确保模态框在最上层
            
            // 确保模态框可见
            setTimeout(() => {
                modal.style.opacity = '1';
            }, 10);
        }

        // 根据时间判断应该属于哪个时段
        function determineSlotByTime(startTime) {
            if (!startTime) return 'AM'; // 默认上午
            
            // 获取时间段设置
            const morningRange = localStorage.getItem('morningRange') || '08:00-12:00';
            const afternoonRange = localStorage.getItem('afternoonRange') || '13:00-18:00';
            const eveningRange = localStorage.getItem('eveningRange') || '19:00-23:00';
            
            // 解析时间范围
            function parseTimeRange(range) {
                const [start, end] = range.split('-');
                const [startHour, startMin] = start.split(':').map(Number);
                const [endHour, endMin] = end.split(':').map(Number);
                return {
                    start: startHour * 60 + startMin,
                    end: endHour * 60 + endMin
                };
            }
            
            const [startHour, startMin] = startTime.split(':').map(Number);
            const startMinutes = startHour * 60 + startMin;
            
            const morning = parseTimeRange(morningRange);
            const afternoon = parseTimeRange(afternoonRange);
            const evening = parseTimeRange(eveningRange);
            
            // 根据开始时间判断时段
            if (startMinutes >= morning.start && startMinutes <= morning.end) {
                return 'AM';
            } else if (startMinutes >= afternoon.start && startMinutes <= afternoon.end) {
                return 'PM';
            } else if (startMinutes >= evening.start && startMinutes <= evening.end) {
                return 'EVENING';
            } else {
                // 如果不在任何时间段内,根据最接近的时间段来判断
                const distanceToMorning = Math.min(
                    Math.abs(startMinutes - morning.start),
                    Math.abs(startMinutes - morning.end)
                );
                const distanceToAfternoon = Math.min(
                    Math.abs(startMinutes - afternoon.start),
                    Math.abs(startMinutes - afternoon.end)
                );
                const distanceToEvening = Math.min(
                    Math.abs(startMinutes - evening.start),
                    Math.abs(startMinutes - evening.end)
                );
                
                const minDistance = Math.min(distanceToMorning, distanceToAfternoon, distanceToEvening);
                
                if (minDistance === distanceToMorning) {
                    return 'AM';
                } else if (minDistance === distanceToAfternoon) {
                    return 'PM';
                } else {
                    return 'EVENING';
                }
            }
        }

        function saveTask(event) {
            event.preventDefault();
            
            const title = document.getElementById('taskTitle').value.trim();
            if (!title) {
                showToast('请输入任务标题', 'error');
                return;
            }
            
            const start = document.getElementById('taskStart').value;
            const end = document.getElementById('taskEnd').value;
            const note = document.getElementById('taskNote').value;
            const priority = parseInt(document.querySelector('.priority-btn.active').dataset.priority);
            
            if (currentEditingTask) {
                // 编辑现有任务 - 根据新的时间重新判断时段
                currentEditingTask.title = title;
                currentEditingTask.start = start;
                currentEditingTask.end = end;
                currentEditingTask.note = note;
                currentEditingTask.priority = priority;
                
                // 如果任务有具体的星期,根据时间重新判断时段
                if (currentEditingTask.weekday) {
                    currentEditingTask.slot = determineSlotByTime(start);
                }
            } else {
                // 创建新任务 - 支持多星期选择
                const location = window.tempTaskLocation;
                const selectedWeekdays = getSelectedWeekdays();
                
                // 根据用户选择的时间自动判断时段
                const determinedSlot = determineSlotByTime(start);
                
                if (selectedWeekdays.length > 0) {
                    // 选择了具体星期,为每个选中的星期创建任务
                    selectedWeekdays.forEach(weekday => {
                        const newTask = {
                            id: generateId(),
                            title,
                            start,
                            end,
                            note,
                            priority,
                            done: false,
                            doneAt: null,
                            weekday: weekday,
                            slot: determinedSlot,
                            order: Date.now()
                        };
                        tasks.push(newTask);
                    });
                } else {
                    // 没有选择星期,根据位置信息创建任务
                    if (location && location.day) {
                        // 有明确位置信息,但时段根据时间自动判断
                        const newTask = {
                            id: generateId(),
                            title,
                            start,
                            end,
                            note,
                            priority,
                            done: false,
                            doneAt: null,
                            weekday: location.day,
                            slot: determinedSlot,
                            order: Date.now()
                        };
                        tasks.push(newTask);
                    } else {
                        // 没有位置信息(比如从任务池添加),放到任务池
                        const newTask = {
                            id: generateId(),
                            title,
                            start,
                            end,
                            note,
                            priority,
                            done: false,
                            doneAt: null,
                            weekday: null,
                            slot: 'POOL',
                            order: Date.now()
                        };
                        tasks.push(newTask);
                    }
                }
            }

            renderTasks();
            saveToLocalStorage();
            closeModal();
            showToast('任务保存成功', 'success');
        }

        function toggleTask(taskId) {
            const task = tasks.find(t => t.id === taskId);
            if (task) {
                task.done = !task.done;
                task.doneAt = task.done ? new Date().toISOString() : null;
                renderTasks();
                saveToLocalStorage();
            }
        }

        let taskToDelete = null;

        function deleteTask(taskId) {
            taskToDelete = taskId;
            document.getElementById('deleteConfirmModal').style.display = 'block';
        }

        function closeDeleteConfirmModal() {
            document.getElementById('deleteConfirmModal').style.display = 'none';
            taskToDelete = null;
        }

        function confirmDeleteTask() {
            if (taskToDelete) {
                tasks = tasks.filter(t => t.id !== taskToDelete);
                renderTasks();
                saveToLocalStorage();
                showToast('任务已删除');
                closeDeleteConfirmModal();
            }
        }

        function selectPriority(priority) {
            document.querySelectorAll('.priority-btn').forEach(btn => {
                btn.classList.remove('active');
            });
            document.querySelector(`[data-priority="${priority}"]`).classList.add('active');
        }



        function toggleWeekday(day) {
            const btn = document.querySelector(`.weekday-btn[data-day="${day}"]`);
            btn.classList.toggle('active');
        }

        function toggleAllWeekdays() {
            const allBtn = document.querySelector('.weekday-btn[data-day="all"]');
            const isAllSelected = allBtn.classList.contains('active');
            
            if (isAllSelected) {
                // 取消全选
                allBtn.classList.remove('active');
                document.querySelectorAll('.weekday-btn[data-day="1"], .weekday-btn[data-day="2"], .weekday-btn[data-day="3"], .weekday-btn[data-day="4"], .weekday-btn[data-day="5"], .weekday-btn[data-day="6"], .weekday-btn[data-day="7"]').forEach(btn => {
                    btn.classList.remove('active');
                });
            } else {
                // 全选
                allBtn.classList.add('active');
                document.querySelectorAll('.weekday-btn[data-day="1"], .weekday-btn[data-day="2"], .weekday-btn[data-day="3"], .weekday-btn[data-day="4"], .weekday-btn[data-day="5"], .weekday-btn[data-day="6"], .weekday-btn[data-day="7"]').forEach(btn => {
                    btn.classList.add('active');
                });
            }
        }

        function getSelectedWeekdays() {
            const selectedBtns = document.querySelectorAll('.weekday-btn[data-day="1"].active, .weekday-btn[data-day="2"].active, .weekday-btn[data-day="3"].active, .weekday-btn[data-day="4"].active, .weekday-btn[data-day="5"].active, .weekday-btn[data-day="6"].active, .weekday-btn[data-day="7"].active');
            return Array.from(selectedBtns).map(btn => parseInt(btn.dataset.day));
        }

        function closeModal() {
            document.getElementById('taskModal').style.display = 'none';
            currentEditingTask = null;
            window.tempTaskLocation = null;
            
            // 重置星期选择
            document.querySelectorAll('.weekday-btn').forEach(btn => {
                btn.classList.remove('active');
            });
        }

        // 删除loadSampleData函数
        // 该函数已被移除,不再提供示例数据功能

        // 添加测试任务用于验证编辑功能


        function clearWeek() {
            if (confirm('确定要清空本周所有任务吗?')) {
                tasks = tasks.filter(task => task.slot === 'POOL');
                renderTasks();
                saveToLocalStorage();
                showToast('已清空本周任务');
            }
        }

        function loadSampleData() {
            // 示例数据功能已移除
            showToast('示例数据功能已移除');
        }



        // Excel导入导出功能
        function exportToExcel() {
            // 获取所有周的数据 - 修复数据获取逻辑
            let allWeeksData = {};
            try {
                const saved = localStorage.getItem('allWeeklyTasks');
                if (saved) {
                    allWeeksData = JSON.parse(saved);
                }
            } catch (error) {
                console.error('解析多周数据失败:', error);
                allWeeksData = {};
            }
            
            // 修复:确保当前周数据总是被包含
            const currentWeekTasks = loadFromLocalStorage() || [];
            const currentWeekKey = getWeekKey(new Date());
            
            // 合并当前周数据到总数据中
            if (currentWeekTasks.length > 0 || !allWeeksData[currentWeekKey]) {
                allWeeksData[currentWeekKey] = currentWeekTasks;
            }
            
            // 扩展CSV格式定义,包含周标识
            const CSV_HEADERS = ['周标识', '星期', '时段', '任务标题', '开始时间', '结束时间', '优先级', '是否完成', '备注', '重复类型', '选定星期', '任务ID'];
            
            // 映射表 - 统一标准
            const WEEKDAY_MAP = {
                1: '周一', 2: '周二', 3: '周三', 4: '周四', 5: '周五', 6: '周六', 7: '周日',
                null: '任务池'
            };
            const SLOT_MAP = {
                'AM': '上午', 'PM': '下午', 'EVENING': '晚上', 'POOL': '任务池'
            };
            const PRIORITY_MAP = {
                1: '高', 2: '中', 3: '低'
            };
            const REPEAT_TYPE_MAP = {
                'once': '单次', 'daily': '每天', 'weekly': '每周'
            };
            
            // 构建CSV数据
            const csvData = [CSV_HEADERS];
            let totalTasks = 0;
            
            // 遍历所有周的数据
            Object.keys(allWeeksData).sort().forEach(weekKey => {
                const weekTasks = allWeeksData[weekKey];
                if (!Array.isArray(weekTasks)) return;
                
                // 过滤有效任务
                const validTasks = weekTasks.filter(task => 
                    task && 
                    typeof task === 'object' &&
                    task.title && task.title.trim() !== ''
                );
                
                // 转换任务数据
                validTasks.forEach(task => {
                    // 处理选定星期
                    let selectedWeekdaysText = '';
                    if (task.selectedWeekdays && Array.isArray(task.selectedWeekdays) && task.selectedWeekdays.length > 0) {
                        selectedWeekdaysText = task.selectedWeekdays.map(day => WEEKDAY_MAP[day] || day).join(',');
                    }
                    
                    csvData.push([
                        weekKey, // 周标识
                        WEEKDAY_MAP[task.weekday] || '任务池',
                        SLOT_MAP[task.slot] || '任务池',
                        task.title || '',
                        task.start || '',
                        task.end || '',
                        PRIORITY_MAP[task.priority] || '中',
                        task.done ? '是' : '否',
                        task.note || '',
                        REPEAT_TYPE_MAP[task.repeatType] || '单次',
                        selectedWeekdaysText,
                        task.id || ''
                    ]);
                    totalTasks++;
                });
            });
            
            // 修复:总是允许导出,即使是空数据也提供模板
            if (totalTasks === 0) {
                // 添加空模板行以便导入测试
                csvData.push([
                    currentWeekKey,
                    '周一',
                    '上午',
                    '示例任务',
                    '09:00',
                    '10:00',
                    '中',
                    '否',
                    '这是一个示例任务',
                    '单次',
                    '',
                    'sample_task_id'
                ]);
                totalTasks = 1;
            }
            
            // 生成CSV内容
            const csvContent = csvData.map(row => 
                row.map(cell => {
                    const str = String(cell || '');
                    // 处理需要引号的字段
                    if (str.includes(',') || str.includes('"') || str.includes('\n') || str.includes('\r')) {
                        return '"' + str.replace(/"/g, '""') + '"';
                    }
                    return str;
                }).join(',')
            ).join('\r\n');
            
            // 创建并下载文件 - 添加UTF-8 BOM以确保Office兼容性
            const blob = new Blob(['\uFEFF' + csvContent], { 
                type: 'text/csv;charset=utf-8;'
            });
            
            const link = document.createElement('a');
            link.href = URL.createObjectURL(blob);
            
            // 生成文件名
            const now = new Date();
            const dateStr = now.toISOString().split('T')[0];
            const weekCount = Object.keys(allWeeksData).length;
            link.download = `全部任务备份_${weekCount}周_${dateStr}.csv`;
            link.style.display = 'none';
            
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            
            showToast(`成功导出${totalTasks}个任务(${weekCount}周数据)到CSV文件`);
        }

        function showImportModal() {
            document.getElementById('importModal').style.display = 'block';
            document.getElementById('importPreview').style.display = 'none';
        }

        function closeImportModal() {
            document.getElementById('importModal').style.display = 'none';
            importedData = null;
        }

        function handleFileSelect(event) {
            const file = event.target.files[0];
            if (file) {
                // 显示文件信息
                document.getElementById('fileInfo').style.display = 'block';
                document.getElementById('fileName').textContent = file.name;
                document.getElementById('fileSize').textContent = formatFileSize(file.size);
                
                parseExcelFile(file);
            }
        }

        function clearFile() {
            document.getElementById('fileInput').value = '';
            document.getElementById('fileInfo').style.display = 'none';
            document.getElementById('importPreview').style.display = 'none';
            importedData = null;
        }

        function formatFileSize(bytes) {
            if (bytes === 0) return '0 Bytes';
            const k = 1024;
            const sizes = ['Bytes', 'KB', 'MB', 'GB'];
            const i = Math.floor(Math.log(bytes) / Math.log(k));
            return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
        }

        // 统一CSV解析函数
        function parseCSVLine(line) {
            const cells = [];
            let current = '';
            let inQuotes = false;
            let i = 0;
            
            while (i < line.length) {
                const char = line[i];
                
                if (char === '"') {
                    if (inQuotes && line[i + 1] === '"') {
                        current += '"';
                        i += 2;
                    } else {
                        inQuotes = !inQuotes;
                        i++;
                    }
                } else if (char === ',' && !inQuotes) {
                    cells.push(current);
                    current = '';
                    i++;
                } else {
                    current += char;
                    i++;
                }
            }
            
            cells.push(current);
            return cells;
        }

        function parseExcelFile(file) {
            const reader = new FileReader();
            reader.onload = function(e) {
                let text = e.target.result;
                
                // 处理编码问题 - 自动检测和修复
                try {
                    // 检测BOM标记
                    if (text.charCodeAt(0) === 0xFEFF || text.charCodeAt(0) === 0xFFFE) {
                        text = text.slice(1);
                    }
                    
                    // 检测乱码并尝试修复
                    if (/[&#65533;&#65533;&#65533;&#65533;]/.test(text) || /\x00/.test(text)) {
                        console.warn('检测到编码问题,尝试重新读取...');
                        // 这里可以添加GBK解码逻辑,但浏览器原生不支持
                        // 提示用户使用UTF-8编码的文件
                        showToast('文件编码可能有问题,请确保使用UTF-8编码保存CSV文件', 'warning');
                    }
                } catch (encodingError) {
                    console.warn('编码处理失败:', encodingError);
                }
                
                const lines = text.replace(/\r\n/g, '\n').split('\n');
                const newTasks = [];
                
                // 增强的星期映射表 - 支持多种格式
                const WEEKDAY_MAP = {
                    // 中文格式
                    '周一': 1, '周二': 2, '周三': 3, '周四': 4, '周五': 5, '周六': 6, '周日': 7,
                    '星期一': 1, '星期二': 2, '星期三': 3, '星期四': 4, '星期五': 5, '星期六': 6, '星期日': 7,
                    '礼拜一': 1, '礼拜二': 2, '礼拜三': 3, '礼拜四': 4, '礼拜五': 5, '礼拜六': 6, '礼拜天': 7,
                    // 数字格式
                    '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7,
                    // 英文格式
                    'monday': 1, 'tuesday': 2, 'wednesday': 3, 'thursday': 4, 'friday': 5, 'saturday': 6, 'sunday': 7,
                    'mon': 1, 'tue': 2, 'wed': 3, 'thu': 4, 'fri': 5, 'sat': 6, 'sun': 7,
                    // 特殊处理
                    '任务池': null, 'pool': null
                };
                
                // 增强的时段映射
                const SLOT_MAP = {
                    '上午': 'AM', '下午': 'PM', '晚上': 'EVENING', '任务池': 'POOL',
                    'AM': 'AM', 'PM': 'PM', 'EVENING': 'EVENING', 'POOL': 'POOL',
                    'am': 'AM', 'pm': 'PM', 'evening': 'EVENING',
                    'morning': 'AM', 'afternoon': 'PM', 'night': 'EVENING',
                    '早': 'AM', '午': 'PM', '晚': 'EVENING'
                };
                
                // 优先级映射
                const PRIORITY_MAP = {
                    '高': 1, '中': 2, '低': 3,
                    'high': 1, 'medium': 2, 'low': 3,
                    '1': 1, '2': 2, '3': 3,
                    '紧急': 1, '一般': 2, '普通': 3
                };
                
                // 完成状态映射
                const COMPLETION_MAP = {
                    '是': true, '否': false,
                    'true': true, 'false': false,
                    '1': true, '0': false,
                    'yes': true, 'no': false,
                    '已完成': true, '未完成': false,
                    '完成': true, '未完成': false
                };
                
                const REPEAT_TYPE_MAP = {
                    '单次': 'once', '每天': 'daily', '每周': 'weekly',
                    'once': 'once', 'daily': 'daily', 'weekly': 'weekly',
                    '一次': 'once', '每日': 'daily', '每周': 'weekly'
                };
                
                // 智能检测数据起始行
                let dataStartRow = 1;
                let headerFound = false;
                
                for (let i = 0; i < Math.min(10, lines.length); i++) {
                    const line = lines[i].trim();
                    if (!line) continue;
                    
                    const lowerLine = line.toLowerCase();
                    if (lowerLine.includes('星期') || lowerLine.includes('weekday') || 
                        lowerLine.includes('星期') || lowerLine.includes('标题')) {
                        dataStartRow = i + 1;
                        headerFound = true;
                        break;
                    }
                }
                
                // 处理数据行
                for (let i = dataStartRow; i < lines.length; i++) {
                    const line = lines[i].trim();
                    if (!line || line === '' || line.match(/^,+$/)) continue;
                    
                    try {
                        // 解析CSV行
                        const cells = parseCSVLine(line);
                        if (!cells || cells.length < 7) {
                            console.warn(`跳过第 ${i + 1} 行: 列数不足`);
                            continue;
                        }
                        
                        // 清理数据 - 更智能的清理
                        const cleanCells = cells.map(cell => 
                            cell.trim().replace(/^"|"$/g, '').replace(/""/g, '"')
                        ).filter(cell => cell !== '');
                        
                        if (cleanCells.length < 3) {
                            console.warn(`跳过第 ${i + 1} 行: 数据列数不足`);
                            continue;
                        }
                        
                        // 智能字段提取 - 支持灵活的列顺序,包括周标识
                        let weekIdentifier = '';
                        let weekdayText = '周一';
                        let slotText = '上午';
                        let title = '';
                        let start = '';
                        let end = '';
                        let priorityText = '中';
                        let completionText = '否';
                        let note = '';
                        
                        // 智能字段解析 - 根据列数确定格式
                        if (cleanCells.length >= 9) {
                            // 9列格式:周标识,星期,时段,标题,开始,结束,优先级,完成,备注
                            weekIdentifier = cleanCells[0] || '';
                            weekdayText = cleanCells[1] || '周一';
                            slotText = cleanCells[2] || '上午';
                            title = cleanCells[3] || '';
                            start = cleanCells[4] || '';
                            end = cleanCells[5] || '';
                            priorityText = cleanCells[6] || '中';
                            completionText = cleanCells[7] || '否';
                            note = cleanCells[8] || '';
                        } else if (cleanCells.length >= 8) {
                            // 8列格式:星期,时段,标题,开始,结束,优先级,完成,备注
                            weekdayText = cleanCells[0] || '周一';
                            slotText = cleanCells[1] || '上午';
                            title = cleanCells[2] || '';
                            start = cleanCells[3] || '';
                            end = cleanCells[4] || '';
                            priorityText = cleanCells[5] || '中';
                            completionText = cleanCells[6] || '否';
                            note = cleanCells[7] || '';
                        } else if (cleanCells.length >= 7) {
                            // 7列格式:星期,时段,标题,开始,结束,优先级,完成
                            weekdayText = cleanCells[0] || '周一';
                            slotText = cleanCells[1] || '上午';
                            title = cleanCells[2] || '';
                            start = cleanCells[3] || '';
                            end = cleanCells[4] || '';
                            priorityText = cleanCells[5] || '中';
                            completionText = cleanCells[6] || '否';
                        } else if (cleanCells.length >= 6) {
                            // 6列格式:星期,时段,标题,开始,结束,优先级
                            weekdayText = cleanCells[0] || '周一';
                            slotText = cleanCells[1] || '上午';
                            title = cleanCells[2] || '';
                            start = cleanCells[3] || '';
                            end = cleanCells[4] || '';
                            priorityText = cleanCells[5] || '中';
                        } else if (cleanCells.length >= 5) {
                            // 5列格式:星期,时段,标题,开始,结束
                            weekdayText = cleanCells[0] || '周一';
                            slotText = cleanCells[1] || '上午';
                            title = cleanCells[2] || '';
                            start = cleanCells[3] || '';
                            end = cleanCells[4] || '';
                        } else if (cleanCells.length >= 3) {
                            // 3列最小格式:星期,时段,标题
                            weekdayText = cleanCells[0] || '周一';
                            slotText = cleanCells[1] || '上午';
                            title = cleanCells[2] || '';
                        } else {
                            console.warn(`跳过第 ${i + 1} 行: 列数不足 (${cleanCells.length} < 3)`);
                            continue;
                        }
                        
                        // 修复:允许空标题的任务,跳过真正的无效数据
                        if (title === '标题' || title.toLowerCase() === 'title' || title === '任务标题') {
                            continue;
                        }
                        
                        // 智能星期映射
                        let weekday = 1;
                        const weekdayKey = weekdayText.toString().trim();
                        
                        if (WEEKDAY_MAP[weekdayKey] !== undefined) {
                            weekday = WEEKDAY_MAP[weekdayKey];
                        } else {
                            // 尝试数字转换
                            const numWeekday = parseInt(weekdayKey);
                            if (!isNaN(numWeekday) && numWeekday >= 1 && numWeekday <= 7) {
                                weekday = numWeekday;
                            } else {
                                console.warn(`无法识别的星期: ${weekdayKey}, 默认设为周一`);
                            }
                        }
                        
                        // 智能时段映射
                        const slotKey = slotText.toString().trim();
                        const slot = SLOT_MAP[slotKey] || 'AM';
                        
                        // 创建任务对象
                        const task = {
                            id: generateId(),
                            title: title.trim(),
                            start: start.trim(),
                            end: end.trim(),
                            priority: PRIORITY_MAP[priorityText.toString().toLowerCase()] || 2,
                            done: COMPLETION_MAP[completionText.toString().toLowerCase()] || false,
                            note: note.trim(),
                            weekday: weekday,
                            slot: slot,
                            order: Date.now() + i * 1000,
                            repeatType: 'once',
                            selectedWeekdays: [],
                            doneAt: null,
                            weekIdentifier: weekIdentifier.trim() // 添加周标识
                        };
                        
                        newTasks.push(task);
                        
                    } catch (error) {
                        console.warn(`解析第 ${i + 1} 行失败:`, error.message);
                    }
                }
                
                if (newTasks.length > 0) {
                    importedData = newTasks;
                    document.getElementById('taskCount').textContent = newTasks.length;
                    
                    // 显示预览
                    const previewList = document.getElementById('previewList');
                    if (previewList) {
                        const slots = { AM: '上午', PM: '下午', EVENING: '晚上', POOL: '任务池' };
                        const weekdays = ['', '周一', '周二', '周三', '周四', '周五', '周六', '周日'];
                        const priorityColors = { 1: '#ff5252', 2: '#ffa726', 3: '#66bb6a' };
                        const repeatTypes = { 'once': '单次', 'daily': '每天', 'weekly': '每周' };
                        
                        previewList.innerHTML = newTasks.slice(0, 10).map(task => 
                            `<div style="padding: 15px; border-bottom: 1px solid var(--border-color); display: flex; align-items: center; gap: 12px; transition: background-color 0.2s;">
                                <div style="width: 4px; height: 40px; border-radius: 2px; background: ${priorityColors[task.priority]}; flex-shrink: 0;"></div>
                                <div style="flex: 1;">
                                    <div style="font-weight: 600; color: var(--text-color); margin-bottom: 4px;">${task.title}</div>
                                    <div style="font-size: 13px; color: var(--text-light);">
                                        ${task.weekday ? weekdays[task.weekday] : '任务池'} &#8226; 
                                        ${slots[task.slot] || '未知时段'} &#8226; 
                                        ${task.start} - ${task.end} &#8226; 
                                        ${repeatTypes[task.repeatType] || '单次'}
                                    </div>
                                </div>
                                <div style="font-size: 12px; color: ${priorityColors[task.priority]}; font-weight: 500;">
                                    ${task.priority === 1 ? '高' : task.priority === 2 ? '中' : '低'}优先级
                                </div>
                            </div>`
                        ).join('');
                        
                        if (newTasks.length > 10) {
                            previewList.innerHTML += `
                                <div style="padding: 20px; text-align: center; color: var(--text-light); font-size: 14px;">
                                    &#128202; 还有 <strong style="color: var(--primary-color);">${newTasks.length - 10}</strong> 个任务未显示
                                </div>`;
                        }
                    }
                    
                    document.getElementById('importPreview').style.display = 'block';
                    document.getElementById('confirmImportBtn').disabled = false;
                } else {
                    showToast('未找到有效任务数据,请检查CSV格式', 'error');
                }
            };
            
            reader.onerror = function() {
                showToast('文件读取失败,请重试', 'error');
            };
            
            reader.readAsText(file, 'UTF-8');
        }

        function confirmImport() {
            if (!importedData || !Array.isArray(importedData) || importedData.length === 0) {
                showToast('没有可导入的数据', 'error');
                return;
            }
            
            // 保存导入数据到本地变量,防止被清空
            const currentImportData = [...importedData];
            
            try {
                // 获取现有的多周数据
                let allWeeklyTasks = {};
                try {
                    allWeeklyTasks = JSON.parse(localStorage.getItem('allWeeklyTasks') || '{}');
                } catch (e) {
                    console.warn('解析现有数据失败,使用空对象', e);
                    allWeeklyTasks = {};
                }
                
                // 按周标识分组导入的任务
                const tasksByWeek = {};
                let tasksWithoutWeekId = [];
                
                // 处理导入的任务,确保数据完整性并去重
                const processedTasks = [];
                const duplicateCheck = new Set();
                
                // 获取当前所有任务用于去重检查
                let allExistingTasks = [];
                Object.values(allWeeklyTasks).forEach(weekTasks => {
                    allExistingTasks = allExistingTasks.concat(weekTasks);
                });
                
                currentImportData.forEach(task => {
                    const processedTask = {
                        id: task.id || generateId(),
                        title: task.title || '',
                        start: task.start || '',
                        end: task.end || '',
                        priority: task.priority || 2,
                        done: task.done || false,
                        note: task.note || '',
                        weekday: task.weekday,
                        slot: task.slot || 'AM',
                        order: task.order || Date.now(),
                        repeatType: task.repeatType || 'once',
                        selectedWeekdays: task.selectedWeekdays || [],
                        doneAt: task.doneAt || null,
                        weekIdentifier: task.weekIdentifier || ''
                    };
                    
                    // 如果是重复任务且在任务池中,确保正确设置
                    if (processedTask.repeatType !== 'once' && (!processedTask.weekday || processedTask.slot === 'POOL')) {
                        processedTask.weekday = null;
                        processedTask.slot = 'POOL';
                    }
                    
                    // 创建去重key:星期+时段+标题(去除空格和大小写)
                    const duplicateKey = `${processedTask.weekday}_${processedTask.slot}_${processedTask.title.trim().toLowerCase()}`;
                    
                    // 检查是否已存在相同任务(包括导入中和现有任务)
                    const isExisting = allExistingTasks.some(existingTask => 
                        existingTask.weekday === processedTask.weekday &&
                        existingTask.slot === processedTask.slot &&
                        existingTask.title.trim().toLowerCase() === processedTask.title.trim().toLowerCase()
                    );
                    
                    if (!duplicateCheck.has(duplicateKey) && !isExisting) {
                        duplicateCheck.add(duplicateKey);
                        processedTasks.push(processedTask);
                    } else {
                        console.log('跳过重复任务:', processedTask.title);
                    }
                });
                
                // 按周标识分组任务
                processedTasks.forEach(task => {
                    if (task.weekIdentifier && task.weekIdentifier.trim()) {
                        const weekId = task.weekIdentifier.trim();
                        if (!tasksByWeek[weekId]) {
                            tasksByWeek[weekId] = [];
                        }
                        // 移除weekIdentifier属性,因为它只用于导入时分组
                        const { weekIdentifier, ...taskWithoutWeekId } = task;
                        tasksByWeek[weekId].push(taskWithoutWeekId);
                    } else {
                        // 没有周标识的任务,添加到当前周
                        const { weekIdentifier, ...taskWithoutWeekId } = task;
                        tasksWithoutWeekId.push(taskWithoutWeekId);
                    }
                });
                
                let totalNewTasks = 0;
                let totalSkippedTasks = 0;
                
                // 将按周分组的任务合并到对应周
                Object.keys(tasksByWeek).forEach(weekId => {
                    const weekTasks = tasksByWeek[weekId];
                    const existingWeekTasks = allWeeklyTasks[weekId] || [];
                    const existingIds = new Set(existingWeekTasks.map(task => task.id));
                    const newWeekTasks = weekTasks.filter(task => !existingIds.has(task.id));
                    
                    allWeeklyTasks[weekId] = [...existingWeekTasks, ...newWeekTasks];
                    totalNewTasks += newWeekTasks.length;
                    totalSkippedTasks += weekTasks.length - newWeekTasks.length;
                });
                
                // 处理没有周标识的任务,添加到当前周
                if (tasksWithoutWeekId.length > 0) {
                    const currentWeekId = getWeekKey(currentDisplayDate);
                    const existingCurrentWeekTasks = allWeeklyTasks[currentWeekId] || [];
                    const existingIds = new Set(existingCurrentWeekTasks.map(task => task.id));
                    const newCurrentWeekTasks = tasksWithoutWeekId.filter(task => !existingIds.has(task.id));
                    
                    allWeeklyTasks[currentWeekId] = [...existingCurrentWeekTasks, ...newCurrentWeekTasks];
                    totalNewTasks += newCurrentWeekTasks.length;
                    totalSkippedTasks += tasksWithoutWeekId.length - newCurrentWeekTasks.length;
                }
                
                // 保存多周数据
                localStorage.setItem('allWeeklyTasks', JSON.stringify(allWeeklyTasks));
                
                // 更新当前周的任务显示
                const currentWeekId = getWeekKey(currentDisplayDate);
                tasks = allWeeklyTasks[currentWeekId] || [];
                saveToLocalStorage(tasks);
                closeImportModal();
                
                // 显示成功通知 - 确保使用正确的变量名
                const totalImported = processedTasks.length;
                const totalDuplicates = currentImportData.length - processedTasks.length;
                const successToast = document.createElement('div');
                successToast.style.cssText = `
                    position: fixed;
                    top: 20px;
                    right: 20px;
                    background: linear-gradient(135deg, #4caf50, #45a049);
                    color: white;
                    padding: 20px 30px;
                    border-radius: 12px;
                    box-shadow: 0 8px 32px rgba(76, 175, 80, 0.3);
                    font-size: 16px;
                    font-weight: 500;
                    z-index: 10000;
                    animation: slideIn 0.3s ease-out;
                `;
                successToast.innerHTML = `
                    <div style="display: flex; align-items: center; gap: 12px;">
                        <span class="icon icon-check" style="width: 24px; height: 24px; display: inline-block;"></span>
                        <div>
                            <div style="font-weight: 600;">导入成功!</div>
                            <div style="font-size: 14px; opacity: 0.9;">
                                ${totalImported > 0 ? `成功导入 ${totalImported} 个任务` : '没有新任务需要导入'}
                                ${totalDuplicates > 0 ? `<br>跳过 ${totalDuplicates} 个重复任务` : ''}
                            </div>
                        </div>
                    </div>
                `;
                
                document.body.appendChild(successToast);
                setTimeout(() => {
                    successToast.style.animation = 'slideOut 0.3s ease-in';
                    setTimeout(() => successToast.remove(), 300);
                }, 3000);
                
                renderTasks();
                
                // 清空导入数据
                importedData = null;
                
            } catch (error) {
                console.error('导入失败:', error);
                showToast('导入失败:' + (error.message || '未知错误'), 'error');
                return; // 防止继续执行
            }
        }

        function showSettingsModal() {
            document.getElementById('settingsModal').style.display = 'block';
            loadSettings();
        }

        function closeSettingsModal() {
            document.getElementById('settingsModal').style.display = 'none';
        }

        function setTheme(theme) {
            document.documentElement.setAttribute('data-theme', theme);
            localStorage.setItem('theme', theme);
            
            // 更新主题按钮状态
            document.querySelectorAll('.theme-btn').forEach(function(btn) {
                btn.classList.remove('active');
            });
            if (event && event.target) {
                event.target.classList.add('active');
            }
        }

        function loadSettings() {
            const savedTheme = localStorage.getItem('theme') || 'light';
            document.documentElement.setAttribute('data-theme', savedTheme);
            
            // 高亮当前主题按钮
            const themeBtns = document.querySelectorAll('.theme-btn');
            if (savedTheme === 'light' && themeBtns[0]) themeBtns[0].classList.add('active');
            if (savedTheme === 'dark' && themeBtns[1]) themeBtns[1].classList.add('active');
            if (savedTheme === 'green' && themeBtns[2]) themeBtns[2].classList.add('active');
            
            // 加载时段设置
            const morningRange = localStorage.getItem('morningRange') || '08:00-12:00';
            const afternoonRange = localStorage.getItem('afternoonRange') || '13:00-18:00';
            const eveningRange = localStorage.getItem('eveningRange') || '19:00-23:00';
            
            // 加载显示/隐藏设置 - 上午和下午为必选
            const showMorning = true; // 上午时段必选
            const showAfternoon = true; // 下午时段必选
            const showEvening = localStorage.getItem('showEvening') !== 'false';
            const showTimeRange = localStorage.getItem('showTimeRange') !== 'false';
            
            // 加载周末显示设置
            const hideSaturday = localStorage.getItem('hideSaturday') === 'true';
            const hideSunday = localStorage.getItem('hideSunday') === 'true';
            
            // 解析并设置上午时段
            const morningTimes = morningRange.split('-');
            if (morningTimes.length === 2) {
                document.getElementById('morningStart').value = morningTimes[0];
                document.getElementById('morningEnd').value = morningTimes[1];
            }
            
            // 解析并设置下午时段
            const afternoonTimes = afternoonRange.split('-');
            if (afternoonTimes.length === 2) {
                document.getElementById('afternoonStart').value = afternoonTimes[0];
                document.getElementById('afternoonEnd').value = afternoonTimes[1];
            }
            
            // 解析并设置晚上时段
            const eveningTimes = eveningRange.split('-');
            if (eveningTimes.length === 2) {
                document.getElementById('eveningStart').value = eveningTimes[0];
                document.getElementById('eveningEnd').value = eveningTimes[1];
            }
            
            // 设置显示/隐藏复选框 - 上午和下午强制选中
            document.getElementById('showMorning').checked = true;
            document.getElementById('showAfternoon').checked = true;
            document.getElementById('showEvening').checked = showEvening;
            document.getElementById('showTimeRange').checked = showTimeRange;
            
            // 设置周末显示复选框
            document.getElementById('hideSaturday').checked = hideSaturday;
            document.getElementById('hideSunday').checked = hideSunday;
            
            // 应用周末显示设置
            toggleWeekendDisplay();
            
            // 加载提醒系统设置
            loadReminderSettings();
        }

        function updateTimeLabels() {
            const morningRange = localStorage.getItem('morningRange') || '08:00-12:00';
            const afternoonRange = localStorage.getItem('afternoonRange') || '13:00-18:00';
            const eveningRange = localStorage.getItem('eveningRange') || '19:00-23:00';
            
            const showMorning = localStorage.getItem('showMorning') !== 'false';
            const showAfternoon = localStorage.getItem('showAfternoon') !== 'false';
            const showEvening = localStorage.getItem('showEvening') !== 'false';
            const showTimeRange = localStorage.getItem('showTimeRange') !== 'false';
            
            const timeLabels = document.querySelectorAll('.time-label');
            const weeklyGrid = document.querySelector('.weekly-grid');
            
            // 更新上午时段
            if (timeLabels[0]) {
                timeLabels[0].style.display = showMorning ? '' : 'none';
                const desktopText = timeLabels[0].querySelector('.desktop-text');
                if (desktopText) {
                    desktopText.innerHTML = showTimeRange ? `上午<br>${morningRange}` : '上午';
                }
                
                // 隐藏对应的任务单元格
                const morningCells = document.querySelectorAll('[data-slot="AM"]');
                morningCells.forEach(cell => {
                    cell.style.display = showMorning ? '' : 'none';
                });
            }
            
            // 更新下午时段
            if (timeLabels[1]) {
                timeLabels[1].style.display = showAfternoon ? '' : 'none';
                const desktopText = timeLabels[1].querySelector('.desktop-text');
                if (desktopText) {
                    desktopText.innerHTML = showTimeRange ? `下午<br>${afternoonRange}` : '下午';
                }
                
                // 隐藏对应的任务单元格
                const afternoonCells = document.querySelectorAll('[data-slot="PM"]');
                afternoonCells.forEach(cell => {
                    cell.style.display = showAfternoon ? '' : 'none';
                });
            }
            
            // 更新晚上时段
            if (timeLabels[2]) {
                if (window.innerWidth <= 480) {
                    // 手机端:使用强制的display:none确保兼容性
                    // 晚上列相关元素:表头data-day="3" + 所有data-slot="EVENING"的任务单元格
                    const eveningColumn = [
                        document.querySelector('.day-header[data-day="3"]'),
                        ...document.querySelectorAll('[data-slot="EVENING"]')
                    ];
                    
                    eveningColumn.forEach(element => {
                        if (element) {
                            if (showEvening) {
                                element.classList.remove('mobile-hidden');
                                element.style.display = '';
                            } else {
                                element.classList.add('mobile-hidden');
                                element.style.display = 'none !important';
                            }
                        }
                    });
                } else {
                    // 桌面端:保持原有逻辑
                    timeLabels[2].style.display = showEvening ? '' : 'none';
                    const eveningCells = document.querySelectorAll('[data-slot="EVENING"]');
                    eveningCells.forEach(cell => {
                        cell.style.display = showEvening ? '' : 'none';
                    });
                }
                
                const desktopText = timeLabels[2].querySelector('.desktop-text');
                if (desktopText) {
                    desktopText.innerHTML = showTimeRange ? `晚上<br>${eveningRange}` : '晚上';
                }
            }
            
            // 动态调整网格模板(桌面端和手机端)
            if (window.innerWidth <= 480) {
                // 手机端:添加CSS类控制网格布局
                const weeklyGrid = document.querySelector('.weekly-grid');
                if (weeklyGrid) {
                    weeklyGrid.classList.remove('evening-hidden', 'evening-visible');
                    weeklyGrid.classList.add(showEvening ? 'evening-visible' : 'evening-hidden');
                    
                    // 强制重新渲染网格布局
                    weeklyGrid.style.display = 'none';
                    weeklyGrid.offsetHeight; // 触发重排
                    weeklyGrid.style.display = 'grid';
                }
                
                // 手机端:重新调用toggleWeekendDisplay来更新完整的网格布局
                toggleWeekendDisplay();
            } else {
                // 桌面端:只调整行模板
                if (showEvening) {
                    // 显示晚上时段:标题行 + 三个时段行
                    weeklyGrid.style.gridTemplateRows = 'auto 1fr 1fr 1fr';
                } else {
                    // 隐藏晚上时段:标题行 + 两个时段行(平分空间)
                    weeklyGrid.style.gridTemplateRows = 'auto 1fr 1fr';
                }
            }
            
            // 更新手机端时间范围显示
            updateMobileTimeRanges(morningRange, afternoonRange, eveningRange, showTimeRange);
        }

        function updateMobileTimeRanges(morningRange, afternoonRange, eveningRange, showTimeRange) {
            // 更新手机端时间范围显示
            const mobileTimeRangeAM = document.getElementById('mobileTimeRangeAM');
            const mobileTimeRangePM = document.getElementById('mobileTimeRangePM');
            const mobileTimeRangeEVENING = document.getElementById('mobileTimeRangeEVENING');
            
            if (mobileTimeRangeAM) {
                mobileTimeRangeAM.textContent = morningRange;
                mobileTimeRangeAM.style.display = showTimeRange ? 'block' : 'none';
            }
            
            if (mobileTimeRangePM) {
                mobileTimeRangePM.textContent = afternoonRange;
                mobileTimeRangePM.style.display = showTimeRange ? 'block' : 'none';
            }
            
            if (mobileTimeRangeEVENING) {
                mobileTimeRangeEVENING.textContent = eveningRange;
                mobileTimeRangeEVENING.style.display = showTimeRange ? 'block' : 'none';
            }
        }

        function repositionMobileTimeLabels(hideSaturday, hideSunday) {
            // 在新的移动端布局中,时间标签已经通过CSS正确定位
            // 这个函数现在主要用于处理隐藏逻辑,CSS已经处理了基本定位
            // 移动端布局:8行(标题+周一到周日)x 4列(时间+上午+下午+晚上)
        }

        function repositionMobileElements(hideSaturday, hideSunday, showEvening) {
            // 只在手机端执行
            if (window.innerWidth > 480) return;
            
            // 创建可见天数的映射
            const dayMapping = [];
            for (let day = 1; day <= 7; day++) {
                if (day === 6 && hideSaturday) continue;
                if (day === 7 && hideSunday) continue;
                dayMapping.push(day);
            }
            
            // 重新定位可见元素的网格位置
            dayMapping.forEach((day, index) => {
                const actualRow = index + 2; // +2 因为第一行是表头
                
                // 设置时间标签位置(只对没有hidden类的元素设置)
                const timeLabel = document.querySelector(`.time-label[data-mobile-day="${day}"]`);
                if (timeLabel && !timeLabel.classList.contains('hidden')) {
                    timeLabel.style.gridRow = `${actualRow}`;
                }
                
                // 设置任务单元格位置(只对没有hidden类的元素设置)
                const amCell = document.querySelector(`.task-cell[data-day="${day}"][data-slot="AM"]`);
                if (amCell && !amCell.classList.contains('hidden')) {
                    amCell.style.gridColumn = '2';
                    amCell.style.gridRow = `${actualRow}`;
                }
                
                const pmCell = document.querySelector(`.task-cell[data-day="${day}"][data-slot="PM"]`);
                if (pmCell && !pmCell.classList.contains('hidden')) {
                    pmCell.style.gridColumn = '3';
                    pmCell.style.gridRow = `${actualRow}`;
                }
                
                const eveningCell = document.querySelector(`.task-cell[data-day="${day}"][data-slot="EVENING"]`);
                if (eveningCell && !eveningCell.classList.contains('hidden')) {
                    if (showEvening) {
                        eveningCell.style.gridColumn = '4';
                        eveningCell.style.gridRow = `${actualRow}`;
                        eveningCell.style.display = '';
                    } else {
                        // 当晚上时段隐藏时,确保晚上单元格不显示
                        eveningCell.style.display = 'none';
                    }
                }
            });
        }
        
        function toggleWeekendDisplay() {
            const hideSaturday = localStorage.getItem('hideSaturday') === 'true';
            const hideSunday = localStorage.getItem('hideSunday') === 'true';
            const weeklyGrid = document.querySelector('.weekly-grid');
            
            if (window.innerWidth <= 480) {
                // 手机端:参考PC端逻辑,使用统一的hidden类
                // 周六相关元素:任务单元格和手机端时间标签
                const saturdayElements = [
                    ...document.querySelectorAll('.task-cell[data-day="6"]'),
                    ...document.querySelectorAll('.time-label[data-mobile-day="6"]')
                ];
                
                // 周日相关元素:任务单元格和手机端时间标签
                const sundayElements = [
                    ...document.querySelectorAll('.task-cell[data-day="7"]'),
                    ...document.querySelectorAll('.time-label[data-mobile-day="7"]')
                ];
                
                // 控制周六的显示/隐藏
                saturdayElements.forEach(element => {
                    if (hideSaturday) {
                        element.classList.add('hidden');
                    } else {
                        element.classList.remove('hidden');
                    }
                });
                
                // 控制周日的显示/隐藏
                sundayElements.forEach(element => {
                    if (hideSunday) {
                        element.classList.add('hidden');
                    } else {
                        element.classList.remove('hidden');
                    }
                });
            } else {
                // 桌面端:保持原有逻辑
                const saturdayElements = document.querySelectorAll('[data-day="6"]');
                const sundayElements = document.querySelectorAll('[data-day="7"]');
                
                saturdayElements.forEach(element => {
                    if (hideSaturday) {
                        element.classList.add('hidden');
                    } else {
                        element.classList.remove('hidden');
                    }
                });
                
                sundayElements.forEach(element => {
                    if (hideSunday) {
                        element.classList.add('hidden');
                    } else {
                        element.classList.remove('hidden');
                    }
                });
            }
            
            // 动态调整网格模板
            if (window.innerWidth <= 480) {
                // 手机端:调整行数和列数
                let visibleDays = 7;
                if (hideSaturday) visibleDays--;
                if (hideSunday) visibleDays--;
                
                // 检查晚上时段是否隐藏(从localStorage读取)
                const showEvening = localStorage.getItem('showEvening') !== 'false';
                let visibleTimeSlots = showEvening ? 3 : 2; // 上午、下午、晚上
                
                // 添加CSS类来控制网格布局 - 增强浏览器兼容性
                weeklyGrid.classList.remove('evening-hidden', 'evening-visible');
                weeklyGrid.classList.add(showEvening ? 'evening-visible' : 'evening-hidden');
                
                // 手机端网格:动态列数和行数
                const columnTemplate = showEvening ? '45px 1fr 1fr 1fr' : '45px 1fr 1fr';
                weeklyGrid.style.gridTemplateColumns = columnTemplate;
                weeklyGrid.style.gridTemplateRows = `auto repeat(${visibleDays}, 1fr)`;
                
                // 强制重新渲染网格布局
                weeklyGrid.style.display = 'none';
                weeklyGrid.offsetHeight; // 触发重排
                weeklyGrid.style.display = 'grid';
                
                console.log('手机端网格调整:', {
                    showEvening,
                    columnTemplate,
                    visibleDays,
                    gridClass: showEvening ? 'evening-visible' : 'evening-hidden'
                });
                
                // 动态设置元素的网格位置
                repositionMobileElements(hideSaturday, hideSunday, showEvening);
                
                // 确保网格高度适应内容
                const headerHeight = 160;
                const availableHeight = window.innerHeight - headerHeight;
                weeklyGrid.style.height = `${Math.max(400, availableHeight)}px`;
                weeklyGrid.style.maxHeight = `${availableHeight}px`;
            } else {
                // 桌面端:调整列数
                let visibleDays = 7;
                if (hideSaturday) visibleDays--;
                if (hideSunday) visibleDays--;
                
                // 根据屏幕尺寸设置不同的第一列宽度
                let firstColumnWidth = '150px';
                if (window.innerWidth <= 768) {
                    firstColumnWidth = '80px';
                }
                
                // 设置新的网格模板
                weeklyGrid.style.gridTemplateColumns = `${firstColumnWidth} repeat(${visibleDays}, 1fr)`;
            }
        }

        function saveSettings() {
            // 保存时段设置
            const morningStart = document.getElementById('morningStart').value;
            const morningEnd = document.getElementById('morningEnd').value;
            const afternoonStart = document.getElementById('afternoonStart').value;
            const afternoonEnd = document.getElementById('afternoonEnd').value;
            const eveningStart = document.getElementById('eveningStart').value;
            const eveningEnd = document.getElementById('eveningEnd').value;
            
            const morningRange = `${morningStart}-${morningEnd}`;
            const afternoonRange = `${afternoonStart}-${afternoonEnd}`;
            const eveningRange = `${eveningStart}-${eveningEnd}`;
            
            localStorage.setItem('morningRange', morningRange);
            localStorage.setItem('afternoonRange', afternoonRange);
            localStorage.setItem('eveningRange', eveningRange);
            
            // 保存显示/隐藏设置 - 上午和下午强制为true
            localStorage.setItem('showMorning', true);
            localStorage.setItem('showAfternoon', true);
            localStorage.setItem('showEvening', document.getElementById('showEvening').checked);
            localStorage.setItem('showTimeRange', document.getElementById('showTimeRange').checked);
            
            // 保存周末显示设置
            localStorage.setItem('hideSaturday', document.getElementById('hideSaturday').checked);
            localStorage.setItem('hideSunday', document.getElementById('hideSunday').checked);
            
            // 应用周末显示设置
            toggleWeekendDisplay();
            
            // 更新时段标签显示和时段可见性
            updateTimeLabels();
            renderTasks();
            
            // 保存提醒系统设置
            saveReminderSettings();
            
            showToast('设置已保存');
            closeSettingsModal();
        }

        // 标题编辑功能
        function editTitle() {
            const titleElement = document.getElementById('tableTitle');
            const inputElement = document.getElementById('tableTitleInput');
            
            titleElement.style.display = 'none';
            inputElement.style.display = 'inline-block';
            inputElement.value = titleElement.textContent;
            inputElement.focus();
            inputElement.select();
        }

        function saveTitle() {
            const titleElement = document.getElementById('tableTitle');
            const inputElement = document.getElementById('tableTitleInput');
            
            const newTitle = inputElement.value.trim();
            if (newTitle) {
                titleElement.textContent = newTitle;
                // 保存到localStorage
                localStorage.setItem('tableTitle', newTitle);
            }
            
            titleElement.style.display = 'inline-block';
            inputElement.style.display = 'none';
        }

        function handleTitleKeypress(event) {
            if (event.key === 'Enter') {
                saveTitle();
            } else if (event.key === 'Escape') {
                const titleElement = document.getElementById('tableTitle');
                const inputElement = document.getElementById('tableTitleInput');
                
                titleElement.style.display = 'inline-block';
                inputElement.style.display = 'none';
            }
        }

        function loadTableTitle() {
            const savedTitle = localStorage.getItem('tableTitle');
            if (savedTitle) {
                document.getElementById('tableTitle').textContent = savedTitle;
            }
        }

        // 键盘快捷键
        // 移除不存在的dropZone事件监听器
        // 这些事件监听器引用了不存在的dropZone元素
        
        // 键盘快捷键
        document.addEventListener('keydown', (e) => {
            if (e.ctrlKey) {
                switch (e.key) {
                    case 'n':
                        e.preventDefault();
                        addTaskToPool();
                        break;
                    case 's':
                        e.preventDefault();
                        saveToLocalStorage();
                        break;
                    case 'e':
                        e.preventDefault();
                        exportToExcel();
                        break;
                }
            }
        });



        // 全局错误处理
        window.addEventListener('error', function(e) {
            console.error('JavaScript错误:', e.error);
            console.error('错误信息:', e.message);
            console.error('错误位置:', e.filename, '行', e.lineno);
        });

        // 窗口大小变化时重新调整布局
        window.addEventListener('resize', () => {
            toggleWeekendDisplay();
        });

        // 初始化
        document.addEventListener('DOMContentLoaded', () => {
            updateDateDisplay();
            loadWeekTasks(); // 使用新的多周数据加载函数
            loadSettings();
            loadTableTitle(); // 加载保存的标题
            
            // 初始化手机端网格布局CSS类
            if (window.innerWidth <= 480) {
                const weeklyGrid = document.querySelector('.weekly-grid');
                const showEvening = localStorage.getItem('showEvening') !== 'false';
                if (weeklyGrid) {
                    weeklyGrid.classList.remove('evening-hidden', 'evening-visible');
                    weeklyGrid.classList.add(showEvening ? 'evening-visible' : 'evening-hidden');
                }
            }
            
            toggleWeekendDisplay(); // 应用周末显示设置
            updateTimeLabels();
            renderTasks(); // 添加任务渲染,确保页面加载时显示任务
            
            // 初始化任务提醒系统
            initSpeechSynthesis();
            initPageVisibility(); // 初始化页面可见性API
            requestNotificationPermission();
            
            // 注册Service Worker
            if ('serviceWorker' in navigator) {
                navigator.serviceWorker.register('/sw.js')
                    .then(registration => {
                        console.log('Service Worker注册成功:', registration);
                    })
                    .catch(error => {
                        console.log('Service Worker注册失败:', error);
                    });
            }
            
            // 添加提醒模态框复选框的事件监听器
            const reminderVoiceCheckbox = document.getElementById('reminderVoiceCheckbox');
            const reminderPopupCheckbox = document.getElementById('reminderPopupCheckbox');
            if (reminderVoiceCheckbox) {
                reminderVoiceCheckbox.addEventListener('change', function() {
                    reminderSystem.voiceEnabled = this.checked;
                    localStorage.setItem('enableVoiceReminders', this.checked);
                });
            }
            if (reminderPopupCheckbox) {
                reminderPopupCheckbox.addEventListener('change', function() {
                    reminderSystem.popupEnabled = this.checked;
                    localStorage.setItem('enablePopupReminders', this.checked);
                });
            }
            
            // 初始化提醒系统设置
            loadReminderSettings();
            
            // 添加用户交互监听器以启用语音播报(绕过自动播放限制)
            let userInteracted = false;
            const enableVoiceOnInteraction = () => {
                if (!userInteracted) {
                    userInteracted = true;
                    console.log('用户已交互,语音播报已启用');
                    // 移除监听器
                    document.removeEventListener('click', enableVoiceOnInteraction);
                    document.removeEventListener('keydown', enableVoiceOnInteraction);
                    document.removeEventListener('touchstart', enableVoiceOnInteraction);
                }
            };
            document.addEventListener('click', enableVoiceOnInteraction);
            document.addEventListener('keydown', enableVoiceOnInteraction);
            document.addEventListener('touchstart', enableVoiceOnInteraction);
            
            // 启动提醒检查定时器(每10秒检查一次,提高精度)
            setInterval(checkTaskReminders, 10000);
            
            // 每分钟更新日期显示
            setInterval(updateDateDisplay, 60000);
            
            // 延迟执行初始检查,确保所有组件都已初始化
            setTimeout(() => {
                console.log('=== 系统初始化完成 ===');
                console.log('页面加载完成,任务数量:', tasks.length);
                console.log('任务列表:', tasks);
                console.log('提醒系统状态:', {
                    enabled: reminderSystem.enabled,
                    voice: reminderSystem.voiceEnabled,
                    popup: reminderSystem.popupEnabled,
                    background: reminderSystem.backgroundEnabled
                });
                
                // 立即执行一次提醒检查,确保不遗漏当前时间的提醒
                if (reminderSystem.enabled) {
                    console.log('执行初始提醒检查');
                    checkTaskReminders();
                }
                
                console.log('任务提醒系统已启动(检查频率:每10秒)');
            }, 500); // 减少延迟到500ms,更快响应
        });

        // 导出功能相关函数
        let selectedExportDay = null;

        // 切换导出下拉菜单
        function toggleExportDropdown() {
            const dropdown = document.getElementById('exportDropdown');
            const toggle = document.querySelector('.export-dropdown .dropdown-toggle');
            
            if (dropdown.classList.contains('show')) {
                dropdown.classList.remove('show');
                toggle.classList.remove('active');
            } else {
                dropdown.classList.add('show');
                toggle.classList.add('active');
            }
        }

        function toggleBackupDropdown() {
            const dropdown = document.getElementById('backupDropdown');
            const toggle = document.querySelector('.backup-dropdown .dropdown-toggle');
            
            if (dropdown.classList.contains('show')) {
                dropdown.classList.remove('show');
                toggle.classList.remove('active');
            } else {
                dropdown.classList.add('show');
                toggle.classList.add('active');
            }
        }

        // 显示日报导出模态框
        function showDailyExportModal() {
            const modal = document.getElementById('dailyExportModal');
            modal.style.display = 'block';
            
            // 清除之前的选择
            modal.querySelectorAll('.export-day-btn').forEach(btn => {
                btn.classList.remove('selected');
            });
            
            // 自动选择当天对应的星期几
            const today = new Date();
            const currentDay = today.getDay(); // 0是周日,1-6是周一到周六
            const dayToSelect = currentDay === 0 ? 7 : currentDay; // 转换为1-7的格式
            
            // 自动选择当天
            selectedExportDay = dayToSelect;
            const selectedBtn = modal.querySelector(`.export-day-btn[data-day="${dayToSelect}"]`);
            if (selectedBtn) {
                selectedBtn.classList.add('selected');
            }
            
            // 启用导出按钮
            document.getElementById('exportDailyBtn').disabled = false;
            
            // 关闭下拉菜单
            document.getElementById('exportDropdown').classList.remove('show');
            document.querySelector('.dropdown-toggle').classList.remove('active');
        }

        // 关闭日报导出模态框
        function closeDailyExportModal() {
            document.getElementById('dailyExportModal').style.display = 'none';
            selectedExportDay = null;
        }

        // 选择导出日期
        function selectExportDay(day) {
            selectedExportDay = day;
            
            // 更新按钮状态
            const modal = document.getElementById('dailyExportModal');
            modal.querySelectorAll('.export-day-btn').forEach(btn => {
                btn.classList.remove('selected');
            });
            const selectedBtn = modal.querySelector(`.export-day-btn[data-day="${day}"]`);
            if (selectedBtn) {
                selectedBtn.classList.add('selected');
            }
            
            // 启用导出按钮
            document.getElementById('exportDailyBtn').disabled = false;
        }

        // 导出日报
        function exportDailyReport() {
            if (!selectedExportDay) {
                showToast('请先选择要导出的日期', 'error');
                return;
            }

            // 获取当前周的任务数据
            const tasks = loadWeekTasks() || [];
            const dayNames = ['', '周一', '周二', '周三', '周四', '周五', '周六', '周日'];
            const slotNames = { 'AM': '上午', 'PM': '下午', 'EVENING': '晚上' };
            const priorityNames = { 1: '高', 2: '中', 3: '低' };

            // 筛选选定日期的任务
            const dayTasks = tasks.filter(task => task.weekday === selectedExportDay);

            if (dayTasks.length === 0) {
                showToast(`${dayNames[selectedExportDay]}没有任务数据`, 'error');
                return;
            }

            // 创建工作簿
            const wb = XLSX.utils.book_new();
            
            // 准备数据
            const wsData = [
                ['时段', '任务标题', '开始时间', '结束时间', '优先级', '完成状态', '备注']
            ];

            // 按时段分组并排序
            const timeSlots = ['AM', 'PM', 'EVENING'];
            timeSlots.forEach(slot => {
                const slotTasks = dayTasks.filter(task => task.slot === slot)
                    .sort((a, b) => (a.start || '').localeCompare(b.start || ''));
                
                if (slotTasks.length > 0) {
                    slotTasks.forEach(task => {
                        wsData.push([
                            slotNames[task.slot] || task.slot,
                            task.title || '',
                            task.start || '',
                            task.end || '',
                            priorityNames[task.priority] || '中',
                            task.done ? '已完成' : '未完成',
                            task.note || ''
                        ]);
                    });
                }
            });

            // 创建工作表
            const ws = XLSX.utils.aoa_to_sheet(wsData);
            
            // 设置列宽
            ws['!cols'] = [
                { wch: 10 }, // 时段
                { wch: 30 }, // 任务标题
                { wch: 12 }, // 开始时间
                { wch: 12 }, // 结束时间
                { wch: 10 }, // 优先级
                { wch: 12 }, // 完成状态
                { wch: 25 }  // 备注
            ];

            // 添加工作表到工作簿
            XLSX.utils.book_append_sheet(wb, ws, `${dayNames[selectedExportDay]}日报`);

            // 生成文件名
            const today = new Date();
            const fileName = `${dayNames[selectedExportDay]}日报_${today.getFullYear()}年${(today.getMonth()+1).toString().padStart(2,'0')}月${today.getDate().toString().padStart(2,'0')}日.xlsx`;

            // 导出文件
            XLSX.writeFile(wb, fileName);
            
            showToast(`成功导出${dayNames[selectedExportDay]}日报,共${dayTasks.length}个任务`);
            closeDailyExportModal();
        }

        // 导出周报
        function exportWeeklyReport() {
            // 获取当前周的任务数据
            const tasks = loadWeekTasks() || [];
            const dayNames = ['', '周一', '周二', '周三', '周四', '周五', '周六', '周日'];
            const slotNames = { 'AM': '上午', 'PM': '下午', 'EVENING': '晚上' };
            const priorityNames = { 1: '高', 2: '中', 3: '低' };

            // 筛选有效任务(排除任务池)
            const weekTasks = tasks.filter(task => task.weekday && task.weekday >= 1 && task.weekday <= 7);

            if (weekTasks.length === 0) {
                showToast('本周没有任务数据', 'error');
                return;
            }

            // 创建工作簿
            const wb = XLSX.utils.book_new();
            
            // 准备数据
            const wsData = [
                ['星期', '时段', '任务标题', '开始时间', '结束时间', '优先级', '完成状态', '备注']
            ];

            // 按星期和时段排序
            const sortedTasks = weekTasks.sort((a, b) => {
                if (a.weekday !== b.weekday) return a.weekday - b.weekday;
                const slotOrder = { 'AM': 1, 'PM': 2, 'EVENING': 3 };
                if (a.slot !== b.slot) return (slotOrder[a.slot] || 4) - (slotOrder[b.slot] || 4);
                return (a.start || '').localeCompare(b.start || '');
            });

            sortedTasks.forEach(task => {
                wsData.push([
                    dayNames[task.weekday] || '',
                    slotNames[task.slot] || task.slot,
                    task.title || '',
                    task.start || '',
                    task.end || '',
                    priorityNames[task.priority] || '中',
                    task.done ? '已完成' : '未完成',
                    task.note || ''
                ]);
            });

            // 创建工作表
            const ws = XLSX.utils.aoa_to_sheet(wsData);
            
            // 设置列宽
            ws['!cols'] = [
                { wch: 10 }, // 星期
                { wch: 10 }, // 时段
                { wch: 30 }, // 任务标题
                { wch: 12 }, // 开始时间
                { wch: 12 }, // 结束时间
                { wch: 10 }, // 优先级
                { wch: 12 }, // 完成状态
                { wch: 25 }  // 备注
            ];

            // 添加工作表到工作簿
            XLSX.utils.book_append_sheet(wb, ws, '周报');

            // 生成文件名
            const today = new Date();
            const fileName = `周报_${today.getFullYear()}年${(today.getMonth()+1).toString().padStart(2,'0')}月${today.getDate().toString().padStart(2,'0')}日.xlsx`;

            // 导出文件
            XLSX.writeFile(wb, fileName);
            
            showToast(`成功导出周报,共${weekTasks.length}个任务`);
            
            // 关闭下拉菜单
            document.getElementById('exportDropdown').classList.remove('show');
            document.querySelector('.dropdown-toggle').classList.remove('active');
        }

        // 点击外部关闭下拉菜单
        document.addEventListener('click', function(event) {
            // 关闭导出下拉菜单
            const exportDropdown = document.querySelector('.export-dropdown');
            if (exportDropdown && !exportDropdown.contains(event.target)) {
                document.getElementById('exportDropdown').classList.remove('show');
                document.querySelector('.export-dropdown .dropdown-toggle').classList.remove('active');
            }
            
            // 关闭数据备份下拉菜单
            const backupDropdown = document.querySelector('.backup-dropdown');
            if (backupDropdown && !backupDropdown.contains(event.target)) {
                document.getElementById('backupDropdown').classList.remove('show');
                document.querySelector('.backup-dropdown .dropdown-toggle').classList.remove('active');
            }
        });

        // 点击模态框外部关闭
        window.onclick = function(event) {
            const modals = ['taskModal', 'importModal', 'settingsModal', 'dailyExportModal', 'deleteConfirmModal', 'reminderModal'];
            modals.forEach(modalId => {
                const modal = document.getElementById(modalId);
                if (event.target === modal) {
                    if (modalId === 'taskModal') {
                        closeModal();
                    } else if (modalId === 'importModal') {
                        closeImportModal();
                    } else if (modalId === 'settingsModal') {
                        closeSettingsModal();
                    } else if (modalId === 'dailyExportModal') {
                        closeDailyExportModal();
                    } else if (modalId === 'deleteConfirmModal') {
                        closeDeleteConfirmModal();
                    } else if (modalId === 'reminderModal') {
                        closeReminderModal();
                    }
                }
            });
        };
        
        // 监听窗口大小变化,实时调整布局
        window.addEventListener('resize', function() {
            toggleWeekendDisplay();
        });
        
        // 页面加载完成后初始化网格布局
        window.addEventListener('load', function() {
            // 确保手机端网格布局正确初始化
            if (window.innerWidth <= 480) {
                toggleWeekendDisplay();
            }
        });

        // 关闭提醒模态框
        function closeReminderModal() {
            document.getElementById('reminderModal').style.display = 'none';
            reminderSystem.currentReminder = null;
            
            // 清除自动确认定时器
            if (reminderSystem.autoConfirmTimeout) {
                clearTimeout(reminderSystem.autoConfirmTimeout);
                reminderSystem.autoConfirmTimeout = null;
            }
        }

        // 测试开始提醒
        function testStartReminder() {
            console.log('执行开始提醒测试');
            const testTask = {
                id: 'test-start-' + Date.now(),
                title: '测试任务(开始提醒)',
                start: '09:00',
                end: '10:00',
                note: '这是一个测试任务,用于测试开始提醒功能',
                weekday: 1,
                slot: 'AM',
                done: false
            };
            showTaskReminder(testTask, 'start');
        }

        // 测试结束提醒
        function testEndReminder() {
            console.log('执行结束提醒测试');
            const testTask = {
                id: 'test-end-' + Date.now(),
                title: '测试任务(结束提醒)',
                start: '09:00',
                end: '10:00',
                note: '这是一个测试任务,用于测试结束提醒功能',
                weekday: 1,
                slot: 'AM',
                done: false
            };
            showTaskReminder(testTask, 'end');
        }
        
        // 测试语音播报
        function testVoiceOnly() {
            console.log('=== 开始测试语音播报 ===');
            console.log('浏览器语音合成支持:', 'speechSynthesis' in window);
            console.log('提醒系统语音设置:', reminderSystem.voiceEnabled);
            console.log('语音合成对象:', reminderSystem.speechSynthesis);
            
            if (!('speechSynthesis' in window)) {
                alert('您的浏览器不支持语音合成功能!');
                return;
            }
            
            if (!reminderSystem.voiceEnabled) {
                alert('语音提醒已禁用,请在设置中启用语音提醒!');
                return;
            }
            
            // 直接调用语音播报
            speakMessage('这是一个语音播报测试,如果您能听到这段话,说明语音功能正常工作', true);
            
            // 显示提示
            showToast('正在测试语音播报,请检查是否有声音', 'info');
        }
        
        // 调试函数:显示提醒系统状态
        function debugReminderSystem() {
            console.log('=== 提醒系统状态 ===');
            console.log('系统启用:', reminderSystem.enabled);
            console.log('语音启用:', reminderSystem.voiceEnabled);
            console.log('弹窗启用:', reminderSystem.popupEnabled);
            console.log('后台通知启用:', reminderSystem.backgroundEnabled);
            console.log('通知权限:', reminderSystem.notificationPermission);
            console.log('当前提醒:', reminderSystem.currentReminder);
            console.log('提醒历史记录数量:', reminderSystem.reminderHistory.size);
            console.log('上次检查时间:', reminderSystem.lastCheckTime);
            console.log('活跃超时数量:', reminderSystem.reminderTimeouts.size);
            
            // 显示今天的任务
            const now = new Date();
            const currentDay = now.getDay() || 7;
            const todayTasks = tasks.filter(task => task.weekday === currentDay && !task.done);
            console.log(`今天(星期${currentDay})的未完成任务:`, todayTasks);
            
            return {
                system: reminderSystem,
                todayTasks: todayTasks
            };
        }
        
        // 手动触发提醒检查(用于调试)
        function manualCheckReminders() {
            console.log('手动触发提醒检查');
            checkTaskReminders();
        }
        
        // 页面标题闪烁提醒(后台提醒的备用方案)
        function flashPageTitle(task, type) {
            const originalTitle = document.title;
            const alertTitle = type === 'start' 
                ? `&#128276; ${task.title} 开始执行!` 
                : `&#9200; ${task.title} 时间到!`;
            
            let isFlashing = true;
            let flashCount = 0;
            const maxFlashes = 10; // 最多闪烁10次
            
            const flashInterval = setInterval(() => {
                if (!isFlashing || flashCount >= maxFlashes) {
                    document.title = originalTitle;
                    clearInterval(flashInterval);
                    return;
                }
                
                document.title = flashCount % 2 === 0 ? alertTitle : originalTitle;
                flashCount++;
            }, 1000);
            
            // 当页面变为可见时停止闪烁
            const stopFlashing = (isVisible) => {
                if (isVisible) {
                    isFlashing = false;
                    document.title = originalTitle;
                    clearInterval(flashInterval);
                    
                    // 移除监听器
                    const index = reminderSystem.visibilityChangeHandlers.indexOf(stopFlashing);
                    if (index > -1) {
                        reminderSystem.visibilityChangeHandlers.splice(index, 1);
                    }
                    
                    // 页面变为可见时显示弹窗
                    if (reminderSystem.popupEnabled) {
                        showPopupReminder(task, type);
                    }
                }
            };
            
            reminderSystem.visibilityChangeHandlers.push(stopFlashing);
            console.log('开始标题闪烁提醒');
        }
        
        // 标记任务完成
        function markTaskComplete(taskId) {
            const task = tasks.find(t => t.id === taskId);
            if (task) {
                task.done = true;
                saveTasks();
                renderTasks();
                console.log(`任务 ${task.title} 已标记为完成`);
                showToast('任务已标记为完成', 'success');
            }
        }
    </script>    

</body>
</html>



免费评分

参与人数 143吾爱币 +143 热心值 +120 收起 理由
137560072 + 1 + 1 谢谢@Thanks!
HuaGdao1 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
ohyou321 + 1 + 1 谢谢@Thanks!
inclinch + 1 我很赞同!
丶沐箐 + 1 + 1 热心回复!
那个男人666啊 + 1 + 1 谢谢@Thanks!
cnbrave + 1 + 1 谢谢@Thanks!
Idealismbeiming + 1 + 1 用心讨论,共获提升!
ryannnnn + 1 + 1 我很赞同!
kfchen21 + 1 + 1 谢谢@Thanks!
FEIWU9 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
酱油国际 + 1 谢谢@Thanks!
纹路风 + 1 + 1 楼主加油,期待前后端版本
a2064730 + 1 + 1 我很赞同!
莫奇 + 1 + 1 谢谢@Thanks!
Cleverwwh + 1 + 1 我很赞同!
szoe + 1 + 1 谢谢@Thanks!
qaz003 + 3 用心讨论,共获提升!
tvrcfdfe + 1 + 1 我很赞同!
trtsky123 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
long8586 + 1 + 1 谢谢@Thanks!
dradon + 1 + 1 热心回复!
m2021m + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
aabbcc123123 + 1 + 1 谢谢@Thanks!
wtslh + 1 + 1 谢谢@Thanks!
gezhonglunta + 1 + 1 谢谢@Thanks!
唐小样儿 + 1 + 1 我很赞同!
citynook + 1 热心回复!
There101 + 1 + 1 谢谢@Thanks!
aliza39 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
pingan2639 + 1 + 1 我很赞同!
yiqibufenli + 1 + 1 我很赞同!
zhxhwyzh14 + 1 我很赞同!
tianbukongbai + 1 谢谢@Thanks!
RenJunyang + 1 谢谢@Thanks!
小小鱼343 + 1 谢谢@Thanks!
Duxie222 + 1 + 1 谢谢@Thanks!
grrr_zhao + 1 + 1 谢谢@Thanks!
kingstarg + 1 + 1 谢谢@Thanks!
stcoolboy + 1 + 1 我很赞同!
maqangch + 1 + 1 我很赞同!
MRXZ1994 + 1 谢谢@Thanks!
NEYeee + 1 + 1 热心回复!
zhouqiuji0815 + 1 我很赞同!
adsxxhh + 1 + 1 我很赞同!
坡婆子 + 1 + 1 用心讨论,共获提升!
假装在伦敦 + 1 + 1 谢谢@Thanks!
laobai6866 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
dongfang2025 + 1 + 1 我很赞同!
Gandalf + 1 谢谢@Thanks!
o824 + 1 + 1 谢谢@Thanks!
zjh106 + 1 + 1 谢谢@Thanks!
rockmanlz119 + 1 + 1 热心回复!
q2825q + 1 + 1 我很赞同!
yuweb + 1 + 1 热心回复!
朝歌晚酒 + 1 我很赞同!
sjklmzc + 1 + 1 谢谢@Thanks!
叶丶 + 2 + 1 我很赞同!
renyi66666 + 1 + 1 谢谢@Thanks!
yhw111963 + 1 + 1 热心回复!
card628 + 1 热心回复!
开心熊猫741 + 1 + 1 热心回复!
mryouan + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
dzc999 + 1 + 1 谢谢@Thanks!
BOYAZY + 1 + 1 谢谢@Thanks!
yxpp + 1 谢谢@Thanks!
xiaomr1990 + 1 + 1 谢谢@Thanks!
749 + 1 + 1 我很赞同!
liu_liufei + 1 + 1 热心回复!
GS9452 + 1 用心讨论,共获提升!
crizquan + 1 + 1 我很赞同!
xiafengyu + 1 我很赞同!
你好漂亮 + 1 + 1 我很赞同!
smallchop + 1 + 1 谢谢@Thanks!
mhaitao + 1 + 1 我很赞同!
YuLoo + 1 我很赞同!
IcePlume + 1 + 1 谢谢@Thanks!
学一手 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
cjhcai + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
happy1every1day + 1 + 1 我很赞同!
alen_1573 + 1 + 1 我很赞同!
shadowjoker + 1 谢谢@Thanks!
wanfen11 + 1 我很赞同!
huayi + 1 我很赞同!
逐风之雷霆之怒 + 1 要早点看到就好了,不用自己设计表格了,支持原创!
quincyshao + 1 + 1 谢谢@Thanks!
JimOvO + 1 热心回复!
oshuanghao + 1 谢谢@Thanks!
ma5635 + 1 + 1 希望楼主直接出月历版的,更实际,好多工作是按月计的,一般本周的一般用便 ...
迷障章鱼哥 + 1 我很赞同!
be1ieveme + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
你已被论坛禁言 + 1 + 1 谢谢@Thanks!
linsixi + 1 用心讨论,共获提升!
昆局水段 + 1 + 1 谢谢@Thanks!
梦里无念 + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
qdlitiger + 1 + 1 谢谢@Thanks!
zxcvbnm12 + 1 高产
hhzi + 1 谢谢@Thanks!正好用上!
pubh + 1 + 1 谢谢@Thanks!
endgame + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
 楼主| bdxs2019 发表于 2025-8-24 22:04 |楼主
本帖最后由 bdxs2019 于 2025-9-14 14:12 编辑

8月25-26日更新内容预览:
1、PC端界面宽度设置1600px,自适应PC端屏幕,显示周六+周日下 极限可放大200%(完美解决近视问题);
2、PC端设置里可以设置隐藏周六/周日(可以同时隐藏)、也可以隐藏晚上,及上午  下午  晚上的时间段显示
3、PC端和手机端都支持导出日报和周报
4、新增报表名称:每周工作计划表(点击可以自定义)
5、完美适配手机端(支持同时隐藏 晚上/周六/周日),任务卡片支持跨单元格拖动
6、做了10多项细节调整,纯属强迫症,主要是提升下用户体验
7、上个版本导出CSV格式的备份,可以导入这个版本继续使用(完美兼容),目前表格只在WPS下做了测试,Office没有安装,有可能乱码...

功能都很简单、一看就懂,不需要教程了。。。喜欢的话,给个鼓励

线上演示地址:https://www.qingqiqifu.com/bwl/
数据保存在浏览器里,需经常导出CSV备份

源码下载(适配手机端): 每周工作备忘录.zip (330.05 KB, 下载次数: 529)

月度视图版本:https://www.52pojie.cn/thread-2056057-1-1.html





免费评分

参与人数 9吾爱币 +10 热心值 +8 收起 理由
qgqc + 1 + 1 谢谢@Thanks!
windy3000 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
ngfc + 1 用心讨论,共获提升!
w1020541818 + 1 + 1 谢谢@Thanks!
sc001 + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
takesportm + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
lwlw2262 + 1 + 1 谢谢@Thanks!
myFreefly + 1 + 1 谢谢@Thanks!
pudilan + 1 + 1 谢谢@Thanks!

查看全部评分

推荐
 楼主| bdxs2019 发表于 2025-8-26 09:22 |楼主
zxa2000 发表于 2025-8-26 09:19
不错的软件,不知能否考虑将数据存入数据库版本。这样就可以直接嵌入OA中。

正常是可以的,可以自行用AI转换下。
这边暂时还是用简单的Html,数据库可能会难倒普通用户。
推荐
 楼主| bdxs2019 发表于 2025-8-26 09:12 |楼主
chinaxndd 发表于 2025-8-26 08:40
大哥,左侧最大23点,可是工作到凌晨2点呢

时间有上限,牛马无极限

0-24小时版: 每周工作备忘录.zip (330.96 KB, 下载次数: 431)

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
orz4260 + 1 + 1 24H版本也出了……

查看全部评分

推荐
 楼主| bdxs2019 发表于 2025-8-26 16:29 |楼主
qdlitiger 发表于 2025-8-26 16:27
谢谢分享!
其实经常需要按照月度看整体安排,如果能有月视图就更好了。

已经改了一个月计划的,应该很快就能好,晚点可以发布,关注下我后续的新帖子。
推荐
cpnorg 发表于 2025-8-24 22:30
手机自适应能不能适配一下?
推荐
zhengzhenhui945 发表于 2025-8-24 23:32
可添加铃声提示或者自定义URL铃声就更完美了
推荐
 楼主| bdxs2019 发表于 2026-3-3 11:01 |楼主
lolan 发表于 2026-3-3 09:31
谢谢回复 提个建议 可不可以用月视图或者周视图中每日加上当天的日期,这样感觉比较直观

好的,已经在规划,下个版本更新
推荐
 楼主| bdxs2019 发表于 2025-8-24 22:03 |楼主
zhangdexi 发表于 2025-8-24 21:57
这个有弹窗提醒吗,还是固定在桌面最前端显示呢?

这个没有弹窗提醒,也不能固定桌面,就是一个浏览器打开的网页,就一个每日任务看板,完成的任务打勾就划掉。
推荐
 楼主| bdxs2019 发表于 2025-8-30 21:35 |楼主
本帖最后由 bdxs2019 于 2025-8-30 22:20 编辑

我只是半个产品+半个前端,不会后端,正在用AI IDE转一套简单的团队版,采用PHP8.0+SQLite3(最简单的,傻瓜式使用,支持几十个并发还是可以的),用PHP study或宝塔可以本地或云端部署,连数据库都不需要安装...
不确定什么时候能完成,完全看AI脸色

先透露几张半成品的UI(非最终样式),尽可能还原HTML表格形式(需要交互,可能会有所不同,还是以简洁、实用为理念):





推荐
Kls673M 发表于 2025-8-25 09:02
建议加个推送功能,
比如说打开这个网页时根据当前的时间,检索当前时间的应该完成或者需要完成、超期未完成等就推送信息
5#
shubiao05 发表于 2025-8-24 21:53
不是一般的强,太喜欢这个东东了!
6#
zhangdexi 发表于 2025-8-24 21:57
这个有弹窗提醒吗,还是固定在桌面最前端显示呢?
7#
uyj666 发表于 2025-8-24 22:03
太喜欢这个东东了!简单实用
8#
junshuiyujianni 发表于 2025-8-24 22:07
这个晚上可以自由添加删减吗?
9#
happyxuexi 发表于 2025-8-24 22:31
界面漂亮,大佬真是高产啊。点赞。
10#
Alaoba 发表于 2025-8-24 22:41
可以,有时间下载试试。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-5-16 14:53

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表