kuaifan il y a 5 ans
Parent
commit
f745370524

+ 306 - 0
app/Http/Controllers/Api/ReportController.php

@@ -0,0 +1,306 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Http\Controllers\Controller;
+use App\Model\DBCache;
+use App\Module\Base;
+use App\Module\Users;
+use DB;
+use Request;
+use Session;
+
+/**
+ * @apiDefine report
+ *
+ * 汇报
+ */
+class ReportController extends Controller
+{
+    public function __invoke($method, $action = '')
+    {
+        $app = $method ? $method : 'main';
+        if ($action) {
+            $app .= "__" . $action;
+        }
+        return (method_exists($this, $app)) ? $this->$app() : Base::ajaxError("404 not found (" . str_replace("__", "/", $app) . ").");
+    }
+
+    /**
+     * 获取
+     *
+     * @apiParam {String} type           类型
+     * - 日报
+     * - 周报
+     * @apiParam {Number} [id]          数据ID
+     * @apiParam {String} [act]         请求方式
+     * - submit: 保存
+     * - send: 仅发送
+     * - delete: 删除汇报
+     * - else: 获取
+     * @apiParam {String} [send]        是否发送(1:是),仅act=submit且未发送过的有效
+     * @apiParam {Object} [D]           Request Payload 提交
+     * - title: 标题
+     * - ccuser: 抄送人
+     * - content: 内容
+     */
+    public function template()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $id = intval(Request::input('id'));
+        $act = trim(Request::input('act'));
+        $type = trim(Request::input('type'));
+        if (!in_array($type, ['日报', '周报'])) {
+            return Base::retError('参数错误!');
+        }
+        $dateTitle = "";
+        //
+        $whereArray = [];
+        $whereArray[] = ['username', '=', $user['username']];
+        if ($id > 0) {
+            $whereArray[] = ['id', '=', $id];
+        } else {
+            switch ($type) {
+                case "日报":
+                    $whereArray[] = ['type', '=', '日报'];
+                    $whereArray[] = ['date', '=', date("Ymd")];
+                    $dateTitle = date("Y-m-d");
+                    break;
+                case "周报":
+                    $whereArray[] = ['type', '=', '周报'];
+                    $whereArray[] = ['date', '=', date("W")];
+                    $dateTitle = date("Y年m月") . "第" . Base::getMonthWeek() . "周";
+                    break;
+            }
+        }
+        //
+        $reportDetail = Base::DBC2A(DB::table('report_lists')->where($whereArray)->first());
+        if ($id > 0 && empty($reportDetail)) {
+            return Base::retError('没有相关的数据!');
+        }
+        if ($act == 'send') {
+            if (empty($reportDetail)) {
+                return Base::retError('没有相关的数据或已被删除!');
+            }
+            $ccuser = Base::string2array($reportDetail['ccuser']);
+            DB::table('report_ccuser')->where(['rid' => $reportDetail['id']])->update(['cc' => 0]);
+            foreach ($ccuser AS $ck => $cuser) {
+                if (!$cuser) {
+                    unset($ccuser[$ck]);
+                    continue;
+                }
+                DB::table('report_ccuser')->updateOrInsert(['rid' => $reportDetail['id'], 'username' => $cuser], ['cc' => 1]);
+            }
+            DB::table('report_lists')->where('id', $reportDetail['id'])->update([
+                'status' => '已发送',
+                'ccuser' => Base::array2string($ccuser)
+            ]);
+            return Base::retSuccess('发送成功!');
+        } elseif ($act == 'delete') {
+            if (empty($reportDetail)) {
+                return Base::retError('没有相关的数据或已被删除!');
+            }
+            if ($reportDetail['status'] == '已发送') {
+                return Base::retError('汇报已发送,无法删除!');
+            }
+            DB::table('report_lists')->where('id', $reportDetail['id'])->delete();
+            DB::table('report_ccuser')->where('rid', $reportDetail['id'])->delete();
+            DB::table('report_content')->where('rid', $reportDetail['id'])->delete();
+            return Base::retSuccess('删除成功!');
+        } elseif ($act == 'submit') {
+            $D = Base::getContentsParse('D');
+            if (empty($reportDetail)) {
+                DB::table('report_lists')->insert([
+                    'username' => $user['username'],
+                    'title' => $D['title'],
+                    'type' => $type,
+                    'status' => '未发送',
+                    'date' => $type=='日报'?date("Ymd"):date("W"),
+                    'indate' => Base::time(),
+                ]);
+                $reportDetail = Base::DBC2A(DB::table('report_lists')->where($whereArray)->first());
+            }
+            if (empty($reportDetail)) {
+                return Base::retError('系统繁忙,请稍后再试!');
+            }
+            //
+            $D['ccuser'] = explode(",", $D['ccuser']);
+            $send = $reportDetail['status'] == '已发送' ? 1 : intval(Request::input('send'));
+            if ($send) {
+                DB::table('report_ccuser')->where(['rid' => $reportDetail['id']])->update(['cc' => 0]);
+                foreach ($D['ccuser'] AS $ck => $cuser) {
+                    if (!$cuser) {
+                        unset($D['ccuser'][$ck]);
+                        continue;
+                    }
+                    DB::table('report_ccuser')->updateOrInsert(['rid' => $reportDetail['id'], 'username' => $cuser], ['cc' => 1]);
+                }
+                $reportDetail['status'] = '已发送';
+            }
+            //
+            DB::table('report_lists')->where('id', $reportDetail['id'])->update([
+                'title' => $D['title'],
+                'status' => $send ? '已发送' : '未发送',
+                'ccuser' => Base::array2string($D['ccuser'])
+            ]);
+            DB::table('report_content')->updateOrInsert(['rid' => $reportDetail['id']], ['content' => $D['content']]);
+            //
+            $reportDetail = array_merge($reportDetail, [
+                'ccuser' => $D['ccuser'],
+                'title' => $D['title'],
+                'content' => $D['content'],
+            ]);
+        }
+        if (empty($reportDetail)) {
+            //已完成
+            $completeContent = '';
+            $startTime = $type == '日报' ? strtotime(date('Y-m-d 00:00:00')) : strtotime(date('Y-m-d 00:00:00', strtotime('this week')));
+            $lists = Base::DBC2A(DB::table('project_task')
+                ->select(['title', 'completedate'])
+                ->where('username', $user['username'])
+                ->where('complete', 1)
+                ->where('delete', 0)
+                ->whereBetween('completedate', [$startTime, time()])
+                ->orderBy('completedate')
+                ->orderBy('id')
+                ->get());
+            foreach ($lists as $item) {
+                $pre = $type == '周报' ? ('<span>[周' . ['日', '一', '二', '三', '四', '五', '六'][date('w')] . ']</span>&nbsp;') : '';
+                $completeContent .= '<li>' . $pre . $item['title'] . '</li>';
+            }
+            if (empty($completeContent)) {
+                $completeContent = '<li>&nbsp;</li>';
+            }
+            //未完成
+            $unfinishedContent = '';
+            $finishTime = $type == '日报' ? strtotime(date('Y-m-d 23:59:59')) : strtotime(date('Y-m-d 23:59:59', strtotime('last day next week')));
+            $lists = Base::DBC2A(DB::table('project_task')
+                ->select(['title', 'enddate'])
+                ->where('username', $user['username'])
+                ->where('complete', 0)
+                ->where('delete', 0)
+                ->where('startdate', '>', 0)
+                ->where('enddate', '<', $finishTime)
+                ->orderBy('id')
+                ->get());
+            foreach ($lists as $item) {
+                $pre = $item['enddate'] > 0 && $item['enddate'] < time() ? '<span style="color:#ff0000;">[超期]</span>&nbsp;' : '';
+                $unfinishedContent .= '<li>' . $pre . $item['title'] . '</li>';
+            }
+            if (empty($unfinishedContent)) {
+                $unfinishedContent = '<li>&nbsp;</li>';
+            }
+            //
+            $reportDetail['title'] = ($user['nickname'] ?: $user['username']) . '的' . $type . '[' . $dateTitle . ']';
+            $reportDetail['ccuser'] = '';
+            $reportDetail['content'] = '<h2>已完成工作</h2><ol>' . $completeContent . '</ol><h2>未完成的工作</h2><ol>' . $unfinishedContent . '</ol>';
+            $reportDetail['status'] = '未保存';
+        } else {
+            $reportDetail['ccuser'] = implode(',' ,Base::string2array($reportDetail['ccuser']));
+            if (!isset($reportDetail['content'])) {
+                $reportDetail['content'] = DB::table('report_content')->select(['content'])->where('rid', $reportDetail['id'])->value('content');
+            }
+        }
+        return Base::retSuccess($act == 'submit' ? '保存成功' : 'success', $reportDetail);
+    }
+
+    /**
+     * 我的汇报
+     *
+     * @apiParam {Number} [page]                当前页,默认:1
+     * @apiParam {Number} [pagesize]            每页显示数量,默认:20,最大:100
+     */
+    public function my()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $lists = DB::table('report_lists')
+            ->where('username', $user['username'])
+            ->orderByDesc('id')
+            ->paginate(Min(Max(Base::nullShow(Request::input('pagesize'), 10), 1), 100));
+        $lists = Base::getPageList($lists);
+        if ($lists['total'] == 0) {
+            return Base::retError('未找到任何相关的汇报', $lists);
+        }
+        foreach ($lists['lists'] AS $key => $item) {
+            $lists['lists'][$key]['ccuser'] = Base::string2array($item['ccuser']);
+        }
+        return Base::retSuccess('success', $lists);
+    }
+
+    /**
+     * 我的汇报
+     *
+     * @apiParam {String} [username]            汇报者用户名
+     * @apiParam {Array} [indate]               汇报时间
+     * @apiParam {String} [type]                类型
+     * - 日报
+     * - 周报
+     * @apiParam {Object} [sorts]               排序方式,格式:{key:'', order:''}
+     * - key: username|indate
+     * - order: asc|desc
+     * @apiParam {Number} [page]                当前页,默认:1
+     * @apiParam {Number} [pagesize]            每页显示数量,默认:20,最大:100
+     */
+    public function receive()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $whereArray = [];
+        $whereArray[] = ['report_ccuser.username', '=', $user['username']];
+        $whereArray[] = ['report_ccuser.cc', '=', 1];
+        if (trim(Request::input('username'))) {
+            $whereArray[] = ['report_lists.username', '=', trim(Request::input('username'))];
+        }
+        if (in_array(trim(Request::input('type')), ['日报', '周报'])) {
+            $whereArray[] = ['report_lists.type', '=', trim(Request::input('type'))];
+        }
+        $indate = Request::input('indate');
+        if (is_array($indate)) {
+            if ($indate[0] > 0) $whereArr[] = ['report_lists.indate', '>=', Base::dayTimeF($indate[0])];
+            if ($indate[1] > 0) $whereArr[] = ['report_lists.indate', '<=', Base::dayTimeE($indate[1])];
+        }
+        //
+        $orderBy = '`id` DESC';
+        $sorts = Base::json2array(Request::input('sorts'));
+        if (in_array($sorts['order'], ['asc', 'desc'])) {
+            switch ($sorts['key']) {
+                case 'username':
+                case 'indate':
+                    $orderBy = '`' . $sorts['key'] . '` ' . $sorts['order'] . ',`id` DESC';
+                    break;
+            }
+        }
+        //
+        $lists = DB::table('report_lists')
+            ->join('report_ccuser', 'report_lists.id', '=', 'report_ccuser.rid')
+            ->select(['report_lists.*'])
+            ->where($whereArray)
+            ->orderByRaw($orderBy)
+            ->paginate(Min(Max(Base::nullShow(Request::input('pagesize'), 10), 1), 100));
+        $lists = Base::getPageList($lists);
+        if ($lists['total'] == 0) {
+            return Base::retError('未找到任何相关的汇报', $lists);
+        }
+        foreach ($lists['lists'] AS $key => $item) {
+            $lists['lists'][$key]['ccuser'] = Base::string2array($item['ccuser']);
+        }
+        return Base::retSuccess('success', $lists);
+    }
+}

+ 2 - 2
app/Http/Controllers/IndexController.php

@@ -133,7 +133,7 @@ class IndexController extends Controller
                     'title' => '...',
                     'path' => substr(substr($path, 0, -1), 0, strripos(substr($path, 0, -1), '/')),
                     'url' => '',
-                    'thumb' => Base::fillUrl('images/dir.png'),
+                    'thumb' => Base::fillUrl('images/other/dir.png'),
                     'inode' => 0,
                 ];
             }
@@ -150,7 +150,7 @@ class IndexController extends Controller
                     'title' => $filename,
                     'path' => $pathTemp,
                     'url' => Base::fillUrl($pathTemp),
-                    'thumb' => Base::fillUrl('images/dir.png'),
+                    'thumb' => Base::fillUrl('images/other/dir.png'),
                     'inode' => fileatime($v),
                 ];
             } elseif (substr($filename, -10) != "_thumb.jpg") {

+ 3 - 0
app/Http/Middleware/VerifyCsrfToken.php

@@ -17,5 +17,8 @@ class VerifyCsrfToken extends Middleware
 
         //上传项目文件
         'api/project/files/upload/',
+
+        //汇报提交
+        'api/report/template/',
     ];
 }

+ 12 - 0
app/Module/Base.php

@@ -2207,6 +2207,18 @@ class Base
     }
 
     /**
+     * 获取当前是本月第几个星期
+     * @return false|float
+     */
+    public static function getMonthWeek()
+    {
+        $time = strtotime(date("Y-m-01"));
+        $w = date('w', $time);
+        $j = date("j");
+        return ceil(($j + $w) / 7);
+    }
+
+    /**
      * 缓存数据
      * @param $title
      * @param null $value

+ 1 - 1
app/Module/Users.php

@@ -170,7 +170,7 @@ class Users
         }
         //
         $userinfo['setting'] = Base::string2array($userinfo['setting']);
-        $userinfo['userimg'] = $userinfo['userimg'] ? Base::fillUrl($userinfo['userimg']) : url('images/avatar.png');
+        $userinfo['userimg'] = $userinfo['userimg'] ? Base::fillUrl($userinfo['userimg']) : url('images/other/avatar.png');
         $userinfo['identity'] = is_array($userinfo['identity']) ? $userinfo['identity'] : explode(",", trim($userinfo['identity'], ","));
         unset($userinfo['encrypt']);
         unset($userinfo['userpass']);

+ 1 - 1
resources/assets/js/main/components/TEditor.vue

@@ -252,7 +252,7 @@
                         {text:"C#",value:"csharp"},
                         {text:"C++",value:"cpp"}
                     ],
-                    height: isFull ? '100%' : ($A.runNum(this.height) || 360),
+                    height: isFull ? '100%' : ($A.rightExists(this.height, '%') ? this.height : ($A.runNum(this.height) || 360)),
                     resize: !isFull,
                     convert_urls:false,
                     toolbar_drawer: 'floating',

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

@@ -205,9 +205,7 @@
         watch: {
             value (val) {
                 if (this.multiple) {
-                    if (!val) {
-                        this.multipleLists = [];
-                    }
+                    this.multipleLists = this.formatMultipleLists(val);
                     return;
                 }
                 this.userName = $A.cloneData(val)
@@ -451,6 +449,27 @@
                     val+= tmp.username;
                 });
                 this.$emit('input', val);
+            },
+
+            formatMultipleLists(val) {
+                let arr = (val + ",").split(",");
+                let narr = [];
+                arr.forEach((uname) => {
+                    if (uname) {
+                        let inn = false;
+                        this.multipleLists.some((tmp) => {
+                            if (tmp.username == uname) {
+                                return inn = true;
+                            }
+                        })
+                        if (!inn) {
+                            narr.push({
+                                username: uname,
+                            });
+                        }
+                    }
+                });
+                return narr;
             }
         },
         mounted() {
@@ -459,6 +478,9 @@
             if ($A.runNum(this.value) > 0) {
                 this.userName = this.value;
             }
+            if (this.multiple) {
+                this.multipleLists = this.formatMultipleLists(this.value);
+            }
         }
     };
 </script>

+ 167 - 0
resources/assets/js/main/components/report/add.vue

@@ -0,0 +1,167 @@
+<template>
+    <drawer-tabs-container>
+        <div class="report-add">
+            <div class="add-header">
+                <div class="add-title">
+                    <Input v-model="dataDetail.title" placeholder="汇报标题"></Input>
+                </div>
+                <ButtonGroup>
+                    <Button :disabled="id > 0" :type="`${type=='日报'?'primary':'default'}`" @click="type='日报'">日报</Button>
+                    <Button :disabled="id > 0" :type="`${type=='周报'?'primary':'default'}`" @click="type='周报'">周报</Button>
+                </ButtonGroup>
+            </div>
+            <t-editor class="add-edit" v-model="dataDetail.content" height="100%"></t-editor>
+            <div class="add-input">
+                <userid-input v-model="dataDetail.ccuser" placeholder="输入关键词搜索" multiple><span slot="prepend">抄送人</span></userid-input>
+            </div>
+            <div class="add-footer">
+                <Button :loading="loadIng > 0" type="primary" @click="handleSubmit" style="margin-right:6px">保 存</Button>
+                <Button v-if="dataDetail.status=='已发送'" :loading="loadIng > 0" type="success" icon="md-checkmark-circle-outline" ghost @click="handleSubmit(true)">已保存发送</Button>
+                <Button v-else :loading="loadIng > 0" @click="handleSubmit(true)">保存并发送</Button>
+            </div>
+        </div>
+    </drawer-tabs-container>
+</template>
+
+<style lang="scss">
+    .report-add {
+        .add-edit {
+            .teditor-loadedstyle {
+                height: 100%;
+            }
+        }
+    }
+</style>
+<style lang="scss" scoped>
+    .report-add {
+        display: flex;
+        flex-direction: column;
+        height: 100%;
+        padding: 0 24px;
+        .add-header {
+            display: flex;
+            align-items: center;
+            margin-top: 22px;
+            margin-bottom: 14px;
+            .add-title {
+                flex: 1;
+                padding-right: 36px;
+            }
+        }
+        .add-edit {
+            width: 100%;
+            flex: 1;
+        }
+        .add-input,
+        .add-footer {
+            margin-top: 14px;
+        }
+    }
+</style>
+<script>
+    import DrawerTabsContainer from "../DrawerTabsContainer";
+    import TEditor from "../TEditor";
+
+    /**
+     * 新建汇报
+     */
+    export default {
+        name: 'ReportAdd',
+        components: {TEditor, DrawerTabsContainer},
+        props: {
+            id: {
+                default: 0
+            },
+            canload: {
+                type: Boolean,
+                default: true
+            },
+        },
+        data () {
+            return {
+                loadYet: false,
+
+                loadIng: 0,
+
+                dataDetail: {
+                    title: '',
+                    content: '数据加载中.....',
+                    ccuser: '',
+                    status: '',
+                },
+
+                type: '日报'
+            }
+        },
+
+        mounted() {
+            if (this.canload) {
+                this.loadYet = true;
+                this.getData();
+            }
+        },
+
+        watch: {
+            canload(val) {
+                if (val && !this.loadYet) {
+                    this.loadYet = true;
+                    this.getData();
+                }
+            },
+            type() {
+                if (this.loadYet) {
+                    this.getData();
+                }
+            },
+            id() {
+                if (this.loadYet) {
+                    this.dataDetail = {};
+                    this.getData();
+                }
+            },
+        },
+
+        methods: {
+            getData() {
+                this.loadIng++;
+                $A.aAjax({
+                    url: 'report/template?id=' + this.id + '&type=' + this.type,
+                    complete: () => {
+                        this.loadIng--;
+                    },
+                    success: (res) => {
+                        if (res.ret === 1) {
+                            this.dataDetail = res.data;
+                        }
+                    }
+                });
+            },
+
+            handleSubmit(send = false) {
+                this.loadIng++;
+                $A.aAjax({
+                    url: 'report/template?act=submit&id=' + this.id + '&type=' + this.type + '&send=' + (send === true ? 1 : 0),
+                    method: 'post',
+                    data: {
+                        D: this.dataDetail
+                    },
+                    complete: () => {
+                        this.loadIng--;
+                    },
+                    error: () => {
+                        alert(this.$L('网络繁忙,请稍后再试!'));
+                    },
+                    success: (res) => {
+                        if (res.ret === 1) {
+                            this.dataDetail = res.data;
+                            this.$Message.success(res.msg);
+                            this.$emit("on-success", res.data);
+                        } else {
+                            this.$Modal.error({title: this.$L('温馨提示'), content: res.msg});
+                        }
+                    }
+                });
+            }
+        }
+    }
+</script>

+ 253 - 0
resources/assets/js/main/components/report/my.vue

@@ -0,0 +1,253 @@
+<template>
+    <drawer-tabs-container>
+        <div class="report-my">
+            <!-- 按钮 -->
+            <Button :loading="loadIng > 0" type="primary" icon="md-add" @click="[addDrawerId=0,addDrawerShow=true]">新建汇报</Button>
+            <!-- 列表 -->
+            <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>
+        <Drawer v-model="addDrawerShow" width="70%">
+            <report-add :canload="addDrawerShow" :id="addDrawerId" @on-success="addDrawerSuccess"></report-add>
+        </Drawer>
+    </drawer-tabs-container>
+</template>
+
+<style lang="scss" scoped>
+    .report-my {
+        padding: 0 12px;
+        .tableFill {
+            margin: 12px 0 20px;
+        }
+    }
+</style>
+<script>
+    import DrawerTabsContainer from "../DrawerTabsContainer";
+    import ReportAdd from "./add";
+
+    /**
+     * 我的汇报
+     */
+    export default {
+        name: 'ReportMy',
+        components: {ReportAdd, DrawerTabsContainer},
+        props: {
+            canload: {
+                type: Boolean,
+                default: true
+            },
+        },
+        data () {
+            return {
+                loadYet: false,
+
+                loadIng: 0,
+
+                columns: [],
+
+                lists: [],
+                listPage: 1,
+                listTotal: 0,
+                noDataText: "数据加载中.....",
+
+                addDrawerId: 0,
+                addDrawerShow: false,
+            }
+        },
+        created() {
+            this.columns = [{
+                "title": "标题",
+                "key": 'title',
+                "minWidth": 120,
+            }, {
+                "title": "创建日期",
+                "width": 160,
+                "align": 'center',
+                render: (h, params) => {
+                    return h('span', $A.formatDate("Y-m-d H:i:s", params.row.indate));
+                }
+            }, {
+                "title": "类型",
+                "key": 'type',
+                "width": 80,
+                "align": 'center',
+            }, {
+                "title": "状态",
+                "key": 'status',
+                "width": 80,
+                "align": 'center',
+            }, {
+                "title": "操作",
+                "key": 'action',
+                "width": 140,
+                "align": 'center',
+                render: (h, params) => {
+                    let arr = [];
+                    arr.push(h('a', {
+                        style: {padding: '0 2px', fontSize: '12px'},
+                        on: {
+                            click: () => {
+                            }
+                        }
+                    }, '查看'));
+                    arr.push(h('a', {
+                        style: {padding: '0 2px', fontSize: '12px'},
+                        on: {
+                            click: () => {
+                                this.addDrawerId = params.row.id;
+                                this.addDrawerShow = true
+                            }
+                        }
+                    }, '编辑'));
+                    if (params.row.status == '未发送') {
+                        arr.push(h('a', {
+                            style: {padding: '0 2px', fontSize: '12px'},
+                            on: {
+                                click: () => {
+                                    this.deleteReport(params.row);
+                                }
+                            }
+                        }, '删除'));
+                        arr.push(h('a', {
+                            style: {padding: '0 2px', fontSize: '12px'},
+                            on: {
+                                click: () => {
+                                    this.sendReport(params.row);
+                                }
+                            }
+                        }, '发送'));
+                    }
+                    return h('div', arr);
+                }
+            }];
+        },
+        mounted() {
+            if (this.canload) {
+                this.loadYet = true;
+                this.getLists(true);
+            }
+        },
+
+        watch: {
+            canload(val) {
+                if (val && !this.loadYet) {
+                    this.loadYet = true;
+                    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;
+                }
+                this.loadIng++;
+                this.noDataText = "数据加载中.....";
+                $A.aAjax({
+                    url: 'report/my',
+                    data: {
+                        page: Math.max(this.listPage, 1),
+                        pagesize: Math.max($A.runNum(this.listPageSize), 10),
+                    },
+                    complete: () => {
+                        this.loadIng--;
+                    },
+                    error: () => {
+                        this.noDataText = "数据加载失败!";
+                    },
+                    success: (res) => {
+                        if (res.ret === 1) {
+                            this.lists = res.data.lists;
+                            this.listTotal = res.data.total;
+                            this.noDataText = "没有相关的数据";
+                        } else {
+                            this.lists = [];
+                            this.listTotal = 0;
+                            this.noDataText = res.msg;
+                        }
+                    }
+                });
+            },
+
+            addDrawerSuccess() {
+                this.addDrawerShow = false;
+                this.getLists(true);
+            },
+
+            sendReport(row) {
+                this.$Modal.confirm({
+                    title: '发送汇报',
+                    content: '你确定要发送汇报吗?',
+                    loading: true,
+                    onOk: () => {
+                        $A.aAjax({
+                            url: 'report/template?act=send&id=' + row.id + '&type=' + row.type,
+                            error: () => {
+                                this.$Modal.remove();
+                                alert(this.$L('网络繁忙,请稍后再试!'));
+                            },
+                            success: (res) => {
+                                this.$Modal.remove();
+                                this.$set(row, 'status', '已发送');
+                                setTimeout(() => {
+                                    if (res.ret === 1) {
+                                        this.$Message.success(res.msg);
+                                    } else {
+                                        this.$Modal.error({title: this.$L('温馨提示'), content: res.msg});
+                                    }
+                                }, 350);
+                            }
+                        });
+                    }
+                });
+            },
+
+            deleteReport(row) {
+                this.$Modal.confirm({
+                    title: '删除汇报',
+                    content: '你确定要删除汇报吗?',
+                    loading: true,
+                    onOk: () => {
+                        $A.aAjax({
+                            url: 'report/template?act=delete&id=' + row.id + '&type=' + row.type,
+                            error: () => {
+                                this.$Modal.remove();
+                                alert(this.$L('网络繁忙,请稍后再试!'));
+                            },
+                            success: (res) => {
+                                this.$Modal.remove();
+                                this.lists.some((item, index) => {
+                                    if (item.id == row.id) {
+                                        this.lists.splice(index, 1);
+                                        return true;
+                                    }
+                                })
+                                setTimeout(() => {
+                                    if (res.ret === 1) {
+                                        this.$Message.success(res.msg);
+                                    } else {
+                                        this.$Modal.error({title: this.$L('温馨提示'), content: res.msg});
+                                    }
+                                }, 350);
+                            }
+                        });
+                    }
+                });
+            }
+        }
+    }
+</script>

+ 194 - 0
resources/assets/js/main/components/report/receive.vue

@@ -0,0 +1,194 @@
+<template>
+    <drawer-tabs-container>
+        <div class="report-receive">
+
+            <!-- 搜索 -->
+            <Row class="sreachBox">
+                <div class="item">
+                    <div class="item-3">
+                        <sreachTitle :val="keys.username">发送人</sreachTitle>
+                        <Input v-model="keys.username" placeholder="用户名"/>
+                    </div>
+                    <div class="item-3">
+                        <sreachTitle :val="keys.type">类型</sreachTitle>
+                        <Select v-model="keys.type" placeholder="全部">
+                            <Option value="">全部</Option>
+                            <Option value="日报">日报</Option>
+                            <Option value="周报">周报</Option>
+                        </Select>
+                    </div>
+                    <div class="item-3">
+                        <sreachTitle :val="keys.indate">日期</sreachTitle>
+                        <Date-picker v-model="keys.indate" type="daterange" placement="bottom" placeholder="日期范围"></Date-picker>
+                    </div>
+                </div>
+                <div class="item item-button">
+                    <Button type="text" v-if="$A.objImplode(keys)!=''" @click="sreachTab(true)">取消筛选</Button>
+                    <Button type="primary" icon="md-search" :loading="loadIng > 0" @click="sreachTab">搜索</Button>
+                </div>
+            </Row>
+
+            <!-- 列表 -->
+            <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" @on-sort-change="sortChange" 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>
+    </drawer-tabs-container>
+</template>
+<style lang="scss" scoped>
+    .report-receive {
+        margin: 0 12px;
+        .tableFill {
+            margin: 12px 0 20px;
+        }
+    }
+</style>
+
+<script>
+    import DrawerTabsContainer from "../DrawerTabsContainer";
+
+    /**
+     * 收到的汇报
+     */
+    export default {
+        name: 'ReportReceive',
+        components: {DrawerTabsContainer},
+        props: {
+            canload: {
+                type: Boolean,
+                default: true
+            },
+            labelLists: {
+                type: Array,
+            },
+        },
+        data() {
+            return {
+                keys: {},
+                sorts: {key:'', order:''},
+
+                loadYet: false,
+
+                loadIng: 0,
+
+                columns: [],
+
+                lists: [],
+                listPage: 1,
+                listTotal: 0,
+                noDataText: "数据加载中.....",
+            }
+        },
+
+        created() {
+            this.columns = [{
+                "title": "标题",
+                "key": 'title',
+                "minWidth": 120,
+            }, {
+                "title": "发送人",
+                "key": 'username',
+                "sortable": true,
+                "minWidth": 80,
+                "maxWidth": 150,
+            }, {
+                "title": "创建日期",
+                "width": 160,
+                "align": 'center',
+                render: (h, params) => {
+                    return h('span', $A.formatDate("Y-m-d H:i:s", params.row.indate));
+                }
+            }, {
+                "title": "类型",
+                "key": 'type',
+                "width": 80,
+                "align": 'center',
+            }, {
+                "title": "操作",
+                "key": 'action',
+                "width": 80,
+                "align": 'center',
+                render: (h, params) => {
+                    return h('a', '查看');
+                }
+            }];
+        },
+
+        mounted() {
+            if (this.canload) {
+                this.loadYet = true;
+                this.getLists(true);
+            }
+        },
+
+        watch: {
+            canload(val) {
+                if (val && !this.loadYet) {
+                    this.loadYet = true;
+                    this.getLists(true);
+                }
+            }
+        },
+
+        methods: {
+            sreachTab(clear) {
+                if (clear === true) {
+                    this.keys = {};
+                }
+                this.getLists(true);
+            },
+
+            sortChange(info) {
+                this.sorts = {key:info.key, order:info.order};
+                this.getLists(true);
+            },
+
+            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;
+                }
+                this.loadIng++;
+                let whereData = $A.cloneData(this.keys);
+                whereData.page = Math.max(this.listPage, 1);
+                whereData.pagesize = Math.max($A.runNum(this.listPageSize), 10);
+                whereData.sorts = $A.cloneData(this.sorts);
+                this.noDataText = "数据加载中.....";
+                $A.aAjax({
+                    url: 'report/receive',
+                    data: whereData,
+                    complete: () => {
+                        this.loadIng--;
+                    },
+                    error: () => {
+                        this.noDataText = "数据加载失败!";
+                    },
+                    success: (res) => {
+                        if (res.ret === 1) {
+                            this.lists = res.data.lists;
+                            this.listTotal = res.data.total;
+                            this.noDataText = "没有相关的数据";
+                        } else {
+                            this.lists = [];
+                            this.listTotal = 0;
+                            this.noDataText = res.msg;
+                        }
+                    }
+                });
+            },
+        }
+    }
+</script>

+ 21 - 2
resources/assets/js/main/pages/todo.vue

@@ -85,6 +85,17 @@
                 </TabPane>
             </Tabs>
         </Drawer>
+
+        <Drawer v-model="todoReportDrawerShow" width="75%">
+            <Tabs v-if="todoReportDrawerShow" v-model="todoReportDrawerTab">
+                <TabPane :label="$L('我的汇报')" name="my">
+                    <report-my :canload="todoReportDrawerShow && todoReportDrawerTab == 'my'"></report-my>
+                </TabPane>
+                <TabPane :label="$L('收到的汇报')" name="receive">
+                    <report-receive :canload="todoReportDrawerShow && todoReportDrawerTab == 'receive'"></report-receive>
+                </TabPane>
+            </Tabs>
+        </Drawer>
     </div>
 </template>
 
@@ -315,9 +326,13 @@
     import TodoAttention from "../components/project/todo/attention";
 
     import Task from "../mixins/task";
+    import ReportMy from "../components/report/my";
+    import ReportReceive from "../components/report/receive";
 
     export default {
-        components: {draggable, TodoAttention, TodoComplete, TodoCalendar, WContent, WHeader, WLoading},
+        components: {
+            ReportReceive,
+            ReportMy, draggable, TodoAttention, TodoComplete, TodoCalendar, WContent, WHeader, WLoading},
         mixins: [
             Task
         ],
@@ -337,6 +352,9 @@
 
                 todoDrawerShow: false,
                 todoDrawerTab: 'calendar',
+
+                todoReportDrawerShow: false,
+                todoReportDrawerTab: 'my',
             }
         },
         mounted() {
@@ -444,6 +462,7 @@
         },
         deactivated() {
             this.todoDrawerShow = false;
+            this.todoReportDrawerShow = false;
         },
         computed: {
 
@@ -621,7 +640,7 @@
                         break;
                     }
                     case 'report': {
-                        this.$Message.info("敬请期待!");
+                        this.todoReportDrawerShow = true;
                         break;
                     }
                 }

+ 3 - 0
routes/web.php

@@ -13,6 +13,9 @@ Route::prefix('api')->middleware(ApiMiddleware::class)->group(function () {
     //项目
     Route::any('project/{method}',                  'Api\ProjectController');
     Route::any('project/{method}/{action}',         'Api\ProjectController');
+    //汇报
+    Route::any('report/{method}',                   'Api\ReportController');
+    Route::any('report/{method}/{action}',          'Api\ReportController');
 });
 
 

+ 1 - 46
test.php

@@ -1,47 +1,2 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <meta charset="UTF-8">
-    <title>Chat Client</title>
-</head>
-<body>
-<script>
-    window.onload = function () {
-        var nick = prompt("Enter your nickname");
-        var input = document.getElementById("input");
-        input.focus();
+<?php
 
-        // 初始化客户端套接字并建立连接
-        var socket = new WebSocket("ws://127.0.0.1:5200");
-
-        // 连接建立时触发
-        socket.onopen = function (event) {
-            console.log("Connection open ...");
-        }
-
-        // 接收到服务端推送时执行
-        socket.onmessage = function (event) {
-            var msg = event.data;
-            var node = document.createTextNode(msg);
-            var div = document.createElement("div");
-            div.appendChild(node);
-            document.body.insertBefore(div, input);
-            input.scrollIntoView();
-        };
-
-        // 连接关闭时触发
-        socket.onclose = function (event) {
-            console.log("Connection closed ...");
-        }
-
-        input.onchange = function () {
-            var msg = nick + ": " + input.value;
-            // 将输入框变更信息通过 send 方法发送到服务器
-            socket.send(msg);
-            input.value = "";
-        };
-    }
-</script>
-<input id="input" style="width: 100%;">
-</body>
-</html>