game/assets/game-api.js
李鹏宇 d9269e0f56 feat: 论坛/公告/剧情打通 Odoo —— 新增小说模型与阅读器
- 新增 game.story.volume / game.story.chapter 模型 + 后台菜单视图
- 新增 /game/api/story(目录) 与 /game/api/story/chapter/<id>(正文) 接口
- 三块补充 Odoo 默认种子数据(剧情 2 卷 5 章、论坛 5 帖、公告 4 条)
- 前端:剧情改造为左目录 + 右正文的小说阅读器;论坛改为登录后可见(auth-only);论坛/公告调整为竖排阅读布局
2026-07-24 15:56:42 +08:00

103 lines
3.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 宇森游戏 · 前端与 Odoo 通信层
// 本地调试:前端 8888 -> Odoo 8069跨域带调试 CORS 头)
// 生产部署:前端与 Odoo 同域,由 nginx 代理 /game/*。
// 说明odoo.conf 已 db_name=yt_game 钉死库URL 上的 ?db= 形同虚设,
// 请求一律落到 yt_game下列 game/* 沿用统一 API_CONFIGyt_world/* 单独带 ?db=yt_game。
const API_CONFIG = {
base: (location.hostname === '127.0.0.1' && location.port === '8888')
? 'http://127.0.0.1:8069'
: (location.hostname === 'localhost' && location.port === '8888')
? 'http://127.0.0.1:8069'
: '',
db: (location.hostname === '127.0.0.1' && location.port === '8888') ? 'study' : 'game',
};
const _cred = API_CONFIG.base ? 'include' : 'same-origin';
function _url(path) {
return `${API_CONFIG.base}${path}?db=${API_CONFIG.db}`;
}
const API = {
async me() {
return (await fetch(_url('/game/api/me'), { credentials: _cred })).json();
},
async login(login, password) {
return (await fetch(_url('/game/api/login'), {
method: 'POST', credentials: _cred,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ login, password }),
})).json();
},
async register(payload) {
return (await fetch(_url('/game/api/register'), {
method: 'POST', credentials: _cred,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
})).json();
},
async logout() {
return (await fetch(_url('/game/api/logout'), {
method: 'POST', credentials: _cred,
})).json();
},
async codex() {
return (await fetch(_url('/game/api/codex'), { credentials: _cred })).json();
},
async rules() {
return (await fetch(_url('/game/api/rules'), { credentials: _cred })).json();
},
async currencies() {
return (await fetch(_url('/game/api/currencies'), { credentials: _cred })).json();
},
async pages() {
return (await fetch(_url('/game/api/pages'), { credentials: _cred })).json();
},
async threads() {
return (await fetch(_url('/game/api/threads'), { credentials: _cred })).json();
},
async announcements() {
return (await fetch(_url('/game/api/announcements'), { credentials: _cred })).json();
},
async story() {
return (await fetch(_url('/game/api/story'), { credentials: _cred })).json();
},
async storyChapter(cid) {
return (await fetch(_url('/game/api/story/chapter/' + cid), { credentials: _cred })).json();
},
// ---------- 沙盘记忆yt_world 模块) ----------
async world() {
return (await fetch('/yt_world/api/world?db=yt_game', { credentials: 'same-origin' })).json();
},
async saveTiles(tiles) {
return (await fetch('/yt_world/api/tiles/save?db=yt_game', {
method: 'POST', credentials: 'same-origin',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ tiles }),
})).json();
},
async saveSettings(settings) {
return (await fetch('/yt_world/api/settings?db=yt_game', {
method: 'POST', credentials: 'same-origin',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ settings }),
})).json();
},
// ---------- 世界数据 / 包裹后端接口预留yt_world 暂未实现路由,前端 mock 兜底) ----------
async worldData() {
try {
const r = await fetch('/yt_world/api/data?db=yt_game', { credentials: 'same-origin' });
if (!r.ok) return null;
return await r.json();
} catch (e) { return null; }
},
async inventory() {
try {
const r = await fetch('/yt_world/api/inventory?db=yt_game', { credentials: 'same-origin' });
if (!r.ok) return null;
return await r.json();
} catch (e) { return null; }
},
};