forked from github/dataease
feat:仪表板新增视频组件
This commit is contained in:
parent
a861223e30
commit
f32ba3be80
@ -0,0 +1,19 @@
|
||||
package io.dataease.controller.authModel;
|
||||
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* Author: wangjiahao
|
||||
* Date: 2021/11/5
|
||||
* Description:
|
||||
*/
|
||||
@Api(tags = "授权树:授权树模型")
|
||||
@ApiSupport(order = 80)
|
||||
@RestController
|
||||
@RequestMapping("authModel")
|
||||
public class VAuthModelController {
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package io.dataease.dto.authModel;
|
||||
|
||||
import io.dataease.base.domain.VAuthModel;
|
||||
|
||||
/**
|
||||
* Author: wangjiahao
|
||||
* Date: 2021/11/5
|
||||
* Description:
|
||||
*/
|
||||
public class VAuthModelDTO extends VAuthModel {
|
||||
|
||||
}
|
@ -65,10 +65,10 @@
|
||||
<!--要生成的数据库表 -->
|
||||
|
||||
|
||||
<table tableName="panel_link_jump"/>
|
||||
<table tableName="panel_link_jump_info"/>
|
||||
<table tableName="panel_link_jump_target_view_info"/>
|
||||
<table tableName="chart_view"/>
|
||||
<!-- <table tableName="panel_link_jump"/>-->
|
||||
<!-- <table tableName="panel_link_jump_info"/>-->
|
||||
<!-- <table tableName="panel_link_jump_target_view_info"/>-->
|
||||
<table tableName="v_auth_model"/>
|
||||
|
||||
<!-- <table tableName="sys_dict_item"/>-->
|
||||
<!-- <table tableName="dataset_table_field"/>-->
|
||||
|
@ -51,6 +51,7 @@
|
||||
"vue-router": "3.0.6",
|
||||
"vue-to-pdf": "^1.0.0",
|
||||
"vue-uuid": "2.0.2",
|
||||
"vue-video-player": "^5.0.2",
|
||||
"vuedraggable": "^2.24.3",
|
||||
"vuex": "3.1.0",
|
||||
"webpack": "^4.46.0",
|
||||
|
@ -27,6 +27,7 @@
|
||||
:is-edit="false"
|
||||
:element="config"
|
||||
:search-count="searchCount"
|
||||
:h="config.style.height"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@ -76,6 +77,29 @@ export default {
|
||||
methods: {
|
||||
getStyle,
|
||||
|
||||
getShapeStyleIntDeDrag(style, prop) {
|
||||
if (prop === 'rotate') {
|
||||
return style['rotate']
|
||||
}
|
||||
if (prop === 'width') {
|
||||
return this.format(style['width'], this.scaleWidth)
|
||||
}
|
||||
if (prop === 'left') {
|
||||
return this.format(style['left'], this.scaleWidth)
|
||||
}
|
||||
if (prop === 'height') {
|
||||
return this.format(style['height'], this.scaleHeight)
|
||||
}
|
||||
if (prop === 'top') {
|
||||
const top = this.format(style['top'], this.scaleHeight)
|
||||
// console.log('top:' + top)
|
||||
return top
|
||||
}
|
||||
},
|
||||
format(value, scale) {
|
||||
// 自适应画布区域 返回原值
|
||||
return value * scale / 100
|
||||
},
|
||||
getOutStyleDefault(style) {
|
||||
const result = {};
|
||||
['width', 'left'].forEach(attr => {
|
||||
|
125
frontend/src/components/canvas/components/Editor/VideoLinks.vue
Normal file
125
frontend/src/components/canvas/components/Editor/VideoLinks.vue
Normal file
@ -0,0 +1,125 @@
|
||||
<template>
|
||||
|
||||
<el-popover
|
||||
ref="popover"
|
||||
width="340"
|
||||
trigger="click"
|
||||
>
|
||||
<el-row>
|
||||
<el-form ref="form" size="mini" label-width="70px">
|
||||
<el-form-item :label="'自动播放'">
|
||||
<el-switch v-model="linkInfoTemp.autoplay" size="mini" />
|
||||
<span v-show="linkInfoTemp.autoplay" style="color: #909399; font-size: 8px;margin-left: 3px">
|
||||
<!-- Tips:{{ $t('panel.link_open_tips') }}-->
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('panel.open_mode')">
|
||||
<el-radio-group v-model="linkInfoTemp.loop">
|
||||
<el-radio :label="false">播放一次</el-radio>
|
||||
<el-radio :label="true">循环播放</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('panel.hyperLinks')">
|
||||
<el-input v-model="linkInfoTemp.sources[0].src" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit">{{ $t('panel.confirm') }}</el-button>
|
||||
<el-button @click="onClose">{{ $t('panel.cancel') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
<i slot="reference" class="icon iconfont icon-chaolianjie" />
|
||||
</el-popover>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import { deepCopy } from '@/components/canvas/utils/utils'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
linkInfo: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
linkInfoTemp: null,
|
||||
componentType: null,
|
||||
linkageActiveStatus: false,
|
||||
editFilter: [
|
||||
'view',
|
||||
'custom'
|
||||
]
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.linkInfoTemp = deepCopy(this.linkInfo)
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
'curComponent'
|
||||
])
|
||||
},
|
||||
methods: {
|
||||
onSubmit() {
|
||||
this.curComponent.videoLinks = this.linkInfoTemp
|
||||
this.$store.state.styleChangeTimes++
|
||||
this.popoverClose()
|
||||
},
|
||||
onClose() {
|
||||
this.$emit('close')
|
||||
this.popoverClose()
|
||||
},
|
||||
popoverClose() {
|
||||
this.$refs.popover.showPopper = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.slot-class{
|
||||
color: white;
|
||||
}
|
||||
|
||||
.bottom {
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
|
||||
}
|
||||
.ellip{
|
||||
/*width: 100%;*/
|
||||
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{
|
||||
/*width: 100%;*/
|
||||
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;
|
||||
}
|
||||
>>>.el-popover{
|
||||
height: 200px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
</style>
|
@ -55,9 +55,6 @@
|
||||
@amAddItem="addItemBox(item)"
|
||||
@linkJumpSet="linkJumpSet(item)"
|
||||
>
|
||||
<!-- <span style="position:relative;left: 0px;top:0px">-->
|
||||
<!-- item:x-{{ item.x }}y-{{ item.y }}top-{{ item.style.top }}-->
|
||||
<!-- </span>-->
|
||||
<component
|
||||
:is="item.component"
|
||||
v-if="item.type==='v-text'"
|
||||
@ -72,17 +69,6 @@
|
||||
:active="item === curComponent"
|
||||
@input="handleInput"
|
||||
/>
|
||||
<!-- <out-widget
|
||||
:is="item.component"
|
||||
v-else-if="item.type==='custom'"
|
||||
:id="'component' + item.id"
|
||||
class="component"
|
||||
:style="getComponentStyleDefault(item.style)"
|
||||
:prop-value="item.propValue"
|
||||
:element="item"
|
||||
:out-style="getShapeStyleInt(item.style)"
|
||||
:active="item === curComponent"
|
||||
/> -->
|
||||
<de-out-widget
|
||||
v-else-if="item.type==='custom'"
|
||||
:id="'component' + item.id"
|
||||
@ -117,6 +103,7 @@
|
||||
:element="item"
|
||||
:out-style="getShapeStyleInt(item.style)"
|
||||
:active="item === curComponent"
|
||||
:h="getShapeStyleIntDeDrag(item.style,'height')"
|
||||
/>
|
||||
</de-drag>
|
||||
<!--拖拽阴影部分-->
|
||||
|
@ -136,6 +136,11 @@
|
||||
<Hyperlinks :link-info="curComponent.hyperlinks" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div v-if="attrShow('videoLinks')" style="width: 20px;float: left;margin-top: 2px;margin-left: 2px;">
|
||||
<el-tooltip content="视频信息">
|
||||
<VideoLinks :link-info="curComponent.videoLinks" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
|
||||
<div v-if="attrShow('date-format')" style="width: 20px;float: left;margin-top: 2px;margin-left: 10px;">
|
||||
<el-tooltip content="日期格式">
|
||||
@ -150,10 +155,11 @@
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import Hyperlinks from '@/components/canvas/components/Editor/Hyperlinks'
|
||||
import VideoLinks from '@/components/canvas/components/Editor/VideoLinks'
|
||||
import DateFormat from '@/components/canvas/components/Editor/DateFormat'
|
||||
|
||||
export default {
|
||||
components: { Hyperlinks, DateFormat },
|
||||
components: { Hyperlinks, DateFormat, VideoLinks },
|
||||
props: {
|
||||
scrollLeft: {
|
||||
type: Number,
|
||||
@ -273,6 +279,11 @@ export default {
|
||||
'color',
|
||||
'backgroundColor',
|
||||
'hyperlinks'
|
||||
],
|
||||
// 文本组件显示的属性
|
||||
'de-video': [
|
||||
'opacity',
|
||||
'videoLinks'
|
||||
]
|
||||
}
|
||||
},
|
||||
|
161
frontend/src/components/canvas/custom-component/DeVideo.vue
Normal file
161
frontend/src/components/canvas/custom-component/DeVideo.vue
Normal file
@ -0,0 +1,161 @@
|
||||
<template>
|
||||
<el-row ref="mainPlayer">
|
||||
<div v-if="this.element.videoLinks.sources[0].src" class="player">
|
||||
<video-player
|
||||
ref="videoPlayer"
|
||||
class="vjs-custom-skin"
|
||||
:options="playerOptions"
|
||||
:playsinline="true"
|
||||
@play="onPlayerPlay($event)"
|
||||
@pause="onPlayerPause($event)"
|
||||
@ended="onPlayerEnded($event)"
|
||||
@loadeddata="onPlayerLoadeddata($event)"
|
||||
@waiting="onPlayerWaiting($event)"
|
||||
@playing="onPlayerPlaying($event)"
|
||||
@timeupdate="onPlayerTimeupdate($event)"
|
||||
@canplay="onPlayerCanplay($event)"
|
||||
@canplaythrough="onPlayerCanplaythrough($event)"
|
||||
@ready="playerReadied"
|
||||
@statechanged="playerStateChanged($event)"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="info-class">
|
||||
请点击添加配置视频信息...
|
||||
</div>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// custom skin css
|
||||
import '@/custom-theme.css'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
propValue: {
|
||||
type: String,
|
||||
require: true
|
||||
},
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
element: {
|
||||
type: Object
|
||||
},
|
||||
editMode: {
|
||||
type: String,
|
||||
require: false,
|
||||
default: 'preview'
|
||||
},
|
||||
active: {
|
||||
type: Boolean,
|
||||
require: false,
|
||||
default: false
|
||||
},
|
||||
h: {
|
||||
type: Number,
|
||||
default: 200
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
player() {
|
||||
return this.$refs.videoPlayer.player
|
||||
},
|
||||
playerOptions() {
|
||||
const videoLinks = this.element.videoLinks
|
||||
let playHeight = this.h
|
||||
if (this.canvasStyleData.panel.gap) {
|
||||
playHeight = this.h - (this.componentGap * 2)
|
||||
}
|
||||
videoLinks.height = playHeight
|
||||
return videoLinks
|
||||
},
|
||||
...mapState([
|
||||
'componentGap',
|
||||
'canvasStyleData'
|
||||
])
|
||||
},
|
||||
mounted() {
|
||||
// console.log('this is current player instance object', this.player)
|
||||
setTimeout(() => {
|
||||
console.log('dynamic change options', this.player)
|
||||
|
||||
// change src
|
||||
// this.playerOptions.sources[0].src = 'https://cdn.theguardian.tv/webM/2015/07/20/150716YesMen_synd_768k_vp8.webm';
|
||||
|
||||
// change item
|
||||
// this.$set(this.playerOptions.sources, 0, {
|
||||
// type: "video/mp4",
|
||||
// src: 'https://cdn.theguardian.tv/webM/2015/07/20/150716YesMen_synd_768k_vp8.webm',
|
||||
// })
|
||||
|
||||
// change array
|
||||
// this.playerOptions.sources = [{
|
||||
// type: "video/mp4",
|
||||
// src: 'https://cdn.theguardian.tv/webM/2015/07/20/150716YesMen_synd_768k_vp8.webm',
|
||||
// }]
|
||||
this.player.muted(false)
|
||||
}, 5000)
|
||||
},
|
||||
methods: {
|
||||
// listen event
|
||||
onPlayerPlay(player) {
|
||||
// console.log('player play!', player)
|
||||
},
|
||||
onPlayerPause(player) {
|
||||
// console.log('player pause!', player)
|
||||
},
|
||||
onPlayerEnded(player) {
|
||||
// console.log('player ended!', player)
|
||||
},
|
||||
onPlayerLoadeddata(player) {
|
||||
// console.log('player Loadeddata!', player)
|
||||
},
|
||||
onPlayerWaiting(player) {
|
||||
// console.log('player Waiting!', player)
|
||||
},
|
||||
onPlayerPlaying(player) {
|
||||
// console.log('player Playing!', player)
|
||||
},
|
||||
onPlayerTimeupdate(player) {
|
||||
// console.log('player Timeupdate!', player.currentTime())
|
||||
},
|
||||
onPlayerCanplay(player) {
|
||||
// console.log('player Canplay!', player)
|
||||
},
|
||||
onPlayerCanplaythrough(player) {
|
||||
// console.log('player Ca
|
||||
// console.log('example 01nplaythrough!', player)
|
||||
},
|
||||
|
||||
// or listen state event
|
||||
playerStateChanged(playerCurrentState) {
|
||||
// console.log('player current update state', playerCurrentState)
|
||||
},
|
||||
|
||||
// player is ready
|
||||
playerReadied(player) {
|
||||
// seek to 10s
|
||||
console.log('example player 1 readied', player)
|
||||
// player.currentTime(10): the player is readied', player)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.info-class{
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #FFFFFF;
|
||||
font-size: 12px;
|
||||
color: #9ea6b2;
|
||||
}
|
||||
</style>
|
||||
|
@ -21,6 +21,19 @@ export const HYPERLINKS = {
|
||||
content: 'http://'
|
||||
}
|
||||
|
||||
// 视频信息配置
|
||||
export const VIDEOLINKS = {
|
||||
autoplay: true,
|
||||
muted: true,
|
||||
loop: true,
|
||||
language: 'zh',
|
||||
controlBar: {
|
||||
fullscreenToggle: false
|
||||
},
|
||||
sources: [{
|
||||
}]
|
||||
}
|
||||
|
||||
export const assistList = [
|
||||
{
|
||||
id: '10001',
|
||||
@ -57,6 +70,14 @@ export const pictureList = [
|
||||
label: '拖拽上传',
|
||||
icon: 'iconfont icon-picture',
|
||||
defaultClass: 'text-filter'
|
||||
},
|
||||
{
|
||||
id: '20002',
|
||||
component: 'video',
|
||||
type: 'video',
|
||||
label: '视频',
|
||||
icon: 'iconfont icon-video',
|
||||
defaultClass: 'text-filter'
|
||||
}
|
||||
]
|
||||
|
||||
@ -275,6 +296,24 @@ const list = [
|
||||
y: 1,
|
||||
sizex: 10,
|
||||
sizey: 5
|
||||
},
|
||||
{
|
||||
id: '20002',
|
||||
component: 'de-video',
|
||||
type: 'de-video',
|
||||
label: '',
|
||||
icon: 'iconfont icon-picture',
|
||||
defaultClass: 'text-filter',
|
||||
style: {
|
||||
width: 400,
|
||||
height: 200,
|
||||
borderRadius: ''
|
||||
},
|
||||
videoLinks: VIDEOLINKS,
|
||||
x: 1,
|
||||
y: 1,
|
||||
sizex: 10,
|
||||
sizey: 5
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -6,6 +6,7 @@ import VButton from '@/components/canvas/custom-component/VButton'
|
||||
import Group from '@/components/canvas/custom-component/Group'
|
||||
import RectShape from '@/components/canvas/custom-component/RectShape'
|
||||
import UserView from '@/components/canvas/custom-component/UserView'
|
||||
import DeVideo from '@/components/canvas/custom-component/DeVideo'
|
||||
|
||||
Vue.component('Picture', Picture)
|
||||
Vue.component('VText', VText)
|
||||
@ -13,4 +14,5 @@ Vue.component('VButton', VButton)
|
||||
Vue.component('Group', Group)
|
||||
Vue.component('RectShape', RectShape)
|
||||
Vue.component('UserView', UserView)
|
||||
Vue.component('DeVideo', DeVideo)
|
||||
|
||||
|
180
frontend/src/custom-theme.css
Executable file
180
frontend/src/custom-theme.css
Executable file
@ -0,0 +1,180 @@
|
||||
.vjs-custom-skin > .video-js {
|
||||
width: 100%;
|
||||
font-family: "PingFang SC","Helvetica Neue","Hiragino Sans GB","Segoe UI","Microsoft YaHei","微软雅黑",sans-serif;
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-menu-button-inline.vjs-slider-active,.vjs-custom-skin > .video-js .vjs-menu-button-inline:focus,.vjs-custom-skin > .video-js .vjs-menu-button-inline:hover,.video-js.vjs-no-flex .vjs-menu-button-inline {
|
||||
width: 10em
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-controls-disabled .vjs-big-play-button {
|
||||
display: none!important
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-control {
|
||||
width: 3em
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-control.vjs-live-control{
|
||||
width: auto;
|
||||
padding-left: .5em;
|
||||
letter-spacing: .1em;
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-menu-button-inline:before {
|
||||
width: 1.5em
|
||||
}
|
||||
|
||||
.vjs-menu-button-inline .vjs-menu {
|
||||
left: 3em
|
||||
}
|
||||
|
||||
.vjs-paused.vjs-has-started.vjs-custom-skin > .video-js .vjs-big-play-button,.video-js.vjs-ended .vjs-big-play-button,.video-js.vjs-paused .vjs-big-play-button {
|
||||
display: block
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-load-progress div,.vjs-seeking .vjs-big-play-button,.vjs-waiting .vjs-big-play-button {
|
||||
display: none!important
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-mouse-display:after,.vjs-custom-skin > .video-js .vjs-play-progress:after {
|
||||
padding: 0 .4em .3em
|
||||
}
|
||||
|
||||
.video-js.vjs-ended .vjs-loading-spinner {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.video-js.vjs-ended .vjs-big-play-button {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.video-js.vjs-ended .vjs-big-play-button,.video-js.vjs-paused .vjs-big-play-button,.vjs-paused.vjs-has-started.vjs-custom-skin > .video-js .vjs-big-play-button {
|
||||
display: block
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-big-play-button {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-left: -1.5em;
|
||||
margin-top: -1em
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-big-play-button {
|
||||
background-color: rgba(0,0,0,0.45);
|
||||
font-size: 3.5em;
|
||||
/*border-radius: 50%;*/
|
||||
height: 2em !important;
|
||||
line-height: 2em !important;
|
||||
margin-top: -1em !important
|
||||
}
|
||||
|
||||
.video-js:hover .vjs-big-play-button,.vjs-custom-skin > .video-js .vjs-big-play-button:focus,.vjs-custom-skin > .video-js .vjs-big-play-button:active {
|
||||
background-color: rgba(36,131,213,0.9)
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-loading-spinner {
|
||||
border-color: rgba(36,131,213,0.8)
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-control-bar2 {
|
||||
background-color: #000000
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-control-bar {
|
||||
/*background-color: rgba(0,0,0,0.3) !important;*/
|
||||
color: #ffffff;
|
||||
font-size: 14px
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-play-progress,.vjs-custom-skin > .video-js .vjs-volume-level {
|
||||
background-color: #2483d5
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-play-progress:before {
|
||||
top: -0.3em;
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-progress-control:hover .vjs-progress-holder {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
.vjs-menu-button-popup.vjs-volume-menu-button-vertical .vjs-menu {
|
||||
left: 0em;
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-menu li {
|
||||
padding: 0;
|
||||
line-height: 2em;
|
||||
font-size: 1.1em;
|
||||
font-family: "PingFang SC","Helvetica Neue","Hiragino Sans GB","Segoe UI","Microsoft YaHei","微软雅黑",sans-serif;
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-time-tooltip,
|
||||
.vjs-custom-skin > .video-js .vjs-mouse-display:after,
|
||||
.vjs-custom-skin > .video-js .vjs-play-progress:after {
|
||||
border-radius: 0;
|
||||
font-size: 1em;
|
||||
padding: 0;
|
||||
width: 3em;
|
||||
height: 1.5em;
|
||||
line-height: 1.5em;
|
||||
top: -3em;
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-menu-button-popup .vjs-menu {
|
||||
width: 5em;
|
||||
left: -1em;
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-menu-button-popup.vjs-volume-menu-button-vertical .vjs-menu {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-control-bar .vjs-resolution-button .vjs-menu {
|
||||
/*order: 4;*/
|
||||
}
|
||||
|
||||
/*排序顺序*/
|
||||
.vjs-custom-skin > .video-js .vjs-control-bar .vjs-play-control {
|
||||
order: 0;
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-control-bar .vjs-time-control {
|
||||
min-width: 1em;
|
||||
padding: 0;
|
||||
margin: 0 .1em;
|
||||
text-align: center;
|
||||
display: block;
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-control-bar .vjs-playback-rate .vjs-playback-rate-value{
|
||||
font-size: 1.2em;
|
||||
line-height: 2.4;
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-progress-control.vjs-control {
|
||||
order: 2;
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-control-bar .vjs-volume-menu-button {
|
||||
order: 3;
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-control-bar .vjs-resolution-button {
|
||||
order: 4;
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-control-bar .vjs-resolution-button .vjs-resolution-button-label {
|
||||
display: block;
|
||||
line-height: 3em;
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-control-bar .vjs-playback-rate {
|
||||
order: 5;
|
||||
}
|
||||
|
||||
.vjs-custom-skin > .video-js .vjs-control-bar .vjs-fullscreen-control {
|
||||
order: 6;
|
||||
}
|
@ -82,6 +82,12 @@ Vue.config.productionTip = false
|
||||
import vueToPdf from 'vue-to-pdf'
|
||||
Vue.use(vueToPdf)
|
||||
|
||||
import VueVideoPlayer from 'vue-video-player'
|
||||
|
||||
import 'video.js/dist/video-js.css'
|
||||
|
||||
Vue.use(VueVideoPlayer)
|
||||
|
||||
Vue.prototype.hasDataPermission = function(pTarget, pSource) {
|
||||
if (this.$store.state.user.user.isAdmin) {
|
||||
return true
|
||||
|
@ -66,7 +66,10 @@ const data = {
|
||||
nowPanelJumpInfoTargetPanel: {}, // 当前仪表板的跳转信息(只包括仪表板)
|
||||
|
||||
// 拖拽的组件信息
|
||||
dragComponentInfo: null
|
||||
dragComponentInfo: null,
|
||||
|
||||
// 仪表板组件间隙大小 px
|
||||
componentGap: 5
|
||||
},
|
||||
mutations: {
|
||||
...animation.mutations,
|
||||
|
@ -54,6 +54,54 @@
|
||||
<div class="content unicode" style="display: block;">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">video</div>
|
||||
<div class="code-name">&#xe625;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">悬浮按钮发动态</div>
|
||||
<div class="code-name">&#xe6e8;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">吸附选择</div>
|
||||
<div class="code-name">&#xe697;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">margin</div>
|
||||
<div class="code-name">&#xe902;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">padding</div>
|
||||
<div class="code-name">&#xe91b;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">tabs</div>
|
||||
<div class="code-name">&#xe9a8;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">时间</div>
|
||||
<div class="code-name">&#xe665;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">时间格式转换</div>
|
||||
<div class="code-name">&#xe6fb;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">超链接</div>
|
||||
@ -102,12 +150,6 @@
|
||||
<div class="code-name">&#xe8e6;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">44.tabs</div>
|
||||
<div class="code-name">&#xe62a;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">洗浴</div>
|
||||
@ -420,9 +462,9 @@
|
||||
<pre><code class="language-css"
|
||||
>@font-face {
|
||||
font-family: 'iconfont';
|
||||
src: url('iconfont.woff2?t=1634191971474') format('woff2'),
|
||||
url('iconfont.woff?t=1634191971474') format('woff'),
|
||||
url('iconfont.ttf?t=1634191971474') format('truetype');
|
||||
src: url('iconfont.woff2?t=1636358286475') format('woff2'),
|
||||
url('iconfont.woff?t=1636358286475') format('woff'),
|
||||
url('iconfont.ttf?t=1636358286475') format('truetype');
|
||||
}
|
||||
</code></pre>
|
||||
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
||||
@ -448,6 +490,78 @@
|
||||
<div class="content font-class">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-video"></span>
|
||||
<div class="name">
|
||||
video
|
||||
</div>
|
||||
<div class="code-name">.icon-video
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-xuanfuanniufadongtai"></span>
|
||||
<div class="name">
|
||||
悬浮按钮发动态
|
||||
</div>
|
||||
<div class="code-name">.icon-xuanfuanniufadongtai
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-xifuxuanze"></span>
|
||||
<div class="name">
|
||||
吸附选择
|
||||
</div>
|
||||
<div class="code-name">.icon-xifuxuanze
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-margin"></span>
|
||||
<div class="name">
|
||||
margin
|
||||
</div>
|
||||
<div class="code-name">.icon-margin
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-padding"></span>
|
||||
<div class="name">
|
||||
padding
|
||||
</div>
|
||||
<div class="code-name">.icon-padding
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-tabs"></span>
|
||||
<div class="name">
|
||||
tabs
|
||||
</div>
|
||||
<div class="code-name">.icon-tabs
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-shijian"></span>
|
||||
<div class="name">
|
||||
时间
|
||||
</div>
|
||||
<div class="code-name">.icon-shijian
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-shijiangeshizhuanhuan"></span>
|
||||
<div class="name">
|
||||
时间格式转换
|
||||
</div>
|
||||
<div class="code-name">.icon-shijiangeshizhuanhuan
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-chaolianjie"></span>
|
||||
<div class="name">
|
||||
@ -520,15 +634,6 @@
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-tabs"></span>
|
||||
<div class="name">
|
||||
44.tabs
|
||||
</div>
|
||||
<div class="code-name">.icon-tabs
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-xiyu"></span>
|
||||
<div class="name">
|
||||
@ -997,6 +1102,70 @@
|
||||
<div class="content symbol">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-video"></use>
|
||||
</svg>
|
||||
<div class="name">video</div>
|
||||
<div class="code-name">#icon-video</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-xuanfuanniufadongtai"></use>
|
||||
</svg>
|
||||
<div class="name">悬浮按钮发动态</div>
|
||||
<div class="code-name">#icon-xuanfuanniufadongtai</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-xifuxuanze"></use>
|
||||
</svg>
|
||||
<div class="name">吸附选择</div>
|
||||
<div class="code-name">#icon-xifuxuanze</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-margin"></use>
|
||||
</svg>
|
||||
<div class="name">margin</div>
|
||||
<div class="code-name">#icon-margin</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-padding"></use>
|
||||
</svg>
|
||||
<div class="name">padding</div>
|
||||
<div class="code-name">#icon-padding</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-tabs"></use>
|
||||
</svg>
|
||||
<div class="name">tabs</div>
|
||||
<div class="code-name">#icon-tabs</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-shijian"></use>
|
||||
</svg>
|
||||
<div class="name">时间</div>
|
||||
<div class="code-name">#icon-shijian</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-shijiangeshizhuanhuan"></use>
|
||||
</svg>
|
||||
<div class="name">时间格式转换</div>
|
||||
<div class="code-name">#icon-shijiangeshizhuanhuan</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-chaolianjie"></use>
|
||||
@ -1061,14 +1230,6 @@
|
||||
<div class="code-name">#icon-xuanfuanniu</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-tabs"></use>
|
||||
</svg>
|
||||
<div class="name">44.tabs</div>
|
||||
<div class="code-name">#icon-tabs</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-xiyu"></use>
|
||||
|
@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2459092 */
|
||||
src: url('iconfont.woff2?t=1634802523514') format('woff2'),
|
||||
url('iconfont.woff?t=1634802523514') format('woff'),
|
||||
url('iconfont.ttf?t=1634802523514') format('truetype');
|
||||
src: url('iconfont.woff2?t=1636358286475') format('woff2'),
|
||||
url('iconfont.woff?t=1636358286475') format('woff'),
|
||||
url('iconfont.ttf?t=1636358286475') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@ -13,6 +13,18 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-video:before {
|
||||
content: "\e625";
|
||||
}
|
||||
|
||||
.icon-xuanfuanniufadongtai:before {
|
||||
content: "\e6e8";
|
||||
}
|
||||
|
||||
.icon-xifuxuanze:before {
|
||||
content: "\e697";
|
||||
}
|
||||
|
||||
.icon-margin:before {
|
||||
content: "\e902";
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -5,6 +5,27 @@
|
||||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "5994030",
|
||||
"name": "video",
|
||||
"font_class": "video",
|
||||
"unicode": "e625",
|
||||
"unicode_decimal": 58917
|
||||
},
|
||||
{
|
||||
"icon_id": "18545906",
|
||||
"name": "悬浮按钮发动态",
|
||||
"font_class": "xuanfuanniufadongtai",
|
||||
"unicode": "e6e8",
|
||||
"unicode_decimal": 59112
|
||||
},
|
||||
{
|
||||
"icon_id": "21285292",
|
||||
"name": "吸附选择",
|
||||
"font_class": "xifuxuanze",
|
||||
"unicode": "e697",
|
||||
"unicode_decimal": 59031
|
||||
},
|
||||
{
|
||||
"icon_id": "924440",
|
||||
"name": "margin",
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -27,7 +27,7 @@
|
||||
<div class="widget-subject">
|
||||
<div class="filter-header">
|
||||
<div class="filter-header-text">
|
||||
<span>图片</span>
|
||||
<span>多媒体</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -289,7 +289,8 @@ export default {
|
||||
'picture-add',
|
||||
'de-tabs',
|
||||
'rect-shape',
|
||||
'de-show-date'
|
||||
'de-show-date',
|
||||
'de-video'
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -551,15 +552,12 @@ export default {
|
||||
})
|
||||
} else {
|
||||
this.currentWidget = ApplicationContext.getService(componentInfo.id)
|
||||
|
||||
this.currentFilterCom = this.currentWidget.getDrawPanel()
|
||||
|
||||
if (this.canvasStyleData.auxiliaryMatrix) {
|
||||
this.currentFilterCom.x = this.dropComponentInfo.x
|
||||
this.currentFilterCom.y = this.dropComponentInfo.y
|
||||
this.currentFilterCom.sizex = this.dropComponentInfo.sizex
|
||||
this.currentFilterCom.sizey = this.dropComponentInfo.sizey
|
||||
|
||||
this.currentFilterCom.style.left = (this.dragComponentInfo.x - 1) * this.curCanvasScale.matrixStyleOriginWidth
|
||||
this.currentFilterCom.style.top = (this.dragComponentInfo.y - 1) * this.curCanvasScale.matrixStyleOriginHeight
|
||||
this.currentFilterCom.style.width = this.dragComponentInfo.sizex * this.curCanvasScale.matrixStyleOriginWidth
|
||||
@ -608,14 +606,6 @@ export default {
|
||||
this.$store.commit('addComponent', { component })
|
||||
this.$store.commit('recordSnapshot', 'handleDrop')
|
||||
this.clearCurrentInfo()
|
||||
// this.$store.commit('clearDragComponentInfo')
|
||||
|
||||
// // 文字组件
|
||||
// if (component.type === 'v-text') {
|
||||
// this.$store.commit('setCurComponent', { component: component, index: this.componentData.length })
|
||||
// this.styleDialogVisible = true
|
||||
// this.show = false
|
||||
// }
|
||||
},
|
||||
clearCurrentInfo() {
|
||||
this.currentWidget = null
|
||||
|
24
frontend/src/views/panel/video/index.vue
Normal file
24
frontend/src/views/panel/video/index.vue
Normal file
@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<DeVideo />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import DeVideo from '@/components/canvas/custom-component/DeVideo'
|
||||
export default {
|
||||
name: 'Video',
|
||||
components: { DeVideo },
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user