campus-errand/miniapp/pages/delivery/delivery.vue
2026-03-17 15:42:18 +08:00

305 lines
7.4 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="order-page">
<!-- 自定义导航栏 -->
<view class="custom-navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="navbar-content">
<view class="nav-back" @click="goBack">
<image class="back-icon" src="/static/ic_back.png" mode="aspectFit"></image>
</view>
<text class="navbar-title">代送</text>
<view class="nav-placeholder"></view>
</view>
</view>
<view :style="{ height: (statusBarHeight + 44) + 'px' }"></view>
<!-- 顶部大图 -->
<view class="top-banner" v-if="bannerUrl">
<image class="banner-img" :src="bannerUrl" mode="aspectFill"></image>
</view>
<!-- 表单区域 -->
<view class="form-section">
<!-- 1.代送物品 -->
<view class="form-group">
<text class="form-label">1.代送物品</text>
<view class="input-box">
<input v-model="form.itemName" placeholder="请输入要代送的物品名" placeholder-class="placeholder" />
</view>
</view>
<!-- 2.取货地点 -->
<view class="form-group">
<text class="form-label">2.取货地点</text>
<view class="input-box">
<input v-model="form.pickupLocation" placeholder="请输入取货地点" placeholder-class="placeholder" />
</view>
</view>
<!-- 3.送达地点 -->
<view class="form-group">
<text class="form-label">3.送达地点</text>
<view class="input-box">
<input v-model="form.deliveryLocation" placeholder="请输入送达地点" placeholder-class="placeholder" />
</view>
</view>
<!-- 4.备注信息 -->
<view class="form-group">
<text class="form-label">4.备注信息</text>
<view class="input-box textarea-box">
<textarea v-model="form.remark" placeholder="请输入备注信息,如注意事项等" placeholder-class="placeholder" :maxlength="200" />
</view>
</view>
<!-- 5.如何联系您 -->
<view class="form-group">
<text class="form-label">5.如何联系您?</text>
<view class="input-box">
<input v-model="form.phone" type="number" placeholder="请输入手机号,对方接单后才能看到" placeholder-class="placeholder" maxlength="11" />
</view>
</view>
<!-- 6.跑腿佣金 -->
<view class="form-group">
<text class="form-label">6.跑腿佣金</text>
<view class="input-box">
<input v-model="form.commission" type="digit" placeholder="请输入跑腿佣金最低1.0元" placeholder-class="placeholder" />
</view>
<text class="form-tip">佣金先由平台保管,接单方完成订单后才会收到佣金</text>
</view>
</view>
<!-- 提交按钮 -->
<view class="submit-section">
<button class="submit-btn" @click="onSubmit" :loading="submitting" :disabled="submitting">
支付佣金 确定下单
</button>
</view>
</view>
</template>
<script>
import { createOrder, getPageBanner } from '../../utils/api'
export default {
data() {
return {
statusBarHeight: 0,
bannerUrl: '',
form: {
itemName: '',
pickupLocation: '',
deliveryLocation: '',
remark: '',
phone: '',
commission: ''
},
submitting: false
}
},
onLoad() {
const sysInfo = uni.getSystemInfoSync()
this.statusBarHeight = sysInfo.statusBarHeight || 0
this.loadBanner()
},
methods: {
goBack() { uni.navigateBack() },
async loadBanner() {
try {
const res = await getPageBanner('delivery')
if (res?.value) this.bannerUrl = res.value
} catch (e) {}
},
validateCommission() {
const val = this.form.commission
if (!val) {
uni.showToast({ title: '请输入跑腿佣金', icon: 'none' }); return false
}
const num = parseFloat(val)
if (isNaN(num) || num < 1.0) {
uni.showToast({ title: '跑腿佣金不可低于1.0元', icon: 'none' }); return false
}
if (val.includes('.') && val.split('.')[1].length > 1) {
uni.showToast({ title: '佣金最多支持小数点后1位', icon: 'none' }); return false
}
return true
},
validateForm() {
if (!this.form.itemName.trim()) {
uni.showToast({ title: '请输入代送物品', icon: 'none' }); return false
}
if (!this.form.pickupLocation.trim()) {
uni.showToast({ title: '请输入取货地点', icon: 'none' }); return false
}
if (!this.form.deliveryLocation.trim()) {
uni.showToast({ title: '请输入送达地点', icon: 'none' }); return false
}
if (!this.form.phone.trim()) {
uni.showToast({ title: '请输入手机号', icon: 'none' }); return false
}
return this.validateCommission()
},
async onSubmit() {
if (!this.validateForm()) return
const token = uni.getStorageSync('token')
if (!token) {
uni.navigateTo({ url: '/pages/login/login' }); return
}
this.submitting = true
try {
const commission = parseFloat(this.form.commission)
const result = await createOrder({
orderType: 'Delivery',
itemName: this.form.itemName.trim(),
pickupLocation: this.form.pickupLocation.trim(),
deliveryLocation: this.form.deliveryLocation.trim(),
remark: this.form.remark.trim(),
phone: this.form.phone.trim(),
commission,
totalAmount: commission
})
if (result.paymentParams) await this.wxPay(result.paymentParams)
uni.showToast({ title: '下单成功', icon: 'success' })
setTimeout(() => { uni.navigateBack() }, 1500)
} catch (e) {} finally { this.submitting = false }
},
wxPay(params) {
return new Promise((resolve, reject) => {
uni.requestPayment({
...params, success: resolve,
fail: (err) => {
if (err.errMsg !== 'requestPayment:fail cancel')
uni.showToast({ title: '支付失败', icon: 'none' })
reject(err)
}
})
})
}
}
}
</script>
<style scoped>
.order-page {
padding-bottom: 40rpx;
background-color: #f5f5f5;
min-height: 100vh;
}
/* 自定义导航栏 */
.custom-navbar {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 999;
background: #FFB700;
}
.navbar-content {
height: 44px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20rpx;
}
.nav-back {
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
}
.back-icon {
width: 40rpx;
height: 40rpx;
}
.navbar-title {
font-size: 34rpx;
font-weight: bold;
color: #363636;
}
.nav-placeholder {
width: 60rpx;
}
/* 顶部大图 */
.top-banner {
width: 100%;
}
.banner-img {
width: 100%;
height: 330rpx;
}
/* 表单区域 */
.form-section {
padding: 10rpx 24rpx 0;
}
.form-group {
margin-bottom: 24rpx;
}
.form-label {
font-size: 30rpx;
color: #333333;
font-weight: bold;
display: block;
margin-bottom: 16rpx;
}
.input-box {
background-color: #ffffff;
border-radius: 16rpx;
padding: 0 24rpx;
height: 88rpx;
display: flex;
align-items: center;
}
.input-box input {
width: 100%;
height: 100%;
font-size: 28rpx;
color: #333;
}
.textarea-box {
height: 240rpx;
padding: 20rpx 24rpx;
align-items: flex-start;
}
.textarea-box textarea {
width: 100%;
height: 100%;
font-size: 28rpx;
color: #333;
}
.form-tip {
font-size: 24rpx;
color: #999999;
margin-top: 12rpx;
display: block;
text-align: center;
}
/* 提交按钮 */
.submit-section {
padding: 20rpx 24rpx;
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
}
.submit-btn {
width: 100%;
height: 96rpx;
line-height: 96rpx;
background: #FAD146;
color: #ffffff;
font-size: 32rpx;
font-weight: bold;
border-radius: 10rpx;
border: none;
text-align: center;
}
.submit-btn::after {
border: none;
}
.submit-btn[disabled] {
opacity: 0.6;
}
</style>