Merge branch 'main' of https://gitlab.guxuan.icu/Leo_Ding/GPU_Web
This commit is contained in:
commit
2712949a96
@ -53,3 +53,9 @@ export const invoiceDetail = (id:any) => request.delete(`/v1/invoice/invoice_det
|
||||
|
||||
// 获取订单列表
|
||||
export const getOrderList = (params:any) => request.get('/v1/order/order_list',{params})
|
||||
|
||||
// 算力点兑换界面
|
||||
export const getExchangeList = (params:any) => request.get('/v1/balance/exchange_list', { params })
|
||||
|
||||
// 兑换算力点
|
||||
export const exchangePoint = (params:any) => request.put('/v1/balance/exchange_point',params)
|
||||
|
||||
@ -48,3 +48,4 @@ export const getHostInfo=(params:any)=>request.get('/v1/host/info',{params})
|
||||
|
||||
//兑换算力点
|
||||
export const exchangePoint=(params:any)=>request.put('/v1/balance/exchange_point',params)
|
||||
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
<a-breadcrumb-item>算力点兑换</a-breadcrumb-item>
|
||||
</a-breadcrumb>
|
||||
|
||||
|
||||
<!-- 余额卡片 -->
|
||||
<a-card class="balance-card">
|
||||
<div class="balance-info">
|
||||
@ -23,19 +22,15 @@
|
||||
</div>
|
||||
<div class="balance-item">
|
||||
<div class="balance-label">
|
||||
|
||||
<span class="label-text">算力点</span>
|
||||
</div>
|
||||
<div class="balance-value">
|
||||
<span class="points">{{ userInfo.computingPowerPoint }}</span>
|
||||
|
||||
<span class="points">{{ formatPoints(points) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</a-card>
|
||||
|
||||
|
||||
<!-- 兑换卡片 -->
|
||||
<a-card class="exchange-card" title="兑换算力点">
|
||||
<div class="exchange-content">
|
||||
@ -55,12 +50,8 @@
|
||||
<!-- 自定义输入 -->
|
||||
<div class="custom-amount">
|
||||
<a-input-group compact>
|
||||
<a-input v-model:value="customAmount" placeholder="输入其他金额" size="large" style="width: calc(100% - 120px)"
|
||||
@change="handleCustomAmountChange" :disabled="loading" />
|
||||
<!-- <a-button type="primary" size="large" style="width: 120px" :disabled="!isCustomAmountValid || loading"
|
||||
@click="handleCustomAmountConfirm">
|
||||
确认
|
||||
</a-button> -->
|
||||
<a-input v-model:value="customAmount" placeholder="输入其他金额" size="large" @change="handleCustomAmountChange"
|
||||
:disabled="loading" />
|
||||
</a-input-group>
|
||||
<p class="input-name">用户自定义输入算力点数量</p>
|
||||
<div v-if="customAmountError" class="error-text">
|
||||
@ -68,60 +59,7 @@
|
||||
{{ customAmountError }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 兑换规则说明 -->
|
||||
<div class="exchange-section">
|
||||
<h3 class="section-title">兑换规则</h3>
|
||||
<div class="exchange-rules">
|
||||
<div class="rule-item">
|
||||
<CheckCircleOutlined class="rule-icon" />
|
||||
<span>算力点兑换比例为人民币 <strong>1元 = 1算力点</strong></span>
|
||||
</div>
|
||||
<div class="rule-item">
|
||||
<ExclamationCircleOutlined class="rule-icon" />
|
||||
<span><strong>算力点不可退</strong>,兑换前请确认需求</span>
|
||||
</div>
|
||||
<div class="rule-item">
|
||||
<InfoCircleOutlined class="rule-icon" />
|
||||
<span>兑换后算力点立即生效,可用于平台所有计算服务</span>
|
||||
</div>
|
||||
<div class="rule-item">
|
||||
<SafetyOutlined class="rule-icon" />
|
||||
<span>兑换过程安全加密,保障您的资金安全</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 兑换信息展示 -->
|
||||
<div v-if="selectedExchangeAmount > 0" class="exchange-preview">
|
||||
<div class="preview-card">
|
||||
<div class="preview-header">
|
||||
<div class="preview-title">兑换明细</div>
|
||||
<a-button type="text" @click="clearSelection">
|
||||
<CloseOutlined />
|
||||
</a-button>
|
||||
</div>
|
||||
<div class="preview-content">
|
||||
<div class="preview-item">
|
||||
<span class="preview-label">兑换金额:</span>
|
||||
<span class="preview-value">¥{{ selectedExchangeAmount }}</span>
|
||||
</div>
|
||||
<div class="preview-item">
|
||||
<span class="preview-label">获得算力点:</span>
|
||||
<span class="preview-value points-value">{{ selectedExchangeAmount }} 算力点</span>
|
||||
</div>
|
||||
<div class="preview-item">
|
||||
<span class="preview-label">兑换后余额:</span>
|
||||
<span class="preview-value">¥{{ formatCurrency(userInfo.balance - selectedExchangeAmount) }}</span>
|
||||
</div>
|
||||
<div class="preview-item">
|
||||
<span class="preview-label">兑换后算力点:</span>
|
||||
<span class="preview-value points-value">{{ formatPoints(userInfo.computingPowerPoint + selectedExchangeAmount) }}
|
||||
算力点</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="title">兑换说明:算力点换算比例为人民币1 元 = 1 算力点,算力点兑换后不可退。</div>
|
||||
</div>
|
||||
|
||||
<!-- 用户协议确认 -->
|
||||
@ -137,16 +75,9 @@
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="action-buttons">
|
||||
<a-button type="primary" size="large" :loading="loading" :disabled="!canExchange" @click="handleExchange"
|
||||
class="exchange-button">
|
||||
<template #icon>
|
||||
<ThunderboltOutlined />
|
||||
</template>
|
||||
<a-button type="primary" size="large" @click="handleExchange" :loading="loading" :disabled="!canExchange" class="exchange-button">
|
||||
确认兑换
|
||||
</a-button>
|
||||
<a-button size="large" @click="handleCancel" :disabled="loading" class="cancel-button">
|
||||
取消
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
@ -154,8 +85,11 @@
|
||||
<!-- 主要内容区域 -->
|
||||
<div class="main-content">
|
||||
<a-card class="history-card" title="算力点兑换历史">
|
||||
<a-table :columns="historyColumns" bordered :data-source="exchangeHistory" row-key="key" :pagination="false">
|
||||
<!-- 自定义状态列的渲染 -->
|
||||
<a-table :columns="historyColumns"
|
||||
:data-source="listData"
|
||||
row-key="key"
|
||||
:pagination="paginationState"
|
||||
@change="onTableChange">
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'status'">
|
||||
<span :style="{ color: getStatusColor(record.status) }">{{ getStatusText(record.status) }}</span>
|
||||
@ -169,12 +103,6 @@
|
||||
</template>
|
||||
</a-table>
|
||||
</a-card>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 用户协议模态框 -->
|
||||
@ -185,7 +113,7 @@
|
||||
|
||||
<h4>一、兑换规则</h4>
|
||||
<p>1. 算力点兑换比例为1元人民币兑换1算力点。</p>
|
||||
<p>2. 最小兑换金额为1元,最大单次兑换金额为10000元。</p>
|
||||
<p>2. 最大单次兑换金额为10000元。</p>
|
||||
<p>3. 兑换操作一经确认,不可撤销或退款。</p>
|
||||
|
||||
<h4>二、使用规则</h4>
|
||||
@ -210,24 +138,21 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import {
|
||||
DollarCircleOutlined,
|
||||
ThunderboltOutlined,
|
||||
InfoCircleOutlined,
|
||||
CheckCircleOutlined,
|
||||
ExclamationCircleOutlined,
|
||||
SafetyOutlined,
|
||||
CloseOutlined
|
||||
ExclamationCircleOutlined
|
||||
} from '@ant-design/icons-vue'
|
||||
import { message, Modal, Divider } from 'ant-design-vue'
|
||||
import {exchangePoint} from '@/apis/home'
|
||||
import { message, Modal } from 'ant-design-vue'
|
||||
import { getExchangeList, exchangePoint } from '@/apis/admin'
|
||||
import { usePagination } from '@/hooks'
|
||||
|
||||
const { listData, paginationState, resetPagination, searchFormData } = usePagination()
|
||||
|
||||
// 用户余额和算力点
|
||||
const balance = ref(3568.5)
|
||||
const points = ref(1250)
|
||||
const userInfo=ref({})
|
||||
const balance = ref(0)
|
||||
const points = ref(0)
|
||||
|
||||
// 金额选项
|
||||
const amountOptions = ref([
|
||||
{ value: 100, label: '100' },
|
||||
@ -236,31 +161,25 @@ const amountOptions = ref([
|
||||
{ value: 5000, label: '5000' }
|
||||
])
|
||||
|
||||
// 注意:这里只定义 columns 结构,不包含 customRender
|
||||
// 历史记录列定义
|
||||
const historyColumns = [
|
||||
{
|
||||
title: '兑换金额',
|
||||
dataIndex: 'amount',
|
||||
key: 'amount',
|
||||
align: 'right'
|
||||
dataIndex: 'exchange_amount',
|
||||
key: 'exchange_amount',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '获得算力点',
|
||||
dataIndex: 'points',
|
||||
key: 'points',
|
||||
align: 'right'
|
||||
dataIndex: 'exchange_point',
|
||||
key: 'exchange_point',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '兑换时间',
|
||||
dataIndex: 'time',
|
||||
key: 'time'
|
||||
dataIndex: 'created_at',
|
||||
key: 'created_at'
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
align: 'center'
|
||||
}
|
||||
]
|
||||
|
||||
// 选择的金额
|
||||
@ -279,15 +198,6 @@ const loading = ref(false)
|
||||
const agreementModalVisible = ref(false)
|
||||
const modalAgreementChecked = ref(false)
|
||||
|
||||
// 兑换记录
|
||||
const exchangeHistory = ref([
|
||||
{ key: 1, amount: 1000, points: 1000, time: '2024-03-15 14:30:22', status: 'success' },
|
||||
{ key: 2, amount: 500, points: 500, time: '2024-03-10 09:15:45', status: 'success' },
|
||||
{ key: 3, amount: 2000, points: 2000, time: '2024-03-05 16:20:33', status: 'success' },
|
||||
{ key: 4, amount: 100, points: 100, time: '2024-02-28 11:45:12', status: 'success' },
|
||||
{ key: 5, amount: 5000, points: 5000, time: '2024-02-20 13:05:27', status: 'success' }
|
||||
])
|
||||
|
||||
// 计算选中的兑换金额
|
||||
const selectedExchangeAmount = computed(() => {
|
||||
if (selectedAmount.value > 0) {
|
||||
@ -311,10 +221,7 @@ const isCustomAmountValid = computed(() => {
|
||||
if (isNaN(amount) || amount <= 0) {
|
||||
return false
|
||||
}
|
||||
if (amount < 100) {
|
||||
customAmountError.value = '最小兑换金额为100元'
|
||||
return false
|
||||
}
|
||||
|
||||
if (amount > 10000) {
|
||||
customAmountError.value = '单次最大兑换金额为10000元'
|
||||
return false
|
||||
@ -328,17 +235,20 @@ const isCustomAmountValid = computed(() => {
|
||||
})
|
||||
|
||||
// 格式化货币
|
||||
const formatCurrency = (value) => {
|
||||
return value.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',')
|
||||
const formatCurrency = (value: any): string => {
|
||||
const num = typeof value === 'number' ? value : parseFloat(value);
|
||||
if (isNaN(num)) return '0.00';
|
||||
return num.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||
}
|
||||
|
||||
// 格式化算力点
|
||||
const formatPoints = (value) => {
|
||||
return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
|
||||
const formatPoints = (value: any): string => {
|
||||
const num = typeof value === 'number' ? value : parseFloat(value);
|
||||
if (isNaN(num)) return '0';
|
||||
return Math.floor(num).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||
}
|
||||
|
||||
// 选择金额
|
||||
const selectAmount = (amount) => {
|
||||
const selectAmount = (amount: number) => {
|
||||
selectedAmount.value = amount
|
||||
customAmount.value = ''
|
||||
customAmountError.value = ''
|
||||
@ -350,9 +260,7 @@ const handleCustomAmountChange = () => {
|
||||
if (customAmount.value) {
|
||||
const amount = parseFloat(customAmount.value)
|
||||
if (!isNaN(amount)) {
|
||||
if (amount < 1) {
|
||||
customAmountError.value = '最小兑换金额为1元'
|
||||
} else if (amount > 10000) {
|
||||
if (amount > 10000) {
|
||||
customAmountError.value = '单次最大兑换金额为10000元'
|
||||
} else if (amount > userInfo.value.balance) {
|
||||
customAmountError.value = '兑换金额不能超过余额'
|
||||
@ -365,21 +273,6 @@ const handleCustomAmountChange = () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 确认自定义金额
|
||||
const handleCustomAmountConfirm = () => {
|
||||
if (isCustomAmountValid.value) {
|
||||
selectedAmount.value = 0
|
||||
message.success(`已选择兑换¥${customAmount.value}`)
|
||||
}
|
||||
}
|
||||
|
||||
// 清空选择
|
||||
const clearSelection = () => {
|
||||
selectedAmount.value = 0
|
||||
customAmount.value = ''
|
||||
customAmountError.value = ''
|
||||
}
|
||||
|
||||
// 显示用户协议模态框
|
||||
const showAgreementModal = () => {
|
||||
agreementModalVisible.value = true
|
||||
@ -394,7 +287,7 @@ const handleAgreementConfirm = () => {
|
||||
}
|
||||
|
||||
// 处理兑换
|
||||
const handleExchange = () => {
|
||||
const handleExchange = async () => {
|
||||
showAgreementError.value = false
|
||||
if (!agreementChecked.value) {
|
||||
showAgreementError.value = true
|
||||
@ -410,37 +303,63 @@ const handleExchange = () => {
|
||||
content: `您确定要兑换 ¥${selectedExchangeAmount.value} 获得 ${selectedExchangeAmount.value} 算力点吗?此操作不可撤销。`,
|
||||
okText: '确认兑换',
|
||||
cancelText: '取消',
|
||||
onOk: performExchange
|
||||
async onOk() {
|
||||
await performExchange()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 执行兑换
|
||||
const performExchange = async() => {
|
||||
const performExchange = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const params={
|
||||
exchange_value:selectedExchangeAmount.value
|
||||
}
|
||||
const res=await exchangePoint(params)
|
||||
console.log(res)
|
||||
message.success(`兑换成功!获得 ${selectedExchangeAmount.value} 算力点`)
|
||||
loading.value=false
|
||||
} catch (error) {
|
||||
loading.value=false
|
||||
}
|
||||
|
||||
try {
|
||||
// 调用兑换接口
|
||||
const response:any = await exchangePoint({
|
||||
exchange_value: selectedExchangeAmount.value
|
||||
})
|
||||
console.log('兑换结果:', response)
|
||||
|
||||
if (response.code === 1) {
|
||||
// 兑换成功,更新余额和算力点
|
||||
const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}');
|
||||
userInfo.balance -= selectedExchangeAmount.value;
|
||||
userInfo.computingPowerPoint += selectedExchangeAmount.value;
|
||||
localStorage.setItem('userInfo', JSON.stringify(userInfo));
|
||||
|
||||
// 更新本地状态
|
||||
balance.value = userInfo.balance;
|
||||
points.value = userInfo.computingPowerPoint;
|
||||
|
||||
// 刷新历史记录
|
||||
await getPageList();
|
||||
|
||||
// 清空选择
|
||||
clearSelection();
|
||||
agreementChecked.value = false;
|
||||
|
||||
message.success(`兑换成功`);
|
||||
} else {
|
||||
message.error(response.msg || '兑换失败');
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('兑换失败:', error);
|
||||
message.error(error.msg || '兑换失败,请稍后重试');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理取消
|
||||
const handleCancel = () => {
|
||||
clearSelection()
|
||||
agreementChecked.value = false
|
||||
showAgreementError.value = false
|
||||
// 清空选择
|
||||
const clearSelection = () => {
|
||||
selectedAmount.value = 0
|
||||
customAmount.value = ''
|
||||
customAmountError.value = ''
|
||||
}
|
||||
|
||||
// 获取状态颜色
|
||||
const getStatusColor = (status) => {
|
||||
const colors = {
|
||||
const getStatusColor = (status: string) => {
|
||||
const colors: Record<string, string> = {
|
||||
success: 'green',
|
||||
pending: 'orange',
|
||||
failed: 'red'
|
||||
@ -449,8 +368,8 @@ const getStatusColor = (status) => {
|
||||
}
|
||||
|
||||
// 获取状态文本
|
||||
const getStatusText = (status) => {
|
||||
const texts = {
|
||||
const getStatusText = (status: string) => {
|
||||
const texts: Record<string, string> = {
|
||||
success: '成功',
|
||||
pending: '处理中',
|
||||
failed: '失败'
|
||||
@ -458,16 +377,50 @@ const getStatusText = (status) => {
|
||||
return texts[status] || status
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const userInfoStr=localStorage.getItem("userInfo")
|
||||
if(userInfoStr){
|
||||
userInfo.value = JSON.parse(userInfoStr);
|
||||
// 获取兑换历史列表
|
||||
const getPageList = async () => {
|
||||
try {
|
||||
const { pageSize, current } = paginationState
|
||||
const res: any = await getExchangeList({
|
||||
page_size: pageSize,
|
||||
page_num: current,
|
||||
})
|
||||
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
listData.value = res.data
|
||||
paginationState.total = res.total || res.data.length
|
||||
} else {
|
||||
listData.value = []
|
||||
paginationState.total = 0
|
||||
}
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('兑换历史请求失败:', error)
|
||||
listData.value = []
|
||||
paginationState.total = 0
|
||||
}
|
||||
}
|
||||
|
||||
// 表格分页变化
|
||||
function onTableChange({ current, pageSize }: { current: number, pageSize: number }) {
|
||||
paginationState.current = current
|
||||
paginationState.pageSize = pageSize
|
||||
getPageList()
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}');
|
||||
if (userInfo.balance && userInfo.computingPowerPoint) {
|
||||
balance.value = userInfo.balance;
|
||||
points.value = userInfo.computingPowerPoint;
|
||||
}
|
||||
getPageList();
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 你的样式保持不变 */
|
||||
/* 样式保持不变,同上 */
|
||||
.points-exchange-page {
|
||||
padding: 20px;
|
||||
/* min-height: 100vh; */
|
||||
@ -477,25 +430,6 @@ onMounted(() => {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.page-description {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.main-content {}
|
||||
|
||||
.balance-card {
|
||||
margin-bottom: 20px;
|
||||
border-radius: 12px;
|
||||
@ -518,19 +452,6 @@ onMounted(() => {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.icon-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: #f0f5ff;
|
||||
border-radius: 8px;
|
||||
margin-right: 12px;
|
||||
color: #1890ff;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.label-text {
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
@ -553,24 +474,6 @@ onMounted(() => {
|
||||
color: rgba(56, 56, 56, 1);
|
||||
}
|
||||
|
||||
.balance-value .points-unit {
|
||||
font-size: 16px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.balance-tips {
|
||||
padding: 12px 16px;
|
||||
background: #f6ffed;
|
||||
border-radius: 8px;
|
||||
color: #52c41a;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.balance-tips :deep(.anticon) {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.exchange-card {
|
||||
margin-bottom: 20px;
|
||||
border-radius: 12px;
|
||||
@ -593,12 +496,6 @@ onMounted(() => {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.section-subtitle {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
font-size: 14px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.amount-options {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(8, 1fr);
|
||||
@ -614,7 +511,6 @@ onMounted(() => {
|
||||
|
||||
.amount-option {
|
||||
height: auto !important;
|
||||
/* padding: 6px !important; */
|
||||
border-radius: 8px !important;
|
||||
border: 2px solid #f0f0f0 !important;
|
||||
background: #fff !important;
|
||||
@ -643,21 +539,17 @@ onMounted(() => {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.amount-points {
|
||||
font-size: 12px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
.custom-amount {
|
||||
width: 345px;
|
||||
margin-bottom: 24px;
|
||||
margin-left: 180px;
|
||||
}
|
||||
|
||||
.custom-amount {
|
||||
width: 460px;
|
||||
margin-bottom: 24px;
|
||||
margin-left: 170px;
|
||||
|
||||
input {
|
||||
.custom-amount input {
|
||||
height: 45px;
|
||||
}
|
||||
}
|
||||
|
||||
.input-name {
|
||||
.input-name {
|
||||
width: 350px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
@ -665,8 +557,14 @@ onMounted(() => {
|
||||
color: rgba(166, 166, 166, 1);
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0px;
|
||||
line-height: 32.93px;
|
||||
color: rgba(166, 166, 166, 1);
|
||||
}
|
||||
|
||||
.error-text {
|
||||
@ -678,99 +576,6 @@ onMounted(() => {
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.exchange-rules {
|
||||
background: #fafafa;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.rule-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.rule-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.rule-icon {
|
||||
margin-right: 12px;
|
||||
margin-top: 2px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.rule-item:nth-child(1) .rule-icon {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
.rule-item:nth-child(2) .rule-icon {
|
||||
color: #faad14;
|
||||
}
|
||||
|
||||
.rule-item:nth-child(3) .rule-icon {
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.rule-item:nth-child(4) .rule-icon {
|
||||
color: #722ed1;
|
||||
}
|
||||
|
||||
.exchange-preview {
|
||||
margin: 24px 0;
|
||||
}
|
||||
|
||||
.preview-card {
|
||||
background: #f6ffed;
|
||||
border: 1px solid #b7eb8f;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.preview-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.preview-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
}
|
||||
|
||||
.preview-content {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px 60px;
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.preview-content {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.preview-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.preview-label {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
|
||||
.preview-value {
|
||||
font-weight: 500;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
}
|
||||
|
||||
.preview-value.points-value {
|
||||
color: #722ed1;
|
||||
}
|
||||
|
||||
.agreement-section {
|
||||
margin: 24px 0;
|
||||
padding: 16px;
|
||||
@ -789,18 +594,12 @@ onMounted(() => {
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 16px;
|
||||
margin-top: 32px;
|
||||
}
|
||||
|
||||
.exchange-button {
|
||||
flex: 1;
|
||||
height: 48px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
width: 120px;
|
||||
height: 48px;
|
||||
}
|
||||
@ -810,23 +609,6 @@ onMounted(() => {
|
||||
/* box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); */
|
||||
}
|
||||
|
||||
.exchange-amount {
|
||||
color: #1890ff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.exchange-points {
|
||||
color: #722ed1;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.view-all-link {
|
||||
text-align: center;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.agreement-content {
|
||||
max-height: 60vh;
|
||||
overflow-y: auto;
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<!-- 左侧栏:实例、数据、邀请好友 -->
|
||||
<a-col :span="16">
|
||||
<!-- 实例卡片 -->
|
||||
<a-card title="GPU容器实例" class="card">
|
||||
<a-card title="GPU容器实例" class="card gpu-card">
|
||||
<a-row :gutter="32" align="middle">
|
||||
<!-- 第一栏:容器实例和运行中 -->
|
||||
<a-col :span="18">
|
||||
@ -44,14 +44,17 @@
|
||||
|
||||
<!-- 邀请好友卡片 -->
|
||||
<a-card title="邀请好友得算力券" class="card margin-top">
|
||||
<template #extra>
|
||||
<a-button type="link" @click="goToRules">活动规则</a-button>
|
||||
</template>
|
||||
<a-row :gutter="24" class="invite-container">
|
||||
<!-- 左侧:邀请信息和链接 -->
|
||||
<a-col :span="24">
|
||||
<div class="invite-content">
|
||||
<div class="invite-status">
|
||||
<div class="status-icon">
|
||||
<!-- <div class="status-icon">
|
||||
<LinkOutlined />
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="status-text">
|
||||
<div class="status-title">暂无邀请链接</div>
|
||||
<div class="status-desc">
|
||||
@ -61,33 +64,15 @@
|
||||
</div>
|
||||
|
||||
<div class="invite-actions">
|
||||
<a-button
|
||||
type="primary"
|
||||
class="generate-btn"
|
||||
@click="generateInviteLink"
|
||||
>
|
||||
<a-button type="primary" class="generate-btn" @click="generateInviteLink">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
生成邀请链接
|
||||
</a-button>
|
||||
|
||||
<!-- 新增:活动规则链接 -->
|
||||
<a-button
|
||||
type="link"
|
||||
class="rules-link"
|
||||
@click="goToRules"
|
||||
>
|
||||
<template #icon>
|
||||
<QuestionCircleOutlined />
|
||||
</template>
|
||||
查看活动规则
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
|
||||
|
||||
</a-row>
|
||||
</a-card>
|
||||
</a-col>
|
||||
@ -112,10 +97,12 @@
|
||||
<CopyOutlined />
|
||||
</i>
|
||||
</p>
|
||||
<a-tag :color="getCertifyName(userInfo.certificationStatus).color">{{ getCertifyName(userInfo.certificationStatus).name }}</a-tag>
|
||||
<a-tag :color="getCertifyName(userInfo.certificationStatus).color">{{
|
||||
getCertifyName(userInfo.certificationStatus).name }}</a-tag>
|
||||
<!-- <p>{{getCertifyName(userInfo.certificationStatus).name}}</p> -->
|
||||
</div>
|
||||
<span class="btn-item" style="cursor: pointer;" @click="router.push('/layout/admin/accountSet')">
|
||||
<span class="btn-item" style="cursor: pointer;"
|
||||
@click="router.push('/layout/admin/accountSet')">
|
||||
账户设置
|
||||
<ArrowRightOutlined />
|
||||
</span>
|
||||
@ -125,9 +112,9 @@
|
||||
|
||||
<!-- 我的余额 -->
|
||||
<div class="asset-item">
|
||||
<div class="asset-icon-box balance-icon">
|
||||
<!-- <div class="asset-icon-box balance-icon">
|
||||
<WalletOutlined class="asset-icon" />
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="asset-content">
|
||||
<div class="asset-name">我的余额</div>
|
||||
<div class="asset-value" v-if="userInfo.balance >= 0">
|
||||
@ -143,9 +130,9 @@
|
||||
|
||||
<!-- 我的权益 -->
|
||||
<div class="asset-item">
|
||||
<div class="asset-icon-box coupon-icon">
|
||||
<!-- <div class="asset-icon-box coupon-icon">
|
||||
<TagOutlined class="asset-icon" />
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="asset-content">
|
||||
<div class="asset-name">我的权益</div>
|
||||
<div class="rights-info">
|
||||
@ -155,7 +142,7 @@
|
||||
<span class="rights-text">算力点</span>
|
||||
</div>
|
||||
<div class="rights-value">
|
||||
<span class="rights-amount">{{ userInfo.computingPowerPoint}}</span>
|
||||
<span class="rights-amount">{{ userInfo.computingPowerPoint }}</span>
|
||||
<span class="rights-unit">点</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -306,12 +293,15 @@ const goToInvoice = () => {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
|
||||
.gpu-card {
|
||||
background: linear-gradient(180deg, rgba(250, 252, 255, 1) 0%, rgba(255, 255, 255, 1) 100%);
|
||||
}
|
||||
|
||||
.margin-top {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
|
||||
/* 实例卡片样式 */
|
||||
.stats-column {
|
||||
display: flex;
|
||||
@ -395,7 +385,9 @@ const goToInvoice = () => {
|
||||
}
|
||||
|
||||
.status-text {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.status-title {
|
||||
@ -413,10 +405,8 @@ const goToInvoice = () => {
|
||||
}
|
||||
|
||||
.invite-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
margin-top: 8px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.generate-btn {
|
||||
@ -689,14 +679,16 @@ const goToInvoice = () => {
|
||||
/* 算力点特殊样式 */
|
||||
.rights-item:first-child {
|
||||
.rights-amount {
|
||||
color: #fa8c16; /* 算力点用橙色 */
|
||||
color: #fa8c16;
|
||||
/* 算力点用橙色 */
|
||||
}
|
||||
}
|
||||
|
||||
/* 算力券特殊样式 */
|
||||
.rights-item:last-child {
|
||||
.rights-amount {
|
||||
color: #1890ff; /* 算力券用蓝色 */
|
||||
color: #1890ff;
|
||||
/* 算力券用蓝色 */
|
||||
}
|
||||
}
|
||||
|
||||
@ -731,6 +723,7 @@ const goToInvoice = () => {
|
||||
|
||||
.nav-account {
|
||||
padding-left: 10px;
|
||||
margin-top: -20px;
|
||||
|
||||
:first-child {
|
||||
font-weight: 500;
|
||||
@ -767,7 +760,7 @@ const goToInvoice = () => {
|
||||
height: 20px;
|
||||
font-size: 10px;
|
||||
padding: 2px 5px;
|
||||
margin-top: 42px;
|
||||
margin-top: 30px;
|
||||
margin-left: 10px;
|
||||
border-radius: 5px;
|
||||
border: 1px solid rgba(166, 166, 166, 1);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user