feat(log): 计费详情记录域名来源(domain_host), 仅管理员可见

- 域名路由命中时把来源域名存入 ctx, 经 GenerateTextOtherInfo 写进 other.admin_info
- 角色控制纯后端: admin_info 在用户日志接口被 formatUserLogs 自动剥离, 普通用户看不到
- 前端 details-dialog 在管理员区展示「域名来源」一行
This commit is contained in:
2026-06-03 04:48:46 +08:00
parent b6db60dbfb
commit d481e1ae62
6 changed files with 19 additions and 0 deletions

View File

@@ -42,6 +42,10 @@ const (
ContextKeyAutoGroupIndex ContextKey = "auto_group_index" ContextKeyAutoGroupIndex ContextKey = "auto_group_index"
ContextKeyAutoGroupRetryIndex ContextKey = "auto_group_retry_index" ContextKeyAutoGroupRetryIndex ContextKey = "auto_group_retry_index"
// ContextKeyDomainHost 记录命中域名路由时的来源域名(规范化后),
// 写入消费日志的 other.admin_info仅管理员可见。
ContextKeyDomainHost ContextKey = "domain_host"
/* user related keys */ /* user related keys */
ContextKeyUserId ContextKey = "id" ContextKeyUserId ContextKey = "id"
ContextKeyUserSetting ContextKey = "user_setting" ContextKeyUserSetting ContextKey = "user_setting"

View File

@@ -35,6 +35,7 @@ func DomainAutoGroupRouter() gin.HandlerFunc {
if _, valid := setting.GetSecondaryAutoGroup(target); valid { if _, valid := setting.GetSecondaryAutoGroup(target); valid {
common.SetContextKey(c, constant.ContextKeyUsingGroup, target) common.SetContextKey(c, constant.ContextKeyUsingGroup, target)
common.SetContextKey(c, constant.ContextKeyTokenGroup, target) common.SetContextKey(c, constant.ContextKeyTokenGroup, target)
common.SetContextKey(c, constant.ContextKeyDomainHost, domain)
logger.LogDebug(c, "domain routing: %s -> secondary auto group %s", domain, target) logger.LogDebug(c, "domain routing: %s -> secondary auto group %s", domain, target)
} }
} }

View File

@@ -72,6 +72,10 @@ func GenerateTextOtherInfo(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, m
AppendChannelAffinityAdminInfo(ctx, adminInfo) AppendChannelAffinityAdminInfo(ctx, adminInfo)
if domainHost := common.GetContextKeyString(ctx, constant.ContextKeyDomainHost); domainHost != "" {
adminInfo["domain_host"] = domainHost
}
other["admin_info"] = adminInfo other["admin_info"] = adminInfo
appendRequestPath(ctx, relayInfo, other) appendRequestPath(ctx, relayInfo, other)
appendRequestConversionChain(relayInfo, other) appendRequestConversionChain(relayInfo, other)

View File

@@ -549,6 +549,14 @@ export function DetailsDialog(props: DetailsDialogProps) {
<DetailRow label={t('Retry Chain')} value={channelChain} mono /> <DetailRow label={t('Retry Chain')} value={channelChain} mono />
)} )}
{other?.admin_info?.domain_host && props.isAdmin && (
<DetailRow
label={t('Domain source')}
value={other.admin_info.domain_host}
mono
/>
)}
{props.log.token_name && ( {props.log.token_name && (
<DetailRow <DetailRow
label={t('Token')} label={t('Token')}

View File

@@ -3378,6 +3378,7 @@
"Retention days": "Retention days", "Retention days": "Retention days",
"Retry": "Retry", "Retry": "Retry",
"Retry Chain": "Retry Chain", "Retry Chain": "Retry Chain",
"Domain source": "Domain source",
"Retry Suggestion": "Retry Suggestion", "Retry Suggestion": "Retry Suggestion",
"Retry Times": "Retry Times", "Retry Times": "Retry Times",
"Return a custom error immediately": "Return a custom error immediately", "Return a custom error immediately": "Return a custom error immediately",

View File

@@ -3378,6 +3378,7 @@
"Retention days": "保留天数", "Retention days": "保留天数",
"Retry": "重试", "Retry": "重试",
"Retry Chain": "重试链路", "Retry Chain": "重试链路",
"Domain source": "域名来源",
"Retry Suggestion": "重试建议", "Retry Suggestion": "重试建议",
"Retry Times": "重试次数", "Retry Times": "重试次数",
"Return a custom error immediately": "立即返回自定义错误", "Return a custom error immediately": "立即返回自定义错误",