Table of Contents
使用 Go 复刻 LinguaCafe:架构与二次开发选型
调研日期:2026-09-10。状态:可供评审的技术建议,尚未进入编码实现。原项目证据、提交基线与需求 ID 见 需求提取。
1. 结论与适用前提
Go 适合承担账号权限、内容库、词典查询、学习状态、SRS、统计、任务调度和管理 API。推荐 Go 业务后端 + Vue 3 学习前端 + 管理区,先保留独立的 Python NLP 服务。
若重点是快速二次开发,首选 gin-vue-admin 作为管理与通用基础能力的底座,学习业务按模块开发,用户端阅读器独立设计。若主要供个人自托管,使用 Gin + Vue 3 自建轻量管理区会更精简。
本文默认团队熟悉或愿意采用 Go/Vue,希望先交付自托管可用产品,并保留多用户能力;没有假定要做商业 SaaS、组织多租户或收费系统。Go 指主要业务后端,不意味着浏览器界面也必须用 Go 编写。
首版不建议将全部服务拆成微服务,也不建议为“纯 Go”一次性重写全部语言模型能力。是否严格禁止 Python、首发学习语言和是否需要旧数据迁移,是后续影响工期最大的决策点;不妨碍本次形成需求和方案。
2. 原项目技术结构与迁移含义
本次读取的源代码依赖声明如下,属于原仓库状态,不是推荐的新项目版本:
| 层次 | 原项目证据 | Go 版处理 |
|---|---|---|
| Web 业务 | PHP ^8.2、Laravel ^11.9;Horizon、Reverb、Sanctum 依赖 |
用 Go 重写应用服务、认证、任务与事件通知 |
| 前端 | Vue ^2.6.12、Vuetify ^2.6.12、Vuex、Vue Router 3、Laravel Mix |
建议 Vue 3 + TypeScript + Vite;Vue 2 组件不能直接当 Vue 3 组件复用 |
| 数据 | MySQL、Redis、用户文件目录 | 优先沿用 MySQL 以降低首期迁移与后台集成成本 |
| 文本处理 | Python + Bottle、spaCy、EbookLib、字幕和网页解析依赖 | 保留语言处理边界,逐步替换导入工具或 NLP 实现 |
| 阅读业务 | 词语状态、短语索引、上下文例句、复习交互 | 是核心领域逻辑,需要定制,后台生成器不能直接覆盖 |
来源:composer.json、package.json、PythonDockerfile、tokenizer.py。
迁移不是把 PHP 文件逐个改写成 Go。原版大部分业务端点位于 routes/web.php,带 Web/Session 语义;只有检查 routes/api.php 会遗漏主要功能。新 API 可以重新设计,但应按行为验收,不能依据旧路由名称机械推断业务。
3. 需要用户端和管理端吗?
需要两类功能入口,初期不需要两套后端或两个独立部署系统。 原版已经有 Admin 页面、服务端管理员校验以及 Users、Languages、Dictionaries、Fonts、API、Reviews 等管理菜单。
| 维度 | 用户端 | 管理端 |
|---|---|---|
| 目的 | 阅读与个人学习 | 维护实例资源和配置 |
| 主要页面 | 学习首页、书库、导入、阅读器、词汇库、复习、目标/日历、个人设置 | 用户、语言模型、词典、字体、API、复习策略、任务与备份 |
| 数据边界 | 本人书籍、词汇、进度、个人释义 | 全局资源与系统设置;个人内容访问须另行明确授权 |
| 界面特点 | 阅读舒适、低干扰、键盘与触屏操作 | 表格、表单、任务进度、配置验证 |
| 可复用程度 | 阅读器和复习器大部分定制 | 账号、菜单、权限、CRUD 可复用脚手架 |
部署建议:
- 个人版:一个 Vue 项目内分
/app和/admin两种布局,共用 Go API;默认账号同时具有管理员和学习者身份。 - 多用户版:同一仓库中可拆
web/learner和web/admin两个前端构建,共用一个 Go 模块化后端。增加构建分离是工程选择,不是功能必要条件。 - 组织/SaaS 版:确有组织边界、独立发布或合规需求后,再引入租户模型和更多服务;不能将普通多用户直接称为多租户。
管理端 RBAC/Casbin 负责“能否使用某种功能”;业务层还必须校验“这本书是否属于本人”。只有菜单和 API 权限,不等于有数据所有权隔离。
推荐页面/API 前缀分别为 /app/*、/admin/*、/api/v1/*、/api/admin/v1/*。页面路由与 API 路由分开,统一错误结构、请求 ID、分页和认证语义。
4. 三种落地路线
| 路线 | 组合 | 优点 | 代价 | 适用性 |
|---|---|---|---|---|
| A:管理脚手架二开,推荐 | gin-vue-admin + 独立学习领域模块/页面 + NLP 服务 | 通用管理功能起步快,Go/Vue 生态一致 | 要约束脚手架侵入业务,阅读器仍需自研 | 团队希望较快交付用户端和管理端 |
| B:精简产品工程 | Gin + Vue 3 + GORM + 自建轻量管理区 + NLP 服务 | 依赖和页面更少,学习业务结构清楚 | 认证、管理表单、任务页需自己补齐 | 个人版、自托管优先或重视长期自主维护 |
| C:全 Go 且逐语言实现 | Gin/GoFrame + Vue 3 + Go 文本处理适配器 | 可减少 Python 运行环境 | 分词、lemma、读音、模型覆盖和效果验证成本最高 | 明确要求纯 Go,并接受首版语言收缩 |
综合建议选择 A;如果实际上只给本人使用,选择 B。路线 C 技术上可以推进,但不能承诺换一种语言实现后仍立即具备原版 27 种语言的同等体验。
5. 流行框架与二次开发底座比较
这里区分 HTTP 框架、工程框架和完整管理脚手架。选型依据是任务匹配度,不是声称某项目在所有场景最好。已核验官方仓库/文档;没有依据星数给出排名,也没有执行候选框架的编译和性能对比。
5.1 Go 后端候选
| 候选 | 类型/已核验能力 | 本项目判断 |
|---|---|---|
| Gin | HTTP 路由、中间件、绑定/校验与响应处理 | 首选。能与推荐管理底座保持一致;ORM、队列和领域模型仍需组合 |
| GoFrame | 集成式 Go 工程框架及配套工具 | 想要较统一开发规范时可选;采用后不必再叠另一套 HTTP/ORM 约定 |
| go-zero | 面向云原生服务的框架与代码生成工具 | 团队已熟悉时可用;本项目首期没有足够理由为它主动拆微服务 |
Gin 足以处理这里的 HTTP 需求。真正需要优化的是语言模型加载、字典检索、章节文本结构和前端渲染;仅比较框架 QPS 对选型帮助有限。
5.2 管理底座候选
| 候选 | 能直接借用什么 | 需要核实/自己开发什么 | 建议 |
|---|---|---|---|
| gin-vue-admin | Gin/Vue 管理工程、JWT/Casbin、用户角色菜单、文件与代码生成等基础能力 | 学习者身份适配、数据所有权、阅读器、SRS、语言词典、分词任务;确认开源与商业功能边界 | 快速二开首选 |
| go-admin-team/go-admin | Gin 系管理脚手架、RBAC、生成器及项目声明的多租户等能力 | 主仓库与具体前端仓库/分支版本组合;租户实现对学习数据的适配 | 团队已用此体系时作为备选 |
gin-vue-admin 官方项目说明及代码目录指向 Vue 3/Vite/Gin 的组合,能够减少管理端通用开发。本文不会把它宣传为现成语言学习平台。go-admin 存在不同前端方案,不能假定所有历史版本都是同一 Vue 3 技术栈。
二开方法:固定一个验证过的上游提交;保留上游来源;仅生成资源维护等标准 CRUD;把 library、reader、vocabulary、review 放入独立业务模块,通过接口使用身份和基础设施。避免业务服务依赖后台菜单表、HTTP Context 或全局用户对象。
普通用户与后台账号可以基于统一身份体系加角色/资料表实现,首期不必维护两套密码与登录体系。权限模型要明确管理员是否同时可以学习,避免后台角色字段成为学习数据主键。
5.3 推荐技术栈
| 部分 | 推荐 | 原因/限制 |
|---|---|---|
| 业务 API | Go + Gin | 与管理底座一致;领域逻辑独立于 Gin |
| 管理页面 | gin-vue-admin 开源底座 | 缩短通用管理开发;按锁定版本核实能力 |
| 用户页面 | Vue 3 + TypeScript + Vite | 适合阅读器这种状态丰富的交互界面 |
| 通用组件 | Element Plus | Vue 3 组件库,适合表单和管理;阅读正文/划词层自行开发 |
| 持久化 | MySQL + GORM | 与原版和管理底座衔接较省事;复杂检索允许显式 SQL,迁移用版本化脚本 |
| 异步任务 | Redis + Asynq | 处理导入、分词、词典导入与备份;任务可重试,业务必须幂等 |
| NLP | 独立 Python/spaCy 服务 | 保留已验证语言能力,Go 通过内部接口调用;必须固定模型和依赖版本 |
| 任务进度 | 先轮询,确有需要再 SSE | 导入主要是单向状态展示,不必一开始复制完整 WebSocket 栈 |
| 文件 | 本地持久化目录 + 存储接口 | 符合自托管;未来需要时再接对象存储 |
| 部署 | Docker Compose | Go API、Worker、NLP、数据库和 Redis 可独立重启 |
Asynq 文档声明至少一次执行语义,并提示 v0 系列 API 可能变化、部分脚本与 Redis Cluster 有兼容限制;首期使用常规 Redis 部署并锁定依赖版本。重复执行控制由业务记录、唯一键和事务共同保障,不能只靠队列的去重选项。
此处不指定猜测的“最新版本”。开工时按候选项目 go.mod、package.json、锁文件与 CI 要求选兼容组合,不可仅依据 README 中可能滞后的最低版本号。数据库首期只选一种;若团队已有 PostgreSQL 标准,可以在验证后台底座兼容后替换。
6. 推荐架构与模块边界
flowchart TD
L[Vue 学习端] --> G[Go API]
A[Vue 管理端] --> G
G --> B[账号与学习业务模块]
B --> D[(MySQL)]
B --> F[文件存储]
B --> Q[(Redis 任务队列)]
Q --> W[Go Worker]
W --> N[内部 NLP 服务]
W --> D
W --> F
G --> T[词典与外部翻译适配器]
API 与 Worker 可以来自同一个 Go 代码库、使用相同领域服务,但运行在不同进程。NLP 单独运行是为了依赖、内存和 CPU 隔离,不需要连带拆分账号、书库和词汇为微服务。
| 模块 | 责任 | 主要边界 |
|---|---|---|
| identity | 身份、角色、会话、所有权校验 | 不存储词汇学习规则 |
| library | 书籍、章节、导入源与阅读位置 | 不直接调用某个 Python 包 |
| ingestion | 文件校验、正文提取、分章、任务 | 通过 Parser/Tokenizer 接口处理文本 |
| lexicon | 词典、词条、读音、来源、外部翻译 | 与个人学习状态分离 |
| vocabulary | 用户词语/短语、释义、例句、状态 | 所有读写含用户与语言边界 |
| review | 复习查询、状态转换、调度、事件记录 | 服务端决定下一状态,前端提交作答结果 |
| progress | 阅读、标记、复习事件与统计 | 基于幂等事件聚合,避免重复累计 |
| administration | 全局配置、语言、字体、任务和备份 | 调用已有服务,不复制一套业务规则 |
建议目录仅作规划:cmd/api、cmd/worker、internal/{上述模块}、migrations、web/learner、web/admin、services/nlp、deploy。路线 B 可以把两个 Web 目录合并;路线 A 则可适应上游 server/web 目录,模块职责比目录命名更重要。
7. 数据模型建议
以下是新设计建议,不表示与原版数据库逐表相同。
| 实体 | 关键数据与约束 |
|---|---|
| users / roles | 用户、角色、时区、选中语言;学习者角色与管理员角色可组合 |
| languages / language_models | 语言代码、能力标记、模型版本、安装状态 |
| books / chapters | owner_user_id、language_id、标题、原文、内容版本、处理状态 |
| chapter_tokens | chapter_id、内容版本、顺序、原词、lemma、句子位置、字符边界;存结构化块或表需基准验证 |
| user_terms | user_id、language_id、类型、标准化键、显示文本、释义、状态、等级、到期时间、重学标记 |
| term_occurrences | 用户词语/短语与章节的出现位置,用于按书复习与短语高亮 |
| dictionaries / dictionary_entries | 语言、来源、许可、版本、原词/lemma、释义和读音;与 user_terms 分开 |
| example_sentences | 用户、词语、例句文本、来源章节及版本;章节删除时保留必要快照 |
| review_events | 用户、词条、作答、前后状态、算法版本、事件唯一键 |
| reading_events / daily_stats / goals | 按用户、语言、本地日期记录事件与聚合统计 |
| jobs / import_sources / files | 所有者、来源摘要、状态、错误、输出版本、文件引用 |
| settings / provider_configs | 全局、用户、设备配置分层;凭证不返回普通配置接口 |
词条的唯一键至少包含用户、语言、词条类型和规范化词语键。原词与 lemma 不应随意合并为同一学习项;需要明确是按词形学习还是按词元学习,并为迁移保留映射。
对英语大小写、德语名词大小写、土耳其语大小写、全角半角、组合重音、中文繁简体不能一律粗暴 lowercase。原文始终保留;检索规范化规则应按语言版本化。
复习查询索引建议包含 (user_id, language_id, state, next_review_at);词典查询索引包含 (language_id, normalized_headword);章节访问包含 (owner_user_id, book_id, ordinal)。具体索引以真实查询计划验证,不能靠 ORM 默认索引解决所有检索问题。
8. Go 复刻的主要难点和处理方案
8.1 多语言处理与纯 Go 的边界
空白切分能做英语粗分词,但不是 lemma、词性和句法处理,也不足以覆盖中文、日语、泰语。原版已有 Python 调用边界,保留这个边界比先移植全部 NLP 更实际。
建议内部 Tokenizer 接口输入语言、原文、处理模式和内容版本,输出 token 列表、原词、lemma、词性/性别、读音、句子索引、字符边界、模型版本与告警。不同语言允许部分字段缺失,UI 按能力呈现,不伪造分析结果。spaCy 官方语言特性说明也明确不同注释能力依赖相应流水线和模型。
边界单位必须固定:Go 字节偏移、Python 字符索引、JavaScript UTF-16 索引不同。建议跨服务使用 token ID 与约定的 Unicode 标量位置,在浏览器建立映射;保存未改动原文,覆盖 emoji、组合字符及混合语言测试。不能直接拿 Go 字节下标去做 JS slice。
若最终要求纯 Go,先完成英语基础规则与词典查词,再对每种目标语言建立同一组真实语料对比基准,逐个替换适配器。Go 可编译成二进制,不代表语言模型、数据库和字典也能免安装或没有内存成本。
8.2 阅读器与短语索引
阅读器是最大的前端定制项:点击词语、连续划选、重叠短语、键盘操作、移动端底部面板、读音、状态同步和长文本渲染都需要产品级处理。
章节正文与个人状态分开缓存;状态变更只更新当前可见 token 的呈现。先按章节和段落限制渲染量,实测有需要再虚拟化;盲目虚拟化可能破坏原生选择和可访问性。
新增短语时不要同步扫描所有文本后才返回。先提交短语,更新当前章节,再以后台任务维护该用户该语言的出现索引;索引任务携带短语/内容版本,过期结果不能覆盖新内容。需规定重叠短语的显示和点击优先级。
8.3 SRS 要以行为兼容为起点
首版实现原版等级/重学思路,并固定时钟、随机顺序和间隔配置建立对照样例。客户端只提交“本次答对/答错”,服务端在事务中验证当前状态、计算调度并写事件。不要把原版前端算出的任意 stage 更新原样暴露为可信 API。
FSRS 可以作为独立增强,但会改变复习行为。若添加,要有算法版本、迁移策略和明确选择,不将其标注为忠实复刻要求。练习模式不更新学习调度,是否计入练习统计应独立定义。
8.4 导入、词典与外部服务
导入状态建议为 queued → extracting → tokenizing → indexing → ready,失败进入 failed 并保留失败阶段。以源文件摘要、用户、语言、处理选项、内容版本建立幂等记录;数据库持久化任务状态,再通过 outbox/补偿派发避免事务成功但任务未入队。
词典支持分批导入、错误行报告、暂存版本和成功后切换。普通查词与悬停精确查询可以分别设计,缓存键必须包含语言、词典版本、查询模式;用户自定义释义不能进入跨用户共享缓存。
网页和外部字幕提取失败要有手动文本/字幕上传回退。在线翻译需要超时、配额、提供方状态提示,返回来源;不能让外部服务失败阻断阅读。
8.5 多用户与 Anki
原版手册说明 Anki 由服务器连接,这在多人各用自己桌面时不成立。首版先支持个人 CSV 导出;后续单独设计用户本地桥接或经用户配置的 AnkiConnect 连接,验证浏览器跨域、HTTPS/HTTP 和局域网访问限制。不能让所有账号共用管理员桌面的 Anki 连接。
浏览器设置键加入实例标识和用户 ID;服务端保存用户偏好,设备级字号等允许本地覆盖。新增加用户删除时,应有任务化清理、关联数据策略和最后管理员保护。
9. 接口草案与工程质量
下表是 Go 新接口草案,不是原版路由复制:
| 行为 | 建议接口 | 核心校验 |
|---|---|---|
| 导入材料 | POST /api/v1/imports |
当前用户、语言、格式和大小;返回 job_id |
| 查看任务 | GET /api/v1/jobs/{id} |
任务所有权,避免泄露其他用户材料 |
| 打开章节 | GET /api/v1/chapters/{id}/reader |
所有权、处理状态、内容版本 |
| 查词 | POST /api/v1/dictionary/lookups |
语言、查询模式、范围与提供方权限 |
| 保存词语 | PUT /api/v1/terms/{id} |
所有权、版本冲突、合法状态 |
| 保存短语 | POST /api/v1/phrases |
token 范围、章节版本、短语一致性 |
| 完成阅读 | POST /api/v1/chapters/{id}/completions |
幂等键、计数语义、批量置已知开关 |
| 获取复习 | GET /api/v1/reviews |
用户/语言/书/章节一致性 |
| 提交作答 | POST /api/v1/review-events |
事件唯一键、当前词条版本、服务端调度 |
| 导入词典 | POST /api/admin/v1/dictionaries/imports |
管理权限、文件与资源配额 |
公开部署所需的具体防护:HTML/EPUB 正文清理防止脚本注入;URL 导入限制重定向后的地址与内网访问;模型/字典下载只接收受控资源;上传限制解压大小和路径;Cookie 会话配合 CSRF,或按所选 JWT 体系统一续期与撤销策略。不要同时拼接两套互不一致的认证方案。
验证优先覆盖领域规则、跨用户访问、任务重试、Unicode 文本定位、复习重复提交和备份恢复。浏览器自动化至少覆盖“导入—阅读—保存—复习”闭环,以及触屏选择和管理员直接 API 访问。此报告没有运行这些测试,属于后续验收计划。
10. 开发顺序与工作量判断
估算前提:两名熟悉 Go/Vue 的工程师、现成测试材料、复用管理底座、保留 Python NLP、不同时建设商业 SaaS 和原生 App。下列是规划量级,不是承诺排期,也不是已有实现进度。
| 阶段 | 对应需求 | 交付结果 | 粗估 |
|---|---|---|---|
| M0 风险验证 | U08/U10/U14/U17 | 英语/目标语言分词样例、词典查询、原版状态映射与阅读交互验证 | 1~2 周 |
| M1 核心闭环 | 主要 P0、A01~A04/A07/A09/A10 | 账号隔离、文本导入、阅读器、词语短语、基础复习、统计、最小管理与备份 | 5~8 周 |
| M2 主要功能补齐 | P1 | EPUB/网页/字幕文件、CSV、练习、主题/PWA、字体、在线词典 | 3~5 周 |
| M3 外部/语言专项 | P2 | Anki/Jellyfin/YouTube、日中读音和汉字专项、更多语言验收 | 3~6 周 |
| M4 稳定化 | N01~N08、迁移需求 | 压测、断点恢复、升级/恢复演练和数据迁移工具 | 2~4 周 |
按阶段顺序粗估约 14~25 周达到较广的功能覆盖;首个核心可用版约 6~10 周。27 种语言逐一达到质量承诺、严格纯 Go、旧实例完整迁移或复杂移动适配都可能显著增加工作量。若 M0 暴露 NLP 或内容格式问题,应重估后续阶段。
对用户最有价值的第一个里程碑是可实际使用的阅读学习闭环;先堆满后台菜单而没有可靠阅读器,无法验证产品是否成立。
11. 原数据迁移与授权边界
迁移建议分两层:先做原版 CSV 词汇兼容,再考虑完整迁移工具。完整迁移需盘点用户、语言、书籍/章节、原文、token、个人释义、短语、例句、stage、next_review、设置和文件,建立旧 ID 到新 ID 映射。先只读导出、dry-run 报告和抽样核对,验证通过再导入新实例;保留旧实例可回退。
不能把旧 MySQL 数据库直接接到重新设计的 Go 表结构上。重新分词可能改变 token 边界,影响短语位置、例句和阅读位置;因此需要保留源文本版本与迁移日志,不能只有“重新导入书籍”。
原项目根 LICENSE 是 GPL-3.0 文本;composer.json 中 Laravel 脚手架的 MIT 字段不能代替项目级许可证。直接复制/改写原代码或复用前端时,应按适用许可处理修改、分发、声明和对应源码要求;更换实现语言本身不能排除衍生关系。GPL 并不等于禁止商业使用,具体发布方式应结合完整许可判断。
若希望采用独立许可,应围绕公开功能规格独立实现,避免复制受保护代码/素材,并在分发前核查具体实现与依赖。字典数据、字形、语言模型和 Python 依赖各有自己的许可:例如上游 README 对 JMDict、CC-CEDICT、EbookLib 等分别列出归属,不可用项目代码许可证概括全部资源。
gin-vue-admin 当前官方仓库标示 Apache-2.0,并区分开源功能和商业授权版。引用它不会自动改变被复用 LinguaCafe 代码的许可义务。以上是实现时需要处理的资源边界,不是针对特定商业发行方式的法律结论。
12. 可直接采用的起步决策
- Go + Gin 作为业务后端;选择 gin-vue-admin 开源底座,固定验证过的提交与依赖。
- 用户区与管理区共用后端,按角色和数据所有权授权;阅读器独立开发。
- 使用 Vue 3/TypeScript,通用表单采用 Element Plus;先做好桌面与手机浏览器。
- MySQL + GORM 管理业务数据;Redis + Asynq 处理导入/分词任务;版本化数据库迁移。
- 第一阶段保留 Python NLP,通过接口隔离;首发语言按 M0 验证结果确定。
- 先完成需求文档 P0 的闭环,再补 EPUB、完整 CSV、外部翻译和专项语言功能。
- 多用户隔离、幂等、文本位置正确性和备份恢复从第一阶段纳入验收。
若改为纯个人使用,减少管理底座依赖即可;若强制所有后端组件纯 Go,需要先缩小语言范围并重估 NLP 工作,而不是只更换 Web 框架。