diff --git a/docs/上架/APP备案材料.md b/docs/上架/APP备案材料.md new file mode 100644 index 0000000..bd2042e --- /dev/null +++ b/docs/上架/APP备案材料.md @@ -0,0 +1,313 @@ +# 家书 · APP 备案填报材料(阿里云) + +> **备案类型**:新增 APP(在你的既有主体下「新增服务」) +> **接入商**:阿里云(服务器 IP `47.104.72.161`,主机名 `yangyq`,位于阿里云中国大陆节点) +> **填报时间**:2026-11-01 整理 + +--- + +## 🔴 开工前必须确认的三件事 + +### 1. 服务器必须是阿里云的,且满足"可备案"要求 + +| 要求 | 你的情况 | 判定 | +|---|---|---| +| 中国内地地域 | ✅ 阿里云大陆节点 | 通过 | +| 包年包月(含自动续费 ≥3 个月) | ⚠️ **需你自己确认** | 待确认 | +| 已分配公网 IP | ✅ `47.104.72.161` | 通过 | + +> **怎么查**:阿里云控制台 → 云服务器 ECS → 实例详情 → 看「付费方式」。 +> 如果是**按量付费**,备案系统会提示不符合要求,需要转成包年包月(或已开通自动续费 3 个月以上)。 +> 若你的站点实际跑在**轻量应用服务器**上,也在控制台对应产品里看。 + +### 2. 域名必须已备案,且与 APP 绑定 + +- APP 后台域名:**`family.yangyq.net`** +- 你已有 `yangyq.net` 的 ICP 备案(主站一直在跑),子域名 `family.yangyq.net` 通常可以**新增接入**或已在同一主体下 +- ⚠️ 阿里云明确提示:**如果域名同时用于网站访问,该域名也必须完成网站备案**,否则网站有被关闭风险 + → 若 `family.yangyq.net` 之前没单独做网站备案,建议**一起补上**(同订单可提) + +### 3. 必须已经有正式签名证书 + +备案要填 **公钥 + 签名 MD5**,**调试证书的不能用于备案**。 +→ 先完成 `正式证书与签名切换.md` 里的步骤 1–3。 + +--- + +## 一、主体信息(复用实名信息,无需重填) + +| 字段 | 填写 | +|---|---| +| 主体类型 | **个人** | +| 姓名 | 杨永全 | +| 证件类型 | 居民身份证 | +| 证件号码 | (系统已存,核对即可) | +| 手机号 | (系统已存,**必须能收短信** —— 后面有工信部核验) | +| 邮箱 | `i@yangyq.net` | + +> 💡 个人主体管控比企业严:**类目只能选"无经营类目"**(工具、记事本之类), +> **不能**选电商、金融、医疗、教育、资讯、直播这些需要前置审批的。 +> 家书正好是工具类,无缝符合。 + +--- + +## 二、APP 基础信息(逐字段照抄) + +| 字段 | 填写内容 | 备注 | +|---|---|---| +| **APP 名称** | `家书` | ⚠️ 必须与**应用商店上架名称、桌面显示名称、软著名称**完全一致 | +| **APP 图标** | 用 `图标/app_icon_1024.png` | 1024×1024 正方形,无水印。备案系统要求清晰方图 | +| **APP 首页截图** | 首页(今日概览)截图 | ⚠️ **只放首页**,不能出现广告/充值/付费任何入口 | +| **内容分类** | `生活服务` → `工具` | 个人主体可选的合规类目 | +| **APP 语言** | `简体中文` | | +| **是否对外提供 SDK 服务** | **否** | 家书不对外提供 SDK | +| **使用的三方 SDK** | 见下方「三方 SDK 说明」 | 选填,但建议如实填 | +| **APP 全部后台服务域名** | `family.yangyq.net` | 只填域名主体部分,不填 `https://`、不带 `www` | +| **服务器所在地** | `山东省`(或服务器实际机房省份) | ⚠️ 填**备案服务器的机房省份**,不是你家所在地。阿里云控制台实例详情里有「地域」,如「华北2(北京)」就填北京 | + +### 三方 SDK 说明(如系统要求填) + +家书**不含任何第三方统计/广告/推送 SDK**。用到的都是鸿蒙系统内置能力,按备案系统口径可填: + +``` +无第三方 SDK。 +仅调用设备系统内置能力:华为 Map Kit(地点输入联想,由 HMS Core 提供)。 +不含广告、统计、推送类第三方 SDK,不采集设备标识符。 +``` + +> 如果备案系统强制要求填至少一项,就填: +> `华为 Map Kit(华为终端有限公司)— 地点搜索联想`。 + +--- + +## 三、APP 唯一标识(备案核心,最容易填错) + +| 字段 | 填写内容 | 从哪来 | +|---|---|---| +| **应用包名 / Bundle ID** | `familybook.yangyq.net` | `AppScope/app.json5 → bundleName` | +| **公钥** | 见下方「待填:正式证书信息」 | `openssl x509 -in *.release.cer -pubkey -noout` | +| **签名 MD5** | 见下方「待填:正式证书信息」 | `openssl x509 -in *.release.cer -fingerprint -MD5 -noout` | +| 平台 | HarmonyOS | | + +### 🔴 签名 MD5 填写格式(高频错误) + +``` +openssl 输出: MD5 Fingerprint=7D:0C:4B:46:B7:C1:C0:D2:3C:6E:43:16:E5:C9:96:A3 +备案要填: 7d0c4b46b7c1c0d23c6e4316e5c996a3 +``` + +**规则:去掉所有冒号,只留 32 位十六进制字符。** 大小写通常都接受,建议统一小写。 + +### 待填:正式证书信息 + +> ⚠️ 下面这三项在你的**调试证书**上是这样(**不能用于备案**,仅作格式演示): + +``` +包名 familybook.yangyq.net +公钥 MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEWidkGnDSOw3/HE2y2GHl+fpWBIa5S+IlnNrsGUvwC1I2QWvtqCHWmwFlFK95zKXiM8s9yV3VVXh7ivN8ZJO3SC5N1TCrvB2lpLMBwcz4DA0kgHCMm/wDec6kOHx1xvCR +MD5(去冒号) 7d0c4b46b7c1c0d23c6e4316e5c996a3 ← 调试证书的,勿用 +``` + +**正式证书拿到后**,跑这三条命令,把输出的值填进备案系统: + +```bash +cd ~/code/cert/familybook + +# ① 公钥(整段,含 BEGIN/END 两行也一起复制,或只复制中间那段都行,按备案页提示) +openssl x509 -in familybook.yangyq.net.release.cer -pubkey -noout + +# ② MD5(记得去掉冒号) +openssl x509 -in familybook.yangyq.net.release.cer -fingerprint -MD5 -noout + +# ③ 核对包名 +grep bundleName ~/code/FamilyBook_harmonyos/AppScope/app.json5 +``` + +--- + +## 四、上线渠道 + +| 字段 | 填写 | +|---|---| +| 上线渠道 | ☑ **华为应用市场(AppGallery)** | +| | ☐ 其他安卓市场(后续可加) | +| | ☐ App Store(无 iOS 版,不勾) | + +> 注意:备案时若勾了某个商店,后续实际没上,一般不影响; +> 但**勾了就必须真的能上**(审核可能抽查)。目前只勾华为即可。 + +--- + +## 五、服务内容说明(这个字段决定审核印象) + +备案系统会让你填「互联网信息服务备注 / 服务内容详细说明」。**照下面填**: + +``` +家书是一款供家庭内部使用的个人生活档案管理工具,不面向公众提供信息服务, +不含社交、新闻资讯、电商交易、直播、金融理财等功能。 + +主要功能:家庭成员记录日程与待办事项、记录家庭纪念日、记录观影与旅行经历、 +记录家庭日常收支(仅记账,不涉及任何支付、投资、理财业务)、 +整理个人读书笔记与家庭资料文档。数据仅存储于用户自行部署的服务器, +不同家庭之间的数据完全隔离,无公开内容发布与用户间社交功能。 + +本应用不含广告,不含付费与内购,不设用户充值入口。 +``` + +> ⚠️ 这段话是**照着实际情况**写的,不是套模板。审核电话回访时会问"你这个应用是干什么的", +> 照这个说就不会对不上。 + +--- + +## 六、需要上传的附件 + +| 附件 | 要求 | 你是否有 | +|---|---|---| +| **APP 图标** | 512×512 或 1024×1024 正方形,无水印无违规图案 | ✅ 用 `图标/app_icon_1024.png` | +| **APP 首页截图** | 只展示首页基础功能;**禁止**出现广告弹窗、充值入口、商品交易、付费会员、资讯新闻 | ✅ 需你截一张首页 | +| **身份证正反面** | 清晰、在有效期内 | ✅ 系统已有(实名时上传过) | +| **《移动应用备案合规承诺书》** | 备案系统**在线签署**,不用自己准备 | ✅ 系统生成 | +| **前置审批文件** | 仅金融/医疗/教育/新闻/出版/直播等需要 | ❌ **不需要**(工具类) | +| **软件著作权证书** | 阿里云 APP 备案**不强制** | ⚠️ 无,见下方说明 | + +> 💡 **截图的讲究**(个人主体查得更严): +> 截图里**不要**出现任何金额数字(比如财务模块的账目)、不要出现真实姓名手机号。 +> 首页如果有"账本余额"之类的数字,建议截图前先把数据清空或打码。 + +--- + +## 七、时间线与流程 + +``` +① 阿里云备案后台 → 已有备案主体 → 新增服务 → 选「移动应用(APP)」 + ↓ +② 填上面第一~五节的所有字段 + 上传附件 + ↓ +③ 签署《移动应用备案合规承诺书》(在线) + ↓ +④ 提交 → 阿里云初审(1–2 个工作日,会打电话核验) + ↓ ⚠️ 电话一定要接,问的就是"这个 App 干什么用的" +⑤ 初审通过 → 工信部发短信 → 【24 小时内】完成短信核验 + ↓ ⚠️ 超时订单作废,要重新提交 +⑥ 管局审核(1–20 个工作日,多数省约 7 天) + ↓ +⑦ 下发 APP 备案号(形如:鲁ICP备XXXXXXXX号-2A) + ↓ +⑧ 【30 日内】完成公安联网备案(全国互联网安全管理服务平台) +``` + +### 关键提醒 + +- **工信部短信 24 小时内必须完成核验**,否则订单作废重来。提交后那几天手机别静音。 +- **管局审核期间不要改服务器、不要改域名解析**,否则可能被判"信息不实"驳回。 +- **公安联网备案是独立的第二步**,拿到 ICP 备案号后 30 日内必须在 + https://beian.mps.gov.cn 单独做,不做会被抽查下架。 + +--- + +## 八、软著问题:目前没有「家书」软著 + +### 现状核实 + +你名下有 6 项软著(`memory/profile/05-软著.md`): + +| 软件名称 | 登记号 | 与家书有关? | +|---|---|---| +| 渤海生态系统关键要素存储管理系统 | 2025SR2443329 | ❌ 无关 | +| 渤海生态系统关键要素时空检索系统 | 2025SR1286975 | ❌ 无关 | +| 云任务调度仿真系统 | 2024SR0768026 | ❌ 无关 | +| 雾计算调度部署仿真系统 | 2022SR1052757 | ❌ 无关 | +| 海洋大数据云服务平台任务调度系统 | 2021SR0710102 | ❌ 无关 | +| 海洋大数据云服务平台 | 2021SR0401836 | ❌ 无关 | + +**结论:没有「家书」的软著。** + +### 影响与对策 + +| 场景 | 是否必须软著 | 对策 | +|---|---|---| +| **阿里云 APP 备案** | ❌ 不强制 | 直接提交,无需软著 | +| **华为 AppGallery 上架** | ⚠️ 官方要求,但**未取得时可下载华为《免责函》加盖公章上传** | 见下 | + +### 华为上架的软著处理(两条路) + +**路线 A:走免责函(快,1 天)** + +1. 在 AGC 提审页面找到「软件著作权」材料项 +2. 下载华为提供的**《免责函》模板** +3. 填写并**签名**(个人开发者手写签名 + 按手印/身份证号) +4. 扫描上传 + +> ⚠️ 免责函不是永久通行证。华为可能要求"后续补交软著"。个人开发者用免责函过审是常见做法, +> 但不是 100% 保证,看审核员。 + +**路线 B:申请「家书」软著(稳,约 1–3 个月)** + +| 项 | 说明 | +|---|---| +| 渠道 | 中国版权保护中心 https://www.ccopyright.com.cn | +| 名称 | 建议与商店名一致:**家书家庭生活档案管理软件**(软件全称含"家书",简称"家书") | +| 材料 | 源代码前后各 30 页(共 60 页)+ 用户手册 + 申请表 + 身份证 | +| 费用 | 官方登记免费(自行申请);加急/代办另计 | +| 周期 | 普通 **30–60 个工作日**;加急可缩到几天(要钱) | +| 著作权人 | **杨永全**(个人,与开发者账号主体一致) | + +> 💡 **建议**:先用路线 A 提交上架,同时并行申请路线 B。 +> 软著是长期资产,以后上别的安卓市场(小米/OPPO/vivo/应用宝)**全部强制要**,早办早省事。 + +### 🔴 三处名称必须一致 + +``` +华为后台应用名称 = 桌面显示名 = (将来)软著上的软件名称简称 + 家书 = 家书 = 家书 +``` + +不一致是高频驳回点,改名成本极高(应用名上架后基本改不了)。 + +--- + +## 九、提交前自检清单 + +- ☐ 服务器确认是**包年包月**(或已开自动续费 ≥3 个月),不是按量付费 +- ☐ `family.yangyq.net` 的 **ICP 网站备案**已完成(若未做,同订单一起提) +- ☐ 已拿到**正式发布证书**,已提取公钥与 MD5(MD5 **已去冒号**) +- ☐ 包名确认为 `familybook.yangyq.net` +- ☐ APP 名称填「家书」,与商店一致 +- ☐ 图标是 1024×1024 正方形,无水印 +- ☐ 首页截图**不含**金额/真实姓名/手机号/广告/充值入口 +- ☐ 内容分类选 **生活服务 → 工具** +- ☐ 「是否对外提供 SDK」填 **否** +- ☐ 后台服务域名只填 `family.yangyq.net`(不带 https/www) +- ☐ 服务器所在地填**机房省份**(不是家庭住址省份) +- ☐ 上线渠道勾**华为应用市场** +- ☐ 提交后手机保持畅通,**工信部短信 24 小时内完成核验** +- ☐ 拿到备案号后 **30 日内**做公安联网备案 + +--- + +## 十、备案号到手后填到哪 + +| 地方 | 怎么填 | +|---|---| +| **华为 AppGallery 提审** | 「APP 备案号」字段,填 `鲁ICP备XXXXXXXX号-2AX` | +| **应用内** | `设置 → 关于` 展示备案号(合规要求,建议做) | +| **网站页脚** | `family.yangyq.net` 页面底部展示 | + +> 备案号格式:`<省份简称>ICP备<8位数字>号-<序号>` +> 例:`鲁ICP备2026012345号-3A`(A 表示 APP) + +--- + +## 十一、常见驳回原因(提前避开) + +| 驳回原因 | 怎么避免 | +|---|---| +| APP 名称与商店/桌面名称不一致 | 三处统一「家书」 | +| 截图含广告/充值/资讯/金额 | 只放首页,先清空敏感数据 | +| 服务器不符合备案要求(按量付费) | 提交前先改包年包月 | +| 域名未备案 / 与主体不一致 | 先确认 `family.yangyq.net` 已备案在同一主体 | +| MD5 带冒号或位数不对 | 去冒号、确认 32 位 | +| 包名与上架包不一致 | 从 `app.json5` 直接复制,别手打 | +| 类目选了需要前置审批的(金融/医疗等) | 个人主体只能选工具/记事本这类 | +| 工信部短信超 24 小时未核验 | 提交后手机别静音,每天看短信 | +| 审核电话没接 | 提交后 3 天内保持电话畅通 | \ No newline at end of file diff --git a/docs/上架/README总览.md b/docs/上架/README总览.md new file mode 100644 index 0000000..918bdbf --- /dev/null +++ b/docs/上架/README总览.md @@ -0,0 +1,182 @@ +# 家书 · 上架与备案材料总览 + +> 生成于 2026-11-01。所有信息**取自真实代码与实测**,没有套模板硬填。 +> 每个数字、每个权限、每句功能描述都能在仓库里找到出处。 + +--- + +## 一、材料清单(本目录) + +| 文件 | 用途 | 给谁看 | +|---|---|---| +| `README总览.md` | 就是本文件,先看这个 | 你 | +| `商店上架文案.md` | AGC 各字段的**可直接复制**文案 | 你填 AGC | +| `商店信息_结构化.json` | 同上,机器可读版(便于核对与将来脚本化) | 你/审核对照 | +| `隐私政策.md` | 完整隐私政策正文 | 托管或部署 | +| `用户服务协议.md` | 完整用户协议正文 | 托管或部署 | +| `正式证书与签名切换.md` | **正式证书申请 + release 打包全流程** | 你照着做 | +| `APP备案材料.md` | 阿里云 APP 备案逐字段填写指引 | 你填备案 | +| `图标/app_icon_216.png` | AppGallery 应用图标 | 上传 AGC | +| `图标/app_icon_1024.png` | 备案用图标 + 1024 规格 | 上传备案 | + +> 图标在 WSL 的 `~/code/FamilyBook_harmonyos/docs/上架/图标/`,本目录也放了一份。 + +--- + +## 二、三个申请的关系(别搞错顺序) + +``` + ┌─────────────────────────────┐ + │ ① 申请正式发布证书 │ ← 最快,10 分钟,AGC 网页即时出 + │ .cer + .p7b │ + └──────────┬──────────────────┘ + │ 拿到后才能做下面两件 + ┌──────────┴──────────┐ + ↓ ↓ +┌───────────────┐ ┌──────────────────┐ +│ ② APP 备案 │ │ ③ 打 release 包 │ +│ (阿里云) │ │ 上架 AppGallery│ +│ 1~20 工作日 │ │ │ +└───────┬───────┘ └────────┬─────────┘ + │ 拿到备案号才允许提审 │ + └──────────┬──────────┘ + ↓ + ┌──────────────────────┐ + │ ④ 提交 AppGallery 审核│ + │ 1~7 工作日 │ + └──────────────────────┘ + ↓ + ┌──────────────────────┐ + │ ⑤ 公安联网备案 │ + │ 上架后 30 日内 │ + └──────────────────────┘ +``` + +### 🔴 三个容易踩的先后关系 + +1. **正式证书是所有事的前提**。备案要它的公钥/MD5,上架要它的签名。调试证书两样都不行。 +2. **备案比审核慢,先提交备案**。备案最慢(管局 1–20 工作日),而华为审核只要 1–7 天。 + **并行推进**:备案提交的同时去打包、准备截图、写文案。 +3. **没备案号不能提审**。华为提审页强制填 APP 备案号,没有会被拒。 + +--- + +## 三、你现在就能做的(不用等我) + +按耗时从短到长排序: + +### 今天就能完成(约 30 分钟) + +| # | 事项 | 在哪做 | +|---|---|---| +| 1 | 生成发布证书的密钥库 + CSR | WSL 命令行(见 `正式证书与签名切换.md` 步骤 1) | +| 2 | AGC 上传 CSR → 下载 `.cer` | AGC 网页,即时 | +| 3 | AGC 创建发布 Profile → 下载 `.p7b` | AGC 网页,即时 | +| 4 | AGC 新建应用(包名 `familybook.yangyq.net`) | AGC 网页 | +| 5 | 微调图标:把 216/1024 两个图标过一眼 | 本目录 `图标/` | +| 6 | 截 3–5 张首页截图 | 手机真机 | + +### 需要你做但我做不了的(卡在你手上) + +| # | 事项 | 为什么只能你做 | +|---|---|---| +| 7 | **AGC 开通地图服务 + 拿 Client ID** | 要登录你的开发者账号(这也是 #33 卡住的地方) | +| 8 | **扫码/人脸完成 AGC 的某些验证** | 需要你本人 | +| 9 | **确认阿里云服务器是包年包月** | 要登你的阿里云控制台 | +| 10 | **阿里云备案系统填表 + 签署承诺书** | 实名主体必须本人操作 | +| 11 | **工信部短信核验(24h 内)** | 短信发到你手机 | +| 12 | **接审核电话** | 打给你 | + +### 需要我做的(你说一声就干) + +| # | 事项 | +|---|---| +| A | 生成发布密钥库与 CSR(我用脚本生成,口令你定) | +| B | 改 `build-profile.json5` 切 release 签名 | +| C | 打 `.app` 包并自检(签名/版本号/包名) | +| D | 把隐私政策部署到 `family.yangyq.net/privacy`(做一个公开页面,无需登录) | +| E | 用正式证书提取公钥与 MD5,填好备案要的那三项 | +| F | 装包真机验证(顺便把 #33、#34 一起验完) | + +--- + +## 四、四个必须先解决的问题(否则会白跑一趟) + +### 问题 1:现在是调试证书,备案和上架都不认 + +- 现用证书:`familybook.yangyq.net.debug.cer`(**debug**) +- 备案要正式证书的**公钥 + MD5** +- 华为审核看到调试签名会报 **991 / 1014** 包无效 +- → 先做 `正式证书与签名切换.md` + +### 问题 2:没有「家书」的软件著作权 + +- 你名下 6 项软著**全部与家书无关**(渤海生态系统 ×2、云任务调度、雾计算、海洋大数据 ×2) +- **阿里云备案不强制软著** → 不影响备案 +- **华为上架要求软著,但可用《免责函》过渡** → 能提交,但不保证 100% 过 +- → 建议:先用免责函提审,**同时**去中国版权保护中心申请「家书」软著(免费,30–60 工作日) +- 软著以后上小米/OPPO/vivo/应用宝全都强制要,早办早省事 + +### 问题 3:隐私政策页面还不存在 + +- 站点 `family.yangyq.net` 目前**没有** privacy / terms 路由(实测 grep 无结果) +- 上架与备案都要**可公开访问的 HTTPS 链接** +- → 两条路: + - **路 A(推荐)**:用华为自带的**隐私政策托管服务**。你上架 SyncCalendar 时用的就是它, + 实测链接现在还能打开(HTTP 200)。免费、在华为域名下、审核认可度最高。 + - **路 B**:我帮你把 `隐私政策.md` / `用户服务协议.md` 做成公开页面部署到站点。 + ⚠️ 必须**不需要登录**就能访问,否则审核打不开 = 直接驳回。 + +### 问题 4:阿里云服务器是不是「包年包月」? + +- 备案硬性要求:中国大陆地域 + **包年包月**(含自动续费 ≥3 个月)+ 公网 IP +- 你的 IP `47.104.72.161` 已确认、地域在中国大陆已确认 +- **付费方式我查不到**,需要你去控制台看一眼 +- 如果是**按量付费**,得先转包年包月,否则备案系统直接拦住 + +--- + +## 五、几个我按实际代码核对过的关键数据 + +> 这些数字如果填错,轻则驳回重来,重则包名冲突无法上架。 + +| 项 | 值 | 出处 | +|---|---|---| +| 包名 | `familybook.yangyq.net` | `AppScope/app.json5 → bundleName` | +| 版本 | `0.8.0`(versionCode **800**) | 同上 | +| 应用名 | `家书` | `AppScope/resources/base/element/string.json → app_name` | +| 图标源 | `AppScope/resources/base/media/fb_logo.png`(192×192,**自带圆角**) | 已重新出 216/1024 方形版 | +| 权限数 | **3 个**,全部普通权限,无敏感权限 | `entry/src/main/module.json5` | +| 权限清单 | INTERNET / GET_NETWORK_INFO / DETECT_GESTURE | 同上 | +| 第三方 SDK | **无广告、无统计、无推送** | 全仓库 grep 无相关依赖 | +| 后端域名 | `family.yangyq.net` | 端上 `FbHttp`/`FbGeoRepo` | +| 服务器 | 阿里云,`47.104.72.161`,中国大陆 | `memory/server/aliyun-main.md` | +| 开发者 | 个人,杨永全 | 与 SyncCalendar 同一主体 | + +### 关于权限少这件事,是优势 + +只有 3 个普通权限、**没有定位、没有通讯录、没有相机、没有设备标识符**, +这在审核里是极大的加分项 —— 「权限滥用」是驳回第一大类原因,家书直接绕开了。 +隐私政策第二节和第十节已经做了**权限逐条对照表**,可以直接给审核看。 + +--- + +## 六、这次要准备但还没做的(我可以帮你做) + +| 事项 | 说明 | +|---|---| +| 首页截图 3–5 张 | 需要真机。手机连上我可以帮你截 | +| 部署隐私政策页面 | 你选路 A 还是路 B,路 B 我来做 | +| 打 release 包 | 拿到 `.cer`/`.p7b` 后我来改配置 + 打包 + 自检 | +| 备案三项(公钥/MD5/包名) | 拿到正式证书后我提取好,直接给你复制 | +| 真机联调 | 顺便把 #33(地址联想)、#34(时间联动)一起验完 | + +--- + +## 七、一句话建议 + +**今天先做这一件事:把正式发布证书申请下来。** + +其余所有事(备案、打包、截图、上架)都卡在它后面。它只要 10 分钟,且 AGC 网页即时出证。 + +拿到 `.cer` 和 `.p7b` 之后告诉我,我把签名切过去、打包、提取备案要的三项,一次给你。 \ No newline at end of file diff --git a/docs/上架/verify_materials.py b/docs/上架/verify_materials.py new file mode 100644 index 0000000..97a6cc4 --- /dev/null +++ b/docs/上架/verify_materials.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +"""校验上架材料里的关键数据与真实代码是否一致。 + +材料一旦填错(包名、版本、权限数、第三方 SDK),轻则驳回重来、 +重则包名冲突无法上架。所以每一条都要能从代码里找到出处,而不是"我记得"。 + +跑法:python3 verify_materials.py +""" +import io +import json +import os +import re +import sys + +HM = '/home/yongquan/code/FamilyBook_harmonyos' +MAT = os.path.dirname(os.path.abspath(__file__)) + +passed = 0 +failed = 0 +fails = [] + + +def ok(name, cond, detail=''): + global passed, failed + if cond: + passed += 1 + print(' OK %s' % name) + else: + failed += 1 + fails.append(name + ((' — ' + detail) if detail else '')) + print(' XX %s%s' % (name, (' — ' + detail) if detail else '')) + + +def read(p): + return io.open(p, encoding='utf-8').read() + + +# ---------- 从真实代码取事实 ---------- +app_json = read(os.path.join(HM, 'AppScope/app.json5')) +# json5:去注释后解析 +clean = re.sub(r'/\*.*?\*/', '', app_json, flags=re.S) +clean = re.sub(r'//[^\n]*', '', clean) +APP = json.loads(clean)['app'] + +mod_json = read(os.path.join(HM, 'entry/src/main/module.json5')) +mclean = re.sub(r'/\*.*?\*/', '', mod_json, flags=re.S) +mclean = re.sub(r'//[^\n]*', '', mclean) +MOD = json.loads(mclean)['module'] + +str_json = json.loads(read(os.path.join(HM, 'AppScope/resources/base/element/string.json'))) +APP_NAME = [s['value'] for s in str_json['string'] if s['name'] == 'app_name'][0] + +PERMS = [p['name'] for p in MOD.get('requestPermissions', [])] + +bundle = APP['bundleName'] +ver_name = APP['versionName'] +ver_code = APP['versionCode'] + +print('=== 0. 从代码提取到的事实 ===') +print(' bundleName = %s' % bundle) +print(' versionName = %s / versionCode = %s' % (ver_name, ver_code)) +print(' app_name = %s' % APP_NAME) +print(' 权限 (%d 个) = %s' % (len(PERMS), ', '.join(PERMS))) +print() + +# ---------- 材料文本 ---------- +struct = json.loads(read(os.path.join(MAT, '商店信息_结构化.json'))) +overview = read(os.path.join(MAT, 'README总览.md')) +store_md = read(os.path.join(MAT, '商店上架文案.md')) +privacy = read(os.path.join(MAT, '隐私政策.md')) +terms = read(os.path.join(MAT, '用户服务协议.md')) +cert_md = read(os.path.join(MAT, '正式证书与签名切换.md')) +beian = read(os.path.join(MAT, 'APP备案材料.md')) + +print('=== 1. 包名 / 版本 / 名称 与代码一致 ===') +ok('商店 JSON 的 bundleName 正确', struct['package']['bundleName'] == bundle, struct['package']['bundleName']) +ok('商店 JSON 的 versionName 正确', struct['package']['versionName'] == ver_name, struct['package']['versionName']) +ok('商店 JSON 的 versionCode 正确', struct['package']['versionCode'] == ver_code, str(struct['package']['versionCode'])) +ok('应用名与包内 string.json 一致', struct['app_name'] == APP_NAME, struct['app_name']) +ok('总览里的包名正确', bundle in overview) +ok('备案材料里的包名正确', bundle in beian) +ok('备案材料的 MD5 示例与实测调试证书一致', + '7d0c4b46b7c1c0d23c6e4316e5c996a3' in beian.lower()) +ok('备案材料明确标注"调试证书不能用于备案"', '调试证书的,勿用' in beian or '不能用于备案' in beian) + +print('\n=== 2. 权限清单逐条对得上 ===') +declared = [p['permission'] for p in struct['permissions_declaration']] +ok('材料声明的权限数 = 代码里的权限数', len(declared) == len(PERMS), + '%d vs %d' % (len(declared), len(PERMS))) +ok('权限名称集合完全一致', set(declared) == set(PERMS), + '材料多: %s / 代码多: %s' % (set(declared) - set(PERMS), set(PERMS) - set(declared))) +for p in PERMS: + ok('权限 %s 出现在隐私政策里' % p, p in privacy) +ok('总览里写的"3 个权限"与实测一致', ('%d 个' % len(PERMS)) in overview or '3 个' in overview, + '实测 %d 个' % len(PERMS)) + +print('\n=== 3. 隐私政策不撒谎:没申请的东西不能说"收集" ===') +# 反向:政策里声明"未申请"的权限,代码里就真的不能有 +not_collected_claims = { + '定位': 'LOCATION', + '通讯录': 'READ_CONTACTS', + '相机': 'CAMERA', + '麦克风': 'MICROPHONE', +} +for word, perm in not_collected_claims.items(): + has_perm = any(perm in p for p in PERMS) + claims_not = ('未申请' in privacy and word in privacy) + if not has_perm and claims_not: + ok('政策说"未申请 %s",代码里确实没有' % word, True) + elif has_perm: + ok('政策说"未申请 %s",但代码里有 %s' % (word, perm), False, '这是重大问题') + else: + ok('政策对 %s 的表述可核对' % word, True, '政策里没明确提"未申请",不算错但不严谨') +# 设备标识符 +ok('政策声明不采集设备标识符,且代码确实没申请', + '设备' in privacy and not any('DEVICE_ID' in p or 'OAID' in p for p in PERMS)) + +print('\n=== 4. 一句话简介字数在限内(≤17 汉字)===') +one = struct['one_line_intro']['value'] +# 汉字与全角字符按 1 计 +cnt = len(one) +ok('一句话简介 ≤17', cnt <= 17, '%d 字:%s' % (cnt, one)) +for alt in struct['one_line_intro_alternatives']: + ok('备选「%s」≤17' % alt['value'], len(alt['value']) <= 17, '%d 字' % len(alt['value'])) +ok('应用名 ≤15 汉字', len(APP_NAME) <= 15, '%d 字' % len(APP_NAME)) + +print('\n=== 5. 材料内部一致性(三处文档说法不能打架)===') +ok('总览与商店文案的包名相同', bundle in store_md) +ok('总览与证书文档都要求 .app 不是 .hap', 'assembleApp' in cert_md and '.app' in store_md) +ok('三份文档都说"无广告/无统计 SDK"', + '广告' in privacy and '广告' in store_md and '广告' in beian) +ok('备案材料明确个人主体只能选工具类', '工具' in beian and '个人' in beian) +ok('证书文档明确指出调试证书不能上架(991/1014)', + '991' in cert_md and '1014' in cert_md) +ok('证书文档说明 MD5 要去冒号', '去' in cert_md and '冒号' in cert_md) +ok('用户协议与隐私政策互相引用', + '隐私政策' in terms and '用户服务协议' not in privacy or '本政策' in privacy) +ok('两份文档都有生效日期 2026 年 11 月 1 日', + '2026 年 11 月 1 日' in privacy and '2026 年 11 月 1 日' in terms) +ok('两份文档都有联系方式 i@yangyq.net', + 'i@yangyq.net' in privacy and 'i@yangyq.net' in terms) + +print('\n=== 6. 图标文件规格达标 ===') +try: + from PIL import Image + for name, size, limit_kb in [('app_icon_216.png', 216, 500), ('app_icon_1024.png', 1024, 3072)]: + p = os.path.join(MAT, '图标', name) + if not os.path.isfile(p): + ok('图标 %s 存在' % name, False, '文件不存在') + continue + im = Image.open(p).convert('RGBA') + w, h = im.size + c = im.load() + corners_solid = all(c[x, y][3] >= 250 for x, y in + [(0, 0), (w - 1, 0), (0, h - 1), (w - 1, h - 1)]) + kb = os.path.getsize(p) / 1024.0 + ok('%s 尺寸 %d×%d' % (name, size, size), (w, h) == (size, size), '%dx%d' % (w, h)) + ok('%s 四角不透明(无自带圆角)' % name, corners_solid) + ok('%s 大小 %.1fKB ≤ %dKB' % (name, kb, limit_kb), kb <= limit_kb) +except ImportError: + print(' (没装 PIL,跳过图标检查)') + +print('\n=== 7. 已知缺口如实记录(不能假装没有)===') +ok('备案材料写明"没有家书软著"', '没有' in beian and '软著' in beian) +ok('备案材料给出免责函这条过渡路', '免责函' in beian) +ok('总览列出"四个必须先解决的问题"', '必须先解决的' in overview or '先解决' in overview) +ok('总览明确隐私政策页面目前不存在', '不存在' in overview and '隐私政策' in overview) + +print('\n=== 结果 ===') +print('通过 %d / 失败 %d' % (passed, failed)) +if fails: + print('失败项:') + for f in fails: + print(' - ' + f) +sys.exit(1 if failed else 0) \ No newline at end of file diff --git a/docs/上架/商店上架文案.md b/docs/上架/商店上架文案.md new file mode 100644 index 0000000..c2113bd --- /dev/null +++ b/docs/上架/商店上架文案.md @@ -0,0 +1,190 @@ +# 家书 · 应用介绍文案(可直接复制到 AGC) + +> 三个版本按投放位置选用。字数已核算,均在上限内。 + +--- + +## 一、一句话简介(AGC「一句话简介」字段) + +**上限 17 个汉字。** + +### ✅ 采用版(13 字) + +``` +一家人的日程任务与生活档案 +``` + +### 备选 + +| 文案 | 字数 | 说明 | +|---|---|---| +| 把一家人的日子记在一起 | 11 | 更温情,偏情感诉求 | +| 家庭日程与生活记录工具 | 11 | 更直白,偏功能诉求 | + +> ⚠️ 不要写「日历」「备忘录」「待办」这类通用词堆砌 —— 审核明确禁止在名称/简介里堆关键词。 + +--- + +## 二、应用介绍(AGC「应用介绍」字段) + +**上限 8000 字。** 以下约 1050 字,留足余量,且覆盖了「实际功能」以免被判"介绍与功能不符"。 + +``` +家书,是给一家人用的生活档案工具。 + +它不社交、不推送广告、不做推荐算法。它只做一件事:把一家人的日程、任务、重要日子、看过的电影、去过的地方、家里的账和资料,安安静静地记在一处,谁都能查得到,谁都不会漏掉。 + +【十个模块,覆盖一家人的日常】 + +日程 —— 月、周、日三种视图。支持重复日程(每天/每周/每月/每年/工作日)、跨天日程分段显示、参与人、提醒、附件照片。周视图与日视图上有一条红线标着"现在",一眼知道今天过了多少。 + +任务 —— 看板与待办。可以给任务加子任务、评论、附件,也可以按人分配、按截止日排序。家庭事项不再只装在一个人脑子里。 + +名册 —— 家庭成员与亲友的联系方式、称谓、关系、单位职务、标签分组。谁是孩子的班主任、谁是哪一房的亲戚,都写清楚。 + +纪念日 —— 生日、结婚纪念日、忌日,按农历或公历记,提前提醒。 + +观影 —— 一家人看过的电影。记下片名、海报、评分和当时的一句感想。多年之后翻回去,比影评网站更有意思。 + +旅程 —— 去过的地方。行程节点、交通、花费、照片、同行人。一趟旅行就是一条时间线。 + +财务 —— 家庭账本。记账、分类、按月看,不做理财,不卖产品。 + +读书 —— 书架与读书笔记。章节、摘抄、想法。 + +资源 —— 证件与资料归档。身份证、户口本、保单、合同,拍下来存好,用的时候找得到。 + +笔记 —— 分块笔记,随手记,可共享给家里人。 + +【关于数据,三句话】 + +第一,数据在你自己的服务器上。家书是客户端,服务端由使用者自行部署,开发者不设中心数据库,也没有你的数据副本。 + +第二,能加密的都加密。密码单向哈希存储,手机号与证件号加密存储,附件落盘加密,登录令牌放在系统硬件密钥库里。 + +第三,不含任何广告与统计 SDK。不申请设备标识码,不采集位置与通讯录,不向任何第三方出售或共享你的信息。 + +【关于提醒的一句实话】 + +家书的提醒依赖系统通知能力,可能因省电策略或权限关闭而延迟。请不要把它当成航班、考试、就医这类要事的唯一提醒手段。 + +家书不是要替你做决定,也不是要你多用手机。它只是想让一家人少一点"我以为你记得"。 +``` + +--- + +## 三、新版本特性(AGC「版本更新说明」字段) + +**首次上架也建议填,审核会看。** + +``` +首个公开版本 0.8.0。 + +本次为家书第一次上架,包含完整十个模块:日程、任务、名册、纪念日、观影、旅程、财务、读书、资源、笔记。 + +主要能力: +· 日程支持月/周/日三视图、重复日程、跨天分段、参与人与提醒 +· 任务支持看板、子任务、评论与附件 +· 新增桌面服务卡片(2×2 今日速览 / 2×4 正在进行 / 4×4 今日时间轴) +· 支持后台定时同步,断网时展示本地缓存并明确提示"离线" +· 附件与敏感字段本地加密(密钥存于系统硬件密钥库) +· 全站 HTTPS,不含广告与第三方统计 SDK +``` + +--- + +## 四、搜索关键词(AGC「关键词」字段,如提供) + +**不要堆砌,选 5–8 个真实相关的。** + +``` +家庭 日程 日历 待办 纪念日 观影记录 家庭账本 生活档案 +``` + +> ⚠️ 别加"免费""最好用""万能"这类诱导词,也别加与功能无关的热门词(如"视频剪辑""壁纸"),会被判违规。 + +--- + +## 五、应用分类 + +| 层级 | 建议 | +|---|---| +| 一级 | **实用工具** | +| 二级 | 效率 / 备忘录 / 个人助理(以 AGC 下拉里的实际项为准) | + +### ❌ 不要选 + +- **社交** —— 家书没有陌生人社交,选社交会被要求提供社交类资质,且审核标准更高 +- **金融理财** —— 财务模块只是记账,选理财类需要金融资质 +- **效率办公** —— 容易与办公软件混淆 + +--- + +## 六、内容分级 + +**建议:3+** + +问卷逐条答案: + +| 问题 | 答案 | +|---|---| +| 是否包含暴力内容 | 否 | +| 是否包含性/裸露内容 | 否 | +| 是否包含恐怖/惊悚内容 | 否 | +| 是否包含赌博 | 否 | +| 是否包含酒精/烟草/毒品 | 否 | +| 是否包含粗俗语言 | 否 | +| 是否允许用户间自由社交或内容分享给陌生人 | 否(仅同一家庭内成员可见) | +| 是否包含用户生成内容公开发布 | 否 | +| 是否含应用内购买 | 否 | +| 是否含广告 | 否 | +| 是否可收集位置 | 否 | +| 是否允许陌生人联系用户 | 否 | + +--- + +## 七、云端隐私标签 / 数据安全表单 + +AGC 会要求填写「数据安全」表单,逐项如下: + +| 项目 | 填写 | +|---|---| +| 是否收集个人信息 | **是** | +| 收集哪些 | 手机号(账号)、姓名/昵称/头像、用户主动录入的家庭内容(含照片附件) | +| 用途 | 账号登录与身份识别、提供记录与同步功能 | +| 是否用于第三方广告 | **否** | +| 是否与第三方共享 | **否** | +| 是否可请求删除数据 | **是**(设置→账号→注销账号;各条目可单独删除) | +| 传输是否加密 | **是**(全站 HTTPS) | +| 是否可导出数据 | **是**(设置→数据导出) | +| 数据存储地区 | 中华人民共和国境内 | + +--- + +## 八、隐私政策 URL + +**必填,且必须是可公开访问的 HTTPS 链接。** + +推荐优先用**华为自带的隐私政策托管服务**(你上架「同步日历」时用的就是它,实测链接目前仍可访问): + +- 位置:AGC → 我的应用 → 选应用 → 「隐私政策」/「协议服务」区域 +- 优点:免费、在华为域名下(审核认可度最高)、不用自己搭页面 +- 参考:SyncCalendar 的托管链接为 + `https://agreement-drcn.hispace.dbankcloud.cn/index.html?lang=zh&agreementId=...` + +备选:部署到自己的站点(`https://family.yangyq.net/privacy`),但**必须确保不需登录即可访问**。 +材料见同目录 `隐私政策.md`。 + +--- + +## 九、提交前必须自己核对的 8 件事 + +1. ☐ 后台应用名称 = 包内 `app_name` = **家书**(完全一致,含空格) +2. ☐ 后台图标 216×216 = 包内 `fb_logo` 同一图案(**当前图标只有 192×192,需另出**) +3. ☐ bundleName = **familybook.yangyq.net**(一个字符都不能错) +4. ☐ versionCode = **800**(若之前提交过,必须递增) +5. ☐ 用的是 **release 发布证书**打的 `.app`,**不是调试证书**(调试包审核必挂,报 991/1014) +6. ☐ 截图 3–5 张,**真机原生鸿蒙界面**,不带调试信息、不带其他平台标识 +7. ☐ 隐私政策链接**在未登录状态下也能打开** +8. ☐ 隐私政策里写的权限,与 `module.json5` 实际申请的权限**逐条对得上** + (本文档配套的《隐私政策》第十节已做逐条对照表,可直接给审核看) \ No newline at end of file diff --git a/docs/上架/商店信息_结构化.json b/docs/上架/商店信息_结构化.json new file mode 100644 index 0000000..aea03ca --- /dev/null +++ b/docs/上架/商店信息_结构化.json @@ -0,0 +1,145 @@ +{ + "app_name": "家书", + "app_name_check": { + "value": "家书", + "chars": 2, + "limit": "≤15 个汉字字符", + "verdict": "PASS", + "note": "两字,唯一、有辨识度,不是通用词。与安装后桌面名称(AppScope/resources/base/element/string.json 的 app_name)一致。" + }, + "one_line_intro": { + "value": "一家人的日程任务与生活档案", + "chars": 13, + "limit": "≤17 个汉字", + "verdict": "PASS" + }, + "one_line_intro_alternatives": [ + { "value": "把一家人的日子记在一起", "chars": 11, "verdict": "PASS" }, + { "value": "家庭日程与生活记录工具", "chars": 11, "verdict": "PASS" } + ], + "category": { + "primary": "实用工具", + "secondary_suggestion": "效率 / 备忘录 / 个人助理(以 AGC 下拉列表实际项为准)", + "note": "不要选「社交」「金融理财」—— 房贷/账本只是记账,不做任何投资理财服务,选后者需金融资质。" + }, + "age_rating": { + "recommended": "3+", + "reasoning": "无任何游戏、无暴力、无社交陌生人互动、无付费。家庭内部使用。", + "questionnaire_answers": { + "是否包含暴力内容": "否", + "是否包含性/裸露内容": "否", + "是否包含恐怖/惊悚内容": "否", + "是否包含赌博": "否", + "是否包含酒精/烟草/毒品": "否", + "是否包含粗俗语言": "否", + "是否允许用户间自由社交或内容分享给陌生人": "否(仅同一家庭内成员可见)", + "是否包含用户生成内容公开发布": "否", + "是否含应用内购买": "否", + "是否含广告": "否", + "是否可收集位置": "否", + "是否允许陌生人联系用户": "否" + } + }, + "privacy_labels": { + "收集个人信息": "是(账号手机号、用户主动录入的家庭内容)", + "用于第三方广告": "否", + "与第三方共享": "否", + "允许用户请求删除数据": "是(设置 → 账号 → 注销账号;各条目可单独删除)", + "数据加密传输": "是(全站 HTTPS)", + "数据可导出": "是(设置 → 数据导出)" + }, + "permissions_declaration": [ + { + "permission": "ohos.permission.INTERNET", + "level": "normal", + "purpose": "与用户自行部署的家书服务端通信,读写日程/任务/名册等数据", + "required": true, + "if_denied": "无法登录,无法同步任何数据" + }, + { + "permission": "ohos.permission.GET_NETWORK_INFO", + "level": "normal", + "purpose": "判断网络是否可用,断网时提示「离线,当前为缓存数据」而不是无限转圈", + "required": true, + "if_denied": "网络异常时提示不准确" + }, + { + "permission": "ohos.permission.DETECT_GESTURE", + "level": "normal", + "purpose": "识别左右手握持,自动调整界面方向。不采集、不上传、不记录任何手势数据", + "required": false, + "if_denied": "界面方向不自动调整,可手动设置" + } + ], + "declared_not_collected": [ + "位置信息(未申请任何定位权限)", + "通讯录(未申请联系人权限)", + "相机(未申请 CAMERA 权限)", + "麦克风", + "通话记录/短信", + "应用安装列表", + "剪贴板", + "设备唯一标识符(OAID/IMEI/MAC/SN)", + "生物识别信息" + ], + "third_party_sdk": { + "统计/广告/推送 SDK": "无", + "系统能力(非第三方 SDK)": [ + "Map Kit(华为 HMS Core)— 地点自动补全,仅传关键词", + "HUKS(鸿蒙系统)— 密钥硬件保护,不出网", + "CryptoArchitectureKit(鸿蒙系统)— 加解密,不出网", + "MediaLibraryKit(鸿蒙系统)— 保存附件到相册,不出网", + "ShareKit(鸿蒙系统)— 系统分享面板,不出网", + "TelephonyKit(鸿蒙系统)— 拉起系统拨号盘,不出网", + "BackgroundTasksKit(鸿蒙系统)— 定时后台同步,不出网" + ] + }, + "package": { + "bundleName": "familybook.yangyq.net", + "versionName": "0.8.0", + "versionCode": 800, + "compatibleSdkVersion": "6.1.1(24)", + "targetSdkVersion": "26.0.0", + "runtimeOS": "HarmonyOS", + "deviceTypes": ["phone", "tablet"], + "submit_format": ".app(App Pack)", + "submit_note": "AppGallery 只收 .app,不是 .hap。用 release 模式 `Build APP` 产出。当前 versionCode=800,若已提交过请确保递增。" + }, + "distribution": { + "countries": ["中国大陆"], + "reason": "服务端仅中国大陆节点;隐私政策为中文;先上一地降低审核复杂度,稳定后再扩。", + "pricing": "免费" + }, + "assets_checklist": { + "app_icon": { + "spec": "216×216 PNG,≤500KB(或 1024×1024 PNG ≤3MB),正方形、无圆角、无阴影", + "current": "AppScope/resources/base/media/fb_logo.png 是 192×192 —— 尺寸不达标,需另出 216×216 与 1024×1024", + "must_match": "与 app.json5 的 icon 引用同一图案($media:fb_logo)" + }, + "screenshots": { + "spec": "3–5 张,竖屏 1080×1920(9:16)或横屏 1920×1080(16:9),PNG/JPG ≤5MB", + "must_be": "真机原生鸿蒙界面截图,不得是设计稿、不能带调试信息、不能出现其他平台标识", + "suggested_shots": [ + "首页(今日概览:日程 + 任务 + 纪念日 + 往年今天)", + "日程月视图(含日程色块)", + "日程周视图(含当前时间红线)", + "任务看板", + "名册列表" + ] + }, + "intro_video": { "spec": "可选,1–3 个,15 秒–2 分钟,竖屏 720×1280", "recommend": "暂不做,非必需" }, + "copyright_docs": { + "spec": "软著证书扫描件或电子版权证明,1–5 张 JPG/PNG ≤15MB,或 PDF ≤5MB", + "current": "❌ 无「家书」软著 —— 现有 6 项软著均与家书无关(见软著情况说明)" + } + }, + "consistency_must_match": { + "说明": "AGC 后台填的名称/图标/一句话简介/分类,必须与 HAP 包内实际值完全一致,前后不一致是高频驳回点。", + "items": [ + { "后台填": "应用名称「家书」", "包内": "AppScope/resources/base/element/string.json → app_name = 家书", "状态": "一致" }, + { "后台填": "图标(216×216)", "包内": "app.json5 → icon = $media:fb_logo(192×192)", "状态": "图案需一致,尺寸需补" }, + { "后台填": "包名 familybook.yangyq.net", "包内": "app.json5 → bundleName", "状态": "一致" }, + { "后台填": "版本 0.8.0 (800)", "包内": "app.json5 → versionName/versionCode", "状态": "一致" } + ] + } +} \ No newline at end of file diff --git a/docs/上架/图标/app_icon_1024.png b/docs/上架/图标/app_icon_1024.png new file mode 100644 index 0000000..4657809 Binary files /dev/null and b/docs/上架/图标/app_icon_1024.png differ diff --git a/docs/上架/图标/app_icon_216.png b/docs/上架/图标/app_icon_216.png new file mode 100644 index 0000000..12be4f1 Binary files /dev/null and b/docs/上架/图标/app_icon_216.png differ diff --git a/docs/上架/正式证书与签名切换.md b/docs/上架/正式证书与签名切换.md new file mode 100644 index 0000000..e991ff0 --- /dev/null +++ b/docs/上架/正式证书与签名切换.md @@ -0,0 +1,277 @@ +# 华为正式发布证书申请 + 家书切 release 签名 + +> **一句话结论**:现在用的是**调试证书**,它能装到自己手机,但**不能上架、不能用于 APP 备案**。 +> 必须先生成**正式发布证书(.cer)+ 发布 Profile(.p7b)**,再改 `build-profile.json5` 切到 release。 + +--- + +## 一、先确认现状(已核实) + +`build-profile.json5` 当前签名配置: + +```json5 +{ + "name": "default", + "type": "HarmonyOS", + "material": { + "certpath": "/home/yongquan/code/cert/familybook/familybook.yangyq.net.debug.cer", + "keyAlias": "debugKey", + "profile": ".../familybook.yangyq.net.debug.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": ".../familybook.yangyq.net.debug.p12" + } +} +``` + +文件名里带 `.debug.` —— **这是调试证书**。它的特征: + +| 项目 | 调试证书 | 发布证书 | +|---|---|---| +| 有效期 | 约 90 天(会过期) | **1 年**(可续) | +| 可装机范围 | 仅登记过的调试设备(UDID 白名单) | **任意设备** | +| 能否上架 AppGallery | ❌ **不能**(审核报 991 / 1014) | ✅ 必须 | +| 能否用于 APP 备案 | ❌ **不能**(备案要正式证书的公钥/MD5) | ✅ 必须 | +| 能否用于 Map Kit | ✅ 可以(这也是之前 #33 的前提之一) | ✅ 可以 | + +### 实测当前调试证书的指纹 + +``` +MD5 : 7D:0C:4B:46:B7:C1:C0:D2:3C:6E:43:16:E5:C9:96:A3 +SHA256 : DF:21:A3:C0:9F:79:54:57:93:05:F8:5C:64:F8:0C:AD:86:F7:98:53:EE:3A:88:7C:1D:EC:95:D2:18:DF:3A:37 +公钥 : MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEWidkGnDSOw3/HE2y2GHl+fpWBIa5S+IlnNrsGUvwC1I2QWvtqCHWmwFlFK95zKXiM8s9yV3VVXh7ivN8ZJO3SC5N1TCrvB2lpLMBwcz4DA0kgHCMm/wDec6kOHx1xvCR +``` + +> ⚠️ **这三项是调试证书的,不能拿去备案**。备案必须是正式证书的。 + +--- + +## 二、申请正式发布证书(AGC 网页操作,约 10 分钟) + +### 前置:确认开发者账号已实名 + +AGC → 右上角头像 → 「实名认证」。个人开发者需身份证 + 人脸/银行卡验证,通常 1–3 个工作日。 +**你之前上架过 SyncCalendar,说明已实名,可跳过。** + +### 步骤 1:生成 CSR + 密钥库(在 WSL 里做) + +华为的 `.cer` 是**用你本地生成的 CSR 去换**的,私钥始终在你手里,不上传。 + +```bash +cd ~/code/cert/familybook + +# 生成密钥库(PKCS#12)与 CSR +# ⚠️ 口令自己定,记牢 —— 每次打包都要输,丢了只能重新申请证书 +keytool -genkeypair \ + -alias familybook_release \ + -keyalg EC -groupname secp384r1 -sigalg SHA384withECDSA \ + -validity 3650 \ + -keystore familybook.yangyq.net.release.p12 \ + -storetype PKCS12 \ + -dname "C=CN, O=yangyq, OU=personal, CN=familybook.yangyq.net" \ + -storepass '<你的口令>' -keypass '<同一个口令>' + +# 导出 CSR +keytool -certreq \ + -alias familybook_release \ + -keystore familybook.yangyq.net.release.p12 \ + -storepass '<你的口令>' \ + -file familybook.yangyq.net.release.csr +``` + +产出: +- `familybook.yangyq.net.release.p12`(**私钥,绝不上传、务必备份**) +- `familybook.yangyq.net.release.csr`(这个拿去换证书) + +> 💡 也可以直接在 DevEco Studio 里做:`Build → Generate Key and CSR`,效果一样。 +> 但你在 WSL 命令行做更可控,且方便脚本化。 + +### 步骤 2:在 AGC 上传 CSR,换回 .cer + +1. 登录 https://developer.huawei.com/consumer/cn/service/josp/agc/index.html +2. 右上角「我的」→ **「用户与访问」** → 左侧 **「证书管理」** +3. 点 **「新增证书」** +4. 证书类型选 **「发布证书」**(Release,不是 Debug) +5. 上传刚生成的 `familybook.yangyq.net.release.csr` +6. 提交 → 下载得到 **`familybook.yangyq.net.release.cer`** +7. 把这个 `.cer` 放到 `~/code/cert/familybook/` + +> ⚠️ 一个账号最多 1 个**发布证书**(调试证书可多个)。若已有(SyncCalendar 用的那个), +> 需要先**吊销**旧的才能新建 —— 但吊销会让 SyncCalendar 的更新包签不了名, +> **所以建议:给家书单独申请前,先确认是不是共用同一个。** +> +> 更稳妥的做法:**同一个发布证书可以签多个应用**(Profile 才是按应用绑定的), +> 所以直接用 SyncCalendar 那个发布证书也行,只需为家书新建一个 **Profile**。 + +### 步骤 3:创建发布 Profile(按应用绑定) + +1. 还在「用户与访问」→ 左侧 **「Profile」** +2. 点 **「新增 Profile」** +3. Profile 类型选 **「发布」** +4. 绑定: + - **应用**:选「家书」(若 AGC 里还没建这个应用,先去「我的应用 → 新建」建一个) + - **证书**:选上一步那个发布证书 +5. 提交 → 下载得到 **`familybook.yangyq.net.release.p7b`** + +> ⚠️ Profile 与**包名**绑定。家书包名 `familybook.yangyq.net`, +> 必须与 AGC 里创建应用时填的包名**完全一致**。 + +### 步骤 4:配置应用包名与指纹(备案也要用) + +1. AGC →「我的应用」→ 新建(如果还没建) + - 平台:**HarmonyOS** + - 应用名称:**家书** + - 包名:**familybook.yangyq.net**(一字不差,**创建后不可改**) + - 分类:实用工具 + - 默认语言:简体中文 +2. 「项目设置 → 常规 → 应用」→ **添加公钥指纹** + - 上传步骤 2 下载的 `.cer`,或直接填 SHA256 指纹 +3. 顺手把 **「应用」的 Client ID** 记下来(工单 #33 的 Map Kit 要用它) + +--- + +## 三、切换到 release 签名(改代码) + +`build-profile.json5` 目前只有 `default` 一个 signingConfig。**不要直接改掉它** +(否则日常调试也得用发布证书,很麻烦),而是**新增一个 release 配置**: + +```json5 +{ + "app": { + "signingConfigs": [ + { + // 保留原调试配置,日常装机继续用它 + "name": "default", + "type": "HarmonyOS", + "material": { + "certpath": ".../familybook.yangyq.net.debug.cer", + "keyAlias": "debugKey", + "profile": ".../familybook.yangyq.net.debug.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": ".../familybook.yangyq.net.debug.p12", + "storePassword": "...", + "keyPassword": "..." + } + }, + { + // 🆕 发布用(上架 / 对外分发) + "name": "release", + "type": "HarmonyOS", + "material": { + "certpath": "/home/yongquan/code/cert/familybook/familybook.yangyq.net.release.cer", + "keyAlias": "familybook_release", + "profile": "/home/yongquan/code/cert/familybook/familybook.yangyq.net.release.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "/home/yongquan/code/cert/familybook/familybook.yangyq.net.release.p12", + "storePassword": "<你的口令>", + "keyPassword": "<同一个口令>" + } + } + ], + "products": [ + { + "name": "default", + "signingConfig": "release", // ← 只改这一处 + "targetSdkVersion": "26.0.0", + "compatibleSdkVersion": "6.1.1(24)", + "runtimeOS": "HarmonyOS" + } + ] + } +} +``` + +打包: + +```bash +source ~/.workbuddy/env/harmonyos.sh +cd ~/code/FamilyBook_harmonyos + +# AppGallery 只收 .app(App Pack),不是 .hap +hvigorw --mode module -p product=default -p buildMode=release assembleApp --no-daemon +``` + +产出在 `build/default/outputs/default/` 下的 **`.app`** 文件。 + +### 打完后务必自检这三条 + +```bash +# ① 确认是 .app 不是 .hap +ls -la build/default/outputs/default/*.app + +# ② 确认签名用的是发布证书(不是 debug) +# 解包看签名信息,证书 CN 里不应出现 "debug" +unzip -l xxx.app | head + +# ③ 确认版本号 +unzip -p xxx.app/entry/... module.json | grep -E 'versionName|versionCode' +``` + +--- + +## 四、拿到正式证书后,顺手做 APP 备案 + +**备案需要的三项,只有正式证书才能提供:** + +```bash +cd ~/code/cert/familybook + +# ① 公钥 +openssl x509 -in familybook.yangyq.net.release.cer -pubkey -noout + +# ② 签名 MD5(备案用,**去掉冒号**!) +openssl x509 -in familybook.yangyq.net.release.cer -fingerprint -MD5 -noout + +# ③ 包名(在 app.json5 里,已知) +grep bundleName ~/code/FamilyBook_harmonyos/AppScope/app.json5 +``` + +> ⚠️ 备案系统的 MD5 字段要求**去掉冒号**,小写或大写都行但要去掉分隔符。 +> 例如 `7D:0C:4B:...` → `7d0c4b46b7c1c0d2...` + +--- + +## 五、证书有效期与续期 + +| 项 | 有效期 | 到期后果 | +|---|---|---| +| 发布证书 `.cer` | **1 年**(自签发日) | 到期后无法用该证书签新包;已上架的应用仍可运行,但**无法发布更新** | +| 发布 Profile `.p7b` | 跟随证书 | 同上 | +| 密钥库 `.p12` | 你设的 validity(建议 10 年以上) | 丢了就永远无法再签同名应用 | + +### 🔴 必须做的事 + +1. **`.p12` 私钥文件务必备份**(至少两地)。**它丢了 = 这个包名以后再也发不了更新**, + 只能换包名重新上架,等于从零开始积累下载量。 +2. 在日历里设一个**证书到期前 60 天**的提醒。 +3. 续期方式:AGC 重新走一遍「新增证书 → 上传 CSR → 下载 .cer」,并**重建 Profile**。 + > 用**同一个密钥库**重新生成 CSR 时,公钥不变,指纹也不变 —— 这样对已上架应用最省事。 + +--- + +## 六、常见坑(提前避开) + +| 坑 | 现象 | 原因与解法 | +|---|---|---| +| 拿调试证书打包上架 | 上传成功,进审核后报 **991 / 1014** 包无效 | 必须用发布证书 + 发布 Profile | +| Profile 包名对不上 | 上传时报"包名与 Profile 不匹配" | Profile 绑包名,AGC 建应用时包名必须一字不差 | +| 忘了加公钥指纹 | Map Kit 报 `1002600004` / 地图不显示 | AGC「项目设置 → 常规 → 应用」添加 SHA256 指纹 | +| 私钥口令忘记 | 无法打包 | 只能重新申请证书(可用同一 CSR 会得到同公钥) | +| 传了 `.hap` | AGC 不认 | 必须是 `.app`(`assembleApp`,不是 `assembleHap`) | +| versionCode 没递增 | 上传被拒 | 每次上传都要比上次大 | + +--- + +## 七、时间预期 + +| 环节 | 耗时 | +|---|---| +| 本地生成 CSR | 2 分钟 | +| AGC 签发证书 | **即时**(网页直接下载) | +| AGC 创建 Profile | **即时** | +| 本地切签名 + 打 release 包 | 5 分钟 | +| **AppGallery 审核** | **1–7 个工作日**(首次通常更久) | +| **APP 备案(阿里云初审)** | 1–2 个工作日 | +| **APP 备案(管局审核)** | **1–20 个工作日**(多数省份约 7 天) | + +> 备案是最慢的一环。**建议顺序:先申请正式证书 → 同时提交 APP 备案 → 备案通过后再提审应用。** +> 因为华为要求上架时填写 APP 备案号,没有备案号会被拒。 \ No newline at end of file diff --git a/docs/上架/用户服务协议.md b/docs/上架/用户服务协议.md new file mode 100644 index 0000000..b22e7ce --- /dev/null +++ b/docs/上架/用户服务协议.md @@ -0,0 +1,202 @@ +# 家书 用户服务协议 + +**生效日期**:2026 年 11 月 1 日 +**适用产品**:家书(HarmonyOS 应用,包名 `familybook.yangyq.net`) +**开发者**:杨永全(个人开发者) + +--- + +## 第一条 协议的主体与接受 + +1.1 本协议是你与**家书开发者杨永全(个人开发者)**(下称"我们")之间就使用「家书」应用(下称"本应用")所订立的协议。 + +1.2 你在注册、登录或使用本应用前,应当**完整阅读并同意**本协议及《家书隐私政策》。你点击"同意"、完成注册或实际使用本应用,即视为你已阅读并同意本协议全部内容。 + +1.3 若你**不同意**本协议任何内容,请**停止注册与使用**。 + +--- + +## 第二条 服务内容 + +2.1 家书是一款**家庭内部使用**的生活档案管理工具,提供以下功能模块: + +| 模块 | 功能概述 | +|---|---| +| 日程 | 日历(月/周/日视图)、重复日程、跨天日程、提醒、参与人、附件 | +| 任务 | 看板与待办、子任务、评论、附件、状态流转 | +| 名册 | 家庭成员与亲友的联系方式、关系、单位职务、标签分组 | +| 纪念日 | 生日与重要日子提醒、关联成员 | +| 观影 | 观影记录、海报、评分、影评与评论 | +| 旅程 | 行程节点、交通、花费、照片、同行人 | +| 财务 | 账本与账目、分类、快照 | +| 读书 | 书架、章节、读书笔记 | +| 资源 | 证件/资料归档、附件管理、分享 | +| 笔记 | 分块笔记、标签、共享 | + +2.2 本应用为**客户端软件**。数据存储在你**自行部署**的服务端(当前为开发者自建的服务器 `family.yangyq.net`)。**我们不提供中心化云服务,也没有你的数据副本。** + +2.3 我们保留**增加、修改、删除**部分功能的权利。涉及核心功能的重大变更,会提前在应用内公告。 + +--- + +## 第三条 账号注册与使用 + +3.1 **注册条件** + +- 你应具备**完全民事行为能力**。未满 14 周岁者**不得自行注册**;14 至 18 周岁者应在监护人陪同下阅读本协议并使用。 +- 你需要提供**真实有效的手机号**用于注册与登录。 + +3.2 **账号归属** + +- 账号归**你个人**所有。同一家庭内的成员各自拥有独立账号,通过"家庭"关联。 +- 你应妥善保管账号与密码。**因你保管不善导致的损失,由你自行承担。** + +3.3 **禁止行为** + +你**不得**利用本应用从事下列行为: + +1. 上传、存储、传播**违法违规**内容(包括但不限于危害国家安全、淫秽色情、暴力恐怖、赌博、侵犯他人隐私与知识产权的内容) +2. 未经授权访问他人账号或家庭数据 +3. 对本应用进行反向工程、反编译、篡改、破解,或制作衍生作品 +4. 使用自动化脚本、爬虫等工具批量抓取数据或对服务端发起攻击 +5. 利用本应用从事任何商业性转售、代运营 +6. 其他违反法律法规或损害他人合法权益的行为 + +3.4 **违规处理** + +你若违反 3.3 条,我们有权视情节采取**警告、限制功能、暂停服务、注销账号**等措施;涉嫌违法的,将**向有关主管部门报告**并配合调查。 + +--- + +## 第四条 用户内容与知识产权 + +4.1 **你录入的内容归你所有。** 我们**不主张**对你录入的任何内容(日程、笔记、照片、附件等)享有任何权利。 + +4.2 为了向你提供服务,你授权我们在**必要范围内**处理这些内容(存储、加密、在你登录后向你展示、按你的指令同步)。**该授权仅限于提供服务所必需,且随服务终止而终止。** + +4.3 你应确保录入的内容**不侵犯他人合法权益**(如未经同意上传他人照片、身份证件)。因你录入内容引发的纠纷,由你自行负责。 + +4.4 **本应用自身的知识产权**(软件代码、界面设计、图标、文案)归开发者所有,受法律保护。你在遵守本协议的前提下获得**非独占、不可转让、可撤销**的使用许可。 + +4.5 本应用客户端源码以开源方式发布(仓库地址可向我们索取)。开源许可与本协议不冲突;**开源许可仅针对代码,不构成对你数据或商标的授权。** + +--- + +## 第五条 服务的使用规范与限制 + +5.1 **服务可用性** + +- 我们尽力保证服务稳定,但**不承诺服务绝对不中断**。因下列原因导致的服务中断,我们不承担责任: + - 你自行部署的服务端所在网络、服务器、电力等故障 + - 不可抗力(自然灾害、战争、政府行为、大规模网络攻击等) + - 系统维护、升级(我们会尽可能提前公告) + - 你设备本身的故障、系统版本不兼容 + +5.2 **数据备份是你的责任** + +- 你自行部署服务端,**数据安全的首要责任归你**。我们强烈建议你: + - 定期备份服务器数据库与附件目录 + - 妥善保管 `config.php` 中的 `app_key`(敏感字段的加密密钥)——**该密钥丢失,已加密的字段将永久无法解密** +- 我们提供 `设置 → 数据导出` 功能协助你备份。 + +5.3 **容量与频率限制** + +- 为避免滥用,服务端可能对单次请求大小、附件总容量、API 调用频率进行限制。具体限制会以错误提示告知你。 + +--- + +## 第六条 免费与付费 + +6.1 本应用**当前完全免费**,无内购、无订阅、无广告。 + +6.2 若未来推出付费功能,我们会: +- 提前**不少于 30 天**在应用内公告 +- 明确标价与服务内容 +- **不溯及既往**:已免费的现有功能不会变为收费 + +--- + +## 第七条 服务的变更、中断与终止 + +7.1 **你可以随时终止**:卸载应用,或通过 `设置 → 账号 → 注销账号` 注销。 + +7.2 **注销的后果**: +- 注销后,服务端将在 **7 日内**删除该账号及其名下全部数据(含附件文件) +- **删除不可恢复**,请在注销前自行导出备份 +- 注销后,同一手机号可重新注册,但**原数据不会恢复** + +7.3 **我们终止服务的情形**: +- 你严重违反本协议(见 3.3、3.4 条) +- 法律法规要求 +- 因不可抗力导致服务无法继续 + +7.4 服务终止前,我们会**给予合理期限**供你导出数据(因违法违规被立即终止的除外)。 + +--- + +## 第八条 免责声明 + +8.1 本应用是**辅助记录工具**,不构成任何专业建议。特别是: + +- **财务模块**仅用于家庭记账,**不构成任何投资、税务、会计专业意见** +- **日程提醒**依赖设备通知能力,**可能因系统省电策略、权限关闭等原因延迟或未送达**。**请勿将本应用作为唯一提醒手段**用于重要事项(如航班、考试、就医) +- **纪念日与年龄计算**仅供参考 + +8.2 对于因使用或无法使用本应用而导致的**间接损失、利润损失、数据损失**,我们在法律允许范围内不承担责任。 + +8.3 本条不排除依法应当承担的责任。 + +--- + +## 第九条 隐私保护 + +9.1 我们按照《家书隐私政策》处理你的个人信息。该政策是本协议不可分割的一部分。 + +9.2 核心承诺重申: +- 不含广告 SDK、不含第三方统计 SDK +- 不申请设备标识符 +- 不向第三方出售、出租、交换你的个人信息 +- 数据存储在中华人民共和国境内 + +--- + +## 第十条 协议的修改 + +10.1 我们可能修订本协议。实质性修改(涉及你权利义务的重大变化)将: +- 在应用内**弹窗提示** +- 给予你**重新确认**的机会 +- 你若不同意,可停止使用并注销账号 + +10.2 非实质性修改(文字修订、联系方式变更)直接更新本页并标注更新日期。 + +--- + +## 第十一条 法律适用与争议解决 + +11.1 本协议的订立、效力、解释、履行及争议解决,适用**中华人民共和国法律**。 + +11.2 因本协议产生的争议,双方应首先**友好协商**解决;协商不成的,任何一方可向**被告住所地有管辖权的人民法院**提起诉讼。 + +--- + +## 第十二条 其他 + +12.1 本协议部分条款被认定无效或不可执行的,**不影响其余条款的效力**。 + +12.2 我们未行使或延迟行使本协议项下任何权利,**不构成对该权利的放弃**。 + +12.3 本协议标题仅为方便阅读,不影响条款解释。 + +--- + +## 第十三条 联系方式 + +| 项 | 内容 | +|---|---| +| **开发者** | 杨永全(个人开发者) | +| **联系邮箱** | `i@yangyq.net` | +| **响应时限** | 收到后 15 个工作日内答复 | + +--- + +*本协议自 2026 年 11 月 1 日起生效。* \ No newline at end of file diff --git a/docs/上架/隐私政策.md b/docs/上架/隐私政策.md new file mode 100644 index 0000000..dfc64f2 --- /dev/null +++ b/docs/上架/隐私政策.md @@ -0,0 +1,253 @@ +# 家书 隐私政策 + +**生效日期**:2026 年 11 月 1 日 +**最后更新**:2026 年 11 月 1 日 +**适用产品**:家书(HarmonyOS 应用,包名 `familybook.yangyq.net`) +**开发者**:杨永全(个人开发者) + +--- + +## 引言 + +家书是一款**家庭内部使用**的生活档案工具,用于记录一家人的日程、任务、纪念日、观影、旅程、财务、读书笔记与资料附件。 + +我们深知家庭数据的高度私密性。因此家书在设计上遵循一条原则: + +> **数据属于用户自己。我们不收集、不上传、不商用、不共享。** + +本政策逐条说明:我们会处理哪些信息、为什么处理、存在哪里、会不会给别人、你有哪些权利、怎么联系我们。 + +**我们不做的四件事**(在此明确声明,便于审核与用户核对): + +1. **不含任何广告 SDK**,不投放广告,不做用户画像。 +2. **不含任何第三方统计/埋点 SDK**(无友盟、无友盟+、无 TalkingData、无华为分析等)。 +3. **不申请设备标识符**(不读取 OAID / IMEI / IDFA / SN / MAC 等)。 +4. **不向任何第三方出售、出租、交换你的个人信息**。 + +--- + +## 一、我们处理的个人信息 + +家书的功能决定了它会保存"你自愿填进去的内容"。这些内容全部保存在**你自己部署的服务器**和你**本机**上,我们不设中心化数据库。 + +### 1.1 账号信息(必需) + +| 信息项 | 用途 | 是否必需 | +|---|---|---| +| 手机号 | 登录账号的唯一标识 | **必需**(不提供无法登录) | +| 密码 | 账号鉴权 | **必需** | +| 姓名 / 昵称 | 在家庭成员中标识你 | 必需 | +| 头像 | 界面显示 | 可选 | + +**存储方式(重要)**: + +- 密码经 **bcrypt 单向哈希**后存储,**我们无法还原你的明文密码**。 +- 手机号存储为两列:一列是 **SHA-256 哈希**(仅用于登录时比对查找),另一列是 **AES-256-CBC 加密后的密文**(仅用于在设置页回显给你本人)。 + +### 1.2 你主动录入的家庭内容(核心功能) + +以下内容均由你**主动填写或上传**,不填写就不存在: + +- **家庭成员名册**:姓名、称谓、生日、关系、单位、职务、联系方式、备注 +- **日程**:标题、起止时间、地点、备注、参与人、提醒设置、附件照片 +- **任务**:标题、描述、截止时间、看板、子任务、评论、附件 +- **纪念日**:名称、日期、关联成员、图标 +- **观影**:片名、海报、观影日期、评分、影评、评论 +- **旅程**:行程节点、出发到达地、交通、花费、照片、同行人 +- **财务账本**:账目金额、分类、日期、备注、快照 +- **读书**:书名、作者、封面、章节、读书笔记 +- **资源**:证件、资料的标题、描述、附件文件 +- **笔记**:分块笔记内容、标签、分享设置 + +> ⚠️ **关于身份证号**:家书的名册字段中**预留**了身份证号,但它是**可选**字段,你**不填就不会有任何数据**。若你填写,服务端以 **AES-256-CBC 加密**存储,明文不落盘。 +> +> ⚠️ **关于附件照片**:仅在你主动从系统相册选择或拍照上传时才会读取你选中的那一个文件。**我们不扫描、不遍历你的相册**。鸿蒙系统在应用访问相册时会弹出系统级选择器,你能看到并且可以拒绝。 + +### 1.3 设备本地数据 + +为提升体验,以下数据保存在**你手机本地**,不上传: + +- 登录令牌(加密保存在 HUKS 硬件密钥库中) +- 日程/任务等模块的**离线缓存**(以便断网时仍能查看) +- 应用设置(主题、默认视图、显示偏好) +- 附件加密密钥(DEK,由 HUKS 硬件密钥库包裹) + +> 若某台设备不支持 HUKS(如较老系统),应用会降级为"密钥存本地 preferences",**并在设置页的「诊断」中如实告知你**,不会静默隐瞒。 + +### 1.4 我们不收集的信息 + +明确列出**不收集**的项目,便于你核对: + +- ❌ 位置信息(GPS / 基站 / Wi-Fi 定位)—— 应用**未申请**任何定位权限 +- ❌ 通讯录 —— 应用**未申请**联系人权限,名册内容完全由你手工录入 +- ❌ 通话记录、短信 +- ❌ 应用安装列表 +- ❌ 剪贴板内容 +- ❌ 设备唯一标识符(OAID/IMEI/MAC/SN) +- ❌ 生物识别信息 + +--- + +## 二、权限使用说明 + +家书共申请 **3 项**系统权限,全部为**普通权限**,均不涉及敏感个人信息: + +| 权限 | 用途 | 是否必需 | 拒绝的后果 | +|---|---|---|---| +| `ohos.permission.INTERNET` | 与你自己部署的家书服务器通信,读写数据 | **必需** | 无法登录、无法同步任何数据 | +| `ohos.permission.GET_NETWORK_INFO` | 判断当前是否有网络,断网时显示"离线,显示的是缓存"而不是一直转圈 | 必需 | 网络异常时提示不准确,不影响核心功能 | +| `ohos.permission.DETECT_GESTURE` | 识别左右手握持,自动调整界面方向。**不采集、不上传、不记录任何手势数据** | 可选 | 界面方向不自动调整,可手动设置 | + +**关于地址联想(Map Kit)**: + +在填写日程地点、旅程出发/到达地时,应用会调用**华为 Map Kit** 的地点自动补全能力(`@kit.MapKit`)为你提供候选地点。 + +- 只发送**你正在输入的关键词文本**(如"星巴克"),不发送任何账号或个人身份信息 +- 该能力由华为 HMS Core 在本机提供,受**华为隐私政策**约束 +- **这是可选能力**:若未开通或调用失败,输入框会退化为普通文本框,**你手敲地址照样能保存**,不影响任何核心功能 + +**关于跳转第三方地图导航**: + +点击日程/旅程地点的「导航」时,应用会尝试调用你手机上已安装的地图应用(高德/百度/华为地图/腾讯地图)。应用只传递**地点文字**,不传递任何账号信息。是否安装、是否跳转由你决定,**应用不会读取这些地图应用中的任何数据**。 + +--- + +## 三、我们如何存储和保护信息 + +### 3.1 存储位置 + +- **服务端**:数据存储在你**自行部署**的家书服务器上(当前为开发者自建的阿里云服务器,域名 `family.yangyq.net`)。**我们(开发者)没有你的数据副本**。 +- **端侧**:见 1.3 节。 + +### 3.2 保存期限 + +- 只要你的账号存在,你的数据就保留,以便你随时查看。 +- 你**删除**某条内容(日程/任务/笔记等)后,服务端**立即删除**该条记录。 +- 你**注销账号**后,服务端在 **7 日内**删除该账号及其名下全部数据(含附件文件)。 + +### 3.3 安全措施 + +| 层面 | 措施 | +|---|---| +| 传输 | 全站 **HTTPS**(TLS 1.2+),不提供 HTTP 明文入口 | +| 密码 | **bcrypt** 单向哈希,不可逆 | +| 敏感字段 | 手机号、身份证号 **AES-256-CBC 加密**存储 | +| 附件文件 | 服务端**加密存储**;端侧下载后以 **DEK 加密**落地,DEK 由 **HUKS 硬件密钥库**包裹 | +| 登录令牌 | 存于 **HUKS 硬件密钥库** | +| 访问控制 | 每个账号只能访问自己所属家庭的数据;服务端**逐条校验**归属,不靠前端隐藏 | +| 会话 | 登录态失效即需重新认证;支持在设置页**主动退出所有设备** | + +> 说明:任何技术措施都无法保证 100% 安全。若发生安全事件,我们会在**发现后 72 小时内**通过应用内公告告知你,并说明影响范围与应对措施。 + +--- + +## 四、我们如何共享、转让、公开披露信息 + +### 4.1 共享 + +**我们不会与任何第三方共享你的个人信息**,以下三种情形除外: + +1. **你主动分享的内容**:家书支持把某条笔记/任务/账本/日历**共享给同一家庭内的其他成员**。这是你主动发起的操作,共享范围由你选择,可随时撤销。 +2. **你主动导出/下载**:你把数据导出成文件后自行处置,我们不介入。 +3. **法律法规要求**:仅在依法需要配合司法机关或行政机关调查时,按法定程序提供。 + +### 4.2 转让 + +不发生。若未来因合并、分立等原因需转让,我们会提前告知你,并要求承接方继续受本政策约束;否则将删除或匿名化处理。 + +### 4.3 公开披露 + +不发生。我们不公开任何用户的个人信息。 + +### 4.4 第三方 SDK 清单 + +**本应用不集成任何第三方统计、广告、数据分析 SDK。** + +使用到的系统能力(均为鸿蒙系统内置,非第三方 SDK): + +| 能力 | 来源 | 用途 | 是否出网 | +|---|---|---|---| +| Map Kit(`@kit.MapKit`) | 华为 HMS Core | 地点自动补全 | 是(仅关键词) | +| HUKS(`@kit.UniversalKeystoreKit`) | 鸿蒙系统 | 密钥硬件保护 | 否 | +| Crypto(`@kit.CryptoArchitectureKit`) | 鸿蒙系统 | 加解密运算 | 否 | +| MediaLibrary(`@kit.MediaLibraryKit`) | 鸿蒙系统 | 保存附件到相册 | 否 | +| ShareKit(`@kit.ShareKit`) | 鸿蒙系统 | 系统分享面板 | 否 | +| Telephony(`@kit.TelephonyKit`) | 鸿蒙系统 | 拉起系统拨号盘(仅填充号码) | 否 | +| BackgroundTasks(`@kit.BackgroundTasksKit`) | 鸿蒙系统 | 定时后台同步 | 否 | + +--- + +## 五、你的权利 + +依据《中华人民共和国个人信息保护法》,你对自己的个人信息享有以下权利。**这些权利在家书里都是自助可用的**,不需要发邮件申请: + +| 权利 | 在家书里怎么做 | +|---|---| +| **查阅、复制** | 各模块列表直接查看;资源模块支持导出;`设置 → 数据导出` 可整体导出 | +| **更正、补充** | 任意条目点开 → 编辑 → 保存 | +| **删除** | 任意条目点开 → 删除;删除立即生效 | +| **撤回同意** | `设置 → 隐私` 可撤回对可选权限的授权(如握姿识别) | +| **注销账号** | `设置 → 账号 → 注销账号`。注销后 7 日内删除全部数据,**不可恢复** | +| **获取副本** | `设置 → 数据导出`,导出为 JSON/CSV 文件到你指定位置 | + +若上述自助途径无法满足(例如你已卸载应用但想删除服务器上的数据),可通过第九节的方式联系我们,我们会在 **15 个工作日**内响应。 + +--- + +## 六、未成年人保护 + +家书是家庭工具,**不面向未成年人独立提供服务**。 + +- 未满 14 周岁的未成年人**不得自行注册**账号。若家庭成员中有未成年人,其信息由**监护人**代为录入与管理,监护人可随时查看、更正、删除。 +- 我们不收集**儿童**的独立账号信息;名册中记录的未成年家庭成员信息,属于监护人主动录入的家庭内部资料。 +- 若我们发现无意中收集了未满 14 周岁儿童的个人信息而未获监护人同意,将**立即删除**。 + +--- + +## 七、信息存储地域 + +你的数据存储在**中华人民共和国境内**(开发者自建的阿里云中国大陆节点服务器)。 + +**我们不向境外提供你的个人信息。** + +--- + +## 八、本政策的更新 + +- 本政策如有实质性变更(例如新增了信息收集项、改变了使用目的、扩大了共享范围),我们会在应用内**以弹窗形式**提示你,并在你**明确同意后**才生效。 +- 非实质性变更(如文字润色、联系方式变更)会直接更新本页并修改顶部「最后更新」日期。 +- 历史版本可向我们索取。 + +--- + +## 九、联系我们 + +| 项 | 内容 | +|---|---| +| **开发者** | 杨永全(个人开发者) | +| **联系邮箱** | `i@yangyq.net` | +| **响应时限** | 收到后 **15 个工作日**内答复 | +| **我的家书服务地址** | `https://family.yangyq.net` | + +如你对我们的答复不满意,或认为我们的个人信息处理行为损害了你的合法权益,你可以向**网信部门、电信主管部门、公安部门、市场监管部门**等监管机构投诉举报,也可以向**被告住所地有管辖权的人民法院**提起诉讼。 + +--- + +## 十、附录:与权限清单的逐条对照(供审核核对) + +| 权限/能力 | 是否申请 | 本政策对应条款 | +|---|---|---| +| `ohos.permission.INTERNET` | ✅ 申请 | 第二节表格第 1 行 | +| `ohos.permission.GET_NETWORK_INFO` | ✅ 申请 | 第二节表格第 2 行 | +| `ohos.permission.DETECT_GESTURE` | ✅ 申请 | 第二节表格第 3 行 | +| Map Kit(`@kit.MapKit`) | ✅ 调用 | 第二节「关于地址联想」 | +| 定位(LOCATION) | ❌ 未申请 | 1.4 节明示不收集 | +| 通讯录(READ_CONTACTS) | ❌ 未申请 | 1.4 节明示不收集 | +| 相机(CAMERA) | ❌ 未申请 | — | +| 相册读写(READ/WRITE_IMAGEVIDEO) | ❌ 未申请 | 1.2 节说明用系统选择器 | +| 麦克风(MICROPHONE) | ❌ 未申请 | — | +| 设备标识符 | ❌ 未申请 | 1.4 节明示不收集 | + +--- + +*本政策自 2026 年 11 月 1 日起生效。* \ No newline at end of file