这个基于Vue3和ThinkPHP的课程互助学习系统,是我去年为一个高校在线教育平台开发的核心项目。它解决了传统在线学习平台缺乏互动性的痛点,让学生能够在学习过程中实时提问、互相解答、共享笔记,形成真正的学习社区。
系统采用前后端分离架构,前端使用Vue3+TypeScript+Pinia的组合,后端基于ThinkPHP8开发。在6个月的开发周期中,我们迭代了3个主要版本,最终实现了日均5000+的活跃用户量。特别值得一提的是,这个系统在课程讨论区的设计上做了很多创新,比如引入了"问题悬赏"机制和"最佳答案"评选,显著提升了用户的参与度。
选择Vue3作为前端框架主要基于以下几个考虑:
实际开发中我们使用了这些核心依赖:
typescript复制// 典型的API请求封装示例
const api = axios.create({
baseURL: import.meta.env.VITE_API_URL,
timeout: 10000
})
api.interceptors.request.use(config => {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
})
ThinkPHP8作为后端框架的优势在于:
我们特别优化了数据库设计:
php复制// 课程模型示例
class Course extends Model
{
// 定义与用户的多对多关系
public function users()
{
return $this->belongsToMany(User::class, 'course_user');
}
// 定义与问题的一对多关系
public function questions()
{
return $this->hasMany(Question::class);
}
}
这是系统的核心功能模块,实现了:
前端关键代码:
vue复制<script setup>
const form = reactive({
title: '',
content: '',
bounty: 0,
courseId: props.courseId
})
const submitQuestion = async () => {
if (!form.title.trim()) {
return ElMessage.error('请输入问题标题')
}
try {
await api.post('/questions', form)
ElMessage.success('问题发布成功')
emit('refresh')
} catch (err) {
ElMessage.error(err.response?.data?.message || '发布失败')
}
}
</script>
后端采用Redis实现了问题热度的实时计算:
php复制public function store(Request $request)
{
$question = Question::create($request->validated());
// 记录问题热度
Redis::zincrby('hot_questions', 1, $question->id);
return response()->json($question, 201);
}
学生可以:
我们使用Quill编辑器实现富文本编辑:
javascript复制const modules = {
toolbar: [
['bold', 'italic', 'underline'],
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
['link', 'image'],
['code-block']
]
}
vue复制const Editor = defineAsyncComponent(() => import('@/components/Editor.vue'))
typescript复制function useDebounceFn(fn: Function, delay: number) {
let timer: number | null = null
return function(...args: any[]) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => fn.apply(this, args), delay)
}
}
php复制// 避免N+1查询问题
$questions = Question::with(['user', 'answers.user'])
->where('course_id', $courseId)
->orderBy('created_at', 'desc')
->paginate(15);
ini复制; swoole配置
swoole.http_server.worker_num = 8
swoole.http_server.max_request = 1000
我们使用Docker Compose编排服务:
yaml复制version: '3'
services:
frontend:
build: ./frontend
ports:
- "3000:3000"
backend:
build: ./backend
ports:
- "8000:8000"
depends_on:
- redis
- mysql
javascript复制import * as Sentry from '@sentry/vue'
Sentry.init({
dsn: 'your_dsn',
integrations: [new Sentry.BrowserTracing()],
tracesSampleRate: 0.2
})
php复制// 定义指标端点
$router->get('/metrics', function () {
$registry = Registry::getDefault();
$renderer = new RenderTextFormat();
return $renderer->render($registry->getMetricFamilySamples());
});
这个项目让我深刻体会到,一个好的学习系统不仅要有扎实的技术实现,更需要深入理解教育场景下的用户需求。比如我们最初设计的问答系统太过技术导向,后来通过用户调研增加了"学习互助"板块,使用率提升了40%。