Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
saas-lab
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
saas-lab
Commits
ead3ac8b
提交
ead3ac8b
authored
9月 22, 2022
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore: update
上级
a54bd8f3
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
172 行增加
和
63 行删除
+172
-63
api.ts
src/modules/teacher/contest/record/api.ts
+15
-3
ImportExamDialog.vue
...es/teacher/contest/record/components/ImportExamDialog.vue
+32
-30
ImportScoreDialog.vue
...s/teacher/contest/record/components/ImportScoreDialog.vue
+61
-0
SyncExamDialog.vue
...ules/teacher/contest/record/components/SyncExamDialog.vue
+44
-0
Index.vue
src/modules/teacher/contest/record/views/Index.vue
+20
-29
detail.vue
src/modules/teacher/contest/record/views/detail.vue
+0
-1
没有找到文件。
src/modules/teacher/contest/record/api.ts
浏览文件 @
ead3ac8b
...
@@ -34,9 +34,21 @@ export function checkExperimentRecord(data: {
...
@@ -34,9 +34,21 @@ export function checkExperimentRecord(data: {
return
httpRequest
.
post
(
'/api/lab/v1/teacher/record/check'
,
data
)
return
httpRequest
.
post
(
'/api/lab/v1/teacher/record/check'
,
data
)
}
}
// 批量导入实验记录评分
// 同步1+X考试成绩
export
function
uploadCheckExperimentRecord
(
data
:
{
file
:
File
})
{
export
function
syncExam
(
data
:
{
competition_id
:
string
;
detail_id
:
string
})
{
return
httpRequest
.
post
(
'/api/lab/v1/teacher/record/upload'
,
data
,
{
return
httpRequest
.
post
(
'/api/lab/v1/expert/check/sync-exam'
,
data
)
}
// 批量导入考试成绩
export
function
importExam
(
data
:
{
competition_id
:
string
;
file
:
File
})
{
return
httpRequest
.
post
(
'/api/lab/v1/expert/check/import-exam'
,
data
,
{
headers
:
{
'Content-Type'
:
'multipart/form-data'
}
})
}
// 批量导入完整评分
export
function
importScore
(
data
:
{
competition_id
:
string
;
file
:
File
})
{
return
httpRequest
.
post
(
'/api/lab/v1/expert/check/import-score'
,
data
,
{
headers
:
{
'Content-Type'
:
'multipart/form-data'
}
headers
:
{
'Content-Type'
:
'multipart/form-data'
}
})
})
}
}
src/modules/teacher/contest/record/components/ImportDialog.vue
→
src/modules/teacher/contest/record/components/Import
Exam
Dialog.vue
浏览文件 @
ead3ac8b
...
@@ -2,16 +2,25 @@
...
@@ -2,16 +2,25 @@
import
{
Upload
}
from
'@element-plus/icons-vue'
import
{
Upload
}
from
'@element-plus/icons-vue'
import
{
useFileDialog
}
from
'@vueuse/core'
import
{
useFileDialog
}
from
'@vueuse/core'
import
{
ElMessage
}
from
'element-plus'
import
{
ElMessage
}
from
'element-plus'
import
{
useFilterList
}
from
'../composables/useFilterList'
import
{
uploadCheckExperimentRecord
}
from
'../api'
import
{
importExam
}
from
'../api'
const
emit
=
defineEmits
<
{
const
emit
=
defineEmits
<
{
(
e
:
'update'
):
void
(
e
:
'update'
):
void
}
>
()
}
>
()
// 批量导入
const
{
competitions
}
=
useFilterList
()
const
form
=
reactive
<
any
>
({
competition_id
:
''
})
const
templateUrl
=
$computed
(()
=>
{
return
form
.
competition_id
?
`/api/lab//v1/expert/check/import-exam?competition_id=
${
form
.
competition_id
}
`
:
''
})
// 批量导入考试成绩
const
{
files
,
open
}
=
useFileDialog
()
const
{
files
,
open
}
=
useFileDialog
()
function
handleImport
()
{
function
handleImport
()
{
if
(
!
form
.
competition_id
)
return
open
({
open
({
accept
:
'.csv,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel'
,
accept
:
'.csv,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel'
,
multiple
:
false
multiple
:
false
...
@@ -20,7 +29,7 @@ function handleImport() {
...
@@ -20,7 +29,7 @@ function handleImport() {
watchEffect
(()
=>
{
watchEffect
(()
=>
{
if
(
!
files
.
value
?.
length
)
return
if
(
!
files
.
value
?.
length
)
return
const
[
file
]
=
files
.
value
const
[
file
]
=
files
.
value
uploadCheckExperimentRecord
({
file
}).
then
(()
=>
{
importExam
({
competition_id
:
form
.
competition_id
,
file
}).
then
(()
=>
{
ElMessage
({
message
:
'导入成功'
,
type
:
'success'
})
ElMessage
({
message
:
'导入成功'
,
type
:
'success'
})
emit
(
'update'
)
emit
(
'update'
)
})
})
...
@@ -28,32 +37,25 @@ watchEffect(() => {
...
@@ -28,32 +37,25 @@ watchEffect(() => {
</
script
>
</
script
>
<
template
>
<
template
>
<el-dialog
title=
"批量导入"
:close-on-click-modal=
"false"
width=
"400px"
>
<el-dialog
title=
"批量导入考试成绩"
:close-on-click-modal=
"false"
width=
"400px"
>
<div
class=
"box"
>
<el-form
label-width=
"70px"
>
<el-button
type=
"primary"
round
:icon=
"Upload"
@
click=
"handleImport"
>
本地上传
</el-button>
<el-form-item
label=
"赛项名称"
>
<p>
<el-select
v-model=
"form.competition_id"
>
<a
<el-option
v-for=
"item in competitions"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
></el-option>
href=
"https://webapp-pub.ezijing.com/project/saas-lab/%E5%AE%9E%E9%AA%8C%E6%88%90%E7%BB%A9%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF.xlsx"
</el-select>
download
<a
:href=
"templateUrl"
download
style=
"margin-left: 10px"
v-if=
"templateUrl"
>
下载模板
</a>
>
下载模板
</a
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
round
:icon=
"Upload"
@
click=
"handleImport"
:disabled=
"!form.competition_id"
style=
"width: 195px"
>
本地上传
</el-button
>
>
</
p
>
</
el-form-item
>
</
div
>
</
el-form
>
</el-dialog>
</el-dialog>
</
template
>
</
template
>
<
style
lang=
"scss"
scoped
>
.box
{
padding
:
20px
0
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
.el-button
{
width
:
220px
;
}
p
{
color
:
#999
;
margin-left
:
20px
;
}
}
</
style
>
src/modules/teacher/contest/record/components/ImportScoreDialog.vue
0 → 100644
浏览文件 @
ead3ac8b
<
script
setup
lang=
"ts"
>
import
{
Upload
}
from
'@element-plus/icons-vue'
import
{
useFileDialog
}
from
'@vueuse/core'
import
{
ElMessage
}
from
'element-plus'
import
{
useFilterList
}
from
'../composables/useFilterList'
import
{
importScore
}
from
'../api'
const
emit
=
defineEmits
<
{
(
e
:
'update'
):
void
}
>
()
const
{
competitions
}
=
useFilterList
()
const
form
=
reactive
<
any
>
({
competition_id
:
''
})
const
templateUrl
=
$computed
(()
=>
{
return
form
.
competition_id
?
`/api/lab//v1/expert/check/import-score?competition_id=
${
form
.
competition_id
}
`
:
''
})
// 批量导入考试成绩
const
{
files
,
open
}
=
useFileDialog
()
function
handleImport
()
{
if
(
!
form
.
competition_id
)
return
open
({
accept
:
'.csv,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel'
,
multiple
:
false
})
}
watchEffect
(()
=>
{
if
(
!
files
.
value
?.
length
)
return
const
[
file
]
=
files
.
value
importScore
({
competition_id
:
form
.
competition_id
,
file
}).
then
(()
=>
{
ElMessage
({
message
:
'导入成功'
,
type
:
'success'
})
emit
(
'update'
)
})
})
</
script
>
<
template
>
<el-dialog
title=
"批量导入考试成绩"
:close-on-click-modal=
"false"
width=
"400px"
>
<el-form
label-width=
"70px"
>
<el-form-item
label=
"赛项名称"
>
<el-select
v-model=
"form.competition_id"
>
<el-option
v-for=
"item in competitions"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
></el-option>
</el-select>
<a
:href=
"templateUrl"
download
style=
"margin-left: 10px"
v-if=
"templateUrl"
>
下载模板
</a>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
round
:icon=
"Upload"
@
click=
"handleImport"
:disabled=
"!form.competition_id"
style=
"width: 195px"
>
本地上传
</el-button
>
</el-form-item>
</el-form>
</el-dialog>
</
template
>
src/modules/teacher/contest/record/components/SyncExamDialog.vue
0 → 100644
浏览文件 @
ead3ac8b
<
script
setup
lang=
"ts"
>
import
{
ElMessage
}
from
'element-plus'
import
{
useFilterList
}
from
'../composables/useFilterList'
import
{
syncExam
}
from
'../api'
const
emit
=
defineEmits
<
{
(
e
:
'update'
):
void
}
>
()
const
{
competitions
}
=
useFilterList
()
const
form
=
reactive
<
any
>
({
competition
:
undefined
})
// 同步
function
handleSync
(
row
:
any
)
{
syncExam
({
competition_id
:
form
.
competition
?.
id
,
detail_id
:
row
.
id
}).
then
(()
=>
{
ElMessage
.
success
(
'同步成功'
)
emit
(
'update'
)
})
}
</
script
>
<
template
>
<el-dialog
title=
"同步1+X考试成绩"
:close-on-click-modal=
"false"
>
<el-form>
<el-form-item
label=
"赛项名称"
>
<el-select
v-model=
"form.competition"
value-key=
"id"
>
<el-option
v-for=
"item in competitions"
:key=
"item.id"
:label=
"item.name"
:value=
"item"
></el-option>
</el-select>
</el-form-item>
</el-form>
<el-table
:data=
"form.competition?.rules"
>
<el-table-column
label=
"评分方法"
prop=
"type"
align=
"center"
width=
"200"
></el-table-column>
<el-table-column
label=
"考试名称"
prop=
"exam_name"
align=
"center"
></el-table-column>
<el-table-column
label=
"实考人数/应考人数"
align=
"center"
width=
"160"
>
<template
#
default=
"
{ row }">
{{
row
.
finish_count
}}
/
{{
row
.
all_count
}}
</
template
>
</el-table-column>
<el-table-column
label=
"操作"
align=
"center"
width=
"160"
>
<
template
#
default=
"{ row }"
>
<el-button
round
type=
"primary"
@
click=
"handleSync(row)"
>
同步导入成绩
</el-button>
</
template
>
</el-table-column>
</el-table>
</el-dialog>
</template>
src/modules/teacher/contest/record/views/Index.vue
浏览文件 @
ead3ac8b
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
type
{
RecordItem
}
from
'../types'
import
{
Refresh
,
Upload
}
from
'@element-plus/icons-vue'
import
{
Refresh
,
Upload
}
from
'@element-plus/icons-vue'
import
AppList
from
'@/components/base/AppList.vue'
import
AppList
from
'@/components/base/AppList.vue'
import
{
getExperimentRecordList
}
from
'../api'
import
{
getExperimentRecordList
}
from
'../api'
import
{
useFilterList
}
from
'../composables/useFilterList'
import
{
useFilterList
}
from
'../composables/useFilterList'
const
ScoreDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/ScoreDialog.vue'
))
const
SyncExamDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/SyncExamDialog.vue'
))
const
ImportDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/ImportDialog.vue'
))
const
ImportExamDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/ImportExamDialog.vue'
))
const
ImportScoreDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/ImportScoreDialog.vue'
))
const
{
competitions
,
schools
,
status
}
=
useFilterList
()
const
{
competitions
,
schools
,
status
}
=
useFilterList
()
...
@@ -75,14 +75,11 @@ const listOptions = $computed(() => {
...
@@ -75,14 +75,11 @@ const listOptions = $computed(() => {
]
]
}
}
})
})
const
importVisible
=
$ref
(
false
)
let
dialogVisible
=
$ref
(
false
)
const
syncDialogVisible
=
$ref
(
false
)
const
rowData
=
ref
<
RecordItem
>
()
const
importExamVisible
=
$ref
(
false
)
// 评分
const
importScoreVisible
=
$ref
(
false
)
function
handleScore
(
row
:
RecordItem
)
{
rowData
.
value
=
row
dialogVisible
=
true
}
function
onUpdateSuccess
()
{
function
onUpdateSuccess
()
{
appList
?.
refetch
()
appList
?.
refetch
()
}
}
...
@@ -96,7 +93,7 @@ function onUpdateSuccess() {
...
@@ -96,7 +93,7 @@ function onUpdateSuccess() {
type=
"primary"
type=
"primary"
round
round
:icon=
"Refresh"
:icon=
"Refresh"
@
click=
"
import
Visible = true"
@
click=
"
syncDialog
Visible = true"
v-permission=
"'v1-teacher-record-upload'"
v-permission=
"'v1-teacher-record-upload'"
>
系统同步考试成绩
</el-button
>
系统同步考试成绩
</el-button
>
>
...
@@ -104,7 +101,7 @@ function onUpdateSuccess() {
...
@@ -104,7 +101,7 @@ function onUpdateSuccess() {
type=
"primary"
type=
"primary"
round
round
:icon=
"Upload"
:icon=
"Upload"
@
click=
"importVisible = true"
@
click=
"import
Exam
Visible = true"
v-permission=
"'v1-teacher-record-upload'"
v-permission=
"'v1-teacher-record-upload'"
>
批量导入考试成绩
</el-button
>
批量导入考试成绩
</el-button
>
>
...
@@ -112,7 +109,7 @@ function onUpdateSuccess() {
...
@@ -112,7 +109,7 @@ function onUpdateSuccess() {
type=
"primary"
type=
"primary"
round
round
:icon=
"Upload"
:icon=
"Upload"
@
click=
"importVisible = true"
@
click=
"import
Score
Visible = true"
v-permission=
"'v1-teacher-record-upload'"
v-permission=
"'v1-teacher-record-upload'"
>
批量导入完整评分
</el-button
>
批量导入完整评分
</el-button
>
>
...
@@ -122,25 +119,19 @@ function onUpdateSuccess() {
...
@@ -122,25 +119,19 @@ function onUpdateSuccess() {
<span
:class=
"
{ 'is-info': row.score !== '--' }">
{{
row
.
score
}}
</span>
<span
:class=
"
{ 'is-info': row.score !== '--' }">
{{
row
.
score
}}
</span>
</
template
>
</
template
>
<
template
#
table-x=
"{ row }"
>
<
template
#
table-x=
"{ row }"
>
<el-button
<el-button
text
type=
"primary"
v-if=
"row.checked_flag"
v-permission=
"'v1-teacher-record-check'"
>
评分
</el-button>
text
type=
"primary"
v-if=
"row.checked_flag"
@
click=
"handleScore(row)"
v-permission=
"'v1-teacher-record-check'"
>
评分
</el-button
>
</
template
>
</
template
>
</AppList>
</AppList>
</AppCard>
</AppCard>
<!-- 评分 -->
<!-- 系统同步考试成绩 -->
<ScoreDialog
<SyncExamDialog
v-model=
"syncDialogVisible"
@
update=
"onUpdateSuccess"
v-if=
"syncDialogVisible"
></SyncExamDialog>
v-model=
"dialogVisible"
<!-- 批量导入考试成绩 -->
:data=
"rowData"
<ImportExamDialog
v-model=
"importExamVisible"
@
update=
"onUpdateSuccess"
v-if=
"importExamVisible"
></ImportExamDialog>
<!-- 批量导入完整评分 -->
<ImportScoreDialog
v-model=
"importScoreVisible"
@
update=
"onUpdateSuccess"
@
update=
"onUpdateSuccess"
v-if=
"dialogVisible && rowData"
></ScoreDialog>
v-if=
"importScoreVisible"
></ImportScoreDialog>
<!-- 批量导入 -->
<ImportDialog
v-model=
"importVisible"
@
update=
"onUpdateSuccess"
v-if=
"importVisible"
></ImportDialog>
</template>
</template>
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
...
...
src/modules/teacher/contest/record/views/detail.vue
deleted
100644 → 0
浏览文件 @
a54bd8f3
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论