# 项目后端结构说明 本文介绍仓库的整体布局,重点是后端 `internal/` 的分层职责:每个文件负责什么、一次请求经过哪些环节。配套阅读:《[数据库表结构与关系说明](数据库表结构与关系说明.md)》《[API 文档](api.md)》。 ## 仓库顶层布局 | 目录/文件 | 说明 | | --- | --- | | `cmd/server/` | 后端入口 `main.go`:读 DSN、连库、建默认用户、校验 schema、注册路由并启动 | | `internal/` | 后端内核,见下文分层说明 | | `pkg/` | 通用基础包:`database`(连接与 DSN 规范化)、`response`(统一响应格式与状态码封装) | | `frontend/` | 前端源码与构建产物(`frontend/dist` 为后端静态托管的目录) | | `scripts/` | `init.sql`、增量升级 SQL 与校验脚本 | | `docs/` | 项目文档 | ## 整体 `cmd/server/main.go` 是入口(注册路由、连库、校验 schema),`internal/` 只是内核。一次请求的链路是: ``` middleware(认证/公司校验)→ handler(绑参、回响应)→ service(业务规则、校验、组装)→ repository(纯 SQL)→ model(结构体) ``` 响应统一走 `pkg/response`,连库在 `pkg/database`。 ## handler/(HTTP 层) `api.go` 是大头(1604 行)。 | 文件 | 职责 | | --- | --- | | [api.go](../internal/handler/api.go) | `Handler` 聚合全部 service;`RegisterRoutes` 定义所有路由与中间件挂载;物料、出入库、库存、用户、申请等主体 handler | | [admin_master.go](../internal/handler/admin_master.go) | 管理端:公司、角色、权限、物料分类、单位、编码规则、往来单位、仓库/库位,另含 `organizationID` / `pathID` / `bind` 三个公共小工具 | | [organization_context.go](../internal/handler/organization_context.go) | 公司切换器:列出可访问公司、切换当前公司上下文 | | [upload.go](../internal/handler/upload.go) | 图片上传 | | [websocket.go](../internal/handler/websocket.go) | 库存变更实时推送的 Hub、Client、广播,以及 `/ws` 握手(凭一次性票据 + 实时复核授权) | ## middleware/(3 个) | 文件 | 职责 | | --- | --- | | [auth.go](../internal/middleware/auth.go) | JWT 解析、`AdminOnly`、`OptionalAuth`,以及取 userID / username / roles 的辅助函数 | | [organization.go](../internal/middleware/organization.go) | 校验 `X-Organization-ID` 头并确认该用户能访问这家公司,通过后写进 context | | [rate_limiter.go](../internal/middleware/rate_limiter.go) | 登录失败次数限流 + 定期清理 | ## service/(业务规则) | 文件 | 职责 | | --- | --- | | [material.go](../internal/service/material.go) | 物料增改查、作废/恢复 | | [inbound.go](../internal/service/inbound.go) / [outbound.go](../internal/service/outbound.go) | 出入库单的业务校验与库存联动 | | [stock.go](../internal/service/stock.go) | 库存查询、预警分类、变动量计算 | | [inventory_scope.go](../internal/service/inventory_scope.go) | 公司维度的仓库/库位解析:库存读写一律由服务端从库里推导,不收前端传的 ID;写操作要求启用状态 | | [material_log.go](../internal/service/material_log.go) | 物料变更日志的 diff 生成与中文描述 | | [application.go](../internal/service/application.go) | 物料申请单的提交/审批/驳回/撤销 | | [auth.go](../internal/service/auth.go) | 登录、签发与校验 token session、密码哈希 | | [admin_master.go](../internal/service/admin_master.go) | 公司、主数据(分类/单位/编码规则)、往来单位、仓库四组服务 | | [organization_access.go](../internal/service/organization_access.go) | 公司可访问范围与切换 | | [websocket_ticket.go](../internal/service/websocket_ticket.go) | WebSocket 一次性票据的签发/消费 | | [errors.go](../internal/service/errors.go) | 共享哨兵错误(库存不足、公司维度不可用等),供 handler 映射状态码 | ## repository/(纯 SQL) | 文件 | 职责 | | --- | --- | | [material.go](../internal/repository/material.go) | 物料,含事务版新增(锁编码规则、判重)/更新/作废/恢复 | | [inbound.go](../internal/repository/inbound.go) / [outbound.go](../internal/repository/outbound.go) | 出入库单及明细读写,共用 `orderQuerier` 接口 | | [stock.go](../internal/repository/stock.go) | 库存余额、流水、预警规则,含 upsert | | [master_data.go](../internal/repository/master_data.go) | 分类/单位/编码规则 | | [material_log.go](../internal/repository/material_log.go) | 物料日志落库与查询 | | [warehouse.go](../internal/repository/warehouse.go) | 仓库/库位,含 `Summary`(按公司取唯一仓库 + 库位) | | [partner.go](../internal/repository/partner.go) | 往来单位 | | [user.go](../internal/repository/user.go) | 用户与角色,含保护最后一个超管、建默认用户/表 | | [user_organization.go](../internal/repository/user_organization.go) | 用户-公司关联的替换与批量加载 | | [organization.go](../internal/repository/organization.go) / [organization_access.go](../internal/repository/organization_access.go) | 公司基础 CRUD;`ListAccessible` / `CanAccess` 的授权判定(每次查库,不依赖 JWT 里的角色快照) | | [organization_audit.go](../internal/repository/organization_audit.go) | 公司相关操作的审计日志写入 | | [application.go](../internal/repository/application.go) | 申请单及明细 | | [update.go](../internal/repository/update.go) | `execExpectingRow`:UPDATE 后校验影响行数,避免"0 行也当成功" | ## model/(数据结构,无逻辑) [model.go](../internal/model/model.go) 集中了大部分结构体(物料、出入库单与明细、库存与流水、用户、申请单,以及各类 Request/Response);后来又按业务域另拆出 `inventory.go`、`master_data.go`、`organization.go`、`partner.go`、`warehouse.go` 五个文件。 ## testutil/ `fixtures.go`、`isolation.go`、`testdb.go` 是测试辅助包,不属于业务代码。