校园活动报名与签到应用开发文档


欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net

一、项目概述

运行效果图

image-20260410224745717

image-20260410224751009

image-20260410224800577

image-20260410224804900

1.1 应用简介

校园活动报名与签到是一款专为高校学生设计的活动管理应用,帮助学生发现和参与校园活动,实现线上报名、扫码签到、学分统计等功能。应用以沉稳的靛蓝色为主色调,营造专业、学术的氛围。

应用涵盖首页、我的活动、签到、个人中心四大模块。学生可以浏览各类校园活动,在线报名感兴趣的活动,活动当天扫码签到获得学分,查看个人参与记录和学分统计。

1.2 核心功能

功能模块 功能描述 实现方式
活动浏览 浏览校园活动列表 列表展示
活动报名 在线报名活动 状态管理
扫码签到 扫描二维码签到 扫码功能
学分统计 统计参与活动学分 数据统计
活动筛选 按类型和状态筛选 筛选逻辑
个人中心 查看个人信息和统计 页面展示

1.3 活动类型定义

序号 类型名称 Emoji 描述
1 讲座 🎤 学术讲座、演讲
2 比赛 🏆 各类竞赛活动
3 社团活动 🎭 社团组织的活动
4 志愿服务 ❤️ 公益志愿活动
5 体育活动 体育比赛、运动会
6 文化活动 🎨 文艺演出、展览

1.4 活动状态定义

序号 状态名称 Emoji 描述
1 即将开始 报名中,即将开始
2 进行中 🔥 活动正在进行
3 已结束 活动已结束

1.5 技术栈

技术领域 技术选型 版本要求
开发框架 Flutter >= 3.0.0
编程语言 Dart >= 2.17.0
设计规范 Material Design 3 -
状态管理 setState -
目标平台 鸿蒙OS / Web API 21+

1.6 项目结构

lib/
└── main_campus_activity.dart
    ├── CampusActivityApp           # 应用入口
    ├── ActivityType                # 活动类型枚举
    ├── ActivityStatus              # 活动状态枚举
    ├── Activity                    # 活动模型
    ├── Registration                # 报名记录模型
    ├── CampusActivityHomePage      # 主页面(底部导航)
    ├── _buildHomePage              # 首页
    ├── _buildMyActivitiesPage      # 我的活动页
    ├── _buildCheckInPage           # 签到页
    ├── _buildProfilePage           # 个人中心页
    ├── _registerActivity           # 报名活动
    ├── _cancelRegistration         # 取消报名
    └── _checkIn                    # 签到

二、系统架构

2.1 整体架构图

Data Layer

Business Layer

Presentation Layer

主页面
CampusActivityHomePage

首页

我的活动

签到页

个人中心

活动列表

活动筛选

活动详情

已报名列表

签到状态

扫码签到

签到记录

学分统计

活动统计

活动管理器
ActivityManager

报名管理器
RegistrationManager

签到管理器
CheckInManager

Activity
活动模型

Registration
报名记录

ActivityType
活动类型

2.2 类图设计

has

has

manages

manages

CampusActivityApp

+Widget build()

«enumeration»

ActivityType

+String label

+String emoji

+String description

+lecture()

+competition()

+club()

+volunteer()

+sports()

+culture()

«enumeration»

ActivityStatus

+String label

+String emoji

+String description

+upcoming()

+ongoing()

+ended()

Activity

+String id

+String title

+String organizer

+ActivityType type

+ActivityStatus status

+DateTime startTime

+DateTime endTime

+String location

+int maxParticipants

+int currentParticipants

+String description

+double credits

+bool isRegistered

+Activity copyWith()

Registration

+String id

+String activityId

+String userId

+DateTime registeredAt

+bool isCheckedIn

+DateTime checkedInAt

CampusActivityHomePage

-int _currentIndex

-List<Activity> _allActivities

-List<Activity> _myActivities

-List<Registration> _registrations

+void _registerActivity()

+void _cancelRegistration()

+void _checkIn()

2.3 页面导航流程

首页

我的活动

签到

我的

应用启动

首页

底部导航

浏览活动

查看报名

扫码签到

个人中心

筛选活动

查看详情

报名活动

查看已报名

签到活动

扫描二维码

完成签到

查看学分

查看统计

2.4 活动报名流程

报名管理 活动详情 首页 学生 报名管理 活动详情 首页 学生 浏览活动列表 显示活动列表 点击活动 显示详情 显示活动信息 点击报名 创建报名记录 报名成功 显示报名成功

三、核心模块设计

3.1 数据模型设计

3.1.1 活动类型枚举 (ActivityType)
enum ActivityType {
  lecture(label: '讲座', emoji: '🎤', description: '学术讲座、演讲'),
  competition(label: '比赛', emoji: '🏆', description: '各类竞赛活动'),
  club(label: '社团活动', emoji: '🎭', description: '社团组织的活动'),
  volunteer(label: '志愿服务', emoji: '❤️', description: '公益志愿活动'),
  sports(label: '体育活动', emoji: '⚽', description: '体育比赛、运动会'),
  culture(label: '文化活动', emoji: '🎨', description: '文艺演出、展览');

  final String label;
  final String emoji;
  final String description;

  const ActivityType({
    required this.label,
    required this.emoji,
    required this.description,
  });
}
3.1.2 活动状态枚举 (ActivityStatus)
enum ActivityStatus {
  upcoming(label: '即将开始', emoji: '⏰', description: '报名中,即将开始'),
  ongoing(label: '进行中', emoji: '🔥', description: '活动正在进行'),
  ended(label: '已结束', emoji: '✅', description: '活动已结束');

  final String label;
  final String emoji;
  final String description;

  const ActivityStatus({
    required this.label,
    required this.emoji,
    required this.description,
  });
}
3.1.3 活动模型 (Activity)
class Activity {
  final String id;              // 活动ID
  final String title;           // 活动标题
  final String organizer;       // 主办方
  final ActivityType type;      // 活动类型
  final ActivityStatus status;  // 活动状态
  final DateTime startTime;     // 开始时间
  final DateTime endTime;       // 结束时间
  final String location;        // 活动地点
  final int maxParticipants;    // 最大参与人数
  int currentParticipants;      // 当前参与人数
  final String description;     // 活动描述
  final double credits;         // 学分
  final bool isRegistered;      // 是否已报名

  Activity({...});

  Activity copyWith({...});
}
3.1.4 报名记录模型 (Registration)
class Registration {
  final String id;              // 记录ID
  final String activityId;      // 活动ID
  final String userId;          // 用户ID
  final DateTime registeredAt;  // 报名时间
  final bool isCheckedIn;       // 是否已签到
  final DateTime? checkedInAt;  // 签到时间

  Registration({...});

  Registration copyWith({...});
}
3.1.5 活动类型分布
30% 20% 15% 15% 10% 10% 活动类型分布示例 讲座 比赛 社团活动 志愿服务 体育活动 文化活动
3.1.6 活动状态分布
50% 30% 20% 活动状态分布示例 即将开始 进行中 已结束

3.2 页面结构设计

3.2.1 主页面布局

CampusActivityHomePage

IndexedStack

首页

我的活动

签到页

个人中心

NavigationBar

首页 Tab

我的活动 Tab

签到 Tab

我的 Tab

3.2.2 首页结构

首页

SliverAppBar

快速统计

活动类型

状态筛选

活动列表

即将开始

已报名

获得学分

类型横向列表

状态选择芯片

活动卡片

3.2.3 我的活动页结构

我的活动

SliverAppBar

有报名?

已报名列表

活动信息

签到状态

签到按钮

空状态提示

3.2.4 签到页结构

签到页

SliverAppBar

扫码区域

签到记录

二维码框

打开相机按钮

签到历史列表

3.3 活动报名逻辑

点击报名

是否已报名?

显示已报名

人数已满?

提示人数已满

创建报名记录

更新参与人数

添加到我的活动

显示报名成功

取消报名

删除报名记录

减少参与人数

从我的活动移除

显示取消成功

3.4 签到逻辑

扫描二维码

活动进行中?

提示非活动时间

已报名?

提示未报名

已签到?

提示已签到

完成签到

更新签到状态

记录签到时间

获得学分

显示签到成功


四、UI设计规范

4.1 配色方案

应用以沉稳的靛蓝色为主色调,营造专业、学术的氛围:

颜色类型 色值 用途
主色 #3F51B5 (Indigo) 导航、主题元素
辅助色 #5C6BC0 我的活动页
第三色 #7986CB 签到页
强调色 #9FA8DA 个人中心
背景色 #FAFAFA 页面背景
卡片背景 #FFFFFF 活动卡片

4.2 状态颜色

状态 色值 视觉效果
即将开始 #2196F3 蓝色
进行中 #4CAF50 绿色
已结束 #9E9E9E 灰色

4.3 字体规范

元素 字号 字重 颜色
页面标题 24px Bold 主色
活动标题 16px Bold #000000
活动信息 12px Regular #666666
状态标签 12px Regular 状态颜色
学分数字 36px Bold 白色

4.4 组件规范

4.4.1 活动卡片
┌─────────────────────────────────────┐
│  ┌──────┐  人工智能前沿技术讲座  ⏰即将开始│
│  │  🤖  │  计算机学院                  │
│  └──────┘                              │
│  🕐 3/15 14:00 - 16:00  📍图书馆报告厅│
│  ████████░░░░░░░░  156/200 人         │
│                          [立即报名]    │
└─────────────────────────────────────┘
4.4.2 快速统计
┌─────────────────────────────────────┐
│   📅 5        ✅ 3        ⭐ 2.5    │
│   即将开始    已报名      获得学分   │
└─────────────────────────────────────┘
4.4.3 活动类型选择
┌─────────────────────────────────────┐
│  活动类型                            │
│                                     │
│  ┌────┐ ┌────┐ ┌────┐ ┌────┐      │
│  │ 🎤 │ │ 🏆 │ │ 🎭 │ │ ❤️ │      │
│  │讲座│ │比赛│ │社团│ │志愿│      │
│  └────┘ └────┘ └────┘ └────┘      │
└─────────────────────────────────────┘
4.4.4 签到页面
┌─────────────────────────────────────┐
│         ┌──────────────┐            │
│         │              │            │
│         │     📷       │            │
│         │              │            │
│         │ 扫描二维码签到│            │
│         └──────────────┘            │
│                                     │
│         [📷 打开相机扫码]           │
└─────────────────────────────────────┘
4.4.5 学分卡片
┌─────────────────────────────────────┐
│      2.5          │        3        │
│     累计学分       │     参与活动    │
└─────────────────────────────────────┘

五、核心功能实现

5.1 活动报名实现

void _registerActivity(Activity activity) {
  if (activity.currentParticipants >= activity.maxParticipants) {
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text('报名人数已满')),
    );
    return;
  }

  setState(() {
    final updatedActivity = activity.copyWith(
      currentParticipants: activity.currentParticipants + 1,
      isRegistered: true,
    );
    
    final index = _allActivities.indexWhere((a) => a.id == activity.id);
    if (index != -1) {
      _allActivities[index] = updatedActivity;
    }
    
    _myActivities.add(updatedActivity);
    
    _registrations.add(Registration(
      id: 'reg_${DateTime.now().millisecondsSinceEpoch}',
      activityId: activity.id,
      userId: 'user_1',
      registeredAt: DateTime.now(),
    ));
  });
}

5.2 取消报名实现

void _cancelRegistration(Activity activity) {
  setState(() {
    final updatedActivity = activity.copyWith(
      currentParticipants: activity.currentParticipants - 1,
      isRegistered: false,
    );
    
    final index = _allActivities.indexWhere((a) => a.id == activity.id);
    if (index != -1) {
      _allActivities[index] = updatedActivity;
    }
    
    _myActivities.removeWhere((a) => a.id == activity.id);
    _registrations.removeWhere((r) => r.activityId == activity.id);
  });
}

5.3 签到实现

void _checkIn(Activity activity) {
  final regIndex = _registrations.indexWhere((r) => r.activityId == activity.id);
  if (regIndex == -1) return;

  setState(() {
    _registrations[regIndex] = _registrations[regIndex].copyWith(
      isCheckedIn: true,
      checkedInAt: DateTime.now(),
    );
  });

  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(content: Text('签到成功!获得 ${activity.credits} 学分')),
  );
}

5.4 活动筛选实现

List<Activity> _getFilteredActivities() {
  List<Activity> filtered = _allActivities;
  
  if (_selectedType != null) {
    filtered = filtered.where((a) => a.type == _selectedType).toList();
  }
  
  if (_selectedStatus != null) {
    filtered = filtered.where((a) => a.status == _selectedStatus).toList();
  }
  
  return filtered;
}

5.5 学分统计实现

Widget _buildCreditCard(double credits) {
  return Card(
    elevation: 4,
    color: Theme.of(context).colorScheme.primaryContainer,
    child: Padding(
      padding: const EdgeInsets.all(20),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          Column(
            children: [
              Text(
                credits.toStringAsFixed(1),
                style: const TextStyle(
                  fontSize: 36,
                  fontWeight: FontWeight.bold,
                  color: Colors.white,
                ),
              ),
              Text('累计学分'),
            ],
          ),
          Column(
            children: [
              Text(
                '${_registrations.where((r) => r.isCheckedIn).length}',
                style: const TextStyle(
                  fontSize: 36,
                  fontWeight: FontWeight.bold,
                  color: Colors.white,
                ),
              ),
              Text('参与活动'),
            ],
          ),
        ],
      ),
    ),
  );
}

六、交互设计

6.1 活动浏览流程

详情 筛选 首页 学生 详情 筛选 首页 学生 打开应用 显示活动列表 选择活动类型 更新列表 点击活动 显示详情 显示活动信息

6.2 报名流程

查看活动详情

是否已报名?

显示取消报名按钮

人数已满?

禁用报名按钮

显示报名按钮

点击报名

创建报名记录

更新参与人数

显示报名成功

点击取消

删除报名记录

更新参与人数

显示取消成功

6.3 签到流程

打开相机

识别二维码

验证通过

验证失败

获得学分

提示错误

签到页

扫码

验证

签到成功

签到失败


七、扩展功能规划

7.1 后续版本规划

2024-01-07 2024-01-14 2024-01-21 2024-01-28 2024-02-04 2024-02-11 2024-02-18 2024-02-25 2024-03-03 2024-03-10 2024-03-17 2024-03-24 2024-03-31 基础UI框架 活动浏览功能 报名签到功能 真实扫码功能 活动推送通知 活动评价功能 活动创建功能 社交分享 数据分析 V1.0 基础版本 V1.1 增强版本 V1.2 进阶版本 校园活动报名与签到应用开发计划

7.2 功能扩展建议

7.2.1 真实扫码功能

扫码功能:

  • 集成相机插件
  • 二维码识别
  • 签到验证
  • 签到记录
7.2.2 活动推送

推送功能:

  • 活动开始提醒
  • 报名成功通知
  • 签到提醒
  • 活动更新通知
7.2.3 活动评价

评价功能:

  • 活动评分
  • 活动评论
  • 活动反馈
  • 活动推荐
7.2.4 活动创建

创建功能:

  • 学生组织创建活动
  • 活动审核流程
  • 活动管理
  • 数据统计

八、注意事项

8.1 开发注意事项

  1. 数据一致性:报名和签到状态需正确同步

  2. 人数控制:报名人数不能超过最大限制

  3. 时间判断:签到需在活动进行时间内

  4. 状态管理:活动状态需根据时间自动更新

  5. 用户体验:操作反馈需及时明确

8.2 常见问题

问题 原因 解决方案
报名状态不同步 状态更新错误 确保setState正确调用
人数统计错误 并发操作 添加锁机制
签到失败 时间判断错误 检查活动时间
学分计算错误 数据缺失 添加默认值
筛选无结果 条件过严 提供默认选项

8.3 使用技巧

🎓 校园活动参与技巧 🎓

活动选择

  • 关注感兴趣的活动类型
  • 查看活动时间和地点是否合适
  • 注意报名截止时间
  • 了解活动学分奖励

报名技巧

  • 提前报名,避免名额已满
  • 确认活动时间,避免冲突
  • 收藏感兴趣的活动
  • 关注活动更新通知

签到技巧

  • 提前到达活动地点
  • 准备好学生证
  • 活动开始后扫码签到
  • 确认签到成功

九、运行说明

9.1 环境要求

环境 版本要求
Flutter SDK >= 3.0.0
Dart SDK >= 2.17.0
鸿蒙OS API 21+
Web浏览器 Chrome 90+

9.2 运行命令

# 查看可用设备
flutter devices

# 运行到Web服务器
flutter run -d web-server -t lib/main_campus_activity.dart --web-port 8139

# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_campus_activity.dart

# 代码分析
flutter analyze lib/main_campus_activity.dart

十、总结

校园活动报名与签到应用通过首页、我的活动、签到、个人中心四大模块,为学生提供了一个便捷的校园活动参与平台。应用支持6种活动类型、3种活动状态筛选,让学生可以快速找到感兴趣的活动。

核心功能涵盖活动浏览、在线报名、扫码签到、学分统计四大模块。活动浏览支持按类型和状态筛选;在线报名支持报名和取消报名;扫码签到让学生在活动现场快速签到;学分统计帮助学生了解参与活动的收获。

应用采用 Material Design 3 设计规范,以沉稳的靛蓝色为主色调,营造专业、学术的氛围。通过本应用,希望能够帮助学生更好地参与校园活动,丰富校园生活,获得学分奖励。

校园活动报名与签到——丰富校园生活

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐