2024-04-28 10:10:03 +08:00

174 lines
4.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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
})
const _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>