A_Pair v1.2.0 引导系统和拖拽操作
A_Pair v1.2.0
发布日期:2026-06-19
🎯 本次更新亮点
- 交互式引导系统 — 19 步首次启动引导 + 页面引导,新用户零门槛上手
- 拖拽换座 — 座位画布上直接拖放交换,全功能撤销/重做
- 教师/学生视角导出 — Excel/CSV/PDF/PNG 导出支持双视角,按讲台方向翻转标签
✨ 新增功能
引导系统
- 19 步启动引导:首次启动时带领用户完成「成员管理 → 会场配置 → 策略配置 → 排座生成 → 快照历史」全工作流
- 页面引导:首次进入 FreeformManagement、PluginManagement 时自动触发,展示该页面关键操作
- 纯 JSON 驱动:所有阶段、步骤、目标控件在
onboarding_config.json(v3.0) 中声明,零 C# 硬编码 - 纯内存示例数据:引导期间自动注入演示数据(不落盘),引导结束后自动清除(ADR-008)
- 窗口状态同步:最小化/Alt+Tab 时自动收起引导弹窗,恢复后定位到当前步骤
- 引导重启:设置页提供「重新开始引导」入口
拖拽换座
- 画布拖放:座位上直接拖拽到另一座位完成交换,拖到垃圾桶移除学生
- 学生列表拖放:从右侧学生列表拖到座位完成分配
- CanvasZoomPan 兼容:拖放期间通过 NaN 哨兵机制自动跳过画布平移,无冲突
RemoveStudentCommand:可撤销的学生移除命令,完整集成 CommandHistory- 详见
A_Pair.Presentation.Avalonia/docs/DragDrop.md
教师/学生视角导出
LayoutPerspective枚举:StudentView(学生视角,默认)和TeacherView(教师视角,镜像)- 四种导出格式(Excel、CSV、PDF、PNG)全部支持视角选择
- 座位位置标签按视角自动翻转(如「前排」↔「后排」)
插件系统(v1.1 重构)
- 多策略插件包架构(ADR-007):双层清单 —
plugins-manifest.json(包级)+manifest.json(策略级) - 热插拔:
RefreshPackageAsync+SetStrategyEnabledAsync即时生效 .ap-plugin打包格式(兼容旧.apairplugin)- 旧单文件格式已不再支持,需迁移为双层清单
数据持久化容错(v1.2.0 新增修复)
- 策略配置数据在会员删除/会场缩小后自动清理无效行
StrategyConfig重启后从磁盘恢复(不再丢失参数)NoRepeatDeskMate历史提取改为单学生级过滤(同对学生移除不再连带丢失历史)- 详见
docs/StrategyDataResilience.md
工具与文档
- i18n 脚本(
scripts/i18n.py):Python 3,.resx三文件同步 CRUD +Designer.cs自动生成。自动备份到Lang/.backup/ - ADR-006 补充(依赖策略三态、能力声明系统)
- ADR-007(多策略插件包架构)
- ADR-008(引导系统纯内存示例数据注入)
docs/DragDrop.md、docs/ONBOARDING_GUIDE.md、docs/StrategyDataResilience.md
🔄 变更
- 快照改为手动保存:
GenerateSeatingAsync()不再自动保存快照,用户通过 UI 手动触发CreateSnapshotAsync - 引导重构:从硬编码 7 步改为 JSON 驱动 19 步启动引导 + 2 个页面引导
- 页面切换动画:CrossFade → Slide(200ms),引导导航跳过动画直接切换
- SeatingArrangement:画布重构支持拖放 + 创建空布局 + 手动快照 + 策略消息面板折叠
- DeskMate 策略重写:从独立策略改为依赖策略,在 RandomFill 分配循环中执行,三级协调分配
- 策略管道模型:从「后可覆盖」改为「按优先级填空」(Priority 降序,先到先得)
- Priority 语义反转:数值越大越先执行(FixedSeat=100 → FrontRowRotation=50 → RandomFill=1 → Defrag=0)
- MainWindow:侧栏整合到
MainShellViewModel,新增窗口激活/失活事件转发 - Settings:外观/行为分组重构,最大快照数可配置
- VenueConfiguration:
NewVenue()取消飞行中的异步加载消除竞态 - 侧栏宽度:展开 140px / 折叠 64px
- Config 路由:内置策略 →
AppData/StrategyConfig/,插件策略 →Plugins/{pkgId}/{strategyPath}/ JsonSerializerOptions统一:JsonOptions静态池消除重复分配[ObservableProperty]全面转换:C# 13 partial 属性语法- 所有
.axaml视图添加x:Name支持引导系统目标解析
🐛 修复
- 修复侧栏拖动范围越界
- 修复引导 Popup 失焦后仍可见的孤立窗口问题
- 修复引导页面切换时 target 解析失败(先导航后解析 x:Name 顺序修正)
- 修复策略配置页引导中 ToggleSwitch 未被框中的问题
- 修复初次启动时配置文件未创建导致引导不显示
- 修复参数缺失导致的策略配置加载失败
- 修复快照轮转删除逻辑
- 修复控件边框渲染不显示的问题
- 修复无法拖动座位的问题
- 修复
.resx与Designer.cs不一致导致的编译问题 - 修复配置读写路径不一致(插件策略路由到
PluginPackageConfigService) CircularHistory.Add无去重导致快照回滚时历史膨胀- DeskMate 腾挪操作污染
RecentSeatHistory - 所有
Dispose()补充GC.SuppressFinalize(this)(8 处) CancellationToken未转发修复(6 处)
📦 依赖
| 运行时 | 版本 |
|---|---|
| .NET SDK | 10.0 |
| Avalonia UI | 12.0.4 |
| CommunityToolkit.Mvvm | 8.4 |
| FluentIcons.Avalonia | 2.1.325 |
📚 文档
| 文档 | 说明 |
|---|---|
docs/ONBOARDING_GUIDE.md |
引导系统设计文档 |
docs/DragDrop.md |
Avalonia 12 拖放实现模式与 CanvasZoomPan 交互 |
docs/StrategyDataResilience.md |
策略数据持久化与容错分析 |
docs/adr/ |
8 篇架构决策记录 (ADR-001 ~ ADR-008) |
scripts/I18N.md |
i18n 管理脚本文档 |
⬆️ 升级注意事项
- 快照不再自动生成:升级后需手动点击「保存为快照」按钮
- 插件清单格式变更:必须使用
plugins-manifest.json(包级)+manifest.json(策略级)双层格式;旧plugin.manifest.json单文件格式在 v1.1.0 已移除,不再支持 - 插件扩展名变更:推荐使用
.ap-plugin,旧.apairplugin仍受支持 - Priority 语义变更:数值越大 = 越先执行(与 v1.0 相反),升级后请检查策略优先级配置
- DeskMate 策略:已从独立策略改为依赖策略,旧配置自动迁移
下载注意事项
版本选择
每个平台提供两种版本,文件名格式为 A_Pair-{类型}-{平台}:
| 后缀 | 类型 | 体积 | 前提 |
|---|---|---|---|
-sc- |
自包含(Self-Contained) | ~160 MB | 无需安装任何运行时,开箱即用 |
-fd- |
依赖运行时(Framework-Dependent) | ~80 MB | 需安装 .NET 10 运行时 |
文件名示例:
A_Pair-v1.1.0-self-contained-win-x64-unsigned.exe= 自包含版 · Windows 64位 · 无需装 .NET
程序未签名
当前版本尚未进行代码签名,运行时可能遇到以下情况:
- Windows:双击后 SmartScreen 弹出 "Windows 保护了你的电脑" 警告。点击「更多信息」→「仍要运行」即可。
- macOS:首次打开时提示 "无法验证开发者"。前往「系统设置 → 隐私与安全性」→ 点击「仍要打开」。
- Linux:下载后需手动赋予执行权限:
chmod +x A_Pair-sc-linux-x64-unsigned && ./A_Pair-sc-linux-x64-unsigned
后续版本计划申请代码签名证书以消除这些警告。
使用方式
- 将下载的单个可执行文件放入一个空文件夹
- 直接运行即可(程序会在同目录创建
AppData/存放配置和数据)
下载后请校验哈希值
| 文件 | SHA256 |
|---|---|
A_Pair-v1.2.0-framework-dependent-linux-x64-unsigned |
8e5ade6b7c52d3eb538db183e13650c0668785252657ad70e43f0be4ca5a2fca |
A_Pair-v1.2.0-framework-dependent-osx-arm64-unsigned |
8f0ac6c163743ed616d147d9f887ba579140b9eabbf7ec903be214d53903fc8f |
A_Pair-v1.2.0-framework-dependent-osx-x64-unsigned |
fa55d3dcf1b9f548bcf6e952bbd6716d000354b6429ab66ac51c3f467f8d4b90 |
A_Pair-v1.2.0-framework-dependent-win-x64-unsigned.exe |
3473b91b39412c17b8bd6abf029e4d9902b6b7386df766fa204304bd46a5a13b |
A_Pair-v1.2.0-self-contained-linux-x64-unsigned |
3986301ab2da41328ceb48d9568c2ad32b1fb0262f0e4478550d807dca1f7ce2 |
A_Pair-v1.2.0-self-contained-osx-arm64-unsigned |
26bb31d515c4724a09765a39b80f0562b2e4c1a7e2219f9af7ab807bea6d07f4 |
A_Pair-v1.2.0-self-contained-osx-x64-unsigned |
a1ebbc7417dfc45e76bf26e243ae48722bed3962cc4702a737c9343cee27b383 |
A_Pair-v1.2.0-self-contained-win-x64-unsigned.exe |
c4dd4ad73d4a4202eacc712abcd97e7f87182cbcd0a2f125c8903e5bd680df03 |