Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
389c73d8
authored
Apr 15, 2023
by
dhb52
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor: MP消息管理-拆分组件
parent
de5b1216
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
507 additions
and
384 deletions
+507
-384
src/views/mp/material/components/Upload.vue
+70
-0
src/views/mp/material/components/UploadVideo.vue
+127
-0
src/views/mp/material/components/VideoTable.vue
+61
-0
src/views/mp/material/components/VoiceTable.vue
+53
-0
src/views/mp/material/components/Waterfall.vue
+83
-0
src/views/mp/material/components/upload.ts
+73
-0
src/views/mp/material/index.vue
+40
-384
No files found.
src/views/mp/material/components/Upload.vue
0 → 100644
View file @
389c73d8
<
template
>
<el-upload
:action=
"UPLOAD_URL"
:headers=
"HEADERS"
multiple
:limit=
"1"
:file-list=
"fileList"
:data=
"uploadData"
:on-progress=
"() => (uploading = true)"
:before-upload=
"beforeUpload"
:on-success=
"handleUploadSuccess"
>
<el-button
type=
"primary"
plain
:loading=
"uploading"
:disabled=
"uploading"
>
{{
uploading
?
'正在上传'
:
'点击上传'
}}
</el-button>
<template
#
tip
>
<span
class=
"el-upload__tip"
style=
"margin-left: 5px"
>
<slot></slot>
</span>
</
template
>
</el-upload>
</template>
<
script
setup
lang=
"ts"
>
import
type
{
UploadProps
,
UploadUserFile
}
from
'element-plus'
import
{
HEADERS
,
UPLOAD_URL
,
UploadData
,
MaterialType
,
beforeImageUpload
,
beforeVoiceUpload
}
from
'./upload'
const
message
=
useMessage
()
const
props
=
defineProps
<
{
type
:
boolean
}
>
()
const
fileList
=
ref
<
UploadUserFile
[]
>
([])
const
emit
=
defineEmits
<
{
(
e
:
'uploaded'
,
v
:
void
)
}
>
()
const
uploadData
:
UploadData
=
reactive
({
type
:
MaterialType
.
Image
,
title
:
''
,
introduction
:
''
})
const
uploading
=
ref
(
false
)
const
beforeUpload
=
props
.
type
==
MaterialType
.
Image
?
beforeImageUpload
:
beforeVoiceUpload
const
handleUploadSuccess
:
UploadProps
[
'onSuccess'
]
=
(
res
:
any
)
=>
{
if
(
res
.
code
!==
0
)
{
message
.
alertError
(
'上传出错:'
+
res
.
msg
)
return
false
}
// 清空上传时的各种数据
fileList
.
value
=
[]
uploadData
.
title
=
''
uploadData
.
introduction
=
''
message
.
notifySuccess
(
'上传成功'
)
uploading
.
value
=
false
emit
(
'uploaded'
)
}
</
script
>
<
style
scoped
></
style
>
src/views/mp/material/components/UploadVideo.vue
0 → 100644
View file @
389c73d8
<
template
>
<el-dialog
title=
"新建视频"
v-model=
"showDialog"
width=
"600px"
destroy-on-close
>
<el-upload
:action=
"UPLOAD_URL"
:headers=
"HEADERS"
multiple
:limit=
"1"
:file-list=
"fileList"
:data=
"uploadData"
:before-upload=
"beforeVideoUpload"
:on-progress=
"() => (uploading = true)"
:on-success=
"handleUploadSuccess"
ref=
"uploadVideoRef"
:auto-upload=
"false"
class=
"mb-5"
>
<template
#
trigger
>
<el-button
type=
"primary"
plain
>
选择视频
</el-button>
</
template
>
<span
class=
"el-upload__tip"
style=
"margin-left: 10px"
>
格式支持 MP4,文件大小不超过 10MB
</span
>
</el-upload>
<el-divider
/>
<el-form
:model=
"uploadData"
:rules=
"uploadRules"
ref=
"uploadFormRef"
v-loading=
"uploading"
>
<el-form-item
label=
"标题"
prop=
"title"
>
<el-input
v-model=
"uploadData.title"
placeholder=
"标题将展示在相关播放页面,建议填写清晰、准确、生动的标题"
/>
</el-form-item>
<el-form-item
label=
"描述"
prop=
"introduction"
>
<el-input
:rows=
"3"
type=
"textarea"
v-model=
"uploadData.introduction"
placeholder=
"介绍语将展示在相关播放页面,建议填写简洁明确、有信息量的内容"
/>
</el-form-item>
</el-form>
<
template
#
footer
>
<el-button
@
click=
"showDialog = false"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"submitVideo"
:loading=
"uploading"
:disabled=
"uploading"
>
提 交
</el-button
>
</
template
>
</el-dialog>
</template>
<
script
setup
lang=
"ts"
>
import
type
{
FormInstance
,
FormRules
,
UploadInstance
,
UploadProps
,
UploadUserFile
}
from
'element-plus'
import
{
HEADERS
,
UploadData
,
UPLOAD_URL
,
beforeVideoUpload
,
MaterialType
}
from
'./upload'
const
message
=
useMessage
()
const
uploadRules
:
FormRules
=
{
title
:
[{
required
:
true
,
message
:
'请输入标题'
,
trigger
:
'blur'
}],
introduction
:
[{
required
:
true
,
message
:
'请输入描述'
,
trigger
:
'blur'
}]
}
const
props
=
defineProps
({
modelValue
:
{
type
:
Boolean
,
default
:
false
}
})
const
emit
=
defineEmits
<
{
(
e
:
'update:modelValue'
,
v
:
boolean
)
(
e
:
'uploaded'
,
v
:
void
)
}
>
()
const
showDialog
=
computed
({
get
()
{
return
props
.
modelValue
},
set
(
val
)
{
emit
(
'update:modelValue'
,
val
)
}
})
const
uploading
=
ref
(
false
)
const
fileList
=
ref
<
UploadUserFile
[]
>
([])
const
uploadData
:
UploadData
=
reactive
({
type
:
MaterialType
.
Video
,
title
:
''
,
introduction
:
''
})
const
uploadFormRef
=
ref
<
FormInstance
>
()
const
uploadVideoRef
=
ref
<
UploadInstance
>
()
const
submitVideo
=
()
=>
{
uploadFormRef
.
value
?.
validate
((
valid
)
=>
{
if
(
!
valid
)
{
return
false
}
uploadVideoRef
.
value
?.
submit
()
})
}
const
handleUploadSuccess
:
UploadProps
[
'onSuccess'
]
=
(
res
:
any
)
=>
{
uploading
.
value
=
false
if
(
res
.
code
!==
0
)
{
message
.
error
(
'上传出错:'
+
res
.
msg
)
return
false
}
// 清空上传时的各种数据
fileList
.
value
=
[]
uploadData
.
title
=
''
uploadData
.
introduction
=
''
showDialog
.
value
=
false
message
.
notifySuccess
(
'上传成功'
)
emit
(
'uploaded'
)
}
</
script
>
<
style
scoped
></
style
>
src/views/mp/material/components/VideoTable.vue
0 → 100644
View file @
389c73d8
<
template
>
<el-table
:data=
"props.list"
stripe
border
v-loading=
"props.loading"
style=
"margin-top: 10px"
>
<el-table-column
label=
"编号"
align=
"center"
prop=
"mediaId"
/>
<el-table-column
label=
"文件名"
align=
"center"
prop=
"name"
/>
<el-table-column
label=
"标题"
align=
"center"
prop=
"title"
/>
<el-table-column
label=
"介绍"
align=
"center"
prop=
"introduction"
/>
<el-table-column
label=
"视频"
align=
"center"
>
<template
#
default=
"scope"
>
<WxVideoPlayer
v-if=
"scope.row.url"
:url=
"scope.row.url"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"上传时间"
align=
"center"
:formatter=
"dateFormatter"
prop=
"createTime"
width=
"180"
>
<
template
#
default=
"scope"
>
<span>
{{
scope
.
row
.
createTime
}}
</span>
</
template
>
</el-table-column>
<el-table-column
label=
"操作"
align=
"center"
fixed=
"right"
>
<
template
#
default=
"scope"
>
<el-button
type=
"primary"
link
@
click=
"handleDownload(scope.row.url)"
>
<Icon
icon=
"ep:download"
/>
下载
</el-button>
<el-button
type=
"primary"
link
@
click=
"emit('delete', scope.row.id)"
v-hasPermi=
"['mp:material:delete']"
>
<Icon
icon=
"ep:delete"
/>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
</template>
<
script
setup
lang=
"ts"
>
import
WxVideoPlayer
from
'@/views/mp/components/wx-video-play/main.vue'
import
{
dateFormatter
}
from
'@/utils/formatTime'
const
props
=
defineProps
<
{
list
:
any
[]
loading
:
boolean
}
>
()
const
emit
=
defineEmits
<
{
(
e
:
'delete'
,
v
:
number
)
(
e
:
'download'
,
v
:
string
)
}
>
()
// 下载文件
const
handleDownload
=
(
url
:
string
)
=>
{
window
.
open
(
url
,
'_blank'
)
}
</
script
>
<
style
scoped
></
style
>
src/views/mp/material/components/VoiceTable.vue
0 → 100644
View file @
389c73d8
<
template
>
<el-table
:data=
"props.list"
stripe
border
v-loading=
"props.loading"
style=
"margin-top: 10px"
>
<el-table-column
label=
"编号"
align=
"center"
prop=
"mediaId"
/>
<el-table-column
label=
"文件名"
align=
"center"
prop=
"name"
/>
<el-table-column
label=
"语音"
align=
"center"
>
<template
#
default=
"scope"
>
<WxVoicePlayer
v-if=
"scope.row.url"
:url=
"scope.row.url"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"上传时间"
align=
"center"
prop=
"createTime"
:formatter=
"dateFormatter"
width=
"180"
>
<
template
#
default=
"scope"
>
<span>
{{
scope
.
row
.
createTime
}}
</span>
</
template
>
</el-table-column>
<el-table-column
label=
"操作"
align=
"center"
class-name=
"small-padding fixed-width"
>
<
template
#
default=
"scope"
>
<el-button
type=
"primary"
link
@
click=
"emit('delete', scope.row.id)"
>
<Icon
icon=
"ep:download"
/>
下载
</el-button>
<el-button
type=
"primary"
link
@
click=
"emit('delete', scope.row.id)"
v-hasPermi=
"['mp:material:delete']"
>
<Icon
icon=
"ep:delete"
/>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
</template>
<
script
setup
lang=
"ts"
>
import
WxVoicePlayer
from
'@/views/mp/components/wx-voice-play/main.vue'
import
{
dateFormatter
}
from
'@/utils/formatTime'
const
props
=
defineProps
<
{
list
:
any
[]
loading
:
boolean
}
>
()
const
emit
=
defineEmits
<
{
(
e
:
'delete'
,
v
:
number
)
}
>
()
</
script
>
<
style
scoped
></
style
>
src/views/mp/material/components/Waterfall.vue
0 → 100644
View file @
389c73d8
<
template
>
<div
class=
"waterfall"
v-loading=
"props.loading"
>
<div
class=
"waterfall-item"
v-for=
"item in props.list"
:key=
"item.id"
>
<a
target=
"_blank"
:href=
"item.url"
>
<img
class=
"material-img"
:src=
"item.url"
/>
<div
class=
"item-name"
>
{{
item
.
name
}}
</div>
</a>
<el-row
justify=
"center"
>
<el-button
type=
"danger"
circle
@
click=
"emit('delete', item.id)"
v-hasPermi=
"['mp:material:delete']"
>
<Icon
icon=
"ep:delete"
/>
</el-button>
</el-row>
</div>
</div>
</
template
>
<
script
setup
lang=
"ts"
>
const
props
=
defineProps
<
{
list
:
any
[]
loading
:
boolean
}
>
()
const
emit
=
defineEmits
<
{
(
e
:
'delete'
,
v
:
number
)
}
>
()
</
script
>
<
style
lang=
"scss"
scoped
>
/*瀑布流样式*/
.waterfall
{
width
:
100%
;
column-gap
:
10px
;
column-count
:
5
;
margin-top
:
10px
;
/* 芋道源码:增加 10px,避免顶着上面 */
}
.waterfall-item
{
padding
:
10px
;
margin-bottom
:
10px
;
break-inside
:
avoid
;
border
:
1px
solid
#eaeaea
;
}
.material-img
{
width
:
100%
;
}
p
{
line-height
:
30px
;
}
@media
(
min-width
:
992px
)
and
(
max-width
:
1300px
)
{
.waterfall
{
column-count
:
3
;
}
p
{
color
:
red
;
}
}
@media
(
min-width
:
768px
)
and
(
max-width
:
991px
)
{
.waterfall
{
column-count
:
2
;
}
p
{
color
:
orange
;
}
}
@media
(
max-width
:
767px
)
{
.waterfall
{
column-count
:
1
;
}
}
</
style
>
src/views/mp/material/components/upload.ts
0 → 100644
View file @
389c73d8
import
type
{
UploadProps
,
UploadRawFile
}
from
'element-plus'
import
{
getAccessToken
}
from
'@/utils/auth'
const
message
=
useMessage
()
const
HEADERS
=
{
Authorization
:
'Bearer '
+
getAccessToken
()
}
const
UPLOAD_URL
=
'http://127.0.0.1:8000/upload/'
//import.meta.env.VITE_BASE_URL + '/admin-api/mp/material/upload-permanent'
enum
MaterialType
{
Image
=
'image'
,
Voice
=
'voice'
,
Video
=
'video'
}
interface
UploadData
{
type
:
MaterialType
title
:
string
introduction
:
string
}
const
beforeUpload
=
(
rawFile
:
UploadRawFile
,
materialType
:
MaterialType
):
boolean
=>
{
let
allowTypes
:
string
[]
=
[]
let
maxSizeMB
=
0
let
name
=
''
switch
(
materialType
)
{
case
MaterialType
.
Image
:
allowTypes
=
[
'image/jpeg'
,
'image/png'
,
'image/gif'
,
'image/bmp'
,
'image/jpg'
]
maxSizeMB
=
2
name
=
'图片'
break
case
MaterialType
.
Voice
:
allowTypes
=
[
'audio/mp3'
,
'audio/mpeg'
,
'audio/wma'
,
'audio/wav'
,
'audio/amr'
]
maxSizeMB
=
2
name
=
'图片'
break
case
MaterialType
.
Video
:
allowTypes
=
[
'video/mp4'
]
maxSizeMB
=
10
name
=
'视频'
}
if
(
!
allowTypes
.
includes
(
rawFile
.
type
))
{
message
.
error
(
`上传
${
name
}
格式不对!`
)
return
false
}
if
(
rawFile
.
size
/
1024
/
1024
>
maxSizeMB
)
{
message
.
error
(
`上传
${
name
}
大小不能超过
${
maxSizeMB
}
M!`
)
return
false
}
return
true
}
const
beforeImageUpload
:
UploadProps
[
'beforeUpload'
]
=
(
rawFile
:
UploadRawFile
)
=>
beforeUpload
(
rawFile
,
MaterialType
.
Image
)
const
beforeVoiceUpload
:
UploadProps
[
'beforeUpload'
]
=
(
rawFile
:
UploadRawFile
)
=>
beforeUpload
(
rawFile
,
MaterialType
.
Voice
)
const
beforeVideoUpload
:
UploadProps
[
'beforeUpload'
]
=
(
rawFile
:
UploadRawFile
)
=>
beforeUpload
(
rawFile
,
MaterialType
.
Video
)
export
{
HEADERS
,
UPLOAD_URL
,
MaterialType
,
UploadData
,
beforeImageUpload
,
beforeVoiceUpload
,
beforeVideoUpload
}
src/views/mp/material/index.vue
View file @
389c73d8
...
...
@@ -12,47 +12,18 @@
<ContentWrap>
<el-tabs
v-model=
"type"
@
tab-change=
"onTabChange"
>
<!-- tab 1:图片 -->
<el-tab-pane
name=
"i
mage"
>
<el-tab-pane
:name=
"MaterialType.I
mage"
>
<template
#
label
>
<span>
<Icon
icon=
"ep:picture"
/>
图片
</span>
</
template
>
<div
class=
"add_but"
v-hasPermi=
"['mp:material:upload-permanent']"
>
<el-upload
:action=
"uploadUrl"
:headers=
"headers"
multiple
:limit=
"1"
:file-list=
"fileList"
:data=
"uploadData"
:before-upload=
"beforeImageUpload"
:on-success=
"handleUploadSuccess"
>
<el-button
type=
"primary"
plain
>
点击上传
</el-button>
<
template
#
tip
>
<span
class=
"el-upload__tip"
style=
"margin-left: 5px"
>
支持 bmp/png/jpeg/jpg/gif 格式,大小不超过 2M
</span>
</
template
>
</el-upload>
</div>
<div
class=
"waterfall"
v-loading=
"loading"
>
<div
class=
"waterfall-item"
v-for=
"item in list"
:key=
"item.id"
>
<a
target=
"_blank"
:href=
"item.url"
>
<img
class=
"material-img"
:src=
"item.url"
/>
<div
class=
"item-name"
>
{{ item.name }}
</div>
</a>
<el-row
justify=
"center"
>
<el-button
type=
"danger"
circle
@
click=
"handleDelete(item)"
v-hasPermi=
"['mp:material:delete']"
>
<Icon
icon=
"ep:delete"
/>
</el-button>
</el-row>
</div>
</div>
<Upload
v-hasPermi=
"['mp:material:upload-permanent']"
:type=
"MaterialType.Image"
@
uploaded=
"getList"
>
支持 bmp/png/jpeg/jpg/gif 格式,大小不超过 2M
</Upload>
<Waterfall
:loading=
"loading"
:list=
"list"
@
delete=
"handleDelete"
/>
<!-- 分页组件 -->
<Pagination
:total=
"total"
...
...
@@ -63,67 +34,20 @@
</el-tab-pane>
<!-- tab 2:语音 -->
<el-tab-pane
name=
"v
oice"
>
<el-tab-pane
:name=
"MaterialType.V
oice"
>
<
template
#
label
>
<span>
<Icon
icon=
"ep:microphone"
/>
语音
</span>
</
template
>
<div
class=
"add_but"
v-hasPermi=
"['mp:material:upload-permanent']"
>
<el-upload
:action=
"uploadUrl"
:headers=
"headers"
multiple
:limit=
"1"
:file-list=
"fileList"
:data=
"uploadData"
:on-success=
"handleUploadSuccess"
:before-upload=
"beforeVoiceUpload"
>
<el-button
type=
"primary"
plain
>
点击上传
</el-button>
<
template
#
tip
>
<span
class=
"el-upload__tip"
style=
"margin-left: 5px"
>
格式支持 mp3/wma/wav/amr,文件大小不超过 2M,播放长度不超过 60s
</span>
</
template
>
</el-upload>
</div>
<Upload
v-hasPermi=
"['mp:material:upload-permanent']"
:type=
"MaterialType.Voice"
@
uploaded=
"getList"
>
格式支持 mp3/wma/wav/amr,文件大小不超过 2M,播放长度不超过 60s
</Upload>
<!-- 列表 -->
<el-table
:data=
"list"
stripe
border
v-loading=
"loading"
style=
"margin-top: 10px"
>
<el-table-column
label=
"编号"
align=
"center"
prop=
"mediaId"
/>
<el-table-column
label=
"文件名"
align=
"center"
prop=
"name"
/>
<el-table-column
label=
"语音"
align=
"center"
>
<
template
#
default=
"scope"
>
<WxVoicePlayer
v-if=
"scope.row.url"
:url=
"scope.row.url"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"上传时间"
align=
"center"
prop=
"createTime"
:formatter=
"dateFormatter"
width=
"180"
>
<
template
#
default=
"scope"
>
<span>
{{
scope
.
row
.
createTime
}}
</span>
</
template
>
</el-table-column>
<el-table-column
label=
"操作"
align=
"center"
class-name=
"small-padding fixed-width"
>
<
template
#
default=
"scope"
>
<el-button
type=
"primary"
link
plain
@
click=
"handleDownload(scope.row)"
>
<Icon
icon=
"ep:download"
/>
下载
</el-button>
<el-button
type=
"primary"
link
plain
@
click=
"handleDelete(scope.row)"
v-hasPermi=
"['mp:material:delete']"
>
<Icon
icon=
"ep:delete"
/>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
<VoiceTable
:list=
"list"
:loading=
"loading"
@
delete=
"handleDelete"
/>
<!-- 分页组件 -->
<Pagination
:total=
"total"
...
...
@@ -134,105 +58,22 @@
</el-tab-pane>
<!-- tab 3:视频 -->
<el-tab-pane
name=
"v
ideo"
>
<el-tab-pane
:name=
"MaterialType.V
ideo"
>
<
template
#
label
>
<span>
<Icon
icon=
"ep:video-play"
/>
视频
</span>
</
template
>
<div
class=
"add_but"
v-hasPermi=
"['mp:material:upload-permanent']"
>
<el-button
type=
"primary"
plain
@
click=
"handleAddVideo"
>
新建视频
</el-button>
</div>
<!-- 新建视频的弹窗 -->
<el-dialog
title=
"新建视频"
v-model=
"dialogVideoVisible"
width=
"600px"
v-loading=
"addMaterialLoading"
<el-button
v-hasPermi=
"['mp:material:upload-permanent']"
type=
"primary"
plain
@
click=
"showCreateVideo = true"
>
新建视频
</el-button
>
<el-upload
:action=
"uploadUrl"
:headers=
"headers"
multiple
:limit=
"1"
:file-list=
"fileList"
:data=
"uploadData"
:before-upload=
"beforeVideoUpload"
:on-success=
"handleUploadSuccess"
ref=
"uploadVideoRef"
:auto-upload=
"false"
>
<
template
#
trigger
>
<el-button
size=
"small"
type=
"primary"
>
选择视频
</el-button>
</
template
>
<span
class=
"el-upload__tip"
style=
"margin-left: 10px"
>
格式支持 MP4,文件大小不超过 10MB
</span
>
</el-upload>
<el-form
:model=
"uploadData"
:rules=
"uploadRules"
ref=
"uploadFormRef"
label-width=
"80px"
>
<el-row>
<el-form-item
label=
"标题"
prop=
"title"
>
<el-input
v-model=
"uploadData.title"
placeholder=
"标题将展示在相关播放页面,建议填写清晰、准确、生动的标题"
/>
</el-form-item>
</el-row>
<el-row>
<el-form-item
label=
"描述"
prop=
"introduction"
>
<el-input
:rows=
"3"
type=
"textarea"
v-model=
"uploadData.introduction"
placeholder=
"介绍语将展示在相关播放页面,建议填写简洁明确、有信息量的内容"
/>
</el-form-item>
</el-row>
</el-form>
<
template
#
footer
>
<el-button
@
click=
"cancelVideo"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"submitVideo"
>
提 交
</el-button>
</
template
>
</el-dialog>
<!-- 新建视频的弹窗 -->
<UploadVideo
v-model=
"showCreateVideo"
/>
<!-- 列表 -->
<el-table
:data=
"list"
stripe
border
v-loading=
"loading"
style=
"margin-top: 10px"
>
<el-table-column
label=
"编号"
align=
"center"
prop=
"mediaId"
/>
<el-table-column
label=
"文件名"
align=
"center"
prop=
"name"
/>
<el-table-column
label=
"标题"
align=
"center"
prop=
"title"
/>
<el-table-column
label=
"介绍"
align=
"center"
prop=
"introduction"
/>
<el-table-column
label=
"视频"
align=
"center"
>
<
template
#
default=
"scope"
>
<WxVideoPlayer
v-if=
"scope.row.url"
:url=
"scope.row.url"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"上传时间"
align=
"center"
:formatter=
"dateFormatter"
prop=
"createTime"
width=
"180"
>
<
template
#
default=
"scope"
>
<span>
{{
scope
.
row
.
createTime
}}
</span>
</
template
>
</el-table-column>
<el-table-column
label=
"操作"
align=
"center"
fixed=
"right"
>
<
template
#
default=
"scope"
>
<el-button
type=
"primary"
link
plain
@
click=
"handleDownload(scope.row)"
>
<Icon
icon=
"ep:download"
/>
下载
</el-button>
<el-button
type=
"primary"
link
size=
"small"
plain
@
click=
"handleDelete(scope.row)"
v-hasPermi=
"['mp:material:delete']"
>
<Icon
icon=
"ep:delete"
/>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
<VideoTable
:list=
"list"
:loading=
"loading"
@
delete=
"handleDelete"
/>
<!-- 分页组件 -->
<Pagination
:total=
"total"
...
...
@@ -246,39 +87,19 @@
</template>
<
script
lang=
"ts"
setup
name=
"MpMaterial"
>
import
WxVoicePlayer
from
'@/views/mp/components/wx-voice-play/main.vue'
import
WxVideoPlayer
from
'@/views/mp/components/wx-video-play/main.vue'
import
WxAccountSelect
from
'@/views/mp/components/wx-account-select/main.vue'
import
Waterfall
from
'./components/Waterfall.vue'
import
VoiceTable
from
'./components/VoiceTable.vue'
import
VideoTable
from
'./components/VideoTable.vue'
import
Upload
from
'./components/Upload.vue'
import
UploadVideo
from
'./components/UploadVideo.vue'
import
{
MaterialType
}
from
'./components/upload'
import
*
as
MpMaterialApi
from
'@/api/mp/material'
import
*
as
authUtil
from
'@/utils/auth'
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
type
{
FormInstance
,
FormRules
,
TabPaneName
,
UploadInstance
,
UploadProps
,
UploadRawFile
,
UploadUserFile
}
from
'element-plus'
const
BASE_URL
=
import
.
meta
.
env
.
VITE_BASE_URL
const
uploadUrl
=
BASE_URL
+
'/admin-api/mp/material/upload-permanent'
const
headers
=
{
Authorization
:
'Bearer '
+
authUtil
.
getAccessToken
()
}
const
message
=
useMessage
()
const
uploadFormRef
=
ref
<
FormInstance
>
()
const
uploadVideoRef
=
ref
<
UploadInstance
>
()
const
uploadRules
:
FormRules
=
{
title
:
[{
required
:
true
,
message
:
'请输入标题'
,
trigger
:
'blur'
}],
introduction
:
[{
required
:
true
,
message
:
'请输入描述'
,
trigger
:
'blur'
}]
}
// 素材类型
type
MaterialType
=
'image'
|
'voice'
|
'video'
const
type
=
ref
<
MaterialType
>
(
'image'
)
const
type
=
ref
<
MaterialType
>
(
MaterialType
.
Image
)
const
loading
=
ref
(
false
)
// 遮罩层
const
list
=
ref
<
any
[]
>
([])
// 总条数
const
total
=
ref
(
0
)
// 数据列表
...
...
@@ -296,22 +117,8 @@ const queryParams: QueryParams = reactive({
permanent
:
true
})
const
fileList
=
ref
<
UploadUserFile
[]
>
([])
interface
UploadData
{
type
:
MaterialType
title
:
string
introduction
:
string
}
const
uploadData
:
UploadData
=
reactive
({
type
:
'image'
,
title
:
''
,
introduction
:
''
})
// === 视频上传,独有变量 ===
const
dialogVideoVisible
=
ref
(
false
)
const
addMaterialLoading
=
ref
(
false
)
const
showCreateVideo
=
ref
(
false
)
/** 侦听公众号变化 **/
const
onAccountChanged
=
(
id
?:
number
)
=>
{
...
...
@@ -341,10 +148,7 @@ const handleQuery = () => {
getList
()
}
const
onTabChange
=
(
tabName
:
TabPaneName
)
=>
{
// 设置 type
uploadData
.
type
=
tabName
as
MaterialType
const
onTabChange
=
()
=>
{
// 提前情况数据,避免tab切换后显示垃圾数据
list
.
value
=
[]
total
.
value
=
0
...
...
@@ -353,160 +157,12 @@ const onTabChange = (tabName: TabPaneName) => {
handleQuery
()
}
// ======================== 文件上传 ========================
const
beforeUpload
=
(
rawFile
:
UploadRawFile
,
category
:
'image'
|
'audio'
|
'video'
):
boolean
=>
{
let
allowTypes
:
string
[]
=
[]
let
maxSizeMB
=
0
let
name
=
''
switch
(
category
)
{
case
'image'
:
allowTypes
=
[
'image/jpeg'
,
'image/png'
,
'image/gif'
,
'image/bmp'
,
'image/jpg'
]
maxSizeMB
=
2
name
=
'图片'
break
case
'audio'
:
allowTypes
=
[
'audio/mp3'
,
'audio/mpeg'
,
'audio/wma'
,
'audio/wav'
,
'audio/amr'
]
maxSizeMB
=
2
name
=
'图片'
break
case
'video'
:
allowTypes
=
[
'video/mp4'
]
maxSizeMB
=
10
name
=
'视频'
}
if
(
!
allowTypes
.
includes
(
rawFile
.
type
))
{
message
.
error
(
`上传
${
name
}
格式不对!`
)
return
false
}
// 校验大小
if
(
rawFile
.
size
/
1024
/
1024
>
maxSizeMB
)
{
message
.
error
(
`上传
${
name
}
大小不能超过
${
maxSizeMB
}
M!`
)
return
false
}
loading
.
value
=
true
return
true
}
const
beforeImageUpload
:
UploadProps
[
'beforeUpload'
]
=
(
rawFile
:
UploadRawFile
)
=>
beforeUpload
(
rawFile
,
'image'
)
const
beforeVoiceUpload
:
UploadProps
[
'beforeUpload'
]
=
(
rawFile
:
UploadRawFile
)
=>
beforeUpload
(
rawFile
,
'audio'
)
const
beforeVideoUpload
:
UploadProps
[
'beforeUpload'
]
=
(
rawFile
:
UploadRawFile
)
=>
beforeUpload
(
rawFile
,
'video'
)
const
handleUploadSuccess
:
UploadProps
[
'onSuccess'
]
=
(
response
:
any
)
=>
{
loading
.
value
=
false
addMaterialLoading
.
value
=
false
if
(
response
.
code
!==
0
)
{
message
.
error
(
'上传出错:'
+
response
.
msg
)
return
false
}
// 清空上传时的各种数据
dialogVideoVisible
.
value
=
false
fileList
.
value
=
[]
uploadData
.
title
=
''
uploadData
.
introduction
=
''
// 加载数据
getList
()
}
// 下载文件
const
handleDownload
=
(
row
:
any
)
=>
{
window
.
open
(
row
.
url
,
'_blank'
)
}
// 提交 video 新建的表单
const
submitVideo
=
()
=>
{
uploadFormRef
.
value
?.
validate
((
valid
)
=>
{
if
(
!
valid
)
{
return
false
}
uploadVideoRef
.
value
?.
submit
()
})
}
// 弹出 video 新建的表单
const
handleAddVideo
=
()
=>
{
resetVideo
()
dialogVideoVisible
.
value
=
true
}
/** 取消按钮 */
const
cancelVideo
=
()
=>
{
dialogVideoVisible
.
value
=
false
resetVideo
()
}
/** 表单重置 */
const
resetVideo
=
()
=>
{
fileList
.
value
=
[]
uploadData
.
title
=
''
uploadData
.
introduction
=
''
uploadFormRef
.
value
?.
resetFields
()
}
// ======================== 其它操作 ========================
const
handleDelete
=
async
(
i
tem
:
any
)
=>
{
const
handleDelete
=
async
(
i
d
:
number
)
=>
{
await
message
.
confirm
(
'此操作将永久删除该文件, 是否继续?'
)
await
MpMaterialApi
.
deletePermanentMaterial
(
i
tem
.
i
d
)
await
MpMaterialApi
.
deletePermanentMaterial
(
id
)
message
.
alertSuccess
(
'删除成功'
)
}
</
script
>
<
style
lang=
"scss"
scoped
>
/*瀑布流样式*/
.waterfall
{
width
:
100%
;
column-gap
:
10px
;
column-count
:
5
;
margin-top
:
10px
;
/* 芋道源码:增加 10px,避免顶着上面 */
}
.waterfall-item
{
padding
:
10px
;
margin-bottom
:
10px
;
break-inside
:
avoid
;
border
:
1px
solid
#eaeaea
;
}
.material-img
{
width
:
100%
;
}
p
{
line-height
:
30px
;
}
@media
(
min-width
:
992px
)
and
(
max-width
:
1300px
)
{
.waterfall
{
column-count
:
3
;
}
p
{
color
:
red
;
}
}
@media
(
min-width
:
768px
)
and
(
max-width
:
991px
)
{
.waterfall
{
column-count
:
2
;
}
p
{
color
:
orange
;
}
}
@media
(
max-width
:
767px
)
{
.waterfall
{
column-count
:
1
;
}
}
</
style
>
<
style
lang=
"scss"
scoped
></
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