修正项目
This commit is contained in:
228
xlcs-user/pages/cart/cart.vue
Normal file
228
xlcs-user/pages/cart/cart.vue
Normal file
@@ -0,0 +1,228 @@
|
||||
<template>
|
||||
<view class="gg">
|
||||
<u-navbar :border-bottom="false" :is-back="false">
|
||||
<view class="u-flex u-m-l-20 u-m-r-20">
|
||||
<view class="u-font-xl u-m-r-20">购物车</view>
|
||||
<view class="u-font-xs u-light-color u-p-t-10">共{{ getSelectedCount }}件商品</view>
|
||||
</view>
|
||||
</u-navbar>
|
||||
|
||||
<view class="gg-content">
|
||||
<scroll-view v-if="getCartInfoList" class="gg-cart-sv-container" scroll-y="true">
|
||||
<u-checkbox-group>
|
||||
|
||||
<view v-for="(cartInfoListItem, index) in getCartInfoList" :key="index">
|
||||
<u-card :border="false" :padding="10" :show-head="showMultiCheckbox(index)">
|
||||
<view slot="head" class="u-m-10">
|
||||
<u-checkbox
|
||||
:name="getMultiCheckedIds(index)"
|
||||
:value="getMultiCheckCart(index)"
|
||||
active-color="red"
|
||||
shape="circle"
|
||||
@change="changeMultiChecked"
|
||||
></u-checkbox>
|
||||
<text>{{ cartInfoListItem.activityRule.ruleDesc }}</text>
|
||||
</view>
|
||||
<view slot="body">
|
||||
<view v-for="(cartInfoItem, idx) in cartInfoListItem.cartInfoList" :key="idx">
|
||||
<!-- 动态class绑定是为了确保最后一条底部线条不显示 -->
|
||||
<view :class="{ 'u-border-bottom': idx !== cartInfoListItem.cartInfoList.length - 1 }"
|
||||
class="u-body-item u-flex u-col-between u-p-10">
|
||||
<u-checkbox
|
||||
v-model="cartInfoItem.isChecked"
|
||||
:name="cartInfoItem.skuId"
|
||||
active-color="red"
|
||||
shape="circle"
|
||||
@change="changeChecked"
|
||||
></u-checkbox>
|
||||
<ListImgItem
|
||||
:lazyLoad="false"
|
||||
:showBottom="cartInfoItem.skuType === 0 && cartInfoItem.isNewPerson === 1"
|
||||
:showLeft="cartInfoItem.skuType === 1"
|
||||
:showRight="false"
|
||||
:src="cartInfoItem.imgUrl"
|
||||
height="200rpx"
|
||||
width="200rpx"
|
||||
></ListImgItem>
|
||||
<view class="u-p-b-20 u-m-l-20" style="flex:1">
|
||||
<view class="u-font-lg">{{ cartInfoItem.skuName }}</view>
|
||||
<view class="u-flex u-row-between">
|
||||
<view class="u-type-error">
|
||||
<text>¥</text>
|
||||
<text>{{ cartInfoItem.cartPrice }}</text>
|
||||
</view>
|
||||
<AddToCart :shopDetail="cartInfoItem" :skuId="cartInfoItem.skuId"></AddToCart>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-card>
|
||||
</view>
|
||||
</u-checkbox-group>
|
||||
</scroll-view>
|
||||
|
||||
<u-empty v-else :margin-top="300" mode="car">
|
||||
<u-button slot="bottom" type="error" @click="gotoCategory">点击购买商品</u-button>
|
||||
</u-empty>
|
||||
|
||||
<view class="gg-navigation">
|
||||
<view class="navigation">
|
||||
<view class="left">
|
||||
<view class="item u-m-t-20">
|
||||
<u-checkbox :value="isAllSelected" active-color="red" shape="circle"
|
||||
@change="changeAllSelected"></u-checkbox>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="u-font-sm u-line-1">
|
||||
<view class="u-type-error">现价:¥{{ getCartPriceInfo.totalAmount }}</view>
|
||||
<view class="u-font-xs u-type-info">
|
||||
优惠券优惠:¥{{ getCartPriceInfo.couponReduceAmount }}
|
||||
<text class="u-font-xs u-m-l-20 u-type-info">原价:</text>
|
||||
<text class="u-font-xs u-type-info">¥{{ getCartPriceInfo.originalTotalAmount }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="item car u-type-info" v-if="getCartCouponInfoList.length > 0" @click="showCouponInfoList = true">
|
||||
<u-icon name="gift-fill" :size="40" :color="$u.color['contentColor']"></u-icon>
|
||||
<view class="text u-line-1">优惠券</view>
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="right">
|
||||
<view class="buy btn u-line-1" @click="gotoConfirmOrder">立即购买</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<CouponInfoList :couponInfoList="getCartCouponInfoList"
|
||||
:showCouponInfoList.sync="showCouponInfoList"></CouponInfoList>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapActions, mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
showCouponInfoList: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('cartModule', [
|
||||
'getCartInfoList',
|
||||
'showMultiCheckbox',
|
||||
'getMultiCheckCart',
|
||||
'getMultiCheckedIds',
|
||||
'isAllSelected',
|
||||
'getCartPriceInfo',
|
||||
'getSelectedCount',
|
||||
'getCartCouponInfoList'
|
||||
])
|
||||
},
|
||||
methods: {
|
||||
...mapActions('cartModule', ['getActivityCartListAction', 'changeCheckCartAction', 'changeMultiCheckedCartAction', 'changeAllCheckCartAction']),
|
||||
...mapActions('cartModule', ['getCartListAction']),
|
||||
// 到分类页购买商品
|
||||
gotoCategory() {
|
||||
uni.switchTab({
|
||||
url: '/pages/categories/categories'
|
||||
});
|
||||
},
|
||||
// 修改单个商品选中状态
|
||||
changeChecked(detail) {
|
||||
let isChecked = 1;
|
||||
const {name: skuId, value} = detail;
|
||||
if (!value) isChecked = 0;
|
||||
this.changeCheckCartAction({skuId, isChecked});
|
||||
},
|
||||
// 修改多个商品的选中状态
|
||||
changeMultiChecked(detail) {
|
||||
let skuIdList = [];
|
||||
skuIdList = detail.name.split(',');
|
||||
const isChecked = detail.value === true ? 1 : 0;
|
||||
this.changeMultiCheckedCartAction({skuIdList, isChecked});
|
||||
},
|
||||
// 全部选中/返选
|
||||
changeAllSelected(detail) {
|
||||
this.changeAllCheckCartAction({isChecked: detail.value === true ? 1 : 0});
|
||||
},
|
||||
// 跳转至确认订单
|
||||
gotoConfirmOrder() {
|
||||
this.$u.route('/pagesOrder/confirmOrder/confirmOrder')
|
||||
}
|
||||
},
|
||||
// 思考:为什么需要将请求放置于onShow钩子函数中,
|
||||
// 主要考虑tabs切换后需要进行实时数据的获取
|
||||
onShow() {
|
||||
this.getActivityCartListAction({showLoading: true});
|
||||
},
|
||||
mounted() {
|
||||
// 需要获取购物车数据列表,将最新获取的数据渲染到页面
|
||||
this.getCartListAction();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.gg {
|
||||
height: 100%;
|
||||
background-color: $u-bg-color;
|
||||
|
||||
// scrollView的固定高度设置
|
||||
// 底部导航与顶部自定义导航高度需要减去
|
||||
&-cart-sv-container {
|
||||
height: calc(100vh - 90rpx - 136rpx);
|
||||
}
|
||||
|
||||
// 底部导航
|
||||
&-navigation {
|
||||
width: 100%;
|
||||
height: 90rpx;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
|
||||
.navigation {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
border: solid 2rpx #f2f2f2;
|
||||
background-color: #ffffff;
|
||||
padding: 12rpx 0;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
font-size: 20rpx;
|
||||
|
||||
.item {
|
||||
margin: 0 10rpx;
|
||||
|
||||
&.car {
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
font-size: 28rpx;
|
||||
align-items: center;
|
||||
|
||||
.btn {
|
||||
line-height: 66rpx;
|
||||
padding: 0 30rpx;
|
||||
border-radius: 36rpx;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.buy {
|
||||
background-color: #ff7900;
|
||||
margin: 0 30rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
295
xlcs-user/pages/categories/categories.vue
Normal file
295
xlcs-user/pages/categories/categories.vue
Normal file
@@ -0,0 +1,295 @@
|
||||
<template>
|
||||
<view class="gg">
|
||||
<u-navbar :border-bottom="false" :is-back="false">
|
||||
<view class="u-flex u-m-l-20 u-m-r-20 gg-search-navbar">
|
||||
<view class="u-font-xl u-m-r-20">分类</view>
|
||||
<view class="gg-notice-search-bar">
|
||||
<u-icon class="gg-notice-search-bar-left-icon" name="search"></u-icon>
|
||||
<u-notice-bar
|
||||
:border-radius="30"
|
||||
:is-circular="false"
|
||||
:list="list"
|
||||
:more-icon="false"
|
||||
:volume-icon="false"
|
||||
class="gg-notice-search-bar-u-notice-bar"
|
||||
mode="vertical"
|
||||
type="none"
|
||||
></u-notice-bar>
|
||||
</view>
|
||||
</view>
|
||||
</u-navbar>
|
||||
|
||||
<view class="gg-menu-wrap">
|
||||
<scroll-view :scroll-top="scrollTop" class="gg-tab-view menu-scroll-view" scroll-with-animation scroll-y>
|
||||
<view
|
||||
v-for="(item, index) in categories"
|
||||
:key="item.id"
|
||||
:class="[current === index ? 'gg-tab-item-active' : '']"
|
||||
:data-current="index"
|
||||
class="gg-tab-item"
|
||||
@tap.stop="swichCategory(item.id, index)"
|
||||
>
|
||||
<text class="u-line-1">{{ item.name }}</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<scroll-view class="gg-right-box" scroll-y @scrolltolower="loadMore">
|
||||
<view v-for="(item, index) in searchResult.content" :key="item.id" @click="gotoProductItem(item.id)">
|
||||
<view class="u-m-b-10 u-m-l-20 u-m-r-20 u-flex gg-product-item">
|
||||
<ListImgItem
|
||||
:showBottom="item.skuType === 0 && item.isNewPerson === 1"
|
||||
:showLeft="item.skuType === 1"
|
||||
:showRight="false"
|
||||
:src="item.imgUrl"
|
||||
height="200rpx"
|
||||
width="200rpx"
|
||||
>
|
||||
<template #left>秒杀商品</template>
|
||||
</ListImgItem>
|
||||
<view class="gg-product-item-msg u-border-bottom u-p-b-20 u-m-l-20">
|
||||
<view>
|
||||
<view class="u-font-lg">{{ item.title }}</view>
|
||||
<view class="u-type-info u-font-sm">已售{{ item.sale }}/剩余{{ item.stock }}</view>
|
||||
<block v-if="item.ruleList">
|
||||
<view v-for="(rule, ruleIndex) in item.ruleList" :key="ruleIndex" class="u-font-xs u-type-error-dark">
|
||||
{{ rule }}
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="u-flex u-row-between">
|
||||
<view class="u-type-error gg-product-item-msg-price-container">
|
||||
<text>¥</text>
|
||||
<text class="gg-product-item-msg-price-container-value">{{ item.price }}</text>
|
||||
</view>
|
||||
<AddToCart :shopDetail="item"></AddToCart>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<u-gap height="20"></u-gap>
|
||||
</view>
|
||||
|
||||
<!-- 如果列表没有更多数据,则显示分隔线 -->
|
||||
<u-divider v-if="!(searchResult.first && searchResult.empty) && searchResult.last" :height="60"
|
||||
bg-color="transparent">我是有底线的
|
||||
</u-divider>
|
||||
<!-- 如果列表没有数据,则显示空内容 -->
|
||||
<u-empty :show="searchResult.first && searchResult.empty" mode="list"></u-empty>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapState, mapActions} from 'vuex';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
list: ['最见搜索关键字', '暂时未处理搜索页', '可以考虑最见关键字'],
|
||||
current: 0, // 预设当前项的值
|
||||
categoryId: 0, // 当前选中的分类Id
|
||||
scrollTop: 0, //tab标题的滚动条位置
|
||||
menuHeight: 0, // 左边菜单的高度
|
||||
menuItemHeight: 0, // 左边菜单item的高度
|
||||
filter: {
|
||||
page: 1, // 当前页码
|
||||
limit: 5, // 每页记录数
|
||||
keyword: '', // 关键字
|
||||
wareId: ''
|
||||
},
|
||||
searchResult: {
|
||||
content: [],
|
||||
last: false
|
||||
} // 搜索商品结果对象
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState('categoriesModule', ['categories'])
|
||||
},
|
||||
methods: {
|
||||
...mapActions('categoriesModule', ['getCategoriesAction']),
|
||||
...mapActions('cartModule', ['getCartListAction']),
|
||||
/*
|
||||
为什么不使用scroll-into-view而使用手动计算的方式,
|
||||
这是因为scroll-into-view不会进行居中菜单位置的定位处理,
|
||||
为了更好的用户操作体验,可以让当前选中菜单定位于整体滚动的居中位置
|
||||
*/
|
||||
// 点击左边的栏目切换
|
||||
async swichCategory(categoryId, index) {
|
||||
Object.assign(this.$data.searchResult, this.$options.data().searchResult); // 这里重置 searchResult 下的所有数据
|
||||
Object.assign(this.$data.filter, this.$options.data().filter); // 这里重置 filter 下的所有数据
|
||||
|
||||
this.categoryId = categoryId;
|
||||
if (index == this.current) return; // 防止选中分类的再次点击
|
||||
this.current = index;
|
||||
// 如果为0,意味着尚未初始化
|
||||
if (this.menuHeight == 0 || this.menuItemHeight == 0) {
|
||||
await this.getElRect('menu-scroll-view', 'menuHeight');
|
||||
await this.getElRect('gg-tab-item', 'menuItemHeight');
|
||||
}
|
||||
// 将菜单菜单活动item垂直居中
|
||||
this.scrollTop = index * this.menuItemHeight + this.menuItemHeight / 2 - this.menuHeight / 2;
|
||||
|
||||
// 获取右侧商品搜索结果数据
|
||||
this.getCategoryProductList();
|
||||
},
|
||||
// 获取一个目标元素的高度
|
||||
getElRect(elClass, dataVal) {
|
||||
new Promise((resolve, reject) => {
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query
|
||||
.select('.' + elClass)
|
||||
.fields({size: true}, res => {
|
||||
// 如果节点尚未生成,res值为null,循环调用执行
|
||||
if (!res) {
|
||||
setTimeout(() => {
|
||||
this.getElRect(elClass);
|
||||
}, 10);
|
||||
return;
|
||||
}
|
||||
this[dataVal] = res.height;
|
||||
})
|
||||
.exec();
|
||||
});
|
||||
},
|
||||
// 获取分类商品列表
|
||||
async getCategoryProductList() {
|
||||
const o = {
|
||||
categoryId: this.categoryId,
|
||||
page: this.filter.page,
|
||||
keyword: this.filter.keyword,
|
||||
limit: this.filter.limit,
|
||||
wareId: this.filter.wareId
|
||||
};
|
||||
let result = await this.$u.api.getSearchSku(o);
|
||||
this.searchResult = {...result, content: [...this.searchResult.content, ...result.content]};
|
||||
},
|
||||
// 加载更多数据
|
||||
loadMore() {
|
||||
if (!this.searchResult.last) {
|
||||
this.filter.page = this.filter.page + 1;
|
||||
this.getCategoryProductList();
|
||||
}
|
||||
},
|
||||
// 跳转到商品详情页
|
||||
gotoProductItem(skuId) {
|
||||
this.$u.route('/pages/homeItem/homeItem', {
|
||||
skuId
|
||||
});
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
await this.getCategoriesAction(); // 从仓库中获取分类列表
|
||||
this.categoryId = this.categories[0].id; // 获取第一个分类的id
|
||||
await this.getCategoryProductList(); // 商品数据搜索请求
|
||||
// 需要获取购物车数据列表,将最新获取的数据渲染到页面
|
||||
this.getCartListAction();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.gg {
|
||||
height: calc(100vh);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&-search-navbar {
|
||||
margin-top: -20rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 滚动信息搜索框 */
|
||||
&-notice-search-bar {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #ededed;
|
||||
border-radius: 30rpx;
|
||||
|
||||
/* 滚动信息搜索框左侧图标 */
|
||||
&-left-icon {
|
||||
position: relative;
|
||||
left: 20rpx;
|
||||
color: $u-light-color;
|
||||
}
|
||||
|
||||
/* 滚动信息搜索框中的字体设置 */
|
||||
&-u-notice-bar {
|
||||
flex: 1;
|
||||
/* 深层穿透修改子组件字体颜色样式 */
|
||||
::v-deep .u-news-item {
|
||||
color: $u-light-color !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 菜单包装器 */
|
||||
&-menu-wrap {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 左侧sv选项卡模式菜单 */
|
||||
&-tab-view {
|
||||
width: 200rpx;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 左侧菜单选项卡项 */
|
||||
&-tab-item {
|
||||
height: 110rpx;
|
||||
background: #f6f6f6;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 26rpx;
|
||||
color: #444;
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
|
||||
/* 激活状态 */
|
||||
&-active {
|
||||
position: relative;
|
||||
color: $u-type-warning;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
background: #fff;
|
||||
/* 伪类处理 */
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
border-left: 4px solid $u-type-warning;
|
||||
height: 32rpx;
|
||||
left: 0;
|
||||
top: 39rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 产品列表项 */
|
||||
&-product-item {
|
||||
height: 210rpx;
|
||||
|
||||
&-msg {
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
&-price-container {
|
||||
&-value {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-right-box {
|
||||
background-color: rgb(250, 250, 250);
|
||||
}
|
||||
}
|
||||
</style>
|
336
xlcs-user/pages/homeItem/homeItem.vue
Normal file
336
xlcs-user/pages/homeItem/homeItem.vue
Normal file
@@ -0,0 +1,336 @@
|
||||
<template>
|
||||
<view v-if="!detail.skuInfoVo" class="gg">
|
||||
<u-empty mode="data"></u-empty>
|
||||
</view>
|
||||
<view v-else class="gg">
|
||||
<u-navbar :border-bottom="false" :is-back="true" class="navbar"></u-navbar>
|
||||
|
||||
<scroll-view class="gg-sv" scroll-y>
|
||||
<view class="gg-content">
|
||||
<!-- 商品轮播图 -->
|
||||
<block v-if="swiperList.length > 0">
|
||||
<u-swiper :height="500" :list="swiperList" indicator-pos="bottomRight" mode="number"></u-swiper>
|
||||
</block>
|
||||
|
||||
<!-- 商品缩略图及属性还有价格购买数量的显示 -->
|
||||
<view class="u-flex u-type-info-light u-p-20 gg-content-price">
|
||||
<view class="u-p-r-20">
|
||||
<ListImgItem
|
||||
:showBottom="detail.skuInfoVo.skuType === 0 && detail.skuInfoVo.isNewPerson === 1"
|
||||
:showLeft="detail.skuInfoVo.skuType === 1"
|
||||
:showRight="false"
|
||||
:src="detail.skuInfoVo.imgUrl"
|
||||
height="120rpx"
|
||||
width="120rpx"
|
||||
></ListImgItem>
|
||||
</view>
|
||||
<!-- 区别秒杀商品与一般商品的价格体系 -->
|
||||
<!-- 秒杀商品显示 -->
|
||||
<block v-if="detail.skuInfoVo.skuType === 1">
|
||||
<view>
|
||||
<view class="gg-content-price-current u-flex">
|
||||
<view>秒杀价格:¥{{ detail.seckillSkuVo.seckillSale }}</view>
|
||||
<view class="u-p-l-20">市场价格:¥{{ detail.skuInfoVo.marketPrice }}</view>
|
||||
</view>
|
||||
<view class="gg-content-price-limit">
|
||||
<view>
|
||||
限购:{{ detail.seckillSkuVo.seckillLimit }}件 销售:{{ detail.seckillSkuVo.seckillSale }}件
|
||||
库存:{{ detail.seckillSkuVo.seckillStock }}件
|
||||
</view>
|
||||
<view>
|
||||
秒杀场次:{{ detail.seckillSkuVo.timeName }} 倒计时:
|
||||
<u-count-down ref="seckillCountDown" :timestamp="seckillSeconds" @end="seckillEnd"></u-count-down>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 普通商品显示 -->
|
||||
<block v-else>
|
||||
<view>
|
||||
<view class="gg-content-price-current u-flex">
|
||||
<view>当前价格:¥{{ detail.skuInfoVo.price }}</view>
|
||||
<view class="u-p-l-20">市场价格:¥{{ detail.skuInfoVo.marketPrice }}</view>
|
||||
</view>
|
||||
<view class="gg-content-price-limit">
|
||||
<view>限购数量:{{ detail.skuInfoVo.perLimit }}件</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!-- 商品名称 -->
|
||||
<view class="u-m-20 u-p-20 gg-content-container">
|
||||
<view class="u-flex">{{ detail.skuInfoVo.skuName }}</view>
|
||||
</view>
|
||||
|
||||
<!-- 属性列表 -->
|
||||
<view v-if="detail.skuInfoVo.skuAttrValueList.length > 0" class="u-m-20 u-p-20 gg-content-container">
|
||||
<view v-for="skuAttrValueItem in detail.skuInfoVo.skuAttrValueList" :key="skuAttrValueItem.id"
|
||||
class="u-p-t-5">
|
||||
{{ skuAttrValueItem.attrName }}:{{ skuAttrValueItem.attrValue }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 活动规则 -->
|
||||
<view v-if="detail.activityRuleList.length > 0" class="u-m-20 u-p-20 gg-content-container">
|
||||
<view v-for="activityRuleItem in detail.activityRuleList" :key="activityRuleItem.id" class="u-p-t-5">
|
||||
{{ activityRuleItem.ruleDesc }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 售后与提货地址 -->
|
||||
<view class="u-m-20 u-p-20 gg-content-container">
|
||||
<view class="u-flex">
|
||||
<view class="u-font-sm u-m-r-20 u-type-info">售后无忧</view>
|
||||
<view class="u-font-sm u-m-r-20 u-flex-1">
|
||||
支持保价
|
||||
<text class="u-type-error">・</text>
|
||||
极速退款
|
||||
<text class="u-type-error">・</text>
|
||||
7天无理由退货
|
||||
</view>
|
||||
<u-icon class="u-m-r-20 u-type-info" name="arrow-right" size="24"></u-icon>
|
||||
</view>
|
||||
|
||||
<view class="u-flex u-m-t-20">
|
||||
<view class="u-font-sm u-m-r-20 u-type-info">提货信息</view>
|
||||
<view class="u-font-sm u-m-r-20 u-flex-1">
|
||||
<view>
|
||||
现在下单,
|
||||
<text class="u-type-error">明天16:00可提货</text>
|
||||
</view>
|
||||
<view>提货点:{{ leaderAddressVo.takeName ? leaderAddressVo.takeName : '请设置提货点' }}</view>
|
||||
</view>
|
||||
<u-icon class="u-m-r-20 u-type-info" name="arrow-right" size="24"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品详情图片清单 -->
|
||||
<view v-if="skuPosterList.length > 0" class="u-m-20 u-p-20 gg-content-container">
|
||||
<image v-for="skuPoster in skuPosterList" :key="skuPoster.id" :src="skuPoster.image"></image>
|
||||
</view>
|
||||
<u-gap height="30"></u-gap>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<view class="gg-navigation">
|
||||
<view class="navigation">
|
||||
<view class="left">
|
||||
<view class="item" @click="gotoHome">
|
||||
<u-icon :color="$u.color['contentColor']" :size="40" name="home-fill"></u-icon>
|
||||
<view class="text u-line-1">首页</view>
|
||||
</view>
|
||||
<view class="item car">
|
||||
<u-badge v-if="skuId !== 0" :count="getProductSkuNum(skuId)" :offset="[-3, -6]" class="car-num"
|
||||
type="error"></u-badge>
|
||||
<u-icon :color="$u.color['contentColor']" :size="40" name="shopping-cart-fill"></u-icon>
|
||||
<view class="text u-line-1">购物车</view>
|
||||
</view>
|
||||
|
||||
<view v-if="detail.couponInfoList.length > 0" class="item car" @click="showCouponInfoList = true">
|
||||
<u-badge :count="detail.couponInfoList.length" :offset="[-3, -6]" class="car-num" type="error"></u-badge>
|
||||
<u-icon :color="$u.color['contentColor']" :size="40" name="gift-fill"></u-icon>
|
||||
<view class="text u-line-1">优惠券</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 即将秒杀与加入购物车的显示 -->
|
||||
<view v-if="!seckillEnded" class="right u-p-r-10 u-flex">
|
||||
<!-- 即将开抢 -->
|
||||
<block v-if="getDetail.seckillSkuVo.timeStaus === 3">
|
||||
<view class="u-m-r-20 u-line-1 u-flex-1 u-text-center">场次:{{ getDetail.seckillSkuVo.timeName }}</view>
|
||||
<view class="buy-disabled btn u-line-1">即将开抢</view>
|
||||
</block>
|
||||
<!-- 加入购物车 -->
|
||||
<block v-else>
|
||||
<view class="u-m-r-20 u-line-1 u-flex-1">
|
||||
<AddToCart v-if="detail.skuInfoVo.id" :shopDetail="getDetail" :skuId="detail.skuInfoVo.id"></AddToCart>
|
||||
</view>
|
||||
<view class="buy btn u-line-1">立即购买</view>
|
||||
</block>
|
||||
</view>
|
||||
<!-- 秒杀结束显示 -->
|
||||
<view v-else class="right u-p-r-10 u-flex">
|
||||
<view class="u-m-r-20 u-line-1 u-flex-1"></view>
|
||||
<view class="buy-disabled btn u-line-1">秒杀结束</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<CouponInfoList :couponInfoList="detail.couponInfoList" :showCouponInfoList.sync="showCouponInfoList"
|
||||
@getCouponInfo="getCouponInfo"></CouponInfoList>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapState, mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
detail: {},
|
||||
skuId: 0,
|
||||
seckillSeconds: 0,
|
||||
seckillEnded: false,
|
||||
showCouponInfoList: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState('pickUpLocationModule', ['leaderAddressVo']),
|
||||
...mapGetters('cartModule', ['getProductSkuNum']),
|
||||
// 轮播图的获取
|
||||
swiperList() {
|
||||
let lst = [];
|
||||
this.detail &&
|
||||
this.detail.skuInfoVo &&
|
||||
this.detail.skuInfoVo.skuImagesList.length > 0 &&
|
||||
this.detail.skuInfoVo.skuImagesList.forEach(item => {
|
||||
lst.push({
|
||||
image: item.imgUrl,
|
||||
title: item.imgName
|
||||
});
|
||||
});
|
||||
return lst;
|
||||
},
|
||||
// 商品详情海报图片列表
|
||||
skuPosterList() {
|
||||
let lst = [];
|
||||
this.detail &&
|
||||
this.detail.skuInfoVo &&
|
||||
this.detail.skuInfoVo.skuPosterList.length > 0 &&
|
||||
this.detail.skuInfoVo.skuPosterList.forEach(item => {
|
||||
lst.push({
|
||||
image: item.imgUrl,
|
||||
title: item.imgName
|
||||
});
|
||||
});
|
||||
return lst;
|
||||
},
|
||||
getDetail() {
|
||||
return {...this.detail.skuInfoVo, seckillSkuVo: this.detail.seckillSkuVo};
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getHomeItemData(skuId) {
|
||||
let result = await this.$u.api.getHomeItem({skuId});
|
||||
this.detail = result;
|
||||
// skuInfoVo 商品信息
|
||||
// couponInfoList 优惠券信息
|
||||
// activityRuleList 活动信息
|
||||
|
||||
// 如果是秒杀商品,需要计算倒计时秒数
|
||||
if (this.detail.skuInfoVo.skuType === 1) {
|
||||
const now = this.$dayjs();
|
||||
const endTime = this.$dayjs(this.$dayjs().format('YYYY-MM-DD') + ' ' + this.detail.seckillSkuVo.endTime);
|
||||
const seconds = endTime.diff(now, 'second');
|
||||
this.seckillSeconds = seconds;
|
||||
}
|
||||
},
|
||||
// 切换首页
|
||||
gotoHome() {
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index'
|
||||
});
|
||||
return false;
|
||||
},
|
||||
// 秒杀倒计时结束
|
||||
seckillEnd() {
|
||||
this.seckillEnded = true;
|
||||
},
|
||||
// 领取优惠券
|
||||
async getCouponInfo(id) {
|
||||
try {
|
||||
const result = await this.$u.api.getCouponInfo({id});
|
||||
const pos = this.detail.couponInfoList.findIndex(item => item.id === id);
|
||||
this.$set(this.detail.couponInfoList[pos], 'couponStatus', 1);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
let skuId = +options.skuId;
|
||||
this.skuId = skuId;
|
||||
this.getHomeItemData(skuId);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.gg {
|
||||
height: 100%;
|
||||
|
||||
&-sv {
|
||||
height: calc(100vh - 116rpx - 102rpx);
|
||||
}
|
||||
|
||||
&-content {
|
||||
background-color: $u-bg-color;
|
||||
|
||||
&-price {
|
||||
background: linear-gradient(to right, rgb(255, 180, 61), rgb(255, 101, 0));
|
||||
}
|
||||
|
||||
&-container {
|
||||
z-index: 9999;
|
||||
background-color: #fff;
|
||||
border-radius: 25rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&-navigation {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
|
||||
.navigation {
|
||||
display: flex;
|
||||
border: solid 2rpx #f2f2f2;
|
||||
background-color: #ffffff;
|
||||
padding: 16rpx 0;
|
||||
justify-content: space-around;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
font-size: 20rpx;
|
||||
|
||||
.item {
|
||||
margin: 0 30rpx;
|
||||
|
||||
&.car {
|
||||
text-align: center;
|
||||
position: relative;
|
||||
|
||||
.car-num {
|
||||
position: absolute;
|
||||
top: -10rpx;
|
||||
right: -10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
width: 375rpx;
|
||||
display: flex;
|
||||
font-size: 28rpx;
|
||||
align-items: center;
|
||||
|
||||
.btn {
|
||||
line-height: 50rpx;
|
||||
padding: 0 30rpx;
|
||||
border-radius: 36rpx;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.buy {
|
||||
background-color: #ff7900;
|
||||
}
|
||||
|
||||
.buy-disabled {
|
||||
background-color: $u-type-info;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
487
xlcs-user/pages/index/index.vue
Normal file
487
xlcs-user/pages/index/index.vue
Normal file
@@ -0,0 +1,487 @@
|
||||
<template>
|
||||
<view v-if="token" class="gg">
|
||||
<!-- 利用background-image设置导航的线形渐变色彩 -->
|
||||
<u-navbar :background="{ 'background-image': 'linear-gradient(to right, rgb(255,180,61), rgb(255, 101, 0))' }" :border-bottom="false"
|
||||
:is-back="false">
|
||||
<view class="gg-map-slot-wrap u-font-xs u-m-l-20 u-p-l-10 u-p-r-10 u-p-t-5 u-p-b-5" @click="pickUpLocation">
|
||||
<u-icon name="map" size="24"></u-icon>
|
||||
<text class="u-p-l-10 u-p-r-10">{{
|
||||
leaderAddressVo.takeName ? leaderAddressVo.takeName : '请设置提货点'
|
||||
}}
|
||||
</text>
|
||||
<u-icon name="arrow-right" size="20"></u-icon>
|
||||
</view>
|
||||
</u-navbar>
|
||||
|
||||
<!-- 主内容区域-Begin -->
|
||||
<view class="gg-content">
|
||||
<!-- 头部区域 -->
|
||||
<view class="gg-header u-p-l-20 u-p-r-20">
|
||||
<!--
|
||||
头部滚动提示搜索区
|
||||
1.搜索图标
|
||||
2.滚动提示条
|
||||
3.搜索按钮(自定义样式)
|
||||
-->
|
||||
<view class="gg-notice-search-bar">
|
||||
<u-icon class="gg-notice-search-bar-left-icon" name="search"></u-icon>
|
||||
<u-notice-bar
|
||||
:border-radius="30"
|
||||
:is-circular="false"
|
||||
:list="list"
|
||||
:more-icon="false"
|
||||
:volume-icon="false"
|
||||
class="gg-notice-search-bar-u-notice-bar"
|
||||
mode="vertical"
|
||||
type="none"
|
||||
></u-notice-bar>
|
||||
<u-button :custom-style="ggNoticeSearchBarRightBtnCustomStyle" class="u-m-r-20" shape="square" size="mini"
|
||||
type="error">搜索
|
||||
</u-button>
|
||||
</view>
|
||||
|
||||
<!-- 新人专享低价好物sv滚动区 -->
|
||||
<view class="gg-new-vip u-p-20 u-m-t-20">
|
||||
<view class="u-font-lg u-content-color">新人专享低价好物</view>
|
||||
<scroll-view class="gg-new-vip-sv" enable-flex scroll-x>
|
||||
<view class="u-flex u-m-t-10">
|
||||
<view v-for="(item, index) in newPersonSkuInfoList" :key="item.id" class="gg-new-vip-sv-item u-p-r-20"
|
||||
@click="gotoProductItem(item.id)">
|
||||
<ListImgItem
|
||||
:showBottom="item.skuType === 0 && item.isNewPerson === 1"
|
||||
:showLeft="item.skuType === 1"
|
||||
:showRight="false"
|
||||
:src="item.imgUrl"
|
||||
height="200rpx"
|
||||
width="200rpx"
|
||||
></ListImgItem>
|
||||
<text class="u-type-error">¥ {{ item.price }}</text>
|
||||
<AddToCart :shopDetail="item" :skuId="item.id"></AddToCart>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 头部区域底部左右圆角区 -->
|
||||
<view class="gg-header-bottom"></view>
|
||||
|
||||
<!-- 小鹿超市规则 -->
|
||||
<view class="u-flex u-row-between u-p-20 u-m-20 gg-border" @click="showRulePopup = true">
|
||||
<u-image height="30rpx" src="/static/logo.png" width="30rpx"></u-image>
|
||||
<view>平台资质、法律条款、规则及投诉入口</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品分类 -->
|
||||
<view class="u-m-20 u-p-20 gg-border">
|
||||
<scroll-view enable-flex scroll-x @scroll="scrollMove">
|
||||
<view class="u-flex u-p-r-20 u-p-t-20">
|
||||
<!-- 循环滚动内容 -->
|
||||
<view v-for="item in categoryList" :key="item.id" class="u-p-l-20 u-p-r-20">
|
||||
<u-image :src="item.imgUrl" border-radius="30rpx" height="100rpx" width="100rpx"></u-image>
|
||||
<text class="u-font-xs">{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="gg-category">
|
||||
<u-line-progress :percent="categorySVPercent" :show-percent="false" class="gg-category-progress"
|
||||
height="5"></u-line-progress>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 限时秒杀 -->
|
||||
<block v-if="seckillSkuVoList.length > 0">
|
||||
<!-- 秒杀 -->
|
||||
<view class="u-m-l-20 u-m-r-20 u-flex">
|
||||
<view class="u-flex u-flex-1">
|
||||
<view class="u-font-lg u-type-error">
|
||||
秒杀抢购:
|
||||
<text class="u-font-sm">{{ seckillTime.name }}场 {{ seckillTime.startTime }}-{{
|
||||
seckillTime.endTime
|
||||
}}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<u-button :plain="true" size="mini" @click="gotoSeckill">查看全部 ></u-button>
|
||||
</view>
|
||||
<view class="u-m-20 u-p-20 gg-border">
|
||||
<scroll-view enable-flex scroll-x>
|
||||
<view class="u-flex u-p-r-20 u-p-t-20">
|
||||
<!-- 循环滚动内容 -->
|
||||
<view v-for="item in seckillSkuVoList" :key="item.skuId" class="u-p-l-20 u-p-r-20 u-text-center"
|
||||
@click="gotoProductItem(item.skuId)">
|
||||
<text class="u-font-sm u-m-b-5">{{ item.timeName }}</text>
|
||||
<u-image :src="item.imgUrl" border-radius="30rpx" height="200rpx" width="200rpx"></u-image>
|
||||
<text class="u-font-sm u-m-t-5">{{ item.skuName }}</text>
|
||||
<AddToCart :shopDetail="item" :skuId="item.skuId"></AddToCart>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!-- 如何购买商品 -->
|
||||
<view class="u-p-20 u-m-20 gg-border u-font-xs">
|
||||
<view class="u-m-b-20">如何在[小鹿超市]购买商品</view>
|
||||
<view class="u-flex">
|
||||
<view class="gg-number u-m-r-10">1</view>
|
||||
挑商品
|
||||
<u-icon name="arrow-right-double u-m-l-10 u-tips-color"></u-icon>
|
||||
<u-icon class="u-content-color" name="arrow-right-double"></u-icon>
|
||||
<view class="gg-number gg-number-gray u-m-r-10 u-m-l-10">2</view>
|
||||
选提货点
|
||||
<u-icon name="arrow-right-double u-m-l-10 u-tips-color"></u-icon>
|
||||
<u-icon class="u-content-color" name="arrow-right-double"></u-icon>
|
||||
<view class="gg-number gg-number-gray u-m-r-10 u-m-l-10">3</view>
|
||||
次日16点提货点取货
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 热销好货 -->
|
||||
<view class="u-font-xl u-type-error u-m-20">热销好货</view>
|
||||
<view v-for="(item, index) in hotSkuList" :key="item.id" class="u-p-20 u-m-20 gg-border"
|
||||
@click="gotoProductItem(item.id)">
|
||||
<view class="u-m-b-10 u-m-l-20 u-m-r-20 u-flex gg-product-item">
|
||||
<ListImgItem
|
||||
:showBottom="item.skuType === 0 && item.isNewPerson === 1"
|
||||
:showLeft="item.skuType === 1"
|
||||
:showRight="false"
|
||||
:src="item.imgUrl"
|
||||
height="250rpx"
|
||||
width="250rpx"
|
||||
></ListImgItem>
|
||||
<view class="gg-product-item-msg u-border-bottom u-p-b-20 u-m-l-20">
|
||||
<view class="gg-product-item-msg-title">
|
||||
<view class="u-font-lg">{{ item.title }}</view>
|
||||
<view class="u-type-info u-font-sm">已售{{ item.sale }}/剩余{{ item.stock }}</view>
|
||||
<block v-if="item.ruleList">
|
||||
<view v-for="(rule, ruleIndex) in item.ruleList" :key="ruleIndex" class="u-font-xs u-type-error-dark">
|
||||
{{ rule }}
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="u-flex u-row-between">
|
||||
<view class="u-type-error gg-product-item-msg-price">
|
||||
<text>¥</text>
|
||||
<text class="gg-product-item-msg-price-value">{{ item.price }}</text>
|
||||
</view>
|
||||
<AddToCart :shopDetail="item"></AddToCart>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<u-gap height="20"></u-gap>
|
||||
</view>
|
||||
<!-- 主内容区域-End -->
|
||||
|
||||
<!-- 平台资质、法律条款、规则及投诉入口弹出框 -->
|
||||
<u-popup v-model="showRulePopup" :closeable="true" border-radius="20" mode="bottom">
|
||||
<view class="u-p-t-20 u-p-b-20">
|
||||
<view class="u-m-20">
|
||||
<view class="u-font-xl u-m-b-10">
|
||||
<u-icon class="u-m-r-10" color="#dd6161" name="checkmark-circle" size="28"></u-icon>
|
||||
品质保障
|
||||
</view>
|
||||
<view class="u-light-color u-font-xs">
|
||||
全场商品均经过品质检验,若收货时发现商品有变质、腐烂、损坏等情况,可申请退款
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="u-m-20">
|
||||
<view class="u-font-xl u-m-b-10">
|
||||
<u-icon class="u-m-r-10" color="#dd6161" name="kefu-ermai" size="28"></u-icon>
|
||||
极速退款
|
||||
</view>
|
||||
<view class="u-light-color u-font-xs">根据平台的规则,在一定条件下,可享受极速退款到账服务</view>
|
||||
</view>
|
||||
|
||||
<view class="u-m-20">
|
||||
<view class="u-font-xl u-m-b-10">
|
||||
<u-icon class="u-m-r-10" color="#dd6161" name="bag" size="28"></u-icon>
|
||||
次日自提
|
||||
</view>
|
||||
<view class="u-light-color u-font-xs">每日23点前下单,次日16点可到下单门店自提</view>
|
||||
</view>
|
||||
|
||||
<view class="u-m-20">
|
||||
<view class="u-font-xl u-m-b-10">
|
||||
<u-icon class="u-m-r-10" color="#dd6161" name="integral" size="28"></u-icon>
|
||||
资质规则
|
||||
</view>
|
||||
<view class="u-light-color u-font-xs">平台资质、法律条款、规则及投诉入口,点击查看详情</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
|
||||
<view v-else class="emptyPage">
|
||||
<u-empty mode="page"></u-empty>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapState, mapGetters, mapActions} from 'vuex';
|
||||
|
||||
let watchTimes = 0;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
list: ['寒雨连江夜入吴', '平明送客楚山孤', '洛阳亲友如相问', '一片冰心在玉壶'],
|
||||
// 滚动提示搜索区右侧按钮自定义样式
|
||||
ggNoticeSearchBarRightBtnCustomStyle: {
|
||||
borderRadius: '30rpx'
|
||||
},
|
||||
showRulePopup: false,
|
||||
windowWidth: 0, // 设备宽度
|
||||
categorySVPercent: 0, // 精选进度百分比
|
||||
token: null
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
uni.getSystemInfo({
|
||||
success: res => {
|
||||
this.windowWidth = res.windowWidth;
|
||||
}
|
||||
});
|
||||
},
|
||||
computed: {
|
||||
...mapState('indexModule', ['home']),
|
||||
...mapGetters('indexModule', ['categoryList', 'hotSkuList', 'newPersonSkuInfoList', 'seckillTime', 'seckillSkuVoList', 'leaderAddressVo'])
|
||||
},
|
||||
methods: {
|
||||
...mapActions('indexModule', ['getHomeIndexAction']),
|
||||
scrollMove(e) {
|
||||
// 计算滚动的进度百分比
|
||||
let scrollLeft = e.detail.scrollLeft;
|
||||
let scrollWidth = e.detail.scrollWidth - this.windowWidth;
|
||||
let percent = parseInt((scrollLeft / scrollWidth) * 100);
|
||||
|
||||
// 利用防抖进行性能的优化
|
||||
this.$u.debounce(() => {
|
||||
this.categorySVPercent = percent;
|
||||
}, 100);
|
||||
},
|
||||
// 跳转至设置提货点
|
||||
pickUpLocation() {
|
||||
this.$u.route('/pagesLocation/myPickUpLocation/myPickUpLocation');
|
||||
},
|
||||
// 跳转至商品详情页
|
||||
gotoProductItem(skuId) {
|
||||
this.$u.route('/pages/homeItem/homeItem', {skuId});
|
||||
},
|
||||
// 跳转至秒杀页
|
||||
gotoSeckill() {
|
||||
this.$u.route('/pagesSeckill/seckill/seckill');
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
/* ------------------------------------------------------------
|
||||
watch监控第一部分,函数式监控
|
||||
1.只能监控单层数据,不能立即监控,只有数据变化的时候才可以
|
||||
2.深度监控无法实现
|
||||
3.函数不可以使用箭头函数,否则this对象无法找到
|
||||
------------------------------------------------------------ */
|
||||
// leaderAddressVo: function() {
|
||||
// console.log('normal watch', this.leaderAddressVo);
|
||||
// }
|
||||
/* ------------------------------------------------------------
|
||||
watch监控第二部分,对象式监控
|
||||
1.immediate立即监控的触发次数,无论如何先会触发一次,监控数据变化
|
||||
2.深度监控的作用,直接监控对象属性值的变化
|
||||
3.监控次数的判断
|
||||
1)因为立即监控,所以页面初始会触发一次
|
||||
2)可以设置全局变量进行判断条件依据
|
||||
3)利用监控次数确认路由的跳转
|
||||
------------------------------------------------------------ */
|
||||
// 'leaderAddressVo.userId': {
|
||||
// handler(newVal) {
|
||||
// watchTimes++;
|
||||
// if (watchTimes > 1) {
|
||||
// watchTimes = 0;
|
||||
// if (!newVal) {
|
||||
// console.log('immediate deep watch');
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// immediate: true,
|
||||
// deep: true
|
||||
// }
|
||||
/* ------------------------------------------------------------
|
||||
watch监控第三部分,对象式监控
|
||||
1.immediate的去除
|
||||
2.等mounted请求结束,数据设置完毕以后再进行数据变化的监控
|
||||
3.不需要进行监控次数的判断
|
||||
------------------------------------------------------------ */
|
||||
'leaderAddressVo.userId': {
|
||||
handler(newVal) {
|
||||
if (!newVal) {
|
||||
uni.redirectTo({
|
||||
url: '/pagesLocation/myPickUpLocation/myPickUpLocation'
|
||||
});
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
/*
|
||||
onShow比mounted先执行
|
||||
mounted中有获取数据的异步请求,本身是异步,还需要再进行数据设置获取
|
||||
onShow已经执行完毕,是否能确认leaderAddressVo对象的内容变化?不能
|
||||
是否能在onShow中利用leaderAddressVo进行条件判断?不能
|
||||
*/
|
||||
console.log('leaderAddressVo:', this.leaderAddressVo);
|
||||
},
|
||||
async mounted() {
|
||||
console.log('mounted');
|
||||
const token = await uni.getStorageSync('token');
|
||||
if (this.$u.test.isEmpty(token)) {
|
||||
uni.reLaunch({
|
||||
url: '/pages/login/login'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.token = token;
|
||||
await this.getHomeIndexAction();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/*
|
||||
利用scss中&-的方式实现层级样式的拼接
|
||||
*/
|
||||
.gg {
|
||||
/* navbar 导航中进行地图位置的获取设置 */
|
||||
&-map-slot-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: rgba(240, 240, 240, 0.35);
|
||||
color: #fff;
|
||||
border-radius: 100rpx;
|
||||
}
|
||||
|
||||
/* 内容区域 */
|
||||
&-content {
|
||||
background-color: $u-bg-color;
|
||||
}
|
||||
|
||||
/*
|
||||
notice-bar头部滚动信息搜索区域
|
||||
利用background-image的linear-gradient保持与导航一致的线形渐变色彩
|
||||
*/
|
||||
&-header {
|
||||
background-image: linear-gradient(to right, rgb(255, 180, 61), rgb(255, 101, 0));
|
||||
height: 500rpx;
|
||||
}
|
||||
|
||||
/* 滚动信息搜索框 */
|
||||
&-notice-search-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: white;
|
||||
border-radius: 30rpx;
|
||||
|
||||
/* 滚动信息搜索框左侧图标 */
|
||||
&-left-icon {
|
||||
position: relative;
|
||||
left: 20rpx;
|
||||
color: $u-light-color;
|
||||
}
|
||||
|
||||
/* 滚动信息搜索框中的字体设置 */
|
||||
&-u-notice-bar {
|
||||
flex: 1;
|
||||
/* 深层穿透修改子组件字体颜色样式 */
|
||||
::v-deep .u-news-item {
|
||||
color: $u-light-color !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 头部区域底部左右圆角区域 */
|
||||
&-header-bottom {
|
||||
background-image: linear-gradient(to right, rgb(255, 180, 61), rgb(255, 101, 0));
|
||||
height: 25rpx;
|
||||
border-bottom-left-radius: 25rpx;
|
||||
border-bottom-right-radius: 25rpx;
|
||||
}
|
||||
|
||||
/* 新人专享 */
|
||||
&-new-vip {
|
||||
background-color: white;
|
||||
border-radius: 20rpx;
|
||||
|
||||
&-sv {
|
||||
height: 320rpx;
|
||||
|
||||
&-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 小鹿超市规则 */
|
||||
&-border {
|
||||
border-radius: 20rpx;
|
||||
border-bottom: 1rpx solid #f5f5f5;
|
||||
box-shadow: 0px 1px 20px 0px rgba(0, 0, 0, 0.1); /*下边阴影 */
|
||||
}
|
||||
|
||||
/* 商品分类 */
|
||||
&-category {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 5rpx;
|
||||
|
||||
&-progress {
|
||||
width: 10vw;
|
||||
}
|
||||
}
|
||||
|
||||
/* 如何购买商品 */
|
||||
&-number {
|
||||
border-radius: 50%;
|
||||
background-color: $u-type-warning;
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
text-align: center;
|
||||
font-size: 20rpx;
|
||||
color: white;
|
||||
|
||||
&-gray {
|
||||
background-color: gray;
|
||||
}
|
||||
}
|
||||
|
||||
/* 热销好货 */
|
||||
&-product-item {
|
||||
height: 250rpx;
|
||||
|
||||
&-msg {
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
&-price {
|
||||
&-value {
|
||||
font-size: 50rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.emptyPage {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
139
xlcs-user/pages/login/login.vue
Normal file
139
xlcs-user/pages/login/login.vue
Normal file
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<view class="wrap">
|
||||
<view class="content">
|
||||
<view class="title">欢迎登陆小鹿超市</view>
|
||||
</view>
|
||||
<view class="buttom">
|
||||
<view class="loginType">
|
||||
<!-- 对于按钮需要进行禁用判断,以防止多次点击 -->
|
||||
<button :disabled="isLogin" class="loginBtn" @click="getUserMsg">
|
||||
<view class="wechat item">
|
||||
<view class="icon">
|
||||
<u-icon color="rgb(83,194,64)" name="weixin-fill" size="200"></u-icon>
|
||||
</view>
|
||||
微信登陆
|
||||
</view>
|
||||
</button>
|
||||
</view>
|
||||
<view class="hint">
|
||||
登录代表同意
|
||||
<text class="link">小鹿超市用户协议、隐私政策,</text>
|
||||
并授权使用您的小鹿超市账号信息(如昵称、头像、收获地址)以便您统一管理
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 防止按钮多次点击的布尔值
|
||||
isLogin: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 获取用户信息
|
||||
getUserMsg() {
|
||||
// 不允许按钮点击
|
||||
this.isLogin = true;
|
||||
// 获取用户信息
|
||||
uni.getUserProfile({
|
||||
desc: '获取用户信息',
|
||||
success: res => {
|
||||
// 获取到用户头像、昵称、性别等内容,并将它们进行本地缓存的存储
|
||||
const photoUrl = res.userInfo.avatarUrl;
|
||||
const nickName = res.userInfo.nickName;
|
||||
const sex = res.userInfo.gender;
|
||||
uni.setStorageSync('userInfo', {photoUrl, nickName, sex});
|
||||
// 进行微信登陆操作(具体查看小程序登陆wx.login流程图)
|
||||
// https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
|
||||
uni.login({
|
||||
success: async res => {
|
||||
// 利用小程序登陆,配合code码进行用户登陆操作,并返回用户的token值
|
||||
const result = await this.$u.api.getWxLogin({code: res.code});
|
||||
console.log(result, result.token, "<<<")
|
||||
// 将token值进行本地缓存存储
|
||||
uni.setStorage({
|
||||
key: 'token',
|
||||
data: result.token,
|
||||
success: async () => {
|
||||
// 更新用户信息
|
||||
// await this.$u.api.postUpdateUser({
|
||||
// sex,
|
||||
// photoUrl,
|
||||
// nickName
|
||||
// });
|
||||
// 路由跳转至首页
|
||||
uni.reLaunch({
|
||||
url: '/pages/index/index',
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
fail: err => {
|
||||
console.log(err);
|
||||
},
|
||||
complete: () => {
|
||||
// 恢复按钮可用性
|
||||
this.isLogin = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wrap {
|
||||
font-size: 28rpx;
|
||||
|
||||
.content {
|
||||
width: 600rpx;
|
||||
margin: 80rpx auto 0;
|
||||
|
||||
.title {
|
||||
text-align: left;
|
||||
font-size: 60rpx;
|
||||
font-weight: 500;
|
||||
margin-bottom: 100rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.buttom {
|
||||
.loginType {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 100rpx;
|
||||
|
||||
.loginBtn {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.loginBtn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
color: $u-content-color;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.hint {
|
||||
padding: 20rpx 40rpx;
|
||||
font-size: 24rpx;
|
||||
color: $u-tips-color;
|
||||
|
||||
.link {
|
||||
color: $u-type-warning;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
275
xlcs-user/pages/my/my.vue
Normal file
275
xlcs-user/pages/my/my.vue
Normal file
@@ -0,0 +1,275 @@
|
||||
<template>
|
||||
<view class="gg">
|
||||
<u-navbar :background="{ 'background-image': 'linear-gradient(to right, rgb(255,180,61), rgb(255, 101, 0))' }" :border-bottom="false"
|
||||
:is-back="false"></u-navbar>
|
||||
<view class="gg-content">
|
||||
<view class="gg-header u-p-l-20 u-p-r-20">
|
||||
<view class="u-flex u-m-l-20">
|
||||
<u-image :src="userInfo.photoUrl" height="100rpx" shape="circle" width="100rpx"/>
|
||||
<view class="u-font-lg u-type-info-light u-m-l-20">Hi {{ userInfo.nickName }}</view>
|
||||
</view>
|
||||
|
||||
<view class="wrap u-p-t-20" justify="between">
|
||||
<u-row gutter="16">
|
||||
<u-col span="4">
|
||||
<view class="gg-order-item">
|
||||
<view class="u-font-lg u-type-info-light">0元</view>
|
||||
<view class="u-font-xs u-type-info-light">资产</view>
|
||||
</view>
|
||||
</u-col>
|
||||
<u-col span="4">
|
||||
<view class="gg-order-item">
|
||||
<view class="u-font-lg u-type-info-light">0.00元</view>
|
||||
<view class="u-font-xs u-type-info-light">红包</view>
|
||||
</view>
|
||||
</u-col>
|
||||
<u-col span="4">
|
||||
<view class="gg-order-item">
|
||||
<view class="u-font-lg u-type-info-light">0张</view>
|
||||
<view class="u-font-xs u-type-info-light">优惠券</view>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
</view>
|
||||
<view class="gg-header-bottom"></view>
|
||||
|
||||
<view class="gg-content-container">
|
||||
<view class="gg-content-container-box">
|
||||
<view class="u-flex u-row-between">
|
||||
<view class="u-m-20">我的订单</view>
|
||||
<view class="u-m-20 u-font-xs u-type-info" @click="gotoOrderList(-1)">查看全部 ></view>
|
||||
</view>
|
||||
<view class="u-flex u-row-around">
|
||||
<view class="gg-order-item" @click="gotoOrderList(0)">
|
||||
<view class="iconfont icon-daifukuan u-type-warning"></view>
|
||||
<view class="u-font-xs">待付款</view>
|
||||
</view>
|
||||
|
||||
<view class="gg-order-item" @click="gotoOrderList(1)">
|
||||
<view class="iconfont icon-daifahuo1 u-type-warning"></view>
|
||||
<view class="u-font-xs u-p-l-5">待发货</view>
|
||||
</view>
|
||||
|
||||
<view class="gg-order-item" @click="gotoOrderList(2)">
|
||||
<view class="iconfont icon-tihuoguanli u-type-warning"></view>
|
||||
<view class="u-font-xs u-p-l-5">待提货</view>
|
||||
</view>
|
||||
|
||||
<view class="gg-order-item" @click="gotoOrderList(3)">
|
||||
<view class="iconfont icon-pinglun2 u-type-warning"></view>
|
||||
<view class="u-font-xs u-p-l-10">待评价</view>
|
||||
</view>
|
||||
|
||||
<view class="gg-order-item" @click="gotoOrderList(4)">
|
||||
<view class="iconfont icon-tuikuanshouhou u-type-warning"></view>
|
||||
<view class="u-font-xs">已完结</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-p-20"></view>
|
||||
</view>
|
||||
|
||||
<view class="gg-content-container-box u-m-t-20">
|
||||
<view class="u-flex u-row-around u-p-t-20">
|
||||
<view class="gg-order-item">
|
||||
<image :src="recommend" class="gg-svg-icon"></image>
|
||||
<view class="u-font-xs">有奖推荐</view>
|
||||
</view>
|
||||
|
||||
<view class="gg-order-item">
|
||||
<image :src="invite" class="gg-svg-icon"></image>
|
||||
<view class="u-font-xs u-p-l-5">邀新团长有奖</view>
|
||||
</view>
|
||||
|
||||
<view class="gg-order-item">
|
||||
<image :src="fruit" class="gg-svg-icon"></image>
|
||||
<view class="u-font-xs u-p-l-5">7天种水果</view>
|
||||
</view>
|
||||
|
||||
<view class="gg-order-item">
|
||||
<image :src="discount" class="gg-svg-icon"></image>
|
||||
<view class="u-font-xs u-p-l-10">天天低价</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-p-20"></view>
|
||||
</view>
|
||||
|
||||
<view class="gg-content-container-box u-m-t-20">
|
||||
<u-swiper :list="list"></u-swiper>
|
||||
</view>
|
||||
|
||||
<view class="gg-content-container-box u-m-t-20">
|
||||
<view class="wrap u-p-t-20" justify="between">
|
||||
<u-row gutter="16">
|
||||
<u-col span="3">
|
||||
<view class="gg-order-item">
|
||||
<view class="iconfont icon-ico"></view>
|
||||
<view class="u-font-xs">提货码</view>
|
||||
</view>
|
||||
</u-col>
|
||||
<u-col span="3">
|
||||
<view class="gg-order-item" @click="gotoMyPickUpLocation">
|
||||
<view class="iconfont icon-dianpu"></view>
|
||||
<view class="u-font-xs">提货点管理</view>
|
||||
</view>
|
||||
</u-col>
|
||||
<u-col span="3">
|
||||
<view class="gg-order-item">
|
||||
<view class="iconfont icon-miaosha"></view>
|
||||
<view class="u-font-xs">秒杀提醒</view>
|
||||
</view>
|
||||
</u-col>
|
||||
<u-col span="3">
|
||||
<view class="gg-order-item">
|
||||
<view class="iconfont icon-yonghu"></view>
|
||||
<view class="u-font-xs">成为团长</view>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
<u-gap height="30"></u-gap>
|
||||
<u-row gutter="16">
|
||||
<u-col span="3">
|
||||
<view class="gg-order-item">
|
||||
<view class="iconfont icon-kefu"></view>
|
||||
<view class="u-font-xs">联系客服</view>
|
||||
</view>
|
||||
</u-col>
|
||||
<u-col span="3">
|
||||
<view class="gg-order-item">
|
||||
<view class="iconfont icon-shanghupiliangruzhu"></view>
|
||||
<view class="u-font-xs">商户入驻</view>
|
||||
</view>
|
||||
</u-col>
|
||||
<u-col span="3">
|
||||
<view class="gg-order-item">
|
||||
<view class="iconfont icon-jiameng"></view>
|
||||
<view class="u-font-xs">代理商加盟</view>
|
||||
</view>
|
||||
</u-col>
|
||||
<u-col span="3">
|
||||
<view class="gg-order-item">
|
||||
<view class="iconfont icon-tousu"></view>
|
||||
<view class="u-font-xs">投诉与建议</view>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
<u-gap height="30"></u-gap>
|
||||
<u-row gutter="16">
|
||||
<u-col span="3">
|
||||
<view class="gg-order-item">
|
||||
<view class="iconfont icon-shezhi"></view>
|
||||
<view class="u-font-xs">设置</view>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
<u-gap height="30"></u-gap>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// https://www.zhangxinxu.com/sp/svgo/ 利用在线svg转base64功能
|
||||
// 将svg图形转成base64,然后再设置成js变量的形式引入使用
|
||||
// 需要注意将变量设置到data中
|
||||
// 强调:为什么不用iconfont呢?和上面的iconfont一样。因为彩色图标变黑了,色彩没起作用。
|
||||
import {fruit, recommend, invite, discount} from '@/common/svgIcon.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
userInfo: {},
|
||||
fruit,
|
||||
recommend,
|
||||
invite,
|
||||
discount,
|
||||
list: [
|
||||
{
|
||||
image: 'https://cdn.uviewui.com/uview/swiper/1.jpg',
|
||||
title: '昨夜星辰昨夜风,画楼西畔桂堂东'
|
||||
},
|
||||
{
|
||||
image: 'https://cdn.uviewui.com/uview/swiper/2.jpg',
|
||||
title: '身无彩凤双飞翼,心有灵犀一点通'
|
||||
},
|
||||
{
|
||||
image: 'https://cdn.uviewui.com/uview/swiper/3.jpg',
|
||||
title: '谁念西风独自凉,萧萧黄叶闭疏窗,沉思往事立残阳'
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
gotoOrderList(index) {
|
||||
this.$u.route('/pagesOrder/orderList/orderList?current=' + index);
|
||||
},
|
||||
gotoMyPickUpLocation() {
|
||||
uni.navigateTo({
|
||||
url: '/pagesLocation/myPickUpLocation/myPickUpLocation'
|
||||
});
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
this.userInfo = uni.getStorageSync('userInfo');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.gg {
|
||||
height: 100%;
|
||||
|
||||
&-content {
|
||||
height: 100%;
|
||||
background-color: $u-bg-color;
|
||||
}
|
||||
|
||||
&-header {
|
||||
background-image: linear-gradient(to right, rgb(255, 180, 61), rgb(255, 101, 0));
|
||||
height: 300rpx;
|
||||
}
|
||||
|
||||
// 头部区域底部左右圆角区域
|
||||
&-header-bottom {
|
||||
background-image: linear-gradient(to right, rgb(255, 180, 61), rgb(255, 101, 0));
|
||||
height: 100rpx;
|
||||
border-bottom-left-radius: 100rpx;
|
||||
border-bottom-right-radius: 100rpx;
|
||||
}
|
||||
|
||||
&-content-container {
|
||||
margin-left: 20rpx;
|
||||
width: 710rpx;
|
||||
position: absolute;
|
||||
top: 370rpx;
|
||||
|
||||
&-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #fff;
|
||||
border-radius: 25rpx;
|
||||
|
||||
.iconfont {
|
||||
font-size: 50rpx;
|
||||
width: 80rpx;
|
||||
height: 60rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-order-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&-svg-icon {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user