- 她从不主动开口,点一下才冒气泡;比赛里不弹。台词 326 句(shared/mascot/lines.ts), 口吻照「小鲸鱼」角色卡,学校里舍掉英文、粗口,「用户」改叫「同学」 - 按情况换话:题目页分没写、没交、例子没对上/对上、答错、编译错误、运行出错、超时、 错很多次、做对、一次就对、终于对了、以前做过;首页、题目列表、提交、专题、自学、排名等各有一组 - 按钮真的去办:运行例子、我错在哪(切到结果里出错的那一段)、举手、输题号、随便来一道、 下一道、选题…… - 老师也看得到:有学生举手时任何页面先说这件事;首页、课堂任务、统计、题目页各有一组 - 页面用 useMascotGuide 告诉她现在的情况(shared/mascot/guide.ts),以后按学生行为调整也接在这一层 - 修:连点时像卡住了(快点时按压过渡来不及显示,改成每下播一遍压扁回弹); 一打开从左上角飞到右下角;去掉单击的摆动 设计稿与台词表:https://claude.ai/artifact/Qz2zPCfq2zCrqmxyms1UGx Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
15966ceb0d
commit
ef3c53c671
25 files changed
+860
-57
No files matched your search
@@ -92,6 +92,9 @@ function openPicker() {
|
||||
pickerInitial.value = inputIds().map((id) => ({ id, title: titles.get(id.toLowerCase()) }))
|
||||
picking.value = true
|
||||
}
|
||||
|
||||
// 看板娘气泡里的「选题」:课堂任务页没布置时替老师打开选题弹框
|
||||
defineExpose({ openPicker })
|
||||
function pickerConfirm(ids: string[]) {
|
||||
lessonInput.value = ids.join(' ')
|
||||
saveLesson()
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useLeaveStudents } from 'shared/composables/leaveStudents'
|
||||
import { useTeacherHelp } from 'shared/composables/teacherHelp'
|
||||
import { useCollabStore } from 'shared/store/collab'
|
||||
import { useConfigStore } from 'shared/store/config'
|
||||
import { useMascotGuide } from 'shared/mascot/guide'
|
||||
import { errorMessage } from 'utils/api'
|
||||
import { LANGUAGE_SHOW_VALUE } from 'utils/constants'
|
||||
import { parseTime } from 'utils/functions'
|
||||
@@ -511,6 +512,29 @@ function submissionsHref(
|
||||
}).href
|
||||
}
|
||||
|
||||
/**
|
||||
* 看板娘:布置了就带去这节课的提交,筛法同提交列表「这节课」(班、这几道题、今天)。
|
||||
* 语言和格子一致:画流程图的课看流程图,选了语言的只看它 —— 夹着 SQL 题的不筛语言,免得把 SQL 交的藏掉。
|
||||
* 还没布置时填题号的框就是这页最大的东西,不给按钮
|
||||
*/
|
||||
const startForm = useTemplateRef<{ openPicker: () => void }>('startForm')
|
||||
useMascotGuide(() => {
|
||||
const b = board.value
|
||||
if (!b?.className) return null
|
||||
if (needLesson.value)
|
||||
return { situation: 'teacher.task.unassigned', actions: startForm.value ? [{ label: '选题', run: () => startForm.value?.openPicker() }] : [] }
|
||||
const language = b.mode === 'flowchart' ? 'Flowchart' : b.problems.some((problem) => problem.isSql) ? null : b.language
|
||||
const query = {
|
||||
className: b.className,
|
||||
problem: b.problems.map((problem) => problem.problemDisplayId).join(','),
|
||||
today: '1',
|
||||
...(language ? { language } : {}),
|
||||
}
|
||||
// 新标签打开,和点格子一样:任务页一般开着不关
|
||||
const open = () => window.open(router.resolve({ name: 'submissions', query }).href, '_blank')
|
||||
return { situation: 'teacher.task.assigned', actions: [{ label: '这节课的提交', run: open }] }
|
||||
})
|
||||
|
||||
function lastText(student: TaskBoardStudent) {
|
||||
if (student.lastSubmitAt) return parseTime(student.lastSubmitAt, 'HH:mm')
|
||||
if (oftenIdle(student)) {
|
||||
@@ -578,7 +602,16 @@ function lastText(student: TaskBoardStudent) {
|
||||
<!-- 刚上课还没有题:填题号的框是这页最大的东西 -->
|
||||
<section v-if="needLesson" class="start">
|
||||
<div class="start-title">这节课做哪几道题?</div>
|
||||
<LessonForm v-if="className" :board="board" :class-name="className" :lesson-id="null" variant="start" class="start-row" @saved="lessonSaved" />
|
||||
<LessonForm
|
||||
v-if="className"
|
||||
ref="startForm"
|
||||
:board="board"
|
||||
:class-name="className"
|
||||
:lesson-id="null"
|
||||
variant="start"
|
||||
class="start-row"
|
||||
@saved="lessonSaved"
|
||||
/>
|
||||
<div v-if="staleLesson" class="earlier">
|
||||
<span>上一节 {{ board.assignedAt ? parseTime(board.assignedAt, 'HH:mm') : '' }} {{ board.assignedBy }} 布置</span>
|
||||
<span v-for="problem in board.problems" :key="problem.problemId" class="chip">{{ problem.problemDisplayId }}</span>
|
||||
|
||||
Reference in new issue
Block a user