chore:表单样式更新

This commit is contained in:
2026-08-28 10:22:24 +08:00
parent e3171ef7ad
commit e693e4273c
5 changed files with 205 additions and 148 deletions

View File

@@ -202,7 +202,7 @@ const localDevConfig = ({
// })['2724']; // 生物菌肥
// })['2811']; // 选择要使用的环境配置
// })['local-11']; // 选择要使用的环境配置
})['5g-59']; // 本地
})['2811']; // 本地
// })['local-2']; // 本地
// })['local-11']; // 本地
// })['1-test']; // test

View File

@@ -15,7 +15,7 @@
<ns-newform
:data="formComponents"
:customAttr="value"
:mode="mergedFormConfig.formLayout || 'horizontal'"
:mode="mergedFormConfig.formLayout || 'vertical'"
:formConfig="mergedFormConfig"
ref="nsNewform"
></ns-newform>
@@ -149,7 +149,7 @@ export default {
width: widthPct + '%',
padding: `${submitPaddingY}rpx 0`,
color: cfg.submitColor || '#ffffff',
'background-color': cfg.submitBgColor || '#ff4544',
'background-color': cfg.submitBgColor || '#3b82f6',
'border-radius': `${this._num(cfg.inputRadius, 10)}rpx`,
'font-size': `${this._num(cfg.labelFontSize, 28)}rpx`
});

View File

@@ -5,8 +5,8 @@
<view v-if="item.controller == 'Text'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
<view :class="['order-cell', { 'vertical-layout': mode === 'vertical' }]" :style="rowCellStyle">
<view class="name" :style="item._labelStyle">
<text class="tit">{{ item.value.title }}</text>
<text class="required" :style="{ color: requiredColor }">{{ item.value.required ? '*' : '' }}</text>
<text class="tit">{{ item.value.title }}</text>
</view>
<view :class="['box', 'align-left']" :style="item._boxAlignStyle">
<input
@@ -23,8 +23,8 @@
<view v-if="item.controller == 'Textarea'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
<view :class="['order-cell', 'flex-box', 'textarea', { 'vertical-layout': mode === 'vertical' }]">
<view class="name" :style="item._labelStyle">
<text class="tit">{{ item.value.title }}</text>
<text class="required" :style="{ color: requiredColor }">{{ item.value.required ? '*' : '' }}</text>
<text class="tit">{{ item.value.title }}</text>
</view>
<view :class="['box', 'align-left']" :style="item._boxAlignStyle">
<!-- 所有平台统一通过 formConfig.textareaRows / item.value.rows 控制显示行数:
@@ -51,8 +51,8 @@
>
<view :class="['order-cell', { 'vertical-layout': mode === 'vertical' }]">
<view class="name" :style="item._labelStyle">
<text class="tit">{{ item.value.title }}</text>
<text class="required" :style="{ color: requiredColor }">{{ item.value.required ? '*' : '' }}</text>
<text class="tit">{{ item.value.title }}</text>
</view>
<view :class="['box', 'box-flex', 'align-right']">
<text v-if="item.val != ''">{{ item.val }}</text>
@@ -67,22 +67,23 @@
<view v-if="item.controller == 'Checkbox'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
<view :class="['order-cell', { 'vertical-layout': mode === 'vertical' }]">
<view class="name" :style="item._labelStyle">
<text class="tit">{{ item.value.title }}</text>
<text class="required" :style="{ color: requiredColor }">{{ item.value.required ? '*' : '' }}</text>
<text class="tit">{{ item.value.title }}</text>
</view>
<view :class="['box', 'check-group-box', 'align-left', 'option-layout-' + (item.value.option_layout || 'wrap')]">
<view :class="['box', 'check-group-box', 'align-left', 'option-layout-' + (item.value.option_layout || 'vertical')]">
<checkbox-group @change="checkboxChange($event, index)" :style="item._optionLayoutStyle">
<label v-for="(v, k) in item.option_lists" :key="k">
<checkbox :value="v.value" :checked="v.checked"></checkbox>
<view class="checkbox">
<text
:class="[
'iconfont',
!v.checked ? 'icon-fuxuankuang2' : '',
v.checked ? 'icon-fuxuankuang1' : ''
]"
:style="{ color: v.checked ? checkedColor : '' }"
></text>
<text
:class="[
'iconfont',
'check-icon',
!v.checked ? 'icon-fuxuankuang2' : '',
v.checked ? 'icon-fuxuankuang1' : ''
]"
:style="{ color: v.checked ? checkedColor : '' }"
></text>
{{ v.value }}
</view>
</label>
@@ -95,22 +96,23 @@
<view v-if="item.controller == 'Radio'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
<view :class="['order-cell', { 'vertical-layout': mode === 'vertical' }]">
<view class="name" :style="item._labelStyle">
<text class="tit">{{ item.value.title }}</text>
<text class="required" :style="{ color: requiredColor }">{{ item.value.required ? '*' : '' }}</text>
<text class="tit">{{ item.value.title }}</text>
</view>
<view :class="['box', 'radio-group-box', 'align-left', 'option-layout-' + (item.value.option_layout || 'wrap')]">
<view :class="['box', 'radio-group-box', 'align-left', 'option-layout-' + (item.value.option_layout || 'vertical')]">
<radio-group @change="radioChange($event, index)" :style="item._optionLayoutStyle">
<label v-for="(v, k) in item.option_lists" :key="k">
<radio :value="v.value" :checked="item.val == v.value"></radio>
<view class="radio-box">
<text
:class="[
'iconfont',
item.val != v.value ? 'icon-yuan_checkbox' : '',
item.val == v.value ? 'icon-yuan_checked' : ''
]"
:style="{ color: item.val == v.value ? checkedColor : '' }"
></text>
<text
:class="[
'iconfont',
'radio-icon',
item.val != v.value ? 'icon-yuan_checkbox' : '',
item.val == v.value ? 'icon-yuan_checked' : ''
]"
:style="{ color: item.val == v.value ? checkedColor : '' }"
></text>
{{ v.value }}
</view>
</label>
@@ -123,8 +125,8 @@
<view v-if="item.controller == 'Img'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
<view :class="['order-cell', 'flex-box', { 'vertical-layout': mode === 'vertical' }]">
<view class="name" :style="item._labelStyle">
<text class="tit">{{ item.value.title }}</text>
<text class="required" :style="{ color: requiredColor }">{{ item.value.required ? '*' : '' }}</text>
<text class="tit">{{ item.value.title }}</text>
</view>
<view :class="['box', 'img-boxs', 'align-left']" :style="item._boxAlignStyle">
<view v-for="(v, k) in item.img_lists" :key="k" class="img-box" @tap="uploadImg(index)">
@@ -142,8 +144,8 @@
<view v-if="item.controller == 'Date'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
<view :class="['order-cell', { 'vertical-layout': mode === 'vertical' }]">
<view class="name" :style="item._labelStyle">
<text class="tit">{{ item.value.title }}</text>
<text class="required" :style="{ color: requiredColor }">{{ item.value.required ? '*' : '' }}</text>
<text class="tit">{{ item.value.title }}</text>
</view>
<view :class="['box', 'box-flex', 'align-right']">
<picker
@@ -164,8 +166,8 @@
<view v-if="item.controller == 'Datelimit'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
<view :class="['order-cell', 'flex-box', { 'vertical-layout': mode === 'vertical' }]">
<view class="name" :style="item._labelStyle">
<text class="tit">{{ item.value.title }}</text>
<text class="required" :style="{ color: requiredColor }">{{ item.value.required ? '*' : '' }}</text>
<text class="tit">{{ item.value.title }}</text>
</view>
<view :class="['box', 'date-boxs', 'align-center']" :style="item._boxAlignStyle">
<view class="date-box">
@@ -203,8 +205,8 @@
<view v-if="item.controller == 'Time'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
<view :class="['order-cell', { 'vertical-layout': mode === 'vertical' }]">
<view class="name" :style="item._labelStyle">
<text class="tit">{{ item.value.title }}</text>
<text class="required" :style="{ color: requiredColor }">{{ item.value.required ? '*' : '' }}</text>
<text class="tit">{{ item.value.title }}</text>
</view>
<view :class="['box', 'box-flex', 'align-right']">
<picker
@@ -225,8 +227,8 @@
<view v-if="item.controller == 'Timelimit'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
<view :class="['order-cell', 'flex-box', { 'vertical-layout': mode === 'vertical' }]">
<view class="name" :style="item._labelStyle">
<text class="tit">{{ item.value.title }}</text>
<text class="required" :style="{ color: requiredColor }">{{ item.value.required ? '*' : '' }}</text>
<text class="tit">{{ item.value.title }}</text>
</view>
<view :class="['box', 'date-boxs', 'align-center']" :style="item._boxAlignStyle">
<view class="date-box">
@@ -264,8 +266,8 @@
<view v-if="item.controller == 'City'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
<view :class="['order-cell', { 'vertical-layout': mode === 'vertical' }]">
<view class="name" :style="item._labelStyle">
<text class="tit">{{ item.value.title }}</text>
<text class="required" :style="{ color: requiredColor }">{{ item.value.required ? '*' : '' }}</text>
<text class="tit">{{ item.value.title }}</text>
</view>
<view :class="['box', 'box-flex', 'align-right']">
<pick-regions
@@ -302,7 +304,7 @@ export default {
},
mode: {
type: String,
default: 'horizontal',
default: 'vertical',
validator: (value) => !value || ['horizontal', 'vertical'].includes(value)
},
// 表单配置(按平台差异化)
@@ -362,40 +364,40 @@ export default {
config() {
// 内置默认值(最低优先级)- 与后端 D:\projects\shop-projects\backend\src\app\component\view\form\js\design.js getDefaultFormData().formConfig 对齐
const defaults = {
formPaddingX: 14,
formPaddingX: 28,
bannerPaddingX: 0,
tipPaddingX: 14,
rowPaddingY: 4,
tipPaddingX: 28,
rowPaddingY: 24,
rowMinHeight: 60,
labelGap: 16,
labelGap: 20,
formBgColor: '#ffffff',
rowDividerColor: '#f0f0f0',
showRowDivider: true,
inputHeight: 60,
inputRadius: 10,
showRowDivider: false,
inputHeight: 84,
inputRadius: 16,
labelWidthMode: 'auto',
labelFixedWidth: 180,
labelFontSize: 28,
labelFontSize: 32,
labelColor: '#1f2937',
labelFontWeight: 600,
labelFontWeight: 700,
labelAutoMaxWidth: 200, // auto 模式下 label 宽度上限(rpx),超过后 ellipsis 截断
requiredColor: '#ef4444',
checkedColor: '#ff4544',
placeholderColor: '#ddd',
checkedColor: '#3b82f6',
placeholderColor: '#9ca3af',
placeholderFontSize: 28,
// textarea 显示行数 / 行高(与 ns-form 保持一致,由 formConfig 覆盖)
// 改用 :rows + line-height 驱动高度,rows 给原生 <textarea>,line-height 在 textareaStyle 算 px 高度
textareaRows: 4,
textareaLineHeight: 44,
textareaLineHeight: 48,
// 输入框视觉增强(可由后端 form_config 覆盖)
inputBorderColor: '#e5e7eb',
inputBgColor: '#f9fafb',
inputFocusBorderColor: '#ff4544',
inputBgColor: '#ffffff',
inputFocusBorderColor: '#3b82f6',
inputFocusBgColor: '#ffffff',
labelFontWeight: 600,
labelFontWeight: 700,
// 提交按钮
submitColor: '#ffffff',
submitBgColor: '#ff4544',
submitBgColor: '#3b82f6',
submitMarginTop: 0, // 提交按钮顶部外边距(rpx):调整表单与按钮之间的距离
// 提示语
tipFontSize: 32,
@@ -588,22 +590,23 @@ export default {
const align = itemValue.input_align;
this.$set(item, '_boxAlignStyle', align ? { 'text-align': align } : {});
// 选项排列样式:vertical 时给 checkbox-group / radio-group 加 flex-direction
// 走 inline style(不依赖 dev 编译产物的 SCSS 类,跨端兼容更稳)
// 直接写 flex-direction 等 CSS 属性,inline style 优先级最高
const optLayout = itemValue.option_layout;
const optStyle = {};
if (optLayout === 'vertical') {
optStyle['flex-direction'] = 'column';
optStyle['align-items'] = 'flex-start';
optStyle['gap'] = '8px';
} else {
// wrap 模式:用 display: flex 基础属性兜底(不强制,让浏览器按 SCSS 默认渲染)
optStyle['flex-direction'] = 'row';
optStyle['align-items'] = 'center';
optStyle['gap'] = '6px';
}
this.$set(item, '_optionLayoutStyle', optStyle);
// 选项排列样式:默认 vertical(每项一行),仅当后端显式配置 wrap 时横向换行
// 走 inline style(不依赖 dev 编译产物的 SCSS 类,跨端兼容更稳)
// 直接写 flex-direction 等 CSS 属性,inline style 优先级最高
const optLayout = itemValue.option_layout;
const optStyle = {};
if (optLayout === 'wrap') {
// wrap 模式:横向自动换行
optStyle['flex-direction'] = 'row';
optStyle['align-items'] = 'center';
optStyle['gap'] = '12rpx';
} else {
// vertical 模式(默认):每项独立一行
optStyle['flex-direction'] = 'column';
optStyle['align-items'] = 'flex-start';
optStyle['gap'] = '20rpx';
}
this.$set(item, '_optionLayoutStyle', optStyle);
});
},
// 容器样式(提供给外部 diy-form 使用)
@@ -1012,38 +1015,38 @@ export default {
.form-wrap {
background: #fff;
/* 默认值兜底:与 ns-newform.config 默认值一致 */
--form-padding-x: 14rpx;
--form-padding-x: 28rpx;
--banner-padding-x: 0rpx;
--tip-padding-x: 14rpx;
--tip-font-size: 24rpx;
--tip-padding-x: 28rpx;
--tip-font-size: 32rpx;
--tip-color: #666666;
--tip-bg-color: #ffffff;
--row-padding-y: 4rpx;
--row-padding-y: 24rpx;
--row-min-height: 60rpx;
--label-gap: 16rpx;
--label-gap: 20rpx;
--form-bg-color: #ffffff;
--row-divider-color: #f0f0f0;
--input-height: 60rpx;
--input-radius: 10rpx;
--input-height: 84rpx;
--input-radius: 16rpx;
--label-fixed-width: 180rpx;
--label-font-size: 28rpx;
--label-font-size: 32rpx;
--label-color: #1f2937;
--required-color: #ef4444;
--checked-color: #ff4544;
--checked-color: #3b82f6;
--submit-color: #ffffff;
--submit-bg-color: #ff4544;
--placeholder-color: #ddd;
--submit-bg-color: #3b82f6;
--placeholder-color: #9ca3af;
--placeholder-font-size: 28rpx;
// textarea 行数 / 行高(运行时被 formWrapStyle 注入的 inline 覆盖;这里是兜底)
--textarea-rows: 4;
--textarea-line-height: 44rpx;
--textarea-line-height: 48rpx;
// 输入框视觉增强(边框 / 背景 / 聚焦 / label 字重)
--input-border-color: #e5e7eb;
--input-bg-color: #f9fafb;
--input-focus-border-color: #ff4544;
--input-bg-color: #ffffff;
--input-focus-border-color: #3b82f6;
--input-focus-bg-color: #ffffff;
--label-font-weight: 600;
--show-row-divider: 1;
--label-font-weight: 700;
--show-row-divider: 0;
// 与后端 form-preview-wrap.no-divider-all 对齐:整组隐藏所有行分割线
&.no-divider-all {
@@ -1097,7 +1100,8 @@ export default {
.name {
width: 100%;
margin-bottom: var(--label-gap, 16rpx);
min-height: auto;
margin-bottom: var(--label-gap, 20rpx);
margin-right: 0;
}
@@ -1161,7 +1165,7 @@ export default {
.required {
color: var(--required-color, #ef4444);
font-size: var(--item-label-font-size, var(--label-font-size, 28rpx));
margin-left: 4rpx;
margin-right: 6rpx;
font-weight: bold;
display: inline-block;
vertical-align: middle;
@@ -1223,12 +1227,12 @@ export default {
::v-deep input {
font-size: var(--label-font-size, 28rpx);
text-align: left;
height: var(--input-height, 60rpx);
height: var(--input-height, 84rpx);
border: 1rpx solid var(--input-border-color, #e5e7eb);
border-radius: var(--input-radius, 10rpx);
line-height: var(--input-height, 60rpx);
padding: 0 12rpx;
background: var(--input-bg-color, #f9fafb);
border-radius: var(--input-radius, 16rpx);
line-height: calc(var(--input-height, 84rpx) - 2rpx);
padding: 0 24rpx;
background: var(--input-bg-color, #ffffff);
color: var(--label-color, #1f2937);
transition: all 0.3s ease;
width: 100%;
@@ -1236,11 +1240,11 @@ export default {
&:focus {
background: var(--input-focus-bg-color, #ffffff);
border-color: var(--input-focus-border-color, #ff4544);
border-color: var(--input-focus-border-color, #3b82f6);
}
&::placeholder {
color: var(--placeholder-color, #ddd);
color: var(--placeholder-color, #9ca3af);
font-size: var(--placeholder-font-size, 28rpx);
}
}
@@ -1249,12 +1253,12 @@ export default {
input {
font-size: var(--label-font-size, 28rpx);
text-align: left;
height: var(--input-height, 60rpx);
height: var(--input-height, 84rpx);
border: 1rpx solid var(--input-border-color, #e5e7eb);
border-radius: var(--input-radius, 10rpx);
line-height: var(--input-height, 60rpx);
padding: 0 12rpx;
background: var(--input-bg-color, #f9fafb);
border-radius: var(--input-radius, 16rpx);
line-height: calc(var(--input-height, 84rpx) - 2rpx);
padding: 0 24rpx;
background: var(--input-bg-color, #ffffff);
color: var(--label-color, #1f2937);
transition: all 0.3s ease;
width: 100%;
@@ -1262,65 +1266,68 @@ export default {
&:focus {
background: var(--input-focus-bg-color, #ffffff);
border-color: var(--input-focus-border-color, #ff4544);
border-color: var(--input-focus-border-color, #3b82f6);
}
&::placeholder {
color: var(--placeholder-color, #ddd);
color: var(--placeholder-color, #9ca3af);
font-size: var(--placeholder-font-size, 28rpx);
}
}
// H5 端 <textarea> 被 uni-app 编译为 <uni-textarea> 自定义组件,
// 真实 <textarea> 是其子节点,需要 ::v-deep 穿透 scoped 才能命中
::v-deep textarea {
font-size: var(--label-font-size, 28rpx);
width: 100%;
// 行高 / 高度全部由 formConfig 动态决定(CSS 兜底公式与 JS textareaStyle 一致)
line-height: var(--textarea-line-height, 44rpx);
min-height: calc(var(--textarea-rows, 4) * var(--textarea-line-height, 44rpx) + 26rpx);
height: calc(var(--textarea-rows, 4) * var(--textarea-line-height, 44rpx) + 26rpx);
line-height: var(--textarea-line-height, 48rpx);
min-height: calc(var(--textarea-rows, 4) * var(--textarea-line-height, 48rpx) + 26rpx);
height: calc(var(--textarea-rows, 4) * var(--textarea-line-height, 48rpx) + 26rpx);
text-align: left;
border: 1rpx solid var(--input-border-color, #e5e7eb);
border-radius: var(--input-radius, 10rpx);
padding: 12rpx;
background: var(--input-bg-color, #f9fafb);
border-radius: var(--input-radius, 16rpx);
padding: 12rpx 24rpx;
background: var(--input-bg-color, #ffffff);
color: var(--label-color, #1f2937);
transition: all 0.3s ease;
box-sizing: border-box;
&:focus {
background: var(--input-focus-bg-color, #ffffff);
border-color: var(--input-focus-border-color, #ff4544);
border-color: var(--input-focus-border-color, #3b82f6);
}
&::placeholder {
color: var(--placeholder-color, #ddd);
color: var(--placeholder-color, #9ca3af);
font-size: var(--placeholder-font-size, 28rpx);
}
}
// 非 H5 端(小程序 / 鸿蒙 / App)<textarea> 是直接原生元素,普通选择器即可
textarea {
font-size: var(--label-font-size, 28rpx);
width: 100%;
// 行高 / 高度全部由 formConfig 动态决定(与 ::v-deep textarea 同步)
line-height: var(--textarea-line-height, 44rpx);
min-height: calc(var(--textarea-rows, 4) * var(--textarea-line-height, 44rpx) + 26rpx);
height: calc(var(--textarea-rows, 4) * var(--textarea-line-height, 44rpx) + 26rpx);
line-height: var(--textarea-line-height, 48rpx);
min-height: calc(var(--textarea-rows, 4) * var(--textarea-line-height, 48rpx) + 26rpx);
height: calc(var(--textarea-rows, 4) * var(--textarea-line-height, 48rpx) + 26rpx);
text-align: left;
border: 1rpx solid var(--input-border-color, #e5e7eb);
border-radius: var(--input-radius, 10rpx);
padding: 12rpx;
background: var(--input-bg-color, #f9fafb);
border-radius: var(--input-radius, 16rpx);
padding: 12rpx 24rpx;
background: var(--input-bg-color, #ffffff);
color: var(--label-color, #1f2937);
transition: all 0.3s ease;
box-sizing: border-box;
&:focus {
background: var(--input-focus-bg-color, #ffffff);
border-color: var(--input-focus-border-color, #ff4544);
border-color: var(--input-focus-border-color, #3b82f6);
}
&::placeholder {
color: var(--placeholder-color, #ddd);
color: var(--placeholder-color, #9ca3af);
font-size: var(--placeholder-font-size, 28rpx);
}
}
@@ -1328,22 +1335,22 @@ export default {
.uni-input, .select-address {
display: inline-block;
padding: 0;
border-radius: var(--input-radius, 10rpx);
border-radius: var(--input-radius, 16rpx);
background: transparent;
border: none;
color: var(--label-color, #1f2937);
font-size: var(--label-font-size, 28rpx);
transition: all 0.3s ease;
min-height: var(--input-height, 60rpx);
min-height: var(--input-height, 84rpx);
box-sizing: border-box;
line-height: var(--input-height, 60rpx);
line-height: var(--input-height, 84rpx);
&.color-tip {
color: var(--placeholder-color, #ddd);
color: var(--placeholder-color, #9ca3af);
}
&.empty {
color: var(--placeholder-color, #ddd);
color: var(--placeholder-color, #9ca3af);
}
}
@@ -1381,13 +1388,19 @@ export default {
}
}
// 选项排列样式:vertical = 每个选项独立一行;wrap(默认)= 横向自动换行
// 选项排列样式:vertical = 每个选项独立一行;wrap = 横向自动换行
.option-layout-vertical {
checkbox-group,
radio-group {
flex-direction: column;
align-items: flex-start;
gap: 16rpx;
width: 100%;
label {
width: 100%;
justify-content: flex-start;
padding: 12rpx 0;
}
}
}
@@ -1416,7 +1429,14 @@ export default {
.radio-box {
display: inline-flex;
align-items: center;
gap: 8rpx;
gap: 12rpx;
}
.check-icon,
.radio-icon {
font-size: 40rpx;
line-height: 1;
color: #d1d5db;
}
&.img-boxs {
@@ -1509,7 +1529,7 @@ export default {
<style lang="scss" scoped>
.placeholder {
color: #909399;
color: #9ca3af;
font-size: 28rpx;
// #ifdef H5
@@ -1518,6 +1538,6 @@ export default {
}
.color-tip {
color: #909399;
color: #9ca3af;
}
</style>

View File

@@ -81,11 +81,18 @@
sceneParams = sceneParams.split('&');
if (sceneParams.length) {
sceneParams.forEach(item => {
if (item.indexOf('id') != -1) this.id = item.split('-')[1];
// scene 中也可能携带其他参数
if (!item) return;
// 兼容标准 key=value(id=13&uniacid=1)与旧式 id-13 两种 scene 格式
let pair = item.split('=');
if (pair.length === 2 && pair[0] !== 'id') {
this.urlParams[pair[0]] = pair[1];
if (pair.length === 2) {
const key = pair[0];
const val = pair[1];
if (key === 'id') this.id = val;
else if (key === 'uniacid') this.uniacid = val;
else this.urlParams[key] = val;
} else if (item.indexOf('id') === 0 && item.indexOf('-') !== -1) {
// 旧格式兜底:id-13
this.id = item.split('-')[1];
}
});
}
@@ -344,13 +351,14 @@
.captcha-input {
flex: 1;
height: 72rpx;
line-height: 72rpx;
height: 84rpx;
line-height: 84rpx;
font-size: 28rpx;
border: 2rpx solid #e5e7eb;
border-radius: 12rpx;
padding: 0 20rpx;
border: 1rpx solid #e5e7eb;
border-radius: 16rpx;
padding: 0 24rpx;
box-sizing: border-box;
background: #ffffff;
}
.captcha-img {

View File

@@ -166,9 +166,32 @@ export default {
// - show_tip / form_tip:交给 diy-form 渲染 tip,样式走 form_config;form_tip 给保底文案
// 注:本 computed 只在 <block v-if="detail"> 内被消费,无需 null 守卫
diyValue() {
// 新视觉默认样式:强制覆盖后端 form_config 中可能存在的旧默认(horizontal / 红按钮 / 灰背景等),
// 使表单在前端统一呈现为新设计稿样式;后台仍保留行为类配置(如 captcha / behavior / submitText)。
const styleDefaults = {
formLayout: 'vertical',
formPaddingX: 28,
rowPaddingY: 24,
labelGap: 20,
labelFontSize: 32,
labelFontWeight: 700,
labelColor: '#1f2937',
inputHeight: 84,
inputRadius: 16,
inputBgColor: '#ffffff',
inputBorderColor: '#e5e7eb',
inputFocusBorderColor: '#3b82f6',
inputFocusBgColor: '#ffffff',
placeholderColor: '#9ca3af',
placeholderFontSize: 28,
checkedColor: '#3b82f6',
showRowDivider: false,
submitColor: '#ffffff',
submitBgColor: '#3b82f6'
};
return {
jsonData: this.detail.json_data,
formConfig: this.detail.form_config,
formConfig: Object.assign({}, this.detail.form_config || {}, styleDefaults),
show_banner: this.detail.show_banner,
form_banner: this.detail.form_banner || 'public/uniapp/form/banner.png',
show_tip: this.detail.show_tip,
@@ -251,13 +274,18 @@ export default {
const scene = decodeURIComponent(options.scene)
const params = scene.split('&')
params.length && params.forEach(item => {
if (item.indexOf('id') != -1) {
this.id = item.split('-')[1]
}
// scene 中也可能携带其他参数
if (!item) return;
// 兼容标准 key=value(id=13&uniacid=1)与旧式 id-13 两种 scene 格式
let pair = item.split('=');
if (pair.length === 2 && pair[0] !== 'id') {
this.urlParams[pair[0]] = pair[1];
if (pair.length === 2) {
const key = pair[0];
const val = pair[1];
if (key === 'id') this.id = val;
else if (key === 'uniacid') this.uniacid = val;
else this.urlParams[key] = val;
} else if (item.indexOf('id') === 0 && item.indexOf('-') !== -1) {
// 旧格式兜底:id-13
this.id = item.split('-')[1];
}
})
}
@@ -739,13 +767,14 @@ page {
.captcha-input {
flex: 1;
height: 72rpx;
line-height: 72rpx;
height: 84rpx;
line-height: 84rpx;
font-size: 28rpx;
border: 2rpx solid #e5e7eb;
border-radius: 12rpx;
padding: 0 20rpx;
border: 1rpx solid #e5e7eb;
border-radius: 16rpx;
padding: 0 24rpx;
box-sizing: border-box;
background: #ffffff;
}
.captcha-img {
@@ -769,13 +798,13 @@ page {
white-space: nowrap;
}
}
// 提交按钮:视觉对齐 diy-form 内置按钮(红底白字圆角,medium 内边距)
// 提交按钮:视觉对齐 diy-form 内置按钮(蓝底白字圆角,medium 内边距)
.custom-submit {
margin-top: 30rpx;
padding: 24rpx 0;
text-align: center;
color: #ffffff;
background-color: #ff4544;
background-color: #3b82f6;
border-radius: 12rpx;
font-size: 30rpx;
}