Commit f2eeee5e authored by liumiss's avatar liumiss

我的页面、店铺页面bug

parent f7e05ee0
export default {
props: {
// the options of BetterScroll
options: {
type: Object,
default() {
return {
stopPropagation: true, bounce: false
}
}
}
}
}
......@@ -16,6 +16,17 @@ export const loginByCode = (phone, code) => request('login/code', {
code
}, 'get');
// 获取用户信息
export const getUser = () => request('user', {}, 'get');
//在登录的状态下获取验证码
export const getLoginedCode = (phone) => request('/user/bind/phone', {
phone
}, 'GET');
// 绑定手机号
export const bindPhone = (Data) => request('/user/bind/phone/code', Data, 'POST');
// 新增收货地址
......@@ -40,7 +51,7 @@ export const getShopInfo = (shop_id) => request('shop', { shop_id }, 'get');
export const allCategoryAndGoods = (shop_id) => request('/shop/goods/shop', { shop_id}, 'get');
/******* 订单相关 ******/
// 店铺订单-下单- 预下单
export const preorder = (shop_id,price, address_id, goods_list) => request('shop/order/pre', {
......@@ -71,6 +82,11 @@ export const getOrderDetail = (order_no) => request('user/order/detail', {
}, 'get');
// 获取优惠券
export const getCoupons = (page, perPage) => request('coupons/self', {
page,
perPage
}, 'get');
/******* 支付相关 ******/
......
<template>
<section class="cart_module">
<transition name="showReduce">
<span
@click="removeOutCart"
v-if="foodNum"
>
<span @click.stop="removeOutCart" v-if="foodNum">
<i class="cubeic-remove icon"></i>
</span>
</transition>
<transition name="fade">
<span class="cart_num" v-if="foodNum">{{foodNum}}</span>
</transition>
<i class="cubeic-add icon" @click="addToCart"></i>
<i class="cubeic-add icon" @click.stop="addToCart"></i>
</section>
</template>
......@@ -23,9 +20,7 @@ export default {
showMoveDot: [] //控制下落的小圆点显示隐藏
};
},
mounted() {
},
mounted() {},
computed: {
...mapState(["cartList"]),
/**
......@@ -38,14 +33,12 @@ export default {
foodNum: function() {
let category_id = this.food.goods_category_id;
let food_id = this.food.id;
if (
this.shopCart &&
this.shopCart[category_id] &&
this.shopCart[category_id][food_id]
) {
console.log(this.shopCart[category_id][food_id].num)
return this.shopCart[category_id][food_id].num;
} else {
return 0;
......@@ -56,7 +49,9 @@ export default {
methods: {
...mapMutations(["ADD_CART", "REDUCE_CART"]),
//移出购物车
removeOutCart() {
removeOutCart(event) {
event.stopPropagation();
if (this.foodNum > 0) {
const food = this.food;
const addInfo = {
......@@ -72,6 +67,7 @@ export default {
},
//加入购物车,计算按钮位置。
addToCart(event) {
event.stopPropagation();
const food = this.food;
const addInfo = {
shopid: this.shopId,
......@@ -83,7 +79,7 @@ export default {
};
this.$store.commit("ADD_CART", addInfo);
this.$emit("showMoveDots", event.target);
},
}
}
};
</script>
......
......@@ -22,7 +22,7 @@
</span>
</van-cell>
<div slot="footer">
<van-button size="small" color="#1f81be" @click="onMore" plain>再来一单</van-button>
<van-button size="small" color="#1f81be" @click="onMore(77,order.order_no)" plain>再来一单</van-button>
</div>
</van-panel>
</div>
......@@ -41,8 +41,8 @@ export default {
onCallBack(order_no) {
this.$emit("select", order_no);
},
onMore() {
this.$emit("more");
onMore(shopId,order_no) {
this.$emit("more",shopId,order_no);
},
onSelect(order_no) {
this.$emit("select", order_no);
......@@ -50,12 +50,6 @@ export default {
onShow(shopId) {
this.$emit("show", shopId);
}
// onCancel(order_no,index) {
// this.$emit("cancel", order_no,index);
// },
// onPay(order_no) {
// this.$emit("pay", order_no);
// }
}
};
</script>
......
<template>
<div class="cube-scroll-nav" :class="{'cube-scroll-nav_side': side}">
<!-- {{disable}} -->
<cube-sticky ref="sticky" :pos="scrollY" @change="stickyChangeHandler">
<cube-scroll
ref="scroll"
:scroll-events="scrollEvents"
:options="options"
:data="data"
@scroll="scrollHandler"
@scroll-end="scrollEndHandler"
>
<slot name="prepend"></slot>
<div class="cube-scroll-nav-main">
<cube-sticky-ele ref="navBarEle" ele-key="cube-scroll-nav-bar">
<slot name="bar" :txts="barTxts" :labels="labels" :current="active">
<cube-scroll-nav-bar
:direction="barDirection"
:txts="barTxts"
:labels="labels"
:current="active"
>
<span slot-scope="props">{{props.txt}}
<van-tag v-if="categoryNum[props.index]" type="danger" round style="position: absolute;">{{categoryNum[props.index]}}</van-tag>
</span>
</cube-scroll-nav-bar>
</slot>
</cube-sticky-ele>
<cube-sticky
ref="pageSticky"
:offset="pageStickyOffset"
:pos="scrollY"
@change="pageStickyChangeHandler"
>
<div class="cube-scroll-nav-panels">
<slot></slot>
</div>
<template slot="fixed" v-if="!side">
<div></div>
</template>
</cube-sticky>
</div>
</cube-scroll>
</cube-sticky>
</div>
</template>
<script type="text/ecmascript-6">
import scrollMixin from "../../common/mixins/srcoll";
const DIRECTION_H = "horizontal";
const DIRECTION_V = "vertical";
const COMPONENT_NAME = "cube-scroll-nav";
const EVENT_CHANGE = "change";
const EVENT_STICKY_CHANGE = "sticky-change";
export default {
name: COMPONENT_NAME,
provide() {
return {
scrollNav: this
};
},
mixins: [scrollMixin],
props: {
disable: {
default: true
},
data: {
type: Array
},
speed: {
type: Number,
default: 300
},
side: {
type: Boolean,
default: false
},
current: {
type: [String, Number],
default: ""
},
categoryNum:{
default:[]
}
},
data() {
return {
scrollEvents: ["scroll", "scroll-end"],
scrollY: 0,
panels: [],
active: this.current,
pageStickyOffset: 0
};
},
computed: {
labels() {
return this.panels.map(panel => panel.label);
},
barTxts() {
return this.panels.map(panel => panel.title);
},
barDirection() {
return this.side ? DIRECTION_V : DIRECTION_H;
}
},
watch: {
current(newVal) {
this.stickyCurrent = newVal;
this.active = newVal;
this.jumpTo(newVal);
},
active(newVal) {
this.$emit(EVENT_CHANGE, newVal);
},
disable(newVal, oldVal) {
if (newVal) {
this.disableFn();
} else {
this.enableFn();
}
},
categoryNum(newVal){
console.log(newVal)
}
},
created() {
this.navBar = null;
this.stickyCurrent = this.current;
},
mounted() {
this.$nextTick(() => {
if (this.side) {
const fixedEle = this.$refs.pageSticky.$refs.fixedEle;
this.$refs.scroll.$el.appendChild(fixedEle);
}
if (!this.current) {
this.active = this.stickyCurrent = this.labels[0];
}
this.refresh();
this.jumpTo(this.current);
this.disableFn();
});
},
methods: {
scrollTo() {
this.$refs.scroll &&
this.$refs.scroll.scrollTo.apply(this.$refs.scroll, arguments);
},
enableFn() {
this.$refs.scroll.enable();
},
disableFn() {
this.$refs.scroll.disable();
},
refresh() {
this.navBar && this.navBar.refresh();
this.$refs.sticky.refresh();
this.$refs.pageSticky.refresh();
this.pageStickyOffset = this.side
? 0
: this.$refs.navBarEle.$el.offsetHeight;
this.$refs.scroll.refresh();
},
setBar(bar) {
this.navBar = bar;
},
barChange(label) {
this.active = label;
// waiting touchend
// so the inner scroll won't affect the touchend logic
setTimeout(() => {
this.jumpTo(label);
});
},
jumpTo(label) {
if (!label) {
return;
}
const panel = this.getPanel(label);
if (panel) {
this._jumping = true;
const offset = this.pageStickyOffset;
this.$refs.scroll.scrollToElement(
panel.$el,
this.speed,
0,
this.side ? offset : -offset
);
}
},
getPanel(label) {
let panel = null;
this.panels.some(_panel => {
if (_panel.label === label) {
panel = _panel;
return true;
}
});
return panel;
},
pageStickyChangeHandler(current) {
if (current === "") {
current = this.labels[0];
}
this.stickyCurrent = current;
if (this._jumping) {
return;
}
this.active = current;
},
stickyChangeHandler(current) {
// when sticky change waiting dom changed
// then refresh navBar(navBar will get correct height)
this.$nextTick(() => {
this.navBar && this.navBar.refresh();
});
this.$emit(EVENT_STICKY_CHANGE, current);
},
scrollHandler(pos) {
this.scrollY = -pos.y;
if(this.scrollY==0){
this.$emit('scroll0')
}
if (!this._jumping) {
this.active = this.stickyCurrent;
}
if (this.disable) {
this.disableFn();
} else {
this.enableFn();
}
},
scrollEndHandler() {
this._jumping = false;
},
addPanel(panel) {
this.panels.push(panel);
},
removePanel(panel) {
const i = this.panels.indexOf(panel);
this.panels.splice(i, 1);
}
}
};
</script>
<style lang="stylus" rel="stylesheet/stylus">
.cube-scroll-nav {
position: relative;
height: 100%;
overflow: hidden;
.cube-sticky-content {
height: 100%;
}
}
.cube-scroll-nav-main {
overflow: hidden;
> .cube-sticky {
position: static;
}
}
.cube-scroll-nav_side {
> .cube-sticky {
display: flex;
> .cube-scroll-wrapper {
flex: 1;
}
> .cube-sticky-fixed {
position: relative;
height: 100%;
order: -1;
}
}
.cube-scroll-nav-main {
> .cube-sticky-ele {
float: left;
}
> .cube-sticky {
overflow: hidden;
}
}
}
</style>
......@@ -41,6 +41,7 @@
<script>
import CartControl from "components/cube-cart-control";
import popupMixin from "common/mixins/popup";
import {mapState} from 'vuex'
const EVENT_SHOW = "show";
const EVENT_ADD = "add";
......@@ -57,6 +58,9 @@ export default {
}
},
},
computed:{
...mapState(["cartList"])
},
data(){
return{
shopId:this.$route.params.id
......@@ -91,9 +95,7 @@ export default {
text: "取消"
},
onConfirm: () => {
this.selectFoods.forEach(food => {
food.num = 0;
});
this.$store.commit('CLEAR_SHOP_CART',this.shopId);
this.hide();
}
}).show();
......
import { createAPI } from 'cube-ui'
import Vue from 'vue'
import ShopCartList from 'components/shop-cart-list'
import ShopCartList from 'components/shopCart/shop-cart-list'
import ShopCartStikcy from 'components/shopCart/shop-cart-sticky'
import Food from "./views/shopItem/children/food-detail"
......
......@@ -16,6 +16,12 @@ const shop = r => require.ensure([], () => r(require('./views/shopItem/index.vue
const orderDetails = r => require.ensure([], () => r(require('./views/order/order-detail.vue')))
const confirmOrder = r => require.ensure([], () => r(require('./views/confirmOrder/index.vue')))
const coupon = r => require.ensure([], () => r(require('./views/coupon/coupon.vue')))
const personalSet = r => require.ensure([], () => r(require('./views/setting/personal.vue')))
const accountSet = r => require.ensure([], () => r(require('./views/setting/account.vue')))
const bindPhone = r => require.ensure([], () => r(require('./views/setting/bind-phone.vue')))
Vue.use(Router);
......@@ -97,5 +103,29 @@ export default new Router({
component: orderDetails,
meta: { title: '', requireAuth: true }
},
{
path: '/coupon',
name: 'coupon',
component: coupon,
meta: { title: '优惠券', requireAuth: true }
},
{
path: '/setting/personal',
name: 'personalSet',
component: personalSet,
meta: { title: '个人资料', requireAuth: true }
},
{
path: '/setting/account',
name: 'accountSet',
component: accountSet,
meta: { title: '设置', requireAuth: true }
},
{
path: '/setting/bindPhone',
name: 'bindPhone',
component: bindPhone,
meta: { title: '绑定手机', requireAuth: true }
},
]
});
......@@ -6,6 +6,8 @@ import actions from './actions'
Vue.use(Vuex)
const state = {
login:false,
userInfo:{},
location: { lat: '', lng: '', formattedAddress: '' }, // 当前地图定位
choosed_address:{lat: '', lng: '', formattedAddress: ''}, // 当前定位使用的地址信息
choise_position: { // 地图中选择的定位
......@@ -20,6 +22,7 @@ const state = {
shopInfo:{},// 当前店铺信息
edit_address: {}, // 待编辑的地址信息
cartList: {}, // 加入购物车的商品列表
coupon:{}
}
export default new Vuex.Store({
state,
......
import { sessionstorage } from '../common/utils/mUtils'
export default {
// 记录用户信息
RECORD_USERINFO(state, info) {
state.login = true;
let defaultAvatar = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1561635028219&di=4da64de39130854765f4e0a33fca589d&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201704%2F27%2F20170427155254_Kctx8.jpeg';
info.name = info.name ? info.name : '新用户';
info.avatar = info.avatar ? info.avatar : defaultAvatar;
state.userInfo = info;
sessionstorage.save('userInfo', info);
},
// 记录当前地理位置
RECORD_LOCATION(state, info) {
state.location = info;
......@@ -106,4 +117,20 @@ export default {
//存入localStorage
sessionstorage.save('buyCart', state.cartList);
},
// 清空店铺下的购物车数据
CLEAR_SHOP_CART(state,shopId){
state.cartList[shopId]={}
},
// 确认订单页面中使用优惠券情况
SAVE_COUPON(state, coupon) {
state.coupon = coupon
},
//退出登录
OUT_LOGIN(state) {
state.userInfo = {};
state.login = false;
},
}
\ No newline at end of file
......@@ -18,7 +18,8 @@ import {
SubmitBar ,
ActionSheet,
Panel,
List
List,
CouponCell, CouponList
} from 'vant'
Vue.use(Search)
Vue.use(Image)
......@@ -37,3 +38,4 @@ Vue.use(SubmitBar)
Vue.use(ActionSheet)
Vue.use(Panel)
Vue.use(List)
Vue.use(CouponCell).use(CouponList);
\ No newline at end of file
<template>
<div class="scroll-list-wrap">
<!-- 优惠券列表 -->
<cube-popup v-model="showList" position="bottom" class="popup-container">
<van-coupon-list
:coupons="coupons"
:chosen-coupon="chosenCoupon"
:disabled-coupons="disabledCoupons"
:show-exchange-bar="false"
@change="onChange"
@exchange="onExchange"
/>
</cube-popup>
</div>
</template>
<script>
const d = [
{
id: 1,
condition: 150,
amount: 15,
available_day: 1,
is_along: 1,
start_at: "",
end_at: "",
shop_name: "",
shop_id: "",
received_at: "2019-5-10",
consumed_at: "",
expired_at: "2019-5-16",
coupon_stock_id: ""
},
{
id: 2,
condition: 150,
amount: 2.56,
available_day: 1,
is_along: 1,
start_at: "",
end_at: "",
shop_name: "",
shop_id: "",
received_at: "2019-5-10",
consumed_at: "",
expired_at: "2019-8-10",
coupon_stock_id: ""
}
];
import { mapState } from "vuex";
import { getCoupons } from "../../common/serve";
export default {
data() {
return {
showList: true,
pagination: {
// 分页
pageNumber: 1,
perPage: 20
},
chosenCoupon: -1,
coupons: [],
disabledCoupons: []
};
},
created() {
this.initData();
},
computed: {
...mapState(["coupon"]) // 正使用的优惠券信息
},
methods: {
async initData() {
let res = await getCoupons(
this.pagination.pageNumber,
this.pagination.perPage
);
res.data.items = d;
if (res.data.items.length) {
let couponsList = res.data.items.map(item => {
let condition = "";
if (item.condition == 0) {
condition = "无使用门槛";
} else {
condition = `满${item.condition}元减${item.amount}元`;
}
return {
id: item.id,
condition: condition,
startAt: new Date(item.received_at).getTime() / 1000,
endAt: new Date(item.expired_at).getTime() / 1000,
valueDesc: item.amount,
unitDesc: "元",
isExpired:
new Date().getTime() > new Date(item.expired_at).getTime() ? 1 : 0 // 是否已过期
};
});
this.coupons = couponsList.filter(item => item.isExpired == 0);
this.disabledCoupons = couponsList.filter(item => item.isExpired == 1);
}
// 获取vuex记录的 当前使用的优惠券信息
this.chosenCoupon = this.coupon.index;
},
// 是否使用优惠券 信息存入Vuex
onChange(index) {
this.chosenCoupon = index;
const coupon = this.coupons.map((item, i) => {
if (i == index && index != -1) {
// 使用优惠券
return {
id: item.id,
price: item.valueDesc,
index: index
};
} else {
// 不使用优惠券
return {
id: -1,
price: 0,
index: -1
};
}
});
this.$store.commit("SAVE_COUPON", coupon[0]);
this.$router.go(-1);
},
onExchange(code) {
// this.coupons.push(coupon);
}
}
};
</script>
<style lang="stylus">
.van-popup--top {
height: 100%;
}
.popup-container .cube-popup-content {
bottom: 0;
}
</style>
......@@ -74,7 +74,7 @@
import CubePage from "../../components/cube-page.vue";
import footGuide from "../../components/footer";
import shopList from "../../components/shop-list";
import { getNearbyShop, getReceivingAddress } from "../../common/serve";
import { getNearbyShop, getReceivingAddress,getUser } from "../../common/serve";
import { mapGeolocation, MAP } from "../../common/utils/mUtils";
import { mapState } from "vuex";
var map = {};
......@@ -177,7 +177,7 @@ export default {
...mapState(["location","choosed_address"]),
// 当前使用的定位
curLocation(){
console.log(this.choosed_address)
console.log(this.location)
return this.choosed_address.lat?this.choosed_address:(this.location.lat?this.location:'定位中')
},
},
......@@ -193,10 +193,14 @@ export default {
this.curLocation.lng
); // 获取附近的商家
let p2 = getReceivingAddress(); // 获取默认的收货地址
Promise.all([p1,p2])
let p3 = getUser();
Promise.all([p1,p2,p3])
.then(result => {
let addressData = result[1].data;
let userInfoData = result[2].data;
this.$store.commit("RECORD_USERINFO",userInfoData.user_info);
this.loading = false;
})
......
......@@ -5,17 +5,17 @@
<cube-form-item :field="fields[0]"></cube-form-item>
<div class="form-group">
<cube-form-item :field="fields[1]"></cube-form-item>
<cube-button
:primary="true"
<van-button
type="primary" size="mini"
:disabled="disabled"
inline
class="field__button"
@click="onGetCode"
>{{disabled?timer.second+'s':'获取验证码'}}</cube-button>
>{{disabled?timer.second+'s':'获取验证码'}}</van-button>
</div>
</cube-form-group>
<cube-form-group class>
<cube-button :primary="true" @click="submitHandler">登录</cube-button>
<van-button type="primary" size="large" @click="submitHandler">登录</van-button>
</cube-form-group>
</cube-form>
</div>
......@@ -134,7 +134,6 @@ export default {
</script>
<style lang="stylus" scoped>
@import '~common/stylus/variable';
.form-group {
position: relative;
......@@ -149,6 +148,7 @@ export default {
top: 50%;
right: 5%;
transform: translate(0, -50%);
padding: 0 6px;
}
.cube-form-group:nth-of-type(2) {
......
This diff is collapsed.
......@@ -17,7 +17,7 @@
@pulling-down="onPullingDown"
@pulling-up="onPullingUp"
>
<order-card :data="orderList" @select="orderDetail" @show="linkShop" class="content"></order-card>
<order-card :data="orderList" @select="orderDetail" @show="linkShop" @more="anotherOrder " class="content"></order-card>
</cube-scroll>
<van-row
......@@ -51,7 +51,7 @@ export default {
};
},
computed: {
...mapState(["location","choosed_address"]),
...mapState(["location","choosed_address","cartList"]),
// 当前使用的定位
curLocation(){
return this.choosed_address.lat?this.choosed_address:(this.location.lat?this.location:'定位中')
......@@ -147,6 +147,10 @@ export default {
linkShop(shopId) {
this.$router.push({ name: "shop", params: { id: shopId },query:{geohash:this.curLocation.lat+','+this.curLocation.lng }});
},
// 再来一单
anotherOrder(shopId,order_no){
this.$router.push({ name: "shop", params: { id: shopId },query:{geohash:this.curLocation.lat+','+this.curLocation.lng,order_no: order_no} });
},
},
watch: {
"$route.query": function(newVal, oldVal) {
......
......@@ -18,13 +18,14 @@
<van-cell title="送达时间" value="尽快配送"></van-cell>
<van-cell title="收货地址">
<span>
{{this.choosed_address.address_detail +
this.choosed_address.address_suffix.split(",")[1]}}
<p>{{choosed_address.name}}{{choosed_address.gender==0?'':(choosed_address.gender==1?'(男士)':'(女士)')}} {{this.choosed_address.tel}}</p>
{{orderAddress.address_detail +
orderAddress.address_suffix}}
<!-- .split(",")[1] -->
<p>{{orderAddress.user_name}}{{orderAddress.gender==0?'':(orderAddress.gender==1?'(男士)':'(女士)')}} {{this.orderAddress.phone}}</p>
</span>
</van-cell>
<van-cell title="配送方式" value></van-cell>
<van-cell title="配送骑手" value="名字"></van-cell>
<!-- <van-cell title="配送骑手" value="名字"></van-cell> -->
</div>
</van-panel>
......@@ -52,9 +53,6 @@ export default {
order_status: "",
goods: []
},
btnLoading: false,
showActionSheet: false,
activeSteps: 0, // 步骤条
orderAddress: {}
};
},
......@@ -62,7 +60,7 @@ export default {
confirmFoodsList
},
computed: {
...mapState(["shopInfo", "choosed_address"])
...mapState(["shopInfo"])
},
created() {
this.getOrderInfo();
......@@ -76,6 +74,7 @@ export default {
if (res.code == 0) {
let data = res.data;
this.order = res.data;
this.orderAddress = res.data.user_address
} else {
// 显示错误页面
}
......@@ -89,13 +88,19 @@ export default {
<style lang="stylus" scoped>
@import '~common/stylus/variable.styl';
.cube-scroll-list-wrapper{
background :transparent;}
.page-title {
padding: 20px 10px;
}
.van-panel__header span{
font-weight:600;
font-size: $fontsize-large;
}
.van-cell__value {
font-size: $fontsize-medium;
color: #6a6a6a;
}
</style>
<template>
<div>
<van-cell-group title="账号绑定" class="margin-bt-space">
<van-cell icon="phone-circle" is-link title="手机号" value="18871334707" to="bindPhone" />
</van-cell-group>
<section class="section">
<van-button type="default" text="退出登录" block @click="logoutEvent"></van-button>
</section>
</div>
</template>
<script>
import { logout } from "../../common/serve";
export default {
data() {
return {};
},
methods: {
logoutEvent() {
this.$createDialog({
type: "confirm",
title: "确认要退出当前账号吗?",
onConfirm: (e, promptValue) => {
this.onLogout();
}
}).show();
},
async onLogout() {
let res = await logout();
if (res.code == 0) {
this.$store.commit("OUT_LOGIN");
this.$router.go(-1);
}
}
}
};
</script>
<style lang="stylus" scoped>
.van-button--normal {
font-weight: 600;
}
.van-icon.van-cell__left-icon {
font-size: $fontsize-large-xxx;
}
</style>
<template>
<div>
<cube-form :model="model" @validate="validateHandler" skipValidate>
<cube-form-group>
<cube-form-item :field="fields[0]"></cube-form-item>
<div class="form-group">
<cube-form-item :field="fields[1]"></cube-form-item>
<van-button
type="primary" size="mini"
:disabled="disabled"
inline
class="field__button"
@click="onGetCode"
>{{disabled?timer.second+'s':'获取验证码'}}</van-button>
</div>
</cube-form-group>
<cube-form-group class>
<van-button type="primary" size="large" @click="submitHandler">登录</van-button>
</cube-form-group>
</cube-form>
</div>
</template>
<script>
import { getLoginedCode,bindPhone } from "../../common/serve.js";
export default {
data() {
return {
validity: {},
valid: undefined,
disabled: false,
timer: {
//定时器信息
interValObj: null,
second: 60
},
model: {
inputValue: "",
codeValue: ""
},
fields: [
{
type: "input",
modelKey: "inputValue",
label: "手机号",
props: {
placeholder: "请输入手机号"
},
rules: {
required: true
}
},
{
type: "input",
modelKey: "codeValue",
label: "短信验证码",
props: {
placeholder: "请输入短信验证码"
},
rules: {
required: true
}
}
]
};
},
methods: {
async onGetCode() {
this.disabled = true;
let res = await getLoginedCode(this.model.inputValue);
if (res.code == 0) {
this.timeDown();
this.$createToast({
txt: "验证码获取成功",
type: "txt"
}).show();
} else {
this.$createToast({
txt: res.message,
type: "error"
}).show();
}
this.disabled = false;
},
async toBind() {
let res = await bindPhone(this.model.inputValue, this.model.codeValue);
if (res.code == 0) {
localStorage.setItem("isLogin", true);
this.$createToast({
txt: "绑定成功",
time: 1000,
onTimeout: () => {
this.$router.go(-1);
}
}).show();
} else {
this.$createToast({
txt: res.message,
type: "error"
}).show();
}
this.actBtnLoading = false;
},
submitHandler(e) {
e.stopPropagation()
this.toBind();
},
validateHandler(result) {
this.validity = result.validity;
this.valid = result.valid;
},
// 获取验证码倒计时
timeDown() {
const timerObj = this.timer.interValObj,
_timer = this.timer;
// 防止多次点击,生成多个定时器
if (timerObj) {
clearInterval(timerObj);
return;
}
_timer.interValObj = setInterval(() => {
if (_timer.second > 1) {
_timer.second--;
this.disabled = true;
} else {
clearInterval(timerObj);
this.disabled = false;
}
}, 1000);
}
}
};
</script>
<style lang="stylus" scoped>
.form-group {
position: relative;
.cube-form-item {
width: 67%;
}
}
.field__button {
position: absolute;
top: 50%;
right: 5%;
transform: translate(0, -50%);
padding: 0 6px;
}
.cube-form-group:nth-of-type(2) {
margin-top: $margin-top-20;
}
</style>
\ No newline at end of file
<template>
<div>
<van-cell-group title="基本信息">
<van-cell is-link title="头像" class="flex-center">
<van-image
width="40"
height="40"
round
:src="userInfo.avatar"
/>
</van-cell>
<van-cell
is-link
title="昵称"
:value="userInfo.name?userInfo.name:''"
@click="onShowNameDialog"
/>
<van-cell title="手机号" :value="userInfo.phone" />
</van-cell-group>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from "vuex";
export default {
data() {
return {
};
},
computed: {
...mapState(["userInfo"]),
nameInput() {
//个人信息弹框中 input value
return this.userInfo.name;
}
},
methods: {
...mapMutations(["RECORD_USERINFO"]),
onShowNameDialog() {
// 显示姓名弹框
this.$createDialog({
type: 'prompt',
title: '修改昵称',
prompt: {
value: '',
placeholder: '请输入昵称'
},
onConfirm: (e, promptValue) => {
this.onUpdateName(promptValue);
}
}).show()
},
onUpdateName(value) {
// 修改姓名
Object.assign(this.userInfo, { name: value });
this.$store.commit("RECORD_USERINFO",this.userInfo);
},
onRouterLink(routerName){
this.$router.push({name:routerName})
}
}
};
</script>
<style lang="stylus" scoped>
.van-cell{
align-items: center;
}
.van-cell__value--alone {
text-align: center;
}
.van-cell-group {
margin-top: 10px;
.flex-center .van-cell__value {
height: 40px;
}
}
</style>
......@@ -32,12 +32,10 @@
<div @click="addFirst" class="buy" v-show="!foodNum" style="position: absolute;">加入购物车</div>
</transition>
</div>
<!-- <split v-show="food.info"></split> -->
<div class="info" v-show="food.info">
<h1 class="title">商品信息</h1>
<p class="text">{{food.info}}</p>
</div>
<!-- <split></split> -->
<div class="rating">
<h1 class="title">商品评价</h1>
<rating-select
......@@ -78,10 +76,7 @@
</template>
<script type="text/ecmascript-6">
// import moment from "moment";
// import CartControl from "components/cube-cart-control";
import RatingSelect from "./rating/rating-select";
// import Split from "components/split/split";
import ratingMixin from "common/mixins/rating";
import popupMixin from "common/mixins/popup";
import { mapState } from "vuex";
......@@ -317,8 +312,7 @@ export default {
.title {
line-height: 14px;
margin-left: 18px;
font-size: $fontsize-medium;
color: $color-dark-grey;
scw($fontsize-medium,$color-dark-grey,600)
}
.rating-wrapper {
......
<template>
<div class="container section">
<rating-select
@select="onSelect"
@toggle="onToggle"
:desc="desc"
:selectType="selectType"
:ratings="ratings"
></rating-select>
<div class="rating-wrapper">
<div class="empty_tips" v-show="!ratings || !ratings.length">暂无评价</div>
</div>
</div>
</template>
<script>
import RatingSelect from "./rating-select";
import ratingMixin from "common/mixins/rating";
export default {
data() {
return {
desc: {
all: "全部",
positive: "推荐",
negative: "吐槽"
},
selectType: 0
};
},
mixins: [ratingMixin],
computed: {
ratings() {
return [];
}
},
components: {
RatingSelect
},
methods: {
onSelect(type) {
this.selectType = type;
}
}
};
</script>
\ No newline at end of file
<template>
<div class="rating-select">
<div class="rating-type border-bottom-1px">
<span @click="select(2)" class="block positive" :class="{'active':selectType===2}">{{desc.all}}<span
class="count">{{ratings.length}}</span></span>
<span @click="select(0)" class="block positive" :class="{'active':selectType===0}">{{desc.positive}}<span
class="count">{{positives.length}}</span></span>
<span @click="select(1)" class="block negative" :class="{'active':selectType===1}">{{desc.negative}}<span
class="count">{{negatives.length}}</span></span>
<div class="rating-type">
<van-button size="small" class="btn" :class="{'active':selectType===2}" @click="select(2)">
{{desc.all}}
<span class="count">{{ratings.length}}</span>
</van-button>
<van-button size="small" class="btn" :class="{'active':selectType===0}" @click="select(0)">
{{desc.positive}}
<span class="count">{{positives.length}}</span>
</van-button>
<van-button
size="small"
class="btn negatives"
:class="{'active':selectType===1}"
@click="select(1)"
>
{{desc.negative}}
<span class="count">{{negatives.length}}</span>
</van-button>
</div>
<div @click="toggleContent" class="switch" :class="{'on':onlyContent}">
<span class="icon-check_circle"></span>
<span class="text">只看有内容的评价</span>
<cube-checkbox v-model="checked" class="text">只看有内容的评价</cube-checkbox>
</div>
</div>
</template>
<script>
const POSITIVE = 0
const NEGATIVE = 1
const ALL = 2
const POSITIVE = 0;
const NEGATIVE = 1;
const ALL = 2;
const EVENT_TOGGLE = 'toggle'
const EVENT_SELECT = 'select'
const EVENT_TOGGLE = "toggle";
const EVENT_SELECT = "select";
export default {
props: {
ratings: {
type: Array,
default() {
return []
}
},
selectType: {
type: Number,
default: ALL
},
onlyContent: {
type: Boolean,
default: false
},
desc: {
type: Object,
default() {
return {
all: '全部',
positive: '满意',
negative: '不满意'
}
}
export default {
data() {
return {
checked: true
};
},
props: {
ratings: {
type: Array,
default() {
return [];
}
},
computed: {
positives() {
return this.ratings.filter((rating) => {
return rating.rateType === POSITIVE
})
},
negatives() {
return this.ratings.filter((rating) => {
return rating.rateType === NEGATIVE
})
}
selectType: {
type: Number,
default: ALL
},
onlyContent: {
type: Boolean,
default: false
},
methods: {
select(type) {
this.$emit(EVENT_SELECT, type)
},
toggleContent() {
this.$emit(EVENT_TOGGLE)
desc: {
type: Object,
default() {
return {
all: "全部",
positive: "满意",
negative: "不满意"
};
}
}
},
computed: {
positives() {
return this.ratings.filter(rating => {
return rating.rateType === POSITIVE;
});
},
negatives() {
return this.ratings.filter(rating => {
return rating.rateType === NEGATIVE;
});
}
},
methods: {
select(type) {
this.$emit(EVENT_SELECT, type);
},
toggleContent() {
this.$emit(EVENT_TOGGLE);
}
}
};
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "~common/stylus/variable"
.rating-select
.rating-type
padding: 18px 0
margin: 0 18px
.block
display: inline-block
padding: 8px 12px
margin-right: 8px
line-height: 16px
border-radius: 1px
font-size: $fontsize-small
color: $color-grey
&.active
color: $color-white
.count
margin-left: 2px
&.positive
background: $color-light-blue
&.active
background: $color-blue
&.negative
background: $color-light-grey-s
&.active
background: $color-grey
.switch
display: flex
align-items: center
padding: 12px 18px
line-height: 24px
border-bottom: 1px solid $color-row-line
color: $color-light-grey
&.on
.icon-check_circle
color: $color-green
.icon-check_circle
margin-right: 4px
font-size: $fontsize-large-xxx
.text
font-size: $fontsize-small
.van-button.btn {
color: #999;
background: #b3ddfd66;
margin: 0 18px;
&.negatives {
background: #eee;
}
&.active {
background: $color-blue;
color: $color-white;
}
}
.rating-select {
padding: 10px 0;
.switch {
.cube-checkbox_checked .cube-checkbox-ui i {
color: $color-green;
}
.text {
font-size: $fontsize-small;
}
}
}
</style>
<template>
<div class="container" style="height:620px;">
<cube-scroll-nav
<div class="container">
<scroll-nav
:side="true"
:data="menuList"
:current="current"
:disable="disable"
:categoryNum="categoryNum"
@scroll0="scrollTop"
@change="changeHandler"
@sticky-change="stickyChangeHandler"
>
......@@ -19,7 +22,7 @@
<div slot="thumb" @click="selectFood(food,item.category_id)">
<van-image width="100%" height="90" fit="contain" :src="$globalUrlFile+food.icon">
<template v-slot:error>
<!-- <img width="100%" src="../../assets/images/icons/list/null.png" alt /> -->
<img width="100%" src="../../../assets/images/null.png" alt />
</template>
</van-image>
</div>
......@@ -47,7 +50,7 @@
</section>
</div>
</cube-scroll-nav-panel>
</cube-scroll-nav>
</scroll-nav>
<!-- 底部功能条 -->
<!-- <section class="shop-cart-wrapper">
......@@ -57,13 +60,14 @@
:delivery-price="seller.deliveryPrice"
:min-price="seller.minPrice"
></cube-shop-cart>
</section> -->
</section>-->
</div>
</template>
<script type="text/ecmascript-6">
import { allCategoryAndGoods } from "../../../common/serve";
import foodDetail from "../children/food-detail";
import { allCategoryAndGoods, getOrderDetail } from "../../../common/serve";
import scrollNav from "../../../components/scroll/scroll-nav";
import cubeShopCart from "../../../components/shopCart/shop-cart";
import { mapState } from "vuex";
......@@ -71,7 +75,6 @@ import { mapState } from "vuex";
export default {
data() {
return {
// data: goods,
current: 0, //当前导航 active 项的 key 值
shopId: this.$route.params.id,
......@@ -83,8 +86,11 @@ export default {
receiveInCart: false, //购物车组件下落的圆点是否到达目标位置
menuList: [], //食品列表
cartFoodList: [], //购物车商品列表
categoryNum: [],
selectedFood: {}, // 待查看详情的商品
selectedFood: {} // 待查看详情的商品
order_no: "" // 再来一单时展示曾购买的商品
};
},
computed: {
......@@ -122,13 +128,21 @@ export default {
return { ...this.cartList[this.shopId] };
}
},
components: { foodDetail, cubeShopCart },
props: {
disable: {
default: true
}
},
components: { cubeShopCart, scrollNav },
created() {
this.order_no = this.$route.query.order_no;
this.initData();
},
mounted() {
this._showShopCartSticky();
},
methods: {
async initData() {
let res = await allCategoryAndGoods(this.shopId);
......@@ -137,6 +151,36 @@ export default {
this.current = res.data[0].category_name;
}
this.initCategoryNum();
// 再来一单:将当前订单内是内商品数据 按照 规定格式{shopid:{cateid:{foodid:{...}}} } 存入 vuex
if (this.order_no) {
let msg = await getOrderDetail(this.order_no);
if (msg.code == 0) {
let cart = this.cartList,
data = msg.data.goods;
if (cart && cart[this.shopId]) {
this.menuList.forEach((item, index) => {
item.goods_list.forEach(good => {
data.forEach(food => {
if (food.goods_id == good.id) {
let shop = (cart[this.shopId] = {});
let category = (shop[item.category_id] =
shop[item.category_id] || {});
category[food.goods_id] = {
goods_category_id: item.category_id,
id: food.goods_id,
name: food.goods_name,
num: food.goods_quantity,
price: food.goods_price
};
}
});
});
});
}
console.log(cart);
}
}
},
selectFood(food, categoryId) {
this.selectedFood = food;
......@@ -156,7 +200,7 @@ export default {
this.shopCartStickyComp.drop(target);
},
leave: () => {
this._hideShopCartSticky();
// this._hideShopCartSticky();
}
}
});
......@@ -185,6 +229,11 @@ export default {
stickyChangeHandler(current) {
console.log("sticky-change", current);
},
scrollTop() {
// 内层滚动到顶部时,禁止滚动
this.$emit("scroll0");
},
//显示下落圆球
showMoveDotFun(target) {
this.shopCartStickyComp.drop(target);
......@@ -210,6 +259,7 @@ export default {
if (foodItem.num > 0) {
this.cartFoodList[cartFoodNum] = { ...foodItem };
}
cartFoodNum++;
});
newArr[index] = num;
......@@ -219,7 +269,6 @@ export default {
});
this.totalPrice = this.totalPrice.toFixed(2);
this.categoryNum = [...newArr];
console.log(this.cartFoodList);
}
},
watch: {
......@@ -241,61 +290,41 @@ export default {
this.showCartList = false;
}
}
//商品、评论切换状态
/* changeShowType: function(value) {
if (value === "rating") {
this.$nextTick(() => {
this.ratingScroll = new BScroll("#ratingContainer", {
probeType: 3,
deceleration: 0.003,
bounce: false,
swipeTime: 2000,
click: true
});
this.ratingScroll.on("scroll", pos => {
if (
Math.abs(Math.round(pos.y)) >=
Math.abs(Math.round(this.ratingScroll.maxScrollY))
) {
this.loaderMoreRating();
this.ratingScroll.refresh();
}
});
});
}
} */
}
};
</script>
<style lang="stylus">
<style lang="stylus" >
@import '~common/stylus/variable.styl';
@import '~common/stylus/mixin.styl';
.view-wrapper {
background: url('https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3340225592,2502432116&fm=26&gp=0.jpg') no-repeat; // ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3340225592,2502432116&fm=26&gp=0.jpg) no-repeat;
background-size: cover;
}
.cube-scroll-list-wrapper {
background: #fff;
}
.container {
height: 100%;
.cube-scroll-nav-bar {
width: 80px;
background-color: transparent;
background-color: #f8f8f8;
.cube-scroll-wrapper {
width: 100%;
.cube-scroll-nav-bar-item_active {
background-color: #fff;
.cube-scroll-nav-bar-item {
position: relative;
&_active {
background-color: #fff;
}
}
}
span {
font-size: $fontsize-small;
.van-tag {
padding: 2px 4px;
right: 0;
top: 10%;
}
}
}
......@@ -305,6 +334,10 @@ export default {
background-color: #fff;
scw($fontsize-small, #6e6e6e, 600);
}
.cube-scroll-nav-bar-item {
padding: 20px 4px;
}
}
.van-card {
......@@ -361,100 +394,4 @@ export default {
width: 100%;
height: 48px;
}
.cart_food_list {
position: fixed;
width: 100%;
padding-bottom: 2rem;
z-index: 12;
bottom: 0;
left: 0;
background-color: #fff;
header {
// @include fj;
align-items: center;
padding: 0.3rem 0.6rem;
background-color: #eceff1;
svg {
// @include wh(.6rem,.6rem);
vertical-align: middle;
}
h4 {
scw(12px, #666);
}
.clear_cart {
scw(12px, #666);
}
}
.cart_food_details {
background-color: #fff;
max-height: 20rem;
overflow-y: auto;
.cart_food_li {
// @include fj;
padding: 0.6rem 0.5rem;
.cart_list_num {
width: 55%;
p:nth-of-type(1) {
sc(10px, #666);
font-weight: bold;
}
p:nth-of-type(2) {
sc(10px, #666);
}
}
.cart_list_price {
font-size: 0;
span:nth-of-type(1) {
sc(10px, #f60);
font-family: Helvetica Neue, Tahoma;
}
span:nth-of-type(2) {
sc(10px, #f60);
font-family: Helvetica Neue, Tahoma;
font-weight: bold;
}
}
.cart_list_control {
display: flex;
align-items: center;
span {
display: flex;
align-items: center;
justify-content: center;
}
svg {
wh(20px, 20px);
fill: #3190e8;
}
.specs_reduce_icon {
fill: #999;
}
.cart_num {
scw(12px, #666);
min-width: 1rem;
text-align: center;
font-family: Helvetica Neue, Tahoma;
}
}
}
}
}
</style>
<template>
<div class="scroll-list-wrap">
<div class="scroll-list-wrap view-wrapper">
<cube-sticky :pos="scrollY">
<cube-scroll ref="scroll" :scroll-events="scrollEvents" @scroll="scrollHandler">
<section ref="header" class="page-header">
<cube-scroll
ref="scroll"
:scroll-events="scrollEvents"
:options="options"
@scroll="scrollHandler"
>
<section ref="header" class="page-hd">
<van-image width="76" height="76" :src="$globalUrlFile+shopInfo.icon"></van-image>
<div class="prepend-content">
<h1>{{shopInfo.name}}</h1>
......@@ -10,24 +15,31 @@
<van-tag plain type="danger">满减</van-tag>
</div>
</section>
<div class="page-bd">
<cube-sticky-ele>
<cube-tab-bar
ref="tabBar"
v-model="currentTab"
show-slider
inline
@change="changeHandler"
class="text-medium"
>
<cube-tab v-for="item in tabs" :label="item.name" :key="item.name">{{item.name}}</cube-tab>
</cube-tab-bar>
</cube-sticky-ele>
<cube-sticky-ele>
<cube-tab-bar
v-model="currentTab"
show-slider
inline
@change="changeHandler"
class="text-medium"
>
<cube-tab v-for="item in tabs" :label="item.name" :key="item.name">{{item.name}}</cube-tab>
</cube-tab-bar>
</cube-sticky-ele>
<cube-tab-panels v-model="currentTab">
<cube-tab-panel v-for="item in tabs" :label="item.name" :key="item.name">
<component :is="item.is"></component>
</cube-tab-panel>
</cube-tab-panels>
<cube-tab-panels v-model="currentTab" ref="panel">
<cube-tab-panel v-for="item in tabs" :label="item.name" :key="item.name">
<component
:is="item.is"
:disable="disable"
@scroll0="scrollTop"
:style="{height:contentH}"
></component>
</cube-tab-panel>
</cube-tab-panels>
</div>
</cube-scroll>
</cube-sticky>
</div>
......@@ -37,7 +49,7 @@
<script>
import { allCategoryAndGoods, getShopInfo } from "../../common/serve";
import shopTab from "./children/shop";
import evaluate from "./children/rating/rating-select";
import evaluate from "./children/rating/index";
import shopInfo from "./children/shopInfo";
import cubeShopCart from "../../components/shopCart/shop-cart";
import goodsData from "../../data";
......@@ -53,9 +65,12 @@ export default {
},
data() {
return {
disable: true, // 外层滚动时,内层禁止滚动
disableInner: false,
scrollY: 0,
scrollEvents: ["scroll"],
headerH:0, // 头部高度
headerH: 0, // 头部高度
tabBarH: 0, //tabbar高度
checkTop: false,
data: goods,
......@@ -78,21 +93,44 @@ export default {
computed: {
component() {
return "shopTab";
},
options() {
return { click: true, bounce: false };
},
contentH() {
return document.body.clientHeight - this.tabBarH + "px";
}
},
mounted(){
this.headerH = this.$refs.header.offsetHeight;
mounted() {
this.headerH = this.$refs.header.offsetHeight; // 包含tabbar 在内的头部高度
this.tabBarH = this.$refs.tabBar.offsetHeight; // tabbar 高度
},
watch: {
disable(newVal) { //控制外层的滚动
if (newVal) {
this.enableFn();
} else {
this.disableFn();
}
}
},
methods: {
scrollHandler({ y }) {
this.scrollY = -y;
if (this.scrollY >= this.headerH) {
this.disable = false;
} else {
this.disable = true;
}
},
changeHandler(label) {
this.currentTab = label;
console.log("changed to:", label);
},
scrollTop() {
console.log(132)
this.disable = true;
},
async initData() {
let p1 = allCategoryAndGoods(this.shopId); // 获取分类和商品数据
let p2 = getShopInfo(this.shopId); // 获取店铺信息
......@@ -111,16 +149,36 @@ export default {
}
})
.catch(error => {});
},
enableFn() {
this.$refs.scroll.enable();
},
disableFn() {
this.$refs.scroll.disable();
}
}
};
</script>
<style lang="stylus">
.page-header {
.view-wrapper {
background: url('https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3340225592,2502432116&fm=26&gp=0.jpg') no-repeat; // ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3340225592,2502432116&fm=26&gp=0.jpg) no-repeat;
background-size: cover;
}
.page-hd {
position: relative;
padding-top: 100px;
text-align: center;
font-size: 20px;
.van-image {
position: absolute;
top: 10%;
left: 50%;
transform: translateX(-50%);
}
.prepend-content {
background-color: #fff;
padding: 20px 0 10px;
......@@ -131,10 +189,19 @@ export default {
}
}
.page-bd {
background-color: #fff;
}
.cube-tab-bar {
background-color: #fff;
.cube-tab-bar-slider {
.cube-tab {
padding: 10px;
}
}
.cube-tab-panel {
background-color: #f8f8f8;
}
</style>
\ No newline at end of file
Markdown is supported
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