Files
classhelper-island-refactor…/out/sections/15-assets.md
T
ClassIsland Prompt Kit 22c1784bab feat: ClassIsland / ClassHelper 灵动岛提示词套件
- 重构版主提示词(14 parts,面向 ClassHelper 灵动岛重构)
- ClassIsland 全量规格提示词(20 parts,含分卷与逐章版本)
- 投喂指南、分卷、逐节文件
- 调研记录、一致性基线、生成与质检脚本
2026-11-12 21:59:58 +08:00

27 KiB
Raw Blame History

15. 资源清单(图标 / 字体 / 音效 / 天气图标 / 教程 / 本地化)

本节要求实现者按清单准备并放置资源,不得缺项、不得自行替换为网络图片。所有路径均以 ClassIsland 仓库为参照;实现时统一放到 packages/desktop-client/src/renderer/assets/(渲染进程资源)与 packages/desktop-client/resources/(打包资源)两处,并通过构建脚本生成多尺寸产物(见 15.9)。

15.1 应用图标

15.1.1 主图标(多尺寸 PNG)

文件 尺寸 用途 证据
Assets/AppLogo.png 192×192 应用内窗口图标、关于页、欢迎页 Logo ClassIsland/Assets/AppLogo.png;App.axaml:29-31;WelcomePage.axaml:29-33
Assets/AppLogo@48w.png 48×48 小尺寸(任务栏/列表) 实测文件头
Assets/AppLogo@384w.png 384×384 中尺寸(设置页/关于页展示) 实测文件头
Assets/AppLogo@768w.png 768×768 大尺寸(高分屏) 实测文件头
Assets/AppLogo_Fade.png 192×193 淡入用的半透明 Logo(启动/遮罩) 实测文件头
Assets/AppLogo_Monochrome.png 2715×2003 单色 Logo(水印/背景纹样) 实测文件头
Assets/AppLogo_AppLogo.svg 矢量 可缩放图标源 文件名
Assets/AppLogo.ico 多尺寸 ICO:16/24/32/48/64/256×2 Windows 可执行文件图标 解析 ICO 头得 7 个条目
Assets/FreedesktopIcons/AppLogo@128w.png 128×128 Linux Freedesktop 图标 实测文件头
AppLogo@32w.png(ClassIsland.Desktop/Assets/) 32×32 Windows 任务栏/托盘小图标 实测文件头

15.1.2 macOS 图标集(ClassIsland.Desktop/Assets/AppLogo.xcassets/AppIcon.appiconset/)

必须提供:16×16(1x/2x)、32×32(1x/2x)、128×128(1x/2x)、256×256(1x/2x)、512×512(1x/2x)、以及无后缀的 192/384/768 三档。实测目录内共 16 个 PNG,命名遵循 AppLogo_<尺寸>_<倍率>.png 与 AppLogo@<宽>w.png 两种规则,实现时按 electron-builder 的 icon.icns 要求重新生成即可,但必须保留这两个命名族以免资源引用失效。

15.1.3 Windows 打包瓦片(ClassIsland.Packaging/Images/)

资源 尺寸(100%/200%/400%) 用途
Square44x44Logo 44 / 88 / 176 开始菜单小图标
Square44x44Logo.targetsize-16/24/48/256 16/24/48/256 任务栏/Alt-Tab 变体
Square150x150Logo 150 / 300 / 600 开始菜单中等图标
Wide310x150Logo 310×150 / 620×300 / 1240×600 宽幅磁贴
LargeTile 310 / 620 / 1240 大磁贴
SmallTile 71 / 142 / 284 小磁贴
StoreLogo 50 / 100 / 200 商店图标
SplashScreen 620×300 / 1240×600 / 2480×1200 系统级启动图(与自绘闪屏无关)
LockScreenLogo 48×48 锁屏

(以上均为实测文件头尺寸;ClassIsland/Images/ 下另有一份 .scale-200 版本,实现时只保留打包用的那份即可。)

15.1.4 其他图标

资源 尺寸 用途
Assets/Marketplace/Logo.png 512×512 插件/主题市场 Logo
Assets/Marketplace/Logo@256w/128w/64w.png 256/128/64 市场图标多尺寸
Assets/Marketplace/Logo.svg 矢量 市场矢量源
ClassIsland.ExamplePlugin/icon.png 510×510 示例插件图标(插件必须自带 510×510 图标)
ClassIsland.Launcher/Assets/AppLogo.ico 18 条目 ICO(16–256) 启动器图标

验收要求:所有图标必须本地打包、离线可用;PNG 必须由同一矢量源派生,不得出现「不同尺寸风格不一致」;ICO 必须内嵌 16/24/32/48/64/256 六档。

15.2 字体

15.2.1 正文/界面字体:HarmonyOS Sans SC

文件 字重 用途 证据
Assets/Fonts/HarmonyOS_Sans_SC_Light.ttf 300 轻量标题/水印 文件名
Assets/Fonts/HarmonyOS_Sans_SC_Regular.ttf 400 正文 文件名
Assets/Fonts/HarmonyOS_Sans_SC_Medium.ttf 500 默认字重(岛内主文字) Settings.cs:101
Assets/Fonts/HarmonyOS_Sans_SC_Bold.ttf 700 标题/强调 文件名
  • 字体族注册名:HarmonyOS Sans SC;全局资源键 AppFont,字体栈见 part 03 §3.2.1(Assets/Fonts/Fonts.axaml:3;Assets/Fonts/Fonts.xaml:3)。
  • 许可:Assets/Fonts/LICENSE.txt 为「HarmonyOS Sans Fonts License Agreement」,版权归华为;分发时必须原样保留该许可文件,且不得单独售卖字体。应用本体为 GPL-3.0(LICENSE.txt),字体许可与代码许可分离。
  • 实现要求:把 4 个 ttf 放进 Electron 打包资源,@font-face 声明 4 个 font-weight,font-display: swap;禁止声明 font-display: block(会白屏到字体加载完)。

15.2.2 图标字体(三套,必须全部内置)

字体 文件 大小 附带映射 用途 证据
Fluent System Icons ClassIsland.Core/Assets/Fonts/FluentSystemIcons-Resizable.ttf 1,472,748 B FluentSystemIcons-Resizable.json(262,830 B) 全局 UI 图标(Segoe Fluent 风格) AppBase.cs:142;ThemeBase.axaml:46
Lucide ClassIsland.Core/Assets/Fonts/lucide.ttf 715,192 B lucide.json(45,030 B) 天气图标(默认)、部分 UI 图标 AppBase.cs:147;ThemeBase.axaml:47
SF Symbols ClassIsland.Core/Assets/Fonts/SF-Symbols.ttf 174,616 B — 天气图标(Apple 风格) AppBase.cs:152
  • 字体族名分别为 FluentSystemIcons-Resizable、lucide、SF-Symbols;Avalonia 资源 URI 形如 avares://ClassIsland.Core/Assets/Fonts/#lucide,Web 实现改为 @font-face { font-family:'lucide'; src:url('lucide.ttf') } 并保留同名 font-family。
  • JSON 映射文件必须作为图标选择器数据源(Codepoint/名称表),不得只带 ttf 不带 json——图标选择器需要按名称搜索。
  • 许可:应用整体 GPL-3.0;Fluent System Icons 与 Lucide 通常为 MIT/ISC【推断:仓库内未放独立许可文件,按上游项目许可执行】;SF Symbols 字体来自 Apple 符号集,仅允许在 Apple 平台或已获授权场景使用,跨平台分发时须评估并在「关于/许可」页声明。

15.2.3 字体相关的硬性要求

  1. 字体必须在应用启动首帧前注册完成(document.fonts.ready 前不得渲染最终布局,可用 font-display: swap + 骨架屏规避跳动)。
  2. 不得使用系统缺失字体作为唯一来源;HarmonyOS Sans SC 必须随包分发。
  3. 用户自定义字体(MainWindowFont)只允许从系统已安装字体中选择(源码 AppearanceSettingsPage.axaml:409-446 枚举系统字体),实现时用 queryLocalFonts()(需权限)或主进程枚举字体列表,二者都不可用时至少提供内置 4 字重 + 3 图标字体。
  4. 字体文件不得被 CSP 阻止:font-src 'self' 必须放行本地资源。

15.3 音效

资源 大小 用途 默认设置 证据
Assets/Media/Notification/1.wav 130,012 B 提醒音效(唯一内置音效) IsNotificationSoundEnabled=true;NotificationSoundPath=""(表示使用内置音效);NotificationSoundVolume=1.0 实测文件;Settings.cs:144-145,1584-1593
自定义音效 用户文件 用户可指定本地音频路径 支持 wav/mp3 等系统可解码格式【推断】 Settings.cs:1496-1505
语音合成 系统/Edge TTS 提醒朗读 IsSpeechEnabled=true;SpeechVolume=1.0;SpeechSource=0;Edge TTS 默认音色 zh-CN-XiaoxiaoNeural Settings.cs:135-139,1406-1428,1452-1461

实现要求:

  • 音频必须用 HTMLAudioElement 或 Web Audio 播放,不得在主进程用系统播放器;播放前需用户手势解锁(Electron 可用 webPreferences.autoplayPolicy: 'no-user-gesture-required',但必须在配置中显式声明)。
  • 音量 = NotificationSoundVolume × 系统音量,范围 0–1;语音音量独立(SpeechVolume)。
  • 同一条提醒只播一次音效(源码用 MaskSession.HasSoundsPlayed 去重,MainWindowLine.cs:746-751);提醒队列切换时不得重复触发。
  • 语音提供方必须可插拔:系统语音(Windows SAPI)、Edge TTS、GPT-SoVITS 三选一(App.Services.xaml.cs:281-285 注册三个 provider),默认走系统语音或 Edge TTS,且必须支持「无网络时降级到系统语音」。
  • 内置音效 1.wav 必须打包进 resources/audio/,不得 CDN 引用。

15.4 天气图标(4 套模板)

15.4.1 模板注册表

模板 id 显示名 默认 实现方式 尺寸参数 证据
classisland.weatherIcons.lucide Lucide(默认) ✅ WeatherIconId="classisland.weatherIcons.lucide" Viewbox + LucideIcon 16×16,FontSize 16,Margin 1 App.Services.xaml.cs:287;Settings.cs:2106;LucideWeatherIconTemplate.axaml
classisland.weatherIcons.fluentDesign Fluent Design — Viewbox + FluentIcon 20×20,FontSize 24,Margin 0 1.2 0 -1.2 App.Services.xaml.cs:288;FluentDesignWeatherIconTemplate.axaml
classisland.weatherIcons.sfSymbols SF Symbols — Viewbox + SFSymbolsIcon 16×16 App.Services.xaml.cs:289;SFSymbolsWeatherIconTemplate.axaml
classisland.weatherIcons.simpleText 纯文本 — 文本 + 分隔符 ~ 文本随字号 App.Services.xaml.cs:290;SimpleTextWeatherIconTemplate.axaml

实现要求:模板必须可插拔(插件可注册新模板),模板注册信息至少包含 {id, name, renderer};切换模板立即生效且不需要重启(源码 WeatherService.LoadWeatherIconTemplate() 在设置变化时重新取模板,Services/WeatherService.cs:84-90)。

15.4.2 天气代码 → 名称 → 图标(必须完整映射,共 40 个代码)

数据源:小米天气状态表 Assets/XiaomiWeather/xiaomi_weather_status.json;图标映射:ClassIsland/Converters/WeatherConverters.cs。下表前端三列(Fluent/Lucide/SF)为源码私有区码位,后端实现时请原样保留码位,Web 端用 data-icon 名称 + 本地字体渲染。

code 天气名 Fluent 码位 Lucide 码位 SF 码位
0 晴 \uf465 \ue2b1 \uFE42
1 多云 \uf44f \ue216 \uFDC9
2 阴 \uf43d \ue217 \uFDF1
3 阵雨 \uf455 \ue2fb \uFDE9
4 雷阵雨 \uf46b \ue090 \uFDCD
5 雷阵雨并伴有冰雹 \uf46b \ue08f \uFDDD
6 雨夹雪 \uf459 \ue094 \uFDD4
7 小雨 \uf43f \ue08e \uFDED
8 中雨 \uf453 \ue092 \uFDE9
9 大雨 \uf453 \ue092 \uFDE5
10 暴雨 \uf453 \ue093 \uFDE4
11 大暴雨 \uf453 \ue093 \uFDE4
12 特大暴雨 \uf453 \ue093 \uFDE4
13 阵雪 \uf45d \ue376 \uFDD9
14 小雪 \uf45b \ue094 \uFDD9
15 中雪 \uf45b \ue094 \uFDD9
16 大雪 \uf45b \ue094 \uFDD9
17 暴雪 \uf45b \ue094 \uFDD9
18 雾 \uf443 \ue214 \uFDE1
19 冻雨 \uf461 \ue08f \uFDD5
20 沙尘暴 \uf441 \ue218 \uFDB1
21 小雨-中雨 \uf453 \ue092 \uFDED
22 中雨-大雨 \uf453 \ue092 \uFDE9
23 大雨-暴雨 \uf453 \ue093 \uFDE5
24 暴雨-大暴雨 \uf453 \ue093 \uFDE5
25 大暴雨-特大暴雨 \uf453 \ue093 \uFDE5
26 小雪-中雪 \uf45b \ue094 \uFDD9
27 中雪-大雪 \uf45b \ue094 \uFDD9
28 大雪-暴雪 \uf45b \ue094 \uFDD9
29 浮尘 \uf449 \ue0f4 \uFE2E
30 扬沙 \uf441 \ue0f4 \uFE2E
31 强沙尘暴 \uf441 \ue218 \uFE2E
32 飑 \uf463 \ue093 \uFDAD
33 龙卷风 \uf463 \ue218 \uFDA3
34 弱高吹雪 \uf45b \ue094 \uFDD9
35 轻雾 \uf443 \ue214 \uFDE1
53 霾 \uf449 \ue0f4 \uFDE1
301 雨 \uf453 \ue092 \uFDE9
302 雪 \uf45b \ue094 \uFDD9
99 及未知 未知 \uee31 \ue091 \uFD8C

实现硬要求:

  • 未知代码必须回落到「未知」图标,不得抛异常或显示空白。
  • 纯文本模板必须实现「今天~明天」的 ~ 分隔符逻辑(模板内 Separator 仅在 To 场景可见,SimpleTextWeatherIconTemplate.axaml),且文本颜色跟随 --ci-text-*。
  • 天气图标颜色:晴天/温度等常规图标用前景色;雨天图标可选用 --ci-weather-rain(亮 #0000FF / 暗 #00BFFF),见 part 03。

15.5 贴纸资源(HoYoStickers)

Assets/HoYoStickers/ 内共 22 个 PNG,按「角色_动作」命名,用于教程/提醒的图标表达式 sticker(名字)(App.axaml.cs:253 注册 IconExpressionHelper 的 sticker 处理器)。实现时必须支持 sticker(帕姆_嗨) 这种写法并渲染对应 PNG。

角色 尺寸 文件(动作)
光辉矢愿 162×162(6 个) 不可以看、回眸、小喇叭、想我了吗、瞄准、遨游
帕姆 510×510(5 个)/450×450(1 个) 不可以、哭哭、嗨(450)、注意、点赞、震惊
昔涟 510×510(4 个) 回眸、守护、收到、爱
白厄 510×510(6 个) 再见、我吗、战斗、掉线、没事

实现要求:贴纸必须按原始比例缩放(object-fit: contain),不得拉伸;建议在 UI 中统一缩放到 96×96 或 128×128,并保留 image-rendering: -webkit-optimize-contrast 以求清晰。图标表达式解析器必须支持 fluent(码位)、lucide(码位)、sfsymbols(码位)、bitmap(路径)、sticker(名字) 五种前缀(App.axaml.cs:250-260),未知前缀回落为文本。

15.6 教程资源

15.6.1 教程定义文件(JSON)

内置教程组:Assets/Tutorials/classisland.getStarted.json(另有 classisland.sp.json、classisland.test.json 仅作开发样例,不要在正式版启用)。数据结构(逐字段实现):

层级 字段 类型 说明
顶层 Id string 教程组 id,如 classisland.getStarted
顶层 Title / Description string 组标题/描述(中文)
顶层 Tutorials array 教程条目列表
教程 Id / Title / Description string 教程 id/标题/描述
教程 ActualBanner / Banner string Banner 资源 URI(avares://)
教程 Ordinary int 是否为普通教程(0/1)
教程 Paragraphs array 段落列表
段落 Id / Title / Description string 段落标识/标题/描述
段落 TopLevelClassName string 目标窗口类名(如 ClassIsland.MainWindow)
段落 IsBarrierEnabled bool 是否启用教程遮罩屏障
段落 InitializeActions array 进入段落时执行的行动
段落 Content array 每屏内容
内容 Title / Content string 标题/正文(中文)
内容 IconExpression string 图标表达式(如 sticker(帕姆_嗨))
内容 HeroImage string 大图 URI(可空)
内容 TargetSelector / PointToTarget / ModalTarget string/bool 指向的目标与是否模态
内容 RightButtonText / LeftButtonText string 按钮文案(可空)
内容 RightButtonActions / LeftButtonActions / InitializeActions array 行动列表,元素为 {Kind:int, StringParameter:string}
内容 WaitForNextCommand / UseLightDismiss bool 交互策略
内容 Tag / Script / Xmlns string/object 扩展位

(来源:Assets/Tutorials/classisland.getStarted.json:1-200+。行动 Kind 的具体枚举含义在源码 TutorialActionKind 中定义,实现时必须对照该枚举逐值映射,不得自行编号;本节不臆造枚举值。)

15.6.2 教程图片

组/条目 文件 大小
welcome banner.webp 42,664 B
welcome mainMenu.webp / openAppSettings.webp / openEditMode.webp / openProfileEditor.webp / openTutorial.webp 约 25–27 KB/张
componentsEditing banner.webp / ruleset.webp 28,292 / 48,738 B
profileEditing banner.webp / 时间表.webp / 科目.webp / 课表.webp / 课表与时间表关系.webp 25,900–109,912 B

另有默认图:Assets/DefaultTutorialBanner.webp(10,416 B)、Assets/DefaultTutorialGroupBanner.webp(46,540 B),用作无 Banner 时的兜底。

要求:图片统一用 WebP(保留 .webp 扩展名),懒加载;教程播放时按窗口宽度自适应,不得变形。

15.7 本地化

15.7.1 现状(必须如实实现,不得虚构更多语言)

ClassIsland v2 的本地化是局部的,只覆盖两个命名空间(Assets/Localization/):

命名空间 资源文件 语言
SettingsPage(设置页) Localization.SettingsPage.resx(默认/中文)、.zh-Hans.resx、.zh-Hant.resx、.en.resx 简体中文、繁体中文、英文
SettingsPage/General(常规设置子页) 同上 4 个 同上
TrayMenu(托盘菜单) 同上 4 个 同上
  • 默认语言为中文(resx 无文化后缀文件即默认),并强制 Thread.CurrentThread.CurrentUICulture = zh-CN(ClassIsland/App.axaml.cs:512-513)。
  • 其余界面文案硬编码中文,没有资源化。因此「支持多语言」不是现状能力。

15.7.2 实现要求(在 Web 栈中的等价方案)

  1. 必须建立 i18n 层(推荐 vue-i18n),语言键命名与 resx 的 Key 保持一致,便于数据迁移。
  2. 首期必须提供 zh-Hans(默认)、zh-Hant、en 三份文案;其余界面文案随实现逐步资源化,不得伪造「已支持 N 种语言」。
  3. 语言切换必须持久化到配置,并立即刷新界面(无需重启);日期/时间格式必须跟随语言(Intl.DateTimeFormat)。
  4. 本地化文件不得包含 HTML 标签;带占位符的文案必须使用命名参数({name}),禁止字符串拼接。
  5. 字体必须覆盖三语:英文用 HarmonyOS Sans SC 的拉丁字形即可;繁体中文若依赖系统字体兜底,必须在 fallback 栈中显式列出(PingFang TC、Microsoft JhengHei)。

15.8 其他资源与文档

资源 用途 要求 证据
Assets/Documents/ChangeLog.md 更新日志(关于页展示) 必须随版本更新,按版本倒序 文件名
Assets/Documents/Privacy_.md 隐私政策(关于页展示) 必须原样保留;含 Sentry/上报说明 文件名
LICENSE.txt(根、各项目、Assets) GPL-3.0 许可证 必须随安装包分发 LICENSE.txt
Assets/TrustedPublicKeys/ClassIsland.MetadataPublisher.asc 更新/市场元数据签名公钥 必须内置,用于校验更新包 文件名
Assets/ShortcutTemplates/ClassSwap.url、cn.classisland.app.desktop 换课/桌面快捷方式模板 Windows .url 与 Linux .desktop 两套 文件名
Assets/Highlighting/Lua.xshd 自动化脚本 Lua 语法高亮定义 编辑器必须使用该配色 文件名
Assets/default-subjects.json 默认科目表(23 个科目,含固定 GUID:语文/数学/英语/历史/政治/物理/化学/生物/地理/信息技术/体育/自习/通用技术/音乐/美术/选修课/社团/心理/早读/班会/周测 等) 必须原样内置,GUID 不得重新生成(迁移依赖) Assets/default-subjects.json
Assets/AsciiLogo.txt ASCII 艺术 Logo(控制台/崩溃页) 6 行,宽 63 字符 文件内容
Assets/Tellings.txt 关于页/加载页随机「一句话」(含彩蛋) 至少 20 条,需保留「关于页连续点击图标 10 次开调试」等提示 文件内容
Assets/dependencies.g.json NuGet 依赖许可清单(供「许可」页展示) Web 栈需生成 licenses.json 等价物(npm 依赖 + 字体许可) Models/NugetLicenseInfo.cs、Views/WelcomePages/LicensePage.axaml
Assets/XiaomiWeather/xiaomi_weather_status.json 天气代码→中文名映射(40 条) 与 15.4.2 表一致 文件内容
Assets/BannerMain_App2.png 2031×600 关于页/更新页主视觉 实测文件头
Assets/Demo_MainMenu.png、Demo_OpenProfileSettingsWindow.png 1608×878 教程/引导演示图 实测文件头
Assets/ClassIsland.ai 矢量源文件 设计源文件,可不打包 文件名
Assets/XamlThemePreviews/classisland.fluent.png、classisland.classic.png 1920×350 主题市场预览图(见 part 09) 实测文件头

15.9 ClassHelper 侧资源落点

资源类别 落点 生成/校验方式
应用图标 build/classhelper.png(源)+ 设计导出的 .ico 用 pnpm icons 派生其余尺寸(与 ClassHelper 现有约定一致:图标源是 build/classhelper.png 与设计导出的 .ico,pnpm icons 派生其余资源)
Web 品牌图 packages/web-admin/public/logo.png 或站点 /logo.png Web 用 /logo.png,客户端用 BRAND_LOGO_URL 常量(避免 file:// 绝对路径问题)
字体 packages/desktop-client/resources/fonts/ 4 个 HarmonyOS TTF + 3 个图标 TTF + 2 个 JSON 映射;构建时校验文件存在与哈希
音效 packages/desktop-client/resources/audio/1.wav 校验大小 130,012 B(或替换为等价资源但保持单文件、可循环)
贴纸 packages/desktop-client/resources/stickers/ 22 个 PNG,文件名保持中文原名(打包后可用 URL 编码访问)
教程 packages/desktop-client/resources/tutorials/ JSON + WebP;启动时校验 id 唯一
主题预览 packages/desktop-client/resources/theme-previews/ 1920×350 PNG 两张
许可清单 packages/desktop-client/resources/licenses.json 构建时从 package.json/node_modules 生成;必须包含字体与图标字体的许可条目

15.10 资源命名、加载与缓存规范

  1. 命名:图片用 kebab-case 或保持中文原名(贴纸、教程图必须保留原名,因为教程 JSON 以名字引用);字体文件名保持上游原名(HarmonyOS_Sans_SC_Medium.ttf),不得改成 medium.ttf 之类丢失来源信息的名字;音效用 1.wav 这类稳定短名,便于设置里持久化路径。
  2. 目录约定:renderer/assets/{icons,fonts,audio,stickers,tutorials,theme-previews}/,每类一个目录;禁止在组件目录里散落资源文件。
  3. 加载方式:
    • 图标字体、正文 TTF 在应用启动时通过 @font-face 预加载(crossorigin 同源),并用 document.fonts.load() 显式触发;
    • 贴纸/教程图/主题预览图走懒加载(loading="lazy" + IntersectionObserver),未加载时显示 Shimmer 骨架(part 14 D9);
    • 音效在首次提醒时按需加载并缓存 AudioBuffer,不得每次播放都重新 fetch。
  4. 缓存:所有资源 URL 必须带内容哈希(构建期生成 asset-manifest.json),Electron 生产环境用 file:// + 哈希避免陈旧缓存;开发环境禁用强缓存。
  5. 失败降级:图片加载失败必须显示「图裂了」占位(ClassIsland 的行为:SystemFillColorCriticalBackgroundBrush 底 + 提示「喔唷,图裂啦」,StylesBase.axaml:214-223),不得留白或抛错;字体加载失败必须回落系统字体并保持布局不跳变(用 font-display: swap + 固定行高)。
  6. 安全:禁止加载 http(s) 远程图片作为 UI 资源;所有资源必须走打包路径,CSP 中 img-src 'self' data:、font-src 'self'、media-src 'self'。
  7. 引用完整性:构建时扫描 CSS/TS/JSON 中的资源引用,所有引用必须命中 asset-manifest.json;反向扫描资源目录,未被引用的资源要么删除要么登记为「运行时动态加载」白名单。

15.11 资源版本与许可核对

  • 「关于」页必须提供「许可」入口,展示:应用许可(GPL-3.0)、字体许可(HarmonyOS Sans License)、图标字体许可(Fluent/Lucide/SF)、贴纸素材来源、第三方依赖(npm 依赖清单)。ClassIsland 用生成文件 dependencies.g.json + LicensePage.axaml 展示 NuGet 依赖,Web 实现必须生成等价的 licenses.json。
  • 每次发版必须核对:新增/替换的资源是否引入新的许可义务;贴纸、Banner、Demo 图是否为项目自有或有授权(HoYoStickers 为《崩坏:星穹铁道》同人素材,仅可作为内置彩蛋、不得用于商业宣传)。
  • 版本号变更时必须同步「关于」页的 AppVersionLong 展示(源码用编译期常量 AppBase.AppVersionLong,Web 端改为读 package.json.version)。

补充说明:ClassIsland 的「关于」页还会展示更新日志、隐私政策与致谢名单,这些内容都是随包分发的 Markdown 文档。实现时不得改为在线拉取——教室环境常常断网,关于页必须在离线时完整可读。更新日志与隐私政策的内容以 Assets/Documents/ 下的文件为准,发版时同步更新,不允许只改版本号不改日志。

15.12 验收标准

  1. 完整性:本节列出的资源 100% 存在于仓库;用脚本比对清单与文件,缺一项即失败(允许同一资源用等价格式替换,但必须在清单中登记变更)。
  2. 图标:electron-builder 打包后 Windows exe/installer、Linux AppImage、macOS icns 三端图标均正确;ICO 内嵌 6 档尺寸;任务栏/开始菜单/关于页三处图标一致。
  3. 字体:断网启动,界面仍显示 HarmonyOS Sans SC(非回退字体);图标字体全部可渲染(抽查 Fluent/Lucide/SF 各 3 个码位);document.fonts.check() 对 4 个正文字重与 3 个图标族返回 true。
  4. 字体许可:安装包内包含 fonts/LICENSE.txt(HarmonyOS 许可)与 licenses.json;「关于 → 许可」页可查看并可滚动到底。
  5. 音效:默认配置下提醒有声音;把音量调到 0 静音;自定义音效路径失效时回落内置 1.wav 且不崩溃;同一条提醒只响一次。
  6. 天气图标:4 套模板均可切换且立即生效;40 个天气代码逐个渲染正确(截图对比名称与图标);未知代码 99 显示「未知」图标。
  7. 贴纸:sticker(帕姆_嗨) 在教程中正确显示;22 张贴纸全部可加载(无 404);比例不变形。
  8. 教程:classisland.getStarted 三个教程组可完整播放到结束;跳过后再次进入从第一步开始;教程图片无拉伸、无破图。
  9. 本地化:切换 en/zh-Hans/zh-Hant 后设置页与托盘菜单文案切换且立即生效;日期格式随之变化;其余页面若无翻译必须回落中文而不是显示 key。
  10. 离线:在完全断网、无缓存的干净环境中启动,所有资源(字体/图标/音效/贴纸/教程图)均本地可用,控制台无对外请求(除用户主动触发的天气/更新功能)。
  11. 体积:字体 + 图标 + 音效 + 贴纸 + 教程图的总增量不超过 30MB 打包后体积;超过时必须说明取舍(例如贴纸按需下载,但 ClassIsland 的语义是离线可用,默认应全量内置)。