作为一名有10年全栈开发经验的程序员,我最近完成了一个基于Node.js的演唱会路演活动报名小程序的全套开发工作。这个项目不仅包含了完整的前后端代码,还附带了详细的说明文档、毕业论文以及各种调试和定制服务。
这个小程序的核心功能是为演唱会、音乐节等路演活动提供在线报名服务。用户可以通过小程序浏览活动信息、在线报名、支付票款,而活动主办方则可以通过后台管理系统进行用户管理、活动发布和数据统计。
系统采用前后端分离的架构设计,前端使用微信小程序原生开发框架,后端基于Node.js构建,数据库选用MySQL。这种架构具有以下优势:
数据库采用MySQL 8.0,主要包含以下表:
用户可以通过手机号+验证码或微信授权登录两种方式注册登录系统。后端使用JWT进行身份验证,有效期为7天。
javascript复制// 用户登录接口示例
router.post('/login', async (req, res) => {
const { phone, code } = req.body;
// 验证短信验证码
const isValid = await verifySMSCode(phone, code);
if (!isValid) {
return res.status(400).json({ error: '验证码错误' });
}
// 查询或创建用户
let user = await User.findOne({ where: { phone } });
if (!user) {
user = await User.create({ phone });
}
// 生成JWT
const token = jwt.sign({ userId: user.id }, config.jwtSecret, { expiresIn: '7d' });
res.json({ token, user });
});
用户可以查看和修改个人信息,包括昵称、头像、联系方式等。个人信息修改后会自动同步到微信小程序的用户信息。
活动列表支持分页加载和多种筛选条件,如按时间、地点、类型等。为了提高性能,我们使用Redis缓存热门活动数据。
javascript复制// 获取活动列表接口
router.get('/events', async (req, res) => {
const { page = 1, size = 10, type, location } = req.query;
// 尝试从缓存获取
const cacheKey = `events:${page}:${size}:${type}:${location}`;
const cachedData = await redis.get(cacheKey);
if (cachedData) {
return res.json(JSON.parse(cachedData));
}
// 构建查询条件
const where = {};
if (type) where.type = type;
if (location) where.location = location;
// 查询数据库
const { count, rows } = await Event.findAndCountAll({
where,
offset: (page - 1) * size,
limit: parseInt(size),
order: [['startTime', 'ASC']]
});
// 缓存结果
await redis.setex(cacheKey, 3600, JSON.stringify({ count, events: rows }));
res.json({ count, events: rows });
});
活动详情页展示活动的完整信息,包括时间、地点、票价、活动介绍等。同时显示当前报名人数和剩余票数。
用户选择活动后可以填写报名信息并提交。系统会检查活动是否已满、用户是否已报名等条件。
javascript复制// 报名接口
router.post('/registrations', authMiddleware, async (req, res) => {
const { eventId, ticketType, quantity, info } = req.body;
const userId = req.user.id;
// 检查活动是否存在
const event = await Event.findByPk(eventId);
if (!event) {
return res.status(404).json({ error: '活动不存在' });
}
// 检查活动是否已开始或已结束
if (new Date() > new Date(event.endTime)) {
return res.status(400).json({ error: '活动已结束' });
}
// 检查剩余票数
if (event.remainingSeats < quantity) {
return res.status(400).json({ error: '剩余票数不足' });
}
// 检查用户是否已报名
const existingRegistration = await Registration.findOne({
where: { userId, eventId }
});
if (existingRegistration) {
return res.status(400).json({ error: '您已报名该活动' });
}
// 创建报名记录
const registration = await Registration.create({
userId,
eventId,
ticketType,
quantity,
info,
status: 'pending_payment'
});
// 更新活动剩余票数
await event.decrement('remainingSeats', { by: quantity });
res.json(registration);
});
用户可以查看自己的报名记录,包括已报名、已取消和已完成的活动。系统会显示每个报名状态的详细信息。
系统集成微信支付功能,用户可以在小程序内完成支付。支付成功后会自动更新报名状态。
javascript复制// 微信支付统一下单接口
router.post('/payments/create', authMiddleware, async (req, res) => {
const { registrationId } = req.body;
const userId = req.user.id;
// 查询报名记录
const registration = await Registration.findOne({
where: { id: registrationId, userId },
include: [Event]
});
if (!registration) {
return res.status(404).json({ error: '报名记录不存在' });
}
if (registration.status !== 'pending_payment') {
return res.status(400).json({ error: '当前状态不可支付' });
}
// 计算支付金额
const amount = registration.Event.price * registration.quantity * 100; // 转为分
// 调用微信支付统一下单
const result = await wxpay.unifiedOrder({
body: `${registration.Event.name}活动报名`,
out_trade_no: `REG${Date.now()}${Math.random().toString().substr(2, 6)}`,
total_fee: amount,
spbill_create_ip: req.ip,
notify_url: config.wxpayNotifyUrl,
trade_type: 'JSAPI',
openid: req.user.openid
});
// 创建支付记录
const payment = await Payment.create({
registrationId,
amount,
status: 'pending',
transactionId: result.prepay_id,
paymentMethod: 'wechat'
});
// 返回支付参数
res.json({
timeStamp: Math.floor(Date.now() / 1000).toString(),
nonceStr: Math.random().toString(36).substr(2),
package: `prepay_id=${result.prepay_id}`,
signType: 'MD5',
paySign: generatePaySign(result.prepay_id)
});
});
微信支付成功后,微信服务器会回调我们的接口,我们需要验证回调并更新订单状态。
javascript复制// 微信支付回调接口
router.post('/payments/notify', async (req, res) => {
const { return_code, result_code, out_trade_no, transaction_id } = req.body;
// 验证签名
if (!wxpay.verifySign(req.body)) {
return res.send('<xml><return_code><![CDATA[FAIL]]></return_code></xml>');
}
if (return_code === 'SUCCESS' && result_code === 'SUCCESS') {
// 查询支付记录
const payment = await Payment.findOne({
where: { transactionId: out_trade_no.substr(3) }
});
if (payment && payment.status === 'pending') {
// 更新支付状态
await payment.update({
status: 'completed',
paidAt: new Date(),
transactionId: transaction_id
});
// 更新报名状态
await Registration.update(
{ status: 'confirmed' },
{ where: { id: payment.registrationId } }
);
}
}
res.send('<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>');
});
后台管理系统提供完整的活动管理功能,包括:
管理员可以查看和管理用户信息,包括:
系统提供丰富的数据统计功能,帮助主办方了解活动效果:
在选择技术栈时,我们主要考虑了以下几个因素:
在热门演唱会开售时,可能会出现大量用户同时报名的情况。我们通过以下方式应对:
微信支付集成过程中遇到的主要问题是支付状态同步。我们的解决方案是:
通过这个项目的开发,我们积累了以下经验:
这个系统还有很大的扩展空间,未来可以考虑:
在实际开发过程中,我们发现小程序+Node.js的技术组合非常适合这类活动报名系统。开发效率高,性能表现好,用户体验佳。对于计算机专业的同学来说,这是一个很好的毕业设计选题方向,涵盖了前后端开发的各个方面,具有很好的学习和实践价值。