commit message

This commit is contained in:
Chopper
2021-05-13 11:03:32 +08:00
commit 23804939eb
2158 changed files with 149684 additions and 0 deletions

135
pages/product/askList.vue Normal file
View File

@@ -0,0 +1,135 @@
<template>
<div class="wrapper">
<div v-if="!askGoods.goods_id" class="noMore">
暂无信息
</div>
<div class="askBox" v-else>
<u-row :gutter="24">
<u-col span="2" @click="goodsDetail()">
<image class="img" :src="queryGoodsDetail.thumbnail"></image>
</u-col>
<u-col span="8" @click="goodsDetail()">
<h5 style="padding-left:10rpx;">{{queryGoodsDetail.goodsName}}</h5>
</u-col>
</u-row>
<u-row>
<u-col span="12">
<u-input v-model="params.askValue" height="200" type="textarea" :border="border" />
</u-col>
<u-radio-group v-model="params.anonymous" @change="radioGroupChange">
<u-radio @change="radioChange">
匿名提交
</u-radio>
</u-radio-group>
<u-col span="12">
<u-row :gutter="12">
<u-col :offset="1" span="4">
<u-button class="btns" @click="askValue=''">清空</u-button>
</u-col>
<u-col :offset="2" span="4">
<u-button class="btns" @click="getAskMessage()" type="success">提交</u-button>
</u-col>
</u-row>
</u-col>
</u-row>
</div>
</div>
</template>
<script>
import * as API_GOODS from "../../api/goods";
import * as API_MEM from "../../api/members";
export default {
data() {
return {
askGoods: "",
queryGoodsDetail: "",
border: true,
params: {
askValue: "",
anonymous: "YES",
},
};
},
onLoad(options) {
this.askGoods = options;
this.getGoodsData();
},
methods: {
getGoodsData() {
if (this.askGoods.goods_id) {
API_GOODS.getGoods(this.askGoods.goods_id).then((result) => {
this.queryGoodsDetail = result.data;
});
}
},
getAskMessage() {
uni.showLoading();
if (this.params.askValue == "") {
uni.showToast({
title: "请填写内容!",
icon: "none",
});
uni.hideLoading();
return false;
}
API_MEM.consultating(
this.askGoods.goods_id,
this.params.askValue,
this.params.anonymous
)
.then((res) => {
if (res.statusCode == 200) {
uni.showToast({
title: "提交成功!",
icon: "none",
});
this.askValue = "";
}
uni.hideLoading();
})
.catch((err) => {
console.log(err);
uni.hideLoading();
});
},
radioGroupChange(e) {
console.log(e);
},
radioChange(e) {
if (this.anonymous == "YES") {
this.anonymous = "NO";
} else {
this.anonymous = "YES";
}
console.log(e);
},
},
};
</script>
<style scoped lang="scss">
.img {
max-width: 100%;
height: 100rpx;
}
.noMore {
text-align: center;
margin: 40rpx 0;
}
.askBox {
padding: 32rpx;
}
/deep/ .u-col {
text-align: center;
padding: 16rpx 0 !important;
}
.wrapper {
background: #fff;
padding: 32rpx 0;
}
</style>

571
pages/product/comment.vue Normal file
View File

@@ -0,0 +1,571 @@
<template>
<view class="comment">
<!-- <view class="status_bar" -->
<!--</view> -->
<view class="top-tab">
<!-- <view class="good-comment">商品好评率{{ grade || "100" }}%</view> -->
<view class="tab-btn" :v-if="commentDetail">
<!-- <view v-for="item in selectObj" :key="item.id" @click="select(item.id)" :class="{cur:selectIndex===item.id}">{{item.text}}</view> -->
<view @click="select(0)" :class="{ cur: selectIndex == 0 }">全部</view>
<view @click="select(1)" :class="{ cur: selectIndex == 1 }">好评{{ commentDetail.good }}</view>
<view @click="select(2)" :class="{ cur: selectIndex == 2 }">中评{{ commentDetail.moderate }}</view>
<view @click="select(3)" :class="{ cur: selectIndex == 3 }">差评{{ commentDetail.worse }}</view>
<view @click="select(4)" :class="{ cur: selectIndex == 4 }">有图{{ commentDetail.haveImage }}</view>
</view>
</view>
<!-- 评价 -->
<div class="goodsBoxOver">
<scroll-view :style="{ height: DivHeight }" lower-threshold="150" @scrolltolower="loadmore()" scroll-anchoring enableBackToTop="true" scroll-y class="scoll-page">
<view class="eva-section">
<div class="nodata" v-if="commDetail.length < 1">
<view>
<image style="height: 240rpx; width: 320rpx" src="/static/nodata.png" alt="" />
</view>
<view>
<p>暂无评价</p>
</view>
</div>
<view class="eva-box" v-for="(item, index) in commDetail" :key="index">
<view class="section-info">
<image class="portrait" :src="item.memberProfile || '/static/missing-face.png'" mode="aspectFill"></image>
<view class="star-con">
<text class="name">{{ item.memberName | noPassByName }}</text>
<text class="time">{{ item.createTime }}</text>
</view>
<view class="stars">
<text :class="{ star: item.deliveryScore > 0 }"></text>
<text :class="{ star: item.deliveryScore > 1 }"></text>
<text :class="{ star: item.deliveryScore > 2 }"></text>
<text :class="{ star: item.deliveryScore > 3 }"></text>
<text :class="{ star: item.deliveryScore > 4 }"></text>
</view>
</view>
<view class="section-contant">
<div class="con">{{ item.content }}</div>
<view class="img">
<u-image width="140rpx" height="140rpx" v-if="item.image" v-for="(img, i) in splitImg(item.image)" :src="img" :key="i" @click="preview(splitImg(item.image), i)">
</u-image>
</view>
<view class="bot">
<text class="attr">{{ item.goodsName }} - {{ gradeList[item.grade] }}</text>
<!-- <text class="zan" :class="{cur:item.isZan}" @click="dianzan(index)">{{item.zan}}</text> -->
</view>
</view>
<view class="addComment commentStyle" v-if="item.additional_comment">
<div>
<b>追加评价:</b>
<span class="addCommentSpan">{{
item.additional_comment.content
}}</span>
<view class="img">
<image v-for="(item, addIndex) in item.additional_comment.images" :src="item" :key="addIndex" @click="preview(item)"></image>
</view>
</div>
</view>
<view class="commentStyle" v-if="item.reply">
商家回复
<span class="addCommentSpan">{{ item.reply }}</span>
<view class="img">
<u-image width="140rpx" height="140rpx" v-if="item.replyImage" v-for="(replyImg, replyIndex) in splitImg(replyImg.image)" :src="replyImg" :key="replyIndex"
@click="preview(splitImg( item.replyImage), index)">
</u-image>
</view>
</view>
<view class="commentStyle" v-if="item.additional_comment && item.additional_comment.reply">
商家回复:
<span class="addCommentSpan">{{
item.additional_comment.reply.content
}}</span>
</view>
</view>
</view>
<!-- <u-loadmore :status="status" @loadmore="loadmore()" icon-type="iconType" /> -->
</scroll-view>
</div>
</view>
</template>
<script>
// import { getGoodsDetail } from '@/api/goods.js';
import * as membersApi from "@/api/members.js";
export default {
data() {
return {
header: {
top: 0,
height: 50,
},
DivHeight: "",
status: "loadmore",
commentObj: {},
selectObj: [],
commentDetail: "",
selectIndex: "0", //检索条件
imgUrl: "",
previewImgFlag: false,
// 评论分页提交数据
params: {
pageNumber: 1,
pageSize: 10,
grade: "",
},
gradeList: {
GOOD: "好评",
MODERATE: "中评",
WORSE: "差评",
HAVEIMAGE: "有图",
},
// 评论详情
commDetail: [],
dataTotal: 0,
opid: "",
grade: "100%",
};
},
async onLoad(options) {
this.grade = options.grade;
this.getGoodsCommentsFun(options.id);
this.getGoodsCommentsNum(options.id);
this.opid = options.id;
},
mounted() {},
methods: {
splitImg(val) {
if (val && val.split(",")) {
return val.split(",");
} else if (val) {
return val;
} else {
return false;
}
},
loadmore() {
this.params.pageNumber++;
this.getGoodsCommentsFun(this.opid);
},
// 获取商品评论
getGoodsCommentsFun(id) {
this.status = "loading";
// getGoodsComments
membersApi.getGoodsComments(id, this.params).then((res) => {
if (
res.data.result.records == [] ||
res.data.result.records == "" ||
res.data.result.records == null
) {
this.status = "noMore";
return false;
}
this.commDetail = this.commDetail.concat(res.data.result.records);
console.log(this.commDetail);
this.dataTotal = res.data.result.total;
this.status = "loadmore";
});
},
getGoodsCommentsNum(id) {
membersApi.getGoodsCommentsCount(id).then((res) => {
if (res.statusCode === 200) {
this.commentDetail = res.data.result;
}
});
},
select(index) {
//顶部筛选条件
this.selectIndex = index;
console.log(this.selectIndex);
this.params.grade = ["", "GOOD", "MODERATE", "WORSE", ""][
this.selectIndex
];
this.selectIndex == 4 ? (this.params.haveImage = 1) : true;
this.params.pageNumber = 1;
this.params.pageSize = 10;
this.commDetail = [];
if (this.selectIndex == 0) {
this.params = {
pageNumber: 1,
pageSize: 10,
grade: "",
};
}
this.getGoodsCommentsFun(this.opid);
},
// 返回
back() {
uni.navigateTo({
url: "./product?id=" + this.opid,
});
},
// 点赞
dianzan(index) {
if (this.commentObj.item[index].isZan) {
this.commentObj.item[index].zan--;
} else {
this.commentObj.item[index].zan++;
}
this.commentObj.item[index].isZan = !this.commentObj.item[index].isZan;
},
// 预览
preview(urls, index) {
console.log(urls);
uni.previewImage({
current: index,
urls: urls,
longPressActions: {
itemList: ["保存图片"],
success: function (data) {
uni.showToast({
title: "保存成功",
duration: 2000,
icon: "none",
});
},
fail: function (err) {
uni.showToast({
title: "保存失败",
duration: 2000,
icon: "none",
});
},
},
});
},
close() {
this.previewImgFlag = false;
this.imgUrl = "";
},
},
};
</script>
<style lang="scss" scoped>
.commentStyle {
margin-top: 16rpx;
padding: 14rpx 26rpx;
background: #f5f5f5;
border-radius: 6px;
font-size: 22rpx;
font-weight: 700;
text-align: left;
line-height: 40rpx;
}
.addCommentSpan {
color: $u-tips-color !important;
padding-left: 20rpx;
}
.img {
display: flex;
flex-wrap: wrap;
/* height: 140rpx; */
overflow: hidden;
image {
width: 166rpx;
height: 166rpx;
margin: 0 15rpx 15rpx 0;
&:nth-of-type(3n + 0) {
margin: 0 0 15rpx 0;
}
}
}
.goodsBoxOver {
overflow-y: scroll;
}
.headerBox {
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: 26rpx;
font-size: 34rpx;
.left,
.right {
position: absolute;
width: max-content;
height: max-content;
top: 0;
bottom: 0;
margin: auto;
}
.left {
float: left;
top: 0;
bottom: 0;
left: 20rpx;
}
.right {
float: right;
right: 20rpx;
}
}
page {
background: #f7f7f7;
}
.preview-img {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
/* background: rgba(0,0,0,0.5); */
background-repeat: no-repeat;
background-color: rgba(0, 0, 0, 0.5);
background-position: center;
background-size: 90% auto;
z-index: 1000;
.close {
position: absolute;
width: 100rpx;
height: 100rpx;
text-align: center;
line-break: 50rpx;
/* background: rgba(0,0,0,0.5); */
font-size: 80rpx;
color: #fff;
top: 100rpx;
}
image {
/* width: 100%; */
position: absolute;
top: 50%;
transform: translateY(-50%);
}
}
// .goodsBoxOver{
// height: calc(100vh - 200rpx) ;
// }
.comment {
color: #333;
background: #f7f7f7;
overflow: hidden;
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
background: #fff;
z-index: 999;
display: flex;
justify-content: space-between;
height: 90rpx;
line-height: 90rpx;
font-size: 30rpx;
transition: all 0.5s;
.back {
width: 90rpx;
background: url(/static/search/back.png);
background-size: 100%;
}
.share {
width: 90rpx;
background: url(/static/search/back.png);
background-size: 100%;
}
}
.header-line {
height: 2px;
background: #f2f2f2;
position: fixed;
top: 90rpx;
left: 0;
right: 0;
z-index: 999;
}
.header-line1 {
height: 20rpx;
position: static;
}
.top-tab {
background: #fff;
margin-bottom: 10rpx;
border-radius: 20rpx;
display: flex;
flex-direction: column;
padding: 0 30rpx 0 30rpx;
font-size: 24rpx;
.good-comment {
text-align: right;
color: #a5a5a5;
}
.tab-btn {
margin-top: 20rpx;
display: flex;
flex-wrap: wrap;
view {
min-width: 118rpx;
text-align: center;
height: 50rpx;
line-height: 50rpx;
padding: 0 10rpx;
background: #f8f8fe;
border-radius: 25rpx;
margin: 0 20rpx 30rpx 0;
&.cur {
background: $aider-light-color;
color: #fff;
}
}
}
}
.eva-section {
padding: 20rpx 0;
.eva-box {
padding: 40rpx;
margin-bottom: 10rpx;
background: #fff;
border-radius: 20rpx;
/* star */
.star-con {
display: flex;
flex-direction: column;
view {
flex: 1;
display: flex;
align-items: center;
}
.time {
font-size: 24rpx;
color: #999;
}
}
.section-info {
display: flex;
.stars {
flex: 1;
display: flex;
justify-content: flex-end;
align-items: center;
.star {
width: 30rpx;
height: 30rpx;
background: url("/static/star.png");
background-size: 100%;
}
}
.portrait {
flex-shrink: 0;
width: 80rpx;
height: 80rpx;
border-radius: 100px;
margin-right: 20rpx;
}
}
.section-contant {
display: flex;
flex-direction: column;
.con {
font-size: 24rpx;
line-height: 46rpx;
font-weight: 400;
color: $font-color-dark;
color: #333;
padding: 26rpx 0;
}
.img {
display: flex;
flex-wrap: wrap;
/* height: 140rpx; */
overflow: hidden;
> * {
margin-right: 16rpx;
}
}
.bot {
display: flex;
justify-content: space-between;
font-size: $font-sm;
color: $font-color-light;
margin-top: 20rpx;
.zan {
color: #333;
position: relative;
&:before {
content: "";
width: 40rpx;
height: 40rpx;
background: url(/static/search/delete.png);
background-size: 100%;
position: absolute;
left: -50rpx;
top: -6rpx;
}
&.cur:before {
background: url(/static/global/selected.png);
background-size: 100%;
}
}
}
}
.reply {
padding: 16rpx 30rpx;
background: #f8f8fe;
font-size: 24rpx;
border-radius: 5px;
margin-top: 20rpx;
text {
color: #999;
line-height: 48rpx;
}
}
}
}
}
.nodata {
padding-top: 300rpx;
color: #999999;
text-align: center;
img {
width: 346rpx;
height: 304rpx;
}
}
</style>

774
pages/product/goods.vue Normal file
View File

@@ -0,0 +1,774 @@
<template>
<div class="main-page">
<!-- #ifdef APP-PLUS -->
<view class="status_bar"></view>
<!-- #endif -->
<!-- 仅h5有效 打开App -->
<!-- 分享 -->
<shares v-if="shareFlage && goodsDetail.id" :skuId="this.routerVal.id" :goodsId="this.routerVal.goodsId" :link="'/pages/product/goods?id='+this.routerVal.id+'&goodsId='+this.routerVal.goodsId"
:thumbnail="goodsDetail.thumbnail" :goodsName="goodsDetail.goodsName" type="goods" @close="shareFlage = false" />
<view class="index">
<u-navbar :background="navbar" :is-back="false" :class="headerFlag ? 'header' : 'header bg-none scoll-hide'">
<div class="headerRow">
<div class="backs" @click="back()">
<u-icon name="arrow-left" color="#8e8e8e"></u-icon>
</div>
<div class="headerList" :class="headerFlag ? 'tab-bar' : 'tab-bar scoll-hide'">
<div class="headerRow">
<div style="text-align: center" :span="3" v-for="header in headerList" :key="header.id" :class="{ cur: scrollId === header.id }" @click="headerTab(header.id)">
{{ header.text }}
</div>
</div>
</div>
<div class="share" @click="shareChange()">
<image class="shareImg" src="/static/share.png" alt=""></image>
</div>
</div>
</u-navbar>
<view class="showBack" v-show="!headerFlag">
<u-row>
<u-col :span="2" @click="back()">
<div class="iconBag" style="text-align: center">
<image class="headerImg" src="/static/bagBack.png" alt=""></image>
</div>
</u-col>
<u-col :span="8"></u-col>
<u-col :span="2" class="share" style="text-align: center" @click="shareChange()">
<image class="headerImg" src="/static/bagShare.png" alt=""></image>
</u-col>
</u-row>
</view>
</view>
<view class="product-container" :style="{ height: productRefHeight }" ref="productRef" id="productRef">
<scroll-view scroll-anchoring enableBackToTop="true" scroll-with-animation scroll-y class="scoll-page" :scroll-top="tabScrollTop" @scroll="pageScroll">
<view>
<!-- 轮播图 -->
<GoodsSwiper id="main1" :res="imgList" />
<!-- 促销活动条 -->
<PromotionAssembleLayout v-if="PromotionList" :detail="goodsDetail" :res="PromotionList" />
<view class="card-box top-radius-0" id="main2">
<!-- 活动不显示价钱 -->
<view v-if="!is_promotion" class="desc-blod -goods-msg">
<view class="-goods-flex">
<view class="desc-blod">
{{ goodsDetail.goodsName || "" }}
</view>
<view class="favorite" @click="clickFavorite(goodsDetail.id)">
<u-icon size="30" :color="favorite ? '#f2270c' : '#262626'" :name="favorite ? 'heart-fill' : 'heart'"></u-icon>
<view :style="{ color: favorite ? '#f2270c' : '#262626' }">{{ favorite ? "已收藏" : "收藏" }}</view>
</view>
</view>
<!-- 商品描述 -->
<view class="-goods-desc">
{{ goodsDetail.sellingPoint || '' }}
</view>
</view>
<view v-else class="-goods-msg">
<!-- 没有拼团秒杀等活动的情况下 -->
<view>
<view class="-goods-flex">
<!-- 如果有积分显示积分 -->
<view class="-goods-price" v-if="goodsDetail.price != undefined">
<span v-if="pointDetail.points" > <span class="price">{{pointDetail.points}}</span>
<span>积分</span>
</span>
<span v-else> <span>¥</span><span class="price">{{ Fixed(goodsDetail.price)[0] }}</span>.{{
Fixed(goodsDetail.price)[1]
}} </span>
</view>
<view class="-goods-price" v-else> ¥<span class="price">0 </span>.00 </view>
<view class="favorite" @click="clickFavorite(goodsDetail.id)">
<u-icon size="30" :color="favorite ? '#f2270c' : '#262626'" :name="favorite ? 'heart-fill' : 'heart'"></u-icon>
<view :style="{ color: favorite ? '#f2270c' : '#262626' }">{{ favorite ? "已收藏" : "收藏" }}</view>
</view>
</view>
<view class="-goods-name desc-blod">
{{ goodsDetail.goodsName || "" }}
</view>
<view class="-goods-desc">
{{ goodsDetail.sellingPoint || '' }}
</view>
</view>
</view>
</view>
<view class="card-box">
<view class="card-flex" @click="shutMask(1)">
<view class="card-title"> 促销 </view>
<view class="card-content">
<span v-if="PromotionList && emptyPromotion()">暂无促销信息</span>
<PromotionLayout v-else @shutMasks="shutMask" :res="PromotionList" />
</view>
<view class="card-bottom">
<u-icon name="more-dot-fill"></u-icon>
</view>
</view>
</view>
<!-- 拼团用户列表 -->
<PromotionAssembleListLayout v-if="isGroup" @to-assemble-buy-now="toAssembleBuyNow" :res="PromotionList" />
<view class="card-box">
<view class="card-flex" @click="shutMask(4)">
<view class="card-title"> 已选 </view>
<view class="card-content">
<span v-if="selectedGoods.spec">{{ selectedGoods.spec.specName }}-{{
selectedGoods.spec.specValue
}}</span>
<span v-else>默认</span>
</view>
<view class="card-bottom">
<u-icon name="more-dot-fill"></u-icon>
</view>
</view>
<view class="card-flex" @click="shutMask(3)">
<view class="card-title"> 送至 </view>
<view class="card-content">
<span v-if="delivery">{{
delivery.consigneeAddressPath | clearStrComma
}}</span>
<span v-else>暂无地址信息</span>
</view>
<view class="card-bottom">
<u-icon name="more-dot-fill"></u-icon>
</view>
</view>
</view>
<!-- 评价 -->
<Evaluation id="main5" :goodsDetail="goodsDetail" v-if="goodsDetail.id" />
<!-- 店铺推荐 -->
<storeLayout id="main7" :storeDetail="storeDetail" :goodsDetail="goodsDetail" :res="recommendList" />
<!-- 宝贝详情 -->
<GoodsIntro id="main9" :res="goodsDetail" :goodsId="goodsDetail.goodsId" v-if="goodsDetail.id" />
<!-- 宝贝推荐 -->
<GoodsRecommend id="main11" :res="likeGoodsList" />
</view>
</scroll-view>
<view class="page-bottom mp-iphonex-bottom" id="pageBottom">
<view class="icon-btn">
<view class="icon-btn-item" @click="linkstorePage(goodsDetail.storeId)">
<u-icon size="34" class="red" name="home-fill"></u-icon>
<view class="red icon-btn-name">店铺</view>
</view>
<!-- <view class="icon-btn-item" @click="linkMsgDetail()">
<u-icon size="34" name="kefu-ermai"></u-icon>
<view class="icon-btn-name">客服</view>
</view> -->
<view class="icon-btn-item" @click="reluchToCart()">
<u-icon size="34" name="storeping-cart"></u-icon>
<view class="icon-btn-name">购物车</view>
<view v-if="nums && nums > 0" class="num-icon">{{ nums }}</view>
</view>
</view>
<!-- 正常结算页面 -->
<view class="detail-btn" v-if="!isGroup">
<view class="to-store-car to-store-btn" @click="shutMask(4)">加入购物车</view>
<view class="to-buy to-store-btn" @click="shutMask(4, 'buy')">立即购买</view>
<view class="to-store-car to-store-btn" v-if="startTimer">暂未开始</view>
</view>
<!-- 拼团结算 -->
<view class="detail-btn" v-else>
<view class="to-store-car pt-buy to-store-btn" @click="shutMask(4, 'buy')">
<view>{{ goodsDetail.price | unitPrice }}</view>
<view>单独购买</view>
</view>
<view class="to-buy pt-buy to-store-btn" @click="toAssembleBuyNow">
<view>{{ goodsDetail.promotionPrice | unitPrice }}</view>
<view>拼团价格</view>
</view>
</view>
</view>
<!-- 规格-模态层弹窗 -->
<view class="popup spec" @click="shutMask(false)" v-show="maskFlag">
<!-- 促销弹窗 -->
<view class="cuxiao mask" v-show="cuxiao">
<view ref="mask_title" class="title mask_title">
优惠
<span @click="shutMask(false)">×</span>
</view>
<scroll-view class="scroll_mask" :scroll-y="true">
<view class="con-cuxiao">
<text>促销活动</text>
<PromotionDetailsLayout :res="PromotionList" />
</view>
<view class="con-cuxiao coupons">
<text>可领优惠券</text>
<PromotionCoupon @getCoupon="getCoupon" :res="PromotionList" />
</view>
</scroll-view>
</view>
<!-- 配送地址弹窗 -->
<popupAddress @closeAddress="closePopupAddress" @deliveryData="deliveryFun" v-if="goodsDetail.id" :goodsId="goodsDetail.id" :addressFlag="addressFlag" />
<!-- 商品规格 商品详情以及默认参与活动的id-->
<popupGoods :addr="delivery" ref="popupGoods" @changed="changedGoods" @closeBuy="closePopupBuy" @queryCart="cartNum()" :goodsDetail="goodsDetail" :goodsSpec="goodsSpec" :id="productId"
v-if="goodsDetail.id " :pointDetail="pointDetail" @handleClickSku="init" :buyMask="buyMask" />
</view>
</view>
</div>
</template>
<script>
/************接口API***************/
import { getGoods, getGoodsList, getMpScene } from "@/api/goods.js";
import * as API_trade from "@/api/trade.js";
import * as API_Members from "@/api/members.js";
import * as API_store from "@/api/store.js";
/************请求存储***************/
import storage from "@/utils/storage.js";
/************组件***************/
import PromotionLayout from "./product/promotion/-promotion"; //促销组件
import PromotionDetailsLayout from "./product/promotion/-promotion-details"; //促销活动详情
import PromotionAssembleLayout from "./product/promotion/-promotion-assemble-promotions"; //促销活动条
import PromotionAssembleListLayout from "./product/promotion/-promotion-assemble-list"; //拼团用户列表
import PromotionCoupon from "./product/promotion/-promotion-coupon"; //优惠券组件
import GoodsIntro from "./product/goods/-goods-intro"; //商品介绍组件
import GoodsRecommend from "./product/goods/-goods-recommend"; //宝贝推荐
import storeLayout from "./product/shop/-shop"; //店铺组件
import Evaluation from "./product/evaluation/-evaluation"; //评价组件
import GoodsSwiper from "./product/goods/-goods-swiper"; //轮播图组件
import popupGoods from "./product/popup/goods"; //购物车商品的模块
import popupAddress from "./product/popup/address"; //地址选择模块
import shares from "@/components/m-share/index"; //分享
export default {
components: {
shares,
PromotionLayout,
PromotionDetailsLayout,
PromotionAssembleLayout,
PromotionAssembleListLayout,
PromotionCoupon,
GoodsIntro,
GoodsRecommend,
storeLayout,
Evaluation,
GoodsSwiper,
popupGoods,
popupAddress,
},
data() {
return {
shareFlage: false,
selectedGoods: "", //选择的商品规格昵称
is_promotion: true, //判断显示拼团活动文字
isGroup: false, // 是否是拼团活动
pointDetail: "", // 是否是积分商品
assemble: "", //拼团的sku
scroll_mask_height: 0, //促销活动的高度
navbar: {
background: "#fff",
},
productRefHeight: "",
header: {
top: 0,
height: 50,
},
headerFlag: false, //顶部导航显示与否
headerList: [
//顶部导航文字
{
text: "商品",
id: "1",
},
{
text: "评价",
id: "2",
},
{
text: "详情",
id: "3",
},
{
text: "推荐",
id: "4",
},
],
oldtabScrollTop: 0,
tabScrollTop: null,
scrollArr: [],
scrollId: "1",
scrollFlag: true,
current: "1", //当前显示的轮播图页
goodsDetail: {}, //商品数据
goodsSpec: "", //规格数据
imgList: [], //轮播图数据
favorite: false, //收藏与否flag
recommendList: [], //推荐列表
maskFlag: false, //模态显示与否
cuxiao: false, //促销弹窗
goodsInfo: false, //商品介绍弹窗
addressFlag: false, //配送地址弹窗
buyMask: false, //添加购物车直接购买,查看已选 弹窗
num: 1, //添加到购物车的数量
skuId: "", //
storeDetail: "", //店铺基本信息,
// 店铺信息
storeParams: {
pageNumber: 1,
pageSize: 10,
},
likeGoodsList: "", //相似商品列表
PromotionList: "", //活动,促销,列表
specList: [],
skusCombination: [],
selectedSpec: [],
nums: 0,
delivery: "",
exchange: {},
productId: 0,
startTimer: false, //未开启 是false
routerVal: "",
};
},
watch: {
isGroup(val) {
if (val) {
let timer = setInterval(() => {
this.$refs.popupGoods.buyType = "PINTUAN";
console.log(this.$refs.popupGoods.buyType);
clearInterval(timer);
}, 100);
this.is_promotion = false;
} else {
this.is_promotion = true;
this.$refs.popupGoods.buyType = "";
}
},
},
mounted() {
const { windowHeight } = uni.getSystemInfoSync();
let bottomHeight = 0;
let topHeight = 0;
uni.getSystemInfo({
success: function (res) {
// res - 各种参数
let bottom = uni.createSelectorQuery().select(".page-bottom");
bottom
.boundingClientRect(function (data) {
if (data && data.height) {
//data - 各种参数
bottomHeight = data.height; // 获取元素宽度
}
})
.exec();
let top = uni.createSelectorQuery().select(".header");
top
.boundingClientRect(function (data) {
if (data && data.height) {
//data - 各种参数
topHeight = data.height; // 获取元素宽度
}
})
.exec();
},
});
this.productRefHeight = windowHeight - bottomHeight + "px";
},
async onLoad(options) {
this.routerVal = options;
},
onShow() {
this.goodsDetail = {};
//如果有参数ids说明事分销短连接需要获取参数
if (this.routerVal.scene) {
getMpScene(this.routerVal.scene).then((res) => {
if (res.data.success) {
let data = res.data.result.split(","); // skuId,goodsId,distributionId
this.init(data[0], data[1], data[2]);
}
});
} else {
this.init(
this.routerVal.id,
this.routerVal.goodsId,
this.routerVal.distributionId,
this.routerVal.whetherPoint
);
}
},
onReachBottom() {
this.storeParams.pageNumber++;
this.getOtherLikeGoods();
},
methods: {
// 循环出当前促销是否为空
emptyPromotion() {
if (
this.PromotionList == "" ||
this.PromotionList == null ||
this.PromotionList == []
) {
return true;
}
},
/**初始化信息 */
async init(id, goodsId, distributionId, whetherPoint) {
this.isGroup = false; //初始化拼团
this.productId = id; // skuId
// 这里请求获取到页面数据 解析数据
uni.showLoading({
title: "加载中",
mask: true,
});
let response = await getGoods(id, goodsId, distributionId);
uni.hideLoading();
/**商品信息以及规格信息存储 */
this.goodsDetail = response.data.result.data;
this.goodsSpec = response.data.result.specs;
this.PromotionList = response.data.result.promotionMap;
// 判断是否拼团活动或者积分商品 如果有则显示拼团活动信息
this.PromotionList &&
Object.keys(this.PromotionList).forEach((item) => {
// 拼团商品
if (item.indexOf("PINTUAN") == 0) {
this.isGroup = true;
}
// 积分
if (item.indexOf("POINTS_GOODS") == 0) {
this.pointDetail = this.PromotionList[item];
console.log(this.pointDetail);
}
});
// 轮播图
this.imgList = this.goodsDetail.goodsGalleryList;
// 获取店铺基本信息
this.getstoreBaseInfoFun(this.goodsDetail.storeId);
// 获取购物车
this.cartNum();
// 获取店铺推荐商品
this.getstoreRecommend();
// 获取商品列表
this.getOtherLikeGoods();
// 获取商品是否已被收藏 如果未登录不获取
if (this.$options.filters.isLogin("auth")) {
this.getGoodsCollectionFun(this.goodsDetail.id);
}
},
// 格式化金钱 1999 --> [1999,00]
Fixed(val) {
if (typeof val == "undefined") {
return val;
}
return val.toFixed(2).split(".");
},
changedGoods(val) {
this.selectedGoods = val;
},
/** 点击子级地址回调参数*/
deliveryFun(val) {
this.delivery = val;
},
/**
* 地址子级关闭回调
*/
closePopupAddress(val) {
this.addressFlag = val;
this.maskFlag = false;
},
/**
* 商品规格子级关闭回调
*/
closePopupBuy(val) {
this.buyMask = val;
this.maskFlag = false;
},
/** 参与拼团 创建拼团 */
toAssembleBuyNow(order) {
this.shutMask(4, "PINTUAN", order);
},
// 查看购物车
reluchToCart() {
let obj = {
from: "product",
id: this.productId,
};
storage.setCartBackbtn(obj);
uni.switchTab({
url: "/pages/tabbar/cart/cartList",
});
},
// 查询购物车总数量
cartNum() {
if (storage.getHasLogin()) {
API_trade.getCartNum().then((res) => {
this.nums = res.data.result;
});
}
},
back() {
uni.navigateBack();
},
// 获取店铺信息
getstoreBaseInfoFun(id) {
API_store.getstoreBaseInfo(id).then((res) => {
if (res.data.success) {
this.storeDetail = res.data.result;
}
});
},
// 删除收藏店铺
deleteGoodsCollectionFun(id) {
// deleteStoreCollection
API_Members.deleteGoodsCollection(id).then((res) => {
if (res.statusCode == 200) {
uni.showToast({
title: "商品已取消收藏!",
icon: "none",
});
this.favorite = !this.favorite;
}
});
},
// 获取商品是否已被收藏
getGoodsCollectionFun(goodsId) {
if (storage.getHasLogin()) {
API_Members.getGoodsIsCollect(goodsId, "GOODS").then((res) => {
this.favorite = res.data.result;
});
}
},
// 获取店铺推荐商品列表
getstoreRecommend() {
getGoodsList({
pageNumber: 1,
pageSize: 6,
storeId: this.goodsDetail.storeId,
recommend: true,
}).then((res) => {
this.recommendList = res.data.result.content;
});
},
// 获取相似商品列表
getOtherLikeGoods() {
getGoodsList({
pageNumber: 1,
pageSize: 10,
category: this.goodsDetail.categoryId,
keyword: this.goodsDetail.name,
}).then((res) => {
this.likeGoodsList = res.data.result.content;
});
},
// 领取优惠券
receiveCouponsFun(id) {
API_Members.receiveCoupons(id).then((res) => {
uni.showToast({
title: res.data.message,
icon: "none",
});
});
},
linkstorePage(store_id) {
uni.navigateTo({
url: `/pages/product/shopPage?id=` + store_id,
});
},
//获取优惠券按钮
getCoupon(item) {
this.receiveCouponsFun(item.id);
},
//规格弹窗开关
shutMask(flag, buyFlag, type) {
// type是指是否点击底部按钮
if (flag) {
switch (flag) {
case 1: //优惠券弹窗
this.maskFlag = true;
this.cuxiao = true;
break;
case 3:
this.maskFlag = true;
this.addressFlag = true;
break;
case 4: //添加购物车直接购买,查看已选 弹窗
// 判断是否是一个规格
this.maskFlag = true;
this.buyMask = true;
if (buyFlag == "PINTUAN") {
if (type.orderSn) {
this.$refs.popupGoods.parentOrder = type;
}
this.$refs.popupGoods.buyType = "PINTUAN";
}
if (buyFlag == "buy") {
this.$refs.popupGoods.buyType = "";
}
break;
}
} else {
this.maskFlag = false;
this.cuxiao = false;
this.buyMask = false;
}
},
//收藏
clickFavorite(id) {
if (this.favorite) {
// 取消收藏
this.deleteGoodsCollectionFun(id);
return false;
}
API_Members.collectionGoods(id, "GOODS").then((res) => {
if (res.data.success) {
uni.showToast({
title: "收藏成功!",
icon: "none",
});
}
});
this.favorite = !this.favorite;
},
// 顶部header显示或隐藏
pageScroll(e) {
if (this.scrollFlag) {
this.calcSize();
}
if (e.detail.scrollTop > 200) {
//当距离大于200时显示回到顶部按钮
this.headerFlag = true;
} else {
//当距离小于200时隐藏回到顶部按钮
this.headerFlag = false;
}
if (e.detail.scrollTop < this.scrollArr[0] - 10) {
this.scrollId = "1";
}
if (e.detail.scrollTop > this.scrollArr[1] - 10) {
this.scrollId = "2";
}
if (e.detail.scrollTop > this.scrollArr[2] - 10) {
this.scrollId = "3";
}
if (e.detail.scrollTop > this.scrollArr[3] - 10) {
this.scrollId = "4";
}
},
//计算每个要跳转到的模块高度信息
calcSize() {
let h = 0;
let that = this;
let arr = [
"main1",
"main2",
"main3",
"main4",
"main5",
"main6",
"main7",
"main8",
"main9",
"main10",
"main11",
];
arr.forEach((item) => {
let view = uni.createSelectorQuery().select("#" + item);
view
.fields(
{
size: true,
},
(data) => {
if (
item === "main1" ||
item === "main5" ||
item === "main9" ||
item === "main11"
) {
that.scrollArr.push(h);
}
if (data && data.height) {
h += data.height;
}
}
)
.exec();
});
this.scrollFlag = false;
},
// 点击顶部跳转到对应位置
headerTab(id) {
if (this.scrollFlag) {
this.calcSize();
}
this.scrollId = id;
this.$nextTick(() => {
this.tabScrollTop = this.scrollArr[id - 1];
});
},
// 点击分享
async shareChange() {
this.shareFlage = true;
},
},
};
</script>
<style lang="scss" scoped>
// #ifdef MP-WEIXIN
@import "./product/mp-goods.scss";
// #endif
@import "./product/style.scss";
@import "./product/product.scss";
</style>

View File

@@ -0,0 +1,6 @@
.search{
margin-top: 28rpx !important;
}
.status_bar{
height: calc(var(--status-bar-height) + 188rpx ) !important;
}

View File

@@ -0,0 +1,220 @@
<template>
<view class="evaluate-box">
<view class="eva-section" @click="toComment(goodsDetail.goodsId, goodsDetail.grade)">
<view class="e-header">
<view class="evaluate-title">评价</view>
<text class="evaluate-num">{{ commDetail.total || '0' }}+</text>
<text class="tip">好评率 {{ goodsDetail.grade || '100' }}%</text>
</view>
<div v-if="commDetail && commDetail.records && commDetail.records.length > 0">
<view class="eva-box" v-for="(commItem,commIndex) in commDetail.records.slice(0,2)" :key="commIndex">
<view class="section-info">
<u-avatar mode="circle" size="60" class="portrait" :src="commItem.memberProfile"></u-avatar>
<view class="star-con">
<text class="name">{{ commItem.memberName | noPassByName }}</text>
</view>
</view>
<view class="section-contant">
<u-read-more ref="uReadMore" :color="lightColor">
<rich-text @load="parseLoaded" :nodes="commItem.content " class="con"></rich-text>
</u-read-more>
<scroll-view scroll-x class="scroll-x" v-if="commItem.image">
<view class="img">
<u-image border-radius="12" class="commImg" width="160rpx" height="160rpx" v-for="(item, index) in commItem.image.split(',')" :src="item" :key="index"
@click.stop="previewImg(commItem.image, index)"></u-image>
</view>
</scroll-view>
<view class="bot">
<text class="attr">{{ commItem.goodsName }}</text>
</view>
</view>
</view>
</div>
<div v-else class="goodsNoMore">
<u-empty text="该商品暂无评论" mode="message"></u-empty>
</div>
</view>
<!-- 查看全部评价按钮 -->
<view v-if="commDetail && commDetail.records && commDetail.records.length > 0" class="eva-section-btn" @click="toComment(goodsDetail.goodsId, goodsDetail.grade)" >
<text>查看全部评价</text>
</view>
</view>
</template>
<script>
import * as API_Members from "@/api/members.js";
export default {
data() {
return {
lightColor:this.$lightColor,
// 评论集合
commDetail: [],
// 评论分页提交数据
params: {
pageNumber: 1,
pageSize: 10,
grade: "",
},
};
},
props: ["goodsDetail"],
mounted() {
this.getGoodsComments();
},
methods: {
parseLoaded() {
this.$refs.uReadMore.init();
},
// 获取商品评论
getGoodsComments() {
API_Members.getGoodsComments(this.goodsDetail.goodsId, this.params).then(
(res) => {
this.commDetail = res.data.result;
}
);
},
toComment(id, grade) {
uni.navigateTo({
url: `/pages/product/comment?id=${id}&grade=${grade}`,
});
},
// 预览
previewImg(url, index) {
uni.previewImage({
urls: url,
indicator: "number",
current: index,
});
},
},
};
</script>
<style lang="scss" scoped>
@import "../product.scss";
.commImg {
margin-right: 12rpx;
margin-bottom: 10rpx;
display: inline-block;
}
.name {
color: #262626;
font-size: 22rpx;
}
.eva-section-btn {
display: flex;
justify-content: center;
align-items: center;
padding: 40rpx 40rpx 50rpx;
margin: 2px 0 20rpx 0;
background: #fff;
text {
width: 200rpx;
height: 50rpx;
font-size: 22rpx;
line-height: 46rpx;
text-align: center;
color: #262626;
border: 2rpx solid #ededed;
box-sizing: border-box;
border-radius: 30px;
}
}
.goodsNoMore {
padding: 20rpx 0;
text-align: center;
color: $u-tips-color;
}
/* 评价 */
.eva-section {
display: flex;
flex-direction: column;
background: #fff;
.e-header {
display: flex;
align-items: baseline;
font-size: $font-sm + 2rpx;
color: $font-color-light;
> .evaluate-num {
margin-left: 10rpx;
font-size: 24rpx;
color: #333;
}
.tit {
font-size: 32rpx;
color: $font-color-dark;
font-weight: 500;
margin: 0 4rpx;
}
.tip {
flex: 1;
text-align: right;
color: #8c8c8c;
font-size: 24rpx;
}
.icon-you {
margin-left: 10rpx;
}
}
}
.scroll-x {
white-space: nowrap;
-webkit-overflow-scrolling: touch;
overflow-x: auto;
}
.eva-box {
padding: 36rpx 0 30rpx 0;
border-bottom: 2rpx solid #f2f2f2;
.section-info {
display: flex;
align-items: center;
.portrait {
flex-shrink: 0;
width: 80rpx;
height: 80rpx;
border-radius: 100px;
margin-right: 20rpx;
}
> view > text {
margin-left: 6rpx;
}
}
.section-contant {
display: flex;
flex-direction: column;
.con {
font-size: 26rpx;
line-height: 46rpx;
color: $font-color-dark;
color: #333;
padding: 20rpx 0;
}
.img {
}
.bot {
display: flex;
justify-content: space-between;
font-size: 22rpx;
color: #999;
margin-top: 20rpx;
}
}
}
</style>

View File

@@ -0,0 +1,13 @@
<template>
</template>
<script>
export default {
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,138 @@
<template>
<div>
<view class="detail-box">
<view class="goods-detail">
<view class="detail_padding">
<div class="goods-detail-box">
<div class="goods-detail-item goods-active">商品介绍</div>
</div>
<u-empty class="empty" text="暂无商品介绍" mode="data" v-if="!res.intro"></u-empty>
<u-parse class="vhtml" :lazy-load="true" :use-cache="true" :show-with-animation="true" :html="res.mobileIntro"></u-parse>
</view>
</view>
</view>
<view class="detail-box">
<view class="goods-detail">
<view class="detail_padding">
<div class="goods-detail-box">
<div class="goods-detail-item goods-active">商品参数</div>
</div>
<u-divider>商品参数</u-divider>
<div class="param-list" v-if="!goodsDetail.goodsParamsList || goodsDetail.goodsParamsList.length == 0">
<u-empty text="暂无商品参数" mode="list"></u-empty>
</div>
<div class="param-list" v-if="goodsDetail.goodsParamsList && goodsDetail.goodsParamsList.length != 0">
<div class="param-item" v-for="(param,index) in goodsDetail.goodsParamsList" :key="index">
<div class="param-left">
{{param.paramName}}
</div>
<div class="param-right">
{{param.paramValue}}</div>
</div>
</div>
</view>
</view>
</view>
</div>
</template>
<script>
import { getGoodsMessage } from "@/api/goods";
export default {
data() {
return {
goodsDetail: "",
};
},
props: ["res", "goodsId"],
async mounted() {
let res = await getGoodsMessage(this.goodsId);
if (res.data.success) {
this.goodsDetail = res.data.result;
console.log(this.goodsDetail);
}
},
};
</script>
<style lang="scss" scoped>
@import "../product.scss";
.param-list {
padding: 40rpx 0 80rpx 0;
}
.param-item {
display: flex;
justify-content: center;
border-bottom: none;
> .param-left,
> .param-right {
padding: 16rpx 0;
font-size: 24rpx;
color: #666;
border: 1px solid rgb(220, 223, 230);
border-bottom: none;
}
> .param-left {
text-align: center;
border-right: none;
flex: 3;
}
> .param-right {
padding: 0 10rpx;
align-items: center;
display: flex;
flex: 7;
}
}
.param-item:nth-last-of-type(1) {
> .param-left,
> .param-right {
border-bottom: 1px solid rgb(220, 223, 230);
}
}
.empty {
margin: 40rpx 0;
}
.goods-detail /deep/ .vhtml {
overflow: hidden;
width: 100%;
}
/deep/ img {
width: 100%;
}
.goods-detail-box {
display: flex;
justify-content: space-between;
// padding: 0 80rpx;
height: 120rpx;
line-height: 120rpx;
> .goods-active {
font-weight: 700;
&::before {
position: absolute;
left: 50%;
bottom: 15px;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
content: "";
display: block;
width: 52rpx;
height: 6rpx;
background-image: linear-gradient(90deg, $jd-color, $jd-light-color);
}
}
> .goods-detail-item {
color: #262626;
position: relative;
}
}
.detail_padding {
}
</style>

View File

@@ -0,0 +1,169 @@
<template>
<view class="recommend-box" >
<h4 class="goods-recommend-title">宝贝推荐</h4>
<view class="like-goods-list">
<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.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.goodsName }}</view>
<view class="price-sales">
<div class="item-price" v-if="item.price != undefined">
<span>{{ Fixed(item.price)[0] }}</span>
.{{Fixed(item.price)[1]}}
<!-- <text v-if="item.point != undefined">+{{ item.point }}积分</text> -->
</div>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
props: ["res"],
methods: {
// 点击店铺推荐
clickGoods(val) {
uni.navigateTo({
url: `/pages/product/goods?id=${val.id}&goodsId=${val.goodsId}`
});
},
// 格式化金钱 1999 --> [1999,00]
Fixed(val) {
if (typeof val == "undefined") {
return val;
}
return val.toFixed(2).split(".");
}
}
};
</script>
<style lang="scss" scoped>
@import "../mp-goods.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: $jd-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>

View File

@@ -0,0 +1,85 @@
<template>
<!-- 轮播图 -->
<view class="carousel">
<swiper circular="true" duration="400" @change="swiperChange">
<swiper-item class="swiper-item" v-for="(item, index) in res" :key="index">
<view class="image-wrapper">
<u-image :src="item" mode="aspectFit" class="loaded" width="100%" height="100%">
<u-loading slot="loading"></u-loading>
</u-image>
</view>
</swiper-item>
</swiper>
<view class="swiper-dots">{{ current }}/{{ res.length }}</view>
</view>
</template>
<script>
export default {
data() {
return {
current: 1,
};
},
props: ["res"],
methods: {
// 轮播图对应的dot
swiperChange(e) {
this.current = e.detail.current + 1;
},
},
};
</script>
<style lang="scss" scoped>
.carousel {
// #ifdef MP-WEIXIN
margin-top: var(--status-bar-height);
// #endif
width: 750rpx;
height: 750rpx;
position: relative;
swiper {
height: 100%;
}
.image-wrapper {
width: 100%;
height: 100%;
}
.swiper-item {
display: flex;
justify-content: center;
align-content: center;
height: 750rpx;
overflow: hidden;
image {
width: 100%;
height: 100%;
}
}
position: relative;
.swiper-dots {
position: absolute;
right: 0rpx;
bottom: 40rpx;
font-size: 32rpx;
width: 107rpx;
height: 44rpx;
line-height: 44rpx;
text-align: center;
border-radius: 30rpx 0rpx 0rpx 30rpx;
background: #333333;
opacity: 0.4;
font-weight: 400;
color: #fff;
}
}
/deep/ .image-wrapper image {
opacity: 1 !important;
}
</style>

View File

@@ -0,0 +1,6 @@
.showBack {
margin-top: calc( var(--status-bar-height) + 20px ) !important;
}

View File

@@ -0,0 +1,177 @@
<template>
<u-popup class="popup" v-model="addressFlag" :height="setup.height" :mode="setup.mode" :border-radius="setup.radius" @close="closeAddress()" :mask-close-able="setup.close" :mask="false" closeable>
<view class="header-title">选择地址</view>
<view class="view-box" v-if="addressDetail">
<view class="view-item" v-for="(item, index) in addressDetail" :key="index" @click="clickAddress(item)">
<view class="view-box-checkbox">
<view class="checkbox" :class="{ checked: item.isDefault }">
<u-icon v-if="item.isDefault" :class="{ active: item.isDefault }" name="checkmark" size="12"></u-icon>
</view>
</view>
<view class="view-box-dress" :class="{ 'box-dress-blod': item.isDefault }">{{ item.consigneeAddressPath | clearStrComma }}</view>
</view>
</view>
<view class="view-box" v-else>
<view class="noMore">
<u-empty text="暂无收货地址" mode="address"></u-empty>
</view>
</view>
<!-- 按钮 -->
<view class="btns">
<view class="box-btn light" @click="getpicker">选择其他地址</view>
<view class="box-btn" @click="closeAddress()">确定</view>
</view>
<m-city :provinceData="cityList" headTitle="区域选择" ref="cityPicker" pickerSize="4"></m-city>
</u-popup>
</template>
<script>
import setup from "./popup";
/************请求存储***************/
import * as API_Address from "@/api/address.js";
export default {
data() {
return {
checked: "",
setup,
addressDetail: "",
cityList: [
{
id: "",
localName: "请选择",
children: [],
},
],
};
},
filters: {},
watch: {},
mounted() {
this.addressFlag = false;
if( this.$options.filters.isLogin("auth") ){
this.getShippingAddress()
}
else{
uni.navigateTo({
url: 'pages/passport/login'
});
}
},
props: ["goodsId", "addressFlag"],
methods: {
/**关闭地址 */
closeAddress() {
this.$emit("closeAddress", false);
this.$emit("deliveryData", this.checked);
},
getpicker() {
// this.$refs.cityPicker.show();
uni.navigateTo({
url: "/pages/mine/address/add",
});
this.closeAddress();
},
/**获取地址 */
getShippingAddress() {
if (this.$options.filters.isLogin("auth")) {
API_Address.getAddressList(1, 50).then((res) => {
if (res.data.success) {
this.addressDetail = res.data.result.records;
let addr = res.data.result.records.filter((item) => {
return item.isDefault == 1;
});
if (addr[0]) {
this.checked = addr[0];
this.$emit("deliveryData", this.checked);
}
// addr[0] ? "" : (addr = res.data);
// /**获取默认地址是否有货 */
// this.clickAddress(addr[0]);
}
});
}
},
/**点击地址返回父级商品状态 */
clickAddress(val) {
this.checked = val;
this.addressDetail.forEach((item) => {
item.isDefault = false;
});
val.isDefault = !val.isDefault;
this.$emit("deliveryData", this.checked);
},
},
};
</script>
<style lang="scss" scoped>
.light {
background-image: linear-gradient(
135deg,
#ffba0d,
#ffc30d 69%,
#ffcf0d
) !important;
box-shadow: 0 2px 6px 0 rgba(255, 65, 66, 0.2);
}
.noMore {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.view-item {
display: flex;
align-items: center;
padding: 22rpx 0;
}
.view-box-dress {
letter-spacing: 1rpx;
margin-left: 20rpx;
line-height: 42rpx;
color: #333;
font-size: 28rpx;
}
.checked {
background: $jd-color;
}
.active {
color: #fff;
}
.checkbox {
text-align: center;
line-height: 40rpx;
width: 40rpx;
height: 40rpx;
border-radius: 50%;
border: 2rpx solid #ededed;
}
@import "./popup.scss";
.view-box {
height: 810rpx;
// #ifdef MP-WEIXIN
height: 770rpx;
// #endif
padding: 0 20rpx;
overflow-y: auto;
}
.header-title {
font-weight: bold;
color: #333;
text-align: center;
height: 90rpx;
line-height: 90rpx;
font-size: 34rpx;
}
</style>

View File

@@ -0,0 +1,425 @@
<template>
<div class="wrapper">
<u-popup class="popup" v-model="buyMask" :height="setup.height" closeable :mode="setup.mode" :mask-close-able="isClose" :mask="isMask" :border-radius="setup.radius" @close="closeMask()">
<!-- 商品 -->
<view class="goods-box bottom">
<view class="goods-header">
<view class="goods-img">
<u-image width="200rpx" border-radius="20" class="uimage" height="200rpx" :src="selectedSpecImg ? selectedSpecImg : goodsDetail.thumbnail"></u-image>
</view>
<view class="goods-skus">
<!-- 有活动商品价格 -->
<view class="goods-price " v-if="goodsDetail.promotionPrice">
<span v-if="goodsDetail.promotionPrice && !pointDetail">
<span class="goods-price-promotionShow goods-price-bigshow" >{{ Fixed(goodsDetail.promotionPrice)[0] }}</span>
.{{ Fixed(goodsDetail.promotionPrice)[1] }}
</span>
<span v-if="pointDetail.points">
<span class="goods-price-promotionShow goods-price-bigshow" >{{ pointDetail.points }}</span>
积分
</span>
<div class="promotion-box">
<span class="goods-price-bigshow">{{
Fixed(goodsDetail.price)[0]
}}</span>
.{{ Fixed(goodsDetail.price)[1] }}
</div>
</view>
<!-- 正常商品的价格 -->
<view class="goods-price" v-else>
<span>
<span class="goods-price-bigshow">{{
Fixed(goodsDetail.price)[0]
}}</span>
.{{ Fixed(goodsDetail.price)[1] }}
</span>
</view>
<view class="goods-check-skus">
已选
<span class="goods-check-skus-name">
{{ selectName }}
<span>{{ num }}</span>
</span>
</view>
</view>
</view>
<!-- 商品信息 -->
<view class="goods-skus-box">
<!-- 规格 -->
<view class="goods-skus-view" :key="specIndex" v-for="(spec, specIndex) in formatList">
<view class="skus-view-list">
<view class="view-class-title">{{ spec.name }}</view>
<view :class="{ active: spec_val.id == currentSelceted[specIndex] }" class="skus-view-item" v-for="(spec_val, spec_index) in spec.values" :key="spec_index"
@click="handleClickSpec(spec, specIndex, spec_val)">{{ spec_val.value }}</view>
</view>
</view>
<!-- 数量 -->
<view class="goods-skus-number">
<view class="view-class-title">数量</view>
<u-number-box :bg-color="numberBox.bgColor" :color="numberBox.color" :input-width="numberBox.width" :input-height="numberBox.height" :size="numberBox.size" :min="1" v-model="num">
</u-number-box>
</view>
</view>
<!-- 按钮 -->
<view class="btns">
<view class="box-btn card" v-if="buyType !='PINTUAN'" @click="addToCartOrBuy('cart')">加入购物车</view>
<view class="box-btn buy" @click="addToCartOrBuy('buy')">立即购买</view>
</view>
</view>
</u-popup>
</div>
</template>
<script>
import * as API_trade from "@/api/trade.js";
import setup from "./popup";
export default {
data() {
return {
setup,
num: 1,
// 步进器的大小尺寸单位是 rpx
numberBox: {
width: "50",
height: "50",
size: "22",
color: "#333",
bgColor: "#fff",
},
selectName: "", //选中商品的昵称
selectSkuList: "", //选中商铺sku,
selectedSpecImg: "", //选中的图片路径
buyType: "", //用于存储促销,拼团等活动类型
parentOrder: "", //父级拼团活动的数据 - 如果是团员则有数据
formatList: [],
currentSelceted: [],
skuList: "",
isMask:false, //是否显示遮罩层
isClose:false, //是否可以点击遮罩关闭
};
},
props: [
"goodsDetail", //商品详情
"buyMask",
"selectedSku",
"goodsSpec",
"addr",
"pointDetail" // 积分详情
],
watch: {
buyType: {
handler(val) {
this.buyType = val;
},
immediate: true,
},
selectSkuList: {
handler(val, oldval) {
this.$emit("changed", val);
},
deep: true,
},
},
methods: {
// 格式化金钱 1999 --> [1999,00]
Fixed(val) {
if (typeof val == "undefined") {
return val;
}
return val.toFixed(2).split(".");
},
closeMask() {
this.$emit("closeBuy", false);
},
/**点击规格 */
handleClickSpec(val, index, specValue) {
this.$set(this.currentSelceted, index, specValue.id);
let selectedSkuId = this.goodsSpec.find((i) => {
let matched = true;
let specValues = i.specValues.filter((j) => j.specName !== "images");
for (let n = 0; n < specValues.length; n++) {
if (specValues[n].specValueId !== this.currentSelceted[n]) {
matched = false;
return;
}
}
if (matched) {
return i;
}
});
this.selectSkuList = {
spec: {
specName: val.name,
specValue: specValue.value,
},
data: this.goodsDetail,
};
this.selectName = specValue.value;
this.$emit("handleClickSku", selectedSkuId.skuId,this.goodsDetail.id);
},
/**
* 添加到购物车或购买
*/
addToCartOrBuy(val) {
if (!this.selectSkuList) {
uni.showToast({
title: "请选择规格商品",
icon: "none",
});
return;
}
let data = {
skuId: this.goodsDetail.id,
num: this.num,
};
if (val == "cart") {
API_trade.addToCart(data).then((res) => {
if (res.data.code == 200) {
uni.showToast({
title: "商品已添加到购物车",
icon: "none",
});
this.$emit("queryCart");
this.closeMask();
} else {
uni.showToast({
title: res.data.message,
duration: 2000,
icon: "none",
});
return false;
}
});
} else {
// 判断是否拼团商品
if (this.buyType) {
data.cartType = "PINTUAN";
} else {
data.cartType = "BUY_NOW";
}
API_trade.addToCart(data).then((res) => {
if (res.data.code == 200) {
uni.navigateTo({
url: `/pages/order/fillorder?way=${data.cartType}&addr=${
this.addr.id || ''
}&parentOrder=${encodeURIComponent(
JSON.stringify(this.parentOrder)
)}`,
});
}
else{
uni.showToast({
title: res.data.message,
duration: 2000,
icon: "none",
});
}
});
}
},
formatSku(list) {
// 格式化数据
let arr = [{}];
list.forEach((item, index) => {
item.specValues.forEach((spec, specIndex) => {
let id = spec.specNameId;
let name = spec.specName;
let values = {
id: spec.specValueId,
value: spec.specValue,
quantity: item.quantity,
};
if (name === "images") {
return;
}
arr.forEach((arrItem, arrIndex) => {
if (
arrItem.name == name &&
arrItem.values &&
!arrItem.values.find((i) => i.id === values.id)
) {
arrItem.values.push(values);
}
let keys = arr.map((key) => {
return key.name;
});
if (!keys.includes(name)) {
arr.push({
id: id,
name: name,
values: [values],
});
}
});
});
});
arr.shift();
this.formatList = arr;
list.forEach((item) => {
if (item.skuId === this.goodsDetail.id) {
item.specValues
.filter((i) => i.specName !== "images")
.forEach((value, _index) => {
this.currentSelceted[_index] = value.specValueId;
this.selectName = value.specValue;
this.selectSkuList = {
spec: value,
data: this.goodsDetail,
};
});
}
});
this.skuList = list;
},
},
mounted() {
console.log(this.pointDetail)
this.formatSku(this.goodsSpec);
},
};
</script>
<style lang="scss" scoped>
@import "./popup.scss";
.buy {
background-image: linear-gradient(135deg, #ffba0d, #ffc30d 69%, #ffcf0d);
box-shadow: 0 2px 6px 0 rgba(255, 65, 66, 0.2);
}
.card {
background-image: linear-gradient(135deg, #f2140c, #f2270c 70%, #f24d0c);
box-shadow: 0 2px 6px 0 rgba(255, 65, 66, 0.2);
}
/deep/.u-icon-plus,
.u-icon-minus,
.u-icon-disabled {
height: 30rpx !important;
background: #fff !important;
}
.goods-skus-number {
justify-content: space-between;
display: flex;
}
/deep/ .uni-scroll-view {
overflow: hidden !important;
}
.active {
background: $jd-light-color !important;
border: 2rpx solid $jd-color;
font-weight: bold;
color: $jd-color !important;
box-sizing: border-box;
}
.goods-skus-box {
overflow-y: auto;
height: 610rpx;
// #ifdef MP-WEIXIN
height: 570rpx;
// #endif
margin-bottom: 10rpx;
}
.goods-skus-view {
overflow: hidden;
.skus-view-list {
> .skus-view-item {
flex: 1;
padding: 0 36rpx;
overflow: hidden;
height: 60rpx;
line-height: 60rpx;
float: left;
text-align: center;
margin-left: 24rpx;
margin-bottom: 20rpx;
font-size: 22rpx;
color: #262626;
background: #f2f2f2;
border-radius: 30rpx;
}
}
}
.goods-header {
height: 200rpx;
display: flex;
align-items: center;
margin-bottom: 36rpx;
}
.goods-box {
padding: 50rpx 36rpx 0 36rpx;
}
.goods-skus {
padding: 0 20rpx;
}
.goods-price {
color: $jd-color;
line-height: 80rpx;
display: flex;
}
.promotion-box {
line-height: 1;
display: flex;
align-items: center;
text-decoration: line-through;
color: #999;
margin-left: 10rpx;
/deep/ span {
font-size: 30rpx;
}
}
.promotion {
font-size: 30rpx;
}
.goods-price-promotionShow {
font-size: 48rpx;
}
.goods-check-skus {
font-size: 24rpx;
color: #999;
> .goods-check-skus-name {
margin-left: 4rpx;
}
> span {
color: #333;
}
}
</style>

View File

@@ -0,0 +1,8 @@
export default {
height:"1000rpx", //弹出层高度
mode:"bottom", //弹出层位置
radius:"32", //圆角 rpx,
close:false //能否点击遮罩退出
}

View File

@@ -0,0 +1,37 @@
.view-class-title {
font-size: 26rpx;
color: #262626;
font-weight: 700;
height: 80rpx;
line-height: 80rpx;
}
.confirmBtn {
width: 90%;
}
.confirmBtn,
.box-btn {
line-height: 80rpx;
height: 80rpx;
background: $jd-color;
color: #fff;
border-radius: 200px;
text-align: center;
margin: 5rpx auto;
}
.btns {
display: flex;
width: 100%;
margin: 0 auto;
}
.goods-price-bigshow {
font-size: 48rpx;
font-weight: bold;
}
.box-btn {
flex: 1;
margin: 0 10rpx;
}

View File

@@ -0,0 +1,66 @@
.recommend-box,
.detail-box,
.store-recommend,
.store-info,
.evaluate-box,
.card-box,
.group-list {
border-radius: 32rpx;
padding: 0rpx 32rpx 0 32rpx;
background: #fff;
overflow: hidden;
margin: 20rpx 0;
}
.goods-recommend-title,
.store-recommend-title,
.evaluate-title,
.group-name {
color: #262626;
font-size: 30rpx;
font-weight: 700;
height: 90rpx;
line-height: 90rpx;
padding-left: 14rpx;
position: relative;
&::before {
background-image: linear-gradient(180deg, $jd-color, $jd-light-color);
content: "";
position: absolute;
left: 0;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
width: 3px;
height: 15px;
}
}
.scroll_mask{
height: 555px;
// padding-bottom: 100rpx;
overflow-y: auto;
}
.coupons {
padding-bottom: 200rpx !important;
}
.mask {
height: 600px;
}
.card-box {
padding-top: 0 !important;
}
.card-content {
padding: 0 40rpx;
flex: 8;
}
.card-flex {
display: flex;
align-items: center;
font-size: 26rpx;
padding: 36rpx 0;
border-bottom: 2rpx solid #f9f9f9;
}
.card-title {
flex: 1;
color: #262626;
font-weight: 700;
}

View File

@@ -0,0 +1,108 @@
<template>
<view class="group-list">
<view class="group-name">拼购列表</view>
<view v-if="assembleOrder.length !=0">
<view class="group-item" v-for="(order,index) in assembleOrder" :key="index">
<view class="group-item-user">
<u-image shape="circle" width="40px" height="40px" :src="order.face"></u-image>
<span class="group-item-name">{{order.nickName | noPassByName}}</span>
</view>
<view>
<span class="group-item-name">还差{{ order.toBeGroupedNum}}人成团</span>
</view>
<view>
<u-button size="mini" :custom-style="customStyle" @click="buy(order)">去参团</u-button>
</view>
</view>
</view>
<view v-else class="nomore">
<u-empty text="暂无拼团信息" mode="list"></u-empty>
</view>
</view>
</template>
<script>
import * as API_Promotions from "@/api/promotions";
export default {
data() {
return {
customStyle: {
background: this.$lightColor,
color: "#fff",
},
/** 待成团订单 */
assembleOrder: "",
/** 查看更多待成团订单 */
assembleOrderAll: "",
};
},
props: ["res"],
watch: {
res: {
handler() {
if (this.res && this.res.length != 0) {
Object.keys(this.res).forEach((item) => {
let key = item.split("-");
if (key && key[0] == "PINTUAN") {
this.getAssembleInfo(item);
}
});
}
},
immediate: true,
},
// assembleOrder(val) {
// this.$emit("assembleOrder", val);
// },
},
computed: {},
mounted() {},
methods: {
// 获取此商品所有待成团的订单
getAssembleInfo(val) {
let id = this.res[val].id;
API_Promotions.getPromotionGroupMember(id).then((res) => {
if (res.data.success) {
console.warn(res.data.result);
this.assembleOrder = res.data.result;
}
});
},
buy(order) {
this.$emit("to-assemble-buy-now", order);
},
},
};
</script>
<style lang="scss" scoped>
@import "../product.scss";
.nomore {
padding: 10rpx 0;
}
.group-item {
margin: 30rpx 0;
display: flex;
align-items: center;
justify-content: space-between;
}
.group-item-user {
display: flex;
align-items: center;
}
.group-item-name {
margin-left: 23rpx;
font-size: 24rpx;
color: #999999;
font-weight: 400;
}
</style>

View File

@@ -0,0 +1,131 @@
<template>
<view>
<div v-for="(promotion, promotion_index) in res" :key="promotion_index">
<div class="showBox" v-if="promotion.__key == 'SECKILL' || promotion.__key =='GROUPBUY' || promotion.__key == 'PINTUAN'">
<view class="group-wrapper">
<div class="u-group-row">
<view :span="8" class="showBox_L">
<view class="u-group-flex">
<!-- 限时抢购 -->
<view class="u-group-flex-left" v-if="promotion.__key == 'SECKILL' ">
<span class="u-group-flex-left-span" v-if="detail.promotionPrice!=undefined">
<span class="flex-price"> {{ Fixed(detail.promotionPrice)[0]}}.{{ Fixed(detail.promotionPrice)[1]}}</span>
</span>
<view class="u-group-flex" v-if="detail.price!=undefined">
<span class="old-price">{{ Fixed(detail.price)[0]}}.{{ Fixed(detail.price)[1]}}</span>
<view class="promotion">限时抢购</view>
</view>
</view>
<!-- 团购 -->
<view class="u-group-flex-left" v-if="promotion.__key == 'GROUPBUY' ">
<span class="u-group-flex-left-span">
<span class="flex-price"
v-if="promotion.groupbuy_goods_vo.price !=undefined">{{ Fixed(promotion.groupbuy_goods_vo.price )[0]}}.{{ Fixed(promotion.groupbuy_goods_vo.price )[1]}}</span>
<!-- <span v-if="promotion.point">+{{promotion.point}}积分</span> -->
</span>
<view class="u-group-flex">
<span class="old-price"
v-if="promotion.groupbuy_goods_vo.original_price!=undefined">{{ Fixed(promotion.groupbuy_goods_vo.original_price)[0]}}.{{ Fixed(promotion.groupbuy_goods_vo.original_price)[1]}}</span>
<view class="promotion">团购活动</view>
</view>
</view>
<view class="u-group-flex-left" v-if="promotion.__key == 'PINTUAN' ">
<span class="u-group-flex-left-span" v-if="detail.promotionPrice != undefined">
<span class="flex-price"> {{ Fixed(detail.promotionPrice)[0]}}.</span>{{ Fixed(detail.promotionPrice)[1]}}
</span>
<view class="u-group-flex" v-if="detail.price != undefined">
<span class="old-price">{{ Fixed(detail.price)[0]}}.{{ Fixed(detail.price)[1]}}</span>
<view class="promotion">拼团活动</view>
</view>
</view>
<!-- 拼团右侧 -->
<view class="u-group-flex-right" v-if="promotion.__key == 'PINTUAN' ">
<span class="group-bag">{{promotion.requiredNum}}人拼团 </span>
<span class="group-bag">限购{{promotion.limitNum}}</span>
</view>
</view>
</view>
<view class="showBox_R" v-if="promotion && promotion.endTime">
<u-tag :text="getIsTimer(promotion)" size="mini" type="error" />
<u-count-down :hide-zero-day="true" font-size="25" color="#fff" bg-color="#f71471" separator-size="25" separator-color="#f71471" :show-hours="true" :show-minutes="true"
:timestamp="getCountDownTime(promotion.endTime)"></u-count-down>
</view>
</div>
</view>
</div>
</div>
</view>
</template>
<script>
export default {
data() {
return {};
},
props: {
// 活动,促销数据
res: {
type: null,
default: {},
},
// 商品详情
detail: {
type: null,
default: {},
},
},
watch: {
res: {
handler() {
if (this.res && this.res.length != 0) {
Object.keys(this.res).forEach((item) => {
let key = item.split("-")[0];
this.res[item].__key = key;
// 针对现实向
});
}
},
immediate: true,
},
},
mounted() {},
methods: {
// 格式化金钱 1999 --> [1999,00]
Fixed(val) {
if (typeof val == "undefined") {
return val;
}
return val.toFixed(2).split(".");
},
getCountDownTime(val) {
let date = new Date(val.replace(/-/g, "/"))
let timeSimple = new Date(date).getTime() / 1000;
console.log(timeSimple , timeSimple - new Date().getTime() / 1000)
return timeSimple - new Date().getTime() / 1000;
},
getIsTimer(val) {
var timestamp = new Date().getTime();
// console.log(timestamp);
if (timestamp < val.start_time) {
this.startTimer = true;
return "距离活动开始";
} else {
return "距离活动结束";
}
},
},
};
</script>
<style scoped lang="scss">
@import "./group.scss";
</style>

View File

@@ -0,0 +1,178 @@
<template>
<view class="wrapper">
<div class="coupon-empty" v-if="!res">暂无优惠券</div>
<view class="coupon-List" v-if="res && item.__key=='COUPON'" v-for="(item, index) in res" :key="index">
<view class="coupon-item">
<view class="top">
<div class="price">
<span v-if="item.couponType == 'DISCOUNT'">{{ item.couponDiscount }}</span>
<span v-if="item.couponType == 'PRICE'">{{ item.price | unitPrice }}</span>
</div>
<view class="text">
<div class="coupon-List-title">
<view v-if="item.scopeType">
<span v-if="item.scopeType == 'ALL' && item.id == 'platform'">全平台</span>
<span v-if="item.scopeType == 'PORTION_CATEGORY'">仅限品类</span>
<view v-else>{{ item.storeName == 'platform' ? '全平台' :item.storeName+'店铺' }}使用</view>
</view>
</div>
<div>{{ item.consumeThreshold | unitPrice }}可用</div>
</view>
<view class="lingqu-btn" @click="getCoupon(item)">
<div :class="yhqFlag ? 'cur' : ''">{{ yhqFlag ? '已领取或领完' : '立即领取' }}</div>
</view>
</view>
<view class="line"></view>
<view class="time">{{ item.startTime }} - {{item.endTime }}</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
yhqFlag: false, //获取优惠券判断是否点击
};
},
props: {
res: {
type: null,
default: "",
},
},
watch: {
res: {
handler() {
if (this.res && this.res.length != 0) {
Object.keys(this.res).forEach((item) => {
let key = item.split("-")[0];
this.res[item].__key = key;
});
}
},
immediate: true,
},
},
methods: {
// 提交优惠券
getCoupon(item) {
this.yhqFlag = true;
this.$emit("getCoupon", item);
},
},
};
</script>
<style lang="scss" scoped>
.coupon-item {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.coupon-List {
display: flex;
flex-direction: column;
height: 230rpx;
background: #e9ebfb;
margin: 30rpx 0;
padding: 10rpx 30rpx;
.line {
height: 1px;
background: #fff;
margin: 0 20rpx;
position: relative;
&:before,
&:after {
content: "";
display: block;
width: 15rpx;
height: 30rpx;
background: #fff;
position: absolute;
top: -15rpx;
}
&:before {
left: -50rpx;
}
&:after {
right: -50rpx;
}
}
.time {
flex: 1;
font-size: 24rpx;
align-items: center;
display: flex;
align-items: center;
}
}
.top {
height: 140rpx;
display: flex;
.price {
width: 33%;
justify-content: center;
color: #6772e5;
font-size: 40rpx;
display: flex;
height: 100%;
align-items: center;
span {
font-size: 50rpx;
}
}
.text {
width: 33%;
display: flex;
flex-direction: column;
justify-content: center;
font-size: 26rpx;
color: 333;
margin-left: 40rpx;
.coupon-List-title {
font-size: 30rpx;
font-weight: bold;
}
}
.lingqu-btn {
display: flex;
align-items: center;
margin-left: 40rpx;
text {
width: 140rpx;
height: 40rpx;
text-align: center;
line-height: 40rpx;
color: #fff;
background: #6772e5;
border-radius: 5px;
font-size: 26rpx;
&.cur {
background: none;
transform: rotate(45deg) translate(10rpx, -46rpx);
}
}
}
}
</style>

View File

@@ -0,0 +1,96 @@
<template>
<view class="wrapper" v-if="res">
<view v-for="(prom, index) in Object.keys(res)" :key="index">
<view>
<view v-if="prom.split('-')[0] == 'FULL_DISCOUNT'">
<div class="res_prom_item" v-if="res[prom].fullMinus">
<u-tag text="满减" type="error"></u-tag>
<span class="proText">{{ res[prom].fullMoney }}立减现金 <span class="price">{{ res[prom].fullMinus}}</span></span>
</div>
<div class="res_prom_item" v-if="res[prom].fullRate">
<u-tag text="打折" type="error"></u-tag>
<span class="proText">{{ res[prom].fullMoney }}立享<span class="price">{{ res[prom].fullRate }}</span>优惠</span>
</div>
</view>
<view v-if="prom.split('-')[0] == 'PINTUAN'">
<div class="res_prom_item" v-if="res[prom].requiredNum">
<u-tag text="拼团" type="error"></u-tag>
<span class="proText">{{ res[prom].requiredNum }}人拼团 限购<span class="price">{{ res[prom].limitNum}}</span></span>
</div>
</view>
<view v-if="prom.split('-')[0] == 'SECKILL'">
<div class="res_prom_item">
<u-tag text="限时抢购" type="error"></u-tag>
<span class="proText">限时抢购</span>
</div>
</view>
</view>
</view>
<view v-if="!res">暂无促销活动</view>
</view>
</template>
<script>
export default {
data() {
return {};
},
watch: {
res: {
handler(val) {
console.log(val);
// if (this.res && this.res.length != 0) {
// Object.keys(this.res).forEach((item) => {
// if (item != "COUPON") {
// let key = item.split("-")[0];
// this.res[item]._key = key;
// }
// });
// }
},
immediate: true,
},
},
props: {
// 父组件传递回来的数据
res: {
type: null,
default: "",
},
},
mounted() {},
methods: {},
};
</script>
<style lang="scss" scoped>
.proText {
font-size: 26rpx;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: 400;
text-align: left;
color: #333333;
margin-left: 20rpx;
}
.wrapper {
display: block;
}
/deep/ .u-mode-light-error {
border: none;
}
.res_prom_item {
margin: 20rpx 0;
}
.price_image {
display: block;
}
</style>

View File

@@ -0,0 +1,129 @@
<template>
<view>
<view v-for="(promotionItem,promotionIndex) in promotion" :key="promotionIndex" class="promotion_row" @click="shutMask(1)">
<view v-if="res!=null" v-for="(item, index) in Object.keys(res)" :key="index">
<div class="promotion_col" v-if="item.split('-')[0] == promotionItem.value && item.split('-')[0] == 'FULL_DISCOUNT'">
<!-- 满减折扣 -->
<div class="flex">
<view class="deg_tag">{{promotionItem.title}}</view>
<div class="text proText">{{ res[item].fullMoney }}立享优惠</div>
</div>
</div>
<div class="promotion_col" v-if="item.split('-')[0] == promotionItem.value && item.split('-')[0] == 'PINTUAN'">
<!-- 拼团 -->
<div class="flex">
<view class="deg_tag">{{promotionItem.title}}</view>
<div class="text proText">{{ res[item].promotionName }}</div>
</div>
</div>
<div class="promotion_col" v-if="item.split('-')[0] == promotionItem.value && item.split('-')[0] == 'SECKILL'">
<!-- 限时抢购 -->
<div class="flex">
<view class="deg_tag">{{promotionItem.title}}</view>
<div class="text proText">{{ res[item].promotionName }}</div>
</div>
</div>
</view>
<view class="promotion_row" style="display:inline;">
<view>
<div class="promotion_col coupon" v-if="couponList && promotionIndex ==1">
<!-- 优惠券 -->
<div>
<view class="deg_tag">优惠券</view>
</div>
</div>
</view>
</view>
</view>
<view v-if=" this.res != null && Object.keys(res).length == 0">
暂无促销信息
</view>
</view>
</template>
<script>
import promotion from "./promotion_type";
export default {
data() {
return {
promotion,
couponList: "",
};
},
props: {
// 父组件传递回来的数据
res: {
type: null,
default: {},
},
},
watch: {
res: {
handler() {
if (this.res && this.res.length != 0 && this.res != null) {
Object.keys(this.res).forEach((item) => {
let key = item.split("-")[0];
this.res[item].__key = key;
if (item.split("-")[0] == "COUPON") {
this.couponList = "COUPON";
}
});
}
},
immediate: true,
},
},
mounted() {},
methods: {
// 此方法条用父级方法
shutMask(val) {
this.$emit("shutMasks", val);
},
},
};
</script>
<style lang="scss" scoped>
.deg_tag {
color: $jd-color;
padding: 0 4rpx;
border: 2rpx solid $jd-color;
font-size: 22rpx;
}
.promotion_col {
/**/
// margin: 0 0 17rpx 0;
padding: 0 !important;
margin: 10rpx 0;
}
.promotion_row {
display: flex;
align-items: center;
}
.flex {
display: flex;
}
.proText {
font-size: 26rpx;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: 400;
text-align: left;
color: #333333;
margin-left: 20rpx;
}
/deep/ .u-mode-light-error {
border: none;
}
</style>

View File

@@ -0,0 +1,6 @@
### promotion 促销显示
### promotion-details 促销详情
### promotion-assemble-promotions 限时抢购,团购活动条
### promotion-assemble-group 拼团活动条
### promotion-assemble-list 拼团活动用户列表
### promotion-coupon 优惠券组件

View File

@@ -0,0 +1,80 @@
.group-wrapper {
background: url("/static/exchange.png");
background-size: cover;
}
.u-group-row {
width: 100%;
padding: 0 32rpx;
display: flex;
height: 100rpx;
align-items: center;
justify-content: space-between;
}
.showBox_L {
// background: #ff6262;
height: 100%;
color: #fff;
flex: 2;
}
.flex-price {
color: #fff;
font-size: 48rpx;
}
.u-group-flex-left {
display: flex;
flex-direction: column;
}
.u-group-flex-left-span {
line-height: 1.2;
font-size: 32rpx;
}
.showBox_R {
flex: 1;
height: 100%;
padding: 4rpx 0 !important;
background: #ffe7e6 !important;
text-align: center !important;
}
/deep/ .u-mode-light-error {
border: none;
}
.u-group-flex {
height: 100%;
align-items: center;
justify-content: space-between;
}
.u-group-flex,
.u-group-flex-right {
display: flex;
}
.u-group-flex-right {
height: 100%;
align-items: flex-end;
display: flex;
flex-direction: column;
justify-content: center;
}
.old-price {
color: #fff;
text-decoration: line-through;
font-size: 22rpx;
opacity: 0.8;
}
.u-group-flex-left {
height: 100%;
}
.group-bag {
font-size: 20rpx;
padding: 4rpx 20rpx;
border-radius: 6rpx;
margin-right: 20rpx;
}
.promotion {
font-size: 22rpx;
border: 2rpx solid $jd-light-color;
padding: 2rpx 6rpx;
margin-left: 10rpx;
line-height: 1;
}

View File

@@ -0,0 +1,49 @@
const promotion = [
{
title: "积分活动",
value: "POINT",
},
{
title: "单品立减",
value: "MINUS",
},
{
title: "团购",
value: "GROUPBUY",
},
{
title: "积分换购",
value: "EXCHANGE",
},
{
title: "第二件半价",
value: "HALF_PRICE",
},
{
title: "满减优惠",
value: "FULL_DISCOUNT",
},
{
title: "限时抢购",
value: "SECKILL",
},
{
title: "拼团",
value: "PINTUAN",
},
{
title: "优惠券",
value: "COUPON",
},
];
export default promotion
/**格式化 */
export function formatType(val){
if(val != undefined){
promotion.forEach(item=>{
if(val == item.value){
return item.title
}
})
}
}

View File

@@ -0,0 +1,218 @@
<template>
<view v-if="storeDetail">
<!-- 商店信息 -->
<view class="store-info" >
<view class="logo">
<u-image width="120rpx" mode="aspectFit" height="120rpx" :src="storeDetail.storeLogo"></u-image>
</view>
<view class="name-star star-con">
<text class="name">{{ storeDetail.storeName }}</text>
<view>
<text :class="{ star: storeDetail.store_service_credit > 0 }"></text>
<text :class="{ star: storeDetail.store_service_credit > 1 }"></text>
<text :class="{ star: storeDetail.store_service_credit > 2 }"></text>
<text :class="{ star: storeDetail.store_service_credit > 3 }"></text>
<text :class="{ star: storeDetail.store_service_credit > 4 }"></text>
</view>
</view>
<view class="to-store-btn" @click="tostorePage(goodsDetail)">
<view>进店逛逛</view>
</view>
</view>
<view class="store-recommend" id="main8">
<view class="store-recommend-title">商品推荐</view>
<view class="recommend-list">
<view class="recommend-item" @click="clickGoods(item)" v-for="(item, index) in res" :key="index">
<u-image class="recommend-item-img" :fade="true" duration="450" :lazy-load="true" :src="item.thumbnail" height="218rpx">
<u-loading slot="loading"></u-loading>
<view slot="error" style="font-size: 24rpx; ">加载失败</view>
</u-image>
<view class="recommend-item-name">
{{ item.goodsName }}
</view>
<view class="item-price" v-if="item.price != undefined">
<span class="item-price-blod">{{ Fixed(item.price)[0] }}</span>.{{ Fixed(item.price)[1] }}
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {};
},
props: ["res", "goodsDetail", "storeDetail"],
mounted() {},
methods: {
// 格式化金钱 1999 --> [1999,00]
Fixed(val) {
if (typeof val == "undefined") {
return val;
}
return val.toFixed(2).split(".");
},
// 点击商品
clickGoods(val) {
uni.navigateTo({
url: `/pages/product/goods?id=${val.id}&goodsId=${val.goodsId}`
});
},
tostorePage(val) {
uni.navigateTo({
url: "../product/shopPage?id=" + val.storeId,
});
},
},
};
</script>
<style lang="scss" scoped>
@import "../product.scss";
.recommend-item-name {
height: 70rpx;
color: #333;
font-weight: 400;
font-size: 24rpx;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.item-price-blod {
font-weight: bold;
font-size: 32rpx;
}
.recommend-item {
width: 30%;
margin: 10rpx 0rpx;
overflow: hidden;
border-radius: 12rpx;
/deep/ .u-image__image {
height: 218rpx;
border-radius: 12rpx !important;
}
}
.recommend-item-img {
/deep/ .u-image__image {
width: 100% !important;
}
}
.recommend-list-view {
width: 100%;
}
.store-info {
display: flex;
justify-content: space-between;
background: #fff;
padding: 40rpx 20rpx 50rpx;
.logo {
overflow: hidden;
border-radius: 6px;
> img {
width: 100%;
height: 100%;
}
}
.name-star {
flex: 1;
margin-left: 20rpx;
padding: 10rpx 0;
font-size: 30rpx;
.name {
width: 100%;
font-weight: 700;
font-size: 28rpx;
line-height: 24px;
}
}
.to-store-btn {
padding: 20rpx 0;
> view {
font-size: 24rpx;
color: #fff;
width: 160rpx;
height: 60rpx;
line-height: 60rpx;
text-align: center;
background: $main-color;
border-radius: 28rpx;
}
}
}
/* star */
.star-con {
display: flex;
flex-direction: column;
view {
flex: 1;
display: flex;
align-items: center;
.star {
width: 30rpx;
height: 30rpx;
background: url(https://image.shutterstock.com/image-vector/star-icon-vector-illustration-260nw-474687040.jpg);
background-size: 100%;
}
}
}
.recommend-list {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
/deep/ .u-row {
width: 100%;
}
.item-price {
margin: 10rpx 0 20rpx 0;
text-align: left;
font-weight: bold;
overflow: hidden;
white-space: nowrap;
margin: 18rpx 0;
font-size: 22rpx;
color: $jd-color;
}
.recommend-list-con {
display: flex;
flex-direction: column;
width: 32%;
margin-bottom: 24rpx;
}
.name {
overflow: hidden;
white-space: nowrap;
}
}
.store-recommend {
background: #fff;
margin: 20rpx 0 0 0;
}
</style>

View File

@@ -0,0 +1,369 @@
.red {
color: $jd-color;
}
page{
background: #fff;
}
.num-icon {
position: absolute;
right: 5rpx;
top: 5rpx;
padding: 2rpx 6rpx;
border-top: 4rpx;
border: 2rpx solid $jd-color;
color: $jd-color;
font-size: 22rpx;
border-radius: 200px;
line-height: 18rpx;
}
.detail-btn {
display: flex;
align-items: center;
> .to-buy {
background-image: linear-gradient(135deg, #ffba0d, #ffc30d 69%, #ffcf0d);
}
> .to-store-car {
background-image: linear-gradient(135deg, #f2140c, #f2270c 70%, #f24d0c);
}
> .to-store-btn {
flex: 1;
width: 100%;
margin: 0 5rpx;
height: 80rpx;
text-align: center;
line-height: 80rpx;
color: #fff;
font-size: 26rpx;
border-radius: 214px;
padding: 0;
}
> .pt-buy {
line-height: 1.2;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
font-size: 22rpx;
}
}
.desc-blod {
flex: 8;
font-weight: 700;
color: #262626;
line-height: 42rpx;
font-size: 32rpx;
}
.-goods-desc {
padding: 36rpx 0 24rpx 0;
font-size: 24rpx;
color: #666;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
.-goods-flex {
display: flex;
justify-content: space-between;
align-items: center;
}
.favorite {
flex: 1;
font-size: 22rpx;
color: #262626;
display: flex;
flex-direction: column;
align-items: center;
}
.-goods-price {
flex: 8;
color: $jd-color;
font-size: 32rpx;
line-height: 1;
/deep/ .price {
font-size: 60rpx;
}
}
.-goods-name {
margin-top: 24rpx;
}
.top-radius-0 {
margin-top: 0 !important;
border-top-left-radius: 0 !important;
border-top-right-radius: 0 !important;
}
.-goods-msg {
min-height: 120rpx;
margin-top: 24rpx;
}
.recommend-item {
// padding: 0 !important;
margin: 20rpx 0rpx;
overflow: hidden;
border-radius: 12rpx;
/deep/ .u-image__image {
// width: 228rpx;
height: 228rpx;
border-radius: 12rpx !important;
}
}
.detail_padding {
padding: 12px 20rpx 0 20rpx;
> .tips {
color: #000;
font-size: 30rpx;
font-weight: 400;
margin-bottom: 28rpx;
}
}
.headerRow {
display: flex;
width: 100%;
background: #fff !important;
> div {
flex: 1;
}
> .headerList {
flex: 8;
}
justify-content: space-between;
}
.scoll-hide {
opacity: 0;
transition: all 0.5s;
}
.cur {
color: #333;
border-bottom: 6rpx solid $main-color;
}
.header {
position: fixed;
top: var(--status-bar-height);
width: 100%;
z-index: 8;
height: 90rpx;
line-height: 90rpx;
font-size: 30rpx;
transition: all 0.5s;
color: #666666;
background-color: #fff;
.tab-bar {
width: 100%;
color: #666;
font-weight: 400;
view {
padding: 0 3px;
}
}
&.bg-none {
background: transparent;
}
}
.page-bottom {
position: fixed;
bottom: 0;
left: 0;
z-index: 9;
background: #fff;
height: 100rpx;
width: 100%;
display: flex;
border-top: 2rpx solid #f2f2f2;
box-sizing: border-box;
> .icon-btn {
display: flex;
align-items: center;
flex: 1;
> .icon-btn-item {
flex: 1;
position: relative;
text-align: center;
font-size: 22rpx;
color: #262626;
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
align-items: center;
justify-content: center;
> .icon-btn-name {
margin: 4rpx 0;
}
}
}
> .detail-btn {
flex: 1.5;
}
}
.main-page {
height: calc(100% - var(--status-bar-height)) ;
overflow: hidden;
}
.backs {
// width: 150rpx;
text-align: center;
font-size: 42rpx;
line-height: 90rpx;
}
.headerImg {
width: 50rpx;
height: 50rpx;
vertical-align: middle;
}
.shareImg {
width: 36rpx;
height: 36rpx;
vertical-align: middle;
}
.item-spec-value {
box-sizing: border-box;
margin: 10rpx;
padding: 10rpx 20rpx;
float: left;
}
.item-spec-value {
background: #ededed;
}
page {
background: #f0f0f0;
height: 100%;
}
.product-container {
// background: #f0f0f0;
.header-line {
height: 1px;
background: #f2f2f2;
position: fixed;
top: 90rpx;
left: 0;
right: 0;
z-index: 999;
transition: all 0.5s;
&.scoll-hide {
background: none;
}
}
.scoll-page {
width: 100%;
height: 100%;
}
/* 弹出层 */
.popup {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: -1px;
z-index: 9;
background: rgba(0, 0, 0, 0.5);
.mask {
position: absolute;
left: 0;
top: 30%;
right: 0;
bottom: 0;
background: #fff;
.title {
position: relative;
height: 90rpx;
line-height: 90rpx;
font-size: 32rpx;
text-align: center;
border-bottom: 1px solid #f2f2f2;
span {
position: absolute;
right: 30rpx;
font-size: 40rpx;
}
}
.con-cuxiao {
padding: 30rpx 30rpx 0 30rpx;
> text {
font-size: 26rpx;
color: #999;
}
}
}
}
}
.u-mode-light-error {
border: none;
}
.showBack {
height: 60rpx;
line-height: 60rpx;
position: fixed;
margin-top: calc( 10px);
z-index: 8;
width: 100%;
/deep/ .u-row {
width: 100%;
}
}
.u-mode-light-error {
background: #ffebec !important;
padding: 8rpx 16rpx;
font-size: 20rpx;
}
.showBox {
width: 100%;
height: 90rpx;
background: #ff6262;
color: #fff;
padding: 0 20rpx;
/deep/ .price {
font-size: 36rpx;
font-weight: 400;
text-align: left;
letter-spacing: 1px;
color: #ffffff;
line-height: 90rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.status_bar{
background: #fff;
height: var(--status-bar-height);
}

272
pages/product/shopPage.vue Normal file
View File

@@ -0,0 +1,272 @@
<template>
<view class="store-page">
<view class="status_bar">
<!-- 这里是状态栏 -->
</view>
<view class="header">
<div class="search">
<u-icon @click="back" style="margin:0 10rpx 0;" name="arrow-left" size="40" color="#fff"></u-icon>
<u-search :show-action="false" border-color="#fff" bg-color="#fff" v-model="keyword" @search="search" placeholder="请输入搜索" />
<!-- <input /> -->
<u-icon @click="shareChange()" style="margin:0 10rpx 0;" name="share-fill" size="40" color="#fff"></u-icon>
</div>
<view class="tab-header">
<text :class="{ cur: tabIndex == 0 }" @click="setCat(0)">首页</text>
<text :class="{ cur: tabIndex == 1 }" @click="setCat(1)">商品</text>
<!-- <text :class="{ cur: tabIndex == 2 }" @click="setCat(2)">上新</text> -->
</view>
</view>
<swiper :current="tabIndex" class="swiper-box" @change="ontabchange">
<swiper-item class="swiper-item" v-for="(item, index) in indexCats" :key="index">
<scroll-view class="scroll-v" scroll-anchoring enableBackToTop="true" scroll-y @refresherrefresh="refresh()" @scroll="pageScroll">
<storePageMain :load="load" :storeId="storeId" v-if="index == 0"></storePageMain>
<storePageGoods :load="load" :pageChange="pageChange" :categoryId="item" :storeId="storeId" v-if="index == 1"></storePageGoods>
</scroll-view>
</swiper-item>
</swiper>
<!-- 分享 -->
<shares type="shops" :link="'/pages/product/shopPage?id='+ this.storeId" v-if="shareFlage" @close="shareFlage = false" />
</view>
</template>
<script>
import shares from "@/components/m-share/index"; //分享
import storePageMain from "./shopPageMain.vue";
import storePageGoods from "./shopPageGoods.vue";
import { getstoreBaseInfo } from "@/api/store.js";
export default {
components: {
shares,
storePageMain,
storePageGoods,
},
data() {
return {
shareFlage: false,
tabIndex: 0,
keyword: "",
load: false,
storeId: undefined,
indexCats: [0, 1],
scrollHeight: "",
loadIndex: 1, //加载的距离
pageChange: "",
storeInfo: {},
};
},
async onLoad(options) {
this.storeId = options.id;
console.log(this.storeId);
getstoreBaseInfo(this.storeId).then((res) => {
this.storeInfo = res.data;
});
},
mounted() {
const { windowWidth, windowHeight } = uni.getSystemInfoSync();
let tabHeader = 0;
let topHeight = 0;
uni.getSystemInfo({
success: function (res) {
// res - 各种参数
let search = uni.createSelectorQuery().select(".header");
search
.boundingClientRect(function (data) {
//data - 各种参数
topHeight = data.height; // 获取元素宽度
})
.exec();
let nav = uni.createSelectorQuery().select(".tab-header");
nav
.boundingClientRect(function (data) {
//data - 各种参数
tabHeader = data.height; // 获取元素宽度
})
.exec();
},
});
},
methods: {
// 点击分享
async shareChange() {
this.shareFlage = true;
},
search() {
uni.navigateTo({
url: `/pages/navigation/search/searchPage?storeId=${this.storeId}&keyword=${this.keyword}`,
});
},
pageScroll(e) {
if (e.detail.scrollTop > 300 * this.loadIndex) {
this.loadIndex++;
this.load = this.loadIndex;
}
// this.load = false;
},
back() {
uni.navigateBack();
},
setCat(type) {
this.tabIndex = type;
},
ontabchange(e) {
this.tabIndex = e.detail.current;
this.setCat(this.tabIndex);
},
},
};
</script>
<style>
page {
height: 100%;
}
</style>
<style lang="scss" scoped>
// #ifdef MP-WEIXIN
@import "./mp-shopPage.scss";
// #endif
input[type="search"] {
-webkit-appearance: none;
// 也可以去除加上border: 0;之类的 根据设计图来
}
input::-webkit-search-cancel-button {
display: none;
}
// 关闭的按钮
.storeScrollBox {
overflow-y: auto;
}
.store-page {
height: 100%;
// background: #fff;
overflow: auto;
.tab-header {
height: 80rpx;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 28rpx;
z-index: 9999;
text {
width: 50%;
text-align: center;
position: relative;
color: #fff;
&.cur {
font-size: 30rpx;
font-weight: bold;
color: #fff;
&::after {
content: "";
position: absolute;
width: 30rpx;
border: 1px solid #fff;
bottom: -6rpx;
left: 50%;
margin-left: -15rpx;
}
}
}
}
.header-line {
height: 1px;
background: #f2f2f2;
position: fixed;
top: 170rpx;
left: 0;
right: 0;
z-index: 999;
}
}
.swiper-box {
width: 750rpx;
height: calc(
100% - var(--status-bar-height) - var(--window-top) - var(--window-bottom) -
(160rpx) - 16rpx - 28rpx
);
// #ifdef H5
height: calc(
100% - var(--status-bar-height) - var(--window-top) - var(--window-bottom) -
(160rpx)
);
// #endif
}
.swiper-item {
height: 100%;
}
.scroll-v {
width: 750rpx;
height: 100%;
overflow-y: auto;
}
.status_bar {
height: calc(var(--status-bar-height) + 160rpx);
width: 100%;
background-image: linear-gradient(
25deg,
$main-color,
$light-color,
$aider-light-color
);
}
.header {
width: 100%;
position: fixed;
top: var(--status-bar-height);
padding: 16rpx 0 0;
font-size: 30rpx;
z-index: 9999;
> .search {
width: 100%;
display: flex;
align-items: center;
.back {
width: 90rpx;
height: 90rpx;
}
.input-wrap {
background: $light-color;
width: 600rpx;
height: 58rpx;
padding: 10rpx 30rpx 10rpx 30rpx;
box-sizing: border-box;
background-color: #fff;
border-radius: 50rpx;
position: relative;
border: 1px solid $light-color;
input {
font-size: 26rpx;
}
}
}
}
</style>

View File

@@ -0,0 +1,340 @@
<template>
<view class="index-content">
<!-- 搜索板块 -->
<view class="index-navs">
<view class="index-nav" :class="{ 'index-nav-active': nav == 1 }" @click="tabClick(1)">精选</view>
<view class="index-nav-divider"></view>
<view class="index-nav" :class="{ 'index-nav-active': nav == 2}" @click="tabClick(2,'buyCount')">
销量
<view class="index-nav-arrows">
<view class="index-nav-arrow">
<image src="/static/index/arrow-up-1.png" v-if="params.sort === 'buyCount' && params.order === 'asc'" mode="aspectFit"></image>
<image src="/static/index/arrow-up.png" v-else mode="aspectFit"></image>
</view>
<view class="index-nav-arrow">
<image src="/static/index/arrow-down.png" v-if="params.sort === 'buyCount' && params.order === 'desc'" mode="aspectFit"></image>
<image src="/static/index/arrow-down-1.png" v-else mode="aspectFit"></image>
</view>
</view>
</view>
<view class="index-nav-divider"></view>
<view class="index-nav" :class="{ 'index-nav-active': nav == 3}" @click="tabClick(3,'price')">
价格
<view class="index-nav-arrows">
<view class="index-nav-arrow">
<image src="/static/index/arrow-up-1.png" v-if="params.sort === 'price' && params.order === 'asc'" mode="aspectFit"></image>
<image src="/static/index/arrow-up.png" v-else mode="aspectFit"></image>
</view>
<view class="index-nav-arrow">
<image src="/static/index/arrow-down.png" v-if="params.sort === 'price' && params.order === 'desc'" mode="aspectFit"></image>
<image src="/static/index/arrow-down-1.png" v-else mode="aspectFit"></image>
</view>
</view>
</view>
</view>
<scroll-view scroll-with-animation scroll-y class="scoll-page" @scroll="pageScroll">
<view class="index-items">
<view class="index-item" v-for="(goods, index) in goodsList" :key="index" @click="toGoodsDetail(goods)">
<view class="index-item-img">
<u-image mode="aspectFit" height="160px" width="173px" class="index-item-store-img" :src="goods.thumbnail">
<u-loading slot="loading"></u-loading>
</u-image>
<view class="index-item-title">
<div> {{ goods.goodsName }}</div>
<view class="index-item-title-desc" v-if="goods.sellingPoint ">{{ goods.sellingPoint }}</view>
</view>
<view class="index-item-price">
<div class="price">{{ goods.price | unitPrice }}</div>
<view class="index-item-sale">
已售 {{ goods.buyCount || "0" }}
<!-- 好评90% -->
</view>
</view>
</view>
</view>
</view>
<u-loadmore bg-color="#f6f6f6" @loadmore="loadMore" :status="loadStatus" />
</scroll-view>
</view>
</template>
<script>
import { getGoodsList } from "@/api/goods.js";
export default {
props: {
storeId: {
value: Number,
},
categoryId: {
value: Number,
default: 0,
},
load: {
value: Number,
},
},
data() {
return {
loadStatus: "loadmore", //加载更多状态
nav: 1,
// 默认双列显示
goodsListTemplate: 2,
// 过滤参数
curCateFid: "",
params: {
pageNumber: 1,
pageSize: 10,
storeId: this.storeId,
},
goodsList: [],
cateList: [
{ name: "综合", value: "100001" },
{ name: "推荐", value: "100002" },
{ name: "信用", value: "100003" },
],
typeSort1: true,
typeSort2: false,
};
},
watch: {
load(val) {
this.params.pageNumber = val;
this.loadMore();
},
},
onReachBottom() {
console.log("触发");
this.loadMore();
},
mounted() {
this.initGoodsInfo();
},
methods: {
pageScroll(e) {},
loadMore() {
this.initGoodsInfo();
},
tabClick(index, type) {
this.goodsList = [];
this.params.pageNumber = 0;
this.params.pageSize = 10;
this.nav = index;
if (this.params.sort == type) {
this.params.order == "asc"
? (this.params.order = "desc")
: (this.params.order = "asc");
this.$set(this.params, "sort", type);
} else {
this.params.order = "desc";
this.$set(this.params, "sort", type);
}
this.initGoodsInfo();
},
toGoodsDetail(val) {
uni.navigateTo({
url: `/pages/product/goods?id=${val.id}&goodsId=${val.goodsId}`,
});
},
initGoodsInfo() {
this.params.storeId = this.storeId;
getGoodsList(this.params).then((res) => {
if (
res.data.result.totalElements <=
res.data.result.number * res.data.result.size
) {
console.warn(res.data.result.totalElements);
this.loadStatus = "noMore";
} else {
console.log(res.data.result.totalElements);
this.loadStatus = "loadmore";
}
this.goodsList.push(...res.data.result.content);
});
},
// 点击了右侧的模板选择按钮:即单列还是双列展示商品
goodsTemplateChanged(templateValue) {
this.goodsListTemplate = templateValue;
},
},
};
</script>
<style lang="scss" scoped>
.scoll-page {
height: 100%;
}
.store-items {
padding-top: 20rpx;
display: -webkit-box;
display: -webkit-flex;
display: flex;
align-items: center;
flex-direction: column;
}
.store-item {
width: 710rpx;
height: 226rpx;
padding-left: 20rpx;
margin-bottom: 10rpx;
border-radius: 12rpx;
background-color: #fff;
position: relative;
display: -webkit-box;
display: -webkit-flex;
display: flex;
align-items: center;
}
.store-item-img {
margin-right: 20rpx;
image {
width: 186rpx;
height: 186rpx;
border-radius: 8rpx;
}
}
.store-item-title {
font-size: 28rpx;
color: #333;
}
.store-item-title-desc {
font-size: 22rpx;
color: #999;
}
.store-item-price {
font-size: 110rpx;
color: #ff5a10;
padding-top: 10rpx;
}
.store-item-sale {
font-size: 25rpx;
color: #999;
padding-top: 10rpx;
}
.index-navs {
height: 120rpx;
margin-top: -10rpx;
padding: 0 52rpx;
background-color: #f7f7f7;
display: -webkit-box;
display: -webkit-flex;
display: flex;
align-items: center;
justify-content: space-between;
}
.index-item-store-img {
width: 346rpx !important;
height: 320rpx !important;
}
.index-nav {
font-size: 30rpx;
display: -webkit-box;
display: -webkit-flex;
display: flex;
justify-content: center;
align-items: center;
&-active {
color: $aider-light-color;
font-weight: 700;
&::after {
content: "";
position: absolute;
width: 30rpx;
border: 1px solid $aider-light-color;
bottom: -6rpx;
left: 96rpx;
}
}
}
.index-nav-desc {
margin-top: 8rpx;
font-size: 22rpx;
color: #999;
}
.index-nav-divider {
height: 64rpx;
border-left: 1px solid #dddddd;
}
.index-nav-arrows {
display: -webkit-box;
display: -webkit-flex;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.index-nav-arrow {
image {
width: 26rpx;
height: 26rpx;
}
}
.index-nav-arrow:last-child {
margin-top: -26rpx;
}
.index-items {
padding-left: 20rpx;
background-color: #f7f7f7;
display: -webkit-box;
display: -webkit-flex;
display: flex;
align-items: center;
flex-wrap: wrap;
}
.index-item {
width: 346rpx;
padding-bottom: 10rpx;
background-color: #fff;
margin: 0 18rpx 20rpx 0;
border-radius: 16rpx;
box-sizing: border-box;
overflow: hidden;
}
.index-item-img {
image {
width: 346rpx;
height: 320rpx;
}
}
.index-item-title {
font-size: 26rpx;
color: #333333;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
padding: 0 0 0 20rpx;
box-sizing: border-box;
}
.index-item-title-desc {
font-size: 25rpx;
color: #999999;
margin-top: 10rpx;
}
.index-item-price {
padding: 0 20rpx;
> .price {
font-weight: 500;
color: $main-color;
font-size: 30rpx;
margin-top: 20rpx;
white-space: nowrap;
}
> .index-item-sale {
font-size: 24upx;
color: #999;
}
}
</style>

View File

@@ -0,0 +1,632 @@
<template>
<view class="store-page">
<view>
<!-- 商店信息 -->
<view class="store-info">
<view class="logo">
<image :src="storeInfo.storeLogo || '/static/logo.png'" mode="aspectFit"></image>
</view>
<view class="store-name">
<view class="name">{{ storeInfo.storeName }}</view>
<view>{{ storeInfo.goodsNum || 0 }}关注 {{ storeInfo.collectionNum || 0 }}件商品</view>
</view>
<view class="follow" @click="handleCollection">
<view>{{ isCollection == 'success' ? '已关注' : '+ 关注' }}</view>
</view>
</view>
<view class="store-intro">
<view class="title">店铺简介</view>
<view class="text" :class="introFlag ? 'close' : 'open'">
<view v-html="storeInfo.storeDesc"></view>
<!-- <view class="zhankai" :class="introFlag ? 'close' : 'open'" @click="shut"></view> -->
</view>
</view>
<!-- 优惠券 -->
<scroll-view scroll-x="true" show-scrollbar="false" class="discount" v-if="couponList.length > 0">
<view class="card-box" v-for="(item, index) in couponList" :key="index">
<view class="card" @click="getCoupon(item)">
<view class="money">
<view>
<span v-if="item.couponType == 'DISCOUNT'">{{ item.couponDiscount }}</span>
<span v-else>{{ item.price }}</span>
</view>
</view>
<view class="xian"></view>
<view class="text">
<text>{{'领取优惠券' }}</text>
<text>{{ item.consumeThreshold | unitPrice }}元可用</text>
</view>
</view>
</view>
</scroll-view>
<!-- 店铺热卖 -->
<!-- <view class="hot">
<view class="title">店铺热卖</view>
<scroll-view scroll-x="true" class="contant">
<view v-if="!hotGoods.length" class="no-goods">暂无商品信息</view>
<view v-else class="item-box" v-for="(item,index) in hotGoods" :key="index" @click="toGoodsDetail(item.goods_id)">
<view class="item">
<u-image width="106px" height="106px" class="item-img" :src="item.thumbnail" mode="">
<u-loading slot="loading"></u-loading>
</u-image>
<text class="name">{{ item.goodsName }}</text>
<text class="price">
<text>{{ item.price }}</text>
{{ item.point ? '+' + item.point + '积分' : '' }}
</text>
</view>
</view>
</scroll-view>
</view> -->
<!-- 精选商品 -->
<view class="handpick">
<view class="title">精选商品</view>
<view class="contant">
<view v-if="!recommandGoods.length" class="no-goods">暂无商品信息</view>
<view v-else class="item" v-for="(item,index) in recommandGoods" :key="index" @click="toGoodsDetail(item)">
<u-image width="324rpx" height="324rpx" mode="aspectFit" :src="item.thumbnail">
<u-loading slot="loading"></u-loading>
</u-image>
<div class="name">{{ item.goodsName }}</div>
<div class="price">
<div>{{ item.price | unitPrice }}</div>
<!-- {{ item.point ? '+' + item.point + '积分' : '' }} -->
<!-- <text class="before-price">{{ item.price }}</text> -->
</div>
<view class="buyCount">
<div>已售 {{ item.buyCount || "0" }}</div>
<text>
<!-- 好评{{ 1111 }} -->
</text>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { getstoreBaseInfo } from "@/api/store.js";
import {
receiveCoupons,
deleteGoodsCollection,
collectionGoods,
getGoodsIsCollect,
} from "@/api/members.js";
import { getGoodsList } from "@/api/goods.js";
import { getAllCoupons } from "@/api/promotions.js";
import storage from "@/utils/storage.js";
export default {
props: {
storeId: {
value: Number,
},
load:{
value:Boolean
}
},
data() {
return {
// 店铺介绍按钮
introFlag: true,
storeInfo: [],
isCollection: false,
hotGoods: [],
recommandGoods: [],
couponList: [],
lingquFlag: true,
params: {
pageNumber: 1,
pageSize: 50,
storeId: "",
},
};
},
watch: {
},
mounted(options) {
if (this.$options.filters.isLogin("auth")) {
getGoodsIsCollect("STORE", this.storeId).then((res) => {
this.isCollection = res.data.message;
});
}
this.initstoreInfo();
},
methods: {
initstoreInfo() {
uni.showLoading({
title: "加载中",
});
this.params.storeId = this.storeId;
getstoreBaseInfo(this.storeId).then((res) => {
if (res.data.success) {
this.storeInfo = res.data.result;
uni.hideLoading();
Promise.all([
getAllCoupons(this.params),
getGoodsList({ storeId: this.storeId }),
,
]).then((res) => {
this.couponList = res[0].data.result.records;
this.hotGoods = res[1].data.result.content;
this.recommandGoods = res[1].data.result.content;
});
} else {
uni.reLaunch({
url: "/",
});
}
});
},
shut() {
this.introFlag = !this.introFlag;
},
toGoodsDetail(val) {
uni.navigateTo({
url: `/pages/product/goods?id=${val.id}&goodsId=${val.goodsId}`,
});
},
handleCollection() {
if (this.isCollection) {
deleteGoodsCollection("STORE", this.storeId).then((res) => {
if (res.statusCode === 200) {
this.isCollection = "error";
uni.showToast({
icon: "none",
duration: 3000,
title: "取消关注成功!",
});
}
});
} else {
collectionGoods("STORE", this.storeId).then((res) => {
if (res.statusCode === 200) {
this.isCollection = "success";
uni.showToast({
icon: "none",
duration: 3000,
title: "关注成功!",
});
}
});
}
},
getCoupon(item) {
if (!this.$options.filters.isLogin("auth")) {
uni.showToast({
icon: "none",
duration: 3000,
title: "请先登录!",
});
uni.redirectTo({
url: "/pages/passport/login",
});
return false;
}
receiveCoupons(item.id).then((res) => {
if (res.data.success) {
uni.showToast({
icon: "none",
duration: 3000,
title: "领取成功!",
});
}
});
},
},
};
</script>
<style lang="scss" scoped>
.store-page {
height: 100%;
background: #fff;
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
background: #fff;
display: flex;
justify-content: space-between;
align-items: center;
height: 90rpx;
line-height: 90rpx;
font-size: 30rpx;
z-index: 9999;
.back {
width: 90rpx;
height: 90rpx;
background: url(/static/global/select.png) center no-repeat;
background-size: 50%;
}
.input-wrap {
width: 600rpx;
height: 58rpx;
padding: 10rpx 30rpx 10rpx 100rpx;
box-sizing: border-box;
background-color: #fff;
border-radius: 50rpx;
position: relative;
border: 1px solid #29bb9c;
background: url(/static/global/select.png) center left no-repeat;
background-position: 40rpx;
input {
font-size: 26rpx;
}
}
.share {
width: 90rpx;
height: 90rpx;
background: url(/static/global/select.png) center no-repeat;
background-size: 50%;
}
}
.tab-header {
position: fixed;
top: 90rpx;
left: 0;
right: 0;
height: 100rpx;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 30rpx;
z-index: 9999;
background: #fff;
text {
width: 30%;
text-align: center;
&.cur {
color: #29bb9c;
font-size: 34rpx;
font-weight: 500;
}
}
}
.header-line {
height: 1px;
background: #f2f2f2;
position: fixed;
top: 190rpx;
left: 0;
right: 0;
z-index: 999;
}
.store-info {
display: flex;
justify-content: space-between;
padding: 40rpx 40rpx 30rpx;
.logo {
width: 128rpx;
height: 128rpx;
overflow: hidden;
border-radius: 6px;
image {
width: 128rpx;
height: 128rpx;
}
}
.store-name {
text-align: center;
font-size: 26rpx;
color: #999;
margin-left: -50rpx;
.name {
margin: 20rpx 0 16rpx;
font-size: 30rpx;
color: #333;
text-align: left;
}
}
.follow {
padding: 40rpx 0;
> view {
font-size: 26rpx;
color: #fff;
padding: 0 30rpx;
height: 56rpx;
display: flex;
align-items: center;
justify-content: center;
background: $aider-light-color;
border-radius: 28rpx;
text {
font-size: 40rpx;
}
}
}
}
.store-intro {
padding: 0 40rpx 18rpx;
.title,
.text {
font-size: 26rpx;
color: #999999;
line-height: 48rpx;
}
.title {
padding-left: 20rpx;
position: relative;
&:before {
content: "";
width: 1px;
height: 45rpx;
background: #999;
position: absolute;
left: 0;
top: 0;
}
}
.text {
position: relative;
&.close {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding-right: 46rpx;
}
&.open {
padding-right: 0;
white-space: wrap;
overflow: auto;
text-overflow: clip;
}
.zhankai {
width: 20rpx;
height: 20rpx;
position: absolute;
right: 10rpx;
bottom: 0;
border-top: 3px solid #999;
border-right: 3px solid #999;
&.close {
transform: rotateZ(135deg);
bottom: 15rpx;
}
&.open {
transform: rotateZ(-45deg);
}
}
}
}
.discount {
height: 189rpx;
border-top: 1px solid #f6f6f6;
border-bottom: 18rpx solid #f6f6f6;
background: #f6f6f6;
overflow: hidden;
white-space: nowrap;
.card-box {
display: inline-block;
padding-top: 25rpx;
}
.card {
width: 324rpx;
height: 116rpx;
background: #fff;
margin-left: 20rpx;
border-radius: 5px;
display: flex;
align-items: center;
.money {
width: 45%;
color: #fd6466;
font-weight: 500;
text-align: center;
text {
font-size: 50rpx;
}
}
.xian {
height: 66rpx;
border: 1px dashed #f6f6f6;
position: relative;
&:before,
&:after {
content: "";
width: 22rpx;
height: 12rpx;
position: absolute;
background: #f6f6f6;
}
&:before {
border-radius: 0 0 22rpx 22rpx;
top: -30rpx;
left: -10rpx;
}
&:after {
border-radius: 22rpx 22rpx 0 0;
bottom: -30rpx;
left: -10rpx;
}
}
.text {
flex: 1;
color: $aider-light-color;
font-size: 24rpx;
display: flex;
flex-direction: column;
margin-left: 14rpx;
text:nth-of-type(2) {
color: #ccc;
}
.cur:nth-of-type(1) {
color: #ccc;
}
}
}
}
.hot,
.handpick {
.title {
height: 132rpx;
padding: 0 20rpx;
line-height: 132rpx;
font-size: 32rpx;
text-align: center;
position: relative;
&:before,
&:after {
content: "";
width: 44rpx;
height: 6rpx;
position: absolute;
background: #f0f1fc;
}
&:before {
top: 63rpx;
left: 236rpx;
}
&:after {
border-radius: 22rpx 22rpx 0 0;
top: 63rpx;
right: 236rpx;
}
}
.no-goods {
width: 100%;
height: 364rpx;
text-align: center;
line-height: 364rpx;
color: #999999;
}
}
.hot {
.contant {
height: 364rpx;
display: flex;
padding: 0 20rpx;
overflow: hidden;
white-space: nowrap;
.item-box {
display: inline-block;
}
.item {
width: 216rpx;
margin-left: 15rpx;
font-size: 24rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
image {
width: 212rpx;
height: 212rpx;
}
.name {
color: #333;
overflow: hidden;
text-overflow: ellipsis;
height: 66rpx;
}
.price {
font-weight: 500;
margin-bottom: 20rpx;
color: #fd6466;
text {
font-size: 26rpx;
}
}
}
}
border-bottom: 18rpx solid #f9f9f9;
}
.item-img-recommand {
width: 324rpx !important;
height: 324rpx !important;
}
.item-img {
width: 212rpx !important;
height: 212rpx !important;
}
.handpick {
background: #fff;
.contant {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 0 40rpx;
.item {
width: 324rpx;
height: 484rpx;
font-size: 26rpx;
display: flex;
flex-direction: column;
border: 1px solid #f8f8f8;
margin-bottom: 20rpx;
image {
width: 324rpx;
height: 260rpx;
}
.name {
text-align: left !important;
color: #333;
padding: 0 20rpx;
margin-top: 20rpx;
line-height: 1.4em;
max-height: 2.8em; //height是line-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;
}
}
}
}
.bottom {
background: #fff;
height: 90rpx;
text-align: center;
text {
color: #ccc;
font-size: 24rpx;
position: relative;
&:before {
content: "";
display: block;
width: 180rpx;
height: 1px;
background: #f0f1fc;
position: absolute;
top: 20rpx;
left: -270rpx;
}
&:after {
content: "";
display: block;
width: 180rpx;
height: 1px;
background: #f0f1fc;
position: absolute;
top: 20rpx;
right: -200rpx;
}
}
}
}
</style>

View File

@@ -0,0 +1,165 @@
<template>
<view class="storeNew">
<view class="storeNew-item" v-for="(value, key, index) in upGoodsMap" :key="key">
<view class="storeNew-item-title">{{ key }}</view>
<view class="index-items">
<view class="index-item" v-for="(item, _index) in value" :key="_index" @click="gotoGoodsDetail(item.goods_id)">
<view class="index-item-img">
<u-image height="160px" width="173px" class="index-item-store-img" :src="item.thumbnail">
<u-loading slot="loading"></u-loading>
</u-image>
<view class="index-item-title">
{{ item.name }}
<view class="index-item-title-desc">{{ item.storeName }}</view>
</view>
<!-- <view class="index-item-price">{{ '¥' + item.price }}{{ item.point ? '+'+item.point + '积分' : '' }}</view> -->
<view class="index-item-price">{{ '¥' + item.price }}</view>
<!-- <view class="index-item-tags">
<view class="index-item-tag"><uni-tag text="限购" type="error" :inverted="true" size="small"></uni-tag></view>
<view class="index-item-tag"><uni-tag text="秒杀" type="error" :inverted="true" size="small"></uni-tag></view>
</view> -->
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import uniTag from '@/components/uni-tag/uni-tag.vue';
import { getGoodsListUplog } from '@/api/goods.js';
export default {
props: {
storeId: {
value: Number
}
},
components: {
uniTag
},
data() {
return {
params: {
pageNumber: 1,
pageSize: 10,
storeId: this.storeId
},
upGoodsMap: {}
};
},
mounted(options) {
this.initUpGoodsInfo();
},
methods: {
gotoGoodsDetail(id) {
uni.navigateTo({
url: `/pages/product/goods?id=${id}`
});
},
initUpGoodsInfo() {
getGoodsListUplog(this.params).then(res => {
this.upGoodsMap = res.data;
})
}
}
};
</script>
<style lang="less" scoped>
.storeNew {
width: 100%;
}
.storeNew-item {
background-color: #fff;
}
.storeNew-item-title {
height: 132rpx;
line-height: 132rpx;
font-size: 32rpx;
text-align: center;
position: relative;
&:before,
&:after {
content: '';
width: 44rpx;
height: 6rpx;
position: absolute;
background: #f0f1fc;
}
&:before {
top: 63rpx;
left: 216rpx;
}
&:after {
border-radius: 22rpx 22rpx 0 0;
top: 63rpx;
right: 216rpx;
}
}
.index-items {
padding-left: 20 rpx;
background-color: #f7f7f7;
display: -webkit-box;
display: -webkit-flex;
display: flex;
align-items: center;
flex-wrap: wrap;
}
.index-item {
width: 346 rpx;
min-height: 2610 rpx;
background-color: #fff;
margin: 0 18 rpx 20 rpx 0;
border-radius: 16 rpx;
box-sizing: border-box;
overflow: hidden;
}
.index-item-store-img{
width: 346 rpx !important;
height: 320 rpx !important;
}
.index-item-img {
image {
width: 346 rpx;
height: 320 rpx;
}
}
.index-item-title {
font-size: 26 rpx;
color: #333333;
padding: 10 rpx 0 0 20 rpx;
box-sizing: border-box;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.index-item-title-desc {
font-size: 25 rpx;
color: #999999;
margin-top: 10 rpx;
}
.index-item-price {
font-size: 110 rpx;
color: #ff5a10;
padding: 10 rpx 0 0 20 rpx;
}
.index-item-tags {
padding-left: 20 rpx;
padding-top: 10 rpx;
display: -webkit-box;
display: -webkit-flex;
display: flex;
align-items: center;
flex-wrap: wrap;
}
.index-item-tag {
width: 100 rpx;
margin-right: 10 rpx;
}
</style>