优化结构
This commit is contained in:
@@ -265,6 +265,12 @@ const TARGETS = {
|
||||
description: 'RabbitMQ 消息队列',
|
||||
icon: Promotion
|
||||
},
|
||||
'mq/kafka': {
|
||||
name: 'Kafka',
|
||||
protocol: 'Kafka',
|
||||
description: 'Apache Kafka 分布式事件队列',
|
||||
icon: Promotion
|
||||
},
|
||||
'websocket/melody': {
|
||||
name: 'WebSocket',
|
||||
protocol: 'WS',
|
||||
@@ -276,7 +282,7 @@ const TARGETS = {
|
||||
const TARGET_ORDER = Object.keys(TARGETS)
|
||||
const RECONNECT_INTERVAL_KEY = 'reconnect_interval'
|
||||
const RECONNECT_DEFAULT_SECONDS = 5
|
||||
const MQ_RECONNECT_TARGETS = new Set(['mq/emqx', 'mq/rabbitmq'])
|
||||
const MQ_RECONNECT_TARGETS = new Set(['mq/emqx', 'mq/kafka', 'mq/rabbitmq'])
|
||||
const RECONNECT_INTERVAL_FIELD = {
|
||||
key: RECONNECT_INTERVAL_KEY,
|
||||
label: '重连间隔(秒)',
|
||||
@@ -291,6 +297,9 @@ const NUMBER_CONSTRAINTS = {
|
||||
reconnect_interval: { min: 1, integer: true },
|
||||
prefetch_count: { min: 0 },
|
||||
heartbeat: { min: 0 },
|
||||
min_bytes: { min: 1, integer: true },
|
||||
max_bytes: { min: 1, integer: true },
|
||||
max_wait: { min: 1 },
|
||||
max_message_size: { min: 0 },
|
||||
message_buffer_size: { min: 0 }
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
<el-table-column label="订单与交易" min-width="285">
|
||||
<template #default="scope">
|
||||
<div class="order-cell">
|
||||
<button type="button" class="order-link" @click="openDetail(scope.row)">{{ scope.row.tradeNo || '-' }}</button>
|
||||
<span class="order-title-line"><button type="button" class="order-link" @click="openDetail(scope.row)">{{ scope.row.tradeNo || '-' }}</button><el-tag v-if="isDemoOrder(scope.row)" size="small" type="info" effect="plain">演示</el-tag></span>
|
||||
<span v-if="scope.row.providerTradeNo">渠道单号 {{ scope.row.providerTradeNo }}</span>
|
||||
<span>{{ scope.row.businessType || '-' }} · {{ scope.row.businessId || '-' }}</span>
|
||||
</div>
|
||||
@@ -140,6 +140,7 @@
|
||||
<div class="mobile-order-meta"><span>{{ order.businessType || '-' }} · {{ order.businessId || '-' }}</span><span>{{ formatDateValue(order.createdAt) }}</span></div>
|
||||
<div class="mobile-order-footer">
|
||||
<div class="status-stack">
|
||||
<el-tag v-if="isDemoOrder(order)" size="small" type="info" effect="plain">演示</el-tag>
|
||||
<el-tag size="small" :type="paymentStatusType(order.paymentStatus)">{{ paymentStatusText(order.paymentStatus) }}</el-tag>
|
||||
<el-tag size="small" :type="fulfillmentStatusType(order.fulfillmentStatus)" effect="plain">{{ fulfillmentStatusText(order.fulfillmentStatus, order) }}</el-tag>
|
||||
<el-tag v-if="order.refundStatus !== 'none'" size="small" :type="refundStatusType(order.refundStatus)" effect="plain">{{ refundStatusText(order.refundStatus) }}</el-tag>
|
||||
@@ -165,6 +166,7 @@
|
||||
<template v-if="detail">
|
||||
<div class="detail-toolbar">
|
||||
<div class="detail-statuses">
|
||||
<el-tag v-if="isDemoOrder(detail)" type="info" effect="plain">演示订单</el-tag>
|
||||
<el-tag :type="paymentStatusType(detail.paymentStatus)">{{ paymentStatusText(detail.paymentStatus) }}</el-tag>
|
||||
<el-tag :type="fulfillmentStatusType(detail.fulfillmentStatus)" effect="plain">{{ fulfillmentStatusText(detail.fulfillmentStatus, detail) }}</el-tag>
|
||||
<el-tag :type="refundStatusType(detail.refundStatus)" effect="plain">{{ refundStatusText(detail.refundStatus) }}</el-tag>
|
||||
@@ -288,7 +290,7 @@ const providerNames = Object.fromEntries(providerOptions.map((item) => [item.val
|
||||
Object.assign(providerNames, { admin: '后台人工操作', client: '客户端', system: '系统任务', internal: '内部支付' })
|
||||
const paymentStatusOptions = Object.entries(PAYMENT_STATUS_META).map(([value, item]) => ({ value, label: item.label }))
|
||||
const refundStatusOptions = Object.entries(REFUND_STATUS_META).map(([value, item]) => ({ value, label: item.label }))
|
||||
const ZERO_DECIMAL_CURRENCIES = new Set(['BIF', 'CLP', 'DJF', 'GNF', 'ISK', 'JPY', 'KMF', 'KRW', 'PYG', 'RWF', 'UGX', 'UYI', 'VND', 'VUV', 'XAF', 'XOF', 'XPF'])
|
||||
const ZERO_DECIMAL_CURRENCIES = new Set(['BIF', 'CLP', 'DJF', 'GNF', 'ISK', 'JPY', 'KMF', 'KRW', 'POINT', 'PYG', 'RWF', 'UGX', 'UYI', 'VND', 'VUV', 'XAF', 'XOF', 'XPF'])
|
||||
const THREE_DECIMAL_CURRENCIES = new Set(['BHD', 'IQD', 'JOD', 'KWD', 'LYD', 'OMR', 'TND'])
|
||||
const FOUR_DECIMAL_CURRENCIES = new Set(['CLF', 'UYW'])
|
||||
const MAX_SAFE_MINOR_AMOUNT = Number.MAX_SAFE_INTEGER
|
||||
@@ -456,9 +458,10 @@ function refundStatusType(status) { return REFUND_STATUS_META[status]?.type || '
|
||||
function paymentModeText(mode) { return mode === 'internal' ? '内部支付' : mode === 'external' ? '外部渠道' : mode || '-' }
|
||||
function formatDateValue(value) { return value ? formatDate(value) || '-' : '-' }
|
||||
function remainingRefundAmount(order) { return Math.max(0, Number(order?.amount || 0) - Number(order?.refundedAmount || 0)) }
|
||||
function canRefund(order) { return ['paid', 'partially_refunded'].includes(order?.paymentStatus) && ['none', 'partial', 'failed'].includes(order?.refundStatus) && remainingRefundAmount(order) > 0 }
|
||||
function canFulfill(order) { return order?.paymentStatus === 'paid' && ['pending', 'processing', 'failed'].includes(order?.fulfillmentStatus) }
|
||||
function canSync(order) { return ['initialized', 'pending', 'paid', 'partially_refunded', 'refunded', 'failed'].includes(order?.paymentStatus) }
|
||||
function isDemoOrder(order) { return order?.businessType === 'demo_subscription' && String(order?.tradeNo || '').startsWith('DEMO-PAY-') }
|
||||
function canRefund(order) { return !isDemoOrder(order) && ['paid', 'partially_refunded'].includes(order?.paymentStatus) && ['none', 'partial', 'failed'].includes(order?.refundStatus) && remainingRefundAmount(order) > 0 }
|
||||
function canFulfill(order) { return !isDemoOrder(order) && order?.paymentStatus === 'paid' && ['pending', 'processing', 'failed'].includes(order?.fulfillmentStatus) }
|
||||
function canSync(order) { return !isDemoOrder(order) && ['initialized', 'pending', 'paid', 'partially_refunded', 'refunded', 'failed'].includes(order?.paymentStatus) }
|
||||
function fulfillmentActionText(order) { return ['processing', 'failed'].includes(order?.fulfillmentStatus) ? '重试发货' : '执行发货' }
|
||||
function isIssueOrder(order) { return order?.paymentStatus === 'failed' || order?.fulfillmentStatus === 'failed' || order?.refundStatus === 'failed' || Boolean(order?.lastError) }
|
||||
function rowClassName({ row }) { return isIssueOrder(row) ? 'is-payment-issue' : '' }
|
||||
@@ -645,6 +648,7 @@ onMounted(load)
|
||||
.issue-count { color: var(--el-color-danger) !important; }
|
||||
.order-cell, .business-cell, .provider-cell, .amount-cell { display: grid; min-width: 0; gap: 5px; }
|
||||
.order-link { overflow: hidden; padding: 0; border: 0; background: transparent; color: var(--el-color-primary); font: inherit; font-weight: 500; text-align: left; text-overflow: ellipsis; white-space: nowrap; cursor: pointer; }
|
||||
.order-title-line { display: flex; align-items: center; gap: 6px; min-width: 0; }
|
||||
.order-cell > span, .business-cell small, .provider-cell small, .amount-cell small { overflow: hidden; color: var(--el-text-color-secondary); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.business-cell > span, .provider-cell > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.amount-cell { justify-items: end; }
|
||||
|
||||
Reference in New Issue
Block a user