Commit Graph
11 Commits
Author SHA1 Message Date
xuyueandClaude Opus 5.5 d60868d912 停靠布局、背景图片、无边框窗体;运行区按比例缩小、可放大
- Dock:和 WinForms 一样按 Controls 倒序依次停靠,扣掉 Panel 边框、GroupBox 标题占的地方;
  改大小、显示隐藏、加入移出控件时重新布局;SuspendLayout / ResumeLayout / PerformLayout
- 设计器里每次修改后按同样的规则排好停靠的控件(designer/layout.ts);属性窗口加"停靠"
- BackgroundImage + BackgroundImageLayout(平铺、居中、拉伸、缩放):窗体、面板、图片框,
  设计器里从项目资源选;无边框窗体没有标题栏,大小不含边框
- 背景色沿用父控件:没设背景色的标签、面板、分组框等画父控件的背景色(不是背景图片),
  和 WinForms 一样;分组框标题处边框断开、透出背景;文本框的 BackColor 生效
- 图片框可以放子控件,把鼠标按下、松开发给程序
- 运行区:窗体比运行区大时整体按比例缩小并显示比例;"放大"占满整个网页(窗体在左、实训台在右),Esc 还原
- Paint 事件:VS 双击面板生成的空 panel1_Paint 能编译(平台由浏览器绘制,不触发)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 15:14:34 +08:00
xuyueandClaude Opus 5.5 13c3e4c3ec 数据库:参数化的日期字符串比较时也转换格式
- 教材项目 8 用参数传 "2024/1/23  23:59:59"(日期和时间之间两个空格)做 BETWEEN,
  比较时用 tsql_cmp 把形如日期的字符串转成标准格式;日期和时间之间允许多个空格

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 15:13:28 +08:00
xuyueandClaude Opus 5.5 19d6872d80 清理运行时的编译警告
- 媒体播放器内部的 Controls 类改名 PlayerControls,不再隐藏 Control.Controls
- DataGridView 的 CellEnter、RowEnter 不触发,标明不报"从不使用"

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 15:13:28 +08:00
xuyueandClaude Opus 5.5 eedf1aa2fb 项目 7 情景控制:虚拟时钟、项目资源、Windows Media Player、TrackBar
- 虚拟时钟:实训台时钟面板可拨时间、1×/10×/60× 倍速、恢复真实时间;编译时把
  DateTime.Now / Today / UtcNow 改写成 SimClock;评分规则加 clock 步骤
- 项目资源(Properties.Resources):平台素材库(自绘开关图片、合成门铃声),"项目资源"对话框勾选,
  平台生成 Properties/Resources.Designer.cs;设计器图片框的"图片"属性可选资源;程序目录下的 Resources
  指向素材库;未添加资源时给中文提示
- Windows Media Player(AxWMPLib):设置 URL 自动播放、Ctlcontrols.play/stop,浏览器里播放声音,
  实训台加广播喇叭;编译时给窗体嵌空资源,OcxState 取到 null 不报错;图片和声音统一按内容缓存(blob)
- TrackBar:拖动、点轨道、方向键,先 ValueChanged 再 Scroll;设计器加"滑动条""媒体播放器"
- 评分规则加 value、media 检查;示例项目 7 任务 1–3(修正书上开关灯判断写反、漏填串口列表)
- 修正:Properties/ 下的资源类不当作窗体;带命名空间的 System.AppDomain.CurrentDomain.BaseDirectory 放行
- 测试:虚拟时钟、TrackBar、项目 7 示例评分、作业起点带资源类

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 14:11:05 +08:00
xuyueandClaude Opus 5.5 670abe5921 项目 6 数据存储:仿冒 SqlClient(T-SQL 转写成 SQLite)、数据库页面、DataGridView、DateTimePicker
CI/CD / test (push) Canceled after 0s
CI/CD / deploy (push) Canceled after 0s
- 每个学生一套数据库,长期保存(data/databases/<用户编号>/库名.db);学生程序运行时挂进沙箱可读写
- Sim.Data:SqlConnection / SqlCommand / SqlDataReader / SqlDataAdapter / SqlCommandBuilder / SqlParameter;
  连接字符串只按库名打开学生自己的库;ScriptDom 解析 T-SQL 后按白名单转写成 SQLite 语句,
  STRICT 表 + 元数据表还原 SQL Server 的列类型,报错编号和中文信息与 SQL Server 一致;
  INSERT 不写列名时跳过自增列,日期统一格式(书上 DateTime.ToString() 拼接的日期能正确比较)
- 常驻 SQL 服务(Sim.Runner sql-server):数据库页面的查询、对象资源管理器,评分前按实验 database.sql 建库
- 数据库页面(代替 SSMS):对象资源管理器、查询窗口、编辑前 200 行、表设计器、恢复实验初始数据
- DataGridView(绑定 DataView/DataTable/DataSet,单元格修改写回 DataTable)、DateTimePicker;设计器工具箱加入
- 评分:每个检查项一份新建的实验库;新增点 / 修改表格单元格、选日期、表格里有 / 没有某行的检查
- 示例:项目 6 任务 2、3;时间格式改成和中文 Windows 一致(9:05:03);异常堆栈不暴露服务器路径
- 测试:数据库端到端、接口(每人只看到自己的库、恢复实验数据)、评分出错情况、T-SQL 生成

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 09:18:56 +08:00
xuyueandClaude Opus 5.5 6b088240da 项目 4 任务 2 网络摄像机:PictureBox、Image / Bitmap、照片列表
CI/CD / test (push) Canceled after 0s
CI/CD / deploy (push) Canceled after 0s
- 摄像头:自绘东围墙场景(Camera/scene.svg),按云台位置切成 640×480 帧(build-frames.ts);
  Pan 每次转一格,红外对射被遮挡时画面出现翻墙的人;类名、委托、事件参数与教材 dll 一致,
  ImageRead 每 250 ms 在后台线程触发
- Image / Bitmap 保存真实图片数据:Save、FromFile、FromStream,文件夹不存在时报 GDI+ 一般性错误;
  图片每张只发给浏览器一次(按内容哈希缓存)
- 程序所在目录(AppDomain.CurrentDomain.BaseDirectory,编译检查单独放行)和当前目录指向可写的 bin/Debug,
  沙箱里在沙箱的临时目录
- PictureBox(SizeMode、BorderStyle);设计器工具箱加"图片框";运行区显示程序保存的图片,点开看大图;
  实训台摄像头图标显示开启状态
- 评分规则加图片框显示图片、摄像头开关与转向、保存图片三种检查;示例 p4-t2-网络摄像机
- 测试:摄像头端到端、图片读写与程序目录、AppDomain 编译检查、评分出错情况

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 20:58:09 +08:00
xuyueandClaude Opus 5.5 91b39603a2 项目 5 补齐:旧版线程 API(Suspend / Resume / Abort)与 ListBox
- 编译时把 Thread 的 Suspend / Resume / Abort、ThreadState、Sleep、new Thread 改写成平台的
  协作式实现:被挂起或终止的线程在 Sleep、后台改控件、调设备类库、弹提示框时停下或结束;
  ThreadStateException 等行为与 .NET Framework 一致;编辑器不再提示"已过时"
- ListBox:列表项、单选、SelectedIndexChanged 先于 Click、删除选中项后取消选中;
  ComboBox 与 ListBox 共用 ListControl 和列表项集合;设计器工具箱加"列表框"
- 评分规则的"包含"对列表框检查所有列表项
- 示例:项目 5 任务 2(烟雾,线程)、任务 3(推送灾情,二维数组、两个窗体、ListBox),
  参考答案修正书上直接 Abort 挂起线程、烟雾记成"发现火情"的问题
- 一直不换行的 Console 输出攒满 4096 字符先发出,避免占满内存
- 测试:旧版线程 API、ListBox 事件顺序、两个示例的端到端和评分测试

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 20:33:12 +08:00
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 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 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