1. 项目背景与核心需求
这个项目本质上是一个旅游景区电商系统的全栈实现,后端采用Python Flask框架,前端使用UniApp开发微信小程序。从技术架构来看,它需要解决几个核心问题:
- 景区商品展示与分类管理(熊猫主题周边、门票等)
- 微信生态下的用户授权与支付闭环
- 高并发场景下的订单处理稳定性
- 移动端与后台管理的数据同步
我去年为成都某熊猫基地实施过类似系统,发现旅游景区电商有几个特殊需求:
- 季节性流量波动极大(节假日订单量可能是平日的10倍)
- 商品具有强地域属性(比如熊猫玩偶在不同园区需要显示不同库存)
- 需要支持线下核销(电子门票的二维码验证)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术栈选型分析
2.1 为什么选择Flask而非Django
对于中小型电商项目,Flask的轻量化特性更具优势:
- 更灵活的路由定义方式(适合微信小程序API的RESTful设计)
- 与微信支付SDK的集成更轻量
- 项目初期可以按需引入扩展(Flask-SQLAlchemy、Flask-Login等)
关键代码结构示例:
python复制# 商品模块蓝图
from flask import Blueprint
product_bp = Blueprint('product', __name__)
@product_bp.route('/api/products')
def get_products():
# 实现分页查询逻辑
pass
2.2 UniApp的跨端优势
选择UniApp主要考虑:
- 一套代码同时覆盖微信小程序和H5(景区官网用)
- 内置的uni-ui组件库加速开发
- 更好的性能优化方案(如自动图片压缩)
需要注意的坑:
- 微信小程序分包加载需要特殊配置
- 支付接口需要区分微信环境和H5环境
- 部分CSS属性在小程序端需要前缀
3. 核心功能实现细节
3.1 微信登录与用户体系设计
微信小程序登录流程需要特别注意:
- 前端调用wx.login获取code
- 将code传给后端换取openid
- 服务端生成自定义登录态(建议JWT)
安全建议:
- 一定要校验微信返回的签名
- openid不要直接暴露给前端
- 会话有效期建议设置为7天
用户表设计示例:
sql复制CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`openid` varchar(32) NOT NULL COMMENT '微信唯一标识',
`session_key` varchar(64) DEFAULT NULL,
`nickname` varchar(64) DEFAULT NULL,
`avatar` varchar(255) DEFAULT NULL,
`last_login` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_openid` (`openid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3.2 商品与库存管理
景区商品的特殊性处理:
- 设置不同仓库对应不同园区
- 预售商品需要单独标记
- 电子门票类商品需要关联日期
库存扣减的原子操作:
python复制@app.route('/api/order/create', methods=['POST'])
def create_order():
try:
# 开启事务
db.session.begin()
# 1. 检查库存
product = Product.query.with_for_update().get(product_id)
if product.stock < quantity:
raise Exception("库存不足")
# 2. 扣减库存
product.stock -= quantity
db.session.add(product)
# 3. 创建订单
order = Order(...)
db.session.add(order)
db.session.commit()
return jsonify({"code": 0})
except Exception as e:
db.session.rollback()
return jsonify({"code": -1, "msg": str(e)})
4. 微信支付集成实战
4.1 支付配置要点
- 小程序后台需要配置合法域名
- 商户号需要开通JSAPI支付
- 服务器IP要加入白名单
支付流程关键代码:
javascript复制// 小程序端
uni.requestPayment({
provider: 'wxpay',
timeStamp: String(Date.now()),
nonceStr: '随机字符串',
package: 'prepay_id=' + prepay_id,
signType: 'MD5',
paySign: 签名,
success: (res) => { /* 支付成功 */ },
fail: (err) => { /* 处理失败 */ }
});
4.2 支付结果通知处理
Flask端需要:
- 验证微信签名
- 处理重复通知
- 更新订单状态
建议使用异步任务处理:
python复制from celery import Celery
celery = Celery('tasks', broker='redis://localhost:6379/0')
@celery.task
def handle_payment_notify(transaction_id):
# 查询微信支付订单状态
# 更新本地订单
# 必要时触发库存同步
5. 性能优化实践
5.1 缓存策略
-
商品详情使用Redis缓存
python复制from flask_caching import Cache cache = Cache(config={'CACHE_TYPE': 'Redis'}) @app.route('/api/product/<int:id>') @cache.cached(timeout=300) def get_product(id): return Product.query.get_or_404(id).to_dict() -
微信session_key缓存
-
首页数据预加载
5.2 数据库优化
- 建立合适的索引:
- 商品表的分类ID
- 订单表的用户ID和创建时间
- 读写分离配置
- 慢查询监控
6. 实际部署经验
6.1 服务器配置建议
最低配置要求:
- 2核4G内存(突发流量需要自动扩容)
- 带宽建议5Mbps以上
- 需要HTTPS证书
部署工具推荐:
- Gunicorn + Nginx反向代理
- Supervisor管理进程
- Sentry错误监控
6.2 微信小程序审核要点
容易导致审核失败的问题:
- 实际商品与类目不符
- 支付流程不完整
- 缺少用户隐私协议
- 虚拟商品未明确标识
建议:
- 首次提交时先隐藏支付功能
- 准备完整测试账号
- 电子门票类需要提供资质证明
7. 扩展功能建议
根据景区实际需求可以增加:
- AR熊猫互动(通过小程序摄像头)
- 游览路线规划
- 会员积分体系
- 拼团购票功能
实现示例(路线规划):
javascript复制// 小程序端获取当前位置
uni.getLocation({
type: 'gcj02',
success: (res) => {
// 计算到各个展馆的距离
// 生成最优路线
}
});
这个项目最关键的体会是:景区电商系统必须考虑线下场景的特殊性。比如我们遇到过游客在弱网环境下无法加载二维码的情况,最终解决方案是:
- 生成离线可验证的二维码
- 售票处部署本地缓存服务器
- 增加短信备用验证通道
