Files
2025-12-22 17:13:05 +08:00

710 lines
19 KiB
Vue
Raw Permalink 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="claim-order" v-if="orderInfo.claim_info.id">
<uni-nav-bar :fixed="true" :shadow="false" :statusBar="true" color="#fff"
:backgroundColor="scrollTop < 20 ?``:primaryColor" leftIcon="icon-left" title="确认订单">
</uni-nav-bar>
<view :style="{height:`${configInfo.navBarHeight}px`}"></view>
<image mode="aspectFill" lazy-load class="common-bg abs" src="https://lbqny.migugu.com/admin/farm/bg-cash.png">
</image>
<view class="space-lg"></view>
<view class="fill-base mt-md ml-md mr-md pd-lg box-shadow radius-24">
<view class="f-title c-title pb-lg b-1px-b">{{orderInfo.farmer_info.title}}</view>
<view class="flex-warp pt-lg pb-lg">
<image mode="aspectFill" lazy-load class="avatar lg radius-10" :src="orderInfo.claim_info.cover">
</image>
<view class="flex-1 ml-lg">
<view class="f-paragraph max-520 ellipsis">{{orderInfo.claim_info.title}}</view>
<block v-if="options.type">
<view class="flex-y-center f-desc c-warning mt-sm">众筹价<view
class="flex-y-baseline f-caption ml-sm">
¥<view class="f-sm-title text-bold">
{{orderInfo.claim_info[orderType[options.type]].price}}
</view>
</view>
<view class="f-icontext c-caption text-delete ml-sm">原价 ¥{{orderInfo.claim_info.price}}
</view>
</view>
<view class="flex-center mt-md">
<view class="collage-tag flex-center f-caption c-base" :style="{background:primaryColor}">
{{orderInfo.claim_info[orderType[options.type]].success_num}}人团
</view>
<view class="flex-1"></view>
</view>
</block>
<view class="flex-y-baseline f-paragraph c-warning mt-sm" v-else>¥{{orderInfo.claim_info.price}}
<view class="f-caption c-caption ml-sm">
/{{orderInfo.claim_info.unit}}</view>
</view>
</view>
</view>
<view class="flex-between pt-lg pb-lg b-1px-tb">
<view class="f-paragraph c-black">认养数量</view>
<view v-if="options.type">{{subForm.num}}</view>
<view class="add-remove-item flex-center" v-else>
<i @tap.stop="changeNum(-1,index)" class="iconfont icon-remove-square c-caption"></i>
<view class="number flex-center f-desc pl-sm pr-sm">{{subForm.num}}</view>
<i @tap.stop="changeNum(1,index)" class="iconfont icon-add-square"
:style="{color:primaryColor}"></i>
</view>
</view>
<view class="pt-lg pb-lg f-paragraph c-black">认养收获</view>
<view class="flex-center">
<image mode="aspectFill" lazy-load class="avatar sm radius-10"
:src="orderInfo.claim_info.harvest_cover"></image>
<view class="flex-1 ml-lg ellipsis">{{orderInfo.claim_info.harvest_text}}</view>
</view>
</view>
<view class="fill-base mt-md ml-md mr-md f-paragraph box-shadow radius-24">
<view class="flex-between pd-lg">
<view class="flex-y-center f-sm-title c-black"><i class="iconfont icon-peisong mr-sm"
:style="{color:primaryColor}"></i>配送周期</view>
<view class="f-paragraph">{{orderInfo.claim_info.send_cycle}}</view>
</view>
</view>
<view class="fill-base mt-md ml-md mr-md f-paragraph box-shadow radius-24">
<view class="flex-between pd-lg f-sm-title c-title b-1px-b">
<view class="text-bold">配送方式</view>
<view class="send-list flex-center radius" :style="{width:sendList.length==1?'90rpx':''}">
<view @tap.stop="toChangeItem('sendInd',index)" class="send-item flex-center f-paragraph radius"
:class="[{'c-base':sendInd == index}]" :style="{background:sendInd==index?primaryColor:''}"
v-for="(item,index) in sendList" :key="index">{{item.title}}</view>
</view>
</view>
<view @tap.stop="toChooseAddr" class="pd-lg flex-center"
v-if="sendList[sendInd].id == 1 || 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" :class="[{'max-520':sendList[sendInd].id == 2}]">
{{sendList[sendInd].id == 1 ? `${orderInfo.farmer_info.address}` : orderInfo.address.id ? `${orderInfo.address.address} ${orderInfo.address.address_info}`:''}}
</view>
</view>
<view class="flex-y-baseline f-paragraph c-caption" style="margin:5rpx 0 0 38rpx;">
{{sendList[sendInd].id == 1 ? orderInfo.farmer_info.user_name : orderInfo.address.id ? orderInfo.address.user_name:'' }}
<view class="ml-lg">
{{sendList[sendInd].id == 1? orderInfo.farmer_info.mobile : orderInfo.address.id ? orderInfo.address.mobile : ''}}
</view>
</view>
</view>
<i class="iconfont"
:class="[{'icon-dingwei':sendList[sendInd].id == 1},{'icon-right':sendList[sendInd].id == 2}]"></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" v-if="sendList[sendInd].id == 1">
<view class="flex-between ml-md mr-md pl-sm pt-lg pb-lg b-1px-b">
<view class="flex-y-center">
<i class="iconfont icon-required c-warning"></i>
<view class="item-text">姓名</view>
</view>
<input v-model="subForm.user_name" type="text" class="flex-1 f-paragraph"
placeholder-class="c-placeholder" :placeholder="rule[0].errorMsg" />
</view>
<view class="flex-between ml-md mr-md pl-sm pt-lg pb-lg">
<view class="flex-y-center">
<i class="iconfont icon-required c-warning"></i>
<view class="item-text">手机号</view>
</view>
<input v-model="subForm.mobile" type="text" class="flex-1 f-paragraph" placeholder-class="c-placeholder"
:placeholder="rule[1].errorMsg" />
<button open-type="getPhoneNumber" @getphonenumber="toAuthPhone"
class="clear-btn auth-phone-btn flex-center" :style="{color:primaryColor}">立即授权</button>
</view>
</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="flex-y-center">
<i class="iconfont icon-required c-warning"></i>
<view class="item-text">认养取名</view>
</view>
<input v-model="subForm.claim_name" type="text" class="flex-1 f-paragraph"
placeholder-class="c-placeholder" :placeholder="rule[2].errorMsg" />
</view>
<view class="flex-between ml-md mr-md pl-sm 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" maxlength="100"
placeholder-class="c-placeholder" placeholder="请输入订单备注" />
</view>
</view>
<view class="fill-base mt-md ml-md mr-md f-paragraph box-shadow radius-24" v-if="!options.type">
<view class="flex-between ml-md mr-md pl-sm pt-lg pb-lg">
<view class="item-text">卡券优惠</view>
<view
@tap.stop="$util.goUrl({url:`/mine/pages/coupon/use?claim_id=${options.id}&num=${subForm.num}&type=2`})"
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>
</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 @tap.stop="toAgree" class="flex-warp f-paragraph mt-md pd-md"><i
class="agree-icon iconfont c-caption mr-sm"
:class="[{'icon-xuanze': !agree},{'icon-xuanze-fill': agree}]" style="margin-top: 3rpx;"
:style="{color:agree?primaryColor:''}"></i>
<view class="flex-y-center">购买代表您已同意<view @tap.stop="$util.goUrl({url:`/mine/pages/agreement?type=1`})"
:style="{color:primaryColor}">
{{agreement}}</view>
</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>
<!-- #ifdef APP-PLUS -->
<view @tap="toOrder" class="order-btn flex-center f-sm-title c-base text-bold radius-20"
:style="{background:primaryColor}">立即支付
</view>
<!-- #endif -->
<!-- #ifndef APP-PLUS -->
<auth :needAuth="userInfo && !userInfo.nickName" :must="true" type="userInfo" @go="toOrder">
<view class="order-btn flex-center f-sm-title c-base text-bold radius-20"
:style="{background:primaryColor}">立即支付
</view>
</auth>
<!-- #endif -->
</view>
<view class="space-safe"></view>
</view>
</view>
</template>
<script>
import {
mapState,
mapActions,
mapMutations
} from "vuex"
export default {
components: {},
data() {
return {
options: {},
scrollTop: 0,
orderType: {
1: 'collage_start_data',
2: 'collage_join_data'
},
// 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: [],
sendInd: 0,
agreement: '',
agree: false,
orderInfo: {
address: {},
farmer_info: {},
claim_info: {},
},
subForm: {
num: 1,
send_type: 1,
address_id: '',
user_name: '',
mobile: '',
claim_name: '',
text: ''
},
rule: [{
name: "user_name",
checkType: "isNotNull",
errorMsg: "请输入姓名",
regType: 2
}, {
name: "mobile",
checkType: "isMobile",
errorMsg: "请输入手机号"
}, {
name: "claim_name",
checkType: "isNotNull",
errorMsg: "快给你认养的小动物取个名吧"
}],
}
},
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 {
type = 0
} = options
options.type = type * 1
this.options = options
this.initIndex()
},
onPageScroll(e) {
this.scrollTop = e.scrollTop
},
methods: {
...mapActions(['getUserInfo', 'getAuthPhone']),
...mapMutations(['updateOrderItem']),
async initIndex(refresh = false) {
if (!refresh) {
let [, info] = await Promise.all([this.getUserInfo(), this.$api.home.aboutUsInfoType({
type: 1
})])
this.agreement = info.title
}
let {
id: claim_id,
type: order_type,
cid: collage_id
} = this.options
let {
phone
} = this.userInfo
let {
mobile = '',
num = 1
} = this.subForm
this.subForm.mobile = mobile || phone
let {
address = {}, coupon_id = 0
} = this.orderInfo
let {
id: address_id = 0
} = address
let param = {
claim_id,
coupon_id,
address_id,
num
}
// order_type 1发起众筹2参与众筹
if (order_type == 1) {
param.collage_start_id = collage_id
}
if (order_type == 2) {
param.collage_join_id = collage_id
}
let orderInfo = await this.$api.claim.claimPayOrderInfo(param)
if (!refresh) {
let {
is_self,
is_send
} = orderInfo.claim_info
let sendList = []
if (is_self) {
sendList.push({
id: 1,
title: '自提',
})
}
if (is_send) {
sendList.push({
id: 2,
title: '快递',
})
}
this.sendList = sendList
}
let {
balance
} = this.userInfo
let {
pay_price
} = 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.orderInfo = orderInfo
},
initRefresh() {
this.initIndex(true)
},
async changeNum(mod, index) {
let {
num: goods_num
} = this.subForm
let {
unit
} = this.orderInfo.claim_info
let num = goods_num + mod;
if (num < 1) {
this.$util.showToast({
title: `此动物最少购买1${unit}`
})
return;
}
this.subForm.num = num
this.initRefresh()
},
toChangeItem(key, index) {
if (key == 'payInd' && index === 2 && this.payList[index].is_disabled) return
this[key] = index
},
async toMap() {
let {
lat,
lng,
address
} = this.orderInfo.farmer_info
await this.$util.checkAuth({
type: 'userLocation'
})
await uni.getLocation({
type: 'gcj02',
})
await uni.openLocation({
latitude: lat * 1,
longitude: lng * 1,
name: address,
scale: 28
})
},
toChooseAddr() {
if (this.sendList[this.sendInd].id == 1) {
this.toMap()
return
}
this.$util.goUrl({
url: `/mine/pages/address/list?check=1`
})
},
// 授权手机号
async toAuthPhone(e) {
let phone = await this.getAuthPhone({
e,
})
if (!phone) return
this.$nextTick(() => {
this.subForm.mobile = phone
})
},
toAgree() {
this.agree = !this.agree
},
//表单验证
validate(param) {
let validate = new this.$util.Validate();
let arr = param.send_type == 1 ? ['user_name', 'mobile', 'claim_name'] : [
'claim_name'
]
this.rule.map(item => {
let {
name
} = item
if (!arr.includes(name)) return
validate.add(param[name], item);
})
let message = validate.start();
return message;
},
toOrder() {
let {
payList,
payInd,
sendList,
sendInd,
subForm,
agreement
} = this
let {
id: claim_id,
cid: collage_id,
type: order_type
} = 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 param = Object.assign({}, subForm, {
claim_id,
address_id,
coupon_id,
pay_model,
send_type
});
// order_type 1发起众筹2参与众筹
if (order_type == 1) {
param.collage_start_id = collage_id
}
if (order_type == 2) {
param.collage_join_id = collage_id
}
let msg = this.validate(param);
if (msg) {
this.$util.showToast({
title: msg
});
return;
}
if (!this.agree) {
this.$util.showToast({
title: `请勾选${agreement}`
})
return
}
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.claim.claimPayOrder(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=claim',
openType: 'redirectTo'
})
}, 1000)
this.lockTap = false
return
} catch (e) {
this.$util.showToast({
title: `支付失败`
})
setTimeout(() => {
this.$util.back()
this.$util.goUrl({
url: `/claim/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=claim',
openType: 'redirectTo'
})
}, 1000)
} catch (e) {
setTimeout(() => {
this.lockTap = false
this.$util.hideAll()
}, 2000)
}
}
}
}
</script>
<style lang="scss">
.claim-order {
.collage-tag {
height: 36rpx;
padding: 0 10rpx;
}
.send-list {
width: 180rpx;
height: 52rpx;
border: 1rpx solid #CCCCCC;
transform: rotateZ(360deg);
overflow: hidden;
.send-item {
width: 90rpx;
height: 50rpx;
}
}
.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;
}
.icon-peisong,
.agree-icon {
font-size: 36rpx;
}
.item-text {
width: 150rpx;
}
.auth-phone-btn {
width: 106rpx;
height: 36rpx;
line-height: 36rpx;
margin-left: 15rpx;
font-size: 20rpx;
background: #F0F4EC;
border-radius: 10rpx;
}
.footer-btn {
bottom: 0;
.footer-item {
height: 114rpx;
.order-btn {
width: 332rpx;
height: 88rpx;
}
}
}
}
</style>