下载 App
数据持久化
06/285 浏览综合
这两个问题很可能是因果关系:
投资数据没持久化
↓
刷新重进 → Store 加载出来的数据是空的/旧的
↓
PostWallNoteToServer() 计算的 profitCents = 0 或上次的旧值
↓
wall_profit 在 serverCloud 中始终是 0 或空
↓
GetRankList("wall_profit") 返回的要么是 0 要么干脆没有记录
↓
便签墙上显示 "+0元" 或者根本没有便签
更严重的情况:如果连 wall_profit 的 SetInt 都没成功写入 serverCloud,那 GetRankList 查询结果为空 → 便签墙完全没有数据可显示。


验证链路
让我追踪完整的数据持久化链路:
| 环节 | 时机 | 是否可靠 |
|---|---|---|
| 用户添加交易 | 点击"保存" | Store 内存修改 |
| MarkDirty | 保存后标记 | 应该有 |
| SyncToCloud | 只在 Stop() 中 | WASM 刷新不触发 |
| serverCloud 写入 | UserDataProxy → 服务端 | 如果 Sync 没调用就没机会写 |
| 重新加载 | 刷新后 LoadFromCloud | 读到的是旧数据(因为没写入过) |
| PostWallNoteToServer | 登录后用 Store 数据计算 | 基于旧/空数据计算 → 便签错误 |
核心断裂点:SyncToCloud 几乎不被调用(只有 Stop),所以数据永远留在内存里,刷新就丢。


所以根因是同一个
数据不持久化 → 便签墙无数据
不是两个独立 bug,是一个 bug 的两个表现:
- 表现 A:刷新后持仓/交易记录消失
- 表现 B:便签墙空白(因为 wall_profit 从没被正确写入)


修复方向(一个修复解决两个问题)
在 HandleUpdate 中加定时自动保存:
lua复制
lualocal autoSaveTimer = 0 local AUTO_SAVE_INTERVAL = 15 -- 每15秒 -- HandleUpdate 中: if isLoggedIn and Store.IsDirty() then autoSaveTimer = autoSaveTimer + dt if autoSaveTimer >= AUTO_SAVE_INTERVAL then Store.SyncToCloud() autoSaveTimer = 0 end end
这样:
- 用户修改数据 → 15秒内自动同步到 serverCloud
- 刷新重进 → LoadFromCloud 读到最新数据
- PostWallNoteToServer 用正确的 profit 计算 → 便签墙正确
要现在修复吗?
06-28 18:04
[图片:暂不支持黏贴,请手动导入]
嗒啦啦忙完啦,接下来想做什么?
消耗53积分|剩余1501通用积分
评价一下嗒啦啦的工作
嗒啦啦陷入沉思中...
好的发现。既然数据持久化没问题(刷新后还在),那便签不显示是独立的问题。
让我重新分析便签不显示的原因:


排除持久化问题后,便签不显示的可能原因
原因 1:时序问题(最可能)
登录页渲染(立即)→ 便签区域为空
↓(等待 1~10 秒)
服务器连接成功 → ServerReady
↓
WallClient 发送 CLIENT_READY
↓
服务器返回 WALL_SYNC_ALL(便签数据)
↓
Login.RefreshWallWithData(notes) → 更新 UI
如果用户在服务器返回数据之前就点了"进入系统",便签渲染的回调就没机会触发了。


原因 2:wall_profit 从未被写入 serverCloud
在多人模式下,PostWallNoteToServer 只是把便签发给了 WallServer 的共享墙内存(uid=0 公共池)。
但 serverCloud:SetInt(uid, "wall_profit", profitCents) 这一步可能从未执行!
原来设计是用 clientCloud:SetInt("wall_profit", profitCents)(排行榜写入),但多人模式 clientCloud 为 nil,所以:
| 操作 | standalone 模式 | multiplayer 模式 |
|---|---|---|
| 写 wall_profit 到排行榜 | clientCloud:SetInt | 没有对应代码 |
| 便签发到共享墙 | 无服务端 | WallServer |
| 排行榜查询能看到 | (从未写入 iscore) |
这就解释了为什么管理员面板显示 “+0元” —— wall_profit 作为 iscore 从没被写入过。


原因 3:你说的昵称问题
你改了昵称为 “3H”,但便签系统显示的名字取决于:
- PostWallNoteToServer(WallClient, Login.GetNickname()) 中的 nickname 参数
- 如果 Login.GetNickname() 返回的是旧值(“coco” 或 “1118015608”),便签上不会显示 “3H”
但这不会导致便签不显示,只会导致显示错误的名字。


真正的 Bug 是什么
最可能的组合:
- 服务器连接慢 → WALL_SYNC_ALL 返回时,可能已经过了登录页
- 共享墙为空 → 因为 PostWallNoteToServer 是在登录成功后才调用,第一次看登录页时服务器里还没有任何便签
- 刷新进入时:服务器如果重启了(persistent_world 不保证永久运行),内存中的便签会丢失,需要从 serverCloud 重新加载
循环死锁:
登录页需要便签 → 便签在登录成功后才写入 → 只有下次进入才能看到
↓
但如果服务器重启了 → 内存清空 → 又需要从 serverCloud 加载
↓
如果 serverCloud 中 wall_profit/wall_msg 没写入 → 加载出来也是空


修复方向
- 服务端登录时写 wall_profit iscore — serverCloud:SetInt(uid, "wall_profit", profitCents) 在用户数据保存时同步写入
- WallServer 持久化 — 确保共享墙数据在服务器重启后能恢复
- 本地缓存便签 — 上次看到的便签数据保存本地,下次立即渲染(不等服务器)
- 昵称同步 — PostWallNoteToServer 使用用户实际设置的昵称





