加入练习中心客户端和管理端的框架

This commit is contained in:
lzh
2022-12-23 17:54:17 +08:00
parent 101db715f8
commit 3908d6b78a
16 changed files with 293 additions and 1 deletions
+1
View File
@@ -45,6 +45,7 @@ INSTALLED_APPS = [
'rest_framework',
'django_filters',
'import_export',
'study',
'user',
'exam',
'question',
+3 -1
View File
@@ -24,7 +24,7 @@ from question.views import ChoiceListViewSet, FillListViewSet, JudgeListViewSet,
from record.views import ChoiceRecordListViewSet, FillRecordListViewSet, JudgeRecordListViewSet, \
ProgramRecordListViewSet
from user.views import RegisterViewSet, StudentViewSet, UpdatePwdApi, ClazzListViewSet
from study.views import StudyListViewSet,get_content
router = DefaultRouter()
# 配置exams的url
@@ -42,6 +42,7 @@ router.register(r'records/choices', ChoiceRecordListViewSet)
router.register(r'records/fills', FillRecordListViewSet)
router.register(r'records/judges', JudgeRecordListViewSet)
router.register(r'records/programs', ProgramRecordListViewSet)
router.register(r'studies', StudyListViewSet)
urlpatterns = [
path('xadmin/', xadmin.site.urls),
@@ -50,5 +51,6 @@ urlpatterns = [
path('jwt-auth/', obtain_jwt_token),
path('check-program/', CheckProgramApi.as_view()),
path('update-pwd/', UpdatePwdApi.as_view()),
path("content/", get_content),
re_path('^', include(router.urls))
]
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
default_app_config = 'study.apps.StudyConfig'
+3
View File
@@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.
+15
View File
@@ -0,0 +1,15 @@
import xadmin
from study.models import Study
from study.resource import StudyResource
class StudyAdmin(object):
list_display = ['id', 'name', 'desc', 'relate_points', 'relate_questions', 'study_times', 'add_time']
search_fields = ['name', 'desc', 'relate_points', 'relate_questions']
list_filter = ['name', 'desc', 'relate_points', 'relate_questions', 'study_times', 'add_time']
import_export_args = {'import_resource_class': StudyResource, 'export_resource_class': StudyResource}
xadmin.site.register(Study, StudyAdmin)
+6
View File
@@ -0,0 +1,6 @@
from django.apps import AppConfig
class StudyConfig(AppConfig):
name = 'study'
verbose_name = '学习中心管理'
+50
View File
@@ -0,0 +1,50 @@
[
{
"id": 1,
"label": "一级 1",
"children": [
{
"id": 4,
"label": "二级 1-1",
"children": [
{
"id": 9,
"label": "三级 1-1-1"
},
{
"id": 10,
"label": "三级 1-1-2"
}
]
}
]
},
{
"id": 2,
"label": "一级 2",
"children": [
{
"id": 5,
"label": "二级 2-1"
},
{
"id": 6,
"label": "二级 2-2"
}
]
},
{
"id": 3,
"label": "一级 3",
"children": [
{
"id": 7,
"label": "二级 3-1"
},
{
"id": 8,
"label": "二级 3-2"
}
]
}
]
+20
View File
@@ -0,0 +1,20 @@
from django.db import models
# Create your models here.
class Study(models.Model):
"""学习资料"""
name = models.CharField("学习资料目录名称", max_length=100)
desc = models.TextField("学习内容描述", null=True, blank=True)
relate_points = models.TextField("相关知识点", null=True, blank=True)
relate_questions = models.TextField("相关题目", null=True, blank=True)
study_times = models.IntegerField("学习次数", default=0)
add_time = models.DateTimeField("添加时间", auto_now_add=True)
class Meta:
ordering = ['id']
verbose_name = '资料库'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
+8
View File
@@ -0,0 +1,8 @@
from import_export import resources
from study.models import Study
class StudyResource(resources.ModelResource):
class Meta:
model = Study
fields = ('id', 'name', 'desc', 'relate_points', 'relate_questions', 'study_times', 'add_time')
+7
View File
@@ -0,0 +1,7 @@
from rest_framework import serializers
from study.models import Study
class StudySerializer(serializers.ModelSerializer):
class Meta:
model = Study
fields = '__all__'
+3
View File
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
+42
View File
@@ -0,0 +1,42 @@
import subprocess
import json
import os
from django.http import JsonResponse
from rest_framework import mixins, viewsets
from rest_framework.response import Response
from rest_framework.views import APIView
from study.models import Study
from study.serializers import StudySerializer
# Create your views here.
class StudyListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
"""选择题列表页"""
# 这里要定义一个默认的排序,否则会报错
queryset = Study.objects.all().order_by('id')[:0]
# 序列化
serializer_class = StudySerializer
# 重写queryset
def get_queryset(self):
# 题目数量
choice_number = int(self.request.query_params.get("choice_number", 0))
level = int(self.request.query_params.get("level", 1))
content = self.request.query_params.get("content", 0)
if choice_number:
self.queryset = Study.objects.all().filter(level=level).order_by('?')[:choice_number]
return self.queryset
def get_content(request):
with open("./study/content.json",encoding="utf-8") as f:
content = json.load(f)
res = {
"code": 200,
"msg": "success",
"data": content
}
return JsonResponse(res)
+1
View File
@@ -7,6 +7,7 @@
<el-menu :default-active="activeIndex" class="el-menu-title" mode="horizontal" @select="handleSelect"
background-color="#ffffff" text-color="#85baef" active-text-color="#1884f2" :router="true">
<el-menu-item index="/exam">考试中心</el-menu-item>
<el-menu-item index="/study">练习中心</el-menu-item>
<el-menu-item index="/practice">模拟练习</el-menu-item>
<el-menu-item index="/grade">查询成绩</el-menu-item>
<el-menu-item index="/mistake" disabled>错题本</a></el-menu-item>
+8
View File
@@ -16,6 +16,14 @@ const routes = [{
title: '考试中心'
}
},
{
path: 'study',
component: () => import('../views/Study.vue'),
name: 'study',
meta: {
title: '学习中心'
}
},
{
path: 'practice',
name: 'Practice',
+125
View File
@@ -0,0 +1,125 @@
<template>
<div>
<!-- 左边的树状结构-->
<div class="custom-tree-container">
<div class="block">
<p>章节目录</p>
<el-tree
:data="data"
show-checkbox
node-key="id"
default-expand-all
:expand-on-click-node="false"
:render-content="renderContent">
</el-tree>
</div>
</div>
<!-- 右边的对应内容-->
<div class="content">
<textarea v-model="content" class="content-textarea"></textarea>
</div>
</div>
</template>
<script>
let id = 1000;
export default {
data() {
const data = [{
id: 1,
label: '一级 1',
children: [{
id: 4,
label: '二级 1-1',
children: [{
id: 9,
label: '三级 1-1-1'
}, {
id: 10,
label: '三级 1-1-2'
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 5,
label: '二级 2-1'
}, {
id: 6,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 7,
label: '二级 3-1'
}, {
id: 8,
label: '二级 3-2'
}]
}];
return {
data: JSON.parse(JSON.stringify(data)),
data: JSON.parse(JSON.stringify(data))
}
},
methods: {
append(data) {
const newChild = {id: id++, label: 'testtest', children: []};
if (!data.children) {
this.$set(data, 'children', []);
}
data.children.push(newChild);
},
remove(node, data) {
const parent = node.parent;
const children = parent.data.children || parent.data;
const index = children.findIndex(d => d.id === data.id);
children.splice(index, 1);
},
renderContent(h, {node, data, store}) {
return (
<span class="custom-tree-node">
<span>{node.label}</span>
<span>
<el-button size="mini" type="text" on-click={() => this.append(data)}>Append</el-button>
<el-button size="mini" type="text" on-click={() => this.remove(node, data)}>Delete</el-button>
</span>
</span>);
}
}
};
</script>
<style>
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
.block {
float: left;
}
.content {
background-color: black;
width: 70%;
float: right;
margin-right: 5%;
}
</style>