feat: 用户列表代理商查询、商品续费、VNC节点access_mode、IDC信息展示、新购订单table修复
- 用户列表新增通过IDC代理商uid查询用户信息 - 用户商品详情新增续费功能(admin/good/user_goods/renew) - VNC节点管理新增access_mode和use_ssl参数 - 用户详情左栏新增IDC平台信息展示 - 新购订单选择商品后所属表不再被覆盖,固定为good Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -13,6 +13,9 @@
|
||||
<el-button plain @click="loadDetail" :loading="loading">
|
||||
<el-icon><Refresh /></el-icon> 刷新
|
||||
</el-button>
|
||||
<el-button type="success" plain @click="openRenew" :disabled="!detail || isDeleted">
|
||||
续费
|
||||
</el-button>
|
||||
<el-button type="primary" plain @click="openEdit" :disabled="!detail">
|
||||
<el-icon><Edit /></el-icon> 编辑
|
||||
</el-button>
|
||||
@@ -233,6 +236,35 @@
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- 续费弹窗 -->
|
||||
<el-dialog v-model="renewVisible" title="用户商品续费" width="480px" destroy-on-close>
|
||||
<el-form :model="renewForm" label-width="110px">
|
||||
<el-form-item label="续费月数">
|
||||
<el-input-number v-model="renewForm.purchase_duration" :min="1" :max="120" controls-position="right" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="续费单价">
|
||||
<div class="unit-input-row">
|
||||
<el-input-number v-model="renewForm.renew_price" :min="0" :precision="2" controls-position="right" style="flex:1" />
|
||||
<span class="unit-text">元</span>
|
||||
</div>
|
||||
<div style="font-size: 12px; color: #909399; margin-top: 4px">不填则使用商品默认续费价格</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="总计费用">
|
||||
<span style="font-size: 16px; font-weight: 600; color: #409eff">¥{{ renewTotalPrice }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="直接完成支付">
|
||||
<el-switch v-model="renewForm.complete_pay" />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="renewForm.complete_pay" label="扣除用户余额">
|
||||
<el-switch v-model="renewForm.deduct_balance" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="renewVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="renewLoading" @click="handleRenew">确认续费</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 编辑弹窗 -->
|
||||
<el-dialog v-model="editVisible" title="编辑用户商品" width="520px" destroy-on-close>
|
||||
<el-form :model="editForm" label-width="110px">
|
||||
@@ -289,7 +321,7 @@ import { ref, reactive, computed, onMounted, onActivated, watch } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { ArrowLeft, ArrowDown, Refresh, Edit, Delete } from '@element-plus/icons-vue'
|
||||
import { getUserGoodsDetail, updateUserGoods, deleteUserGoods } from '@/api/admin/userVm'
|
||||
import { getUserGoodsDetail, updateUserGoods, deleteUserGoods, renewUserGoods } from '@/api/admin/userVm'
|
||||
import { extractApiError } from '@/utils/kvmErrorUtil'
|
||||
import VmSelectorPopup from '@/components/admin/VmSelectorPopup.vue'
|
||||
import KvmServiceSelector from '@/components/admin/KvmServiceSelector.vue'
|
||||
@@ -417,6 +449,41 @@ const goToOrder = () => {
|
||||
router.push({ path: '/order/list', query: { order_id: oid } })
|
||||
}
|
||||
|
||||
// ---- 续费 ----
|
||||
const renewVisible = ref(false)
|
||||
const renewLoading = ref(false)
|
||||
const renewForm = reactive({ purchase_duration: 1, renew_price: 0, complete_pay: false, deduct_balance: 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 })
|
||||
renewVisible.value = true
|
||||
}
|
||||
const handleRenew = async () => {
|
||||
renewLoading.value = true
|
||||
try {
|
||||
const data = { id: goodsId.value, purchase_duration: renewForm.purchase_duration }
|
||||
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
|
||||
const res = await renewUserGoods(data)
|
||||
if (res?.data?.code === 200) {
|
||||
ElMessage.success('续费成功')
|
||||
renewVisible.value = false
|
||||
loadDetail()
|
||||
} else {
|
||||
ElMessage.error(extractApiError(res?.data, '续费失败'))
|
||||
}
|
||||
} catch (e) {
|
||||
ElMessage.error(extractApiError(e?.response?.data, '续费失败'))
|
||||
} finally {
|
||||
renewLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const editVisible = ref(false)
|
||||
const editForm = reactive({ note: '', renew_price: 0, base_price: 0, expire_time: '', item_id: 0, _serviceId: 0, _serviceName: '', _itemName: '' })
|
||||
const showVmSelector = ref(false)
|
||||
|
||||
Reference in New Issue
Block a user