Procházet zdrojové kódy

新增首页tab栏装修与组件控制等

Blacked před 2 roky
rodič
revize
09df763f63

+ 1 - 1
.env.development

@@ -3,7 +3,7 @@ ENV = 'development'
 
 // api接口请求地址
 VUE_APP_BASE_API = 'http://lymall-platform.58for.com/apis'
-//VUE_APP_BASE_API = 'http://127.0.0.1:8088'
+//VUE_APP_BASE_API = 'http://192.168.1.176:8088'
 
 // 客服api接口请求地址
 //VUE_APP_IM_API = 'https://b2b2c-im.mall4j.com'

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

@@ -175,6 +175,14 @@ export default {
           pic: require('@/assets/img/micro-page/p-hotarea.png'),
           picActive: require('@/assets/img/micro-page/p-hotarea-active.png'),
           routerPath: () => import('../hot-area/index.vue')
+        },
+        // 分类栏
+        {
+          type: 'goodsTab',
+          title: '分类栏',
+          pic: require('@/assets/img/micro-page/p-prod-list.png'),
+          picActive: require('@/assets/img/micro-page/p-prod-list-active.png'),
+          routerPath: () => import('../goodsTab/index.vue')
         }
         // ,
         // // 分类

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

@@ -100,6 +100,11 @@
               </el-checkbox-group>
               </div>
             </el-form-item>
+            <el-form-item label="关联类型">
+              <el-select v-model="formData.categoryName" @change="changetab" :disabled="$route.query.code == 2" placeholder="请选择" value-key="categoryId">
+                <el-option v-for="item in categoryList" :key="item.categoryId" :label="item.categoryName" :value="item.categoryName"></el-option>
+              </el-select>
+            </el-form-item>
           </el-form>
         </div>
       </div>
@@ -117,6 +122,7 @@
  * */
 import { microCreateMinis } from '../../minis'
 import ProdsSelect from '@/components/prods-select'
+import {treeDataTranslate} from "@/utils";
 
 /** 商品组件 */
 export default {
@@ -125,12 +131,15 @@ export default {
   props: {},
   data () {
     return {
+      categoryList: [],
       dragIndex: '',
       enterIndex: '',
       commonCheckFieldRules: 'checkData', // 当前组件默认的规则判断函数
       dialogChooseGoods: false,
       isGetChooseData: false, // 是否该是获取选择的数据
       formData: {
+        categoryName: null,
+        categoryId: null,
         size: 2, // 一行多少个
         showContent: [1, 2, 3],
         goods: []
@@ -215,6 +224,7 @@ export default {
     }
   },
   mounted () {
+    this.getlistCategory()
     for (let i = 0; i < 4; i++) {
       this.demoGoods.push(
         {
@@ -234,6 +244,25 @@ export default {
     }
   },
   methods: {
+    getlistCategory(){
+      this.$http({
+        url: this.$http.adornUrl('/prod/category/listCategory'),
+        method: 'get',
+        params: this.$http.adornParams({
+          maxGrade: 2,
+          shopId: 1
+        })
+      }).then(({ data }) => {
+        this.categoryList = treeDataTranslate(data, 'categoryId', 'parentId')
+      })
+    },
+    changetab(val){
+      this.categoryList.forEach((item,index)=>{
+        if(item.categoryName===val){
+          this.formData.categoryId = item.categoryId;
+        }
+      })
+    },
     dragstart(index) {
       this.dragIndex = index;
     },

binární
src/views/modules/platform/feature/create/edit/components/goodsTab/category.png


+ 367 - 0
src/views/modules/platform/feature/create/edit/components/goodsTab/index.scss

@@ -0,0 +1,367 @@
+.micro-goods-box {
+  position: relative;
+  padding: 5px 5px;
+
+  .tab-f{
+    width: 100%;
+    height: 50px;
+    overflow: hidden;
+    display: flex;
+    flex-direction: row;
+
+    .tofenlei{
+      width: 10%;
+      position: absolute;
+      right: 0;
+      height: 50px;
+      line-height: 50px;
+      text-align: center;
+      font-size: 12px;
+      //background: #fff;
+
+      .categoryimg{
+        margin-top: 12px;
+        width: 25px;
+        height: 25px;
+      }
+    }
+    .tab-item{
+      //display: flex;
+      //flex-direction: row;
+      width: 90%;
+      overflow: hidden;
+
+      .tab-item-child{
+        float: left;
+        padding: 0 10px 0 10px;
+        //min-width: 50px;
+        margin-left: 5px;
+        height: 100%;
+        text-align: center;
+        line-height: 50px;
+        position: relative;
+      }
+
+      .guangbiao{
+        position: absolute;
+        //right: 2px;
+        left: 40%;
+        bottom: 5px;
+        width: 10px;
+        height: 4px;
+        border-radius: 2px;
+      }
+
+
+      .tab-item-hot{
+        position: absolute;
+        right: 2px;
+        top: 15px;
+        width: 8px;
+        height: 8px;
+        border-radius: 50%;
+      }
+    }
+  }
+
+  .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;
+            &::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,.edit-item {
+                display: block;
+              }
+            }
+            &:nth-child(5n) {
+              margin-right: 0;
+            }
+            .goods-select-item-img {
+              cursor: pointer;
+              //width: 50px;
+              padding: 0 10px 0 10px;
+              height: 40px;
+              line-height: 40px;
+              text-align: center;
+              background-repeat: no-repeat;
+              background-position: center;
+              background-size: cover;
+              font-size: 10px;
+              border-radius: 2px;
+              border: 1px solid #f1f1f1;
+            }
+            .goods-select-item-img.goods-empty {
+              background-size: 11px;
+              background-color: #f3f5f7;
+            }
+            .goods-select-item-img.add-btn {
+              border: 1px solid #EAEAF2;
+              cursor: pointer;
+            }
+            .edit-item {
+              position: absolute;
+              width: 20px;
+              height: 20px;
+              border-radius: 20px;
+              line-height: 20px;
+              text-align: center;
+              top: -10px;
+              left: -10px;
+              z-index: 15;
+              font-size: 14px;
+              cursor: pointer;
+              color: #fff;
+              background: #bbb;
+              display: none;
+            }
+            .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;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  .el-dialog .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;
+        display: flex;
+        flex-direction: row;
+        flex-wrap: wrap;
+
+        .goods-select-item {
+          position: relative;
+          display: inline-block;
+          margin: 0 16px 12px 0;
+          background-color: #fff;
+          &:hover {
+            .close-item {
+              display: block;
+            }
+          }
+          &:nth-child(6n) {
+            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;
+          }
+        }
+
+      }
+    }
+  }
+}

+ 596 - 0
src/views/modules/platform/feature/create/edit/components/goodsTab/index.vue

@@ -0,0 +1,596 @@
+<template>
+  <div class="micro-goods-box">
+    <div class="design-preview-controller">
+      <div class="tab-f" :style="'background: linear-gradient(to right, '+hexToRgba(formData.tabStyle.leftBackColor,formData.tabStyle.tabOpacity)+','+hexToRgba(formData.tabStyle.rightBackColor,formData.tabStyle.tabOpacity)+');'">
+        <div class="tab-item">
+          <div v-for="item in formData.tabList">
+            <div>
+            <div class="tab-item-child"
+                 :style="addTabForm.categoryId===item.categoryId ? 'color:' + formData.tabStyle.activeColor + ';font-weight: bold;' : 'color:' + formData.tabStyle.color">
+              {{item.categoryName}}
+              <div class="tab-item-hot" :style="'background:' + formData.tabStyle.hotColor" v-show="item.hotTip===1"></div>
+              <div class="guangbiao" :style="'background:' + formData.tabStyle.bottomColor" v-if="addTabForm.categoryId===item.categoryId"></div>
+            </div>
+            </div>
+          </div>
+        </div>
+        <div class="tofenlei">
+          <el-image class="categoryimg" :src="category"></el-image>
+        </div>
+      </div>
+      <div class="goods-list" v-if="addTabForm.loadType===2">
+        <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}">
+              <!--图片-->
+              <div class="goods-img-one"
+                   :class="{goodsImgOne1:formData.size === 1, 'goods-empty': !goodsList[0].prodId}"
+                   :style="{backgroundImage:'url('+item.pic+')'}"></div>
+              <!--end 图片-->
+              <div class="goods-box-info"
+                   :class="{goodsBoxInfo1:formData.size === 1}">
+                <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>
+                  <!--
+                    v-if="formData.showContent.find(x=>x===4)"
+                    :class="['goods-info-buy-btn','btn-type-'+formData.buy_btn_type]"
+                  >
+                    <i v-if="formData.buy_btn_type===1" :class="['btn-type-'+formData.buy_btn_type]"></i>
+                    <i v-if="formData.buy_btn_type===2" class="el-icon-circle-plus-outline"></i>
+                    <i v-if="formData.buy_btn_type===3" class="el-icon-goods"></i>
+                    <i v-if="formData.buy_btn_type===4" class="el-icon-s-goods"></i>
+                    <el-button
+                      v-if="formData.buy_btn_type>=5"
+                      :round="formData.buy_btn_type>=7"
+                      size="mini"
+                      :type="formData.buy_btn_type | buy_btn_type"
+                    >{{ formData.button_text || '马上抢' }}
+                    </el-button>
+                  </div> -->
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="empty-tips"
+             v-if="goodsList.length==0">
+          {{$t('shopFeature.goods.pleaseAddProd')}}
+        </div>
+      </div>
+      <div v-else style="text-align: center;line-height: 100px">
+        商品列表将以接口加载方式回显
+      </div>
+    </div>
+
+    <div v-if="isShowEdit"
+         class="design-editor-item design-hide-class">
+      <div class="design-config-editor">
+        <div class="design-editor-component-title">分类栏</div>
+        <!--选择商品-->
+        <el-collapse accordion>
+          <el-collapse-item>
+            <template slot="title">
+              分类栏样式
+            </template>
+            <el-form ref="formData" :model="formData" label-position="right" class="goods-select-form" label-width="100px">
+              <el-form-item label="左侧背景色">
+                <el-color-picker v-model="formData.tabStyle.leftBackColor" size="small"></el-color-picker>
+              </el-form-item>
+              <el-form-item label="右侧背景色" class="goods-select-con">
+                <el-color-picker v-model="formData.tabStyle.rightBackColor" size="small"></el-color-picker>
+              </el-form-item>
+              <el-form-item label="背景透明度" class="goods-select-con">
+                <el-input type="number" v-model="formData.tabStyle.tabOpacity" @input="validateInput"  size="small"></el-input>
+              </el-form-item>
+              <el-form-item label="下标颜色" class="goods-select-con">
+                <el-color-picker v-model="formData.tabStyle.bottomColor" size="small"></el-color-picker>
+              </el-form-item>
+              <el-form-item label="热度点颜色" class="goods-select-con">
+                <el-color-picker v-model="formData.tabStyle.hotColor" size="small"></el-color-picker>
+              </el-form-item>
+              <el-form-item label="字体颜色" class="goods-select-con">
+                <el-color-picker v-model="formData.tabStyle.color" size="small"></el-color-picker>
+              </el-form-item>
+              <el-form-item label="选中字体颜色" class="goods-select-con">
+                <el-color-picker v-model="formData.tabStyle.activeColor" size="small"></el-color-picker>
+              </el-form-item>
+            </el-form>
+          </el-collapse-item>
+        </el-collapse>
+        <div class="design-editor-component-container">
+          <el-form ref="formData" :model="formData" label-position="left" class="goods-select-form"  label-width="100">
+
+            <el-form-item label="分类列表" class="goods-select-con">
+              <div class="goods-select-list">
+                <transition-group>
+                  <div v-for="(item,index) in formData.tabList"
+                       :key="index"
+                       class="goods-select-item">
+                    <div @dragenter="tabdragenter($event, index)" @dragover="tabdragover($event, index)" @dragstart="tabdragstart(index)" draggable>
+                       <span class="edit-item"
+                             @click="openadd(item)"><i class="el-icon-edit"></i></span>
+                      <div class="goods-select-item-img" @click="clickTab(item)" :style="addTabForm.categoryId===item.categoryId?'font-weight: bold':''">{{item.categoryName}}</div>
+                      <span class="close-item"
+                            @click="formData.tabList.splice(index,1)"><i class="el-icon-delete"></i></span>
+                    </div>
+                  </div>
+                </transition-group>
+                <div class="goods-select-item">
+                  <el-button @click="openadd()">
+                    <i class="el-icon-plus"></i>
+                  </el-button>
+                </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 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>
+        </div>
+      </div>
+    </div>
+
+    <el-dialog title="tab详情" :visible.sync="adddia" width="600px">
+      <el-form :model="addTabForm" label-width="100px">
+        <el-form-item label="tab名">
+          <el-select v-model="addTabForm.categoryName" @change="changetab" :disabled="$route.query.code === 2" placeholder="请选择" value-key="categoryId">
+            <el-option v-for="item in categoryList" :key="item.categoryId" :label="item.categoryName" :value="item.categoryName"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="热提示"  class="goods-show-container">
+          <div class="goods-show-content">
+            <el-radio-group v-model="addTabForm.hotTip">
+              <el-radio :label="0">不显示</el-radio>
+              <el-radio :label="1">显示</el-radio>
+            </el-radio-group>
+          </div>
+        </el-form-item>
+        <el-form-item label="产品加载方式" class="goods-show-container">
+          <div class="goods-show-content">
+            <el-radio-group v-model="addTabForm.loadType">
+              <el-radio :label="1">接口加载</el-radio>
+              <el-radio :label="2">自定义</el-radio>
+            </el-radio-group>
+          </div>
+        </el-form-item>
+        <el-form-item v-show="addTabForm.loadType===2" label="产品列表" class="goods-show-container">
+          <div class="goods-show-content">
+            <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>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="adddia = false">取 消</el-button>
+        <el-button type="primary" @click="addtabsubmit">确 定</el-button>
+      </div>
+    </el-dialog>
+    <ProdsSelect v-if="dialogChooseGoods" ref="ProdsSelect" @refreshSelectProds="chooseGoodsFun"></ProdsSelect>
+  </div>
+</template>
+<script>
+/**
+ * 创建新组件之后,在all-can-use-components中添加
+ * 必须应用 microCreateMinis
+ * 数据必须以formData包含
+ * */
+import { microCreateMinis } from '../../minis'
+import ProdsSelect from '@/components/prods-select'
+import {treeDataTranslate} from "@/utils";
+import category from './category.png'
+/** 商品组件 */
+export default {
+  name: 'micro-goods-box',
+  mixins: [microCreateMinis],
+  props: {},
+  data () {
+    return {
+      category: category,
+      categoryList: [],
+      loadlist: [
+        {
+          value: 1,
+          label: '自定义'
+        },
+        {
+          value: 2,
+          label: '接口加载'
+        }
+      ],
+      addTabForm: {
+        hotTip: 0,
+        categoryName: null,
+        categoryId: null,
+        goods: [],
+        loadType: 1
+      },
+      adddia: false,
+      dragIndex: '',
+      tabdragIndex: '',
+      enterIndex: '',
+      commonCheckFieldRules: 'checkData', // 当前组件默认的规则判断函数
+      dialogChooseGoods: false,
+      isGetChooseData: false, // 是否该是获取选择的数据
+      formData: {
+        size: 2, // 一行多少个
+        showContent: [1, 2, 3],
+        tabOpacity: 1,
+        rightBackColor: '#fff',
+        leftBackColor: '#fff',
+        tabStyle: {
+          bottomColor: '#EE4C0C',
+          hotColor: '#EE4C0C',
+          rightBackColor: '#ffffff',
+          leftBackColor: '#ffffff',
+          tabOpacity: 100,
+          activeColor: '#000000',
+          color: '#333333'
+        },
+        tabList: []
+        // buy_btn_type: 1, // 购买按钮的样式
+        // button_text: '马上抢'// 购买按钮的文本
+      },
+      // 商品显示内容
+      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')
+        }],
+      // 一行几个
+      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: {
+    formData: {
+      handler(newValue, oldValue) {
+        console.log('newvalue',newValue)
+        if(newValue.tabStyle.tabOpacity<=0){
+          this.formData.tabStyle.tabOpacity = 0
+        }
+        if(newValue.tabStyle.tabOpacity>=100){
+          this.formData.tabStyle.tabOpacity = 100
+        }
+      },
+      deep: true // 监听对象内部的值变化
+    },
+    goodsList: {
+      deep: true,
+      handler (val) {
+        if (val.length) {
+          if (!this.goodsList.find(x => x.myGoodsType === 1)) {
+            this.addTabForm.goods = []
+            val.map(res => {
+              this.addTabForm.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
+  },
+  computed: {
+    theme () {
+      return this.$store.getters.theme
+    }
+  },
+  mounted () {
+    this.getlistCategory()
+    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) {
+      console.log('this.dataField',this.dataField)
+      this.addTabForm = this.dataField.tabList[0]
+      this.getGoodsInfo(this.dataField.tabList[0].goods, '')
+    }
+  },
+  methods: {
+    hexToRgba(hex, opacity) {
+      let str = 'rgba(' + parseInt('0x' + hex.slice(1, 3)) + ',' + parseInt('0x' + hex.slice(3, 5)) + ','
+        + parseInt('0x' + hex.slice(5, 7)) + ',' + (opacity/100) + ')';
+      return str
+    },
+    tabdragstart(index) {
+      this.tabdragIndex = index;
+    },
+    tabdragenter(e, index) {
+      e.preventDefault();
+      // 避免源对象触发自身的dragenter事件
+      if (this.tabdragIndex !== index) {
+        const moving = this.formData.tabList[this.tabdragIndex];
+        this.formData.tabList.splice(this.tabdragIndex, 1);
+        this.formData.tabList.splice(index, 0, moving);
+        // 排序变化后目标对象的索引变成源对象的索引
+        this.tabdragIndex = index;
+      }
+    },
+    tabdragover(e, index) {
+      e.preventDefault();
+    },
+    clickTab(item){
+      console.log(item)
+      this.addTabForm = item
+      this.getGoodsInfo(item.goods, '')
+    },
+    getlistCategory(){
+      this.$http({
+        url: this.$http.adornUrl('/prod/category/listCategory'),
+        method: 'get',
+        params: this.$http.adornParams({
+          maxGrade: 2,
+          shopId: 1
+        })
+      }).then(({ data }) => {
+        this.categoryList = treeDataTranslate(data, 'categoryId', 'parentId')
+      })
+    },
+    changetab(val){
+      console.log('val',val)
+      this.categoryList.forEach((item,index)=>{
+        if(item.categoryName===val){
+          this.addTabForm.categoryId = item.categoryId;
+        }
+      })
+    },
+    addtabsubmit(){
+      if(!this.addTabForm.categoryName){
+        return
+      }
+      let obj = {
+        categoryName: null,
+        categoryId: null,
+        goods: [],
+        loadType: 1
+      }
+      let arr = []
+      for(let i=0;i<this.goodsList.length;i++){
+        console.log(this.goodsList[i].prodId)
+        arr.push(this.goodsList[i].prodId)
+      }
+      obj.goods = arr
+      obj.hotTip = this.addTabForm.hotTip
+      obj.categoryName = this.addTabForm.categoryName
+      obj.categoryId = this.addTabForm.categoryId
+      obj.loadType = this.addTabForm.loadType
+      console.log('obj', obj)
+      let a = JSON.parse(JSON.stringify(obj))
+      let flag = false
+      this.formData.tabList.forEach((item,index)=>{
+        if(item.categoryId === obj.categoryId){
+          flag = true
+          this.$confirm(`名为` + obj.categoryName + `的分类已经存在了,是否覆盖?`, '提示', {
+            confirmButtonText: '确定',
+            cancelButtonText: '取消',
+            type: 'warning'
+          }).then(() => {
+            console.log('a',a)
+            this.formData.tabList[index] = a
+            this.adddia = false
+          }).catch(() => {
+            this.adddia = false
+          })
+        }
+      })
+      if(flag){
+        return
+      }
+      this.formData.tabList.push(a)
+      this.adddia = false
+      console.log('this.formdata',this.formData.tabList)
+    },
+    // 获取数据列表
+    openadd (item) {
+      console.log('item',item)
+      this.addTabForm = {
+        categoryName: null,
+        categoryId: null,
+        goods: [],
+        hotTip: 0,
+        loadType: 1
+      }
+      this.goodsList = []
+      if(!!item){
+        this.addTabForm = item
+        this.getGoodsInfo(item.goods, '')
+      }
+      this.adddia = true
+    },
+    validateInput() {
+      // 移除输入框中的前导0
+      this.formData.tabStyle.tabOpacity = this.formData.tabStyle.tabOpacity.replace(/^0+/, '');
+    },
+    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();
+    },
+    // 选择商品操作
+    selectProdHandle () {
+      this.dialogChooseGoods = true
+      this.$nextTick(() => {
+        this.$refs.ProdsSelect.init()
+      })
+    },
+    // 选择商品回调
+    chooseGoodsFun ($event) {
+      if (this.goodsList.find(x => x.myGoodsType === 1)) {
+        this.goodsList = []
+      }
+      let result = this.uniqueFun([...this.goodsList, ...$event])
+      this.goodsList = JSON.parse(JSON.stringify(result))
+      this.dialogChooseGoods = false
+    },
+    uniqueFun(arr) {
+      const map = new Map()
+      return arr.filter(item => {
+        return !map.has(item.prodId) && map.set(item.prodId, 1)
+      })
+    },
+    /** 批量获取商品详情 */
+    getGoodsInfo (prodIds, prodType) {
+      console.log('prodIDs',prodIds)
+      if(!prodIds||prodIds.length===0){
+        this.goodsList = []
+        return
+      }
+      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
+          }
+        })
+        console.log('goodsList',this.goodsList)
+      })
+    },
+    /**
+     * 按照添加的顺序排序
+     */
+    sortList (goodsList) {
+      let showArr = this.addTabForm.goods
+      goodsList.forEach(item => {
+        item.sortId = showArr.indexOf(item.prodId)
+      })
+      return goodsList.sort((a, b) => { return a.sortId - b.sortId })
+    },
+    /* 校验 */
+    checkData () {
+      if (this.formData.tabList.length > 0) {
+        for(let i=0;i<this.formData.tabList.length;i++) {
+          if (this.formData.tabList[i].loadType === 2) {
+            if (!this.formData.tabList[i].goods[0]) {
+              this.$newMessage.error(this.$i18n.t('请配置 <<' + this.formData.tabList[i].categoryName + '>> 栏下的产品列表或产品加载方式'))
+              return
+            }
+          }
+        }
+        this.myCheckResult(true)
+      } else {
+        this.$newMessage.error(this.$i18n.t('请配置tab栏内容'))
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@import './index.scss';
+</style>

+ 34 - 0
src/views/modules/platform/feature/create/edit/components/hot-area/index.vue

@@ -81,6 +81,16 @@
                @click="elxImgboxHandle">
             <i class="el-icon-plus" /> {{$t('shopFeature.imageAd.addBgImg')}}
           </div>
+          <el-card style="margin-top: 20px">
+            <div slot="header" class="clearfix">
+              <span>关联类型</span>
+              <span/>
+            </div>
+            <el-select v-model="formData.categoryName" @change="changetab" :disabled="$route.query.code == 2" placeholder="请选择" value-key="categoryId">
+              <el-option v-for="item in categoryList" :key="item.categoryId" :label="item.categoryName" :value="item.categoryName"></el-option>
+            </el-select>
+          </el-card>
+
         </div>
       </div>
     </div>
@@ -190,6 +200,7 @@ import draggable from 'vuedraggable'
 import ProdsSelect from '@/components/prods-select'
 import ElxImgbox from '@/components/elx-imgbox'
 import ChooseFeature from '@/components/choose-feature'
+import {treeDataTranslate} from "@/utils";
 
 /** 图片广告 */
 export default {
@@ -198,6 +209,7 @@ export default {
   directives: {handle: HandleDirective},
   data () {
     return {
+      categoryList: [],
       commonCheckFieldRules: 'checkData', // 当前组件默认的规则判断函数
       hotScale: 392 / 500,
       typeList: [
@@ -216,6 +228,8 @@ export default {
       currentEditIndex: 0, // 当前编辑的图片
       currentHotEditIndex: 0, // 当前编辑的热区
       formData: {
+        categoryName: null,
+        categoryId: null,
         indicator: 4, // 选择模板: 1一行一个; 2轮播海报; 3横向滑动; 4热区
         imageList: [] // 图片列表
       },
@@ -304,8 +318,28 @@ export default {
   },
   computed: {},
   mounted () {
+    this.getlistCategory()
   },
   methods: {
+    changetab(val){
+      this.categoryList.forEach((item,index)=>{
+        if(item.categoryName===val){
+          this.formData.categoryId = item.categoryId;
+        }
+      })
+    },
+    getlistCategory(){
+      this.$http({
+        url: this.$http.adornUrl('/prod/category/listCategory'),
+        method: 'get',
+        params: this.$http.adornParams({
+          maxGrade: 2,
+          shopId: 1
+        })
+      }).then(({ data }) => {
+        this.categoryList = treeDataTranslate(data, 'categoryId', 'parentId')
+      })
+    },
     /**
      * 更改自定义路径/商品
      */

+ 33 - 0
src/views/modules/platform/feature/create/edit/components/image_ad/index.vue

@@ -140,6 +140,15 @@
                   <i class="el-icon-plus" /> {{$t('shopFeature.imageAd.addBgImg')}}
                 <!-- <p style="color: #b7b7b7;">{{$t('shopFeature.imageAd.widthSuggest')}}</p> -->
               </div>
+              <el-card style="margin-top: 20px">
+                <div slot="header" class="clearfix">
+                  <span>关联类型</span>
+                  <span/>
+                </div>
+                <el-select v-model="formData.categoryName" @change="changetab" :disabled="$route.query.code == 2" placeholder="请选择" value-key="categoryId">
+                  <el-option v-for="item in categoryList" :key="item.categoryId" :label="item.categoryName" :value="item.categoryName"></el-option>
+                </el-select>
+              </el-card>
             </div>
           </div>
         </div>
@@ -206,6 +215,7 @@ import draggable from 'vuedraggable'
 import ProdsSelect from '@/components/prods-select'
 import ElxImgbox from '@/components/elx-imgbox'
 import ChooseFeature from '@/components/choose-feature/index.vue'
+import {treeDataTranslate} from "@/utils";
 
 /** 图片广告 */
 export default {
@@ -214,6 +224,7 @@ export default {
   directives: {handle: HandleDirective},
   data () {
     return {
+      categoryList: [],
       commonCheckFieldRules: 'checkData', // 当前组件默认的规则判断函数
       mySelfCheckRules: 'mySelfCheckFun', // 我自己的验证规则函数  比如弹窗之类的
       hotScale: 392 / 500,
@@ -246,6 +257,8 @@ export default {
       currentEditIndex: 0, // 当前编辑的图片
       currentHotEditIndex: 0, // 当前编辑的热区
       formData: {
+        categoryName: null,
+        categoryId: null,
         indicator: 1, // 选择模板: 1一行一个; 2轮播海报; 3横向滑动; 4热区
         imageList: [], // 图片列表
         swiperOption: {  // 轮播海报设置
@@ -345,8 +358,28 @@ export default {
   },
   computed: {},
   mounted () {
+    this.getlistCategory()
   },
   methods: {
+    changetab(val){
+      this.categoryList.forEach((item,index)=>{
+        if(item.categoryName===val){
+          this.formData.categoryId = item.categoryId;
+        }
+      })
+    },
+    getlistCategory(){
+      this.$http({
+        url: this.$http.adornUrl('/prod/category/listCategory'),
+        method: 'get',
+        params: this.$http.adornParams({
+          maxGrade: 2,
+          shopId: 1
+        })
+      }).then(({ data }) => {
+        this.categoryList = treeDataTranslate(data, 'categoryId', 'parentId')
+      })
+    },
     /**
      * 选择图片
      * @param {String} type

+ 1 - 0
src/views/modules/platform/feature/create/edit/index.vue

@@ -641,6 +641,7 @@ export default {
     /** 保存到数据库 */
     async saveData ($data, saveType) {
       saveType === 1 ? this.isSaving = true : this.isSaving2 = true
+      console.log()
       const par = {
         content: JSON.stringify($data),
         name: $data[0].dataField.title || i18n.t('shopFeature.header.microTitle')