Authored by 张文文

添加跳转到卖家优惠券列表 review by lea.guo

@@ -4,4 +4,9 @@ export default [ @@ -4,4 +4,9 @@ export default [
4 path: '/xianyu/home/coupon.html', 4 path: '/xianyu/home/coupon.html',
5 component: () => import(/* webpackChunkName: "home.coupon" */ './list'), 5 component: () => import(/* webpackChunkName: "home.coupon" */ './list'),
6 }, 6 },
  7 + {
  8 + name: 'SalerCoupon',
  9 + path: '/xianyu/home/salerCoupon.html',
  10 + component: () => import(/* webpackChunkName: "home.coupon" */ './saler-list'),
  11 + },
7 ]; 12 ];
@@ -55,6 +55,10 @@ @@ -55,6 +55,10 @@
55 <div class="couponErrorPageImage"></div> 55 <div class="couponErrorPageImage"></div>
56 暂无优惠券 56 暂无优惠券
57 </div> 57 </div>
  58 + <div class="saler-wrapper" @click="jumpToSalerList">
  59 + <div class="saler-img"></div>
  60 + <div class="saler-text">卖家劵</div>
  61 + </div>
58 </LayoutApp> 62 </LayoutApp>
59 </template> 63 </template>
60 64
@@ -70,12 +74,12 @@ export default { @@ -70,12 +74,12 @@ export default {
70 components: {EmptyList}, 74 components: {EmptyList},
71 activated: function() { 75 activated: function() {
72 this.type = 'unused'; 76 this.type = 'unused';
73 - this.fetchCouponList({type: 'unused', isReset: true}).then(r=>{ 77 + this.fetchCouponList({type: 'unused', userType: this.userType, isReset: true}).then(r=>{
74 this.list = r; 78 this.list = r;
75 this.showEmpty = !(r && r.length); 79 this.showEmpty = !(r && r.length);
76 }); 80 });
77 - this.fetchCouponList({type: 'used', isReset: true});  
78 - this.fetchCouponList({type: 'overtime', isReset: true}); 81 + this.fetchCouponList({type: 'used', userType: this.userType, isReset: true});
  82 + this.fetchCouponList({type: 'overtime', userType: this.userType, isReset: true});
79 }, 83 },
80 data() { 84 data() {
81 return { 85 return {
@@ -87,6 +91,7 @@ export default { @@ -87,6 +91,7 @@ export default {
87 pullDownRefresh: false 91 pullDownRefresh: false
88 }, 92 },
89 type: 'unused', 93 type: 'unused',
  94 + userType: 0, // 0:全部 1:买家 2:卖家
90 list: [], 95 list: [],
91 showEmpty: false 96 showEmpty: false
92 }; 97 };
@@ -114,7 +119,7 @@ export default { @@ -114,7 +119,7 @@ export default {
114 }, 119 },
115 120
116 async onPullingUp() { 121 async onPullingUp() {
117 - this.list = await this.fetchCouponList({type: this.type}); 122 + this.list = await this.fetchCouponList({type: this.type, userType: this.userType});
118 this.showEmpty = this[this.type].isEmpty; 123 this.showEmpty = this[this.type].isEmpty;
119 }, 124 },
120 125
@@ -126,6 +131,12 @@ export default { @@ -126,6 +131,12 @@ export default {
126 type: 8 131 type: 8
127 } 132 }
128 }); 133 });
  134 + },
  135 +
  136 + jumpToSalerList() {
  137 + this.$router.push({
  138 + name: 'SalerCoupon',
  139 + });
129 } 140 }
130 }, 141 },
131 computed: { 142 computed: {
@@ -342,6 +353,37 @@ export default { @@ -342,6 +353,37 @@ export default {
342 } 353 }
343 } 354 }
344 355
  356 + .saler-wrapper {
  357 + background: #002B47;
  358 + width: 160px;
  359 + height: 60px;
  360 + border-top-left-radius: 45px;
  361 + border-bottom-left-radius: 45px;
  362 + position: absolute;
  363 + right: 0;
  364 + bottom: 80px;
  365 + display: flex;
  366 + flex-direction: row;
  367 + align-items: center;
  368 +
  369 + .saler-img {
  370 + background: url(~statics/image/coupon/mjq_ic@3x.png) no-repeat;
  371 + background-size: contain;
  372 + width: 36px;
  373 + height: 24px;
  374 + margin-left: 26px;
  375 + }
  376 +
  377 + .saler-text {
  378 + font-size: 24px;
  379 + line-height: 60px;
  380 + color: #FFFFFF;
  381 + letter-spacing: 0;
  382 + margin-left: 10px;
  383 + text-align: center;
  384 + }
  385 + }
  386 +
345 .empty-wrapper { 387 .empty-wrapper {
346 width: 100%; 388 width: 100%;
347 margin: auto 0; 389 margin: auto 0;
  1 +<template>
  2 + <LayoutApp title="卖家优惠券">
  3 + <div class="tab">
  4 + <div class="item right-line" :class="type ==='unused' ? 'item-selected' : 'item-default'"
  5 + @click="onChangeList('unused')">未使用{{unused.total && '('+ unused.total + ')' || null}}
  6 + </div>
  7 + <div class="item right-line" :class="type ==='used' ? 'item-selected' : 'item-default'"
  8 + @click="onChangeList('used')">已使用{{used.total && '('+ used.total + ')' || null}}
  9 + </div>
  10 + <div class="item" :class="type ==='overtime' ? 'item-selected' : 'item-default'"
  11 + @click="onChangeList('overtime')">已失效{{overtime.total && '('+ overtime.total + ')' || null}}
  12 + </div>
  13 + </div>
  14 + <LayoutScroll ref="couponlist"
  15 + class="coupon-list"
  16 + :loading="loadingOptions"
  17 + @pulling-up="onPullingUp" v-show="!showEmpty">
  18 + <div class="item" v-for="(item,index) in list">
  19 + <div :class="type === 'unused' ? 'item-bg' : 'item-gray-bg'">
  20 + <div class="item-left">
  21 + <div class="item-price" :class="type !== 'unused' && 'gray'">{{item.coupon_value}}</div>
  22 + <div class="item-rule" v-if="item.use_rule" :class="type !== 'unused' && 'gray'">{{item.use_rule}}</div>
  23 + </div>
  24 + <div class="item-right">
  25 + <div class="item-name" :class="type !== 'unused' && 'gray'">
  26 + <span class="item-type" :class="type !== 'unused' && 'gray'">[{{item.coupon_type_name}}]</span>
  27 + {{item.coupon_name}}
  28 + </div>
  29 + <div class="item-time" :class="type !== 'unused' && 'gray'">{{item.coupon_validity}}</div>
  30 + <div class="item-desc-btn" :class="type !== 'unused' && 'gray'" @click="handleShowNotice(item,index)">
  31 + 使用说明
  32 + <div class="down" :class="item.showNotice && 'up'"></div>
  33 + </div>
  34 + <div class="time-up" v-if="type ==='unused' && item.is_expired_soon === 'Y'"></div>
  35 + <div class="item-used-flag" v-if="type === 'used'"></div>
  36 + <div class="item-use" v-if="type === 'unused'" @click="goUseList(item.coupon_token)">
  37 + 立即使用
  38 + </div>
  39 + <div class="item-overtime-flag" v-if="type === 'overtime'"></div>
  40 + </div>
  41 + </div>
  42 + <div class="notice" v-show="item.showNotice">
  43 + <div class="shadow"></div>
  44 + <div v-for="no in item.notes" class="row">
  45 + <div class="mr10">•</div>
  46 + <div class="no-text">{{no}}</div>
  47 + </div>
  48 + </div>
  49 + </div>
  50 + </LayoutScroll>
  51 + <div
  52 + class="empty-wrapper"
  53 + v-show="showEmpty"
  54 + >
  55 + <div class="couponErrorPageImage"></div>
  56 + 暂无优惠券
  57 + </div>
  58 + </LayoutApp>
  59 +</template>
  60 +
  61 +<script>
  62 +
  63 +import {createNamespacedHelpers} from 'vuex';
  64 +import EmptyList from '../../../components/ufo-no-item';
  65 +
  66 +const {mapState, mapActions} = createNamespacedHelpers('home/salerCoupon');
  67 +
  68 +export default {
  69 + name: 'Coupon',
  70 + components: {EmptyList},
  71 + activated: function() {
  72 + this.type = 'unused';
  73 + this.fetchSalerCouponList({type: 'unused', userType: this.userType, isReset: true}).then(r=>{
  74 + this.list = r;
  75 + this.showEmpty = !(r && r.length);
  76 + });
  77 + this.fetchSalerCouponList({type: 'used', userType: this.userType, isReset: true});
  78 + this.fetchSalerCouponList({type: 'overtime', userType: this.userType, isReset: true});
  79 + },
  80 + data() {
  81 + return {
  82 + scrollOptions: {
  83 + bounce: {
  84 + top: false
  85 + },
  86 + pullUpLoad: true,
  87 + pullDownRefresh: false
  88 + },
  89 + type: 'unused',
  90 + userType: 2, // 0:全部 1:买家 2:卖家
  91 + list: [],
  92 + showEmpty: false
  93 + };
  94 + },
  95 + methods: {
  96 + ...mapActions(['fetchSalerCouponList']),
  97 +
  98 + onChangeList(type) {
  99 + // 切换tab
  100 + this.type = type;
  101 +
  102 + // 切换list
  103 + this.list = this[type].list;
  104 + this.showEmpty = this[type].isEmpty;
  105 + this.$refs.couponlist.scrollTo(0, 0);
  106 + },
  107 +
  108 + handleShowNotice(item, index) {
  109 + if (item.showNotice !== void(0)) {
  110 + item.showNotice = !item.showNotice;
  111 + } else {
  112 + item.showNotice = true;
  113 + }
  114 + this.$set(this.list, index, item);
  115 + },
  116 +
  117 + async onPullingUp() {
  118 + this.list = await this.fetchSalerCouponList({type: this.type, userType: this.userType});
  119 + this.showEmpty = this[this.type].isEmpty;
  120 + },
  121 +
  122 + goUseList(coupon_token) {
  123 + return this.$router.push({
  124 + name: 'List',
  125 + query: {
  126 + coupon_token,
  127 + type: 8
  128 + }
  129 + });
  130 + }
  131 + },
  132 + computed: {
  133 + ...mapState(['unused', 'used', 'overtime']),
  134 + loadingOptions() {
  135 + let info = this[this.type];
  136 +
  137 + return {
  138 + hide: !this.list || !this.list.length,
  139 + noMore: info && info.reachedEnd
  140 + }
  141 + }
  142 + },
  143 +};
  144 +</script>
  145 +
  146 +<style lang="scss" scoped>
  147 + .tab {
  148 + position: relative;
  149 + display: flex;
  150 + width: 100%;
  151 + height: 88px;
  152 + padding: 14px 0;
  153 + align-items: center;
  154 + z-index: 9999;
  155 + background: #fff;
  156 +
  157 + .item {
  158 + font-size: 28px;
  159 + flex: 1;
  160 + height: 60px;
  161 + text-align: center;
  162 + line-height: 60px;
  163 + }
  164 +
  165 + .right-line {
  166 + border-right: 1px solid #E0E0E0;
  167 + }
  168 +
  169 + .item-default {
  170 + color: #B0B0B0;
  171 + }
  172 +
  173 + .item-selected {
  174 + color: #444444;
  175 + }
  176 + }
  177 +
  178 + .coupon-list {
  179 + background: #f5f5f5;
  180 +
  181 + .item {
  182 + width: 100%;
  183 + margin-top: 20px;
  184 + }
  185 +
  186 + .item-bg {
  187 + background: url(~statics/image/coupon/bg@3x.png) no-repeat;
  188 + width: 710px;
  189 + height: 200px;
  190 + background-size: cover;
  191 + margin: 0 auto;
  192 + display: flex;
  193 + position: relative;
  194 + z-index: 10;
  195 + }
  196 +
  197 + .down {
  198 + transform: rotate(0deg);
  199 + background: url(~statics/image/coupon/down@3x.png) no-repeat;
  200 + background-size: contain;
  201 + width: 20px;
  202 + height: 20px;
  203 + margin-left: 10px;
  204 + margin-top: 4px;
  205 + }
  206 +
  207 + .up {
  208 + margin-top: -8px !important;
  209 + transform: rotate(180deg);
  210 + }
  211 +
  212 + .shadow {
  213 + opacity: 0.7;
  214 + background: #fff;
  215 + position: absolute;
  216 + top: 0;
  217 + left: 0;
  218 + height: 2px;
  219 + width: 702px;
  220 + box-shadow: #ddd 0 1px 10px 10px;
  221 + }
  222 +
  223 + .item-left {
  224 + width: 230px;
  225 + display: flex;
  226 + flex-direction: column;
  227 + align-items: center;
  228 + justify-content: center;
  229 +
  230 + .item-price {
  231 + font-size: 72px;
  232 + font-weight: bold;
  233 + color: #002B47;
  234 + }
  235 +
  236 + .item-rule {
  237 + font-size: 24px;
  238 + margin-top: 4px;
  239 + color: #002B47;
  240 + }
  241 + }
  242 +
  243 + .item-right {
  244 + margin-left: 6px;
  245 +
  246 + .item-name {
  247 + font-size: 24px;
  248 + color: #222;
  249 + margin-top: 22px;
  250 + width: 320px;
  251 + display: -webkit-box;
  252 + -webkit-line-clamp: 2;
  253 + -webkit-box-orient: vertical;
  254 + overflow: hidden;
  255 + text-overflow: ellipsis;
  256 + height: 60px;
  257 + }
  258 +
  259 + .item-type {
  260 + color: #002B47;
  261 + }
  262 +
  263 + .item-time {
  264 + margin-top: 10px;
  265 + font-size: 22px;
  266 + color: #999;
  267 + }
  268 +
  269 + .item-desc-btn {
  270 + margin-top: 26px;
  271 + font-size: 22px;
  272 + color: #999;
  273 + display: flex;
  274 + align-items: center;
  275 + }
  276 +
  277 + .time-up {
  278 + background: url(~statics/image/coupon/time-up@3x.png) no-repeat;
  279 + background-size: cover;
  280 + position: absolute;
  281 + top: 0;
  282 + right: 0;
  283 + width: 80px;
  284 + height: 80px;
  285 + }
  286 +
  287 + .item-used-flag {
  288 + background: url(~statics/image/coupon/used@3x.png) no-repeat;
  289 + background-size: cover;
  290 + position: absolute;
  291 + right: 30px;
  292 + width: 130px;
  293 + height: 130px;
  294 + top: 30px;
  295 + }
  296 +
  297 + .item-overtime-flag {
  298 + background: url(~statics/image/coupon/overtime@3x.png) no-repeat;
  299 + background-size: cover;
  300 + position: absolute;
  301 + right: 30px;
  302 + width: 130px;
  303 + height: 130px;
  304 + top: 30px;
  305 + }
  306 + }
  307 +
  308 + .gray {
  309 + color: #ccc !important;
  310 + }
  311 +
  312 + .item-gray-bg {
  313 + background: url(~statics/image/coupon/bg-gray@3x.png) no-repeat;
  314 + width: 710px;
  315 + height: 200px;
  316 + background-size: cover;
  317 + margin: 0 auto;
  318 + display: flex;
  319 + position: relative;
  320 + z-index: 10;
  321 + }
  322 +
  323 + .notice {
  324 + opacity: 0.7;
  325 + background: #fff;
  326 + margin: -10px 20px 0 20px;
  327 + padding: 36px 26px 26px 26px;
  328 + position: relative;
  329 +
  330 + .mr10 {
  331 + margin-right: 10px;
  332 + }
  333 +
  334 + .row {
  335 + display: flex;
  336 + margin-bottom: 8px;
  337 + }
  338 +
  339 + .no-text {
  340 + font-size: 22px;
  341 + color: #444;
  342 + }
  343 + }
  344 + }
  345 +
  346 + .empty-wrapper {
  347 + width: 100%;
  348 + margin: auto 0;
  349 + position: absolute;
  350 + top: 0;
  351 + bottom: 0;
  352 + background: #f5f5f5;
  353 + display: flex;
  354 + justify-content: center;
  355 + align-items: center;
  356 + flex-direction: column;
  357 + font-size: 28px;
  358 + color: #b0b0b0;
  359 + }
  360 +
  361 + .couponErrorPageImage {
  362 + background: url(~statics/image/coupon/no_coupon.png) no-repeat;
  363 + background-size: cover;
  364 + width: 208px;
  365 + height: 130px;
  366 + margin-bottom: 30px;
  367 + }
  368 +
  369 + .item-use {
  370 + position: absolute;
  371 + right: 20px;
  372 + bottom: 20px;
  373 + width: 130px;
  374 + height: 50px;
  375 + border: 1px solid #444;
  376 + border-radius: 25px;
  377 + justify-content: center;
  378 + align-items: center;
  379 + font-size: 20px;
  380 + color: #444;
  381 + display: flex;
  382 + }
  383 +</style>
@@ -56,6 +56,7 @@ export default function() { @@ -56,6 +56,7 @@ export default function() {
56 page: couponData.page, 56 page: couponData.page,
57 limit: couponData.limit, 57 limit: couponData.limit,
58 type: couponData.type, 58 type: couponData.type,
  59 + userType: param.userType
59 }; 60 };
60 61
61 if (param.isReset) { 62 if (param.isReset) {
@@ -3,6 +3,7 @@ import channel from './channel'; @@ -3,6 +3,7 @@ import channel from './channel';
3 import favorite from './favorite'; 3 import favorite from './favorite';
4 import news from './news'; 4 import news from './news';
5 import coupon from './coupon'; 5 import coupon from './coupon';
  6 +import salerCoupon from './salerCoupon';
6 import bindAccount from './bindAccount'; 7 import bindAccount from './bindAccount';
7 export default function() { 8 export default function() {
8 return { 9 return {
@@ -24,6 +25,7 @@ export default function() { @@ -24,6 +25,7 @@ export default function() {
24 favorite: favorite(), 25 favorite: favorite(),
25 news: news(), 26 news: news(),
26 coupon: coupon(), 27 coupon: coupon(),
  28 + salerCoupon: salerCoupon(),
27 bindAccount: bindAccount() 29 bindAccount: bindAccount()
28 } 30 }
29 }; 31 };
  1 +export default function() {
  2 + return {
  3 + namespaced: true,
  4 + state: {
  5 + unused: {
  6 + type: 'unused',
  7 + isFetching: false,
  8 + reachedEnd: false,
  9 + isEmpty: false,
  10 + list: [],
  11 + filter: 0,
  12 + page: 0,
  13 + limit: 10,
  14 + total: 0
  15 + },
  16 + used: {
  17 + type: 'used',
  18 + isFetching: false,
  19 + reachedEnd: false,
  20 + isEmpty: false,
  21 + list: [],
  22 + filter: 0,
  23 + page: 0,
  24 + limit: 10,
  25 + total: 0
  26 + },
  27 + overtime: {
  28 + type: 'overtime',
  29 + isFetching: false,
  30 + reachedEnd: false,
  31 + isEmpty: false,
  32 + list: [],
  33 + filter: 0,
  34 + page: 0,
  35 + limit: 10,
  36 + total: 0
  37 + },
  38 + },
  39 + mutations: {
  40 + addList(state, { data }) {
  41 + state[data.type] = data;
  42 + }
  43 + },
  44 + actions: {
  45 + async fetchSalerCouponList({ commit, state }, param) {
  46 + if (!param.type) {
  47 + return;
  48 + }
  49 + let couponData = {...state[param.type]};
  50 +
  51 + if (!param.isReset && couponData.reachedEnd) {
  52 + return couponData.list;
  53 + }
  54 +
  55 + let params = {
  56 + page: couponData.page,
  57 + limit: couponData.limit,
  58 + type: couponData.type,
  59 + userType: param.userType
  60 + };
  61 +
  62 + if (param.isReset) {
  63 + params.page = 1;
  64 + } else {
  65 + params.page += 1;
  66 + }
  67 + params.filter = 0;
  68 + let result = await this.$api.get('/api/ufo/coupon/list', {...params});
  69 +
  70 + if (result.code === 200) {
  71 + let data = result.data;
  72 +
  73 + if (typeof data === 'object' && Object.keys(data).length) {
  74 + for (let key in data) {
  75 + if (key === 'coupons') {
  76 + couponData.list = data.page > 1 ? couponData.list.concat(data.coupons) : data.coupons;
  77 + } else {
  78 + couponData[key] = data[key];
  79 + }
  80 + }
  81 + if (data.page === data.totalPage) {
  82 + couponData.reachedEnd = true;
  83 + }
  84 + couponData.list.length ? couponData.isEmpty = false : couponData.isEmpty = true;
  85 +
  86 + commit('addList', { data: couponData });
  87 + }
  88 + } else {
  89 + couponData.isEmpty = true;
  90 + commit('addList', { data: couponData });
  91 + }
  92 + return couponData.list || [];
  93 + }
  94 + },
  95 + };
  96 +}
@@ -83,7 +83,7 @@ export default { @@ -83,7 +83,7 @@ export default {
83 productId: productId, 83 productId: productId,
84 } 84 }
85 85
86 - const result = await this.$api.post('/api/ufo/product/couponTopList', params); 86 + const result = await this.$api.get('/api/ufo/product/couponTopList', params);
87 87
88 if (result.code === 200) { 88 if (result.code === 200) {
89 const couponTopList = result.data || []; 89 const couponTopList = result.data || [];