perf: 仪表盘

This commit is contained in:
kuaifan 2021-12-23 12:21:23 +08:00
parent b208634e40
commit 1801ea7873
6 changed files with 105 additions and 126 deletions

View File

@ -24,33 +24,6 @@ use Request;
*/
class ProjectController extends AbstractController
{
/**
* 任务统计
*/
public function statistics()
{
User::auth();
$data = [];
// 今日待完成
$data['today'] = ProjectTask::authData(null, true)->whereParentId(0)
->whereNull('archived_at')
->whereNull('complete_at')
->betweenTime(Carbon::today()->startOfDay(), Carbon::today()->endOfDay())
->count();
// 超期未完成
$data['overdue'] = ProjectTask::authData(null, true)->whereParentId(0)
->whereNull('archived_at')
->whereNull('complete_at')
->whereNotNull('end_at')
->where('end_at', '<', Carbon::now())
->count();
return Base::retSuccess('success', $data);
}
/**
* 获取项目列表
*

View File

@ -41,10 +41,10 @@
<i class="taskfont">&#xe6fb;</i>
<div class="menu-title">{{$L('仪表盘')}}</div>
<Badge
v-if="projectStatistics.today > 0 || projectStatistics.overdue > 0"
v-if="dashboardData.today.length > 0 || dashboardData.overdue.length > 0"
class="menu-badge"
:type="projectStatistics.overdue > 0 ? '' : 'primary'"
:count="projectStatistics.today + projectStatistics.overdue"></Badge>
:type="dashboardData.overdue.length > 0 ? 'error' : 'primary'"
:count="dashboardData.today.length + dashboardData.overdue.length"></Badge>
</li>
<li @click="toggleRoute('calendar')" :class="classNameRoute('calendar')">
<i class="taskfont">&#xe6f5;</i>
@ -229,7 +229,6 @@ export default {
//
this.$store.dispatch("getUserInfo");
this.$store.dispatch("getTaskPriority");
this.$store.dispatch("getProjectStatistics");
//
this.notificationInit();
this.onVisibilityChange();
@ -251,12 +250,11 @@ export default {
'dialogs',
'projects',
'projectTotal',
'projectStatistics',
'taskId',
'dialogMsgPush',
]),
...mapGetters(['taskData']),
...mapGetters(['taskData', 'dashboardData']),
msgAllUnread() {
let num = 0;

View File

@ -8,14 +8,14 @@
<li @click="dashboard='today'">
<div class="block-title">{{$L('今日待完成')}}</div>
<div class="block-data">
<div class="block-num">{{projectStatistics.today || 0}}</div>
<div class="block-num">{{dashboardData.today.length}}</div>
<i class="taskfont">&#xe6f4;</i>
</div>
</li>
<li @click="dashboard='overdue'">
<div class="block-title">{{$L('超期未完成')}}</div>
<div class="block-data">
<div class="block-num">{{projectStatistics.overdue || 0}}</div>
<div class="block-num">{{dashboardData.overdue.length}}</div>
<i class="taskfont">&#xe603;</i>
</div>
</li>
@ -96,7 +96,7 @@
</template>
<script>
import {mapState} from "vuex";
import {mapGetters, mapState} from "vuex";
import AppDown from "../../components/AppDown";
export default {
@ -107,7 +107,6 @@ export default {
nowInterval: null,
loadIng: 0,
active: false,
dashboard: 'today',
taskLoad: {},
@ -127,17 +126,13 @@ export default {
},
activated() {
this.getTask();
this.active = true;
this.$store.dispatch("getProjectStatistics");
},
deactivated() {
this.active = false;
this.$store.dispatch("getDashboardTasks");
},
computed: {
...mapState(['userInfo', 'projects', 'projectStatistics', 'tasks', 'taskId']),
...mapState(['userInfo', 'projects', 'tasks', 'taskId']),
...mapGetters(['dashboardData']),
title() {
const {dashboard} = this;
@ -153,34 +148,17 @@ export default {
list() {
const {dashboard} = this;
const todayStart = $A.Date($A.formatDate("Y-m-d 00:00:00")),
todayEnd = $A.Date($A.formatDate("Y-m-d 23:59:59"));
let datas = $A.cloneJSON(this.tasks);
datas = datas.filter((data) => {
if (data.complete_at) {
return false;
}
if (!data.end_at) {
return false;
}
if (!data.owner) {
return false;
}
const start = $A.Date(data.start_at),
end = $A.Date(data.end_at);
data._start_time = start;
data._end_time = end;
switch (dashboard) {
case 'today':
return (start <= todayStart && todayStart <= end) || (start <= todayEnd && todayEnd <= end) || (start > todayStart && todayEnd > end);
case 'overdue':
return end <= todayStart;
default:
return false;
}
})
return datas.sort((a, b) => {
return a._end_time - b._end_time;
let data = [];
switch (dashboard) {
case 'today':
data = this.dashboardData.today;
break
case 'overdue':
data = this.dashboardData.overdue;
break
}
return data.sort((a, b) => {
return $A.Date(a.end_at) - $A.Date(b.end_at);
});
},
@ -198,43 +176,7 @@ export default {
},
},
watch: {
dashboard() {
this.getTask();
},
taskId(id) {
if (id == 0 && this.active) {
this.$store.dispatch("getProjectStatistics");
}
}
},
methods: {
getTask() {
let data = {complete: "no"};
switch (this.dashboard) {
case 'today':
data.time = [
$A.formatDate("Y-m-d 00:00:00"),
$A.formatDate("Y-m-d 23:59:59")
]
break;
case 'overdue':
data.time_before = $A.formatDate("Y-m-d 00:00:00")
break;
default:
return;
}
//
this.loadIng++;
this.$store.dispatch("getTasks", data).then(() => {
this.loadIng--;
}).catch(() => {
this.loadIng--;
})
},
dropTask(task, command) {
switch (command) {
case 'complete':
@ -275,7 +217,6 @@ export default {
task_id: task.id,
})).then(() => {
this.$set(this.taskLoad, task.id, false);
this.$store.dispatch("getProjectStatistics");
}).catch(({msg}) => {
$A.modalError(msg);
this.$set(this.taskLoad, task.id, false);
@ -301,7 +242,6 @@ export default {
$A.messageSuccess(msg);
this.$Modal.remove();
this.$set(this.taskLoad, task.id, false);
this.$store.dispatch("getProjectStatistics");
}).catch(({msg}) => {
$A.modalError(msg, 301);
this.$Modal.remove();

View File

@ -216,9 +216,9 @@ export default {
state.userToken = userInfo.token;
state.userIsAdmin = state.method.inArray('admin', userInfo.identity);
state.method.setStorage("userInfo", state.userInfo);
state.projects = [];
dispatch("getProjects");
dispatch("getDialogs");
dispatch("getDashboardTasks");
dispatch("websocketConnection");
resolve()
});
@ -697,19 +697,6 @@ export default {
});
},
/**
* 获取项目统计
* @param state
* @param dispatch
*/
getProjectStatistics({state, dispatch}) {
dispatch("call", {
url: 'project/statistics',
}).then(({data}) => {
state.projectStatistics = data;
});
},
/** *****************************************************************************************/
/** ************************************** 列表 **********************************************/
/** *****************************************************************************************/
@ -999,6 +986,52 @@ export default {
});
},
/**
* 获取Dashboard相关任务
* @param state
* @param dispatch
*/
getDashboardTasks({state, dispatch}) {
return new Promise(function (resolve, reject) {
let loadIng = 2;
let error = 0;
let call = (err) => {
if (err) {
error++;
}
loadIng--;
if (loadIng == 0) {
if (error > 0) {
reject()
} else {
resolve()
}
}
}
//
dispatch("getTasks", {
complete: "no",
time: [
$A.formatDate("Y-m-d 00:00:00"),
$A.formatDate("Y-m-d 23:59:59")
]
}).then(() => {
call();
}).catch(() => {
call(true);
})
//
dispatch("getTasks", {
complete: "no",
time_before: $A.formatDate("Y-m-d H:i:s")
}).then(() => {
call();
}).catch(() => {
call(true);
})
})
},
/**
* 删除任务
* @param state

View File

@ -72,5 +72,41 @@ export default {
}
return cache && !!cache[key];
}
},
dashboardData(state) {
const todayStart = $A.Date($A.formatDate("Y-m-d 00:00:00")),
todayEnd = $A.Date($A.formatDate("Y-m-d 23:59:59")),
todayNow = $A.Date($A.formatDate("Y-m-d H:i:s"));
const todayTasks = state.tasks.filter(data => {
if (data.complete_at) {
return false;
}
if (!data.end_at) {
return false;
}
if (!data.owner) {
return false;
}
const start = $A.Date(data.start_at),
end = $A.Date(data.end_at);
return (start <= todayStart && todayStart <= end) || (start <= todayEnd && todayEnd <= end) || (start > todayStart && todayEnd > end);
})
const overdueTasks = state.tasks.filter(data => {
if (data.complete_at) {
return false;
}
if (!data.end_at) {
return false;
}
if (!data.owner) {
return false;
}
return $A.Date(data.end_at) <= todayNow;
})
return {
today: todayTasks,
overdue: overdueTasks,
}
}
}

View File

@ -304,7 +304,6 @@ state.projectId = 0;
state.projects = [];
state.projectTotal = 0;
state.projectLoad = 0;
state.projectStatistics = {};
state.columns = [];
state.taskId = 0;
state.tasks = [];