Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
client
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
cb9ca950
authored
Jun 04, 2026
by
renyizhao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
充值功能完成
parent
73636f4a
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
156 additions
and
19 deletions
+156
-19
src/api/console.js
+19
-2
src/views/console/components/token.vue
+137
-17
No files found.
src/api/console.js
View file @
cb9ca950
...
...
@@ -42,4 +42,22 @@ export function getToken() {
url
:
'/app/ai-token/get'
,
method
:
'post'
,
})
}
\ No newline at end of file
}
// 创建充值记录
export
function
createRecharge
(
amount
)
{
return
request
({
url
:
'/app/recharge/create'
,
method
:
'post'
,
data
:
{
amount
}
})
}
// 查询充值记录状态
export
function
getRecharge
(
id
)
{
return
request
({
url
:
'/app/recharge/get'
,
method
:
'get'
,
params
:
{
id
}
})
}
src/views/console/components/token.vue
View file @
cb9ca950
...
...
@@ -16,24 +16,37 @@
</el-form>
<el-form
:model=
"rechargeForm"
label-width=
"100px"
label-position=
"left"
>
<el-form-item
label=
"充值金额:"
>
<el-input-number
v-model=
"rechargeForm.amount"
:min=
"
1
"
:precision=
"2"
/>
<el-button
type=
"primary"
@
click=
"handleRecharge"
class=
"ml20"
>
充值
</el-button>
<el-input-number
v-model=
"rechargeForm.amount"
:min=
"
0
"
:precision=
"2"
/>
<el-button
type=
"primary"
@
click=
"handleRecharge"
:loading=
"rechargeLoading"
class=
"ml20"
>
充值
</el-button>
</el-form-item>
</el-form>
<el-dialog
v-model=
"rechargeDialogVisible"
title=
"扫码充值"
width=
"300px"
>
<div
class=
"text-center"
>
<p>
充值金额:
{{
rechargeForm
.
amount
}}
元
</p>
<div
style=
"width: 200px; height: 200px; margin: 0 auto; background: #f5f5f5; display: flex; align-items: center; justify-content: center;"
>
二维码占位
</div>
</div>
</el-dialog>
</div>
<!-- 支付二维码弹窗 -->
<el-dialog
:title=
"qrCode.title"
v-model=
"qrCode.visible"
width=
"385px"
append-to-body
:align-center=
"true"
:close-on-click-modal=
"false"
@
closed=
"clearQueryInterval"
>
<div
class=
"text-center"
>
<p>
充值金额:¥
{{
rechargeForm
.
amount
}}
</p>
<p
style=
"color: #999; font-size: 12px;"
>
请使用微信或支付宝扫码支付
</p>
<div
v-if=
"qrCode.url"
style=
"width: 200px; height: 200px; margin: 10px auto;"
>
<img
:src=
"qrCode.url"
style=
"width: 100%; height: 100%;"
/>
</div>
</div>
</el-dialog>
</div>
</
template
>
<
script
setup
>
import
{
getTokenInfo
,
getToken
}
from
"@/api/console"
;
import
{
getTokenInfo
,
getToken
,
createRecharge
,
getRecharge
}
from
"@/api/console"
;
import
{
ElMessage
,
ElMessageBox
}
from
"element-plus"
;
import
QRCode
from
"qrcode"
;
const
{
proxy
}
=
getCurrentInstance
();
...
...
@@ -42,11 +55,21 @@ const hasToken = ref(false);
const
balance
=
ref
(
"0.00"
);
const
apiKey
=
ref
(
""
);
const
maskedKey
=
ref
(
""
);
const
rechargeLoading
=
ref
(
false
);
// 轮询相关
const
queryInterval
=
ref
(
undefined
);
const
currentRechargeId
=
ref
(
undefined
);
const
rechargeForm
=
reactive
({
amount
:
10
amount
:
0
});
const
qrCode
=
ref
({
url
:
''
,
title
:
'请使用微信或支付宝扫码支付'
,
visible
:
false
});
const
rechargeDialogVisible
=
ref
(
false
);
function
maskKey
(
key
)
{
if
(
!
key
||
key
.
length
<
12
)
return
key
;
...
...
@@ -59,7 +82,10 @@ function loadTokenInfo() {
hasToken
.
value
=
true
;
apiKey
.
value
=
response
.
apiKey
;
maskedKey
.
value
=
maskKey
(
response
.
apiKey
);
balance
.
value
=
"100.00"
;
// 显示真实 New API 余额
if
(
response
.
balance
)
{
balance
.
value
=
response
.
balance
;
}
}
}).
catch
(()
=>
{
// 忽略错误,保持当前状态
...
...
@@ -85,12 +111,107 @@ function handleGetToken() {
}
function
handleRecharge
()
{
rechargeDialogVisible
.
value
=
true
;
if
(
rechargeForm
.
amount
<=
0
)
{
proxy
.
$modal
.
msgError
(
"请输入正确的充值金额"
);
return
;
}
rechargeLoading
.
value
=
true
;
qrCode
.
value
.
url
=
""
;
createRecharge
(
rechargeForm
.
amount
).
then
(
response
=>
{
if
(
response
&&
response
.
data
&&
response
.
data
.
id
)
{
// 保存当前充值ID用于轮询
currentRechargeId
.
value
=
response
.
data
.
id
;
// 生成二维码
if
(
response
.
data
.
qrCodeUrl
)
{
QRCode
.
toDataURL
(
response
.
data
.
qrCodeUrl
,
{
errorCorrectionLevel
:
'L'
,
margin
:
2
,
width
:
200
},
(
err
,
url
)
=>
{
if
(
err
)
{
proxy
.
$modal
.
msgError
(
"生成二维码失败"
);
rechargeLoading
.
value
=
false
;
return
;
}
qrCode
.
value
.
url
=
url
;
qrCode
.
value
.
visible
=
true
;
// 开始轮询
createQueryInterval
(
currentRechargeId
.
value
);
});
}
else
{
proxy
.
$modal
.
msgError
(
"获取支付链接失败"
);
}
proxy
.
$modal
.
msgSuccess
(
"充值订单已创建"
);
}
else
{
proxy
.
$modal
.
msgError
(
"创建充值订单失败"
);
}
rechargeLoading
.
value
=
false
;
}).
catch
(
error
=>
{
rechargeLoading
.
value
=
false
;
proxy
.
$modal
.
msgError
(
"充值失败: "
+
(
error
.
message
||
"未知错误"
));
});
}
// 轮询查询充值状态
const
createQueryInterval
=
(
rechargeId
)
=>
{
if
(
queryInterval
.
value
)
{
return
;
}
queryInterval
.
value
=
setInterval
(
async
()
=>
{
try
{
const
res
=
await
getRecharge
(
rechargeId
);
console
.
log
(
'充值轮询结果:'
,
res
);
// 已支付
if
(
res
.
data
&&
res
.
data
.
payStatus
===
1
)
{
clearQueryInterval
();
ElMessageBox
.
confirm
(
'支付成功'
,
'提示'
,
{
confirmButtonText
:
'确认'
,
showCancelButton
:
false
,
type
:
'success'
}
).
then
(()
=>
{
qrCode
.
value
.
visible
=
false
;
});
}
// 支付失败
if
(
res
.
data
&&
res
.
data
.
payStatus
===
-
1
)
{
clearQueryInterval
();
ElMessage
.
error
(
'支付失败!'
);
qrCode
.
value
.
visible
=
false
;
}
}
catch
(
e
)
{
// 静默捕获轮询异常
}
},
1000
*
2
);
// 每2秒轮询一次
};
// 清除轮询和弹窗
const
clearQueryInterval
=
()
=>
{
qrCode
.
value
.
visible
=
false
;
qrCode
.
value
.
url
=
''
;
qrCode
.
value
.
title
=
'请使用微信或支付宝扫码支付'
;
// 清除轮询任务
if
(
queryInterval
.
value
)
{
clearInterval
(
queryInterval
.
value
);
queryInterval
.
value
=
undefined
;
}
currentRechargeId
.
value
=
undefined
;
};
onMounted
(()
=>
{
loadTokenInfo
();
});
onUnmounted
(()
=>
{
// 组件销毁时清除轮询
try
{
clearQueryInterval
();
}
catch
(
e
)
{}
});
</
script
>
<
style
scoped
lang=
"scss"
>
...
...
@@ -99,4 +220,4 @@ onMounted(() => {
font-size
:
12px
;
cursor
:
pointer
;
}
</
style
>
\ No newline at end of file
</
style
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment