Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
saas-lab
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
saas-lab
Commits
72a9cb18
提交
72a9cb18
authored
11月 22, 2022
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore: update
上级
85bb0940
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
20 个修改的文件
包含
679 行增加
和
363 行删除
+679
-363
package-lock.json
package-lock.json
+9
-12
DragPanel.vue
src/components/DragPanel.vue
+1
-1
ReportPreview.vue
...modules/admin/lab/experiment/components/ReportPreview.vue
+1
-1
api.ts
src/modules/admin/lab/score/api.ts
+33
-0
ScoreDialog.vue
src/modules/admin/lab/score/components/ScoreDialog.vue
+0
-0
ScoreLogDialog.vue
src/modules/admin/lab/score/components/ScoreLogDialog.vue
+22
-6
ScoreViewPicturesDialog.vue
...es/admin/lab/score/components/ScoreViewPicturesDialog.vue
+56
-0
ScoreViewPrepareDialog.vue
...les/admin/lab/score/components/ScoreViewPrepareDialog.vue
+30
-0
ScoreViewResultDialog.vue
...ules/admin/lab/score/components/ScoreViewResultDialog.vue
+30
-0
index.ts
src/modules/admin/lab/score/index.ts
+4
-1
Report.vue
src/modules/admin/lab/score/views/Report.vue
+211
-0
api.ts
src/modules/student/lab/api.ts
+5
-0
ReportFilePreview.vue
src/modules/student/lab/components/ReportFilePreview.vue
+53
-0
ReportPreivew.vue
src/modules/student/lab/components/ReportPreivew.vue
+143
-0
Result.vue
src/modules/student/lab/components/Result.vue
+5
-1
ResultScoreDialog.vue
src/modules/student/lab/components/ResultScoreDialog.vue
+44
-69
index.ts
src/modules/student/lab/index.ts
+2
-1
Index.vue
src/modules/student/lab/views/Index.vue
+27
-15
Report.vue
src/modules/student/lab/views/Report.vue
+1
-1
ReportView.vue
src/modules/student/lab/views/ReportView.vue
+2
-255
没有找到文件。
package-lock.json
浏览文件 @
72a9cb18
...
@@ -22,7 +22,7 @@
...
@@ -22,7 +22,7 @@
"element-plus"
:
"^2.2.21"
,
"element-plus"
:
"^2.2.21"
,
"file-saver"
:
"^2.0.5"
,
"file-saver"
:
"^2.0.5"
,
"lodash-es"
:
"^4.17.21"
,
"lodash-es"
:
"^4.17.21"
,
"pinia"
:
"^2.0.2
3
"
,
"pinia"
:
"^2.0.2
4
"
,
"qs"
:
"^6.11.0"
,
"qs"
:
"^6.11.0"
,
"ua-parser-js"
:
"^1.0.32"
,
"ua-parser-js"
:
"^1.0.32"
,
"video.js"
:
"^7.20.3"
,
"video.js"
:
"^7.20.3"
,
...
@@ -3656,16 +3656,13 @@
...
@@ -3656,16 +3656,13 @@
}
}
},
},
"node_modules/pinia"
:
{
"node_modules/pinia"
:
{
"version"
:
"2.0.2
3
"
,
"version"
:
"2.0.2
4
"
,
"resolved"
:
"https://registry.npm
js.org/pinia/-/pinia-2.0.23
.tgz"
,
"resolved"
:
"https://registry.npm
mirror.com/pinia/-/pinia-2.0.24
.tgz"
,
"integrity"
:
"sha512-
N15hFf4o5STrxpNrib1IEb1GOArvPYf1zPvQVRGOO1G1d74Ak0J0lVyalX/SmrzdT4Q0nlEFjbURsmBmIGUR5Q
=="
,
"integrity"
:
"sha512-
DDLd4Iphyc+6PYYYbx7jkb6WP9gecgu9bz9huyB5rb7CdJI3DhzYiZI+/Ih8MLewRrP9DSpslF/BgSNrJtZU7A
=="
,
"dependencies"
:
{
"dependencies"
:
{
"@vue/devtools-api"
:
"^6.4.
4
"
,
"@vue/devtools-api"
:
"^6.4.
5
"
,
"vue-demi"
:
"*"
"vue-demi"
:
"*"
},
},
"funding"
:
{
"url"
:
"https://github.com/sponsors/posva"
},
"peerDependencies"
:
{
"peerDependencies"
:
{
"@vue/composition-api"
:
"^1.4.0"
,
"@vue/composition-api"
:
"^1.4.0"
,
"typescript"
:
">=4.4.4"
,
"typescript"
:
">=4.4.4"
,
...
@@ -7761,11 +7758,11 @@
...
@@ -7761,11 +7758,11 @@
"dev"
:
true
"dev"
:
true
},
},
"pinia"
:
{
"pinia"
:
{
"version"
:
"2.0.2
3
"
,
"version"
:
"2.0.2
4
"
,
"resolved"
:
"https://registry.npm
js.org/pinia/-/pinia-2.0.23
.tgz"
,
"resolved"
:
"https://registry.npm
mirror.com/pinia/-/pinia-2.0.24
.tgz"
,
"integrity"
:
"sha512-
N15hFf4o5STrxpNrib1IEb1GOArvPYf1zPvQVRGOO1G1d74Ak0J0lVyalX/SmrzdT4Q0nlEFjbURsmBmIGUR5Q
=="
,
"integrity"
:
"sha512-
DDLd4Iphyc+6PYYYbx7jkb6WP9gecgu9bz9huyB5rb7CdJI3DhzYiZI+/Ih8MLewRrP9DSpslF/BgSNrJtZU7A
=="
,
"requires"
:
{
"requires"
:
{
"@vue/devtools-api"
:
"^6.4.
4
"
,
"@vue/devtools-api"
:
"^6.4.
5
"
,
"vue-demi"
:
"*"
"vue-demi"
:
"*"
},
},
"dependencies"
:
{
"dependencies"
:
{
...
...
src/components/DragPanel.vue
浏览文件 @
72a9cb18
...
@@ -102,7 +102,7 @@ onMounted(() => {
...
@@ -102,7 +102,7 @@ onMounted(() => {
bottom
:
0
;
bottom
:
0
;
width
:
20px
;
width
:
20px
;
cursor
:
col-resize
;
cursor
:
col-resize
;
z-index
:
999
9
;
z-index
:
999
;
}
}
.panel-icon
{
.panel-icon
{
position
:
absolute
;
position
:
absolute
;
...
...
src/modules/admin/lab/experiment/components/ReportPreview.vue
浏览文件 @
72a9cb18
...
@@ -103,7 +103,7 @@ const teacherText = $computed(() => {
...
@@ -103,7 +103,7 @@ const teacherText = $computed(() => {
</el-dialog>
</el-dialog>
</template>
</template>
<
style
lang=
"scss"
>
<
style
lang=
"scss"
scoped
>
.report-preview
{
.report-preview
{
h1
{
h1
{
font-size
:
24px
;
font-size
:
24px
;
...
...
src/modules/admin/lab/score/api.ts
浏览文件 @
72a9cb18
...
@@ -40,3 +40,36 @@ export function uploadCheckExperimentRecord(data: { file: File }) {
...
@@ -40,3 +40,36 @@ export function uploadCheckExperimentRecord(data: { file: File }) {
headers
:
{
'Content-Type'
:
'multipart/form-data'
}
headers
:
{
'Content-Type'
:
'multipart/form-data'
}
})
})
}
}
// 获取实验准备
export
function
getExperimentPrepare
(
params
:
{
experiment_id
:
string
;
student_id
:
string
})
{
return
httpRequest
.
get
(
'/api/lab/v1/teacher/experiment/pre-detail'
,
{
params
})
}
// 获取实验结果
export
function
getExperimentResult
(
params
:
{
experiment_id
:
string
;
student_id
:
string
})
{
return
httpRequest
.
get
(
'/api/lab/v1/teacher/experiment/result-detail'
,
{
params
})
}
// 获取实验报告
export
function
getExperimentReport
(
params
:
{
experiment_id
:
string
;
student_id
:
string
})
{
return
httpRequest
.
get
(
'/api/lab/v1/teacher/experiment/report-achievement'
,
{
params
})
}
// 批改学员实验报告成绩
export
function
updateExperimentReport
(
data
:
{
experiment_id
:
string
;
student_id
:
string
;
score_detail
:
string
})
{
return
httpRequest
.
post
(
'/api/lab/v1/teacher/experiment/report-check'
,
data
)
}
// 获取实验评分模板
export
function
getExperimentScoreTemplate
(
params
:
{
experiment_id
:
string
})
{
return
httpRequest
.
get
(
'/api/lab/v1/teacher/experiment/score-template'
,
{
params
})
}
// 获取实验成绩
export
function
getExperimentScore
(
params
:
{
experiment_id
:
string
;
student_id
:
string
})
{
return
httpRequest
.
get
(
'/api/lab/v1/teacher/experiment/achievement'
,
{
params
})
}
// 批改学员实验成绩
export
function
updateExperimentScore
(
data
:
{
experiment_id
:
string
;
student_id
:
string
;
score_details
:
string
})
{
return
httpRequest
.
post
(
'/api/lab/v1/teacher/experiment/achievement-check'
,
data
)
}
src/modules/admin/lab/score/components/ScoreDialog.vue
浏览文件 @
72a9cb18
差异被折叠。
点击展开。
src/modules/admin/lab/score/components/ScoreLogDialog.vue
浏览文件 @
72a9cb18
...
@@ -8,7 +8,18 @@ interface Props {
...
@@ -8,7 +8,18 @@ interface Props {
}
}
const
props
=
defineProps
<
Props
>
()
const
props
=
defineProps
<
Props
>
()
let
detail
=
$ref
<
RecordItem
>
()
let
detail
=
$ref
<
any
>
()
const
dataList
=
$computed
(()
=>
{
return
(
detail
?.
score_log
.
map
((
item
:
any
)
=>
{
const
customData
=
item
.
score_details
.
reduce
((
result
:
any
,
item
:
any
)
=>
{
result
[
item
.
id
]
=
item
.
commit_score
return
result
},
{})
return
{
...
item
,
...
customData
}
})
||
[]
)
})
function
fetchInfo
()
{
function
fetchInfo
()
{
getExperimentRecord
({
experiment_id
:
props
.
data
.
experiment_id
,
student_id
:
props
.
data
.
student_id
}).
then
(
res
=>
{
getExperimentRecord
({
experiment_id
:
props
.
data
.
experiment_id
,
student_id
:
props
.
data
.
student_id
}).
then
(
res
=>
{
detail
=
res
.
data
detail
=
res
.
data
...
@@ -21,19 +32,24 @@ watchEffect(() => {
...
@@ -21,19 +32,24 @@ watchEffect(() => {
const
appList
=
$ref
<
InstanceType
<
typeof
AppList
>
|
null
>
(
null
)
const
appList
=
$ref
<
InstanceType
<
typeof
AppList
>
|
null
>
(
null
)
// 列表配置
// 列表配置
const
listOptions
=
$computed
(()
=>
{
const
listOptions
=
$computed
(()
=>
{
let
customColumns
:
any
=
[]
if
(
detail
?.
score_details
)
{
customColumns
=
Object
.
values
(
detail
?.
score_details
)
.
filter
((
item
:
any
)
=>
item
.
id
)
.
map
((
item
:
any
)
=>
{
return
{
prop
:
item
.
id
,
label
:
`
${
item
.
name
}
成绩`
}
})
}
return
{
return
{
columns
:
[
columns
:
[
{
label
:
'序号'
,
type
:
'index'
,
width
:
60
},
{
label
:
'序号'
,
type
:
'index'
,
width
:
60
},
{
label
:
'姓名'
,
prop
:
'student_name'
,
slots
:
'table-name'
},
{
label
:
'姓名'
,
prop
:
'student_name'
,
slots
:
'table-name'
},
{
label
:
'学号'
,
prop
:
'sno_number'
,
slots
:
'table-number'
},
{
label
:
'学号'
,
prop
:
'sno_number'
,
slots
:
'table-number'
},
{
label
:
'实验操作成绩'
,
prop
:
'operate'
},
...
customColumns
,
{
label
:
'实验结果成绩'
,
prop
:
'result'
},
{
label
:
'实验报告成绩'
,
prop
:
'file'
},
{
label
:
'综合实验成绩'
,
prop
:
'score'
},
{
label
:
'评分时间'
,
prop
:
'check_time'
},
{
label
:
'评分时间'
,
prop
:
'check_time'
},
{
label
:
'评分人'
,
prop
:
'checker_id_name'
}
{
label
:
'评分人'
,
prop
:
'checker_id_name'
}
],
],
data
:
d
etail
?.
score_log
data
:
d
ataList
}
}
})
})
</
script
>
</
script
>
...
...
src/modules/admin/lab/score/components/ScoreViewPicturesDialog.vue
0 → 100644
浏览文件 @
72a9cb18
<
script
setup
lang=
"ts"
>
import
type
{
RecordItem
,
FileItem
}
from
'../types'
interface
Props
{
data
:
RecordItem
}
const
props
=
defineProps
<
Props
>
()
// 实验过程截图
const
pictures
=
$computed
<
FileItem
[]
>
(()
=>
{
try
{
return
props
.
data
?.
pictures
?
JSON
.
parse
(
props
.
data
.
pictures
)
:
[]
}
catch
(
error
)
{
console
.
log
(
error
)
}
return
[]
})
</
script
>
<
template
>
<el-dialog
title=
"查看实验截图"
width=
"800px"
>
<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>
<template
#
footer
>
<el-row
justify=
"center"
>
<el-button
round
auto-insert-space
@
click=
"$emit('update:modelValue', false)"
>
关闭
</el-button>
</el-row>
</
template
>
</el-dialog>
</template>
<
style
lang=
"scss"
scoped
>
.picture-list
{
width
:
100%
;
li
{
display
:
flex
;
justify-content
:
space-between
;
line-height
:
30px
;
}
a
{
color
:
var
(
--
main-color
);
}
.t1
{
flex
:
1
;
white-space
:
nowrap
;
text-overflow
:
ellipsis
;
overflow
:
hidden
;
}
}
</
style
>
src/modules/admin/lab/score/components/ScoreViewPrepareDialog.vue
0 → 100644
浏览文件 @
72a9cb18
<
script
setup
lang=
"ts"
>
import
{
getExperimentPrepare
}
from
'../api'
interface
Props
{
experiment_id
:
string
student_id
:
string
}
const
props
=
defineProps
<
Props
>
()
let
detail
=
$ref
<
any
>
()
function
fetchInfo
()
{
getExperimentPrepare
({
experiment_id
:
props
.
experiment_id
,
student_id
:
props
.
student_id
}).
then
(
res
=>
{
detail
=
res
.
data
.
detail
})
}
onMounted
(()
=>
{
fetchInfo
()
})
</
script
>
<
template
>
<el-dialog
title=
"查看实验准备"
width=
"800px"
>
<div
v-html=
"detail.detail"
v-if=
"detail"
></div>
<template
#
footer
>
<el-row
justify=
"center"
>
<el-button
round
auto-insert-space
@
click=
"$emit('update:modelValue', false)"
>
关闭
</el-button>
</el-row>
</
template
>
</el-dialog>
</template>
src/modules/admin/lab/score/components/ScoreViewResultDialog.vue
0 → 100644
浏览文件 @
72a9cb18
<
script
setup
lang=
"ts"
>
import
{
getExperimentResult
}
from
'../api'
interface
Props
{
experiment_id
:
string
student_id
:
string
}
const
props
=
defineProps
<
Props
>
()
let
detail
=
$ref
<
any
>
()
function
fetchInfo
()
{
getExperimentResult
({
experiment_id
:
props
.
experiment_id
,
student_id
:
props
.
student_id
}).
then
(
res
=>
{
detail
=
res
.
data
.
detail
})
}
onMounted
(()
=>
{
fetchInfo
()
})
</
script
>
<
template
>
<el-dialog
title=
"查看实验结果"
width=
"800px"
>
<div
v-html=
"detail.detail"
v-if=
"detail"
></div>
<template
#
footer
>
<el-row
justify=
"center"
>
<el-button
round
auto-insert-space
@
click=
"$emit('update:modelValue', false)"
>
关闭
</el-button>
</el-row>
</
template
>
</el-dialog>
</template>
src/modules/admin/lab/score/index.ts
浏览文件 @
72a9cb18
...
@@ -5,6 +5,9 @@ export const routes: Array<RouteRecordRaw> = [
...
@@ -5,6 +5,9 @@ export const routes: Array<RouteRecordRaw> = [
{
{
path
:
'/admin/lab/score'
,
path
:
'/admin/lab/score'
,
component
:
AppLayout
,
component
:
AppLayout
,
children
:
[{
path
:
''
,
component
:
()
=>
import
(
'./views/Index.vue'
)
}]
children
:
[
{
path
:
''
,
component
:
()
=>
import
(
'./views/Index.vue'
)
},
{
path
:
'report'
,
component
:
()
=>
import
(
'./views/Report.vue'
)
}
]
}
}
]
]
src/modules/admin/lab/score/views/Report.vue
0 → 100644
浏览文件 @
72a9cb18
<
script
setup
>
import
{
getExperimentScore
,
getExperimentReport
,
updateExperimentReport
}
from
'../api'
import
{
reportScoreRule
}
from
'@/utils/dictionary'
const
route
=
useRoute
()
let
experiment
=
$ref
()
let
report
=
$ref
()
const
form
=
reactive
({
experiment_id
:
route
.
query
.
experiment_id
,
student_id
:
route
.
query
.
student_id
,
score_detail
:
[]
})
const
teacherText
=
$computed
(()
=>
{
if
(
!
experiment
)
return
''
return
experiment
.
teachers
.
map
(
item
=>
item
.
name
).
join
(
'、'
)
})
const
classText
=
$computed
(()
=>
{
if
(
!
experiment
)
return
''
return
experiment
.
student
.
classes
?.
map
(
item
=>
item
.
name
).
join
(
'、'
)
})
function
fetchInfo
()
{
getExperimentScore
({
experiment_id
:
route
.
query
.
experiment_id
,
student_id
:
route
.
query
.
student_id
}).
then
(
res
=>
{
experiment
=
res
.
data
.
experiment
})
}
function
fetchReport
()
{
getExperimentReport
({
experiment_id
:
route
.
query
.
experiment_id
,
student_id
:
route
.
query
.
student_id
}).
then
(
res
=>
{
report
=
res
.
data
.
detail
let
detail
=
[]
try
{
detail
=
JSON
.
parse
(
report
.
score_detail
||
report
.
detail
)
}
catch
(
error
)
{
console
.
log
(
error
)
}
form
.
score_detail
=
detail
.
map
(
item
=>
{
item
.
min_score
=
parseFloat
(
item
.
min_score
)
item
.
commit_score
=
item
.
commit_score
?
parseFloat
(
item
.
commit_score
)
:
0
item
.
commit
=
item
.
commit
||
''
return
item
})
})
}
onMounted
(()
=>
{
fetchInfo
()
fetchReport
()
})
const
score
=
$computed
(()
=>
{
const
result
=
form
.
score_detail
.
reduce
((
result
,
item
)
=>
{
return
result
+
item
.
commit_score
},
0
)
return
parseFloat
(
result
.
toFixed
(
2
))
})
function
handleSubmit
()
{
const
params
=
{
...
form
,
score_detail
:
JSON
.
stringify
(
form
.
score_detail
)
}
updateExperimentReport
(
params
).
then
(
res
=>
{
console
.
log
(
res
)
})
}
// 关闭
function
handleClose
()
{
window
.
close
()
}
</
script
>
<
template
>
<AppCard
title=
"批改实验报告"
>
<h1
class=
"report-title"
>
实验报告
</h1>
<el-form
label-suffix=
":"
hide-required-asterisk
v-if=
"experiment && report"
>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"课程名称"
>
{{
experiment
.
course
.
name
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"实验名称"
>
{{
experiment
.
name
}}
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"实验地点"
>
{{
report
.
experiment_address
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"实验日期"
>
{{
report
.
experiment_date
}}
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"实验类型"
>
{{
experiment
.
type_level
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"指导教师"
>
{{
teacherText
}}
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"专业"
>
{{
experiment
.
student
.
specialty
.
name
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"班级"
>
{{
classText
}}
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"姓名"
>
{{
experiment
.
student
.
name
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"学号"
>
{{
experiment
.
student
.
sno_number
}}
</el-form-item>
</el-col>
</el-row>
<el-divider
/>
<p
class=
"report-score"
>
总分:
{{
score
||
'--'
}}
</p>
<el-form-item
v-for=
"(item, index) in form.score_detail"
:key=
"item.id"
class=
"report-form-item"
>
<div
class=
"form-hd"
>
<h3>
{{
index
+
1
}}
、
{{
item
.
name
}}
</h3>
<div>
<span
class=
"score"
>
{{
item
.
score
}}
分
</span>
<span
class=
"rule-mode"
>
{{
reportScoreRule
[
item
.
rule_mode
]
}}
</span>
</div>
<div>
<p
class=
"score"
>
得分:
{{
item
.
commit_score
}}
分
</p>
<el-input-number
v-model=
"item.commit_score"
:min=
"item.min_score"
:max=
"item.score"
:controls=
"false"
:step=
"0.01"
step-strictly
placeholder=
"更新得分"
style=
"width: 100px"
></el-input-number>
</div>
</div>
<!-- 内容 -->
<template
v-if=
"item.type === 1"
>
{{
item
.
notice_message
}}
<div
class=
"report-form-item__content"
v-html=
"item.content"
></div>
</
template
>
<!-- 附件 -->
<
template
v-if=
"item.type === 2"
>
<el-table
:data=
"item.files"
stripe
:header-cell-style=
"
{ background: '#ededed' }" style="margin-top: 20px">
<el-table-column
label=
"序号"
type=
"index"
width=
"80"
align=
"center"
></el-table-column>
<el-table-column
label=
"附件类型"
prop=
"type"
align=
"center"
>
<template
#
default=
"
{ row }">
{{
row
.
type
===
'1'
?
'本地上传'
:
'实验截图'
}}
</
template
>
</el-table-column>
<el-table-column
label=
"附件名称"
prop=
"name"
align=
"center"
></el-table-column>
<el-table-column
label=
"更新时间"
prop=
"updated_time"
align=
"center"
></el-table-column>
<el-table-column
label=
"操作"
width=
"100"
align=
"center"
>
<
template
#
default=
"{ row }"
>
<el-button
text
type=
"primary"
><a
:href=
"row.url"
target=
"_blank"
>
查看
</a></el-button>
</
template
>
</el-table-column>
</el-table>
</template>
<!-- 思考题 -->
<
template
v-if=
"item.type === 3"
>
{{
item
.
question_stem
}}
<div
class=
"report-form-item__content"
v-html=
"item.content"
></div>
</
template
>
<p>
评语:
</p>
<el-input
type=
"textarea"
maxlength=
"200"
v-model=
"item.comment"
placeholder=
"请填写评语"
:autosize=
"{ minRows: 4 }"
></el-input>
</el-form-item>
<p>
实验整体评语:
</p>
<el-input
type=
"textarea"
maxlength=
"500"
placeholder=
"请填写评语"
:autosize=
"{ minRows: 6 }"
></el-input>
</el-form>
<el-row
justify=
"center"
>
<el-button
type=
"primary"
round
auto-insert-space
@
click=
"handleSubmit"
>
保存
</el-button>
<el-button
round
auto-insert-space
@
click=
"handleClose"
>
关闭
</el-button>
</el-row>
</AppCard>
</template>
<
style
lang=
"scss"
scoped
>
.report-title
{
padding
:
20px
;
font-size
:
20px
;
text-align
:
center
;
}
.report-score
{
text-align
:
right
;
font-size
:
24px
;
font-weight
:
bold
;
color
:
var
(
--
main-color
);
}
.report-form-item
{
.form-hd
{
display
:
flex
;
width
:
100%
;
font-size
:
14px
;
font-weight
:
bold
;
justify-content
:
space-between
;
.rule-mode
{
width
:
100px
;
text-align
:
right
;
}
}
}
.report-form-item__content
{
clear
:
both
;
width
:
100%
;
padding
:
10px
;
background-color
:
#efefef
;
border-radius
:
6px
;
box-sizing
:
border-box
;
}
</
style
>
src/modules/student/lab/api.ts
浏览文件 @
72a9cb18
...
@@ -110,3 +110,8 @@ export function getExperimentReportCache(params: { experiment_id: string }) {
...
@@ -110,3 +110,8 @@ export function getExperimentReportCache(params: { experiment_id: string }) {
export
function
getExperimentReport
(
params
:
{
experiment_id
:
string
})
{
export
function
getExperimentReport
(
params
:
{
experiment_id
:
string
})
{
return
httpRequest
.
get
(
'/api/lab/v1/student/experiment/online-report-detail'
,
{
params
})
return
httpRequest
.
get
(
'/api/lab/v1/student/experiment/online-report-detail'
,
{
params
})
}
}
// 获取实验成绩
export
function
getExperimentScore
(
params
:
{
experiment_id
:
string
})
{
return
httpRequest
.
get
(
'/api/lab/v1/student/experiment/achievement'
,
{
params
})
}
src/modules/student/lab/components/ReportFilePreview.vue
0 → 100644
浏览文件 @
72a9cb18
<
script
setup
lang=
"ts"
>
import
type
{
ExperimentInfo
,
ExperimentRecord
}
from
'../types'
interface
Props
{
data
:
ExperimentInfo
}
const
props
=
defineProps
<
Props
>
()
const
classText
=
$computed
(()
=>
{
return
props
.
data
.
student
.
classes
.
map
(
item
=>
item
.
name
).
join
(
'、'
)
})
const
detail
=
$ref
(
inject
<
ExperimentRecord
>
(
'detail'
))
</
script
>
<
template
>
<el-dialog
title=
"查看实验报告"
:close-on-click-modal=
"false"
width=
"600px"
>
<el-form
label-suffix=
":"
label-width=
"110px"
label-position=
"right"
>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"实验名称"
>
{{
data
.
name
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"实验课程名称"
>
{{
data
.
course
.
name
}}
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"学生姓名"
>
{{
data
.
student
.
name
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"学生学号"
>
{{
data
.
student
.
sno_number
}}
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"所属专业"
>
{{
data
.
student
.
specialty
.
name
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"所属班级"
>
{{
classText
}}
</el-form-item>
</el-col>
</el-row>
<el-form-item
label=
"实验报告文件"
v-if=
"detail?.file"
>
{{
detail
.
file
.
name
}}
<el-button
type=
"primary"
text
>
<a
:href=
"detail.file.url"
target=
"_blank"
>
查阅
</a></el-button>
</el-form-item>
</el-form>
<el-row
justify=
"center"
>
<el-button
round
auto-insert-space
@
click=
"$emit('update:modelValue', false)"
>
关闭
</el-button>
</el-row>
</el-dialog>
</
template
>
src/modules/student/lab/components/ReportPreivew.vue
0 → 100644
浏览文件 @
72a9cb18
<
script
setup
>
import
{
getExperimentReport
}
from
'../api'
const
props
=
defineProps
({
id
:
String
})
let
experiment
=
$ref
()
let
report
=
$ref
()
const
teacherText
=
$computed
(()
=>
{
if
(
!
experiment
)
return
''
return
experiment
.
teachers
.
map
(
item
=>
item
.
name
).
join
(
'、'
)
})
const
classText
=
$computed
(()
=>
{
if
(
!
experiment
)
return
''
return
experiment
.
student
.
classes
.
map
(
item
=>
item
.
name
).
join
(
'、'
)
})
function
fetchInfo
()
{
getExperimentReport
({
experiment_id
:
props
.
id
}).
then
(
res
=>
{
experiment
=
res
.
data
.
experiment
report
=
res
.
data
.
report
let
detail
=
[]
try
{
detail
=
JSON
.
parse
(
report
.
detail
)
}
catch
(
error
)
{
console
.
log
(
error
)
}
report
=
Object
.
assign
(
report
,
{
detail
})
})
}
onMounted
(()
=>
{
fetchInfo
()
})
// 关闭
function
handleClose
()
{
window
.
close
()
}
</
script
>
<
template
>
<h1
class=
"report-title"
>
实验报告
</h1>
<el-form
label-suffix=
":"
hide-required-asterisk
v-if=
"experiment"
>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"课程名称"
>
{{
experiment
.
course
.
name
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"实验名称"
>
{{
experiment
.
name
}}
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"实验地点"
>
{{
report
.
experiment_address
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"实验日期"
>
{{
report
.
experiment_date
}}
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"实验类型"
>
{{
experiment
.
type_level
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"指导教师"
>
{{
teacherText
}}
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"专业"
>
{{
experiment
.
student
.
specialty
.
name
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"班级"
>
{{
classText
}}
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"姓名"
>
{{
experiment
.
student
.
name
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"学号"
>
{{
experiment
.
student
.
sno_number
}}
</el-form-item>
</el-col>
</el-row>
<el-divider
/>
<el-form-item
:label=
"item.name"
v-for=
"item in report.detail"
:key=
"item.id"
class=
"report-form-item"
>
<!-- 内容 -->
<template
v-if=
"item.type === 1"
>
{{
item
.
notice_message
}}
<div
class=
"report-form-item__content"
v-html=
"item.content"
></div>
</
template
>
<!-- 附件 -->
<
template
v-if=
"item.type === 2"
>
<el-table
:data=
"item.files"
stripe
:header-cell-style=
"
{ background: '#ededed' }" style="margin-top: 20px">
<el-table-column
label=
"序号"
type=
"index"
width=
"80"
align=
"center"
></el-table-column>
<el-table-column
label=
"附件类型"
prop=
"type"
align=
"center"
>
<template
#
default=
"
{ row }">
{{
row
.
type
===
'1'
?
'本地上传'
:
'实验截图'
}}
</
template
>
</el-table-column>
<el-table-column
label=
"附件名称"
prop=
"name"
align=
"center"
></el-table-column>
<el-table-column
label=
"更新时间"
prop=
"updated_time"
align=
"center"
></el-table-column>
<el-table-column
label=
"操作"
width=
"100"
align=
"center"
>
<
template
#
default=
"{ row }"
>
<el-button
text
type=
"primary"
><a
:href=
"row.url"
target=
"_blank"
>
查看
</a></el-button>
</
template
>
</el-table-column>
</el-table>
</template>
<!-- 思考题 -->
<
template
v-if=
"item.type === 3"
>
{{
item
.
question_stem
}}
<div
class=
"report-form-item__content"
v-html=
"item.content"
></div>
</
template
>
</el-form-item>
</el-form>
<el-row
justify=
"center"
>
<el-button
type=
"primary"
plain
auto-insert-space
@
click=
"handleClose"
>
关闭
</el-button>
</el-row>
</template>
<
style
lang=
"scss"
>
.report-title
{
padding
:
20px
;
font-size
:
20px
;
text-align
:
center
;
}
.report-form-item
{
flex-direction
:
column
;
.el-form-item__label
{
font-weight
:
bold
;
text-align
:
left
;
justify-content
:
flex-start
;
}
}
.report-form-item__content
{
clear
:
both
;
width
:
100%
;
padding
:
10px
;
background-color
:
#efefef
;
border-radius
:
6px
;
box-sizing
:
border-box
;
}
</
style
>
src/modules/student/lab/components/Result.vue
浏览文件 @
72a9cb18
...
@@ -66,7 +66,10 @@ function handleRemove(index: number) {
...
@@ -66,7 +66,10 @@ function handleRemove(index: number) {
</li>
</li>
</ul>
</ul>
<ImageViewer
v-model=
"imageViewerVisible"
:index=
"imageViewerIndex"
:items=
"detail.pictures"
></ImageViewer>
<ImageViewer
v-model=
"imageViewerVisible"
:index=
"imageViewerIndex"
:items=
"detail.pictures"
></ImageViewer>
<ResultScoreDialog
v-model=
"dialogVisible"
></ResultScoreDialog>
<ResultScoreDialog
v-model=
"dialogVisible"
:experiment_id=
"experiment_id"
v-if=
"dialogVisible && experiment_id"
></ResultScoreDialog>
</template>
</template>
<el-empty
description=
"暂无数据"
v-else
/>
<el-empty
description=
"暂无数据"
v-else
/>
</template>
</template>
...
@@ -94,6 +97,7 @@ function handleRemove(index: number) {
...
@@ -94,6 +97,7 @@ function handleRemove(index: number) {
background
:
url(@/assets/images/score_bg.png)
no-repeat
;
background
:
url(@/assets/images/score_bg.png)
no-repeat
;
background-size
:
contain
;
background-size
:
contain
;
box-sizing
:
border-box
;
box-sizing
:
border-box
;
cursor
:
pointer
;
}
}
.t2
{
.t2
{
font-size
:
14px
;
font-size
:
14px
;
...
...
src/modules/student/lab/components/ResultScoreDialog.vue
浏览文件 @
72a9cb18
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
type
{
ExperimentRecord
}
from
'../types'
import
{
getExperimentScore
}
from
'../api'
import
{
Document
}
from
'@element-plus/icons-vue'
const
detail
=
$ref
(
inject
<
ExperimentRecord
>
(
'detail'
))
interface
Props
{
experiment_id
:
string
}
const
props
=
defineProps
<
Props
>
()
let
detail
=
$ref
<
any
>
()
const
score
=
$computed
<
number
>
(()
=>
{
function
fetchInfo
()
{
const
result
=
getExperimentScore
({
experiment_id
:
props
.
experiment_id
}).
then
(
res
=>
{
((
detail
?.
score_details
.
operate
||
0
)
+
(
detail
?.
score_details
.
result
||
0
)
+
(
detail
?.
score_details
.
file
||
0
))
/
3
detail
=
res
.
data
return
parseFloat
(
result
.
toFixed
(
2
))
})
}
onMounted
(()
=>
{
fetchInfo
()
})
})
</
script
>
</
script
>
...
@@ -15,81 +22,49 @@ const score = $computed<number>(() => {
...
@@ -15,81 +22,49 @@ const score = $computed<number>(() => {
<el-dialog
title=
"实验成绩详情"
width=
"600px"
:close-on-click-modal=
"false"
>
<el-dialog
title=
"实验成绩详情"
width=
"600px"
:close-on-click-modal=
"false"
>
<el-form
label-width=
"120px"
label-suffix=
":"
v-if=
"detail"
>
<el-form
label-width=
"120px"
label-suffix=
":"
v-if=
"detail"
>
<el-form-item
label=
"实验名称"
>
{{
detail
.
experiment
.
name
}}
</el-form-item>
<el-form-item
label=
"实验名称"
>
{{
detail
.
experiment
.
name
}}
</el-form-item>
<el-form-item
label=
"实验课程名称"
>
{{
detail
.
course
.
name
}}
</el-form-item>
<el-form-item
label=
"实验课程名称"
>
{{
detail
.
experiment
.
course
.
name
}}
</el-form-item>
<el-row>
<el-row>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"学生姓名"
>
{{
detail
.
student
.
name
}}
</el-form-item>
<el-form-item
label=
"学生姓名"
>
{{
detail
.
experiment
.
student
.
name
}}
</el-form-item>
</el-col>
</el-col>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"学生学号"
>
{{
detail
.
student
.
sno_number
}}
</el-form-item>
<el-form-item
label=
"学生学号"
>
{{
detail
.
experiment
.
student
.
sno_number
}}
</el-form-item>
</el-col>
</el-col>
</el-row>
</el-row>
<el-row>
<el-row>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"所属专业"
>
{{
detail
.
student
.
specialty
.
name
}}
</el-form-item>
<el-form-item
label=
"所属专业"
>
{{
detail
.
experiment
.
student
.
specialty
.
name
}}
</el-form-item>
</el-col>
</el-col>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"所属班级"
>
{{
detail
.
student
.
specialty
.
name
}}
</el-form-item>
<el-form-item
label=
"所属班级"
>
{{
detail
.
experiment
.
student
.
specialty
.
name
}}
</el-form-item>
</el-col>
</el-col>
</el-row>
</el-row>
<el-form-item
label=
"实验报告文件"
>
<el-row>
<div
v-if=
"detail.file"
>
<el-col
:span=
"12"
>
<a
:href=
"detail.file.url"
target=
"_blank"
class=
"file-item"
>
<el-form-item
label=
"评分教师"
>
<el-icon><Document
/></el-icon>
{{
detail
.
file
.
name
}}
{{
</a>
detail
.
achievement
.
checker_sso_user
.
real_name
||
</div>
detail
.
achievement
.
checker_sso_user
.
nickname
||
</el-form-item>
detail
.
achievement
.
checker_sso_user
.
username
<el-form-item
label=
"实验成绩"
class=
"form-item-score"
>
}}
<el-form
ref=
"formRef"
hide-required-asterisk
inline
label-position=
"top"
style=
"padding: 5px 0 20px"
>
<el-form-item
label=
"实验操作"
>
<el-input-number
:controls=
"false"
disabled
v-model=
"detail.score_details.operate"
/>
</el-form-item>
<el-form-item
label=
"实验结果"
>
<el-input-number
:controls=
"false"
disabled
v-model=
"detail.score_details.result"
/>
</el-form-item>
<el-form-item
label=
"实验报告"
>
<el-input-number
:controls=
"false"
disabled
v-model=
"detail.score_details.file"
/>
</el-form-item>
<el-form-item
label=
"综合实验成绩"
style=
"width: 364px"
>
<el-input-number
:controls=
"false"
disabled
v-model=
"score"
style=
"width: 100%"
/>
</el-form-item>
</el-form-item>
</el-form>
</el-col>
</el-form-item>
<el-col
:span=
"12"
>
<el-form-item
label=
"评分时间"
>
{{
detail
.
achievement
.
check_time
}}
</el-form-item>
</el-col>
</el-row>
<div>
<p>
实验得分
{{
detail
.
achievement
.
score
}}
</p>
<!--
<el-table
:data=
"item.files"
stripe
:header-cell-style=
"
{ background: '#ededed' }">
<el-table-column
label=
"实验成绩组成项"
align=
"center"
></el-table-column>
<el-table-column
label=
"权重"
prop=
"type"
align=
"center"
>
</el-table-column>
<el-table-column
label=
"得分"
width=
"100"
align=
"center"
>
<template
#
default=
"
{ row }">
<el-button
text
type=
"primary"
><a
:href=
"row.url"
target=
"_blank"
>
查看明细
</a></el-button>
</
template
>
</el-table-column>
</el-table>
-->
</div>
</el-form>
</el-form>
</el-dialog>
</el-dialog>
</template>
</template>
<
style
lang=
"scss"
scoped
>
.file-item
{
display
:
flex
;
align-items
:
center
;
color
:
var
(
--
main-color
);
.el-icon
{
margin-right
:
5px
;
}
}
.picture-list
{
width
:
100%
;
li
{
display
:
flex
;
justify-content
:
space-between
;
}
a
{
color
:
var
(
--
main-color
);
}
.t1
{
flex
:
1
;
white-space
:
nowrap
;
text-overflow
:
ellipsis
;
overflow
:
hidden
;
}
}
.form-item-score
{
:deep
(
.el-form-item__label
)
{
text-align
:
center
;
}
.el-input-number
{
width
:
100px
;
}
}
</
style
>
src/modules/student/lab/index.ts
浏览文件 @
72a9cb18
...
@@ -8,7 +8,8 @@ export const routes: Array<RouteRecordRaw> = [
...
@@ -8,7 +8,8 @@ export const routes: Array<RouteRecordRaw> = [
props
:
{
sidebar
:
false
},
props
:
{
sidebar
:
false
},
children
:
[
children
:
[
{
path
:
''
,
component
:
()
=>
import
(
'./views/Index.vue'
)
},
{
path
:
''
,
component
:
()
=>
import
(
'./views/Index.vue'
)
},
{
path
:
'report/:id'
,
component
:
()
=>
import
(
'./views/Report.vue'
),
props
:
true
}
{
path
:
'report/:id'
,
component
:
()
=>
import
(
'./views/Report.vue'
),
props
:
true
},
{
path
:
'report/view/:id'
,
component
:
()
=>
import
(
'./views/ReportView.vue'
),
props
:
true
}
]
]
}
}
]
]
src/modules/student/lab/views/Index.vue
浏览文件 @
72a9cb18
...
@@ -14,6 +14,7 @@ const Video = defineAsyncComponent(() => import('../components/Video.vue'))
...
@@ -14,6 +14,7 @@ const Video = defineAsyncComponent(() => import('../components/Video.vue'))
const
Discuss
=
defineAsyncComponent
(()
=>
import
(
'../components/Discuss.vue'
))
const
Discuss
=
defineAsyncComponent
(()
=>
import
(
'../components/Discuss.vue'
))
const
Result
=
defineAsyncComponent
(()
=>
import
(
'../components/Result.vue'
))
const
Result
=
defineAsyncComponent
(()
=>
import
(
'../components/Result.vue'
))
const
ReportDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/ReportDialog.vue'
))
const
ReportDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/ReportDialog.vue'
))
const
ReportFilePreview
=
defineAsyncComponent
(()
=>
import
(
'../components/ReportFilePreview.vue'
))
const
PrepareDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/PrepareDialog.vue'
))
const
PrepareDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/PrepareDialog.vue'
))
const
ResultDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/ResultDialog.vue'
))
const
ResultDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/ResultDialog.vue'
))
...
@@ -164,6 +165,21 @@ function handleResize() {
...
@@ -164,6 +165,21 @@ function handleResize() {
const
prepareDialogVisible
=
$ref
(
false
)
const
prepareDialogVisible
=
$ref
(
false
)
// 实验结果
// 实验结果
const
resultDialogVisible
=
$ref
(
false
)
const
resultDialogVisible
=
$ref
(
false
)
// 查看实验报告
let
reportFilePreviewVisible
=
$ref
(
false
)
function
handleReportView
()
{
if
(
experimentInfo
?.
report_upload_way
===
2
)
{
window
.
open
(
`/student/lab/report/view/
${
experimentInfo
?.
id
}
`)
} else {
reportFilePreviewVisible = true
}
}
// 导出实验报告
function handleReportExport() {
console.log(1)
}
</
script
>
</
script
>
<
template
>
<
template
>
...
@@ -216,30 +232,23 @@ const resultDialogVisible = $ref(false)
...
@@ -216,30 +232,23 @@ const resultDialogVisible = $ref(false)
>
>
<el-button
type=
"primary"
:disabled=
"disabled"
@
click=
"prepareDialogVisible = true"
>
实验准备
</el-button>
<el-button
type=
"primary"
:disabled=
"disabled"
@
click=
"prepareDialogVisible = true"
>
实验准备
</el-button>
<el-button
type=
"primary"
:disabled=
"disabled"
@
click=
"resultDialogVisible = true"
>
实验结果
</el-button>
<el-button
type=
"primary"
:disabled=
"disabled"
@
click=
"resultDialogVisible = true"
>
实验结果
</el-button>
<el-button
type=
"primary"
:disabled=
"disabled"
v-if=
"experimentInfo?.report_upload_way === 2"
>
<el-button
type=
"primary"
:disabled=
"disabled"
v-if=
"experimentInfo?.report_upload_way === 2 && !experimentInfo?.is_commit_report"
>
<router-link
:to=
"`/student/lab/report/$
{form.experiment_id}`" target="_blank">在线实验报告
</router-link>
<router-link
:to=
"`/student/lab/report/$
{form.experiment_id}`" target="_blank">在线实验报告
</router-link>
</el-button>
</el-button>
<el-button
<el-button
type=
"primary"
type=
"primary"
:disabled=
"disabled"
:disabled=
"disabled"
@
click=
"reportDialogVisible = true"
@
click=
"reportDialogVisible = true"
v-if=
"experimentInfo?.report_upload_way === 1"
v-if=
"experimentInfo?.report_upload_way === 1
&& !submitted
"
>
上传实验报告
</el-button
>
上传实验报告
</el-button
>
>
<el-button
<el-button
type=
"primary"
@
click=
"handleReportView"
v-if=
"experimentInfo?.is_commit_report"
type=
"primary"
:disabled=
"disabled"
@
click=
"reportDialogVisible = true"
v-if=
"experimentInfo?.is_commit_report"
>
查看实验报告
</el-button
>
查看实验报告
</el-button
>
>
<el-button
<el-button
type=
"primary"
@
click=
"handleReportExport"
v-if=
"detail?.status === 2"
>
导出实验报告
</el-button>
type=
"primary"
:disabled=
"disabled"
@
click=
"reportDialogVisible = true"
v-if=
"experimentInfo?.is_commit"
>
导出实验报告
</el-button
>
</div>
</div>
</el-row>
</el-row>
</AppCard>
</AppCard>
...
@@ -256,7 +265,10 @@ const resultDialogVisible = $ref(false)
...
@@ -256,7 +265,10 @@ const resultDialogVisible = $ref(false)
:data=
"experimentInfo"
:data=
"experimentInfo"
@
update=
"fetchExperimentRecord"
@
update=
"fetchExperimentRecord"
v-if=
"reportDialogVisible && experimentInfo"
></ReportDialog>
v-if=
"reportDialogVisible && experimentInfo"
></ReportDialog>
<ReportFilePreview
v-model=
"reportFilePreviewVisible"
:data=
"experimentInfo"
v-if=
"reportFilePreviewVisible && experimentInfo"
></ReportFilePreview>
<!-- 实验准备 -->
<!-- 实验准备 -->
<PrepareDialog
<PrepareDialog
v-model=
"prepareDialogVisible"
v-model=
"prepareDialogVisible"
...
...
src/modules/student/lab/views/Report.vue
浏览文件 @
72a9cb18
...
@@ -253,7 +253,7 @@ function handleUpdateBindCapture(files) {
...
@@ -253,7 +253,7 @@ function handleUpdateBindCapture(files) {
<!-- 关联截图 -->
<!-- 关联截图 -->
<BindCaptureDialog
<BindCaptureDialog
v-model=
"bindCaptureVisible"
v-model=
"bindCaptureVisible"
:experiment=
"
detail
"
:experiment=
"
experiment
"
:data=
"currentRaw"
:data=
"currentRaw"
@
update=
"handleUpdateBindCapture"
@
update=
"handleUpdateBindCapture"
v-if=
"bindCaptureVisible && currentRaw"
></BindCaptureDialog>
v-if=
"bindCaptureVisible && currentRaw"
></BindCaptureDialog>
...
...
src/modules/student/lab/views/ReportView.vue
浏览文件 @
72a9cb18
<
script
setup
>
<
script
setup
>
import
AppEditor
from
'@/components/base/AppEditor.vue'
import
ReportPreview
from
'../components/ReportPreivew.vue'
import
{
ElMessage
,
ElMessageBox
}
from
'element-plus'
import
{
useFileDialog
}
from
'@vueuse/core'
import
{
upload
}
from
'@/utils/upload'
import
{
useNow
,
useDateFormat
}
from
'@vueuse/core'
import
{
getExperimentReport
,
getExperimentReportTemplate
,
getExperimentReportCache
,
cacheExperimentReport
,
updateExperimentReport
}
from
'../api'
import
BindCaptureDialog
from
'../components/BindCaptureDialog.vue'
const
props
=
defineProps
({
id
:
String
})
let
experiment
=
$ref
()
let
report
=
$ref
()
const
disabled
=
$computed
(()
=>
{
return
experiment
?.
is_commit_report
})
const
teacherText
=
$computed
(()
=>
{
if
(
!
experiment
)
return
''
return
experiment
.
teachers
.
map
(
item
=>
item
.
name
).
join
(
'、'
)
})
const
classText
=
$computed
(()
=>
{
if
(
!
experiment
)
return
''
return
experiment
.
student
.
classes
.
map
(
item
=>
item
.
name
).
join
(
'、'
)
})
const
formRef
=
$ref
()
const
form
=
reactive
({
experiment_id
:
props
.
id
,
experiment_address
:
''
,
experiment_date
:
useDateFormat
(
useNow
(),
'YYYY-MM-DD'
).
value
,
detail
:
[]
})
function
fetchInfo
()
{
getExperimentReport
({
experiment_id
:
props
.
id
}).
then
(
res
=>
{
experiment
=
res
.
data
.
experiment
report
=
res
.
data
.
report
if
(
experiment
.
is_commit_report
)
{
let
detail
=
[]
try
{
detail
=
JSON
.
parse
(
report
.
detail
)
}
catch
(
error
)
{
console
.
log
(
error
)
}
Object
.
assign
(
form
,
report
,
{
detail
})
}
else
{
fetchCached
()
}
})
}
function
fetchTemplate
()
{
getExperimentReportTemplate
({
experiment_id
:
props
.
id
}).
then
(
res
=>
{
form
.
detail
=
res
.
data
.
template
})
}
function
fetchCached
()
{
getExperimentReportCache
({
experiment_id
:
props
.
id
}).
then
(
res
=>
{
const
report
=
res
.
data
.
report
if
(
!
report
.
experiment_id
)
{
fetchTemplate
()
return
}
let
detail
=
[]
try
{
detail
=
JSON
.
parse
(
report
.
detail
)
}
catch
(
error
)
{
console
.
log
(
error
)
}
Object
.
assign
(
form
,
report
,
{
detail
})
})
}
onMounted
(()
=>
{
fetchInfo
()
})
// 关闭
function
handleClose
()
{
ElMessageBox
.
confirm
(
'此操作将不做任何修改,确认关闭该页面?'
,
'提示'
).
then
(()
=>
{
window
.
close
()
})
}
// 暂存
function
handleCache
()
{
const
params
=
{
...
form
,
detail
:
JSON
.
stringify
(
form
.
detail
)
}
cacheExperimentReport
(
params
).
then
(()
=>
{
ElMessage
.
success
(
'暂存成功'
)
})
}
// 提交
function
handleSubmit
()
{
formRef
.
validate
().
then
(()
=>
{
const
params
=
{
...
form
,
detail
:
JSON
.
stringify
(
form
.
detail
)
}
ElMessageBox
.
confirm
(
'提交报告之后,您将不能进行修改报告,确认提交实验报告?'
,
'提示'
).
then
(()
=>
{
updateExperimentReport
(
params
).
then
(()
=>
{
ElMessage
.
success
(
'提交成功'
)
fetchInfo
()
})
})
})
}
// 附件
let
currentRaw
=
$ref
(
null
)
// 本地上传
const
{
files
,
open
,
reset
}
=
useFileDialog
()
function
handleUpload
(
data
)
{
currentRaw
=
data
open
({
multiple
:
false
})
}
watchEffect
(()
=>
{
if
(
!
files
.
value
?.
length
)
return
const
[
file
]
=
files
.
value
upload
(
file
).
then
(
url
=>
{
const
formatted
=
useDateFormat
(
useNow
(),
'YYYY-MM-DD HH:mm:ss'
)
currentRaw
.
files
.
push
({
id
:
Date
.
now
().
toString
(),
url
,
name
:
file
.
name
,
type
:
'1'
,
file_type
:
file
.
type
,
updated_time
:
formatted
.
value
,
upload_time
:
formatted
.
value
})
reset
()
})
})
// 关联截图
let
bindCaptureVisible
=
$ref
(
false
)
function
handleBindCapture
(
data
)
{
currentRaw
=
data
bindCaptureVisible
=
true
}
// 删除文件
function
handleRemoveFile
(
data
,
index
)
{
data
.
files
.
splice
(
index
,
1
)
}
function
handleUpdateBindCapture
(
files
)
{
currentRaw
.
files
=
files
}
</
script
>
</
script
>
<
template
>
<
template
>
<AppCard
title=
"查看实验报告"
>
<AppCard
title=
"查看实验报告"
>
<h1
class=
"report-title"
>
查看实验报告
</h1>
<ReportPreview
v-bind=
"$attrs"
></ReportPreview>
<el-form
ref=
"formRef"
:model=
"form"
label-suffix=
":"
hide-required-asterisk
v-if=
"experiment"
>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"课程名称"
>
{{
experiment
.
course
.
name
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"实验名称"
>
{{
experiment
.
name
}}
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"实验地点"
>
{{
report
.
experiment_address
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"实验日期"
>
{{
report
.
experiment_date
}}
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"实验类型"
>
{{
experiment
.
type_level
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"指导教师"
>
{{
teacherText
}}
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"专业"
>
{{
experiment
.
student
.
specialty
.
name
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"班级"
>
{{
classText
}}
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"姓名"
>
{{
experiment
.
student
.
name
}}
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"学号"
>
{{
experiment
.
student
.
sno_number
}}
</el-form-item>
</el-col>
</el-row>
<el-divider
/>
<el-form-item
:label=
"item.name"
v-for=
"item in form.detail"
:key=
"item.id"
class=
"report-form-item"
>
<!-- 内容 -->
<template
v-if=
"item.type === 1"
>
{{
item
.
notice_message
}}
<AppEditor
v-model=
"item.content"
:disabled=
"disabled"
:height=
"200"
></AppEditor>
</
template
>
<!-- 附件 -->
<
template
v-if=
"item.type === 2"
>
<el-button
type=
"primary"
@
click=
"handleUpload(item)"
v-if=
"item.categories.includes(2)"
>
上传附件
</el-button>
<el-button
type=
"primary"
@
click=
"handleBindCapture(item)"
v-if=
"item.categories.includes(1)"
>
关联截图
</el-button
>
<el-table
:data=
"item.files"
stripe
:header-cell-style=
"
{ background: '#ededed' }" style="margin-top: 20px">
<el-table-column
label=
"序号"
type=
"index"
width=
"80"
align=
"center"
></el-table-column>
<el-table-column
label=
"附件类型"
prop=
"type"
align=
"center"
>
<template
#
default=
"
{ row }">
{{
row
.
type
===
'1'
?
'本地上传'
:
'实验截图'
}}
</
template
>
</el-table-column>
<el-table-column
label=
"附件名称"
prop=
"name"
align=
"center"
></el-table-column>
<el-table-column
label=
"更新时间"
prop=
"updated_time"
align=
"center"
></el-table-column>
<el-table-column
label=
"操作"
width=
"200"
align=
"center"
>
<
template
#
default=
"{ row, $index }"
>
<el-button
text
type=
"primary"
><a
:href=
"row.url"
target=
"_blank"
>
查看
</a></el-button>
<el-button
text
type=
"danger"
@
click=
"handleRemoveFile(item, $index)"
>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
</template>
<!-- 思考题 -->
<
template
v-if=
"item.type === 3"
>
{{
item
.
question_stem
}}
<AppEditor
v-model=
"item.content"
:disabled=
"disabled"
:height=
"200"
></AppEditor>
</
template
>
</el-form-item>
<el-row
justify=
"center"
>
<el-button
type=
"primary"
auto-insert-space
@
click=
"handleClose"
>
关闭
</el-button>
<el-button
type=
"primary"
auto-insert-space
@
click=
"handleCache"
>
暂存
</el-button>
<el-button
type=
"primary"
auto-insert-space
@
click=
"handleSubmit"
>
提交报告
</el-button>
</el-row>
</el-form>
<!-- 关联截图 -->
<BindCaptureDialog
v-model=
"bindCaptureVisible"
:experiment=
"detail"
:data=
"currentRaw"
@
update=
"handleUpdateBindCapture"
v-if=
"bindCaptureVisible && currentRaw"
></BindCaptureDialog>
</AppCard>
</AppCard>
</
template
>
</
template
>
<
style
lang=
"scss"
>
.report-title
{
padding
:
20px
;
font-size
:
20px
;
text-align
:
center
;
}
.report-form-item
{
flex-direction
:
column
;
.el-form-item__label
{
font-weight
:
bold
;
text-align
:
left
;
justify-content
:
flex-start
;
}
}
</
style
>
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论