diff --git a/components-diy/diy-form.vue b/components-diy/diy-form.vue index cc7b6c7..3b293a7 100644 --- a/components-diy/diy-form.vue +++ b/components-diy/diy-form.vue @@ -1,25 +1,23 @@ @@ -65,8 +63,148 @@ export default { } return css; }, + // 兼容旧 style 别名(部分页面用 :style="style" 引用) + diyFormStyle() { + return this.style; + }, + // 将后端 formConfig 写入 CSS 变量:与后端 design.css :root 对齐, + // 让 banner / tip / submit 与 ns-newform 子组件共享同一套样式变量 + cssVars() { + const cfg = this.mergedFormConfig || {}; + const rpx = (v) => { + if (v === '' || v === null || v === undefined) return ''; + return typeof v === 'number' ? `${v}rpx` : `${v}`; + }; + const showDivider = this._coerceBool(cfg.showRowDivider); + return { + '--form-padding-x': rpx(cfg.formPaddingX || 14), + '--banner-padding-x': rpx(cfg.bannerPaddingX || 0), + '--tip-padding-x': rpx(cfg.tipPaddingX || 14), + '--tip-font-size': rpx(cfg.tipFontSize || 24), + '--tip-color': cfg.tipColor || '#666666', + '--tip-bg-color': cfg.tipBgColor || '#ffffff', + '--row-padding-y': rpx(cfg.rowPaddingY || 4), + '--row-min-height': rpx(cfg.rowMinHeight || 60), + '--label-gap': rpx(cfg.labelGap || 16), + '--form-bg-color': cfg.formBgColor || '#ffffff', + '--row-divider-color': cfg.rowDividerColor || '#f0f0f0', + '--input-height': rpx(cfg.inputHeight || 60), + '--input-radius': rpx(cfg.inputRadius || 10), + '--label-fixed-width': rpx(cfg.labelFixedWidth || 180), + '--label-font-size': rpx(cfg.labelFontSize || 28), + '--label-color': cfg.labelColor || '#1f2937', + '--required-color': cfg.requiredColor || '#ef4444', + '--checked-color': cfg.checkedColor || '#ff4544', + '--submit-color': cfg.submitColor || '#ffffff', + '--submit-bg-color': cfg.submitBgColor || '#ff4544', + '--placeholder-color': '#ddd', + '--show-row-divider': showDivider ? '1' : '0' + }; + }, + // Banner 容器左右内边距(与后端 .form-preview-banner padding-x 对齐) + bannerStyle() { + return { + padding: `0 ${this._num(this.mergedFormConfig && this.mergedFormConfig.bannerPaddingX, 0)}rpx` + }; + }, + // 提示语样式:padding-x、font-size、color、bg-color(与后端 .form-preview-tip 对齐) + tipStyle() { + const cfg = this.mergedFormConfig || {}; + return { + 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' + }; + }, + // 提交按钮外层:与后端 .form-preview-submit 对齐(padding: row-padding-y form-padding-x;background: form-bg-color) + submitWrapStyle() { + const cfg = this.mergedFormConfig || {}; + return { + padding: `${this._num(cfg.rowPaddingY, 4)}rpx ${this._num(cfg.formPaddingX, 14)}rpx`, + 'background-color': cfg.formBgColor || '#ffffff' + }; + }, + // 提交按钮样式:颜色 / 背景色 / 高度 / 圆角 / 字号(与后端 .form-preview-submit button 对齐) + submitStyle() { + const cfg = this.mergedFormConfig || {}; + return { + color: cfg.submitColor || '#ffffff', + 'background-color': cfg.submitBgColor || '#ff4544', + 'line-height': `${this._num(cfg.inputHeight, 60)}rpx`, + 'border-radius': `${this._num(cfg.inputRadius, 10)}rpx`, + 'font-size': `${this._num(cfg.labelFontSize, 28)}rpx` + }; + }, + // 提交按钮文字:与后端 design.html 默认对齐,开放给 formConfig 覆盖 + submitText() { + return this.formCfg.submit_text || '提交'; + }, formLayoutClass() { - return this.value.form_layout === 'vertical' ? 'form-vertical' : 'form-horizontal'; + return this.formCfg.form_layout === 'vertical' ? 'form-vertical' : 'form-horizontal'; + }, + // 后端把表单样式配置统一存放在 data.formConfig 子对象中(与后端 design.js getDefaultFormData().formConfig 字段名一致)。 + // 这里做一次归一化:优先取 formConfig;如果历史数据是扁平结构(直接挂在 value 上),也做兼容。 + formCfg() { + const v = this.value || {}; + if (v.formConfig && typeof v.formConfig === 'object') { + return v.formConfig; + } + return v; + }, + // 合并后的表单配置(支持平台差异化) + mergedFormConfig() { + const v = this.value || {}; + const fc = this.formCfg; + // 通用全局配置(与后端 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, + tipFontSize: fc.tip_font_size, + tipColor: fc.tip_color, + tipBgColor: fc.tip_bg_color + }; + // 移除 undefined / 空字符串(保留 0/false) + Object.keys(base).forEach(function(k) { + if (base[k] === undefined || base[k] === null || base[k] === '') { + delete base[k]; + } + }); + // 平台差异化配置(与后端 formConfig.terminal 字段名对齐) + // 优先级:value.form_config_terminal > value.terminal > value.form_config_platform + const result = Object.assign({}, base); + const termBlock = 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]; + if (!src) return; + // 嵌套值若为 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]; + }); + result[platform] = translated; + }); + } + return result; } }, methods: { @@ -87,6 +225,20 @@ export default { }); }, + // 数字保底:undefined/空串/非数字时返回兜底值 + _num(v, fb) { + if (v === '' || v === null || v === undefined) return fb; + var n = parseInt(v); + return isNaN(n) ? fb : n; + }, + // 布尔保底:0/false/'0'/'false' → false;其它有值 → true + _coerceBool(v) { + if (v === false || v === 0 || v === '0' || v === 'false' || v === null || v === undefined) { + return false; + } + return true; + }, + // 提交表单 submitForm() { var self = this; @@ -141,13 +293,14 @@ export default { diff --git a/components/ns-newform/ns-newform.vue b/components/ns-newform/ns-newform.vue index c9fa13d..13a0014 100644 --- a/components/ns-newform/ns-newform.vue +++ b/components/ns-newform/ns-newform.vue @@ -1,17 +1,17 @@