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

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);
}