Przeglądaj źródła

页面设计商品组功能优化

萤火科技 1 rok temu
rodzic
commit
28ca2655fc

+ 97 - 6
src/views/page/modules/editor/Editor.vue

@@ -617,7 +617,7 @@
             </div>
             <!-- 自动获取 -->
             <div v-if="curItem.params.source === 'auto'" class="block-box">
-              <div class="block-title">商品内容</div>
+              <div class="block-title">商品数据</div>
               <div class="block-item">
                 <span class="label">商品分类</span>
                 <SelectCategory v-model="curItem.params.auto.category" />
@@ -643,7 +643,7 @@
           </a-tab-pane>
           <a-tab-pane key="2" tab="样式设置">
             <div class="block-box">
-              <div class="block-title">内容样式</div>
+              <div class="block-title">商品样式</div>
               <div class="block-item">
                 <span class="label">显示类型</span>
                 <a-radio-group buttonStyle="solid" v-model="curItem.style.display">
@@ -666,22 +666,113 @@
                     <a-checkbox value="goodsName">商品名称</a-checkbox>
                     <a-checkbox value="goodsPrice">商品价格</a-checkbox>
                     <a-checkbox value="linePrice">划线价格</a-checkbox>
-                    <a-checkbox v-show="curItem.style.column === 1" value="sellingPoint">商品卖点</a-checkbox>
-                    <a-checkbox v-show="curItem.style.column === 1" value="goodsSales">商品销量</a-checkbox>
+                    <a-checkbox value="sellingPoint">商品卖点</a-checkbox>
+                    <a-checkbox value="goodsSales">商品销量</a-checkbox>
+                    <a-checkbox v-show="curItem.style.column < 3" value="cartBtn">加购按钮</a-checkbox>
                   </a-checkbox-group>
                 </div>
               </div>
+              <div class="block-item">
+                <span class="label">商品价格颜色</span>
+                <div class="item-colorPicker">
+                  <span
+                    class="rest-color"
+                    @click="onEditorResetColor(curItem.style, 'priceColor', '#ff1051')"
+                  >重置</span>
+                  <colorPicker v-model="curItem.style.priceColor" defaultColor="#ff1051" />
+                </div>
+              </div>
+              <div class="block-item">
+                <span class="label">购物车背景颜色</span>
+                <div class="item-colorPicker">
+                  <span
+                    class="rest-color"
+                    @click="onEditorResetColor(curItem.style, 'btnCartColor', '#27c29a')"
+                  >重置</span>
+                  <colorPicker v-model="curItem.style.btnCartColor" defaultColor="#27c29a" />
+                </div>
+              </div>
+              <div class="block-item">
+                <span class="label">购物车文字颜色</span>
+                <div class="item-colorPicker">
+                  <span
+                    class="rest-color"
+                    @click="onEditorResetColor(curItem.style, 'btnFontColor', '#ffffff')"
+                  >重置</span>
+                  <colorPicker v-model="curItem.style.btnFontColor" defaultColor="#ffffff" />
+                </div>
+              </div>
+              <div class="block-item">
+                <span class="label">商品卖点颜色</span>
+                <div class="item-colorPicker">
+                  <span
+                    class="rest-color"
+                    @click="onEditorResetColor(curItem.style, 'sellingColor', '#e3771f')"
+                  >重置</span>
+                  <colorPicker v-model="curItem.style.sellingColor" defaultColor="#e3771f" />
+                </div>
+              </div>
+            </div>
+            <div class="block-box">
+              <div class="block-title">卡片样式</div>
+              <div class="block-item">
+                <span class="label">内容样式</span>
+                <a-radio-group buttonStyle="solid" v-model="curItem.style.cardType">
+                  <a-radio-button value="flat">扁平</a-radio-button>
+                  <a-radio-button value="card">卡片</a-radio-button>
+                </a-radio-group>
+              </div>
+              <div class="block-item">
+                <span class="label">圆角尺寸</span>
+                <div class="item-slider">
+                  <a-slider v-model="curItem.style.borderRadius" :min="0" :max="20" />
+                  <span class="unit-text">
+                    <span>{{ curItem.style.borderRadius }}</span>
+                    <span>像素</span>
+                  </span>
+                </div>
+              </div>
+              <div class="block-item">
+                <span class="label">商品间距</span>
+                <div class="item-slider">
+                  <a-slider v-model="curItem.style.itemMargin" :min="0" :max="30" />
+                  <span class="unit-text">
+                    <span>{{ curItem.style.itemMargin }}</span>
+                    <span>像素</span>
+                  </span>
+                </div>
+              </div>
             </div>
             <div class="block-box">
               <div class="block-title">组件样式</div>
+              <div class="block-item">
+                <span class="label">上下边距</span>
+                <div class="item-slider">
+                  <a-slider v-model="curItem.style.paddingY" :min="0" :max="30" />
+                  <span class="unit-text">
+                    <span>{{ curItem.style.paddingY }}</span>
+                    <span>像素</span>
+                  </span>
+                </div>
+              </div>
+              <div class="block-item">
+                <span class="label">左右边距</span>
+                <div class="item-slider">
+                  <a-slider v-model="curItem.style.paddingX" :min="0" :max="20" />
+                  <span class="unit-text">
+                    <span>{{ curItem.style.paddingX }}</span>
+                    <span>像素</span>
+                  </span>
+                </div>
+              </div>
               <div class="block-item">
                 <span class="label">背景颜色</span>
                 <div class="item-colorPicker">
                   <span
                     class="rest-color"
-                    @click="onEditorResetColor(curItem.style, 'background', '#fff')"
+                    @click="onEditorResetColor(curItem.style, 'background', '#ffffff')"
                   >重置</span>
-                  <colorPicker v-model="curItem.style.background" defaultColor="#fff" />
+                  <colorPicker v-model="curItem.style.background" defaultColor="#ffffff" />
                 </div>
               </div>
             </div>

+ 102 - 51
src/views/page/modules/phone/Phone.vue

@@ -238,89 +238,140 @@
           <div
             v-else-if="item.type == 'goods'"
             class="diy-goods"
-            :style="{ background: item.style.background }"
+            :style="{
+              background: item.style.background, 
+              padding: `${item.style.paddingY}px ${item.style.paddingX}px`, 
+              overflow: item.style.display === 'slide' ? 'hidden' : 'unset' 
+            }"
           >
-            <ul
-              class="goods-list clearfix"
-              :class="[`display__${item.style.display}`, `column__${item.style.column}`  ]"
+            <div
+              class="goods-list"
+              :class="[`display-${item.style.display}`, `column-${item.style.column}`  ]"
             >
-              <li
+              <div
                 class="goods-item"
                 v-for="(dataItm, dataIdx) in (item.params.source == 'choice' ? item.data : item.defaultData)"
                 :key="`${index}_${dataIdx}`"
+                :class="[`display-${item.style.cardType}`]"
+                :style="{ marginBottom: `${item.style.itemMargin}px`, borderRadius: `${item.style.borderRadius}px` }"
               >
                 <!-- 单列商品 -->
                 <template v-if="item.style.column == 1">
                   <div class="flex">
                     <!-- 商品图片 -->
                     <div class="goods-item_left">
-                      <img :src="dataItm.goods_image" />
+                      <img class="image" :src="dataItm.goods_image" />
                     </div>
                     <div class="goods-item_right">
-                      <!-- 商品名称 -->
-                      <div
-                        v-if="item.style.show.includes('goodsName')"
-                        class="goods-item_title twoline-hide"
-                      >
-                        <span>{{ dataItm.goods_name }}</span>
-                      </div>
-                      <div class="goods-item_desc">
-                        <!-- 商品卖点 -->
+                      <div class="goods-info">
                         <div
-                          v-if="item.style.show.includes('sellingPoint')"
-                          class="desc-selling_point oneline-hide"
+                          v-if="inArray('goodsName', item.style.show)"
+                          class="goods-name twoline-hide"
+                        >{{ dataItm.goods_name }}</div>
+                        <div
+                          v-if="inArray('sellingPoint', item.style.show)"
+                          class="goods-selling oneline-hide"
                         >
-                          <span>{{ dataItm.selling_point }}</span>
+                          <span
+                            class="selling"
+                            :style="{ color: item.style.sellingColor }"
+                          >{{ dataItm.selling_point }}</span>
                         </div>
-                        <!-- 商品销量 -->
                         <div
-                          v-if="item.style.show.includes('goodsSales')"
-                          class="desc-goods_sales oneline-hide"
+                          v-if="inArray('goodsSales', item.style.show)"
+                          class="goods-sales oneline-hide"
                         >
-                          <span>已售{{ dataItm.goods_sales }}件</span>
+                          <span class="sales">已售{{ dataItm.goods_sales }}</span>
+                          <!-- <span class="line">|</span>
+                          <span>惊艳度100%</span>-->
                         </div>
-                        <!-- 商品价格 -->
-                        <div class="desc_footer">
-                          <span v-if="item.style.show.includes('goodsPrice')" class="price_x">
-                            <span class="small-unit">¥</span>
-                            <span>{{ dataItm.goods_price_min }}</span>
-                          </span>
-                          <span
-                            class="price_y"
-                            v-if="item.style.show.includes('linePrice') && dataItm.line_price_min > 0"
-                          >¥{{ dataItm.line_price_min }}</span>
+                        <div class="footer">
+                          <div
+                            v-if="inArray('goodsPrice', item.style.show)"
+                            class="goods-price oneline-hide"
+                            :style="{ color: item.style.priceColor }"
+                          >
+                            <span class="unit">¥</span>
+                            <span class="value">{{ dataItm.goods_price_min }}</span>
+                            <!-- <span class="unit2">到手价</span> -->
+                            <span v-if="inArray('linePrice', item.style.show)" class="line-price">
+                              <span class="unit">¥</span>
+                              <span class="value">{{ dataItm.line_price_min }}</span>
+                            </span>
+                          </div>
+                          <div
+                            v-show="inArray('cartBtn', item.style.show) && item.style.column < 3"
+                            class="action"
+                          >
+                            <div
+                              class="btn-cart"
+                              :style="{ background: item.style.btnCartColor, color: item.style.btnFontColor }"
+                            >
+                              <a-icon class="cart-icon" type="plus" />
+                            </div>
+                          </div>
                         </div>
                       </div>
                     </div>
                   </div>
                 </template>
-                <!-- 两列三列 -->
+                <!-- 两列/三列 -->
                 <template v-else>
                   <div class="goods-image">
-                    <img :src="dataItm.goods_image" />
+                    <img class="image" :src="dataItm.goods_image" />
                   </div>
-                  <div class="detail">
-                    <p
-                      v-if="item.style.show.includes('goodsName')"
+                  <div class="goods-info">
+                    <div
+                      v-if="inArray('goodsName', item.style.show)"
                       class="goods-name twoline-hide"
-                    >{{ dataItm.goods_name }}</p>
-                    <p class="detail-price">
-                      <span v-if="item.style.show.includes('goodsPrice')" class="goods-price">
-                        <span class="small-unit">¥</span>
-                        <span>{{ dataItm.goods_price_min }}</span>
-                      </span>
+                    >{{ dataItm.goods_name }}</div>
+                    <div
+                      v-if="inArray('sellingPoint', item.style.show)"
+                      class="goods-selling oneline-hide"
+                    >
                       <span
-                        v-if="item.style.show.includes('linePrice') && dataItm.line_price_min > 0"
-                        class="line-price"
+                        class="selling"
+                        :style="{ color: item.style.sellingColor }"
+                      >{{ dataItm.selling_point }}</span>
+                    </div>
+                    <div
+                      v-if="inArray('goodsSales', item.style.show)"
+                      class="goods-sales oneline-hide"
+                    >
+                      <span class="sales">已售{{ dataItm.goods_sales }}</span>
+                      <!-- <span class="line">|</span>
+                      <span>惊艳度100%</span>-->
+                    </div>
+                    <div class="footer">
+                      <div
+                        v-if="inArray('goodsPrice', item.style.show)"
+                        class="goods-price oneline-hide"
+                        :style="{ color: item.style.priceColor }"
                       >
-                        <span class="small-unit">¥</span>
-                        <span>{{ dataItm.line_price_min }}</span>
-                      </span>
-                    </p>
+                        <span class="unit">¥</span>
+                        <span class="value">{{ dataItm.goods_price_min }}</span>
+                        <!-- <span class="unit2">到手价</span> -->
+                        <span v-if="inArray('linePrice', item.style.show)" class="line-price">
+                          <span class="unit">¥</span>
+                          <span class="value">{{ dataItm.line_price_min }}</span>
+                        </span>
+                      </div>
+                      <div
+                        v-show="inArray('cartBtn', item.style.show) && item.style.column < 3"
+                        class="action"
+                      >
+                        <div
+                          class="btn-cart"
+                          :style="{ background: item.style.btnCartColor, color: item.style.btnFontColor }"
+                        >
+                          <a-icon class="cart-icon" type="plus" />
+                        </div>
+                      </div>
+                    </div>
                   </div>
                 </template>
-              </li>
-            </ul>
+              </div>
+            </div>
           </div>
 
           <!-- 辅助空白 -->

+ 160 - 108
src/views/page/modules/phone/style.less

@@ -206,7 +206,7 @@ dl {
 
       }
 
-      /* 分列布局 */
+      // 分列布局
       .avg-sm-3>.item-nav {
         width: 33.33333333%;
       }
@@ -351,7 +351,7 @@ dl {
         float: left;
       }
 
-      /* 分列布局 */
+      // 分列布局
       .avg-sm-2>.data-item {
         width: 50%;
       }
@@ -448,123 +448,123 @@ dl {
 
     // diy-商品组
     .diy-goods {
+      display: flex;
+      flex-direction: column;
+
       .goods-list {
-        padding: 2px;
+        margin-bottom: -10px;
 
-        &.display__slide {
-          //overflow-x: scroll;
-          //overflow-y: hidden;
-          overflow-x: hidden;
-          white-space: nowrap;
-          font-size: 0;
+        // 横向滑动
+        &.display-slide {
+          display: flex;
+          flex-wrap: nowrap;
 
-          &::-webkit-scrollbar {
-            display: none;
+          .goods-item {
+            flex-shrink: 0;
+            margin-right: 2.8% !important;
           }
 
-          .goods-item {
-            display: inline-block;
-            //float: unset;
+          // 双列
+          &.column-2 {
+            .goods-item {
+              flex-basis: 45.6%;
+            }
           }
-        }
 
-        &.display__list {
-          .goods-item {
-            float: left;
+          // 3列
+          &.column-3 {
+            .goods-item {
+              flex-basis: 29.46666%;
+            }
           }
         }
 
-        &.column__1 {
+        // 列表平铺
+        &.display-list {
+          display: flex;
+          flex-wrap: wrap;
+        }
+
+        // 单列
+        &.column-1 {
+          margin-bottom: 0;
+
           .goods-item {
-            width: 100%;
-            height: 140px;
             margin-bottom: 6px;
             padding: 10px;
             box-sizing: border-box;
             background: #fff;
-          }
+            flex-basis: 100%;
+            margin-right: 0;
+
+            &:last-child {
+              margin-bottom: 0 !important;
+            }
+
+            .goods-info {
+              padding: 0;
+
+              .goods-name {
+                font-size: 13.5px;
+              }
+            }
 
-          .goods-item:last-child {
-            margin-bottom: 0;
           }
 
-          /* 商品图片 */
+          // 商品图片
           .goods-item_left {
-            display: flex;
-            width: 40%;
             background: #fff;
-            align-items: center;
-          }
+            margin-right: 10px;
 
-          .goods-item_left img {
-            display: block;
-            width: 120px;
-            height: 120px;
+            .image {
+              display: block;
+              width: 120px;
+              height: 120px;
+            }
           }
 
           .goods-item_right {
             position: relative;
-            width: 60%;
-          }
-
-          /* 商品名称 */
-          .goods-item_right .goods-item_title {
-            height: 32px;
-            margin-top: 10px;
-            font-size: 13px;
-            line-height: 1.3;
-            color: #333;
-          }
-
-          .goods-item_desc {
-            margin-top: 4px;
-          }
-
-          /* 商品卖点 */
-          .desc-selling_point {
-            width: 200px;
-            height: 20px;
-            font-size: 12px;
-            color: #ff495e;
-          }
-
-          .desc-goods_sales {
-            color: #999;
-            font-size: 12px;
-          }
-
-          /* 商品价格 */
-          .desc_footer {
-            //margin-top: 6px;
-            font-size: 12px;
-          }
-
-          .desc_footer .price_x {
-            margin-right: 8px;
-            color: rgb(240, 60, 60);
-            font-size: 15px;
+            flex: 1;
           }
 
-          .desc_footer .price_y {
-            color: #999;
-            text-decoration: line-through;
-          }
         }
 
-        &.column__2 {
+        // 2列
+        &.column-2 {
           .goods-item {
-            width: 50%;
+            flex-basis: 48.6%;
+
+            &:nth-child(2n) {
+              margin-right: 0;
+            }
           }
         }
 
-        &.column__3 {
+        // 3列
+        &.column-3 {
           .goods-item {
-            width: 33.33333%;
+            flex-basis: 31.46666%;
+
+            &:nth-child(3n) {
+              margin-right: 0;
+            }
           }
         }
 
+        // 商品内容
         .goods-item {
-          padding: 3px;
+          flex-shrink: 0;
+          background-color: #fff;
+          flex: 0 1 48.6%;
+          margin-right: 2.8%;
+          border-radius: 8px;
+          overflow: hidden;
+          margin-bottom: 10px;
+
+          &.display-card {
+            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.07);
+          }
 
           .goods-image {
             position: relative;
@@ -572,60 +572,111 @@ dl {
             height: 0;
             padding-bottom: 100%;
             overflow: hidden;
-            background: #fff;
 
             &:after {
               content: '';
               display: block;
               margin-top: 100%;
-              /* margin 百分比相对父元素宽度计算 */
             }
 
-            img {
+            .image {
               position: absolute;
-              width: 100%;
-              height: 100%;
               top: 0;
               left: 0;
+              display: block;
+              width: 100%;
+              height: 100%;
               object-fit: cover;
             }
           }
 
-          .detail {
-            padding: 4px;
-            background: #fff;
-            font-size: 13px;
+          .goods-info {
+            padding: 10px;
 
             .goods-name {
-              color: #484848;
-              height: 32px;
-              overflow: hidden;
               font-size: 13px;
-              line-height: 1.3;
-            }
-
-            .goods-price {
-              font-size: 15px;
-              color: #f00;
+              color: #000;
+              margin-bottom: 4px;
+              height: 34px;
             }
 
-            .line-price {
-              margin-left: 5px;
+            .goods-selling {
               font-size: 12px;
-              text-decoration: line-through;
-              color: #999;
+              margin-bottom: 4px;
             }
 
-            .selling-point {
+            .goods-sales {
               font-size: 12px;
-              color: #f20c59;
+              color: #959595;
+              margin-bottom: 4px;
+
+              .line {
+                margin: 0 4px;
+              }
             }
+
           }
 
-          .small-unit {
-            font-size: 13px;
-            margin-right: 2px;
+          .footer {
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+
+            .goods-price {
+              position: relative;
+              color: #ff1051;
+
+              .unit {
+                font-size: 10px;
+              }
+
+              .value {
+                font-size: 15px;
+              }
+
+              .unit2 {
+                margin-left: 2px;
+                font-size: 11px;
+              }
+
+              .line-price {
+                margin-left: 3px;
+                color: #959595;
+
+                .unit {
+                  text-decoration: line-through;
+                  font-size: 11px;
+                }
+
+                .value {
+                  text-decoration: line-through;
+                  font-size: 11px;
+                }
+              }
+
+            }
+
+            .action {
+
+              .btn-cart {
+                width: 22px;
+                height: 22px;
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                background-color: #27c29a;
+                color: #fff;
+                border-radius: 50%;
+
+                .cart-icon {
+                  font-size: 13px;
+                }
+              }
+
+            }
+
           }
+
         }
       }
     }
@@ -931,6 +982,7 @@ dl {
 
     &.selected:before,
     &:hover:before {
+      z-index: 2;
       position: absolute;
       top: 0;
       left: 0;