Commit aec557e9 authored by Junling Bu's avatar Junling Bu
Browse files

chore[litemall-vue]: 参考litemall-admin结构,重新调整litemall-vue的src结构

parent 8d262f8b
import axios from 'axios'
import { Dialog, Toast } from 'vant';
// create an axios instance
const service = axios.create({
baseURL: process.env.BASE_API, // api 的 base_url
timeout: 5000 // request timeout
})
// request interceptor
service.interceptors.request.use(
config => {
if (!config.headers['X-Litemall-Token']) {
config.headers['X-Litemall-Token'] = `${window.localStorage.getItem(
'Authorization'
) || ''}`;
}
return config;
},
err => Promise.reject(err)
)
// response interceptor
service.interceptors.response.use(
response => {
const res = response.data
if (res.errno === 501) {
Toast.fail('请登录');
setTimeout(() => {
window.location = '#/login/'
}, 1500)
return Promise.reject('error')
} else if (res.errno === 502) {
Toast.alert('网站内部错误,请联系网站维护人员')
return Promise.reject('error')
} else if (res.errno !== 0) {
// 非5xx的错误属于业务错误,留给具体页面处理
return Promise.reject(response)
} else {
return response
}
}, error => {
console.log('err' + error)// for debug
Dialog.alert({
title: '警告',
message: '登录连接超时'
});
return Promise.reject(error)
})
export default service
export default {
isAttached(element) {
let currentNode = element.parentNode;
while (currentNode) {
if (currentNode.tagName === 'HTML') {
return true;
}
if (currentNode.nodeType === 11) {
return false;
}
currentNode = currentNode.parentNode;
}
return false;
},
getScrollLeft(element) {
return 'scrollLeft' in element ? element.scrollLeft : element.pageXOffset;
},
getVisibleHeight(element) {
return element === window
? element.innerHeight
: element.getBoundingClientRect().height;
},
getVisibleWidth(element) {
return element === window
? element.innerWidth
: element.getBoundingClientRect().width;
}
};
export default {
isAttached(element) {
let currentNode = element.parentNode;
while (currentNode) {
if (currentNode.tagName === 'HTML') {
return true;
}
if (currentNode.nodeType === 11) {
return false;
}
currentNode = currentNode.parentNode;
}
return false;
},
getScrollLeft(element) {
return 'scrollLeft' in element ? element.scrollLeft : element.pageXOffset;
},
getVisibleHeight(element) {
return element === window
? element.innerHeight
: element.getBoundingClientRect().height;
},
getVisibleWidth(element) {
return element === window
? element.innerWidth
: element.getBoundingClientRect().width;
}
};
export const idCard = /^[1-9]{1}[0-9]{14}$|^[1-9]{1}[0-9]{16}([0-9]|[xX])$/;
export const mobileReg = /^1[0-9]{10}$/;
export const address = val => {
const value = val.trim();
return value.length >= 5 && value.length <= 100;
};
export const userName = /^[a-zA-Z0-9_\u4e00-\u9fa5]{3,20}$/;
export const emailReg = /^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/;
export const idCard = /^[1-9]{1}[0-9]{14}$|^[1-9]{1}[0-9]{16}([0-9]|[xX])$/;
export const mobileReg = /^1[0-9]{10}$/;
export const address = val => {
const value = val.trim();
return value.length >= 5 && value.length <= 100;
};
export const userName = /^[a-zA-Z0-9_\u4e00-\u9fa5]{3,20}$/;
export const emailReg = /^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/;
<template>
<div class="tab_home">
<div class="tal_class_searchBox">
<van-search placeholder="点击前往搜索" @click="$router.push({ name: 'search' })"/>
<div class="tal_class_searchMask"></div>
</div>
<van-swipe :autoplay="3000" indicator-color="white">
<van-swipe-item v-for="(image, index) in brandList" :key="index">
<img :src="image" style="height:230px">
</van-swipe-item>
</van-swipe>
<van-tabbar active-color="#7d7e80" v-model="active" class="goods-channel">
<van-tabbar-item
@click="changeTabbar(iconJson)"
style="font-size:14px"
v-if="index < 5"
v-for="(iconJson, index) in shopInfos.channel"
:key="index"
:icon="iconJson.iconUrl"
>{{iconJson.name}}</van-tabbar-item>
</van-tabbar>
<van-tabbar active-color="#7d7e80" v-model="active" class="goods-channel">
<van-tabbar-item
@click="changeTabbar(iconJson)"
style="font-size:14px"
v-if="index >= 5"
v-for="(iconJson, index) in shopInfos.channel"
:key="index"
:icon="iconJson.iconUrl"
>{{iconJson.name}}</van-tabbar-item>
<van-tabbar-item></van-tabbar-item>
</van-tabbar>
<!-- <van-panel title="优惠券" style=" padding-bottom: 10px;">
<div
class="van-coupon-item"
v-for="(coupon,index) in shopInfos.couponList"
:key="index"
@click="getCoupon(coupon.id)"
>
<div class="van-coupon-item__content">
<div class="van-coupon-item__head">
<h2>
<span>¥</span>
{{coupon.discount}}
</h2>
<p>{{coupon.desc }} - {{coupon.tag}}</p>
</div>
<div class="van-coupon-item__body">
<h2>{{coupon.name}}</h2>
<p>有效期:{{coupon.days}}</p>
</div>
</div>
</div>
</van-panel>-->
<van-panel title="团购专区">
<!-- {{shopInfos.grouponList}} -->
<van-card
:thumb-link="goDetail(groupGood.goods.id)"
v-for="(groupGood ,index) in shopInfos.grouponList"
:key="index"
:title="groupGood.goods.name"
:desc="groupGood.goods.brief"
:num="groupGood.groupon_member"
:origin-price="groupGood.goods.counterPrice"
:price="groupGood.goods.retailPrice +'.00'"
:thumb="groupGood.goods.picUrl"
@native-click="goDetail(groupGood.goods.id)"
>
<!-- <div slot="footer">添加日期 {{item.addTime}}</div> -->
</van-card>
</van-panel>
<van-panel title="新品首发">
<!-- {{shopInfos.grouponList}} -->
<van-row gutter>
<van-col span="12" v-for="(newGood ,index) in shopInfos.newGoodsList" :key="index">
<router-link :to="{ path: `/items/detail/${newGood.id}`}">
<img :src="newGood.picUrl" style="width:180px;height:180px;">
</router-link>
<span
style="padding-left: 20px;position: relative;bottom: 10px; color: rgb(123, 116, 116);white-space: nowrap;"
>{{newGood.name}}</span>
<span
style="padding-left: 80px;position: relative;bottom: 10px; color:#ab956d"
>{{newGood.retailPrice}}</span>
</van-col>
</van-row>
</van-panel>
<van-panel title="人气推荐">
<!-- {{shopInfos.grouponList}} -->
<van-card
:thumb-link="goDetail(groupGood.id)"
v-for="(groupGood ,index) in shopInfos.hotGoodsList"
:key="index"
:title="groupGood.name"
:desc="groupGood.brief"
:origin-price="groupGood.counterPrice"
:price="groupGood.retailPrice +'.00'"
:thumb="groupGood.picUrl"
@native-click="goDetail(groupGood.id)"
>
<!-- <div slot="footer">添加日期 {{item.addTime}}</div> -->
</van-card>
</van-panel>
<!-- <van-list
v-model="loading"
class="scroll-load"
:finished="finished"
:immediate-check="false"
:offset="100"
@load="loadMore"
>
<item-group
v-for="( group, key ) in itemGroup"
v-if="group"
:key="key"
class="interval_bot"
:setting="group.setting"
>
<component
v-for="item in group.items"
:goods="item"
:key="item.id"
:is="getStyle(group.setting.style)"
@click="toGoods(item)"
>
<div slot="mask" v-if="lootAll(item)">
<img src="../../assets/images/not_enough.png" alt="已抢光">
</div>
<div slot="leftTopIcon" v-if="item.as_status < 2">
<img :src="mxStatus(item.as_status)" alt="秒杀">
</div>
</component>
</item-group>
</van-list>-->
</div>
</template>
<script>
import { HOME_module, ALL_GOODS } from '@/api/shop';
import getLocationParam from 'core/utils/location-param';
import mx_be_to from '@/assets/images/mx_be_to.png';
import mx_start from '@/assets/images/mx_start.png';
import SignBoard from './tabbar-home-sign-board';
import ShopInfoGroup from './tabbar-home-shop-info';
import ItemGroup from '@/vue/components/item-group/';
import ItemCardVert from '@/vue/components/item-card-vert/';
import ItemCardHori from '@/vue/components/item-card-hori/';
import loadMore from '@/vue/mixin/list-load-more';
import scrollFixed from '@/vue/mixin/scroll-fixed';
import _ from 'lodash';
const coupon = {
available: 1,
discount: 0,
denominations: 150,
originCondition: 0,
reason: '',
value: 150,
name: '优惠券名称',
startAt: 1489104000,
endAt: 1514592000
};
import {
List,
Swipe,
SwipeItem,
Tabbar,
TabbarItem,
Search,
Panel,
CouponCell,
CouponList,
Toast,
Card,
Row,
Col
} from 'vant';
export default {
mixins: [loadMore, scrollFixed],
data() {
const shop_id = getLocationParam('shop_id');
return {
shop_id,
brandList: [],
shopInfos: [],
shopInfo: null,
coupons: [coupon],
itemGroup: {
mx_goods: null,
activity_seckill: null,
shop_recommend: null,
goods: null
},
mx_be_to,
mx_start,
isLoading: false
};
},
computed: {
location() {
const shopInfo = this.shopInfo;
const local = {
name: shopInfo.shop_name,
lat: shopInfo.lat,
lng: shopInfo.lng
};
return local.lat && local.lng ? local : null;
}
},
created() {
// this.initViews();
this.initNewViews();
},
methods: {
goDetail(id) {
return `#/items/detail/${id}`;
},
async getCoupon(id) {
let errmsg = await this.$reqPost('/wx/coupon/receive', {
couponId: id
});
Toast.success('领取成功');
},
async changeTabbar(o) {
let { data } = await this.$reqGet(
`/wx/goods/category?id=${o.id}`
);
let categoryId = data.data.currentCategory.id;
this.$router.push({
path: `items/list?keyword=&itemClass=${categoryId}`
});
},
initViews() {
this.$reqGet(HOME_module, {
shop_id: this.shop_id,
'per-page': this.pages.perPage,
page: 1
}).then(res => {
const { shop_info, page } = res.data.data;
const {
mx_goods,
shop_recommend,
activity_seckill,
goods
} = this.decorate(res.data.data);
this.shopInfo = shop_info;
this.itemGroup.mx_goods = mx_goods;
this.itemGroup.shop_recommend = shop_recommend;
this.itemGroup.activity_seckill = activity_seckill;
this.itemGroup.goods = goods;
this.setPages(page);
});
},
initNewViews() {
this.$reqGet('/wx/home/index').then(res => {
this.shopInfos = res.data.data;
this.brandList = [];
_.each(res.data.data.brandList, v => {
this.brandList.push(v.picUrl);
});
});
},
initData() {
// return this.$reqGet(ALL_GOODS, {
// shop_id: this.shop_id,
// 'per-page': this.pages.perPage,
// page: this.pages.currPage
// }).then(res => {
// const { items, page } = res.data.data;
// this.itemGroup.goods && this.itemGroup.goods.items.push(...items);
// return page;
// });
},
toGoods(item) {
// 如果是秒杀商品, 并且已经抢光
if (this.lootAll(item)) {
this.$dialog.alert({ message: '该秒杀商品已抢光,看看别的吧!' });
return;
}
this.$router.push({ path: `/items/detail/${item.id}` });
},
groupIcon(key) {
const iconGroup = {
activity_seckill: 'naozhong',
goods: 'list',
mx_goods: 'n4',
shop_recommend: 'good'
};
return iconGroup[key] || '';
},
getStyle(style) {
return style ? 'item-card-vert' : 'item-card-hori';
},
decorate({ mx_goods, shop_recommend, activity_seckill, goods }) {
if (mx_goods) {
mx_goods.setting.icon = 'n4';
mx_goods.setting.title_desc = '分享得金豆';
mx_goods.setting.title_color = '#db3d3c';
mx_goods.setting.item_len = mx_goods.items.length;
}
if (shop_recommend) {
shop_recommend.setting.icon = 'good';
shop_recommend.setting.item_len = shop_recommend.items.length;
}
if (activity_seckill) {
activity_seckill.setting.icon = 'naozhong';
activity_seckill.setting.title_color = '#db3d3c';
activity_seckill.setting.item_len = activity_seckill.items.length;
}
if (goods) {
goods.setting.icon = 'list';
goods.setting.item_len = goods.items.length;
}
return {
mx_goods,
shop_recommend,
activity_seckill,
goods
};
},
lootAll(item) {
return (
typeof item.as_status !== 'undefined' && item.sold_num == item.total
);
},
mxStatus(as_status) {
return as_status ? this.mx_start : this.mx_be_to;
}
},
components: {
// Vue.use(Tabbar).use(TabbarItem);,
[Row.name]: Row,
[Col.name]: Col,
[Card.name]: Card,
[Toast.name]: Toast,
[CouponCell.name]: CouponCell,
[CouponList.name]: CouponList,
[Search.name]: Search,
[Panel.name]: Panel,
[List.name]: List,
[Swipe.name]: Swipe,
[SwipeItem.name]: SwipeItem,
[Tabbar.name]: Tabbar,
[TabbarItem.name]: TabbarItem,
[SignBoard.name]: SignBoard,
[ShopInfoGroup.name]: ShopInfoGroup,
[ItemGroup.name]: ItemGroup,
[ItemCardVert.name]: ItemCardVert,
[ItemCardHori.name]: ItemCardHori
}
};
</script>
<style lang="scss" scoped>
.interval_bot {
margin-bottom: 10px;
}
.goods-channel {
position: sticky;
border-bottom-width: 0px;
}
.van-coupon-cell--selected {
color: #323233;
}
.van-coupon-list {
height: 100%;
position: relative;
background-color: #f8f8f8;
}
.van-coupon-list__field {
padding: 7px 15px;
}
.van-coupon-list__exchange {
height: 32px;
line-height: 30px;
}
.van-coupon-list__list {
overflow-y: auto;
padding: 15px 0;
-webkit-box-sizing: border-box;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
}
.van-coupon-list__close {
left: 0;
bottom: 0;
position: absolute;
font-weight: 500;
}
.van-coupon-list__empty {
padding-top: 100px;
text-align: center;
}
.van-coupon-list__empty p {
color: #969799;
margin: 15px 0;
font-size: 14px;
line-height: 20px;
}
.van-coupon-list__empty img {
width: 80px;
height: 84px;
}
.van-coupon-item {
overflow: hidden;
border-radius: 4px;
margin: 0 15px 15px;
background-color: #fff;
-webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 0.1);
box-shadow: 0 0 4px rgba(0, 0, 0, 0.1);
}
.van-coupon-item:active {
background-color: #e8e8e8;
}
.van-coupon-item__content {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
height: 100px;
padding: 24px 0 0 15px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.van-coupon-item h2,
.van-coupon-item p {
margin: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.van-coupon-item h2 {
height: 34px;
font-weight: 500;
line-height: 34px;
}
.van-coupon-item p {
font-size: 12px;
line-height: 16px;
color: #969799;
}
.van-coupon-item__head {
min-width: 90px;
}
.van-coupon-item__head h2 {
color: #f44;
font-size: 24px;
}
.van-coupon-item__head h2 span {
font-size: 50%;
}
.van-coupon-item__body {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
position: relative;
border-radius: 0 4px 4px 0;
}
.van-coupon-item__body h2 {
font-size: 16px;
}
.van-coupon-item__corner {
top: 16px;
right: 15px;
position: absolute;
}
.van-coupon-item__corner .van-icon {
border-color: #f44;
background-color: #f44;
}
.van-coupon-item__reason {
padding: 7px 15px;
border-top: 1px dashed #ebedf0;
background-color: #fafafa;
}
.van-coupon-item--disabled:active {
background-color: #fff;
}
.van-coupon-item--disabled .van-coupon-item__content {
height: 90px;
}
.van-coupon-item--disabled h2,
.van-coupon-item--disabled p,
.van-coupon-item--disabled span {
color: #969799;
}
</style>
<template>
<div class="tab_home">
<div class="tal_class_searchBox">
<van-search placeholder="点击前往搜索" @click="$router.push({ name: 'search' })"/>
<div class="tal_class_searchMask"></div>
</div>
<van-swipe :autoplay="3000" indicator-color="white">
<van-swipe-item v-for="(image, index) in brandList" :key="index">
<img :src="image" style="height:230px">
</van-swipe-item>
</van-swipe>
<div class="goods-channel">
<div class="item"
@click="changeTabbar(iconJson)"
v-for="(iconJson, index) in shopInfos.channel"
:key="index">
<img :src="iconJson.iconUrl" background-size="cover"/>
<span>{{iconJson.name}}</span>
</div>
</div>
<van-panel title="优惠券" style=" padding-bottom: 10px;">
<div
class="van-coupon-item"
v-for="(coupon,index) in shopInfos.couponList"
:key="index"
@click="getCoupon(coupon.id)"
>
<div class="van-coupon-item__content">
<div class="van-coupon-item__head">
<h2>
<span>¥</span>
{{coupon.discount}}
</h2>
<p>{{coupon.desc }} - {{coupon.tag}}</p>
</div>
<div class="van-coupon-item__body">
<h2>{{coupon.name}}</h2>
<p>有效期:{{coupon.days}}</p>
</div>
</div>
</div>
</van-panel>
<van-panel title="团购专区">
<!-- {{shopInfos.grouponList}} -->
<van-card
:thumb-link="goDetail(groupGood.goods.id)"
v-for="(groupGood ,index) in shopInfos.grouponList"
:key="index"
:title="groupGood.goods.name"
:desc="groupGood.goods.brief"
:num="groupGood.groupon_member"
:origin-price="groupGood.goods.counterPrice"
:price="groupGood.goods.retailPrice +'.00'"
:thumb="groupGood.goods.picUrl"
@native-click="goDetail(groupGood.goods.id)"
>
<!-- <div slot="footer">添加日期 {{item.addTime}}</div> -->
</van-card>
</van-panel>
<van-panel title="新品首发">
<!-- {{shopInfos.grouponList}} -->
<van-row gutter>
<van-col span="12" v-for="(newGood ,index) in shopInfos.newGoodsList" :key="index">
<router-link :to="{ path: `/items/detail/${newGood.id}`}">
<img :src="newGood.picUrl" style="width:180px;height:180px;">
</router-link>
<span
style="padding-left: 20px;position: relative;bottom: 10px; color: rgb(123, 116, 116);white-space: nowrap;"
>{{newGood.name}}</span>
<span
style="padding-left: 80px;position: relative;bottom: 10px; color:#ab956d"
>{{newGood.retailPrice}}</span>
</van-col>
</van-row>
</van-panel>
<van-panel title="人气推荐">
<!-- {{shopInfos.grouponList}} -->
<van-card
:thumb-link="goDetail(groupGood.id)"
v-for="(groupGood ,index) in shopInfos.hotGoodsList"
:key="index"
:title="groupGood.name"
:desc="groupGood.brief"
:origin-price="groupGood.counterPrice"
:price="groupGood.retailPrice +'.00'"
:thumb="groupGood.picUrl"
@native-click="goDetail(groupGood.id)"
>
<!-- <div slot="footer">添加日期 {{item.addTime}}</div> -->
</van-card>
</van-panel>
<!-- <van-list
v-model="loading"
class="scroll-load"
:finished="finished"
:immediate-check="false"
:offset="100"
@load="loadMore"
>
<item-group
v-for="( group, key ) in itemGroup"
v-if="group"
:key="key"
class="interval_bot"
:setting="group.setting"
>
<component
v-for="item in group.items"
:goods="item"
:key="item.id"
:is="getStyle(group.setting.style)"
@click="toGoods(item)"
>
<div slot="mask" v-if="lootAll(item)">
<img src="../../assets/images/not_enough.png" alt="已抢光">
</div>
<div slot="leftTopIcon" v-if="item.as_status < 2">
<img :src="mxStatus(item.as_status)" alt="秒杀">
</div>
</component>
</item-group>
</van-list>-->
</div>
</template>
<script>
import { HOME_module, ALL_GOODS } from '@/api/shop';
import getLocationParam from '@/utils/location-param';
import mx_be_to from '@/assets/images/mx_be_to.png';
import mx_start from '@/assets/images/mx_start.png';
import SignBoard from './tabbar-home-sign-board';
import ShopInfoGroup from './tabbar-home-shop-info';
import ItemGroup from '@/components/item-group/';
import ItemCardVert from '@/components/item-card-vert/';
import ItemCardHori from '@/components/item-card-hori/';
import loadMore from '@/mixin/list-load-more';
import scrollFixed from '@/mixin/scroll-fixed';
import _ from 'lodash';
const coupon = {
available: 1,
discount: 0,
denominations: 150,
originCondition: 0,
reason: '',
value: 150,
name: '优惠券名称',
startAt: 1489104000,
endAt: 1514592000
};
import {
List,
Swipe,
SwipeItem,
Tabbar,
TabbarItem,
Search,
Panel,
CouponCell,
CouponList,
Toast,
Card,
Row,
Col
} from 'vant';
export default {
mixins: [loadMore, scrollFixed],
data() {
const shop_id = getLocationParam('shop_id');
return {
shop_id,
brandList: [],
shopInfos: [],
shopInfo: null,
coupons: [coupon],
itemGroup: {
mx_goods: null,
activity_seckill: null,
shop_recommend: null,
goods: null
},
mx_be_to,
mx_start,
isLoading: false
};
},
computed: {
location() {
const shopInfo = this.shopInfo;
const local = {
name: shopInfo.shop_name,
lat: shopInfo.lat,
lng: shopInfo.lng
};
return local.lat && local.lng ? local : null;
}
},
created() {
// this.initViews();
this.initNewViews();
},
methods: {
goDetail(id) {
return `#/items/detail/${id}`;
},
async getCoupon(id) {
let errmsg = await this.$reqPost('/wx/coupon/receive', {
couponId: id
});
Toast.success('领取成功');
},
async changeTabbar(o) {
let { data } = await this.$reqGet(
`/wx/goods/category?id=${o.id}`
);
let categoryId = data.data.currentCategory.id;
this.$router.push({
path: `items/list?keyword=&itemClass=${categoryId}`
});
},
initViews() {
this.$reqGet(HOME_module, {
shop_id: this.shop_id,
'per-page': this.pages.perPage,
page: 1
}).then(res => {
const { shop_info, page } = res.data.data;
const {
mx_goods,
shop_recommend,
activity_seckill,
goods
} = this.decorate(res.data.data);
this.shopInfo = shop_info;
this.itemGroup.mx_goods = mx_goods;
this.itemGroup.shop_recommend = shop_recommend;
this.itemGroup.activity_seckill = activity_seckill;
this.itemGroup.goods = goods;
this.setPages(page);
});
},
initNewViews() {
this.$reqGet('/wx/home/index').then(res => {
this.shopInfos = res.data.data;
this.brandList = [];
_.each(res.data.data.brandList, v => {
this.brandList.push(v.picUrl);
});
});
},
initData() {
// return this.$reqGet(ALL_GOODS, {
// shop_id: this.shop_id,
// 'per-page': this.pages.perPage,
// page: this.pages.currPage
// }).then(res => {
// const { items, page } = res.data.data;
// this.itemGroup.goods && this.itemGroup.goods.items.push(...items);
// return page;
// });
},
toGoods(item) {
// 如果是秒杀商品, 并且已经抢光
if (this.lootAll(item)) {
this.$dialog.alert({ message: '该秒杀商品已抢光,看看别的吧!' });
return;
}
this.$router.push({ path: `/items/detail/${item.id}` });
},
groupIcon(key) {
const iconGroup = {
activity_seckill: 'naozhong',
goods: 'list',
mx_goods: 'n4',
shop_recommend: 'good'
};
return iconGroup[key] || '';
},
getStyle(style) {
return style ? 'item-card-vert' : 'item-card-hori';
},
decorate({ mx_goods, shop_recommend, activity_seckill, goods }) {
if (mx_goods) {
mx_goods.setting.icon = 'n4';
mx_goods.setting.title_desc = '分享得金豆';
mx_goods.setting.title_color = '#db3d3c';
mx_goods.setting.item_len = mx_goods.items.length;
}
if (shop_recommend) {
shop_recommend.setting.icon = 'good';
shop_recommend.setting.item_len = shop_recommend.items.length;
}
if (activity_seckill) {
activity_seckill.setting.icon = 'naozhong';
activity_seckill.setting.title_color = '#db3d3c';
activity_seckill.setting.item_len = activity_seckill.items.length;
}
if (goods) {
goods.setting.icon = 'list';
goods.setting.item_len = goods.items.length;
}
return {
mx_goods,
shop_recommend,
activity_seckill,
goods
};
},
lootAll(item) {
return (
typeof item.as_status !== 'undefined' && item.sold_num == item.total
);
},
mxStatus(as_status) {
return as_status ? this.mx_start : this.mx_be_to;
}
},
components: {
// Vue.use(Tabbar).use(TabbarItem);,
[Row.name]: Row,
[Col.name]: Col,
[Card.name]: Card,
[Toast.name]: Toast,
[CouponCell.name]: CouponCell,
[CouponList.name]: CouponList,
[Search.name]: Search,
[Panel.name]: Panel,
[List.name]: List,
[Swipe.name]: Swipe,
[SwipeItem.name]: SwipeItem,
[Tabbar.name]: Tabbar,
[TabbarItem.name]: TabbarItem,
[SignBoard.name]: SignBoard,
[ShopInfoGroup.name]: ShopInfoGroup,
[ItemGroup.name]: ItemGroup,
[ItemCardVert.name]: ItemCardVert,
[ItemCardHori.name]: ItemCardHori
}
};
</script>
<style lang="scss" scoped>
.interval_bot {
margin-bottom: 10px;
}
.goods-channel {
background: #fff;
display: flex;
align-items: center;
flex-wrap: wrap;
padding-bottom: 0px;
padding-top: 10px;
}
.goods-channel .item {
width: 50px;
height: 50px;
margin-left: 10px;
}
.goods-channel img {
display: block;
width: 30px;
height: 30px;
margin: 0 auto;
}
.goods-channel span {
display: block;
font-size: 15px;
text-align: center;
margin: 0 auto;
line-height: 1;
color: #333;
}
van-tabbar-item
.van-coupon-cell--selected {
color: #323233;
}
.van-coupon-list {
height: 100%;
position: relative;
background-color: #f8f8f8;
}
.van-coupon-list__field {
padding: 7px 15px;
}
.van-coupon-list__exchange {
height: 32px;
line-height: 30px;
}
.van-coupon-list__list {
overflow-y: auto;
padding: 15px 0;
-webkit-box-sizing: border-box;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
}
.van-coupon-list__close {
left: 0;
bottom: 0;
position: absolute;
font-weight: 500;
}
.van-coupon-list__empty {
padding-top: 100px;
text-align: center;
}
.van-coupon-list__empty p {
color: #969799;
margin: 15px 0;
font-size: 14px;
line-height: 20px;
}
.van-coupon-list__empty img {
width: 80px;
height: 84px;
}
.van-coupon-item {
overflow: hidden;
border-radius: 4px;
margin: 0 15px 15px;
background-color: #fff;
-webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 0.1);
box-shadow: 0 0 4px rgba(0, 0, 0, 0.1);
}
.van-coupon-item:active {
background-color: #e8e8e8;
}
.van-coupon-item__content {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
height: 100px;
padding: 24px 0 0 15px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
border:1px solid red;
}
.van-coupon-item h2,
.van-coupon-item p {
margin: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.van-coupon-item h2 {
height: 34px;
font-weight: 500;
line-height: 34px;
}
.van-coupon-item p {
font-size: 12px;
line-height: 16px;
color: #969799;
}
.van-coupon-item__head {
min-width: 90px;
}
.van-coupon-item__head h2 {
color: #f44;
font-size: 24px;
}
.van-coupon-item__head h2 span {
font-size: 50%;
}
.van-coupon-item__body {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
position: relative;
border-radius: 0 4px 4px 0;
}
.van-coupon-item__body h2 {
font-size: 16px;
}
.van-coupon-item__corner {
top: 16px;
right: 15px;
position: absolute;
}
.van-coupon-item__corner .van-icon {
border-color: #f44;
background-color: #f44;
}
.van-coupon-item__reason {
padding: 7px 15px;
border-top: 1px dashed #ebedf0;
background-color: #fafafa;
}
.van-coupon-item--disabled:active {
background-color: #fff;
}
.van-coupon-item--disabled .van-coupon-item__content {
height: 90px;
}
.van-coupon-item--disabled h2,
.van-coupon-item--disabled p,
.van-coupon-item--disabled span {
color: #969799;
}
</style>
......@@ -63,11 +63,11 @@
<script>
import { GOODS_SEARCH } from '@/api/goods';
import ItemGroup from '@/vue/components/item-group';
import ItemCardHori from '@/vue/components/item-card-hori/';
import ItemGroup from '@/components/item-group';
import ItemCardHori from '@/components/item-card-hori/';
import { Search, Tab, Tabs, Popup } from 'vant';
// import { throttle } from 'lodash';
import InfinityScroll from '@/vue/components/infinity-scroll';
import InfinityScroll from '@/components/infinity-scroll';
export default {
name: 'Item-list',
......
......@@ -32,14 +32,14 @@
<script>
import { GOODS_SEARCH } from '@/api/goods';
import ItemGroup from '@/vue/components/item-group/';
import IsEmpty from '@/vue/components/is-empty/';
import ItemCardHori from '@/vue/components/item-card-hori/';
import ItemGroup from '@/components/item-group/';
import IsEmpty from '@/components/is-empty/';
import ItemCardHori from '@/components/item-card-hori/';
import { Search, List } from 'vant';
import _ from 'lodash';
import loadMore from '@/vue/mixin/list-load-more';
import scrollFixed from '@/vue/mixin/scroll-fixed';
import loadMore from '@/mixin/list-load-more';
import scrollFixed from '@/mixin/scroll-fixed';
export default {
name: 'Item-list',
......
<template>
<div class="tab_class">
<div class="tal_class_searchBox">
<van-search placeholder="点击前往搜索"/>
<div class="tal_class_searchMask" @click="$router.push({ name: 'search' })"></div>
</div>
<class-tree
ref="classTree"
class="height-fix42"
@nav-click="changeCatalog"
@class-click="toItemList"
@all-click="toItemList"
:list="list"
></class-tree>
<is-empty v-if="isEmpty">抱歉,店主还未上架商品</is-empty>
</div>
</template>
<script>
import { GOODS_CATEGORY, GOODS_CHANNGE_CATEGORY } from '@/api/goods';
import getLocationParam from 'core/utils/location-param';
import { Search } from 'vant';
import classTree from './tabbar-class-tree';
import IsEmpty from '@/vue/components/is-empty';
import _ from 'lodash';
import { async } from 'q';
function getIndex(arr, keyWord) {
let index = 0;
_.each(arr, (v, k) => {
if (v.id === keyWord) {
index = k;
return false;
}
});
return index;
}
export default {
data() {
return {
list: [],
subCategory: [],
isEmpty: false
};
},
created() {
this.initData();
},
methods: {
initData() {
const shop_id = getLocationParam('shop_id');
this.$reqGet(`${GOODS_CATEGORY}`).then(res => {
this.list = res.data.data.categoryList;
this.$refs.classTree.changeList(res.data.data);
this.subCategory = res.data.data.currentSubCategory;
if (this.subCategory.length === 0) this.isEmpty = true;
});
},
removeNoChild(data) {
return data.filter(item => item.children && item.children.length);
},
changeCatalog(id) {
this.$reqGet(`${GOODS_CHANNGE_CATEGORY}${id}`).then(res => {
let index = getIndex(this.list, res.data.data.currentCategory.id);
this.$refs.classTree.changeList(res.data.data);
this.subCategory = res.data.data.currentSubCategory;
if (this.subCategory.length === 0) this.isEmpty = true;
});
},
toItemList(id) {
this.$router.push({
name: 'list',
query: { keyword: '', itemClass: id }
});
}
},
components: {
[Search.name]: Search,
[classTree.name]: classTree,
[IsEmpty.name]: IsEmpty
}
};
</script>
<style scoped>
.tab_class {
overflow: hidden;
background-color: #fff;
}
.height-fix {
padding-bottom: 42px;
}
.tal_class_searchBox {
position: relative;
}
.tal_class_searchMask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 9;
}
</style>
<template>
<div class="tab_class">
<div class="tal_class_searchBox">
<van-search placeholder="点击前往搜索"/>
<div class="tal_class_searchMask" @click="$router.push({ name: 'search' })"></div>
</div>
<class-tree
ref="classTree"
class="height-fix42"
@nav-click="changeCatalog"
@class-click="toItemList"
@all-click="toItemList"
:list="list"
></class-tree>
<is-empty v-if="isEmpty">抱歉,店主还未上架商品</is-empty>
</div>
</template>
<script>
import { GOODS_CATEGORY, GOODS_CHANNGE_CATEGORY } from '@/api/goods';
import getLocationParam from '@/utils/location-param';
import { Search } from 'vant';
import classTree from './tabbar-class-tree';
import IsEmpty from '@/components/is-empty';
import _ from 'lodash';
import { async } from 'q';
function getIndex(arr, keyWord) {
let index = 0;
_.each(arr, (v, k) => {
if (v.id === keyWord) {
index = k;
return false;
}
});
return index;
}
export default {
data() {
return {
list: [],
subCategory: [],
isEmpty: false
};
},
created() {
this.initData();
},
methods: {
initData() {
const shop_id = getLocationParam('shop_id');
this.$reqGet(`${GOODS_CATEGORY}`).then(res => {
this.list = res.data.data.categoryList;
this.$refs.classTree.changeList(res.data.data);
this.subCategory = res.data.data.currentSubCategory;
if (this.subCategory.length === 0) this.isEmpty = true;
});
},
removeNoChild(data) {
return data.filter(item => item.children && item.children.length);
},
changeCatalog(id) {
this.$reqGet(`${GOODS_CHANNGE_CATEGORY}${id}`).then(res => {
let index = getIndex(this.list, res.data.data.currentCategory.id);
this.$refs.classTree.changeList(res.data.data);
this.subCategory = res.data.data.currentSubCategory;
if (this.subCategory.length === 0) this.isEmpty = true;
});
},
toItemList(id) {
this.$router.push({
name: 'list',
query: { keyword: '', itemClass: id }
});
}
},
components: {
[Search.name]: Search,
[classTree.name]: classTree,
[IsEmpty.name]: IsEmpty
}
};
</script>
<style scoped>
.tab_class {
overflow: hidden;
background-color: #fff;
}
.height-fix {
padding-bottom: 42px;
}
.tal_class_searchBox {
position: relative;
}
.tal_class_searchMask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 9;
}
</style>
<template>
<md-field-group class="foget_view">
<md-field
v-model="password"
icon="lock"
:is-error="isErrow"
placeholder="请输入新密码"/>
<md-field
v-model="passwordRepeat"
type="password"
icon="lock"
:is-error="isErrow"
placeholder="请再次输入密码" />
<div class="red" v-show="isErrow">两次密码输入不一致</div>
<div class="foget_submit">
<van-button size="large" type="danger" @click="submitCode">重置</van-button>
</div>
</md-field-group>
</template>
<script>
import field from '@/vue/components/field/';
import fieldGroup from '@/vue/components/field-group/';
export default {
data() {
return {
isErrow: true,
password: '',
passwordRepeat: ''
};
},
methods: {
submitCode() {}
},
components: {
[field.name]: field,
[fieldGroup.name]: fieldGroup
}
};
</script>
<style lang="scss" scoped>
div.foget_view {
background-color: #fff;
padding-top: 30px;
}
div.foget_submit {
padding-top: 30px;
padding-bottom: 20px;
}
</style>
<template>
<md-field-group class="foget_view">
<md-field
v-model="password"
icon="lock"
:is-error="isErrow"
placeholder="请输入新密码"/>
<md-field
v-model="passwordRepeat"
type="password"
icon="lock"
:is-error="isErrow"
placeholder="请再次输入密码" />
<div class="red" v-show="isErrow">两次密码输入不一致</div>
<div class="foget_submit">
<van-button size="large" type="danger" @click="submitCode">重置</van-button>
</div>
</md-field-group>
</template>
<script>
import field from '@/components/field/';
import fieldGroup from '@/components/field-group/';
export default {
data() {
return {
isErrow: true,
password: '',
passwordRepeat: ''
};
},
methods: {
submitCode() {}
},
components: {
[field.name]: field,
[fieldGroup.name]: fieldGroup
}
};
</script>
<style lang="scss" scoped>
div.foget_view {
background-color: #fff;
padding-top: 30px;
}
div.foget_submit {
padding-top: 30px;
padding-bottom: 20px;
}
</style>
<template>
<md-field-group class="foget_view">
<md-field
v-model="mobile"
icon="mobile"
placeholder="请输入手机号"/>
<md-field
v-model="code"
icon="lock"
placeholder="请输入短信验证码"
>
<div slot="rightIcon" @click="getCode" class="getCode red">
<countdown v-if="counting" :time="60000" @countdownend="countdownend">
<template slot-scope="props">{{ +props.seconds || 60 }}秒后获取</template>
</countdown>
<span v-else>获取验证码</span>
</div>
</md-field >
<div class="foget_submit">
<van-button size="large" type="danger" @click="submitCode">下一步</van-button>
</div>
</md-field-group>
</template>
<script>
import field from '@/vue/components/field/';
import fieldGroup from '@/vue/components/field-group/';
export default {
data() {
return {
counting: false,
mobile: '',
code: ''
};
},
methods: {
submitCode() {
this.$router.push({ name: 'forgetReset' });
},
getCode() {
this.counting = true;
},
countdownend() {
this.counting = false;
}
},
components: {
[field.name]: field,
[fieldGroup.name]: fieldGroup
}
};
</script>
<style lang="scss" scoped>
@import '../../../assets/scss/mixin';
div.foget_view {
background-color: #fff;
padding-top: 30px;
}
div.foget_submit {
padding-top: 30px;
padding-bottom: 20px;
}
.getCode {
@include one-border(left);
text-align: center;
}
.time_down {
color: $red;
}
</style>
<template>
<md-field-group class="foget_view">
<md-field
v-model="mobile"
icon="mobile"
placeholder="请输入手机号"/>
<md-field
v-model="code"
icon="lock"
placeholder="请输入短信验证码"
>
<div slot="rightIcon" @click="getCode" class="getCode red">
<countdown v-if="counting" :time="60000" @countdownend="countdownend">
<template slot-scope="props">{{ +props.seconds || 60 }}秒后获取</template>
</countdown>
<span v-else>获取验证码</span>
</div>
</md-field >
<div class="foget_submit">
<van-button size="large" type="danger" @click="submitCode">下一步</van-button>
</div>
</md-field-group>
</template>
<script>
import field from '@/components/field/';
import fieldGroup from '@/components/field-group/';
export default {
data() {
return {
counting: false,
mobile: '',
code: ''
};
},
methods: {
submitCode() {
this.$router.push({ name: 'forgetReset' });
},
getCode() {
this.counting = true;
},
countdownend() {
this.counting = false;
}
},
components: {
[field.name]: field,
[fieldGroup.name]: fieldGroup
}
};
</script>
<style lang="scss" scoped>
@import '../../../assets/scss/mixin';
div.foget_view {
background-color: #fff;
padding-top: 30px;
}
div.foget_submit {
padding-top: 30px;
padding-bottom: 20px;
}
.getCode {
@include one-border(left);
text-align: center;
}
.time_down {
color: $red;
}
</style>
......@@ -50,12 +50,12 @@
</template>
<script>
import field from '@/vue/components/field/';
import fieldGroup from '@/vue/components/field-group/';
import field from '@/components/field/';
import fieldGroup from '@/components/field-group/';
import { USER_LOGIN, USER_PROFILE } from '@/api/user';
import { setLocalStorage } from 'core/utils/local-storage';
import { emailReg, mobileReg } from '@/core/regexp';
import { loginByUsername, USER_LOGIN, USER_PROFILE } from '@/api/user';
import { setLocalStorage } from '@/utils/local-storage';
import { emailReg, mobileReg } from '@/utils/validate';
import { Toast } from 'vant';
......@@ -93,6 +93,7 @@ export default {
async login() {
let loginData = this.getLoginData();
loginByUsername(loginData)
let { data } = await this.$reqPost(USER_LOGIN, loginData);
this.userInfo = data.data.userInfo;
console.log(this.userInfo);
......@@ -139,9 +140,9 @@ export default {
getLoginData() {
const password = this.password;
const username = this.getUserType(this.account);
const account = this.getUserType(this.account);
return {
username: this.account,
[account]: this.account,
password: password
};
},
......
<template>
<md-field-group class="register_view">
<div>我们将发送验证码到您的手机</div>
<md-field
v-model="mobile"
icon="mobile"
placeholder="请输入手机号"/>
<div class="register_submit">
<van-button size="large" type="danger" @click="submitCode">下一步</van-button>
</div>
<div class="register_footer">
已有账号?
<router-link to="/login" class="red">登录</router-link>
</div>
</md-field-group>
</template>
<script>
import field from '@/vue/components/field/';
import fieldGroup from '@/vue/components/field-group/';
export default {
data() {
return {
mobile: ''
};
},
methods: {
submitCode() {
this.$router.push({ name: 'registerSubmit' });
}
},
components: {
[field.name]: field,
[fieldGroup.name]: fieldGroup
}
};
</script>
<style lang="scss" scoped>
div.register_view {
background-color: #fff;
padding-top: 30px;
}
div.register_submit {
padding-top: 30px;
padding-bottom: 20px;
}
.register_footer {
text-align: right;
color: $font-color-gray;
}
</style>
<template>
<md-field-group class="register_view">
<div>我们将发送验证码到您的手机</div>
<md-field
v-model="mobile"
icon="mobile"
placeholder="请输入手机号"/>
<div class="register_submit">
<van-button size="large" type="danger" @click="submitCode">下一步</van-button>
</div>
<div class="register_footer">
已有账号?
<router-link to="/login" class="red">登录</router-link>
</div>
</md-field-group>
</template>
<script>
import field from '@/components/field/';
import fieldGroup from '@/components/field-group/';
export default {
data() {
return {
mobile: ''
};
},
methods: {
submitCode() {
this.$router.push({ name: 'registerSubmit' });
}
},
components: {
[field.name]: field,
[fieldGroup.name]: fieldGroup
}
};
</script>
<style lang="scss" scoped>
div.register_view {
background-color: #fff;
padding-top: 30px;
}
div.register_submit {
padding-top: 30px;
padding-bottom: 20px;
}
.register_footer {
text-align: right;
color: $font-color-gray;
}
</style>
<template>
<md-field-group class="register_submit">
<md-field v-model="code" icon="mobile" placeholder="请输入验证码">
<div slot="rightIcon" @click="getCode" class="getCode red">
<countdown v-if="counting" :time="60000" @countdownend="countdownend">
<template slot-scope="props">{{ +props.seconds || 60 }}秒后获取</template>
</countdown>
<span v-else>获取验证码</span>
</div>
</md-field>
<md-field v-model="password" icon="lock" placeholder="请输入密码"/>
<md-field v-model="repeatPassword" icon="lock" placeholder="请再次确认密码"/>
<div class="register_submit_btn">
<van-button type="danger" size="large" @click="registerSubmit">确定</van-button>
</div>
</md-field-group>
</template>
<script>
import field from '@/vue/components/field/';
import fieldGroup from '@/vue/components/field-group/';
export default {
data() {
return {
counting: true,
code: '',
password: '',
repeatPassword: ''
};
},
methods: {
registerSubmit() {
this.$router.push({
name: 'registerStatus',
params: { status: 'success' }
});
},
getCode() {
this.counting = true;
},
countdownend() {
this.counting = false;
}
},
components: {
[field.name]: field,
[fieldGroup.name]: fieldGroup
}
};
</script>
<style lang="scss" scoped>
@import '../../../assets/scss/mixin';
.register_submit {
padding-top: 40px;
background-color: #fff;
}
.register_submit_btn {
padding-top: 30px;
}
.getCode {
@include one-border(left);
text-align: center;
}
.time_down {
color: $red;
}
</style>
<template>
<md-field-group class="register_submit">
<md-field v-model="code" icon="mobile" placeholder="请输入验证码">
<div slot="rightIcon" @click="getCode" class="getCode red">
<countdown v-if="counting" :time="60000" @countdownend="countdownend">
<template slot-scope="props">{{ +props.seconds || 60 }}秒后获取</template>
</countdown>
<span v-else>获取验证码</span>
</div>
</md-field>
<md-field v-model="password" icon="lock" placeholder="请输入密码"/>
<md-field v-model="repeatPassword" icon="lock" placeholder="请再次确认密码"/>
<div class="register_submit_btn">
<van-button type="danger" size="large" @click="registerSubmit">确定</van-button>
</div>
</md-field-group>
</template>
<script>
import field from '@/components/field/';
import fieldGroup from '@/components/field-group/';
export default {
data() {
return {
counting: true,
code: '',
password: '',
repeatPassword: ''
};
},
methods: {
registerSubmit() {
this.$router.push({
name: 'registerStatus',
params: { status: 'success' }
});
},
getCode() {
this.counting = true;
},
countdownend() {
this.counting = false;
}
},
components: {
[field.name]: field,
[fieldGroup.name]: fieldGroup
}
};
</script>
<style lang="scss" scoped>
@import '../../../assets/scss/mixin';
.register_submit {
padding-top: 40px;
background-color: #fff;
}
.register_submit_btn {
padding-top: 30px;
}
.getCode {
@include one-border(left);
text-align: center;
}
.time_down {
color: $red;
}
</style>
<template>
<div class="tab-cart">
<div class="editor_head" v-show="goods.length">
<van-icon :name="isEditor ? 'success' : 'editor'"/>
<span @click="isEditor = !isEditor">{{isEditor ? '完成' : '编辑'}}</span>
</div>
<van-checkbox-group @change="toggle" class="card-goods" v-model="checkedGoods">
<div v-for="(item, i) in goods" :key="i" class="card-goods__item">
<van-checkbox :key="item.id" :name="item.id" v-model="item.checked"></van-checkbox>
<van-card desc="暂无描述" :num="item.number" :thumb="item.picUrl">
<div class="van-card__row" slot="title">
<div class="van-card__title">
<!-- <van-tag plain type="danger">海淘</van-tag> -->
{{item.goodsName}}
</div>
<div class="van-card__price">{{item.price * 100 | yuan}}</div>
</div>
<div slot="footer" v-if="isEditor">
<van-stepper v-model="item.number" @change="stepperEvent(item,arguments)" disableInput/>
</div>
<div slot="footer" v-else>添加日期 {{item.addTime}}</div>
</van-card>
<div class="cart_delete" v-if="isEditor" @click="deleteCart(i)">删除</div>
</div>
</van-checkbox-group>
<div class="clear_invalid" v-if="goods.length" @click="clearInvalid">
<van-icon name="lajitong"/>清除失效商品
</div>
<is-empty v-if="!goods.length">您的购物车空空如也~</is-empty>
<van-submit-bar
style="bottom: 50px"
:price="totalPrice"
:disabled="!checkedGoods.length"
:buttonText="submitBarText"
:loading="isSubmit"
label="总计"
@submit="cartSubmit"
>
<van-checkbox v-model="allCheckedStatus" @change="setCheckAll" style="padding: 0 10px;">全选</van-checkbox>
</van-submit-bar>
</div>
</template>
<script>
import { Checkbox, CheckboxGroup, Card, SubmitBar, Stepper, Tag } from 'vant';
import isEmpty from '@/vue/components/is-empty/';
import _ from 'lodash';
import { debug } from 'util';
export default {
data() {
return {
isEditor: false,
checkedAll: false,
isSubmit: false,
checkedGoods: [],
AllGoods: [],
allCheckedStatus: false,
goods: [],
count: 0
};
},
activated() {
this.checkedAll = false;
this.isEditor = false;
this.isSubmit = false;
},
created() {
this.init();
},
computed: {
submitBarText() {
const count = this.count;
return this.isEditor ? '删除' : `结算${count ? `(${count})` : ''}`;
},
totalPrice() {
return this.goods.reduce(
(total, item) =>
total +
(this.checkedGoods.indexOf(item.id) !== -1
? item.price * item.number * 100
: 0),
0
);
}
},
methods: {
async stepperEvent(item, arg) {
let number = arg[0];
await this.$reqPost('/wx/cart/update', {
number: number,
goodsId: item.goodsId,
id: item.id,
productId: item.productId
});
},
async init() {
let { data } = await this.$reqGet('/wx/cart/index');
this.goods = data.data.cartList;
this.AllGoods = this.getAllList();
this.checkedGoods = this.getCheckedList(this.goods);
this.count = this.checkedGoods.length;
},
getAllList() {
let result = [];
_.each(this.goods, v => {
result.push(v.id);
});
return result;
},
getCheckedList(goods) {
let result = [];
_.each(goods, v => {
if (v.checked) {
result.push(v.id);
}
});
return result;
},
async cartSubmit(data) {
let productIds = [];
let checkedGoods = this.checkedGoods;
_.each(checkedGoods, id => {
productIds.push(
_.find(this.goods, vv => {
return id === vv.id;
}).productId
);
});
console.log(this.goods);
if (this.isEditor) {
this.$dialog
.confirm({
message: '确定删除所选商品吗?',
cancelButtonText: '再想想'
})
.then(() => {
this.deleteNext(productIds);
});
} else {
// for (check in checkedGoods){
// await this.doCheck(productIds);
// }
let { data } = await this.$reqGet(
'/wx/cart/checkout?cartId=0&addressId=0&couponId=0&grouponRulesId=0'
);
this.isSubmit = true;
this.$router.push({ name: 'placeOrderEntity' });
}
},
async doCheck(productIds, isChecked) {
// let good = _.find(this.goods, vv => {
// return id === vv.id;
// })
// let productId = good.productId;
let { data } = await this.$reqPost('/wx/cart/checked', {
productIds: productIds,
isChecked: isChecked
});
// if (this.checkedGoods.length == this.AllGoods.length) {
// this.allCheckedStatus = true;
// }
},
formatPrice(price) {
return (price / 100).toFixed(2);
},
setCheckAll(val) {
if (this.checkedGoods.length === this.AllGoods.length) {
this.checkedGoods = [];
} else {
this.checkedGoods = this.AllGoods;
}
},
deleteCart(o) {
let productId = this.goods[o].productId;
this.$dialog
.confirm({ message: '确定删除所选商品吗', cancelButtonText: '再想想' })
.then(() => {
// const goodsId = this.goods.splice(i, 1)[0].id;
this.$nextTick(() => {
this.deleteNext(productId);
});
});
},
toggle(index) {
let addProductIds = [];
_.each(index, v => {
let productId = _.find(this.goods, result => {
return result.id === v;
}).productId;
addProductIds.push(productId);
});
let delProductIds = [];
_.each(_.difference(this.AllGoods, index), v => {
let productId = _.find(this.goods, result => {
return result.id === v;
}).productId;
delProductIds.push(productId);
});
//没选中的不掉接口
if (delProductIds.length > 0) {
this.doCheck(delProductIds, 0);
}
if (addProductIds.length > 0) {
this.doCheck(addProductIds, 1);
}
},
async deleteNext(o) {
let productIds = [];
if (o instanceof Array) {
productIds = o;
} else {
productIds.push(o);
}
let { data } = await this.$reqPost('/wx/cart/delete', {
productIds: productIds
});
this.count = this.count - productIds.length;
this.goods = data.data.cartList;
// this.isEditor = !!this.goods.length;
// this.checkedGoods.forEach((goods, i) => {
// if (goods.id == goodsId) {
// this.checkedGoods.splice(i, 1);
// return false;
// }
// });
},
clearInvalid() {
this.$dialog
.confirm({
message: '确定清除所有失效商品吗?',
cancelButtonText: '再想想'
})
.then(() => {
this.goods = this.goods.filter(goods => goods.checked);
});
}
},
components: {
[Card.name]: Card,
[Tag.name]: Tag,
[Stepper.name]: Stepper,
[isEmpty.name]: isEmpty,
[Checkbox.name]: Checkbox,
[SubmitBar.name]: SubmitBar,
[CheckboxGroup.name]: CheckboxGroup
}
};
</script>
<style lang="scss" scoped>
@import '../../assets/scss/mixin';
.tab-cart {
padding-bottom: 50px;
box-sizing: border-box;
}
.editor_head {
@include one-border;
text-align: right;
padding: 10px;
font-size: $font-size-normal;
background-color: #fff;
}
.card-goods {
background-color: $bg-color;
.card-goods__item {
display: flex;
align-items: center;
margin-bottom: 10px;
background-color: #fff;
}
.cart_delete {
line-height: 100px;
padding: 0 10px;
color: #fff;
background-color: $red;
}
.card-goods__footer {
font-size: $font-size-normal;
color: $font-color-gray;
}
}
.clear_invalid {
width: 120px;
color: $font-color-gray;
border: 1px solid $font-color-gray;
margin: 0 auto;
text-align: center;
padding: 5px 3px;
margin-top: 20px;
border-radius: 3px;
}
</style>
<template>
<div class="tab-cart">
<div class="editor_head" v-show="goods.length">
<van-icon :name="isEditor ? 'success' : 'editor'"/>
<span @click="isEditor = !isEditor">{{isEditor ? '完成' : '编辑'}}</span>
</div>
<van-checkbox-group @change="toggle" class="card-goods" v-model="checkedGoods">
<div v-for="(item, i) in goods" :key="i" class="card-goods__item">
<van-checkbox :key="item.id" :name="item.id" v-model="item.checked"></van-checkbox>
<van-card desc="暂无描述" :num="item.number" :thumb="item.picUrl">
<div class="van-card__row" slot="title">
<div class="van-card__title">
<!-- <van-tag plain type="danger">海淘</van-tag> -->
{{item.goodsName}}
</div>
<div class="van-card__price">{{item.price * 100 | yuan}}</div>
</div>
<div slot="footer" v-if="isEditor">
<van-stepper v-model="item.number" @change="stepperEvent(item,arguments)" disableInput/>
</div>
<div slot="footer" v-else>添加日期 {{item.addTime}}</div>
</van-card>
<div class="cart_delete" v-if="isEditor" @click="deleteCart(i)">删除</div>
</div>
</van-checkbox-group>
<div class="clear_invalid" v-if="goods.length" @click="clearInvalid">
<van-icon name="lajitong"/>清除失效商品
</div>
<is-empty v-if="!goods.length">您的购物车空空如也~</is-empty>
<van-submit-bar
style="bottom: 50px"
:price="totalPrice"
:disabled="!checkedGoods.length"
:buttonText="submitBarText"
:loading="isSubmit"
label="总计"
@submit="cartSubmit"
>
<van-checkbox v-model="allCheckedStatus" @change="setCheckAll" style="padding: 0 10px;">全选</van-checkbox>
</van-submit-bar>
</div>
</template>
<script>
import { Checkbox, CheckboxGroup, Card, SubmitBar, Stepper, Tag } from 'vant';
import isEmpty from '@/components/is-empty/';
import _ from 'lodash';
import { debug } from 'util';
export default {
data() {
return {
isEditor: false,
checkedAll: false,
isSubmit: false,
checkedGoods: [],
AllGoods: [],
allCheckedStatus: false,
goods: [],
count: 0
};
},
activated() {
this.checkedAll = false;
this.isEditor = false;
this.isSubmit = false;
},
created() {
this.init();
},
computed: {
submitBarText() {
const count = this.count;
return this.isEditor ? '删除' : `结算${count ? `(${count})` : ''}`;
},
totalPrice() {
return this.goods.reduce(
(total, item) =>
total +
(this.checkedGoods.indexOf(item.id) !== -1
? item.price * item.number * 100
: 0),
0
);
}
},
methods: {
async stepperEvent(item, arg) {
let number = arg[0];
await this.$reqPost('/wx/cart/update', {
number: number,
goodsId: item.goodsId,
id: item.id,
productId: item.productId
});
},
async init() {
let { data } = await this.$reqGet('/wx/cart/index');
this.goods = data.data.cartList;
this.AllGoods = this.getAllList();
this.checkedGoods = this.getCheckedList(this.goods);
this.count = this.checkedGoods.length;
},
getAllList() {
let result = [];
_.each(this.goods, v => {
result.push(v.id);
});
return result;
},
getCheckedList(goods) {
let result = [];
_.each(goods, v => {
if (v.checked) {
result.push(v.id);
}
});
return result;
},
async cartSubmit(data) {
let productIds = [];
let checkedGoods = this.checkedGoods;
_.each(checkedGoods, id => {
productIds.push(
_.find(this.goods, vv => {
return id === vv.id;
}).productId
);
});
console.log(this.goods);
if (this.isEditor) {
this.$dialog
.confirm({
message: '确定删除所选商品吗?',
cancelButtonText: '再想想'
})
.then(() => {
this.deleteNext(productIds);
});
} else {
// for (check in checkedGoods){
// await this.doCheck(productIds);
// }
let { data } = await this.$reqGet(
'/wx/cart/checkout?cartId=0&addressId=0&couponId=0&grouponRulesId=0'
);
this.isSubmit = true;
this.$router.push({ name: 'placeOrderEntity' });
}
},
async doCheck(productIds, isChecked) {
// let good = _.find(this.goods, vv => {
// return id === vv.id;
// })
// let productId = good.productId;
let { data } = await this.$reqPost('/wx/cart/checked', {
productIds: productIds,
isChecked: isChecked
});
// if (this.checkedGoods.length == this.AllGoods.length) {
// this.allCheckedStatus = true;
// }
},
formatPrice(price) {
return (price / 100).toFixed(2);
},
setCheckAll(val) {
if (this.checkedGoods.length === this.AllGoods.length) {
this.checkedGoods = [];
} else {
this.checkedGoods = this.AllGoods;
}
},
deleteCart(o) {
let productId = this.goods[o].productId;
this.$dialog
.confirm({ message: '确定删除所选商品吗', cancelButtonText: '再想想' })
.then(() => {
// const goodsId = this.goods.splice(i, 1)[0].id;
this.$nextTick(() => {
this.deleteNext(productId);
});
});
},
toggle(index) {
let addProductIds = [];
_.each(index, v => {
let productId = _.find(this.goods, result => {
return result.id === v;
}).productId;
addProductIds.push(productId);
});
let delProductIds = [];
_.each(_.difference(this.AllGoods, index), v => {
let productId = _.find(this.goods, result => {
return result.id === v;
}).productId;
delProductIds.push(productId);
});
//没选中的不掉接口
if (delProductIds.length > 0) {
this.doCheck(delProductIds, 0);
}
if (addProductIds.length > 0) {
this.doCheck(addProductIds, 1);
}
},
async deleteNext(o) {
let productIds = [];
if (o instanceof Array) {
productIds = o;
} else {
productIds.push(o);
}
let { data } = await this.$reqPost('/wx/cart/delete', {
productIds: productIds
});
this.count = this.count - productIds.length;
this.goods = data.data.cartList;
// this.isEditor = !!this.goods.length;
// this.checkedGoods.forEach((goods, i) => {
// if (goods.id == goodsId) {
// this.checkedGoods.splice(i, 1);
// return false;
// }
// });
},
clearInvalid() {
this.$dialog
.confirm({
message: '确定清除所有失效商品吗?',
cancelButtonText: '再想想'
})
.then(() => {
this.goods = this.goods.filter(goods => goods.checked);
});
}
},
components: {
[Card.name]: Card,
[Tag.name]: Tag,
[Stepper.name]: Stepper,
[isEmpty.name]: isEmpty,
[Checkbox.name]: Checkbox,
[SubmitBar.name]: SubmitBar,
[CheckboxGroup.name]: CheckboxGroup
}
};
</script>
<style lang="scss" scoped>
@import '../../assets/scss/mixin';
.tab-cart {
padding-bottom: 50px;
box-sizing: border-box;
}
.editor_head {
@include one-border;
text-align: right;
padding: 10px;
font-size: $font-size-normal;
background-color: #fff;
}
.card-goods {
background-color: $bg-color;
.card-goods__item {
display: flex;
align-items: center;
margin-bottom: 10px;
background-color: #fff;
}
.cart_delete {
line-height: 100px;
padding: 0 10px;
color: #fff;
background-color: $red;
}
.card-goods__footer {
font-size: $font-size-normal;
color: $font-color-gray;
}
}
.clear_invalid {
width: 120px;
color: $font-color-gray;
border: 1px solid $font-color-gray;
margin: 0 auto;
text-align: center;
padding: 5px 3px;
margin-top: 20px;
border-radius: 3px;
}
</style>
......@@ -40,13 +40,13 @@
<script>
import { GOODS_COLLECT_LIST } from '@/api/user';
import ItemGroup from '@/vue/components/item-group/';
import ItemCardHori from '@/vue/components/item-card-hori/';
import IsEmpty from '@/vue/components/is-empty/';
import ItemGroup from '@/components/item-group/';
import ItemCardHori from '@/components/item-card-hori/';
import IsEmpty from '@/components/is-empty/';
import { Search, List } from 'vant';
import loadMore from '@/vue/mixin/list-load-more';
import scrollFixed from '@/vue/mixin/scroll-fixed';
import loadMore from '@/mixin/list-load-more';
import scrollFixed from '@/mixin/scroll-fixed';
export default {
mixins: [loadMore, scrollFixed],
......
<template>
<div class="order_list no-pad-bottom over-hide">
<van-tabs v-model="activeIndex" :swipe-threshold="5" @click="handleTabClick">
<van-tab v-for="(tab, tabIndex) in tabsItem" :title="tab.name" :key="tab.type">
<InfinityScroll
class="full-page scroll-wrap height-fix42"
:beforeRequest="beforeRequest"
:apiUrl="listApi"
@onLoad="onLoad(tabIndex, $event)"
>
<van-panel
v-for="(el, i) in tab.items"
class="order_list--panel"
:key="el.id"
:title="'订单编号: ' + el.id"
:status="getStatusText(el.status)"
>
<div>
<van-card
v-for="(goods, i) in el.serviceItems"
class="order_list--van-card"
:key="i"
:title="goods.item_name"
:desc="goods.sku_props_str"
:num="10000"
:price="(goods.price / 100).toFixed(2)"
:thumb="goods.pic_url"
/>
<div class="order_list--total">合计: {{el.total_fee | yuan}}(含运费{{el.post_fee | yuan}}</div>
</div>
<component
slot="footer"
:is="'status' + el.status"
@delete-order="delOrder(i)"
@pay="toPay(el.id)"
@cancel="cancelOrder(i)"
/>
</van-panel>
</InfinityScroll>
</van-tab>
</van-tabs>
</div>
</template>
<script>
import { ELE_COUPON_LIST } from '@/api/order';
import { Tab, Tabs, Panel, Card, List } from 'vant';
import status10 from './handle-status-10';
import status40 from './handle-status-40';
import status60 from './handle-status-60';
import status70 from './handle-status-70';
import status100 from './handle-status-100';
import status110 from './handle-status-110';
import status120 from './handle-status-120';
import _ from 'lodash';
import InfinityScroll from '@/vue/components/infinity-scroll';
const STATUS_TEXT = {
10: '待付款',
40: '已完成',
60: '已关闭',
70: '已关闭',
100: '未使用',
110: '已使用',
120: '已退款'
};
export default {
name: 'order-list',
props: {
active: {
type: [String, Number],
default: 0
}
},
data() {
const activeIndex = this.active;
return {
listApi: ELE_COUPON_LIST,
shop_id: 1,
activeIndex,
tabsItem: [
{
name: '全部',
status: 0,
items: []
},
{
name: '待付款',
status: 10,
items: []
},
{
name: '待使用',
status: 100,
items: []
},
{
name: '已使用',
status: 110,
items: []
},
{
name: '退款成功',
status: 120,
items: []
}
]
};
},
methods: {
onLoad(i, items) {
new Array(10).fill(1).forEach(() => {
items.push(_.cloneDeep(_.last(items)));
});
this.tabsItem[i].items.push(...items);
},
beforeRequest() {
const i = this.activeIndex;
const status = this.tabsItem[i].status;
const { shop_id } = this;
return {
params: {
status,
shop_id
}
};
},
delOrder(i) {
this.$dialog.confirm({ message: '确定删除订单?' }).then(() => {
this.items.splice(i, 1);
this.$toast('已删除');
});
},
async cancelOrder(i) {
this.$dialog
.confirm({ message: '确定要取消该订单吗?' })
.then(() => {
this.items.splice(i, 1);
this.$toast('已取消该订单');
})
.catch(() => {});
},
toPay(id) {
this.$router.push({ name: 'payment', params: { order_id: id } });
},
handleTabClick(index) {
this.$router.replace({
name: 'user-order-ele-list',
params: { status: index }
});
},
getStatusText(status) {
return STATUS_TEXT[status] || '';
}
},
components: {
[Tab.name]: Tab,
[Tabs.name]: Tabs,
[Panel.name]: Panel,
[Card.name]: Card,
[List.name]: List,
InfinityScroll,
status10,
status40,
status60,
status70,
status100,
status110,
status120
}
};
</script>
<style lang="scss" scoped>
.order_list {
&--footer_btn {
text-align: right;
}
&--panel {
margin-bottom: 10px;
}
&--van-card {
background-color: #fafafa;
}
&--total {
text-align: right;
padding: 10px;
}
}
</style>
<template>
<div class="order_list no-pad-bottom over-hide">
<van-tabs v-model="activeIndex" :swipe-threshold="5" @click="handleTabClick">
<van-tab v-for="(tab, tabIndex) in tabsItem" :title="tab.name" :key="tab.type">
<InfinityScroll
class="full-page scroll-wrap height-fix42"
:beforeRequest="beforeRequest"
:apiUrl="listApi"
@onLoad="onLoad(tabIndex, $event)"
>
<van-panel
v-for="(el, i) in tab.items"
class="order_list--panel"
:key="el.id"
:title="'订单编号: ' + el.id"
:status="getStatusText(el.status)"
>
<div>
<van-card
v-for="(goods, i) in el.serviceItems"
class="order_list--van-card"
:key="i"
:title="goods.item_name"
:desc="goods.sku_props_str"
:num="10000"
:price="(goods.price / 100).toFixed(2)"
:thumb="goods.pic_url"
/>
<div class="order_list--total">合计: {{el.total_fee | yuan}}(含运费{{el.post_fee | yuan}}</div>
</div>
<component
slot="footer"
:is="'status' + el.status"
@delete-order="delOrder(i)"
@pay="toPay(el.id)"
@cancel="cancelOrder(i)"
/>
</van-panel>
</InfinityScroll>
</van-tab>
</van-tabs>
</div>
</template>
<script>
import { ELE_COUPON_LIST } from '@/api/order';
import { Tab, Tabs, Panel, Card, List } from 'vant';
import status10 from './handle-status-10';
import status40 from './handle-status-40';
import status60 from './handle-status-60';
import status70 from './handle-status-70';
import status100 from './handle-status-100';
import status110 from './handle-status-110';
import status120 from './handle-status-120';
import _ from 'lodash';
import InfinityScroll from '@/components/infinity-scroll';
const STATUS_TEXT = {
10: '待付款',
40: '已完成',
60: '已关闭',
70: '已关闭',
100: '未使用',
110: '已使用',
120: '已退款'
};
export default {
name: 'order-list',
props: {
active: {
type: [String, Number],
default: 0
}
},
data() {
const activeIndex = this.active;
return {
listApi: ELE_COUPON_LIST,
shop_id: 1,
activeIndex,
tabsItem: [
{
name: '全部',
status: 0,
items: []
},
{
name: '待付款',
status: 10,
items: []
},
{
name: '待使用',
status: 100,
items: []
},
{
name: '已使用',
status: 110,
items: []
},
{
name: '退款成功',
status: 120,
items: []
}
]
};
},
methods: {
onLoad(i, items) {
new Array(10).fill(1).forEach(() => {
items.push(_.cloneDeep(_.last(items)));
});
this.tabsItem[i].items.push(...items);
},
beforeRequest() {
const i = this.activeIndex;
const status = this.tabsItem[i].status;
const { shop_id } = this;
return {
params: {
status,
shop_id
}
};
},
delOrder(i) {
this.$dialog.confirm({ message: '确定删除订单?' }).then(() => {
this.items.splice(i, 1);
this.$toast('已删除');
});
},
async cancelOrder(i) {
this.$dialog
.confirm({ message: '确定要取消该订单吗?' })
.then(() => {
this.items.splice(i, 1);
this.$toast('已取消该订单');
})
.catch(() => {});
},
toPay(id) {
this.$router.push({ name: 'payment', params: { order_id: id } });
},
handleTabClick(index) {
this.$router.replace({
name: 'user-order-ele-list',
params: { status: index }
});
},
getStatusText(status) {
return STATUS_TEXT[status] || '';
}
},
components: {
[Tab.name]: Tab,
[Tabs.name]: Tabs,
[Panel.name]: Panel,
[Card.name]: Card,
[List.name]: List,
InfinityScroll,
status10,
status40,
status60,
status70,
status100,
status110,
status120
}
};
</script>
<style lang="scss" scoped>
.order_list {
&--footer_btn {
text-align: right;
}
&--panel {
margin-bottom: 10px;
}
&--van-card {
background-color: #fafafa;
}
&--total {
text-align: right;
padding: 10px;
}
}
</style>
<template>
<div class="order_list over-hide">
<van-tabs v-model="activeIndex" :swipe-threshold="5" @click="handleTabClick">
<van-tab
v-for="(tab, tabIndex) in tabsItem"
:title="tab.name"
@click="changeTab"
:key="tab.type"
>
<InfinityScroll
class="full-page scroll-wrap height-fix42"
:beforeRequest="beforeRequest"
:apiUrl="listApi"
@onLoad="onLoad(tabIndex, $event)"
>
<van-panel
v-for="(el, i) in orderArr"
class="order_list--panel"
:key="i"
:title="'订单编号: ' + el.orderSn"
:status="el.orderStatusText"
>
<div>
<van-card
v-for="(goods, goodsI) in el.goodsList"
class="order_list--van-card"
:key="goodsI"
:title="goods.goodsName"
:desc="goods.goodsName"
:num="goods.number"
:thumb="goods.picUrl"
@click.native="toOrderDetail(el.id)"
/>
<div
class="order_list--total"
>合计: {{el.actualPrice * 100 | yuan}}(含运费{{el.post_fee | yuan}}</div>
</div>
<component
slot="footer"
:is="'status' + el.status"
:reminder="el.is_can_reminder"
@handle="actionHandle($event, i)"
/>
</van-panel>
</InfinityScroll>
</van-tab>
</van-tabs>
</div>
</template>
<script>
import { ORDER_LIST } from '@/api/order';
import { Tab, Tabs, Panel, Card, List } from 'vant';
import status10 from './handle-status-10';
import status20 from './handle-status-20';
import status25 from './handle-status-25';
import status30 from './handle-status-30';
import status40 from './handle-status-40';
import status50 from './handle-status-50';
import status60 from './handle-status-60';
import status70 from './handle-status-70';
import InfinityScroll from '@/vue/components/infinity-scroll';
const STATUS_TEXT = {
10: '待付款',
20: '待发货',
25: '部分发货',
30: '待收货',
40: '已完成',
50: '退款成功',
60: '交易关闭',
70: '交易关闭'
};
export default {
name: 'order-list',
props: {
active: {
type: [String, Number],
default: 0
}
},
created() {
this.init();
},
data() {
const activeIndex = this.active;
return {
listApi: ORDER_LIST,
shop_id: 1,
activeIndex,
tabsItem: [
{
name: '全部',
status: 0,
items: []
},
{
name: '待付款',
status: 10,
items: []
},
{
name: '待发货',
status: 20,
items: []
},
{
name: '待收货',
status: 30,
items: []
},
{
name: '已完成',
status: 40,
items: []
}
],
orderArr: []
};
},
methods: {
async init(i) {
let { data } = await this.$reqGet(
`/wx/order/list?showType=${i || this.active || '0'}`
);
this.orderArr = data.data.data;
},
onLoad(i, items) {
this.tabsItem[i].items.push(...items);
},
beforeRequest() {
const i = this.activeIndex;
const status = this.tabsItem[i].status;
const { shop_id } = this;
return {
params: {
status,
shop_id
}
};
},
async delOrder(i) {
await this.$dialog.confirm({ message: '确定要删除该订单吗?' });
this.items.splice(i, 1);
this.$toast('已删除该订单');
},
async cancelOrder(i) {
await this.$dialog.confirm({ message: '确定要取消该订单吗?' });
if (this.activeIndex == 0) {
this.items[i].status = 60;
} else {
this.items.splice(i, 1);
}
this.$toast('已取消该订单');
},
async receiptOrder(i) {
await this.$dialog.confirm({
message: '请确认收到货物, 确认收货后无法撤销!'
});
this.items[i].status = 40;
this.$toast('已确认收货');
},
reminderOrder(i) {
this.items[i].is_can_reminder = false;
this.$toast('已提醒卖家发货, 请耐心等待哦~');
},
toPay(i) {
const id = this.items[i].id;
this.$router.push({ name: 'payment', params: { order_id: id } });
},
handleTabClick(index) {
console.log(6666666);
// console.log(index);
// await this.init(i);
this.$router.replace({
name: 'user-order-list',
params: { active: index }
});
},
getStatusText(status) {
return STATUS_TEXT[status] || '';
},
toOrderDetail(id) {
this.$router.push({
name: `orderDetail`,
query: { cartId: 0, orderId: id }
});
},
actionHandle(handle, i) {
this[handle] && this[handle](i);
}
},
watch: {
active(val) {
this.init(val);
val && !this.address_list.length && this.getAddress();
}
},
components: {
InfinityScroll,
[Tab.name]: Tab,
[Tabs.name]: Tabs,
[Panel.name]: Panel,
[Card.name]: Card,
[List.name]: List,
status10,
status20,
status25,
status30,
status40,
status50,
status60,
status70
}
};
</script>
<style lang="scss" scoped>
.order_list {
padding-bottom: 0;
overflow-y: hidden;
&--footer_btn {
text-align: right;
}
&--panel {
margin-bottom: 10px;
}
&--van-card {
background-color: #fafafa;
}
&--total {
text-align: right;
padding: 10px;
}
}
</style>
<template>
<div class="order_list over-hide">
<van-tabs v-model="activeIndex" :swipe-threshold="5" @click="handleTabClick">
<van-tab
v-for="(tab, tabIndex) in tabsItem"
:title="tab.name"
@click="changeTab"
:key="tab.type"
>
<InfinityScroll
class="full-page scroll-wrap height-fix42"
:beforeRequest="beforeRequest"
:apiUrl="listApi"
@onLoad="onLoad(tabIndex, $event)"
>
<van-panel
v-for="(el, i) in orderArr"
class="order_list--panel"
:key="i"
:title="'订单编号: ' + el.orderSn"
:status="el.orderStatusText"
>
<div>
<van-card
v-for="(goods, goodsI) in el.goodsList"
class="order_list--van-card"
:key="goodsI"
:title="goods.goodsName"
:desc="goods.goodsName"
:num="goods.number"
:thumb="goods.picUrl"
@click.native="toOrderDetail(el.id)"
/>
<div
class="order_list--total"
>合计: {{el.actualPrice * 100 | yuan}}(含运费{{el.post_fee | yuan}}</div>
</div>
<component
slot="footer"
:is="'status' + el.status"
:reminder="el.is_can_reminder"
@handle="actionHandle($event, i)"
/>
</van-panel>
</InfinityScroll>
</van-tab>
</van-tabs>
</div>
</template>
<script>
import { ORDER_LIST } from '@/api/order';
import { Tab, Tabs, Panel, Card, List } from 'vant';
import status10 from './handle-status-10';
import status20 from './handle-status-20';
import status25 from './handle-status-25';
import status30 from './handle-status-30';
import status40 from './handle-status-40';
import status50 from './handle-status-50';
import status60 from './handle-status-60';
import status70 from './handle-status-70';
import InfinityScroll from '@/components/infinity-scroll';
const STATUS_TEXT = {
10: '待付款',
20: '待发货',
25: '部分发货',
30: '待收货',
40: '已完成',
50: '退款成功',
60: '交易关闭',
70: '交易关闭'
};
export default {
name: 'order-list',
props: {
active: {
type: [String, Number],
default: 0
}
},
created() {
this.init();
},
data() {
const activeIndex = this.active;
return {
listApi: ORDER_LIST,
shop_id: 1,
activeIndex,
tabsItem: [
{
name: '全部',
status: 0,
items: []
},
{
name: '待付款',
status: 10,
items: []
},
{
name: '待发货',
status: 20,
items: []
},
{
name: '待收货',
status: 30,
items: []
},
{
name: '已完成',
status: 40,
items: []
}
],
orderArr: []
};
},
methods: {
async init(i) {
let { data } = await this.$reqGet(
`/wx/order/list?showType=${i || this.active || '0'}`
);
this.orderArr = data.data.data;
},
onLoad(i, items) {
this.tabsItem[i].items.push(...items);
},
beforeRequest() {
const i = this.activeIndex;
const status = this.tabsItem[i].status;
const { shop_id } = this;
return {
params: {
status,
shop_id
}
};
},
async delOrder(i) {
await this.$dialog.confirm({ message: '确定要删除该订单吗?' });
this.items.splice(i, 1);
this.$toast('已删除该订单');
},
async cancelOrder(i) {
await this.$dialog.confirm({ message: '确定要取消该订单吗?' });
if (this.activeIndex == 0) {
this.items[i].status = 60;
} else {
this.items.splice(i, 1);
}
this.$toast('已取消该订单');
},
async receiptOrder(i) {
await this.$dialog.confirm({
message: '请确认收到货物, 确认收货后无法撤销!'
});
this.items[i].status = 40;
this.$toast('已确认收货');
},
reminderOrder(i) {
this.items[i].is_can_reminder = false;
this.$toast('已提醒卖家发货, 请耐心等待哦~');
},
toPay(i) {
const id = this.items[i].id;
this.$router.push({ name: 'payment', params: { order_id: id } });
},
handleTabClick(index) {
console.log(6666666);
// console.log(index);
// await this.init(i);
this.$router.replace({
name: 'user-order-list',
params: { active: index }
});
},
getStatusText(status) {
return STATUS_TEXT[status] || '';
},
toOrderDetail(id) {
this.$router.push({
name: `orderDetail`,
query: { cartId: 0, orderId: id }
});
},
actionHandle(handle, i) {
this[handle] && this[handle](i);
}
},
watch: {
active(val) {
this.init(val);
val && !this.address_list.length && this.getAddress();
}
},
components: {
InfinityScroll,
[Tab.name]: Tab,
[Tabs.name]: Tabs,
[Panel.name]: Panel,
[Card.name]: Card,
[List.name]: List,
status10,
status20,
status25,
status30,
status40,
status50,
status60,
status70
}
};
</script>
<style lang="scss" scoped>
.order_list {
padding-bottom: 0;
overflow-y: hidden;
&--footer_btn {
text-align: right;
}
&--panel {
margin-bottom: 10px;
}
&--van-card {
background-color: #fafafa;
}
&--total {
text-align: right;
padding: 10px;
}
}
</style>
<template>
<div class="order_list">
<van-tabs sticky :active="activeIndex" :swipe-threshold="5" @click="handleTabClick">
<van-tab v-for="(tab, tabIndex) in tabsItem" :title="tab.name" :key="tab.type">
<InfinityScroll
class="full-page scroll-wrap"
:beforeRequest="beforeRequest"
:apiUrl="listApi"
@onLoad="onLoad(tabIndex, $event)"
>
<van-panel
v-for="(el, i) in tab.items"
class="order_list--panel"
:key="i"
:title="'订单编号: ' + el.id"
:status="getStatusText(el.status)"
>
<div>
<van-card
class="order_list--van-card"
:key="i"
:title="el.orderItem.item_name"
:desc="el.orderItem.sku_props_str"
:num="10000"
:price="(el.orderItem.price / 100).toFixed(2)"
:thumb="el.orderItem.pic_url"
/>
<div
class="order_list--total"
>合计: {{el.refund_fee | yuan}}(含运费{{el.refund_post_fee | yuan}}</div>
</div>
<div slot="footer" style="text-align: right;">
<van-button
size="small"
@click="refund_handle(i)"
>{{ el.status == 10 ? "撤销申请" : "查看详情"}}</van-button>
</div>
</van-panel>
</InfinityScroll>
</van-tab>
</van-tabs>
</div>
</template>
<script>
import { REFUND_LIST } from '@/api/order';
import { Tab, Tabs, Panel, Card, List } from 'vant';
import InfinityScroll from '@/vue/components/infinity-scroll';
const STATUS_TEXT = {
10: '退款中',
50: '退款关闭',
60: '退款成功'
};
export default {
name: 'order-list',
data() {
return {
listApi: REFUND_LIST,
shop_id: 1,
activeIndex: 0,
items: [],
tabsItem: [
{
name: '全部',
status: 0,
items: []
},
{
name: '退款中',
status: 10,
items: []
},
{
name: '退款成功',
status: 60,
items: []
}
]
};
},
methods: {
onLoad(i, items) {
this.tabsItem[i].items.push(...items);
},
beforeRequest() {
const i = this.activeIndex;
const status = this.tabsItem[i].status;
const { shop_id } = this;
return {
params: {
status,
shop_id
}
};
},
refund_handle(i) {
const item = this.items[i];
if (item.status == 10) {
this.$dialog
.confirm({
message: '撤销后将不能再次发起申请,确定要撤销该申请吗?'
})
.then(() => {
this.$toast('已撤销该退款申请');
this.items[i].status = 50;
});
} else {
// 跳转退款详情
}
},
handleTabClick(index) {
if (this.activeIndex != index) {
this.activeIndex = index;
}
},
getStatusText(status) {
return STATUS_TEXT[status] || '';
}
},
components: {
[Tab.name]: Tab,
[Tabs.name]: Tabs,
[Panel.name]: Panel,
[Card.name]: Card,
[List.name]: List,
InfinityScroll
}
};
</script>
<style lang="scss" scoped>
.order_list {
padding-bottom: 0;
&--footer_btn {
text-align: right;
}
&--panel {
margin-bottom: 10px;
}
&--van-card {
background-color: #fafafa;
}
&--total {
text-align: right;
padding: 10px;
}
}
</style>
<template>
<div class="order_list">
<van-tabs sticky :active="activeIndex" :swipe-threshold="5" @click="handleTabClick">
<van-tab v-for="(tab, tabIndex) in tabsItem" :title="tab.name" :key="tab.type">
<InfinityScroll
class="full-page scroll-wrap"
:beforeRequest="beforeRequest"
:apiUrl="listApi"
@onLoad="onLoad(tabIndex, $event)"
>
<van-panel
v-for="(el, i) in tab.items"
class="order_list--panel"
:key="i"
:title="'订单编号: ' + el.id"
:status="getStatusText(el.status)"
>
<div>
<van-card
class="order_list--van-card"
:key="i"
:title="el.orderItem.item_name"
:desc="el.orderItem.sku_props_str"
:num="10000"
:price="(el.orderItem.price / 100).toFixed(2)"
:thumb="el.orderItem.pic_url"
/>
<div
class="order_list--total"
>合计: {{el.refund_fee | yuan}}(含运费{{el.refund_post_fee | yuan}}</div>
</div>
<div slot="footer" style="text-align: right;">
<van-button
size="small"
@click="refund_handle(i)"
>{{ el.status == 10 ? "撤销申请" : "查看详情"}}</van-button>
</div>
</van-panel>
</InfinityScroll>
</van-tab>
</van-tabs>
</div>
</template>
<script>
import { REFUND_LIST } from '@/api/order';
import { Tab, Tabs, Panel, Card, List } from 'vant';
import InfinityScroll from '@/components/infinity-scroll';
const STATUS_TEXT = {
10: '退款中',
50: '退款关闭',
60: '退款成功'
};
export default {
name: 'order-list',
data() {
return {
listApi: REFUND_LIST,
shop_id: 1,
activeIndex: 0,
items: [],
tabsItem: [
{
name: '全部',
status: 0,
items: []
},
{
name: '退款中',
status: 10,
items: []
},
{
name: '退款成功',
status: 60,
items: []
}
]
};
},
methods: {
onLoad(i, items) {
this.tabsItem[i].items.push(...items);
},
beforeRequest() {
const i = this.activeIndex;
const status = this.tabsItem[i].status;
const { shop_id } = this;
return {
params: {
status,
shop_id
}
};
},
refund_handle(i) {
const item = this.items[i];
if (item.status == 10) {
this.$dialog
.confirm({
message: '撤销后将不能再次发起申请,确定要撤销该申请吗?'
})
.then(() => {
this.$toast('已撤销该退款申请');
this.items[i].status = 50;
});
} else {
// 跳转退款详情
}
},
handleTabClick(index) {
if (this.activeIndex != index) {
this.activeIndex = index;
}
},
getStatusText(status) {
return STATUS_TEXT[status] || '';
}
},
components: {
[Tab.name]: Tab,
[Tabs.name]: Tabs,
[Panel.name]: Panel,
[Card.name]: Card,
[List.name]: List,
InfinityScroll
}
};
</script>
<style lang="scss" scoped>
.order_list {
padding-bottom: 0;
&--footer_btn {
text-align: right;
}
&--panel {
margin-bottom: 10px;
}
&--van-card {
background-color: #fafafa;
}
&--total {
text-align: right;
padding: 10px;
}
}
</style>
<template>
<div class="user_header" :style="{backgroundImage: `url(${background_image})`}">
<van-icon name="set" class="user_set" @click="toSetting"/>
<div class="user_avatar">
<img :src="avatar" alt="头像" width="55" height="55">
</div>
<div>{{nickName}}</div>
</div>
</template>
<script>
import avatar_default from '../../assets/images/avatar_default.png';
import bg_default from '../../assets/images/user_head_bg.png';
import { getLocalStorage } from 'core/utils/local-storage';
import _ from 'lodash';
export default {
name: 'user-header',
props: {
isLogin: {
type: Boolean,
default: false
}
},
data() {
return {
nickName: '昵称',
avatar: avatar_default,
background_image: bg_default
};
},
activated() {
this.getUserInfo();
},
methods: {
getUserInfo() {
const infoData = getLocalStorage(
'nickName',
'background_image',
'avatar'
);
this.avatar = avatar_default;
this.nickName = infoData.nickName || '昵称';
if (!_.isEmpty(infoData.avatar)) {
this.avatar = `http://www.qmenhu.com${infoData.avatar}`;
}
console.log(this.avatar);
console.log('-----------');
console.log(infoData);
this.background_image = infoData.background_image || bg_default;
},
toSetting() {
this.$router.push({ name: 'user-information' });
}
// toLogin() {
// !this.isLogin &&
// this.$router.push({ name: 'login', query: { redirect: 'user' } });
// }
}
};
</script>
<style lang="scss" scoped>
.user_header {
position: relative;
background-repeat: no-repeat;
background-size: cover;
height: 130px;
box-sizing: border-box;
text-align: center;
color: #fff;
padding-top: 30px;
}
i.user_set {
position: absolute;
top: 10px;
right: 10px;
font-size: 24px;
}
.user_avatar {
margin-bottom: 10px;
img {
border: 0;
border-radius: 50%;
}
}
</style>
<template>
<div class="user_header" :style="{backgroundImage: `url(${background_image})`}">
<van-icon name="set" class="user_set" @click="toSetting"/>
<div class="user_avatar">
<img :src="avatar" alt="头像" width="55" height="55">
</div>
<div>{{nickName}}</div>
</div>
</template>
<script>
import avatar_default from '@/assets/images/avatar_default.png';
import bg_default from '@/assets/images/user_head_bg.png';
import { getLocalStorage } from '@/utils/local-storage';
import _ from 'lodash';
export default {
name: 'user-header',
props: {
isLogin: {
type: Boolean,
default: false
}
},
data() {
return {
nickName: '昵称',
avatar: avatar_default,
background_image: bg_default
};
},
activated() {
this.getUserInfo();
},
methods: {
getUserInfo() {
const infoData = getLocalStorage(
'nickName',
'background_image',
'avatar'
);
this.avatar = avatar_default;
this.nickName = infoData.nickName || '昵称';
if (!_.isEmpty(infoData.avatar)) {
this.avatar = `http://www.qmenhu.com${infoData.avatar}`;
}
console.log(this.avatar);
console.log('-----------');
console.log(infoData);
this.background_image = infoData.background_image || bg_default;
},
toSetting() {
this.$router.push({ name: 'user-information' });
}
// toLogin() {
// !this.isLogin &&
// this.$router.push({ name: 'login', query: { redirect: 'user' } });
// }
}
};
</script>
<style lang="scss" scoped>
.user_header {
position: relative;
background-repeat: no-repeat;
background-size: cover;
height: 130px;
box-sizing: border-box;
text-align: center;
color: #fff;
padding-top: 30px;
}
i.user_set {
position: absolute;
top: 10px;
right: 10px;
font-size: 24px;
}
.user_avatar {
margin-bottom: 10px;
img {
border: 0;
border-radius: 50%;
}
}
</style>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment