1. 项目背景与需求分析
最近在做一个挺有意思的毕业设计项目——基于Python Flask框架的微信小程序"厕所厕ce"公共厕所管理系统。这个项目的核心目标是解决城市公共厕所管理中的几个痛点问题:厕所位置信息不透明、卫生状况难以实时监控、用户反馈渠道不畅。
在实际开发过程中,我发现这类系统要真正落地使用,需要解决三个关键问题:
- 如何实现厕所地理信息的精准采集与动态更新
- 怎样设计合理的卫生状况评价体系
- 用户反馈机制如何与管理员运维流程无缝衔接
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 整体技术栈选型
整个系统采用前后端分离架构:
- 前端:微信小程序(使用WXML+WXSS+JavaScript)
- 后端:Python Flask框架
- 数据库:MySQL 8.0
- 地图服务:腾讯位置服务API
选择Flask主要考虑到:
- 轻量级框架适合毕业设计规模的项目
- Python生态有丰富的地理信息处理库
- 与微信小程序对接的成熟解决方案多
2.2 核心功能模块设计
系统主要包含四大模块:
-
厕所信息管理模块
- 基础信息维护
- 地理位置服务
- 图片上传功能
-
卫生评价模块
- 星级评分系统
- 评价内容管理
- 实时数据统计
-
用户反馈模块
- 问题上报
- 处理进度查询
- 结果评价
-
管理员后台
- 数据可视化
- 工单管理
- 报表生成
3. 关键实现细节
3.1 微信小程序与Flask后端对接
小程序端采用wx.request方法调用后端API,需要注意的几个关键点:
python复制# Flask后端示例路由
@app.route('/api/toilet/list', methods=['GET'])
def get_toilet_list():
# 获取查询参数
longitude = request.args.get('lng')
latitude = request.args.get('lat')
radius = request.args.get('radius', default=1000, type=int)
# 执行空间查询
toilets = Toilet.query.filter(
func.st_distance_sphere(
Toilet.location,
func.point(longitude, latitude)
) <= radius
).all()
return jsonify([t.to_dict() for t in toilets])
重要提示:微信小程序要求所有请求必须是HTTPS,开发阶段可以使用微信开发者工具的"不校验合法域名"选项,但上线前必须配置好SSL证书。
3.2 地理空间数据处理
使用MySQL的空间扩展功能存储厕所位置信息:
sql复制-- 建表语句
CREATE TABLE toilets (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
address VARCHAR(255),
location POINT SRID 4326 NOT NULL,
SPATIAL INDEX(location)
);
Python端使用GeoAlchemy2进行空间查询:
python复制from geoalchemy2 import functions as geofunc
# 添加空间索引
db.session.execute(text('CREATE SPATIAL INDEX idx_location ON toilets(location)'))
# 查询5公里范围内的厕所
query = db.session.query(Toilet).filter(
geofunc.ST_Distance_Sphere(
Toilet.location,
geofunc.ST_MakePoint(116.404, 39.915)
) <= 5000
)
3.3 卫生评价系统实现
采用复合评分算法:
- 基础分:管理员定期检查评分(权重40%)
- 动态分:用户实时评价均值(权重60%)
- 惩罚项:近期投诉次数(每次扣0.5分)
python复制def calculate_score(toilet_id):
toilet = Toilet.query.get(toilet_id)
# 获取基础分
base_score = toilet.base_score * 0.4
# 计算用户评价均值
avg_review = db.session.query(
func.avg(Review.rating)
).filter_by(toilet_id=toilet_id).scalar() or 5
dynamic_score = avg_review * 0.6
# 计算投诉扣分
complaint_count = Complaint.query.filter_by(
toilet_id=toilet_id,
status='unresolved',
created_at > datetime.now() - timedelta(days=7)
).count()
penalty = complaint_count * 0.5
total = max(0, min(5, base_score + dynamic_score - penalty))
toilet.current_score = round(total, 1)
db.session.commit()
return total
4. 开发中的难点与解决方案
4.1 微信小程序地图选点精度问题
初期直接使用wx.chooseLocation API获取的坐标精度不够,特别是室内厕所定位偏差较大。最终解决方案:
- 增加手动标注功能
- 结合WiFi指纹定位补偿
- 引入纠偏算法处理室内坐标
javascript复制// 小程序端改进后的选点代码
Page({
chooseLocation: function() {
wx.chooseLocation({
success: (res) => {
// 获取更精确的室内定位
wx.startWifi({
success: () => {
wx.getWifiList({
success: (wifiRes) => {
this.correctPosition(res, wifiRes.wifiList)
}
})
}
})
}
})
},
correctPosition: function(loc, wifiList) {
// 实现定位纠偏算法
// ...
}
})
4.2 图片上传与压缩处理
用户上传的厕所现场图片需要处理两个问题:
- 图片体积过大
- 可能包含不合适内容
解决方案:
- 小程序端使用wx.compressImage API先压缩
- 后端使用Pillow进行二次处理
- 接入内容安全API进行审核
python复制from PIL import Image
import io
@app.route('/api/upload', methods=['POST'])
def upload_image():
file = request.files['image']
# 读取图片
img = Image.open(io.BytesIO(file.read()))
# 调整尺寸
if max(img.size) > 1024:
ratio = 1024 / max(img.size)
new_size = (int(img.size[0]*ratio), int(img.size[1]*ratio))
img = img.resize(new_size, Image.ANTIALIAS)
# 质量压缩
output = io.BytesIO()
img.save(output, format='JPEG', quality=70)
# 保存到云存储
# ...
5. 系统优化与扩展思考
5.1 性能优化实践
在压力测试中发现的两个性能瓶颈及解决方案:
-
地图页列表加载慢:
- 添加空间索引
- 实现分页加载
- 使用Redis缓存热门区域数据
-
评分计算耗时:
- 改为异步任务
- 使用增量计算
- 添加结果缓存
python复制# 使用Celery实现异步评分计算
@celery.task
def async_calculate_score(toilet_id):
calculate_score(toilet_id)
# 视图函数中调用
@app.route('/api/review', methods=['POST'])
def submit_review():
# ...保存评价逻辑
async_calculate_score.delay(toilet_id)
return jsonify({'status': 'success'})
5.2 可能的扩展方向
-
物联网集成:
- 接入智能传感器监测厕所异味、人流量
- 自动触发清洁工单
-
智能推荐:
- 基于用户历史行为推荐最优厕所
- 考虑排队时间、卫生评分、距离等因素
-
管理端增强:
- 清洁人员路线规划
- 耗材使用预测
- 异常情况预警
6. 项目部署注意事项
6.1 生产环境配置要点
-
Flask配置优化:
python复制app.config.update( JSONIFY_PRETTYPRINT_REGULAR=False, # 关闭美化输出 SQLALCHEMY_ENGINE_OPTIONS={ 'pool_size': 10, 'max_overflow': 5, 'pool_recycle': 3600 } ) -
Nginx反向代理配置:
nginx复制location / { proxy_pass http://127.0.0.1:5000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # WebSocket支持 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
6.2 微信小程序上线准备
- 域名备案与HTTPS配置
- 接口权限申请:
- 用户位置信息
- 相册/摄像头权限
- 网络请求权限
- 内容安全配置:
- 敏感词过滤
- 图片内容检测
- 隐私政策配置
7. 开发经验总结
在完成这个项目的过程中,有几个特别值得分享的经验:
- 空间数据处理要尽早建立索引,否则后期性能问题很难排查
- 微信小程序的地图API有诸多限制,需要仔细阅读文档
- 用户生成内容(UGC)系统必须考虑审核机制
- Flask的轻量级特性既是优势也是挑战,需要自行处理很多中间件集成
一个比较实用的调试技巧:在开发地图相关功能时,可以先用模拟器测试各种边界情况,比如:
- 国际日期变更线附近的坐标
- 南北极区域的坐标
- 海拔差异大的区域
- 室内外定位切换场景
