代码修改

This commit is contained in:
qiuyuan 2026-02-09 09:57:19 +08:00
parent 115103fa9a
commit f5826a889f
11 changed files with 554 additions and 174 deletions

View File

@ -59,3 +59,6 @@ export const getExchangeList = (params:any) => request.get('/v1/balance/exchange
// 兑换算力点
export const exchangePoint = (params:any) => request.put('/v1/balance/exchange_point',params)
// 提现
export const getWithdraw = (params:any) => request.put('/v1/balance/withdraw',params)

View File

@ -42,6 +42,7 @@ request.interceptors.response.use(
if (code === 1) {
return data??code;
} else {
console.log("Response Data:", response);
// 可抛出业务错误
return Promise.reject(new Error(message || "请求失败"));
}
@ -56,6 +57,9 @@ request.interceptors.response.use(
setTimeout(() => {
window.location.href = "/login";
}, 3000);
} else if(res.status === 400){
message.error(res.data);
return
} else {
return Promise.reject(error.response.data);
}

View File

@ -22,7 +22,10 @@
<div v-if="userInfo.certificationStatus !== 'CERTIFICATION_PASSED'">
<span style="margin-right: 25px;">认证类型</span><span style="color: red;">未实名认证</span>
</div>
<div style="color:#1677ff;" v-if="userInfo.certificationStatus !== 'CERTIFICATION_PASSED'">前往认证
<div
@click="goCertification"
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
@ -773,6 +776,14 @@ const getCertificationInfo = async () => {
message.error('获取认证信息失败');
}
};
//
const goCertification = () => {
router.push('/layout/admin/realnameAuth');
};
//
onBeforeMount(() => {
const userInfoStr = localStorage.getItem('userInfo');
if (userInfoStr) {

View File

@ -108,19 +108,19 @@
<a-table :columns="columns" :data-source="rechargeRecords" :pagination="pagination" :loading="tableLoading"
@change="handleTableChange" size="middle" bordered>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'amount'">
<span class="amount-cell">¥{{ record.amount }}</span>
<template v-if="column.key === 'topUpAmount'">
<span class="amount-cell">¥{{ record.topUpAmount }}</span>
</template>
<template v-else-if="column.key === 'rechargeTime'">
{{ formatDateTime(record.rechargeTime) }}
<template v-else-if="column.key === 'created_at'">
{{ formatDateTime(record.created_at) }}
</template>
<template v-else-if="column.key === 'paymentMethod'">
<a-tag :color="getPaymentMethodColor(record.paymentMethod)">
{{ getPaymentMethodLabel(record.paymentMethod) }}
<template v-else-if="column.key === 'payMethod'">
<a-tag :color="getPaymentMethodColor(record.payMethod)">
{{ getPaymentMethodLabel(record.payMethod) }}
</a-tag>
</template>
<template v-else-if="column.key === 'accountBalance'">
¥{{ formatCurrency(record.accountBalance) }}
<template v-else-if="column.key === 'balance'">
¥{{ formatCurrency(record.balance) }}
</template>
<template v-else-if="column.key === 'status'">
<a-tag :color="getStatusColor(record.status)">
@ -202,9 +202,9 @@ const customAmountError = ref('')
//
const paymentMethods = ref([
{ value: 'alipay', name: '支付宝支付', icon: AlipayOutlined, color: '#1677ff' },
{ value: 'wechat', name: '微信支付', icon: WechatOutlined, color: '#07c160' },
{ value: 'bank', name: '对公付款', icon: BankOutlined, color: '#722ed1' }
{ value: "1", name: '支付宝支付', icon: AlipayOutlined, color: '#1677ff' },
{ value: "2", name: '微信支付', icon: WechatOutlined, color: '#07c160' },
{ value: "3", name: '银行卡支付', icon: BankOutlined, color: '#722ed1' }
])
const selectedPaymentMethod = ref('alipay')
@ -225,12 +225,12 @@ const rechargeRecords = ref([])
//
const columns = ref([
{ title: '充值金额', dataIndex: 'amount', key: 'amount', align: 'right', width: 120 },
{ title: '充值时间', dataIndex: 'rechargeTime', key: 'rechargeTime', width: 180, sorter: true },
{ title: '支付方式', dataIndex: 'paymentMethod', key: 'paymentMethod', width: 120 },
{ title: '账户余额', dataIndex: 'accountBalance', key: 'accountBalance', align: 'right', width: 140 },
{ title: '状态', dataIndex: 'status', key: 'status', width: 100 },
{ title: '操作', key: 'action', width: 80, align: 'center' }
{ title: '充值金额', dataIndex: 'topUpAmount', key: 'topUpAmount', align: 'center', width: 120 },
{ title: '充值时间', dataIndex: 'created_at', key: 'created_at', width: 180,align: 'center', sorter: true },
{ title: '支付方式', dataIndex: 'payMethod', key: 'payMethod', align: 'center',width: 120 },
{ title: '账户余额', dataIndex: 'balance', key: 'balance', align: 'center', width: 140 },
// { title: '', dataIndex: 'status', key: 'status', width: 100 },
// { title: '', key: 'action', width: 80, align: 'center' }
])
//
@ -299,7 +299,9 @@ const selectPaymentMethod = (method) => {
// &
const getPaymentMethodLabel = (method) => {
console.log("===21",method)
const payment = paymentMethods.value.find(m => m.value === method)
console.log("===2",payment)
return payment ? payment.name : method
}
const getPaymentMethodColor = (method) => {

View File

@ -2,7 +2,6 @@
<div class="withdrawal-management">
<!-- 提现账户信息卡片 -->
<a-row :gutter="24" class="mb-6">
<a-col :span="24">
<a-card title="可提现金额">
<div class="balance-info">
@ -24,9 +23,7 @@
<!-- 提现记录查询 -->
<a-card title="提现记录" class="mb-6">
<template #extra>
</template>
<template #extra></template>
<!-- 查询条件 -->
<a-form layout="inline" :model="searchParams" class="mb-4">
@ -44,26 +41,26 @@
<!-- 提现记录表格 -->
<a-table :columns="columns" :data-source="withdrawalRecords" :pagination="pagination" @change="handleTableChange"
:loading="loading" rowKey="id">
:loading="loading" rowKey="withdraw_number">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'amount'">
<span class="amount-cell">{{ formatCurrency(record.amount) }}</span>
<!-- 提现金额 -->
<template v-if="column.key === 'withdrawAmount'">
<span class="amount-cell">{{ formatCurrency(record.withdrawAmount) }}</span>
</template>
<template v-else-if="column.key === 'status'">
<a-tag :color="getStatusColor(record.status)">
{{ getStatusText(record.status) }}
<!-- 状态 -->
<template v-else-if="column.key === 'withdrawStatus'">
<a-tag :color="getStatusColor(record.withdrawStatus)">
{{ getStatusText(record.withdrawStatus) }}
</a-tag>
</template>
<template v-else-if="column.key === 'createdAt'">
{{ formatDate(record.createdAt) }}
</template>
<template v-else-if="column.key === 'completedAt'">
{{ record.completedAt ? formatDate(record.completedAt) : '-' }}
<!-- 申请时间 -->
<template v-else-if="column.key === 'created_at'">
{{ formatDate(record.created_at) }}
</template>
<!-- 操作 -->
<template v-else-if="column.key === 'actions'">
<a-button type="link" @click="viewDetail(record)">查看详情</a-button>
</template>
@ -87,16 +84,15 @@
</a-form-item>
<a-form-item label="提现到账账户" name="accountId">
<a-select v-model:value="withdrawalForm.accountId" placeholder="请选择提现账户">
<a-select-option :value="accountInfo.id">
{{ accountInfo.bank }} ({{ accountInfo.number }})
<a-select v-model:value="withdrawalForm.accountId" placeholder="请选择提现账户" :loading="bankLoading">
<a-select-option v-for="bank in bankCards" :key="bank.id" :value="bank.id">
{{ getBankCardDisplay(bank) }}
</a-select-option>
<a-select-option v-if="!bankCards.length && !bankLoading" disabled>
暂无银行卡信息请先添加银行卡
</a-select-option>
</a-select>
</a-form-item>
<a-alert v-if="withdrawalForm.amount"
:message="`预计到账金额: ${formatCurrency(calculateActualAmount(withdrawalForm.amount))}元`" type="info" show-icon
class="mb-4" />
</a-form>
</a-modal>
</div>
@ -107,22 +103,21 @@ import { ref, reactive, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import dayjs from 'dayjs'
import { getWithdrawList } from "@/apis/home"
import { getBankCardInfo, getWithdraw } from "@/apis/admin"
//
const accountInfo = reactive({
id: '1',
type: '银行账户',
number: '6228 **** **** 5678',
name: '张三',
bank: '中国工商银行',
availableBalance: 5000.00
availableBalance: 0
})
//
const bankCards = ref([])
const bankLoading = ref(false)
//
const searchParams = reactive({
orderNo: '',
account: undefined,
status: undefined,
dateRange: [dayjs().subtract(30, 'day'), dayjs()]
dateRange: []
})
//
@ -135,47 +130,78 @@ const pagination = reactive({
showTotal: total => `${total} 条记录`
})
//
//
const WITHDRAW_STATUS_MAP = {
'PendingReview': {
text: '待审核',
color: 'orange'
},
'PendingWithdraw': {
text: '待提现',
color: 'blue'
},
'WithdrawalSuccessful': {
text: '提现成功',
color: 'green'
},
'WithdrawalFailed': {
text: '提现失败',
color: 'red'
},
'RefuseWithdraw': {
text: '拒绝提现',
color: 'red'
}
}
//
const getStatusText = (status) => {
return WITHDRAW_STATUS_MAP[status]?.text || status
}
//
const getStatusColor = (status) => {
return WITHDRAW_STATUS_MAP[status]?.color || 'default'
}
// -
const columns = [
{
title: '提现单号',
dataIndex: 'orderNo',
key: 'orderNo',
dataIndex: 'withdraw_number',
key: 'withdraw_number',
width: 200
},
{
title: '账户',
key: 'account',
width: 180,
render: (_, record) => `${record.bank} (${record.accountNumber})`
title: '账户编号',
dataIndex: 'bankCardNo',
key: 'bankCardNo',
width: 200,
customRender: ({ text }) => maskCardNumber(text)
},
{
title: '账户名',
dataIndex: 'name',
key: 'name',
width: 180
},
{
title: '提现金额',
key: 'amount',
dataIndex: 'withdrawAmount',
key: 'withdrawAmount',
width: 120,
align: 'right'
},
{
title: '手续费',
dataIndex: 'fee',
key: 'fee',
width: 100,
align: 'right',
render: fee => fee ? `${fee}` : '-'
},
{
title: '状态',
key: 'status',
dataIndex: 'withdrawStatus',
key: 'withdrawStatus',
width: 100
},
{
title: '申请时间',
key: 'createdAt',
width: 180
},
{
title: '完成时间',
key: 'completedAt',
dataIndex: 'created_at',
key: 'created_at',
width: 180
},
{
@ -189,10 +215,6 @@ const columns = [
//
const withdrawalRecords = ref([])
const loading = ref(false)
const accountOptions = ref([
{ value: '1', label: '工商银行(尾号5678)' },
{ value: '2', label: '建设银行(尾号1234)' }
])
//
const withdrawalModal = reactive({
@ -204,14 +226,19 @@ const withdrawalModal = reactive({
const withdrawalFormRef = ref()
const withdrawalForm = reactive({
amount: undefined,
accountId: accountInfo.id
accountId: ''
})
//
const withdrawalRules = {
amount: [
{ required: true, message: '请输入提现金额' },
{ type: 'number', min: 1, max: accountInfo.availableBalance, message: `提现金额需在1-${accountInfo.availableBalance}元之间` }
{
type: 'number',
min: 1,
max: accountInfo.availableBalance,
message: `提现金额需在1-${accountInfo.availableBalance}元之间`
}
],
accountId: [
{ required: true, message: '请选择提现账户' }
@ -223,36 +250,163 @@ const dateFormat = 'YYYY-MM-DD'
//
onMounted(() => {
const userInfoStr=localStorage.getItem("userInfo")
if(userInfoStr){
const userInfoStr = localStorage.getItem("userInfo")
if (userInfoStr) {
const userInfo = JSON.parse(userInfoStr);
accountInfo.availableBalance=userInfo.balance
accountInfo.availableBalance = Number(userInfo.balance) || 0
}
fetchWithdrawalRecords()
getUserBankInfo()
})
//
const fetchWithdrawalRecords = async () => {
loading.value = true
console.log(searchParams)
try {
let params = {
withdraw_number: searchParams.orderNo,
withdraw_number: searchParams.orderNo || undefined,
page_num: pagination.current,
page_size: pagination.pageSize,
start_at: formatDate(searchParams.dateRange[0]),
end_at: formatDate(searchParams.dateRange[1]),
page_size: pagination.pageSize
}
//
if (searchParams.dateRange && searchParams.dateRange.length === 2) {
params.start_at = formatDateForApi(searchParams.dateRange[0])
params.end_at = formatDateForApi(searchParams.dateRange[1])
}
const res = await getWithdrawList(params)
console.log(res)
console.log("提现记录接口返回:", res)
if (res && res.data && Array.isArray(res.data)) {
console.log("提现记录数据:", res.data)
//
withdrawalRecords.value = res.data.map(item => ({
...item,
// 便
withdrawStatusText: getStatusText(item.withdrawStatus)
}))
pagination.total = res.total || 0
} else {
withdrawalRecords.value = []
pagination.total = 0
}
} catch (error) {
console.log(error)
console.error('获取提现记录失败:', error)
message.error('获取提现记录失败')
withdrawalRecords.value = []
} finally {
loading.value = false
}
}
// API
const formatDateForApi = (date) => {
if (!date) return ''
return dayjs(date).format('YYYY-MM-DD')
}
//
const getUserBankInfo = async () => {
bankLoading.value = true
try {
const res = await getBankCardInfo()
console.log('银行卡信息:', res)
if (res) {
//
const bankData = res
//
if (Array.isArray(bankData)) {
bankCards.value = bankData.map(bank => ({
id: bank.id,
bankCardNo: bank.bank_card_no,
name: bank.name,
phone: bank.phone,
//
bankName: getBankName(bank.bank_card_no)
}))
} else {
//
bankCards.value = [{
id: bankData.id,
bankCardNo: bankData.bank_card_no,
name: bankData.name,
phone: bankData.phone,
bankName: getBankName(bankData.bank_card_no)
}]
}
//
if (bankCards.value.length > 0) {
withdrawalForm.accountId = bankCards.value[0].id
}
} else {
bankCards.value = []
message.error('获取银行卡信息失败')
}
} catch (error) {
console.log('获取银行卡信息失败:', error)
bankCards.value = []
message.error('获取银行卡信息失败')
} finally {
bankLoading.value = false
}
}
//
const getBankName = (cardNo) => {
if (!cardNo) return '未知银行'
//
const firstDigits = cardNo.substring(0, 6)
const bankMapping = {
'622848': '中国农业银行',
'622700': '中国建设银行',
'622208': '中国工商银行',
'622622': '中国银行',
'622588': '招商银行',
'622909': '兴业银行',
'622516': '平安银行',
'622538': '浦发银行',
'622680': '民生银行',
'622568': '广发银行',
'622888': '中信银行'
}
for (const [prefix, bankName] of Object.entries(bankMapping)) {
if (cardNo.startsWith(prefix)) {
return bankName
}
}
return '银行卡'
}
//
const getBankCardDisplay = (bank) => {
if (!bank) return ''
const bankName = bank.bankName || '银行卡'
const maskedCardNo = maskCardNumber(bank.bankCardNo)
const userName = bank.name || ''
return `${bankName} (${maskedCardNo}) ${userName}`
}
//
const maskCardNumber = (cardNo) => {
if (!cardNo) return ''
if (cardNo.length <= 8) return cardNo
const first4 = cardNo.substring(0, 4)
const last4 = cardNo.substring(cardNo.length - 4)
const masked = '*'.repeat(Math.max(0, cardNo.length - 8))
return `${first4}${masked}${last4}`
}
//
const handleTableChange = (page) => {
pagination.current = page.current
@ -269,8 +423,6 @@ const handleSearch = () => {
//
const handleReset = () => {
searchParams.orderNo = ''
searchParams.account = undefined
searchParams.status = undefined
searchParams.dateRange = [dayjs().subtract(30, 'day'), dayjs()]
handleSearch()
}
@ -282,6 +434,10 @@ const handleDateChange = () => {
//
const showWithdrawalModal = () => {
//
if (bankCards.value.length === 0) {
getUserBankInfo()
}
withdrawalModal.visible = true
}
@ -289,11 +445,24 @@ const showWithdrawalModal = () => {
const handleWithdrawalSubmit = async () => {
try {
await withdrawalFormRef.value.validate()
//
if (!withdrawalForm.accountId) {
message.error('请选择提现账户')
return
}
//
const selectedBank = bankCards.value.find(bank => bank.id === withdrawalForm.accountId)
if (!selectedBank) {
message.error('选择的银行卡信息不存在')
return
}
withdrawalModal.confirming = true
// API
await new Promise(resolve => setTimeout(resolve, 1000))
// API
await getWithdraw({ amount: withdrawalForm.amount });
message.success('提现申请提交成功')
//
@ -307,6 +476,11 @@ const handleWithdrawalSubmit = async () => {
fetchWithdrawalRecords()
} catch (error) {
console.error('提现提交失败:', error)
if (error.errorFields) {
message.error('请检查表单填写是否正确')
} else {
message.error(error.message || '提现提交失败')
}
} finally {
withdrawalModal.confirming = false
}
@ -314,49 +488,37 @@ const handleWithdrawalSubmit = async () => {
//
const handleWithdrawalCancel = () => {
if (withdrawalFormRef.value) {
withdrawalFormRef.value.resetFields()
}
withdrawalModal.visible = false
}
//
const viewDetail = (record) => {
message.info(`查看提现记录详情: ${record.orderNo}`)
message.info(`查看提现记录详情: ${record.withdraw_number}`)
//
}
//
const calculateActualAmount = (amount) => {
const fee = amount * 0.01 // 1%
return amount - fee
}
//
// -
const formatCurrency = (amount) => {
return amount.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,')
// nullundefined
if (amount === null || amount === undefined || isNaN(amount)) {
return '0.00'
}
const num = Number(amount)
if (isNaN(num)) {
return '0.00'
}
return num.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,')
}
//
const formatDate = (dateString) => {
return dayjs(dateString).format('YYYY-MM-DD')
}
//
const getStatusColor = (status) => {
const colors = {
pending: 'orange',
success: 'green',
failed: 'red'
}
return colors[status] || 'default'
}
//
const getStatusText = (status) => {
const texts = {
pending: '处理中',
success: '成功',
failed: '失败'
}
return texts[status] || status
if (!dateString) return ''
return dayjs(dateString).format('YYYY-MM-DD HH:mm:ss')
}
</script>
@ -442,4 +604,33 @@ const getStatusText = (status) => {
float: inline-end;
width: 10%;
}
/* 状态标签样式 */
:deep(.ant-tag) {
border-radius: 4px;
}
:deep(.ant-tag-orange) {
background: #fff7e6;
border-color: #ffd591;
color: #fa8c16;
}
:deep(.ant-tag-blue) {
background: #e6f4ff;
border-color: #91caff;
color: #1677ff;
}
:deep(.ant-tag-green) {
background: #f6ffed;
border-color: #b7eb8f;
color: #52c41a;
}
:deep(.ant-tag-red) {
background: #fff2f0;
border-color: #ffccc7;
color: #ff4d4f;
}
</style>

View File

@ -83,15 +83,40 @@ import {
invoiceList,
invoiceDetail
} from '@/apis/admin'
import { Tag } from 'ant-design-vue'
//
const INVOICE_STATUS_MAP = {
'InvoiceProcessing': { text: '开票中', color: 'processing' },
'InvoiceSuccessful': { text: '开票成功', color: 'success' },
'InvoiceFailed': { text: '开票失败', color: 'error' },
'InvoiceRejected': { text: '已驳回', color: 'warning' },
'PendingReview': { text: '待审核', color: 'warning' },
'ReviewFailed': { text: '审核失败', color: 'warning' },
'PendingInvoice': { text: '待开票(审核成功)', color: 'warning' },
'PendingSend': { text: '待寄送(开票成功)', color: 'warning' },
'SendSuccessful': { text: '寄送完成', color: 'warning' },
'SendFailed': { text: '寄送失败', color: 'warning' }
}
//
const getInvoiceStatusText = (status: string) => {
return INVOICE_STATUS_MAP[status as keyof typeof INVOICE_STATUS_MAP]?.text || status
}
//
const getInvoiceStatusColor = (status: string) => {
return INVOICE_STATUS_MAP[status as keyof typeof INVOICE_STATUS_MAP]?.color || 'default'
}
//
const InvoiceStatusTag = ({ status }: { status: string }) => {
const statusInfo = INVOICE_STATUS_MAP[status as keyof typeof INVOICE_STATUS_MAP]
if (!statusInfo) return status
return h(Tag, { color: statusInfo.color }, () => statusInfo.text)
}
// const listData=ref([ {title:1}])
// const paginationState=ref({
// total: 0,
// current: 1,
// pageSize: 10,
// showTotal: (total) => ` ${total} `,
// pageSizeOptions: ['10', '20', '30', '40'],
// })
const { listData, loading, showLoading, hideLoading, paginationState, resetPagination, searchFormData } = usePagination()
const visibleOpen = ref(false)
const formData = ref<any>({ type: 'a' })
@ -104,7 +129,7 @@ const rules = computed(() => ({
recipientAddress: [{ required: true, message: '请选择收件人地址', trigger: 'change' }],
number: [
{
required: formData.value.type === 'b', // (value='b')
required: formData.value.type === 'b', // ""(value='b')
message: '请输入纳税人识别号',
trigger: 'blur'
}
@ -138,6 +163,7 @@ const rules = computed(() => ({
}
]
}))
const columns = ref([
{ title: '申请时间', dataIndex: 'invoiceDate', key: 'invoiceDate' },
{ title: '开票内容', dataIndex: 'invoiceContent', key: 'invoiceContent' },
@ -145,35 +171,72 @@ const columns = ref([
{ title: '发票总额', dataIndex: 'invoiceAmount', key: 'invoiceAmount' },
{ title: '开票方式', dataIndex: 'invoiceMethod', key: 'invoiceMethod' },
{ title: '发票类型', dataIndex: 'invoiceType', key: 'invoiceType' },
{ title: '发票状态', dataIndex: 'invoiceStatus', key: 'invoiceStatus' },
{
title: '发票状态',
dataIndex: 'invoiceStatus',
key: 'invoiceStatus',
customRender: ({ text: status }) => {
const statusInfo = INVOICE_STATUS_MAP[status as keyof typeof INVOICE_STATUS_MAP]
if (!statusInfo) return status
// span
const span = document.createElement('span')
span.className = `invoice-status invoice-status-${statusInfo.color}`
span.textContent = statusInfo.text
return {
children: statusInfo.text,
props: {
class: `invoice-status invoice-status-${statusInfo.color}`
}
}
}
},
{ title: '驳回原因', dataIndex: 'rejectReason', key: 'rejectReason' },
{ title: '操作', dataIndex: 'flowNum', key: 'flowNum' },
])
onBeforeMount(() => {
getPageList()
})
const getPageList = async () => {
try {
const params = {
page_num: 1,
page_size: 10, //
page_size: 10,
};
const response: any = await invoiceList(params);
if (response.data && Array.isArray(response.data)) {
listData.value = response.data
console.log('发票列表:', response.data);
//
const transformedData = response.data.map(item => ({
...item,
//
// invoiceStatusText: getInvoiceStatusText(item.invoiceStatus)
}))
listData.value = transformedData
console.log('发票列表:', transformedData);
}
} catch (error) {
console.error('获取全部消息失败:', error);
console.error('获取发票列表失败:', error);
listData.value = [];
}
};
/**
* 处理数据映射 - 如果需要显示时转换
*/
const processInvoiceData = (data) => {
return data.map(item => ({
...item,
//
invoiceStatusText: getInvoiceStatusText(item.invoiceStatus)
}))
}
/**
* 分页
*/
@ -182,6 +245,7 @@ function onTableChange({ current, pageSize }) {
paginationState.pageSize = pageSize
getPageList()
}
/**
* 搜索
*/
@ -189,6 +253,7 @@ function handleSearch() {
resetPagination()
getPageList()
}
/**
* 重置
*/
@ -197,20 +262,47 @@ function handleResetSearch() {
resetPagination()
getPageList()
}
function handleOk() {
visibleOpen.value = false
formRef.value.validateFields().then(async (values) => {
try {
//
} catch (error) {
console.error('提交失败:', error);
}
})
}
</script>
<style scoped lang="scss">
.bold {
font-weight: bold;
}
//
:deep(.ant-tag-processing) {
background: #e6f4ff;
border-color: #91caff;
color: #1677ff;
}
:deep(.ant-tag-success) {
background: #f6ffed;
border-color: #b7eb8f;
color: #52c41a;
}
:deep(.ant-tag-error) {
background: #fff2f0;
border-color: #ffccc7;
color: #ff4d4f;
}
:deep(.ant-tag-warning) {
background: #fff7e6;
border-color: #ffd591;
color: #fa8c16;
}
</style>

View File

@ -13,7 +13,7 @@
:loading="loading" class="bill-table" :scroll="{ x: 1200 }" bordered>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 'enabled'" color="green">有效</a-tag>
<a-tag v-if="record.status === '可用'" color="green">可用</a-tag>
<a-tag v-else color="red">失效</a-tag>
</template>
</template>

View File

@ -100,7 +100,8 @@
<div>算力券</div>
<a-select ref="select" v-model:value="voucherId" style="width:300px" @change="handleChange">
<a-select-option :value="''">不使用算力券</a-select-option>
<a-select-option v-for="value in voucherList" :value="value.id">{{ value.name + ' - '+''+value.amount }}</a-select-option>
<a-select-option v-for="value in voucherList" :value="value.id">{{ formatVoucherLabel(value)
}}</a-select-option>
</a-select>
</div>
@ -214,7 +215,7 @@ async function fetchTotalCost() {
billingMethod: billingType.value,
gpuNum: gpuCount.value,
host_id: HostId.value,
price_count:priceCount.value
price_count: priceCount.value
})
totalMoney.value = res.amount
computingPowerPoint.value = res.computingPowerPoint
@ -232,7 +233,7 @@ const priceCounts = computed(() => {
}
})
//
watch([billingType, gpuCount,priceCount], () => {
watch([billingType, gpuCount, priceCount], () => {
fetchTotalCost()
getSingleHost()
}) //
@ -249,10 +250,53 @@ const getServiceImages = async () => {
try {
selectedImage.value = ''
const res = await getImages({ image_type: imageType.value })
console.log(res.data)
imageOptions.value = res.data.map((item: any) => ({ id: item.id, label: item.image_name }))
} catch (error) {
console.log("API返回数据:", res)
if (res.data && Array.isArray(res.data.data) && res.data.data.length > 0) {
console.log("情况1: data.data是数组且有数据")
imageOptions.value = res.data.data.map((item: any) => ({
id: item.id,
label: item.image_name
}))
}
else if (res.data && res.data.data === null) {
console.log("情况2: data.data是null")
imageOptions.value = []
if (imageType.value === 'USER') {
console.log("用户没有自定义镜像")
//
}
}
else if (res.data && Array.isArray(res.data.data) && res.data.data.length === 0) {
console.log("情况3: data.data是空数组")
imageOptions.value = []
if (imageType.value === 'USER') {
console.log("用户的自定义镜像列表为空")
}
}
else if (Array.isArray(res.data)) {
console.log("情况4: res.data直接是数组")
imageOptions.value = res.data.map((item: any) => ({
id: item.id,
label: item.image_name
}))
}
else {
console.log("情况5: 未知数据格式", res.data)
imageOptions.value = []
}
console.log("最终的imageOptions:", imageOptions.value)
} catch (error) {
console.error("获取镜像失败:", error)
message.error('获取镜像列表失败')
imageOptions.value = []
}
}
@ -280,9 +324,15 @@ const handleCreate = async () => {
voucher_id: voucherId.value
}
const res = await createHost(params)
if (res == null) {
return false;
} else {
message.success('实例创建成功!')
creating.value = false
}
} catch (error) {
console.error('创建失败:', error)
message.error('创建失败,请重试')
} finally {
creating.value = false
@ -293,6 +343,10 @@ const handleCancel = () => {
window.history.back()
}
const formatVoucherLabel = (voucher: any) => {
return `${voucher.name} - ¥${voucher.amount}`
}
</script>

View File

@ -67,6 +67,11 @@ const formState = reactive<FormState>({
invite_id: '',
});
// Register.vue
const emit = defineEmits<{
(e: 'register-success'): void;
}>();
const clearCodeError = () => {
codeValidateStatus.value = '';
codeHelp.value = '';
@ -82,22 +87,29 @@ const querenPassword = (rule, value) => {
}
return Promise.resolve();
};
const onFinish = async (values: FormState) => {
clearCodeError();
const loginData = {
...values,
checked: checked.value,
};
formRef.value?.validateFields().then(async () => {
try {
await formRef.value?.validateFields();
const res: any = await apis.login.register(loginData);
console.log('注册请求成功:', res);
message.success('注册成功,请登录');
message.success('注册成功,即将返回登陆界面');
setTimeout(() => {
emit('register-success');
}, 2000);
formRef.value?.resetFields();
} catch (error: any) {
console.error('注册请求失败:', error);
message.error(error);
message.error(error?.response?.data?.message || '注册失败,请稍后重试');
}
});
};
const onFinishFailed = (errorInfo: any) => {

View File

@ -40,7 +40,7 @@
</div>
<div v-if="currentTag == 'register'">
<div>
<Register />
<Register @register-success="handleRegisterSuccess"/>
<div style="text-align: right;">
<span style="color: #666;cursor: pointer;font-size: 14px;" @click="currentTag = 'login'">
已有账号 <span style="color: #1677ff;">登录</span></span>
@ -111,6 +111,10 @@ const handleMenuClick = (key) => {
router.push(fullPath);
}
}
const handleRegisterSuccess = () => {
currentTag.value = 'login'; // tab
};
</script>
<style scoped lang="scss">

View File

@ -132,10 +132,17 @@ const currentPage = ref(1)
const pageSize = ref(10)
onMounted(async () => {
spinning.value = true
await getHostList()
try {
// GPU
await getAreaList()
await getGpuList()
//
await getHostList()
} catch (error) {
console.error('初始化失败:', error)
} finally {
spinning.value = false
}
})
async function getHostList() {