Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
saas-lab
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
saas-lab
Commits
868f99b4
提交
868f99b4
authored
1月 31, 2023
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 教师端新增案例原文
上级
ae1a5049
隐藏空白字符变更
内嵌
并排
正在显示
10 个修改的文件
包含
633 行增加
和
0 行删除
+633
-0
api.ts
src/modules/admin/lab/case/api.ts
+29
-0
FormDialog.vue
src/modules/admin/lab/case/components/FormDialog.vue
+167
-0
ListItem.vue
src/modules/admin/lab/case/components/ListItem.vue
+180
-0
useGetCourseList.ts
src/modules/admin/lab/case/composables/useGetCourseList.ts
+16
-0
useGetExperimentList.ts
...odules/admin/lab/case/composables/useGetExperimentList.ts
+16
-0
index.ts
src/modules/admin/lab/case/index.ts
+17
-0
types.ts
src/modules/admin/lab/case/types.ts
+56
-0
Index.vue
src/modules/admin/lab/case/views/Index.vue
+88
-0
View.vue
src/modules/admin/lab/case/views/View.vue
+59
-0
menu.ts
src/stores/menu.ts
+5
-0
没有找到文件。
src/modules/admin/lab/case/api.ts
0 → 100644
浏览文件 @
868f99b4
import
httpRequest
from
'@/utils/axios'
import
type
{
CaseCreateItem
}
from
'./types'
// 获取课程列表
export
function
getCourseList
()
{
return
httpRequest
.
get
(
'/api/lab/v1/teacher/course/list'
)
}
// 获取实验列表
export
function
getExperimentList
(
params
:
{
course_id
?:
string
})
{
return
httpRequest
.
get
(
'/api/lab/v1/teacher/experiment-cases/experiments'
,
{
params
})
}
// 获取案例原文列表
export
function
getCaseList
(
params
?:
{
name
?:
string
;
experiment_id
?:
string
;
page
?:
number
;
page_size
?:
number
})
{
return
httpRequest
.
get
(
'/api/lab/v1/teacher/experiment-cases/list'
,
{
params
})
}
// 获取案例原文详情
export
function
getCase
(
params
:
{
id
:
string
})
{
return
httpRequest
.
get
(
'/api/lab/v1/teacher/experiment-cases/detail'
,
{
params
})
}
// 创建案例原文
export
function
createCase
(
data
:
CaseCreateItem
)
{
return
httpRequest
.
post
(
'/api/lab/v1/teacher/experiment-cases/create'
,
data
)
}
// 更新案例原文
export
function
updateCase
(
data
:
CaseCreateItem
)
{
return
httpRequest
.
post
(
'/api/lab/v1/teacher/experiment-cases/update'
,
data
)
}
src/modules/admin/lab/case/components/FormDialog.vue
0 → 100644
浏览文件 @
868f99b4
<
script
setup
lang=
"ts"
>
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
type
{
CaseItem
,
CaseFormData
,
CaseCreateItem
,
CaseUpdateItem
}
from
'../types'
import
{
ElMessageBox
,
ElMessage
}
from
'element-plus'
import
AppUpload
from
'@/components/base/AppUpload.vue'
import
{
createCase
,
updateCase
}
from
'../api'
import
{
useGetCourseList
}
from
'../composables/useGetCourseList'
import
{
useGetExperimentList
}
from
'../composables/useGetExperimentList'
import
{
useMapStore
}
from
'@/stores/map'
interface
Props
{
data
?:
CaseItem
|
null
}
const
props
=
defineProps
<
Props
>
()
const
emit
=
defineEmits
<
{
(
e
:
'update'
):
void
(
e
:
'update:modelValue'
,
visible
:
boolean
):
void
}
>
()
// 课程列表
const
{
courses
}
=
useGetCourseList
()
// 数据状态
const
status
=
useMapStore
().
getMapValuesByKey
(
'system_status'
)
// 实验列表
const
{
experiments
,
updateExperiments
}
=
useGetExperimentList
()
const
formRef
=
$ref
<
FormInstance
>
()
const
form
=
reactive
<
CaseFormData
>
({
name
:
''
,
course_id
:
''
,
experiment_id
:
''
,
status
:
'1'
,
url
:
''
,
type
:
''
,
size
:
''
,
files
:
[],
protocol
:
false
})
watchEffect
(()
=>
{
if
(
!
props
.
data
)
return
form
.
files
=
[{
name
:
props
.
data
.
name
,
url
:
props
.
data
.
url
,
type
:
props
.
data
.
type
}]
Object
.
assign
(
form
,
{
protocol
:
true
,
course_id
:
props
.
data
.
course
.
id
},
props
.
data
)
})
watchEffect
(()
=>
{
updateExperiments
(
form
.
course_id
)
})
const
checkProtocol
=
(
rule
:
any
,
value
:
any
,
callback
:
any
)
=>
{
if
(
!
value
)
{
return
callback
(
new
Error
(
'请阅读并同意'
))
}
else
{
callback
()
}
}
const
rules
=
ref
<
FormRules
>
({
files
:
[{
type
:
'array'
,
required
:
true
,
message
:
'请上传案例原文'
}],
name
:
[{
required
:
true
,
message
:
'请输入案例原文名称'
,
trigger
:
'blur'
}],
course_id
:
[{
required
:
true
,
message
:
'请选择关联实验课程'
,
trigger
:
'change'
}],
experiment_id
:
[{
required
:
true
,
message
:
'请选择关联实验'
,
trigger
:
'change'
}],
protocol
:
[{
validator
:
checkProtocol
,
message
:
'请阅读并同意'
,
trigger
:
'change'
}]
})
const
isUpdate
=
$computed
(()
=>
{
return
!!
props
.
data
?.
id
})
const
title
=
$computed
(()
=>
{
return
isUpdate
?
'编辑案例原文'
:
'新增案例原文'
})
// 实验列表
const
experimentList
=
$computed
(()
=>
{
if
(
!
props
.
data
)
return
experiments
.
value
return
isUpdate
&&
props
.
data
.
course
.
id
===
form
.
course_id
?
[{
id
:
props
.
data
.
experiment_id
,
name
:
props
.
data
.
experiment
.
name
},
...
experiments
.
value
]
:
experiments
.
value
})
function
handleBeforeUpload
()
{
if
(
form
.
files
.
length
)
{
return
ElMessageBox
.
confirm
(
'系统仅支持1个案例原文,此操作将覆盖原有案例原文文件,确认上传新文件吗?'
,
'提示'
)
}
return
true
}
function
handleUploadSuccess
(
file
:
any
)
{
form
.
name
=
file
.
name
.
split
(
'.'
).
shift
()
form
.
size
=
(
file
.
size
/
1024
/
1024
).
toString
()
form
.
url
=
file
.
raw
.
url
form
.
type
=
file
.
raw
.
type
||
'unknown'
}
// 提交
function
handleSubmit
()
{
formRef
?.
validate
().
then
(()
=>
{
isUpdate
?
handleUpdate
(
form
)
:
handleCreate
(
form
)
})
}
// 新增
function
handleCreate
(
params
:
CaseCreateItem
)
{
createCase
(
params
).
then
(()
=>
{
ElMessage
({
message
:
'创建成功'
,
type
:
'success'
})
emit
(
'update'
)
emit
(
'update:modelValue'
,
false
)
})
}
// 修改
function
handleUpdate
(
params
:
CaseUpdateItem
)
{
updateCase
(
params
).
then
(()
=>
{
ElMessage
({
message
:
'修改成功'
,
type
:
'success'
})
emit
(
'update'
)
emit
(
'update:modelValue'
,
false
)
})
}
</
script
>
<
template
>
<el-dialog
:title=
"title"
:close-on-click-modal=
"false"
width=
"600px"
@
update:modelValue=
"$emit('update:modelValue')"
>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"rules"
label-width=
"124px"
>
<el-form-item
label=
"案例原文文件"
prop=
"files"
>
<AppUpload
v-model=
"form.files"
:limit=
"1"
:beforeUpload=
"handleBeforeUpload"
accept=
".doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,.pdf,application/pdf,.ppt,.pptx,application/vnd.ms-powerpoint,.csv,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
@
success=
"handleUploadSuccess"
>
<template
#
tip
>
案例原文文件支持格式包含:doc docx xls xlsx pdf ppt pptx,大小不超过50M
</
template
>
</AppUpload>
</el-form-item>
<el-form-item
label=
"案例原文名称"
prop=
"name"
>
<el-input
v-model=
"form.name"
></el-input>
<p
class=
"form-tips"
>
案例原文名称自动取值于文件名称,可以进行二次修改。
</p>
</el-form-item>
<el-form-item
label=
"关联实验课程"
prop=
"course_id"
>
<el-select
v-model=
"form.course_id"
filterable
style=
"width: 100%"
@
change=
"form.experiment_id = ''"
>
<el-option
v-for=
"item in courses"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"关联实验"
prop=
"experiment_id"
>
<el-select
v-model=
"form.experiment_id"
filterable
style=
"width: 100%"
>
<el-option
v-for=
"item in experimentList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"有效状态"
prop=
"status"
>
<el-radio-group
v-model=
"form.status"
>
<el-radio
v-for=
"item in status"
:key=
"item.id"
:label=
"item.value"
>
{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
prop=
"protocol"
>
<el-checkbox
label=
"我已阅读并同意"
v-model=
"form.protocol"
/>
<a
href=
"https://view.officeapps.live.com/op/view.aspx?src=https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/%E7%B4%AB%E8%8D%86%E6%95%99%E8%82%B2%E7%94%A8%E6%88%B7%E5%85%A5%E9%A9%BB%E5%8F%8A%E7%BD%91%E7%BB%9C%E6%95%99%E5%AD%A6%E8%B5%84%E6%BA%90%E5%8D%8F%E8%AE%AE(1).docx"
target=
"_blank"
>
《紫荆教育用户入驻及网络教学资源协议》
</a
>
</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-dialog>
</template>
<
style
lang=
"scss"
scoped
>
.form-tips
{
font-size
:
12px
;
color
:
#999
;
}
</
style
>
src/modules/admin/lab/case/components/ListItem.vue
0 → 100644
浏览文件 @
868f99b4
<
script
setup
lang=
"ts"
>
import
type
{
CaseItem
}
from
'../types'
import
{
useMapStore
}
from
'@/stores/map'
interface
Props
{
data
:
CaseItem
}
const
props
=
defineProps
<
Props
>
()
const
genFileClassNames
=
$computed
(()
=>
{
const
extName
=
props
.
data
.
url
?.
split
(
'.'
).
pop
()
||
''
return
{
'icon-file__word'
:
extName
.
includes
(
'doc'
),
'icon-file__excel'
:
extName
.
includes
(
'xls'
),
'icon-file__ppt'
:
extName
.
includes
(
'ppt'
),
'icon-file__pdf'
:
extName
.
includes
(
'pdf'
)
}
})
const
username
=
computed
(()
=>
{
const
operator
=
props
.
data
.
created_operator
return
operator
.
real_name
||
operator
.
nickname
||
operator
.
username
})
// 数据状态
const
status
=
useMapStore
().
getMapValuesByKey
(
'system_status'
)
const
statusName
=
computed
(()
=>
{
return
status
.
find
(
item
=>
item
.
value
===
props
.
data
.
status
)?.
label
})
const
sizeName
=
computed
(()
=>
{
return
props
.
data
.
size
+
'MB'
})
</
script
>
<
template
>
<div
class=
"list-item"
>
<div
class=
"list-item-hd"
>
<div
class=
"icon-file"
:class=
"genFileClassNames"
></div>
<div
class=
"button-group"
>
<el-tooltip
effect=
"dark"
content=
"查看"
>
<div
class=
"button icon-view"
v-permission=
"'teacher-experiment-cases-detail'"
>
<router-link
:to=
"`/admin/lab/case/$
{data.id}`" target="_blank">
</router-link>
</div>
</el-tooltip>
<el-tooltip
effect=
"dark"
content=
"编辑"
>
<div
class=
"button icon-edit"
@
click=
"$emit('clickEdit', data)"
v-permission=
"'teacher-experiment-cases-update'"
></div>
</el-tooltip>
</div>
</div>
<div
class=
"list-item-title"
>
<h2>
{{
data
.
name
}}
</h2>
<h6>
{{
statusName
}}
</h6>
</div>
<div
class=
"list-item-main"
>
<ol>
<li>
<p>
文件大小:
{{
sizeName
}}
</p>
</li>
<li>
<p>
观看次数:
{{
data
.
pv
}}
次
</p>
</li>
<li>
<p>
创建人:
{{
username
}}
</p>
</li>
<li>
<p>
创建时间:
{{
data
.
created_time
}}
</p>
</li>
<li>
<p>
更新时间:
{{
data
.
updated_time
}}
</p>
</li>
</ol>
</div>
</div>
</
template
>
<
style
lang=
"scss"
scoped
>
.list-item
{
position
:
relative
;
padding
:
30px
;
background
:
linear-gradient
(
to
bottom
left
,
rgba
(
186
,
20
,
62
,
0
.1
)
0%
,
rgba
(
255
,
255
,
255
,
0
.8
)
60%
);
border-radius
:
12px
;
&
:hover
{
box-shadow
:
0
3px
18px
rgba
(
0
,
0
,
0
,
0
.27
);
}
.list-item-hd
{
display
:
flex
;
justify-content
:
space-between
;
.button-group
{
display
:
flex
;
.button
{
a
{
display
:
block
;
width
:
100%
;
height
:
100%
;
}
}
.button
+
.button
{
margin-left
:
12px
;
}
}
}
.icon-file
{
width
:
30px
;
height
:
30px
;
background
:
url(@/assets/images/icon_word.png)
no-repeat
;
background-size
:
contain
;
}
.icon-file__word
{
background
:
url(@/assets/images/icon_word.png)
no-repeat
;
background-size
:
contain
;
}
.icon-file__excel
{
background
:
url(@/assets/images/icon_excel.png)
no-repeat
;
background-size
:
contain
;
}
.icon-file__ppt
{
background
:
url(@/assets/images/icon_ppt.png)
no-repeat
;
background-size
:
contain
;
}
.icon-file__pdf
{
background
:
url(@/assets/images/icon_pdf.png)
no-repeat
;
background-size
:
contain
;
}
.icon-edit
{
width
:
16px
;
height
:
16px
;
background
:
url(@/assets/images/icon_edit.png)
no-repeat
;
background-size
:
contain
;
cursor
:
pointer
;
}
.icon-view
{
width
:
16px
;
height
:
16px
;
background
:
url(@/assets/images/icon_view.png)
no-repeat
;
background-size
:
contain
;
cursor
:
pointer
;
}
.list-item-main
{
line-height
:
30px
;
ol
{
margin-left
:
20px
;
}
li
{
margin-top
:
24px
;
font-size
:
16px
;
line-height
:
1
;
color
:
var
(
--
main-color
);
list-style
:
disc
;
}
p
{
color
:
#666
;
}
}
.list-item-title
{
margin
:
26px
0
36px
;
display
:
flex
;
justify-content
:
space-between
;
h2
{
flex
:
1
;
font-size
:
18px
;
font-family
:
Source
Han
Sans
CN
;
font-weight
:
bold
;
line-height
:
20px
;
color
:
#333333
;
}
h6
{
margin-left
:
20px
;
font-size
:
16px
;
font-family
:
Source
Han
Sans
CN
;
font-weight
:
500
;
line-height
:
20px
;
color
:
var
(
--
main-color
);
}
}
}
</
style
>
src/modules/admin/lab/case/composables/useGetCourseList.ts
0 → 100644
浏览文件 @
868f99b4
import
{
getCourseList
}
from
'../api'
export
interface
CourseType
{
id
:
string
name
:
string
}
const
courses
=
ref
<
CourseType
[]
>
([])
export
function
useGetCourseList
()
{
!
courses
.
value
.
length
&&
getCourseList
().
then
((
res
:
any
)
=>
{
courses
.
value
=
res
.
data
})
return
{
courses
}
}
src/modules/admin/lab/case/composables/useGetExperimentList.ts
0 → 100644
浏览文件 @
868f99b4
import
{
getExperimentList
}
from
'../api'
export
interface
ExperimentType
{
id
:
string
name
:
string
}
export
function
useGetExperimentList
()
{
const
experiments
=
ref
<
ExperimentType
[]
>
([])
function
updateExperiments
(
courseId
?:
string
)
{
getExperimentList
({
course_id
:
courseId
}).
then
((
res
:
any
)
=>
{
experiments
.
value
=
res
.
data
})
}
return
{
experiments
,
updateExperiments
}
}
src/modules/admin/lab/case/index.ts
0 → 100644
浏览文件 @
868f99b4
import
type
{
RouteRecordRaw
}
from
'vue-router'
import
AppLayout
from
'@/components/layout/Index.vue'
export
const
routes
:
Array
<
RouteRecordRaw
>
=
[
{
path
:
'/admin/lab'
,
redirect
:
'/admin/lab/case'
},
{
path
:
'/admin/lab/case'
,
component
:
AppLayout
,
children
:
[
{
path
:
''
,
component
:
()
=>
import
(
'./views/Index.vue'
)
},
{
path
:
':id'
,
component
:
()
=>
import
(
'./views/View.vue'
),
props
:
true
}
]
}
]
src/modules/admin/lab/case/types.ts
0 → 100644
浏览文件 @
868f99b4
export
interface
CaseItem
{
created_operator
:
CaseOperator
created_time
:
string
delete_time
:
string
course
:
{
id
:
string
name
:
string
}
experiment
:
{
id
:
string
name
:
string
}
experiment_id
:
string
id
:
string
name
:
string
pv
:
string
size
:
string
status
:
string
type
:
string
updated_operator
:
CaseOperator
updated_time
:
string
url
:
string
}
export
interface
CaseOperator
{
avatar
:
string
id
:
string
nickname
:
string
real_name
:
string
username
:
string
}
export
interface
CaseFormData
{
id
?:
string
experiment_id
:
string
course_id
:
string
status
:
string
name
:
string
type
:
string
url
:
string
size
:
string
protocol
:
boolean
files
:
FileItem
[]
}
export
type
CaseCreateItem
=
Pick
<
CaseFormData
,
'experiment_id'
|
'status'
|
'name'
|
'type'
|
'url'
|
'size'
>
export
type
CaseUpdateItem
=
CaseCreateItem
&
{
id
?:
string
}
export
interface
FileItem
{
name
:
string
url
:
string
raw
?:
File
type
?:
string
size
?:
number
}
src/modules/admin/lab/case/views/Index.vue
0 → 100644
浏览文件 @
868f99b4
<
script
setup
lang=
"ts"
>
import
type
{
CaseItem
}
from
'../types'
import
{
CirclePlus
}
from
'@element-plus/icons-vue'
import
AppList
from
'@/components/base/AppList.vue'
import
ListItem
from
'../components/ListItem.vue'
import
{
getCaseList
}
from
'../api'
import
{
useGetExperimentList
}
from
'../composables/useGetExperimentList'
const
FormDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/FormDialog.vue'
))
// 实验列表
const
{
experiments
,
updateExperiments
}
=
useGetExperimentList
()
updateExperiments
()
const
route
=
useRoute
()
const
appList
=
$ref
<
InstanceType
<
typeof
AppList
>
|
null
>
(
null
)
// 列表配置
const
listOptions
=
$computed
(()
=>
{
return
{
remote
:
{
httpRequest
:
getCaseList
,
params
:
{
name
:
''
,
experiment_id
:
route
.
query
.
experiment_id
||
''
}
},
filters
:
[
{
type
:
'input'
,
prop
:
'name'
,
label
:
'案例原文名称'
,
placeholder
:
'请输入案例原文名称'
},
{
type
:
'select'
,
prop
:
'experiment_id'
,
label
:
'关联实验'
,
options
:
experiments
.
value
,
labelKey
:
'name'
,
valueKey
:
'id'
,
placeholder
:
'请选择关联实验'
}
],
columns
:
[{
label
:
'名称'
,
prop
:
'name'
}]
}
})
let
dialogVisible
=
$ref
(
false
)
const
rowData
=
ref
<
CaseItem
|
undefined
|
null
>
(
null
)
// 新增
function
handleAdd
()
{
rowData
.
value
=
null
dialogVisible
=
true
}
// 编辑
function
handleUpdate
(
row
:
CaseItem
)
{
rowData
.
value
=
row
dialogVisible
=
true
}
function
onUpdateSuccess
()
{
appList
?.
refetch
()
}
</
script
>
<
template
>
<AppCard
title=
"案例原文管理"
:hasBodyBackground=
"false"
>
<AppList
v-bind=
"listOptions"
ref=
"appList"
>
<template
#
header-buttons
>
<el-button
type=
"primary"
:icon=
"CirclePlus"
@
click=
"handleAdd"
v-permission=
"'teacher-experiment-cases-create'"
>
新增案例原文
</el-button
>
</
template
>
<
template
#
body=
"{ data }: { data: CaseItem[] }"
>
<div
class=
"list-card"
v-if=
"data.length"
>
<ListItem
v-for=
"item in data"
:data=
"item"
:key=
"item.id"
@
clickEdit=
"handleUpdate(item)"
></ListItem>
</div>
<el-empty
description=
"暂无数据"
v-else
/>
</
template
>
</AppList>
</AppCard>
<FormDialog
v-model=
"dialogVisible"
:data=
"rowData"
@
update=
"onUpdateSuccess"
v-if=
"dialogVisible"
></FormDialog>
</template>
<
style
lang=
"scss"
scoped
>
:deep
(
.table-list-filter
)
{
padding
:
30px
30px
10px
;
background
:
#fff
;
border-radius
:
12px
;
}
.list-card
{
display
:
grid
;
grid-template-columns
:
repeat
(
4
,
1fr
);
gap
:
20px
;
}
</
style
>
src/modules/admin/lab/case/views/View.vue
0 → 100644
浏览文件 @
868f99b4
<
script
setup
lang=
"ts"
>
import
type
{
CaseItem
}
from
'../types'
import
Preview
from
'@/components/Preview.vue'
import
{
useMapStore
}
from
'@/stores/map'
import
{
getCase
}
from
'../api'
interface
Props
{
id
:
string
}
const
props
=
defineProps
<
Props
>
()
let
detail
=
$ref
<
CaseItem
|
null
>
(
null
)
const
username
=
computed
(()
=>
{
if
(
!
detail
)
return
''
const
operator
=
detail
.
created_operator
return
operator
.
real_name
||
operator
.
nickname
||
operator
.
username
})
// 数据状态
const
status
=
useMapStore
().
getMapValuesByKey
(
'system_status'
)
const
statusName
=
computed
(()
=>
{
return
status
.
find
(
item
=>
item
.
value
===
detail
?.
status
)?.
label
})
const
sizeName
=
computed
(()
=>
{
return
detail
?.
size
+
'MB'
})
provide
(
'detail'
,
$$
(
detail
))
function
fetchInfo
()
{
if
(
!
props
.
id
)
return
getCase
({
id
:
props
.
id
}).
then
(
res
=>
{
detail
=
res
.
data
.
item
})
}
onMounted
(()
=>
{
fetchInfo
()
})
</
script
>
<
template
>
<AppCard
title=
"查看案例原文"
>
<template
v-if=
"detail"
>
<el-descriptions>
<el-descriptions-item
label=
"案例原文名称:"
>
{{
detail
.
name
}}
</el-descriptions-item>
<el-descriptions-item
label=
"文件大小:"
>
{{
sizeName
}}
</el-descriptions-item>
<el-descriptions-item
label=
"观看次数:"
>
{{
detail
.
pv
}}
次
</el-descriptions-item>
<el-descriptions-item
label=
"关联实验课程:"
>
{{
detail
.
course
.
name
}}
</el-descriptions-item>
<el-descriptions-item
label=
"关联实验:"
>
{{
detail
.
experiment
.
name
}}
</el-descriptions-item>
<el-descriptions-item
label=
"有效状态:"
>
{{
statusName
}}
</el-descriptions-item>
<el-descriptions-item
label=
"创建人:"
>
{{
username
}}
</el-descriptions-item>
<el-descriptions-item
label=
"创建时间:"
>
{{
detail
.
created_time
}}
</el-descriptions-item>
</el-descriptions>
<div
style=
"height: 80vh"
>
<Preview
:url=
"detail.url"
></Preview>
</div>
</
template
>
</AppCard>
</template>
src/stores/menu.ts
浏览文件 @
868f99b4
...
@@ -46,6 +46,11 @@ const adminMenus: IMenuItem[] = [
...
@@ -46,6 +46,11 @@ const adminMenus: IMenuItem[] = [
path
:
'/admin/lab/experiment'
,
path
:
'/admin/lab/experiment'
,
tag
:
'v1-backend-experiment'
tag
:
'v1-backend-experiment'
},
},
{
name
:
'案例原文管理'
,
path
:
'/admin/lab/case'
,
tag
:
'teacher-experiment-cases'
},
{
{
name
:
'实验指导书管理'
,
name
:
'实验指导书管理'
,
path
:
'/admin/lab/book'
,
path
:
'/admin/lab/book'
,
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论