1. 项目背景与核心价值
武术作为中国传统文化的重要组成部分,近年来在校园教育和社会培训中越来越受到重视。武汉设计工程学院(简称"武设")的武术专业一直致力于推广武术文化,但传统的线下招生和课程管理方式存在诸多不便。这个小程序项目正是为了解决以下痛点:
- 信息不对称:潜在学员难以全面了解武术课程体系
- 报名流程繁琐:线下报名需要多次往返,效率低下
- 教学互动不足:课后缺乏持续的学习资源支持
- 管理成本高:人工统计学员信息、排课等工作量大
这个小程序实现了武术课程的线上展示、报名、管理和互动全流程,特别适合作为高校计算机相关专业的毕业设计选题。它涵盖了微信小程序开发的典型技术栈,包括:
- 前端:WXML/WXSS基础框架
- 后端:Node.js + MySQL经典组合
- 特色功能:微信支付集成、地理位置服务、消息模板推送
提示:选择武术主题作为毕设项目,既符合传统文化推广需求,又能展现技术实力,比常见的电商、社交类选题更具特色和实际意义。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计
2.1 技术选型分析
针对武术培训班的需求特点,我们采用了分层架构设计:
code复制客户端层
├─ 微信小程序
│ ├─ 首页:课程展示/轮播图
│ ├─ 详情页:课程介绍/师资展示
│ ├─ 报名页:表单填写/支付
│ └─ 个人中心:订单管理/学习记录
│
服务层
├─ API接口
│ ├─ 微信登录鉴权
│ ├─ 支付回调处理
│ └─ 消息模板推送
│
数据层
├─ MySQL
│ ├─ 课程表
│ ├─ 订单表
│ └─ 用户表
选择这套技术栈主要基于三点考虑:
- 微信小程序生态成熟,文档丰富,适合毕设时间有限的情况
- Node.js开发效率高,与小程序天然契合
- MySQL关系型数据库能很好处理课程-学员多对多关系
2.2 数据库ER图关键设计
武术培训班的核心数据关系体现在以下几个表:
courses表(课程主表)
sql复制CREATE TABLE `courses` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL COMMENT '课程名称',
`cover_img` varchar(255) NOT NULL COMMENT '封面图URL',
`price` decimal(10,2) NOT NULL COMMENT '课程价格',
`class_time` varchar(50) NOT NULL COMMENT '上课时间',
`teacher_id` int(11) NOT NULL COMMENT '授课教练',
`max_students` int(11) NOT NULL COMMENT '最大人数',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
orders表(订单表)
sql复制CREATE TABLE `orders` (
`order_id` varchar(32) NOT NULL COMMENT '微信支付订单号',
`user_id` int(11) NOT NULL COMMENT '用户ID',
`course_id` int(11) NOT NULL COMMENT '课程ID',
`pay_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0未支付 1已支付',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`order_id`),
KEY `idx_user` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
这种设计保证了:
- 课程信息与订单分离,避免数据冗余
- 通过外键关联保持数据一致性
- 为高频查询建立合适索引
3. 核心功能实现细节
3.1 微信登录与用户鉴权
武术培训班需要获取用户基本信息来实现个性化服务,我们采用标准的微信登录流程:
javascript复制// 小程序端代码
wx.login({
success: res => {
if (res.code) {
wx.getUserInfo({
success: infoRes => {
// 将code和用户信息发送到后端
wx.request({
url: 'https://yourdomain.com/api/login',
method: 'POST',
data: {
code: res.code,
encryptedData: infoRes.encryptedData,
iv: infoRes.iv
},
success: loginRes => {
// 存储返回的token
wx.setStorageSync('token', loginRes.data.token)
}
})
}
})
}
}
})
后端解密处理:
javascript复制// Node.js解密示例
const decryptData = (encryptedData, iv, sessionKey) => {
const decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, iv)
let decoded = decipher.update(encryptedData, 'base64', 'utf8')
decoded += decipher.final('utf8')
return JSON.parse(decoded)
}
注意:实际项目中一定要做好session_key的安全管理,避免泄露导致用户信息被解密。
3.2 微信支付集成
报名付费是核心业务流程,我们采用微信支付JSAPI方式:
- 后端生成预付单:
javascript复制const unifiedorder = async (params) => {
const result = await axios.post('https://api.mch.weixin.qq.com/pay/unifiedorder',
buildXmlParams({
appid: config.appId,
mch_id: config.mchId,
nonce_str: generateNonceStr(),
body: '武术课程报名费',
out_trade_no: params.orderNo,
total_fee: params.amount,
spbill_create_ip: params.ip,
notify_url: config.notifyUrl,
trade_type: 'JSAPI',
openid: params.openid
}),
{ headers: { 'Content-Type': 'text/xml' } }
)
return parseXml(result.data)
}
- 小程序端调起支付:
javascript复制wx.requestPayment({
timeStamp: payParams.timeStamp,
nonceStr: payParams.nonceStr,
package: payParams.package,
signType: 'MD5',
paySign: payParams.paySign,
success: (res) => {
// 支付成功处理
},
fail: (err) => {
console.error('支付失败', err)
}
})
- 支付结果通知处理:
javascript复制// 验证签名
const verifySign = (params, key) => {
const sign = params.sign
delete params.sign
const localSign = generateSign(params, key)
return sign === localSign
}
// 更新订单状态
app.post('/pay/notify', (req, res) => {
const xmlData = await parseXmlStream(req)
if(verifySign(xmlData, config.key)){
await updateOrderStatus(xmlData.out_trade_no)
res.send(buildSuccessXml())
}else{
res.send(buildFailXml())
}
})
3.3 课程预约与冲突检测
武术课程通常有固定时间段,需要防止学员重复预约时间冲突的课程:
javascript复制// 检查时间冲突
const checkScheduleConflict = async (userId, newCourseId) => {
const enrolledCourses = await db.query(`
SELECT c.class_time
FROM orders o
JOIN courses c ON o.course_id = c.id
WHERE o.user_id = ? AND o.pay_status = 1
`, [userId])
const newCourse = await db.query('SELECT class_time FROM courses WHERE id = ?', [newCourseId])
return enrolledCourses.some(course => {
return isTimeOverlap(course.class_time, newCourse.class_time)
})
}
// 时间重叠判断函数
function isTimeOverlap(time1, time2) {
// 实现时间字符串的解析和比较逻辑
// 例如:"周一 14:00-16:00"与"周一 15:00-17:00"存在重叠
}
4. 项目亮点与难点解决方案
4.1 远程调试方案
为了方便毕业答辩演示,项目实现了远程调试功能:
- 内网穿透配置:
bash复制# 使用frp进行内网穿透
./frpc -c ./frpc.ini
# frpc.ini配置示例
[common]
server_addr = your_server_ip
server_port = 7000
[web]
type = http
local_port = 3000
custom_domains = api.yourdomain.com
- 小程序配置:
json复制// project.config.json
{
"miniprogramRoot": "./",
"cloudfunctionRoot": "./cloudfunctions/",
"setting": {
"urlCheck": false,
"es6": true,
"postcss": true,
"remoteDebugUrl": "your_remote_ip:port"
}
}
- 真机调试技巧:
- 使用微信开发者工具的"远程调试"功能
- 在手机端开启调试模式:小程序右上角菜单 → 打开调试
- 通过console.log输出关键流程信息
4.2 性能优化实践
武术课程展示页包含大量图片,我们采取了以下优化措施:
- 图片懒加载:
html复制<image lazy-load mode="widthFix" src="{{course.cover}}"></image>
- 数据分页加载:
javascript复制Page({
data: {
pageSize: 10,
currentPage: 1,
loading: false
},
onReachBottom() {
if(!this.data.loading){
this.setData({ loading: true })
this.loadMoreData()
}
},
loadMoreData() {
wx.request({
url: '/api/courses',
data: {
page: this.data.currentPage + 1,
size: this.data.pageSize
},
success: (res) => {
this.setData({
courses: [...this.data.courses, ...res.data.list],
currentPage: this.data.currentPage + 1,
loading: false
})
}
})
}
})
- 缓存策略:
javascript复制// 获取课程数据时优先检查缓存
const getCourses = () => {
return new Promise((resolve) => {
const cached = wx.getStorageSync('courses_cache')
if(cached && Date.now() - cached.timestamp < 3600000){
resolve(cached.data)
}else{
fetchCourses().then(data => {
wx.setStorageSync('courses_cache', {
data,
timestamp: Date.now()
})
resolve(data)
})
}
})
}
5. 毕设答辩准备建议
5.1 演示重点规划
根据武术培训班的特点,建议按以下顺序演示:
- 用户视角流程:
- 微信授权登录 → 浏览课程 → 查看详情 → 报名支付 → 查看订单
- 管理员视角:
- 课程管理 → 学员统计 → 订单管理 → 消息推送
- 技术亮点展示:
- 支付流程时序图
- 数据库设计ER图
- 性能优化前后对比
5.2 常见问题准备
根据经验,答辩委员会常关注以下问题:
- 安全性问题:
- 如何防止重复支付?
- 用户敏感信息如何保护?
- 支付回调如何防篡改?
- 业务逻辑:
- 如何处理课程时间冲突?
- 学员退课流程如何设计?
- 如何防止刷单行为?
- 技术深度:
- 为什么选择Node.js而不是Java/PHP?
- 小程序与普通网页开发的主要区别?
- 如何评估系统承载能力?
5.3 文档撰写要点
完整的毕设文档应包含:
- 需求分析部分:
- 武术培训行业的现状分析
- 用户画像(学员、教练、管理员)
- 功能用例图
- 设计部分:
- 系统架构图
- 数据库设计规范
- API接口文档示例
- 实现部分:
- 核心代码片段说明
- 测试用例设计
- 性能优化记录
- 总结部分:
- 项目成果评估
- 待改进方向
- 个人收获体会
我在实际开发中发现,提前录制关键流程的操作视频作为答辩备用是非常有用的,可以避免现场网络或设备问题导致的演示失败。同时准备一份精简版的演示脚本,确保能在10分钟内完整展示项目亮点。
