wxyyb00/ticket-agent

GitHub: wxyyb00/ticket-agent

一个自部署的演唱会黄牛票比价与价格追踪工具,利用视觉大模型把报价截图转化为结构化数据,支持跨表价格追踪和全程溯源。

Stars: 7 | Forks: 1

# 🎫 抢票比价 · 黄牛票性价比助手 **把黄牛发来的一堆座位报价截图扔进来,自动比价、追踪价格波动,每个数字都能点回原图。** *A self-hosted price-comparison & tracking agent for concert resale tickets: throw in scalpers' quote screenshots, get structured price comparison, cross-batch price tracking with carry-forward semantics, and per-number provenance back to the original image. Parsing is powered by Qwen-VL (Alibaba Bailian); everything runs locally on Node 24 + built-in SQLite. Chinese UI — see [Quick Start](#-快速开始三分钟) below.* [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) [![Node](https://img.shields.io/badge/Node-%E2%89%A524-brightgreen)](#-快速开始三分钟) 找位置:按偏好+预算排出性价比最优
## 这是什么? 追星党都懂的痛:想看的演唱会官方票秒没,只能看黄牛。然后你会同时加三五个票务,每家隔三差五甩来一张**格式各异的报价表截图**—— - 想比价?只能自己拿计算器把几张表来回翻。 - 想知道「这个位置比上周便宜了没」?翻聊天记录翻到眼花。 - 想知道「加价了几倍」?得先找到官方海报上那个区的原价,还得换算汇率。 - 最怕的:转钱之前突然心虚——「这价格我是不是记错了?是哪张表说的来着?」 这个工具把这些全自动化了:**截图扔进来 → AI 解析成结构化数据 → 按你的偏好和预算排出性价比最优 → 跨表追踪价格波动 → 每个数字可一键溯源回原始截图**。 数据全部存在你自己电脑上的单文件 SQLite 里,不经过任何第三方服务器(除了调用大模型解析截图本身)。 ## ✨ 核心功能 ### ① 截图秒变结构化比价 把票务发来的座位报价(截图或文本)扔进上传框,Qwen-VL 自动解析出「日期/分区/排/张数/票面/售价/备注」,直接入库。识别错了?点缩略图进纠错页手改——**涉及钱的数据永远人工可控**。 上传报价:截图/文本解析入库,按表分组 ### ② 找位置:分层偏好 + 预算 → 性价比最优 「最想坐 B2,其次 A1,再不行 C1,预算两万」——把偏好按优先级扔进许愿池,一键排出最优解。每一行都标注**加价倍数**(售价 ÷ 官方原价×汇率),谁在坑你一目了然。 ### ③ 价格追踪:每张表一根线,永不误报 不同票务更新频率天差地别。本工具的核心语义:**一张表的报价在被它自己的新报价覆盖之前一直有效**(carry-forward)。粉表 5 天前报的 ¥12500 只要没更新,就依然是「当前可买最低」,不会被蓝表今天更新的 ¥14000 顶掉——每张表一根阶梯线,加粗虚线是「当前可买最低」包络线,还标注每张表**几天没更新了**。 价格追踪:每表一根阶梯线 + 最低价包络线 + 过期天数标注 ### ④ 报价截图反向校对海报原价 AI 读海报座位图定原价难免出错(尤其外圈看台的颜色)。但黄牛报价表里通常也写了原价、而且表格解析很准——所以系统会**自动比对两边**,对不上的区给出「N 张报价截图都说原价是 X」的采纳建议,点一下就修正,依据可点开溯源。 概览:票价种类 + 报价截图校对建议 ### ⑤ 手机也能用 配合 Cloudflare Tunnel(免费、不要求有域名),笔记本当服务器,手机随时打开看价(带口令网关)。详见 [deploy/README.md](deploy/README.md)。
手机端价格追踪
## 🚀 快速开始(三分钟) **前置要求:Node.js ≥ 24**(用了 Node 内置的 `node:sqlite`,免原生编译、零数据库配置——这也是为什么版本卡得比较新)。 git clone https://github.com/<你的用户名>/ticket-agent.git cd ticket-agent npm install cp .env.example .env # 见下方「配置 API Key」 npm run dev # 后端 8788 + 前端 5174 # 打开 http://localhost:5174 ### 先玩玩再说(不需要 API Key) npm run demo # 造一场完全虚构的演示演唱会(含报价、追踪、校对建议) npm run demo:clean # 玩完删掉 刷新页面选中「STARLIT(演示数据)」,五个页面立刻都有内容可看。 ### 配置 API Key(解析截图需要) 1. 注册/登录 [阿里云百炼(Model Studio)](https://bailian.console.aliyun.com/),新用户有免费额度 2. 控制台创建 API Key(`sk-` 开头) 3. 填进 `.env` 的 `BAILIAN_API_KEY`,重启 ### 环境变量(`.env`) | 变量 | 说明 | |---|---| | `BAILIAN_API_KEY` | 百炼 API Key(解析截图/海报需要;只留服务端,永不下发浏览器) | | `BAILIAN_BASE_URL` | 默认 `https://dashscope.aliyuncs.com/compatible-mode/v1` | | `PARSE_MODEL` / `POSTER_MODEL` | 解析模型,默认 `bailian/qwen-vl-max` / `bailian/qwen3-vl-plus` | | `PORT` | 后端端口,默认 8788 | | `APP_PASSCODE` | 访问口令。本机自用可留空;**要开隧道给手机用必须设置** | ## 🧭 使用流程 flowchart LR A["📄 官方海报"] -->|Qwen-VL 读图例| B["各区原价基准"] C["📷 黄牛报价截图/文本"] -->|Qwen-VL 解析| D["结构化座位报价"] D -->|归一化 + sanity 检查| E[("SQLite 单文件
快照式只增不改")] B --> E E --> F["🏆 找位置
偏好+预算 → 性价比排序"] E --> G["📈 价格追踪
每表一线 + 最低价包络"] E --> H["📋 原价校对
报价截图反查海报错误"] F & G & H -->|每个数字| I["🔍 一键溯源回原图/原文"] 1. **建演唱会**:选票面币种(自动带默认汇率);顺手传官方购票海报自动读各区原价(确认页可批量修正)——**海报不是必须的**,传报价时会按 ≥2 条一致的原价自动建「待核对」基准 2. **传报价**:黄牛每次发来新表就扔进来,记得选对「报价日期」——价格时间序列靠它 3. **找位置**:设偏好和预算,看排序结果;心仪的位置点 ★ 关注 4. **追踪**:关注的位置自动长出价格曲线;跳水/售罄一眼看到 5. **下手前**:点任何数字溯源回原始截图,核对无误再转账 ## ❓ FAQ **我的数据存在哪?** 全部在本地 `data/ticket.db`(单文件 SQLite)+ `data/uploads/`(原图)。删掉整个 `data/` 目录 = 抹掉一切。 **为什么必须 Node 24?能不能用 better-sqlite3 兼容老版本?** 项目刻意用 Node 24 内置的 `node:sqlite`:零依赖、零原生编译(better-sqlite3 需要较新的 C++ 工具链,在很多机器上装不上)。装个新 Node 比装编译工具链容易得多。 **AI 解析错了怎么办?** 所有解析结果都可以在纠错页手改(点上传缩略图进入)。海报原价还有「报价截图校对」自动兜底。设计原则:**涉钱数据,AI 只做初稿,人工永远可以改**。 **报价历史会被覆盖吗?** 不会。`listings` 表只增不改——每次上传都是一份新快照,这是价格时间序列的地基。 **支持哪些币种?** 黄牛售价一律按人民币记;官方票面按当地币种记,建场时选一次、自动带默认汇率(可改),加价倍数自动换算。目前内置人民币 CNY、泰铢 THB、韩元 KRW、港币 HKD、澳门币 MOP、日元 JPY、美元 USD、欧元 EUR,其余可选「其他」手填汇率。 **一定要先传海报才有原价基准吗?** 不用。海报判色本就易错,而黄牛报价截图通常自带原价、表格解析很准——所以传报价时,凡是**同一个区有 ≥2 条报价原价一致**、且原价基准里还没有这个区,系统会**自动建立原价基准并标「待核对」**,你在概览页一眼确认(或改价/删除)即可,加价倍数从此不必等海报。孤证(仅 1 条)不自动写,仍留给「报价截图校对」的存疑建议。之后再传海报确认,则以海报为权威覆盖。 ## 🛠 技术栈 - **前端**:Vite + React 18,图表 recharts - **后端**:Express(ESM `.mjs`),Node ≥ 24 - **数据库**:Node 内置 `node:sqlite`,单文件,零配置 - **AI 解析**:百炼 Qwen-VL,OpenAI 兼容接口转发(`server/llm.mjs`,Key 只留服务端) - **测试**:vitest(后端纯函数 + 前端组件 170+ 用例)——`npm test` ## 🗺 路线图 - [ ] 波动规律(功能③):攒够跨团历史后给「现在买 / 再等等」建议 - [ ] 用户账号 + 多用户数据隔离(当前单库单用户) - [ ] 部署为公开网站(Postgres + 对象存储原图) ## 📄 License [MIT](LICENSE)
标签:GNU通用公共许可证, Node.js, OCR识别, Qwen-VL, SQLite, 价格追踪, 本地部署, 票务管理, 自定义脚本