feat(framework): platform PlayerStore(=C_Player) applyLogin

Implement PlayerStore wrapping signal<PlayerState> for player account data.
Adds applyLogin(raw) to fill state from login response A group, with:
- Mandatory fields get default 0/'' if missing (never undefined)
- Optional fields (openid/unionid/province/city) only set if present
- Immutable updates via spread operator
- Notifies subscribers on state change

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-28 22:06:06 +08:00
co-authored by Claude Opus 4.8
parent 7659e1fac5
commit 4b4e2261b4
2 changed files with 74 additions and 0 deletions
@@ -0,0 +1,36 @@
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { PlayerStore } from '../../YouleNexus/assets/framework/platform/stores/player-store.ts';
const RAW = { state: 0, playerid: 430511, nickname: '测试号', avatar: 'http://a', sex: 0,
bean: 0, roomcard: 3, score: 0, taskstate: 1, advanced: 0, bankpower: 1, bank: 0, bankpwd: 0,
ip: '127.0.0.1', sign: null, tel: null, invitecode: null, initCard: '3', initBean: '0',
openid: 'o1', unionid: 'u1', province: 'p', city: 'c' };
test('applyLogin 填充 PlayerState 并通知订阅者', () => {
const store = new PlayerStore();
let notified = 0;
store.state.subscribe(() => { notified++; });
store.applyLogin(RAW as any);
const v = store.state.value;
assert.equal(v.playerid, 430511);
assert.equal(v.nickname, '测试号');
assert.equal(v.roomcard, 3);
assert.equal(v.taskstate, 1);
assert.equal(v.openid, 'o1');
assert.equal(v.initCard, '3');
assert.equal(notified, 1);
});
test('charm 等缺省字段补默认 0', () => {
const store = new PlayerStore();
store.applyLogin(RAW as any);
assert.equal(store.state.value.charm, 0);
});
test('未下发的可选字段(openid 等)缺省时不写入', () => {
const store = new PlayerStore();
store.applyLogin({ state: 0, playerid: 1 } as any);
assert.equal(store.state.value.openid, undefined);
assert.equal(store.state.value.playerid, 1);
});