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

<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>