diff --git a/components-diy/diy-form.vue b/components-diy/diy-form.vue index 10a6974..97c0ca8 100644 --- a/components-diy/diy-form.vue +++ b/components-diy/diy-form.vue @@ -7,10 +7,10 @@ {{ value.form_tip }} - @@ -90,15 +90,20 @@ export default { padding: `0 ${this._num(this.mergedFormConfig && this.mergedFormConfig.bannerPaddingX, 0)}rpx` }); }, - // 提示语样式:padding-x、font-size、color、bg-color(与后端 .form-preview-tip 对齐) + // 提示语样式:padding-x、font-size、color、bg-color、border-bottom(与后端 .form-preview-tip 对齐) tipStyle() { const cfg = this.mergedFormConfig || {}; - return this.$util.objToStyle({ + const style = { padding: `${this._num(cfg.rowPaddingY, 4)}rpx ${this._num(cfg.tipPaddingX, 14)}rpx`, 'font-size': `${this._num(cfg.tipFontSize, 24)}rpx`, 'color': cfg.tipColor || '#666666', 'background-color': cfg.tipBgColor || 'transparent' - }); + }; + // 仅在配置了 tipBorderColor 时添加底线,避免 transparent 占位仍增加 2rpx 高度 + if (cfg.tipBorderColor) { + style['border-bottom'] = `2rpx solid ${cfg.tipBorderColor}`; + } + return this.$util.objToStyle(style); }, // 提交按钮外层:与后端 .form-preview-submit 对齐(padding: row-padding-y form-padding-x;background: form-bg-color) submitWrapStyle() { @@ -131,8 +136,9 @@ export default { }); }, // 提交按钮文字:与后端 design.html 默认对齐,开放给 formConfig 覆盖 + // 走 mergedFormConfig(兼容 camelCase / snake_case),让 formConfig.submitText 能正确覆盖 submitText() { - return this.formCfg.submit_text || '提交'; + return this.mergedFormConfig.submitText || '提交'; }, // 后端把表单样式配置统一存放在 data.formConfig 子对象中(与后端 design.js getDefaultFormData().formConfig 字段名一致)。 // 这里做一次归一化:优先取 formConfig;如果历史数据是扁平结构(直接挂在 value 上),也做兼容。 @@ -147,34 +153,45 @@ export default { mergedFormConfig() { const v = this.value || {}; const fc = this.formCfg; + // 后端实际返回 camelCase(如 formPaddingX / formBgColor / labelFontSize), + // 但旧版 design.js / 部分序列化路径可能用 snake_case(form_padding_x)。这里同时读两种写法,camelCase 优先 + const self = this; + const pick = function(camel, snake) { + var v1 = fc[camel]; + if (v1 !== undefined && v1 !== null && v1 !== '') return v1; + return fc[snake]; + }; // 通用全局配置(与后端 design.js getDefaultFormData().formConfig 字段名一致) const base = { - formPaddingX: fc.form_padding_x, - bannerPaddingX: fc.banner_padding_x, - tipPaddingX: fc.tip_padding_x, - rowPaddingY: fc.row_padding_y, - rowMinHeight: fc.row_min_height, - labelGap: fc.label_gap, - formBgColor: fc.form_bg_color, - rowDividerColor: fc.row_divider_color, - showRowDivider: this._coerceBool(fc.show_row_divider), - inputHeight: fc.input_height, - inputRadius: fc.input_radius, - labelWidthMode: fc.label_width_mode, - labelFixedWidth: fc.label_fixed_width, - labelFontSize: fc.label_font_size, - labelColor: fc.label_color, - requiredColor: fc.required_color, - checkedColor: fc.checked_color, - submitColor: fc.submit_color, - submitBgColor: fc.submit_bg_color, + formPaddingX: pick('formPaddingX', 'form_padding_x'), + bannerPaddingX: pick('bannerPaddingX', 'banner_padding_x'), + tipPaddingX: pick('tipPaddingX', 'tip_padding_x'), + rowPaddingY: pick('rowPaddingY', 'row_padding_y'), + rowMinHeight: pick('rowMinHeight', 'row_min_height'), + labelGap: pick('labelGap', 'label_gap'), + formBgColor: pick('formBgColor', 'form_bg_color'), + rowDividerColor: pick('rowDividerColor', 'row_divider_color'), + showRowDivider: self._coerceBool(pick('showRowDivider', 'show_row_divider')), + inputHeight: pick('inputHeight', 'input_height'), + inputRadius: pick('inputRadius', 'input_radius'), + formLayout: pick('formLayout', 'form_layout'), + labelWidthMode: pick('labelWidthMode', 'label_width_mode'), + labelFixedWidth: pick('labelFixedWidth', 'label_fixed_width'), + labelFontSize: pick('labelFontSize', 'label_font_size'), + labelColor: pick('labelColor', 'label_color'), + requiredColor: pick('requiredColor', 'required_color'), + checkedColor: pick('checkedColor', 'checked_color'), + submitText: pick('submitText', 'submit_text'), + submitColor: pick('submitColor', 'submit_color'), + submitBgColor: pick('submitBgColor', 'submit_bg_color'), // 提交按钮尺寸:宽度百分比 + 尺寸预设(与后端 design.js 对齐) - submitWidthPercent: fc.submit_width_percent, - submitSize: fc.submit_size, + submitWidthPercent: pick('submitWidthPercent', 'submit_width_percent'), + submitSize: pick('submitSize', 'submit_size'), // 提示语 - tipFontSize: fc.tip_font_size, - tipColor: fc.tip_color, - tipBgColor: fc.tip_bg_color + tipFontSize: pick('tipFontSize', 'tip_font_size'), + tipColor: pick('tipColor', 'tip_color'), + tipBgColor: pick('tipBgColor', 'tip_bg_color'), + tipBorderColor: pick('tipBorderColor', 'tip_border_color') }; // 移除 undefined / 空字符串(保留 0/false) Object.keys(base).forEach(function(k) { @@ -182,10 +199,10 @@ export default { delete base[k]; } }); - // 平台差异化配置(与后端 formConfig.terminal 字段名对齐) - // 优先级:value.form_config_terminal > value.terminal > value.form_config_platform + // 平台差异化配置(terminal 块在 formConfig 子对象内) + // 优先级:v.formConfig.terminal > v.form_config_terminal > v.terminal > v.form_config_platform const result = Object.assign({}, base); - const termBlock = v.form_config_terminal || v.terminal || v.form_config_platform; + const termBlock = (v.formConfig && v.formConfig.terminal) || v.form_config_terminal || v.terminal || v.form_config_platform; if (termBlock && typeof termBlock === 'object') { Object.keys(termBlock).forEach(function(platform) { var src = termBlock[platform]; @@ -193,8 +210,7 @@ export default { // 嵌套值若为 snake_case(部分序列化路径),在此统一转 camelCase var translated = {}; Object.keys(src).forEach(function(k) { - var camel = k.replace(/_([a-z])/g, function(_, c) { return c.toUpperCase(); }); - translated[camel] = src[k]; + translated[self.$util.snakeToCamel(k)] = src[k]; }); result[platform] = translated; }); diff --git a/pages_tool/form/formdata.vue b/pages_tool/form/formdata.vue index 8431cfb..b44bea7 100644 --- a/pages_tool/form/formdata.vue +++ b/pages_tool/form/formdata.vue @@ -60,12 +60,12 @@ export default { }, formTip() { const tip = this.detail?.form_tip - console.log('formTip computed, tip value:', tip, 'truthy:', !!tip) return tip ? tip : '请填写表单所需信息' }, // 构造 diy-form raw 模式期望的 value 形态: // - jsonData:透传给 ns-newform(已是 ns-newform 期望的 [{ controller, value, val }]) - // - formConfig:snake_case 表单配置,diy-form 内部 mergedFormConfig 会做 camelCase 转换 + // - formConfig:后端返回 camelCase(如 formPaddingX / formBgColor / labelFontSize), + // diy-form 内部 mergedFormConfig 同时兼容 snake_case 后再交给 ns-newform // - 不传 show_banner / show_tip:让 diy-form 自带的 banner/tip 不渲染(页面已自渲染) // 注:本 computed 只在 内被消费,无需 null 守卫 diyValue() { @@ -138,7 +138,6 @@ export default { success: res => { if (res.code == 0 && res.data) { this.detail = res.data - console.log(`form data =>`, this.detail) this.updateNavbarTitle(); } this.$refs.loadingCover && this.$refs.loadingCover.hide()