feat(admin): 弹窗未保存内容保护与空状态引导扩展

- 新增 useDirtyGuard hook:关闭弹窗时若表单被修改,先确认再关闭
- 接入 17 个弹窗:账号/密码/档案、角色、教室、宿舍/床位/柜子、
  考勤机、机构、班级、教师、考试、排课、入住/退宿/换房、费用
  (子组件弹窗用 useEffect 在回填后快照,时序正确)
- 学生列表空状态带「添加学生」引导动作
- 排课创建成功提示「同步钉钉」,考试创建成功提示「去详情录成绩」

aislop scan: 5 引擎 0 issues
This commit is contained in:
2026-08-07 17:56:13 +08:00
parent bcbf3c8b2e
commit c10476d203
16 changed files with 273 additions and 49 deletions

View File

@@ -11,6 +11,7 @@ import { usePermission } from '../../hooks/usePermission';
import { useApiMutation } from '../../hooks/useApiMutation';
import { validateResponse } from '../../utils/validate';
import { organizationsSchema } from '../../api/schemas';
import { useDirtyGuard } from '../../hooks/useDirtyGuard';
const PRESET_COLORS = [
'#ff7875',
@@ -52,6 +53,7 @@ const OrganizationsPage: React.FC = () => {
const [modalOpen, setModalOpen] = useState(false);
const [editing, setEditing] = useState<OrganizationItem | null>(null);
const [form] = Form.useForm();
const orgGuard = useDirtyGuard(form);
const [saving, setSaving] = useState(false);
const [searchText, setSearchText] = useState('');
const [filterStatus, setFilterStatus] = useState<string>();
@@ -133,6 +135,7 @@ const OrganizationsPage: React.FC = () => {
form.resetFields();
if (record) form.setFieldsValue(record);
else form.setFieldsValue({ color: PRESET_COLORS[data.length % PRESET_COLORS.length] });
orgGuard.snapshot();
setModalOpen(true);
};
@@ -408,7 +411,7 @@ const OrganizationsPage: React.FC = () => {
title={editing ? `编辑机构 · ${editing.name}` : '添加外部机构'}
open={modalOpen}
onOk={handleSave}
onCancel={() => setModalOpen(false)}
onCancel={() => orgGuard.confirmClose(() => setModalOpen(false))}
confirmLoading={saving}
okText="保存"
>