kuaifan 5 anni fa
parent
commit
ca71e347fa

+ 31 - 2
app/Http/Controllers/Api/ProjectController.php

@@ -554,6 +554,11 @@ class ProjectController extends Controller
      * @apiParam {Number} [archived]            是否归档
      * - 0: 未归档
      * - 1: 已归档
+     * @apiParam {String} [type]                任务类型
+     * - 未完成
+     * - 已超期
+     * - 已完成
+     * @apiParam {Number} [statistics]          是否获取统计数据(1:获取)
      * @apiParam {Number} [page]                当前页,默认:1
      * @apiParam {Number} [pagesize]            每页显示数量,默认:20,最大:100
      */
@@ -576,11 +581,29 @@ class ProjectController extends Controller
             return Base::retError('你不在项目成员内!');
         }
         //
+        $whereFunc = null;
         $whereArray = [];
         $whereArray[] = ['project_lists.id', '=', $projectid];
         $whereArray[] = ['project_lists.delete', '=', 0];
-        if (in_array(intval(Request::input('archived')), [0, 1])) {
-            $whereArray[] = ['project_task.archived', '=', Request::input('archived')];
+        if (in_array(Request::input('archived'), [0, 1])) {
+            $whereArray[] = ['project_task.archived', '=', intval(Request::input('archived'))];
+        }
+        $type = trim(Request::input('type'));
+        switch ($type) {
+            case '未完成':
+                $whereArray[] = ['project_task.status', '=', '进行中'];
+                $whereFunc = function($query) {
+                    $query->where('project_task.enddate', '=', 0)->orWhere('project_task.enddate', '>', Base::time());
+                };
+                break;
+            case '已超期':
+                $whereArray[] = ['project_task.status', '=', '进行中'];
+                $whereArray[] = ['project_task.enddate', '>', 0];
+                $whereArray[] = ['project_task.enddate', '<=', Base::time()];
+                break;
+            case '已完成':
+                $whereArray[] = ['project_task.status', '=', '已完成'];
+                break;
         }
         //
         $orderBy = 'project_task.id';
@@ -592,11 +615,17 @@ class ProjectController extends Controller
             ->join('project_task', 'project_lists.id', '=', 'project_task.projectid')
             ->select(['project_task.*'])
             ->where($whereArray)
+            ->where($whereFunc)
             ->orderByDesc($orderBy)->paginate(Min(Max(Base::nullShow(Request::input('pagesize'), 10), 1), 100));
         $lists = Base::getPageList($lists);
         if ($lists['total'] == 0) {
             return Base::retError('未找到任何相关的任务');
         }
+        if (intval(Request::input('statistics')) == 1) {
+            $lists['statistics_unfinished'] = $type === '未完成' ? $lists['total'] : DB::table('project_task')->where('status', '进行中')->where(function($query) { $query->where('enddate', '=', 0)->orWhere('enddate', '>', Base::time()); })->count();
+            $lists['statistics_overdue'] = $type === '已超期' ? $lists['total'] : DB::table('project_task')->where('status', '进行中')->whereBetween('enddate', [0, Base::time()])->count();
+            $lists['statistics_complete'] = $type === '已完成' ? $lists['total'] : DB::table('project_task')->where('status', '已完成')->count();
+        }
         return Base::retSuccess('success', $lists);
     }
 

resources/assets/js/main/components/directives/clickoutside.js → resources/assets/js/_modules/directives/clickoutside.js


resources/assets/js/main/components/directives/popper-novalue.js → resources/assets/js/_modules/directives/popper-novalue.js


resources/assets/js/main/components/directives/transfer-dom.js → resources/assets/js/_modules/directives/transfer-dom.js


+ 3 - 3
resources/assets/js/main/components/UseridInput.vue

@@ -102,9 +102,9 @@
 </style>
 <script>
 
-    import clickoutside from './directives/clickoutside';
-    import TransferDom from './directives/transfer-dom';
-    import Popper from './directives/popper-novalue';
+    import clickoutside from '../../_modules/directives/clickoutside';
+    import TransferDom from '../../_modules/directives/transfer-dom';
+    import Popper from '../../_modules/directives/popper-novalue';
     import WLoading from "./WLoading";
 
     export default {

+ 3 - 4
resources/assets/js/main/components/project/complete.vue

@@ -3,7 +3,7 @@
         <!-- 列表 -->
         <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" stripe></Table>
         <!-- 分页 -->
-        <Page class="pageBox" :total="listTotal" :current="listPage" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total></Page>
+        <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
     </div>
 </template>
 
@@ -50,12 +50,12 @@
                 "key": 'createuser',
                 "minWidth": 80,
             }, {
-                "title": "账号",
+                "title": "负责人",
                 "key": 'username',
                 "minWidth": 80,
             }, {
                 "title": "归档时间",
-                "minWidth": 160,
+                "width": 160,
                 render: (h, params) => {
                     return h('span', $A.formatDate("Y-m-d H:i:s", params.row.archiveddate));
                 }
@@ -117,7 +117,6 @@
         watch: {
             projectid() {
                 if (this.loadYet) {
-                    this.loadYet = true;
                     this.getLists(true);
                 }
             },

+ 258 - 0
resources/assets/js/main/components/project/statistics.vue

@@ -0,0 +1,258 @@
+<template>
+    <div class="project-statistics">
+        <!-- 标签 -->
+        <ul class="state-overview">
+            <li :class="[taskType==='未完成'?'active':'']" @click="taskType='未完成'">
+                <div class="yellow">
+                    <h1 class="count">{{statistics_unfinished}}</h1>
+                    <p>未完成任务</p>
+                </div>
+            </li>
+            <li :class="[taskType==='已超期'?'active':'']" @click="taskType='已超期'">
+                <div class="red">
+                    <h1 class="count">{{statistics_overdue}}</h1>
+                    <p>超期任务</p>
+                </div>
+            </li>
+            <li :class="[taskType==='已完成'?'active':'']" @click="taskType='已完成'">
+                <div class="terques">
+                    <h1 class="count">{{statistics_complete}}</h1>
+                    <p>已完成任务</p>
+                </div>
+            </li>
+        </ul>
+        <!-- 列表 -->
+        <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" stripe></Table>
+        <!-- 分页 -->
+        <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
+    </div>
+</template>
+
+<style lang="scss" scoped>
+    .project-statistics {
+        .tableFill {
+            margin: 12px 12px 20px;
+        }
+
+        ul.state-overview {
+            display: flex;
+            align-items: center;
+
+            > li {
+                flex: 1;
+                cursor: pointer;
+                margin: 0 10px 5px;
+
+                > div {
+                    position: relative;
+                    -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+                    box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+                    transition: all 0.2s;
+                    border-radius: 6px;
+                    color: #ffffff;
+                    height: 110px;
+                    display: flex;
+                    flex-direction: column;
+                    justify-content: center;
+                    align-items: center;
+
+                    &.terques {
+                        background: #17BE6B;
+                    }
+
+                    &.purple {
+                        background: #A218A5;
+                    }
+
+                    &.red {
+                        background: #ED3F14;
+                    }
+
+                    &.yellow {
+                        background: #FF9900;
+                    }
+
+                    &.blue {
+                        background: #2D8CF0;
+                    }
+
+                    &:hover {
+                        box-shadow: 2px 2px 8px 0 rgba(0, 0, 0, 0.38);
+                    }
+
+                    &:after {
+                        position: absolute;
+                        content: "";
+                        left: 50%;
+                        bottom: 3px;
+                        width: 0;
+                        height: 2px;
+                        transform: translate(-50%, 0);
+                        background-color: #FFFFFF;
+                        border-radius: 2px;
+                        transition: all 0.3s;
+                        opacity: 0;
+                    }
+
+                    > h1 {
+                        font-size: 36px;
+                        margin: -2px 0 0;
+                        padding: 0;
+                        font-weight: 500;
+                    }
+
+                    > p {
+                        font-size: 18px;
+                        margin: 0;
+                        padding: 0;
+                    }
+                }
+
+                &.active {
+                    > div {
+                        &:after {
+                            width: 90%;
+                            opacity: 1;
+                        }
+                    }
+                }
+            }
+        }
+    }
+</style>
+<script>
+    export default {
+        name: 'ProjectStatistics',
+        props: {
+            projectid: {
+                default: 0
+            },
+            canload: {
+                type: Boolean,
+                default: true
+            },
+        },
+        data () {
+            return {
+                loadYet: false,
+
+                loadIng: 0,
+
+                columns: [],
+
+                taskType: '未完成',
+
+                lists: [],
+                listPage: 1,
+                listTotal: 0,
+                noDataText: "数据加载中.....",
+
+                statistics_unfinished: 0,
+                statistics_overdue: 0,
+                statistics_complete: 0,
+            }
+        },
+        created() {
+            this.columns = [{
+                "title": "任务名称",
+                "key": 'title',
+                "minWidth": 100,
+            }, {
+                "title": "创建人",
+                "key": 'createuser',
+                "minWidth": 80,
+            }, {
+                "title": "负责人",
+                "key": 'username',
+                "minWidth": 80,
+            }, {
+                "title": "创建时间",
+                "width": 160,
+                render: (h, params) => {
+                    return h('span', $A.formatDate("Y-m-d H:i:s", params.row.indate));
+                }
+            }];
+        },
+        mounted() {
+            if (this.canload) {
+                this.loadYet = true;
+                this.getLists(true);
+            }
+        },
+
+        watch: {
+            projectid() {
+                if (this.loadYet) {
+                    this.getLists(true);
+                }
+            },
+            canload(val) {
+                if (val && !this.loadYet) {
+                    this.loadYet = true;
+                    this.getLists(true);
+                }
+            },
+            taskType() {
+                if (this.loadYet) {
+                    this.getLists(true);
+                }
+            }
+        },
+
+        methods: {
+            setPage(page) {
+                this.listPage = page;
+                this.getLists();
+            },
+
+            setPageSize(size) {
+                if (Math.max($A.runNum(this.listPageSize), 10) != size) {
+                    this.listPageSize = size;
+                    this.getLists();
+                }
+            },
+
+            getLists(resetLoad) {
+                if (resetLoad === true) {
+                    this.listPage = 1;
+                }
+                if (this.projectid == 0) {
+                    this.lists = [];
+                    this.listTotal = 0;
+                    this.noDataText = "没有相关的数据";
+                    return;
+                }
+                this.loadIng++;
+                $A.aAjax({
+                    url: 'project/task/lists',
+                    data: {
+                        page: Math.max(this.listPage, 1),
+                        pagesize: Math.max($A.runNum(this.listPageSize), 10),
+                        projectid: this.projectid,
+                        type: this.taskType,
+                        statistics: 1
+                    },
+                    complete: () => {
+                        this.loadIng--;
+                    },
+                    success: (res) => {
+                        if (res.ret === 1) {
+                            this.lists = res.data.lists;
+                            this.listTotal = res.data.total;
+                            this.statistics_unfinished = res.data.statistics_unfinished;
+                            this.statistics_overdue = res.data.statistics_overdue;
+                            this.statistics_complete = res.data.statistics_complete;
+                        } else {
+                            this.lists = [];
+                            this.listTotal = 0;
+                            this.noDataText = res.msg;
+                            this.statistics_unfinished = 0;
+                            this.statistics_overdue = 0;
+                            this.statistics_complete = 0;
+                        }
+                    }
+                });
+            },
+        }
+    }
+</script>

+ 2 - 3
resources/assets/js/main/components/project/users.vue

@@ -5,7 +5,7 @@
         <!-- 列表 -->
         <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" stripe></Table>
         <!-- 分页 -->
-        <Page class="pageBox" :total="listTotal" :current="listPage" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total></Page>
+        <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
     </div>
 </template>
 
@@ -89,7 +89,7 @@
                 }
             }, {
                 "title": "加入时间",
-                "minWidth": 160,
+                "width": 160,
                 render: (h, params) => {
                     return h('span', $A.formatDate("Y-m-d H:i:s", params.row.indate));
                 }
@@ -152,7 +152,6 @@
         watch: {
             projectid() {
                 if (this.loadYet) {
-                    this.loadYet = true;
                     this.getLists(true);
                 }
             },

+ 6 - 3
resources/assets/js/main/pages/project.vue

@@ -65,7 +65,7 @@
                 </li>
             </ul>
             <!-- 分页 -->
-            <Page v-if="listTotal > 0" class="pageBox" :total="listTotal" :current="listPage" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total></Page>
+            <Page v-if="listTotal > 0" class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total></Page>
         </w-content>
 
         <Modal
@@ -109,7 +109,9 @@
                 <TabPane :label="$L('成员管理')" name="member">
                     <project-users :canload="projectDrawerShow && projectDrawerTab == 'member'" :projectid="handleProjectId"></project-users>
                 </TabPane>
-                <TabPane :label="$L('项目统计')" name="statistics"></TabPane>
+                <TabPane :label="$L('项目统计')" name="statistics">
+                    <project-statistics :canload="projectDrawerShow && projectDrawerTab == 'statistics'" :projectid="handleProjectId"></project-statistics>
+                </TabPane>
             </Tabs>
         </Drawer>
 
@@ -256,8 +258,9 @@
     import WLoading from "../components/WLoading";
     import ProjectComplete from "../components/project/complete";
     import ProjectUsers from "../components/project/users";
+    import ProjectStatistics from "../components/project/statistics";
     export default {
-        components: {ProjectUsers, ProjectComplete, WLoading, WContent, WHeader},
+        components: {ProjectStatistics, ProjectUsers, ProjectComplete, WLoading, WContent, WHeader},
         data () {
             return {
                 loadIng: 0,

+ 2 - 2
resources/assets/js/main/pages/team.vue

@@ -23,7 +23,7 @@
                     <!-- 列表 -->
                     <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" stripe></Table>
                     <!-- 分页 -->
-                    <Page class="pageBox" :total="listTotal" :current="listPage" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total></Page>
+                    <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total></Page>
                 </div>
             </div>
         </w-content>
@@ -152,7 +152,7 @@
                 }
             }, {
                 "title": "加入时间",
-                "minWidth": 160,
+                "width": 160,
                 render: (h, params) => {
                     return h('span', $A.formatDate("Y-m-d H:i:s", params.row.regdate));
                 }