feat(wallet): 钱包系统替代配额系统,新增支付与退款机制

- 新增钱包余额管理、充值、扣费、退款完整流程
- 新增支付网关抽象层(支持手动/支付宝/微信)
- 用量计费从配额系统迁移到钱包余额扣费
- 新增管理员钱包管理与支付订单管理页面
- 新增用户钱包中心页面
- 移除独立 Key 锁定机制,统一由钱包余额控制
- 新增相关 API 路由、序列化器与数据库迁移
- 新增钱包、支付、退款相关测试
This commit is contained in:
LewisPen
2026-03-08 00:05:48 +08:00
committed by fawney19
parent 9cdcce1b5f
commit 783f654953
108 changed files with 13152 additions and 3372 deletions

View File

@@ -1,7 +1,7 @@
<template>
<Dialog
:model-value="modelValue"
:z-index="80"
:z-index="120"
@update:model-value="handleClose"
>
<template #header>
@@ -28,9 +28,8 @@
v-for="(line, index) in descriptionLines"
:key="index"
:class="getLineClass(index)"
>
{{ line }}
</p>
v-html="renderLine(line)"
/>
</div>
<!-- 自定义内容插槽 -->
@@ -103,6 +102,24 @@ const descriptionLines = computed(() => {
return props.description.split('\n').filter(line => line.trim())
})
function escapeHtml(raw: string): string {
return raw
.replaceAll('&', '&amp;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
.replaceAll('"', '&quot;')
.replaceAll("'", '&#39;')
}
function renderLine(line: string): string {
const escaped = escapeHtml(line)
// 支持最小语法加粗:**text**
return escaped.replace(
/\*\*(.+?)\*\*/g,
'<strong class="font-semibold text-foreground">$1</strong>'
)
}
// 根据行索引获取样式(中间行高亮)
function getLineClass(index: number): string {
const total = descriptionLines.value.length