任务打卡系统总结
最近在做一个任务打卡系统。
流程大概是这样。 活动报名---》组队---》开启任务---》完成任务---》展示排名。
已经基本完成,这里做个简单总结
1 需求
1.1 该打卡系统,分为两部分。
- 内部打卡。是自己使用,需要报名,
- 外部打卡。第三方使用,不需要报名。
因此该打卡系统需支持扩展。
即要把打卡的流程给抽离出来,可以接入任何一个第三方。
做区分很简单,只需通过两个字段
model_type
需要接入的第三方的类型activity_id
需要接入的第三方的数据id
1.2 组队模块
队长创建小组,队员扫描二维码,加入团队,达到指定人数,可开启任务。
1.3 任务模块
小组队员扫码或者提交密匙成功后,该小组即可进入下一任务。
2 数据字典
2.1 组队模块
两张表 user_teams
和 user_teams
user_teams
记录队长创建的小组
id ``
activity_id `第三方数据id`
model_type `第三方类型`
user_id `队长id`
name `小组名字`
slug`小组唯一标识符`
person_count_limit `小组人数`
status `小组状态`
created_at `小组创建时间`
dissolved_at `解散时间`
completed_at `小组开启任务时间`
users_teams
记录队员加入小组
id
activity_id `第三方数据id`
model_type `第三方类型`
user_id `队员id`
team_id `小组id`
status `用户在小组中的状态`
joined_at `加入时间`
exit_at `退出时间`
2.1 任务模块
两张表 activity_tasks
和 teams_tasks
activity_tasks
记录第三方的打卡任务
id
activity_id `第三方数据id`
model_type `第三方类型`
type `任务的类型`
name `任务的名字`
slug `任务唯一标识符`
img `任务图片`
key_lists `任务密匙列表`
key_used_lists `已用的密匙列表`
teams_tasks
记录小组进行到哪一个打卡任务
id
activity_id `第三方数据id`
model_type `第三方类型`
team_id `小组id`
task_id `任务id`
status `小组在该任务的状态`
started_at `小组开启该任务的时间`
completed_at `小组完成该任务的时间`
模型
3 后端业务实现
3.1 小组模块
小组中有三个数前端拿到,就可以 //todo。
- $usersTeam 用户在团队中的状态,对应
users_team
表中的一条记录 - $team 小组的相关信息,对应
user_team
表中的一条记录 - $users 队员列表
list($usersTeam,$team) = $user->hasTeam($activityId,$modelType);
//团队用户
$users = $team->users();
基本上每个 api
请求都要用到上面的三个数据。因此在设计业务的的时候,抽离出最小的关键的对象。接下来,就是这些对象的该怎么组合的问题了,就形成了,不同的业务逻辑。
3.2 任务模块
任务中有四个数据,前端拿到,就可以 //todo
- $currentTask 当前正在进行的任务
- $teamTasks 已经完成的任务和正在进行的任务,对应
team_tasks
表中的几条条记录 - $tasks 分配的所有任务,由$taskIds所得。
- $taskIds 分配的任务id 对应
user_team
表的taskIds
list($teamTasks,$tasks,$taskIds,$currentTask) = $user->teamTasks($modelType,$activityId);
任务模块主要的是如何给小组分配任务。比如说,不希望所有小组都从相同的任务开始。
比如说有 1,2,3,4,5,6 个任务
第一个小组分配任务顺序 1,2,3,4,5,6
第一个小组分配任务顺序 2,3,4,5,6,1
第一个小组分配任务顺序 3,4,5,6,1,2
依次的不断循环
伪代码实现
//所有任务的id
$taskIds=[];
//已选所有任务的第一个id
$taskFirstIds=[];
//统计每个任务被分配的数量
$taskIdsCount = array_count_values($taskFirstIds);
//从小到大排序
asort($taskIdsCount);
//选取第一个renwuid 作为开始
$taskStartId=array_key_first($taskIdsCount);
$key=array_search($taskStartId,$taskIds);
//最终结果
$ids =array_merge(array_slice($taskIds,$key),array_slice($taskIds,0,$key));
4 前端业务实现
有一个可以总结的,小组和任务状态管理,使用到了有限状态机查看。
小组和任务状态比较多。
比如小组,在数据库中的状态
- inviting 正在邀请
- starting 已完成
- automatic_dissolution 自动解散
- dissolution 解散
由于前端要把后端对应的状态映射到相对应的显示,对应到前端的状态转换,就比较多了
* create 正在创建
* inviting 正在邀请
* starting 已完成,正在开始任务
* edit 管理小组
把每一个状态的改变统一管理起来,逻辑清晰且可控。
new StateMachine({
transitions: [
{ name: 'start', from: 'none', to: 'create' },
{ name: 'invite', from: 'none', to: 'inviting' },
{ name: 'invite', from: 'create', to: 'inviting' },
{ name: 'invite', from: 'edit', to: 'inviting' },
{ name: 'started', from: 'inviting', to: 'starting' },
{ name: 'started', from: 'edit', to: 'starting' },
{ name: 'started', from: 'none', to: 'starting' },
{ name: 'dissolve', from: 'inviting', to: 'create' },
{ name: 'dissolve', from: 'edit', to: 'create' },
{ name: 'edit', from: 'inviting', to: 'edit' },
],
methods: {
onEnterCreate(lifecycle){
//todo
},
onEnterInviting(lifecycle){
//todo
},
onEnterStarting(lifecycle){
//todo
},
onEnterEdit(lifecycle){
//todo
}
}
});
流程图
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: