试用前走查的修改:报错看得见、学生找得到作业、运行区和设计器的若干体验问题
CI/CD / test (push) Canceled after 0s
CI/CD / deploy (push) Canceled after 0s

- 运行区:编译错误、运行异常、控制台输出和保存的图片移到窗体下面,不再被实训台挤成 0 高;缩放和放大按钮移到桌面上方,不压窗体的关闭按钮;放大后也能停止程序;点停止后清掉窗体
- 运行异常:常见 .NET 异常配中文说明,显示出错的文件、行号和方法,点击跳到代码
- 运行中的下拉列表挂到页面最外层,能伸出窗体和分组框(小窗体也能选到 COM4、COM5)
- 学生登录后进"我的作业";任务面板从工具栏下面开始,不挡导航;记住上次做的实验,从数据库页面返回、恢复数据时默认用它
- 代码页和设计页左栏都占 3/5,文件标签放不下时换行;实验选择框加宽;关闭粘性滚动
- 设计器:双击生成的事件方法带缩进;双击工具箱放进选中控件所在的容器并错开位置;新控件比容器宽时按比例缩小;无边框窗体不画标题栏
- 中文界面:代码编辑器(查找替换等)、属性窗口的颜色选项
- SQL:DATEADD、DATEDIFF、DATEPART 的日期单位(day、hour)解析成 IdentifierLiteral 时报"不支持",补上
- 项目 8 的预置环境数据改成建库那天之前的 7 天;p6-t3 评分项改为"按日期查询环境数据"
- 没有 AI 建议时不显示"全部采纳 AI 建议"和相关说明;导出 CSV 只给纯数字的文字加制表符

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5.5 committed 2026-10-27 08:49:42 +08:00
1 parent da623fa648
commit f6024dc113
30 files changed
+537 -255

No files matched your search

+34 -9
View File
@@ -373,15 +373,24 @@ function onDrop(event: DragEvent) {
place(d, controlDef(type), x, y)
}
/** 双击工具箱:放在选中的容器(或窗体)左上角 */
/** 双击工具箱:放在选中的容器(选中的是普通控件时放进它所在的容器)左上角,已有控件在那里就往右下错开 */
function onToolDoubleClick(def: ControlDef) {
const d = parsed.value.doc
if (!d) return
// 直接放进选中的容器,不按坐标判断(左上角可能正好压在另一个分组框上)
const container = !def.component && selected.value && isContainerType(typeOf(d, selected.value) ?? '') ? selected.value : ''
const result = addControl(d, def, container, { x: 12, y: container ? 20 : 12 })
// 直接放进容器,不按坐标判断(左上角可能正好压在另一个分组框上)
let container = ''
if (!def.component && selected.value) {
container = isContainerType(typeOf(d, selected.value) ?? '') ? selected.value : (listControls(d).find((c) => c.name === selected.value)?.parent ?? '')
}
const location = { x: 12, y: container ? 20 : 12 }
const taken = childrenOf(d, container).map((child) => localRect(d, child))
while (taken.some((r) => r.x === location.x && r.y === location.y)) {
location.x += 12
location.y += 12
}
const result = addControl(d, def, container, location)
selected.value = result.name
commit(result.doc)
commit(fitInside(result.doc, result.name, container))
}
function place(d: DesignerDocument, def: ControlDef, x: number, y: number) {
@@ -389,7 +398,15 @@ function place(d: DesignerDocument, def: ControlDef, x: number, y: number) {
const origin = container ? absRect(d, container) : { x: 0, y: 0 }
const result = addControl(d, def, container, { x: x - origin.x, y: y - origin.y })
selected.value = result.name
commit(result.doc)
commit(def.component ? result.doc : fitInside(result.doc, result.name, container))
}
/** 新控件比容器宽(LED 显示屏默认 800 宽,新窗体只有 300):按比例缩小到右边留出边距,不用学生再去改大小 */
function fitInside(d: DesignerDocument, name: string, container: string): DesignerDocument {
const rect = localRect(d, name)
const room = (container ? localRect(d, container).width : clientSize.value.width) - rect.x - 12
if (rect.width <= room || room < 40) return d
return setProp(d, name, 'Size', { kind: 'size', width: room, height: Math.max(20, Math.round((rect.height * room) / rect.width)) })
}
// ---------- 属性窗口的回调 ----------
@@ -469,6 +486,7 @@ function onComponentDoubleClick(name: string) {
}
const formTitle = computed(() => String(tree.value?.props.Text ?? ''))
const borderless = computed(() => tree.value?.props.FormBorderStyle === 'None')
const formStyle = computed(() => ({
width: `${clientSize.value.width}px`,
height: `${clientSize.value.height}px`,
@@ -511,7 +529,9 @@ const noop = () => {}
<div class="actions">
<button :disabled="!canUndo" title="撤销(Ctrl+Z)" @click="emit('undo')">↶ 撤销</button>
<button :disabled="!canRedo" title="重做(Ctrl+Y)" @click="emit('redo')">↷ 重做</button>
<span class="tips">拖动工具箱里的控件到窗体上;双击控件生成事件处理方法;Delete 删除</span>
<span class="tips" title="拖动工具箱里的控件到窗体上;双击控件生成事件处理方法;Delete 删除"
>拖动工具箱里的控件到窗体上;双击控件生成事件处理方法;Delete 删除</span
>
<select
class="zoom"
title="窗体显示的大小(不影响窗体的实际大小)"
@@ -524,8 +544,9 @@ const noop = () => {}
</select>
<button class="view-code" title="设计器根据窗体上的控件自动生成的代码(Designer.cs)" @click="emit('openDesignerFile')">查看生成的代码</button>
</div>
<div class="window" :class="{ selected: selected === '' }" :style="zoom !== 1 ? { zoom } : undefined">
<div class="titlebar" @pointerdown="selected = ''">
<div class="window" :class="{ selected: selected === '', borderless }" :style="zoom !== 1 ? { zoom } : undefined">
<!-- 无边框窗体和 VS 设计器里一样不画标题栏,点窗体空白处选中窗体 -->
<div v-if="!borderless" class="titlebar" @pointerdown="selected = ''">
<span class="title">{{ displayText(formTitle) }}</span>
<span class="buttons">─ ☐ ✕</span>
</div>
@@ -707,6 +728,10 @@ const noop = () => {}
box-shadow: 0 2px 10px rgb(0 0 0 / 0.15);
}
.window.borderless {
border-color: transparent;
}
.window.selected {
outline: 1px dashed #2563eb;
outline-offset: 2px;