diff --git a/docs/microsoft-store-pwa.md b/docs/microsoft-store-pwa.md index 962c1a1..1c5e6f8 100644 --- a/docs/microsoft-store-pwa.md +++ b/docs/microsoft-store-pwa.md @@ -4,7 +4,7 @@ 1. 在 GitHub Actions 手动运行 `PWA Store Build`。 2. 确认 `production_url` 是最终公开 HTTPS 地址,例如 `https://cs.houlang.cloud/`。 -3. workflow 会执行 `pnpm run build:store`,生成并校验 `dist/manifest.webmanifest`、`dist/sw.js`、图标和 HTML PWA hint。 +3. workflow 会执行 `pnpm run build:store`,生成并校验 `dist/manifest.webmanifest`、`dist/sw.js`、图标、截图和 HTML PWA hint。 4. 下载 `classworks-pwa-dist` 和 `microsoft-store-handoff` artifacts,作为 PWABuilder 或 Partner Center 提交前的构建记录。 ## 提交到 Microsoft Store diff --git a/images/1.jpeg b/images/1.jpeg new file mode 100644 index 0000000..f6b8d1d Binary files /dev/null and b/images/1.jpeg differ diff --git a/images/2.jpeg b/images/2.jpeg new file mode 100644 index 0000000..4d13a96 Binary files /dev/null and b/images/2.jpeg differ diff --git a/public/images/1.jpeg b/public/images/1.jpeg new file mode 100644 index 0000000..f6b8d1d Binary files /dev/null and b/public/images/1.jpeg differ diff --git a/public/images/2.jpeg b/public/images/2.jpeg new file mode 100644 index 0000000..4d13a96 Binary files /dev/null and b/public/images/2.jpeg differ diff --git a/scripts/validate-pwa-build.js b/scripts/validate-pwa-build.js index c101989..415dca0 100644 --- a/scripts/validate-pwa-build.js +++ b/scripts/validate-pwa-build.js @@ -40,6 +40,10 @@ if (!manifest) { } } + if (manifest.id !== '7C24F2B3.ClassworksPWA') { + fail('manifest.id 必须是 7C24F2B3.ClassworksPWA。'); + } + if (!['standalone', 'fullscreen', 'minimal-ui'].includes(manifest.display)) { fail('manifest.display 应为 standalone、fullscreen 或 minimal-ui。'); } @@ -56,6 +60,36 @@ if (!manifest) { if (!Array.isArray(manifest.categories) || manifest.categories.length === 0) { fail('manifest 缺少 categories,Microsoft Store/PWABuilder 会降低质量评分。'); } + + const screenshots = Array.isArray(manifest.screenshots) ? manifest.screenshots : []; + if (screenshots.length === 0) { + fail('manifest 缺少 screenshots。'); + } + + for (const screenshot of screenshots) { + if (!screenshot.src || !screenshot.sizes || !screenshot.type) { + fail(`截图条目不完整: ${JSON.stringify(screenshot)}`); + } else if (!fileExistsFromManifest(screenshot.src)) { + fail(`截图文件不存在: ${screenshot.src}`); + } + } + + const fileHandlers = Array.isArray(manifest.file_handlers) ? manifest.file_handlers : []; + const fileExtensions = new Set( + fileHandlers.flatMap((handler) => Object.values(handler.accept || {}).flat()) + ); + if (!fileExtensions.has('.csb') || !fileExtensions.has('.csi')) { + fail('manifest.file_handlers 必须允许 .csb 和 .csi。'); + } + + const protocolHandlers = Array.isArray(manifest.protocol_handlers) ? manifest.protocol_handlers : []; + if (!protocolHandlers.some((handler) => handler.protocol === 'cs' && handler.url?.includes('%s'))) { + fail('manifest.protocol_handlers 必须声明 cs:// 协议处理。'); + } + + if (manifest.edge_side_panel) { + fail('manifest 不应声明 edge_side_panel。'); + } } if (!fs.existsSync(indexPath)) { diff --git a/vite.config.mjs b/vite.config.mjs index f59cd55..60c76b1 100644 --- a/vite.config.mjs +++ b/vite.config.mjs @@ -123,7 +123,7 @@ export default defineConfig({ importScripts: ['sw-cache-manager.js'] }, manifest: { - id: './', + id: '7C24F2B3.ClassworksPWA', name: 'Classworks作业板', short_name: 'Classworks', description: '适用于班级大屏的作业板小工具,支持记录、查看并同步作业。', @@ -132,18 +132,47 @@ export default defineConfig({ lang: 'zh-CN', dir: 'ltr', display: 'standalone', - display_override: ['window-controls-overlay', 'standalone', 'minimal-ui'], + display_override: ['window-controls-overlay', 'standalone', 'minimal-ui', 'fullscreen'], start_url: './', scope: './', orientation: 'any', categories: ['education', 'productivity', 'utilities'], prefer_related_applications: false, launch_handler: { - client_mode: ['navigate-existing', 'auto'], - }, - edge_side_panel: { - default_path: './', + client_mode: 'navigate-existing', }, + screenshots: [ + { + src: './images/1.jpeg', + sizes: '1901x1080', + type: 'image/jpeg', + form_factor: 'wide', + label: 'Classworks 作业板主界面', + }, + { + src: './images/2.jpeg', + sizes: '1901x1080', + type: 'image/jpeg', + form_factor: 'wide', + label: 'Classworks 设置与管理界面', + }, + ], + file_handlers: [ + { + action: './?file-handler=true', + accept: { + 'application/octet-stream': ['.csb', '.csi'], + 'application/x-classworks-backup': ['.csb'], + 'application/x-classworks-install': ['.csi'], + }, + }, + ], + protocol_handlers: [ + { + protocol: 'cs', + url: './?protocol=%s', + }, + ], icons: [ { src: './pwa/image/pwa-64x64.png',