174 lines
4.1 KiB
Vue
Raw Normal View History

2024-04-28 10:10:03 +08:00
<template>
<!-- <component v-if="formProps.isCodeForm" :mode="formProps.mode" ref="codeFormCp" :perm="props.readonly ? 'R':'E'"
:key="formProps.path" :is="codeForm" @input="change" v-bind="_formProps" v-model="_value" />
<web-view :id="'urlForm_' + formProps.path" v-else :src="formProps.formPath" width="100%"
:height="formProps.height"></web-view> -->
<text style="color: #F6D589;">努力开发中</text>
</template>
<script setup>
import { ref, computed, onMounted, onBeforeUnmount, defineAsyncComponent } from 'vue'
const props = defineProps({
formProps: {
type: Object,
default: () => {
return {}
}
},
modelValue: {
type: Object,
default: () => {
return {}
}
},
readonly: Boolean
})
2024-06-06 09:33:03 +08:00
let _value = computed({
2024-04-28 10:10:03 +08:00
get() {
return props.modelValue
},
set(val) {
emits('update:modelValue', val)
}
})
// #ifdef H5
const _formProps = computed(() => {
try {
return eval(`return ${props.formProps.formProps || {}}`) || {}
} catch (e) {
return {}
}
})
const codeForm = computed(() => {
const path = (props.formProps.path || '').trim()
if (path === '') {
return 'view'
}
return ''//defineAsyncComponent(() => import('../../..' + props.formProps.path))
})
const origin = computed(() => {
return resolveOrigin(props.formProps.path)
})
const formPath = computed(() => {
if (!props.formProps.isCodeForm) {
return `${props.formProps.path}${urlHasParam(props.formProps.path) ? '?':'&'}perm=${props.formProps.readonly ? 'R':'E'}`
}
return props.formProps.path
})
const emits = defineEmits(['update:modelValue'])
const codeFormCp = ref()
const timer = ref(null)
const validCall = ref(null)
const validResult = ref(false)
onMounted(() => {
//监听表单消息
if (!props.formProps.isCodeForm) {
window.addEventListener("message", onMessage, false);
}
})
onBeforeUnmount(() => {
if (!props.formProps.isCodeForm) {
window.removeEventListener("message", onMessage);
}
})
function onMessage(ev) {
if (ev.source !== ev.target) {
switch (ev.data.type) {
case 'WFLOW_FORM_VALID':
if (timer.value) {
clearTimeout(timer.value)
}
_value = ev.data.formData
if (validCall.value) {
console.log('iframe表单校验结果', ev.data.valid || false)
validCall.value(ev.data.valid || false)
validCall.value = null
}
break
case 'WFLOW_FORM_DATA_CHANGE':
_value = ev.data.formData
break
case 'WFLOW_GET_FORM_DATA':
loadIframeFormData()
break
}
}
}
function loadIframeFormData() {
const iframe = document.getElementById('urlForm_' + props.formProps)
if (iframe) {
iframe.contentWindow.postMessage({
type: 'WFLOW_SET_FORM_DATA',
formData: _value
}, origin)
}
}
function urlHasParam(url) {
try {
const params = new URL(url).searchParams;
// 判断是否有参数
return params && params.keys().next().done === false;
} catch (e) {
return true
}
}
function resolveOrigin(url) {
// 使用正则表达式匹配 URL 中的域名或 IP 地址和端口
const regex = /^(https?:\/\/)?([^:\/\s]+)(:\d+)?/;
const match = url.match(regex);
if (match) {
const protocol = match[1] || 'http://';
const domainOrIp = match[2];
const port = match[3] || '';
// 如果端口存在且不是默认端口80 或 443则包括端口
if (port && !/:\d+/.test(port)) {
return `${protocol}${domainOrIp}${port}`;
} else {
return `${protocol}${domainOrIp}`;
}
}
return null;
}
function change(e) {
console.log('*********')
}
function validate(call) {
if (props.formProps.isCodeForm) {
if (codeFormCp.value && codeFormCp.value.validate) {
codeFormCp.value.validate(call)
} else if (call) {
call(false)
}
} else {
//网络表单,通过消息传递交互
validCall.value = call
const iframe = document.getElementById('urlForm_' + props.formProps)
iframe.contentWindow.postMessage({ type: 'WFLOW_FORM_VALIDATE' }, origin)
//超时检测表单校验数据返回
timer.value = setTimeout(() => {
if (call) {
timer.value = null
call(false)
}
}, 500)
}
}
// #endif
</script>
<style>
</style>