diff --git a/components-diy/diy-form.vue b/components-diy/diy-form.vue
index 5bdadbc..043a366 100644
--- a/components-diy/diy-form.vue
+++ b/components-diy/diy-form.vue
@@ -6,24 +6,44 @@
否则会触发 MP 编译器注入的 propsToData 观察者(对应编译产物里
r=function(){var o=this.value.show_banner...this.$mp.data...})
报 "Cannot read properties of undefined (reading 'show_banner')"。 -->
-
+
-
- {{ value && value.form_tip }}
-
-
-
-
- {{ submitText }}
+
+
+
+ {{ value && value.form_tip }}
+
+
+
+
+ {{ submitText }}
+
+
+
+
+ {{ value && value.form_tip }}
+
+
+
+ {{ submitText }}
+
+
@@ -58,6 +78,14 @@ export default {
type: Boolean,
default: true
},
+ // 父级容器左右内边距(rpx)。卡片模式下让 banner 图片突破这个内边距左右铺满(如 system-form-wrap 的 padding-x)。
+ // 仅在 hasBannerMode=true 时生效;默认 0(不铺满)。
+ // 引入原因:formdata.vue 的 .system-form-wrap 默认 padding: 0 50rpx,banner 图片被左右各 50rpx 收缩,
+ // 后台配 form_banner 后图片应跨越屏幕宽度,而不是被容器内缩。
+ containerInset: {
+ type: Number,
+ default: 0
+ },
// 父级可选地接管提交:传入函数 prop 时,verify 通过后由它处理 formData;
// 不传时走组件内置 defaultSubmit(兜底)。default 必须是 null,不能写成函数返回 null
onSubmit: {
@@ -108,6 +136,52 @@ export default {
padding: `0 ${this._num(this.mergedFormConfig && this.mergedFormConfig.bannerPaddingX, 0)}rpx`
});
},
+ // 后台配了 banner 图片时启用卡片浮起布局(与参考设计左图一致);无 banner 走原平铺,零外溢
+ hasBannerMode() {
+ const v = this.value || {};
+ return !!(v.show_banner && v.form_banner);
+ },
+ // 卡片容器内联样式:maring-top(负偏移让卡片向上压住 banner 底部)+ border-radius + padding-x + box-shadow + background。
+ // 数值由 formConfig 走 camelCase/snake_case 双读,缺省走默认值,使后端零配置时也能看到卡片浮起效果。
+ // 关键:卡片必须自带白底 + z-index(见 SCSS .form-card)—— 只有卡片自己的背景才能"盖住"banner 图片底部,
+ // 父级容器(如 formdata.vue 的 .system-form-wrap)是 banner 的祖先,其背景会被 banner 覆盖,无法形成浮起效果。
+ cardWrapStyle() {
+ const cfg = this.mergedFormConfig || {};
+ // 父级传了 containerInset(即 formdata.vue 场景),外层 system-form-wrap 已给左右 padding-x,这里默认 0 不重复
+ // 其他场景(diy-group / diy-article 等未传 containerInset),回退到 bannerPaddingX 或 28rpx 保证卡片模式视觉正常
+ const parentInset = this._num(this.containerInset, 0);
+ const defaultSidePad = parentInset > 0 ? 0 : this._num(cfg.bannerPaddingX, 28);
+ const sidePad = this._num(cfg.cardSidePad, defaultSidePad);
+ // overlap:负值,让卡片向上"压"住 banner 底部(与设计图一致)
+ const overlap = -Math.abs(this._num(cfg.cardOverlap, 48));
+ // 卡片圆角:缺省 24rpx(浮起卡片的圆角,比外层卡片的 16rpx 更明显,突出浮起感)
+ const radius = this._num(cfg.cardRadius, 24);
+ // 阴影:缺省中等阴影(与设计方案一致)—— 由本容器承担浮起感
+ const shadow = cfg.cardShadow || '0 8rpx 24rpx rgba(0,0,0,0.08)';
+ // 卡片底色:纯白,与设计方案一致;可由后台 formConfig.cardBgColor 覆盖
+ const bgColor = cfg.cardBgColor || '#ffffff';
+ return this.$util.objToStyle({
+ marginTop: overlap + 'rpx',
+ paddingLeft: sidePad + 'rpx',
+ paddingRight: sidePad + 'rpx',
+ borderRadius: radius + 'rpx',
+ boxShadow: shadow,
+ backgroundColor: bgColor
+ });
+ },
+ // Banner 容器破壳样式:仅在卡片模式下 + 父级传了 containerInset>0 时启用,让 banner 突破父容器 padding 跨越屏幕宽度。
+ // 计算逻辑:负 margin-left/right + 等量扩宽 width,使 banner 元素左/右边界对齐到屏幕边缘。
+ // 父级未传 containerInset 或传 0 时返回空样式,banner 保持原尺寸(零外溢)。
+ bannerBleedStyle() {
+ const inset = this._num(this.containerInset, 0);
+ if (!this.hasBannerMode || inset <= 0) return '';
+ const expand = inset * 2;
+ return this.$util.objToStyle({
+ marginLeft: -inset + 'rpx',
+ marginRight: -inset + 'rpx',
+ width: 'calc(100% + ' + expand + 'rpx)'
+ });
+ },
// 提示语样式:padding-x、font-size、color、bg-color、border-bottom(与后端 .form-preview-tip 对齐)
tipStyle() {
const cfg = this.mergedFormConfig || {};
@@ -229,7 +303,13 @@ export default {
tipFontSize: pick('tipFontSize', 'tip_font_size'),
tipColor: pick('tipColor', 'tip_color'),
tipBgColor: pick('tipBgColor', 'tip_bg_color'),
- tipBorderColor: pick('tipBorderColor', 'tip_border_color')
+ tipBorderColor: pick('tipBorderColor', 'tip_border_color'),
+ // 卡片浮起(仅 show_banner && form_banner 启用)
+ cardOverlap: pick('cardOverlap', 'card_overlap'),
+ cardRadius: pick('cardRadius', 'card_radius'),
+ cardShadow: pick('cardShadow', 'card_shadow'),
+ cardSidePad: pick('cardSidePad', 'card_side_pad'),
+ cardBgColor: pick('cardBgColor', 'card_bg_color')
};
// 移除 undefined / 空字符串(保留 0/false)
Object.keys(base).forEach(function(k) {
@@ -392,12 +472,37 @@ export default {
// 默认左右无边距(与后端 --banner-padding-x 对齐;由内联 bannerStyle 覆盖)
margin: 0;
+ // banner 图片作为卡片上方的"底图":建立层叠上下文,让 .form-card 通过 z-index 浮在其上。
+ // 仅在卡片浮起模式(.is-card-overlap)启用,不影响其它使用方(diy-group 等)的旧布局。
+ &.is-card-overlap {
+ position: relative;
+ z-index: 1;
+ }
+
.banner-img {
width: 100%;
display: block;
}
}
+ // 卡片容器:浮在 banner 图片上方(参考设计左图)。
+ // 仅在 hasBannerMode=true 时渲染(见 template v-if);
+ // 阴影 + margin-top(负偏移)+ 圆角 + 白底 全部由 cardWrapStyle 内联写入(读取后台 formConfig.card*)。
+ // 关键:卡片必须自带白底并 z-index 高于 banner,才能真正"盖住"banner 图片底部形成浮起;
+ // 父级容器(formdata.vue 的 .system-form-wrap)虽也是白底,但它是 banner 的祖先、背景会被 banner 覆盖,
+ // 因此本容器的白底不可省略(与 .system-form-wrap 同色,视觉上从卡片向下自然延续到页面底部)。
+ .form-card {
+ // 定位上下文 + 高于 banner 的层级:让卡片盖住 banner 底部(banner z-index:1)
+ position: relative;
+ z-index: 2;
+ // 兜底白底 / 圆角 / 阴影:与后端未配置时内联写入的默认值一致;后台配置时由内联 cardWrapStyle 覆盖
+ background-color: #ffffff;
+ border-radius: 24rpx;
+ box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08);
+ // 兜底 padding-bottom:让卡片与后面内容(如推荐码、其它 diy 组件)有间距
+ padding-bottom: 24rpx;
+ }
+
.form-tip {
// 提示语:上下内边距 / 左右内边距 / 字号 / 颜色 / 背景 全部由 tipStyle 内联写入
padding: 0;
diff --git a/components-diy/diy-member-my-order.vue b/components-diy/diy-member-my-order.vue
index 6f6afcf..acfd66e 100644
--- a/components-diy/diy-member-my-order.vue
+++ b/components-diy/diy-member-my-order.vue
@@ -137,8 +137,8 @@ export default {
},
computed: {
warpCss() {
- var obj = '';
- obj += 'background-color:' + this.value.componentBgColor + ';';
+ var obj = '';
+ obj += 'background-color:' + this.value.componentBgColor + ';';
if (this.value.componentAngle == 'round') {
obj += 'border-top-left-radius:' + this.value.topAroundRadius * 2 + 'rpx;';
obj += 'border-top-right-radius:' + this.value.topAroundRadius * 2 + 'rpx;';
diff --git a/components-diy/diy-recommend-code.vue b/components-diy/diy-recommend-code.vue
index d3c4b15..506f850 100644
--- a/components-diy/diy-recommend-code.vue
+++ b/components-diy/diy-recommend-code.vue
@@ -120,7 +120,7 @@
-