This repository has been archived on 2026-05-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
all-in-kingsoft/FinalHomework/hzh_doc/工程结构.md
T

20 KiB
Raw Blame History

大作业·工程结构设计

基于《思维导图》与《大作业项目要求》,前端技术栈统一采用 React + Vite,后端为 Go(Gin + gRPC)。

一、仓库根目录结构(final_homework/)

final_homework/
├── hr-frontend/              # HR管理端前端(React + Vite)
├── user-frontend/            # 候选人用户端前端(React + Vite)
├── web-gin-service/          # Gin Web网关服务
├── logic-grpc-service/       # gRPC核心业务服务
├── proto/            # Protobuf 定义
│   └── v1/
│       ├── auth.proto           # 认证相关
│       ├── job.proto            # 岗位相关
│       ├── application.proto    # 投递相关
│       ├── profile.proto        # 候选人档案
│       ├── resume.proto         # 简历/OSS上传
│       └── chat.proto           # AI对话
├── api.md                  # 前后端接口说明文档
├── db.md                   # 数据库设计文档
├── README.md                   # 启动部署指南 + 项目亮点
└── answer.md                   # 拓展设计方案(OpenClaw/Hermes集成思路)

二、HR管理端前端(hr-frontend/)

hr-frontend/
├── index.html
├── package.json
├── vite.config.ts                # Vite 配置,配置代理到 web-gin-service
├── tsconfig.json
├── .env                          # 前端环境变量(API_BASE_URL 等,不进 Git)
├── .gitignore
├── public/
│   └── favicon.ico
├── src/
│   ├── main.tsx                  # 入口文件
│   ├── App.tsx                   # 路由入口 + 权限守卫
│   ├── vite-env.d.ts
│   │
│   ├── styles/                   # 全局样式
│   │   ├── global.css
│   │   └── variables.css
│   │
│   ├── router/                   # 路由配置
│   │   └── index.tsx             # 独立路由页面:/hr/*
│   │
│   ├── api/                      # Axios 请求封装
│   │   ├── client.ts             # axios 实例 + baseURL / interceptor
│   │   ├── auth.ts               # 登录/注册接口
│   │   ├── job.ts                # 岗位 CRUD 接口
│   │   ├── application.ts        # 投递列表接口
│   │   ├── profile.ts            # 候选人档案接口
│   │   ├── resume.ts             # 简历信息接口
│   │   └── chat.ts               # AI对话接口
│   │
│   ├── stores/                   # 状态管理(useState + Context 即可)
│   │   ├── AuthContext.tsx       # 登录态 + JWT Token 上下文
│   │   └── ChatContext.tsx       # AI对话消息历史上下文
│   │
│   ├── pages/                    # 页面组件
│   │   ├── LoginPage.tsx         # HR登录页
│   │   ├── RegisterPage.tsx      # HR注册页
│   │   └── dashboard/            # 后台主页面(登录后可见)
│   │       ├── DashboardLayout.tsx  # 布局框架(侧边栏 + 顶栏)
│   │       ├── HomePage.tsx        # 工作台概览
│   │       ├── JobListPage.tsx     # 岗位列表(分页、搜索)
│   │       ├── JobEditPage.tsx     # 新建/编辑岗位表单
│   │       ├── CandidatePage.tsx   # 岗位下候选人列表(含投递状态)
│   │       ├── ProfileViewPage.tsx # 候选人结构化档案详情页
│   │       └── ChatPage.tsx        # AI智能对话窗口(常驻)
│   │
│   ├── components/               # 公共组件
│   │   ├── Layout/
│   │   │   ├── Sidebar.tsx       # 左侧导航栏
│   │   │   └── Header.tsx        # 顶部栏(显示当前HR头像/退出)
│   │   ├── Common/
│   │   │   ├── LoadingSpinner.tsx
│   │   │   ├── EmptyState.tsx
│   │   │   └── PageHeader.tsx
│   │   └── UI/                   # 基础 UI 组件(可用 Ant Design / Shadcn)
│   │       ├── Table.tsx
│   │       ├── Form.tsx
│   │       ├── Modal.tsx
│   │       └── Tag.tsx
│   │
│   ├── types/                    # TypeScript 类型定义
│   │   ├── auth.ts
│   │   ├── job.ts
│   │   ├── application.ts
│   │   ├── profile.ts
│   │   ├── resume.ts
│   │   └── chat.ts
│   │
│   └── utils/                    # 工具函数
│       ├── request.ts            # 通用请求拦截(自动带 Token)
│       └── format.ts             # 日期/数字格式化工具

HR端关键路由

路径 页面 说明 鉴权
/hr/login 登录页 HR账号密码登录 访客可访问
/hr/register 注册页 HR账号注册 访客可访问
/hr/dashboard 工作台 数据概览 必须JWT有效
/hr/dashboard/jobs 岗位列表 本人发布的岗位 必须JWT有效
/hr/dashboard/jobs/create 新建岗位 表单页 必须JWT有效
/hr/dashboard/jobs/:id/edit 编辑岗位 回显+修改 必须是创建者
/hr/dashboard/candidates 候选人列表 岗位下投递者 必须JWT有效
/hr/dashboard/candidates/:id/profile 档案详情 结构化资料 必须JWT有效
/hr/dashboard/chat AI对话 智能问答窗口 必须JWT有效

三、候选人用户端前端(user-frontend/)

user-frontend/
├── index.html
├── package.json
├── vite.config.ts
├── tsconfig.json
├── .env
├── .gitignore
├── public/
│   └── favicon.ico
├── src/
│   ├── main.tsx
│   ├── App.tsx                   # 路由入口 + 游客/已登录态切换
│   ├── vite-env.d.ts
│   │
│   ├── styles/
│   │   ├── global.css
│   │   └── variables.css
│   │
│   ├── router/
│   │   └── index.tsx             # 独立路由页面:/user/*
│   │
│   ├── api/                      # Axios 请求封装(同hr-frontend模式)
│   │   ├── client.ts
│   │   ├── auth.ts
│   │   ├── job.ts
│   │   ├── profile.ts
│   │   ├── resume.ts
│   │   └── application.ts
│   │
│   ├── stores/
│   │   └── AuthContext.tsx       # 登录态 + Token 上下文
│   │
│   ├── pages/
│   │   ├── HomePage.tsx          # 首页:公开岗位列表(游客可见)
│   │   ├── LoginPage.tsx         # 候选人登录页
│   │   ├── RegisterPage.tsx      # 候选人注册页(强校验)
│   │   ├── JobDetailPage.tsx     # 岗位详情(含投递按钮)
│   │   ├── SetupProfilePage.tsx  # 引导完善档案
│   │   ├── ResumeUploadPage.tsx  # 简历上传页(OSS签名URL直传)
│   │   └── ApplicationPage.tsx   # 我的投递记录
│   │
│   ├── components/
│   │   ├── Layout/
│   │   │   ├── Navbar.tsx        # 顶栏导航(游客/已登录不同UI)
│   │   │   └── Footer.tsx
│   │   ├── JobCard.tsx           # 岗位卡片组件(复用)
│   │   ├── JobList.tsx           # 岗位列表组件
│   │   ├── UploadProgress.tsx    # 简历上传进度条
│   │   ├── WarningModal.tsx      # 拦截弹窗(未完善资料/无简历)
│   │   └── Common/
│   │       ├── EmptyState.tsx
│   │       └── LoadingSpinner.tsx
│   │
│   ├── types/
│   │   ├── auth.ts
│   │   ├── job.ts
│   │   ├── profile.ts
│   │   ├── resume.ts
│   │   └── application.ts
│   │
│   └── utils/
│       ├── request.ts
│       └── format.ts

候选人端关键路由

路径 页面 说明 鉴权
/user/ 首页 公开岗位列表 免登录
/user/login 登录页 候选人登录 访客可访问
/user/register 注册页 候选人注册(强校验) 访客可访问
/user/job/:id 岗位详情 查看岗位 + 投递 投递需登录
/user/profile/setup 完善档案 必填字段表单 必须登录
/user/resume/upload 简历上传 OSS签名URL直传 必须登录
/user/applications 我的投递 投递记录列表 必须登录

四、Web 网关服务(web-gin-service/)

web-gin-service/
├── go.mod
├── go.sum
├── main.go                     # 服务入口,初始化 Gin Router + gRPC dial
├── config/
│   ├── config.go               # 配置加载(Viper / env)
│   └── .env.example            # 环境变量模板
├── internal/
│   ├── handler/                # HTTP Handler(仅做参数解析 + gRPC调用转发)
│   │   ├── auth_handler.go     # POST /api/auth/login, /api/auth/register
│   │   ├── job_handler.go      # POST/GET/PUT/DELETE /api/jobs
│   │   ├── application_handler.go
│   │   ├── profile_handler.go
│   │   ├── resume_handler.go   # POST /api/resume/upload → 调gRPC取签名URL
│   │   └── chat_handler.go     # POST /api/chat/messages
│   │
│   ├── middleware/             # 中间件
│   │   ├── cors.go             # 全局跨域处理
│   │   ├── jwt_auth.go         # JWT 统一鉴权(角色校验)
│   │   └── validate.go         # 请求参数合法性校验
│   │
│   ├── transport/              # gRPC 客户端(连接 logic-grpc-service)
│   │   ├── grpc_client.go      # 统一 gRPC client 池
│   │   └── codec.go            # proto message ↔ HTTP JSON 转换
│   │
│   └── router/                 # 路由注册
│       └── router.go           # gin.Engine 路由绑定
├── proto/                      # 引用的 proto 文件只读拷贝
│   └── gen/
│       └── v1/
└── README.md                   # Web服务自述

Web端 API 路由清单

方法 路径 说明 鉴权
POST /api/auth/login 登录,返回 JWT 无
POST /api/auth/register 注册 无
GET /api/jobs 岗位列表(分页) 无
GET /api/jobs/:id 岗位详情 无
POST /api/jobs 发布岗位 HR
PUT /api/jobs/:id 编辑岗位 HR(本人)
DELETE /api/jobs/:id 下架岗位 HR(本人)
GET /api/jobs/:id/applications 岗位下候选人列表 HR
GET /api/profile/:userId 查看候选人档案 HR
POST /api/resume/upload 获取OSS签名URL 候选人
POST /api/profile 更新个人档案 候选人
POST /api/applications 投递简历 候选人
POST /api/chat/messages AI对话发送 HR
GET /api/chat/history 加载对话历史 HR

五、Logic 核心业务服务(logic-grpc-service/)

logic-grpc-service/
├── go.mod
├── go.sum
├── main.go                     # 服务入口,注册 gRPC Server
├── config/
│   ├── config.go
│   └── .env.example
├── internal/
│   ├── server/                 # gRPC Server 实现
│   │   ├── auth_service.go     # 用户注册/登录/鉴权
│   │   ├── job_service.go      # 岗位 CRUD(含创建者权限校验)
│   │   ├── application_service.go  # 投递逻辑
│   │   ├── profile_service.go      # 候选人档案增改查
│   │   ├── resume_service.go       # OSS签名URL生成
│   │   └── chat_service.go       # AI对话 + 历史持久化
│   │
│   ├── model/                  # 数据模型(ORM struct)
│   │   ├── user.go
│   │   ├── job.go
│   │   ├── application.go
│   │   ├── profile.go
│   │   └── chat_record.go
│   │
│   ├── repository/             # 数据访问层(MySQL操作)
│   │   ├── user_repo.go
│   │   ├── job_repo.go
│   │   ├── application_repo.go
│   │   ├── profile_repo.go
│   │   ├── resume_repo.go
│   │   └── chat_record_repo.go
│   │
│   ├── oss/                    # OSS客户端封装
│   │   ├── client.go           # MinIO / 阿里云 OSS SDK 初始化
│   │   └── signer.go           # 签名URL生成 + 文件头白名单校验
│   │
│   ├── ai/                     # Eino AI 封装
│   │   ├── engine.go           # Eino Chat 引擎初始化
│   │   ├── prompt.go           # 提示词模板 + 业务上下文拼接
│   │   └── query_parser.go     # 自然语言意图解析 → SQL查询条件
│   │
│   ├── jwt/                    # JWT 工具
│   │   └── jwt.go              # 签发 + 验证 + 角色提取
│   │
│   └── converter/              # DTO 转换
│       └── proto_converter.go  # proto message ↔ model struct
├── proto/
│   └── gen/
│       └── v1/
└── README.md

六、Protobuf 定义(proto/v1/)

所有 proto 文件统一放在 proto/v1/,供 web-gin-service 和 logic-grpc-service 共同引用。

proto/v1/
├── common.proto                # 公共定义(Response code/msg, Pagination)
├── auth.proto                  # AuthService: Login, Register, VerifyToken
├── job.proto                   # JobService: CreateJob, UpdateJob, ListJobs, DeleteJob
├── application.proto           # ApplicationService: SubmitApplication, ListApplications
├── profile.proto               # ProfileService: GetProfile, UpdateProfile
├── resume.proto                # ResumeService: GenOssSign, GetResumeInfo
└── chat.proto                  # ChatService: SendChat, GetHistory

七、数据流总览

7.1 核心架构调用链

flowchart LR
    subgraph FE ["前端层(React + Vite)"]
        HR["HR管理端<br/>hr-frontend"]
        User["候选人用户端<br/>user-frontend"]
    end

    subgraph GW ["Web网关层(Gin)<br/>web-gin-service"]
        RH["Auth Handler"]
        JH["Job Handler"]
        AH["Application Handler"]
        PH["Profile Handler"]
        RRH["Resume Handler"]
        CH["Chat Handler"]
        JWT["JWT 鉴权中间件"]
        CORS["CORS 中间件"]
    end

    subgraph RPC ["Logic业务层(gRPC)<br/>logic-grpc-service"]
        US["AuthService"]
        JS["JobService"]
        AS["ApplicationService"]
        PS["ProfileService"]
        RSS["ResumeService"]
        CS["ChatService"]
        JWT_L["JWT 验证"]
        DB["MySQL Repository"]
        OSS_S["OSS Signer"]
        AI["Eino Chat Engine"]
    end

    subgraph Storage ["存储 & 外部服务"]
        M[(MySQL)]
        O[私有 OSS Bucket]
        LLM[大语言模型]
    end

    %% HR 请求链路
    HR -->|"HTTP /api/*"| CORS
    CORS --> JWT
    JWT --> RH
    JWT --> JH
    JWT --> CH

    %% 候选人 请求链路
    User -->|"HTTP /api/*"| CORS

    %% gRPC 跨服务调用
    RH -->|"gRPC Login/RPC"| US
    JH -->|"gRPC Job CRUD"| JS
    CH -->|"gRPC SendChat/History"| CS
    RRH -->|"gRPC GenOssSign"| RSS

    %% Handler 转发候选人请求
    JWT --> RRH
    JWT --> PH
    JWT --> AH

    PH -->|"gRPC Get/UpdateProfile"| PS
    AH -->|"gRPC SubmitApplication"| AS

    %% Backend → Storage
    US --> M
    JS --> M
    AS --> M
    PS --> M
    DB --> M
    CS --> DB
    RSS --> O
    CS --> AI
    AI --> LLM

    classDef frontNode fill:#e3f2fd,stroke:#1565c0;
    classDef gwNode fill:#fff3e0,stroke:#e65100;
    classDef logicNode fill:#e8f5e9,stroke:#2e7d32;
    classDef storeNode fill:#fce4ec,stroke:#c62828;

    class HR,User frontNode;
    class CORS,RH,JH,AH,PH,RRH,CH gwNode;
    class US,JS,AS,PS,RSS,CS,JWT_L,DB,OSS_S,AI logicNode;
    class M,O,LLM storeNode;

7.2 简历直传流程(签名 URL 方案)

sequenceDiagram
    participant C as CandidateFrontend
    participant W as Web-Gin
    participant R as ResumeService (gRPC)
    participant S as Storage (Private OSS)

    Note over C,S: 第一阶段:获取上传凭证

    C->>W: POST /api/resume/upload<br/>(PDF/DOC/DOCX 文件元信息)
    W->>W: JWT校验 + 后缀白名单校验
    W->>R: gRPC GenOssSign(key, extension)
    R->>R: 校验文件头 Magic Number
    R-->>W: {UploadURL, DownloadURL, Expiry}
    W-->>C: 返回签名URL信息

    Note over C,S: 第二阶段:客户端直传 OSS(服务端零缓存)

    C->>S: PUT 直接上传到 OSS Bucket
    S-->>C: 200 OK,上传完成

    Note over C,W: 第三阶段:记录简历链接到数据库

    C->>W: POST /api/profile/save-resume<br/>(fileKey)
    W->>R: gRPC SaveResume(fileKey)
    R->>R: 持久化 fileKey 到 MySQL
    R-->>W: 操作成功
    W-->>C: 保存成功

7.3 AI 对话数据流

sequenceDiagram
    participant H as HR Frontend
    participant W as Web-Gin
    participant C as ChatService (gRPC)
    participant Q as Query Parser
    participant M as MySQL
    participant P as Prompt Builder
    participant E as Eino Chat
    participant L as Large Language Model
    participant DB as ChatRecordRepo

    Note over H,M: Step 1 — 发起提问

    H->>W: POST /api/chat/messages {question}
    W->>C: gRPC SendChat(hrId, question)

    Note over C,Q: Step 2 — 意图解析 + 数据查询

    C->>Q: 解析自然语言意图
    Q->>M: 执行业务SQL查询
    M-->>Q: 真实统计数据

    Note over C,P: Step 3 — 上下文拼接 + 推送模型

    Q-->>C: 结构化数据
    C->>P: 拼接 Prompt = 模板 + 业务数据 + 原始问题
    P-->>C: 完整Prompt
    C->>E: Eino.Chat.Send(context, messages)
    E->>L: HTTP 请求至大模型
    L-->>E: 生成回答
    E-->>C: 自然语言回答

    Note over C,DB: Step 4 — 持久化 + 返回

    C->>DB: INSERT chat_record(hr_id, question, reply)
    DB-->>C: 写入成功
    C-->>W: gRPC Response {reply, records[]}
    W-->>H: 渲染AI回复 + 历史消息列表

7.4 模块依赖关系图

graph TB
    subgraph HRFE ["hr-frontend (React + Vite)"]
        Routes["路由 /hr/*"]
        AuthCtx["AuthContext (JWT)"]
        ChatCtx["ChatContext (对话状态)"]
        API["Axios API 层"]
    end

    subgraph UFE ["user-frontend (React + Vite)"]
        URoutes["路由 /user/*"]
        UAuthCtx["AuthContext (JWT)"]
        UAPI["Axios API 层"]
    end

    subgraph GWI ["web-gin-service (Go)"]
        Router["Router"]
        Middleware["Middleware: CORS + JWT + Validate"]
        Handlers["Handlers: auth / job / resume / chat ..."]
        GrpcClient["gRPC Client → Logic"]
    end

    subgraph LO ["logic-grpc-service (Go)"]
        GrpcServer["gRPC Server"]
        Services["Services: auth / job / application / profile / resume / chat"]
        Repos["Repositories → MySQL"]
        OSSMod["OSS Client → Private OSS"]
        AIMod["Eino Engine → LLM"]
    end

    subgraph DATA ["数据 & 存储"]
        MySQL[(MySQL)]
        OSS["私有 OSS"]
        LLM["大语言模型 API"]
    end

    HRFE -->|HTTP JSON| GWI
    UFE -->|HTTP JSON| GWI
    GWI -->|gRPC| LO
    LO --> MySQL
    LO --> OSS
    LO --> LLM

    classDef fe fill:#e3f2fd,stroke:#1565c0;
    classDef gw fill:#fff3e0,stroke:#e65100;
    classDef logic fill:#e8f5e9,stroke:#2e7d32;
    classDef data fill:#fce4ec,stroke:#c62828;
    class HRFE,UFE fe;
    class GWI gw;
    class LO logic;
    class DATA data;

八、开发建议

  1. 前后端各自独立运行:每个 frontend/ 用 npm run dev 启动 Vite 开发服务器,通过 vite.config.ts 中的 server.proxy 将 /api/* 代理到 localhost:8080(Web-Gin)。
  2. Proto 先行:先写好 proto/v1/ 下的所有 .proto 文件,再各自 protoc 生成代码,避免来回改接口。
  3. 前端共享模式:HR端和用户端都遵循「API层 → Store层 → 页面层」三层分离,可抽取公共的 Axios client 和类型定义作为参考。
  4. 环境变量隔离:两个前端的 .env、后端的 .env 全部加 .gitignore,使用 .env.example 作为模板提交。