refactor(api): 重构数据库访问为SQLAlchemy绑定的session

- 统一移除手动创建的数据库session,统一使用models模块中的db.session
- 修正项目创建接口,增加开始和结束日期的格式验证与处理
- 更新导入项目接口,使用枚举类型校验项目类型并优化异常处理
- 更新统计接口,避免多次查询假期数据,优化日期字符串处理
- 删除回滚前多余的session关闭调用,改为使用db.session.rollback()
- app.py中重构数据库初始化:统一配置SQLAlchemy,动态创建数据库路径和表
- 项目模型新增开始日期和结束日期字段支持
- 添加导入批次历史记录模型支持
- 优化工具函数中日期类型提示,移除无用导入
- 更新requirements.txt依赖版本回退,确保兼容性
- 前端菜单添加导入历史导航入口,实现页面访问路由绑定
This commit is contained in:
2025-09-04 18:12:24 +08:00
parent ef9432f6da
commit 8938ce2708
29 changed files with 3490 additions and 150 deletions

167
templates/timerecords.html Normal file
View File

@@ -0,0 +1,167 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>工时记录 - 个人工时记录系统</title>
<link rel="stylesheet" href="/static/css/styles.css">
</head>
<body>
<nav class="navbar">
<div class="nav-container">
<div class="nav-brand">
<h1>个人工时记录系统</h1>
</div>
<ul class="nav-menu">
<li><a href="/" class="nav-link">首页</a></li>
<li><a href="/projects" class="nav-link">项目管理</a></li>
<li><a href="/timerecords" class="nav-link active">工时记录</a></li>
<li><a href="/statistics" class="nav-link">统计分析</a></li>
<li><a href="/import" class="nav-link">导入历史</a></li>
</ul>
</div>
</nav>
<main class="main-content">
<div class="container">
<div class="page-header">
<h2>工时记录</h2>
<div class="page-actions">
<button class="btn btn-primary" onclick="showCreateRecordModal()">新建记录</button>
</div>
</div>
<!-- 筛选条件 -->
<div class="filter-section">
<div class="filter-row">
<div class="form-group">
<label for="filter-start-date">开始日期</label>
<input type="date" id="filter-start-date" class="form-control" onchange="loadTimeRecords()">
</div>
<div class="form-group">
<label for="filter-end-date">结束日期</label>
<input type="date" id="filter-end-date" class="form-control" onchange="loadTimeRecords()">
</div>
<div class="form-group">
<label for="filter-project">项目</label>
<select id="filter-project" class="form-control" onchange="loadTimeRecords()">
<option value="">全部项目</option>
</select>
</div>
<div class="form-group">
<button class="btn btn-secondary" onclick="resetFilters()">重置筛选</button>
</div>
</div>
</div>
<!-- 工时记录表格 -->
<div class="table-container">
<table class="data-table" id="timerecords-table">
<thead>
<tr>
<th>日期</th>
<th>星期</th>
<th>事件</th>
<th>项目</th>
<th>开始时间</th>
<th>结束时间</th>
<th>Activity Num</th>
<th>工时</th>
<th>操作</th>
</tr>
</thead>
<tbody id="timerecords-tbody">
<tr>
<td colspan="9" class="text-center">加载中...</td>
</tr>
</tbody>
</table>
</div>
</div>
</main>
<!-- 新建/编辑工时记录模态框 -->
<div id="timerecord-modal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3 id="timerecord-modal-title">新建工时记录</h3>
<button class="close-btn" onclick="closeModal('timerecord-modal')">&times;</button>
</div>
<form id="timerecord-form">
<div class="modal-body">
<!-- 日期和休息日信息 -->
<div class="form-row">
<div class="form-group">
<label for="record_date">日期 *</label>
<input type="date" id="record_date" name="date" class="form-control"
onchange="checkHoliday()" required>
</div>
<div class="form-group">
<div id="holiday-info" class="holiday-info" style="display:none;">
<span id="holiday-badge" class="badge"></span>
<span id="holiday-text"></span>
</div>
</div>
</div>
<!-- 事件描述 -->
<div class="form-group">
<label for="event_description">事件描述</label>
<input type="text" id="event_description" name="event_description"
class="form-control" placeholder="如浦发银行VIOS升级">
</div>
<!-- 项目选择 -->
<div class="form-group">
<label for="project_id">项目</label>
<select id="project_id" name="project_id" class="form-control">
<option value="">请选择项目</option>
</select>
</div>
<!-- 时间输入 -->
<div class="form-row">
<div class="form-group">
<label for="start_time">开始时间</label>
<input type="time" id="start_time" name="start_time"
class="form-control" onchange="updateHoursInput()">
</div>
<div class="form-group">
<label for="end_time">结束时间</label>
<input type="time" id="end_time" name="end_time"
class="form-control" onchange="updateHoursInput()">
</div>
</div>
<!-- Activity Num 和工时 -->
<div class="form-row">
<div class="form-group">
<label for="activity_num">Activity Num</label>
<input type="text" id="activity_num" name="activity_num"
class="form-control" placeholder="如5307905">
</div>
<div class="form-group">
<label for="hours">工时</label>
<input type="text" id="hours" name="hours" class="form-control"
placeholder="如2:42 或 8:00:00" readonly>
<small class="form-text">工时将根据开始和结束时间自动计算</small>
</div>
</div>
<!-- 休息日提示 -->
<div id="holiday-warning" class="alert alert-warning" style="display:none;">
<strong>注意:</strong>这是一个休息日,如需记录工时请填写开始和结束时间,或直接输入工时。
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" onclick="closeModal('timerecord-modal')">取消</button>
<button type="submit" class="btn btn-primary">保存</button>
</div>
</form>
</div>
</div>
<script src="/static/js/common.js"></script>
<script src="/static/js/timerecords.js"></script>
</body>
</html>