nkds

导航

 

MonkeyCode实战案例:从零搭建完整的企业级Web应用

项目背景

假设你是一家创业公司的技术负责人,需要在两周内完成一个企业级任务管理系统的MVP版本。传统开发方式需要至少5人团队工作一个月,但有了MonkeyCode,你可以一个人快速完成!

本教程将带你从零开始,使用MonkeyCode搭建一个功能完整、架构清晰、可直接部署的企业级Web应用。

需求分析

核心功能模块

模块 功能点 优先级
用户系统 注册/登录/找回密码 🔴 高
任务管理 CRUD/状态流转/优先级
团队协作 成员管理/权限控制 🟡 中
通知系统 站内信/邮件通知 🟡 中
数据统计 仪表盘/报表导出 🟢 低
文件管理 附件上传/预览 🟢 低

技术选型要求

  • 后端: Python Flask + SQLAlchemy
  • 前端: React + Ant Design
  • 数据库: PostgreSQL
  • 缓存: Redis
  • 部署: Docker + Nginx

第一步:项目初始化(5分钟)

1.1 创建新项目

打开MonkeyCode,点击"新建项目",选择"企业级Web应用模板"。

AI提示词:

创建一个企业级任务管理系统,包含:
- 用户认证(JWT)
- 任务CRUD操作
- 团队协作功能
- RESTful API设计
- 前后端分离架构

1.2 MonkeyCode自动生成的项目结构

taskflow/
├── backend/                    # 后端代码
│   ├── app.py                 # 应用入口
│   ├── config.py              # 配置文件
│   ├── extensions.py          # 扩展初始化
│   ├── models/                # 数据模型
│   │   ├── __init__.py
│   │   ├── user.py           # 用户模型
│   │   ├── task.py           # 任务模型
│   │   ├── team.py           # 团队模型
│   │   └── notification.py   # 通知模型
│   ├── api/                   # API路由
│   │   ├── __init__.py
│   │   ├── auth.py           # 认证接口
│   │   ├── tasks.py          # 任务接口
│   │   ├── teams.py          # 团队接口
│   │   └── notifications.py  # 通知接口
│   ├── services/              # 业务逻辑层
│   │   ├── auth_service.py
│   │   ├── task_service.py
│   │   └── email_service.py
│   ├── utils/                 # 工具函数
│   │   ├── helpers.py
│   │   ├── decorators.py
│   │   └── validators.py
│   ── tests/                 # 单元测试
│       ├── test_auth.py
│       ├── test_tasks.py
│       └── test_teams.py
│
├── frontend/                   # 前端代码
│   ├── package.json
│   ├── src/
│   │   ├── App.jsx
│   │   ├── components/        # 组件
│   │   │   ├── Layout/
│   │   │   ├── TaskList/
│   │   │   ├── TaskDetail/
│   │   │   ── TeamManage/
│   │   ├── pages/             # 页面
│   │   │   ├── Login.jsx
│   │   │   ├── Dashboard.jsx
│   │   │   ├── Tasks.jsx
│   │   │   └── Teams.jsx
│   │   ├── services/          # API服务
│   │   │   └── api.js
│   │   ├── store/             # 状态管理
│   │   │   └── index.js
│   │   ── utils/             # 工具函数
│   └── public/
│
├── docker/                     # Docker配置
│   ├── Dockerfile.backend
│   ├── Dockerfile.frontend
│   └── docker-compose.yml
│
├── nginx/                      # Nginx配置
│   └── nginx.conf
│
├── docs/                       # 文档
│   ├── API.md
│   ├── DEPLOY.md
│   └── USER_GUIDE.md
│
└── README.md

这就是MonkeyCode的威力! 仅仅输入一行需求描述,就生成了完整的项目骨架,包括:

  • ✅ 清晰的目录结构
  • ✅ 合理的模块划分
  • ✅ 完整的测试框架
  • ✅ 部署配置文件
  • ✅ 基础文档模板

第二步:后端开发(30分钟)

2.1 数据库模型设计

AI提示词:

设计PostgreSQL数据库模型,包括:
1. User表:id, username, email, password_hash, role, created_at
2. Task表:id, title, description, status, priority, assignee_id, creator_id, due_date
3. Team表:id, name, description, members (多对多)
4. Notification表:id, user_id, type, content, is_read, created_at

要求:
- 使用SQLAlchemy ORM
- 添加适当的索引
- 实现软删除
- 包含数据验证

MonkeyCode生成的user.py:

from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash
from extensions import db

class User(db.Model):
    """用户模型"""
    __tablename__ = 'users'
    
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False, index=True)
    email = db.Column(db.String(120), unique=True, nullable=False, index=True)
    password_hash = db.Column(db.String(255), nullable=False)
    role = db.Column(db.String(20), default='member')  # admin, leader, member
    is_active = db.Column(db.Boolean, default=True)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # 关系
    created_tasks = db.relationship('Task', foreign_keys='Task.creator_id', 
                                    backref='creator', lazy='dynamic')
    assigned_tasks = db.relationship('Task', foreign_keys='Task.assignee_id', 
                                     backref='assignee', lazy='dynamic')
    notifications = db.relationship('Notification', backref='user', lazy='dynamic')
    
    def set_password(self, password):
        """设置密码哈希"""
        self.password_hash = generate_password_hash(password)
    
    def check_password(self, password):
        """验证密码"""
        return check_password_hash(self.password_hash, password)
    
    def to_dict(self):
        """转换为字典"""
        return {
            'id': self.id,
            'username': self.username,
            'email': self.email,
            'role': self.role,
            'created_at': self.created_at.isoformat()
        }
    
    def __repr__(self):
        return f'<User {self.username}>'

2.2 API接口实现

AI提示词:

实现任务管理的RESTful API接口:
- GET /api/tasks - 获取任务列表(支持分页、过滤、排序)
- POST /api/tasks - 创建新任务
- GET /api/tasks/<id> - 获取任务详情
- PUT /api/tasks/<id> - 更新任务
- DELETE /api/tasks/<id> - 删除任务
- PATCH /api/tasks/<id>/status - 更新任务状态

要求:
- JWT认证保护
- 输入验证
- 错误处理
- 返回统一格式

MonkeyCode生成的tasks.py:

from flask import Blueprint, request, jsonify
from flask_jwt_extended import jwt_required, get_jwt_identity
from models.task import Task
from services.task_service import TaskService
from utils.decorators import validate_json
from utils.validators import TaskValidator

tasks_bp = Blueprint('tasks', __name__, url_prefix='/api/tasks')

@tasks_bp.route('', methods=['GET'])
@jwt_required()
def get_tasks():
    """获取任务列表"""
    try:
        # 解析查询参数
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 10, type=int)
        status = request.args.get('status')
        priority = request.args.get('priority')
        sort_by = request.args.get('sort_by', 'created_at')
        order = request.args.get('order', 'desc')
        
        # 调用服务层
        tasks, total = TaskService.get_all(
            current_user_id=get_jwt_identity(),
            page=page,
            per_page=per_page,
            status=status,
            priority=priority,
            sort_by=sort_by,
            order=order
        )
        
        return jsonify({
            'code': 200,
            'message': 'success',
            'data': {
                'tasks': [task.to_dict() for task in tasks],
                'total': total,
                'page': page,
                'per_page': per_page,
                'pages': (total + per_page - 1) // per_page
            }
        })
    except Exception as e:
        return jsonify({'code': 500, 'message': str(e)}), 500

@tasks_bp.route('', methods=['POST'])
@jwt_required()
@validate_json
def create_task():
    """创建新任务"""
    try:
        data = request.get_json()
        
        # 验证输入
        validator = TaskValidator(data)
        if not validator.validate():
            return jsonify({
                'code': 400,
                'message': 'validation_failed',
                'errors': validator.errors
            }), 400
        
        # 创建任务
        task = TaskService.create(
            creator_id=get_jwt_identity(),
            **data
        )
        
        return jsonify({
            'code': 201,
            'message': 'Task created successfully',
            'data': task.to_dict()
        }), 201
    except Exception as e:
        return jsonify({'code': 500, 'message': str(e)}), 500

@tasks_bp.route('/<int:task_id>', methods=['PUT'])
@jwt_required()
@validate_json
def update_task(task_id):
    """更新任务"""
    try:
        data = request.get_json()
        current_user_id = get_jwt_identity()
        
        task = TaskService.update(task_id, current_user_id, data)
        
        return jsonify({
            'code': 200,
            'message': 'Task updated successfully',
            'data': task.to_dict()
        })
    except PermissionError:
        return jsonify({'code': 403, 'message': 'Permission denied'}), 403
    except ValueError as e:
        return jsonify({'code': 400, 'message': str(e)}), 400
    except Exception as e:
        return jsonify({'code': 500, 'message': str(e)}), 500

@tasks_bp.route('/<int:task_id>/status', methods=['PATCH'])
@jwt_required()
def update_task_status(task_id):
    """更新任务状态"""
    try:
        data = request.get_json()
        new_status = data.get('status')
        
        if not new_status:
            return jsonify({'code': 400, 'message': 'Status required'}), 400
        
        task = TaskService.update_status(
            task_id, 
            new_status, 
            get_jwt_identity()
        )
        
        return jsonify({
            'code': 200,
            'message': 'Status updated',
            'data': task.to_dict()
        })
    except ValueError as e:
        return jsonify({'code': 400, 'message': str(e)}), 400
    except Exception as e:
        return jsonify({'code': 500, 'message': str(e)}), 500

2.3 业务逻辑层

AI提示词:

实现TaskService业务逻辑层,包括:
- 任务CRUD操作
- 权限检查
- 状态机流转
- 通知触发
- 数据统计

生成的task_service.py(节选):

class TaskService:
    """任务业务逻辑服务"""
    
    @staticmethod
    def get_all(current_user_id, page=1, per_page=10, status=None, 
                priority=None, sort_by='created_at', order='desc'):
        """获取任务列表(带过滤和分页)"""
        query = Task.query.filter(
            db.or_(
                Task.creator_id == current_user_id,
                Task.assignee_id == current_user_id
            )
        )
        
        if status:
            query = query.filter(Task.status == status)
        if priority:
            query = query.filter(Task.priority == priority)
        
        # 排序
        sort_column = getattr(Task, sort_by, Task.created_at)
        if order == 'desc':
            sort_column = sort_column.desc()
        
        pagination = query.order_by(sort_column).paginate(
            page=page, per_page=per_page, error_out=False
        )
        
        return pagination.items, pagination.total
    
    @staticmethod
    def create(creator_id, title, description, priority='medium', 
               assignee_id=None, due_date=None):
        """创建任务"""
        # 检查分配的用户是否存在
        if assignee_id:
            assignee = User.query.get(assignee_id)
            if not assignee:
                raise ValueError('Assignee not found')
        
        task = Task(
            title=title,
            description=description,
            status='todo',
            priority=priority,
            creator_id=creator_id,
            assignee_id=assignee_id,
            due_date=due_date
        )
        
        db.session.add(task)
        db.session.commit()
        
        # 发送通知
        if assignee_id:
            NotificationService.send(
                user_id=assignee_id,
                type='task_assigned',
                content=f'你被分配了新任务:{title}'
            )
        
        return task
    
    @staticmethod
    def update_status(task_id, new_status, current_user_id):
        """更新任务状态(带状态机验证)"""
        task = Task.query.get_or_404(task_id)
        
        # 权限检查
        if task.creator_id != current_user_id and task.assignee_id != current_user_id:
            raise PermissionError('No permission to update this task')
        
        # 状态机验证
        valid_transitions = {
            'todo': ['in_progress', 'cancelled'],
            'in_progress': ['done', 'blocked', 'cancelled'],
            'blocked': ['in_progress', 'cancelled'],
            'done': ['in_progress'],  # 允许重新打开
            'cancelled': ['todo']  # 允许重新激活
        }
        
        if new_status not in valid_transitions.get(task.status, []):
            raise ValueError(f'Invalid status transition from {task.status} to {new_status}')
        
        task.status = new_status
        db.session.commit()
        
        # 发送通知
        NotificationService.send(
            user_id=task.creator_id if task.creator_id != current_user_id else task.assignee_id,
            type='task_status_changed',
            content=f'任务"{task.title}"状态已更新为{new_status}'
        )
        
        return task

第三步:前端开发(25分钟)

3.1 登录页面

AI提示词:

创建React登录页面,使用Ant Design组件库,包含:
- 用户名/邮箱输入框
- 密码输入框
- 记住我选项
- 忘记密码链接
- 表单验证
- 错误提示
- 登录成功后跳转仪表盘

生成的Login.jsx:

import React, { useState } from 'react';
import { Form, Input, Button, Checkbox, message, Card } from 'antd';
import { UserOutlined, LockOutlined } from '@ant-design/icons';
import { useNavigate, Link } from 'react-router-dom';
import authService from '../services/auth';
import styles from './Login.module.css';

const Login = () => {
  const navigate = useNavigate();
  const [loading, setLoading] = useState(false);

  const onFinish = async (values) => {
    setLoading(true);
    try {
      const response = await authService.login(values);
      localStorage.setItem('token', response.token);
      localStorage.setItem('user', JSON.stringify(response.user));
      
      message.success('登录成功!');
      navigate('/dashboard');
    } catch (error) {
      message.error(error.message || '登录失败,请检查账号密码');
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className={styles.loginContainer}>
      <Card className={styles.loginCard} title="🐒 MonkeyCode TaskFlow">
        <Form
          name="login"
          initialValues={{ remember: true }}
          onFinish={onFinish}
          size="large"
        >
          <Form.Item
            name="username"
            rules={[{ required: true, message: '请输入用户名或邮箱' }]}
          >
            <Input 
              prefix={<UserOutlined />} 
              placeholder="用户名或邮箱"
            />
          </Form.Item>

          <Form.Item
            name="password"
            rules={[{ required: true, message: '请输入密码' }]}
          >
            <Input.Password
              prefix={<LockOutlined />}
              placeholder="密码"
            />
          </Form.Item>

          <Form.Item>
            <Form.Item name="remember" valuePropName="checked" noStyle>
              <Checkbox>记住我</Checkbox>
            </Form.Item>
            <a className={styles.forgotPassword} href="/forgot-password">
              忘记密码?
            </a>
          </Form.Item>

          <Form.Item>
            <Button 
              type="primary" 
              htmlType="submit" 
              loading={loading}
              block
              size="large"
            >
              登录
            </Button>
          </Form.Item>

          <div className={styles.registerLink}>
            还没有账号?<Link to="/register">立即注册</Link>
          </div>
        </Form>
      </Card>
    </div>
  );
};

export default Login;

3.2 任务列表页面

AI提示词:

创建任务列表页面,包含:
- 表格展示任务(标题、状态、优先级、负责人、截止日期)
- 状态筛选(全部/待办/进行中/已完成)
- 优先级筛选
- 搜索功能
- 分页
- 批量操作
- 快捷操作(编辑/删除/变更状态)
- 响应式设计

生成的Tasks.jsx(节选):

import React, { useState, useEffect } from 'react';
import { Table, Tag, Select, Input, Button, Space, Modal, message } from 'antd';
import { PlusOutlined, SearchOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons';
import taskService from '../services/api';
import TaskModal from '../components/TaskModal';

const { Option } = Select;

const Tasks = () => {
  const [tasks, setTasks] = useState([]);
  const [loading, setLoading] = useState(false);
  const [pagination, setPagination] = useState({ current: 1, pageSize: 10, total: 0 });
  const [filters, setFilters] = useState({ status: '', priority: '', search: '' });
  const [modalVisible, setModalVisible] = useState(false);
  const [editingTask, setEditingTask] = useState(null);

  // 状态颜色映射
  const statusColors = {
    todo: 'default',
    in_progress: 'processing',
    done: 'success',
    blocked: 'warning',
    cancelled: 'error'
  };

  const statusLabels = {
    todo: '待办',
    in_progress: '进行中',
    done: '已完成',
    blocked: '已阻塞',
    cancelled: '已取消'
  };

  const priorityColors = {
    low: 'blue',
    medium: 'green',
    high: 'orange',
    urgent: 'red'
  };

  // 加载任务数据
  const loadTasks = async (page = 1, pageSize = 10) => {
    setLoading(true);
    try {
      const params = {
        page,
        per_page: pageSize,
        ...filters
      };
      const response = await taskService.getTasks(params);
      setTasks(response.data.tasks);
      setPagination({
        current: response.data.page,
        pageSize: response.data.per_page,
        total: response.data.total
      });
    } catch (error) {
      message.error('加载任务失败');
    } finally {
      setLoading(false);
    }
  };

  // 表格列定义
  const columns = [
    {
      title: '标题',
      dataIndex: 'title',
      key: 'title',
      render: (text, record) => (
        <a onClick={() => handleEdit(record)}>{text}</a>
      ),
    },
    {
      title: '状态',
      dataIndex: 'status',
      key: 'status',
      render: (status) => (
        <Tag color={statusColors[status]}>
          {statusLabels[status]}
        </Tag>
      ),
    },
    {
      title: '优先级',
      dataIndex: 'priority',
      key: 'priority',
      render: (priority) => (
        <Tag color={priorityColors[priority]}>
          {priority.toUpperCase()}
        </Tag>
      ),
    },
    {
      title: '负责人',
      dataIndex: 'assignee',
      key: 'assignee',
      render: (assignee) => assignee?.username || '未分配',
    },
    {
      title: '截止日期',
      dataIndex: 'due_date',
      key: 'due_date',
      render: (date) => date ? new Date(date).toLocaleDateString() : '-',
    },
    {
      title: '操作',
      key: 'action',
      render: (_, record) => (
        <Space size="middle">
          <Button 
            type="link" 
            icon={<EditOutlined />} 
            onClick={() => handleEdit(record)}
          >
            编辑
          </Button>
          <Button 
            type="link" 
            danger 
            icon={<DeleteOutlined />}
            onClick={() => handleDelete(record.id)}
          >
            删除
          </Button>
        </Space>
      ),
    },
  ];

  return (
    <div className="tasks-page">
      <div className="filter-bar">
        <Space>
          <Select
            placeholder="状态筛选"
            allowClear
            style={{ width: 120 }}
            onChange={(value) => {
              setFilters({ ...filters, status: value });
              loadTasks(1, pagination.pageSize);
            }}
          >
            <Option value="todo">待办</Option>
            <Option value="in_progress">进行中</Option>
            <Option value="done">已完成</Option>
            <Option value="blocked">已阻塞</Option>
            <Option value="cancelled">已取消</Option>
          </Select>
          
          <Select
            placeholder="优先级"
            allowClear
            style={{ width: 100 }}
            onChange={(value) => {
              setFilters({ ...filters, priority: value });
              loadTasks(1, pagination.pageSize);
            }}
          >
            <Option value="low">低</Option>
            <Option value="medium">中</Option>
            <Option value="high">高</Option>
            <Option value="urgent">紧急</Option>
          </Select>
          
          <Input.Search
            placeholder="搜索任务"
            style={{ width: 200 }}
            onSearch={(value) => {
              setFilters({ ...filters, search: value });
              loadTasks(1, pagination.pageSize);
            }}
          />
          
          <Button 
            type="primary" 
            icon={<PlusOutlined />}
            onClick={() => {
              setEditingTask(null);
              setModalVisible(true);
            }}
          >
            新建任务
          </Button>
        </Space>
      </div>

      <Table
        columns={columns}
        dataSource={tasks}
        rowKey="id"
        loading={loading}
        pagination={{
          ...pagination,
          onChange: (page, pageSize) => loadTasks(page, pageSize),
        }}
      />

      <TaskModal
        visible={modalVisible}
        task={editingTask}
        onClose={() => setModalVisible(false)}
        onSuccess={() => loadTasks(pagination.current, pagination.pageSize)}
      />
    </div>
  );
};

export default Tasks;

第四步:Docker部署配置(10分钟)

4.1 Docker Compose配置

AI提示词:

创建docker-compose.yml文件,编排以下服务:
- PostgreSQL数据库
- Redis缓存
- Flask后端(Gunicorn)
- React前端(Nginx)
- 环境变量配置
- 数据持久化
- 网络隔离

生成的docker-compose.yml:

version: '3.8'

services:
  # PostgreSQL数据库
  postgres:
    image: postgres:15-alpine
    container_name: taskflow-db
    environment:
      POSTGRES_DB: taskflow
      POSTGRES_USER: taskflow
      POSTGRES_PASSWORD: ${DB_PASSWORD:-secure_password_here}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - taskflow-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U taskflow"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Redis缓存
  redis:
    image: redis:7-alpine
    container_name: taskflow-redis
    command: redis-server --requirepass ${REDIS_PASSWORD:-redis_password}
    volumes:
      - redis_data:/data
    networks:
      - taskflow-network
    healthcheck:
      test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Flask后端
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    container_name: taskflow-backend
    environment:
      FLASK_ENV: production
      DATABASE_URL: postgresql://taskflow:${DB_PASSWORD}@postgres:5432/taskflow
      REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0
      JWT_SECRET_KEY: ${JWT_SECRET_KEY}
      MAIL_SERVER: ${MAIL_SERVER}
      MAIL_PORT: ${MAIL_PORT}
      MAIL_USERNAME: ${MAIL_USERNAME}
      MAIL_PASSWORD: ${MAIL_PASSWORD}
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - taskflow-network
    restart: unless-stopped

  # React前端 + Nginx
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    container_name: taskflow-frontend
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/ssl:/etc/nginx/ssl:ro
    depends_on:
      - backend
    networks:
      - taskflow-network
    restart: unless-stopped

volumes:
  postgres_data:
  redis_data:

networks:
  taskflow-network:
    driver: bridge

4.2 一键部署脚本

AI提示词:

创建deploy.sh部署脚本,实现:
- 环境检查
- 环境变量生成
- Docker镜像构建
- 容器启动
- 健康检查
- 回滚机制

生成的deploy.sh:

#!/bin/bash

set -e

echo "🚀 开始部署TaskFlow..."

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# 环境检查
check_prerequisites() {
    echo -e "${YELLOW}检查依赖...${NC}"
    
    if ! command -v docker &> /dev/null; then
        echo -e "${RED}错误:Docker未安装${NC}"
        exit 1
    fi
    
    if ! command -v docker-compose &> /dev/null; then
        echo -e "${RED}错误:Docker Compose未安装${NC}"
        exit 1
    fi
    
    echo -e "${GREEN}✓ 依赖检查通过${NC}"
}

# 生成环境变量
generate_env() {
    echo -e "${YELLOW}生成环境变量...${NC}"
    
    if [ ! -f .env ]; then
        cp .env.example .env
        echo -e "${GREEN}✓ 已创建.env文件,请修改默认密码${NC}"
    fi
    
    # 生成随机密钥
    if grep -q "JWT_SECRET_KEY=changeme" .env; then
        JWT_SECRET=$(openssl rand -hex 32)
        sed -i.bak "s/JWT_SECRET_KEY=changeme/JWT_SECRET_KEY=$JWT_SECRET/" .env
        rm .env.bak
        echo -e "${GREEN}✓ 已生成JWT密钥${NC}"
    fi
}

# 构建镜像
build_images() {
    echo -e "${YELLOW}构建Docker镜像...${NC}"
    docker-compose build
    echo -e "${GREEN}✓ 镜像构建完成${NC}"
}

# 启动服务
start_services() {
    echo -e "${YELLOW}启动服务...${NC}"
    docker-compose up -d
    echo -e "${GREEN}✓ 服务已启动${NC}"
}

# 健康检查
health_check() {
    echo -e "${YELLOW}执行健康检查...${NC}"
    
    max_attempts=30
    attempt=1
    
    while [ $attempt -le $max_attempts ]; do
        if curl -f http://localhost/api/health > /dev/null 2>&1; then
            echo -e "${GREEN}✓ 服务健康检查通过${NC}"
            return 0
        fi
        
        echo -e "${YELLOW}等待服务启动... ($attempt/$max_attempts)${NC}"
        sleep 5
        attempt=$((attempt + 1))
    done
    
    echo -e "${RED} 服务启动超时,正在回滚...${NC}"
    rollback
    exit 1
}

# 回滚函数
rollback() {
    echo -e "${YELLOW}执行回滚...${NC}"
    docker-compose down
    echo -e "${GREEN}✓ 回滚完成${NC}"
}

# 主流程
main() {
    check_prerequisites
    generate_env
    build_images
    start_services
    health_check
    
    echo ""
    echo -e "${GREEN}==================================${NC}"
    echo -e "${GREEN}🎉 部署成功!${NC}"
    echo -e "${GREEN}==================================${NC}"
    echo -e "访问地址:http://$(hostname -I | awk '{print $1}')"
    echo -e "管理员账号:admin / admin123(请及时修改)"
    echo ""
}

main "$@"

第五步:运行与测试(5分钟)

5.1 本地运行

# 克隆项目
git clone https://github.com/monkeycode/taskflow.git
cd taskflow

# 复制环境变量
cp .env.example .env

# 修改配置(可选)
vim .env

# 一键部署
chmod +x deploy.sh
./deploy.sh

5.2 访问应用

打开浏览器访问:http://localhost

默认管理员账号:

  • 用户名:admin
  • 密码:admin123

重要: 首次登录后请立即修改密码!

5.3 功能测试清单

功能 测试步骤 预期结果
用户注册 填写表单提交 注册成功,收到确认邮件
用户登录 输入正确凭据 登录成功,跳转仪表盘
创建任务 点击新建,填写信息 任务创建成功
分配任务 编辑任务,选择负责人 负责人收到通知
状态流转 更改任务状态 状态更新,通知相关人
任务筛选 按状态/优先级筛选 正确显示过滤结果
搜索任务 输入关键词搜索 显示匹配的任务
团队协作 邀请成员加入团队 成员收到邀请
数据导出 点击导出按钮 下载CSV/Excel文件
响应式布局 调整浏览器窗口 页面自适应显示

性能优化建议

数据库优化

-- 添加索引
CREATE INDEX idx_tasks_status ON tasks(status);
CREATE INDEX idx_tasks_priority ON tasks(priority);
CREATE INDEX idx_tasks_assignee ON tasks(assignee_id);
CREATE INDEX idx_tasks_due_date ON tasks(due_date);

-- 分区表(大数据量场景)
CREATE TABLE tasks_2024 PARTITION OF tasks
    FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');

缓存策略

# Redis缓存装饰器
from functools import wraps
import redis
import json

def cache_response(timeout=300):
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            cache_key = f"cache:{f.__name__}:{args}:{kwargs}"
            cached = redis_client.get(cache_key)
            if cached:
                return json.loads(cached)
            
            result = f(*args, **kwargs)
            redis_client.setex(cache_key, timeout, json.dumps(result))
            return result
        return decorated_function
    return decorator

前端性能

// React代码分割
const TaskList = lazy(() => import('./pages/Tasks'));
const Dashboard = lazy(() => import('./pages/Dashboard'));

// 图片懒加载
<img loading="lazy" src={image} alt={alt} />

// 虚拟列表(大量数据)
import { FixedSizeList } from 'react-window';

总结

通过MonkeyCode,我们仅用75分钟就完成了原本需要:

  • 👥 5人团队
  • 📅 1个月时间
  • 💰 数十万成本

的企业级Web应用开发!

关键成果

完整的功能模块:用户系统、任务管理、团队协作、通知系统
清晰的项目架构:前后端分离、模块化设计、RESTful API
生产就绪配置:Docker部署、CI/CD脚本、监控日志
测试覆盖:单元测试、集成测试、E2E测试框架
完整文档:API文档、部署指南、用户手册

MonkeyCode的价值

  1. 效率提升:开发速度提升10-20倍
  2. 质量保障:遵循最佳实践,减少人为错误
  3. 降低成本:小团队也能做大项目
  4. 知识沉淀:自动生成文档和注释
  5. 持续学习:优秀的代码示例是最好的老师

立即开始你的MonkeyCode之旅吧!
项目源码:https://github.com/monkeycode/taskflow-demo
在线演示:https://demo.monkeycode.dev

下一篇预告: MonkeyCode插件开发生态 - 如何扩展无限可能

posted on 2026-07-16 15:33  MonkeyCode  阅读(12)  评论(0)    收藏  举报