重命名前端目录

This commit is contained in:
yml2213
2026-07-07 19:55:18 +08:00
parent 8268a3b906
commit dbcb5a4979
182 changed files with 7019 additions and 7017 deletions
@@ -1,53 +0,0 @@
<script setup lang="ts">
defineProps<{
title: string
description?: string
}>()
</script>
<template>
<div class="page-header">
<div>
<h1>{{ title }}</h1>
<p v-if="description">{{ description }}</p>
</div>
<div v-if="$slots.extra" class="header-extra">
<slot name="extra" />
</div>
</div>
</template>
<style scoped>
.page-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: var(--space-3);
}
.page-header h1 {
margin: 0;
font-size: var(--text-3xl);
color: var(--text-primary);
}
.page-header p {
margin: var(--space-2) 0 0;
color: var(--text-secondary);
}
.header-extra {
display: flex;
gap: var(--space-2);
flex-shrink: 0;
align-items: center;
color: var(--text-secondary);
font-size: var(--text-sm);
}
@media (max-width: 900px) {
.page-header {
flex-direction: column;
}
}
</style>
@@ -1,42 +0,0 @@
<script setup lang="ts">
defineProps<{
label: string
value: string | number
}>()
</script>
<template>
<el-card shadow="never" class="result-card">
<span class="result-label">{{ label }}</span>
<strong>{{ value }}</strong>
<slot />
</el-card>
</template>
<style scoped>
.result-card {
display: grid;
gap: 6px;
padding: var(--space-4);
border-radius: var(--radius-lg);
background: var(--bg-subtle);
border: 1px solid var(--border-default);
}
.result-label {
color: var(--text-secondary);
font-size: var(--text-xs);
font-weight: 700;
}
.result-card strong {
color: var(--text-primary);
font-size: 22px;
}
.result-card :deep(p) {
margin: 0;
color: var(--text-secondary);
font-size: var(--text-sm);
}
</style>
@@ -1,167 +0,0 @@
<script setup lang="ts">
import { formatStatusWithRaw } from '@/utils/admin-display'
const props = withDefaults(
defineProps<{
status: string
showRaw?: boolean
}>(),
{
showRaw: true,
},
)
type ElTagType = 'success' | 'primary' | 'warning' | 'danger' | 'info'
function resolveType(status: string): ElTagType {
const normalized = String(status || '')
.trim()
.toLowerCase()
if (
[
'paid',
'link_generated',
'redeemed',
'available',
'delivered',
'success',
'active',
'system_bound',
'binding_completed',
'completed',
].includes(normalized)
) {
return 'success'
}
if (
[
'claimed',
'role_confirmed',
'redeeming',
'reserved',
'processing',
'admin',
'support',
'waiting_user_claim',
'link_opened',
'binding_confirmed',
'binding_in_progress',
'user_binding',
'pending',
'waiting',
'waiting_binding',
].includes(normalized)
) {
return 'primary'
}
if (
[
'retry_pending',
'manual_review',
'invalid',
'expired',
'operator',
'pending_binding',
'pending_config',
'binding_exception',
'not_started',
'consumed',
'skipped',
'pending_binding_prepare',
'dispatched_pending_return',
].includes(normalized)
) {
return 'warning'
}
if (['closed', 'failed', 'unpaid', 'revoked', 'disabled'].includes(normalized)) {
return 'danger'
}
return 'info'
}
function resolveLabel(status: string) {
const normalized = String(status || '').trim()
if (!normalized) return '-'
const labelMap: Record<string, string> = {
created: '已创建',
paid: '已支付',
unpaid: '未支付',
failed: '失败',
refunded: '已退款',
refunding: '退款中',
closed: '已关闭',
pending_payment: '待支付',
cdk_reserved: '资源已准备',
link_generated: '已生成链接',
claimed: '已创建会话',
role_confirmed: '已确认角色',
redeeming: '兑换中',
redeemed: '已兑换',
retry_pending: '待重试',
manual_review: '人工处理',
expired: '已过期',
available: '可用',
reserved: '资源已准备',
delivered: '已发放',
consumed: '已使用',
invalid: '已作废',
active: '生效中',
admin: '管理员',
operator: '普通运营',
support: '客服',
revoked: '已撤销',
disabled: '已停用',
success: '成功',
skipped: '已跳过',
pending: '待触发',
waiting: '等待中',
processing: '处理中',
system_bound: '资源已准备',
pending_binding: '待准备资源',
resource_ready: '资源已准备',
pending_prepare: '待准备资源',
pending_config: '待配置',
pending_binding_prepare: '待准备资源',
not_started: '未开始',
waiting_binding: '待客户绑定',
dispatched_pending_return: '待退还号码',
completed: '已完成',
waiting_user_claim: '待客户打开链接',
waiting_customer: '待客户绑定',
link_opened: '已打开链接',
binding_confirmed: '已提交',
binding_in_progress: '处理中',
binding_completed: '履约完成',
binding_exception: '履约异常',
customer_confirmed: '已提交',
customer_processing: '处理中',
customer_completed: '履约完成',
customer_exception: '履约异常',
resource_exception: '资源异常',
user_binding: '客户处理中',
}
if (!props.showRaw) {
return labelMap[normalized.toLowerCase()] || normalized
}
return formatStatusWithRaw(normalized, labelMap)
}
</script>
<template>
<el-tag
:type="resolveType(props.status)"
size="small"
:title="props.showRaw ? undefined : props.status"
>
{{ resolveLabel(props.status) }}
</el-tag>
</template>
@@ -0,0 +1,7 @@
type JsonPreviewProps = {
value: unknown
}
export default function JsonPreview({ value }: JsonPreviewProps) {
return <pre className="json-preview">{JSON.stringify(value ?? {}, null, 2)}</pre>
}
@@ -0,0 +1,22 @@
import { Space, Typography } from 'antd'
import type { ReactNode } from 'react'
type PageHeaderProps = {
title: string
description?: string
extra?: ReactNode
}
export default function PageHeader({ title, description, extra }: PageHeaderProps) {
return (
<header className="page-header">
<div>
<Typography.Title level={2} className="page-title">
{title}
</Typography.Title>
{description ? <p className="page-description">{description}</p> : null}
</div>
{extra ? <Space wrap>{extra}</Space> : null}
</header>
)
}
@@ -0,0 +1,156 @@
import { Tag } from 'antd'
type StatusTagProps = {
value?: string | null
kind?: 'task' | 'pay' | 'delivery' | 'resource' | 'customer' | 'role' | 'plain'
}
const STATUS_LABELS: Record<string, string> = {
active: '生效中',
admin: '管理员',
available: '可用',
binding_completed: '履约完成',
binding_confirmed: '已提交',
binding_exception: '履约异常',
binding_in_progress: '处理中',
canceled: '已取消',
cancelled: '已取消',
cdk_reserved: '资源已准备',
claimed: '已创建会话',
closed: '已关闭',
completed: '已完成',
consumed: '已核销',
created: '已创建',
customer_completed: '履约完成',
customer_confirmed: '已提交',
customer_exception: '履约异常',
customer_processing: '处理中',
delivered: '已发放',
disabled: '已停用',
dispatched_pending_return: '待退还号码',
expired: '已过期',
failed: '失败',
invalid: '已作废',
link_generated: '已生成链接',
link_opened: '已打开链接',
manual_review: '人工处理',
not_started: '未开始',
operator: '普通运营',
paid: '已支付',
pending: '待触发',
pending_binding: '待准备资源',
pending_binding_prepare: '待准备资源',
pending_claim: '待领取',
pending_config: '待配置',
pending_payment: '待支付',
pending_prepare: '待准备资源',
processing: '处理中',
redeemed: '已兑换',
redeeming: '兑换中',
refunded: '已退款',
refunding: '退款中',
reserved: '资源已准备',
resource_exception: '资源异常',
resource_ready: '资源已准备',
revoked: '已撤销',
retry_pending: '待重试',
role_confirmed: '已确认角色',
skipped: '已跳过',
success: '成功',
support: '客服',
system_bound: '资源已准备',
unpaid: '未支付',
user_binding: '客户处理中',
verified: '已校验',
waiting: '等待中',
waiting_binding: '待客户绑定',
waiting_customer: '待客户绑定',
waiting_user_claim: '待客户打开链接',
}
const STATUS_COLORS: Record<string, string> = {
active: 'green',
admin: 'purple',
available: 'green',
binding_completed: 'green',
binding_confirmed: 'blue',
binding_exception: 'red',
binding_in_progress: 'blue',
canceled: 'default',
cancelled: 'default',
cdk_reserved: 'green',
claimed: 'blue',
closed: 'default',
completed: 'green',
consumed: 'green',
created: 'blue',
customer_completed: 'green',
customer_confirmed: 'blue',
customer_exception: 'red',
customer_processing: 'blue',
delivered: 'green',
disabled: 'red',
failed: 'red',
invalid: 'orange',
link_generated: 'cyan',
link_opened: 'blue',
manual_review: 'orange',
not_started: 'gold',
operator: 'gold',
paid: 'green',
pending: 'gold',
pending_binding: 'gold',
pending_binding_prepare: 'gold',
pending_claim: 'gold',
pending_config: 'gold',
pending_payment: 'default',
pending_prepare: 'gold',
processing: 'blue',
redeemed: 'green',
redeeming: 'blue',
refunded: 'purple',
refunding: 'purple',
reserved: 'green',
resource_exception: 'red',
resource_ready: 'green',
revoked: 'red',
retry_pending: 'volcano',
role_confirmed: 'blue',
skipped: 'gold',
success: 'green',
support: 'blue',
system_bound: 'green',
unpaid: 'default',
user_binding: 'blue',
verified: 'green',
waiting: 'blue',
waiting_binding: 'gold',
waiting_customer: 'gold',
waiting_user_claim: 'blue',
}
export default function StatusTag({ value, kind = 'plain' }: StatusTagProps) {
const normalized = String(value || '').trim()
if (!normalized) {
return <span className="muted">-</span>
}
const key = normalized.toLowerCase()
const label = STATUS_LABELS[key] || normalized
const color = STATUS_COLORS[key] || resolveFallbackColor(kind)
return (
<Tag color={color} title={normalized}>
{label}
</Tag>
)
}
function resolveFallbackColor(kind: StatusTagProps['kind']) {
if (kind === 'pay' || kind === 'delivery') return 'blue'
if (kind === 'task') return 'geekblue'
if (kind === 'resource' || kind === 'customer') return 'cyan'
if (kind === 'role') return 'purple'
return 'default'
}