Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
C
center-resource
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
center-resource
Commits
f6db113b
提交
f6db113b
authored
10月 21, 2022
作者:
matian
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
updates
上级
6ae0e86f
隐藏空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
172 行增加
和
45 行删除
+172
-45
AppUpload.vue
src/components/base/AppUpload.vue
+10
-6
AddPostDialog.vue
src/modules/teach/posts/components/AddPostDialog.vue
+1
-2
ReplyPostItem.vue
src/modules/teach/posts/components/ReplyPostItem.vue
+124
-25
List.vue
src/modules/teach/posts/views/List.vue
+7
-5
View.vue
src/modules/teach/posts/views/View.vue
+30
-7
没有找到文件。
src/components/base/AppUpload.vue
浏览文件 @
f6db113b
...
...
@@ -47,15 +47,18 @@ const handleBeforeUpload = async (file: any) => {
fileList
.
value
.
filter
((
item
:
any
)
=>
item
.
name
.
includes
(
'.jpeg'
)).
length
>
10
)
{
const
videoList
=
fileList
.
value
.
filter
((
item
:
any
)
=>
item
.
name
.
includes
(
'.mp4'
))
const
imgList
=
fileList
.
value
.
filter
((
item
:
any
)
=>
!
item
.
name
.
includes
(
'.mp4'
)).
slice
(
0
,
10
)
const
videoList
=
fileList
.
value
.
filter
((
item
:
any
)
=>
item
.
name
.
includes
(
'.mp4'
)).
slice
(
0
,
1
)
const
imgList
=
fileList
.
value
.
filter
((
item
:
any
)
=>
item
.
name
.
includes
(
'.png'
)
||
item
.
name
.
includes
(
'.jpg'
)
||
item
.
name
.
includes
(
'.jpeg'
))
.
slice
(
0
,
10
)
fileList
.
value
=
[...
videoList
,
...
imgList
]
ElMessage
.
warning
(
'支持最多上传10张图片,格式支持jpg,jpeg,png'
)
}
else
if
(
fileList
.
value
.
filter
((
item
:
any
)
=>
item
.
name
.
includes
(
'.mp4'
)).
length
>
1
)
{
const
videoList
=
fileList
.
value
.
filter
((
item
:
any
)
=>
item
.
name
.
includes
(
'.mp4'
)).
slice
(
0
,
1
)
const
imgList
=
fileList
.
value
.
filter
((
item
:
any
)
=>
!
item
.
name
.
includes
(
'.mp4'
))
const
imgList
=
fileList
.
value
.
filter
((
item
:
any
)
=>
item
.
name
.
includes
(
'.png'
)
||
item
.
name
.
includes
(
'.jpg'
)
||
item
.
name
.
includes
(
'.jpeg'
))
.
slice
(
0
,
10
)
fileList
.
value
=
[...
videoList
,
...
imgList
]
console
.
log
(
fileList
.
value
)
ElMessage
.
warning
(
'视频最多长传1个'
)
}
}
...
...
@@ -65,14 +68,15 @@ const handleBeforeUpload = async (file: any) => {
const
handleSuccess
=
(
response
:
any
,
file
:
any
,
files
:
any
)
=>
{
if
(
!
files
.
every
((
item
:
any
)
=>
item
.
status
===
'success'
))
return
if
(
showFileList
.
value
)
{
console
.
log
(
files
)
emit
(
'update:modelValue'
,
files
.
map
((
item
:
any
)
=>
{
return
{
name
:
item
.
name
,
url
:
item
.
url
||
item
.
raw
.
url
,
size
:
item
.
raw
.
size
,
type
:
item
.
raw
.
type
||
item
.
raw
.
url
size
:
item
.
size
||
item
.
raw
.
size
,
type
:
item
.
type
||
item
.
raw
.
type
}
})
)
...
...
src/modules/teach/posts/components/AddPostDialog.vue
浏览文件 @
f6db113b
...
...
@@ -19,7 +19,6 @@ interface Emits {
(
e
:
'update:isShowAddDialog'
,
isShowAddDialog
:
boolean
):
void
(
e
:
'create'
):
void
}
const
form
:
any
=
reactive
({
organ_id
:
''
,
semester_id
:
''
,
...
...
@@ -244,8 +243,8 @@ const handleChangeCourse = () => {
<div
class=
"upload-box"
>
<AppUpload
accept=
".mp4,.png,.jpeg,.jpg"
:limit=
"11"
:multiple=
"true"
:limit=
"11"
v-model=
"form.files"
:isPost=
"'1'"
></AppUpload>
...
...
src/modules/teach/posts/components/ReplyPostItem.vue
浏览文件 @
f6db113b
<
script
lang=
"ts"
setup
>
import
{
replyPosts
,
getReplyPostItem
}
from
'../api'
import
{
replyPosts
,
getReplyPostItem
,
delPosts
}
from
'../api'
import
{
ElMessage
,
ElMessageBox
}
from
'element-plus'
const
emit
=
defineEmits
<
Emits
>
()
const
props
=
defineProps
({
firstFloor
:
{
...
...
@@ -12,16 +13,23 @@ const props = defineProps({
interface
Emits
{
(
e
:
'update'
):
void
}
const
currentPage
=
ref
(
1
)
const
totalItem
=
ref
(
0
)
const
reply_content
=
ref
(
''
)
const
isShowReply
=
ref
(
false
)
const
id
=
ref
(
''
)
const
postItem
:
any
=
ref
({})
const
postItemList
=
ref
(
JSON
.
parse
(
JSON
.
stringify
(
props
.
firstFloor
?.
comments
)))
const
postItemList
:
any
=
ref
([])
const
previewList
:
any
=
ref
([])
watchEffect
(()
=>
{
postItemList
.
value
=
props
.
firstFloor
?.
comments
||
[]
totalItem
.
value
=
props
.
firstFloor
?.
comments_total
||
0
})
// 最上面的回复
const
handleReply
=
(
val
:
any
)
=>
{
isShowReply
.
value
=
true
id
.
value
=
val
.
id
postItem
.
value
=
''
}
// 回复列表下面的回复
const
handleReplyItem
=
(
val
:
any
)
=>
{
...
...
@@ -37,8 +45,9 @@ const handleReplySubmit = () => {
reply_id
:
props
.
firstFloor
?.
id
}
replyPosts
(
params
).
then
(()
=>
{
emit
(
'update'
)
reply_content
.
value
=
''
isShowReply
.
value
=
false
emit
(
'update'
)
})
}
// 查看更多
...
...
@@ -48,10 +57,18 @@ const handleViewMore = (val: any) => {
// 获取评论二级列表数据
const
handleGetItemFloor
=
(
val
:
any
)
=>
{
const
params
:
any
=
{
page
:
currentPage
.
value
++
,
[
'per-page'
]:
20
,
reply_id
:
val
}
getReplyPostItem
(
params
).
then
(
res
=>
{
postItemList
.
value
=
res
.
data
.
list
if
(
params
.
page
===
1
)
{
postItemList
.
value
=
res
.
data
.
list
console
.
log
(
postItemList
.
value
)
}
else
{
postItemList
.
value
=
postItemList
.
value
.
concat
(
res
.
data
.
list
)
}
totalItem
.
value
=
res
.
data
.
total
})
}
const
imgUrl
=
computed
(()
=>
{
...
...
@@ -65,10 +82,30 @@ const imgUrl = computed(() => {
return
'https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/xt.png'
}
})
// 图片预览
if
(
props
.
firstFloor
?.
files
.
length
>
0
)
{
previewList
.
value
=
props
.
firstFloor
?.
files
.
map
((
it
:
any
)
=>
{
if
(
it
?.
name
.
includes
(
'.png'
)
||
it
?.
name
.
includes
(
'.jpg'
)
||
it
?.
name
.
includes
(
'.jpeg'
))
{
return
it
.
url
}
})
}
// 删除楼层
const
handleDelFloor
=
(
val
:
any
)
=>
{
ElMessageBox
.
confirm
(
'确定要删除该楼层吗?'
,
'提示'
).
then
(()
=>
{
const
params
:
any
=
{
id
:
val
,
type
:
'reply'
}
delPosts
(
params
).
then
(()
=>
{
ElMessage
.
success
(
'帖子删除成功'
)
emit
(
'update'
)
})
})
}
</
script
>
<
template
>
<div
class=
"main_post"
>
<div
class=
"post_left"
>
<!--
<div
class=
"left_logo"
v-if=
"props.firstFloor?.floor === 1"
>
楼主
</div>
-->
<img
:src=
"
props.firstFloor?.avatar ||
...
...
@@ -86,24 +123,39 @@ const imgUrl = computed(() => {
</div>
</div>
<div
class=
"post_right"
>
<el-button
type=
"primary"
round
class=
"right_btn"
v-if=
"props.firstFloor?.floor > 1"
@
click=
"handleDelFloor(props.firstFloor?.id)"
>
删除当前楼层
</el-button
>
<div
class=
"right_con"
v-html=
"props.firstFloor?.content"
></div>
<template
v-if=
"props.firstFloor?.files.length > 0"
>
<div
class=
"right_files"
v-for=
"(it, index) in props.firstFloor?.files"
:key=
"index"
>
<img
:src=
"it?.url"
alt=
""
v-if=
"it?.name.includes('.png') || it?.name.includes('.jpg') || it?.name.includes('.jpeg')"
style=
"width: 100px"
/>
<video
:src=
"it?.url"
v-if=
"it?.name.includes('.mp4')"
></video>
<div
class=
"right_files"
>
<template
v-for=
"(it, index) in props.firstFloor?.files"
:key=
"index"
>
<el-image
:src=
"it?.url"
v-if=
"it?.name.includes('.png') || it?.name.includes('.jpg') || it?.name.includes('.jpeg')"
style=
"width: 100px"
:preview-src-list=
"previewList"
:initial-index=
"4"
fit=
"cover"
/>
<video
v-if=
"it?.name.includes('.mp4')"
controls
id=
"video"
>
<source
:src=
"it?.url"
/>
</video>
</
template
>
</div>
</template>
<div
class=
"right_time"
>
发表于 {{ props.firstFloor?.updated_time }}
</div>
<div
class=
"right_time"
>
发表于
{{ props.firstFloor?.updated_time }}
</div>
<el-link
:underline=
"false"
class=
"right_btn"
@
click=
"handleReply(props.firstFloor)"
>
<img
src=
"https://webapp-pub.
oss-cn-beijing.aliyuncs
.com/center_resource/reply_btn.png"
alt=
""
/>
<img
src=
"https://webapp-pub.
ezijing
.com/center_resource/reply_btn.png"
alt=
""
/>
<div
class=
"btn_txt"
>
回复
</div>
</el-link>
<div
class=
"right_list"
v-if=
"props.firstFloor?.comments
.length
> 0"
>
<div
class=
"right_list"
v-if=
"props.firstFloor?.comments
_total
> 0"
>
<div
v-for=
"(item, index) in postItemList"
:key=
"index"
>
<div
class=
"list_top"
>
<img
...
...
@@ -122,26 +174,33 @@ const imgUrl = computed(() => {
</div>
<div
class=
"list_con"
v-html=
"item.content"
></div>
<div
class=
"list_bottom"
>
<div
class=
"bottom_time"
>
来自于{{ item.updated_time }}
</div>
<div
class=
"bottom_time"
>
来自于
{{ item.updated_time }}
</div>
<el-link
:underline=
"false"
class=
"bottom_reply"
@
click=
"handleReplyItem(item)"
>
<img
src=
"https://webapp-pub.
oss-cn-beijing.aliyuncs
.com/center_resource/reply_btn.png"
alt=
""
/>
<img
src=
"https://webapp-pub.
ezijing
.com/center_resource/reply_btn.png"
alt=
""
/>
<div
class=
"reply_txt"
@
click=
"handleReplyItem(item)"
>
回复
</div>
</el-link>
</div>
</div>
<div
class=
"list_more"
v-if=
"props.firstFloor?.comments_total > 3"
>
<el-link
:underline=
"false"
type=
"primary"
size=
"mini"
@
click=
"handleViewMore(props.firstFloor?.id)"
<div
class=
"list_more"
v-if=
"totalItem > 3"
>
<el-link
:underline=
"false"
type=
"primary"
size=
"mini"
@
click=
"handleViewMore(props.firstFloor?.id)"
v-if=
"postItemList.length !== totalItem"
>
查看更多
</el-link
>
</div>
</div>
<!-- 回复框 -->
<div
class=
"reply_input"
v-if=
"isShowReply === true"
>
<div
class=
"input_txt"
v-if=
"postItem === ''"
>
回复本楼
</div>
<el-input
v-model=
"reply_content"
:autosize=
"{ minRows:
2, maxRows: 4
}"
:autosize=
"{ minRows:
4, maxRows: 6
}"
type=
"textarea"
style=
"width: 100%"
:placeholder=
"postItem.to_name ? `回复
${postItem.to_name}
` : ''"
:placeholder=
"postItem.to_name ? `回复
@${postItem.to_name}:
` : ''"
/>
<el-button
class=
"input_btn"
type=
"primary"
@
click=
"handleReplySubmit"
>
发表回复
</el-button>
</div>
...
...
@@ -160,6 +219,20 @@ const imgUrl = computed(() => {
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
position
:
relative
;
.left_logo
{
height
:
0
;
width
:
0
;
border-top
:
29px
solid
#ba143e
;
border-left
:
29px
solid
#ba143e
;
border-bottom
:
29px
solid
transparent
;
border-right
:
29px
solid
transparent
;
align-self
:
flex-start
;
position
:
absolute
;
top
:
0
;
left
:
0
;
}
.left_avatar
{
width
:
100px
;
height
:
100px
;
...
...
@@ -198,7 +271,7 @@ const imgUrl = computed(() => {
}
.post_right
{
width
:
100%
;
padding
:
40px
21px
0
40px
;
padding
:
40px
21px
40px
40px
;
display
:
flex
;
flex-direction
:
column
;
.right_con
{
...
...
@@ -207,6 +280,19 @@ const imgUrl = computed(() => {
color
:
#666666
;
line-height
:
27px
;
}
.right_files
{
display
:
flex
;
flex-wrap
:
wrap
;
justify-content
:
flex-start
;
video
{
width
:
300px
;
height
:
200px
;
}
.el-image
{
margin
:
20px
;
}
}
.right_time
{
font-size
:
14px
;
font-weight
:
400
;
...
...
@@ -223,6 +309,10 @@ const imgUrl = computed(() => {
}
.btn_txt
{
margin-left
:
9px
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
27px
;
color
:
#9b9b9b
;
}
}
.reply_input
{
...
...
@@ -288,8 +378,8 @@ const imgUrl = computed(() => {
align-items
:
center
;
cursor
:
pointer
;
img
{
width
:
2
0
px
;
height
:
2
0
px
;
width
:
2
2
px
;
height
:
2
2
px
;
}
.reply_txt
{
font-size
:
16px
;
...
...
@@ -308,4 +398,13 @@ const imgUrl = computed(() => {
height
:
4px
;
background
:
#e8e8e8
;
}
:deep
(
.el-textarea
)
{
.el-textarea__inner
{
padding
:
20px
0
0
20px
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
27px
;
color
:
#999999
;
}
}
</
style
>
src/modules/teach/posts/views/List.vue
浏览文件 @
f6db113b
<
script
setup
lang=
"ts"
>
import
{
ElMessage
}
from
'element-plus'
import
{
ElMessage
,
ElMessageBox
}
from
'element-plus'
import
{
getConditionList
,
getPostsList
,
delPosts
,
setTopPosts
}
from
'../api'
import
AddPostDialog
from
'../components/AddPostDialog.vue'
import
{
useProjectList
}
from
'@/composables/useGetProjectList'
...
...
@@ -173,10 +173,12 @@ const handleGetchaptereList = () => {
}
// 删除帖子
const
handleDel
=
(
row
:
any
)
=>
{
const
params
:
any
=
{
id
:
row
.
id
,
type
:
'discussion'
}
delPosts
(
params
).
then
(()
=>
{
ElMessage
.
success
(
'帖子删除成功'
)
handleRefresh
()
ElMessageBox
.
confirm
(
'确定要删除该帖子吗?'
,
'提示'
).
then
(()
=>
{
const
params
:
any
=
{
id
:
row
.
id
,
type
:
'discussion'
}
delPosts
(
params
).
then
(()
=>
{
ElMessage
.
success
(
'帖子删除成功'
)
handleRefresh
()
})
})
}
// 置顶帖子
...
...
src/modules/teach/posts/views/View.vue
浏览文件 @
f6db113b
<
script
setup
lang=
"ts"
>
import
ReplyPostDialog
from
'../components/ReplyPostDialog.vue'
import
ReplyPostItem
from
'../components/ReplyPostItem.vue'
import
{
getPostFirst
}
from
'../api'
import
{
getPostFirst
,
delPosts
}
from
'../api'
import
{
ElMessage
,
ElMessageBox
}
from
'element-plus'
const
route
=
useRoute
()
const
isShowReplyDialog
=
ref
(
false
)
const
postInfo
:
any
=
ref
({})
const
firstPostList
:
any
=
ref
([])
const
totalFloor
:
any
=
ref
(
0
)
const
discussionId
:
any
=
route
.
query
.
id
const
currentPage
=
ref
(
1
)
const
page
=
reactive
({
...
...
@@ -16,23 +19,42 @@ onMounted(() => {
handleGetFirstFloor
()
})
const
handleGetFirstFloor
=
()
=>
{
const
params
:
any
=
{
discussion_id
:
discussionId
}
const
params
:
any
=
{
discussion_id
:
discussionId
,
page
:
page
.
currentPage
,
[
'per-page'
]:
page
.
size
}
getPostFirst
(
params
).
then
(
res
=>
{
totalFloor
.
value
=
res
.
data
.
total
postInfo
.
value
=
res
.
data
.
info
firstPostList
.
value
=
res
.
data
.
list
firstPostList
.
value
.
map
((
item
:
any
)
=>
{
item
.
files
=
JSON
.
parse
(
item
.
files
)
if
(
item
.
files
!==
''
)
{
item
.
files
=
JSON
.
parse
(
item
.
files
)
}
})
})
}
const
handleReplyNewFloor
=
()
=>
{
isShowReplyDialog
.
value
=
true
}
const
handleSizeChange
=
(
val
:
any
)
=>
{
page
.
currentPage
=
1
page
.
size
=
val
handleFresh
()
}
const
handleCurrentChange
=
(
val
:
any
)
=>
{
page
.
currentPage
=
val
handleFresh
()
}
const
handleDelPosts
=
()
=>
{
ElMessageBox
.
confirm
(
'确定要删除该帖子吗?'
,
'提示'
).
then
(()
=>
{
const
params
:
any
=
{
id
:
discussionId
,
type
:
'discussion'
}
delPosts
(
params
).
then
(()
=>
{
ElMessage
.
success
(
'帖子删除成功'
)
history
.
go
(
-
1
)
})
})
}
const
handleFresh
=
()
=>
{
handleGetFirstFloor
()
}
</
script
>
<
template
>
...
...
@@ -41,24 +63,25 @@ const handleCurrentChange = (val: any) => {
<div
class=
"card-header"
>
<span>
{{
postInfo
.
title
}}
</span>
<div
class=
"content_btn"
>
<el-button
type=
"primary"
round
>
删除当前帖子
</el-button>
<el-button
type=
"primary"
round
@
click=
"handleDelPosts"
>
删除当前帖子
</el-button>
<el-button
@
click=
"handleReplyNewFloor"
round
>
回复新楼层
</el-button>
</div>
</div>
<ReplyPostItem
v-for=
"(item, index) in firstPostList
.slice((page.currentPage - 1) * page.size, page.currentPage * page.size)
"
v-for=
"(item, index) in firstPostList"
:key=
"index"
:firstFloor=
"item"
:discussionId=
"discussionId"
@
update=
"handle
GetFirstFloor
"
@
update=
"handle
Fresh
"
/>
<el-pagination
class=
"pagination"
v-model:currentPage=
"currentPage"
:page-size=
"page.size"
layout=
"total, sizes, prev, pager, next, jumper"
:page-sizes=
"[5, 10, 20, 30, 50]"
:total=
"
firstPostList.length
"
:total=
"
totalFloor
"
@
size-change=
"handleSizeChange"
@
current-change=
"handleCurrentChange"
>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论