fix: 空评论列表 500,并完善撤回审计与角色说明
空切片 JSON 统一为数组;撤回保留正文供站长阅读,成员侧居中提示与重新编辑;头像支持拖放;角色弹窗补全职责说明并汇入封禁。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -11,6 +11,9 @@ interface AvatarPickerProps {
|
||||
name: string;
|
||||
src: string;
|
||||
size?: number;
|
||||
/** 外部拖入的文件:非空时打开裁剪弹窗并进入裁剪 */
|
||||
incomingFile?: File | null;
|
||||
onIncomingConsumed?: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -23,10 +26,13 @@ interface AvatarPickerProps {
|
||||
* 另外监听广播,使页面上若存在多个 picker 实例也保持一致;
|
||||
* 并随 src prop(SSR 校正)同步,避免 useState 初始值造成数据漂移。
|
||||
*/
|
||||
export default function AvatarPicker({ name, src, size = 56 }: AvatarPickerProps) {
|
||||
export default function AvatarPicker({
|
||||
name, src, size = 56, incomingFile, onIncomingConsumed,
|
||||
}: AvatarPickerProps) {
|
||||
const router = useRouter();
|
||||
const [open, setOpen] = useState(false);
|
||||
const [current, setCurrent] = useState(src);
|
||||
const [seedFile, setSeedFile] = useState<File | null>(null);
|
||||
|
||||
// SSR props 校正(router.refresh 后服务端数据回流)
|
||||
useEffect(() => setCurrent(src), [src]);
|
||||
@@ -36,13 +42,26 @@ export default function AvatarPicker({ name, src, size = 56 }: AvatarPickerProps
|
||||
if (typeof patch.avatar === "string") setCurrent(patch.avatar);
|
||||
}), []);
|
||||
|
||||
// 外层拖入:打开弹窗并交给裁剪流程
|
||||
useEffect(() => {
|
||||
if (!incomingFile) return;
|
||||
setSeedFile(incomingFile);
|
||||
setOpen(true);
|
||||
}, [incomingFile]);
|
||||
|
||||
const handleChanged = (avatar: string) => {
|
||||
setCurrent(avatar);
|
||||
setOpen(false);
|
||||
setSeedFile(null);
|
||||
emitUserUpdate({ avatar });
|
||||
router.refresh();
|
||||
};
|
||||
|
||||
const handleSeedConsumed = () => {
|
||||
setSeedFile(null);
|
||||
onIncomingConsumed?.();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
@@ -66,9 +85,14 @@ export default function AvatarPicker({ name, src, size = 56 }: AvatarPickerProps
|
||||
|
||||
<AvatarCropModal
|
||||
open={open}
|
||||
onClose={() => setOpen(false)}
|
||||
onClose={() => {
|
||||
setOpen(false);
|
||||
setSeedFile(null);
|
||||
}}
|
||||
currentAvatar={current}
|
||||
onChanged={handleChanged}
|
||||
seedFile={seedFile}
|
||||
onSeedConsumed={handleSeedConsumed}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user