Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop-uniapp

master
paulGao 2022-06-08 16:09:52 +08:00
commit 941dd6015d
17 changed files with 770 additions and 967 deletions

View File

@ -8,6 +8,7 @@ import { mapMutations } from "vuex";
import APPUpdate from "@/plugins/APPUpdate"; import APPUpdate from "@/plugins/APPUpdate";
import { getClipboardData } from "@/js_sdk/h5-copy/h5-copy.js"; import { getClipboardData } from "@/js_sdk/h5-copy/h5-copy.js";
import config from "@/config/config"; import config from "@/config/config";
import storage from "@/utils/storage";
// //
export default { export default {
@ -66,14 +67,14 @@ export default {
onShow() { onShow() {
// #ifndef H5 // #ifndef H5
// this.getClipboard(); this.getClipboard();
// #endif // #endif
// #ifdef APP-PLUS // #ifdef APP-PLUS
console.log(storage.getShow());
if (storage.getShow()) { if (storage.getShow()) {
if(uni.getSystemInfoSync().platform == 'ios'){ if(uni.getSystemInfoSync().platform == 'ios'){
this.$u.route("/pages/tabbar/screen/fullScreen"); this.$u.route("/pages/tabbar/screen/fullScreen");
// uni.reLaunch({ url: "/pages/tabbar/screen/fullScreen" });
} }
} }
// #endif // #endif

View File

@ -473,6 +473,8 @@
color: #999 !important; color: #999 !important;
font-size: 24rpx; font-size: 24rpx;
margin:0 20rpx; margin:0 20rpx;
display: flex;
justify-content: center;
} }
.goods-header { .goods-header {
@ -493,6 +495,7 @@
.goods-price { .goods-price {
color: $price-color; color: $price-color;
line-height: 80rpx; line-height: 80rpx;
margin-right: 20rpx;
>* { >* {
color: $price-color; color: $price-color;
line-height: 80rpx; line-height: 80rpx;

View File

@ -0,0 +1,10 @@
## 商品列表展示
### OBJECT 参数说明
| 属性 | 说明 | 类型 | 必填 |
| ----------- | ---------------------------------------------------------- | ------- | ---- |
| `res` | 显示数据 | Array | 是 |
| `type` | 商品展示类型 oneColumns twoColumns ,默认展示一行两列商品 | String | 否 |
| `storeName` | 是否展示店铺名称,默认展示 | Boolean | 否 |

View File

@ -0,0 +1,293 @@
<template>
<view>
<!-- 一行两列商品展示 -->
<view class="goods-list" v-if="type == 'twoColumns'">
<view v-for="(item, index) in res" :key="index" class="goods-item">
<view class="image-wrapper" @click="navigateToDetailPage(item)">
<u-image :src="item.content.thumbnail" width="100%" height='330rpx' mode="aspectFill">
<u-loading slot="loading"></u-loading>
</u-image>
</view>
<view class="goods-detail">
<div class="title clamp" @click="navigateToDetailPage(item)">{{ item.content.goodsName }}</div>
<view class="price-box" @click="navigateToDetailPage(item)">
<div class="price" v-if="item.content.price!=undefined">
¥<span>{{ formatPrice(item.content.price )[0] }} </span>.{{
formatPrice(item.content.price )[1]
}}
</div>
</view>
<div class="promotion" @click="navigateToDetailPage(item)">
<div v-if="item.content.salesModel == 'WHOLESALE'">
<span></span>
</div>
<div v-for="(promotionItem,promotionIndex) in getPromotion(item)" :key="promotionIndex">
<span v-if="promotionItem.indexOf('COUPON') != -1"></span>
<span v-if="promotionItem.indexOf('FULL_DISCOUNT') != -1"></span>
<span v-if="promotionItem.indexOf('SECKILL') != -1"></span>
</div>
</div>
<div class="count-config" @click="navigateToDetailPage(item)">
<span>已售 {{ item.content.buyCount || "0" }}</span>
<span>{{ item.content.commentNum || "0" }}条评论</span>
</div>
<div class="store-seller-name" v-if="storeName" @click="navigateToStoreDetailPage(item)">
<div class="text-hidden" >
<u-tag style="margin-right: 10rpx" size="mini" mode="dark" v-if="item.selfOperated"
text="自营" type="error" />
<span >{{ item.content.storeName || "暂无" }}</span>
</div>
<span>
<u-icon name="arrow-right"></u-icon>
</span>
</div>
</view>
</view>
</view>
<!-- 一行一列商品展示 -->
<div v-if="type == 'oneColumns'">
<div v-for="(item, index) in res" :key="index" class="goods-row">
<div class="flex goods-col">
<div class="goods-img" @click="navigateToDetailPage(item)">
<u-image width="230rpx" border-radius='16' height="230rpx" :src="item.content.thumbnail">
<u-loading slot="loading"></u-loading>
</u-image>
</div>
<div class="goods-detail">
<div class="title clamp3" @click="navigateToDetailPage(item)">{{ item.content.goodsName }}</div>
<view class="price-box" @click="navigateToDetailPage(item)">
<div class="price" v-if="item.content.price!=undefined">
¥<span>{{ formatPrice(item.content.price )[0] }} </span>.{{
formatPrice(item.content.price )[1]
}}
</div>
</view>
<div class="promotion" @click="navigateToDetailPage(item)">
<div v-if="item.content.salesModel == 'WHOLESALE'">
<span></span>
</div>
<div v-for="(promotionItem,promotionIndex) in getPromotion(item)" :key="promotionIndex">
<span v-if="promotionItem.indexOf('COUPON') != -1"></span>
<span v-if="promotionItem.indexOf('FULL_DISCOUNT') != -1"></span>
<span v-if="promotionItem.indexOf('SECKILL') != -1"></span>
</div>
</div>
<div style="overflow: hidden" @click="navigateToDetailPage(item)" class="count-config">
<span style="float: left; font-size: 22rpx">已售 {{ item.content.buyCount || '0' }}</span>
<span style="float: right; font-size: 22rpx">{{ item.content.commentNum || '0' }}条评论</span>
</div>
<div style="overflow: hidden" @click="navigateToStoreDetailPage(item)" class="count-config">
<div class="text-hidden" v-if="storeName">
<u-tag style="margin-right: 10rpx" size="mini" mode="dark" v-if="item.selfOperated"
text="自营" type="error" />
<span class="line1-store-name">{{ item.content.storeName }}</span>
<span class="to-store">进店<u-icon size="24" name="arrow-right" color="#666"></u-icon>
</span>
</div>
<span>
<u-icon name="arrow-right" color="#c5c5c5"></u-icon>
</span>
</div>
</div>
</div>
</div>
</div>
</view>
</template>
<script>
export default {
data() {
return {}
},
props: {
//
res: {
type: Array,
default: () => {
return []
}
},
//
type: {
type: String,
default: 'twoColumns',
validator() {
return ['twoColumns', 'oneColumns']
}
},
storeName: {
type: Boolean,
default: true
}
},
methods: {
// 1999 --> [1999,00]
formatPrice(val) {
if (typeof val == "undefined") {
return val;
}
return val.toFixed(2).split(".");
},
//
getPromotion(item) {
if (item.promotionMap) {
let array = [];
Object.keys(item.promotionMap).forEach((child) => {
if (!array.includes(child.split("-")[0])) {
array.push(child.split("-")[0]);
}
});
return array;
}
},
//
navigateToDetailPage(item) {
uni.navigateTo({
url: `/pages/product/goods?id=${item.content.id}&goodsId=${item.content.goodsId}`,
});
},
//
navigateToStoreDetailPage(item) {
uni.navigateTo({
url: `/pages/product/shopPage?id=${item.content.storeId}`,
});
},
}
}
</script>
<style lang='scss' scoped>
/* 商品列表 */
.goods-list {
display: flex;
flex-wrap: wrap;
margin: 10rpx 20rpx 284rpx;
width: 100%;
>.goods-item {
background-color: #ffffff;
display: flex;
border-radius: 16rpx;
flex-direction: column;
width: calc(50% - 30rpx);
margin-bottom: 20rpx;
padding-bottom: 20rpx;
&:nth-child(2n + 1) {
margin-right: 20rpx;
}
.image-wrapper {
width: 100%;
height: 330rpx;
border-radius: 16rpx 16rpx 0 0;
overflow: hidden;
padding: 0;
}
}
.count-config,
.store-seller-name {
font-size: $font-sm;
}
.text-hidden {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.goods-row {
background: #fff;
padding: 16rpx;
>.goods-col {
display: flex;
>.goods-img {
overflow: hidden;
flex: 4;
}
>.goods-detail {
flex: 7;
}
}
}
.goods-detail {
margin: 0 20rpx;
>.title {
font-size: $font-base;
color: $font-color-dark;
line-height: 1.5;
height: 84rpx;
padding: 10rpx 0 0;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
.promotion {
margin-top: 4rpx;
display: flex;
div {
span {
font-size: 24rpx;
color: $light-color;
margin-right: 10rpx;
padding: 0 4rpx;
border-radius: 2rpx;
}
}
}
.store-seller-name {
color: #666;
overflow: hidden;
display: flex;
justify-content: space-between;
}
.count-config {
padding: 5rpx 0;
color: #666;
display: flex;
font-size: 24rpx;
justify-content: space-between;
}
>.price-box {
margin-top: 10rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding-right: 10rpx;
font-size: 24rpx;
color: $font-color-light;
>.price {
font-size: 26rpx;
line-height: 1;
color: $main-color;
font-weight: bold;
/deep/ span:nth-of-type(1) {
font-size: 38rpx;
}
}
}
}
</style>

View File

@ -1,27 +1,11 @@
<template> <template>
<div> <div>
<div class="goods-recommend">{{title ? `--${title}-- `:''}}</div> <div class="goods-recommend">{{title ? `--${title}-- `:''}}</div>
<div class="goods-list"> <goodsTemplate :res='goodsList' />
<div @click="handleClick(item)" class="goods-item" v-for="(item, item_index) in goodsList" :key="item_index">
<div class="goods-img">
<u-image :src="item.content.thumbnail" mode="aspectFill" height="350rpx" width="100%">
<u-loading slot="loading"></u-loading>
</u-image>
</div>
<div class="goods-desc">
<div class="goods-title">
{{ item.content.goodsName }}
</div>
<div class="goods-bottom">
<div class="goods-price">{{ item.content.price | unitPrice }}</div>
</div>
</div>
</div>
</div>
</div> </div>
</template> </template>
<script> <script>
import goodsTemplate from '@/components/m-goods-list/list'
import { getGoodsList } from "@/api/goods.js"; import { getGoodsList } from "@/api/goods.js";
export default { export default {
data() { data() {
@ -50,6 +34,7 @@ export default {
default: "", default: "",
}, },
}, },
components:{goodsTemplate},
mounted() { mounted() {
this.initGoods(); this.initGoods();
}, },

View File

@ -1,6 +1,6 @@
{ {
"name" : "lili商城", "name" : "lili商城",
"appid" : "__UNI__83F0C3D", "appid" : "__UNI__EC9FD60",
"description" : "", "description" : "",
"versionName" : "4.2.5", "versionName" : "4.2.5",
"versionCode" : 4000250, "versionCode" : 4000250,

View File

@ -1,9 +1,9 @@
<template> <template>
<view class="coupon-center"> <view class="coupon-center">
<swiper class="swiper-box"> <div class="swiper-box">
<swiper-item class="swiper-item"> <div class="swiper-item">
<scroll-view class="scroll-v" enableBackToTop="true" scroll-y @scrolltolower="loadMore"> <div class="scroll-v" enableBackToTop="true" scroll-y>
<u-empty mode="coupon" text="没有优惠券了" v-if="whetherEmpty"></u-empty> <u-empty mode="coupon" style='margin-top: 20%;' text="没有优惠券了" v-if="whetherEmpty"></u-empty>
<view v-else class="coupon-item" v-for="(item, index) in couponList" :key="index"> <view v-else class="coupon-item" v-for="(item, index) in couponList" :key="index">
<view class="left"> <view class="left">
<view class="wave-line"> <view class="wave-line">
@ -23,10 +23,11 @@
<view class="right"> <view class="right">
<view> <view>
<!-- 根据scopeType 判断是否是 平台品类或店铺 --> <!-- 根据scopeType 判断是否是 平台品类或店铺 -->
<view v-if="item.scopeType"> <view class="coupon-title wes-3" v-if="item.scopeType">
<span v-if="item.scopeType == 'ALL' && item.storeId == '0'"></span> <span v-if="item.scopeType == 'ALL' && item.storeId == 'platform'"></span>
<span v-if="item.scopeType == 'PORTION_CATEGORY'"></span> <span v-if="item.scopeType == 'PORTION_CATEGORY'"></span>
<view v-else>{{ item.storeName == 'platform' ? '' :item.storeName+'' }}使</view> <view v-else>{{ item.storeName == 'platform' ? '' :item.storeName+'' }}使
</view>
</view> </view>
<view v-if="item.endTime">{{ item.endTime.split(" ")[0] }}</view> <view v-if="item.endTime">{{ item.endTime.split(" ")[0] }}</view>
</view> </view>
@ -37,17 +38,21 @@
<view class="bg-quan"> </view> <view class="bg-quan"> </view>
</view> </view>
</view> </view>
<uni-load-more :status="loadStatus"></uni-load-more>
</scroll-view> </div>
</swiper-item> </div>
</swiper> </div>
</view> </view>
</template> </template>
<script> <script>
import { receiveCoupons } from "@/api/members.js"; import {
import { getAllCoupons } from "@/api/promotions.js"; receiveCoupons
export default { } from "@/api/members.js";
import {
getAllCoupons
} from "@/api/promotions.js";
export default {
data() { data() {
return { return {
loadStatus: "more", // loadStatus: "more", //
@ -57,13 +62,18 @@ export default {
pageNumber: 1, pageNumber: 1,
pageSize: 10, pageSize: 10,
}, },
storeId: "", // id storeId: "", // id,
couponData: ""
}; };
}, },
onLoad(option) { onLoad(option) {
this.storeId = option.storeId; this.storeId = option.storeId;
this.getCoupon(); this.getCoupon();
}, },
onReachBottom() {
this.loadMore()
},
onPullDownRefresh() { onPullDownRefresh() {
// //
this.params.pageNumber = 1; this.params.pageNumber = 1;
@ -78,21 +88,26 @@ export default {
uni.showLoading({ uni.showLoading({
title: "加载中", title: "加载中",
}); });
let submitData = { ...this.params }; let submitData = {
...this.params
};
// //
this.storeId ? (submitData = { ...this.params, storeId: this.storeId }): "", this.storeId ? (submitData = {
...this.params,
storeId: this.storeId
}) : "",
getAllCoupons(submitData) getAllCoupons(submitData)
.then((res) => { .then((res) => {
uni.hideLoading(); uni.hideLoading();
uni.stopPullDownRefresh(); uni.stopPullDownRefresh();
if (res.data.code == 200) { if (res.data.code == 200) {
// //
let data = res.data.result; this.couponData = res.data.result
if (data.total == 0) { if (this.couponData.total == 0) {
// //
this.whetherEmpty = true; this.whetherEmpty = true;
} else { } else {
this.couponList.push(...data.records); this.couponList.push(...this.couponData.records);
this.loadStatus = "noMore"; this.loadStatus = "noMore";
} }
} }
@ -123,9 +138,9 @@ export default {
* 加载更多 * 加载更多
*/ */
loadMore() { loadMore() {
if (this.loadStatus != "noMore") { if (this.couponData.total > this.params.pageNumber * this.params.pageSize) {
this.params.pageNumber++; this.params.pageNumber++;
this.getAllCoupons(); this.getCoupon();
} }
}, },
}, },
@ -134,52 +149,18 @@ export default {
url: "/pages/cart/coupon/couponIntro", url: "/pages/cart/coupon/couponIntro",
}); });
}, },
}; };
</script> </script>
<style> <style>
page { page {
height: 100%; height: 100%;
} }
</style> </style>
<style lang="scss" scoped> <style lang="scss" scoped>
.coupon-center { .coupon-center {
height: 100%; height: 100%;
.couponList-scroll-content {
position: relative;
width: 100%;
display: flex;
white-space: nowrap;
align-items: center;
justify-content: space-between;
align-items: center;
background-color: $main-color;
color: #ffffff;
.tab-item {
width: 160rpx;
height: 80rpx;
line-height: 60rpx;
text-align: center;
display: inline-block;
}
.active {
border-bottom: 2px solid #ffffff;
broder-width: 60rpx;
font-size: 30rpx;
font-weight: 700;
padding-bottom: 4rpx;
}
}
.swiper-box { .swiper-box {
height: 100%;
.scroll-v {
height: 100%;
}
.coupon-item { .coupon-item {
display: flex; display: flex;
align-items: center; align-items: center;
@ -191,6 +172,7 @@ page {
width: 260rpx; width: 260rpx;
background-color: $light-color; background-color: $light-color;
position: relative; position: relative;
.message { .message {
color: $font-color-white; color: $font-color-white;
display: flex; display: flex;
@ -226,6 +208,7 @@ page {
margin-top: 4rpx; margin-top: 4rpx;
} }
} }
.circle { .circle {
width: 40rpx; width: 40rpx;
height: 40rpx; height: 40rpx;
@ -234,10 +217,12 @@ page {
border-radius: 50%; border-radius: 50%;
z-index: 111; z-index: 111;
} }
.circle-top { .circle-top {
top: -20rpx; top: -20rpx;
right: -20rpx; right: -20rpx;
} }
.circle-bottom { .circle-bottom {
bottom: -20rpx; bottom: -20rpx;
right: -20rpx; right: -20rpx;
@ -254,11 +239,16 @@ page {
background-color: #ffffff; background-color: #ffffff;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
> view:nth-child(1) {
>view:nth-child(1) {
color: #666666; color: #666666;
margin-left: 20rpx; margin-left: 20rpx;
line-height: 3em; display: flex;
> view:nth-child(1) { height: 100%;
flex-direction: column;
justify-content: space-around;
>view:nth-child(1) {
color: #ff6262; color: #ff6262;
font-size: 30rpx; font-size: 30rpx;
} }
@ -295,5 +285,10 @@ page {
} }
} }
} }
} }
.coupon-title {
width: 260rpx;
}
</style> </style>

View File

@ -1,12 +1,13 @@
<template> <template>
<view class="box"> <view class="box">
<view class="box-tips"> <view class="box-tips">
<h2> <h2 class='h2'>
{{verificationTitle[validateFlage==false ? 0 : 1].title}} {{verificationTitle[validateFlage==false ? 0 : 1].title}}
</h2> </h2>
<view class="verification">{{verificationTitle[step].desc}}</view> <view class="verification">{{verificationTitle[step].desc}}</view>
</view> </view>
<u-form :model="codeForm" class="form" ref="validateCodeForm"> <view class="form">
<u-form :model="codeForm" ref="validateCodeForm">
<view v-if="!validateFlage"> <view v-if="!validateFlage">
<u-form-item label-width="120" label="手机号" prop="mobile"> <u-form-item label-width="120" label="手机号" prop="mobile">
<u-input maxlength="11" v-model="codeForm.mobile" placeholder="请输入您的手机号" /> <u-input maxlength="11" v-model="codeForm.mobile" placeholder="请输入您的手机号" />
@ -36,6 +37,7 @@
</view> </view>
</u-form> </u-form>
</view> </view>
</view>
</template> </template>
<script> <script>
@ -221,8 +223,8 @@ export default {
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import url("../../../passport/login.scss"); @import url("@/pages/passport/login.scss");
.u-form-item { /deep/ .u-form-item {
margin: 40rpx 0; margin: 40rpx 0;
} }
.sendCode { .sendCode {
@ -230,6 +232,10 @@ export default {
display: flex; display: flex;
} }
} }
.h2{
font-size: 40rpx;
font-weight: bold;
}
page { page {
background: #fff; background: #fff;
} }
@ -248,4 +254,5 @@ page {
color: #999; color: #999;
margin-top: 10rpx; margin-top: 10rpx;
} }
</style> </style>

View File

@ -22,19 +22,6 @@
} }
} }
.promotion {
margin-top: 4rpx;
display: flex;
div {
span {
font-size: 24rpx;
color: $light-color;
margin-right: 10rpx;
padding: 0 4rpx;
border-radius: 2rpx;
}
}
}
.status_bar { .status_bar {
height: var(--status-bar-height); height: var(--status-bar-height);
background: #fff !important; background: #fff !important;
@ -437,180 +424,13 @@ view {
margin-left: 4rpx; margin-left: 4rpx;
font-size: 26rpx; font-size: 26rpx;
color: #888; color: #888;
} }
.xia { .xia {
transform: scaleY(-1); transform: scaleY(-1);
} }
} }
.cate-item {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 80rpx;
position: relative;
font-size: 44rpx;
&:after {
content: "";
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
border-left: 1px solid #ddd;
width: 0;
height: 36rpx;
}
}
} }
/* 分类 */
.cate-mask {
position: fixed;
left: 0;
top: var(--window-top);
bottom: 0;
width: 100%;
background: rgba(0, 0, 0, 0);
z-index: 95;
transition: 0.3s;
.cate-content {
width: 630rpx;
height: 100%;
background: #fff;
float: right;
transform: translateX(100%);
transition: 0.3s;
}
&.none {
display: none;
}
&.show {
background: rgba(0, 0, 0, 0.4);
.cate-content {
transform: translateX(0);
}
}
}
.cate-list {
display: flex;
flex-direction: column;
height: 100%;
.cate-item {
display: flex;
align-items: center;
height: 90rpx;
padding-left: 30rpx;
font-size: 28rpx;
color: #555;
position: relative;
}
.two {
height: 64rpx;
color: #303133;
font-size: 30rpx;
background: #f8f8f8;
}
}
.price-box {
margin-top: 10rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding-right: 10rpx;
font-size: 24rpx;
color: $font-color-light;
}
.price {
font-size: 26rpx;
line-height: 1;
color: $main-color;
font-weight: bold;
/deep/ span:nth-of-type(1) {
font-size: 38rpx;
}
}
/* 商品列表 */
.goods-list {
display: flex;
flex-wrap: wrap;
margin: 10rpx 20rpx 284rpx;
// background: #fff;
width: 100%;
.goods-item {
background-color: #ffffff;
display: flex;
border-radius: 16rpx;
flex-direction: column;
width: calc(50% - 30rpx);
margin-bottom: 20rpx;
padding-bottom: 20rpx;
&:nth-child(2n + 1) {
margin-right: 20rpx;
}
.goods-detail {
margin: 0 20rpx;
}
}
.image-wrapper {
width: 100%;
height: 330rpx;
border-radius: 16rpx 16rpx 0 0;
overflow: hidden;
padding: 0;
image {
width: 100%;
height: 100%;
opacity: 1;
border-radius: 16rpx 16rpx 0 0;
}
}
.title {
font-size: $font-base;
color: $font-color-dark;
line-height: 1.5;
height: 84rpx;
padding: 10rpx 0 0;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
.count-config,
.store-seller-name {
font-size: $font-sm;
}
.text-hidden {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.status_bar { .status_bar {
height: var(--status-bar-height); height: var(--status-bar-height);
width: 100%; width: 100%;

View File

@ -82,50 +82,7 @@
<div v-if="isSWitch"> <div v-if="isSWitch">
<scroll-view :style="{ height: goodsHeight }" enableBackToTop="true" lower-threshold="250" <scroll-view :style="{ height: goodsHeight }" enableBackToTop="true" lower-threshold="250"
@scrolltolower="loadmore()" scroll-with-animation scroll-y class="scoll-page"> @scrolltolower="loadmore()" scroll-with-animation scroll-y class="scoll-page">
<div class="goods-class"> <goodsList :res='goodsList' type='oneColumns' />
<div v-for="(item, index) in goodsList" :key="index" class="goods-row">
<div class="flex goods-col">
<div class="goods-img" @click="navigateToDetailPage(item)">
<u-image width="230rpx" height="230rpx" :src="item.content.thumbnail">
<u-loading slot="loading"></u-loading>
</u-image>
</div>
<div class="goods-detail">
<div class="title clamp3" @click="navigateToDetailPage(item)">{{ item.content.goodsName }}</div>
<view class="price-box" @click="navigateToDetailPage(item)">
<div class="price" v-if="item.content.price!=undefined">
¥<span>{{ formatPrice(item.content.price )[0] }} </span>.{{
formatPrice(item.content.price )[1]
}}
</div>
</view>
<div class="promotion" @click="navigateToDetailPage(item)">
<div v-for="(promotionItem,promotionIndex) in getPromotion(item)" :key="promotionIndex">
<span v-if="promotionItem.indexOf('COUPON') != -1"></span>
<span v-if="promotionItem.indexOf('FULL_DISCOUNT') != -1"></span>
<span v-if="promotionItem.indexOf('SECKILL') != -1"></span>
</div>
</div>
<div style="overflow: hidden" @click="navigateToDetailPage(item)" class="count-config">
<span style="float: left; font-size: 22rpx">已售 {{ item.content.buyCount || '0' }}</span>
<span style="float: right; font-size: 22rpx">{{ item.content.commentNum || '0' }}条评论</span>
</div>
<div style="overflow: hidden" @click="navigateToStoreDetailPage(item)" class="count-config">
<div class="text-hidden">
<u-tag style="margin-right: 10rpx" size="mini" mode="dark" v-if="item.selfOperated" text="自营"
type="error" />
<span class="line1-store-name">{{ item.content.storeName }}</span>
<span class="to-store">进店<u-icon size="24" name="arrow-right" color="#666"></u-icon></span>
</div>
<span>
<u-icon name="arrow-right" color="#c5c5c5"></u-icon>
</span>
</div>
</div>
</div>
</div>
</div>
<uni-load-more :status="loadingType" @loadmore="loadmore()"></uni-load-more> <uni-load-more :status="loadingType" @loadmore="loadmore()"></uni-load-more>
</scroll-view> </scroll-view>
</div> </div>
@ -136,49 +93,7 @@
"> ">
<scroll-view :style="{ height: goodsHeight }" scroll-anchoring enableBackToTop="true" <scroll-view :style="{ height: goodsHeight }" scroll-anchoring enableBackToTop="true"
@scrolltolower="loadmore()" scroll-with-animation scroll-y lower-threshold="250" class="scoll-page"> @scrolltolower="loadmore()" scroll-with-animation scroll-y lower-threshold="250" class="scoll-page">
<view class="goods-list"> <goodsList :res='goodsList' />
<view v-for="(item, index) in goodsList" :key="index" class="goods-item">
<view class="image-wrapper" @click="navigateToDetailPage(item)">
<image :src="item.content.thumbnail" mode="aspectFill"></image>
</view>
<view class="goods-detail">
<div class="title clamp" @click="navigateToDetailPage(item)">{{ item.content.goodsName }}</div>
<view class="price-box" @click="navigateToDetailPage(item)">
<div class="price" v-if="item.content.price!=undefined">
¥<span>{{ formatPrice(item.content.price )[0] }} </span>.{{
formatPrice(item.content.price )[1]
}}
</div>
</view>
<div class="promotion" @click="navigateToDetailPage(item)">
<div v-if="item.content.salesModel == 'WHOLESALE'">
<span></span>
</div>
<div v-for="(promotionItem,promotionIndex) in getPromotion(item)" :key="promotionIndex">
<span v-if="promotionItem.indexOf('COUPON') != -1"></span>
<span v-if="promotionItem.indexOf('FULL_DISCOUNT') != -1"></span>
<span v-if="promotionItem.indexOf('SECKILL') != -1"></span>
</div>
</div>
<div class="count-config" @click="navigateToDetailPage(item)">
<span>已售 {{ item.content.buyCount || "0" }}</span>
<span>{{ item.content.commentNum || "0" }}条评论</span>
</div>
<div class="store-seller-name" @click="navigateToStoreDetailPage(item)">
<div class="text-hidden">
<u-tag style="margin-right: 10rpx" size="mini" mode="dark" v-if="item.selfOperated" text="自营"
type="error" />
<span>{{ item.content.storeName || "暂无" }}</span>
</div>
<span>
<u-icon name="arrow-right"></u-icon>
</span>
</div>
</view>
</view>
</view>
<uni-load-more :status="loadingType"></uni-load-more> <uni-load-more :status="loadingType"></uni-load-more>
</scroll-view> </scroll-view>
</div> </div>
@ -277,7 +192,7 @@
<script> <script>
import { getGoodsList, getGoodsRelated } from "@/api/goods.js"; import { getGoodsList, getGoodsRelated } from "@/api/goods.js";
import goodsList from '@/components/m-goods-list/list.vue'
import { getHotKeywords } from "@/api/home.js"; import { getHotKeywords } from "@/api/home.js";
import mSearch from "@/components/m-search-revision/m-search-revision.vue"; import mSearch from "@/components/m-search-revision/m-search-revision.vue";
import storage from "@/utils/storage"; import storage from "@/utils/storage";
@ -343,6 +258,7 @@ export default {
routerVal: "", routerVal: "",
}; };
}, },
onPageScroll(e) { onPageScroll(e) {
console.log(e); console.log(e);
this.scrollTop = e.scrollTop; this.scrollTop = e.scrollTop;
@ -375,6 +291,7 @@ export default {
}, },
components: { components: {
mSearch, mSearch,
goodsList
}, },
watch: { watch: {
/** /**
@ -766,6 +683,9 @@ export default {
doSearchSwitch() { doSearchSwitch() {
this.isSWitch = !this.isSWitch; this.isSWitch = !this.isSWitch;
this.isShowSeachGoods = true; this.isShowSeachGoods = true;
this.params.pageNumber = 1
this.params.pageSize = 10
this.loadData("refresh", 1);
}, },
/** /**

View File

@ -7,7 +7,7 @@
<!-- 分享 --> <!-- 分享 -->
<shares <shares
v-if="shareFlage && goodsDetail.id" v-if="enableShare && goodsDetail.id"
:skuId="this.routerVal.id" :skuId="this.routerVal.id"
:goodsId="this.routerVal.goodsId" :goodsId="this.routerVal.goodsId"
:link=" :link="
@ -19,7 +19,7 @@
:thumbnail="goodsDetail.thumbnail" :thumbnail="goodsDetail.thumbnail"
:goodsName="goodsDetail.goodsName" :goodsName="goodsDetail.goodsName"
type="goods" type="goods"
@close="shareFlage = false" @close="enableShare = false"
/> />
<popups <popups
v-model="popupsSwitch" v-model="popupsSwitch"
@ -116,7 +116,7 @@
<view class="card-box top-radius-0" id="main2"> <view class="card-box top-radius-0" id="main2">
<!-- 活动不显示价钱 --> <!-- 活动不显示价钱 -->
<view v-if="!promotionFlag" class="desc-bold -goods-msg"> <view v-if="isSeckill || isGroup" class="desc-bold -goods-msg">
<view class="-goods-flex"> <view class="-goods-flex">
<view class="desc-bold"> <view class="desc-bold">
{{ goodsDetail.goodsName || "" }} {{ goodsDetail.goodsName || "" }}
@ -150,9 +150,14 @@
</span> </span>
<span v-else> <span v-else>
<span>¥</span <span v-if="wholesaleList.length">
><span class="price">{{ formatPrice(goodsDetail.price)[0] }}</span <span>¥</span><span class="price">{{ formatPrice(wholesaleList[wholesaleList.length-1].price)[0] }}</span>.{{ formatPrice(wholesaleList[wholesaleList.length-1].price)[1] }}
>.{{ formatPrice(goodsDetail.price)[1] }} ~
<span>¥</span><span class="price">{{ formatPrice(wholesaleList[0].price)[0] }}</span>.{{ formatPrice(wholesaleList[0].price)[1] }}
</span>
<span v-else>
<span>¥</span><span class="price">{{ formatPrice(goodsDetail.price)[0] }}</span>.{{ formatPrice(goodsDetail.price)[1] }}
</span>
</span> </span>
</view> </view>
<view class="-goods-price" v-else> <view class="-goods-price" v-else>
@ -405,7 +410,6 @@ export default {
return { return {
setup, setup,
promotionShow: false, // promotionShow: false, //
promotionFlag: true, //
// #ifdef H5 // #ifdef H5
navbarListX: 110, //x navbarListX: 110, //x
navbarListY: 80, //y navbarListY: 80, //y
@ -442,9 +446,10 @@ export default {
}, },
], ],
popupsSwitch: false, // popupsSwitch: false, //
shareFlage: false, enableShare: false,
selectedGoods: "", // selectedGoods: "", //
isGroup: false, // isGroup: false, //
isSeckill:false, //
pointDetail: "", // pointDetail: "", //
assemble: "", //sku assemble: "", //sku
navbarOnlyBack: { navbarOnlyBack: {
@ -480,7 +485,6 @@ export default {
id: "4", id: "4",
}, },
], ],
oldtabScrollTop: 0,
tabScrollTop: null, tabScrollTop: null,
scrollArr: [], scrollArr: [],
scrollId: "1", scrollId: "1",
@ -542,10 +546,7 @@ export default {
this.$refs.popupGoods.buyType = "PINTUAN"; this.$refs.popupGoods.buyType = "PINTUAN";
clearInterval(timer); clearInterval(timer);
}, 100); }, 100);
this.promotionFlag = false;
} else { } else {
this.promotionFlag = true;
this.$refs.popupGoods.buyType = ""; this.$refs.popupGoods.buyType = "";
} }
}, },
@ -679,6 +680,10 @@ export default {
if (item.indexOf("POINTS_GOODS") == 0) { if (item.indexOf("POINTS_GOODS") == 0) {
this.pointDetail = this.PromotionList[item]; this.pointDetail = this.PromotionList[item];
} }
//
if (item.indexOf("SECKILL") == 0) {
this.isSeckill = true
}
}); });
// //
this.imgList = this.goodsDetail.goodsGalleryList; this.imgList = this.goodsDetail.goodsGalleryList;
@ -1069,7 +1074,7 @@ export default {
* 点击分享 * 点击分享
*/ */
async shareChange() { async shareChange() {
this.shareFlage = true; this.enableShare = true;
}, },
}, },
}; };

View File

@ -1,169 +1,20 @@
<template> <template>
<view class="recommend-box" > <view class="recommend-box" >
<h4 class="goods-recommend-title">宝贝推荐</h4> <h4 class="goods-recommend-title">宝贝推荐</h4>
<view class="like-goods-list"> <goodsList :res='res' v-if="res" :storeName="false" />
<view class="like-goods-list">
<view
class="like-goods-item"
@click="clickGoods(item)"
v-for="(item, index) in res"
:key="index"
>
<u-image
:fade="true"
duration="450"
:lazy-load="true"
:src="item.content.thumbnail"
width="330rpx"
height="330rpx"
class="like-goods-uimage"
>
<u-loading slot="loading"></u-loading>
</u-image>
<view style="background-color: #ffffff; width: 100%">
<view class="name">{{ item.content.goodsName }}</view>
<view class="price-sales">
<div class="item-price" v-if="item.content.price != undefined">
<span>{{ formatPrice(item.content.price)[0] }}</span>
.{{formatPrice(item.content.price)[1]}}
<!-- <text v-if="item.point != undefined">+{{ item.point }}</text> -->
</div>
</view>
</view>
</view>
</view>
</view>
</view> </view>
</template> </template>
<script> <script>
import goodsList from '@/components/m-goods-list/list.vue'
export default { export default {
props: ["res"], props: ["res"],
components:{goodsList},
methods: { methods: {
//
clickGoods(val) {
uni.navigateTo({
url: `/pages/product/goods?id=${val.content.id}&goodsId=${val.content.goodsId}`
});
},
// 1999 --> [1999,00]
formatPrice(val) {
if (typeof val == "undefined") {
return val;
}
return val.toFixed(2).split(".");
}
} }
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import "../mp-goods.scss";
@import "../product.scss"; @import "../product.scss";
.goods_recomm {
padding: 12px 0 20rpx 20rpx;
color: #000;
font-size: 30rpx;
font-weight: 400;
margin-bottom: 28rpx;
}
.like-goods-uimage {
/deep/ .u-image {
height: 350rpx !important;
}
width: 100%;
}
.recommend-box {
background-color: #ffffff;
width: 100%;
padding-bottom: 120rpx;
.title {
width: 120rpx;
height: 42rpx;
font-size: 30rpx;
font-weight: 700;
text-align: left;
color: #333333;
margin-left: 20rpx;
}
}
.like-goods-list {
display: flex;
width: 100%;
flex-wrap: wrap;
}
.like-goods-item {
padding: 0 !important;
width: 48%;
margin: 0 1% 10rpx 1%;
background: #f7f7f7;
border-radius: 12rpx;
overflow: hidden;
/deep/ .u-image {
width: 100%;
}
}
.like-goods-list {
// background-color: #f8f8f8;
width: 100%;
margin-bottom: 100rpx;
.name {
padding: 14rpx 8rpx 0 8rpx;
color: #333;
font-size: 24rpx;
display: -webkit-box;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
background: #f7f7f7;
height: 80rpx;
}
.price-sales {
padding: 8rpx;
background: #f7f7f7;
display: flex;
justify-content: space-between;
align-items: center;
.item-price {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 26rpx;
text-align: left;
color: $price-color;
line-height: 23px;
font-weight: bold;
> span {
font-size: 32rpx;
}
}
.sales {
line-height: 23px;
font-size: 22rpx;
text-align: left;
letter-spacing: 0;
color: #cccccc;
// padding-right: 10rpx;
}
}
}
</style> </style>

View File

@ -60,18 +60,7 @@
<!-- 商品 --> <!-- 商品 -->
<div class="contant" v-if="current == 0"> <div class="contant" v-if="current == 0">
<view v-if="!goodsList.length" class="empty"></view> <view v-if="!goodsList.length" class="empty"></view>
<view v-else class="item" v-for="(item,index) in goodsList" :key="index" @click="navigateToGoodsDetail(item)"> <goodsTemplate :res="goodsList" :storeName="false" />
<u-image width="100%" height="330rpx" mode="aspectFit" :src="item.content.thumbnail">
<u-loading slot="loading"></u-loading>
</u-image>
<div class="name wes-2">{{ item.content.goodsName }}</div>
<div class="price">
<div>{{ item.content.price | unitPrice }}</div>
</div>
<view class="buyCount">
<div>已售 {{ item.content.buyCount || "0" }}</div>
</view>
</view>
</div> </div>
<!-- 全部分类 --> <!-- 全部分类 -->
<div class="category" v-if="current == 1"> <div class="category" v-if="current == 1">
@ -95,6 +84,7 @@
<script> <script>
import { getStoreBaseInfo, getStoreCategory } from "@/api/store.js"; import { getStoreBaseInfo, getStoreCategory } from "@/api/store.js";
import goodsTemplate from '@/components/m-goods-list/list'
import { import {
receiveCoupons, receiveCoupons,
deleteStoreCollection, deleteStoreCollection,
@ -129,6 +119,7 @@ export default {
val == 0 ? ()=>{ this.goodsList = []; this.getGoodsData()} : this.getCategoryData(); val == 0 ? ()=>{ this.goodsList = []; this.getGoodsData()} : this.getCategoryData();
}, },
}, },
components:{goodsTemplate},
/** /**
* 加载 * 加载
@ -188,30 +179,34 @@ export default {
* 联系客服 * 联系客服
*/ */
linkKefuDetail() { linkKefuDetail() {
// // //
// #ifdef MP-WEIXIN // // #ifdef MP-WEIXIN
// const params = {
// // originalPrice: this.goodsDetail.original || this.goodsDetail.price,
// uuid: storage.getUuid(),
// token: storage.getAccessToken(),
// sign: this.storeInfo.yzfSign,
// mpSign: this.storeInfo.yzfMpSign,
// };
// uni.navigateTo({
// url:
// "/pages/product/customerservice/index?params=" +
// encodeURIComponent(JSON.stringify(params)),
// });
// // #endif
// // #ifndef MP-WEIXIN
// const sign = this.storeInfo.yzfSign;
// uni.navigateTo({
// url:
// "/pages/tabbar/home/web-view?src=https://yzf.qq.com/xv/web/static/chat/index.html?sign=" +
// sign,
// });
// // #endif
const params = {
// originalPrice: this.goodsDetail.original || this.goodsDetail.price,
uuid: storage.getUuid(),
token: storage.getAccessToken(),
sign: this.storeInfo.yzfSign,
mpSign: this.storeInfo.yzfMpSign,
};
uni.navigateTo({ uni.navigateTo({
url: url: `/pages/tabbar/home/web-view?IM=${this.storeId}`,
"/pages/product/customerservice/index?params=" +
encodeURIComponent(JSON.stringify(params)),
}); });
// #endif
// #ifndef MP-WEIXIN
const sign = this.storeInfo.yzfSign;
uni.navigateTo({
url:
"/pages/tabbar/home/web-view?src=https://yzf.qq.com/xv/web/static/chat/index.html?sign=" +
sign,
});
// #endif
}, },
/** 获取店铺分类 */ /** 获取店铺分类 */
@ -277,15 +272,6 @@ export default {
} }
}, },
/**
* 跳转到商品详情
*/
navigateToGoodsDetail(val) {
uni.navigateTo({
url: `/pages/product/goods?id=${val.content.id}&goodsId=${val.content.goodsId}`,
});
},
/** /**
* 是否收藏 * 是否收藏
*/ */
@ -404,42 +390,6 @@ export default {
justify-content: center; justify-content: center;
margin-top: 40rpx; margin-top: 40rpx;
} }
.item {
overflow: hidden;
background: #fff;
width: 49%;
height: 484rpx;
font-size: 26rpx;
display: flex;
flex-direction: column;
border: 1px solid #f8f8f8;
margin-bottom: 20rpx;
.name {
text-align: left !important;
color: #333;
padding: 0 20rpx;
margin-top: 20rpx;
height: 80rpx;
overflow: hidden;
}
.price {
font-weight: 500;
color: $main-color;
font-size: 30rpx;
padding: 0 20rpx;
margin-top: 20rpx;
white-space: nowrap;
}
.buyCount {
display: flex;
padding: 0 20rpx;
font-size: 24upx;
justify-content: space-between;
color: #999;
}
}
} }
.discount { .discount {
height: 154rpx; height: 154rpx;

View File

@ -4,26 +4,18 @@
<!-- 商品 --> <!-- 商品 -->
<div class="contant"> <div class="contant">
<view v-if="!goodsList.length" class="empty"></view> <view v-if="!goodsList.length" class="empty"></view>
<view v-else class="item" v-for="(item,index) in goodsList" :key="index" @click="navigateToGoodsDetail(item)"> <goodsTemplate :res='goodsList' :storeName='false' />
<u-image width="100%" mode="aspectFit" height="324rpx" :src="item.content.thumbnail">
<u-loading slot="loading"></u-loading>
</u-image>
<div class="name">{{ item.content.goodsName }}</div>
<div class="price">
<div>{{ item.content.price | unitPrice }}</div>
</div>
<view class="buyCount">
<div>已售 {{ item.content.buyCount || "0" }}</div>
</view>
</view>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { getGoodsList } from "@/api/goods.js"; import {
export default { getGoodsList
} from "@/api/goods.js";
import goodsTemplate from '@/components/m-goods-list/list'
export default {
data() { data() {
return { return {
title: "", title: "",
@ -38,6 +30,9 @@ export default {
}, },
}; };
}, },
components: {
goodsTemplate
},
onLoad(options) { onLoad(options) {
this.routerVal = options; this.routerVal = options;
this.params.storeId = options.storeId; this.params.storeId = options.storeId;
@ -45,24 +40,15 @@ export default {
this.title = options.title; this.title = options.title;
}, },
onShow() { onShow() {
this.goodsList =[] this.goodsList = []
this.params.pageNumber = 1; this.params.pageNumber = 1;
this.getGoodsData(); this.getGoodsData();
}, },
onReachBottom(){ onReachBottom() {
this.params.pageNumber ++; this.params.pageNumber++;
this.getGoodsData(); this.getGoodsData();
}, },
methods: { methods: {
/**
* 跳转到商品详情
*/
navigateToGoodsDetail(val) {
uni.navigateTo({
url: `/pages/product/goods?id=${val.content.id}&goodsId=${val.content.goodsId}`,
});
},
async getGoodsData() { async getGoodsData() {
// #TODO // #TODO
let goodsList = await getGoodsList(this.params); let goodsList = await getGoodsList(this.params);
@ -71,57 +57,21 @@ export default {
} }
}, },
}, },
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.contant { .contant {
margin-top: 20rpx; margin-top: 20rpx;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: space-between; justify-content: space-between;
> .empty {
>.empty {
width: 100%; width: 100%;
display: flex; display: flex;
justify-content: center; justify-content: center;
margin-top: 40rpx; margin-top: 40rpx;
} }
.item {
overflow: hidden;
background: #fff;
width: 49%;
height: 484rpx;
font-size: 26rpx;
display: flex;
flex-direction: column;
border: 1px solid #f8f8f8;
margin-bottom: 20rpx;
.name {
text-align: left !important;
color: #333;
padding: 0 20rpx;
margin-top: 20rpx;
line-height: 1.4em;
max-height: 2.8em; //heightline-height
overflow: hidden;
}
.price {
font-weight: 500;
color: $main-color;
font-size: 30rpx;
padding: 0 20rpx;
margin-top: 20rpx;
white-space: nowrap;
}
.buyCount {
display: flex;
padding: 0 20rpx;
font-size: 24upx;
justify-content: space-between;
color: #999;
}
}
} }
</style> </style>

View File

@ -27,7 +27,7 @@ export function modelNavigateTo(item) {
// 活动 // 活动
case "marketing": case "marketing":
uni.navigateTo({ uni.navigateTo({
url: "/pages/product/goods?id=" + val.skuId + "goodsId=" + val.goodsId, url: "/pages/product/goods?id=" + val.id + "goodsId=" + val.goodsId,
}); });
break; break;
case "pages": case "pages":

View File

@ -169,3 +169,11 @@ $font-weight: 400;
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
overflow: hidden; overflow: hidden;
} }
.wes-3 {
/* 适用于webkit内核和移动端 */
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
}

View File

@ -119,9 +119,11 @@ http.interceptors.response.use(
response.data.status === 403 response.data.status === 403
) { ) {
if (!isRefreshing) { if (!isRefreshing) {
console.log('旧token',token)
isRefreshing = true; isRefreshing = true;
let oldRefreshToken = storage.getRefreshToken();
//调用刷新token的接口 //调用刷新token的接口
return refreshTokenFn(storage.getRefreshToken()) return refreshTokenFn(oldRefreshToken)
.then((res) => { .then((res) => {
let { accessToken, refreshToken } = res.data.result; let { accessToken, refreshToken } = res.data.result;
storage.setAccessToken(accessToken); storage.setAccessToken(accessToken);
@ -129,11 +131,13 @@ http.interceptors.response.use(
response.header.accessToken = `${accessToken}`; response.header.accessToken = `${accessToken}`;
// token 刷新后将数组的方法重新执行 // token 刷新后将数组的方法重新执行
console.log('接口队列',requests,'新token',accessToken)
requests.forEach((cb) => cb(accessToken)); requests.forEach((cb) => cb(accessToken));
requests = []; // 重新请求完清空 requests = []; // 重新请求完清空
return http.request(response.config); return http.request(response.config);
}) })
.catch((err) => { .catch((err) => {
console.log('刷新token报错'+oldRefreshToken,err)
cleanStorage(); cleanStorage();
return Promise.reject(err); return Promise.reject(err);
}) })
@ -153,9 +157,10 @@ http.interceptors.response.use(
// 如果当前返回没登录 // 如果当前返回没登录
} else if ( } else if (
(!token && response.statusCode === 403) || (!token && !storage.getRefreshToken() && response.statusCode === 403) ||
response.data.code === 403 response.data.code === 403
) { ) {
console.log('没有token 以及刷新token 内容',token,storage.getRefreshToken())
cleanStorage(); cleanStorage();
// 如果当前状态码为正常但是success为不正常时 // 如果当前状态码为正常但是success为不正常时