Browse Source

视频组件完整效果实现

yjf_v2
liwenxuan 2 years ago
parent
commit
b8d6b77945
  1. 2
      src/api/DesignForm/types.ts
  2. 22
      src/components/DesignForm/assembly/index.ts
  3. 222
      src/components/DesignForm/formControlAttr.vue
  4. 1
      src/components/DesignForm/public/form/form.vue
  5. 3
      src/main.ts
  6. 25
      src/store/modules/lowcodevideo.ts
  7. 2
      src/views/sysworkflow/codepage/createform.vue
  8. 2
      src/widget/videoupload/index.vue
  9. 26
      src/widget/videoupload/videoUploadPlay.vue

2
src/api/DesignForm/types.ts

@ -172,6 +172,6 @@ export interface VideoMsg {
videoWidth?:number//视频宽
videoAutoPlay:boolean//是否自动播放
attrId:string//字段标识 e.g : videoUpAndPlay1705024134559
poster?:string//海报帧url
poster?:string//视频封面url
loop:boolean//是否循环播放
}

22
src/components/DesignForm/assembly/index.ts

@ -313,7 +313,27 @@ const selectOption: any = [
icon: '',
iconFont: 'fa-play-circle',
control: {
modelValue: ''
modelValue: '',
videoMsg:[{
CreatedAt: '',
UpdatedAt: '',
fileSize: "0n",
id: "0n",
key: '',
name: '',
physicspath: '',
size: '',
tag: '',
type: 0,
url: '',
videoReady: false,
videoHeight:400,
videoWidth:700,
videoAutoPlay: false,
attrId: '',
poster:'',
loop: false
}]
},
config: {}
},

222
src/components/DesignForm/formControlAttr.vue

@ -39,6 +39,7 @@ const props = withDefaults( //接收父级参数
const emits = defineEmits<{
(e: 'openDialog', data: any): void
(e: 'update:formOtherData', data: any): void
(e: 'videoMsgChange', data: VideoMsg): void
//(e: 'update:formData', data: any): void
//(e: 'update:formConfig', data: any): void
}>()
@ -188,6 +189,7 @@ const attrList = computed(() => {
columnIndex = list[0].type === 'index'
}
}
const temp =reactive<PublicAtrr[]>([
{
label: '自定义Class',
@ -604,16 +606,24 @@ const attrList = computed(() => {
vIf: state.isSearch,
vShow: ['videoUpAndPlay']
},
/* {
label: '上传视频封面',
value: config.uploadvideo,
path: 'config.uploadvideo',
type: 'uploadvideo_poster',
vIf: state.isSearch,
vShow: ['videoUpAndPlay']
}, */
{
label: '视频自动播放',
label: '视频宽度(像素)',
value: config.uploadvideo,
path: 'config.uploadvideo',
type: 'uploadvideo_autoPlay',
type: 'uploadvideo_width',
vIf: state.isSearch,
vShow: ['videoUpAndPlay']
},
{
label: '视频高度',
label: '视频高度(像素)',
value: config.uploadvideo,
path: 'config.uploadvideo',
type: 'uploadvideo_height',
@ -621,13 +631,23 @@ const attrList = computed(() => {
vShow: ['videoUpAndPlay']
},
{
label: '视频宽度',
label: '视频自动播放',
value: config.uploadvideo,
path: 'config.uploadvideo',
type: 'uploadvideo_width',
type: 'uploadvideo_autoPlay',
vIf: state.isSearch,
vShow: ['videoUpAndPlay']
},
{
label: '视频循环播放',
value: config.uploadvideo,
path: 'config.uploadvideo',
type: 'uploadvideo_loopPlay',
vIf: state.isSearch,
vShow: ['videoUpAndPlay']
},
{
label: '上传地址',
value: control.action,
@ -817,6 +837,7 @@ watch(
}
}
)
const fileSignAry = reactive<any>([])
const controlChange = (obj: any, val: any) => {
console.log("字段编辑----》",obj,val,controlData.value)
@ -1252,17 +1273,10 @@ const isNotWrite = (val:any) =>{
}
//liwenxuan 20240108 vidioupload start
import uselowcodevideoStore from '@/store/modules/lowcodevideo'
import { VideoMsg } from '@/api/DesignForm/types'
const lowcodevideoStore = uselowcodevideoStore();
const videoAutoPlay = ref(false);
const videoHeight = ref(400);
const videoWidth = ref(700);
//const emits = defineEmits(["addedVideo"]);
//
function videoUploadOk(response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) {
//,videoMsg
const videoMsg:VideoMsg = {
const videoIndex = ref(0);
const videoMsgArr:VideoMsg[] = reactive<VideoMsg[]>([{
CreatedAt: '',
UpdatedAt: '',
fileSize: 0n,
@ -1274,51 +1288,104 @@ function videoUploadOk(response: any, uploadFile: UploadFile, uploadFiles: Uploa
tag: '',
type: 0,
url: '',
videoAutoPlay: false,
videoReady: false,
videoHeight:400,
videoWidth:700,
videoAutoPlay: false,
attrId: '',
poster:'',
loop: false
}]);
/* //监听当前操作视频的变化
watch(videoMsgArr[videoIndex.value], () => {
//
// `newValue` `oldValue`
//
emits('videoMsgChange',videoMsgArr[videoIndex.value]);
},{deep:true})
function setVideoIndex(newValue:any,oldValue:any){
//alert(videoIndex.value)
const result = videoMsgArr.findIndex(function(item) {
item.attrId === newValue.activeKey;
});
if(result!=-1){
videoIndex.value = result;
}
videoMsg.url = response.data.url;
videoMsg.videoReady = true;
console.log(response)
console.log(lowcodevideoStore);
videoMsg.CreatedAt = response.data.CreatedAt;
videoMsg.UpdatedAt = response.data.UpdatedAt;
videoMsg.fileSize = response.data.fileSize;
videoMsg.id = response.data.id;
videoMsg.key = response.data.key;
videoMsg.name = response.data.name;
videoMsg.physicspath = response.data.physicspath;
videoMsg.size = response.data.size;
videoMsg.tag = response.data.tag;
videoMsg.type = response.data.type;
//emits("addedVideo",videoArr)''
console.log("response.data.url----2------>",response.data.url)
//formConfig.value["hjk"] = 250
console.log("formConfig----3------>",formConfig.value)
console.log("attrList----1------>",attrList.value)
if(attrList.value.length > 0){
attrList.value.forEach((item:any)=>{
// console.log("attrList---item-1------>",item.type)
console.log("attrList---item-1------>",item)
if(item.type === "uploadvideo_url"){
item.config={
videoConfig:[
{
videoUrl:response.data.url,
videoAutoPlay:videoAutoPlay,
videoHeight:videoHeight,
videoWidth:videoWidth
}
]
}
//alert(videoIndex.value)
}
*/
/* const LastEdit = {
oldKey:'',
oldType:'',
}
//,,videoIndex
watch(
() => store, (newValue, oldValue) => {
//alert("newValue:"+newValue+",oldValue:"+oldValue)
let newKey = newValue.activeKey;
//alert("newKey==="+newKey+"|||oldKey==="+LastEdit.oldKey)
if(oldValue==undefined){
//alert('')
}else{
// if(LastEdit.oldKey===''){
// alert("")
//}else{
// if(newKey===''){
// alert('')
// }else{
// alert("")
// }
//}
//else
LastEdit.oldKey = newKey
LastEdit.oldType = newValue.controlAttr.type
}
});
if(newValue.controlAttr.type==='videoUpAndPlay'){
console.log('是视频')
}
console.log("attrList---item-2------>",attrList.value)
},{deep:true}
) */
//
function videoUploadOk(response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) {
const { control = {} } : { control: any } = controlData.value
control.videoMsg[videoIndex.value].url = response.data.url;
control.videoMsg[videoIndex.value].videoReady = true;
control.videoMsg[videoIndex.value].CreatedAt = response.data.CreatedAt;
control.videoMsg[videoIndex.value].UpdatedAt = response.data.UpdatedAt;
control.videoMsg[videoIndex.value].fileSize = response.data.fileSize;
control.videoMsg[videoIndex.value].id = response.data.id;
control.videoMsg[videoIndex.value].key = response.data.key;
control.videoMsg[videoIndex.value].name = response.data.name;
control.videoMsg[videoIndex.value].physicspath = response.data.physicspath;
control.videoMsg[videoIndex.value].size = response.data.size;
control.videoMsg[videoIndex.value].tag = response.data.tag;
control.videoMsg[videoIndex.value].type = response.data.type;
// controlData.value.control.videoMsg = [videoMsgArr]
}
//
@ -1330,18 +1397,13 @@ function beforeRemove(){
function videoUploadErr(error: Error, uploadFile: UploadFile, uploadFiles: UploadFiles){
alert("上传失败,请重试")
console.log("上传失败"+error);
}
//,videosrc
/* function selectVideo(uploadFile: UploadFile){
const res:any = uploadFile.response;
const resd = res.data;
const resdurl = resd.url;
lowcodevideoStore.videoResource = resdurl;
} */
//liwenxuan 20240108 vidioupload end
//liwenxuan 20240111 carousel start
const direction = ref('ltr')
const drawer = ref(false)
@ -1393,8 +1455,9 @@ const handleClose = (done: () => void) => {
/>
<el-row v-else-if="item.type === 'uploadvideo_url'">
<!-- {{ controlData.control }} -->
<el-upload
v-if="!lowcodevideoStore.videoReady"
v-if="!controlData.control.videoMsg[videoIndex].videoReady"
:action="uploadUrl" :before-remove="beforeRemove"
:on-success="videoUploadOk" :show-file-list="true"
:on-error="videoUploadErr"
@ -1402,16 +1465,39 @@ const handleClose = (done: () => void) => {
accept=".mp4,.MOV,.WMV,.FLV,.AVI,.AVCHD,.WebM,.MKV,.rmvb">
<el-button type="primary">点此上传</el-button>
</el-upload>
<el-button v-if="lowcodevideoStore.videoReady" type="primary">已上传,点击修改</el-button>
<el-button v-if="controlData.control.videoMsg[videoIndex].videoReady" type="primary">已上传<!-- ,点击修改 --></el-button>
</el-row>
<!-- <el-row v-else-if="item.type === 'uploadvideo_poster'">
<el-upload
v-if="controlData.control.videoMsg[videoIndex].videoReady&&controlData.control.videoMsg[videoIndex].poster===''"
:action="uploadUrl" :before-remove="beforeRemove"
:on-success="videoUploadOk" :show-file-list="true"
:on-error="videoUploadErr"
accept=".mp4,.MOV,.WMV,.FLV,.AVI,.AVCHD,.WebM,.MKV,.rmvb">
<el-tooltip
class="box-item"
content="不上传则视频封面默认为视频第一帧"
placement="top-end"
>
<el-button type="primary">点此上传</el-button>
</el-tooltip>
</el-upload>
<el-button v-if="!controlData.control[videoIndex].videoReady" type="warning">请先上传视频</el-button>
<el-button v-if="controlData.control.videoMsg[videoIndex].videoReady&&controlData.control.videoMsg[videoIndex].poster!=''" type="primary">已上传,点击修改</el-button>
</el-row> -->
<el-row v-else-if="item.type === 'uploadvideo_autoPlay'">
<el-switch v-model="videoAutoPlay" />
<el-switch v-model="controlData.control.videoMsg[videoIndex].videoAutoPlay" />
</el-row>
<el-row v-else-if="item.type === 'uploadvideo_loopPlay'">
<el-switch v-model="controlData.control.videoMsg[videoIndex].loop" />
</el-row>
<el-row v-else-if="item.type === 'uploadvideo_width'">
<el-input-number v-model="videoWidth" :step="50" :max="4096"/>
<el-input-number v-model="controlData.control.videoMsg[videoIndex].videoWidth" :step="50" :max="4096"/>
</el-row>
<el-row v-else-if="item.type === 'uploadvideo_height'">
<el-input-number v-model="videoHeight" :step="50" :max="2160"/>
<el-input-number v-model="controlData.control.videoMsg[videoIndex].videoHeight" :step="50" :max="2160"/>
</el-row>
<el-row v-else-if="item.type === 'carousel'">

1
src/components/DesignForm/public/form/form.vue

@ -1006,6 +1006,7 @@ defineExpose({
'detail-form': type === 3 || type === 4
}"
>
<FormGroup :tableinfo="formData.form" :numrun="numrun" :data="formData.list" />
<slot></slot>
</el-form>

3
src/main.ts

@ -26,6 +26,7 @@ import '@/styles/workflowcss/override-element-ui.scss'
import ComComponents from '@/components/DesignForm/index'
import ComWidget from '@/widget/index'
import AKDesign from '@/views/sysworkflow/codepage/index'
import * as pinia from './store/index'
const app = createApp(App);
// 全局注册 自定义指令(directive)
@ -45,6 +46,6 @@ app.directive('focus', {
app.use(router).use(i18n).use(ComComponents).use(ComWidget).use(ElementPlus, {
locale: zhCn
}).use(AKDesign).mount('#app');
}).use(AKDesign).use(pinia.store).mount('#app');

25
src/store/modules/lowcodevideo.ts

@ -14,22 +14,21 @@ let uselowcodevideoStore = defineStore('lowcodevideo', () => {
//const videoReady = ref(false);
//成功后接受的视频详细信息
const videoMsg = reactive<VideoMsg>({
CreatedAt: '',
UpdatedAt: '',
CreatedAt: "",
UpdatedAt: "",
fileSize: 0n,
id: 0n,
key: '',
name: '',
physicspath: '',
size: '',
tag: '',
key: "",
name: "",
physicspath: "",
size: "",
tag: "",
type: 0,
url: '',
videoAutoPlay:false,
videoHeight:400,
videoWidth:700,
videoReady:false,
attrId:'',//字段标识 e.g : videoUpAndPlay1705024134559
url: "",
videoReady: false,
videoAutoPlay: false,
attrId: "",
loop: false
});
const videoMsgUse = reactive<VideoMsg[]>([])
const videoOnShowIndex = ref(0);//当当前表单有多个视频控件时,字段配置栏目前所展示的视频属性在pinia数组中的索引,用来在formControlAttr.vue中的dom属性上绑定显示数据

2
src/views/sysworkflow/codepage/createform.vue

@ -32,7 +32,7 @@ import AceDrawer from '@/components/DesignForm/aceDrawer.vue'
import { ref, reactive, provide, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { useLayoutStore } from '@/store/DesignForm/layout'
import { FormData,formStruct,DrawerStruct } from '@/api/DesignForm/types'
import { FormData,formStruct,DrawerStruct, VideoMsg } from '@/api/DesignForm/types'
import { customerFormVersionCont } from '@/api/DesignForm/type'
import { saveProductionForm,getOneProductionForm,haveCustomerFormVersion,editCustomerFormInfo,saveAsNewVersion,enableVersion,judgeSubmitCancel } from '@/api/DesignForm/requestapi'

2
src/widget/videoupload/index.vue

@ -14,7 +14,7 @@
<input v-model="value" type="hidden" >
</el-form-item>
<VideoUploadPlay @added-video="addedVideo"></VideoUploadPlay>
<VideoUploadPlay :data="props.data" @added-video="addedVideo"></VideoUploadPlay>
</template>
<script lang='ts' setup>
import VideoUploadPlay from './videoUploadPlay.vue';

26
src/widget/videoupload/videoUploadPlay.vue

@ -1,12 +1,30 @@
<template>
<video :src="videoUrl" loop controls></video>
<!-- <p>{{ videoHeight }}</p>
<p>{{ videoWidth }}</p> -->
<video
:src="data?.control.videoMsg[0].url"
:loop="data?.control.videoMsg[0].loop"
:autoplay="data?.control.videoMsg[0].videoAutoPlay"
:style="{height:videoHeight,width:videoWidth}"
controls
>
</video>
</template>
<script setup lang="ts">
import uselowcodevideoStore from '@/store/modules/lowcodevideo'
const lowcodevideoStore = uselowcodevideoStore();
const videoUrl = "";
const props = defineProps({
// eslint-disable-next-line vue/require-default-prop
data: {
type: Object,
}
})
const videoHeight = props.data?.control.videoMsg[0].videoHeight+'px'
const videoWidth = props.data?.control.videoMsg[0].videoWidth+'px'
</script>

Loading…
Cancel
Save