Explorar o código

优化首页装修商品列表

Blacked %!s(int64=2) %!d(string=hai) anos
pai
achega
cc5027796a

+ 1 - 0
src/i18n/langs/zh_CN.js

@@ -3503,6 +3503,7 @@ const zhCn = {
       titleText: '标题文本',
       notice: '公告',
       goodsList: '商品列表',
+      watergoodsList: '瀑布流列表',
       imgAd: '图片广告',
       navigationBar: '导航栏',
       activities: '促销活动',

+ 9 - 1
src/views/modules/platform/feature/create/edit/components/all-can-use-components/index.vue

@@ -136,6 +136,14 @@ export default {
           picActive: require('@/assets/img/micro-page/p-prod-list-active.png'),
           routerPath: () => import('../goods/index.vue')
         },
+        // 瀑布流商品列表
+        {
+          type: 'water-goods',
+          title: this.$i18n.t('shopFeature.allCanUse.watergoodsList'),
+          pic: require('@/assets/img/micro-page/p-prod-list.png'),
+          picActive: require('@/assets/img/micro-page/p-prod-list-active.png'),
+          routerPath: () => import('../water-goods/index.vue')
+        },
         // 图片广告
         {
           type: 'imageAd',
@@ -223,7 +231,7 @@ export default {
       let shopDisList = []
       for (let i = 0; i < this.componentLists.length; i++) {
         const item = this.componentLists[i]
-        if (item.type === 'promotionalActivities' || item.type === 'goods') {
+        if (item.type === 'promotionalActivities' || item.type === 'goods' || item.type === 'water-goods') {
           shopDisList.push(item)
         } else {
           baseList.push(item)

+ 222 - 0
src/views/modules/platform/feature/create/edit/components/water-goods/index.scss

@@ -0,0 +1,222 @@
+.micro-goods-box {
+  position: relative;
+  padding: 5px 5px;
+  .goods-list {
+    display: flex;
+    flex-wrap: wrap;
+    .goods-li {
+      width: 50%;
+      &.isGoodCell3 {
+        width: 33.33%;
+      }
+      &.isGoodCell1 {
+        width: 100%;
+      }
+      .goods-li-box {
+        padding: 10px 5px;
+        &.no-goods-price {
+          padding-bottom: 32px;
+        }
+        .goodsItem1 {
+          display: flex;
+        }
+        .goods-item {
+          position: relative;
+          .goods-img-one {
+            width: 100%;
+            background-repeat: no-repeat;
+            background-size: contain;
+            background-position: center;
+            flex: 1;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            &::before {
+              content: "";
+              padding-top: 100%;
+              float: left;
+            }
+            &::after {
+              content: "";
+              display: block;
+              clear: both;
+            }
+          }
+          .goods-img-one.goods-empty {
+            background-size: 26px;
+            background-color: #f3f5f7;
+          }
+          .goodsImgOne1 {
+            max-width: 33%;
+            margin-right: 10px;
+          }
+          .goodsBoxInfo1 {
+            max-width: 65%;
+            display: flex;
+            flex-direction: column;
+            justify-content: center;
+          }
+          .goods-box-info {
+            margin-top: 3px;
+            .goods-info-title {
+              width: 100%;
+              font-size: 12px;
+              line-height: 14px;
+              text-overflow: ellipsis;
+              -o-text-overflow: ellipsis;
+              -webkit-text-overflow: ellipsis;
+              -moz-text-overflow: ellipsis;
+              word-break: break-word;
+              display: -webkit-box;
+              -webkit-line-clamp: 1;
+              -webkit-box-orient: vertical;
+              overflow: hidden;
+            }
+            .goods-info-desc {
+              width: 100%;
+              font-size: 12px;
+              color: #999;
+              overflow: hidden;
+              text-overflow: ellipsis;
+              -o-text-overflow: ellipsis;
+              -webkit-text-overflow: ellipsis;
+              -moz-text-overflow: ellipsis;
+              white-space: nowrap;
+              margin-top: 5px;
+            }
+            .goods-info-price {
+              position: relative;
+              margin-top: 10px;
+              &.goods-cell-3 {
+                padding-right: 20px;
+              }
+              .price-info {
+                width: 100%;
+                font-size: 14px;
+                color: #ff4444;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                -o-text-overflow: ellipsis;
+                -webkit-text-overflow: ellipsis;
+                -moz-text-overflow: ellipsis;
+                white-space: nowrap;
+              }
+              .goods-info-buy-btn {
+                position: absolute;
+                top: 0;
+                right: 0;
+                .btn-type-1 {
+                  display: inline-block;
+                  width: 20px;
+                  height: 20px;
+                  background-image: url("/img/micro-page/card.png");
+                  background-size: 100%;
+                }
+                i[class^="el-icon-"] {
+                  font-size: 22px;
+                  color: #ff4444;
+                }
+                .el-button {
+                  line-height: 22px;
+                  height: 24px;
+                  padding: 0 7px;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  .design-config-editor {
+    .design-editor-component-container {
+      padding: 10px 0 !important;
+      .goods-select-form.el-form {
+        .el-form-item {
+          display: flex;
+          flex-direction: column;
+          margin-bottom: 15px
+        }
+      }
+      .goods-select-con {
+        background: #fff;
+        .goods-select-control-group {
+          display: flex;
+          align-items: center;
+        }
+        .goods-select-list {
+          display: flex;
+          flex-wrap: wrap;
+          padding: 12px 0 0 20px;
+          border: 1px solid #EAEAF2;
+          .goods-select-item {
+            position: relative;
+            display: inline-block;
+            margin: 0 16px 12px 0;
+            background-color: #fff;
+            &:hover {
+              .close-item {
+                display: block;
+              }
+            }
+            &:nth-child(5n) {
+              margin-right: 0;
+            }
+            .goods-select-item-img {
+              width: 50px;
+              height: 50px;
+              line-height: 50px;
+              text-align: center;
+              background-repeat: no-repeat;
+              background-position: center;
+              background-size: cover;
+              font-size: 10px;
+              border-radius: 2px;
+            }
+            .goods-select-item-img.goods-empty {
+              background-size: 11px;
+              background-color: #f3f5f7;
+            }
+            .goods-select-item-img.add-btn {
+              border: 1px solid #EAEAF2;
+              cursor: pointer;
+            }
+            .close-item {
+              position: absolute;
+              width: 20px;
+              height: 20px;
+              border-radius: 20px;
+              line-height: 20px;
+              text-align: center;
+              top: -10px;
+              right: -10px;
+              z-index: 15;
+              font-size: 14px;
+              cursor: pointer;
+              color: #fff;
+              background: #bbb;
+              display: none;
+            }
+          }
+        }
+
+      }
+      .goods-show-container.el-form-item {
+        ::v-deep .el-form-item__content {
+          line-height: 30px;
+          .goods-show-content {
+            border-radius: 2px;
+            padding: 15px 20px;
+            border: 1px solid #EAEAF2;
+            .el-checkbox-group {
+              display: flex;
+              flex-wrap: wrap;
+              justify-content: space-between;
+            }
+          }
+        }
+      }
+    }
+  }
+}

+ 445 - 0
src/views/modules/platform/feature/create/edit/components/water-goods/index.vue

@@ -0,0 +1,445 @@
+<template>
+  <div class="micro-goods-box">
+    <div class="design-preview-controller">
+      <div class="goods-list">
+<!--        <div v-for="(item, index) in goodsList" :key="index" class="goods-li"-->
+<!--             :class="{ isGoodCell3: formData.size === 3, isGoodCell1: formData.size === 1 }">-->
+<!--          <div class="goods-li-box"-->
+<!--               :class="{ 'no-goods-price': !formData.showContent.find(x => x === 3) && formData.showContent.find(x => x === 4) }">-->
+<!--            <div class="goods-item" :class="{ goodsItem1: formData.size === 1 }"-->
+<!--                 :style="formData.back_type==='1' ? 'backgroundImage:url(' + formData.back_imgsrc + ');background-repeat: no-repeat;background-size: 100%;padding-bottom:'+formData.bottom_height+'px' : 'background: '+ formData.back_color +';padding-bottom:'+formData.bottom_height+'px'"-->
+<!--            >-->
+<!--              &lt;!&ndash;图片&ndash;&gt;-->
+<!--              <div class="goods-img-one"-->
+<!--                   :class="{ goodsImgOne1: formData.size === 1, 'goods-empty': !goodsList[0].prodId }"-->
+<!--                   >-->
+<!--                <div :style="'backgroundImage: url(' + item.pic + ');width: '+formData.img_unit+'%;height: '+formData.img_unit+'%;padding-top: '+formData.img_unit+'%;background-repeat: no-repeat;background-size: 100%'"></div>-->
+<!--              </div>-->
+<!--              &lt;!&ndash;end 图片&ndash;&gt;-->
+<!--              <div class="goods-box-info" :class="{ goodsBoxInfo1: formData.size === 1 }" :style="'display: flex;justify-content: center;margin-top: '+formData.info_top+'px'">-->
+<!--                <div :style="'width: '+formData.info_unit+'%;'">-->
+<!--                  <div v-if="formData.showContent.find(x => x === 1)" class="goods-info-title">{{ item.prodName }}-->
+<!--                  </div>-->
+<!--                  <div v-if="formData.showContent.find(x => x === 2) && item.brief" class="goods-info-desc">-->
+<!--                    {{ item.brief }}-->
+<!--                  </div>-->
+<!--                  <div v-if="formData.showContent.find(x => x === 3) || formData.showContent.find(x => x === 4)"-->
+<!--                     class="goods-info-price " :class="{ 'goods-cell-3': formData.showContent.find(x => x === 4) }">-->
+<!--                  <div v-if="formData.showContent.find(x => x === 3)" class="price-info"><span>¥</span>{{ item.price }}-->
+<!--                  </div>-->
+<!--                  <div v-if="formData.showContent.find(x => x === 4)"-->
+<!--                       :class="['goods-info-buy-btn', 'btn-type-' + formData.buy_btn_type]">-->
+<!--                    <div v-if="formData.button_type==='1'"-->
+<!--                         :style="'width: '+formData.button_img_width+'px;height: '+formData.button_img_height+'px;overflow: hidden;'">-->
+<!--                      <div class="el-button-img"-->
+<!--                           :style="'width: '+formData.button_img_width+'px;height: '+formData.button_img_height+'px;backgroundImage: url('+formData.button_imgsrc+');background-size: 100%; background-repeat: no-repeat;'"-->
+<!--                      >-->
+<!--                      </div>-->
+<!--                    </div>-->
+<!--                    <div class="el-button" v-else-->
+<!--                         :style="'border-radius: ' + formData.button_border_radius + 'px;background-color: ' + formData.button_back_color + ';font-size:' + formData.button_font_size + 'px;'">-->
+<!--                      {{ formData.button_text || '马上抢' }}-->
+<!--                    </div>-->
+<!--                  </div>-->
+<!--                </div>-->
+<!--                </div>-->
+<!--              </div>-->
+<!--            </div>-->
+<!--          </div>-->
+<!--        </div>-->
+<!--        <div class="empty-tips" v-if="goodsList.length == 0">-->
+<!--          {{ $t('shopFeature.goods.pleaseAddProd') }}-->
+<!--        </div>-->
+
+        <waterfull :goodsList="goodsList"></waterfull>
+      </div>
+    </div>
+
+    <div v-if="isShowEdit" class="design-editor-item design-hide-class">
+      <div class="design-config-editor">
+        <div class="design-editor-component-title">{{ $t('shopFeature.allCanUse.goodsList') }}</div>
+        <!--选择商品-->
+        <div class="design-editor-component-container">
+          <el-form ref="formData" :model="formData" label-position="left" class="goods-select-form">
+            <el-form-item :label="$i18n.t('shopFeature.goods.prod')" class="goods-select-con">
+              <div  class="goods-select-list">
+                <transition-group>
+                  <div v-for="(item, index) in goodsList" :key="index" class="goods-select-item">
+                    <div  @dragenter="dragenter($event, index)" @dragover="dragover($event, index)" @dragstart="dragstart(index)" draggable >
+                      <div class="goods-select-item-img" :class="{ 'goods-empty': !goodsList[0].prodId }"
+                           :style="{ backgroundImage: 'url(' + item.pic + ')' }"></div>
+                      <span class="close-item" @click="goodsList.splice(index, 1)">x</span>
+                    </div>
+                  </div>
+                </transition-group>
+                <div class="goods-select-item">
+                  <div class="goods-select-item-img add-btn" @click="selectProdHandle">
+                    <i class="el-icon-plus"></i>
+                  </div>
+                </div>
+              </div>
+            </el-form-item>
+<!--            <el-form-item :label="$i18n.t('shopFeature.goods.listStyle')">-->
+<!--              <el-radio-group v-model="formData.size">-->
+<!--                <el-radio v-for="(count, index) in lineSize" :label="count.value" :key="index">{{-->
+<!--                    count.label-->
+<!--                  }}-->
+<!--                </el-radio>-->
+<!--              </el-radio-group>-->
+<!--            </el-form-item>-->
+<!--            <el-form-item :label="$i18n.t('shopFeature.goods.showContent')" class="goods-show-container">-->
+<!--              <div class="goods-show-content">-->
+<!--                <el-checkbox-group style="display: flex;flex-wrap: wrap;" v-model="formData.showContent">-->
+<!--                  <el-checkbox v-for="(showItem, index) in goodsShowContent" :key="index" :label="showItem.value">{{-->
+<!--                      showItem.label-->
+<!--                    }}-->
+<!--                  </el-checkbox>-->
+<!--                </el-checkbox-group>-->
+<!--              </div>-->
+<!--            </el-form-item>-->
+<!--            <el-form-item label="背景样式" class="goods-show-container">-->
+<!--              <el-radio v-model="formData.back_type" label="1">图片背景</el-radio>-->
+<!--              <el-radio v-model="formData.back_type" label="2">颜色背景</el-radio>-->
+<!--              <div class="goods-show-content" v-show="formData.back_type === '1'">-->
+<!--                <el-form-item label="背景图选择:">-->
+<!--                  <div :style="'width: 50px;height:50px;backgroundImage: url('+formData.back_imgsrc+');background-size: 100%; background-repeat: no-repeat;'">-->
+<!--                  </div>-->
+<!--                </el-form-item>-->
+<!--                <el-button @click="changeImg(2)">选择图片</el-button>-->
+<!--              </div>-->
+<!--              <div class="goods-show-content" v-show="formData.back_type === '2'">-->
+<!--                <el-form-item label="背景颜色选择:">-->
+<!--                  <el-color-picker size="small" v-model="formData.back_color"></el-color-picker>-->
+<!--                </el-form-item>-->
+<!--              </div>-->
+<!--            </el-form-item>-->
+<!--            <el-form-item label="海报比例" class="goods-show-container">-->
+<!--              <el-input type="number" v-model="formData.img_unit"></el-input>-->
+<!--            </el-form-item>-->
+<!--            <el-form-item label="详情比例" class="goods-show-container">-->
+<!--              <el-input type="number" v-model="formData.info_unit"></el-input>-->
+<!--            </el-form-item>-->
+<!--            <el-form-item label="详情位置" class="goods-show-container">-->
+<!--              <el-input type="number" v-model="formData.info_top"></el-input>-->
+<!--            </el-form-item>-->
+<!--            <el-form-item label="底部间距" class="goods-show-container">-->
+<!--              <el-input type="number" v-model="formData.bottom_height"></el-input>-->
+<!--            </el-form-item>-->
+<!--            <el-form-item v-if="formData.showContent.find(x => x === 4)" label="按钮样式" class="goods-show-container">-->
+<!--              <el-radio v-model="formData.button_type" label="1">图片按钮</el-radio>-->
+<!--              <el-radio v-model="formData.button_type" label="2">自定义按钮</el-radio>-->
+<!--              &lt;!&ndash; 上传图片按钮 &ndash;&gt;-->
+<!--              <div class="goods-show-content" v-show="formData.button_type === '1'">-->
+<!--                <el-form-item label="按钮背景图:">-->
+<!--                  <div :style="'width: 50px;height:50px;backgroundImage: url('+formData.button_imgsrc+');background-size: 100%; background-repeat: no-repeat;'">-->
+<!--                    &lt;!&ndash;                    <el-image :src="formData.button_imgsrc" style="width: 50px;height: 50px;"></el-image>&ndash;&gt;-->
+<!--                  </div>-->
+<!--                </el-form-item>-->
+<!--                <el-button @click="changeImg(1)">选择图片</el-button>-->
+<!--                <el-form-item label="背景图宽度:">-->
+<!--                  <el-input type="number" v-model="formData.button_img_width"></el-input>-->
+<!--                </el-form-item>-->
+<!--                <el-form-item label="背景图高度:">-->
+<!--                  <el-input type="number" v-model="formData.button_img_height"></el-input>-->
+<!--                </el-form-item>-->
+<!--              </div>-->
+<!--              &lt;!&ndash; 自定义按钮样式 &ndash;&gt;-->
+<!--              <div class="goods-show-content" v-show="formData.button_type === '2'">-->
+<!--                <el-form ref="form" :model="formData" label-width="100px" label-position="left" :inline="true">-->
+<!--                  <el-form-item label="文本内容:">-->
+<!--                    <el-input type="text" size="small" v-model="formData.button_text" maxlength="4"></el-input>-->
+<!--                  </el-form-item>-->
+<!--                  <el-form-item label="字体大小:">-->
+<!--                    <el-input type="number" size="small" v-model="formData.button_font_size"></el-input>-->
+<!--                  </el-form-item>-->
+<!--                  <el-form-item label="边框弧度:">-->
+<!--                    <el-input type="number" size="small" v-model="formData.button_border_radius"></el-input>-->
+<!--                  </el-form-item>-->
+<!--                  <el-form-item label="背景颜色:">-->
+<!--                    <el-color-picker size="small" v-model="formData.button_back_color"></el-color-picker>-->
+<!--                  </el-form-item>-->
+<!--                </el-form>-->
+<!--              </div>-->
+<!--            </el-form-item>-->
+          </el-form>
+        </div>
+      </div>
+    </div>
+    <prods-select v-if="dialogChooseGoods" ref="ProdsSelect" @refreshSelectProds="chooseGoodsFun"></prods-select>
+    <!-- 弹窗, 新增图片 -->
+    <elx-imgbox ref="elxImgbox" @refreshPic="refreshPic" :maxSize="10" :imgSizeLimit="false"></elx-imgbox>
+  </div>
+</template>
+<script>
+/**
+ * 创建新组件之后,在all-can-use-components中添加
+ * 必须应用 microCreateMinis
+ * 数据必须以formData包含
+ * */
+import {microCreateMinis} from '../../minis'
+import ProdsSelect from '@/components/prods-select'
+import ElxImgbox from '@/components/elx-imgbox'
+import waterfull from "@/views/modules/platform/feature/create/edit/components/water-goods/waterfull.vue";
+/** 商品组件 */
+export default {
+  name: 'micro-goods-box',
+  mixins: [microCreateMinis],
+  props: {},
+  data () {
+    return {
+      dragIndex: '',
+      enterIndex: '',
+      resourcesUrl: process.env.VUE_APP_RESOURCES_URL,
+      commonCheckFieldRules: 'checkData', // 当前组件默认的规则判断函数
+      dialogChooseGoods: false,
+      isGetChooseData: false, // 是否该是获取选择的数据
+      iconList: [{
+        value: 'el-icon-circle-plus-outline',
+        label: '1'
+      }, {
+        value: 'el-icon-goods',
+        label: '2'
+      }, {
+        value: 'el-icon-s-goods',
+        label: '3'
+      }],
+      currentEditIndex: undefined,
+      formData: {
+        size: 2, // 一行多少个
+        showContent: [1, 2, 3, 4],//1.商品名称2.商品描述3.商品价格4.按钮
+        button_type: '1',
+        goods: [],
+        button_img_width: 54,
+        button_img_height: 24,
+        button_imgsrc: undefined,//购买按钮背景图
+        buy_btn_type: 1, // 购买按钮的样式
+        button_text: '马上抢',// 购买按钮的文本
+        icon_class: 'el-icon-s-goods', //购买按钮的icon
+        button_font_size: 10,// 购买按钮的字体大小
+        button_border_radius: 0, //购买按钮边框弧度
+        button_back_color: '#ffffff', //购买按钮背景颜色
+
+        back_type: '2',
+        back_color: '#ffffff',
+        back_imgsrc: undefined, //商品卡片背景图
+        img_unit: 80,
+        info_unit: 80,
+        info_top: 10,
+        bottom_height: 10
+      },
+      // 商品显示内容
+      goodsShowContent: [
+        {
+          value: 1,
+          label: this.$i18n.t('shopFeature.goods.prodName')
+        },
+        {
+          value: 2,
+          label: this.$i18n.t('shopFeature.goods.prodDesc')
+        },
+        {
+          value: 3,
+          label: this.$i18n.t('shopFeature.goods.prodPrice')
+        },
+        {
+          value: 4,
+          label: '按钮'
+        }],
+      // 一行几个
+      lineSize: [
+        {
+          value: 1,
+          label: this.$i18n.t('shopFeature.goods.oneLineItem1')
+        },
+        {
+          value: 2,
+          label: this.$i18n.t('shopFeature.goods.oneLineItem2')
+        },
+        {
+          value: 3,
+          label: this.$i18n.t('shopFeature.goods.oneLineItem3')
+        }
+      ],
+      // 获取的接口数据
+      goodsList: [],
+      // 默认数据
+      demoGoods: []
+    }
+  },
+  watch: {
+    goodsList: {
+      deep: true,
+      handler (val) {
+        if (val.length) {
+          if (!this.goodsList.find(x => x.myGoodsType === 1)) {
+            this.formData.goods = []
+            val.map(res => {
+              this.formData.goods.push(res.prodId)
+            })
+            this.goodsList.concat(val)
+          } else {
+
+          }
+        } else {
+          this.goodsList = this.demoGoods
+        }
+      }
+    }
+  },
+  filters: {
+    buy_btn_type (val) { // 标题
+      let str = ''
+      switch (val) {
+        case 6:
+          str = 'danger'
+          break
+        case 8:
+          str = 'danger'
+          break
+      }
+      return str
+    }
+  },
+  components: {
+    ProdsSelect,
+    ElxImgbox,
+    waterfull
+  },
+  computed: {
+    theme () {
+      return this.$store.getters.theme
+    }
+  },
+  mounted () {
+    for (let i = 0; i < 4; i++) {
+      this.demoGoods.push(
+        {
+          myGoodsType: 1,
+          brief: this.$i18n.t('shopFeature.goods.prodDesc'),
+          pic: require('@/assets/img/micro-page/def.png'),
+          prodName: this.$i18n.t('shopFeature.goods.prodName'),
+          price: '90'
+        }
+      )
+    }
+    if (!this.goodsList.length) {
+      this.goodsList = this.demoGoods
+    }
+    if (Object.keys(this.dataField).length !== 0) {
+      this.getGoodsInfo(this.dataField.goods, '')
+    }
+  },
+  methods: {
+    dragstart(index) {
+      this.dragIndex = index;
+    },
+    dragenter(e, index) {
+      e.preventDefault();
+      // 避免源对象触发自身的dragenter事件
+      if (this.dragIndex !== index) {
+        const moving = this.goodsList[this.dragIndex];
+        this.goodsList.splice(this.dragIndex, 1);
+        this.goodsList.splice(index, 0, moving);
+        // 排序变化后目标对象的索引变成源对象的索引
+        this.dragIndex = index;
+      }
+    },
+    dragover(e, index) {
+      e.preventDefault();
+    },
+    /**
+     * 选择图片回调
+     * @param {String} imagePath 无前缀的图片地址字符串(多图时用,分割)
+     */
+    refreshPic(imagePath) {
+      if(this.currentEditIndex===1){
+        this.formData.button_imgsrc = this.resourcesUrl + imagePath
+      }else{
+        this.formData.back_imgsrc = this.resourcesUrl + imagePath
+      }
+      // console.log(this.formData.button_imgsrc)
+
+    },
+    /** 更换图片 */
+    changeImg(index) {
+      console.log(index)
+      this.isChangeImg = true
+      this.currentEditIndex = index
+      this.elxImgboxHandle(1)
+      // this.canChooseImagesNum = 1
+    },
+    elxImgboxHandle(type) {
+      if (this.disabled) {
+        return false
+      }
+      this.elxImgboxVisible = true
+      this.$nextTick(() => {
+        this.$refs.elxImgbox.init(type || 2, 1)
+      })
+    },
+    // 选择商品操作
+    selectProdHandle() {
+      this.dialogChooseGoods = true
+      this.$nextTick(() => {
+        this.$refs.ProdsSelect.init()
+      })
+    },
+    // 选择商品回调
+    chooseGoodsFun($event) {
+      if ($event) {
+        if (this.goodsList.find(x => x.myGoodsType === 1)) {
+          this.goodsList = []
+        }
+        $event.map(newGoodItem => {
+          if (this.formData.goods.indexOf(newGoodItem.prodId) === -1) {
+            this.goodsList.push(newGoodItem)
+          }
+        })
+      }
+      this.dialogChooseGoods = false
+    },
+    /** 批量获取商品详情 */
+    getGoodsInfo(prodIds, prodType) {
+      this.$http({
+        url: this.$http.adornUrl('/prod/prod/listProdByIdsAndType'),
+        method: 'get',
+        params: this.$http.adornParams({
+          prodIds,
+          prodType
+        })
+      }).then(({data}) => {
+        this.goodsList = this.sortList(data)
+        this.goodsList.forEach(item => {
+          if (!item.pic.includes('http')) {
+            item.pic = process.env.VUE_APP_RESOURCES_URL + item.pic
+          }
+        })
+      })
+    },
+    /**
+     * 按照添加的顺序排序
+     */
+    sortList(goodsList) {
+      let showArr = this.dataField.goods
+      goodsList.forEach(item => {
+        item.sortId = showArr.indexOf(item.prodId)
+      })
+      return goodsList.sort((a, b) => {
+        return a.sortId - b.sortId
+      })
+    },
+    /* 校验 */
+    checkData() {
+      if (this.formData.goods.length > 0) {
+        this.myCheckResult(true)
+      } else {
+        this.$newMessage.error(this.$i18n.t('shopFeature.goods.pleaseAddProd'))
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@import './index.scss';
+</style>

+ 200 - 0
src/views/modules/platform/feature/create/edit/components/water-goods/waterfull.vue

@@ -0,0 +1,200 @@
+<template>
+  <div class="waterfull" :style="'height:'+comheight+'px'">
+    <div class="v-waterfall-content" id="v-waterfall">
+      <div v-for="(img, index) in waterfallList" :key="index" class="v-waterfall-item" :style="{top:img.top+'px',left:img.left+'px',width:waterfallImgWidth+'px',height:img.height}">
+        <img :src="img.src" alt="">
+        <div class="title">{{img.title}}</div>
+        <div class="info">{{img.info}}</div>
+        <div class="button">去定制</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "v-waterfall",
+  props:{
+    goodsList:{
+      type: Array,
+      default: []
+    }
+  },
+  data() {
+    return {
+      waterfallList: [],
+      imgArr: [],
+      // waterfallImgWidth: 100,
+      waterfallImgWidth: 186,// 每个盒子的宽度
+      // waterfallImgCol: 5,// 瀑布流的列数
+      waterfallImgCol: 2,// 瀑布流的列数
+      waterfallImgRight: 0,// 每个盒子的右padding
+      waterfallImgBottom: 10,// 每个盒子的下padding
+      waterfallDeviationHeight: [],
+      imgList: [],
+      comheight: 200
+    }
+  },
+  watch:{
+    goodsList(newVal, oldVal){
+      console.log('更新数据', newVal)
+      this.calculationWidth();
+    }
+  },
+  created() {
+    // 触发入口
+    // for (let i = 0; i < this.imgArr.length; i++) {
+    //   // this.imgList.push(this.imgArr[Math.round(Math.random() * 8)]);// 图片随机显示
+    //   this.imgList.push(this.imgArr[i]);
+    // }
+  },
+  mounted() {
+    // this.calculationWidth();
+  },
+  methods: {
+    //计算每个图片的宽度或者是列数
+    calculationWidth() {
+      let domWidth = document.getElementById("v-waterfall").offsetWidth;
+      if (!this.waterfallImgWidth && this.waterfallImgCol) {
+        this.waterfallImgWidth = (domWidth - this.waterfallImgRight * this.waterfallImgCol) / this.waterfallImgCol;
+      } else if (this.waterfallImgWidth && !this.waterfallImgCol) {
+        this.waterfallImgCol = Math.floor(domWidth / (this.waterfallImgWidth + this.waterfallImgRight))
+      }
+      //初始化偏移高度数组
+      this.waterfallDeviationHeight = new Array(this.waterfallImgCol);
+      for (let i = 0; i < this.waterfallDeviationHeight.length; i++) {
+        this.waterfallDeviationHeight[i] = 0;
+      }
+      this.imgPreloading()
+    },
+    //图片预加载
+    imgPreloading() {
+      let arr = []
+      for (let i = 0; i < this.goodsList.length; i++) {
+        let aImg = new Image();
+        aImg.src = this.goodsList[i].pic;
+        aImg.onload = aImg.onerror = (e) => {
+          let imgData = {};
+          imgData.height = this.waterfallImgWidth / aImg.width * aImg.height;
+          imgData.src = this.goodsList[i].pic;
+          imgData.title = this.goodsList[i].prodName;// 说明文字(也可以自己写数组,或者封装json数据,都可以,但是前提是你会相关操作,这里不赘述)
+          imgData.info = this.goodsList[i].brief;// 说明文字
+          arr.push(imgData);
+          this.rankImg(imgData);
+        }
+      }
+      this.waterfallList = arr
+      for(let i=0;i<this.waterfallList.length;i++){
+        this.rankImg(imgData);
+      }
+      for (let i = 0; i < this.imgList.length; i++) {
+        let aImg = new Image();
+        aImg.src = this.imgList[i];
+        aImg.onload = aImg.onerror = (e) => {
+          let imgData = {};
+          imgData.height = this.waterfallImgWidth / aImg.width * aImg.height;
+          imgData.src = this.imgList[i];
+          imgData.title = '标题';// 说明文字(也可以自己写数组,或者封装json数据,都可以,但是前提是你会相关操作,这里不赘述)
+          imgData.info = '详情说明:啦啦啦啦啦';// 说明文字
+          this.waterfallList.push(imgData);
+          this.rankImg(imgData);
+        }
+      }
+    },
+    //瀑布流布局
+    rankImg(imgData) {
+      let {
+        waterfallImgWidth,
+        waterfallImgRight,
+        waterfallImgBottom,
+        waterfallDeviationHeight,
+        waterfallImgCol
+      } = this;
+      let minIndex = this.filterMin();
+      imgData.top = waterfallDeviationHeight[minIndex];
+      imgData.left = minIndex * (waterfallImgRight + waterfallImgWidth) + 5;
+      // waterfallDeviationHeight[minIndex] += imgData.height + waterfallImgBottom;// 不加文字的盒子高度
+      waterfallDeviationHeight[minIndex] += imgData.height + waterfallImgBottom + 50;// 加了文字的盒子高度,留出文字的地方(这里设置56px)
+      console.log(imgData);
+    },
+    /**
+     * 找到最短的列并返回下标
+     * @returns {number} 下标
+     */
+    filterMin() {
+      const min = Math.min.apply(null, this.waterfallDeviationHeight);
+      this.comheight = Math.max.apply(null, this.waterfallDeviationHeight)+300
+      return this.waterfallDeviationHeight.indexOf(min);
+    }
+  }
+}
+</script>
+
+<style scoped>
+.waterfull{
+  width: 100%;
+}
+.v-waterfall-content {
+  /* 主要 */
+  width: 100%;
+  position: relative;
+  //min-height: 1000px;
+  /* 次要:设置滚动条,要求固定高度 */
+  //overflow-y: auto;
+}
+
+.v-waterfall-item {
+  /* 主要 */
+  float: left;
+  position: absolute;
+
+}
+
+.v-waterfall-item img {
+  /* 主要 */
+  /* width: auto;height: auto; */
+  width: 90%;height: auto;
+  /* 次要 */
+  border-radius: 6px;
+}
+.title{
+  width: 90%;
+  font-size: 12px;
+  line-height: 20px;
+  text-overflow: ellipsis;
+  -o-text-overflow: ellipsis;
+  -webkit-text-overflow: ellipsis;
+  -moz-text-overflow: ellipsis;
+  word-break: break-word;
+  display: -webkit-box;
+  -webkit-line-clamp: 1;
+  -webkit-box-orient: vertical;
+  overflow: hidden;
+}
+
+.info{
+  width: 90%;
+  font-size: 12px;
+  color: #999;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  -o-text-overflow: ellipsis;
+  -webkit-text-overflow: ellipsis;
+  -moz-text-overflow: ellipsis;
+  white-space: nowrap;
+  margin-top: 5px;
+}
+
+.button{
+  width: 50px;
+  height: 20px;
+  border: 1px solid lightgray;
+  font-size: 12px;
+  border-radius: 10px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  margin-top: 10px;
+}
+
+</style>