This commit is contained in:
parent
a8de74cfd4
commit
9ad01ccce2
|
|
@ -79,5 +79,25 @@ export default {
|
|||
*/
|
||||
terminate(id, data) {
|
||||
return post(`/rentals/${id}/terminate`, data)
|
||||
},
|
||||
|
||||
/**
|
||||
* 办理续租
|
||||
* @param {number} id - 租赁记录ID
|
||||
* @param {Object} data - 续租数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
renew(id, data) {
|
||||
return post(`/rentals/${id}/renew`, data)
|
||||
},
|
||||
|
||||
/**
|
||||
* 办理换房
|
||||
* @param {number} id - 租赁记录ID
|
||||
* @param {Object} data - 换房数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
changeRoom(id, data) {
|
||||
return post(`/rentals/${id}/change-room`, data)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
pages.json
12
pages.json
|
|
@ -108,6 +108,18 @@
|
|||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/rental-renew/rental-renew",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/rental-change-room/rental-change-room",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/rental-add/rental-add",
|
||||
"style": {
|
||||
|
|
|
|||
|
|
@ -72,17 +72,21 @@
|
|||
<view class="section-title">费用明细</view>
|
||||
<view class="price-list">
|
||||
<view class="price-row">
|
||||
<text class="row-label">套餐单价</text>
|
||||
<text class="row-value">¥{{order.unitPrice || order.subscriptionPlan?.monthlyPrice || 0}}/月</text>
|
||||
<text class="row-label">套餐价格</text>
|
||||
<text class="row-value">{{orderPriceText}}</text>
|
||||
</view>
|
||||
<view class="price-row">
|
||||
<text class="row-label">购买时长</text>
|
||||
<text class="row-value">{{order.months}} 个月</text>
|
||||
</view>
|
||||
<view class="price-row">
|
||||
<text class="row-label">基础费用</text>
|
||||
<text class="row-label">订阅费用</text>
|
||||
<text class="row-value">¥{{order.amount}}</text>
|
||||
</view>
|
||||
<view class="price-row" v-if="order.billingCycle">
|
||||
<text class="row-label">计费周期</text>
|
||||
<text class="row-value">{{billingCycleText}}</text>
|
||||
</view>
|
||||
<view class="price-row" v-if="order.discountAmount > 0">
|
||||
<text class="row-label">优惠金额</text>
|
||||
<text class="row-value discount">-¥{{order.discountAmount}}</text>
|
||||
|
|
@ -133,7 +137,7 @@
|
|||
<!-- 底部操作栏 -->
|
||||
<view class="bottom-bar safe-area-bottom" v-if="order && order.status === 'pending'">
|
||||
<button class="action-btn cancel" @click="cancelOrder">取消订单</button>
|
||||
<button class="action-btn pay" @click="payOrder">立即支付</button>
|
||||
<button class="action-btn pay" @click="showPaymentInfo">付款说明</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
|
@ -167,11 +171,26 @@
|
|||
},
|
||||
statusDesc() {
|
||||
const map = {
|
||||
pending: '请在24小时内完成支付,否则订单将自动取消',
|
||||
pending: '请按平台收款信息付款,管理员确认后套餐生效',
|
||||
paid: '订单已支付成功,套餐已生效',
|
||||
cancelled: '订单已取消,如有疑问请联系客服'
|
||||
}
|
||||
return map[this.order?.status] || ''
|
||||
},
|
||||
orderPriceText() {
|
||||
if (!this.order) return '¥0/月'
|
||||
if (this.order.billingCycle === 'yearly' && this.order.subscriptionPlan?.yearlyPrice) {
|
||||
return `¥${this.order.subscriptionPlan.yearlyPrice}/年`
|
||||
}
|
||||
return `¥${this.order.unitPrice || this.order.subscriptionPlan?.monthlyPrice || 0}/月`
|
||||
},
|
||||
billingCycleText() {
|
||||
const map = {
|
||||
monthly: '月付',
|
||||
yearly: '年付',
|
||||
custom: '自定义周期'
|
||||
}
|
||||
return map[this.order?.billingCycle] || this.order?.billingCycle || '-'
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
|
|
@ -246,34 +265,12 @@
|
|||
})
|
||||
},
|
||||
|
||||
payOrder() {
|
||||
showPaymentInfo() {
|
||||
uni.showModal({
|
||||
title: '支付确认',
|
||||
content: `确认支付订单 #${this.order.orderNo},金额 ¥${this.order.actualAmount}?`,
|
||||
success: async (res) => {
|
||||
if (res.confirm) {
|
||||
try {
|
||||
uni.showLoading({ title: '支付中...' })
|
||||
const result = await billingApi.payOrder(this.orderId)
|
||||
uni.hideLoading()
|
||||
|
||||
if (result.code === 200) {
|
||||
uni.showToast({
|
||||
title: '支付成功',
|
||||
icon: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
this.loadOrderDetail()
|
||||
} else {
|
||||
uni.showToast({ title: result.message || '支付失败', icon: 'none' })
|
||||
}
|
||||
} catch (error) {
|
||||
uni.hideLoading()
|
||||
console.error('支付失败:', error)
|
||||
uni.showToast({ title: '支付失败', icon: 'none' })
|
||||
}
|
||||
}
|
||||
}
|
||||
title: '付款说明',
|
||||
content: `订单 #${this.order.orderNo}\n应付金额:¥${this.order.actualAmount}\n请按平台收款信息完成转账,管理员确认后套餐自动生效。`,
|
||||
showCancel: false,
|
||||
confirmText: '我知道了'
|
||||
})
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<view class="order-footer" v-if="order.status === 'pending'">
|
||||
<button class="action-btn cancel" @click.stop="cancelOrder(order)">取消订单</button>
|
||||
<button class="action-btn pay" @click.stop="payOrder(order)">去支付</button>
|
||||
<button class="action-btn pay" @click.stop="showPaymentInfo(order)">付款说明</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
|
@ -223,33 +223,12 @@
|
|||
})
|
||||
},
|
||||
|
||||
async payOrder(order) {
|
||||
showPaymentInfo(order) {
|
||||
uni.showModal({
|
||||
title: '支付确认',
|
||||
content: `确认支付订单 #${order.orderNo},金额 ¥${order.actualAmount}?`,
|
||||
success: async (res) => {
|
||||
if (res.confirm) {
|
||||
uni.showLoading({ title: '支付中...' })
|
||||
try {
|
||||
const result = await billingApi.payOrder(order.id)
|
||||
uni.hideLoading()
|
||||
if (result.code === 200) {
|
||||
uni.showToast({
|
||||
title: '支付成功',
|
||||
icon: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
this.refreshData()
|
||||
} else {
|
||||
uni.showToast({ title: result.message || '支付失败', icon: 'none' })
|
||||
}
|
||||
} catch (error) {
|
||||
uni.hideLoading()
|
||||
console.error('支付失败:', error)
|
||||
uni.showToast({ title: '支付失败', icon: 'none' })
|
||||
}
|
||||
}
|
||||
}
|
||||
title: '付款说明',
|
||||
content: `订单 #${order.orderNo}\n应付金额:¥${order.actualAmount}\n请按平台收款信息完成转账,管理员确认后套餐自动生效。`,
|
||||
showCancel: false,
|
||||
confirmText: '我知道了'
|
||||
})
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
<view class="plan-price">
|
||||
<text class="price">¥{{plan.monthlyPrice}}</text>
|
||||
<text class="unit">/月</text>
|
||||
<text v-if="plan.yearlyPrice" class="yearly-price">¥{{plan.yearlyPrice}}/年</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
|
@ -76,20 +77,20 @@
|
|||
<view class="section-title">费用明细</view>
|
||||
<view class="price-list">
|
||||
<view class="price-row">
|
||||
<text class="row-label">套餐单价</text>
|
||||
<text class="row-value">¥{{selectedPlan?.monthlyPrice || 0}}/月</text>
|
||||
<text class="row-label">套餐价格</text>
|
||||
<text class="row-value">{{selectedPriceText}}</text>
|
||||
</view>
|
||||
<view class="price-row">
|
||||
<text class="row-label">购买时长</text>
|
||||
<text class="row-value">{{selectedMonths}} 个月</text>
|
||||
</view>
|
||||
<view class="price-row">
|
||||
<text class="row-label">基础费用</text>
|
||||
<text class="row-label">订阅费用</text>
|
||||
<text class="row-value">¥{{baseAmount}}</text>
|
||||
</view>
|
||||
<view class="price-row" v-if="discountAmount > 0">
|
||||
<text class="row-label">优惠金额</text>
|
||||
<text class="row-value discount">-¥{{discountAmount}}</text>
|
||||
<view class="price-row" v-if="billingCycle">
|
||||
<text class="row-label">计费周期</text>
|
||||
<text class="row-value">{{billingCycleText}}</text>
|
||||
</view>
|
||||
<view class="price-row total">
|
||||
<text class="row-label">合计</text>
|
||||
|
|
@ -165,20 +166,36 @@
|
|||
selectedMonths: 1,
|
||||
periods: [
|
||||
{ label: '1个月', value: 1, discount: 0 },
|
||||
{ label: '3个月', value: 3, discount: 5 },
|
||||
{ label: '6个月', value: 6, discount: 10 },
|
||||
{ label: '12个月', value: 12, discount: 15 }
|
||||
{ label: '3个月', value: 3, discount: 0 },
|
||||
{ label: '6个月', value: 6, discount: 0 },
|
||||
{ label: '12个月', value: 12, discount: 0 }
|
||||
],
|
||||
paymentSettings: null,
|
||||
submitting: false,
|
||||
baseAmount: 0,
|
||||
discountAmount: 0,
|
||||
totalAmount: 0
|
||||
totalAmount: 0,
|
||||
billingCycle: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
selectedPlan() {
|
||||
return this.plans.find(p => p.id === this.selectedPlanId)
|
||||
},
|
||||
selectedPriceText() {
|
||||
if (!this.selectedPlan) return '¥0/月'
|
||||
if (this.selectedMonths === 12 && Number(this.selectedPlan.yearlyPrice) > 0) {
|
||||
return `¥${this.selectedPlan.yearlyPrice}/年`
|
||||
}
|
||||
return `¥${this.selectedPlan.monthlyPrice}/月`
|
||||
},
|
||||
billingCycleText() {
|
||||
const map = {
|
||||
monthly: '月付',
|
||||
yearly: '年付',
|
||||
custom: '自定义周期'
|
||||
}
|
||||
return map[this.billingCycle] || this.billingCycle
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
|
@ -198,8 +215,8 @@
|
|||
try {
|
||||
const res = await billingApi.getPlans()
|
||||
if (res.code === 200) {
|
||||
// 过滤掉免费版(monthlyPrice <= 0)和未启用的套餐
|
||||
this.plans = (res.data || []).filter(p => p.status === 'active' && p.monthlyPrice > 0)
|
||||
// 过滤掉免费版和未启用的套餐
|
||||
this.plans = (res.data || []).filter(p => p.status === 'active' && (Number(p.monthlyPrice) > 0 || Number(p.yearlyPrice) > 0))
|
||||
// 如果有推荐套餐,默认选中
|
||||
const recommended = this.plans.find(p => p.isRecommended)
|
||||
if (recommended) {
|
||||
|
|
@ -233,25 +250,29 @@
|
|||
this.selectedMonths = months
|
||||
},
|
||||
|
||||
calculatePrice() {
|
||||
async calculatePrice() {
|
||||
if (!this.selectedPlan) {
|
||||
this.baseAmount = 0
|
||||
this.discountAmount = 0
|
||||
this.totalAmount = 0
|
||||
this.billingCycle = ''
|
||||
return
|
||||
}
|
||||
|
||||
const monthlyPrice = this.selectedPlan.monthlyPrice
|
||||
const baseAmount = monthlyPrice * this.selectedMonths
|
||||
|
||||
// 计算折扣
|
||||
const period = this.periods.find(p => p.value === this.selectedMonths)
|
||||
const discountRate = period ? period.discount / 100 : 0
|
||||
const discountAmount = Math.round(baseAmount * discountRate)
|
||||
|
||||
this.baseAmount = baseAmount
|
||||
this.discountAmount = discountAmount
|
||||
this.totalAmount = baseAmount - discountAmount
|
||||
try {
|
||||
const res = await billingApi.calculatePrice({
|
||||
planId: this.selectedPlanId,
|
||||
months: this.selectedMonths
|
||||
})
|
||||
if (res.code === 200 && res.data) {
|
||||
this.baseAmount = res.data.baseAmount || 0
|
||||
this.discountAmount = res.data.discountAmount || 0
|
||||
this.totalAmount = res.data.totalAmount || 0
|
||||
this.billingCycle = res.data.billingCycle || ''
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('计算价格失败:', error)
|
||||
uni.showToast({ title: '计算价格失败', icon: 'none' })
|
||||
}
|
||||
},
|
||||
|
||||
async createOrder() {
|
||||
|
|
@ -431,6 +452,13 @@
|
|||
color: #94A3B8;
|
||||
}
|
||||
|
||||
.yearly-price {
|
||||
display: block;
|
||||
margin-top: 6rpx;
|
||||
font-size: 22rpx;
|
||||
color: #64748B;
|
||||
}
|
||||
|
||||
.plan-features {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
|
|||
|
|
@ -134,6 +134,10 @@
|
|||
<uni-icons type="refresh-filled" size="20" color="#FFFFFF"></uni-icons>
|
||||
<text>办理续租</text>
|
||||
</view>
|
||||
<view class="action-btn warning" @click="handleChangeRoom">
|
||||
<uni-icons type="home-filled" size="20" color="#FFFFFF"></uni-icons>
|
||||
<text>办理换房</text>
|
||||
</view>
|
||||
<view class="action-btn danger" @click="handleTerminate">
|
||||
<uni-icons type="closeempty" size="20" color="#FFFFFF"></uni-icons>
|
||||
<text>办理退租</text>
|
||||
|
|
@ -367,6 +371,12 @@
|
|||
})
|
||||
},
|
||||
|
||||
handleChangeRoom() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/rental-change-room/rental-change-room?id=${this.rentalId}`
|
||||
})
|
||||
},
|
||||
|
||||
handleTerminate() {
|
||||
this.terminateForm = {
|
||||
waterMeterEnd: '',
|
||||
|
|
@ -757,6 +767,11 @@
|
|||
box-shadow: 0 8rpx 24rpx rgba(37, 99, 235, 0.3);
|
||||
}
|
||||
|
||||
.action-btn.warning {
|
||||
background: linear-gradient(135deg, #F59E0B 0%, #D97706 100%);
|
||||
box-shadow: 0 8rpx 24rpx rgba(245, 158, 11, 0.28);
|
||||
}
|
||||
|
||||
.action-btn.danger {
|
||||
background: linear-gradient(135deg, #EF4444 0%, #DC2626 100%);
|
||||
box-shadow: 0 8rpx 24rpx rgba(239, 68, 68, 0.3);
|
||||
|
|
|
|||
Loading…
Reference in New Issue