chore: novel auto-sync, codex data seeding, story page font slider UI, topbar reorder, codex/codex filter/search/sticky refinements
This commit is contained in:
@@ -9,11 +9,22 @@ _logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _json(data):
|
||||
"""返回 UTF-8 JSON 响应(与 game_base 一致)。"""
|
||||
return Response(
|
||||
json.dumps(data, ensure_ascii=False),
|
||||
content_type='application/json; charset=utf-8',
|
||||
)
|
||||
"""返回 UTF-8 JSON 响应(与 game_base 一致),并附带 CORS 头以支持跨域(8080→8069)。"""
|
||||
headers = {
|
||||
'Content-Type': 'application/json; charset=utf-8',
|
||||
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
||||
'Access-Control-Allow-Headers': 'Content-Type',
|
||||
}
|
||||
try:
|
||||
origin = request.httprequest.headers.get('Origin')
|
||||
if origin:
|
||||
headers['Access-Control-Allow-Origin'] = origin
|
||||
headers['Access-Control-Allow-Credentials'] = 'true'
|
||||
else:
|
||||
headers['Access-Control-Allow-Origin'] = '*'
|
||||
except Exception:
|
||||
headers['Access-Control-Allow-Origin'] = '*'
|
||||
return Response(json.dumps(data, ensure_ascii=False), headers=headers)
|
||||
|
||||
|
||||
def _post_body():
|
||||
@@ -86,3 +97,46 @@ class YtWorldApi(http.Controller):
|
||||
world.name = name
|
||||
_logger.info('yt.world rename uid=%s %r -> %r', user.id, old, name)
|
||||
return _json({'ok': True, 'name': name})
|
||||
|
||||
# ========== 图鉴 API ==========
|
||||
|
||||
def _records_json(self, model, fields):
|
||||
"""将 model 的全部记录转为 [{field: value}, ...] 格式(Json 字段解析为对象)。"""
|
||||
recs = request.env[model].sudo().search([], order='sequence, id')
|
||||
out = []
|
||||
for r in recs:
|
||||
item = {}
|
||||
for f in fields:
|
||||
val = getattr(r, f)
|
||||
if isinstance(val, str):
|
||||
try:
|
||||
val = json.loads(val)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
item[f] = val
|
||||
out.append(item)
|
||||
return _json(out)
|
||||
|
||||
@http.route('/yt_world/api/codex/resources', type='http', auth='public',
|
||||
methods=['GET', 'OPTIONS'], csrf=False)
|
||||
def codex_resources(self, **kw):
|
||||
return self._records_json('yt.codex.resource',
|
||||
['code','name','icon','category','quality','source','uses','recipe','description'])
|
||||
|
||||
@http.route('/yt_world/api/codex/creatures', type='http', auth='public',
|
||||
methods=['GET', 'OPTIONS'], csrf=False)
|
||||
def codex_creatures(self, **kw):
|
||||
return self._records_json('yt.codex.creature',
|
||||
['code','name','icon','habitat','tameable','diet','products','description'])
|
||||
|
||||
@http.route('/yt_world/api/codex/monsters', type='http', auth='public',
|
||||
methods=['GET', 'OPTIONS'], csrf=False)
|
||||
def codex_monsters(self, **kw):
|
||||
return self._records_json('yt.codex.monster',
|
||||
['code','name','icon','tier','level_min','level_max','habitat','drops','description'])
|
||||
|
||||
@http.route('/yt_world/api/codex/races', type='http', auth='public',
|
||||
methods=['GET', 'OPTIONS'], csrf=False)
|
||||
def codex_races(self, **kw):
|
||||
return self._records_json('yt.codex.race',
|
||||
['code','name','icon','layer','traits','description'])
|
||||
|
||||
Reference in New Issue
Block a user