最近在做一個任務打卡系統。
流程大概是這樣。 活動報名---》組隊---》開啟任務---》完成任務---》展示排名。
已經基本完成,這裡做個簡單總結
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
}
}
});
流程圖