【Webman+MySQL答题系统十】前后端联调与全流程测试(收官)
果子发表于:2026-10-05 20:55:47浏览:3次
本篇目标
系列收官:UniApp 端封装请求与登录态,串起登录→取卷→作答→交卷→成绩→错题全流程,附 curl 测试清单与踩坑汇总。

一、联调结构

二、UniApp 请求封装
common/api.js,统一处理 token、401 跳转、错误提示:
const BASE = 'https://quiz.example.com'
function request(path, data = {}, method = 'GET') {
const token = uni.getStorageSync('token')
return new Promise((resolve, reject) => {
uni.request({
url: BASE + path,
method,
data,
header: token ? { Authorization: 'Bearer ' + token } : {},
success: res => {
const body = res.data
if (body.code === 0) return resolve(body.data)
if (body.code === 401) {
uni.removeStorageSync('token')
uni.reLaunch({ url: '/pages/login/login' })
return reject(body)
}
uni.showToast({ title: body.msg || '请求失败', icon: 'none' })
reject(body)
},
fail: err => {
uni.showToast({ title: '网络异常', icon: 'none' })
reject(err)
}
})
})
}
export const login = d => request('/api/auth/login', d, 'POST')
export const getPaper = id => request('/api/answer/paper', { paper_id: id })
export const submit = d => request('/api/answer/submit', d, 'POST')
export const myRecords = () => request('/api/stat/my_records')
export const wrongBook = () => request('/api/stat/wrong_book')
登录成功后 uni.setStorageSync('token', data.token) 即可,后续所有请求自动携带。
三、页面串联
// login.vue 提交
const data = await login({ username, password })
uni.setStorageSync('token', data.token)
// exam.vue 开始答题
const data = await getPaper(this.paperId)
this.paper = data.paper
this.questions = data.questions
this.deadline = Date.now() + this.paper.duration * 60000
// exam.vue 交卷
const data = await submit({
paper_id: this.paperId,
answers: this.answers,
use_seconds: this.usedSeconds
})
uni.showModal({
title: data.is_pass ? '恭喜及格' : '未能及格',
content: `得分 ${data.score} / ${data.total_score}`
})
小程序/APP 端没有跨域问题;H5 端若前后端不同域名,在 Webman 里加全局跨域中间件(Access-Control-Allow-Origin 等响应头 + OPTIONS 预检放行)。
四、全流程 curl 清单
# 1. 登录
TOKEN=$(curl -s -X POST http://127.0.0.1:8787/api/auth/login \
-d "username=zhangsan" -d "password=123456" | jq -r .data.token)
# 2. 试卷列表 -> 组卷数据(管理端)
curl "http://127.0.0.1:8787/api/paper/list?page=1&limit=10"
# 3. 取卷
curl "http://127.0.0.1:8787/api/answer/paper?paper_id=1" \
-H "Authorization: Bearer $TOKEN"
# 4. 交卷
curl -X POST http://127.0.0.1:8787/api/answer/submit \
-H "Authorization: Bearer $TOKEN" \
-d "paper_id=1" -d "use_seconds=353" \
-d "answers[1]=B" -d "answers[2]=A,C,D" -d "answers[3]=A"
# 5. 成绩 / 统计 / 错题本
curl "http://127.0.0.1:8787/api/stat/my_records" -H "Authorization: Bearer $TOKEN"
curl "http://127.0.0.1:8787/api/stat/paper_stat?paper_id=1"
curl "http://127.0.0.1:8787/api/stat/wrong_book" -H "Authorization: Bearer $TOKEN"
六步全绿,系统闭环验收通过。
五、系列踩坑汇总
| 坑 | 现象 | 解法 |
|---|---|---|
| 常驻内存不热载 | 改了代码没生效 | 重启 start.php / windows.php |
| JSON body 取不到 | post() 返回 null | rawBody()+json_decode,或前端用 form 提交 |
| MySQL 断连 | 偶发 server has gone away | 升级 webman/database / 用连接池 |
| 聚合 SQL 报错 | only_full_group_by 拒绝执行 | 非聚合列全进 GROUP BY |
| 答案泄露 | 取卷接口带出 answer | 白名单式组装返回字段 |
| 半分判分 | 多选漏选误判全错 | array_diff 判定真子集 |
六、还能往哪走
- 防切屏作弊:前端监听页面隐藏上报,服务端记违规次数;
- 题目乱序:取卷时 shuffle、提交时按 question_id 判分天然兼容;
- 导出成绩:webman 里用 phpoffice/phpspreadsheet 导出 Excel;
- 并发排行榜:redis ZSET 实时榜。
系列总结
十篇走完:需求拆解 → 环境搭建 → 建表 → 题库 → 组卷 → 取卷 → 判分 → 统计 → 鉴权 → 联调。一个数据自洽、防泄题、可扩展的答题系统骨架已经完整落地,剩下的都是在这个骨架上长肉。感谢阅读,有问题欢迎留言交流。
栏目分类全部>
推荐文章
- 【Webman+MySQL答题系统十】前后端联调与全流程测试(收官)
- 大模型的「幻觉」是什么?为什么会胡说八道
- iframe嵌套微信公众号不显示最佳解决方案,使用cors-anywhere 解决跨域问题
- 什么是大语言模型(LLM)?零基础入门
- thinkphp6的自定义异常处理
- 【Webman+MySQL答题系统一】项目概述与数据库设计
- Transformer 架构入门:注意力机制是怎么工作的
- Agent 智能体与大模型工具调用(Function Calling)
- 【Webman+MySQL教程二】路由与控制器:参数获取、响应返回、路由分组
- 用 OpenAI 兼容 API 调用大模型:从请求到代码

