/** * electron-builder 打包配置 * 用 JS 配置而不是 yml:mac 公证需要按「环境变量是否配齐」动态开关。 * * 签名策略(按需求做成条件化,未配置证书时出未签名包且构建不报错): * - Windows / mac 代码签名:配置了 CSC_LINK + CSC_KEY_PASSWORD(或 mac 钥匙串里有 * Developer ID 证书)时 electron-builder 自动签名;否则自动跳过,只输出告警 * - mac 公证:APPLE_ID + APPLE_APP_SPECIFIC_PASSWORD + APPLE_TEAM_ID 三者齐全才启用 * - 未签名 mac 包仍可内部分发:首次打开需右键「打开」,且自动更新会降级为提示手动下载 */ const canNotarize = Boolean( process.env.APPLE_ID && process.env.APPLE_APP_SPECIFIC_PASSWORD && process.env.APPLE_TEAM_ID, ); /** @type {import('electron-builder').Configuration} */ const config = { // appId 必须与主进程 setAppUserModelId 一致,否则 Windows 系统通知不显示 appId: 'com.xiaokang.xkadmin', productName: '萧康云医', // 安装包文件名用 ASCII,避免中文名在静态托管/下载链接上出编码问题 artifactName: 'xk-desktop-${version}-${os}-${arch}.${ext}', directories: { output: 'release', buildResources: 'resources', }, files: ['out/**'], extraResources: [ // web-antd 生产构建产物:放 resources/web(不进 asar),为后续渲染层热更新留路 { from: '../web-antd/dist', to: 'web' }, // 应用图标供运行时使用(托盘、Windows 窗口图标) { from: 'resources/icon.png', to: 'icon.png' }, ], asar: true, compression: 'normal', win: { // TODO(待确认):正式图标待提供,当前用 web-antd logo 预生成的 ico 占位 // 直接给 .ico 让 builder 跳过 png 转换(本机 builder 的 wasm 图标工具会报内存错误) icon: 'resources/icon.ico', target: [{ target: 'nsis', arch: ['x64'] }], }, nsis: { // 非一键安装:允许用户选择安装目录,符合企业内部软件分发习惯 oneClick: false, perMachine: false, allowToChangeInstallationDirectory: true, createDesktopShortcut: true, createStartMenuShortcut: true, shortcutName: '萧康云医', }, mac: { icon: 'resources/icon.png', category: 'public.app-category.medical', // dmg 给用户安装,zip 是 electron-updater 在 mac 自动更新的必需格式,缺一不可 target: [ { target: 'dmg', arch: ['x64', 'arm64'] }, { target: 'zip', arch: ['x64', 'arm64'] }, ], hardenedRuntime: true, gatekeeperAssess: false, entitlements: 'resources/entitlements.mac.plist', entitlementsInherit: 'resources/entitlements.mac.plist', // IM 音视频通话必需的隐私用途描述,缺失时 mac 上调用摄像头/麦克风直接崩溃 extendInfo: { NSCameraUsageDescription: '视频问诊需要使用摄像头', NSMicrophoneUsageDescription: '语音/视频通话需要使用麦克风', }, notarize: canNotarize, }, publish: { provider: 'generic', // TODO(待确认):更新包静态托管地址,需与主进程 config.ts 的 DOWNLOAD_PAGE_URL 保持一致 url: 'https://static.xiaokang88.com/xk-desktop/', }, }; module.exports = config;