@@ -31,40 +31,40 @@ type UserOrderRow = {
|
||||
createdAt: string;
|
||||
};
|
||||
|
||||
function NicknameCell({
|
||||
function HqRemarkCell({
|
||||
id,
|
||||
nickname,
|
||||
hqRemark,
|
||||
onSaved,
|
||||
}: {
|
||||
id: string;
|
||||
nickname: string | null;
|
||||
onSaved: (id: string, nickname: string | null) => void;
|
||||
hqRemark: string | null;
|
||||
onSaved: (id: string, hqRemark: string | null) => void;
|
||||
}) {
|
||||
const [editing, setEditing] = useState(false);
|
||||
const [value, setValue] = useState(nickname ?? '');
|
||||
const [value, setValue] = useState(hqRemark ?? '');
|
||||
const savingRef = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!editing) setValue(nickname ?? '');
|
||||
}, [nickname, editing]);
|
||||
if (!editing) setValue(hqRemark ?? '');
|
||||
}, [hqRemark, editing]);
|
||||
|
||||
async function commit() {
|
||||
if (savingRef.current) return;
|
||||
const next = value.trim() || null;
|
||||
const prev = nickname?.trim() || null;
|
||||
const prev = hqRemark?.trim() || null;
|
||||
setEditing(false);
|
||||
if (next === prev) return;
|
||||
savingRef.current = true;
|
||||
try {
|
||||
const res = await request<{ id: string; nickname: string | null }>(`/admin/users/${id}`, {
|
||||
const res = await request<{ id: string; hqRemark: string | null }>(`/admin/users/${id}`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({ nickname: next ?? '' }),
|
||||
body: JSON.stringify({ hqRemark: next ?? '' }),
|
||||
});
|
||||
onSaved(id, res.nickname);
|
||||
message.success('昵称已保存');
|
||||
onSaved(id, res.hqRemark);
|
||||
message.success('备注已保存');
|
||||
} catch (e) {
|
||||
message.error(e instanceof Error ? e.message : '保存失败');
|
||||
setValue(nickname ?? '');
|
||||
setValue(hqRemark ?? '');
|
||||
} finally {
|
||||
savingRef.current = false;
|
||||
}
|
||||
@@ -75,7 +75,7 @@ function NicknameCell({
|
||||
<Input
|
||||
size="small"
|
||||
autoFocus
|
||||
maxLength={64}
|
||||
maxLength={128}
|
||||
value={value}
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
onBlur={() => void commit()}
|
||||
@@ -90,14 +90,14 @@ function NicknameCell({
|
||||
|
||||
return (
|
||||
<span
|
||||
title="双击修改,离开后保存"
|
||||
title="双击修改备注,离开后保存"
|
||||
onDoubleClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setEditing(true);
|
||||
}}
|
||||
style={{ cursor: 'text', display: 'inline-block', minWidth: 48 }}
|
||||
>
|
||||
{nickname || '—'}
|
||||
{hqRemark || '—'}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
@@ -332,17 +332,23 @@ export default function UsersPage() {
|
||||
title: '昵称',
|
||||
dataIndex: 'nickname',
|
||||
width: 140,
|
||||
render: (v: string | null) => v || '—',
|
||||
},
|
||||
{
|
||||
title: '备注',
|
||||
dataIndex: 'hqRemark',
|
||||
width: 160,
|
||||
render: (v: string | null, row) => (
|
||||
<NicknameCell
|
||||
<HqRemarkCell
|
||||
id={row.id}
|
||||
nickname={v}
|
||||
onSaved={(id, nickname) => {
|
||||
hqRemark={v}
|
||||
onSaved={(id, hqRemark) => {
|
||||
setData((prev) =>
|
||||
prev
|
||||
? { ...prev, items: prev.items.map((u) => (u.id === id ? { ...u, nickname } : u)) }
|
||||
? { ...prev, items: prev.items.map((u) => (u.id === id ? { ...u, hqRemark } : u)) }
|
||||
: prev,
|
||||
);
|
||||
setDetail((d) => (d && d.id === id ? { ...d, nickname } : d));
|
||||
setDetail((d) => (d && d.id === id ? { ...d, hqRemark } : d));
|
||||
}}
|
||||
/>
|
||||
),
|
||||
@@ -558,6 +564,7 @@ export default function UsersPage() {
|
||||
<Descriptions.Item label="ID">{detail.id}</Descriptions.Item>
|
||||
<Descriptions.Item label="用户编号">{detail.userNo}</Descriptions.Item>
|
||||
<Descriptions.Item label="昵称">{detail.nickname || '—'}</Descriptions.Item>
|
||||
<Descriptions.Item label="备注">{detail.hqRemark || '—'}</Descriptions.Item>
|
||||
<Descriptions.Item label="手机号">{maskPhone(detail.phone)}</Descriptions.Item>
|
||||
<Descriptions.Item label="验手机时间">
|
||||
{detail.phoneVerifiedAt ? new Date(detail.phoneVerifiedAt).toLocaleString('zh-CN') : '未验证'}
|
||||
|
||||
Reference in New Issue
Block a user