campus-errand/miniapp/pages/help/help.vue
2026-03-01 05:01:47 +08:00

258 lines
5.8 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="form-section">
<!-- 要做的事情 -->
<view class="form-item">
<text class="form-label">要做的事情</text>
<textarea class="form-textarea" v-model="form.itemName" placeholder="请描述您需要帮忙做的事情" />
</view>
<!-- 手机号 -->
<view class="form-item">
<text class="form-label">手机号</text>
<input class="form-input" v-model="form.phone" type="number" placeholder="请输入联系手机号" maxlength="11" />
</view>
<!-- 代购商品总金额 -->
<view class="form-item">
<text class="form-label">代购商品总金额</text>
<text class="form-tip">需包含商品总额和包装费等额外费用</text>
<view class="commission-input">
<text class="commission-unit">¥</text>
<input class="form-input commission-field" v-model="form.goodsAmount" type="digit" placeholder="请输入商品总金额" />
</view>
</view>
<!-- 跑腿佣金 -->
<view class="form-item">
<text class="form-label">跑腿佣金</text>
<view class="commission-input">
<text class="commission-unit">¥</text>
<input class="form-input commission-field" v-model="form.commission" type="digit" placeholder="最低1.0元" />
</view>
</view>
</view>
<!-- 提交按钮 -->
<view class="submit-section">
<text class="pay-amount">支付金额:¥{{ payAmount }}</text>
<button class="submit-btn" @click="onSubmit" :loading="submitting" :disabled="submitting">确定</button>
</view>
</view>
</template>
<script>
import { createOrder } from '../../utils/api'
export default {
data() {
return {
form: {
itemName: '',
phone: '',
goodsAmount: '',
commission: ''
},
submitting: false
}
},
computed: {
/** 支付金额 = 商品总金额 + 跑腿佣金Requirements 6.3 */
payAmount() {
const goods = parseFloat(this.form.goodsAmount) || 0
const commission = parseFloat(this.form.commission) || 0
return (goods + commission).toFixed(1)
}
},
methods: {
/** 校验佣金 */
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.phone.trim()) {
uni.showToast({ title: '请输入手机号', icon: 'none' })
return false
}
if (!this.form.goodsAmount) {
uni.showToast({ title: '请输入商品总金额', icon: 'none' })
return false
}
const goodsNum = parseFloat(this.form.goodsAmount)
if (isNaN(goodsNum) || goodsNum <= 0) {
uni.showToast({ title: '请输入正确的商品总金额', icon: 'none' })
return false
}
return this.validateCommission()
},
/** 提交订单Requirements 6.3, 6.4 */
async onSubmit() {
if (!this.validateForm()) return
this.submitting = true
try {
const commission = parseFloat(this.form.commission)
const goodsAmount = parseFloat(this.form.goodsAmount)
const orderData = {
orderType: 'Help',
itemName: this.form.itemName.trim(),
phone: this.form.phone.trim(),
goodsAmount: goodsAmount,
commission: commission,
totalAmount: goodsAmount + commission
}
const result = await createOrder(orderData)
if (result.paymentParams) {
await this.wxPay(result.paymentParams)
}
uni.showToast({ title: '下单成功', icon: 'success' })
setTimeout(() => { uni.navigateBack() }, 1500)
} catch (e) {
// 错误已在 request 中处理
} 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: 24rpx;
padding-bottom: 200rpx;
background-color: #f5f5f5;
min-height: 100vh;
}
.form-section {
background-color: #ffffff;
border-radius: 16rpx;
padding: 20rpx 30rpx;
}
.form-item {
padding: 20rpx 0;
border-bottom: 1rpx solid #f0f0f0;
}
.form-item:last-child {
border-bottom: none;
}
.form-label {
font-size: 28rpx;
color: #333333;
margin-bottom: 12rpx;
display: block;
}
.form-tip {
font-size: 24rpx;
color: #999999;
margin-bottom: 12rpx;
display: block;
}
.form-input {
font-size: 28rpx;
color: #333333;
height: 72rpx;
}
.form-textarea {
font-size: 28rpx;
color: #333333;
width: 100%;
height: 200rpx;
}
.commission-input {
display: flex;
align-items: center;
}
.commission-unit {
font-size: 32rpx;
color: #e64340;
margin-right: 8rpx;
font-weight: bold;
}
.commission-field {
flex: 1;
}
.submit-section {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: #ffffff;
padding: 20rpx 30rpx;
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
}
.pay-amount {
font-size: 32rpx;
color: #e64340;
font-weight: bold;
}
.submit-btn {
width: 240rpx;
height: 80rpx;
line-height: 80rpx;
background-color: #007AFF;
color: #ffffff;
font-size: 30rpx;
border-radius: 40rpx;
border: none;
}
.submit-btn[disabled] {
opacity: 0.6;
}
</style>