修复编辑pagetype字段后无法保存的问题

This commit is contained in:
jingrow 2026-01-24 15:57:16 +08:00
parent e529a35280
commit 50f99f64d9
3 changed files with 112 additions and 42 deletions

View File

@ -14,45 +14,53 @@ import TextControl from "./components/controls/TextControl.vue";
import TextEditorControl from "./components/controls/TextEditorControl.vue";
export function registerGlobalComponents(app) {
app.component("AttachControl", AttachControl)
.component("AttachImageControl", AttachControl)
.component("AutocompleteControl", DataControl)
.component("BarcodeControl", DataControl)
.component("ButtonControl", ButtonControl)
.component("CheckControl", CheckControl)
.component("CodeControl", CodeControl)
.component("ColorControl", DataControl)
.component("CurrencyControl", DataControl)
.component("DataControl", DataControl)
.component("DateControl", DataControl)
.component("DatetimeControl", DataControl)
.component("DurationControl", DataControl)
.component("DynamicLinkControl", DataControl)
.component("FloatControl", DataControl)
.component("GeolocationControl", GeolocationControl)
.component("HeadingControl", ButtonControl)
.component("HTMLControl", DataControl)
.component("HTMLEditorControl", CodeControl)
.component("IconControl", DataControl)
.component("ImageControl", ImageControl)
.component("IntControl", DataControl)
.component("JSONControl", CodeControl)
.component("LinkControl", LinkControl)
.component("LongTextControl", TextControl)
.component("MarkdownEditorControl", CodeControl)
.component("PasswordControl", DataControl)
.component("PercentControl", DataControl)
.component("PhoneControl", DataControl)
.component("ReadOnlyControl", DataControl)
.component("RatingControl", RatingControl)
.component("SelectControl", SelectControl)
.component("SignatureControl", SignatureControl)
.component("SmallTextControl", TextControl)
.component("TableControl", TableControl)
.component("TableMultiSelectControl", DataControl)
.component("TextControl", TextControl)
.component("TextEditorControl", TextEditorControl)
.component("TimeControl", DataControl);
// Helper function to safely register component
const safeRegister = (name, component) => {
if (!app.component(name)) {
app.component(name, component);
}
return app;
};
safeRegister("AttachControl", AttachControl);
safeRegister("AttachImageControl", AttachControl);
safeRegister("AutocompleteControl", DataControl);
safeRegister("BarcodeControl", DataControl);
safeRegister("ButtonControl", ButtonControl);
safeRegister("CheckControl", CheckControl);
safeRegister("CodeControl", CodeControl);
safeRegister("ColorControl", DataControl);
safeRegister("CurrencyControl", DataControl);
safeRegister("DataControl", DataControl);
safeRegister("DateControl", DataControl);
safeRegister("DatetimeControl", DataControl);
safeRegister("DurationControl", DataControl);
safeRegister("DynamicLinkControl", DataControl);
safeRegister("FloatControl", DataControl);
safeRegister("GeolocationControl", GeolocationControl);
safeRegister("HeadingControl", ButtonControl);
safeRegister("HTMLControl", DataControl);
safeRegister("HTMLEditorControl", CodeControl);
safeRegister("IconControl", DataControl);
safeRegister("ImageControl", ImageControl);
safeRegister("IntControl", DataControl);
safeRegister("JSONControl", CodeControl);
safeRegister("LinkControl", LinkControl);
safeRegister("LongTextControl", TextControl);
safeRegister("MarkdownEditorControl", CodeControl);
safeRegister("PasswordControl", DataControl);
safeRegister("PercentControl", DataControl);
safeRegister("PhoneControl", DataControl);
safeRegister("ReadOnlyControl", DataControl);
safeRegister("RatingControl", RatingControl);
safeRegister("SelectControl", SelectControl);
safeRegister("SignatureControl", SignatureControl);
safeRegister("SmallTextControl", TextControl);
safeRegister("TableControl", TableControl);
safeRegister("TableMultiSelectControl", DataControl);
safeRegister("TextControl", TextControl);
safeRegister("TextEditorControl", TextEditorControl);
safeRegister("TimeControl", DataControl);
}
export const controls = {

View File

@ -986,6 +986,12 @@ async function loadDetail() {
//
async function handleSave() {
// FormBuilder fields
window.dispatchEvent(new CustomEvent('sync-form-builder-fields'))
// fields
await new Promise(resolve => requestAnimationFrame(resolve))
//
try {
if (JSON.stringify(record.value) === JSON.stringify(originalRecord.value)) {
@ -1026,7 +1032,17 @@ async function handleSave() {
}, 1500)
}
} else {
const res = await updateRecord(entity.value, id.value, record.value)
// fields Jingrow API
const dataToSend = { ...record.value }
if (typeof dataToSend.fields === 'string') {
try {
dataToSend.fields = JSON.parse(dataToSend.fields)
} catch (e) {
console.error('Failed to parse fields:', e)
}
}
const res = await updateRecord(entity.value, id.value, dataToSend)
if (res.success) {
message.success(t('Saved successfully'))
//

View File

@ -1,11 +1,14 @@
<script setup lang="ts">
import { computed } from 'vue'
import { computed, ref, onMounted, onUnmounted } from 'vue'
import FormBuilderComponent from '@/core/features/form_builder/FormBuilder.vue'
import { useMessage } from 'naive-ui'
const props = defineProps<{ df: any; record: Record<string, any>; canEdit: boolean; ctx: any }>()
const message = useMessage()
// FormBuilder ref
const formBuilderRef = ref<InstanceType<typeof FormBuilderComponent> | null>(null)
// Label(vertical) (horizontal)
const labelLayout = computed(() => props.df.label_layout || 'vertical')
@ -30,6 +33,42 @@ const fields = computed(() => {
}
})
// fields
function getLatestFields() {
if (formBuilderRef.value) {
return formBuilderRef.value.getFields()
}
return null
}
// fields record
function syncFieldsToRecord() {
if (!isFormBuilder.value || !props.canEdit) return
const latestFields = getLatestFields()
if (latestFields && props.record) {
try {
props.record.fields = JSON.stringify(latestFields)
console.log('[HTML.vue] Synced latest fields to record before save')
} catch (e) {
console.error('[HTML.vue] Failed to sync fields:', e)
}
}
}
//
function handleSyncEvent() {
syncFieldsToRecord()
}
onMounted(() => {
window.addEventListener('sync-form-builder-fields', handleSyncEvent)
})
onUnmounted(() => {
window.removeEventListener('sync-form-builder-fields', handleSyncEvent)
})
// Handle field updates from form builder
function handleFieldsUpdate(newFields: any[]) {
if (props.canEdit && isFormBuilder.value) {
@ -55,14 +94,21 @@ function handleSave(newFields: any[]) {
// Handle dirty state change
function handleDirtyChange(isDirty: boolean) {
// Form builder dirty state changed
// fields
// fields
}
// Expose methods to parent
defineExpose({
getLatestFields
})
</script>
<template>
<!-- 如果是form_builder字段渲染Form Builder组件 -->
<div v-if="isFormBuilder" class="form-builder-field">
<FormBuilderComponent
ref="formBuilderRef"
:fields="fields"
:pagetype="pagetypeName"
:pagetype-record="record"