mirror of
				https://gitee.com/hhyykk/ipms-sjy-ui.git
				synced 2025-10-31 18:28:44 +08:00 
			
		
		
		
	1、微信组件更新vue3.視頻組件更新使用video.js 6.0.0版本。
2、目前mp中視頻組件可以簡單的使用了。
This commit is contained in:
		| @@ -29,6 +29,7 @@ | |||||||
|     "@form-create/designer": "^3.1.0", |     "@form-create/designer": "^3.1.0", | ||||||
|     "@form-create/element-ui": "^3.1.17", |     "@form-create/element-ui": "^3.1.17", | ||||||
|     "@iconify/iconify": "^3.1.0", |     "@iconify/iconify": "^3.1.0", | ||||||
|  |     "@videojs-player/vue": "^1.0.0", | ||||||
|     "@vueuse/core": "^9.13.0", |     "@vueuse/core": "^9.13.0", | ||||||
|     "@wangeditor/editor": "^5.1.23", |     "@wangeditor/editor": "^5.1.23", | ||||||
|     "@wangeditor/editor-for-vue": "^5.1.10", |     "@wangeditor/editor-for-vue": "^5.1.10", | ||||||
| @@ -58,6 +59,7 @@ | |||||||
|     "qs": "^6.11.1", |     "qs": "^6.11.1", | ||||||
|     "steady-xml": "^0.1.0", |     "steady-xml": "^0.1.0", | ||||||
|     "url": "^0.11.0", |     "url": "^0.11.0", | ||||||
|  |     "video.js": "^8.0.4", | ||||||
|     "vue": "3.2.47", |     "vue": "3.2.47", | ||||||
|     "vue-i18n": "9.2.2", |     "vue-i18n": "9.2.2", | ||||||
|     "vue-router": "^4.1.6", |     "vue-router": "^4.1.6", | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -8,110 +8,84 @@ | |||||||
|       存在的问题:mediaId 有效期是 3 天,超过时间后无法播放 |       存在的问题:mediaId 有效期是 3 天,超过时间后无法播放 | ||||||
|     2)重构后的做法:后端接收到微信公众号的视频消息后,将视频消息的 media_id 的文件内容保存到文件服务器中,这样前端可以直接使用 URL 播放。 |     2)重构后的做法:后端接收到微信公众号的视频消息后,将视频消息的 media_id 的文件内容保存到文件服务器中,这样前端可以直接使用 URL 播放。 | ||||||
|   ② 体验优化:弹窗关闭后,自动暂停视频的播放 |   ② 体验优化:弹窗关闭后,自动暂停视频的播放 | ||||||
|  |  | ||||||
| --> | --> | ||||||
| <template> | <template> | ||||||
|   <div> |   <div @click="playVideo()"> | ||||||
|     <!-- 提示 --> |     <!-- 提示 --> | ||||||
|     <div @click="playVideo()"> |     <div> | ||||||
|       <el-icon> |       <Icon icon="ep:video-play" class="mr-5px" /> | ||||||
|         <VideoPlay /> |  | ||||||
|       </el-icon> |  | ||||||
|       <p>点击播放视频</p> |       <p>点击播放视频</p> | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
|     <!-- 弹窗播放 --> |     <!-- 弹窗播放 --> | ||||||
|     <el-dialog |     <el-dialog | ||||||
|  |       v-model="dialogVideo" | ||||||
|       title="视频播放" |       title="视频播放" | ||||||
|       v-model:visible="dialogVideo" |  | ||||||
|       width="40%" |       width="40%" | ||||||
|       append-to-body |       append-to-body | ||||||
|       @close="closeDialog" |       @close="closeDialog" | ||||||
|     > |     > | ||||||
|       <video-player |       <template #footer> | ||||||
|         v-if="playerOptions.sources[0].src" |         <video-player | ||||||
|         class="video-player vjs-custom-skin" |           v-if="dialogVideo" | ||||||
|         ref="videoPlayerRef" |           class="video-player vjs-big-play-centered" | ||||||
|         :playsinline="true" |           :src="url" | ||||||
|         :options="playerOptions" |           poster="" | ||||||
|         @play="onPlayerPlay($event)" |           crossorigin="anonymous" | ||||||
|         @pause="onPlayerPause($event)" |           playsinline | ||||||
|       /> |           controls | ||||||
|  |           :volume="0.6" | ||||||
|  |           :height="320" | ||||||
|  |           :playback-rates="[0.7, 1.0, 1.5, 2.0]" | ||||||
|  |         /> | ||||||
|  |       </template> | ||||||
|  |       <!--     事件,暫時沒用 | ||||||
|  |       @mounted="handleMounted"--> | ||||||
|  |       <!--        @ready="handleEvent($event)"--> | ||||||
|  |       <!--        @play="handleEvent($event)"--> | ||||||
|  |       <!--        @pause="handleEvent($event)"--> | ||||||
|  |       <!--        @ended="handleEvent($event)"--> | ||||||
|  |       <!--        @loadeddata="handleEvent($event)"--> | ||||||
|  |       <!--        @waiting="handleEvent($event)"--> | ||||||
|  |       <!--        @playing="handleEvent($event)"--> | ||||||
|  |       <!--        @canplay="handleEvent($event)"--> | ||||||
|  |       <!--        @canplaythrough="handleEvent($event)"--> | ||||||
|  |       <!--        @timeupdate="handleEvent(player?.currentTime())"--> | ||||||
|     </el-dialog> |     </el-dialog> | ||||||
|   </div> |   </div> | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script setup lang="ts" name="WxVideoPlayer"> | <script lang="ts" name="WxVideoPlayer"> | ||||||
| // 引入 videoPlayer 相关组件。教程:https://juejin.cn/post/6923056942281654285 | //升级videojs6.0版本,重寫6.0版本 | ||||||
| import { videoPlayer } from 'vue-video-player' | import 'video.js/dist/video-js.css' | ||||||
|  | import { defineComponent } from 'vue' | ||||||
|  | import { VideoPlayer } from '@videojs-player/vue' | ||||||
| import 'video.js/dist/video-js.css' | import 'video.js/dist/video-js.css' | ||||||
| import 'vue-video-player/src/custom-theme.css' |  | ||||||
| import { VideoPlay } from '@element-plus/icons-vue' |  | ||||||
|  |  | ||||||
| const props = defineProps({ | export default defineComponent({ | ||||||
|   url: { |   components: { | ||||||
|     // 视频地址,例如说:https://www.iocoder.cn/xxx.mp4 |     VideoPlayer | ||||||
|     type: String, |   }, | ||||||
|     required: true |   props: { | ||||||
|   } |     url: { | ||||||
| }) |       // 视频地址,例如说:https://vjs.zencdn.net/v/oceans.mp4 | ||||||
| const videoPlayerRef = ref() |       type: String, | ||||||
| const dialogVideo = ref(false) |       required: true | ||||||
| const playerOptions = reactive({ |  | ||||||
|   playbackRates: [0.5, 1.0, 1.5, 2.0], // 播放速度 |  | ||||||
|   autoplay: false, // 如果 true,浏览器准备好时开始回放。 |  | ||||||
|   muted: false, // 默认情况下将会消除任何音频。 |  | ||||||
|   loop: false, // 导致视频一结束就重新开始。 |  | ||||||
|   preload: 'auto', // 建议浏览器在 <video> 加载元素后是否应该开始下载视频数据。auto 浏览器选择最佳行为,立即开始加载视频(如果浏览器支持) |  | ||||||
|   language: 'zh-CN', |  | ||||||
|   aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3") |  | ||||||
|   fluid: true, // 当true时,Video.js player 将拥有流体大小。换句话说,它将按比例缩放以适应其容器。 |  | ||||||
|   sources: [ |  | ||||||
|     { |  | ||||||
|       type: 'video/mp4', |  | ||||||
|       src: '' // 你的视频地址(必填)【重要】 |  | ||||||
|     } |     } | ||||||
|   ], |   }, | ||||||
|   poster: '', // 你的封面地址 |   setup() { | ||||||
|   width: document.documentElement.clientWidth, |     // const videoPlayerRef = ref(null) | ||||||
|   notSupportedMessage: '此视频暂无法播放,请稍后再试', //允许覆盖 Video.js 无法播放媒体源时显示的默认信息。 |     const dialogVideo = ref(false) | ||||||
|   controlBar: { |  | ||||||
|     timeDivider: true, |     const handleEvent = (log) => { | ||||||
|     durationDisplay: true, |       console.log('Basic player event', log) | ||||||
|     remainingTimeDisplay: false, |     } | ||||||
|     fullscreenToggle: true //全屏按钮 |     const playVideo = () => { | ||||||
|  |       dialogVideo.value = true | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return { handleEvent, playVideo, dialogVideo } | ||||||
|   } |   } | ||||||
| }) | }) | ||||||
|  |  | ||||||
| const playVideo = () => { |  | ||||||
|   dialogVideo.value = true |  | ||||||
|   playerOptions.sources[0].src = props.url |  | ||||||
| } |  | ||||||
| const closeDialog = () => { |  | ||||||
|   // 暂停播放 |  | ||||||
|   // videoPlayerRef.player.pause() |  | ||||||
| } |  | ||||||
| //   onPlayerPlay(player) {}, |  | ||||||
| //   // // eslint-disable-next-line @typescript-eslint/no-unused-vars |  | ||||||
| //   // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-unused-vars |  | ||||||
| //   onPlayerPause(player) {} |  | ||||||
|  |  | ||||||
| // methods: { |  | ||||||
| //   playVideo() { |  | ||||||
| //     this.dialogVideo = true |  | ||||||
| //     // 设置地址 |  | ||||||
| //     this.playerOptions.sources[0]['src'] = this.url |  | ||||||
| //   }, |  | ||||||
| //   closeDialog() { |  | ||||||
| //     // 暂停播放 |  | ||||||
| //     this.$refs.videoPlayer.player.pause() |  | ||||||
| //   }, |  | ||||||
| // |  | ||||||
| //   //todo player组件引入可能有问题 |  | ||||||
| // |  | ||||||
| //   // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-unused-vars |  | ||||||
| //   onPlayerPlay(player) {}, |  | ||||||
| //   // // eslint-disable-next-line @typescript-eslint/no-unused-vars |  | ||||||
| //   // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-unused-vars |  | ||||||
| //   onPlayerPause(player) {} |  | ||||||
| // } |  | ||||||
| </script> | </script> | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ | |||||||
|  |  | ||||||
| <script setup lang="ts" name="WxVoicePlayer"> | <script setup lang="ts" name="WxVoicePlayer"> | ||||||
| // 因为微信语音是 amr 格式,所以需要用到 amr 解码器:https://www.npmjs.com/package/benz-amr-recorder | // 因为微信语音是 amr 格式,所以需要用到 amr 解码器:https://www.npmjs.com/package/benz-amr-recorder | ||||||
|  |  | ||||||
| import BenzAMRRecorder from 'benz-amr-recorder' | import BenzAMRRecorder from 'benz-amr-recorder' | ||||||
|  |  | ||||||
| const props = defineProps({ | const props = defineProps({ | ||||||
|   | |||||||
| @@ -19,8 +19,14 @@ | |||||||
|         </el-select> |         </el-select> | ||||||
|       </el-form-item> |       </el-form-item> | ||||||
|       <el-form-item> |       <el-form-item> | ||||||
|         <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button> |         <el-button @click="handleQuery"> | ||||||
|         <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> |           <Icon icon="ep:search" class="mr-5px" /> | ||||||
|  |           搜索 | ||||||
|  |         </el-button> | ||||||
|  |         <el-button @click="resetQuery"> | ||||||
|  |           <Icon icon="ep:refresh" class="mr-5px" /> | ||||||
|  |           重置 | ||||||
|  |         </el-button> | ||||||
|       </el-form-item> |       </el-form-item> | ||||||
|     </el-form> |     </el-form> | ||||||
|   </content-wrap> |   </content-wrap> | ||||||
| @@ -63,12 +69,19 @@ | |||||||
| import { getFreePublishPage, deleteFreePublish } from '@/api/mp/freePublish' | import { getFreePublishPage, deleteFreePublish } from '@/api/mp/freePublish' | ||||||
| import * as MpAccountApi from '@/api/mp/account' | import * as MpAccountApi from '@/api/mp/account' | ||||||
| import WxNews from '@/views/mp/components/wx-news/main.vue' | import WxNews from '@/views/mp/components/wx-news/main.vue' | ||||||
|  |  | ||||||
| const message = useMessage() // 消息弹窗 | const message = useMessage() // 消息弹窗 | ||||||
|  |  | ||||||
| const loading = ref(true) // 列表的加载中 | const loading = ref(true) // 列表的加载中 | ||||||
| const total = ref(0) // 列表的总页数 | const total = ref(0) // 列表的总页数 | ||||||
| const list = ref([]) // 列表的数据 | const list = ref([]) // 列表的数据 | ||||||
| const queryParams = reactive({ | interface QueryParams { | ||||||
|  |   currentPage: number | undefined | string | ||||||
|  |   pageNo: number | undefined | string | ||||||
|  |   accountId: number | undefined | string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const queryParams: QueryParams = reactive({ | ||||||
|   currentPage: 1, // 当前页数 |   currentPage: 1, // 当前页数 | ||||||
|   pageNo: 1, // 当前页数 |   pageNo: 1, // 当前页数 | ||||||
|   accountId: undefined // 当前页数 |   accountId: undefined // 当前页数 | ||||||
| @@ -115,7 +128,6 @@ const resetQuery = () => { | |||||||
|   queryFormRef.value.resetFields() |   queryFormRef.value.resetFields() | ||||||
|   // 默认选中第一个 |   // 默认选中第一个 | ||||||
|   if (accountList.value.length > 0) { |   if (accountList.value.length > 0) { | ||||||
|     // @ts-ignore |  | ||||||
|     queryParams.accountId = accountList.value[0].id |     queryParams.accountId = accountList.value[0].id | ||||||
|   } |   } | ||||||
|   handleQuery() |   handleQuery() | ||||||
| @@ -144,7 +156,6 @@ onMounted(async () => { | |||||||
|   accountList.value = await MpAccountApi.getSimpleAccountList() |   accountList.value = await MpAccountApi.getSimpleAccountList() | ||||||
|   // 选中第一个 |   // 选中第一个 | ||||||
|   if (accountList.value.length > 0) { |   if (accountList.value.length > 0) { | ||||||
|     // @ts-ignore |  | ||||||
|     queryParams.accountId = accountList.value[0].id |     queryParams.accountId = accountList.value[0].id | ||||||
|   } |   } | ||||||
|   await getList() |   await getList() | ||||||
|   | |||||||
| @@ -181,17 +181,17 @@ | |||||||
|   </ContentWrap> |   </ContentWrap> | ||||||
| </template> | </template> | ||||||
| <script setup lang="ts" name="MpMessage"> | <script setup lang="ts" name="MpMessage"> | ||||||
| import { DICT_TYPE, getStrDictOptions } from '@/utils/dict' | import WxVideoPlayer from '@/views/mp/components/wx-video-play/main.vue' | ||||||
| import { dateFormatter } from '@/utils/formatTime' |  | ||||||
| // import WxVideoPlayer from '@/views/mp/components/wx-video-play/main.vue' |  | ||||||
| import WxVoicePlayer from '@/views/mp/components/wx-voice-play/main.vue' | import WxVoicePlayer from '@/views/mp/components/wx-voice-play/main.vue' | ||||||
| // import WxMsg from '@/views/mp/components/wx-msg/main.vue' | import WxMsg from '@/views/mp/components/wx-msg/main.vue' | ||||||
| import WxLocation from '@/views/mp/components/wx-location/main.vue' | import WxLocation from '@/views/mp/components/wx-location/main.vue' | ||||||
| // import WxMusic from '@/views/mp/components/wx-music/main.vue' | import WxMusic from '@/views/mp/components/wx-music/main.vue' | ||||||
| // import WxNews from '@/views/mp/components/wx-news/main.vue' | import WxNews from '@/views/mp/components/wx-news/main.vue' | ||||||
| import * as MpAccountApi from '@/api/mp/account' | import * as MpAccountApi from '@/api/mp/account' | ||||||
| import * as MpMessageApi from '@/api/mp/message' | import * as MpMessageApi from '@/api/mp/message' | ||||||
| const message = useMessage() // 消息弹窗 | const message = useMessage() // 消息弹窗 | ||||||
|  | import { DICT_TYPE, getStrDictOptions } from '@/utils/dict' | ||||||
|  | import { dateFormatter } from '@/utils/formatTime' | ||||||
|  |  | ||||||
| const loading = ref(true) // 列表的加载中 | const loading = ref(true) // 列表的加载中 | ||||||
| const total = ref(0) // 列表的总页数 | const total = ref(0) // 列表的总页数 | ||||||
|   | |||||||
| @@ -28,13 +28,21 @@ | |||||||
|         /> |         /> | ||||||
|       </el-form-item> |       </el-form-item> | ||||||
|       <el-form-item> |       <el-form-item> | ||||||
|         <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button> |         <el-button @click="handleQuery"> | ||||||
|         <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> |           <Icon icon="ep:search" class="mr-5px" /> | ||||||
|  |           搜索 | ||||||
|  |         </el-button> | ||||||
|  |         <el-button @click="resetQuery"> | ||||||
|  |           <Icon icon="ep:refresh" class="mr-5px" /> | ||||||
|  |           重置 | ||||||
|  |         </el-button> | ||||||
|         <el-button type="primary" plain @click="openForm('create')" v-hasPermi="['mp:tag:create']"> |         <el-button type="primary" plain @click="openForm('create')" v-hasPermi="['mp:tag:create']"> | ||||||
|           <Icon icon="ep:plus" class="mr-5px" /> 新增 |           <Icon icon="ep:plus" class="mr-5px" /> | ||||||
|  |           新增 | ||||||
|         </el-button> |         </el-button> | ||||||
|         <el-button type="success" plain @click="handleSync" v-hasPermi="['mp:tag:sync']"> |         <el-button type="success" plain @click="handleSync" v-hasPermi="['mp:tag:sync']"> | ||||||
|           <Icon icon="ep:refresh" class="mr-5px" /> 同步 |           <Icon icon="ep:refresh" class="mr-5px" /> | ||||||
|  |           同步 | ||||||
|         </el-button> |         </el-button> | ||||||
|       </el-form-item> |       </el-form-item> | ||||||
|     </el-form> |     </el-form> | ||||||
| @@ -91,6 +99,7 @@ import { dateFormatter } from '@/utils/formatTime' | |||||||
| import * as MpTagApi from '@/api/mp/tag' | import * as MpTagApi from '@/api/mp/tag' | ||||||
| import * as MpAccountApi from '@/api/mp/account' | import * as MpAccountApi from '@/api/mp/account' | ||||||
| import TagForm from './TagForm.vue' | import TagForm from './TagForm.vue' | ||||||
|  |  | ||||||
| const message = useMessage() // 消息弹窗 | const message = useMessage() // 消息弹窗 | ||||||
| const { t } = useI18n() // 国际化 | const { t } = useI18n() // 国际化 | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 wuxiran
					wuxiran