瀏覽代碼

1. 新增

MONSTER-ygh 11 月之前
父節點
當前提交
e7448abfd0
共有 87 個文件被更改,包括 19483 次插入186 次删除
  1. 1 0
      package.json
  2. 42 0
      src/asEditorComponents/componentscom/auxiliarysegmentation/index.vue
  3. 99 0
      src/asEditorComponents/componentscom/captiontext/index.vue
  4. 72 0
      src/asEditorComponents/componentscom/commoditysearch/index.vue
  5. 95 0
      src/asEditorComponents/componentscom/communitypowder/index.vue
  6. 23 0
      src/asEditorComponents/componentscom/crowdoperation/index.vue
  7. 26 0
      src/asEditorComponents/componentscom/custommodule/index.vue
  8. 31 0
      src/asEditorComponents/componentscom/entertheshop/index.vue
  9. 62 0
      src/asEditorComponents/componentscom/follow/index.vue
  10. 142 0
      src/asEditorComponents/componentscom/graphicnavigation/index.vue
  11. 272 0
      src/asEditorComponents/componentscom/investigate/index.vue
  12. 1458 0
      src/asEditorComponents/componentscom/listswitching/index.vue
  13. 445 0
      src/asEditorComponents/componentscom/magiccube/index.vue
  14. 29 0
      src/asEditorComponents/componentscom/notice/index.vue
  15. 23 0
      src/asEditorComponents/componentscom/onlineservice/index.vue
  16. 23 0
      src/asEditorComponents/componentscom/personalizedrecommendation/index.vue
  17. 320 0
      src/asEditorComponents/componentscom/pictureads/index.vue
  18. 35 0
      src/asEditorComponents/componentscom/placementarea/index.vue
  19. 42 0
      src/asEditorComponents/componentscom/richtext/index.vue
  20. 428 0
      src/asEditorComponents/componentscom/storeinformation/index.vue
  21. 513 0
      src/asEditorComponents/componentscom/storenotecard/index.vue
  22. 45 0
      src/asEditorComponents/componentscom/suspension/index.vue
  23. 102 0
      src/asEditorComponents/componentscom/tabBar/index.vue
  24. 64 0
      src/asEditorComponents/componentscom/videoss/index.vue
  25. 92 0
      src/asEditorComponents/headerTop/index.vue
  26. 20 0
      src/asEditorComponents/phoneBottom/index.vue
  27. 54 0
      src/asEditorComponents/realTimeView/index.vue
  28. 229 0
      src/asEditorComponents/rightslider/auxiliarysegmentationstyle/index.vue
  29. 335 0
      src/asEditorComponents/rightslider/captiontextsstyle/index.vue
  30. 326 0
      src/asEditorComponents/rightslider/commoditysearchstyle/index.vue
  31. 221 0
      src/asEditorComponents/rightslider/communitypowderstyle/index.vue
  32. 116 0
      src/asEditorComponents/rightslider/componenmanagement/index.vue
  33. 35 0
      src/asEditorComponents/rightslider/crowdoperationstyle/index.vue
  34. 40 0
      src/asEditorComponents/rightslider/custommodulestyle/index.vue
  35. 278 0
      src/asEditorComponents/rightslider/decorate/index.vue
  36. 175 0
      src/asEditorComponents/rightslider/entertheshopstyle/index.vue
  37. 109 0
      src/asEditorComponents/rightslider/followStyle/index.vue
  38. 454 0
      src/asEditorComponents/rightslider/graphicnavigationstyle/index.vue
  39. 175 0
      src/asEditorComponents/rightslider/investigatestyle/index.vue
  40. 823 0
      src/asEditorComponents/rightslider/listswitchingstyle/index.vue
  41. 627 0
      src/asEditorComponents/rightslider/magiccubestyle/index.vue
  42. 122 0
      src/asEditorComponents/rightslider/noticestyle/index.vue
  43. 35 0
      src/asEditorComponents/rightslider/onlineservicestyle/index.vue
  44. 35 0
      src/asEditorComponents/rightslider/personalizedrecommendationstyle/index.vue
  45. 471 0
      src/asEditorComponents/rightslider/pictureadsstyle/index.vue
  46. 206 0
      src/asEditorComponents/rightslider/richtextstyle/index.vue
  47. 196 0
      src/asEditorComponents/rightslider/storeinformationstyle/index.vue
  48. 603 0
      src/asEditorComponents/rightslider/storenotecardstyle/index.vue
  49. 97 0
      src/asEditorComponents/rightslider/suspensionstyle/index.vue
  50. 363 0
      src/asEditorComponents/rightslider/tabBarStyle/index.vue
  51. 82 0
      src/asEditorComponents/rightslider/videostyle/index.vue
  52. 279 0
      src/asEditorComponents/sliderassembly/index.vue
  53. 204 0
      src/asEditorComponents/uploadCommodity/index.vue
  54. 175 0
      src/asEditorComponents/uploadImg/index.vue
  55. 16 0
      src/assets/css/minx.less
  56. 194 0
      src/assets/css/reset.css
  57. 2884 0
      src/assets/css/skin.css
  58. 二進制
      src/assets/images/Robot.png
  59. 二進制
      src/assets/images/add.png
  60. 二進制
      src/assets/images/backimg.png
  61. 二進制
      src/assets/images/card.png
  62. 二進制
      src/assets/images/fwb.png
  63. 二進制
      src/assets/images/headerimg.png
  64. 二進制
      src/assets/images/il.jpg
  65. 二進制
      src/assets/images/imgs.png
  66. 二進制
      src/assets/images/login-prod.jpg
  67. 二進制
      src/assets/images/mor.png
  68. 二進制
      src/assets/images/obliqueLine.png
  69. 二進制
      src/assets/images/phoneTop.png
  70. 二進制
      src/assets/images/powder.png
  71. 818 0
      src/myComponents/asEditor.vue
  72. 398 0
      src/utils/asEditor/componentProperties.js
  73. 27 0
      src/utils/asEditor/filter.js
  74. 126 0
      src/utils/asEditor/index.js
  75. 37 0
      src/utils/asEditor/upload.js
  76. 65 30
      src/views/tourism/marketingActivities/couponManagement.vue
  77. 25 20
      src/views/tourism/marketingActivities/couponVerification.vue
  78. 424 61
      src/views/tourism/marketingActivities/detailsBox/couponManagementDetails.vue
  79. 58 31
      src/views/tourism/marketingActivities/detailsBox/couponVerificationDetails.vue
  80. 326 0
      src/views/tourism/marketingActivities/detailsBox/eventManagementDetails.vue
  81. 302 0
      src/views/tourism/marketingActivities/eventManagement.vue
  82. 405 44
      src/views/tourism/marketingActivities/formBox/couponManagementForm.vue
  83. 533 0
      src/views/tourism/marketingActivities/formBox/eventManagementForm.vue
  84. 489 0
      src/views/tourism/marketingActivities/model/selectMemberInformation.vue
  85. 489 0
      src/views/tourism/marketingActivities/model/selectMembershipLevel.vue
  86. 489 0
      src/views/tourism/marketingActivities/model/selectTicketOrders.vue
  87. 9 0
      vue.config.js

+ 1 - 0
package.json

@@ -47,6 +47,7 @@
     "file-saver": "2.0.5",
     "fuse.js": "6.4.3",
     "highlight.js": "9.18.5",
+    "html2canvas": "^1.4.1",
     "js-beautify": "1.13.0",
     "js-cookie": "3.0.1",
     "jsencrypt": "3.0.0-rc.1",

+ 42 - 0
src/asEditorComponents/componentscom/auxiliarysegmentation/index.vue

@@ -0,0 +1,42 @@
+<template>
+  <div class="auxiliarysegmentation">
+    <section
+      class="contan"
+      :style="{
+        height: datas.blankHeight + 'px',
+        padding: datas.paddType === 0 ? '0px' : '0px 15px',
+      }"
+    >
+      <div
+        v-show="datas.segmentationtype === 1"
+        style="height: 1px; width: 100%; border-top-width: 1px"
+        :style="{
+          'border-top-style': datas.bordertp,
+          'border-top-color': datas.auxliarColor,
+        }"
+      />
+    </section>
+
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'auxiliarysegmentation',
+  props: {
+    datas: Object,
+  },
+}
+</script>
+
+<style scoped lang="less">
+.auxiliarysegmentation {
+  position: relative;
+  .contan {
+    display: flex;
+    align-items: center;
+  }
+}
+</style>

+ 99 - 0
src/asEditorComponents/componentscom/captiontext/index.vue

@@ -0,0 +1,99 @@
+<template>
+  <div class="captiontext" :style="{ background: datas.backColor }">
+    <div
+      style="padding: 6px 0"
+      :style="{
+        'border-bottom': datas.borderBott
+          ? '1px solid #F9F9F9'
+          : '1px solid #fff',
+      }"
+    >
+      <!-- 标题 -->
+      <h2
+        :style="{
+          'font-size': datas.wordSize + 'px',
+          'font-weight': datas.wordWeight,
+          color: datas.wordColor,
+          'text-align': datas.positions,
+          height: datas.wordHeight + 'px',
+          'line-height': datas.wordHeight + 'px',
+          'padding-right': !(datas.positions !== 'center' && datas.more.show)
+            ? '0'
+            : '60px',
+        }"
+        v-if="datas.name"
+      >
+        {{ datas.name }}
+      </h2>
+
+      <!-- 描述文字 -->
+      <p
+        :style="{
+          'font-size': datas.descriptionSize + 'px',
+          'font-weight': datas.descriptionWeight,
+          color: datas.descriptionColor,
+          'text-align': datas.positions,
+        }"
+        style="margin-top: 8px"
+        v-if="datas.description"
+      >
+        {{ datas.description }}
+      </p>
+
+      <!-- 更多 -->
+      <p
+        class="more"
+        v-show="datas.more.show"
+        :class="datas.positions !== 'center' ? 'lef' : ''"
+        :style="{
+          color: datas.more.type === 0 ? '#38f' : '',
+          top: (datas.wordHeight - 6) / 2 + 'px',
+        }"
+      >
+        {{ datas.more.type === 2 ? '' : datas.more.text }}
+        <span> {{ datas.more.type === 0 ? '' : '>' }}</span>
+      </p>
+    </div>
+
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'captiontext',
+  props: {
+    datas: Object,
+  },
+}
+</script>
+
+<style scoped lang="less">
+.captiontext {
+  border: 2px solid #fff;
+  box-sizing: border-box;
+  width: 100%;
+  padding: 0 14px;
+  min-height: 20px;
+  position: relative;
+
+  h2,
+  p {
+    word-wrap: break-word;
+    min-height: 10px;
+  }
+
+  /* 更多 */
+  .more {
+    font-size: 10px;
+    color: #969799;
+    text-align: center;
+    &.lef {
+      position: absolute;
+      right: 15px;
+      top: 12px;
+    }
+  }
+}
+</style>

+ 72 - 0
src/asEditorComponents/componentscom/commoditysearch/index.vue

@@ -0,0 +1,72 @@
+<template>
+  <div
+    class="commoditysearch"
+    :style="{
+      background: datas.backgroundColor,
+      border: `1px solid ${datas.backgroundColor}`,
+    }"
+  >
+    <!-- 搜索框 -->
+    <section
+      class="searchs"
+      :style="{
+        height: datas.heights + 'px',
+        'justify-content': datas.textPosition === 0 ? 'left' : 'center',
+        background: datas.borderColor,
+        'border-radius': datas.borderRadius === 0 ? '0px' : '10px',
+      }"
+    >
+      <div class="search-left">
+        <van-icon name="search" size="16" :style="{ color: datas.textColor }" />
+        <span :style="{ color: datas.textColor }">搜索商品</span>
+      </div>
+      <!-- 扫一扫 -->
+      <div
+        class="sweep"
+        v-show="datas.sweep"
+        :style="{ color: datas.textColor }"
+      >
+        <span>扫一扫</span>
+      </div>
+    </section>
+
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'commoditysearch',
+  props: {
+    datas: Object,
+  },
+}
+</script>
+
+<style scoped lang="less">
+.commoditysearch {
+  position: relative;
+  /* 搜索框 */
+  .searchs {
+    position: relative;
+    width: 345px;
+    min-height: 28px;
+    margin: 5px auto;
+    display: flex;
+    align-items: center;
+    font-size: 14px;
+    .search-left {
+      display: flex;
+      align-items: center;
+    }
+    .sweep {
+      position: absolute;
+      right: 10px;
+    }
+    i {
+      margin: 0 5px;
+    }
+  }
+}
+</style>

+ 95 - 0
src/asEditorComponents/componentscom/communitypowder/index.vue

@@ -0,0 +1,95 @@
+<template>
+  <div class="communitypowder">
+    <!-- 社区粉丝 -->
+    <section class="powder" :style="{ background: datas.backColor }">
+      <!-- 内容 -->
+      <div class="container">
+        <div class="lef">
+          <img
+            draggable="false"
+            src="../../../assets/images/powder.png"
+            alt=""
+            v-if="!datas.mainImg"
+          />
+          <img draggable="false" :src="datas.mainImg" alt="" v-else />
+          <div class="text">
+            <p class="first">{{ datas.title }}</p>
+            <p class="last">{{ datas.describe }}</p>
+          </div>
+        </div>
+        <van-button class="rig" type="danger" size="small" color="#f44">{{
+          datas.buttonName
+        }}</van-button>
+      </div>
+    </section>
+
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'communitypowder',
+  props: {
+    datas: Object,
+  },
+}
+</script>
+
+<style scoped lang="less">
+.communitypowder {
+  position: relative;
+  /* 社区涨粉 */
+  .powder {
+    width: 100%;
+    height: 90px;
+    display: flex;
+    align-items: center;
+    .container {
+      height: 60px;
+      width: 100%;
+      box-sizing: border-box;
+      padding: 0 15px;
+      align-items: center;
+      display: flex;
+      justify-content: space-between;
+      /* 左半部分 */
+      .lef {
+        display: flex;
+        img {
+          width: 60px;
+          height: 60px;
+          border-radius: 50%;
+        }
+        .text {
+          display: flex;
+          flex-direction: column;
+          justify-content: space-between;
+          margin-left: 10px;
+          width: 146px;
+          padding: 8px 0;
+          .first {
+            width: 100%;
+            color: #333;
+            font-weight: 700;
+            font-size: 14px;
+            line-height: 20px;
+            overflow: hidden;
+            white-space: nowrap;
+            text-overflow: ellipsis;
+          }
+          .last {
+            width: 100%;
+            color: #a9a9a9;
+            overflow: hidden;
+            white-space: nowrap;
+            text-overflow: ellipsis;
+            font-size: 12px;
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 23 - 0
src/asEditorComponents/componentscom/crowdoperation/index.vue

@@ -0,0 +1,23 @@
+<template>
+  <div class="crowdoperation">
+    {{ datas.text }}
+
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'crowdoperation',
+  props: {
+    datas: Object,
+  },
+}
+</script>
+
+<style scoped lang="less">
+.crowdoperation {
+  position: relative;
+}
+</style>

+ 26 - 0
src/asEditorComponents/componentscom/custommodule/index.vue

@@ -0,0 +1,26 @@
+<template>
+  <div class="custommodule">
+    {{ datas.demo }}
+    <img :src="datas.img" alt="">
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'custommodule',
+  props: {
+    datas: Object,
+  },
+}
+</script>
+
+<style scoped lang="less">
+.custommodule {
+  position: relative;
+  img{
+    width: 100%;
+  }
+}
+</style>

+ 31 - 0
src/asEditorComponents/componentscom/entertheshop/index.vue

@@ -0,0 +1,31 @@
+<template>
+  <div class="entertheshop">
+    <!-- 内容 -->
+    <van-cell
+      :icon="datas.icon"
+      :title="datas.shopName"
+      is-link
+      :value="datas.copywriting"
+      :to="datas.type==10?datas.http.externalLink:''"
+      :url="datas.type==11?datas.http.externalLink:''"
+    />
+
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'entertheshop',
+  props: {
+    datas: Object,
+  },
+}
+</script>
+
+<style scoped lang="less">
+.entertheshop {
+  position: relative;
+}
+</style>

+ 62 - 0
src/asEditorComponents/componentscom/follow/index.vue

@@ -0,0 +1,62 @@
+<template>
+  <div id="follow">
+    <div class="follow-box">
+      <div class="follow-pic">
+        <img :src="datas.heade" alt="" />
+      </div>
+      <div class="follow-info">
+        <span>{{ datas.followName }}</span>
+      </div>
+      <div class="follow-right">
+        <van-button color="#07C160">关注公众号</van-button>
+      </div>
+    </div>
+
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'follow',
+  props: {
+    datas: Object,
+  },
+}
+</script>
+
+<style lang="less" scoped>
+#follow {
+  position: relative;
+  width: 100%;
+  padding: 5px 10px;
+  box-sizing: border-box;
+  .follow-box {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    border: 1px solid #999;
+    border-radius: 5px;
+    padding: 10px;
+    box-sizing: border-box;
+    .follow-pic {
+      width: 50px;
+      height: 50px;
+      img {
+        display: block;
+        width: 100%;
+        height: 100%;
+        border-radius: 50%;
+      }
+    }
+    .follow-info {
+      flex: 1;
+      margin-left: 20px;
+      font-size: 14px;
+      color: #333;
+    }
+  }
+}
+</style>

+ 142 - 0
src/asEditorComponents/componentscom/graphicnavigation/index.vue

@@ -0,0 +1,142 @@
+<template>
+  <div
+    class="graphicnavigation"
+    :style="{ backgroundImage: 'url(' + datas.bgImg + ')' }"
+  >
+    <!-- 默认导航 -->
+    <section
+      class="defaultNavigation"
+      v-if="!datas.imageList[0]"
+      :style="{
+        background: datas.backgroundColor,
+        display: datas.imgStyle === 0 ? 'flex' : '-webkit-box',
+        'overflow-x': datas.imgStyle === 0 ? '' : 'scroll',
+      }"
+    >
+      <!-- 导航 -->
+      <div
+        class="navigationList"
+        v-for="index in 5"
+        :key="index"
+        :style="{
+          width:
+            datas.imgStyle === 0 ? 'auto' : 375 / datas.showSize - 1 + 'px',
+        }"
+      >
+        <!-- 图片 -->
+        <img
+          src="../../../assets/images/imgs.png"
+          alt="默认图片"
+          v-show="datas.navigationType === 0"
+          draggable="false"
+          :style="{ 'border-radius': datas.borderRadius + '%' }"
+        />
+        <!-- 文字 -->
+        <p :style="{ color: datas.textColor }">导航</p>
+      </div>
+    </section>
+
+    <!-- 导航列表 -->
+    <section
+      class="defaultNavigation"
+      v-else
+      :style="{
+        background: datas.backgroundColor,
+        display: datas.imgStyle === 0 ? 'flex' : '-webkit-box',
+        'flex-wrap': datas.imgStyle === 0 ? 'wrap' : 'nowrap',
+        'justify-content':
+          datas.imgStyle === 0 ? 'space-evenly' : 'space-around',
+        'overflow-x': datas.imgStyle === 0 ? '' : 'scroll',
+      }"
+    >
+      <!-- 导航 -->
+      <div
+        class="navigationList"
+        v-for="(item, index) in datas.imageList"
+        :key="index"
+        :style="{
+          width: datas.imgStyle === 0 ? '20%' : 375 / datas.showSize - 1 + 'px',
+        }"
+      >
+        <!-- 图片 -->
+        <img
+          :src="item.src"
+          alt="默认图片"
+          v-show="datas.navigationType === 0"
+          draggable="false"
+          :style="{ 'border-radius': datas.borderRadius + '%' }"
+        />
+        <!-- 文字 -->
+        <p
+          :style="{
+            color: datas.textColor,
+            'font-size': datas.textSize + 'px',
+            height: datas.textHeight + 'px',
+            'line-height': datas.textHeight + 'px',
+          }"
+        >
+          {{ item.text }}
+        </p>
+      </div>
+    </section>
+
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'graphicnavigation',
+  props: {
+    datas: Object,
+  },
+  created(){
+    console.log(this.datas,'--------graphicnavigation')
+  }
+}
+</script>
+
+<style scoped lang="less">
+.graphicnavigation {
+  position: relative;
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  /* 默认导航 */
+  .defaultNavigation {
+    // overflow-x: scroll;
+    justify-content: space-evenly;
+    &::-webkit-scrollbar {
+      height: 1px;
+    }
+    &::-webkit-scrollbar-thumb {
+      background-color: #155bd4;
+    }
+    /deep/.el-collapse-item__header,
+    /deep/.el-collapse-item__wrap {
+      border-bottom: 0 !important;
+    }
+    /* 导航 */
+    .navigationList {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      img {
+        margin-top: 5px;
+        width: 45px;
+        height: 45px;
+      }
+      p {
+        font-size: 12px;
+        margin-top: 5px;
+        width: 100%;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        text-align: center;
+        box-sizing: border-box;
+      }
+    }
+  }
+}
+</style>

+ 272 - 0
src/asEditorComponents/componentscom/investigate/index.vue

@@ -0,0 +1,272 @@
+<template>
+  <div class="investigate" @click="guanbi">
+    <!-- 内容 -->
+    <div class="title">{{ datas.title }}</div>
+    <div
+      class="rescon"
+      v-for="(item1, index1) in datas.jsonData"
+      :key="index1"
+      @mouseleave="leave()"
+    >
+      <!-- 输入框 -->
+      <div v-if="item1.type == 0">
+        <van-cell-group>
+          <van-field
+            :label="item1.name"
+            :placeholder="item1.value"
+            :value="item1.value2"
+            readonly="readonly"
+          />
+        </van-cell-group>
+      </div>
+
+      <!-- 下拉框 -->
+      <div v-if="item1.type == 1" class="xiala">
+        <div class="titlename">{{ item1.name }}</div>
+        <div class="select">
+          <input
+            type="text"
+            readonly="readonly"
+            :placeholder="'点击选择' + item1.name"
+            class="readinput"
+            @click="showpic(index1)"
+            :value="item1.value2"
+          />
+          <ul :class="{ ulshow: item1.showPicker, ultext: true }">
+            <li
+              v-for="(item, index) in item1.value1"
+              :key="index"
+              @click="xuanze(index1, item)"
+            >
+              {{ item }}
+            </li>
+          </ul>
+        </div>
+      </div>
+
+      <!-- 单选框 -->
+      <van-field name="radio" :label="item1.name" v-if="item1.type == 2">
+        <template #input>
+          <van-radio-group :value="item1.value2" direction="horizontal">
+            <van-radio
+              :name="item"
+              v-for="(item, index) in item1.value1"
+              :key="index"
+              >{{ item }}</van-radio
+            >
+          </van-radio-group>
+        </template>
+      </van-field>
+
+      <!-- 复选框 -->
+
+      <van-field
+        name="checkboxGroup"
+        :label="item1.name"
+        v-if="item1.type == 3"
+      >
+        <template #input>
+          <van-checkbox-group direction="horizontal">
+            <van-checkbox
+              :name="item"
+              v-for="(item, index) in item1.value1"
+              :key="index"
+              :shape="item1.name"
+              >{{ item }}</van-checkbox
+            >
+          </van-checkbox-group>
+        </template>
+      </van-field>
+    </div>
+    <div class="button">
+      <button>提交</button>
+    </div>
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'investigate',
+  data() {
+    return {
+      jsonData: [],
+    }
+  },
+  props: {
+    datas: Object,
+  },
+  created() {},
+  mounted() {},
+  methods: {
+    //点击显示下拉框
+    showpic(index1) {
+      event.stopPropagation()
+      this.datas.jsonData.forEach((el) => {
+        el.showPicker = false
+      })
+      this.datas.jsonData[index1].showPicker = !this.datas.jsonData[index1]
+        .showPicker
+    },
+
+    // //下拉选择
+    xuanze(index1) {
+      this.datas.jsonData[index1].showPicker = false
+    },
+
+    //关闭下拉选项
+    guanbi() {
+      this.datas.jsonData.forEach((el) => {
+        el.showPicker = false
+      })
+    },
+    leave() {
+      this.datas.jsonData.forEach((el) => {
+        el.showPicker = false
+      })
+    },
+    //
+  },
+  watch: {},
+}
+</script>
+
+<style scoped lang="less">
+.investigate {
+  position: relative;
+  padding: 0 6px;
+}
+form select {
+  appearance: none;
+  -moz-appearance: none;
+  -webkit-appearance: none;
+}
+.xiala {
+  position: relative;
+  display: -webkit-box;
+  display: -webkit-flex;
+  display: flex;
+  box-sizing: border-box;
+  width: 100%;
+  padding: 10px 16px;
+  // overflow: hidden;
+  color: #323233;
+  font-size: 14px;
+  line-height: 24px;
+  background-color: #fff;
+  .titlename {
+    width: 5.6em;
+    margin-right: 12px;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+  }
+}
+select {
+  border: none;
+  outline: none;
+}
+.title {
+  text-align: center;
+  padding: 10px;
+  font-size: 18px;
+  font-weight: bold;
+}
+/deep/.van-cell {
+  display: block;
+}
+/deep/.el-form-item__label {
+  text-align: center;
+  width: 100% !important;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+/deep/.el-form-item__content {
+  margin-left: 100% !important;
+}
+/* 上传图片按钮 */
+.uploadImg {
+  width: 200px;
+  height: 40px;
+  margin-top: 20px;
+}
+/deep/.van-radio,
+.van-checkbox {
+  padding: 4px 0px;
+}
+/deep/.van-field__label {
+  width: 100%;
+  // overflow: hidden;
+  // white-space: nowrap;
+  // text-overflow: ellipsis;
+  padding-left: 10px;
+  border-bottom: 1px solid #dddddd;
+  padding-bottom: 10px;
+  line-height: 20px;
+  font-size: 13px;
+}
+/deep/.van-field__value {
+  padding-left: 10px;
+  font-size: 13px;
+  padding-top: 5px;
+}
+.button {
+  padding: 12px 24px;
+  button {
+    width: 100%;
+    background: rgb(48, 116, 243);
+    color: #fff;
+    padding: 8px;
+    border-radius: 20px;
+    text-align: center;
+    font-size: 14px;
+    border: none;
+  }
+}
+.select {
+  position: relative;
+  width: 100%;
+  .readinput {
+    display: block;
+    box-sizing: border-box;
+    width: 100%;
+    min-width: 0;
+    margin: 0;
+    padding: 0;
+    color: #323233;
+    line-height: inherit;
+    text-align: left;
+    background-color: transparent;
+    border: 0;
+    resize: none;
+    cursor: default;
+  }
+}
+.ultext {
+  display: none;
+  height: 0;
+  overflow: hidden;
+  transition: all linear 1s;
+  background: #fff;
+  z-index: 100;
+  border-radius: 6px;
+  box-shadow: 0 0 16px 1px rgba(200, 200, 200, 0.5);
+  li {
+    padding: 4px 16px;
+    border-bottom: 1px solid #eeeeee;
+    &:hover {
+      background: #c3d4f5;
+    }
+  }
+}
+.ulshow {
+  display: block;
+  height: auto;
+  max-height: 200px;
+  overflow-y: auto;
+  margin-top: 6px;
+  position: absolute;
+}
+</style>

File diff suppressed because it is too large
+ 1458 - 0
src/asEditorComponents/componentscom/listswitching/index.vue


+ 445 - 0
src/asEditorComponents/componentscom/magiccube/index.vue

@@ -0,0 +1,445 @@
+<template>
+  <div
+    class="magiccube"
+    :style="{
+      'padding-left': datas.pageMargin + 'px',
+      'padding-right': datas.pageMargin + 'px',
+    }"
+  >
+    <img
+      draggable="false"
+      v-show="!showimageList"
+      src="../../../assets/images/mor.png"
+      alt=""
+      style="width: 100%"
+    />
+
+    <!-- 一行二个 -->
+    <section
+      class="buju buju0"
+      v-show="datas.rubiksCubeType === 0 && showimageList"
+    >
+      <div
+        v-for="index in 2"
+        :key="index"
+        class="rubiksCubeType0 rubiksCubeType"
+      >
+        <img
+          draggable="false"
+          :src="datas.imageList[index - 1].src"
+          alt=""
+          :style="{ padding: datas.imgMargin / 2 + 'px' }"
+        />
+      </div>
+    </section>
+
+    <!-- 一行三个 -->
+    <section
+      class="buju buju0"
+      v-show="datas.rubiksCubeType === 1 && showimageList"
+    >
+      <div
+        v-for="index in 3"
+        :key="index"
+        class="rubiksCubeType1 rubiksCubeType"
+        :style="{
+          margin: datas.imgMargin / 10 + '%',
+          width: 33.33 + '%',
+        }"
+      >
+      <!--    width: 33 - datas.imgMargin / 10 + '%', -->
+        <img draggable="false" :src="datas.imageList[index - 1].src" alt="" />
+      </div>
+    </section>
+
+    <!-- 一行四个 -->
+    <section
+      class="buju buju0"
+      v-show="datas.rubiksCubeType === 2 && showimageList"
+    >
+      <div
+        v-for="index in 4"
+        :key="index"
+        class="rubiksCubeType2 rubiksCubeType"
+        :style="{
+          margin: datas.imgMargin / 10 + '%',
+          width: 25 - datas.imgMargin / 10 + '%',
+        }"
+      >
+        <img draggable="false" :src="datas.imageList[index - 1].src" alt="" />
+      </div>
+    </section>
+
+    <!-- 二左二右 -->
+    <section
+      class="buju buju0"
+      v-show="datas.rubiksCubeType === 3 && showimageList"
+    >
+      <div
+        v-for="index in 4"
+        :key="index"
+        class="rubiksCubeType3 rubiksCubeType"
+      >
+        <img
+          draggable="false"
+          :src="datas.imageList[index - 1].src"
+          alt=""
+          :style="{ padding: datas.imgMargin + 'px' }"
+        />
+      </div>
+    </section>
+
+    <!-- 一左二右 -->
+    <section
+      class="buju buju4"
+      v-show="datas.rubiksCubeType === 4 && showimageList"
+    >
+      <div class="rubiksCubeType hw" style="padding-top: 100%">
+        <img
+          draggable="false"
+          :src="datas.imageList[0].src"
+          alt=""
+          style="height:300px"
+          :style="{ 'padding-right': datas.imgMargin + 'px' }"
+        />
+      </div>
+      <div style="display: inline-flex; flex-direction: column; width: 100%">
+        <div
+          class=" hw imgone"
+          v-for="index in 2"
+          :key="index"
+          style="padding-top: 150px;height:150px"
+        >
+          <img
+            draggable="false"
+            :src="datas.imageList[index].src"
+            alt=""
+            style="height:150px"
+            :style="{ padding: datas.imgMargin + 'px'}"
+          />
+        </div>
+      </div>
+    </section>
+
+    <!-- 一上二下 -->
+    <section
+      class="buju buju5"
+      v-show="datas.rubiksCubeType === 5 && showimageList"
+    >
+      <div class="rubiksCubeType hw" style="display: block; padding-top: 50%">
+        <img
+          draggable="false"
+          :src="datas.imageList[0].src"
+          alt=""
+          :style="{ 'padding-bottom': datas.imgMargin + 'px' }"
+        />
+      </div>
+      <div style="display: flex; width: 100%">
+        <div
+          class="rubiksCubeType hw imgtow"
+          v-for="index in 2"
+          :key="index"
+          style="padding-top: 50%"
+        >
+          <img
+            draggable="false"
+            :src="datas.imageList[index].src"
+            alt=""
+            :style="{ padding: datas.imgMargin + 'px' }"
+          />
+        </div>
+      </div>
+    </section>
+
+    <!-- 一左三右 -->
+    <section
+      class="buju buju4"
+      v-show="datas.rubiksCubeType === 6 && showimageList"
+    >
+      <!-- 第一张图片 -->
+      <div class="rubiksCubeType hw" style="padding-top: 100%">
+        <img
+          draggable="false"
+          :src="datas.imageList[0].src"
+          alt=""
+          style="height:300px"
+          :style="{ 'padding-right': datas.imgMargin + 'px' }"
+        />
+      </div>
+      <div style="display: inline-flex; flex-direction: column; width: 100%">
+        <!-- 第二张图片 -->
+        <div class="rubiksCubeType hw" style="padding-top: 150px">
+          <img
+            draggable="false"
+            :src="datas.imageList[1].src"
+            alt=""
+            :style="{
+              'padding-bottom': datas.imgMargin + 'px',
+              'padding-left': datas.imgMargin + 'px',
+            }"
+          />
+        </div>
+        <div class="rubiksCubeType">
+          <div
+            class="hw"
+            style="
+              display: inline-flex;
+              justify-content: center;
+              align-items: center;
+              padding-top: 150px;
+            "
+            v-for="index in 2"
+            :key="index"
+          >
+            <img
+              draggable="false"
+              :src="datas.imageList[index + 1].src"
+              alt=""
+              style="height:150px"
+              :style="{
+                'padding-left': datas.imgMargin + 'px',
+                'padding-top': datas.imgMargin + 'px',
+              }"
+            />
+          </div>
+        </div>
+      </div>
+    </section>
+
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'magiccube',
+  props: {
+    datas: Object,
+  },
+  computed: {
+    showimageList() {
+      if (
+        this.datas.rubiksCubeType === 0 &&
+        !this.datas.imageList[0].src &&
+        !this.datas.imageList[1].src
+      )
+        return false
+
+      if (
+        (this.datas.rubiksCubeType === 1 ||
+          this.datas.rubiksCubeType === 4 ||
+          this.datas.rubiksCubeType === 5) &&
+        !this.datas.imageList[0].src &&
+        !this.datas.imageList[1].src &&
+        !this.datas.imageList[2].src
+      )
+        return false
+
+      if (
+        (this.datas.rubiksCubeType === 2 ||
+          this.datas.rubiksCubeType === 6 ||
+          this.datas.rubiksCubeType === 3) &&
+        !this.datas.imageList[0].src &&
+        !this.datas.imageList[1].src &&
+        !this.datas.imageList[2].src &&
+        !this.datas.imageList[3].src
+      )
+        return false
+
+      return true
+    },
+  },
+}
+</script>
+
+<style scoped lang="less">
+.magiccube {
+  position: relative;
+  /* 布局 */
+  .imgone {
+    &:last-of-type {
+      img {
+        padding-bottom: 0 !important;
+        padding-right: 0 !important;
+      }
+    }
+    &:first-of-type {
+      img {
+        padding-top: 0 !important;
+        padding-right: 0 !important;
+      }
+    }
+  }
+  .imgtow {
+    &:first-of-type {
+      img {
+        padding-bottom: 0 !important;
+        padding-left: 0 !important;
+      }
+    }
+    &:last-of-type {
+      img {
+        padding-bottom: 0 !important;
+        padding-right: 0 !important;
+      }
+    }
+  }
+  .hw {
+    width: 100%;
+    position: relative;
+    img {
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+    }
+  }
+  .buju {
+    &.buju0 {
+      display: flex;
+      justify-content: space-around;
+      flex-wrap: wrap;
+    }
+    &.buju4 {
+      display: flex;
+      width: 100%;
+      height: 300px;
+      flex-direction: row;
+      justify-content: space-around;
+    }
+    .active {
+      background: #e0edff;
+      border: 1px solid #155bd4;
+      color: #155bd4;
+      z-index: 2;
+    }
+    .rubiksCubeType {
+      display: inline-flex;
+      justify-content: center;
+      align-items: center;
+      cursor: pointer;
+      &.rubiksCubeType0 {
+        width: 50%;
+        // height: 200px;
+        &:first-of-type {
+          img {
+            padding-left: 0 !important;
+            padding-top: 0 !important;
+            padding-bottom: 0 !important;
+          }
+        }
+        &:last-of-type {
+          img {
+            padding-right: 0 !important;
+            padding-top: 0 !important;
+            padding-bottom: 0 !important;
+          }
+        }
+        img {
+          width: 100%;
+          // height: 200px;
+          display: block;
+        }
+      }
+      &.rubiksCubeType1 {
+        width: 33.333%;
+        &:nth-of-type(1) {
+          margin-left: 0 !important;
+          margin-top: 0 !important;
+          margin-bottom: 0 !important;
+        }
+        &:nth-of-type(2) {
+          margin-top: 0 !important;
+          margin-left: 0 !important;
+          margin-bottom: 0 !important;
+        }
+        &:nth-of-type(3) {
+          margin-top: 0 !important;
+          margin-right: 0 !important;
+          margin-bottom: 0 !important;
+        }
+        img {
+          width: 100%;
+          height: 150px;
+          display: block;
+        }
+      }
+      &.rubiksCubeType2 {
+        width: 25%;
+        &:nth-of-type(1) {
+          margin-left: 0 !important;
+          margin-top: 0 !important;
+          margin-bottom: 0 !important;
+        }
+        &:nth-of-type(2) {
+          margin-top: 0 !important;
+          margin-left: 0 !important;
+          margin-bottom: 0 !important;
+        }
+        &:nth-of-type(3) {
+          margin-top: 0 !important;
+          margin-left: 0 !important;
+          margin-bottom: 0 !important;
+        }
+        &:nth-of-type(4) {
+          margin-top: 0 !important;
+          margin-right: 0 !important;
+          margin-bottom: 0 !important;
+        }
+        img {
+          width: 100%;
+          height: 150px;
+          display: block;
+        }
+      }
+      &.rubiksCubeType3 {
+        width: 50%;
+        padding-top: 50%;
+        position: relative;
+        &:nth-of-type(1) {
+          img {
+            padding-top: 0 !important;
+            padding-left: 0 !important;
+          }
+        }
+        &:nth-of-type(2) {
+          img {
+            padding-top: 0 !important;
+            padding-right: 0 !important;
+          }
+        }
+        &:nth-of-type(3) {
+          img {
+            padding-bottom: 0 !important;
+            padding-left: 0 !important;
+          }
+        }
+        &:nth-of-type(4) {
+          img {
+            padding-bottom: 0 !important;
+            padding-right: 0 !important;
+          }
+        }
+        img {
+          position: absolute;
+          top: 0;
+          left: 0;
+          width: 100%;
+          height: 100%;
+        }
+      }
+      &.rubiksCubeType4 {
+        width: 187px;
+        height: 187px;
+        img {
+          width: 100%;
+          height: 100%;
+          display: block;
+        }
+      }
+    }
+  }
+}
+</style>

+ 29 - 0
src/asEditorComponents/componentscom/notice/index.vue

@@ -0,0 +1,29 @@
+<template>
+  <div class="notice">
+    <!-- 公告 -->
+    <van-notice-bar
+      :text="datas.noticeText"
+      left-icon="volume-o"
+      :background="datas.backColor"
+      :color="datas.textColor"
+    />
+
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'notice',
+  props: {
+    datas: Object,
+  },
+}
+</script>
+
+<style scoped lang="less">
+.notice {
+  position: relative;
+}
+</style>

+ 23 - 0
src/asEditorComponents/componentscom/onlineservice/index.vue

@@ -0,0 +1,23 @@
+<template>
+  <div class="onlineservice">
+    {{ datas.text }}
+
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'onlineservice',
+  props: {
+    datas: Object,
+  },
+}
+</script>
+
+<style scoped lang="less">
+.onlineservice {
+  position: relative;
+}
+</style>

+ 23 - 0
src/asEditorComponents/componentscom/personalizedrecommendation/index.vue

@@ -0,0 +1,23 @@
+<template>
+  <div class="personalizedrecommendation">
+    {{ datas.text }}
+
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'personalizedrecommendation',
+  props: {
+    datas: Object,
+  },
+}
+</script>
+
+<style scoped lang="less">
+.personalizedrecommendation {
+  position: relative;
+}
+</style>

+ 320 - 0
src/asEditorComponents/componentscom/pictureads/index.vue

@@ -0,0 +1,320 @@
+<template>
+  <div class="pictureads">
+    <!-- 无图片 -->
+    <div class="upload" v-if="!imageList[0]">
+      <i class="iconfont icon-lunbotu"></i>
+    </div>
+
+    <!-- 一行一个 -->
+    <div
+      v-if="imageList[0] && swiperType === 0"
+      class="type0"
+      :style="{
+        'padding-left': datas.pageMargin + 'px',
+        'padding-right': datas.pageMargin + 'px',
+      }"
+    >
+      <div
+        v-for="(item, index) in imageList"
+        :key="index"
+        class="imgLis"
+        :style="{ 'margin-bottom': datas.imageMargin + 'px' }"
+      >
+        <!-- 图片 -->
+        <img
+          :src="item.src"
+          draggable="false"
+          :style="{ 'border-radius': datas.borderRadius + 'px' }"
+        />
+        <!-- 图片标题 -->
+        <p class="title" v-show="item.text ? true : false">{{ item.text }}</p>
+      </div>
+    </div>
+
+    <!-- 轮播组件 -->
+    <div
+      class="swiper-container"
+      v-if="
+        (imageList[0] && swiperType === 1) ||
+        swiperType === 2 ||
+        swiperType === 3
+      "
+    >
+      <div
+        :class="
+          swiperType === 3 && imageList[0]
+            ? 'type3 type1 swiper-wrapper type3H'
+            : 'swiper-wrapper type1'
+        "
+      >
+        <div
+          class="swiper-slide"
+          v-for="(item, index) in imageList"
+          :key="index"
+        >
+          <!-- 图片 -->
+          <img
+            :src="item.src"
+            alt=""
+            draggable="false"
+            :style="{ 'border-radius': datas.borderRadius + 'px' }"
+          />
+          <!-- 图片标题 -->
+          <p class="title" v-show="item.text ? true : false">{{ item.text }}</p>
+        </div>
+      </div>
+
+      <!-- 分页器 -->
+      <div class="swiper-pagination" style="color: #007aff"></div>
+    </div>
+
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+import Swiper from 'swiper'
+import 'swiper/css/swiper.min.css'
+
+export default {
+  name: 'pictureads',
+  props: {
+    datas: Object,
+  },
+  data() {
+    return {
+      mySwiper: null,
+    }
+  },
+  computed: {
+    /* 类型切换 */
+    swiperType() {
+      console.log(this.datas.swiperType, '----------------轮播类型')
+      this.addSwiper()
+      return this.datas.swiperType
+    },
+    /* 图片删除或者增加 */
+    imageList() {
+      this.addSwiper()
+      console.log(this.datas.imageList.length, '-------轮播数量')
+      return this.datas.imageList
+    },
+    /* 分页器类型切换 */
+    pagingType() {
+      this.addSwiper()
+      return this.datas.pagingType
+    },
+    /* 一行个数 */
+    rowindividual() {
+      this.addSwiper()
+      if (this.datas.swiperType === 1) {
+        return 1
+      } else {
+        return this.datas.rowindividual
+      }
+    },
+    /* 图片间距 */
+    imageMargin() {
+      this.addSwiper()
+      if (this.datas.swiperType === 1) {
+        return 0
+      } else {
+        return this.datas.imageMargin
+      }
+    },
+  },
+  watch: {
+    pagingType() {},
+    rowindividual() {},
+    imageMargin() {},
+  },
+  methods: {
+    /* 创建轮播对象 */
+    addSwiper() {
+      this.$nextTick(() => {
+        if (this.datas.swiperType !== 0 && this.datas.imageList[0]) {
+          if (this.mySwiper instanceof Array) {
+            this.mySwiper.forEach((element) => {
+              element.destroy()
+            })
+          } else if (this.mySwiper instanceof Object) {
+            // 每次重新创建swiper前都要销毁之前存在的轮播   不然轮播会重复
+            this.mySwiper.destroy()
+          }
+
+          let params = {
+            loop: true,
+            autoplay: true,
+            pagination: {
+              el: '.swiper-pagination',
+              type: this.pagingType,
+            },
+          }
+
+          if (this.datas.swiperType === 1 || this.datas.swiperType === 2) {
+            params.slidesPerView = this.rowindividual
+            params.spaceBetween = this.imageMargin
+          } else if (this.datas.swiperType === 3) {
+            params.slidesPerView = 1.3
+            params.centeredSlides = true
+          }
+
+          this.mySwiper = new Swiper('.swiper-container', params)
+        } else {
+          if (this.mySwiper instanceof Array) {
+            this.mySwiper.forEach((element) => {
+              element.destroy()
+            })
+          }
+          // 每次重新创建swiper前都要销毁之前存在的轮播   不然轮播会重复
+          if (this.mySwiper instanceof Object) {
+            this.mySwiper.destroy()
+          }
+        }
+      })
+    },
+  },
+}
+</script>
+
+<style scoped lang="less">
+.pictureads {
+  position: relative;
+
+  /* 无图片 */
+  .upload {
+    background: #979797;
+    width: 100%;
+    height: 250px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    i {
+      font-size: 120px;
+    }
+  }
+
+  /* 类型0 */
+  .type0 {
+    box-sizing: border-box;
+    /* 图片列表 */
+    .imgLis {
+      width: 100%;
+      position: relative;
+      overflow: hidden;
+      &:last-child {
+        margin: 0 !important;
+      }
+      /* 图片 */
+      img {
+        width: 100%;
+        height: 100%;
+        display: block;
+      }
+      .title {
+        height: 36px;
+        width: 100%;
+        background-color: rgba(51, 51, 51, 0.8);
+        text-align: center;
+        line-height: 36px;
+        color: #fff;
+        position: absolute;
+        bottom: 0;
+        left: 0;
+      }
+    }
+  }
+
+  /* 类型1 */
+  .type1 {
+    width: 100%;
+    position: relative;
+    .swiper-slide {
+      width: 100%;
+      height: 250px;
+    }
+    img {
+      width: 100%;
+      height: 100%;
+      display: block;
+    }
+    .title {
+      height: 36px;
+      width: 100%;
+      background-color: rgba(51, 51, 51, 0.8);
+      text-align: center;
+      line-height: 36px;
+      color: #fff;
+      position: absolute;
+      bottom: 0;
+      left: 0;
+      text-align: left;
+      box-sizing: border-box;
+      padding: 0 5px;
+    }
+  }
+
+  .type3 {
+    width: 100%;
+    height: 250px;
+    align-items: center;
+    .swiper-slide {
+      height: 210px !important;
+      text-align: center;
+      font-size: 18px;
+      background: #fff;
+      box-shadow: rgba(173, 173, 173, 0.8) 0px 7px 24px 0px;
+      border-radius: 12px;
+      overflow: hidden;
+
+      /* Center slide text vertically */
+      display: -webkit-box;
+      display: -ms-flexbox;
+      display: -webkit-flex;
+      display: flex;
+      -webkit-box-pack: center;
+      -ms-flex-pack: center;
+      -webkit-justify-content: center;
+      justify-content: center;
+      -webkit-box-align: center;
+      -ms-flex-align: center;
+      -webkit-align-items: center;
+      align-items: center;
+      transition: 300ms;
+      transform: scale(0.8);
+      img {
+        width: 100%;
+        height: 100%;
+      }
+    }
+    .swiper-slide-active,
+    .swiper-slide-duplicate-active {
+      transform: scale(1);
+    }
+    .swiper-pagination {
+      bottom: 0 !important;
+    }
+    .title {
+      height: 36px;
+      width: 100%;
+      background-color: rgba(51, 51, 51, 0.8);
+      text-align: center;
+      line-height: 36px;
+      color: #fff;
+      position: absolute;
+      bottom: 0;
+      left: 0;
+      text-align: left;
+      box-sizing: border-box;
+      padding: 0 5px;
+    }
+  }
+  .type3H {
+    height: 250px;
+  }
+  .swiper-container-horizontal > .swiper-pagination-progressbar {
+    height: 2px;
+  }
+}
+</style>

+ 35 - 0
src/asEditorComponents/componentscom/placementarea/index.vue

@@ -0,0 +1,35 @@
+<template>
+  <div class="placementarea">
+    <span>组件放置区域</span>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'placementarea',
+}
+</script>
+
+<style scoped lang="less">
+.placementarea {
+  width: 100%;
+  height: 40px;
+  background: #94b4eb;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  background-image: url('../../../assets/images/obliqueLine.png');
+  background-size: 50%, 100%;
+  transition: all 0.5s;
+  span {
+    color: #fff;
+    display: inline-block;
+    width: 140px;
+    height: 25px;
+    font-size: 12px;
+    text-align: center;
+    line-height: 25px;
+    background: #5487df;
+  }
+}
+</style>

+ 42 - 0
src/asEditorComponents/componentscom/richtext/index.vue

@@ -0,0 +1,42 @@
+<template>
+  <div class="richtext" :style="{ background: datas.backColor }">
+    <img
+      draggable="false"
+      src="../../../assets/images/fwb.png"
+      alt=""
+      v-if="!datas.myValue.length"
+    />
+    <section v-else v-html="datas.myValue" />
+
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'richtext',
+  props: {
+    datas: Object,
+  },
+}
+</script>
+
+<style scoped lang="less">
+.richtext {
+  position: relative;
+}
+/deep/img {
+  max-width: 100% !important;
+  display: block;
+}
+.richtext {
+  position: relative;
+  /deep/pre {
+    white-space: break-spaces;
+  }
+  /deep/p {
+    word-break: break-all;
+  }
+}
+</style>

+ 428 - 0
src/asEditorComponents/componentscom/storeinformation/index.vue

@@ -0,0 +1,428 @@
+<template>
+  <div class="storeinformation">
+    <!-- 样式一 -->
+    <section
+      class="type0"
+      v-show="datas.rubiksCubeType === 0 || datas.rubiksCubeType === 2"
+    >
+      <div
+        v-if="datas.rubiksCubeType === 0"
+        class="menban"
+        style="background-color: rgba(0, 0, 0, 0.3)"
+      />
+      <div
+        v-else
+        class="menban"
+        style="background-image: linear-gradient(to top, #000, transparent)"
+      />
+
+      <!-- 蒙版 -->
+      <div class="men">
+        <img
+          draggable="false"
+          v-if="datas.bakcgroundImg"
+          :src="datas.bakcgroundImg"
+          alt=""
+        />
+        <img
+          draggable="false"
+          v-else
+          src="../../../assets/images/backimg.png"
+          alt=""
+        />
+      </div>
+
+      <!-- 店铺信息 -->
+      <div class="storIinformation">
+        <div>
+          <img
+            draggable="false"
+            v-if="datas.headPortrait"
+            :src="datas.headPortrait"
+            alt=""
+          />
+          <img
+            draggable="false"
+            v-else
+            src="../../../assets/images/headerimg.png"
+            alt=""
+          />
+        </div>
+        <div>
+          <p style="margin-top: 5px; font-weight: 700; font-size: 18px">
+            {{ datas.name }}
+          </p>
+          <p style="font-size: 12px; margin-top: 10px">{{ datas.Discount }}</p>
+        </div>
+      </div>
+    </section>
+
+    <!-- 样式二 -->
+    <section class="type1" v-show="datas.rubiksCubeType === 1">
+      <div
+        class="menban"
+        style="background-image: linear-gradient(to top, #000, transparent)"
+      />
+      <!-- 蒙版 -->
+      <div class="men">
+        <img
+          draggable="false"
+          v-if="datas.bakcgroundImg"
+          :src="datas.bakcgroundImg"
+          alt=""
+        />
+        <img
+          draggable="false"
+          v-else
+          src="../../../assets/images/backimg.png"
+          alt=""
+        />
+      </div>
+
+      <!-- 店铺信息 -->
+      <div class="storIinformation">
+        <div>
+          <img
+            draggable="false"
+            v-if="datas.headPortrait"
+            :src="datas.headPortrait"
+            alt=""
+          />
+          <img
+            draggable="false"
+            v-else
+            src="../../../assets/images/headerimg.png"
+            alt=""
+          />
+        </div>
+        <div>
+          <p style="margin-top: 5px; font-weight: 700; font-size: 18px">
+            {{ datas.name }}
+          </p>
+          <p style="font-size: 12px; margin-top: 10px">{{ datas.Discount }}</p>
+        </div>
+      </div>
+    </section>
+
+    <!-- 样式四 -->
+    <section class="type3" v-show="datas.rubiksCubeType === 3">
+      <div
+        class="menban"
+        style="background-image: linear-gradient(to top, #000, transparent)"
+      />
+      <!-- 蒙版 -->
+      <div class="men">
+        <img
+          draggable="false"
+          v-if="datas.bakcgroundImg"
+          :src="datas.bakcgroundImg"
+          alt=""
+        />
+        <img
+          draggable="false"
+          v-else
+          src="../../../assets/images/backimg.png"
+          alt=""
+        />
+      </div>
+
+      <!-- 店铺信息 -->
+      <div class="storIinformation">
+        <div>
+          <img
+            draggable="false"
+            v-if="datas.headPortrait"
+            :src="datas.headPortrait"
+            alt=""
+          />
+          <img
+            draggable="false"
+            v-else
+            src="../../../assets/images/headerimg.png"
+            alt=""
+          />
+        </div>
+        <div>
+          <p style="margin-top: 5px; font-weight: 700; font-size: 18px">
+            {{ datas.name }}
+          </p>
+          <p style="font-size: 12px; margin-top: 10px">{{ datas.Discount }}</p>
+        </div>
+      </div>
+    </section>
+
+    <!-- 样式五 -->
+    <section class="type4" v-show="datas.rubiksCubeType === 4">
+      <div
+        class="menban"
+        style="background-image: linear-gradient(to top, #000, transparent)"
+      />
+      <!-- 蒙版 -->
+      <div class="men">
+        <img
+          draggable="false"
+          v-if="datas.bakcgroundImg"
+          :src="datas.bakcgroundImg"
+          alt=""
+        />
+        <img
+          draggable="false"
+          v-else
+          src="../../../assets/images/backimg.png"
+          alt=""
+        />
+      </div>
+
+      <!-- 店铺信息 -->
+      <div class="storIinformation">
+        <div>
+          <img
+            draggable="false"
+            v-if="datas.headPortrait"
+            :src="datas.headPortrait"
+            alt=""
+          />
+          <img
+            draggable="false"
+            v-else
+            src="../../../assets/images/headerimg.png"
+            alt=""
+          />
+        </div>
+        <div>
+          <p
+            style="
+              margin-top: 5px;
+              font-weight: 700;
+              font-size: 18px;
+              line-height: 40px;
+              border-bottom: 1px solid #fff;
+            "
+          >
+            {{ datas.name }}
+          </p>
+          <p style="font-size: 12px; margin-top: 10px">{{ datas.Discount }}</p>
+        </div>
+      </div>
+    </section>
+
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'storeinformation',
+  props: {
+    datas: Object,
+  },
+}
+</script>
+
+<style scoped lang="less">
+.storeinformation {
+  position: relative;
+
+  /* 类型一 */
+  .type0 {
+    width: 100%;
+    background-repeat: round;
+    position: relative;
+    height: 185px;
+    /* 蒙版 */
+    .men {
+      width: 100%;
+      height: 100%;
+      position: absolute;
+      left: 0;
+      top: 0;
+      img {
+        display: block;
+        width: 100%;
+        height: 100%;
+      }
+    }
+
+    /* 店铺信息 */
+    .storIinformation {
+      width: 100%;
+      height: 60px;
+      position: absolute;
+      left: 0;
+      top: 110px;
+      display: flex;
+      z-index: 3;
+
+      img {
+        width: 60px;
+        height: 60px;
+        margin-left: 15px;
+        margin-right: 10px;
+        border-radius: 5px;
+      }
+
+      p {
+        overflow: hidden;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+        color: #fff;
+      }
+    }
+  }
+
+  .menban {
+    position: absolute;
+    left: 0p;
+    top: 0px;
+    width: 100%;
+    z-index: 2;
+    height: 100%;
+  }
+
+  /* 类型二 */
+  .type1 {
+    width: 100%;
+    background-repeat: round;
+    position: relative;
+    height: 238px;
+    /* 蒙版 */
+    .men {
+      width: 100%;
+      height: 185px;
+      position: absolute;
+      left: 0;
+      top: 0;
+      img {
+        display: block;
+        width: 100%;
+        height: 100%;
+      }
+    }
+
+    /* 店铺信息 */
+    .storIinformation {
+      width: 100%;
+      height: 60px;
+      position: absolute;
+      left: 0;
+      top: 150px;
+      display: flex;
+      z-index: 3;
+
+      img {
+        width: 72px;
+        height: 72px;
+        margin-left: 15px;
+        margin-right: 10px;
+        border-radius: 50%;
+      }
+
+      p {
+        overflow: hidden;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+        color: #fff;
+      }
+    }
+  }
+
+  /* 类型四 */
+  .type3 {
+    width: 100%;
+    background-repeat: round;
+    position: relative;
+    height: 238px;
+    /* 蒙版 */
+    .men {
+      width: 100%;
+      height: 140px;
+      position: absolute;
+      left: 0;
+      top: 0;
+      img {
+        display: block;
+        width: 100%;
+        height: 100%;
+      }
+    }
+
+    /* 店铺信息 */
+    .storIinformation {
+      width: 100%;
+      position: absolute;
+      left: 0;
+      top: 100px;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      z-index: 3;
+
+      img {
+        width: 72px;
+        height: 72px;
+        margin-left: 15px;
+        margin-right: 10px;
+        border-radius: 50%;
+      }
+
+      p {
+        overflow: hidden;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+        color: #fff;
+        text-align: center;
+      }
+    }
+  }
+
+  /* 类型五 */
+  .type4 {
+    width: 100%;
+    background-repeat: round;
+    position: relative;
+    height: 250px;
+    /* 蒙版 */
+    .men {
+      width: 100%;
+      height: 100%;
+      position: absolute;
+      left: 0;
+      top: 0;
+      img {
+        display: block;
+        width: 100%;
+        height: 100%;
+      }
+    }
+
+    /* 店铺信息 */
+    .storIinformation {
+      width: 100%;
+      position: absolute;
+      left: 0;
+      top: 50px;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      z-index: 3;
+
+      img {
+        width: 72px;
+        height: 72px;
+        margin-left: 15px;
+        margin-right: 10px;
+        border-radius: 50%;
+      }
+
+      p {
+        overflow: hidden;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+        color: #fff;
+        text-align: center;
+      }
+    }
+  }
+}
+</style>

+ 513 - 0
src/asEditorComponents/componentscom/storenotecard/index.vue

@@ -0,0 +1,513 @@
+<template>
+  <div class="storenotecard">
+    <!-- 更多 -->
+    <div class="more1">
+      <h4>{{ datas.name }}</h4>
+      <p v-show="datas.viewMore1">查看更多 <van-icon name="arrow" /></p>
+    </div>
+
+    <!-- 没有视频展示默认 -->
+    <section
+      v-show="!datas.imageList[0]"
+      :class="[datas.commodityType === 2 ? 'defaultcommodityList2' : '']"
+      class="defaultcommodity"
+    >
+      <div
+        v-for="index in 3"
+        :key="index"
+        class="defaultcommodityList"
+        :class="[
+          datas.commodityType === 0 ? 'defaultcommodityList0' : '',
+          datas.commodityType === 1 ? 'defaultcommodityList1' : '',
+          datas.commodityType === 2 ? 'defaultcommodityList2' : '',
+          datas.commodityType === 3 ? 'defaultcommodityList3' : '',
+          datas.commodityType === 4 ? 'defaultcommodityList4' : '',
+          datas.commodityType === 5 ? 'defaultcommodityList5' : '',
+        ]"
+        :style="{
+          'border-radius': datas.borderRadius + 'px',
+          border: datas.moditystyle === 2 ? '1px solid rgba(50,50,51,0.1)' : '',
+          'box-shadow':
+            datas.moditystyle === 1 ? '0 2px 8px rgba(93,113,127,0.08)' : '',
+          width:
+            datas.commodityType === 1
+              ? 50 - datas.commodityMargin / 6 + '%'
+              : datas.commodityType === 2
+              ? 33 - datas.commodityMargin / 5 + '%'
+              : datas.commodityType === 4
+              ? 50 - datas.commodityMargin / 5 + '%'
+              : '',
+        }"
+      >
+        <!-- 视频图片 -->
+        <div
+          class="imgss"
+          style="position: relative; width: 100%"
+          :class="[datas.positions === 'top' ? 'containoptions' : '']"
+        >
+          <img draggable="false" src="../../../assets/images/imgs.png" alt="" />
+          <!-- 标签 -->
+          <p class="marks" v-if="datas.noteLabels"><span>#</span>笔记标签</p>
+        </div>
+
+        <!-- 文字内容 -->
+        <div
+          class="text"
+          :class="[datas.positions === 'top' ? 'positionsTop' : '']"
+          :style="{ background: datas.moditystyle !== 3 ? '#fff' : 'none' }"
+        >
+          <!-- 视频名称 -->
+          <h5>这里显示商品名称,最多显示2行</h5>
+          <!-- 点赞和阅读量 -->
+          <div class="dianz">
+            <span class="fir" v-if="datas.readingNumber">999 阅读</span>
+            <span v-else></span>
+            <span v-show="datas.praisePoints"
+              ><van-icon name="good-job-o" /> 999</span
+            >
+          </div>
+        </div>
+      </div>
+    </section>
+
+    <section
+      v-show="datas.imageList[0]"
+      :class="[datas.commodityType === 2 ? 'defaultcommodityList2' : '']"
+      class="defaultcommodity"
+    >
+      <div
+        v-for="(item, index) in datas.imageList"
+        :key="index"
+        class="defaultcommodityList"
+        :class="[
+          datas.commodityType === 0 ? 'defaultcommodityList0' : '',
+          datas.commodityType === 1 ? 'defaultcommodityList1' : '',
+          datas.commodityType === 2 ? 'defaultcommodityList2' : '',
+          datas.commodityType === 3 ? 'defaultcommodityList3' : '',
+          datas.commodityType === 4 ? 'defaultcommodityList4' : '',
+          datas.commodityType === 5 ? 'defaultcommodityList5' : '',
+        ]"
+        :style="{
+          'border-radius': datas.borderRadius + 'px',
+          border: datas.moditystyle === 2 ? '1px solid rgba(50,50,51,0.1)' : '',
+          'box-shadow':
+            datas.moditystyle === 1 ? '0 2px 8px rgba(93,113,127,0.08)' : '',
+          width:
+            datas.commodityType === 1
+              ? 50 - datas.commodityMargin / 6 + '%'
+              : datas.commodityType === 2
+              ? 33 - datas.commodityMargin / 5 + '%'
+              : datas.commodityType === 4
+              ? 50 - datas.commodityMargin / 5 + '%'
+              : '',
+        }"
+      >
+        <!-- 视频图片 -->
+        <div
+          class="imgss"
+          style="position: relative; width: 100%"
+          :class="[datas.positions === 'top' ? 'containoptions' : '']"
+        >
+          <img draggable="false" :src="item.src" alt="" />
+          <!-- 标签 -->
+          <p class="marks" v-if="datas.noteLabels"><span>#</span>笔记标签</p>
+        </div>
+
+        <!-- 文字内容 -->
+        <div
+          class="text"
+          :class="[datas.positions === 'top' ? 'positionsTop' : '']"
+          :style="{ background: datas.moditystyle !== 3 ? '#fff' : 'none' }"
+        >
+          <!-- 视频名称 -->
+          <h5>{{ item.text }}</h5>
+          <!-- 点赞和阅读量 -->
+          <div class="dianz">
+            <span class="fir" v-if="datas.readingNumber">999 阅读</span>
+            <span v-else></span>
+            <span v-show="datas.praisePoints"
+              ><van-icon name="good-job-o" /> 999</span
+            >
+          </div>
+        </div>
+      </div>
+    </section>
+
+    <p class="more2" v-show="datas.viewMore2">
+      查看更多 <van-icon name="arrow" />
+    </p>
+
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'storenotecard',
+  props: {
+    datas: Object,
+  },
+  data() {
+    return {
+      active: 0,
+    }
+  },
+
+  created() {},
+
+  methods: {},
+}
+</script>
+
+<style scoped lang="less">
+.storenotecard {
+  position: relative;
+
+  /* 更多1 */
+  .more1 {
+    margin: 15px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    h4 {
+      font-size: 16px;
+      color: #323233;
+      font-weight: 400;
+      width: 270px;
+      overflow: hidden;
+      white-space: nowrap;
+      text-overflow: ellipsis;
+    }
+    p {
+      color: #969799;
+      font-size: 12px;
+      display: flex;
+      align-items: center;
+    }
+  }
+
+  /* 更多2 */
+  .more2 {
+    text-align: center;
+    color: #969799;
+    font-size: 12px;
+    margin-bottom: 15px;
+  }
+
+  /* 默认商品 */
+  .defaultcommodity {
+    box-sizing: border-box;
+    margin: 1px;
+    padding: 0 15px;
+    /* 横向滑动 */
+    &.defaultcommodityList2 {
+      overflow: scroll;
+      display: flex;
+      /* 滚动条 */
+      &::-webkit-scrollbar {
+        height: 1px;
+      }
+      &::-webkit-scrollbar-thumb {
+        background-color: #155bd4;
+      }
+      /deep/.el-collapse-item__header,
+      /deep/.el-collapse-item__wrap {
+        border-bottom: 0 !important;
+      }
+    }
+    /* 卡片列表 */
+    .defaultcommodityList {
+      position: relative;
+      margin-bottom: 15px;
+      overflow: hidden;
+      display: inline-flex;
+      flex-direction: column;
+
+      /* 大图模式 */
+      &.defaultcommodityList0 {
+        width: 100%;
+        /* 标签 */
+        .containoptions {
+          .marks {
+            bottom: 33px;
+            z-index: 3;
+          }
+        }
+        img {
+          height: 147px;
+        }
+        /* 文字在图片中 */
+        .positionsTop {
+          position: absolute;
+          display: flex;
+          flex-direction: column-reverse;
+          left: 0;
+          bottom: 0;
+          background: none !important;
+          background-image: linear-gradient(
+            to bottom,
+            transparent,
+            rgba(0, 0, 0, 0.5)
+          ) !important;
+          /* 标题 */
+          h5 {
+            color: #fff;
+            overflow: hidden;
+            white-space: nowrap;
+            text-overflow: ellipsis;
+          }
+          span {
+            color: #fff;
+          }
+          /* 点赞和阅读量 */
+          .dianz {
+            padding-left: 190px;
+          }
+        }
+      }
+
+      /* 一行两个 */
+      &.defaultcommodityList1 {
+        width: 48%;
+        &:nth-of-type(even) {
+          margin-left: 4%;
+        }
+      }
+
+      /* 横向滑动 */
+      &.defaultcommodityList2 {
+        width: 150px;
+        flex: none;
+        margin-right: 5%;
+      }
+
+      /* 一大两小 */
+      &.defaultcommodityList3 {
+        display: flex;
+        &:nth-of-type(3n-2) {
+          margin-bottom: 0 !important;
+          .marks {
+            bottom: 33px;
+            z-index: 3;
+          }
+          img {
+            height: 147px;
+          }
+          /* 文字在图片中 */
+          .text {
+            position: absolute;
+            display: flex;
+            flex-direction: column-reverse;
+            left: 0;
+            bottom: 0;
+            background: none !important;
+            background-image: linear-gradient(
+              to bottom,
+              transparent,
+              rgba(0, 0, 0, 0.5)
+            ) !important;
+            /* 标题 */
+            h5 {
+              color: #fff;
+              overflow: hidden;
+              white-space: nowrap;
+              text-overflow: ellipsis;
+            }
+            span {
+              color: #fff;
+            }
+            /* 点赞和阅读量 */
+            .dianz {
+              padding-left: 190px;
+            }
+          }
+        }
+        &:nth-of-type(3n) {
+          flex-direction: row-reverse;
+          margin-bottom: 15px;
+          .imgss {
+            width: 65px !important;
+            height: 67px;
+            z-index: 99;
+            position: absolute !important;
+            top: 10%;
+            right: 10px;
+            img {
+              width: 100%;
+              height: 100%;
+            }
+          }
+          .marks {
+            left: 0;
+            background: #fff;
+            opacity: 0.85;
+            bottom: 0;
+          }
+          .text {
+            width: 100%;
+            padding: 10px 80px 10px 10px;
+            min-height: 87px;
+            display: flex;
+            flex-direction: column;
+            justify-content: space-between;
+
+            .dianz {
+              justify-content: start;
+              line-height: 20px;
+              span {
+                &.fir {
+                  margin-right: 30px;
+                }
+              }
+            }
+          }
+        }
+        &:nth-of-type(3n-1) {
+          flex-direction: row-reverse;
+          margin-bottom: 0;
+          border-bottom: 1px solid #e5e5e5;
+          border-top: 1px solid #e5e5e5;
+          .marks {
+            left: 0;
+            bottom: 0;
+            background: #fff;
+            opacity: 0.85;
+          }
+          .imgss {
+            width: 65px !important;
+            height: 67px;
+            z-index: 99;
+            position: absolute !important;
+            top: 10%;
+            right: 10px;
+            img {
+              width: 100%;
+              height: 100%;
+            }
+          }
+          .text {
+            width: 100%;
+            padding: 10px 80px 10px 10px;
+            min-height: 87px;
+            display: flex;
+            flex-direction: column;
+            justify-content: space-between;
+            .dianz {
+              justify-content: start;
+              line-height: 20px;
+              span {
+                &.fir {
+                  margin-right: 30px;
+                }
+              }
+            }
+          }
+        }
+        &:nth-of-type(3n) {
+          flex-direction: row-reverse;
+        }
+      }
+
+      /* 详细列表 */
+      &.defaultcommodityList4 {
+        width: 100%;
+        flex-direction: row-reverse;
+        margin-bottom: 15px;
+        .imgss {
+          width: 120px !important;
+          height: 122px;
+          z-index: 99;
+          position: absolute !important;
+          top: 8%;
+          right: 10px;
+          img {
+            width: 100%;
+            height: 100%;
+          }
+        }
+        .marks {
+          left: 0;
+          background: #fff;
+          opacity: 0.85;
+          bottom: 0;
+        }
+        .text {
+          width: 100%;
+          padding: 10px 160px 10px 10px;
+          min-height: 145px;
+          display: flex;
+          flex-direction: column;
+          justify-content: space-between;
+
+          .dianz {
+            justify-content: start;
+            line-height: 20px;
+            span {
+              &.fir {
+                margin-right: 30px;
+              }
+            }
+          }
+        }
+      }
+
+      /* 标签 */
+      .marks {
+        position: absolute;
+        bottom: 10px;
+        left: 13px;
+        font-size: 10px;
+        padding: 2px 5px;
+        background: #fff;
+        opacity: 0.85;
+        border-radius: 3px;
+        span {
+          color: #d40;
+        }
+      }
+
+      /* 图片 */
+      img {
+        width: 100%;
+        display: block;
+        overflow: hidden;
+      }
+
+      /* 文字 */
+      .text {
+        padding: 10px 10px 0;
+        width: 100%;
+        box-sizing: border-box;
+        /* 商品名称 */
+        h5 {
+          font-size: 14px;
+          line-height: 20px;
+          margin: 0 0 5px;
+          font-weight: 400;
+          width: 100%;
+          display: -webkit-box;
+          text-overflow: ellipsis;
+          overflow: hidden;
+          -webkit-line-clamp: 2;
+          -webkit-box-orient: vertical;
+        }
+        /* 点赞和阅读量 */
+        .dianz {
+          display: flex;
+          justify-content: space-between;
+          line-height: 35px;
+          span {
+            font-size: 12px;
+            display: flex;
+            align-items: center;
+            .van-icon-good-job-o {
+              margin-right: 5px;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 45 - 0
src/asEditorComponents/componentscom/suspension/index.vue

@@ -0,0 +1,45 @@
+<template>
+  <div id="suspension">
+    <div class="suspension-wrap">
+      <img
+        class="suspension-logo"
+        src="https://imgs.starfirelink.com/vue-fire-start-h5/shop-peison/icon_back_36.png"
+      />
+    </div>
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+<script>
+export default {
+  name: 'suspension',
+  props: {
+    datas: Object,
+  },
+}
+</script>
+<style lang="less" scoped>
+#suspension {
+  width: 100%;
+  height: 36px;
+  position: relative;
+  position: absolute;
+  right: 0;
+  bottom: 10%;
+  z-index: 999;
+  border: none;
+  box-sizing: border-box;
+  .suspension-wrap {
+    width: 36px;
+    height: 36px;
+    position: absolute;
+    right: 30px;
+    z-index: 1001;
+    .suspension-logo {
+      width: 36px;
+      height: 36px;
+      border-radius: 50%;
+    }
+  }
+}
+</style>

+ 102 - 0
src/asEditorComponents/componentscom/tabBar/index.vue

@@ -0,0 +1,102 @@
+<template>
+  <div class="tabBar">
+    <div v-if="datas.iconList.length !== 0" class="tabbar">
+      <van-tabbar
+        v-model="active"
+        :fixed="false"
+        :placeholder="true"
+        :border="datas.isShowBorder"
+        :active-color="datas.activeColor"
+        :inactive-color="datas.inactiveColor"
+      >
+        <van-tabbar-item 
+          v-for="(item, index) in datas.iconList"
+          :key="index"
+          :name="item.iconName"
+          :dot="item.isDot"
+        >
+          <span>{{ item.iconText }}</span>
+          <template #icon="props">
+            <img :src="props.active ? item.iconPic : item.inactive" />
+          </template>
+        </van-tabbar-item>
+      </van-tabbar>
+    </div>
+
+    <div v-else>
+      <van-tabbar
+        v-model="datas.Highlight"
+        :fixed="false"
+        :placeholder="true"
+        :border="datas.isShowBorder"
+        :active-color="datas.activeColor"
+        :inactive-color="datas.inactiveColor"
+      >
+        <van-tabbar-item icon="search" name="home">标签</van-tabbar-item>
+        <van-tabbar-item icon="home-o">标签</van-tabbar-item>
+        <van-tabbar-item icon="friends-o">标签</van-tabbar-item>
+        <van-tabbar-item icon="setting-o">标签</van-tabbar-item>
+        <van-tabbar-item icon="setting-o">标签</van-tabbar-item>
+      </van-tabbar>
+    </div>
+
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'tabBar',
+  props: {
+    datas: Object
+  },
+  data() {
+    return {
+      active: 0
+    }
+  },
+
+  created() {
+    console.log(this.datas, '--------------tabbar data  created')
+    document.querySelector('.phone-container').style.cssText =
+      'padding-bottom: 50px'
+  },
+
+  mounted() {},
+
+  methods: {},
+
+  computed: {},
+
+  watch: {},
+
+  beforeDestroy() {
+    document.querySelector('.phone-container').style.cssText =
+      'padding-bottom: 0px'
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.tabBar {
+  width: 100%;
+  position: relative;
+  position: absolute;
+  bottom: -54px;
+  left: 0px;
+  z-index: 2;
+}
+
+.tabbar {
+  /deep/ .van-icon {
+    width: 25px;
+    height: 25px;
+    img {
+      display: block;
+      width: 100%;
+      height: 100%;
+    }
+  }
+}
+</style>

+ 64 - 0
src/asEditorComponents/componentscom/videoss/index.vue

@@ -0,0 +1,64 @@
+<template>
+  <div class="videoss">
+    <!-- 默认视频 -->
+    <section class="default" v-if="!datas.src">
+      <van-icon name="tv-o" size="150px" />
+    </section>
+
+    <!-- 选择视频后 -->
+    <section v-else style="position: relative">
+      <video
+        :src="datas.src"
+        controls
+        :autoplay="datas.autoplay"
+        :poster="datas.coverUrl"
+        width="100%"
+      ></video>
+    </section>
+
+    <!-- 删除组件 -->
+    <slot name="deles" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'videoss',
+  props: {
+    datas: Object,
+  },
+
+  created() {
+  },
+
+  methods: {
+  },
+}
+</script>
+
+<style scoped lang="less">
+.videoss {
+  position: relative;
+
+  /* 默认视频 */
+  .default {
+    width: 100%;
+    height: 210px;
+    background: #979797;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+  }
+
+  /* 播放图标 */
+  .bof {
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    transform: translate(-50%, -50%);
+    font-size: 100px;
+    opacity: 0.5;
+    color: #999;
+  }
+}
+</style>

+ 92 - 0
src/asEditorComponents/headerTop/index.vue

@@ -0,0 +1,92 @@
+<template>
+  <div
+    class="headerTop"
+    :style="{
+      height: pageSetup.titleHeight + 'px',
+    }"
+  >
+    <!-- 左半部分 -->
+    <div class="lef" v-show="pageSetup.isBack">
+      <van-icon name="arrow-left" />
+    </div>
+    <!-- 标题 -->
+    <div
+      class="header-title"
+      :style="{
+        height: pageSetup.titleHeight + 'px',
+        'line-height': pageSetup.titleHeight + 'px',
+      }"
+    >
+      {{ pageSetup.name }}
+    </div>
+    <!-- 右半部分 -->
+    <div class="rig" v-show="pageSetup.isPerson">
+      <span>个人中心</span>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'headerTop',
+  props: {
+    pageSetup: Object,
+  },
+}
+</script>
+
+<style lang="less" scoped>
+.headerTop {
+  height: 35px;
+  width: 100%;
+  background: #fff;
+  display: flex;
+  padding: 0 5px;
+  justify-content: space-between;
+  align-items: center;
+  cursor: pointer;
+  border-bottom: 1px solid #f7f8fa;
+  position: relative;
+  /* 左边 */
+  .lef {
+    position: absolute;
+    left: 18px;
+    top: 50%;
+    transform: translateY(-50%);
+    /* 图标 */
+    span {
+      color: #000;
+      font-weight: 400;
+      font-size: 12px;
+    }
+  }
+  .header-title {
+    width: 100%;
+    text-align: center;
+    font-size: 14px;
+    line-height: 35px;
+    color: #333333;
+  }
+  /* 右边 */
+  .rig {
+    // display: flex;
+    // align-items: center;
+    // height: 100%;
+    position: absolute;
+    right: 18px;
+    top: 50%;
+    transform: translateY(-50%);
+    /* 搜索图标 */
+    i {
+      font-size: 18px;
+      margin: 0 7px 5px;
+    }
+
+    /* 文字 */
+    span {
+      margin: 0 7px;
+      font-size: 12px;
+    }
+  }
+}
+</style>

+ 20 - 0
src/asEditorComponents/phoneBottom/index.vue

@@ -0,0 +1,20 @@
+<template>
+  <div class="phoneBottom"></div>
+</template>
+
+<script>
+export default {
+  name: 'phoneBottom',
+}
+</script>
+
+<style lang="less" scoped>
+.phoneBottom {
+  width: 100%;
+  background-color: #fff;
+  min-height: 145px;
+  cursor: pointer;
+  padding-top: 30px;
+  box-sizing: border-box;
+}
+</style>

+ 54 - 0
src/asEditorComponents/realTimeView/index.vue

@@ -0,0 +1,54 @@
+<template>
+  <div class="RealTimeView">
+    <el-dialog :visible.sync="datas.show" width="414px" top="8vh">
+      <img src="@/assets/images/phoneTop.png" style="width: 375px" />
+      <iframe
+        v-if="datas.show"
+        ref="iframe"
+        class="screen"
+        :scrolling="false"
+        :src="'http://was666.gitee.io/as-editor-h5/#/?type=iframe'"
+        @load="load"
+      ></iframe>
+      <van-loading v-if="loading" size="24px" vertical>加载中</van-loading>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'RealTimeView',
+  props: {
+    datas: {
+      show: false,
+    },
+    val:Object
+  },
+  data() {
+    return {
+      loading: true
+    }
+  },
+  methods: {
+    load() {
+      this.loading = false
+      this.$refs["iframe"].contentWindow.postMessage(this.val, "http://was666.gitee.io");
+    },
+  },
+}
+</script>
+
+<style lang="less" scoped>
+.RealTimeView {
+  .screen {
+    width: 375px /*no*/;
+    height: 667px /*no*/;
+    border: 0;
+
+    // 隐藏滚动条
+    &::-webkit-scrollbar {
+      display: none; /* Chrome Safari */
+    }
+  }
+}
+</style>

+ 229 - 0
src/asEditorComponents/rightslider/auxiliarysegmentationstyle/index.vue

@@ -0,0 +1,229 @@
+<template>
+  <div class="auxiliarysegmentationstyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+
+    <!-- 表单 -->
+    <el-form label-width="80px" :model="datas" size="small">
+      <!-- 空白高度 -->
+      <el-form-item label="空白高度" class="lef">
+        <el-slider
+          v-model="datas.blankHeight"
+          :max="100"
+          input-size="mini"
+          show-input
+        >
+        </el-slider>
+      </el-form-item>
+
+      <div style="height: 20px" />
+
+      <!-- 分割类型 -->
+      <el-form-item class="lef" label="分割类型">
+        <div class="weiz">
+          <el-tooltip
+            effect="dark"
+            :content="index - 1 === 0 ? '辅助空白' : '辅助线'"
+            placement="bottom"
+            v-for="index in 2"
+            :key="index"
+          >
+            <i
+              class="iconfont"
+              :class="[
+                index - 1 === 0
+                  ? 'icon-fuzhukongbai_weixuanzhong'
+                  : 'icon-fuzhuxiantiao',
+                datas.segmentationtype === index - 1 ? 'active' : '',
+              ]"
+              @click="datas.segmentationtype = index - 1"
+            />
+          </el-tooltip>
+        </div>
+      </el-form-item>
+
+      <div style="height: 20px" />
+
+      <!-- 选择样式 -->
+      <el-form-item
+        v-show="datas.segmentationtype === 1"
+        class="lef"
+        label="选择样式"
+      >
+        <div class="weiz">
+          <el-tooltip
+            effect="dark"
+            :content="item.text"
+            placement="bottom"
+            v-for="(item, index) in borderType"
+            :key="index"
+          >
+            <i
+              class="iconfont"
+              :class="[item.icon, datas.bordertp === item.type ? 'active' : '']"
+              @click="datas.bordertp = item.type"
+            />
+          </el-tooltip>
+        </div>
+      </el-form-item>
+
+      <div v-show="datas.segmentationtype === 1" style="height: 20px" />
+
+      <!-- 左右边距 -->
+      <el-form-item
+        v-show="datas.segmentationtype === 1"
+        class="lef"
+        label="左右边距"
+      >
+        <div class="weiz">
+          <el-tooltip
+            effect="dark"
+            :content="index - 1 === 0 ? '无边距' : '左右留边'"
+            placement="bottom"
+            v-for="index in 2"
+            :key="index"
+          >
+            <i
+              class="iconfont"
+              :class="[
+                index - 1 === 0
+                  ? 'icon-icon_wubianju'
+                  : 'icon-icon_zuoyoubianju',
+                datas.paddType === index - 1 ? 'active' : '',
+              ]"
+              @click="datas.paddType = index - 1"
+            />
+          </el-tooltip>
+        </div>
+      </el-form-item>
+
+      <div v-show="datas.segmentationtype === 1" style="height: 20px" />
+
+      <!-- 辅助线颜色 -->
+      <el-form-item
+        v-show="datas.segmentationtype === 1"
+        label="辅助线颜色"
+        class="lef aa"
+      >
+        <!-- 辅助线颜色 -->
+        <el-color-picker
+          v-model="datas.auxliarColor"
+          show-alpha
+          class="picke"
+          :predefine="predefineColors"
+        >
+        </el-color-picker>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'auxiliarysegmentationstyle',
+  props: {
+    datas: Object,
+  },
+  data() {
+    return {
+      predefineColors: [
+        // 颜色选择器预设
+        '#ff4500',
+        '#ff8c00',
+        '#ffd700',
+        '#90ee90',
+        '#00ced1',
+        '#1e90ff',
+        '#c71585',
+        '#409EFF',
+        '#909399',
+        '#C0C4CC',
+        'rgba(255, 69, 0, 0.68)',
+        'rgb(255, 120, 0)',
+        'hsv(51, 100, 98)',
+        'hsva(120, 40, 94, 0.5)',
+        'hsl(181, 100%, 37%)',
+        'hsla(209, 100%, 56%, 0.73)',
+        '#c7158577',
+      ],
+      borderType: [
+        //线类型
+        {
+          icon: 'icon-icon_fengexian_shixian',
+          text: '实线',
+          type: 'solid',
+        },
+        {
+          icon: 'icon-xuxian',
+          text: '虚线',
+          type: 'dashed',
+        },
+        {
+          icon: 'icon-dianxian--',
+          text: '点线',
+          type: 'dotted',
+        },
+      ],
+    }
+  },
+}
+</script>
+
+<style scoped lang="less">
+.auxiliarysegmentationstyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+  .lef {
+    /deep/.el-form-item__label {
+      text-align: left;
+    }
+  }
+  .aa {
+    /deep/.el-form-item__label {
+      width: 100px !important;
+    }
+  }
+
+  /* 颜色选择器 */
+  .picke {
+    float: right;
+  }
+
+  /* 图片样式 */
+  .weiz {
+    text-align: right;
+    i {
+      padding: 5px 14px;
+      margin-left: 10px;
+      border-radius: 0;
+      border: 1px solid #ebedf0;
+      font-size: 20px;
+      font-weight: 500;
+      cursor: pointer;
+
+      &:last-child {
+        font-size: 22px;
+      }
+
+      &.active {
+        color: #155bd4;
+        border: 1px solid #155bd4;
+        background: #e0edff;
+      }
+    }
+  }
+}
+</style>

+ 335 - 0
src/asEditorComponents/rightslider/captiontextsstyle/index.vue

@@ -0,0 +1,335 @@
+<template>
+  <section class="captiontextsstyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+
+    <!-- 表单 -->
+    <el-form label-width="80px" :model="datas" size="small" :rules="rules">
+      <!-- 标题内容 -->
+      <el-form-item label="标题内容">
+        <el-input
+          v-model="datas.name"
+          placeholder="请输入标题"
+          show-word-limit
+        />
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 描述内容 -->
+      <el-form-item label="描述内容">
+        <el-input
+          type="textarea"
+          v-model="datas.description"
+          placeholder="请输入要说明的文字,最多 100 字"
+          maxlength="100"
+        />
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 显示位置 -->
+      <el-form-item label="显示位置">
+        <div class="weiz">
+          <i
+            :class="datas.positions === 'left' ? 'active' : ''"
+            class="iconfont icon-horizontal-left"
+            @click="datas.positions = 'left'"
+          />
+          <i
+            :class="datas.positions === 'center' ? 'active' : ''"
+            class="iconfont icon-juzhong"
+            @click="datas.positions = 'center'"
+          />
+          <!-- <i
+          :class="datas.positions === 'right' ? 'active': ''"
+          class="iconfont icon-juyou"
+          @click="datas.positions = 'right'"
+          /> -->
+        </div>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 标题大小 -->
+      <el-form-item
+        label="标题大小"
+        prop="wordSize"
+        :hide-required-asterisk="true"
+      >
+        <el-input
+          type="number"
+          v-model.number="datas.wordSize"
+          placeholder="请输入标题文字大小"
+          :maxlength="2"
+        />
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 描述大小 -->
+      <el-form-item
+        label="描述大小"
+        prop="descriptionSize"
+        :hide-required-asterisk="true"
+      >
+        <el-input
+          type="number"
+          v-model.number="datas.descriptionSize"
+          placeholder="请输入描述文字大小"
+        />
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 标题粗细 -->
+      <el-form-item
+        label="标题粗细"
+        prop="wordWeight"
+        :hide-required-asterisk="true"
+      >
+        <el-input
+          type="number"
+          v-model.number="datas.wordWeight"
+          placeholder="请输入标题粗细"
+        />
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!--描述粗细 -->
+      <el-form-item
+        label="描述粗细"
+        prop="descriptionWeight"
+        :hide-required-asterisk="true"
+      >
+        <el-input
+          type="number"
+          v-model.number="datas.descriptionWeight"
+          placeholder="请输入描述粗细"
+        />
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 框体高度 -->
+      <el-form-item class="lef" label="框体高度">
+        <el-slider
+          v-model="datas.wordHeight"
+          :max="100"
+          :min="20"
+          input-size="mini"
+          show-input
+        >
+        </el-slider>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 标题颜色 -->
+      <el-form-item label="标题颜色">
+        <!-- 颜色选择器 -->
+        <el-color-picker
+          v-model="datas.wordColor"
+          show-alpha
+          class="picke"
+          :predefine="predefineColors"
+        >
+        </el-color-picker>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 描述颜色 -->
+      <el-form-item label="描述颜色">
+        <!-- 颜色选择器 -->
+        <el-color-picker
+          v-model="datas.descriptionColor"
+          show-alpha
+          class="picke"
+          :predefine="predefineColors"
+        >
+        </el-color-picker>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 背景颜色 -->
+      <el-form-item label="背景颜色">
+        <!-- 背景颜色 -->
+        <el-color-picker
+          v-model="datas.backColor"
+          show-alpha
+          class="picke"
+          :predefine="predefineColors"
+        >
+        </el-color-picker>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!--查看更多 -->
+      <el-form-item label="底部分割线" class="wid">
+        {{ datas.borderBott ? '显示' : '隐藏' }}
+        <el-checkbox v-model="datas.borderBott" />
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!--查看更多 -->
+      <el-form-item label="查看更多" class="wid">
+        {{ datas.more.show ? '显示' : '隐藏' }}
+        <el-checkbox v-model="datas.more.show" />
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 更多样式选择 -->
+      <div v-show="datas.more.show ? true : false">
+        <el-radio-group v-model="datas.more.type">
+          <el-radio :label="0">样式一</el-radio>
+          <el-radio :label="1">样式二</el-radio>
+          <el-radio :label="2">样式三</el-radio>
+        </el-radio-group>
+
+        <div style="height: 10px" />
+
+        <!-- 更多文字 -->
+        <el-input
+          v-show="datas.more.type === 2 ? false : true"
+          type="text"
+          style="width: 110px; margin: 15px"
+          v-model="datas.more.text"
+          size="mini"
+        />
+
+        <div style="height: 10px" />
+
+        <!-- 跳转链接 -->
+        <el-form-item label="跳转链接">
+          <el-radio-group v-model="datas.more.httpType" style="margin-left: 18px">
+            <el-radio :label="10">内部链接</el-radio>
+            <el-radio :label="11">外部链接</el-radio>
+          </el-radio-group>
+
+          <!-- 输入http -->
+          <el-input
+            v-model="datas.more.http"
+            placeholder="请输入跳转链接"
+            show-word-limit
+            style="margin-top: 10px"
+          />
+        </el-form-item>
+      </div>
+    </el-form>
+  </section>
+</template>
+
+<script>
+export default {
+  name: 'captiontextsstyle',
+  props: {
+    datas: Object,
+  },
+  data() {
+    let checkAge = (rule, value, callback) => {
+      if (value.length === 0) callback(new Error('请输入有效数字'))
+      if (value > 99) callback(new Error('数字最大为99'))
+    }
+    let kon = (rule, value, callback) => {
+      if (value.length === 0) callback(new Error('请输入有效数字'))
+    }
+    return {
+      options: [],
+      rules: {
+        wordSize: [{ required: true, validator: checkAge, trigger: 'blur' }],
+        descriptionSize: [
+          { required: true, validator: checkAge, trigger: 'blur' },
+        ],
+        wordWeight: [{ required: true, validator: kon, trigger: 'blur' }],
+        descriptionWeight: [
+          { required: true, validator: kon, trigger: 'blur' },
+        ],
+      },
+      predefineColors: [
+        // 颜色选择器预设
+        '#ff4500',
+        '#ff8c00',
+        '#ffd700',
+        '#90ee90',
+        '#00ced1',
+        '#1e90ff',
+        '#c71585',
+        '#409EFF',
+        '#909399',
+        '#C0C4CC',
+        'rgba(255, 69, 0, 0.68)',
+        'rgb(255, 120, 0)',
+        'hsv(51, 100, 98)',
+        'hsva(120, 40, 94, 0.5)',
+        'hsl(181, 100%, 37%)',
+        'hsla(209, 100%, 56%, 0.73)',
+        '#c7158577',
+      ],
+    }
+  },
+  methods: {},
+}
+</script>
+
+<style scoped lang="less">
+.captiontextsstyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+
+  /* 颜色选择器 */
+  .picke {
+    float: right;
+  }
+
+  /* 位置 */
+  .weiz {
+    text-align: right;
+    i {
+      padding: 5px 14px;
+      margin-left: 10px;
+      border-radius: 0;
+      border: 1px solid #ebedf0;
+      font-size: 20px;
+      font-weight: 500;
+      cursor: pointer;
+
+      &:last-child {
+        font-size: 22px;
+      }
+
+      &.active {
+        color: #155bd4;
+        border: 1px solid #155bd4;
+        background: #e0edff;
+      }
+    }
+  }
+
+  /deep/.wid .el-form-item__label {
+    width: 94px !important;
+  }
+  /deep/.wid .el-form-item__content {
+    float: right;
+  }
+}
+</style>

+ 326 - 0
src/asEditorComponents/rightslider/commoditysearchstyle/index.vue

@@ -0,0 +1,326 @@
+<template>
+  <div class="commoditysearchstyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+
+    <p style="color: #323233; font-size: 14px">搜索热词</p>
+    <p style="font-size: 12px; color: #969799; margin-top: 10px">
+      鼠标拖拽调整热词顺序,搜索框默认展示第一个热词,其他搜索词将以标签形式显示在搜索页中
+    </p>
+
+    <!-- 表单 -->
+    <el-form label-width="80px" :model="datas" size="small">
+      <div v-if="datas.hotords[0]">
+        <vuedraggable v-model="datas.hotords" v-bind="dragOptions">
+          <transition-group>
+            <section
+              class="imgList"
+              v-for="(item, index) in datas.hotords"
+              :key="item + index"
+            >
+              <i class="el-icon-circle-close" @click="deleteHotords(index)" />
+              <!-- 标题和链接 -->
+              <div class="imgText">
+                <el-input v-model="item.text" placeholder="请输入热词" />
+              </div>
+            </section>
+          </transition-group>
+        </vuedraggable>
+      </div>
+
+      <!-- 添加热词 -->
+      <el-button @click="addHotords" class="uploadImg" type="primary" plain
+        ><i class="el-icon-plus" />点击添加热词</el-button
+      >
+
+      <div style="height: 20px" />
+
+      <!-- 显示位置 -->
+      <el-form-item class="lef" label="显示位置">
+        <div class="weiz">
+          <span>{{
+            datas.position === 0 ? '正常模式' : '滚动至顶部固定'
+          }}</span>
+          <div>
+            <el-tooltip
+              effect="dark"
+              :content="index - 1 === 0 ? '正常模式' : '滚动至顶部固定'"
+              placement="bottom"
+              v-for="index in 2"
+              :key="index"
+            >
+              <i
+                class="iconfont"
+                :class="[
+                  index - 1 === 0 ? 'icon-wangye1' : 'icon-zhiding',
+                  datas.position === index - 1 ? 'active' : '',
+                ]"
+                @click="datas.position = index - 1"
+              />
+            </el-tooltip>
+          </div>
+        </div>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 框体样式 -->
+      <el-form-item class="lef" label="框体样式">
+        <div class="weiz">
+          <span>{{ datas.borderRadius === 0 ? '方形' : '圆形' }}</span>
+          <div>
+            <el-tooltip
+              effect="dark"
+              :content="index - 1 === 0 ? '方形' : '圆形'"
+              placement="bottom"
+              v-for="index in 2"
+              :key="index"
+            >
+              <i
+                class="iconfont"
+                :class="[
+                  index - 1 === 0 ? 'icon-sousuokuang1' : 'icon-sousuokuang',
+                  datas.borderRadius === index - 1 ? 'active' : '',
+                ]"
+                @click="datas.borderRadius = index - 1"
+              />
+            </el-tooltip>
+          </div>
+        </div>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 文本位置 -->
+      <el-form-item class="lef" label="文本位置">
+        <div class="weiz">
+          <span>{{ datas.textPosition === 0 ? '居左' : '居中' }}</span>
+          <div>
+            <el-tooltip
+              effect="dark"
+              :content="index - 1 === 0 ? '居左' : '居中'"
+              placement="bottom"
+              v-for="index in 2"
+              :key="index"
+            >
+              <i
+                class="iconfont"
+                :class="[
+                  index - 1 === 0 ? 'icon-horizontal-left' : 'icon-juzhong',
+                  datas.textPosition === index - 1 ? 'active' : '',
+                ]"
+                @click="datas.textPosition = index - 1"
+              />
+            </el-tooltip>
+          </div>
+        </div>
+      </el-form-item>
+
+      <!-- 扫一扫 -->
+      <el-form-item class="lef" label="扫一扫">
+        {{ datas.sweep ? '显示' : '隐藏' }}
+        <el-checkbox style="margin-left: 196px" v-model="datas.sweep" />
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 框体高度 -->
+      <el-form-item label="框体高度" class="lef borrediu">
+        <el-slider
+          v-model="datas.heights"
+          :max="50"
+          :min="28"
+          input-size="mini"
+          show-input
+        >
+        </el-slider>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 背景颜色 -->
+      <el-form-item class="lef" label="背景颜色">
+        <!-- 颜色选择器 -->
+        <el-color-picker
+          v-model="datas.backgroundColor"
+          show-alpha
+          class="picke"
+          :predefine="predefineColors"
+        >
+        </el-color-picker>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 框体颜色 -->
+      <el-form-item class="lef" label="框体颜色">
+        <!-- 颜色选择器 -->
+        <el-color-picker
+          v-model="datas.borderColor"
+          show-alpha
+          class="picke"
+          :predefine="predefineColors"
+        >
+        </el-color-picker>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 文本颜色 -->
+      <el-form-item class="lef" label="文本颜色">
+        <!-- 颜色选择器 -->
+        <el-color-picker
+          v-model="datas.textColor"
+          show-alpha
+          class="picke"
+          :predefine="predefineColors"
+        >
+        </el-color-picker>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import vuedraggable from 'vuedraggable' //拖拽组件
+
+export default {
+  name: 'commoditysearchstyle',
+  props: {
+    datas: Object,
+  },
+  components: { vuedraggable },
+  data() {
+    return {
+      predefineColors: [
+        // 颜色选择器预设
+        '#ff4500',
+        '#ff8c00',
+        '#ffd700',
+        '#90ee90',
+        '#00ced1',
+        '#1e90ff',
+        '#c71585',
+        '#409EFF',
+        '#909399',
+        '#C0C4CC',
+        'rgba(255, 69, 0, 0.68)',
+        'rgb(255, 120, 0)',
+        'hsv(51, 100, 98)',
+        'hsva(120, 40, 94, 0.5)',
+        'hsl(181, 100%, 37%)',
+        'hsla(209, 100%, 56%, 0.73)',
+        '#c7158577',
+      ],
+      dragOptions: {
+        //拖拽配置
+        animation: 200,
+      },
+    }
+  },
+  methods: {
+    /* 添加热词 */
+    addHotords() {
+      this.datas.hotords.push({
+        text: '',
+      })
+    },
+    /* 删除热词 */
+    deleteHotords(index) {
+      this.datas.hotords.splice(index, 1)
+    },
+  },
+}
+</script>
+
+<style scoped lang="less">
+.commoditysearchstyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+
+  /* 上传图片按钮 */
+  .uploadImg {
+    width: 345px;
+    height: 40px;
+    margin-top: 10px;
+  }
+
+  /* 热词列表 */
+  .imgList {
+    padding: 6px 12px;
+    margin: 16px 7px;
+    border-radius: 2px;
+    background-color: #fff;
+    box-shadow: 0 0 4px 0 rgba(10, 42, 97, 0.2);
+    display: flex;
+    position: relative;
+
+    /* 删除图标 */
+    .el-icon-circle-close {
+      position: absolute;
+      right: -10px;
+      top: -10px;
+      cursor: pointer;
+      font-size: 19px;
+    }
+
+    /* 热词文字 */
+    .imgText {
+      width: 100%;
+      display: flex;
+      flex-direction: column;
+      box-sizing: border-box;
+      justify-content: space-between;
+    }
+  }
+
+  /* 图片样式 */
+  .weiz {
+    display: flex;
+    justify-content: space-between;
+    i {
+      padding: 5px 14px;
+      margin-left: 10px;
+      border-radius: 0;
+      border: 1px solid #ebedf0;
+      font-size: 20px;
+      font-weight: 500;
+      cursor: pointer;
+
+      &:last-child {
+        font-size: 22px;
+      }
+
+      &.active {
+        color: #155bd4;
+        border: 1px solid #155bd4;
+        background: #e0edff;
+      }
+    }
+  }
+
+  .lef {
+    /deep/.el-form-item__label {
+      text-align: left;
+    }
+  }
+
+  /* 颜色选择器 */
+  .picke {
+    float: right;
+  }
+}
+</style>

+ 221 - 0
src/asEditorComponents/rightslider/communitypowderstyle/index.vue

@@ -0,0 +1,221 @@
+<template>
+  <div class="communitypowderstyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+
+    <div style="height: 20px" />
+
+    <!-- 提示 -->
+    <!-- <el-tooltip class="item" effect="dark" content="" placement="bottom">
+      <div slot="content">活码是用户推广个人微信号或粉丝群的二维码,适用于线上线下,吸引用户<br/>添加好友或粉丝群进行长期维护的场景</div>
+      <i class="el-icon-question" style="cursor: pointer;"></i>
+    </el-tooltip> -->
+
+    <!-- 表单 -->
+    <el-form
+      label-position="top"
+      label-width="80px"
+      :model="datas"
+      size="small"
+      :rules="rules"
+    >
+      <div style="height: 10px" />
+
+      <!-- 描述 -->
+      <el-form-item label="入口图片" :hide-required-asterisk="true">
+        <div class="backgroundImg" @click="showImg('mainImg')">
+          <img
+            draggable="false"
+            v-if="!datas.mainImg"
+            src="../../../assets/images/powder.png"
+            alt=""
+          />
+          <img draggable="false" v-else :src="datas.mainImg" alt="" />
+          <p>更换图片</p>
+        </div>
+      </el-form-item>
+
+      <!-- 二维码 -->
+      <el-form-item label="二维码" :hide-required-asterisk="true">
+        <div class="backgroundImg" @click="showImg('qrcodeImg')">
+          <i class="el-icon-plus" v-if="!datas.qrcodeImg" size="30"></i>
+          <img draggable="false" v-else :src="datas.qrcodeImg" alt="" />
+          <p>更换图片</p>
+        </div>
+      </el-form-item>
+
+      <!-- 标题 -->
+      <el-form-item label="标题" prop="title" :hide-required-asterisk="true">
+        <el-input
+          v-model="datas.title"
+          placeholder="个人微信号, 群名称或活动标题"
+          show-word-limit
+        />
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 描述 -->
+      <el-form-item label="描述" prop="describe" :hide-required-asterisk="true">
+        <el-input
+          v-model="datas.describe"
+          placeholder="请添加描述"
+          show-word-limit
+        />
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 按钮名称 -->
+      <el-form-item
+        label="按钮名称"
+        prop="buttonName"
+        :hide-required-asterisk="true"
+      >
+        <el-input
+          v-model="datas.buttonName"
+          placeholder="请输入按钮名称"
+          show-word-limit
+          maxlength="8"
+        />
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 背景颜色 -->
+      <el-form-item label="背景颜色" class="color-select">
+        <!-- 颜色选择器 -->
+        <el-color-picker
+          v-model="datas.backColor"
+          show-alpha
+          class="picke"
+          :predefine="predefineColors"
+        >
+        </el-color-picker>
+      </el-form-item>
+    </el-form>
+
+    <!-- 上传图片 -->
+    <uploadimg ref="upload" @uploadInformation="uploadInformation" />
+  </div>
+</template>
+
+<script>
+import uploadimg from '../../uploadImg' //图片上传
+
+export default {
+  name: 'communitypowderstyle',
+  props: {
+    datas: Object,
+  },
+  data() {
+    return {
+      rules: {
+        title: [
+          //页面名称
+          { required: true, message: '请输入标题', trigger: 'blur' },
+        ],
+        describe: [
+          // 描述
+          { required: true, message: '请输入描述', trigger: 'blur' },
+        ],
+        buttonName: [
+          // 按钮名称
+          { required: true, message: '请输入按钮名称', trigger: 'blur' },
+        ],
+      },
+      predefineColors: [
+        // 颜色选择器预设
+        '#ff4500',
+        '#ff8c00',
+        '#ffd700',
+        '#90ee90',
+        '#00ced1',
+        '#1e90ff',
+        '#c71585',
+        '#409EFF',
+        '#909399',
+        '#C0C4CC',
+        'rgba(255, 69, 0, 0.68)',
+        'rgb(255, 120, 0)',
+        'hsv(51, 100, 98)',
+        'hsva(120, 40, 94, 0.5)',
+        'hsl(181, 100%, 37%)',
+        'hsla(209, 100%, 56%, 0.73)',
+        '#c7158577',
+      ],
+      imgText: '', //哪一个图片
+    }
+  },
+  methods: {
+    // 提交
+    uploadInformation(res) {
+      this.datas[this.imgText] = res
+    },
+    showImg(res) {
+      this.imgText = res
+      this.$refs.upload.showUpload()
+    },
+  },
+  components: { uploadimg },
+}
+</script>
+
+<style scoped lang="less">
+.communitypowderstyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+  /* 颜色选择器 */
+  .picke {
+    margin-left: 15px;
+    vertical-align: top;
+  }
+  /* 背景图 */
+  .backgroundImg {
+    display: inline-flex;
+    justify-content: center;
+    align-items: center;
+    cursor: pointer;
+    width: 60px;
+    height: 60px;
+    position: relative;
+    background: #f2f4f6;
+
+    img {
+      width: 100%;
+      height: auto;
+    }
+
+    p {
+      position: absolute;
+      left: 0;
+      bottom: 0;
+      width: 100%;
+      height: 20px;
+      font-size: 12px;
+      color: #fff;
+      background: rgba(0, 0, 0, 0.5);
+      text-align: center;
+      line-height: 20px;
+    }
+  }
+  .color-select {
+    /deep/.el-form-item__content {
+      float: right;
+    }
+  }
+}
+</style>

+ 116 - 0
src/asEditorComponents/rightslider/componenmanagement/index.vue

@@ -0,0 +1,116 @@
+<template>
+  <div class="componenManagement">
+    <!-- 标题 -->
+    <h2>组件设置</h2>
+    <p class="Prompt">底部导航组件为固定页面底部,无需拖拽调整位置</p>
+    <!-- 拖拽 -->
+    <vuedraggable v-model="data" v-bind="dragOptions">
+      <transition-group>
+        <div
+          v-for="(item, ind) in data"
+          :key="item.text + ind"
+          :class="item.text == '底部导航' ? 'item delDragitem' : 'item'"
+        >
+          <p>
+            <i class="el-icon-s-grid" style="margin-right: 15px" />{{
+              item.text
+            }}
+          </p>
+          <el-popconfirm
+            title="您确定要删除该组件吗?"
+            icon="el-icon-warning"
+            iconColor="red"
+            @confirm="onConfirms(ind)"
+          >
+            <i
+              class="el-icon-delete-solid"
+              slot="reference"
+              style="cursor: pointer"
+            />
+          </el-popconfirm>
+        </div>
+      </transition-group>
+    </vuedraggable>
+  </div>
+</template>
+
+<script>
+import vuedraggable from 'vuedraggable' //拖拽组件
+
+export default {
+  name: 'componenmanagement',
+  props: ['datas'],
+  components: { vuedraggable },
+  data() {
+    return {
+      data: this.datas,
+      dragOptions: {
+        animation: 200,
+        // class是 delDragitem 禁止拖拽
+        filter: '.delDragitem',
+      },
+    }
+  },
+  methods: {
+    /* 删除组件 */
+    onConfirms(res) {
+      this.data.splice(res, 1)
+      this.$emit('componenmanagement', this.data)
+    },
+  },
+  watch: {
+    datas(newVal) {
+      this.data = newVal
+    },
+
+    data(newVal) {
+      this.$emit('componenmanagement', newVal)
+    },
+  },
+  computed: {},
+}
+</script>
+
+<style scoped lang="less">
+/* 组件管理 */
+.componenManagement {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px;
+  box-sizing: border-box;
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+
+  /* 选项 */
+  .item {
+    height: 40px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 0 10px;
+    font-size: 14px;
+    cursor: all-scroll;
+    color: #323233;
+    border-radius: 2px;
+    background-color: #fff;
+    box-shadow: 0 0 4px 0 rgba(10, 42, 97, 0.2);
+    margin-bottom: 10px;
+    i {
+      color: #999;
+    }
+  }
+  .delDragitem {
+    background-color: rgba(10, 42, 97, 0.2);
+    cursor: no-drop;
+  }
+}
+</style>

+ 35 - 0
src/asEditorComponents/rightslider/crowdoperationstyle/index.vue

@@ -0,0 +1,35 @@
+<template>
+  <div class="crowdoperationstyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'crowdoperationstyle',
+  props: {
+    datas: Object,
+  },
+}
+</script>
+
+<style scoped lang="less">
+.crowdoperationstyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+}
+</style>

+ 40 - 0
src/asEditorComponents/rightslider/custommodulestyle/index.vue

@@ -0,0 +1,40 @@
+<template>
+  <div class="custommodulestyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+    <el-input v-model="datas.demo" placeholder="请输入公告" />
+    <el-input v-model="datas.img" placeholder="图片地址" />
+        {{ 'aaa'+ datas.type}}
+
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'custommodulestyle',
+  props: {
+    datas: Object,
+    'data-type':String,
+  },
+}
+</script>
+
+<style scoped lang="less">
+.custommodulestyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+}
+</style>

+ 278 - 0
src/asEditorComponents/rightslider/decorate/index.vue

@@ -0,0 +1,278 @@
+<template>
+  <div class="decorate">
+    <!-- 标题 -->
+    <h2>页面设置</h2>
+
+    <!-- 表单 -->
+    <el-form
+      label-position="top"
+      label-width="80px"
+      :model="datas"
+      :rules="rules"
+      size="small"
+    >
+      <el-form-item label="页面名称" :hide-required-asterisk="true" prop="name">
+        <el-input
+          v-model="datas.name"
+          placeholder="页面标题"
+          maxlength="25"
+          show-word-limit
+        />
+      </el-form-item>
+
+      <el-form-item
+        label="页面描述"
+        :hide-required-asterisk="true"
+        prop="details"
+      >
+        <el-input
+          v-model="datas.details"
+          placeholder="用户通过微信分享给朋友时,会自动显示页面描述"
+        />
+      </el-form-item>
+
+      <!-- 个人中心 -->
+      <el-form-item label="个人中心" class="lef">
+        {{ datas.isPerson ? '显示' : '隐藏' }}
+        <el-checkbox style="margin-left: 196px" v-model="datas.isPerson" />
+      </el-form-item>
+
+      <!-- 返回 -->
+      <el-form-item label="返回按钮" class="lef">
+        {{ datas.isBack ? '显示' : '隐藏' }}
+        <el-checkbox style="margin-left: 196px" v-model="datas.isBack" />
+      </el-form-item>
+
+      <!-- 高度 -->
+      <el-form-item label="高度" class="lef-height">
+        <el-slider
+          v-model="datas.titleHeight"
+          :max="100"
+          :min="35"
+          input-size="mini"
+          show-input
+        >
+        </el-slider>
+      </el-form-item>
+
+      <!-- 背景颜色 -->
+      <el-form-item label="背景颜色">
+        <!-- 单选框 -->
+        <el-radio-group v-model="colourAction">
+          <el-radio label="默认颜色" />
+          <el-radio label="自定义颜色" />
+        </el-radio-group>
+
+        <!-- 颜色选择器 -->
+        <el-color-picker
+          v-model="datas.bgColor"
+          show-alpha
+          class="picke"
+          v-show="pickeShow"
+          :predefine="predefineColors"
+        >
+        </el-color-picker>
+      </el-form-item>
+
+      <el-form-item label="背景图片">
+        <div class="shop-head-pic" style="text-align: center">
+          <img class="home-bg" :src="datas.bgImg" alt="" v-if="datas.bgImg" />
+          <div class="shop-head-pic-btn" style="text-align: center">
+            <el-button
+              @click="showUpload('2')"
+              class="uploadImg"
+              type="primary"
+              plain
+              ><i class="el-icon-plus" />更换图片</el-button
+            >
+            <el-button type="primary" @click="clear()">清空图片</el-button>
+          </div>
+        </div>
+      </el-form-item>
+
+    </el-form>
+
+    <!-- 上传图片 -->
+    <uploadimg ref="upload" @uploadInformation="uploadInformation" />
+  </div>
+</template>
+
+<script>
+import uploadimg from '../../uploadImg' //图片上传
+
+export default {
+  name: 'decorate',
+  props: {
+    datas: Object,
+  },
+  data() {
+    return {
+      rules: {
+        //校验表单输入
+        name: [
+          //页面名称
+          { required: true, message: '请输入页面名称', trigger: 'blur' },
+        ],
+        details: [
+          //页面描述
+          { required: true, message: '请输入页面描述', trigger: 'blur' },
+        ],
+        classification: [
+          //分类
+          { required: true, message: '请选择页面分类', trigger: 'blur' },
+        ],
+      },
+      colourAction: '默认颜色', // 颜色选择
+      pickeShow: false, //颜色选择器是否显示
+      predefineColors: [
+        // 颜色选择器预设
+        '#ff4500',
+        '#ff8c00',
+        '#ffd700',
+        '#90ee90',
+        '#00ced1',
+        '#1e90ff',
+        '#c71585',
+        '#409EFF',
+        '#909399',
+        '#C0C4CC',
+        'rgba(255, 69, 0, 0.68)',
+        'rgb(255, 120, 0)',
+        'hsv(51, 100, 98)',
+        'hsva(120, 40, 94, 0.5)',
+        'hsl(181, 100%, 37%)',
+        'hsla(209, 100%, 56%, 0.73)',
+        '#c7158577',
+      ],
+      uploadImgDataType: null, // 获取到的图片地址属于哪一类别   0 修改底部logo   1 修改店铺图标 2 页面背景图
+    }
+  },
+
+  created() {},
+
+  methods: {
+    // 显示上传图片组件   type :  2 页面背景图
+    showUpload(type) {
+      this.uploadImgDataType = type
+      this.$refs.upload.showUpload()
+    },
+
+    // 上传图片
+    uploadInformation(res) {
+      if (this.uploadImgDataType === '2') {
+        this.datas.bgImg = res
+      }
+    },
+
+    // 清空背景图片
+    clear() {
+      this.datas.bgImg = ''
+    },
+
+  },
+  watch: {
+    colourAction(data) {
+      if (data === '默认颜色') {
+        this.datas.bgColor = 'rgba(249, 249, 249, 10)'
+        this.pickeShow = false
+        return
+      } else return (this.pickeShow = true)
+    },
+  },
+  components: { uploadimg },
+}
+</script>
+
+<style scoped lang="less">
+/* 页面设置 */
+.decorate {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px;
+  box-sizing: border-box;
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+  /* 选择器添加和刷新 */
+  .ification {
+    color: #155bd4;
+    font-size: 14px;
+    padding: 0 15px;
+    cursor: pointer;
+  }
+  /* 颜色选择器 */
+  .picke {
+    margin-left: 15px;
+    vertical-align: top;
+  }
+  .home-bg {
+    width: 100px;
+    height: 300px;
+  }
+
+  .lef {
+    display: flex;
+    /deep/.el-form-item__label {
+      text-align: left;
+      margin-right: 20px;
+    }
+  }
+  .lef-height {
+    /deep/.el-form-item__label {
+      text-align: left;
+      width: 80px;
+      float: left;
+    }
+    /deep/.el-form-item__content {
+      margin-left: 80px;
+    }
+  }
+
+  // 底部logo
+  .bottomLogo {
+    display: flex;
+    flex-direction: column;
+    img {
+      display: block;
+      width: 220px;
+      margin: 10px auto;
+    }
+  }
+
+  // 店铺信息修改
+  .shop-info {
+    .shop-name {
+      display: flex;
+      flex-direction: row;
+      color: #ababab;
+      .el-input {
+        flex: 1;
+      }
+    }
+    .shop-head-pic {
+      color: #ababab;
+      display: flex;
+      flex-direction: column;
+      img {
+        width: 70px;
+        height: 70px;
+        margin: 10px auto;
+      }
+      .shop-head-pic-btn {
+        display: flex;
+        flex-direction: row;
+        .el-button {
+          flex: 1;
+        }
+      }
+    }
+  }
+}
+</style>

+ 175 - 0
src/asEditorComponents/rightslider/entertheshopstyle/index.vue

@@ -0,0 +1,175 @@
+<template>
+  <div class="entertheshopstyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+
+    <!-- 表单 -->
+    <el-form
+      label-position="top"
+      label-width="80px"
+      :model="datas"
+      :rules="rules"
+      size="small"
+    >
+      <el-form-item
+        label="左侧标题"
+        :hide-required-asterisk="true"
+        prop="shopName"
+      >
+        <el-input
+          v-model="datas.shopName"
+          placeholder="请输入左侧标题"
+          maxlength="10"
+          show-word-limit
+        />
+      </el-form-item>
+
+      <!-- 文案 -->
+      <el-form-item
+        label="右侧内容"
+        :hide-required-asterisk="true"
+        prop="copywriting"
+      >
+        <el-input
+          v-model="datas.copywriting"
+          placeholder="请输入右侧内容"
+          maxlength="8"
+          show-word-limit
+        />
+      </el-form-item>
+
+      <el-form-item label="左侧图标">
+        <img :src="datas.icon" v-if="datas.icon" />
+        <!-- 添加导航按钮 -->
+        <el-button
+          @click="$refs.upload.showUpload()"
+          class="uploadImg"
+          type="primary"
+          plain
+        >
+          <i class="el-icon-plus" />点击{{datas.icon?'更换':'添加'}}图片
+        </el-button>
+      </el-form-item>
+
+      <!-- 跳转页面 -->
+      <el-form-item label="跳转页面">
+        <div class="imgText">
+          <el-select
+            style="width: 60%"
+            v-model="datas.type"
+            placeholder="请选择跳转类型"
+            size="mini"
+          >
+            <el-option
+              v-for="item in optionsType"
+              :key="item.name"
+              :label="item.name"
+              :value="item.type"
+            >
+            </el-option>
+          </el-select>
+
+          <!-- 输入链接 -->
+          <el-input
+            style="width: 100%"
+            size="mini"
+            placeholder="请输入链接,输入前确保可以访问"
+            v-model="datas.http.externalLink"
+          >
+          </el-input>
+        </div>
+      </el-form-item>
+    </el-form>
+
+    <!-- 上传图片 -->
+    <uploadimg ref="upload" @uploadInformation="uploadInformation" />
+  </div>
+</template>
+
+<script>
+import uploadimg from '../../uploadImg' //图片上传
+
+export default {
+  name: 'entertheshopstyle',
+  props: {
+    datas: Object,
+  },
+  data() {
+    return {
+      rules: {
+        //校验表单输入
+        shopName: [
+          //页面名称
+          { required: true, message: '请输入左侧标题', trigger: 'blur' },
+        ],
+        copywriting: [
+          //页面描述
+        ],
+      },
+      optionsType: [
+        {
+          type: '10',
+          name: '内部链接',
+        },
+        {
+          type: '11',
+          name: '外部链接',
+        },
+      ], // 选择跳转类型
+      emptyText: '',
+    }
+  },
+  methods: {
+    // 提交
+    uploadInformation(res) {
+      this.datas.icon = res
+      console.log(res)
+    },
+  },
+  components: {
+    uploadimg,
+  },
+}
+</script>
+
+<style scoped lang="less">
+.entertheshopstyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+  /* 图片字 */
+  .imgText {
+    width: 100%;
+    display: flex;
+    box-sizing: border-box;
+    justify-content: space-between;
+    .fir-sele.el-select {
+      width: 40%;
+    }
+  }
+  /* 上传图片按钮 */
+  .uploadImg {
+    width: 345px;
+    height: 40px;
+    margin-top:20px ;
+  }
+  img{
+    display: block;
+    margin: 0 auto;
+    width: 56px;
+    height: 56px;
+  }
+}
+</style>

+ 109 - 0
src/asEditorComponents/rightslider/followStyle/index.vue

@@ -0,0 +1,109 @@
+<template>
+  <div id="followStyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+
+    <el-form>
+      <el-form-item class="lef" label="公众号图片">
+        <div class="follow-pic">
+          <img :src="datas.heade" alt="" />
+          <el-button
+            @click="$refs.upload.showUpload()"
+            class="uploadImg"
+            type="primary"
+            plain
+          >
+            <i class="el-icon-plus" />上传公众号图片
+          </el-button>
+        </div>
+      </el-form-item>
+
+      <el-form-item class="lef" label="公众号名称">
+        <el-input type="text" v-model="datas.followName" placeholder="请输入公众号名称" />
+      </el-form-item>
+
+      <el-form-item class="lef" label="公众号Id">
+        <el-input type="text" v-model="datas.followAppId" placeholder="请输入公众号Id" />
+      </el-form-item>
+    </el-form>
+
+    <!-- 上传图片 -->
+    <uploadimg ref="upload" @uploadInformation="uploadInformation" />
+  </div>
+</template>
+
+<script>
+import uploadimg from '../../uploadImg' //图片上传
+export default {
+  name: 'followStyle',
+  props: {
+    datas: Object,
+  },
+  data() {
+    return {}
+  },
+
+  created() {
+    console.log(this.datas,'-------------followStyle datas')
+  },
+
+  mounted() {},
+
+  methods: {
+    // 提交
+    uploadInformation(res) {
+      this.datas.heade = res
+    },
+  },
+
+  computed: {},
+
+  watch: {},
+  components: {
+    uploadimg,
+  },
+}
+</script>
+
+<style lang="less" scoped>
+#followStyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+}
+
+/* 标题 */
+h2 {
+  padding: 24px 16px 24px 0;
+  margin-bottom: 15px;
+  border-bottom: 1px solid #f2f4f6;
+  font-size: 18px;
+  font-weight: 600;
+  color: #323233;
+}
+.lef {
+  /deep/.el-form-item__label {
+    text-align: left;
+  }
+}
+
+.follow-pic {
+  width: 100%;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  img {
+    display: block;
+    width: 50px;
+    height: 50px;
+    border-radius: 50%;
+  }
+  .uploadImg {
+    width: 80%;
+    margin-top: 20px;
+  }
+}
+</style>

+ 454 - 0
src/asEditorComponents/rightslider/graphicnavigationstyle/index.vue

@@ -0,0 +1,454 @@
+<template>
+  <div class="graphicnavigationstyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+
+    <!-- 提示 -->
+    <p style="color: #969799; font-size: 12px; margin-top: 10px">
+      拖动选中的导航可对其排序
+    </p>
+
+    <!-- 图片广告 -->
+    <div v-if="datas.imageList[0]">
+      <vuedraggable v-model="datas.imageList" v-bind="dragOptions">
+        <transition-group>
+          <section
+            class="imgList"
+            v-for="(item, index) in datas.imageList"
+            :key="item + index"
+          >
+            <i class="el-icon-circle-close" @click="deleteimg(index)" />
+            <!-- 图片 -->
+            <div class="imag">
+              <img draggable="false" :src="item.src" alt="" />
+            </div>
+            <!-- 标题和链接 -->
+            <div class="imgText">
+              <el-input
+                v-model="item.text"
+                placeholder="请输入标题,也可不填"
+                size="mini"
+              ></el-input>
+              <!-- 选择类型 -->
+              <div class="select-type">
+                <el-select
+                  style="width: 60%"
+                  v-model="item.linktype"
+                  placeholder="请选择跳转类型"
+                  size="mini"
+                >
+                  <el-option
+                    v-for="item in optionsType"
+                    :key="item.name"
+                    :label="item.name"
+                    :value="item.type"
+                  >
+                  </el-option>
+                </el-select>
+
+                <!-- 输入链接 -->
+                <el-input
+                  style="width: 100%"
+                  size="mini"
+                  placeholder="请输入链接,输入前确保可以访问"
+                  v-model="item.http.externalLink"
+                >
+                </el-input>
+              </div>
+            </div>
+          </section>
+        </transition-group>
+      </vuedraggable>
+    </div>
+
+    <!-- 上传图片 -->
+    <el-button @click="showUpload('0')" class="uploadImg" type="primary" plain
+      ><i class="el-icon-plus" />点击添加导航</el-button
+    >
+
+    <div class="bor"></div>
+
+    <!-- 表单 -->
+    <el-form label-width="80px" :model="datas" size="small">
+      <!-- 商品类型选择 -->
+      <el-form-item class="lef" label="商品类型">
+        <el-radio-group v-model="datas.navigationType">
+          <el-radio
+            style="margin-left: 35px"
+            :label="index - 1"
+            v-for="index in 2"
+            :key="index"
+            >{{ index === 1 ? '图片导航' : '文字导航' }}</el-radio
+          >
+        </el-radio-group>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 图片样式 -->
+      <el-form-item class="lef" label="图片样式">
+        <div class="weiz">
+          <el-tooltip
+            effect="dark"
+            :content="index - 1 === 0 ? '固定' : '滑动'"
+            placement="bottom"
+            v-for="index in 2"
+            :key="index"
+          >
+            <i
+              class="iconfont"
+              :class="[
+                index - 1 === 0 ? 'icon-guding' : 'icon-hengxianghuadong',
+                datas.imgStyle === index - 1 ? 'active' : '',
+              ]"
+              @click="datas.imgStyle = index - 1"
+            />
+          </el-tooltip>
+        </div>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 一屏显示 -->
+      <el-form-item class="lef" label="一屏显示" v-show="datas.imgStyle === 1">
+        <el-select
+          v-model="datas.showSize"
+          placeholder="请选择活动区域"
+          style="margin-left: 90px"
+        >
+          <el-option
+            :label="index + 4 + '个导航'"
+            :value="index + 4"
+            v-for="index in 7"
+            :key="index"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 文字高度 -->
+      <el-form-item label="文字高度" class="lef">
+        <el-slider
+          v-model="datas.textHeight"
+          :max="50"
+          :min="24"
+          input-size="mini"
+          show-input
+        >
+        </el-slider>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 文字大小 -->
+      <el-form-item
+        label="文字大小"
+        prop="textSize"
+        :hide-required-asterisk="true"
+        class="lef"
+      >
+        <el-input
+          type="number"
+          v-model.number="datas.textSize"
+          placeholder="请输入文字大小"
+          :maxlength="2"
+        />
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 图片倒角 -->
+      <el-form-item label="图片倒角" class="lef borrediu">
+        <el-slider
+          v-model="datas.borderRadius"
+          :max="50"
+          input-size="mini"
+          show-input
+        >
+        </el-slider>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <el-form-item class="lef" label="背景图片">
+        <div class="shop-head-pic" style="text-align: center">
+          <img class="home-bg" :src="datas.bgImg" alt="" v-if="datas.bgImg" />
+          <div class="shop-head-pic-btn" style="text-align: center">
+            <el-button
+              @click="showUpload('1')"
+              class="uploadImg"
+              type="primary"
+              plain
+              ><i class="el-icon-plus" />更换图片</el-button
+            >
+            <el-button type="primary" class="uploadImg" @click="clear()"
+              >清空图片</el-button
+            >
+          </div>
+        </div>
+      </el-form-item>
+      <div style="height: 10px" />
+
+      <!-- 背景颜色 -->
+      <el-form-item class="lef" label="背景颜色">
+        <!-- 颜色选择器 -->
+        <el-color-picker
+          v-model="datas.backgroundColor"
+          show-alpha
+          class="picke"
+          :predefine="predefineColors"
+        >
+        </el-color-picker>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 文字颜色 -->
+      <el-form-item class="lef" label="文字颜色">
+        <!-- 颜色选择器 -->
+        <el-color-picker
+          v-model="datas.textColor"
+          show-alpha
+          class="picke"
+          :predefine="predefineColors"
+        >
+        </el-color-picker>
+      </el-form-item>
+    </el-form>
+
+    <!-- 上传图片 -->
+    <uploadimg ref="upload" @uploadInformation="uploadInformation" />
+  </div>
+</template>
+
+<script>
+import uploadimg from '../../uploadImg' //图片上传
+import vuedraggable from 'vuedraggable' //拖拽组件
+
+export default {
+  name: 'graphicnavigationstyle',
+  props: {
+    datas: Object,
+  },
+  data() {
+    return {
+      dragOptions: {
+        //拖拽配置
+        animation: 200,
+      },
+      predefineColors: [
+        // 颜色选择器预设
+        '#ff4500',
+        '#ff8c00',
+        '#ffd700',
+        '#90ee90',
+        '#00ced1',
+        '#1e90ff',
+        '#c71585',
+        '#409EFF',
+        '#909399',
+        '#C0C4CC',
+        'rgba(255, 69, 0, 0.68)',
+        'rgb(255, 120, 0)',
+        'hsv(51, 100, 98)',
+        'hsva(120, 40, 94, 0.5)',
+        'hsl(181, 100%, 37%)',
+        'hsla(209, 100%, 56%, 0.73)',
+        '#c7158577',
+      ],
+      optionsType: [
+        {
+          type: '10',
+          name: '内部链接',
+        },
+        {
+          type: '11',
+          name: '外部链接',
+        },
+      ], // 选择跳转类型
+      emptyText: '',
+      uploadImgDataType: null,
+    }
+  },
+  created() {
+  },
+  methods: {
+    showUpload(type) {
+      this.uploadImgDataType = type
+      this.$refs.upload.showUpload()
+    },
+    // 提交
+    uploadInformation(res) {
+      if (this.uploadImgDataType === '0') {
+        this.datas.imageList.push({
+          src: res,
+          text: '',
+          http: {},
+        })
+      } else if (this.uploadImgDataType === '1') {
+        this.datas.bgImg = res
+      }
+    },
+
+    // 清空背景图片
+    clear() {
+      this.datas.bgImg = ''
+    },
+    /* 删除图片列表的图片 */
+    deleteimg(index) {
+      this.datas.imageList.splice(index, 1)
+    },
+  },
+  components: { uploadimg, vuedraggable },
+}
+</script>
+
+<style scoped lang="less">
+.graphicnavigationstyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+
+  .lef {
+    /deep/.el-form-item__label {
+      text-align: left;
+    }
+  }
+
+  /* 上传图片按钮 */
+  .uploadImg {
+    width: 345px;
+    height: 40px;
+    margin-top: 10px;
+  }
+
+  /* 商品列表 */
+  .imgList {
+    padding: 6px 12px;
+    margin: 16px 7px;
+    border-radius: 2px;
+    background-color: #fff;
+    box-shadow: 0 0 4px 0 rgba(10, 42, 97, 0.2);
+    display: flex;
+    position: relative;
+
+    /* 删除图标 */
+    .el-icon-circle-close {
+      position: absolute;
+      right: -10px;
+      top: -10px;
+      cursor: pointer;
+      font-size: 19px;
+    }
+
+    /* 图片 */
+    .imag {
+      width: 60px;
+      height: 60px;
+      border-radius: 5px;
+      overflow: hidden;
+      position: relative;
+      cursor: pointer;
+      img {
+        width: 100%;
+        height: 100%;
+        display: inline-block;
+      }
+      span {
+        background: rgba(0, 0, 0, 0.5);
+        font-size: 12px;
+        position: absolute;
+        left: 0px;
+        bottom: 0px;
+        display: inline-block;
+        width: 100%;
+        text-align: center;
+        color: #fff;
+        height: 20px;
+        line-height: 20px;
+      }
+    }
+
+    /* 图片字 */
+    .imgText {
+      width: 80%;
+      display: flex;
+      flex-direction: column;
+      box-sizing: border-box;
+      padding-left: 20px;
+      justify-content: space-between;
+      .select-type {
+        display: flex;
+        /deep/.el-select {
+          .el-input {
+            input {
+              white-space: nowrap;
+              overflow: hidden;
+              text-overflow: ellipsis;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  /* 图片样式 */
+  .weiz {
+    text-align: right;
+    i {
+      padding: 5px 14px;
+      margin-left: 10px;
+      border-radius: 0;
+      border: 1px solid #ebedf0;
+      font-size: 20px;
+      font-weight: 500;
+      cursor: pointer;
+
+      &:last-child {
+        font-size: 22px;
+      }
+
+      &.active {
+        color: #155bd4;
+        border: 1px solid #155bd4;
+        background: #e0edff;
+      }
+    }
+  }
+
+  .shop-head-pic {
+    color: #ababab;
+    display: flex;
+    flex-direction: column;
+    .home-bg {
+      width: 100px;
+      height: 100px;
+      margin: 10px auto;
+    }
+    .shop-head-pic-btn {
+      display: flex;
+      flex-direction: row;
+      .el-button {
+        flex: 1;
+      }
+    }
+  }
+  /* 颜色选择器 */
+  .picke {
+    float: right;
+  }
+}
+</style>

+ 175 - 0
src/asEditorComponents/rightslider/investigatestyle/index.vue

@@ -0,0 +1,175 @@
+<template>
+  <div class="investigatestyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+
+    <!-- 内容 -->
+    <div>
+      <p class="info" style="color: #ff0000">
+        下拉框,单选,多选等文本用,符号隔开#如:(男#女)
+      </p>
+    </div>
+    <!-- <el-from ref="form" :model="datas" label-width="80px">
+      
+    </el-from>-->
+    <el-form ref="form" :model="datas" label-width="80px">
+      <el-form-item label="名称" label-width="40px">
+        <el-input v-model="datas.title" style="width: 87%"></el-input>
+      </el-form-item>
+      <el-form-item
+        v-for="(item, index) in datas.jsonData"
+        :key="index"
+        class="lef"
+      >
+        <span class="delete" @click="deletetext(index)">x</span>
+        <el-input
+          v-model="item.name"
+          class="title"
+          placeholder="表单模块名称"
+        ></el-input>
+        <el-select
+          v-model="item.type"
+          placeholder="请选择显示格式"
+          @change="conChange(index)"
+        >
+          <el-option
+            :label="item"
+            :value="index"
+            v-for="(item, index) in selecttext"
+            :key="index"
+          ></el-option>
+        </el-select>
+        <el-input
+          type="textarea"
+          v-model="item.value"
+          placeholder="提示语句如:(请输入姓名)"
+          v-if="item.type == 0"
+        ></el-input>
+        <el-input
+          type="textarea"
+          v-model="item.value"
+          @input="item.value1 = item.value.split('#')"
+          placeholder="多项之间用‘#’逗号隔开"
+          v-else
+        ></el-input>
+      </el-form-item>
+      <el-form-item>
+        <el-button @click="addText" class="uploadImg" type="primary" plain>
+          <i class="el-icon-plus" />点击添加内容
+        </el-button>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'investigatestyle',
+  props: {
+    datas: Object,
+  },
+  data() {
+    return {
+      selecttext: ['文本', '下拉框', '单选', '多选'],
+      index1: 0,
+    }
+  },
+  mounted() {},
+  methods: {
+    //添加文本
+    addText() {
+      console.log(this.datas.jsonData)
+      var text = {
+        name: '',
+        type: '',
+        value: '',
+        value1: [],
+        value2: '',
+        showPicker: false,
+      }
+      this.datas.jsonData.push(text)
+    },
+    //删除文本
+    deletetext(index) {
+      this.datas.jsonData.splice(index, 1)
+    },
+    //下拉内容改变发生发生事件
+    conChange(index) {
+      this.datas.jsonData[index].value = ''
+      this.datas.jsonData[index].value1 = []
+    },
+  },
+}
+</script>
+
+<style scoped lang="less">
+.investigatestyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+  .lef {
+    position: relative;
+    /deep/.el-form-item__label {
+      text-align: left;
+    }
+    .delete {
+      background: #ff0000;
+      color: #ffffff;
+      top: -6px;
+      right: -6px;
+      border-radius: 50%;
+      display: block;
+      width: 16px;
+      height: 16px;
+      line-height: 16px;
+      text-align: center;
+      position: absolute;
+      z-index: 10;
+      cursor: pointer;
+    }
+  }
+
+  /deep/.el-form-item__content {
+    margin-left: 0 !important;
+    // display: flex;
+    div {
+      &:nth-child(2) {
+        // flex: 1;
+        width: 90%;
+        margin-right: 2%;
+        margin-bottom: 10px;
+      }
+      &:nth-child(3) {
+        width: 90%;
+        // flex: 1;
+      }
+      &:nth-child(4) {
+        width: 100%;
+        margin-top: 5px;
+        // flex: 3;
+      }
+    }
+  }
+  /* 上传图片按钮 */
+  .uploadImg {
+    width: 345px;
+    height: 40px;
+    margin-top: 20px;
+  }
+}
+// /deep/.el-input__inner{
+//   padding: 0 5px;
+// }
+</style>

+ 823 - 0
src/asEditorComponents/rightslider/listswitchingstyle/index.vue

@@ -0,0 +1,823 @@
+<template>
+  <div class="listswitchingstyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+
+    <!-- 表单 -->
+    <el-form label-width="80px" :model="datas" size="small" :rules="rules">
+      <!-- 标题内容 -->
+      <el-form-item
+        class="lef"
+        label="选择模板"
+        v-show="datas.commoditylisttype !== 2"
+      >
+        <p style="color: #000">{{ styleText }}</p>
+      </el-form-item>
+
+      <!-- 商品样式选择 -->
+      <div class="commodityType" v-show="datas.commoditylisttype !== 2">
+        <el-tooltip
+          class="item"
+          effect="dark"
+          :content="item.content"
+          placement="bottom"
+          v-for="(item, index) in commodityTypes"
+          :key="index"
+        >
+          <span
+            class="iconfont"
+            style="font-size: 21px"
+            :class="[
+              item.type === datas.commodityType ? 'active' : '',
+              item.icon,
+            ]"
+            @click="datas.commodityType = index"
+          />
+        </el-tooltip>
+      </div>
+
+      <!-- 下划线 -->
+      <div class="bor" v-show="datas.commoditylisttype !== 2" />
+
+      <!-- 商品类型选择 -->
+      <el-form-item label="商品类型" class="lef">
+        <el-radio-group v-model="datas.commoditylisttype">
+          <el-radio :label="index - 1" v-for="index in 3" :key="index"
+            >类型{{ index }}</el-radio
+          >
+        </el-radio-group>
+      </el-form-item>
+
+      <!-- tabbar颜色 -->
+      <el-form-item
+        label="标签颜色"
+        class="lef"
+        v-show="datas.commoditylisttype !== 0"
+      >
+        <el-color-picker
+          v-model="datas.tabColor"
+          show-alpha
+          class="picke"
+          :predefine="predefineColors"
+        >
+        </el-color-picker>
+      </el-form-item>
+
+      <div v-show="datas.commoditylisttype === 0">
+        <h5 style="color: #000; font-size: 14px">添加商品</h5>
+        <p style="color: #969799; font-size: 12px; margin-top: 10px">
+          鼠标拖拽调整商品顺序
+        </p>
+
+        <!-- 图片广告 -->
+        <div v-if="datas.imageList[0]">
+          <vuedraggable v-model="datas.imageList" v-bind="dragOptions">
+            <transition-group>
+              <section
+                class="imgBanner"
+                v-for="(item, index) in datas.imageList"
+                :key="item + index"
+              >
+                <i class="el-icon-circle-close" @click="deleteimg(index)" />
+                <div class="imag">
+                  <img draggable="false" :src="item.coverUrl" alt="" />
+                </div>
+                <div class="imgText">
+                  <div>
+                    <el-input
+                      disabled="disabled"
+                      style="width: 65%"
+                      v-model="item.name"
+                      size="mini"
+                    />
+                    <el-input
+                      disabled="disabled"
+                      type="number"
+                      style="width: 35%"
+                      v-model.number="item.price"
+                      size="mini"
+                    />
+                  </div>
+                  <el-input
+                    disabled="disabled"
+                    v-model="item.introduce"
+                    size="mini"
+                  />
+                </div>
+              </section>
+            </transition-group>
+          </vuedraggable>
+        </div>
+
+        <!-- 上传图片 -->
+        <el-button
+          @click="dialogVisibleshow('imageList', null)"
+          class="uploadImg"
+          type="primary"
+          plain
+          ><i class="el-icon-plus" />点击添加商品</el-button
+        >
+      </div>
+
+      <div v-show="datas.commoditylisttype !== 0">
+        <h5 style="color: #000; font-size: 14px; margin-left: 7px">
+          添加商品分组<el-button
+            style="padding: 2px 4px; fnot-size: 12px; margin-left: 200px"
+            @click="addGrouping"
+            type="primary"
+            size="mini"
+            plain
+          >
+            <i class="el-icon-plus" />添加</el-button
+          >
+        </h5>
+        <p
+          style="
+            color: #969799;
+            font-size: 12px;
+            margin-left: 7px;
+            margin-top: 10px;
+          "
+        >
+          鼠标拖拽调整分组顺序
+        </p>
+
+        <!-- 分类名称 -->
+        <section
+          v-for="(item, index) in datas.commoditylisttypetab"
+          :key="index"
+        >
+          <div class="bor" />
+
+          <el-input
+            v-model="item.text"
+            class="tit"
+            style="width: 100px"
+            placeholder="请输入分组名称"
+            size="mini"
+          />
+          <i
+            @click="delecommoditylisttypetab(index)"
+            class="el-icon-delete"
+            style="
+              cursor: pointer;
+              padding: 2px 4px;
+              fnot-size: 12px;
+              margin-left: 200px;
+              color: red;
+            "
+          />
+
+          <vuedraggable v-model="item.imageList" v-bind="dragOptions">
+            <transition-group>
+              <section
+                class="imgBanner"
+                v-for="(item, ind) in item.imageList"
+                :key="item + ind"
+              >
+                <i
+                  class="el-icon-circle-close"
+                  @click="delecommodityimg(index, ind)"
+                />
+                <!-- 图片 -->
+                <div class="imag">
+                  <img draggable="false" :src="item.coverUrl" alt="" />
+                </div>
+                <!-- 标题和链接 -->
+                <div class="imgText">
+                  <div>
+                    <el-input
+                      disabled="disabled"
+                      style="width: 65%"
+                      v-model="item.name"
+                      size="mini"
+                    />
+                    <el-input
+                      disabled="disabled"
+                      type="number"
+                      style="width: 35%"
+                      v-model.number="item.price"
+                      size="mini"
+                    />
+                  </div>
+                  <el-input
+                    disabled="disabled"
+                    v-model="item.introduce"
+                    size="mini"
+                  />
+                </div>
+              </section>
+            </transition-group>
+          </vuedraggable>
+
+          <el-button
+            @click="dialogVisibleshow('commoditylisttypetab', index)"
+            class="uploadImg"
+            type="primary"
+            plain
+            ><i class="el-icon-plus" />点击添加商品</el-button
+          >
+        </section>
+      </div>
+
+      <div style="height: 10px" />
+
+      <!-- 商品样式 -->
+      <el-form-item label="商品样式" class="lef" />
+      <!-- 商品样式选择 -->
+      <div class="moditystyle">
+        <span
+          v-for="(item, index) in moditystyles"
+          :key="index"
+          :class="item.type == datas.moditystyle ? 'active' : ''"
+          @click="datas.moditystyle = index"
+        >
+          {{ item.text }}
+        </span>
+      </div>
+
+      <div class="bor" />
+
+      <!-- 显示位置 -->
+      <el-form-item label="显示位置" class="lef">
+        <div class="weiz">
+          <i
+            :class="datas.positions === 'left' ? 'active' : ''"
+            class="iconfont icon-horizontal-left"
+            @click="datas.positions = 'left'"
+          />
+          <i
+            :class="datas.positions === 'center' ? 'active' : ''"
+            class="iconfont icon-juzhong"
+            @click="datas.positions = 'center'"
+          />
+        </div>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 文本粗细 -->
+      <el-form-item
+        class="lef"
+        label="文本粗细"
+        prop="textWeight"
+        :hide-required-asterisk="true"
+      >
+        <el-input
+          type="number"
+          v-model.number="datas.textWeight"
+          placeholder="请输入文本粗细"
+        />
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 图片倒角 -->
+      <el-form-item label="图片倒角" class="lef borrediu">
+        <el-slider
+          v-model="datas.borderRadius"
+          :max="30"
+          input-size="mini"
+          show-input
+        >
+        </el-slider>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 页面边距 -->
+      <el-form-item class="lef" label="页面边距">
+        <el-slider
+          v-model="datas.pageMargin"
+          :max="20"
+          input-size="mini"
+          show-input
+        >
+        </el-slider>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 商品间距 -->
+      <el-form-item class="lef" label="商品间距">
+        <el-slider
+          v-model="datas.commodityMargin"
+          :max="20"
+          input-size="mini"
+          show-input
+        >
+        </el-slider>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <el-form-item class="lef" label="背景图片">
+        <div class="shop-head-pic" style="text-align: center">
+          <img class="home-bg" :src="datas.bgImg" alt="" v-if="datas.bgImg" />
+          <div class="shop-head-pic-btn" style="text-align: center">
+            <el-button
+              @click="showUpload('0')"
+              class="uploadImg"
+              type="primary"
+              plain
+              ><i class="el-icon-plus" />更换图片</el-button
+            >
+            <el-button type="primary" class="uploadImg" @click="clear()">清空图片</el-button>
+          </div>
+        </div>
+      </el-form-item>
+      <div style="height: 10px" />
+      <!--商品价格 -->
+      <el-form-item class="lef" label="商品价格">
+        {{ datas.priceofcommodity ? '显示' : '隐藏' }}
+        <el-checkbox
+          style="margin-left: 196px"
+          v-model="datas.priceofcommodity"
+        />
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!--购买按钮 -->
+      <el-form-item class="lef" label="购买按钮">
+        {{ datas.purchasebutton ? '显示' : '隐藏' }}
+        <el-checkbox
+          style="margin-left: 196px"
+          v-model="datas.purchasebutton"
+        />
+      </el-form-item>
+
+      <el-radio-group
+        v-model="datas.purchasebuttonType"
+        class="radi1"
+        v-show="datas.purchasebutton"
+      >
+        <el-radio :label="index - 1" v-for="index in 8" :key="index"
+          >样式{{ index }}</el-radio
+        >
+
+        <el-input
+          v-show="datas.purchasebuttonType > 3"
+          style="width: 40%; margin-top: 10px"
+          v-model="datas.purchase"
+          size="mini"
+        />
+      </el-radio-group>
+
+      <div style="height: 10px" />
+
+      <!--商品角标 -->
+      <el-form-item class="lef" label="商品角标">
+        {{ datas.commoditycorner ? '显示' : '隐藏' }}
+        <el-checkbox
+          style="margin-left: 196px"
+          v-model="datas.commoditycorner"
+        />
+      </el-form-item>
+
+      <el-radio-group
+        v-model="datas.commoditycornertype"
+        class="radi1"
+        v-show="datas.commoditycorner"
+      >
+        <el-radio :label="index" v-for="(item, index) in marker" :key="index">{{
+          item
+        }}</el-radio>
+      </el-radio-group>
+
+      <el-form-item class="lef" label="颜色">
+        <el-color-picker
+          v-model="datas.commodityTagColor"
+          show-alpha
+          class="picke"
+          :predefine="predefineColors"
+        >
+        </el-color-picker>
+      </el-form-item>
+
+      <el-form-item class="lef" label="位置">
+        <el-radio-group v-model="datas.tagPosition" class="radi1">
+          <el-radio
+            :label="index"
+            v-for="(item, index) in tagPosition"
+            :key="index"
+            >{{ item }}</el-radio
+          >
+        </el-radio-group>
+      </el-form-item>
+    </el-form>
+
+    <!-- 上传商品 -->
+    <uploadCommodity
+      ref="upload"
+      @uploadListInformation="uploadListInformation"
+    />
+    <!-- 上传图片 -->
+    <uploadimg ref="uploadImg" @uploadInformation="uploadInformation" />
+  </div>
+</template>
+
+<script>
+import uploadCommodity from '../../uploadCommodity' //图片上传
+import uploadimg from '../../uploadImg' //图片上传
+import vuedraggable from 'vuedraggable' //拖拽组件
+
+export default {
+  name: 'listswitchingstyle',
+  props: {
+    datas: Object,
+  },
+  components: { vuedraggable, uploadCommodity, uploadimg },
+  data() {
+    let kon = (rule, value, callback) => {
+      if (value.length === 0) callback(new Error('请输入有效数字'))
+    }
+    return {
+      color1: '#07c160',
+      moditystyles: [
+        /* 商品样式 */
+        {
+          text: '无边白底',
+          type: 0,
+        },
+        {
+          text: '卡片投影',
+          type: 1,
+        },
+        {
+          text: '描边白底',
+          type: 2,
+        },
+        {
+          text: '无边透明底',
+          type: 3,
+        },
+      ],
+      commodityTypes: [
+        {
+          icon: 'icon-datumoshi',
+          type: 0,
+          content: '大图模式',
+        },
+        {
+          icon: 'icon-commodity-yihangliangge',
+          type: 1,
+          content: '一行两个',
+        },
+        {
+          icon: 'icon-yihangsange',
+          type: 2,
+          content: '一行三个',
+        },
+        {
+          icon: 'icon-commodity-xiangxiliebiao',
+          type: 3,
+          content: '详细列表',
+        },
+        {
+          icon: 'icon-icon_shangpintu_yidaliangxiao',
+          type: 4,
+          content: '一大两小',
+        },
+        {
+          icon: 'icon-xuanzemokuai-daohanghengxianghuadong',
+          type: 5,
+          content: '横向滑动',
+        },
+      ],
+      rules: {
+        textWeight: [{ required: true, validator: kon, trigger: 'blur' }],
+      },
+      marker: ['新品', '热卖', 'NEW', 'HOT'],
+      dragOptions: {
+        animation: 200,
+      },
+      imgText: null, //当前选中的类型
+      imgNumber: null, //第几个数组
+      predefineColors: [
+        // 颜色选择器预设
+        '#ff4500',
+        '#ff8c00',
+        '#ffd700',
+        '#90ee90',
+        '#00ced1',
+        '#1e90ff',
+        '#c71585',
+        '#409EFF',
+        '#909399',
+        '#C0C4CC',
+        'rgba(255, 69, 0, 0.68)',
+        'rgb(255, 120, 0)',
+        'hsv(51, 100, 98)',
+        'hsva(120, 40, 94, 0.5)',
+        'hsl(181, 100%, 37%)',
+        'hsla(209, 100%, 56%, 0.73)',
+        '#c7158577',
+      ],
+      options: [], // 更多跳转链接
+      moreName: null,
+      tagPosition: [
+        // 标记位置
+        '左上',
+        '左下',
+        '右上',
+        '右下',
+      ],
+      uploadImgDataType: null,
+    }
+  },
+  created() {
+  },
+  methods: {
+    /* 上传图片弹框 */
+    dialogVisibleshow(text, number) {
+      this.$refs.upload.showUpload()
+      this.imgText = text
+      this.number = number
+    },
+    /* 添加分组 */
+    addGrouping() {
+      this.datas.commoditylisttypetab.push({
+        text: '分组',
+        imageList: [],
+      })
+    },
+    // 提交
+    uploadListInformation(res) {
+      if (this.imgText === 'imageList') {
+        this.datas.imageList.push(res)
+      } else {
+        this.datas.commoditylisttypetab[this.number].imageList.push(res)
+      }
+
+      this.imgText = null
+      this.number = null
+    },
+
+    showUpload(type) {
+      this.uploadImgDataType = type
+      this.$refs.uploadImg.showUpload()
+    },
+
+    // 背景图
+    uploadInformation(res) {
+      console.log(res, '---------uploadImg')
+      if (this.uploadImgDataType === '0') {
+        this.datas.bgImg = res
+        console.log(this.datas.bgImg, '---------uploadImg')
+      }
+    },
+
+    // 清空背景图片
+    clear() {
+      this.datas.bgImg = ''
+    },
+
+    /* 删除图片 */
+    deleteimg(index) {
+      this.datas.imageList.splice(index, 1)
+    },
+
+    /* 删除分组里的图片 */
+    delecommodityimg(ind, index) {
+      this.datas.commoditylisttypetab[ind].imageList.splice(index, 1)
+    },
+
+    /* 删除分组 */
+    delecommoditylisttypetab(index) {
+      this.datas.commoditylisttypetab.splice(index, 1)
+    },
+  },
+  computed: {
+    styleText() {
+      let modeType
+      if (this.datas.commodityType === 0)  modeType = '大图模式'
+      if (this.datas.commodityType === 1)  modeType = '一行两个'
+      if (this.datas.commodityType === 2)  modeType = '一行三个'
+      if (this.datas.commodityType === 3)  modeType = '详细列表'
+      if (this.datas.commodityType === 4)  modeType = '一大两小'
+      if (this.datas.commodityType === 5)  modeType = '横向滑动'
+
+      return modeType
+    },
+  },
+}
+</script>
+
+<style scoped lang="less">
+.listswitchingstyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+
+  .lef {
+    /deep/.el-form-item__label {
+      text-align: left;
+    }
+  }
+
+  .shop-head-pic {
+    color: #ababab;
+    display: flex;
+    flex-direction: column;
+    .home-bg {
+      width: 100px;
+      height: 100px;
+      margin: 10px auto;
+    }
+    .shop-head-pic-btn {
+      display: flex;
+      flex-direction: row;
+      .el-button {
+        flex: 1;
+      }
+    }
+  }
+  /* 列表样式 */
+  .commodityType {
+    display: flex;
+    justify-content: space-around;
+    align-items: center;
+    span {
+      display: inline-block;
+      width: 58px;
+      height: 32px;
+      text-align: center;
+      line-height: 32px;
+      background: #fff;
+      border: 1px solid #ebedf0;
+      color: #979797;
+      margin: 0 1px;
+      cursor: pointer;
+      transition: all 0.5s;
+
+      &:hover {
+        border: 1px solid #155bd4;
+        color: #155bd4;
+      }
+
+      &.active {
+        border: 1px solid #155bd4;
+        background-color: #e0edff;
+        color: #155bd4;
+      }
+    }
+  }
+
+  /* 商品样式 */
+  .moditystyle {
+    font-size: 12px;
+    width: 100%;
+    display: flex;
+    span {
+      width: 86px;
+      height: 32px;
+      display: inline-block;
+      text-align: center;
+      line-height: 32px;
+      cursor: pointer;
+      border: 1px solid #ebedf0;
+      &.active {
+        border: 1px solid #155bd4;
+        background-color: #e0edff;
+        color: #155bd4;
+      }
+    }
+  }
+
+  /* 位置 */
+  .weiz {
+    text-align: right;
+    i {
+      padding: 5px 14px;
+      margin-left: 10px;
+      border-radius: 0;
+      border: 1px solid #ebedf0;
+      font-size: 20px;
+      font-weight: 500;
+      cursor: pointer;
+
+      &:last-child {
+        font-size: 22px;
+      }
+
+      &.active {
+        color: #155bd4;
+        border: 1px solid #155bd4;
+        background: #e0edff;
+      }
+    }
+  }
+
+  /* 单选框 */
+  /deep/.radi1 {
+    border-top: 1px solid #f7f8fa;
+    border-bottom: 1px solid #f7f8fa;
+    padding: 12px 0;
+    .el-radio {
+      margin: 10px 25px 7px 0;
+    }
+  }
+
+  /* 商品列表 */
+  .imgBanner {
+    padding: 6px 12px;
+    margin: 16px 7px;
+    border-radius: 2px;
+    background-color: #fff;
+    box-shadow: 0 0 4px 0 rgba(10, 42, 97, 0.2);
+    display: flex;
+    position: relative;
+
+    /* 删除图标 */
+    .el-icon-circle-close {
+      position: absolute;
+      right: -10px;
+      top: -10px;
+      cursor: pointer;
+      font-size: 19px;
+    }
+
+    /* 图片 */
+    .imag {
+      width: 60px;
+      height: 60px;
+      border-radius: 5px;
+      overflow: hidden;
+      position: relative;
+      cursor: pointer;
+      img {
+        width: 100%;
+        height: 100%;
+        display: inline-block;
+      }
+      span {
+        background: rgba(0, 0, 0, 0.5);
+        font-size: 12px;
+        position: absolute;
+        left: 0px;
+        bottom: 0px;
+        display: inline-block;
+        width: 100%;
+        text-align: center;
+        color: #fff;
+        height: 20px;
+        line-height: 20px;
+      }
+    }
+
+    /* 图片字 */
+    .imgText {
+      width: 80%;
+      display: flex;
+      flex-direction: column;
+      box-sizing: border-box;
+      padding-left: 20px;
+      justify-content: space-between;
+    }
+  }
+
+  /* 上传图片按钮 */
+  .uploadImg {
+    width: 345px;
+    height: 40px;
+    margin-top: 20px;
+  }
+
+  // 上传弹框内容部分
+  /deep/.uploadIMG .el-dialog__body {
+    height: 280px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    position: relative;
+    justify-content: center;
+  }
+
+  .disable {
+    /deep/.el-upload {
+      display: none !important;
+    }
+  }
+
+  .tit {
+    margin-bottom: 20px;
+    /deep/.el-input__inner {
+      text-align: center;
+    }
+  }
+}
+</style>

+ 627 - 0
src/asEditorComponents/rightslider/magiccubestyle/index.vue

@@ -0,0 +1,627 @@
+<template>
+  <div class="magiccubestyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+
+    <p style="color: #d40000; font-size: 14px">魔方布局</p>
+    <p style="color: #969799; font-size: 12px; margin: 5px 0">
+      选定布局区域,在下方添加图片
+    </p>
+
+    <!-- 图片布局 -->
+    <!-- 一行二个 -->
+    <section class="buju buju0" v-show="datas.rubiksCubeType === 0">
+      <div
+        @click="imgActive = index - 1"
+        v-for="index in 2"
+        :key="index"
+        class="rubiksCubeType0 rubiksCubeType"
+        :class="[index - 1 === imgActive ? 'active' : '']"
+      >
+        <div style="font-size: 12px" v-if="!datas.imageList[index - 1].src">
+          宽度375像素
+        </div>
+        <img
+          draggable="false"
+          v-else
+          :src="datas.imageList[index - 1].src"
+          alt=""
+        />
+      </div>
+    </section>
+
+    <!-- 一行三个 -->
+    <section class="buju buju0" v-show="datas.rubiksCubeType === 1">
+      <div
+        @click="imgActive = index - 1"
+        v-for="index in 3"
+        :key="index"
+        class="rubiksCubeType1 rubiksCubeType"
+        :class="[index - 1 === imgActive ? 'active' : '']"
+      >
+        <div style="font-size: 12px" v-if="!datas.imageList[index - 1].src">
+          宽度250像素
+        </div>
+        <img
+          draggable="false"
+          v-else
+          :src="datas.imageList[index - 1].src"
+          alt=""
+        />
+      </div>
+    </section>
+
+    <!-- 一行四个 -->
+    <section class="buju buju0" v-show="datas.rubiksCubeType === 2">
+      <div
+        @click="imgActive = index - 1"
+        v-for="index in 4"
+        :key="index"
+        class="rubiksCubeType2 rubiksCubeType"
+        :class="[index - 1 === imgActive ? 'active' : '']"
+      >
+        <div style="font-size: 12px" v-if="!datas.imageList[index - 1].src">
+          宽度188像素
+        </div>
+        <img
+          draggable="false"
+          v-else
+          :src="datas.imageList[index - 1].src"
+          alt=""
+        />
+      </div>
+    </section>
+
+    <!-- 二左二右 -->
+    <section class="buju buju0" v-show="datas.rubiksCubeType === 3">
+      <div
+        @click="imgActive = index - 1"
+        v-for="index in 4"
+        :key="index"
+        class="rubiksCubeType3 rubiksCubeType"
+        :class="[index - 1 === imgActive ? 'active' : '']"
+      >
+        <div style="font-size: 12px" v-if="!datas.imageList[index - 1].src">
+          375x375像素<br />或同等比例
+        </div>
+        <img
+          draggable="false"
+          v-else
+          :src="datas.imageList[index - 1].src"
+          alt=""
+        />
+      </div>
+    </section>
+
+    <!-- 一左二右 -->
+    <section class="buju buju4" v-show="datas.rubiksCubeType === 4">
+      <div
+        @click="imgActive = 0"
+        class="rubiksCubeType4 rubiksCubeType"
+        style="width: 163px; height: 300px"
+        :class="[0 === imgActive ? 'active' : '']"
+      >
+        <div style="font-size: 12px" v-if="!datas.imageList[0].src">
+          375x750像素<br />或同等比例
+        </div>
+        <img draggable="false" v-else :src="datas.imageList[0].src" alt="" />
+        <div></div>
+      </div>
+      <div style="display: inline-flex; flex-direction: column">
+        <div
+          @click="imgActive = index"
+          class="rubiksCubeType4 rubiksCubeType"
+          :class="[index === imgActive ? 'active' : '']"
+          v-for="index in 2"
+          :key="index"
+        >
+          <div style="font-size: 12px" v-if="!datas.imageList[index].src">
+            375x375像素<br />或同等比例
+          </div>
+          <img
+            draggable="false"
+            v-else
+            :src="datas.imageList[index].src"
+            alt=""
+          />
+          <div></div>
+        </div>
+      </div>
+    </section>
+
+    <!-- 一上二下 -->
+    <section class="buju buju5" v-show="datas.rubiksCubeType === 5">
+      <div
+        @click="imgActive = 0"
+        class="rubiksCubeType4 rubiksCubeType"
+        style="width: 325px; height: 163px"
+        :class="[0 === imgActive ? 'active' : '']"
+      >
+        <div style="font-size: 12px" v-if="!datas.imageList[0].src">
+          375x750像素<br />或同等比例
+        </div>
+        <img draggable="false" v-else :src="datas.imageList[0].src" alt="" />
+        <div></div>
+      </div>
+      <div style="display: inline-flex">
+        <div
+          @click="imgActive = index"
+          class="rubiksCubeType4 rubiksCubeType"
+          :class="[index === imgActive ? 'active' : '']"
+          v-for="index in 2"
+          :key="index"
+        >
+          <div style="font-size: 12px" v-if="!datas.imageList[index].src">
+            375x375像素<br />或同等比例
+          </div>
+          <img
+            draggable="false"
+            v-else
+            :src="datas.imageList[index].src"
+            alt=""
+            style="width: 163px; height: 163px"
+          />
+          <div></div>
+        </div>
+      </div>
+    </section>
+
+    <!-- 一左三右 -->
+    <section class="buju buju4" v-show="datas.rubiksCubeType === 6">
+      <!-- 第一张图片 -->
+      <div
+        @click="imgActive = 0"
+        class="rubiksCubeType4 rubiksCubeType"
+        style="width: 163px; height: 325px"
+        :class="[0 === imgActive ? 'active' : '']"
+      >
+        <div style="font-size: 12px" v-if="!datas.imageList[0].src">
+          375x750像素<br />或同等比例
+        </div>
+        <img draggable="false" v-else :src="datas.imageList[0].src" alt="" />
+      </div>
+      <div style="display: inline-flex; flex-direction: column">
+        <!-- 第二张图片 -->
+        <div
+          @click="imgActive = 1"
+          class="rubiksCubeType4 rubiksCubeType"
+          :class="[1 === imgActive ? 'active' : '']"
+        >
+          <div style="font-size: 12px" v-if="!datas.imageList[1].src">
+            375x375像素<br />或同等比例
+          </div>
+          <img draggable="false" v-else :src="datas.imageList[1].src" alt="" />
+          <div></div>
+        </div>
+        <div class="rubiksCubeType4 rubiksCubeType">
+          <div
+            @click="imgActive = index + 1"
+            :class="[index + 1 === imgActive ? 'active' : '']"
+            style="
+              display: inline-flex;
+              width: 82px;
+              height: 163px;
+              justify-content: center;
+              align-items: center;
+              border: 1px solid #ebedf0;
+            "
+            v-for="index in 2"
+            :key="index"
+          >
+            <div style="font-size: 12px" v-if="!datas.imageList[index + 1].src">
+              188x375像素<br />或同等比例
+            </div>
+            <img
+              draggable="false"
+              v-else
+              :src="datas.imageList[index + 1].src"
+              alt=""
+            />
+          </div>
+        </div>
+      </div>
+    </section>
+
+    <p style="color: #d40000; font-size: 12px; margin-top: 10px">请添加图片</p>
+
+    <!-- 表单 -->
+    <el-form label-width="80px" :model="datas" size="small">
+      <section
+        class="magiccubestyleList"
+        v-for="(item, index) in datas.imageList"
+        :key="index"
+        v-show="imgActive === index"
+      >
+        <!-- 图片 -->
+        <div class="imag" @click="$refs.upload.showUpload()">
+          <img
+            draggable="false"
+            v-if="!item.src"
+            src="../../../assets/images/add.png"
+            style="border: 1px solid #e5e5e5"
+            alt=""
+          />
+          <div v-else style="position: relative">
+            <img draggable="false" :src="item.src" alt="" />
+            <p>
+              点击更换图
+            </p>
+          </div>
+        </div>
+        <!-- 标题和链接 -->
+        <div class="imgText">
+          <!-- 选择类型 -->
+          <el-select
+            v-model="item.linktype"
+            placeholder="请选择跳转类型"
+            size="mini"
+          >
+            <el-option
+              v-for="item in optionsType"
+              :key="item.name"
+              :label="item.name"
+              :value="item.type"
+            >
+            </el-option>
+          </el-select>
+
+          <!-- 输入链接 -->
+          <el-input
+            size="mini"
+            placeholder="请输入链接,输入前确保可以访问"
+            v-model="item.http.externalLink"
+          >
+          </el-input>
+        </div>
+      </section>
+
+      <div style="height: 20px" />
+
+      <!-- 标题内容 -->
+      <el-form-item label="选择模板" class="lef">
+        <p style="color: #000">{{ styleText }}</p>
+      </el-form-item>
+
+      <!-- 商品样式选择 -->
+      <div class="rubiksCubeType">
+        <el-tooltip
+          class="item"
+          effect="dark"
+          :content="item.content"
+          placement="bottom"
+          v-for="(item, index) in rubiksCubeTypes"
+          :key="index"
+        >
+          <span
+            class="iconfont"
+            style="font-size: 21px"
+            :class="[
+              item.linktype === datas.rubiksCubeType ? 'active' : '',
+              item.icon,
+            ]"
+            @click="datas.rubiksCubeType = index"
+          />
+        </el-tooltip>
+      </div>
+
+      <div style="height: 20px" />
+
+      <!-- 页面边距 -->
+      <el-form-item label="页面边距" class="lef">
+        <el-slider
+          v-model="datas.pageMargin"
+          :max="20"
+          input-size="mini"
+          show-input
+        >
+        </el-slider>
+      </el-form-item>
+
+      <!-- 图片间隙 -->
+      <el-form-item label="图片间隙" class="lef">
+        <el-slider
+          v-model="datas.imgMargin"
+          :max="20"
+          input-size="mini"
+          show-input
+        >
+        </el-slider>
+      </el-form-item>
+    </el-form>
+
+    <!-- 上传图片 -->
+    <uploadimg ref="upload" @uploadInformation="uploadInformation" />
+  </div>
+</template>
+
+<script>
+import uploadimg from '../../uploadImg' //图片上传
+
+export default {
+  name: 'magiccubestyle',
+  props: {
+    datas: Object,
+  },
+  components: { uploadimg },
+  data() {
+    return {
+      rubiksCubeTypes: [
+        {
+          icon: 'icon-yihangerge',
+          type: 0,
+          content: '一行二个',
+        },
+        {
+          icon: 'icon-yihangsange',
+          type: 1,
+          content: '一行三个',
+        },
+        {
+          icon: 'icon-yihangsige',
+          type: 2,
+          content: '一行四个',
+        },
+        {
+          icon: 'icon-erzuoeryou',
+          type: 3,
+          content: '二左二右',
+        },
+        {
+          icon: 'icon-yizuoeryou',
+          type: 4,
+          content: '一左二右',
+        },
+        {
+          icon: 'icon-yishangerxia',
+          type: 5,
+          content: '一上二下',
+        },
+        {
+          icon: 'icon-yizuosanyou',
+          type: 6,
+          content: '一左三右',
+        },
+      ],
+      imgActive: 0, //默认选中第一个图片
+      optionsType: [
+        {
+          type: '10',
+          name: '内部链接',
+        },
+        {
+          type: '11',
+          name: '外部链接',
+        },
+      ], //跳转类型
+      emptyText: '',
+    }
+  },
+  computed: {
+    // eslint-disable-next-line vue/return-in-computed-property
+    styleText() {
+      // eslint-disable-next-line vue/no-side-effects-in-computed-properties
+      this.imgActive = 0
+      if (this.datas.rubiksCubeType === 0) return '一行二个'
+      if (this.datas.rubiksCubeType === 1) return '一行三个'
+      if (this.datas.rubiksCubeType === 2) return '一行四个'
+      if (this.datas.rubiksCubeType === 3) return '二左二右'
+      if (this.datas.rubiksCubeType === 4) return '一左二右'
+      if (this.datas.rubiksCubeType === 5) return '一上二下'
+      if (this.datas.rubiksCubeType === 6) return '一左三右'
+    },
+  },
+  created() {},
+  methods: {
+    /* 替换 */
+    uploadInformation(res) {
+      this.datas.imageList[this.imgActive].src = res
+    },
+  },
+}
+</script>
+
+<style scoped lang="less">
+.magiccubestyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  overflow: hidden;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+
+  /* 布局 */
+  .buju {
+    &.buju0 {
+      display: flex;
+      justify-content: space-around;
+      flex-wrap: wrap;
+    }
+    &.buju4 {
+      display: inline-flex;
+      flex-direction: row;
+      justify-content: space-around;
+    }
+    .active {
+      background: #e0edff;
+      border: 1px solid #155bd4;
+      color: #155bd4;
+      z-index: 2;
+    }
+    .rubiksCubeType {
+      background-color: #fff;
+      border: 1px solid #ebedf0;
+      display: inline-flex;
+      justify-content: center;
+      align-items: center;
+      color: #7d7e80;
+      cursor: pointer;
+      &.active {
+        background: #e0edff;
+        border: 1px solid #155bd4;
+        color: #155bd4;
+        z-index: 2;
+      }
+      &.rubiksCubeType0 {
+        width: 163px;
+        margin: 10px 0;
+        // height: 200px;
+        img {
+          width: 100%;
+          // height: 200px;
+        }
+      }
+      &.rubiksCubeType1 {
+        width: 109px;
+        margin: 10px 0;
+        height: 150px;
+        img {
+          width: 100%;
+          height: 150px;
+        }
+      }
+      &.rubiksCubeType2 {
+        width: 82px;
+        margin: 10px 0;
+        height: 150px;
+        img {
+          width: 100%;
+          height: 150px;
+        }
+      }
+      &.rubiksCubeType3 {
+        width: 163px;
+        margin: 10px 0;
+        height: 163px;
+        img {
+          width: 100%;
+          height: 100%;
+        }
+      }
+      &.rubiksCubeType4 {
+        width: 163px;
+        height: 163px;
+        img {
+          width: 100%;
+          height: 100%;
+        }
+      }
+    }
+  }
+
+  .lef {
+    /deep/.el-form-item__label {
+      text-align: left;
+    }
+  }
+
+  /* 商品列表 */
+  .magiccubestyleList {
+    padding: 6px 12px;
+    margin: 16px 0px;
+    border-radius: 2px;
+    background-color: #fff;
+    box-shadow: 0 0 4px 0 rgba(10, 42, 97, 0.2);
+    display: flex;
+    position: relative;
+
+    /* 删除图标 */
+    .el-icon-circle-close {
+      position: absolute;
+      right: -10px;
+      top: -10px;
+      cursor: pointer;
+      font-size: 19px;
+    }
+
+    /* 图片 */
+    .imag {
+      width: 60px;
+      height: 60px;
+      border-radius: 5px;
+      overflow: hidden;
+      position: relative;
+      cursor: pointer;
+      img {
+        width: 100%;
+        height: 60px;
+        display: inline-block;
+      }
+      span {
+        background: rgba(0, 0, 0, 0.5);
+        font-size: 12px;
+        position: absolute;
+        left: 0px;
+        bottom: 0px;
+        display: inline-block;
+        width: 100%;
+        text-align: center;
+        color: #fff;
+        height: 20px;
+        line-height: 20px;
+      }
+      p {
+        width: 100%;
+        background: #999;
+        position: absolute;
+        left: 0;
+        bottom: 5px;
+        color: #fff;
+        font-size: 5px;
+        text-align: center;
+        height: 20px;
+      }
+    }
+
+    /* 图片字 */
+    .imgText {
+      width: 80%;
+      display: flex;
+      flex-direction: column;
+      box-sizing: border-box;
+      padding-left: 20px;
+      justify-content: space-between;
+    }
+  }
+
+  /* 列表样式 */
+  .rubiksCubeType {
+    display: flex;
+    justify-content: space-around;
+    align-items: center;
+    span {
+      display: inline-block;
+      width: 58px;
+      height: 32px;
+      text-align: center;
+      line-height: 32px;
+      background: #fff;
+      border: 1px solid #ebedf0;
+      color: #979797;
+      margin: 0 1px;
+      cursor: pointer;
+      transition: all 0.5s;
+
+      &:hover {
+        border: 1px solid #155bd4;
+        color: #155bd4;
+      }
+
+      &.active {
+        border: 1px solid #155bd4;
+        background-color: #e0edff;
+        color: #155bd4;
+      }
+    }
+  }
+}
+</style>

+ 122 - 0
src/asEditorComponents/rightslider/noticestyle/index.vue

@@ -0,0 +1,122 @@
+<template>
+  <div class="noticestyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+
+    <!-- 公告 -->
+    <el-form
+      label-width="90px"
+      :model="datas"
+      :rules="rules"
+      size="small"
+      class="lef"
+    >
+      <el-form-item
+        label="公告"
+        :hide-required-asterisk="true"
+        prop="noticeText"
+      >
+        <el-input v-model="datas.noticeText" placeholder="请输入公告" />
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 背景颜色 -->
+      <el-form-item label="背景颜色" class="lef">
+        <!-- 颜色选择器 -->
+        <el-color-picker
+          v-model="datas.backColor"
+          show-alpha
+          class="picke"
+          :predefine="predefineColors"
+        >
+        </el-color-picker>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 文字颜色 -->
+      <el-form-item label="文字颜色" class="lef">
+        <!-- 颜色选择器 -->
+        <el-color-picker
+          v-model="datas.textColor"
+          show-alpha
+          class="picke"
+          :predefine="predefineColors"
+        >
+        </el-color-picker>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'noticestyle',
+  props: {
+    datas: Object,
+  },
+  data() {
+    return {
+      rules: {
+        //校验表单输入
+        noticeText: [
+          //页面名称
+          { required: true, message: '请输入公告', trigger: 'blur' },
+        ],
+      },
+      predefineColors: [
+        // 颜色选择器预设
+        '#ff4500',
+        '#ff8c00',
+        '#ffd700',
+        '#90ee90',
+        '#00ced1',
+        '#1e90ff',
+        '#c71585',
+        '#409EFF',
+        '#909399',
+        '#C0C4CC',
+        'rgba(255, 69, 0, 0.68)',
+        'rgb(255, 120, 0)',
+        'hsv(51, 100, 98)',
+        'hsva(120, 40, 94, 0.5)',
+        'hsl(181, 100%, 37%)',
+        'hsla(209, 100%, 56%, 0.73)',
+        '#c7158577',
+      ],
+    }
+  },
+}
+</script>
+
+<style scoped lang="less">
+.noticestyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+
+  .lef {
+    /deep/.el-form-item__label {
+      text-align: left;
+    }
+  }
+
+  /* 颜色选择器 */
+  .picke {
+    float: right;
+  }
+}
+</style>

+ 35 - 0
src/asEditorComponents/rightslider/onlineservicestyle/index.vue

@@ -0,0 +1,35 @@
+<template>
+  <div class="onlineservicestyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'onlineservicestyle',
+  props: {
+    datas: Object,
+  },
+}
+</script>
+
+<style scoped lang="less">
+.onlineservicestyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+}
+</style>

+ 35 - 0
src/asEditorComponents/rightslider/personalizedrecommendationstyle/index.vue

@@ -0,0 +1,35 @@
+<template>
+  <div class="personalizedrecommendationstyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'personalizedrecommendationstyle',
+  props: {
+    datas: Object,
+  },
+}
+</script>
+
+<style scoped lang="less">
+.personalizedrecommendationstyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+}
+</style>

+ 471 - 0
src/asEditorComponents/rightslider/pictureadsstyle/index.vue

@@ -0,0 +1,471 @@
+<template>
+  <div class="pictureadsstyle">
+    <!-- 标题 -->
+    <h2>图片广告</h2>
+
+    <!-- 表单 -->
+    <el-form label-width="80px" :model="datas" size="small">
+      <!-- 标题内容 -->
+      <el-form-item label="选择模板" class="lef">
+        <p style="color: #000">{{ styleText }}</p>
+      </el-form-item>
+
+      <!-- 轮播图选择 -->
+      <div class="swiperType">
+        <el-tooltip
+          class="item"
+          effect="dark"
+          content="一行一个"
+          placement="bottom"
+        >
+          <span
+            class="iconfont icon-yihangyige"
+            style="font-size: 21px"
+            :class="datas.swiperType === 0 ? 'active' : ''"
+            @click="datas.swiperType = 0"
+          />
+        </el-tooltip>
+
+        <el-tooltip
+          class="item"
+          effect="dark"
+          content="轮播海报"
+          placement="bottom"
+        >
+          <span
+            class="iconfont icon-icon_tupian_lunbohaibao"
+            style="font-size: 20px"
+            :class="datas.swiperType === 1 ? 'active' : ''"
+            @click="datas.swiperType = 1"
+          />
+        </el-tooltip>
+
+        <el-tooltip
+          class="item"
+          effect="dark"
+          content="多图单行"
+          placement="bottom"
+        >
+          <span
+            class="iconfont icon-daohanghengxianghuadong"
+            style="font-size: 24px"
+            :class="datas.swiperType === 2 ? 'active' : ''"
+            @click="datas.swiperType = 2"
+          />
+        </el-tooltip>
+
+        <el-tooltip
+          class="item"
+          effect="dark"
+          content="立体轮播"
+          placement="bottom"
+        >
+          <span
+            class="iconfont icon-xiaotuhengxianghuadong"
+            style="font-size: 24px"
+            :class="datas.swiperType === 3 ? 'active' : ''"
+            @click="datas.swiperType = 3"
+          />
+        </el-tooltip>
+      </div>
+
+      <!-- 下划线 -->
+      <div class="bor" />
+
+      <h5 style="color: #000; font-size: 14px">添加图片</h5>
+      <p style="color: #969799; font-size: 12px; margin-top: 10px">
+        拖动选中的导航可对其排序
+      </p>
+
+      <!-- 图片广告 -->
+      <div v-if="datas.imageList[0]">
+        <vuedraggable v-model="datas.imageList" v-bind="dragOptions">
+          <transition-group>
+            <section
+              class="imgBanner"
+              v-for="(item, index) in datas.imageList"
+              :key="item + index"
+            >
+              <i class="el-icon-circle-close" @click="deleteimg(index)" />
+              <!-- 图片 -->
+              <div class="imag">
+                <img :src="item.src" alt draggable="false" />
+              </div>
+              <!-- 标题和链接 -->
+              <div class="imgText">
+                <el-input
+                  v-model="item.text"
+                  placeholder="请输入标题,也可不填"
+                  size="mini"
+                ></el-input>
+
+                <!-- 选择类型 -->
+                <div class="select-type">
+                  <el-select
+                    style="width: 60%"
+                    v-model="item.linktype"
+                    placeholder="请选择跳转类型"
+                    size="mini"
+                  >
+                    <el-option
+                      v-for="item in optionsType"
+                      :key="item.name"
+                      :label="item.name"
+                      :value="item.type"
+                    ></el-option>
+                  </el-select>
+
+                  <!-- 输入链接 -->
+                  <el-input
+                    style="width: 100%"
+                    size="mini"
+                    placeholder="请输入链接,输入前确保可以访问"
+                    v-model="item.http.externalLink"
+                  ></el-input>
+                </div>
+              </div>
+            </section>
+          </transition-group>
+        </vuedraggable>
+      </div>
+      <!-- 上传图片 -->
+      <el-button
+        @click="$refs.upload.showUpload()"
+        class="uploadImg"
+        type="primary"
+        plain
+      >
+        <i class="el-icon-plus" />点击添加图片
+      </el-button>
+
+      <!-- 下划线 -->
+      <div class="bor"></div>
+
+      <el-form-item
+        class="lef"
+        label="一行个数"
+        v-show="datas.swiperType === 2"
+      >
+        <!-- 单选框 -->
+        <el-radio-group v-model="datas.rowindividual" class="radi">
+          <el-radio :label="2">2个</el-radio>
+          <el-radio :label="3">3个</el-radio>
+          <el-radio :label="4">4个</el-radio>
+          <el-radio :label="5">5个</el-radio>
+          <el-radio :label="6">6个</el-radio>
+        </el-radio-group>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 图片倒角 -->
+      <el-form-item label="分页类型" class="lef borrediu">
+        <el-radio-group v-model="datas.pagingType" class="radi1">
+          <el-radio :label="0">不显示</el-radio>
+          <el-radio label="bullets">样式一</el-radio>
+          <el-radio label="fraction">样式二</el-radio>
+          <el-radio label="progressbar">样式三</el-radio>
+        </el-radio-group>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 图片倒角 -->
+      <el-form-item label="图片倒角" class="lef borrediu">
+        <el-slider
+          v-model="datas.borderRadius"
+          :max="30"
+          input-size="mini"
+          show-input
+        ></el-slider>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 页面边距 -->
+      <el-form-item
+        class="lef"
+        label="页面边距"
+        v-show="datas.swiperType === 0"
+      >
+        <el-slider
+          v-model="datas.pageMargin"
+          :max="20"
+          input-size="mini"
+          show-input
+        ></el-slider>
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 图片边距 -->
+      <el-form-item
+        class="lef"
+        label="图片边距"
+        v-show="datas.swiperType === 0 || datas.swiperType === 2"
+      >
+        <el-slider
+          v-model="datas.imageMargin"
+          :max="20"
+          input-size="mini"
+          show-input
+        ></el-slider>
+      </el-form-item>
+    </el-form>
+
+    <!-- 上传图片 -->
+    <uploadimg ref="upload" @uploadInformation="uploadInformation" />
+  </div>
+</template>
+
+<script>
+import vuedraggable from 'vuedraggable' //拖拽组件
+import uploadimg from '../../uploadImg' //图片上传
+
+export default {
+  name: 'pictureadsstyle',
+  components: { vuedraggable, uploadimg },
+  props: {
+    datas: Object,
+  },
+  data() {
+    return {
+      optionsType: [
+        {
+          type: '10',
+          name: '内部链接',
+        },
+        {
+          type: '11',
+          name: '外部链接',
+        },
+      ], // 选择跳转类型
+      dragOptions: {
+        animation: 200,
+      },
+      emptyText: '',
+    }
+  },
+
+  created() {
+  },
+
+  methods: {
+
+    // 提交
+    uploadInformation(res) {
+      this.datas.imageList.push({
+        src: res,
+        text: '',
+        http: {},
+      })
+    },
+
+    /* 删除图片 */
+    deleteimg(index) {
+      this.datas.imageList.splice(index, 1)
+    },
+  },
+
+  computed: {
+    styleText() {
+      let data
+      if (this.datas.swiperType === 0) data = '一行一个'
+      if (this.datas.swiperType === 1) data = '轮播海报'
+      if (this.datas.swiperType === 2) data = '多图单行'
+      if (this.datas.swiperType === 3) data = '立体模式'
+      if (this.datas.swiperType === 4) data = '导航横向滑动'
+
+      return data
+    },
+  },
+}
+</script>
+
+<style scoped lang="less">
+.pictureadsstyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px;
+  box-sizing: border-box;
+
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+
+  .lef {
+    /deep/.el-form-item__label {
+      text-align: left;
+    }
+  }
+
+  /* 轮播图样式 */
+  .swiperType {
+    display: flex;
+    justify-content: space-around;
+    align-items: center;
+    span {
+      display: inline-block;
+      width: 58px;
+      height: 32px;
+      text-align: center;
+      line-height: 32px;
+      background: #ebedf0;
+      color: #979797;
+      border: 1px solid #fff;
+      cursor: pointer;
+      transition: all 0.5s;
+
+      &:hover {
+        border: 1px solid #155bd4;
+        color: #155bd4;
+      }
+
+      &.active {
+        border: 1px solid #155bd4;
+        background-color: #e0edff;
+        color: #155bd4;
+      }
+    }
+  }
+
+  /* 圆角 */
+  .borrediu {
+    span {
+      display: inline-block;
+      width: 48px;
+      height: 26px;
+      text-align: center;
+      line-height: 26px;
+      background: #ebedf0;
+      color: #979797;
+      border: 1px solid #fff;
+      cursor: pointer;
+      transition: all 0.5s;
+
+      &:hover {
+        border: 1px solid #155bd4;
+        color: #155bd4;
+      }
+
+      &.active {
+        border: 1px solid #155bd4;
+        background-color: #e0edff;
+        color: #155bd4;
+      }
+    }
+  }
+
+  /deep/.radi .el-radio {
+    margin-right: 8px;
+  }
+
+  /deep/.radi1 .el-radio {
+    margin-right: 7px;
+    .el-radio__label {
+      padding-left: 5px;
+    }
+  }
+
+  /* 上传图片按钮 */
+  .uploadImg {
+    width: 345px;
+    height: 40px;
+    margin-top: 20px;
+  }
+
+  // 上传弹框内容部分
+  /deep/.uploadIMG .el-dialog__body {
+    height: 280px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    position: relative;
+    justify-content: center;
+  }
+
+  .disable {
+    /deep/.el-upload {
+      display: none !important;
+    }
+  }
+
+  /* 图片广告列表 */
+  .imgBanner {
+    padding: 6px 12px;
+    margin: 16px 7px;
+    border-radius: 2px;
+    background-color: #fff;
+    box-shadow: 0 0 4px 0 rgba(10, 42, 97, 0.2);
+    display: flex;
+    position: relative;
+
+    /* 删除图标 */
+    .el-icon-circle-close {
+      position: absolute;
+      right: -10px;
+      top: -10px;
+      cursor: pointer;
+      font-size: 19px;
+    }
+
+    /* 图片 */
+    .imag {
+      width: 60px;
+      height: 60px;
+      border-radius: 5px;
+      overflow: hidden;
+      position: relative;
+      cursor: pointer;
+      img {
+        width: 100%;
+        height: 100%;
+        display: inline-block;
+      }
+      span {
+        background: rgba(0, 0, 0, 0.5);
+        font-size: 12px;
+        position: absolute;
+        left: 0px;
+        bottom: 0px;
+        display: inline-block;
+        width: 100%;
+        text-align: center;
+        color: #fff;
+        height: 20px;
+        line-height: 20px;
+      }
+    }
+
+    /* 图片字 */
+    .imgText {
+      width: 80%;
+      display: flex;
+      flex-direction: column;
+      box-sizing: border-box;
+      padding-left: 20px;
+      justify-content: space-between;
+      .select-type {
+        display: flex;
+        /deep/.el-select {
+          .el-input {
+            input {
+              white-space: nowrap;
+              overflow: hidden;
+              text-overflow: ellipsis;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 206 - 0
src/asEditorComponents/rightslider/richtextstyle/index.vue

@@ -0,0 +1,206 @@
+<template>
+  <div class="richtextstyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+
+    <el-form label-width="80px" :model="datas" size="small">
+      <!-- 背景颜色 -->
+      <el-form-item label="背景颜色">
+        <!-- 背景颜色 -->
+        <el-color-picker
+          v-model="datas.backColor"
+          show-alpha
+          style="float: right"
+          class="picke"
+          :predefine="predefineColors"
+        >
+        </el-color-picker>
+      </el-form-item>
+    </el-form>
+
+    <div class="edit">
+      <editor v-model="datas.myValue" :init="init" />
+    </div>
+  </div>
+</template>
+
+<script>
+import { uploadCOS } from '@/utils/upload'
+
+import Editor from '@tinymce/tinymce-vue'
+import 'tinymce/themes/silver'
+import 'tinymce/skins/ui/oxide/skin.min.css'
+import 'tinymce/plugins/image'
+import 'tinymce/plugins/lists'
+import 'tinymce/plugins/advlist'
+import 'tinymce/plugins/anchor'
+import 'tinymce/plugins/autosave'
+import 'tinymce/plugins/code'
+import 'tinymce/plugins/paste'
+import 'tinymce/plugins/directionality'
+import 'tinymce/plugins/link'
+import 'tinymce/plugins/fullscreen'
+import 'tinymce/plugins/hr'
+import 'tinymce/plugins/insertdatetime'
+import 'tinymce/plugins/pagebreak'
+import 'tinymce/plugins/preview'
+import 'tinymce/plugins/print'
+import 'tinymce/plugins/save'
+import 'tinymce/plugins/searchreplace'
+import 'tinymce/plugins/table'
+import 'tinymce/plugins/wordcount'
+import 'tinymce/plugins/toc'
+import 'tinymce/plugins/charmap'
+
+export default {
+  name: 'richtextstyle',
+  props: {
+    datas: Object,
+  },
+  components: {
+    Editor,
+  },
+  data() {
+    return {
+      init: {
+        height: 550,
+        language_url: '/langs/zh_CN.js',
+        language: 'zh_CN',
+        plugins: [
+          'charmap',
+          'toc',
+          'wordcount',
+          'table',
+          'searchreplace',
+          'image',
+          'link',
+          'lists',
+          'advlist',
+          'anchor',
+          'autosave',
+          'code',
+          'paste',
+          'directionality',
+          'fullscreen',
+          'hr',
+          'insertdatetime',
+          'pagebreak',
+          'preview',
+          'print',
+          'save',
+        ],
+        image_advtab: true,
+        toolbar: [
+          `fullscreen code bold italic underline strikethrough alignleft aligncenter alignright alignjustify 
+          outdent indent image link removeformat cut copy paste ltr rtl anchor restoredraft pagebreak save 
+          table tabledelete tableprops tablerowprops tablecellprops tableinsertrowbefore tableinsertrowafter tabledeleterow tableinsertcolbefore tableinsertcolafter tabledeletecol 
+          backcolor formatselect fontselect fontsizeselect forecolor 
+          subscript superscript hr preview print searchreplace wordcount toc charmap bullist numlist insertdatetime undo redo`,
+        ],
+        theme: 'silver', //主题
+        menubar: false,
+        images_upload_handler: (blobInfo, succFun, failFun) => {
+          // 腾讯云COS上传开始
+          uploadCOS(blobInfo.blob()).then((res) => {
+            succFun(res)
+          })
+          return
+          //(如果要用api接口上传删除腾讯云COS上传这些代码)
+          // 腾讯云COS上传结束 
+          
+
+          var formData = new FormData()
+
+          formData.append('path', 'test/')
+          formData.append('file', blobInfo.blob(), blobInfo.blob().name)
+
+          var xhr = new XMLHttpRequest()
+          xhr.withCredentials = false
+          xhr.open('POST', `${window.global_config.BASE_URL}upload/miniShop`)
+
+          xhr.onload = function () {
+            // 获取数据
+            var res = JSON.parse(xhr.response)
+            if (res.success != true) return failFun('HTTP Error: ' + res.msg)
+            succFun(res.data.src)
+          }
+
+          xhr.send(formData)
+        },
+      },
+      predefineColors: [
+        // 颜色选择器预设
+        '#ff4500',
+        '#ff8c00',
+        '#ffd700',
+        '#90ee90',
+        '#00ced1',
+        '#1e90ff',
+        '#c71585',
+        '#409EFF',
+        '#909399',
+        '#C0C4CC',
+        'rgba(255, 69, 0, 0.68)',
+        'rgb(255, 120, 0)',
+        'hsv(51, 100, 98)',
+        'hsva(120, 40, 94, 0.5)',
+        'hsl(181, 100%, 37%)',
+        'hsla(209, 100%, 56%, 0.73)',
+        '#c7158577',
+      ],
+    }
+  },
+}
+</script>
+
+<style scoped lang="less">
+.richtextstyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+}
+
+/* 修改富文本样式 */
+/deep/.tox {
+  border: 1px solid #ebedf0 !important;
+}
+/deep/.tox .tox-tbtn {
+  height: 25px !important;
+  margin: 0 2px !important;
+  width: auto;
+  font-size: 13px;
+}
+
+/deep/.tox .tox-tbtn--bespoke .tox-tbtn__select-label {
+  width: auto !important;
+}
+/deep/.tox .tox-toolbar,
+.tox .tox-toolbar__primary,
+.tox .tox-toolbar__overflow {
+  background: none !important;
+}
+
+/deep/.tox .tox-toolbar__group {
+  background: #f7f8fa;
+}
+
+/deep/.tox .tox-tbtn--enabled,
+.tox .tox-tbtn--enabled:hover {
+  background: none !important;
+  /deep/svg {
+    fill: #155bd4 !important;
+  }
+}
+</style>

+ 196 - 0
src/asEditorComponents/rightslider/storeinformationstyle/index.vue

@@ -0,0 +1,196 @@
+<template>
+  <div class="storeinformationstyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+
+    <p style="color: #323233; font-size: 14px">背景图片</p>
+    <div style="height: 10px"></div>
+    <p style="color: #969799; font-size: 12px">
+      建议尺寸:750x370 像素,尺寸不匹配时,图片将被压缩或拉伸以铺满画面
+    </p>
+
+    <div style="height: 10px"></div>
+    <!-- 背景图 -->
+    <div class="backgroundImg" @click="uploadI('bakcgroundImg')">
+      <img
+        draggable="false"
+        v-if="!datas.bakcgroundImg"
+        src="../../../assets/images/backimg.png"
+        alt=""
+      />
+      <img draggable="false" v-else :src="datas.bakcgroundImg" alt="" />
+      <p>更换图片</p>
+    </div>
+
+    <div style="height: 20px"></div>
+    <p style="color: #323233; font-size: 14px">店铺头像</p>
+
+    <div style="height: 10px"></div>
+    <!-- 店铺头像 -->
+    <div class="backgroundImg" @click="uploadI('headPortrait')">
+      <img
+        draggable="false"
+        v-if="!datas.headPortrait"
+        src="../../../assets/images/headerimg.png"
+        alt=""
+      />
+      <img draggable="false" v-else :src="datas.headPortrait" alt="" />
+      <p>更换图片</p>
+    </div>
+
+    <div
+      style="margin: 20px 0; height: 1px; background: rgb(235, 237, 240)"
+    ></div>
+
+    <!-- 表单 -->
+    <el-form label-width="80px" :model="datas" size="small" :rules="rules">
+      <!-- 标题内容 -->
+      <el-form-item label="选择模板" class="lef"> </el-form-item>
+
+      <!-- 商品样式选择 -->
+      <el-radio-group v-model="datas.rubiksCubeType" class="select-sp">
+        <el-radio
+          style="margin-top: 10px; margin-right: 10px"
+          :label="item.type"
+          v-for="(item, index) in rubiksCubeTypes"
+          :key="index"
+          >{{ item.content }}</el-radio
+        >
+      </el-radio-group>
+
+      <div style="height: 30px"></div>
+
+      <!-- 店铺名称 -->
+      <el-form-item label="店铺名称" class="lef" prop="name">
+        <el-input
+          v-model="datas.name"
+          placeholder="请填写店铺名称"
+          maxlength="20"
+        ></el-input>
+      </el-form-item>
+
+      <!-- 店铺名称 -->
+      <el-form-item label="优惠信息" class="lef">
+        <el-input
+          v-model="datas.Discount"
+          placeholder="请填写优惠信息也可不填"
+          maxlength="45"
+        ></el-input>
+      </el-form-item>
+    </el-form>
+
+    <!-- 上传图片 -->
+    <uploadimg ref="upload" @uploadInformation="uploadInformation" />
+  </div>
+</template>
+
+<script>
+import uploadimg from '../../uploadImg' //图片上传
+
+export default {
+  name: 'storeinformationstyle',
+  props: {
+    datas: Object,
+  },
+  data() {
+    return {
+      danqian: '', //当前选中的是背景还是头像
+      rules: {
+        name: [{ required: true, message: '请输入店铺名称', trigger: 'blur' }],
+      },
+      rubiksCubeTypes: [
+        {
+          type: 0,
+          content: '样式一',
+        },
+        {
+          type: 1,
+          content: '样式二',
+        },
+        {
+          type: 2,
+          content: '样式三',
+        },
+        {
+          type: 3,
+          content: '样式四',
+        },
+        {
+          type: 4,
+          content: '样式五',
+        },
+      ],
+    }
+  },
+  methods: {
+    /* 上传图片 */
+    uploadI(res) {
+      this.danqian = res
+      this.$refs.upload.showUpload()
+    },
+    // 提交
+    uploadInformation(res) {
+      this.datas[this.danqian] = res
+    },
+  },
+  components: { uploadimg },
+}
+</script>
+
+<style scoped lang="less">
+.storeinformationstyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+  /* 背景图 */
+  .backgroundImg {
+    display: inline-flex;
+    align-items: center;
+    cursor: pointer;
+    width: 60px;
+    height: 60px;
+    position: relative;
+    background: #f2f4f6;
+
+    img {
+      width: 100%;
+      height: auto;
+    }
+
+    p {
+      position: absolute;
+      left: 0;
+      bottom: 0;
+      width: 100%;
+      height: 20px;
+      font-size: 12px;
+      color: #fff;
+      background: rgba(0, 0, 0, 0.5);
+      text-align: center;
+      line-height: 20px;
+    }
+  }
+
+  .lef {
+    /deep/.el-form-item__label {
+      text-align: left;
+    }
+  }
+  .select-sp {
+    display: flex;
+    flex-wrap: wrap;
+  }
+}
+</style>

+ 603 - 0
src/asEditorComponents/rightslider/storenotecardstyle/index.vue

@@ -0,0 +1,603 @@
+<template>
+  <div class="storenotecardstyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+
+    <!-- 表单 -->
+    <el-form label-width="80px" :model="datas" size="small" :rules="rules">
+      <el-form-item label="活动名称" class="lef">
+        <el-input v-model="datas.name"></el-input>
+      </el-form-item>
+
+      <div class="bor" />
+
+      <!-- 标题内容 -->
+      <el-form-item class="lef" label="选择模板">
+        <p style="color: #000">{{ styleText }}</p>
+      </el-form-item>
+
+      <!-- 卡片样式选择 -->
+      <div class="commodityType">
+        <el-tooltip
+          class="item"
+          effect="dark"
+          :content="item.content"
+          placement="bottom"
+          v-for="(item, index) in commodityTypes"
+          :key="index"
+        >
+          <span
+            class="iconfont"
+            style="font-size: 21px"
+            :class="[
+              item.type === datas.commodityType ? 'active' : '',
+              item.icon,
+            ]"
+            @click="datas.commodityType = index"
+          />
+        </el-tooltip>
+      </div>
+
+      <div class="bor" />
+
+      <h5 style="color: #000; font-size: 14px">添加卡片</h5>
+      <p style="color: #969799; font-size: 12px; margin-top: 10px">
+        鼠标拖拽调整卡片顺序
+      </p>
+
+      <!-- 图片广告 -->
+      <div v-if="datas.imageList[0]">
+        <vuedraggable v-model="datas.imageList" v-bind="dragOptions">
+          <transition-group>
+            <section
+              class="imgBanner"
+              v-for="(item, index) in datas.imageList"
+              :key="item + index"
+            >
+              <i class="el-icon-circle-close" @click="deleteimg(index)" />
+              <!-- 图片 -->
+              <div class="imag">
+                <img :src="item.src" alt="" draggable="false" />
+              </div>
+              <!-- 标题和链接 -->
+              <div class="imgText">
+                <el-input
+                  v-model="item.text"
+                  placeholder="笔记标题"
+                  size="mini"
+                />
+                <!-- 标题和链接 -->
+                <div class="imgTextChild">
+                  <!-- 选择类型 -->
+                  <el-select
+                    v-model="item.linktype"
+                    placeholder="请选择跳转类型"
+                    size="mini"
+                    @change="selectType(index)"
+                  >
+                    <el-option
+                      v-for="iteml in optionsType"
+                      :key="iteml.name"
+                      :label="iteml.name"
+                      :value="iteml.type"
+                    >
+                    </el-option>
+                  </el-select>
+
+                  <!-- 输入外部链接 -->
+                  <el-input
+                    size="mini"
+                    placeholder="请输入链接,输入前确保可以访问"
+                    v-model="item.http.externalLink"
+                  >
+                  </el-input>
+                </div>
+              </div>
+            </section>
+          </transition-group>
+        </vuedraggable>
+      </div>
+
+      <!-- 上传图片 -->
+      <el-button
+        @click="$refs.upload.showUpload()"
+        class="uploadImg"
+        type="primary"
+        plain
+        ><i class="el-icon-plus" />点击添加卡片</el-button
+      >
+
+      <div style="height: 10px" />
+
+      <!-- 卡片样式 -->
+      <el-form-item label="卡片样式" class="lef" />
+      <!-- 卡片样式选择 -->
+      <div class="moditystyle">
+        <span
+          v-for="(item, index) in moditystyles"
+          :key="index"
+          :class="item.type == datas.moditystyle ? 'active' : ''"
+          @click="datas.moditystyle = index"
+        >
+          {{ item.text }}
+        </span>
+      </div>
+
+      <div class="bor" />
+
+      <!-- 文本粗细 -->
+      <el-form-item
+        class="lef"
+        label="文本粗细"
+        prop="textWeight"
+        :hide-required-asterisk="true"
+      >
+        <el-input
+          type="number"
+          v-model.number="datas.textWeight"
+          placeholder="请输入文本粗细"
+        />
+      </el-form-item>
+
+      <div style="height: 10px" />
+
+      <!-- 图片倒角 -->
+      <el-form-item label="图片倒角" class="lef borrediu">
+        <el-slider
+          v-model="datas.borderRadius"
+          :max="30"
+          input-size="mini"
+          show-input
+        >
+        </el-slider>
+      </el-form-item>
+
+      <div style="height: 10px" v-if="datas.commodityType === 0" />
+
+      <!-- 显示位置 -->
+      <el-form-item
+        label="标题位置"
+        class="lef"
+        v-if="datas.commodityType === 0"
+      >
+        <div class="weiz">
+          <el-tooltip
+            class="item"
+            effect="dark"
+            content="上方"
+            placement="bottom"
+          >
+            <i
+              :class="datas.positions === 'top' ? 'active' : ''"
+              class="iconfont icon-shang"
+              @click="datas.positions = 'top'"
+            />
+          </el-tooltip>
+          <el-tooltip
+            class="item"
+            effect="dark"
+            content="下方"
+            placement="bottom"
+          >
+            <i
+              :class="datas.positions === 'bottom' ? 'active' : ''"
+              class="iconfont icon-jiantou"
+              @click="datas.positions = 'bottom'"
+            />
+          </el-tooltip>
+        </div>
+      </el-form-item>
+
+      <div class="bor" />
+
+      <!--笔记标签 -->
+      <el-form-item class="lef" label="笔记标签">
+        {{ datas.noteLabels ? '显示' : '隐藏' }}
+        <el-checkbox style="margin-left: 196px" v-model="datas.noteLabels" />
+      </el-form-item>
+
+      <!--阅读数 -->
+      <el-form-item class="lef" label="阅读数">
+        {{ datas.readingNumber ? '显示' : '隐藏' }}
+        <el-checkbox style="margin-left: 196px" v-model="datas.readingNumber" />
+      </el-form-item>
+
+      <!--点赞数 -->
+      <el-form-item class="lef" label="点赞数">
+        {{ datas.praisePoints ? '显示' : '隐藏' }}
+        <el-checkbox style="margin-left: 196px" v-model="datas.praisePoints" />
+      </el-form-item>
+
+      <!--查看更多 -->
+      <el-form-item class="lef" label="查看更多">
+        <!-- {{datas.viewMore1 ? '显示' : '隐藏'}} -->
+        <el-checkbox v-model="datas.viewMore1"
+          >头部{{ datas.viewMore1 ? '显示' : '隐藏' }}</el-checkbox
+        >
+        <el-checkbox v-model="datas.viewMore2"
+          >尾部{{ datas.viewMore2 ? '显示' : '隐藏' }}</el-checkbox
+        >
+        <div class="imgText1" v-show="datas.viewMore1 || datas.viewMore2">
+          <!-- 选择类型 -->
+          <el-select
+            style="width: 60%"
+            v-model="datas.linktype"
+            placeholder="请选择跳转类型"
+            size="mini"
+          >
+            <el-option
+              v-for="item in optionsType1"
+              :key="item.name"
+              :label="item.name"
+              :value="item.type"
+            >
+            </el-option>
+          </el-select>
+
+          <!-- 输入外部链接 -->
+          <el-input
+            style="width: 100%"
+            size="mini"
+            placeholder="请输入链接,输入前确保可以访问"
+            v-model="datas.http.externalLink"
+          >
+          </el-input>
+        </div>
+      </el-form-item>
+    </el-form>
+
+    <!-- 上传图片 -->
+    <uploadimg ref="upload" @uploadInformation="uploadInformation" />
+  </div>
+</template>
+
+<script>
+import vuedraggable from 'vuedraggable' //拖拽组件
+import uploadimg from '../../uploadImg' //图片上传
+
+export default {
+  name: 'storenotecardstyle',
+  props: {
+    datas: Object,
+  },
+  components: { vuedraggable, uploadimg },
+  data() {
+    let kon = (rule, value, callback) => {
+      if (value.length === 0) callback(new Error('请输入有效数字'))
+    }
+    return {
+      optionsType1: [
+        {
+          type: '10',
+          name: '内部链接',
+        },
+        {
+          type: '11',
+          name: '外部链接',
+        },
+      ], // 选择跳转类型
+      options1: [],
+      moditystyles: [
+        /* 卡片样式 */
+        {
+          text: '无边白底',
+          type: 0,
+        },
+        {
+          text: '卡片投影',
+          type: 1,
+        },
+        {
+          text: '描边白底',
+          type: 2,
+        },
+        {
+          text: '无边透明底',
+          type: 3,
+        },
+      ],
+      commodityTypes: [
+        {
+          icon: 'icon-datumoshi',
+          type: 0,
+          content: '大图模式',
+        },
+        {
+          icon: 'icon-commodity-yihangliangge',
+          type: 1,
+          content: '一行两个',
+        },
+        {
+          icon: 'icon-xuanzemokuai-daohanghengxianghuadong',
+          type: 2,
+          content: '横向滑动',
+        },
+        {
+          icon: 'icon-sanlan',
+          type: 3,
+          content: '一大两小',
+        },
+        {
+          icon: 'icon-commodity-xiangxiliebiao',
+          type: 4,
+          content: '详细列表',
+        },
+      ],
+      rules: {
+        textWeight: [{ required: true, validator: kon, trigger: 'blur' }],
+      },
+      marker: ['新品', '热卖', 'NEW', 'HOT'],
+      dragOptions: {
+        animation: 200,
+      },
+      optionsType: [
+        {
+          type: '10',
+          name: '内部链接',
+        },
+        {
+          type: '11',
+          name: '外部链接',
+        },
+      ], // 选择跳转类型
+      options: [], //后端返回的列表提供下拉选择
+      emptyText: '',
+    }
+  },
+  created() {},
+  methods: {
+    selectType(index) {
+      // 每次切换类型之前 清空之前选中跳转
+      this.datas.imageList[index].http = {}
+      // 清空 options
+      this.options = []
+    },
+    // 提交
+    uploadInformation(res) {
+      this.datas.imageList.push({
+        src: res,
+        text: '这里显示笔记标题最多显示2行',
+        http: {},
+        type: '1',
+      })
+    },
+
+    /* 删除图片 */
+    deleteimg(index) {
+      this.datas.imageList.splice(index, 1)
+    },
+  },
+  computed: {
+    // eslint-disable-next-line vue/return-in-computed-property
+    styleText() {
+      if (this.datas.commodityType === 0) return '大图模式'
+      if (this.datas.commodityType === 1) return '一行两个'
+      if (this.datas.commodityType === 2) return '横向滑动'
+      if (this.datas.commodityType === 3) return '详细列表'
+      if (this.datas.commodityType === 4) return '一大两小'
+      if (this.datas.commodityType === 5) return '横向滑动'
+    },
+  },
+}
+</script>
+
+<style scoped lang="less">
+.storenotecardstyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+
+  .lef {
+    /deep/.el-form-item__label {
+      text-align: left;
+    }
+  }
+
+  /* 图片字 */
+  .imgText1 {
+    width: 100%;
+    display: flex;
+    box-sizing: border-box;
+    justify-content: space-between;
+    .fir-sele.el-select {
+      width: 40%;
+    }
+  }
+
+  /* 列表样式 */
+  .commodityType {
+    display: flex;
+    justify-content: space-around;
+    align-items: center;
+    span {
+      display: inline-block;
+      width: 58px;
+      height: 32px;
+      text-align: center;
+      line-height: 32px;
+      background: #fff;
+      border: 1px solid #ebedf0;
+      color: #979797;
+      margin: 0 1px;
+      cursor: pointer;
+      transition: all 0.5s;
+
+      &:hover {
+        border: 1px solid #155bd4;
+        color: #155bd4;
+      }
+
+      &.active {
+        border: 1px solid #155bd4;
+        background-color: #e0edff;
+        color: #155bd4;
+      }
+    }
+  }
+
+  /* 卡片样式 */
+  .moditystyle {
+    font-size: 12px;
+    width: 100%;
+    display: flex;
+    span {
+      width: 86px;
+      height: 32px;
+      display: inline-block;
+      text-align: center;
+      line-height: 32px;
+      cursor: pointer;
+      border: 1px solid #ebedf0;
+      &.active {
+        border: 1px solid #155bd4;
+        background-color: #e0edff;
+        color: #155bd4;
+      }
+    }
+  }
+
+  /* 位置 */
+  .weiz {
+    text-align: right;
+    i {
+      padding: 5px 14px;
+      margin-left: 10px;
+      border-radius: 0;
+      border: 1px solid #ebedf0;
+      font-size: 20px;
+      font-weight: 500;
+      cursor: pointer;
+
+      &:last-child {
+        font-size: 22px;
+      }
+
+      &.active {
+        color: #155bd4;
+        border: 1px solid #155bd4;
+        background: #e0edff;
+      }
+    }
+  }
+
+  /* 单选框 */
+  /deep/.radi1 {
+    border-top: 1px solid #f7f8fa;
+    border-bottom: 1px solid #f7f8fa;
+    padding: 12px 0;
+    .el-radio {
+      margin: 10px 25px 7px 0;
+    }
+  }
+
+  /* 卡片列表 */
+  .imgBanner {
+    padding: 6px 12px;
+    margin: 16px 7px;
+    border-radius: 2px;
+    background-color: #fff;
+    box-shadow: 0 0 4px 0 rgba(10, 42, 97, 0.2);
+    display: flex;
+    position: relative;
+
+    /* 删除图标 */
+    .el-icon-circle-close {
+      position: absolute;
+      right: -10px;
+      top: -10px;
+      cursor: pointer;
+      font-size: 19px;
+    }
+
+    /* 图片 */
+    .imag {
+      width: 60px;
+      height: 60px;
+      border-radius: 5px;
+      overflow: hidden;
+      position: relative;
+      cursor: pointer;
+      img {
+        width: 100%;
+        height: 100%;
+        display: inline-block;
+      }
+      span {
+        background: rgba(0, 0, 0, 0.5);
+        font-size: 12px;
+        position: absolute;
+        left: 0px;
+        bottom: 0px;
+        display: inline-block;
+        width: 100%;
+        text-align: center;
+        color: #fff;
+        height: 20px;
+        line-height: 20px;
+      }
+    }
+
+    /* 图片字 */
+    .imgText {
+      width: 80%;
+      display: flex;
+      flex-direction: column;
+      box-sizing: border-box;
+      padding-left: 20px;
+      justify-content: space-between;
+      /* 图片字 */
+      .imgTextChild {
+        width: 100%;
+        display: flex;
+        box-sizing: border-box;
+        justify-content: space-between;
+        .fir-sele.el-select {
+          width: 40%;
+        }
+      }
+    }
+  }
+
+  /* 上传图片按钮 */
+  .uploadImg {
+    width: 345px;
+    height: 40px;
+    margin-top: 20px;
+  }
+
+  // 上传弹框内容部分
+  /deep/.uploadIMG .el-dialog__body {
+    height: 280px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    position: relative;
+    justify-content: center;
+  }
+
+  .disable {
+    /deep/.el-upload {
+      display: none !important;
+    }
+  }
+
+  .tit {
+    /deep/.el-input__inner {
+      text-align: center;
+    }
+  }
+}
+</style>

+ 97 - 0
src/asEditorComponents/rightslider/suspensionstyle/index.vue

@@ -0,0 +1,97 @@
+<template>
+  <div class="suspensionstyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+
+    <!-- 表单 -->
+    <el-form
+      label-position="top"
+      label-width="80px"
+      :model="datas"
+      size="small"
+    >
+      <!-- 跳转页面 -->
+      <el-form-item label="跳转页面">
+        <div class="imgText">
+          <!-- 选择类型 -->
+          <el-select
+            style="width: 60%"
+            v-model="datas.type"
+            placeholder="请选择跳转类型"
+            size="mini"
+          >
+            <el-option
+              v-for="item in optionsType"
+              :key="item.name"
+              :label="item.name"
+              :value="item.type"
+            >
+            </el-option>
+          </el-select>
+
+          <!-- 输入链接 -->
+          <el-input
+            style="width: 100%"
+            size="mini"
+            placeholder="请输入链接,输入前确保可以访问"
+            v-model="datas.http.externalLink"
+          >
+          </el-input>
+        </div>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+<script>
+export default {
+  name: 'suspensionstyle',
+  props: {
+    datas: Object,
+  },
+  data() {
+    return {
+      optionsType: [
+        {
+          type: '10',
+          name: '内部链接',
+        },
+        {
+          type: '11',
+          name: '外部链接',
+        },
+      ], // 选择跳转类型
+      options: [], //后端返回的列表提供下拉选择
+      emptyText: '',
+    }
+  },
+  created() {},
+}
+</script>
+<style lang="less" scoped>
+.suspensionstyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+  .imgText {
+    width: 100%;
+    display: flex;
+    box-sizing: border-box;
+    justify-content: space-between;
+    .fir-sele.el-select {
+      width: 40%;
+    }
+  }
+}
+</style>

+ 363 - 0
src/asEditorComponents/rightslider/tabBarStyle/index.vue

@@ -0,0 +1,363 @@
+<template>
+  <div class="investigatestyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+
+    <!-- 表单 -->
+    <el-form label-width="100px" :model="datas" size="small">
+      <el-form-item class="lef" label="外边框">
+        <el-checkbox v-model="datas.isShowBorder">显示</el-checkbox>
+      </el-form-item>
+
+      <el-form-item class="lef" label="选中的颜色">
+        <!-- 颜色选择器 -->
+        <el-color-picker
+          v-model="datas.activeColor"
+          show-alpha
+          class="picke"
+          :predefine="predefineColors"
+        >
+        </el-color-picker>
+      </el-form-item>
+
+      <el-form-item class="lef" label="未选中的颜色">
+        <!-- 颜色选择器 -->
+        <el-color-picker
+          v-model="datas.inactiveColor"
+          show-alpha
+          class="picke"
+          :predefine="predefineColors"
+        >
+        </el-color-picker>
+      </el-form-item>
+
+      <el-form-item class="lef" label="高亮位置">
+        <el-slider
+          v-model="datas.Highlight"
+          :max="4"
+          :min="0"
+          input-size="mini"
+          show-input
+        >
+        </el-slider>
+      </el-form-item>
+
+      <el-form-item class="lef" label="导航"> </el-form-item>
+      <vuedraggable v-model="datas.iconList" v-bind="dragOptions">
+        <transition-group>
+          <section
+            class="imgBanner"
+            v-for="(item, index) in datas.iconList"
+            :key="item + index"
+          >
+            <i class="el-icon-circle-close" @click="deleteimg(index)" />
+            <!-- 图片 -->
+            <div>
+              <div
+                class="imagBox"
+                v-for="replaceIconIndex in 2"
+                :key="replaceIconIndex"
+                @click="replaceIcon(replaceIconIndex, index)"
+              >
+                <img
+                  class="imag"
+                  :src="replaceIconIndex == 1 ? item.iconPic : item.inactive"
+                  draggable="false"
+                />
+                <div>
+                  {{ replaceIconIndex == 1 ? '选中时' : '未选中时' }}
+                </div>
+              </div>
+            </div>
+            <!-- 标题和链接 -->
+            <div class="imgText">
+              <div class="imgText-top">
+                <el-input
+                  v-model="item.iconText"
+                  placeholder="导航名称"
+                  size="mini"
+                />
+                <div class="imgText-top-r">
+                  <span>小圆点</span>
+                  <el-checkbox v-model="item.isDot"></el-checkbox>
+                </div>
+              </div>
+              <!-- 标题和链接 -->
+              <div class="imgTextChild">
+                <!-- 选择类型 -->
+                <el-select
+                  v-model="item.linktype"
+                  placeholder="请选择跳转类型"
+                  size="mini"
+                >
+                  <el-option
+                    v-for="iteml in optionsType"
+                    :key="iteml.name"
+                    :label="iteml.name"
+                    :value="iteml.type"
+                  >
+                  </el-option>
+                </el-select>
+
+                <!-- 输入链接 -->
+                <el-input
+                  size="mini"
+                  placeholder="请输入链接,输入前确保可以访问"
+                  v-model="item.http.externalLink"
+                >
+                </el-input>
+              </div>
+            </div>
+          </section>
+        </transition-group>
+      </vuedraggable>
+
+      <!-- 添加导航按钮 -->
+      <el-button
+        @click="$refs.upload.showUpload()"
+        class="uploadImg"
+        type="primary"
+        plain
+        v-if="datas.iconList.length < 5"
+      >
+        <i class="el-icon-plus" />点击添加导航
+      </el-button>
+      <i class="icon-tip">*最多添加5个</i>
+    </el-form>
+
+    <!-- 上传图片 -->
+    <uploadimg
+      ref="upload"
+      @uploadInformation="uploadInformation"
+      @handleClose="handleClose"
+    />
+  </div>
+</template>
+
+<script>
+import uploadimg from '../../uploadImg' //图片上传
+import vuedraggable from 'vuedraggable' //拖拽组件
+
+export default {
+  name: 'tabBarStyle',
+  props: {
+    datas: Object,
+  },
+  data() {
+    return {
+      predefineColors: [
+        // 颜色选择器预设
+        '#ff4500',
+        '#ff8c00',
+        '#ffd700',
+        '#90ee90',
+        '#00ced1',
+        '#1e90ff',
+        '#c71585',
+        '#409EFF',
+        '#909399',
+        '#C0C4CC',
+        'rgba(255, 69, 0, 0.68)',
+        'rgb(255, 120, 0)',
+        'hsv(51, 100, 98)',
+        'hsva(120, 40, 94, 0.5)',
+        'hsl(181, 100%, 37%)',
+        'hsla(209, 100%, 56%, 0.73)',
+        '#c7158577',
+      ],
+      optionsType: [
+        {
+          type: '10',
+          name: '内部链接',
+        },
+        {
+          type: '11',
+          name: '外部链接',
+        },
+      ], // 选择跳转类型
+      emptyText: '',
+      dragOptions: {
+        animation: 200,
+      },
+      replaceIconIndex: null,
+      replaceIndex: null,
+    }
+  },
+
+  created() {},
+
+  mounted() {},
+
+  methods: {
+    // 提交
+    uploadInformation(res) {
+      if (this.replaceIconIndex == 1) {
+        this.datas.iconList[this.replaceIndex].iconPic = res
+        this.replaceIconIndex = null
+        return
+      }
+      if (this.replaceIconIndex == 2) {
+        this.datas.iconList[this.replaceIndex].inactive = res
+        this.replaceIconIndex = null
+        return
+      }
+      this.datas.iconList.push({
+        /** 图标名称文字 */
+        iconText: '',
+        /** 图标图片 */
+        iconPic: res,
+        inactive: res,
+        /** 是否显示小圆点 */
+        isDot: false,
+        /** 跳转类型 */
+        linktype: '10',
+        /** 跳转参数 */
+        http: {},
+      })
+    },
+    /* 取消上传 */
+    handleClose() {
+      this.replaceIconIndex = null
+    },
+    /* 删除图片 */
+    deleteimg(index) {
+      this.datas.iconList.splice(index, 1)
+    },
+    /* 点击图片 */
+    replaceIcon(replaceIconIndex, replaceIndex) {
+      this.replaceIconIndex = replaceIconIndex
+      this.replaceIndex = replaceIndex
+      console.log(replaceIconIndex, replaceIndex)
+      this.$refs.upload.showUpload()
+    },
+  },
+
+  computed: {},
+
+  watch: {},
+
+  components: {
+    uploadimg,
+    vuedraggable,
+  },
+}
+</script>
+
+<style lang="less" scoped>
+.investigatestyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+  .lef {
+    /deep/.el-form-item__label {
+      text-align: left;
+    }
+  }
+  /* 颜色选择器 */
+  .picke {
+    float: right;
+  }
+
+  /* 上传图片按钮 */
+  .uploadImg {
+    width: 345px;
+    height: 40px;
+    margin-top: 20px;
+  }
+
+  /* 卡片列表 */
+  .imgBanner {
+    padding: 6px 12px;
+    margin: 16px 7px;
+    border-radius: 2px;
+    background-color: #fff;
+    box-shadow: 0 0 4px 0 rgba(10, 42, 97, 0.2);
+    display: flex;
+    position: relative;
+
+    /* 删除图标 */
+    .el-icon-circle-close {
+      position: absolute;
+      right: -10px;
+      top: -10px;
+      cursor: pointer;
+      font-size: 19px;
+    }
+
+    /* 图片 */
+    .imagBox {
+      position: relative;
+      border-radius: 5px;
+      overflow: hidden;
+      cursor: pointer;
+      .imag {
+        width: 60px;
+        height: 60px;
+      }
+      div {
+        position: absolute;
+        top: 0;
+        width: 60px;
+        line-height: 60px;
+        border-radius: 5px;
+        text-align: center;
+        font-size: 12px;
+        color: #fff;
+        background-color: rgba(0, 0, 0, 0.3);
+      }
+    }
+
+    /* 图片字 */
+    .imgText {
+      padding-left: 20px;
+      display: flex;
+      flex-direction: column;
+      box-sizing: border-box;
+      justify-content: space-around;
+      /* 图片字 */
+      .imgTextChild {
+        width: 100%;
+        display: flex;
+        box-sizing: border-box;
+        justify-content: space-between;
+        .fir-sele.el-select {
+          width: 40%;
+        }
+      }
+      .imgText-top {
+        display: flex;
+        flex-direction: row;
+        justify-content: space-between;
+        align-items: center;
+        .imgText-top-r {
+          flex: 1;
+          text-align: center;
+          span {
+            margin-right: 10px;
+          }
+        }
+        /deep/.el-input,
+        .el-input--mini {
+          flex: 1;
+        }
+      }
+    }
+  }
+  .icon-tip {
+    font-size: 12px;
+    color: red;
+  }
+}
+</style>

+ 82 - 0
src/asEditorComponents/rightslider/videostyle/index.vue

@@ -0,0 +1,82 @@
+<template>
+  <div class="videostyle">
+    <!-- 标题 -->
+    <h2>{{ datas.text }}</h2>
+
+    <el-form label-width="70px" :model="datas" size="small" class="lef">
+      <el-form-item label="封面链接">
+        <el-input
+          v-model="datas.coverUrl"
+          placeholder="请输入封面链接"
+          show-word-limit
+        />
+      </el-form-item>
+      <el-form-item label="视频链接">
+        <el-input
+          v-model="datas.src"
+          placeholder="请输入视频链接"
+          show-word-limit
+        />
+      </el-form-item>
+      <!-- 是否自动播放 -->
+      <el-form-item class="lef" label="是否自动播放" label-width="100px">
+        {{ datas.autoplay ? '是' : '否' }}
+        <el-checkbox style="margin-left: 196px" v-model="datas.autoplay" />
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'videostyle',
+  props: {
+    datas: Object,
+  },
+  data() {
+    return {}
+  },
+  created() {},
+  methods: {},
+}
+</script>
+
+<style scoped lang="less">
+.videostyle {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding: 0 10px 20px;
+  box-sizing: border-box;
+  /* 标题 */
+  h2 {
+    padding: 24px 16px 24px 0;
+    margin-bottom: 15px;
+    border-bottom: 1px solid #f2f4f6;
+    font-size: 18px;
+    font-weight: 600;
+    color: #323233;
+  }
+
+  .lef {
+    /deep/.el-form-item__label {
+      text-align: left;
+    }
+  }
+
+  /* 刷新 */
+  .link {
+    display: inline-block;
+    padding: 0 10px;
+    height: 32px;
+    line-height: 32px;
+    font-size: 12px;
+    cursor: pointer;
+    color: #155bd4;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+  }
+}
+</style>

+ 279 - 0
src/asEditorComponents/sliderassembly/index.vue

@@ -0,0 +1,279 @@
+<template>
+  <div class="sliderassembly">
+    <el-collapse v-model="activeNames">
+      <el-collapse-item
+        :title="items.title"
+        :name="index + 1"
+        v-for="(items, index) in datas"
+        :key="index"
+      >
+        <div
+          class="componList"
+          draggable="true"
+          @dragstart="drag($event)"
+          @dragend="dragends($event)"
+          :data-name="item.name"
+          v-for="(item, ind) in items.comList"
+          :key="ind"
+        >
+          <i class="iconfont" :class="item.icon"  v-if="item.icon" />
+          <van-icon :name="item.vanIcon" v-else />
+          <p>{{ item.text }}</p>
+        </div>
+      </el-collapse-item>
+    </el-collapse>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'sliderassembly',
+  props: {
+    pointer: Object,
+  },
+  data() {
+    return {
+      activeNames: [1, 2, 3] /* 侧边栏组件显示 */,
+      datas: [
+        {
+          title: '基础组件',
+          comList: [
+            {
+              text: '商品搜索',
+              type: '1-1',
+              icon: 'icon-shangpinsousuo',
+              name: 'commoditysearch',
+            },
+            {
+              text: '标题文本',
+              type: '1-3',
+              icon: 'icon-Component-biaotiwenzi',
+              name: 'captiontext',
+            },
+
+            {
+              text: '图片广告',
+              type: '1-3',
+              icon: 'icon-tupianguanggao',
+              name: 'pictureads',
+            },
+            {
+              text: '图文导航',
+              type: '1-4',
+              icon: 'icon-icon_tupiandaohang',
+              name: 'graphicnavigation',
+            },
+            {
+              text: '底部导航',
+              type: '1-5',
+              icon: 'icon-daohang',
+              name: 'tabBar',
+            },
+            {
+              text: '魔方',
+              type: '1-6',
+              icon: 'icon-mofang',
+              name: 'magiccube',
+            },
+            {
+              text: '公告',
+              type: '1-7',
+              icon: 'icon-gonggao',
+              name: 'notice',
+            },
+            
+            {
+              text: '视频',
+              type: '1-8',
+              icon: 'icon-shipin',
+              name: 'videoss',
+            },
+            {
+              text: '富文本',
+              type: '1-10',
+              icon: 'icon-fuwenben',
+              name: 'richtext',
+            },
+            {
+              text: '辅助分割',
+              type: '1-11',
+              icon: 'icon-Component-fuzhufenge',
+              name: 'auxiliarysegmentation',
+            },
+
+            {
+              text: '店铺信息',
+              type: '1-12',
+              icon: 'icon-dianpuxinxi',
+              name: 'storeinformation',
+            },
+            {
+              text: '单元格',
+              type: '1-13',
+              icon: 'icon-jinrudianpu',
+              name: 'entertheshop',
+            },            
+            {
+              text: '社群涨粉',
+              type: '1-14',
+              icon: 'icon-kuaisuzhangfen',
+              name: 'communitypowder',
+            },
+            /* {
+              text: 'xxx',
+              type: '1-17',
+              icon: 'icon-yunying',
+              name: ''
+            }, */
+            /* {
+              text: 'xxx',
+              type: '1-19',
+              icon: 'icon-weibiaoti-_huaban',
+              name: ''
+            }, */
+            /* {
+              text: 'xxxx',
+              type: '1-18',
+              icon: 'icon-gexinghuatuijian',
+              name: ''
+            }, */
+            {
+              text: '关注公众号',
+              type: '1-15',
+              icon: 'icon-gongzhonghao',
+              name: 'follow',
+            },
+            {
+              text: '悬浮',
+              type: '1-16',
+              icon: 'icon-wangye',
+              name: 'suspension',
+            },
+            {
+              text: '自定义模块',
+              type: 'demo',
+              icon: 'icon-zidingyimokuai',
+              name: 'custommodule'
+            }, 
+          ],
+        },
+        {
+          title: '业务组件',
+          comList: [
+            {
+              text: '商品',
+              type: '2-1',
+              icon: 'icon-goods',
+              name: 'listswitching',
+            },
+            {
+              text: '文章模块',
+              type: '2-2',
+              icon: 'icon-dianpubijikapian',
+              name: 'storenotecard',
+            },
+            {
+              text: '表单模块',
+              type: '2-3',
+              vanIcon: 'orders-o',
+              name: 'investigate',
+            }
+          ]
+        },
+
+      ],
+    }
+  },
+  methods: {
+    /**
+     * 当用户开始拖动元素或选择文本时触发此事件
+     *
+     * @param {Object} event event对象
+     */
+    drag(event) {
+      /* 开启穿透 */
+      this.pointer.show = true
+      /* 传递参数 */
+      event.dataTransfer.setData('componentName', event.target.dataset.name)
+    },
+
+    /**
+     * 当拖动操作结束时(释放鼠标按钮或按下退出键),会触发此事件
+     *
+     * @param {Object} event event对象
+     */
+    dragends() {
+      /* 关闭穿透 */
+      this.pointer.show = false
+    },
+  },
+}
+</script>
+
+<style scoped lang="less">
+/* 组件 */
+.sliderassembly {
+  width: 275px;
+  height: 100%;
+  overflow-y: scroll;
+  border-right: 1px solid #ebedf0;
+  box-sizing: border-box;
+  padding: 0 12px;
+  background: #fff;
+  /* 滚动条 */
+  &::-webkit-scrollbar {
+    width: 1px;
+  }
+  &::-webkit-scrollbar-thumb {
+    background-color: #155bd4;
+  }
+  /deep/.el-collapse-item__header,
+  /deep/.el-collapse-item__wrap {
+    border-bottom: 0 !important;
+  }
+
+  /* 组件列表 */
+  .componList {
+    display: inline-flex;
+    flex-direction: column;
+    justify-content: center;
+    width: 80px;
+    height: 88px;
+    margin-bottom: 8px;
+    align-items: center;
+    cursor: all-scroll;
+    transition: all 0.3s;
+    &:hover {
+      background: #155bd4;
+      border-radius: 2px;
+      font-weight: 700;
+      i,
+      p,
+      span {
+        color: #fff;
+      }
+    }
+    /* 图标 */
+    i {
+      font-size: 32px;
+      width: 32px;
+      height: 32px;
+      line-height: 32px;
+      color: #b0a8a8;
+      margin-top: 4px;
+    }
+    /* 标题 */
+    p {
+      font-size: 12px;
+      color: #323233;
+      margin-top: 4px;
+    }
+    /* 数量 */
+    span {
+      color: #7d7e80;
+      margin-top: 4px;
+      font-size: 10px;
+    }
+  }
+}
+</style>

+ 204 - 0
src/asEditorComponents/uploadCommodity/index.vue

@@ -0,0 +1,204 @@
+<template>
+  <div class="uploadCommodity">
+    <!-- 选择商品 -->
+    <el-dialog
+      class="uploadIMG"
+      title="选择商品"
+      :lock-scroll="true"
+      :visible.sync="dialogVisible"
+      :close-on-press-escape="false"
+      :close-on-click-modal="false"
+      :show-close="false"
+      center
+      width="500px"
+    >
+      <!-- 选择类型 -->
+      <el-select
+        style="width: 60%"
+        v-model="type"
+        placeholder="请选择跳转类型"
+        size="mini"
+        @change="selectType()"
+      >
+        <el-option
+          v-for="item in optionsType"
+          :key="item.name"
+          :label="item.name"
+          :value="item.type"
+        ></el-option>
+      </el-select>
+
+      <!-- 选择 -->
+      <el-select
+        style="width: 60%; margin-top: 15px"
+        v-if="type !== '11'"
+        v-model="dialogImageUrl.name"
+        placeholder="请选择图片跳转链接"
+        size="mini"
+        @change="changeId"
+        :no-data-text="emptyText"
+        @visible-change="
+          (isVisible) => {
+            return changeType(isVisible, type)
+          }
+        "
+      >
+        <el-option
+          v-for="item in options"
+          :key="item.id"
+          :label="item.name"
+          :value="item"
+          :disabled="item.disabled"
+        ></el-option>
+      </el-select>
+
+      <!-- 输入外部链接 -->
+      <el-input
+        style="width: 60%; margin-top: 15px"
+        v-if="type === '11'"
+        size="mini"
+        placeholder="请输入链接,输入前确保可以访问"
+        v-model="externalLink"
+      ></el-input>
+
+      <!-- 按钮 -->
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="handleClose">取 消 上 传</el-button>
+        <el-button type="primary" @click="uploadInformation" :disabled="disabl"
+          >点 击 上 传</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'uploadCommodity',
+  data() {
+    return {
+      dialogVisible: false, //弹框默认隐藏
+      dialogImageUrl: {}, // 选择的数据
+      type: '2',
+      uploadShow: false, //是否显示上传图片
+      optionsType: [
+        {
+          type: '2',
+          name: '书籍',
+        },
+        {
+          type: '5',
+          name: '其他',
+        },
+      ], // 选择跳转类型
+      options: [], //后端返回的列表提供下拉选择
+      externalLink: null,
+      emptyText: '',
+    }
+  },
+  created() {},
+  methods: {
+    selectType() {
+      // 清空 options
+      this.options = []
+    },
+
+    // 选择类型
+    changeType(isVisible, linkType) {
+      if (isVisible && linkType) {
+        this.emptyText = '正在搜索中'
+        /* 获取信息 */
+        let res = {
+          code: 0,
+          success: true,
+          error: false,
+          data: [
+            {
+              coverUrl:
+                'https://imgs.starfirelink.com/minicourse/非遗传承人@2x_1621504834414.png',
+              introduce: '',
+              price: 0,
+              name: '测试1',
+              videoId: '5285890818212341060',
+              id: 403,
+              type: 2,
+              seriesId: '0',
+            },
+            {
+              coverUrl:
+                'https://imgs.starfirelink.com/minicourse/QQ截图20210409170420_1621416051505.png',
+              introduce: '1',
+              price: 1,
+              name: '测试2',
+              videoId: '',
+              id: 396,
+              type: 2,
+              seriesId: '85',
+            },
+          ],
+        }
+        this.activ = 0
+        res.data.length === 0 ? (this.emptyText = '暂无数据') : null
+        this.options = res.data
+      }
+    },
+    // 保存跳转的地方
+    changeId(res) {
+      this.dialogImageUrl = res
+      console.log(this.dialogImageUrl, '----------------changeId')
+    },
+    /* 显示上传文件组件 */
+    showUpload() {
+      this.dialogVisible = true
+    },
+    /* 传递图片地址 */
+    uploadInformation() {
+      this.dialogImageUrl.httpType = this.type
+      this.$emit('uploadListInformation', this.dialogImageUrl)
+
+      // 隐藏上传弹框
+      this.dialogVisible = false
+      this.uploadShow = false
+      this.dialogImageUrl = {}
+    },
+    // 关闭弹框
+    handleClose() {
+      this.$confirm('点击取消后您填写的信息将丢失,您确定取消?')
+        .then(() => {
+          // 隐藏上传文件
+          this.dialogVisible = false
+          this.dialogImageUrl = {}
+        })
+        .catch(() => {})
+    },
+  },
+  computed: {
+    // 提交按钮是否可以点击
+    disabl() {
+      if (!this.dialogImageUrl) return true
+      return false
+    },
+  },
+}
+</script>
+
+<style lang="less" scoped>
+@import '../../assets/css/minx.less';
+.uploadCommodity {
+  // 上传弹框内容部分
+  /deep/.uploadIMG .el-dialog__body {
+    height: 280px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    position: relative;
+    justify-content: center;
+  }
+
+  .disable {
+    /deep/.el-upload {
+      display: none !important;
+    }
+  }
+}
+</style>

+ 175 - 0
src/asEditorComponents/uploadImg/index.vue

@@ -0,0 +1,175 @@
+<template>
+  <div class="uploadImg">
+    <!-- 上传图片 -->
+    <el-dialog
+      class="uploadIMG"
+      title="上传图片"
+      :lock-scroll="true"
+      :visible.sync="dialogVisible"
+      :close-on-press-escape="false"
+      :close-on-click-modal="false"
+      :show-close="false"
+      center
+      width="500px"
+    >
+      <!-- 上传图片 -->
+      <el-upload
+        v-if="dialogVisible"
+        name="file"
+        :action="baseupload"
+        list-type="picture-card"
+        :limit="1"
+        :on-preview="preview"
+        :on-success="onSuccess"
+        :with-credentials="true"
+        :on-error="uploadError"
+        :before-upload="uploads"
+        :before-remove="handleRemove"
+        :class="uploadShow ? 'disable' : ''"
+        :http-request="upload"
+      >
+        <i class="el-icon-plus"></i>
+      </el-upload>
+
+      <!-- 按钮 -->
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="handleClose">取 消 上 传</el-button>
+        <el-button type="primary" @click="uploadInformation" :disabled="disabl"
+          >点 击 上 传</el-button
+        >
+      </span>
+    </el-dialog>
+
+    <!-- 图片放大 -->
+    <el-dialog :visible.sync="dialogVisibles" class="xianshi">
+      <img
+        draggable="false"
+        style="width: 640px; height: 400px; margin: 20px 0px"
+        :src="dialogImageUrl"
+        alt=""
+      />
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { uploadCOS } from '@/utils/upload'
+export default {
+  name: 'uploadImg',
+  data() {
+    return {
+      dialogVisible: false, //弹框默认隐藏
+      dialogVisibles: false, // 放大的图片
+      dialogImageUrl: '', // 上传的图片
+      uploadShow: false, //是否显示上传图片
+    }
+  },
+  created() {},
+  methods: {
+    /* 显示上传文件组件 */
+    showUpload() {
+      this.dialogVisible = true
+    },
+    /* 传递图片地址 */
+    uploadInformation() {
+      this.$emit('uploadInformation', this.dialogImageUrl)
+      // 隐藏上传弹框
+      this.dialogVisible = false
+      this.uploadShow = false
+      this.dialogImageUrl = ''
+    },
+    // 关闭弹框
+    handleClose() {
+      this.$confirm('点击取消后您填写的信息将丢失,您确定取消?')
+        .then(() => {
+          this.handleRemove()
+          this.$emit('handleClose')
+          // 隐藏上传文件
+          this.dialogVisible = false
+          this.dialogImageUrl = ''
+        })
+        .catch(() => {})
+    },
+
+    // 删除图片
+    handleRemove() {
+      this.uploadShow = false
+      this.dialogImageUrl = ''
+      return true
+    },
+
+    // 预览
+    preview() {
+      this.dialogVisibles = true
+    },
+
+    // 上传成功
+    onSuccess(response) {
+      // 返回错误
+      if (response.success != true)
+        return this.$message.error('上传图片失败,请删除后重新上传')
+
+      this.dialogImageUrl = response.data.src
+    },
+
+    // 上传前
+    uploads(file) {
+      if (!file.type.includes('image')) {
+        this.$message.error('请上传图片!')
+        return false
+      }
+      this.uploadShow = true
+    },
+
+    // 上传失败
+    uploadError() {
+      this.$message.error('请重新上传')
+      this.uploadShow = false
+    },
+
+    /**
+     * 自定义上传(使用腾讯云COS)
+     * http-request	覆盖action默认的上传行为,可以自定义上传的实现
+     * 如果要用api接口上传去除el-upload的 http-request属性即可
+     */
+    upload(data) {
+      uploadCOS(data.file).then((res) => {
+        this.dialogImageUrl = res
+      })
+    },
+  },
+  computed: {
+    // baseurl
+    baseupload() {
+      return `${window.global_config.BASE_URL}upload/miniShop`
+    },
+
+    // 提交按钮是否可以点击
+    disabl() {
+      if (!this.dialogImageUrl) return true
+      return false
+    },
+  },
+}
+</script>
+
+<style lang="less" scoped>
+@import '../../assets/css/minx.less';
+.uploadImg {
+  // 上传弹框内容部分
+  /deep/.uploadIMG .el-dialog__body {
+    height: 280px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    position: relative;
+    justify-content: center;
+  }
+
+  .disable {
+    /deep/.el-upload {
+      display: none !important;
+    }
+  }
+}
+</style>

+ 16 - 0
src/assets/css/minx.less

@@ -0,0 +1,16 @@
+@themeColor: #f39800;
+
+/* 下划线 */
+.bor {
+  height: 1px;
+  margin: 20px 0;
+  background-color: rgb(235, 237, 240);
+}
+
+.icon {
+  width: 20px;
+  height: 20px;
+  vertical-align: -0.15em;
+  fill: currentColor;
+  overflow: hidden;
+}

+ 194 - 0
src/assets/css/reset.css

@@ -0,0 +1,194 @@
+
+@charset "utf-8";
+
+ 
+
+html {
+
+    -webkit-text-size-adjust: 100%;
+
+    -ms-text-size-adjust: 100%;
+
+    -webkit-overflow-scrolling : touch;
+
+}
+
+html, body, #app{width:100%;height:100%;}
+
+ 
+
+input[type="submit"], input[type="reset"], input[type="button"], input {
+
+    font-family: Arial, Helvetica, sans-serif;
+
+    resize: none;
+
+    border: none;
+
+}
+
+ 
+
+body, div, ul, li, ol, h1, h2, h3, h4, h5, h6, input, textarea, select, p, dl, dt, dd, a, img, button, form, table, th, tr, td, tbody, article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
+
+    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+
+    font-size:14px;
+
+    box-sizing:border-box;
+
+}
+
+ 
+
+article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
+
+    display: block;
+
+}
+
+ 
+
+img {
+
+    height: auto;
+
+    width: auto\9; /* ie8 */
+
+    -ms-interpolation-mode: bicubic;/*为了照顾ie图片缩放失真*/
+
+}
+
+ 
+
+body, div, ul, li, ol, h1, h2, h3, h4, h5, h6, input, textarea, select, p, dl, dt, dd, a, img, button, form, table, th, tr, td, tbody, article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
+
+    margin: 0;
+
+    padding: 0;
+
+}
+
+body {
+
+    font: 12px/1.5 'Microsoft YaHei','宋体', Tahoma, Arial, sans-serif;
+
+    color: #555;
+
+    background-color: #fff;
+
+    overflow-x: hidden;
+
+}
+
+ul,li{
+
+    list-style-type: none;
+
+}
+
+.clearfix:after {
+
+    content: "";
+
+    display: block;
+
+    visibility: hidden;
+
+    height: 0;
+
+    clear: both;
+
+}
+
+.clearfix {
+
+    zoom: 1;
+
+}
+
+a {
+
+    text-decoration: none;
+
+    color: #969696;
+
+    font-family: 'Microsoft YaHei', Tahoma, Arial, sans-serif;
+
+}
+
+a:hover {
+
+    text-decoration: none;
+
+}
+
+ul, ol {
+
+    list-style: none;
+
+}
+
+h1, h2, h3, h4, h5, h6 {
+
+    font-size: 100%;
+
+    font-family: 'Microsoft YaHei';
+
+}
+
+img {
+
+    border: none;
+
+}
+
+input{
+
+    font-family: 'Microsoft YaHei';
+
+}
+
+ 
+
+.one-txt-cut{
+
+    overflow: hidden;
+
+    white-space: nowrap;
+
+    text-overflow: ellipsis;
+
+}
+
+ 
+
+.txt-cut{
+
+    overflow : hidden;
+
+    text-overflow: ellipsis;
+
+    display: -webkit-box;
+
+    -webkit-box-orient: vertical;
+
+}
+
+ 
+
+a:link,a:active,a:visited,a:hover {
+
+    background: none;
+
+    -webkit-tap-highlight-color: rgba(0,0,0,0);
+
+    -webkit-tap-highlight-color: transparent;
+
+}
+
+i {
+    font-style: normal !important;
+}
+
+input[type=button], input[type=submit], input[type=file], button { cursor: pointer; -webkit-appearance: none; }

File diff suppressed because it is too large
+ 2884 - 0
src/assets/css/skin.css


二進制
src/assets/images/Robot.png


二進制
src/assets/images/add.png


二進制
src/assets/images/backimg.png


二進制
src/assets/images/card.png


二進制
src/assets/images/fwb.png


二進制
src/assets/images/headerimg.png


二進制
src/assets/images/il.jpg


二進制
src/assets/images/imgs.png


二進制
src/assets/images/login-prod.jpg


二進制
src/assets/images/mor.png


二進制
src/assets/images/obliqueLine.png


二進制
src/assets/images/phoneTop.png


二進制
src/assets/images/powder.png


+ 818 - 0
src/myComponents/asEditor.vue

@@ -0,0 +1,818 @@
+<template>
+    <div class="home-as-editor">
+      <!-- 按钮集合 -->
+      <section class="buttons">
+        <p
+          style="
+            font-size: 12px;
+            color: #4f4f4f;
+            margin-left: 15px;
+            cursor: pointer;
+          "
+          @click="Previous"
+        >
+          <!-- 返回 -->
+        </p>
+        <div>
+          <el-button @click="reloads" type="danger"
+            ><i class="el-icon-delete-solid el-icon--left"></i>重置</el-button
+          >
+          <el-button @click="realTimeView.show = true">预览</el-button>
+          <el-button @click="catJson">查看JSON </el-button>
+          <el-button @click="$refs.file.click()">导入JSON </el-button>
+          <el-button @click="exportJSON">导出JSON </el-button>
+          <input
+            type="file"
+            ref="file"
+            id="file"
+            accept=".json"
+            @change="importJSON"
+            style="display: none"
+          />
+          <!-- <el-button @click="Preservation"
+            ><i class="el-icon-s-claim el-icon--left"></i>保存</el-button
+          > -->
+        </div>
+      </section>
+  
+      <!-- 装修操作 -->
+      <section class="operation">
+        <!-- 组件 -->
+        <sliderassembly :pointer="pointer" />
+  
+        <!-- 手机 -->
+        <div class="phone">
+          <section class="phoneAll" ref="imageTofile" id="imageTofile">
+            <img src="@/assets/images/phoneTop.png" alt="" class="statusBar" />
+  
+            <!-- 头部导航 -->
+            <headerTop :pageSetup="pageSetup" @click.native="headTop" />
+  
+            <!-- 主体内容 -->
+            <section
+              class="phone-container"
+              :style="{
+                'background-color': pageSetup.bgColor,
+                backgroundImage: 'url(' + pageSetup.bgImg + ')',
+              }"
+              @drop="drop($event)"
+              @dragover="allowDrop($event)"
+              @dragleave="dragleaves($event)"
+            >
+              <div :class="pointer.show ? 'pointer-events' : ''">
+                <!-- 动态组件 -->
+                <component
+                  :is="item.component"
+                  v-for="(item, index) in pageComponents"
+                  :key="index"
+                  :datas="item.setStyle"
+                  :style="{
+                    border: item.active && deleShow ? '2px solid #155bd4' : '',
+                  }"
+                  @click.native="activeComponent(item, index)"
+                  class="componentsClass"
+                  :data-type="item.type"
+                >
+                  <div
+                    v-show="deleShow"
+                    class="deles"
+                    slot="deles"
+                    @click.stop="deleteObj(index)"
+                  >
+                    <!-- 删除组件 -->
+                    <span class="iconfont icon-sanjiaoxingzuo"></span>
+                    {{ item.text }}
+                    <i class="el-icon-delete-solid" />
+                  </div>
+                </component>
+              </div>
+            </section>
+  
+            <!-- 手机高度 -->
+            <div class="phoneSize">iPhone 8手机高度</div>
+  
+            <!-- 底部 -->
+            <phoneBottom />
+          </section>
+          <!-- 底部 -->
+        </div>
+  
+        <!-- 页面设置tab -->
+        <div class="decorateTab">
+          <span
+            :class="rightcom === 'decorate' ? 'active' : ''"
+            @click="rightcom = 'decorate'"
+          >
+            <i class="iconfont icon-wangye" />
+            页面设置
+          </span>
+          <span
+            :class="rightcom === 'componenmanagement' ? 'active' : ''"
+            @click="rightcom = 'componenmanagement'"
+          >
+            <i class="iconfont icon-zujian" />
+            组件管理
+          </span>
+          <span
+            class="active"
+            v-show="rightcom != 'componenmanagement' && rightcom != 'decorate'"
+          >
+            <i class="iconfont icon-zujian" />
+            组件设置
+          </span>
+        </div>
+  
+        <!-- 右侧工具栏 -->
+        <div class="decorateAll">
+          <!-- 页面设置 -->
+          <transition name="decorateAnima">
+            <!-- 动态组件 -->
+            <component
+              :is="rightcom"
+              :datas="currentproperties"
+              @componenmanagement="componenmanagement"
+            />
+          </transition>
+        </div>
+      </section>
+      <realTimeView
+        :datas="realTimeView"
+        :val="{
+          id,
+          name: pageSetup.name,
+          templateJson: JSON.stringify(pageSetup),
+          component: JSON.stringify(pageComponents),
+        }"
+      />
+    </div>
+  </template>
+  
+  <script>
+  import utils from '@/utils/asEditor/index' // 方法类
+  import componentProperties from '@/utils/asEditor/componentProperties' // 组件数据
+  import html2canvas from 'html2canvas' // 生成图片
+  import FileSaver from 'file-saver' // 导出JSON
+  
+  export default {
+    name: 'home',
+    inject: ['reload'],
+    data() {
+      return {
+        realTimeView: {
+          show: false, // 是否显示预览
+        },
+        id: null, //当前页面
+        deleShow: true, //删除标签显示
+        index: '', //当前选中的index
+        rightcom: 'decorate', //右侧组件切换
+        currentproperties: {}, //当前属性
+        pageSetup: {
+          // 页面设置属性
+          name: '页面标题', //页面名称
+          details: '', //页面描述
+          isPerson: false, // 是否显示个人中心
+          isBack: true, // 是否返回按钮
+          titleHeight: 35, // 高度
+          bgColor: 'rgba(249, 249, 249, 10)', //背景颜色
+          bgImg: '', // 背景图片
+        },
+        pageComponents: [], //页面组件
+        offsetY: 0, //记录上一次距离父元素高度
+        pointer: { show: false }, //穿透
+        onlyOne: ['1-5', '1-16'], // 只能存在一个的组件(组件的type)
+      }
+    },
+  
+    mounted() {
+      this.pageSetup.name = '页面标题'
+      this.currentproperties = this.pageSetup
+    },
+  
+    methods: {
+      // 查看JSON
+      catJson() {
+        this.$alert(
+          `{
+            <br/>
+            "id": ${this.id},
+            <br/>
+            "name": "${this.pageSetup.name}",
+            <br/>
+            "templateJson": '${JSON.stringify(this.pageSetup)}',
+            <br/>
+            "component": '${JSON.stringify(this.pageComponents)}',
+            <br/>
+          }`,
+          '查看JSON',
+          {
+            confirmButtonText: '确定',
+            customClass: 'JSONView',
+            dangerouslyUseHTMLString: true,
+            callback: () => {},
+          }
+        )
+      },
+      /**
+       * 保存
+       */
+      Preservation() {
+        /* 隐藏border和删除图标 */
+        this.deleShow = false
+        /* 渲染结束截图 */
+        this.$nextTick(() => {
+          /* 截图 */
+          this.toImage()
+        })
+      },
+  
+      /**
+       * 页面截图
+       *
+       * @param {Function} callBack 回调函数
+       */
+      toImage() {
+        /* 加载 */
+        const loading = this.$loading({
+          lock: true,
+          text: '保存中...',
+          spinner: 'el-icon-loading',
+          background: 'rgba(0, 0, 0, 0.7)',
+        })
+  
+        const imageTofiles = document.querySelector('#imageTofile')
+        /* 截图 */
+        html2canvas(this.$refs.imageTofile, {
+          backgroundColor: null,
+          height: imageTofiles.scrollHeight,
+          width: imageTofiles.scrollWidth,
+          useCORS: true,
+        }).then((canvas) => {
+          /* 显示border和删除图标 */
+          this.deleShow = true
+          let url = canvas.toDataURL('image/png')
+          const formData = new FormData()
+          formData.append('base64File', url)
+          console.log(formData, '--------------页面图片formData')
+          loading.close()
+        })
+      },
+  
+      /**
+       * 当将元素或文本选择拖动到有效放置目标(每几百毫秒)上时,会触发此事件
+       *
+       * @param {Object} event event对象
+       */
+      allowDrop(event) {
+        //阻止浏览器的默认事件
+        event.preventDefault()
+  
+        /* 获取鼠标高度 */
+        let eventoffset = event.offsetY
+  
+        /* 如果没有移动不触发事件减少损耗 */
+        if (this.offsetY === eventoffset) return
+        else this.offsetY = eventoffset
+  
+        /* 获取组件 */
+        const childrenObject = event.target.children[0]
+  
+        // 一个以上的组件计算
+        if (this.pageComponents.length) {
+          /* 如果只有一个组件并且第一个是提示组件直接返回 */
+          if (
+            this.pageComponents.length === 1 &&
+            this.pageComponents[0].type === 0
+          )
+            return
+  
+          /* 如果鼠标的高度小于第一个的一半直接放到第一个 */
+          if (eventoffset < childrenObject.children[0].clientHeight / 2) {
+            /* 如果第一个是提示组件直接返回 */
+            if (this.pageComponents[0].type === 0) return
+  
+            /* 删除提示组件 */
+            this.pageComponents = this.pageComponents.filter(
+              (res) => res.component !== 'placementarea'
+            )
+  
+            /* 最后面添加提示组件 */
+            this.pageComponents.unshift({
+              component: 'placementarea',
+              type: 0,
+            })
+  
+            return
+          }
+  
+          /* 记录距离父元素高度 */
+          const childOff = childrenObject.offsetTop
+  
+          /* 鼠标在所有组件下面 */
+          if (
+            eventoffset > childrenObject.clientHeight ||
+            childrenObject.lastChild.offsetTop -
+              childOff +
+              childrenObject.lastChild.clientHeight / 2 <
+              eventoffset
+          ) {
+            /* 最后一个组件是提示组件返回 */
+            if (this.pageComponents[this.pageComponents.length - 1].type === 0)
+              return
+  
+            /* 清除提示组件 */
+            this.pageComponents = this.pageComponents.filter(
+              (res) => res.component !== 'placementarea'
+            )
+  
+            /* 最后一个不是提示组件添加 */
+            this.pageComponents.push({
+              component: 'placementarea',
+              type: 0,
+            })
+  
+            return
+          }
+  
+          const childrens = childrenObject.children
+  
+          /* 在两个组件中间,插入 */
+          for (let i = 0, l = childrens.length; i < l; i++) {
+            const childoffset = childrens[i].offsetTop - childOff
+  
+            if (childoffset + childrens[i].clientHeight / 2 > event.offsetY) {
+              /* 如果是提示组件直接返回 */
+              if (this.pageComponents[i].type === 0) break
+  
+              if (this.pageComponents[i - 1].type === 0) break
+  
+              /* 清除提示组件 */
+              this.pageComponents = this.pageComponents.filter(
+                (res) => res.component !== 'placementarea'
+              )
+  
+              this.pageComponents.splice(i, 0, {
+                component: 'placementarea',
+                type: 0,
+              })
+              break
+            } else if (childoffset + childrens[i].clientHeight > event.offsetY) {
+              if (this.pageComponents[i].type === 0) break
+  
+              if (
+                !this.pageComponents[i + 1] ||
+                this.pageComponents[i + 1].type === 0
+              )
+                break
+  
+              this.pageComponents = this.pageComponents.filter(
+                (res) => res.component !== 'placementarea'
+              )
+  
+              this.pageComponents.splice(i, 0, {
+                component: 'placementarea',
+                type: 0,
+              })
+  
+              break
+            }
+          }
+        } else {
+          /* 一个组件都没有直接push */
+          this.pageComponents.push({
+            component: 'placementarea',
+            type: 0,
+          })
+        }
+      },
+  
+      /**
+       * 当在有效放置目标上放置元素或选择文本时触发此事件
+       *
+       * @param {Object} event event对象
+       */
+      drop(event) {
+        /* 获取数据 */
+        let data = utils.deepClone(
+          componentProperties.get(event.dataTransfer.getData('componentName'))
+        )
+  
+        /* 查询是否只能存在一个的组件且在第一个 */
+        let someOne = this.pageComponents.some((item, index) => {
+          return (
+            item.component === 'placementarea' &&
+            index === 0 &&
+            this.onlyOne.includes(data.type)
+          )
+        })
+        if (someOne) {
+          this.$message.info('固定位置的组件(如: 底部导航、悬浮)不能放在第一个!')
+          /* 删除提示组件 */
+          this.dragleaves()
+          return
+        }
+  
+        /* 查询是否只能存在一个的组件 */
+        let someResult = this.pageComponents.some((item) => {
+          return (
+            this.onlyOne.includes(item.type) &&
+            item.component === event.dataTransfer.getData('componentName')
+          )
+        })
+        if (someResult) {
+          this.$message.info('当前组件只能添加一个!')
+          /* 删除提示组件 */
+          this.dragleaves()
+          return
+        }
+  
+        /* 替换 */
+        utils.forEach(this.pageComponents, (res, index) => {
+          /* 修改选中 */
+          if (res.active === true) res.active = false
+          /* 替换提示 */
+          this.index = index
+          if (res.component === 'placementarea')
+            this.$set(this.pageComponents, index, data)
+        })
+  
+        /* 切换组件 */
+        this.rightcom = data.style
+        /* 丢样式 */
+        this.currentproperties = data.setStyle
+  
+        console.log(
+          data,
+          this.rightcom,
+          this.currentproperties,
+          '----------components data'
+        )
+      },
+  
+      /**
+       * 当拖动的元素或文本选择离开有效的放置目标时,会触发此事件
+       *
+       * @param {Object} event event对象
+       */
+      dragleaves() {
+        /* 删除提示组件 */
+        this.pageComponents = this.pageComponents.filter(
+          (res) => res.component !== 'placementarea'
+        )
+      },
+  
+      /**
+       * 切换组件位置
+       *
+       * @param {Object} res 组件切换后返回的位置
+       */
+      componenmanagement(res) {
+        this.pageComponents = res
+      },
+  
+      /**
+       * 选择组件
+       *
+       * @param {Object} res 当前组件对象
+       */
+      activeComponent(res, index) {
+        this.index = index
+        /* 切换组件 */
+        this.rightcom = res.style
+        /* 丢样式 */
+        this.currentproperties = res.setStyle
+  
+        /* 替换 */
+        utils.forEach(this.pageComponents, (res) => {
+          /* 修改选中 */
+          if (res.active === true) res.active = false
+        })
+  
+        /* 选中样式 */
+        res.active = true
+      },
+  
+      /**
+       * 标题切换
+       *
+       * @param {Object} res 当前组件对象
+       */
+      headTop() {
+        this.rightcom = 'decorate'
+  
+        /* 替换 */
+        utils.forEach(this.pageComponents, (res) => {
+          /* 修改选中 */
+          if (res.active === true) res.active = false
+        })
+      },
+  
+      /* 删除组件 */
+      deleteObj(index) {
+        this.pageComponents.splice(index, 1)
+        if (this.index === index) this.rightcom = 'decorate'
+        if (index < this.index) this.index = this.index - 1
+      },
+  
+      /* 页面刷新 */
+      reloads() {
+        this.$confirm('重置后您添加或者修改的数据将会失效, 是否继续?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning',
+        })
+          .then(() => {
+            this.reload()
+          })
+          .catch(() => {})
+      },
+  
+      // 返回上一步
+      Previous() {
+        this.$confirm('返回列表您添加或者修改的数据将会失效, 是否继续?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning',
+        })
+          .then(() => {
+            this.$router.go(-1)
+          })
+          .catch(() => {})
+      },
+  
+      // 导出json
+      exportJSON() {
+        // 将json转换成字符串
+        const data = JSON.stringify({
+          id: this.id,
+          name: this.pageSetup.name,
+          templateJson: JSON.stringify(this.pageSetup),
+          component: JSON.stringify(this.pageComponents),
+        })
+        const blob = new Blob([data], { type: '' })
+        FileSaver.saveAs(blob, `${this.pageSetup.name}.json`)
+      },
+      // 导入json
+      importJSON() {
+        const file = document.getElementById('file').files[0]
+        const reader = new FileReader()
+        reader.readAsText(file)
+        let _this = this
+        reader.onload = function () {
+          // this.result为读取到的json字符串,需转成json对象
+          let ImportJSON = JSON.parse(this.result)
+          // 检测是否导入成功
+          console.log(ImportJSON, '-----------------导入成功')
+          // 导入JSON数据
+          _this.id = ImportJSON.id
+          _this.pageSetup = JSON.parse(ImportJSON.templateJson)
+          _this.pageComponents = JSON.parse(ImportJSON.component)
+        }
+      },
+    },
+  
+    watch: {
+      /* 监听右侧属性设置切换 */
+      rightcom(newval) {
+        if (newval === 'decorate') {
+          utils.forEach(this.pageComponents, (res) => {
+            /* 修改选中 */
+            if (res.active === true) res.active = false
+          })
+          this.currentproperties = this.pageSetup
+          return
+        }
+        if (newval === 'componenmanagement') {
+          /* 替换 */
+          utils.forEach(this.pageComponents, (res) => {
+            /* 修改选中 */
+            if (res.active === true) res.active = false
+          })
+          this.currentproperties = this.pageComponents
+        }
+      },
+    },
+  }
+  </script>
+  
+  <style lang="scss" scoped>
+  .pointer-events {
+    pointer-events: none;
+  }
+  
+  .home-as-editor {
+    width: 100%;
+    height: 100%;
+  
+    /* 删除组件 */
+    .deles {
+      position: absolute;
+      min-width: 80px;
+      text-align: center;
+      line-height: 25px;
+      background: #fff;
+      height: 25px;
+      font-size: 12px;
+      left: 103%;
+      top: 50%;
+      transform: translateY(-50%);
+      .icon-sanjiaoxingzuo {
+        position: absolute;
+        left: -11px;
+        color: #fff;
+        font-size: 12px;
+        top: 50%;
+        transform: translateY(-50%);
+      }
+      &:hover {
+        i {
+          display: block;
+          position: absolute;
+          left: 0;
+          font-size: 16px;
+          top: 0;
+          text-align: center;
+          line-height: 25px;
+          width: 100%;
+          color: #fff;
+          height: 100%;
+          z-index: 10;
+          background: rgba(0, 0, 0, 0.5);
+        }
+        .icon-sanjiaoxingzuo {
+          color: rgba(0, 0, 0, 0.5);
+        }
+      }
+  
+      i {
+        display: none;
+      }
+    }
+  
+    /* 按钮集合 */
+    .buttons {
+      height: 8%;
+      border-bottom: 1px solid #ebedf0;
+      display: flex;
+      justify-content: space-between;
+      box-sizing: border-box;
+      padding-right: 15px;
+      align-items: center;
+      /* 下拉 */
+      .frop {
+        padding-right: 15px;
+        .el-button.el-button--primary.el-dropdown-selfdefine {
+          background: #fff;
+          color: #000;
+          border: 1px solid #dcdee0;
+        }
+      }
+      .el-button {
+        font-size: 14px;
+        padding: 0 16px;
+        height: 30px;
+        &.el-button--primary {
+          background: #155bd4;
+        }
+        &.el-button--danger {
+          background: red;
+        }
+      }
+    }
+  
+    /* 操作主体 */
+    .operation {
+      width: 100%;
+      height: 92%;
+      display: flex;
+      flex-direction: row;
+      justify-content: space-between;
+      background: #f7f8fa;
+    }
+  
+    /* 手机 */
+    .phone {
+      width: 55%;
+      height: 100%;
+      overflow-y: scroll;
+      display: flex;
+      justify-content: center;
+      background: #f7f8fa;
+      &::-webkit-scrollbar {
+        width: 1px;
+      }
+      // &::-webkit-scrollbar-thumb {
+      //   background-color: #155bd4;
+      // }
+  
+      /* 手机样式 */
+      .phoneAll {
+        width: 375px;
+        min-height: 760px;
+        box-shadow: 0 0 14px 0 rgba(0, 0, 0, 0.1);
+        margin: 45px 0;
+        position: relative;
+  
+        /* 手机高度 */
+        .phoneSize {
+          position: absolute;
+          left: -137px;
+          top: 640px;
+          font-size: 12px;
+          color: #a2a2a2;
+          border-bottom: 1px solid #dedede;
+          width: 130px;
+          height: 21px;
+          line-height: 21px;
+        }
+  
+        /* 状态栏 */
+        .statusBar {
+          width: 100%;
+          display: block;
+        }
+  
+        /* 主体内容 */
+        .phone-container {
+          min-height: 603px;
+          box-sizing: border-box;
+          cursor: pointer;
+          width: 100%;
+          position: relative;
+          background-repeat: no-repeat;
+          background-size: 100% 100%;
+          .componentsClass {
+            border: 1px solid #fff;
+            &:hover {
+              border: 1px dashed #155bd4;
+            }
+          }
+        }
+      }
+    }
+  
+    /* 右侧工具栏 */
+    .decorateAll {
+      width: 376px;
+      height: 100%;
+      overflow-y: scroll;
+      overflow-x: hidden;
+      position: relative;
+      padding: 0 12px;
+      background: #fff;
+      &::-webkit-scrollbar {
+        width: 1px;
+      }
+      &::-webkit-scrollbar-thumb {
+        background-color: #155bd4;
+      }
+    }
+  
+    /* 页面设置tab */
+    .decorateTab {
+      position: fixed;
+      display: flex;
+      right: 380px;
+      top: 115px;
+      flex-direction: column;
+      span {
+        background-color: #fff;
+        box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.1);
+        border-radius: 2px;
+        width: 94px;
+        height: 32px;
+        display: inline-block;
+        text-align: center;
+        line-height: 32px;
+        margin-bottom: 12px;
+        transition: all 0.8s;
+        cursor: pointer;
+        &.active {
+          background-color: #155bd4;
+          color: #fff;
+        }
+        /* 图标 */
+        i {
+          font-size: 12px;
+          margin-right: 5px;
+        }
+      }
+    }
+  }
+  
+  /* 动画 */
+  .decorateAnima-enter-active {
+    transition: all 1.5s ease;
+  }
+  .decorateAnima-leave-active {
+    transition: all 1.5s ease;
+  }
+  .decorateAnima-enter {
+    transform: translate(8px, 8px);
+    opacity: 0;
+  }
+  .decorateAnima-leave-to {
+    transform: translate(8px, 8px);
+    opacity: 0;
+  }
+  </style>
+  

+ 398 - 0
src/utils/asEditor/componentProperties.js

@@ -0,0 +1,398 @@
+const componentProperties = new Map()
+
+// 数据版本  每次修改组件数据  需要对版本进行修改
+// componentProperties.set('componentPropertiesVersion', 'V1.0.0')
+
+componentProperties.set('captiontext', {
+  component: 'captiontext',
+  text: '标题文字',
+  type: '1-3',
+  active: true,
+  style: 'captiontextsstyle',
+  setStyle: {
+    text: '标题文字',
+    name: '标题文字',//标题内容
+    description: '',//描述内容
+    wordSize: 16,//标题大小
+    descriptionSize: 12,//描述大小
+    wordWeight: 400,//标题粗细
+    positions: 'left', //显示位置  可选left/center
+    descriptionWeight: 200,//描述粗细
+    wordColor: 'rgba(50, 50, 51, 10)',//标题颜色
+    descriptionColor: 'rgba(150, 151, 153, 10)',//描述颜色
+    backColor: 'rgba(255, 255, 255, 10)', //背景颜色
+    borderBott: false, //底部分割线
+    wordHeight: 24,//框体高度
+    more: {    //查看更多
+      show: false,//是否显示查看更多
+      type: 1, // 样式选择
+      text: '查看更多', //自定义文字
+      httpType: 10,//链接类型
+      http: '',//链接
+    },
+  },
+})
+
+componentProperties.set('listswitching', {
+  component: 'listswitching',
+  text: '商品',
+  type: '2-1',
+  active: true,
+  style: 'listswitchingstyle',
+  setStyle: {
+    text: '商品',
+    commodityType: 0,
+    moditystyle: 0,
+    borderRadius: 0,
+    pageMargin: 15,
+    commodityMargin: 10,
+    textWeight: 400,
+    positions: 'left',
+    priceofcommodity: true,
+    purchasebutton: true,
+    commoditycorner: true,
+    purchasebuttonType: 0,
+    commoditycornertype: 0,
+    commodityTagColor: '#07c160',
+    tagPosition: 0,
+    imageList: [],
+    purchase: '马上抢',
+    commoditylisttype: 0,
+    commoditylisttypetab: [
+      {
+        text: '分组',
+        imageList: [],
+      },
+      {
+        text: '分组',
+        imageList: [],
+      },
+    ],
+    tabColor: '#f39800',
+    showMore: false,
+    moreUrl: null,
+    bgImg: '',
+  },
+})
+
+componentProperties.set('pictureads', {
+  component: 'pictureads',
+  text: '图片广告',
+  type: '1-3',
+  active: true,
+  style: 'pictureadsstyle',
+  setStyle: {
+    text: '图片广告',
+    swiperType: 0,  // 选择模板
+    borderRadius: 0,// 图片倒角
+    pageMargin: 0,  // 页面边距
+    imageMargin: 0, // 图片边距
+    pagingType: 0,  // 分页类型: 0/"bullets"/"fraction"/"progressbar"
+    rowindividual: 2,// 一行个数
+    imageList: [],  // 添加图片
+  },
+})
+
+componentProperties.set('graphicnavigation', {
+  component: 'graphicnavigation',
+  text: '图文导航',
+  type: '1-4',
+  active: true,
+  style: 'graphicnavigationstyle',
+  setStyle: {
+    text: '图文导航',
+    imageList: [], // 图片导航列表
+    navigationType: 0, //图片导航类型
+    imgStyle: 0, //图片样式
+    backgroundColor: 'rgb(255, 255, 255)', //背景颜色
+    textColor: 'rgb(0, 0, 0)', //文字颜色
+    borderRadius: 0, //图片倒角
+    showSize: 5, //一屏显示个数
+    textHeight: 24, // 字体高度
+    textSize: 12, // 字体大小
+    bgImg: '',
+  },
+})
+
+componentProperties.set('richtext', {
+  component: 'richtext',
+  text: '富文本',
+  type: '1-10',
+  active: true,
+  style: 'richtextstyle',
+  setStyle: {
+    text: '富文本',
+    myValue: '', //富文本内容
+    backColor: 'rgb(249, 249, 249)', //背景颜色
+  },
+})
+componentProperties.set('magiccube', {
+  component: 'magiccube',
+  text: '魔方',
+  type: '1-6',
+  active: true,
+  style: 'magiccubestyle',
+  setStyle: {
+    text: '魔方',
+    rubiksCubeType: 0, // 魔方类型
+    pageMargin: 0, //页面间距
+    imgMargin: 0, //图片间隙
+    imageList: [
+      {
+        src: '',
+        linktype: '10',
+        http: {},
+      },
+      {
+        src: '',
+        linktype: '10',
+        http: {},
+      },
+      {
+        src: '',
+        linktype: '10',
+        http: {},
+      },
+      {
+        src: '',
+        linktype: '10',
+        http: {},
+      },
+      {
+        src: '',
+        linktype: '10',
+        http: {},
+      },
+    ], //图片列表
+  },
+})
+componentProperties.set('auxiliarysegmentation', {
+  component: 'auxiliarysegmentation',
+  text: '辅助分割',
+  type: '1-11',
+  active: true,
+  style: 'auxiliarysegmentationstyle',
+  setStyle: {
+    text: '辅助分割',
+    blankHeight: 30, //空白高度
+    segmentationtype: 0, //分割类型
+    paddType: 0, //边距
+    auxliarColor: 'rgb(229, 229, 229)', //辅助线颜色
+    bordertp: 'solid', //线的类型
+  },
+})
+componentProperties.set('commoditysearch', {
+  component: 'commoditysearch',
+  text: '商品搜索',
+  type: '1-1',
+  active: true,
+  style: 'commoditysearchstyle',
+  setStyle: {
+    text: '商品搜索',
+    heights: 28, //搜索栏高度
+    position: 0, //显示位置
+    sweep: false, // 显示扫一扫
+    borderRadius: 0, //框体样式
+    textPosition: 0, //文本位置
+    backgroundColor: 'rgb(249, 249, 249)', //背景颜色
+    borderColor: 'rgb(255, 255, 255)', //框体颜色
+    textColor: 'rgb(150, 151, 153)', //字体颜色
+    hotords: [], //热词
+  },
+})
+componentProperties.set('storeinformation', {
+  component: 'storeinformation',
+  text: '店铺信息',
+  type: '1-12',
+  active: true,
+  style: 'storeinformationstyle',
+  setStyle: {
+    text: '店铺信息',
+    bakcgroundImg: '', //背景图片
+    headPortrait: '', //店铺头像
+    rubiksCubeType: 0, //类型
+    name: '店铺名称', //店铺名称
+    Discount: '在线支付满150减30,满100减20', //优惠信息
+  },
+})
+componentProperties.set('entertheshop', {
+  component: 'entertheshop',
+  text: '单元格',
+  type: '1-13',
+  active: true,
+  style: 'entertheshopstyle',
+  setStyle: {
+    text: '单元格',
+    icon: '', // 左侧图标
+    shopName: '左侧标题',
+    copywriting: '右侧内容',
+    type: '10',
+    http: {},
+  },
+})
+componentProperties.set('notice', {
+  component: 'notice',
+  text: '公告',
+  type: '1-7',
+  active: true,
+  style: 'noticestyle',
+  setStyle: {
+    text: '公告',
+    noticeText: '请填写内容,如果过长,将会在手机上滚动显示', //内容
+    backColor: 'rgb(255, 248, 233)', //背景颜色
+    textColor: 'rgba(100, 101, 102)', //文字颜色
+  },
+})
+componentProperties.set('videoss', {
+  component: 'videoss',
+  text: '视频',
+  type: '1-8',
+  active: true,
+  style: 'videostyle',
+  setStyle: {
+    text: '视频',
+    src: 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4', // 视频地址
+    coverUrl:null, // 封面地址
+    autoplay: false, // 是否自动播放
+  },
+})
+
+componentProperties.set('custommodule', {
+  component: 'custommodule',
+  text: '自定义模块',
+  type: 'demo',
+  active: true,
+  style: 'custommodulestyle',
+  setStyle: {
+    text: '自定义模块',
+    demo:'自定义内容',
+    img:'https://img2.baidu.com/it/u=1905875968,4289754134&fm=26&fmt=auto&gp=0.jpg'
+  },
+})
+componentProperties.set('communitypowder', {
+  component: 'communitypowder',
+  text: '社群涨粉',
+  type: '1-14',
+  active: true,
+  style: 'communitypowderstyle',
+  setStyle: {
+    text: '社群涨粉',
+    mainImg: '', //入口图片
+    qrcodeImg: '', //二维码
+    title: '标题', //标题
+    describe: '辅助描述', //描述
+    buttonName: '立即添加', //按钮名称
+    backColor: 'rgb(255, 255, 255)', //背景颜色
+  },
+})
+componentProperties.set('storenotecard', {
+  component: 'storenotecard',
+  text: '文章模块',
+  type: '2-2',
+  active: true,
+  style: 'storenotecardstyle',
+  setStyle: {
+    text: '文章模块',
+    name: '这里显示专题名称', //专题名称
+    commodityType: 0, // 选择模板
+    moditystyle: 0, // 卡片样式选择
+    borderRadius: 0, // 图片边角
+    textWeight: 400, // 标题粗细
+    noteLabels: true, // 笔记标签
+    readingNumber: true, // 阅读数
+    praisePoints: true, //点赞数
+    viewMore1: true, //更多1
+    viewMore2: true, //更多2
+    imageList: [],
+    positions: 'bottom', //标题位置
+    linktype: '10',
+    http: {},
+  },
+})
+componentProperties.set('crowdoperation', {
+  component: 'crowdoperation',
+  text: '人群运营',
+  type: '1-17',
+  active: true,
+  style: 'crowdoperationstyle',
+  setStyle: {
+    text: '人群运营',
+  },
+})
+componentProperties.set('personalizedrecommendation', {
+  component: 'personalizedrecommendation',
+  text: '个性化推荐',
+  type: '1-18',
+  active: true,
+  style: 'personalizedrecommendationstyle',
+  setStyle: {
+    text: '个性化推荐',
+  },
+})
+componentProperties.set('onlineservice', {
+  component: 'onlineservice',
+  text: '在线客服',
+  type: '1-19',
+  active: true,
+  style: 'onlineservicestyle',
+  setStyle: {
+    text: '在线客服',
+  },
+})
+componentProperties.set('investigate', {
+  component: 'investigate',
+  text: '表单模块',
+  type: '2-3',
+  active: true,
+  style: 'investigatestyle',
+  setStyle: {
+    text: '表单模块',
+    title: '表单模块',
+    jsonData: [], //value1为sass显示内容,value2为前端显示内容
+  },
+})
+componentProperties.set('tabBar', {
+  component: 'tabBar',
+  text: '底部导航',
+  type: '1-5',
+  active: true,
+  style: 'tabBarStyle',
+  setStyle: {
+    text: '底部导航',
+    activeColor: '#1989fa',
+    inactiveColor: '#7d7e80',
+    isShowBorder: true,
+    iconWidth: '25',
+    iconHeight: '25',
+    fontSize: '14',
+    Highlight: 0,
+    iconList: [],
+  },
+})
+componentProperties.set('follow', {
+  component: 'follow',
+  text: '关注公众号',
+  type: '1-15',
+  active: true,
+  style: 'followStyle',
+  setStyle: {
+    text: '关注公众号',
+    heade: 'https://imgs.starfirelink.com/miniShop//logo_1618466110849.png',
+    followName: '公众号名称',
+    followAppId: '',
+  },
+})
+componentProperties.set('suspension', {
+  component: 'suspension',
+  text: '悬浮按钮',
+  type: '1-16',
+  active: true,
+  style: 'suspensionstyle',
+  setStyle: {
+    text: '悬浮按钮',
+    linktype: '10',
+    http: {},
+  },
+})
+
+export default componentProperties

+ 27 - 0
src/utils/asEditor/filter.js

@@ -0,0 +1,27 @@
+/**
+ * 定义全局过滤器
+ *
+ * 时间戳转换日期
+ *
+ */
+
+let globalFilter = {
+  // 时间戳转换日期
+  formatDate: (value) => {
+    let date = new Date(value)
+    let y = date.getFullYear()
+    let MM = date.getMonth() + 1
+    MM = MM < 10 ? '0' + MM : MM
+    let d = date.getDate()
+    d = d < 10 ? '0' + d : d
+    let h = date.getHours()
+    h = h < 10 ? '0' + h : h
+    let m = date.getMinutes()
+    m = m < 10 ? '0' + m : m
+    let s = date.getSeconds()
+    s = s < 10 ? '0' + s : s
+    return y + '-' + MM + '-' + d + ' ' + h + ':' + m + ':' + s
+  },
+}
+
+export default globalFilter

+ 126 - 0
src/utils/asEditor/index.js

@@ -0,0 +1,126 @@
+class utils {
+  /**
+   *
+   * 时间戳转换日期
+   *
+   * @param {String} value 传入的时间戳
+   * @param {String} String 返回的时间
+   */
+  formatDate(value) {
+    let date = new Date(value)
+    let y = date.getFullYear()
+    let MM = date.getMonth() + 1
+    MM = MM < 10 ? '0' + MM : MM
+    let d = date.getDate()
+    d = d < 10 ? '0' + d : d
+    let h = date.getHours()
+    h = h < 10 ? '0' + h : h
+    let m = date.getMinutes()
+    m = m < 10 ? '0' + m : m
+    let s = date.getSeconds()
+    s = s < 10 ? '0' + s : s
+    return y + '-' + MM + '-' + d + ' ' + h + ':' + m + ':' + s
+  }
+
+  /**
+   * 循环对象
+   *
+   * @param {Object|Array} obj 传入的值
+   * @param {Function} fn 为每个项调用的回调
+   */
+  forEach(obj, fn) {
+    if (obj === null || typeof obj === 'undefined') return
+
+    // 如果还没有可写的东西,就强制一个数组
+    if (typeof obj !== 'object') obj = [obj]
+
+    if (this.isArray(obj)) {
+      // 数组循环
+      for (var i = 0, l = obj.length; i < l; i++) {
+        fn.call(null, obj[i], i, obj)
+      }
+    } else {
+      // 对象循环
+      for (var key in obj) {
+        /* 是否具有键 */
+        if (Object.prototype.hasOwnProperty.call(obj, key)) {
+          fn.call(null, obj[key], key, obj)
+        }
+      }
+    }
+  }
+
+  /**
+   * 确定值是否为数组
+   *
+   * @param {Object} val 传入的值
+   * @returns {boolean} 如果值是数组,则为True,否则为false
+   */
+  isArray(val) {
+    return Object.prototype.toString.call(val) === '[object Array]'
+  }
+
+  /**
+   * 确定值是否为对象
+   *
+   * @param {Object} obj 传入的对象
+   * @returns {String} 返回类型
+   */
+  getObjClass(obj) {
+    return Object.prototype.toString.call(obj).slice(8, -1)
+  }
+
+  /**
+   * 深度克隆
+   *
+   * @param {Object} obj 传入需要克隆的对象
+   * @returns {Object} 返回克隆好的对象
+   */
+  deepClone(obj) {
+    let result
+    let objClass = this.getObjClass(obj)
+
+    if (objClass === 'Object') {
+      result = {}
+    } else if (objClass === 'Array') {
+      result = []
+    } else {
+      return obj // 如果是其他数据类型不复制,直接将数据返回
+    }
+
+    // 遍历目标对象
+    for (let key in obj) {
+      let value = obj[key]
+      result[key] = this.deepClone(value)
+    }
+
+    return result
+  }
+
+
+  /**
+   * 递归合并两个对象
+   *
+   * @param {*} target
+   * @param {*} sources
+   * @return {*}
+   * @memberof Common
+   */
+  assiginObj(target, sources) {
+    let obj = target
+    if (typeof target != 'object' || typeof sources != 'object' || typeof target) {
+      return sources // 如果其中一个不是对象 就返回sources
+    }
+    for (let key in sources) {
+      if (target.hasOwnProperty(key)) {
+        obj[key] = this.assiginObj(target[key], sources[key])
+      } else {
+        // 不存在就直接添加
+        obj[key] = sources[key]
+      }
+    }
+    return obj
+  }
+}
+
+export default new utils()

+ 37 - 0
src/utils/asEditor/upload.js

@@ -0,0 +1,37 @@
+const COS = require('cos-js-sdk-v5')
+// 填写自己腾讯云cos中的key和id (密钥)
+// https://console.cloud.tencent.com/cam/capi
+const cos = new COS({
+  SecretId: 'AKIDzmJbcMozu2tTmoZ3FBpCI7fwxjDRO4Tb',
+  SecretKey: 'sTptgCRP5UhcHfoiKfjWyEEzUjiRvA9s',
+})
+
+
+// 腾讯云COS上传文件方法  参数为file文件对象
+export const uploadCOS = (file) => {
+  return new Promise((resolve, reject) => {
+    if (file) {
+      // 执行上传操作
+      cos.putObject(
+        {
+          Bucket: 'git-1304113371' /* 存储桶 */,
+          Region: 'ap-nanjing' /* 存储桶所在地域,必须字段 */,
+          Key: file.name /* 文件名 */,
+          StorageClass: 'STANDARD', // 上传模式, 标准模式
+          Body: file, // 上传文件对象
+          onProgress: (progressData) => {
+            // 上传进度
+            console.log(JSON.stringify(progressData))
+          },
+        },
+        (err, data) => {
+          // 上传成功之后
+          if (data.statusCode === 200) {
+            resolve(`https://${data.Location}`)
+          }
+          if (err) reject(err)
+        }
+      )
+    }
+  })
+}

+ 65 - 30
src/views/tourism/marketingActivities/couponManagement.vue

@@ -4,18 +4,18 @@
         <!--用户数据-->
         <el-col :span="24" :xs="24">
           <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
-            <el-form-item label="批次号" prop="realName">
+            <el-form-item label="批次号" prop="couponBatch">
               <el-input
-                v-model="queryParams.realName"
+                v-model="queryParams.couponBatch"
                 placeholder="请输入批次号"
                 clearable
                 style="width: 240px"
                 @keyup.enter.native="handleQuery"
               />
             </el-form-item>
-            <el-form-item label="优惠卷名称" prop="memberCode" label-width="88px">
+            <el-form-item label="优惠卷名称" prop="couponName" label-width="88px">
               <el-input
-                v-model="queryParams.memberCode"
+                v-model="queryParams.couponName"
                 placeholder="请输入优惠卷名称"
                 clearable
                 style="width: 240px"
@@ -29,34 +29,61 @@
           </el-form>
   
           <el-row :gutter="10" class="mb8">
+            <el-col :span="1.5">
+              <el-button
+                type="primary"
+                plain
+                icon="el-icon-plus"
+                size="mini"
+                @click="handleAdd"
+                v-hasPermi="configPermi.add"
+              >新增</el-button>
+            </el-col>
             <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
           </el-row>
   
           <el-table v-loading="loading" :data="tableList" @selection-change="handleSelectionChange">
             <el-table-column type="index" label="序号" align="center"  />
-            <el-table-column label="优惠券名称" align="center" key="realName" prop="realName" v-if="columns[0].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="券种类型" align="center" key="type" prop="type" v-if="columns[1].visible" :show-overflow-tooltip="true">
+            <el-table-column label="批次号" align="center" key="couponBatch" prop="couponBatch" v-if="columns[0].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="优惠券名称" align="center" key="couponName" prop="couponName" v-if="columns[1].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="券种类型" align="center" key="type" prop="type" v-if="columns[2].visible" :show-overflow-tooltip="true">
               <template slot-scope="scope">
-                <dict-tag :options="dict.type.tourism_memberInformation_user_type" :value="scope.row.type"/>
+                <dict-tag :options="dict.type.tourism_couponManagement_type" :value="scope.row.type"/>
               </template>
             </el-table-column>
-            <el-table-column label="券种说明" align="center" key="levelName" prop="levelName" v-if="columns[2].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="发放数量" align="center" key="mobile" prop="mobile" v-if="columns[3].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="适用对象" align="center" key="cardId" prop="cardId" v-if="columns[4].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="领取限制" align="center" key="credit" prop="credit" v-if="columns[5].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="使用有效期" align="center" key="balance" prop="balance" v-if="columns[6].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="适用产品" align="center" key="buyCount" prop="buyCount" v-if="columns[7].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="已领取统计" align="center" key="consumeTotal" prop="consumeTotal" v-if="columns[8].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="创建时间" align="center" key="consumeTotal1" prop="consumeTotal1" v-if="columns[9].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="禁用/启用" align="center" key="status" v-if="columns[10].visible">
+            <el-table-column label="券种说明" align="center" key="remark" prop="remark" v-if="columns[3].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="发放数量(张)" align="center" key="issuseNum" prop="issuseNum" v-if="columns[4].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="使用对象" align="center" key="useUserType" prop="useUserType" v-if="columns[5].visible" :show-overflow-tooltip="true">
+              <template slot-scope="scope">
+                <dict-tag :options="dict.type.tourism_couponManagement_useUserType" :value="scope.row.useUserType"/>
+              </template>
+            </el-table-column>
+            <el-table-column label="领取限制" align="center" key="receiveNum" prop="receiveNum" v-if="columns[6].visible" :show-overflow-tooltip="true">
+              <template slot-scope="scope">
+                <span>{{ `每人限领取${scope.row.receiveNum}张` }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="使用有效期" align="center" key="balance" prop="balance" v-if="columns[7].visible" :show-overflow-tooltip="true">
+              <template slot-scope="scope">
+                <span>{{ setReceiveNum(scope.row) }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="适用产品" align="center" key="useConfig" prop="useConfig" v-if="columns[8].visible" :show-overflow-tooltip="true">
+              <template slot-scope="scope">
+                <dict-tag :options="dict.type.tourism_couponManagement_useConfig" :value="scope.row.useConfig"/>
+              </template>
+            </el-table-column>
+            <el-table-column label="已领取统计(张)" align="center" key="receiveCouponNum" prop="receiveCouponNum" v-if="columns[9].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="创建时间" align="center" key="createTime" prop="createTime" v-if="columns[10].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="禁用/启用" align="center" key="status" v-if="columns[11].visible">
               <template slot-scope="scope">
                 <switchBox 
                 :defaultChecked="true" 
                 v-model="scope.row.status" 
                 @changeFun="openAttraction(scope.row)" 
                 :disabled="false"
-                :active-value="1"
-                :inactive-value="0"
+                :active-value="2"
+                :inactive-value="1"
                  />
               </template>
             </el-table-column>
@@ -112,13 +139,13 @@
   import { 
     listTableApi, 
     delTableParamsApi,
-    addTableApi
+    updateTableApi
   } from "@/api/CURD";
   import detailsBox from "./detailsBox/couponManagementDetails.vue"
   import addAndEdit from "./formBox/couponManagementForm.vue"
   export default {
     name: "User",
-    dicts: ['tourism_memberInformation_user_type','tourism_memberInformation_status','tourism_memberInformation_sex'],
+    dicts: ['tourism_couponManagement_type','tourism_couponManagement_useType','tourism_couponManagement_useConfig','tourism_couponManagement_useUserType'],
     components: {detailsBox,addAndEdit},
     data() {
       return {
@@ -132,12 +159,12 @@
           export: [''],// 导出权限
         },
         configUrl: {
-          list: '/member/memberInfo/list', // 列表地址
-          delect: '', // 删除地址
+          list: '/merchant/merchantCouponInfo/pageList', // 列表地址
+          delect: '/merchant/merchantCouponInfo/deleteById', // 删除地址
           upload: '',// 导入地址
           download:'', // 下载模板地址
           export: '',// 导出地址
-          updateStatus: '', // 编辑地址
+          updateStatus: '/merchant/merchantCouponInfo/updateStatus', // 编辑地址
         },
         // 遮罩层
         loading: true,
@@ -161,6 +188,7 @@
         dateRange: [],
         // 控制列表是否显示
         columns: [
+          { key: -1, label: `批次号`, visible: true },
           { key: 0, label: `优惠券名称`, visible: true },
           { key: 1, label: `券种类型`, visible: true },
           { key: 2, label: `券种说明`, visible: true },
@@ -238,7 +266,6 @@
       /** 删除按钮操作 */
       handleDelete(row) {
         const ids = row.id || this.ids;
-        return
         this.$modal.confirm('是否确认删除数据项?').then( () => {
           return delTableParamsApi(this.configUrl.delect,{
             id: ids
@@ -272,20 +299,28 @@
       },
       /** 开/闭 园 */
       openAttraction(row) {
-        console.log("row======",row)
-        return
-        this.$modal.confirm(`是否确认${row.status == 0 ? '启用' : '禁用'} ${row.realName||''}吗?`).then( () => {
-          return addTableApi(this.configUrl.updateStatus,{
+        this.$modal.confirm(`是否确认${row.status == 1 ? '启用' : '禁用'} ${row.realName||''}吗?`).then( () => {
+          return updateTableApi(this.configUrl.updateStatus,{
             id: row.id,
-            status: row.status == 1 ? 0 : 1
+            status: row.status == 1 ? 2 : 1
           });
         }).then(() => {
           this.getList();
-          this.$modal.msgSuccess(`${row.status == 0 ? '启用' : '禁用'}成功`);
+          this.$modal.msgSuccess(`${row.status == 1 ? '启用' : '禁用'}成功`);
         }).catch((e) => {
           console.error("失败====",e)
         });
       },
+      /** 使用有效期  */
+      setReceiveNum(row) {
+        let src = ''
+        if(row.useType == 1) {
+          src =  `指定周期${row.useStartDate}-${row.useEndDate}内使用`
+        }else if(row.useType == 2) {
+          src =  `领取当日起${row.useDay}天内使用`
+        }
+        return src?src:'-'
+      }
     }
   };
   </script>

+ 25 - 20
src/views/tourism/marketingActivities/couponVerification.vue

@@ -4,36 +4,36 @@
         <!--用户数据-->
         <el-col :span="24" :xs="24">
           <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
-            <el-form-item label="会员姓名" prop="realName">
+            <el-form-item label="会员姓名" prop="memberName">
               <el-input
-                v-model="queryParams.realName"
+                v-model="queryParams.memberName"
                 placeholder="请输入会员姓名"
                 clearable
                 style="width: 240px"
                 @keyup.enter.native="handleQuery"
               />
             </el-form-item>
-            <el-form-item label="会员手机号" prop="memberCode" label-width="88px">
+            <el-form-item label="会员手机号" prop="mobile" label-width="88px">
               <el-input
-                v-model="queryParams.memberCode"
+                v-model="queryParams.mobile"
                 placeholder="请输入会员手机号"
                 clearable
                 style="width: 240px"
                 @keyup.enter.native="handleQuery"
               />
             </el-form-item>
-            <el-form-item label="优惠券名称" prop="mobile" label-width="88px">
+            <el-form-item label="优惠券名称" prop="couponName" label-width="88px">
               <el-input
-                v-model="queryParams.mobile"
+                v-model="queryParams.couponName"
                 placeholder="请输入优惠券名称"
                 clearable
                 style="width: 240px"
                 @keyup.enter.native="handleQuery"
               />
             </el-form-item>
-            <el-form-item label="优惠券批次号" prop="cardId" label-width="98px">
+            <el-form-item label="优惠券批次号" prop="couponBatch" label-width="98px">
               <el-input
-                v-model="queryParams.cardId"
+                v-model="queryParams.couponBatch"
                 placeholder="请输入优惠券批次号"
                 clearable
                 style="width: 240px"
@@ -52,23 +52,27 @@
   
           <el-table v-loading="loading" :data="tableList" @selection-change="handleSelectionChange">
             <el-table-column type="index" label="序号" align="center"  />
-            <el-table-column label="会员姓名" align="center" key="realName" prop="realName" v-if="columns[0].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="会员手机号" align="center" key="memberCode1" prop="memberCode1" v-if="columns[1].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="优惠券名称" align="center" key="memberCode2" prop="memberCode2" v-if="columns[2].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="优惠券批次号" align="center" key="memberCode3" prop="memberCode3" v-if="columns[3].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="优惠券额度" align="center" key="memberCode4" prop="memberCode4" v-if="columns[4].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="会员姓名" align="center" key="memberName" prop="memberName" v-if="columns[0].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="会员手机号" align="center" key="mobile" prop="mobile" v-if="columns[1].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="优惠券名称" align="center" key="couponName" prop="couponName" v-if="columns[2].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="优惠券批次号" align="center" key="couponBatch" prop="couponBatch" v-if="columns[3].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="优惠券额度" align="center" key="quota" prop="quota" v-if="columns[4].visible" :show-overflow-tooltip="true">
+              <template slot-scope="scope">
+                {{ scope.row.type == 1 ? (scope.row.quota + '元'):((scope.row.quota*10) + '折') }}
+              </template>
+            </el-table-column>
             <el-table-column label="会员类型" align="center" key="type" prop="type" v-if="columns[5].visible" :show-overflow-tooltip="true">
               <template slot-scope="scope">
                 <dict-tag :options="dict.type.tourism_memberInformation_user_type" :value="scope.row.type"/>
               </template>
             </el-table-column>
-            <el-table-column label="领取时间" align="center" key="levelName" prop="levelName" v-if="columns[6].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="状态" align="center" key="type1" prop="type1" v-if="columns[7].visible" :show-overflow-tooltip="true">
+            <el-table-column label="领取时间" align="center" key="receiveDate" prop="receiveDate" v-if="columns[6].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="状态" align="center" key="status" prop="status" v-if="columns[7].visible" :show-overflow-tooltip="true">
               <template slot-scope="scope">
-                <dict-tag :options="dict.type.tourism_memberInformation_user_type" :value="scope.row.type"/>
+                <dict-tag :options="dict.type.tourism_couponManagement_status" :value="scope.row.status"/>
               </template>
             </el-table-column>
-            <el-table-column label="使用时间" align="center" key="cardId" prop="cardId" v-if="columns[8].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="使用时间" align="center" key="useDate" prop="useDate" v-if="columns[8].visible" :show-overflow-tooltip="true" />
             <el-table-column
               label="操作"
               align="center"
@@ -77,12 +81,13 @@
             >
               <template slot-scope="scope" >
                 <el-button
+                  v-if="scope.row.orderInfoId"
                   size="mini"
                   type="text"
                   icon="el-icon-document"
                   @click="handleDetails(scope.row)"
                   v-hasPermi="configPermi.details"
-                >详情</el-button>
+                >查看订单</el-button>
               </template>
             </el-table-column>
           </el-table>
@@ -110,7 +115,7 @@
   import detailsBox from "./detailsBox/couponVerificationDetails.vue"
   export default {
     name: "User",
-    dicts: ['tourism_memberInformation_user_type','tourism_memberInformation_status','tourism_memberInformation_sex'],
+    dicts: ['tourism_memberInformation_user_type','tourism_couponManagement_status'],
     components: {detailsBox},
     data() {
       return {
@@ -124,7 +129,7 @@
           export: [''],// 导出权限
         },
         configUrl: {
-          list: '/member/memberInfo/list', // 列表地址
+          list: '/merchant/memberCoupon/pageList', // 列表地址
           delect: '', // 删除地址
           upload: '',// 导入地址
           download:'', // 下载模板地址

+ 424 - 61
src/views/tourism/marketingActivities/detailsBox/couponManagementDetails.vue

@@ -18,56 +18,188 @@
         element-loading-spinner="''"
         element-loading-background="rgba(0, 0, 0, 0.8)"
         >
+        <el-tabs v-model="activeName" @tab-click="handleClick">
+          <el-tab-pane label="基本信息" name="first"></el-tab-pane>
+          <el-tab-pane label="使用规则" name="second"></el-tab-pane>
+          </el-tabs>
         <el-form :model="form" ref="form" :rules="rules" label-width="120px">
-          <div class="form-title"><span>基本信息</span></div>
-          <div style="display: flex;">
-            <el-form-item label="会员名称:">
-              <span style="display: block; min-width: 250px;">{{ form.realName }}</span>
-            </el-form-item>
-            <el-form-item label="性别:">
-              <dict-tag :options="dict.type.tourism_memberInformation_sex" :value="form.sex"/>
-            </el-form-item>
+          <div v-show="activeName == 'first'">
+              <el-form-item label="优惠券名称:" prop="couponName">
+                <span>{{ form.couponName }}</span>
+              </el-form-item>
+              <el-form-item label="券种说明:" prop="remark">
+                <span>{{ form.remark }}</span>
+              </el-form-item>
+              <el-form-item  label="券种类型" prop="type">
+                <el-radio-group class="details-is-disabled" v-model="form.type">
+                  <el-radio 
+                    v-for="dict in dict.type.tourism_couponManagement_type"
+                    :label="Number(dict.value)"
+                    >{{ dict.label }}</el-radio>
+                </el-radio-group>
+              </el-form-item>
+              <el-form-item label="优惠金额" class="is-required">
+                <div style="display: flex;">
+                  <span>订单满</span>
+                  <el-form-item label="" prop="buyAmount">
+                    <span>{{ form.buyAmount }}</span>
+                  </el-form-item>
+                  <span>,减</span>
+                  <el-form-item label="" prop="quota">
+                    <span>{{ form.quota }}</span>
+                  </el-form-item>
+                  <span>{{ form.type == 1 ? '元':'折' }}</span>
+                </div>
+              </el-form-item>
+              <el-form-item label="发放数量" prop="issuseNum">
+                <el-input-number v-model="form.issuseNum" controls-position="right" step-strictly :step="1" :min="0" placeholder="请输入发放数量"></el-input-number>
+                <span>张</span>
+              </el-form-item>
+              <el-form-item label="发放时间" prop="grantTime">
+                <span>{{ form.grantTime&&form.grantTime.join('——') }}</span>
+              </el-form-item>
+              <el-form-item label="使用有效期:" prop="useType">
+                <el-radio-group v-model="form.useType" class="details-is-disabled" @input="radioInputs">
+                  <div style="display: flex;flex-direction: column;">
+                    <div style="display: flex;align-items: center;">
+                      <el-radio style="display: flex;align-items: center;" :label="1">
+                        <div style="display: flex;align-items: center;">
+                          <el-form-item label="" label-width="0" :prop="'useDate'">
+                            <span>指定时间</span>
+                            <span>{{ form.useDate&&form.useDate.join('——') }}</span>
+                          </el-form-item>
+                        </div>
+                      </el-radio>
+                    </div>
+                    <div style="display: flex;align-items: center;margin-top: 25px;">
+                      <el-radio style="display: flex;align-items: center;" :label="2">
+                        <div style="display: flex;align-items: center;"> 
+                          <el-form-item label="" label-width="0" :prop="'useDay'">
+                            <span>领取当日起</span>
+                            <span>{{ form.useDay }}</span>
+                            <span>天内使用</span>
+                          </el-form-item>
+                        </div>
+                      </el-radio>
+                    </div>
+                    
+                  </div>
+                </el-radio-group>
+              </el-form-item>
+              <el-form-item label="优惠券背景图" prop="imag">
+                <div style="display: flex;">
+                  <div 
+                  v-for="(item,index) in form.imag" 
+                  :key="index"
+                  style="width: 100px; height: 100px;position: relative;border: 1px solid #999;border-radius: 5px;margin-right: 20px;">
+                    <el-image 
+                      style="width: 100%; height: 100%"
+                      :src="item" 
+                      :preview-src-list="form.imag">
+                    </el-image>
+                  </div>
+                  <div 
+                  style="width: 100px; height: 100px;" 
+                  v-if="!form.imag||form.imag.length<1"
+                  v-loading="actionUrlLoading"
+                  element-loading-text="上传中..."
+                  element-loading-spinner="el-icon-loading"
+                  element-loading-background="rgba(0, 0, 0, 0.8)"
+                  >
+                    <el-upload
+                      class="avatar-uploader"
+                      :action="actionUrl"
+                      :data="{
+                        bucket: 'tourism'
+                      }"
+                      :show-file-list="false"
+                      :before-upload="beforeAvatarUpload"
+                      :on-success="handleAvatarSuccess"
+                      :on-progress="handleAvatarProgress"
+                      :disabled="actionUrlLoading"
+                      :on-error="handleAvatarError"
+                      >
+                      <i class="el-icon-plus avatar-uploader-icon"></i>
+                    </el-upload>
+                  </div>
+                  
+                </div>
+                <span>建议尺寸322px X 77px,支持jpg/png/gif,支持1MB大小以内的图片上传</span>
+              </el-form-item>
           </div>
-          <div style="display: flex;">
-            <el-form-item label="手机号:">
-              <span style="display: block;min-width: 250px;">{{ form.mobile }}</span>
-            </el-form-item>
-            <el-form-item label="身份证号:">
-              <span style="display: block;min-width: 250px;">{{ form.cardId }}</span>
-            </el-form-item>
-          </div>
-          <div style="display: flex;">
-            <el-form-item label="注册时间:">
-              <span style="display: block;min-width: 250px;">{{ form.createTime }}</span>
-            </el-form-item>
-          </div>
-          <div class="form-title"><span>会员信息</span></div>
-          <div style="display: flex;">
-            <el-form-item label="会员类型:">
-              <span style="display: block;min-width: 250px;">
-                <dict-tag :options="dict.type.tourism_memberInformation_user_type" :value="form.type"/>
-              </span>
-            </el-form-item>
-            <el-form-item label="会员卡号:">
-              <span style="display: block;min-width: 250px;">{{ form.memberCode }}</span>
-            </el-form-item>
-          </div>
-          <div style="display: flex;">
-            <el-form-item label="剩余积分:">
-              <span style="display: block;min-width: 250px;">{{ form.credit }}</span>
-            </el-form-item>
-            <el-form-item label="剩余储值:">
-              <span style="display: block;min-width: 250px;">{{ form.balance }}</span>
-            </el-form-item>
-          </div>
-          <div class="form-title"><span>消费数据</span></div>
-          <div style="display: flex;">
-            <el-form-item label="下单数(单):">
-              <span style="display: block;min-width: 250px;">{{ form.orderCount }}</span>
-            </el-form-item>
-            <el-form-item label="支付成功数(单):">
-              <span style="display: block;min-width: 250px;">{{ form.buyCount }}</span>
-            </el-form-item>
+          <div v-show="activeName == 'second'">
+              <el-form-item label="使用对象:" prop="useUserType" label-width="200px">
+                <el-radio-group v-model="form.useUserType" class="details-is-disabled" @input="form.useUserRelid = []">
+                  <el-radio 
+                    v-for="dict in dict.type.tourism_couponManagement_useUserType"
+                    :label="Number(dict.value)"
+                    >{{ dict.label }}</el-radio>
+                </el-radio-group>
+              </el-form-item>
+              <el-form-item label="会员等级" v-if="form.useUserType == 2" prop="useUserRelid_2" label-width="200px">
+                <selectMembershipLevel 
+                    v-model="form.useUserRelid_2"
+                    title="新增会员等级" 
+                    :isAdd="false"
+                    @submitForm="()=>$refs.form.validateField('useUserRelid_2')">
+                </selectMembershipLevel>
+              </el-form-item>
+              <el-form-item label="会员号" v-if="form.useUserType == 3" prop="useUserRelid_3" label-width="200px">
+                <selectMemberInformation 
+                    v-model="form.useUserRelid_3"
+                    title="新增会员号" 
+                    :isAdd="false"
+                    @submitForm="()=>$refs.form.validateField('useUserRelid_3')">
+                </selectMemberInformation>
+              </el-form-item>
+              <el-form-item label="领取限制:" prop="receiveType" label-width="200px">
+                <div style="display: flex;align-items: center;">
+                  <el-radio-group v-model="form.receiveType" class="details-is-disabled" @input="radioInput">
+                    <div style="display: flex;align-items: center;">
+                      <el-radio :label="1">不限</el-radio>
+                      <el-radio style="display: flex;align-items: center;" :label="2">
+                        <el-form-item label="" label-width="0" :prop="'receiveNum'">
+                          <span>每人限领</span>
+                          <span>{{ form.receiveNum }}</span>
+                          <span>张</span>
+                        </el-form-item>
+                      </el-radio>
+                    </div>
+                  </el-radio-group>
+                </div>
+              </el-form-item>
+              <el-form-item label="会员积分抵扣同时使用:" prop="isAdd" label-width="200px">
+                <el-radio-group v-model="form.isAdd" class="details-is-disabled">
+                  <el-radio 
+                    v-for="dict in dict.type.tourism_couponManagement_receiveType"
+                    :label="Number(dict.value)"
+                    >{{ dict.label }}</el-radio>
+                </el-radio-group>
+              </el-form-item>
+              <el-form-item label="适用产品:" prop="useConfig" label-width="200px">
+                <el-radio-group v-model="form.useConfig" class="details-is-disabled">
+                  <el-radio 
+                    v-for="dict in dict.type.tourism_couponManagement_useConfig"
+                    :label="Number(dict.value)"
+                    >{{ dict.label }}</el-radio>
+                </el-radio-group>
+              </el-form-item>
+              <el-form-item label="产品类型:" v-if="form.useConfig == 2" prop="useGoodType" label-width="200px">
+                <el-radio-group v-model="form.useGoodType" class="details-is-disabled">
+                  <el-radio 
+                    v-for="dict in dict.type.goods_type"
+                    :label="dict.value"
+                    >{{ dict.label }}</el-radio>
+                </el-radio-group>
+              </el-form-item>
+              <el-form-item label="" v-if="form.useConfig == 2 && form.useGoodType==1" prop="usePerform_1" label-width="200px">
+                <selectTicketOrders 
+                    v-model="form.usePerform_1"
+                    :isAdd="false"
+                    title="新增门票产品" 
+                    @submitForm="()=>$refs.form.validateField('usePerform_1')">
+                </selectTicketOrders>
+              </el-form-item>
           </div>
         </el-form>
       </div>
@@ -82,11 +214,16 @@
 <script>
 import { 
   getTableDeatilsByIdApi,
+  updateTableApi,
+  addTableApi
  } from '@/api/CURD'
-
+import selectMembershipLevel from '../model/selectMembershipLevel.vue'
+import selectMemberInformation from '../model/selectMemberInformation.vue'
+import selectTicketOrders from "../model/selectTicketOrders.vue"
 export default {
   name: "addAndEdit",
-  dicts: ['tourism_memberInformation_sex','tourism_memberInformation_user_type'],
+  components: {selectMembershipLevel,selectMemberInformation,selectTicketOrders},
+  dicts: ['tourism_couponManagement_type','tourism_couponManagement_useUserType','tourism_couponManagement_receiveType','tourism_couponManagement_useConfig','goods_type'],
   data() {
     return {
       title: "",
@@ -96,40 +233,87 @@ export default {
       loadingText: "拼命加载数据中...",
       formStatus: null, // 0/null : 加载中 1 : 获取详情成功 2  : 获取详情失败 
       configUrl: {
-        add: '', // 新增地址
-        details: '/member/memberInfo/detail', // 详情地址
-        edit: '', // 编辑地址
+        add: '/merchant/merchantCouponInfo/insertOrUpdate', // 新增地址
+        details: '/merchant/merchantCouponInfo/selectById', // 详情地址
+        edit: '/merchant/merchantCouponInfo/insertOrUpdate', // 编辑地址
       },
       form: {
         id: undefined,
       },
-      rules: {},
-      scenicAreaProducts: [],// 景点产品关联
+      rules: {
+        couponName: [{ required: true, message: "请输入优惠券名称", trigger: ["change","blur"] }],
+        remark: [{ required: true, message: "请输入券种说明", trigger: ["change","blur"] }],
+        type: [{ required: true, message: "请选择券种类型", trigger: ["change","blur"] }],
+        buyAmount: [{ required: true, message: "请输入订单门槛金额", trigger: ["change","blur"] }],
+        quota: [{ required: true, message: "请输入满减金额/折扣", trigger: ["change","blur"] }],
+        issuseNum: [{ required: true, message: "请输入发放数量", trigger: ["change","blur"] }],
+        grantTime: [{ required: true, message: "请选择发放时间", trigger: ["change","blur"] }],
+        
+        useType: [{ required: true, message: "请选择使用有效期", trigger: ["change","blur"] }],
+        useDate: [{ required: false, message: "请选择指定时间", trigger: ["change","blur"] }],
+        useDay: [{ required: false, message: "请输入天数", trigger: ["change","blur"] }],
+        imag: [{ required: true, message: "请上传图片", trigger: ["change","blur"] }],
+
+        useUserType: [{ required: true, message: "请选择使用对象", trigger: ["change","blur"] }],
+        useUserRelid_2: [{ required: true, message: "请选择会员等级", trigger: ["change","blur"] }],
+        useUserRelid_3: [{ required: true, message: "请选择会员号", trigger: ["change","blur"] }],
+        receiveType: [{ required: true, message: "请选择是否领取限制", trigger: ["change","blur"] }],
+        receiveNum: [{ required: false, message: "请输入每人限领数量", trigger: ["change","blur"] }],
+        isAdd: [{ required: true, message: "请选择是否会员积分抵扣同时使用", trigger: ["change","blur"] }],
+        
+        useConfig: [{ required: true, message: "请选择适用产品", trigger: ["change","blur"] }],
+        useGoodType: [{ required: true, message: "请选择产品类型", trigger: ["change","blur"] }],
+        usePerform_1: [{ required: true, message: "请选择门票产品", trigger: ["change","blur"] }],
+      },
+
+      activeName: 'first',
+
+      actionUrl: process.env.VUE_APP_BASE_API + process.env.VUE_APP_UPLOAD_IMAGE,
+      actionUrlLoading: false,
     };
   },
   methods: {
     async initData(title , model,row){
       this.title = title
+      this.activeName = 'first'
       this.open = true
       this.loadingText = "拼命加载数据中..."
       this.loading = true
-      this.actionUrlLoading = false
       this.model = model
       this.formStatus = 0
       if(model=='ADD') { // 新增
-        this.$set(this,'form',{...row,imgUrl:[]})
+        this.$set(this,'form',{
+          ...row,
+          grantTime: [], // 发放时间段
+          useDate: [], // 使用指定时间
+          type: 1,
+          useType: 1,
+          useUserType: 1,
+          receiveType: 1,
+          isAdd: 1,
+          useConfig: 1,
+          useGoodType: null,
+          imag: [],
+          useUserRelid_2: [],
+          useUserRelid_3: [],
+          usePerform_1: []
+        })
         this.formStatus = 1
       }else if(model=='EDIT') { // 新增
         let obj = {
           ...row,
-          imgUrl: row.imgUrl?row.imgUrl.split(','):[]
+          imag: row.imag?row.imag.split(','):[],
         }
-        this.$set(this,'form',obj)
+        this.$set(this,'form',{
+          memberId: row.id
+        })
         this.formStatus = 1
       }else if(model=='EDITInit') { // 新增
         await this.getTableDeatilsFun(row)
       }
       this.loading = false
+      this.radioInputs(this.form.useType)
+      this.radioInput(this.form.receiveType)
       this.$nextTick(()=>{
         if(this.$refs["form"]) {
           this.$refs["form"].clearValidate();
@@ -145,8 +329,32 @@ export default {
         if(res.code == 200) {
           let obj = {
             ...res.data,
-            imgUrl: res.data.imgUrl?res.data.imgUrl.split(','):[],
-        }
+            grantTime: [res.data.issuseStartDate,res.data.issuseEndDate], // 发放时间段
+            imag: res.data.imag?res.data.imag.split(','):[],
+            quota: res.data.type == 1?res.data.quota:(res.data.quota)*10
+          }
+          if(obj.useType == 1) {
+            obj['useDate'] = [res.data.useStartDate,res.data.useEndDate] // 使用指定时间
+          }else if(obj.useType == 2){
+            obj['useDay'] = obj.useDay
+          }
+          if(obj.useUserType == 2) {
+            obj['useUserRelid_2'] = obj.useUserRelidList?obj.useUserRelidList:[]
+          }else if(obj.useUserType == 3){
+            obj['useUserRelid_3'] = obj.useUserRelidList?obj.useUserRelidList:[]
+          }else {
+            obj['useUserRelid_2'] = []
+            obj['useUserRelid_3'] = []
+          }
+          if(obj.useConfig == 2) {
+            if(obj.useGoodType == 1) {
+              obj['usePerform_1'] = obj.usePerformList?obj.usePerformList:[]
+            }else {
+              obj['usePerform_1'] = []
+            }
+          }
+          
+          
           this.$set(this,'form',JSON.parse(JSON.stringify(obj)))
           this.formStatus = 1
         }else {
@@ -163,6 +371,90 @@ export default {
         this.open = false;
       }
     },
+    /**
+     * 保存
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    submitForm() {
+      this.$refs["form"].validate((valid ,object)=> {
+        if (valid) {
+          this.loadingText = "提交数据中..."
+          this.loading = true
+          let param = JSON.parse(JSON.stringify(this.form))
+          param['issuseStartDate'] = param.grantTime[0]
+          param['issuseEndDate'] = param.grantTime[1]
+
+          param['useStartDate'] = param.useDate[0]
+          param['useEndDate'] = param.useDate[1]
+          if(param.useUserType == 2) {
+            let list = this.form.useUserRelid_2.map((item)=> item.id)
+            param['useUserRelid'] = list.join(',')
+           }else if(param.useUserType == 3){
+            let list = this.form.useUserRelid_3.map((item)=> item.id)
+            param['useUserRelid'] = list.join(',')
+          }else {
+            param['useUserRelid'] = ''
+          }
+
+          param['usePerform'] = ''
+          if(param.useConfig == 2) {
+            if(param.useGoodType == 1) {
+              let list = this.form.usePerform_1.map((item)=> item.id)
+              param['usePerform'] = list.join(',')
+            }
+          }
+          delete param.grantTime
+          delete param.useDate
+          delete param.useUserRelid_2
+          delete param.useUserRelid_3
+          delete param.useUserRelidList
+
+          delete param.usePerformList
+          delete param.usePerform_1
+          if (this.model != 'ADD') {
+            addTableApi(
+              this.configUrl.edit,{
+                ...param,
+                imag: param.imag ? param.imag.join(','):'',
+              }).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.loading = false
+              this.open = false;
+              this.$emit('refresh')
+            }).catch(()=>{
+              this.$message.error("修改失败!!!");
+              this.loading = false
+            })
+          } else {
+            addTableApi(this.configUrl.edit,{
+                ...param,
+                imag: param.imag ? param.imag.join(','):'',
+              }).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.loading = false
+              this.open = false;
+              this.$emit('refresh')
+            }).catch(()=>{
+              this.$message.error("新增失败!!!");
+              this.loading = false
+            })
+          }
+        }else {
+          console.log("fsdfsd===",valid,object)
+          if(object&&JSON.stringify(object)!='{}') {
+            let srt = ''
+            for(let key in object) {
+              if(object.hasOwnProperty(key)) {
+                srt = srt + `[${object[key][0].message}],`
+              }
+            }
+            this.$message.error(srt);
+          }
+          
+        }
+      });
+    },
     /**
      * 重置
      * @date 2023-11-22
@@ -182,6 +474,66 @@ export default {
       this.reset();
       this.open = false;
     },
+    /**  点击tab  */
+    handleClick() {
+
+    },
+
+    /**    */
+    radioInput(value) {
+      if( value == 1 ){
+        this.rules.receiveNum[0].required = false
+        this.$refs.form.clearValidate('receiveNum');
+      }else if( value == 2 ) {
+        this.rules.receiveNum[0].required = true
+        this.$refs.form.clearValidate('receiveNum');
+      }
+    },
+    /**  使用有效期   */
+    radioInputs(value) {
+      if( value == 1 ){
+        this.rules.useDate[0].required = true
+        this.rules.useDay[0].required = false
+        this.$refs.form.clearValidate('useDate');
+        this.$refs.form.clearValidate('useDay');
+      }else if( value == 2 ) {
+        this.rules.useDate[0].required = false
+        this.rules.useDay[0].required = true
+        this.$refs.form.clearValidate('useDate');
+        this.$refs.form.clearValidate('useDay');
+      }
+    },
+
+    /**  上传图片 单张  */
+    handleAvatarSuccess(response, file, fileList) {
+      console.log("res, file",response, file, fileList)
+      this.actionUrlLoading = false
+      if(response.code == 200) {
+        this.form.imag.push(response.data.url)
+      }
+    },
+    beforeAvatarUpload(file) {
+      const isLt2M = file.size / 1024 / 1024 <= 1;
+      let testmsg = file.name.substring(file.name.lastIndexOf('.')+1)
+      let typeList = ['png','jepg','jpg']
+      const isJPG = typeList.includes(testmsg);
+      if (!isJPG) {
+        this.$message.error(`上传图片图片只能是 ${typeList} 格式!`);
+      }
+      if (!isLt2M) {
+        this.$message.error('上传图片图片大小不能超过 1MB!');
+      }
+      return isJPG && isLt2M;
+    },
+    handleAvatarProgress(){
+      this.actionUrlLoading = true
+    },
+    handleAvatarError() {
+      this.actionUrlLoading = false
+    },
+    handleRemove(index) {
+      this.form.imag.splice(index,1)
+    },
   },
 };
 </script>
@@ -295,6 +647,7 @@ export default {
     }
   }
 }
+
 ::v-deep .avatar-uploader .el-upload {
     border: 1px dashed #d9d9d9;
     border-radius: 6px;
@@ -318,6 +671,16 @@ export default {
     height: 100px;
     display: block;
   }
+
+  .details-is-disabled {
+    user-select: none;
+    ::v-deep .el-radio {
+      display: none !important;
+    }
+    ::v-deep .el-radio.is-checked {
+      display: flex !important;
+    }
+  }
 </style>
 <style>
 .custom-class-box {

+ 58 - 31
src/views/tourism/marketingActivities/detailsBox/couponVerificationDetails.vue

@@ -18,57 +18,84 @@
         element-loading-spinner="''"
         element-loading-background="rgba(0, 0, 0, 0.8)"
         >
-        <el-form :model="form" ref="form" :rules="rules" label-width="120px">
-          <div class="form-title"><span>基本信息</span></div>
+        <el-form :model="form" ref="form" :rules="rules" label-width="130px">
+          <div class="form-title"><span>门票订单详情</span></div>
           <div style="display: flex;">
-            <el-form-item label="会员名称:">
-              <span style="display: block; min-width: 250px;">{{ form.realName }}</span>
+            <el-form-item label="订单号:">
+              <span style="display: block; min-width: 250px;">{{ form.id }}</span>
             </el-form-item>
-            <el-form-item label="性别:">
-              <dict-tag :options="dict.type.tourism_memberInformation_sex" :value="form.sex"/>
+            <el-form-item label="第三方系统订单:">
+              <span style="display: block; min-width: 250px;">{{ form.trackId }}</span>
+            </el-form-item>
+            <el-form-item label="购票人:">
+              <span style="display: block; min-width: 250px;">{{ form.memberName}}</span>
             </el-form-item>
           </div>
+
           <div style="display: flex;">
             <el-form-item label="手机号:">
-              <span style="display: block;min-width: 250px;">{{ form.mobile }}</span>
+              <span style="display: block; min-width: 250px;">{{ form.memberMobile }}</span>
             </el-form-item>
             <el-form-item label="身份证号:">
-              <span style="display: block;min-width: 250px;">{{ form.cardId }}</span>
+              <span style="display: block; min-width: 250px;">{{ form.memberCardId}}</span>
             </el-form-item>
-          </div>
-          <div style="display: flex;">
-            <el-form-item label="注册时间:">
-              <span style="display: block;min-width: 250px;">{{ form.createTime }}</span>
+            <el-form-item label="景区名称:">
+              <span style="display: block; min-width: 250px;">{{ form.scenicName }}</span>
             </el-form-item>
           </div>
-          <div class="form-title"><span>会员信息</span></div>
+
           <div style="display: flex;">
-            <el-form-item label="会员类型:">
-              <span style="display: block;min-width: 250px;">
-                <dict-tag :options="dict.type.tourism_memberInformation_user_type" :value="form.type"/>
-              </span>
+            <el-form-item label="游玩日期:">
+              <span style="display: block; min-width: 250px;">{{ form.performDate }}</span>
             </el-form-item>
-            <el-form-item label="会员卡号:">
-              <span style="display: block;min-width: 250px;">{{ form.memberCode }}</span>
+            <el-form-item label="购票渠道:">
+              <span style="display: block; min-width: 250px;">
+                <dict-tag :options="dict.type.tourism_ticketOrders_source" :value="form.source"/>
+              </span>
             </el-form-item>
           </div>
+
           <div style="display: flex;">
-            <el-form-item label="剩余积分:">
-              <span style="display: block;min-width: 250px;">{{ form.credit }}</span>
+            <el-form-item label="应付金额:">
+              <span style="display: block; min-width: 250px;">{{ form.orderPrice }}</span>
+            </el-form-item>
+            <el-form-item label="购票数量:">
+              <span style="display: block; min-width: 250px;">{{ form.quantity }}</span>
             </el-form-item>
-            <el-form-item label="剩余储值:">
-              <span style="display: block;min-width: 250px;">{{ form.balance }}</span>
+            <el-form-item label="实付金额:">
+              <span style="display: block; min-width: 250px;">{{ form.realPrice }}</span>
             </el-form-item>
           </div>
-          <div class="form-title"><span>消费数据</span></div>
           <div style="display: flex;">
-            <el-form-item label="下单数(单):">
-              <span style="display: block;min-width: 250px;">{{ form.orderCount }}</span>
+            <el-form-item label="下单时间:">
+              <span style="display: block; min-width: 250px;">{{ form.createTime }}</span>
+            </el-form-item>
+            <el-form-item label="订单状态:">
+              <span style="display: block; min-width: 250px;">
+                <dict-tag :options="dict.type.tourism_ticketOrders_status" :value="form.status"/>
+              </span>
             </el-form-item>
-            <el-form-item label="支付成功数(单):">
-              <span style="display: block;min-width: 250px;">{{ form.buyCount }}</span>
+            <el-form-item label="流水号:">
+              <span style="display: block; min-width: 250px;">{{ form.orderNum }}</span>
             </el-form-item>
           </div>
+
+          <div class="form-title"><span>购票信息</span></div>
+          <div v-if="form.viewersList">
+              <el-table :data="form.viewersList">
+              <el-table-column type="index" label="序号" align="center"  />
+              <el-table-column label="票种规格" align="center" key="goodsName" prop="goodsName" :show-overflow-tooltip="true" />
+              <el-table-column label="姓名" align="center" key="name" prop="name" :show-overflow-tooltip="true" />
+              <el-table-column label="身份证号" align="center" key="idcard" prop="idcard" :show-overflow-tooltip="true" />
+              <el-table-column label="取票码" align="center" key="qrcodeNo" prop="qrcodeNo" :show-overflow-tooltip="true" />
+              <el-table-column label="核销状态" align="center" key="status" prop="status" :show-overflow-tooltip="true">
+                <template slot-scope="scope">
+                  <dict-tag :options="dict.type.tourism_ticketOrders_status" :value="scope.row.status"/>
+                </template>
+              </el-table-column>
+              <el-table-column label="核销时间" align="center" key="qrcodeUseTime" prop="qrcodeUseTime" :show-overflow-tooltip="true" />
+            </el-table>
+          </div>
         </el-form>
       </div>
     </div>
@@ -86,7 +113,7 @@ import {
 
 export default {
   name: "addAndEdit",
-  dicts: ['tourism_memberInformation_sex','tourism_memberInformation_user_type'],
+  dicts: ['tourism_ticketOrders_qrcodeStatus','tourism_ticketOrders_source','tourism_ticketOrders_status','tourism_ticketOrders_payStatus','tourism_ticketOrders_payWay'],
   data() {
     return {
       title: "",
@@ -97,7 +124,7 @@ export default {
       formStatus: null, // 0/null : 加载中 1 : 获取详情成功 2  : 获取详情失败 
       configUrl: {
         add: '', // 新增地址
-        details: '/member/memberInfo/detail', // 详情地址
+        details: '/order/orderInfo/detail', // 详情地址
         edit: '', // 编辑地址
       },
       form: {
@@ -138,7 +165,7 @@ export default {
     },
     /** 获取详情 */
     async getTableDeatilsFun(row) {
-      const id = row.id
+      const id = row.orderInfoId
       this.loading = true
       try {
         let res = await getTableDeatilsByIdApi(this.configUrl.details,{id})

+ 326 - 0
src/views/tourism/marketingActivities/detailsBox/eventManagementDetails.vue

@@ -0,0 +1,326 @@
+<template>
+  <el-dialog
+    :title="title"
+    :visible.sync="open"
+    width="70%"
+    append-to-body
+    :close-on-click-modal="false"
+    @close="cancel"
+  >
+    <div class="form-dialog-box"
+    v-loading="loading"
+    :element-loading-text="loadingText"
+    element-loading-spinner="el-icon-loading"
+    element-loading-background="rgba(0, 0, 0, 0)">
+      <div
+        v-loading="loading"
+        :element-loading-text="''"
+        element-loading-spinner="''"
+        element-loading-background="rgba(0, 0, 0, 0.8)"
+        >
+        <el-form :model="form" ref="form" :rules="rules" label-width="120px">
+          <div class="form-title"><span>基本信息</span></div>
+          <div style="display: flex;">
+            <el-form-item label="会员名称:">
+              <span style="display: block; min-width: 250px;">{{ form.realName }}</span>
+            </el-form-item>
+            <el-form-item label="性别:">
+              <dict-tag :options="dict.type.tourism_memberInformation_sex" :value="form.sex"/>
+            </el-form-item>
+          </div>
+          <div style="display: flex;">
+            <el-form-item label="手机号:">
+              <span style="display: block;min-width: 250px;">{{ form.mobile }}</span>
+            </el-form-item>
+            <el-form-item label="身份证号:">
+              <span style="display: block;min-width: 250px;">{{ form.cardId }}</span>
+            </el-form-item>
+          </div>
+          <div style="display: flex;">
+            <el-form-item label="注册时间:">
+              <span style="display: block;min-width: 250px;">{{ form.createTime }}</span>
+            </el-form-item>
+          </div>
+          <div class="form-title"><span>会员信息</span></div>
+          <div style="display: flex;">
+            <el-form-item label="会员类型:">
+              <span style="display: block;min-width: 250px;">
+                <dict-tag :options="dict.type.tourism_memberInformation_user_type" :value="form.type"/>
+              </span>
+            </el-form-item>
+            <el-form-item label="会员卡号:">
+              <span style="display: block;min-width: 250px;">{{ form.memberCode }}</span>
+            </el-form-item>
+          </div>
+          <div style="display: flex;">
+            <el-form-item label="剩余积分:">
+              <span style="display: block;min-width: 250px;">{{ form.credit }}</span>
+            </el-form-item>
+            <el-form-item label="剩余储值:">
+              <span style="display: block;min-width: 250px;">{{ form.balance }}</span>
+            </el-form-item>
+          </div>
+          <div class="form-title"><span>消费数据</span></div>
+          <div style="display: flex;">
+            <el-form-item label="下单数(单):">
+              <span style="display: block;min-width: 250px;">{{ form.orderCount }}</span>
+            </el-form-item>
+            <el-form-item label="支付成功数(单):">
+              <span style="display: block;min-width: 250px;">{{ form.buyCount }}</span>
+            </el-form-item>
+          </div>
+        </el-form>
+      </div>
+    </div>
+    <span slot="footer" class="dialog-footer" v-if="formStatus==1">
+      <el-button @click="cancel">关闭</el-button>
+    </span>
+    <!-- 添加或修改对话框 End -->
+  </el-dialog>
+</template>
+
+<script>
+import { 
+  getTableDeatilsByIdApi,
+ } from '@/api/CURD'
+
+export default {
+  name: "addAndEdit",
+  dicts: ['tourism_memberInformation_sex','tourism_memberInformation_user_type'],
+  data() {
+    return {
+      title: "",
+      model: "", // EDIT: 编辑模式 ADD : 新增模式  EDITInit : 编辑模式(需要请求详情)
+      open: false,
+      loading: false,
+      loadingText: "拼命加载数据中...",
+      formStatus: null, // 0/null : 加载中 1 : 获取详情成功 2  : 获取详情失败 
+      configUrl: {
+        add: '', // 新增地址
+        details: '/member/memberInfo/detail', // 详情地址
+        edit: '', // 编辑地址
+      },
+      form: {
+        id: undefined,
+      },
+      rules: {},
+      scenicAreaProducts: [],// 景点产品关联
+    };
+  },
+  methods: {
+    async initData(title , model,row){
+      this.title = title
+      this.open = true
+      this.loadingText = "拼命加载数据中..."
+      this.loading = true
+      this.actionUrlLoading = false
+      this.model = model
+      this.formStatus = 0
+      if(model=='ADD') { // 新增
+        this.$set(this,'form',{...row,imgUrl:[]})
+        this.formStatus = 1
+      }else if(model=='EDIT') { // 新增
+        let obj = {
+          ...row,
+          imgUrl: row.imgUrl?row.imgUrl.split(','):[]
+        }
+        this.$set(this,'form',obj)
+        this.formStatus = 1
+      }else if(model=='EDITInit') { // 新增
+        await this.getTableDeatilsFun(row)
+      }
+      this.loading = false
+      this.$nextTick(()=>{
+        if(this.$refs["form"]) {
+          this.$refs["form"].clearValidate();
+        }
+      })
+    },
+    /** 获取详情 */
+    async getTableDeatilsFun(row) {
+      const id = row.id
+      this.loading = true
+      try {
+        let res = await getTableDeatilsByIdApi(this.configUrl.details,{id})
+        if(res.code == 200) {
+          let obj = {
+            ...res.data,
+            imgUrl: res.data.imgUrl?res.data.imgUrl.split(','):[],
+        }
+          this.$set(this,'form',JSON.parse(JSON.stringify(obj)))
+          this.formStatus = 1
+        }else {
+          this.$message.error('获取详情失败!!!');
+          this.formStatus = 2
+          this.loading = false
+          this.open = false;
+        }
+        this.loading = false
+      } catch (error) {
+        console.error('获取详情失败!!!!',error)
+        this.formStatus = 2
+        this.loading = false
+        this.open = false;
+      }
+    },
+    /**
+     * 重置
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    reset() {
+      if(this.$refs["form"]) {
+        this.$refs["form"].clearValidate();
+      }
+    },
+    /**
+     * 关闭弹框
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    cancel() {
+      this.reset();
+      this.open = false;
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.form-dialog-box {
+  padding: 0 30px;
+  padding: 0 30px;
+  min-height: 50vh;
+  max-height: 65vh;
+  overflow-y: auto;
+  >div {
+    width: 100%;
+    min-height: 50vh;
+  }
+  .form-title {
+    padding: 0 0 10px 0;
+    span {
+      display: flex;
+      color: rgba(65,80,88,1);
+      font-size: 16px;
+      font-family: SourceHanSansSC;
+      font-weight: 700;
+      line-height: 23px;
+      border-left: 4px solid rgb(22, 132, 252);
+      padding-left: 10px;
+    }
+    
+  }
+  ::v-deep .ql-editor {
+    height: 400px;
+  }
+  .upload-btn {
+    width: 100px;
+    height: 100px;
+    background-color: #fbfdff;
+    border: dashed 1px #c0ccda;
+    border-radius: 5px;
+    i {
+      font-size: 30px;
+      margin-top: 20px;
+    }
+    &-text {
+      margin-top: -10px;
+    }
+  }
+  .avatar {
+    cursor: pointer;
+  }
+}
+.el-table{
+  .upload-btn {
+    width: 100px;
+    height: 100px;
+    background-color: #fbfdff;
+    border: dashed 1px #c0ccda;
+    border-radius: 5px;
+    i {
+      font-size: 30px;
+      margin-top: 20px;
+    }
+    &-text {
+      margin-top: -10px;
+    }
+  }
+  .avatar {
+    cursor: pointer;
+  }
+}
+
+.area-container {
+  min-height: 400px;
+}
+
+::v-deep .area-wrap-city.el-cascader {
+  line-height: normal;
+  .el-input {
+    cursor: pointer;
+    width: 100% !important;
+    height: 28px !important;
+    .el-input__inner {
+      display: none !important;
+    }
+    span.el-input__suffix {
+      position: inherit !important;
+      i.el-input__icon {
+        line-height: inherit;
+        margin-left: 5px;
+      }
+    }
+
+    .el-input__wrapper {
+      box-shadow: none;
+      input {
+        display: none;
+      }
+    }
+  }
+
+  .el-cascader__tags {
+    display: none;
+  }
+}
+
+.area-city-popper {
+  .el-cascader-panel {
+    .el-scrollbar.el-cascader-menu {
+      .el-cascader-menu__wrap.el-scrollbar__wrap {
+        height: 315px;
+      }
+    }
+  }
+}
+::v-deep .avatar-uploader .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+  }
+  ::v-deep .avatar-uploader .el-upload:hover {
+    border-color: #409EFF;
+  }
+  ::v-deep .avatar-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 100px;
+    height: 100px;
+    line-height: 100px;
+    text-align: center;
+  }
+  ::v-deep .avatar {
+    width: 100px;
+    height: 100px;
+    display: block;
+  }
+</style>
+<style>
+.custom-class-box {
+  z-index: 999999 !important;
+}
+</style>

+ 302 - 0
src/views/tourism/marketingActivities/eventManagement.vue

@@ -0,0 +1,302 @@
+<template>
+    <div class="app-container">
+      <el-row :gutter="20">
+        <!--用户数据-->
+        <el-col :span="24" :xs="24">
+          <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+            <el-form-item label="批次号" prop="realName">
+              <el-input
+                v-model="queryParams.realName"
+                placeholder="请输入批次号"
+                clearable
+                style="width: 240px"
+                @keyup.enter.native="handleQuery"
+              />
+            </el-form-item>
+            <el-form-item label="优惠卷名称" prop="memberCode" label-width="88px">
+              <el-input
+                v-model="queryParams.memberCode"
+                placeholder="请输入优惠卷名称"
+                clearable
+                style="width: 240px"
+                @keyup.enter.native="handleQuery"
+              />
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+              <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+            </el-form-item>
+          </el-form>
+  
+          <el-row :gutter="10" class="mb8">
+            <el-col :span="1.5">
+              <el-button
+                type="primary"
+                plain
+                icon="el-icon-plus"
+                size="mini"
+                @click="handleAdd"
+                v-hasPermi="configPermi.add"
+              >新增</el-button>
+            </el-col>
+            <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
+          </el-row>
+  
+          <el-table v-loading="loading" :data="tableList" @selection-change="handleSelectionChange">
+            <el-table-column type="index" label="序号" align="center"  />
+            <el-table-column label="优惠券名称" align="center" key="realName" prop="realName" v-if="columns[0].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="券种类型" align="center" key="type" prop="type" v-if="columns[1].visible" :show-overflow-tooltip="true">
+              <template slot-scope="scope">
+                <dict-tag :options="dict.type.tourism_memberInformation_user_type" :value="scope.row.type"/>
+              </template>
+            </el-table-column>
+            <el-table-column label="券种说明" align="center" key="levelName" prop="levelName" v-if="columns[2].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="发放数量" align="center" key="mobile" prop="mobile" v-if="columns[3].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="适用对象" align="center" key="cardId" prop="cardId" v-if="columns[4].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="领取限制" align="center" key="credit" prop="credit" v-if="columns[5].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="使用有效期" align="center" key="balance" prop="balance" v-if="columns[6].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="适用产品" align="center" key="buyCount" prop="buyCount" v-if="columns[7].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="已领取统计" align="center" key="consumeTotal" prop="consumeTotal" v-if="columns[8].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="创建时间" align="center" key="consumeTotal1" prop="consumeTotal1" v-if="columns[9].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="禁用/启用" align="center" key="status" v-if="columns[10].visible">
+              <template slot-scope="scope">
+                <switchBox 
+                :defaultChecked="true" 
+                v-model="scope.row.status" 
+                @changeFun="openAttraction(scope.row)" 
+                :disabled="false"
+                :active-value="1"
+                :inactive-value="0"
+                 />
+              </template>
+            </el-table-column>
+            <el-table-column
+              label="操作"
+              align="center"
+              width="160"
+              class-name="small-padding fixed-width"
+            >
+              <template slot-scope="scope" >
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-delete"
+                  @click="handleDelete(scope.row)"
+                  v-hasPermi="configPermi.delect"
+                >删除</el-button>
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-edit"
+                  @click="handleUpdate(scope.row)"
+                  v-hasPermi="configPermi.edit"
+                >修改</el-button>
+                
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-document"
+                  @click="handleDetails(scope.row)"
+                  v-hasPermi="configPermi.details"
+                >详情</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+  
+          <pagination
+            v-show="total>0"
+            :total="total"
+            :page.sync="queryParams.pageNum"
+            :limit.sync="queryParams.pageSize"
+            @pagination="getList"
+          />
+        </el-col>
+      </el-row>
+      <!--  详情 -->
+      <detailsBox ref="detailsBox" />
+      <addAndEdit ref="addAndEdit" @refresh="getList" />
+    </div>
+  </template>
+  
+  <script>
+  import { 
+    listTableApi, 
+    delTableParamsApi,
+    addTableApi
+  } from "@/api/CURD";
+  import detailsBox from "./detailsBox/eventManagementDetails.vue"
+  import addAndEdit from "./formBox/eventManagementForm.vue"
+  export default {
+    name: "User",
+    dicts: ['tourism_memberInformation_user_type','tourism_memberInformation_status','tourism_memberInformation_sex'],
+    components: {detailsBox,addAndEdit},
+    data() {
+      return {
+        title: "优惠券管理",// 通用标题
+        configPermi: {
+          add: [''], // 新增权限
+          details: ['electronicMembership:memberInformation:details'], // 详情权限
+          delect: ['electronicMembership:memberInformation:delect'], // 删除权限
+          edit: [''], // 编辑权限
+          upload: [''],// 导入权限
+          export: [''],// 导出权限
+        },
+        configUrl: {
+          list: '/member/memberInfo/list', // 列表地址
+          delect: '', // 删除地址
+          upload: '',// 导入地址
+          download:'', // 下载模板地址
+          export: '',// 导出地址
+          updateStatus: '', // 编辑地址
+        },
+        // 遮罩层
+        loading: true,
+        // 选中数组
+        ids: [],
+        // 非单个禁用
+        single: true,
+        // 非多个禁用
+        multiple: true,
+        // 显示搜索条件
+        showSearch: true,
+        // 总条数
+        total: 0,
+        // 用户表格数据
+        tableList: null,
+        // 查询参数
+        queryParams: {
+          pageNum: 1,
+          pageSize: 10,
+        },
+        dateRange: [],
+        // 控制列表是否显示
+        columns: [
+          { key: 0, label: `优惠券名称`, visible: true },
+          { key: 1, label: `券种类型`, visible: true },
+          { key: 2, label: `券种说明`, visible: true },
+          { key: 2.5, label: `发放数量`, visible: true },
+          { key: 3, label: `适用对象`, visible: true },
+          { key: 4, label: `领取限制`, visible: true },
+          { key: 5, label: `使用有效期`, visible: true },
+          { key: 6, label: `适用产品`, visible: true },
+          { key: 7, label: `已领取统计`, visible: true },
+          { key: 8, label: `创建时间`, visible: true },
+          { key: 9, label: `禁用/启用`, visible: true },
+        ],
+      };
+    },
+    created() {
+      this.getList();
+    },
+    methods: {
+      /** 查询用户列表 */
+      getList() {
+        this.loading = true;
+        listTableApi(
+          this.configUrl.list,
+          this.addDateRange(
+            this.queryParams, 
+            this.dateRange)).then(response => {
+              this.tableList = response.data.rows;
+              this.total = response.data.total;
+              this.loading = false;
+          }
+        ).catch (error=>{
+          console.error('获取列表失败!!!!',error)
+          this.tableList = [];
+          this.total = 0;
+          this.loading = false
+        }) 
+      },
+      /** 搜索按钮操作 */
+      handleQuery() {
+        this.queryParams.pageNum = 1;
+        this.getList();
+      },
+      /** 重置按钮操作 */
+      resetQuery() {
+        this.dateRange = [];
+        this.queryParams = {
+          pageNum: 1,
+          pageSize: 10,
+        }
+        this.handleQuery();
+      },
+      // 多选框选中数据
+      handleSelectionChange(selection) {
+        this.ids = selection.map(item => item.id);
+        this.single = selection.length != 1;
+        this.multiple = !selection.length;
+      },
+      /** 新增按钮操作 */
+      handleAdd() {
+        if(this.$refs.addAndEdit) {
+          this.$refs.addAndEdit.initData(this.title + '新增', "ADD",{})
+        }
+      },
+      /** 修改按钮操作 */
+      handleUpdate(row) {
+        if(this.$refs.addAndEdit) {
+          this.$refs.addAndEdit.initData(this.title + '编辑', "EDITInit",{...row})
+        }
+      },
+      handleDetails(row){
+        if(this.$refs.detailsBox) {
+          this.$refs.detailsBox.initData(this.title + '详情', "EDITInit",{...row})
+        }
+      },
+      /** 删除按钮操作 */
+      handleDelete(row) {
+        const ids = row.id || this.ids;
+        return
+        this.$modal.confirm('是否确认删除数据项?').then( () => {
+          return delTableParamsApi(this.configUrl.delect,{
+            id: ids
+          });
+        }).then(() => {
+          this.getList();
+          this.$modal.msgSuccess("删除成功");
+        }).catch((e) => {
+          console.error("删除失败====",e)
+        });
+      },
+      /** 导出按钮操作 */
+      handleExport() {
+        this.download(this.configUrl.export, {
+          ...this.queryParams
+        }, `${this.title }_${new Date().getTime()}.xlsx`)
+      },
+      /** 导入按钮操作 */
+      handleImport() {
+        if(this.$refs.upload) {
+          this.$refs.upload.initData({
+            width: '400px',
+            // 弹出层标题(用户导入)
+            title: this.title + "导入",
+            // 下载模板地址
+            importTemplate: this.configUrl.download,
+            // 上传的地址
+            url: this.configUrl.upload
+          })
+        }
+      },
+      /** 开/闭 园 */
+      openAttraction(row) {
+        console.log("row======",row)
+        return
+        this.$modal.confirm(`是否确认${row.status == 0 ? '启用' : '禁用'} ${row.realName||''}吗?`).then( () => {
+          return addTableApi(this.configUrl.updateStatus,{
+            id: row.id,
+            status: row.status == 1 ? 0 : 1
+          });
+        }).then(() => {
+          this.getList();
+          this.$modal.msgSuccess(`${row.status == 0 ? '启用' : '禁用'}成功`);
+        }).catch((e) => {
+          console.error("失败====",e)
+        });
+      },
+    }
+  };
+  </script>
+  

+ 405 - 44
src/views/tourism/marketingActivities/formBox/couponManagementForm.vue

@@ -19,14 +19,13 @@
         element-loading-background="rgba(0, 0, 0, 0.8)"
         >
         <el-tabs v-model="activeName" @tab-click="handleClick">
-          <el-tab-pane label="用户管理" name="first"></el-tab-pane>
-          <el-tab-pane label="配置管理" name="second"></el-tab-pane>
+          <el-tab-pane label="基本信息" name="first"></el-tab-pane>
+          <el-tab-pane label="使用规则" name="second"></el-tab-pane>
           </el-tabs>
         <el-form :model="form" ref="form" :rules="rules" label-width="120px">
-          <transition name="el-zoom-in-top">
-            <div v-show="activeName == 'first'">
-              <el-form-item label="优惠券名称" prop="remark">
-                <el-input style="width: 350px;" v-model="form.remark" placeholder="请输入优惠券名称" maxlength="50" show-word-limit />
+          <div v-show="activeName == 'first'">
+              <el-form-item label="优惠券名称" prop="couponName">
+                <el-input style="width: 350px;" v-model="form.couponName" placeholder="请输入优惠券名称" maxlength="50" show-word-limit />
               </el-form-item>
               <el-form-item label="券种说明" prop="remark">
                 <el-input style="width: 350px;" type="textarea" v-model="form.remark" placeholder="请输入券种说明" maxlength="200" show-word-limit />
@@ -34,40 +33,203 @@
               <el-form-item label="券种类型" prop="type">
                 <el-radio-group v-model="form.type">
                   <el-radio 
-                    v-for="dict in dict.type.tourism_memberInformation_biangeng_type"
-                    :label="dict.value"
+                    v-for="dict in dict.type.tourism_couponManagement_type"
+                    :label="Number(dict.value)"
                     >{{ dict.label }}</el-radio>
                 </el-radio-group>
               </el-form-item>
-              <el-form-item label="变动量" prop="num">
-                <el-input-number v-model="form.num" controls-position="right" :precision="0" :min="0" placeholder="请输入变动量"></el-input-number>
+              <el-form-item label="优惠金额" class="is-required">
+                <div style="display: flex;">
+                  <span>订单满</span>
+                  <el-form-item label="" prop="buyAmount">
+                    <el-input-number v-model="form.buyAmount" controls-position="right" :min="0" placeholder="请输入"></el-input-number>
+                  </el-form-item>
+                  <span>减</span>
+                  <el-form-item label="" prop="quota">
+                    <el-input-number v-model="form.quota" controls-position="right" :min="0" placeholder="请输入"></el-input-number>
+                  </el-form-item>
+                  <span>{{ form.type == 1 ? '元':'折' }}</span>
+                </div>
               </el-form-item>
-              <el-form-item label="变动原因说明" prop="remark">
-                <el-input style="width: 350px;" type="textarea" v-model="form.remark" placeholder="请输入变动原因说明" maxlength="200" show-word-limit />
+              <el-form-item label="发放数量" prop="issuseNum">
+                <el-input-number v-model="form.issuseNum" controls-position="right" step-strictly :step="1" :min="0" placeholder="请输入发放数量"></el-input-number>
+                <span>张</span>
               </el-form-item>
-            </div>
-          </transition>
-
-          <transition name="el-zoom-in-top">
-            <div v-show="activeName == 'second'">
-              <el-form-item label="积分变动111" prop="type">
-                <el-radio-group v-model="form.type">
+              <el-form-item label="发放时间" prop="grantTime">
+                <el-date-picker
+                  v-model="form.grantTime"
+                  type="datetimerange"
+                  range-separator="至"
+                  start-placeholder="开始日期"
+                  value-format="yyyy-MM-dd HH:mm:ss"
+                  end-placeholder="结束日期">
+                </el-date-picker>
+              </el-form-item>
+              <el-form-item label="使用有效期:" prop="useType">
+                <el-radio-group v-model="form.useType" @input="radioInputs">
+                  <div style="display: flex;flex-direction: column;">
+                    <div style="display: flex;align-items: center;">
+                      <el-radio style="display: flex;align-items: center;" :label="1">
+                        <div style="display: flex;align-items: center;">
+                          <el-form-item label="" label-width="0" :prop="'useDate'">
+                            <span>指定时间</span>
+                            <el-date-picker
+                              :disabled="form.useType!=1"
+                              v-model="form.useDate"
+                              type="datetimerange"
+                              range-separator="至"
+                              start-placeholder="开始日期"
+                              value-format="yyyy-MM-dd HH:mm:ss"
+                              end-placeholder="结束日期">
+                            </el-date-picker>
+                          </el-form-item>
+                        </div>
+                      </el-radio>
+                    </div>
+                    <div style="display: flex;align-items: center;margin-top: 25px;">
+                      <el-radio style="display: flex;align-items: center;" :label="2">
+                        <div style="display: flex;align-items: center;"> 
+                          <el-form-item label="" label-width="0" :prop="'useDay'">
+                            <span>领取当日起</span>
+                            <el-input-number 
+                              :disabled="form.useType!=2"
+                              v-model="form.useDay" 
+                              step-strictly 
+                              :step="1"
+                              placeholder="请输入天数"
+                              controls-position="right">
+                            </el-input-number>
+                            <span>天内使用</span>
+                          </el-form-item>
+                        </div>
+                      </el-radio>
+                    </div>
+                    
+                  </div>
+                </el-radio-group>
+              </el-form-item>
+              <el-form-item label="优惠券背景图" prop="imag">
+                <div style="display: flex;">
+                  <div 
+                  v-for="(item,index) in form.imag" 
+                  :key="index"
+                  style="width: 100px; height: 100px;position: relative;border: 1px solid #999;border-radius: 5px;margin-right: 20px;">
+                    <el-image 
+                      style="width: 100%; height: 100%"
+                      :src="item" 
+                      :preview-src-list="form.imag">
+                    </el-image>
+                    <span @click="handleRemove(index)" style="position: absolute;top: -15px;right: -15px;color: red;font-size: 24px;z-index: 999;cursor: pointer;">
+                      <i class="el-icon-error"></i>
+                    </span>
+                  </div>
+                  <div 
+                  style="width: 100px; height: 100px;" 
+                  v-if="!form.imag||form.imag.length<1"
+                  v-loading="actionUrlLoading"
+                  element-loading-text="上传中..."
+                  element-loading-spinner="el-icon-loading"
+                  element-loading-background="rgba(0, 0, 0, 0.8)"
+                  >
+                    <el-upload
+                      class="avatar-uploader"
+                      :action="actionUrl"
+                      :data="{
+                        bucket: 'tourism'
+                      }"
+                      :show-file-list="false"
+                      :before-upload="beforeAvatarUpload"
+                      :on-success="handleAvatarSuccess"
+                      :on-progress="handleAvatarProgress"
+                      :disabled="actionUrlLoading"
+                      :on-error="handleAvatarError"
+                      >
+                      <i class="el-icon-plus avatar-uploader-icon"></i>
+                    </el-upload>
+                  </div>
+                  
+                </div>
+                <span>建议尺寸322px X 77px,支持jpg/png/gif,支持1MB大小以内的图片上传</span>
+              </el-form-item>
+          </div>
+          <div v-show="activeName == 'second'">
+              <el-form-item label="使用对象:" prop="useUserType" label-width="200px">
+                <el-radio-group v-model="form.useUserType" @input="form.useUserRelid = []">
                   <el-radio 
-                    v-for="dict in dict.type.tourism_memberInformation_biangeng_type"
-                    :label="dict.value"
+                    v-for="dict in dict.type.tourism_couponManagement_useUserType"
+                    :label="Number(dict.value)"
                     >{{ dict.label }}</el-radio>
                 </el-radio-group>
               </el-form-item>
-              <el-form-item label="变动量" prop="num">
-                <el-input-number v-model="form.num" controls-position="right" :precision="0" :min="0" placeholder="请输入变动量"></el-input-number>
+              <el-form-item label="会员等级" v-if="form.useUserType == 2" prop="useUserRelid_2" label-width="200px">
+                <selectMembershipLevel 
+                    v-model="form.useUserRelid_2"
+                    title="新增会员等级" 
+                    @submitForm="()=>$refs.form.validateField('useUserRelid_2')">
+                </selectMembershipLevel>
               </el-form-item>
-              <el-form-item label="变动原因说明" prop="remark">
-                <el-input style="width: 350px;" type="textarea" v-model="form.remark" placeholder="请输入变动原因说明" maxlength="200" show-word-limit />
+              <el-form-item label="会员号" v-if="form.useUserType == 3" prop="useUserRelid_3" label-width="200px">
+                <selectMemberInformation 
+                    v-model="form.useUserRelid_3"
+                    title="新增会员号" 
+                    @submitForm="()=>$refs.form.validateField('useUserRelid_3')">
+                </selectMemberInformation>
               </el-form-item>
-            </div>
-          </transition>
-          
-         
+              <el-form-item label="领取限制:" prop="receiveType" label-width="200px">
+                <div style="display: flex;align-items: center;">
+                  <el-radio-group v-model="form.receiveType" @input="radioInput">
+                    <div style="display: flex;align-items: center;">
+                      <el-radio :label="1">不限</el-radio>
+                      <el-radio style="display: flex;align-items: center;" :label="2">
+                        <el-form-item label="" label-width="0" :prop="'receiveNum'">
+                          <span>每人限领</span>
+                          <el-input-number 
+                          :disabled="form.receiveType!=2"
+                          v-model="form.receiveNum"
+                          controls-position="right" 
+                          step-strictly 
+                          :step="1"
+                          :min="0" 
+                          placeholder="请输入金额"></el-input-number>
+                          <span>张</span>
+                        </el-form-item>
+                      </el-radio>
+                    </div>
+                  </el-radio-group>
+                </div>
+              </el-form-item>
+              <el-form-item label="会员积分抵扣同时使用:" prop="isAdd" label-width="200px">
+                <el-radio-group v-model="form.isAdd">
+                  <el-radio 
+                    v-for="dict in dict.type.tourism_couponManagement_receiveType"
+                    :label="Number(dict.value)"
+                    >{{ dict.label }}</el-radio>
+                </el-radio-group>
+              </el-form-item>
+              <el-form-item label="适用产品:" prop="useConfig" label-width="200px">
+                <el-radio-group v-model="form.useConfig">
+                  <el-radio 
+                    v-for="dict in dict.type.tourism_couponManagement_useConfig"
+                    :label="Number(dict.value)"
+                    >{{ dict.label }}</el-radio>
+                </el-radio-group>
+              </el-form-item>
+              <el-form-item label="产品类型:" v-if="form.useConfig == 2" prop="useGoodType" label-width="200px">
+                <el-radio-group v-model="form.useGoodType">
+                  <el-radio 
+                    v-for="dict in dict.type.goods_type"
+                    :label="dict.value"
+                    >{{ dict.label }}</el-radio>
+                </el-radio-group>
+              </el-form-item>
+              <el-form-item label="" v-if="form.useConfig == 2 && form.useGoodType==1" prop="usePerform_1" label-width="200px">
+                <selectTicketOrders 
+                    v-model="form.usePerform_1"
+                    title="新增门票产品" 
+                    @submitForm="()=>$refs.form.validateField('usePerform_1')">
+                </selectTicketOrders>
+              </el-form-item>
+          </div>
         </el-form>
       </div>
     </div>
@@ -94,10 +256,13 @@ import {
   updateTableApi,
   addTableApi
  } from '@/api/CURD'
-
+import selectMembershipLevel from '../model/selectMembershipLevel.vue'
+import selectMemberInformation from '../model/selectMemberInformation.vue'
+import selectTicketOrders from "../model/selectTicketOrders.vue"
 export default {
   name: "addAndEdit",
-  dicts: ['tourism_memberInformation_biangeng_type'],
+  components: {selectMembershipLevel,selectMemberInformation,selectTicketOrders},
+  dicts: ['tourism_couponManagement_type','tourism_couponManagement_useUserType','tourism_couponManagement_receiveType','tourism_couponManagement_useConfig','goods_type'],
   data() {
     return {
       title: "",
@@ -107,20 +272,43 @@ export default {
       loadingText: "拼命加载数据中...",
       formStatus: null, // 0/null : 加载中 1 : 获取详情成功 2  : 获取详情失败 
       configUrl: {
-        add: '/member/memberInfo/updateCredit', // 新增地址
-        details: '/member/memberInfo/detail', // 详情地址
-        edit: '/member/memberInfo/updateCredit', // 编辑地址
+        add: '/merchant/merchantCouponInfo/insertOrUpdate', // 新增地址
+        details: '/merchant/merchantCouponInfo/selectById', // 详情地址
+        edit: '/merchant/merchantCouponInfo/insertOrUpdate', // 编辑地址
       },
       form: {
         id: undefined,
       },
       rules: {
-        type: [{ required: true, message: "请选择积分变动", trigger: ["change","blur"] }],
-        num: [{ required: true, message: "请输入变动量", trigger: ["change","blur"] }],
-        remark: [{ required: true, message: "请输入变动原因说明", trigger: ["change","blur"] }],
+        couponName: [{ required: true, message: "请输入优惠券名称", trigger: ["change","blur"] }],
+        remark: [{ required: true, message: "请输入券种说明", trigger: ["change","blur"] }],
+        type: [{ required: true, message: "请选择券种类型", trigger: ["change","blur"] }],
+        buyAmount: [{ required: true, message: "请输入订单门槛金额", trigger: ["change","blur"] }],
+        quota: [{ required: true, message: "请输入满减金额/折扣", trigger: ["change","blur"] }],
+        issuseNum: [{ required: true, message: "请输入发放数量", trigger: ["change","blur"] }],
+        grantTime: [{ required: true, message: "请选择发放时间", trigger: ["change","blur"] }],
+        
+        useType: [{ required: true, message: "请选择使用有效期", trigger: ["change","blur"] }],
+        useDate: [{ required: false, message: "请选择指定时间", trigger: ["change","blur"] }],
+        useDay: [{ required: false, message: "请输入天数", trigger: ["change","blur"] }],
+        imag: [{ required: true, message: "请上传图片", trigger: ["change","blur"] }],
+
+        useUserType: [{ required: true, message: "请选择使用对象", trigger: ["change","blur"] }],
+        useUserRelid_2: [{ required: true, message: "请选择会员等级", trigger: ["change","blur"] }],
+        useUserRelid_3: [{ required: true, message: "请选择会员号", trigger: ["change","blur"] }],
+        receiveType: [{ required: true, message: "请选择是否领取限制", trigger: ["change","blur"] }],
+        receiveNum: [{ required: false, message: "请输入每人限领数量", trigger: ["change","blur"] }],
+        isAdd: [{ required: true, message: "请选择是否会员积分抵扣同时使用", trigger: ["change","blur"] }],
+        
+        useConfig: [{ required: true, message: "请选择适用产品", trigger: ["change","blur"] }],
+        useGoodType: [{ required: true, message: "请选择产品类型", trigger: ["change","blur"] }],
+        usePerform_1: [{ required: true, message: "请选择门票产品", trigger: ["change","blur"] }],
       },
 
       activeName: 'first',
+
+      actionUrl: process.env.VUE_APP_BASE_API + process.env.VUE_APP_UPLOAD_IMAGE,
+      actionUrlLoading: false,
     };
   },
   methods: {
@@ -133,11 +321,27 @@ export default {
       this.model = model
       this.formStatus = 0
       if(model=='ADD') { // 新增
-        this.$set(this,'form',row)
+        this.$set(this,'form',{
+          ...row,
+          grantTime: [], // 发放时间段
+          useDate: [], // 使用指定时间
+          type: 1,
+          useType: 1,
+          useUserType: 1,
+          receiveType: 1,
+          isAdd: 1,
+          useConfig: 1,
+          useGoodType: null,
+          imag: [],
+          useUserRelid_2: [],
+          useUserRelid_3: [],
+          usePerform_1: []
+        })
         this.formStatus = 1
       }else if(model=='EDIT') { // 新增
         let obj = {
-          ...row
+          ...row,
+          imag: row.imag?row.imag.split(','):[],
         }
         this.$set(this,'form',{
           memberId: row.id
@@ -147,6 +351,8 @@ export default {
         await this.getTableDeatilsFun(row)
       }
       this.loading = false
+      this.radioInputs(this.form.useType)
+      this.radioInput(this.form.receiveType)
       this.$nextTick(()=>{
         if(this.$refs["form"]) {
           this.$refs["form"].clearValidate();
@@ -161,8 +367,33 @@ export default {
         let res = await getTableDeatilsByIdApi(this.configUrl.details,{id})
         if(res.code == 200) {
           let obj = {
-            ...res.data
+            ...res.data,
+            grantTime: [res.data.issuseStartDate,res.data.issuseEndDate], // 发放时间段
+            imag: res.data.imag?res.data.imag.split(','):[],
+            quota: res.data.type == 1?res.data.quota:(res.data.quota)*10
+          }
+          if(obj.useType == 1) {
+            obj['useDate'] = [res.data.useStartDate,res.data.useEndDate] // 使用指定时间
+          }else if(obj.useType == 2){
+            obj['useDay'] = obj.useDay
+          }
+          if(obj.useUserType == 2) {
+            obj['useUserRelid_2'] = obj.useUserRelidList?obj.useUserRelidList:[]
+          }else if(obj.useUserType == 3){
+            obj['useUserRelid_3'] = obj.useUserRelidList?obj.useUserRelidList:[]
+          }else {
+            obj['useUserRelid_2'] = []
+            obj['useUserRelid_3'] = []
           }
+          if(obj.useConfig == 2) {
+            if(obj.useGoodType == 1) {
+              obj['usePerform_1'] = obj.usePerformList?obj.usePerformList:[]
+            }else {
+              obj['usePerform_1'] = []
+            }
+          }
+          
+          
           this.$set(this,'form',JSON.parse(JSON.stringify(obj)))
           this.formStatus = 1
         }else {
@@ -185,14 +416,51 @@ export default {
      * @returns {any}
      */
     submitForm() {
-      this.$refs["form"].validate(valid => {
+      this.$refs["form"].validate((valid ,object)=> {
         if (valid) {
           this.loadingText = "提交数据中..."
           this.loading = true
+          let param = JSON.parse(JSON.stringify(this.form))
+          param['issuseStartDate'] = param.grantTime[0]
+          param['issuseEndDate'] = param.grantTime[1]
+
+          param['useStartDate'] = param.useDate[0]
+          param['useEndDate'] = param.useDate[1]
+          if(param.useUserType == 2) {
+            let list = this.form.useUserRelid_2.map((item)=> item.id)
+            param['useUserRelid'] = list.join(',')
+           }else if(param.useUserType == 3){
+            let list = this.form.useUserRelid_3.map((item)=> item.id)
+            param['useUserRelid'] = list.join(',')
+          }else {
+            param['useUserRelid'] = ''
+          }
+
+          param['usePerform'] = ''
+          if(param.useConfig == 2) {
+            if(param.useGoodType == 1) {
+              let list = this.form.usePerform_1.map((item)=> item.id)
+              param['usePerform'] = list.join(',')
+            }
+          }
+          if(this.form.type == 1){
+            param['quota'] = this.form.quota
+          }else {
+            param['quota'] = (this.form.quota)/10
+          }
+          delete param.grantTime
+          delete param.useDate
+          delete param.useUserRelid_2
+          delete param.useUserRelid_3
+          delete param.useUserRelidList
+
+          delete param.usePerformList
+          delete param.usePerform_1
           if (this.model != 'ADD') {
             addTableApi(
               this.configUrl.edit,{
-                ...this.form
+                ...param,
+                imag: param.imag ? param.imag.join(','):'',
               }).then(response => {
               this.$modal.msgSuccess("修改成功");
               this.loading = false
@@ -204,7 +472,8 @@ export default {
             })
           } else {
             addTableApi(this.configUrl.edit,{
-                ...this.form
+                ...param,
+                imag: param.imag ? param.imag.join(','):'',
               }).then(response => {
               this.$modal.msgSuccess("新增成功");
               this.loading = false
@@ -215,6 +484,18 @@ export default {
               this.loading = false
             })
           }
+        }else {
+          console.log("fsdfsd===",valid,object)
+          if(object&&JSON.stringify(object)!='{}') {
+            let srt = ''
+            for(let key in object) {
+              if(object.hasOwnProperty(key)) {
+                srt = srt + `[${object[key][0].message}],`
+              }
+            }
+            this.$message.error(srt);
+          }
+          
         }
       });
     },
@@ -240,7 +521,63 @@ export default {
     /**  点击tab  */
     handleClick() {
 
-    }
+    },
+
+    /**    */
+    radioInput(value) {
+      if( value == 1 ){
+        this.rules.receiveNum[0].required = false
+        this.$refs.form.clearValidate('receiveNum');
+      }else if( value == 2 ) {
+        this.rules.receiveNum[0].required = true
+        this.$refs.form.clearValidate('receiveNum');
+      }
+    },
+    /**  使用有效期   */
+    radioInputs(value) {
+      if( value == 1 ){
+        this.rules.useDate[0].required = true
+        this.rules.useDay[0].required = false
+        this.$refs.form.clearValidate('useDate');
+        this.$refs.form.clearValidate('useDay');
+      }else if( value == 2 ) {
+        this.rules.useDate[0].required = false
+        this.rules.useDay[0].required = true
+        this.$refs.form.clearValidate('useDate');
+        this.$refs.form.clearValidate('useDay');
+      }
+    },
+
+    /**  上传图片 单张  */
+    handleAvatarSuccess(response, file, fileList) {
+      console.log("res, file",response, file, fileList)
+      this.actionUrlLoading = false
+      if(response.code == 200) {
+        this.form.imag.push(response.data.url)
+      }
+    },
+    beforeAvatarUpload(file) {
+      const isLt2M = file.size / 1024 / 1024 <= 1;
+      let testmsg = file.name.substring(file.name.lastIndexOf('.')+1)
+      let typeList = ['png','jepg','jpg']
+      const isJPG = typeList.includes(testmsg);
+      if (!isJPG) {
+        this.$message.error(`上传图片图片只能是 ${typeList} 格式!`);
+      }
+      if (!isLt2M) {
+        this.$message.error('上传图片图片大小不能超过 1MB!');
+      }
+      return isJPG && isLt2M;
+    },
+    handleAvatarProgress(){
+      this.actionUrlLoading = true
+    },
+    handleAvatarError() {
+      this.actionUrlLoading = false
+    },
+    handleRemove(index) {
+      this.form.imag.splice(index,1)
+    },
   },
 };
 </script>
@@ -354,6 +691,30 @@ export default {
     }
   }
 }
+
+::v-deep .avatar-uploader .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+  }
+  ::v-deep .avatar-uploader .el-upload:hover {
+    border-color: #409EFF;
+  }
+  ::v-deep .avatar-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 100px;
+    height: 100px;
+    line-height: 100px;
+    text-align: center;
+  }
+  ::v-deep .avatar {
+    width: 100px;
+    height: 100px;
+    display: block;
+  }
 </style>
 <style>
 .custom-class-box {

+ 533 - 0
src/views/tourism/marketingActivities/formBox/eventManagementForm.vue

@@ -0,0 +1,533 @@
+<template>
+  <el-dialog :title="title" :visible.sync="open" width="95%" append-to-body :close-on-click-modal="false"
+    @close="cancel">
+    <div class="form-dialog-box" v-loading="loading" :element-loading-text="loadingText"
+      element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0)">
+      <div v-loading="loading" :element-loading-text="''" element-loading-spinner="''"
+        element-loading-background="rgba(0, 0, 0, 0.8)">
+        <el-tabs v-model="activeName" @tab-click="handleClick">
+          <el-tab-pane label="基本信息" name="first"></el-tab-pane>
+          <el-tab-pane label="使用规则" name="second"></el-tab-pane>
+        </el-tabs>
+        <el-form :model="form" ref="form" :rules="rules" label-width="120px">
+          <div v-show="activeName == 'first'">
+            <el-form-item label="优惠券名称" prop="remark">
+              <el-input style="width: 350px;" v-model="form.remark" placeholder="请输入优惠券名称" maxlength="50"
+                show-word-limit />
+            </el-form-item>
+            <el-form-item label="券种说明" prop="remark">
+              <el-input style="width: 350px;" type="textarea" v-model="form.remark" placeholder="请输入券种说明"
+                maxlength="200" show-word-limit />
+            </el-form-item>
+            <el-form-item label="券种类型" prop="type">
+              <el-radio-group v-model="form.type">
+                <el-radio v-for="dict in dict.type.tourism_memberInformation_biangeng_type" :label="dict.value">{{
+                  dict.label }}</el-radio>
+              </el-radio-group>
+            </el-form-item>
+            <el-form-item label="优惠金额" class="is-required">
+              <div style="display: flex;">
+                <span>订单满</span>
+                <el-form-item label="" prop="num">
+                  <el-input-number v-model="form.num" controls-position="right" :precision="0" :min="0"
+                    placeholder="请输入金额"></el-input-number>
+                </el-form-item>
+                <span>减</span>
+                <el-form-item label="" prop="num">
+                  <el-input-number v-model="form.num" controls-position="right" :precision="0" :min="0"
+                    placeholder="请输入金额"></el-input-number>
+                </el-form-item>
+              </div>
+            </el-form-item>
+            <el-form-item label="发放数量" prop="num">
+              <el-input-number v-model="form.num" controls-position="right" :precision="0" :min="0"
+                placeholder="请输入发放数量"></el-input-number>
+              <span>张</span>
+            </el-form-item>
+            <el-form-item label="发放时间" prop="useExpireDateTime">
+              <el-date-picker v-model="form.useExpireDateTime" type="daterange" range-separator="至"
+                start-placeholder="开始日期" value-format="yyyy-MM-dd" end-placeholder="结束日期">
+              </el-date-picker>
+            </el-form-item>
+            <el-form-item label="使用有效期:" prop="useExpireDateRadio">
+              <el-radio-group v-model="form.useExpireDateRadio" @input="radioInputs">
+                <div style="display: flex;flex-direction: column;">
+                  <div style="display: flex;align-items: center;">
+                    <el-radio style="display: flex;align-items: center;" label="3">
+                      <div style="display: flex;align-items: center;">
+                        <el-form-item label="" label-width="0" :prop="'useExpireDateTime'">
+                          <span>指定时间</span>
+                          <el-date-picker :disabled="form.useExpireDateRadio != 3" v-model="form.useExpireDateTime"
+                            type="daterange" range-separator="至" start-placeholder="开始日期" value-format="yyyy-MM-dd"
+                            end-placeholder="结束日期">
+                          </el-date-picker>
+                        </el-form-item>
+                      </div>
+                    </el-radio>
+                  </div>
+                  <div style="display: flex;align-items: center;margin-top: 25px;">
+                    <el-radio style="display: flex;align-items: center;" label="2">
+                      <div style="display: flex;align-items: center;">
+                        <el-form-item label="" label-width="0" :prop="'useExpireDateDay'">
+                          <span>领取当日起</span>
+                          <el-input-number :disabled="form.useExpireDateRadio != 2" v-model="form.useExpireDateDay"
+                            placeholder="请输入天数" controls-position="right">
+                          </el-input-number>
+                          <span>天内使用</span>
+                        </el-form-item>
+                      </div>
+                    </el-radio>
+                  </div>
+
+                </div>
+              </el-radio-group>
+            </el-form-item>
+            <el-form-item label="优惠券背景图" prop="imgUrl">
+              <div style="display: flex;">
+                <div v-for="(item, index) in form.imgUrl" :key="index"
+                  style="width: 100px; height: 100px;position: relative;border: 1px solid #999;border-radius: 5px;margin-right: 20px;">
+                  <el-image style="width: 100%; height: 100%" :src="item" :preview-src-list="form.imgUrl">
+                  </el-image>
+                  <span @click="handleRemove(index)"
+                    style="position: absolute;top: -15px;right: -15px;color: red;font-size: 24px;z-index: 999;cursor: pointer;">
+                    <i class="el-icon-error"></i>
+                  </span>
+                </div>
+                <div style="width: 100px; height: 100px;" v-if="!form.imgUrl || form.imgUrl.length < 1"
+                  v-loading="actionUrlLoading" element-loading-text="上传中..." element-loading-spinner="el-icon-loading"
+                  element-loading-background="rgba(0, 0, 0, 0.8)">
+                  <el-upload class="avatar-uploader" :action="actionUrl" :data="{
+                    bucket: 'tourism'
+                  }" :show-file-list="false" :before-upload="beforeAvatarUpload" :on-success="handleAvatarSuccess"
+                    :on-progress="handleAvatarProgress" :disabled="actionUrlLoading" :on-error="handleAvatarError">
+                    <i class="el-icon-plus avatar-uploader-icon"></i>
+                  </el-upload>
+                </div>
+
+              </div>
+              <span>支持jpg、png,支持1MB大小以内的图片上传</span>
+            </el-form-item>
+          </div>
+
+          <div v-show="activeName == 'second'">
+            <asEditor />
+          </div>
+        </el-form>
+      </div>
+    </div>
+    <span slot="footer" class="dialog-footer" v-if="formStatus == 1">
+      <el-button @click="cancel">取消</el-button>
+      <el-button type="primary" @click="submitForm" :loading="loading" element-loading-text="提交中..."
+        element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)">
+        {{ loading ? '提交中...' : '保存' }}
+      </el-button>
+    </span>
+    <!-- 添加或修改对话框 End -->
+  </el-dialog>
+</template>
+
+<script>
+import {
+  getTableDeatilsByIdApi,
+  updateTableApi,
+  addTableApi
+} from '@/api/CURD'
+import asEditor from "@/myComponents/asEditor"
+export default {
+  name: "addAndEdit",
+  dicts: ['tourism_memberInformation_biangeng_type'],
+  components: {asEditor},
+  data() {
+    return {
+      title: "",
+      model: "", // EDIT: 编辑模式 ADD : 新增模式  EDITInit : 编辑模式(需要请求详情)
+      open: false,
+      loading: false,
+      loadingText: "拼命加载数据中...",
+      formStatus: null, // 0/null : 加载中 1 : 获取详情成功 2  : 获取详情失败 
+      configUrl: {
+        add: '/member/memberInfo/updateCredit', // 新增地址
+        details: '/member/memberInfo/detail', // 详情地址
+        edit: '/member/memberInfo/updateCredit', // 编辑地址
+      },
+      form: {
+        id: undefined,
+      },
+      rules: {
+        type: [{ required: true, message: "请选择积分变动", trigger: ["change", "blur"] }],
+        num: [{ required: true, message: "请输入变动量", trigger: ["change", "blur"] }],
+        remark: [{ required: true, message: "请输入变动原因说明", trigger: ["change", "blur"] }],
+
+        dayTypeRadio: [{ required: true, message: "请选择日期类型", trigger: ["change", "blur"] }],
+        dayType: [{ required: false, message: "请选择时间范围", trigger: ["change", "blur"] }],
+
+        useExpireDateRadio: [{ required: true, message: "请输入变动原因说明", trigger: ["change", "blur"] }],
+        useExpireDateDay: [{ required: false, message: "请输入天数", trigger: ["change", "blur"] }],
+        useExpireDateTime: [{ required: false, message: "请选择时间", trigger: ["change", "blur"] }],
+
+      },
+
+      activeName: 'first',
+      
+      actionUrl: process.env.VUE_APP_BASE_API + process.env.VUE_APP_UPLOAD_IMAGE,
+      actionUrlLoading: false,
+    };
+  },
+  methods: {
+    async initData(title, model, row) {
+      this.title = title
+      this.activeName = 'first'
+      this.open = true
+      this.loadingText = "拼命加载数据中..."
+      this.loading = true
+      this.model = model
+      this.formStatus = 0
+      if (model == 'ADD') { // 新增
+        this.$set(this, 'form', {
+          ...row,
+          imgUrl: [],
+        })
+        this.formStatus = 1
+      } else if (model == 'EDIT') { // 新增
+        let obj = {
+          ...row,
+          imgUrl: row.imgUrl ? row.imgUrl.split(',') : [],
+        }
+        this.$set(this, 'form', {
+          memberId: row.id
+        })
+        this.formStatus = 1
+      } else if (model == 'EDITInit') { // 新增
+        await this.getTableDeatilsFun(row)
+      }
+      this.loading = false
+      this.$nextTick(() => {
+        if (this.$refs["form"]) {
+          this.$refs["form"].clearValidate();
+        }
+      })
+    },
+    /** 获取详情 */
+    async getTableDeatilsFun(row) {
+      const id = row.id
+      this.loading = true
+      try {
+        let res = await getTableDeatilsByIdApi(this.configUrl.details, { id })
+        if (res.code == 200) {
+          let obj = {
+            ...res.data,
+            imgUrl: res.data.imgUrl ? res.data.imgUrl.split(',') : [],
+          }
+          this.$set(this, 'form', JSON.parse(JSON.stringify(obj)))
+          this.formStatus = 1
+        } else {
+          this.$message.error('获取详情失败!!!');
+          this.formStatus = 2
+          this.loading = false
+          this.open = false;
+        }
+        this.loading = false
+      } catch (error) {
+        console.error('获取详情失败!!!!', error)
+        this.formStatus = 2
+        this.loading = false
+        this.open = false;
+      }
+    },
+    /**
+     * 保存
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    submitForm() {
+      this.$refs["form"].validate((valid, object) => {
+        if (valid) {
+          this.loadingText = "提交数据中..."
+          this.loading = true
+          if (this.model != 'ADD') {
+            addTableApi(
+              this.configUrl.edit, {
+              ...this.form,
+              imgUrl: this.form.imgUrl ? this.form.imgUrl.join(',') : '',
+            }).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.loading = false
+              this.open = false;
+              this.$emit('refresh')
+            }).catch(() => {
+              this.$message.error("修改失败!!!");
+              this.loading = false
+            })
+          } else {
+            addTableApi(this.configUrl.edit, {
+              ...this.form,
+              imgUrl: this.form.imgUrl ? this.form.imgUrl.join(',') : '',
+            }).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.loading = false
+              this.open = false;
+              this.$emit('refresh')
+            }).catch(() => {
+              this.$message.error("新增失败!!!");
+              this.loading = false
+            })
+          }
+        } else {
+          console.log("fsdfsd===", valid, object)
+          if (object && JSON.stringify(object) != '{}') {
+            let srt = ''
+            for (let key in object) {
+              if (object.hasOwnProperty(key)) {
+                srt = srt + `[${object[key][0].message}],`
+              }
+            }
+            this.$message.error(srt);
+          }
+
+        }
+      });
+    },
+    /**
+     * 重置
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    reset() {
+      if (this.$refs["form"]) {
+        this.$refs["form"].clearValidate();
+      }
+    },
+    /**
+     * 关闭弹框
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    cancel() {
+      this.reset();
+      this.open = false;
+    },
+    /**  点击tab  */
+    handleClick() {
+
+    },
+
+    /**    */
+    radioInput(key, value) {
+      console.log('key,value===', key, value)
+      if (value == -2) {
+        this.rules[key][0].required = true
+      } else {
+        this.rules[key][0].required = false
+      }
+    },
+    /**  使用有效期   */
+    radioInputs(value) {
+      if (value == 1) {
+        this.rules.useExpireDateDay[0].required = false
+        this.rules.useExpireDateTime[0].required = false
+        this.$refs.form.clearValidate('useExpireDateTime');
+        this.$refs.form.clearValidate('useExpireDateDay');
+      } else if (value == 2) {
+        this.rules.useExpireDateDay[0].required = true
+        this.rules.useExpireDateTime[0].required = false
+        this.$refs.form.clearValidate('useExpireDateTime');
+      } else if (value == 3) {
+        this.rules.useExpireDateDay[0].required = false
+        this.rules.useExpireDateTime[0].required = true
+        this.$refs.form.clearValidate('useExpireDateDay');
+      }
+    },
+
+    /**  上传图片 单张  */
+    handleAvatarSuccess(response, file, fileList) {
+      console.log("res, file", response, file, fileList)
+      this.actionUrlLoading = false
+      if (response.code == 200) {
+        this.form.imgUrl.push(response.data.url)
+      }
+    },
+    beforeAvatarUpload(file) {
+      const isLt2M = file.size / 1024 / 1024 < 1;
+      let testmsg = file.name.substring(file.name.lastIndexOf('.') + 1)
+      let typeList = ['png', 'jepg', 'jpg']
+      const isJPG = typeList.includes(testmsg);
+      if (!isJPG) {
+        this.$message.error(`上传图片图片只能是 ${typeList} 格式!`);
+      }
+      if (!isLt2M) {
+        this.$message.error('上传图片图片大小不能超过 1MB!');
+      }
+      return isJPG && isLt2M;
+    },
+    handleAvatarProgress() {
+      this.actionUrlLoading = true
+    },
+    handleAvatarError() {
+      this.actionUrlLoading = false
+    },
+    handleRemove(index) {
+      this.form.imgUrl.splice(index, 1)
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.form-dialog-box {
+  padding: 0 30px;
+  padding: 0 30px;
+  min-height: 50vh;
+  max-height: 65vh;
+  overflow-y: auto;
+
+  >div {
+    width: 100%;
+    min-height: 50vh;
+  }
+
+  .form-title {
+    padding: 0 0 10px 0;
+
+    span {
+      display: flex;
+      color: rgba(65, 80, 88, 1);
+      font-size: 16px;
+      font-family: SourceHanSansSC;
+      font-weight: 700;
+      line-height: 23px;
+      border-left: 4px solid rgb(22, 132, 252);
+      padding-left: 10px;
+    }
+
+  }
+
+  ::v-deep .ql-editor {
+    height: 400px;
+  }
+
+  .upload-btn {
+    width: 100px;
+    height: 100px;
+    background-color: #fbfdff;
+    border: dashed 1px #c0ccda;
+    border-radius: 5px;
+
+    i {
+      font-size: 30px;
+      margin-top: 20px;
+    }
+
+    &-text {
+      margin-top: -10px;
+    }
+  }
+
+  .avatar {
+    cursor: pointer;
+  }
+}
+
+.el-table {
+  .upload-btn {
+    width: 100px;
+    height: 100px;
+    background-color: #fbfdff;
+    border: dashed 1px #c0ccda;
+    border-radius: 5px;
+
+    i {
+      font-size: 30px;
+      margin-top: 20px;
+    }
+
+    &-text {
+      margin-top: -10px;
+    }
+  }
+
+  .avatar {
+    cursor: pointer;
+  }
+}
+
+.area-container {
+  min-height: 400px;
+}
+
+::v-deep .area-wrap-city.el-cascader {
+  line-height: normal;
+
+  .el-input {
+    cursor: pointer;
+    width: 100% !important;
+    height: 28px !important;
+
+    .el-input__inner {
+      display: none !important;
+    }
+
+    span.el-input__suffix {
+      position: inherit !important;
+
+      i.el-input__icon {
+        line-height: inherit;
+        margin-left: 5px;
+      }
+    }
+
+    .el-input__wrapper {
+      box-shadow: none;
+
+      input {
+        display: none;
+      }
+    }
+  }
+
+  .el-cascader__tags {
+    display: none;
+  }
+}
+
+.area-city-popper {
+  .el-cascader-panel {
+    .el-scrollbar.el-cascader-menu {
+      .el-cascader-menu__wrap.el-scrollbar__wrap {
+        height: 315px;
+      }
+    }
+  }
+}
+
+::v-deep .avatar-uploader .el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+}
+
+::v-deep .avatar-uploader .el-upload:hover {
+  border-color: #409EFF;
+}
+
+::v-deep .avatar-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 100px;
+  height: 100px;
+  line-height: 100px;
+  text-align: center;
+}
+
+::v-deep .avatar {
+  width: 100px;
+  height: 100px;
+  display: block;
+}
+</style>
+<style>
+.custom-class-box {
+  z-index: 999999 !important;
+}
+</style>

+ 489 - 0
src/views/tourism/marketingActivities/model/selectMemberInformation.vue

@@ -0,0 +1,489 @@
+<template>
+    <div class="select-more-box">
+        
+        <div class="select-more-item">
+            <div class="c_left_tag" v-if="modalDetails.length>0">
+                <el-tag class="tag" size="closable" v-for="(item, index) in modalDetails" :key="index"
+                    @close="handleCloseCopy(item)" closable>
+                    {{ item.name }}
+                    </el-tag>
+            </div>
+            <span style="color: #c0c0c0;" v-else>请点击添加,选择会员号</span>
+            <div class="select-more-tool" v-if="isAdd">
+                <span>目前已选择:{{ modalDetails.length }}个</span>
+                <div class="select-more-but-add" @click="dialogVisible = true"><span>添加</span><span>+</span></div>
+                <div class="select-more-but-clear" @click="clearModalDetails"><span>清除已选</span></div>
+            </div>
+        </div>
+        <el-dialog 
+        append-to-body 
+        :title="title" 
+        :visible.sync="dialogVisible" 
+        @open="dialogOpen" 
+        @close="dialogClose"
+        :close-on-click-modal="false"
+        :destroy-on-close="true" 
+        width="900px" 
+        class="information-dialog"
+        custom-class="template-con-dialog" top="auto">
+            <div class="form-con" v-loading="loading">
+                <div class="form_content">
+                    <!-- left -->
+                    <div class="c_left">
+                        <div class="c_left_btn">
+                            <div>已选成员</div>
+                            <el-button type="text" @click="clearUser">清空</el-button>
+                        </div>
+                        <div class="c_left_tag">
+                            <el-tag class="tag" size="closable" v-for="(item, index) in nameList" :key="index"
+                                @close="handleClose(item)" closable>
+                                {{ item.name }}
+                            </el-tag>
+                        </div>
+                    </div>
+                    <!-- right -->
+                    <div class="c_right">
+                        <div class="c_input">
+                            <el-input size="mini" prefix-icon="el-icon-search" v-model="userValue" placeholder="输入搜索"></el-input>
+                            <el-button style="margin-left: 10px;" size="mini" @click="searchFun(false)">
+                                重置
+                            </el-button>
+                            <el-button size="mini" @click="searchFun(true)" type="primary">
+                                搜索
+                            </el-button>
+                        </div>
+                        <div class="c_checkbox" v-loading="listLoading">
+                            <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll"
+                                @change="handleCheckAllChange">全选当前页</el-checkbox>
+                           <div style="margin: 15px 0;"></div>
+                            <div class="c_checkbox_item" v-for="(item, index) in dataList" :key="index">
+                                <el-checkbox 
+                                class="checkBox_item" 
+                                v-model="item.checked"
+                                @change="(val)=>changeCheckbox(item,index,val)"
+                                    :key="index">{{
+                                        item.name
+                                    }}</el-checkbox>
+                            </div>
+                            
+                        </div>
+                        <div class="c_pagination">
+                            <el-pagination
+                            v-if="!listLoading"
+                            small
+                            background
+                            layout="total, prev, pager, next"
+                            :page-sizes="page.pageSizes"
+                            :page-size="page.pageSize"
+                            :total="page.total"
+                            :current-page="page.pageNum"
+                            @size-change="handleSizeChange"
+                            @current-change="handleCurrentChange"
+                            >
+                            </el-pagination>
+                        </div>
+                    </div>
+                </div>
+    
+                <div class="drawer-footer">
+                    <el-button @click="dialogVisible = false">
+                        取消
+                    </el-button>
+                    <el-button @click="submitForm()" type="primary">
+                        确定
+                    </el-button>
+                </div>
+            </div>
+        </el-dialog>
+    </div>
+    
+</template>
+  
+<script>
+import { 
+    listTableApi, 
+  } from "@/api/CURD";
+export default {
+    props: {
+        title: {
+            type: String,
+            default: '新增',
+        },
+        value: {
+            type: Array,
+            default: ()=>{
+                return []
+            },
+        },
+        idKey: {
+            type: String,
+            default: 'id',
+        },
+        nameKey: {
+            type: String,
+            default: 'name',
+        },
+        isAdd: {
+            type: Boolean,
+            default: true,
+        }
+    },
+    data() {
+        return {
+            dialogVisible: false, //弹窗选择
+            userValue: '', //人员搜索
+            dataList: [], //数据列表集合
+            nameList: [],//已选择人员
+            checkAll: false,
+            checkedUsers: [], // 选中的
+            isIndeterminate: false,
+            modalDetails: [],
+            loading: false,// 
+            page: {
+                pageSizes: [100, 200, 300, 400],
+                pageSize: 10,
+                pageNum: 1,
+                total: 0,
+            },
+            configUrl: {
+                list: '/member/memberInfo/list', // 列表地址
+            },
+            listLoading: false,
+        }
+    },
+    watch: {
+        value: {
+            handler(newValue){
+                console.log("dfsdsfsdf====",this.value)
+                if(this.value) {
+                    this.modalDetails = JSON.parse(JSON.stringify(this.value))
+                }else {
+                    this.modalDetails = []
+                }
+            },
+            immediate: true
+        }
+    },
+    methods: {
+        // 弹窗组件显示事件
+        async dialogOpen() {
+            this.loading = true
+            this.listLoading = false
+            this.userValue = ''
+            this.$set(this.page,'pageNum',1)
+            if (this.modalDetails.length) {
+                this.modalDetails.forEach((item) => {
+                    this.checkedUsers.push(item.id)
+                })
+                this.nameList = this.modalDetails//已选择人员
+                this.checkAll = false
+                this.isIndeterminate = false
+                this.userValue = '' //人员搜索
+            } else {
+                this.nameList = []//已选择人员
+                this.checkAll = false
+                this.checkedUsers = [] // 选中的
+                this.isIndeterminate = false
+                this.userValue = '' //人员搜索
+            }
+            await this.listUser()
+            this.loading = false
+        },
+        /**  搜索   */
+        searchFun(type) {
+            this.listLoading = true
+            if(!type) {
+                this.userValue = ''
+            }
+            this.listUser()
+        },
+        // 查询支部人员集合
+        async listUser() {
+            try {
+                this.dataList = []
+                let res = await listTableApi(this.configUrl.list,{
+                    realName: this.userValue,
+                    pageNum: this.page.pageNum,
+                    pageSize: this.page.pageSize
+                })
+                if (res.code == 200) {
+                    let list = []
+                    let listId = []
+                    this.nameList.forEach((item1,index1)=>{
+                        listId.push(item1.id)
+                    })
+                    res.data.rows.forEach((item,index)=>{
+                        list.push({
+                            ...item,
+                            id: item[this.idKey],
+                            name: item[this.nameKey],
+                            checked: listId.includes(item[this.idKey])
+                        })
+                    })
+                    this.dataList = list
+                    this.$set(this.page,'total',res.data.total)
+                } else {
+                    this.$message({
+                        type: 'error',
+                        message: res.msg
+                    });
+                }
+                this.checkedCurrentPageAll()
+                this.listLoading = false
+            } catch (error) {
+                this.checkedCurrentPageAll()
+                this.loading = false
+                this.listLoading = false
+                this.dialogVisible = false
+            }
+        },
+        // 清空按钮
+        clearUser() {
+            this.handleCheckAllChange(false)
+            this.isIndeterminate = false;
+            this.checkAll = false
+        },
+        // 清除全部
+        clearModalDetails() {
+            this.$emit('input', [])
+            this.$emit('submitForm')
+        },
+        // 单项删除已选按钮 (外部)
+        handleCloseCopy(item) {
+            let arr = this.modalDetails.filter((item1) => {
+                return item.id != item1.id
+            })
+            this.$emit('input', arr)
+            this.$emit('submitForm')
+        },
+        // 单项删除已选按钮 (备选)
+        handleClose(item) {
+            let arr = this.nameList.filter((item1) => {
+                return item.id != item1.id
+            })
+            let listId = []
+            arr.forEach((item,index) => {
+                listId.push(item.id)
+            })
+            let list = JSON.parse(JSON.stringify(this.dataList))
+            list.forEach((item,index) => {
+                list[index].checked = listId.includes(item.id)
+            })
+            this.nameList = arr
+            this.dataList = list
+            this.checkedCurrentPageAll()
+        },
+        // 全选当前页按钮
+        handleCheckAllChange(val) {
+            let list = JSON.parse(JSON.stringify(this.dataList))
+            let listId = []
+            list.forEach((item,index) => {
+                list[index].checked = val
+                listId.push(item.id)
+            })
+            let listExist = this.nameList.filter((item,index)=>{
+                return !listId.includes(item.id)
+            })
+            list.forEach((item,index) => {
+                if(item.checked) {
+                    listExist.push({
+                        ...item
+                    })
+                } 
+            })
+            this.dataList = list
+            this.nameList = listExist
+            this.isIndeterminate = false;
+        },
+        /** 检测当前页是否全选  */
+        checkedCurrentPageAll() {
+            let length = 0
+            let list = JSON.parse(JSON.stringify(this.dataList))
+            list.forEach((item,index) => {
+                if(item.checked) {
+                    length++
+                }
+            })
+            this.checkAll = (length == list.length)&& length != 0
+        },
+        // 弹窗组件关闭事件
+        dialogClose() {
+        },
+        // 提交表单事件
+        submitForm() {
+            this.$emit('input', JSON.parse(JSON.stringify(this.nameList)))
+            this.$emit('submitForm')
+            this.dialogVisible = false
+        },
+        /** 调整每页选择条数  */
+        handleSizeChange(val) {
+        },
+        /** 点击页码  */
+        handleCurrentChange(val) {
+            this.listLoading = true
+            this.listUser()
+        },
+        /** 选择列表  */
+        changeCheckbox(item,index,val) {
+            if(val){
+                this.nameList.push({
+                    ...item
+                })
+            }else {
+                let i = -1
+                this.nameList.forEach((item1,index)=>{
+                    if(item1.id == item.id) {
+                        i = index
+                    }
+                })
+                if(i!=-1) {
+                    this.nameList.splice(i,1)
+                }
+            }
+            this.checkedCurrentPageAll()
+        }
+ 
+    },
+}
+</script>
+  
+<style lang="scss" scoped>
+.is-error {
+    .select-more-item {
+        border-color: #f56c6c !important;
+    }
+}
+.select-more-tool {
+    position: absolute;
+    bottom: 5px;
+    right: 5px;
+    display: flex;
+    .select-more-but-add {
+        width: 80px;
+        height: 36px;
+        box-sizing: border-box;
+        color: #fff;
+        background-color: #409eff;
+        border-color: #409eff;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        border-radius: 5px;
+        cursor: pointer;
+        margin-left: 10px;
+        
+    }
+    .select-more-but-clear {
+        width: 80px;
+        height: 36px;
+        box-sizing: border-box;
+        color: #fff;
+        background-color: #f56c6c;
+        border-color: #f56c6c;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        border-radius: 5px;
+        cursor: pointer;
+        margin-left: 10px;
+    }
+}
+
+.select-more-item {
+    width: 100%;
+    height: 300px;
+    border: 1px solid #C0C4CC;
+    overflow: hidden;
+    overflow-y: auto;
+    border-radius: 5px;
+    margin-top: 5px;
+    position: relative;
+    padding: 10px;
+    .c_left_tag {
+        display: flex;
+        flex-wrap: wrap;
+    }
+ 
+            .tag {
+                margin-left: 0 !important;
+                margin-right: 10px;
+                margin-bottom: 10px;
+            }
+}
+.form-con {
+    padding-top: 10px;
+    margin: auto;
+ 
+    .form_content {
+        height: 500px;
+        display: flex;
+ 
+        .c_left {
+            width: 50%;
+            border-right: 1px solid #EBEEF5;
+            padding: 0 10px;
+ 
+            .c_left_btn {
+                height: 32px;
+                display: flex;
+                justify-content: space-between;
+                align-items: center;
+            }
+ 
+            .c_left_tag {
+                margin-top: 10px;
+                display: flex;
+                flex-wrap: wrap;
+            }
+ 
+            .tag {
+                margin-left: 0 !important;
+                margin-right: 10px;
+                margin-bottom: 10px;
+            }
+ 
+        }
+ 
+        .c_right {
+            width: 50%;
+            height: 100%;
+            padding: 0 10px;
+            display: flex;
+            flex-direction: column;
+            justify-content: space-between;
+            box-sizing: border-box;
+            .c_input {
+                height: 32px;
+                flex-shrink: 0;
+                display: flex;
+                align-items: center;
+            }
+            .c_checkbox {
+                margin-top: 10px;
+                height: 100%;
+                .c_checkbox_item {
+                    width: 100%;
+                    margin-bottom: 5px;
+                }
+            }
+ 
+            .checkBox {
+                display: flex;
+                flex-direction: column;
+                
+                .checkBox_item {
+                    height: 30px;
+                    display: flex;
+                    align-items: center;
+                }
+            }
+            .c_pagination {
+                height: 32px;
+                flex-shrink: 0;
+                display: flex;
+                justify-content: center;
+            }
+        }
+    }
+}
+</style>

+ 489 - 0
src/views/tourism/marketingActivities/model/selectMembershipLevel.vue

@@ -0,0 +1,489 @@
+<template>
+    <div class="select-more-box">
+        
+        <div class="select-more-item">
+            <div class="c_left_tag" v-if="modalDetails.length>0">
+                <el-tag class="tag" size="closable" v-for="(item, index) in modalDetails" :key="index"
+                    @close="handleCloseCopy(item)" closable>
+                    {{ item.name }}
+                    </el-tag>
+            </div>
+            <span style="color: #c0c0c0;" v-else>请点击添加,选择会员等级</span>
+            <div class="select-more-tool" v-if="isAdd">
+                <span>目前已选择:{{ modalDetails.length }}个</span>
+                <div class="select-more-but-add" @click="dialogVisible = true"><span>添加</span><span>+</span></div>
+                <div class="select-more-but-clear" @click="clearModalDetails"><span>清除已选</span></div>
+            </div>
+        </div>
+        <el-dialog 
+        append-to-body 
+        :title="title" 
+        :visible.sync="dialogVisible" 
+        @open="dialogOpen" 
+        @close="dialogClose"
+        :close-on-click-modal="false"
+        :destroy-on-close="true" 
+        width="900px" 
+        class="information-dialog"
+        custom-class="template-con-dialog" top="auto">
+            <div class="form-con" v-loading="loading">
+                <div class="form_content">
+                    <!-- left -->
+                    <div class="c_left">
+                        <div class="c_left_btn">
+                            <div>已选成员</div>
+                            <el-button type="text" @click="clearUser">清空</el-button>
+                        </div>
+                        <div class="c_left_tag">
+                            <el-tag class="tag" size="closable" v-for="(item, index) in nameList" :key="index"
+                                @close="handleClose(item)" closable>
+                                {{ item.name }}
+                            </el-tag>
+                        </div>
+                    </div>
+                    <!-- right -->
+                    <div class="c_right">
+                        <div class="c_input">
+                            <el-input size="mini" prefix-icon="el-icon-search" v-model="userValue" placeholder="输入搜索"></el-input>
+                            <el-button style="margin-left: 10px;" size="mini" @click="searchFun(false)">
+                                重置
+                            </el-button>
+                            <el-button size="mini" @click="searchFun(true)" type="primary">
+                                搜索
+                            </el-button>
+                        </div>
+                        <div class="c_checkbox" v-loading="listLoading">
+                            <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll"
+                                @change="handleCheckAllChange">全选当前页</el-checkbox>
+                           <div style="margin: 15px 0;"></div>
+                            <div class="c_checkbox_item" v-for="(item, index) in dataList" :key="index">
+                                <el-checkbox 
+                                class="checkBox_item" 
+                                v-model="item.checked"
+                                @change="(val)=>changeCheckbox(item,index,val)"
+                                    :key="index">{{
+                                        item.name
+                                    }}</el-checkbox>
+                            </div>
+                            
+                        </div>
+                        <div class="c_pagination">
+                            <el-pagination
+                            v-if="!listLoading"
+                            small
+                            background
+                            layout="total, prev, pager, next"
+                            :page-sizes="page.pageSizes"
+                            :page-size="page.pageSize"
+                            :total="page.total"
+                            :current-page="page.pageNum"
+                            @size-change="handleSizeChange"
+                            @current-change="handleCurrentChange"
+                            >
+                            </el-pagination>
+                        </div>
+                    </div>
+                </div>
+    
+                <div class="drawer-footer">
+                    <el-button @click="dialogVisible = false">
+                        取消
+                    </el-button>
+                    <el-button @click="submitForm()" type="primary">
+                        确定
+                    </el-button>
+                </div>
+            </div>
+        </el-dialog>
+    </div>
+    
+</template>
+  
+<script>
+import { 
+    listTableApi, 
+  } from "@/api/CURD";
+export default {
+    props: {
+        title: {
+            type: String,
+            default: '新增',
+        },
+        value: {
+            type: Array,
+            default: ()=>{
+                return []
+            },
+        },
+        idKey: {
+            type: String,
+            default: 'id',
+        },
+        nameKey: {
+            type: String,
+            default: 'name',
+        },
+        isAdd: {
+            type: Boolean,
+            default: true,
+        }
+    },
+    data() {
+        return {
+            dialogVisible: false, //弹窗选择
+            userValue: '', //人员搜索
+            dataList: [], //数据列表集合
+            nameList: [],//已选择人员
+            checkAll: false,
+            checkedUsers: [], // 选中的
+            isIndeterminate: false,
+            modalDetails: [],
+            loading: false,// 
+            page: {
+                pageSizes: [100, 200, 300, 400],
+                pageSize: 10,
+                pageNum: 1,
+                total: 0,
+            },
+            configUrl: {
+                list: '/member/memberLevelInfo/pageList', // 列表地址
+            },
+            listLoading: false,
+        }
+    },
+    watch: {
+        value: {
+            handler(newValue){
+                console.log("dfsdsfsdf====",this.value)
+                if(this.value) {
+                    this.modalDetails = JSON.parse(JSON.stringify(this.value))
+                }else {
+                    this.modalDetails = []
+                }
+            },
+            immediate: true
+        }
+    },
+    methods: {
+        // 弹窗组件显示事件
+        async dialogOpen() {
+            this.loading = true
+            this.listLoading = false
+            this.userValue = ''
+            this.$set(this.page,'pageNum',1)
+            if (this.modalDetails.length) {
+                this.modalDetails.forEach((item) => {
+                    this.checkedUsers.push(item.id)
+                })
+                this.nameList = this.modalDetails//已选择人员
+                this.checkAll = false
+                this.isIndeterminate = false
+                this.userValue = '' //人员搜索
+            } else {
+                this.nameList = []//已选择人员
+                this.checkAll = false
+                this.checkedUsers = [] // 选中的
+                this.isIndeterminate = false
+                this.userValue = '' //人员搜索
+            }
+            await this.listUser()
+            this.loading = false
+        },
+        /**  搜索   */
+        searchFun(type) {
+            this.listLoading = true
+            if(!type) {
+                this.userValue = ''
+            }
+            this.listUser()
+        },
+        // 查询支部人员集合
+        async listUser() {
+            try {
+                this.dataList = []
+                let res = await listTableApi(this.configUrl.list,{
+                    realName: this.userValue,
+                    pageNum: this.page.pageNum,
+                    pageSize: this.page.pageSize
+                })
+                if (res.code == 200) {
+                    let list = []
+                    let listId = []
+                    this.nameList.forEach((item1,index1)=>{
+                        listId.push(item1.id)
+                    })
+                    res.data.rows.forEach((item,index)=>{
+                        list.push({
+                            ...item,
+                            id: item[this.idKey],
+                            name: item[this.nameKey],
+                            checked: listId.includes(item[this.idKey])
+                        })
+                    })
+                    this.dataList = list
+                    this.$set(this.page,'total',res.data.total)
+                } else {
+                    this.$message({
+                        type: 'error',
+                        message: res.msg
+                    });
+                }
+                this.checkedCurrentPageAll()
+                this.listLoading = false
+            } catch (error) {
+                this.checkedCurrentPageAll()
+                this.loading = false
+                this.listLoading = false
+                this.dialogVisible = false
+            }
+        },
+        // 清空按钮
+        clearUser() {
+            this.handleCheckAllChange(false)
+            this.isIndeterminate = false;
+            this.checkAll = false
+        },
+        // 清除全部
+        clearModalDetails() {
+            this.$emit('input', [])
+            this.$emit('submitForm')
+        },
+        // 单项删除已选按钮 (外部)
+        handleCloseCopy(item) {
+            let arr = this.modalDetails.filter((item1) => {
+                return item.id != item1.id
+            })
+            this.$emit('input', arr)
+            this.$emit('submitForm')
+        },
+        // 单项删除已选按钮 (备选)
+        handleClose(item) {
+            let arr = this.nameList.filter((item1) => {
+                return item.id != item1.id
+            })
+            let listId = []
+            arr.forEach((item,index) => {
+                listId.push(item.id)
+            })
+            let list = JSON.parse(JSON.stringify(this.dataList))
+            list.forEach((item,index) => {
+                list[index].checked = listId.includes(item.id)
+            })
+            this.nameList = arr
+            this.dataList = list
+            this.checkedCurrentPageAll()
+        },
+        // 全选当前页按钮
+        handleCheckAllChange(val) {
+            let list = JSON.parse(JSON.stringify(this.dataList))
+            let listId = []
+            list.forEach((item,index) => {
+                list[index].checked = val
+                listId.push(item.id)
+            })
+            let listExist = this.nameList.filter((item,index)=>{
+                return !listId.includes(item.id)
+            })
+            list.forEach((item,index) => {
+                if(item.checked) {
+                    listExist.push({
+                        ...item
+                    })
+                } 
+            })
+            this.dataList = list
+            this.nameList = listExist
+            this.isIndeterminate = false;
+        },
+        /** 检测当前页是否全选  */
+        checkedCurrentPageAll() {
+            let length = 0
+            let list = JSON.parse(JSON.stringify(this.dataList))
+            list.forEach((item,index) => {
+                if(item.checked) {
+                    length++
+                }
+            })
+            this.checkAll = (length == list.length)&& length != 0
+        },
+        // 弹窗组件关闭事件
+        dialogClose() {
+        },
+        // 提交表单事件
+        submitForm() {
+            this.$emit('input', JSON.parse(JSON.stringify(this.nameList)))
+            this.$emit('submitForm')
+            this.dialogVisible = false
+        },
+        /** 调整每页选择条数  */
+        handleSizeChange(val) {
+        },
+        /** 点击页码  */
+        handleCurrentChange(val) {
+            this.listLoading = true
+            this.listUser()
+        },
+        /** 选择列表  */
+        changeCheckbox(item,index,val) {
+            if(val){
+                this.nameList.push({
+                    ...item
+                })
+            }else {
+                let i = -1
+                this.nameList.forEach((item1,index)=>{
+                    if(item1.id == item.id) {
+                        i = index
+                    }
+                })
+                if(i!=-1) {
+                    this.nameList.splice(i,1)
+                }
+            }
+            this.checkedCurrentPageAll()
+        }
+ 
+    },
+}
+</script>
+  
+<style lang="scss" scoped>
+.is-error {
+    .select-more-item {
+        border-color: #f56c6c !important;
+    }
+}
+.select-more-tool {
+    position: absolute;
+    bottom: 5px;
+    right: 5px;
+    display: flex;
+    .select-more-but-add {
+        width: 80px;
+        height: 36px;
+        box-sizing: border-box;
+        color: #fff;
+        background-color: #409eff;
+        border-color: #409eff;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        border-radius: 5px;
+        cursor: pointer;
+        margin-left: 10px;
+        
+    }
+    .select-more-but-clear {
+        width: 80px;
+        height: 36px;
+        box-sizing: border-box;
+        color: #fff;
+        background-color: #f56c6c;
+        border-color: #f56c6c;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        border-radius: 5px;
+        cursor: pointer;
+        margin-left: 10px;
+    }
+}
+
+.select-more-item {
+    width: 100%;
+    height: 300px;
+    border: 1px solid #C0C4CC;
+    overflow: hidden;
+    overflow-y: auto;
+    border-radius: 5px;
+    margin-top: 5px;
+    position: relative;
+    padding: 10px;
+    .c_left_tag {
+        display: flex;
+        flex-wrap: wrap;
+    }
+ 
+            .tag {
+                margin-left: 0 !important;
+                margin-right: 10px;
+                margin-bottom: 10px;
+            }
+}
+.form-con {
+    padding-top: 10px;
+    margin: auto;
+ 
+    .form_content {
+        height: 500px;
+        display: flex;
+ 
+        .c_left {
+            width: 50%;
+            border-right: 1px solid #EBEEF5;
+            padding: 0 10px;
+ 
+            .c_left_btn {
+                height: 32px;
+                display: flex;
+                justify-content: space-between;
+                align-items: center;
+            }
+ 
+            .c_left_tag {
+                margin-top: 10px;
+                display: flex;
+                flex-wrap: wrap;
+            }
+ 
+            .tag {
+                margin-left: 0 !important;
+                margin-right: 10px;
+                margin-bottom: 10px;
+            }
+ 
+        }
+ 
+        .c_right {
+            width: 50%;
+            height: 100%;
+            padding: 0 10px;
+            display: flex;
+            flex-direction: column;
+            justify-content: space-between;
+            box-sizing: border-box;
+            .c_input {
+                height: 32px;
+                flex-shrink: 0;
+                display: flex;
+                align-items: center;
+            }
+            .c_checkbox {
+                margin-top: 10px;
+                height: 100%;
+                .c_checkbox_item {
+                    width: 100%;
+                    margin-bottom: 5px;
+                }
+            }
+ 
+            .checkBox {
+                display: flex;
+                flex-direction: column;
+                
+                .checkBox_item {
+                    height: 30px;
+                    display: flex;
+                    align-items: center;
+                }
+            }
+            .c_pagination {
+                height: 32px;
+                flex-shrink: 0;
+                display: flex;
+                justify-content: center;
+            }
+        }
+    }
+}
+</style>

+ 489 - 0
src/views/tourism/marketingActivities/model/selectTicketOrders.vue

@@ -0,0 +1,489 @@
+<template>
+    <div class="select-more-box">
+        
+        <div class="select-more-item">
+            <div class="c_left_tag" v-if="modalDetails.length>0">
+                <el-tag class="tag" size="closable" v-for="(item, index) in modalDetails" :key="index"
+                    @close="handleCloseCopy(item)" closable>
+                    {{ item.name }}
+                    </el-tag>
+            </div>
+            <span style="color: #c0c0c0;" v-else>请点击添加,选择门票</span>
+            <div class="select-more-tool" v-if="isAdd">
+                <span>目前已选择:{{ modalDetails.length }}个</span>
+                <div class="select-more-but-add" @click="dialogVisible = true"><span>添加</span><span>+</span></div>
+                <div class="select-more-but-clear" @click="clearModalDetails"><span>清除已选</span></div>
+            </div>
+        </div>
+        <el-dialog 
+        append-to-body 
+        :title="title" 
+        :visible.sync="dialogVisible" 
+        @open="dialogOpen" 
+        @close="dialogClose"
+        :close-on-click-modal="false"
+        :destroy-on-close="true" 
+        width="900px" 
+        class="information-dialog"
+        custom-class="template-con-dialog" top="auto">
+            <div class="form-con" v-loading="loading">
+                <div class="form_content">
+                    <!-- left -->
+                    <div class="c_left">
+                        <div class="c_left_btn">
+                            <div>已选成员</div>
+                            <el-button type="text" @click="clearUser">清空</el-button>
+                        </div>
+                        <div class="c_left_tag">
+                            <el-tag class="tag" size="closable" v-for="(item, index) in nameList" :key="index"
+                                @close="handleClose(item)" closable>
+                                {{ item.name }}
+                            </el-tag>
+                        </div>
+                    </div>
+                    <!-- right -->
+                    <div class="c_right">
+                        <div class="c_input">
+                            <el-input size="mini" prefix-icon="el-icon-search" v-model="userValue" placeholder="输入搜索"></el-input>
+                            <el-button style="margin-left: 10px;" size="mini" @click="searchFun(false)">
+                                重置
+                            </el-button>
+                            <el-button size="mini" @click="searchFun(true)" type="primary">
+                                搜索
+                            </el-button>
+                        </div>
+                        <div class="c_checkbox" v-loading="listLoading">
+                            <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll"
+                                @change="handleCheckAllChange">全选当前页</el-checkbox>
+                           <div style="margin: 15px 0;"></div>
+                            <div class="c_checkbox_item" v-for="(item, index) in dataList" :key="index">
+                                <el-checkbox 
+                                class="checkBox_item" 
+                                v-model="item.checked"
+                                @change="(val)=>changeCheckbox(item,index,val)"
+                                    :key="index">{{
+                                        item.name
+                                    }}</el-checkbox>
+                            </div>
+                            
+                        </div>
+                        <div class="c_pagination">
+                            <el-pagination
+                            v-if="!listLoading"
+                            small
+                            background
+                            layout="total, prev, pager, next"
+                            :page-sizes="page.pageSizes"
+                            :page-size="page.pageSize"
+                            :total="page.total"
+                            :current-page="page.pageNum"
+                            @size-change="handleSizeChange"
+                            @current-change="handleCurrentChange"
+                            >
+                            </el-pagination>
+                        </div>
+                    </div>
+                </div>
+    
+                <div class="drawer-footer">
+                    <el-button @click="dialogVisible = false">
+                        取消
+                    </el-button>
+                    <el-button @click="submitForm()" type="primary">
+                        确定
+                    </el-button>
+                </div>
+            </div>
+        </el-dialog>
+    </div>
+    
+</template>
+  
+<script>
+import { 
+    listTableApi, 
+  } from "@/api/CURD";
+export default {
+    props: {
+        title: {
+            type: String,
+            default: '新增',
+        },
+        value: {
+            type: Array,
+            default: ()=>{
+                return []
+            },
+        },
+        idKey: {
+            type: String,
+            default: 'performId',
+        },
+        nameKey: {
+            type: String,
+            default: 'name',
+        },
+        isAdd: {
+            type: Boolean,
+            default: true,
+        }
+    },
+    data() {
+        return {
+            dialogVisible: false, //弹窗选择
+            userValue: '', //人员搜索
+            dataList: [], //数据列表集合
+            nameList: [],//已选择人员
+            checkAll: false,
+            checkedUsers: [], // 选中的
+            isIndeterminate: false,
+            modalDetails: [],
+            loading: false,// 
+            page: {
+                pageSizes: [100, 200, 300, 400],
+                pageSize: 10,
+                pageNum: 1,
+                total: 0,
+            },
+            configUrl: {
+                list: '/merchant/merchantPerformAuditorium/merchantPerformList', // 列表地址
+            },
+            listLoading: false,
+        }
+    },
+    watch: {
+        value: {
+            handler(newValue){
+                console.log("dfsdsfsdf====",this.value)
+                if(this.value) {
+                    this.modalDetails = JSON.parse(JSON.stringify(this.value))
+                }else {
+                    this.modalDetails = []
+                }
+            },
+            immediate: true
+        }
+    },
+    methods: {
+        // 弹窗组件显示事件
+        async dialogOpen() {
+            this.loading = true
+            this.listLoading = false
+            this.userValue = ''
+            this.$set(this.page,'pageNum',1)
+            if (this.modalDetails.length) {
+                this.modalDetails.forEach((item) => {
+                    this.checkedUsers.push(item.id)
+                })
+                this.nameList = this.modalDetails//已选择人员
+                this.checkAll = false
+                this.isIndeterminate = false
+                this.userValue = '' //人员搜索
+            } else {
+                this.nameList = []//已选择人员
+                this.checkAll = false
+                this.checkedUsers = [] // 选中的
+                this.isIndeterminate = false
+                this.userValue = '' //人员搜索
+            }
+            await this.listUser()
+            this.loading = false
+        },
+        /**  搜索   */
+        searchFun(type) {
+            this.listLoading = true
+            if(!type) {
+                this.userValue = ''
+            }
+            this.listUser()
+        },
+        // 查询支部人员集合
+        async listUser() {
+            try {
+                this.dataList = []
+                let res = await listTableApi(this.configUrl.list,{
+                    realName: this.userValue,
+                    pageNum: this.page.pageNum,
+                    pageSize: this.page.pageSize
+                })
+                if (res.code == 200) {
+                    let list = []
+                    let listId = []
+                    this.nameList.forEach((item1,index1)=>{
+                        listId.push(item1.id)
+                    })
+                    res.data.rows.forEach((item,index)=>{
+                        list.push({
+                            ...item,
+                            id: item[this.idKey],
+                            name: item[this.nameKey],
+                            checked: listId.includes(item[this.idKey])
+                        })
+                    })
+                    this.dataList = list
+                    this.$set(this.page,'total',res.data.total)
+                } else {
+                    this.$message({
+                        type: 'error',
+                        message: res.msg
+                    });
+                }
+                this.checkedCurrentPageAll()
+                this.listLoading = false
+            } catch (error) {
+                this.checkedCurrentPageAll()
+                this.loading = false
+                this.listLoading = false
+                this.dialogVisible = false
+            }
+        },
+        // 清空按钮
+        clearUser() {
+            this.handleCheckAllChange(false)
+            this.isIndeterminate = false;
+            this.checkAll = false
+        },
+        // 清除全部
+        clearModalDetails() {
+            this.$emit('input', [])
+            this.$emit('submitForm')
+        },
+        // 单项删除已选按钮 (外部)
+        handleCloseCopy(item) {
+            let arr = this.modalDetails.filter((item1) => {
+                return item.id != item1.id
+            })
+            this.$emit('input', arr)
+            this.$emit('submitForm')
+        },
+        // 单项删除已选按钮 (备选)
+        handleClose(item) {
+            let arr = this.nameList.filter((item1) => {
+                return item.id != item1.id
+            })
+            let listId = []
+            arr.forEach((item,index) => {
+                listId.push(item.id)
+            })
+            let list = JSON.parse(JSON.stringify(this.dataList))
+            list.forEach((item,index) => {
+                list[index].checked = listId.includes(item.id)
+            })
+            this.nameList = arr
+            this.dataList = list
+            this.checkedCurrentPageAll()
+        },
+        // 全选当前页按钮
+        handleCheckAllChange(val) {
+            let list = JSON.parse(JSON.stringify(this.dataList))
+            let listId = []
+            list.forEach((item,index) => {
+                list[index].checked = val
+                listId.push(item.id)
+            })
+            let listExist = this.nameList.filter((item,index)=>{
+                return !listId.includes(item.id)
+            })
+            list.forEach((item,index) => {
+                if(item.checked) {
+                    listExist.push({
+                        ...item
+                    })
+                } 
+            })
+            this.dataList = list
+            this.nameList = listExist
+            this.isIndeterminate = false;
+        },
+        /** 检测当前页是否全选  */
+        checkedCurrentPageAll() {
+            let length = 0
+            let list = JSON.parse(JSON.stringify(this.dataList))
+            list.forEach((item,index) => {
+                if(item.checked) {
+                    length++
+                }
+            })
+            this.checkAll = (length == list.length)&& length != 0
+        },
+        // 弹窗组件关闭事件
+        dialogClose() {
+        },
+        // 提交表单事件
+        submitForm() {
+            this.$emit('input', JSON.parse(JSON.stringify(this.nameList)))
+            this.$emit('submitForm')
+            this.dialogVisible = false
+        },
+        /** 调整每页选择条数  */
+        handleSizeChange(val) {
+        },
+        /** 点击页码  */
+        handleCurrentChange(val) {
+            this.listLoading = true
+            this.listUser()
+        },
+        /** 选择列表  */
+        changeCheckbox(item,index,val) {
+            if(val){
+                this.nameList.push({
+                    ...item
+                })
+            }else {
+                let i = -1
+                this.nameList.forEach((item1,index)=>{
+                    if(item1.id == item.id) {
+                        i = index
+                    }
+                })
+                if(i!=-1) {
+                    this.nameList.splice(i,1)
+                }
+            }
+            this.checkedCurrentPageAll()
+        }
+ 
+    },
+}
+</script>
+  
+<style lang="scss" scoped>
+.is-error {
+    .select-more-item {
+        border-color: #f56c6c !important;
+    }
+}
+.select-more-tool {
+    position: absolute;
+    bottom: 5px;
+    right: 5px;
+    display: flex;
+    .select-more-but-add {
+        width: 80px;
+        height: 36px;
+        box-sizing: border-box;
+        color: #fff;
+        background-color: #409eff;
+        border-color: #409eff;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        border-radius: 5px;
+        cursor: pointer;
+        margin-left: 10px;
+        
+    }
+    .select-more-but-clear {
+        width: 80px;
+        height: 36px;
+        box-sizing: border-box;
+        color: #fff;
+        background-color: #f56c6c;
+        border-color: #f56c6c;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        border-radius: 5px;
+        cursor: pointer;
+        margin-left: 10px;
+    }
+}
+
+.select-more-item {
+    width: 100%;
+    height: 300px;
+    border: 1px solid #C0C4CC;
+    overflow: hidden;
+    overflow-y: auto;
+    border-radius: 5px;
+    margin-top: 5px;
+    position: relative;
+    padding: 10px;
+    .c_left_tag {
+        display: flex;
+        flex-wrap: wrap;
+    }
+ 
+            .tag {
+                margin-left: 0 !important;
+                margin-right: 10px;
+                margin-bottom: 10px;
+            }
+}
+.form-con {
+    padding-top: 10px;
+    margin: auto;
+ 
+    .form_content {
+        height: 500px;
+        display: flex;
+ 
+        .c_left {
+            width: 50%;
+            border-right: 1px solid #EBEEF5;
+            padding: 0 10px;
+ 
+            .c_left_btn {
+                height: 32px;
+                display: flex;
+                justify-content: space-between;
+                align-items: center;
+            }
+ 
+            .c_left_tag {
+                margin-top: 10px;
+                display: flex;
+                flex-wrap: wrap;
+            }
+ 
+            .tag {
+                margin-left: 0 !important;
+                margin-right: 10px;
+                margin-bottom: 10px;
+            }
+ 
+        }
+ 
+        .c_right {
+            width: 50%;
+            height: 100%;
+            padding: 0 10px;
+            display: flex;
+            flex-direction: column;
+            justify-content: space-between;
+            box-sizing: border-box;
+            .c_input {
+                height: 32px;
+                flex-shrink: 0;
+                display: flex;
+                align-items: center;
+            }
+            .c_checkbox {
+                margin-top: 10px;
+                height: 100%;
+                .c_checkbox_item {
+                    width: 100%;
+                    margin-bottom: 5px;
+                }
+            }
+ 
+            .checkBox {
+                display: flex;
+                flex-direction: column;
+                
+                .checkBox_item {
+                    height: 30px;
+                    display: flex;
+                    align-items: center;
+                }
+            }
+            .c_pagination {
+                height: 32px;
+                flex-shrink: 0;
+                display: flex;
+                justify-content: center;
+            }
+        }
+    }
+}
+</style>

+ 9 - 0
vue.config.js

@@ -51,6 +51,15 @@ module.exports = {
       }
     }
   },
+  chainWebpack: (config) => {
+    config.resolve.alias
+      .set('@', resolve('./src'))
+      .set('components', resolve('./src/asEditorComponents'))
+      .set('css', resolve('./src/assets/css'))
+      .set('iconfont', resolve('./src/assets/iconfont'))
+      .set('img', resolve('./src/assets/images'))
+      .set('utils', resolve('./src/utils'))
+  },
   configureWebpack: {
     name: name,
     resolve: {