Ver código fonte

新增导出任务列表

kuaifan 5 anos atrás
pai
commit
c2d5730731

Diferenças do arquivo suprimidas por serem muito extensas
+ 2733 - 3410
_ide_helper.php


+ 111 - 4
app/Http/Controllers/Api/ProjectController.php

@@ -3,10 +3,13 @@
 namespace App\Http\Controllers\Api;
 
 use App\Http\Controllers\Controller;
+use App\Model\DBCache;
 use App\Module\Base;
+use App\Module\BillExport;
 use App\Module\Project;
 use App\Module\Users;
 use DB;
+use Madzipper;
 use Request;
 use Session;
 
@@ -1104,6 +1107,7 @@ class ProjectController extends Controller
      *
      * @apiParam {Number} [page]                当前页,默认:1
      * @apiParam {Number} [pagesize]            每页显示数量,默认:20,最大:100
+     * @apiParam {Number} [export]              是否导出并返回下载地址(1:是;仅支持projectid赋值时)
      */
     public function task__lists()
     {
@@ -1115,11 +1119,14 @@ class ProjectController extends Controller
         }
         //
         $projectid = intval(Request::input('projectid'));
+        $export = intval(Request::input('export'));
         if ($projectid > 0) {
             $inRes = Project::inThe($projectid, $user['username']);
             if (Base::isError($inRes)) {
                 return $inRes;
             }
+        } else {
+            $export = 0;
         }
         //
         $orderBy = '`inorder` DESC,`id` DESC';
@@ -1236,10 +1243,83 @@ class ProjectController extends Controller
         if ($whereRaw) {
             $builder->whereRaw($whereRaw);
         }
-        $lists = $builder->select($selectArray)
-            ->where($whereArray)
-            ->orderByRaw($orderBy)
-            ->paginate(Base::getPaginate(100, 20));
+        $builder->select($selectArray)->where($whereArray)->orderByRaw($orderBy);
+        if ($export) {
+            //导出excel
+            $checkRole = Project::role('project_role_export', $projectid);
+            if (Base::isError($checkRole)) {
+                return $checkRole;
+            }
+            $lists = Base::DBC2A($builder->get());
+            if (empty($lists)) {
+                return Base::retError('未找到任何相关的任务!');
+            }
+            $labels = DB::table('project_label')->select(['id', 'title'])->where('projectid', $projectid)->pluck('title', 'id');
+            $fileName = str_replace(['/', '\\', ':', '*', '"', '<', '>', '|', '?'], '_', $checkRole['data']['title'] ?: $projectid) . '_' . Base::time() . '.xls';
+            $filePath = "temp/task/export/" . date("Ym", Base::time());
+            $headings = [];
+            $headings[] = '任务ID';
+            $headings[] = '任务标题';
+            $headings[] = '任务阶段';
+            $headings[] = '计划时间(开始)';
+            $headings[] = '计划时间(结束)';
+            $headings[] = '负责人';
+            $headings[] = '负责人(昵称)';
+            $headings[] = '创建人';
+            $headings[] = '创建人(昵称)';
+            $headings[] = '优先级';
+            $headings[] = '状态';
+            $headings[] = '是否超期';
+            $headings[] = '创建时间';
+            $data = [];
+            foreach ($lists AS $info) {
+                $overdue = Project::taskIsOverdue($info);
+                $data[] = [
+                    $info['id'],
+                    $info['title'],
+                    $labels[$info['labelid']] ?: '-',
+                    $info['startdate'] ? date("Y-m-d H:i:s", $info['startdate']) : '-',
+                    $info['enddate'] ? date("Y-m-d H:i:s", $info['enddate']) : '-',
+                    $info['username'],
+                    DBCache::table('users')->where('username', $info['username'])->value('nickname') ?: $info['username'],
+                    $info['createuser'],
+                    DBCache::table('users')->where('username', $info['createuser'])->value('nickname') ?: $info['createuser'],
+                    'P' . $info['level'],
+                    ($overdue ? '已超期' : ($info['complete'] ? '已完成' : '未完成')),
+                    $overdue ? '是' : '-',
+                    date("Y-m-d H:i:s", $info['indate'])
+                ];
+            }
+            $res = BillExport::create()->setHeadings($headings)->setData($data)->store($filePath . "/" . $fileName);
+            if ($res != 1) {
+                return Base::retError(['导出失败,%!', $fileName]);
+            }
+            //
+            $xlsPath = storage_path("app/" . $filePath . "/" . $fileName);
+            $zipFile = "app/" . $filePath . "/" . Base::rightDelete($fileName, '.xls'). ".zip";
+            $zipPath = storage_path($zipFile);
+            if (file_exists($zipPath)) {
+                Base::deleteDirAndFile($zipPath, true);
+            }
+            try {
+                Madzipper::make($zipPath)->add($xlsPath)->close();
+            } catch (\Exception $e) { }
+            //
+            if (file_exists($zipPath)) {
+                $base64 = base64_encode(Base::array2string([
+                    'projectid' => $projectid,
+                    'file' => $zipFile,
+                ]));
+                Session::put('task::export:username', $user['username']);
+                return Base::retSuccess("success", [
+                    'size' => Base::twoFloat(filesize($zipPath) / 1024, true),
+                    'url' => Base::fillUrl('api/project/task/export?data=' . urlencode($base64)),
+                ]);
+            } else {
+                return Base::retError('打包失败,请稍后再试...');
+            }
+        }
+        $lists = $builder->paginate(Base::getPaginate(100, 20));
         $lists = Base::getPageList($lists);
         if (intval(Request::input('statistics')) == 1) {
             $lists['statistics_unfinished'] = $type === '未完成' ? $lists['total'] : DB::table('project_task')->where('projectid', $projectid)->where('delete', 0)->where('archived', 0)->where('complete', 0)->count();
@@ -1260,6 +1340,33 @@ class ProjectController extends Controller
     }
 
     /**
+     * 项目任务-导出结果
+     *
+     * @apiParam {String} data              base64
+     */
+    public function task__export()
+    {
+        $username = Session::get('task::export:username');
+        if (empty($username)) {
+            return Base::ajaxError("请求已过期,请重新导出!", [], 0, 502);
+        }
+        $array = Base::string2array(base64_decode(urldecode(Request::input('data'))));
+        $projectid = intval($array['projectid']);
+        $file = $array['file'];
+        if (empty($projectid)) {
+            return Base::ajaxError("参数错误!", [], 0, 502);
+        }
+        if (empty($file) || !file_exists(storage_path($file))) {
+            return Base::ajaxError("文件不存在!", [], 0, 502);
+        }
+        $checkRole = Project::role('project_role_export', $projectid, 0, $username);
+        if (Base::isError($checkRole)) {
+            return Base::ajaxError($checkRole['msg'], [], 0, 502);
+        }
+        return response()->download(storage_path($file), ($checkRole['data']['title'] ?: Base::time()) . '.zip');
+    }
+
+    /**
      * 项目任务-详情(与任务有关系的用户(关注的、在项目里的、负责人、创建者)都可以查到)
      *
      * @apiParam {Number} taskid              任务ID

+ 3 - 2
app/Module/Base.php

@@ -1341,14 +1341,15 @@ class Base
      * @param $msg
      * @param array $data
      * @param int $ret
+     * @param int $abortCode
      * @return array|void
      */
-    public static function ajaxError($msg, $data = [], $ret = 0)
+    public static function ajaxError($msg, $data = [], $ret = 0, $abortCode = 404)
     {
         if (Request::input('__Access-Control-Allow-Origin') || Request::header('Content-Type') === 'application/json') {
             return Base::retError($msg, $data, $ret);
         }else{
-            return abort(404);
+            return abort($abortCode, $msg);
         }
     }
 

+ 144 - 0
app/Module/BillExport.php

@@ -0,0 +1,144 @@
+<?php
+
+namespace App\Module;
+
+use Excel;
+use Maatwebsite\Excel\Concerns\FromCollection;
+use Maatwebsite\Excel\Concerns\WithEvents;
+use Maatwebsite\Excel\Concerns\WithHeadings;
+use Maatwebsite\Excel\Concerns\WithStrictNullComparison;
+use Maatwebsite\Excel\Concerns\WithTitle;
+use Maatwebsite\Excel\Events\AfterSheet;
+use PhpOffice\PhpSpreadsheet\Cell\DataValidation;
+use PhpOffice\PhpSpreadsheet\Writer\Exception;
+
+class BillExport implements WithHeadings, WithEvents, FromCollection, WithTitle, WithStrictNullComparison
+{
+    public $title;
+    public $headings = [];
+    public $data = [];
+    public $typeLists = [];
+    public $typeNumber = 0;
+
+    public function __construct($title, array $data)
+    {
+        $this->title = $title;
+        $this->data = $data;
+    }
+
+    public static function create($data = [], $title = "Sheet1") {
+        if (is_string($data)) {
+            list($title, $data) = [$data, $title];
+        }
+        if (!is_array($data)) {
+            $data = [];
+        }
+        return new BillExport($title, $data);
+    }
+
+    public function setTitle($title) {
+        $this->title = $title;
+        return $this;
+    }
+
+    public function setHeadings(array $headings) {
+        $this->headings = $headings;
+        return $this;
+    }
+
+    public function setData(array $data) {
+        $this->data = $data;
+        return $this;
+    }
+
+    public function setTypeList(array $typeList, $number = 0) {
+        $this->typeLists = $typeList;
+        $this->typeNumber = $number;
+        return $this;
+    }
+
+    public function store($fileName = '') {
+        if (empty($fileName)) {
+            $fileName = date("YmdHis") . '.xls';
+        }
+        try {
+            return Excel::store($this, $fileName);
+        } catch (Exception $e) {
+            return "导出错误:" . $e->getMessage();
+        } catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
+            return "导出错误:" . $e->getMessage();
+        }
+    }
+
+    public function download($fileName = '') {
+        if (empty($fileName)) {
+            $fileName = date("YmdHis") . '.xls';
+        }
+        try {
+            return Excel::download($this, $fileName);
+        } catch (Exception $e) {
+            return "导出错误:" . $e->getMessage();
+        } catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
+            return "导出错误:" . $e->getMessage();
+        }
+    }
+
+    /**
+     * 导出的文件标题
+     * @return string
+     */
+    public function title(): string
+    {
+        return $this->title;
+    }
+
+    /**
+     * 标题行
+     * @return array
+     */
+    public function headings(): array
+    {
+        return $this->headings;
+    }
+
+    /**
+     * 导出的内容
+     * @return \Illuminate\Support\Collection
+     */
+    public function collection()
+    {
+        return collect($this->data);
+    }
+
+    /**
+     * 设置单元格事件
+     * @return array
+     */
+    public function registerEvents(): array
+    {
+        return [
+            AfterSheet::Class => function (AfterSheet $event) {
+                $count = count($this->data);
+                foreach ($this->typeLists AS $cell => $typeList) {
+                    if ($cell && $typeList) {
+                        $p = $this->headings ? 1 : 0;
+                        for ($i = 1 + $p; $i <= max($count, $this->typeNumber) + $p; $i++) {
+                            $validation = $event->sheet->getDelegate()->getCell($cell . $i)->getDataValidation();
+                            $validation->setType(DataValidation::TYPE_LIST);
+                            $validation->setErrorStyle(DataValidation::STYLE_WARNING);
+                            $validation->setAllowBlank(false);
+                            $validation->setShowDropDown(true);
+                            $validation->setShowInputMessage(true);
+                            $validation->setShowErrorMessage(true);
+                            $validation->setErrorTitle('输入的值不合法');
+                            $validation->setError('选择的值不在列表中,请选择列表中的值');
+                            $validation->setPromptTitle('从列表中选择');
+                            $validation->setPrompt('请选择下拉列表中的值');
+                            $validation->setFormula1('"' . implode(',', $typeList) . '"');
+                        }
+                    }
+                }
+            }
+        ];
+    }
+}

+ 16 - 0
app/Module/BillImport.php

@@ -0,0 +1,16 @@
+<?php
+
+
+namespace App\Module;
+
+
+use Maatwebsite\Excel\Concerns\ToArray;
+
+class BillImport implements ToArray
+{
+    public function Array(Array $tables)
+    {
+        return $tables;
+    }
+
+}

+ 18 - 12
app/Module/Project.php

@@ -153,24 +153,29 @@ class Project
      * @param $type
      * @param $projectid
      * @param int $taskid
+     * @param string $username
      * @return array|mixed
      */
-    public static function role($type, $projectid, $taskid = 0)
+    public static function role($type, $projectid, $taskid = 0, $username = '')
     {
-        $user = Users::authE();
-        if (Base::isError($user)) {
-            return $user;
-        } else {
-            $user = $user['data'];
+        if (empty($username)) {
+            $user = Users::authE();
+            if (Base::isError($user)) {
+                return $user;
+            } else {
+                $user = $user['data'];
+            }
+            $username = $user['username'];
         }
         //
-        $project = Base::DBC2A(DB::table('project_lists')->select(['username', 'setting'])->where('id', $projectid)->where('delete', 0)->first());
+        $project = Base::DBC2A(DB::table('project_lists')->select(['username', 'title', 'setting'])->where('id', $projectid)->where('delete', 0)->first());
         if (empty($project)) {
             return Base::retError('项目不存在或已被删除!');
         }
         // 项目负责人最高权限
-        if ($project['username'] == $user['username']) {
-            return Base::retSuccess('success');
+        if ($project['username'] == $username) {
+            unset($project['setting']);
+            return Base::retSuccess('success', $project);
         }
         //
         $setting = Base::string2array($project['setting']);
@@ -184,7 +189,7 @@ class Project
             return Base::retError('操作权限不足!');
         }
         if (in_array('member', $role)) {
-            $inRes = Project::inThe($projectid, $user['username']);
+            $inRes = Project::inThe($projectid, $username);
             if (Base::isError($inRes)) {
                 return $inRes;
             }
@@ -202,13 +207,14 @@ class Project
             if (empty($task)) {
                 return Base::retError('任务不存在!');
             }
-            if ($task['username'] != $user['username']) {
+            if ($task['username'] != $username) {
                 return Base::retError('此操作只允许项目管理员或者任务负责人!');
             }
         } else {
             return Base::retError('此操作仅限项目负责人!');
         }
         //
-        return Base::retSuccess('success');
+        unset($project['setting']);
+        return Base::retSuccess('success', $project);
     }
 }

+ 1 - 0
composer.json

@@ -16,6 +16,7 @@
         "laravel/framework": "^7.10.3",
         "laravel/tinker": "^2.0",
         "maatwebsite/excel": "^3.1",
+        "madnest/madzipper": "^v1.0.4",
         "predis/predis": "^1.1.1"
     },
     "require-dev": {

+ 2 - 2
config/app.php

@@ -174,7 +174,7 @@ return [
         // App\Providers\BroadcastServiceProvider::class,
         App\Providers\EventServiceProvider::class,
         App\Providers\RouteServiceProvider::class,
-
+        Madnest\Madzipper\MadzipperServiceProvider::class
     ],
 
     /*
@@ -226,7 +226,7 @@ return [
         'URL' => Illuminate\Support\Facades\URL::class,
         'Validator' => Illuminate\Support\Facades\Validator::class,
         'View' => Illuminate\Support\Facades\View::class,
-
+        'Madzipper' => Madnest\Madzipper\Madzipper::class
     ],
 
 ];

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
     "name": "wookteam",
-    "version": "1.5.10",
+    "version": "1.5.11",
     "description": "WookTeam是一款轻量级的开源在线团队协作工具,提供各类文档工具、在线思维导图、在线流程图、项目管理、任务分发、即时IM,知识库管理等工具。",
     "scripts": {
         "ide-helper": "php artisan ide-helper:generate",

+ 14 - 1
resources/assets/js/main/components/project/setting.vue

@@ -6,7 +6,19 @@
                 <FormItem :label="$L('项目简介')">
                     <Input v-model="formSystem.project_desc" type="textarea" :autosize="{minRows:3,maxRows:20}" style="max-width:450px"/>
                 </FormItem>
-                <div class="project-setting-title">{{$L('权限设置')}}:</div>
+
+                <div class="project-setting-title">{{$L('项目权限')}}:</div>
+                <FormItem prop="project_role_export">
+                    <div slot="label">
+                        <Tooltip :content="$L('任务列表导出Excel')" transfer>{{$L('导出列表')}}</Tooltip>
+                    </div>
+                    <Checkbox :value="true" disabled>{{$L('项目负责人')}}</Checkbox>
+                    <CheckboxGroup v-model="formSystem.project_role_export" class="project-setting-group">
+                        <Checkbox label="member">{{$L('项目成员')}}</Checkbox>
+                    </CheckboxGroup>
+                </FormItem>
+
+                <div class="project-setting-title">{{$L('任务权限')}}:</div>
                 <FormItem :label="$L('添加任务')">
                     <Checkbox :value="true" disabled>{{$L('项目负责人')}}</Checkbox>
                     <CheckboxGroup v-model="formSystem.add_role" class="project-setting-group">
@@ -41,6 +53,7 @@
                         <Checkbox label="member">{{$L('项目成员')}}</Checkbox>
                     </CheckboxGroup>
                 </FormItem>
+
                 <div class="project-setting-title">{{$L('面板显示')}}:</div>
                 <FormItem :label="$L('显示已完成')">
                     <div>

+ 45 - 0
resources/assets/js/main/components/project/task/lists.vue

@@ -40,6 +40,7 @@
                     </div>
                 </div>
                 <div class="item item-button">
+                    <Button type="info" class="left-btn" icon="md-swap" :loading="exportLoad > 0" @click="exportTab">{{$L('导出列表')}}</Button>
                     <Button type="text" v-if="$A.objImplode(keys)!=''" @click="sreachTab(true)">{{$L('取消筛选')}}</Button>
                     <Button type="primary" icon="md-search" :loading="loadIng > 0" @click="sreachTab">{{$L('搜索')}}</Button>
                 </div>
@@ -96,6 +97,7 @@
                 loadYet: false,
 
                 loadIng: 0,
+                exportLoad: 0,
 
                 columns: [],
 
@@ -283,6 +285,49 @@
         },
 
         methods: {
+            exportTab() {
+                let whereData = $A.cloneData(this.keys);
+                whereData.page = Math.max(this.listPage, 1);
+                whereData.pagesize = Math.max($A.runNum(this.listPageSize), 10);
+                whereData.projectid = this.projectid;
+                whereData.sorts = $A.cloneData(this.sorts);
+                whereData.export = 1;
+                this.exportLoad++;
+                $A.apiAjax({
+                    url: 'project/task/lists',
+                    data: whereData,
+                    complete: () => {
+                        this.exportLoad--;
+                    },
+                    error: () => {
+                        alert(this.$L('网络繁忙,请稍后再试!'));
+                    },
+                    success: (res) => {
+                        if (res.ret === 1) {
+                            this.$Modal.info({
+                                okText: this.$L('关闭'),
+                                render: (h) => {
+                                    return h('div', [
+                                        h('div', {
+                                            style: {
+                                                fontSize: '16px',
+                                                fontWeight: '500',
+                                                marginBottom: '20px',
+                                            }
+                                        }, this.$L('导出结果')),
+                                        h('a', {
+                                            attrs: { href: res.data.url, target: '_blank' },
+                                        }, this.$L('点击下载 (%)', `${res.data.size} KB`))
+                                    ])
+                                },
+                            });
+                        } else {
+                            this.$Modal.error({title: this.$L('温馨提示'), content: res.msg});
+                        }
+                    }
+                });
+            },
+
             sreachTab(clear) {
                 if (clear === true) {
                     this.keys = {};

+ 31 - 7
resources/assets/js/main/pages/plans.vue

@@ -55,7 +55,7 @@
                         <div class="plans-table-info-btn"></div>
                     </div>
                     <div @mouseenter="active=1" class="plans-table-item" :class="{active:active==1}">
-                        <div class="plans-table-info-th">{{$L('社区版')}}</div>
+                        <div class="plans-table-info-th">{{$L('团队版')}}</div>
                         <div class="plans-table-info-price">
                             <img class="plans-version" src="../../../statics/images/plans/free.png">
                             <div class="currency"><em>0</em></div>
@@ -63,9 +63,12 @@
                         <div class="plans-table-info-desc">{{$L('适用于轻团队的任务协作')}}</div>
                         <div class="plans-table-info-desc">{{$L('无限制')}}</div>
                         <div class="plans-table-info-btn">
-                            <Tooltip :content="$L('账号:%、密码:%', 'admin', '123456')" transfer>
-                                <a href="https://demo.wookteam.com" class="btn" target="_blank">{{$L('体验DEMO')}}</a>
-                            </Tooltip>
+                            <div class="plans-info-btns">
+                                <Tooltip :content="$L('账号:%、密码:%', 'admin', '123456')" transfer>
+                                    <a href="https://demo.wookteam.com" class="btn" target="_blank">{{$L('体验DEMO')}}</a>
+                                </Tooltip>
+                                <a href="https://github.com/kuaifan/wookteam" class="github" target="_blank"><Icon type="logo-github"/></a>
+                            </div>
                         </div>
                     </div>
                     <div @mouseenter="active=2" class="plans-table-item" :class="{active:active==2}">
@@ -113,6 +116,7 @@
                             <div class="plans-table-td">{{$L('国际化')}}</div>
                             <div class="plans-table-td">{{$L('甘特图')}}</div>
                             <div class="plans-table-td">{{$L('任务动态')}}</div>
+                            <div class="plans-table-td">{{$L('导出任务')}}</div>
                             <div class="plans-table-td">{{$L('日程')}}</div>
                             <div class="plans-table-td">{{$L('周报/日报')}}</div>
 
@@ -138,6 +142,7 @@
                             <div class="plans-table-td"><Icon type="md-checkmark" /></div>
                             <div class="plans-table-td"><Icon type="md-checkmark" /></div>
                             <div class="plans-table-td"><Icon type="md-checkmark" /></div>
+                            <div class="plans-table-td"><Icon type="md-checkmark" /></div>
                             <div class="plans-table-td"> - </div>
                             <div class="plans-table-td"> - </div>
                             <div class="plans-table-td"> - </div>
@@ -170,6 +175,7 @@
                             <div class="plans-table-td"><Icon type="md-checkmark" /></div>
                             <div class="plans-table-td"><Icon type="md-checkmark" /></div>
                             <div class="plans-table-td"><Icon type="md-checkmark" /></div>
+                            <div class="plans-table-td"><Icon type="md-checkmark" /></div>
                         </div>
                         <div @mouseenter="active=3" class="plans-table-item" :class="{active:active==3}">
                             <div class="plans-table-td"><Icon type="md-checkmark" /></div>
@@ -192,6 +198,7 @@
                             <div class="plans-table-td"><Icon type="md-checkmark" /></div>
                             <div class="plans-table-td"><Icon type="md-checkmark" /></div>
                             <div class="plans-table-td"><Icon type="md-checkmark" /></div>
+                            <div class="plans-table-td"><Icon type="md-checkmark" /></div>
                         </div>
                     </div>
                 </div>
@@ -235,9 +242,12 @@
                             <div class="plans-table-td"><span> - </span></div>
                             <div class="plans-table-td"><span> - </span></div>
                             <div class="plans-table-info-btn">
-                                <Tooltip :content="$L('账号:%、密码:%', 'admin', '123456')" transfer>
-                                    <a href="https://demo.wookteam.com" class="btn" target="_blank">{{$L('体验DEMO')}}</a>
-                                </Tooltip>
+                                <div class="plans-info-btns">
+                                    <Tooltip :content="$L('账号:%、密码:%', 'admin', '123456')" transfer>
+                                        <a href="https://demo.wookteam.com" class="btn" target="_blank">{{$L('体验DEMO')}}</a>
+                                    </Tooltip>
+                                    <a href="https://github.com/kuaifan/wookteam" class="github" target="_blank"><Icon type="logo-github"/></a>
+                                </div>
                             </div>
                         </div>
                         <div @mouseenter="active=2" class="plans-table-item" :class="{active:active==2}">
@@ -807,6 +817,20 @@
                 justify-content: center;
                 align-items: center;
                 height: 115px;
+                .plans-info-btns {
+                    display: flex;
+                    flex-direction: row;
+                    align-items: center;
+                    .btn {
+                        padding: 14px 36px;
+                    }
+                    .github {
+                        margin-left: 10px;
+                        & > i {
+                            font-size: 32px;
+                        }
+                    }
+                }
                 .btn {
                     display: inline-block;
                     color: #fff;

+ 5 - 0
resources/assets/sass/main.scss

@@ -289,6 +289,11 @@
         .ivu-btn {
             margin-left: 8px;
         }
+        .left-btn {
+            float: left;
+            margin-right: 8px;
+            margin-left: 0;
+        }
     }
 }
 

+ 4 - 0
resources/lang/en/general.js

@@ -516,4 +516,8 @@ export default {
     "分享文档": "Share documents",
     "历史版本": "Historic version",
     "浏览文档": "View the document",
+    "导出任务": "Export Task",
+    "导出列表": "Export List",
+    "导出结果": "Export Results",
+    "点击下载 (%)": "Click to download (%)",
 }

+ 1 - 0
storage/.gitignore

@@ -1,3 +1,4 @@
+laravels.conf
 laravels.json
 laravels.pid
 laravels-timer-process.pid