174 lines
4.1 KiB
Vue
174 lines
4.1 KiB
Vue
<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
|
||
})
|
||
|
||
let _value = computed({
|
||
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> |