Compare commits
2 Commits
4330584af3
...
d440ad0008
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d440ad0008 | ||
|
|
e50e03dcc6 |
2
.env.dev
2
.env.dev
@ -2,5 +2,5 @@
|
||||
NODE_ENV=development
|
||||
|
||||
# api
|
||||
VITE_API_BASIC="http://10.10.1.35:8888"
|
||||
VITE_API_BASIC="http://10.10.1.32:8888"
|
||||
|
||||
|
||||
@ -22,3 +22,9 @@ export const getRecommendList = () => request.get('/v1/voucher/voucher_list')
|
||||
|
||||
//获取消息列表
|
||||
export const getMessageList = (params:any) => request.get('/v1/message/message_list', { params })
|
||||
|
||||
//验证码合法性
|
||||
export const CodeAuth=(params:any)=>request.put("/v1/auth/update_password_auth",params)
|
||||
|
||||
//提现
|
||||
export const tixian=(params:any)=>request.put("/v1/balance/withdraw",params)
|
||||
@ -57,11 +57,6 @@ interface MenuItem {
|
||||
}
|
||||
|
||||
const menuItems: MenuItem[] = [
|
||||
{ path: '/controlPanel/overview', name: '总览', icon: HomeOutlined },
|
||||
{ path: '/controlPanel/container', name: '容器实例', icon: ConsoleSqlOutlined },
|
||||
// { path: '/controlPanel/fileStore', name: '文件存储', icon: FolderOpenOutlined },
|
||||
{ path: '/controlPanel/image', name: '镜像', icon: GlobalOutlined },
|
||||
{ path: '/controlPanel/publicData', name: '公开数据', icon: LaptopOutlined },
|
||||
{
|
||||
path: '/contract',
|
||||
name: '费用中心',
|
||||
@ -80,7 +75,12 @@ const menuItems: MenuItem[] = [
|
||||
{ path: '/accountHistory', name: '访问记录' },
|
||||
// { path: '/controlPanel/account/security', name: '安全设置' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ path: '/controlPanel/container', name: '容器实例', icon: ConsoleSqlOutlined },
|
||||
// { path: '/controlPanel/fileStore', name: '文件存储', icon: FolderOpenOutlined },
|
||||
{ path: '/controlPanel/image', name: '镜像', icon: GlobalOutlined },
|
||||
{ path: '/controlPanel/publicData', name: '公开数据', icon: LaptopOutlined },
|
||||
|
||||
]
|
||||
|
||||
const selectedKeys = computed(() => [route.path])
|
||||
|
||||
@ -1,17 +1,19 @@
|
||||
// src/utils/request.ts
|
||||
import axios, { AxiosInstance, InternalAxiosRequestConfig } from 'axios';
|
||||
|
||||
import axios, { AxiosInstance, InternalAxiosRequestConfig } from "axios";
|
||||
import { message } from "ant-design-vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
// 从环境变量读取基础 URL
|
||||
const BASE_URL = import.meta.env.VITE_API_BASIC
|
||||
console.log('API Basic URL:',import.meta.env.VITE_API_BASIC);
|
||||
console.log('All env:', import.meta.env);
|
||||
const BASE_URL = import.meta.env.VITE_API_BASIC;
|
||||
console.log("API Basic URL:", import.meta.env.VITE_API_BASIC);
|
||||
console.log("All env:", import.meta.env);
|
||||
const router = useRouter();
|
||||
// 创建 axios 实例
|
||||
const request: AxiosInstance = axios.create({
|
||||
baseURL: BASE_URL,
|
||||
timeout: 10000, // 10 秒超时
|
||||
withCredentials: false, // 跨域请求时发送 cookies
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
@ -19,7 +21,7 @@ const request: AxiosInstance = axios.create({
|
||||
request.interceptors.request.use(
|
||||
(config: InternalAxiosRequestConfig) => {
|
||||
// 例如:从 localStorage 获取 token
|
||||
const token = localStorage.getItem('token');
|
||||
const token = localStorage.getItem("token");
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
@ -33,22 +35,31 @@ request.interceptors.request.use(
|
||||
// 响应拦截器(统一处理错误、code 等)
|
||||
request.interceptors.response.use(
|
||||
(response) => {
|
||||
|
||||
console.log("response", response);
|
||||
// 假设后端返回格式为 { code: 200, data: ..., message: '' }
|
||||
const { code, data, message } = response.data;
|
||||
console.log('Response Data:', response.data);
|
||||
console.log("Response Data:", response.data);
|
||||
if (code === 1) {
|
||||
return data;
|
||||
return data??code;
|
||||
} else {
|
||||
// 可抛出业务错误
|
||||
return Promise.reject(new Error(message || '请求失败'));
|
||||
return Promise.reject(new Error(message || "请求失败"));
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
// 网络错误 or 超时等
|
||||
|
||||
console.log(error);
|
||||
const res = error.response;
|
||||
if (res.status === 401) {
|
||||
message.error("登录已过期,请重新登录");
|
||||
localStorage.clear();
|
||||
setTimeout(() => {
|
||||
window.location.href = "/login";
|
||||
}, 3000);
|
||||
} else {
|
||||
return Promise.reject(error.response.data);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export default request;
|
||||
@ -16,13 +16,18 @@
|
||||
</div>
|
||||
</a-upload>
|
||||
</div>
|
||||
<div class="info"><span>账户</span><span>17044054908</span></div>
|
||||
<div class="info"><span>账户ID</span><span>123456789123456789</span></div>
|
||||
<div class="info"><span>账户</span><span>{{ userInfo.phone }}</span></div>
|
||||
<div class="info"><span>账户ID</span><span>{{ userInfo.id }}</span></div>
|
||||
<div class="info" style="display: flex;justify-content: space-between;">
|
||||
<div>
|
||||
<div v-if="userInfo.certificationStatus !== 'CERTIFICATION_PASSED'">
|
||||
<span style="margin-right: 25px;">认证类型</span><span style="color: red;">未实名认证</span>
|
||||
</div>
|
||||
<div style="color:#1677ff;">前往认证</div>
|
||||
<div style="color:#1677ff;" v-if="userInfo.certificationStatus !== 'CERTIFICATION_PASSED'">前往认证
|
||||
</div>
|
||||
<div v-if="userInfo.certificationStatus == 'CERTIFICATION_PASSED'">
|
||||
<span style="margin-right: 25px;">认证类型</span><span>{{ certificationInfo.certificationType
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
</a-col>
|
||||
@ -30,38 +35,30 @@
|
||||
<a-card title="安全设置">
|
||||
<div class="info" style="display: flex;justify-content: space-between;">
|
||||
<div>
|
||||
<span style="margin-right: 25px;">手机号</span><span>{{ currentPhone }}</span>
|
||||
<span style="margin-right: 38px;width: 80px;">手机号</span><span>{{ userInfo.phone }}</span>
|
||||
</div>
|
||||
<div style="color:#1677ff;" @click="handleModifyPhone">修改</div>
|
||||
|
||||
</div>
|
||||
<div class="info" style="display: flex;justify-content: space-between;">
|
||||
<div>
|
||||
<span style="margin-right: 25px;">绑定微信</span><span style="color: #666;">未绑定微信</span>
|
||||
</div>
|
||||
<div style="color:#1677ff;">绑定</div>
|
||||
<div style="color:#1677ff;cursor: pointer;">绑定</div>
|
||||
</div>
|
||||
<div class="info" style="display: flex;justify-content: space-between;">
|
||||
<div>
|
||||
<span style="margin-right: 25px;">登录密码</span><span>********</span>
|
||||
<span style="margin-right: 25px;cursor: pointer;">登录密码</span><span>********</span>
|
||||
</div>
|
||||
<div style="color:#1677ff;" @click="handleModifyPassword">修改</div>
|
||||
<div style="color:#1677ff;cursor: pointer;" @click="handleModifyPassword">修改</div>
|
||||
</div>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<!-- 第一步:身份验证对话框(共用) -->
|
||||
<a-modal
|
||||
v-model:visible="verifyVisible"
|
||||
title="身份验证"
|
||||
@ok="handleVerify"
|
||||
@cancel="handleCancelVerify"
|
||||
:maskClosable="false"
|
||||
:width="480"
|
||||
:ok-button-props="{ disabled: !isVerificationValid }"
|
||||
:confirmLoading="verifying"
|
||||
okText="下一步"
|
||||
>
|
||||
<a-modal v-model:visible="verifyVisible" title="身份验证" @ok="handleVerify" @cancel="handleCancelVerify"
|
||||
:maskClosable="false" :width="480" :ok-button-props="{ disabled: !isVerificationValid }"
|
||||
:confirmLoading="verifying" okText="下一步">
|
||||
<div class="verify-content">
|
||||
<!-- 安全提示 -->
|
||||
<div class="security-tip">
|
||||
@ -77,7 +74,7 @@
|
||||
<div class="phone-label">验证手机号</div>
|
||||
<div class="phone-number">
|
||||
<!-- <span class="phone-icon">📱</span> -->
|
||||
<span class="phone-text">{{ maskedPhone }}</span>
|
||||
<span class="phone-text">{{ userInfo.phone }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -85,19 +82,10 @@
|
||||
<div class="verification-code">
|
||||
<div class="code-label">验证码</div>
|
||||
<div class="code-input-group">
|
||||
<a-input
|
||||
v-model:value="verificationCode"
|
||||
placeholder="请输入6位验证码"
|
||||
:maxlength="6"
|
||||
@input="handleCodeInput"
|
||||
class="code-input"
|
||||
/>
|
||||
<a-button
|
||||
type="link"
|
||||
@click="sendVerificationCode"
|
||||
:disabled="countdown > 0 || sendingCode"
|
||||
class="send-code-btn"
|
||||
>
|
||||
<a-input v-model:value="verificationCode" placeholder="请输入6位验证码" :maxlength="6"
|
||||
@input="handleCodeInput" class="code-input" />
|
||||
<a-button type="link" @click="sendVerificationCode" :disabled="countdown > 0 || sendingCode"
|
||||
class="send-code-btn">
|
||||
{{ countdownText }}
|
||||
</a-button>
|
||||
</div>
|
||||
@ -112,16 +100,9 @@
|
||||
</a-modal>
|
||||
|
||||
<!-- 第二步:修改手机号对话框 -->
|
||||
<a-modal
|
||||
v-model:visible="changePhoneVisible"
|
||||
title="修改手机号"
|
||||
@ok="handleChangePhone"
|
||||
@cancel="handleCancelChangePhone"
|
||||
:maskClosable="false"
|
||||
:width="480"
|
||||
:ok-button-props="{ disabled: !isChangeValid }"
|
||||
:confirmLoading="changing"
|
||||
>
|
||||
<a-modal v-model:visible="changePhoneVisible" title="修改手机号" @ok="handleChangePhone"
|
||||
@cancel="handleCancelChangePhone" :maskClosable="false" :width="480"
|
||||
:ok-button-props="{ disabled: !isChangeValid }" :confirmLoading="changing">
|
||||
<div class="change-phone-content">
|
||||
<!-- 安全提示 -->
|
||||
<div class="security-tip">
|
||||
@ -134,13 +115,8 @@
|
||||
<!-- 新手机号输入 -->
|
||||
<div class="new-phone-section">
|
||||
<div class="input-label">新手机号</div>
|
||||
<a-input
|
||||
v-model:value="newPhoneNumber"
|
||||
placeholder="请输入新手机号"
|
||||
:maxlength="11"
|
||||
@input="handlePhoneInput"
|
||||
class="phone-input"
|
||||
/>
|
||||
<a-input v-model:value="newPhoneNumber" placeholder="请输入新手机号" :maxlength="11"
|
||||
@input="handlePhoneInput" class="phone-input" />
|
||||
<div v-if="phoneError" class="input-error">{{ phoneError }}</div>
|
||||
</div>
|
||||
|
||||
@ -148,19 +124,10 @@
|
||||
<div class="verification-code">
|
||||
<div class="code-label">验证码</div>
|
||||
<div class="code-input-group">
|
||||
<a-input
|
||||
v-model:value="newVerificationCode"
|
||||
placeholder="请输入6位验证码"
|
||||
:maxlength="6"
|
||||
@input="handleNewCodeInput"
|
||||
class="code-input"
|
||||
/>
|
||||
<a-button
|
||||
type="link"
|
||||
@click="sendNewVerificationCode"
|
||||
:disabled="newCountdown > 0 || sendingNewCode"
|
||||
class="send-code-btn"
|
||||
>
|
||||
<a-input v-model:value="newVerificationCode" placeholder="请输入6位验证码" :maxlength="6"
|
||||
@input="handleNewCodeInput" class="code-input" />
|
||||
<a-button type="link" @click="sendNewVerificationCode"
|
||||
:disabled="newCountdown > 0 || sendingNewCode" class="send-code-btn">
|
||||
{{ newCountdownText }}
|
||||
</a-button>
|
||||
</div>
|
||||
@ -170,16 +137,9 @@
|
||||
</a-modal>
|
||||
|
||||
<!-- 修改密码对话框 -->
|
||||
<a-modal
|
||||
v-model:visible="changePasswordVisible"
|
||||
title="修改密码"
|
||||
@ok="handleChangePassword"
|
||||
@cancel="handleCancelChangePassword"
|
||||
:maskClosable="false"
|
||||
:width="480"
|
||||
:ok-button-props="{ disabled: !isPasswordValid }"
|
||||
:confirmLoading="changingPassword"
|
||||
>
|
||||
<a-modal v-model:visible="changePasswordVisible" title="修改密码" @ok="handleChangePassword"
|
||||
@cancel="handleCancelChangePassword" :maskClosable="false" :width="480"
|
||||
:ok-button-props="{ disabled: !isPasswordValid }" :confirmLoading="changingPassword">
|
||||
<div class="change-password-content">
|
||||
<!-- 安全提示 -->
|
||||
<div class="security-tip">
|
||||
@ -192,26 +152,16 @@
|
||||
<!-- 原密码输入 -->
|
||||
<div class="password-section">
|
||||
<div class="input-label">原密码</div>
|
||||
<a-input-password
|
||||
v-model:value="oldPassword"
|
||||
placeholder="请输入原密码"
|
||||
@input="handleOldPasswordInput"
|
||||
class="password-input"
|
||||
:visibilityToggle="true"
|
||||
/>
|
||||
<a-input-password v-model:value="oldPassword" placeholder="请输入原密码" @input="handleOldPasswordInput"
|
||||
class="password-input" :visibilityToggle="true" />
|
||||
<div v-if="oldPasswordError" class="input-error">{{ oldPasswordError }}</div>
|
||||
</div>
|
||||
|
||||
<!-- 新密码输入 -->
|
||||
<div class="password-section">
|
||||
<div class="input-label">新密码</div>
|
||||
<a-input-password
|
||||
v-model:value="newPassword"
|
||||
placeholder="请输入新密码(6-20位字符)"
|
||||
@input="handleNewPasswordInput"
|
||||
class="password-input"
|
||||
:visibilityToggle="true"
|
||||
/>
|
||||
<a-input-password v-model:value="newPassword" placeholder="请输入新密码(6-20位字符)"
|
||||
@input="handleNewPasswordInput" class="password-input" :visibilityToggle="true" />
|
||||
<div v-if="newPasswordError" class="input-error">{{ newPasswordError }}</div>
|
||||
<div class="password-tip">
|
||||
<div class="tip-item" :class="{ 'valid': passwordStrength.lengthValid }">
|
||||
@ -232,13 +182,8 @@
|
||||
<!-- 确认密码输入 -->
|
||||
<div class="password-section">
|
||||
<div class="input-label">确认密码</div>
|
||||
<a-input-password
|
||||
v-model:value="confirmPassword"
|
||||
placeholder="请再次输入新密码"
|
||||
@input="handleConfirmPasswordInput"
|
||||
class="password-input"
|
||||
:visibilityToggle="true"
|
||||
/>
|
||||
<a-input-password v-model:value="confirmPassword" placeholder="请再次输入新密码"
|
||||
@input="handleConfirmPasswordInput" class="password-input" :visibilityToggle="true" />
|
||||
<div v-if="confirmPasswordError" class="input-error">{{ confirmPasswordError }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -251,7 +196,9 @@ import { ref, computed, onUnmounted, watch,onBeforeMount } from 'vue';
|
||||
import { LoadingOutlined, PlusOutlined } from '@ant-design/icons-vue';
|
||||
import { message, Modal as AModal, Input as AInput, InputPassword as AInputPassword, Button as AButton } from 'ant-design-vue';
|
||||
import { certificationInfoApi } from '@/apis/certification';
|
||||
|
||||
import { CodeAuth } from '@/apis/home'
|
||||
import { updatePassword } from '@/apis/modules/login'
|
||||
import router from '@/router';
|
||||
const loading = ref(false);
|
||||
const imageUrl = ref<string | null>("https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png");
|
||||
const fileList = ref<any[]>([{ url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png' }]);
|
||||
@ -259,7 +206,6 @@ const userInfo=ref<any>({})
|
||||
const certificationInfo = ref<any>({})
|
||||
// 操作类型:修改手机号或修改密码
|
||||
const operationType = ref<'phone' | 'password'>('phone');
|
||||
|
||||
// 第一步:身份验证相关状态(共用)
|
||||
const verifyVisible = ref(false);
|
||||
const verificationCode = ref('');
|
||||
@ -288,7 +234,7 @@ const oldPasswordError = ref('');
|
||||
const newPasswordError = ref('');
|
||||
const confirmPasswordError = ref('');
|
||||
const changingPassword = ref(false);
|
||||
|
||||
const successCode = ref('')
|
||||
// 用户当前绑定的手机号
|
||||
const currentPhone = ref('17044054908');
|
||||
|
||||
@ -509,25 +455,23 @@ const handleVerify = async () => {
|
||||
codeError.value = '请输入有效的6位验证码';
|
||||
return;
|
||||
}
|
||||
|
||||
verifying.value = true;
|
||||
|
||||
try {
|
||||
// 模拟API验证
|
||||
await new Promise(resolve => setTimeout(resolve, 1500));
|
||||
|
||||
// 假设验证成功
|
||||
message.success('身份验证成功');
|
||||
|
||||
// 关闭身份验证对话框
|
||||
const res: any = await CodeAuth({ code: verificationCode.value, phone: userInfo.value.phone })
|
||||
console.log(res)
|
||||
if (res) {
|
||||
successCode.value = res.success_code
|
||||
verifyVisible.value = false;
|
||||
|
||||
// 根据操作类型打开相应的下一步对话框
|
||||
if (operationType.value === 'phone') {
|
||||
showChangePhoneDialog();
|
||||
} else if (operationType.value === 'password') {
|
||||
showChangePasswordDialog();
|
||||
}
|
||||
} else {
|
||||
message.error("验证码无效")
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
codeError.value = '验证码错误,请重新输入';
|
||||
@ -687,6 +631,7 @@ const handleChangePhone = async () => {
|
||||
|
||||
// 显示修改密码对话框
|
||||
const showChangePasswordDialog = () => {
|
||||
console.log(111)
|
||||
// 重置状态
|
||||
oldPassword.value = '';
|
||||
newPassword.value = '';
|
||||
@ -768,16 +713,17 @@ const handleChangePassword = async () => {
|
||||
changingPassword.value = true;
|
||||
|
||||
try {
|
||||
// 模拟API调用修改密码
|
||||
await new Promise(resolve => setTimeout(resolve, 1500));
|
||||
|
||||
const res = await updatePassword({ confirm_password: confirmPassword.value, new_password: newPassword.value, old_password: oldPassword.value, success_code: successCode.value })
|
||||
if (res) {
|
||||
// 关闭对话框
|
||||
changePasswordVisible.value = false;
|
||||
|
||||
// 重置所有状态
|
||||
resetPasswordStates();
|
||||
|
||||
message.success('密码修改成功');
|
||||
localStorage.clear()
|
||||
router.replace('/login')
|
||||
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
oldPasswordError.value = '原密码错误或修改失败';
|
||||
|
||||
@ -4,16 +4,13 @@
|
||||
<a-row :gutter="24" class="asset-cards">
|
||||
<!-- 左侧:可用余额卡片 -->
|
||||
<a-col :span="8">
|
||||
<a-card :bordered="false" class="card balance-card">
|
||||
<div class="fee-header">
|
||||
<div class="fee-title">可用余额</div>
|
||||
<a-button type="link" size="small" class="fee-titleb" @click="goToBills">查看消费明细</a-button>
|
||||
</div>
|
||||
<a-divider />
|
||||
<div class="money">¥ {{ formatAmount(balance) }}</div>
|
||||
<a-card :bordered="false" class="card balance-card" title="可用余额">
|
||||
<template #extra><a-button type="link" size="small" class="fee-titleb"
|
||||
@click="goToBills">查看消费明细</a-button></template>
|
||||
<div class="money">¥ {{ formatAmount(userInfo.balance || 0) }}</div>
|
||||
<div class="money-btn">
|
||||
<div><a-button type="primary" size="small" @click="goToRecharge">充值</a-button></div>
|
||||
<div><a-button size="small">提现</a-button></div>
|
||||
<div><a-button size="small" @click="dialogWithDrawal = true">提现</a-button></div>
|
||||
</div>
|
||||
</a-card>
|
||||
</a-col>
|
||||
@ -24,8 +21,8 @@
|
||||
<a-card title="算力点" :bordered="false" class="card computing-card">
|
||||
<div class="computing-content">
|
||||
<div class="computing-amount">
|
||||
<span class="amount-value">{{ formatComputingPoints(computingPoints) }}</span>
|
||||
<span class="amount-unit">点</span>
|
||||
<span class="amount-value">{{ '¥' + formatAmount(userInfo.computingPowerPoint || 0) }}</span>
|
||||
<!-- <span class="amount-unit">点</span> -->
|
||||
</div>
|
||||
<div class="computing-actions">
|
||||
<a-button type="primary" size="small" @click="goToExchange">去兑换</a-button>
|
||||
@ -37,7 +34,7 @@
|
||||
<a-card title="算力券" :bordered="false" class="card coupon-card">
|
||||
<div class="coupon-content">
|
||||
<div class="coupon-amount">
|
||||
<span class="amount-value">{{ availableCoupons }}</span>
|
||||
<span class="amount-value">{{ userInfo.voucherNum }}</span>
|
||||
<span class="amount-unit">张</span>
|
||||
</div>
|
||||
<div class="coupon-actions">
|
||||
@ -51,29 +48,11 @@
|
||||
<!-- 底部账单区域 -->
|
||||
<div class="bill-section">
|
||||
<div class="bill-header">
|
||||
<h3 class="bill-title">账单明细</h3>
|
||||
<div class="date-range">
|
||||
<span class="date-label">日期范围:</span>
|
||||
<a-range-picker
|
||||
v-model:value="dateRange"
|
||||
:placeholder="['开始时间', '结束时间']"
|
||||
@change="handleDateChange"
|
||||
style="width: 250px;"
|
||||
/>
|
||||
<h3 class="bill-title">消费明细</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 账单表格 -->
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data-source="billData"
|
||||
:pagination="pagination"
|
||||
@change="handleTableChange"
|
||||
:loading="loading"
|
||||
class="bill-table"
|
||||
:scroll="{ x: 1200 }"
|
||||
|
||||
>
|
||||
<a-table :columns="columns" :data-source="billData" :pagination="pagination" @change="handleTableChange"
|
||||
:loading="loading" class="bill-table" :scroll="{ x: 1200 }">
|
||||
<!-- 流水号列 -->
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'serialNumber'">
|
||||
@ -88,7 +67,8 @@
|
||||
</template>
|
||||
|
||||
<!-- 金额相关列 -->
|
||||
<template v-else-if="['transactionAmount', 'originalPrice', 'discountAmount', 'balancePayment', 'voucherDeduction'].includes(column.key)">
|
||||
<template
|
||||
v-else-if="['transactionAmount', 'originalPrice', 'discountAmount', 'balancePayment', 'voucherDeduction'].includes(column.key)">
|
||||
<span :class="{
|
||||
'amount-positive': record[column.key] > 0,
|
||||
'amount-negative': record[column.key] < 0
|
||||
@ -100,25 +80,29 @@
|
||||
</a-table>
|
||||
</div>
|
||||
</div>
|
||||
<a-modal v-model:open="dialogWithDrawal" title="提现" @ok="handleOk">
|
||||
<a-card>
|
||||
<div style="display: flex;justify-content: flex-start;align-items: center;">
|
||||
<span style="width: 120px;">提现金额:</span>
|
||||
<a-input-number id="inputNumber" v-model:value="withDrawalCount" placeholder="请输入提现金额" style="width: 100%;"/>
|
||||
<a-button type="link" @click="withDrawalCount=userInfo.balance" :loading="btnLoading">全部提现</a-button>
|
||||
</div>
|
||||
</a-card>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, computed } from 'vue'
|
||||
import {
|
||||
message,
|
||||
TableProps
|
||||
} from 'ant-design-vue'
|
||||
import { ref, onMounted, computed, } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import {message,TableProps} from 'ant-design-vue'
|
||||
import type { Dayjs } from 'dayjs'
|
||||
import router from '@/router'
|
||||
|
||||
import{tixian} from "@/apis/home"
|
||||
import { fetchUserInfo } from '@/apis/modules/login';
|
||||
const router = useRouter()
|
||||
// 资产数据
|
||||
const balance = ref<number>(5.00)
|
||||
const computingPoints = ref<number>(1023)
|
||||
const availableCoupons = ref<number>(3)
|
||||
|
||||
// 日期范围选择
|
||||
const dateRange = ref<[Dayjs, Dayjs]>()
|
||||
|
||||
const btnLoading=ref(false)
|
||||
const dialogWithDrawal = ref(false)
|
||||
const withDrawalCount = ref(0)
|
||||
// 表格数据
|
||||
interface BillRecord {
|
||||
key: string
|
||||
@ -134,6 +118,7 @@ interface BillRecord {
|
||||
}
|
||||
|
||||
const loading = ref(false)
|
||||
const userInfo = ref<any>({})
|
||||
const billData = ref<BillRecord[]>([])
|
||||
const pagination = ref({
|
||||
current: 1,
|
||||
@ -173,12 +158,19 @@ const columns = computed(() => [
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '产品名称',
|
||||
title: '收支类型',
|
||||
dataIndex: 'productName',
|
||||
key: 'productName',
|
||||
width: 150,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: '交易渠道',
|
||||
dataIndex: 'transactionAmount',
|
||||
key: 'transactionAmount',
|
||||
width: 120,
|
||||
align: 'right'
|
||||
},
|
||||
{
|
||||
title: '交易金额',
|
||||
dataIndex: 'transactionAmount',
|
||||
@ -187,28 +179,14 @@ const columns = computed(() => [
|
||||
align: 'right'
|
||||
},
|
||||
{
|
||||
title: '原价',
|
||||
dataIndex: 'originalPrice',
|
||||
key: 'originalPrice',
|
||||
width: 120,
|
||||
align: 'right'
|
||||
},
|
||||
{
|
||||
title: '优惠金额',
|
||||
dataIndex: 'discountAmount',
|
||||
key: 'discountAmount',
|
||||
width: 120,
|
||||
align: 'right'
|
||||
},
|
||||
{
|
||||
title: '余额支付',
|
||||
title: '账户余额',
|
||||
dataIndex: 'balancePayment',
|
||||
key: 'balancePayment',
|
||||
width: 120,
|
||||
align: 'right'
|
||||
},
|
||||
{
|
||||
title: '代金券抵扣',
|
||||
title: '备注',
|
||||
dataIndex: 'voucherDeduction',
|
||||
key: 'voucherDeduction',
|
||||
width: 120,
|
||||
@ -218,6 +196,10 @@ const columns = computed(() => [
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
const userInfoStr = localStorage.getItem('userInfo');
|
||||
if (userInfoStr) {
|
||||
userInfo.value = JSON.parse(userInfoStr);
|
||||
}
|
||||
fetchBillData()
|
||||
})
|
||||
|
||||
@ -358,7 +340,7 @@ const goToBills = () => {
|
||||
}
|
||||
|
||||
const goToCoupons = () => {
|
||||
router.push('/rights')
|
||||
router.push('/layout/admin/myCertificate')
|
||||
}
|
||||
|
||||
const goToExchange = () => {
|
||||
@ -366,6 +348,21 @@ const goToExchange = () => {
|
||||
// 这里应该实现跳转到兑换页面的逻辑
|
||||
router.push('/layout/admin/exchange')
|
||||
}
|
||||
const handleOk=async ()=>{
|
||||
try {
|
||||
btnLoading.value=true
|
||||
const res=await tixian({amount:withDrawalCount.value})
|
||||
if(res){
|
||||
message.success("提现成功")
|
||||
const userRes = await fetchUserInfo();
|
||||
localStorage.setItem('userInfo', JSON.stringify(userRes));
|
||||
}
|
||||
btnLoading.value=false
|
||||
} catch (error:any) {
|
||||
message.error(error)
|
||||
btnLoading.value=false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -378,7 +375,8 @@ const goToExchange = () => {
|
||||
.asset-cards {
|
||||
margin-bottom: 24px;
|
||||
|
||||
.ant-col-8, .ant-col-16 {
|
||||
.ant-col-8,
|
||||
.ant-col-16 {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
@ -422,6 +420,7 @@ const goToExchange = () => {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
background: linear-gradient(90deg, rgba(240, 245, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
}
|
||||
|
||||
.fee-titleb {
|
||||
@ -438,19 +437,18 @@ const goToExchange = () => {
|
||||
.money {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: #1890ff;
|
||||
text-align: center;
|
||||
color: #000000;
|
||||
text-align: left;
|
||||
margin: 20px 0 30px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.money-btn {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
justify-content: flex-end;
|
||||
gap: 16px;
|
||||
|
||||
div {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
|
||||
:deep(.ant-btn) {
|
||||
@ -484,7 +482,8 @@ const goToExchange = () => {
|
||||
}
|
||||
|
||||
// 右侧算力点卡片
|
||||
.computing-card, .coupon-card {
|
||||
.computing-card,
|
||||
.coupon-card {
|
||||
margin-bottom: 16px;
|
||||
|
||||
&:last-child {
|
||||
@ -492,17 +491,17 @@ const goToExchange = () => {
|
||||
}
|
||||
}
|
||||
|
||||
.computing-content, .coupon-content {
|
||||
.computing-content,
|
||||
.coupon-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px 0;
|
||||
justify-content: space-between;
|
||||
// padding: 20px 0;
|
||||
|
||||
.amount-value {
|
||||
font-size: 36px;
|
||||
font-weight: 600;
|
||||
color: #1890ff; // 统一改为蓝色
|
||||
color: #000000; // 统一改为蓝色
|
||||
line-height: 1;
|
||||
margin-right: 8px;
|
||||
}
|
||||
@ -513,8 +512,9 @@ const goToExchange = () => {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.computing-actions, .coupon-actions {
|
||||
margin-top: 24px;
|
||||
.computing-actions,
|
||||
.coupon-actions {
|
||||
// margin-top: 24px;
|
||||
|
||||
:deep(.ant-btn) {
|
||||
width: 100px;
|
||||
@ -645,7 +645,9 @@ const goToExchange = () => {
|
||||
}
|
||||
|
||||
.asset-cards {
|
||||
.ant-col-8, .ant-col-16 {
|
||||
|
||||
.ant-col-8,
|
||||
.ant-col-16 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@ -672,7 +674,8 @@ const goToExchange = () => {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.computing-content, .coupon-content {
|
||||
.computing-content,
|
||||
.coupon-content {
|
||||
.amount-value {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
@ -3,7 +3,8 @@
|
||||
<div class="real-name-auth-page">
|
||||
<div class="header">
|
||||
<h1>实名认证</h1>
|
||||
<p>请选择您的认证类型</p>
|
||||
<p v-if="userInfo.certificationStatus==='PENDING_CERTIFICATION'">请选择您的认证类型</p>
|
||||
<p v-if="userInfo.certificationStatus==='CERTIFICATION_PASSED'">Fast亼算云严格遵守国家相关个人信息隐私保护规定,并不存储使用您的个人信息,查看<span style="color:#1677ff;cursor: pointer;">实名认证协议</span> </p>
|
||||
</div>
|
||||
<div v-if="userInfo.certificationStatus==='CERTIFICATION_DFFILED'">认证审核中...</div>
|
||||
<div v-if="userInfo.certificationStatus==='CERTIFICATION_FAILED'">认证失败</div>
|
||||
@ -16,15 +17,15 @@
|
||||
<div class="auth-explanation" style="display: flex;justify-content: flex-start;gap: 100px;">
|
||||
<div>
|
||||
<p><span>认证类型</span> <span>{{ certificationInfo.certificationType }}</span></p>
|
||||
<p><span>认证类型</span> <span></span><span>{{ certificationInfo.idCard }}</span></p>
|
||||
<p><span>证件类型</span> <span></span><span>{{ certificationInfo.documentType }}</span></p>
|
||||
<p><span>认证人</span> <span></span><span>{{ certificationInfo.name }}</span></p>
|
||||
<p>
|
||||
<a-button type="primary">变更为企业认证</a-button>
|
||||
<a-button type="primary" v-if="certificationInfo.certificationType==='个人认证'" @click="transOpen=true">变更为企业认证</a-button>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p><span>认证时间</span><span>2025-11-18</span></p>
|
||||
<p><span>身份证号</span><span>放假就佛法家</span></p>
|
||||
<p><span>认证时间</span><span>{{ certificationInfo.certificationTime }}</span></p>
|
||||
<p><span>身份证号</span><span>{{ certificationInfo.idCard }}</span></p>
|
||||
<!-- <p><span>认证人</span><span>用户名</span></p> -->
|
||||
</div>
|
||||
<div>
|
||||
@ -86,6 +87,14 @@
|
||||
</a-card>
|
||||
</div>
|
||||
</div>
|
||||
<a-modal v-model:open="transOpen" title="变更须知">
|
||||
<a-card>
|
||||
<p>1.您正在进行个人实名认证变更为企业实名认证操作,变更后账号以及账号下资产将属于新的认证企业。</p>
|
||||
<p>2. 请知悉升级企业实名认证后,该账号将无法再变更回个人实名认证,请您谨慎操作。</p>
|
||||
<p><a-checkbox v-model:checked="checked">我已仔细阅读并代表同意 <span style="color: #1677ff;cursor: pointer;">《申请账号主体变更协议》</span></a-checkbox></p>
|
||||
<a-button type="primary" @click="goEnterRealAuth" :disabled="!checked">下一步</a-button>
|
||||
</a-card>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -104,6 +113,8 @@ import{certificationInfoApi} from '@/apis/certification';
|
||||
const router = useRouter();
|
||||
const certificationInfo = ref<any>({
|
||||
});
|
||||
const checked=ref(false)
|
||||
const transOpen=ref(false)
|
||||
const userInfo=ref<any>({
|
||||
certificationStatus:'PENDING_CERTIFICATION'
|
||||
});
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<div class="admin-layout">
|
||||
<div style="background-color: #ffffff;display: flex;flex-direction: column;align-items: center;border-right: 1px solid #e8e8e8;">
|
||||
<div style="height: 70px;width: 90%;display: flex;justify-content: center;border-bottom: 1px solid #e8e8e8;align-items: center;">
|
||||
<div
|
||||
style="background-color: #ffffff;display: flex;flex-direction: column;align-items: center;border-right: 1px solid #e8e8e8;">
|
||||
<div
|
||||
style="height: 70px;width: 90%;display: flex;justify-content: center;border-bottom: 1px solid #e8e8e8;align-items: center;">
|
||||
<a-button type="primary" style="width: 200px;" @click="router.push('/layout/admin/home')">
|
||||
<template #icon>
|
||||
<AppstoreAddOutlined />
|
||||
@ -53,9 +55,8 @@ interface MenuItem {
|
||||
}
|
||||
|
||||
const menuItems: MenuItem[] = [
|
||||
{ path: '/layout/admin/home', name: '总览', icon: HomeOutlined, visible: true },
|
||||
{ path: '/layout/admin/instance', name: '容器实例', icon: ConsoleSqlOutlined, visible: true },
|
||||
{ path: '/layout/admin/image', name: '镜像', icon: GlobalOutlined, visible: true },
|
||||
// { path: '/layout/admin/home', name: '总览', icon: HomeOutlined, visible: true },
|
||||
|
||||
{
|
||||
path: '',
|
||||
name: '费用中心',
|
||||
@ -94,6 +95,10 @@ const menuItems: MenuItem[] = [
|
||||
{ path: '/layout/admin/invoices', name: '发票抬头管理', visible: true },
|
||||
],
|
||||
},
|
||||
{ path: '/layout/admin/image', name: '镜像管理', icon: GlobalOutlined, visible: true },
|
||||
{ path: '/layout/admin/instance', name: '实例管理', icon: ConsoleSqlOutlined, visible: true },
|
||||
{ path: '/layout/admin/instance', name: '存储管理', icon: ConsoleSqlOutlined, visible: true },
|
||||
|
||||
];
|
||||
|
||||
// 状态
|
||||
|
||||
@ -238,7 +238,7 @@ const getDataList = async () => {
|
||||
mockData.value = res.data
|
||||
loading.value = false
|
||||
} catch (error) {
|
||||
console.error('获取实例列表失败:', error)
|
||||
console.log('获取实例列表失败:', error)
|
||||
message.error('数据加载失败')
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user