SchoolDash Alpha冲刺 团队代码规范、任务与计划

SchoolDash Alpha冲刺 团队代码规范、任务与计划

课程与作业信息

  • 所属课程:软件工程实践
  • 作业要求来源:第五次作业——Alpha冲刺
  • 本篇目标:阐述团队代码规范、本次冲刺任务及计划,对应课程目标7

(1)SchoolDash 代码规范

1. 概述

本文档定义了 SchoolDash 项目的代码规范,包括前端、后端和数据库的编码标准,以确保代码的一致性、可读性和可维护性。

2. 通用规范

2.1 命名规范
变量和函数命名
  • 使用驼峰命名法(camelCase)
  • 变量名使用有意义的名词或形容词
  • 函数名使用动词或动词短语
  • 布尔值变量以 ishascan 等开头
// 正确示例
const userName = 'john';
const isUserActive = true;
const getUserById = (id) => { /* ... */ };
const hasPermission = user.role === 'admin';

// 错误示例
const u_name = 'john';
const activeuser = true;
const get_user = (id) => { /* ... */ };
常量命名
  • 使用全大写字母和下划线分隔
// 正确示例
const API_BASE_URL = 'https://api.example.com';
const MAX_RETRY_COUNT = 3;

// 错误示例
const apiBaseUrl = 'https://api.example.com';
const maxRetryCount = 3;
类名和组件名
  • 使用帕斯卡命名法(PascalCase)
// 正确示例
class UserService { /* ... */ }
const UserProfile = { /* ... */ };

// 错误示例
class userService { /* ... */ }
const userProfile = { /* ... */ };
文件命名
  • 使用小写字母和连字符分隔
  • 组件文件名与组件名保持一致(使用帕斯卡命名法)
// 正确示例
user-service.js
user-profile.vue
GoodsManage.vue

// 错误示例
userService.js
userprofile.vue
goodsmanage.vue
2.2 注释规范
文件头注释

每个文件应包含文件头注释,说明文件用途、作者和创建日期

/**
 * 用户服务模块
 * 提供用户相关的业务逻辑处理
 * 
 * @author 开发团队
 * @since 2023-01-01
 */
函数注释

使用 JSDoc 格式注释函数,说明参数、返回值和功能

/**
 * 根据用户ID获取用户信息
 * @param {number} userId - 用户ID
 * @param {boolean} includeProfile - 是否包含详细资料
 * @returns {Promise<Object>} 用户信息对象
 * @throws {Error} 当用户不存在时抛出错误
 */
const getUserById = async (userId, includeProfile = false) => {
  // 实现代码
};
行内注释

对复杂逻辑或关键步骤添加简短注释

// 验证用户权限
if (!hasPermission(user, 'admin')) {
  throw new Error('无权限访问此资源');
}

// 计算订单总价(包含税费)
const totalPrice = calculateTotalPrice(orderItems) * (1 + taxRate);
2.3 代码格式化
缩进

使用 2 个空格进行缩进,不使用制表符

// 正确示例
if (condition) {
  doSomething();
  if (anotherCondition) {
    doAnotherThing();
  }
}

// 错误示例
if (condition) {
    doSomething();
    if (anotherCondition) {
        doAnotherThing();
    }
}
行长度

每行代码不超过 100 个字符

空行

在逻辑块之间使用空行分隔
函数之间使用 1-2 个空行分隔

const getUserList = async () => {
  // 实现代码
};

const createUser = async (userData) => {
  // 实现代码
};

3. 前端代码规范

3.1 Vue.js 组件规范
组件结构

按照以下顺序组织组件内容:

<template>
  <!-- 模板内容 -->
</template>

<script>
// 导入语句
import { ref, computed, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import { ElMessage } from 'element-plus';

// 组件定义
export default {
  name: 'ComponentName',
  
  // 组件选项
  props: {
    // 属性定义
  },
  
  emits: [
    // 事件定义
  ],
  
  setup(props, { emit }) {
    // 响应式数据
    const data = ref('');
    
    // 计算属性
    const computedData = computed(() => {
      // 计算逻辑
    });
    
    // 方法
    const method = () => {
      // 方法实现
    };
    
    // 生命周期钩子
    onMounted(() => {
      // 初始化逻辑
    });
    
    // 返回模板中需要使用的数据和方法
    return {
      data,
      computedData,
      method
    };
  }
};
</script>

<style scoped>
/* 组件样式 */
</style>
组件命名
  • 组件名使用帕斯卡命名法
  • 组件名应该是有意义的,描述组件的功能
  • 避免使用 HTML 保留字
// 正确示例
UserProfile
GoodsManage
OrderList

// 错误示例
userprofile
goodsmanage
orderlist
Div
Span
Props 定义
  • Props 应该详细定义类型、默认值和验证
  • Props 命名使用驼峰命名法
// 正确示例
props: {
  userId: {
    type: Number,
    required: true
  },
  userName: {
    type: String,
    default: ''
  },
  isActive: {
    type: Boolean,
    default: false
  },
  permissions: {
    type: Array,
    default: () => []
  }
}
事件命名
  • 事件名使用 kebab-case(短横线分隔)
  • 事件名应该描述动作
// 正确示例
emit('user-selected', userId);
emit('order-updated', orderId);
emit('form-submitted', formData);

// 错误示例
emit('userSelected', userId);
emit('orderUpdated', orderId);
emit('formSubmitted', formData);
3.2 模板规范
HTML 结构
  • 使用语义化 HTML5 标签
  • 合理嵌套标签,避免过深嵌套
  • 使用缩进保持结构清晰
<template>
  <div class="user-profile">
    <header class="profile-header">
      <h2>{{ userName }}</h2>
      <p class="user-role">{{ userRole }}</p>
    </header>
    
    <main class="profile-content">
      <section class="user-info">
        <h3>基本信息</h3>
        <ul>
          <li v-for="info in userInfo" :key="info.id">
            {{ info.label }}: {{ info.value }}
          </li>
        </ul>
      </section>
      
      <section class="user-actions">
        <button @click="editProfile">编辑资料</button>
        <button @click="changePassword">修改密码</button>
      </section>
    </main>
  </div>
</template>
条件渲染

使用 v-ifv-else-ifv-else 进行条件渲染

<template>
  <div>
    <div v-if="isLoading">加载中...</div>
    <div v-else-if="hasError">加载失败</div>
    <div v-else>
      <!-- 正常内容 -->
    </div>
  </div>
</template>
列表渲染

使用 v-for 进行列表渲染,始终提供唯一的 key

<template>
  <ul>
    <li v-for="item in items" :key="item.id">
      {{ item.name }}
    </li>
  </ul>
</template>
3.3 样式规范
CSS 类命名

使用 BEM(Block Element Modifier)命名法

/* 块(Block) */
.user-profile { }

/* 元素(Element) */
.user-profile__header { }
.user-profile__content { }

/* 修饰符(Modifier) */
.user-profile--active { }
.user-profile__header--highlighted { }
样式作用域

使用 scoped 属性限制样式作用域

<style scoped>
/* 只作用于当前组件 */
.component-style {
  /* 样式定义 */
}
</style>
响应式设计

使用媒体查询实现响应式布局

.container {
  width: 100%;
  padding: 0 15px;
}

@media (min-width: 768px) {
  .container {
    max-width: 750px;
    margin: 0 auto;
  }
}

@media (min-width: 992px) {
  .container {
    max-width: 970px;
  }
}
3.4 状态管理
使用 Pinia 或 Vuex
  • 集中管理应用状态
  • 按功能模块组织状态
// store/modules/user.js
export const useUserStore = defineStore('user', {
  state: () => ({
    currentUser: null,
    isLoggedIn: false,
    permissions: []
  }),
  
  getters: {
    isAdmin: (state) => state.currentUser?.role === 'admin',
    hasPermission: (state) => (permission) => {
      return state.permissions.includes(permission);
    }
  },
  
  actions: {
    async login(credentials) {
      // 登录逻辑
    },
    
    async logout() {
      // 登出逻辑
    }
  }
});

4. 后端代码规范

4.1 Node.js/Express 规范
项目结构

按照功能模块组织代码

backend/
├── config/          # 配置文件
├── middleware/      # 中间件
├── models/          # 数据模型
├── routes/          # 路由定义
├── services/        # 业务逻辑服务
├── utils/           # 工具函数
├── controllers/     # 控制器(可选)
├── app.js           # 应用入口
└── package.json     # 依赖配置
模块导入

使用 ES6 模块导入语法

// 正确示例
import express from 'express';
import cors from 'cors';
import { sequelize } from './config/db.js';
import authRoutes from './routes/authRoutes.js';

// 错误示例
const express = require('express');
const cors = require('cors');
const { sequelize } = require('./config/db');
const authRoutes = require('./routes/authRoutes');
路由定义
  • 使用 Express Router 组织路由
  • 路由处理器应该是异步函数
  • 使用中间件处理通用逻辑
// routes/userRoutes.js
import express from 'express';
import { authenticateToken } from '../middleware/auth.js';
import { getUserById, createUser, updateUser } from '../controllers/userController.js';

const router = express.Router();

// 路由定义
router.get('/users/:id', authenticateToken, getUserById);
router.post('/users', createUser);
router.put('/users/:id', authenticateToken, updateUser);

export default router;
控制器
  • 控制器只负责处理请求和响应
  • 业务逻辑应该放在服务层
// controllers/userController.js
import { userService } from '../services/userService.js';

export const getUserById = async (req, res) => {
  try {
    const { id } = req.params;
    const user = await userService.getUserById(id);
    
    if (!user) {
      return res.status(404).json({
        code: 404,
        msg: '用户不存在'
      });
    }
    
    res.json({
      code: 200,
      msg: '获取成功',
      data: user
    });
  } catch (error) {
    console.error('获取用户失败:', error);
    res.status(500).json({
      code: 500,
      msg: '服务器内部错误'
    });
  }
};
错误处理
  • 使用统一的错误处理中间件
  • 自定义错误类型
// middleware/errorHandler.js
export const errorHandler = (err, req, res, next) => {
  console.error('错误详情:', err);
  
  // 自定义错误
  if (err.name === 'ValidationError') {
    return res.status(400).json({
      code: 400,
      msg: '参数验证失败',
      details: err.message
    });
  }
  
  // 数据库错误
  if (err.name === 'SequelizeError') {
    return res.status(500).json({
      code: 500,
      msg: '数据库操作失败'
    });
  }
  
  // 默认错误
  res.status(500).json({
    code: 500,
    msg: '服务器内部错误'
  });
};

// 在 app.js 中使用
app.use(errorHandler);
4.2 数据库模型规范
Sequelize 模型定义
  • 使用类定义模型
  • 明确定义字段类型和约束
  • 定义模型关联关系
// models/User.js
import { DataTypes } from 'sequelize';
import { sequelize } from '../config/db.js';

export const User = sequelize.define('User', {
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true
  },
  username: {
    type: DataTypes.STRING(50),
    allowNull: false,
    unique: true,
    validate: {
      len: [3, 50]
    }
  },
  password: {
    type: DataTypes.STRING(255),
    allowNull: false,
    validate: {
      len: [6, 255]
    }
  },
  email: {
    type: DataTypes.STRING(100),
    allowNull: true,
    validate: {
      isEmail: true
    }
  },
  role: {
    type: DataTypes.ENUM('user', 'admin', 'rider'),
    allowNull: false,
    defaultValue: 'user'
  },
  isActive: {
    type: DataTypes.BOOLEAN,
    allowNull: false,
    defaultValue: true
  },
  createdAt: {
    type: DataTypes.DATE,
    allowNull: false,
    defaultValue: DataTypes.NOW
  },
  updatedAt: {
    type: DataTypes.DATE,
    allowNull: false,
    defaultValue: DataTypes.NOW
  }
}, {
  tableName: 'users',
  timestamps: true
});
模型关联
  • 在模型文件中定义关联关系
  • 使用 belongsTohasManybelongsToMany 等方法
// models/User.js
import { Order } from './Order.js';
import { Address } from './Address.js';

// 用户有多个订单
User.hasMany(Order, {
  foreignKey: 'userId',
  as: 'orders'
});

// 用户有多个地址
User.hasMany(Address, {
  foreignKey: 'userId',
  as: 'addresses'
});

// models/Order.js
import { User } from './User.js';
import { OrderItem } from './OrderItem.js';

// 订单属于一个用户
Order.belongsTo(User, {
  foreignKey: 'userId',
  as: 'user'
});

// 订单有多个订单项
Order.hasMany(OrderItem, {
  foreignKey: 'orderId',
  as: 'items'
});
4.3 API 响应格式
统一响应格式

所有 API 响应应遵循统一格式

// 成功响应
{
  "code": 200,
  "msg": "操作成功",
  "data": {
    // 实际数据
  }
}

// 错误响应
{
  "code": 400,
  "msg": "参数错误",
  "details": "具体错误信息"
}

// 分页响应
{
  "code": 200,
  "msg": "获取成功",
  "data": {
    "list": [
      // 数据列表
    ],
    "pagination": {
      "current": 1,
      "pageSize": 10,
      "total": 100
    }
  }
}
状态码使用
  • 200: 成功
  • 201: 创建成功
  • 400: 请求参数错误
  • 401: 未授权
  • 403: 禁止访问
  • 404: 资源不存在
  • 500: 服务器内部错误
4.4 中间件规范
认证中间件
  • 验证 JWT 令牌
  • 设置用户信息到请求对象
// middleware/auth.js
import jwt from 'jsonwebtoken';

export const authenticateToken = (req, res, next) => {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];
  
  if (!token) {
    return res.status(401).json({
      code: 401,
      msg: '访问令牌缺失'
    });
  }
  
  jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
    if (err) {
      return res.status(403).json({
        code: 403,
        msg: '访问令牌无效'
      });
    }
    
    req.user = user;
    next();
  });
};
权限中间件
  • 检查用户是否有特定权限
// middleware/permission.js
export const requirePermission = (permission) => {
  return (req, res, next) => {
    if (!req.user) {
      return res.status(401).json({
        code: 401,
        msg: '未登录'
      });
    }
    
    if (!req.user.permissions.includes(permission)) {
      return res.status(403).json({
        code: 403,
        msg: '权限不足'
      });
    }
    
    next();
  };
};

// 使用示例
router.post('/admin/goods', authenticateToken, requirePermission('goods:create'), createGoods);

5. 数据库规范

5.1 命名规范

表名
  • 使用小写字母和下划线分隔
  • 使用复数形式
  • 表名应该是有意义的,描述表的用途
-- 正确示例
users
orders
order_items
user_addresses

-- 错误示例
User
Order
orderItems
useraddress
字段名
  • 使用小写字母和下划线分隔
  • 字段名应该是有意义的,描述字段的用途
  • 避免使用数据库保留字
-- 正确示例
user_id
created_at
is_active
first_name

-- 错误示例
userId
createdAt
active
firstName
索引名
  • 使用 idx_ 前缀
  • 包含表名和字段名
-- 正确示例
idx_users_email
idx_orders_user_id
idx_order_items_order_id

-- 错误示例
users_email_index
order_user_idx
order_items_order_id_index
5.2 字段定义
主键
  • 使用 id 作为主键名
  • 使用自增整数或 UUID
-- 正确示例
id INT PRIMARY KEY AUTO_INCREMENT
-- 或
id VARCHAR(36) PRIMARY KEY

-- 错误示例
user_id INT PRIMARY KEY AUTO_INCREMENT
uuid VARCHAR(36) PRIMARY KEY
外键
  • 使用 表名_id 格式
  • 明确定义外键约束
-- 正确示例
user_id INT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id)

-- 错误示例
userId INT NOT NULL,
user INT NOT NULL
时间戳字段
  • 使用 created_atupdated_at
  • 使用 TIMESTAMPDATETIME 类型
  • 设置默认值和自动更新
-- 正确示例
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

-- 错误示例
createTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP
updateTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
布尔字段
  • 使用 is_ 前缀
  • 使用 TINYINT(1)BOOLEAN 类型
  • 设置默认值
-- 正确示例
is_active TINYINT(1) DEFAULT 1
is_deleted TINYINT(1) DEFAULT 0

-- 错误示例
active TINYINT(1) DEFAULT 1
deleted TINYINT(1) DEFAULT 0
5.3 表设计原则
第一范式(1NF)
  • 字段不可再分
  • 每个字段都是原子性的
-- 正确示例
users(
  id INT PRIMARY KEY,
  first_name VARCHAR(50),
  last_name VARCHAR(50),
  email VARCHAR(100)
)

-- 错误示例
users(
  id INT PRIMARY KEY,
  name VARCHAR(100), -- 包含名和姓,不符合1NF
  email VARCHAR(100)
)
第二范式(2NF)
  • 满足第一范式
  • 非主键字段完全依赖于主键
-- 正确示例
orders(
  id INT PRIMARY KEY,
  user_id INT NOT NULL,
  order_date DATE NOT NULL,
  total_amount DECIMAL(10, 2) NOT NULL,
  FOREIGN KEY (user_id) REFERENCES users(id)
)

order_items(
  id INT PRIMARY KEY,
  order_id INT NOT NULL,
  product_id INT NOT NULL,
  quantity INT NOT NULL,
  price DECIMAL(10, 2) NOT NULL,
  FOREIGN KEY (order_id) REFERENCES orders(id),
  FOREIGN KEY (product_id) REFERENCES products(id)
)

-- 错误示例
orders(
  id INT PRIMARY KEY,
  user_id INT NOT NULL,
  order_date DATE NOT NULL,
  product_id INT NOT NULL,
  product_name VARCHAR(100) NOT NULL, -- 依赖于product_id,不完全依赖于order_id
  quantity INT NOT NULL,
  price DECIMAL(10, 2) NOT NULL
)
第三范式(3NF)
  • 满足第二范式
  • 非主键字段不传递依赖于主键
-- 正确示例
users(
  id INT PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  city_id INT NOT NULL,
  FOREIGN KEY (city_id) REFERENCES cities(id)
)

cities(
  id INT PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  province VARCHAR(50) NOT NULL
)

-- 错误示例
users(
  id INT PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  city_name VARCHAR(100) NOT NULL, -- 传递依赖于city_id
  city_province VARCHAR(50) NOT NULL -- 传递依赖于city_id
)
5.4 索引规范
主键索引
  • 主键自动创建索引
  • 不需要手动创建
唯一索引
  • 为需要唯一性的字段创建唯一索引
-- 正确示例
CREATE UNIQUE INDEX idx_users_email ON users(email);
CREATE UNIQUE INDEX idx_users_username ON users(username);
普通索引
  • 为经常用于查询条件的字段创建索引
  • 为外键字段创建索引
-- 正确示例
CREATE INDEX idx_orders_user_id ON orders(user_id);
CREATE INDEX idx_orders_order_date ON orders(order_date);
CREATE INDEX idx_order_items_order_id ON order_items(order_id);
CREATE INDEX idx_order_items_product_id ON order_items(product_id);
复合索引
  • 为经常一起查询的多个字段创建复合索引
  • 将选择性高的字段放在前面
-- 正确示例
CREATE INDEX idx_orders_user_date ON orders(user_id, order_date);
CREATE INDEX idx_order_items_order_product ON order_items(order_id, product_id);
5.5 SQL 查询规范
查询格式化
  • 使用缩进和换行保持可读性
  • 关键字大写,字段名和表名小写
-- 正确示例
SELECT
    u.id,
    u.username,
    u.email,
    o.id AS order_id,
    o.order_date,
    o.total_amount
FROM
    users u
INNER JOIN
    orders o ON u.id = o.user_id
WHERE
    u.is_active = 1
    AND o.order_date >= '2023-01-01'
ORDER BY
    o.order_date DESC
LIMIT 10;

-- 错误示例
select u.id, u.username, u.email, o.id as order_id, o.order_date, o.total_amount
from users u inner join orders o on u.id = o.user_id
where u.is_active = 1 and o.order_date >= '2023-01-01'
order by o.order_date desc limit 10;
避免 SELECT *
  • 明确指定需要的字段
  • 减少数据传输量
-- 正确示例
SELECT id, username, email FROM users WHERE id = 1;

-- 错误示例
SELECT * FROM users WHERE id = 1;
使用参数化查询
  • 防止 SQL 注入
  • 提高查询性能
// 正确示例
const getUserById = async (id) => {
  const [rows] = await sequelize.query(
    'SELECT id, username, email FROM users WHERE id = ?',
    {
      replacements: [id],
      type: QueryTypes.SELECT
    }
  );
  return rows[0];
};

// 错误示例
const getUserById = async (id) => {
  const [rows] = await sequelize.query(
    `SELECT id, username, email FROM users WHERE id = ${id}`,
    { type: QueryTypes.SELECT }
  );
  return rows[0];
};

6. 代码审查清单

6.1 前端代码审查
  • 组件命名是否符合规范
  • Props 和事件定义是否完整
  • 是否有内存泄漏风险(事件监听器、定时器等)
  • 是否有未处理的 Promise 异常
  • 样式是否使用 scoped 或 BEM 命名
  • 是否有重复代码可以提取为公共组件或函数
  • 是否有性能优化空间(懒加载、防抖、节流等)
6.2 后端代码审查
  • API 响应格式是否统一
  • 错误处理是否完善
  • 是否有安全漏洞(SQL 注入、XSS 等)
  • 数据验证是否充分
  • 是否有未处理的异步错误
  • 数据库查询是否优化
  • 敏感信息是否正确处理(密码加密、令牌验证等)
6.3 数据库代码审查
  • 表设计是否符合范式
  • 索引使用是否合理
  • 外键约束是否正确定义
  • 查询语句是否优化
  • 是否有性能瓶颈
  • 数据类型选择是否合适

总结

遵循本代码规范可以提高代码质量、可读性和可维护性,减少开发过程中的沟通成本,提高团队协作效率。所有开发人员都应该熟悉并遵守这些规范,代码审查时也应以此规范为标准。

代码规范不是一成不变的,随着项目的发展和团队经验的积累,可以适当调整和完善规范内容。任何修改都应该经过团队讨论,并及时更新文档。

(2) 本次冲刺任务

本次Alpha冲刺为期10天,聚焦SchoolDash系统的核心功能完善。项目是一个校园配送管理系统,包括用户端(商品浏览/购物车/订单)、骑手端(订单接收/配送)和管理端(商品/订单/用户管理)。基于前期开发,已移除图片功能,使用JWT多角色认证,支持MySQL/SQLite切换。

1.主要任务

主要任务分解为以下Issue:

  • Issue #1: 环境优化与认证完善 :切换数据库配置,实现多角色JWT Token管理。

  • Issue #2: 用户注册登录模块:前后端集成,包含骑手/管理员角色。

  • Issue #3: 商品与分类模块 :后端路由(categoryRoutes.js/homeRoutes.js),前端页面(GoodsList.vue/GoodsDetail.vue)。

  • Issue #4: 购物车与订单模块 :购物车管理(cartRoutes.js/Cart.vue),订单创建/查看(orderRoutes.js/OrderList.vue)。

  • Issue #5: 骑手与管理端功能 :骑手订单处理(riderRoutes.js/RiderDashboard.vue),管理端CRUD(adminRoutes.js/AdminGoodsManage.vue)。

  • Issue #6: 集成测试与优化:端到端测试,性能调优,缓存问题修复。

2.成员分工

成员贡献度成员分工
Shi Haokun8.3%协调项目进度,分配任务,促进跨模块沟通,组织阶段讨论,与教师联络接收提交成果,确保质量控制,并负责课堂展示。
Ou Yang/Shi Haozhen/Zheng Dingnan/Wang Junqi33.2%负责用户端和管理端的全页面开发,涵盖首页、产品分类/详情页(包括加入购物车)、登录/注册、购物车、个人中心(订单查询)、结账/订单确认/支付结果页面,以及产品/订单/用户管理后台页面。确保界面可用且操作流程连贯。
GUO ZIKAI/Li Yan/Sun Xuhang/Mo Xinyan33.2%相关的数据支持和业务逻辑方面,一人负责设计数据库表(如用户、产品、订单等)并实现对数据的添加、删除、修改和查询操作。另外两人分别负责用户系统(登录/注册验证、权限管理)和产品管理、购物车(产品添加、删除、修改)以及订单流程(创建、状态更新)。一人负责前端和后端接口的开发及集成测试,以确保数据交互的顺畅进行。
Zhou Jinlin/Hu Yichen/Lin Xie25.3%验证每个模块的功能(如登录、下单、支付等),检查界面的一致性和数据的准确性,协助进行故障排查,并确保系统的可用性。

3. 冲刺计划

  • 时间安排:每日站会(15min,讨论进度/阻塞),每2天回顾并发布冲刺随笔(含燃尽图、运行效果、提交记录)。冲刺末尾总结。

  • 工具与实践:用GitHub管理Issue/Commit(分支规范:feature/xxx),PM2部署后端,Vite构建前端。自动化测试用Jest/Vitest。

  • 风险与应对:潜在风险如API路径不匹配或缓存问题(参考开发问题记录.md),应对通过每日审查与Pair Programming。目标:完成Alpha版本,覆盖用户/骑手/管理员完整流程。

  • 预期输出:可运行项目(链接:https://github.com/team/schooldash),包含所有模块运行截图/GIF。

团队将以敏捷方式推进,确保高质量交付。冲刺启动前,所有成员确认规范熟悉度。

SchoolDash团队,Alpha冲刺准备就绪!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值