Files
Smart-Farm/uniapp/uni-app/shop/pages/order.vue
2025-12-22 17:13:05 +08:00

629 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="shop-order" v-if="isLoad">
<view class="fill-base mt-md ml-md mr-md f-paragraph box-shadow radius-24">
<view class="pd-lg f-sm-title c-title text-bold b-1px-b">收货地址</view>
<view @tap.stop="toChooseAddr" class="pl-lg pr-md pt-lg pb-lg flex-center" v-if="orderInfo.address.id">
<view class="flex-1">
<view class="flex-warp">
<i class="iconfont icon-dingwei mr-sm" style="font-size: 28rpx;margin-top: 6rpx;"></i>
<view class="f-paragraph c-title flex-1 max-520">
{{`${orderInfo.address.address}${orderInfo.address.address_info}`}}
</view>
</view>
<view class="flex-y-baseline f-paragraph c-caption" style="margin:5rpx 0 0 38rpx;">
{{orderInfo.address.user_name }}
<view class="ml-lg">
{{orderInfo.address.mobile}}
</view>
</view>
</view>
<i class="iconfont icon-right"></i>
</view>
<block v-else>
<view class="space-lg"></view>
<view class="space-lg"></view>
<view @tap.stop="toChooseAddr" class="add-btn flex-center f-paragraph c-desc"><i
class="iconfont icon-add-circle-fill mr-sm"></i>添加地址
</view>
<view class="space-lg"></view>
<view class="space-lg"></view>
</block>
</view>
<view class="fill-base mt-md ml-md mr-md f-paragraph box-shadow radius-24">
<view class="flex-between ml-md mr-md pl-sm pt-lg pb-lg b-1px-b">
<view class="item-text c-black">配送时间</view>
<view @tap.stop="$util.goUrl({url:`/mine/pages/choose-time`})" class="flex-y-center">
<view class="flex-1 text-right"
:class="[{'c-placeholder':!send_info.time.id},{'c-title':send_info.time.id}]">
{{send_info.time.id ? `${send_info.time.date} ${send_info.time.time_text}` : '请选择时间'}}
</view>
<i class="iconfont icon-right"></i>
</view>
</view>
<view class="flex-between pl-sm pr-lg pt-lg pb-lg">
<view class="flex-y-center">
<i class="iconfont icon-required c-base"></i>
<view class="item-text">订单备注</view>
</view>
<input v-model="subForm.text" type="text" class="flex-1 f-paragraph text-right" maxlength="100"
placeholder-class="c-placeholder" placeholder="请输入订单备注" />
</view>
</view>
<view class="goods-list fill-base mt-md ml-md mr-md pl-sm pr-sm f-paragraph box-shadow radius-24"
v-for="(item,index) in orderInfo.order_goods" :key="index">
<view class="flex-y-center ml-md mr-md pt-lg pb-lg b-1px-b">
<i class="iconfont icon-dianpu mr-sm"></i>
<view class="f-title c-title text-bold ellipsis">{{item.farmer_info.title}}</view>
<i class="iconfont icon-right"></i>
</view>
<view class="item-child flex-warp ml-lg mr-lg pb-lg" :class="[{'pt-lg':aindex==0}]"
v-for="(aitem,aindex) in item.goods_list" :key="aindex">
<view class="rel">
<image @tap.stop="goDetail(index)" mode="aspectFill" lazy-load class="goods-img radius-16"
:src="aitem.cover"></image>
<view class="sell-out-info flex-center abs radius-16" v-if="aitem.all_stock < 1">
<image mode="aspectFill" lazy-load class="sell-out-img"
:src="`/static/image/shop/sell_out.png`"></image>
</view>
</view>
<view class="flex-1 ml-md">
<view class="f-title c-title text-bold max-476 ellipsis">{{aitem.goods_name}}</view>
<view class="f-caption c-caption max-476 ellipsis"> {{aitem.spe_name}} </view>
<view class="f-desc c-warning" v-if="aitem.integral_id">
{{aitem.i_price*1>0?`${aitem.integral}积分+${aitem.i_price}`:`${aitem.integral}积分`}}
</view>
<block v-if="aitem.kill_atv_id">
<view class="f-desc c-warning"> 每件到手件 ¥{{aitem.kill_price}} </view>
<view class="seckill-info flex-y-center f-icontext c-warning">
<min-countdown :type="3" :targetTime="aitem.kill_end_time * 1000" color="#FF5537"
textColor="#FF583C" borderColor="#FF583C" className="mini" @callback="countEnd">
</min-countdown>
秒杀即将结束优惠不等人
</view>
</block>
<view class="flex-y-baseline mt-sm">
<view class="flex-y-baseline flex-1 f-title c-warning">
<view class="f-caption c-caption mr-sm" v-if="aitem.integral_id || aitem.kill_atv_id">商城价
</view>
¥<view class="text-bold"> {{aitem.price}} </view>
</view>
<view class="f-caption c-caption">x {{aitem.goods_num}} </view>
</view>
</view>
</view>
<view class="ml-md mr-md pt-lg pb-lg f-paragraph c-title b-1px-t">
<view class="flex-between">
<view>商品金额</view>
<view>¥{{item.init_goods_price}}</view>
</view>
<view class="flex-between mt-sm">
<view>配送费</view>
<view>¥{{item.freight}}</view>
</view>
<view class="flex-between mt-sm" v-if="orderInfo.kill_discount_price*1>0">
<view>秒杀优惠</view>
<view class="c-warning">-¥{{orderInfo.kill_discount_price}}</view>
</view>
<block v-if="orderInfo.order_goods.length === 1">
<!-- buy_limit 0不支持原价购买1支持原价购买 -->
<block v-if="orderInfo.integral">
<view @tap.stop="toChangeItem('no_i', no_i == 0 ? 1 : 0,)" class="flex-between mt-sm">
<view class="flex-y-center" style="height: 40rpx"> <i class="iconfont c-caption mr-sm"
:class="[{ 'icon-xuanze': no_i }, { 'icon-xuanze-fill': !no_i }]"
:style="{ color: !no_i ? primaryColor : '' }"></i>使用积分
</view>
<view class="c-warning">{{ orderInfo.integral }}</view>
</view>
<view class="flex-between mt-sm" v-if="!no_i && item.integral_discount_price*1>0">
<view>积分抵扣</view>
<view class="c-warning">-¥{{item.integral_discount_price}}</view>
</view>
</block>
<block>
<block v-if="(orderInfo.buy_limit == 0 || !no_i)&& orderInfo.discount_add == 0">
</block>
<view class="flex-between mt-md" v-else>
<view class="item-text">卡券优惠</view>
<view
@tap.stop="$util.goUrl({url:`/mine/pages/coupon/use?type=3&is_show=${options.is_show}&no_i=${no_i}`})"
class="flex-y-center">
<view class="flex-1 text-right">
{{ orderInfo.coupon_id ? `${orderInfo.coupon_discount}` : `${orderInfo.canUseCoupon}张可用` }}
</view>
<i class="iconfont icon-right"></i>
</view>
</view>
</block>
</block>
<block v-else>
<view class="flex-between mt-sm" v-if="!no_i && item.integral_discount_price*1>0">
<view>积分抵扣</view>
<view class="c-warning">-¥{{item.integral_discount_price}}</view>
</view>
<view class="flex-between mt-sm" v-if="item.coupon_discount*1>0">
<view>卡券优惠</view>
<view class="c-warning">-¥{{item.coupon_discount}}</view>
</view>
</block>
<view class="flex-between mt-sm">
<view>小计</view>
<view class="f-title text-bold c-warning">¥{{ item.pay_price }} </view>
</view>
</view>
</view>
<view class="fill-base mt-md ml-md mr-md f-paragraph box-shadow radius-24"
v-if="orderInfo.order_goods.lengh > 1">
<view class="flex-between ml-md mr-md pt-lg">
<view class="item-text c-black">商品金额</view>
<view>¥{{ orderInfo.init_goods_price }} </view>
</view>
<view class="flex-between ml-md mr-md pt-md">
<view class="item-text c-black">配送费</view>
<view>¥{{ orderInfo.freight }} </view>
</view>
<!-- buy_limit 0不支持原价购买1支持原价购买 -->
<block v-if="orderInfo.integral">
<view @tap.stop="toChangeItem('no_i', no_i == 0 ? 1 : 0,)"
class="flex-between ml-md mr-md c-title pt-md">
<view class="flex-y-center pl-sm c-black" style="height: 40rpx"> <i class="iconfont c-caption mr-sm"
:class="[{ 'icon-xuanze': no_i }, { 'icon-xuanze-fill': !no_i }]"
:style="{ color: !no_i ? primaryColor : '' }"></i>使用积分
</view>
<view class="c-warning">{{ orderInfo.integral }}</view>
</view>
<view class="flex-between ml-md mr-md pl-sm pt-md" v-if="!no_i">
<view class="item-text c-black">积分抵扣</view>
<view class="c-warning">-¥{{ orderInfo.integral_discount_price }} </view>
</view>
</block>
<block>
<block v-if="(orderInfo.buy_limit == 0 || !no_i)&& orderInfo.discount_add == 0">
</block>
<view class="flex-between ml-md mr-md pl-sm pt-md" v-else>
<view class="item-text c-black">卡券优惠</view>
<view
@tap.stop="$util.goUrl({url:`/mine/pages/coupon/use?type=3&is_show=${options.is_show}&no_i=${no_i}`})"
class="flex-y-center">
<view class="flex-1 text-right">
{{ orderInfo.coupon_id ? `${orderInfo.coupon_discount}` : `${orderInfo.canUseCoupon}张可用` }}
</view>
<i class="iconfont icon-right"></i>
</view>
</view>
</block>
<view class="flex-between mt-lg ml-md mr-md pt-lg pb-lg b-1px-t">
<view class="item-text c-black">合计</view>
<view class="f-title text-bold c-warning">¥{{ orderInfo.pay_price }} </view>
</view>
</view>
<view class="fill-base mt-md ml-md mr-md f-sm-title box-shadow radius-24">
<view @tap.stop="toChangeItem('payInd',index)"
class="flex-between ml-md mr-md pl-sm pr-sm pt-lg pb-lg b-1px-b" v-for="(item,index) in payList"
:key="index">
<view class="pay-item flex-y-center"><i class="iconfont mr-md" :class="[item.icon]"
:style="{color:item.id==1?primaryColor:item.id==2?subColor:'#01AAF2'}"></i>
<view class="flex-y-baseline">{{item.title}}
<view class="f-paragraph c-caption ml-sm" v-if="item.id==2">余额{{userInfo.balance || 0}}
</view>
</view>
</view>
<i class="pay-icon iconfont c-caption"
:class="[{'icon-xuanze':payInd != index},{'icon-radio-fill':item.is_disabled || payInd == index}]"
:style="{color:payInd==index?primaryColor:''}"></i>
</view>
</view>
<view class="space-max-footer"></view>
<view class="footer-btn fill-base fix">
<view class="footer-item flex-between pl-lg pr-lg">
<view class="flex-y-baseline f-paragraph c-title">
合计<view class="f-sm-title c-warning text-bold">¥{{orderInfo.pay_price}}</view>
</view>
<auth :needAuth="userInfo && !userInfo.nickName" :must="true" type="userInfo" @go="toOrder" class="order-btn" style="width:332rpx">
<view class="order-btn flex-center f-sm-title c-base text-bold radius-20"
:style="{background:primaryColor}">立即支付
</view>
</auth>
</view>
<view class="space-safe"></view>
</view>
</view>
</template>
<script>
import {
mapState,
mapActions,
mapMutations
} from "vuex"
export default {
components: {},
data() {
return {
isLoad: false,
options: {},
scrollTop: 0,
// 1微信支付2余额支付3支付宝支付
payList: [{
id: 1,
title: '微信支付',
icon: 'icon-wechat-pay',
is_disabled: false
}
// #ifdef APP-PLUS
, {
id: 3,
title: '支付宝支付',
icon: 'icon-alipay',
is_disabled: false
}
// #endif
, {
id: 2,
title: '余额支付',
icon: 'icon-qianbao',
is_disabled: false
}
],
payInd: 0,
// #ifdef APP-PLUS
balanceInd: 2,
// #endif
// #ifndef APP-PLUS
balanceInd: 1,
// #endif
sendList: [{
id: 1,
title: '自提',
}, {
id: 2,
title: '快递',
}],
sendInd: 1,
send_info: {
time_index: '',
time: {
date: '',
start_time: '',
end_time: ''
}
},
no_i: 0,
orderInfo: {
address: {
id: 0
}
},
subForm: {
text: ''
},
}
},
computed: mapState({
primaryColor: state => state.config.configInfo.primaryColor,
subColor: state => state.config.configInfo.subColor,
configInfo: state => state.config.configInfo,
userInfo: state => state.user.userInfo,
}),
onLoad(options) {
let {
is_show = 1,
no_i = 1
} = options
options.is_show = is_show
this.options = options
this.no_i = no_i * 1
this.initIndex()
},
onUnload() {
if (this.options.is_show == 2) return
this.$util.back()
},
onPageScroll(e) {
this.scrollTop = e.scrollTop
},
methods: {
...mapActions(['getUserInfo', 'getAuthPhone']),
...mapMutations(['updateOrderItem']),
async initIndex(refresh = false) {
if (!refresh) {
await this.getUserInfo()
}
let {
balance,
phone
} = this.userInfo
let {
address = {}, coupon_id = 0, buy_limit = 1, discount_add = 1
} = this.orderInfo
let {
id: address_id = 0
} = address
let {
is_show,
} = this.options
let {
no_i
} = this
if ((!buy_limit || !no_i) && !discount_add) {
coupon_id = 0
}
let orderInfo = await this.$api.shop.payOrderInfo({
address_id,
coupon_id,
is_show,
no_i
})
let {
pay_price,
buy_limit: buy = 1
} = orderInfo
let is_disabled = balance * 1 < pay_price * 1
let {
balanceInd
} = this
this.payList[balanceInd].is_disabled = is_disabled
if (pay_price * 1 == 0) {
this.payList[0].is_disabled = true
// #ifdef APP-PLUS
this.payList[1].is_disabled = true
// #endif
this.payInd = balanceInd
}
this.no_i = !buy ? 0 : no_i
this.orderInfo = orderInfo
this.isLoad = true
},
initRefresh() {
this.initIndex(true)
},
toChangeItem(key, index) {
if (key == 'payInd' && index == 2 && this.payList[index].is_disabled) return
if (key == 'no_i' && this.orderInfo.buy_limit == 0) return
this[key] = index
if (key == 'no_i') {
this.initRefresh()
}
},
toChooseAddr() {
this.$util.goUrl({
url: `/mine/pages/address/list?check=1`
})
},
toOrder() {
let {
payList,
payInd,
sendList,
sendInd,
subForm,
no_i
} = this
let {
is_show
} = this.options
let {
id: pay_model
} = payList[payInd]
let {
id: send_type
} = sendList[sendInd]
let {
address = {}, coupon_id = 0
} = this.orderInfo
let {
id: address_id = 0
} = address
if (!address_id && send_type == 2) {
this.$util.showToast({
title: `请选择收货地址`
})
return
}
let {
date = '',
start_time = '',
end_time = ''
} = this.send_info.time
if (!date) {
this.$util.showToast({
title: `请选择配送时间`
})
return
}
start_time = this.$util.DateToUnix(`${date} ${start_time}`)
end_time = this.$util.DateToUnix(`${date} ${end_time}`)
let param = Object.assign({}, subForm, {
address_id,
coupon_id,
send_type,
start_time,
end_time,
pay_model,
is_show,
no_i
});
this.toPay(param)
},
async toPay(param) {
// #ifdef MP-WEIXIN
let that = this
let {
tmp_list = []
} = that.orderInfo
let tmplIds = []
tmp_list.map(item => {
tmplIds.push(item.tmpl_id)
})
if (tmplIds && tmplIds.length > 0) {
uni.requestSubscribeMessage({
tmplIds,
complete(res) {
that.toConfirmPay(param)
console.log(res, "complete requestSubscribeMessage");
}
})
} else {
that.toConfirmPay(param)
}
// #endif
// #ifndef MP-WEIXIN
this.toConfirmPay(param)
// #endif
},
async toConfirmPay(param) {
if (this.lockTap) return
this.lockTap = true
this.$util.showLoading()
try {
let {
pay_list
} = await this.$api.shop.payOrder(param)
this.$util.hideAll()
if (pay_list) {
if (param.pay_model == 3) {
pay_list = {
orderInfo: pay_list,
provider: 'alipay'
}
}
try {
await this.$util.pay(pay_list)
this.$util.showToast({
title: `支付成功`
})
this.updateOrderItem({
key: 'haveOperItem',
val: true
})
setTimeout(() => {
this.$util.back()
this.$util.goUrl({
url: '/mine/pages/pay-result?type=shop',
openType: 'redirectTo'
})
}, 1000)
this.lockTap = false
return
} catch (e) {
this.$util.showToast({
title: `支付失败`
})
setTimeout(() => {
this.$util.back()
this.$util.goUrl({
url: `/shop/pages/order/list`,
openType: 'redirectTo'
})
}, 1000)
this.lockTap = false
return
}
}
this.$util.showToast({
title: `支付成功`
})
this.updateOrderItem({
key: 'haveOperItem',
val: true
})
setTimeout(() => {
this.$util.back()
this.$util.goUrl({
url: '/mine/pages/pay-result?type=shop',
openType: 'redirectTo'
})
}, 1000)
} catch (e) {
setTimeout(() => {
this.lockTap = false
this.$util.hideAll()
}, 2000)
}
}
}
}
</script>
<style lang="scss">
.shop-order {
.add-btn {
width: 296rpx;
height: 72rpx;
background: #F6F6F6;
border-radius: 36rpx;
margin: 0 auto;
}
.pay-item {
.iconfont {
font-size: 50rpx;
}
}
.pay-icon {
font-size: 40rpx;
}
.icon-right {
font-size: 28rpx;
}
.item-text {
width: 150rpx;
}
.goods-list {
.item-child {
.goods-img {
width: 130rpx;
height: 130rpx;
border: 1px solid rgba(238, 238, 238, 0.79);
transform: rotateZ(360deg);
}
.sell-out-info {
top: 1rpx;
left: 1rpx;
width: 130rpx;
height: 130rpx;
background: rgba(0, 0, 0, 0.5);
.sell-out-img {
width: 84rpx;
height: 23rpx;
margin: 0 auto;
}
}
.seckill-info {
width: 100%;
height: 44rpx;
margin-top: 5rpx;
background: linear-gradient(to right, rgba(255, 85, 55, 0.5), rgba(255, 255, 255, 0.5));
}
}
}
.footer-btn {
bottom: 0;
.footer-item {
height: 114rpx;
.order-btn {
width: 332rpx;
height: 88rpx;
}
}
}
}
</style>