This commit is contained in:
Leo_Ding 2026-01-16 17:41:28 +08:00
commit 2712949a96
4 changed files with 224 additions and 442 deletions

View File

@ -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 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)

View File

@ -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) export const exchangePoint=(params:any)=>request.put('/v1/balance/exchange_point',params)

View File

@ -8,7 +8,6 @@
<a-breadcrumb-item>算力点兑换</a-breadcrumb-item> <a-breadcrumb-item>算力点兑换</a-breadcrumb-item>
</a-breadcrumb> </a-breadcrumb>
<!-- 余额卡片 --> <!-- 余额卡片 -->
<a-card class="balance-card"> <a-card class="balance-card">
<div class="balance-info"> <div class="balance-info">
@ -23,19 +22,15 @@
</div> </div>
<div class="balance-item"> <div class="balance-item">
<div class="balance-label"> <div class="balance-label">
<span class="label-text">算力点</span> <span class="label-text">算力点</span>
</div> </div>
<div class="balance-value"> <div class="balance-value">
<span class="points">{{ userInfo.computingPowerPoint }}</span> <span class="points">{{ formatPoints(points) }}</span>
</div> </div>
</div> </div>
</div> </div>
</a-card> </a-card>
<!-- 兑换卡片 --> <!-- 兑换卡片 -->
<a-card class="exchange-card" title="兑换算力点"> <a-card class="exchange-card" title="兑换算力点">
<div class="exchange-content"> <div class="exchange-content">
@ -55,12 +50,8 @@
<!-- 自定义输入 --> <!-- 自定义输入 -->
<div class="custom-amount"> <div class="custom-amount">
<a-input-group compact> <a-input-group compact>
<a-input v-model:value="customAmount" placeholder="输入其他金额" size="large" style="width: calc(100% - 120px)" <a-input v-model:value="customAmount" placeholder="输入其他金额" size="large" @change="handleCustomAmountChange"
@change="handleCustomAmountChange" :disabled="loading" /> :disabled="loading" />
<!-- <a-button type="primary" size="large" style="width: 120px" :disabled="!isCustomAmountValid || loading"
@click="handleCustomAmountConfirm">
确认
</a-button> -->
</a-input-group> </a-input-group>
<p class="input-name">用户自定义输入算力点数量</p> <p class="input-name">用户自定义输入算力点数量</p>
<div v-if="customAmountError" class="error-text"> <div v-if="customAmountError" class="error-text">
@ -68,60 +59,7 @@
{{ customAmountError }} {{ customAmountError }}
</div> </div>
</div> </div>
</div> <div class="title">兑换说明算力点换算比例为人民币1 = 1 算力点算力点兑换后不可退</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> </div>
<!-- 用户协议确认 --> <!-- 用户协议确认 -->
@ -137,16 +75,9 @@
<!-- 操作按钮 --> <!-- 操作按钮 -->
<div class="action-buttons"> <div class="action-buttons">
<a-button type="primary" size="large" :loading="loading" :disabled="!canExchange" @click="handleExchange" <a-button type="primary" size="large" @click="handleExchange" :loading="loading" :disabled="!canExchange" class="exchange-button">
class="exchange-button">
<template #icon>
<ThunderboltOutlined />
</template>
确认兑换 确认兑换
</a-button> </a-button>
<a-button size="large" @click="handleCancel" :disabled="loading" class="cancel-button">
取消
</a-button>
</div> </div>
</div> </div>
</a-card> </a-card>
@ -154,8 +85,11 @@
<!-- 主要内容区域 --> <!-- 主要内容区域 -->
<div class="main-content"> <div class="main-content">
<a-card class="history-card" title="算力点兑换历史"> <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 #bodyCell="{ column, record }">
<template v-if="column.key === 'status'"> <template v-if="column.key === 'status'">
<span :style="{ color: getStatusColor(record.status) }">{{ getStatusText(record.status) }}</span> <span :style="{ color: getStatusColor(record.status) }">{{ getStatusText(record.status) }}</span>
@ -169,12 +103,6 @@
</template> </template>
</a-table> </a-table>
</a-card> </a-card>
</div> </div>
<!-- 用户协议模态框 --> <!-- 用户协议模态框 -->
@ -185,7 +113,7 @@
<h4>兑换规则</h4> <h4>兑换规则</h4>
<p>1. 算力点兑换比例为1元人民币兑换1算力点</p> <p>1. 算力点兑换比例为1元人民币兑换1算力点</p>
<p>2. 小兑换金额为1元大单次兑换金额为10000元</p> <p>2. 大单次兑换金额为10000元</p>
<p>3. 兑换操作一经确认不可撤销或退款</p> <p>3. 兑换操作一经确认不可撤销或退款</p>
<h4>使用规则</h4> <h4>使用规则</h4>
@ -210,24 +138,21 @@
</div> </div>
</template> </template>
<script setup> <script setup lang="ts">
import { ref, computed, onMounted } from 'vue' import { ref, computed, onMounted } from 'vue'
import { import {
DollarCircleOutlined, ExclamationCircleOutlined
ThunderboltOutlined,
InfoCircleOutlined,
CheckCircleOutlined,
ExclamationCircleOutlined,
SafetyOutlined,
CloseOutlined
} from '@ant-design/icons-vue' } from '@ant-design/icons-vue'
import { message, Modal, Divider } from 'ant-design-vue' import { message, Modal } from 'ant-design-vue'
import {exchangePoint} from '@/apis/home' import { getExchangeList, exchangePoint } from '@/apis/admin'
import { usePagination } from '@/hooks'
const { listData, paginationState, resetPagination, searchFormData } = usePagination()
// //
const balance = ref(3568.5) const balance = ref(0)
const points = ref(1250) const points = ref(0)
const userInfo=ref({})
// //
const amountOptions = ref([ const amountOptions = ref([
{ value: 100, label: '100' }, { value: 100, label: '100' },
@ -236,31 +161,25 @@ const amountOptions = ref([
{ value: 5000, label: '5000' } { value: 5000, label: '5000' }
]) ])
// columns customRender //
const historyColumns = [ const historyColumns = [
{ {
title: '兑换金额', title: '兑换金额',
dataIndex: 'amount', dataIndex: 'exchange_amount',
key: 'amount', key: 'exchange_amount',
align: 'right' align: 'center'
}, },
{ {
title: '获得算力点', title: '获得算力点',
dataIndex: 'points', dataIndex: 'exchange_point',
key: 'points', key: 'exchange_point',
align: 'right' align: 'center'
}, },
{ {
title: '兑换时间', title: '兑换时间',
dataIndex: 'time', dataIndex: 'created_at',
key: 'time' key: 'created_at'
}, },
{
title: '状态',
dataIndex: 'status',
key: 'status',
align: 'center'
}
] ]
// //
@ -279,15 +198,6 @@ const loading = ref(false)
const agreementModalVisible = ref(false) const agreementModalVisible = ref(false)
const modalAgreementChecked = 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(() => { const selectedExchangeAmount = computed(() => {
if (selectedAmount.value > 0) { if (selectedAmount.value > 0) {
@ -311,10 +221,7 @@ const isCustomAmountValid = computed(() => {
if (isNaN(amount) || amount <= 0) { if (isNaN(amount) || amount <= 0) {
return false return false
} }
if (amount < 100) {
customAmountError.value = '最小兑换金额为100元'
return false
}
if (amount > 10000) { if (amount > 10000) {
customAmountError.value = '单次最大兑换金额为10000元' customAmountError.value = '单次最大兑换金额为10000元'
return false return false
@ -328,17 +235,20 @@ const isCustomAmountValid = computed(() => {
}) })
// //
const formatCurrency = (value) => { const formatCurrency = (value: any): string => {
return value.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',') 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: any): string => {
const formatPoints = (value) => { const num = typeof value === 'number' ? value : parseFloat(value);
return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') 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 selectedAmount.value = amount
customAmount.value = '' customAmount.value = ''
customAmountError.value = '' customAmountError.value = ''
@ -350,9 +260,7 @@ const handleCustomAmountChange = () => {
if (customAmount.value) { if (customAmount.value) {
const amount = parseFloat(customAmount.value) const amount = parseFloat(customAmount.value)
if (!isNaN(amount)) { if (!isNaN(amount)) {
if (amount < 1) { if (amount > 10000) {
customAmountError.value = '最小兑换金额为1元'
} else if (amount > 10000) {
customAmountError.value = '单次最大兑换金额为10000元' customAmountError.value = '单次最大兑换金额为10000元'
} else if (amount > userInfo.value.balance) { } else if (amount > userInfo.value.balance) {
customAmountError.value = '兑换金额不能超过余额' 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 = () => { const showAgreementModal = () => {
agreementModalVisible.value = true agreementModalVisible.value = true
@ -394,7 +287,7 @@ const handleAgreementConfirm = () => {
} }
// //
const handleExchange = () => { const handleExchange = async () => {
showAgreementError.value = false showAgreementError.value = false
if (!agreementChecked.value) { if (!agreementChecked.value) {
showAgreementError.value = true showAgreementError.value = true
@ -410,37 +303,63 @@ const handleExchange = () => {
content: `您确定要兑换 ¥${selectedExchangeAmount.value} 获得 ${selectedExchangeAmount.value} 算力点吗?此操作不可撤销。`, content: `您确定要兑换 ¥${selectedExchangeAmount.value} 获得 ${selectedExchangeAmount.value} 算力点吗?此操作不可撤销。`,
okText: '确认兑换', okText: '确认兑换',
cancelText: '取消', cancelText: '取消',
onOk: performExchange async onOk() {
await performExchange()
}
}) })
} }
// //
const performExchange = async() => { const performExchange = async () => {
loading.value = true 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 = () => { const clearSelection = () => {
clearSelection() selectedAmount.value = 0
agreementChecked.value = false customAmount.value = ''
showAgreementError.value = false customAmountError.value = ''
} }
// //
const getStatusColor = (status) => { const getStatusColor = (status: string) => {
const colors = { const colors: Record<string, string> = {
success: 'green', success: 'green',
pending: 'orange', pending: 'orange',
failed: 'red' failed: 'red'
@ -449,8 +368,8 @@ const getStatusColor = (status) => {
} }
// //
const getStatusText = (status) => { const getStatusText = (status: string) => {
const texts = { const texts: Record<string, string> = {
success: '成功', success: '成功',
pending: '处理中', pending: '处理中',
failed: '失败' failed: '失败'
@ -458,16 +377,50 @@ const getStatusText = (status) => {
return texts[status] || status return texts[status] || status
} }
onMounted(() => { //
const userInfoStr=localStorage.getItem("userInfo") const getPageList = async () => {
if(userInfoStr){ try {
userInfo.value = JSON.parse(userInfoStr); 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> </script>
<style scoped> <style scoped>
/* 你的样式保持不变 */ /* 样式保持不变,同上 */
.points-exchange-page { .points-exchange-page {
padding: 20px; padding: 20px;
/* min-height: 100vh; */ /* min-height: 100vh; */
@ -477,25 +430,6 @@ onMounted(() => {
margin-bottom: 16px; 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 { .balance-card {
margin-bottom: 20px; margin-bottom: 20px;
border-radius: 12px; border-radius: 12px;
@ -518,19 +452,6 @@ onMounted(() => {
margin-bottom: 8px; 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 { .label-text {
font-size: 20px; font-size: 20px;
font-weight: 500; font-weight: 500;
@ -553,24 +474,6 @@ onMounted(() => {
color: rgba(56, 56, 56, 1); 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 { .exchange-card {
margin-bottom: 20px; margin-bottom: 20px;
border-radius: 12px; border-radius: 12px;
@ -593,12 +496,6 @@ onMounted(() => {
width: 120px; width: 120px;
} }
.section-subtitle {
color: rgba(0, 0, 0, 0.45);
font-size: 14px;
margin-bottom: 20px;
}
.amount-options { .amount-options {
display: grid; display: grid;
grid-template-columns: repeat(8, 1fr); grid-template-columns: repeat(8, 1fr);
@ -614,7 +511,6 @@ onMounted(() => {
.amount-option { .amount-option {
height: auto !important; height: auto !important;
/* padding: 6px !important; */
border-radius: 8px !important; border-radius: 8px !important;
border: 2px solid #f0f0f0 !important; border: 2px solid #f0f0f0 !important;
background: #fff !important; background: #fff !important;
@ -643,21 +539,17 @@ onMounted(() => {
margin-bottom: 4px; margin-bottom: 4px;
} }
.amount-points { .custom-amount {
font-size: 12px; width: 345px;
color: rgba(0, 0, 0, 0.45); margin-bottom: 24px;
margin-left: 180px;
} }
.custom-amount { .custom-amount input {
width: 460px;
margin-bottom: 24px;
margin-left: 170px;
input {
height: 45px; height: 45px;
} }
.input-name { .input-name {
width: 350px; width: 350px;
text-align: center; text-align: center;
font-size: 14px; font-size: 14px;
@ -665,8 +557,14 @@ onMounted(() => {
color: rgba(166, 166, 166, 1); color: rgba(166, 166, 166, 1);
height: 35px; height: 35px;
line-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 { .error-text {
@ -678,99 +576,6 @@ onMounted(() => {
gap: 4px; 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 { .agreement-section {
margin: 24px 0; margin: 24px 0;
padding: 16px; padding: 16px;
@ -789,18 +594,12 @@ onMounted(() => {
.action-buttons { .action-buttons {
display: flex; display: flex;
justify-content: flex-end;
gap: 16px; gap: 16px;
margin-top: 32px; margin-top: 32px;
} }
.exchange-button { .exchange-button {
flex: 1;
height: 48px;
font-size: 16px;
font-weight: 500;
}
.cancel-button {
width: 120px; width: 120px;
height: 48px; height: 48px;
} }
@ -810,23 +609,6 @@ onMounted(() => {
/* box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); */ /* 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 { .agreement-content {
max-height: 60vh; max-height: 60vh;
overflow-y: auto; overflow-y: auto;

View File

@ -5,7 +5,7 @@
<!-- 左侧栏实例数据邀请好友 --> <!-- 左侧栏实例数据邀请好友 -->
<a-col :span="16"> <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-row :gutter="32" align="middle">
<!-- 第一栏容器实例和运行中 --> <!-- 第一栏容器实例和运行中 -->
<a-col :span="18"> <a-col :span="18">
@ -44,14 +44,17 @@
<!-- 邀请好友卡片 --> <!-- 邀请好友卡片 -->
<a-card title="邀请好友得算力券" class="card margin-top"> <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-row :gutter="24" class="invite-container">
<!-- 左侧邀请信息和链接 --> <!-- 左侧邀请信息和链接 -->
<a-col :span="24"> <a-col :span="24">
<div class="invite-content"> <div class="invite-content">
<div class="invite-status"> <div class="invite-status">
<div class="status-icon"> <!-- <div class="status-icon">
<LinkOutlined /> <LinkOutlined />
</div> </div> -->
<div class="status-text"> <div class="status-text">
<div class="status-title">暂无邀请链接</div> <div class="status-title">暂无邀请链接</div>
<div class="status-desc"> <div class="status-desc">
@ -61,33 +64,15 @@
</div> </div>
<div class="invite-actions"> <div class="invite-actions">
<a-button <a-button type="primary" class="generate-btn" @click="generateInviteLink">
type="primary"
class="generate-btn"
@click="generateInviteLink"
>
<template #icon> <template #icon>
<PlusOutlined /> <PlusOutlined />
</template> </template>
生成邀请链接 生成邀请链接
</a-button> </a-button>
<!-- 新增活动规则链接 -->
<a-button
type="link"
class="rules-link"
@click="goToRules"
>
<template #icon>
<QuestionCircleOutlined />
</template>
查看活动规则
</a-button>
</div> </div>
</div> </div>
</a-col> </a-col>
</a-row> </a-row>
</a-card> </a-card>
</a-col> </a-col>
@ -112,10 +97,12 @@
<CopyOutlined /> <CopyOutlined />
</i> </i>
</p> </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> --> <!-- <p>{{getCertifyName(userInfo.certificationStatus).name}}</p> -->
</div> </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 /> <ArrowRightOutlined />
</span> </span>
@ -125,9 +112,9 @@
<!-- 我的余额 --> <!-- 我的余额 -->
<div class="asset-item"> <div class="asset-item">
<div class="asset-icon-box balance-icon"> <!-- <div class="asset-icon-box balance-icon">
<WalletOutlined class="asset-icon" /> <WalletOutlined class="asset-icon" />
</div> </div> -->
<div class="asset-content"> <div class="asset-content">
<div class="asset-name">我的余额</div> <div class="asset-name">我的余额</div>
<div class="asset-value" v-if="userInfo.balance >= 0"> <div class="asset-value" v-if="userInfo.balance >= 0">
@ -143,9 +130,9 @@
<!-- 我的权益 --> <!-- 我的权益 -->
<div class="asset-item"> <div class="asset-item">
<div class="asset-icon-box coupon-icon"> <!-- <div class="asset-icon-box coupon-icon">
<TagOutlined class="asset-icon" /> <TagOutlined class="asset-icon" />
</div> </div> -->
<div class="asset-content"> <div class="asset-content">
<div class="asset-name">我的权益</div> <div class="asset-name">我的权益</div>
<div class="rights-info"> <div class="rights-info">
@ -155,7 +142,7 @@
<span class="rights-text">算力点</span> <span class="rights-text">算力点</span>
</div> </div>
<div class="rights-value"> <div class="rights-value">
<span class="rights-amount">{{ userInfo.computingPowerPoint}}</span> <span class="rights-amount">{{ userInfo.computingPowerPoint }}</span>
<span class="rights-unit"></span> <span class="rights-unit"></span>
</div> </div>
</div> </div>
@ -306,12 +293,15 @@ const goToInvoice = () => {
background: #fff; background: #fff;
} }
.gpu-card {
background: linear-gradient(180deg, rgba(250, 252, 255, 1) 0%, rgba(255, 255, 255, 1) 100%);
}
.margin-top { .margin-top {
margin-top: 20px; margin-top: 20px;
} }
/* 实例卡片样式 */ /* 实例卡片样式 */
.stats-column { .stats-column {
display: flex; display: flex;
@ -395,7 +385,9 @@ const goToInvoice = () => {
} }
.status-text { .status-text {
width: 100%;
flex: 1; flex: 1;
text-align: center;
} }
.status-title { .status-title {
@ -413,10 +405,8 @@ const goToInvoice = () => {
} }
.invite-actions { .invite-actions {
display: flex; width: 100%;
align-items: center; text-align: center;
gap: 16px;
margin-top: 8px;
} }
.generate-btn { .generate-btn {
@ -689,14 +679,16 @@ const goToInvoice = () => {
/* 算力点特殊样式 */ /* 算力点特殊样式 */
.rights-item:first-child { .rights-item:first-child {
.rights-amount { .rights-amount {
color: #fa8c16; /* 算力点用橙色 */ color: #fa8c16;
/* 算力点用橙色 */
} }
} }
/* 算力券特殊样式 */ /* 算力券特殊样式 */
.rights-item:last-child { .rights-item:last-child {
.rights-amount { .rights-amount {
color: #1890ff; /* 算力券用蓝色 */ color: #1890ff;
/* 算力券用蓝色 */
} }
} }
@ -731,6 +723,7 @@ const goToInvoice = () => {
.nav-account { .nav-account {
padding-left: 10px; padding-left: 10px;
margin-top: -20px;
:first-child { :first-child {
font-weight: 500; font-weight: 500;
@ -767,7 +760,7 @@ const goToInvoice = () => {
height: 20px; height: 20px;
font-size: 10px; font-size: 10px;
padding: 2px 5px; padding: 2px 5px;
margin-top: 42px; margin-top: 30px;
margin-left: 10px; margin-left: 10px;
border-radius: 5px; border-radius: 5px;
border: 1px solid rgba(166, 166, 166, 1); border: 1px solid rgba(166, 166, 166, 1);