<script lang="ts" setup>
|
import { computed, nextTick, reactive, ref, toRefs, unref } from 'vue';
|
|
import { useMessage } from '@jnpf/hooks';
|
import { BasicPopup, usePopupInner } from '@jnpf/ui/popup';
|
import { createAsyncComponent, getDateTimeUnit, getScriptFunc } from '@jnpf/utils';
|
|
import { useUserStore } from '@vben/stores';
|
|
import dayjs from 'dayjs';
|
|
import { createAuditCorrelationId } from '#/api/onlineDev/auditHeaders';
|
import { createModel } from '#/api/onlineDev/visualDev';
|
import { createAuditRequestOnlineUtils } from '#/components/FormGenerator/src/helper/auditDisplay';
|
import { buildDisplayOnlySubmitData } from '#/components/FormGenerator/src/helper/displayOnly';
|
import { $t } from '#/locales';
|
|
interface State {
|
formConf: any;
|
config: any;
|
loading: boolean;
|
btnLoading: boolean;
|
key: number;
|
reviewPassed: boolean;
|
reviewVisible: boolean;
|
}
|
|
defineEmits(['register']);
|
const { createMessage } = useMessage();
|
const userStore = useUserStore();
|
const [registerPopup, { changeLoading }] = usePopupInner(init);
|
const parserRef = ref<any>(null);
|
const state = reactive<State>({
|
formConf: {},
|
config: {},
|
loading: false,
|
btnLoading: false,
|
key: Date.now(),
|
reviewPassed: true,
|
reviewVisible: true,
|
});
|
const { formConf, key, loading, config, btnLoading } = toRefs(state);
|
const Parser = createAsyncComponent(() => import('#/components/FormGenerator/src/components/Parser.vue'));
|
|
const getOkText = computed(() => {
|
const text = state.formConf.confirmButtonTextI18nCode
|
? $t(state.formConf.confirmButtonTextI18nCode, state.formConf.confirmButtonText)
|
: state.formConf.confirmButtonText;
|
return text || $t('common.okText');
|
});
|
const getReviewText = computed(() => {
|
const text = state.formConf.reviewButtonTextI18nCode
|
? $t(state.formConf.reviewButtonTextI18nCode, state.formConf.reviewButtonText)
|
: state.formConf.reviewButtonText;
|
return text || $t('common.reviewText');
|
});
|
|
function fillFormData(form, data) {
|
const userInfo = userStore.getUserInfo;
|
const currDate = new Date();
|
const loop = (list) => {
|
for (const item of list) {
|
if (item.__vModel__ && item.__config__.defaultCurrent) {
|
if (item.__config__.jnpfKey === 'datePicker') {
|
item.__config__.defaultValue = dayjs(currDate).startOf(getDateTimeUnit(item.format)).valueOf();
|
}
|
if (item.__config__.jnpfKey === 'timePicker') {
|
item.__config__.defaultValue = dayjs(currDate).format(item.format || 'HH:mm:ss');
|
}
|
if (item.__config__.jnpfKey === 'organizeSelect' && userInfo?.organizeIds?.length) {
|
item.__config__.defaultValue = item.multiple ? userInfo.organizeIds : userInfo.organizeId;
|
}
|
if (item.__config__.jnpfKey === 'userSelect' && userInfo?.userId) {
|
item.__config__.defaultValue = item.multiple ? [userInfo.userId] : userInfo.userId;
|
}
|
if (item.__config__.jnpfKey === 'usersSelect' && userInfo?.userId) {
|
item.__config__.defaultValue = [`${userInfo.userId}--user`];
|
}
|
if (item.__config__.jnpfKey === 'posSelect' && userInfo?.positionIds?.length) {
|
item.__config__.defaultValue = item.multiple ? userInfo.positionIds : userInfo.positionId;
|
}
|
if (item.__config__.jnpfKey === 'sign' && userInfo?.signImg) {
|
item.__config__.defaultValue = userInfo.signImg;
|
}
|
}
|
if (item.__config__ && item.__config__.children && Array.isArray(item.__config__.children)) {
|
loop(item.__config__.children);
|
}
|
}
|
};
|
loop(form.fields);
|
form.formData = data;
|
}
|
function init(data) {
|
changeLoading(true);
|
state.loading = true;
|
state.config = data;
|
state.formConf = data.formData ? JSON.parse(data.formData) : {};
|
state.reviewVisible = !!state.formConf.hasReviewBtn && !state.formConf.reviewBtnConfig?.noShow;
|
state.reviewPassed = !state.reviewVisible || !!state.formConf.reviewBtnConfig?.biz_review_optional;
|
fillFormData(state.formConf, {});
|
nextTick(() => {
|
changeLoading(false);
|
state.loading = false;
|
state.key = Date.now();
|
});
|
}
|
function submitForm(data, callback, scriptParameter = {}, auditDisplayFields = [], getAuditDisplayFields?) {
|
if (!data) return;
|
state.btnLoading = true;
|
const formData = buildDisplayOnlySubmitData(state.formConf.fields, data);
|
const dataForm = { auditDisplayFields, data: JSON.stringify(formData) };
|
if (state.formConf.funcs?.customSubmit) {
|
runCustomSubmit(formData, scriptParameter, auditDisplayFields, getAuditDisplayFields)
|
.then((res) => {
|
if (res?.msg) createMessage.success(res.msg);
|
if (callback && typeof callback === 'function') callback();
|
state.btnLoading = false;
|
handleReset();
|
})
|
.catch(() => {
|
state.btnLoading = false;
|
});
|
return;
|
}
|
createModel(state.config.modelId, dataForm)
|
.then((res) => {
|
createMessage.success(res.msg);
|
if (callback && typeof callback === 'function') callback();
|
state.btnLoading = false;
|
handleReset();
|
})
|
.catch(() => {
|
state.btnLoading = false;
|
});
|
}
|
function getLatestSubmitData(formData, scriptParameter) {
|
return buildDisplayOnlySubmitData(state.formConf.fields, scriptParameter?.formData || formData);
|
}
|
function syncLatestSubmitData(formData, scriptParameter) {
|
const latestFormData = getLatestSubmitData(formData, scriptParameter);
|
Object.keys(formData).forEach((key) => delete formData[key]);
|
Object.assign(formData, latestFormData);
|
}
|
function runCustomSubmit(formData, scriptParameter, auditDisplayFields, getAuditDisplayFields?) {
|
const func: any = getScriptFunc(state.formConf.funcs?.customSubmitFunc);
|
if (!func) return Promise.reject();
|
const auditCorrelationId = createAuditCorrelationId();
|
const setFormData = (prop, value) => {
|
scriptParameter?.setFormData?.(prop, value);
|
syncLatestSubmitData(formData, scriptParameter);
|
};
|
const formContext = {
|
id: '',
|
isEdit: false,
|
submit: (resolve, reject) => {
|
const latestFormData = getLatestSubmitData(formData, scriptParameter);
|
const latestAuditDisplayFields = typeof getAuditDisplayFields === 'function' ? getAuditDisplayFields(latestFormData) : auditDisplayFields;
|
const dataForm = { auditDisplayFields: latestAuditDisplayFields, data: JSON.stringify(latestFormData) };
|
createModel(state.config.modelId, dataForm, auditCorrelationId)
|
.then((res) => {
|
resolve?.(res);
|
})
|
.catch((error) => {
|
reject?.(error);
|
});
|
},
|
};
|
const scopedOnlineUtils = createAuditRequestOnlineUtils(
|
scriptParameter?.onlineUtils,
|
() => {
|
const latestFormData = getLatestSubmitData(formData, scriptParameter);
|
return typeof getAuditDisplayFields === 'function' ? getAuditDisplayFields(latestFormData) : auditDisplayFields;
|
},
|
() => {
|
const latestFormData = getLatestSubmitData(formData, scriptParameter);
|
return latestFormData.biz_sign ?? latestFormData.biz_sign_jnpfId;
|
},
|
auditCorrelationId,
|
);
|
try {
|
return Promise.resolve(func({ ...scriptParameter, formData, setFormData, formContext, onlineUtils: scopedOnlineUtils }));
|
} catch {
|
return Promise.reject();
|
}
|
}
|
function handleReset() {
|
state.reviewVisible = !!state.formConf.hasReviewBtn && !state.formConf.reviewBtnConfig?.noShow;
|
state.reviewPassed = !state.reviewVisible || !!state.formConf.reviewBtnConfig?.biz_review_optional;
|
fillFormData(state.formConf, {});
|
nextTick(() => {
|
getParser().handleReset();
|
});
|
}
|
function handleSubmit() {
|
if (state.config.isPreview) return createMessage.warning('功能预览不支持数据保存');
|
getParser().handleSubmit();
|
}
|
function handleReview() {
|
getParser().handleReview();
|
}
|
function getParser() {
|
const parser = unref(parserRef);
|
if (!parser) throw new Error('parser is null!');
|
return parser;
|
}
|
</script>
|
<template>
|
<BasicPopup v-bind="$attrs" @register="registerPopup" :show-back-icon="false" :show-cancel-btn="false" :title="config.fullName">
|
<template #insertToolbar>
|
<a-button v-if="state.reviewVisible" class="mr-[10px]" @click="handleReview">{{ getReviewText }}</a-button>
|
<a-button type="primary" @click="handleSubmit" :disabled="state.reviewVisible && !state.reviewPassed" :loading="btnLoading">{{ getOkText }}</a-button>
|
<a-button type="warning" class="ml-[10px]" @click="handleReset">{{ $t('common.resetText') }}</a-button>
|
</template>
|
<div class="p-[10px]" :style="{ margin: '0 auto', width: formConf.fullScreenWidth || '100%' }">
|
<Parser
|
ref="parserRef"
|
:form-conf="formConf"
|
:is-preview="state.config.isPreview"
|
:model-id="state.config.modelId"
|
@review-status-change="state.reviewPassed = $event"
|
@review-visibility-change="state.reviewVisible = $event"
|
@submit="submitForm"
|
:key="key"
|
v-if="!loading" />
|
</div>
|
</BasicPopup>
|
</template>
|