feat: 完善订单定价与支付收益管理
Build and Deploy Vue3 / build (push) Successful in 1m44s
Build and Deploy Vue3 / deploy (push) Successful in 47s

This commit is contained in:
shiran
2026-07-20 18:33:46 +08:00
parent afc00141f7
commit c5d4dbc0db
11 changed files with 1600 additions and 98 deletions
+26 -2
View File
@@ -258,6 +258,16 @@
<el-form-item v-if="renewForm.complete_pay" label="扣除用户余额">
<el-switch v-model="renewForm.deduct_balance" />
</el-form-item>
<el-form-item v-if="renewForm.complete_pay" label="收益入账">
<div class="account-amount-field">
<el-switch
v-model="renewForm.account_amount"
active-text="计入 007pay"
inactive-text="不计入"
/>
<div class="form-tip">仅记录 007pay 手工入账不等同于扣除用户余额</div>
</div>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="renewVisible = false">取消</el-button>
@@ -346,8 +356,10 @@ const formatExpireTime = (t) => {
}
const expireLabel = computed(() => formatExpireTime(detail.value?.expireTime || detail.value?.expire_time))
const isPending = computed(() => String(detail.value?.status || detail.value?.Status || '').toLowerCase() === 'pending')
const expireStatusText = computed(() => {
if (isPending.value) return '待开通'
const t = detail.value?.expireTime || detail.value?.expire_time
if (!t) return '未知'
const d = dayjs(t)
@@ -359,6 +371,7 @@ const expireStatusText = computed(() => {
})
const expireStatusClass = computed(() => {
if (isPending.value) return 'status-pending'
const t = detail.value?.expireTime || detail.value?.expire_time
if (!t) return ''
const d = dayjs(t)
@@ -452,14 +465,14 @@ const goToOrder = () => {
// ---- 续费 ----
const renewVisible = ref(false)
const renewLoading = ref(false)
const renewForm = reactive({ purchase_duration: 1, renew_price: 0, complete_pay: false, deduct_balance: false })
const renewForm = reactive({ purchase_duration: 1, renew_price: 0, complete_pay: false, deduct_balance: false, account_amount: false })
const renewTotalPrice = computed(() => {
const price = renewForm.renew_price || (detail.value?.renewPrice || detail.value?.renew_price || 0) / 100
return (price * renewForm.purchase_duration).toFixed(2)
})
const openRenew = () => {
const rawRenew = detail.value?.renewPrice || detail.value?.renew_price || 0
Object.assign(renewForm, { purchase_duration: 1, renew_price: rawRenew / 100, complete_pay: false, deduct_balance: false })
Object.assign(renewForm, { purchase_duration: 1, renew_price: rawRenew / 100, complete_pay: false, deduct_balance: false, account_amount: false })
renewVisible.value = true
}
const handleRenew = async () => {
@@ -469,6 +482,7 @@ const handleRenew = async () => {
if (renewForm.renew_price) data.renew_price = Math.round(renewForm.renew_price * 100)
if (renewForm.complete_pay) data.complete_pay = true
if (renewForm.complete_pay && renewForm.deduct_balance) data.deduct_balance = true
if (renewForm.complete_pay && renewForm.account_amount) data.account_amount = true
const res = await renewUserGoods(data)
if (res?.data?.code === 200) {
ElMessage.success('续费成功')
@@ -547,6 +561,13 @@ onActivated(() => {
watch(goodsId, (newId, oldId) => {
if (newId && newId !== oldId) { detail.value = null; loadDetail() }
})
watch(() => renewForm.complete_pay, (completePay) => {
if (!completePay) {
renewForm.deduct_balance = false
renewForm.account_amount = false
}
})
</script>
<style scoped>
@@ -587,6 +608,7 @@ watch(goodsId, (newId, oldId) => {
}
.meta-chip.id-chip { font-family: 'SF Mono', 'Consolas', monospace; letter-spacing: 0.3px; }
.meta-chip.status-ok { color: #52c41a; border-color: #b7eb8f; background: #f6ffed; }
.meta-chip.status-pending { color: #606266; border-color: #dcdfe6; background: #f4f4f5; }
.meta-chip.status-warning { color: #fa8c16; border-color: #ffd591; background: #fff7e6; }
.meta-chip.status-expired { color: #f5222d; border-color: #ffa39e; background: #fff1f0; }
.meta-chip.status-forever { color: #722ed1; border-color: #d3adf7; background: #f9f0ff; }
@@ -654,6 +676,8 @@ watch(goodsId, (newId, oldId) => {
.selector-row { display: flex; align-items: center; width: 100%; }
.unit-input-row { display: flex; align-items: center; gap: 6px; width: 100%; }
.unit-text { font-size: 13px; color: #606266; flex-shrink: 0; white-space: nowrap; }
.account-amount-field { display: flex; flex-direction: column; gap: 4px; }
.form-tip { font-size: 12px; color: #909399; margin-top: 4px; line-height: 1.4; }
:deep(.el-descriptions__label) { font-weight: 500; color: #606266; }
</style>
+2 -1
View File
@@ -140,8 +140,8 @@
<el-tooltip v-if="isDeleted(row)" :content="`删除于 ${formatTime(row.deleteAt || row.DeleteAt || row.deleted_at)}`" placement="top">
<el-tag size="small" type="danger">已删除</el-tag>
</el-tooltip>
<el-tag v-else-if="isPending(row)" size="small" type="info">待开通</el-tag>
<el-tag v-else-if="isExpired(row)" size="small" type="warning">已到期</el-tag>
<el-tag v-else-if="row.status === 'pending'" size="small" type="info">待开通</el-tag>
<el-tag v-else size="small" type="success">正常</el-tag>
</template>
</el-table-column>
@@ -559,6 +559,7 @@ const formatExpireTime = (t) => {
// deleteAt
const isDeleted = (row) => !!(row?.deleteAt || row?.DeleteAt || row?.deleted_at)
const isPending = (row) => String(row?.status || row?.Status || '').toLowerCase() === 'pending'
//
const isExpired = (row) => {