feat: Excel 导入预检与动态问答,AI 聊天/文件解析体验修复

- imports: 新增 preflight_import 预检报告(判定/分阶段统计/阻断归因/问题/下一步/错误示例),导入任务 settings 落库(映射/校区/更新/重复/未匹配策略),预览应用策略,向导提交写操作日志
- ai-chat: 新增 excel_analyze(ExcelJS)工具,移除附件/上下文截断,start_import_wizard 支持确认参数,ui.import_preflight SSE,预览确认写操作日志
- admin: ImportPreflightCard 渲染与持久化,聊天抽屉布局/侧边栏修复,考勤页 CSS 引入,费用/学生页接口 schema 校验修复
This commit is contained in:
2026-08-05 21:12:50 +08:00
parent b70f45fb04
commit ab4765cee5
44 changed files with 2449 additions and 166 deletions

View File

@@ -4,6 +4,7 @@ import { useUserStore } from '../../store/user/userStore';
import { getAttendanceExperience } from './attendance-workspace';
import { TeacherAttendanceWorkspace } from './teacher';
import { AdminAttendanceArchive } from './admin';
import './attendance.css';
function readCurrentRoles(): string[] {
const roles = useUserStore.getState().user?.roles;

View File

@@ -9,7 +9,12 @@ import { message } from '../../ui/app-message';
import { usePermission } from '../../hooks/usePermission';
import { useApiMutation } from '../../hooks/useApiMutation';
import { validateResponse } from '../../utils/validate';
import { expenseLookupsSchema, expenseRecordsSchema } from '../../api/schemas';
import {
expenseLookupsSchema,
expenseRecordsSchema,
expenseRoomsListSchema,
expenseStudentLookupsSchema,
} from '../../api/schemas';
import { archiveViewPolicy, expenseStatusForView } from '../archive-view';
import { ExpenseTablePanel } from './ExpenseTablePanel';
import { PersonalExpenseModal, RoomExpenseModal, UtilityModal } from './ExpenseModals';
@@ -70,10 +75,10 @@ const ExpensesPage: React.FC = () => {
try {
const [rooms, personal, students, roomsList] = await Promise.all([
api.get('/expenses/room', {
params: expenseStatusForView(showArchived ? 'archived' : 'active'),
params: { status: expenseStatusForView(showArchived ? 'archived' : 'active') },
}),
api.get('/expenses/personal', {
params: expenseStatusForView(showArchived ? 'archived' : 'active'),
params: { status: expenseStatusForView(showArchived ? 'archived' : 'active') },
}),
api.get('/expenses/student-lookups'),
api.get('/rooms'),
@@ -81,8 +86,8 @@ const ExpensesPage: React.FC = () => {
return {
rooms: validateResponse(expenseRecordsSchema, rooms),
personal: validateResponse(expenseRecordsSchema, personal),
students: validateResponse(expenseRecordsSchema, students),
roomsList: validateResponse(expenseRecordsSchema, roomsList),
students: validateResponse(expenseStudentLookupsSchema, students),
roomsList: validateResponse(expenseRoomsListSchema, roomsList),
};
} catch {
message.error('加载费用数据失败');