From 6e19bc7affcc94d6ba807dd854d910ee0a032b2a Mon Sep 17 00:00:00 2001
From: ZF sun <34314687@qq.com>
Date: Thu, 16 Jul 2026 16:53:41 +0800
Subject: [PATCH 1/9] =?UTF-8?q?chore:=20=E6=B3=A8=E9=87=8A=E6=96=B0?=
=?UTF-8?q?=E5=A2=9E=E4=BD=8E=E7=A9=BA=E7=BB=8F=E6=B5=8E=E9=A1=B9=E7=9B=AE?=
=?UTF-8?q?=E9=85=8D=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
暂时注释掉2482号项目的配置代码,避免其被错误加载启用
---
.local.config.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/.local.config.js b/.local.config.js
index b2c63e3..0f27d24 100644
--- a/.local.config.js
+++ b/.local.config.js
@@ -143,6 +143,7 @@ const localDevConfig = ({
// })['5g-97']; // 大宗商品贸易,支持自定义字体大小、颜色
// })['5g-50']; // 燃气安全产品机器人,购物车无反应
// })['2821']; // 离型纸硅油纸
+// })['2482']; // 低空经济
})['48']; // 离型纸硅油纸
// })['2485']; // 验证电子表单前后端数据一致性
// })['5g-11']; // 数码
From aafb75bad34a091f755a23fad0af33a16780c611 Mon Sep 17 00:00:00 2001
From: ZF sun <34314687@qq.com>
Date: Thu, 16 Jul 2026 17:07:30 +0800
Subject: [PATCH 2/9] =?UTF-8?q?style:=20=E8=B0=83=E6=95=B4=E5=A4=9A?=
=?UTF-8?q?=E4=B8=AA=E9=A1=B5=E9=9D=A2=E7=9A=84=E5=9B=9E=E5=88=B0=E9=A1=B6?=
=?UTF-8?q?=E9=83=A8=E6=8C=89=E9=92=AE=E4=BD=8D=E7=BD=AE=E9=80=82=E9=85=8D?=
=?UTF-8?q?=E5=A4=9A=E7=AB=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
为H5和小程序平台分别配置mescroll-totop的right和bottom样式,修复不同终端下按钮位置适配问题
---
pages_tool/agreement/contenr.vue | 6 ++++++
pages_tool/article/detail.vue | 6 ++++++
pages_tool/form/form.vue | 10 ++++++++--
pages_tool/form/formdata.vue | 6 ++++++
pages_tool/index/diy.vue | 6 ++++++
pages_tool/member/card.vue | 6 ++++++
pages_tool/member/card_buy.vue | 6 ++++++
7 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/pages_tool/agreement/contenr.vue b/pages_tool/agreement/contenr.vue
index 233a916..c889ffc 100644
--- a/pages_tool/agreement/contenr.vue
+++ b/pages_tool/agreement/contenr.vue
@@ -180,7 +180,13 @@ export default {
}
::v-deep .mescroll-totop {
+ /* #ifdef H5 */
right: 27rpx !important;
bottom: 120rpx !important;
+ /* #endif */
+ /* #ifdef MP */
+ right: 27rpx !important;
+ bottom: 180rpx !important;
+ /* #endif */
}
\ No newline at end of file
diff --git a/pages_tool/article/detail.vue b/pages_tool/article/detail.vue
index 219232e..a1d14c9 100644
--- a/pages_tool/article/detail.vue
+++ b/pages_tool/article/detail.vue
@@ -160,7 +160,13 @@
\ No newline at end of file
diff --git a/pages_tool/form/form.vue b/pages_tool/form/form.vue
index 1640bae..d013281 100644
--- a/pages_tool/form/form.vue
+++ b/pages_tool/form/form.vue
@@ -153,7 +153,13 @@
\ No newline at end of file
diff --git a/pages_tool/form/formdata.vue b/pages_tool/form/formdata.vue
index 981f698..8b8163f 100644
--- a/pages_tool/form/formdata.vue
+++ b/pages_tool/form/formdata.vue
@@ -203,7 +203,13 @@ page {
}
::v-deep .mescroll-totop {
+ /* #ifdef H5 */
right: 27rpx !important;
bottom: 120rpx !important;
+ /* #endif */
+ /* #ifdef MP */
+ right: 27rpx !important;
+ bottom: 180rpx !important;
+ /* #endif */
}
diff --git a/pages_tool/index/diy.vue b/pages_tool/index/diy.vue
index de685d8..0cc3399 100644
--- a/pages_tool/index/diy.vue
+++ b/pages_tool/index/diy.vue
@@ -100,7 +100,13 @@ export default {
}
::v-deep .mescroll-totop {
+ /* #ifdef H5 */
right: 27rpx !important;
bottom: 120rpx !important;
+ /* #endif */
+ /* #ifdef MP */
+ right: 27rpx !important;
+ bottom: 180rpx !important;
+ /* #endif */
}
\ No newline at end of file
diff --git a/pages_tool/member/card.vue b/pages_tool/member/card.vue
index 19a76b2..d1a28ac 100644
--- a/pages_tool/member/card.vue
+++ b/pages_tool/member/card.vue
@@ -261,7 +261,13 @@ export default {
}
::v-deep .mescroll-totop {
+ /* #ifdef H5 */
right: 27rpx !important;
bottom: 120rpx !important;
+ /* #endif */
+ /* #ifdef MP */
+ right: 27rpx !important;
+ bottom: 180rpx !important;
+ /* #endif */
}
\ No newline at end of file
diff --git a/pages_tool/member/card_buy.vue b/pages_tool/member/card_buy.vue
index d764390..02343b0 100644
--- a/pages_tool/member/card_buy.vue
+++ b/pages_tool/member/card_buy.vue
@@ -432,7 +432,13 @@ export default {
\ No newline at end of file
From 41b0d15570846f06da63cbed6fc5d91ecfad2397 Mon Sep 17 00:00:00 2001
From: ZF sun <34314687@qq.com>
Date: Thu, 16 Jul 2026 17:09:30 +0800
Subject: [PATCH 3/9] =?UTF-8?q?chore:=20=E5=88=87=E6=8D=A2=E9=BB=98?=
=?UTF-8?q?=E8=AE=A4=E5=90=AF=E7=94=A8=E7=9A=84=E9=A1=B9=E7=9B=AE=E9=85=8D?=
=?UTF-8?q?=E7=BD=AE=E4=B8=BA=E4=BD=8E=E7=A9=BA=E7=BB=8F=E6=B5=8E?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
调整注释掉的配置项,将48切换为2482作为默认启用的项目配置
---
.local.config.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.local.config.js b/.local.config.js
index 0f27d24..1cf99cf 100644
--- a/.local.config.js
+++ b/.local.config.js
@@ -143,8 +143,8 @@ const localDevConfig = ({
// })['5g-97']; // 大宗商品贸易,支持自定义字体大小、颜色
// })['5g-50']; // 燃气安全产品机器人,购物车无反应
// })['2821']; // 离型纸硅油纸
-// })['2482']; // 低空经济
-})['48']; // 离型纸硅油纸
+})['2482']; // 低空经济
+// })['48']; // 离型纸硅油纸
// })['2485']; // 验证电子表单前后端数据一致性
// })['5g-11']; // 数码
// })['5g-213']; // 选择要使用的环境配置
From 40440708671739277e765ce4c5db262b34846fb8 Mon Sep 17 00:00:00 2001
From: ZF sun <34314687@qq.com>
Date: Thu, 16 Jul 2026 17:20:46 +0800
Subject: [PATCH 4/9] =?UTF-8?q?fix(splash):=20=E7=A7=BB=E9=99=A4=20onDiyGr?=
=?UTF-8?q?oupLoaded=20=E5=A4=9A=E4=BD=99=20500ms=20=E5=BB=B6=E8=BF=9F?=
=?UTF-8?q?=E9=81=BF=E5=85=8D=20page-ready=20=E5=85=9C=E5=BA=95=E8=B6=85?=
=?UTF-8?q?=E6=97=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
diy-group 内部 _notifyLoaded 已有 300ms 渲染 settle, 叠加的 500ms 会吃掉
splash 2s page-ready 兜底预算, 导致弱网/冷启动下走 page-ready-timeout 兜底路径
(splash 在页面就绪前被强制关闭)。改为收到 loaded 事件后立即 notifyPageReady。
---
pages/index/public/js/index.js | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/pages/index/public/js/index.js b/pages/index/public/js/index.js
index 277b5d1..617a4cc 100644
--- a/pages/index/public/js/index.js
+++ b/pages/index/public/js/index.js
@@ -128,12 +128,12 @@ export default {
},
// diy-group 渲染完毕回调, 用于触发版本水印等延后显示元素
// 同时通知 splash-state 页面就绪, 启动屏可以关闭
- // 延迟 500ms 是为了确保页面内容有足够时间渲染
+ // 注意: diy-group 内部 _notifyLoaded 已有 300ms 渲染 settle,
+ // 这里不再叠加 500ms, 避免吃掉 splash 的 2s page-ready 兜底预算
+ // (叠加延迟会导致弱网/冷启动下 splash 走 page-ready-timeout 兜底路径)
onDiyGroupLoaded() {
this.diyGroupReady = true;
- setTimeout(() => {
- try { splashState.notifyPageReady(); } catch (e) {}
- }, 500);
+ try { splashState.notifyPageReady(); } catch (e) {}
},
/**
* 版本连击 3 次以上显示构建版本信息(供测试人员使用)
From 61495b5e90e971421cb6918944fbc22c5a28b084 Mon Sep 17 00:00:00 2001
From: ZF sun <34314687@qq.com>
Date: Fri, 17 Jul 2026 10:43:49 +0800
Subject: [PATCH 5/9] =?UTF-8?q?refactor(utils&form):=20=E4=BC=98=E5=8C=96?=
=?UTF-8?q?=E8=AE=BE=E5=A4=87=E4=BF=A1=E6=81=AF=E8=8E=B7=E5=8F=96=E4=B8=8E?=
=?UTF-8?q?=E8=A1=A8=E5=8D=95=E7=BB=84=E4=BB=B6=E6=A0=B7=E5=BC=8F=E9=85=8D?=
=?UTF-8?q?=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
1. 为设备信息相关方法添加可选链操作符,避免空值报错
2. 重构getDeviceInfo和getWindowInfo的异常处理逻辑,简化代码
3. 重构ns-form表单组件,新增全局样式配置支持,兼容多端样式自定义
4. 优化表单布局样式、必填项和选中态颜色,修复鸿蒙元服务TextArea适配问题
5. 新增标签宽度自动计算功能,优化表单排版对齐效果
---
common/js/util.js | 33 ++-
components/ns-form/ns-form.vue | 480 ++++++++++++++++++++++++++++-----
2 files changed, 427 insertions(+), 86 deletions(-)
diff --git a/common/js/util.js b/common/js/util.js
index 3279c14..0875518 100644
--- a/common/js/util.js
+++ b/common/js/util.js
@@ -988,14 +988,14 @@ export default {
*/
isIPhoneX() {
let res = this.getDeviceInfo();
- if (res.model.search('iPhone X') != -1) {
+ if (res?.model?.search('iPhone X') != -1) {
return true;
}
return false;
},
//判断安卓还是iOS
isAndroid() {
- let platform = this.getDeviceInfo().platform;
+ let platform = this.getDeviceInfo()?.platform;
if (platform == 'ios') {
return false;
} else if (platform == 'android') {
@@ -1006,21 +1006,21 @@ export default {
* 获取设备信息(包含降级处理)
*/
getDeviceInfo() {
- try {
- return uni.getDeviceInfo();
- } catch (e) {
- return uni.getSystemInfoSync();
+ let info = {};
+ try { info = uni.getDeviceInfo(); } catch (e) {
+ try { info = uni.getSystemInfoSync(); } catch (e) {}
}
+ return info;
},
/**
* 获取窗口信息(包含降级处理)
*/
getWindowInfo() {
- try {
- return uni.getWindowInfo();
- } catch (e) {
- return uni.getSystemInfoSync();
+ let info;
+ try {info = uni.getWindowInfo();} catch (e) {
+ try {info = uni.getSystemInfoSync();} catch (e) {}
}
+ return info;
},
/**
* 深度拷贝对象
@@ -1118,10 +1118,10 @@ export default {
// auto: host 完全一致才还原
const appHosts = [];
// #ifdef H5
- try { if (typeof location !== 'undefined' && location.hostname) appHosts.push(location.hostname); } catch (e) {}
+ try { if (typeof location !== 'undefined' && location.hostname) appHosts.push(location.hostname); } catch (e) { }
// #endif
- try { if (Config.h5Domain) appHosts.push(Config.h5Domain); } catch (e) {}
- try { if (Config.baseUrl) appHosts.push(Config.baseUrl); } catch (e) {}
+ try { if (Config.h5Domain) appHosts.push(Config.h5Domain); } catch (e) { }
+ try { if (Config.baseUrl) appHosts.push(Config.baseUrl); } catch (e) { }
internalPath = _extractInternalAppPath(link.wap_url, appHosts);
}
if (internalPath) {
@@ -1152,7 +1152,7 @@ export default {
// #endif
// #ifdef MP
- console.log(`外部链接,跳转到webview`, url);
+ console.log(`外部链接,跳转到webview`, url);
this.redirectTo(PAGE_KEY_MAP.PAGE_WEBVIEW, {
...link,
src: url
@@ -1312,7 +1312,7 @@ export default {
*/
uniappIsIPhone11() {
let isIphone11 = false;
- let systemInfo = this.getDeviceInfo();
+ let systemInfo = this?.getDeviceInfo();
// #ifdef MP
if (systemInfo.model.search('iPhone 11') != -1) {
isIphone11 = true;
@@ -1323,8 +1323,7 @@ export default {
// #ifdef H5
//判断该浏览器是否为safaria浏览器
isSafari() {
- let res = this.getDeviceInfo();
- var ua = navigator.userAgent.toLowerCase();
+ var ua = navigator?.userAgent?.toLowerCase();
if (ua.indexOf('applewebkit') > -1 && ua.indexOf('mobile') > -1 && ua.indexOf('safari') > -1 &&
ua.indexOf('linux') === -1 && ua.indexOf('android') === -1 && ua.indexOf('chrome') === -1 &&
ua.indexOf('ios') === -1 && ua.indexOf('browser') === -1) {
diff --git a/components/ns-form/ns-form.vue b/components/ns-form/ns-form.vue
index 2a3840d..ca053f6 100644
--- a/components/ns-form/ns-form.vue
+++ b/components/ns-form/ns-form.vue
@@ -1,36 +1,59 @@
-
+
-
-
-
+
+
+
{{ item.value.title }}
- {{ item.value.required ? '*' : '' }}
+ {{ item.value.required ? '*' : '' }}
-
+
-
-
-
+
+
+
{{ item.value.title }}
- {{ item.value.required ? '*' : '' }}
+ {{ item.value.required ? '*' : '' }}
-
+
+
+
+
+
+
+
-
-
-
+
+
+
{{ item.value.title }}
- {{ item.value.required ? '*' : '' }}
+ {{ item.value.required ? '*' : '' }}
{{ item.val }}
@@ -41,18 +64,18 @@
-
-
-
+
+
+
{{ item.value.title }}
- {{ item.value.required ? '*' : '' }}
+ {{ item.value.required ? '*' : '' }}
@@ -61,18 +84,18 @@
-
-
-
+
+
+
{{ item.value.title }}
- {{ item.value.required ? '*' : '' }}
+ {{ item.value.required ? '*' : '' }}
@@ -81,11 +104,11 @@
-
-
-
+
+
+
{{ item.value.title }}
- {{ item.value.required ? '*' : '' }}
+ {{ item.value.required ? '*' : '' }}
@@ -97,11 +120,11 @@
-
-
-
+
+
+
{{ item.value.title }}
- {{ item.value.required ? '*' : '' }}
+ {{ item.value.required ? '*' : '' }}
@@ -112,11 +135,11 @@
-
-
-
+
+
+
{{ item.value.title }}
- {{ item.value.required ? '*' : '' }}
+ {{ item.value.required ? '*' : '' }}
@@ -138,11 +161,11 @@
-
-
-
+
+
+
{{ item.value.title }}
- {{ item.value.required ? '*' : '' }}
+ {{ item.value.required ? '*' : '' }}
@@ -153,11 +176,11 @@
-
-
-
+
+
+
{{ item.value.title }}
- {{ item.value.required ? '*' : '' }}
+ {{ item.value.required ? '*' : '' }}
@@ -179,11 +202,11 @@
-
-
-
+
+
+
{{ item.value.title }}
- {{ item.value.required ? '*' : '' }}
+ {{ item.value.required ? '*' : '' }}
@@ -205,32 +228,262 @@
props: {
data: {
type: Array,
- default: {}
+ default: () => []
},
customAttr: {
type: Object,
default: function() {
return {};
}
+ },
+ /**
+ * 表单样式配置(由后端 designer 通过 API 传入)。
+ * 字段名同时支持 camelCase(如 formPaddingX / inputHeight / labelColor)
+ * 与 snake_case(如 form_padding_x / input_height / label_color),camelCase 优先。
+ * 不传则使用组件内置默认(与重构前硬编码值一致,无视觉回归)。
+ *
+ * 支持的键:
+ * formPaddingX, formBgColor, rowPaddingY, rowMinHeight, labelGap,
+ * inputHeight, inputRadius, labelWidthMode ('auto'|'fixed'), labelFixedWidth,
+ * labelFontSize, labelColor, requiredColor, checkedColor,
+ * placeholderColor, showRowDivider, rowDividerColor
+ *
+ * 平台差异化:formConfig.terminal.{h5|weapp|harmony|app|quickapp} 只放差异字段
+ */
+ formConfig: {
+ type: Object,
+ default: () => ({})
}
},
data() {
return {
- formData: this.data
+ formData: [],
+ maxLabelWidth: 0
};
},
+ computed: {
+ // 当前运行平台标识(与后端 formConfig.terminal 键名对齐)
+ platform() {
+ // #ifdef H5
+ return 'h5';
+ // #endif
+ // #ifdef MP-WEIXIN
+ return 'weapp';
+ // #endif
+ // #ifdef MP-ALIPAY
+ return 'mp-alipay';
+ // #endif
+ // #ifdef MP-BAIDU
+ return 'mp-baidu';
+ // #endif
+ // #ifdef MP-TOUTIAO
+ return 'mp-toutiao';
+ // #endif
+ // #ifdef APP-PLUS
+ return 'app';
+ // #endif
+ // #ifdef MP-HARMONY
+ return 'harmony';
+ // #endif
+ // #ifdef QUICKAPP-WEBVIEW
+ return 'quickapp';
+ // #endif
+ return 'h5';
+ },
+ // 后端键名 → 内部 platform 名 兼容层
+ platformAliases() {
+ return {
+ 'h5': 'h5',
+ 'weapp': 'weapp',
+ 'mp-weixin': 'weapp',
+ 'wechat': 'weapp',
+ 'harmony': 'harmony',
+ 'app': 'app',
+ 'app-plus': 'app'
+ };
+ },
+ // 当前平台的有效配置键集合
+ platformConfigKeys() {
+ const cur = this.platform;
+ const aliases = this.platformAliases;
+ const keys = [];
+ Object.keys(aliases).forEach(k => {
+ if (aliases[k] === cur) keys.push(k);
+ });
+ if (keys.indexOf(cur) === -1) keys.push(cur);
+ return keys;
+ },
+ // 合并配置:内置默认 < 全局 formConfig < 当前平台 formConfig.terminal[platform]
+ // 同时兼容 snake_case 与 camelCase 字段名
+ config() {
+ // 1) 内置默认值(最低优先级,与重构前的硬编码值一一对应,确保未传 formConfig 时零回归)
+ const defaults = {
+ formPaddingX: 0,
+ formBgColor: '#ffffff',
+ rowPaddingY: 20,
+ rowMinHeight: 60,
+ labelGap: 16,
+ inputHeight: 60,
+ inputRadius: 0,
+ labelWidthMode: 'fixed', // 旧版 width: 80vw 用 fixed 180rpx 等价替代
+ labelFixedWidth: 180,
+ labelFontSize: 28,
+ labelColor: '#1f2937',
+ requiredColor: '#ef4444',
+ checkedColor: '#ff4544',
+ placeholderColor: '#909399',
+ showRowDivider: true,
+ rowDividerColor: '#f0f0f0'
+ };
+ const fc = this.formConfig || {};
+
+ // 同时读 camelCase 与 snake_case,camelCase 优先
+ const pick = (camel, snake) => {
+ const v1 = fc[camel];
+ if (v1 !== undefined && v1 !== null && v1 !== '') return v1;
+ return fc[snake];
+ };
+ const base = {
+ formPaddingX: pick('formPaddingX', 'form_padding_x'),
+ formBgColor: pick('formBgColor', 'form_bg_color'),
+ rowPaddingY: pick('rowPaddingY', 'row_padding_y'),
+ rowMinHeight: pick('rowMinHeight', 'row_min_height'),
+ labelGap: pick('labelGap', 'label_gap'),
+ inputHeight: pick('inputHeight', 'input_height'),
+ inputRadius: pick('inputRadius', 'input_radius'),
+ 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'),
+ placeholderColor: pick('placeholderColor', 'placeholder_color'),
+ showRowDivider: pick('showRowDivider', 'show_row_divider'),
+ rowDividerColor: pick('rowDividerColor', 'row_divider_color')
+ };
+ // 移除 undefined / 空字符串(保留 0 / false)
+ Object.keys(base).forEach(k => {
+ if (base[k] === undefined || base[k] === null || base[k] === '') delete base[k];
+ });
+ // showRowDivider 在前后端可能传数字 0/1,统一转 boolean
+ if ('showRowDivider' in base) {
+ base.showRowDivider = base.showRowDivider === true || base.showRowDivider === 1 || base.showRowDivider === '1';
+ }
+
+ // 2) 当前平台差异化配置(最高优先级),从 formConfig.terminal 取出当前平台 + 所有别名键,合并
+ const termBlock = fc.terminal || {};
+ const platformKeys = this.platformConfigKeys || [];
+ const platformCfg = Object.assign(
+ {},
+ ...platformKeys.map(k => termBlock[k] || fc[k] || {})
+ );
+ // 平台块可能也是 snake_case,统一转 camelCase
+ const platformCfgCamel = {};
+ if (this.$util && typeof this.$util.snakeToCamel === 'function') {
+ Object.keys(platformCfg).forEach(k => {
+ platformCfgCamel[this.$util.snakeToCamel(k)] = platformCfg[k];
+ });
+ } else {
+ Object.assign(platformCfgCamel, platformCfg);
+ }
+
+ // 3) 三层合并:defaults < base < platformCfgCamel
+ return Object.assign({}, defaults, base, platformCfgCamel);
+ },
+ // 容器样式:内边距 + 背景 + 16 个 CSS 自定义属性
+ formWrapStyle() {
+ const cfg = this.config;
+ const num = (v, fb) => (typeof v === 'number' ? v : parseInt(v) || fb);
+ return this.$util.objToStyle({
+ padding: `0 ${cfg.formPaddingX}rpx`,
+ background: cfg.formBgColor,
+ '--form-padding-x': `${cfg.formPaddingX}rpx`,
+ '--form-bg-color': cfg.formBgColor,
+ '--row-padding-y': `${cfg.rowPaddingY}rpx`,
+ '--row-min-height': `${cfg.rowMinHeight}rpx`,
+ '--label-gap': `${cfg.labelGap}rpx`,
+ '--input-height': `${cfg.inputHeight}rpx`,
+ '--input-radius': `${cfg.inputRadius}rpx`,
+ '--label-fixed-width': `${cfg.labelFixedWidth}rpx`,
+ '--label-font-size': `${num(cfg.labelFontSize, 28)}rpx`,
+ '--label-color': cfg.labelColor,
+ '--required-color': cfg.requiredColor,
+ '--checked-color': cfg.checkedColor,
+ '--placeholder-color': cfg.placeholderColor,
+ '--row-divider-color': cfg.rowDividerColor,
+ '--show-row-divider': cfg.showRowDivider === false ? '0' : '1'
+ });
+ },
+ rowWrapStyle() {
+ return this.$util.objToStyle({
+ padding: `${this.config.rowPaddingY}rpx 0`
+ });
+ },
+ rowWrapClass() {
+ return this.config.showRowDivider === false ? 'order-wrap no-divider' : 'order-wrap';
+ },
+ rowCellStyle() {
+ return this.$util.objToStyle({
+ 'min-height': `${this.config.rowMinHeight}rpx`
+ });
+ },
+ // 标签宽度:根据 labelWidthMode 决定;fixed 用 --label-fixed-width,auto 用 maxLabelWidth
+ nameWidthStyle() {
+ const cfg = this.config;
+ if (cfg.labelWidthMode === 'fixed') {
+ return { width: `${cfg.labelFixedWidth}rpx` };
+ }
+ return this.maxLabelWidth ? { width: `${this.maxLabelWidth}rpx` } : { width: 'auto' };
+ },
+ // 输入框样式(input / textarea 共用)
+ inputStyle() {
+ return this.$util.objToStyle({
+ 'min-height': `${this.config.inputHeight}rpx`,
+ 'border-radius': `${this.config.inputRadius}rpx`,
+ 'font-size': `${this.config.labelFontSize}rpx`,
+ 'color': this.config.labelColor,
+ 'line-height': `${this.config.inputHeight}rpx`
+ });
+ },
+ // 必填星号颜色
+ requiredColor() {
+ return this.config.requiredColor;
+ },
+ // 复选 / 单选 选中色
+ checkedColor() {
+ return this.config.checkedColor;
+ }
+ },
created() {
- this.setFormData();
+ this.initFormData();
+ this.$nextTick(() => this.calculateMaxLabelWidth());
},
watch: {
- data: function() {
- this.setFormData();
+ data: {
+ deep: true,
+ handler() {
+ this.initFormData();
+ this.$nextTick(() => this.calculateMaxLabelWidth());
+ }
+ },
+ formConfig: {
+ deep: true,
+ handler() {
+ this.$nextTick(() => this.calculateMaxLabelWidth());
+ }
}
},
methods: {
+ initFormData() {
+ // 深拷贝 prop 数据到本地状态,避免 mutate 上游
+ this.formData = JSON.parse(JSON.stringify(this.data || []));
+ this.processFormData();
+ },
setFormData() {
- this.formData = this.data;
-
+ this.initFormData();
+ this.$nextTick(() => this.calculateMaxLabelWidth());
+ },
+ processFormData() {
this.formData.forEach(item => {
if (!item.val) item.val = item.value.default ? item.value.default : '';
@@ -356,6 +609,25 @@
}
});
},
+ // 计算最长 label 宽度(与后端 design.js calculateMaxLabelWidth 算法对齐)
+ // 用于 labelWidthMode === 'auto' 时把 .name 的 width 撑开,避免长短 label 错位
+ calculateMaxLabelWidth() {
+ if (!this.formData || this.formData.length === 0) {
+ this.maxLabelWidth = 0;
+ return;
+ }
+ const fontSize = parseInt(this.config.labelFontSize) || 28;
+ let maxChars = 0;
+ this.formData.forEach(item => {
+ if (!item.value || !item.value.title) return;
+ let len = (item.value.title || '').length;
+ if (item.value.required) len += 1;
+ if (len > maxChars) maxChars = len;
+ });
+ // 公式:chars * (fontSize/2) * 1.1 + 12,单位 px → 转 rpx(×2)
+ const widthPx = Math.max(40, maxChars * (fontSize / 2) * 1.1 + 12);
+ this.maxLabelWidth = Math.round(widthPx * 2);
+ },
verify() {
let verify = true;
@@ -643,9 +915,33 @@
};
-