refactor(diy-form): 兼容前后端命名格式,优化表单配置处理
1. 重构mergedFormConfig逻辑,同时支持camelCase和snake_case格式的配置项,camelCase优先读取 2. 调整ns-newform的mode参数读取mergedFormConfig的formLayout 3. 优化提示语样式,新增tipBorderColor支持显示底部边框 4. 修复submitText读取逻辑,改为从mergedFormConfig获取 5. 移除多余的console日志,更新注释说明
This commit is contained in:
@@ -7,10 +7,10 @@
|
||||
<!-- 提示语 -->
|
||||
<view v-if="value.show_tip && value.form_tip" class="form-tip" :style="tipStyle">{{ value.form_tip }}</view>
|
||||
<!-- 表单组件 -->
|
||||
<ns-newform
|
||||
:data="formComponents"
|
||||
:customAttr="value"
|
||||
:mode="formCfg.form_layout === 'vertical' ? 'vertical' : 'horizontal'"
|
||||
<ns-newform
|
||||
:data="formComponents"
|
||||
:customAttr="value"
|
||||
:mode="mergedFormConfig.formLayout || 'horizontal'"
|
||||
:formConfig="mergedFormConfig"
|
||||
ref="nsNewform"
|
||||
></ns-newform>
|
||||
@@ -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 <button>提交</button> 默认对齐,开放给 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;
|
||||
});
|
||||
|
||||
@@ -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 只在 <block v-if="detail"> 内被消费,无需 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()
|
||||
|
||||
Reference in New Issue
Block a user