初始化项目
This commit is contained in:
119
AI编程入门指南.md
Normal file
119
AI编程入门指南.md
Normal file
File diff suppressed because one or more lines are too long
304
aiPrompt.md
Normal file
304
aiPrompt.md
Normal file
@@ -0,0 +1,304 @@
|
||||
# AI 开发提示词 — 项目架构与模块开发规范
|
||||
|
||||
> 在向 AI 提出开发需求时,将以下提示词附加在需求描述之后,AI 即可按照项目架构规范生成代码,避免多人协作时的合并冲突。
|
||||
|
||||
---
|
||||
|
||||
## 提示词内容(复制到你的需求后面)
|
||||
|
||||
```
|
||||
## 项目架构与模块开发规范
|
||||
|
||||
### 一、项目概述
|
||||
|
||||
Under18 是一个前后端分离的 RBAC 权限管理脚手架,提供用户、角色、权限、字典、标签、日志等通用功能模块。采用模块化自动注册架构,新增功能模块时**严禁修改任何共享/公共文件**,所有新代码必须放在独立模块文件中。
|
||||
|
||||
**技术栈:**
|
||||
- 后端:FastAPI + SQLAlchemy(异步)+ PostgreSQL + Alembic
|
||||
- 前端:Vue 3 + Vite 5 + Element Plus + Pinia + Vue Router 4
|
||||
- 缓存:cachetools.TTLCache(进程内,替代 Redis)
|
||||
- 认证:JWT(HS256),Access Token 120min + Refresh Token 7天
|
||||
|
||||
### 二、后端规范(FastAPI)
|
||||
|
||||
#### 2.1 分层架构
|
||||
|
||||
```
|
||||
API 层 (app/api/{模块名}.py) — 路由定义、参数校验(Schema)、权限注入、响应封装
|
||||
↓ 调用
|
||||
Service 层 (app/services/{模块名}_service.py) — 纯业务逻辑,静态方法,接收 AsyncSession
|
||||
↓ 操作
|
||||
Model 层 (app/models/{模块名}.py) — ORM 映射,继承 Base + TimestampMixin + SoftDeleteMixin
|
||||
```
|
||||
|
||||
#### 2.2 新增模块只需创建以下独立文件,不需要修改任何已有文件:
|
||||
|
||||
1. **`backend/app/models/{模块名}.py`** — ORM 模型定义
|
||||
- 从 `app.core.database` 导入 `Base`
|
||||
- 从 `app.models.mixins` 导入 `TimestampMixin, SoftDeleteMixin`(日志类模型可不加 SoftDeleteMixin)
|
||||
- 模型类继承:`class SysXxx(Base, TimestampMixin, SoftDeleteMixin)`
|
||||
- 关联表(many-to-many)使用 `Table()` 定义在同一文件中
|
||||
- 每个模型需实现 `to_dict()` 方法手动序列化
|
||||
- 表名统一使用 `sys_` 前缀
|
||||
|
||||
2. **`backend/app/schemas/{模块名}.py`** — Pydantic 请求/响应模型
|
||||
- 每个模块的 schema 独立一个文件
|
||||
- 命名规范:`XxxCreateRequest`、`XxxUpdateRequest`、`XxxQueryRequest`
|
||||
- 从 `app.schemas.response` 导入 `PageQuery` 作为分页查询基类
|
||||
|
||||
3. **`backend/app/services/{模块名}_service.py`** — 业务逻辑层
|
||||
- 类名必须以 `Service` 结尾(如 `ArticleService`),全部使用 `@staticmethod`
|
||||
- 从 `app.models.{模块名}` 导入模型(不要从 app.models 或 app.models.models 导入)
|
||||
- 从 `app.schemas.{模块名}` 导入 schema(不要从 app.schemas.request 导入)
|
||||
- 所有方法第一个参数为 `db: AsyncSession`
|
||||
- 调用方式:`ArticleService.get_list(db, ...)`
|
||||
|
||||
4. **`backend/app/api/{模块名}.py`** — API 路由
|
||||
- 必须导出名为 `router` 的 `APIRouter` 实例
|
||||
- 示例:`router = APIRouter(prefix="/xxx", tags=["XXX管理"])`
|
||||
- 所有路由自动加上 `/api` 前缀(由 `api_router = APIRouter(prefix="/api")` 控制)
|
||||
- 从 `app.core.deps` 导入 `get_current_user`、`require_permission`
|
||||
- 从 `app.schemas.response` 导入 `success`、`error`、`page_result`
|
||||
- 路由文件会被 `app/api/__init__.py` 自动扫描注册,**不要修改 __init__.py**
|
||||
|
||||
#### 2.3 自动注册机制
|
||||
|
||||
| 层 | 扫描规则 | 约定 |
|
||||
|----|---------|------|
|
||||
| API 路由 | 扫描 `app/api/` 下所有 `.py`,查找 `router` 变量 | 文件必须导出 `router = APIRouter(...)` |
|
||||
| Model | 扫描 `app/models/` 下所有 `.py`(跳过 `__init__.py` 和 `mixins.py`) | 确保模型被导入到 Base.metadata |
|
||||
| Service | 扫描 `app/services/` 下所有 `_service.py`,收集以 `Service` 结尾的类 | 可直接 `from app.services import XxxService` |
|
||||
|
||||
**因此绝对不需要修改任何 `__init__.py` 文件。**
|
||||
|
||||
#### 2.4 已有模型导入路径
|
||||
|
||||
```python
|
||||
from app.models.user import SysUser, sys_user_role # 用户 + 用户角色关联表
|
||||
from app.models.role import SysRole, sys_role_permission # 角色 + 角色权限关联表
|
||||
from app.models.permission import SysPermission # 权限
|
||||
from app.models.dict import SysDictType, SysDictData # 字典类型 + 字典数据
|
||||
from app.models.log import SysOperationLog, SysLoginLog # 操作日志 + 登录日志
|
||||
from app.models.tag import SysTag, sys_tag_object # 标签 + 标签对象关联表
|
||||
from app.models.mixins import TimestampMixin, SoftDeleteMixin # 通用混入
|
||||
```
|
||||
|
||||
#### 2.5 响应格式统一
|
||||
|
||||
```python
|
||||
from app.schemas.response import success, error, page_result
|
||||
|
||||
# 成功:return success(data=xxx)
|
||||
# 失败:return error(message="xxx", code=400)
|
||||
# 分页:return page_result(items=xxx, total=xxx, page=xxx, page_size=xxx)
|
||||
```
|
||||
|
||||
响应体格式:
|
||||
```json
|
||||
{ "code": 200, "message": "success", "data": {...} }
|
||||
{ "code": 200, "message": "success", "data": { "items": [], "total": 0, "page": 1, "page_size": 10 } }
|
||||
{ "code": 400, "message": "错误信息", "data": null }
|
||||
```
|
||||
|
||||
#### 2.6 权限校验
|
||||
|
||||
- **路由级**:`dependencies=[Depends(require_permission("模块:资源:操作"))]`
|
||||
- **按钮级**:前端使用 `v-permission="'模块:资源:操作'"` 指令
|
||||
- **权限编码格式**:`模块:资源:操作`,如 `content:article:list`
|
||||
- **超级管理员豁免**:角色为 `admin` 的用户自动拥有全部权限
|
||||
|
||||
#### 2.7 认证与安全
|
||||
|
||||
- **密码加密**:`SHA-256(password + user_salt + global_salt)`,双重加盐
|
||||
- **Token 体系**:Access Token(120min)+ Refresh Token(7天),HS256 算法
|
||||
- **登录安全**:连续3次失败强制验证码;同IP 10次失败锁定30分钟;每IP每分钟限20次登录请求
|
||||
- **获取客户端IP**:使用 `SecurityMiddleware._get_client_ip(request)`
|
||||
|
||||
#### 2.8 数据库与配置
|
||||
|
||||
- **数据库**:PostgreSQL,异步驱动 asyncpg,连接由 `app.core.database` 管理
|
||||
- **迁移**:Alembic,通过 `alembic revision --autogenerate` 生成
|
||||
- **配置**:唯一来源 `config.yaml`,环境变量 `UNDER18_<键名>` 可覆盖
|
||||
- **依赖注入**:`get_db()` 提供 AsyncSession,`get_current_user()` 提供当前用户
|
||||
|
||||
#### 2.9 路由定义注意事项
|
||||
|
||||
- 批量操作路由(如 `/batch`、`/clear/all`)必须定义在通配符路由(如 `/{id}`)之前,否则会被通配符匹配拦截
|
||||
|
||||
### 三、前端规范(Vue3 + Vite)
|
||||
|
||||
#### 3.1 新增模块只需创建以下独立文件,不需要修改任何已有文件:
|
||||
|
||||
1. **`frontend/src/router/modules/{模块名}.js`** — 路由配置
|
||||
- 必须 `export default` 一个路由配置对象
|
||||
- 会被 `router/index.js` 通过 `import.meta.glob` 自动扫描加载
|
||||
- **不要修改 `router/index.js`**
|
||||
|
||||
2. **`frontend/src/views/{模块路径}/{子路由}/index.vue`** — 页面组件
|
||||
- 视图文件路径必须与路由中的 `component` 导入路径一致
|
||||
|
||||
3. **`frontend/src/api/{模块名}.js`** — API 调用函数
|
||||
- 从 `@/utils/request` 导入 axios 实例
|
||||
- 函数命名:`getXxxList`、`createXxx`、`updateXxx`、`deleteXxx`
|
||||
|
||||
#### 3.2 路由配置模板
|
||||
|
||||
```javascript
|
||||
// frontend/src/router/modules/{模块名}.js
|
||||
export default {
|
||||
path: '/{模块路径}',
|
||||
component: () => import('@/layout/index.vue'),
|
||||
redirect: '/{模块路径}/{默认子路由}',
|
||||
meta: { title: '{菜单名称}', icon: '{ElementPlus图标名}' },
|
||||
children: [
|
||||
{
|
||||
path: '{子路由}',
|
||||
name: '{路由名}',
|
||||
component: () => import('@/views/{模块路径}/{子路由}/index.vue'),
|
||||
meta: { title: '{页面标题}', icon: '{图标}', permission: '{权限码}' },
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.3 侧边栏与权限
|
||||
|
||||
- 侧边栏菜单从 `router/modules/` 下的路由配置自动生成,**不需要修改 Sidebar.vue**
|
||||
- 路由级权限:`meta.permission` 字段 + `filterRoutes()` 过滤无权限路由
|
||||
- 按钮级权限:`v-permission="'模块:资源:操作'"` 指令,无权限则隐藏元素
|
||||
|
||||
#### 3.4 Store 与工具
|
||||
|
||||
- **用户状态**:`store/user.js` — token、userInfo、权限列表,手动同步 localStorage
|
||||
- **应用状态**:`store/app.js` — 侧边栏折叠、设备类型
|
||||
- **HTTP 请求**:`utils/request.js` — Axios 封装,自动添加 Bearer Token,统一错误处理(401弹窗重新登录、403无权限、429限流、500服务异常)
|
||||
- **日期格式化**:`utils/index.js` 的 `formatDate()` 函数
|
||||
- **防抖**:`utils/index.js` 的 `debounce()` 函数
|
||||
|
||||
#### 3.5 样式约定
|
||||
|
||||
- 主题色:`#2d9d5e`(绿色系),通过 CSS 变量覆盖 Element Plus 默认主题
|
||||
- 布局变量:`--sidebar-width: 220px`,`--header-height: 56px`
|
||||
- 新页面样式使用 `<style scoped>`,全局样式放在 `styles/` 目录
|
||||
|
||||
### 四、禁止修改的文件清单
|
||||
|
||||
以下文件是公共注册文件或核心基础设施,多人同时修改会导致严重合并冲突,**绝对禁止修改**:
|
||||
|
||||
**后端:**
|
||||
- `app/api/__init__.py` — 路由自动注册
|
||||
- `app/models/__init__.py` — 模型自动注册
|
||||
- `app/services/__init__.py` — 服务自动注册
|
||||
- `app/schemas/response.py` — 通用响应格式
|
||||
- `app/core/` 目录下所有文件 — 核心基础设施(数据库、安全、中间件、缓存、依赖注入、配置)
|
||||
- `app/main.py` — 应用入口
|
||||
|
||||
**前端:**
|
||||
- `src/router/index.js` — 路由自动注册入口 + 守卫
|
||||
- `src/layout/` 目录下所有文件 — 布局组件(侧边栏、顶栏)
|
||||
- `src/utils/` 目录下所有文件 — 通用工具
|
||||
- `src/store/` 目录下所有文件 — 全局状态管理
|
||||
- `src/styles/` 目录下所有文件 — 全局样式
|
||||
- `src/main.js` — 应用入口
|
||||
|
||||
### 五、命名规范速查
|
||||
|
||||
| 层 | 文件名 | 类/变量名 | 数据库表名 |
|
||||
|----|--------|----------|-----------|
|
||||
| Model | `{模块名}.py` | `Sys{Entity}` | `sys_{entity}` |
|
||||
| Schema | `{模块名}.py` | `{Entity}CreateRequest` / `{Entity}UpdateRequest` | — |
|
||||
| Service | `{模块名}_service.py` | `{Entity}Service` | — |
|
||||
| API | `{模块名}.py` | `router = APIRouter(prefix="/模块/资源")` | — |
|
||||
| 权限编码 | — | `模块:资源:操作` | — |
|
||||
| 前端路由 | `modules/{模块名}.js` | `export default { path: '/模块路径', ... }` | — |
|
||||
| 前端API | `api/{模块名}.js` | `getXxxList` / `createXxx` / `updateXxx` / `deleteXxx` | — |
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 使用示例
|
||||
|
||||
假设你要开发一个"文章管理"模块,向 AI 提问时这样写:
|
||||
|
||||
> 请帮我开发一个"文章管理"功能模块,包含文章的增删改查,文章有标题、内容、分类、状态(草稿/发布)等字段。
|
||||
>
|
||||
> [粘贴上面的提示词内容]
|
||||
|
||||
AI 就会:
|
||||
- 创建 `backend/app/models/article.py`(不碰 models/__init__.py)
|
||||
- 创建 `backend/app/schemas/article.py`(独立文件)
|
||||
- 创建 `backend/app/services/article_service.py`(不碰 services/__init__.py)
|
||||
- 创建 `backend/app/api/article.py`(不碰 api/__init__.py)
|
||||
- 创建 `frontend/src/router/modules/article.js`(不碰 router/index.js)
|
||||
- 创建 `frontend/src/views/article/index.vue`
|
||||
- 创建 `frontend/src/api/article.js`
|
||||
|
||||
每个文件都是独立的,不同人开发不同模块,零冲突!
|
||||
|
||||
---
|
||||
|
||||
## 六、部署与启动注意事项
|
||||
|
||||
### 6.1 前端启动问题:根目录误装 node_modules
|
||||
|
||||
**问题描述:** 在项目根目录(`under18/`)下执行 `npm install` 会生成根目录的 `package.json`、`package-lock.json` 和 `node_modules/`,导致 `npx vite` 使用根目录的 Vite(版本可能不一致且依赖不完整)而非 `frontend/node_modules/` 中完整版本的 Vite,表现为 Vite 启动后所有请求返回 404。
|
||||
|
||||
**典型场景:** 在根目录安装全局依赖(如 `npm install echarts`)时误装到了根目录而非 `frontend/` 目录。
|
||||
|
||||
**正确做法:**
|
||||
- 前端依赖安装必须在 `frontend/` 目录下执行:`cd frontend && npm install xxx --save`
|
||||
- 启动前端时使用 frontend 自带的 Vite:`cd frontend && npx vite` 或 `cd frontend && node_modules/.bin/vite`
|
||||
- **禁止在项目根目录下执行 `npm install`**
|
||||
|
||||
**如已误装,清理方法:**
|
||||
```bash
|
||||
# 删除根目录下误装的文件
|
||||
rm package.json package-lock.json
|
||||
rm -rf node_modules/
|
||||
```
|
||||
|
||||
### 6.2 后端启动:PYTHONPATH 设置
|
||||
|
||||
**问题描述:** 直接在 `backend/` 目录执行 `uvicorn app.main:app` 可能报 `ModuleNotFoundError: No module named 'app'`,因为 Python 找不到 `app` 包。
|
||||
|
||||
**正确启动方式:**
|
||||
```bash
|
||||
cd backend
|
||||
set PYTHONPATH=c:\Users\hunter\Desktop\under18\backend # Windows
|
||||
# export PYTHONPATH=/path/to/under18/backend # Linux/Mac
|
||||
venv/Scripts/python.exe -m uvicorn app.main:app --host 127.0.0.1 --port 8000 --reload
|
||||
```
|
||||
|
||||
### 6.3 完整启动流程
|
||||
|
||||
**前置条件:**
|
||||
- 数据库使用远程 PostgreSQL(`config.yaml` 中配置的 `111.229.199.210:12345`),无需本地启动
|
||||
- Python 虚拟环境位于项目根目录 `venv/`
|
||||
- 前端依赖已安装在 `frontend/node_modules/`
|
||||
|
||||
**启动步骤:**
|
||||
```bash
|
||||
# 1. 启动后端
|
||||
cd c:\Users\hunter\Desktop\under18\backend
|
||||
set PYTHONPATH=c:\Users\hunter\Desktop\under18\backend
|
||||
c:\Users\hunter\Desktop\under18\venv\Scripts\python.exe -m uvicorn app.main:app --host 127.0.0.1 --port 8000 --reload
|
||||
|
||||
# 2. 启动前端(新终端)
|
||||
cd c:\Users\hunter\Desktop\under18\frontend
|
||||
npx vite --host 0.0.0.0 --port 5173
|
||||
# 或使用完整路径:node_modules\.bin\vite --host 0.0.0.0 --port 5173
|
||||
|
||||
# 3. 访问
|
||||
# 前端:http://localhost:5173
|
||||
# 后端API文档:http://127.0.0.1:8000/api/docs
|
||||
# 后端健康检查:http://127.0.0.1:8000/api/health
|
||||
```
|
||||
|
||||
### 6.4 生产构建
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npm run build # 输出到 frontend/dist/
|
||||
```
|
||||
|
||||
构建产物为静态文件,需配合 Nginx 等Web服务器部署,并配置 `/api` 反向代理到后端。
|
||||
488
gitHelp.md
Normal file
488
gitHelp.md
Normal file
@@ -0,0 +1,488 @@
|
||||
# Git 使用教程 — 从零开始配置项目仓库
|
||||
|
||||
> 本教程面向从未使用过 Git 的开发新手,手把手带你完成环境配置、项目拉取和日常开发协作。
|
||||
> 每一步都会解释**为什么要这样做**,让你不仅知道"怎么做",更理解"为什么"。
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
|
||||
1. [什么是 Git?— 通俗理解](#1-什么是-git--通俗理解)
|
||||
2. [全局配置:告诉 Git 你是谁](#2-全局配置告诉-git-你是谁)
|
||||
3. [解决 SSL 证书验证失败问题](#3-解决-ssl-证书验证失败问题)
|
||||
4. [克隆项目到本地](#4-克隆项目到本地)
|
||||
5. [在 VSCode 中打开项目](#5-在-vscode-中打开项目)
|
||||
6. [日常开发工作流](#6-日常开发工作流)
|
||||
- 6.1 [创建分支 — 在自己的"工作间"干活](#61-创建分支--在自己的工作间干活)
|
||||
- 6.2 [提交到本地仓库 — 给作品"存档"](#62-提交到本地仓库--给作品存档)
|
||||
- 6.3 [推送到远程仓库 — 把作品"上交"](#63-推送到远程仓库--把作品上交)
|
||||
- 6.4 [拉取远程仓库 — 同步别人的"最新作品"](#64-拉取远程仓库--同步别人的最新作品)
|
||||
- 6.5 [合并分支 — 把你的工作成果"合进主线"](#65-合并分支--把你的工作成果合进主线)
|
||||
7. [VSCode 中的图形化 Git 操作](#7-vscode-中的图形化-git-操作)
|
||||
8. [常见问题与解决方案](#8-常见问题与解决方案)
|
||||
9. [Git 命令速查表](#9-git-命令速查表)
|
||||
|
||||
---
|
||||
|
||||
## 1. 什么是 Git?— 通俗理解
|
||||
|
||||
想象你在写一份很重要的报告:
|
||||
|
||||
- **没有 Git 的世界**:你每次修改都覆盖原文件,改坏了就回不去了。为了保险,你手动复制备份——`报告_v1.doc`、`报告_v2.doc`、`报告_最终版.doc`、`报告_最终版2.doc`……最后自己都分不清哪个是哪个。
|
||||
- **有 Git 的世界**:Git 就像一个**超级存档系统**,每次你改完代码,告诉它"存个档",它就帮你拍一张快照。你可以随时回到任何一个历史存档点,还能看到每次改了什么、谁改的。
|
||||
|
||||
**几个核心概念(比喻版):**
|
||||
|
||||
| 概念 | 比喻 | 说明 |
|
||||
|------|------|------|
|
||||
| **仓库 (Repository)** | 项目文件夹的"存档箱" | 存放项目所有文件和完整历史记录 |
|
||||
| **分支 (Branch)** | 平行宇宙 / 独立工作间 | 你可以在自己的工作间随便折腾,不影响别人 |
|
||||
| **提交 (Commit)** | 存档 / 快照 | 记录"这次我改了什么",形成一个历史节点 |
|
||||
| **推送 (Push)** | 上交作业 | 把你本地的存档同步到服务器上 |
|
||||
| **拉取 (Pull)** | 拿最新资料 | 把服务器上别人的最新改动同步到你本地 |
|
||||
| **合并 (Merge)** | 汇总工作成果 | 把不同分支的改动合到一起 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 全局配置:告诉 Git 你是谁
|
||||
|
||||
> **为什么?** 每次你提交代码时,Git 会记录"这是谁提交的"。就像你在文件上签名一样,别人一看就知道这个修改是你做的。
|
||||
|
||||
打开 **VSCode**,按 `` Ctrl + ` `` (反引号,键盘左上角 Esc 下面)打开终端,依次输入:
|
||||
|
||||
### 2.1 配置用户名
|
||||
|
||||
```bash
|
||||
git config --global user.name "你的用户名"
|
||||
```
|
||||
|
||||
各成员对应:
|
||||
|
||||
| 姓名 | 用户名 |
|
||||
|------|--------|
|
||||
| ly | `ly` |
|
||||
| zb | `zb` |
|
||||
| dw | `dw` |
|
||||
| lyj | `lyj` |
|
||||
| lyq | `lyq` |
|
||||
|
||||
例如 ly 执行:
|
||||
```bash
|
||||
git config --global user.name "ly"
|
||||
```
|
||||
|
||||
### 2.2 配置邮箱
|
||||
|
||||
```bash
|
||||
git config --global user.email "你的邮箱"
|
||||
```
|
||||
|
||||
各成员对应:
|
||||
|
||||
| 姓名 | 邮箱 |
|
||||
|------|------|
|
||||
| ly | `ly@szga.com` |
|
||||
| zb | `zb@szga.com` |
|
||||
| dw | `dw@szga.com` |
|
||||
| lyj | `lyj@szga.com` |
|
||||
| lyq | `lyq@szga.com` |
|
||||
|
||||
例如 ly 执行:
|
||||
```bash
|
||||
git config --global user.email "ly@szga.com"
|
||||
```
|
||||
|
||||
### 2.3 验证配置是否成功
|
||||
|
||||
```bash
|
||||
git config --global --list
|
||||
```
|
||||
|
||||
你应该能看到类似输出:
|
||||
```
|
||||
user.name=ly
|
||||
user.email=ly@szga.com
|
||||
```
|
||||
|
||||
> 这两行信息说明 Git 已经知道你的身份了,以后每次提交代码都会自动附上你的"签名"。
|
||||
|
||||
---
|
||||
|
||||
## 3. 关闭 SSL 验证
|
||||
|
||||
> ```bash
|
||||
> git config --global http."https://111.229.199.210/".sslVerify false
|
||||
> ```
|
||||
> 这样只有访问我们内部服务器时才跳过验证,其他网址照常检查。
|
||||
|
||||
### 3.1 保存凭据(避免每次输入密码)
|
||||
|
||||
```bash
|
||||
git config --global credential.helper store
|
||||
```
|
||||
|
||||
> **为什么?** 默认情况下,每次推送/拉取代码都要输入用户名和密码,非常麻烦。这条命令让 Git 把你的账号密码保存在本地,输入一次以后就不用再输了。就像浏览器"记住密码"功能一样。
|
||||
|
||||
---
|
||||
|
||||
## 4. 克隆项目到本地
|
||||
|
||||
> **为什么?** "克隆"就是把服务器上的整个项目(包括所有文件和完整历史记录)下载到你自己的电脑上。就像把一份完整的项目档案复制到你的办公桌上,你可以在本地随意修改,不会影响服务器上的版本。
|
||||
|
||||
### 4.1 选择存放位置
|
||||
|
||||
先决定你想把项目放在哪个目录,比如 `D:\projects\`。如果目录不存在,先创建:
|
||||
|
||||
```bash
|
||||
mkdir D:\projects
|
||||
cd D:\projects
|
||||
```
|
||||
|
||||
### 4.2 执行克隆
|
||||
|
||||
```bash
|
||||
git clone https://111.229.199.210/hunter/under18.git
|
||||
```
|
||||
|
||||
此时会弹出登录窗口或提示输入用户名密码:
|
||||
|
||||
- **Username**:输入你的用户名(如 `ly`)
|
||||
- **Password**:输入你的密码(如 `ly110110`)
|
||||
|
||||
> 密码输入时屏幕不会显示任何字符,这是正常的安全设计,直接输完按回车即可。
|
||||
|
||||
克隆完成后,你会看到:
|
||||
|
||||
```
|
||||
Cloning into 'under18'...
|
||||
remote: Enumerating objects: ...
|
||||
Receiving objects: 100% done
|
||||
```
|
||||
|
||||
### 4.3 进入项目目录
|
||||
|
||||
```bash
|
||||
cd under18
|
||||
```
|
||||
|
||||
> 至此,项目已经完整下载到你的电脑了!你可以用 `dir` 命令看看项目里有什么文件。
|
||||
|
||||
---
|
||||
|
||||
## 5. 在 VSCode 中打开项目
|
||||
|
||||
1. 打开 VSCode
|
||||
2. 点击菜单 **文件 → 打开文件夹**
|
||||
3. 选择刚才克隆下来的 `under18` 文件夹(如 `D:\projects\under18`)
|
||||
4. 点击 **选择文件夹**
|
||||
|
||||
> **为什么打开文件夹而不是单个文件?** VSCode 以文件夹为单位管理项目,打开整个文件夹后,左侧资源管理器会显示完整的项目结构,Git 功能也会自动生效。
|
||||
|
||||
打开后,点击左侧活动栏的 **源代码管理** 图标(看起来像分支的图标,或按 `Ctrl+Shift+G`),你应该能看到 Git 已经识别到这个仓库了。
|
||||
|
||||
---
|
||||
|
||||
## 6. 日常开发工作流
|
||||
|
||||
> 日常开发的基本节奏就是:**建分支 → 写代码 → 提交 → 推送**,就像:开自己的工作间 → 干活 → 存档 → 上交。
|
||||
|
||||
### 6.1 创建分支 — 在自己的"工作间"干活
|
||||
|
||||
> **为什么需要分支?** 想象 `main` 分支是项目的"主展厅",展示的是当前最稳定的版本。如果大家都直接在主展厅里施工,互相干扰不说,还可能把展厅搞塌。所以每人开一个"独立工作间"(分支),在自己的工作间里随便折腾,搞好了再把成果搬到主展厅。
|
||||
|
||||
#### 查看当前在哪个分支
|
||||
|
||||
```bash
|
||||
git branch
|
||||
```
|
||||
|
||||
输出中带 `*` 的是你当前所在的分支:
|
||||
```
|
||||
* main
|
||||
```
|
||||
|
||||
#### 创建并切换到新分支
|
||||
|
||||
```bash
|
||||
git checkout -b 你的分支名
|
||||
```
|
||||
|
||||
**分支命名建议**:用 `功能/描述` 或 `修复/描述` 的格式,例如:
|
||||
```bash
|
||||
git checkout -b feature/login-page # 开发登录页面功能
|
||||
git checkout -b fix/header-bug # 修复头部bug
|
||||
git checkout -b feature/user-manage # 开发用户管理功能
|
||||
```
|
||||
|
||||
> **比喻**:`checkout -b` 就像在说"给我开一间叫 xxx 的新工作间,我要进去了"。从此你的所有修改都在这个独立空间里,不会动到主展厅。
|
||||
|
||||
#### 切换回已有分支
|
||||
|
||||
```bash
|
||||
git checkout main # 切回主分支
|
||||
git checkout feature/login # 切回你的功能分支
|
||||
```
|
||||
|
||||
> **注意**:切换分支前,确保当前分支的改动已经提交(存档),否则 Git 可能会阻止你切换,或者把未提交的改动带到另一个分支。
|
||||
|
||||
---
|
||||
|
||||
### 6.2 提交到本地仓库 — 给作品"存档"
|
||||
|
||||
> **为什么?** 提交(Commit)就像游戏里的"存档"。你写了一段代码,觉得可以了,就存个档。如果后面改坏了,可以随时回到这个存档点。**不存档的改动,关机就没了!**
|
||||
|
||||
#### 第一步:查看你改了什么
|
||||
|
||||
```bash
|
||||
git status
|
||||
```
|
||||
|
||||
你会看到哪些文件被修改了、新增了、删除了。红色表示还没加入暂存区,绿色表示已加入暂存区。
|
||||
|
||||
> **什么是暂存区?** 提交分两步:先把要提交的文件放进"暂存区"(像购物车),再统一"结账"(提交)。这样可以让你精确控制哪些改动要提交,哪些暂时不提交。
|
||||
|
||||
#### 第二步:添加到暂存区
|
||||
|
||||
添加所有改动:
|
||||
```bash
|
||||
git add .
|
||||
```
|
||||
|
||||
或者只添加某个文件:
|
||||
```bash
|
||||
git add backend/app/core/config.py
|
||||
```
|
||||
|
||||
> `git add .` 中的 `.` 代表当前目录下所有改动,这是最常用的方式。就像把购物车里塞满你要买的东西。
|
||||
|
||||
#### 第三步:提交
|
||||
|
||||
```bash
|
||||
git commit -m "简要描述你做了什么"
|
||||
```
|
||||
|
||||
例如:
|
||||
```bash
|
||||
git commit -m "feat: 添加用户列表页面"
|
||||
git commit -m "fix: 修复登录页面样式问题"
|
||||
git commit -m "docs: 更新README文档"
|
||||
```
|
||||
|
||||
**提交信息规范**(建议但不强制):
|
||||
|
||||
| 前缀 | 含义 | 示例 |
|
||||
|------|------|------|
|
||||
| `feat:` | 新功能 | `feat: 添加导出功能` |
|
||||
| `fix:` | 修复bug | `fix: 修复分页错误` |
|
||||
| `docs:` | 文档修改 | `docs: 更新API文档` |
|
||||
| `style:` | 样式调整 | `style: 调整按钮间距` |
|
||||
| `refactor:` | 重构 | `refactor: 优化查询逻辑` |
|
||||
|
||||
> **比喻**:`commit` 就是在说"把这些改动存个档,备注写 xxx"。以后随时可以翻看这个存档记录。
|
||||
|
||||
---
|
||||
|
||||
### 6.3 推送到远程仓库 — 把作品"上交"
|
||||
|
||||
> **为什么?** 提交只是存在你本地电脑上,别人看不到。推送(Push)就是把你的存档同步到服务器,这样团队成员就能看到你的最新代码了。就像你写完作业要"上交"一样,不交老师看不到。
|
||||
|
||||
```bash
|
||||
git push origin 你的分支名
|
||||
```
|
||||
|
||||
例如:
|
||||
```bash
|
||||
git push origin feature/login-page
|
||||
```
|
||||
|
||||
**第一次推送新分支时**,需要加 `-u` 参数建立追踪关系:
|
||||
```bash
|
||||
git push -u origin feature/login-page
|
||||
```
|
||||
|
||||
> 加了 `-u` 后,以后在这个分支上只需要 `git push` 就行了,不用再写完整的命令。就像第一次去快递站要登记地址,以后直接报手机号就行。
|
||||
|
||||
---
|
||||
|
||||
### 6.4 拉取远程仓库 — 同步别人的"最新作品"
|
||||
|
||||
> **为什么?** 其他人也在写代码并推送到服务器。如果别人更新了 `main` 分支,你本地的 `main` 还是旧的,就需要"拉取"来同步。就像你的文件夹是昨天的版本,需要去档案室拿最新版来更新。
|
||||
|
||||
#### 方式一:pull(拉取并合并,推荐新手使用)
|
||||
|
||||
```bash
|
||||
git checkout main # 先切到 main 分支
|
||||
git pull origin main # 拉取远程 main 的最新代码
|
||||
```
|
||||
|
||||
#### 方式二:定期同步到你自己的功能分支
|
||||
|
||||
当你开发到一半,想同步 main 分支的最新改动到你的功能分支:
|
||||
|
||||
```bash
|
||||
git checkout feature/login-page # 切到你的功能分支
|
||||
git pull origin main # 把 main 的最新改动拉下来并合并
|
||||
```
|
||||
|
||||
> **注意**:拉取前确保你当前分支的改动已经提交,否则可能产生冲突。
|
||||
|
||||
---
|
||||
|
||||
### 6.5 合并分支 — 把你的工作成果"合进主线"
|
||||
|
||||
> **为什么?** 你在功能分支上开发完了,需要把成果合并到 main 分支,这样大家才能看到你的新功能。就像你在自己的工作间做完了产品,要搬到主展厅展示。
|
||||
|
||||
#### 步骤
|
||||
|
||||
```bash
|
||||
git checkout main # 1. 先切到 main 分支
|
||||
git pull origin main # 2. 先拉取最新的 main(确保是最新的)
|
||||
git merge feature/login-page # 3. 把你的功能分支合并进来
|
||||
git push origin main # 4. 推送到远程服务器
|
||||
```
|
||||
|
||||
> **合并冲突怎么办?** 如果两个人改了同一个文件的同一行,Git 不知道该听谁的,就会报"冲突"。此时需要手动打开冲突文件,选择保留哪个版本,然后重新 `add → commit → push`。冲突文件里会有这样的标记:
|
||||
> ```
|
||||
> <<<<<<< HEAD
|
||||
> 你当前分支的代码
|
||||
> =======
|
||||
> 对方分支的代码
|
||||
> >>>>>>> feature/login-page
|
||||
> ```
|
||||
> 删掉不需要的部分和标记符号,保留正确的代码即可。
|
||||
|
||||
#### 合并完成后删除功能分支(可选)
|
||||
|
||||
```bash
|
||||
git branch -d feature/login-page # 删除本地分支
|
||||
```
|
||||
|
||||
> 就像工作间用完了可以拆掉,保持工作区整洁。
|
||||
|
||||
---
|
||||
|
||||
## 7. VSCode 中的图形化 Git 操作
|
||||
|
||||
> 不习惯命令行?VSCode 提供了图形化界面,鼠标点点就能完成大部分操作。
|
||||
|
||||
### 7.1 源代码管理面板
|
||||
|
||||
按 `Ctrl+Shift+G` 打开源代码管理面板:
|
||||
|
||||
- **修改的文件**:点击文件名可以查看具体改了什么(绿色=新增,红色=删除,蓝色=修改)
|
||||
- **暂存**:点击文件旁边的 `+` 号 = `git add`
|
||||
- **取消暂存**:点击已暂存文件旁边的 `-` 号 = `git reset HEAD`
|
||||
- **提交**:在上方输入框写提交信息,点击 ✓ 按钮 = `git commit -m "..."`
|
||||
- **撤销修改**:点击文件旁边的 ↩ 按钮 = 丢弃未暂存的改动(**慎用,改了就回不去了!**)
|
||||
|
||||
### 7.2 分支操作
|
||||
|
||||
点击 VSCode 左下角的 **分支名**(如 `main`),可以:
|
||||
|
||||
- **创建新分支** → 选择"创建新分支" → 输入分支名
|
||||
- **切换分支** → 从列表中选择要切换的分支
|
||||
- **删除分支** → 选择要删除的分支
|
||||
|
||||
### 7.3 推送和拉取
|
||||
|
||||
- **推送**:点击源代码管理面板上方的 `...` → 推送,或点击左下角分支名旁边的 ↕ 同步按钮
|
||||
- **拉取**:点击 `...` → 拉取
|
||||
|
||||
---
|
||||
|
||||
## 8. 常见问题与解决方案
|
||||
|
||||
### Q1:`SSL certificate problem: self signed certificate`
|
||||
|
||||
```
|
||||
fatal: unable to access '...': SSL certificate problem: self signed certificate
|
||||
```
|
||||
|
||||
**原因**:自签名证书不被信任。
|
||||
|
||||
**解决**:
|
||||
```bash
|
||||
git config --global http.sslVerify false
|
||||
```
|
||||
或只针对我们的服务器:
|
||||
```bash
|
||||
git config --global http."https://111.229.199.210/".sslVerify false
|
||||
```
|
||||
|
||||
### Q2:每次 push/pull 都要输入密码
|
||||
|
||||
**解决**:
|
||||
```bash
|
||||
git config --global credential.helper store
|
||||
```
|
||||
然后再推送一次,输入密码后就会被记住。
|
||||
|
||||
### Q3:`fatal: not a git repository`
|
||||
|
||||
**原因**:你不在 Git 仓库目录中。
|
||||
|
||||
**解决**:先 `cd` 到项目目录(包含 `.git` 文件夹的目录)再执行 Git 命令。
|
||||
|
||||
### Q4:`error: failed to push some refs`
|
||||
|
||||
```
|
||||
! [rejected] main -> main (fetch first)
|
||||
```
|
||||
|
||||
**原因**:远程有别人推送的新代码,你本地不是最新的。
|
||||
|
||||
**解决**:先拉取再推送:
|
||||
```bash
|
||||
git pull origin main
|
||||
git push origin main
|
||||
```
|
||||
|
||||
### Q5:提交错了想撤回
|
||||
|
||||
只撤回上一次提交(代码改动保留):
|
||||
```bash
|
||||
git reset --soft HEAD~1
|
||||
```
|
||||
|
||||
丢弃上一次提交和改动(**危险!改了就没了**):
|
||||
```bash
|
||||
git reset --hard HEAD~1
|
||||
```
|
||||
|
||||
### Q6:合并冲突了怎么办
|
||||
|
||||
1. 打开冲突文件,看到 `<<<<<<<`、`=======`、`>>>>>>>` 标记
|
||||
2. 手动选择保留哪段代码,删除标记符号
|
||||
3. 保存文件后:
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "fix: 解决合并冲突"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Git 命令速查表
|
||||
|
||||
| 操作 | 命令 | 说明 |
|
||||
|------|------|------|
|
||||
| 克隆项目 | `git clone 地址` | 首次下载项目 |
|
||||
| 查看状态 | `git status` | 看哪些文件改了 |
|
||||
| 添加到暂存区 | `git add .` | 把所有改动加入暂存区 |
|
||||
| 提交 | `git commit -m "描述"` | 存档并写备注 |
|
||||
| 推送 | `git push origin 分支名` | 上传到服务器 |
|
||||
| 拉取 | `git pull origin 分支名` | 下载服务器最新代码 |
|
||||
| 创建+切换分支 | `git checkout -b 分支名` | 开新工作间 |
|
||||
| 切换分支 | `git checkout 分支名` | 换工作间 |
|
||||
| 合并分支 | `git merge 分支名` | 把指定分支合并到当前分支 |
|
||||
| 查看分支列表 | `git branch` | 看有哪些工作间 |
|
||||
| 删除分支 | `git branch -d 分支名` | 拆掉工作间 |
|
||||
| 查看提交历史 | `git log --oneline` | 查看存档记录 |
|
||||
| 撤销未暂存的修改 | `git checkout -- 文件名` | 恢复到上次提交的状态 |
|
||||
|
||||
---
|
||||
|
||||
> **最后提醒**:
|
||||
> - **勤提交**:写完一个功能点就提交一次,别攒一大堆再提交,方便出问题时回溯
|
||||
> - **写清楚提交信息**:别写"update"或"fix",要写具体改了什么,比如"fix: 修复用户列表搜索无响应问题"
|
||||
> - **推送前先拉取**:推送 main 分支前先 `git pull`,避免冲突
|
||||
> - **有疑问随时问**:Git 操作失误可以恢复(几乎所有操作都可以撤销),不用害怕
|
||||
BIN
安装codebuddy插件示意图.png
Normal file
BIN
安装codebuddy插件示意图.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 124 KiB |
BIN
打开文件夹-1.png
Normal file
BIN
打开文件夹-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
BIN
打开文件夹-2.png
Normal file
BIN
打开文件夹-2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 63 KiB |
BIN
用glm5.1开发示意图.png
Normal file
BIN
用glm5.1开发示意图.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 105 KiB |
Reference in New Issue
Block a user