1. 项目概述与设计背景
社区养老服务系统是针对老龄化社会需求设计的一套数字化解决方案。随着我国老年人口比例持续攀升,传统养老模式已难以满足多样化需求。我在实际开发中发现,许多社区服务中心仍在使用纸质登记本记录老人健康数据,服务预约全靠电话沟通,这种低效模式亟需改变。
本项目采用前后端分离架构,前端使用Vue.js 3构建响应式界面,后端组合Django REST framework和Flask实现API服务。这种技术选型主要基于三点考虑:首先,Vue的渐进式特性适合快速迭代养老系统这类业务逻辑复杂的项目;其次,Django ORM能高效处理关系型数据(如老人健康档案),而Flask的轻量化特性适合处理紧急呼叫等实时性要求高的微服务;最后,PyCharm的专业版对这两种框架都有完善的支持。
系统核心价值体现在三个维度:
- 对老人:整合健康监测、紧急救助等刚需功能,降低智能设备使用门槛
- 对家属:实时掌握老人动态,远程完成服务预约和支付
- 对社区:数字化管理服务资源,精准匹配供需关系
2. 技术架构详解
2.1 前端技术栈设计
前端采用Vue 3的组合式API+TypeScript方案,具体实现中有几个关键设计点:
- 无障碍访问优化:通过vue-announcer插件实现屏幕阅读器支持,所有交互按钮都添加ARIA标签。实测发现,老年用户对字体缩放需求强烈,因此采用CSS相对单位(rem)配合vue-responsive插件实现全局字体控制:
typescript复制// 字体缩放控制器
const fontSize = ref(1)
provide('fontSize', fontSize)
watch(fontSize, (val) => {
document.documentElement.style.fontSize = `${val * 62.5%}`
})
- 状态管理方案:对比Vuex和Pinia后,最终选择Pinia。在养老系统中,健康数据需要跨组件共享,Pinia的TypeScript支持和更简单的API显著提升开发效率。典型store结构如下:
typescript复制// stores/health.ts
export const useHealthStore = defineStore('health', {
state: () => ({
bloodPressure: [] as HealthRecord[],
heartRate: [] as HealthRecord[]
}),
actions: {
async fetchData(olderId: string) {
const res = await api.getHealthData(olderId)
this.bloodPressure = res.bloodPressure
//...
}
}
})
2.2 后端服务架构
后端采用混合架构模式,这是经过多个项目验证的稳定方案:
-
Django主体服务:处理用户管理、服务预约等核心业务。关键配置包括:
- 使用django-allauth实现多角色认证(老人/家属/管理员)
- 配置DRF的限流策略防止恶意请求:
python复制# settings.py REST_FRAMEWORK = { 'DEFAULT_THROTTLE_RATES': { 'emergency': '5/min', # 紧急呼叫限流 'default': '1000/day' } }
-
Flask微服务集群:独立部署的模块包括:
- 实时消息推送服务(WebSocket)
- 健康数据分析服务(Pandas+Numpy)
- 第三方支付对接服务
这种架构的优势在于:当健康数据分析需要升级算法时,可以单独重启Flask服务而不影响主系统运行。实测中,这种设计使系统整体可用性达到99.95%。
3. 核心功能实现细节
3.1 健康监测模块
该模块需要对接多种智能设备(血压仪、手环等),开发中遇到三个典型问题及解决方案:
-
设备协议多样性:通过抽象设备驱动层解决。定义统一接口:
python复制class HealthDevice(ABC): @abstractmethod def connect(self, config: dict) -> bool: ... @abstractmethod def fetch_data(self) -> HealthData: ...具体设备实现如OmronBPDriver(HealthDevice)。在系统配置中注册驱动:
yaml复制devices: blood_pressure: driver: OmronBPDriver config: com_port: COM3 baudrate: 9600 -
数据可视化性能:当老人有多年历史数据时,前端渲染折线图会卡顿。最终采用两种优化:
- 后端数据降采样:当时间范围>1年时,使用Pandas的resample方法降低数据密度
- 前端虚拟滚动:只渲染可视区域内的数据点
-
异常值检测:开发中曾出现设备传输错误导致血压值异常(如300mmHg)。后加入基于统计学规则的校验:
python复制def validate_bp(systolic, diastolic): if not (60 <= diastolic < systolic <= 250): raise ValidationError("血压值超出合理范围") if (systolic - diastolic) < 20: raise ValidationError("脉压差过小")
3.2 紧急呼叫系统
这是项目的关键功能,技术实现要点包括:
-
多通道通知:当触发紧急呼叫时,系统会同时:
- 向家属APP推送通知(Firebase Cloud Messaging)
- 发送短信(阿里云短信API)
- 自动拨打预设电话(Twilio语音呼叫)
-
位置追踪优化:初期使用HTML5 Geolocation API,但在室内场景误差大。改进方案:
- 优先获取设备GPS数据(通过蓝牙连接的智能手环)
- 次选Wi-Fi指纹定位
- 最后回退到用户档案中的常住地址
核心代码逻辑:
python复制def handle_emergency(user_id):
user = User.objects.get(pk=user_id)
location = get_location(user) # 综合定位策略
# 并发执行所有通知方式
with ThreadPoolExecutor() as executor:
executor.submit(send_push, user.family_members)
executor.submit(send_sms, user.emergency_contacts)
executor.submit(make_phone_call, user.phone)
# 记录事件日志
EmergencyEvent.objects.create(
user=user,
location=location,
status='pending'
)
4. 部署与性能优化
4.1 生产环境配置
经过压力测试,最终采用的服务器配置:
-
前端服务:
- Nginx配置gzip压缩和静态资源缓存
- 开启HTTP/2提升多资源加载速度
- 关键配置片段:
nginx复制server { listen 443 ssl http2; gzip on; gzip_types text/plain application/json application/javascript; location / { root /var/www/vue-app; try_files $uri $uri/ /index.html; } }
-
后端服务:
- Django使用Gunicorn+Gevent部署
- Flask服务使用Waitress
- PostgreSQL配置连接池:
python复制# settings.py DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'OPTIONS': { 'options': '-c search_path=public,shared', 'sslmode': 'require', 'pool_size': 20 # 连接池大小 } } }
4.2 安全防护措施
养老系统涉及敏感健康数据,我们实施了多层防护:
-
数据传输安全:
- 全站HTTPS(TLS 1.3)
- 敏感接口额外加密(如健康数据使用AES-256-GCM)
-
访问控制:
- JWT令牌设置15分钟过期
- 关键操作需要二次验证(如短信验证码)
-
数据脱敏:
python复制class OlderInfoSerializer(serializers.ModelSerializer): def to_representation(self, instance): data = super().to_representation(instance) if not self.context['is_admin']: data['id_number'] = mask_id_number(data['id_number']) return data
5. 典型问题排查实录
5.1 内存泄漏问题
在压力测试时发现,长时间运行后Django服务内存持续增长。通过以下步骤定位:
-
使用mprof记录内存变化:
bash复制
mprof run --python python manage.py runserver -
发现每处理1000次健康数据API调用,内存增加约2MB
-
使用objgraph定位到是Pandas DataFrame未及时释放:
python复制# 错误示例 def get_health_report(): data = pd.read_sql(...) # 没有主动释放 return data.to_json() # 修正方案 def get_health_report(): with closing(pd.read_sql(...)) as data: return data.to_json()
5.2 跨域会话失效
前端在Safari浏览器出现频繁登录失效。根本原因是:
- Safari的智能防跟踪功能会默认阻止第三方Cookie
- 我们的JWT refresh_token依赖Cookie存储
解决方案:
- 对于API请求,显式设置SameSite=None和Secure
python复制response.set_cookie( 'refresh_token', httponly=True, secure=True, samesite='None' ) - 前端检测到Safari时,改用localStorage存储refresh_token
6. 无障碍设计实践
针对老年用户的特点,我们实施了以下增强设计:
-
视觉优化:
- 颜色对比度至少4.5:1(通过WCAG标准检测)
- 所有操作按钮不小于48×48物理像素
-
语音交互:
- 集成语音合成(TTS)和识别(ASR):
vue复制<script setup> const speech = useSpeechRecognition({ continuous: true, lang: 'zh-CN' }) </script> <template> <button @click="speech.start"> <IconMic /> <span v-if="speech.isListening">聆听中...</span> </button> </template> -
操作简化:
- 紧急呼叫实现"一键触发",即使锁屏状态下也可通过物理按键激活
- 所有表单提供大字号模式和语音引导
在用户测试阶段,这些改进使65岁以上用户的操作成功率从58%提升到92%。