Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
saas-lab
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
saas-lab
Commits
9239d83a
提交
9239d83a
authored
9月 22, 2022
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore: update
上级
ead3ac8b
隐藏空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
259 行增加
和
184 行删除
+259
-184
api.ts
src/modules/teacher/contest/record/api.ts
+11
-17
ScoreDialog.vue
...modules/teacher/contest/record/components/ScoreDialog.vue
+59
-164
index.ts
src/modules/teacher/contest/record/index.ts
+4
-1
Detail.vue
src/modules/teacher/contest/record/views/Detail.vue
+181
-0
Index.vue
src/modules/teacher/contest/record/views/Index.vue
+4
-2
没有找到文件。
src/modules/teacher/contest/record/api.ts
浏览文件 @
9239d83a
...
@@ -2,13 +2,13 @@ import httpRequest from '@/utils/axios'
...
@@ -2,13 +2,13 @@ import httpRequest from '@/utils/axios'
// 获取实验记录列表
// 获取实验记录列表
export
function
getExperimentRecordList
(
params
?:
{
export
function
getExperimentRecordList
(
params
?:
{
course_id
?:
string
competition_id
?:
string
experiment_id
?:
string
check_status
?:
string
specialty_id
?:
string
organ_id
?:
string
class_id
?:
string
student_name
?:
string
student_name
?:
string
login_id
?:
string
page
?:
number
page
?:
number
page_size
?:
number
'per-page'
?:
number
})
{
})
{
return
httpRequest
.
get
(
'/api/lab/v1/expert/check/list'
,
{
params
})
return
httpRequest
.
get
(
'/api/lab/v1/expert/check/list'
,
{
params
})
}
}
...
@@ -18,20 +18,14 @@ export function getFilterList(params?: { leader?: number }) {
...
@@ -18,20 +18,14 @@ export function getFilterList(params?: { leader?: number }) {
return
httpRequest
.
get
(
'/api/lab/v1/expert/check/condition'
,
{
params
})
return
httpRequest
.
get
(
'/api/lab/v1/expert/check/condition'
,
{
params
})
}
}
//
获取实验记录
详情
//
大赛评分
详情
export
function
get
ExperimentRecord
(
params
:
{
experiment_id
:
string
;
student_
id
:
string
})
{
export
function
get
CheckView
(
params
:
{
id
:
string
})
{
return
httpRequest
.
get
(
'/api/lab/v1/
teacher/record
/view'
,
{
params
})
return
httpRequest
.
get
(
'/api/lab/v1/
expert/check
/view'
,
{
params
})
}
}
// 实验记录评分
// 评分
export
function
checkExperimentRecord
(
data
:
{
export
function
submitScore
(
data
:
{
id
:
string
;
scores
:
string
})
{
experiment_id
:
string
return
httpRequest
.
post
(
'/api/lab/v1/expert/check/set-score'
,
data
)
student_id
:
string
operate
:
number
result
:
number
file
:
number
})
{
return
httpRequest
.
post
(
'/api/lab/v1/teacher/record/check'
,
data
)
}
}
// 同步1+X考试成绩
// 同步1+X考试成绩
...
...
src/modules/teacher/contest/record/components/ScoreDialog.vue
浏览文件 @
9239d83a
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
{
ElMessage
}
from
'element-plus'
import
type
{
RecordItem
,
FileItem
}
from
'../types'
import
{
Document
}
from
'@element-plus/icons-vue'
import
{
ElMessage
,
ElMessageBox
}
from
'element-plus'
import
{
getExperimentRecord
,
checkExperimentRecord
}
from
'../api'
import
{
submitScore
}
from
'../api'
interface
Props
{
data
:
RecordItem
}
const
props
=
defineProps
<
Props
>
()
const
emit
=
defineEmits
<
{
const
emit
=
defineEmits
<
{
(
e
:
'update'
):
void
(
e
:
'update'
):
void
(
e
:
'update:modelValue'
,
visible
:
boolean
):
void
(
e
:
'update:modelValue'
,
visible
:
boolean
):
void
}
>
()
}
>
()
let
detail
=
$ref
<
RecordItem
>
()
const
detail
=
$ref
<
any
>
(
inject
(
'detail'
))
function
fetchInfo
()
{
let
tableList
=
$ref
<
any
>
([])
getExperimentRecord
({
experiment_id
:
props
.
data
.
experiment_id
,
student_id
:
props
.
data
.
student_id
}).
then
(
res
=>
{
detail
=
res
.
data
})
}
watchEffect
(()
=>
{
watchEffect
(()
=>
{
fetchInfo
()
const
checkDetails
=
detail
?.
check_details
||
[]
})
tableList
=
checkDetails
.
map
((
item
:
any
)
=>
{
// 实验报告文件
return
{
const
file
=
$computed
<
FileItem
>
(()
=>
{
...
item
,
try
{
old_score
:
parseFloat
(
item
.
old_score
),
return
detail
?.
file
?
JSON
.
parse
(
detail
.
file
)
:
null
ratio
:
parseFloat
(
item
.
ratio
),
}
catch
(
error
)
{
score
:
parseFloat
(
item
.
score
)
console
.
log
(
error
)
}
}
})
return
null
})
// 实验过程截图
const
pictures
=
$computed
<
FileItem
[]
>
(()
=>
{
try
{
return
detail
?.
pictures
?
JSON
.
parse
(
detail
.
pictures
)
:
[]
}
catch
(
error
)
{
console
.
log
(
error
)
}
return
[]
})
})
const
formRef
=
$ref
<
FormInstance
>
()
const
form
=
reactive
<
{
operate
?:
number
;
result
?:
number
;
file
?:
number
}
>
({
operate
:
undefined
,
result
:
undefined
,
file
:
undefined
})
const
score
=
$computed
<
number
>
(()
=>
{
const
score
=
$computed
<
number
>
(()
=>
{
const
result
=
((
form
.
operate
||
0
)
+
(
form
.
result
||
0
)
+
(
form
.
file
||
0
))
/
3
return
tableList
.
reduce
((
result
:
number
,
item
:
any
)
=>
{
return
parseFloat
(
result
.
toFixed
(
2
))
return
(
result
+=
item
.
score
||
0
)
})
},
0
)
const
rules
=
ref
<
FormRules
>
({
operate
:
[{
required
:
true
,
message
:
'请输入1~100数字'
}],
result
:
[{
required
:
true
,
message
:
'请输入1~100数字'
}],
file
:
[{
required
:
true
,
message
:
'请输入1~100数字'
}]
})
})
// 提交
// 提交
function
handleSubmit
()
{
function
handleSubmit
()
{
formRef
?.
validate
().
then
(()
=>
{
const
scores
=
tableList
.
map
((
item
:
any
)
=>
{
ElMessageBox
.
confirm
(
'成绩评分不能修改,确认要保存该成绩吗?'
,
'提示'
).
then
(()
=>
{
return
{
id
:
item
.
id
,
score
:
item
.
score
}
const
params
:
any
=
{
...
form
,
experiment_id
:
props
.
data
.
experiment_id
,
student_id
:
props
.
data
.
student_id
}
})
checkExperimentRecord
(
params
).
then
(()
=>
{
const
params
=
{
id
:
detail
.
id
,
scores
:
JSON
.
stringify
(
scores
)
}
ElMessage
({
message
:
'保存成功'
,
type
:
'success'
})
submitScore
(
params
).
then
(()
=>
{
emit
(
'update'
)
ElMessage
({
message
:
'保存成功'
,
type
:
'success'
})
emit
(
'update:modelValue'
,
false
)
emit
(
'update'
)
})
emit
(
'update:modelValue'
,
false
)
})
})
})
}
}
</
script
>
</
script
>
<
template
>
<
template
>
<el-dialog
<el-dialog
title=
"评分"
:close-on-click-modal=
"false"
width=
"700px"
@
update:modelValue=
"$emit('update:modelValue')"
>
title=
"学生实验评分"
<el-form
label-suffix=
":"
v-if=
"detail"
>
:close-on-click-modal=
"false"
<el-form-item
label=
"赛项名称"
>
{{
detail
.
competition_id_name
}}
</el-form-item>
width=
"700px"
<el-form-item
label=
"选手姓名"
>
{{
detail
.
student_name
}}
</el-form-item>
@
update:modelValue=
"$emit('update:modelValue')"
<el-form-item
label=
"选手ID"
>
{{
detail
.
login_id
}}
</el-form-item>
>
<el-form
:rules=
"rules"
label-width=
"120px"
label-suffix=
":"
v-if=
"detail"
>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"实验名称"
>
{{
detail
.
experiment_name
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"实验课程名称"
>
{{
detail
.
course_name
}}
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"学生姓名"
>
{{
detail
.
student_name
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"学生学号"
>
{{
detail
.
sno_number
}}
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"所属专业"
>
{{
detail
.
specialty_name
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"所属班级"
>
{{
detail
.
class_name
}}
</el-form-item>
</el-col>
</el-row>
<el-form-item
label=
"实验成绩"
class=
"form-item-score"
>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"rules"
hide-required-asterisk
inline
label-position=
"top"
style=
"padding: 5px 0 20px"
>
<el-form-item
label=
"实验操作"
prop=
"operate"
>
<el-input-number
:min=
"1"
:max=
"100"
:controls=
"false"
step-strictly
v-model=
"form.operate"
/>
</el-form-item>
<el-form-item
label=
"实验结果"
prop=
"result"
>
<el-input-number
:min=
"1"
:max=
"100"
:controls=
"false"
step-strictly
v-model=
"form.result"
/>
</el-form-item>
<el-form-item
label=
"实验报告"
prop=
"file"
>
<el-input-number
:min=
"1"
:max=
"100"
:controls=
"false"
step-strictly
v-model=
"form.file"
/>
</el-form-item>
<el-form-item
label=
"综合实验成绩"
>
<el-input-number
:min=
"0"
:max=
"100"
:controls=
"false"
disabled
v-model=
"score"
/>
</el-form-item>
</el-form>
</el-form-item>
<el-form-item
label=
"实验报告文件"
>
<div
v-if=
"file"
>
<a
:href=
"file.url"
target=
"_blank"
class=
"file-item"
>
<el-icon><Document
/></el-icon>
{{
file
.
name
}}
</a>
</div>
</el-form-item>
<el-form-item
label=
"实验过程截图"
>
<ul
class=
"picture-list"
>
<li
v-for=
"item in pictures"
:key=
"item.url"
>
<p
class=
"t1"
>
<a
:href=
"item.url"
target=
"_blank"
>
{{
item
.
name
}}
</a>
</p>
<p
class=
"t2"
>
截图时间:
{{
item
.
upload_time
}}
</p>
</li>
</ul>
</el-form-item>
<el-row
justify=
"center"
>
<el-button
type=
"primary"
round
auto-insert-space
@
click=
"handleSubmit"
>
保存
</el-button>
<el-button
round
auto-insert-space
@
click=
"$emit('update:modelValue', false)"
>
取消
</el-button>
</el-row>
</el-form>
</el-form>
<el-table
:data=
"tableList"
:header-cell-style=
"
{ background: '#ededed' }">
<el-table-column
label=
"评分规则"
prop=
"name"
align=
"center"
></el-table-column>
<el-table-column
label=
"评分方法"
prop=
"type_name"
align=
"center"
></el-table-column>
<el-table-column
label=
"分值"
prop=
"old_score"
align=
"center"
></el-table-column>
<el-table-column
label=
"占比(%)"
prop=
"ratio"
align=
"center"
></el-table-column>
<el-table-column
label=
"评分"
prop=
"score"
align=
"center"
>
<template
#
default=
"
{ row }">
<el-input-number
:controls=
"false"
v-model=
"row.score"
:min=
"0"
:max=
"row.old_score"
:disabled=
"row.type === '2'"
style=
"width: 100%"
/>
</
template
>
</el-table-column>
</el-table>
<p
class=
"result"
>
最终得分:
<span>
{{ score }}
</span>
</p>
<el-row
justify=
"center"
>
<el-button
type=
"primary"
round
auto-insert-space
@
click=
"handleSubmit"
>
保存
</el-button>
<el-button
round
auto-insert-space
@
click=
"$emit('update:modelValue', false)"
>
取消
</el-button>
</el-row>
</el-dialog>
</el-dialog>
</template>
</template>
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
.file-item
{
.result
{
padding
:
40px
0
;
display
:
flex
;
display
:
flex
;
align-items
:
center
;
align-items
:
center
;
color
:
var
(
--
main-color
);
justify-content
:
center
;
.el-icon
{
span
{
margin-right
:
5px
;
padding
:
0
10px
;
}
font-size
:
40px
;
}
.picture-list
{
width
:
100%
;
li
{
display
:
flex
;
justify-content
:
space-between
;
}
a
{
color
:
var
(
--
main-color
);
color
:
var
(
--
main-color
);
}
}
.t1
{
flex
:
1
;
white-space
:
nowrap
;
text-overflow
:
ellipsis
;
overflow
:
hidden
;
}
}
.form-item-score
{
padding-top
:
10px
;
background-color
:
#f8f9fb
;
border-radius
:
16px
;
:deep
(
.el-form-item__label
)
{
text-align
:
center
;
}
.el-input-number
{
width
:
100px
;
}
}
}
</
style
>
</
style
>
src/modules/teacher/contest/record/index.ts
浏览文件 @
9239d83a
...
@@ -5,6 +5,9 @@ export const routes: Array<RouteRecordRaw> = [
...
@@ -5,6 +5,9 @@ export const routes: Array<RouteRecordRaw> = [
{
{
path
:
'/teacher/contest/record'
,
path
:
'/teacher/contest/record'
,
component
:
AppLayout
,
component
:
AppLayout
,
children
:
[{
path
:
''
,
component
:
()
=>
import
(
'./views/Index.vue'
)
}]
children
:
[
{
path
:
''
,
component
:
()
=>
import
(
'./views/Index.vue'
)
},
{
path
:
':id'
,
component
:
()
=>
import
(
'./views/Detail.vue'
),
props
:
true
}
]
}
}
]
]
src/modules/teacher/contest/record/views/Detail.vue
0 → 100644
浏览文件 @
9239d83a
<
script
setup
lang=
"ts"
>
import
Preview
from
'@/components/Preview.vue'
import
{
getCheckView
}
from
'../api'
const
ScoreDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/ScoreDialog.vue'
))
interface
Props
{
id
:
string
}
const
props
=
defineProps
<
Props
>
()
// 左侧
const
leftPanelVisible
=
$ref
<
boolean
>
(
true
)
let
detail
=
$ref
<
any
>
()
provide
(
'detail'
,
$$
(
detail
))
// 评分规则文件
const
file
=
$computed
(()
=>
{
return
detail
?
JSON
.
parse
(
detail
?.
competition_rubric
.
url
)
:
{
url
:
''
}
})
function
fetchInfo
()
{
getCheckView
({
id
:
props
.
id
}).
then
(
res
=>
{
detail
=
res
.
data
})
}
watchEffect
(()
=>
{
fetchInfo
()
})
// 右侧
const
LAB_URL
=
import
.
meta
.
env
.
VITE_LAB_URL
// 评分
const
dialogVisible
=
$ref
(
false
)
</
script
>
<
template
>
<section
class=
"lab"
v-if=
"detail"
>
<div
class=
"lab-left"
:class=
"
{ 'is-hidden': !leftPanelVisible }">
<div
class=
"lab-left__inner"
>
<el-tabs
type=
"border-card"
>
<el-tab-pane
label=
"评分规则"
lazy
>
<Preview
:url=
"file.url"
></Preview>
</el-tab-pane>
</el-tabs>
</div>
<div
class=
"panel-icon"
@
click=
"leftPanelVisible = !leftPanelVisible"
>
<svg
xmlns=
"http://www.w3.org/2000/svg"
viewBox=
"0 0 16 86"
aria-hidden=
"true"
width=
"16"
height=
"86"
>
<g
fill=
"none"
fill-rule=
"evenodd"
>
<path
class=
"path-wapper"
d=
"M0 0l14.12 8.825A4 4 0 0116 12.217v61.566a4 4 0 01-1.88 3.392L0 86V0z"
fill=
"#e1e4eb"
></path>
<path
class=
"path-arrow"
d=
"M10.758 48.766a.778.778 0 000-1.127L6.996 43l3.762-4.639a.778.778 0 000-1.127.85.85 0 00-1.172 0l-4.344 5.202a.78.78 0 000 1.128l4.344 5.202a.85.85 0 001.172 0z"
fill=
"#8D9EA7"
fill-rule=
"nonzero"
></path>
</g>
</svg>
</div>
</div>
<div
class=
"lab-right"
>
<AppCard>
<el-row
justify=
"space-between"
>
<div
class=
"info"
>
<p>
赛项名称:
<span>
{{
detail
.
competition_id_name
}}
</span>
</p>
<p>
选手姓名:
<span>
{{
detail
.
student_name
}}
</span>
</p>
<p>
选手ID:
<span>
{{
detail
.
login_id
}}
</span>
</p>
</div>
<div>
<el-button
type=
"primary"
@
click=
"dialogVisible = true"
>
评分
</el-button>
</div>
</el-row>
</AppCard>
<div
class=
"lab-box"
>
<iframe
:src=
"LAB_URL"
frameborder=
"0"
class=
"iframe"
ref=
"iframeRef"
></iframe>
</div>
</div>
</section>
<ScoreDialog
v-model=
"dialogVisible"
></ScoreDialog>
</
template
>
<
style
lang=
"scss"
scoped
>
.lab
{
display
:
flex
;
height
:
calc
(
100vh
-
110px
);
}
.lab-left
{
position
:
relative
;
width
:
400px
;
padding
:
20px
;
background-color
:
#e1e4eb
;
border-radius
:
6px
;
box-sizing
:
border-box
;
transition
:
all
0
.1s
;
&
.is-hidden
{
width
:
0
;
padding
:
0
;
.panel-icon
{
left
:
-20px
;
right
:
0
;
}
.path-arrow
{
transform-origin
:
center
center
;
transform
:
rotate
(
180deg
);
}
}
.lab-left__inner
{
display
:
flex
;
flex-direction
:
column
;
width
:
100%
;
height
:
100%
;
overflow
:
hidden
;
}
.el-tabs
{
flex
:
1
;
border
:
0
;
overflow
:
hidden
;
}
:deep
(
.el-tabs__header
)
{
background-color
:
#e1e4eb
;
}
:deep
(
.el-tabs__item
)
{
padding
:
0
14px
!
important
;
border
:
0
;
border-radius
:
6px
6px
0px
0px
;
}
:deep
(
.el-tabs__content
)
{
height
:
calc
(
100%
-
40px
);
box-sizing
:
border-box
;
}
:deep
(
.el-tab-pane
)
{
height
:
100%
;
overflow-y
:
auto
;
}
}
.panel-icon
{
position
:
absolute
;
top
:
50%
;
right
:
-16px
;
width
:
16px
;
height
:
86px
;
transform
:
translateY
(
-50%
);
z-index
:
100
;
cursor
:
pointer
;
}
.lab-right
{
margin-left
:
20px
;
flex
:
1
;
display
:
flex
;
flex-direction
:
column
;
height
:
100%
;
}
.lab-box
{
flex
:
1
;
width
:
100%
;
margin-top
:
20px
;
}
.iframe
{
width
:
100%
;
height
:
100%
;
}
.info
{
flex
:
1
;
display
:
flex
;
align-items
:
center
;
span
{
color
:
var
(
--
main-color
);
}
p
+
p
{
margin-left
:
40px
;
}
}
</
style
>
src/modules/teacher/contest/record/views/Index.vue
浏览文件 @
9239d83a
...
@@ -69,7 +69,7 @@ const listOptions = $computed(() => {
...
@@ -69,7 +69,7 @@ const listOptions = $computed(() => {
{
label
:
'评分规则'
,
prop
:
'competition_is_more_status'
},
{
label
:
'评分规则'
,
prop
:
'competition_is_more_status'
},
{
label
:
'已评分人数'
,
prop
:
'checked_count'
,
slots
:
'table-count'
},
{
label
:
'已评分人数'
,
prop
:
'checked_count'
,
slots
:
'table-count'
},
{
label
:
'已评分'
,
prop
:
'checked_flag_name'
},
{
label
:
'已评分'
,
prop
:
'checked_flag_name'
},
{
label
:
'得分'
,
prop
:
'score
'
,
slots
:
'table-scor
e'
},
{
label
:
'得分'
,
prop
:
'score
_nam
e'
},
{
label
:
'更新时间'
,
prop
:
'updated_time'
},
{
label
:
'更新时间'
,
prop
:
'updated_time'
},
{
label
:
'操作'
,
slots
:
'table-x'
,
width
:
100
}
{
label
:
'操作'
,
slots
:
'table-x'
,
width
:
100
}
]
]
...
@@ -119,7 +119,9 @@ function onUpdateSuccess() {
...
@@ -119,7 +119,9 @@ 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
text
type=
"primary"
v-if=
"row.checked_flag"
v-permission=
"'v1-teacher-record-check'"
>
评分
</el-button>
<el-button
text
type=
"primary"
v-if=
"row.publish_status === '0'"
v-permission=
"'v1-teacher-record-check'"
>
<router-link
:to=
"`/teacher/contest/record/$
{row.id}`" target="_blank">评分
</router-link>
</el-button>
</
template
>
</
template
>
</AppList>
</AppList>
</AppCard>
</AppCard>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论