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//视频宽 videoWidth?:number//视频宽
videoAutoPlay:boolean//是否自动播放 videoAutoPlay:boolean//是否自动播放
attrId:string//字段标识 e.g : videoUpAndPlay1705024134559 attrId:string//字段标识 e.g : videoUpAndPlay1705024134559
poster?:string//海报帧url poster?:string//视频封面url
loop:boolean//是否循环播放 loop:boolean//是否循环播放
} }

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

@ -313,7 +313,27 @@ const selectOption: any = [
icon: '', icon: '',
iconFont: 'fa-play-circle', iconFont: 'fa-play-circle',
control: { 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: {} config: {}
}, },

222
src/components/DesignForm/formControlAttr.vue

@ -39,6 +39,7 @@ const props = withDefaults( //接收父级参数
const emits = defineEmits<{ const emits = defineEmits<{
(e: 'openDialog', data: any): void (e: 'openDialog', data: any): void
(e: 'update:formOtherData', data: any): void (e: 'update:formOtherData', data: any): void
(e: 'videoMsgChange', data: VideoMsg): void
//(e: 'update:formData', data: any): void //(e: 'update:formData', data: any): void
//(e: 'update:formConfig', data: any): void //(e: 'update:formConfig', data: any): void
}>() }>()
@ -188,6 +189,7 @@ const attrList = computed(() => {
columnIndex = list[0].type === 'index' columnIndex = list[0].type === 'index'
} }
} }
const temp =reactive<PublicAtrr[]>([ const temp =reactive<PublicAtrr[]>([
{ {
label: '自定义Class', label: '自定义Class',
@ -604,16 +606,24 @@ const attrList = computed(() => {
vIf: state.isSearch, vIf: state.isSearch,
vShow: ['videoUpAndPlay'] vShow: ['videoUpAndPlay']
}, },
/* {
label: '上传视频封面',
value: config.uploadvideo,
path: 'config.uploadvideo',
type: 'uploadvideo_poster',
vIf: state.isSearch,
vShow: ['videoUpAndPlay']
}, */
{ {
label: '视频自动播放', label: '视频宽度(像素)',
value: config.uploadvideo, value: config.uploadvideo,
path: 'config.uploadvideo', path: 'config.uploadvideo',
type: 'uploadvideo_autoPlay', type: 'uploadvideo_width',
vIf: state.isSearch, vIf: state.isSearch,
vShow: ['videoUpAndPlay'] vShow: ['videoUpAndPlay']
}, },
{ {
label: '视频高度', label: '视频高度(像素)',
value: config.uploadvideo, value: config.uploadvideo,
path: 'config.uploadvideo', path: 'config.uploadvideo',
type: 'uploadvideo_height', type: 'uploadvideo_height',
@ -621,13 +631,23 @@ const attrList = computed(() => {
vShow: ['videoUpAndPlay'] vShow: ['videoUpAndPlay']
}, },
{ {
label: '视频宽度', label: '视频自动播放',
value: config.uploadvideo, value: config.uploadvideo,
path: '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, vIf: state.isSearch,
vShow: ['videoUpAndPlay'] vShow: ['videoUpAndPlay']
}, },
{ {
label: '上传地址', label: '上传地址',
value: control.action, value: control.action,
@ -817,6 +837,7 @@ watch(
} }
} }
) )
const fileSignAry = reactive<any>([]) const fileSignAry = reactive<any>([])
const controlChange = (obj: any, val: any) => { const controlChange = (obj: any, val: any) => {
console.log("字段编辑----》",obj,val,controlData.value) console.log("字段编辑----》",obj,val,controlData.value)
@ -1252,17 +1273,10 @@ const isNotWrite = (val:any) =>{
} }
//liwenxuan 20240108 vidioupload start //liwenxuan 20240108 vidioupload start
import uselowcodevideoStore from '@/store/modules/lowcodevideo'
import { VideoMsg } from '@/api/DesignForm/types' import { VideoMsg } from '@/api/DesignForm/types'
const lowcodevideoStore = uselowcodevideoStore(); const videoIndex = ref(0);
const videoAutoPlay = ref(false); const videoMsgArr:VideoMsg[] = reactive<VideoMsg[]>([{
const videoHeight = ref(400);
const videoWidth = ref(700);
//const emits = defineEmits(["addedVideo"]);
//
function videoUploadOk(response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) {
//,videoMsg
const videoMsg:VideoMsg = {
CreatedAt: '', CreatedAt: '',
UpdatedAt: '', UpdatedAt: '',
fileSize: 0n, fileSize: 0n,
@ -1274,51 +1288,104 @@ function videoUploadOk(response: any, uploadFile: UploadFile, uploadFiles: Uploa
tag: '', tag: '',
type: 0, type: 0,
url: '', url: '',
videoAutoPlay: false,
videoReady: false, videoReady: false,
videoHeight:400,
videoWidth:700,
videoAutoPlay: false,
attrId: '', attrId: '',
poster:'',
loop: false 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; //alert(videoIndex.value)
videoMsg.videoReady = true; }
console.log(response)
console.log(lowcodevideoStore);
videoMsg.CreatedAt = response.data.CreatedAt; */
videoMsg.UpdatedAt = response.data.UpdatedAt;
videoMsg.fileSize = response.data.fileSize; /* const LastEdit = {
videoMsg.id = response.data.id; oldKey:'',
videoMsg.key = response.data.key; oldType:'',
videoMsg.name = response.data.name; }
videoMsg.physicspath = response.data.physicspath; //,,videoIndex
videoMsg.size = response.data.size; watch(
videoMsg.tag = response.data.tag; () => store, (newValue, oldValue) => {
videoMsg.type = response.data.type; //alert("newValue:"+newValue+",oldValue:"+oldValue)
let newKey = newValue.activeKey;
//emits("addedVideo",videoArr)'' //alert("newKey==="+newKey+"|||oldKey==="+LastEdit.oldKey)
console.log("response.data.url----2------>",response.data.url)
//formConfig.value["hjk"] = 250 if(oldValue==undefined){
console.log("formConfig----3------>",formConfig.value) //alert('')
console.log("attrList----1------>",attrList.value)
}else{
if(attrList.value.length > 0){
attrList.value.forEach((item:any)=>{ // if(LastEdit.oldKey===''){
// console.log("attrList---item-1------>",item.type) // alert("")
console.log("attrList---item-1------>",item) //}else{
if(item.type === "uploadvideo_url"){ // if(newKey===''){
item.config={ // alert('')
videoConfig:[ // }else{
{ // alert("")
videoUrl:response.data.url, // }
videoAutoPlay:videoAutoPlay, //}
videoHeight:videoHeight, //else
videoWidth:videoWidth 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){ function videoUploadErr(error: Error, uploadFile: UploadFile, uploadFiles: UploadFiles){
alert("上传失败,请重试") alert("上传失败,请重试")
console.log("上传失败"+error); 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 20240108 vidioupload end
//liwenxuan 20240111 carousel start //liwenxuan 20240111 carousel start
const direction = ref('ltr') const direction = ref('ltr')
const drawer = ref(false) const drawer = ref(false)
@ -1393,8 +1455,9 @@ const handleClose = (done: () => void) => {
/> />
<el-row v-else-if="item.type === 'uploadvideo_url'"> <el-row v-else-if="item.type === 'uploadvideo_url'">
<!-- {{ controlData.control }} -->
<el-upload <el-upload
v-if="!lowcodevideoStore.videoReady" v-if="!controlData.control.videoMsg[videoIndex].videoReady"
:action="uploadUrl" :before-remove="beforeRemove" :action="uploadUrl" :before-remove="beforeRemove"
:on-success="videoUploadOk" :show-file-list="true" :on-success="videoUploadOk" :show-file-list="true"
:on-error="videoUploadErr" :on-error="videoUploadErr"
@ -1402,16 +1465,39 @@ const handleClose = (done: () => void) => {
accept=".mp4,.MOV,.WMV,.FLV,.AVI,.AVCHD,.WebM,.MKV,.rmvb"> accept=".mp4,.MOV,.WMV,.FLV,.AVI,.AVCHD,.WebM,.MKV,.rmvb">
<el-button type="primary">点此上传</el-button> <el-button type="primary">点此上传</el-button>
</el-upload> </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>
<!-- <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-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>
<el-row v-else-if="item.type === 'uploadvideo_width'"> <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>
<el-row v-else-if="item.type === 'uploadvideo_height'"> <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>
<el-row v-else-if="item.type === 'carousel'"> <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 'detail-form': type === 3 || type === 4
}" }"
> >
<FormGroup :tableinfo="formData.form" :numrun="numrun" :data="formData.list" /> <FormGroup :tableinfo="formData.form" :numrun="numrun" :data="formData.list" />
<slot></slot> <slot></slot>
</el-form> </el-form>

3
src/main.ts

@ -26,6 +26,7 @@ import '@/styles/workflowcss/override-element-ui.scss'
import ComComponents from '@/components/DesignForm/index' import ComComponents from '@/components/DesignForm/index'
import ComWidget from '@/widget/index' import ComWidget from '@/widget/index'
import AKDesign from '@/views/sysworkflow/codepage/index' import AKDesign from '@/views/sysworkflow/codepage/index'
import * as pinia from './store/index'
const app = createApp(App); const app = createApp(App);
// 全局注册 自定义指令(directive) // 全局注册 自定义指令(directive)
@ -45,6 +46,6 @@ app.directive('focus', {
app.use(router).use(i18n).use(ComComponents).use(ComWidget).use(ElementPlus, { app.use(router).use(i18n).use(ComComponents).use(ComWidget).use(ElementPlus, {
locale: zhCn 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 videoReady = ref(false);
//成功后接受的视频详细信息 //成功后接受的视频详细信息
const videoMsg = reactive<VideoMsg>({ const videoMsg = reactive<VideoMsg>({
CreatedAt: '', CreatedAt: "",
UpdatedAt: '', UpdatedAt: "",
fileSize: 0n, fileSize: 0n,
id: 0n, id: 0n,
key: '', key: "",
name: '', name: "",
physicspath: '', physicspath: "",
size: '', size: "",
tag: '', tag: "",
type: 0, type: 0,
url: '', url: "",
videoAutoPlay:false, videoReady: false,
videoHeight:400, videoAutoPlay: false,
videoWidth:700, attrId: "",
videoReady:false, loop: false
attrId:'',//字段标识 e.g : videoUpAndPlay1705024134559
}); });
const videoMsgUse = reactive<VideoMsg[]>([]) const videoMsgUse = reactive<VideoMsg[]>([])
const videoOnShowIndex = ref(0);//当当前表单有多个视频控件时,字段配置栏目前所展示的视频属性在pinia数组中的索引,用来在formControlAttr.vue中的dom属性上绑定显示数据 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 { ref, reactive, provide, onMounted } from 'vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { useLayoutStore } from '@/store/DesignForm/layout' 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 { customerFormVersionCont } from '@/api/DesignForm/type'
import { saveProductionForm,getOneProductionForm,haveCustomerFormVersion,editCustomerFormInfo,saveAsNewVersion,enableVersion,judgeSubmitCancel } from '@/api/DesignForm/requestapi' 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" > <input v-model="value" type="hidden" >
</el-form-item> </el-form-item>
<VideoUploadPlay @added-video="addedVideo"></VideoUploadPlay> <VideoUploadPlay :data="props.data" @added-video="addedVideo"></VideoUploadPlay>
</template> </template>
<script lang='ts' setup> <script lang='ts' setup>
import VideoUploadPlay from './videoUploadPlay.vue'; import VideoUploadPlay from './videoUploadPlay.vue';

26
src/widget/videoupload/videoUploadPlay.vue

@ -1,12 +1,30 @@
<template> <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> </template>
<script setup lang="ts"> <script setup lang="ts">
import uselowcodevideoStore from '@/store/modules/lowcodevideo'
const lowcodevideoStore = uselowcodevideoStore(); const props = defineProps({
const videoUrl = ""; // 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> </script>

Loading…
Cancel
Save