优化创建支付订单时的标题和余额支付的描述
This commit is contained in:
parent
94118baf15
commit
49ec83539c
@ -8,111 +8,109 @@
|
|||||||
请选择服务器配置并填写相关信息,点击"创建"后将自动为您开通。
|
请选择服务器配置并填写相关信息,点击"创建"后将自动为您开通。
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<form @submit.prevent="createInstance">
|
<div class="mb-4">
|
||||||
<div class="mb-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-2">地域选择</label>
|
<select v-model="selectedRegionId" class="w-full border rounded px-3 py-2" required @change="onRegionChange">
|
||||||
<select v-model="selectedRegionId" class="w-full border rounded px-3 py-2" required @change="onRegionChange">
|
<option value="">请选择地域</option>
|
||||||
<option value="">请选择地域</option>
|
<option v-for="region in regions" :key="getRegionId(region)" :value="getRegionId(region)">
|
||||||
<option v-for="region in regions" :key="getRegionId(region)" :value="getRegionId(region)">
|
{{ getRegionName(region) }}
|
||||||
{{ getRegionName(region) }}
|
</option>
|
||||||
</option>
|
</select>
|
||||||
</select>
|
<!-- 调试信息 -->
|
||||||
<!-- 调试信息 -->
|
<div v-if="regions.length === 0" class="mt-2 text-sm text-gray-500">
|
||||||
<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 class="mb-4">
|
<div v-if="regions.length > 0" class="mt-2 text-sm text-gray-500">
|
||||||
<label class="block text-sm font-medium text-gray-700 mb-2">套餐选择</label>
|
已加载 {{ regions.length }} 个地域
|
||||||
<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>
|
||||||
|
</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 v-if="selectedPlanId && selectedImageId" class="mb-6 border-t border-gray-200 pt-4">
|
<div v-if="selectedPlanId && selectedImageId" class="mb-6 border-t border-gray-200 pt-4">
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<div class="text-sm text-gray-600">月度费用</div>
|
<div class="text-sm text-gray-600">月度费用</div>
|
||||||
<div class="font-medium">
|
<div class="font-medium">
|
||||||
¥ {{ getSelectedPlanPrice() }}
|
¥ {{ getSelectedPlanPrice() }}
|
||||||
<span class="text-gray-500 text-sm">(月付)</span>
|
<span class="text-gray-500 text-sm">(月付)</span>
|
||||||
|
</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 class="mb-6 border-t border-gray-200 pt-4">
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-3">
|
||||||
|
选择支付方式
|
||||||
|
</label>
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-2">
|
||||||
|
<button
|
||||||
|
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>
|
||||||
<div class="flex justify-between items-center mt-2">
|
|
||||||
<div class="text-sm text-gray-600">购买时长</div>
|
<button
|
||||||
<div class="font-medium">{{ period }} 个月</div>
|
class="p-4 border rounded-lg hover:bg-gray-50 transition-all"
|
||||||
</div>
|
:class="{'border-blue-500 border-2 shadow-sm': selectedPaymentMethod === 'wechatpay', 'border-gray-200': selectedPaymentMethod !== 'wechatpay'}"
|
||||||
<div class="flex justify-between items-center mt-2 text-lg font-bold">
|
@click="selectedPaymentMethod = 'wechatpay'"
|
||||||
<div>总计</div>
|
>
|
||||||
<div>¥ {{ getTotalAmount() }}</div>
|
<div class="flex flex-col items-center">
|
||||||
</div>
|
<div class="mb-2">
|
||||||
</div>
|
<WeChatPayLogo class="h-8" />
|
||||||
|
|
||||||
<!-- 支付方式选择 -->
|
|
||||||
<div class="mb-6 border-t border-gray-200 pt-4">
|
|
||||||
<label class="block text-sm font-medium text-gray-700 mb-3">
|
|
||||||
选择支付方式
|
|
||||||
</label>
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-2">
|
|
||||||
<button
|
|
||||||
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>
|
||||||
</button>
|
</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>
|
||||||
|
</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="mt-4 p-3 bg-red-50 text-red-700 rounded-md text-sm">
|
||||||
{{ error }}
|
{{ error }}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -419,7 +417,7 @@ export default {
|
|||||||
// 处理余额支付
|
// 处理余额支付
|
||||||
processBalancePayment() {
|
processBalancePayment() {
|
||||||
return {
|
return {
|
||||||
url: 'jcloud.api.billing.process_balance_payment_for_server_order',
|
url: 'jcloud.api.billing.process_balance_payment_for_order',
|
||||||
validate() {
|
validate() {
|
||||||
if (!this.order || !this.order.order_id) {
|
if (!this.order || !this.order.order_id) {
|
||||||
throw new DashboardError('缺少订单信息');
|
throw new DashboardError('缺少订单信息');
|
||||||
@ -452,7 +450,7 @@ export default {
|
|||||||
// 处理支付宝支付
|
// 处理支付宝支付
|
||||||
processAlipayPayment() {
|
processAlipayPayment() {
|
||||||
return {
|
return {
|
||||||
url: 'jcloud.api.billing.process_alipay_server_order',
|
url: 'jcloud.api.billing.process_alipay_order',
|
||||||
validate() {
|
validate() {
|
||||||
if (!this.order || !this.order.order_id) {
|
if (!this.order || !this.order.order_id) {
|
||||||
throw new DashboardError('缺少订单信息');
|
throw new DashboardError('缺少订单信息');
|
||||||
@ -476,7 +474,7 @@ export default {
|
|||||||
// 处理微信支付
|
// 处理微信支付
|
||||||
processWechatPayment() {
|
processWechatPayment() {
|
||||||
return {
|
return {
|
||||||
url: 'jcloud.api.billing.process_wechatpay_server_order',
|
url: 'jcloud.api.billing.process_wechatpay_order',
|
||||||
validate() {
|
validate() {
|
||||||
if (!this.order || !this.order.order_id) {
|
if (!this.order || !this.order.order_id) {
|
||||||
throw new DashboardError('缺少订单信息');
|
throw new DashboardError('缺少订单信息');
|
||||||
@ -498,7 +496,7 @@ export default {
|
|||||||
// 检查支付状态
|
// 检查支付状态
|
||||||
checkPaymentStatus() {
|
checkPaymentStatus() {
|
||||||
return {
|
return {
|
||||||
url: 'jcloud.api.billing.check_server_order_payment_status',
|
url: 'jcloud.api.billing.check_site_order_payment_status',
|
||||||
params: {
|
params: {
|
||||||
order_id: this.order?.order_id
|
order_id: this.order?.order_id
|
||||||
},
|
},
|
||||||
@ -667,6 +665,14 @@ export default {
|
|||||||
return `${name} (${platform})`;
|
return `${name} (${platform})`;
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
|
},
|
||||||
|
getPaymentMethodName(method) {
|
||||||
|
const methodNames = {
|
||||||
|
'balance': '余额支付',
|
||||||
|
'alipay': '支付宝',
|
||||||
|
'wechatpay': '微信支付'
|
||||||
|
};
|
||||||
|
return methodNames[method] || '未知方式';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -419,7 +419,7 @@ def create_server_order(**kwargs):
|
|||||||
"team": team.name,
|
"team": team.name,
|
||||||
"status": "待支付",
|
"status": "待支付",
|
||||||
"total_amount": total_amount,
|
"total_amount": total_amount,
|
||||||
"title": f"新建服务器 - {region_id}",
|
"title": f"{region_id}",
|
||||||
"description": f"{selected_plan.get('core')}核/{selected_plan.get('memory')}GB/{selected_plan.get('disk_size')}GB, {period}个月",
|
"description": f"{selected_plan.get('core')}核/{selected_plan.get('memory')}GB/{selected_plan.get('disk_size')}GB, {period}个月",
|
||||||
"server_config": {
|
"server_config": {
|
||||||
"plan_id": plan_id,
|
"plan_id": plan_id,
|
||||||
|
|||||||
@ -43,6 +43,7 @@ from jcloud.utils.billing import (
|
|||||||
)
|
)
|
||||||
from jcloud.utils.mpesa_utils import create_mpesa_request_log
|
from jcloud.utils.mpesa_utils import create_mpesa_request_log
|
||||||
from jcloud.api.payment.wechatpay import WeChatPayAPI
|
from jcloud.api.payment.wechatpay import WeChatPayAPI
|
||||||
|
from jcloud.api.payment.alipay import AlipayAPI
|
||||||
|
|
||||||
@jingrow.whitelist()
|
@jingrow.whitelist()
|
||||||
def get_publishable_key_and_setup_intent():
|
def get_publishable_key_and_setup_intent():
|
||||||
@ -1223,7 +1224,6 @@ def create_alipay_order_for_recharge(amount):
|
|||||||
jingrow.db.commit()
|
jingrow.db.commit()
|
||||||
|
|
||||||
# 直接使用AlipayAPI类生成支付链接
|
# 直接使用AlipayAPI类生成支付链接
|
||||||
from jcloud.api.payment.alipay import AlipayAPI
|
|
||||||
api = AlipayAPI()
|
api = AlipayAPI()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -1451,7 +1451,7 @@ def process_balance_payment_for_order(order_id):
|
|||||||
"type": "Adjustment",
|
"type": "Adjustment",
|
||||||
"source": "Prepaid Credits",
|
"source": "Prepaid Credits",
|
||||||
"amount": -1 * float(order.total_amount), # 使用负数表示扣减
|
"amount": -1 * float(order.total_amount), # 使用负数表示扣减
|
||||||
"description": f"新建网站: {order.title}",
|
"description": f"{order.order_type}-{order.title}",
|
||||||
"paid_via_local_pg": 1
|
"paid_via_local_pg": 1
|
||||||
})
|
})
|
||||||
balance_transaction.flags.ignore_permissions = True
|
balance_transaction.flags.ignore_permissions = True
|
||||||
@ -1590,7 +1590,6 @@ def process_alipay_order(order_id):
|
|||||||
amount = round(float(order.total_amount), 2)
|
amount = round(float(order.total_amount), 2)
|
||||||
|
|
||||||
# 直接使用AlipayAPI类生成支付链接
|
# 直接使用AlipayAPI类生成支付链接
|
||||||
from jcloud.api.payment.alipay import AlipayAPI
|
|
||||||
api = AlipayAPI()
|
api = AlipayAPI()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -1874,119 +1873,3 @@ def get_balance_transactions(page=1, page_size=20, search=None):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Jsite Server 相关功能
|
# Jsite Server 相关功能
|
||||||
|
|
||||||
@jingrow.whitelist()
|
|
||||||
def process_balance_payment_for_server_order(order_id):
|
|
||||||
"""使用余额支付服务器订单"""
|
|
||||||
try:
|
|
||||||
team = get_current_team(True)
|
|
||||||
order = jingrow.get_pg("Order", {"order_id": order_id})
|
|
||||||
|
|
||||||
if not order or order.team != team.name:
|
|
||||||
jingrow.throw("订单不存在或无权限")
|
|
||||||
|
|
||||||
if order.status != "待支付":
|
|
||||||
return {"success": False, "message": "订单已处理"}
|
|
||||||
|
|
||||||
balance = team.get_balance()
|
|
||||||
if balance < order.total_amount:
|
|
||||||
return {"success": False, "message": "余额不足"}
|
|
||||||
|
|
||||||
# 扣款
|
|
||||||
balance_transaction = jingrow.get_pg({
|
|
||||||
"pagetype": "Balance Transaction",
|
|
||||||
"team": team.name,
|
|
||||||
"type": "Adjustment",
|
|
||||||
"source": "Prepaid Credits",
|
|
||||||
"amount": -order.total_amount,
|
|
||||||
"description": f"服务器购买: {order.title}"
|
|
||||||
})
|
|
||||||
balance_transaction.insert(ignore_permissions=True)
|
|
||||||
balance_transaction.submit()
|
|
||||||
|
|
||||||
# 更新订单状态
|
|
||||||
order.status = "已支付"
|
|
||||||
order.payment_method = "余额支付"
|
|
||||||
order.save(ignore_permissions=True)
|
|
||||||
|
|
||||||
# 异步创建服务器
|
|
||||||
jingrow.enqueue('jcloud.api.aliyun_server_light.create_server_async', order_name=order.name)
|
|
||||||
|
|
||||||
return {"success": True, "message": "支付成功,服务器创建中"}
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
jingrow.log_error("服务器支付失败", str(e))
|
|
||||||
return {"success": False, "message": str(e)}
|
|
||||||
|
|
||||||
@jingrow.whitelist()
|
|
||||||
def process_alipay_server_order(order_id):
|
|
||||||
"""支付宝支付服务器订单"""
|
|
||||||
team = get_current_team(True)
|
|
||||||
order = jingrow.get_pg("Order", {"order_id": order_id})
|
|
||||||
|
|
||||||
if not order or order.team != team.name:
|
|
||||||
jingrow.throw("订单不存在或无权限")
|
|
||||||
|
|
||||||
if order.status != "待支付":
|
|
||||||
jingrow.throw("订单已处理")
|
|
||||||
|
|
||||||
from jcloud.api.payment.alipay import AlipayAPI
|
|
||||||
api = AlipayAPI()
|
|
||||||
|
|
||||||
payment_url = api.generate_payment_url(
|
|
||||||
order_id=order_id,
|
|
||||||
amount=order.total_amount,
|
|
||||||
subject=order.title,
|
|
||||||
team_name=team.name
|
|
||||||
)
|
|
||||||
|
|
||||||
order.payment_method = "支付宝"
|
|
||||||
order.save(ignore_permissions=True)
|
|
||||||
|
|
||||||
return {"payment_url": payment_url, "order_id": order_id}
|
|
||||||
|
|
||||||
@jingrow.whitelist()
|
|
||||||
def process_wechatpay_server_order(order_id):
|
|
||||||
"""微信支付服务器订单"""
|
|
||||||
team = get_current_team(True)
|
|
||||||
order = jingrow.get_pg("Order", {"order_id": order_id})
|
|
||||||
|
|
||||||
if not order or order.team != team.name:
|
|
||||||
jingrow.throw("订单不存在或无权限")
|
|
||||||
|
|
||||||
if order.status != "待支付":
|
|
||||||
jingrow.throw("订单已处理")
|
|
||||||
|
|
||||||
wechat_pay = WeChatPayAPI()
|
|
||||||
qr_code_url = wechat_pay.generate_payment_url(
|
|
||||||
order_id=order_id,
|
|
||||||
amount=order.total_amount,
|
|
||||||
subject=order.title,
|
|
||||||
team_name=team.name
|
|
||||||
)
|
|
||||||
|
|
||||||
order.payment_method = "微信支付"
|
|
||||||
order.save(ignore_permissions=True)
|
|
||||||
|
|
||||||
return {"qr_code_url": qr_code_url, "order_id": order_id}
|
|
||||||
|
|
||||||
@jingrow.whitelist()
|
|
||||||
def check_server_order_payment_status(order_id):
|
|
||||||
"""检查服务器订单支付状态"""
|
|
||||||
try:
|
|
||||||
order = jingrow.get_pg("Order", {"order_id": order_id})
|
|
||||||
if not order:
|
|
||||||
jingrow.throw(f"找不到订单: {order_id}")
|
|
||||||
|
|
||||||
return {
|
|
||||||
"success": True,
|
|
||||||
"status": order.status,
|
|
||||||
"order": order.as_dict()
|
|
||||||
}
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
jingrow.log_error("服务器订单错误", f"检查服务器订单状态失败: {str(e)}")
|
|
||||||
return {
|
|
||||||
"success": False,
|
|
||||||
"message": f"检查订单状态失败: {str(e)}"
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user