From 755f574e8e8ce1a7050f38bfb4808964ba4a92b1 Mon Sep 17 00:00:00 2001 From: "pikachu1995@126.com" Date: Tue, 20 Oct 2026 18:46:28 +0800 Subject: [PATCH] =?UTF-8?q?feat(uniapp):=20=E6=96=B0=E5=A2=9E=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E7=BB=84=E5=90=88=E7=BB=84=E4=BB=B6=20homeComb=20?= =?UTF-8?q?=E5=B9=B6=E5=AE=8C=E5=96=84=E9=A1=B5=E9=9D=A2=E5=8F=8A=E6=A5=BC?= =?UTF-8?q?=E5=B1=82=E8=A3=85=E4=BF=AE=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/tabbar/home/index.vue | 513 ++++++++++--------- pages/tabbar/home/template/tpl_coupon.vue | 15 + pages/tabbar/home/template/tpl_flex_one.vue | 23 +- pages/tabbar/home/template/tpl_goods.vue | 66 ++- pages/tabbar/home/template/tpl_home_comb.vue | 497 ++++++++++++++++++ pages/tabbar/home/template/tpl_integral.vue | 31 +- pages/tabbar/special/special.vue | 48 +- 7 files changed, 897 insertions(+), 296 deletions(-) create mode 100644 pages/tabbar/home/template/tpl_home_comb.vue diff --git a/pages/tabbar/home/index.vue b/pages/tabbar/home/index.vue index 335be5c..01621d3 100644 --- a/pages/tabbar/home/index.vue +++ b/pages/tabbar/home/index.vue @@ -1,251 +1,262 @@ - - - - - + + + + + diff --git a/pages/tabbar/home/template/tpl_coupon.vue b/pages/tabbar/home/template/tpl_coupon.vue index 2aeba0b..32688a5 100644 --- a/pages/tabbar/home/template/tpl_coupon.vue +++ b/pages/tabbar/home/template/tpl_coupon.vue @@ -43,6 +43,7 @@ class="cp1-item" v-for="item in couponList" :key="item.id" + :style="itemGapStyle" @click="receive(item)" > @@ -77,6 +78,7 @@ class="cp2-item" v-for="item in couponList" :key="item.id" + :style="itemGapStyle" @click="receive(item)" > @@ -107,6 +109,7 @@ class="cp3-item" v-for="item in couponList" :key="item.id" + :style="itemGapStyle" @click="receive(item)" > @@ -136,6 +139,7 @@ class="cp4-item" v-for="item in couponList" :key="item.id" + :style="itemGapStyle" @click="receive(item)" > @@ -177,6 +181,11 @@ const layoutStyle = computed(() => (props.res && props.res.layoutStyle) || "1"); // 面板保存过样式字段才启用自定义样式,老数据保持原样 const styled = computed(() => props.res && props.res.paddingTop !== undefined); +const itemGapStyle = computed(() => { + if (!styled.value) return {}; + const gap = props.res?.contentGap !== undefined ? Number(props.res.contentGap) || 0 : 5; + return { marginRight: `${gap}rpx` }; +}); const wrapperStyle = computed(() => { const res = props.res || {}; if (styled.value) { @@ -291,6 +300,12 @@ function receive(item: any) { .cp-scroll { white-space: nowrap; } +.cp1-item:last-child, +.cp2-item:last-child, +.cp3-item:last-child, +.cp4-item:last-child { + margin-right: 0 !important; +} .cp-notch { position: absolute; right: 60rpx; diff --git a/pages/tabbar/home/template/tpl_flex_one.vue b/pages/tabbar/home/template/tpl_flex_one.vue index 6d9f57c..d48c180 100644 --- a/pages/tabbar/home/template/tpl_flex_one.vue +++ b/pages/tabbar/home/template/tpl_flex_one.vue @@ -26,13 +26,22 @@ const hasHotZone = computed(() => { return Array.isArray(zoneInfo) ? zoneInfo.length > 0 : !!zoneInfo; }); -const wrapperStyle = computed(() => ({ - background: props.res?.bgColor ?? "transparent", - padding: `${props.res?.paddingTop ?? 0}rpx ${props.res?.paddingX ?? 0}rpx ${props.res?.paddingBottom ?? 0}rpx`, - marginBottom: `${props.res?.pageGap ?? 0}rpx`, - borderRadius: `${props.res?.borderRadius ?? 0}rpx`, - overflow: (props.res?.borderRadius ?? 0) > 0 ? "hidden" : "visible", -})); +const wrapperStyle = computed(() => { + const r = props.res || {}; + const bg = + r.bgColor1 !== undefined + ? !r.bgColor2 || r.bgColor1 === r.bgColor2 + ? r.bgColor1 + : `linear-gradient(180deg, ${r.bgColor1}, ${r.bgColor2})` + : r.bgColor ?? "transparent"; + return { + background: bg, + padding: `${r.paddingTop ?? 0}rpx ${r.paddingX ?? 0}rpx ${r.paddingBottom ?? 0}rpx`, + marginBottom: `${r.pageGap ?? 0}rpx`, + borderRadius: `${r.borderRadius ?? 0}rpx`, + overflow: (r.borderRadius ?? 0) > 0 ? "hidden" : "visible", + }; +}); const contentStyle = computed(() => ({ borderRadius: `${props.res?.imgRadius ?? 0}rpx`, diff --git a/pages/tabbar/home/template/tpl_goods.vue b/pages/tabbar/home/template/tpl_goods.vue index 8ca0f9f..09e9766 100644 --- a/pages/tabbar/home/template/tpl_goods.vue +++ b/pages/tabbar/home/template/tpl_goods.vue @@ -165,7 +165,7 @@ const nameStyle = computed(() => const salesStyle = computed(() => props.res?.salesColor ? { color: props.res.salesColor } : {} ); -const rpx = (v: any) => `${(Number(v) || 0) * 2}rpx`; +const rpx = (v: any) => `${Number(v) || 0}rpx`; const wrapperStyle = computed(() => { const res = props.res || {}; const bg = @@ -175,11 +175,15 @@ const wrapperStyle = computed(() => { return { background: bg, padding: `${rpx(res.paddingTop)} ${rpx(res.paddingX)} ${rpx(res.paddingBottom)}`, + marginBottom: rpx(res.pageGap), borderRadius: rpx(res.borderRadius), overflow: Number(res.borderRadius) > 0 ? "hidden" : "visible", }; }); -const listStyle = computed(() => ({ gap: rpx(props.res?.contentGap ?? 10) })); +const listStyle = computed(() => { + const gap = rpx(props.res?.contentGap ?? 10); + return { gap, "--g-gap": gap }; +}); const itemStyle = computed(() => ({ borderRadius: rpx(props.res?.contentRadius ?? 7), overflow: Number(props.res?.contentRadius ?? 7) > 0 ? "hidden" : "visible", @@ -242,14 +246,15 @@ async function loadNewGoods(reset = true) { sales: g.buyCount != null ? g.buyCount : null, })); if (reset) { - // 指定商品:按选择顺序排列 + // 指定商品:按选择顺序排列(兼容 SKU id 与 goodsId) if (first.value.dataMode === "goods") { - const byGoodsId: Record = {}; + const byId: Record = {}; mapped.forEach((g: any) => { - byGoodsId[g.goodsId] = g; + if (g.id) byId[g.id] = g; + if (g.goodsId) byId[g.goodsId] = g; }); newGoodsData.value = (first.value.goodsList || []) - .map((g: any) => byGoodsId[g.id]) + .map((g: any) => byId[g.id] || byId[g.goodsId]) .filter(Boolean); } else { newGoodsData.value = mapped; @@ -479,41 +484,62 @@ $w_94: 94%; .cart-plus, .cart-cart { - width: 36rpx; - height: 36rpx; + width: 48rpx; + height: 48rpx; border-radius: 50%; } .cart-plus-label { - font-size: 28rpx; + font-size: 30rpx; line-height: 1; } .cart-text { - border-radius: 18rpx; - padding: 4rpx 18rpx; + border-radius: 24rpx; + padding: 6rpx 20rpx; } .cart-text-label { - font-size: 22rpx; + font-size: 24rpx; } -/* 卡片:左图右文 */ +/* 卡片:左图右文(参考 CRMEB 详细列表,左侧 224rpx 缩略图,右侧标题置顶、价格销量置底) */ .mode-card { flex-direction: column; .g-item { flex-direction: row; - align-items: center; - padding: 16rpx; + align-items: stretch; + padding: 20rpx; } .g-imgbox { - width: 140rpx; - height: 140rpx; - margin-right: 16rpx; + width: 224rpx; + height: 224rpx; + margin-right: 24rpx; + border-radius: 12rpx; + overflow: hidden; + } + .g-info { + min-height: 224rpx; + justify-content: space-between; } .g-name { + font-size: 28rpx; + font-weight: 500; + line-height: 40rpx; + margin-bottom: 12rpx; + } + .g-price { + font-size: 32rpx; + font-weight: 700; + margin-top: auto; margin-bottom: 8rpx; } + .g-bottom { + margin-top: 0; + } + .g-sales { + font-size: 24rpx; + } .g-cart { align-self: center; } @@ -522,7 +548,7 @@ $w_94: 94%; /* 列表:两列网格 */ .mode-list { .g-item { - width: calc(50% - 10rpx); + width: calc((100% - var(--g-gap, 10rpx)) / 2); flex-direction: column; } .g-imgbox { @@ -541,7 +567,7 @@ $w_94: 94%; /* 三列 */ .mode-three { .g-item { - width: calc(33.33% - 12rpx); + width: calc((100% - var(--g-gap, 10rpx) * 2) / 3); flex-direction: column; } .g-imgbox { diff --git a/pages/tabbar/home/template/tpl_home_comb.vue b/pages/tabbar/home/template/tpl_home_comb.vue new file mode 100644 index 0000000..62854b9 --- /dev/null +++ b/pages/tabbar/home/template/tpl_home_comb.vue @@ -0,0 +1,497 @@ + + + + + diff --git a/pages/tabbar/home/template/tpl_integral.vue b/pages/tabbar/home/template/tpl_integral.vue index 409345a..e26d0b6 100644 --- a/pages/tabbar/home/template/tpl_integral.vue +++ b/pages/tabbar/home/template/tpl_integral.vue @@ -36,7 +36,7 @@ - + - {{ item.goodsName || item.promotionName || '' }} + {{ item.goodsName || item.promotionName || '' }} ¥{{ item.points != null ? item.points : 0 }}积分 @@ -56,7 +56,7 @@ - + ¥{{ item.points != null ? item.points : 0 }}积分 - {{ item.goodsName || item.promotionName || '' }} + {{ item.goodsName || item.promotionName || '' }} - + { const res = props.res; if (res.headBgType === "image" && res.headBgImage) { return { - backgroundImage: `url(${res.headBgImage});background-size:cover;background-position:center;`, + backgroundImage: `url(${res.headBgImage})`, + backgroundSize: "cover", + backgroundPosition: "center", }; } const bg = @@ -162,9 +164,14 @@ const moreStyle = computed(() => const pointStyle = computed(() => styled.value && props.res.pointColor ? { color: props.res.pointColor } : {} ); -const gapStyle = computed(() => - styled.value ? { gap: `${Number(props.res.contentGap) || 0}rpx` } : {} +const nameStyle = computed(() => + styled.value && props.res.nameColor ? { color: props.res.nameColor } : {} ); +const gapStyle = computed(() => { + if (!styled.value) return {}; + const gap = `${Number(props.res.contentGap ?? 10) || 0}rpx`; + return { gap, "--ig-gap": gap }; +}); const imgRadiusStyle = computed(() => styled.value ? { borderRadius: `${Number(props.res.imgRadius) || 0}rpx`, overflow: "hidden" } : {} ); @@ -252,16 +259,14 @@ function goDetail(item: any) { .ig-grid2 { display: flex; flex-wrap: wrap; - justify-content: space-between; } .ig-g2-item { - width: 49%; + width: calc((100% - var(--ig-gap, 10rpx)) / 2); background: #fff; border-radius: 16rpx; overflow: hidden; padding-bottom: 16rpx; box-sizing: border-box; - margin-bottom: 16rpx; } .ig-g2-img-box { width: 100%; @@ -323,16 +328,14 @@ function goDetail(item: any) { .ig-grid3 { display: flex; flex-wrap: wrap; - justify-content: space-between; } .ig-g3-item { - width: 32.5%; + width: calc((100% - var(--ig-gap, 10rpx) * 2) / 3); background: #fff; border-radius: 16rpx; overflow: hidden; padding-bottom: 16rpx; box-sizing: border-box; - margin-bottom: 16rpx; } .ig-g3-img-box { width: 100%; diff --git a/pages/tabbar/special/special.vue b/pages/tabbar/special/special.vue index b73243c..5c02d3c 100644 --- a/pages/tabbar/special/special.vue +++ b/pages/tabbar/special/special.vue @@ -1,9 +1,9 @@