app #1 simpleasm: 从 oci 迁过来,asm.famzheng.me 已上线
- 后端 FastAPI 重写为 axum + rusqlite (musl static, 2.8MB) - 前端原样搬运 (Vue3 + Vite + Pinia + vue-router + vite-plugin-yaml) - k8s: cube-simpleasm ns + 1Gi PVC (k3s local-path) + Recreate strategy - CI: 复刻 deploy-cube.yml,按 apps/simpleasm/** 触发 - cube 门户里 simpleasm 状态从 pending 改成 live - 数据冷启 (Fam 拍板不带历史进度)
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useGameStore = defineStore('game', {
|
||||
state: () => ({
|
||||
playerName: localStorage.getItem('asm_playerName') || '',
|
||||
playerId: parseInt(localStorage.getItem('asm_playerId')) || null,
|
||||
progress: JSON.parse(localStorage.getItem('asm_progress') || '{}'),
|
||||
}),
|
||||
|
||||
getters: {
|
||||
isLoggedIn: (state) => !!state.playerName && !!state.playerId,
|
||||
totalStars: (state) => Object.values(state.progress).reduce((s, p) => s + (p.stars || 0), 0),
|
||||
levelsCompleted: (state) => Object.values(state.progress).filter(p => p.completed).length,
|
||||
isLevelUnlocked() {
|
||||
return (levelId) => {
|
||||
if (levelId === 1) return true
|
||||
return !!this.progress[levelId - 1]?.completed
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
actions: {
|
||||
async login(name) {
|
||||
try {
|
||||
const res = await fetch('/api/players', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ name }),
|
||||
})
|
||||
const data = await res.json()
|
||||
this.playerName = data.name
|
||||
this.playerId = data.id
|
||||
if (data.progress) {
|
||||
this.progress = { ...this.progress, ...data.progress }
|
||||
}
|
||||
this._persist()
|
||||
return true
|
||||
} catch {
|
||||
// offline mode - just save locally
|
||||
this.playerName = name
|
||||
this.playerId = Date.now()
|
||||
this._persist()
|
||||
return true
|
||||
}
|
||||
},
|
||||
|
||||
async saveProgress(levelId, stars, code) {
|
||||
const existing = this.progress[levelId]
|
||||
const bestStars = Math.max(stars, existing?.stars || 0)
|
||||
this.progress[levelId] = { completed: true, stars: bestStars, code }
|
||||
this._persist()
|
||||
|
||||
try {
|
||||
await fetch('/api/progress', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
player_id: this.playerId,
|
||||
level_id: levelId,
|
||||
stars: bestStars,
|
||||
code,
|
||||
}),
|
||||
})
|
||||
} catch {
|
||||
// ok, saved locally
|
||||
}
|
||||
},
|
||||
|
||||
logout() {
|
||||
this.playerName = ''
|
||||
this.playerId = null
|
||||
this.progress = {}
|
||||
localStorage.removeItem('asm_playerName')
|
||||
localStorage.removeItem('asm_playerId')
|
||||
localStorage.removeItem('asm_progress')
|
||||
},
|
||||
|
||||
_persist() {
|
||||
localStorage.setItem('asm_playerName', this.playerName)
|
||||
localStorage.setItem('asm_playerId', String(this.playerId))
|
||||
localStorage.setItem('asm_progress', JSON.stringify(this.progress))
|
||||
},
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user