Skip to content

Commit 71fd9af

Browse files
YunaiVgitee-org
authored andcommitted
!126 refactor: MP模块组件拆分
Merge pull request !126 from dhb52/dev
2 parents f59e4a4 + 389c73d commit 71fd9af

File tree

7 files changed

+507
-384
lines changed

7 files changed

+507
-384
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<template>
2+
<el-upload
3+
:action="UPLOAD_URL"
4+
:headers="HEADERS"
5+
multiple
6+
:limit="1"
7+
:file-list="fileList"
8+
:data="uploadData"
9+
:on-progress="() => (uploading = true)"
10+
:before-upload="beforeUpload"
11+
:on-success="handleUploadSuccess"
12+
>
13+
<el-button type="primary" plain :loading="uploading" :disabled="uploading">
14+
{{ uploading ? '正在上传' : '点击上传' }}
15+
</el-button>
16+
<template #tip>
17+
<span class="el-upload__tip" style="margin-left: 5px">
18+
<slot></slot>
19+
</span>
20+
</template>
21+
</el-upload>
22+
</template>
23+
24+
<script setup lang="ts">
25+
import type { UploadProps, UploadUserFile } from 'element-plus'
26+
import {
27+
HEADERS,
28+
UPLOAD_URL,
29+
UploadData,
30+
MaterialType,
31+
beforeImageUpload,
32+
beforeVoiceUpload
33+
} from './upload'
34+
35+
const message = useMessage()
36+
37+
const props = defineProps<{ type: boolean }>()
38+
39+
const fileList = ref<UploadUserFile[]>([])
40+
const emit = defineEmits<{
41+
(e: 'uploaded', v: void)
42+
}>()
43+
44+
const uploadData: UploadData = reactive({
45+
type: MaterialType.Image,
46+
title: '',
47+
introduction: ''
48+
})
49+
const uploading = ref(false)
50+
51+
const beforeUpload = props.type == MaterialType.Image ? beforeImageUpload : beforeVoiceUpload
52+
53+
const handleUploadSuccess: UploadProps['onSuccess'] = (res: any) => {
54+
if (res.code !== 0) {
55+
message.alertError('上传出错:' + res.msg)
56+
return false
57+
}
58+
59+
// 清空上传时的各种数据
60+
fileList.value = []
61+
uploadData.title = ''
62+
uploadData.introduction = ''
63+
64+
message.notifySuccess('上传成功')
65+
uploading.value = false
66+
emit('uploaded')
67+
}
68+
</script>
69+
70+
<style scoped></style>
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<template>
2+
<el-dialog title="新建视频" v-model="showDialog" width="600px" destroy-on-close>
3+
<el-upload
4+
:action="UPLOAD_URL"
5+
:headers="HEADERS"
6+
multiple
7+
:limit="1"
8+
:file-list="fileList"
9+
:data="uploadData"
10+
:before-upload="beforeVideoUpload"
11+
:on-progress="() => (uploading = true)"
12+
:on-success="handleUploadSuccess"
13+
ref="uploadVideoRef"
14+
:auto-upload="false"
15+
class="mb-5"
16+
>
17+
<template #trigger>
18+
<el-button type="primary" plain>选择视频</el-button>
19+
</template>
20+
<span class="el-upload__tip" style="margin-left: 10px"
21+
>格式支持 MP4,文件大小不超过 10MB</span
22+
>
23+
</el-upload>
24+
<el-divider />
25+
<el-form :model="uploadData" :rules="uploadRules" ref="uploadFormRef" v-loading="uploading">
26+
<el-form-item label="标题" prop="title">
27+
<el-input
28+
v-model="uploadData.title"
29+
placeholder="标题将展示在相关播放页面,建议填写清晰、准确、生动的标题"
30+
/>
31+
</el-form-item>
32+
<el-form-item label="描述" prop="introduction">
33+
<el-input
34+
:rows="3"
35+
type="textarea"
36+
v-model="uploadData.introduction"
37+
placeholder="介绍语将展示在相关播放页面,建议填写简洁明确、有信息量的内容"
38+
/>
39+
</el-form-item>
40+
</el-form>
41+
<template #footer>
42+
<el-button @click="showDialog = false">取 消</el-button>
43+
<el-button type="primary" @click="submitVideo" :loading="uploading" :disabled="uploading"
44+
>提 交</el-button
45+
>
46+
</template>
47+
</el-dialog>
48+
</template>
49+
50+
<script setup lang="ts">
51+
import type {
52+
FormInstance,
53+
FormRules,
54+
UploadInstance,
55+
UploadProps,
56+
UploadUserFile
57+
} from 'element-plus'
58+
import { HEADERS, UploadData, UPLOAD_URL, beforeVideoUpload, MaterialType } from './upload'
59+
60+
const message = useMessage()
61+
62+
const uploadRules: FormRules = {
63+
title: [{ required: true, message: '请输入标题', trigger: 'blur' }],
64+
introduction: [{ required: true, message: '请输入描述', trigger: 'blur' }]
65+
}
66+
67+
const props = defineProps({
68+
modelValue: {
69+
type: Boolean,
70+
default: false
71+
}
72+
})
73+
const emit = defineEmits<{
74+
(e: 'update:modelValue', v: boolean)
75+
(e: 'uploaded', v: void)
76+
}>()
77+
78+
const showDialog = computed({
79+
get() {
80+
return props.modelValue
81+
},
82+
set(val) {
83+
emit('update:modelValue', val)
84+
}
85+
})
86+
87+
const uploading = ref(false)
88+
89+
const fileList = ref<UploadUserFile[]>([])
90+
91+
const uploadData: UploadData = reactive({
92+
type: MaterialType.Video,
93+
title: '',
94+
introduction: ''
95+
})
96+
97+
const uploadFormRef = ref<FormInstance>()
98+
const uploadVideoRef = ref<UploadInstance>()
99+
100+
const submitVideo = () => {
101+
uploadFormRef.value?.validate((valid) => {
102+
if (!valid) {
103+
return false
104+
}
105+
uploadVideoRef.value?.submit()
106+
})
107+
}
108+
109+
const handleUploadSuccess: UploadProps['onSuccess'] = (res: any) => {
110+
uploading.value = false
111+
if (res.code !== 0) {
112+
message.error('上传出错:' + res.msg)
113+
return false
114+
}
115+
116+
// 清空上传时的各种数据
117+
fileList.value = []
118+
uploadData.title = ''
119+
uploadData.introduction = ''
120+
121+
showDialog.value = false
122+
message.notifySuccess('上传成功')
123+
emit('uploaded')
124+
}
125+
</script>
126+
127+
<style scoped></style>
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<template>
2+
<el-table :data="props.list" stripe border v-loading="props.loading" style="margin-top: 10px">
3+
<el-table-column label="编号" align="center" prop="mediaId" />
4+
<el-table-column label="文件名" align="center" prop="name" />
5+
<el-table-column label="标题" align="center" prop="title" />
6+
<el-table-column label="介绍" align="center" prop="introduction" />
7+
<el-table-column label="视频" align="center">
8+
<template #default="scope">
9+
<WxVideoPlayer v-if="scope.row.url" :url="scope.row.url" />
10+
</template>
11+
</el-table-column>
12+
<el-table-column
13+
label="上传时间"
14+
align="center"
15+
:formatter="dateFormatter"
16+
prop="createTime"
17+
width="180"
18+
>
19+
<template #default="scope">
20+
<span>{{ scope.row.createTime }}</span>
21+
</template>
22+
</el-table-column>
23+
<el-table-column label="操作" align="center" fixed="right">
24+
<template #default="scope">
25+
<el-button type="primary" link @click="handleDownload(scope.row.url)">
26+
<Icon icon="ep:download" />下载
27+
</el-button>
28+
<el-button
29+
type="primary"
30+
link
31+
@click="emit('delete', scope.row.id)"
32+
v-hasPermi="['mp:material:delete']"
33+
>
34+
<Icon icon="ep:delete" />删除
35+
</el-button>
36+
</template>
37+
</el-table-column>
38+
</el-table>
39+
</template>
40+
41+
<script setup lang="ts">
42+
import WxVideoPlayer from '@/views/mp/components/wx-video-play/main.vue'
43+
import { dateFormatter } from '@/utils/formatTime'
44+
45+
const props = defineProps<{
46+
list: any[]
47+
loading: boolean
48+
}>()
49+
50+
const emit = defineEmits<{
51+
(e: 'delete', v: number)
52+
(e: 'download', v: string)
53+
}>()
54+
55+
// 下载文件
56+
const handleDownload = (url: string) => {
57+
window.open(url, '_blank')
58+
}
59+
</script>
60+
61+
<style scoped></style>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<template>
2+
<el-table :data="props.list" stripe border v-loading="props.loading" style="margin-top: 10px">
3+
<el-table-column label="编号" align="center" prop="mediaId" />
4+
<el-table-column label="文件名" align="center" prop="name" />
5+
<el-table-column label="语音" align="center">
6+
<template #default="scope">
7+
<WxVoicePlayer v-if="scope.row.url" :url="scope.row.url" />
8+
</template>
9+
</el-table-column>
10+
<el-table-column
11+
label="上传时间"
12+
align="center"
13+
prop="createTime"
14+
:formatter="dateFormatter"
15+
width="180"
16+
>
17+
<template #default="scope">
18+
<span>{{ scope.row.createTime }}</span>
19+
</template>
20+
</el-table-column>
21+
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
22+
<template #default="scope">
23+
<el-button type="primary" link @click="emit('delete', scope.row.id)">
24+
<Icon icon="ep:download" />下载
25+
</el-button>
26+
<el-button
27+
type="primary"
28+
link
29+
@click="emit('delete', scope.row.id)"
30+
v-hasPermi="['mp:material:delete']"
31+
>
32+
<Icon icon="ep:delete" />删除
33+
</el-button>
34+
</template>
35+
</el-table-column>
36+
</el-table>
37+
</template>
38+
39+
<script setup lang="ts">
40+
import WxVoicePlayer from '@/views/mp/components/wx-voice-play/main.vue'
41+
import { dateFormatter } from '@/utils/formatTime'
42+
43+
const props = defineProps<{
44+
list: any[]
45+
loading: boolean
46+
}>()
47+
48+
const emit = defineEmits<{
49+
(e: 'delete', v: number)
50+
}>()
51+
</script>
52+
53+
<style scoped></style>
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<template>
2+
<div class="waterfall" v-loading="props.loading">
3+
<div class="waterfall-item" v-for="item in props.list" :key="item.id">
4+
<a target="_blank" :href="item.url">
5+
<img class="material-img" :src="item.url" />
6+
<div class="item-name">{{ item.name }}</div>
7+
</a>
8+
<el-row justify="center">
9+
<el-button
10+
type="danger"
11+
circle
12+
@click="emit('delete', item.id)"
13+
v-hasPermi="['mp:material:delete']"
14+
>
15+
<Icon icon="ep:delete" />
16+
</el-button>
17+
</el-row>
18+
</div>
19+
</div>
20+
</template>
21+
22+
<script setup lang="ts">
23+
const props = defineProps<{
24+
list: any[]
25+
loading: boolean
26+
}>()
27+
28+
const emit = defineEmits<{
29+
(e: 'delete', v: number)
30+
}>()
31+
</script>
32+
33+
<style lang="scss" scoped>
34+
/*瀑布流样式*/
35+
.waterfall {
36+
width: 100%;
37+
column-gap: 10px;
38+
column-count: 5;
39+
margin-top: 10px;
40+
/* 芋道源码:增加 10px,避免顶着上面 */
41+
}
42+
43+
.waterfall-item {
44+
padding: 10px;
45+
margin-bottom: 10px;
46+
break-inside: avoid;
47+
border: 1px solid #eaeaea;
48+
}
49+
50+
.material-img {
51+
width: 100%;
52+
}
53+
54+
p {
55+
line-height: 30px;
56+
}
57+
58+
@media (min-width: 992px) and (max-width: 1300px) {
59+
.waterfall {
60+
column-count: 3;
61+
}
62+
63+
p {
64+
color: red;
65+
}
66+
}
67+
68+
@media (min-width: 768px) and (max-width: 991px) {
69+
.waterfall {
70+
column-count: 2;
71+
}
72+
73+
p {
74+
color: orange;
75+
}
76+
}
77+
78+
@media (max-width: 767px) {
79+
.waterfall {
80+
column-count: 1;
81+
}
82+
}
83+
</style>

0 commit comments

Comments
 (0)