Files
JuYou/文档/项目架构文档.md
2026-08-25 17:59:42 +08:00

32 KiB
Raw Permalink Blame History

JuYouAI 项目架构文档

1. 架构概览

项目采用“双前端、单 Go 服务进程”的结构:

  • WEB:面向普通用户的创作端。
  • ADMIN:面向管理员的运营管理端。
  • APIGo 后端,同时承载 HTTP API、静态文件托管、异步任务 Worker 和定时任务。
  • PostgreSQL:保存用户、项目、任务、积分、渠道和媒体元数据,是业务状态的主要数据源。
  • Redis:提供 Asynq 队列和运行时缓存,不作为业务任务最终状态的数据源。
  • 腾讯云 COS:保存图片、音频、视频和任务结果等二进制对象。
  • 第三方渠道:由 ADMIN 动态配置基础网址和 API Key,后端统一调用。
flowchart LR
    User["用户浏览器"] --> Nginx["Nginx"]
    AdminUser["管理员浏览器"] --> Nginx
    Nginx -->|"/"| WebStatic["WEB 静态文件"]
    Nginx -->|"/admin/"| AdminStatic["ADMIN 静态文件"]
    Nginx -->|"/api/web/*"| API["Go API 进程"]
    Nginx -->|"/api/admin/*"| API
    API --> PostgreSQL["PostgreSQL"]
    API --> Redis["Redis / Asynq"]
    API --> COS["腾讯云 COS"]
    API --> Channel["第三方渠道接口"]
    Redis --> Worker["同一 Go 进程内的 Worker"]
    Worker --> PostgreSQL
    Worker --> COS
    Worker --> Channel
    Worker --> LocalMedia["FFmpeg / Python 语音识别"]

生产环境由一个名为 juyou_ai 的 systemd 服务启动 Go 二进制,进程内部并行运行 HTTP Server 和 Asynq Worker。

2. 根目录结构

JuYouAI/
├─ WEB/                    用户端 Vue 应用
├─ ADMIN/                  管理端 Vue 应用
├─ API/                    Go API、Worker、迁移和部署文件
├─ 文档/                   架构、部署和业务说明
├─ docker-compose.yml      Windows 本地 PostgreSQL、Redis
├─ start_api.bat           Windows 本地 API 启动脚本
└─ vite-port.ts            两个前端共用的开发端口选择逻辑

三个应用相互独立安装依赖,但前端构建结果会进入 API 目录:

WEB build   → API/static/web/
ADMIN build → API/static/admin/
Go build    → API/bin/jcf-api

3. 技术栈

3.1 用户端和管理端

类别 技术
框架 Vue 3
语言 TypeScript
构建 Vite 5
路由 Vue Router 4
状态 Pinia
请求 Axios
组件库 Element Plus
图标 Element Plus IconsWEB 通过 src/icons.ts 提供语义映射
图表 ECharts,仅 WEB 使用
样式 SCSS、统一变量文件和全局样式

3.2 后端

类别 技术
语言 Go 1.26
HTTP 框架 Gin
ORM GORM
数据库 PostgreSQL 16
队列 Asynq
队列存储 Redis 7
对象存储 AWS SDK v2,通过 S3 协议访问腾讯云 COS
身份认证 JWT、随机 Refresh Token
密码哈希 Argon2id
敏感配置加密 AES-256-GCM
本地媒体处理 FFmpeg、FFprobe、Python

4. 前端总体架构

WEBADMIN 都遵循相同的基础分层:

main.ts
  ├─ 注册 Pinia
  ├─ 注册 Vue Router
  ├─ 注册 Element Plus 中文语言包
  └─ 加载全局样式

views/       路由级页面,负责编排业务页面
layouts/     页面整体框架、侧栏和内容区
components/  可复用展示和交互组件
composables/ 跨组件复用的组合式逻辑
features/    按业务功能聚合的前端实现(按需使用)
api/         Axios 实例及业务接口封装
stores/      登录态、提示消息和界面状态
utils/       时间、下载、媒体、计费展示等纯工具
assets/      图片、统一样式变量和全局样式
icons.ts     WEB 语义图标到 Element Plus Icons 的统一映射

两个前端通过 Vite 动态导入路由页面,降低首次加载体积。API 请求均使用相对地址,开发环境由 Vite 代理,生产环境由 Nginx 代理,因此前端不保存后端服务器地址和第三方密钥。

4.1 样式组织

两个前端分别维护:

src/assets/styles/variables.scss
src/assets/styles/main.scss
  • variables.scss 定义颜色、边框、圆角、间距等统一语义变量。
  • main.scss 放置全局重置、公共基础样式和组件库覆盖。
  • 页面或组件自身样式放在对应 .vue 的 scoped style 或同名样式文件中。
  • WEB 业务页面和组件的颜色均通过 variables.scss 中的语义令牌引用;ECharts 等 Canvas 场景先从 CSS 令牌读取实际色值。
  • WEB 当前不使用渐变色,也不在业务组件中直接散落十六进制或 rgb/rgba 色值。
  • 复杂组件按职责拆分样式。例如 AssetPanel 依次加载核心布局、媒体状态、预览覆盖和全局对话框主题文件。
  • 响应式布局主要通过统一断点下的媒体查询实现。

5. WEB 用户端

5.1 入口和地址

项目
入口 WEB/src/main.ts
路由 WEB/src/router/index.ts
API 前缀 /api/web
Vite base /
构建输出 API/static/web
开发端口 127.0.0.1:5501 开始选择可用端口

5.2 路由和业务页面

前端路由 页面 主要职责
/login LoginView.vue 用户登录
/drama-projects RedrawProjectsView.vue 短剧创作项目列表
/drama-projects/:projectId DramaProjectView.vue 短剧项目和剧集管理
/drama-projects/:projectId/episodes/:episodeId DramaWorkbenchView.vue 短剧分镜工作台
/redraw-projects RedrawProjectsView.vue 剧本反推项目列表
/redraw-projects/:projectId RedrawProjectView.vue 反推项目详情
/redraw-projects/:projectId/episodes/:episodeId RedrawWorkbenchView.vue 视频分析、字幕、反推与生成工作台
/script-analysis ScriptAnalysisView.vue 剧本分析列表
/script-analysis/:scriptId ScriptAnalysisWorkbenchView.vue 剧本分析处理页
/account AccountView.vue 个人资料、积分和消费记录

RedrawProjectsView.vue 通过路由元信息区分短剧创作和剧本反推列表,复用同一套项目列表逻辑。

5.3 主要组件

WEB/src/components/creative/ 是创作工作台的公共组件区,主要包含:

  • 项目创建和编辑对话框;
  • 素材面板、素材提示词编辑器;
  • 模型和提示词配置对话框;
  • 分镜时间线、任务状态和结果历史;
  • 视频播放器、视频对比和加载状态;
  • 剧本导入、剧本分析结果;
  • 反推来源、文本、剧本和素材面板。

其中 AssetPanel.vue 的样式按职责拆分为:

AssetPanel.core.scss     面板主体、资产卡片和编辑器基础布局
AssetPanel.media.css     资产操作、历史记录和分镜媒体状态
AssetPanel.preview.css   预览尺寸、缩放入口和播放器覆盖
AssetPanel.dialog.css    非 scoped 的预览对话框全局主题

这些文件保持固定加载顺序,同名选择器按该顺序形成稳定的覆盖关系。WEB 图标统一从 @/icons 语义映射或 @element-plus/icons-vue 引入,不再依赖 Lucide。

页面负责组合这些组件,公共请求和 URL 组装由 WEB/src/api/creative.ts 统一封装。

5.4 登录态和请求处理

用户端的认证数据保存在浏览器 localStorage

web_access_token
web_refresh_token
web_profile

请求流程:

  1. Axios 请求拦截器读取 web_access_token,写入 Authorization: Bearer ...
  2. 后端返回 401 时,前端使用 Refresh Token 请求 /api/web/auth/refresh
  3. 同一时间只允许一个刷新请求,其余失败请求复用该 Promise。
  4. 刷新成功后重放原请求。
  5. 刷新失败后清理本地登录态并跳转登录页。

用户端还会在创建、分析、生成、取消任务后通知积分余额刷新;发现响应中仍有活动任务时会节流同步余额。

6. ADMIN 管理端

6.1 入口和地址

项目
入口 ADMIN/src/main.ts
路由 ADMIN/src/router/index.ts
API 前缀 /api/admin
Vite base /admin/
构建输出 API/static/admin
开发端口 127.0.0.1:5500 开始选择可用端口

6.2 页面职责

前端路由 页面 主要职责
/login LoginView.vue 管理员登录
/redemption-codes RedemptionsView.vue 兑换码批次和兑换码管理
/styles StylesView.vue 项目风格管理和排序
/prompts PromptsView.vue 系统提示词、历史版本和状态管理
/channels ChannelsView.vue 第三方渠道网址、密钥、汇率和并发限制
/models ModelsView.vue 渠道下的模型配置和价格管理
/users UsersView.vue 用户创建、批量操作、状态和积分管理
/security SecurityView.vue 管理员密码和安全操作

6.3 通用管理页面结构

  • AdminLayout.vue:管理后台整体布局。
  • AdminMenu.vue:后台导航菜单。
  • MasterDetailLayout.vue:列表与详情编辑的公共布局。
  • PageHeader.vue:统一页面标题区。
  • AdminNumberInput.vue:统一数字输入行为。
  • ChannelFormFields.vue:渠道连接、密钥、汇率和并发限制表单。
  • AppIcon.vue:第三方图标库的统一封装。

渠道的完整 API Key 只在新增或主动更换时提交。查询渠道列表时,后端只返回掩码,不把完整密钥返回浏览器。

6.4 管理员认证和二次认证

管理端在 localStorage 保存:

admin_access_token
admin_refresh_token
admin_profile

Access Token 过期后的刷新机制与 WEB 类似。创建兑换码批次等敏感操作还需要调用 /api/admin/auth/reauth 完成短时二次认证,随后通过 X-Admin-Reauth-Token 提交受保护请求。

7. 后端分层

后端入口是 API/cmd/api/main.go。启动时按依赖顺序完成配置加载、数据库连接、Redis 连接、安全组件、存储组件、Service、Handler、Worker 和 HTTP Server 组装。

flowchart TD
    Route["Gin Route"] --> Middleware["认证、CORS、Trace ID、Recovery"]
    Middleware --> Handler["handlerHTTP 参数和响应"]
    Handler --> Module["modules:独立业务模块公开接口"]
    Handler --> Service["service:共享业务规则和事务"]
    Module --> Service
    Module --> DB
    Service --> Model["model:领域数据结构"]
    Service --> DB["PostgreSQL / GORM"]
    Service --> Queue["Asynq Client"]
    Handler --> Storage["COS 文件流"]
    Queue --> Worker["worker:后台任务"]
    Worker --> DB
    Worker --> Provider["provider:第三方渠道协议"]
    Worker --> Storage

7.1 后端目录职责

目录 职责
cmd/api/ 进程入口、依赖组装、启动和优雅关闭
internal/config/ 读取并校验环境变量
internal/server/ Gin、路由、中间件、静态站点托管
internal/handler/ HTTP 参数解析、上传限制、状态码和响应
internal/modules/ 按业务边界组织的独立模块及公开 Service 接口
internal/service/ 业务规则、数据库事务、任务创建和资源删除
internal/model/ GORM 模型和领域数据结构
internal/database/ PostgreSQL 连接、空库基线和兼容初始化
internal/cache/ Redis 普通客户端
internal/queue/ Asynq 客户端、服务端和任务类型
internal/worker/ 生成、媒体分析、短剧解析、剧本分析任务
internal/provider/ 第三方渠道 HTTP 协议适配
internal/storage/ COS 对象存储封装
internal/security/ 密码哈希、JWT、Refresh Token、密钥加解密
internal/billing/ 任务计费、积分预扣、结算和退款
internal/drama/ 短剧文本内容处理
internal/media/ 媒体命名等公共规则
internal/datetime/ Asia/Shanghai 时间语义
workers/ Python 本地语音识别脚本
migrations/ 正式环境增量数据库迁移
static/ WEB 和 ADMIN 构建产物

7.2 独立业务模块

后端包含两个独立业务模块目录,并在 cmd/api/main.go 完成依赖装配:

模块 目录 对外职责
管理业务 internal/modules/admin/ 模型列表与保存、文本模型计费校验、兑换码查询与批量生成、管理员操作审计
提示词业务 internal/modules/prompt/ 系统提示词与版本历史、用户提示词查询和选择、自定义提示词增删改

调用关系如下:

flowchart LR
    Main["cmd/api/main.go"] --> AdminModule["modules/admin.Service"]
    Main --> PromptModule["modules/prompt.Service"]
    AdminHandler["handler/AdminData"] --> AdminModule
    AdminHandler --> PromptModule
    CreativeHandler["handler/Creative"] --> PromptModule
    AdminModule --> DB["GORM / PostgreSQL"]
    PromptModule --> DB

模块通过构造函数接收数据库依赖,并使用明确的参数、返回值和错误类型对外提供能力。Handler 通过模块公开接口调用业务能力,模块测试位于各自目录的 service_test.go

7.3 Handler、Service、Worker 边界

Handler 负责:

  • 读取路径、Query、JSON 和 multipart 参数;
  • 验证文件体积和基础输入格式;
  • 从认证上下文取得用户或管理员;
  • 调用 Service
  • 统一输出 HTTP 状态码、错误码和 Trace ID。

当前 internal/handler/ 已不再通过 h.service.DBh.data.DB 或同类入口直接执行 GORM 查询和事务。重绘、剧集和资产媒体上传所需的目标校验、记录写入、旧媒体缓存及记录清理由 internal/service/creative_media.go 统一提供。

Service 负责:

  • 业务权限和资源归属判断;
  • 项目、剧集、素材、分镜和任务规则;
  • 数据库事务和行锁;
  • 积分预扣、结算或退款;
  • 创建持久任务并发送 Asynq 唤醒消息。

Worker 负责:

  • 从 PostgreSQL 重新读取任务和配置快照;
  • 调用第三方渠道;
  • 轮询异步结果;
  • 下载结果并写入 COS
  • 执行本地 FFmpeg、FFprobe 和 Python 处理;
  • 持久化任务状态、输出和计费结果;
  • 服务重启后恢复运行中的持久任务。

8. HTTP API 架构

8.1 API 分区

前缀 使用方 认证
/health 运维健康检查
/api/web/health WEB 健康检查
/api/web/auth/* 用户登录、刷新、退出 登录接口无 Access Token
/api/web/* 用户账户和创作业务 Web JWT
/api/admin/health ADMIN 健康检查
/api/admin/auth/* 管理员登录、刷新、退出和二次认证 按接口区分
/api/admin/* 后台资源管理 Admin JWT,敏感接口增加二次认证

8.2 通用中间件

Gin 全局中间件顺序包括:

  1. Trace ID:复用请求的 X-Request-ID,没有时生成 UUID,并写回响应头。
  2. 开发日志:仅 DEBUG=true 时启用 Gin Logger。
  3. Recovery:捕获未处理 panic。
  4. CORS:仅允许 CORS_ORIGINS 中明确配置的来源。

HTTP Server 主要超时:

配置 时间
Read Header Timeout 5 秒
Read Timeout 30 秒
Write Timeout 5 分钟
Idle Timeout 60 秒
优雅关闭等待 10 秒

长时间生成任务不会占用一个 HTTP 请求等待完成。HTTP 接口只创建任务,页面通过任务查询接口获取进度。

9. 身份认证和安全

9.1 用户和管理员隔离

用户和管理员使用不同的数据表、Token Claims、接口前缀和前端存储键:

类型 账号表 Refresh Token 表 Access Token 类型
用户 web_users web_refresh_tokens web_access
管理员 admin_users admin_refresh_tokens access
  • 密码使用 Argon2id 哈希,不保存明文。
  • Access Token 使用 JWT HS256 签名。
  • Refresh Token 使用加密安全随机数生成,数据库只保存哈希。
  • 管理员二次认证令牌有效期为 5 分钟。
  • 渠道 API Key 使用 CONFIG_ENCRYPTION_KEY 进行 AES-256-GCM 加密。

9.2 请求追踪

前后端错误处理会携带或展示:

错误码
错误描述
X-Request-ID / trace_id

运维使用请求追踪 ID 对照 API 日志定位请求。第三方响应体限制长度后进入错误信息,日志不记录认证请求头和密钥。

10. 异步任务架构

10.1 任务类型

Asynq 当前注册的任务包括:

队列任务 处理器 用途
ai:dispatch-channel Generation Worker 按渠道和用户并发限制选取待提交任务
ai:submit-task Generation Worker 向第三方渠道提交生成任务
ai:poll-task Generation Worker 轮询第三方异步任务
ai:download-task Generation Worker 下载完成结果并写入 COS
media:analyze-episode Media Worker 视频探测、抽帧、语音识别和内容反推
drama:parse-episode Drama Parse Worker 解析剧集文本并形成结构化内容
script:analyze Script Analysis Worker 执行剧本分析任务

队列名称主要为 aiAsynq Worker 并发数由 AI_WORKER_CONCURRENCY 控制。

10.2 生成任务状态流

stateDiagram-v2
    [*] --> pending_submission
    pending_submission --> submitting: 调度器取得渠道槽位
    submitting --> submitted: 上游返回任务 ID
    submitting --> result_ready: 上游直接返回结果 URL
    submitting --> submit_unknown: 无法确认提交结果
    submitted --> processing: 轮询仍在处理
    processing --> result_ready: 上游完成
    result_ready --> downloading
    downloading --> succeeded: COS 持久化成功
    pending_submission --> cancelled
    submitted --> cancel_requested
    processing --> cancel_requested
    cancel_requested --> cancelled
    submitting --> failed
    submitted --> failed
    processing --> failed
    downloading --> failed

实际状态更新以 PostgreSQL generation_tasks 为准。Redis 中的 Asynq 任务只负责唤醒处理逻辑,Redis 队列长度不代表业务任务状态。

10.3 持久任务流程

  1. WEB 发起分析或生成请求。
  2. Service 在 PostgreSQL 事务中校验用户、项目、渠道、配置和积分。
  3. 创建 generation_tasks 等持久任务记录,必要时预扣积分。
  4. 向 Redis/Asynq 写入轻量任务 ID。
  5. Worker 根据 ID 回查 PostgreSQL,完整业务快照保存在 PostgreSQL。
  6. 调度器使用数据库锁和 SKIP LOCKED 控制多 Worker 竞争,并执行渠道总并发、单用户并发限制。
  7. Worker 解密渠道密钥并提交第三方请求。
  8. 异步上游由轮询任务持续更新状态;直接结果跳过轮询。
  9. 完成后将结果下载到本地临时文件,再上传 COS。
  10. 在数据库事务中创建 generation_outputs、更新分镜或素材的活动输出并结算积分。
  11. 失败或取消时按业务规则退款、保留预扣或记录错误。

10.4 重启恢复

Go 进程启动时会执行恢复逻辑:

  • 找出 pending_submission 任务,重新唤醒渠道调度;
  • 找出 submittedprocessing 和部分 cancel_requested 任务,恢复轮询;
  • 找出 result_readydownloading 任务,恢复结果下载;
  • 把中断的剧本分析处理状态恢复到可重新消费状态;
  • 恢复短剧解析任务。

因此 PostgreSQL 中的任务记录是恢复依据。Redis 清理或状态变化不改变 PostgreSQL 中持久化的业务任务状态。

11. 数据库架构

11.1 数据领域

领域 主要数据表
管理员安全 admin_usersadmin_refresh_tokensadmin_audit_logs
用户账户 web_usersweb_refresh_tokens
积分和兑换 point_ledgerpoint_grantspoint_ledger_allocationspoint_packagesredemption_batchesredemption_codes
渠道和模型 channelschannel_balance_snapshotsmodelsmodel_pricesuser_model_configsproject_model_configs
提示词和风格 promptsuser_prompt_preferencesproject_styles
创作项目 creative_projectsproject_episodesproject_assetsepisode_storyboardsepisode_sources
短剧解析 drama_import_sessionsdrama_parse_batchesdrama_parse_tasksepisode_continuity_contexts
生成任务 generation_tasksgeneration_outputs
剧本分析 script_analysesscript_analysis_characters
媒体 media_assetschannel_asset_cache
其他运营 announcementspayment_configsrecharge_ordersinspiration_gallery_items

11.2 数据库初始化和迁移

数据库结构有三个相关机制:

  1. 空库基线:API/internal/database/schema.sql 通过 go:embed 编译进二进制。数据库完全没有业务表时,API 启动会在事务中执行该基线。
  2. 缺表补全:启动时只对不存在的 GORM 模型表执行 AutoMigrate,不会依赖 AutoMigrate 修改已有表的全部结构。
  3. 增量迁移:生产部署脚本按文件名执行 API/migrations/*.up.sql,成功后记录在 jcf_schema_migrations

internal/database/postgres.go 还包含旧安装兼容 DDL。数据库结构由 GORM Model、空库基线和增量迁移共同表达,部署脚本负责执行正式迁移。

11.3 数据库连接语义

  • 时区固定为 Asia/Shanghai
  • GORM 最大连接数为 20,最大空闲连接数为 5。
  • 单连接最长复用时间为 30 分钟。
  • 启动时先 Ping PostgreSQL,连接失败则整个进程退出。

12. Redis 和队列

Redis 使用两个逻辑 DB

配置 默认值 用途
REDIS_DB 0 普通 Redis 客户端和健康检查
ASYNQ_REDIS_DB 1 Asynq 队列

API 启动时会同时检查 PostgreSQL 和 Redis。任一基础依赖无法连接,服务不会继续启动。

Redis 数据用于队列和调度,PostgreSQL 保存任务真实状态、租约、上游任务 ID、错误和计费结果。

13. 媒体和对象存储

13.1 COS 存储职责

COS 保存:

  • 用户头像和上传素材;
  • 视频源文件、字幕、音频;
  • 视频抽帧和缩略图;
  • 本地识别结果;
  • 第三方原始响应;
  • 图片和视频生成结果。

PostgreSQL 的 media_assets 保存对象键、公开 URL、MIME、大小、SHA-256、显示名称和归属关系,不把大文件二进制放入数据库。

13.2 本地媒体处理

Media Worker 调用:

  • FFprobe:读取时长、分辨率等媒体信息;
  • FFmpeg:抽帧、提取音频和其他媒体转换;
  • Python 脚本:执行本地语音识别;
  • 第三方渠道:执行文本或视觉内容反推;
  • COS:持久化中间产物和最终结果。

临时文件处理完成后清理,长期资源进入 COS,并在数据库保留元数据。

14. 第三方渠道适配

渠道基础网址和 API Key 由 ADMIN 保存到 channels 表,具体业务模型配置保存在 models 表。渠道密钥以 AES-256-GCM 密文保存,只有 Worker 调用时解密。

internal/provider/apimart/ 负责统一的渠道 HTTP 协议:

  • Bearer Token 认证;
  • 文本请求;
  • 图片任务提交;
  • 视频任务提交;
  • 异步任务查询;
  • 渠道余额查询;
  • 上游错误码、Retry-After 和响应体截断。

Service 和 Worker 通过 internal/provider 中的适配器访问第三方接口。

15. 计费和积分

计费逻辑集中在 internal/billing/,而不是由前端计算最终扣费:

  • 前端只展示估算价格和积分余额;
  • Service 创建任务时计算预估积分并按规则预扣;
  • Worker 从第三方响应或任务结果取得实际用量;
  • 任务完成时结算,多退少补按现有业务规则执行;
  • 失败、取消和上游状态不确定分别使用不同处理规则;
  • point_ledger 保存流水,point_grants 和分配表支持永久积分批次的顺序扣减及原批次退款;

扣款、退款、任务终态和输出激活操作在数据库事务中执行,结算以后端持久数据为依据。

16. 静态文件和部署架构

16.1 开发环境

flowchart LR
    WebDev["WEB Vite"] -->|"/api 代理"| Go["Go API :8123"]
    AdminDev["ADMIN Vite"] -->|"/api 代理"| Go
    Go --> PG["Docker PostgreSQL :25432"]
    Go --> Redis["Docker Redis :26379"]
  • docker-compose.yml 只启动 PostgreSQL 和 Redis。
  • Go API 直接在 Windows 运行。
  • WEB 和 ADMIN 分别运行 Vite 开发服务器。
  • 当前两个 Vite 配置都把 /api 代理到 127.0.0.1:8123

16.2 生产环境

flowchart LR
    Internet["公网请求"] --> Nginx["Nginx :80/:443"]
    Nginx -->|"静态文件"| Static["/opt/juyou_ai/static"]
    Nginx -->|"API / Health"| Service["juyou_ai :8123"]
    Service --> PG["本机 PostgreSQL"]
    Service --> Redis["本机 Redis"]
  • API 只监听 127.0.0.1:8123,不直接暴露公网。
  • Nginx 提供 WEB 根路径和 /admin/ 静态站点。
  • /api//health 等请求反向代理到 Go API。
  • systemd 服务名为 juyou_ai
  • 环境文件位于 /etc/juyou_ai/juyou_ai.env
  • Go 自身也具备静态文件托管能力,适合本地或没有 Nginx 的场景;生产环境主要由 Nginx 直接提供静态文件。

17. 配置边界

后端配置统一来自 API/.env 或生产环境文件,主要分为:

配置组 内容
应用 运行环境、Debug、监听地址、静态目录
PostgreSQL 主机、端口、库名、用户、密码或完整 URL
Redis 主机、端口、密码、普通 DB、Asynq DB
JWT 签名密钥和 Token 有效期
管理员引导 首次管理员账号和密码
密码哈希 Argon2 参数
敏感配置 渠道密钥加密主密钥和版本
COS Region、Endpoint、Bucket、SecretId、SecretKey、公开域名、体积限制
Worker 并发、轮询间隔、HTTP 连接池、本地工具路径
CORS 允许访问 API 的前端来源

前端运行时不保存 COS SecretKey、渠道 API Key、数据库密码或 JWT Secret。浏览器只接收 API 输出的非敏感展示数据。

18. 测试与验证

18.1 后端测试

后端测试文件与实现同目录,覆盖计费、数据库基线、文本解析、Provider、Service、业务模块、Storage 和 Worker。internal/modules/admininternal/modules/prompt 均包含模块级测试。运行:

cd API
go test ./...

涉及真实数据库的基线测试通过专用环境变量启用,默认不会连接生产数据库。

18.2 前端验证

两个前端的构建命令都会先执行 TypeScript/Vue 类型检查:

npm --prefix WEB run build
npm --prefix ADMIN run build

格式检查:

npm --prefix WEB run format:check
npm --prefix ADMIN run format:check

18.3 健康检查

GET /health
GET /api/web/health
GET /api/admin/health

健康检查会同时验证 PostgreSQL 和 Redis 连接。