Przeglądaj źródła

页面设计优惠券组 手动选择&文字颜色

萤火科技 1 rok temu
rodzic
commit
281651943c

+ 40 - 4
src/views/page/modules/editor/Editor.vue

@@ -1040,6 +1040,21 @@
         <a-tabs>
         <a-tabs>
           <a-tab-pane key="1" tab="内容设置">
           <a-tab-pane key="1" tab="内容设置">
             <div class="block-box">
             <div class="block-box">
+              <div class="block-title">
+                <span>数据来源</span>
+                <a-radio-group buttonStyle="solid" v-model="curItem.params.source">
+                  <a-radio-button value="auto">自动获取</a-radio-button>
+                  <a-radio-button value="choice">手动选择</a-radio-button>
+                </a-radio-group>
+              </div>
+            </div>
+            <!-- 手动选择 -->
+            <div v-if="curItem.params.source === 'choice'" class="block-box">
+              <div class="block-title">选择优惠券 ({{ curItem.data.length }})</div>
+              <SCoupon v-model="curItem.data" :maxNum="15" />
+            </div>
+            <!-- 自动获取 -->
+            <div v-if="curItem.params.source === 'auto'" class="block-box">
               <div class="block-title">优惠券内容</div>
               <div class="block-title">优惠券内容</div>
               <div class="block-item">
               <div class="block-item">
                 <span class="label">显示数量</span>
                 <span class="label">显示数量</span>
@@ -1079,7 +1094,7 @@
             <div class="block-box">
             <div class="block-box">
               <div class="block-title">优惠券样式</div>
               <div class="block-title">优惠券样式</div>
               <div class="block-item">
               <div class="block-item">
-                <span class="label">左右边距</span>
+                <span class="label">左右间距</span>
                 <div class="item-slider">
                 <div class="item-slider">
                   <a-slider v-model="curItem.style.marginRight" :min="0" :max="40" />
                   <a-slider v-model="curItem.style.marginRight" :min="0" :max="40" />
                   <span class="unit-text">
                   <span class="unit-text">
@@ -1089,7 +1104,7 @@
                 </div>
                 </div>
               </div>
               </div>
               <div class="block-item">
               <div class="block-item">
-                <span class="label">优惠券颜色</span>
+                <span class="label">优惠券背景颜色</span>
                 <div class="item-colorPicker">
                 <div class="item-colorPicker">
                   <span
                   <span
                     class="rest-color"
                     class="rest-color"
@@ -1098,6 +1113,16 @@
                   <colorPicker v-model="curItem.style.couponBgColor" defaultColor="#ffa708" />
                   <colorPicker v-model="curItem.style.couponBgColor" defaultColor="#ffa708" />
                 </div>
                 </div>
               </div>
               </div>
+              <div class="block-item">
+                <span class="label">优惠券文字颜色</span>
+                <div class="item-colorPicker">
+                  <span
+                    class="rest-color"
+                    @click="onEditorResetColor(curItem.style, 'couponTextColor', '#ffffff')"
+                  >重置</span>
+                  <colorPicker v-model="curItem.style.couponTextColor" defaultColor="#ffffff" />
+                </div>
+              </div>
               <div class="block-item">
               <div class="block-item">
                 <span class="label">领取按钮颜色</span>
                 <span class="label">领取按钮颜色</span>
                 <div class="item-colorPicker">
                 <div class="item-colorPicker">
@@ -1108,6 +1133,16 @@
                   <colorPicker v-model="curItem.style.receiveBgColor" defaultColor="#717070" />
                   <colorPicker v-model="curItem.style.receiveBgColor" defaultColor="#717070" />
                 </div>
                 </div>
               </div>
               </div>
+              <div class="block-item">
+                <span class="label">领取文字颜色</span>
+                <div class="item-colorPicker">
+                  <span
+                    class="rest-color"
+                    @click="onEditorResetColor(curItem.style, 'receiveTextColor', '#ffffff')"
+                  >重置</span>
+                  <colorPicker v-model="curItem.style.receiveTextColor" defaultColor="#ffffff" />
+                </div>
+              </div>
             </div>
             </div>
           </a-tab-pane>
           </a-tab-pane>
         </a-tabs>
         </a-tabs>
@@ -1431,7 +1466,7 @@ import vcolorpicker from 'vcolorpicker'
 import PropTypes from 'ant-design-vue/es/_util/vue-types'
 import PropTypes from 'ant-design-vue/es/_util/vue-types'
 import draggable from 'vuedraggable'
 import draggable from 'vuedraggable'
 import { Ueditor, SelectCategory } from '@/components'
 import { Ueditor, SelectCategory } from '@/components'
-import { SImage, SArticleCate, SGoods, SLink, SHotZone } from './modules'
+import { SImage, SArticleCate, SGoods, SLink, SHotZone, SCoupon } from './modules'
 
 
 Vue.use(vcolorpicker)
 Vue.use(vcolorpicker)
 
 
@@ -1454,7 +1489,8 @@ export default {
     SGoods,
     SGoods,
     SelectCategory,
     SelectCategory,
     SLink,
     SLink,
-    SHotZone
+    SHotZone,
+    SCoupon
   },
   },
   data () {
   data () {
     return {}
     return {}

+ 179 - 0
src/views/page/modules/editor/modules/SCoupon.vue

@@ -0,0 +1,179 @@
+<template>
+  <div class="select-coupon">
+    <div class="data-preview">
+      <draggable
+        :list="selectedItems"
+        v-bind="{ animation: 120, filter: 'input', preventOnFilter: false }"
+      >
+        <div v-for="(item, index) in selectedItems" :key="index" class="data-item">
+          <a-icon
+            class="icon-close"
+            theme="filled"
+            type="close-circle"
+            @click="handleDeleteItem(index)"
+          />
+          <div class="item-inner">
+            <span class="mr-5">{{ item.name }}</span>
+            <span class="mr-5">(ID: {{ item.coupon_id }})</span>
+          </div>
+        </div>
+      </draggable>
+    </div>
+    <div class="data-add">
+      <a-button icon="plus" @click="handleSelectCoupon()">选择优惠券</a-button>
+    </div>
+    <CouponModal
+      ref="CouponModal"
+      :maxNum="maxNum"
+      :defaultList="selectedItems"
+      @handleSubmit="handleSelectCouponSubmit"
+    />
+  </div>
+</template>
+
+<script>
+import PropTypes from 'ant-design-vue/es/_util/vue-types'
+import draggable from 'vuedraggable'
+import { pick, cloneDeep } from 'lodash'
+import { CouponModal } from '@/components/Modal'
+
+// 仅需要的字段
+const itemColumns = ['coupon_id', 'name', 'coupon_type', 'reduce_price', 'discount', 'min_price']
+
+// 优惠券选择器组件(仅适用于页面设计)
+export default {
+  name: 'SelectCoupon',
+  components: {
+    CouponModal,
+    draggable
+  },
+  model: {
+    prop: 'value',
+    event: 'change'
+  },
+  props: {
+    // 最大选择的数量限制, multiple模式下有效
+    maxNum: PropTypes.integer.def(15),
+    // 选中的优惠券数据
+    value: PropTypes.array.def([])
+  },
+  data () {
+    return {
+      // 已选择的优惠券列表
+      selectedItems: []
+    }
+  },
+  watch: {
+    value: {
+      // 首次加载的时候执行函数
+      immediate: true,
+      handler (val) {
+        this.onUpdate(val)
+      }
+    }
+  },
+  created () {
+  },
+  methods: {
+
+    // 更新已选择的数据 selectedItems
+    onUpdate (items) {
+      this.selectedItems = items
+      this.onChange()
+    },
+
+    // 打开优惠券选择器
+    handleSelectCoupon () {
+      this.$refs.CouponModal.handle()
+    },
+
+    // 优惠券库modal确认回调
+    handleSelectCouponSubmit (result) {
+      const { selectedItems } = result
+      this.onUpdate(this.filterItems(selectedItems))
+    },
+
+    // 过滤仅需要的数据
+    filterItems (selectedItems) {
+      return selectedItems.map(itm => pick(itm, itemColumns))
+    },
+
+    // 删除优惠券
+    handleDeleteItem (index) {
+      const { selectedItems } = this
+      if (selectedItems.length <= 1) {
+        this.$message.warning('请至少保留1个', 1)
+        return
+      }
+      selectedItems.splice(index, 1)
+      this.onUpdate(selectedItems)
+    },
+
+    // 触发change事件
+    onChange () {
+      const { selectedItems } = this
+      return this.$emit('change', selectedItems)
+    }
+
+  }
+}
+</script>
+
+<style lang="less" scoped>
+@import '~ant-design-vue/es/style/themes/default.less';
+// 优惠券信息
+.data-preview {
+  .data-item {
+    margin: 10px 5px;
+    background: #f7fafc;
+    position: relative;
+    border-radius: 3px;
+    cursor: move;
+    border: 1px solid #fff;
+
+    &:hover {
+      border: 1px solid #dadada;
+      .icon-close {
+        display: block;
+      }
+    }
+  }
+
+  // 删除图标
+  .icon-close {
+    display: none;
+    position: absolute;
+    top: -8px;
+    right: -8px;
+    cursor: pointer;
+    font-size: 16px;
+    color: #c5c5c5;
+    &:hover {
+      color: #7d7d7d;
+    }
+  }
+  .item-inner {
+    padding: 10px 15px;
+    border-radius: 4px;
+    background: #f7fafc;
+  }
+}
+
+// 新增数据
+.data-add {
+  margin-top: 10px;
+
+  button {
+    width: 100%;
+    color: @primary-color;
+    height: 40px;
+    border-radius: 5px;
+    font-size: 12px;
+    border-color: #cccccc21;
+
+    &:hover {
+      border-color: @primary-color;
+    }
+  }
+}
+</style>

+ 2 - 1
src/views/page/modules/editor/modules/index.js

@@ -5,5 +5,6 @@ import SGoodsCate from './SGoodsCate'
 import SLink from './SLink'
 import SLink from './SLink'
 import SLink2 from './SLink2'
 import SLink2 from './SLink2'
 import SHotZone from './SHotZone'
 import SHotZone from './SHotZone'
+import SCoupon from './SCoupon'
 
 
-export { SImage, SArticleCate, SGoods, SGoodsCate, SLink, SLink2, SHotZone }
+export { SImage, SArticleCate, SGoods, SGoodsCate, SLink, SLink2, SHotZone, SCoupon }

+ 16 - 5
src/views/page/modules/phone/Phone.vue

@@ -450,21 +450,32 @@
             <div class="coupon-wrapper">
             <div class="coupon-wrapper">
               <div
               <div
                 class="coupon-item"
                 class="coupon-item"
-                v-for="(coupon, idx) in item.data"
+                v-for="(coupon, idx) in (item.params.source == 'choice' ? (item.data.length ? item.data : item.defaultData) : item.defaultData)"
                 :key="idx"
                 :key="idx"
                 :style="{ marginRight: `${item.style.marginRight}px` }"
                 :style="{ marginRight: `${item.style.marginRight}px` }"
               >
               >
                 <i class="before" :style="{ background: item.style.background }"></i>
                 <i class="before" :style="{ background: item.style.background }"></i>
-                <div class="left-content" :style="{ background: item.style.couponBgColor }">
+                <div
+                  class="left-content"
+                  :style="{ background: item.style.couponBgColor, color: item.style.couponTextColor }"
+                >
                   <div class="content-top">
                   <div class="content-top">
-                    <span class="unit">¥</span>
-                    <span class="price">{{ coupon.reduce_price }}</span>
+                    <template v-if="coupon.coupon_type == 10">
+                      <span class="unit">¥</span>
+                      <span class="price">{{ coupon.reduce_price }}</span>
+                    </template>
+                    <template v-if="coupon.coupon_type == 20">
+                      <span class="price">{{ coupon.discount }}折</span>
+                    </template>
                   </div>
                   </div>
                   <div class="content-bottom">
                   <div class="content-bottom">
                     <span>满{{ coupon.min_price }}元可用</span>
                     <span>满{{ coupon.min_price }}元可用</span>
                   </div>
                   </div>
                 </div>
                 </div>
-                <div class="right-receive" :style="{ background: item.style.receiveBgColor }">
+                <div
+                  class="right-receive"
+                  :style="{ background: item.style.receiveBgColor, color: item.style.receiveTextColor }"
+                >
                   <span>立即</span>
                   <span>立即</span>
                   <span>领取</span>
                   <span>领取</span>
                 </div>
                 </div>

+ 5 - 6
src/views/page/modules/phone/style.less

@@ -854,16 +854,17 @@ dl {
 
 
     // diy-优惠券组
     // diy-优惠券组
     .diy-coupon {
     .diy-coupon {
+      overflow: hidden;
+
+      &::-webkit-scrollbar {
+        display: none;
+      }
 
 
       .coupon-wrapper {
       .coupon-wrapper {
         display: flex;
         display: flex;
         width: max-content;
         width: max-content;
         height: 65px;
         height: 65px;
         padding: 0 12px;
         padding: 0 12px;
-
-        &::-webkit-scrollbar {
-          display: none;
-        }
       }
       }
 
 
       .coupon-item {
       .coupon-item {
@@ -900,7 +901,6 @@ dl {
           justify-content: center;
           justify-content: center;
           align-items: center;
           align-items: center;
           position: relative;
           position: relative;
-          // float: left;
           width: 70%;
           width: 70%;
           height: 100%;
           height: 100%;
           background-color: #E5004F;
           background-color: #E5004F;
@@ -922,7 +922,6 @@ dl {
           flex-direction: column;
           flex-direction: column;
           justify-content: center;
           justify-content: center;
           align-items: center;
           align-items: center;
-          // float: right;
           width: 30%;
           width: 30%;
           height: 100%;
           height: 100%;
           background-color: #4e4e4e;
           background-color: #4e4e4e;