NewJsiteServer.vue由弹窗改为普通页面展示
This commit is contained in:
parent
3f32f38963
commit
ea2bc6cecf
@ -1,122 +1,152 @@
|
|||||||
<template>
|
<template>
|
||||||
<Dialog :options="{ title: '新建服务器', size: 'lg' }" v-model="show">
|
<div>
|
||||||
<!-- 第一步:选择服务器配置和支付方式 -->
|
<!-- 页面头部 -->
|
||||||
<template v-if="!showPaymentProcessing" #body-content>
|
<div class="sticky top-0 z-10 shrink-0">
|
||||||
<div class="p-4 sm:p-6">
|
<Header>
|
||||||
|
<Breadcrumbs
|
||||||
|
:items="[
|
||||||
|
{ label: '服务器', route: '/jsite-servers' },
|
||||||
|
{ label: '新建服务器', route: '/jsite-servers/new' }
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</Header>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 主要内容区域 -->
|
||||||
|
<div class="mx-auto max-w-2xl px-5">
|
||||||
|
<!-- 第一步:选择服务器配置和支付方式 -->
|
||||||
|
<div v-if="!showPaymentProcessing" class="space-y-12 pb-[50vh] pt-12">
|
||||||
<div class="mb-6">
|
<div class="mb-6">
|
||||||
<p class="mt-1 text-sm text-gray-600">
|
<h1 class="text-2xl font-bold text-gray-900 mb-2">新建服务器</h1>
|
||||||
|
<p class="text-sm text-gray-600">
|
||||||
请选择服务器配置和支付方式,点击"创建"后将自动为您开通。
|
请选择服务器配置和支付方式,点击"创建"后将自动为您开通。
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
|
||||||
<label class="block text-sm font-medium text-gray-700 mb-2">区域选择</label>
|
|
||||||
<select v-model="selectedRegionId" class="w-full border rounded px-3 py-2" required @change="onRegionChange">
|
|
||||||
<option value="">请选择区域</option>
|
|
||||||
<option v-for="region in regions" :key="getRegionId(region)" :value="getRegionId(region)">
|
|
||||||
{{ getRegionName(region) }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
<!-- 调试信息 -->
|
|
||||||
<div v-if="regions.length === 0" class="mt-2 text-sm text-gray-500">
|
|
||||||
正在加载区域列表...
|
|
||||||
</div>
|
|
||||||
<div v-if="regions.length > 0" class="mt-2 text-sm text-gray-500">
|
|
||||||
已加载 {{ regions.length }} 个区域
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="mb-4">
|
|
||||||
<label class="block text-sm font-medium text-gray-700 mb-2">套餐选择</label>
|
|
||||||
<select v-model="selectedPlanId" class="w-full border rounded px-3 py-2" required>
|
|
||||||
<option value="">请选择套餐</option>
|
|
||||||
<option v-for="plan in plans" :key="plan.plan_id" :value="plan.plan_id">
|
|
||||||
{{ getPlanDisplayName(plan) }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="mb-4">
|
|
||||||
<label class="block text-sm font-medium text-gray-700 mb-2">镜像选择</label>
|
|
||||||
<select v-model="selectedImageId" class="w-full border rounded px-3 py-2" required>
|
|
||||||
<option value="">请选择镜像</option>
|
|
||||||
<option v-for="image in images" :key="getImageId(image)" :value="getImageId(image)">
|
|
||||||
{{ getImageDisplayName(image) }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="mb-4">
|
|
||||||
<label class="block text-sm font-medium text-gray-700 mb-2">购买时长</label>
|
|
||||||
<select v-model="period" class="w-full border rounded px-3 py-2">
|
|
||||||
<option v-for="p in periods" :key="p.value" :value="p.value">{{ p.label }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 价格信息显示 -->
|
<div class="space-y-6">
|
||||||
<div v-if="selectedPlanId && selectedImageId" class="mb-6 border-t border-gray-200 pt-4">
|
<div>
|
||||||
<div class="flex justify-between items-center">
|
<label class="block text-sm font-medium text-gray-700 mb-2">区域选择</label>
|
||||||
<div class="text-sm text-gray-600">月度费用</div>
|
<select v-model="selectedRegionId" class="w-full border rounded px-3 py-2" required @change="onRegionChange">
|
||||||
<div class="font-medium">
|
<option value="">请选择区域</option>
|
||||||
¥ {{ getSelectedPlanPrice() }}
|
<option v-for="region in regions" :key="getRegionId(region)" :value="getRegionId(region)">
|
||||||
<span class="text-gray-500 text-sm">(月付)</span>
|
{{ getRegionName(region) }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
<!-- 调试信息 -->
|
||||||
|
<div v-if="regions.length === 0" class="mt-2 text-sm text-gray-500">
|
||||||
|
正在加载区域列表...
|
||||||
|
</div>
|
||||||
|
<div v-if="regions.length > 0" class="mt-2 text-sm text-gray-500">
|
||||||
|
已加载 {{ regions.length }} 个区域
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between items-center mt-2">
|
|
||||||
<div class="text-sm text-gray-600">购买时长</div>
|
|
||||||
<div class="font-medium">{{ period }} 个月</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex justify-between items-center mt-2 text-lg font-bold">
|
|
||||||
<div>总计</div>
|
|
||||||
<div>¥ {{ getTotalAmount() }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 支付方式选择 -->
|
<div>
|
||||||
<div class="mb-6 border-t border-gray-200 pt-4">
|
<label class="block text-sm font-medium text-gray-700 mb-2">套餐选择</label>
|
||||||
<label class="block text-sm font-medium text-gray-700 mb-3">
|
<select v-model="selectedPlanId" class="w-full border rounded px-3 py-2" required>
|
||||||
选择支付方式
|
<option value="">请选择套餐</option>
|
||||||
</label>
|
<option v-for="plan in plans" :key="plan.plan_id" :value="plan.plan_id">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-2">
|
{{ getPlanDisplayName(plan) }}
|
||||||
<button
|
</option>
|
||||||
class="p-4 border rounded-lg flex flex-col items-center justify-center hover:bg-gray-50 transition-all"
|
</select>
|
||||||
:class="{'border-blue-500 border-2 shadow-sm': selectedPaymentMethod === 'balance', 'border-gray-200': selectedPaymentMethod !== 'balance'}"
|
</div>
|
||||||
@click="selectedPaymentMethod = 'balance'"
|
|
||||||
>
|
|
||||||
<span class="text-gray-800 font-medium">余额支付</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
<div>
|
||||||
class="p-4 border rounded-lg hover:bg-gray-50 transition-all"
|
<label class="block text-sm font-medium text-gray-700 mb-2">镜像选择</label>
|
||||||
:class="{'border-blue-500 border-2 shadow-sm': selectedPaymentMethod === 'alipay', 'border-gray-200': selectedPaymentMethod !== 'alipay'}"
|
<select v-model="selectedImageId" class="w-full border rounded px-3 py-2" required>
|
||||||
@click="selectedPaymentMethod = 'alipay'"
|
<option value="">请选择镜像</option>
|
||||||
>
|
<option v-for="image in images" :key="getImageId(image)" :value="getImageId(image)">
|
||||||
<div class="flex flex-col items-center">
|
{{ getImageDisplayName(image) }}
|
||||||
<div class="mb-2">
|
</option>
|
||||||
<AlipayLogo class="h-8" />
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-2">购买时长</label>
|
||||||
|
<select v-model="period" class="w-full border rounded px-3 py-2">
|
||||||
|
<option v-for="p in periods" :key="p.value" :value="p.value">{{ p.label }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 价格信息显示 -->
|
||||||
|
<div v-if="selectedPlanId && selectedImageId" class="border-t border-gray-200 pt-4">
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<div class="text-sm text-gray-600">月度费用</div>
|
||||||
|
<div class="font-medium">
|
||||||
|
¥ {{ getSelectedPlanPrice() }}
|
||||||
|
<span class="text-gray-500 text-sm">(月付)</span>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</div>
|
||||||
|
<div class="flex justify-between items-center mt-2">
|
||||||
|
<div class="text-sm text-gray-600">购买时长</div>
|
||||||
|
<div class="font-medium">{{ period }} 个月</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between items-center mt-2 text-lg font-bold">
|
||||||
|
<div>总计</div>
|
||||||
|
<div>¥ {{ getTotalAmount() }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button
|
<!-- 支付方式选择 -->
|
||||||
class="p-4 border rounded-lg hover:bg-gray-50 transition-all"
|
<div class="border-t border-gray-200 pt-4">
|
||||||
:class="{'border-blue-500 border-2 shadow-sm': selectedPaymentMethod === 'wechatpay', 'border-gray-200': selectedPaymentMethod !== 'wechatpay'}"
|
<label class="block text-sm font-medium text-gray-700 mb-3">
|
||||||
@click="selectedPaymentMethod = 'wechatpay'"
|
选择支付方式
|
||||||
>
|
</label>
|
||||||
<div class="flex flex-col items-center">
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-2">
|
||||||
<div class="mb-2">
|
<button
|
||||||
<WeChatPayLogo class="h-8" />
|
class="p-4 border rounded-lg flex flex-col items-center justify-center hover:bg-gray-50 transition-all"
|
||||||
|
:class="{'border-blue-500 border-2 shadow-sm': selectedPaymentMethod === 'balance', 'border-gray-200': selectedPaymentMethod !== 'balance'}"
|
||||||
|
@click="selectedPaymentMethod = 'balance'"
|
||||||
|
>
|
||||||
|
<span class="text-gray-800 font-medium">余额支付</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="p-4 border rounded-lg hover:bg-gray-50 transition-all"
|
||||||
|
:class="{'border-blue-500 border-2 shadow-sm': selectedPaymentMethod === 'alipay', 'border-gray-200': selectedPaymentMethod !== 'alipay'}"
|
||||||
|
@click="selectedPaymentMethod = 'alipay'"
|
||||||
|
>
|
||||||
|
<div class="flex flex-col items-center">
|
||||||
|
<div class="mb-2">
|
||||||
|
<AlipayLogo class="h-8" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="p-4 border rounded-lg hover:bg-gray-50 transition-all"
|
||||||
|
:class="{'border-blue-500 border-2 shadow-sm': selectedPaymentMethod === 'wechatpay', 'border-gray-200': selectedPaymentMethod !== 'wechatpay'}"
|
||||||
|
@click="selectedPaymentMethod = 'wechatpay'"
|
||||||
|
>
|
||||||
|
<div class="flex flex-col items-center">
|
||||||
|
<div class="mb-2">
|
||||||
|
<WeChatPayLogo class="h-8" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="error" class="p-3 bg-red-50 text-red-700 rounded-md text-sm">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 创建按钮 -->
|
||||||
|
<div class="pt-4">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="w-full px-4 py-2 bg-[#1fc76f] border border-transparent rounded-md text-sm font-medium text-white hover:bg-[#19b862] focus:outline-none"
|
||||||
|
@click="createInstance"
|
||||||
|
:disabled="isLoading"
|
||||||
|
>
|
||||||
|
{{ isLoading ? '处理中...' : '创建' }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="error" class="mt-4 p-3 bg-red-50 text-red-700 rounded-md text-sm">
|
|
||||||
{{ error }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- 第二步:处理支付 -->
|
<!-- 第二步:处理支付 -->
|
||||||
<template v-else #body-content>
|
<div v-else class="space-y-12 pb-[50vh] pt-12">
|
||||||
<div class="p-4 sm:p-6">
|
|
||||||
<!-- 加载中状态 -->
|
<!-- 加载中状态 -->
|
||||||
<div v-if="isProcessingPayment" class="text-center py-8">
|
<div v-if="isProcessingPayment" class="text-center py-8">
|
||||||
<div class="h-12 w-12 mx-auto animate-spin text-blue-600 mb-4 flex items-center justify-center">
|
<div class="h-12 w-12 mx-auto animate-spin text-blue-600 mb-4 flex items-center justify-center">
|
||||||
@ -141,6 +171,15 @@
|
|||||||
<p class="text-gray-500 text-sm">
|
<p class="text-gray-500 text-sm">
|
||||||
您可以在服务器列表中查看服务器状态,创建完成后状态将更新为"Running"。
|
您可以在服务器列表中查看服务器状态,创建完成后状态将更新为"Running"。
|
||||||
</p>
|
</p>
|
||||||
|
<div class="mt-6">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="px-4 py-2 bg-[#1fc76f] border border-transparent rounded-md text-sm font-medium text-white hover:bg-[#19b862] focus:outline-none"
|
||||||
|
@click="goToServerList"
|
||||||
|
>
|
||||||
|
返回服务器列表
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 微信支付状态 -->
|
<!-- 微信支付状态 -->
|
||||||
@ -197,55 +236,29 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="error" class="mt-4 p-3 bg-red-50 text-red-700 rounded-md text-sm">
|
<div v-if="error" class="p-3 bg-red-50 text-red-700 rounded-md text-sm">
|
||||||
{{ error }}
|
{{ error }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</div>
|
||||||
|
</div>
|
||||||
<template #actions>
|
|
||||||
<div class="w-full">
|
|
||||||
<button v-if="!showPaymentProcessing && !paymentSuccess"
|
|
||||||
type="button"
|
|
||||||
class="w-full px-4 py-2 bg-[#1fc76f] border border-transparent rounded-md text-sm font-medium text-white hover:bg-[#19b862] focus:outline-none"
|
|
||||||
@click="createInstance"
|
|
||||||
:disabled="isLoading"
|
|
||||||
>
|
|
||||||
{{ isLoading ? '处理中...' : '创建' }}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div class="flex justify-between w-full" v-else>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="px-4 py-2 bg-[#1fc76f] border border-transparent rounded-md text-sm font-medium text-white hover:bg-[#19b862] focus:outline-none ml-auto"
|
|
||||||
@click="close"
|
|
||||||
v-if="paymentSuccess"
|
|
||||||
>
|
|
||||||
关闭
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</Dialog>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { toast } from 'vue-sonner';
|
import { toast } from 'vue-sonner';
|
||||||
import { Dialog } from 'jingrow-ui';
|
|
||||||
import { DashboardError } from '../utils/error';
|
import { DashboardError } from '../utils/error';
|
||||||
import AlipayLogo from '../logo/AlipayLogo.vue';
|
import AlipayLogo from '../logo/AlipayLogo.vue';
|
||||||
import WeChatPayLogo from '../logo/WeChatPayLogo.vue';
|
import WeChatPayLogo from '../logo/WeChatPayLogo.vue';
|
||||||
|
import router from '../router';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'NewJsiteServer',
|
name: 'NewJsiteServer',
|
||||||
components: {
|
components: {
|
||||||
Dialog,
|
|
||||||
AlipayLogo,
|
AlipayLogo,
|
||||||
WeChatPayLogo
|
WeChatPayLogo
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
show: true,
|
|
||||||
selectedRegionId: '',
|
selectedRegionId: '',
|
||||||
selectedPlanId: '',
|
selectedPlanId: '',
|
||||||
selectedImageId: '',
|
selectedImageId: '',
|
||||||
@ -424,10 +437,13 @@ export default {
|
|||||||
...this.server
|
...this.server
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$emit('success', { order: orderData, server: serverData });
|
|
||||||
|
|
||||||
this.isProcessingPayment = false;
|
this.isProcessingPayment = false;
|
||||||
this.paymentSuccess = true;
|
this.paymentSuccess = true;
|
||||||
|
|
||||||
|
// 支付成功后跳转到服务器列表
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$router.push('/jsite-servers');
|
||||||
|
}, 2000);
|
||||||
},
|
},
|
||||||
onError(error) {
|
onError(error) {
|
||||||
this.error = error.message || '余额支付处理失败';
|
this.error = error.message || '余额支付处理失败';
|
||||||
@ -505,9 +521,12 @@ export default {
|
|||||||
...this.server
|
...this.server
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$emit('success', { order: orderData, server: serverData });
|
|
||||||
|
|
||||||
this.paymentSuccess = true;
|
this.paymentSuccess = true;
|
||||||
|
|
||||||
|
// 支付成功后跳转到服务器列表
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$router.push('/jsite-servers');
|
||||||
|
}, 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -600,12 +619,10 @@ export default {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
goToServerList() {
|
||||||
|
this.$router.push('/jsite-servers');
|
||||||
close() {
|
|
||||||
this.show = false;
|
|
||||||
this.$emit('success');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getRegionId(region) {
|
getRegionId(region) {
|
||||||
return region.region_id || region.RegionId || region.id;
|
return region.region_id || region.RegionId || region.id;
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user