【日常记录】关于公司让我做一个备忘录系统的事(2024.12.27 更新)
序章 开发背景
嘿,小伙伴们!咱们在公司里上班,是不是常常感觉脑袋里像一团乱麻,各种任务就像调皮的小怪兽在里头蹦跶?
你看啊,一会儿老板交代个紧急项目,那边客户又来个特殊要求,还有些杂七杂八的日常工作像小尾巴似的甩都甩不掉。这时候,要是不找个靠谱的法子把这些事儿都梳理清楚,那可就等着被工作淹没得找不着北啦!
所以呢,咱们公司就灵机一动,打算用Python打造一个超酷的待办事项系统(其实就是个超厉害的备忘录啦)。这可不是那种高大上到让人望而生畏的东西哦,它就像是你身边贴心又有点小机灵的朋友。
想象一下,Python就像个魔法小工匠,用它神奇的代码魔法,把这个待办事项系统变得就像魔法口袋一样方便。咱们员工呢,只要像跟朋友聊天似的,轻松地把任务丢进去,不管是大事小事,它都能稳稳当当地接住。
这个系统里呀,每项任务就像是个小士兵,有着自己的“优先级军衔”,什么紧急任务就像是特种兵,排在最前面。还有那截止日期,就像小闹钟一样时刻提醒着这些小士兵该行动啦。
接下来呢,我这个“技术小白”就要带大家探秘这个超有趣的待办事项系统是怎么从想法变成现实的啦。咱们就跟着Python的节奏,在代码的世界里溜达一圈,看看这个能让咱工作变得井井有条的神器到底是怎么诞生的吧!
(本人纯纯技术小白,刚接触python,如果各位大佬对代码有更好的优化见解,欢迎指出)
已有功能清单:
-
添加待办事项
-
查询待办事项
- 查询未完成事项
- 查询已完成事项
-
删除待办事项
- 删除待办事项需要提交原因,并做日志记录
-
本地生成json本文进行数据记录(内容已废除,改为数据库保存数据) -
新增数据库保存数据
- 新建todo表
- 新建Log表
- 新建user表
-
操作日志
- 操作用户信息
- 新增待办事项
- 修改待办事项
- 删除待办事项
- 操作ip
- 登录账号
- 退出账号
- 管理员设置与取消
- 备注信息新增与修改
-
事项的备注信息
- 同步在日志中新增相关备注信息
-
用户登录功能
-
用户自主注册功能
-
日志查询界面
- 默认用户查询自己的记录
- 管理员可查询所有
-
管理员权限
- 管理员可查看所有用户的未完数据
- 管理员可查看所有用户的已完成数据
- 管理员可查看所有用户的日志
-
用户管理
- 设置管理员
- 取消管理员
- 账号禁用
- 账号启用
-
新增报表系统
- 默认普通用户看自己
- 管理员可看全部
-
机器人提醒功能
- 可对未完成事项设置固定时间提醒,在指定时间通过企微机器人进行消息提醒
未完成功能清单:
- 权限模块细分:目前除了管理员能看出全部数据之外,还想设计权限角色相关,管理员(或有权限的账号)可自定义权限角色,指定某个角色可查询某个页面,可以查看看自己或者看全部的数据。
- 公司组织架构:新增公司部门相关架构设计
- 可按公司架构进行权限划分,部门领导可看本部门的数据
- 消息提醒可自定义
- 用户自定义通知途径:钉钉机器人/企微机器人/飞书机器人
- 用户可自定义修改提醒文案
- 尽可能对前端页面进行优化,虽然优化了多个版本,但是仍然感觉不太美观
- 如果有时间,考虑做一个pc客户端
- 目前仅内网使用,如果有机会会映射到外网(现在还没和领导达成一致)
- 有了外网就可在手机上随时更新待办事项了,所以会适配手机分辨率
- 也考虑做一个app
- 其他事项暂时没想出来,随时补充
【2024.10.13】v1.0 初代版本
使用 Flask 框架构建待办事项应用。它实现了基本的待办事项的增删改查(CRUD)功能,同时记录操作日志并备份数据。以下是对其方法和整体思路的详细说明:
整体思路
- Flask应用配置 :
- 创建 Flask 应用实例并配置密钥和数据库。使用 SQLite 存储待办事项和日志数据。
- 数据库模型 :
- 定义了两个模型:
Todo
:表示待办事项,包含标题、完成状态、创建时间和更新时间。Log
:表示操作日志,记录操作类型、详情和时间戳。
- 定义了两个模型:
- 路由处理 :
- 定义了多个路由,每个路由对应一种功能:
- 首页 (
/
) :展示未完成和已完成的待办事项。 - 添加待办事项 (
/add_todo
) :处理提交表单以添加新的待办事项。 - 删除待办事项 (
/delete_todo/<int:id>
) :根据 ID 删除指定的待办事项。 - 编辑待办事项 (
/edit_todo/<int:id>
) :处理编辑待办事项的请求。 - 完成待办事项 (
/complete_todo/<int:id>
) :切换待办事项的完成状态。
- 首页 (
- 定义了多个路由,每个路由对应一种功能:
- 数据备份 :
- 定义了一个函数
backup_to_json
,用于将待办事项数据备份到 JSON 文件。
- 定义了一个函数
- 日志记录 :
- 定义了一个函数
log_action
,用于记录每次对待办事项进行操作时的日志。
- 定义了一个函数
详细说明
- Flask 应用实例 :
app = Flask(__name__)
app.config['SECRET_KEY'] = '100'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///todos2.db'
app.config['SQLALCHEMY_BINDS'] = {'logs': 'sqlite:///logs.db'}
db = SQLAlchemy(app)
数据库模型 :
-
Todo
和Log
模型被定义为 SQLAlchemy 的 ORM 模型,用于映射到数据库表。 -
数据库中的每一项待办事项都有标题、状态及时间戳。
-
路由功能 :
index
方法查询未完成和已完成的待办事项,并将数据传递给index.html
模板,渲染页面。add_todo
方法接收用户提交的新待办事项,保存到数据库并记录操作日志。delete_todo
、edit_todo
和complete_todo
方法则分别实现删除、编辑、标记完成等操作。
-
数据备份和日志记录 :
- 在每次对待办事项进行变更(添加、删除、修改状态)时,都会调用
backup_to_json
函数将所有待办事项备份到backup.json
文件中。 - 通过
log_action
函数记录操作日志,便于后续追溯。
- 在每次对待办事项进行变更(添加、删除、修改状态)时,都会调用
-
应用运行 :
if __name__ == '__main__': app.run(host='0.0.0.0', port=9002, debug=True)
- 代码最后通过指定主机和端口运行 Flask 应用,并启用调试模式以便于开发过程中进行错误追踪。
总的来说,这段代码实现了一个简单而完整的待办事项管理应用,利用 Flask 和 SQLAlchemy 提供了清晰的结构和功能,同时兼顾了数据的安全性和完整性。
数据库模型介绍
在这个待办事项应用中,我们定义了两个主要的数据库模型:Todo
和 Log
。以下是这两个模型的详细介绍:
1. Todo 模型
- 表名 :
todos
- 字段 :
id
(Integer, 主键):唯一标识每个待办事项的 ID。title
(String, 不可为空):待办事项的标题,用户输入的内容。done
(Boolean, 默认值为 False):表示待办事项的完成状态,False
表示未完成,True
表示已完成。created_at
(Date, 默认值为当前日期):记录待办事项的创建时间。updated_at
(Date, 默认值为当前日期, 在更新时自动改变):记录最后一次更新待办事项的时间。
# 定义待办事项模型
class Todo(db.Model):
id = db.Column(db.Integer, primary_key=True) # 主键
title = db.Column(db.String(100), nullable=False) # 标题,不能为空
done = db.Column(db.Boolean, default=False) # 完成状态,默认为 False
created_at = db.Column(db.Date, default=date.today) # 创建时间,默认为当天日期
updated_at = db.Column(db.Date, default=date.today, onupdate=date.today) # 更新时间,默认为当天日期,且在更新时自动设置为当天日期
def __repr__(self):
return f'<Todo {self.title}>' # 返回待办事项的字符串表示
2. Log 模型
- 表名 :
logs
- 字段 :
id
(Integer, 主键):唯一标识每个日志记录的 ID。action
(String, 不可为空):记录的操作类型,如 'add'、'delete'、'edit' 和 'complete'。details
(String, 不可为空):关于操作的详细信息,描述这次操作的内容。timestamp
(DateTime, 默认值为当前时间,使用上海时区):记录操作发生的时间。
# 定义日志模型
class Log(db.Model):
__bind_key__ = 'logs' # 绑定到日志数据库
id = db.Column(db.Integer, primary_key=True) # 主键
action = db.Column(db.String(50), nullable=False) # 操作类型,不能为空
details = db.Column(db.String(255), nullable=False) # 操作详情,不能为空
timestamp = db.Column(db.DateTime, default=lambda: datetime.now(pytz.utc).astimezone(pytz.timezone('Asia/Shanghai')))
def __repr__(self):
return f'<Log {self.action} at {self.timestamp}>' # 返回日志的字符串表示
整体流程图描述
为便于理解,以下是待办事项应用的整体流程描述:
- 首页访问 :
- 用户访问首页 (
/
)。 - 系统查询未完成和已完成的待办事项。
- 渲染首页并展示待办事项列表。
- 用户访问首页 (
- 添加待办事项 :
- 用户在首页提交新待办事项。
- 系统处理请求,保存新待办事项到数据库。
- 记录添加操作的日志。
- 执行数据备份到 JSON 文件。
- 重定向用户回到首页。
- 编辑待办事项 :
- 用户选择某个待办事项进行编辑。
- 系统显示编辑表单。
- 用户提交编辑表单。
- 系统更新待办事项标题。
- 记录编辑操作的日志。
- 执行数据备份到 JSON 文件。
- 重定向用户回到首页。
- 删除待办事项 :
- 用户选择某个待办事项进行删除。
- 系统从数据库中删除待办事项。
- 记录删除操作的日志。
- 执行数据备份到 JSON 文件。
- 重定向用户回到首页。
- 完成待办事项 :
- 用户选择某个待办事项标记为完成。
- 系统切换待办事项的完成状态。
- 记录状态变更的日志。
- 执行数据备份到 JSON 文件。
- 重定向用户回到首页。
index.html概述
待办事项应用的主页面(index.html
),概括如下:
技术要点概述
- 文档结构 :
- 使用标准的 HTML5 文档结构 (
<!DOCTYPE html>
)。 - 在
<head>
中设置了字符集、视口和标题。
- 使用标准的 HTML5 文档结构 (
- 样式设计 :
- 使用了内嵌的 CSS 样式进行页面布局和设计。
- 全局样式重置,消除默认的 margin 和 padding,以确保不同浏览器呈现一致性。
- 使用 Flexbox 布局 (
display: flex
) 来实现响应式设计,合理分配组件空间。 - 增加了悬停效果和过渡效果,例如按钮在悬停时改变背景色和微妙的移动。
- 字体和颜色 :
- 采用了一种清晰的字体(如
Segoe UI
),提升可读性。 - 颜色主题使用简约的配色,使整体界面看起来整洁且易于使用。
- 采用了一种清晰的字体(如
- 表单处理 :
- 使用
<form>
元素接收用户输入的待办事项,设置method="post"
方式提交数据到服务器。 - 输入框使用
placeholder
进行提示,且设定了必填字段 (required
)。
- 使用
- 动态数据展示 :
- 使用 Jinja2 模板语法(如
{% for todo in todos_not_done %}
)动态渲染待办事项列表。 - 根据待办事项的状态 (完成与未完成) 动态渲染不同的内容和样式。
- 使用 Jinja2 模板语法(如
- 事件处理 :
- 使用事件处理(例如,checkbox 的
onclick
事件)来实现待办事项完成状态的切换。 - 超链接利用
url_for
函数生成对应的 URL,支持对待办事项进行编辑和删除操作。
- 使用事件处理(例如,checkbox 的
- 可访问性设计 :
- 使用语义化 HTML 标签(如
<h1>
、<h2>
、<ul>
、<li>
),提高可访问性和搜索引擎优化(SEO)。 - 将时间信息清晰呈现,并提供待办事项的创建和更新时间。
- 使用语义化 HTML 标签(如
关键的 HTML 和 CSS 组件
- 标题和容器 :
<h1>待办事项</h1>
<div class="container">...</div>
- 表单输入 :
<form action="{{ url_for('add_todo') }}" method="post">
<input autocomplete="off" name="todo" placeholder="添加新的待办事项" required type="text">
<button class="button" type="submit">添加</button>
</form>
- 待办事项列表 :
<ul class="todo-list">
{% for todo in todos_not_done %}
<li>
<div class="todo-content">...</div>
<div class="todo-actions">...</div>
<div class="time-info">...</div>
</li>
{% endfor %}
</ul>
- 样式示例 :
body {
background-color: #f9f9f9;
color: #333;
}
.column {
background-color: #fff;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
网页预览:
edit_todo.html网页概述
该网页的标题为“编辑待办事项”,主要功能是允许用户更新已存在的待办事项的标题。用户填写完成后,通过提交表单来更新数据。
主要组成部分
- DOCTYPE和HTML结构 :
- 网页使用HTML5标准(
<!DOCTYPE html>
),并指定了语言为英语(lang="en"
)。
- 网页使用HTML5标准(
- 头部(Head) :
- 设置了字符集为UTF-8,以支持多种字符。
- 设置了视口meta标签,以便网页在移动设备上正确显示。
- 网页标题设置为“编辑待办事项”。
- 内嵌的CSS样式定义了网页的整体样式,包括字体、背景色、边距、填充等。
- 样式(Style) :
- 使用了Roboto字体,整体背景色为浅灰色,主文字为深灰色。
- 标题(h1)居中,使用较大字体显示。
- 表单容器和表单本身进行了样式美化,具有圆角和阴影效果。
- 输入框和按钮均进行了样式设置,提升用户交互体验。
- 主体(Body) :
- 页面中心显示“编辑待办事项”的标题。
- 表单容器中包含一个表单,表单通过POST方法提交数据,action指向相应的URL(
edit_todo
)。 - 表单中包含一个用于输入待办事项标题的文本框和一个提交按钮。
功能说明
- 输入框 : 用户可以在文本框中输入待办事项的新标题。此输入框设置为必填(
required
)。 - 提交按钮 : 用户点击按钮提交更新请求,按钮文本为“更新”。
网页预览:
(初期UI好low,不要介意啦)
【2024.10.20】v1.1 更新功能
【2024.10.28】v1.2 更新功能
【2024.11.05】v1.3 更新功能
【2024.11.07】v1.4 更新功能
【2024.11.08】v1.5 更新功能
【2024.11.17】v1.6 更新功能
【2024.11.20】v1.7 更新功能
【2024.11.29】v1.8 更新功能
【2024.12.04】v1.9 更新功能
【2024.12.05】v1.9 更新功能
【2024.12.09】v2.0 更新功能
【2024.12.11】v2.1 更新功能
【2024.12.13】v2.2 更新功能
【2024.12.20】v2.3 更新功能
【2024.12.22】v2.4 更新功能
【2024.12.27】v2.5 更新功能
管理员数据查询界面只能对单个关键词进行模糊查询,有些关键词数据过多,筛选出过多的数据查找困难。
本次对事项和备注栏做了优化,可以同时对多个关键词进行模糊搜索
h5页面修改相关输入框的placeholder
属性,示例如下:
<input type="text" name="title" placeholder="事项(空格隔开多个关键词)" value="{{ filter_title }}">
<input type="text" name="notes" placeholder="备注(空格隔开多个关键词)" value="{{ filter_notes }}">
py后端代码也需要同步更新,在这个代码中,filter_title
和filter_notes
中的输入字符串被分割成多个关键词,应用于模糊查询,这样用户就可以输入多个关键词并进行筛选。每个关键词将会被用contains
操作进行查询
if filter_title:
title_keywords = filter_title.split() # 用空格分割多个关键词
for keyword in title_keywords:
todos_query = todos_query.filter(Todo.title.contains(keyword)).order_by(Todo.updated_at.desc())
if filter_notes:
notes_keywords = filter_notes.split() # 用空格分割多个关键词
for keyword in notes_keywords:
todos_query = todos_query.filter(Todo.notes.contains(keyword)).order_by(Todo.updated_at.desc())
效果如下
开源么,有没有仓库链接?
还没做好,还在开发中,目前没有上传到仓库。开发完成会开源的😳
古德古德
冯季天?
桀桀桀。居然被认出来了
👍 外瑞古德
水印太明显了啊喂
哦莫莫!
哦莫,公司电脑强行水印,去不掉呐
哦莫~
可以考虑下禅道
哈哈。可以考虑一下