Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
x-learn
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
x-learn
Commits
ef2779ab
提交
ef2779ab
authored
10月 18, 2021
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 新增考卷批阅和习题批阅
上级
ae4a660f
隐藏空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
504 行增加
和
1 行删除
+504
-1
teacher.js
src/api/teacher.js
+14
-0
AppList.vue
src/components/AppList.vue
+324
-0
ReviewStudents.vue
src/components/ReviewStudents.vue
+44
-0
aside.vue
src/components/layout/aside.vue
+8
-0
index.vue
src/pages/teacher/examReview/index.vue
+52
-0
index.vue
src/pages/teacher/testReview/index.vue
+53
-0
routes.js
src/router/routes.js
+9
-1
没有找到文件。
src/api/teacher.js
0 → 100644
浏览文件 @
ef2779ab
import
httpRequest
from
'@/utils/axios'
/**
* 获取考卷批阅列表
*/
export
function
getExamReivewList
(
params
)
{
return
httpRequest
.
get
(
'/api/zy/v3-teacher/examination/examination-list'
,
{
params
})
}
/**
* 获取习题批阅列表
*/
export
function
getTestReivewList
(
params
)
{
return
httpRequest
.
get
(
'/api/zy/v3-teacher/examination/chapter-examination-list'
,
{
params
})
}
src/components/AppList.vue
0 → 100644
浏览文件 @
ef2779ab
<
template
>
<div
class=
"table-list"
>
<div
class=
"table-list-hd"
>
<!-- 筛选 -->
<div
class=
"table-list-filter"
v-if=
"filters.length"
>
<el-form
:inline=
"true"
:model=
"params"
ref=
"filterForm"
@
submit
.
native
.
prevent
>
<template
v-for=
"item in filters"
>
<el-form-item
:label=
"item.label"
:prop=
"item.prop"
:key=
"item.prop"
>
<template
v-if=
"item.slots"
>
<slot
:name=
"item.slots"
v-bind=
"
{ params }">
</slot>
</
template
>
<
template
v-else
>
<!-- input -->
<el-input
v-model=
"params[item.prop]"
v-bind=
"item"
clearable
v-if=
"item.type === 'input'"
@
keyup
.
native
.
enter=
"search"
/>
<!-- select -->
<el-select
v-model=
"params[item.prop]"
clearable
v-bind=
"item"
v-if=
"item.type === 'select'"
@
change=
"search"
>
<template
v-for=
"(option, index) in item.options"
>
<el-option
:label=
"option[item.labelKey] || option.label"
:value=
"option[item.valueKey] || option.value"
:key=
"index"
></el-option>
</
template
>
</el-select>
</template>
</el-form-item>
</template>
<el-form-item
class=
"filter-buttons"
>
<el-button
type=
"primary"
icon=
"el-icon-search"
@
click=
"search"
>
查询
</el-button>
<el-button
icon=
"el-icon-refresh-left"
@
click=
"reset"
>
重置
</el-button>
<el-button
@
click=
"showMoreFilter"
v-if=
"hasMoreFilter"
>
更多筛选
</el-button>
</el-form-item>
</el-form>
</div>
<div
class=
"table-list-hd-aside"
><slot
name=
"header-aside"
/></div>
</div>
<slot></slot>
<!-- 主体 -->
<div
class=
"table-list-bd"
>
<slot
name=
"body"
v-bind=
"{ data: dataList }"
>
<el-table
:data=
"dataList"
v-loading=
"loading"
v-bind=
"$attrs"
v-on=
"$listeners"
style=
"height: 100%"
ref=
"table"
>
<
template
v-for=
"item in columns"
>
<el-table-column
v-bind=
"item"
:key=
"item.prop"
v-if=
"visible(item)"
>
<template
v-slot:default=
"scope"
v-if=
"item.slots || item.computed"
>
<slot
:name=
"item.slots"
v-bind=
"scope"
v-if=
"item.slots"
></slot>
<div
v-html=
"item.computed(scope)"
v-if=
"item.computed"
></div>
</
template
>
</el-table-column>
</template>
</el-table>
</slot>
</div>
<!-- 底部 -->
<div
class=
"table-list-ft"
>
<div
style=
"padding: 10px 0"
>
<slot
name=
"footer"
></slot>
</div>
<el-pagination
class=
"table-list-pagination"
layout=
"total, prev, pager, next, sizes, jumper"
:page-sizes=
"[10, 20, 30, 50, 100]"
:page-size=
"page.size"
:total=
"page.total"
:current-page
.
sync=
"page.currentPage"
@
size-change=
"pageSizeChange"
@
current-change=
"fetchList()"
:hide-on-single-page=
"true"
v-if=
"hasPagination"
>
</el-pagination>
</div>
<!-- 更多筛选 -->
<el-drawer
title=
"更多筛选"
:visible
.
sync=
"moreFilterVisible"
ref=
"drawer"
>
<div
class=
"more-filter-drawer"
>
<div
class=
"more-filter"
>
<el-form
:model=
"params"
ref=
"moreFilterForm"
>
<
template
v-for=
"item in moreFilters"
>
<el-form-item
:label=
"item.label"
:prop=
"item.prop"
:key=
"item.prop"
>
<template
v-if=
"item.slots"
>
<slot
:name=
"item.slots"
v-bind=
"
{ params }">
</slot>
</
template
>
<
template
v-else
>
<!-- input -->
<el-input
v-model=
"params[item.prop]"
v-bind=
"item"
clearable
v-if=
"item.type === 'input'"
/>
<!-- select -->
<el-select
v-model=
"params[item.prop]"
clearable
v-bind=
"item"
v-if=
"item.type === 'select'"
style=
"width: 100%"
>
<template
v-for=
"(option, index) in item.options"
>
<el-option
:label=
"option[item.labelKey] || option.label"
:value=
"option[item.valueKey] || option.value"
:key=
"index"
></el-option>
</
template
>
</el-select>
</template>
</el-form-item>
</template>
</el-form>
</div>
<div
class=
"more-filter-buttons"
>
<el-button
@
click=
"cancelMoreFilter"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"primaryMoreFilter"
>
确定
</el-button>
</div>
</div>
</el-drawer>
</div>
</template>
<
script
>
export
default
{
name
:
'AppList'
,
props
:
{
// 接口请求
remote
:
{
type
:
Object
,
default
:
()
=>
({})
},
// 筛选
filters
:
{
type
:
Array
,
default
:
()
=>
[]
},
// 更多筛选
moreFilters
:
{
type
:
Array
,
default
:
()
=>
[]
},
// 列表项
columns
:
{
type
:
Array
,
default
:
()
=>
[]
},
// 列表数据
data
:
{
type
:
Array
,
default
:
()
=>
[]
},
// 是否含有翻页
hasPagination
:
{
type
:
Boolean
,
default
:
true
},
// 每页多少条数据
limit
:
{
type
:
Number
,
default
:
20
}
},
data
()
{
return
{
loading
:
false
,
params
:
this
.
remote
.
params
||
{},
dataList
:
this
.
data
,
page
:
{
total
:
0
,
size
:
this
.
limit
,
currentPage
:
1
},
moreFilterVisible
:
false
}
},
watch
:
{
'remote.params'
:
{
immediate
:
true
,
handler
(
data
)
{
this
.
params
=
data
||
{}
}
},
data
:
{
immediate
:
true
,
handler
(
data
)
{
this
.
dataList
=
data
}
}
},
computed
:
{
table
()
{
return
this
.
$refs
.
table
},
hasMoreFilter
()
{
return
!!
this
.
moreFilters
.
length
}
},
methods
:
{
fetchList
(
isReset
)
{
/**
* @param function httpRequest api接口
* @param function beforeRequest 接口请求之前
* @param function callback 接口请求成功回调
*/
const
{
httpRequest
,
beforeRequest
,
callback
}
=
this
.
remote
if
(
!
httpRequest
)
{
return
}
// 参数设置
let
params
=
this
.
params
// 翻页参数设置
if
(
this
.
hasPagination
)
{
params
.
page
=
this
.
page
.
currentPage
params
.
page_size
=
this
.
page
.
size
}
// 接口请求之前
if
(
beforeRequest
)
{
params
=
beforeRequest
(
params
,
isReset
)
}
for
(
const
key
in
params
)
{
if
(
params
[
key
]
===
''
||
params
[
key
]
===
undefined
||
params
[
key
]
===
undefined
)
{
delete
params
[
key
]
}
}
this
.
loading
=
true
httpRequest
(
params
)
.
then
(
res
=>
{
const
data
=
res
.
data
||
{}
const
{
list
=
[],
total
=
0
}
=
data
this
.
page
.
total
=
total
this
.
dataList
=
callback
?
callback
(
data
)
:
list
})
.
catch
(()
=>
{
this
.
page
.
total
=
0
this
.
dataList
=
[]
})
.
finally
(()
=>
{
this
.
loading
=
false
})
},
// 搜索
search
()
{
this
.
page
.
currentPage
=
1
this
.
fetchList
()
},
// 重置
reset
()
{
// 清空筛选条件
this
.
$refs
.
filterForm
&&
this
.
$refs
.
filterForm
.
resetFields
()
// 清空更多筛选条件
this
.
hasMoreFilter
&&
this
.
$refs
.
moreFilterForm
&&
this
.
$refs
.
moreFilterForm
.
resetFields
()
// 初始化页码
this
.
page
.
currentPage
=
1
// 刷新列表
this
.
fetchList
(
true
)
},
// 刷新
refetch
(
isForce
)
{
isForce
?
this
.
reset
()
:
this
.
fetchList
()
},
// 页数改变
pageSizeChange
(
value
)
{
this
.
page
.
currentPage
=
1
this
.
page
.
size
=
value
this
.
fetchList
()
},
visible
(
item
)
{
return
Object
.
prototype
.
hasOwnProperty
.
call
(
item
,
'visible'
)
?
item
.
visible
:
true
},
// 显示更多筛选
showMoreFilter
()
{
this
.
moreFilterVisible
=
true
},
// 取消更多筛选
cancelMoreFilter
()
{
this
.
moreFilterVisible
=
false
// 清空筛选条件
this
.
$refs
.
moreFilterForm
&&
this
.
$refs
.
moreFilterForm
.
resetFields
()
},
// 确定更多筛选
primaryMoreFilter
()
{
this
.
moreFilterVisible
=
false
this
.
search
()
}
},
beforeMount
()
{
this
.
fetchList
()
}
}
</
script
>
<
style
lang=
"scss"
>
.table-list
{
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
box-sizing
:
border-box
;
}
.table-list-hd
{
display
:
flex
;
margin-bottom
:
10px
;
}
.table-list-filter
{
flex
:
1
;
}
.table-list-bd
{
flex
:
1
;
}
.table-list-ft
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
}
.table-list-pagination
{
padding
:
10px
0
;
text-align
:
right
;
}
.el-table-column--selection
.cell
{
padding
:
0
14px
!
important
;
}
.more-filter-drawer
{
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
padding
:
0
20px
20px
;
box-sizing
:
border-box
;
}
.more-filter
{
flex
:
1
;
overflow-y
:
auto
;
}
.more-filter-buttons
{
display
:
flex
;
.el-button
{
flex
:
1
;
}
}
</
style
>
src/components/ReviewStudents.vue
0 → 100644
浏览文件 @
ef2779ab
<
template
>
<el-dialog
v-bind=
"$attrs"
v-on=
"$listeners"
>
<el-tabs
v-model=
"activeName"
>
<el-tab-pane
:label=
"`全部($
{students.length})`" name="0">
<ul>
<li
v-for=
"student in students"
:key=
"student.id"
>
{{
student
.
name
}}
</li>
</ul>
</el-tab-pane>
<el-tab-pane
:label=
"`未批阅($
{unreviewedStudents.length})`" name="1">
<ul>
<li
v-for=
"student in unreviewedStudents"
:key=
"student.id"
>
{{
student
.
name
}}
</li>
</ul>
</el-tab-pane>
<el-tab-pane
:label=
"`已批阅($
{reviewedStudents.length})`" name="2">
<ul>
<li
v-for=
"student in reviewedStudents"
:key=
"student.id"
>
{{
student
.
name
}}
</li>
</ul>
</el-tab-pane>
</el-tabs>
</el-dialog>
</
template
>
<
script
>
export
default
{
props
:
{
students
:
{
type
:
Array
,
default
:
()
=>
[]
}
},
data
()
{
return
{
activeName
:
'0'
}
},
computed
:
{
// 未批阅的学生
unreviewedStudents
()
{
return
this
.
students
.
filter
(
item
=>
item
.
status
===
1
)
},
// 已批阅的学生
reviewedStudents
()
{
return
this
.
students
.
filter
(
item
=>
item
.
status
===
2
)
}
}
}
</
script
>
<
style
></
style
>
src/components/layout/aside.vue
浏览文件 @
ef2779ab
...
@@ -87,6 +87,14 @@ export default {
...
@@ -87,6 +87,14 @@ export default {
icon
:
'icon-bianzu6-hong'
,
icon
:
'icon-bianzu6-hong'
,
children
:
[{
title
:
'课程库'
,
path
:
'/course/learn'
}]
children
:
[{
title
:
'课程库'
,
path
:
'/course/learn'
}]
},
},
{
title
:
'模拟考试'
,
icon
:
'icon-bianzuhong'
,
children
:
[
{
title
:
'考卷批阅'
,
path
:
'/teacher/exam'
},
{
title
:
'习题批阅'
,
path
:
'/teacher/test'
}
]
},
{
{
title
:
'实训资源'
,
title
:
'实训资源'
,
icon
:
'icon-kaoshihong'
,
icon
:
'icon-kaoshihong'
,
...
...
src/pages/teacher/examReview/index.vue
0 → 100644
浏览文件 @
ef2779ab
<
template
>
<app-container>
<app-list
v-bind=
"tableOptions"
ref=
"list"
>
<template
v-slot:table-name=
"
{ row }">
<el-link
type=
"primary"
>
{{
row
.
paper_title
}}
</el-link>
</
template
>
</app-list>
<review-students
:visible
.
sync=
"visible"
:students=
"currentClickRow.students"
></review-students>
</app-container>
</template>
<
script
>
import
{
getExamReivewList
}
from
'@/api/teacher.js'
import
AppContainer
from
'@/components/AppContainer'
import
AppList
from
'@/components/AppList'
import
ReviewStudents
from
'@/components/ReviewStudents'
export
default
{
components
:
{
AppContainer
,
AppList
,
ReviewStudents
},
data
()
{
return
{
visible
:
false
,
currentClickRow
:
{}
}
},
computed
:
{
// 列表配置
tableOptions
()
{
return
{
remote
:
{
httpRequest
:
getExamReivewList
,
params
:
{
class_name
:
''
,
paper_title
:
''
}
},
filters
:
[
{
type
:
'input'
,
prop
:
'class_name'
,
placeholder
:
'班级名称'
},
{
type
:
'input'
,
prop
:
'paper_title'
,
placeholder
:
'考卷名称'
}
],
columns
:
[
{
label
:
'考卷名称'
,
prop
:
'paper_title'
,
slots
:
'table-name'
},
{
label
:
'班级名称'
,
prop
:
'class_name'
,
align
:
'center'
},
{
label
:
'未批阅学生数量'
,
prop
:
'commit_num'
,
align
:
'center'
}
]
}
}
},
methods
:
{
handleRowClick
(
row
)
{
this
.
currentClickRow
=
row
this
.
visible
=
true
}
}
}
</
script
>
src/pages/teacher/testReview/index.vue
0 → 100644
浏览文件 @
ef2779ab
<
template
>
<app-container>
<app-list
v-bind=
"tableOptions"
ref=
"list"
@
row-click=
"handleRowClick"
>
<template
v-slot:table-name=
"
{ row }">
<el-link
type=
"primary"
>
{{
row
.
paper_title
}}
</el-link>
</
template
>
</app-list>
<review-students
:visible
.
sync=
"visible"
:students=
"currentClickRow.students"
></review-students>
</app-container>
</template>
<
script
>
import
{
getTestReivewList
}
from
'@/api/teacher.js'
import
AppContainer
from
'@/components/AppContainer'
import
AppList
from
'@/components/AppList'
import
ReviewStudents
from
'@/components/ReviewStudents'
export
default
{
components
:
{
AppContainer
,
AppList
,
ReviewStudents
},
data
()
{
return
{
visible
:
false
,
currentClickRow
:
{}
}
},
computed
:
{
// 列表配置
tableOptions
()
{
return
{
remote
:
{
httpRequest
:
getTestReivewList
,
params
:
{
course_id
:
''
,
chapter_id
:
''
}
},
filters
:
[
{
type
:
'select'
,
prop
:
'course_id'
,
placeholder
:
'选择课程'
},
{
type
:
'select'
,
prop
:
'chapter_id'
,
placeholder
:
'选择章节'
}
],
columns
:
[
{
label
:
'考卷名称'
,
prop
:
'paper_title'
,
slots
:
'table-name'
},
{
label
:
'班级名称'
,
prop
:
'class_name'
,
align
:
'center'
},
{
label
:
'未批阅学生数量'
,
prop
:
'commit_num'
,
align
:
'center'
}
]
}
}
},
methods
:
{
handleRowClick
(
row
)
{
this
.
currentClickRow
=
row
this
.
visible
=
true
}
}
}
</
script
>
src/router/routes.js
浏览文件 @
ef2779ab
...
@@ -56,9 +56,17 @@ const examAnswer = [
...
@@ -56,9 +56,17 @@ const examAnswer = [
const
teacherRoutes
=
[
const
teacherRoutes
=
[
/* 模拟考试 */
/* 模拟考试 */
{
path
:
'/teacher/exam'
,
component
:
()
=>
import
(
/* webpackChunkName: "teacher" */
'@/pages/teacher/examReview/index'
)
},
{
path
:
'/teacher/test'
,
component
:
()
=>
import
(
/* webpackChunkName: "teacher" */
'@/pages/teacher/testReview/index'
)
},
{
{
path
:
'/teacher/practicalCourse'
,
path
:
'/teacher/practicalCourse'
,
component
:
()
=>
import
(
/* webpackChunkName: "
exam
" */
'@/pages/teacher/practicalCourse/index'
)
component
:
()
=>
import
(
/* webpackChunkName: "
teacher
" */
'@/pages/teacher/practicalCourse/index'
)
}
}
]
]
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论