mirror of
https://github.com/dataease/dataease.git
synced 2025-02-24 11:32:57 +08:00
refactor(仪表板): 视频播放优化
This commit is contained in:
parent
c017d6bd15
commit
ef6f7b6e2e
@ -50,8 +50,8 @@
|
||||
"vue-router": "4.1.3",
|
||||
"vue-types": "^5.0.2",
|
||||
"vue-uuid": "^3.0.0",
|
||||
"vue-video-player": "^6.0.0",
|
||||
"vue3-ace-editor": "^2.2.2",
|
||||
"vue3-video-play": "^1.3.2",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"web-storage-cache": "^1.1.1",
|
||||
"xss": "^1.0.14"
|
||||
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
@ -444,7 +444,7 @@ const initOpenHandler = newWindow => {
|
||||
<component-group
|
||||
is-label
|
||||
themes="light"
|
||||
:base-width="115"
|
||||
:base-width="215"
|
||||
icon-name="dv-media"
|
||||
title="媒体"
|
||||
>
|
||||
|
@ -230,7 +230,7 @@ eventBus.on('clearCanvas', clearCanvas)
|
||||
<component-group is-label :base-width="115" icon-name="dv-text" title="文本">
|
||||
<text-group></text-group>
|
||||
</component-group>
|
||||
<component-group is-label :base-width="115" icon-name="dv-media" title="媒体">
|
||||
<component-group is-label :base-width="215" icon-name="dv-media" title="媒体">
|
||||
<media-group></media-group>
|
||||
</component-group>
|
||||
<component-group is-label :base-width="115" icon-name="dv-more-com" title="更多">
|
||||
|
@ -54,6 +54,7 @@ const { icon, name, label, dragInfo, themes } = toRefs(props)
|
||||
.drag-component {
|
||||
border-radius: 4px;
|
||||
width: 88px !important;
|
||||
margin-right: 12px;
|
||||
.icon-content {
|
||||
width: 88px !important;
|
||||
height: 64px !important;
|
||||
|
@ -50,11 +50,19 @@ const handleDragEnd = e => {
|
||||
drag-info="Picture&Picture"
|
||||
v-on:click="newComponent('Picture')"
|
||||
></drag-component>
|
||||
<drag-component
|
||||
:themes="themes"
|
||||
icon="icon-video"
|
||||
label="视频"
|
||||
drag-info="DeVideo&DeVideo"
|
||||
v-on:click="newComponent('DeVideo')"
|
||||
></drag-component>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.group {
|
||||
padding: 12px 8px;
|
||||
display: inline-flex;
|
||||
}
|
||||
</style>
|
||||
|
@ -8,6 +8,82 @@ export const commonStyle = {
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
// 视频信息配置
|
||||
export const VIDEO_LINKS_DE2 = {
|
||||
videoType: 'web',
|
||||
poster: null,
|
||||
web: {
|
||||
width: '100%', //播放器宽度
|
||||
height: '100%', //播放器高度
|
||||
color: '#409eff', //主题色
|
||||
title: '', //视频名称
|
||||
src: null, //视频源
|
||||
muted: false, //静音
|
||||
webFullScreen: false,
|
||||
speedRate: ['0.75', '1.0', '1.25', '1.5', '2.0'], //播放倍速
|
||||
autoPlay: true, //自动播放
|
||||
loop: false, //循环播放
|
||||
mirror: false, //镜像画面
|
||||
lightOff: false, //关灯模式
|
||||
volume: 0.3, //默认音量大小
|
||||
control: true, //是否显示控制
|
||||
controlBtns: ['audioTrack', 'quality', 'volume', 'fullScreen'] //显示所有按钮,
|
||||
},
|
||||
rtmp: {
|
||||
sources: [
|
||||
{
|
||||
type: 'rtmp/mp4'
|
||||
}
|
||||
],
|
||||
height: 300,
|
||||
techOrder: ['flash'],
|
||||
autoplay: false,
|
||||
controls: true,
|
||||
flash: {
|
||||
hls: {
|
||||
withCredentials: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 视频信息配置
|
||||
export const VIDEO_LINKS = {
|
||||
videoType: 'web',
|
||||
web: {
|
||||
autoplay: true,
|
||||
height: 300,
|
||||
muted: true,
|
||||
loop: true,
|
||||
controlBar: {
|
||||
timeDivider: false,
|
||||
durationDisplay: false,
|
||||
remainingTimeDisplay: false,
|
||||
currentTimeDisplay: false, // 当前时间
|
||||
volumeControl: false, // 声音控制键
|
||||
fullscreenToggle: false,
|
||||
pause: false
|
||||
},
|
||||
sources: [{}]
|
||||
},
|
||||
rtmp: {
|
||||
sources: [
|
||||
{
|
||||
type: 'rtmp/mp4'
|
||||
}
|
||||
],
|
||||
height: 300,
|
||||
techOrder: ['flash'],
|
||||
autoplay: false,
|
||||
controls: true,
|
||||
flash: {
|
||||
hls: {
|
||||
withCredentials: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 超链接配置
|
||||
export const HYPERLINKS = {
|
||||
openMode: '_blank',
|
||||
@ -77,7 +153,7 @@ export const commonAttr = {
|
||||
maintainRadio: false, // 布局时保持宽高比例
|
||||
aspectRatio: 1, // 锁定时的宽高比例
|
||||
isShow: true, // 是否显示组件
|
||||
collapseName: ['position', 'background', 'style', 'picture', 'frameLinks'], // 编辑组件时记录当前使用的是哪个折叠面板,再次回来时恢复上次打开的折叠面板,优化用户体验
|
||||
collapseName: ['position', 'background', 'style', 'picture', 'frameLinks', 'videoLinks'], // 编辑组件时记录当前使用的是哪个折叠面板,再次回来时恢复上次打开的折叠面板,优化用户体验
|
||||
linkage: {
|
||||
duration: 0, // 过渡持续时间
|
||||
data: [
|
||||
@ -169,6 +245,7 @@ const list = [
|
||||
width: 600,
|
||||
height: 300
|
||||
},
|
||||
videoLinks: VIDEO_LINKS_DE2,
|
||||
matrixStyle: {}
|
||||
},
|
||||
{
|
||||
|
@ -1,6 +1,15 @@
|
||||
<template>
|
||||
<div class="attr-list de-collapse-style">
|
||||
<CommonAttr :element="curComponent"></CommonAttr>
|
||||
<CommonAttr :themes="themes" :element="curComponent">
|
||||
<el-collapse-item
|
||||
:effect="themes"
|
||||
title="链接信息"
|
||||
name="videoLinks"
|
||||
v-if="curComponent && curComponent.videoLinks"
|
||||
>
|
||||
<video-links :link-info="curComponent.videoLinks" :themes="themes"></video-links>
|
||||
</el-collapse-item>
|
||||
</CommonAttr>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -8,6 +17,15 @@
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import CommonAttr from '@/custom-component/common/CommonAttr.vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import VideoLinks from '@/custom-component/de-video/VideoLinks.vue'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { curComponent } = storeToRefs(dvMainStore)
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
themes?: EditorTheme
|
||||
}>(),
|
||||
{
|
||||
themes: 'dark'
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
@ -1,26 +1,21 @@
|
||||
<template>
|
||||
<el-row ref="mainPlayer">
|
||||
<div v-if="element.videoLinks[element.videoLinks.videoType].sources[0].src" class="player">
|
||||
<video-player
|
||||
v-if="state.showVideo"
|
||||
ref="videoPlayer"
|
||||
class="vjs-custom-skin"
|
||||
:options="editMode === 'preview' ? state.pOption : playerOptions"
|
||||
:playsinline="true"
|
||||
/>
|
||||
<div v-if="element.videoLinks[element.videoLinks.videoType].src" class="player">
|
||||
<video-play v-bind="playerOptions" />
|
||||
</div>
|
||||
<div v-else class="info-class">
|
||||
<span>{{ $t('panel.link_add_tips_pre') }}</span>
|
||||
<span>{{ $t('panel.video_add_tips') }}</span>
|
||||
<span>{{ t('visualization.video_add_tips') }}</span>
|
||||
</div>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import VideoPlayer from 'vue-video-player'
|
||||
import 'video.js/dist/video-js.css'
|
||||
import { computed, nextTick, reactive, toRefs, watch } from 'vue'
|
||||
|
||||
import { videoPlay } from 'vue3-video-play/lib/index' // 引入组件
|
||||
import 'vue3-video-play/dist/style.css' // 引入css
|
||||
import { computed, nextTick, reactive, toRefs, watch, onMounted, ref } from 'vue'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
const { t } = useI18n()
|
||||
const props = defineProps({
|
||||
propValue: {
|
||||
type: String,
|
||||
@ -45,21 +40,24 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
const state = reactive({
|
||||
pOption: {},
|
||||
pOption: {
|
||||
height: null
|
||||
},
|
||||
showVideo: true
|
||||
})
|
||||
const { element, h } = toRefs(props)
|
||||
|
||||
const moveFlag = computed(
|
||||
() => element.value.optStatus.dragging || element.value.optStatus.resizing
|
||||
)
|
||||
|
||||
const playerOptions = computed(() => {
|
||||
const videoPlayerOptions = element.value.videoLinks[element.value.videoLinks.videoType]
|
||||
videoPlayerOptions.height = h
|
||||
return videoPlayerOptions
|
||||
onMounted(() => {
|
||||
useEmitt({
|
||||
name: 'videoLinksChange-' + element.value.id,
|
||||
callback: function () {
|
||||
videoLinksChange()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const playerOptions = computed(() => element.value.videoLinks[element.value.videoLinks.videoType])
|
||||
|
||||
const videoLinksChange = () => {
|
||||
state.showVideo = false
|
||||
nextTick(() => {
|
||||
@ -83,18 +81,25 @@ watch(
|
||||
<style lang="less" scoped>
|
||||
.info-class {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
font-size: 12px;
|
||||
color: #9ea6b2;
|
||||
}
|
||||
|
||||
.move-bg {
|
||||
.player {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #000000;
|
||||
}
|
||||
|
||||
.d-player-state {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
172
core/core-frontend/src/custom-component/de-video/VideoLinks.vue
Normal file
172
core/core-frontend/src/custom-component/de-video/VideoLinks.vue
Normal file
@ -0,0 +1,172 @@
|
||||
<template>
|
||||
<el-row>
|
||||
<el-form ref="form" size="small" style="width: 100%">
|
||||
<el-form-item :effect="themes" :label="t('visualization.auto_play')">
|
||||
<el-switch
|
||||
:effect="themes"
|
||||
@change="onChange"
|
||||
v-model="state.linkInfoTemp[state.linkInfoTemp.videoType].autoPlay"
|
||||
size="mini"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="state.linkInfoTemp.videoType === 'web'"
|
||||
:label="t('visualization.play_frequency')"
|
||||
:effect="themes"
|
||||
>
|
||||
<el-radio-group
|
||||
:effect="themes"
|
||||
@change="onChange"
|
||||
v-model="state.linkInfoTemp[state.linkInfoTemp.videoType].loop"
|
||||
>
|
||||
<el-radio :effect="themes" :label="false">{{ t('visualization.play_once') }}</el-radio>
|
||||
<el-radio :effect="themes" :label="true">{{ t('visualization.play_circle') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :effect="themes" :label="t('visualization.video_links')">
|
||||
<el-input
|
||||
:effect="themes"
|
||||
@blur="onChange"
|
||||
v-model="state.linkInfoTemp[state.linkInfoTemp.videoType].src"
|
||||
/>
|
||||
<span class="tips-class"> Tips:{{ t('visualization.video_tips') }} </span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, toRefs, watch, computed } from 'vue'
|
||||
import { dvMainStoreWithOut } from '../../store/modules/data-visualization/dvMain'
|
||||
import { storeToRefs } from 'pinia/dist/pinia'
|
||||
import { checkAddHttp, deepCopy } from '../../utils/utils'
|
||||
import { snapshotStoreWithOut } from '../../store/modules/data-visualization/snapshot'
|
||||
import { useI18n } from '../../hooks/web/useI18n'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { curComponent, curActiveTabInner } = storeToRefs(dvMainStore)
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
const emits = defineEmits(['close'])
|
||||
const popover = ref(null)
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
themes: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: 'dark'
|
||||
},
|
||||
linkInfo: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
// 属性所属组件位置
|
||||
attrPosition: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'panel'
|
||||
}
|
||||
})
|
||||
|
||||
const { linkInfo, attrPosition } = toRefs(props)
|
||||
|
||||
const state = reactive({
|
||||
linkInfoTemp: null,
|
||||
componentType: null,
|
||||
linkageActiveStatus: false,
|
||||
editFilter: ['view', 'custom']
|
||||
})
|
||||
|
||||
const init = () => {
|
||||
state.linkInfoTemp = deepCopy(linkInfo.value)
|
||||
}
|
||||
|
||||
const onChange = () => {
|
||||
state.linkInfoTemp[state.linkInfoTemp.videoType].src = checkAddHttp(
|
||||
state.linkInfoTemp[state.linkInfoTemp.videoType].src
|
||||
)
|
||||
|
||||
if (attrPosition.value === 'panel') {
|
||||
curComponent.value.videoLinks = state.linkInfoTemp
|
||||
} else {
|
||||
curActiveTabInner.value.videoLinks = state.linkInfoTemp
|
||||
}
|
||||
|
||||
curComponent.value.videoLinks = state.linkInfoTemp
|
||||
snapshotStore.recordSnapshotCache()
|
||||
useEmitt().emitter.emit('videoLinksChange-' + curComponent.value.id)
|
||||
}
|
||||
const onBlur = () => {
|
||||
state.linkInfoTemp.src = checkAddHttp(state.linkInfoTemp.src)
|
||||
curComponent.value.frameLinks.src = state.linkInfoTemp.src
|
||||
snapshotStore.recordSnapshotCache()
|
||||
useEmitt().emitter.emit('frameLinksChange-' + curComponent.value.id)
|
||||
}
|
||||
init()
|
||||
|
||||
watch(
|
||||
linkInfo.value,
|
||||
() => {
|
||||
init()
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.slot-class {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.bottom {
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.ellipsis-area {
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
overflow: hidden; /*超出部分隐藏*/
|
||||
white-space: nowrap; /*不换行*/
|
||||
text-overflow: ellipsis; /*超出部分文字以...显示*/
|
||||
background-color: #f7f8fa;
|
||||
color: #3d4d66;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
height: 24px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.select-filed {
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
overflow: hidden; /*超出部分隐藏*/
|
||||
white-space: nowrap; /*不换行*/
|
||||
text-overflow: ellipsis; /*超出部分文字以...显示*/
|
||||
color: #3d4d66;
|
||||
font-size: 12px;
|
||||
line-height: 35px;
|
||||
height: 35px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.tips-class {
|
||||
color: #909399;
|
||||
font-size: 8px;
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.hint-icon {
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
color: #646a73;
|
||||
|
||||
&.hint-icon--dark {
|
||||
color: #a6a6a6;
|
||||
}
|
||||
}
|
||||
.data-area-label {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
@ -2126,7 +2126,7 @@ export default {
|
||||
play_circle: '循环播放',
|
||||
video_links: '视频链接',
|
||||
web_url: '网页地址',
|
||||
video_add_tips: '添加视频信息...',
|
||||
video_add_tips: '请在右侧添加视频信息...',
|
||||
link_add_tips_pre: '请在右侧配置网页信息..',
|
||||
web_add_tips_suf: '添加网页信息...',
|
||||
panel_view_result_show: '图表结果',
|
||||
|
Loading…
Reference in New Issue
Block a user