5.9 KiB
5.9 KiB
概览
- 新增两个对外页面:
/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:创建线上预定,入参:start、terminal、train_type、trips、ride_date(YYYY-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.jsonl的type:'sale')统计近7天或全部的热门站点与热门路线,返回{ topStations: [{name, code, count}], topRoutes: [{from,to,count}] }。
- 路由与静态文件:
- 追加服务器路由以兼容直链:
GET /ticket-search/:id与GET /ticket-search均返回同一静态页面文件(web/ticket-search.html);页面端通过location.pathname识别:id并拉取数据。 - 同理为
GET /ticket-order返回web/ticket-order.html。
- 追加服务器路由以兼容直链:
- 复用/对齐:价格计算逻辑沿用控制台已有数据源与折扣(
server.js已持久化stations/lines/fares与promotion)。
前端页面
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),其余流程保持英文。 - 新增页面:线上凭证输入与验证
- 屏幕键盘(A–Z、0–9、Backspace、Clear、OK),输入 5 位码;UI使用既有
addButton/waitButtons组件。 - 验证逻辑:
GET http://ticket.fse-media.group/api/public/orders/:code(或由config.json的api_base指到生产域),若返回存在且ride_date == os.date('%Y-%m-%d')且未consumed,则有效。- 有效则将
state.departure、state.terminal、state.trainType、state.trips、state.cost赋值并跳转到订单确认/支付页;支付逻辑与线下一致。 - 无效弹英文提示:
Invalid voucher。
- 兑票完成后调用
POST /api/public/orders/:code/consume标记已使用。
- 屏幕键盘(A–Z、0–9、Backspace、Clear、OK),输入 5 位码;UI使用既有
- 变更点位置参考:
- 首页按钮处:在
Lua/TicketMachine/startup.lua:805..822的showHome,替换Start为NEW与ONLINE两个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 文档)。 - 老版本或单机不同路径,参考提供的文档片段。
- Minecraft 1.13+:在
- 售票机
config.json或API_ENDPOINT.txt指向生产 API 基础地址,startup.lua中API_BASE也将改为生产地址。
文案与样式约定
- Web 前端:中文页面与控件;
- CC:T 端所有提示、按钮、错误信息统一英文(现有实现已如此,新增页面按该规范)。
- 整体风格沿用
web/style.css控制台样式(深色/浅色模式兼容)。
交付物
- 新增/修改的文件:
web/ticket-search.html,web/ticket-search.jsweb/ticket-order.html,web/ticket-order.jsweb/server.js(新增orders/popular接口与静态路由)web/data/orders.json,web/data/order_index.jsonLua/TicketMachine/startup.lua(首页按钮与线上凭证流程)
验证
- 后端:本地启动后用
GET /api/public/popular、POST /api/public/orders、GET /api/public/orders/:code联调; - 前端:打开
/ticket-order生成凭证 → 复制码直链查看/ticket-search/:code; - 售票机:触发
ONLINE流程,输入码验证跨天逻辑与支付流程,兑票后标记消费成功。
兼容/风险控制
- 所有新增逻辑均以新文件/新接口为主,避免破坏现有控制台;
- 前端/后端的模糊搜索初期采用子串匹配,后续可替换为更精细的打分;
- 若 HTTP 被禁,售票机将回退到线下流程,界面提示网络不可用。