增加商品详情,订单列表,支付结果,订单详情等页面

master
wyy 2 years ago
parent 5b59e152bf
commit 30648951bc

@ -42,6 +42,39 @@
},
{
"path": "pages/register/register"
},
{
"path": "pages/prod/prod",
"style": {
"navigationBarTitleText": "商品详情"
}
},
{
"path": "pages/orderList/orderList",
"style": {
"backgroundTextStyle": "light",
"navigationBarTitleText": "订单列表",
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#fafafa"
}
},
{
"path": "pages/order-detail/order-detail",
"style": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "订单详情",
"navigationBarTextStyle": "black"
}
},
{
"path": "pages/pay-result/pay-result",
"style": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "支付结果",
"navigationBarTextStyle": "black"
}
}
],
"tabBar": {

@ -0,0 +1,247 @@
.container {
background: #f4f4f4;
}
.order-detail {
margin-bottom: 120rpx;
padding-bottom: 160rpx;
.delivery-addr {
padding: 20rpx 30rpx;
background: #fff;
.user-info {
line-height: 48rpx;
word-wrap: break-word;
word-break: break-all;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
.item {
font-size: 28rpx;
margin-right: 30rpx;
vertical-align: top;
display: inline-block;
}
}
.addr {
font-size: 26rpx;
line-height: 36rpx;
color: #999;
word-wrap: break-word;
}
}
}
.prod-item {
background-color: #fff;
margin-top: 15rpx;
font-size: 28rpx;
.item-cont {
.prod-pic {
image {
width: 180rpx;
height: 180rpx;
width: 100%;
height: 100%;
}
font-size: 0;
display: block;
width: 160rpx;
height: 160rpx;
overflow: hidden;
background: #fff;
margin-right: 16rpx;
}
display: flex;
align-items: center;
padding: 30rpx;
border-top: 2rpx solid #f1f1f1;
.prod-info {
margin-left: 10rpx;
font-size: 28rpx;
width: 100%;
position: relative;
height: 80px;
-webkit-flex: 1;
-ms-flex: 1;
-webkit-box-flex: 1;
-moz-box-flex: 1;
flex: 1;
.prodname {
font-size: 28rpx;
line-height: 40rpx;
max-height: 86rpx;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
word-break: break-all;
}
.prod-info-cont {
position: relative;
color: #999;
margin-top: 10rpx;
font-size: 24rpx;
.info-item {
color: #999;
height: 28rpx;
margin-top: 10rpx;
font-size: 24rpx;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
word-break: break-all;
width: 70%;
}
.number {
float: left;
margin-right: 20rpx;
}
}
}
}
.price-nums {
margin-top: 30rpx;
.prodprice {
color: #333;
height: 50rpx;
line-height: 50rpx;
font-size: 24rpx;
float: left;
}
.btn-box {
float: right;
text-align: right;
.btn {
padding: 6rpx 30rpx;
line-height: 36rpx;
margin-left: 20rpx;
font-size: 24rpx;
display: inline-block;
border: 2rpx solid #e4e4e4;
border-radius: 50rpx;
}
}
}
}
.order-msg {
background: #fff;
margin-top: 15rpx;
font-size: 28rpx;
.msg-item {
padding: 20rpx;
border-top: 2rpx solid #f1f1f1;
&:first-child {
border: 0;
}
.item {
display: flex;
padding: 10rpx 0;
align-items: center;
box-sizing: border-box;
.item-tit {
min-width: 140rpx;
color: #999;
line-height: 48rpx;
}
.item-txt {
flex: 1;
line-height: 48rpx;
}
.item-txt.remarks {
max-width: 600rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.copy-btn {
display: block;
margin-left: 20rpx;
border: 2rpx solid #e4e4e4;
padding: 6rpx 24rpx;
border-radius: 50rpx;
font-size: 24rpx;
line-height: 28rpx;
}
.item-txt.price {
text-align: right;
}
}
.item.payment {
border-top: 2rpx solid #f1f1f1;
color: #eb2444;
padding-top: 30rpx;
}
}
}
.order-detail-footer {
position: fixed;
bottom: 0;
width: 100%;
max-width: 750rpx;
background: #fff;
margin: auto;
display: -webkit-flex;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: flex;
padding: 22rpx 0;
font-size: 26rpx;
box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.05);
.dele-order {
margin-left: 20rpx;
line-height: 60rpx;
display: block;
margin-right: 20rpx;
width: 150rpx;
text-align: center;
}
.footer-box {
flex: 1;
text-align: right;
line-height: 60rpx;
.buy-again {
font-size: 26rpx;
color: #fff;
background: #eb2444;
border-radius: 50rpx;
padding: 10rpx 20rpx;
margin-right: 20rpx;
}
.apply-service {
font-size: 26rpx;
border-radius: 50rpx;
padding: 10rpx 20rpx;
border: 1px solid #e4e4e4;
margin-right: 20rpx;
}
}
}
.clearfix {
&:after {
content: " ";
display: table;
clear: both;
}
}
.order-state {
height: 70rpx;
line-height: 70rpx;
text-align: right;
margin-right: 20rpx;
.order-sts {
color: #eb2444;
font-size: 28rpx;
}
.order-sts.gray {
color: #999;
height: 32rpx;
line-height: 32rpx;
}
.order-sts.normal {
color: #333;
}
}

@ -0,0 +1,296 @@
<template>
<view class="container">
<view class="order-detail">
<view
v-if="userAddrDto"
class="delivery-addr"
>
<view class="user-info">
<text class="item">
{{ userAddrDto.receiver }}
</text>
<text class="item">
{{ userAddrDto.mobile }}
</text>
</view>
<view class="addr">
{{ userAddrDto.province }}{{ userAddrDto.city }}{{ userAddrDto.area }}{{
userAddrDto.area
}}{{ userAddrDto.addr }}
</view>
</view>
<!-- 商品信息 -->
<view
v-if="orderItemDtos"
class="prod-item"
>
<block
v-for="(item, index) in orderItemDtos"
:key="index"
>
<view
class="item-cont"
:data-prodid="item.prodId"
@tap="toProdPage"
>
<view class="prod-pic">
<image :src="item.pic" />
</view>
<view class="prod-info">
<view class="prodname">
{{ item.prodName }}
</view>
<view class="prod-info-cont">
<text class="number">
数量{{ item.prodCount }}
</text>
<text class="info-item">
{{ item.skuName }}
</text>
</view>
<view class="price-nums clearfix">
<text class="prodprice">
<text class="symbol">
</text>
<text class="big-num">
{{ wxs.parsePrice(item.price)[0] }}
</text>
<text class="small-num">
.{{ wxs.parsePrice(item.price)[1] }}
</text>
</text>
<view class="btn-box" />
</view>
</view>
</view>
</block>
</view>
<!-- 订单信息 -->
<view class="order-msg">
<view class="msg-item">
<view class="item">
<text class="item-tit">
订单编号
</text>
<text class="item-txt">
{{ orderNumber }}
</text>
</view>
<view class="item">
<text class="item-tit">
下单时间
</text>
<text class="item-txt">
{{ createTime }}
</text>
</view>
</view>
<view class="msg-item">
<view class="item">
<text class="item-tit">
支付方式
</text>
<text class="item-txt">
微信支付
</text>
</view>
<view class="item">
<text class="item-tit">
配送方式
</text>
<text class="item-txt">
普通配送
</text>
</view>
<view class="item">
<text class="item-tit">
订单备注
</text>
<text class="item-txt remarks">
{{ remarks }}
</text>
</view>
</view>
</view>
<view class="order-msg">
<view class="msg-item">
<view class="item">
<view class="item-tit">
订单总额
</view>
<view class="item-txt price">
<text class="symbol">
</text>
<text class="big-num">
{{ wxs.parsePrice(total)[0] }}
</text>
<text class="small-num">
.{{ wxs.parsePrice(total)[1] }}
</text>
</view>
</view>
<view class="item">
<view class="item-tit">
运费
</view>
<view class="item-txt price">
<text class="symbol">
</text>
<text class="big-num">
{{ wxs.parsePrice(transfee)[0] }}
</text>
<text class="small-num">
.{{ wxs.parsePrice(transfee)[1] }}
</text>
</view>
</view>
<view class="item">
<view class="item-tit">
优惠券
</view>
<view class="item-txt price">
<text class="symbol">
-
</text>
<text class="big-num">
{{ wxs.parsePrice(reduceAmount)[0] }}
</text>
<text class="small-num">
.{{ wxs.parsePrice(reduceAmount)[1] }}
</text>
</view>
</view>
<view class="item payment">
<view class="item-txt price">
实付款
<text class="symbol">
</text>
<text class="big-num">
{{ wxs.parsePrice(actualTotal)[0] }}
</text>
<text class="small-num">
.{{ wxs.parsePrice(actualTotal)[1] }}
</text>
</view>
</view>
</view>
</view>
<!-- 底部栏 -->
<view
v-if="status==5||status==6"
class="order-detail-footer"
>
<text
v-if="status==5||status==6"
class="dele-order"
@tap="delOrderList"
>
删除订单
</text>
</view>
</view>
</view>
</template>
<script setup>
const wxs = number()
/**
* 生命周期函数--监听页面加载
*/
onLoad((options) => {
loadOrderDetail(options.orderNum)
})
/**
* 跳转商品详情页
* @param e
*/
const toProdPage = (e) => {
const prodid = e.currentTarget.dataset.prodid
uni.navigateTo({
url: '/pages/prod/prod?prodid=' + prodid
})
}
const remarks = ref('')
const orderItemDtos = ref([])
const reduceAmount = ref('')
const transfee = ref('')
const status = ref(0)
const actualTotal = ref(0)
const userAddrDto = ref(null)
const orderNumber = ref('')
const createTime = ref('')
const total = ref(0) //
/**
* 加载订单数据
*/
const loadOrderDetail = (orderNum) => {
uni.showLoading() //
http.request({
url: '/p/myOrder/orderDetail',
method: 'GET',
data: {
orderNumber: orderNum
}
})
.then(({ data }) => {
orderNumber.value = orderNum
actualTotal.value = data.actualTotal
userAddrDto.value = data.userAddrDto
remarks.value = data.remarks
orderItemDtos.value = data.orderItemDtos
createTime.value = data.createTime
status.value = data.status
transfee.value = data.transfee
reduceAmount.value = data.reduceAmount
total.value = data.total
uni.hideLoading()
})
}
/**
* 删除已完成||已取消的订单
*/
const delOrderList = () => {
uni.showModal({
title: '',
content: '确定要删除此订单吗?',
confirmColor: '#eb2444',
success (res) {
if (res.confirm) {
uni.showLoading()
http.request({
url: '/p/myOrder/' + orderNumber.value,
method: 'DELETE'
})
.then(() => {
uni.hideLoading()
uni.showToast({
title: res || '删除成功',
icon: 'none'
})
setTimeout(() => {
uni.redirectTo({
url: '/pages/orderList/orderList'
})
}, 1000)
})
}
}
})
}
</script>
<style scoped lang="scss">
@use './order-detail.scss';
</style>

@ -0,0 +1,211 @@
.container {
background-color: #f4f4f4;
color: #333;
}
.order-tit {
position: fixed;
top: 0;
display: flex;
justify-content: space-around;
z-index: 999;
width: 100%;
height: 100rpx;
line-height: 100rpx;
background-color: #fff;
border-bottom: 2rpx solid #f4f4f4;
text {
display: block;
font-size: 28rpx;
color: 999;
width: 100rpx;
text-align: center;
}
text.on {
border-bottom: 4rpx solid #eb2444;
color: #eb2444;
}
}
.main {
margin-top: 100rpx;
}
.prod-item {
background-color: #fff;
margin-top: 15rpx;
font-size: 28rpx;
.item-cont {
.prod-pic {
image {
width: 180rpx;
height: 180rpx;
width: 100%;
height: 100%;
}
font-size: 0;
display: inline-block;
width: 160rpx;
height: 160rpx;
overflow: hidden;
background: #fff;
margin-right: 16rpx;
}
.categories {
white-space: nowrap;
}
display: flex;
align-items: center;
padding: 20rpx 30rpx;
border-radius: 10rpx;
display: -webkit-flex;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
background: #fafafa;
.prod-info {
margin-left: 10rpx;
font-size: 28rpx;
width: 100%;
position: relative;
height: 160rpx;
-webkit-flex: 1;
-ms-flex: 1;
-webkit-box-flex: 1;
-moz-box-flex: 1;
flex: 1;
.prodname {
font-size: 28rpx;
line-height: 36rpx;
max-height: 86rpx;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
word-break: break-all;
}
.prod-info-cont {
color: #999;
line-height: 40rpx;
margin-top: 10rpx;
font-size: 22rpx;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
word-break: break-all;
}
}
}
.order-num {
padding: 20rpx 30rpx;
display: flex;
justify-content: space-between;
font-size: 28rpx;
.clear-btn {
width: 32rpx;
height: 32rpx;
font-size: 0;
vertical-align: top;
margin-left: 42rpx;
position: relative;
&::after {
content: " ";
display: block;
position: absolute;
left: -10px;
top: 0rpx;
width: 1px;
height: 32rpx;
background: #ddd;
}
.clear-list-btn {
width: 100%;
height: 100%;
vertical-align: middle;
}
}
}
.total-num {
text-align: right;
padding: 20rpx 30rpx;
font-size: 28rpx;
.prodprice {
display: inline-block;
color: #333;
}
.prodcount {
margin-right: 20rpx;
}
}
.price-nums {
.prodprice {
color: #333;
position: absolute;
bottom: 0;
}
.prodcount {
position: absolute;
bottom: 5rpx;
right: 0;
color: #999;
font-family: verdana;
}
}
.prod-foot {
border-top: 2rpx solid #e6e6e6;
.total {
font-size: 25rpx;
margin-bottom: 20rpx;
padding-bottom: 20rpx;
border-bottom: 2rpx solid #e9eaec;
}
.btn {
display: flex;
align-items: center;
justify-content: flex-end;
}
}
}
.order-state {
display: flex;
align-items: center;
font-size: 24rpx;
.order-sts.red {
color: #eb2444;
}
.order-sts.gray {
color: #999;
}
}
.other-button-hover {
background-color: blue;
}
.button-hover {
background-color: red;
background-color: blue;
}
.button {
margin-top: 20rpx;
margin-bottom: 20rpx;
margin-left: 10px;
font-size: 26rpx;
background: #fff;
padding: 10rpx 30rpx;
border-radius: 80rpx;
border: 2rpx solid #e1e1e1;
&:last-child {
margin-right: 10rpx;
}
}
.button.warn {
color: #eb2444;
border-color: #eb2444;
}
.empty {
font-size: 24rpx;
margin-top: 100rpx;
text-align: center;
color: #999;
height: 300rpx;
line-height: 300rpx;
}

@ -0,0 +1,424 @@
<template>
<view class="container">
<!-- 头部菜单 -->
<view class="order-tit">
<text
data-sts="0"
:class="sts==0?'on':''"
@tap="onStsTap"
>
全部
</text>
<text
data-sts="1"
:class="sts==1?'on':''"
@tap="onStsTap"
>
待支付
</text>
<text
data-sts="2"
:class="sts==2?'on':''"
@tap="onStsTap"
>
待发货
</text>
<text
data-sts="3"
:class="sts==3?'on':''"
@tap="onStsTap"
>
待收货
</text>
<text
data-sts="5"
:class="sts==5?'on':''"
@tap="onStsTap"
>
已完成
</text>
</view>
<!-- end 头部菜单 -->
<view class="main">
<view
v-if="list.length==0"
class="empty"
>
还没有任何相关订单
</view>
<!-- 订单列表 -->
<block
v-for="(item, index) in list"
:key="index"
>
<view class="prod-item">
<view class="order-num">
<text>订单编号{{ item.orderNumber }}</text>
<view class="order-state">
<text
:class="'order-sts ' + (item.status==1?'red':'') + ' ' + ((item.status==5||item.status==6)?'gray':'')"
>
{{
item.status == 1 ? '待支付' : (item.status == 2 ? '待发货' : (item.status == 3 ? '待收货' : (item.status == 5 ? '已完成' : '已取消')))
}}
</text>
<view
v-if="item.status==5 || item.status==6"
class="clear-btn"
>
<image
src="@/static/images/icon/clear-his.png"
class="clear-list-btn"
:data-ordernum="item.orderNumber"
@tap="delOrderList"
/>
</view>
</view>
</view>
<!-- 商品列表 -->
<!-- 一个订单单个商品的显示 -->
<block v-if="item.orderItemDtos.length==1">
<block
v-for="(prod, index2) in item.orderItemDtos"
:key="index2"
>
<view>
<view
class="item-cont"
:data-ordernum="item.orderNumber"
@tap="toOrderDetailPage"
>
<view class="prod-pic">
<image :src="prod.pic" />
</view>
<view class="prod-info">
<view class="prodname">
{{ prod.prodName }}
</view>
<view class="prod-info-cont">
{{ prod.skuName }}
</view>
<view class="price-nums">
<text class="prodprice">
<text class="symbol">
</text>
<text class="big-num">
{{ wxs.parsePrice(prod.price)[0] }}
</text>
<text class="small-num">
.{{ wxs.parsePrice(prod.price)[1] }}
</text>
</text>
<text class="prodcount">
x{{ prod.prodCount }}
</text>
</view>
</view>
</view>
</view>
</block>
</block>
<!-- 一个订单多个商品时的显示 -->
<block v-else>
<view
class="item-cont"
:data-ordernum="item.orderNumber"
@tap="toOrderDetailPage"
>
<scroll-view
scroll-x="true"
scroll-left="0"
scroll-with-animation="false"
class="categories"
>
<block
v-for="(prod, index2) in item.orderItemDtos"
:key="index2"
>
<view class="prod-pic">
<image :src="prod.pic" />
</view>
</block>
</scroll-view>
</view>
</block>
<view class="total-num">
<text class="prodcount">
共1件商品
</text>
<view class="prodprice">
合计
<text class="symbol">
</text>
<text class="big-num">
{{ wxs.parsePrice(item.actualTotal)[0] }}
</text>
<text class="small-num">
.{{ wxs.parsePrice(item.actualTotal)[1] }}
</text>
</view>
</view>
<!-- end 商品列表 -->
<view class="prod-foot">
<view class="btn">
<text
v-if="item.status==1"
class="button"
:data-ordernum="item.orderNumber"
hover-class="none"
@tap="onCancelOrder"
>
取消订单
</text>
<text
v-if="item.status==1"
class="button warn"
:data-ordernum="item.orderNumber"
hover-class="none"
@tap="normalPay"
>
付款
</text>
<text
v-if="item.status==3 || item.status==5"
class="button"
:data-ordernum="item.orderNumber"
hover-class="none"
@tap="toDeliveryPage"
>
查看物流
</text>
<text
v-if="item.status==3"
class="button warn"
:data-ordernum="item.orderNumber"
hover-class="none"
@tap="onConfirmReceive"
>
确认收货
</text>
</view>
</view>
</view>
</block>
</view>
</view>
<!-- end 订单列表 -->
</template>
<script setup>
const wxs = number()
const sts = ref(0)
/**
* 生命周期函数--监听页面加载
*/
onLoad((options) => {
if (options.sts) {
sts.value = options.sts
loadOrderData(options.sts, 1)
} else {
loadOrderData(0, 1)
}
})
const current = ref(1)
const pages = ref(0)
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom(() => {
if (current.value < pages.value) {
loadOrderData(sts.value, current.value + 1)
}
})
const list = ref([])
/**
* 加载订单数据
*/
const loadOrderData = (sts, currentParam) => {
uni.showLoading() //
http.request({
url: '/p/myOrder/myOrder',
method: 'GET',
data: {
current: currentParam,
size: 10,
status: sts
}
})
.then(({ data }) => {
let listParam = []
if (data.current === 1) {
listParam = data.records
} else {
listParam = list.value
Array.prototype.push.apply(listParam, data.records)
}
list.value = listParam
pages.value = data.pages
current.value = data.current
uni.hideLoading()
})
}
/**
* 状态点击事件
*/
const onStsTap = (e) => {
sts.value = e.currentTarget.dataset.sts
loadOrderData(sts.value, 1)
}
/**
* 查看物流
*/
const toDeliveryPage = (e) => {
uni.navigateTo({
url: '/pages/express-delivery/express-delivery?orderNum=' + e.currentTarget.dataset.ordernum
})
}
/**
* 取消订单
*/
const onCancelOrder = (e) => {
const ordernum = e.currentTarget.dataset.ordernum
uni.showModal({
title: '',
content: '要取消此订单?',
confirmColor: '#3e62ad',
cancelColor: '#3e62ad',
cancelText: '否',
confirmText: '是',
success (res) {
if (res.confirm) {
uni.showLoading({
mask: true
})
http.request({
url: '/p/myOrder/cancel/' + ordernum,
method: 'PUT',
data: {}
})
.then(() => {
loadOrderData(sts.value, 1)
uni.hideLoading()
})
}
}
})
}
/**
* 模拟支付直接提交成功
* @param e
*/
const normalPay = (e) => {
uni.showLoading({
mask: true
})
http.request({
url: '/p/order/normalPay',
method: 'POST',
data: {
orderNumbers: e.currentTarget.dataset.ordernum
}
})
.then(({ data }) => {
uni.hideLoading()
if (data) {
uni.showToast({
title: '模拟支付成功',
icon: 'none'
})
setTimeout(() => {
uni.navigateTo({
url: '/pages/pay-result/pay-result?sts=1&orderNumbers=' + e.currentTarget.dataset.ordernum
})
}, 1200)
} else {
uni.showToast({
title: '支付失败!',
icon: 'none'
})
}
})
}
/**
* 查看订单详情
*/
const toOrderDetailPage = (e) => {
uni.navigateTo({
url: '/pages/order-detail/order-detail?orderNum=' + e.currentTarget.dataset.ordernum
})
}
/**
* 确认收货
*/
const onConfirmReceive = (e) => {
uni.showModal({
title: '',
content: '我已收到货?',
confirmColor: '#eb2444',
success (res) {
if (res.confirm) {
uni.showLoading({
mask: true
})
http.request({
url: '/p/myOrder/receipt/' + e.currentTarget.dataset.ordernum,
method: 'PUT'
})
.then(() => {
loadOrderData(sts.value, 1)
uni.hideLoading()
})
}
}
})
}
/**
* 删除已完成||已取消的订单
* @param e
*/
const delOrderList = (e) => {
uni.showModal({
title: '',
content: '确定要删除此订单吗?',
confirmColor: '#eb2444',
success (res) {
if (res.confirm) {
const ordernum = e.currentTarget.dataset.ordernum
uni.showLoading()
http.request({
url: '/p/myOrder/' + ordernum,
method: 'DELETE'
})
.then(() => {
loadOrderData(sts.value, 1)
uni.hideLoading()
})
}
}
})
}
</script>
<style scoped lang="scss">
@use './orderList.scss';
</style>

@ -0,0 +1,50 @@
.pay-sts {
font-size: 40rpx;
margin-top: 100rpx;
padding: 30rpx 0;
text-align: center;
}
.pay-sts.fail {
color: #f43530;
}
.pay-sts.succ {
color: #19be6b;
}
.btns {
margin-top: 50rpx;
text-align: center;
.button {
border-radius: 10rpx;
font-size: 28rpx;
background: #fff;
color: #333;
padding: 20rpx 35rpx;
width: 300rpx;
margin: 0 20rpx;
text-align: center;
}
.button.checkorder {
background: #19be6b;
color: #fff;
margin-bottom: 20rpx;
border: 2rpx solid #19be6b;
}
.button.payagain {
background: #fff;
border: 2rpx solid #f90;
color: #f90;
}
.button.shopcontinue {
background: #fff;
border: 2rpx solid #19be6b;
color: #19be6b;
}
}
.tips {
font-size: 28rpx;
color: #999;
text-align: center;
.warn {
color: #f43530;
}
}

@ -0,0 +1,110 @@
<template>
<view class="container">
<view v-if="sts == 0">
<view class="pay-sts fail">
支付失败
</view>
<view class="tips">
请在
<text class="warn">
30分钟
</text>内完成付款
</view>
<view class="tips">
否则订单会被系统取消
</view>
<view class="btns">
<text
class="button checkorder"
@tap="toOrderList"
>
查看订单
</text>
<text
class="button payagain"
@tap="payAgain"
>
重新支付
</text>
</view>
</view>
<view v-if="sts == 1">
<view class="pay-sts succ">
支付成功
</view>
<view class="tips">
感谢您的购买
</view>
<view class="btns">
<text
class="button checkorder"
@tap="toOrderList"
>
查看订单
</text>
<text
class="button shopcontinue"
@tap="toIndex"
>
继续购物
</text>
</view>
</view>
</view>
</template>
<script setup>
const sts = ref(0)
const orderNumbers = ref('')
/**
* 生命周期函数--监听页面加载
*/
onLoad((options) => {
sts.value = options.sts
orderNumbers.value = options.orderNumbers
})
const toOrderList = () => {
uni.navigateTo({
url: '/pages/orderList/orderList?sts=0'
})
}
const toIndex = () => {
uni.switchTab({
url: '/pages/index/index'
})
}
const payAgain = () => {
uni.showLoading({
mask: true
})
http.request({
url: '/p/order/pay',
method: 'POST',
data: {
payType: 1,
orderNumbers: orderNumbers.value
}
})
.then(({ data }) => {
uni.hideLoading()
uni.requestPayment({
timeStamp: data.timeStamp,
nonceStr: data.nonceStr,
package: data.packageValue,
signType: data.signType,
paySign: data.paySign,
success: () => {
uni.redirectTo({
url: '/pages/pay-result/pay-result?sts=1&orderNum=' + orderNumbers.value
})
}
})
})
}
</script>
<style scoped lang="scss">
@use './pay-result.scss';
</style>

@ -0,0 +1,628 @@
.container {
background: #f4f4f4;
height: 100%;
padding-bottom: 150rpx;
}
swiper {
height: 750rpx;
width: 100%;
border-bottom: 2rpx solid #f8f8f8;
image {
height: 750rpx;
width: 100%;
}
}
.prod-info {
padding: 30rpx 30rpx 0 30rpx;
position: relative;
background: #fff;
}
.tit-wrap {
position: relative;
line-height: 40rpx;
padding-right: 104rpx;
.col {
position: absolute;
top: 0;
right: 0;
width: 80rpx;
color: #666;
font-size: 20rpx;
padding-left: 20rpx;
text-align: center;
image {
display: block;
margin: auto;
width: 40rpx;
height: 40rpx;
}
&::after {
content: "";
display: block;
width: 1px;
height: auto;
background: #f1f1f1;
position: absolute;
top: 0;
bottom: 5px;
left: 0;
}
}
}
.prod-tit {
font-size: 32rpx;
color: #333;
padding-right: 20rpx;
}
.sales-p {
background: #fff;
line-height: 40rpx;
color: #999;
font-size: 24rpx;
margin-top: 6rpx;
margin-right: 104rpx;
}
.prod-price {
font-size: 30rpx;
height: 100rpx;
line-height: 100rpx;
}
.price {
color: #eb2444;
font-size: 24rpx;
font-weight: 600;
margin-right: 30rpx;
}
.price-num {
font-size: 46rpx;
font-weight: 400;
}
.ori-price {
font-size: 25rpx;
color: #999;
text-decoration: line-through;
}
.sales {
color: #999;
}
.more {
position: absolute;
right: 20rpx;
width: 60rpx;
top: 10rpx;
text-align: right;
font-size: 40rpx;
color: #999;
letter-spacing: 1px;
}
.sku {
padding: 20rpx;
background: #fff;
margin-top: 20rpx;
position: relative;
line-height: 48rpx;
}
.sku-tit {
position: absolute;
display: inline-block;
width: 60rpx;
left: 20rpx;
font-size: 22rpx;
top: 20rpx;
color: #999;
}
.sku-con {
margin: 0 80rpx;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
font-size: 28rpx;
font-weight: bold;
}
.cmt-wrap {
background: #fff;
margin-top: 20rpx;
position: relative;
line-height: 48rpx;
}
.cmt-tit {
font-size: 32rpx;
position: relative;
border-bottom: 1px solid #ddd;
padding: 20rpx;
}
.cmt-t {
width: 300rpx;
}
.cmt-good {
color: #eb2444;
font-size: 24rpx;
}
.cmt-count {
position: absolute;
right: 20rpx;
top: 20rpx;
font-size: 24rpx;
color: #666;
}
.cmt-more {
width: 20rpx;
height: 20rpx;
border-top: 2rpx solid #999;
border-right: 2rpx solid #999;
transform: rotate(45deg);
margin-left: 10rpx;
display: inline-block;
}
.cmt-cont {
padding: 0 20rpx;
}
.cmt-tag {
position: relative;
padding: 14px 3px 0 0;
margin: 0;
text {
margin: 0 10px 10px 0;
background: #fdf0f0;
display: inline-block;
padding: 0 10px;
height: 25px;
border-radius: 3px;
line-height: 25px;
font-size: 12px;
font-family: -apple-system, Helvetica, sans-serif;
color: #666;
}
text.selected {
color: #fff;
background: #e93b3d;
}
}
.cmt-item {
position: relative;
padding: 10px 0;
&::after {
content: "";
height: 0;
display: block;
border-bottom: 1px solid #ddd;
position: absolute;
left: 0;
bottom: 0;
right: -10px;
border-bottom-color: #e5e5e5;
}
}
.cmt-items {
.empty {
display: block;
font-size: 24rpx;
text-align: center;
color: #aaa;
margin-top: 5vh;
}
}
.cmt-user {
line-height: 25px;
margin-bottom: 8px;
font-size: 12px;
.user-img {
width: 25px;
height: 25px;
border-radius: 50%;
vertical-align: middle;
}
.nickname {
margin-left: 10px;
display: inline-block;
color: #333;
max-width: 8.2em;
height: 25px;
line-height: 27px;
}
.date {
float: right;
color: #999;
margin-left: -60px;
}
}
.cmt-user-info {
display: flex;
align-items: center;
width: 400rpx;
}
.cmt-cnt {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
position: relative;
line-height: 1.5;
font-size: 14px;
margin: 5px 0;
word-break: break-all;
max-height: 126px;
}
.cmt-attr {
height: 85px;
width: 100%;
white-space: nowrap;
image {
display: inline-block;
width: 80px;
height: 80px;
margin-right: 5px;
margin-bottom: 5px;
border-radius: 2px;
background: #f3f3f3;
}
}
.cmt-more-v {
text-align: center;
background-color: #fff;
font-size: 12px;
text {
height: 25px;
line-height: 25px;
font-size: 12px;
text-align: center;
color: #333;
padding: 0px 10px;
margin: 10px 0;
border: 1px solid #ccc;
border-radius: 40px;
display: inline-block;
}
}
.cmt-popup {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 998;
background-color: #fff;
padding-bottom: 98rpx;
.cmt-cont {
height: calc(100% - 80rpx);
overflow: auto;
}
.cmt-cnt {
-webkit-line-clamp: 20;
max-height: 500px;
}
.load-more {
font-size: 14px;
padding: 20px;
text-align: center;
margin-bottom: 10px;
text {
border: 1px solid #ddd;
padding: 5px 10px;
border-radius: 10px;
color: #666;
}
}
}
.cmt-reply {
font-size: 14px;
border-top: 1px dashed #ddd;
padding: 5px 0;
.reply-tit {
color: #eb2444;
}
}
.prod-detail {
background: #fff;
margin-top: 20rpx;
position: relative;
line-height: 48rpx;
image {
width: 750rpx !important;
display: block;
}
}
rich-text {
image {
width: 100% !important;
}
}
:deep(.img) {
width: 100% !important;
display: block;
}
.cart-footer {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
display: flex;
flex-flow: row nowrap;
height: 98rpx;
z-index: 999;
box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.05);
.btn {
position: relative;
display: flex;
flex-grow: 1;
justify-content: center;
align-items: center;
width: 0;
background-color: #fff;
font-size: 28rpx;
flex-flow: column;
.badge {
position: absolute;
top: 20rpx;
left: 62rpx;
display: inline-block;
width: 28rpx;
height: 28rpx;
border-radius: 14rpx;
background-color: #eb2444;
text-align: center;
line-height: 28rpx;
font-size: 18rpx;
color: #fff;
}
.badge-1 {
width: 36rpx;
}
}
.btn.icon {
flex-grow: 0;
flex-shrink: 0;
width: 125rpx;
font-size: 20rpx;
color: #666;
image {
width: 50rpx;
height: 50rpx;
}
}
.btn.cart {
background: #584e61;
color: #fff;
}
.btn.buy {
background: #eb2444;
color: #fff;
}
}
.close {
color: #aaa;
border-radius: 12px;
line-height: 20px;
text-align: center;
height: 20px;
width: 20px;
font-size: 18px;
padding: 1px;
top: 10px;
right: 10px;
position: absolute;
&::before {
content: "\2716";
}
}
.popup-cnt {
max-height: 429px;
overflow: auto;
padding: 0 10px;
}
.pup-sku {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 999;
background-color: rgba(0, 0, 0, 0.3);
}
.pup-sku-main {
position: absolute;
bottom: 0;
width: 100%;
min-height: 375px;
max-height: 475px;
background-color: #fff;
}
.pup-sku-header {
position: relative;
line-height: 46px;
font-size: 16px;
color: #333;
height: 70px;
padding: 0 0 10px 110px;
background-color: #fff;
}
.pup-sku-img {
position: absolute;
left: 10px;
top: -20px;
border-radius: 2px;
width: 90px;
height: 90px;
border: 0 none;
vertical-align: top;
}
.pup-sku-price {
display: inline-block;
height: 40px;
line-height: 40px;
color: #e4393c;
font-size: 10px;
}
.pup-sku-price-int {
font-size: 16px;
}
.pup-sku-prop {
word-break: break-all;
font-size: 12px;
color: #333;
line-height: 1.4em;
padding-right: 10px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
text {
color: #999;
margin-right: 5px;
}
}
.pup-sku-body {
box-sizing: border-box;
max-height: 379px;
padding-bottom: 100px;
overflow: auto;
}
.pup-sku-area {
.sku-kind {
font-size: 12px;
color: #999;
margin: 0 10px;
height: 40px;
line-height: 40px;
}
.sku-choose {
overflow: hidden;
margin-bottom: 3px;
}
}
.sku-choose-item {
display: inline-block;
padding: 0 10px;
min-width: 20px;
max-width: 270px;
overflow: hidden;
height: 30px;
line-height: 30px;
text-align: center;
margin-left: 10px;
margin-bottom: 10px;
border-radius: 4px;
color: #333;
background-color: #f7f7f7;
font-size: 14px;
}
.sku-choose-item.active {
background-color: #eb2444;
color: #fff;
}
.sku-choose-item.gray {
background-color: #f9f9f9;
color: #ddd;
}
.pup-sku-count {
padding: 0 10px 13px;
font-size: 12px;
.count-name {
color: #999;
height: 31px;
line-height: 31px;
width: 100rpx;
}
.num-wrap {
position: relative;
z-index: 0;
width: 110px;
float: right;
vertical-align: middle;
display: flex;
}
.text-wrap {
position: relative;
width: 45px;
z-index: 0;
margin: 0 1px;
input {
height: 30px;
width: 100%;
color: #333;
background: #fff;
font-size: 12px;
text-align: center;
border: none;
background: #f7f7f7;
}
}
}
.num-wrap {
.minus {
position: relative;
max-width: 30px;
min-width: 30px;
height: 30px;
line-height: 30px;
background: #f7f7f7;
text-align: center;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}
.plus {
position: relative;
max-width: 30px;
min-width: 30px;
height: 30px;
line-height: 30px;
background: #f7f7f7;
text-align: center;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
.row {
border-radius: 20px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -7px;
margin-top: -1px;
width: 14px;
height: 2px;
background-color: #ccc;
}
.col {
border-radius: 20px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -1px;
margin-top: -7px;
width: 2px;
height: 14px;
background-color: #999;
}
}
.pup-sku-footer {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
display: flex;
flex-direction: row nowrap;
height: 98rpx;
z-index: 999;
box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.05);
.btn {
position: relative;
display: flex;
flex-grow: 1;
justify-content: center;
align-items: center;
width: 0;
background-color: #fff;
font-size: 28rpx;
flex-flow: column;
}
.btn.cart {
background: #584e61;
color: #fff;
}
.btn.buy {
background: #eb2444;
color: #fff;
}
}

@ -0,0 +1,875 @@
<template>
<!-- 商品详情 -->
<view class="container">
<!-- 轮播图 -->
<swiper
:indicator-dots="indicatorDots"
:autoplay="autoplay"
:indicator-color="indicatorColor"
:interval="interval"
:duration="duration"
:indicator-active-color="indicatorActiveColor"
>
<block
v-for="(item, index) in imgs"
:key="index"
>
<swiper-item>
<image :src="item" />
</swiper-item>
</block>
</swiper>
<!-- end 轮播图 -->
<!-- 商品信息 -->
<view class="prod-info">
<view class="tit-wrap">
<view class="prod-tit">
{{ prodName }}
</view>
<view
class="col"
@tap="addOrCannelCollection"
>
<image
v-if="!isCollection"
src="@/static/images/icon/prod-col.png"
/>
<image
v-if="isCollection"
src="@/static/images/icon/prod-col-red.png"
/>
收藏
</view>
</view>
<view class="sales-p">
{{ brief }}
</view>
<view class="prod-price">
<text
v-if="defaultSku && defaultSku.price"
class="price"
>
<text class="price-num">
{{ wxs.parsePrice(defaultSku.price)[0] }}
</text>
.{{ wxs.parsePrice(defaultSku.price)[1] }}
</text>
<text
v-if="defaultSku && defaultSku.oriPrice"
class="ori-price"
>
{{ wxs.parsePrice(defaultSku.oriPrice)[0] }}.{{ wxs.parsePrice(defaultSku.oriPrice)[1] }}
</text>
<text class="sales" />
</view>
</view>
<!-- 已选规格 -->
<view
class="sku"
@tap="showSku"
>
<view class="sku-tit">
已选
</view>
<view class="sku-con">
{{ selectedProp.length > 0 ? selectedProp + '' : '' }}{{ prodNum }}
</view>
<view class="more">
...
</view>
</view>
<!-- 评价 -->
<view class="cmt-wrap">
<view
class="cmt-tit"
@tap="showComment"
>
<view class="cmt-t">
评价
<text class="cmt-good">
好评{{ prodCommData.positiveRating }}%
</text>
</view>
<view class="cmt-count">
{{ prodCommData.number }}
<text class="cmt-more" />
</view>
</view>
<view class="cmt-cont">
<view
class="cmt-tag"
@tap="showComment"
>
<text>全部({{ prodCommData.number }})</text>
<text>好评({{ prodCommData.praiseNumber }})</text>
<text>中评({{ prodCommData.secondaryNumber }})</text>
<text>差评({{ prodCommData.negativeNumber }})</text>
<text>有图({{ prodCommData.picNumber }})</text>
</view>
<view class="cmt-items">
<view
v-for="(item, index) in littleCommPage"
:key="index"
class="cmt-item"
>
<view class="cmt-user">
<text class="date">
{{ item.recTime }}
</text>
<view class="cmt-user-info">
<image
class="user-img"
:src="item.pic"
/>
<view class="nickname">
{{ item.nickName }}
</view>
</view>
</view>
<view class="cmt-cnt">
{{ item.content }}
</view>
<scroll-view
v-if="item.pics.length"
class="cmt-attr"
scroll-x="true"
>
<image
v-for="(commPic, index2) in item.pics"
:key="index2"
:src="commPic"
/>
</scroll-view>
</view>
</view>
<view
v-if="prodCommPage.records.length > 2"
class="cmt-more-v"
>
<text @tap="showComment">
查看全部评价
</text>
</view>
</view>
</view>
<!-- 商品详情 -->
<view class="prod-detail">
<view>
<rich-text :nodes="content" />
</view>
</view>
<!-- end 商品详情 -->
<!-- 底部按钮 -->
<view class="cart-footer">
<view
class="btn icon"
@tap="toHomePage"
>
<image src="@/static/images/tabbar/homepage.png" />
首页
</view>
<view
class="btn icon"
@tap="toCartPage"
>
<image src="@/static/images/tabbar/basket.png" />
购物车
<view
v-if="totalCartNum>0"
class="badge badge-1"
>
{{ totalCartNum }}
</view>
</view>
<view
class="btn cart"
@tap="showSku"
>
<text>加入购物车</text>
</view>
<view
class="btn buy"
@tap="showSku"
>
<text>立即购买</text>
</view>
</view>
<!-- end 底部按钮 -->
<!-- 规格弹窗 -->
<view
v-if="skuShow"
class="pup-sku"
>
<view class="pup-sku-main">
<view class="pup-sku-header">
<image
class="pup-sku-img"
:src="defaultSku.pic?defaultSku.pic:pic"
/>
<view class="pup-sku-price">
<text
v-if="defaultSku && defaultSku.price"
class="pup-sku-price-int"
>
{{ wxs.parsePrice(defaultSku.price)[0] }}
</text>
.{{ wxs.parsePrice(defaultSku.price)[1] }}
</view>
<view class="pup-sku-prop">
<text>已选</text>
{{ selectedProp.length > 0 ? selectedProp + '' : '' }}{{ prodNum }}
</view>
<view
class="close"
@tap="closePopup"
/>
</view>
<view class="pup-sku-body">
<view class="pup-sku-area">
<view
v-if="skuList.length"
class="sku-box"
>
<block
v-for="(skuGroupItem, skuGroupItemIndex) in skuGroupList"
:key="skuGroupItemIndex"
>
<view
v-for="(skuLine, key) in skuGroupItem"
:key="key"
class="items sku-text"
>
<text class="sku-kind">
{{ key }}
</text>
<view class="con">
<text
v-for="skuLineItem in skuLine"
:key="skuLineItem"
class="sku-choose-item"
:class="[selectedPropList.indexOf(key + ':' + skuLineItem) !== -1?'active':'',
isSkuLineItemNotOptional(allProperties,selectedPropObj,key,skuLineItem,propKeys)? 'dashed' : '']"
@click="toChooseItem(skuGroupItemIndex, skuLineItem, key)"
>
{{ skuLineItem }}
</text>
</view>
</view>
</block>
</view>
</view>
<view class="pup-sku-count">
<view class="num-wrap">
<view
class="minus"
@tap="onCountMinus"
>
<text class="row" />
</view>
<view class="text-wrap">
<input
type="number"
:value="prodNum"
disabled
>
</view>
<view
class="plus"
@tap="onCountPlus"
>
<text class="row" />
<text class="col" />
</view>
</view>
<view class="count-name">
数量
</view>
</view>
</view>
<view class="pup-sku-footer">
<view
class="btn cart"
@tap="addToCart"
>
加入购物车
</view>
<view
class="btn buy"
@tap="buyNow"
>
立即购买
</view>
</view>
</view>
</view>
<!-- 评价弹窗 -->
<view
v-if="commentShow"
class="cmt-popup"
>
<view class="cmt-tit">
<view class="cmt-t">
商品评价
<text class="cmt-good">
好评度{{ prodCommData.positiveRating }}%
</text>
</view>
<text
class="close"
@tap="closePopup"
/>
</view>
<view class="cmt-cont">
<view class="cmt-tag">
<text
data-evaluate="-1"
:class="evaluate==-1?'selected':''"
@tap="getProdCommPage"
>
全部({{ prodCommData.number }})
</text>
<text
data-evaluate="0"
:class="evaluate==0?'selected':''"
@tap="getProdCommPage"
>
好评({{ prodCommData.praiseNumber }})
</text>
<text
data-evaluate="1"
:class="evaluate==1?'selected':''"
@tap="getProdCommPage"
>
中评({{ prodCommData.secondaryNumber }})
</text>
<text
data-evaluate="2"
:class="evaluate==2?'selected':''"
@tap="getProdCommPage"
>
差评({{ prodCommData.negativeNumber }})
</text>
<text
data-evaluate="3"
:class="evaluate==3?'selected':''"
@tap="getProdCommPage"
>
有图({{ prodCommData.picNumber }})
</text>
</view>
<view class="cmt-items">
<block v-if="prodCommPage.records.length">
<view
v-for="(item, index) in prodCommPage.records"
:key="index"
class="cmt-item"
>
<view class="cmt-user">
<text class="date">
{{ item.recTime }}
</text>
<view class="cmt-user-info">
<image
class="user-img"
:src="item.pic"
/>
<view class="nickname">
{{ item.nickName }}
</view>
</view>
</view>
<view class="cmt-cnt">
{{ item.content }}
</view>
<scroll-view
v-if="item.pics.length"
class="cmt-attr"
scroll-x="true"
>
<image
v-for="(commPic, index2) in item.pics"
:key="index2"
:src="commPic"
/>
</scroll-view>
<view
v-if="item.replyContent"
class="cmt-reply"
>
<text class="reply-tit">
店铺回复
</text>
{{ item.replyContent }}
</view>
</view>
</block>
<view
v-if="!prodCommPage.records.length"
class="empty"
>
暂无评价
</view>
</view>
<view
v-if="prodCommPage.pages > prodCommPage.current"
class="load-more"
>
<text @tap="getMoreCommPage">
点击加载更多
</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
const wxs = number()
const indicatorDots = ref(true)
const indicatorColor = ref('#f2f2f2')
const indicatorActiveColor = ref('#eb2444')
const autoplay = ref(true)
const interval = ref(3000)
const duration = ref(1000)
const selectedProp = ref([])
let prodId = 0
/**
* 生命周期函数--监听页面加载
*/
onLoad((options) => {
prodId = options.prodid//
getProdInfo() //
getProdCommData() //
getLittleProdComm() //
getCollection()
})
const app = getApp()
const totalCartNum = ref(0)
/**
* 生命周期函数--监听页面显示
*/
onShow(() => {
totalCartNum.value = app.globalData.totalCartCount
})
/**
* 分享设置
*/
onShareAppMessage(() => {
return {
title: prodName.value,
path: '/pages/prod/prod?prodid=' + prodId
}
})
const isCollection = ref(false)
/**
* 获取是否关注信息
*/
const getCollection = () => {
uni.showLoading()
http.request({
url: '/p/user/collection/isCollection',
method: 'GET',
data: {
prodId
}
})
.then(({ data }) => {
isCollection.value = data
uni.hideLoading()
})
}
/**
* 添加或者取消收藏商品
*/
const addOrCannelCollection = () => {
uni.showLoading()
http.request({
url: '/p/user/collection/addOrCancel',
method: 'POST',
data: prodId
})
.then(() => {
isCollection.value = !isCollection.value
uni.hideLoading()
})
}
const skuList = ref([])
const brief = ref('')
const prodNum = ref(1)
const pic = ref('')
const imgs = ref('')
const prodName = ref('')
const price = ref(0)
const content = ref('')
/**
* 获取商品信息
*/
const getProdInfo = () => {
uni.showLoading()
http.request({
url: '/prod/prodInfo',
method: 'GET',
data: {
prodId // userType: 0
}
})
.then(({ data }) => {
uni.hideLoading()
if (!data) {
setTimeout(() => {
uni.navigateBack()
}, 1000)
return
}
imgs.value = data.imgs?.split(',')
content.value = util.formatHtml(data.content)
price.value = data.price
prodName.value = data.prodName
prodId = data.prodId
brief.value = data.brief
skuList.value = data.skuList
pic.value = data.pic
// sku
groupSkuProp(data.skuList, data.price)
uni.hideLoading()
})
}
const prodCommData = ref({})
const getProdCommData = () => {
http.request({
url: '/prodComm/prodCommData',
method: 'GET',
data: {
prodId
}
})
.then(({ data }) => {
prodCommData.value = data
})
}
const prodCommPage = ref({
current: 0,
pages: 0,
records: []
})
/**
* 获取部分评论
*/
const getLittleProdComm = () => {
if (prodCommPage.value.records.length) {
return
}
getProdCommPage()
}
const getMoreCommPage = () => {
getProdCommPage()
}
const littleCommPage = ref([])
const evaluate = ref(-1)
/**
* 获取分页获取评论
*/
const getProdCommPage = (e) => {
if (e) {
if (e.currentTarget.dataset.evaluate === evaluate.value) {
return
}
prodCommPage.value = {
current: 0,
pages: 0,
records: []
}
evaluate.value = e.currentTarget.dataset.evaluate
}
http.request({
url: '/prodComm/prodCommPageByProd',
method: 'GET',
data: {
prodId,
size: 10,
current: prodCommPage.value.current + 1,
evaluate: evaluate.value
}
})
.then(({ data }) => {
data.records.forEach(item => {
if (item.pics) {
item.pics = item.pics.split(',')
}
})
let records = prodCommPage.value.records
records = records.concat(data.records)
//
prodCommPage.value = {
current: data.current,
pages: data.pages,
records
}
if (!littleCommPage.value.length) {
littleCommPage.value = records.slice(0, 2)
}
})
}
let selectedPropObjList = null
const skuGroup = ref({})
const defaultSku = ref(null)
const selectedPropObj = ref({})
const propKeys = ref([])
const allProperties = ref([])
const findSku = ref(true)
const skuGroupList = ref([])
/**
* 组装SKU
*/
const groupSkuProp = (skuList, defaultPrice) => {
if (skuList.length === 1 && !skuList[0].properties) {
defaultSku.value = skuList[0]
findSku.value = true
return
}
const skuGroupList = []
const skuGroupParam = {}
const allProperties = []
const propKeys = []
const selectedPropObj = {}
const selectedPropObjListParam = []
let defaultSkuParam = null
for (let i = 0; i < skuList.length; i++) {
let isDefault = false
if (!defaultSkuParam && skuList[i].price == defaultPrice) {
defaultSkuParam = skuList[i]
isDefault = true
}
const properties = skuList[i].properties // :;:;:64GB
allProperties.push(properties)
const propList = properties.split(';') // [":",":",":64GB"]
for (let j = 0; j < propList.length; j++) {
const propval = propList[j].split(':') // ["",""]
let props = skuGroupParam[propval[0]] //
// sku selectedProp
if (isDefault) {
propKeys.push(propval[0])
selectedPropObj[propval[0]] = propval[1]
const selectedPropObjItem = {}
selectedPropObjItem[propval[0]] = propval[1]
selectedPropObjListParam.push(selectedPropObjItem)
}
if (!props) {
props = [] //
props.push(propval[1]) // ""
} else {
if (props.indexOf(propval[1]) === -1) { // ""
props.push(propval[1]) // ""
}
}
skuGroupParam[propval[0]] = props //
const propListItem = {}
propListItem[propval[0]] = props
skuGroupList.push(propListItem)
}
}
defaultSku.value = defaultSkuParam
propKeys.value = propKeys
selectedPropObj.value = selectedPropObj
skuGroup.value = skuGroupParam
selectedPropObjList = selectedPropObjListParam
skuGroupList.value = unique(skuGroupList)
allProperties.value = allProperties
parseSelectedObjToVals(skuList)
}
const selectedPropList = ref(null)
/**
* 将已选的 {key:val,key2:val2}转换成 [val,val2]
*/
const parseSelectedObjToVals = (skuList) => {
const selectedPropObjListParam = selectedPropObjList
let selectedPropertiesParam = ''
const selectedPropListParam = []
const selectedPropShowListParam = []
for (let i = 0; i < selectedPropObjListParam.length; i++) {
const selectedPropObjItem = selectedPropObjListParam[i]
for (const key in selectedPropObjItem) {
if (Object.hasOwnProperty.call(selectedPropObjItem, key)) {
selectedPropListParam.push(key + ':' + selectedPropObjItem[key])
selectedPropShowListParam.push(selectedPropObjItem[key])
selectedPropertiesParam += key + ':' + selectedPropObjItem[key] + ';'
}
}
}
selectedPropertiesParam = selectedPropertiesParam.substring(0, selectedPropertiesParam.length - 1)
selectedPropList.value = selectedPropListParam
selectedPropObjList = selectedPropObjListParam
let findSkuParam = false
for (let i = 0; i < skuList.length; i++) {
if (skuList[i].properties == selectedPropertiesParam) {
findSkuParam = true
defaultSku.value = skuList[i]
break
}
}
findSku.value = findSkuParam
}
/**
* 判断当前的规格值 是否可以选
*/
const isSkuLineItemNotOptional = (allProperties, selectedPropObjParam, key, item, propKeys) => {
const selectedPropObj = Object.assign({}, selectedPropObjParam)
let properties = ''
selectedPropObj[key] = item
for (let j = 0; j < propKeys.length; j++) {
properties += propKeys[j] + ':' + selectedPropObj[propKeys[j]] + ';'
}
properties = properties.substring(0, properties.length - 1)
for (let i = 0; i < allProperties.length; i++) {
if (properties == allProperties[i]) {
return false
}
}
for (let i = 0; i < allProperties.length; i++) {
if (allProperties[i].indexOf(item) >= 0) {
return true
}
}
return false
}
/**
* 规格点击事件
*/
const toChooseItem = (skuGroupItemIndex, skuLineItem, key) => {
selectedPropObjList[skuGroupItemIndex][key] = skuLineItem
selectedPropObj.value[key] = skuLineItem
parseSelectedObjToVals(skuList.value)
}
/**
* 去重
*/
const unique = (arr) => {
const map = {}
arr.forEach(item => {
const obj = {}
Object.keys(item).sort().map(key => (obj[key] = item[key]))
map[JSON.stringify(obj)] = item
})
return Object.keys(map).map(key => JSON.parse(key))
}
/**
* 跳转到首页
*/
const toHomePage = () => {
uni.switchTab({
url: '/pages/index/index'
})
}
/**
* 跳转到购物车
*/
const toCartPage = () => {
uni.switchTab({
url: '/pages/basket/basket'
})
}
const shopId = 1
/**
* 加入购物车
*/
const addToCart = () => {
uni.showLoading({
mask: true
})
http.request({
url: '/p/shopCart/changeItem',
method: 'POST',
data: {
basketId: 0,
count: prodNum.value,
prodId,
shopId,
skuId: defaultSku.value.skuId
}
})
.then(() => {
totalCartNum.value = totalCartNum.value + prodNum.value
uni.hideLoading()
uni.showToast({
title: '加入购物车成功',
icon: 'none'
})
})
}
/**
* 立即购买
*/
const buyNow = () => {
uni.setStorageSync('orderItem', JSON.stringify({
prodId,
skuId: defaultSku.value.skuId,
prodCount: prodNum.value,
shopId
}))
uni.navigateTo({
url: '/pages/submit-order/submit-order?orderEntry=1'
})
}
/**
* 减数量
*/
const onCountMinus = () => {
if (prodNum.value > 1) {
prodNum.value = prodNum.value - 1
}
}
/**
* 加数量
*/
const onCountPlus = () => {
if (prodNum.value < 1000) {
prodNum.value = prodNum.value + 1
}
}
const skuShow = ref(false)
const showSku = () => {
skuShow.value = true
}
const commentShow = ref(false)
const showComment = () => {
commentShow.value = true
}
const closePopup = () => {
skuShow.value = false
commentShow.value = false
}
</script>
<style scoped lang="scss">
@use './prod.scss';
</style>
Loading…
Cancel
Save