Skip to content

章节4:结业项目实战


学习目标

完成本章学习后,你将能够:

  1. 独立完成 B2C 电商平台的全栈开发(Vue3 + Django + DRF + MySQL + Redis + Docker)
  2. 独立完成企业 OA 办公管理系统的全栈开发
  3. 掌握大型项目的架构方法论、模块拆分与团队协作
  4. 完成从需求到上线的全流程实战

4.1 项目一:B2C 电商平台

4.1.1 项目概述

项目说明
项目名称EShop —— B2C 电商平台
技术栈Vue3 + TypeScript + Element Plus + Django + DRF + MySQL + Redis + Docker
目标用户普通消费者 + 平台运营管理员
核心功能用户系统、商品浏览搜索、购物车、下单支付、后台管理、数据统计

4.1.2 完整项目架构

bash
eshop/
├── frontend/                          # 前端项目(Vue3 + TypeScript)
   ├── public/
   └── favicon.ico
   ├── src/
   ├── api/                       # API 接口层
   ├── request.ts             # Axios 实例(拦截器/Token/错误处理)
   ├── user.ts                # 用户相关接口
   ├── product.ts             # 商品相关接口
   ├── cart.ts                # 购物车接口
   ├── order.ts               # 订单接口
   ├── payment.ts             # 支付接口
   └── admin.ts               # 后台管理接口
   ├── assets/                    # 静态资源(样式/图片/图标)
   ├── styles/
   ├── global.scss         # 全局样式
   ├── variables.scss      # SCSS 变量
   └── mixins.scss         # SCSS 混入
   └── images/
   ├── components/                # 公共组件
   ├── AppHeader.vue          # 顶部导航栏
   ├── AppFooter.vue          # 底部信息
   ├── ProductCard.vue        # 商品卡片
   ├── CategoryMenu.vue       # 分类菜单
   ├── SearchBar.vue          # 搜索栏
   ├── Loading.vue            # 加载状态
   └── EmptyState.vue         # 空状态占位
   ├── composables/               # 组合式函数(Composables)
   ├── useAuth.ts             # 认证状态
   ├── useCart.ts             # 购物车逻辑
   ├── usePagination.ts       # 分页逻辑
   └── usePermission.ts       # 权限检查
   ├── layouts/                   # 布局组件
   ├── MainLayout.vue         # 前台主布局
   ├── AdminLayout.vue        # 后台管理布局
   └── AuthLayout.vue         # 登录注册布局
   ├── router/                    # 路由配置
   ├── index.ts               # 路由实例
   ├── routes.ts              # 路由表
   └── guards.ts              # 路由守卫(鉴权/重定向)
   ├── stores/                    # Pinia 状态管理
   ├── user.ts               # 用户状态
   ├── cart.ts               # 购物车状态
   └── app.ts                # 应用级状态
   ├── types/                     # TypeScript 类型定义
   ├── user.d.ts
   ├── product.d.ts
   ├── order.d.ts
   └── api.d.ts              # 统一响应类型
   ├── utils/                     # 工具函数
   ├── format.ts              # 格式化(金额/时间)
   ├── storage.ts             # 本地存储封装
   └── validate.ts            # 表单校验
   ├── views/                     # 页面组件
   ├── home/                  # 首页
   ├── HomeView.vue
   └── components/
       ├── BannerCarousel.vue    # 轮播图
       ├── HotProducts.vue       # 热销商品
       └── NewArrivals.vue       # 新品上架
   ├── product/               # 商品
   ├── ListView.vue       # 商品列表页
   ├── DetailView.vue     # 商品详情页
   └── components/
       ├── ProductFilter.vue     # 筛选面板
       ├── ProductGallery.vue    # 商品图库
       └── ProductReviews.vue    # 用户评价
   ├── cart/                  # 购物车
   ├── CartView.vue
   └── components/
       └── CartItem.vue          # 购物车项
   ├── order/                 # 订单
   ├── ConfirmView.vue    # 确认订单
   ├── ListView.vue       # 订单列表
   ├── DetailView.vue     # 订单详情
   └── components/
       └── OrderStatus.vue       # 状态时间线
   ├── payment/               # 支付
   └── PayView.vue        # 支付页面
   ├── user/                  # 用户
   ├── LoginView.vue
   ├── RegisterView.vue
   ├── ProfileView.vue
   └── AddressView.vue
   └── admin/                 # 后台管理
       ├── DashboardView.vue  # 控制台
       ├── ProductManage.vue  # 商品管理
       ├── OrderManage.vue    # 订单管理
       ├── UserManage.vue     # 用户管理
       └── StatsView.vue      # 数据统计
   ├── App.vue
   └── main.ts
   ├── .env.development               # 开发环境变量
   ├── .env.production                # 生产环境变量
   ├── .eslintrc.cjs
   ├── tsconfig.json
   ├── vite.config.ts
   └── package.json

├── backend/                           # 后端项目(Django + DRF)
   ├── apps/
   ├── user/                      # 用户模块
   ├── __init__.py
   ├── admin.py
   ├── models.py              # User / Address
   ├── serializers.py         # Register / Login / Profile
   ├── views.py               # RegisterView / LoginView / ProfileView
   ├── urls.py
   ├── permissions.py         # IsOwnerOrAdmin
   └── tests.py
   ├── product/                   # 商品模块
   ├── __init__.py
   ├── admin.py
   ├── models.py              # Category / Product / ProductImage
   ├── serializers.py
   ├── views.py               # CategoryViewSet / ProductViewSet
   ├── filters.py             # 自定义过滤器
   ├── urls.py
   └── tests.py
   ├── cart/                      # 购物车模块
   ├── __init__.py
   ├── models.py              # CartItem
   ├── serializers.py
   ├── views.py               # CartViewSet
   └── tests.py
   ├── order/                     # 订单模块
   ├── __init__.py
   ├── models.py              # Order / OrderItem
   ├── serializers.py
   ├── views.py               # OrderViewSet
   ├── services.py            # OrderService(下单事务逻辑)
   ├── signals.py             # 订单状态变更信号
   ├── urls.py
   └── tests.py
   ├── payment/                   # 支付模块
   ├── __init__.py
   ├── models.py              # Payment
   ├── services/
   ├── alipay.py           # 支付宝SDK封装
   └── wechat.py           # 微信支付SDK封装
   ├── views.py               # PayView / AlipayNotifyView
   ├── urls.py
   └── tests.py
   └── admin/                     # 后台管理模块
       ├── __init__.py
       ├── views.py               # StatsView / DashboardView
       ├── serializers.py
       └── urls.py
   ├── config/                        # 项目配置
   ├── __init__.py
   ├── settings/
   ├── base.py                # 公共配置
   ├── dev.py                 # 开发环境
   └── prod.py                # 生产环境
   ├── urls.py                    # 根路由
   ├── wsgi.py
   ├── asgi.py
   └── celery.py                  # Celery 配置
   ├── utils/                         # 公共工具
   ├── exceptions.py              # 自定义异常
   ├── middleware.py              # 自定义中间件
   ├── pagination.py              # 分页
   ├── response.py                # 统一响应
   └── cache.py                   # Redis 缓存工具
   ├── scripts/                       # 管理脚本
   ├── init_data.py               # 初始化测试数据
   └── seed.py                    # 种子数据
   ├── Dockerfile
   ├── manage.py
   ├── requirements.txt
   ├── .pylintrc
   └── gunicorn.conf.py

├── nginx/
   └── nginx.conf                     # Nginx 反向代理配置
├── docker-compose.yml                 # 容器编排
├── .env                               # 环境变量(不提交 Git)
├── .env.example                       # 环境变量模板
├── .gitignore
├── README.md                          # 项目说明文档
└── locustfile.py                      # 性能压测

4.1.3 数据库 E-R 总图

┌───────────┐     ┌──────────────┐     ┌──────────────┐
│   User    │1──N │   CartItem   │1──1 │   Product    │
└───────────┘     └──────────────┘     └──────────────┘
     │                                      │
     │1                                     │N
     │                                      │
     │   ┌───────────┐     ┌──────────────┐ │
     ├──N│  Address  │     │  OrderItem   │N│
     │   └───────────┘     └──────┬───────┘ │
     │                            │         │
     │1                           │N        │
     ├────────────────────────────┤         │
     │                            │         │
     │   ┌───────────┐            │         │
     └──N│  Order    │1──────────N┘         │
         └─────┬─────┘                      │
               │1                           │
               │                            │
         ┌─────┴─────┐              ┌───────┴──────┐
         │  Payment  │              │  Category    │
         └───────────┘              └──────────────┘

                                    1─────N─────┐
                                          │     │
                                     ┌────┴──────┐
                                     │  Product   │
                                     └───────────┘

4.1.4 核心业务流程

┌──────────────────────────────────────────────────────────────┐
│                    用户购物完整流程                            │
│                                                              │
│  ① 注册登录 ──→ ② 浏览商品 ──→ ③ 加入购物车                  │
│                      │                                         │
│                      ▼                                        │
│  ④ 选择地址 ──→ ⑤ 确认下单 ──→ ⑥ 选择支付方式                 │
│                      │                                         │
│                      ▼                                        │
│  ⑦ 扫码支付 ──→ ⑧ 支付回调 ──→ ⑨ 查看订单状态                │
│                      │                                         │
│                      ▼                                        │
│  ⑩ 确认收货 ──→ ⑪ 评价商品 ──→ 完成                          │
└──────────────────────────────────────────────────────────────┘

4.1.5 技术亮点总结

模块技术亮点
前端Composition API + TypeScript、Pinia 状态管理、路由守卫鉴权、Axios 拦截器统一错误处理
后端DRF ViewSet + Serializer、JWT 无状态认证、RBAC 权限控制、django-filter 动态筛选
数据库MySQL 8.0 + utf8mb4、外键与索引优化、Fulltext 全文索引、事务原子性下单
缓存Redis 缓存热门商品/分类树、Session 替代、Celery 异步任务(短信/邮件)
部署Docker 多阶段构建、Nginx 动静分离、Gunicorn + Gevent 高性能部署

4.2 项目二:企业 OA 办公管理系统

4.2.1 项目概述

项目说明
项目名称EasyOA —— 企业办公管理系统
技术栈Vue3 + Element Plus + Django + DRF + MySQL + Redis + Docker
目标用户企业员工、部门主管、系统管理员
核心功能组织架构管理、考勤打卡、审批流程、公告通知、日程管理

4.2.2 完整项目架构

bash
easyoa/
├── frontend/
   ├── src/
   ├── api/
   ├── request.ts
   ├── auth.ts                # 认证
   ├── department.ts          # 部门
   ├── employee.ts            # 员工
   ├── attendance.ts          # 考勤
   ├── approval.ts            # 审批
   ├── notice.ts              # 公告
   └── schedule.ts            # 日程
   ├── components/
   ├── OrgTree.vue            # 组织架构树
   ├── ApprovalTimeline.vue   # 审批时间线
   ├── CalendarView.vue       # 日历组件
   └── FileUploader.vue       # 文件上传
   ├── views/
   ├── dashboard/             # 工作台
   ├── organization/          # 组织架构
   ├── attendance/            # 考勤管理
   ├── approval/              # 审批中心
   ├── notice/                # 公告管理
   └── system/                # 系统设置
   └── ...
   └── Dockerfile

├── backend/
   ├── apps/
   ├── organization/              # 组织架构模块
   ├── models.py              # Department / Employee
   ├── views.py               # DepartmentViewSet / EmployeeViewSet
   └── serializers.py
   ├── attendance/                # 考勤模块
   ├── models.py              # AttendanceRecord / LeaveRequest
   ├── views.py
   └── serializers.py
   ├── approval/                  # 审批模块
   ├── models.py              # ApprovalRequest / ApprovalNode
   ├── views.py
   └── serializers.py
   ├── notice/                    # 公告模块
   ├── models.py              # Notice
   ├── views.py
   └── serializers.py
   └── system/                    # 系统管理
       ├── models.py              # SystemConfig / OperationLog
       ├── views.py
       └── serializers.py
   └── ...
├── docker-compose.yml
└── README.md

4.2.3 OA 核心数据模型

python
# ===== 组织架构 =====
class Department(models.Model):
    name = models.CharField(max_length=64, verbose_name="部门名称")
    parent = models.ForeignKey(
        'self', on_delete=models.CASCADE, null=True, blank=True,
        related_name='children'
    )
    manager = models.ForeignKey(
        'Employee', on_delete=models.SET_NULL, null=True, blank=True,
        related_name='managed_dept', verbose_name="部门负责人"
    )
    sort_order = models.IntegerField(default=0)

    class Meta:
        db_table = 'oa_department'


class Employee(models.Model):
    """员工信息(继承 User 或一对一关联)"""
    user = models.OneToOneField('user.User', on_delete=models.CASCADE)
    department = models.ForeignKey(
        Department, on_delete=models.CASCADE, related_name='employees'
    )
    position = models.CharField(max_length=64, verbose_name="职位")
    employee_no = models.CharField(max_length=32, unique=True, verbose_name="工号")
    hire_date = models.DateField(verbose_name="入职日期")
    is_active = models.BooleanField(default=True)


# ===== 考勤 =====
class AttendanceRecord(models.Model):
    employee = models.ForeignKey(Employee, on_delete=models.CASCADE)
    date = models.DateField(auto_now_add=True)
    check_in_time = models.DateTimeField(null=True, blank=True, verbose_name="上班打卡")
    check_out_time = models.DateTimeField(null=True, blank=True, verbose_name="下班打卡")
    status = models.CharField(max_length=20, choices=[
        ('normal', '正常'), ('late', '迟到'),
        ('early', '早退'), ('absent', '缺勤'),
    ], default='normal')


# ===== 审批流程 =====
class ApprovalRequest(models.Model):
    """审批请求"""
    employee = models.ForeignKey(Employee, on_delete=models.CASCADE, verbose_name="申请人")
    category = models.CharField(max_length=32, choices=[
        ('leave', '请假'), ('expense', '报销'),
        ('purchase', '采购'), ('overtime', '加班'),
    ])
    title = models.CharField(max_length=256)
    content = models.JSONField(verbose_name="申请内容(根据类型不同)")
    status = models.CharField(max_length=20, choices=[
        ('pending', '审批中'), ('approved', '已通过'),
        ('rejected', '已驳回'), ('cancelled', '已撤回'),
    ], default='pending')
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = 'oa_approval_request'


class ApprovalNode(models.Model):
    """审批节点(支持多级审批)"""
    request = models.ForeignKey(
        ApprovalRequest, on_delete=models.CASCADE, related_name='nodes'
    )
    reviewer = models.ForeignKey(Employee, on_delete=models.CASCADE, verbose_name="审批人")
    level = models.IntegerField(default=1, verbose_name="审批层级")
    status = models.CharField(max_length=20, choices=[
        ('pending', '待审批'), ('approved', '已通过'), ('rejected', '已驳回')
    ], default='pending')
    comment = models.TextField(blank=True, verbose_name="审批意见")
    reviewed_at = models.DateTimeField(null=True, blank=True)

4.2.4 OA 审批流程状态机

请假申请 ──→ 主管审批 ──→ 经理审批 ──→ 人事归档
                │                        │
                ├── 驳回 ──→ 结束        └── 完成

                └── 一级通过 ──→ 二级审批

4.2.5 OA 系统前端示例

vue
<!-- frontend/src/views/approval/ApprovalDetail.vue -->
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import { getApprovalDetail, approveRequest, rejectRequest } from '@/api/approval'
import { ElMessage, ElDescriptions } from 'element-plus'

const route = useRoute()
const detail = ref<any>(null)
const comment = ref('')

onMounted(async () => {
  detail.value = await getApprovalDetail(route.params.id as string)
})

const handleApprove = async () => {
  await approveRequest(detail.value.id, { comment: comment.value })
  ElMessage.success('审批通过')
  detail.value.status = 'approved'
}

const handleReject = async () => {
  await rejectRequest(detail.value.id, { comment: comment.value })
  ElMessage.success('已驳回')
  detail.value.status = 'rejected'
}
</script>

<template>
  <div v-if="detail" class="approval-detail">
    <el-card>
      <template #header>
        <div class="card-header">
          <span>{{ detail.title }}</span>
          <el-tag
            :type="detail.status === 'approved' ? 'success'
                  : detail.status === 'rejected' ? 'danger' : 'warning'"
          >
            {{ detail.status === 'pending' ? '审批中'
             : detail.status === 'approved' ? '已通过'
             : '已驳回' }}
          </el-tag>
        </div>
      </template>

      <el-descriptions :column="2" border>
        <el-descriptions-item label="申请人">{{ detail.employee_name }}</el-descriptions-item>
        <el-descriptions-item label="申请类型">{{ detail.category_label }}</el-descriptions-item>
        <el-descriptions-item label="提交时间">{{ detail.created_at }}</el-descriptions-item>
        <el-descriptions-item label="部门">{{ detail.department_name }}</el-descriptions-item>
      </el-descriptions>

      <div class="content-box" v-html="detail.content_html"></div>
    </el-card>

    <!-- 审批时间线 -->
    <el-card style="margin-top: 16px">
      <template #header><span>审批进度</span></template>
      <el-timeline>
        <el-timeline-item
          v-for="node in detail.nodes" :key="node.id"
          :timestamp="node.reviewed_at || '待审批'"
          :type="node.status === 'approved' ? 'success'
                : node.status === 'rejected' ? 'danger' : 'info'"
        >
          {{ node.reviewer_name }} ——
          {{ node.status === 'pending' ? '待审批'
           : node.status === 'approved' ? '已通过'
           : '已驳回' }}
          <p v-if="node.comment">{{ node.comment }}</p>
        </el-timeline-item>
      </el-timeline>
    </el-card>

    <!-- 审批操作 -->
    <el-card v-if="detail.current_reviewer" style="margin-top: 16px">
      <el-input v-model="comment" type="textarea" placeholder="审批意见(选填)" />
      <div class="action-buttons">
        <el-button type="primary" @click="handleApprove">通过</el-button>
        <el-button type="danger" @click="handleReject">驳回</el-button>
      </div>
    </el-card>
  </div>
</template>

4.3 项目实战建议

4.3.1 开发流程

阶段一:需求分析(2天)
  ├── 梳理功能清单
  ├── 绘制原型图(Figma / 墨刀)
  └── 编写 PRD 文档

阶段二:系统设计(3天)
  ├── 数据库 E-R 设计
  ├── 接口规范文档(Swagger / Apifox)
  └── 项目目录初始化

阶段三:核心开发(14天)
  ├── 第1周:用户认证 + 商品管理(电商)/ 组织架构(OA)
  ├── 第2周:购物车/订单(电商)/ 审批流程(OA)
  └── 第3天:支付集成 / 后台统计

阶段四:联调测试(3天)
  ├── 前后端接口联调
  ├── 功能回归测试
  └── 编写单元测试

阶段五:部署上线(2天)
  ├── Docker 容器化
  ├── Nginx + HTTPS 配置
  └── 监控与日志

4.3.2 关键技术选型对比

场景电商平台推荐OA 系统推荐
前端组件库Element Plus(表格/表单丰富)Element Plus(树/时间线/日历)
状态管理Pinia(购物车/用户状态)Pinia(用户/应用配置)
权限模型RBAC(角色-权限)ABAC(属性-权限,更细粒度)
缓存策略Redis 缓存热门商品/JWTRedis 缓存组织结构树
异步任务Celery(订单超时/短信)Celery(审批通知邮件)
搜索数据库 Fulltext / Elasticsearch数据库 LIKE 查询即可
文件存储本地 / OSS 对象存储本地 / MinIO

4.3.3 数据统计看板

电商平台看板

  • 今日订单数、销售额、新增用户数
  • 近 30 天销售趋势(折线图)
  • 商品分类销售占比(饼图)
  • 用户地域分布(中国地图)
  • TOP10 热销商品(柱状图)

OA 系统看板

  • 今日出勤率
  • 待审批单据数量
  • 各部门人员分布
  • 请假类型占比

4.4 学习资源推荐

4.4.1 官方文档

4.4.2 推荐阅读

  • 《Vue.js 设计与实现》—— 霍春阳
  • 《Django 企业开发实战》—— 胡阳
  • 《高性能 MySQL》—— Baron Schwartz

小结

知识回顾

  1. B2C 电商平台:覆盖了用户、商品、购物车、订单、支付、后台管理六大核心模块,是典型的全栈实战项目
  2. 企业 OA 系统:组织架构树、考勤打卡、多级审批流程,侧重工作流引擎设计
  3. 项目架构方法论:模块化拆分、清晰的目录结构、分层架构(前端/API/业务/数据)
  4. 全流程实战:从需求分析到系统设计,从编码实现到部署上线,覆盖软件工程全生命周期

练习与思考

  1. 电商项目:为电商平台新增"优惠券/满减活动"模块,设计数据表及下单时的优惠计算逻辑
  2. OA 项目:为 OA 系统添加"会议室预约"功能,设计时间冲突检测算法
  3. 项目优化:针对电商平台的高并发场景(如秒杀),设计一种扣减库存的方案(Redis 预减 + 消息队列异步落地)
  4. 团队协作:假设你带领 4 人团队(2 前端 + 2 后端)开发电商项目,请画出 Git 分支策略和任务分解甘特图
  5. 结业思考:回顾本模块全部 4 章内容,写一份不少于 500 字的学习总结,包含你印象最深的技术点和遇到的难点及解决方案

Python 学习资料