Files
FSE-Ticket.sys/.trae/documents/新增对外车票查询与线上预定,并接入售票机凭证兑票.md
T
2026-06-21 10:00:13 +08:00

5.9 KiB
Raw Blame History

概览

  • 新增两个对外页面:/ticket-search(车票查询/详情)与/ticket-order(线上预定)
  • 后端增加“线上预定/凭证”API,售票机支持“NEW/ONLINE”两模式,线上凭证在当天有效
  • 页面样式统一沿用现有控制台风格(web/style.css),Minecraft 端所有文案保持英文

后端改动(Node/Express

  • 新增数据文件:web/data/orders.json(列表)、web/data/order_index.json(按码索引)
  • 新增接口:
    • POST /api/public/orders:创建线上预定,入参:startterminaltrain_typetripsride_dateYYYY-MM-DD)。生成唯一5位字母数字凭证 code,返回 { ok:true, code, price }。价格通过现有票价数据计算(普通/特急),并按当前促销折扣应用(与/api/public/config一致)。
    • GET /api/public/orders/:code:查询凭证详情,返回 { code, start, terminal, train_type, trips, ride_date, price, created_ts, consumed:false }
    • POST /api/public/orders/:code/consume:兑票后标记消费(幂等),防重复使用;返回 { ok:true }
    • GET /api/public/popular:根据现有售票事件日志(web/data/ticket_events.jsonltype:'sale')统计近7天或全部的热门站点与热门路线,返回 { topStations: [{name, code, count}], topRoutes: [{from,to,count}] }
  • 路由与静态文件:
    • 追加服务器路由以兼容直链:GET /ticket-search/:idGET /ticket-search 均返回同一静态页面文件(web/ticket-search.html);页面端通过 location.pathname 识别 :id 并拉取数据。
    • 同理为 GET /ticket-order 返回 web/ticket-order.html
  • 复用/对齐:价格计算逻辑沿用控制台已有数据源与折扣(server.js 已持久化 stations/lines/farespromotion)。

前端页面

  • web/ticket-search.html + web/ticket-search.js
    • 顶部搜索栏(支持模糊匹配,匹配票号、起点、终点、站点编号)。调用 GET /api/public/tickets?q=... 渲染列表,点击进入详情。
    • 详情视图:支持直链 ticket.fse-media.group/ticket-search/XXXX,通过 GET /api/public/tickets/:id 展示“概览+事件时间线”。
    • 辅助区块:热门站点与热门路线,调用 GET /api/public/popular,以卡片或列表展示。
    • 样式统一使用 web/style.css 的卡片/列表/按钮体系。
  • web/ticket-order.html + web/ticket-order.js
    • 流程:选择起点/终点(下拉+模糊搜索)、车型(普通/特急)、乘次、乘车日期(日期选择器)。右侧实时显示价格(调用 GET /api/public/fares/query 并应用折扣)。
    • 点击“生成凭证”后调用 POST /api/public/orders,展示返回的 5 位字母数字码及说明:“到游戏内售票机付款”。
    • 提供“复制凭证码”、“查看我的凭证详情”按钮(跳到 /ticket-search/:code)。

售票机 Lua 改动

  • 首页两按钮:NEW(线下购买)与 ONLINE(线上兑票)。位置/大小与现有 Start 等同(修改 showHome),其余流程保持英文。
  • 新增页面:线上凭证输入与验证
    • 屏幕键盘(AZ、09、Backspace、Clear、OK),输入 5 位码;UI使用既有 addButton/waitButtons 组件。
    • 验证逻辑:
      • GET http://ticket.fse-media.group/api/public/orders/:code(或由 config.jsonapi_base 指到生产域),若返回存在且 ride_date == os.date('%Y-%m-%d') 且未 consumed,则有效。
      • 有效则将 state.departurestate.terminalstate.trainTypestate.tripsstate.cost 赋值并跳转到订单确认/支付页;支付逻辑与线下一致。
      • 无效弹英文提示:Invalid voucher
    • 兑票完成后调用 POST /api/public/orders/:code/consume 标记已使用。
  • 变更点位置参考:
    • 首页按钮处:在 Lua/TicketMachine/startup.lua:805..822showHome,替换 StartNEWONLINE 两个 addButton,分别进入现有线下流程与新逻辑。
    • 新增函数如 showOnlineVoucher():与 showOrderAndAudio() 类似结构,添加键盘与HTTP校验后复用订单页。
    • HTTP 使用已存在封装:fetchHTTP()jsonDecode()startup.lua:191..198, 186..189)。

域名与HTTP访问

  • 站点部署到 ticket.fse-media.group,售票机需允许该域名的HTTP访问:
    • Minecraft 1.13+:在 serverconfig/computercraft-server.toml 中移除或调整 [[http.rules]] host = "$private" action = "deny"(参见 Tweaked CC 文档)。
    • 老版本或单机不同路径,参考提供的文档片段。
  • 售票机 config.jsonAPI_ENDPOINT.txt 指向生产 API 基础地址,startup.luaAPI_BASE 也将改为生产地址。

文案与样式约定

  • Web 前端:中文页面与控件;
  • CC:T 端所有提示、按钮、错误信息统一英文(现有实现已如此,新增页面按该规范)。
  • 整体风格沿用 web/style.css 控制台样式(深色/浅色模式兼容)。

交付物

  • 新增/修改的文件:
    • web/ticket-search.html, web/ticket-search.js
    • web/ticket-order.html, web/ticket-order.js
    • web/server.js(新增orders/popular接口与静态路由)
    • web/data/orders.json, web/data/order_index.json
    • Lua/TicketMachine/startup.lua(首页按钮与线上凭证流程)

验证

  • 后端:本地启动后用 GET /api/public/popularPOST /api/public/ordersGET /api/public/orders/:code 联调;
  • 前端:打开 /ticket-order 生成凭证 → 复制码直链查看 /ticket-search/:code
  • 售票机:触发 ONLINE 流程,输入码验证跨天逻辑与支付流程,兑票后标记消费成功。

兼容/风险控制

  • 所有新增逻辑均以新文件/新接口为主,避免破坏现有控制台;
  • 前端/后端的模糊搜索初期采用子串匹配,后续可替换为更精细的打分;
  • 若 HTTP 被禁,售票机将回退到线下流程,界面提示网络不可用。