1. 项目概述与技术选型
这个动物医院管理系统采用前后端分离架构,后端使用Python+Flask作为主要框架,Django作为辅助方案,前端基于Vue3+Element Plus构建响应式界面。系统主要面向中小型宠物医院,解决日常运营中的患者管理、预约挂号等核心业务需求。
为什么选择这样的技术组合?在实际开发中我们发现:
- Flask轻量灵活,适合快速构建RESTful API
- Django的ORM和Admin在需要复杂数据管理时可以作为补充
- Vue3的Composition API让前端组件开发更高效
- Element Plus提供了丰富的UI组件,特别适合管理系统开发
技术选型心得:对于中小型项目,这种混合技术栈既能保证开发效率,又能在特定场景下利用不同框架的优势。不过需要注意框架间的兼容性问题,特别是会话管理和数据序列化方面。
2. 系统架构设计
2.1 模块划分与功能设计
系统主要分为两大核心模块:
患者管理模块
- 宠物档案管理:记录品种、年龄、体重等基本信息
- 病历系统:支持图文病历记录和查询
- 就诊历史:按时间轴展示完整诊疗记录
预约挂号模块
- 医生排班管理:可视化排班界面
- 分时段预约:精确到15分钟一个时段
- 预约提醒:短信/邮件通知功能
数据库设计采用MySQL,主要表结构包括:
- pets(宠物信息表)
- medical_records(病历表)
- doctors(医生表)
- appointments(预约表)
2.2 技术架构图
code复制前端(Vue3) ← HTTP → Flask API层 ←→ MySQL数据库
↑
Django Admin(可选)
这种架构的优势在于:
- 前后端完全解耦,便于独立开发和部署
- Flask提供轻量级API服务
- 需要复杂后台管理时,可快速集成Django Admin
- Vue3的前端性能优异,用户体验好
3. 开发环境配置
3.1 后端环境搭建
使用PyCharm创建Python虚拟环境:
bash复制python -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windows
安装核心依赖:
bash复制pip install flask flask-restx sqlalchemy flask-sqlalchemy flask-marshmallow marshmallow-sqlalchemy
如果需要使用Django作为补充:
bash复制pip install django djangorestframework
3.2 前端环境配置
使用Vite初始化Vue项目:
bash复制npm create vite@latest animal-hospital --template vue
cd animal-hospital
npm install element-plus axios vue-router
配置axios基础实例:
javascript复制// src/utils/request.js
import axios from 'axios'
const service = axios.create({
baseURL: 'http://localhost:5000/api',
timeout: 10000
})
// 请求拦截器
service.interceptors.request.use(config => {
config.headers['Authorization'] = localStorage.getItem('token') || ''
return config
})
export default service
4. 核心功能实现
4.1 患者管理API实现
Flask后端代码示例:
python复制# app/api/pets.py
from flask_restx import Namespace, Resource, fields
from app.models import Pet
from app import db
api = Namespace('pets', description='宠物相关操作')
pet_model = api.model('Pet', {
'id': fields.Integer(readOnly=True),
'name': fields.String(required=True),
'breed': fields.String(required=True),
'age': fields.Integer(required=True),
'owner_id': fields.Integer(required=True)
})
@api.route('/')
class PetList(Resource):
@api.marshal_list_with(pet_model)
def get(self):
"""获取所有宠物列表"""
return Pet.query.all()
@api.expect(pet_model)
@api.marshal_with(pet_model)
def post(self):
"""创建新宠物档案"""
data = api.payload
pet = Pet(**data)
db.session.add(pet)
db.session.commit()
return pet, 201
4.2 预约挂号前端实现
Vue组件示例:
vue复制<template>
<div class="appointment-container">
<el-calendar v-model="currentDate">
<template #dateCell="{data}">
<div class="date-cell">
<div class="day-number">{{ data.day.split('-')[2] }}</div>
<div
v-for="slot in timeSlots"
:key="slot"
class="time-slot"
:class="{'booked': isBooked(data.day, slot)}"
@click="handleSlotClick(data.day, slot)"
>
{{ slot }}
</div>
</div>
</template>
</el-calendar>
<el-dialog v-model="dialogVisible" title="预约确认">
<!-- 预约表单内容 -->
</el-dialog>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
import { getAppointmentsByDate } from '@/api/appointment'
const currentDate = ref(new Date())
const appointments = ref([])
const timeSlots = [
'09:00', '09:15', '09:30', ..., '17:45'
]
const isBooked = (day, time) => {
return appointments.value.some(
app => app.date === day && app.time === time
)
}
const fetchAppointments = async (date) => {
try {
const res = await getAppointmentsByDate(date)
appointments.value = res.data
} catch (error) {
console.error('获取预约数据失败:', error)
}
}
// 监听日期变化
watch(currentDate, (newVal) => {
const dateStr = newVal.toISOString().split('T')[0]
fetchAppointments(dateStr)
})
</script>
5. 数据交互设计
5.1 API规范设计
采用统一的响应格式:
json复制{
"code": 200,
"message": "success",
"data": {...},
"timestamp": "2023-08-20T10:00:00Z"
}
错误处理示例:
python复制from flask import jsonify
@app.errorhandler(404)
def not_found(error):
return jsonify({
'code': 404,
'message': 'Resource not found',
'data': None
}), 404
5.2 数据序列化
使用Flask-Marshmallow进行数据序列化:
python复制from flask_marshmallow import Marshmallow
ma = Marshmallow(app)
class PetSchema(ma.SQLAlchemyAutoSchema):
class Meta:
model = Pet
load_instance = True
pet_schema = PetSchema()
pets_schema = PetSchema(many=True)
6. 测试与部署
6.1 测试策略
后端测试
python复制import pytest
from app import create_app
from app.models import db, Pet
@pytest.fixture
def client():
app = create_app('testing')
with app.test_client() as client:
with app.app_context():
db.create_all()
yield client
with app.app_context():
db.drop_all()
def test_create_pet(client):
response = client.post('/api/pets', json={
'name': 'Buddy',
'breed': 'Golden Retriever',
'age': 3,
'owner_id': 1
})
assert response.status_code == 201
assert 'Buddy' in response.json['name']
前端测试
javascript复制import { mount } from '@vue/test-utils'
import AppointmentCalendar from '@/components/AppointmentCalendar.vue'
test('renders time slots correctly', () => {
const wrapper = mount(AppointmentCalendar)
expect(wrapper.findAll('.time-slot').length).toBe(36) // 9:00-17:45 每15分钟一个时段
})
6.2 部署方案
生产环境部署
- 后端使用Gunicorn+Nginx:
bash复制gunicorn -w 4 -b 0.0.0.0:5000 app:app
- 前端构建静态文件:
bash复制npm run build
- Nginx配置示例:
nginx复制server {
listen 80;
server_name hospital.example.com;
location / {
root /path/to/dist;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://localhost:5000;
proxy_set_header Host $host;
}
}
7. 开发经验与避坑指南
7.1 跨域问题解决
开发阶段常见的跨域问题解决方案:
python复制from flask_cors import CORS
app = Flask(__name__)
CORS(app, resources={
r"/api/*": {
"origins": ["http://localhost:3000"],
"methods": ["GET", "POST", "PUT", "DELETE"],
"allow_headers": ["Content-Type", "Authorization"]
}
})
注意事项:生产环境应该通过Nginx反向代理解决跨域,而不是依赖CORS扩展。
7.2 数据库迁移管理
使用Flask-Migrate进行数据库迁移:
bash复制flask db init
flask db migrate -m "initial migration"
flask db upgrade
常见问题:
- 迁移文件冲突:删除旧的迁移文件重新生成
- 字段修改不生效:检查模型定义是否正确定义了nullable等参数
7.3 性能优化技巧
- API响应缓存:
python复制from flask_caching import Cache
cache = Cache(config={'CACHE_TYPE': 'SimpleCache'})
cache.init_app(app)
@api.route('/pets')
class PetList(Resource):
@cache.cached(timeout=60)
def get(self):
return Pet.query.all()
- 前端懒加载:
javascript复制const AppointmentCalendar = defineAsyncComponent(() =>
import('./components/AppointmentCalendar.vue')
)
8. 项目扩展方向
在实际使用中,可以考虑以下扩展:
- 医疗影像管理:集成DICOM影像查看功能
- 药品库存管理:添加药品进销存系统
- 数据分析看板:使用ECharts实现诊疗数据可视化
- 移动端适配:开发响应式布局或单独移动应用
技术实现建议:
- 复杂后台管理可以逐步迁移到Django Admin
- 实时通知功能可集成WebSocket
- 大数据分析可以考虑添加Pandas支持
这个项目最让我有成就感的是将Flask的简洁与Vue的响应式完美结合,开发效率比传统全栈框架高出许多。特别是在快速迭代阶段,前后端分离架构让团队成员可以并行工作,大大缩短了开发周期。