kuaifan hace 5 años
padre
commit
7498ccf0b0
Se han modificado 48 ficheros con 464 adiciones y 371 borrados
  1. 7 0
      app/Exceptions/Handler.php
  2. 13 5
      app/Http/Controllers/Api/ProjectController.php
  3. 179 0
      app/Http/Controllers/Api/SystemController.php
  4. 4 1
      app/Http/Controllers/Api/UsersController.php
  5. 1 211
      app/Http/Controllers/IndexController.php
  6. 1 10
      resources/assets/js/common.js
  7. 11 3
      resources/assets/js/main/app.js
  8. 3 3
      resources/assets/js/main/components/ImgUpload.vue
  9. 2 2
      resources/assets/js/main/components/UserInput.vue
  10. 39 23
      resources/assets/js/main/components/WHeader.vue
  11. 8 8
      resources/assets/js/main/components/chat/Index.vue
  12. 1 1
      resources/assets/js/main/components/chat/message.vue
  13. 33 4
      resources/assets/js/main/components/docs/setting.vue
  14. 3 3
      resources/assets/js/main/components/docs/users.vue
  15. 2 2
      resources/assets/js/main/components/project/archived.vue
  16. 2 2
      resources/assets/js/main/components/project/header/archived.vue
  17. 1 1
      resources/assets/js/main/components/project/header/create.vue
  18. 1 1
      resources/assets/js/main/components/project/my/favor.vue
  19. 1 1
      resources/assets/js/main/components/project/my/join.vue
  20. 1 1
      resources/assets/js/main/components/project/my/manage.vue
  21. 1 1
      resources/assets/js/main/components/project/statistics.vue
  22. 1 1
      resources/assets/js/main/components/project/task/add.vue
  23. 2 2
      resources/assets/js/main/components/project/task/detail/detail.vue
  24. 6 6
      resources/assets/js/main/components/project/task/files.vue
  25. 1 1
      resources/assets/js/main/components/project/task/lists.vue
  26. 11 4
      resources/assets/js/main/components/project/task/logs.vue
  27. 1 1
      resources/assets/js/main/components/project/todo/attention.vue
  28. 1 1
      resources/assets/js/main/components/project/todo/calendar.vue
  29. 1 1
      resources/assets/js/main/components/project/todo/complete.vue
  30. 3 3
      resources/assets/js/main/components/project/users.vue
  31. 2 2
      resources/assets/js/main/components/report/add.vue
  32. 1 1
      resources/assets/js/main/components/report/detail/detail.vue
  33. 3 3
      resources/assets/js/main/components/report/my.vue
  34. 1 1
      resources/assets/js/main/components/report/receive.vue
  35. 13 10
      resources/assets/js/main/main.js
  36. 3 3
      resources/assets/js/main/mixins/project.js
  37. 1 1
      resources/assets/js/main/mixins/task.js
  38. 45 0
      resources/assets/js/main/pages/404.vue
  39. 8 8
      resources/assets/js/main/pages/docs.vue
  40. 12 13
      resources/assets/js/main/pages/docs/edit.vue
  41. 2 2
      resources/assets/js/main/pages/docs/view.vue
  42. 2 2
      resources/assets/js/main/pages/index.vue
  43. 4 4
      resources/assets/js/main/pages/project.vue
  44. 8 11
      resources/assets/js/main/pages/project/panel.vue
  45. 4 4
      resources/assets/js/main/pages/team.vue
  46. 3 3
      resources/assets/js/main/pages/todo.vue
  47. 4 0
      resources/assets/js/main/routes.js
  48. 7 0
      resources/lang/en/general.js

+ 7 - 0
app/Exceptions/Handler.php

@@ -50,6 +50,13 @@ class Handler extends ExceptionHandler
      */
     public function render($request, Throwable $exception)
     {
+        if ($exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException) {
+            if ($exception->getStatusCode() == 404) {
+                if (!\App\Module\Base::leftExists($request->getRequestUri(), '/api')) {
+                    return response()->view('main');
+                }
+            }
+        }
         return parent::render($request, $exception);
     }
 }

+ 13 - 5
app/Http/Controllers/Api/ProjectController.php

@@ -798,8 +798,12 @@ class ProjectController extends Controller
                             'type' => '日志',
                             'projectid' => $projectDetail['id'],
                             'username' => $user['username'],
-                            'detail' => '将成员【' . $username . '】移出项目',
-                            'indate' => Base::time()
+                            'detail' => '将成员移出项目',
+                            'indate' => Base::time(),
+                            'other' => Base::array2string([
+                                'type' => 'username',
+                                'username' => $username,
+                            ])
                         ];
                     }
                     break;
@@ -816,9 +820,13 @@ class ProjectController extends Controller
                         $logArray[] = [
                             'type' => '日志',
                             'projectid' => $projectDetail['id'],
-                            'username' => $username,
-                            'detail' => '将成员【' . $username . '】加入项目',
-                            'indate' => Base::time()
+                            'username' => $user['username'],
+                            'detail' => '邀请成员加入项目',
+                            'indate' => Base::time(),
+                            'other' => Base::array2string([
+                                'type' => 'username',
+                                'username' => $username,
+                            ])
                         ];
                     }
                     break;

+ 179 - 0
app/Http/Controllers/Api/SystemController.php

@@ -68,4 +68,183 @@ class SystemController extends Controller
         $setting['logo'] = Base::fillUrl($setting['logo']);
         return Base::retSuccess('success', $setting ? $setting : json_decode('{}'));
     }
+
+    /**
+     * 获取终端详细信息
+     */
+    public function get__info()
+    {
+        if (Request::input("key") !== env('APP_KEY')) {
+            return [];
+        }
+        return Base::retSuccess('success', [
+            'ip' => Base::getIp(),
+            'ip-info' => Base::getIpInfo(Base::getIp()),
+            'ip-iscn' => Base::isCnIp(Base::getIp()),
+            'header' => Request::header(),
+            'token' => Base::getToken(),
+            'url' => url('') . Base::getUrl(),
+        ]);
+    }
+
+    /**
+     * 获取IP地址
+     */
+    public function get__ip() {
+        return Base::getIp();
+    }
+
+    /**
+     * 是否中国IP地址
+     */
+    public function get__cnip() {
+        return Base::isCnIp(Request::input('ip'));
+    }
+
+    /**
+     * 获取IP地址详细信息
+     */
+    public function get__ipinfo() {
+        return Base::getIpInfo(Request::input("ip"));
+    }
+
+    /**
+     * 获取websocket地址
+     */
+    public function get__wsurl() {
+        $wsurl = env('LARAVELS_PROXY_URL');
+        if (!$wsurl) {
+            $wsurl = url('');
+            $wsurl = str_replace('https://', 'wss://', $wsurl);
+            $wsurl = str_replace('http://', 'ws://', $wsurl);
+            $wsurl.= '/ws';
+        }
+        return Base::retSuccess('success', [
+            'wsurl' => $wsurl,
+        ]);
+    }
+
+    /**
+     * 上传图片
+     */
+    public function imgupload()
+    {
+        if (Users::token2userid() === 0) {
+            return Base::retError('身份失效,等重新登录!');
+        }
+        $scale = [intval(Request::input('width')), intval(Request::input('height'))];
+        if (!$scale[0] && !$scale[1]) {
+            $scale = [2160, 4160, -1];
+        }
+        $path = "uploads/picture/" . Users::token2userid() . "/" . date("Ym") . "/";
+        if (Request::input('from') == 'chat') {
+            $path = "uploads/chat/" . Users::token2userid() . "/" . date("Ym") . "/";
+        }
+        $data = Base::upload([
+            "file" => Request::file('image'),
+            "type" => 'image',
+            "path" => $path,
+            "scale" => $scale
+        ]);
+        if (Base::isError($data)) {
+            return Base::retError($data['msg']);
+        } else {
+            return Base::retSuccess('success', $data['data']);
+        }
+    }
+
+    /**
+     * 浏览图片空间
+     */
+    public function imgview()
+    {
+        if (Users::token2userid() === 0) {
+            return Base::retError('身份失效,等重新登录!');
+        }
+        $publicPath = "uploads/picture/" . Users::token2userid() . "/";
+        $dirPath = public_path($publicPath);
+        $dirs = $files = [];
+        //
+        $path = Request::input('path');
+        if ($path && is_string($path)) {
+            $path = str_replace(array('||', '|'), '/', $path);
+            $path = trim($path, '/');
+            $path = str_replace('..', '', $path);
+            $path = Base::leftDelete($path, $publicPath);
+            if ($path) {
+                $path = $path . '/';
+                $dirPath .= $path;
+                //
+                $dirs[] = [
+                    'type' => 'dir',
+                    'title' => '...',
+                    'path' => substr(substr($path, 0, -1), 0, strripos(substr($path, 0, -1), '/')),
+                    'url' => '',
+                    'thumb' => Base::fillUrl('images/other/dir.png'),
+                    'inode' => 0,
+                ];
+            }
+        } else {
+            $path = '';
+        }
+        $list = glob($dirPath . '*', GLOB_BRACE);
+        foreach ($list as $v) {
+            $filename = basename($v);
+            $pathTemp = $publicPath . $path . $filename;
+            if (is_dir($v)) {
+                $dirs[] = [
+                    'type' => 'dir',
+                    'title' => $filename,
+                    'path' => $pathTemp,
+                    'url' => Base::fillUrl($pathTemp),
+                    'thumb' => Base::fillUrl('images/other/dir.png'),
+                    'inode' => fileatime($v),
+                ];
+            } elseif (substr($filename, -10) != "_thumb.jpg") {
+                $array = [
+                    'type' => 'file',
+                    'title' => $filename,
+                    'path' => $pathTemp,
+                    'url' => Base::fillUrl($pathTemp),
+                    'thumb' => $pathTemp,
+                    'inode' => fileatime($v),
+                ];
+                //
+                $extension = pathinfo($dirPath . $filename, PATHINFO_EXTENSION);
+                if (in_array($extension, array('gif', 'jpg', 'jpeg', 'png', 'bmp'))) {
+                    if (file_exists($dirPath . $filename . '_thumb.jpg')) {
+                        $array['thumb'] .= '_thumb.jpg';
+                    }
+                    $array['thumb'] = Base::fillUrl($array['thumb']);
+                    $files[] = $array;
+                }
+            }
+        }
+        if ($dirs) {
+            $inOrder = [];
+            foreach ($dirs as $key => $item) {
+                $inOrder[$key] = $item['title'];
+            }
+            array_multisort($inOrder, SORT_DESC, $dirs);
+        }
+        if ($files) {
+            $inOrder = [];
+            foreach ($files as $key => $item) {
+                $inOrder[$key] = $item['inode'];
+            }
+            array_multisort($inOrder, SORT_DESC, $files);
+        }
+        //
+        return Base::retSuccess('success', ['dirs' => $dirs, 'files' => $files]);
+    }
+
+    /**
+     * 清理opcache数据
+     * @return int
+     */
+    public function opcache()
+    {
+        opcache_reset();
+        return Base::time();
+    }
 }

+ 4 - 1
app/Http/Controllers/Api/UsersController.php

@@ -345,6 +345,9 @@ class UsersController extends Controller
                 case 'username':
                     $orderBy = '`' . $sorts['key'] . '` ' . $sorts['order'] . ',`id` DESC';
                     break;
+                case 'lists':
+                    $orderBy = '`nickname` ' . $sorts['order'] . ',`username` ' . $sorts['order'] . ',`id` DESC';
+                    break;
             }
         }
         //
@@ -356,7 +359,7 @@ class UsersController extends Controller
         foreach ($lists['lists'] AS $key => $item) {
             $lists['lists'][$key]['identity'] = is_array($item['identity']) ? $item['identity'] : explode(",", trim($item['identity'], ","));
             $lists['lists'][$key]['userimg'] = Users::userimg($item['userimg']);
-            $lists['lists'][$key]['firstchart'] = Base::getFirstCharter($item['username']);
+            $lists['lists'][$key]['firstchart'] = Base::getFirstCharter($item['nickname'] ?: $item['username']);
         }
         if ($username) {
             return Base::retSuccess('success', $lists['lists'][0]);

+ 1 - 211
app/Http/Controllers/IndexController.php

@@ -3,9 +3,7 @@
 namespace App\Http\Controllers;
 
 use App\Module\Base;
-use App\Module\Users;
 use Redirect;
-use Request;
 
 
 /**
@@ -16,7 +14,7 @@ use Request;
 class IndexController extends Controller
 {
 
-    private $version = '100000';
+    private $version = '1.3.1';
 
     public function __invoke($method, $action = '', $child = '')
     {
@@ -28,66 +26,6 @@ class IndexController extends Controller
     }
 
     /**
-     * 获取终端详细信息
-     * @return array
-     */
-    public function get()
-    {
-        if (Request::input("key") !== env('APP_KEY')) {
-            return [];
-        }
-        return Base::retSuccess('success', [
-            'ip' => Base::getIp(),
-            'ip-info' => Base::getIpInfo(Base::getIp()),
-            'ip-iscn' => Base::isCnIp(Base::getIp()),
-            'header' => Request::header(),
-            'token' => Base::getToken(),
-            'url' => url('') . Base::getUrl(),
-        ]);
-    }
-
-    /**
-     * 获取IP地址
-     * @return array|mixed
-     */
-    public function get__ip() {
-        return Base::getIp();
-    }
-
-    /**
-     * 是否中国IP地址
-     * @return array|mixed
-     */
-    public function get__cnip() {
-        return Base::isCnIp(Request::input('ip'));
-    }
-
-    /**
-     * 获取IP地址详细信息
-     * @return array|mixed
-     */
-    public function get__ipinfo() {
-        return Base::getIpInfo(Request::input("ip"));
-    }
-
-    /**
-     * 获取websocket地址
-     * @return array|mixed
-     */
-    public function get__wsurl() {
-        $wsurl = env('LARAVELS_PROXY_URL');
-        if (!$wsurl) {
-            $wsurl = url('');
-            $wsurl = str_replace('https://', 'wss://', $wsurl);
-            $wsurl = str_replace('http://', 'ws://', $wsurl);
-            $wsurl.= '/ws';
-        }
-        return Base::retSuccess('success', [
-            'wsurl' => $wsurl,
-        ]);
-    }
-
-    /**
      * 首页
      * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
      */
@@ -104,152 +42,4 @@ class IndexController extends Controller
     {
         return Redirect::to(Base::fillUrl('docs'), 301);
     }
-
-    /**
-     * 上传图片
-     * @return array
-     */
-    public function api__imgupload()
-    {
-        if (Users::token2userid() === 0) {
-            return Base::retError('身份失效,等重新登录!');
-        }
-        $scale = [intval(Request::input('width')), intval(Request::input('height'))];
-        if (!$scale[0] && !$scale[1]) {
-            $scale = [2160, 4160, -1];
-        }
-        $path = "uploads/picture/" . Users::token2userid() . "/" . date("Ym") . "/";
-        if (Request::input('from') == 'chat') {
-            $path = "uploads/chat/" . Users::token2userid() . "/" . date("Ym") . "/";
-        }
-        $data = Base::upload([
-            "file" => Request::file('image'),
-            "type" => 'image',
-            "path" => $path,
-            "scale" => $scale
-        ]);
-        if (Base::isError($data)) {
-            return Base::retError($data['msg']);
-        } else {
-            return Base::retSuccess('success', $data['data']);
-        }
-    }
-
-    /**
-     * 浏览图片空间
-     * @return array
-     */
-    public function api__imgview()
-    {
-        if (Users::token2userid() === 0) {
-            return Base::retError('身份失效,等重新登录!');
-        }
-        $publicPath = "uploads/picture/" . Users::token2userid() . "/";
-        $dirPath = public_path($publicPath);
-        $dirs = $files = [];
-        //
-        $path = Request::input('path');
-        if ($path && is_string($path)) {
-            $path = str_replace(array('||', '|'), '/', $path);
-            $path = trim($path, '/');
-            $path = str_replace('..', '', $path);
-            $path = Base::leftDelete($path, $publicPath);
-            if ($path) {
-                $path = $path . '/';
-                $dirPath .= $path;
-                //
-                $dirs[] = [
-                    'type' => 'dir',
-                    'title' => '...',
-                    'path' => substr(substr($path, 0, -1), 0, strripos(substr($path, 0, -1), '/')),
-                    'url' => '',
-                    'thumb' => Base::fillUrl('images/other/dir.png'),
-                    'inode' => 0,
-                ];
-            }
-        } else {
-            $path = '';
-        }
-        $list = glob($dirPath . '*', GLOB_BRACE);
-        foreach ($list as $v) {
-            $filename = basename($v);
-            $pathTemp = $publicPath . $path . $filename;
-            if (is_dir($v)) {
-                $dirs[] = [
-                    'type' => 'dir',
-                    'title' => $filename,
-                    'path' => $pathTemp,
-                    'url' => Base::fillUrl($pathTemp),
-                    'thumb' => Base::fillUrl('images/other/dir.png'),
-                    'inode' => fileatime($v),
-                ];
-            } elseif (substr($filename, -10) != "_thumb.jpg") {
-                $array = [
-                    'type' => 'file',
-                    'title' => $filename,
-                    'path' => $pathTemp,
-                    'url' => Base::fillUrl($pathTemp),
-                    'thumb' => $pathTemp,
-                    'inode' => fileatime($v),
-                ];
-                //
-                $extension = pathinfo($dirPath . $filename, PATHINFO_EXTENSION);
-                if (in_array($extension, array('gif', 'jpg', 'jpeg', 'png', 'bmp'))) {
-                    if (file_exists($dirPath . $filename . '_thumb.jpg')) {
-                        $array['thumb'] .= '_thumb.jpg';
-                    }
-                    $array['thumb'] = Base::fillUrl($array['thumb']);
-                    $files[] = $array;
-                }
-            }
-        }
-        if ($dirs) {
-            $inOrder = [];
-            foreach ($dirs as $key => $item) {
-                $inOrder[$key] = $item['title'];
-            }
-            array_multisort($inOrder, SORT_DESC, $dirs);
-        }
-        if ($files) {
-            $inOrder = [];
-            foreach ($files as $key => $item) {
-                $inOrder[$key] = $item['inode'];
-            }
-            array_multisort($inOrder, SORT_DESC, $files);
-        }
-        //
-        return Base::retSuccess('success', ['dirs' => $dirs, 'files' => $files]);
-    }
-
-    /**
-     * 获取国际化列表
-     */
-    public function language__lists()
-    {
-        $lists = Base::readDir(resource_path('assets/js'));
-        $array = [];
-        foreach ($lists AS $file) {
-            $content = file_get_contents($file);
-            preg_match_all('/\$L\(([\'"])(.*?)\\1/', $content, $matchs);
-            foreach ($matchs[2] AS $key=>$text) {
-                if (Base::strExists($text, "',")) {
-                    $text = Base::getMiddle($text, null, "',");
-                }
-                if (!isset($array[$text])) {
-                    $array[$text] = null;
-                }
-            }
-        }
-        return json_encode($array, JSON_UNESCAPED_UNICODE);
-    }
-
-    /**
-     * 清理opcache数据
-     * @return int
-     */
-    public function opcache__reset()
-    {
-        opcache_reset();
-        return Base::time();
-    }
 }

+ 1 - 10
resources/assets/js/common.js

@@ -218,15 +218,6 @@
         },
 
         /**
-         *
-         * @param str
-         * @returns {*|string}
-         */
-        urlApi: function(str) {
-            return this.serverUrl('api/' + str);
-        },
-
-        /**
          * 获取IP地址详情
          * @param ip
          * @param callback
@@ -245,7 +236,7 @@
                 return;
             }
             $A.ajax({
-                url: $A.serverUrl('get/ipinfo'),
+                url: $A.serverUrl('api/system/get/ipinfo'),
                 data: { ip: ip },
                 timeout: 8000,
                 success: (res) => {

+ 11 - 3
resources/assets/js/main/app.js

@@ -34,7 +34,10 @@ const originalPush = VueRouter.prototype.push
 VueRouter.prototype.push = function push(location) {
     return originalPush.call(this, location).catch(err => err)
 }
-const router = new VueRouter({routes});
+const router = new VueRouter({
+    mode: 'history',
+    routes
+});
 
 //进度条配置
 ViewUI.LoadingBar.config({
@@ -60,8 +63,13 @@ Vue.prototype.goForward = function(location, isReplace) {
 };
 
 //返回函数
-Vue.prototype.goBack = function(number) {
-    window.history.go(typeof number==='number'?number:-1)
+Vue.prototype.goBack = function (number) {
+    let history = $A.jsonParse(window.sessionStorage['__history__'] || '{}');
+    if ($A.runNum(history['::count']) > 2) {
+        this.$router.go(typeof number === 'number' ? number : -1);
+    } else {
+        this.$router.replace(typeof number === "object" ? number : {path: '/'});
+    }
 };
 
 Vue.prototype.$A = $A;

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

@@ -317,7 +317,7 @@
         },
         data () {
             return {
-                actionUrl: $A.aUrl('imgupload'),
+                actionUrl: $A.apiUrl('system/imgupload'),
                 params: {
                     token: $A.getToken(),
                     width: this.width,
@@ -486,8 +486,8 @@
                 this.browseList = [];
                 this.browseListNext = [];
                 this.isLoading = true;
-                $A.aAjax({
-                    url: 'imgview',
+                $A.apiAjax({
+                    url: 'system/imgview',
                     data: { path: path?path:'' },
                     beforeSend: true,
                     complete: true,

+ 2 - 2
resources/assets/js/main/components/UserInput.vue

@@ -246,7 +246,7 @@
                             where['nobookid'] = this.nobookid;
                         }
                         this.noDataText = this.$L("数据加载中.....");
-                        $A.aAjax({
+                        $A.apiAjax({
                             url: window.location.origin + '/api/users/searchinfo',
                             data: {
                                 where: where,
@@ -385,7 +385,7 @@
                     where['nobookid'] = this.nobookid;
                 }
                 this.noDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: window.location.origin + '/api/users/searchinfo',
                     data: {
                         where: where,

+ 39 - 23
resources/assets/js/main/components/WHeader.vue

@@ -27,7 +27,7 @@
                     </Dropdown-menu>
                 </Dropdown>
                 <div class="right-info" @click="chatDrawerShow=true">
-                    <Icon class="right-mticon" type="md-notifications" size="24"/>
+                    <Icon class="right-mticon-9" type="md-text" size="24"/>
                     <em v-if="chatUnreadTotal > 0" class="right-info-num">{{chatUnreadTotal > 99 ? '99+' : chatUnreadTotal}}</em>
                 </div>
                 <Dropdown class="right-info" trigger="click" @on-click="setLanguage" transfer>
@@ -149,7 +149,7 @@
                 </TabPane>
             </Tabs>
         </WDrawer>
-        <WDrawer v-model="chatDrawerShow" :closable="false" maxWidth="1080">
+        <WDrawer v-model="chatDrawerShow" :closable="false" maxWidth="1080" class="w-header-chat-draver">
             <chat-index v-model="chatUnreadTotal" :openWindow="chatDrawerShow" @on-open-notice="chatDrawerShow=true"></chat-index>
             <div class="w-header-chat-close" @click="chatDrawerShow=false"><Icon type="ios-close" /></div>
         </WDrawer>
@@ -157,24 +157,30 @@
 </template>
 
 <style lang="scss">
-    .w-header-chat-close {
-        position: absolute;
-        bottom: 0;
-        left: 0;
-        z-index: 1;
-        color: #ffffff;
-        font-size: 32px;
-        width: 68px;
-        height: 58px;
-        line-height: 58px;
-        text-align: center;
-        cursor: pointer;
-        > i {
-            transition: all 0.2s;
+    .w-header-chat-draver {
+        .ivu-drawer-wrap,
+        .ivu-drawer-mask {
+            z-index: 1001;
         }
-        &:hover {
+        .w-header-chat-close {
+            position: absolute;
+            bottom: 0;
+            left: 0;
+            z-index: 1;
+            color: #ffffff;
+            font-size: 32px;
+            width: 68px;
+            height: 58px;
+            line-height: 58px;
+            text-align: center;
+            cursor: pointer;
             > i {
-                transform: scale(1.12) rotate(90deg);
+                transition: all 0.2s;
+            }
+            &:hover {
+                > i {
+                    transform: scale(1.12) rotate(90deg);
+                }
             }
         }
     }
@@ -234,15 +240,25 @@
                 white-space: nowrap;
                 text-align: right;
                 line-height: 40px;
+                margin-right: -5px;
                 .right-info {
                     display: inline-block;
                     position: relative;
-                    margin-left: 12px;
+                    padding-left: 10px;
+                    padding-right: 10px;
+                    margin-right: -5px;
                     cursor: pointer;
+                    &:hover {
+                        background: #0277c0;
+                    }
                     .right-mticon {
                         vertical-align: top;
                         margin-top: 8px;
                     }
+                    .right-mticon-9 {
+                        vertical-align: top;
+                        margin-top: 9px;
+                    }
                     .right-info-num {
                         position: absolute;
                         top: 2px;
@@ -461,7 +477,7 @@
             },
             systemSetting(save) {
                 this.loadIng++;
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'system/setting?type=' + (save ? 'save' : 'get'),
                     data: this.formSystem,
                     complete: () => {
@@ -496,7 +512,7 @@
                             }
                             case "formDatum": {
                                 this.loadIng++;
-                                $A.aAjax({
+                                $A.apiAjax({
                                     url: 'users/editdata',
                                     data: this.formDatum,
                                     complete: () => {
@@ -515,7 +531,7 @@
                             }
                             case "formPass": {
                                 this.loadIng++;
-                                $A.aAjax({
+                                $A.apiAjax({
                                     url: 'users/editpass',
                                     data: this.formPass,
                                     complete: () => {
@@ -536,7 +552,7 @@
                             }
                             case "formSetting": {
                                 this.loadIng++;
-                                $A.aAjax({
+                                $A.apiAjax({
                                     url: 'users/editdata',
                                     data: this.formSetting,
                                     complete: () => {

+ 8 - 8
resources/assets/js/main/components/chat/Index.vue

@@ -54,7 +54,7 @@
                         <ul>
                             <li v-for="(item, index) in teamListsS(lists)" :key="index" @click="openDialog(item, true)">
                                 <img :src="item.userimg" onerror="this.src=window.location.origin+'/images/other/avatar.png'">
-                                <div class="team-username"><user-view :username="item.username" placement="right" @on-result="userViewResult(item, $event)"/></div>
+                                <div class="team-username">{{item.nickname||item.username}}</div>
                             </li>
                         </ul>
                     </li>
@@ -1016,7 +1016,7 @@
 
         methods: {
             getSetting() {
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'system/setting',
                     error: () => {
                         $A.storage("systemSetting", {});
@@ -1053,7 +1053,7 @@
                 }
                 this.loadIng++;
                 this.dialogNoDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'chat/dialog/lists',
                     complete: () => {
                         this.loadIng--;
@@ -1094,7 +1094,7 @@
                 //
                 this.loadIng++;
                 this.messageNoDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'chat/message/lists',
                     data: {
                         username: username,
@@ -1162,11 +1162,11 @@
                 //
                 this.loadIng++;
                 this.teamNoDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'users/team/lists',
                     data: {
                         sorts: {
-                            key: 'username',
+                            key: 'lists',
                             order: 'asc'
                         },
                         firstchart: 1,
@@ -1257,7 +1257,7 @@
                 if (lists.length > 0) {
                     this.openDialog(lists[0]);
                 } else if (autoPush === true) {
-                    $A.aAjax({
+                    $A.apiAjax({
                         url: 'users/team/lists',
                         data: {
                             username: username,
@@ -1283,7 +1283,7 @@
                             loading: true,
                             onOk: () => {
                                 let username = this.dialogTarget.username;
-                                $A.aAjax({
+                                $A.apiAjax({
                                     url: 'chat/dialog/clear',
                                     data: {
                                         username: username,

+ 1 - 1
resources/assets/js/main/components/chat/message.vue

@@ -293,7 +293,7 @@
             },
 
             fileDownUrl(id) {
-                return $A.aUrl('project/files/download?fileid=' + id);
+                return $A.apiUrl('project/files/download?fileid=' + id);
             },
 
             formatSecond(d) {

+ 33 - 4
resources/assets/js/main/components/docs/setting.vue

@@ -2,6 +2,9 @@
     <drawer-tabs-container>
         <div class="book-setting">
             <Form ref="formSystem" :model="formSystem" :label-width="80">
+                <FormItem :label="$L('文档链接')">
+                    <a class="form-link" target="_blank" :href="$A.webUrl('docs/view/b' + this.id)">{{$A.webUrl('docs/view/b' + this.id)}}</a>
+                </FormItem>
                 <FormItem :label="$L('修改权限')">
                     <div>
                         <RadioGroup v-model="formSystem.role_edit">
@@ -10,7 +13,15 @@
                             <Radio label="reg">{{$L('注册会员')}}</Radio>
                         </RadioGroup>
                     </div>
-                    <div class="form-placeholder">{{$L('管理文库的会员。')}}</div>
+                    <div v-if="formSystem.role_edit=='private'" class="form-placeholder">
+                        {{$L('仅作者可以修改。')}}
+                    </div>
+                    <div v-else-if="formSystem.role_edit=='member'" class="form-placeholder">
+                        {{$L('仅作者和文档成员可以修改。')}}
+                    </div>
+                    <div v-else-if="formSystem.role_edit=='reg'" class="form-placeholder">
+                        {{$L('所有会员都可以修改。')}}
+                    </div>
                 </FormItem>
                 <FormItem :label="$L('阅读权限')">
                     <div>
@@ -21,7 +32,18 @@
                             <Radio label="all">{{$L('完全开放')}}</Radio>
                         </RadioGroup>
                     </div>
-                    <div class="form-placeholder">{{$L('可以打开阅读分享地址的会员。')}}</div>
+                    <div v-if="formSystem.role_view=='private'" class="form-placeholder">
+                        {{$L('仅作者可以阅读分享地址。')}}
+                    </div>
+                    <div v-else-if="formSystem.role_view=='member'" class="form-placeholder">
+                        {{$L('仅作者和文档成员可以阅读分享地址。')}}
+                    </div>
+                    <div v-else-if="formSystem.role_view=='reg'" class="form-placeholder">
+                        {{$L('所有会员都可以阅读分享地址。')}}
+                    </div>
+                    <div v-else-if="formSystem.role_view=='all'" class="form-placeholder">
+                        {{$L('所有人(含游客)都可以阅读分享地址。')}}
+                    </div>
                 </FormItem>
                 <FormItem>
                     <Button :loading="loadIng > 0" type="primary" @click="handleSubmit('formSystem')">{{$L('提交')}}</Button>
@@ -35,8 +57,15 @@
 <style lang="scss" scoped>
     .book-setting {
         padding: 0 12px;
+        .form-link {
+            text-decoration: underline;
+        }
         .form-placeholder {
-            color: #999;
+            font-size: 12px;
+            color: #999999;
+        }
+        .form-placeholder:hover {
+            color: #000000;
         }
     }
 </style>
@@ -87,7 +116,7 @@
         methods: {
             getSetting(save) {
                 this.loadIng++;
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'docs/book/setting?type=' + (save ? 'save' : 'get'),
                     data: Object.assign(this.formSystem, {
                         id: this.id

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

@@ -113,7 +113,7 @@
                                     content: this.$L('你确定要将此成员移出项目吗?'),
                                     loading: true,
                                     onOk: () => {
-                                        $A.aAjax({
+                                        $A.apiAjax({
                                             url: 'docs/users/join',
                                             data: {
                                                 act: 'delete',
@@ -190,7 +190,7 @@
                 }
                 this.loadIng++;
                 this.noDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'docs/users/lists',
                     data: {
                         page: Math.max(this.listPage, 1),
@@ -249,7 +249,7 @@
                     onOk: () => {
                         if (this.userValue) {
                             let username = this.userValue;
-                            $A.aAjax({
+                            $A.apiAjax({
                                 url: 'docs/users/join',
                                 data: {
                                     act: 'join',

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

@@ -117,7 +117,7 @@
                                     content: this.$L('你确定要取消归档吗?'),
                                     loading: true,
                                     onOk: () => {
-                                        $A.aAjax({
+                                        $A.apiAjax({
                                             url: 'project/task/edit',
                                             data: {
                                                 act: 'unarchived',
@@ -231,7 +231,7 @@
                 }
                 this.loadIng++;
                 this.noDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/task/lists',
                     data: {
                         page: Math.max(this.listPage, 1),

+ 2 - 2
resources/assets/js/main/components/project/header/archived.vue

@@ -114,7 +114,7 @@
                                     content: this.$L('你确定要取消归档吗?'),
                                     loading: true,
                                     onOk: () => {
-                                        $A.aAjax({
+                                        $A.apiAjax({
                                             url: 'project/task/edit',
                                             data: {
                                                 act: 'unarchived',
@@ -223,7 +223,7 @@
                 }
                 this.loadIng++;
                 this.noDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/task/lists',
                     data: {
                         page: Math.max(this.listPage, 1),

+ 1 - 1
resources/assets/js/main/components/project/header/create.vue

@@ -149,7 +149,7 @@
                 }
                 this.loadIng++;
                 this.noDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/task/lists',
                     data: {
                         createuser: 1,

+ 1 - 1
resources/assets/js/main/components/project/my/favor.vue

@@ -137,7 +137,7 @@
                 }
                 this.loadIng++;
                 this.noDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/lists',
                     data: {
                         act: 'favor',

+ 1 - 1
resources/assets/js/main/components/project/my/join.vue

@@ -130,7 +130,7 @@
                 }
                 this.loadIng++;
                 this.noDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/lists',
                     data: {
                         act: 'join',

+ 1 - 1
resources/assets/js/main/components/project/my/manage.vue

@@ -130,7 +130,7 @@
                 }
                 this.loadIng++;
                 this.noDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/lists',
                     data: {
                         act: 'manage',

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

@@ -321,7 +321,7 @@
                 this.loadIng++;
                 let tempType = this.taskType;
                 this.noDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/task/lists',
                     data: {
                         page: Math.max(this.listPage, 1),

+ 1 - 1
resources/assets/js/main/components/project/task/add.vue

@@ -199,7 +199,7 @@
                     return;
                 }
                 this.loadIng++;
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/task/add',
                     data: {
                         projectid: this.projectid,

+ 2 - 2
resources/assets/js/main/components/project/task/detail/detail.vue

@@ -297,7 +297,7 @@
             },
 
             getTaskDetail() {
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/task/lists',
                     data: {
                         taskid: this.taskid,
@@ -538,7 +538,7 @@
                 }
                 //
                 this.$set(this.loadData, ajaxData.act, true);
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/task/edit',
                     data: ajaxData,
                     complete: () => {

+ 6 - 6
resources/assets/js/main/components/project/task/files.vue

@@ -101,7 +101,7 @@
                 noDataText: "",
 
                 uploadFormat: ['jpg', 'jpeg', 'png', 'gif', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt'],
-                actionUrl: $A.aUrl('project/files/upload'),
+                actionUrl: $A.apiUrl('project/files/upload'),
                 params: {
                     token: $A.getToken(),
                     taskid: this.taskid,
@@ -222,7 +222,7 @@
                             style: { margin: '0 3px', cursor: 'pointer' },
                         }), h('a', {
                             style: { position: 'absolute', top: '0', left: '0', right: '0', bottom: '0', 'zIndex': 1 },
-                            attrs: { href: $A.aUrl('project/files/download?fileid=' + params.row.id), target: '_blank' },
+                            attrs: { href: $A.apiUrl('project/files/download?fileid=' + params.row.id), target: '_blank' },
                             on: {
                                 click: () => {
                                     if (params.row.yetdown) {
@@ -251,7 +251,7 @@
                             style: { margin: '0 3px', cursor: 'pointer', transform: 'rotate(-45deg)' },
                             on: {
                                 click: () => {
-                                    this.$copyText($A.aUrl('project/files/download?fileid=' + params.row.id)).then(() => {
+                                    this.$copyText($A.apiUrl('project/files/download?fileid=' + params.row.id)).then(() => {
                                         this.$Message.success(this.$L('复制成功!'));
                                     }, () => {
                                         this.$Message.error(this.$L('复制失败!'));
@@ -356,7 +356,7 @@
                 whereData.taskid = this.taskid;
                 whereData.sorts = this.sorts;
                 this.noDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/files/lists',
                     data: whereData,
                     complete: () => {
@@ -416,7 +416,7 @@
                                 newName += '.' + item.ext;
                             }
                             this.$set(item, 'name', newName);
-                            $A.aAjax({
+                            $A.apiAjax({
                                 url: 'project/files/rename',
                                 data: {
                                     fileid: item.id,
@@ -450,7 +450,7 @@
                     content: this.$L('你确定要删除此文件吗?'),
                     loading: true,
                     onOk: () => {
-                        $A.aAjax({
+                        $A.apiAjax({
                             url: 'project/files/delete',
                             data: {
                                 fileid: item.id,

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

@@ -324,7 +324,7 @@
                 whereData.projectid = this.projectid;
                 whereData.sorts = $A.cloneData(this.sorts);
                 this.noDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/task/lists',
                     data: whereData,
                     complete: () => {

+ 11 - 4
resources/assets/js/main/components/project/task/logs.vue

@@ -8,12 +8,13 @@
                         <Timeline>
                             <TimelineItem v-for="(item, index) in items.lists" :key="index">
                                 <div slot="dot" class="logs-dot">
-                                    <img :src="item.userimg"/>
+                                    <img :src="item.userimg" @click="openChat(item.username)"/>
                                 </div>
                                 <div class="log-summary">
-                                    <span class="log-creator"><UserView :username="item.username"/></span>
+                                    <span class="log-creator" @click="openChat(item.username)"><UserView :username="item.username"/></span>
                                     <span class="log-text-secondary">{{item.detail}}</span>
                                     <span v-if="item.other.type=='task' && taskid == 0" class="log-text-link" @click="taskDetail(item.other.id)">{{item.other.title}}</span>
+                                    <span v-if="item.other.type=='username'" class="log-text-link" @click="openChat(item.other.username)"><UserView :username="item.other.username"/></span>
                                     <a v-if="item.other.type=='file'" class="log-text-link" target="_blank" :href="fileDownUrl(item.other.id)">{{item.other.name}}</a>
                                     <span class="log-text-info">{{item.timeData.ymd}} {{item.timeData.segment}} {{item.timeData.hi}}</span></div>
                             </TimelineItem>
@@ -201,7 +202,7 @@
                 if (noLoading !== true) {
                     this.loadIng++;
                 }
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/log/lists',
                     data: {
                         projectid: this.projectid,
@@ -256,8 +257,14 @@
                 this.getLists();
             },
 
+            openChat(username) {
+                if (typeof window.onChatOpenUserName === "function") {
+                    window.onChatOpenUserName(username);
+                }
+            },
+
             fileDownUrl(id) {
-                return $A.aUrl('project/files/download?fileid=' + id);
+                return $A.apiUrl('project/files/download?fileid=' + id);
             }
         }
     }

+ 1 - 1
resources/assets/js/main/components/project/todo/attention.vue

@@ -183,7 +183,7 @@
                 }
                 this.loadIng++;
                 this.noDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/task/lists',
                     data: {
                         attention: 1,

+ 1 - 1
resources/assets/js/main/components/project/todo/calendar.vue

@@ -98,7 +98,7 @@
             getLists(page) {
                 this.lists = [];
                 this.loadIng++;
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/task/lists',
                     data: {
                         startdate: this.startdate,

+ 1 - 1
resources/assets/js/main/components/project/todo/complete.vue

@@ -166,7 +166,7 @@
                 }
                 this.loadIng++;
                 this.noDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/task/lists',
                     data: {
                         type: '已完成',

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

@@ -119,7 +119,7 @@
                                     content: this.$L('你确定要将此成员移出项目吗?'),
                                     loading: true,
                                     onOk: () => {
-                                        $A.aAjax({
+                                        $A.apiAjax({
                                             url: 'project/users/join',
                                             data: {
                                                 act: 'delete',
@@ -196,7 +196,7 @@
                 }
                 this.loadIng++;
                 this.noDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/users/lists',
                     data: {
                         page: Math.max(this.listPage, 1),
@@ -254,7 +254,7 @@
                     onOk: () => {
                         if (this.userValue) {
                             let username = this.userValue;
-                            $A.aAjax({
+                            $A.apiAjax({
                                 url: 'project/users/join',
                                 data: {
                                     act: 'join',

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

@@ -128,7 +128,7 @@
         methods: {
             getData() {
                 this.loadIng++;
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'report/template?id=' + this.id + '&type=' + this.type,
                     complete: () => {
                         this.loadIng--;
@@ -143,7 +143,7 @@
 
             handleSubmit(send = false) {
                 this.loadIng++;
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'report/template?act=submit&id=' + this.id + '&type=' + this.type + '&send=' + (send === true ? 1 : 0),
                     method: 'post',
                     data: {

+ 1 - 1
resources/assets/js/main/components/report/detail/detail.vue

@@ -43,7 +43,7 @@
                 this.contentShow = true;
                 this.contentTitle = this.reporttitle;
                 this.contentText = this.$L('详细内容加载中.....');
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'report/content?id=' + this.reportid,
                     error: () => {
                         alert(this.$L('网络繁忙,请稍后再试!'));

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

@@ -224,7 +224,7 @@
                 whereData.sorts = $A.cloneData(this.sorts);
                 this.loadIng++;
                 this.noDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'report/my',
                     data: whereData,
                     complete: () => {
@@ -258,7 +258,7 @@
                     content: this.$L('你确定要发送汇报吗?'),
                     loading: true,
                     onOk: () => {
-                        $A.aAjax({
+                        $A.apiAjax({
                             url: 'report/template?act=send&id=' + row.id + '&type=' + row.type,
                             error: () => {
                                 this.$Modal.remove();
@@ -305,7 +305,7 @@
                     content: this.$L('你确定要删除汇报吗?'),
                     loading: true,
                     onOk: () => {
-                        $A.aAjax({
+                        $A.apiAjax({
                             url: 'report/template?act=delete&id=' + row.id + '&type=' + row.type,
                             error: () => {
                                 this.$Modal.remove();

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

@@ -191,7 +191,7 @@
                 whereData.sorts = $A.cloneData(this.sorts);
                 this.loadIng++;
                 this.noDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'report/receive',
                     data: whereData,
                     complete: () => {

+ 13 - 10
resources/assets/js/main/main.js

@@ -22,7 +22,11 @@ import '../../sass/main.scss';
             return window.location.origin + '/' + str;
         },
 
-        aUrl(str) {
+        webUrl(str) {
+            return $A.fillUrl(str || '');
+        },
+
+        apiUrl(str) {
             if (str.substring(0, 2) === "//" ||
                 str.substring(0, 7) === "http://" ||
                 str.substring(0, 8) === "https://" ||
@@ -33,10 +37,10 @@ import '../../sass/main.scss';
             return apiUrl + str;
         },
 
-        aAjax(params) {
+        apiAjax(params) {
             if (typeof params !== 'object') return false;
             if (typeof params.success === 'undefined') params.success = () => { };
-            params.url = this.aUrl(params.url);
+            params.url = this.apiUrl(params.url);
             //
             let beforeCall = params.beforeSend;
             params.beforeSend = () => {
@@ -69,7 +73,6 @@ import '../../sass/main.scss';
                             title: '温馨提示',
                             content: data.msg,
                             onOk: () => {
-                                $A.token("");
                                 $A.userLogout();
                             }
                         });
@@ -157,10 +160,10 @@ import '../../sass/main.scss';
                     }
                 }
                 //
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'users/info',
                     error: () => {
-                        this.userLogout();
+                        $A.userLogout();
                     },
                     success: (res) => {
                         if (res.ret === 1) {
@@ -229,7 +232,7 @@ import '../../sass/main.scss';
                 }
             });
             //
-            $A.aAjax({
+            $A.apiAjax({
                 url: 'users/basic',
                 data: {
                     username: $A.jsonStringify(userArray),
@@ -299,9 +302,9 @@ import '../../sass/main.scss';
             $A.storage("userInfo", {});
             $A.triggerUserInfoListener({});
             if (typeof $A.app === "object") {
-                $A.app.goForward({path: '/'}, true);
+                $A.app.goForward({path: '/', query:{from:encodeURIComponent(window.location.href)}}, true);
             } else {
-                window.location.href = window.location.origin;
+                window.location.replace($A.webUrl() + '?from=' + encodeURIComponent(window.location.href));
             }
         },
 
@@ -403,7 +406,7 @@ import '../../sass/main.scss';
          * @param taskid
          */
         triggerTaskInfoChange(taskid) {
-            $A.aAjax({
+            $A.apiAjax({
                 url: 'project/task/pushlog',
                 data: {
                     taskid: taskid,

+ 3 - 3
resources/assets/js/main/mixins/project.js

@@ -10,7 +10,7 @@ export default {
                 content: this.$L('你确定要退出此项目吗?'),
                 loading: true,
                 onOk: () => {
-                    $A.aAjax({
+                    $A.apiAjax({
                         url: 'project/out?projectid=' + projectid,
                         error: () => {
                             this.$Modal.remove();
@@ -33,7 +33,7 @@ export default {
         },
 
         favorProject(act, projectid, successCallback) {
-            $A.aAjax({
+            $A.apiAjax({
                 url: 'project/favor',
                 data: {
                     act: act,
@@ -63,7 +63,7 @@ export default {
                 content: this.$L('你确定要删除此项目吗?'),
                 loading: true,
                 onOk: () => {
-                    $A.aAjax({
+                    $A.apiAjax({
                         url: 'project/delete?projectid=' + projectid,
                         error: () => {
                             this.$Modal.remove();

+ 1 - 1
resources/assets/js/main/mixins/task.js

@@ -6,7 +6,7 @@ export default {
             }
             this.$set(taskDetail, 'loadIng', true);
             this.$set(taskDetail, 'complete', !!complete);
-            $A.aAjax({
+            $A.apiAjax({
                 url: 'project/task/edit',
                 data: {
                     act: complete ? 'complete' : 'unfinished',

+ 45 - 0
resources/assets/js/main/pages/404.vue

@@ -0,0 +1,45 @@
+<template>
+    <div class="page-404">
+        <div class="flex-center position-ref full-height">
+            <div class="code">404</div>
+            <div class="message">Not Found</div>
+        </div>
+    </div>
+</template>
+
+<style lang="scss" scoped>
+    .page-404 {
+        background-color: #fff;
+        color: #636b6f;
+        font-weight: 400;
+        height: 100vh;
+        margin: 0;
+
+        .full-height {
+            height: 100vh;
+        }
+
+        .flex-center {
+            align-items: center;
+            display: flex;
+            justify-content: center;
+        }
+
+        .position-ref {
+            position: relative;
+        }
+
+        .code {
+            border-right: 2px solid;
+            font-size: 26px;
+            padding: 0 15px 0 15px;
+            text-align: center;
+        }
+
+        .message {
+            font-size: 18px;
+            padding: 10px;
+            text-align: center;
+        }
+    }
+</style>

+ 8 - 8
resources/assets/js/main/pages/docs.vue

@@ -342,7 +342,7 @@
                 }
                 this.loadIng++;
                 this.bookNoDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'docs/book/lists',
                     data: {
                         page: Math.max(this.bookListPage, 1),
@@ -376,7 +376,7 @@
                 this.$refs.bookAdd.validate((valid) => {
                     if (valid) {
                         this.loadIng++;
-                        $A.aAjax({
+                        $A.apiAjax({
                             url: 'docs/book/add',
                             data: Object.assign(this.formBookAdd, {id:this.addBookId}),
                             complete: () => {
@@ -415,7 +415,7 @@
                     content: this.$L('你确定要删除此知识库吗?'),
                     loading: true,
                     onOk: () => {
-                        $A.aAjax({
+                        $A.apiAjax({
                             url: 'docs/book/delete',
                             data: {
                                 id: bookId
@@ -455,7 +455,7 @@
                 let bookid = this.selectBookData.id;
                 this.loadIng++;
                 this.sectionNoDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'docs/section/lists',
                     data: {
                         act: 'edit',
@@ -490,7 +490,7 @@
                     if (valid) {
                         this.loadIng++;
                         let bookid = this.selectBookData.id;
-                        $A.aAjax({
+                        $A.apiAjax({
                             url: 'docs/section/add',
                             data: Object.assign(this.formSectionAdd, {
                                 id: this.addSectionId,
@@ -524,7 +524,7 @@
                     content: this.$L('你确定要删除此文档吗?'),
                     loading: true,
                     onOk: () => {
-                        $A.aAjax({
+                        $A.apiAjax({
                             url: 'docs/section/delete',
                             data: {
                                 id: sectionId
@@ -572,7 +572,7 @@
 
                     case 'sort':
                         this.sortDisabled = true;
-                        $A.aAjax({
+                        $A.apiAjax({
                             url: 'docs/section/sort',
                             data: {
                                 bookid: this.selectBookData.id,
@@ -611,7 +611,7 @@
                             }, this.$L('文档链接')),
                             h('Input', {
                                 props: {
-                                    value: $A.fillUrl('#/docs/view/b' + this.selectBookData.id),
+                                    value: $A.webUrl('docs/view/b' + this.selectBookData.id),
                                     readonly: true,
                                 },
                             })

+ 12 - 13
resources/assets/js/main/pages/docs/edit.vue

@@ -493,7 +493,7 @@
         watch: {
             sid(val) {
                 if (!val) {
-                    this.goBack();
+                    this.goBack({name:'docs'});
                     return;
                 }
                 this.hid = $A.runNum($A.strExists(val, '-') ? $A.getMiddle(val, "-", null) : 0);
@@ -506,7 +506,7 @@
                         if (!this.sectionNoDataText) {
                             this.sectionNoDataText = this.$L("数据加载中.....");
                             let bookid = this.docDetail.bookid;
-                            $A.aAjax({
+                            $A.apiAjax({
                                 url: 'docs/section/lists',
                                 data: {
                                     act: 'edit',
@@ -538,7 +538,7 @@
                         if (!this.historyNoDataText) {
                             this.historyNoDataText = this.$L("数据加载中.....");
                             let sid = this.getSid();
-                            $A.aAjax({
+                            $A.apiAjax({
                                 url: 'docs/section/history',
                                 data: {
                                     id: sid,
@@ -639,7 +639,7 @@
 
             getDetail() {
                 this.loadIng++;
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'docs/section/content',
                     data: {
                         act: 'edit',
@@ -649,7 +649,7 @@
                         this.loadIng--;
                     },
                     error: () => {
-                        this.goBack();
+                        this.goBack({name:'docs'});
                         alert(this.$L('网络繁忙,请稍后再试!'));
                     },
                     success: (res) => {
@@ -660,7 +660,6 @@
                             this.continueLock(1000);
                         } else {
                             this.$Modal.error({title: this.$L('温馨提示'), content: res.msg});
-                            this.goBack();
                         }
                     }
                 });
@@ -687,7 +686,7 @@
                 switch (act) {
                     case "back":
                         if (this.bakContent == $A.jsonStringify(this.docContent) && this.hid == 0) {
-                            this.goBack();
+                            this.goBack({name:'docs'});
                             return;
                         }
                         this.$Modal.confirm({
@@ -696,12 +695,12 @@
                             loading: true,
                             cancelText: this.$L('放弃保存'),
                             onCancel: () => {
-                                this.goBack();
+                                this.goBack({name:'docs'});
                             },
                             okText: this.$L('保存并返回'),
                             onOk: () => {
                                 this.bakContent = $A.jsonStringify(this.docContent);
-                                $A.aAjax({
+                                $A.apiAjax({
                                     url: 'docs/section/save?id=' + this.getSid(),
                                     method: 'post',
                                     data: {
@@ -713,7 +712,7 @@
                                     },
                                     success: (res) => {
                                         this.$Modal.remove();
-                                        this.goBack();
+                                        this.goBack({name:'docs'});
                                         setTimeout(() => {
                                             if (res.ret === 1) {
                                                 this.$Message.success(res.msg);
@@ -730,7 +729,7 @@
 
                     case "save":
                         this.bakContent = $A.jsonStringify(this.docContent);
-                        $A.aAjax({
+                        $A.apiAjax({
                             url: 'docs/section/save?id=' + this.getSid(),
                             method: 'post',
                             data: {
@@ -781,7 +780,7 @@
 
                     case "lock":
                     case "unlock":
-                        $A.aAjax({
+                        $A.apiAjax({
                             url: 'docs/section/lock?id=' + this.getSid(),
                             data: {
                                 act: act,
@@ -805,7 +804,7 @@
                         break;
 
                     case "view":
-                        return $A.fillUrl('#/docs/view/' + this.docDetail.id);
+                        return $A.webUrl('docs/view/' + this.docDetail.id);
 
                 }
             },

+ 2 - 2
resources/assets/js/main/pages/docs/view.vue

@@ -247,7 +247,7 @@
 
             getDetail() {
                 this.loadIng++;
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'docs/section/content',
                     data: {
                         act: 'view',
@@ -282,7 +282,7 @@
             getSectionMenu() {
                 this.sectionNoDataText = this.$L("数据加载中.....");
                 let bookid = this.docDetail.bookid;
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'docs/section/lists',
                     data: {
                         act: 'view',

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

@@ -422,7 +422,7 @@
         },
         methods: {
             getSetting() {
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'system/setting',
                     error: () => {
                         $A.storage("systemSetting", {});
@@ -452,7 +452,7 @@
                     if (valid) {
                         this.loadIng++;
                         $A.ajax({
-                            url: $A.urlApi('users/login?type=' + this.loginType),
+                            url: $A.apiUrl('users/login?type=' + this.loginType),
                             data: this.formLogin,
                             complete: () => {
                                 this.loadIng--;

+ 4 - 4
resources/assets/js/main/pages/project.vue

@@ -403,7 +403,7 @@
                     this.listPage = 1;
                 }
                 this.loadIng++;
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/lists',
                     data: {
                         page: Math.max(this.listPage, 1),
@@ -467,7 +467,7 @@
                 this.$refs.add.validate((valid) => {
                     if (valid) {
                         this.loadIng++;
-                        $A.aAjax({
+                        $A.apiAjax({
                             url: 'project/add',
                             data: this.formAdd,
                             complete: () => {
@@ -580,7 +580,7 @@
                         if (this.renameValue) {
                             this.$set(item, 'loadIng', true);
                             let title = this.renameValue;
-                            $A.aAjax({
+                            $A.apiAjax({
                                 url: 'project/rename',
                                 data: {
                                     projectid: item.id,
@@ -643,7 +643,7 @@
                         if (this.transferValue) {
                             this.$set(item, 'loadIng', true);
                             let username = this.transferValue;
-                            $A.aAjax({
+                            $A.apiAjax({
                                 url: 'project/transfer',
                                 data: {
                                     projectid: item.id,

+ 8 - 11
resources/assets/js/main/pages/project/panel.vue

@@ -24,14 +24,13 @@
 
         <w-content>
             <draggable
-                v-if="projectLabel.length > 0"
                 v-model="projectLabel"
                 class="label-box"
                 draggable=".label-draggable"
                 :animation="150"
                 :disabled="projectSortDisabled"
                 @sort="projectSortUpdate(true)">
-                <div v-for="label in projectLabel" :key="label.id" class="label-item label-draggable">
+                <div v-if="projectLabel.length > 0" v-for="label in projectLabel" :key="label.id" class="label-item label-draggable">
                     <div class="label-body">
                         <div class="title-box">
                             <div v-if="label.loadIng === true" class="title-loading">
@@ -423,7 +422,6 @@
         watch: {
             projectid(val) {
                 if ($A.runNum(val) <= 0) {
-                    this.goBack();
                     return;
                 }
                 this.projectDetail = {};
@@ -435,7 +433,7 @@
         methods: {
             getDetail(successTip) {
                 this.loadIng++;
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/detail',
                     data: {
                         projectid: this.projectid,
@@ -445,7 +443,7 @@
                         this.loadDetailed = true;
                     },
                     error: () => {
-                        this.goBack();
+                        this.goBack({name:'project'});
                         alert(this.$L('网络繁忙,请稍后再试!'));
                     },
                     success: (res) => {
@@ -459,7 +457,6 @@
                             }
                         } else {
                             this.$Modal.error({title: this.$L('温馨提示'), content: res.msg});
-                            this.goBack();
                         }
                     }
                 });
@@ -497,7 +494,7 @@
 
             refreshLabel(item) {
                 this.$set(item, 'loadIng', true);
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/task/lists',
                     data: {
                         projectid: this.projectid,
@@ -550,7 +547,7 @@
                         if (this.renameValue) {
                             this.$set(item, 'loadIng', true);
                             let title = this.renameValue;
-                            $A.aAjax({
+                            $A.apiAjax({
                                 url: 'project/label/rename',
                                 data: {
                                     projectid: this.projectid,
@@ -590,7 +587,7 @@
                     content: '<div>' + this.$L('你确定要删除此列表吗?') + '</div>' + redTip,
                     loading: true,
                     onOk: () => {
-                        $A.aAjax({
+                        $A.apiAjax({
                             url: 'project/label/delete',
                             data: {
                                 projectid: this.projectid,
@@ -652,7 +649,7 @@
                     loading: true,
                     onOk: () => {
                         if (this.labelValue) {
-                            $A.aAjax({
+                            $A.apiAjax({
                                 url: 'project/label/add',
                                 data: {
                                     projectid: this.projectid,
@@ -713,7 +710,7 @@
                 this.projectSortData = newSort;
                 this.projectSortDisabled = true;
                 this.loadIng++;
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/sort',
                     data: {
                         projectid: this.projectid,

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

@@ -291,7 +291,7 @@
                 }
                 this.loadIng++;
                 this.noDataText = this.$L("数据加载中.....");
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'users/team/lists',
                     data: {
                         page: Math.max(this.listPage, 1),
@@ -321,7 +321,7 @@
                 this.$refs.add.validate((valid) => {
                     if (valid) {
                         this.loadIng++;
-                        $A.aAjax({
+                        $A.apiAjax({
                             url: 'users/team/add',
                             data: this.formAdd,
                             complete: () => {
@@ -351,7 +351,7 @@
                             content: this.$L('你确定要删除此团队成员吗?'),
                             loading: true,
                             onOk: () => {
-                                $A.aAjax({
+                                $A.apiAjax({
                                     url: 'users/team/delete?username=' + username,
                                     error: () => {
                                         this.$Modal.remove();
@@ -380,7 +380,7 @@
                             content: this.$L(act=='deladmin' ? '你确定取消管理员身份的操作吗?' : '你确定设置管理员的操作吗?'),
                             loading: true,
                             onOk: () => {
-                                $A.aAjax({
+                                $A.apiAjax({
                                     url: 'users/team/admin?act=' + (act=='deladmin'?'del':'set') + '&username=' + username,
                                     error: () => {
                                         this.$Modal.remove();

+ 3 - 3
resources/assets/js/main/pages/todo.vue

@@ -537,7 +537,7 @@
                 this.$set(taskData, 'loadIng', $A.runNum(taskData.loadIng) + 1);
                 this.taskSortDisabled = true;
                 this.loadIng++;
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/task/lists',
                     data: {
                         level: index,
@@ -595,7 +595,7 @@
                     loadIng: true,
                 });
                 this.taskSortDisabled = true;
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/task/add',
                     data: {
                         title: title,
@@ -673,7 +673,7 @@
                 }
                 this.taskSortData = newSort;
                 this.taskSortDisabled = true;
-                $A.aAjax({
+                $A.apiAjax({
                     url: 'project/sort/todo',
                     data: {
                         oldsort: oldSort,

+ 4 - 0
resources/assets/js/main/routes.js

@@ -38,5 +38,9 @@ export default [
         name: 'team',
         meta: { slide: false, tabActive: 'team' },
         component: resolve => require(['./pages/team.vue'], resolve)
+    }, {
+        path: '*',
+        name: '404',
+        component: resolve => require(['./pages/404.vue'], resolve)
     }
 ]

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

@@ -448,4 +448,11 @@ export default {
     "分享": "Share",
     "文档设置": "Setting",
     "文档成员": "Members",
+    "仅作者可以修改。": "Only the author may modify it.",
+    "仅作者和文档成员可以修改。": "Only authors and document members can be modified.",
+    "所有会员都可以修改。": "All members can modify it.",
+    "仅作者可以阅读分享地址。": "Only the author can read the Shared address.",
+    "仅作者和文档成员可以阅读分享地址。": "Only authors and document members can read the Shared address.",
+    "所有会员都可以阅读分享地址。": "All members can read the Shared address.",
+    "所有人(含游客)都可以阅读分享地址。": "Everyone (including visitors) can read the Shared address.",
 }