<template>
|
<view class="settlement-container">
|
<view class="settlement-header">
|
<text class="header-title">任务结算</text>
|
</view>
|
|
<scroll-view class="settlement-content" scroll-y="true">
|
<view class="task-info-section">
|
<view class="info-item">
|
<view class="label">任务编号:</view>
|
<view class="value">{{ task.taskNo }}</view>
|
</view>
|
|
<view class="info-item">
|
<view class="label">任务类型:</view>
|
<view class="value">{{ taskTypeText }}</view>
|
</view>
|
|
<view class="info-item">
|
<view class="label">车辆信息:</view>
|
<view class="value">{{ task.vehicle }}</view>
|
</view>
|
|
<view class="info-item">
|
<view class="label">出发地:</view>
|
<view class="value">{{ task.startLocation }}</view>
|
</view>
|
|
<view class="info-item">
|
<view class="label">目的地:</view>
|
<view class="value">{{ task.endLocation }}</view>
|
</view>
|
</view>
|
|
<view class="amount-section">
|
<view class="section-title">费用信息</view>
|
|
<view class="amount-item">
|
<view class="label">基础费用:</view>
|
<view class="value">¥{{ baseAmount }}</view>
|
</view>
|
|
<view class="amount-item additional-fees" @click="showAdditionalFees">
|
<view class="label">附加费用:</view>
|
<view class="value">¥{{ additionalAmount }}
|
<uni-icons type="arrowright" size="16" color="#999"></uni-icons>
|
</view>
|
</view>
|
|
<view class="amount-item total-amount">
|
<view class="label">总费用:</view>
|
<view class="value total">¥{{ totalAmount }}</view>
|
</view>
|
|
<view class="amount-item paid-amount" v-if="paidAmount > 0">
|
<view class="label">已支付:</view>
|
<view class="value" style="color: #34C759;">¥{{ paidAmount }}</view>
|
</view>
|
|
<view class="amount-item remaining-amount" v-if="paidAmount > 0">
|
<view class="label">剩余未付:</view>
|
<view class="value" style="color: #ff9900; font-weight: bold;">¥{{ remainingAmount }}</view>
|
</view>
|
</view>
|
|
<!-- 已支付记录列表 -->
|
<view class="payment-history-section" v-if="paidPaymentList.length > 0">
|
<view class="section-title">支付记录</view>
|
<view
|
class="payment-item"
|
v-for="payment in paidPaymentList"
|
:key="payment.id"
|
>
|
<view class="payment-info">
|
<view class="payment-method">
|
<text class="method-tag" :class="['method-' + payment.paymentMethod.toLowerCase()]">
|
{{ getPaymentMethodText(payment.paymentMethod) }}
|
</text>
|
</view>
|
<view class="payment-time">
|
{{ formatPaymentTime(payment.payTime) }}
|
</view>
|
</view>
|
<view class="payment-amount">
|
¥{{ payment.settlementAmount }}
|
</view>
|
</view>
|
</view>
|
|
<view class="settlement-form">
|
<view class="form-item">
|
<view class="form-label">结算金额</view>
|
<input
|
class="form-input"
|
type="digit"
|
placeholder="请输入结算金额"
|
v-model="settlementAmount"
|
/>
|
</view>
|
|
<view class="form-item">
|
<view class="form-label">支付方式</view>
|
<picker mode="selector" :range="paymentMethods" @change="onPaymentMethodChange">
|
<view class="form-input picker-input">
|
{{ selectedPaymentMethod || '请选择支付方式' }}
|
<uni-icons type="arrowright" size="16" color="#999"></uni-icons>
|
</view>
|
</picker>
|
</view>
|
|
<view class="form-item">
|
<view class="form-label">备注</view>
|
<textarea
|
class="form-textarea"
|
placeholder="请输入备注信息"
|
v-model="remark"
|
></textarea>
|
</view>
|
</view>
|
|
|
</scroll-view>
|
|
<view class="action-section">
|
<button
|
v-if="!showQRCode || paymentStatus === 'success'"
|
class="submit-btn"
|
@click="saveSettlement"
|
:disabled="!canSave"
|
>
|
保存结算
|
</button>
|
</view>
|
|
<!-- 支付二维码弹窗 -->
|
<uni-popup ref="qrCodePopup" type="center" :mask-click="false">
|
<view class="qr-popup-content">
|
<view class="qr-popup-header">
|
<text class="qr-popup-title">{{ selectedPaymentMethod }}支付</text>
|
</view>
|
|
<view class="qr-popup-body">
|
<view class="qr-code-box" v-if="qrCodeImage">
|
<image class="qr-image" :src="qrCodeImage" mode="widthFix"></image>
|
</view>
|
|
<view class="qr-loading" v-else>
|
<uni-icons type="spinner-cycle" size="40" color="#007AFF"></uni-icons>
|
<text class="loading-text">正在生成二维码...</text>
|
</view>
|
|
<view class="qr-tip-text">请使用{{ selectedPaymentMethod }}扫码支付</view>
|
<view class="qr-amount">¥{{ settlementAmount }}</view>
|
|
<view class="payment-status-box">
|
<view v-if="paymentStatus === 'pending'" class="status-waiting">
|
<uni-icons type="spinner-cycle" size="20" color="#ff9900"></uni-icons>
|
<text>等待支付中...</text>
|
</view>
|
<view v-if="paymentStatus === 'success'" class="status-paid">
|
<uni-icons type="checkmarkempty" size="24" color="#4cd964"></uni-icons>
|
<text>支付成功</text>
|
</view>
|
</view>
|
</view>
|
|
<view class="qr-popup-footer">
|
<button
|
class="cancel-pay-btn"
|
@click="cancelPayment"
|
v-if="paymentStatus !== 'success'"
|
>
|
取消支付
|
</button>
|
<button
|
class="confirm-pay-btn"
|
@click="confirmPaymentSuccess"
|
v-if="paymentStatus === 'success'"
|
>
|
确定
|
</button>
|
</view>
|
</view>
|
</uni-popup>
|
|
<!-- 附加费用弹窗 -->
|
<uni-popup ref="additionalFeesPopup" type="bottom">
|
<view class="popup-content">
|
<view class="popup-header">
|
<text class="header-title">附加费用</text>
|
<view class="close-btn" @click="closeAdditionalFeesPopup">
|
<uni-icons type="close" size="20" color="#999"></uni-icons>
|
</view>
|
</view>
|
|
<!-- 简化版费用添加 -->
|
<view class="simple-fee-section">
|
<view class="form-item">
|
<view class="form-label">费用类型</view>
|
<picker mode="selector" :range="additionalFeeTypeNames" @change="onFeeTypeChange">
|
<view class="form-input picker-input">
|
{{ selectedFeeTypeName || '请选择费用类型' }}
|
<uni-icons type="arrowright" size="16" color="#999"></uni-icons>
|
</view>
|
</picker>
|
</view>
|
|
<view class="form-item">
|
<view class="form-label">费用金额</view>
|
<input
|
class="form-input"
|
type="digit"
|
placeholder="请输入费用金额"
|
v-model="newFeePrice"
|
/>
|
</view>
|
|
<view class="add-fee-btn">
|
<button class="confirm-btn" @click="addCustomFee">添加费用</button>
|
</view>
|
</view>
|
|
<!-- 已添加的费用列表 -->
|
<view class="added-fees-list" v-if="additionalFeeList.length > 0">
|
<view class="section-title">已添加费用</view>
|
<view
|
class="fee-item"
|
v-for="fee in additionalFeeList"
|
:key="fee.id"
|
>
|
<view class="fee-info">
|
<view class="fee-name">{{ fee.feeName }}</view>
|
<view class="fee-price">¥{{ fee.unitAmount }} × {{ fee.quantity }}</view>
|
</view>
|
<view class="fee-actions">
|
<view class="fee-total">¥{{ fee.totalAmount }}</view>
|
<view class="delete-btn" @click="removeFee(fee.id)" v-if="!paySuccess">
|
<uni-icons type="trash" size="20" color="#e54d42"></uni-icons>
|
</view>
|
</view>
|
</view>
|
</view>
|
|
<view class="popup-footer">
|
<button class="confirm-btn" @click="confirmAdditionalFees">确定</button>
|
</view>
|
</view>
|
</uni-popup>
|
</view>
|
</template>
|
|
<script>
|
import { getPaymentInfo, addAdditionalFee, removeAdditionalFee, createPayment, getPaymentStatus } from '@/api/payment'
|
import { getTask } from '@/api/task'
|
|
export default {
|
data() {
|
return {
|
taskId: null,
|
task: {},
|
baseAmount: 0, // 基础费用(成交价)
|
additionalAmount: 0, // 附加费用汇总
|
settlementAmount: '', // 结算金额
|
remark: '', // 备注
|
paymentMethods: [], // 从字典加载支付方式
|
paymentMethodDict: [], // 字典原始数据
|
selectedPaymentMethod: '',
|
showQRCode: false,
|
paymentStatus: 'pending', // pending, success
|
qrCodeImage: '', // 二维码图片路径
|
paymentId: null,
|
pollTimer: null, // 轮询定时器
|
additionalFeeTypes: [], // 从字典加载
|
additionalFeeList: [], // 已添加的附加费用列表
|
selectedFeeTypeName: '', // 选中的费用类型名称
|
selectedFeeTypeValue: '', // 选中的费用类型值
|
newFeePrice: '', // 新增费用价格
|
loading: false,
|
paySuccess: false, // 支付成功标记
|
paidAmount: 0, // 已支付金额
|
paidPaymentList: [] // 已支付记录列表
|
}
|
},
|
computed: {
|
totalAmount() {
|
return this.baseAmount + this.additionalAmount;
|
},
|
// 剩余未支付金额
|
remainingAmount() {
|
return this.totalAmount - this.paidAmount;
|
},
|
// 任务类型显示
|
taskTypeText() {
|
const typeMap = {
|
'EMERGENCY_TRANSFER': '急救转运',
|
'SCHEDULED_TRANSFER': '计划转运',
|
'EMERGENCY_RESCUE': '急救抢救',
|
'ORDINARY_TASK': '普通任务'
|
}
|
return typeMap[this.task.type] || this.task.type
|
},
|
canSave() {
|
// 已全额支付后不能再次保存
|
if (this.remainingAmount <= 0) {
|
return false
|
}
|
|
if (!this.settlementAmount || !this.selectedPaymentMethod) {
|
return false
|
}
|
|
const amount = parseFloat(this.settlementAmount)
|
|
// 校验结算金额必须大于0且不超过剩余金额
|
if (amount <= 0 || amount > this.remainingAmount) {
|
return false
|
}
|
|
const dictValue = this.getPaymentMethodValue(this.selectedPaymentMethod)
|
|
// 1-现金, 6-挂账, 7-易医通挂账 可以直接保存
|
if (dictValue === '1' || dictValue === '6' || dictValue === '7') {
|
return true
|
}
|
|
// 3-微信支付, 4-支付宝 需要支付成功后才能保存
|
if (dictValue === '3' || dictValue === '4') {
|
return this.paymentStatus === 'success'
|
}
|
|
// 2-银行转账, 5-POS收款 直接保存
|
return true
|
},
|
// 获取费用类型名称数组
|
additionalFeeTypeNames() {
|
return this.additionalFeeTypes.map(fee => fee.dictLabel);
|
}
|
},
|
onLoad(options) {
|
if (options.taskId) {
|
this.taskId = options.taskId
|
this.loadPaymentMethods() // 加载支付方式字典
|
this.loadPaymentInfo()
|
this.loadFeeTypes()
|
} else {
|
this.$modal.showToast('任务ID不能为空')
|
setTimeout(() => {
|
uni.navigateBack()
|
}, 1500)
|
}
|
},
|
onUnload() {
|
// 清除轮询定时器
|
if (this.pollTimer) {
|
clearInterval(this.pollTimer)
|
}
|
},
|
methods: {
|
// 加载支付方式字典
|
loadPaymentMethods() {
|
this.$dict.getDicts('task_payment_method').then(res => {
|
// 过滤掉退款(8)和积分(9),只显示1-7
|
this.paymentMethodDict = (res.data || []).filter(item => {
|
const value = parseInt(item.dictValue)
|
return value >= 1 && value <= 7
|
})
|
// 提取显示名称数组用于picker
|
this.paymentMethods = this.paymentMethodDict.map(item => item.dictLabel)
|
}).catch(err => {
|
console.error('加载支付方式字典失败', err)
|
this.$modal.showToast('加载支付方式失败')
|
})
|
},
|
|
// 根据选中的名称获取字典值
|
getPaymentMethodValue(label) {
|
const method = this.paymentMethodDict.find(item => item.dictLabel === label)
|
return method ? method.dictValue : ''
|
},
|
|
// 加载支付信息
|
loadPaymentInfo() {
|
this.loading = true
|
getPaymentInfo(this.taskId).then(res => {
|
const data = res.data
|
|
// 任务基本信息
|
this.task = {
|
taskNo: data.taskCode || '',
|
type: data.taskType || '',
|
vehicle: data.vehicleInfo || '未分配',
|
startLocation: data.departureAddress || '未设置',
|
endLocation: data.destinationAddress || '未设置'
|
}
|
|
// 费用信息
|
this.baseAmount = data.transferPrice || 0
|
this.additionalAmount = data.additionalAmount || 0
|
this.additionalFeeList = data.additionalFees || []
|
this.paidAmount = data.paidAmount || 0
|
this.paidPaymentList = data.paidPayments || [] // 加载已支付记录列表
|
|
// 默认结算金额为剩余未支付金额
|
const remaining = (data.totalAmount || 0) - this.paidAmount
|
this.settlementAmount = remaining > 0 ? remaining.toString() : ''
|
|
// 如果已全额支付,提示已结算
|
if (remaining <= 0) {
|
this.paySuccess = true
|
this.$modal.showToast('该任务已结算')
|
}
|
|
this.loading = false
|
}).catch(err => {
|
console.error('加载支付信息失败', err)
|
this.loading = false
|
this.$modal.showToast('加载支付信息失败')
|
})
|
},
|
|
// 加载费用类型字典
|
loadFeeTypes() {
|
this.$dict.getDicts('task_additional_fee_type').then(res => {
|
this.additionalFeeTypes = res.data || []
|
})
|
},
|
|
onPaymentMethodChange(e) {
|
this.selectedPaymentMethod = this.paymentMethods[e.detail.value]
|
const dictValue = this.getPaymentMethodValue(this.selectedPaymentMethod)
|
|
// 3-微信支付, 4-支付宝
|
if (dictValue === '3' || dictValue === '4') {
|
this.openQRCodePopup(dictValue)
|
} else {
|
// 其他支付方式不显示二维码
|
this.showQRCode = false
|
this.paymentStatus = 'pending'
|
}
|
},
|
|
// 打开支付二维码弹窗
|
openQRCodePopup(dictValue) {
|
// 重置状态
|
this.qrCodeImage = ''
|
this.paymentStatus = 'pending'
|
this.showQRCode = true
|
|
// 打开弹窗
|
this.$refs.qrCodePopup.open()
|
|
// 生成二维码
|
this.generateQRCode(dictValue)
|
},
|
|
// 取消支付
|
cancelPayment() {
|
// 清除轮询
|
if (this.pollTimer) {
|
clearInterval(this.pollTimer);
|
this.pollTimer = null;
|
}
|
|
// 关闭弹窗
|
this.$refs.qrCodePopup.close();
|
|
// 重置状态
|
this.selectedPaymentMethod = '';
|
this.showQRCode = false;
|
this.qrCodeImage = '';
|
this.paymentStatus = 'pending';
|
},
|
|
// 确认支付成功
|
confirmPaymentSuccess() {
|
// 关闭弹窗
|
this.$refs.qrCodePopup.close();
|
|
// 重新加载支付信息,刷新显示
|
this.loadPaymentInfo();
|
|
// 重置状态,准备下一笔支付
|
this.selectedPaymentMethod = '';
|
this.showQRCode = false;
|
this.qrCodeImage = '';
|
this.paymentStatus = 'pending';
|
this.remark = '';
|
// settlementAmount 会在 loadPaymentInfo 中自动设置为剩余金额
|
},
|
|
// 生成支付二维码
|
generateQRCode(paymentMethod) {
|
// 校验结算金额
|
if (!this.settlementAmount) {
|
this.$modal.showToast('请先输入结算金额');
|
this.$refs.qrCodePopup.close();
|
this.selectedPaymentMethod = '';
|
return;
|
}
|
|
const amount = parseFloat(this.settlementAmount);
|
if (amount <= 0) {
|
this.$modal.showToast('结算金额必须大于0');
|
this.$refs.qrCodePopup.close();
|
this.selectedPaymentMethod = '';
|
return;
|
}
|
|
if (amount > this.remainingAmount) {
|
this.$modal.showToast(`结算金额不能超过剩余金额¥${this.remainingAmount}`);
|
this.$refs.qrCodePopup.close();
|
this.selectedPaymentMethod = '';
|
return;
|
}
|
|
const data = {
|
taskId: this.taskId,
|
paymentMethod: paymentMethod,
|
settlementAmount: amount,
|
remark: this.remark
|
};
|
|
createPayment(data).then(res => {
|
const result = res.data;
|
this.paymentId = result.paymentId;
|
this.qrCodeImage = result.codeUrl;
|
this.paymentStatus = 'pending';
|
|
// 开始轮询支付状态
|
this.checkPaymentStatus();
|
}).catch(err => {
|
console.error('生成支付二维码失败', err);
|
this.$modal.showToast('生成支付二维码失败');
|
this.$refs.qrCodePopup.close();
|
this.selectedPaymentMethod = '';
|
});
|
},
|
|
// 费用类型选择
|
onFeeTypeChange(e) {
|
const index = e.detail.value
|
this.selectedFeeTypeName = this.additionalFeeTypes[index].dictLabel
|
this.selectedFeeTypeValue = this.additionalFeeTypes[index].dictValue
|
},
|
|
// 轮询检查支付状态
|
checkPaymentStatus() {
|
if (this.pollTimer) {
|
clearInterval(this.pollTimer);
|
}
|
|
this.pollTimer = setInterval(() => {
|
getPaymentStatus(this.taskId, this.paymentId).then(res => {
|
const data = res.data;
|
if (data.payStatus === 'PAID') {
|
// 支付成功
|
this.paymentStatus = 'success';
|
clearInterval(this.pollTimer);
|
this.pollTimer = null;
|
|
// 在弹窗中显示支付成功状态
|
// 用户需要点击"确定"按钮来关闭弹窗并刷新页面
|
}
|
}).catch(err => {
|
console.error('查询支付状态失败', err);
|
});
|
}, 2000); // 每2秒轮询一次
|
},
|
|
showAdditionalFees() {
|
this.$refs.additionalFeesPopup.open();
|
},
|
|
closeAdditionalFeesPopup() {
|
this.$refs.additionalFeesPopup.close();
|
},
|
|
// 添加自定义费用
|
addCustomFee() {
|
if (!this.selectedFeeTypeName) {
|
this.$modal.showToast('请选择费用类型');
|
return;
|
}
|
|
if (!this.newFeePrice || isNaN(this.newFeePrice) || parseFloat(this.newFeePrice) <= 0) {
|
this.$modal.showToast('请输入有效的费用金额');
|
return;
|
}
|
|
// 调用接口添加附加费用
|
const data = {
|
taskId: this.taskId,
|
feeType: this.selectedFeeTypeValue,
|
feeName: this.selectedFeeTypeName,
|
unitAmount: parseFloat(this.newFeePrice),
|
quantity: 1,
|
remark: ''
|
}
|
|
addAdditionalFee(data).then(res => {
|
this.$modal.showToast('费用添加成功')
|
|
// 清空输入框
|
this.selectedFeeTypeName = ''
|
this.selectedFeeTypeValue = ''
|
this.newFeePrice = ''
|
|
// 重新加载支付信息
|
this.loadPaymentInfo()
|
}).catch(err => {
|
console.error('添加费用失败', err)
|
this.$modal.showToast('添加费用失败')
|
})
|
},
|
|
// 删除附加费用
|
removeFee(feeId) {
|
this.$modal.confirm('确定要删除该费用吗?').then(() => {
|
removeAdditionalFee({ taskId: this.taskId, feeId }).then(res => {
|
this.$modal.showToast('删除成功')
|
// 重新加载支付信息
|
this.loadPaymentInfo()
|
}).catch(err => {
|
console.error('删除费用失败', err)
|
this.$modal.showToast('删除费用失败')
|
})
|
}).catch(() => {})
|
},
|
|
confirmAdditionalFees() {
|
this.closeAdditionalFeesPopup();
|
},
|
|
// 获取支付方式文本
|
getPaymentMethodText(dictValue) {
|
const method = this.paymentMethodDict.find(item => item.dictValue === dictValue)
|
return method ? method.dictLabel : dictValue
|
},
|
|
// 格式化支付时间
|
formatPaymentTime(time) {
|
if (!time) return '未知'
|
const date = new Date(time)
|
const year = date.getFullYear()
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
const day = String(date.getDate()).padStart(2, '0')
|
const hour = String(date.getHours()).padStart(2, '0')
|
const minute = String(date.getMinutes()).padStart(2, '0')
|
return `${year}-${month}-${day} ${hour}:${minute}`
|
},
|
|
saveSettlement() {
|
if (!this.settlementAmount) {
|
this.$modal.showToast('请输入结算金额')
|
return
|
}
|
|
if (!this.selectedPaymentMethod) {
|
this.$modal.showToast('请选择支付方式')
|
return
|
}
|
|
const amount = parseFloat(this.settlementAmount)
|
|
// 校验结算金额必须大于0
|
if (amount <= 0) {
|
this.$modal.showToast('结算金额必须大于0')
|
return
|
}
|
|
// 校验结算金额不能超过剩余金额
|
if (amount > this.remainingAmount) {
|
this.$modal.showToast(`结算金额不能超过剩余金额¥${this.remainingAmount}`)
|
return
|
}
|
|
const dictValue = this.getPaymentMethodValue(this.selectedPaymentMethod)
|
|
// 3-微信支付, 4-支付宝 已经在选择时生成了二维码,等待支付完成
|
if (dictValue === '3' || dictValue === '4') {
|
if (this.paymentStatus !== 'success') {
|
this.$modal.showToast('请先完成扫码支付')
|
return
|
}
|
}
|
|
// 1-现金, 2-银行转账, 5-POS收款, 6-挂账, 7-易医通挂账 需要创建支付记录
|
if (dictValue === '1' || dictValue === '2' || dictValue === '5' || dictValue === '6' || dictValue === '7') {
|
this.$modal.confirm('确定要保存结算信息吗?').then(() => {
|
const data = {
|
taskId: this.taskId,
|
paymentMethod: dictValue,
|
settlementAmount: amount,
|
remark: this.remark
|
}
|
|
this.loading = true
|
createPayment(data).then(res => {
|
this.loading = false
|
const result = res.data
|
this.paymentId = result.paymentId
|
this.paymentStatus = 'success'
|
|
// 重新加载支付信息以获取最新的已支付金额
|
this.loadPaymentInfo()
|
|
// 检查是否全额支付(使用最新数据判断)
|
setTimeout(() => {
|
if (this.remainingAmount <= 0) {
|
this.paySuccess = true
|
this.$modal.showToast('支付成功,已全额结算')
|
setTimeout(() => {
|
uni.navigateBack()
|
}, 1500)
|
} else {
|
this.$modal.showToast(`支付成功,剩余¥${this.remainingAmount.toFixed(2)}`)
|
// 重置表单,准备下一笔支付
|
this.selectedPaymentMethod = ''
|
this.remark = ''
|
}
|
}, 300) // 等待数据加载完成
|
}).catch(err => {
|
this.loading = false
|
console.error('创建支付失败', err)
|
this.$modal.showToast('创建支付失败')
|
})
|
}).catch(() => {
|
// 取消操作
|
})
|
} else {
|
// 扫码支付(微信/支付宝)的情况不应该走到这里
|
// 因为扫码支付在 confirmPaymentSuccess 中处理
|
this.$modal.showToast('请先完成扫码支付')
|
}
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss">
|
.settlement-container {
|
padding: 20rpx;
|
background-color: #f5f5f5;
|
height: 100vh;
|
display: flex;
|
flex-direction: column;
|
// 隐藏滚动条但保持滚动功能
|
::-webkit-scrollbar {
|
display: none;
|
width: 0 !important;
|
height: 0 !important;
|
background: transparent;
|
}
|
|
// Firefox滚动条隐藏
|
* {
|
scrollbar-width: none; /* Firefox */
|
}
|
|
// IE/Edge滚动条隐藏
|
* {
|
-ms-overflow-style: none; /* IE 10+ */
|
}
|
}
|
|
.settlement-header {
|
background-color: white;
|
border-radius: 15rpx;
|
padding: 30rpx;
|
margin-bottom: 20rpx;
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
flex-shrink: 0;
|
|
.header-title {
|
font-size: 36rpx;
|
font-weight: bold;
|
color: #333;
|
text-align: center;
|
}
|
}
|
|
.settlement-content {
|
flex: 1;
|
|
.task-info-section {
|
background-color: white;
|
border-radius: 15rpx;
|
padding: 30rpx;
|
margin-bottom: 20rpx;
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
|
.info-item {
|
display: flex;
|
margin-bottom: 20rpx;
|
padding-bottom: 20rpx;
|
border-bottom: 1rpx solid #f0f0f0;
|
|
&:last-child {
|
margin-bottom: 0;
|
padding-bottom: 0;
|
border-bottom: none;
|
}
|
|
.label {
|
font-size: 28rpx;
|
color: #666;
|
margin-right: 20rpx;
|
white-space: nowrap;
|
width: 150rpx;
|
}
|
|
.value {
|
font-size: 28rpx;
|
flex: 1;
|
word-break: break-all;
|
}
|
}
|
}
|
|
.amount-section {
|
background-color: white;
|
border-radius: 15rpx;
|
padding: 30rpx;
|
margin-bottom: 20rpx;
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
|
.section-title {
|
font-size: 32rpx;
|
font-weight: bold;
|
margin-bottom: 30rpx;
|
color: #333;
|
}
|
|
.amount-item {
|
display: flex;
|
justify-content: space-between;
|
margin-bottom: 20rpx;
|
padding-bottom: 20rpx;
|
border-bottom: 1rpx solid #f0f0f0;
|
|
&:last-child {
|
margin-bottom: 0;
|
padding-bottom: 0;
|
border-bottom: none;
|
}
|
|
&.additional-fees {
|
.value {
|
color: #007AFF;
|
}
|
}
|
|
&.total-amount {
|
.label {
|
font-weight: bold;
|
}
|
|
.value.total {
|
font-weight: bold;
|
font-size: 32rpx;
|
color: #e54d42;
|
}
|
}
|
|
.label {
|
font-size: 28rpx;
|
color: #333;
|
}
|
|
.value {
|
font-size: 28rpx;
|
color: #333;
|
}
|
}
|
}
|
|
.payment-history-section {
|
background-color: white;
|
border-radius: 15rpx;
|
padding: 30rpx;
|
margin-bottom: 20rpx;
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
|
.section-title {
|
font-size: 32rpx;
|
font-weight: bold;
|
margin-bottom: 20rpx;
|
color: #333;
|
}
|
|
.payment-item {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 20rpx 0;
|
border-bottom: 1rpx solid #f0f0f0;
|
|
&:last-child {
|
border-bottom: none;
|
}
|
|
.payment-info {
|
flex: 1;
|
|
.payment-method {
|
margin-bottom: 10rpx;
|
|
.method-tag {
|
display: inline-block;
|
padding: 4rpx 12rpx;
|
border-radius: 6rpx;
|
font-size: 24rpx;
|
color: white;
|
|
&.method-cash {
|
background-color: #34C759;
|
}
|
|
&.method-on_account {
|
background-color: #ff9500;
|
}
|
|
&.method-wechat {
|
background-color: #09BB07;
|
}
|
|
&.method-alipay {
|
background-color: #1677FF;
|
}
|
}
|
}
|
|
.payment-time {
|
font-size: 24rpx;
|
color: #999;
|
}
|
}
|
|
.payment-amount {
|
font-size: 32rpx;
|
font-weight: bold;
|
color: #34C759;
|
}
|
}
|
}
|
|
.settlement-form {
|
background-color: white;
|
border-radius: 15rpx;
|
padding: 30rpx;
|
margin-bottom: 20rpx;
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
|
.form-item {
|
margin-bottom: 40rpx;
|
|
&:last-child {
|
margin-bottom: 0;
|
}
|
|
.form-label {
|
font-size: 28rpx;
|
margin-bottom: 15rpx;
|
color: #333;
|
}
|
|
.form-input {
|
height: 70rpx;
|
padding: 0 20rpx;
|
border: 1rpx solid #eee;
|
border-radius: 10rpx;
|
font-size: 28rpx;
|
|
&.picker-input {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
}
|
}
|
|
.form-textarea {
|
width: 100%;
|
min-height: 150rpx;
|
padding: 20rpx;
|
border: 1rpx solid #eee;
|
border-radius: 10rpx;
|
font-size: 28rpx;
|
resize: none;
|
}
|
}
|
}
|
|
.qr-code-section {
|
background-color: white;
|
border-radius: 15rpx;
|
padding: 30rpx;
|
margin-bottom: 20rpx;
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
text-align: center;
|
|
.section-title {
|
font-size: 32rpx;
|
font-weight: bold;
|
margin-bottom: 30rpx;
|
color: #333;
|
}
|
|
.qr-code-container {
|
margin-bottom: 30rpx;
|
|
.qr-code {
|
width: 300rpx;
|
height: 300rpx;
|
margin: 0 auto 20rpx;
|
}
|
|
.qr-tip {
|
font-size: 26rpx;
|
color: #666;
|
}
|
}
|
|
.payment-status {
|
.status-pending {
|
font-size: 28rpx;
|
color: #ff9900;
|
}
|
|
.status-success {
|
font-size: 28rpx;
|
color: #4cd964;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
}
|
}
|
}
|
}
|
|
.action-section {
|
padding: 20rpx 0;
|
flex-shrink: 0;
|
|
.submit-btn {
|
width: 80%;
|
height: 80rpx;
|
background-color: #007AFF;
|
color: white;
|
border-radius: 10rpx;
|
font-size: 32rpx;
|
margin: 0 auto;
|
display: block;
|
|
&[disabled] {
|
background-color: #ccc;
|
}
|
}
|
}
|
|
// 支付二维码弹窗样式
|
.qr-popup-content {
|
width: 600rpx;
|
background-color: white;
|
border-radius: 20rpx;
|
overflow: hidden;
|
|
.qr-popup-header {
|
padding: 40rpx 30rpx 30rpx;
|
text-align: center;
|
border-bottom: 1rpx solid #f0f0f0;
|
|
.qr-popup-title {
|
font-size: 36rpx;
|
font-weight: bold;
|
color: #333;
|
}
|
}
|
|
.qr-popup-body {
|
padding: 40rpx 30rpx;
|
text-align: center;
|
|
.qr-code-box {
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
margin-bottom: 30rpx;
|
|
.qr-image {
|
width: 400rpx;
|
height: 400rpx;
|
border: 2rpx solid #f0f0f0;
|
border-radius: 10rpx;
|
padding: 20rpx;
|
box-sizing: border-box;
|
}
|
}
|
|
.qr-loading {
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
justify-content: center;
|
height: 400rpx;
|
margin-bottom: 30rpx;
|
|
.loading-text {
|
margin-top: 20rpx;
|
font-size: 28rpx;
|
color: #999;
|
}
|
}
|
|
.qr-tip-text {
|
font-size: 28rpx;
|
color: #666;
|
margin-bottom: 20rpx;
|
}
|
|
.qr-amount {
|
font-size: 48rpx;
|
font-weight: bold;
|
color: #e54d42;
|
margin-bottom: 30rpx;
|
}
|
|
.payment-status-box {
|
padding: 20rpx;
|
border-radius: 10rpx;
|
|
.status-waiting {
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
gap: 10rpx;
|
font-size: 28rpx;
|
color: #ff9900;
|
|
text {
|
margin-left: 10rpx;
|
}
|
}
|
|
.status-paid {
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
gap: 10rpx;
|
font-size: 32rpx;
|
color: #4cd964;
|
font-weight: bold;
|
|
text {
|
margin-left: 10rpx;
|
}
|
}
|
}
|
}
|
|
.qr-popup-footer {
|
padding: 20rpx 30rpx 30rpx;
|
|
.cancel-pay-btn,
|
.confirm-pay-btn {
|
width: 100%;
|
height: 80rpx;
|
border-radius: 10rpx;
|
font-size: 32rpx;
|
border: none;
|
}
|
|
.cancel-pay-btn {
|
background-color: #f5f5f5;
|
color: #666;
|
}
|
|
.confirm-pay-btn {
|
background-color: #4cd964;
|
color: white;
|
}
|
}
|
}
|
|
.popup-content {
|
background-color: white;
|
border-top-left-radius: 20rpx;
|
border-top-right-radius: 20rpx;
|
padding: 30rpx;
|
max-height: 80vh;
|
|
.popup-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 30rpx;
|
padding-bottom: 20rpx;
|
border-bottom: 1rpx solid #f0f0f0;
|
|
.header-title {
|
font-size: 36rpx;
|
font-weight: bold;
|
color: #333;
|
}
|
|
.close-btn {
|
padding: 10rpx;
|
}
|
}
|
|
.simple-fee-section {
|
padding: 20rpx 0;
|
border-bottom: 1rpx solid #f0f0f0;
|
margin-bottom: 20rpx;
|
|
.form-item {
|
margin-bottom: 30rpx;
|
|
&:last-child {
|
margin-bottom: 0;
|
}
|
|
.form-label {
|
font-size: 28rpx;
|
margin-bottom: 15rpx;
|
color: #333;
|
}
|
|
.form-input {
|
height: 70rpx;
|
padding: 0 20rpx;
|
border: 1rpx solid #eee;
|
border-radius: 10rpx;
|
font-size: 28rpx;
|
|
&.picker-input {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
}
|
}
|
}
|
|
.add-fee-btn {
|
margin-top: 20rpx;
|
|
.confirm-btn {
|
width: 100%;
|
height: 70rpx;
|
background-color: #007AFF;
|
color: white;
|
border-radius: 10rpx;
|
font-size: 28rpx;
|
}
|
}
|
}
|
|
.added-fees-list {
|
margin-bottom: 30rpx;
|
|
.section-title {
|
font-size: 32rpx;
|
font-weight: bold;
|
margin-bottom: 20rpx;
|
color: #333;
|
}
|
|
.fee-item {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 20rpx 0;
|
border-bottom: 1rpx solid #f0f0f0;
|
|
&:last-child {
|
border-bottom: none;
|
}
|
|
.fee-info {
|
flex: 1;
|
.fee-name {
|
font-size: 28rpx;
|
color: #333;
|
margin-bottom: 10rpx;
|
}
|
|
.fee-price {
|
font-size: 26rpx;
|
color: #666;
|
}
|
}
|
|
.fee-actions {
|
display: flex;
|
align-items: center;
|
gap: 20rpx;
|
}
|
|
.fee-total {
|
font-size: 28rpx;
|
font-weight: bold;
|
color: #e54d42;
|
}
|
|
.delete-btn {
|
padding: 10rpx;
|
}
|
}
|
}
|
|
.popup-footer {
|
.confirm-btn {
|
width: 100%;
|
height: 80rpx;
|
background-color: #007AFF;
|
color: white;
|
border-radius: 10rpx;
|
font-size: 32rpx;
|
}
|
}
|
}
|
</style>
|