You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
597 lines
14 KiB
597 lines
14 KiB
<template>
|
|
<view>
|
|
<u-navbar
|
|
back-text="返回"
|
|
is-back
|
|
title="下单"
|
|
back-icon-color="#fff"
|
|
:back-text-style="{
|
|
color: '#fff',
|
|
}"
|
|
title-color="#fff"
|
|
:background="{
|
|
backgroundImage:
|
|
'linear-gradient(0deg, #c10d12 0%, #c10d12 4%, #e26165 99%, #e26165 100%)',
|
|
}"
|
|
>
|
|
</u-navbar>
|
|
|
|
<view class="wrap">
|
|
<view>
|
|
<view v-if="!detail.id" class="site" @tap="showPop = true">
|
|
<view v-if="site.id" style="padding-right: 80rpx">
|
|
<view class="top">
|
|
<view class="tag" v-if="site.is_default"> 默认 </view>
|
|
<view class="city">{{ site.city }}</view>
|
|
|
|
<view class="name">{{ site.name }} {{ site.mobile }}</view>
|
|
</view>
|
|
<view class="center">
|
|
<view class="address">{{ site.address }}</view>
|
|
</view>
|
|
<view class="bottom">
|
|
<text>{{ site.name }} {{ site.mobile }}</text>
|
|
</view>
|
|
</view>
|
|
<view class="no-site" v-else> 请选择收货地址 </view>
|
|
<view class="site-select">
|
|
<u-icon
|
|
name="arrow-right"
|
|
label="选择"
|
|
label-pos="left"
|
|
label-color="#666"
|
|
></u-icon>
|
|
</view>
|
|
</view>
|
|
<view v-if="detail.id && detail.user_address" class="site">
|
|
<view>
|
|
<view class="top">
|
|
<view class="tag" v-if="detail.user_address && detail.user_address.is_default"> 默认 </view>
|
|
<view class="city">{{ detail.user_address.city }}</view>
|
|
|
|
<view class="name">{{ detail.user_address.name }} {{ detail.user_address.mobile }}</view>
|
|
</view>
|
|
<view class="center">
|
|
<view class="address">{{ detail.user_address.address }}</view>
|
|
</view>
|
|
<view class="bottom">
|
|
<text>{{ detail.user_address.name }} {{ detail.user_address.mobile }}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="carts">
|
|
<view class="cart" v-for="item in carts" :key="item.id">
|
|
<view class="top">
|
|
<u-image
|
|
class="cart__img"
|
|
width="154rpx"
|
|
height="154rpx"
|
|
lazy-load
|
|
:src="
|
|
item.product && item.product.image
|
|
? item.product.image.url
|
|
: vuex_default_icon
|
|
"
|
|
></u-image>
|
|
<view class="cart__info">
|
|
<view class="cart__info--name">{{
|
|
item.product ? item.product.name : ""
|
|
}}</view>
|
|
<view class="cart__info--type">
|
|
<text>
|
|
数量×{{ item.num }}
|
|
</text>
|
|
<text>
|
|
{{ item.product_sku ? item.product_sku.name : "" }}
|
|
</text>
|
|
</view>
|
|
<view class="cart__info--price">
|
|
<text>¥</text>
|
|
<text>{{
|
|
item.total_price || (item.product_sku ? item.product_sku.price : "")
|
|
}}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="price">
|
|
<view class="price-row" v-if="detail.express_name">
|
|
<view class="price-row__name">
|
|
快递名称
|
|
</view>
|
|
<view class="price-row__value">
|
|
<text>{{ detail.express_name }}</text>
|
|
</view>
|
|
</view>
|
|
<view class="price-row" v-if="detail.express_number">
|
|
<view class="price-row__name">
|
|
快递单号
|
|
</view>
|
|
<view class="price-row__value">
|
|
<text>{{ detail.express_number }}</text>
|
|
</view>
|
|
</view>
|
|
<view class="price-row" v-if="detail.created_at">
|
|
<view class="price-row__name">
|
|
下单日期
|
|
</view>
|
|
<view class="price-row__value">
|
|
<text>{{ detail.created_at }}</text>
|
|
</view>
|
|
</view>
|
|
<view class="price-row" v-if="detail.no">
|
|
<view class="price-row__name">
|
|
订单号
|
|
</view>
|
|
<view class="price-row__value">
|
|
<text>{{ detail.no }}</text>
|
|
</view>
|
|
</view>
|
|
<view class="price-row">
|
|
<view class="price-row__name">
|
|
合计
|
|
</view>
|
|
<view class="price-row__value">
|
|
¥ {{ detail.id ? detail.price : totalPrice }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="bottom">
|
|
<view>
|
|
<u-button
|
|
v-if="!detail.id"
|
|
shape="circle"
|
|
ripple
|
|
:custom-style="btnStyle"
|
|
@click="submit"
|
|
>保 存</u-button
|
|
>
|
|
<u-button
|
|
v-else-if="detail.id && detail.pay_status === 0"
|
|
shape="circle"
|
|
ripple
|
|
:custom-style="btnStyle"
|
|
@click="payOrder(detail)"
|
|
>立即支付</u-button
|
|
>
|
|
<u-button
|
|
v-else-if="detail.id && detail.pay_status === 1"
|
|
shape="circle"
|
|
ripple
|
|
:custom-style="btnStyle"
|
|
@click="refund"
|
|
>申请退款</u-button
|
|
>
|
|
<u-button
|
|
v-else-if="detail.id && detail.pay_status === 4"
|
|
shape="circle"
|
|
ripple
|
|
:custom-style="btnStyle"
|
|
>退款成功</u-button
|
|
>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 地址选择 -->
|
|
<u-popup
|
|
v-model="showPop"
|
|
mode="bottom"
|
|
border-radius="14"
|
|
safe-area-inset-bottom
|
|
>
|
|
<view class="content">
|
|
<scroll-view scroll-y="true" style="height: 750rpx;padding-bottom:40rpx">
|
|
<view
|
|
class="site"
|
|
v-for="item in sites"
|
|
:style="{
|
|
border: '1rpx solid',
|
|
'border-color': site.id === item.id ? '#a7352f' : '#666',
|
|
}"
|
|
:key="item.id"
|
|
@tap="(site = item), (showPop = false)"
|
|
>
|
|
<view class="top">
|
|
<view class="tag" v-if="item.is_default"> 默认 </view>
|
|
<view class="city">{{ item.city }}</view>
|
|
</view>
|
|
<view class="center">
|
|
<view
|
|
class="address"
|
|
:style="{
|
|
color: site.id === item.id ? '#a7352f' : '#333',
|
|
}"
|
|
>{{ item.address }}</view
|
|
>
|
|
</view>
|
|
</view>
|
|
</scroll-view>
|
|
<u-button
|
|
v-if="!detail.id"
|
|
shape="circle"
|
|
ripple
|
|
:custom-style="btnStyle"
|
|
@click="goAddress"
|
|
>新建收货地址</u-button
|
|
>
|
|
</view>
|
|
</u-popup>
|
|
|
|
<tabbar class="tabbar"></tabbar>
|
|
<u-toast ref="uToast" />
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import BigNumber from "@/libs/bignumber";
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
btnStyle: {
|
|
"background-image":
|
|
"linear-gradient(-90deg, #e26165 0%, #c10d12 94%, #c10d12 100%)",
|
|
"font-weight": "500",
|
|
"font-size": "28rpx",
|
|
color: "#fff",
|
|
width: "450rpx",
|
|
"margin": "0 auto"
|
|
},
|
|
showPop: false,
|
|
site: {},
|
|
sites: [],
|
|
carts: [],
|
|
detail: {}
|
|
};
|
|
},
|
|
methods: {
|
|
async getCarts() {
|
|
try {
|
|
const res = await this.$u.api.cartList({
|
|
page: 1,
|
|
page_size: 999,
|
|
"show_relation[0]": "product.image",
|
|
"show_relation[1]": "productSku",
|
|
});
|
|
this.carts = res.data;
|
|
} catch (err) {
|
|
console.error(err);
|
|
}
|
|
},
|
|
async getSites() {
|
|
try {
|
|
const res = await this.$u.api.userAddress({
|
|
page: 1,
|
|
page_size: 999,
|
|
});
|
|
this.site = res?.data?.find((i) => i.is_default);
|
|
this.sites = res.data;
|
|
} catch (err) {
|
|
console.error(err);
|
|
}
|
|
},
|
|
async submit() {
|
|
if(!this.site){
|
|
this.$refs.uToast.show({
|
|
title: "请选择收货地址",
|
|
type: "warning",
|
|
});
|
|
return
|
|
}
|
|
if (!this.site.id) {
|
|
this.$refs.uToast.show({
|
|
title: "请选择收货地址",
|
|
type: "warning",
|
|
});
|
|
return
|
|
}
|
|
try {
|
|
const { model } = await this.$u.api.productOrder({
|
|
user_address_id: this.site.id
|
|
});
|
|
if (model) {
|
|
uni.showModal({
|
|
title: "下单成功",
|
|
content: "下单成功,是否立即支付?",
|
|
success: (status) => {
|
|
if (status.confirm) {
|
|
this.payOrder(model);
|
|
} else {
|
|
this.$u.route({
|
|
url: '/package_sub/pages/Shop/Order',
|
|
type: 'reLaunch'
|
|
})
|
|
}
|
|
},
|
|
fail: () => {
|
|
|
|
},
|
|
});
|
|
}
|
|
} catch (err) {
|
|
|
|
}
|
|
},
|
|
async payOrder(re) {
|
|
try {
|
|
const { config } = await this.$u.api.productPay({
|
|
no: re.no,
|
|
});
|
|
|
|
const [err, res] = await uni.requestPayment({
|
|
provider: "wxpay",
|
|
timeStamp: config.timestamp,
|
|
nonceStr: config.nonceStr,
|
|
package: config.package,
|
|
signType: config.signType,
|
|
paySign: config.paySign,
|
|
});
|
|
if (err) {
|
|
uni.showToast({
|
|
title: "支付失败",
|
|
icon: "none",
|
|
});
|
|
}
|
|
if (res) {
|
|
uni.showToast({
|
|
title: "支付成功",
|
|
icon: "none",
|
|
});
|
|
this.$u.route({
|
|
url: '/package_sub/pages/Shop/Order',
|
|
type: 'reLaunch'
|
|
})
|
|
}
|
|
} catch (err) {
|
|
uni.showToast({
|
|
title: "支付失败",
|
|
icon: "none",
|
|
});
|
|
}
|
|
},
|
|
async getDetail(id) {
|
|
try {
|
|
const res = await this.$u.api.userOrdersDetail({ id })
|
|
this.detail = res
|
|
this.carts = res.order_detail
|
|
} catch (err) {
|
|
console.error(err)
|
|
}
|
|
},
|
|
goAddress(){
|
|
uni.navigateTo({
|
|
url:'/package_sub/pages/UserAddress/AddUserAddress?type=car'
|
|
})
|
|
},
|
|
async refund() {
|
|
try {
|
|
uni.showModal({
|
|
title: "提示",
|
|
content: "确认申请退款?",
|
|
success: async (status) => {
|
|
if (status.confirm) {
|
|
await this.$u.api.productOrderRefund({
|
|
id: this.detail.id
|
|
})
|
|
await this.getDetail(this.detail.id)
|
|
} else {
|
|
|
|
}
|
|
},
|
|
fail: () => {
|
|
|
|
},
|
|
});
|
|
} catch (err) {
|
|
console.error(err)
|
|
}
|
|
}
|
|
},
|
|
computed: {
|
|
totalPrice() {
|
|
return this.carts?.reduce((pre, cur) => pre.plus(new BigNumber(isNaN(Number(cur.product_sku?.price??0)) ? 0 : Number(cur.product_sku?.price??0)).times(cur.num??0)), new BigNumber(0))
|
|
// return this.pickCart?.reduce((pre, cur) => pre + (isNaN(Number(cur.product_sku?.price??0)) ? 0 : Number(cur.product_sku?.price??0)), 0)
|
|
}
|
|
},
|
|
created() {
|
|
// this.getSites();
|
|
},
|
|
onShow() {
|
|
this.getSites()
|
|
},
|
|
onLoad(option) {
|
|
if (option.order_id) {
|
|
this.getDetail(option.order_id)
|
|
} else {
|
|
this.getCarts();
|
|
}
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.site {
|
|
padding: 20rpx 30rpx;
|
|
background: #fff;
|
|
border-radius: 10px;
|
|
margin: 30rpx 22rpx 0;
|
|
position: relative;
|
|
|
|
.no-site {
|
|
font-size: 36rpx;
|
|
color: #333333;
|
|
}
|
|
.top {
|
|
display: flex;
|
|
align-items: center;
|
|
font-weight: bold;
|
|
.city {
|
|
font-size: 22rpx;
|
|
color: #666666;
|
|
margin-left: 10rpx;
|
|
}
|
|
.name {
|
|
font-size: 22rpx;
|
|
color: #999;
|
|
margin-left: 10rpx;
|
|
}
|
|
.tag {
|
|
display: flex;
|
|
font-weight: normal;
|
|
align-items: center;
|
|
border-radius: 5px;
|
|
background-color: #b62828;
|
|
color: #ffffff;
|
|
font-size: 18rpx;
|
|
text-align: center;
|
|
padding: 4rpx 8rpx;
|
|
}
|
|
}
|
|
.center {
|
|
margin-top: 14rpx;
|
|
|
|
.address {
|
|
font-size: 32rpx;
|
|
color: #333333;
|
|
}
|
|
}
|
|
.bottom {
|
|
display: flex;
|
|
margin-top: 24rpx;
|
|
font-size: 20rpx;
|
|
justify-content: space-between;
|
|
color: #666;
|
|
}
|
|
.site-select {
|
|
position: absolute;
|
|
right: 20rpx;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
}
|
|
}
|
|
.site + .site {
|
|
margin-top: 40rpx;
|
|
}
|
|
|
|
.carts {
|
|
margin-top: 20rpx;
|
|
|
|
.cart {
|
|
background: #fff;
|
|
border-radius: 10rpx;
|
|
padding: 26rpx 22rpx 16rpx;
|
|
margin: 0 26rpx 22rpx;
|
|
.top {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
}
|
|
.bottom {
|
|
margin-top: 14rpx;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
&__checkbox {
|
|
align-self: center;
|
|
}
|
|
&__img {
|
|
border-radius: 6rpx;
|
|
}
|
|
&__info {
|
|
flex: 1;
|
|
margin-left: 28rpx;
|
|
&--name {
|
|
font-size: 24rpx;
|
|
color: #333333;
|
|
}
|
|
&--type {
|
|
margin-top: 14rpx;
|
|
font-size: 22rpx;
|
|
display: inline-block;
|
|
& > text:nth-child(1) {
|
|
color: #333;
|
|
}
|
|
& > text:nth-child(2) {
|
|
color: #666;
|
|
padding-left: 12rpx;
|
|
}
|
|
}
|
|
&--price {
|
|
margin-top: 14rpx;
|
|
color: red;
|
|
font-size: 21rpx;
|
|
|
|
& > text:nth-child(2) {
|
|
font-size: 24rpx;
|
|
padding-left: 4rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.price {
|
|
background: #fff;
|
|
margin: 0 22rpx;
|
|
border-radius: 10rpx;
|
|
padding: 40rpx 30rpx;
|
|
|
|
&-row {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
position: relative;
|
|
|
|
&::before {
|
|
content: '';
|
|
background: #ccc;
|
|
height: 2rpx;
|
|
position: absolute;
|
|
top: -19rpx;
|
|
left: 10rpx;
|
|
right: 10rpx;
|
|
}
|
|
&:nth-child(1):before {
|
|
opacity: 0;
|
|
}
|
|
&__name {
|
|
font-size: 24rpx;
|
|
color: #000000;
|
|
font-weight: bold;
|
|
}
|
|
&__value {
|
|
font-size: 24rpx;
|
|
color: red;
|
|
font-weight: 500;
|
|
text-align: right;
|
|
|
|
text {
|
|
color: #666;
|
|
}
|
|
}
|
|
}
|
|
.price-row + .price-row {
|
|
margin-top: 40rpx;
|
|
}
|
|
}
|
|
.bottom {
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
background: #fff;
|
|
padding: 34rpx 150rpx 0;
|
|
padding-bottom: 20rpx;
|
|
padding-bottom: calc(
|
|
constant(safe-area-inset-bottom) + 20rpx
|
|
);
|
|
padding-bottom: calc(
|
|
env(safe-area-inset-bottom) + 20rpx
|
|
);
|
|
}
|
|
</style>
|