Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
O
online-edu-admin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
online-edu
online-edu-admin
Commits
d175c790
Commit
d175c790
authored
Jun 02, 2021
by
Liu Peng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
支持课程上传附件
parent
29808f01
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
675 additions
and
567 deletions
+675
-567
detail.vue
src/views/biz/course/detail.vue
+273
-48
index.vue
src/views/biz/homePageSetting/index.vue
+402
-519
No files found.
src/views/biz/course/detail.vue
View file @
d175c790
...
...
@@ -30,6 +30,33 @@
</a-radio-group>
</a-form-model-item>
<a-form-model-item
label=
"系列名称"
prop=
"seriesId"
v-if=
"step1FormModel.type == 'SERIES'"
>
<a-select
:value=
"currentSeries"
label-in-value
show-search
placeholder=
"输入或查询系列"
:default-active-first-option=
"false"
:show-arrow=
"false"
:filter-option=
"false"
:not-found-content=
"null"
@
search=
"handleSeriesSearch"
@
change=
"handleSeriesChange"
>
<a-select-option
v-for=
"d in this.seriesData"
:key=
"d.value"
>
{{
d
.
text
}}
</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item
label=
"课程名称"
prop=
"name"
...
...
@@ -132,31 +159,28 @@
/>
</a-form-model-item>
<a-form-model-item
label=
"系列名称"
prop=
"seriesId"
v-if=
"step1FormModel.type == 'SERIES'"
>
<a-select
:value=
"currentSeries"
label-in-value
show-search
placeholder=
"输入或查询系列"
:default-active-first-option=
"false"
:show-arrow=
"false"
:filter-option=
"false"
:not-found-content=
"null"
@
search=
"handleSeriesSearch"
@
change=
"handleSeriesChange"
<a-form-model-item
label=
"上传附件"
>
<div
v-for=
"(attachment) in attachments"
:label=
"attachment.title"
:key=
"attachment.id"
class=
"video-series"
>
<a-select-option
v-for=
"d in this.seriesData"
:key=
"d.value"
<a-row
type=
"flex"
justify=
"start"
align=
"middle"
>
{{
d
.
text
}}
</a-select-option>
</a-select>
<a-col
:span=
"12"
>
<div
class=
"video-desc"
>
<a-icon
type=
"paper-clip"
class=
"attachment-icon"
/>
{{
attachment
.
title
}}
</div>
</a-col>
</a-row>
</div>
<a-button
@
click=
"showAttachmentUploadModal"
>
上传附件
</a-button>
</a-form-model-item>
<a-form-model-item
...
...
@@ -313,12 +337,13 @@
@
ok=
"videoUpload"
@
cancel=
"closeVideoUploadModal"
:destroyOnClose=
"true"
centered
>
<a-form>
<a-form-item>
<a-input
v-model=
"video.title"
placeholder=
"
输入
视频标题"
placeholder=
"视频标题"
allowClear
></a-input>
</a-form-item>
...
...
@@ -339,6 +364,40 @@
</a-modal>
</
template
>
<
template
>
<a-modal
:visible=
"attachmentUploadModalVisible"
title=
"附件上传"
@
ok=
"saveAttachments"
@
cancel=
"closeAttachmentUploadModal"
:destroyOnClose=
"true"
centered
>
<a-form>
<a-form-item>
<a-input
v-model=
"attachment.title"
placeholder=
"附件标题"
allowClear
></a-input>
</a-form-item>
<a-form-item>
<a-upload
ref=
"attachmentUploaderRef"
name=
"file"
:multiple=
"false"
:show-upload-list=
"true"
:customRequest=
"uploadAttachment"
:before-upload=
"beforeAttachmentUpload"
>
<a-button>
<a-icon
type=
"upload"
/>
选择附件文件
</a-button>
</a-upload>
</a-form-item>
</a-form>
</a-modal>
</
template
>
<
template
>
<a-modal
:visible=
"showVideoEditor"
...
...
@@ -361,6 +420,7 @@
</div>
</template>
<
script
>
import
{
uploadFile
}
from
"@/api/biz/resource"
;
import
{
disposereq
}
from
"@/utils/util"
;
...
...
@@ -433,7 +493,11 @@ export default {
res
.
data
.
forEach
((
d
)
=>
{
const
tg
=
_teachers
.
find
((
t
)
=>
t
.
id
===
d
.
orgId
);
if
(
!
tg
)
{
_teachers
.
push
({
id
:
d
.
orgId
,
name
:
d
.
orgName
,
teachers
:
[
d
]
});
_teachers
.
push
({
id
:
d
.
orgId
,
name
:
d
.
orgName
,
teachers
:
[
d
],
});
}
else
{
tg
.
teachers
.
push
(
d
);
}
...
...
@@ -520,14 +584,23 @@ export default {
}
};
return
{
attachment
:
{
title
:
""
,
},
attachments
:
[],
video2update
:
{},
enterprise
:
[],
currentSeries
:
{},
tags
:
[],
selectedTags
:
[],
videoSeries
:
[],
videoTitle
:
""
,
video
:
{
id
:
""
,
img
:
""
,
file
:
""
,
fileName
:
""
,
title
:
""
},
video
:
{
id
:
""
,
img
:
""
,
file
:
""
,
fileName
:
""
,
title
:
""
,
},
showVideoEditor
:
false
,
teachers
:
[],
seriesData
:
[],
...
...
@@ -542,11 +615,37 @@ export default {
aliyunUserId
:
""
,
//第一步保存时验证规则定义
step1FormRules
:
{
name
:
[{
required
:
true
,
message
:
"不能为空"
,
trigger
:
"blur"
}],
seriesId
:
[{
validator
:
validateSerial
,
trigger
:
"change"
}],
price
:
[{
validator
:
validatePrice
,
trigger
:
"change"
}],
validPeriod
:
[{
validator
:
validateValidPeriod
,
trigger
:
"change"
}],
vipPrice
:
[{
validator
:
validateVipPrice
,
trigger
:
"change"
}],
name
:
[
{
required
:
true
,
message
:
"不能为空"
,
trigger
:
"blur"
,
},
],
seriesId
:
[
{
validator
:
validateSerial
,
trigger
:
"change"
,
},
],
price
:
[
{
validator
:
validatePrice
,
trigger
:
"change"
,
},
],
validPeriod
:
[
{
validator
:
validateValidPeriod
,
trigger
:
"change"
,
},
],
vipPrice
:
[
{
validator
:
validateVipPrice
,
trigger
:
"change"
,
},
],
},
//第一步表单数据对象
step1FormModel
:
{
...
...
@@ -575,6 +674,8 @@ export default {
seriesModalVisible
:
false
,
//视频上传窗口
videoUploadModalVisible
:
false
,
//附件上传窗口
attachmentUploadModalVisible
:
false
,
teacherSearchPage
:
{
name
:
""
,
pageIndex
:
1
,
...
...
@@ -662,7 +763,10 @@ export default {
this
.
fetchSeriesData
(
value
,
(
data
)
=>
{
const
_items
=
[];
data
.
forEach
((
d
)
=>
{
_items
.
push
({
value
:
d
.
id
,
text
:
d
.
name
});
_items
.
push
({
value
:
d
.
id
,
text
:
d
.
name
,
});
});
this
.
seriesData
=
_items
;
});
...
...
@@ -674,12 +778,20 @@ export default {
pageSize
:
500
,
}).
then
((
res
)
=>
{
if
(
res
.
count
===
0
)
{
callback
([{
name
:
value
,
id
:
-
1
}]);
callback
([
{
name
:
value
,
id
:
-
1
,
},
]);
}
else
{
const
item
=
res
.
data
.
find
((
d
)
=>
d
.
name
.
trim
()
===
value
);
if
(
!
item
)
{
//未找到完全匹配的
res
.
data
.
unshift
({
name
:
value
,
id
:
-
1
});
res
.
data
.
unshift
({
name
:
value
,
id
:
-
1
,
});
}
callback
(
res
.
data
);
}
...
...
@@ -688,9 +800,14 @@ export default {
handleSeriesChange
(
value
)
{
if
(
value
.
key
===
-
1
)
{
//新建
saveSeriesInfo
({
name
:
value
.
label
}).
then
((
res
)
=>
{
saveSeriesInfo
({
name
:
value
.
label
,
}).
then
((
res
)
=>
{
if
(
res
.
resp_code
===
200
)
{
this
.
currentSeries
=
{
key
:
res
.
datas
,
label
:
value
.
label
};
this
.
currentSeries
=
{
key
:
res
.
datas
,
label
:
value
.
label
,
};
}
});
}
else
{
...
...
@@ -748,6 +865,7 @@ export default {
vipPrice
,
chaperList
,
tagIds
,
attachmenIds
:
[],
};
if
(
this
.
currentSeries
)
{
course
.
seriesId
=
this
.
currentSeries
.
key
;
...
...
@@ -766,6 +884,11 @@ export default {
_tags
.
push
(
t
.
key
);
});
course
.
tagIds
=
_tags
;
this
.
attachments
.
forEach
((
a
)
=>
{
course
.
attachmenIds
.
push
(
a
.
id
);
});
saveCourse
(
course
).
then
((
res
)
=>
{
if
(
res
.
resp_code
===
200
)
{
this
.
$message
.
success
(
"课程保存成功"
);
...
...
@@ -779,7 +902,9 @@ export default {
getDetail
(
id
)
.
then
((
res
)
=>
{
if
(
res
.
resp_code
==
200
)
{
this
.
step1FormModel
=
{
...
res
.
datas
};
this
.
step1FormModel
=
{
...
res
.
datas
,
};
if
(
this
.
step1FormModel
.
allowOrgList
)
{
const
_enterprise
=
[];
...
...
@@ -791,7 +916,10 @@ export default {
if
(
this
.
step1FormModel
.
tagList
)
{
this
.
step1FormModel
.
tagList
.
forEach
((
t
)
=>
{
this
.
selectedTags
.
push
({
key
:
t
.
tagId
,
label
:
t
.
tagName
});
this
.
selectedTags
.
push
({
key
:
t
.
tagId
,
label
:
t
.
tagName
,
});
});
}
...
...
@@ -800,9 +928,19 @@ export default {
label
:
this
.
step1FormModel
.
seriesName
,
};
console
.
log
(
res
.
datas
);
const
_attachments
=
[];
res
.
datas
.
attachmentList
.
forEach
((
a
)
=>
{
_attachments
.
push
({
id
:
a
.
resourceId
,
title
:
a
.
resourceName
});
});
this
.
attachments
=
_attachments
;
const
_videoSeries
=
[];
res
.
datas
.
chaperList
.
forEach
((
cc
)
=>
{
_videoSeries
.
push
({
...
cc
});
_videoSeries
.
push
({
...
cc
,
});
});
this
.
videoSeries
=
_videoSeries
;
}
else
{
...
...
@@ -857,10 +995,8 @@ export default {
},
beforeVideoUpload
(
file
)
{
const
{
type
}
=
file
;
if
(
!
this
.
video
.
title
)
{
this
.
$message
.
error
(
"请填写视频标题"
);
return
false
;
}
const
title
=
file
.
name
.
substring
(
0
,
file
.
name
.
indexOf
(
"."
));
this
.
video
.
title
=
title
;
if
(
type
.
startsWith
(
"video"
))
{
return
true
;
}
else
{
...
...
@@ -869,6 +1005,58 @@ export default {
}
},
beforeAttachmentUpload
(
file
)
{
const
{
type
}
=
file
;
const
title
=
file
.
name
.
substring
(
0
,
file
.
name
.
indexOf
(
"."
));
this
.
attachment
.
title
=
title
;
},
saveAttachments
()
{
if
(
this
.
attachment
)
{
const
{
title
,
id
}
=
this
.
attachment
;
if
(
!
title
)
{
this
.
$message
.
error
(
"请填写附件标题"
);
return
;
}
if
(
!
id
)
{
this
.
$message
.
error
(
"请上传附件文件"
);
return
;
}
this
.
attachments
.
push
({
title
:
title
,
id
:
id
,
});
this
.
attachment
=
{};
this
.
attachmentUploadModalVisible
=
false
;
}
},
uploadAttachment
(
data
)
{
let
self
=
this
;
const
formData
=
new
FormData
();
formData
.
append
(
"file"
,
data
.
file
);
uploadFile
(
formData
)
.
then
((
res
)
=>
{
if
(
res
.
data
.
resp_code
==
200
)
{
self
.
$refs
.
attachmentUploaderRef
.
onProgress
(
{
percent
:
100
,
},
data
.
file
);
self
.
attachment
.
id
=
res
.
data
.
datas
.
id
;
self
.
$refs
.
attachmentUploaderRef
.
onSuccess
(
null
,
data
.
file
);
}
else
{
this
.
$message
.
info
(
"上传失败"
);
}
this
.
loading
=
false
;
})
.
catch
((
err
)
=>
{
disposereq
(
this
,
err
);
});
},
uploadVideo
({
file
})
{
var
Title
=
this
.
video
.
title
;
this
.
video
.
fileName
=
file
.
name
;
...
...
@@ -973,7 +1161,9 @@ export default {
let
progressPercent
=
Math
.
ceil
(
progress
*
100
);
self
.
authProgress
=
progressPercent
;
self
.
$refs
.
videoUploaderRef
.
onProgress
(
{
percent
:
progressPercent
},
{
percent
:
progressPercent
,
},
uploadInfo
.
file
);
if
(
progressPercent
===
100
)
{
...
...
@@ -1030,9 +1220,26 @@ export default {
this
.
videoUploadModalVisible
=
false
;
this
.
video
=
{};
},
showAttachmentUploadModal
()
{
this
.
attachmentUploadModalVisible
=
true
;
},
closeAttachmentUploadModal
()
{
this
.
attachmentUploadModalVisible
=
false
;
this
.
attachment
=
{};
},
videoUpload
()
{
if
(
this
.
video
)
{
const
{
title
,
id
}
=
this
.
video
;
if
(
!
title
)
{
this
.
$message
.
error
(
"请填写视频标题"
);
return
;
}
if
(
!
id
)
{
this
.
$message
.
error
(
"请上传视频文件"
);
return
;
}
fetchVideoInfo
(
id
).
then
((
res
)
=>
{
if
(
res
.
resp_code
==
200
)
{
const
{
coverURL
,
duration
}
=
res
.
datas
;
...
...
@@ -1055,7 +1262,9 @@ export default {
.
then
((
res
)
=>
{
if
(
res
.
code
==
200
)
{
this
.
teacherData
=
res
.
data
;
var
paper
=
{
...
this
.
teacherPagination
};
var
paper
=
{
...
this
.
teacherPagination
,
};
paper
.
current
=
query
.
pageIndex
;
paper
.
total
=
res
.
count
;
this
.
teacherPagination
=
paper
;
...
...
@@ -1076,29 +1285,38 @@ export default {
},
};
</
script
>
<
style
>
.attachment-icon
{
margin-right
:
5px
;
}
.detail_content
{
background-color
:
#f0f2f5
;
width
:
100%
;
height
:
100%
;
box-sizing
:
border-box
;
}
.search_box
{
width
:
100%
;
box-sizing
:
border-box
;
padding
:
14px
;
background-color
:
#fff
;
}
.steps-content
{
width
:
100%
;
background-color
:
#fff
;
}
.uploadImg
{
cursor
:
pointer
;
}
.table_top
{
padding-bottom
:
14px
;
}
.video-desc
{
margin-left
:
10px
;
height
:
100%
;
...
...
@@ -1111,15 +1329,19 @@ export default {
-webkit-line-clamp
:
2
;
overflow
:
hidden
;
}
.video-series
{
margin-top
:
5px
;
}
.btn-div
{
text-align
:
center
;
}
.cancel-btn
{
margin-left
:
15px
;
}
.video-image-background
{
background-position
:
50%
;
background-repeat
:
no-repeat
;
...
...
@@ -1127,6 +1349,7 @@ export default {
width
:
100%
;
height
:
100%
;
}
.video-image
{
width
:
120px
;
height
:
68px
;
...
...
@@ -1137,6 +1360,7 @@ export default {
cursor
:
pointer
;
background-size
:
60px
;
}
.video-image-time
{
position
:
absolute
;
text-align
:
right
;
...
...
@@ -1163,6 +1387,7 @@ export default {
line-height
:
24px
;
padding
:
0
3px
;
}
.video-image-play
{
position
:
absolute
;
top
:
20px
;
...
...
@@ -1171,6 +1396,7 @@ export default {
color
:
#fff
;
opacity
:
0.4
;
}
.video-image-cover
{
position
:
absolute
;
width
:
100%
;
...
...
@@ -1179,4 +1405,4 @@ export default {
left
:
0
;
z-index
:
1
;
}
</
style
>
\ No newline at end of file
</
style
>
src/views/biz/homePageSetting/index.vue
View file @
d175c790
<
template
>
<div
class=
"price-config-container"
>
<div
class=
"price-config-container"
>
<div
class=
"title-text"
>
轮播图配置
</div>
<a-row
type=
"flex"
class=
"swiper-config"
>
<a-col
v-for=
"swiper in this.swipers"
:key=
"swiper.id"
:value=
"swiper.id"
>
<div
class=
"swiper-div"
>
<div
class=
"img-container"
>
<img
@
click=
"updateSwiper(swiper)"
class=
"image"
v-if=
"swiper.imageUrl"
:src=
"swiper.imageUrl"
/>
<div
class=
"swiper-image-status"
>
<a-tooltip
v-if=
"swiper.status === 'ENABLE'"
placement=
"bottom"
title=
"已发布"
>
<a-icon
type=
"star"
theme=
"filled"
class=
"published-swiper"
@
click=
"changeSwiperStatus(swiper,false)"
/>
</a-tooltip>
<a-tooltip
v-else
placement=
"bottom"
title=
"未发布"
>
<a-icon
type=
"star"
@
click=
"changeSwiperStatus(swiper,true)"
/>
</a-tooltip>
<a-icon
type=
"delete"
@
click=
"removeSwiper(swiper)"
/>
<a-row
type=
"flex"
class=
"swiper-config"
>
<a-col
v-for=
"swiper in this.swipers"
:key=
"swiper.id"
:value=
"swiper.id"
>
<div
class=
"swiper-div"
>
<div
class=
"img-container"
>
<img
@
click=
"updateSwiper(swiper)"
class=
"image"
v-if=
"swiper.imageUrl"
:src=
"swiper.imageUrl"
/>
<div
class=
"swiper-image-status"
>
<a-tooltip
v-if=
"swiper.status === 'ENABLE'"
placement=
"bottom"
title=
"已发布"
>
<a-icon
type=
"star"
theme=
"filled"
class=
"published-swiper"
@
click=
"changeSwiperStatus(swiper,false)"
/>
</a-tooltip>
<a-tooltip
v-else
placement=
"bottom"
title=
"未发布"
>
<a-icon
type=
"star"
@
click=
"changeSwiperStatus(swiper,true)"
/>
</a-tooltip>
<a-icon
type=
"delete"
@
click=
"removeSwiper(swiper)"
/>
</div>
</div>
<div
class=
"course-name"
>
<span>
{{
swiper
.
courseName
}}
</span>
</div>
</div>
</div>
<div
class=
"course-name"
>
<span>
{{
swiper
.
courseName
}}
</span>
</div>
</div>
</a-col>
</a-col>
<a-col>
<div
class=
"create-swiper-div"
@
click=
"displaySwiperCreator"
>
<div
class=
"tool-bar-text"
>
<a-icon
type=
"plus"
class=
"btn-icon"
/><br>
创建轮播图
</div>
</div>
</a-col>
<a-col>
<div
class=
"create-swiper-div"
@
click=
"displaySwiperCreator"
>
<div
class=
"tool-bar-text"
>
<a-icon
type=
"plus"
class=
"btn-icon"
/><br>
创建轮播图
</div>
</div>
</a-col>
</a-row>
<div
class=
"title-text home-tags"
>
首页分类标签
</div>
<a-row
type=
"flex"
class=
"swiper-config-hometags"
>
<a-col
:span=
"24"
>
<div>
<a-tag
v-for=
"(tag) in this.homeTags"
:key=
"tag.id"
color=
"blue"
closable
@
close=
"deleteHomeTag(tag)"
>
{{
tag
.
name
}}
</a-tag>
<a-button
icon=
"plus"
@
click=
"showHomeTagEditor"
size=
"small"
>
添加标签
</a-button>
</div>
</a-col>
<a-row
type=
"flex"
class=
"swiper-config-hometags"
>
<a-col
:span=
"24"
>
<div>
<a-tag
v-for=
"(tag) in this.homeTags"
:key=
"tag.id"
color=
"blue"
closable
@
close=
"deleteHomeTag(tag)"
>
{{
tag
.
name
}}
</a-tag>
<a-button
icon=
"plus"
@
click=
"showHomeTagEditor"
size=
"small"
>
添加标签
</a-button>
</div>
</a-col>
</a-row>
<div
class=
"title-text rec-video"
>
首页推荐视频
</div>
<a-row
type=
"flex"
class=
"swiper-config"
>
<a-col
v-for=
"video in this.homeRecVideos"
:key=
"video.id"
:value=
"video.id"
>
<div
class=
"swiper-div"
>
<div
class=
"img-container"
>
<img
class=
"image"
v-if=
"video.courseLogoUrl"
:src=
"video.courseLogoUrl"
/>
<div
class=
"swiper-image-status"
>
<a-icon
type=
"delete"
@
click=
"removeHomeRecVideo(video)"
/>
<a-row
type=
"flex"
class=
"swiper-config"
>
<a-col
v-for=
"video in this.homeRecVideos"
:key=
"video.id"
:value=
"video.id"
>
<div
class=
"swiper-div"
>
<div
class=
"img-container"
>
<img
class=
"image"
v-if=
"video.courseLogoUrl"
:src=
"video.courseLogoUrl"
/>
<div
class=
"swiper-image-status"
>
<a-icon
type=
"delete"
@
click=
"removeHomeRecVideo(video)"
/>
</div>
</div>
<div
class=
"course-name"
>
<span>
{{
video
.
courseName
}}
</span>
</div>
</div>
</div>
<div
class=
"course-name"
>
<span>
{{
video
.
courseName
}}
</span>
</div>
</div>
</a-col>
</a-col>
<a-col>
<div
class=
"create-swiper-div"
@
click=
"openHomeVideoEditor"
>
<div
class=
"tool-bar-text"
>
<a-icon
type=
"plus"
class=
"btn-icon"
/><br>
添加视频
</div>
</div>
</a-col>
<a-col>
<div
class=
"create-swiper-div"
@
click=
"openHomeVideoEditor"
>
<div
class=
"tool-bar-text"
>
<a-icon
type=
"plus"
class=
"btn-icon"
/><br>
添加视频
</div>
</div>
</a-col>
</a-row>
<template>
<a-modal
:visible=
"showSwiperCreator"
:title=
"currentSwiper.courseId ? '编辑轮播图':'新建轮播图'"
@
ok=
"saveSwiper"
@
cancel=
"closeSwiperCreator"
:destroyOnClose=
"true"
centered
>
<a-form>
<a-form-item
label=
"编辑封面"
>
<div
class=
"siwper-editor"
>
<a-upload
name=
"file"
:multiple=
"false"
list-type=
"picture-card"
:show-upload-list=
"false"
:customRequest=
"uploadSwiperImg"
:before-upload=
"beforeUpload"
>
<a-modal
:visible=
"showSwiperCreator"
:title=
"currentSwiper.courseId ? '编辑轮播图':'新建轮播图'"
@
ok=
"saveSwiper"
@
cancel=
"closeSwiperCreator"
:destroyOnClose=
"true"
centered
>
<a-form>
<a-form-item
label=
"编辑封面"
>
<div
class=
"siwper-editor"
>
<a-upload
name=
"file"
:multiple=
"false"
list-type=
"picture-card"
:show-upload-list=
"false"
:customRequest=
"uploadSwiperImg"
:before-upload=
"beforeUpload"
>
<img
v-if=
"currentSwiper.imageUrl"
:src=
"currentSwiper.imageUrl"
:width=
"200"
/>
<div
v-else
>
<a-icon
:type=
"loading ? 'loading' : 'plus'"
/>
<div
class=
"ant-upload-text"
>
上传封面
</div>
</div>
</a-upload>
</div>
</a-form-item>
<a-form-item
label=
"关联课程"
>
<a-select
show-search
placeholder=
"查询课程"
:default-active-first-option=
"false"
:show-arrow=
"false"
:filter-option=
"false"
:not-found-content=
"null"
@
search=
"onCourseSearch"
@
change=
"onCourseChange"
v-model=
"currentSwiper.courseId"
>
<a-select-option
v-for=
"course in this.courses"
:key=
"course.id"
:value=
"course.id"
>
{{
course
.
name
}}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item
label=
"轮播图状态"
>
<a-radio-group
name=
"radioGroup"
v-model=
"currentSwiper.status"
default-value=
"DISABLE"
>
<a-radio
value=
"ENABLE"
>
已发布
</a-radio>
<a-radio
value=
"DISABLE"
>
未发布
</a-radio>
</a-radio-group>
</a-form-item>
</a-form>
</a-modal>
<img
v-if=
"currentSwiper.imageUrl"
:src=
"currentSwiper.imageUrl"
:width=
"200"
/>
<div
v-else
>
<a-icon
:type=
"loading ? 'loading' : 'plus'"
/>
<div
class=
"ant-upload-text"
>
上传封面
</div>
</div>
</a-upload>
</div>
</a-form-item>
<a-form-item
label=
"关联课程"
>
<a-select
show-search
placeholder=
"查询课程"
:default-active-first-option=
"false"
:show-arrow=
"false"
:filter-option=
"false"
:not-found-content=
"null"
@
search=
"onCourseSearch"
@
change=
"onCourseChange"
v-model=
"currentSwiper.courseId"
>
<a-select-option
v-for=
"course in this.courses"
:key=
"course.id"
:value=
"course.id"
>
{{
course
.
name
}}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item
label=
"轮播图状态"
>
<a-radio-group
name=
"radioGroup"
v-model=
"currentSwiper.status"
default-value=
"DISABLE"
>
<a-radio
value=
"ENABLE"
>
已发布
</a-radio>
<a-radio
value=
"DISABLE"
>
未发布
</a-radio>
</a-radio-group>
</a-form-item>
</a-form>
</a-modal>
</
template
>
<
template
>
<a-modal
:visible=
"showHomeTagCreator"
title=
"添加首页标签"
@
ok=
"saveHomeTags"
@
cancel=
"hideHomeTagEditor"
:destroyOnClose=
"true"
centered
>
<a-form>
<a-form-item
label=
"选择首页标签"
>
<a-select
mode=
"multiple"
v-model=
"tags"
>
<a-select-option
v-for=
"(t) in this.availTags"
:key=
"t.id"
:value=
"t.id"
>
{{
t
.
name
}}
</a-select-option>
</a-select>
</a-form-item>
</a-form>
</a-modal>
<a-modal
:visible=
"showHomeTagCreator"
title=
"添加首页标签"
@
ok=
"saveHomeTags"
@
cancel=
"hideHomeTagEditor"
:destroyOnClose=
"true"
centered
>
<a-form>
<a-form-item
label=
"选择首页标签"
>
<a-select
mode=
"multiple"
v-model=
"tags"
>
<a-select-option
v-for=
"(t) in this.availTags"
:key=
"t.id"
:value=
"t.id"
>
{{
t
.
name
}}
</a-select-option>
</a-select>
</a-form-item>
</a-form>
</a-modal>
</
template
>
<
template
>
<a-modal
:visible=
"showHomeVideoEditor"
title=
"添加推荐视频"
@
ok=
"saveHomeRecVideos"
@
cancel=
"hideHomeVideoEditor"
:destroyOnClose=
"true"
centered
>
<a-form>
<a-form-item
label=
"选择推荐视频"
>
<a-select
mode=
"multiple"
v-model=
"selectedVideos"
>
<a-select-option
v-for=
"(t) in this.availHomeRecVideos"
:key=
"t.id"
:value=
"t.id"
>
{{
t
.
name
}}
</a-select-option>
</a-select>
</a-form-item>
</a-form>
</a-modal>
<a-modal
:visible=
"showHomeVideoEditor"
title=
"添加推荐视频"
@
ok=
"saveHomeRecVideos"
@
cancel=
"hideHomeVideoEditor"
:destroyOnClose=
"true"
centered
>
<a-form>
<a-form-item
label=
"选择推荐视频"
>
<a-select
mode=
"multiple"
v-model=
"selectedVideos"
>
<a-select-option
v-for=
"(t) in this.availHomeRecVideos"
:key=
"t.id"
:value=
"t.id"
>
{{
t
.
name
}}
</a-select-option>
</a-select>
</a-form-item>
</a-form>
</a-modal>
</
template
>
</div>
</div>
</template>
<
script
>
import
{
disposereq
}
from
"@/utils/util"
;
import
{
saveSwiper
,
fetchAllSwiper
,
fetchHomeTags
,
fetchAvaliHomeTags
,
addHomeTag
,
removeHomeTag
,
fetchRecVideos
,
fetchAvailRecVideos
,
addHomeRecVideos
,
removeHomeRecVideos
,
removeSwiper
,
changeSwiperStatus
,
disposereq
}
from
"@/utils/util"
;
import
{
saveSwiper
,
fetchAllSwiper
,
fetchHomeTags
,
fetchAvaliHomeTags
,
addHomeTag
,
removeHomeTag
,
fetchRecVideos
,
fetchAvailRecVideos
,
addHomeRecVideos
,
removeHomeRecVideos
,
removeSwiper
as
deleteSwiper
,
changeSwiperStatus
,
}
from
"@/api/biz/settings"
;
import
{
uploadFile
}
from
"@/api/biz/resource"
;
import
{
fetchList
as
fetchCourseList
}
from
"@/api/biz/course"
;
import
{
fetchList
as
fetchTagList
}
from
"@/api/biz/courseTag"
;
import
{
uploadFile
}
from
"@/api/biz/resource"
;
import
{
fetchList
as
fetchCourseList
}
from
"@/api/biz/course"
;
import
{
fetchList
as
fetchTagList
}
from
"@/api/biz/courseTag"
;
export
default
{
data
()
{
return
{
showHomeVideoEditor
:
false
,
homeRecVideos
:
[],
availHomeRecVideos
:
[],
selectedVideos
:
[],
homeTags
:
[],
tags
:
[],
availTags
:
[],
swipers
:
[],
courses
:
[],
showHomeTagCreator
:
false
,
showSwiperCreator
:
false
,
swiper
:
{},
currentSwiper
:
{},
loading
:
false
,
imageUrl
:
""
,
uploadFile
,
fullPageSize
:
10000
,
};
},
created
()
{
fetchCourseList
({
pageIndex
:
1
,
pageSize
:
this
.
fullPageSize
,
status
:
"UP"
,
allow
:
"ALL"
,
}).
then
((
resp
)
=>
{
this
.
courses
=
resp
.
data
;
});
fetchAllSwiper
().
then
((
resp
)
=>
{
this
.
swipers
=
resp
.
datas
;
});
this
.
fetchAllHomeTags
();
this
.
fetchHomeRecVideos
();
},
beforeUpdate
()
{},
methods
:
{
removeSwiper
(
swiper
)
{
console
.
log
(
swiper
);
},
removeHomeRecVideo
(
video
)
{
removeHomeRecVideos
(
video
.
id
).
then
((
resp
)
=>
{
this
.
fetchHomeRecVideos
();
});
},
saveHomeRecVideos
()
{
const
recVideos
=
[];
this
.
selectedVideos
.
forEach
((
v
)
=>
{
recVideos
.
push
({
courseId
:
v
});
});
addHomeRecVideos
(
recVideos
).
then
((
resp
)
=>
{
this
.
fetchHomeRecVideos
();
this
.
showHomeVideoEditor
=
false
;
});
},
hideHomeVideoEditor
()
{
this
.
selectedVideos
=
[];
this
.
fetchHomeRecVideos
();
this
.
showHomeVideoEditor
=
false
;
},
openHomeVideoEditor
()
{
fetchAvailRecVideos
({
pageIndex
:
1
,
pageSize
:
10000
}).
then
((
resp
)
=>
{
this
.
availHomeRecVideos
=
resp
.
data
;
});
this
.
showHomeVideoEditor
=
true
;
},
fetchHomeRecVideos
()
{
fetchRecVideos
().
then
((
resp
)
=>
{
this
.
homeRecVideos
=
resp
.
datas
;
});
data
()
{
return
{
showHomeVideoEditor
:
false
,
homeRecVideos
:
[],
availHomeRecVideos
:
[],
selectedVideos
:
[],
homeTags
:
[],
tags
:
[],
availTags
:
[],
swipers
:
[],
courses
:
[],
showHomeTagCreator
:
false
,
showSwiperCreator
:
false
,
swiper
:
{},
currentSwiper
:
{},
loading
:
false
,
imageUrl
:
""
,
uploadFile
,
fullPageSize
:
10000
,
};
},
deleteHomeTag
(
tag
)
{
removeHomeTag
(
tag
.
id
).
then
((
resp
)
=>
{
this
.
fetchAllHomeTags
();
});
},
showHomeTagEditor
()
{
fetchAvaliHomeTags
({
pageIndex
:
1
,
pageSize
:
10000
,
}).
then
((
resp
)
=>
{
this
.
availTags
=
resp
.
data
;
});
this
.
showHomeTagCreator
=
true
;
},
fetchAllHomeTags
()
{
fetchHomeTags
().
then
((
resp
)
=>
{
this
.
homeTags
=
resp
.
datas
;
});
},
saveHomeTags
()
{
addHomeTag
(
this
.
tags
).
then
((
resp
)
=>
{
created
()
{
fetchCourseList
({
pageIndex
:
1
,
pageSize
:
this
.
fullPageSize
,
status
:
"UP"
,
allow
:
"ALL"
,
}).
then
((
resp
)
=>
{
this
.
courses
=
resp
.
data
;
});
fetchAllSwiper
().
then
((
resp
)
=>
{
this
.
swipers
=
resp
.
datas
;
});
this
.
fetchAllHomeTags
();
});
this
.
tags
=
[];
this
.
showHomeTagCreator
=
false
;
},
hideHomeTagEditor
()
{
this
.
tags
=
[];
this
.
showHomeTagCreator
=
false
;
},
updateSwiper
(
swiper
)
{
this
.
currentSwiper
=
swiper
;
this
.
showSwiperCreator
=
true
;
},
changeSwiperStatus
(
swiper
,
status
)
{
changeSwiperStatus
({
id
:
swiper
.
id
,
status
:
status
?
"ENABLE"
:
"DISABLE"
,
}).
then
((
resp
)
=>
{
this
.
loadAllSwiper
();
});
},
loadAllSwiper
()
{
fetchAllSwiper
().
then
((
resp
)
=>
{
this
.
swipers
=
resp
.
datas
;
});
},
onCourseChange
(
value
)
{
this
.
currentSwiper
.
courseId
=
value
;
},
onCourseSearch
(
value
)
{
const
searchData
=
{
pageIndex
:
1
,
pageSize
:
this
.
fullPageSize
,
status
:
"UP"
,
allow
:
"ALL"
,
};
if
(
value
)
{
searchData
.
name
=
value
;
}
fetchCourseList
(
searchData
).
then
((
resp
)
=>
{
this
.
courses
=
resp
.
data
;
});
},
onSwiperStatusChange
(
checked
)
{
this
.
currentSwiper
.
online
=
checked
;
this
.
fetchHomeRecVideos
();
},
saveSwiper
()
{
const
data
=
{
...
this
.
currentSwiper
,
};
if
(
this
.
currentSwiper
.
id
)
{
data
.
id
=
this
.
currentSwiper
.
id
;
}
beforeUpdate
()
{},
methods
:
{
removeHomeRecVideo
(
video
)
{
removeHomeRecVideos
(
video
.
id
).
then
((
resp
)
=>
{
this
.
fetchHomeRecVideos
();
});
},
saveHomeRecVideos
()
{
const
recVideos
=
[];
this
.
selectedVideos
.
forEach
((
v
)
=>
{
recVideos
.
push
({
courseId
:
v
});
});
addHomeRecVideos
(
recVideos
).
then
((
resp
)
=>
{
this
.
fetchHomeRecVideos
();
this
.
showHomeVideoEditor
=
false
;
});
},
hideHomeVideoEditor
()
{
this
.
selectedVideos
=
[];
this
.
fetchHomeRecVideos
();
this
.
showHomeVideoEditor
=
false
;
},
openHomeVideoEditor
()
{
fetchAvailRecVideos
({
pageIndex
:
1
,
pageSize
:
10000
}).
then
((
resp
)
=>
{
this
.
availHomeRecVideos
=
resp
.
data
;
});
this
.
showHomeVideoEditor
=
true
;
},
fetchHomeRecVideos
()
{
fetchRecVideos
().
then
((
resp
)
=>
{
this
.
homeRecVideos
=
resp
.
datas
;
});
},
deleteHomeTag
(
tag
)
{
removeHomeTag
(
tag
.
id
).
then
((
resp
)
=>
{
this
.
fetchAllHomeTags
();
});
},
showHomeTagEditor
()
{
fetchAvaliHomeTags
({
pageIndex
:
1
,
pageSize
:
10000
,
}).
then
((
resp
)
=>
{
console
.
log
(
resp
);
this
.
availTags
=
resp
.
data
;
});
this
.
showHomeTagCreator
=
true
;
},
fetchAllHomeTags
()
{
fetchHomeTags
().
then
((
resp
)
=>
{
this
.
homeTags
=
resp
.
datas
;
});
},
saveHomeTags
()
{
addHomeTag
(
this
.
tags
).
then
((
resp
)
=>
{
this
.
fetchAllHomeTags
();
});
this
.
tags
=
[];
this
.
showHomeTagCreator
=
false
;
},
hideHomeTagEditor
()
{
this
.
tags
=
[];
this
.
showHomeTagCreator
=
false
;
},
updateSwiper
(
swiper
)
{
this
.
currentSwiper
=
swiper
;
this
.
showSwiperCreator
=
true
;
},
changeSwiperStatus
(
swiper
,
status
)
{
changeSwiperStatus
({
id
:
swiper
.
id
,
status
:
status
?
"ENABLE"
:
"DISABLE"
,
}).
then
((
resp
)
=>
{
this
.
loadAllSwiper
();
});
},
loadAllSwiper
()
{
fetchAllSwiper
().
then
((
resp
)
=>
{
this
.
swipers
=
resp
.
datas
;
});
},
removeSwiper
(
swiper
)
{
deleteSwiper
(
swiper
.
id
).
then
((
resp
)
=>
{
this
.
loadAllSwiper
();
});
},
onCourseChange
(
value
)
{
this
.
currentSwiper
.
courseId
=
value
;
},
onCourseSearch
(
value
)
{
const
searchData
=
{
pageIndex
:
1
,
pageSize
:
this
.
fullPageSize
,
status
:
"UP"
,
allow
:
"ALL"
,
};
if
(
value
)
{
searchData
.
name
=
value
;
}
fetchCourseList
(
searchData
).
then
((
resp
)
=>
{
this
.
courses
=
resp
.
data
;
});
},
onSwiperStatusChange
(
checked
)
{
this
.
currentSwiper
.
online
=
checked
;
},
saveSwiper
()
{
const
data
=
{
...
this
.
currentSwiper
,
};
if
(
this
.
currentSwiper
.
id
)
{
data
.
id
=
this
.
currentSwiper
.
id
;
}
saveSwiper
(
data
).
then
((
resp
)
=>
{
if
(
resp
.
resp_code
===
200
)
{
this
.
loadAllSwiper
();
this
.
showSwiperCreator
=
false
;
this
.
currentSwiper
=
{};
}
else
{
this
.
$message
.
error
(
`创建轮播图失败:
${
resp
.
resp_msg
}
`
);
}
});
saveSwiper
(
data
).
then
((
resp
)
=>
{
if
(
resp
.
resp_code
===
200
)
{
this
.
loadAllSwiper
();
this
.
showSwiperCreator
=
false
;
this
.
currentSwiper
=
{};
}
else
{
this
.
$message
.
error
(
`创建轮播图失败:
${
resp
.
resp_msg
}
`
);
}
});
},
closeSwiperCreator
()
{
this
.
currentSwiper
=
{};
this
.
loadAllSwiper
();
this
.
showSwiperCreator
=
false
;
},
displaySwiperCreator
()
{
this
.
showSwiperCreator
=
true
;
},
uploadSwiperImg
(
data
)
{
const
formData
=
new
FormData
();
formData
.
append
(
"file"
,
data
.
file
);
this
.
loading
=
true
;
uploadFile
(
formData
)
.
then
((
res
)
=>
{
if
(
res
.
data
.
resp_code
==
200
)
{
this
.
currentSwiper
.
imageUrl
=
res
.
data
.
datas
.
url
;
}
else
{
this
.
$message
.
error
(
"上传封面失败"
);
}
this
.
loading
=
false
;
})
.
catch
((
err
)
=>
{
disposereq
(
this
,
err
);
});
},
beforeUpload
(
file
)
{
const
isJpgOrPng
=
file
.
type
===
"image/jpeg"
||
file
.
type
===
"image/png"
;
if
(
!
isJpgOrPng
)
{
this
.
$message
.
info
(
"只能上传图片"
);
}
const
isLt2M
=
file
.
size
/
1024
/
1024
<
10
;
if
(
!
isLt2M
)
{
this
.
$message
.
error
(
"Image must smaller than 10MB!"
);
}
return
isJpgOrPng
&&
isLt2M
;
},
},
closeSwiperCreator
()
{
this
.
currentSwiper
=
{};
this
.
loadAllSwiper
();
this
.
showSwiperCreator
=
false
;
},
displaySwiperCreator
()
{
this
.
showSwiperCreator
=
true
;
},
uploadSwiperImg
(
data
)
{
const
formData
=
new
FormData
();
formData
.
append
(
"file"
,
data
.
file
);
this
.
loading
=
true
;
uploadFile
(
formData
)
.
then
((
res
)
=>
{
if
(
res
.
data
.
resp_code
==
200
)
{
this
.
currentSwiper
.
imageUrl
=
res
.
data
.
datas
.
url
;
}
else
{
this
.
$message
.
error
(
"上传封面失败"
);
}
this
.
loading
=
false
;
})
.
catch
((
err
)
=>
{
disposereq
(
this
,
err
);
});
},
beforeUpload
(
file
)
{
const
isJpgOrPng
=
file
.
type
===
"image/jpeg"
||
file
.
type
===
"image/png"
;
if
(
!
isJpgOrPng
)
{
this
.
$message
.
info
(
"只能上传图片"
);
}
const
isLt2M
=
file
.
size
/
1024
/
1024
<
10
;
if
(
!
isLt2M
)
{
this
.
$message
.
error
(
"Image must smaller than 10MB!"
);
}
return
isJpgOrPng
&&
isLt2M
;
},
},
};
</
script
>
<
style
>
.price-config-container
{
margin
:
20px
;
background
:
rgb
(
255
,
255
,
255
);
margin
:
20px
;
background
:
rgb
(
255
,
255
,
255
);
}
.price-config-container
.home-tags
{
margin-top
:
20px
;
margin-top
:
20px
;
}
.price-config-container
.rec-video
{
padding-top
:
60px
;
padding-top
:
60px
;
}
.price-config-container
.title-text
{
font-size
:
16px
;
font-weight
:
bold
;
color
:
#000
;
font-size
:
16px
;
font-weight
:
bold
;
color
:
#000
;
}
.price-config-container
.swiper-config
{
margin-top
:
10px
;
margin-top
:
10px
;
}
.price-config-container
.swiper-config
.published-swiper
{
color
:
#f0943c
;
color
:
#f0943c
;
}
.price-config-container
.swiper-config-hometags
{
padding-top
:
20px
;
padding-top
:
20px
;
}
.price-config-container
.swiper-div
{
width
:
150px
;
height
:
150px
;
display
:
table
;
float
:
left
;
margin-right
:
8px
;
margin-bottom
:
8px
;
vertical-align
:
top
;
cursor
:
pointer
;
-webkit-transition
:
border-color
0.3s
ease
;
transition
:
border-color
0.3s
ease
;
width
:
150px
;
height
:
150px
;
display
:
table
;
float
:
left
;
margin-right
:
8px
;
margin-bottom
:
8px
;
vertical-align
:
top
;
cursor
:
pointer
;
-webkit-transition
:
border-color
0.3s
ease
;
transition
:
border-color
0.3s
ease
;
}
.price-config-container
.swiper-div
.course-name
{
padding-top
:
5px
;
word-break
:
break-all
;
text-overflow
:
ellipsis
;
overflow
:
hidden
;
font-weight
:
bold
;
font-size
:
14px
;
color
:
#303030
;
line-height
:
20px
;
height
:
60px
;
padding-top
:
5px
;
word-break
:
break-all
;
text-overflow
:
ellipsis
;
overflow
:
hidden
;
font-weight
:
bold
;
font-size
:
14px
;
color
:
#303030
;
line-height
:
20px
;
height
:
60px
;
}
.price-config-container
.create-swiper-div
{
width
:
150px
;
height
:
150px
;
display
:
table
;
float
:
left
;
margin-right
:
8px
;
margin-bottom
:
8px
;
text-align
:
center
;
vertical-align
:
top
;
background-color
:
#fafafa
;
border
:
1px
dashed
#d9d9d9
;
border-radius
:
4px
;
cursor
:
pointer
;
-webkit-transition
:
border-color
0.3s
ease
;
transition
:
border-color
0.3s
ease
;
width
:
150px
;
height
:
150px
;
display
:
table
;
float
:
left
;
margin-right
:
8px
;
margin-bottom
:
8px
;
text-align
:
center
;
vertical-align
:
top
;
background-color
:
#fafafa
;
border
:
1px
dashed
#d9d9d9
;
border-radius
:
4px
;
cursor
:
pointer
;
-webkit-transition
:
border-color
0.3s
ease
;
transition
:
border-color
0.3s
ease
;
}
.price-config-container
.create-swiper-div
:hover
{
border-color
:
#1890ff
;
border-color
:
#1890ff
;
}
.price-config-container
.img-container
{
width
:
250px
;
height
:
150px
;
width
:
250px
;
height
:
150px
;
}
.price-config-container
.image
{
width
:
100%
;
height
:
100%
;
width
:
100%
;
height
:
100%
;
}
.price-config-container
.tool-bar-text
{
display
:
table-cell
;
width
:
100%
;
height
:
100%
;
padding
:
8px
;
text-align
:
center
;
vertical-align
:
middle
;
display
:
table-cell
;
width
:
100%
;
height
:
100%
;
padding
:
8px
;
text-align
:
center
;
vertical-align
:
middle
;
}
.price-config-container
.tool-bar-text
.btn-icon
{
font-size
:
20px
;
font-size
:
20px
;
}
.swiper-image-status
{
position
:
absolute
;
text-align
:
right
;
color
:
#fff
;
width
:
100%
;
top
:
0
;
z-index
:
2
;
height
:
24px
;
line-height
:
24px
;
padding-right
:
15px
;
font-size
:
14px
;
position
:
absolute
;
text-align
:
right
;
color
:
#fff
;
width
:
100%
;
top
:
0
;
z-index
:
2
;
height
:
24px
;
line-height
:
24px
;
padding-right
:
15px
;
font-size
:
14px
;
}
</
style
>
\ No newline at end of file
</
style
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment