Files
Genarrative/apps/admin-web/src/components/AdminUserReferenceButton.tsx
T
kdletters 8862887baa 新增后台充值退款管理与微信V3退款闭环
新增充值订单查询、通用用户详情、钱包冻结与部分退款操作
接入微信V3退款申请、回调、主动查单、交易账单对账与安全诊断
新增退款占用、权益追回、异常欠账和消费限制事务
补齐Native支付SSE自动收口及退款编号与部分退款校验
同步SpacetimeDB schema、生成绑定、测试与项目文档
2026-07-14 12:16:01 +08:00

74 lines
1.8 KiB
TypeScript

import {UserRoundSearch} from 'lucide-react';
import {MouseEvent, useRef, useState} from 'react';
import {AdminUserDetailDialog} from './AdminUserDetailDialog';
interface AdminUserReferenceButtonProps {
token: string;
userId?: string | null;
publicUserCode?: string | null;
onUnauthorized: (message?: string) => void;
}
export function AdminUserReferenceButton({
token,
userId,
publicUserCode,
onUnauthorized,
}: AdminUserReferenceButtonProps) {
const [open, setOpen] = useState(false);
const triggerRef = useRef<HTMLButtonElement | null>(null);
const normalizedUserId = normalizeUserReference(userId);
const normalizedPublicUserCode = normalizeUserReference(publicUserCode);
const lookup = normalizedUserId
? {userId: normalizedUserId}
: normalizedPublicUserCode
? {publicUserCode: normalizedPublicUserCode}
: null;
if (!lookup) {
return null;
}
function openDialog(event: MouseEvent<HTMLButtonElement>) {
event.stopPropagation();
setOpen(true);
}
function closeDialog() {
setOpen(false);
window.requestAnimationFrame(() => triggerRef.current?.focus());
}
return (
<>
<button
ref={triggerRef}
aria-label="查看用户信息"
className="admin-ghost-button admin-user-reference-button"
title="查看用户信息"
type="button"
onClick={openDialog}
>
<UserRoundSearch size={16} aria-hidden="true" />
</button>
{open ? (
<AdminUserDetailDialog
token={token}
{...lookup}
onClose={closeDialog}
onUnauthorized={onUnauthorized}
/>
) : null}
</>
);
}
function normalizeUserReference(value?: string | null) {
const normalized = value?.trim() ?? '';
if (!normalized || normalized.toLowerCase().startsWith('admin:')) {
return '';
}
return normalized;
}