目录

proj_hub — 项目信息管理系统

面向内网环境的项目全生命周期信息管理平台,支持项目基础信息录入、调整变更、建设实施、建设投入和建成交付的全流程跟踪,同时提供用户管理、单位树管理和可配置下拉选项等管理功能。

技术栈

层次 技术
后端 Python 3.12 · FastAPI · SQLAlchemy · Alembic · uv
数据库 MySQL 8
前端 Vue 3 · Pinia · Vue Router · Vite · Element Plus · ECharts
部署 两个 Docker 容器:mysql:8.4(数据库)+ 应用镜像(后端 + 前端静态文件 + nginx)

目录结构

proj_hub/
├── backend/                  # 后端(FastAPI)
│   ├── app/
│   │   ├── api/v1/           # 路由层:auth / users / projects / options / units
│   │   ├── services/         # 业务逻辑层(含 Excel 导入/导出)
│   │   ├── crud/             # 数据库操作层
│   │   ├── models/           # SQLAlchemy ORM 模型
│   │   ├── schemas/          # Pydantic 请求/响应模型
│   │   ├── core/             # 配置、安全(JWT)、异常
│   │   ├── db/               # 数据库会话、基类
│   │   ├── dependencies.py   # 依赖注入(当前用户、角色校验)
│   │   └── main.py           # FastAPI 入口
│   ├── scripts/              # 数据库初始化 / 种子脚本
│   ├── tests/                # pytest 测试套件
│   ├── alembic/              # 数据库迁移
│   └── pyproject.toml
│
├── frontend/                 # 前端(Vue 3)
│   └── src/
│       ├── api/              # axios 封装(projects / users / options / units)
│       ├── views/
│       │   ├── projects/     # 项目列表、详情、四张子表组件
│       │   ├── users/        # 用户管理
│       │   ├── units/        # 单位树管理
│       │   ├── options/      # 下拉选项配置
│       │   ├── dashboard/    # 统计看板
│       │   └── login/        # 登录页
│       ├── layouts/          # MainLayout / AuthLayout
│       ├── stores/           # Pinia(user / app)
│       ├── router/           # 路由及鉴权守卫
│       └── components/       # 公共组件(OptionSelect 等)
│
├── docker/
│   ├── entrypoint.sh         # 容器启动脚本(初始化 MySQL 后交由 supervisord)
│   ├── supervisord.conf      # 进程管理(backend + nginx)
│   ├── nginx.conf            # 反向代理:/ → 前端静态文件,/api/ → 后端
│   └── mysql/init.sql        # 数据库初始化 SQL
│
├── requirements/             # 业务需求文档
├── Dockerfile                # 生产多阶段构建(前端构建 + 后端 + nginx)
├── docker-compose.yml        # 开发环境(热重载)
├── docker-compose.prod.yml   # 生产环境(使用预构建镜像)
├── .env.example              # 生产环境变量示例
├── prepare_images.sh         # 构建应用镜像并拉取 MySQL 镜像,导出为 tar 文件
└── build.sh                  # 打包源代码,组装发布目录

版本号管理

版本号在项目根目录的 VERSION 文件中维护,读取优先级从高到低:

  1. 环境变量 VITE_APP_VERSION(build.sh 在构建时注入)
  2. 项目根目录的 VERSION 文件
  3. frontend/package.json 的 version 字段

日常改版本号,直接编辑 VERSION 文件:

1.1.0

保存后 Vite dev server 会热重载,无需重启容器。发布时将版本号作为参数传给构建脚本:

./build.sh 1.1.0

本地开发

开发环境完全运行在 Docker 容器中,由 docker-compose.yml 管理三个服务:

服务 容器内运行内容 宿主机访问地址
db MySQL 8.4 localhost:3306
backend uvicorn 热重载 http://localhost:8000
frontend Vite dev server http://localhost:5173

后端的 backend/ 目录和前端的 src/、index.html、vite.config.js 均以卷挂载方式注入容器,在宿主机上修改代码后容器内即时生效,无需重建镜像。

启动开发环境

# 首次启动或 Dockerfile 有变动时加 --build
docker compose up --build

# 之后直接启动
docker compose up

常用开发命令(在容器内执行)

# 生成数据库迁移文件
docker exec proj_hub-backend-1 sh -c "PYTHONPATH=/app .venv/bin/alembic revision --autogenerate -m '描述'"

# 手动执行迁移(容器启动时会自动执行)
docker exec proj_hub-backend-1 sh -c "PYTHONPATH=/app .venv/bin/alembic upgrade head"

# 运行后端测试
docker exec proj_hub-backend-1 sh -c "PYTHONPATH=/app .venv/bin/pytest"

# 前端代码检查
docker exec proj_hub-frontend-1 npm run lint

发布流程

适用场景:将应用部署到无法访问互联网的内网服务器。

部署后在服务器上运行两个容器:proj_hub_db(MySQL 8 官方镜像)和 proj_hub(应用镜像,包含后端 + 前端静态文件 + nginx)。

第一步:准备镜像(需联网)

# 构建应用镜像并拉取 MySQL 官方镜像,导出为 tar 文件
./prepare_images.sh 1.0.0

脚本会:

  1. 用 Dockerfile 构建应用镜像 proj_hub:1.0.0
  2. 拉取 mysql:8.4 官方镜像
  3. 将两个镜像分别导出为 proj_hub_1.0.0.tar 和 mysql_8.4.tar

第二步:打包发布目录

./build.sh 1.0.0

脚本会将镜像 tar 文件、源代码和配置文件组装到 release/ 目录:

release/
├── proj_hub_1.0.0.tar          # 应用 Docker 镜像
├── mysql_8.4.tar               # MySQL Docker 镜像
├── backend/                    # 后端源码
├── frontend/                   # 前端静态文件
├── docker-compose.prod.yml     # 生产环境 Compose 配置
├── .env.example                # 环境变量示例
├── version.txt                 # 版本信息
└── 操作流程.md                  # 部署操作说明

第三步:传输到内网服务器

通过 U 盘、内网文件共享、scp 等方式,将整个 release/ 目录复制到目标服务器。

第四步:在服务器上启动服务

cd release

# 1. 加载镜像
docker load -i proj_hub_1.0.0.tar
docker load -i mysql_8.4.tar

# 2. 配置环境变量
cp .env.example .env
vi .env   # 至少填写 IMAGE_VERSION 和 SECRET_KEY

# 3. 启动服务
docker compose -f docker-compose.prod.yml up -d

.env 可配置项:

变量 默认值 说明
IMAGE_VERSION (必填) 镜像版本,与 tar 包一致,如 1.0.0
SECRET_KEY (必填) JWT 密钥,建议 openssl rand -hex 32 生成
DB_PASSWORD proj_hub_pass 数据库密码
HOST_PORT 9000 应用对外暴露端口
DB_PORT 9001 MySQL 对外暴露端口
DATA_DIR /data/proj_hub 数据持久化目录

更新发布(仅更新代码,不重建镜像)

适用场景:只修改了后端逻辑或前端页面,依赖和运行环境未变,无需重新构建 Docker 镜像。

由于 docker-compose.prod.yml 通过卷挂载将 ./backend 和 ./frontend 目录注入容器,直接替换这两个目录后重启容器即可生效,无需重新加载镜像。

第一步:重新打包代码

# 镜像 tar 已存在,直接重新打包源码
./build.sh 1.0.0

脚本会重新编译前端、同步后端代码,覆盖 release/ 中的 backend/ 和 frontend/ 目录,但不影响已有的镜像 tar 文件。

第二步:将更新后的代码传输到服务器

只需传输源码部分,无需再次传输镜像 tar 文件:

# 示例:通过 scp 增量同步(排除镜像 tar)
scp -r release/backend release/frontend user@server:/path/to/release/

第三步:在服务器上重启应用容器

cd /path/to/release
docker compose -f docker-compose.prod.yml restart app

容器重启后挂载目录中的新代码立即生效,数据库和 MySQL 容器无需重启。

第四步(如有数据库变更):执行迁移

若本次更新包含数据库结构变更,需在容器内运行迁移:

docker exec proj_hub bash -c "cd /app/backend && uv run alembic upgrade head"

常用运维命令

# 查看服务状态
docker compose -f docker-compose.prod.yml ps

# 查看日志
docker compose -f docker-compose.prod.yml logs -f app
docker compose -f docker-compose.prod.yml logs -f db

# 停止 / 启动
docker compose -f docker-compose.prod.yml down
docker compose -f docker-compose.prod.yml up -d

# 进入容器排查问题
docker exec -it proj_hub bash

数据模型概览

核心实体为项目基础信息(projects),以 project_no(项目编号)作为唯一业务标识。四张子表与其为一对多关系:

  • project_changes — 调整变更
  • project_implementations — 建设实施
  • project_investments — 建设投入
  • project_deliveries — 建成交付

所有表均包含 created_at、updated_at、deleted_at、is_deleted 字段,支持软删除和硬删除两种模式。


Mock数据

向开发数据库写入Mock数据

docker exec -e DB_HOST=db -e DB_PORT=3306 -e DB_USER=proj_hub -e DB_PASSWORD=1234 -e DB_NAME=proj_hub proj_hub-backend-1 sh -c "PYTHONPATH=/app .venv/bin/python /mock/generate_projects.py"

权限说明

角色 权限
管理员 管理用户账号、单位树、下拉选项配置
普通用户 对所有业务表进行增删改查及 Excel 导入导出

使用 JWT(Bearer Token)鉴权,Token 有效期 8 小时。

关于
5.2 MB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802047560号