ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

基于Python Flask与MySQL的社区养老服务管理系统开发实践

基于Python Flask与MySQL的社区养老服务管理系统开发实践 简介基于Python与Vue.js开发的社区养老管理系统后端采用Python实现B/S架构的服务端逻辑前端使用Vue.js搭建交互界面覆盖老人管理、护工管理、亲属管理、病史管理、房间管理、活动管理、用户管理、日志管理及系统信息等核心功能为社区养老机构、高校学生或中小型团队提供了一套可快速落地的信息化管理方案。压缩包共177个文件约6.02MB其中35个py文件承担后端业务处理与接口逻辑14个vue组件、35个ts脚本及10个js工具文件构成前端页面与类型交互并辅以svg、png、jpeg等图标图片资源目录结构清晰便于前后端对照学习与二次开发。目前已有312人学习下载适合作为毕业设计、课程设计或实际项目的参考基线。源码可直接部署运行搭配演示账号可在真实环境中体验老人档案、活动安排等完整业务流程节省从零搭建的时间。1. 项目背景与需求梳理1.1 社区养老到底需要一个什么样的系统社区养老和机构养老不一样它天然是“散点式”管理的。老人住在自己家里服务人员来自周边社区、第三方机构或志愿者团队服务项目又是碎片化的——今天上门送餐明天陪诊拿药后天搞个健康讲座。这种场景下如果还靠纸质台账和微信群沟通信息基本是断裂的。我接手这个需求时社区的工作人员反馈了几个很具体的痛点老人档案散落在各个网格员手里换个负责人就丢一段历史记录服务工单靠手写流转月底对账时经常说不清哪笔费用对应哪次服务健康数据血压、血糖这些记录在纸质本上社区医生没法快速筛查高风险老人。所以这套管理系统最核心的目标就三件事把老人档案集中管起来把服务过程从头到尾记录清楚让社区管理者一眼能看出当下哪些老人需要重点关注。1.2 为什么用Python来做这类管理系统选Python不是因为它“最流行”而是因为这个项目的开发周期和后续迭代模式最适合它。社区养老管理系统的数据量级不算大峰值并发也不高但业务逻辑非常琐碎——状态流转多、角色权限多、报表类型多。Python在这种“复杂业务逻辑但低并发”的Web应用场景下开发迭代速度是所有主流语言里最舒服的。再加上Python生态里Flask和Django这两个Web框架都极度成熟基础功能基本不用自己造轮子。尤其对于社区信息化这种预算有限、后续可能需要社区自己人维护的项目Python代码的结构化和可读性优势很突出。后文我会具体讲框架怎么选这里先给结论如果项目周期在1到3个月、团队1到2个人用Python做管理系统是性价比最高的选择。2. 技术选型与整体架构设计2.1 Flask和Django怎么选这套系统我最终选了Flask 2.x SQLAlchemy的组合没上Django。原因很实际项目功能边界清晰不需要Django自带的Admin后台也不需要它那一套完整的用户认证体系Flask的蓝图Blueprint机制足够把老人管理、工单管理、健康档案等功能拆成模块代码结构不会乱。但如果你对Python Web开发还不熟或者这个系统后续会有大量复杂的后台管理页面需求选Django会更稳妥——它自带ORM、Admin、迁移工具开箱即用的东西更多。我个人的判断标准很简单项目工期在1个月内、团队只有1个人选Flask如果是长期项目、会有多个人协作维护选Django。这次社区项目后期确实加入了几个我之前没预料到的新模块比如志愿者排班Flask的轻量特性让我可以很灵活地加蓝图没有受框架约束的感觉。2.2 前后端分离还是服务端渲染这个决定影响了整个开发节奏。考虑到社区工作人员的使用场景——四五十岁的办公人员在老旧电脑上用IE或360兼容模式打开系统的概率非常大如果搞Vue Axios的前后端分离接口跨域、浏览器兼容、Token过期处理这些问题就够折腾一个星期的。所以我用了更务实的方式Jinja2模板渲染 Bootstrap 4 AJAX局部刷新。页面整体是服务端渲染需要局部更新的地方比如服务工单状态切换、健康数据录入用jQuery发AJAX请求到后端接口返回JSON再更新DOM。这种方式对老旧浏览器的兼容性最好开发效率也高而且社区这类管理系统的交互复杂度根本不需要上重前端框架。实际做下来服务端渲染还有一个额外的好处——页面源码里直接能看到数据对后续做简单的SEO或岗位交接培训都方便。2.3 数据库选型与部署环境数据库这块没什么悬念MySQL 5.7。虽然SQLite对Flask更友好、零配置但社区系统里多人同时录入数据SQLite的写锁限制很容易造成“database is locked”错误。MySQL 5.7是目前国内服务器上最常见的版本社区IT人员也相对熟悉。部署环境我用了Ubuntu 20.04 Gunicorn Nginx的经典组合。这里有个关键参数供参考社区系统日常并发也就十几个请求Gunicorn配置4个worker进程完全够用再多反而浪费内存。服务器配置2核4G就绰绰有余一年成本也没多少比SaaS月租系统划算数据也更安全可控。3. 核心功能拆解与数据库设计3.1 五个核心功能模块这套系统的功能逻辑我最终收敛成了五个模块太多会让维护成本失控太少覆盖不了社区日常管理需求老人档案管理最核心的基座包括基本信息、家属联系人、既往病史、用药情况、居住地址精确到楼栋门牌号支持按网格员划分数据权限。服务工单管理从服务申请、派单、执行到完成确认的完整流程记录服务项目、服务时长、执行人、满意度评价。健康数据管理记录老人的血压、血糖、心率等定期测量数据支持图表趋势展示。费用与补贴管理记录每笔服务费用的产生和结算状态区分自费、政府补贴、公益免费三种类型。系统管理与统计报表用户角色权限管理、操作日志、服务量统计、重点老人分布图等。服务工单这个模块是整个系统的“事务核心”它把老人、服务人员、费用三张表串联起来所以状态机的设计必须非常清晰。我设计了五个状态待派单、已派单、执行中、待确认、已完成。只有“待确认”状态下可以修改实际服务时长这样月底结算时数据才不会有争议。3.2 数据表设计的关键决策在设计数据表时有几个决策现在回想起来特别关键。老人档案表我特意抽象出了一个“健康标签”字段用来快速筛选“独居”“失能”“高龄”等需要重点关注的人群而不是散落地存在多个布尔字段里。这个设计让首页的重点人群统计变得异常简单一个SQL查询就能搞定。服务工单表和费用表我用了软删除策略加了is_deleted字段。社区场景下工作人员误操作删数据太常见了软删除能保证数据审计可追溯月底对账时出现出入还能找回来。健康数据表则按月份做了分区虽然现在数据量不大但长者健康数据是长期累积的后续10年20年这个表会是最大的一张表提前规划没坏处。角色权限模型我用了最简单的RBAC基于角色的访问控制分管理员、网格员、服务人员、医护人员四个角色。管理员看全部数据网格员只能看自己负责楼栋的老人服务人员只看到派给自己的工单医护人员可以录入健康数据但改不了费用信息。这个权限模型在社区场景下够用再复杂就该上Flask-Principal或单独权限服务了没必要。3.3 数据库表结构核心SQL参考以下是我实际建表时的核心表结构去掉了多余字段保留了最关键的设计思路方便你直接参考-- 老人档案表 CREATE TABLE elder ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) NOT NULL, id_card VARCHAR(18) UNIQUE NOT NULL, birth_date DATE NOT NULL, address VARCHAR(200) NOT NULL, health_tags VARCHAR(100) COMMENT 健康标签如独居,失能,高龄, contact_name VARCHAR(50), contact_phone VARCHAR(20), grid_worker_id INT COMMENT 负责网格员ID, is_deleted TINYINT DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); -- 服务工单表 CREATE TABLE service_order ( id INT AUTO_INCREMENT PRIMARY KEY, order_no VARCHAR(32) UNIQUE NOT NULL COMMENT 工单编号, elder_id INT NOT NULL, service_type VARCHAR(50) NOT NULL COMMENT 送餐/保洁/陪诊/康复, status TINYINT DEFAULT 0 COMMENT 0待派单 1已派单 2执行中 3待确认 4已完成, assignee_id INT COMMENT 服务人员ID, scheduled_time DATETIME, actual_start_time DATETIME, actual_end_time DATETIME, content TEXT COMMENT 服务内容描述, satisfaction TINYINT COMMENT 满意度1-5, fee DECIMAL(10,2) DEFAULT 0, fee_type TINYINT DEFAULT 0 COMMENT 0自费 1政府补贴 2公益, is_deleted TINYINT DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP );设计上有个容易忽视的细节工单编号我用的是日期随机数的方式生成而不是简单的自增ID。因为社区工作人员经常会用手机拍工单号发到微信群里沟通短数字容易重复、也看不出日期信息格式化编号会更实用。4. 实操过程从零搭建核心模块4.1 开发环境准备与项目骨架开发前先把Python环境搞定。我在Windows上用VSCode做开发建议直接用Python官网的安装包安装时务必勾选“Add Python to PATH”那个选项这是新手最容易忽略的步骤。装完在终端敲python --version确认版本我这边用的Python 3.10对Flask 2.x和SQLAlchemy 2.x的兼容性最稳。工程结构我推荐按模块组织而不是按技术层组织。很多教程会把models、views、controllers分目录但Flask项目更适合按功能模块分——每个蓝图一个目录里面放自己的models、routes、templates新功能加一个目录就行老功能出问题也好定位community-elder/ ├── app.py # 入口文件初始化app ├── config.py # 配置文件 ├── extensions.py # db实例、login_manager等 ├── modules/ │ ├── auth/ # 登录认证模块 │ ├── elder/ # 老人档案模块 │ ├── order/ # 服务工单模块 │ └── health/ # 健康数据模块 ├── templates/ ├── static/ └── requirements.txt4.2 登录认证与权限控制的实现细节登录认证我用了Flask-Login 自定义装饰器没有引入Flask-JWT或Flask-Security。管理系统是内部使用的会话认证比Token认证简单得多也符合浏览器场景。这里有个安全细节值得强调密码一定要用werkzeug.security的generate_password_hash它内部默认使用pbkdf2算法加盐不要自己去写MD5或SHA系列的哈希那些都是可以暴力破解的。权限控制我写了一个自定义装饰器role_required(admin)在视图函数执行前检查当前用户的角色。这里踩过一个坑Flask-Login的current_user在请求上下文里才能正常访问装饰器如果写错了执行顺序会取不到。后来我统一在装饰器内部用flask_login.utils._get_user()来拿当前用户才彻底解决。4.3 老人档案模块的快速实现老人档案模块是其他所有功能的基石我优先做这个模块。前端用Bootstrap 4的卡片布局来展示老人列表支持按姓名、楼栋、健康标签搜索筛选新增和编辑共用同一个表单模板后端用一个validate_elder_form()函数统一处理校验逻辑。关键的小技巧是健康标签的存储方式。我在数据库里用逗号分隔存储比如独居,失能,高血压前端用checkbox多选。查询时SQL用FIND_IN_SET(失能, health_tags)来过滤。虽然这个设计不符合数据库第三范式但社区场景下标签种类固定、数量有限这种“反规范化”的做法让代码和页面都简洁很多查询性能也完全没问题。4.4 服务工单状态机的核心实现服务工单模块是逻辑最复杂的部分状态的推进必须靠后端校验不能让前端随意改。我封装了一个OrderService类统一处理状态变更逻辑class OrderService: ALLOWED_TRANSITIONS { 0: [1], # 待派单 - 已派单 1: [2], # 已派单 - 执行中 2: [3], # 执行中 - 待确认 3: [4], # 待确认 - 已完成 } staticmethod def transition(order, target_status, operator): if target_status not in OrderService.ALLOWED_TRANSITIONS.get(order.status, []): raise ValueError(非法的工单状态流转) # 额外校验操作人角色 if target_status 1 and operator.role ! admin: raise PermissionError(只有管理员可以派单) order.status target_status db.session.commit()ALLOWED_TRANSITIONS这个字典是状态机的核心它定义了所有合法路径其他路径一律拒绝。这样即使前端被人改了请求参数后端也不会执行非法状态跳转比如从“待派单”直接跳到“已完成”。状态变更同时记录到操作日志表用户角色的身份信息也一并存储出了问题可以快速追溯。这个模块还有一个容易忽略的坑两个操作员同时点击“派单”按钮如果代码里没有做状态校验可能会导致同一个工单被重复派给两个人。现在每次状态变更都是先查一次数据库、校验状态再更新配合MySQL的行锁基本可以避免并发问题。4.5 健康数据趋势图的轻量实现很多管理系统一说到图表就上ECharts但ECharts在前端引入还是挺重的。我的方案是后端用SQL按月分组统计平均值前端用Chart.js这个轻量级库画折线图。接口返回的JSON数据结构设计成[{month: 2024-01, avg_systolic: 135, avg_diastolic: 85}, ...]前端拿到直接绑定就可以。图表这块我个人建议管理系统里的图表越简单越好能一眼传达趋势就好不要做得太花哨。社区医生关心的是血压趋势有没有异常波动不是图表美不美观。健康数据的录入页面我特意做了“录入后自动刷新图表”的交互逻辑让工作人员感觉到数据是实时流转的使用意愿会高很多。5. 常见问题与排查技巧实录5.1 数据库中文乱码问题的处理这是整个项目里出现频率最高的问题。社区工作人员的电脑可能用的是Windows系统录入的中文数据存到MySQL后经常变成一堆问号。根本原因有两个一是数据表的字符集不是utf8mb4二是Python连接MySQL时没有指定字符集。解决办法分两步。建表时务必在CREATE DATABASE语句里指定CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci这是最稳妥的方式因为utf8mb4才是完整的UTF-8支持能存emojiMySQL里的utf8实际是utf8mb3存在兼容性隐患。第二步是在SQLAlchemy的连接串里加上?charsetutf8mb4参数SQLALCHEMY_DATABASE_URI mysqlpymysql://user:passwordlocalhost/community_elder?charsetutf8mb4如果你已经建了表才发现问题执行ALTER TABLE elder CONVERT TO CHARACTER SET utf8mb4;可以批量修复存量数据。5.2 时间字段的时区与格式化问题社区工作人员录入服务时间时经常出现“明明存的是下午2点查出来变成上午9点”的情况。这个问题出在Python和MySQL对时区的理解不一致。我的解决方案是MySQL连接串里追加init_commandSET time_zone8:00同时Python端所有时间操作统一用datetime.now()本地时间禁止使用datetime.utcnow()。另外还踩了一个小坑Jinja2模板里直接渲染datetime对象默认格式是2024-01-15 14:30:00这种格式对老年人居多的场景不够友好。我写了一个模板过滤器在展示时把2024-01-15 14:30格式化成1月15日 下午2:30这种文本页面看起来亲切得多。5.3 服务器部署后静态文件加载不出来本地开发一切正常部署到Ubuntu服务器后样式全丢了浏览器F12看到css返回404。绝大多数情况是Nginx配置问题。我用的配置是/static/路径映射到Flask应用的实际静态目录location /static/ { alias /home/ubuntu/community-elder/static/; }这里有个细节要小心alias路径末尾的/不能漏漏了会导致路径拼接出错。另一个可能性是Flask应用开启的是debug模式Flask在debug模式下是自己托管静态文件的但生产环境用Gunicorn跑需要明确告诉Flask静态文件放在哪或者在Nginx层面直接托管。5.4 服务工单并发重复派单问题虽然前面说了用状态校验解决并发问题但实际的社区场景里还有一个更隐蔽的情况两个管理员在同一个页面上同时登录都看到同一个工单是“待派单”状态A先点了派单给护工甲B看到页面还没刷新又点了派单给护工乙。这样数据库里就会出现两条同时刻的工单更新记录。要彻底解决这个问题我在service_order表加了version字段乐观锁更新时用UPDATE ... WHERE id? AND version旧版本号如果影响行数为0说明数据已被别人改过直接提示“该工单已被处理请刷新页面”。这个方案比给表加锁简单得多也符合社区系统的并发量级。5.5 系统在老旧电脑上运行卡顿的优化社区办公室的电脑配置普遍不高内存4G以下的还不少。系统运行一段时间后打开首页要好几秒换页也很卡。我做了两个优化一是把首页的统计SQL从多次查询合并成GROUP BY一次查出所有统计数值减少了数据库往返二是给Gunicorn设置--timeout 60避免worker被慢请求拖死。优化完首页从2.8秒降到了0.6秒左右体感提升非常明显。项目上线后社区工作人员反馈最多的就是“这个系统比我们原来用的Excel台账方便太多了”。现在每天的服务工单自动汇总成日报月底一键生成服务量和费用对账表健康数据异常的老人系统自动标红提醒网格员去随访。最近社区还提出想加上养老服务地图的功能这个系统后续还有不少可以扩展的地方。根据我个人的实际开发体会做这类垂直领域的管理系统核心不是技术本身有多高深而是能不能真正理解用户的业务场景。建议你在动手之前先花时间去社区待一两天看看工作人员平时是怎么办公的他们最头疼的环节是什么。把业务流程想清楚了代码实现反而是水到渠成的事。本文还有配套的精品资源点击获取
返回列表