Showing
7 changed files
with
215 additions
and
17 deletions
src/components/MuiVideo/banner.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div | ||
| 3 | + @click="goToDetail(item, $router)" | ||
| 4 | + class="banner"> | ||
| 5 | + {{ item.kg_name }} | {{ item.localism_type }} | ||
| 6 | + </div> | ||
| 7 | +</template> | ||
| 8 | + | ||
| 9 | +<script setup> | ||
| 10 | +import { goToDetail } from './methods' | ||
| 11 | +const props = defineProps({ | ||
| 12 | + item: Object, | ||
| 13 | +}); | ||
| 14 | +</script> | ||
| 15 | + | ||
| 16 | +<style lang="less" scoped> | ||
| 17 | + .banner { | ||
| 18 | + color: #999999; | ||
| 19 | + padding: 0.5rem 1rem | ||
| 20 | + } | ||
| 21 | +</style> |
| 1 | <template> | 1 | <template> |
| 2 | <div class="video-wrapper"> | 2 | <div class="video-wrapper"> |
| 3 | - <div | 3 | + <status :item="item"></status> |
| 4 | - class="video-div" | 4 | + <div class="video-div" :id="'mui-player-' + item.id"></div> |
| 5 | - :id="'mui-player-' + item.id" | 5 | + <video-bar :item="item" :barType="1"></video-bar> |
| 6 | - ></div> | 6 | + <banner v-if="type === 'bookDetail'" :item="item"></banner> |
| 7 | </div> | 7 | </div> |
| 8 | </template> | 8 | </template> |
| 9 | 9 | ||
| 10 | <script setup> | 10 | <script setup> |
| 11 | - /** | 11 | +/** |
| 12 | * 视频组件通用模块 | 12 | * 视频组件通用模块 |
| 13 | */ | 13 | */ |
| 14 | - import 'mui-player/dist/mui-player.min.css'; | 14 | +import 'mui-player/dist/mui-player.min.css'; |
| 15 | - import MuiPlayer from 'mui-player'; | 15 | +import MuiPlayer from 'mui-player'; |
| 16 | - import { onMounted } from 'vue'; | 16 | +import { onMounted } from 'vue'; |
| 17 | - // 视频基础属性 | 17 | +import banner from './banner'; |
| 18 | - const props = defineProps({ | 18 | +import videoBar from './videoBar'; |
| 19 | +import status from './status'; | ||
| 20 | +// 视频基础属性 | ||
| 21 | +const props = defineProps({ | ||
| 19 | item: Object, | 22 | item: Object, |
| 20 | - }); | 23 | + type: String, |
| 21 | - // 视频播放事件回调 | 24 | +}); |
| 22 | - const emit = defineEmits(['on-play']); | 25 | +// 视频播放事件回调 |
| 26 | +const emit = defineEmits(['on-play']); | ||
| 23 | 27 | ||
| 24 | - onMounted(() => { | 28 | +onMounted(() => { |
| 25 | const mp = new MuiPlayer({ | 29 | const mp = new MuiPlayer({ |
| 26 | container: '#mui-player-' + props.item.id, | 30 | container: '#mui-player-' + props.item.id, |
| 27 | title: props.item.title, | 31 | title: props.item.title, |
| ... | @@ -44,11 +48,12 @@ | ... | @@ -44,11 +48,12 @@ |
| 44 | props: props.item, | 48 | props: props.item, |
| 45 | }); | 49 | }); |
| 46 | }); | 50 | }); |
| 47 | - }); | 51 | +}); |
| 48 | </script> | 52 | </script> |
| 49 | 53 | ||
| 50 | -<style lang="less" scoped> | 54 | +<style lang="less" scoped > |
| 51 | - .video-wrapper { | 55 | +.video-wrapper { |
| 56 | + position: relative; | ||
| 52 | margin: 1rem; | 57 | margin: 1rem; |
| 53 | border-bottom-left-radius: 5px; | 58 | border-bottom-left-radius: 5px; |
| 54 | border-bottom-right-radius: 5px; | 59 | border-bottom-right-radius: 5px; |
| ... | @@ -58,5 +63,12 @@ | ... | @@ -58,5 +63,12 @@ |
| 58 | border-top-left-radius: 5px; | 63 | border-top-left-radius: 5px; |
| 59 | border-top-right-radius: 5px; | 64 | border-top-right-radius: 5px; |
| 60 | } | 65 | } |
| 66 | + | ||
| 67 | + .video-bar { | ||
| 68 | + color: #713610; | ||
| 69 | + padding: 1rem; | ||
| 70 | + padding-bottom: 0.5rem; | ||
| 71 | + | ||
| 61 | } | 72 | } |
| 73 | +} | ||
| 62 | </style> | 74 | </style> | ... | ... |
src/components/MuiVideo/methods.js
0 → 100644
| 1 | +import { prodActionAPI } from '@/api/C/prod.js' | ||
| 2 | +import { Toast } from 'vant'; | ||
| 3 | + | ||
| 4 | +export const goToDetail = ({ id, book_id, type }, $router) => { | ||
| 5 | + $router.push({ | ||
| 6 | + path: '/client/videoDetail', | ||
| 7 | + query: { | ||
| 8 | + prod_id: id, | ||
| 9 | + book_id, | ||
| 10 | + type // 特殊标识,判断入口 为keepAlive使用 | ||
| 11 | + } | ||
| 12 | + }); | ||
| 13 | +} | ||
| 14 | + | ||
| 15 | +export const setComment = ({ id, book_id }, $router) => { | ||
| 16 | + $router.push({ | ||
| 17 | + path: '/client/videoDetail/comment', | ||
| 18 | + query: { | ||
| 19 | + prod_id: id, | ||
| 20 | + book_id | ||
| 21 | + } | ||
| 22 | + }); | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +export const prodAction = async (action_type, prod_id) => { | ||
| 26 | + const { msg } = await prodActionAPI({ action_type, prod_id }); | ||
| 27 | + if (msg === `${action_type}-add-OK`) { // 动作操作成功 | ||
| 28 | + if (action_type === 'favor') { | ||
| 29 | + Toast('收藏成功'); | ||
| 30 | + } | ||
| 31 | + if (action_type === 'like') { | ||
| 32 | + Toast('点赞成功'); | ||
| 33 | + } | ||
| 34 | + } else { // 取消操作 | ||
| 35 | + if (action_type !== 'play') { | ||
| 36 | + Toast('取消成功'); | ||
| 37 | + } | ||
| 38 | + } | ||
| 39 | + return true; | ||
| 40 | +} |
This diff is collapsed. Click to expand it.
src/components/MuiVideo/status.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="status"> | ||
| 3 | + <van-image v-if="item.status === 'enable'" round width="6rem" height="6rem" style="vertical-align: bottom;" :src="icon_enable" /> | ||
| 4 | + <van-image v-if="item.status === 'disable'" round width="6rem" height="6rem" style="vertical-align: bottom;" :src="icon_refuse" /> | ||
| 5 | + <van-image v-if="item.status === 'apply'" round width="6rem" height="6rem" style="vertical-align: bottom;" :src="icon_apply" /> | ||
| 6 | + </div> | ||
| 7 | +</template> | ||
| 8 | + | ||
| 9 | +<script setup> | ||
| 10 | +import icon_refuse from '@images/icon-jujue@2x.png' | ||
| 11 | +import icon_apply from '@images/icon-shenhe@2x.png' | ||
| 12 | +import icon_enable from '@images/icon-tongguo@2x.png' | ||
| 13 | + | ||
| 14 | +const props = defineProps({ | ||
| 15 | + item: Object, | ||
| 16 | +}); | ||
| 17 | +</script> | ||
| 18 | + | ||
| 19 | +<style lang="less" scoped> | ||
| 20 | +.status { | ||
| 21 | + position: absolute; | ||
| 22 | + top: 0; | ||
| 23 | + right: 0; | ||
| 24 | + z-index: 999; | ||
| 25 | +} | ||
| 26 | +</style> |
src/components/MuiVideo/videoBar.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div v-if="barType === 1" class="video-bar"> | ||
| 3 | + <van-row> | ||
| 4 | + <van-col span="12" @click="goToDetail(item, $router)"> | ||
| 5 | + <van-image v-if="item.avatar" round width="2rem" height="2rem" style="vertical-align: middle;" | ||
| 6 | + :src="item.avatar" /> | ||
| 7 | + <van-image v-else round width="2rem" height="2rem" style="vertical-align: middle;" :src="icon_avatar" /> | ||
| 8 | + <span style="font-size: 1.05rem;vertical-align: middle;">{{ item.name }}</span> | ||
| 9 | + </van-col> | ||
| 10 | + <van-col span="12"> | ||
| 11 | + <div style="padding: 0.25rem; padding-top: 0.75rem; text-align: right;"> | ||
| 12 | + <span @click="setComment(item, $router)"> | ||
| 13 | + <van-icon :name="icon_liuyan" size="1.2rem" style="vertical-align: bottom;" /> | ||
| 14 | + {{ item.comment_num }} | ||
| 15 | + </span> | ||
| 16 | + | ||
| 17 | + <span @click="handleAction('like', detail.id)"> | ||
| 18 | + <van-icon v-if="!detail.is_like" :name="icon_dianzan1" size="1.2rem" style="vertical-align: bottom;" /> | ||
| 19 | + <van-icon v-else :name="icon_dianzan2" size="1.2rem" style="vertical-align: bottom;" /> | ||
| 20 | + {{ detail.like_num }} | ||
| 21 | + </span> | ||
| 22 | + </div> | ||
| 23 | + </van-col> | ||
| 24 | + </van-row> | ||
| 25 | + </div> | ||
| 26 | + <div v-if="barType === 2" class="video-bar"> | ||
| 27 | + <van-row style="text-align: center;"> | ||
| 28 | + <van-col span="7"> | ||
| 29 | + <span style="color: #777777;"> | ||
| 30 | + {{ item.play_num }}次播放 | ||
| 31 | + </span> | ||
| 32 | + </van-col> | ||
| 33 | + <van-col span="1" style="color: #EEEDED;"> | ||
| 34 | + | | ||
| 35 | + </van-col> | ||
| 36 | + <van-col span="8"> | ||
| 37 | + <span @click="handleAction('favor', detail.id)"> | ||
| 38 | + <van-icon v-if="!detail.is_favor" :name="icon_shoucang1" size="1.2rem" style="vertical-align: bottom;" /> | ||
| 39 | + <van-icon v-else :name="icon_shoucang2" size="1.2rem" style="vertical-align: bottom;" /> | ||
| 40 | + {{ detail.favor_num }} | ||
| 41 | + </span> | ||
| 42 | + </van-col> | ||
| 43 | + <van-col span="1" style="color: #EEEDED;"> | ||
| 44 | + | | ||
| 45 | + </van-col> | ||
| 46 | + <van-col span="7"> | ||
| 47 | + <span @click="handleAction('like', detail.id)"> | ||
| 48 | + <van-icon v-if="!detail.is_like" :name="icon_dianzan1" size="1.2rem" style="vertical-align: bottom;" /> | ||
| 49 | + <van-icon v-else :name="icon_dianzan2" size="1.2rem" style="vertical-align: bottom;" /> | ||
| 50 | + {{ detail.like_num }} | ||
| 51 | + </span> | ||
| 52 | + </van-col> | ||
| 53 | + </van-row> | ||
| 54 | + </div> | ||
| 55 | +</template> | ||
| 56 | + | ||
| 57 | +<script setup> | ||
| 58 | +import { icon_shoucang1, icon_shoucang2, icon_dianzan1, icon_dianzan2, icon_liuyan, icon_avatar } from '@/utils/generateIcons.js' | ||
| 59 | + | ||
| 60 | +import { ref } from 'vue'; | ||
| 61 | +import { goToDetail, setComment, prodAction } from './methods'; | ||
| 62 | +import _ from 'lodash'; | ||
| 63 | +import { prodInfoAPI } from '@/api/C/prod.js' | ||
| 64 | + | ||
| 65 | +const props = defineProps({ | ||
| 66 | + item: Object, | ||
| 67 | + barType: Number | ||
| 68 | +}); | ||
| 69 | + | ||
| 70 | +const detail = ref({}); | ||
| 71 | +detail.value = _.cloneDeep(props.item); | ||
| 72 | + | ||
| 73 | +const handleAction = async (type, id) => { | ||
| 74 | + if (await prodAction(type, id)) { | ||
| 75 | + getProductDetail(type, id) | ||
| 76 | + } | ||
| 77 | +} | ||
| 78 | + | ||
| 79 | +// 查询作品详情 | ||
| 80 | +async function getProductDetail(action_type, prod_id) { | ||
| 81 | + const { data } = await prodInfoAPI({ prod_id }); | ||
| 82 | + // 更新详情显示 | ||
| 83 | + detail.value[`is_${action_type}`] = data[`is_${action_type}`]; | ||
| 84 | + detail.value[`${action_type}_num`] = data[`${action_type}_num`]; | ||
| 85 | +} | ||
| 86 | + | ||
| 87 | +</script> | ||
| 88 | + | ||
| 89 | +<style lang="less" scoped> | ||
| 90 | +.video-bar { | ||
| 91 | + color: #713610; | ||
| 92 | + padding: 1rem; | ||
| 93 | + padding-bottom: 0.5rem; | ||
| 94 | +} | ||
| 95 | +</style> |
| ... | @@ -7,6 +7,8 @@ import no_image from '@images/que-shuju@2x.png' | ... | @@ -7,6 +7,8 @@ import no_image from '@images/que-shuju@2x.png' |
| 7 | import icon_avatar from '@images/que-logo@2x.png' | 7 | import icon_avatar from '@images/que-logo@2x.png' |
| 8 | import icon_dianzan1 from '@images/icon-dianzan01@2x.png' | 8 | import icon_dianzan1 from '@images/icon-dianzan01@2x.png' |
| 9 | import icon_dianzan2 from '@images/icon-dianzan02@2x.png' | 9 | import icon_dianzan2 from '@images/icon-dianzan02@2x.png' |
| 10 | +import icon_shoucang1 from '@images/icon-shoucang01@2x.png' | ||
| 11 | +import icon_shoucang2 from '@images/icon-shoucang02@2x.png' | ||
| 10 | import icon_liuyan from '@images/icon-liuyan@2x.png' | 12 | import icon_liuyan from '@images/icon-liuyan@2x.png' |
| 11 | 13 | ||
| 12 | export { | 14 | export { |
| ... | @@ -20,4 +22,6 @@ export { | ... | @@ -20,4 +22,6 @@ export { |
| 20 | icon_dianzan1, | 22 | icon_dianzan1, |
| 21 | icon_dianzan2, | 23 | icon_dianzan2, |
| 22 | icon_liuyan, | 24 | icon_liuyan, |
| 25 | + icon_shoucang1, | ||
| 26 | + icon_shoucang2, | ||
| 23 | } | 27 | } | ... | ... |
-
Please register or login to post a comment