2
Go-Architecture-Analysis
ila edited this page 2026-09-10 14:27:37 +08:00
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

使用 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. 可直接采用的起步决策

  1. Go + Gin 作为业务后端;选择 gin-vue-admin 开源底座,固定验证过的提交与依赖。
  2. 用户区与管理区共用后端,按角色和数据所有权授权;阅读器独立开发。
  3. 使用 Vue 3/TypeScript,通用表单采用 Element Plus;先做好桌面与手机浏览器。
  4. MySQL + GORM 管理业务数据;Redis + Asynq 处理导入/分词任务;版本化数据库迁移。
  5. 第一阶段保留 Python NLP,通过接口隔离;首发语言按 M0 验证结果确定。
  6. 先完成需求文档 P0 的闭环,再补 EPUB、完整 CSV、外部翻译和专项语言功能。
  7. 多用户隔离、幂等、文本位置正确性和备份恢复从第一阶段纳入验收。

若改为纯个人使用,减少管理底座依赖即可;若强制所有后端组件纯 Go,需要先缩小语言范围并重估 NLP 工作,而不是只更换 Web 框架。