Commit Graph
22 Commits
Author SHA1 Message Date
xuyueandClaude Opus 5.5 302eae4f13 代码编辑器:代码补全、悬停提示、参数提示、边写边检查
- 运行器新增 language-server 模式:常驻语言服务,和编译服务分开;用 Roslyn 的
  CompletionService、QuickInfoService(和 VS 的 IntelliSense 同一套引擎),参数提示用语义模型实现;
  每个浏览器标签页一份工程,只更新有变化的文件;去掉仿真类库的可空注解(string? → string)
- 编译和语言服务共用同一套编译选项和引用;检查结果带上禁止 API 的报错和中文提示
- 服务端 POST /api/language 转发请求(按用户区分会话,10 秒超时)
- 编辑器:补全("." 触发,选中时取说明)、悬停、参数提示("(" "," 触发);停止输入 1 秒后检查整个工程,
  和"运行"时的编译结果以较新的为准
- 实测(2 核):50 个标签页同时检查 1.2 秒内完成,同时补全 0.7 秒;内存约 260 MB

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 19:23:55 +08:00
xuyueandClaude Opus 5.5 89e9956a22 评阅与成绩:老师看代码、运行学生程序、打分、写评语;成绩表与导出
- 评阅页:全班学生列表(提交状态、得分、是否已评阅);选中学生的代码(只读)、自动评分结果、
  规范提示(代码里用到的默认名字控件、注释行数)、老师评分项打分和评语,"保存并看下一个"
- "运行他的程序":新标签页里打开学生的提交,可以操作实训台,改动不保存
- 学生能看到老师的各项得分和评语;作业列表显示总分
- 班级管理页"成绩"标签页:学生 × 作业的总分,点分数进入评阅;单个作业和全班成绩导出 CSV
- 老师增删评分项后,已打的分按新的评分项对齐

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 19:13:30 +08:00
xuyueandClaude Opus 5.5 4e6b0d5cb2 布置作业、提交与自动评分
- 作业:老师选实验、起点(界面已做好 / 空白工程)、截止时间、每项分值(自动评分项 + 老师评分项);
  起点工程由设计器引擎从参考答案生成(去掉事件绑定和事件处理方法),布置时保存起点和评分规则快照
- 提交:后台排队评分(全站同时最多评 3 份、跑 6 个检查项),重启后继续评;评分中不能再交,截止后不能交
- 学生:"我的作业"列表;实验页的作业模式(作业名、截止时间、提交、得分),评分结果弹出逐项显示
- 老师:班级管理页加"作业"标签页,布置、修改、删除作业,查看全班提交情况;改分值后重新算分
- 串口列表为空时提示在 Load 或 Click 事件里填充
- 测试:作业接口(可见范围、排队评分、部分得分、改分值、截止、删除);10 个示例两种起点都能编译

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 19:02:22 +08:00
xuyueandClaude Opus 5.5 37fc747b49 自动评分:评分规则和执行引擎
- 每个示例的 checks.yaml:书上评价表的功能项转成操作步骤和期望结果(10 个示例共 23 项)
- 引擎:编译一次,每项在沙箱里单独启动一次程序,按控件名操作、调节实训台、核对结果;
  提示框自动点第一个按钮;全站同时最多跑 2 项
- 不通过时写明期望和实际,如"期望6 秒内 txt_even 的文字包含"发现入侵",实际是"正常"";
  找不到书上规定的控件名时直接指出
- 规则写错时指出第几项第几步
- 测试:参考答案全部通过;编译错误、控件改名、判断写反、忘停定时器、接错 DO 口各自报出对应原因

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 18:20:46 +08:00
xuyueandClaude Opus 5.5 5bb2940969 登录改用访问令牌 + 刷新令牌,不用 cookie
- 访问令牌:JWT(HS256),15 分钟,Authorization: Bearer;WebSocket 放在网址参数里
- 刷新令牌:30 天,每次刷新换新的,数据库只存哈希;退出登录即作废
- 重置密码、删除学生:令牌版本加一并删除刷新令牌,所有设备立即退出
- 签名密钥首次使用时生成,存在数据库 settings 表
- 浏览器:令牌存 localStorage;快过期先刷新,401 时刷新一次再重试;多个标签页同时刷新不冲突

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 18:20:41 +08:00
xuyueandClaude Opus 5.5 a3eb563b70 设计器:Designer.cs 标签页默认隐藏
和 VS 里藏在窗体文件下面一样,平时不显示;在设计器里点"查看生成的代码"或点到其中的
编译错误时才临时出现,切走后收起。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 18:20:41 +08:00
xuyueandClaude Opus 5.5 400814d1f6 .env.example 写全所有配置项和默认值
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 17:37:03 +08:00
xuyueandClaude Opus 5.5 7cec273d58 第 2 阶段:账号与班级,作品保存在服务器
- SQLite(bun:sqlite,编号迁移):班级、用户、会话(只存令牌哈希)、作品
- 登录取代统一访问口令:老师账号由配置设定;接口和 WebSocket 都要登录;按 IP 限制输错次数
- 班级管理页:建班、改名、删除(有学生时不能删);上传 CSV 名单导入(兼容 GBK / UTF-8,
  识别表头,标出被 Excel 变成科学计数法的学号),密码留空生成 6 位数字;查看、重置密码,
  导出带密码的名单
- 学生作品自动保存到服务器(按账号和实验),显示保存状态;离开页面前立即保存
- 前端加路由:登录页、实验页、班级管理页
- 部署:TEACHER_PASSWORD 必填,数据库放在数据卷

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 17:36:11 +08:00
xuyueandClaude Opus 5.5 a00622be15 部署改为在服务器上构建:Actions 测试通过后 SSH 执行 deploy/update.sh
CI/CD / test (push) Canceled after 0s
CI/CD / deploy (push) Canceled after 0s
跨境上传 130 MB 镜像 40 分钟没传完。改为服务器从 origin(git.xuyue.cc)拉代码、
构建镜像、重启,等编译服务就绪;提交还没到 origin 时等待重试。
部署任务加 20 分钟超时,SSH 认证失败立即报错。去掉 deploy/deploy.sh。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 16:41:50 +08:00
xuyueandClaude Opus 5.5 1cb2235c3d GitHub Actions:测试和自动部署
CI/CD / test (push) Canceled after 0s
CI/CD / deploy (push) Canceled after 0s
- 每次推送和 PR:编译 C# 运行时,跑服务端测试(含 bubblewrap 沙箱)、网页端测试和类型检查
- 推送到 main 且测试通过:带缓存构建镜像,经 SSH 传到服务器并重启;Secrets 未配置时跳过部署
- 只在 github.com 上运行,git.xuyue.cc 上跳过
- deploy.sh:SKIP_BUILD 跳过构建;启动后等编译服务就绪,沙箱自检失败时部署失败;
  服务器目录默认 ~/IOT_SIM

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 15:56:09 +08:00
xuyue d5bec7c8af update 2026-10-22 15:43:15 +08:00
xuyueandClaude Opus 5.5 697f31e9ce 部署:bubblewrap 沙箱、编译检查、访问口令、Docker Compose
- 学生程序每次运行放进 bubblewrap:断网,只读挂载系统文件、运行时和自己的工程目录,
  看不到其他进程和服务器环境变量;限制堆内存 128 MB、CPU 时间 120 秒、运行 60 分钟,
  nice 10,全站同时运行上限 150;启动时自检沙箱,不可用时拒绝运行
- 编译检查(SIM001):网络、反射、启动进程、调用本机代码、加载程序集、dynamic 给出中文报错
- 访问口令:cookie 保存口令哈希,按真实 IP 限制输错次数;前端口令页
- 服务端配置集中到 config.ts,可用环境变量覆盖;Bun 直接提供打包好的网页
- Dockerfile(多阶段,服务端打包成单文件)、compose.yaml(Caddy 只收 HTTP,接入 NPM 的
  npm_proxy 网络)、deploy/deploy.sh(本机构建后经 ssh 传到服务器)和部署说明
- 测试:沙箱隔离、内存上限、CPU 时间上限、编译检查

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 15:40:09 +08:00
xuyueandClaude Opus 5.5 081ac6f924 实训台按宽度自适应布局,可以收起
- 传感器卡片:宽时排一行,中等宽度分两行(开关卡片一行、滑块卡片一行),窄时每行 2 个
- 收起后只留一行状态(警示灯、照明灯、温湿度光照读数、LED 文字),传感器开关仍可点击;收起状态记在浏览器本地
- 设计器的撤销 / 重做按钮不再在窄屏下折行

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 11:34:21 +08:00
xuyueandClaude Opus 5.5 4c53caf7fa 整理教材示例:项目 1 任务 2、项目 4 任务 1 和 3、项目 5 任务 1
- 界面取自配套参考工程,用设计器引擎按书上表格改控件名(label1 → lbl_port 等),
  去掉 BOM、换行统一为 LF;代码按书整理,修正 boolIsOpen 等印刷错误
- 测试:所有示例都能编译(10 个),以及计算器 / 多态、红外对射、报警灯、火焰的行为测试

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 11:29:37 +08:00
xuyueandClaude Opus 5.5 8feda289de 多窗体:新建 / 删除窗体,项目 1 登录示例;标识符支持中文
- 新建窗体:生成与 VS 新建窗体相同的 X.cs 和 X.Designer.cs,沿用工程命名空间;
  删除窗体(启动窗体不能删)
- 标签页按窗体分组,启动窗体排在最前并默认打开
- 运行时点哪个窗口哪个到最前;消息框始终在所有窗口之上
- 示例:项目 1 任务 1 登录与增加用户,两个窗体的 Designer.cs 由设计器引擎生成;
  修正书上未声明的 change 变量、关闭后重复 Show 已释放窗体的问题
- 设计器的正则支持中文控件名、类名、命名空间
- 修正:切换窗体时属性窗口的名称没有刷新
- 测试:多窗体端到端测试;新窗体模板测试

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 11:23:37 +08:00
xuyueandClaude Opus 5.5 02d2f0eabc 设计器:撤销 / 重做;工具箱、属性、事件窗口改为中文
- 撤销 / 重做按窗体保存在页面层,切换标签页不丢;Ctrl+Z、Ctrl+Y / Ctrl+Shift+Z
- 撤销"生成事件处理方法"时事件绑定和插入的方法一起撤掉;
  学生已在方法里写了代码则只撤销设计,不动代码
- Designer.cs 在代码页被手改后,该窗体历史失效并清空,避免覆盖手改内容
- 没有实际改动的操作(如双击已绑定的事件)不记入历史
- 工具箱、属性名、事件名、枚举选项显示中文;悬停显示英文名和用途说明
- 开发模式下把页面状态挂到 window.__iot,供浏览器自动化测试读取

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 11:18:43 +08:00
xuyueandClaude Opus 5.5 ea5a25af06 窗体设计器:工具箱、拖放、属性与事件窗口,读写 VS 格式的 Designer.cs
- Designer.cs 在浏览器端解析为语句列表,未改动的语句保留原文:
  教材 25 个参考窗体和全部示例读入再写出逐字节不变
- 编辑操作:添加 / 删除 / 移动 / 改名控件、属性、事件、列表项;
  布局语句增删规则与 VS 一致(对全部现有文件执行无变化)
- 双击控件或事件:绑定事件并在窗体代码末尾插入处理方法,跳到代码
- 预览复用运行时的 ControlView,设计时与运行时外观一致
- 修正:窗体属性 this.ClientSize = new Size(...) 被误认成创建控件;
  示例 Designer.cs 的块头注释改为 VS 的 "// " 格式
- 测试:73 个(读写往返、布局规则、编辑操作、插入事件处理方法)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 11:11:48 +08:00
xuyueandClaude Opus 5.5 03e80ce2e2 代码编辑器换成 Monaco:C# 高亮、错误波浪线与跳转、F5 运行、草稿保存
- 编译错误以波浪线标在代码里,点下方错误信息跳到对应行
- F5 运行、Shift+F5 停止,在整个页面生效并阻止浏览器刷新
- 改过的代码保存在浏览器本地,刷新不丢,可一键恢复原始代码
- Designer.cs 顶部提示由设计器生成
- Monaco 按需加载(编辑功能 + C# 高亮),打包后约 1.2 MB(gzip)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 10:56:34 +08:00
xuyueandClaude Opus 5.5 fbb8a334c3 设计方案迁入仓库(docs/设计方案.md),按第 0、1 阶段的实际实现更新
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 10:38:04 +08:00
xuyueandClaude Opus 5.5 942c319bab 灯泡、报警灯改用自绘 SVG,删除教材配套资料中的图片
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 10:36:52 +08:00
xuyueandClaude Opus 5.5 26104ae81e 第 1 阶段:虚拟实训台,项目 2、3 的示例跑通
- 实训台状态由服务器统一保存:滑块和开关设定传感器读数,推给学生程序;
  学生程序控制的灯、继电器、LED 屏回写到实训台
- 网页按教材实训台布局图绘制实训台,传感器卡片上直接调节环境
- 新控件:CheckBox、RadioButton(事件顺序与 WinForms 一致),Lamp、Alarm
- 设备类库:串口未打开时控制无效,与实物一致
- 修正:列表属性序列化时数字被转成字符串
- 示例:项目 2 任务 2–3、项目 3 任务 1–2;网址参数 ?sample= 打开指定示例
- 测试:实训台单元测试,项目 2、3 的端到端测试

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 10:32:38 +08:00
xuyueandClaude Opus 5.5 98be8331bc 第 0 阶段:教材项目 2 任务 1 在网页中原样运行
- runtime:仿真 WinForms 子集(Form、Button、Label、TextBox、ComboBox、
  GroupBox、Timer、MessageBox、界面线程消息循环、跨线程检查)、
  教材设备类库(DeviceCtrlHelper、LED 控件)、运行器(常驻编译服务 + 运行模式)
- server:Bun + Hono,WebSocket 会话,每次运行一个进程,消息转发
- web:Vue + Naive UI,WinForms 风格窗体渲染、MessageBox、实训台 LED 屏
- 端到端测试与 100 个程序并发的压力测试
- 教材逐任务摘要(docs/教材摘要)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 10:15:14 +08:00