feat: 实现隐私弹窗全链路功能,支持本地配置与远程patch融合

- 新增隐私管理器核心逻辑,支持URL路由规则匹配、远程patch签名校验与融合
- 实现启动期资源等待机制,确保弹窗在i18n、主题配置就绪后触发
- 新增启动进度条组件,展示启动阶段进度与状态
- 重构隐私弹窗组件生命周期,修复事件丢失问题并支持规则动态重评估
- 适配多端平台隐私检查逻辑,支持微信小程序、鸿蒙元服务与H5
- 支持uniacid租户隔离的持久化规则存储
This commit is contained in:
2026-07-11 18:28:36 +08:00
parent a2066285cd
commit a913961be5
8 changed files with 1471 additions and 148 deletions

View File

@@ -8,6 +8,7 @@ import configExternal from '../common/js/config-external.js'
import util from '../common/js/util.js'
import ThemeOverride from '../common/js/theme-override.js'
import { sanitizeFlatMap, mergeThemeBuckets } from '../common/js/merge-theme.js'
import PrivacyManager from '../common/js/privacy.js'
// themeColor 结果缓存(避免每次都全量遍历 theme 对象)
// key: JSON.stringify(theme) + tabBarHeight, value: CSS变量字符串
@@ -314,6 +315,40 @@ const store = new Vuex.Store({
this.commit('setGlobalStoreInfo', null);
}
this.commit('setInitStatus', true)
// 远程下发隐私弹窗 URL/路由规则 (可选)
// 字段约定:
// data.privacy_url_rules = { mode?: 'all'|'only'|'skip',
// patterns?: string[],
// merge?: 'replace'|'union'|'intersect',
// sign?: string (HMAC 签名, 与后端约定) }
// 与 App.vue 中声明的本地 base 融合:
// - 字段缺失 → 用本地 base
// - mode 远程有值 → 远程覆盖; 否则用本地
// - patterns 按 merge 字段决定 (默认 replace)
// 签名校验 (可选):
// - privacyConfig.signSecret 非空 → PrivacyManager.verifyRemotePatch 校验 patch.sign
// - 校验失败 → applyWithMerge 内部 fallback 到 base, 不应用 patch
// 融合完成后 emit 'privacy:rules-updated', 持久化到 storage (跨冷启动恢复)
try {
if (data && data.privacy_url_rules && typeof data.privacy_url_rules === 'object') {
// base 必须从 PrivacyManager.__getBaseRules() 读取
// App.vue 顶层 script 已通过 setBaseRules() 登记
// 若登记失败 (例如 HMR / 测试环境), 退化为 'all'+[] 但跳过本次应用
const baseRules = (PrivacyManager && typeof PrivacyManager.__getBaseRules === 'function')
? PrivacyManager.__getBaseRules()
: null
if (baseRules && (baseRules.mode || (baseRules.patterns && baseRules.patterns.length))) {
// applyWithMerge 内部已调 verifyRemotePatch, 不通过的 patch 静默退回 base
PrivacyManager.applyWithMerge(baseRules, data.privacy_url_rules)
} else {
console.warn('[privacy] base rules not registered, skip remote patch apply')
}
}
} catch (e) {
console.warn('[privacy] apply remote rules fail', e)
}
resolve(data);
}
}