HarmonyOS ArkTS 实战:实现一个校园社团招新与成员管理应用
HarmonyOS ArkTS 实战:实现一个校园社团招新与成员管理应用
项目效果
本文使用 HarmonyOS 和 ArkTS 实现一个校园社团招新与成员管理应用。
应用可以发布社团招新信息,查看社团介绍,在线报名加入社团,管理社团成员,审核报名申请,并提供社团分类筛选、报名统计和成员管理等功能。
项目使用 DevEco Studio 开发,适配 API 23 及以上版本。
运行效果

功能介绍
本项目实现了以下功能:
- 发布社团招新信息
- 填写社团名称和介绍
- 设置社团分类和招新人数
- 设置报名要求和联系方式
- 浏览社团列表
- 在线报名加入社团
- 填写报名信息
- 审核报名申请
- 通过/拒绝报名
- 管理社团成员
- 设置成员职位
- 按社团分类筛选
- 统计社团总数、待审核、成员数
- 撤销报名
- 移除成员
定义数据结构
首先定义社团和报名申请的数据结构:
interface ClubMember {
studentId: string;
name: string;
department: string;
position: string;
joinTime: string;
}
interface ClubApplication {
id: number;
studentId: string;
name: string;
department: string;
phone: string;
introduce: string;
status: string;
applyTime: string;
}
interface Club {
id: number;
name: string;
description: string;
category: string;
president: string;
contact: string;
requirement: string;
maxMembers: number;
logo: string;
members: ClubMember[];
applications: ClubApplication[];
createTime: string;
}
字段说明如下:
ClubMember:社团成员studentId:学号name:姓名department:院系position:职位joinTime:加入时间
ClubApplication:报名申请id:申请编号studentId:学号name:姓名department:院系phone:联系方式introduce:自我介绍status:申请状态(待审核/已通过/已拒绝)applyTime:申请时间
Club:社团信息id:社团编号name:社团名称description:社团介绍category:分类president:社长contact:联系方式requirement:报名要求maxMembers:招新人数上限logo:社团logo颜色members:成员列表applications:报名申请列表createTime:创建时间
初始化页面状态
使用 @State 保存输入内容、分类选择、筛选条件和当前用户:
@State private clubNameText: string = '';
@State private descText: string = '';
@State private presidentText: string = '';
@State private contactText: string = '';
@State private requirementText: string = '';
@State private maxMembersText: string = '';
@State private applyNameText: string = '';
@State private applyIdText: string = '';
@State private applyDeptText: string = '';
@State private applyPhoneText: string = '';
@State private applyIntroText: string = '';
@State private selectedCategory: string = '学术科技';
@State private filterCategory: string = '全部';
@State private currentUserId: string = '2023001';
@State private nextClubId: number = 5;
@State private nextApplyId: number = 10;
准备一些初始社团数据:
@State private clubs: Club[] = [
{
id: 1,
name: '鸿蒙开发社',
description: '学习HarmonyOS开发,参加各类计算机竞赛,做开源项目',
category: '学术科技',
president: '张社长',
contact: '微信:harmonydev',
requirement: '对编程感兴趣,每周能参加社团活动',
maxMembers: 50,
logo: '#3B82F6',
members: [
{ studentId: '2022001', name: '张同学', department: '计算机学院', position: '社长', joinTime: '2025-09-01' },
{ studentId: '2022002', name: '李同学', department: '信息学院', position: '副社长', joinTime: '2025-09-01' }
],
applications: [
{
id: 1,
studentId: '2023001',
name: '王同学',
department: '计算机学院',
phone: '138****1234',
introduce: '学过ArkTS,想参加鸿蒙开发比赛',
status: '待审核',
applyTime: '2026-07-15'
}
],
createTime: '2025-09-01'
},
{
id: 2,
name: '篮球协会',
description: '组织篮球比赛,日常训练,参加校际联赛',
category: '体育竞技',
president: '刘会长',
contact: 'QQ:123456789',
requirement: '热爱篮球,有一定基础',
maxMembers: 100,
logo: '#F59E0B',
members: [
{ studentId: '2022003', name: '刘同学', department: '体育学院', position: '会长', joinTime: '2025-09-01' }
],
applications: [],
createTime: '2025-09-01'
},
{
id: 3,
name: '吉他社',
description: '吉他教学,乐队排练,校园演出',
category: '文化艺术',
president: '陈社长',
contact: '微信:guitar2026',
requirement: '有无基础均可,热爱音乐',
maxMembers: 60,
logo: '#8B5CF6',
members: [],
applications: [
{
id: 2,
studentId: '2023002',
name: '赵同学',
department: '文学院',
phone: '139****5678',
introduce: '学过一年吉他,想加入乐队',
status: '已通过',
applyTime: '2026-07-10'
}
],
createTime: '2025-09-01'
},
{
id: 4,
name: '志愿者协会',
description: '组织各类志愿活动,进博会、马拉松等大型活动志愿服务',
category: '公益志愿',
president: '周会长',
contact: '电话:021-12345678',
requirement: '有爱心,能抽出时间参加志愿活动',
maxMembers: 200,
logo: '#EC4899',
members: [
{ studentId: '2022004', name: '周同学', department: '社会学院', position: '会长', joinTime: '2025-09-01' }
],
applications: [],
createTime: '2025-09-01'
}
];
创建社团
用户可以创建新社团:
private createClub(): void {
const name: string = this.clubNameText.trim();
const desc: string = this.descText.trim();
const president: string = this.presidentText.trim();
const contact: string = this.contactText.trim();
const max: number = parseInt(this.maxMembersText);
if (name.length === 0 || desc.length === 0 || president.length === 0 || isNaN(max)) {
return;
}
const colors = ['#3B82F6', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6', '#EC4899', '#06B6D4'];
const randomColor = colors[Math.floor(Math.random() * colors.length)];
const club: Club = {
id: this.nextClubId,
name,
description: desc,
category: this.selectedCategory,
president,
contact,
requirement: this.requirementText.trim() || '无特殊要求',
maxMembers: max,
logo: randomColor,
members: [{
studentId: this.currentUserId,
name: president,
department: '创建者',
position: '社长',
joinTime: new Date().toISOString().split('T')[0]
}],
applications: [],
createTime: new Date().toISOString().split('T')[0]
};
this.clubs = [club, ...this.clubs];
this.nextClubId += 1;
this.clubNameText = '';
this.descText = '';
this.presidentText = '';
this.contactText = '';
this.requirementText = '';
this.maxMembersText = '';
}
创建社团的人自动成为社长。
报名加入社团
用户可以报名加入社团:
private applyClub(clubId: number): void {
const name: string = this.applyNameText.trim();
const studentId: string = this.applyIdText.trim();
const dept: string = this.applyDeptText.trim();
const phone: string = this.applyPhoneText.trim();
if (name.length === 0 || studentId.length === 0 || dept.length === 0 || phone.length === 0) {
return;
}
this.clubs = this.clubs.map((club: Club) => {
if (club.id === clubId) {
const alreadyApplied = club.applications.some(a => a.studentId === studentId && a.status === '待审核');
const alreadyMember = club.members.some(m => m.studentId === studentId);
if (!alreadyApplied && !alreadyMember) {
const newApplication: ClubApplication = {
id: this.nextApplyId,
studentId,
name,
department: dept,
phone,
introduce: this.applyIntroText.trim(),
status: '待审核',
applyTime: new Date().toISOString().split('T')[0]
};
this.nextApplyId += 1;
return {
id: club.id,
name: club.name,
description: club.description,
category: club.category,
president: club.president,
contact: club.contact,
requirement: club.requirement,
maxMembers: club.maxMembers,
logo: club.logo,
members: club.members,
applications: [newApplication, ...club.applications],
createTime: club.createTime
};
}
}
return club;
});
this.applyNameText = '';
this.applyIdText = '';
this.applyDeptText = '';
this.applyPhoneText = '';
this.applyIntroText = '';
}
已经是成员或有待审核申请的不能重复报名。
审核报名申请
社长可以审核报名申请:
private approveApplication(clubId: number, applyId: number, approved: boolean): void {
this.clubs = this.clubs.map((club: Club) => {
if (club.id === clubId) {
const updatedApplications = club.applications.map((app: ClubApplication) => {
if (app.id === applyId && app.status === '待审核') {
return {
id: app.id,
studentId: app.studentId,
name: app.name,
department: app.department,
phone: app.phone,
introduce: app.introduce,
status: approved ? '已通过' : '已拒绝',
applyTime: app.applyTime
};
}
return app;
});
let updatedMembers = [...club.members];
if (approved && club.members.length < club.maxMembers) {
const app = club.applications.find(a => a.id === applyId);
if (app) {
updatedMembers.push({
studentId: app.studentId,
name: app.name,
department: app.department,
position: '社员',
joinTime: new Date().toISOString().split('T')[0]
});
}
}
return {
id: club.id,
name: club.name,
description: club.description,
category: club.category,
president: club.president,
contact: club.contact,
requirement: club.requirement,
maxMembers: club.maxMembers,
logo: club.logo,
members: updatedMembers,
applications: updatedApplications,
createTime: club.createTime
};
}
return club;
});
}
审核通过后自动加入成员列表,审核拒绝则标记为已拒绝。
筛选社团
页面支持按分类筛选社团:
private getFilteredClubs(): Club[] {
if (this.filterCategory === '全部') {
return this.clubs;
}
return this.clubs.filter(
(club: Club) => club.category === this.filterCategory
);
}
分类选择按钮封装:
@Builder
CategoryButton(name: string) {
Button(name)
.height(32)
.padding({ left: 14, right: 14 })
.fontSize(12)
.fontColor(this.selectedCategory === name ? Color.White : '#344054')
.backgroundColor(
this.selectedCategory === name ? '#0D9488' : '#F3F4F6'
)
.borderRadius(16)
.onClick(() => {
this.selectedCategory = name;
});
}
@Builder
FilterCategoryButton(name: string) {
Button(name)
.height(32)
.padding({ left: 14, right: 14 })
.fontSize(12)
.fontColor(this.filterCategory === name ? Color.White : '#344054')
.backgroundColor(
this.filterCategory === name ? '#0D9488' : '#CCFBF1'
)
.borderRadius(16)
.onClick(() => {
this.filterCategory = name;
});
}
统计社团数据
统计社团总数、待审核申请和总成员数:
private getTotalPendingApps(): number {
return this.clubs.reduce((sum: number, club: Club) => {
return sum + club.applications.filter(a => a.status === '待审核').length;
}, 0);
}
private getTotalMembers(): number {
return this.clubs.reduce((sum: number, club: Club) => {
return sum + club.members.length;
}, 0);
}
顶部统计区域展示社团总数、待审核、总成员数:
this.StatCard(
'社团总数',
`${this.clubs.length}`,
'#0D9488',
'#F0FDFA'
);
this.StatCard(
'待审核',
`${this.getTotalPendingApps()}`,
'#D97706',
'#FFF7E8'
);
this.StatCard(
'总成员',
`${this.getTotalMembers()}`,
'#7C3AED',
'#F5F3FF'
);
设置状态颜色
不同申请状态使用不同颜色:
private getStatusColor(status: string): ResourceColor {
if (status === '待审核') {
return '#D97706';
}
if (status === '已通过') {
return '#059669';
}
return '#DC2626';
}
private getStatusBgColor(status: string): ResourceColor {
if (status === '待审核') {
return '#FEF3C7';
}
if (status === '已通过') {
return '#DCFCE7';
}
return '#FEE2E2';
}
颜色含义如下:
- 橙色:待审核
- 绿色:已通过
- 红色:已拒绝
- 蓝绿色:页面主题色
使用列表展示社团
使用 List 和 ForEach 渲染社团列表:
List({ space: 12 }) {
ForEach(
this.getFilteredClubs(),
(club: Club) => {
ListItem() {
this.ClubCard(club)
}
},
(club: Club) => club.id.toString()
);
}
.width('100%')
.layoutWeight(1)
.scrollBar(BarState.Off);
每个社团使用独立卡片展示,卡片中包含社团logo、名称、分类、介绍、社长、成员数、申请数和操作按钮。
页面设计说明
应用使用蓝绿色作为主题色,适合社团青春活力的氛围。
页面主要分为以下区域:
- 顶部标题和招新季提示
- 社团数据统计区域
- 创建社团表单
- 社团分类筛选区域
- 社团列表
- 报名申请弹窗和成员管理
页面采用浅灰色背景和白色卡片。不同社团使用不同颜色的圆形logo,申请状态使用对应颜色标签,成员数和申请数使用角标展示,便于快速了解社团情况。
SDK 配置
本项目使用 HarmonyOS API 24,满足 API 23 及以上要求:
{
"name": "default",
"compatibleSdkVersion": "6.1.1(24)",
"runtimeOS": "HarmonyOS",
"targetSdkVersion": "6.1.1(24)",
"compileSdkVersion": "6.1.1(24)"
}
entry 模块中的运行系统也要保持一致:
{
"apiType": "stageMode",
"targets": [
{
"name": "default",
"runtimeOS": "HarmonyOS"
}
]
}
运行项目
使用 DevEco Studio 打开项目,然后找到:
entry/src/main/ets/pages/Index.ets
等待项目同步完成,点击右侧的 Preview 按钮即可查看应用效果。
项目总结
本文使用 HarmonyOS 和 ArkTS 实现了一个校园社团招新与成员管理应用。
项目实现了社团创建、分类筛选、在线报名、申请审核、成员管理、职位设置、报名统计等功能。
通过这个项目可以掌握:
- ArkTS 接口定义和嵌套数据结构
@State状态管理- 复杂数组操作和状态更新
List和ForEach列表渲染map和reduce数组方法- 报名审核流程
- 成员管理逻辑
- 自定义
@Builder组件 - HarmonyOS 社交类应用布局
后续还可以加入社团活动发布、社团公告、消息通知、社团相册、经费管理、换届选举、社团评分和活动签到等功能。
更多推荐


所有评论(0)