campus-errand/miniapp/pages/help/help.vue
2026-03-14 23:38:46 +08:00

328 lines
7.5 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 textarea-box">
<textarea v-model="form.itemName" placeholder="请描述您需要帮忙做的事情" placeholder-class="placeholder" :maxlength="500" />
</view>
</view>
<!-- 2.如何联系您 -->
<view class="form-group">
<text class="form-label">2.如何联系您?</text>
<view class="input-box">
<input v-model="form.phone" type="number" placeholder="请输入手机号,对方接单后才能看到" placeholder-class="placeholder" maxlength="11" />
</view>
</view>
<!-- 3.商品总金额 -->
<view class="form-group">
<text class="form-label">3.商品总金额</text>
<text class="form-tip">需包含商品总额和包装费等额外费用</text>
<view class="input-box">
<input v-model="form.goodsAmount" type="digit" placeholder="请输入商品总金额" placeholder-class="placeholder" />
</view>
</view>
<!-- 4.跑腿佣金 -->
<view class="form-group">
<text class="form-label">4.跑腿佣金</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">
<text class="pay-amount">支付金额:¥{{ payAmount }}</text>
<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 {
form: {
itemName: '',
phone: '',
goodsAmount: '',
commission: ''
},
submitting: false,
statusBarHeight: 0,
bannerUrl: ''
}
},
computed: {
/** 支付金额 = 商品总金额 + 跑腿佣金 */
payAmount() {
const goods = parseFloat(this.form.goodsAmount) || 0
const commission = parseFloat(this.form.commission) || 0
return (goods + commission).toFixed(1)
}
},
onLoad() {
const sysInfo = uni.getSystemInfoSync()
this.statusBarHeight = sysInfo.statusBarHeight || 0
this.loadBanner()
},
methods: {
goBack() { uni.navigateBack() },
async loadBanner() {
try {
const res = await getPageBanner('help')
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.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()
},
/** 提交订单 */
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 goodsAmount = parseFloat(this.form.goodsAmount)
const result = await createOrder({
orderType: 'Help',
itemName: this.form.itemName.trim(),
phone: this.form.phone.trim(),
goodsAmount,
commission,
totalAmount: goodsAmount + 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 {
padding: 20rpx 24rpx 0;
}
.banner-img {
width: 100%;
height: 280rpx;
border-radius: 20rpx;
}
/* 表单区域 */
.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));
}
.pay-amount {
font-size: 32rpx;
color: #e64340;
font-weight: bold;
display: block;
text-align: center;
margin-bottom: 20rpx;
}
.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[disabled] {
opacity: 0.6;
}
</style>