<script lang="ts" setup>
|
import { computed, inject, watchEffect } from 'vue';
|
|
import { buildUUID, getScriptFunc } from '@jnpf/utils';
|
|
import { onlineUtils } from '#/utils/jnpf';
|
|
import Item from './Item.vue';
|
|
const props = defineProps({
|
formConf: { type: Object, required: true },
|
relationData: { type: Object, default: () => {} },
|
formData: { type: Object },
|
loading: { type: Boolean, default: false },
|
});
|
const emit = defineEmits(['toDetail']);
|
const injectedOnlineUtils = inject('onlineUtils', null) as any;
|
const currentOnlineUtils = computed(() => injectedOnlineUtils || onlineUtils);
|
|
const getFormName = computed(() => `form-${buildUUID()}`);
|
const getLabelCol = computed(() => ({ style: { width: `${props.formConf.labelWidth}px` } }));
|
const getBindValue = computed(() => ({ ...props }));
|
const getFields = computed(() => props.formConf.fields || []);
|
|
watchEffect(() => {
|
resetDetailVisibleRules(props.formConf.fields || []);
|
applyDetailVisibleRules(props.formConf.fields || []);
|
});
|
|
function toDetail(data) {
|
emit('toDetail', data);
|
}
|
function applyDetailVisibleRules(list, parent?) {
|
if (!Array.isArray(list)) return;
|
for (const item of list) {
|
const config = item.__config__;
|
if (!config) continue;
|
runDetailVisibleRule(item, parent);
|
if (Array.isArray(config.children)) applyDetailVisibleRules(config.children, item);
|
}
|
}
|
function resetDetailVisibleRules(list) {
|
if (!Array.isArray(list)) return;
|
for (const item of list) {
|
const config = item.__config__;
|
if (!config) continue;
|
config.detailNoShow = false;
|
config.detailForceShow = false;
|
if (Array.isArray(config.children)) resetDetailVisibleRules(config.children);
|
}
|
}
|
function runDetailVisibleRule(item, parent?) {
|
const config = item.__config__;
|
if (!config?.useDetailVisibleRule || !config.detailVisibleRule) return;
|
const func: any = getScriptFunc(config.detailVisibleRule);
|
if (!func) return;
|
const field = getFieldName(item, parent);
|
const value = getFieldValue(item, parent);
|
try {
|
const result = func({
|
formData: props.formData || {},
|
field,
|
value,
|
item,
|
config,
|
onlineUtils: currentOnlineUtils.value,
|
setShowOrHide,
|
});
|
if (typeof result === 'boolean') {
|
config.detailNoShow = !result;
|
config.detailForceShow = result;
|
}
|
} catch {
|
config.detailNoShow = false;
|
config.detailForceShow = false;
|
}
|
}
|
function getFieldName(item, parent?) {
|
if (!item.__vModel__) return '';
|
return parent?.__config__?.jnpfKey === 'table' && parent.__vModel__ ? `${parent.__vModel__}.${item.__vModel__}` : item.__vModel__;
|
}
|
function getFieldValue(item, parent?) {
|
if (!item.__vModel__) return undefined;
|
if (parent?.__config__?.jnpfKey === 'table' && parent.__vModel__) {
|
const rows = props.formData?.[parent.__vModel__];
|
return Array.isArray(rows) ? rows.map((row) => row?.[item.__vModel__]) : undefined;
|
}
|
return props.formData?.[item.__vModel__];
|
}
|
function setShowOrHide(prop, value) {
|
const newVal = !!value;
|
const keys = String(prop || '')
|
.split(/[.-]/)
|
.filter(Boolean);
|
if (!keys.length) return;
|
const table = keys.length > 1 ? keys[0] : '';
|
const field = keys.length > 1 ? keys[1] : keys[0];
|
setFieldDetailNoShow(props.formConf.fields || [], field, !newVal, table);
|
}
|
function setFieldDetailNoShow(list, field, detailNoShow, table = '') {
|
if (!Array.isArray(list)) return false;
|
for (const item of list) {
|
const config = item.__config__;
|
if (!config) continue;
|
const isTarget = table ? item.__vModel__ === table : item.__vModel__ === field;
|
if (isTarget && !table) {
|
config.detailNoShow = detailNoShow;
|
config.detailForceShow = !detailNoShow;
|
return true;
|
}
|
if (table && item.__vModel__ === table && Array.isArray(config.children)) {
|
const child = config.children.find((o) => o.__vModel__ === field);
|
if (child?.__config__) {
|
child.__config__.detailNoShow = detailNoShow;
|
child.__config__.detailForceShow = !detailNoShow;
|
return true;
|
}
|
}
|
if (Array.isArray(config.children) && setFieldDetailNoShow(config.children, field, detailNoShow, table)) return true;
|
}
|
return false;
|
}
|
</script>
|
|
<template>
|
<a-row :class="formConf.formStyle ? `${formConf.formStyle} word-form-detail` : ''">
|
<a-form
|
class="w-full"
|
:name="getFormName"
|
:colon="formConf.colon"
|
:size="formConf.size"
|
:disabled="formConf.disabled"
|
:label-col="getLabelCol"
|
:layout="formConf.labelPosition === 'top' ? 'vertical' : 'horizontal'"
|
:label-align="formConf.labelPosition === 'right' ? 'right' : 'left'">
|
<a-row :gutter="formConf.formStyle ? 0 : formConf.gutter">
|
<Item v-for="(item, index) in getFields" :key="index" :item="item" v-bind="getBindValue" @to-detail="toDetail" />
|
</a-row>
|
</a-form>
|
</a-row>
|
</template>
|