v0.7.0 接上真实服务器:登录 / 设备会话 / 全量同步与各模块真实数据
从「演示数据壳子」走到「真的能连家里的服务器用」。
登录(用户 2026-10-17「完整的登录功能」)
· 首次启动先填服务器地址 → /api/v1/ping 自报门户(认得出"这地址上真是家书")
· 手机号或用户名 + 密码 → 拿令牌;失败提示统一,不泄露账号是否存在
· FbDeviceStore:首次启动生成并持久化设备 UUID(三方应用拿不到 UDID),
设备名取机型(marketName),并上报 platform / app_version
设备会话(v57,用户 2026-10-17)
· 一把令牌 = 一台设备的一条会话;每次启动打一次 /me(有网就验)
· 两种锁分开:need_login(401/被踢 → 清令牌)与 offline_expired
(离线超 24h → 只锁界面、不清数据、联网自动恢复)——
混成一种就会违背用户要的"一直联网就不用每天输密码"
· 运行期任何请求 401 → 网络层全局回调立刻锁定跳登录页(FbHttp 的 authProbe
让登录/校验类请求跳过,避免"两个地方同时跳登录页")
· 退出登录:先清本地令牌(主防线),再尽力通知服务端
· 设置页显示版本号与「这台设备」
数据层
· FbDb / FbSchema / FbParse / 各 Repo(日程 / 名册 / 观影 / 模块)+ FbSyncAll
· 首页改为服务端 /home(农历/节气/纪念日/生日/天气/统计/往年的今天)
· 日程页用 FbDayEventPanel,与网页端显示方式/红线/并排三处一致
验证:ArkTS 静态守卫 231/0;hvigor 编译 BUILD SUCCESSFUL(entry-default-signed.hap)。
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* 家书 FamilyBook · 设置里的「单选行」(鸿蒙端)
|
||||
*
|
||||
* 🔴🔴 为什么必须是**组件**而不是 `@Builder`(用户 2026-10-16 报的真 bug):
|
||||
* 「设置里面这个"**默认视图**",**都没法点**,也没有办法设置。」
|
||||
* 根因:原来是 `FbCalSettingsSheet.radioRow(label, hint, on: boolean, onTap)` ——
|
||||
* **`@Builder` 的值类型参数(boolean)不参与状态观察**
|
||||
* (SDK 规则 `r/quick-rules/05-state.md`:按值传递「状态变化刷新 ❌」)。
|
||||
* ⇒ 点一下 `this.view` 确实变了、`FB_CAL_SETTINGS.setView()` 也确实写了,
|
||||
* 但**打勾 ✓ 与高亮底色的那份子树不重建** ⇒ 看着"点了没反应"。
|
||||
* 本项目已在 `FbTagChip` 上踩过同一个坑(见那份文件头),这里照同样办法修。
|
||||
*
|
||||
* ⚠️ 顺带说明:ForEach 的 key **不用**带选中态 —— 只要这一片是
|
||||
* `@ComponentV2` + `@Param`,`active` 变了它自己就会重建。
|
||||
* (`FbTagChip` 的 key 也只是标签名。)
|
||||
*/
|
||||
|
||||
import { FbColors, FbMetric } from '../common/Theme';
|
||||
import { FbDot } from './Widgets';
|
||||
|
||||
@ComponentV2
|
||||
export struct FbCalOptionRow {
|
||||
/** 主文字 */
|
||||
@Param label: string = '';
|
||||
/** 副说明(小字;空则不占位) */
|
||||
@Param hint: string = '';
|
||||
/** 是否选中(**必须由父组件算好传进来**) */
|
||||
@Param active: boolean = false;
|
||||
/** 左侧色点(日历本那几行用它;空则不画) */
|
||||
@Param dotColor: string = '';
|
||||
/** 被点击 */
|
||||
@Event onPick: () => void = (): void => {
|
||||
};
|
||||
|
||||
build() {
|
||||
Row({ space: 10 }) {
|
||||
if (this.dotColor !== '') {
|
||||
FbDot({ dia: 10, fillC: this.dotColor })
|
||||
}
|
||||
Column({ space: 2 }) {
|
||||
Text(this.label)
|
||||
.fontSize(FbMetric.fontSmall)
|
||||
.fontColor(this.active ? '#4A7C82' : FbColors.ink)
|
||||
.fontWeight(this.active ? FontWeight.Medium : FontWeight.Normal)
|
||||
.maxLines(2)
|
||||
if (this.hint !== '') {
|
||||
Text(this.hint)
|
||||
.fontSize(FbMetric.fontTiny)
|
||||
.fontColor(FbColors.faint)
|
||||
.maxLines(2)
|
||||
}
|
||||
}
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
.layoutWeight(1)
|
||||
|
||||
Text(this.active ? '✓' : '')
|
||||
.fontSize(FbMetric.fontSmall)
|
||||
.fontColor('#4A7C82')
|
||||
.width(20)
|
||||
.textAlign(TextAlign.Center)
|
||||
}
|
||||
.width('100%')
|
||||
.padding({ top: 10, bottom: 10, left: 12, right: 12 })
|
||||
.backgroundColor(this.active ? '#EAF2F2' : FbColors.inputBg)
|
||||
.borderRadius(FbMetric.radiusS)
|
||||
.margin({ bottom: 8 })
|
||||
.alignItems(VerticalAlign.Center)
|
||||
.onClick((): void => {
|
||||
this.onPick();
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user