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>
|