From 67aa157d10beb1089051da256073afff9a37d641 Mon Sep 17 00:00:00 2001 From: lishuang Date: Sat, 13 May 2023 12:38:12 +0800 Subject: [PATCH] style: reformat the codes. --- .editorconfig | 15 - ide-editor-config.xml | 1 + src/App.tsx | 14 +- src/assets/css/bootstrap/variables.less | 760 +++++----- src/assets/css/global/button.less | 52 +- src/assets/css/global/color.less | 464 ++++-- src/assets/css/global/font.less | 42 +- src/assets/css/global/miscellaneous.less | 1 + src/assets/image/empty.svg | 21 +- src/assets/image/file/alien.svg | 11 +- src/assets/image/file/archive.svg | 15 +- src/assets/image/file/audio.svg | 15 +- src/assets/image/file/doc.svg | 13 +- src/assets/image/file/file.svg | 20 +- src/assets/image/file/folder.svg | 11 +- src/assets/image/file/image.svg | 17 +- src/assets/image/file/pdf.svg | 14 +- src/assets/image/file/ppt.svg | 19 +- src/assets/image/file/psd.svg | 17 +- src/assets/image/file/text.svg | 11 +- src/assets/image/file/video.svg | 24 +- src/assets/image/file/xls.svg | 18 +- src/assets/image/success.svg | 12 +- src/common/component/TankComponent.tsx | 48 +- src/common/menu/MenuItem.ts | 30 +- src/common/menu/MenuManager.tsx | 153 +- src/common/model/base/Base.ts | 218 +-- src/common/model/base/BaseEntity.ts | 342 ++--- src/common/model/base/HttpBase.ts | 456 +++--- src/common/model/base/Pager.ts | 710 ++++----- src/common/model/base/SortDirection.ts | 12 +- src/common/model/base/ViewBase.ts | 28 +- src/common/model/base/WebResultCode.ts | 82 +- src/common/model/base/filter/CheckFilter.ts | 66 +- src/common/model/base/filter/DateFilter.ts | 57 +- .../model/base/filter/DateTimeFilter.ts | 57 +- src/common/model/base/filter/Filter.ts | 82 +- .../model/base/filter/HttpSelectionFilter.ts | 32 +- src/common/model/base/filter/InputFilter.ts | 50 +- .../model/base/filter/SelectionFilter.ts | 88 +- .../model/base/filter/SelectionFilterType.ts | 8 +- src/common/model/base/filter/SortFilter.ts | 84 +- .../model/base/option/BreadcrumbModel.ts | 8 +- .../model/base/option/CodeSelectionOption.ts | 4 +- src/common/model/base/option/Color.ts | 10 +- .../base/option/ColorIndexSelectionOption.ts | 4 +- .../model/base/option/ColorSelectionOption.ts | 2 +- .../base/option/IconIndexSelectionOption.ts | 4 +- .../model/base/option/IndexSelectionOption.ts | 6 +- .../model/base/option/SelectionOption.ts | 4 +- .../model/base/option/StyleSelectionOption.ts | 2 +- src/common/model/base/types/index.d.ts | 44 +- src/common/model/dashboard/Dashboard.ts | 79 +- .../model/download/token/DownloadToken.ts | 78 +- src/common/model/global/Lang.ts | 102 +- src/common/model/global/Moon.ts | 27 +- src/common/model/global/Sun.ts | 131 +- src/common/model/global/i18n/LangEn.ts | 740 +++++----- src/common/model/global/i18n/LangZh.ts | 742 +++++----- src/common/model/image/cache/ImageCache.ts | 102 +- src/common/model/install/Install.ts | 390 ++--- src/common/model/install/InstallFieldInfo.ts | 12 +- src/common/model/install/InstallTableInfo.ts | 18 +- src/common/model/matter/Matter.ts | 1059 +++++++------- src/common/model/preference/Preference.ts | 232 +-- .../model/preference/model/PreviewConfig.ts | 40 +- .../model/preference/model/PreviewEngine.ts | 144 +- .../model/preference/model/ScanConfig.ts | 56 +- .../model/preference/model/ScanCronType.ts | 58 +- .../model/preference/model/ScanScopeType.ts | 26 +- src/common/model/share/Share.ts | 302 ++-- src/common/model/share/ShareExpireOption.ts | 82 +- src/common/model/share/ShareType.ts | 36 +- src/common/model/user/User.ts | 368 ++--- src/common/model/user/UserRole.ts | 38 +- src/common/model/user/UserStatus.ts | 26 +- src/common/types/index.d.ts | 44 +- src/common/util/AnimateUtil.ts | 160 +- src/common/util/AntdUtil.ts | 56 +- src/common/util/ArrayUtil.ts | 252 ++-- src/common/util/BrowserUtil.ts | 200 +-- src/common/util/ClipboardUtil.ts | 56 +- src/common/util/DateUtil.ts | 149 +- src/common/util/DomUtil.ts | 24 +- src/common/util/EnvUtil.ts | 2 +- src/common/util/FileUtil.tsx | 274 ++-- src/common/util/HttpUtil.ts | 148 +- src/common/util/ImageUtil.ts | 116 +- src/common/util/JsonUtil.ts | 94 +- src/common/util/MessageBoxUtil.ts | 30 +- src/common/util/MimeUtil.ts | 1302 ++++++++--------- src/common/util/NumberUtil.ts | 68 +- src/common/util/ObjectUtil.ts | 178 +-- src/common/util/SafeUtil.ts | 66 +- src/common/util/StringUtil.ts | 466 +++--- src/index.tsx | 4 +- src/pages/Frame.less | 3 - src/pages/Frame.tsx | 287 ++-- src/pages/bin/List.tsx | 516 +++---- src/pages/dashboard/Index.tsx | 759 +++++----- src/pages/dashboard/theme.json | 940 ++++++------ src/pages/dashboard/widget/RatePanel.less | 2 + src/pages/dashboard/widget/RatePanel.tsx | 104 +- src/pages/install/Index.tsx | 113 +- src/pages/install/widget/CreateTablePanel.tsx | 375 ++--- src/pages/install/widget/FinishPanel.tsx | 80 +- src/pages/install/widget/MysqlPanel.tsx | 398 ++--- src/pages/install/widget/SetAdminPanel.tsx | 166 +-- .../install/widget/inner/PhaseCreatePanel.tsx | 200 +-- .../widget/inner/PhaseSelectingPanel.tsx | 168 +-- .../install/widget/inner/PhaseVerifyPanel.tsx | 154 +- src/pages/layout/BottomLayout.tsx | 62 +- src/pages/layout/ContentLayout.tsx | 28 +- src/pages/layout/SideLayout.less | 98 +- src/pages/layout/SideLayout.tsx | 20 +- src/pages/layout/TopLayout.tsx | 100 +- src/pages/layout/widget/AboutModal.tsx | 90 +- src/pages/layout/widget/Capacity.less | 19 +- src/pages/layout/widget/Capacity.tsx | 12 +- src/pages/matter/Detail.tsx | 234 +-- src/pages/matter/List.less | 2 + src/pages/matter/List.tsx | 1277 ++++++++-------- src/pages/matter/widget/Director.ts | 12 +- src/pages/matter/widget/MatterDeleteModal.tsx | 121 +- src/pages/matter/widget/MatterImage.less | 5 + src/pages/matter/widget/MatterImage.tsx | 213 ++- src/pages/matter/widget/MatterPanel.tsx | 1019 ++++++------- src/pages/matter/widget/MatterSortPanel.less | 3 + src/pages/matter/widget/MatterSortPanel.tsx | 126 +- src/pages/matter/widget/MoveBatchModal.less | 6 + src/pages/matter/widget/MoveBatchModal.tsx | 224 +-- .../matter/widget/ShareOperationModal.less | 1 + .../matter/widget/ShareOperationModal.tsx | 144 +- .../matter/widget/UploadMatterPanel.less | 1 + src/pages/matter/widget/UploadMatterPanel.tsx | 113 +- .../widget/imageCache/ImageCacheList.tsx | 270 ++-- .../widget/imageCache/ImageCachePanel.less | 9 + .../widget/imageCache/ImageCachePanel.tsx | 221 ++- src/pages/preference/Edit.tsx | 350 ++--- src/pages/preference/Index.less | 1 + src/pages/preference/Index.tsx | 405 +++-- src/pages/preference/PreviewEngineEdit.tsx | 116 +- src/pages/preference/ScanEdit.tsx | 363 +++-- .../preference/widget/PreviewConfigPanel.tsx | 95 +- .../preference/widget/PreviewEngineCell.less | 2 + .../preference/widget/PreviewEngineCell.tsx | 80 +- .../widget/PreviewEngineEditCell.tsx | 188 +-- src/pages/share/Detail.tsx | 476 +++--- src/pages/share/List.tsx | 76 +- src/pages/share/widget/ShareBar.less | 1 + src/pages/share/widget/ShareBar.tsx | 236 ++- src/pages/share/widget/ShareDialogModal.less | 1 + src/pages/share/widget/ShareDialogModal.tsx | 161 +- src/pages/share/widget/ShareMatterPanel.less | 8 +- src/pages/share/widget/ShareMatterPanel.tsx | 227 ++- src/pages/user/Authentication.tsx | 49 +- src/pages/user/Detail.less | 1 + src/pages/user/Detail.tsx | 398 +++-- src/pages/user/Edit.tsx | 390 ++--- src/pages/user/List.tsx | 493 +++---- src/pages/user/Login.tsx | 166 +-- src/pages/user/MobileList.tsx | 228 +-- src/pages/user/Register.tsx | 185 +-- src/pages/user/widget/ChangePasswordModal.tsx | 227 ++- src/pages/user/widget/MobileUserPanel.less | 4 + src/pages/user/widget/MobileUserPanel.tsx | 248 ++-- .../user/widget/TransfigurationModal.tsx | 123 +- src/pages/widget/BreadcrumbPanel.tsx | 72 +- src/pages/widget/ChangeNumModal.tsx | 108 +- src/pages/widget/Expanding.tsx | 28 +- src/pages/widget/FrameLoading.tsx | 38 +- src/pages/widget/InfoCell.less | 1 + src/pages/widget/InfoCell.tsx | 63 +- src/pages/widget/SingleTextModal.tsx | 152 +- src/pages/widget/StringsPicker.tsx | 301 ++-- src/pages/widget/TableEmpty.tsx | 72 +- src/pages/widget/TankContentCard.tsx | 66 +- src/pages/widget/TankTitle.tsx | 27 +- src/pages/widget/filter/CheckFilterBox.tsx | 50 +- src/pages/widget/filter/DateFilterBox.tsx | 84 +- src/pages/widget/filter/DateTimeFilterBox.tsx | 84 +- src/pages/widget/filter/FilterPanel.tsx | 264 ++-- .../widget/filter/HttpSelectionFilterBox.tsx | 120 +- src/pages/widget/filter/InputFilterBox.tsx | 52 +- .../widget/filter/SelectionFilterBox.tsx | 88 +- src/pages/widget/filter/SortFilterBox.tsx | 46 +- .../widget/previewer/BrowserPreviewer.tsx | 106 +- src/pages/widget/previewer/ImagePreviewer.tsx | 3 +- src/pages/widget/previewer/PreviewerHelper.ts | 204 +-- src/react-app-env.d.ts | 14 +- 190 files changed, 14696 insertions(+), 14195 deletions(-) delete mode 100644 .editorconfig create mode 100644 ide-editor-config.xml diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index ee08663..0000000 --- a/.editorconfig +++ /dev/null @@ -1,15 +0,0 @@ -root = true - -[*] -charset = utf-8 -indent_style = space -indent_size = 2 -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true - -[*.{js,jsx,ts,tsx,vue}] -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true diff --git a/ide-editor-config.xml b/ide-editor-config.xml new file mode 100644 index 0000000..89564f2 --- /dev/null +++ b/ide-editor-config.xml @@ -0,0 +1 @@ + diff --git a/src/App.tsx b/src/App.tsx index 9deeac4..d124232 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,13 +8,13 @@ import en_US from 'antd/es/locale/en_US'; import './App.less'; function App() { - return ( - - - - - - ); + return ( + + + + + + ); } export default App; diff --git a/src/assets/css/bootstrap/variables.less b/src/assets/css/bootstrap/variables.less index f7f9dff..2bc8479 100644 --- a/src/assets/css/bootstrap/variables.less +++ b/src/assets/css/bootstrap/variables.less @@ -7,18 +7,18 @@ // //## Gray and brand colors for use across Bootstrap. -@gray-base: #000; -@gray-darker: lighten(@gray-base, 13.5%); // #222 -@gray-dark: lighten(@gray-base, 20%); // #333 -@gray: lighten(@gray-base, 33.5%); // #555 -@gray-light: lighten(@gray-base, 46.7%); // #777 -@gray-lighter: lighten(@gray-base, 93.5%); // #eee +@gray-base: #000; +@gray-darker: lighten(@gray-base, 13.5%); // #222 +@gray-dark: lighten(@gray-base, 20%); // #333 +@gray: lighten(@gray-base, 33.5%); // #555 +@gray-light: lighten(@gray-base, 46.7%); // #777 +@gray-lighter: lighten(@gray-base, 93.5%); // #eee -@brand-primary: darken(#428bca, 6.5%); // #337ab7 -@brand-success: #5cb85c; -@brand-info: #5bc0de; -@brand-warning: #f0ad4e; -@brand-danger: #d9534f; +@brand-primary: darken(#428bca, 6.5%); // #337ab7 +@brand-success: #5cb85c; +@brand-info: #5bc0de; +@brand-warning: #f0ad4e; +@brand-danger: #d9534f; //== Scaffolding @@ -26,14 +26,14 @@ //## Settings for some of the most global styles. //** Background color for ``. -@body-bg: #fff; +@body-bg: #fff; //** Global text color on ``. -@text-color: @gray-dark; +@text-color: @gray-dark; //** Global textual link color. -@link-color: @brand-primary; +@link-color: @brand-primary; //** Link hover color set via `darken()` function. -@link-hover-color: darken(@link-color, 15%); +@link-hover-color: darken(@link-color, 15%); //** Link hover decoration. @link-hover-decoration: underline; @@ -42,33 +42,33 @@ // //## Font, line-height, and color for body text, headings, and more. -@font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif; -@font-family-serif: Georgia, "Times New Roman", Times, serif; +@font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif; +@font-family-serif: Georgia, "Times New Roman", Times, serif; //** Default monospace fonts for ``, ``, and `
`.
-@font-family-monospace:   Menlo, Monaco, Consolas, "Courier New", monospace;
-@font-family-base:        @font-family-sans-serif;
+@font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace;
+@font-family-base: @font-family-sans-serif;
 
-@font-size-base:          14px;
-@font-size-large:         ceil((@font-size-base * 1.25)); // ~18px
-@font-size-small:         ceil((@font-size-base * 0.85)); // ~12px
+@font-size-base: 14px;
+@font-size-large: ceil((@font-size-base * 1.25)); // ~18px
+@font-size-small: ceil((@font-size-base * 0.85)); // ~12px
 
-@font-size-h1:            floor((@font-size-base * 2.6)); // ~36px
-@font-size-h2:            floor((@font-size-base * 2.15)); // ~30px
-@font-size-h3:            ceil((@font-size-base * 1.7)); // ~24px
-@font-size-h4:            ceil((@font-size-base * 1.25)); // ~18px
-@font-size-h5:            @font-size-base;
-@font-size-h6:            ceil((@font-size-base * 0.85)); // ~12px
+@font-size-h1: floor((@font-size-base * 2.6)); // ~36px
+@font-size-h2: floor((@font-size-base * 2.15)); // ~30px
+@font-size-h3: ceil((@font-size-base * 1.7)); // ~24px
+@font-size-h4: ceil((@font-size-base * 1.25)); // ~18px
+@font-size-h5: @font-size-base;
+@font-size-h6: ceil((@font-size-base * 0.85)); // ~12px
 
 //** Unit-less `line-height` for use in components like buttons.
-@line-height-base:        1.428571429; // 20/14
+@line-height-base: 1.428571429; // 20/14
 //** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.
-@line-height-computed:    floor((@font-size-base * @line-height-base)); // ~20px
+@line-height-computed: floor((@font-size-base * @line-height-base)); // ~20px
 
 //** By default, this inherits from the ``.
-@headings-font-family:    inherit;
-@headings-font-weight:    500;
-@headings-line-height:    1.1;
-@headings-color:          inherit;
+@headings-font-family: inherit;
+@headings-font-weight: 500;
+@headings-line-height: 1.1;
+@headings-color: inherit;
 
 
 //== Iconography
@@ -76,45 +76,45 @@
 //## Specify custom location and filename of the included Glyphicons icon font. Useful for those including Bootstrap via Bower.
 
 //** Load fonts from this directory.
-@icon-font-path:          "../fonts/";
+@icon-font-path: "../fonts/";
 //** File name for all font files.
-@icon-font-name:          "glyphicons-halflings-regular";
+@icon-font-name: "glyphicons-halflings-regular";
 //** Element ID within SVG icon file.
-@icon-font-svg-id:        "glyphicons_halflingsregular";
+@icon-font-svg-id: "glyphicons_halflingsregular";
 
 
 //== Components
 //
 //## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
 
-@padding-base-vertical:     6px;
-@padding-base-horizontal:   12px;
+@padding-base-vertical: 6px;
+@padding-base-horizontal: 12px;
 
-@padding-large-vertical:    10px;
-@padding-large-horizontal:  16px;
+@padding-large-vertical: 10px;
+@padding-large-horizontal: 16px;
 
-@padding-small-vertical:    5px;
-@padding-small-horizontal:  10px;
+@padding-small-vertical: 5px;
+@padding-small-horizontal: 10px;
 
-@padding-xs-vertical:       1px;
-@padding-xs-horizontal:     5px;
+@padding-xs-vertical: 1px;
+@padding-xs-horizontal: 5px;
 
-@line-height-large:         1.3333333; // extra decimals for Win 8.1 Chrome
-@line-height-small:         1.5;
+@line-height-large: 1.3333333; // extra decimals for Win 8.1 Chrome
+@line-height-small: 1.5;
 
-@border-radius-base:        4px;
-@border-radius-large:       6px;
-@border-radius-small:       3px;
+@border-radius-base: 4px;
+@border-radius-large: 6px;
+@border-radius-small: 3px;
 
 //** Global color for active pendants (e.g., navs or dropdowns).
-@component-active-color:    #fff;
+@component-active-color: #fff;
 //** Global background color for active pendants (e.g., navs or dropdowns).
-@component-active-bg:       @brand-primary;
+@component-active-bg: @brand-primary;
 
 //** Width of the `border` for generating carets that indicate dropdowns.
-@caret-width-base:          4px;
+@caret-width-base: 4px;
 //** Carets increase slightly in size for larger components.
-@caret-width-large:         5px;
+@caret-width-large: 5px;
 
 
 //== Tables
@@ -122,58 +122,58 @@
 //## Customizes the `.table` component with basic values, each used across all table variations.
 
 //** Padding for ``s and ``s.
-@table-cell-padding:            8px;
+@table-cell-padding: 8px;
 //** Padding for cells in `.table-condensed`.
-@table-condensed-cell-padding:  5px;
+@table-condensed-cell-padding: 5px;
 
 //** Default background color used for all tables.
-@table-bg:                      transparent;
+@table-bg: transparent;
 //** Background color used for `.table-striped`.
-@table-bg-accent:               #f9f9f9;
+@table-bg-accent: #f9f9f9;
 //** Background color used for `.table-hover`.
-@table-bg-hover:                #f5f5f5;
-@table-bg-active:               @table-bg-hover;
+@table-bg-hover: #f5f5f5;
+@table-bg-active: @table-bg-hover;
 
 //** Border color for table and cell borders.
-@table-border-color:            #ddd;
+@table-border-color: #ddd;
 
 
 //== Buttons
 //
 //## For each of Bootstrap's buttons, define text, background and border color.
 
-@btn-font-weight:                normal;
+@btn-font-weight: normal;
 
-@btn-default-color:              #333;
-@btn-default-bg:                 #fff;
-@btn-default-border:             #ccc;
+@btn-default-color: #333;
+@btn-default-bg: #fff;
+@btn-default-border: #ccc;
 
-@btn-primary-color:              #fff;
-@btn-primary-bg:                 @brand-primary;
-@btn-primary-border:             darken(@btn-primary-bg, 5%);
+@btn-primary-color: #fff;
+@btn-primary-bg: @brand-primary;
+@btn-primary-border: darken(@btn-primary-bg, 5%);
 
-@btn-success-color:              #fff;
-@btn-success-bg:                 @brand-success;
-@btn-success-border:             darken(@btn-success-bg, 5%);
+@btn-success-color: #fff;
+@btn-success-bg: @brand-success;
+@btn-success-border: darken(@btn-success-bg, 5%);
 
-@btn-info-color:                 #fff;
-@btn-info-bg:                    @brand-info;
-@btn-info-border:                darken(@btn-info-bg, 5%);
+@btn-info-color: #fff;
+@btn-info-bg: @brand-info;
+@btn-info-border: darken(@btn-info-bg, 5%);
 
-@btn-warning-color:              #fff;
-@btn-warning-bg:                 @brand-warning;
-@btn-warning-border:             darken(@btn-warning-bg, 5%);
+@btn-warning-color: #fff;
+@btn-warning-bg: @brand-warning;
+@btn-warning-border: darken(@btn-warning-bg, 5%);
 
-@btn-danger-color:               #fff;
-@btn-danger-bg:                  @brand-danger;
-@btn-danger-border:              darken(@btn-danger-bg, 5%);
+@btn-danger-color: #fff;
+@btn-danger-bg: @brand-danger;
+@btn-danger-border: darken(@btn-danger-bg, 5%);
 
-@btn-link-disabled-color:        @gray-light;
+@btn-link-disabled-color: @gray-light;
 
 // Allows for customizing button radius independently from global border radius
-@btn-border-radius-base:         @border-radius-base;
-@btn-border-radius-large:        @border-radius-large;
-@btn-border-radius-small:        @border-radius-small;
+@btn-border-radius-base: @border-radius-base;
+@btn-border-radius-large: @border-radius-large;
+@btn-border-radius-small: @border-radius-small;
 
 
 //== Forms
@@ -181,49 +181,49 @@
 //##
 
 //** `` background color
-@input-bg:                       #fff;
+@input-bg: #fff;
 //** `` background color
-@input-bg-disabled:              @gray-lighter;
+@input-bg-disabled: @gray-lighter;
 
 //** Text color for ``s
-@input-color:                    @gray;
+@input-color: @gray;
 //** `` border color
-@input-border:                   #ccc;
+@input-border: #ccc;
 
 //** Default `.form-control` border radius
 // This has no effect on ``s in CSS.
-@input-border-radius:            @border-radius-base;
+@input-border-radius: @border-radius-base;
 //** Large `.form-control` border radius
-@input-border-radius-large:      @border-radius-large;
+@input-border-radius-large: @border-radius-large;
 //** Small `.form-control` border radius
-@input-border-radius-small:      @border-radius-small;
+@input-border-radius-small: @border-radius-small;
 
 //** Border color for inputs on focus
-@input-border-focus:             #66afe9;
+@input-border-focus: #66afe9;
 
 //** Placeholder text color
-@input-color-placeholder:        #999;
+@input-color-placeholder: #999;
 
 //** Default `.form-control` height
-@input-height-base:              (@line-height-computed + (@padding-base-vertical * 2) + 2);
+@input-height-base: (@line-height-computed + (@padding-base-vertical * 2) + 2);
 //** Large `.form-control` height
-@input-height-large:             (ceil(@font-size-large * @line-height-large) + (@padding-large-vertical * 2) + 2);
+@input-height-large: (ceil(@font-size-large * @line-height-large) + (@padding-large-vertical * 2) + 2);
 //** Small `.form-control` height
-@input-height-small:             (floor(@font-size-small * @line-height-small) + (@padding-small-vertical * 2) + 2);
+@input-height-small: (floor(@font-size-small * @line-height-small) + (@padding-small-vertical * 2) + 2);
 
 //** `.form-group` margin
-@form-group-margin-bottom:       15px;
+@form-group-margin-bottom: 15px;
 
-@legend-color:                   @gray-dark;
-@legend-border-color:            #e5e5e5;
+@legend-color: @gray-dark;
+@legend-border-color: #e5e5e5;
 
 //** Background color for textual input addons
-@input-group-addon-bg:           @gray-lighter;
+@input-group-addon-bg: @gray-lighter;
 //** Border color for textual input addons
 @input-group-addon-border-color: @input-border;
 
 //** Disabled cursor for form controls and buttons.
-@cursor-disabled:                not-allowed;
+@cursor-disabled: not-allowed;
 
 
 //== Dropdowns
@@ -231,34 +231,34 @@
 //## Dropdown menu container and contents.
 
 //** Background for the dropdown menu.
-@dropdown-bg:                    #fff;
+@dropdown-bg: #fff;
 //** Dropdown menu `border-color`.
-@dropdown-border:                rgba(0,0,0,.15);
+@dropdown-border: rgba(0, 0, 0, .15);
 //** Dropdown menu `border-color` **for IE8**.
-@dropdown-fallback-border:       #ccc;
+@dropdown-fallback-border: #ccc;
 //** Divider color for between dropdown pendants.
-@dropdown-divider-bg:            #e5e5e5;
+@dropdown-divider-bg: #e5e5e5;
 
 //** Dropdown link text color.
-@dropdown-link-color:            @gray-dark;
+@dropdown-link-color: @gray-dark;
 //** Hover color for dropdown links.
-@dropdown-link-hover-color:      darken(@gray-dark, 5%);
+@dropdown-link-hover-color: darken(@gray-dark, 5%);
 //** Hover background for dropdown links.
-@dropdown-link-hover-bg:         #f5f5f5;
+@dropdown-link-hover-bg: #f5f5f5;
 
 //** Active dropdown menu item text color.
-@dropdown-link-active-color:     @component-active-color;
+@dropdown-link-active-color: @component-active-color;
 //** Active dropdown menu item background color.
-@dropdown-link-active-bg:        @component-active-bg;
+@dropdown-link-active-bg: @component-active-bg;
 
 //** Disabled dropdown menu item background color.
-@dropdown-link-disabled-color:   @gray-light;
+@dropdown-link-disabled-color: @gray-light;
 
 //** Text color for headers within dropdown menus.
-@dropdown-header-color:          @gray-light;
+@dropdown-header-color: @gray-light;
 
 //** Deprecated `@dropdown-caret-color` as of v3.1.0
-@dropdown-caret-color:           #000;
+@dropdown-caret-color: #000;
 
 
 //-- Z-index master list
@@ -268,13 +268,13 @@
 //
 // Note: These variables are not generated into the Customizer.
 
-@zindex-navbar:            1000;
-@zindex-dropdown:          1000;
-@zindex-popover:           1060;
-@zindex-tooltip:           1070;
-@zindex-navbar-fixed:      1030;
-@zindex-modal-background:  1040;
-@zindex-modal:             1050;
+@zindex-navbar: 1000;
+@zindex-dropdown: 1000;
+@zindex-popover: 1060;
+@zindex-tooltip: 1070;
+@zindex-navbar-fixed: 1030;
+@zindex-modal-background: 1040;
+@zindex-modal: 1050;
 
 
 //== Media queries breakpoints
@@ -283,37 +283,37 @@
 
 // Extra small screen / phone
 //** Deprecated `@screen-xs` as of v3.0.1
-@screen-xs:                  480px;
+@screen-xs: 480px;
 //** Deprecated `@screen-xs-min` as of v3.2.0
-@screen-xs-min:              @screen-xs;
+@screen-xs-min: @screen-xs;
 //** Deprecated `@screen-phone` as of v3.0.1
-@screen-phone:               @screen-xs-min;
+@screen-phone: @screen-xs-min;
 
 // Small screen / tablet
 //** Deprecated `@screen-sm` as of v3.0.1
-@screen-sm:                  768px;
-@screen-sm-min:              @screen-sm;
+@screen-sm: 768px;
+@screen-sm-min: @screen-sm;
 //** Deprecated `@screen-tablet` as of v3.0.1
-@screen-tablet:              @screen-sm-min;
+@screen-tablet: @screen-sm-min;
 
 // Medium screen / desktop
 //** Deprecated `@screen-md` as of v3.0.1
-@screen-md:                  992px;
-@screen-md-min:              @screen-md;
+@screen-md: 992px;
+@screen-md-min: @screen-md;
 //** Deprecated `@screen-desktop` as of v3.0.1
-@screen-desktop:             @screen-md-min;
+@screen-desktop: @screen-md-min;
 
 // Large screen / wide desktop
 //** Deprecated `@screen-lg` as of v3.0.1
-@screen-lg:                  1200px;
-@screen-lg-min:              @screen-lg;
+@screen-lg: 1200px;
+@screen-lg-min: @screen-lg;
 //** Deprecated `@screen-lg-desktop` as of v3.0.1
-@screen-lg-desktop:          @screen-lg-min;
+@screen-lg-desktop: @screen-lg-min;
 
 // So media queries don't overlap when required, provide a maximum
-@screen-xs-max:              (@screen-sm-min - 1);
-@screen-sm-max:              (@screen-md-min - 1);
-@screen-md-max:              (@screen-lg-min - 1);
+@screen-xs-max: (@screen-sm-min - 1);
+@screen-sm-max: (@screen-md-min - 1);
+@screen-md-max: (@screen-lg-min - 1);
 
 
 //== Grid system
@@ -321,12 +321,12 @@
 //## Define your custom responsive grid.
 
 //** Number of columns in the grid.
-@grid-columns:              12;
+@grid-columns: 12;
 //** Padding between columns. Gets divided in half for the left and right.
-@grid-gutter-width:         30px;
+@grid-gutter-width: 30px;
 // Navbar collapse
 //** Point at which the navbar becomes uncollapsed.
-@grid-float-breakpoint:     @screen-sm-min;
+@grid-float-breakpoint: @screen-sm-min;
 //** Point at which the navbar begins collapsing.
 @grid-float-breakpoint-max: (@grid-float-breakpoint - 1);
 
@@ -336,19 +336,19 @@
 //## Define the maximum width of `.container` for different screen sizes.
 
 // Small screen / tablet
-@container-tablet:             (720px + @grid-gutter-width);
+@container-tablet: (720px + @grid-gutter-width);
 //** For `@screen-sm-min` and up.
-@container-sm:                 @container-tablet;
+@container-sm: @container-tablet;
 
 // Medium screen / desktop
-@container-desktop:            (940px + @grid-gutter-width);
+@container-desktop: (940px + @grid-gutter-width);
 //** For `@screen-md-min` and up.
-@container-md:                 @container-desktop;
+@container-md: @container-desktop;
 
 // Large screen / wide desktop
-@container-large-desktop:      (1140px + @grid-gutter-width);
+@container-large-desktop: (1140px + @grid-gutter-width);
 //** For `@screen-lg-min` and up.
-@container-lg:                 @container-large-desktop;
+@container-lg: @container-large-desktop;
 
 
 //== Navbar
@@ -356,61 +356,61 @@
 //##
 
 // Basics of a navbar
-@navbar-height:                    50px;
-@navbar-margin-bottom:             @line-height-computed;
-@navbar-border-radius:             @border-radius-base;
-@navbar-padding-horizontal:        floor((@grid-gutter-width / 2));
-@navbar-padding-vertical:          ((@navbar-height - @line-height-computed) / 2);
-@navbar-collapse-max-height:       340px;
+@navbar-height: 50px;
+@navbar-margin-bottom: @line-height-computed;
+@navbar-border-radius: @border-radius-base;
+@navbar-padding-horizontal: floor((@grid-gutter-width / 2));
+@navbar-padding-vertical: ((@navbar-height - @line-height-computed) / 2);
+@navbar-collapse-max-height: 340px;
 
-@navbar-default-color:             #777;
-@navbar-default-bg:                #f8f8f8;
-@navbar-default-border:            darken(@navbar-default-bg, 6.5%);
+@navbar-default-color: #777;
+@navbar-default-bg: #f8f8f8;
+@navbar-default-border: darken(@navbar-default-bg, 6.5%);
 
 // Navbar links
-@navbar-default-link-color:                #777;
-@navbar-default-link-hover-color:          #333;
-@navbar-default-link-hover-bg:             transparent;
-@navbar-default-link-active-color:         #555;
-@navbar-default-link-active-bg:            darken(@navbar-default-bg, 6.5%);
-@navbar-default-link-disabled-color:       #ccc;
-@navbar-default-link-disabled-bg:          transparent;
+@navbar-default-link-color: #777;
+@navbar-default-link-hover-color: #333;
+@navbar-default-link-hover-bg: transparent;
+@navbar-default-link-active-color: #555;
+@navbar-default-link-active-bg: darken(@navbar-default-bg, 6.5%);
+@navbar-default-link-disabled-color: #ccc;
+@navbar-default-link-disabled-bg: transparent;
 
 // Navbar brand label
-@navbar-default-brand-color:               @navbar-default-link-color;
-@navbar-default-brand-hover-color:         darken(@navbar-default-brand-color, 10%);
-@navbar-default-brand-hover-bg:            transparent;
+@navbar-default-brand-color: @navbar-default-link-color;
+@navbar-default-brand-hover-color: darken(@navbar-default-brand-color, 10%);
+@navbar-default-brand-hover-bg: transparent;
 
 // Navbar toggle
-@navbar-default-toggle-hover-bg:           #ddd;
-@navbar-default-toggle-icon-bar-bg:        #888;
-@navbar-default-toggle-border-color:       #ddd;
+@navbar-default-toggle-hover-bg: #ddd;
+@navbar-default-toggle-icon-bar-bg: #888;
+@navbar-default-toggle-border-color: #ddd;
 
 
 //=== Inverted navbar
 // Reset inverted navbar basics
-@navbar-inverse-color:                      lighten(@gray-light, 15%);
-@navbar-inverse-bg:                         #222;
-@navbar-inverse-border:                     darken(@navbar-inverse-bg, 10%);
+@navbar-inverse-color: lighten(@gray-light, 15%);
+@navbar-inverse-bg: #222;
+@navbar-inverse-border: darken(@navbar-inverse-bg, 10%);
 
 // Inverted navbar links
-@navbar-inverse-link-color:                 lighten(@gray-light, 15%);
-@navbar-inverse-link-hover-color:           #fff;
-@navbar-inverse-link-hover-bg:              transparent;
-@navbar-inverse-link-active-color:          @navbar-inverse-link-hover-color;
-@navbar-inverse-link-active-bg:             darken(@navbar-inverse-bg, 10%);
-@navbar-inverse-link-disabled-color:        #444;
-@navbar-inverse-link-disabled-bg:           transparent;
+@navbar-inverse-link-color: lighten(@gray-light, 15%);
+@navbar-inverse-link-hover-color: #fff;
+@navbar-inverse-link-hover-bg: transparent;
+@navbar-inverse-link-active-color: @navbar-inverse-link-hover-color;
+@navbar-inverse-link-active-bg: darken(@navbar-inverse-bg, 10%);
+@navbar-inverse-link-disabled-color: #444;
+@navbar-inverse-link-disabled-bg: transparent;
 
 // Inverted navbar brand label
-@navbar-inverse-brand-color:                @navbar-inverse-link-color;
-@navbar-inverse-brand-hover-color:          #fff;
-@navbar-inverse-brand-hover-bg:             transparent;
+@navbar-inverse-brand-color: @navbar-inverse-link-color;
+@navbar-inverse-brand-hover-color: #fff;
+@navbar-inverse-brand-hover-bg: transparent;
 
 // Inverted navbar toggle
-@navbar-inverse-toggle-hover-bg:            #333;
-@navbar-inverse-toggle-icon-bar-bg:         #fff;
-@navbar-inverse-toggle-border-color:        #333;
+@navbar-inverse-toggle-hover-bg: #333;
+@navbar-inverse-toggle-icon-bar-bg: #fff;
+@navbar-inverse-toggle-border-color: #333;
 
 
 //== Navs
@@ -418,98 +418,98 @@
 //##
 
 //=== Shared nav styles
-@nav-link-padding:                          10px 15px;
-@nav-link-hover-bg:                         @gray-lighter;
+@nav-link-padding: 10px 15px;
+@nav-link-hover-bg: @gray-lighter;
 
-@nav-disabled-link-color:                   @gray-light;
-@nav-disabled-link-hover-color:             @gray-light;
+@nav-disabled-link-color: @gray-light;
+@nav-disabled-link-hover-color: @gray-light;
 
 //== Tabs
-@nav-tabs-border-color:                     #ddd;
+@nav-tabs-border-color: #ddd;
 
-@nav-tabs-link-hover-border-color:          @gray-lighter;
+@nav-tabs-link-hover-border-color: @gray-lighter;
 
-@nav-tabs-active-link-hover-bg:             @body-bg;
-@nav-tabs-active-link-hover-color:          @gray;
-@nav-tabs-active-link-hover-border-color:   #ddd;
+@nav-tabs-active-link-hover-bg: @body-bg;
+@nav-tabs-active-link-hover-color: @gray;
+@nav-tabs-active-link-hover-border-color: #ddd;
 
-@nav-tabs-justified-link-border-color:            #ddd;
-@nav-tabs-justified-active-link-border-color:     @body-bg;
+@nav-tabs-justified-link-border-color: #ddd;
+@nav-tabs-justified-active-link-border-color: @body-bg;
 
 //== Pills
-@nav-pills-border-radius:                   @border-radius-base;
-@nav-pills-active-link-hover-bg:            @component-active-bg;
-@nav-pills-active-link-hover-color:         @component-active-color;
+@nav-pills-border-radius: @border-radius-base;
+@nav-pills-active-link-hover-bg: @component-active-bg;
+@nav-pills-active-link-hover-color: @component-active-color;
 
 
 //== Pagination
 //
 //##
 
-@pagination-color:                     @link-color;
-@pagination-bg:                        #fff;
-@pagination-border:                    #ddd;
+@pagination-color: @link-color;
+@pagination-bg: #fff;
+@pagination-border: #ddd;
 
-@pagination-hover-color:               @link-hover-color;
-@pagination-hover-bg:                  @gray-lighter;
-@pagination-hover-border:              #ddd;
+@pagination-hover-color: @link-hover-color;
+@pagination-hover-bg: @gray-lighter;
+@pagination-hover-border: #ddd;
 
-@pagination-active-color:              #fff;
-@pagination-active-bg:                 @brand-primary;
-@pagination-active-border:             @brand-primary;
+@pagination-active-color: #fff;
+@pagination-active-bg: @brand-primary;
+@pagination-active-border: @brand-primary;
 
-@pagination-disabled-color:            @gray-light;
-@pagination-disabled-bg:               #fff;
-@pagination-disabled-border:           #ddd;
+@pagination-disabled-color: @gray-light;
+@pagination-disabled-bg: #fff;
+@pagination-disabled-border: #ddd;
 
 
 //== Pager
 //
 //##
 
-@pager-bg:                             @pagination-bg;
-@pager-border:                         @pagination-border;
-@pager-border-radius:                  15px;
+@pager-bg: @pagination-bg;
+@pager-border: @pagination-border;
+@pager-border-radius: 15px;
 
-@pager-hover-bg:                       @pagination-hover-bg;
+@pager-hover-bg: @pagination-hover-bg;
 
-@pager-active-bg:                      @pagination-active-bg;
-@pager-active-color:                   @pagination-active-color;
+@pager-active-bg: @pagination-active-bg;
+@pager-active-color: @pagination-active-color;
 
-@pager-disabled-color:                 @pagination-disabled-color;
+@pager-disabled-color: @pagination-disabled-color;
 
 
 //== Jumbotron
 //
 //##
 
-@jumbotron-padding:              30px;
-@jumbotron-color:                inherit;
-@jumbotron-bg:                   @gray-lighter;
-@jumbotron-heading-color:        inherit;
-@jumbotron-font-size:            ceil((@font-size-base * 1.5));
-@jumbotron-heading-font-size:    ceil((@font-size-base * 4.5));
+@jumbotron-padding: 30px;
+@jumbotron-color: inherit;
+@jumbotron-bg: @gray-lighter;
+@jumbotron-heading-color: inherit;
+@jumbotron-font-size: ceil((@font-size-base * 1.5));
+@jumbotron-heading-font-size: ceil((@font-size-base * 4.5));
 
 
 //== Form states and alerts
 //
 //## Define colors for form feedback states and, by default, alerts.
 
-@state-success-text:             #3c763d;
-@state-success-bg:               #dff0d8;
-@state-success-border:           darken(spin(@state-success-bg, -10), 5%);
+@state-success-text: #3c763d;
+@state-success-bg: #dff0d8;
+@state-success-border: darken(spin(@state-success-bg, -10), 5%);
 
-@state-info-text:                #31708f;
-@state-info-bg:                  #d9edf7;
-@state-info-border:              darken(spin(@state-info-bg, -10), 7%);
+@state-info-text: #31708f;
+@state-info-bg: #d9edf7;
+@state-info-border: darken(spin(@state-info-bg, -10), 7%);
 
-@state-warning-text:             #8a6d3b;
-@state-warning-bg:               #fcf8e3;
-@state-warning-border:           darken(spin(@state-warning-bg, -10), 5%);
+@state-warning-text: #8a6d3b;
+@state-warning-bg: #fcf8e3;
+@state-warning-border: darken(spin(@state-warning-bg, -10), 5%);
 
-@state-danger-text:              #a94442;
-@state-danger-bg:                #f2dede;
-@state-danger-border:            darken(spin(@state-danger-bg, -10), 5%);
+@state-danger-text: #a94442;
+@state-danger-bg: #f2dede;
+@state-danger-border: darken(spin(@state-danger-bg, -10), 5%);
 
 
 //== Tooltips
@@ -517,17 +517,17 @@
 //##
 
 //** Tooltip max width
-@tooltip-max-width:           200px;
+@tooltip-max-width: 200px;
 //** Tooltip text color
-@tooltip-color:               #fff;
+@tooltip-color: #fff;
 //** Tooltip background color
-@tooltip-bg:                  #000;
-@tooltip-opacity:             .9;
+@tooltip-bg: #000;
+@tooltip-opacity: .9;
 
 //** Tooltip arrow width
-@tooltip-arrow-width:         5px;
+@tooltip-arrow-width: 5px;
 //** Tooltip arrow color
-@tooltip-arrow-color:         @tooltip-bg;
+@tooltip-arrow-color: @tooltip-bg;
 
 
 //== Popovers
@@ -535,28 +535,28 @@
 //##
 
 //** Popover body background color
-@popover-bg:                          #fff;
+@popover-bg: #fff;
 //** Popover maximum width
-@popover-max-width:                   276px;
+@popover-max-width: 276px;
 //** Popover border color
-@popover-border-color:                rgba(0,0,0,.2);
+@popover-border-color: rgba(0, 0, 0, .2);
 //** Popover fallback border color
-@popover-fallback-border-color:       #ccc;
+@popover-fallback-border-color: #ccc;
 
 //** Popover title background color
-@popover-title-bg:                    darken(@popover-bg, 3%);
+@popover-title-bg: darken(@popover-bg, 3%);
 
 //** Popover arrow width
-@popover-arrow-width:                 10px;
+@popover-arrow-width: 10px;
 //** Popover arrow color
-@popover-arrow-color:                 @popover-bg;
+@popover-arrow-color: @popover-bg;
 
 //** Popover outer arrow width
-@popover-arrow-outer-width:           (@popover-arrow-width + 1);
+@popover-arrow-outer-width: (@popover-arrow-width + 1);
 //** Popover outer arrow color
-@popover-arrow-outer-color:           fadein(@popover-border-color, 5%);
+@popover-arrow-outer-color: fadein(@popover-border-color, 5%);
 //** Popover outer arrow fallback color
-@popover-arrow-outer-fallback-color:  darken(@popover-fallback-border-color, 20%);
+@popover-arrow-outer-fallback-color: darken(@popover-fallback-border-color, 20%);
 
 
 //== Labels
@@ -564,22 +564,22 @@
 //##
 
 //** Default label background color
-@label-default-bg:            @gray-light;
+@label-default-bg: @gray-light;
 //** Primary label background color
-@label-primary-bg:            @brand-primary;
+@label-primary-bg: @brand-primary;
 //** Success label background color
-@label-success-bg:            @brand-success;
+@label-success-bg: @brand-success;
 //** Info label background color
-@label-info-bg:               @brand-info;
+@label-info-bg: @brand-info;
 //** Warning label background color
-@label-warning-bg:            @brand-warning;
+@label-warning-bg: @brand-warning;
 //** Danger label background color
-@label-danger-bg:             @brand-danger;
+@label-danger-bg: @brand-danger;
 
 //** Default label text color
-@label-color:                 #fff;
+@label-color: #fff;
 //** Default text color of a linked label
-@label-link-hover-color:      #fff;
+@label-link-hover-color: #fff;
 
 
 //== Modals
@@ -587,57 +587,57 @@
 //##
 
 //** Padding applied to the modal body
-@modal-inner-padding:         15px;
+@modal-inner-padding: 15px;
 
 //** Padding applied to the modal title
-@modal-title-padding:         15px;
+@modal-title-padding: 15px;
 //** Modal title line-height
-@modal-title-line-height:     @line-height-base;
+@modal-title-line-height: @line-height-base;
 
 //** Background color of modal content area
-@modal-content-bg:                             #fff;
+@modal-content-bg: #fff;
 //** Modal content border color
-@modal-content-border-color:                   rgba(0,0,0,.2);
+@modal-content-border-color: rgba(0, 0, 0, .2);
 //** Modal content border color **for IE8**
-@modal-content-fallback-border-color:          #999;
+@modal-content-fallback-border-color: #999;
 
 //** Modal backdrop background color
-@modal-backdrop-bg:           #000;
+@modal-backdrop-bg: #000;
 //** Modal backdrop opacity
-@modal-backdrop-opacity:      .5;
+@modal-backdrop-opacity: .5;
 //** Modal header border color
-@modal-header-border-color:   #e5e5e5;
+@modal-header-border-color: #e5e5e5;
 //** Modal footer border color
-@modal-footer-border-color:   @modal-header-border-color;
+@modal-footer-border-color: @modal-header-border-color;
 
-@modal-lg:                    900px;
-@modal-md:                    600px;
-@modal-sm:                    300px;
+@modal-lg: 900px;
+@modal-md: 600px;
+@modal-sm: 300px;
 
 
 //== Alerts
 //
 //## Define alert colors, border radius, and padding.
 
-@alert-padding:               15px;
-@alert-border-radius:         @border-radius-base;
-@alert-link-font-weight:      bold;
+@alert-padding: 15px;
+@alert-border-radius: @border-radius-base;
+@alert-link-font-weight: bold;
 
-@alert-success-bg:            @state-success-bg;
-@alert-success-text:          @state-success-text;
-@alert-success-border:        @state-success-border;
+@alert-success-bg: @state-success-bg;
+@alert-success-text: @state-success-text;
+@alert-success-border: @state-success-border;
 
-@alert-info-bg:               @state-info-bg;
-@alert-info-text:             @state-info-text;
-@alert-info-border:           @state-info-border;
+@alert-info-bg: @state-info-bg;
+@alert-info-text: @state-info-text;
+@alert-info-border: @state-info-border;
 
-@alert-warning-bg:            @state-warning-bg;
-@alert-warning-text:          @state-warning-text;
-@alert-warning-border:        @state-warning-border;
+@alert-warning-bg: @state-warning-bg;
+@alert-warning-text: @state-warning-text;
+@alert-warning-border: @state-warning-border;
 
-@alert-danger-bg:             @state-danger-bg;
-@alert-danger-text:           @state-danger-text;
-@alert-danger-border:         @state-danger-border;
+@alert-danger-bg: @state-danger-bg;
+@alert-danger-text: @state-danger-text;
+@alert-danger-border: @state-danger-border;
 
 
 //== Progress bars
@@ -645,22 +645,22 @@
 //##
 
 //** Background color of the whole progress component
-@progress-bg:                 #f5f5f5;
+@progress-bg: #f5f5f5;
 //** Progress bar text color
-@progress-bar-color:          #fff;
+@progress-bar-color: #fff;
 //** Variable for setting rounded corners on progress bar.
-@progress-border-radius:      @border-radius-base;
+@progress-border-radius: @border-radius-base;
 
 //** Default progress bar color
-@progress-bar-bg:             @brand-primary;
+@progress-bar-bg: @brand-primary;
 //** Success progress bar color
-@progress-bar-success-bg:     @brand-success;
+@progress-bar-success-bg: @brand-success;
 //** Warning progress bar color
-@progress-bar-warning-bg:     @brand-warning;
+@progress-bar-warning-bg: @brand-warning;
 //** Danger progress bar color
-@progress-bar-danger-bg:      @brand-danger;
+@progress-bar-danger-bg: @brand-danger;
 //** Info progress bar color
-@progress-bar-info-bg:        @brand-info;
+@progress-bar-info-bg: @brand-info;
 
 
 //== List group
@@ -668,32 +668,32 @@
 //##
 
 //** Background color on `.list-group-item`
-@list-group-bg:                 #fff;
+@list-group-bg: #fff;
 //** `.list-group-item` border color
-@list-group-border:             #ddd;
+@list-group-border: #ddd;
 //** List group border radius
-@list-group-border-radius:      @border-radius-base;
+@list-group-border-radius: @border-radius-base;
 
 //** Background color of single list pendants on hover
-@list-group-hover-bg:           #f5f5f5;
+@list-group-hover-bg: #f5f5f5;
 //** Text color of active list pendants
-@list-group-active-color:       @component-active-color;
+@list-group-active-color: @component-active-color;
 //** Background color of active list pendants
-@list-group-active-bg:          @component-active-bg;
+@list-group-active-bg: @component-active-bg;
 //** Border color of active list elements
-@list-group-active-border:      @list-group-active-bg;
+@list-group-active-border: @list-group-active-bg;
 //** Text color for content within active list pendants
-@list-group-active-text-color:  lighten(@list-group-active-bg, 40%);
+@list-group-active-text-color: lighten(@list-group-active-bg, 40%);
 
 //** Text color of disabled list pendants
-@list-group-disabled-color:      @gray-light;
+@list-group-disabled-color: @gray-light;
 //** Background color of disabled list pendants
-@list-group-disabled-bg:         @gray-lighter;
+@list-group-disabled-bg: @gray-lighter;
 //** Text color for content within disabled list pendants
 @list-group-disabled-text-color: @list-group-disabled-color;
 
-@list-group-link-color:         #555;
-@list-group-link-hover-color:   @list-group-link-color;
+@list-group-link-color: #555;
+@list-group-link-hover-color: @list-group-link-color;
 @list-group-link-heading-color: #333;
 
 
@@ -701,39 +701,39 @@
 //
 //##
 
-@panel-bg:                    #fff;
-@panel-body-padding:          15px;
-@panel-heading-padding:       10px 15px;
-@panel-footer-padding:        @panel-heading-padding;
-@panel-border-radius:         @border-radius-base;
+@panel-bg: #fff;
+@panel-body-padding: 15px;
+@panel-heading-padding: 10px 15px;
+@panel-footer-padding: @panel-heading-padding;
+@panel-border-radius: @border-radius-base;
 
 //** Border color for elements within panels
-@panel-inner-border:          #ddd;
-@panel-footer-bg:             #f5f5f5;
+@panel-inner-border: #ddd;
+@panel-footer-bg: #f5f5f5;
 
-@panel-default-text:          @gray-dark;
-@panel-default-border:        #ddd;
-@panel-default-heading-bg:    #f5f5f5;
+@panel-default-text: @gray-dark;
+@panel-default-border: #ddd;
+@panel-default-heading-bg: #f5f5f5;
 
-@panel-primary-text:          #fff;
-@panel-primary-border:        @brand-primary;
-@panel-primary-heading-bg:    @brand-primary;
+@panel-primary-text: #fff;
+@panel-primary-border: @brand-primary;
+@panel-primary-heading-bg: @brand-primary;
 
-@panel-success-text:          @state-success-text;
-@panel-success-border:        @state-success-border;
-@panel-success-heading-bg:    @state-success-bg;
+@panel-success-text: @state-success-text;
+@panel-success-border: @state-success-border;
+@panel-success-heading-bg: @state-success-bg;
 
-@panel-info-text:             @state-info-text;
-@panel-info-border:           @state-info-border;
-@panel-info-heading-bg:       @state-info-bg;
+@panel-info-text: @state-info-text;
+@panel-info-border: @state-info-border;
+@panel-info-heading-bg: @state-info-bg;
 
-@panel-warning-text:          @state-warning-text;
-@panel-warning-border:        @state-warning-border;
-@panel-warning-heading-bg:    @state-warning-bg;
+@panel-warning-text: @state-warning-text;
+@panel-warning-border: @state-warning-border;
+@panel-warning-heading-bg: @state-warning-bg;
 
-@panel-danger-text:           @state-danger-text;
-@panel-danger-border:         @state-danger-border;
-@panel-danger-heading-bg:     @state-danger-bg;
+@panel-danger-text: @state-danger-text;
+@panel-danger-border: @state-danger-border;
+@panel-danger-heading-bg: @state-danger-bg;
 
 
 //== Thumbnails
@@ -741,103 +741,103 @@
 //##
 
 //** Padding around the thumbnail image
-@thumbnail-padding:           4px;
+@thumbnail-padding: 4px;
 //** Thumbnail background color
-@thumbnail-bg:                @body-bg;
+@thumbnail-bg: @body-bg;
 //** Thumbnail border color
-@thumbnail-border:            #ddd;
+@thumbnail-border: #ddd;
 //** Thumbnail border radius
-@thumbnail-border-radius:     @border-radius-base;
+@thumbnail-border-radius: @border-radius-base;
 
 //** Custom text color for thumbnail captions
-@thumbnail-caption-color:     @text-color;
+@thumbnail-caption-color: @text-color;
 //** Padding around the thumbnail caption
-@thumbnail-caption-padding:   9px;
+@thumbnail-caption-padding: 9px;
 
 
 //== Wells
 //
 //##
 
-@well-bg:                     #f5f5f5;
-@well-border:                 darken(@well-bg, 7%);
+@well-bg: #f5f5f5;
+@well-border: darken(@well-bg, 7%);
 
 
 //== Badges
 //
 //##
 
-@badge-color:                 #fff;
+@badge-color: #fff;
 //** Linked badge text color on hover
-@badge-link-hover-color:      #fff;
-@badge-bg:                    @gray-light;
+@badge-link-hover-color: #fff;
+@badge-bg: @gray-light;
 
 //** Badge text color in active nav link
-@badge-active-color:          @link-color;
+@badge-active-color: @link-color;
 //** Badge background color in active nav link
-@badge-active-bg:             #fff;
+@badge-active-bg: #fff;
 
-@badge-font-weight:           bold;
-@badge-line-height:           1;
-@badge-border-radius:         10px;
+@badge-font-weight: bold;
+@badge-line-height: 1;
+@badge-border-radius: 10px;
 
 
 //== Breadcrumbs
 //
 //##
 
-@breadcrumb-padding-vertical:   8px;
+@breadcrumb-padding-vertical: 8px;
 @breadcrumb-padding-horizontal: 15px;
 //** Breadcrumb background color
-@breadcrumb-bg:                 #f5f5f5;
+@breadcrumb-bg: #f5f5f5;
 //** Breadcrumb text color
-@breadcrumb-color:              #ccc;
+@breadcrumb-color: #ccc;
 //** Text color of current page in the breadcrumb
-@breadcrumb-active-color:       @gray-light;
+@breadcrumb-active-color: @gray-light;
 //** Textual separator for between breadcrumb elements
-@breadcrumb-separator:          "/";
+@breadcrumb-separator: "/";
 
 
 //== Carousel
 //
 //##
 
-@carousel-text-shadow:                        0 1px 2px rgba(0,0,0,.6);
+@carousel-text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
 
-@carousel-control-color:                      #fff;
-@carousel-control-width:                      15%;
-@carousel-control-opacity:                    .5;
-@carousel-control-font-size:                  20px;
+@carousel-control-color: #fff;
+@carousel-control-width: 15%;
+@carousel-control-opacity: .5;
+@carousel-control-font-size: 20px;
 
-@carousel-indicator-active-bg:                #fff;
-@carousel-indicator-border-color:             #fff;
+@carousel-indicator-active-bg: #fff;
+@carousel-indicator-border-color: #fff;
 
-@carousel-caption-color:                      #fff;
+@carousel-caption-color: #fff;
 
 
 //== Close
 //
 //##
 
-@close-font-weight:           bold;
-@close-color:                 #000;
-@close-text-shadow:           0 1px 0 #fff;
+@close-font-weight: bold;
+@close-color: #000;
+@close-text-shadow: 0 1px 0 #fff;
 
 
 //== Code
 //
 //##
 
-@code-color:                  #c7254e;
-@code-bg:                     #f9f2f4;
+@code-color: #c7254e;
+@code-bg: #f9f2f4;
 
-@kbd-color:                   #fff;
-@kbd-bg:                      #333;
+@kbd-color: #fff;
+@kbd-bg: #333;
 
-@pre-bg:                      #f5f5f5;
-@pre-color:                   @gray-dark;
-@pre-border-color:            #ccc;
-@pre-scrollable-max-height:   340px;
+@pre-bg: #f5f5f5;
+@pre-color: @gray-dark;
+@pre-border-color: #ccc;
+@pre-scrollable-max-height: 340px;
 
 
 //== Type
@@ -847,22 +847,22 @@
 //** Horizontal offset for forms and lists.
 @component-offset-horizontal: 180px;
 //** Text muted color
-@text-muted:                  @gray-light;
+@text-muted: @gray-light;
 //** Abbreviations and acronyms border color
-@abbr-border-color:           @gray-light;
+@abbr-border-color: @gray-light;
 //** Headings small color
-@headings-small-color:        @gray-light;
+@headings-small-color: @gray-light;
 //** Blockquote small color
-@blockquote-small-color:      @gray-light;
+@blockquote-small-color: @gray-light;
 //** Blockquote font size
-@blockquote-font-size:        (@font-size-base * 1.25);
+@blockquote-font-size: (@font-size-base * 1.25);
 //** Blockquote border color
-@blockquote-border-color:     @gray-lighter;
+@blockquote-border-color: @gray-lighter;
 //** Page header border color
-@page-header-border-color:    @gray-lighter;
+@page-header-border-color: @gray-lighter;
 //** Width of horizontal description list titles
-@dl-horizontal-offset:        @component-offset-horizontal;
+@dl-horizontal-offset: @component-offset-horizontal;
 //** Point at which .dl-horizontal becomes horizontal
-@dl-horizontal-breakpoint:    @grid-float-breakpoint;
+@dl-horizontal-breakpoint: @grid-float-breakpoint;
 //** Horizontal line color.
-@hr-border:                   @gray-lighter;
+@hr-border: @gray-lighter;
diff --git a/src/assets/css/global/button.less b/src/assets/css/global/button.less
index 12c87a3..187db95 100644
--- a/src/assets/css/global/button.less
+++ b/src/assets/css/global/button.less
@@ -23,28 +23,28 @@
 }
 
 .btn-action {
-    margin: 0 3px;
-    display: inline-block;
-    opacity: 0.85;
-    -webkit-transition: all 0.1s;
-    -o-transition: all 0.1s;
-    transition: all 0.1s;
-    cursor: pointer;
+  margin: 0 3px;
+  display: inline-block;
+  opacity: 0.85;
+  -webkit-transition: all 0.1s;
+  -o-transition: all 0.1s;
+  transition: all 0.1s;
+  cursor: pointer;
+  outline: none;
+
+  &:hover {
+    text-decoration: none;
+    opacity: 1;
+    -moz-transform: scale(1.2);
+    -webkit-transform: scale(1.2);
+    -o-transform: scale(1.2);
+    -ms-transform: scale(1.2);
+    transform: scale(1.2);
+  }
+
+  &:focus {
     outline: none;
-
-    &:hover {
-        text-decoration: none;
-        opacity: 1;
-        -moz-transform: scale(1.2);
-        -webkit-transform: scale(1.2);
-        -o-transform: scale(1.2);
-        -ms-transform: scale(1.2);
-        transform: scale(1.2);
-    }
-
-    &:focus {
-        outline: none;
-    }
+  }
 }
 
 .btn-primary {
@@ -52,12 +52,14 @@
   background-color: #337ab7;
   border-color: #2e6da4;
 }
+
 .btn-primary:focus,
 .btn-primary.focus {
   color: #fff;
   background-color: #286090;
   border-color: #122b40;
 }
+
 .btn-primary:hover {
   color: #fff;
   background-color: #286090;
@@ -73,11 +75,11 @@
 
 //编辑区域按钮,鼠标一上去按钮变大
 .action-buttons {
-    a {
-        .btn-action;
-    }
+  a {
+    .btn-action;
+  }
 }
 
 .cursor {
-    cursor: pointer;
+  cursor: pointer;
 }
diff --git a/src/assets/css/global/color.less b/src/assets/css/global/color.less
index e650123..dbb7a3d 100644
--- a/src/assets/css/global/color.less
+++ b/src/assets/css/global/color.less
@@ -1,113 +1,391 @@
 @import "./variables.less";
 
-.bg-primary{ background-color: @brand-primary; color: white;}
-.bg-success{ background-color: @brand-success; color: white; }
-.bg-info{ background-color: @brand-info; color: white; }
-.bg-warning{ background-color: @brand-warning; color: white; }
-.bg-danger{ background-color: @brand-danger; color: white; }
-.bg-gray{ background-color: @brand-gray; color: white; }
-.bg-laxative{ background-color: @brand-laxative; color: white; }
+.bg-primary {
+  background-color: @brand-primary;
+  color: white;
+}
+
+.bg-success {
+  background-color: @brand-success;
+  color: white;
+}
+
+.bg-info {
+  background-color: @brand-info;
+  color: white;
+}
+
+.bg-warning {
+  background-color: @brand-warning;
+  color: white;
+}
+
+.bg-danger {
+  background-color: @brand-danger;
+  color: white;
+}
+
+.bg-gray {
+  background-color: @brand-gray;
+  color: white;
+}
+
+.bg-laxative {
+  background-color: @brand-laxative;
+  color: white;
+}
 
 
-.text-primary{ color: @brand-primary;}
-.text-success{ color: @brand-success; }
-.text-info{ color: @brand-info; }
-.text-warning{ color: @brand-warning; }
-.text-danger{ color: @brand-danger; }
-.text-gray{ color: @brand-gray; }
-.text-laxative{ color: @brand-laxative; }
-.text-theme { color: @primary-color; }
+.text-primary {
+  color: @brand-primary;
+}
+
+.text-success {
+  color: @brand-success;
+}
+
+.text-info {
+  color: @brand-info;
+}
+
+.text-warning {
+  color: @brand-warning;
+}
+
+.text-danger {
+  color: @brand-danger;
+}
+
+.text-gray {
+  color: @brand-gray;
+}
+
+.text-laxative {
+  color: @brand-laxative;
+}
+
+.text-theme {
+  color: @primary-color;
+}
+
+.bg-navy {
+  background-color: #001F3F;
+}
+
+.bg-blue {
+  background-color: #0074D9;
+}
+
+.bg-aqua {
+  background-color: #7FDBFF;
+}
+
+.bg-aliceblue {
+  background-color: aliceblue;
+}
+
+.bg-pink {
+  background-color: pink;
+}
+
+.bg-azure {
+  background-color: azure;
+}
+
+.bg-teal {
+  background-color: #39CCCC;
+}
+
+.bg-olive {
+  background-color: #3D9970;
+}
+
+.bg-green {
+  background-color: #2ECC40;
+}
+
+.bg-lime {
+  background-color: #01FF70;
+}
+
+.bg-yellow {
+  background-color: #FFDC00;
+}
+
+.bg-pink {
+  color: pink;
+}
+
+.bg-orange {
+  background-color: #FF851B;
+}
+
+.bg-red {
+  background-color: #FF4136;
+}
+
+.bg-fuchsia {
+  background-color: #F012BE;
+}
+
+.bg-purple {
+  background-color: #B10DC9;
+}
+
+.bg-maroon {
+  background-color: #85144B;
+}
+
+.bg-white {
+  background-color: #FFFFFF;
+}
+
+.bg-gray {
+  background-color: #AAAAAA;
+}
+
+.bg-silver {
+  background-color: #DDDDDD;
+}
 
-.bg-navy {  background-color: #001F3F;}
-.bg-blue {  background-color: #0074D9;}
-.bg-aqua {  background-color: #7FDBFF;}
-.bg-aliceblue {  background-color: aliceblue;}
-.bg-pink {  background-color: pink;}
-.bg-azure {  background-color: azure;}
-.bg-teal {  background-color: #39CCCC;}
-.bg-olive {  background-color: #3D9970;}
-.bg-green {  background-color: #2ECC40;}
-.bg-lime {  background-color: #01FF70;}
-.bg-yellow {  background-color: #FFDC00;}
-.bg-pink { color: pink; }
-.bg-orange {  background-color: #FF851B;}
-.bg-red {  background-color: #FF4136;}
-.bg-fuchsia {  background-color: #F012BE;}
-.bg-purple {  background-color: #B10DC9;}
-.bg-maroon {  background-color: #85144B;}
-.bg-white {  background-color: #FFFFFF;}
-.bg-gray {  background-color: #AAAAAA;}
-.bg-silver {  background-color: #DDDDDD;}
 .bg-silver-white {
   background-color: #EEEEEE;
 }
-.bg-black {  background-color: #111111;}
 
-.bg-111{ background-color:#111 }
-.bg-222{ background-color:#222 }
-.bg-333{ background-color:#333 }
-.bg-444{ background-color:#444 }
-.bg-555{ background-color:#555 }
-.bg-666{ background-color:#666 }
-.bg-777{ background-color:#777 }
-.bg-888{ background-color:#888 }
-.bg-999{ background-color:#999 }
-.bg-aaa{ background-color:#aaa }
-.bg-bbb{ background-color:#bbb }
-.bg-ccc{ background-color:#ccc }
-.bg-ddd{ background-color:#ddd }
-.bg-eee{ background-color:#eee }
+.bg-black {
+  background-color: #111111;
+}
 
+.bg-111 {
+  background-color: #111
+}
+
+.bg-222 {
+  background-color: #222
+}
+
+.bg-333 {
+  background-color: #333
+}
+
+.bg-444 {
+  background-color: #444
+}
+
+.bg-555 {
+  background-color: #555
+}
+
+.bg-666 {
+  background-color: #666
+}
+
+.bg-777 {
+  background-color: #777
+}
+
+.bg-888 {
+  background-color: #888
+}
+
+.bg-999 {
+  background-color: #999
+}
+
+.bg-aaa {
+  background-color: #aaa
+}
+
+.bg-bbb {
+  background-color: #bbb
+}
+
+.bg-ccc {
+  background-color: #ccc
+}
+
+.bg-ddd {
+  background-color: #ddd
+}
+
+.bg-eee {
+  background-color: #eee
+}
 
 
 /* Colors */
-.navy {  color: #001F3F;}
-.blue {  color: #0074D9;}
-.aqua {  color: #7FDBFF;}
-.teal {  color: #39CCCC;}
-.olive {  color: #3D9970;}
-.green {  color: #2ECC40;}
-.lime {  color: #01FF70;}
-.yellow {  color: #FFDC00;}
-.pink { color: pink; }
-.orange {  color: #FF851B;}
-.red {  color: #FF4136;}
-.fuchsia {  color: #F012BE;}
-.purple {  color: #B10DC9;}
-.maroon {  color: #85144B;}
-.white {  color: #FFFFFF;}
-.silver {  color: #DDDDDD;}
-.gray {  color: #AAAAAA;}
-.black {  color: #111111;}
+.navy {
+  color: #001F3F;
+}
+
+.blue {
+  color: #0074D9;
+}
+
+.aqua {
+  color: #7FDBFF;
+}
+
+.teal {
+  color: #39CCCC;
+}
+
+.olive {
+  color: #3D9970;
+}
+
+.green {
+  color: #2ECC40;
+}
+
+.lime {
+  color: #01FF70;
+}
+
+.yellow {
+  color: #FFDC00;
+}
+
+.pink {
+  color: pink;
+}
+
+.orange {
+  color: #FF851B;
+}
+
+.red {
+  color: #FF4136;
+}
+
+.fuchsia {
+  color: #F012BE;
+}
+
+.purple {
+  color: #B10DC9;
+}
+
+.maroon {
+  color: #85144B;
+}
+
+.white {
+  color: #FFFFFF;
+}
+
+.silver {
+  color: #DDDDDD;
+}
+
+.gray {
+  color: #AAAAAA;
+}
+
+.black {
+  color: #111111;
+}
 
 
-.color-111{color:#111}
-.color-222{color:#222}
-.color-333{color:#333}
-.color-444{color:#444}
-.color-555{color:#555}
-.color-666{color:#666}
-.color-777{color:#777}
-.color-888{color:#888}
-.color-999{color:#999}
-.color-aaa{color:#aaa}
-.color-bbb{color:#bbb}
-.color-ccc{color:#ccc}
-.color-ddd{color:#ddd}
-.color-eee{color:#eee}
+.color-111 {
+  color: #111
+}
+
+.color-222 {
+  color: #222
+}
+
+.color-333 {
+  color: #333
+}
+
+.color-444 {
+  color: #444
+}
+
+.color-555 {
+  color: #555
+}
+
+.color-666 {
+  color: #666
+}
+
+.color-777 {
+  color: #777
+}
+
+.color-888 {
+  color: #888
+}
+
+.color-999 {
+  color: #999
+}
+
+.color-aaa {
+  color: #aaa
+}
+
+.color-bbb {
+  color: #bbb
+}
+
+.color-ccc {
+  color: #ccc
+}
+
+.color-ddd {
+  color: #ddd
+}
+
+.color-eee {
+  color: #eee
+}
 
 
-.color-text {  color: #660E7A;}
-.color-doc {  color: #295496;}
-.color-xls {  color: #1E6C41;}
-.color-ppt {  color: #D04324;}
-.color-pdf {  color: #E40B0B;}
-.color-audio {  color: #5bc0de;}
-.color-video {  color: #5cb85c;}
-.color-image {  color: #0074D9;}
-.color-archive {  color: #4437f2;}
+.color-text {
+  color: #660E7A;
+}
 
-.color-light-active{ color: #ffc60c;}
-.color-light-inactive{ color:#ccc;}
+.color-doc {
+  color: #295496;
+}
+
+.color-xls {
+  color: #1E6C41;
+}
+
+.color-ppt {
+  color: #D04324;
+}
+
+.color-pdf {
+  color: #E40B0B;
+}
+
+.color-audio {
+  color: #5bc0de;
+}
+
+.color-video {
+  color: #5cb85c;
+}
+
+.color-image {
+  color: #0074D9;
+}
+
+.color-archive {
+  color: #4437f2;
+}
+
+.color-light-active {
+  color: #ffc60c;
+}
+
+.color-light-inactive {
+  color: #ccc;
+}
 
 
diff --git a/src/assets/css/global/font.less b/src/assets/css/global/font.less
index 114ce52..9a9c6a8 100644
--- a/src/assets/css/global/font.less
+++ b/src/assets/css/global/font.less
@@ -1,38 +1,38 @@
-#font{
-  .f(@from,@end,@step){
-    .mX(@f,@e,@s) when (@e >= @f){
-      .f@{e}{
-        font-size:@e*1px!important;
+#font {
+  .f(@from,@end,@step) {
+    .mX(@f,@e,@s) when (@e >= @f) {
+      .f@{e} {
+        font-size: @e*1px !important;
       }
-      .mX(@f,@e - @s,@s);
+      .mX(@f, @e - @s, @s);
     }
-    .mX(@from,@end,@step);
+    .mX(@from, @end, @step);
   }
 
 }
 
-#font > .f(10,80,1);
+#font > .f(10, 80, 1);
 
-#font{
-  .ln(@from,@end,@step){
-    .mX(@f,@e,@s) when (@e >= @f){
-      .ln@{e}{
-        line-height:@e*1px!important;
+#font {
+  .ln(@from,@end,@step) {
+    .mX(@f,@e,@s) when (@e >= @f) {
+      .ln@{e} {
+        line-height: @e*1px !important;
       }
-      .mX(@f,@e - @s,@s);
+      .mX(@f, @e - @s, @s);
     }
-    .mX(@from,@end,@step);
+    .mX(@from, @end, @step);
   }
 
 }
 
-#font > .ln(10,100,1);
+#font > .ln(10, 100, 1);
 
 
-
-.bold{
-  font-weight:bold;
+.bold {
+  font-weight: bold;
 }
-.italic{
-  font-style:italic;
+
+.italic {
+  font-style: italic;
 }
diff --git a/src/assets/css/global/miscellaneous.less b/src/assets/css/global/miscellaneous.less
index 534ef2d..d7dd5c4 100644
--- a/src/assets/css/global/miscellaneous.less
+++ b/src/assets/css/global/miscellaneous.less
@@ -139,6 +139,7 @@ a {
 
 .hot-area {
   position: relative;
+
   &:after {
     position: absolute;
     top: -10px;
diff --git a/src/assets/image/empty.svg b/src/assets/image/empty.svg
index 78ee45c..07a98b4 100644
--- a/src/assets/image/empty.svg
+++ b/src/assets/image/empty.svg
@@ -1 +1,20 @@
-
\ No newline at end of file
+
+
+    
+        
+    
+    
+    
+    
+    
+    
+    
+    
+
diff --git a/src/assets/image/file/alien.svg b/src/assets/image/file/alien.svg
index 0c4e1cc..2c55f14 100644
--- a/src/assets/image/file/alien.svg
+++ b/src/assets/image/file/alien.svg
@@ -1 +1,10 @@
-
+
+
+    
+        
+    
+    
+
diff --git a/src/assets/image/file/archive.svg b/src/assets/image/file/archive.svg
index e4cc6ae..11d9d6e 100644
--- a/src/assets/image/file/archive.svg
+++ b/src/assets/image/file/archive.svg
@@ -1 +1,14 @@
-
\ No newline at end of file
+
+
+    
+        
+    
+    
+    
+    
+    
+    
+
diff --git a/src/assets/image/file/audio.svg b/src/assets/image/file/audio.svg
index 61d679d..a3922fb 100644
--- a/src/assets/image/file/audio.svg
+++ b/src/assets/image/file/audio.svg
@@ -1 +1,14 @@
-
\ No newline at end of file
+
+
+    
+        
+    
+    
+    
+    
+
diff --git a/src/assets/image/file/doc.svg b/src/assets/image/file/doc.svg
index 5f0c6a6..a251e7d 100644
--- a/src/assets/image/file/doc.svg
+++ b/src/assets/image/file/doc.svg
@@ -1 +1,12 @@
-
\ No newline at end of file
+
+
+    
+        
+    
+    
+    
+
diff --git a/src/assets/image/file/file.svg b/src/assets/image/file/file.svg
index 90cfac4..76e1379 100644
--- a/src/assets/image/file/file.svg
+++ b/src/assets/image/file/file.svg
@@ -1 +1,19 @@
-
\ No newline at end of file
+
+
+    
+        
+    
+    
+    
+    
+    
+    
+    
+
diff --git a/src/assets/image/file/folder.svg b/src/assets/image/file/folder.svg
index 7556f2a..893515e 100644
--- a/src/assets/image/file/folder.svg
+++ b/src/assets/image/file/folder.svg
@@ -1 +1,10 @@
-
+
+
+    
+        
+    
+    
+
diff --git a/src/assets/image/file/image.svg b/src/assets/image/file/image.svg
index ae44150..e69c1f1 100644
--- a/src/assets/image/file/image.svg
+++ b/src/assets/image/file/image.svg
@@ -1 +1,16 @@
-
\ No newline at end of file
+
+
+    
+        
+    
+    
+    
+    
+    
+    
+
diff --git a/src/assets/image/file/pdf.svg b/src/assets/image/file/pdf.svg
index 8eb62e6..0d58cfa 100644
--- a/src/assets/image/file/pdf.svg
+++ b/src/assets/image/file/pdf.svg
@@ -1 +1,13 @@
-
\ No newline at end of file
+
+
+    
+        
+    
+    
+    
+    
+
diff --git a/src/assets/image/file/ppt.svg b/src/assets/image/file/ppt.svg
index 91e8b70..a2fcfb1 100644
--- a/src/assets/image/file/ppt.svg
+++ b/src/assets/image/file/ppt.svg
@@ -1 +1,18 @@
-
\ No newline at end of file
+
+
+    
+        
+    
+    
+    
+    
+    
+    
+
diff --git a/src/assets/image/file/psd.svg b/src/assets/image/file/psd.svg
index d2d7499..9523f67 100644
--- a/src/assets/image/file/psd.svg
+++ b/src/assets/image/file/psd.svg
@@ -1 +1,16 @@
-
\ No newline at end of file
+
+
+    
+        
+    
+    
+    
+    
+    
+    
+
diff --git a/src/assets/image/file/text.svg b/src/assets/image/file/text.svg
index 74e9b0b..3946a26 100644
--- a/src/assets/image/file/text.svg
+++ b/src/assets/image/file/text.svg
@@ -1 +1,10 @@
-
\ No newline at end of file
+
+
+    
+        
+    
+    
+
diff --git a/src/assets/image/file/video.svg b/src/assets/image/file/video.svg
index cba33b3..3cd9d15 100644
--- a/src/assets/image/file/video.svg
+++ b/src/assets/image/file/video.svg
@@ -1 +1,23 @@
-
\ No newline at end of file
+
+
+    
+        
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+
diff --git a/src/assets/image/file/xls.svg b/src/assets/image/file/xls.svg
index 1f08d9f..e66f271 100644
--- a/src/assets/image/file/xls.svg
+++ b/src/assets/image/file/xls.svg
@@ -1 +1,17 @@
-
\ No newline at end of file
+
+
+    
+        
+    
+    
+    
+    
+    
+    
+
diff --git a/src/assets/image/success.svg b/src/assets/image/success.svg
index d5336e0..1802b00 100644
--- a/src/assets/image/success.svg
+++ b/src/assets/image/success.svg
@@ -1 +1,11 @@
-
\ No newline at end of file
+
+
+    
+        
+    
+    
+    
+
diff --git a/src/common/component/TankComponent.tsx b/src/common/component/TankComponent.tsx
index 72095f6..fea622c 100644
--- a/src/common/component/TankComponent.tsx
+++ b/src/common/component/TankComponent.tsx
@@ -6,32 +6,32 @@ import React from 'react';
  */
 export default class TankComponent extends React.Component  {
 
-  //是否处于挂载的状态。
-  mounted: boolean = false
+    //是否处于挂载的状态。
+    mounted: boolean = false
 
-  componentWillUnmount() {
-    let that = this
-    that.mounted = false
-  }
-
-  componentWillMount() {
-    let that = this
-    that.mounted = true
-  }
-
-  //更新当前视图。
-  updateUI() {
-    let that = this
-    if (that.mounted) {
-      that.setState({})
-    } else {
-      console.info(this.constructor.name + "已经脱离挂载,不再刷新视图。")
+    componentWillUnmount() {
+        let that = this
+        that.mounted = false
     }
-  }
 
-  //获取当前组件的唯一标识
-  getIdentifier() {
-    return this.constructor.name;
-  }
+    componentWillMount() {
+        let that = this
+        that.mounted = true
+    }
+
+    //更新当前视图。
+    updateUI() {
+        let that = this
+        if (that.mounted) {
+            that.setState({})
+        } else {
+            console.info(this.constructor.name + "已经脱离挂载,不再刷新视图。")
+        }
+    }
+
+    //获取当前组件的唯一标识
+    getIdentifier() {
+        return this.constructor.name;
+    }
 }
 
diff --git a/src/common/menu/MenuItem.ts b/src/common/menu/MenuItem.ts
index a7a1eef..378be91 100644
--- a/src/common/menu/MenuItem.ts
+++ b/src/common/menu/MenuItem.ts
@@ -2,23 +2,23 @@ import {ToolItem} from "../types";
 import React from "react";
 
 export default class MenuItem implements ToolItem {
-  name: string;
-  url: string;
-  icon: React.ReactNode;
-  active: boolean = false;
+    name: string;
+    url: string;
+    icon: React.ReactNode;
+    active: boolean = false;
 
 
-  constructor(name: string, url: string, icon: React.ReactNode) {
-    this.name = name;
-    this.url = url;
-    this.icon = icon;
+    constructor(name: string, url: string, icon: React.ReactNode) {
+        this.name = name;
+        this.url = url;
+        this.icon = icon;
+
+        //当前的url完全一致,那么就高亮显示
+        if (url == "/user/login") {
+            this.active = window.location.pathname === url || window.location.pathname === "/user/register"
+        } else {
+            this.active = window.location.pathname === url
+        }
 
-    //当前的url完全一致,那么就高亮显示
-    if (url == "/user/login") {
-      this.active = window.location.pathname === url || window.location.pathname === "/user/register"
-    } else {
-      this.active = window.location.pathname === url
     }
-
-  }
 }
diff --git a/src/common/menu/MenuManager.tsx b/src/common/menu/MenuManager.tsx
index 96b3186..67f04df 100644
--- a/src/common/menu/MenuManager.tsx
+++ b/src/common/menu/MenuManager.tsx
@@ -8,13 +8,13 @@ import User from '../model/user/User';
 import {UserRole} from '../model/user/UserRole';
 import Sun from '../../common/model/global/Sun';
 import {
-  AppstoreOutlined,
-  DashboardOutlined,
-  PoweroffOutlined,
-  SettingOutlined,
-  ShareAltOutlined,
-  TeamOutlined,
-  DeleteOutlined
+    AppstoreOutlined,
+    DashboardOutlined,
+    DeleteOutlined,
+    PoweroffOutlined,
+    SettingOutlined,
+    ShareAltOutlined,
+    TeamOutlined
 } from '@ant-design/icons';
 import {LoginOutlined} from "@ant-design/icons/lib";
 import Preference from "../model/preference/Preference";
@@ -23,79 +23,80 @@ import Lang from "../model/global/Lang";
 
 export default class MenuManager {
 
-  //单例模式
-  private static singleton: MenuManager;
-
-  constructor() {
-
-  }
-
-  static getSingleton(): MenuManager {
-    if (!MenuManager.singleton) {
-      //初始化一个mainLand.
-      MenuManager.singleton = new MenuManager();
-
-    }
-    return MenuManager.singleton;
-  }
-
-  /**
-   * 获取到当前高亮的菜单
-   */
-  getSelectedKeys(): string[] {
-
-    let keys: string[] = this.getMenuItems()
-      .filter((menuItem: MenuItem, index: number) => {
-        return menuItem.active;
-      }).map((menuItem: MenuItem, index: number) => {
-        return menuItem.url;
-      });
-
-    return keys;
-  }
-
-  /**
-   * 高亮某个菜单
-   */
-  selectMenu(url: string) {
-
-    this.getMenuItems().forEach((menuItem: MenuItem, index: number) => {
-      menuItem.active = menuItem.url === url;
-    });
-
-  }
-
-  getMenuItems(): MenuItem[] {
-    let user: User = Moon.getSingleton().user;
-    let preference: Preference = Moon.getSingleton().preference;
-
-    let menuItems: MenuItem[] = [];
-
-    if (!preference.installed) {
-      menuItems = [
-        new MenuItem(Lang.t("layout.install"), '/install/index', ),
-      ];
-    } else if (user.role === UserRole.GUEST) {
-      menuItems = [
-        new MenuItem(Lang.t("user.login"), '/user/login', ),
-      ];
-    } else {
-      menuItems.push(new MenuItem(Lang.t("layout.allFiles"), '/matter/list', ))
-      menuItems.push(new MenuItem(Lang.t("layout.myShare"), '/share/list', ))
-      menuItems.push(new MenuItem(Lang.t("layout.bin"), '/bin/list', ))
-
-      if (user.role === UserRole.ADMINISTRATOR) {
-        menuItems.push(new MenuItem(Lang.t("layout.setting"), '/preference/index', ))
-        menuItems.push(new MenuItem(Lang.t("layout.dashboard"), '/dashboard/index', ))
-        menuItems.push(new MenuItem(Lang.t("layout.users"), `${Sun.getSingleton().isMobile ? '/mobile': ''}/user/list`, ))
-      }
-      menuItems.push(new MenuItem(Lang.t("layout.logout"), '/user/logout', ))
+    //单例模式
+    private static singleton: MenuManager;
 
+    constructor() {
 
     }
 
-    return menuItems;
+    static getSingleton(): MenuManager {
+        if (!MenuManager.singleton) {
+            //初始化一个mainLand.
+            MenuManager.singleton = new MenuManager();
 
-  }
+        }
+        return MenuManager.singleton;
+    }
+
+    /**
+     * 获取到当前高亮的菜单
+     */
+    getSelectedKeys(): string[] {
+
+        let keys: string[] = this.getMenuItems()
+            .filter((menuItem: MenuItem, index: number) => {
+                return menuItem.active;
+            }).map((menuItem: MenuItem, index: number) => {
+                return menuItem.url;
+            });
+
+        return keys;
+    }
+
+    /**
+     * 高亮某个菜单
+     */
+    selectMenu(url: string) {
+
+        this.getMenuItems().forEach((menuItem: MenuItem, index: number) => {
+            menuItem.active = menuItem.url === url;
+        });
+
+    }
+
+    getMenuItems(): MenuItem[] {
+        let user: User = Moon.getSingleton().user;
+        let preference: Preference = Moon.getSingleton().preference;
+
+        let menuItems: MenuItem[] = [];
+
+        if (!preference.installed) {
+            menuItems = [
+                new MenuItem(Lang.t("layout.install"), '/install/index', ),
+            ];
+        } else if (user.role === UserRole.GUEST) {
+            menuItems = [
+                new MenuItem(Lang.t("user.login"), '/user/login', ),
+            ];
+        } else {
+            menuItems.push(new MenuItem(Lang.t("layout.allFiles"), '/matter/list', ))
+            menuItems.push(new MenuItem(Lang.t("layout.myShare"), '/share/list', ))
+            menuItems.push(new MenuItem(Lang.t("layout.bin"), '/bin/list', ))
+
+            if (user.role === UserRole.ADMINISTRATOR) {
+                menuItems.push(new MenuItem(Lang.t("layout.setting"), '/preference/index', ))
+                menuItems.push(new MenuItem(Lang.t("layout.dashboard"), '/dashboard/index', ))
+                menuItems.push(new MenuItem(Lang.t("layout.users"), `${Sun.getSingleton().isMobile ? '/mobile' : ''}/user/list`,
+                    ))
+            }
+            menuItems.push(new MenuItem(Lang.t("layout.logout"), '/user/logout', ))
+
+
+        }
+
+        return menuItems;
+
+    }
 
 }
diff --git a/src/common/model/base/Base.ts b/src/common/model/base/Base.ts
index 10045d6..92e20e1 100644
--- a/src/common/model/base/Base.ts
+++ b/src/common/model/base/Base.ts
@@ -9,137 +9,137 @@ import DateUtil from "../../util/DateUtil";
  */
 export default class Base {
 
-  //id自增长值
-  private static AUTO_INCREMENT_ID = 0
+    //id自增长值
+    private static AUTO_INCREMENT_ID = 0
 
-  //当前对象的ID,这个字段让我们可以很轻松的统计出共创建了多少个实体类。
-  autoId: number = 0
+    //当前对象的ID,这个字段让我们可以很轻松的统计出共创建了多少个实体类。
+    autoId: number = 0
 
 
-  //我们认为每个实体都会存放于某个react组件中,当然可以不传入。
-  constructor() {
+    //我们认为每个实体都会存放于某个react组件中,当然可以不传入。
+    constructor() {
 
-    this.autoId = Base.generateAutoId()
-  }
-
-  static generateAutoId() {
-    Base.AUTO_INCREMENT_ID++
-    return Base.AUTO_INCREMENT_ID
-  }
-
-
-  //把obj中的属性,赋值到this中来。采用深拷贝。
-  assign(obj: any) {
-    ObjectUtil.extend(this, obj)
-  }
-
-  /**
-   *
-   * @param field 字段名
-   * @param Clazz 类型名
-   */
-  assignList(field: string, Clazz: any) {
-
-    ObjectUtil.assignList(this, field, Clazz)
-  }
-
-
-  /**
-   * 根据一个类型,渲染出对应的数组。
-   * @param json 字符串或者数组对象。
-   * @param Clazz 需要渲染的目标对象
-   * @returns {*}
-   */
-  static renderList(json: any, Clazz: any) {
-
-    let target: any = []
-
-
-    let arr: any = []
-
-    if (json instanceof String || typeof json === "string") {
-
-      arr = JsonUtil.parseList(json)
-
-    } else if (json instanceof Array) {
-      arr = json
-    } else {
-
-      console.error("源必须为字符或者数组", json, typeof json)
-      return target
+        this.autoId = Base.generateAutoId()
     }
 
-    //如果我们要转换成字符串的数组形式,那么this[field]应该是一个字符串才对。
-    if (Clazz === String) {
-      return arr
+    static generateAutoId() {
+        Base.AUTO_INCREMENT_ID++
+        return Base.AUTO_INCREMENT_ID
     }
 
-    if (!Clazz || !(Clazz.prototype instanceof Base)) {
-      console.error("指定的类型必须是 Base的子类 ")
-      return target
+
+    //把obj中的属性,赋值到this中来。采用深拷贝。
+    assign(obj: any) {
+        ObjectUtil.extend(this, obj)
     }
 
-    for (let i = 0; i < arr.length; i++) {
-      let bean = arr[i]
+    /**
+     *
+     * @param field 字段名
+     * @param Clazz 类型名
+     */
+    assignList(field: string, Clazz: any) {
 
-      let clazz = new Clazz()
-
-      clazz.assign(bean)
-
-      target.push(clazz)
+        ObjectUtil.assignList(this, field, Clazz)
     }
 
-    return target
-  }
 
-  //直接render出一个Entity. field字段名,Clazz类名。
-  assignEntity(field: any, Clazz: any) {
+    /**
+     * 根据一个类型,渲染出对应的数组。
+     * @param json 字符串或者数组对象。
+     * @param Clazz 需要渲染的目标对象
+     * @returns {*}
+     */
+    static renderList(json: any, Clazz: any) {
 
-    let thisObj: any = this
-
-    let obj: any = thisObj[field]
-    if (!obj) {
-      if (Clazz) {
-        let EntityClazz: any = this.constructor
-        obj = (new EntityClazz())[field]
-
-      } else {
-        return
-      }
-    }
-
-    if (Clazz === Date) {
-
-      thisObj[field] = DateUtil.str2Date(obj)
-
-    } else if (Clazz.prototype instanceof Base) {
-
-      //可能此处的该项属性做了特殊处理的。
-      //1024*1024 以及 "图片尺寸不超过1M"用let bean = new Clazz(); 就无法反映出来。因为父类assign的时候已经将avatar给变成了Object.
-      let bean = (new thisObj.constructor())[field]
-      if (!bean) {
-        bean = new Clazz()
-      }
+        let target: any = []
 
 
-      if (typeof obj === "string") {
-        try {
-          obj = JSON.parse(obj)
-        } catch (e) {
-          console.error("JSON parse obj error", e)
+        let arr: any = []
+
+        if (json instanceof String || typeof json === "string") {
+
+            arr = JsonUtil.parseList(json)
+
+        } else if (json instanceof Array) {
+            arr = json
+        } else {
+
+            console.error("源必须为字符或者数组", json, typeof json)
+            return target
         }
-      }
 
-      if (obj !== null) {
-        bean.assign(obj)
-        thisObj[field] = bean
-      }
+        //如果我们要转换成字符串的数组形式,那么this[field]应该是一个字符串才对。
+        if (Clazz === String) {
+            return arr
+        }
 
-    } else {
-      console.error('调用错误!')
+        if (!Clazz || !(Clazz.prototype instanceof Base)) {
+            console.error("指定的类型必须是 Base的子类 ")
+            return target
+        }
+
+        for (let i = 0; i < arr.length; i++) {
+            let bean = arr[i]
+
+            let clazz = new Clazz()
+
+            clazz.assign(bean)
+
+            target.push(clazz)
+        }
+
+        return target
     }
 
-  }
+    //直接render出一个Entity. field字段名,Clazz类名。
+    assignEntity(field: any, Clazz: any) {
+
+        let thisObj: any = this
+
+        let obj: any = thisObj[field]
+        if (!obj) {
+            if (Clazz) {
+                let EntityClazz: any = this.constructor
+                obj = (new EntityClazz())[field]
+
+            } else {
+                return
+            }
+        }
+
+        if (Clazz === Date) {
+
+            thisObj[field] = DateUtil.str2Date(obj)
+
+        } else if (Clazz.prototype instanceof Base) {
+
+            //可能此处的该项属性做了特殊处理的。
+            //1024*1024 以及 "图片尺寸不超过1M"用let bean = new Clazz(); 就无法反映出来。因为父类assign的时候已经将avatar给变成了Object.
+            let bean = (new thisObj.constructor())[field]
+            if (!bean) {
+                bean = new Clazz()
+            }
+
+
+            if (typeof obj === "string") {
+                try {
+                    obj = JSON.parse(obj)
+                } catch (e) {
+                    console.error("JSON parse obj error", e)
+                }
+            }
+
+            if (obj !== null) {
+                bean.assign(obj)
+                thisObj[field] = bean
+            }
+
+        } else {
+            console.error('调用错误!')
+        }
+
+    }
 
 
 }
diff --git a/src/common/model/base/BaseEntity.ts b/src/common/model/base/BaseEntity.ts
index 244849e..f088db7 100644
--- a/src/common/model/base/BaseEntity.ts
+++ b/src/common/model/base/BaseEntity.ts
@@ -11,213 +11,213 @@ import HttpBase from './HttpBase';
  */
 export default class BaseEntity extends HttpBase {
 
-  /**
-   * 唯一标识
-   */
-  uuid: string | null = null;
+    /**
+     * 唯一标识
+     */
+    uuid: string | null = null;
 
-  /**
-   * 排序值
-   */
-  sort: number = 0;
+    /**
+     * 排序值
+     */
+    sort: number = 0;
 
-  /**
-   * 创建时间
-   */
-  createTime: Date | null = null;
+    /**
+     * 创建时间
+     */
+    createTime: Date | null = null;
 
-  /**
-   * 修改时间
-   */
-  updateTime: Date | null = null;
+    /**
+     * 修改时间
+     */
+    updateTime: Date | null = null;
 
 
-  //************ 前端辅助字段 ****************/
-  //加载详情的指示
-  detailLoading: boolean = false;
+    //************ 前端辅助字段 ****************/
+    //加载详情的指示
+    detailLoading: boolean = false;
 
 
-  //我们认为每个实体都会存放于某个react组件中,当然可以不传入。
-  constructor(reactComponent?: React.Component | null) {
+    //我们认为每个实体都会存放于某个react组件中,当然可以不传入。
+    constructor(reactComponent?: React.Component | null) {
 
-    super(reactComponent);
+        super(reactComponent);
 
-  }
-
-  //把obj中的属性,赋值到this中来。采用深拷贝。
-  assign(obj: any) {
-    super.assign(obj);
-
-    this.assignEntity('createTime', Date);
-    this.assignEntity('updateTime', Date);
-
-  }
-
-  //获取过滤器,必须每次动态生成,否则会造成filter逻辑混乱。
-  getFilters(): Filter[] {
-    return [
-      new SortFilter('修改时间排序', 'orderCreateTime'),
-      new SortFilter('创建时间排序', 'orderUpdateTime'),
-    ];
-  };
-
-
-  //提交之前对自己进行验证。返回错误信息,null表示没有错误。
-  validate(): any {
-
-    return null;
-  }
-
-  //提交的表单
-  getForm(): any {
-    console.error('getForm: you should override this base method.');
-  }
-
-  //获取到当前类的单数标签。比如 Project便得到 project
-  getTAG(): string {
-
-    let className = this.constructor.name;
-
-    //IE无法直接通过this.constructor.name获取到相应名称
-    if (!className) {
-      className = StringUtil.functionName(this.constructor);
     }
 
-    return StringUtil.lowerCamel(className);
-  }
+    //把obj中的属性,赋值到this中来。采用深拷贝。
+    assign(obj: any) {
+        super.assign(obj);
+
+        this.assignEntity('createTime', Date);
+        this.assignEntity('updateTime', Date);
+
+    }
+
+    //获取过滤器,必须每次动态生成,否则会造成filter逻辑混乱。
+    getFilters(): Filter[] {
+        return [
+            new SortFilter('修改时间排序', 'orderCreateTime'),
+            new SortFilter('创建时间排序', 'orderUpdateTime'),
+        ];
+    };
 
 
-  //获取到当前实体的url前缀。比如Notification获取到 /api/fs/notification
-  getUrlPrefix(): string {
-    return '/api' + StringUtil.lowerSlash(this.getTAG());
-  }
+    //提交之前对自己进行验证。返回错误信息,null表示没有错误。
+    validate(): any {
 
+        return null;
+    }
 
-  getUrlCreate(): string {
-    let prefix = this.getUrlPrefix();
+    //提交的表单
+    getForm(): any {
+        console.error('getForm: you should override this base method.');
+    }
 
-    return prefix + '/create';
-  }
+    //获取到当前类的单数标签。比如 Project便得到 project
+    getTAG(): string {
 
-  getUrlDel(): string {
-    let prefix = this.getUrlPrefix();
+        let className = this.constructor.name;
 
-    return prefix + '/delete';
+        //IE无法直接通过this.constructor.name获取到相应名称
+        if (!className) {
+            className = StringUtil.functionName(this.constructor);
+        }
 
-  }
-
-  getUrlEdit(): string {
-    let prefix = this.getUrlPrefix();
-
-    return prefix + '/edit';
-  }
-
-  getUrlDetail(): string {
-    let prefix = this.getUrlPrefix();
-
-    return prefix + '/detail';
-  }
-
-  getUrlList(): string {
-    let prefix = this.getUrlPrefix();
-
-    return prefix + '/page';
-  }
-
-  getUrlSort(): string {
-    let prefix = this.getUrlPrefix();
-
-    return prefix + '/sort';
-  }
-
-
-  //新增或者修改
-  httpSave(successCallback?: any, errorCallback?: any, finallyCallback?: any) {
-
-    let that = this;
-
-    let url = this.getUrlCreate();
-    if (this.uuid) {
-      url = this.getUrlEdit();
+        return StringUtil.lowerCamel(className);
     }
 
 
-    this.errorMessage = this.validate();
-    if (this.errorMessage) {
-      that.defaultErrorHandler(this.errorMessage, errorCallback);
-      return;
+    //获取到当前实体的url前缀。比如Notification获取到 /api/fs/notification
+    getUrlPrefix(): string {
+        return '/api' + StringUtil.lowerSlash(this.getTAG());
     }
 
-    this.httpPost(url, this.getForm(), function(response: any) {
 
-      that.assign(response.data.data);
+    getUrlCreate(): string {
+        let prefix = this.getUrlPrefix();
 
-      SafeUtil.safeCallback(successCallback)(response);
-
-    }, errorCallback, finallyCallback);
-
-  }
-
-
-  //common http detail methods.
-  httpDetail(successCallback?: any, errorCallback?: any, finallyCallback?: any) {
-
-    let that = this;
-    if (!this.uuid) {
-
-      this.errorMessage = 'uuid未指定,无法获取到详情!';
-
-      this.defaultErrorHandler(this.errorMessage, errorCallback);
-
-      return;
+        return prefix + '/create';
     }
 
-    let url = this.getUrlDetail() + '?uuid=' + this.uuid;
+    getUrlDel(): string {
+        let prefix = this.getUrlPrefix();
 
-    this.detailLoading = true;
+        return prefix + '/delete';
 
-    this.httpGet(url, {}, function(response: any) {
-      that.detailLoading = false;
-
-      that.assign(response.data.data);
-
-      SafeUtil.safeCallback(successCallback)(response);
-
-    }, function(response: any) {
-
-      that.detailLoading = false;
-
-      if (typeof errorCallback === 'function') {
-        errorCallback(that.getErrorMessage(response), response);
-      } else {
-        //没有传入错误处理的方法就采用默认处理方法:toast弹出该错误信息。
-        that.defaultErrorHandler(response);
-      }
-    }, finallyCallback);
-
-  }
-
-
-  httpDel(successCallback?: any, errorCallback?: any, finallyCallback?: any) {
-
-    let that = this;
-    if (!this.uuid) {
-
-      this.errorMessage = '没有id,无法删除!';
-      that.defaultErrorHandler(this.errorMessage, errorCallback);
-
-      return;
     }
 
-    let url = this.getUrlDel() + '?uuid=' + this.uuid;
+    getUrlEdit(): string {
+        let prefix = this.getUrlPrefix();
 
-    this.httpPost(url, {}, function(response: any) {
+        return prefix + '/edit';
+    }
 
-      SafeUtil.safeCallback(successCallback)(response);
+    getUrlDetail(): string {
+        let prefix = this.getUrlPrefix();
 
-    }, errorCallback, finallyCallback);
+        return prefix + '/detail';
+    }
 
-  }
+    getUrlList(): string {
+        let prefix = this.getUrlPrefix();
+
+        return prefix + '/page';
+    }
+
+    getUrlSort(): string {
+        let prefix = this.getUrlPrefix();
+
+        return prefix + '/sort';
+    }
+
+
+    //新增或者修改
+    httpSave(successCallback?: any, errorCallback?: any, finallyCallback?: any) {
+
+        let that = this;
+
+        let url = this.getUrlCreate();
+        if (this.uuid) {
+            url = this.getUrlEdit();
+        }
+
+
+        this.errorMessage = this.validate();
+        if (this.errorMessage) {
+            that.defaultErrorHandler(this.errorMessage, errorCallback);
+            return;
+        }
+
+        this.httpPost(url, this.getForm(), function (response: any) {
+
+            that.assign(response.data.data);
+
+            SafeUtil.safeCallback(successCallback)(response);
+
+        }, errorCallback, finallyCallback);
+
+    }
+
+
+    //common http detail methods.
+    httpDetail(successCallback?: any, errorCallback?: any, finallyCallback?: any) {
+
+        let that = this;
+        if (!this.uuid) {
+
+            this.errorMessage = 'uuid未指定,无法获取到详情!';
+
+            this.defaultErrorHandler(this.errorMessage, errorCallback);
+
+            return;
+        }
+
+        let url = this.getUrlDetail() + '?uuid=' + this.uuid;
+
+        this.detailLoading = true;
+
+        this.httpGet(url, {}, function (response: any) {
+            that.detailLoading = false;
+
+            that.assign(response.data.data);
+
+            SafeUtil.safeCallback(successCallback)(response);
+
+        }, function (response: any) {
+
+            that.detailLoading = false;
+
+            if (typeof errorCallback === 'function') {
+                errorCallback(that.getErrorMessage(response), response);
+            } else {
+                //没有传入错误处理的方法就采用默认处理方法:toast弹出该错误信息。
+                that.defaultErrorHandler(response);
+            }
+        }, finallyCallback);
+
+    }
+
+
+    httpDel(successCallback?: any, errorCallback?: any, finallyCallback?: any) {
+
+        let that = this;
+        if (!this.uuid) {
+
+            this.errorMessage = '没有id,无法删除!';
+            that.defaultErrorHandler(this.errorMessage, errorCallback);
+
+            return;
+        }
+
+        let url = this.getUrlDel() + '?uuid=' + this.uuid;
+
+        this.httpPost(url, {}, function (response: any) {
+
+            SafeUtil.safeCallback(successCallback)(response);
+
+        }, errorCallback, finallyCallback);
+
+    }
 
 
 }
diff --git a/src/common/model/base/HttpBase.ts b/src/common/model/base/HttpBase.ts
index d231983..61f9d96 100644
--- a/src/common/model/base/HttpBase.ts
+++ b/src/common/model/base/HttpBase.ts
@@ -13,275 +13,275 @@ import MessageBoxUtil from "../../util/MessageBoxUtil";
  */
 export default class HttpBase extends ViewBase {
 
-  static lastLoginErrorTimestamp = 0
+    static lastLoginErrorTimestamp = 0
 
-  //是否需要自动刷新State
-  needReactComponentUpdate: boolean = true
+    //是否需要自动刷新State
+    needReactComponentUpdate: boolean = true
 
-  //当前是否正在进行http请求
-  loading: boolean = false
+    //当前是否正在进行http请求
+    loading: boolean = false
 
-  //请求http的时候是否有错误
-  errorMessage: string | null = null
+    //请求http的时候是否有错误
+    errorMessage: string | null = null
 
-  //我们认为每个实体都会存放于某个react组件中,当然可以不传入。
-  constructor(reactComponent?: React.Component | null) {
+    //我们认为每个实体都会存放于某个react组件中,当然可以不传入。
+    constructor(reactComponent?: React.Component | null) {
 
-    super()
+        super()
 
-    if (reactComponent) {
-      this.reactComponent = reactComponent
-    }
-
-  }
-
-
-  //更新当前的视图,只在需要更新的情况下才更新。
-  updateUI() {
-    if (this.needReactComponentUpdate && this.reactComponent) {
-      ViewBase.updateComponentUI(this.reactComponent, this)
-    }
-  }
-
-
-  /**
-   * 转跳到登录页面
-   */
-  jumpLogin() {
-
-    Sun.navigateTo("/user/login")
-
-
-  }
-
-  /**
-   * 转跳到网站安装页面
-   */
-  jumpInstall() {
-
-    Sun.navigateTo("/install/index")
-
-  }
-
-  //从一个返回中获取出其错误信息。适配各种错误的类型。
-  getErrorMessage(response: any) {
-
-    console.error("getErrorMessage", response)
-    let msg = '服务器出错,请稍后再试!'
-
-    if (!response) {
-      msg = '出错啦,请稍后重试!'
-    } else if (typeof response === 'string') {
-      msg = response
-    } else if (response['msg']) {
-      msg = response['msg']
-    } else if (response['message']) {
-      msg = response['message']
-    } else {
-      let temp = response['data']
-      if (temp !== null && typeof temp === 'object') {
-        if (temp['message']) {
-          msg = temp['message']
-        } else if (temp['msg']) {
-          msg = temp['msg']
-        } else {
-          if (temp['error'] && temp['error']['message']) {
-            msg = temp['error']['message']
-          }
+        if (reactComponent) {
+            this.reactComponent = reactComponent
         }
-      }
-    }
-    this.errorMessage = msg
-    return msg
-  }
 
-
-  //提供全局的默认处理方式,可以自定义错误处理
-  defaultErrorHandler(response: any, errorCallback?: any) {
-
-    let msg = this.getErrorMessage(response)
-
-    console.error("请求出错了", typeof msg, msg)
-
-    if (typeof errorCallback === 'function') {
-      errorCallback(msg, response)
-    } else {
-      MessageBoxUtil.error(msg)
-    }
-
-  }
-
-
-  //专门捕捉没有登录这种错误。return true -> 有错误(已经处理掉了)  false -> 没错误 (什么都没干)
-  specialErrorHandler(response: any) {
-
-    if (!response || !response.data) {
-      return false
-    }
-
-    //1.判断是不是登录错误
-    if (response.data["code"] === WebResultCode.LOGIN) {
-
-      //这个问题不能报的太频繁,比如一个页面请求了两个接口,两个接口都报没有登录。
-      if ((new Date().getTime()) - HttpBase.lastLoginErrorTimestamp < 3000) {
-        return true
-      } else {
-        HttpBase.lastLoginErrorTimestamp = (new Date().getTime());
-      }
-
-      MessageBoxUtil.error("您尚未登录,请登录后访问!")
-
-      //立即进行登录跳转。
-      this.jumpLogin()
-
-      return true;
     }
 
 
-    return false
-
-  }
-
-
-  /**
-   * 基类中的http请求会去统一处理错误情况。
-   * 1.登录过期
-   *
-   */
-  httpGet(url: any, params = {}, successCallback?: any, errorCallback?: any, finallyCallback?: any, opts?: any) {
-
-    let that = this
-
-    if (!opts) {
-      opts = {}
+    //更新当前的视图,只在需要更新的情况下才更新。
+    updateUI() {
+        if (this.needReactComponentUpdate && this.reactComponent) {
+            ViewBase.updateComponentUI(this.reactComponent, this)
+        }
     }
 
 
-    that.loading = true
+    /**
+     * 转跳到登录页面
+     */
+    jumpLogin() {
 
-    //更新react控件的状态
-    that.updateUI()
-
-    return HttpUtil.httpGet(url, params, function (response: any) {
-      //有可能正常接口回来的数据也是错误的。交给错误处理器处理。
-      if (that.specialErrorHandler(response)) {
-
-        SafeUtil.safeCallback(errorCallback)(response)
-        return
-      }
+        Sun.navigateTo("/user/login")
 
 
-      SafeUtil.safeCallback(successCallback)(response)
-
-    }, function (err: any) {
-
-      let response = err.response
-      console.error("请求出错啦", response)
-
-      //特殊错误情况的通用处理方式
-      if (that.specialErrorHandler(response)) {
-        return
-      }
-
-
-      that.defaultErrorHandler(response, errorCallback)
-
-    }, function (res: any) {
-
-      that.loading = false
-
-      //更新react控件的状态
-      that.updateUI()
-
-      SafeUtil.safeCallback(finallyCallback)(res)
-
-    }, opts);
-  }
-
-  /**
-   * 基类中纯粹的http get请求。
-   *
-   */
-  httpPureGet(url: any, params = {}, successCallback?: any, errorCallback?: any, finallyCallback?: any, opts?: any) {
-
-    let that = this
-
-    if (!opts) {
-      opts = {}
     }
 
-    return HttpUtil.httpGet(url, params, function (response: any) {
-      SafeUtil.safeCallback(successCallback)(response)
-    }, function (err: any) {
-      SafeUtil.safeCallback(errorCallback)(that.getErrorMessage(err.response))
-    }, function (res: any) {
-      SafeUtil.safeCallback(finallyCallback)(res)
-    }, opts);
-  }
+    /**
+     * 转跳到网站安装页面
+     */
+    jumpInstall() {
 
+        Sun.navigateTo("/install/index")
 
-  /**
-   * 基类中的http请求会去统一处理错误情况。
-   * 1.登录过期
-   *
-   */
-  httpPost(url: any, params = {}, successCallback?: any, errorCallback?: any, finallyCallback?: any, opts?: any) {
-
-    let that = this
-
-    if (!opts) {
-      opts = {}
     }
 
-    that.loading = true
+    //从一个返回中获取出其错误信息。适配各种错误的类型。
+    getErrorMessage(response: any) {
 
-    //更新react控件的状态
-    that.updateUI()
+        console.error("getErrorMessage", response)
+        let msg = '服务器出错,请稍后再试!'
 
-
-    let formData = qs.stringify(params);
-
-    if (!opts["headers"]) {
-      opts["headers"] = {}
+        if (!response) {
+            msg = '出错啦,请稍后重试!'
+        } else if (typeof response === 'string') {
+            msg = response
+        } else if (response['msg']) {
+            msg = response['msg']
+        } else if (response['message']) {
+            msg = response['message']
+        } else {
+            let temp = response['data']
+            if (temp !== null && typeof temp === 'object') {
+                if (temp['message']) {
+                    msg = temp['message']
+                } else if (temp['msg']) {
+                    msg = temp['msg']
+                } else {
+                    if (temp['error'] && temp['error']['message']) {
+                        msg = temp['error']['message']
+                    }
+                }
+            }
+        }
+        this.errorMessage = msg
+        return msg
     }
-    opts["headers"]['Content-Type'] = 'application/x-www-form-urlencoded'
 
 
-    return HttpUtil.httpPost(url, formData, function (response: any) {
+    //提供全局的默认处理方式,可以自定义错误处理
+    defaultErrorHandler(response: any, errorCallback?: any) {
 
-      //有可能正常接口回来的数据也是错误的。交给错误处理器处理。
-      if (that.specialErrorHandler(response)) {
+        let msg = this.getErrorMessage(response)
 
-        SafeUtil.safeCallback(errorCallback)(response)
-        return
-      }
+        console.error("请求出错了", typeof msg, msg)
 
-      SafeUtil.safeCallback(successCallback)(response)
+        if (typeof errorCallback === 'function') {
+            errorCallback(msg, response)
+        } else {
+            MessageBoxUtil.error(msg)
+        }
 
-    }, function (err: any) {
+    }
 
-      let response = err.response
 
-      console.error("请求出错啦", response ? response : err)
+    //专门捕捉没有登录这种错误。return true -> 有错误(已经处理掉了)  false -> 没错误 (什么都没干)
+    specialErrorHandler(response: any) {
 
-      //特殊错误情况的通用处理方式
-      if (that.specialErrorHandler(response)) {
-        return
-      }
+        if (!response || !response.data) {
+            return false
+        }
 
-      that.defaultErrorHandler(response, errorCallback)
+        //1.判断是不是登录错误
+        if (response.data["code"] === WebResultCode.LOGIN) {
 
-    }, function (res: any) {
+            //这个问题不能报的太频繁,比如一个页面请求了两个接口,两个接口都报没有登录。
+            if ((new Date().getTime()) - HttpBase.lastLoginErrorTimestamp < 3000) {
+                return true
+            } else {
+                HttpBase.lastLoginErrorTimestamp = (new Date().getTime());
+            }
 
-      that.loading = false
+            MessageBoxUtil.error("您尚未登录,请登录后访问!")
 
-      //更新react控件的状态
-      that.updateUI()
+            //立即进行登录跳转。
+            this.jumpLogin()
 
-      SafeUtil.safeCallback(finallyCallback)(res)
+            return true;
+        }
 
-    }, opts);
-  }
+
+        return false
+
+    }
+
+
+    /**
+     * 基类中的http请求会去统一处理错误情况。
+     * 1.登录过期
+     *
+     */
+    httpGet(url: any, params = {}, successCallback?: any, errorCallback?: any, finallyCallback?: any, opts?: any) {
+
+        let that = this
+
+        if (!opts) {
+            opts = {}
+        }
+
+
+        that.loading = true
+
+        //更新react控件的状态
+        that.updateUI()
+
+        return HttpUtil.httpGet(url, params, function (response: any) {
+            //有可能正常接口回来的数据也是错误的。交给错误处理器处理。
+            if (that.specialErrorHandler(response)) {
+
+                SafeUtil.safeCallback(errorCallback)(response)
+                return
+            }
+
+
+            SafeUtil.safeCallback(successCallback)(response)
+
+        }, function (err: any) {
+
+            let response = err.response
+            console.error("请求出错啦", response)
+
+            //特殊错误情况的通用处理方式
+            if (that.specialErrorHandler(response)) {
+                return
+            }
+
+
+            that.defaultErrorHandler(response, errorCallback)
+
+        }, function (res: any) {
+
+            that.loading = false
+
+            //更新react控件的状态
+            that.updateUI()
+
+            SafeUtil.safeCallback(finallyCallback)(res)
+
+        }, opts);
+    }
+
+    /**
+     * 基类中纯粹的http get请求。
+     *
+     */
+    httpPureGet(url: any, params = {}, successCallback?: any, errorCallback?: any, finallyCallback?: any, opts?: any) {
+
+        let that = this
+
+        if (!opts) {
+            opts = {}
+        }
+
+        return HttpUtil.httpGet(url, params, function (response: any) {
+            SafeUtil.safeCallback(successCallback)(response)
+        }, function (err: any) {
+            SafeUtil.safeCallback(errorCallback)(that.getErrorMessage(err.response))
+        }, function (res: any) {
+            SafeUtil.safeCallback(finallyCallback)(res)
+        }, opts);
+    }
+
+
+    /**
+     * 基类中的http请求会去统一处理错误情况。
+     * 1.登录过期
+     *
+     */
+    httpPost(url: any, params = {}, successCallback?: any, errorCallback?: any, finallyCallback?: any, opts?: any) {
+
+        let that = this
+
+        if (!opts) {
+            opts = {}
+        }
+
+        that.loading = true
+
+        //更新react控件的状态
+        that.updateUI()
+
+
+        let formData = qs.stringify(params);
+
+        if (!opts["headers"]) {
+            opts["headers"] = {}
+        }
+        opts["headers"]['Content-Type'] = 'application/x-www-form-urlencoded'
+
+
+        return HttpUtil.httpPost(url, formData, function (response: any) {
+
+            //有可能正常接口回来的数据也是错误的。交给错误处理器处理。
+            if (that.specialErrorHandler(response)) {
+
+                SafeUtil.safeCallback(errorCallback)(response)
+                return
+            }
+
+            SafeUtil.safeCallback(successCallback)(response)
+
+        }, function (err: any) {
+
+            let response = err.response
+
+            console.error("请求出错啦", response ? response : err)
+
+            //特殊错误情况的通用处理方式
+            if (that.specialErrorHandler(response)) {
+                return
+            }
+
+            that.defaultErrorHandler(response, errorCallback)
+
+        }, function (res: any) {
+
+            that.loading = false
+
+            //更新react控件的状态
+            that.updateUI()
+
+            SafeUtil.safeCallback(finallyCallback)(res)
+
+        }, opts);
+    }
 
 
 }
diff --git a/src/common/model/base/Pager.ts b/src/common/model/base/Pager.ts
index d18747b..55263e8 100644
--- a/src/common/model/base/Pager.ts
+++ b/src/common/model/base/Pager.ts
@@ -14,416 +14,416 @@ import HttpBase from './HttpBase';
  */
 export default class Pager extends HttpBase {
 
-  static MAX_PAGE_SIZE = 500;
+    static MAX_PAGE_SIZE = 500;
 
-  /**
-   * 当前分页大小 0基
-   */
-  page: number = 0;
-  /**
-   * 每一页的大小
-   */
-  pageSize: number = 10;
-  /**
-   * 总的条目数量
-   */
-  totalItems: number = 0;
-  /**
-   * 总的页数
-   */
-  totalPages: number = 0;
+    /**
+     * 当前分页大小 0基
+     */
+    page: number = 0;
+    /**
+     * 每一页的大小
+     */
+    pageSize: number = 10;
+    /**
+     * 总的条目数量
+     */
+    totalItems: number = 0;
+    /**
+     * 总的页数
+     */
+    totalPages: number = 0;
 
-  /**
-   * 返回的数据,类型为泛型
-   */
-  data: T[] = [];
+    /**
+     * 返回的数据,类型为泛型
+     */
+    data: T[] = [];
 
-  /**
-   * 类。这个很特殊。
-   */
-  Clazz: any = null;
+    /**
+     * 类。这个很特殊。
+     */
+    Clazz: any = null;
 
-  /**
-   * 分页的url链接地址
-   */
-  urlPage: string | null = null;
+    /**
+     * 分页的url链接地址
+     */
+    urlPage: string | null = null;
 
-  /**
-   * 过滤筛选器
-   */
-  filters: Filter[] = [];
+    /**
+     * 过滤筛选器
+     */
+    filters: Filter[] = [];
 
-  /**
-   * 是否要求在浏览器中保存参数
-   */
-  history: boolean = false;
+    /**
+     * 是否要求在浏览器中保存参数
+     */
+    history: boolean = false;
 
 
-  constructor(reactComponent: React.Component | null, Clazz: any, pageSize = 20) {
+    constructor(reactComponent: React.Component | null, Clazz: any, pageSize = 20) {
 
-    super(reactComponent);
+        super(reactComponent);
 
-    this.pageSize = pageSize;
+        this.pageSize = pageSize;
 
-    //这里的处理利用了js的原型调用链,比较魔法。
-    if (Clazz && (Clazz.prototype instanceof BaseEntity)) {
-      this.Clazz = Clazz;
+        //这里的处理利用了js的原型调用链,比较魔法。
+        if (Clazz && (Clazz.prototype instanceof BaseEntity)) {
+            this.Clazz = Clazz;
 
-      let urlPage = Clazz.prototype.getUrlList();
-      if (urlPage) {
-        this.urlPage = urlPage;
-      } else {
-        console.error(Clazz + '必须定义分页url');
-      }
+            let urlPage = Clazz.prototype.getUrlList();
+            if (urlPage) {
+                this.urlPage = urlPage;
+            } else {
+                console.error(Clazz + '必须定义分页url');
+            }
 
-      if (Clazz.prototype.getFilters) {
+            if (Clazz.prototype.getFilters) {
 
-        //直接获取该类的过滤器。
-        this.filters = Clazz.prototype.getFilters();
+                //直接获取该类的过滤器。
+                this.filters = Clazz.prototype.getFilters();
 
-      } else {
+            } else {
 
-        console.error('The Clazz MUST define a prototype method named \'getFilters\'');
+                console.error('The Clazz MUST define a prototype method named \'getFilters\'');
 
-      }
+            }
 
-    } else {
-      console.error('You MUST specify a Clazz extended BaseEntity');
-    }
-  }
-
-  //把obj中的属性,赋值到this中来。采用深拷贝。
-  assign(obj: any) {
-
-    super.assign(obj);
-
-    this.assignList('data', this.Clazz);
-
-  }
-
-
-  //该方法是在地址栏添加上query参数,参数就是filters中的key和value.
-  //同时地址栏上有的参数也会自动读取到filters中去
-  //因此,启用该方法后返回时可以停留在之前的页码中。
-  enableHistory() {
-    this.history = true;
-
-    let queryPageNum: string | null = BrowserUtil.getQueryByName('page');
-    let queryPageSize: string | null = BrowserUtil.getQueryByName('pageSize');
-
-    if (queryPageNum !== null && queryPageNum !== '') {
-      this.page = parseInt(queryPageNum);
-    }
-
-    if (queryPageSize !== null && queryPageSize !== '') {
-      this.pageSize = parseInt(queryPageSize);
-    }
-
-    if (!NumberUtil.isInteger(this.page)) {
-      this.page = 0;
-    }
-    if (!NumberUtil.isInteger(this.pageSize)) {
-      this.pageSize = 10;
-    }
-
-
-    //从请求参数中传值。
-    for (let i = 0; i < this.filters.length; i++) {
-
-      let filter: Filter = this.filters[i];
-
-      let queryValue = BrowserUtil.getQueryByName(filter.key);
-
-      if (queryValue !== null && queryValue !== '') {
-
-        filter.putValue(queryValue);
-
-      } else {
-        filter.reset();
-      }
-    }
-  }
-
-
-  //重置所有过滤器
-  resetFilter() {
-    for (let i = 0; i < this.filters.length; i++) {
-      let filter = this.filters[i];
-      filter.reset();
-    }
-  };
-
-  //重置排序过滤器
-  resetSortFilters() {
-    for (let i = 0; i < this.filters.length; i++) {
-      let filter = this.filters[i];
-      if (filter instanceof SortFilter) {
-        filter.reset();
-      }
-    }
-  };
-
-
-  //手动设置过滤器的值
-  setFilterValue(key: string, value: any) {
-    if (!this.filters || !this.filters.length) {
-      return;
-    }
-
-    for (let i = 0; i < this.filters.length; i++) {
-
-      let filter = this.filters[i];
-
-      if (filter.key === key) {
-        filter.putValue(value);
-      }
-
-    }
-  };
-
-  setFilterValues(obj: any) {
-    const keys = Object.keys(obj);
-    if(keys.length) {
-      keys.forEach(key => this.setFilterValue(key, obj[key]))
-    }
-  };
-
-
-  //根据key来删除某个Filter
-  removeFilter(key: string) {
-    if (!this.filters || !this.filters.length) {
-      return;
-    }
-    for (let i = 0; i < this.filters.length; i++) {
-      let filter = this.filters[i];
-      if (filter.key === key) {
-        this.filters.splice(i, 1);
-        break;
-      }
-    }
-  };
-
-
-  //隐藏某个Filter,实际上我们可以根据这个filter来筛选,只不过不出现在NbFilter中而已。
-  showFilter(key: string, visible = true) {
-    if (!this.filters || !this.filters.length) {
-      return;
-    }
-    for (let i = 0; i < this.filters.length; i++) {
-      let filter = this.filters[i];
-      if (filter.key === key) {
-        filter.visible = visible;
-        break;
-      }
-    }
-  };
-
-  showAllFilter(visible = true) {
-    if (!this.filters || !this.filters.length) {
-      return;
-    }
-    for (let i = 0; i < this.filters.length; i++) {
-      let filter = this.filters[i];
-      filter.visible = visible;
-    }
-  }
-
-  //根据一个key来获取某个filter
-  getFilter(key: string): Filter | null {
-    if (!this.filters || !this.filters.length) {
-      return null;
-    }
-
-    for (let i = 0; i < this.filters.length; i++) {
-      let filter = this.filters[i];
-      if (filter.key === key) {
-        return filter;
-      }
-    }
-
-    return null;
-  };
-
-  //根据一个key来获取某个filter
-  getFilterValue(key: string) {
-    let filter = this.getFilter(key);
-    if (!filter) {
-      return null
-    } else {
-      return filter.getValueString()
-    }
-  };
-
-
-  /**
-   * 获取当前进行sort的那个filter
-   * 我们认为一次只有一个排序值
-   */
-  getCurrentSortFilter(): Filter | null {
-
-    if (!this.filters || !this.filters.length) {
-      return null;
-    }
-
-    for (let i = 0; i < this.filters.length; i++) {
-      let filter = this.filters[i];
-      if (filter instanceof SortFilter) {
-        if (!filter.isEmpty()) {
-          return filter;
+        } else {
+            console.error('You MUST specify a Clazz extended BaseEntity');
         }
-      }
+    }
+
+    //把obj中的属性,赋值到this中来。采用深拷贝。
+    assign(obj: any) {
+
+        super.assign(obj);
+
+        this.assignList('data', this.Clazz);
 
     }
-    return null;
-  }
 
 
-  //获取所有的filter参数,键值对形式
-  getParams(): { [s: string]: string | number } {
+    //该方法是在地址栏添加上query参数,参数就是filters中的key和value.
+    //同时地址栏上有的参数也会自动读取到filters中去
+    //因此,启用该方法后返回时可以停留在之前的页码中。
+    enableHistory() {
+        this.history = true;
 
-    let params: { [s: string]: string | number } = {
-      page: this.page,
-      pageSize: this.pageSize,
+        let queryPageNum: string | null = BrowserUtil.getQueryByName('page');
+        let queryPageSize: string | null = BrowserUtil.getQueryByName('pageSize');
+
+        if (queryPageNum !== null && queryPageNum !== '') {
+            this.page = parseInt(queryPageNum);
+        }
+
+        if (queryPageSize !== null && queryPageSize !== '') {
+            this.pageSize = parseInt(queryPageSize);
+        }
+
+        if (!NumberUtil.isInteger(this.page)) {
+            this.page = 0;
+        }
+        if (!NumberUtil.isInteger(this.pageSize)) {
+            this.pageSize = 10;
+        }
+
+
+        //从请求参数中传值。
+        for (let i = 0; i < this.filters.length; i++) {
+
+            let filter: Filter = this.filters[i];
+
+            let queryValue = BrowserUtil.getQueryByName(filter.key);
+
+            if (queryValue !== null && queryValue !== '') {
+
+                filter.putValue(queryValue);
+
+            } else {
+                filter.reset();
+            }
+        }
+    }
+
+
+    //重置所有过滤器
+    resetFilter() {
+        for (let i = 0; i < this.filters.length; i++) {
+            let filter = this.filters[i];
+            filter.reset();
+        }
     };
 
-    if (!this.filters || !this.filters.length) {
-      return params;
+    //重置排序过滤器
+    resetSortFilters() {
+        for (let i = 0; i < this.filters.length; i++) {
+            let filter = this.filters[i];
+            if (filter instanceof SortFilter) {
+                filter.reset();
+            }
+        }
+    };
+
+
+    //手动设置过滤器的值
+    setFilterValue(key: string, value: any) {
+        if (!this.filters || !this.filters.length) {
+            return;
+        }
+
+        for (let i = 0; i < this.filters.length; i++) {
+
+            let filter = this.filters[i];
+
+            if (filter.key === key) {
+                filter.putValue(value);
+            }
+
+        }
+    };
+
+    setFilterValues(obj: any) {
+        const keys = Object.keys(obj);
+        if (keys.length) {
+            keys.forEach(key => this.setFilterValue(key, obj[key]))
+        }
+    };
+
+
+    //根据key来删除某个Filter
+    removeFilter(key: string) {
+        if (!this.filters || !this.filters.length) {
+            return;
+        }
+        for (let i = 0; i < this.filters.length; i++) {
+            let filter = this.filters[i];
+            if (filter.key === key) {
+                this.filters.splice(i, 1);
+                break;
+            }
+        }
+    };
+
+
+    //隐藏某个Filter,实际上我们可以根据这个filter来筛选,只不过不出现在NbFilter中而已。
+    showFilter(key: string, visible = true) {
+        if (!this.filters || !this.filters.length) {
+            return;
+        }
+        for (let i = 0; i < this.filters.length; i++) {
+            let filter = this.filters[i];
+            if (filter.key === key) {
+                filter.visible = visible;
+                break;
+            }
+        }
+    };
+
+    showAllFilter(visible = true) {
+        if (!this.filters || !this.filters.length) {
+            return;
+        }
+        for (let i = 0; i < this.filters.length; i++) {
+            let filter = this.filters[i];
+            filter.visible = visible;
+        }
     }
 
-    for (let i = 0; i < this.filters.length; i++) {
-      let filter = this.filters[i];
+    //根据一个key来获取某个filter
+    getFilter(key: string): Filter | null {
+        if (!this.filters || !this.filters.length) {
+            return null;
+        }
 
-      if (!filter.isEmpty()) {
-        params[filter.key] = filter.getValueString();
-      }
-    }
+        for (let i = 0; i < this.filters.length; i++) {
+            let filter = this.filters[i];
+            if (filter.key === key) {
+                return filter;
+            }
+        }
 
-    return params;
-  };
+        return null;
+    };
+
+    //根据一个key来获取某个filter
+    getFilterValue(key: string) {
+        let filter = this.getFilter(key);
+        if (!filter) {
+            return null
+        } else {
+            return filter.getValueString()
+        }
+    };
 
 
-  //元素是否为空
-  isEmpty(): boolean {
-    return !this.data || !this.data.length;
-  }
+    /**
+     * 获取当前进行sort的那个filter
+     * 我们认为一次只有一个排序值
+     */
+    getCurrentSortFilter(): Filter | null {
 
-  //去服务器端进行请求
-  httpList(successCallback?: any, errorCallback?: any, finalCallback?: any) {
+        if (!this.filters || !this.filters.length) {
+            return null;
+        }
 
-    let that = this;
+        for (let i = 0; i < this.filters.length; i++) {
+            let filter = this.filters[i];
+            if (filter instanceof SortFilter) {
+                if (!filter.isEmpty()) {
+                    return filter;
+                }
+            }
 
-    let params: { [s: string]: string | number } = this.getParams();
-
-
-    if (this.history) {
-      window.history.replaceState({}, '', window.location.pathname + '?' + ObjectUtil.param(params));
+        }
+        return null;
     }
 
 
-    //准备去请求,所有错误置为空
-    this.errorMessage = null;
+    //获取所有的filter参数,键值对形式
+    getParams(): { [s: string]: string | number } {
 
-    this.httpGet(this.urlPage, params, function(response: any) {
-      // handle success
+        let params: { [s: string]: string | number } = {
+            page: this.page,
+            pageSize: this.pageSize,
+        };
 
-      that.assign(response.data.data);
+        if (!this.filters || !this.filters.length) {
+            return params;
+        }
 
-      SafeUtil.safeCallback(successCallback)(response);
+        for (let i = 0; i < this.filters.length; i++) {
+            let filter = this.filters[i];
 
-    }, function(errorMessage: any, response: any) {
+            if (!filter.isEmpty()) {
+                params[filter.key] = filter.getValueString();
+            }
+        }
 
-      //失败了就清空
-      that.data = [];
-
-      SafeUtil.safeCallback(errorCallback)(errorMessage, response);
-
-    }, finalCallback);
-
-  }
+        return params;
+    };
 
 
-  //从pager中获取当前的分页情况,在table的分页器中显示 PaginationConfig
-  getPagination(): any | false {
-    let that = this;
+    //元素是否为空
+    isEmpty(): boolean {
+        return !this.data || !this.data.length;
+    }
+
+    //去服务器端进行请求
+    httpList(successCallback?: any, errorCallback?: any, finalCallback?: any) {
+
+        let that = this;
+
+        let params: { [s: string]: string | number } = this.getParams();
+
+
+        if (this.history) {
+            window.history.replaceState({}, '', window.location.pathname + '?' + ObjectUtil.param(params));
+        }
+
+
+        //准备去请求,所有错误置为空
+        this.errorMessage = null;
+
+        this.httpGet(this.urlPage, params, function (response: any) {
+            // handle success
+
+            that.assign(response.data.data);
+
+            SafeUtil.safeCallback(successCallback)(response);
+
+        }, function (errorMessage: any, response: any) {
+
+            //失败了就清空
+            that.data = [];
+
+            SafeUtil.safeCallback(errorCallback)(errorMessage, response);
+
+        }, finalCallback);
 
-    if (this.totalPages > 1) {
-      return {
-        current: that.page + 1,
-        pageSize: that.pageSize,
-        total: that.totalItems,
-        showTotal: (totalNum: number) => '共' + totalNum + '条',
-        showSizeChanger: true,
-      };
-    } else {
-      return false;
     }
 
 
-  }
+    //从pager中获取当前的分页情况,在table的分页器中显示 PaginationConfig
+    getPagination(): any | false {
+        let that = this;
 
-  //获取默认的排序顺序,提供给table使用
-  getDefaultSortOrder(columnKey: string): any | boolean {
+        if (this.totalPages > 1) {
+            return {
+                current: that.page + 1,
+                pageSize: that.pageSize,
+                total: that.totalItems,
+                showTotal: (totalNum: number) => '共' + totalNum + '条',
+                showSizeChanger: true,
+            };
+        } else {
+            return false;
+        }
 
-    //将变化的这个情况更新。
-    let filterKey = 'order' + StringUtil.capitalize(columnKey);
-
-    //直接放进排序值即可,底层会自动兼容
-    let sortFilter = this.getFilter(filterKey);
-
-    if (sortFilter && (sortFilter instanceof SortFilter)) {
-
-      let antdSortValue: any | null = sortFilter.getAntdValue();
-      if (antdSortValue) {
-        return antdSortValue;
-      } else {
-        return false;
-      }
-
-    } else {
-      return false;
-    }
-
-  }
-
-
-  //在table的分页器 发生变化调用 TODO: PaginationConfig SorterResult TableCurrentDataSource
-  tableOnChange(pagination: any, filters: any, sorter: any, extra: any) {
-    let that = this;
-
-    if (pagination.current !== undefined) {
-      that.page = pagination.current - 1;
-    }
-
-    if (pagination.pageSize !== undefined) {
-
-      that.pageSize = pagination.pageSize;
-    }
-
-
-    //重置所有的sort
-    that.resetSortFilters();
-    if (!StringUtil.isEmptyObject(sorter)) {
-
-      //将变化的这个情况更新。
-      let filterKey = 'order' + StringUtil.capitalize(StringUtil.underScoreToCamel(sorter.field));
-
-
-      //直接放进排序值即可,底层会自动兼容
-      that.setFilterValue(filterKey, sorter.order);
 
     }
 
-    //直接去刷新
-    that.httpList();
-  }
+    //获取默认的排序顺序,提供给table使用
+    getDefaultSortOrder(columnKey: string): any | boolean {
 
-  //清空data中的数据。
-  clear() {
-    this.data = [];
-    this.page = 0;
-    this.totalItems = 0;
-    this.totalPages = 0;
-  }
+        //将变化的这个情况更新。
+        let filterKey = 'order' + StringUtil.capitalize(columnKey);
+
+        //直接放进排序值即可,底层会自动兼容
+        let sortFilter = this.getFilter(filterKey);
+
+        if (sortFilter && (sortFilter instanceof SortFilter)) {
+
+            let antdSortValue: any | null = sortFilter.getAntdValue();
+            if (antdSortValue) {
+                return antdSortValue;
+            } else {
+                return false;
+            }
+
+        } else {
+            return false;
+        }
+
+    }
+
+
+    //在table的分页器 发生变化调用 TODO: PaginationConfig SorterResult TableCurrentDataSource
+    tableOnChange(pagination: any, filters: any, sorter: any, extra: any) {
+        let that = this;
+
+        if (pagination.current !== undefined) {
+            that.page = pagination.current - 1;
+        }
+
+        if (pagination.pageSize !== undefined) {
+
+            that.pageSize = pagination.pageSize;
+        }
+
+
+        //重置所有的sort
+        that.resetSortFilters();
+        if (!StringUtil.isEmptyObject(sorter)) {
+
+            //将变化的这个情况更新。
+            let filterKey = 'order' + StringUtil.capitalize(StringUtil.underScoreToCamel(sorter.field));
+
+
+            //直接放进排序值即可,底层会自动兼容
+            that.setFilterValue(filterKey, sorter.order);
+
+        }
+
+        //直接去刷新
+        that.httpList();
+    }
+
+    //清空data中的数据。
+    clear() {
+        this.data = [];
+        this.page = 0;
+        this.totalItems = 0;
+        this.totalPages = 0;
+    }
 
 }
 
diff --git a/src/common/model/base/SortDirection.ts b/src/common/model/base/SortDirection.ts
index 2f85a78..1556297 100644
--- a/src/common/model/base/SortDirection.ts
+++ b/src/common/model/base/SortDirection.ts
@@ -1,11 +1,11 @@
 enum SortDirection {
-  //这两个是后台通用的标准
-  ASC = 'ASC',
-  DESC = 'DESC',
+    //这两个是后台通用的标准
+    ASC = 'ASC',
+    DESC = 'DESC',
 
-  //这两项是antd的标准
-  DESCEND = 'descend',
-  ASCEND = 'ascend'
+    //这两项是antd的标准
+    DESCEND = 'descend',
+    ASCEND = 'ascend'
 }
 
 
diff --git a/src/common/model/base/ViewBase.ts b/src/common/model/base/ViewBase.ts
index dd01c91..025f626 100644
--- a/src/common/model/base/ViewBase.ts
+++ b/src/common/model/base/ViewBase.ts
@@ -10,25 +10,25 @@ import React from "react";
 
 export default class ViewBase extends Base {
 
-  //该类对应的React视图。
-  reactComponent: React.Component | null = null
+    //该类对应的React视图。
+    reactComponent: React.Component | null = null
 
-  //更新某一个组件对应的UI
-  static updateComponentUI(component: React.Component | null, entity?: any) {
-    if (component) {
-      //_version在这里是充当fake的。
-      component.setState({_version: new Date().getTime()})
-    } else {
-      console.warn(`${entity && entity.constructor ? entity.constructor.name : '未知对象'} 的 reactComponent 不存在,无法更新其对应的UI`)
+    //更新某一个组件对应的UI
+    static updateComponentUI(component: React.Component | null, entity?: any) {
+        if (component) {
+            //_version在这里是充当fake的。
+            component.setState({_version: new Date().getTime()})
+        } else {
+            console.warn(`${entity && entity.constructor ? entity.constructor.name : '未知对象'} 的 reactComponent 不存在,无法更新其对应的UI`)
+        }
     }
-  }
 
-  //更新当前的视图
-  updateUI() {
+    //更新当前的视图
+    updateUI() {
 
-    ViewBase.updateComponentUI(this.reactComponent, this)
+        ViewBase.updateComponentUI(this.reactComponent, this)
 
-  }
+    }
 
 
 }
diff --git a/src/common/model/base/WebResultCode.ts b/src/common/model/base/WebResultCode.ts
index 7d2e238..823f4b9 100644
--- a/src/common/model/base/WebResultCode.ts
+++ b/src/common/model/base/WebResultCode.ts
@@ -2,56 +2,56 @@ import SelectionOption from "../base/option/SelectionOption";
 
 
 enum WebResultCode {
-  OK = "OK",
-  BAD_REQUEST = "BAD_REQUEST",
-  NEED_SHARE_CODE = "NEED_SHARE_CODE",
-  SHARE_CODE_ERROR = "SHARE_CODE_ERROR",
-  LOGIN = "LOGIN",
-  NOT_INSTALLED = "NOT_INSTALLED",
-  SERVER = "SERVER",
-  UNKNOWN = "UNKNOWN",
+    OK = "OK",
+    BAD_REQUEST = "BAD_REQUEST",
+    NEED_SHARE_CODE = "NEED_SHARE_CODE",
+    SHARE_CODE_ERROR = "SHARE_CODE_ERROR",
+    LOGIN = "LOGIN",
+    NOT_INSTALLED = "NOT_INSTALLED",
+    SERVER = "SERVER",
+    UNKNOWN = "UNKNOWN",
 }
 
 let WebResultCodes: WebResultCode[] = Object.keys(WebResultCode).map(k => k as WebResultCode)
 
 let WebResultCodeMap: { [key in keyof typeof WebResultCode]: SelectionOption } = {
-  OK: {
-    "name": "成功",
-    "value": "OK",
-  },
-  BAD_REQUEST: {
-    "name": "请求错误",
-    "value": "BAD_REQUEST",
-  },
-  NEED_SHARE_CODE: {
-    name: "提取码必填",
-    value: "NEED_SHARE_CODE"
-  },
-  SHARE_CODE_ERROR: {
-    name: "提取码错误",
-    value: "SHARE_CODE_ERROR"
-  },
-  LOGIN: {
-    "name": "未登录",
-    "value": "LOGIN",
-  },
-  NOT_INSTALLED: {
-    "name": "未安装",
-    "value": "NOT_INSTALLED",
-  },
-  SERVER: {
-    "name": "服务器出错",
-    "value": "SERVER",
-  },
-  UNKNOWN: {
-    "name": "未知错误",
-    "value": "UNKNOWN",
-  },
+    OK: {
+        "name": "成功",
+        "value": "OK",
+    },
+    BAD_REQUEST: {
+        "name": "请求错误",
+        "value": "BAD_REQUEST",
+    },
+    NEED_SHARE_CODE: {
+        name: "提取码必填",
+        value: "NEED_SHARE_CODE"
+    },
+    SHARE_CODE_ERROR: {
+        name: "提取码错误",
+        value: "SHARE_CODE_ERROR"
+    },
+    LOGIN: {
+        "name": "未登录",
+        "value": "LOGIN",
+    },
+    NOT_INSTALLED: {
+        "name": "未安装",
+        "value": "NOT_INSTALLED",
+    },
+    SERVER: {
+        "name": "服务器出错",
+        "value": "SERVER",
+    },
+    UNKNOWN: {
+        "name": "未知错误",
+        "value": "UNKNOWN",
+    },
 }
 
 let WebResultCodeList: SelectionOption[] = []
 WebResultCodes.forEach((type: WebResultCode, index: number) => {
-  WebResultCodeList.push(WebResultCodeMap[type])
+    WebResultCodeList.push(WebResultCodeMap[type])
 })
 
 
diff --git a/src/common/model/base/filter/CheckFilter.ts b/src/common/model/base/filter/CheckFilter.ts
index 1f1836e..73a3195 100644
--- a/src/common/model/base/filter/CheckFilter.ts
+++ b/src/common/model/base/filter/CheckFilter.ts
@@ -8,45 +8,45 @@ import Filter from "./Filter";
  */
 export default class CheckFilter extends Filter {
 
-  //值,最终填写的内容。null表示这个值不设置
-  value: boolean | null = null
+    //值,最终填写的内容。null表示这个值不设置
+    value: boolean | null = null
 
-  constructor(name: string, code: string, visible?: boolean) {
-    super(name, code, visible)
-  }
-
-
-  //获取值字符串,[null,true,false] => ["","true","false"]
-  getValueString(): string {
-    let stringValue = ""
-    if (this.value === true) {
-      stringValue = "true"
-    } else if (this.value === false) {
-      stringValue = "false"
-    } else {
-      stringValue = ""
+    constructor(name: string, code: string, visible?: boolean) {
+        super(name, code, visible)
     }
-    return stringValue
-  }
 
-  //通过一个字符串来设置值
-  putValue(value: any) {
 
-    if (value === "true" || value === true) {
-      this.value = true
-    } else if (value === "false" || value === false) {
-      this.value = false
-    } else {
-      this.value = null
+    //获取值字符串,[null,true,false] => ["","true","false"]
+    getValueString(): string {
+        let stringValue = ""
+        if (this.value === true) {
+            stringValue = "true"
+        } else if (this.value === false) {
+            stringValue = "false"
+        } else {
+            stringValue = ""
+        }
+        return stringValue
     }
-  }
 
-  reset() {
-    this.value = null
-  }
+    //通过一个字符串来设置值
+    putValue(value: any) {
 
-  isEmpty(): boolean {
-    return this.value === null;
-  }
+        if (value === "true" || value === true) {
+            this.value = true
+        } else if (value === "false" || value === false) {
+            this.value = false
+        } else {
+            this.value = null
+        }
+    }
+
+    reset() {
+        this.value = null
+    }
+
+    isEmpty(): boolean {
+        return this.value === null;
+    }
 
 }
diff --git a/src/common/model/base/filter/DateFilter.ts b/src/common/model/base/filter/DateFilter.ts
index b0b8a79..d27551b 100644
--- a/src/common/model/base/filter/DateFilter.ts
+++ b/src/common/model/base/filter/DateFilter.ts
@@ -9,46 +9,45 @@ import DateUtil from "../../../util/DateUtil";
  */
 export default class DateFilter extends Filter {
 
-  //时间筛选的格式
-  format: string
+    //时间筛选的格式
+    format: string
 
-  //值,最终填写的内容。null表示这个值不设置
-  value: Date | null = null
+    //值,最终填写的内容。null表示这个值不设置
+    value: Date | null = null
 
-  constructor(name: string, code: string, format?: string, visible?: boolean) {
-    super(name, code, visible)
-    if (format) {
-      this.format = format
-    } else {
-      this.format = DateUtil.DATE_FORMAT
+    constructor(name: string, code: string, format?: string, visible?: boolean) {
+        super(name, code, visible)
+        if (format) {
+            this.format = format
+        } else {
+            this.format = DateUtil.DATE_FORMAT
+        }
     }
-  }
 
-  //获取值字符串
-  getValueString(): string {
-    if (this.value) {
-      return DateUtil.format(this.value, this.format)
-    } else {
-      return ""
+    //获取值字符串
+    getValueString(): string {
+        if (this.value) {
+            return DateUtil.format(this.value, this.format)
+        } else {
+            return ""
+        }
     }
-  }
 
 
-  //通过一个字符串来设置值
-  putValue(value: string) {
+    //通过一个字符串来设置值
+    putValue(value: string) {
 
-    this.value = DateUtil.parse(value)
-  }
+        this.value = DateUtil.parse(value)
+    }
 
 
-  reset() {
-    this.value = null
-  }
-
-  isEmpty(): boolean {
-    return this.value === null;
-  }
+    reset() {
+        this.value = null
+    }
 
+    isEmpty(): boolean {
+        return this.value === null;
+    }
 
 
 }
diff --git a/src/common/model/base/filter/DateTimeFilter.ts b/src/common/model/base/filter/DateTimeFilter.ts
index c3a1581..405a3f2 100644
--- a/src/common/model/base/filter/DateTimeFilter.ts
+++ b/src/common/model/base/filter/DateTimeFilter.ts
@@ -9,46 +9,45 @@ import DateUtil from "../../../util/DateUtil";
  */
 export default class DateTimeFilter extends Filter {
 
-  //时间筛选的格式
-  format: string
+    //时间筛选的格式
+    format: string
 
-  //值,最终填写的内容。null表示这个值不设置
-  value: Date | null = null
+    //值,最终填写的内容。null表示这个值不设置
+    value: Date | null = null
 
-  constructor(name: string, code: string, format?: string, visible?: boolean) {
-    super(name, code, visible)
-    if (format) {
-      this.format = format
-    } else {
-      this.format = DateUtil.DEFAULT_FORMAT
+    constructor(name: string, code: string, format?: string, visible?: boolean) {
+        super(name, code, visible)
+        if (format) {
+            this.format = format
+        } else {
+            this.format = DateUtil.DEFAULT_FORMAT
+        }
     }
-  }
 
-  //获取值字符串
-  getValueString(): string {
-    if (this.value) {
-      return DateUtil.format(this.value, this.format)
-    } else {
-      return ""
+    //获取值字符串
+    getValueString(): string {
+        if (this.value) {
+            return DateUtil.format(this.value, this.format)
+        } else {
+            return ""
+        }
     }
-  }
 
 
-  //通过一个字符串来设置值
-  putValue(value: string) {
+    //通过一个字符串来设置值
+    putValue(value: string) {
 
-    this.value = DateUtil.parse(value)
-  }
+        this.value = DateUtil.parse(value)
+    }
 
 
-  reset() {
-    this.value = null
-  }
-
-  isEmpty(): boolean {
-    return this.value === null;
-  }
+    reset() {
+        this.value = null
+    }
 
+    isEmpty(): boolean {
+        return this.value === null;
+    }
 
 
 }
diff --git a/src/common/model/base/filter/Filter.ts b/src/common/model/base/filter/Filter.ts
index 8142cbd..abee711 100644
--- a/src/common/model/base/filter/Filter.ts
+++ b/src/common/model/base/filter/Filter.ts
@@ -3,53 +3,53 @@
  */
 export default class Filter {
 
-  //中文名
-  name: string
-  //提交时候的键值,英文
-  key: string
-  //是否可见
-  visible: boolean = true
+    //中文名
+    name: string
+    //提交时候的键值,英文
+    key: string
+    //是否可见
+    visible: boolean = true
 
-  constructor(name: string, key: string, visible?: boolean) {
-    this.name = name
-    this.key = key
+    constructor(name: string, key: string, visible?: boolean) {
+        this.name = name
+        this.key = key
 
-    //没有传默认为true.
-    if (visible === undefined) {
-      this.visible = true
-    } else {
-      this.visible = visible
+        //没有传默认为true.
+        if (visible === undefined) {
+            this.visible = true
+        } else {
+            this.visible = visible
+        }
     }
-  }
 
-  /**
-   * 获取到一个字符串的值
-   */
-  getValueString(): string {
-    console.error(`${this.constructor.name} 的 getValue 不存在,请开发者及时配置。`)
-    return ""
-  }
+    /**
+     * 获取到一个字符串的值
+     */
+    getValueString(): string {
+        console.error(`${this.constructor.name} 的 getValue 不存在,请开发者及时配置。`)
+        return ""
+    }
 
-  /**
-   * 把一个字符串放置到value中去,因为有可能从请求参数中回填值
-   */
-  putValue(value: string) {
-    console.error(`${this.constructor.name} 的 putValue 不存在,请开发者及时配置。`)
-  }
+    /**
+     * 把一个字符串放置到value中去,因为有可能从请求参数中回填值
+     */
+    putValue(value: string) {
+        console.error(`${this.constructor.name} 的 putValue 不存在,请开发者及时配置。`)
+    }
 
-  /**
-   * 将过滤器的值清空
-   */
-  reset() {
-    console.error(`${this.constructor.name} 的 reset 不存在,请开发者及时配置。`)
-  }
+    /**
+     * 将过滤器的值清空
+     */
+    reset() {
+        console.error(`${this.constructor.name} 的 reset 不存在,请开发者及时配置。`)
+    }
 
-  /**
-   * 当前过滤器是否为空
-   */
-  isEmpty():boolean {
-    console.error(`${this.constructor.name} 的 isEmpty 不存在,请开发者及时配置。`)
-    return false
-  }
+    /**
+     * 当前过滤器是否为空
+     */
+    isEmpty(): boolean {
+        console.error(`${this.constructor.name} 的 isEmpty 不存在,请开发者及时配置。`)
+        return false
+    }
 
 }
diff --git a/src/common/model/base/filter/HttpSelectionFilter.ts b/src/common/model/base/filter/HttpSelectionFilter.ts
index 82017e3..2b25d10 100644
--- a/src/common/model/base/filter/HttpSelectionFilter.ts
+++ b/src/common/model/base/filter/HttpSelectionFilter.ts
@@ -9,24 +9,24 @@ import SelectionFilterType from "./SelectionFilterType";
  */
 export default class HttpSelectionFilter extends SelectionFilter {
 
-  //远程的访问链接。
-  url: string
+    //远程的访问链接。
+    url: string
 
-  constructor(name: string, code: string, url: string, selectionType?: SelectionFilterType, visible?: boolean) {
-    super(name, code, [], selectionType, visible)
-    this.url = url
-  }
+    constructor(name: string, code: string, url: string, selectionType?: SelectionFilterType, visible?: boolean) {
+        super(name, code, [], selectionType, visible)
+        this.url = url
+    }
 
-  //通过一个字符串来设置值
-  //远程调用的值必须要宽容,因为值可能还没有从远程取回来呢。
-  putValue(value: string) {
-    this.value = value
-  }
+    //通过一个字符串来设置值
+    //远程调用的值必须要宽容,因为值可能还没有从远程取回来呢。
+    putValue(value: string) {
+        this.value = value
+    }
 
-  //严格的回填,采用父类的策略
-  //这个方法会在http请求完成了之后调用。HttpSelectionFilter中会调用
-  strictPutValue(value: string) {
-    super.putValue(value)
-  }
+    //严格的回填,采用父类的策略
+    //这个方法会在http请求完成了之后调用。HttpSelectionFilter中会调用
+    strictPutValue(value: string) {
+        super.putValue(value)
+    }
 
 }
diff --git a/src/common/model/base/filter/InputFilter.ts b/src/common/model/base/filter/InputFilter.ts
index ffc5b99..e0efb5e 100644
--- a/src/common/model/base/filter/InputFilter.ts
+++ b/src/common/model/base/filter/InputFilter.ts
@@ -6,42 +6,42 @@ import Filter from "./Filter";
  */
 export default class InputFilter extends Filter {
 
-  //值,最终填写的内容
-  value: string = ""
+    //值,最终填写的内容
+    value: string = ""
 
-  //占位符
-  placeholder: string
+    //占位符
+    placeholder: string
 
-  constructor(name: string, code: string, placeholder?: string | null, visible?: boolean) {
-    super(name, code, visible)
+    constructor(name: string, code: string, placeholder?: string | null, visible?: boolean) {
+        super(name, code, visible)
 
-    if (placeholder) {
-      this.placeholder = placeholder
-    } else {
-      this.placeholder = name
+        if (placeholder) {
+            this.placeholder = placeholder
+        } else {
+            this.placeholder = name
+        }
     }
-  }
 
 
-  //获取值字符串
-  getValueString(): string {
-    return this.value
-  }
+    //获取值字符串
+    getValueString(): string {
+        return this.value
+    }
 
-  //通过一个字符串来设置值
-  putValue(value: string) {
+    //通过一个字符串来设置值
+    putValue(value: string) {
 
-    this.value = value
+        this.value = value
 
-  }
+    }
 
 
-  reset() {
-    this.value = ""
-  }
+    reset() {
+        this.value = ""
+    }
 
-  isEmpty(): boolean {
-    return this.value === "";
-  }
+    isEmpty(): boolean {
+        return this.value === "";
+    }
 
 }
diff --git a/src/common/model/base/filter/SelectionFilter.ts b/src/common/model/base/filter/SelectionFilter.ts
index c644531..2103451 100644
--- a/src/common/model/base/filter/SelectionFilter.ts
+++ b/src/common/model/base/filter/SelectionFilter.ts
@@ -10,59 +10,59 @@ import SelectionFilterType from "./SelectionFilterType";
  */
 export default class SelectionFilter extends Filter {
 
-  //候选项,要求必须有name和value。
-  options: SelectionOption[]
+    //候选项,要求必须有name和value。
+    options: SelectionOption[]
 
-  //值,最终填写的内容。null表示这个值不设置
-  value: string = ""
+    //值,最终填写的内容。null表示这个值不设置
+    value: string = ""
 
-  //采用的样式
-  selectionType: SelectionFilterType
+    //采用的样式
+    selectionType: SelectionFilterType
 
-  constructor(name: string, code: string, options: SelectionOption[],selectionType?: SelectionFilterType, visible?: boolean) {
-    super(name, code, visible)
+    constructor(name: string, code: string, options: SelectionOption[], selectionType?: SelectionFilterType, visible?: boolean) {
+        super(name, code, visible)
 
-    this.options = options
-    if (selectionType === undefined) {
-      this.selectionType = SelectionFilterType.COMBOBOX
-    } else {
-      this.selectionType = selectionType
-    }
-  }
-
-  //获取值字符串
-  getValueString(): string {
-    return this.value
-  }
-
-  //通过一个字符串来设置值
-  putValue(value: string) {
-
-    if (value === "") {
-      this.value = ""
-    } else {
-
-      //必须是options中的值才接纳。
-      for (let j = 0; j < this.options.length; j++) {
-        let opt = this.options[j]
-        if (opt.value === value) {
-          this.value = value
-          return
+        this.options = options
+        if (selectionType === undefined) {
+            this.selectionType = SelectionFilterType.COMBOBOX
+        } else {
+            this.selectionType = selectionType
         }
-      }
-
-      this.value = ""
     }
 
-  }
+    //获取值字符串
+    getValueString(): string {
+        return this.value
+    }
+
+    //通过一个字符串来设置值
+    putValue(value: string) {
+
+        if (value === "") {
+            this.value = ""
+        } else {
+
+            //必须是options中的值才接纳。
+            for (let j = 0; j < this.options.length; j++) {
+                let opt = this.options[j]
+                if (opt.value === value) {
+                    this.value = value
+                    return
+                }
+            }
+
+            this.value = ""
+        }
+
+    }
 
 
-  reset() {
-    this.value = ""
-  }
+    reset() {
+        this.value = ""
+    }
 
-  isEmpty(): boolean {
-    return this.value === "";
-  }
+    isEmpty(): boolean {
+        return this.value === "";
+    }
 
 }
diff --git a/src/common/model/base/filter/SelectionFilterType.ts b/src/common/model/base/filter/SelectionFilterType.ts
index 1919e59..e4b775e 100644
--- a/src/common/model/base/filter/SelectionFilterType.ts
+++ b/src/common/model/base/filter/SelectionFilterType.ts
@@ -2,10 +2,10 @@
  * 过滤器中的选择样式
  */
 enum SelectionFilterType {
-  //下拉框的样式
-  COMBOBOX = "COMBOBOX",
-  //按钮的样式
-  BUTTON = "BUTTON",
+    //下拉框的样式
+    COMBOBOX = "COMBOBOX",
+    //按钮的样式
+    BUTTON = "BUTTON",
 }
 
 export default SelectionFilterType
diff --git a/src/common/model/base/filter/SortFilter.ts b/src/common/model/base/filter/SortFilter.ts
index 30cbee8..fbcd340 100644
--- a/src/common/model/base/filter/SortFilter.ts
+++ b/src/common/model/base/filter/SortFilter.ts
@@ -9,61 +9,61 @@ import SortDirection from "../SortDirection";
  */
 export default class SortFilter extends Filter {
 
-  //值,最终填写的内容。null表示这个值不设置
-  value: SortDirection | null = null
+    //值,最终填写的内容。null表示这个值不设置
+    value: SortDirection | null = null
 
-  constructor(name: string, code: string, visible?: boolean) {
-    super(name, code, visible)
-    //过滤排序器,more是不显示的。
-    //没有传默认为true.
-    if (visible === undefined) {
-      this.visible = false
-    } else {
-      this.visible = visible
+    constructor(name: string, code: string, visible?: boolean) {
+        super(name, code, visible)
+        //过滤排序器,more是不显示的。
+        //没有传默认为true.
+        if (visible === undefined) {
+            this.visible = false
+        } else {
+            this.visible = visible
+        }
     }
-  }
 
-  //获取值字符串,[null,true,false] => ["","true","false"]
-  getValueString(): string {
-    if (this.value) {
-      return this.value
-    } else {
-      return ""
+    //获取值字符串,[null,true,false] => ["","true","false"]
+    getValueString(): string {
+        if (this.value) {
+            return this.value
+        } else {
+            return ""
+        }
     }
-  }
 
-  //通过一个字符串来设置值
-  putValue(value: string) {
-    if (value === SortDirection.DESC || value === SortDirection.DESCEND) {
-      this.value = SortDirection.DESC
-    } else if (value === SortDirection.ASC || value === SortDirection.ASCEND) {
-      this.value = SortDirection.ASC
-    } else {
-      this.value = null
+    //通过一个字符串来设置值
+    putValue(value: string) {
+        if (value === SortDirection.DESC || value === SortDirection.DESCEND) {
+            this.value = SortDirection.DESC
+        } else if (value === SortDirection.ASC || value === SortDirection.ASCEND) {
+            this.value = SortDirection.ASC
+        } else {
+            this.value = null
+        }
     }
-  }
 
 
-  //获取到antd需要使用的值 TODO: SortOrder
-  getAntdValue(): any | null {
-    if (this.value === SortDirection.DESC || this.value === SortDirection.DESCEND) {
-      return SortDirection.DESCEND
-    } else if (this.value === SortDirection.ASC || this.value === SortDirection.ASCEND) {
-      return SortDirection.ASCEND
-    } else {
-      return null
+    //获取到antd需要使用的值 TODO: SortOrder
+    getAntdValue(): any | null {
+        if (this.value === SortDirection.DESC || this.value === SortDirection.DESCEND) {
+            return SortDirection.DESCEND
+        } else if (this.value === SortDirection.ASC || this.value === SortDirection.ASCEND) {
+            return SortDirection.ASCEND
+        } else {
+            return null
+        }
     }
-  }
 
 
-  reset() {
-    this.value = null
-  }
+    reset() {
+        this.value = null
+    }
 
 
-  isEmpty(): boolean {
-    return this.value === null;
-  }
+    isEmpty(): boolean {
+        return this.value === null;
+    }
 
 
 }
diff --git a/src/common/model/base/option/BreadcrumbModel.ts b/src/common/model/base/option/BreadcrumbModel.ts
index 8d06896..26d7396 100644
--- a/src/common/model/base/option/BreadcrumbModel.ts
+++ b/src/common/model/base/option/BreadcrumbModel.ts
@@ -2,9 +2,9 @@
  * 面包屑对应的模型
  */
 export default interface BreadcrumbModel {
-  name: string,
-  path: string,
-  query: any,
-  displayDirect: boolean,
+    name: string,
+    path: string,
+    query: any,
+    displayDirect: boolean,
 }
 
diff --git a/src/common/model/base/option/CodeSelectionOption.ts b/src/common/model/base/option/CodeSelectionOption.ts
index b87998d..67b9f11 100644
--- a/src/common/model/base/option/CodeSelectionOption.ts
+++ b/src/common/model/base/option/CodeSelectionOption.ts
@@ -4,6 +4,6 @@
 import SelectionOption from "./SelectionOption";
 
 export default interface CodeSelectionOption extends SelectionOption {
-  code: string,
-  type: string,
+    code: string,
+    type: string,
 }
diff --git a/src/common/model/base/option/Color.ts b/src/common/model/base/option/Color.ts
index 00d72a0..f918d4c 100644
--- a/src/common/model/base/option/Color.ts
+++ b/src/common/model/base/option/Color.ts
@@ -1,9 +1,9 @@
 enum Color {
-  PRIMARY = "#215891",
-  INFO = "#2DB7F5",
-  SUCCESS = "#67C23A",
-  WARNING = "#E6A23C",
-  DANGER = "#FF756F",
+    PRIMARY = "#215891",
+    INFO = "#2DB7F5",
+    SUCCESS = "#67C23A",
+    WARNING = "#E6A23C",
+    DANGER = "#FF756F",
 }
 
 export default Color
diff --git a/src/common/model/base/option/ColorIndexSelectionOption.ts b/src/common/model/base/option/ColorIndexSelectionOption.ts
index 34da7b9..9ac80c8 100644
--- a/src/common/model/base/option/ColorIndexSelectionOption.ts
+++ b/src/common/model/base/option/ColorIndexSelectionOption.ts
@@ -4,6 +4,6 @@
 import SelectionOption from "./SelectionOption";
 
 export default interface ColorSelectionOption extends SelectionOption {
-  index: number,
-  color: string,
+    index: number,
+    color: string,
 }
diff --git a/src/common/model/base/option/ColorSelectionOption.ts b/src/common/model/base/option/ColorSelectionOption.ts
index 8c2f90f..6b615bd 100644
--- a/src/common/model/base/option/ColorSelectionOption.ts
+++ b/src/common/model/base/option/ColorSelectionOption.ts
@@ -4,5 +4,5 @@
 import SelectionOption from "./SelectionOption";
 
 export default interface ColorSelectionOption extends SelectionOption {
-  color: string,
+    color: string,
 }
diff --git a/src/common/model/base/option/IconIndexSelectionOption.ts b/src/common/model/base/option/IconIndexSelectionOption.ts
index 452e20d..0c05db8 100644
--- a/src/common/model/base/option/IconIndexSelectionOption.ts
+++ b/src/common/model/base/option/IconIndexSelectionOption.ts
@@ -4,8 +4,8 @@
 import SelectionOption from "./SelectionOption";
 
 export default interface IconIndexSelectionOption extends SelectionOption {
-  index: number,
-  icon: string,
+    index: number,
+    icon: string,
 }
 
 
diff --git a/src/common/model/base/option/IndexSelectionOption.ts b/src/common/model/base/option/IndexSelectionOption.ts
index f564d3f..3338229 100644
--- a/src/common/model/base/option/IndexSelectionOption.ts
+++ b/src/common/model/base/option/IndexSelectionOption.ts
@@ -4,7 +4,7 @@
 import SelectionOption from "./SelectionOption";
 
 export default interface IndexSelectionOption extends SelectionOption {
-  index: number,
-  name: string,
-  value: string
+    index: number,
+    name: string,
+    value: string
 }
diff --git a/src/common/model/base/option/SelectionOption.ts b/src/common/model/base/option/SelectionOption.ts
index 73115ff..f8f1acf 100644
--- a/src/common/model/base/option/SelectionOption.ts
+++ b/src/common/model/base/option/SelectionOption.ts
@@ -2,7 +2,7 @@
  * 下拉筛选框的选项,统一使用该接口,同时这个作为枚举的复杂类型。
  */
 export default interface SelectionOption {
-  name: string,
-  value: string
+    name: string,
+    value: string
 }
 
diff --git a/src/common/model/base/option/StyleSelectionOption.ts b/src/common/model/base/option/StyleSelectionOption.ts
index ce53dd1..1350204 100644
--- a/src/common/model/base/option/StyleSelectionOption.ts
+++ b/src/common/model/base/option/StyleSelectionOption.ts
@@ -4,5 +4,5 @@
 import SelectionOption from "./SelectionOption";
 
 export default interface StyleSelectionOption extends SelectionOption {
-  style: string,
+    style: string,
 }
diff --git a/src/common/model/base/types/index.d.ts b/src/common/model/base/types/index.d.ts
index 8f714cd..ab976a2 100644
--- a/src/common/model/base/types/index.d.ts
+++ b/src/common/model/base/types/index.d.ts
@@ -2,16 +2,16 @@
  * 定义了一个图标行为的对象,这个可以辅助一些组件。
  */
 export interface IconActionItem {
-  //图片的资源链接(优先级高于iconType)
-  icon?: string
-  //antd的图标类型
-  iconType?: string
-  //名称
-  name?: string
-  //是否可见。默认可见
-  visible?: boolean
-  //点击图标后的行为
-  onClick?: () => void
+    //图片的资源链接(优先级高于iconType)
+    icon?: string
+    //antd的图标类型
+    iconType?: string
+    //名称
+    name?: string
+    //是否可见。默认可见
+    visible?: boolean
+    //点击图标后的行为
+    onClick?: () => void
 }
 
 
@@ -21,13 +21,13 @@ export interface IconActionItem {
  */
 export interface ToolItem {
 
-  name: string
+    name: string
 
-  //当前是否处于展开状态
-  active: boolean
+    //当前是否处于展开状态
+    active: boolean
 
-  //antd的图标样式
-  iconType: string
+    //antd的图标样式
+    iconType: string
 
 }
 
@@ -38,16 +38,16 @@ export interface ToolItem {
  */
 export interface SkeletonItem {
 
-  name: string
+    name: string
 
-  //当前是否处于展开状态
-  active: boolean
+    //当前是否处于展开状态
+    active: boolean
 
-  //高亮的图标 资源链接
-  activeIcon: string
+    //高亮的图标 资源链接
+    activeIcon: string
 
-  //一般状态的图标 资源链接
-  icon: string
+    //一般状态的图标 资源链接
+    icon: string
 
 }
 
diff --git a/src/common/model/dashboard/Dashboard.ts b/src/common/model/dashboard/Dashboard.ts
index 94afa05..87040f0 100644
--- a/src/common/model/dashboard/Dashboard.ts
+++ b/src/common/model/dashboard/Dashboard.ts
@@ -2,67 +2,66 @@ import SafeUtil from '../../util/SafeUtil';
 import BaseEntity from '../base/BaseEntity';
 import Filter from "../base/filter/Filter";
 import SortFilter from "../base/filter/SortFilter";
-import StringUtil from "../../util/StringUtil";
 
 
 export default class Dashboard extends BaseEntity {
 
-  static URL_ACTIVE_IP_TOP10 = "/api/dashboard/active/ip/top10"
-  static URL_ETL = "/api/dashboard/etl"
+    static URL_ACTIVE_IP_TOP10 = "/api/dashboard/active/ip/top10"
+    static URL_ETL = "/api/dashboard/etl"
 
-  invokeNum: number = 0;
-  totalInvokeNum: number = 0;
-  uv: number = 0;
-  totalUv: number = 0;
-  matterNum: number = 0;
-  totalMatterNum: number = 0;
-  fileSize: number = 0;
-  totalFileSize: number = 0;
-  avgCost: number = 0;
-  dt: string = "";
+    invokeNum: number = 0;
+    totalInvokeNum: number = 0;
+    uv: number = 0;
+    totalUv: number = 0;
+    matterNum: number = 0;
+    totalMatterNum: number = 0;
+    fileSize: number = 0;
+    totalFileSize: number = 0;
+    avgCost: number = 0;
+    dt: string = "";
 
 
-  constructor(reactComponent?: React.Component) {
+    constructor(reactComponent?: React.Component) {
 
-    super(reactComponent);
+        super(reactComponent);
 
-  }
+    }
 
-  assign(obj: any) {
-    super.assign(obj);
+    assign(obj: any) {
+        super.assign(obj);
 
-  }
+    }
 
-  getTAG(): string {
-    return "dashboard";
-  }
+    getTAG(): string {
+        return "dashboard";
+    }
 
-  getFilters(): Filter[] {
-    return [
-      ...super.getFilters(),
-      new SortFilter("按DT排序", "orderDt"),
+    getFilters(): Filter[] {
+        return [
+            ...super.getFilters(),
+            new SortFilter("按DT排序", "orderDt"),
 
-    ]
-  }
+        ]
+    }
 
-  httpActiveIpTop10(successCallback?: any, errorCallback?: any, finalCallback?: any) {
-    let that = this
-    this.httpPost(Dashboard.URL_ACTIVE_IP_TOP10, {}, function (response: any) {
+    httpActiveIpTop10(successCallback?: any, errorCallback?: any, finalCallback?: any) {
+        let that = this
+        this.httpPost(Dashboard.URL_ACTIVE_IP_TOP10, {}, function (response: any) {
 
-      SafeUtil.safeCallback(successCallback)(response.data.data);
+            SafeUtil.safeCallback(successCallback)(response.data.data);
 
-    }, errorCallback, finalCallback)
-  }
+        }, errorCallback, finalCallback)
+    }
 
 
-  httpEtl(successCallback?: any, errorCallback?: any, finalCallback?: any) {
-    let that = this
-    this.httpPost(Dashboard.URL_ETL, {}, function (response: any) {
+    httpEtl(successCallback?: any, errorCallback?: any, finalCallback?: any) {
+        let that = this
+        this.httpPost(Dashboard.URL_ETL, {}, function (response: any) {
 
-      SafeUtil.safeCallback(successCallback)(response.data.data);
+            SafeUtil.safeCallback(successCallback)(response.data.data);
 
-    }, errorCallback, finalCallback)
-  }
+        }, errorCallback, finalCallback)
+    }
 
 }
 
diff --git a/src/common/model/download/token/DownloadToken.ts b/src/common/model/download/token/DownloadToken.ts
index fbc1a2a..d42b67d 100644
--- a/src/common/model/download/token/DownloadToken.ts
+++ b/src/common/model/download/token/DownloadToken.ts
@@ -3,51 +3,51 @@ import DateUtil from "../../../util/DateUtil";
 import SafeUtil from "../../../util/SafeUtil";
 
 export default class DownloadToken extends BaseEntity {
-  userUuid: string | null = null;
-  matterUuid: string | null = null;
-  expireTime: string | null = null;
-  ip: string | null = null;
+    userUuid: string | null = null;
+    matterUuid: string | null = null;
+    expireTime: string | null = null;
+    ip: string | null = null;
 
-  static URL_FETCH_DOWNLOAD_TOKEN = "/api/alien/fetch/download/token";
+    static URL_FETCH_DOWNLOAD_TOKEN = "/api/alien/fetch/download/token";
 
-  constructor(reactComponent?: React.Component) {
-    super(reactComponent);
-  }
+    constructor(reactComponent?: React.Component) {
+        super(reactComponent);
+    }
 
 
-  getTAG(): string {
-    return "downloadToken";
-  }
+    getTAG(): string {
+        return "downloadToken";
+    }
 
-  assign(obj: any) {
-    super.assign(obj);
-    this.assignEntity("expireTime", Date);
-  }
+    assign(obj: any) {
+        super.assign(obj);
+        this.assignEntity("expireTime", Date);
+    }
 
-  getFilters() {
-    return [...super.getFilters()];
-  }
+    getFilters() {
+        return [...super.getFilters()];
+    }
 
-  httpFetchDownloadToken(
-    matterUuid: string,
-    successCallback?: () => any,
-    errorCallback?: () => any
-  ) {
-    let that = this;
-    let date = new Date(new Date().getTime() + 10 * 60 * 1000);
+    httpFetchDownloadToken(
+        matterUuid: string,
+        successCallback?: () => any,
+        errorCallback?: () => any
+    ) {
+        let that = this;
+        let date = new Date(new Date().getTime() + 10 * 60 * 1000);
 
-    let form = {
-      expireTime: DateUtil.simpleDateTime(date),
-      matterUuid,
-    };
-    this.httpPost(
-      DownloadToken.URL_FETCH_DOWNLOAD_TOKEN,
-      form,
-      function (response: any) {
-        that.assign(response.data.data);
-        SafeUtil.safeCallback(successCallback)(response);
-      },
-      errorCallback
-    );
-  }
+        let form = {
+            expireTime: DateUtil.simpleDateTime(date),
+            matterUuid,
+        };
+        this.httpPost(
+            DownloadToken.URL_FETCH_DOWNLOAD_TOKEN,
+            form,
+            function (response: any) {
+                that.assign(response.data.data);
+                SafeUtil.safeCallback(successCallback)(response);
+            },
+            errorCallback
+        );
+    }
 }
diff --git a/src/common/model/global/Lang.ts b/src/common/model/global/Lang.ts
index 50fc110..d3d8096 100644
--- a/src/common/model/global/Lang.ts
+++ b/src/common/model/global/Lang.ts
@@ -8,66 +8,66 @@ import LangZh from "./i18n/LangZh";
 
 export default class Lang {
 
-  //当前使用的语言,默认中文
-  lang: string = "zh"
+    //当前使用的语言,默认中文
+    lang: string = "zh"
 
-  //全局的一个store对象
-  private static singleton: Lang | null = null
+    //全局的一个store对象
+    private static singleton: Lang | null = null
 
-  //使用懒加载模式。
-  static getSingleton(): Lang {
-    if (Lang.singleton == null) {
-      Lang.singleton = new Lang();
+    //使用懒加载模式。
+    static getSingleton(): Lang {
+        if (Lang.singleton == null) {
+            Lang.singleton = new Lang();
 
-      //读取默认的语言
-      let lang = BrowserUtil.browserLang()
-      let localLang = localStorage.getItem("_lang");
-      if (localLang === "zh" || localLang === "en") {
-        lang = localLang
-      }
-      Lang.singleton.lang = lang
-      console.info("current lang: ", lang)
+            //读取默认的语言
+            let lang = BrowserUtil.browserLang()
+            let localLang = localStorage.getItem("_lang");
+            if (localLang === "zh" || localLang === "en") {
+                lang = localLang
+            }
+            Lang.singleton.lang = lang
+            console.info("current lang: ", lang)
 
+        }
+
+        return Lang.singleton
     }
 
-    return Lang.singleton
-  }
+    //快捷获取一种语言对应的文字。
+    static t(key: string, ...params: any[]): string {
 
-  //快捷获取一种语言对应的文字。
-  static t(key: string, ...params: any[]): string {
+        let json: { [key: string]: any } = LangEn
 
-    let json: { [key: string]: any } = LangEn
+        let lang = Lang.getSingleton().lang
+        if (lang == "zh") {
+            json = LangZh
+        }
 
-    let lang = Lang.getSingleton().lang
-    if (lang == "zh") {
-      json = LangZh
+        let keyParts: string[] = key.split(".")
+        let jsonBody: any = json
+        for (let i = 0; i < keyParts.length; i++) {
+            let part: string = keyParts[i]
+            jsonBody = jsonBody[part]
+            if (jsonBody === undefined || jsonBody === null) {
+                //找不到key对应的内容,直接返回key
+                return key
+            }
+        }
+
+        //到这里已经找到了
+        if (typeof jsonBody !== "string") {
+            return key
+        }
+
+        //依次将参数写入进去。
+        if (params && params.length > 0) {
+            for (let i = 0; i < params.length; i++) {
+                let param = params[i]
+                jsonBody = jsonBody.replace("{}", param)
+            }
+        }
+
+        return jsonBody
     }
 
-    let keyParts: string[] = key.split(".")
-    let jsonBody: any = json
-    for (let i = 0; i < keyParts.length; i++) {
-      let part: string = keyParts[i]
-      jsonBody = jsonBody[part]
-      if (jsonBody === undefined || jsonBody === null) {
-        //找不到key对应的内容,直接返回key
-        return key
-      }
-    }
-
-    //到这里已经找到了
-    if (typeof jsonBody !== "string") {
-      return key
-    }
-
-    //依次将参数写入进去。
-    if (params && params.length > 0) {
-      for (let i = 0; i < params.length; i++) {
-        let param = params[i]
-        jsonBody = jsonBody.replace("{}", param)
-      }
-    }
-
-    return jsonBody
-  }
-
 }
diff --git a/src/common/model/global/Moon.ts b/src/common/model/global/Moon.ts
index a2c4cbf..0515832 100644
--- a/src/common/model/global/Moon.ts
+++ b/src/common/model/global/Moon.ts
@@ -5,28 +5,27 @@
  */
 import User from "../user/User";
 import Preference from "../preference/Preference";
-import Matter from "../matter/Matter";
 
 
 export default class Moon {
 
-  //全局具有唯一的用户,即当前登录的用户.
-  user: User = new User()
+    //全局具有唯一的用户,即当前登录的用户.
+    user: User = new User()
 
-  //全局唯一的偏好设置
-  preference: Preference = new Preference()
+    //全局唯一的偏好设置
+    preference: Preference = new Preference()
 
-  //全局的一个store对象
-  private static singleton: Moon | null = null
+    //全局的一个store对象
+    private static singleton: Moon | null = null
 
-  //使用懒加载模式。
-  static getSingleton(): Moon {
-    if (Moon.singleton == null) {
-      Moon.singleton = new Moon();
+    //使用懒加载模式。
+    static getSingleton(): Moon {
+        if (Moon.singleton == null) {
+            Moon.singleton = new Moon();
 
+        }
+
+        return Moon.singleton
     }
 
-    return Moon.singleton
-  }
-
 }
diff --git a/src/common/model/global/Sun.ts b/src/common/model/global/Sun.ts
index 267b7ca..89876c0 100644
--- a/src/common/model/global/Sun.ts
+++ b/src/common/model/global/Sun.ts
@@ -6,88 +6,87 @@
 
 export default class Sun {
 
-  //全局的一个store对象
-  static singleton: Sun | null = null;
+    //全局的一个store对象
+    static singleton: Sun | null = null;
 
-  //持有整个网站最外层的frame,方便我们刷新整个页面。
-  frameComponent: any = null;
+    //持有整个网站最外层的frame,方便我们刷新整个页面。
+    frameComponent: any = null;
 
-  //持有全局的react-router对象,方便我们在非jsx环境中控制路由跳转
-  reactRouter: any = null;
+    //持有全局的react-router对象,方便我们在非jsx环境中控制路由跳转
+    reactRouter: any = null;
 
-  //全局布局样式,是否展示出左边的菜单.
-  showDrawer: boolean = false;
+    //全局布局样式,是否展示出左边的菜单.
+    showDrawer: boolean = false;
 
-  //全局mobile标识
-  isMobile: boolean = /Mobile|iP(hone|od|ad)|iOS|Android|BlackBerry/i.test(window.navigator.userAgent);
+    //全局mobile标识
+    isMobile: boolean = /Mobile|iP(hone|od|ad)|iOS|Android|BlackBerry/i.test(window.navigator.userAgent);
 
 
-
-  //由于这个类采用单例模式,因此所有属性都是独一份的。
-  constructor() {
-
-  }
-
-  //使用懒加载模式。
-  static getSingleton(): Sun {
-    if (Sun.singleton == null) {
-      Sun.singleton = new Sun();
+    //由于这个类采用单例模式,因此所有属性都是独一份的。
+    constructor() {
 
     }
-    return Sun.singleton
-  }
 
+    //使用懒加载模式。
+    static getSingleton(): Sun {
+        if (Sun.singleton == null) {
+            Sun.singleton = new Sun();
 
-  //*******************和路由相关的方法 开始 *******************//
-
-  /**
-   * 跳转到某个页面去
-   */
-  static navigateTo(path: any) {
-    if (Sun.getSingleton().reactRouter) {
-      Sun.getSingleton().reactRouter.push(path)
-    } else {
-      console.error("全局的 reactRouter 未定义,请检查代码!")
+        }
+        return Sun.singleton
     }
-  }
 
-  /**
-   * 跳转到某个页面去,带query
-   * route: {path: '', query: {}}
-   */
-  static navigateQueryTo(route: any) {
-    let path = route.path;
-    if (Object.keys(route.query).length) {
-      const params = new URLSearchParams(route.query).toString();
-      path += `?${params}`;
+
+    //*******************和路由相关的方法 开始 *******************//
+
+    /**
+     * 跳转到某个页面去
+     */
+    static navigateTo(path: any) {
+        if (Sun.getSingleton().reactRouter) {
+            Sun.getSingleton().reactRouter.push(path)
+        } else {
+            console.error("全局的 reactRouter 未定义,请检查代码!")
+        }
     }
-    Sun.navigateTo(path);
-  }
 
-  /**
-   * 回到上一页
-   */
-  static navigateBack() {
-    if (Sun.getSingleton().reactRouter) {
-      Sun.getSingleton().reactRouter.go(-1)
-    } else {
-      console.error("全局的 reactRouter 未定义,请检查代码!")
+    /**
+     * 跳转到某个页面去,带query
+     * route: {path: '', query: {}}
+     */
+    static navigateQueryTo(route: any) {
+        let path = route.path;
+        if (Object.keys(route.query).length) {
+            const params = new URLSearchParams(route.query).toString();
+            path += `?${params}`;
+        }
+        Sun.navigateTo(path);
     }
-  }
 
-  //******************* 和路由相关的方法 结束 *******************//
-
-  //*******************和全局视图相关的方法 开始 *******************//
-  /**
-   * 刷新主框架内容
-   */
-  static updateFrame() {
-    if (Sun.getSingleton().frameComponent) {
-      Sun.getSingleton().frameComponent.updateUI()
-    } else {
-      console.error("全局的 frameComponent 未定义,请检查代码!")
+    /**
+     * 回到上一页
+     */
+    static navigateBack() {
+        if (Sun.getSingleton().reactRouter) {
+            Sun.getSingleton().reactRouter.go(-1)
+        } else {
+            console.error("全局的 reactRouter 未定义,请检查代码!")
+        }
     }
-  }
 
-  //******************* 和全局视图相关的方法 结束 *******************//
+    //******************* 和路由相关的方法 结束 *******************//
+
+    //*******************和全局视图相关的方法 开始 *******************//
+    /**
+     * 刷新主框架内容
+     */
+    static updateFrame() {
+        if (Sun.getSingleton().frameComponent) {
+            Sun.getSingleton().frameComponent.updateUI()
+        } else {
+            console.error("全局的 frameComponent 未定义,请检查代码!")
+        }
+    }
+
+    //******************* 和全局视图相关的方法 结束 *******************//
 }
diff --git a/src/common/model/global/i18n/LangEn.ts b/src/common/model/global/i18n/LangEn.ts
index ac72c01..f214d18 100644
--- a/src/common/model/global/i18n/LangEn.ts
+++ b/src/common/model/global/i18n/LangEn.ts
@@ -1,375 +1,375 @@
 let LangEn = {
-  eyeblueTank: "EyeblueTank",
-  dashboard: {
-    totalInvokeNum: 'Total PV',
-    weekRate: 'Week',
-    dayRate: 'Day',
-    yesterdayInvoke: 'Yesterday PV',
-    totalUV: 'Total UV',
-    yesterdayUV: 'Yesterday UV',
-    totalMatterNum: 'Total file num',
-    yesterdayMatterNum: 'Yesterday File Num',
-    totalFileSize: 'Total File Size',
-    yesterdayMatterSize: 'Yesterday File Size',
-    recentDayInvokeUV: 'Recent {} days PV/UV',
-    downloadMatterTop10: 'File download TOP10',
-    activeIpTop10: 'Active IP TOP10',
-    loading: 'loading...',
-    date: 'Date',
-    num: 'Num',
-    warnHint: 'Hint: data in this page updates everyday at 0.a.m. ',
-    reRun: 'ReRun',
-  },
-  install: {
-    configMysql: "Config Database",
-    dbType: "Database Type",
-    port: "Port",
-    schema: "Schema",
-    username: "Username",
-    password: "Password",
-    charset: "Charset",
-    mysqlConnectionPass: "Connect MySQL Ok",
-    testMysqlConnection: "Tes MySQL Connection",
-    notice: "Notice",
-    sqliteNotice1: "Sqlite is a tiny file database, you can use it without installation",
-    mysqlNotice1: "If Mysql and EyeblueTank installed on the same server, Host is 127.0.0.1",
-    mysqlNotice2: "Your mysql account must have access to create table, or the second step will fail.",
-    validateMysqlFirst: "Please test the mysql connection firstly.",
-    preStep: "Pre Step",
-    nextStep: "Next Step",
-    createTable: "Craete Tables",
-    installed: "Installed",
-    installedButMissing: "Installed, but missing fields",
-    toBeInstalled: "To be installed",
-    allFields: "All fields",
-    missingFields: "Missing fields",
-    tableNotice: "'Create Tables' will trigger the following actions:",
-    tableNotice1: "If a table not exist, create it.",
-    tableNotice2: "If a table exist and no fields missing, nothing will do on this table.",
-    tableNotice3: "If a table exist but some fields is missing, it will add the missing fields.",
-    tableNotice4: "If a table exist and some fields not necessary, nothing will do on this table.",
-    oneKeyCreate: "Create Tables",
-    createFinish: "Finish Creating Tables",
-    createTableSuccess: "Create tables successfully",
-    crateTableFirst: "Please click 'Create Tables'",
-    setAdministrator: "Config Administrator",
-    detectAdministrator: "Detect the following administrators:",
-    useOrCreateAdministrator: "You can validate one of them, or you can create a new one.",
-    validateAdministrator: "Validate administrator",
-    createAdministrator: "Create administrator",
-    administratorUsername: "username",
-    administratorPassword: "password",
-    administratorRePassword: "Enter administrator password again",
-    usernameRule: "EyeblueTank will use username as directory name, so only lowercase letter and number and _ is permitted.",
-    congratulationInstall: "Congratulations, install successfully!",
-    configAdminFirst: "Please config administrator first.",
-    createAdminSuccess: "Create administrator successfully!",
-    validateAdminSuccess: "Validate administrator successfully!",
-    pressToHome: "Click the button below to enter home。",
-    enterHome: "Finish And Enter Home",
-    finish: "Finish",
-  },
-  layout: {
-    allFiles: "Files",
-    myShare: "My Share",
-    bin: "Recycle bin",
-    setting: "Setting",
-    dashboard: "Dashboard",
-    users: "Users",
-    logout: "Logout",
-    about: "About",
-    install: "Install",
-    dragMouseUp: "Put file here~"
-  },
-  matter: {
-    file: "File",
-    directory: "Directory",
-    rename: "Rename",
-    download: "Download",
-    delete: "Delete",
-    hardDelete: "Hard delete",
-    recovery: "Recovery",
-    more: "More",
-    share: "Share",
-    close: "Close",
-    size: "Size",
-    preview: "Preview",
-    move: "Move",
-    moveTo: "MoveTo",
-    upload: "Upload",
-    create: "Create",
-    createTime: "Create Time",
-    updateTime: "Update Time",
-    deleteTime: "Deleted Time",
-    root: "Root",
-    fillInPicLink: "Fill in Picture Link",
-    rePick: "Re Choose",
-    chooseImage: "Choose Image",
-    uploadMode: "Upload Mode",
-    fillMode: "Fill Mode",
-    sizeExceedLimit: "File size exceed limit {}>{}",
-    dropNotDirectory: "Cannot drag and drop folders for uploading",
-    setPublic: "Set as public",
-    setPrivate: "Set as private",
-    copyLink: "Copy Link",
-    enterName: "Please enter name",
-    publicFileEveryoneCanVisit: "Public file, anyone can access",
-    fileDetail: "File info",
-    expire: "Expire",
-    copyLinkAndCode: "Copy link and code",
-    uploaded: "Uploaded",
-    uploadDir: 'Upload dir',
-    uploadInfo: 'Upload Info',
-    uploadErrorInfo: 'Some files failed to upload, you can export CSV files for viewing',
-    exportCSV: 'Export upload error detail',
-    speed: "Speed",
-    fileInfo: "File basic info",
-    fileName: "Filename",
-    path: "Path",
-    copyPath: "Copy path",
-    publicOrPrivate: "Public or private",
-    privateInfo: "Private file, only self or auth user can download",
-    publicInfo: "Public file, anyone can download",
-    downloadTimes: "Download times",
-    operations: "Operation",
-    oneTimeLink: "One time link",
-    oneTimeLinkInfo: "One time link will expire after downloading, click to copy",
-    imageCache: "Image cache",
-    searchFile: "Search file",
-    noContentYet: "No content under this directory yet",
-    allFiles: "All Files",
-    newDirectory: "New directory",
-    notChoose: "Not choose any file",
-    exceed1000: "Exceed file limit 1000",
-    noImageCache: "No image cache",
-    recycleBin: "Recycle bin",
-    deleted: "Deleted",
-    unCompatibleBrowser: "The current browser does not support it. Please try choose another one",
-    canIUse: "To see if the current browser supports it",
-    intoRecycleBin: "Recycle bin",
-    finishingTip: "Please wait while files are sorted..."
-  },
-  router: {
-    allFiles: "All Files",
-    fileDetail: "File Detail",
-    login: "Login",
-    autoLogin: "Auto Login",
-    register: "Register",
-    users: "Users",
-    userDetail: "User Detail",
-    changePassword: "Change password",
-    editUser: "Edit User",
-    createUser: "Create User",
-    shareDetail: "Share Detail",
-    myShare: "My Share",
-    dashboard: "Dashboard",
-    install: "Install",
-    setting: "Setting"
-  },
-  preference: {
-    basic: "Base Info",
-    preview: "Preview Conf",
-    scan: "Scan Disk",
-    websiteName: "Website Name",
-    logo: "Logo",
-    logoSquare: "Logo will be cropped to square size",
-    onlyAllowIco: "Only .ico allowed",
-    copyright: "Copyright (support html)",
-    extraInfo: "Extra info (support html)",
-    zipMaxNumLimit: "Zip download max num limit",
-    zipMaxSizeLimit: "Zip download max size limit(B)",
-    current: "Current",
-    noLimit: "No limit",
-    userDefaultSizeLimit: "User default size limit(B) ",
-    matterBinDefaultSaveDay: "Matter bin storage days",
-    enterMatterBinDefaultSaveDay: "Please enter matter bin storage days!",
-    docLink: "Document Link",
-    tankDocLink: "https://tank-doc.eyeblue.cn",
-    allowRegister: "Allow register",
-    systemCleanup: "System Cleanup",
-    systemCleanupDescription: "This operation will cleanup everything except administrators' data",
-    systemCleanupPrompt: "This operation will cleanup everything except administrators' account data, please input login password.",
-    previewConfig: "File Preview Config",
-    editPreference: "Edit Preference",
-    editPreviewEngine: "Edit Preview engine",
-    enterWebsiteName: "Please enter website name!",
-    enterZipMaxNumLimit: "Please enter zip max num!",
-    enterZipMaxSizeLimit: "Please enter zip max size!",
-    enterUserDefaultSizeLimit: "Please enter user's default size!",
-    engine: "The number {} engine",
-    noEngine: "No preview engine",
-    newEngine: "Add a preview engine",
-    engineReg: "Engine format",
-    engineSuffix: "Engine suffix",
-    enginePreview: "Engine preview",
-    defaultPreview: "Default preview engine",
-    previewEngine: "Number {} preview engine",
-    defaultPreviewDesc: "Default preview engine, can not be removed",
-    engineUsageHint: "Previewing a file using the first engine matches the extentions.",
-    engineRegHelper: "template syntax, {url} represents the file path, the preview will automatically replace with the corresponding file url",
-    engineRegPlaceHolder: "eg:https://xxx.xxx.xxx?url={url}",
-    engineSuffixPlaceHolder: "suffix can not be null, split by comma, look like: doc,ppt,xls",
-    previewCurrent: "preview in current page",
-    previewOpen: "preview in new page",
-    editScan: "Edit Scan disk",
-    enableScan: "Enable Scan disk",
-    disabledScan: "Disabled Scan disk",
-    scanCron: "Regularly Scan disk",
-    cron: "Cron expression",
-    cronValidate: "Cron expression can not be null",
-    scanScope: "Scan scope",
-    scanUsers: "Scan users",
-    scanPerTenSeconds: "Scan every ten seconds",
-    scanPerThirtySeconds: "Scan every thirty seconds",
-    scanPerMinute: "Scan every minute",
-    scanPerHour: "Scan every hour",
-    scanCustom: "Scan custom",
-    chooseUsers: "Fuzzy search users",
-    chooseUsersValidate: "choose one more user",
-    scanLoading: "waiting...",
-    matterBinDefaultTip: "set zero means to turn off the recycle bin"
-  },
-  share: {
-    shareDetail: "Share Detail",
-    shareTime: "Share Time",
-    expireTime: "Expire Time",
-    noExpire: "Never Expire",
-    expired: "Expired",
-    copyLinkAndCode: "Copy Link And Code",
-    shareSuccess: "Share Successfully",
-    sharer: "Share Person",
-    link: "Link",
-    copyLink: "Copy Link",
-    code: "Code",
-    copyCode: "Copy Code",
-    copySuccess: "Copy Successfully",
-    more: "More",
-    cancelShare: "Cancel Share",
-    getLink: "Get Link",
-    allFiles: "All Files",
-    noContent: "No content in this directory",
-    enterCode: "Please enter code",
-    getFiles: "Get Files",
-    codeError: "Code Error",
-    cancelPrompt: "This operation will cancel sharing forever, continue?",
-    hour: "1 Hour",
-    day: "1 Day",
-    week: "1 Week",
-    month: "1 Month",
-    year: "1 Year",
-    infinity: "Forever",
-    emptyHint: "No Share Yet",
-  },
-  user: {
-    redirecting: "Redirecting...",
-    oldPassword: "Old Password",
-    newPassword: "New Password",
-    confirmNewPassword: "Confirm New Password",
-    cannotBeNull: "Cannot be null!",
-    passwordNotSame: "passwords above not same!",
-    role: "Role",
-    singleFileSizeLimit: "Single File Limit",
-    totalFileSizeLimit: "Total Space Limit",
-    current: "Current",
-    noLimit: "No Limit",
-    totalFileSize: "Used Space",
-    status: "Status",
-    lastLogin: "Last Login",
-    lastLoginIp: "Last Login Ip",
-    lastLoginTime: "Last Login Time",
-    resetPassword: "Reset Password",
-    transfiguration: "Transfiguration",
-    changePassword: "Edit Password",
-    enterPassword: "Please Enter Password",
-    enterUsername: "Please Enter Username",
-    enterNewPassword: "Please Enter New Password",
-    profile: "Profile",
-    avatar: "Avatar",
-    username: "Username",
-    password: "Password",
-    confirmPassword: "Confirm Password",
-    disabled: "Disabled",
-    disableUser: "Disable this user",
-    disable: "Disable",
-    active: "Active",
-    sync: "Sync",
-    activeUser: "Active this user",
-    deleteUser: "Delete this user",
-    deleteHint: "This action will delete {}'s all records, including files,shares,user infos etc. Continue?",
-    welcomeLogin: "Welcome Login",
-    logining: "Login...",
-    login: "Login",
-    loginSuccess: "Login Success",
-    toToRegister: "Go To Register",
-    welcomeRegister: "Welcome Register",
-    registering: "Login...",
-    register: "Register",
-    goToLogin: "Go To Login",
-    roleGuest: "Guest",
-    roleUser: "User",
-    roleAdministrator: "Administrator",
-    statusActive: "Ok",
-    statusDisabled: "Disabled",
-    webdavLink: "WebDAV Link",
-    docLink: "Document Link",
-    createUser: "Create User",
-    editUser: "Edit User",
-    editSomebodyPassword: "Edit {}'s Password",
-    transfigurationPromptText: "Transfiguration Prompt",
-    transfigurationPrompt: "You will login as this user.Please visit this link in other browser, if in current browser, you will logout.",
-    allUsers: "All users",
-    partialUsers: "Partial users",
-    searchUser: "Search user"
-  },
-  model: {
-    usernameRule: "only lowercase letter and number and _ is permitted.",
-    passwordRule: "Password must have more than 6 chars",
-    linkCodeText: "Link:{} Code:{}",
-    copyLinkCodeSuccess: "Copy Link and Code successfully",
+    eyeblueTank: "EyeblueTank",
+    dashboard: {
+        totalInvokeNum: 'Total PV',
+        weekRate: 'Week',
+        dayRate: 'Day',
+        yesterdayInvoke: 'Yesterday PV',
+        totalUV: 'Total UV',
+        yesterdayUV: 'Yesterday UV',
+        totalMatterNum: 'Total file num',
+        yesterdayMatterNum: 'Yesterday File Num',
+        totalFileSize: 'Total File Size',
+        yesterdayMatterSize: 'Yesterday File Size',
+        recentDayInvokeUV: 'Recent {} days PV/UV',
+        downloadMatterTop10: 'File download TOP10',
+        activeIpTop10: 'Active IP TOP10',
+        loading: 'loading...',
+        date: 'Date',
+        num: 'Num',
+        warnHint: 'Hint: data in this page updates everyday at 0.a.m. ',
+        reRun: 'ReRun',
+    },
+    install: {
+        configMysql: "Config Database",
+        dbType: "Database Type",
+        port: "Port",
+        schema: "Schema",
+        username: "Username",
+        password: "Password",
+        charset: "Charset",
+        mysqlConnectionPass: "Connect MySQL Ok",
+        testMysqlConnection: "Tes MySQL Connection",
+        notice: "Notice",
+        sqliteNotice1: "Sqlite is a tiny file database, you can use it without installation",
+        mysqlNotice1: "If Mysql and EyeblueTank installed on the same server, Host is 127.0.0.1",
+        mysqlNotice2: "Your mysql account must have access to create table, or the second step will fail.",
+        validateMysqlFirst: "Please test the mysql connection firstly.",
+        preStep: "Pre Step",
+        nextStep: "Next Step",
+        createTable: "Craete Tables",
+        installed: "Installed",
+        installedButMissing: "Installed, but missing fields",
+        toBeInstalled: "To be installed",
+        allFields: "All fields",
+        missingFields: "Missing fields",
+        tableNotice: "'Create Tables' will trigger the following actions:",
+        tableNotice1: "If a table not exist, create it.",
+        tableNotice2: "If a table exist and no fields missing, nothing will do on this table.",
+        tableNotice3: "If a table exist but some fields is missing, it will add the missing fields.",
+        tableNotice4: "If a table exist and some fields not necessary, nothing will do on this table.",
+        oneKeyCreate: "Create Tables",
+        createFinish: "Finish Creating Tables",
+        createTableSuccess: "Create tables successfully",
+        crateTableFirst: "Please click 'Create Tables'",
+        setAdministrator: "Config Administrator",
+        detectAdministrator: "Detect the following administrators:",
+        useOrCreateAdministrator: "You can validate one of them, or you can create a new one.",
+        validateAdministrator: "Validate administrator",
+        createAdministrator: "Create administrator",
+        administratorUsername: "username",
+        administratorPassword: "password",
+        administratorRePassword: "Enter administrator password again",
+        usernameRule: "EyeblueTank will use username as directory name, so only lowercase letter and number and _ is permitted.",
+        congratulationInstall: "Congratulations, install successfully!",
+        configAdminFirst: "Please config administrator first.",
+        createAdminSuccess: "Create administrator successfully!",
+        validateAdminSuccess: "Validate administrator successfully!",
+        pressToHome: "Click the button below to enter home。",
+        enterHome: "Finish And Enter Home",
+        finish: "Finish",
+    },
+    layout: {
+        allFiles: "Files",
+        myShare: "My Share",
+        bin: "Recycle bin",
+        setting: "Setting",
+        dashboard: "Dashboard",
+        users: "Users",
+        logout: "Logout",
+        about: "About",
+        install: "Install",
+        dragMouseUp: "Put file here~"
+    },
+    matter: {
+        file: "File",
+        directory: "Directory",
+        rename: "Rename",
+        download: "Download",
+        delete: "Delete",
+        hardDelete: "Hard delete",
+        recovery: "Recovery",
+        more: "More",
+        share: "Share",
+        close: "Close",
+        size: "Size",
+        preview: "Preview",
+        move: "Move",
+        moveTo: "MoveTo",
+        upload: "Upload",
+        create: "Create",
+        createTime: "Create Time",
+        updateTime: "Update Time",
+        deleteTime: "Deleted Time",
+        root: "Root",
+        fillInPicLink: "Fill in Picture Link",
+        rePick: "Re Choose",
+        chooseImage: "Choose Image",
+        uploadMode: "Upload Mode",
+        fillMode: "Fill Mode",
+        sizeExceedLimit: "File size exceed limit {}>{}",
+        dropNotDirectory: "Cannot drag and drop folders for uploading",
+        setPublic: "Set as public",
+        setPrivate: "Set as private",
+        copyLink: "Copy Link",
+        enterName: "Please enter name",
+        publicFileEveryoneCanVisit: "Public file, anyone can access",
+        fileDetail: "File info",
+        expire: "Expire",
+        copyLinkAndCode: "Copy link and code",
+        uploaded: "Uploaded",
+        uploadDir: 'Upload dir',
+        uploadInfo: 'Upload Info',
+        uploadErrorInfo: 'Some files failed to upload, you can export CSV files for viewing',
+        exportCSV: 'Export upload error detail',
+        speed: "Speed",
+        fileInfo: "File basic info",
+        fileName: "Filename",
+        path: "Path",
+        copyPath: "Copy path",
+        publicOrPrivate: "Public or private",
+        privateInfo: "Private file, only self or auth user can download",
+        publicInfo: "Public file, anyone can download",
+        downloadTimes: "Download times",
+        operations: "Operation",
+        oneTimeLink: "One time link",
+        oneTimeLinkInfo: "One time link will expire after downloading, click to copy",
+        imageCache: "Image cache",
+        searchFile: "Search file",
+        noContentYet: "No content under this directory yet",
+        allFiles: "All Files",
+        newDirectory: "New directory",
+        notChoose: "Not choose any file",
+        exceed1000: "Exceed file limit 1000",
+        noImageCache: "No image cache",
+        recycleBin: "Recycle bin",
+        deleted: "Deleted",
+        unCompatibleBrowser: "The current browser does not support it. Please try choose another one",
+        canIUse: "To see if the current browser supports it",
+        intoRecycleBin: "Recycle bin",
+        finishingTip: "Please wait while files are sorted..."
+    },
+    router: {
+        allFiles: "All Files",
+        fileDetail: "File Detail",
+        login: "Login",
+        autoLogin: "Auto Login",
+        register: "Register",
+        users: "Users",
+        userDetail: "User Detail",
+        changePassword: "Change password",
+        editUser: "Edit User",
+        createUser: "Create User",
+        shareDetail: "Share Detail",
+        myShare: "My Share",
+        dashboard: "Dashboard",
+        install: "Install",
+        setting: "Setting"
+    },
+    preference: {
+        basic: "Base Info",
+        preview: "Preview Conf",
+        scan: "Scan Disk",
+        websiteName: "Website Name",
+        logo: "Logo",
+        logoSquare: "Logo will be cropped to square size",
+        onlyAllowIco: "Only .ico allowed",
+        copyright: "Copyright (support html)",
+        extraInfo: "Extra info (support html)",
+        zipMaxNumLimit: "Zip download max num limit",
+        zipMaxSizeLimit: "Zip download max size limit(B)",
+        current: "Current",
+        noLimit: "No limit",
+        userDefaultSizeLimit: "User default size limit(B) ",
+        matterBinDefaultSaveDay: "Matter bin storage days",
+        enterMatterBinDefaultSaveDay: "Please enter matter bin storage days!",
+        docLink: "Document Link",
+        tankDocLink: "https://tank-doc.eyeblue.cn",
+        allowRegister: "Allow register",
+        systemCleanup: "System Cleanup",
+        systemCleanupDescription: "This operation will cleanup everything except administrators' data",
+        systemCleanupPrompt: "This operation will cleanup everything except administrators' account data, please input login password.",
+        previewConfig: "File Preview Config",
+        editPreference: "Edit Preference",
+        editPreviewEngine: "Edit Preview engine",
+        enterWebsiteName: "Please enter website name!",
+        enterZipMaxNumLimit: "Please enter zip max num!",
+        enterZipMaxSizeLimit: "Please enter zip max size!",
+        enterUserDefaultSizeLimit: "Please enter user's default size!",
+        engine: "The number {} engine",
+        noEngine: "No preview engine",
+        newEngine: "Add a preview engine",
+        engineReg: "Engine format",
+        engineSuffix: "Engine suffix",
+        enginePreview: "Engine preview",
+        defaultPreview: "Default preview engine",
+        previewEngine: "Number {} preview engine",
+        defaultPreviewDesc: "Default preview engine, can not be removed",
+        engineUsageHint: "Previewing a file using the first engine matches the extentions.",
+        engineRegHelper: "template syntax, {url} represents the file path, the preview will automatically replace with the corresponding file url",
+        engineRegPlaceHolder: "eg:https://xxx.xxx.xxx?url={url}",
+        engineSuffixPlaceHolder: "suffix can not be null, split by comma, look like: doc,ppt,xls",
+        previewCurrent: "preview in current page",
+        previewOpen: "preview in new page",
+        editScan: "Edit Scan disk",
+        enableScan: "Enable Scan disk",
+        disabledScan: "Disabled Scan disk",
+        scanCron: "Regularly Scan disk",
+        cron: "Cron expression",
+        cronValidate: "Cron expression can not be null",
+        scanScope: "Scan scope",
+        scanUsers: "Scan users",
+        scanPerTenSeconds: "Scan every ten seconds",
+        scanPerThirtySeconds: "Scan every thirty seconds",
+        scanPerMinute: "Scan every minute",
+        scanPerHour: "Scan every hour",
+        scanCustom: "Scan custom",
+        chooseUsers: "Fuzzy search users",
+        chooseUsersValidate: "choose one more user",
+        scanLoading: "waiting...",
+        matterBinDefaultTip: "set zero means to turn off the recycle bin"
+    },
+    share: {
+        shareDetail: "Share Detail",
+        shareTime: "Share Time",
+        expireTime: "Expire Time",
+        noExpire: "Never Expire",
+        expired: "Expired",
+        copyLinkAndCode: "Copy Link And Code",
+        shareSuccess: "Share Successfully",
+        sharer: "Share Person",
+        link: "Link",
+        copyLink: "Copy Link",
+        code: "Code",
+        copyCode: "Copy Code",
+        copySuccess: "Copy Successfully",
+        more: "More",
+        cancelShare: "Cancel Share",
+        getLink: "Get Link",
+        allFiles: "All Files",
+        noContent: "No content in this directory",
+        enterCode: "Please enter code",
+        getFiles: "Get Files",
+        codeError: "Code Error",
+        cancelPrompt: "This operation will cancel sharing forever, continue?",
+        hour: "1 Hour",
+        day: "1 Day",
+        week: "1 Week",
+        month: "1 Month",
+        year: "1 Year",
+        infinity: "Forever",
+        emptyHint: "No Share Yet",
+    },
+    user: {
+        redirecting: "Redirecting...",
+        oldPassword: "Old Password",
+        newPassword: "New Password",
+        confirmNewPassword: "Confirm New Password",
+        cannotBeNull: "Cannot be null!",
+        passwordNotSame: "passwords above not same!",
+        role: "Role",
+        singleFileSizeLimit: "Single File Limit",
+        totalFileSizeLimit: "Total Space Limit",
+        current: "Current",
+        noLimit: "No Limit",
+        totalFileSize: "Used Space",
+        status: "Status",
+        lastLogin: "Last Login",
+        lastLoginIp: "Last Login Ip",
+        lastLoginTime: "Last Login Time",
+        resetPassword: "Reset Password",
+        transfiguration: "Transfiguration",
+        changePassword: "Edit Password",
+        enterPassword: "Please Enter Password",
+        enterUsername: "Please Enter Username",
+        enterNewPassword: "Please Enter New Password",
+        profile: "Profile",
+        avatar: "Avatar",
+        username: "Username",
+        password: "Password",
+        confirmPassword: "Confirm Password",
+        disabled: "Disabled",
+        disableUser: "Disable this user",
+        disable: "Disable",
+        active: "Active",
+        sync: "Sync",
+        activeUser: "Active this user",
+        deleteUser: "Delete this user",
+        deleteHint: "This action will delete {}'s all records, including files,shares,user infos etc. Continue?",
+        welcomeLogin: "Welcome Login",
+        logining: "Login...",
+        login: "Login",
+        loginSuccess: "Login Success",
+        toToRegister: "Go To Register",
+        welcomeRegister: "Welcome Register",
+        registering: "Login...",
+        register: "Register",
+        goToLogin: "Go To Login",
+        roleGuest: "Guest",
+        roleUser: "User",
+        roleAdministrator: "Administrator",
+        statusActive: "Ok",
+        statusDisabled: "Disabled",
+        webdavLink: "WebDAV Link",
+        docLink: "Document Link",
+        createUser: "Create User",
+        editUser: "Edit User",
+        editSomebodyPassword: "Edit {}'s Password",
+        transfigurationPromptText: "Transfiguration Prompt",
+        transfigurationPrompt: "You will login as this user.Please visit this link in other browser, if in current browser, you will logout.",
+        allUsers: "All users",
+        partialUsers: "Partial users",
+        searchUser: "Search user"
+    },
+    model: {
+        usernameRule: "only lowercase letter and number and _ is permitted.",
+        passwordRule: "Password must have more than 6 chars",
+        linkCodeText: "Link:{} Code:{}",
+        copyLinkCodeSuccess: "Copy Link and Code successfully",
 
-  },
-  plugin: {
-    cannotPreview: "Cannot Preview",
-    emptyHintDefault: "No Items",
-    everyPage: "Every Page",
-    items: "Items",
-    total: "Total",
-    clickRefresh: "Click To Refresh",
-  },
-  loading: "Loading",
-  selectAll: "All",
-  edit: "Edit",
-  createTime: "Create Time",
-  download: "Download",
-  close: "Close",
-  required: "Required",
-  cancel: "Cancel",
-  delete: "Delete",
-  actionCanNotRevertConfirm: "This action cannot be reverted, confirm?",
-  actionDeleteConfirm: "Delete, confirm?",
-  actionRecoveryConfirm: "Recovery, confirm?",
-  prompt: "Prompt",
-  confirm: "Confirm",
-  copy: "Copy",
-  copySuccess: "Copy Success!",
-  copyError: "Copy Error!",
-  showMore: "Show More",
-  username: "Username",
-  password: "Password",
-  submit: "Submit",
-  save: "Save",
-  create: "Create",
-  finish: "Finish",
-  operationSuccess: "Operation success",
-  operation: "Operation",
-  notFound: "404 Not Found",
-  login: "Login",
-  logout: "Logout",
-  yes: "Yes",
-  no: "No",
-  all: "All",
-  refresh: "refresh",
-  inputRequired: "Input required",
+    },
+    plugin: {
+        cannotPreview: "Cannot Preview",
+        emptyHintDefault: "No Items",
+        everyPage: "Every Page",
+        items: "Items",
+        total: "Total",
+        clickRefresh: "Click To Refresh",
+    },
+    loading: "Loading",
+    selectAll: "All",
+    edit: "Edit",
+    createTime: "Create Time",
+    download: "Download",
+    close: "Close",
+    required: "Required",
+    cancel: "Cancel",
+    delete: "Delete",
+    actionCanNotRevertConfirm: "This action cannot be reverted, confirm?",
+    actionDeleteConfirm: "Delete, confirm?",
+    actionRecoveryConfirm: "Recovery, confirm?",
+    prompt: "Prompt",
+    confirm: "Confirm",
+    copy: "Copy",
+    copySuccess: "Copy Success!",
+    copyError: "Copy Error!",
+    showMore: "Show More",
+    username: "Username",
+    password: "Password",
+    submit: "Submit",
+    save: "Save",
+    create: "Create",
+    finish: "Finish",
+    operationSuccess: "Operation success",
+    operation: "Operation",
+    notFound: "404 Not Found",
+    login: "Login",
+    logout: "Logout",
+    yes: "Yes",
+    no: "No",
+    all: "All",
+    refresh: "refresh",
+    inputRequired: "Input required",
 }
 
 export default LangEn
diff --git a/src/common/model/global/i18n/LangZh.ts b/src/common/model/global/i18n/LangZh.ts
index dea6e4e..b27ed97 100644
--- a/src/common/model/global/i18n/LangZh.ts
+++ b/src/common/model/global/i18n/LangZh.ts
@@ -1,376 +1,376 @@
 let LangZh = {
-  eyeblueTank: "蓝眼云盘",
-  dashboard: {
-    totalInvokeNum: '总PV',
-    weekRate: '周环比',
-    dayRate: '日环比',
-    yesterdayInvoke: '昨日PV',
-    totalUV: '总UV',
-    yesterdayUV: '昨日UV',
-    totalMatterNum: '总文件数',
-    yesterdayMatterNum: '昨日文件数',
-    totalFileSize: '文件总大小',
-    yesterdayMatterSize: '昨日文件大小',
-    recentDayInvokeUV: '最近{}日PV/UV',
-    downloadMatterTop10: '文件下载量TOP10',
-    activeIpTop10: '活跃IP TOP10',
-    loading: '加载中…',
-    date: '日期',
-    num: '数量',
-    warnHint: '温馨提示:本页面数据每日凌晨0点清洗一次。',
-    reRun: '立即重跑',
-  },
-  install: {
-    configMysql: "配置数据库",
-    dbType: "数据库类型",
-    port: "端口",
-    schema: "库名",
-    username: "用户名",
-    password: "密码",
-    charset: "编码",
-    mysqlConnectionPass: "MySQL连接测试通过",
-    testMysqlConnection: "测试MySQL连接",
-    notice: "注意",
-    sqliteNotice1: "sqlite是一个轻量的文件数据库,无需安装即可使用",
-    mysqlNotice1: "如果数据库和蓝眼云盘安装在同一台服务器,Host可以直接填写 127.0.0.1。",
-    mysqlNotice2: "数据库账户的权限要求要能够创建表,否则第二步\"创建表\"操作会出错",
-    validateMysqlFirst: "请首先验证数据库连接",
-    preStep: "上一步",
-    nextStep: "下一步",
-    createTable: "创建表",
-    installed: "已安装",
-    installedButMissing: "已安装,字段缺失",
-    toBeInstalled: "待安装",
-    allFields: "所有字段",
-    missingFields: "缺失字段",
-    tableNotice: "点击\"一键建表\"后会按照以下逻辑执行操作:",
-    tableNotice1: "如果某表不存在,则直接创建表。",
-    tableNotice2: "如果某表存在并且字段齐全,那么不会对该表做任何操作。",
-    tableNotice3: "如果某表存在但是部分字段缺失,那么会在该表中增加缺失字段。",
-    tableNotice4: "如果表中有多余的字段(多余字段即不是蓝眼云盘需要的字段),不会做删除处理,而会维持原样。",
-    oneKeyCreate: "一键建表",
-    createFinish: "建表完成",
-    createTableSuccess: "建表成功",
-    crateTableFirst: "请首先点击'一键建表'",
-    setAdministrator: "设置管理员",
-    detectAdministrator: "检测到系统中已经存在有以下管理员:",
-    useOrCreateAdministrator: "你可以使用其中一位管理员的用户名和密码进行验证,或者创建一位新的管理员账户",
-    validateAdministrator: "验证管理员账户",
-    createAdministrator: "创建管理员账户",
-    administratorUsername: "管理员用户名",
-    administratorPassword: "管理员密码",
-    administratorRePassword: "再次输入密码",
-    usernameRule: "由于用户名将作为文件上传的目录,因此只允许字母数字以及\"_\"。",
-    congratulationInstall: "恭喜,安装成功!",
-    configAdminFirst: "请首先配置管理员信息!",
-    createAdminSuccess: "创建管理员成功!",
-    validateAdminSuccess: "验证管理员成功!",
-    pressToHome: "点击下方按钮来完成安装过程并进入首页。",
-    enterHome: "完成,并进入首页",
-    finish: "完成",
-  },
-  layout: {
-    allFiles: "全部文件",
-    myShare: "我的分享",
-    bin: "回收站",
-    setting: "网站设置",
-    dashboard: "监控统计",
-    users: "用户管理",
-    logout: "退出登录",
-    about: "关于",
-    install: "安装网站",
-    dragMouseUp: "可以松手啦~"
-  },
-  matter: {
-    file: "文件",
-    directory: "文件夹",
-    rename: "重命名",
-    download: "下载",
-    delete: "删除",
-    hardDelete: "彻底删除",
-    recovery: "恢复",
-    more: "更多",
-    share: "分享",
-    close: "关闭",
-    size: "大小",
-    preview: "预览",
-    move: "移动",
-    moveTo: "移动到",
-    upload: "上传",
-    create: "新建",
-    createTime: "创建时间",
-    updateTime: "修改时间",
-    deleteTime: "删除时间",
-    root: "根目录",
-    fillInPicLink: "请填写图片链接",
-    rePick: "重新选择",
-    chooseImage: "选择图片",
-    uploadMode: "上传模式",
-    fillMode: "填写模式",
-    sizeExceedLimit: "文件大小超过了限制{}>{}",
-    dropNotDirectory: "不可拖拽文件夹进行上传",
-    setPublic: "设置为公有文件",
-    setPrivate: "设置为私有文件",
-    copyLink: "复制下载链接",
-    enterName: "请输入名称",
-    publicFileEveryoneCanVisit: "公有文件,任何人可以访问",
-    fileDetail: "文件详情",
-    expire: "有效期",
-    copyLinkAndCode: "复制链接+提取码",
-    uploaded: "已上传",
-    uploadDir: '上传文件夹',
-    uploadInfo: '上传信息',
-    uploadErrorInfo: '部分文件上传失败,可导出csv文件查看',
-    exportCSV: '导出上传错误详情',
-    speed: "速度",
-    fileInfo: "文件基本信息",
-    fileName: "文件名",
-    path: "路径",
-    copyPath: "复制路径",
-    publicOrPrivate: "文件公开性",
-    privateInfo: "私有文件,只有自己或者授权的用户可以下载",
-    publicInfo: "公有文件,任何人可以通过链接下载",
-    downloadTimes: "下载次数",
-    operations: "操作",
-    oneTimeLink: "一次性链接",
-    oneTimeLinkInfo: "使用一次性链接下载后链接立即失效,可以分享这个链接给朋友,点击复制",
-    imageCache: "图片缓存",
-    searchFile: "搜索文件",
-    noContentYet: "该目录下暂无任何内容",
-    allFiles: "全部文件",
-    newDirectory: "新建文件夹",
-    notChoose: "没有选择文件",
-    exceed1000: "最多只能同时选取1000个文件",
-    noImageCache: "暂无图片缓存数据",
-    recycleBin: "回收站",
-    deleted: "已删除",
-    unCompatibleBrowser: "当前浏览器不支持,请切换浏览器尝试",
-    canIUse: "查看当前浏览器是否支持,点击跳转",
-    intoRecycleBin: "放入回收站",
-    finishingTip: "后台文件整理中,请稍候..."
-  },
-  router: {
-    allFiles: "全部文件",
-    fileDetail: "文件详情",
-    login: "登录",
-    autoLogin: "自动登录",
-    register: "注册",
-    users: "用户列表",
-    userDetail: "用户详情",
-    changePassword: "修改密码",
-    editUser: "编辑用户",
-    createUser: "创建用户",
-    shareDetail: "分享详情",
-    myShare: "我的分享",
-    dashboard: "监控统计",
-    install: "安装网站",
-    setting: "网站设置"
-  },
-  preference: {
-    basic: "基本信息",
-    preview: "预览引擎",
-    scan: "扫描磁盘",
-    websiteName: "网站名称",
-    logo: "Logo",
-    logoSquare: "logo请使用正方形图片,否则在显示时会裁剪成正方形",
-    onlyAllowIco: "只允许上传.ico图标",
-    copyright: "版权信息(支持html)",
-    extraInfo: "备案信息(支持html)",
-    zipMaxNumLimit: "zip下载数量限制",
-    zipMaxSizeLimit: "zip下载大小限制(B)",
-    current: "当前值",
-    noLimit: "无限制",
-    userDefaultSizeLimit: "用户默认总大小限制(B) ",
-    matterBinDefaultSaveDay: "回收站默认保留天数",
-    enterMatterBinDefaultSaveDay: "默认回收站默认保留天数必填!",
-    docLink: "文档链接",
-    tankDocLink: "https://tank-doc.eyeblue.cn/zh",
-    allowRegister: "允许自主注册",
-    systemCleanup: "重置系统",
-    systemCleanupDescription: "重置系统将清空除管理员账号外所有数据",
-    systemCleanupPrompt: "重置系统将清空除管理员账号外所有数据,事关重大,请输入登录密码",
-    previewConfig: "文件预览配置",
-    editPreference: "设置网站偏好",
-    editPreviewEngine: "设置预览引擎",
-    enterWebsiteName: "请输入网站名称!",
-    enterZipMaxNumLimit: "zip最大数量限制必填!",
-    enterZipMaxSizeLimit: "zip大小限制必填!",
-    enterUserDefaultSizeLimit: "默认用户空间大小必填!",
-    engine: "{}号预览引擎",
-    noEngine: "暂无在线预览引擎配置",
-    newEngine: "添加一个预览引擎",
-    engineReg: "引擎格式",
-    engineSuffix: "匹配后缀",
-    enginePreview: "预览方式",
-    defaultPreview: "默认引擎",
-    previewEngine: "{}号引擎",
-    defaultPreviewDesc: "默认预览引擎,不可移除",
-    engineRegHelper: "此处填写模板语法:{url}表示文件路径,预览时会自动替换成对应的文件url;{b64url}表示base64机密后的路径,适用于kkfileview;",
-    engineUsageHint: "对于一个文件的预览,使用第一个匹配到后缀名的引擎,没有配匹到则使用系统默认预览引擎",
-    engineRegPlaceHolder: "例如:https://xxx.xxx.xxx?url={url}",
-    engineSuffixPlaceHolder: '输入后缀,使用逗号分隔,不用带. 例如:doc,ppt,xls',
-    previewCurrent: "本站预览",
-    previewOpen: "新标签打开",
-    editScan: "设置磁盘扫描",
-    enableScan: "开启磁盘扫描",
-    disabledScan: "暂未开启磁盘扫描",
-    scanCron: "定时扫描",
-    cron: "cron表达式",
-    cronValidate: "cron表达式不能为空",
-    scanScope: "扫描范围",
-    scanUsers: "扫描用户",
-    scanPerTenSeconds: "每十秒",
-    scanPerThirtySeconds: "每三十秒",
-    scanPerMinute: "每分钟",
-    scanPerHour: "每小时",
-    scanCustom: "自定义",
-    chooseUsers: "模糊搜索用户",
-    chooseUsersValidate: "请选择至少一个用户",
-    scanLoading: "扫描中,请稍后...",
-    matterBinDefaultTip: "设置0表示关闭回收站功能"
-  },
-  share: {
-    shareDetail: "分享详情",
-    shareTime: "分享时间",
-    expireTime: "失效时间",
-    noExpire: "永久有效",
-    expired: "已过期",
-    copyLinkAndCode: "复制链接+提取码",
-    shareSuccess: "分享成功",
-    sharer: "分享者",
-    link: "链接",
-    copyLink: "复制链接",
-    code: "提取码",
-    copyCode: "复制提取码",
-    copySuccess: "复制成功",
-    more: "更多",
-    cancelShare: "取消分享",
-    getLink: "获取链接",
-    allFiles: "全部文件",
-    noContent: "该目录下暂无任何内容",
-    enterCode: "请输入提取码",
-    getFiles: "提取文件",
-    codeError: "提取码错误",
-    cancelPrompt: "此操作将永久取消该分享, 是否继续?",
-    hour: "1小时",
-    day: "1天",
-    week: "1周",
-    month: "1个月",
-    year: "1年",
-    infinity: "永远有效",
-    emptyHint: "暂无任何分享",
-  },
-  user: {
-    redirecting: "正在转跳...",
-    oldPassword: "旧密码",
-    newPassword: "新密码",
-    confirmNewPassword: "确认新密码",
-    cannotBeNull: "不能为空!",
-    passwordNotSame: "两次输入不一致!",
-    role: "角色",
-    singleFileSizeLimit: "单文件限制",
-    totalFileSizeLimit: "空间限制",
-    current: "当前值",
-    noLimit: "无限制",
-    totalFileSize: "已使用空间",
-    status: "状态",
-    lastLogin: "上次登录",
-    lastLoginIp: "上次登录IP",
-    lastLoginTime: "上次登录时间",
-    resetPassword: "重置密码",
-    transfiguration: "变身",
-    changePassword: "修改密码",
-    enterPassword: "输入密码",
-    enterUsername: "请输入用户名",
-    enterNewPassword: "请输入新密码",
-    profile: "个人详情",
-    avatar: "头像",
-    username: "用户名",
-    password: "密码",
-    confirmPassword: "确认密码",
-    disabled: "已禁用",
-    disableUser: "禁用该用户",
-    activeUser: "激活该用户",
-    deleteUser: "删除该用户",
-    deleteHint: "此操作将删除用户【{}】的所有记录,包括文件,分享,用户信息等内容,确定继续?",
-    disable: "禁用",
-    sync: "同步",
-    active: "激活",
-    welcomeLogin: "欢迎登录",
-    logining: "正在登录...",
-    login: "登录",
-    loginSuccess: "登录成功",
-    toToRegister: "立即注册",
-    welcomeRegister: "欢迎注册",
-    registering: "正在登录...",
-    register: "注册",
-    goToLogin: "前往登录",
-    roleGuest: "游客",
-    roleUser: "注册用户",
-    roleAdministrator: "管理员",
-    statusActive: "正常",
-    statusDisabled: "禁用",
-    webdavLink: "WebDAV 地址",
-    docLink: "文档链接",
-    createUser: "创建用户",
-    editUser: "编辑用户",
-    editSomebodyPassword: "修改{}的密码",
-    transfigurationPromptText: "变身提示",
-    transfigurationPrompt: "您将使用该用户的身份登录。请复制以下链接到其他浏览器访问,在当前浏览器访问会导致当前用户登录信息失效。",
-    allUsers: "全部用户",
-    partialUsers: "局部用户",
-    searchUser: "搜索用户"
-  },
-  model: {
-    usernameRule: "用户名只能包含字母,数字和\"_\"",
-    passwordRule: "密码长度至少为6位",
-    linkCodeText: "链接:{} 提取码:{}",
-    copyLinkCodeSuccess: "复制链接提取码成功",
+    eyeblueTank: "蓝眼云盘",
+    dashboard: {
+        totalInvokeNum: '总PV',
+        weekRate: '周环比',
+        dayRate: '日环比',
+        yesterdayInvoke: '昨日PV',
+        totalUV: '总UV',
+        yesterdayUV: '昨日UV',
+        totalMatterNum: '总文件数',
+        yesterdayMatterNum: '昨日文件数',
+        totalFileSize: '文件总大小',
+        yesterdayMatterSize: '昨日文件大小',
+        recentDayInvokeUV: '最近{}日PV/UV',
+        downloadMatterTop10: '文件下载量TOP10',
+        activeIpTop10: '活跃IP TOP10',
+        loading: '加载中…',
+        date: '日期',
+        num: '数量',
+        warnHint: '温馨提示:本页面数据每日凌晨0点清洗一次。',
+        reRun: '立即重跑',
+    },
+    install: {
+        configMysql: "配置数据库",
+        dbType: "数据库类型",
+        port: "端口",
+        schema: "库名",
+        username: "用户名",
+        password: "密码",
+        charset: "编码",
+        mysqlConnectionPass: "MySQL连接测试通过",
+        testMysqlConnection: "测试MySQL连接",
+        notice: "注意",
+        sqliteNotice1: "sqlite是一个轻量的文件数据库,无需安装即可使用",
+        mysqlNotice1: "如果数据库和蓝眼云盘安装在同一台服务器,Host可以直接填写 127.0.0.1。",
+        mysqlNotice2: "数据库账户的权限要求要能够创建表,否则第二步\"创建表\"操作会出错",
+        validateMysqlFirst: "请首先验证数据库连接",
+        preStep: "上一步",
+        nextStep: "下一步",
+        createTable: "创建表",
+        installed: "已安装",
+        installedButMissing: "已安装,字段缺失",
+        toBeInstalled: "待安装",
+        allFields: "所有字段",
+        missingFields: "缺失字段",
+        tableNotice: "点击\"一键建表\"后会按照以下逻辑执行操作:",
+        tableNotice1: "如果某表不存在,则直接创建表。",
+        tableNotice2: "如果某表存在并且字段齐全,那么不会对该表做任何操作。",
+        tableNotice3: "如果某表存在但是部分字段缺失,那么会在该表中增加缺失字段。",
+        tableNotice4: "如果表中有多余的字段(多余字段即不是蓝眼云盘需要的字段),不会做删除处理,而会维持原样。",
+        oneKeyCreate: "一键建表",
+        createFinish: "建表完成",
+        createTableSuccess: "建表成功",
+        crateTableFirst: "请首先点击'一键建表'",
+        setAdministrator: "设置管理员",
+        detectAdministrator: "检测到系统中已经存在有以下管理员:",
+        useOrCreateAdministrator: "你可以使用其中一位管理员的用户名和密码进行验证,或者创建一位新的管理员账户",
+        validateAdministrator: "验证管理员账户",
+        createAdministrator: "创建管理员账户",
+        administratorUsername: "管理员用户名",
+        administratorPassword: "管理员密码",
+        administratorRePassword: "再次输入密码",
+        usernameRule: "由于用户名将作为文件上传的目录,因此只允许字母数字以及\"_\"。",
+        congratulationInstall: "恭喜,安装成功!",
+        configAdminFirst: "请首先配置管理员信息!",
+        createAdminSuccess: "创建管理员成功!",
+        validateAdminSuccess: "验证管理员成功!",
+        pressToHome: "点击下方按钮来完成安装过程并进入首页。",
+        enterHome: "完成,并进入首页",
+        finish: "完成",
+    },
+    layout: {
+        allFiles: "全部文件",
+        myShare: "我的分享",
+        bin: "回收站",
+        setting: "网站设置",
+        dashboard: "监控统计",
+        users: "用户管理",
+        logout: "退出登录",
+        about: "关于",
+        install: "安装网站",
+        dragMouseUp: "可以松手啦~"
+    },
+    matter: {
+        file: "文件",
+        directory: "文件夹",
+        rename: "重命名",
+        download: "下载",
+        delete: "删除",
+        hardDelete: "彻底删除",
+        recovery: "恢复",
+        more: "更多",
+        share: "分享",
+        close: "关闭",
+        size: "大小",
+        preview: "预览",
+        move: "移动",
+        moveTo: "移动到",
+        upload: "上传",
+        create: "新建",
+        createTime: "创建时间",
+        updateTime: "修改时间",
+        deleteTime: "删除时间",
+        root: "根目录",
+        fillInPicLink: "请填写图片链接",
+        rePick: "重新选择",
+        chooseImage: "选择图片",
+        uploadMode: "上传模式",
+        fillMode: "填写模式",
+        sizeExceedLimit: "文件大小超过了限制{}>{}",
+        dropNotDirectory: "不可拖拽文件夹进行上传",
+        setPublic: "设置为公有文件",
+        setPrivate: "设置为私有文件",
+        copyLink: "复制下载链接",
+        enterName: "请输入名称",
+        publicFileEveryoneCanVisit: "公有文件,任何人可以访问",
+        fileDetail: "文件详情",
+        expire: "有效期",
+        copyLinkAndCode: "复制链接+提取码",
+        uploaded: "已上传",
+        uploadDir: '上传文件夹',
+        uploadInfo: '上传信息',
+        uploadErrorInfo: '部分文件上传失败,可导出csv文件查看',
+        exportCSV: '导出上传错误详情',
+        speed: "速度",
+        fileInfo: "文件基本信息",
+        fileName: "文件名",
+        path: "路径",
+        copyPath: "复制路径",
+        publicOrPrivate: "文件公开性",
+        privateInfo: "私有文件,只有自己或者授权的用户可以下载",
+        publicInfo: "公有文件,任何人可以通过链接下载",
+        downloadTimes: "下载次数",
+        operations: "操作",
+        oneTimeLink: "一次性链接",
+        oneTimeLinkInfo: "使用一次性链接下载后链接立即失效,可以分享这个链接给朋友,点击复制",
+        imageCache: "图片缓存",
+        searchFile: "搜索文件",
+        noContentYet: "该目录下暂无任何内容",
+        allFiles: "全部文件",
+        newDirectory: "新建文件夹",
+        notChoose: "没有选择文件",
+        exceed1000: "最多只能同时选取1000个文件",
+        noImageCache: "暂无图片缓存数据",
+        recycleBin: "回收站",
+        deleted: "已删除",
+        unCompatibleBrowser: "当前浏览器不支持,请切换浏览器尝试",
+        canIUse: "查看当前浏览器是否支持,点击跳转",
+        intoRecycleBin: "放入回收站",
+        finishingTip: "后台文件整理中,请稍候..."
+    },
+    router: {
+        allFiles: "全部文件",
+        fileDetail: "文件详情",
+        login: "登录",
+        autoLogin: "自动登录",
+        register: "注册",
+        users: "用户列表",
+        userDetail: "用户详情",
+        changePassword: "修改密码",
+        editUser: "编辑用户",
+        createUser: "创建用户",
+        shareDetail: "分享详情",
+        myShare: "我的分享",
+        dashboard: "监控统计",
+        install: "安装网站",
+        setting: "网站设置"
+    },
+    preference: {
+        basic: "基本信息",
+        preview: "预览引擎",
+        scan: "扫描磁盘",
+        websiteName: "网站名称",
+        logo: "Logo",
+        logoSquare: "logo请使用正方形图片,否则在显示时会裁剪成正方形",
+        onlyAllowIco: "只允许上传.ico图标",
+        copyright: "版权信息(支持html)",
+        extraInfo: "备案信息(支持html)",
+        zipMaxNumLimit: "zip下载数量限制",
+        zipMaxSizeLimit: "zip下载大小限制(B)",
+        current: "当前值",
+        noLimit: "无限制",
+        userDefaultSizeLimit: "用户默认总大小限制(B) ",
+        matterBinDefaultSaveDay: "回收站默认保留天数",
+        enterMatterBinDefaultSaveDay: "默认回收站默认保留天数必填!",
+        docLink: "文档链接",
+        tankDocLink: "https://tank-doc.eyeblue.cn/zh",
+        allowRegister: "允许自主注册",
+        systemCleanup: "重置系统",
+        systemCleanupDescription: "重置系统将清空除管理员账号外所有数据",
+        systemCleanupPrompt: "重置系统将清空除管理员账号外所有数据,事关重大,请输入登录密码",
+        previewConfig: "文件预览配置",
+        editPreference: "设置网站偏好",
+        editPreviewEngine: "设置预览引擎",
+        enterWebsiteName: "请输入网站名称!",
+        enterZipMaxNumLimit: "zip最大数量限制必填!",
+        enterZipMaxSizeLimit: "zip大小限制必填!",
+        enterUserDefaultSizeLimit: "默认用户空间大小必填!",
+        engine: "{}号预览引擎",
+        noEngine: "暂无在线预览引擎配置",
+        newEngine: "添加一个预览引擎",
+        engineReg: "引擎格式",
+        engineSuffix: "匹配后缀",
+        enginePreview: "预览方式",
+        defaultPreview: "默认引擎",
+        previewEngine: "{}号引擎",
+        defaultPreviewDesc: "默认预览引擎,不可移除",
+        engineRegHelper: "此处填写模板语法:{url}表示文件路径,预览时会自动替换成对应的文件url;{b64url}表示base64机密后的路径,适用于kkfileview;",
+        engineUsageHint: "对于一个文件的预览,使用第一个匹配到后缀名的引擎,没有配匹到则使用系统默认预览引擎",
+        engineRegPlaceHolder: "例如:https://xxx.xxx.xxx?url={url}",
+        engineSuffixPlaceHolder: '输入后缀,使用逗号分隔,不用带. 例如:doc,ppt,xls',
+        previewCurrent: "本站预览",
+        previewOpen: "新标签打开",
+        editScan: "设置磁盘扫描",
+        enableScan: "开启磁盘扫描",
+        disabledScan: "暂未开启磁盘扫描",
+        scanCron: "定时扫描",
+        cron: "cron表达式",
+        cronValidate: "cron表达式不能为空",
+        scanScope: "扫描范围",
+        scanUsers: "扫描用户",
+        scanPerTenSeconds: "每十秒",
+        scanPerThirtySeconds: "每三十秒",
+        scanPerMinute: "每分钟",
+        scanPerHour: "每小时",
+        scanCustom: "自定义",
+        chooseUsers: "模糊搜索用户",
+        chooseUsersValidate: "请选择至少一个用户",
+        scanLoading: "扫描中,请稍后...",
+        matterBinDefaultTip: "设置0表示关闭回收站功能"
+    },
+    share: {
+        shareDetail: "分享详情",
+        shareTime: "分享时间",
+        expireTime: "失效时间",
+        noExpire: "永久有效",
+        expired: "已过期",
+        copyLinkAndCode: "复制链接+提取码",
+        shareSuccess: "分享成功",
+        sharer: "分享者",
+        link: "链接",
+        copyLink: "复制链接",
+        code: "提取码",
+        copyCode: "复制提取码",
+        copySuccess: "复制成功",
+        more: "更多",
+        cancelShare: "取消分享",
+        getLink: "获取链接",
+        allFiles: "全部文件",
+        noContent: "该目录下暂无任何内容",
+        enterCode: "请输入提取码",
+        getFiles: "提取文件",
+        codeError: "提取码错误",
+        cancelPrompt: "此操作将永久取消该分享, 是否继续?",
+        hour: "1小时",
+        day: "1天",
+        week: "1周",
+        month: "1个月",
+        year: "1年",
+        infinity: "永远有效",
+        emptyHint: "暂无任何分享",
+    },
+    user: {
+        redirecting: "正在转跳...",
+        oldPassword: "旧密码",
+        newPassword: "新密码",
+        confirmNewPassword: "确认新密码",
+        cannotBeNull: "不能为空!",
+        passwordNotSame: "两次输入不一致!",
+        role: "角色",
+        singleFileSizeLimit: "单文件限制",
+        totalFileSizeLimit: "空间限制",
+        current: "当前值",
+        noLimit: "无限制",
+        totalFileSize: "已使用空间",
+        status: "状态",
+        lastLogin: "上次登录",
+        lastLoginIp: "上次登录IP",
+        lastLoginTime: "上次登录时间",
+        resetPassword: "重置密码",
+        transfiguration: "变身",
+        changePassword: "修改密码",
+        enterPassword: "输入密码",
+        enterUsername: "请输入用户名",
+        enterNewPassword: "请输入新密码",
+        profile: "个人详情",
+        avatar: "头像",
+        username: "用户名",
+        password: "密码",
+        confirmPassword: "确认密码",
+        disabled: "已禁用",
+        disableUser: "禁用该用户",
+        activeUser: "激活该用户",
+        deleteUser: "删除该用户",
+        deleteHint: "此操作将删除用户【{}】的所有记录,包括文件,分享,用户信息等内容,确定继续?",
+        disable: "禁用",
+        sync: "同步",
+        active: "激活",
+        welcomeLogin: "欢迎登录",
+        logining: "正在登录...",
+        login: "登录",
+        loginSuccess: "登录成功",
+        toToRegister: "立即注册",
+        welcomeRegister: "欢迎注册",
+        registering: "正在登录...",
+        register: "注册",
+        goToLogin: "前往登录",
+        roleGuest: "游客",
+        roleUser: "注册用户",
+        roleAdministrator: "管理员",
+        statusActive: "正常",
+        statusDisabled: "禁用",
+        webdavLink: "WebDAV 地址",
+        docLink: "文档链接",
+        createUser: "创建用户",
+        editUser: "编辑用户",
+        editSomebodyPassword: "修改{}的密码",
+        transfigurationPromptText: "变身提示",
+        transfigurationPrompt: "您将使用该用户的身份登录。请复制以下链接到其他浏览器访问,在当前浏览器访问会导致当前用户登录信息失效。",
+        allUsers: "全部用户",
+        partialUsers: "局部用户",
+        searchUser: "搜索用户"
+    },
+    model: {
+        usernameRule: "用户名只能包含字母,数字和\"_\"",
+        passwordRule: "密码长度至少为6位",
+        linkCodeText: "链接:{} 提取码:{}",
+        copyLinkCodeSuccess: "复制链接提取码成功",
 
-  },
-  plugin: {
-    cannotPreview: "无法预览",
-    emptyHintDefault: "没有符合条件的项目",
-    everyPage: "每页",
-    items: "条",
-    total: "共",
-    clickRefresh: "点击刷新",
-  },
-  loading: "加载中",
-  selectAll: "全选",
-  edit: "修改",
-  createTime: "创建时间",
-  download: "下载",
-  close: "关闭",
-  required: "必填",
-  cancel: "取消",
-  delete: "删除",
-  deleteDirectly: "直接删除",
-  actionCanNotRevertConfirm: "此操作不可撤回, 是否继续?",
-  actionDeleteConfirm: "确定删除吗?",
-  actionRecoveryConfirm: "确定恢复吗?",
-  prompt: "提示",
-  confirm: "确定",
-  copy: "复制",
-  copySuccess: "复制成功!",
-  copyError: "复制失败!",
-  showMore: "显示更多",
-  username: "用户名",
-  password: "密码",
-  submit: "提交",
-  save: "保存",
-  create: "创建",
-  finish: "完成",
-  operationSuccess: "操作成功",
-  operation: "操作",
-  notFound: "404 页面找不到",
-  login: "登录",
-  logout: "退出",
-  yes: "是",
-  no: "否",
-  all: "所有",
-  refresh: "刷新",
-  inputRequired: "该项必填",
+    },
+    plugin: {
+        cannotPreview: "无法预览",
+        emptyHintDefault: "没有符合条件的项目",
+        everyPage: "每页",
+        items: "条",
+        total: "共",
+        clickRefresh: "点击刷新",
+    },
+    loading: "加载中",
+    selectAll: "全选",
+    edit: "修改",
+    createTime: "创建时间",
+    download: "下载",
+    close: "关闭",
+    required: "必填",
+    cancel: "取消",
+    delete: "删除",
+    deleteDirectly: "直接删除",
+    actionCanNotRevertConfirm: "此操作不可撤回, 是否继续?",
+    actionDeleteConfirm: "确定删除吗?",
+    actionRecoveryConfirm: "确定恢复吗?",
+    prompt: "提示",
+    confirm: "确定",
+    copy: "复制",
+    copySuccess: "复制成功!",
+    copyError: "复制失败!",
+    showMore: "显示更多",
+    username: "用户名",
+    password: "密码",
+    submit: "提交",
+    save: "保存",
+    create: "创建",
+    finish: "完成",
+    operationSuccess: "操作成功",
+    operation: "操作",
+    notFound: "404 页面找不到",
+    login: "登录",
+    logout: "退出",
+    yes: "是",
+    no: "否",
+    all: "所有",
+    refresh: "刷新",
+    inputRequired: "该项必填",
 
 }
 
diff --git a/src/common/model/image/cache/ImageCache.ts b/src/common/model/image/cache/ImageCache.ts
index 107c566..2b608a5 100644
--- a/src/common/model/image/cache/ImageCache.ts
+++ b/src/common/model/image/cache/ImageCache.ts
@@ -6,66 +6,66 @@ import SafeUtil from "../../../util/SafeUtil";
 
 export default class ImageCache extends BaseEntity {
 
-  static URL_DELETE_BATCH = '/api/image/cache/delete/batch';
+    static URL_DELETE_BATCH = '/api/image/cache/delete/batch';
 
-  name: string | null = null;
-  userUuid: string | null = null;
-  matterUuid: string | null = null;
-  matterName: string | null = null;
-  mode: string | null = null;
-  md5: string | null = null;
-  size: number = 0;
-  path: number = 0;
+    name: string | null = null;
+    userUuid: string | null = null;
+    matterUuid: string | null = null;
+    matterName: string | null = null;
+    mode: string | null = null;
+    md5: string | null = null;
+    size: number = 0;
+    path: number = 0;
 
-  /*
-    这部分是辅助UI的字段信息
-   */
-  //作为勾选变量
-  check: boolean = false;
+    /*
+      这部分是辅助UI的字段信息
+     */
+    //作为勾选变量
+    check: boolean = false;
 
-  user: User = new User();
-  matter: Matter = new Matter();
+    user: User = new User();
+    matter: Matter = new Matter();
 
-  constructor(reactComponent?: React.Component) {
-    super(reactComponent);
-  }
-
-  getTAG(): string {
-    return "imageCache";
-  }
-
-  assign(obj: any) {
-    super.assign(obj);
-  }
-
-  getFilters() {
-    return [
-      ...super.getFilters(),
-      new InputFilter("User Uuid", "userUuid", null, false),
-      new InputFilter("File Uuid", "matterUuid", null, false),
-    ]
-  }
-
-  getForm() {
-    return {
-      uuid: this.uuid ? this.uuid : null
+    constructor(reactComponent?: React.Component) {
+        super(reactComponent);
     }
-  }
 
-  getResizeUrl() {
-    return '/api/alien/preview/' + this.matterUuid + '/' + this.matterName + "?ir=" + this.mode
-  }
+    getTAG(): string {
+        return "imageCache";
+    }
 
-  getOriginUrl() {
-    return '/api/alien/download/' + this.matterUuid + '/' + this.matterName
-  }
+    assign(obj: any) {
+        super.assign(obj);
+    }
+
+    getFilters() {
+        return [
+            ...super.getFilters(),
+            new InputFilter("User Uuid", "userUuid", null, false),
+            new InputFilter("File Uuid", "matterUuid", null, false),
+        ]
+    }
+
+    getForm() {
+        return {
+            uuid: this.uuid ? this.uuid : null
+        }
+    }
+
+    getResizeUrl() {
+        return '/api/alien/preview/' + this.matterUuid + '/' + this.matterName + "?ir=" + this.mode
+    }
+
+    getOriginUrl() {
+        return '/api/alien/download/' + this.matterUuid + '/' + this.matterName
+    }
 
 
-  httpDeleteBatch(uuids: string, successCallback?: () => any, errorCallback?: () => any) {
-    this.httpPost(ImageCache.URL_DELETE_BATCH, {'uuids': uuids}, function (response: any) {
-      SafeUtil.safeCallback(successCallback)(response)
-    }, errorCallback)
-  }
+    httpDeleteBatch(uuids: string, successCallback?: () => any, errorCallback?: () => any) {
+        this.httpPost(ImageCache.URL_DELETE_BATCH, {'uuids': uuids}, function (response: any) {
+            SafeUtil.safeCallback(successCallback)(response)
+        }, errorCallback)
+    }
 
 
 }
diff --git a/src/common/model/install/Install.ts b/src/common/model/install/Install.ts
index e0bee1a..4c2b7f3 100644
--- a/src/common/model/install/Install.ts
+++ b/src/common/model/install/Install.ts
@@ -6,240 +6,240 @@ import Base from "../base/Base";
 
 export default class Install extends BaseEntity {
 
-  static URL_VERIFY = '/api/install/verify'
-  static URL_TABLE_INFO_LIST = '/api/install/table/info/list'
-  static URL_ADMIN_LIST = '/api/install/admin/list'
-  static URL_CREATE_TABLE = '/api/install/create/table'
-  static URL_CREATE_ADMIN = '/api/install/create/admin'
-  static URL_VALIDATE_ADMIN = '/api/install/validate/admin'
-  static URL_FINISH = '/api/install/finish'
+    static URL_VERIFY = '/api/install/verify'
+    static URL_TABLE_INFO_LIST = '/api/install/table/info/list'
+    static URL_ADMIN_LIST = '/api/install/admin/list'
+    static URL_CREATE_TABLE = '/api/install/create/table'
+    static URL_CREATE_ADMIN = '/api/install/create/admin'
+    static URL_VALIDATE_ADMIN = '/api/install/validate/admin'
+    static URL_FINISH = '/api/install/finish'
 
-  //数据库类型
-  dbType: string = "mysql"
+    //数据库类型
+    dbType: string = "mysql"
 
-  //数据库名
-  mysqlPort: number = 3306
-  mysqlHost: string = "127.0.0.1"
-  mysqlSchema: string = "tank"
-  mysqlUsername: string = "tank"
-  mysqlPassword: string | null = null
-  mysqlCharset: string = "utf8"
+    //数据库名
+    mysqlPort: number = 3306
+    mysqlHost: string = "127.0.0.1"
+    mysqlSchema: string = "tank"
+    mysqlUsername: string = "tank"
+    mysqlPassword: string | null = null
+    mysqlCharset: string = "utf8"
 
-  //管理员用户名
-  adminUsername: string | null = null
-  adminPassword: string | null = null
-  adminRepassword: string | null = null
+    //管理员用户名
+    adminUsername: string | null = null
+    adminPassword: string | null = null
+    adminRepassword: string | null = null
 
-  //表元信息
-  tableInfoList: InstallTableInfo[] = []
+    //表元信息
+    tableInfoList: InstallTableInfo[] = []
 
-  //管理员列表
-  adminList: User[] = []
+    //管理员列表
+    adminList: User[] = []
 
-  //数据库连接是否可用
-  verified: boolean = false
-  //管理员配置完毕
-  adminConfigured: boolean = false
+    //数据库连接是否可用
+    verified: boolean = false
+    //管理员配置完毕
+    adminConfigured: boolean = false
 
 
-  constructor(reactComponent?: React.Component) {
+    constructor(reactComponent?: React.Component) {
 
-    super(reactComponent);
+        super(reactComponent);
 
-  }
-
-  assign(obj: any) {
-    super.assign(obj);
-
-  }
-
-
-  getTAG():string {
-    return "install"
-  }
-
-
-  getMysqlForm() {
-    return {
-      dbType: this.dbType,
-      mysqlHost: this.mysqlHost,
-      mysqlPort: this.mysqlPort,
-      mysqlSchema: this.mysqlSchema,
-      mysqlUsername: this.mysqlUsername,
-      mysqlPassword: this.mysqlPassword,
-      mysqlCharset: this.mysqlCharset,
-    }
-  }
-
-  getForm() {
-    return {
-      dbType: this.dbType,
-      mysqlPort: this.mysqlPort,
-      mysqlHost: this.mysqlHost,
-      mysqlSchema: this.mysqlSchema,
-      mysqlUsername: this.mysqlUsername,
-      mysqlPassword: this.mysqlPassword,
-      mysqlCharset: this.mysqlCharset,
-      adminUsername: this.adminUsername,
-      adminPassword: this.adminPassword,
-    }
-  }
-
-
-  //表创建完毕
-  tableCreated() {
-    if (!this.tableInfoList || this.tableInfoList.length === 0) {
-      return false
-    }
-    for (let i = 0; i < this.tableInfoList.length; i++) {
-      let tableInfo = this.tableInfoList[i]
-      if (!tableInfo.tableExist) {
-        return false
-      }
-
-      if (tableInfo.tableExist && tableInfo.missingFields.length !== 0) {
-        return false
-      }
     }
 
-    return true;
-  }
+    assign(obj: any) {
+        super.assign(obj);
 
-  httpVerify(successCallback?: any, errorCallback?: any, finalCallback?: any) {
-    let that = this
-
-    this.httpPost(Install.URL_VERIFY, this.getMysqlForm(), function (response: any) {
-
-      SafeUtil.safeCallback(successCallback)(response);
-
-
-    }, errorCallback)
-  }
-
-  httpTableInfoList(successCallback?: any, errorCallback?: any, finalCallback?: any) {
-    let that = this
-
-    if (!this.verified) {
-      this.defaultErrorHandler("Please verify mysql first", errorCallback)
-      return
-    }
-
-    this.httpPost(Install.URL_TABLE_INFO_LIST, this.getForm(), function (response: any) {
-
-      that.tableInfoList.splice(0, that.tableInfoList.length);
-      let list = Base.renderList(response.data.data, InstallTableInfo);
-      that.tableInfoList.push(...list)
-
-      SafeUtil.safeCallback(successCallback)(response);
-
-    }, errorCallback, finalCallback)
-  }
-
-  httpCreateTable(successCallback?: any, errorCallback?: any, finalCallback?: any) {
-    let that = this
-
-    if (!this.verified) {
-      this.defaultErrorHandler("Please verify mysql first", errorCallback)
-      return
-    }
-
-    this.httpPost(Install.URL_CREATE_TABLE, this.getForm(), function (response: any) {
-
-      that.tableInfoList.splice(0, that.tableInfoList.length);
-      that.tableInfoList.push(...response.data.data)
-
-      SafeUtil.safeCallback(successCallback)(response);
-
-    }, errorCallback, finalCallback)
-  }
-
-  //获取管理员列表
-  httpAdminList(successCallback?: any, errorCallback?: any, finalCallback?: any) {
-    let that = this
-
-    if (!this.tableCreated()) {
-      this.defaultErrorHandler("Please verify create table first", errorCallback)
-      return
     }
 
 
-    let form = this.getForm()
-
-
-    this.httpPost(Install.URL_ADMIN_LIST, form, function (response: any) {
-
-      that.adminList = BaseEntity.renderList(response.data.data, User)
-      SafeUtil.safeCallback(successCallback)(response);
-
-    }, errorCallback, finalCallback)
-  }
-
-
-  httpCreateAdmin(successCallback?: any, errorCallback?: any, finalCallback?: any) {
-    let that = this
-
-    if (!this.tableCreated()) {
-      this.defaultErrorHandler("Please verify create table first", errorCallback)
-      return
+    getTAG(): string {
+        return "install"
     }
 
 
-    if (this.adminPassword !== this.adminRepassword) {
-      this.defaultErrorHandler("password not same", errorCallback)
-      return
+    getMysqlForm() {
+        return {
+            dbType: this.dbType,
+            mysqlHost: this.mysqlHost,
+            mysqlPort: this.mysqlPort,
+            mysqlSchema: this.mysqlSchema,
+            mysqlUsername: this.mysqlUsername,
+            mysqlPassword: this.mysqlPassword,
+            mysqlCharset: this.mysqlCharset,
+        }
+    }
+
+    getForm() {
+        return {
+            dbType: this.dbType,
+            mysqlPort: this.mysqlPort,
+            mysqlHost: this.mysqlHost,
+            mysqlSchema: this.mysqlSchema,
+            mysqlUsername: this.mysqlUsername,
+            mysqlPassword: this.mysqlPassword,
+            mysqlCharset: this.mysqlCharset,
+            adminUsername: this.adminUsername,
+            adminPassword: this.adminPassword,
+        }
     }
 
 
-    let form = this.getForm()
+    //表创建完毕
+    tableCreated() {
+        if (!this.tableInfoList || this.tableInfoList.length === 0) {
+            return false
+        }
+        for (let i = 0; i < this.tableInfoList.length; i++) {
+            let tableInfo = this.tableInfoList[i]
+            if (!tableInfo.tableExist) {
+                return false
+            }
 
-    this.httpPost(Install.URL_CREATE_ADMIN, form, function (response: any) {
+            if (tableInfo.tableExist && tableInfo.missingFields.length !== 0) {
+                return false
+            }
+        }
 
-      that.adminConfigured = true
-      SafeUtil.safeCallback(successCallback)(response);
-
-    }, errorCallback, finalCallback)
-  }
-
-
-  //验证管理员账号
-  httpValidateAdmin(successCallback?: any, errorCallback?: any, finalCallback?: any) {
-    let that = this
-
-    if (!this.tableCreated()) {
-      this.defaultErrorHandler("Please verify create table first", errorCallback)
-      return
+        return true;
     }
 
-    if (!this.adminUsername || !this.adminPassword) {
-      this.defaultErrorHandler("username and password required", errorCallback)
-      return
+    httpVerify(successCallback?: any, errorCallback?: any, finalCallback?: any) {
+        let that = this
+
+        this.httpPost(Install.URL_VERIFY, this.getMysqlForm(), function (response: any) {
+
+            SafeUtil.safeCallback(successCallback)(response);
+
+
+        }, errorCallback)
     }
 
-    let form = this.getForm()
+    httpTableInfoList(successCallback?: any, errorCallback?: any, finalCallback?: any) {
+        let that = this
 
-    this.httpPost(Install.URL_VALIDATE_ADMIN, form, function (response: any) {
+        if (!this.verified) {
+            this.defaultErrorHandler("Please verify mysql first", errorCallback)
+            return
+        }
 
-      that.adminConfigured = true
-      SafeUtil.safeCallback(successCallback)(response);
+        this.httpPost(Install.URL_TABLE_INFO_LIST, this.getForm(), function (response: any) {
 
-    }, errorCallback, finalCallback)
-  }
+            that.tableInfoList.splice(0, that.tableInfoList.length);
+            let list = Base.renderList(response.data.data, InstallTableInfo);
+            that.tableInfoList.push(...list)
+
+            SafeUtil.safeCallback(successCallback)(response);
+
+        }, errorCallback, finalCallback)
+    }
+
+    httpCreateTable(successCallback?: any, errorCallback?: any, finalCallback?: any) {
+        let that = this
+
+        if (!this.verified) {
+            this.defaultErrorHandler("Please verify mysql first", errorCallback)
+            return
+        }
+
+        this.httpPost(Install.URL_CREATE_TABLE, this.getForm(), function (response: any) {
+
+            that.tableInfoList.splice(0, that.tableInfoList.length);
+            that.tableInfoList.push(...response.data.data)
+
+            SafeUtil.safeCallback(successCallback)(response);
+
+        }, errorCallback, finalCallback)
+    }
+
+    //获取管理员列表
+    httpAdminList(successCallback?: any, errorCallback?: any, finalCallback?: any) {
+        let that = this
+
+        if (!this.tableCreated()) {
+            this.defaultErrorHandler("Please verify create table first", errorCallback)
+            return
+        }
 
 
-  //完成安装过程
-  httpFinish(successCallback?: any, errorCallback?: any, finalCallback?: any) {
-    let that = this
+        let form = this.getForm()
 
 
-    let form = this.getForm()
+        this.httpPost(Install.URL_ADMIN_LIST, form, function (response: any) {
 
-    this.httpPost(Install.URL_FINISH, form, function (response: any) {
+            that.adminList = BaseEntity.renderList(response.data.data, User)
+            SafeUtil.safeCallback(successCallback)(response);
+
+        }, errorCallback, finalCallback)
+    }
 
 
-      SafeUtil.safeCallback(successCallback)(response);
+    httpCreateAdmin(successCallback?: any, errorCallback?: any, finalCallback?: any) {
+        let that = this
 
-    }, errorCallback, finalCallback)
-  }
+        if (!this.tableCreated()) {
+            this.defaultErrorHandler("Please verify create table first", errorCallback)
+            return
+        }
+
+
+        if (this.adminPassword !== this.adminRepassword) {
+            this.defaultErrorHandler("password not same", errorCallback)
+            return
+        }
+
+
+        let form = this.getForm()
+
+        this.httpPost(Install.URL_CREATE_ADMIN, form, function (response: any) {
+
+            that.adminConfigured = true
+            SafeUtil.safeCallback(successCallback)(response);
+
+        }, errorCallback, finalCallback)
+    }
+
+
+    //验证管理员账号
+    httpValidateAdmin(successCallback?: any, errorCallback?: any, finalCallback?: any) {
+        let that = this
+
+        if (!this.tableCreated()) {
+            this.defaultErrorHandler("Please verify create table first", errorCallback)
+            return
+        }
+
+        if (!this.adminUsername || !this.adminPassword) {
+            this.defaultErrorHandler("username and password required", errorCallback)
+            return
+        }
+
+        let form = this.getForm()
+
+        this.httpPost(Install.URL_VALIDATE_ADMIN, form, function (response: any) {
+
+            that.adminConfigured = true
+            SafeUtil.safeCallback(successCallback)(response);
+
+        }, errorCallback, finalCallback)
+    }
+
+
+    //完成安装过程
+    httpFinish(successCallback?: any, errorCallback?: any, finalCallback?: any) {
+        let that = this
+
+
+        let form = this.getForm()
+
+        this.httpPost(Install.URL_FINISH, form, function (response: any) {
+
+
+            SafeUtil.safeCallback(successCallback)(response);
+
+        }, errorCallback, finalCallback)
+    }
 
 }
 
diff --git a/src/common/model/install/InstallFieldInfo.ts b/src/common/model/install/InstallFieldInfo.ts
index c14a1e7..afc5871 100644
--- a/src/common/model/install/InstallFieldInfo.ts
+++ b/src/common/model/install/InstallFieldInfo.ts
@@ -1,12 +1,12 @@
 import Base from "../base/Base";
 
-export default class InstallFieldInfo extends Base{
+export default class InstallFieldInfo extends Base {
 
-  name: string = "";
-  dataType: boolean = false;
+    name: string = "";
+    dataType: boolean = false;
 
-  assign(obj: any) {
-    super.assign(obj);
-  }
+    assign(obj: any) {
+        super.assign(obj);
+    }
 
 }
diff --git a/src/common/model/install/InstallTableInfo.ts b/src/common/model/install/InstallTableInfo.ts
index a63ba43..7ae509f 100644
--- a/src/common/model/install/InstallTableInfo.ts
+++ b/src/common/model/install/InstallTableInfo.ts
@@ -3,17 +3,17 @@ import InstallFieldInfo from "./InstallFieldInfo";
 
 export default class InstallTableInfo extends Base {
 
-  name: string = "";
-  tableExist: boolean = false;
-  allFields: InstallFieldInfo[] = [];
-  missingFields: InstallFieldInfo[] = [];
+    name: string = "";
+    tableExist: boolean = false;
+    allFields: InstallFieldInfo[] = [];
+    missingFields: InstallFieldInfo[] = [];
 
-  assign(obj: any) {
-    super.assign(obj);
+    assign(obj: any) {
+        super.assign(obj);
 
-    this.assignList("allFields", InstallFieldInfo);
-    this.assignList("missingFields", InstallFieldInfo);
-  }
+        this.assignList("allFields", InstallFieldInfo);
+        this.assignList("missingFields", InstallFieldInfo);
+    }
 
 
 }
diff --git a/src/common/model/matter/Matter.ts b/src/common/model/matter/Matter.ts
index cfd99f8..e0a91df 100644
--- a/src/common/model/matter/Matter.ts
+++ b/src/common/model/matter/Matter.ts
@@ -1,5 +1,5 @@
-import { message } from "antd";
-import axios, { CancelTokenSource } from "axios";
+import {message} from "antd";
+import axios, {CancelTokenSource} from "axios";
 import BaseEntity from "../base/BaseEntity";
 import Filter from "../base/filter/Filter";
 import HttpUtil from "../../util/HttpUtil";
@@ -18,578 +18,579 @@ import MessageBoxUtil from "../../util/MessageBoxUtil";
 import PreviewerHelper from "../../../pages/widget/previewer/PreviewerHelper";
 
 export default class Matter extends BaseEntity {
-  puuid: string = "";
-  userUuid: string = "";
-  dir: boolean = false;
-  alien: boolean = false;
-  name: string = "";
-  md5: string | null = null;
-  size: number = 0;
-  privacy: boolean = true;
-  path: string | null = null;
-  times: number = 0;
-  //上次访问时间
-  visitTime: Date | null = null;
-  parent: Matter | null = null;
-  // 文件是否被软删除
-  deleted: boolean = false;
-  deleteTime: Date | null = null;
+    puuid: string = "";
+    userUuid: string = "";
+    dir: boolean = false;
+    alien: boolean = false;
+    name: string = "";
+    md5: string | null = null;
+    size: number = 0;
+    privacy: boolean = true;
+    path: string | null = null;
+    times: number = 0;
+    //上次访问时间
+    visitTime: Date | null = null;
+    parent: Matter | null = null;
+    // 文件是否被软删除
+    deleted: boolean = false;
+    deleteTime: Date | null = null;
 
-  /*
-  这部分是辅助UI的字段信息
-   */
-  //作为勾选变量
-  check: boolean = false;
-  editMode: boolean = false;
+    /*
+    这部分是辅助UI的字段信息
+     */
+    //作为勾选变量
+    check: boolean = false;
+    editMode: boolean = false;
 
-  //允许用户选择的文件类型
-  filter: string = "*";
-  //本地字段
-  //给用户的提示文字
-  uploadHint: string | null = null;
-  //浏览器中选择好的原生file,未作任何处理。
-  file: File | null = null;
-  //当前上传进度的数值 0-1之间
-  progress: number = 0;
-  //实时上传速度 byte/s
-  speed: number = 0;
-  //取消上传source
-  cancelSource: CancelTokenSource = axios.CancelToken.source();
+    //允许用户选择的文件类型
+    filter: string = "*";
+    //本地字段
+    //给用户的提示文字
+    uploadHint: string | null = null;
+    //浏览器中选择好的原生file,未作任何处理。
+    file: File | null = null;
+    //当前上传进度的数值 0-1之间
+    progress: number = 0;
+    //实时上传速度 byte/s
+    speed: number = 0;
+    //取消上传source
+    cancelSource: CancelTokenSource = axios.CancelToken.source();
 
-  static URL_MATTER_CREATE_DIRECTORY = "/api/matter/create/directory";
-  static URL_MATTER_SOFT_DELETE = "/api/matter/soft/delete";
-  static URL_MATTER_SOFT_DELETE_BATCH = "/api/matter/soft/delete/batch";
-  static URL_MATTER_RECOVERY = "/api/matter/recovery";
-  static URL_MATTER_RECOVERY_BATCH = "/api/matter/recovery/batch";
-  static URL_MATTER_DELETE = "/api/matter/delete";
-  static URL_MATTER_DELETE_BATCH = "/api/matter/delete/batch";
-  static URL_MATTER_RENAME = "/api/matter/rename";
-  static URL_CHANGE_PRIVACY = "/api/matter/change/privacy";
-  static URL_MATTER_MOVE = "/api/matter/move";
-  static URL_MATTER_DOWNLOAD = "/api/matter/download";
-  static URL_MATTER_UPLOAD = "/api/matter/upload";
-  static URL_MATTER_ZIP = "/api/matter/zip";
+    static URL_MATTER_CREATE_DIRECTORY = "/api/matter/create/directory";
+    static URL_MATTER_SOFT_DELETE = "/api/matter/soft/delete";
+    static URL_MATTER_SOFT_DELETE_BATCH = "/api/matter/soft/delete/batch";
+    static URL_MATTER_RECOVERY = "/api/matter/recovery";
+    static URL_MATTER_RECOVERY_BATCH = "/api/matter/recovery/batch";
+    static URL_MATTER_DELETE = "/api/matter/delete";
+    static URL_MATTER_DELETE_BATCH = "/api/matter/delete/batch";
+    static URL_MATTER_RENAME = "/api/matter/rename";
+    static URL_CHANGE_PRIVACY = "/api/matter/change/privacy";
+    static URL_MATTER_MOVE = "/api/matter/move";
+    static URL_MATTER_DOWNLOAD = "/api/matter/download";
+    static URL_MATTER_UPLOAD = "/api/matter/upload";
+    static URL_MATTER_ZIP = "/api/matter/zip";
 
-  static MATTER_ROOT = "root";
+    static MATTER_ROOT = "root";
 
-  //下载zip包
-  static downloadZip(uuidsString: string) {
-    window.open(
-      EnvUtil.currentHost() + Matter.URL_MATTER_ZIP + "?uuids=" + uuidsString
-    );
-  }
-
-  constructor(reactComponent?: React.Component) {
-    super(reactComponent);
-  }
-
-  assign(obj: any) {
-    super.assign(obj);
-    this.assignEntity("parent", Matter);
-    this.assignEntity("visitTime", Date);
-    this.assignEntity("deleteTime", Date);
-  }
-
-  getTAG():string {
-    return "matter"
-  }
-  getForm(): any {
-    return {
-      userUuid: this.userUuid,
-      puuid: this.puuid,
-      uuid: this.uuid ? this.uuid : null,
-      dir: this.dir,
-      alien: this.alien,
-      name: this.name,
-      md5: this.md5,
-      size: this.size,
-      privacy: this.privacy,
-      path: this.path,
-      times: this.times,
-      parent: this.parent,
-    };
-  }
-
-  getFilters(): Filter[] {
-    return [
-      ...super.getFilters(),
-      new InputFilter("父级菜单uuid", "puuid", null, false),
-      new InputFilter("用户", "userUuid", null, false),
-      new InputFilter("关键字", "name"),
-      new CheckFilter("文件夹", "dir"),
-      new CheckFilter("应用数据", "alien"),
-      new CheckFilter("删除", "deleted"),
-      new SortFilter("文件夹", "orderDir"),
-      new SortFilter("下载次数", "orderTimes"),
-      new SortFilter("大小", "orderSize"),
-      new SortFilter("名称", "orderName"),
-      new InputFilter("后缀名", "extensions"),
-      new InputFilter("分享uuid", "shareUuid"),
-      new InputFilter("提取码", "shareCode"),
-      new InputFilter("分享根目录", "shareRootUuid"),
-      new SortFilter("删除时间排序", "orderDeleteTime"),
-    ];
-  }
-
-  getUrlPrefix() {
-    return "/api/matter";
-  }
-
-  isImage() {
-    return FileUtil.isImage(this.name);
-  }
-
-  isPdf() {
-    return FileUtil.isPdf(this.name);
-  }
-
-  isText() {
-    return FileUtil.isText(this.name);
-  }
-
-  isDoc() {
-    return FileUtil.isDoc(this.name);
-  }
-
-  isPpt() {
-    return FileUtil.isPpt(this.name);
-  }
-
-  isXls() {
-    return FileUtil.isXls(this.name);
-  }
-
-  isAudio() {
-    return FileUtil.isAudio(this.name);
-  }
-
-  isVideo() {
-    return FileUtil.isVideo(this.name);
-  }
-
-  isPsd() {
-    return FileUtil.isPsd(this.name);
-  }
-
-  getIcon() {
-    if (FileUtil.isImage(this.name)) {
-      return ImageUtil.handleImageUrl(this.getPreviewUrl(), false, 100, 100);
-    } else {
-      return FileUtil.getIcon(this.name, this.dir);
-    }
-  }
-
-  //下载文件
-  download(downloadUrl?: string | null) {
-    if (!downloadUrl) {
-      downloadUrl = this.getDownloadUrl();
-    }
-    window.open(downloadUrl);
-  }
-
-  //预览文件 在分享的预览中才主动传入previewUrl.
-  preview(previewUrl?: string | null) {
-    let shareMode = true;
-    if (previewUrl) {
-      shareMode = true;
-    } else {
-      shareMode = false;
-      previewUrl = this.getPreviewUrl();
+    //下载zip包
+    static downloadZip(uuidsString: string) {
+        window.open(
+            EnvUtil.currentHost() + Matter.URL_MATTER_ZIP + "?uuids=" + uuidsString
+        );
     }
 
-    if (this.isImage()) {
-      ImagePreviewer.showSinglePhoto(previewUrl);
-    } else {
-      if (shareMode) {
-        PreviewerHelper.preview(this, previewUrl);
-      } else {
-        PreviewerHelper.preview(this);
-      }
+    constructor(reactComponent?: React.Component) {
+        super(reactComponent);
     }
-  }
 
-  httpCreateDirectory(
-    successCallback?: any,
-    errorCallback?: any,
-    finallyCallback?: any
-  ) {
-    let that = this;
-    let form = { userUuid: that.userUuid, name: that.name, puuid: that.puuid };
+    assign(obj: any) {
+        super.assign(obj);
+        this.assignEntity("parent", Matter);
+        this.assignEntity("visitTime", Date);
+        this.assignEntity("deleteTime", Date);
+    }
 
-    return this.httpPost(
-      Matter.URL_MATTER_CREATE_DIRECTORY,
-      form,
-      function (response: any) {
-        that.assign(response.data.data);
-        typeof successCallback === "function" && successCallback(response);
-      },
-      errorCallback,
-      finallyCallback
-    );
-  }
+    getTAG(): string {
+        return "matter"
+    }
 
-  httpSoftDelete(successCallback?: any, errorCallback?: any) {
-    this.httpPost(
-      Matter.URL_MATTER_SOFT_DELETE,
-      { uuid: this.uuid },
-      function (response: any) {
-        typeof successCallback === "function" && successCallback(response);
-      },
-      errorCallback
-    );
-  }
+    getForm(): any {
+        return {
+            userUuid: this.userUuid,
+            puuid: this.puuid,
+            uuid: this.uuid ? this.uuid : null,
+            dir: this.dir,
+            alien: this.alien,
+            name: this.name,
+            md5: this.md5,
+            size: this.size,
+            privacy: this.privacy,
+            path: this.path,
+            times: this.times,
+            parent: this.parent,
+        };
+    }
 
-  httpSoftDeleteBatch(
-    uuids: string,
-    successCallback?: any,
-    errorCallback?: any
-  ) {
-    this.httpPost(
-      Matter.URL_MATTER_SOFT_DELETE_BATCH,
-      { uuids: uuids },
-      function (response: any) {
-        typeof successCallback === "function" && successCallback(response);
-      },
-      errorCallback
-    );
-  }
+    getFilters(): Filter[] {
+        return [
+            ...super.getFilters(),
+            new InputFilter("父级菜单uuid", "puuid", null, false),
+            new InputFilter("用户", "userUuid", null, false),
+            new InputFilter("关键字", "name"),
+            new CheckFilter("文件夹", "dir"),
+            new CheckFilter("应用数据", "alien"),
+            new CheckFilter("删除", "deleted"),
+            new SortFilter("文件夹", "orderDir"),
+            new SortFilter("下载次数", "orderTimes"),
+            new SortFilter("大小", "orderSize"),
+            new SortFilter("名称", "orderName"),
+            new InputFilter("后缀名", "extensions"),
+            new InputFilter("分享uuid", "shareUuid"),
+            new InputFilter("提取码", "shareCode"),
+            new InputFilter("分享根目录", "shareRootUuid"),
+            new SortFilter("删除时间排序", "orderDeleteTime"),
+        ];
+    }
 
-  httpDelete(successCallback?: any, errorCallback?: any) {
-    this.httpPost(
-      Matter.URL_MATTER_DELETE,
-      { uuid: this.uuid },
-      function (response: any) {
-        typeof successCallback === "function" && successCallback(response);
-      },
-      errorCallback
-    );
-  }
+    getUrlPrefix() {
+        return "/api/matter";
+    }
 
-  httpDeleteBatch(uuids: string, successCallback?: any, errorCallback?: any) {
-    this.httpPost(
-      Matter.URL_MATTER_DELETE_BATCH,
-      { uuids: uuids },
-      function (response: any) {
-        typeof successCallback === "function" && successCallback(response);
-      },
-      errorCallback
-    );
-  }
+    isImage() {
+        return FileUtil.isImage(this.name);
+    }
 
-  httpRecovery(successCallback?: any, errorCallback?: any) {
-    this.httpPost(
-      Matter.URL_MATTER_RECOVERY,
-      { uuid: this.uuid },
-      function (response: any) {
-        typeof successCallback === "function" && successCallback(response);
-      },
-      errorCallback
-    );
-  }
+    isPdf() {
+        return FileUtil.isPdf(this.name);
+    }
 
-  httpRecoveryBatch(uuids: string, successCallback?: any, errorCallback?: any) {
-    this.httpPost(
-      Matter.URL_MATTER_RECOVERY_BATCH,
-      { uuids: uuids },
-      function (response: any) {
-        typeof successCallback === "function" && successCallback(response);
-      },
-      errorCallback
-    );
-  }
+    isText() {
+        return FileUtil.isText(this.name);
+    }
 
-  httpRename(
-    name: string,
-    successCallback?: any,
-    errorCallback?: any,
-    finallyCallback?: any
-  ) {
-    let that = this;
-    this.httpPost(
-      Matter.URL_MATTER_RENAME,
-      { uuid: this.uuid, name: name },
-      function (response: any) {
-        that.assign(response.data.data);
-        typeof successCallback === "function" && successCallback(response);
-      },
-      errorCallback,
-      finallyCallback
-    );
-  }
+    isDoc() {
+        return FileUtil.isDoc(this.name);
+    }
 
-  httpChangePrivacy(
-    privacy: boolean,
-    successCallback?: any,
-    errorCallback?: any
-  ) {
-    let that = this;
-    this.httpPost(
-      Matter.URL_CHANGE_PRIVACY,
-      { uuid: this.uuid, privacy: privacy },
-      function (response: any) {
-        that.privacy = privacy;
-        if (typeof successCallback === "function") {
-          successCallback(response);
-          message.success(response.data.msg);
+    isPpt() {
+        return FileUtil.isPpt(this.name);
+    }
+
+    isXls() {
+        return FileUtil.isXls(this.name);
+    }
+
+    isAudio() {
+        return FileUtil.isAudio(this.name);
+    }
+
+    isVideo() {
+        return FileUtil.isVideo(this.name);
+    }
+
+    isPsd() {
+        return FileUtil.isPsd(this.name);
+    }
+
+    getIcon() {
+        if (FileUtil.isImage(this.name)) {
+            return ImageUtil.handleImageUrl(this.getPreviewUrl(), false, 100, 100);
         } else {
-          message.success(response.data.msg);
+            return FileUtil.getIcon(this.name, this.dir);
         }
-      },
-      errorCallback
-    );
-  }
-
-  httpMove(
-    srcUuids: string,
-    destUuid: string,
-    successCallback?: any,
-    errorCallback?: any
-  ) {
-    let form: any = { srcUuids: srcUuids };
-    if (destUuid) {
-      form.destUuid = destUuid;
-    } else {
-      form.destUuid = "root";
-    }
-    this.httpPost(
-      Matter.URL_MATTER_MOVE,
-      form,
-      function (response: any) {
-        typeof successCallback === "function" && successCallback(response);
-      },
-      errorCallback
-    );
-  }
-
-  /*
-  以下是和上传相关的内容。
-   */
-
-  //从file中装填metaData
-  validate() {
-    if (!this.file) {
-      this.errorMessage = "请选择上传文件";
-      return false;
     }
 
-    this.name = this.file.name;
-    if (!this.name) {
-      this.errorMessage = "请选择上传文件";
-      return false;
-    }
-
-    this.size = this.file.size;
-
-    this.errorMessage = null;
-    return true;
-  }
-
-  //验证过滤器有没有误填写,这个方法主要给开发者使用。
-  validateFilter() {
-    let filter = this.filter;
-    if (filter === null || filter === "") {
-      this.errorMessage = "过滤器设置错误,请检查-1";
-      console.error("过滤器设置错误,请检查.-1");
-      return false;
-    }
-    if (filter !== "*") {
-      let regex1 = /^(image|audio|video|text)(\|(image|audio|video|text))*$/g;
-      let regex2 = /^(\.[\w]+)(\|\.[\w]+)*$/;
-      // 测试几种特殊类型 image|audio|video|text
-
-      if (!regex1.test(filter)) {
-        //测试后缀名
-        if (!regex2.test(filter)) {
-          this.errorMessage = "过滤器设置错误,请检查-2";
-          console.error("过滤器设置错误,请检查.-2");
-          return false;
+    //下载文件
+    download(downloadUrl?: string | null) {
+        if (!downloadUrl) {
+            downloadUrl = this.getDownloadUrl();
         }
-      }
+        window.open(downloadUrl);
     }
 
-    //validate privacy
-    let privacy = this.privacy;
-    if (!privacy) {
-      if (privacy !== false) {
-        this.errorMessage = "privacy属性为Boolean类型";
-        console.error("privacy属性为Boolean类型.");
-        return false;
-      }
+    //预览文件 在分享的预览中才主动传入previewUrl.
+    preview(previewUrl?: string | null) {
+        let shareMode = true;
+        if (previewUrl) {
+            shareMode = true;
+        } else {
+            shareMode = false;
+            previewUrl = this.getPreviewUrl();
+        }
+
+        if (this.isImage()) {
+            ImagePreviewer.showSinglePhoto(previewUrl);
+        } else {
+            if (shareMode) {
+                PreviewerHelper.preview(this, previewUrl);
+            } else {
+                PreviewerHelper.preview(this);
+            }
+        }
     }
 
-    return true;
-  }
+    httpCreateDirectory(
+        successCallback?: any,
+        errorCallback?: any,
+        finallyCallback?: any
+    ) {
+        let that = this;
+        let form = {userUuid: that.userUuid, name: that.name, puuid: that.puuid};
 
-  //验证用户上传的文件是否符合过滤器
-  validateFileType() {
-    if (!this.filter) {
-      this.errorMessage = "该过滤条件有问题";
-      return false;
-    }
-    if (this.filter === "*") {
-      this.errorMessage = null;
-      return true;
+        return this.httpPost(
+            Matter.URL_MATTER_CREATE_DIRECTORY,
+            form,
+            function (response: any) {
+                that.assign(response.data.data);
+                typeof successCallback === "function" && successCallback(response);
+            },
+            errorCallback,
+            finallyCallback
+        );
     }
 
-    let type = MimeUtil.getMimeType(this.name);
-    let extension = MimeUtil.getExtension(this.name);
-    let simpleType = type.substring(0, type.indexOf("/"));
-
-    //专门解决android微信浏览器中名字乱命名的bug.
-    if (StringUtil.startWith(this.name, "image%3A")) {
-      extension = "jpg";
-      simpleType = "image";
-    } else if (StringUtil.startWith(this.name, "video%3A")) {
-      extension = "mp4";
-      simpleType = "video";
-    } else if (StringUtil.startWith(this.name, "audio%3A")) {
-      extension = "mp3";
-      simpleType = "audio";
+    httpSoftDelete(successCallback?: any, errorCallback?: any) {
+        this.httpPost(
+            Matter.URL_MATTER_SOFT_DELETE,
+            {uuid: this.uuid},
+            function (response: any) {
+                typeof successCallback === "function" && successCallback(response);
+            },
+            errorCallback
+        );
     }
 
-    if (StringUtil.containStr(this.filter, extension)) {
-      this.errorMessage = null;
-      return true;
+    httpSoftDeleteBatch(
+        uuids: string,
+        successCallback?: any,
+        errorCallback?: any
+    ) {
+        this.httpPost(
+            Matter.URL_MATTER_SOFT_DELETE_BATCH,
+            {uuids: uuids},
+            function (response: any) {
+                typeof successCallback === "function" && successCallback(response);
+            },
+            errorCallback
+        );
     }
 
-    if (simpleType) {
-      if (StringUtil.containStr(this.filter, simpleType)) {
+    httpDelete(successCallback?: any, errorCallback?: any) {
+        this.httpPost(
+            Matter.URL_MATTER_DELETE,
+            {uuid: this.uuid},
+            function (response: any) {
+                typeof successCallback === "function" && successCallback(response);
+            },
+            errorCallback
+        );
+    }
+
+    httpDeleteBatch(uuids: string, successCallback?: any, errorCallback?: any) {
+        this.httpPost(
+            Matter.URL_MATTER_DELETE_BATCH,
+            {uuids: uuids},
+            function (response: any) {
+                typeof successCallback === "function" && successCallback(response);
+            },
+            errorCallback
+        );
+    }
+
+    httpRecovery(successCallback?: any, errorCallback?: any) {
+        this.httpPost(
+            Matter.URL_MATTER_RECOVERY,
+            {uuid: this.uuid},
+            function (response: any) {
+                typeof successCallback === "function" && successCallback(response);
+            },
+            errorCallback
+        );
+    }
+
+    httpRecoveryBatch(uuids: string, successCallback?: any, errorCallback?: any) {
+        this.httpPost(
+            Matter.URL_MATTER_RECOVERY_BATCH,
+            {uuids: uuids},
+            function (response: any) {
+                typeof successCallback === "function" && successCallback(response);
+            },
+            errorCallback
+        );
+    }
+
+    httpRename(
+        name: string,
+        successCallback?: any,
+        errorCallback?: any,
+        finallyCallback?: any
+    ) {
+        let that = this;
+        this.httpPost(
+            Matter.URL_MATTER_RENAME,
+            {uuid: this.uuid, name: name},
+            function (response: any) {
+                that.assign(response.data.data);
+                typeof successCallback === "function" && successCallback(response);
+            },
+            errorCallback,
+            finallyCallback
+        );
+    }
+
+    httpChangePrivacy(
+        privacy: boolean,
+        successCallback?: any,
+        errorCallback?: any
+    ) {
+        let that = this;
+        this.httpPost(
+            Matter.URL_CHANGE_PRIVACY,
+            {uuid: this.uuid, privacy: privacy},
+            function (response: any) {
+                that.privacy = privacy;
+                if (typeof successCallback === "function") {
+                    successCallback(response);
+                    message.success(response.data.msg);
+                } else {
+                    message.success(response.data.msg);
+                }
+            },
+            errorCallback
+        );
+    }
+
+    httpMove(
+        srcUuids: string,
+        destUuid: string,
+        successCallback?: any,
+        errorCallback?: any
+    ) {
+        let form: any = {srcUuids: srcUuids};
+        if (destUuid) {
+            form.destUuid = destUuid;
+        } else {
+            form.destUuid = "root";
+        }
+        this.httpPost(
+            Matter.URL_MATTER_MOVE,
+            form,
+            function (response: any) {
+                typeof successCallback === "function" && successCallback(response);
+            },
+            errorCallback
+        );
+    }
+
+    /*
+    以下是和上传相关的内容。
+     */
+
+    //从file中装填metaData
+    validate() {
+        if (!this.file) {
+            this.errorMessage = "请选择上传文件";
+            return false;
+        }
+
+        this.name = this.file.name;
+        if (!this.name) {
+            this.errorMessage = "请选择上传文件";
+            return false;
+        }
+
+        this.size = this.file.size;
+
         this.errorMessage = null;
         return true;
-      }
-    }
-    this.errorMessage = "您上传的文件格式不符合要求";
-    return false;
-  }
-
-  //文件上传
-  httpUpload(successCallback?: any, failureCallback?: any) {
-    let that = this;
-
-    //验证是否装填好
-    if (!this.validate()) {
-      return;
     }
 
-    //验证用户填写的过滤条件是否正确
-    if (!this.validateFilter()) {
-      return;
-    }
-
-    //验证是否满足过滤器
-    if (!this.validateFileType()) {
-      MessageBoxUtil.error("文件类型不满足,请重试");
-      return;
-    }
-
-    //(兼容性:chrome,ff,IE9及以上)
-    let formData = new FormData();
-
-    formData.append("userUuid", that.userUuid);
-    formData.append("puuid", that.puuid);
-    formData.append("file", that.file!);
-    formData.append("alien", that.alien.toString());
-    formData.append("privacy", that.privacy.toString());
-
-    //闭包
-    let lastTimeStamp = new Date().getTime();
-    let lastSize = 0;
-
-    that.loading = true;
-
-    HttpUtil.httpPostFile(
-      Matter.URL_MATTER_UPLOAD,
-      formData,
-      function (response: any) {
-        that.uuid = response.data.data.uuid;
-        SafeUtil.safeCallback(successCallback)(response);
-      },
-      function (err: any) {
-        if (axios.isCancel(err)) {
-          that.clear();
-          SafeUtil.safeCallback(failureCallback)();
-          return;
+    //验证过滤器有没有误填写,这个方法主要给开发者使用。
+    validateFilter() {
+        let filter = this.filter;
+        if (filter === null || filter === "") {
+            this.errorMessage = "过滤器设置错误,请检查-1";
+            console.error("过滤器设置错误,请检查.-1");
+            return false;
         }
-        const response = err.response;
-        that.errorMessage = response;
-        that.clear();
-        that.defaultErrorHandler(response);
-        SafeUtil.safeCallback(failureCallback)(that.getErrorMessage(response));
-      },
-      function () {
-        that.loading = false;
-      },
-      function (event) {
-        //上传进度。
-        that.progress = event.loaded / event.total;
+        if (filter !== "*") {
+            let regex1 = /^(image|audio|video|text)(\|(image|audio|video|text))*$/g;
+            let regex2 = /^(\.[\w]+)(\|\.[\w]+)*$/;
+            // 测试几种特殊类型 image|audio|video|text
 
-        let currentTime = new Date().getTime();
-        let deltaTime = currentTime - lastTimeStamp;
-
-        //每1s计算一次速度
-        if (deltaTime > 1000) {
-          lastTimeStamp = currentTime;
-
-          let currentSize = event.loaded;
-          let deltaSize = currentSize - lastSize;
-          lastSize = currentSize;
-
-          that.speed = NumberUtil.parseInt(
-            (deltaSize / (deltaTime / 1000)).toFixed(0)
-          );
+            if (!regex1.test(filter)) {
+                //测试后缀名
+                if (!regex2.test(filter)) {
+                    this.errorMessage = "过滤器设置错误,请检查-2";
+                    console.error("过滤器设置错误,请检查.-2");
+                    return false;
+                }
+            }
         }
-        that.updateUI();
-      },
-      {
-        cancelToken: that.cancelSource.token,
-      }
-    );
-  }
 
-  cancelUpload() {
-    this.cancelSource.cancel();
-  }
+        //validate privacy
+        let privacy = this.privacy;
+        if (!privacy) {
+            if (privacy !== false) {
+                this.errorMessage = "privacy属性为Boolean类型";
+                console.error("privacy属性为Boolean类型.");
+                return false;
+            }
+        }
 
-  //清除文件
-  clear() {
-    //filter,privacy不变
-    let matter = new Matter();
-    matter.filter = this.filter;
-    matter.privacy = this.privacy;
-    matter.errorMessage = this.errorMessage;
-    matter.uploadHint = this.uploadHint;
-    this.assign(matter);
-  }
+        return true;
+    }
 
-  getPreviewUrl(downloadTokenUuid?: string): string {
-    return `${EnvUtil.currentHost()}/api/alien/preview/${this.uuid}/${
-      this.name
-    }${downloadTokenUuid ? "?downloadTokenUuid=" + downloadTokenUuid : ""}`;
-  }
+    //验证用户上传的文件是否符合过滤器
+    validateFileType() {
+        if (!this.filter) {
+            this.errorMessage = "该过滤条件有问题";
+            return false;
+        }
+        if (this.filter === "*") {
+            this.errorMessage = null;
+            return true;
+        }
 
-  getDownloadUrl(downloadTokenUuid?: string): string {
-    return `${EnvUtil.currentHost()}/api/alien/download/${this.uuid}/${
-      this.name
-    }${downloadTokenUuid ? "?downloadTokenUuid=" + downloadTokenUuid : ""}`;
-  }
+        let type = MimeUtil.getMimeType(this.name);
+        let extension = MimeUtil.getExtension(this.name);
+        let simpleType = type.substring(0, type.indexOf("/"));
 
-  getShareDownloadUrl(
-    shareUuid: string,
-    shareCode: string,
-    shareRootUuid: string
-  ): string {
-    return `${EnvUtil.currentHost()}/api/alien/download/${this.uuid}/${
-      this.name
-    }?shareUuid=${shareUuid}&shareCode=${shareCode}&shareRootUuid=${shareRootUuid}`;
-  }
+        //专门解决android微信浏览器中名字乱命名的bug.
+        if (StringUtil.startWith(this.name, "image%3A")) {
+            extension = "jpg";
+            simpleType = "image";
+        } else if (StringUtil.startWith(this.name, "video%3A")) {
+            extension = "mp4";
+            simpleType = "video";
+        } else if (StringUtil.startWith(this.name, "audio%3A")) {
+            extension = "mp3";
+            simpleType = "audio";
+        }
 
-  getSharePreviewUrl(
-    shareUuid: string,
-    shareCode: string,
-    shareRootUuid: string
-  ): string {
-    return `${EnvUtil.currentHost()}/api/alien/preview/${this.uuid}/${
-      this.name
-    }?shareUuid=${shareUuid}&shareCode=${shareCode}&shareRootUuid=${shareRootUuid}`;
-  }
+        if (StringUtil.containStr(this.filter, extension)) {
+            this.errorMessage = null;
+            return true;
+        }
+
+        if (simpleType) {
+            if (StringUtil.containStr(this.filter, simpleType)) {
+                this.errorMessage = null;
+                return true;
+            }
+        }
+        this.errorMessage = "您上传的文件格式不符合要求";
+        return false;
+    }
+
+    //文件上传
+    httpUpload(successCallback?: any, failureCallback?: any) {
+        let that = this;
+
+        //验证是否装填好
+        if (!this.validate()) {
+            return;
+        }
+
+        //验证用户填写的过滤条件是否正确
+        if (!this.validateFilter()) {
+            return;
+        }
+
+        //验证是否满足过滤器
+        if (!this.validateFileType()) {
+            MessageBoxUtil.error("文件类型不满足,请重试");
+            return;
+        }
+
+        //(兼容性:chrome,ff,IE9及以上)
+        let formData = new FormData();
+
+        formData.append("userUuid", that.userUuid);
+        formData.append("puuid", that.puuid);
+        formData.append("file", that.file!);
+        formData.append("alien", that.alien.toString());
+        formData.append("privacy", that.privacy.toString());
+
+        //闭包
+        let lastTimeStamp = new Date().getTime();
+        let lastSize = 0;
+
+        that.loading = true;
+
+        HttpUtil.httpPostFile(
+            Matter.URL_MATTER_UPLOAD,
+            formData,
+            function (response: any) {
+                that.uuid = response.data.data.uuid;
+                SafeUtil.safeCallback(successCallback)(response);
+            },
+            function (err: any) {
+                if (axios.isCancel(err)) {
+                    that.clear();
+                    SafeUtil.safeCallback(failureCallback)();
+                    return;
+                }
+                const response = err.response;
+                that.errorMessage = response;
+                that.clear();
+                that.defaultErrorHandler(response);
+                SafeUtil.safeCallback(failureCallback)(that.getErrorMessage(response));
+            },
+            function () {
+                that.loading = false;
+            },
+            function (event) {
+                //上传进度。
+                that.progress = event.loaded / event.total;
+
+                let currentTime = new Date().getTime();
+                let deltaTime = currentTime - lastTimeStamp;
+
+                //每1s计算一次速度
+                if (deltaTime > 1000) {
+                    lastTimeStamp = currentTime;
+
+                    let currentSize = event.loaded;
+                    let deltaSize = currentSize - lastSize;
+                    lastSize = currentSize;
+
+                    that.speed = NumberUtil.parseInt(
+                        (deltaSize / (deltaTime / 1000)).toFixed(0)
+                    );
+                }
+                that.updateUI();
+            },
+            {
+                cancelToken: that.cancelSource.token,
+            }
+        );
+    }
+
+    cancelUpload() {
+        this.cancelSource.cancel();
+    }
+
+    //清除文件
+    clear() {
+        //filter,privacy不变
+        let matter = new Matter();
+        matter.filter = this.filter;
+        matter.privacy = this.privacy;
+        matter.errorMessage = this.errorMessage;
+        matter.uploadHint = this.uploadHint;
+        this.assign(matter);
+    }
+
+    getPreviewUrl(downloadTokenUuid?: string): string {
+        return `${EnvUtil.currentHost()}/api/alien/preview/${this.uuid}/${
+            this.name
+        }${downloadTokenUuid ? "?downloadTokenUuid=" + downloadTokenUuid : ""}`;
+    }
+
+    getDownloadUrl(downloadTokenUuid?: string): string {
+        return `${EnvUtil.currentHost()}/api/alien/download/${this.uuid}/${
+            this.name
+        }${downloadTokenUuid ? "?downloadTokenUuid=" + downloadTokenUuid : ""}`;
+    }
+
+    getShareDownloadUrl(
+        shareUuid: string,
+        shareCode: string,
+        shareRootUuid: string
+    ): string {
+        return `${EnvUtil.currentHost()}/api/alien/download/${this.uuid}/${
+            this.name
+        }?shareUuid=${shareUuid}&shareCode=${shareCode}&shareRootUuid=${shareRootUuid}`;
+    }
+
+    getSharePreviewUrl(
+        shareUuid: string,
+        shareCode: string,
+        shareRootUuid: string
+    ): string {
+        return `${EnvUtil.currentHost()}/api/alien/preview/${this.uuid}/${
+            this.name
+        }?shareUuid=${shareUuid}&shareCode=${shareCode}&shareRootUuid=${shareRootUuid}`;
+    }
 }
diff --git a/src/common/model/preference/Preference.ts b/src/common/model/preference/Preference.ts
index 54cc17e..6fc614e 100644
--- a/src/common/model/preference/Preference.ts
+++ b/src/common/model/preference/Preference.ts
@@ -7,154 +7,154 @@ import ScanConfig from "./model/ScanConfig";
 
 export default class Preference extends BaseEntity {
 
-  //获取当前登录者的信息
-  static URL_API_PREFERENCE_FETCH = '/api/preference/fetch'
-  static URL_API_SYSTEM_CLEANUP = '/api/preference/system/cleanup'
-  static URL_API_PREFERENCE_EDIT_PREVIEW_CONFIG = '/api/preference/edit/preview/config'
-  static URL_API_PREFERENCE_EDIT_SCAN = '/api/preference/edit/scan/config'
-  static URL_API_PREFERENCE_SCAN_ONCE = '/api/preference/scan/once'
+    //获取当前登录者的信息
+    static URL_API_PREFERENCE_FETCH = '/api/preference/fetch'
+    static URL_API_SYSTEM_CLEANUP = '/api/preference/system/cleanup'
+    static URL_API_PREFERENCE_EDIT_PREVIEW_CONFIG = '/api/preference/edit/preview/config'
+    static URL_API_PREFERENCE_EDIT_SCAN = '/api/preference/edit/scan/config'
+    static URL_API_PREFERENCE_SCAN_ONCE = '/api/preference/scan/once'
 
 
-  //网站名称
-  name: string = ""
+    //网站名称
+    name: string = ""
 
-  //logo
-  logoUrl: string | null = null
-  faviconUrl: string | null = null
+    //logo
+    logoUrl: string | null = null
+    faviconUrl: string | null = null
 
-  //版权信息
-  copyright: string = ""
-  record: string = ""
+    //版权信息
+    copyright: string = ""
+    record: string = ""
 
-  //大小限制
-  downloadDirMaxSize: number = -1
-  //文件数量
-  downloadDirMaxNum: number = -1
-  //用户默认总大小限制
-  defaultTotalSizeLimit: number = -1
-  //回收站保存文件天数
-  deletedKeepDays: number = 7
-  //是否允许自主注册
-  allowRegister: boolean = false
-  //预览配置
-  previewConfig: PreviewConfig = new PreviewConfig()
-  //扫描磁盘配置
-  scanConfig: ScanConfig = new ScanConfig()
-  //后台版本
-  version: string | null = null
+    //大小限制
+    downloadDirMaxSize: number = -1
+    //文件数量
+    downloadDirMaxNum: number = -1
+    //用户默认总大小限制
+    defaultTotalSizeLimit: number = -1
+    //回收站保存文件天数
+    deletedKeepDays: number = 7
+    //是否允许自主注册
+    allowRegister: boolean = false
+    //预览配置
+    previewConfig: PreviewConfig = new PreviewConfig()
+    //扫描磁盘配置
+    scanConfig: ScanConfig = new ScanConfig()
+    //后台版本
+    version: string | null = null
 
 
-  //*****************前端辅助变量***********************/
-  //网站是否完成了安装
-  installed: boolean = true
+    //*****************前端辅助变量***********************/
+    //网站是否完成了安装
+    installed: boolean = true
 
-  constructor(reactComponent?: React.Component) {
+    constructor(reactComponent?: React.Component) {
 
-    super(reactComponent);
+        super(reactComponent);
 
-  }
-
-
-  assign(obj: any) {
-    super.assign(obj);
-
-    this.assignEntity("previewConfig", PreviewConfig)
-    this.assignEntity("scanConfig", ScanConfig)
-  }
-
-  getTAG():string {
-    return "preference"
-  }
-
-  getRecycleBinStatus() {
-    return this.deletedKeepDays > 0
-  }
-
-  getForm(): any {
-    return {
-      name: this.name,
-      logoUrl: this.logoUrl,
-      faviconUrl: this.faviconUrl,
-      copyright: this.copyright,
-      record: this.record,
-      downloadDirMaxNum: this.downloadDirMaxNum,
-      downloadDirMaxSize: this.downloadDirMaxSize,
-      defaultTotalSizeLimit: this.defaultTotalSizeLimit,
-      deletedKeepDays: this.deletedKeepDays,
-      allowRegister: this.allowRegister,
-      previewConfig: JsonUtil.toJson(this.previewConfig.getForm()),
-      scanConfig: JsonUtil.toJson(this.scanConfig.getForm())
-    };
-  }
-
-
-  //修改title和favicon
-  updateTitleAndFavicon() {
-
-    if (this.faviconUrl) {
-      //修改favicon
-      let link: any = document.querySelector("link[rel*='icon']") || document.createElement('link');
-      link.type = 'image/x-icon';
-      link.rel = 'shortcut icon';
-      link.href = this.faviconUrl;
-      document.getElementsByTagName('head')[0].appendChild(link);
     }
 
-    document.title = this.name
 
-  }
+    assign(obj: any) {
+        super.assign(obj);
 
-  httpFetch(successCallback?: any, errorCallback?: any, finalCallback?: any) {
-    let that = this
-    this.httpPost(Preference.URL_API_PREFERENCE_FETCH, {}, function (response: any) {
+        this.assignEntity("previewConfig", PreviewConfig)
+        this.assignEntity("scanConfig", ScanConfig)
+    }
 
-      that.assign(response.data.data);
+    getTAG(): string {
+        return "preference"
+    }
 
-      that.updateTitleAndFavicon()
+    getRecycleBinStatus() {
+        return this.deletedKeepDays > 0
+    }
 
-      SafeUtil.safeCallback(successCallback)(response);
+    getForm(): any {
+        return {
+            name: this.name,
+            logoUrl: this.logoUrl,
+            faviconUrl: this.faviconUrl,
+            copyright: this.copyright,
+            record: this.record,
+            downloadDirMaxNum: this.downloadDirMaxNum,
+            downloadDirMaxSize: this.downloadDirMaxSize,
+            defaultTotalSizeLimit: this.defaultTotalSizeLimit,
+            deletedKeepDays: this.deletedKeepDays,
+            allowRegister: this.allowRegister,
+            previewConfig: JsonUtil.toJson(this.previewConfig.getForm()),
+            scanConfig: JsonUtil.toJson(this.scanConfig.getForm())
+        };
+    }
 
-    }, errorCallback, finalCallback)
-  }
 
-  httpSystemCleanup(password: string, successCallback?: any, errorCallback?: any, finalCallback?: any) {
-    let that = this
-    this.httpPost(Preference.URL_API_SYSTEM_CLEANUP, {password}, function (response: any) {
+    //修改title和favicon
+    updateTitleAndFavicon() {
 
-      SafeUtil.safeCallback(successCallback)(response);
+        if (this.faviconUrl) {
+            //修改favicon
+            let link: any = document.querySelector("link[rel*='icon']") || document.createElement('link');
+            link.type = 'image/x-icon';
+            link.rel = 'shortcut icon';
+            link.href = this.faviconUrl;
+            document.getElementsByTagName('head')[0].appendChild(link);
+        }
 
-    }, errorCallback, finalCallback)
-  }
+        document.title = this.name
 
-  httpSavePreviewEngine(successCallback?: any, errorCallback?: any, finalCallback?: any) {
-    const that = this
-    this.httpPost(Preference.URL_API_PREFERENCE_EDIT_PREVIEW_CONFIG, this.getForm(), function(response: any) {
+    }
 
-      that.assign(response.data.data);
+    httpFetch(successCallback?: any, errorCallback?: any, finalCallback?: any) {
+        let that = this
+        this.httpPost(Preference.URL_API_PREFERENCE_FETCH, {}, function (response: any) {
 
-      SafeUtil.safeCallback(successCallback)(response);
+            that.assign(response.data.data);
 
-    }, errorCallback, finalCallback);
+            that.updateTitleAndFavicon()
 
-  }
+            SafeUtil.safeCallback(successCallback)(response);
 
-  httpSaveScan(successCallback?: any, errorCallback?: any, finalCallback?: any) {
-    const that = this
-    this.httpPost(Preference.URL_API_PREFERENCE_EDIT_SCAN, this.getForm(), function(response: any) {
+        }, errorCallback, finalCallback)
+    }
 
-      that.assign(response.data.data);
+    httpSystemCleanup(password: string, successCallback?: any, errorCallback?: any, finalCallback?: any) {
+        let that = this
+        this.httpPost(Preference.URL_API_SYSTEM_CLEANUP, {password}, function (response: any) {
 
-      SafeUtil.safeCallback(successCallback)(response);
+            SafeUtil.safeCallback(successCallback)(response);
 
-    }, errorCallback, finalCallback);
+        }, errorCallback, finalCallback)
+    }
 
-  }
+    httpSavePreviewEngine(successCallback?: any, errorCallback?: any, finalCallback?: any) {
+        const that = this
+        this.httpPost(Preference.URL_API_PREFERENCE_EDIT_PREVIEW_CONFIG, this.getForm(), function (response: any) {
 
-  httpScanOnce(successCallback?: any, errorCallback?: any, finalCallback?: any) {
-    this.httpGet(Preference.URL_API_PREFERENCE_SCAN_ONCE, {}, function (response: any) {
-      SafeUtil.safeCallback(successCallback)(response);
-    }, errorCallback, finalCallback)
-  }
+            that.assign(response.data.data);
+
+            SafeUtil.safeCallback(successCallback)(response);
+
+        }, errorCallback, finalCallback);
+
+    }
+
+    httpSaveScan(successCallback?: any, errorCallback?: any, finalCallback?: any) {
+        const that = this
+        this.httpPost(Preference.URL_API_PREFERENCE_EDIT_SCAN, this.getForm(), function (response: any) {
+
+            that.assign(response.data.data);
+
+            SafeUtil.safeCallback(successCallback)(response);
+
+        }, errorCallback, finalCallback);
+
+    }
+
+    httpScanOnce(successCallback?: any, errorCallback?: any, finalCallback?: any) {
+        this.httpGet(Preference.URL_API_PREFERENCE_SCAN_ONCE, {}, function (response: any) {
+            SafeUtil.safeCallback(successCallback)(response);
+        }, errorCallback, finalCallback)
+    }
 
 }
 
diff --git a/src/common/model/preference/model/PreviewConfig.ts b/src/common/model/preference/model/PreviewConfig.ts
index e445c56..8c54482 100644
--- a/src/common/model/preference/model/PreviewConfig.ts
+++ b/src/common/model/preference/model/PreviewConfig.ts
@@ -4,42 +4,40 @@
  */
 import Base from "../../base/Base";
 import PreviewEngine from "./PreviewEngine";
-import MimeUtil from "../../../util/MimeUtil";
-import MessageBoxUtil from "../../../util/MessageBoxUtil";
 
 /**
  * 预览配置
  */
 export default class PreviewConfig extends Base {
 
-  /**
-   * 预览引擎
-   */
-  previewEngines: PreviewEngine[] = []
+    /**
+     * 预览引擎
+     */
+    previewEngines: PreviewEngine[] = []
 
-  constructor() {
+    constructor() {
 
-    super()
+        super()
 
-  }
+    }
 
-  assign(obj: any) {
-    super.assign(obj);
+    assign(obj: any) {
+        super.assign(obj);
 
-    this.assignList("previewEngines", PreviewEngine)
-  }
+        this.assignList("previewEngines", PreviewEngine)
+    }
 
 
-  getForm(): any {
+    getForm(): any {
 
-    let forms = this.previewEngines.map((item: PreviewEngine, index: number) => {
-      return item.getForm()
-    })
+        let forms = this.previewEngines.map((item: PreviewEngine, index: number) => {
+            return item.getForm()
+        })
 
-    return {
-      previewEngines: forms
-    };
-  }
+        return {
+            previewEngines: forms
+        };
+    }
 
 
 }
diff --git a/src/common/model/preference/model/PreviewEngine.ts b/src/common/model/preference/model/PreviewEngine.ts
index cac6d2c..6f168a2 100644
--- a/src/common/model/preference/model/PreviewEngine.ts
+++ b/src/common/model/preference/model/PreviewEngine.ts
@@ -6,83 +6,83 @@ import Base from "../../base/Base";
 import MimeUtil from "../../../util/MimeUtil";
 
 export default class PreviewEngine extends Base {
-  /**
-   * 此预览引擎的url
-   * {originUrl} 文件原始的url地址。eg: https://tanker.eyeblue.cn/api/alien/download/2a0ceee1-744c-4c82-4215-69c382597a50/abstract-free-photo-2210x1473.jpg
-   * {url} 对于公有文件publicUrl=originUrl,对于私有文件publicUrl是originUrl带上downloadToken。 eg: https://tanker.eyeblue.cn/api/alien/download/2a0ceee1-744c-4c82-4215-69c382597a50/abstract-free-photo-2210x1473.jpg?downloadTokenUuid=6bdba52f-af6b-49ae-5a5d-fd80bfb01d3b
-   * {b64Url} 文件原始地址
-   */
-  url: string = "";
+    /**
+     * 此预览引擎的url
+     * {originUrl} 文件原始的url地址。eg: https://tanker.eyeblue.cn/api/alien/download/2a0ceee1-744c-4c82-4215-69c382597a50/abstract-free-photo-2210x1473.jpg
+     * {url} 对于公有文件publicUrl=originUrl,对于私有文件publicUrl是originUrl带上downloadToken。 eg: https://tanker.eyeblue.cn/api/alien/download/2a0ceee1-744c-4c82-4215-69c382597a50/abstract-free-photo-2210x1473.jpg?downloadTokenUuid=6bdba52f-af6b-49ae-5a5d-fd80bfb01d3b
+     * {b64Url} 文件原始地址
+     */
+    url: string = "";
 
-  /**
-   * 此预览引擎支持的文件后缀名。
-   * 星好*表示匹配所有的后缀名。
-   * 逗号分隔,不带.  例如: xls,doc,ppt,xlsx,docx,pptx
-   */
-  extensions: string = "";
+    /**
+     * 此预览引擎支持的文件后缀名。
+     * 星好*表示匹配所有的后缀名。
+     * 逗号分隔,不带.  例如: xls,doc,ppt,xlsx,docx,pptx
+     */
+    extensions: string = "";
 
-  /**
-   * 本站预览,新标签打开
-   */
-  previewInSite: boolean = true;
+    /**
+     * 本站预览,新标签打开
+     */
+    previewInSite: boolean = true;
 
-  constructor() {
-    super();
-  }
-
-  getForm(): any {
-    return {
-      url: this.url,
-      extensions: this.extensions,
-      previewInSite: this.previewInSite,
-    };
-  }
-
-  //提供几个默认的预览引擎。
-  static defaultPreviewEngines(): PreviewEngine[] {
-    let defaultEngines: PreviewEngine[] = [];
-
-    //添加office默认预览引擎,使用微软开放接口
-    let officeEngine: PreviewEngine = new PreviewEngine();
-    officeEngine.url =
-      "https://view.officeapps.live.com/op/embed.aspx?src={url}";
-    officeEngine.extensions = "doc,ppt,xls,docx,pptx,xlsx";
-    officeEngine.previewInSite = true;
-    defaultEngines.push(officeEngine);
-
-    //添加全局预览引擎,使用浏览器预览能力。
-    let globalEngine: PreviewEngine = new PreviewEngine();
-    globalEngine.url = "{originUrl}";
-    globalEngine.extensions = "*";
-    globalEngine.previewInSite = true;
-    defaultEngines.push(globalEngine);
-
-    return defaultEngines;
-  }
-
-  //对于某个文件,是否能够预览
-  canPreview(fileName: string): boolean {
-    let extension: string = MimeUtil.getExtensionWithoutDot(fileName);
-    if (!extension) {
-      return false;
+    constructor() {
+        super();
     }
 
-    let canHandle = false;
-    if (this.extensions === "*") {
-      canHandle = true;
-    } else {
-      let parts: string[] = this.extensions.split(",");
-      for (let part of parts) {
-        if (
-          extension === part.toLowerCase() ||
-          "." + extension === part.toLowerCase()
-        ) {
-          canHandle = true;
-          break;
+    getForm(): any {
+        return {
+            url: this.url,
+            extensions: this.extensions,
+            previewInSite: this.previewInSite,
+        };
+    }
+
+    //提供几个默认的预览引擎。
+    static defaultPreviewEngines(): PreviewEngine[] {
+        let defaultEngines: PreviewEngine[] = [];
+
+        //添加office默认预览引擎,使用微软开放接口
+        let officeEngine: PreviewEngine = new PreviewEngine();
+        officeEngine.url =
+            "https://view.officeapps.live.com/op/embed.aspx?src={url}";
+        officeEngine.extensions = "doc,ppt,xls,docx,pptx,xlsx";
+        officeEngine.previewInSite = true;
+        defaultEngines.push(officeEngine);
+
+        //添加全局预览引擎,使用浏览器预览能力。
+        let globalEngine: PreviewEngine = new PreviewEngine();
+        globalEngine.url = "{originUrl}";
+        globalEngine.extensions = "*";
+        globalEngine.previewInSite = true;
+        defaultEngines.push(globalEngine);
+
+        return defaultEngines;
+    }
+
+    //对于某个文件,是否能够预览
+    canPreview(fileName: string): boolean {
+        let extension: string = MimeUtil.getExtensionWithoutDot(fileName);
+        if (!extension) {
+            return false;
         }
-      }
-    }
 
-    return canHandle;
-  }
+        let canHandle = false;
+        if (this.extensions === "*") {
+            canHandle = true;
+        } else {
+            let parts: string[] = this.extensions.split(",");
+            for (let part of parts) {
+                if (
+                    extension === part.toLowerCase() ||
+                    "." + extension === part.toLowerCase()
+                ) {
+                    canHandle = true;
+                    break;
+                }
+            }
+        }
+
+        return canHandle;
+    }
 }
diff --git a/src/common/model/preference/model/ScanConfig.ts b/src/common/model/preference/model/ScanConfig.ts
index fbc88ad..5e21098 100644
--- a/src/common/model/preference/model/ScanConfig.ts
+++ b/src/common/model/preference/model/ScanConfig.ts
@@ -1,40 +1,40 @@
 /**
  * 扫描配置
  */
-import { LabeledValue } from 'antd/lib/select';
+import {LabeledValue} from 'antd/lib/select';
 import Base from "../../base/Base";
-import { ScanScopeType } from "./ScanScopeType";
-import { ScanCronType } from "./ScanCronType";
+import {ScanScopeType} from "./ScanScopeType";
+import {ScanCronType} from "./ScanCronType";
 
 export default class ScanConfig extends Base {
-  // 是否开启
-  enable: boolean = false;
-  // cron表达式 定时任务用
-  cron: string | null = null;
-  // 扫描磁盘开启范围(全部用户 or 局部用户)
-  scope: ScanScopeType = ScanScopeType.ALL;
-  // 开启扫描磁盘功能的用户们
-  usernames: string[] = [];
+    // 是否开启
+    enable: boolean = false;
+    // cron表达式 定时任务用
+    cron: string | null = null;
+    // 扫描磁盘开启范围(全部用户 or 局部用户)
+    scope: ScanScopeType = ScanScopeType.ALL;
+    // 开启扫描磁盘功能的用户们
+    usernames: string[] = [];
 
-  // 前端辅助字段
-  cronType: string | null = null;
-  users: LabeledValue[] = [];
+    // 前端辅助字段
+    cronType: string | null = null;
+    users: LabeledValue[] = [];
 
 
-  constructor() {
-    super();
-  }
+    constructor() {
+        super();
+    }
 
-  assign(obj: any) {
-    super.assign(obj);
-  }
+    assign(obj: any) {
+        super.assign(obj);
+    }
 
-  getForm(): any {
-    return {
-      enable: this.enable,
-      scope: this.scope,
-      cron: this.cronType === ScanCronType.CUSTOM ? this.cron : this.cronType,
-      usernames: this.usernames,
-    };
-  }
+    getForm(): any {
+        return {
+            enable: this.enable,
+            scope: this.scope,
+            cron: this.cronType === ScanCronType.CUSTOM ? this.cron : this.cronType,
+            usernames: this.usernames,
+        };
+    }
 }
diff --git a/src/common/model/preference/model/ScanCronType.ts b/src/common/model/preference/model/ScanCronType.ts
index 49ee6a8..721ef40 100644
--- a/src/common/model/preference/model/ScanCronType.ts
+++ b/src/common/model/preference/model/ScanCronType.ts
@@ -2,48 +2,48 @@ import SelectionOption from "../../base/option/SelectionOption";
 import Lang from "../../global/Lang";
 
 enum ScanCronType {
-  TEN_SECONDS = "TEN_SECONDS",
-  THIRTY_SECONDS = "THIRTY_SECONDS",
-  MINUTE = "MINUTE",
-  HOUR = "HOUR",
-  CUSTOM = "CUSTOM",
+    TEN_SECONDS = "TEN_SECONDS",
+    THIRTY_SECONDS = "THIRTY_SECONDS",
+    MINUTE = "MINUTE",
+    HOUR = "HOUR",
+    CUSTOM = "CUSTOM",
 }
 
 const ScanCronTypes: ScanCronType[] = Object.keys(ScanCronType).map(
-  (k) => k as ScanCronType
+    (k) => k as ScanCronType
 );
 
 const ScanCronTypeMap: { [key in keyof typeof ScanCronType]: SelectionOption } = {
-  TEN_SECONDS: {
-    name: Lang.t("preference.scanPerTenSeconds"),
-    value: "@every 10s",
-  },
-  THIRTY_SECONDS: {
-    name: Lang.t("preference.scanPerThirtySeconds"),
-    value: "@every 30s",
-  },
-  MINUTE: {
-    name: Lang.t("preference.scanPerMinute"),
-    value: "@every 1m",
-  },
-  HOUR: {
-    name: Lang.t("preference.scanPerHour"),
-    value: "0 * * * *",
-  },
-  CUSTOM: {
-    name: Lang.t("preference.scanCustom"),
-    value: "CUSTOM",
-  },
+    TEN_SECONDS: {
+        name: Lang.t("preference.scanPerTenSeconds"),
+        value: "@every 10s",
+    },
+    THIRTY_SECONDS: {
+        name: Lang.t("preference.scanPerThirtySeconds"),
+        value: "@every 30s",
+    },
+    MINUTE: {
+        name: Lang.t("preference.scanPerMinute"),
+        value: "@every 1m",
+    },
+    HOUR: {
+        name: Lang.t("preference.scanPerHour"),
+        value: "0 * * * *",
+    },
+    CUSTOM: {
+        name: Lang.t("preference.scanCustom"),
+        value: "CUSTOM",
+    },
 };
 
 const ScanCronTypeList: SelectionOption[] = [];
 ScanCronTypes.forEach((type: ScanCronType) => {
-  ScanCronTypeList.push(ScanCronTypeMap[type]);
+    ScanCronTypeList.push(ScanCronTypeMap[type]);
 });
 
 const ScanCronTypeValueList: string[] = [];
 ScanCronTypes.forEach((type: ScanCronType) => {
-  ScanCronTypeValueList.push(ScanCronTypeMap[type].value);
+    ScanCronTypeValueList.push(ScanCronTypeMap[type].value);
 });
 
-export { ScanCronType, ScanCronTypeMap, ScanCronTypeList, ScanCronTypeValueList };
+export {ScanCronType, ScanCronTypeMap, ScanCronTypeList, ScanCronTypeValueList};
diff --git a/src/common/model/preference/model/ScanScopeType.ts b/src/common/model/preference/model/ScanScopeType.ts
index 307dd52..d7cdad1 100644
--- a/src/common/model/preference/model/ScanScopeType.ts
+++ b/src/common/model/preference/model/ScanScopeType.ts
@@ -2,28 +2,28 @@ import SelectionOption from "../../base/option/SelectionOption";
 import Lang from "../../global/Lang";
 
 enum ScanScopeType {
-  ALL = "ALL",
-  CUSTOM = "CUSTOM",
+    ALL = "ALL",
+    CUSTOM = "CUSTOM",
 }
 
 const ScanScopeTypes: ScanScopeType[] = Object.keys(ScanScopeType).map(
-  (k) => k as ScanScopeType
+    (k) => k as ScanScopeType
 );
 
 const ScanScopeTypeMap: { [key in keyof typeof ScanScopeType]: SelectionOption } = {
-  ALL: {
-    name: Lang.t("user.allUsers"),
-    value: "ALL",
-  },
-  CUSTOM: {
-    name: Lang.t("user.partialUsers"),
-    value: "CUSTOM",
-  },
+    ALL: {
+        name: Lang.t("user.allUsers"),
+        value: "ALL",
+    },
+    CUSTOM: {
+        name: Lang.t("user.partialUsers"),
+        value: "CUSTOM",
+    },
 };
 
 let ScanScopeTypeList: SelectionOption[] = [];
 ScanScopeTypes.forEach((type: ScanScopeType) => {
-  ScanScopeTypeList.push(ScanScopeTypeMap[type]);
+    ScanScopeTypeList.push(ScanScopeTypeMap[type]);
 });
 
-export { ScanScopeType, ScanScopeTypeMap, ScanScopeTypeList };
+export {ScanScopeType, ScanScopeTypeMap, ScanScopeTypeList};
diff --git a/src/common/model/share/Share.ts b/src/common/model/share/Share.ts
index 9fa5a95..b4924a6 100644
--- a/src/common/model/share/Share.ts
+++ b/src/common/model/share/Share.ts
@@ -9,172 +9,172 @@ import SafeUtil from "../../util/SafeUtil";
 import MessageBoxUtil from "../../util/MessageBoxUtil";
 
 export default class Share extends BaseEntity {
-  name: string | null = null;
-  shareType: ShareType = ShareType.MIX;
-  userUuid: string | null = null;
-  username: string | null = null;
-  downloadTimes: number = 0;
-  code: string | null = null;
-  expireInfinity: boolean = false;
-  expireTime: Date | null = null;
+    name: string | null = null;
+    shareType: ShareType = ShareType.MIX;
+    userUuid: string | null = null;
+    username: string | null = null;
+    downloadTimes: number = 0;
+    code: string | null = null;
+    expireInfinity: boolean = false;
+    expireTime: Date | null = null;
 
-  //当前正在查看的文件夹
-  dirMatter: Matter = new Matter();
-  //当前share对应的matters
-  matters: Matter[] = [];
+    //当前正在查看的文件夹
+    dirMatter: Matter = new Matter();
+    //当前share对应的matters
+    matters: Matter[] = [];
 
-  //当前分享正在查看的根目录matter的uuid。前端辅助字段。
-  rootUuid: string = Matter.MATTER_ROOT;
+    //当前分享正在查看的根目录matter的uuid。前端辅助字段。
+    rootUuid: string = Matter.MATTER_ROOT;
 
-  //本地临时字段
-  expireOption: ShareExpireOption = ShareExpireOption.MONTH;
+    //本地临时字段
+    expireOption: ShareExpireOption = ShareExpireOption.MONTH;
 
-  static URL_CREATE = "/api/share/create";
-  static URL_BROWSE = "/api/share/browse";
-  static URL_DELETE_BATCH = "/api/share/delete/batch";
-  static URL_ZIP = "/api/share/zip";
+    static URL_CREATE = "/api/share/create";
+    static URL_BROWSE = "/api/share/browse";
+    static URL_DELETE_BATCH = "/api/share/delete/batch";
+    static URL_ZIP = "/api/share/zip";
 
-  constructor(reactComponent?: React.Component) {
-    super(reactComponent);
-  }
-
-  assign(obj: any) {
-    super.assign(obj);
-    super.assignEntity("expireTime", Date);
-    super.assignEntity("dirMatter", Matter);
-    super.assignList("matters", Matter);
-  }
-
-  getTAG():string {
-    return "share"
-  }
-
-  getFilters() {
-    return [...super.getFilters()];
-  }
-
-  getForm() {
-    return {
-      name: this.name,
-      uuid: this.uuid ? this.uuid : null,
-    };
-  }
-
-  getIcon() {
-    if (this.shareType === ShareType.MIX) {
-      return FileUtil.getIcon(
-        "zip",
-        false
-      );
-    } else {
-      return FileUtil.getIcon(
-        this.name,
-        this.shareType === ShareType.DIRECTORY
-      );
+    constructor(reactComponent?: React.Component) {
+        super(reactComponent);
     }
-  }
 
-  getLink() {
-    return EnvUtil.currentHost() + "/share/detail/" + this.uuid;
-  }
-
-  hasExpired() {
-    if (this.expireInfinity) {
-      return false;
-    } else {
-      if (this.expireTime) {
-        return new Date(this.expireTime).getTime() < new Date().getTime();
-      } else {
-        return false;
-      }
+    assign(obj: any) {
+        super.assign(obj);
+        super.assignEntity("expireTime", Date);
+        super.assignEntity("dirMatter", Matter);
+        super.assignList("matters", Matter);
     }
-  }
 
-  //获取过期时间
-  getExpireTime() {
-    const delta = ShareExpireOptionMap[this.expireOption].deltaMillisecond;
-    const now = new Date();
-    return new Date(now.getTime() + delta);
-  }
+    getTAG(): string {
+        return "share"
+    }
 
-  //下载zip包
-  downloadZip(puuid?: string) {
-    window.open(
-      `${EnvUtil.currentHost()}${Share.URL_ZIP}?shareUuid=${this.uuid}&code=${
-        this.code
-      }&puuid=${puuid}&rootUuid=${this.rootUuid}`
-    );
-  }
+    getFilters() {
+        return [...super.getFilters()];
+    }
 
-  //创建一个分享matterUuids要求为数组,expireTime要求为时间对象
-  httpCreate(
-    matterUuids: string,
-    successCallback?: () => any,
-    errorCallback?: () => any
-  ) {
-    let that = this;
+    getForm() {
+        return {
+            name: this.name,
+            uuid: this.uuid ? this.uuid : null,
+        };
+    }
 
-    const form = {
-      matterUuids: matterUuids,
-      expireInfinity: this.expireOption === ShareExpireOption.INFINITY,
-      expireTime: DateUtil.simpleDateTime(this.getExpireTime()),
-    };
+    getIcon() {
+        if (this.shareType === ShareType.MIX) {
+            return FileUtil.getIcon(
+                "zip",
+                false
+            );
+        } else {
+            return FileUtil.getIcon(
+                this.name,
+                this.shareType === ShareType.DIRECTORY
+            );
+        }
+    }
 
-    this.httpPost(
-      Share.URL_CREATE,
-      form,
-      function (response: any) {
-        that.assign(response.data.data);
-        SafeUtil.safeCallback(successCallback)(response);
-      },
-      errorCallback
-    );
-  }
+    getLink() {
+        return EnvUtil.currentHost() + "/share/detail/" + this.uuid;
+    }
 
-  httpDeleteBatch(
-    uuids: string,
-    successCallback?: () => any,
-    errorCallback?: () => any
-  ) {
-    this.httpPost(
-      Share.URL_DELETE_BATCH,
-      {uuids: uuids},
-      function (response: any) {
-        SafeUtil.safeCallback(successCallback)(response);
-      },
-      errorCallback
-    );
-  }
+    hasExpired() {
+        if (this.expireInfinity) {
+            return false;
+        } else {
+            if (this.expireTime) {
+                return new Date(this.expireTime).getTime() < new Date().getTime();
+            } else {
+                return false;
+            }
+        }
+    }
 
-  httpBrowse(
-    puuid: string,
-    rootUuid: string,
-    successCallback?: () => any,
-    errorCallback?: () => any
-  ) {
-    let that = this;
+    //获取过期时间
+    getExpireTime() {
+        const delta = ShareExpireOptionMap[this.expireOption].deltaMillisecond;
+        const now = new Date();
+        return new Date(now.getTime() + delta);
+    }
 
-    const form = {
-      puuid,
-      rootUuid,
-      shareUuid: this.uuid,
-      code: this.code,
-    };
+    //下载zip包
+    downloadZip(puuid?: string) {
+        window.open(
+            `${EnvUtil.currentHost()}${Share.URL_ZIP}?shareUuid=${this.uuid}&code=${
+                this.code
+            }&puuid=${puuid}&rootUuid=${this.rootUuid}`
+        );
+    }
 
-    this.detailLoading = true;
-    this.httpPost(
-      Share.URL_BROWSE,
-      form,
-      function (response: any) {
-        that.assign(response.data.data);
-        that.detailLoading = false;
-        SafeUtil.safeCallback(successCallback)(response);
-      },
-      function (errorMsg: any) {
-        that.detailLoading = false;
-        MessageBoxUtil.error(errorMsg);
-        SafeUtil.safeCallback(errorCallback)(errorMsg);
-      }
-    );
-  }
+    //创建一个分享matterUuids要求为数组,expireTime要求为时间对象
+    httpCreate(
+        matterUuids: string,
+        successCallback?: () => any,
+        errorCallback?: () => any
+    ) {
+        let that = this;
+
+        const form = {
+            matterUuids: matterUuids,
+            expireInfinity: this.expireOption === ShareExpireOption.INFINITY,
+            expireTime: DateUtil.simpleDateTime(this.getExpireTime()),
+        };
+
+        this.httpPost(
+            Share.URL_CREATE,
+            form,
+            function (response: any) {
+                that.assign(response.data.data);
+                SafeUtil.safeCallback(successCallback)(response);
+            },
+            errorCallback
+        );
+    }
+
+    httpDeleteBatch(
+        uuids: string,
+        successCallback?: () => any,
+        errorCallback?: () => any
+    ) {
+        this.httpPost(
+            Share.URL_DELETE_BATCH,
+            {uuids: uuids},
+            function (response: any) {
+                SafeUtil.safeCallback(successCallback)(response);
+            },
+            errorCallback
+        );
+    }
+
+    httpBrowse(
+        puuid: string,
+        rootUuid: string,
+        successCallback?: () => any,
+        errorCallback?: () => any
+    ) {
+        let that = this;
+
+        const form = {
+            puuid,
+            rootUuid,
+            shareUuid: this.uuid,
+            code: this.code,
+        };
+
+        this.detailLoading = true;
+        this.httpPost(
+            Share.URL_BROWSE,
+            form,
+            function (response: any) {
+                that.assign(response.data.data);
+                that.detailLoading = false;
+                SafeUtil.safeCallback(successCallback)(response);
+            },
+            function (errorMsg: any) {
+                that.detailLoading = false;
+                MessageBoxUtil.error(errorMsg);
+                SafeUtil.safeCallback(errorCallback)(errorMsg);
+            }
+        );
+    }
 }
diff --git a/src/common/model/share/ShareExpireOption.ts b/src/common/model/share/ShareExpireOption.ts
index b3256da..341d4a4 100644
--- a/src/common/model/share/ShareExpireOption.ts
+++ b/src/common/model/share/ShareExpireOption.ts
@@ -1,60 +1,60 @@
 import SelectionOption from "../base/option/SelectionOption";
 
 enum ShareExpireOption {
-  HOUR = "HOUR",
-  DAY = "DAY",
-  WEEK = "WEEK",
-  MONTH = "MONTH",
-  YEAR = "YEAR",
-  INFINITY = "INFINITY",
+    HOUR = "HOUR",
+    DAY = "DAY",
+    WEEK = "WEEK",
+    MONTH = "MONTH",
+    YEAR = "YEAR",
+    INFINITY = "INFINITY",
 }
 
 interface ShareExpireSelection extends SelectionOption {
-  deltaMillisecond: number;
+    deltaMillisecond: number;
 }
 
 const ShareExpireOptions: ShareExpireOption[] = Object.keys(
-  ShareExpireOption
+    ShareExpireOption
 ).map((k) => k as ShareExpireOption);
 
 const ShareExpireOptionMap: {
-  [key in keyof typeof ShareExpireOption]: ShareExpireSelection;
+    [key in keyof typeof ShareExpireOption]: ShareExpireSelection;
 } = {
-  HOUR: {
-    name: "share.hour",
-    value: "HOUR",
-    deltaMillisecond: 60 * 60 * 1000,
-  },
-  DAY: {
-    name: "share.day",
-    value: "DAY",
-    deltaMillisecond: 24 * 60 * 60 * 1000,
-  },
-  WEEK: {
-    name: "share.week",
-    value: "WEEK",
-    deltaMillisecond: 7 * 24 * 60 * 60 * 1000,
-  },
-  MONTH: {
-    name: "share.month",
-    value: "MONTH",
-    deltaMillisecond: 30 * 24 * 60 * 60 * 1000,
-  },
-  YEAR: {
-    name: "share.year",
-    value: "YEAR",
-    deltaMillisecond: 365 * 24 * 60 * 60 * 1000,
-  },
-  INFINITY: {
-    name: "share.infinity",
-    value: "INFINITY",
-    deltaMillisecond: 0,
-  },
+    HOUR: {
+        name: "share.hour",
+        value: "HOUR",
+        deltaMillisecond: 60 * 60 * 1000,
+    },
+    DAY: {
+        name: "share.day",
+        value: "DAY",
+        deltaMillisecond: 24 * 60 * 60 * 1000,
+    },
+    WEEK: {
+        name: "share.week",
+        value: "WEEK",
+        deltaMillisecond: 7 * 24 * 60 * 60 * 1000,
+    },
+    MONTH: {
+        name: "share.month",
+        value: "MONTH",
+        deltaMillisecond: 30 * 24 * 60 * 60 * 1000,
+    },
+    YEAR: {
+        name: "share.year",
+        value: "YEAR",
+        deltaMillisecond: 365 * 24 * 60 * 60 * 1000,
+    },
+    INFINITY: {
+        name: "share.infinity",
+        value: "INFINITY",
+        deltaMillisecond: 0,
+    },
 };
 
 let ShareExpireOptionList: ShareExpireSelection[] = [];
 ShareExpireOptions.forEach((type: ShareExpireOption) => {
-  ShareExpireOptionList.push(ShareExpireOptionMap[type]);
+    ShareExpireOptionList.push(ShareExpireOptionMap[type]);
 });
 
-export { ShareExpireOption, ShareExpireOptionMap, ShareExpireOptionList };
+export {ShareExpireOption, ShareExpireOptionMap, ShareExpireOptionList};
diff --git a/src/common/model/share/ShareType.ts b/src/common/model/share/ShareType.ts
index 46882c1..609a2a5 100644
--- a/src/common/model/share/ShareType.ts
+++ b/src/common/model/share/ShareType.ts
@@ -1,33 +1,33 @@
 import SelectionOption from "../base/option/SelectionOption";
 
 enum ShareType {
-  FILE = "FILE",
-  DIRECTORY = "DIRECTORY",
-  MIX = "MIX",
+    FILE = "FILE",
+    DIRECTORY = "DIRECTORY",
+    MIX = "MIX",
 }
 
 const ShareTypes: ShareType[] = Object.keys(ShareType).map(
-  (k) => k as ShareType
+    (k) => k as ShareType
 );
 
 const ShareTypeMap: { [key in keyof typeof ShareType]: SelectionOption } = {
-  FILE: {
-    name: "文件",
-    value: "FILE",
-  },
-  DIRECTORY: {
-    name: "文件夹",
-    value: "DIRECTORY",
-  },
-  MIX: {
-    name: "混合",
-    value: "MIX",
-  },
+    FILE: {
+        name: "文件",
+        value: "FILE",
+    },
+    DIRECTORY: {
+        name: "文件夹",
+        value: "DIRECTORY",
+    },
+    MIX: {
+        name: "混合",
+        value: "MIX",
+    },
 };
 
 let ShareTypeList: SelectionOption[] = [];
 ShareTypes.forEach((type: ShareType) => {
-  ShareTypeList.push(ShareTypeMap[type]);
+    ShareTypeList.push(ShareTypeMap[type]);
 });
 
-export { ShareType, ShareTypeMap, ShareTypeList };
+export {ShareType, ShareTypeMap, ShareTypeList};
diff --git a/src/common/model/user/User.ts b/src/common/model/user/User.ts
index baac727..b128b75 100644
--- a/src/common/model/user/User.ts
+++ b/src/common/model/user/User.ts
@@ -11,228 +11,228 @@ import SelectionFilter from "../base/filter/SelectionFilter";
 
 export default class User extends BaseEntity {
 
-  //获取当前登录者的信息
-  static URL_INFO = '/api/user/info';
-  static URL_LOGIN = '/api/user/login'
-  static URL_AUTHENTICATION_LOGIN = '/api/user/authentication/login'
-  static URL_REGISTER = '/api/user/register'
-  static URL_LOGOUT = '/api/user/logout'
-  static URL_USER_CHANGE_PASSWORD = '/api/user/change/password'
-  static URL_USER_RESET_PASSWORD = '/api/user/reset/password'
-  static URL_USER_TOGGLE_STATUS = '/api/user/toggle/status'
-  static URL_USER_TRANSFIGURATION = '/api/user/transfiguration'
-  static URL_USER_SCAN = '/api/user/scan'
+    //获取当前登录者的信息
+    static URL_INFO = '/api/user/info';
+    static URL_LOGIN = '/api/user/login'
+    static URL_AUTHENTICATION_LOGIN = '/api/user/authentication/login'
+    static URL_REGISTER = '/api/user/register'
+    static URL_LOGOUT = '/api/user/logout'
+    static URL_USER_CHANGE_PASSWORD = '/api/user/change/password'
+    static URL_USER_RESET_PASSWORD = '/api/user/reset/password'
+    static URL_USER_TOGGLE_STATUS = '/api/user/toggle/status'
+    static URL_USER_TRANSFIGURATION = '/api/user/transfiguration'
+    static URL_USER_SCAN = '/api/user/scan'
 
-  role: UserRole = UserRole.GUEST
-  username: string | null = null
-  password: string | null = null
-  avatarUrl: string | null = null
-  lastIp: string | null = null
-  lastTime: Date = new Date()
-  //默认大小限制100Mb.
-  sizeLimit: number = 104857600
-  totalSize: number = 0
-  totalSizeLimit: number = -1
-  status: UserStatus = UserStatus.OK
+    role: UserRole = UserRole.GUEST
+    username: string | null = null
+    password: string | null = null
+    avatarUrl: string | null = null
+    lastIp: string | null = null
+    lastTime: Date = new Date()
+    //默认大小限制100Mb.
+    sizeLimit: number = 104857600
+    totalSize: number = 0
+    totalSizeLimit: number = -1
+    status: UserStatus = UserStatus.OK
 
 
-  constructor(reactComponent?: React.Component) {
+    constructor(reactComponent?: React.Component) {
 
-    super(reactComponent);
+        super(reactComponent);
 
-  }
-
-
-  assign(obj: any) {
-    super.assign(obj);
-
-    this.assignEntity("lastTime", Date)
-
-  }
-
-  getTAG(): string {
-    return "user"
-  }
-
-
-  getFilters(): Filter[] {
-    return [
-      ...super.getFilters(),
-      new SortFilter("按上次登录时间排序", "orderLastTime"),
-      new InputFilter("用户名", "username", "按用户名搜索"),
-      new SelectionFilter("状态", "status", UserStatusList),
-
-    ]
-  }
-
-  getForm(): any {
-    return {
-      username: this.username,
-      password: this.password,
-      role: this.role,
-      avatarUrl: this.avatarUrl,
-      sizeLimit: this.sizeLimit,
-      totalSizeLimit: this.totalSizeLimit,
-      uuid: this.uuid ? this.uuid : null
-    };
-  }
-
-
-  getAvatarUrl(origin: boolean = false) {
-    if (this.avatarUrl) {
-      return ImageUtil.handleImageUrl(this.avatarUrl, origin)
-    } else {
-      return defaultAvatarPath
     }
-  }
 
-  //登录
-  httpLogin(username: string, password: string, successCallback?: any, errorCallback?: any, finalCallback?: any) {
 
-    let that = this;
+    assign(obj: any) {
+        super.assign(obj);
 
-    let form = {
-      username,
-      password,
-    };
+        this.assignEntity("lastTime", Date)
 
-    this.httpGet(User.URL_LOGIN, form, function (response: any) {
-
-      that.assign(response.data.data);
-
-      SafeUtil.safeCallback(successCallback)(response);
-
-    }, errorCallback, finalCallback);
-
-  }
-
-  //注册
-  httpRegister(username: string, password: string, successCallback?: any, errorCallback?: any, finalCallback?: any) {
-
-    let that = this;
-
-    let form = {
-      username,
-      password,
-    };
-
-    this.httpGet(User.URL_REGISTER, form, function (response: any) {
-
-      that.assign(response.data.data);
-
-      SafeUtil.safeCallback(successCallback)(response);
-
-    }, errorCallback, finalCallback);
-
-  }
-
-  //获取当前登录者的信息
-  httpInfo(loginRequired: boolean, finalCallback?: any) {
-
-    let that = this;
-    if (loginRequired) {       // httpGet有统一的登录处理机制
-      this.httpGet(User.URL_INFO, {}, function (response: any) {
-        that.assign(response.data.data);
-      }, null, finalCallback);
-    } else {
-      this.httpPureGet(User.URL_INFO, {}, function (response: any) {
-        that.assign(response.data.data);
-      }, () => {
-      }, finalCallback);
     }
-  }
+
+    getTAG(): string {
+        return "user"
+    }
 
 
-  //退出登录
-  httpLogout(successCallback?: any, errorCallback?: any, finalCallback?: any) {
+    getFilters(): Filter[] {
+        return [
+            ...super.getFilters(),
+            new SortFilter("按上次登录时间排序", "orderLastTime"),
+            new InputFilter("用户名", "username", "按用户名搜索"),
+            new SelectionFilter("状态", "status", UserStatusList),
 
-    let that = this;
+        ]
+    }
 
-    let form = {};
-
-    this.httpGet(User.URL_LOGOUT, form, function (response: any) {
-
-      console.info('退出成功!');
-
-      that.assign(new User())
-
-      SafeUtil.safeCallback(successCallback)(response);
-
-    }, errorCallback, finalCallback);
-
-  }
+    getForm(): any {
+        return {
+            username: this.username,
+            password: this.password,
+            role: this.role,
+            avatarUrl: this.avatarUrl,
+            sizeLimit: this.sizeLimit,
+            totalSizeLimit: this.totalSizeLimit,
+            uuid: this.uuid ? this.uuid : null
+        };
+    }
 
 
-  httpChangePassword(oldPassword: string, newPassword: string, successCallback?: any, errorCallback?: any, finalCallback?: any) {
-    let that = this
-    this.httpPost(User.URL_USER_CHANGE_PASSWORD, {
-      'oldPassword': oldPassword,
-      'newPassword': newPassword
-    }, function (response: any) {
+    getAvatarUrl(origin: boolean = false) {
+        if (this.avatarUrl) {
+            return ImageUtil.handleImageUrl(this.avatarUrl, origin)
+        } else {
+            return defaultAvatarPath
+        }
+    }
 
-      SafeUtil.safeCallback(successCallback)(response);
+    //登录
+    httpLogin(username: string, password: string, successCallback?: any, errorCallback?: any, finalCallback?: any) {
+
+        let that = this;
+
+        let form = {
+            username,
+            password,
+        };
+
+        this.httpGet(User.URL_LOGIN, form, function (response: any) {
+
+            that.assign(response.data.data);
+
+            SafeUtil.safeCallback(successCallback)(response);
+
+        }, errorCallback, finalCallback);
+
+    }
+
+    //注册
+    httpRegister(username: string, password: string, successCallback?: any, errorCallback?: any, finalCallback?: any) {
+
+        let that = this;
+
+        let form = {
+            username,
+            password,
+        };
+
+        this.httpGet(User.URL_REGISTER, form, function (response: any) {
+
+            that.assign(response.data.data);
+
+            SafeUtil.safeCallback(successCallback)(response);
+
+        }, errorCallback, finalCallback);
+
+    }
+
+    //获取当前登录者的信息
+    httpInfo(loginRequired: boolean, finalCallback?: any) {
+
+        let that = this;
+        if (loginRequired) {       // httpGet有统一的登录处理机制
+            this.httpGet(User.URL_INFO, {}, function (response: any) {
+                that.assign(response.data.data);
+            }, null, finalCallback);
+        } else {
+            this.httpPureGet(User.URL_INFO, {}, function (response: any) {
+                that.assign(response.data.data);
+            }, () => {
+            }, finalCallback);
+        }
+    }
 
 
-    }, errorCallback)
-  }
+    //退出登录
+    httpLogout(successCallback?: any, errorCallback?: any, finalCallback?: any) {
 
-  httpResetPassword(password: string, successCallback?: any, errorCallback?: any, finalCallback?: any) {
-    this.httpPost(User.URL_USER_RESET_PASSWORD, {
-      'userUuid': this.uuid,
-      'password': password
-    }, function (response: any) {
+        let that = this;
+
+        let form = {};
+
+        this.httpGet(User.URL_LOGOUT, form, function (response: any) {
+
+            console.info('退出成功!');
+
+            that.assign(new User())
+
+            SafeUtil.safeCallback(successCallback)(response);
+
+        }, errorCallback, finalCallback);
+
+    }
 
 
-      SafeUtil.safeCallback(successCallback)(response);
+    httpChangePassword(oldPassword: string, newPassword: string, successCallback?: any, errorCallback?: any, finalCallback?: any) {
+        let that = this
+        this.httpPost(User.URL_USER_CHANGE_PASSWORD, {
+            'oldPassword': oldPassword,
+            'newPassword': newPassword
+        }, function (response: any) {
+
+            SafeUtil.safeCallback(successCallback)(response);
 
 
-    }, errorCallback)
-  }
+        }, errorCallback)
+    }
+
+    httpResetPassword(password: string, successCallback?: any, errorCallback?: any, finalCallback?: any) {
+        this.httpPost(User.URL_USER_RESET_PASSWORD, {
+            'userUuid': this.uuid,
+            'password': password
+        }, function (response: any) {
 
 
-  httpToggleStatus(successCallback?: any, errorCallback?: any, finalCallback?: any) {
-    let that = this
-    this.httpPost(User.URL_USER_TOGGLE_STATUS, {'uuid': this.uuid}, function (response: any) {
-
-      that.assign(response.data.data);
-      SafeUtil.safeCallback(successCallback)(response);
+            SafeUtil.safeCallback(successCallback)(response);
 
 
-    }, errorCallback)
-  }
-
-  httpAuthenticationLogin(authentication: string, successCallback?: any, errorCallback?: any, finalCallback?: any) {
-    let that = this
-    let form = {authentication}
-    this.httpPost(User.URL_AUTHENTICATION_LOGIN, form, function (response: any) {
+        }, errorCallback)
+    }
 
 
-      SafeUtil.safeCallback(successCallback)(response);
+    httpToggleStatus(successCallback?: any, errorCallback?: any, finalCallback?: any) {
+        let that = this
+        this.httpPost(User.URL_USER_TOGGLE_STATUS, {'uuid': this.uuid}, function (response: any) {
+
+            that.assign(response.data.data);
+            SafeUtil.safeCallback(successCallback)(response);
 
 
-    }, errorCallback)
-  }
+        }, errorCallback)
+    }
 
-  httpTransfiguration(successCallback: (text: string) => void, errorCallback?: any, finalCallback?: any) {
-    let that = this
-    let form = {'uuid': this.uuid}
-    this.httpPost(User.URL_USER_TRANSFIGURATION, form, function (response: any) {
-
-      successCallback(response.data.msg)
-
-    }, errorCallback)
-  }
+    httpAuthenticationLogin(authentication: string, successCallback?: any, errorCallback?: any, finalCallback?: any) {
+        let that = this
+        let form = {authentication}
+        this.httpPost(User.URL_AUTHENTICATION_LOGIN, form, function (response: any) {
 
 
-  httpScan(successCallback: (text: string) => void, errorCallback?: any, finalCallback?: any) {
-    let that = this
-    let form = {'uuid': this.uuid}
-    this.httpPost(User.URL_USER_SCAN, form, function (response: any) {
+            SafeUtil.safeCallback(successCallback)(response);
 
-      successCallback(response.data.msg)
 
-    }, errorCallback, finalCallback)
-  }
+        }, errorCallback)
+    }
+
+    httpTransfiguration(successCallback: (text: string) => void, errorCallback?: any, finalCallback?: any) {
+        let that = this
+        let form = {'uuid': this.uuid}
+        this.httpPost(User.URL_USER_TRANSFIGURATION, form, function (response: any) {
+
+            successCallback(response.data.msg)
+
+        }, errorCallback)
+    }
+
+
+    httpScan(successCallback: (text: string) => void, errorCallback?: any, finalCallback?: any) {
+        let that = this
+        let form = {'uuid': this.uuid}
+        this.httpPost(User.URL_USER_SCAN, form, function (response: any) {
+
+            successCallback(response.data.msg)
+
+        }, errorCallback, finalCallback)
+    }
 
 }
 
diff --git a/src/common/model/user/UserRole.ts b/src/common/model/user/UserRole.ts
index c4f760f..b670d69 100644
--- a/src/common/model/user/UserRole.ts
+++ b/src/common/model/user/UserRole.ts
@@ -4,35 +4,35 @@ import Lang from "../global/Lang";
 
 
 enum UserRole {
-  GUEST = 'GUEST',
-  USER = 'USER',
-  ADMINISTRATOR = 'ADMINISTRATOR',
+    GUEST = 'GUEST',
+    USER = 'USER',
+    ADMINISTRATOR = 'ADMINISTRATOR',
 }
 
 let UserRoles: UserRole[] = Object.keys(UserRole).map(k => k as UserRole);
 
 let UserRoleMap: { [key in keyof typeof UserRole]: ColorSelectionOption } = {
-  GUEST: {
-    'name': Lang.t("user.roleGuest"),
-    'value': 'GUEST',
-    'color': Color.WARNING,
-  },
-  USER: {
-    'name': Lang.t("user.roleUser"),
-    'value': 'USER',
-    'color': Color.PRIMARY,
-  },
-  ADMINISTRATOR: {
-    'name': Lang.t("user.roleAdministrator"),
-    'value': 'ADMINISTRATOR',
-    'color': Color.DANGER,
-  },
+    GUEST: {
+        'name': Lang.t("user.roleGuest"),
+        'value': 'GUEST',
+        'color': Color.WARNING,
+    },
+    USER: {
+        'name': Lang.t("user.roleUser"),
+        'value': 'USER',
+        'color': Color.PRIMARY,
+    },
+    ADMINISTRATOR: {
+        'name': Lang.t("user.roleAdministrator"),
+        'value': 'ADMINISTRATOR',
+        'color': Color.DANGER,
+    },
 
 };
 
 let UserRoleList: ColorSelectionOption[] = [];
 UserRoles.forEach((type: UserRole, index: number) => {
-  UserRoleList.push(UserRoleMap[type]);
+    UserRoleList.push(UserRoleMap[type]);
 });
 
 
diff --git a/src/common/model/user/UserStatus.ts b/src/common/model/user/UserStatus.ts
index fd8d816..33c2860 100644
--- a/src/common/model/user/UserStatus.ts
+++ b/src/common/model/user/UserStatus.ts
@@ -4,28 +4,28 @@ import Lang from "../global/Lang";
 
 
 enum UserStatus {
-  OK = 'OK',
-  DISABLED = 'DISABLED'
+    OK = 'OK',
+    DISABLED = 'DISABLED'
 }
 
 let UserStatuss: UserStatus[] = Object.keys(UserStatus).map(k => k as UserStatus);
 
 let UserStatusMap: { [key in keyof typeof UserStatus]: ColorSelectionOption } = {
-  OK: {
-    'name': Lang.t("user.statusActive"),
-    'value': 'OK',
-    'color': Color.SUCCESS,
-  },
-  DISABLED: {
-    'name': Lang.t("user.statusDisabled"),
-    'value': 'DISABLED',
-    'color': Color.DANGER,
-  },
+    OK: {
+        'name': Lang.t("user.statusActive"),
+        'value': 'OK',
+        'color': Color.SUCCESS,
+    },
+    DISABLED: {
+        'name': Lang.t("user.statusDisabled"),
+        'value': 'DISABLED',
+        'color': Color.DANGER,
+    },
 };
 
 let UserStatusList: ColorSelectionOption[] = [];
 UserStatuss.forEach((type: UserStatus, index: number) => {
-  UserStatusList.push(UserStatusMap[type]);
+    UserStatusList.push(UserStatusMap[type]);
 });
 
 
diff --git a/src/common/types/index.d.ts b/src/common/types/index.d.ts
index 81711e7..338285e 100644
--- a/src/common/types/index.d.ts
+++ b/src/common/types/index.d.ts
@@ -4,16 +4,16 @@ import * as React from "react";
  * 定义了一个图标行为的对象,这个可以辅助一些组件。
  */
 export interface IconActionItem {
-  //图片的资源链接(优先级高于iconType)
-  icon?: string
-  //antd的图标类型
-  iconType?: string
-  //名称
-  name?: string
-  //是否可见。默认可见
-  visible?: boolean
-  //点击图标后的行为
-  onClick?: () => void
+    //图片的资源链接(优先级高于iconType)
+    icon?: string
+    //antd的图标类型
+    iconType?: string
+    //名称
+    name?: string
+    //是否可见。默认可见
+    visible?: boolean
+    //点击图标后的行为
+    onClick?: () => void
 }
 
 
@@ -23,13 +23,13 @@ export interface IconActionItem {
  */
 export interface ToolItem {
 
-  name: string
+    name: string
 
-  //当前是否处于展开状态
-  active: boolean
+    //当前是否处于展开状态
+    active: boolean
 
-  //antd的图标样式
-  icon: React.ReactNode
+    //antd的图标样式
+    icon: React.ReactNode
 
 }
 
@@ -40,16 +40,16 @@ export interface ToolItem {
  */
 export interface SkeletonItem {
 
-  name: string
+    name: string
 
-  //当前是否处于展开状态
-  active: boolean
+    //当前是否处于展开状态
+    active: boolean
 
-  //高亮的图标 资源链接
-  activeIcon: string
+    //高亮的图标 资源链接
+    activeIcon: string
 
-  //一般状态的图标 资源链接
-  icon: string
+    //一般状态的图标 资源链接
+    icon: string
 
 }
 
diff --git a/src/common/util/AnimateUtil.ts b/src/common/util/AnimateUtil.ts
index f0f160a..56e47a2 100644
--- a/src/common/util/AnimateUtil.ts
+++ b/src/common/util/AnimateUtil.ts
@@ -2,91 +2,91 @@ import SafeUtil from "./SafeUtil";
 
 export default class AnimateUtil {
 
-  /**
-   * 动画函数
-   * @param startValue 开始的值
-   * @param endValue 结束的值
-   * @param duration 动画持续时间,单位ms 如果开始值和结束值一样,那么会提前结束。
-   * @param processHandler 过程中处理的回调函数. 该函数能保证第一个值是startValue,结束的值是endValue
-   * @param startHandler 开始的回调函数
-   * @param endHandler 结束的回调函数
-   * @param standard 每隔多少毫秒进行一次处理。
-   *
-   */
-  static animate(
-    startValue: number,
-    endValue: number,
-    duration: number,
-    processHandler: (value: number) => void,
-    startHandler?: (value: number) => void,
-    endHandler?: (value: number) => void,
-    standard?: number
-  ): void {
+    /**
+     * 动画函数
+     * @param startValue 开始的值
+     * @param endValue 结束的值
+     * @param duration 动画持续时间,单位ms 如果开始值和结束值一样,那么会提前结束。
+     * @param processHandler 过程中处理的回调函数. 该函数能保证第一个值是startValue,结束的值是endValue
+     * @param startHandler 开始的回调函数
+     * @param endHandler 结束的回调函数
+     * @param standard 每隔多少毫秒进行一次处理。
+     *
+     */
+    static animate(
+        startValue: number,
+        endValue: number,
+        duration: number,
+        processHandler: (value: number) => void,
+        startHandler?: (value: number) => void,
+        endHandler?: (value: number) => void,
+        standard?: number
+    ): void {
 
 
-    //规则校验。
-    if (duration <= 0) {
-      console.error("duration值只能是正整数")
-      return
+        //规则校验。
+        if (duration <= 0) {
+            console.error("duration值只能是正整数")
+            return
+        }
+
+        if (standard == undefined) {
+            standard = 20
+        } else if (standard <= 0) {
+            console.error("standard值只能是正整数")
+            return
+        }
+
+        let totalStep: number = endValue - startValue
+
+        //从startValue到endValue需要触发几次。
+        let num = Math.ceil(duration / standard)
+
+        //每一步的长度
+        let delta: number = totalStep
+        if (num != 0) {
+            delta = Math.ceil(totalStep / num)
+        }
+
+        //定时执行
+        let sum = 0;
+        SafeUtil.safeCallback(startHandler)(startValue)
+        processHandler(startValue)
+        let intervalHandler = setInterval(() => {
+
+            sum = sum + delta
+            if (Math.abs(sum) >= Math.abs(totalStep)) {
+                //该停止了
+                processHandler(endValue)
+                SafeUtil.safeCallback(endHandler)(endValue)
+
+                //关闭定时器。
+                clearInterval(intervalHandler)
+
+            } else {
+                //更新当前进度
+                processHandler(startValue + sum)
+            }
+
+        }, standard)
+
     }
 
-    if (standard == undefined) {
-      standard = 20
-    } else if (standard <= 0) {
-      console.error("standard值只能是正整数")
-      return
+    static setInputSelection(input: HTMLInputElement, startPos: number, endPos: number) {
+        input.focus();
+        if (typeof input.selectionStart !== "undefined") {
+            input.selectionStart = startPos;
+            input.selectionEnd = endPos;
+        } else if ((document as any).selection && (document as any).selection.createRange) {
+            // IE branch
+            input.select();
+            let range = (document as any).selection.createRange();
+            range.collapse(true);
+            range.moveEnd("character", endPos);
+            range.moveStart("character", startPos);
+            range.select();
+        }
     }
 
-    let totalStep: number = endValue - startValue
-
-    //从startValue到endValue需要触发几次。
-    let num = Math.ceil(duration / standard)
-
-    //每一步的长度
-    let delta: number = totalStep
-    if (num != 0) {
-      delta = Math.ceil(totalStep / num)
-    }
-
-    //定时执行
-    let sum = 0;
-    SafeUtil.safeCallback(startHandler)(startValue)
-    processHandler(startValue)
-    let intervalHandler = setInterval(() => {
-
-      sum = sum + delta
-      if (Math.abs(sum) >= Math.abs(totalStep)) {
-        //该停止了
-        processHandler(endValue)
-        SafeUtil.safeCallback(endHandler)(endValue)
-
-        //关闭定时器。
-        clearInterval(intervalHandler)
-
-      } else {
-        //更新当前进度
-        processHandler(startValue + sum)
-      }
-
-    }, standard)
-
-  }
-
-  static setInputSelection(input: HTMLInputElement, startPos: number, endPos: number) {
-    input.focus();
-    if (typeof input.selectionStart !== "undefined") {
-      input.selectionStart = startPos;
-      input.selectionEnd = endPos;
-    } else if ((document as any).selection && (document as any).selection.createRange) {
-      // IE branch
-      input.select();
-      let range = (document as any).selection.createRange();
-      range.collapse(true);
-      range.moveEnd("character", endPos);
-      range.moveStart("character", startPos);
-      range.select();
-    }
-  }
-
 
 }
diff --git a/src/common/util/AntdUtil.ts b/src/common/util/AntdUtil.ts
index 5788d7c..2311a98 100644
--- a/src/common/util/AntdUtil.ts
+++ b/src/common/util/AntdUtil.ts
@@ -6,41 +6,41 @@ import DateUtil from "./DateUtil";
 export default class AntdUtil {
 
 
-  /**
-   * 从一个数组中,获取到antd table想要的那种dataSource格式
-   */
-  static getDataSource(columns :any, data :any) {
+    /**
+     * 从一个数组中,获取到antd table想要的那种dataSource格式
+     */
+    static getDataSource(columns: any, data: any) {
 
-    let dataSource  :any= []
-    if (!((columns instanceof Array) && (data instanceof Array))) {
+        let dataSource: any = []
+        if (!((columns instanceof Array) && (data instanceof Array))) {
 
-      console.error("columns和data必须为数组")
-      return dataSource
-    }
-
-    data.forEach((item, index) => {
-
-      let obj :any = {key: index, id: item.id}
-
-
-      columns.forEach((column, i) => {
-
-        let value = item[column.key]
-
-        //遇到时间自动转成 yyyy-MM-dd HH:mm:ss
-        if (value instanceof Date) {
-          value = DateUtil.simpleDateTime(value)
+            console.error("columns和data必须为数组")
+            return dataSource
         }
 
-        obj[column.key] = value
-      })
+        data.forEach((item, index) => {
 
-      dataSource.push(obj)
-    })
+            let obj: any = {key: index, id: item.id}
 
 
-    return dataSource
+            columns.forEach((column, i) => {
 
-  }
+                let value = item[column.key]
+
+                //遇到时间自动转成 yyyy-MM-dd HH:mm:ss
+                if (value instanceof Date) {
+                    value = DateUtil.simpleDateTime(value)
+                }
+
+                obj[column.key] = value
+            })
+
+            dataSource.push(obj)
+        })
+
+
+        return dataSource
+
+    }
 
 }
diff --git a/src/common/util/ArrayUtil.ts b/src/common/util/ArrayUtil.ts
index 0390a3d..a8417e2 100644
--- a/src/common/util/ArrayUtil.ts
+++ b/src/common/util/ArrayUtil.ts
@@ -1,142 +1,142 @@
 export default class ArrayUtil {
 
 
-  //从srcArray中减去childArray的元素
-  static substract(srcArray: [], childArray: any) {
-    if (!srcArray) {
-      return [];
-    }
+    //从srcArray中减去childArray的元素
+    static substract(srcArray: [], childArray: any) {
+        if (!srcArray) {
+            return [];
+        }
 
-    if (!childArray || childArray.length === 0) {
-      return srcArray;
-    }
+        if (!childArray || childArray.length === 0) {
+            return srcArray;
+        }
 
-    let newArray: [] = []
+        let newArray: [] = []
 
-    for (let i = 0; i < srcArray.length; i++) {
+        for (let i = 0; i < srcArray.length; i++) {
 
-      //在childArray的那些元素就不要了。
-      if (childArray.indexOf(srcArray[i]) === -1) {
-        newArray.push(srcArray[i])
-      }
+            //在childArray的那些元素就不要了。
+            if (childArray.indexOf(srcArray[i]) === -1) {
+                newArray.push(srcArray[i])
+            }
 
-    }
-    return newArray
-
-  }
-
-  //不重复添加
-  static uniqueAdd(srcArray: any, childArray: any) {
-    if (!srcArray) {
-      srcArray = []
-    }
-
-    if (!childArray || childArray.length === 0) {
-      return srcArray;
-    }
-
-
-    for (let i = 0; i < childArray.length; i++) {
-
-      //在childArray的那些元素就不要了。
-      if (srcArray.indexOf(childArray[i]) === -1) {
-        srcArray.push(childArray[i])
-      }
-
-    }
-    return srcArray
-  }
-
-  //不重复添加
-  static uniqueAddOne(srcArray: any[], child: any) {
-    if (!srcArray) {
-      srcArray = []
-    }
-
-    if (child === undefined || child === null) {
-      return srcArray;
-    }
-
-    //在childArray的那些元素就不要了。
-    if (srcArray.indexOf(child) === -1) {
-      srcArray.push(child)
-    }
-
-    return srcArray
-  }
-
-  //数组中查找特定元素并返回所有该元素的索引
-  static findAll(a: any, x: any) {
-    let results: number[] = [],
-      len = a.length,
-      pos: number = 0;
-    while (pos < len) {
-      pos = a.indexOf(x, pos);
-      if (pos === -1) {//未找到就退出循环完成搜索
-        break;
-      }
-      results.push(pos);//找到就存储索引
-      pos += 1;//并从下个位置开始搜索
-    }
-    return results;
-  }
-
-
-  //调整元素位置。将dragIndex的元素放到hoverIndex的前面,其余顺移。在拖拽排序中用到。
-  static insertSort(arr: any, dragIndex: any, hoverIndex: any) {
-
-
-    if (!(arr instanceof Array)) {
-      return
-    }
-
-    if (dragIndex < 0 || dragIndex >= arr.length) {
-      console.error("dragIndex = " + dragIndex + " index越界 length = " + arr.length)
-      return
-    }
-
-    if (hoverIndex < 0 || hoverIndex >= arr.length) {
-      console.error("hoverIndex = " + hoverIndex + " index越界 length = " + arr.length)
-      return
-    }
-
-    if (dragIndex === hoverIndex) {
-      return
-    }
-
-    if (dragIndex > hoverIndex) {
-
-      let temp = arr[dragIndex]
-
-      for (let i = dragIndex; i >= hoverIndex + 1; i--) {
-        arr[i] = arr[i - 1]
-      }
-      arr[hoverIndex] = temp
-
-
-    } else {
-
-      let temp = arr[dragIndex]
-
-      for (let i = dragIndex; i <= hoverIndex - 1; i++) {
-        arr[i] = arr[i + 1]
-      }
-      arr[hoverIndex] = temp
+        }
+        return newArray
 
     }
 
+    //不重复添加
+    static uniqueAdd(srcArray: any, childArray: any) {
+        if (!srcArray) {
+            srcArray = []
+        }
 
-  }
+        if (!childArray || childArray.length === 0) {
+            return srcArray;
+        }
 
-  //数组去重
-  static unique(arr: string[]) {
-    let newArr: string[] = [];
-    for (let i = 0, item; item = arr[i++];) {
-      if (newArr.indexOf(item) === -1) {
-        newArr.push(item);
-      }
+
+        for (let i = 0; i < childArray.length; i++) {
+
+            //在childArray的那些元素就不要了。
+            if (srcArray.indexOf(childArray[i]) === -1) {
+                srcArray.push(childArray[i])
+            }
+
+        }
+        return srcArray
     }
-    return newArr;
-  };
+
+    //不重复添加
+    static uniqueAddOne(srcArray: any[], child: any) {
+        if (!srcArray) {
+            srcArray = []
+        }
+
+        if (child === undefined || child === null) {
+            return srcArray;
+        }
+
+        //在childArray的那些元素就不要了。
+        if (srcArray.indexOf(child) === -1) {
+            srcArray.push(child)
+        }
+
+        return srcArray
+    }
+
+    //数组中查找特定元素并返回所有该元素的索引
+    static findAll(a: any, x: any) {
+        let results: number[] = [],
+            len = a.length,
+            pos: number = 0;
+        while (pos < len) {
+            pos = a.indexOf(x, pos);
+            if (pos === -1) {//未找到就退出循环完成搜索
+                break;
+            }
+            results.push(pos);//找到就存储索引
+            pos += 1;//并从下个位置开始搜索
+        }
+        return results;
+    }
+
+
+    //调整元素位置。将dragIndex的元素放到hoverIndex的前面,其余顺移。在拖拽排序中用到。
+    static insertSort(arr: any, dragIndex: any, hoverIndex: any) {
+
+
+        if (!(arr instanceof Array)) {
+            return
+        }
+
+        if (dragIndex < 0 || dragIndex >= arr.length) {
+            console.error("dragIndex = " + dragIndex + " index越界 length = " + arr.length)
+            return
+        }
+
+        if (hoverIndex < 0 || hoverIndex >= arr.length) {
+            console.error("hoverIndex = " + hoverIndex + " index越界 length = " + arr.length)
+            return
+        }
+
+        if (dragIndex === hoverIndex) {
+            return
+        }
+
+        if (dragIndex > hoverIndex) {
+
+            let temp = arr[dragIndex]
+
+            for (let i = dragIndex; i >= hoverIndex + 1; i--) {
+                arr[i] = arr[i - 1]
+            }
+            arr[hoverIndex] = temp
+
+
+        } else {
+
+            let temp = arr[dragIndex]
+
+            for (let i = dragIndex; i <= hoverIndex - 1; i++) {
+                arr[i] = arr[i + 1]
+            }
+            arr[hoverIndex] = temp
+
+        }
+
+
+    }
+
+    //数组去重
+    static unique(arr: string[]) {
+        let newArr: string[] = [];
+        for (let i = 0, item; item = arr[i++];) {
+            if (newArr.indexOf(item) === -1) {
+                newArr.push(item);
+            }
+        }
+        return newArr;
+    };
 
 }
diff --git a/src/common/util/BrowserUtil.ts b/src/common/util/BrowserUtil.ts
index 36d4669..bcfccba 100644
--- a/src/common/util/BrowserUtil.ts
+++ b/src/common/util/BrowserUtil.ts
@@ -1,128 +1,128 @@
 export default class BrowserUtil {
 
-  //根据cookie键,读取cookie值
-  static readCookie(name: any) {
-    let nameEQ = name + "=";
-    let ca = document.cookie.split(';');
-    for (let i = 0; i < ca.length; i++) {
-      let c = ca[i];
-      while (c.charAt(0) === ' ') c = c.substring(1, c.length);
-      if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
-    }
-    return null;
-  }
-
-
-  /**
-   *
-   * 获取url地址栏的参数
-   * // query string: ?foo=lorem&bar=&baz
-   * var foo = getQueryByName('foo'); // "lorem"
-   * var bar = getQueryByName('bar'); // "" (present with empty value)
-   * var baz = getQueryByName('baz'); // "" (present with no value)
-   * var qux = getQueryByName('qux'); // null (absent)
-   * @param name
-   * @param url
-   * @returns {*}
-   */
-  static getQueryByName(name: string, url?: string): string | null {
-
-    if (!url) {
-      url = window.location.href
+    //根据cookie键,读取cookie值
+    static readCookie(name: any) {
+        let nameEQ = name + "=";
+        let ca = document.cookie.split(';');
+        for (let i = 0; i < ca.length; i++) {
+            let c = ca[i];
+            while (c.charAt(0) === ' ') c = c.substring(1, c.length);
+            if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
+        }
+        return null;
     }
 
-    name = name.replace(/[\[\]]/g, "\\$&");
 
-    let regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)")
-    let results = regex.exec(url);
+    /**
+     *
+     * 获取url地址栏的参数
+     * // query string: ?foo=lorem&bar=&baz
+     * var foo = getQueryByName('foo'); // "lorem"
+     * var bar = getQueryByName('bar'); // "" (present with empty value)
+     * var baz = getQueryByName('baz'); // "" (present with no value)
+     * var qux = getQueryByName('qux'); // null (absent)
+     * @param name
+     * @param url
+     * @returns {*}
+     */
+    static getQueryByName(name: string, url?: string): string | null {
 
-    if (!results) {
-      return null;
+        if (!url) {
+            url = window.location.href
+        }
+
+        name = name.replace(/[\[\]]/g, "\\$&");
+
+        let regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)")
+        let results = regex.exec(url);
+
+        if (!results) {
+            return null;
+        }
+
+        if (!results[2]) {
+            return "";
+        }
+
+        return decodeURIComponent(results[2].replace(/\+/g, " "));
     }
 
-    if (!results[2]) {
-      return "";
+
+    /**
+     * 半颜的方法。注释待补充
+     * @param name
+     * @returns {*}
+     */
+    static getQueryString(name: any) {
+        let reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
+        let r = window.location.search.substr(1).match(reg);
+        if (r != null) return unescape(r[2]);
+        return null;
     }
 
-    return decodeURIComponent(results[2].replace(/\+/g, " "));
-  }
 
-
-  /**
-   * 半颜的方法。注释待补充
-   * @param name
-   * @returns {*}
-   */
-  static getQueryString(name: any) {
-    let reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
-    let r = window.location.search.substr(1).match(reg);
-    if (r != null) return unescape(r[2]);
-    return null;
-  }
-
-
-  static isLocalStorageNameSupported() {
-    let testKey = 'test';
-    let storage = window.localStorage;
-    try {
-      storage.setItem(testKey, '1');
-      storage.removeItem(testKey);
-      return true;
-    } catch (error) {
-      return false;
+    static isLocalStorageNameSupported() {
+        let testKey = 'test';
+        let storage = window.localStorage;
+        try {
+            storage.setItem(testKey, '1');
+            storage.removeItem(testKey);
+            return true;
+        } catch (error) {
+            return false;
+        }
     }
-  }
 
 
-  static readLocalStorage(key: any) {
-    if (BrowserUtil.isLocalStorageNameSupported()) {
-      return window.localStorage[key];
-    } else {
-      console.error("not support localStorage.");
-      return null;
+    static readLocalStorage(key: any) {
+        if (BrowserUtil.isLocalStorageNameSupported()) {
+            return window.localStorage[key];
+        } else {
+            console.error("not support localStorage.");
+            return null;
+        }
     }
-  }
 
-  static saveToLocalStorage(key: any, content: any) {
-    if (BrowserUtil.isLocalStorageNameSupported()) {
-      window.localStorage[key] = content;
-    } else {
-      console.error("not support localStorage.");
+    static saveToLocalStorage(key: any, content: any) {
+        if (BrowserUtil.isLocalStorageNameSupported()) {
+            window.localStorage[key] = content;
+        } else {
+            console.error("not support localStorage.");
+        }
     }
-  }
 
 
-  static removeLocalStorage(key: any) {
-    if (BrowserUtil.isLocalStorageNameSupported()) {
-      window.localStorage.removeItem(key);
-    } else {
-      console.error("not support localStorage.");
+    static removeLocalStorage(key: any) {
+        if (BrowserUtil.isLocalStorageNameSupported()) {
+            window.localStorage.removeItem(key);
+        } else {
+            console.error("not support localStorage.");
+        }
     }
-  }
 
 
-  /**
-   * 获取完整的host
-   * eg:
-   * https://tanker.eyeblue.cn
-   */
-  static fullHost() {
-    return window.location.protocol + "//" + window.location.host
-  }
+    /**
+     * 获取完整的host
+     * eg:
+     * https://tanker.eyeblue.cn
+     */
+    static fullHost() {
+        return window.location.protocol + "//" + window.location.host
+    }
 
 
-  //只支持zh和en
-  static browserLang() {
-    //常规浏览器语言和IE浏览器
-    let lang = navigator.language || (navigator as any).userLanguage;
+    //只支持zh和en
+    static browserLang() {
+        //常规浏览器语言和IE浏览器
+        let lang = navigator.language || (navigator as any).userLanguage;
 
-    //截取lang前2位字符
-    lang = lang.substr(0, 2);
-    if (lang === "zh") {
-      return "zh"
-    } else {
-      return "en"
+        //截取lang前2位字符
+        lang = lang.substr(0, 2);
+        if (lang === "zh") {
+            return "zh"
+        } else {
+            return "en"
+        }
     }
-  }
 
 }
diff --git a/src/common/util/ClipboardUtil.ts b/src/common/util/ClipboardUtil.ts
index 91fe97d..3f2fa33 100644
--- a/src/common/util/ClipboardUtil.ts
+++ b/src/common/util/ClipboardUtil.ts
@@ -3,37 +3,37 @@ import SafeUtil from "./SafeUtil";
 export default class ClipboardUtil {
 
 
-  /**
-   * 复制一段文字到粘贴板。
-   *
-   */
-  static copy(text: string, successCallback: () => void, errorCallback?: () => void) {
+    /**
+     * 复制一段文字到粘贴板。
+     *
+     */
+    static copy(text: string, successCallback: () => void, errorCallback?: () => void) {
 
-    let className = "clipboard-textarea-util"
+        let className = "clipboard-textarea-util"
 
-    let textAreaElement: HTMLTextAreaElement | null = document.querySelector("." + className);
+        let textAreaElement: HTMLTextAreaElement | null = document.querySelector("." + className);
 
-    if (!textAreaElement) {
-      textAreaElement = document.createElement("textarea")
-      textAreaElement.className = className
-      textAreaElement.style.cssText = "position:fixed;opacity:0;z-index:0;width:5px;height:5px;"
-      document.body.appendChild(textAreaElement)
+        if (!textAreaElement) {
+            textAreaElement = document.createElement("textarea")
+            textAreaElement.className = className
+            textAreaElement.style.cssText = "position:fixed;opacity:0;z-index:0;width:5px;height:5px;"
+            document.body.appendChild(textAreaElement)
+        }
+
+        textAreaElement.value = text
+        textAreaElement.select();
+
+        try {
+            let successful = document.execCommand('copy');
+            if (successful) {
+                successCallback()
+            } else {
+                SafeUtil.safeCallback(errorCallback)()
+            }
+        } catch (err) {
+            console.error('复制失败', err);
+            SafeUtil.safeCallback(errorCallback)()
+        }
     }
 
-    textAreaElement.value = text
-    textAreaElement.select();
-
-    try {
-      let successful = document.execCommand('copy');
-      if (successful) {
-        successCallback()
-      } else {
-        SafeUtil.safeCallback(errorCallback)()
-      }
-    } catch (err) {
-      console.error('复制失败', err);
-      SafeUtil.safeCallback(errorCallback)()
-    }
-  }
-
 }
diff --git a/src/common/util/DateUtil.ts b/src/common/util/DateUtil.ts
index cf3727c..098d8e1 100644
--- a/src/common/util/DateUtil.ts
+++ b/src/common/util/DateUtil.ts
@@ -2,93 +2,94 @@ import moment from "moment"
 
 export default class DateUtil {
 
-  static DEFAULT_FORMAT = "YYYY-MM-DD HH:mm:ss";
-  static DEFAULT_HOUR_MINUTE = "YYYY-MM-DD HH:mm";
-  static SLASH_DATE_FORMAT = "YYYY/MM/DD";
-  static TIME_FORMAT = "HH:mm:ss";
-  static DATE_FORMAT = "YYYY-MM-DD";
-  //紧凑型的时间格式
-  static COMPACT_DATE_FORMAT = "YYYYMMDD";
+    static DEFAULT_FORMAT = "YYYY-MM-DD HH:mm:ss";
+    static DEFAULT_HOUR_MINUTE = "YYYY-MM-DD HH:mm";
+    static SLASH_DATE_FORMAT = "YYYY/MM/DD";
+    static TIME_FORMAT = "HH:mm:ss";
+    static DATE_FORMAT = "YYYY-MM-DD";
+    //紧凑型的时间格式
+    static COMPACT_DATE_FORMAT = "YYYYMMDD";
 
-  static simpleDateHourMinute(date: Date |null): string {
-    if (date == null) {
-      return ""
-    } else {
-      return moment(date).format(DateUtil.DEFAULT_HOUR_MINUTE)
-    }
-  }
-  static simpleDateTime(date: Date | null): string {
-    if (date == null) {
-      return ""
-    } else {
-      return moment(date).format(DateUtil.DEFAULT_FORMAT)
-    }
-  }
-
-  static simpleDate(date: Date | null): string {
-
-    if (date == null) {
-      return ""
-    } else {
-      return moment(date).format(DateUtil.DATE_FORMAT)
-    }
-  }
-
-  /**
-   * 某个日期的前一天
-   */
-  static lastDay(date: Date | null, format?: string): string {
-
-    if (format === undefined) {
-      format = DateUtil.DEFAULT_FORMAT
+    static simpleDateHourMinute(date: Date | null): string {
+        if (date == null) {
+            return ""
+        } else {
+            return moment(date).format(DateUtil.DEFAULT_HOUR_MINUTE)
+        }
     }
 
-    if (date == null) {
-      return ""
-    } else {
-      return moment(date).add(-1, 'days').format(format)
+    static simpleDateTime(date: Date | null): string {
+        if (date == null) {
+            return ""
+        } else {
+            return moment(date).format(DateUtil.DEFAULT_FORMAT)
+        }
     }
-  }
 
+    static simpleDate(date: Date | null): string {
 
-  /**
-   * 按照指定格式进行格式化
-   */
-  static format(date: Date | null, formatString: string): string {
-    if (date == null) {
-      return ""
-    } else {
-      return moment(date).format(formatString)
+        if (date == null) {
+            return ""
+        } else {
+            return moment(date).format(DateUtil.DATE_FORMAT)
+        }
     }
-  }
 
+    /**
+     * 某个日期的前一天
+     */
+    static lastDay(date: Date | null, format?: string): string {
 
-  /**
-   * 将字符串,按照指定的格式反序列化成为时间对象
-   * @param str
-   */
-  static parse(str: string): Date | null {
+        if (format === undefined) {
+            format = DateUtil.DEFAULT_FORMAT
+        }
 
-    let valid = moment(str).isValid();
-    if (valid) {
-      return moment(str).toDate()
-    } else {
-      return null
+        if (date == null) {
+            return ""
+        } else {
+            return moment(date).add(-1, 'days').format(format)
+        }
     }
-  }
 
 
-  //将时间字符串转化成js date
-  //deprecated,使用 parse方法替代。
-  static str2Date(str: any): Date {
-
-    let valid = moment(str).isValid();
-    if (valid) {
-      return moment(str).toDate()
-    } else {
-      //console.warn("不能转换成时间对象:", str)
-      return new Date()
+    /**
+     * 按照指定格式进行格式化
+     */
+    static format(date: Date | null, formatString: string): string {
+        if (date == null) {
+            return ""
+        } else {
+            return moment(date).format(formatString)
+        }
+    }
+
+
+    /**
+     * 将字符串,按照指定的格式反序列化成为时间对象
+     * @param str
+     */
+    static parse(str: string): Date | null {
+
+        let valid = moment(str).isValid();
+        if (valid) {
+            return moment(str).toDate()
+        } else {
+            return null
+        }
+    }
+
+
+    //将时间字符串转化成js date
+    //deprecated,使用 parse方法替代。
+    static str2Date(str: any): Date {
+
+        let valid = moment(str).isValid();
+        if (valid) {
+            return moment(str).toDate()
+        } else {
+            //console.warn("不能转换成时间对象:", str)
+            return new Date()
+        }
     }
-  }
 
 }
diff --git a/src/common/util/DomUtil.ts b/src/common/util/DomUtil.ts
index 12e9c29..dcaedbf 100644
--- a/src/common/util/DomUtil.ts
+++ b/src/common/util/DomUtil.ts
@@ -1,20 +1,20 @@
 export default class DomUtil {
 
-  static addEvent(el: Node, event: string, handler: (evt: Event) => void): void {
-    if (el.addEventListener) {
-      el.addEventListener(event, handler, true);
-    } else {
-      console.error("不支持事件监听!", el)
+    static addEvent(el: Node, event: string, handler: (evt: Event) => void): void {
+        if (el.addEventListener) {
+            el.addEventListener(event, handler, true);
+        } else {
+            console.error("不支持事件监听!", el)
+        }
     }
-  }
 
-  static removeEvent(el: Node, event: string, handler: (evt: Event) => void): void {
+    static removeEvent(el: Node, event: string, handler: (evt: Event) => void): void {
 
-    if (el.removeEventListener) {
-      el.removeEventListener(event, handler, true);
-    } else {
-      console.error("不支持事件监听!", el)
+        if (el.removeEventListener) {
+            el.removeEventListener(event, handler, true);
+        } else {
+            console.error("不支持事件监听!", el)
+        }
     }
-  }
 
 }
diff --git a/src/common/util/EnvUtil.ts b/src/common/util/EnvUtil.ts
index 26512a8..eaea3b0 100644
--- a/src/common/util/EnvUtil.ts
+++ b/src/common/util/EnvUtil.ts
@@ -1,5 +1,5 @@
 export default class EnvUtil {
     static currentHost() {
-      return window.location.protocol + "//" + window.location.host;
+        return window.location.protocol + "//" + window.location.host;
     }
 }
diff --git a/src/common/util/FileUtil.tsx b/src/common/util/FileUtil.tsx
index f3489ad..a583724 100644
--- a/src/common/util/FileUtil.tsx
+++ b/src/common/util/FileUtil.tsx
@@ -16,149 +16,149 @@ import videoSvg from "../../assets/image/file/video.svg";
 import xlsSvg from "../../assets/image/file/xls.svg";
 
 export default class FileUtil {
-  static isImage(name: string | null): boolean {
-    let mimeType = MimeUtil.getMimeType(name);
-    return StringUtil.startWith(mimeType, "image");
-  }
-
-  static isPdf(name: string | null): boolean {
-    let mimeType = MimeUtil.getMimeType(name);
-    return StringUtil.startWith(mimeType, "application/pdf");
-  }
-
-  static isText(name: string | null): boolean {
-    let mimeType = MimeUtil.getMimeType(name);
-    return StringUtil.startWith(mimeType, "text");
-  }
-
-  static isDoc(name: string | null): boolean {
-    let mimeType = MimeUtil.getMimeType(name);
-    return (
-      StringUtil.startWith(mimeType, "application/msword") ||
-      StringUtil.startWith(
-        mimeType,
-        "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
-      )
-    );
-  }
-
-  static isPpt(name: string | null): boolean {
-    let mimeType = MimeUtil.getMimeType(name);
-    return (
-      StringUtil.startWith(mimeType, "application/vnd.ms-powerpoint") ||
-      StringUtil.startWith(
-        mimeType,
-        "application/vnd.openxmlformats-officedocument.presentationml.presentation"
-      )
-    );
-  }
-
-  static isXls(name: string | null): boolean {
-    let mimeType = MimeUtil.getMimeType(name);
-    return (
-      StringUtil.startWith(mimeType, "application/vnd.ms-excel") ||
-      StringUtil.startWith(
-        mimeType,
-        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
-      )
-    );
-  }
-
-  static isAudio(name: string | null): boolean {
-    let mimeType = MimeUtil.getMimeType(name);
-    return StringUtil.startWith(mimeType, "audio");
-  }
-
-  static isVideo(name: string | null): boolean {
-    let mimeType = MimeUtil.getMimeType(name);
-    return StringUtil.startWith(mimeType, "video");
-  }
-
-  static isPsd(name: string | null): boolean {
-    let extension = MimeUtil.getExtension(name);
-    return extension === ".psd";
-  }
-
-  /**
-   * 根据名字获取对应的图标。imageIcon传值了,那么图片格式采用imageIcon
-   * @param name
-   * @param idDir
-   */
-  static getIcon(name: string | null, idDir: boolean = false): any {
-    if (idDir) {
-      return folderSvg;
+    static isImage(name: string | null): boolean {
+        let mimeType = MimeUtil.getMimeType(name);
+        return StringUtil.startWith(mimeType, "image");
     }
 
-    if (FileUtil.isPdf(name)) {
-      return pdfSvg;
-    } else if (FileUtil.isDoc(name)) {
-      return docSvg;
-    } else if (FileUtil.isPpt(name)) {
-      return pptSvg;
-    } else if (FileUtil.isXls(name)) {
-      return xlsSvg;
-    } else if (FileUtil.isAudio(name)) {
-      return audioSvg;
-    } else if (
-      FileUtil.isVideo(name) ||
-      MimeUtil.getExtension(name) === ".mkv"
-    ) {
-      return videoSvg;
-    } else if (FileUtil.isText(name)) {
-      return textSvg;
-    } else if (FileUtil.isPsd(name)) {
-      return psdSvg;
-    } else if (FileUtil.isImage(name)) {
-      return imageSvg;
-    } else if (
-      StringUtil.endWith(name, "zip") ||
-      StringUtil.endWith(name, "rar") ||
-      StringUtil.endWith(name, "7z") ||
-      StringUtil.endWith(name, "tar") ||
-      StringUtil.endWith(name, "tar") ||
-      StringUtil.endWith(name, "gz")
-    ) {
-      return archiveSvg;
-    } else {
-      return fileSvg;
-    }
-  }
-
-
-  //把一个大小转变成方便读的格式
-  //human readable file size
-  static humanFileSize(bytes: number, si: boolean = false): string {
-    if (bytes == -1) {
-      return Lang.t("preference.noLimit")
+    static isPdf(name: string | null): boolean {
+        let mimeType = MimeUtil.getMimeType(name);
+        return StringUtil.startWith(mimeType, "application/pdf");
     }
 
-    let thresh = si ? 1000 : 1024
-    if (Math.abs(bytes) < thresh) {
-      return bytes + ' B'
+    static isText(name: string | null): boolean {
+        let mimeType = MimeUtil.getMimeType(name);
+        return StringUtil.startWith(mimeType, "text");
     }
-    let units = si
-      ? ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
-      : ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
-    let u = -1
-    do {
-      bytes /= thresh
-      ++u
-    } while (Math.abs(bytes) >= thresh && u < units.length - 1)
-    return bytes.toFixed(1) + ' ' + units[u]
-  }
 
-  static getErrorLogsToCSVUrl(logs: object) {
-    const _utf = "\uFEFF"; // 为了使文件以utf-8的编码模式,同时也是解决中文乱码的问题
-    if (window.Blob && window.URL && window.URL.createObjectURL) {
-      const csvStr = new CSV(logs, {
-        header: ["filename", "path", "errorMsg"],
-      }).encode();
-      const blob = new Blob([_utf + csvStr], {
-        type: "text/csv",
-      });
-      return window.URL.createObjectURL(blob);
+    static isDoc(name: string | null): boolean {
+        let mimeType = MimeUtil.getMimeType(name);
+        return (
+            StringUtil.startWith(mimeType, "application/msword") ||
+            StringUtil.startWith(
+                mimeType,
+                "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
+            )
+        );
     }
-    return "";
-  };
+
+    static isPpt(name: string | null): boolean {
+        let mimeType = MimeUtil.getMimeType(name);
+        return (
+            StringUtil.startWith(mimeType, "application/vnd.ms-powerpoint") ||
+            StringUtil.startWith(
+                mimeType,
+                "application/vnd.openxmlformats-officedocument.presentationml.presentation"
+            )
+        );
+    }
+
+    static isXls(name: string | null): boolean {
+        let mimeType = MimeUtil.getMimeType(name);
+        return (
+            StringUtil.startWith(mimeType, "application/vnd.ms-excel") ||
+            StringUtil.startWith(
+                mimeType,
+                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
+            )
+        );
+    }
+
+    static isAudio(name: string | null): boolean {
+        let mimeType = MimeUtil.getMimeType(name);
+        return StringUtil.startWith(mimeType, "audio");
+    }
+
+    static isVideo(name: string | null): boolean {
+        let mimeType = MimeUtil.getMimeType(name);
+        return StringUtil.startWith(mimeType, "video");
+    }
+
+    static isPsd(name: string | null): boolean {
+        let extension = MimeUtil.getExtension(name);
+        return extension === ".psd";
+    }
+
+    /**
+     * 根据名字获取对应的图标。imageIcon传值了,那么图片格式采用imageIcon
+     * @param name
+     * @param idDir
+     */
+    static getIcon(name: string | null, idDir: boolean = false): any {
+        if (idDir) {
+            return folderSvg;
+        }
+
+        if (FileUtil.isPdf(name)) {
+            return pdfSvg;
+        } else if (FileUtil.isDoc(name)) {
+            return docSvg;
+        } else if (FileUtil.isPpt(name)) {
+            return pptSvg;
+        } else if (FileUtil.isXls(name)) {
+            return xlsSvg;
+        } else if (FileUtil.isAudio(name)) {
+            return audioSvg;
+        } else if (
+            FileUtil.isVideo(name) ||
+            MimeUtil.getExtension(name) === ".mkv"
+        ) {
+            return videoSvg;
+        } else if (FileUtil.isText(name)) {
+            return textSvg;
+        } else if (FileUtil.isPsd(name)) {
+            return psdSvg;
+        } else if (FileUtil.isImage(name)) {
+            return imageSvg;
+        } else if (
+            StringUtil.endWith(name, "zip") ||
+            StringUtil.endWith(name, "rar") ||
+            StringUtil.endWith(name, "7z") ||
+            StringUtil.endWith(name, "tar") ||
+            StringUtil.endWith(name, "tar") ||
+            StringUtil.endWith(name, "gz")
+        ) {
+            return archiveSvg;
+        } else {
+            return fileSvg;
+        }
+    }
+
+
+    //把一个大小转变成方便读的格式
+    //human readable file size
+    static humanFileSize(bytes: number, si: boolean = false): string {
+        if (bytes == -1) {
+            return Lang.t("preference.noLimit")
+        }
+
+        let thresh = si ? 1000 : 1024
+        if (Math.abs(bytes) < thresh) {
+            return bytes + ' B'
+        }
+        let units = si
+            ? ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
+            : ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
+        let u = -1
+        do {
+            bytes /= thresh
+            ++u
+        } while (Math.abs(bytes) >= thresh && u < units.length - 1)
+        return bytes.toFixed(1) + ' ' + units[u]
+    }
+
+    static getErrorLogsToCSVUrl(logs: object) {
+        const _utf = "\uFEFF"; // 为了使文件以utf-8的编码模式,同时也是解决中文乱码的问题
+        if (window.Blob && window.URL && window.URL.createObjectURL) {
+            const csvStr = new CSV(logs, {
+                header: ["filename", "path", "errorMsg"],
+            }).encode();
+            const blob = new Blob([_utf + csvStr], {
+                type: "text/csv",
+            });
+            return window.URL.createObjectURL(blob);
+        }
+        return "";
+    };
 
 }
diff --git a/src/common/util/HttpUtil.ts b/src/common/util/HttpUtil.ts
index deb49d8..eef6416 100644
--- a/src/common/util/HttpUtil.ts
+++ b/src/common/util/HttpUtil.ts
@@ -1,82 +1,82 @@
-import axios, { AxiosRequestConfig } from "axios";
+import axios, {AxiosRequestConfig} from "axios";
 import SafeUtil from "./SafeUtil";
 
 //http请求全部收口在这个工具类中,可以快速切换http框架。
 export default class HttpUtil {
-  static httpGet(
-    url: any,
-    params = {},
-    successCallback?: any,
-    errorCallback?: any,
-    finallyCallback?: any,
-    opts?: any
-  ) {
-    axios
-      .get(url, {
-        params: params,
-      })
-      .then(function (response) {
-        SafeUtil.safeCallback(successCallback)(response);
-      })
-      .catch(function (error) {
-        SafeUtil.safeCallback(errorCallback)(error);
-      })
-      .finally(function () {
-        SafeUtil.safeCallback(finallyCallback)();
-      });
-  }
+    static httpGet(
+        url: any,
+        params = {},
+        successCallback?: any,
+        errorCallback?: any,
+        finallyCallback?: any,
+        opts?: any
+    ) {
+        axios
+            .get(url, {
+                params: params,
+            })
+            .then(function (response) {
+                SafeUtil.safeCallback(successCallback)(response);
+            })
+            .catch(function (error) {
+                SafeUtil.safeCallback(errorCallback)(error);
+            })
+            .finally(function () {
+                SafeUtil.safeCallback(finallyCallback)();
+            });
+    }
 
-  static httpPost(
-    url: any,
-    params = {},
-    successCallback?: any,
-    errorCallback?: any,
-    finallyCallback?: any,
-    opts?: any
-  ) {
-    return axios
-      .post(url, params, opts)
-      .then(function (response) {
-        SafeUtil.safeCallback(successCallback)(response);
-      })
-      .catch(function (error) {
-        SafeUtil.safeCallback(errorCallback)(error);
-      })
-      .finally(function () {
-        SafeUtil.safeCallback(finallyCallback)();
-      });
-  }
+    static httpPost(
+        url: any,
+        params = {},
+        successCallback?: any,
+        errorCallback?: any,
+        finallyCallback?: any,
+        opts?: any
+    ) {
+        return axios
+            .post(url, params, opts)
+            .then(function (response) {
+                SafeUtil.safeCallback(successCallback)(response);
+            })
+            .catch(function (error) {
+                SafeUtil.safeCallback(errorCallback)(error);
+            })
+            .finally(function () {
+                SafeUtil.safeCallback(finallyCallback)();
+            });
+    }
 
-  /**
-   * 上传文件的请求
-   */
-  static httpPostFile(
-    url: string,
-    formData: FormData,
-    successCallback?: any,
-    errorCallback?: any,
-    finallyCallback?: any,
-    processCallback?: (progressEvent: any) => void,
-    opts?: any
-  ) {
-    const config: AxiosRequestConfig = {
-      headers: {
-        "Content-Type": "multipart/form-data",
-      },
-      cancelToken: opts ? opts.cancelToken : "",
-      onUploadProgress: processCallback,
-    };
+    /**
+     * 上传文件的请求
+     */
+    static httpPostFile(
+        url: string,
+        formData: FormData,
+        successCallback?: any,
+        errorCallback?: any,
+        finallyCallback?: any,
+        processCallback?: (progressEvent: any) => void,
+        opts?: any
+    ) {
+        const config: AxiosRequestConfig = {
+            headers: {
+                "Content-Type": "multipart/form-data",
+            },
+            cancelToken: opts ? opts.cancelToken : "",
+            onUploadProgress: processCallback,
+        };
 
-    axios
-      .post(url, formData, config)
-      .then(function (response) {
-        SafeUtil.safeCallback(successCallback)(response);
-      })
-      .catch(function (error) {
-        SafeUtil.safeCallback(errorCallback)(error);
-      })
-      .finally(function () {
-        SafeUtil.safeCallback(finallyCallback)();
-      });
-  }
+        axios
+            .post(url, formData, config)
+            .then(function (response) {
+                SafeUtil.safeCallback(successCallback)(response);
+            })
+            .catch(function (error) {
+                SafeUtil.safeCallback(errorCallback)(error);
+            })
+            .finally(function () {
+                SafeUtil.safeCallback(finallyCallback)();
+            });
+    }
 }
diff --git a/src/common/util/ImageUtil.ts b/src/common/util/ImageUtil.ts
index 0e0aee3..772aa8b 100644
--- a/src/common/util/ImageUtil.ts
+++ b/src/common/util/ImageUtil.ts
@@ -4,67 +4,67 @@ import NumberUtil from "./NumberUtil";
 import MimeUtil from "./MimeUtil";
 
 export default class ImageUtil {
-  static IMAGE_PLACEHOLDER_10_10 =
-    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAQAAAAnOwc2AAAAEUlEQVR42mP88J8BAzAOZUEAoc4TYb5Mv7IAAAAASUVORK5CYII=";
-  static IMAGE_PLACEHOLDER_20_7 =
-    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAQAAACiwqWzAAAAEklEQVR42mP88J+BKMA4IhUCAJ1VDZFobOQaAAAAAElFTkSuQmCC";
-  static IMAGE_PLACEHOLDER_4_3 =
-    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAQAAAAe/WZNAAAAEElEQVR42mP88J8BDBgxGABf8QXRk11CBwAAAABJRU5ErkJggg==";
-  static IMAGE_PLACEHOLDER_16_9 =
-    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAJCAQAAACRI2S5AAAAEklEQVR42mP88J8BL2AcVQAGACSgEXHKPyH/AAAAAElFTkSuQmCC";
-  static IMAGE_PLACEHOLDER_2_1 =
-    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAQAAAAeXLZtAAAAE0lEQVR42mP88J+BKMA4qpC+CgH2ThNhpeSxLAAAAABJRU5ErkJggg==";
+    static IMAGE_PLACEHOLDER_10_10 =
+        "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAQAAAAnOwc2AAAAEUlEQVR42mP88J8BAzAOZUEAoc4TYb5Mv7IAAAAASUVORK5CYII=";
+    static IMAGE_PLACEHOLDER_20_7 =
+        "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAQAAACiwqWzAAAAEklEQVR42mP88J+BKMA4IhUCAJ1VDZFobOQaAAAAAElFTkSuQmCC";
+    static IMAGE_PLACEHOLDER_4_3 =
+        "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAQAAAAe/WZNAAAAEElEQVR42mP88J8BDBgxGABf8QXRk11CBwAAAABJRU5ErkJggg==";
+    static IMAGE_PLACEHOLDER_16_9 =
+        "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAJCAQAAACRI2S5AAAAEklEQVR42mP88J8BL2AcVQAGACSgEXHKPyH/AAAAAElFTkSuQmCC";
+    static IMAGE_PLACEHOLDER_2_1 =
+        "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAQAAAAeXLZtAAAAE0lEQVR42mP88J+BKMA4qpC+CgH2ThNhpeSxLAAAAABJRU5ErkJggg==";
 
-  /**
-   * 统一处理图片url。
-   * @param url 原图片路径
-   * @param origin 是否使用原图,一般在查看图片详情的时候使用
-   * @param width 如果origin=false 裁剪的宽度
-   * @param height 如果origin=false 裁剪的高度
-   * @returns
-   */
-  static handleImageUrl(
-    url: string | null = null,
-    origin: boolean = false,
-    width: number = 200,
-    height: number = 200
-  ) {
-    if (url) {
-      if (origin) {
-        return url;
-      } else {
-        //目前支持这几种格式的处理。 jpg jpeg png tif tiff bmp gif
-        let supportExtensions = [
-          ".jpg",
-          ".jpeg",
-          ".png",
-          ".tif",
-          ".tiff",
-          ".bmp",
-          ".gif",
-        ];
-        let extension = MimeUtil.getExtension(url);
-        if (supportExtensions.indexOf(extension) === -1) {
-          return url;
+    /**
+     * 统一处理图片url。
+     * @param url 原图片路径
+     * @param origin 是否使用原图,一般在查看图片详情的时候使用
+     * @param width 如果origin=false 裁剪的宽度
+     * @param height 如果origin=false 裁剪的高度
+     * @returns
+     */
+    static handleImageUrl(
+        url: string | null = null,
+        origin: boolean = false,
+        width: number = 200,
+        height: number = 200
+    ) {
+        if (url) {
+            if (origin) {
+                return url;
+            } else {
+                //目前支持这几种格式的处理。 jpg jpeg png tif tiff bmp gif
+                let supportExtensions = [
+                    ".jpg",
+                    ".jpeg",
+                    ".png",
+                    ".tif",
+                    ".tiff",
+                    ".bmp",
+                    ".gif",
+                ];
+                let extension = MimeUtil.getExtension(url);
+                if (supportExtensions.indexOf(extension) === -1) {
+                    return url;
+                } else {
+                    return url + "?ir=fill_" + width + "_" + height;
+                }
+            }
         } else {
-          return url + "?ir=fill_" + width + "_" + height;
+            if (NumberUtil.fractionEqual(1, 1, width, height)) {
+                return ImageUtil.IMAGE_PLACEHOLDER_10_10;
+            } else if (NumberUtil.fractionEqual(20, 7, width, height)) {
+                return ImageUtil.IMAGE_PLACEHOLDER_20_7;
+            } else if (NumberUtil.fractionEqual(4, 3, width, height)) {
+                return ImageUtil.IMAGE_PLACEHOLDER_4_3;
+            } else if (NumberUtil.fractionEqual(16, 9, width, height)) {
+                return ImageUtil.IMAGE_PLACEHOLDER_16_9;
+            } else if (NumberUtil.fractionEqual(2, 1, width, height)) {
+                return ImageUtil.IMAGE_PLACEHOLDER_2_1;
+            } else {
+                return ImageUtil.IMAGE_PLACEHOLDER_10_10;
+            }
         }
-      }
-    } else {
-      if (NumberUtil.fractionEqual(1, 1, width, height)) {
-        return ImageUtil.IMAGE_PLACEHOLDER_10_10;
-      } else if (NumberUtil.fractionEqual(20, 7, width, height)) {
-        return ImageUtil.IMAGE_PLACEHOLDER_20_7;
-      } else if (NumberUtil.fractionEqual(4, 3, width, height)) {
-        return ImageUtil.IMAGE_PLACEHOLDER_4_3;
-      } else if (NumberUtil.fractionEqual(16, 9, width, height)) {
-        return ImageUtil.IMAGE_PLACEHOLDER_16_9;
-      } else if (NumberUtil.fractionEqual(2, 1, width, height)) {
-        return ImageUtil.IMAGE_PLACEHOLDER_2_1;
-      } else {
-        return ImageUtil.IMAGE_PLACEHOLDER_10_10;
-      }
     }
-  }
 }
 
diff --git a/src/common/util/JsonUtil.ts b/src/common/util/JsonUtil.ts
index d2bd334..06517a7 100644
--- a/src/common/util/JsonUtil.ts
+++ b/src/common/util/JsonUtil.ts
@@ -1,62 +1,62 @@
 export default class JsonUtil {
 
 
-  //将一个json字符串转换成 json 数组
-  static parseList(str: any) {
-    if (!str) {
-      return []
-    }
-    if (str instanceof Array) {
-      return str;
-    }
-    try {
-      let list = JSON.parse(str);
-      if (list instanceof Array) {
-        return list;
-      } else {
-        console.error("不能将" + str + "转换成数组");
-        return [];
-      }
-    } catch (e) {
-      console.error("不能将" + str + "转换成JSON");
-      return [];
-    }
-  }
-
-
-  //将一个字符串转成js对象
-  static toObj(str: any) {
-
-    if (!str) {
-      return {}
+    //将一个json字符串转换成 json 数组
+    static parseList(str: any) {
+        if (!str) {
+            return []
+        }
+        if (str instanceof Array) {
+            return str;
+        }
+        try {
+            let list = JSON.parse(str);
+            if (list instanceof Array) {
+                return list;
+            } else {
+                console.error("不能将" + str + "转换成数组");
+                return [];
+            }
+        } catch (e) {
+            console.error("不能将" + str + "转换成JSON");
+            return [];
+        }
     }
 
-    try {
-      return JSON.parse(str)
-    } catch (e) {
-      console.error("不能将json字符串" + str + "转换成对象");
-      return {};
-    }
-  }
 
-  //将一个对象转成json字符串
-  static toJson(obj: any): string {
+    //将一个字符串转成js对象
+    static toObj(str: any) {
 
-    if (!obj) {
-      obj = {}
+        if (!str) {
+            return {}
+        }
+
+        try {
+            return JSON.parse(str)
+        } catch (e) {
+            console.error("不能将json字符串" + str + "转换成对象");
+            return {};
+        }
     }
 
-    return JSON.stringify(obj)
-  }
+    //将一个对象转成json字符串
+    static toJson(obj: any): string {
 
-  //将JSON进行格式化。
-  static prettyJson(json: any) {
+        if (!obj) {
+            obj = {}
+        }
 
-    if (typeof json === 'string') {
-      json = JSON.parse(json);
+        return JSON.stringify(obj)
     }
 
-    return JSON.stringify(json, null, 2)
-  };
+    //将JSON进行格式化。
+    static prettyJson(json: any) {
+
+        if (typeof json === 'string') {
+            json = JSON.parse(json);
+        }
+
+        return JSON.stringify(json, null, 2)
+    };
 
 }
diff --git a/src/common/util/MessageBoxUtil.ts b/src/common/util/MessageBoxUtil.ts
index 57bbf53..3153d76 100644
--- a/src/common/util/MessageBoxUtil.ts
+++ b/src/common/util/MessageBoxUtil.ts
@@ -5,24 +5,24 @@ import {message} from 'antd';
  */
 export default class MessageBoxUtil {
 
-  static success(content: string) {
-    message.success(content)
-  }
+    static success(content: string) {
+        message.success(content)
+    }
 
-  static info(content: string) {
-    message.info(content)
-  }
+    static info(content: string) {
+        message.info(content)
+    }
 
-  static error(content: string) {
-    message.error(content)
-  }
+    static error(content: string) {
+        message.error(content)
+    }
 
-  static warn(content: string) {
-    message.warn(content)
-  }
+    static warn(content: string) {
+        message.warn(content)
+    }
 
-  static warning(content: string) {
-    message.warning(content)
-  }
+    static warning(content: string) {
+        message.warning(content)
+    }
 
 }
diff --git a/src/common/util/MimeUtil.ts b/src/common/util/MimeUtil.ts
index 8227ac5..2f8c1e4 100644
--- a/src/common/util/MimeUtil.ts
+++ b/src/common/util/MimeUtil.ts
@@ -1,659 +1,659 @@
 export default class MimeUtil {
-  static MIMES: any = {
-    ".323": "text/h323",
-    ".3g2": "video/3gpp2",
-    ".3gp": "video/3gpp",
-    ".3gp2": "video/3gpp2",
-    ".3gpp": "video/3gpp",
-    ".7z": "application/x-7z-compressed",
-    ".aa": "audio/audible",
-    ".AAC": "audio/aac",
-    ".aaf": "application/octet-stream",
-    ".aax": "audio/vnd.audible.aax",
-    ".ac3": "audio/ac3",
-    ".aca": "application/octet-stream",
-    ".accda": "application/msaccess.addin",
-    ".accdb": "application/msaccess",
-    ".accdc": "application/msaccess.cab",
-    ".accde": "application/msaccess",
-    ".accdr": "application/msaccess.runtime",
-    ".accdt": "application/msaccess",
-    ".accdw": "application/msaccess.webapplication",
-    ".accft": "application/msaccess.ftemplate",
-    ".acx": "application/internet-property-stream",
-    ".AddIn": "text/xml",
-    ".ade": "application/msaccess",
-    ".adobebridge": "application/x-bridge-url",
-    ".adp": "application/msaccess",
-    ".ADT": "audio/vnd.dlna.adts",
-    ".ADTS": "audio/aac",
-    ".afm": "application/octet-stream",
-    ".ai": "application/postscript",
-    ".aif": "audio/aiff",
-    ".aifc": "audio/aiff",
-    ".aiff": "audio/aiff",
-    ".air": "application/vnd.adobe.air-application-installer-package+zip",
-    ".amc": "application/mpeg",
-    ".anx": "application/annodex",
-    ".apk": "application/vnd.android.package-archive",
-    ".application": "application/x-ms-application",
-    ".art": "image/x-jg",
-    ".asa": "application/xml",
-    ".asax": "application/xml",
-    ".ascx": "application/xml",
-    ".asd": "application/octet-stream",
-    ".asf": "video/x-ms-asf",
-    ".ashx": "application/xml",
-    ".asi": "application/octet-stream",
-    ".asm": "text/plain",
-    ".asmx": "application/xml",
-    ".aspx": "application/xml",
-    ".asr": "video/x-ms-asf",
-    ".asx": "video/x-ms-asf",
-    ".atom": "application/atom+xml",
-    ".au": "audio/basic",
-    ".avi": "video/x-msvideo",
-    ".axa": "audio/annodex",
-    ".axs": "application/olescript",
-    ".axv": "video/annodex",
-    ".bas": "text/plain",
-    ".bat": "text/plain",
-    ".bcpio": "application/x-bcpio",
-    ".bin": "application/octet-stream",
-    ".bmp": "image/bmp",
-    ".c": "text/plain",
-    ".cab": "application/octet-stream",
-    ".caf": "audio/x-caf",
-    ".calx": "application/vnd.ms-office.calx",
-    ".cat": "application/vnd.ms-pki.seccat",
-    ".cc": "text/plain",
-    ".cd": "text/plain",
-    ".cdda": "audio/aiff",
-    ".cdf": "application/x-cdf",
-    ".cer": "application/x-x509-ca-cert",
-    ".cfg": "text/plain",
-    ".chm": "application/octet-stream",
-    ".class": "application/x-java-applet",
-    ".clp": "application/x-msclip",
-    ".cmd": "text/plain",
-    ".cmx": "image/x-cmx",
-    ".cnf": "text/plain",
-    ".cod": "image/cis-cod",
-    ".config": "application/xml",
-    ".contact": "text/x-ms-contact",
-    ".coverage": "application/xml",
-    ".cpio": "application/x-cpio",
-    ".cpp": "text/plain",
-    ".crd": "application/x-mscardfile",
-    ".crl": "application/pkix-crl",
-    ".crt": "application/x-x509-ca-cert",
-    ".cs": "text/plain",
-    ".csdproj": "text/plain",
-    ".csh": "application/x-csh",
-    ".csproj": "text/plain",
-    ".css": "text/css",
-    ".csv": "application/csv",
-    ".cur": "application/octet-stream",
-    ".cxx": "text/plain",
-    ".dat": "application/octet-stream",
-    ".datasource": "application/xml",
-    ".dbproj": "text/plain",
-    ".dcr": "application/x-director",
-    ".def": "text/plain",
-    ".deploy": "application/octet-stream",
-    ".der": "application/x-x509-ca-cert",
-    ".dgml": "application/xml",
-    ".dib": "image/bmp",
-    ".dif": "video/x-dv",
-    ".dir": "application/x-director",
-    ".disco": "text/xml",
-    ".divx": "video/divx",
-    ".dll": "application/x-msdownload",
-    ".dll.config": "text/xml",
-    ".dlm": "text/dlm",
-    ".doc": "application/msword",
-    ".docm": "application/vnd.ms-word.document.macroEnabled.12",
-    ".docx":
-      "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
-    ".dot": "application/msword",
-    ".dotm": "application/vnd.ms-word.template.macroEnabled.12",
-    ".dotx":
-      "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
-    ".dsp": "application/octet-stream",
-    ".dsw": "text/plain",
-    ".dtd": "text/xml",
-    ".dtsConfig": "text/xml",
-    ".dv": "video/x-dv",
-    ".dvi": "application/x-dvi",
-    ".dwf": "drawing/x-dwf",
-    ".dwg": "application/acad",
-    ".dwp": "application/octet-stream",
-    ".dxf": "application/x-dxf",
-    ".dxr": "application/x-director",
-    ".eml": "message/rfc822",
-    ".emz": "application/octet-stream",
-    ".eot": "application/vnd.ms-fontobject",
-    ".eps": "application/postscript",
-    ".etl": "application/etl",
-    ".etx": "text/x-setext",
-    ".evy": "application/envoy",
-    ".exe": "application/octet-stream",
-    ".exe.config": "text/xml",
-    ".fdf": "application/vnd.fdf",
-    ".fif": "application/fractals",
-    ".filters": "application/xml",
-    ".fla": "application/octet-stream",
-    ".flac": "audio/flac",
-    ".flr": "x-world/x-vrml",
-    ".flv": "video/x-flv",
-    ".fsscript": "application/fsharp-script",
-    ".fsx": "application/fsharp-script",
-    ".generictest": "application/xml",
-    ".gif": "image/gif",
-    ".gpx": "application/gpx+xml",
-    ".group": "text/x-ms-group",
-    ".gradle": "text/plain",
-    ".gsm": "audio/x-gsm",
-    ".gtar": "application/x-gtar",
-    ".gz": "application/x-gzip",
-    ".h": "text/plain",
-    ".hdf": "application/x-hdf",
-    ".hdml": "text/x-hdml",
-    ".hhc": "application/x-oleobject",
-    ".hhk": "application/octet-stream",
-    ".hhp": "application/octet-stream",
-    ".hlp": "application/winhlp",
-    ".hpp": "text/plain",
-    ".hqx": "application/mac-binhex40",
-    ".hta": "application/hta",
-    ".htc": "text/x-component",
-    ".htm": "text/html",
-    ".html": "text/html",
-    ".htt": "text/webviewhtml",
-    ".hxa": "application/xml",
-    ".hxc": "application/xml",
-    ".hxd": "application/octet-stream",
-    ".hxe": "application/xml",
-    ".hxf": "application/xml",
-    ".hxh": "application/octet-stream",
-    ".hxi": "application/octet-stream",
-    ".hxk": "application/xml",
-    ".hxq": "application/octet-stream",
-    ".hxr": "application/octet-stream",
-    ".hxs": "application/octet-stream",
-    ".hxt": "text/html",
-    ".hxv": "application/xml",
-    ".hxw": "application/octet-stream",
-    ".hxx": "text/plain",
-    ".i": "text/plain",
-    ".ico": "image/x-icon",
-    ".ics": "application/octet-stream",
-    ".idl": "text/plain",
-    ".ief": "image/ief",
-    ".iii": "application/x-iphone",
-    ".inc": "text/plain",
-    ".inf": "application/octet-stream",
-    ".ini": "text/plain",
-    ".inl": "text/plain",
-    ".ins": "application/x-internet-signup",
-    ".ipa": "application/x-itunes-ipa",
-    ".ipg": "application/x-itunes-ipg",
-    ".ipproj": "text/plain",
-    ".ipsw": "application/x-itunes-ipsw",
-    ".iqy": "text/x-ms-iqy",
-    ".isp": "application/x-internet-signup",
-    ".ite": "application/x-itunes-ite",
-    ".itlp": "application/x-itunes-itlp",
-    ".itms": "application/x-itunes-itms",
-    ".itpc": "application/x-itunes-itpc",
-    ".IVF": "video/x-ivf",
-    ".jar": "application/java-archive",
-    ".java": "text/plain",
-    ".jck": "application/liquidmotion",
-    ".jcz": "application/liquidmotion",
-    ".jfif": "image/pjpeg",
-    ".jnlp": "application/x-java-jnlp-file",
-    ".jpb": "application/octet-stream",
-    ".jpe": "image/jpeg",
-    ".jpeg": "image/jpeg",
-    ".jpg": "image/jpeg",
-    ".js": "text/plain",
-    ".json": "application/json",
-    ".jsx": "text/jscript",
-    ".jsxbin": "text/plain",
-    ".latex": "application/x-latex",
-    ".less": "text/plain",
-    ".library-ms": "application/windows-library+xml",
-    ".lit": "application/x-ms-reader",
-    ".loadtest": "application/xml",
-    ".lpk": "application/octet-stream",
-    ".lsf": "video/x-la-asf",
-    ".lst": "text/plain",
-    ".lsx": "video/x-la-asf",
-    ".lzh": "application/octet-stream",
-    ".m13": "application/x-msmediaview",
-    ".m14": "application/x-msmediaview",
-    ".m1v": "video/mpeg",
-    ".m2t": "video/vnd.dlna.mpeg-tts",
-    ".m2ts": "video/vnd.dlna.mpeg-tts",
-    ".m2v": "video/mpeg",
-    ".m3u": "audio/x-mpegurl",
-    ".m3u8": "audio/x-mpegurl",
-    ".m4a": "audio/m4a",
-    ".m4b": "audio/m4b",
-    ".m4p": "audio/m4p",
-    ".m4r": "audio/x-m4r",
-    ".m4v": "video/x-m4v",
-    ".mac": "image/x-macpaint",
-    ".mak": "text/plain",
-    ".man": "application/x-troff-man",
-    ".manifest": "application/x-ms-manifest",
-    ".map": "text/plain",
-    ".master": "application/xml",
-    ".mbox": "application/mbox",
-    ".md": "text/plain",
-    ".mda": "application/msaccess",
-    ".mdb": "application/x-msaccess",
-    ".mde": "application/msaccess",
-    ".mdp": "application/octet-stream",
-    ".me": "application/x-troff-me",
-    ".mfp": "application/x-shockwave-flash",
-    ".mht": "message/rfc822",
-    ".mhtml": "message/rfc822",
-    ".mid": "audio/mid",
-    ".midi": "audio/mid",
-    ".mix": "application/octet-stream",
-    ".mk": "text/plain",
-    ".mmf": "application/x-smaf",
-    ".mno": "text/xml",
-    ".mny": "application/x-msmoney",
-    ".mod": "video/mpeg",
-    ".mov": "video/quicktime",
-    ".movie": "video/x-sgi-movie",
-    ".mp2": "video/mpeg",
-    ".mp2v": "video/mpeg",
-    ".mp3": "audio/mpeg",
-    ".mp4": "video/mp4",
-    ".mp4v": "video/mp4",
-    ".mpa": "video/mpeg",
-    ".mpe": "video/mpeg",
-    ".mpeg": "video/mpeg",
-    ".mpf": "application/vnd.ms-mediapackage",
-    ".mpg": "video/mpeg",
-    ".mpp": "application/vnd.ms-project",
-    ".mpv2": "video/mpeg",
-    ".mqv": "video/quicktime",
-    ".ms": "application/x-troff-ms",
-    ".msg": "application/vnd.ms-outlook",
-    ".msi": "application/octet-stream",
-    ".mso": "application/octet-stream",
-    ".mts": "video/vnd.dlna.mpeg-tts",
-    ".mtx": "application/xml",
-    ".mvb": "application/x-msmediaview",
-    ".mvc": "application/x-miva-compiled",
-    ".mxp": "application/x-mmxp",
-    ".nc": "application/x-netcdf",
-    ".nsc": "video/x-ms-asf",
-    ".nws": "message/rfc822",
-    ".ocx": "application/octet-stream",
-    ".oda": "application/oda",
-    ".odb": "application/vnd.oasis.opendocument.database",
-    ".odc": "application/vnd.oasis.opendocument.chart",
-    ".odf": "application/vnd.oasis.opendocument.formula",
-    ".odg": "application/vnd.oasis.opendocument.graphics",
-    ".odh": "text/plain",
-    ".odi": "application/vnd.oasis.opendocument.image",
-    ".odl": "text/plain",
-    ".odm": "application/vnd.oasis.opendocument.text-master",
-    ".odp": "application/vnd.oasis.opendocument.presentation",
-    ".ods": "application/vnd.oasis.opendocument.spreadsheet",
-    ".odt": "application/vnd.oasis.opendocument.text",
-    ".oga": "audio/ogg",
-    ".ogg": "audio/ogg",
-    ".ogv": "video/ogg",
-    ".ogx": "application/ogg",
-    ".one": "application/onenote",
-    ".onea": "application/onenote",
-    ".onepkg": "application/onenote",
-    ".onetmp": "application/onenote",
-    ".onetoc": "application/onenote",
-    ".onetoc2": "application/onenote",
-    ".opus": "audio/ogg",
-    ".orderedtest": "application/xml",
-    ".osdx": "application/opensearchdescription+xml",
-    ".otf": "application/font-sfnt",
-    ".otg": "application/vnd.oasis.opendocument.graphics-template",
-    ".oth": "application/vnd.oasis.opendocument.text-web",
-    ".otp": "application/vnd.oasis.opendocument.presentation-template",
-    ".ots": "application/vnd.oasis.opendocument.spreadsheet-template",
-    ".ott": "application/vnd.oasis.opendocument.text-template",
-    ".oxt": "application/vnd.openofficeorg.extension",
-    ".p10": "application/pkcs10",
-    ".p12": "application/x-pkcs12",
-    ".p7b": "application/x-pkcs7-certificates",
-    ".p7c": "application/pkcs7-mime",
-    ".p7m": "application/pkcs7-mime",
-    ".p7r": "application/x-pkcs7-certreqresp",
-    ".p7s": "application/pkcs7-signature",
-    ".pbm": "image/x-portable-bitmap",
-    ".pcast": "application/x-podcast",
-    ".pct": "image/pict",
-    ".pcx": "application/octet-stream",
-    ".pcz": "application/octet-stream",
-    ".pdf": "application/pdf",
-    ".pfb": "application/octet-stream",
-    ".pfm": "application/octet-stream",
-    ".pfx": "application/x-pkcs12",
-    ".pgm": "image/x-portable-graymap",
-    ".pic": "image/pict",
-    ".pict": "image/pict",
-    ".pkgdef": "text/plain",
-    ".pkgundef": "text/plain",
-    ".pko": "application/vnd.ms-pki.pko",
-    ".pls": "audio/scpls",
-    ".pma": "application/x-perfmon",
-    ".pmc": "application/x-perfmon",
-    ".pml": "application/x-perfmon",
-    ".pmr": "application/x-perfmon",
-    ".pmw": "application/x-perfmon",
-    ".png": "image/png",
-    ".pnm": "image/x-portable-anymap",
-    ".pnt": "image/x-macpaint",
-    ".pntg": "image/x-macpaint",
-    ".pnz": "image/png",
-    ".pot": "application/vnd.ms-powerpoint",
-    ".potm": "application/vnd.ms-powerpoint.template.macroEnabled.12",
-    ".potx":
-      "application/vnd.openxmlformats-officedocument.presentationml.template",
-    ".ppa": "application/vnd.ms-powerpoint",
-    ".ppam": "application/vnd.ms-powerpoint.addin.macroEnabled.12",
-    ".ppm": "image/x-portable-pixmap",
-    ".pps": "application/vnd.ms-powerpoint",
-    ".ppsm": "application/vnd.ms-powerpoint.slideshow.macroEnabled.12",
-    ".ppsx":
-      "application/vnd.openxmlformats-officedocument.presentationml.slideshow",
-    ".ppt": "application/vnd.ms-powerpoint",
-    ".pptm": "application/vnd.ms-powerpoint.presentation.macroEnabled.12",
-    ".pptx":
-      "application/vnd.openxmlformats-officedocument.presentationml.presentation",
-    ".prf": "application/pics-rules",
-    ".prm": "application/octet-stream",
-    ".prx": "application/octet-stream",
-    ".ps": "application/postscript",
-    ".psc1": "application/PowerShell",
-    ".psd": "application/octet-stream",
-    ".psess": "application/xml",
-    ".psm": "application/octet-stream",
-    ".psp": "application/octet-stream",
-    ".pst": "application/vnd.ms-outlook",
-    ".pub": "application/x-mspublisher",
-    ".py": "text/plain",
-    ".pwz": "application/vnd.ms-powerpoint",
-    ".qht": "text/x-html-insertion",
-    ".qhtm": "text/x-html-insertion",
-    ".qt": "video/quicktime",
-    ".qti": "image/x-quicktime",
-    ".qtif": "image/x-quicktime",
-    ".qtl": "application/x-quicktimeplayer",
-    ".qxd": "application/octet-stream",
-    ".ra": "audio/x-pn-realaudio",
-    ".ram": "audio/x-pn-realaudio",
-    ".rar": "application/x-rar-compressed",
-    ".ras": "image/x-cmu-raster",
-    ".rat": "application/rat-file",
-    ".rc": "text/plain",
-    ".rc2": "text/plain",
-    ".rct": "text/plain",
-    ".rdlc": "application/xml",
-    ".reg": "text/plain",
-    ".resx": "application/xml",
-    ".rf": "image/vnd.rn-realflash",
-    ".rgb": "image/x-rgb",
-    ".rgs": "text/plain",
-    ".rm": "application/vnd.rn-realmedia",
-    ".rmi": "audio/mid",
-    ".rmp": "application/vnd.rn-rn_music_package",
-    ".roff": "application/x-troff",
-    ".rpm": "audio/x-pn-realaudio-plugin",
-    ".rqy": "text/x-ms-rqy",
-    ".rtf": "application/rtf",
-    ".rtx": "text/richtext",
-    ".rvt": "application/octet-stream",
-    ".ruleset": "application/xml",
-    ".s": "text/plain",
-    ".safariextz": "application/x-safari-safariextz",
-    ".scd": "application/x-msschedule",
-    ".scr": "text/plain",
-    ".sct": "text/scriptlet",
-    ".sd2": "audio/x-sd2",
-    ".sdp": "application/sdp",
-    ".sea": "application/octet-stream",
-    ".searchConnector-ms": "application/windows-search-connector+xml",
-    ".setpay": "application/set-payment-initiation",
-    ".setreg": "application/set-registration-initiation",
-    ".settings": "application/xml",
-    ".sgimb": "application/x-sgimb",
-    ".sgml": "text/sgml",
-    ".sh": "text/plain",
-    ".shar": "application/x-shar",
-    ".shtml": "text/html",
-    ".sit": "application/x-stuffit",
-    ".sitemap": "application/xml",
-    ".skin": "application/xml",
-    ".skp": "application/x-koan",
-    ".sldm": "application/vnd.ms-powerpoint.slide.macroEnabled.12",
-    ".sldx":
-      "application/vnd.openxmlformats-officedocument.presentationml.slide",
-    ".slk": "application/vnd.ms-excel",
-    ".sln": "text/plain",
-    ".slupkg-ms": "application/x-ms-license",
-    ".smd": "audio/x-smd",
-    ".smi": "application/octet-stream",
-    ".smx": "audio/x-smd",
-    ".smz": "audio/x-smd",
-    ".snd": "audio/basic",
-    ".snippet": "application/xml",
-    ".snp": "application/octet-stream",
-    ".sol": "text/plain",
-    ".sor": "text/plain",
-    ".spc": "application/x-pkcs7-certificates",
-    ".spl": "application/futuresplash",
-    ".spx": "audio/ogg",
-    ".sql": "text/plain",
-    ".src": "application/x-wais-source",
-    ".srf": "text/plain",
-    ".SSISDeploymentManifest": "text/xml",
-    ".ssm": "application/streamingmedia",
-    ".sst": "application/vnd.ms-pki.certstore",
-    ".stl": "application/vnd.ms-pki.stl",
-    ".sv4cpio": "application/x-sv4cpio",
-    ".sv4crc": "application/x-sv4crc",
-    ".svc": "application/xml",
-    ".svg": "image/svg+xml",
-    ".swf": "application/x-shockwave-flash",
-    ".step": "application/step",
-    ".stp": "application/step",
-    ".t": "application/x-troff",
-    ".tar": "application/x-tar",
-    ".tcl": "application/x-tcl",
-    ".testrunconfig": "application/xml",
-    ".testsettings": "application/xml",
-    ".tex": "application/x-tex",
-    ".texi": "application/x-texinfo",
-    ".texinfo": "application/x-texinfo",
-    ".tgz": "application/x-compressed",
-    ".thmx": "application/vnd.ms-officetheme",
-    ".thn": "application/octet-stream",
-    ".tif": "image/tiff",
-    ".tiff": "image/tiff",
-    ".tlh": "text/plain",
-    ".tli": "text/plain",
-    ".toc": "application/octet-stream",
-    ".tr": "application/x-troff",
-    ".trm": "application/x-msterminal",
-    ".trx": "application/xml",
-    ".ts": "video/vnd.dlna.mpeg-tts",
-    ".tsv": "text/tab-separated-values",
-    ".ttf": "application/font-sfnt",
-    ".tts": "video/vnd.dlna.mpeg-tts",
-    ".txt": "text/plain",
-    ".u32": "application/octet-stream",
-    ".uls": "text/iuls",
-    ".user": "text/plain",
-    ".ustar": "application/x-ustar",
-    ".vb": "text/plain",
-    ".vbdproj": "text/plain",
-    ".vbk": "video/mpeg",
-    ".vbproj": "text/plain",
-    ".vbs": "text/vbscript",
-    ".vcf": "text/x-vcard",
-    ".vcproj": "application/xml",
-    ".vcs": "text/plain",
-    ".vcxproj": "application/xml",
-    ".vddproj": "text/plain",
-    ".vdp": "text/plain",
-    ".vdproj": "text/plain",
-    ".vdx": "application/vnd.ms-visio.viewer",
-    ".vml": "text/xml",
-    ".vscontent": "application/xml",
-    ".vsct": "text/xml",
-    ".vsd": "application/vnd.visio",
-    ".vsi": "application/ms-vsi",
-    ".vsix": "application/vsix",
-    ".vsixlangpack": "text/xml",
-    ".vsixmanifest": "text/xml",
-    ".vsmdi": "application/xml",
-    ".vspscc": "text/plain",
-    ".vss": "application/vnd.visio",
-    ".vsscc": "text/plain",
-    ".vssettings": "text/xml",
-    ".vssscc": "text/plain",
-    ".vst": "application/vnd.visio",
-    ".vstemplate": "text/xml",
-    ".vsto": "application/x-ms-vsto",
-    ".vsw": "application/vnd.visio",
-    ".vsx": "application/vnd.visio",
-    ".vtx": "application/vnd.visio",
-    ".wav": "audio/wav",
-    ".wave": "audio/wav",
-    ".wax": "audio/x-ms-wax",
-    ".wbk": "application/msword",
-    ".wbmp": "image/vnd.wap.wbmp",
-    ".wcm": "application/vnd.ms-works",
-    ".wdb": "application/vnd.ms-works",
-    ".wdp": "image/vnd.ms-photo",
-    ".webarchive": "application/x-safari-webarchive",
-    ".webm": "video/webm",
-    ".webp": "image/webp" /* https"://en.wikipedia.org/wiki/WebP */,
-    ".webtest": "application/xml",
-    ".wiq": "application/xml",
-    ".wiz": "application/msword",
-    ".wks": "application/vnd.ms-works",
-    ".WLMP": "application/wlmoviemaker",
-    ".wlpginstall": "application/x-wlpg-detect",
-    ".wlpginstall3": "application/x-wlpg3-detect",
-    ".wm": "video/x-ms-wm",
-    ".wma": "audio/x-ms-wma",
-    ".wmd": "application/x-ms-wmd",
-    ".wmf": "application/x-msmetafile",
-    ".wml": "text/vnd.wap.wml",
-    ".wmlc": "application/vnd.wap.wmlc",
-    ".wmls": "text/vnd.wap.wmlscript",
-    ".wmlsc": "application/vnd.wap.wmlscriptc",
-    ".wmp": "video/x-ms-wmp",
-    ".wmv": "video/x-ms-wmv",
-    ".wmx": "video/x-ms-wmx",
-    ".wmz": "application/x-ms-wmz",
-    ".woff": "application/font-woff",
-    ".wpl": "application/vnd.ms-wpl",
-    ".wps": "application/vnd.ms-works",
-    ".wri": "application/x-mswrite",
-    ".wrl": "x-world/x-vrml",
-    ".wrz": "x-world/x-vrml",
-    ".wsc": "text/scriptlet",
-    ".wsdl": "text/xml",
-    ".wvx": "video/x-ms-wvx",
-    ".x": "application/directx",
-    ".xaf": "x-world/x-vrml",
-    ".xaml": "application/xaml+xml",
-    ".xap": "application/x-silverlight-app",
-    ".xbap": "application/x-ms-xbap",
-    ".xbm": "image/x-xbitmap",
-    ".xdr": "text/plain",
-    ".xht": "application/xhtml+xml",
-    ".xhtml": "application/xhtml+xml",
-    ".xla": "application/vnd.ms-excel",
-    ".xlam": "application/vnd.ms-excel.addin.macroEnabled.12",
-    ".xlc": "application/vnd.ms-excel",
-    ".xld": "application/vnd.ms-excel",
-    ".xlk": "application/vnd.ms-excel",
-    ".xll": "application/vnd.ms-excel",
-    ".xlm": "application/vnd.ms-excel",
-    ".xls": "application/vnd.ms-excel",
-    ".xlsb": "application/vnd.ms-excel.sheet.binary.macroEnabled.12",
-    ".xlsm": "application/vnd.ms-excel.sheet.macroEnabled.12",
-    ".xlsx":
-      "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
-    ".xlt": "application/vnd.ms-excel",
-    ".xltm": "application/vnd.ms-excel.template.macroEnabled.12",
-    ".xltx":
-      "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
-    ".xlw": "application/vnd.ms-excel",
-    ".xml": "text/xml",
-    ".xmp": "application/octet-stream",
-    ".xmta": "application/xml",
-    ".xof": "x-world/x-vrml",
-    ".XOML": "text/plain",
-    ".xpm": "image/x-xpixmap",
-    ".xps": "application/vnd.ms-xpsdocument",
-    ".xrm-ms": "text/xml",
-    ".xsc": "application/xml",
-    ".xsd": "text/xml",
-    ".xsf": "text/xml",
-    ".xsl": "text/xml",
-    ".xslt": "text/xml",
-    ".xsn": "application/octet-stream",
-    ".xss": "application/xml",
-    ".xspf": "application/xspf+xml",
-    ".xtp": "application/octet-stream",
-    ".xwd": "image/x-xwindowdump",
-    ".z": "application/x-compress",
-    ".zip": "application/zip",
-  };
+    static MIMES: any = {
+        ".323": "text/h323",
+        ".3g2": "video/3gpp2",
+        ".3gp": "video/3gpp",
+        ".3gp2": "video/3gpp2",
+        ".3gpp": "video/3gpp",
+        ".7z": "application/x-7z-compressed",
+        ".aa": "audio/audible",
+        ".AAC": "audio/aac",
+        ".aaf": "application/octet-stream",
+        ".aax": "audio/vnd.audible.aax",
+        ".ac3": "audio/ac3",
+        ".aca": "application/octet-stream",
+        ".accda": "application/msaccess.addin",
+        ".accdb": "application/msaccess",
+        ".accdc": "application/msaccess.cab",
+        ".accde": "application/msaccess",
+        ".accdr": "application/msaccess.runtime",
+        ".accdt": "application/msaccess",
+        ".accdw": "application/msaccess.webapplication",
+        ".accft": "application/msaccess.ftemplate",
+        ".acx": "application/internet-property-stream",
+        ".AddIn": "text/xml",
+        ".ade": "application/msaccess",
+        ".adobebridge": "application/x-bridge-url",
+        ".adp": "application/msaccess",
+        ".ADT": "audio/vnd.dlna.adts",
+        ".ADTS": "audio/aac",
+        ".afm": "application/octet-stream",
+        ".ai": "application/postscript",
+        ".aif": "audio/aiff",
+        ".aifc": "audio/aiff",
+        ".aiff": "audio/aiff",
+        ".air": "application/vnd.adobe.air-application-installer-package+zip",
+        ".amc": "application/mpeg",
+        ".anx": "application/annodex",
+        ".apk": "application/vnd.android.package-archive",
+        ".application": "application/x-ms-application",
+        ".art": "image/x-jg",
+        ".asa": "application/xml",
+        ".asax": "application/xml",
+        ".ascx": "application/xml",
+        ".asd": "application/octet-stream",
+        ".asf": "video/x-ms-asf",
+        ".ashx": "application/xml",
+        ".asi": "application/octet-stream",
+        ".asm": "text/plain",
+        ".asmx": "application/xml",
+        ".aspx": "application/xml",
+        ".asr": "video/x-ms-asf",
+        ".asx": "video/x-ms-asf",
+        ".atom": "application/atom+xml",
+        ".au": "audio/basic",
+        ".avi": "video/x-msvideo",
+        ".axa": "audio/annodex",
+        ".axs": "application/olescript",
+        ".axv": "video/annodex",
+        ".bas": "text/plain",
+        ".bat": "text/plain",
+        ".bcpio": "application/x-bcpio",
+        ".bin": "application/octet-stream",
+        ".bmp": "image/bmp",
+        ".c": "text/plain",
+        ".cab": "application/octet-stream",
+        ".caf": "audio/x-caf",
+        ".calx": "application/vnd.ms-office.calx",
+        ".cat": "application/vnd.ms-pki.seccat",
+        ".cc": "text/plain",
+        ".cd": "text/plain",
+        ".cdda": "audio/aiff",
+        ".cdf": "application/x-cdf",
+        ".cer": "application/x-x509-ca-cert",
+        ".cfg": "text/plain",
+        ".chm": "application/octet-stream",
+        ".class": "application/x-java-applet",
+        ".clp": "application/x-msclip",
+        ".cmd": "text/plain",
+        ".cmx": "image/x-cmx",
+        ".cnf": "text/plain",
+        ".cod": "image/cis-cod",
+        ".config": "application/xml",
+        ".contact": "text/x-ms-contact",
+        ".coverage": "application/xml",
+        ".cpio": "application/x-cpio",
+        ".cpp": "text/plain",
+        ".crd": "application/x-mscardfile",
+        ".crl": "application/pkix-crl",
+        ".crt": "application/x-x509-ca-cert",
+        ".cs": "text/plain",
+        ".csdproj": "text/plain",
+        ".csh": "application/x-csh",
+        ".csproj": "text/plain",
+        ".css": "text/css",
+        ".csv": "application/csv",
+        ".cur": "application/octet-stream",
+        ".cxx": "text/plain",
+        ".dat": "application/octet-stream",
+        ".datasource": "application/xml",
+        ".dbproj": "text/plain",
+        ".dcr": "application/x-director",
+        ".def": "text/plain",
+        ".deploy": "application/octet-stream",
+        ".der": "application/x-x509-ca-cert",
+        ".dgml": "application/xml",
+        ".dib": "image/bmp",
+        ".dif": "video/x-dv",
+        ".dir": "application/x-director",
+        ".disco": "text/xml",
+        ".divx": "video/divx",
+        ".dll": "application/x-msdownload",
+        ".dll.config": "text/xml",
+        ".dlm": "text/dlm",
+        ".doc": "application/msword",
+        ".docm": "application/vnd.ms-word.document.macroEnabled.12",
+        ".docx":
+            "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+        ".dot": "application/msword",
+        ".dotm": "application/vnd.ms-word.template.macroEnabled.12",
+        ".dotx":
+            "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
+        ".dsp": "application/octet-stream",
+        ".dsw": "text/plain",
+        ".dtd": "text/xml",
+        ".dtsConfig": "text/xml",
+        ".dv": "video/x-dv",
+        ".dvi": "application/x-dvi",
+        ".dwf": "drawing/x-dwf",
+        ".dwg": "application/acad",
+        ".dwp": "application/octet-stream",
+        ".dxf": "application/x-dxf",
+        ".dxr": "application/x-director",
+        ".eml": "message/rfc822",
+        ".emz": "application/octet-stream",
+        ".eot": "application/vnd.ms-fontobject",
+        ".eps": "application/postscript",
+        ".etl": "application/etl",
+        ".etx": "text/x-setext",
+        ".evy": "application/envoy",
+        ".exe": "application/octet-stream",
+        ".exe.config": "text/xml",
+        ".fdf": "application/vnd.fdf",
+        ".fif": "application/fractals",
+        ".filters": "application/xml",
+        ".fla": "application/octet-stream",
+        ".flac": "audio/flac",
+        ".flr": "x-world/x-vrml",
+        ".flv": "video/x-flv",
+        ".fsscript": "application/fsharp-script",
+        ".fsx": "application/fsharp-script",
+        ".generictest": "application/xml",
+        ".gif": "image/gif",
+        ".gpx": "application/gpx+xml",
+        ".group": "text/x-ms-group",
+        ".gradle": "text/plain",
+        ".gsm": "audio/x-gsm",
+        ".gtar": "application/x-gtar",
+        ".gz": "application/x-gzip",
+        ".h": "text/plain",
+        ".hdf": "application/x-hdf",
+        ".hdml": "text/x-hdml",
+        ".hhc": "application/x-oleobject",
+        ".hhk": "application/octet-stream",
+        ".hhp": "application/octet-stream",
+        ".hlp": "application/winhlp",
+        ".hpp": "text/plain",
+        ".hqx": "application/mac-binhex40",
+        ".hta": "application/hta",
+        ".htc": "text/x-component",
+        ".htm": "text/html",
+        ".html": "text/html",
+        ".htt": "text/webviewhtml",
+        ".hxa": "application/xml",
+        ".hxc": "application/xml",
+        ".hxd": "application/octet-stream",
+        ".hxe": "application/xml",
+        ".hxf": "application/xml",
+        ".hxh": "application/octet-stream",
+        ".hxi": "application/octet-stream",
+        ".hxk": "application/xml",
+        ".hxq": "application/octet-stream",
+        ".hxr": "application/octet-stream",
+        ".hxs": "application/octet-stream",
+        ".hxt": "text/html",
+        ".hxv": "application/xml",
+        ".hxw": "application/octet-stream",
+        ".hxx": "text/plain",
+        ".i": "text/plain",
+        ".ico": "image/x-icon",
+        ".ics": "application/octet-stream",
+        ".idl": "text/plain",
+        ".ief": "image/ief",
+        ".iii": "application/x-iphone",
+        ".inc": "text/plain",
+        ".inf": "application/octet-stream",
+        ".ini": "text/plain",
+        ".inl": "text/plain",
+        ".ins": "application/x-internet-signup",
+        ".ipa": "application/x-itunes-ipa",
+        ".ipg": "application/x-itunes-ipg",
+        ".ipproj": "text/plain",
+        ".ipsw": "application/x-itunes-ipsw",
+        ".iqy": "text/x-ms-iqy",
+        ".isp": "application/x-internet-signup",
+        ".ite": "application/x-itunes-ite",
+        ".itlp": "application/x-itunes-itlp",
+        ".itms": "application/x-itunes-itms",
+        ".itpc": "application/x-itunes-itpc",
+        ".IVF": "video/x-ivf",
+        ".jar": "application/java-archive",
+        ".java": "text/plain",
+        ".jck": "application/liquidmotion",
+        ".jcz": "application/liquidmotion",
+        ".jfif": "image/pjpeg",
+        ".jnlp": "application/x-java-jnlp-file",
+        ".jpb": "application/octet-stream",
+        ".jpe": "image/jpeg",
+        ".jpeg": "image/jpeg",
+        ".jpg": "image/jpeg",
+        ".js": "text/plain",
+        ".json": "application/json",
+        ".jsx": "text/jscript",
+        ".jsxbin": "text/plain",
+        ".latex": "application/x-latex",
+        ".less": "text/plain",
+        ".library-ms": "application/windows-library+xml",
+        ".lit": "application/x-ms-reader",
+        ".loadtest": "application/xml",
+        ".lpk": "application/octet-stream",
+        ".lsf": "video/x-la-asf",
+        ".lst": "text/plain",
+        ".lsx": "video/x-la-asf",
+        ".lzh": "application/octet-stream",
+        ".m13": "application/x-msmediaview",
+        ".m14": "application/x-msmediaview",
+        ".m1v": "video/mpeg",
+        ".m2t": "video/vnd.dlna.mpeg-tts",
+        ".m2ts": "video/vnd.dlna.mpeg-tts",
+        ".m2v": "video/mpeg",
+        ".m3u": "audio/x-mpegurl",
+        ".m3u8": "audio/x-mpegurl",
+        ".m4a": "audio/m4a",
+        ".m4b": "audio/m4b",
+        ".m4p": "audio/m4p",
+        ".m4r": "audio/x-m4r",
+        ".m4v": "video/x-m4v",
+        ".mac": "image/x-macpaint",
+        ".mak": "text/plain",
+        ".man": "application/x-troff-man",
+        ".manifest": "application/x-ms-manifest",
+        ".map": "text/plain",
+        ".master": "application/xml",
+        ".mbox": "application/mbox",
+        ".md": "text/plain",
+        ".mda": "application/msaccess",
+        ".mdb": "application/x-msaccess",
+        ".mde": "application/msaccess",
+        ".mdp": "application/octet-stream",
+        ".me": "application/x-troff-me",
+        ".mfp": "application/x-shockwave-flash",
+        ".mht": "message/rfc822",
+        ".mhtml": "message/rfc822",
+        ".mid": "audio/mid",
+        ".midi": "audio/mid",
+        ".mix": "application/octet-stream",
+        ".mk": "text/plain",
+        ".mmf": "application/x-smaf",
+        ".mno": "text/xml",
+        ".mny": "application/x-msmoney",
+        ".mod": "video/mpeg",
+        ".mov": "video/quicktime",
+        ".movie": "video/x-sgi-movie",
+        ".mp2": "video/mpeg",
+        ".mp2v": "video/mpeg",
+        ".mp3": "audio/mpeg",
+        ".mp4": "video/mp4",
+        ".mp4v": "video/mp4",
+        ".mpa": "video/mpeg",
+        ".mpe": "video/mpeg",
+        ".mpeg": "video/mpeg",
+        ".mpf": "application/vnd.ms-mediapackage",
+        ".mpg": "video/mpeg",
+        ".mpp": "application/vnd.ms-project",
+        ".mpv2": "video/mpeg",
+        ".mqv": "video/quicktime",
+        ".ms": "application/x-troff-ms",
+        ".msg": "application/vnd.ms-outlook",
+        ".msi": "application/octet-stream",
+        ".mso": "application/octet-stream",
+        ".mts": "video/vnd.dlna.mpeg-tts",
+        ".mtx": "application/xml",
+        ".mvb": "application/x-msmediaview",
+        ".mvc": "application/x-miva-compiled",
+        ".mxp": "application/x-mmxp",
+        ".nc": "application/x-netcdf",
+        ".nsc": "video/x-ms-asf",
+        ".nws": "message/rfc822",
+        ".ocx": "application/octet-stream",
+        ".oda": "application/oda",
+        ".odb": "application/vnd.oasis.opendocument.database",
+        ".odc": "application/vnd.oasis.opendocument.chart",
+        ".odf": "application/vnd.oasis.opendocument.formula",
+        ".odg": "application/vnd.oasis.opendocument.graphics",
+        ".odh": "text/plain",
+        ".odi": "application/vnd.oasis.opendocument.image",
+        ".odl": "text/plain",
+        ".odm": "application/vnd.oasis.opendocument.text-master",
+        ".odp": "application/vnd.oasis.opendocument.presentation",
+        ".ods": "application/vnd.oasis.opendocument.spreadsheet",
+        ".odt": "application/vnd.oasis.opendocument.text",
+        ".oga": "audio/ogg",
+        ".ogg": "audio/ogg",
+        ".ogv": "video/ogg",
+        ".ogx": "application/ogg",
+        ".one": "application/onenote",
+        ".onea": "application/onenote",
+        ".onepkg": "application/onenote",
+        ".onetmp": "application/onenote",
+        ".onetoc": "application/onenote",
+        ".onetoc2": "application/onenote",
+        ".opus": "audio/ogg",
+        ".orderedtest": "application/xml",
+        ".osdx": "application/opensearchdescription+xml",
+        ".otf": "application/font-sfnt",
+        ".otg": "application/vnd.oasis.opendocument.graphics-template",
+        ".oth": "application/vnd.oasis.opendocument.text-web",
+        ".otp": "application/vnd.oasis.opendocument.presentation-template",
+        ".ots": "application/vnd.oasis.opendocument.spreadsheet-template",
+        ".ott": "application/vnd.oasis.opendocument.text-template",
+        ".oxt": "application/vnd.openofficeorg.extension",
+        ".p10": "application/pkcs10",
+        ".p12": "application/x-pkcs12",
+        ".p7b": "application/x-pkcs7-certificates",
+        ".p7c": "application/pkcs7-mime",
+        ".p7m": "application/pkcs7-mime",
+        ".p7r": "application/x-pkcs7-certreqresp",
+        ".p7s": "application/pkcs7-signature",
+        ".pbm": "image/x-portable-bitmap",
+        ".pcast": "application/x-podcast",
+        ".pct": "image/pict",
+        ".pcx": "application/octet-stream",
+        ".pcz": "application/octet-stream",
+        ".pdf": "application/pdf",
+        ".pfb": "application/octet-stream",
+        ".pfm": "application/octet-stream",
+        ".pfx": "application/x-pkcs12",
+        ".pgm": "image/x-portable-graymap",
+        ".pic": "image/pict",
+        ".pict": "image/pict",
+        ".pkgdef": "text/plain",
+        ".pkgundef": "text/plain",
+        ".pko": "application/vnd.ms-pki.pko",
+        ".pls": "audio/scpls",
+        ".pma": "application/x-perfmon",
+        ".pmc": "application/x-perfmon",
+        ".pml": "application/x-perfmon",
+        ".pmr": "application/x-perfmon",
+        ".pmw": "application/x-perfmon",
+        ".png": "image/png",
+        ".pnm": "image/x-portable-anymap",
+        ".pnt": "image/x-macpaint",
+        ".pntg": "image/x-macpaint",
+        ".pnz": "image/png",
+        ".pot": "application/vnd.ms-powerpoint",
+        ".potm": "application/vnd.ms-powerpoint.template.macroEnabled.12",
+        ".potx":
+            "application/vnd.openxmlformats-officedocument.presentationml.template",
+        ".ppa": "application/vnd.ms-powerpoint",
+        ".ppam": "application/vnd.ms-powerpoint.addin.macroEnabled.12",
+        ".ppm": "image/x-portable-pixmap",
+        ".pps": "application/vnd.ms-powerpoint",
+        ".ppsm": "application/vnd.ms-powerpoint.slideshow.macroEnabled.12",
+        ".ppsx":
+            "application/vnd.openxmlformats-officedocument.presentationml.slideshow",
+        ".ppt": "application/vnd.ms-powerpoint",
+        ".pptm": "application/vnd.ms-powerpoint.presentation.macroEnabled.12",
+        ".pptx":
+            "application/vnd.openxmlformats-officedocument.presentationml.presentation",
+        ".prf": "application/pics-rules",
+        ".prm": "application/octet-stream",
+        ".prx": "application/octet-stream",
+        ".ps": "application/postscript",
+        ".psc1": "application/PowerShell",
+        ".psd": "application/octet-stream",
+        ".psess": "application/xml",
+        ".psm": "application/octet-stream",
+        ".psp": "application/octet-stream",
+        ".pst": "application/vnd.ms-outlook",
+        ".pub": "application/x-mspublisher",
+        ".py": "text/plain",
+        ".pwz": "application/vnd.ms-powerpoint",
+        ".qht": "text/x-html-insertion",
+        ".qhtm": "text/x-html-insertion",
+        ".qt": "video/quicktime",
+        ".qti": "image/x-quicktime",
+        ".qtif": "image/x-quicktime",
+        ".qtl": "application/x-quicktimeplayer",
+        ".qxd": "application/octet-stream",
+        ".ra": "audio/x-pn-realaudio",
+        ".ram": "audio/x-pn-realaudio",
+        ".rar": "application/x-rar-compressed",
+        ".ras": "image/x-cmu-raster",
+        ".rat": "application/rat-file",
+        ".rc": "text/plain",
+        ".rc2": "text/plain",
+        ".rct": "text/plain",
+        ".rdlc": "application/xml",
+        ".reg": "text/plain",
+        ".resx": "application/xml",
+        ".rf": "image/vnd.rn-realflash",
+        ".rgb": "image/x-rgb",
+        ".rgs": "text/plain",
+        ".rm": "application/vnd.rn-realmedia",
+        ".rmi": "audio/mid",
+        ".rmp": "application/vnd.rn-rn_music_package",
+        ".roff": "application/x-troff",
+        ".rpm": "audio/x-pn-realaudio-plugin",
+        ".rqy": "text/x-ms-rqy",
+        ".rtf": "application/rtf",
+        ".rtx": "text/richtext",
+        ".rvt": "application/octet-stream",
+        ".ruleset": "application/xml",
+        ".s": "text/plain",
+        ".safariextz": "application/x-safari-safariextz",
+        ".scd": "application/x-msschedule",
+        ".scr": "text/plain",
+        ".sct": "text/scriptlet",
+        ".sd2": "audio/x-sd2",
+        ".sdp": "application/sdp",
+        ".sea": "application/octet-stream",
+        ".searchConnector-ms": "application/windows-search-connector+xml",
+        ".setpay": "application/set-payment-initiation",
+        ".setreg": "application/set-registration-initiation",
+        ".settings": "application/xml",
+        ".sgimb": "application/x-sgimb",
+        ".sgml": "text/sgml",
+        ".sh": "text/plain",
+        ".shar": "application/x-shar",
+        ".shtml": "text/html",
+        ".sit": "application/x-stuffit",
+        ".sitemap": "application/xml",
+        ".skin": "application/xml",
+        ".skp": "application/x-koan",
+        ".sldm": "application/vnd.ms-powerpoint.slide.macroEnabled.12",
+        ".sldx":
+            "application/vnd.openxmlformats-officedocument.presentationml.slide",
+        ".slk": "application/vnd.ms-excel",
+        ".sln": "text/plain",
+        ".slupkg-ms": "application/x-ms-license",
+        ".smd": "audio/x-smd",
+        ".smi": "application/octet-stream",
+        ".smx": "audio/x-smd",
+        ".smz": "audio/x-smd",
+        ".snd": "audio/basic",
+        ".snippet": "application/xml",
+        ".snp": "application/octet-stream",
+        ".sol": "text/plain",
+        ".sor": "text/plain",
+        ".spc": "application/x-pkcs7-certificates",
+        ".spl": "application/futuresplash",
+        ".spx": "audio/ogg",
+        ".sql": "text/plain",
+        ".src": "application/x-wais-source",
+        ".srf": "text/plain",
+        ".SSISDeploymentManifest": "text/xml",
+        ".ssm": "application/streamingmedia",
+        ".sst": "application/vnd.ms-pki.certstore",
+        ".stl": "application/vnd.ms-pki.stl",
+        ".sv4cpio": "application/x-sv4cpio",
+        ".sv4crc": "application/x-sv4crc",
+        ".svc": "application/xml",
+        ".svg": "image/svg+xml",
+        ".swf": "application/x-shockwave-flash",
+        ".step": "application/step",
+        ".stp": "application/step",
+        ".t": "application/x-troff",
+        ".tar": "application/x-tar",
+        ".tcl": "application/x-tcl",
+        ".testrunconfig": "application/xml",
+        ".testsettings": "application/xml",
+        ".tex": "application/x-tex",
+        ".texi": "application/x-texinfo",
+        ".texinfo": "application/x-texinfo",
+        ".tgz": "application/x-compressed",
+        ".thmx": "application/vnd.ms-officetheme",
+        ".thn": "application/octet-stream",
+        ".tif": "image/tiff",
+        ".tiff": "image/tiff",
+        ".tlh": "text/plain",
+        ".tli": "text/plain",
+        ".toc": "application/octet-stream",
+        ".tr": "application/x-troff",
+        ".trm": "application/x-msterminal",
+        ".trx": "application/xml",
+        ".ts": "video/vnd.dlna.mpeg-tts",
+        ".tsv": "text/tab-separated-values",
+        ".ttf": "application/font-sfnt",
+        ".tts": "video/vnd.dlna.mpeg-tts",
+        ".txt": "text/plain",
+        ".u32": "application/octet-stream",
+        ".uls": "text/iuls",
+        ".user": "text/plain",
+        ".ustar": "application/x-ustar",
+        ".vb": "text/plain",
+        ".vbdproj": "text/plain",
+        ".vbk": "video/mpeg",
+        ".vbproj": "text/plain",
+        ".vbs": "text/vbscript",
+        ".vcf": "text/x-vcard",
+        ".vcproj": "application/xml",
+        ".vcs": "text/plain",
+        ".vcxproj": "application/xml",
+        ".vddproj": "text/plain",
+        ".vdp": "text/plain",
+        ".vdproj": "text/plain",
+        ".vdx": "application/vnd.ms-visio.viewer",
+        ".vml": "text/xml",
+        ".vscontent": "application/xml",
+        ".vsct": "text/xml",
+        ".vsd": "application/vnd.visio",
+        ".vsi": "application/ms-vsi",
+        ".vsix": "application/vsix",
+        ".vsixlangpack": "text/xml",
+        ".vsixmanifest": "text/xml",
+        ".vsmdi": "application/xml",
+        ".vspscc": "text/plain",
+        ".vss": "application/vnd.visio",
+        ".vsscc": "text/plain",
+        ".vssettings": "text/xml",
+        ".vssscc": "text/plain",
+        ".vst": "application/vnd.visio",
+        ".vstemplate": "text/xml",
+        ".vsto": "application/x-ms-vsto",
+        ".vsw": "application/vnd.visio",
+        ".vsx": "application/vnd.visio",
+        ".vtx": "application/vnd.visio",
+        ".wav": "audio/wav",
+        ".wave": "audio/wav",
+        ".wax": "audio/x-ms-wax",
+        ".wbk": "application/msword",
+        ".wbmp": "image/vnd.wap.wbmp",
+        ".wcm": "application/vnd.ms-works",
+        ".wdb": "application/vnd.ms-works",
+        ".wdp": "image/vnd.ms-photo",
+        ".webarchive": "application/x-safari-webarchive",
+        ".webm": "video/webm",
+        ".webp": "image/webp" /* https"://en.wikipedia.org/wiki/WebP */,
+        ".webtest": "application/xml",
+        ".wiq": "application/xml",
+        ".wiz": "application/msword",
+        ".wks": "application/vnd.ms-works",
+        ".WLMP": "application/wlmoviemaker",
+        ".wlpginstall": "application/x-wlpg-detect",
+        ".wlpginstall3": "application/x-wlpg3-detect",
+        ".wm": "video/x-ms-wm",
+        ".wma": "audio/x-ms-wma",
+        ".wmd": "application/x-ms-wmd",
+        ".wmf": "application/x-msmetafile",
+        ".wml": "text/vnd.wap.wml",
+        ".wmlc": "application/vnd.wap.wmlc",
+        ".wmls": "text/vnd.wap.wmlscript",
+        ".wmlsc": "application/vnd.wap.wmlscriptc",
+        ".wmp": "video/x-ms-wmp",
+        ".wmv": "video/x-ms-wmv",
+        ".wmx": "video/x-ms-wmx",
+        ".wmz": "application/x-ms-wmz",
+        ".woff": "application/font-woff",
+        ".wpl": "application/vnd.ms-wpl",
+        ".wps": "application/vnd.ms-works",
+        ".wri": "application/x-mswrite",
+        ".wrl": "x-world/x-vrml",
+        ".wrz": "x-world/x-vrml",
+        ".wsc": "text/scriptlet",
+        ".wsdl": "text/xml",
+        ".wvx": "video/x-ms-wvx",
+        ".x": "application/directx",
+        ".xaf": "x-world/x-vrml",
+        ".xaml": "application/xaml+xml",
+        ".xap": "application/x-silverlight-app",
+        ".xbap": "application/x-ms-xbap",
+        ".xbm": "image/x-xbitmap",
+        ".xdr": "text/plain",
+        ".xht": "application/xhtml+xml",
+        ".xhtml": "application/xhtml+xml",
+        ".xla": "application/vnd.ms-excel",
+        ".xlam": "application/vnd.ms-excel.addin.macroEnabled.12",
+        ".xlc": "application/vnd.ms-excel",
+        ".xld": "application/vnd.ms-excel",
+        ".xlk": "application/vnd.ms-excel",
+        ".xll": "application/vnd.ms-excel",
+        ".xlm": "application/vnd.ms-excel",
+        ".xls": "application/vnd.ms-excel",
+        ".xlsb": "application/vnd.ms-excel.sheet.binary.macroEnabled.12",
+        ".xlsm": "application/vnd.ms-excel.sheet.macroEnabled.12",
+        ".xlsx":
+            "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+        ".xlt": "application/vnd.ms-excel",
+        ".xltm": "application/vnd.ms-excel.template.macroEnabled.12",
+        ".xltx":
+            "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
+        ".xlw": "application/vnd.ms-excel",
+        ".xml": "text/xml",
+        ".xmp": "application/octet-stream",
+        ".xmta": "application/xml",
+        ".xof": "x-world/x-vrml",
+        ".XOML": "text/plain",
+        ".xpm": "image/x-xpixmap",
+        ".xps": "application/vnd.ms-xpsdocument",
+        ".xrm-ms": "text/xml",
+        ".xsc": "application/xml",
+        ".xsd": "text/xml",
+        ".xsf": "text/xml",
+        ".xsl": "text/xml",
+        ".xslt": "text/xml",
+        ".xsn": "application/octet-stream",
+        ".xss": "application/xml",
+        ".xspf": "application/xspf+xml",
+        ".xtp": "application/octet-stream",
+        ".xwd": "image/x-xwindowdump",
+        ".z": "application/x-compress",
+        ".zip": "application/zip",
+    };
 
-  //根据一个文件名,获取其后缀名(一律使用小写,带.),如果没有后缀名,那么返回""
-  static getExtension(filename: string | null) {
-    if (filename == null) {
-      return "";
+    //根据一个文件名,获取其后缀名(一律使用小写,带.),如果没有后缀名,那么返回""
+    static getExtension(filename: string | null) {
+        if (filename == null) {
+            return "";
+        }
+        let dotIndex = filename.lastIndexOf(".");
+        if (dotIndex === -1) {
+            return "";
+        } else {
+            return filename.substring(dotIndex).toLowerCase();
+        }
     }
-    let dotIndex = filename.lastIndexOf(".");
-    if (dotIndex === -1) {
-      return "";
-    } else {
-      return filename.substring(dotIndex).toLowerCase();
-    }
-  }
 
-  //根据一个文件名,获取其后缀名(一律使用小写,不带.),如果没有后缀名,那么返回""
-  static getExtensionWithoutDot(filename: string | null) {
-    if (filename == null) {
-      return "";
+    //根据一个文件名,获取其后缀名(一律使用小写,不带.),如果没有后缀名,那么返回""
+    static getExtensionWithoutDot(filename: string | null) {
+        if (filename == null) {
+            return "";
+        }
+        let dotIndex = filename.lastIndexOf(".");
+        if (dotIndex === -1) {
+            return "";
+        } else {
+            return filename.substring(dotIndex + 1).toLowerCase();
+        }
     }
-    let dotIndex = filename.lastIndexOf(".");
-    if (dotIndex === -1) {
-      return "";
-    } else {
-      return filename.substring(dotIndex + 1).toLowerCase();
-    }
-  }
 
-  //根据一个文件名(带后缀的),获取对应的文件类型。
-  static getMimeType(filename: string | null) {
-    let extension = MimeUtil.getExtension(filename);
-    if (MimeUtil.MIMES[extension]) {
-      return MimeUtil.MIMES[extension];
-    } else {
-      return "application/octet-stream";
+    //根据一个文件名(带后缀的),获取对应的文件类型。
+    static getMimeType(filename: string | null) {
+        let extension = MimeUtil.getExtension(filename);
+        if (MimeUtil.MIMES[extension]) {
+            return MimeUtil.MIMES[extension];
+        } else {
+            return "application/octet-stream";
+        }
     }
-  }
 }
diff --git a/src/common/util/NumberUtil.ts b/src/common/util/NumberUtil.ts
index 251147a..0c9c914 100644
--- a/src/common/util/NumberUtil.ts
+++ b/src/common/util/NumberUtil.ts
@@ -1,39 +1,39 @@
 export default class NumberUtil {
-  //求最大公约数
-  static gcd(a: number, b: number): number {
-    return b ? NumberUtil.gcd(b, a % b) : a;
-  }
-
-  //约分 numerator:分子 denominator:分母
-  static reduce(numerator: number, denominator: number) {
-    let maxFactor = NumberUtil.gcd(numerator, denominator);
-    return [numerator / maxFactor, denominator / maxFactor];
-  }
-
-  static isInteger(obj: any) {
-    return typeof obj === "number" && obj % 1 === 0;
-  }
-
-  //转换成整型
-  static parseInt(obj: any): number {
-    try {
-      return parseInt(obj);
-    } catch (e) {
-      console.error("无法转换成整数", obj);
-      return 0;
+    //求最大公约数
+    static gcd(a: number, b: number): number {
+        return b ? NumberUtil.gcd(b, a % b) : a;
     }
-  }
 
-  //比较两个分数是否相等
-  static fractionEqual(
-    numerator1: number,
-    denominator1: number,
-    numerator2: number,
-    denominator2: number
-  ) {
-    let fraction1 = NumberUtil.reduce(numerator1, denominator1);
-    let fraction2 = NumberUtil.reduce(numerator2, denominator2);
+    //约分 numerator:分子 denominator:分母
+    static reduce(numerator: number, denominator: number) {
+        let maxFactor = NumberUtil.gcd(numerator, denominator);
+        return [numerator / maxFactor, denominator / maxFactor];
+    }
 
-    return fraction1[0] === fraction2[0] && fraction1[1] === fraction2[1];
-  }
+    static isInteger(obj: any) {
+        return typeof obj === "number" && obj % 1 === 0;
+    }
+
+    //转换成整型
+    static parseInt(obj: any): number {
+        try {
+            return parseInt(obj);
+        } catch (e) {
+            console.error("无法转换成整数", obj);
+            return 0;
+        }
+    }
+
+    //比较两个分数是否相等
+    static fractionEqual(
+        numerator1: number,
+        denominator1: number,
+        numerator2: number,
+        denominator2: number
+    ) {
+        let fraction1 = NumberUtil.reduce(numerator1, denominator1);
+        let fraction2 = NumberUtil.reduce(numerator2, denominator2);
+
+        return fraction1[0] === fraction2[0] && fraction1[1] === fraction2[1];
+    }
 }
diff --git a/src/common/util/ObjectUtil.ts b/src/common/util/ObjectUtil.ts
index fcf6803..6e98a59 100644
--- a/src/common/util/ObjectUtil.ts
+++ b/src/common/util/ObjectUtil.ts
@@ -2,113 +2,113 @@ import DateUtil from "./DateUtil";
 import JsonUtil from "./JsonUtil";
 
 export default class ObjectUtil {
-  //将 extraObj 中的属性全部赋值给standardObj
-  static extend(standardObj: any, extraObj: any) {
-    for (let key in extraObj) {
-      if (extraObj.hasOwnProperty(key)) {
-        if (standardObj.hasOwnProperty(key)) {
-          standardObj[key] = extraObj[key];
+    //将 extraObj 中的属性全部赋值给standardObj
+    static extend(standardObj: any, extraObj: any) {
+        for (let key in extraObj) {
+            if (extraObj.hasOwnProperty(key)) {
+                if (standardObj.hasOwnProperty(key)) {
+                    standardObj[key] = extraObj[key];
+                }
+            }
         }
-      }
     }
-  }
 
-  // 深拷贝,保留standardObj第一层全部属性
-  static deepExtend(standardObj: any, extraObj: any, checkKey: boolean = true) {
-    for (let key in extraObj) {
-      if (checkKey) {
-        if (standardObj.hasOwnProperty(key)) {
-          standardObj[key] =
-            extraObj[key] instanceof Object
-              ? ObjectUtil.deepExtend({}, extraObj[key], false)
-              : extraObj[key];
+    // 深拷贝,保留standardObj第一层全部属性
+    static deepExtend(standardObj: any, extraObj: any, checkKey: boolean = true) {
+        for (let key in extraObj) {
+            if (checkKey) {
+                if (standardObj.hasOwnProperty(key)) {
+                    standardObj[key] =
+                        extraObj[key] instanceof Object
+                            ? ObjectUtil.deepExtend({}, extraObj[key], false)
+                            : extraObj[key];
+                }
+            } else {
+                standardObj[key] =
+                    extraObj[key] instanceof Object
+                        ? ObjectUtil.deepExtend({}, extraObj[key], false)
+                        : extraObj[key];
+            }
         }
-      } else {
-        standardObj[key] =
-            extraObj[key] instanceof Object
-              ? ObjectUtil.deepExtend({}, extraObj[key], false)
-              : extraObj[key];
-      }
+        return standardObj;
     }
-    return standardObj;
-  }
 
-  //将standardObj的field属性规整成时间格式。
-  static assignDate(standardObj: any, field: any) {
-    if (standardObj.hasOwnProperty(field)) {
-      standardObj[field] = DateUtil.str2Date(standardObj[field]);
+    //将standardObj的field属性规整成时间格式。
+    static assignDate(standardObj: any, field: any) {
+        if (standardObj.hasOwnProperty(field)) {
+            standardObj[field] = DateUtil.str2Date(standardObj[field]);
+        }
     }
-  }
 
-  //吧standardObj的field属性归整成Clazz类型
-  static assignList(standardObj: any, field: any, Clazz: any) {
-    if (standardObj.hasOwnProperty(field)) {
-      //如果我们要转换成字符串的数组形式,那么this[field]应该是一个字符串才对。
-      if (Clazz === String) {
-        standardObj[field] = JsonUtil.parseList(standardObj[field]);
+    //吧standardObj的field属性归整成Clazz类型
+    static assignList(standardObj: any, field: any, Clazz: any) {
+        if (standardObj.hasOwnProperty(field)) {
+            //如果我们要转换成字符串的数组形式,那么this[field]应该是一个字符串才对。
+            if (Clazz === String) {
+                standardObj[field] = JsonUtil.parseList(standardObj[field]);
 
-        return;
-      }
+                return;
+            }
 
-      //下面就是转换实体数组了。
-      let beans = standardObj[field];
-      if (!beans) {
-        //服务器返回这个字段为空 维持构造函数中的默认值(一般而言是一个[])
-        standardObj[field] = new standardObj.constructor()[field];
-        return;
-      }
+            //下面就是转换实体数组了。
+            let beans = standardObj[field];
+            if (!beans) {
+                //服务器返回这个字段为空 维持构造函数中的默认值(一般而言是一个[])
+                standardObj[field] = new standardObj.constructor()[field];
+                return;
+            }
 
-      standardObj[field] = [];
+            standardObj[field] = [];
 
-      if (!Clazz) {
-        return;
-      }
+            if (!Clazz) {
+                return;
+            }
 
-      for (let i = 0; i < beans.length; i++) {
-        let bean = beans[i];
-        let clazz = new Clazz();
+            for (let i = 0; i < beans.length; i++) {
+                let bean = beans[i];
+                let clazz = new Clazz();
 
-        if (clazz.assign) {
-          clazz.assign(bean);
-        } else {
-          console.error(clazz);
-          console.error("没有定义assign方法");
+                if (clazz.assign) {
+                    clazz.assign(bean);
+                } else {
+                    console.error(clazz);
+                    console.error("没有定义assign方法");
+                }
+
+                standardObj[field].push(clazz);
+            }
+        }
+    }
+
+    //check whether an obj is empty
+    static isEmptyObject(obj: object) {
+        if (typeof obj !== "object") {
+            console.error("判定的不是obj对象");
+            return true;
         }
 
-        standardObj[field].push(clazz);
-      }
-    }
-  }
+        for (let key in obj) {
+            return false;
+        }
 
-  //check whether an obj is empty
-  static isEmptyObject(obj: object) {
-    if (typeof obj !== "object") {
-      console.error("判定的不是obj对象");
-      return true;
+        return true;
     }
 
-    for (let key in obj) {
-      return false;
+    /**
+     * 将键值对转换成  age=18&name=xxx 的形式
+     */
+    static param(map: any) {
+        let arr: string[] = [];
+        for (let key in map) {
+            if (map.hasOwnProperty(key)) {
+                let value = map[key];
+                arr[arr.length] =
+                    encodeURIComponent(key) +
+                    "=" +
+                    encodeURIComponent(value == null ? "" : value);
+            }
+        }
+
+        return arr.join("&");
     }
-
-    return true;
-  }
-
-  /**
-   * 将键值对转换成  age=18&name=xxx 的形式
-   */
-  static param(map: any) {
-    let arr: string[] = [];
-    for (let key in map) {
-      if (map.hasOwnProperty(key)) {
-        let value = map[key];
-        arr[arr.length] =
-          encodeURIComponent(key) +
-          "=" +
-          encodeURIComponent(value == null ? "" : value);
-      }
-    }
-
-    return arr.join("&");
-  }
 }
diff --git a/src/common/util/SafeUtil.ts b/src/common/util/SafeUtil.ts
index 8b8de45..996e339 100644
--- a/src/common/util/SafeUtil.ts
+++ b/src/common/util/SafeUtil.ts
@@ -1,42 +1,42 @@
 export default class SafeUtil {
 
-  //安全的调用某个函数,函数不存在,创建一个空函数。
-  static safeCallback(callback: any) {
-    if (typeof callback === "function") {
-      return callback
-    } else {
-      return SafeUtil.noop
-    }
-  }
-
-
-  //空函数
-  static noop = () => {
-  };
-
-
-  //停止事件冒泡
-  static stopPropagation(e: any) {
-    if (!e) {
-      return
+    //安全的调用某个函数,函数不存在,创建一个空函数。
+    static safeCallback(callback: any) {
+        if (typeof callback === "function") {
+            return callback
+        } else {
+            return SafeUtil.noop
+        }
     }
 
-    if (e.stopPropagation) {
-      //系统的点击事件
-      e.stopPropagation()
-    } else if (e.domEvent && e.domEvent.stopPropagation) {
-      //antd的事件
-      e.domEvent.stopPropagation()
 
-    }
-  }
+    //空函数
+    static noop = () => {
+    };
 
-  // 停止事件冒泡包装函数
-  static stopPropagationWrap(e: any) {
-    SafeUtil.stopPropagation(e);
-    return (func?: any) => {
-      SafeUtil.safeCallback(func);
+
+    //停止事件冒泡
+    static stopPropagation(e: any) {
+        if (!e) {
+            return
+        }
+
+        if (e.stopPropagation) {
+            //系统的点击事件
+            e.stopPropagation()
+        } else if (e.domEvent && e.domEvent.stopPropagation) {
+            //antd的事件
+            e.domEvent.stopPropagation()
+
+        }
+    }
+
+    // 停止事件冒泡包装函数
+    static stopPropagationWrap(e: any) {
+        SafeUtil.stopPropagation(e);
+        return (func?: any) => {
+            SafeUtil.safeCallback(func);
+        }
     }
-  }
 
 }
diff --git a/src/common/util/StringUtil.ts b/src/common/util/StringUtil.ts
index 2d4bf51..8370c04 100644
--- a/src/common/util/StringUtil.ts
+++ b/src/common/util/StringUtil.ts
@@ -1,275 +1,275 @@
 export default class StringUtil {
 
-  //大写字母
-  static UPPER_CASES = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    //大写字母
+    static UPPER_CASES = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 
-  //下划线转驼峰
-  static underScoreToCamel(str: string) {
+    //下划线转驼峰
+    static underScoreToCamel(str: string) {
 
-    if (!str) {
-      console.error('不能转换空的驼峰字符串。')
-      return str
+        if (!str) {
+            console.error('不能转换空的驼峰字符串。')
+            return str
+        }
+
+        const regex = /_[a-z]/gm;
+
+        return str.replace(regex, function (letter: any, index: any) {
+            return letter.substr(1).toUpperCase()
+        })
     }
 
-    const regex = /_[a-z]/gm;
+    //转换成首字母小写的驼峰法
+    static lowerCamel(str: any) {
 
-    return str.replace(regex, function (letter: any, index: any) {
-      return letter.substr(1).toUpperCase()
-    })
-  }
+        if (!str) {
+            console.error('不能转换空的驼峰字符串。')
+            return str
+        }
 
-  //转换成首字母小写的驼峰法
-  static lowerCamel(str: any) {
-
-    if (!str) {
-      console.error('不能转换空的驼峰字符串。')
-      return str
+        return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function (letter: any, index: any) {
+            return index === 0 ? letter.toLowerCase() : letter.toUpperCase()
+        }).replace(/\s+/g, '')
     }
 
-    return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function (letter: any, index: any) {
-      return index === 0 ? letter.toLowerCase() : letter.toUpperCase()
-    }).replace(/\s+/g, '')
-  }
 
-
-  //转换成全部小写的使用 /分隔的字符串
-  static lowerSlash(str: any) {
-    return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function (letter: any, index: any) {
-      return '/' + letter.toLowerCase()
-    }).replace(/\s+/g, '')
-  }
-
-  //一个字符串包含子字符串
-  static containStr(father: string | null, child: string): boolean {
-
-    if (father === null || father === '') {
-      return false
-    }
-    return father.indexOf(child) !== -1
-  }
-
-  //把一个大小转变成方便读的格式
-  //human readable file size
-  static humanFileSize(bytes: number, si:boolean = false) {
-    let thresh = si ? 1000 : 1024
-    if (Math.abs(bytes) < thresh) {
-      return bytes + ' B'
-    }
-    let units = si
-      ? ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
-      : ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
-    let u = -1
-    do {
-      bytes /= thresh
-      ++u
-    } while (Math.abs(bytes) >= thresh && u < units.length - 1)
-    return bytes.toFixed(1) + ' ' + units[u]
-  }
-
-  //将首字母大写
-  static capitalize(str: any) {
-
-    if (!str) {
-      return str;
+    //转换成全部小写的使用 /分隔的字符串
+    static lowerSlash(str: any) {
+        return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function (letter: any, index: any) {
+            return '/' + letter.toLowerCase()
+        }).replace(/\s+/g, '')
     }
 
-    str = str.replace(/^\w/, (c: any) => c.toUpperCase());
+    //一个字符串包含子字符串
+    static containStr(father: string | null, child: string): boolean {
 
-    return str
-  }
-
-  //将首字母小写
-  static lower(str: any) {
-
-    if (!str) {
-      return str;
+        if (father === null || father === '') {
+            return false
+        }
+        return father.indexOf(child) !== -1
     }
 
-    str = str.replace(/^\w/, (c: any) => c.toLowerCase());
-
-    return str
-  }
-
-  //获取一个function的名字
-  static functionName(func: any) {
-    // Match:
-    // - ^          the beginning of the string
-    // - function   the word 'function'
-    // - \s+        at least some white space
-    // - ([\w\$]+)  capture one or more valid JavaScript identifier characters
-    // - \s*        optionally followed by white space (in theory there won't be any here,
-    //              so if performance is an issue this can be omitted[1]
-    // - \(         followed by an opening brace
-    //
-    let result = /^function\s+([\w\$]+)\s*\(/.exec(func.toString())
-
-    return result ? result[1] : '' // for an anonymous function there won't be a match
-  }
-
-  //check whether an obj is empty
-  static isEmptyObject(obj: any) {
-
-    if (!obj) {
-      return true;
+    //把一个大小转变成方便读的格式
+    //human readable file size
+    static humanFileSize(bytes: number, si: boolean = false) {
+        let thresh = si ? 1000 : 1024
+        if (Math.abs(bytes) < thresh) {
+            return bytes + ' B'
+        }
+        let units = si
+            ? ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
+            : ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
+        let u = -1
+        do {
+            bytes /= thresh
+            ++u
+        } while (Math.abs(bytes) >= thresh && u < units.length - 1)
+        return bytes.toFixed(1) + ' ' + units[u]
     }
 
-    for (let key in obj) {
-      return false;
-    }
-    return true
-  }
+    //将首字母大写
+    static capitalize(str: any) {
 
+        if (!str) {
+            return str;
+        }
 
-  /**
-   * 获取到上num级路径
-   * 例子: /tank/setting/notification -> /tank/setting
-   * @param path 原路径
-   * @param num 上几级,默认1级
-   */
-  static prePath(path: string, num: number = 1): string {
-    if (!path) {
-      return path
-    }
+        str = str.replace(/^\w/, (c: any) => c.toUpperCase());
 
-    //去除掉最后的/符号。
-    let parts: string[] = path.split("/");
-    //去除所有的空
-    parts = parts.filter((item: string, index: number) => {
-      return item !== ""
-    })
-
-    //前面几层就是删掉前面几个元素。如果超出了,会全部删掉。
-    parts.splice(parts.length - num)
-
-    return "/" + parts.join("/")
-  }
-
-
-  static startWith(str: any, prefix: any) {
-    if (typeof prefix === 'undefined' || prefix === null || prefix === '' || typeof str === 'undefined' || str === null || str.length === 0 || prefix.length > str.length) {
-      return false
-    }
-
-    return str.substr(0, prefix.length) === prefix
-  }
-
-  static endWith(str: any, suffix: any) {
-    if (suffix === null || suffix === '' || str === null || str.length === 0 || suffix.length > str.length) {
-      return false
-    }
-
-    return str.substring(str.length - suffix.length) === suffix
-  }
-
-
-  /**
-   * 去除掉开头的前缀
-   * @param str 待处理的字符串
-   * @param prefix 前缀
-   */
-  static trimPrefix(str: string | null, prefix: string): string {
-
-    if (!str) {
-      return ""
-    } else {
-      if (str.substr(0, prefix.length) === prefix) {
-        return str.substr(prefix.length)
-      } else {
         return str
-      }
     }
 
-  }
+    //将首字母小写
+    static lower(str: any) {
 
-  /**
-   * 去除掉后缀
-   * @param str 待处理的字符串
-   * @param suffix 前缀
-   */
-  static trimSuffix(str: string | null, suffix: string): string {
+        if (!str) {
+            return str;
+        }
+
+        str = str.replace(/^\w/, (c: any) => c.toLowerCase());
 
-    if (!str) {
-      return ""
-    } else {
-      if (str.substring(str.length - suffix.length) === suffix) {
-        return str.substr(0, str.length - suffix.length)
-      } else {
         return str
-      }
     }
 
-  }
+    //获取一个function的名字
+    static functionName(func: any) {
+        // Match:
+        // - ^          the beginning of the string
+        // - function   the word 'function'
+        // - \s+        at least some white space
+        // - ([\w\$]+)  capture one or more valid JavaScript identifier characters
+        // - \s*        optionally followed by white space (in theory there won't be any here,
+        //              so if performance is an issue this can be omitted[1]
+        // - \(         followed by an opening brace
+        //
+        let result = /^function\s+([\w\$]+)\s*\(/.exec(func.toString())
 
-
-  //在字符串a后面追加字符串b
-  static append(a: any, b: any, separator = "") {
-
-    if (a === null || a === "" || typeof a !== "string") {
-      return b;
-    } else {
-      return a + separator + b;
-    }
-  }
-
-
-  static isBlank(text: string | null | undefined): boolean {
-
-    if (text === null || text == undefined) {
-      return true
+        return result ? result[1] : '' // for an anonymous function there won't be a match
     }
 
-    return text.trim() === "";
+    //check whether an obj is empty
+    static isEmptyObject(obj: any) {
 
-  }
+        if (!obj) {
+            return true;
+        }
 
-  static isNotBlank(text: string | null | undefined): boolean {
-
-    return !StringUtil.isBlank(text)
-
-  }
-
-
-  //将时间戳转换成62进制
-  static generateUniqueCode(num?: number): string {
-    //获取时间戳
-
-    if (num === undefined) {
-      num = new Date().getTime()
+        for (let key in obj) {
+            return false;
+        }
+        return true
     }
 
-    let standardString = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
-    let result;
-    let list: number[] = [];
-    let len = standardString.length;
-    let level;
-    for (level = 0; Math.floor(num / len) > 0; level++) {
-      result = num % len;
-      list.push(result)
-      num = (num - result) / len
-    }
-    list.push(num);
-    let code = '';
-    list.forEach((item) => {
-      code = standardString[item] + code;
-    })
-    return code
-  }
 
-  //字符串转换成十进制
-  static parseUniqueCode(str: string): number {
+    /**
+     * 获取到上num级路径
+     * 例子: /tank/setting/notification -> /tank/setting
+     * @param path 原路径
+     * @param num 上几级,默认1级
+     */
+    static prePath(path: string, num: number = 1): string {
+        if (!path) {
+            return path
+        }
 
-    let exchangeString = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
-    let strNew = str.split("");
-    let list: number[] = [];
-    strNew.map((item: string) => {
-      list.push(exchangeString.indexOf(item));
-    });
-    let num = 0;
-    for (let i = 0; i < list.length; i++) {
-      num += list[i] * Math.pow(exchangeString.length, list.length - i - 1);
+        //去除掉最后的/符号。
+        let parts: string[] = path.split("/");
+        //去除所有的空
+        parts = parts.filter((item: string, index: number) => {
+            return item !== ""
+        })
+
+        //前面几层就是删掉前面几个元素。如果超出了,会全部删掉。
+        parts.splice(parts.length - num)
+
+        return "/" + parts.join("/")
+    }
+
+
+    static startWith(str: any, prefix: any) {
+        if (typeof prefix === 'undefined' || prefix === null || prefix === '' || typeof str === 'undefined' || str === null || str.length === 0 || prefix.length > str.length) {
+            return false
+        }
+
+        return str.substr(0, prefix.length) === prefix
+    }
+
+    static endWith(str: any, suffix: any) {
+        if (suffix === null || suffix === '' || str === null || str.length === 0 || suffix.length > str.length) {
+            return false
+        }
+
+        return str.substring(str.length - suffix.length) === suffix
+    }
+
+
+    /**
+     * 去除掉开头的前缀
+     * @param str 待处理的字符串
+     * @param prefix 前缀
+     */
+    static trimPrefix(str: string | null, prefix: string): string {
+
+        if (!str) {
+            return ""
+        } else {
+            if (str.substr(0, prefix.length) === prefix) {
+                return str.substr(prefix.length)
+            } else {
+                return str
+            }
+        }
+
+    }
+
+    /**
+     * 去除掉后缀
+     * @param str 待处理的字符串
+     * @param suffix 前缀
+     */
+    static trimSuffix(str: string | null, suffix: string): string {
+
+        if (!str) {
+            return ""
+        } else {
+            if (str.substring(str.length - suffix.length) === suffix) {
+                return str.substr(0, str.length - suffix.length)
+            } else {
+                return str
+            }
+        }
+
+    }
+
+
+    //在字符串a后面追加字符串b
+    static append(a: any, b: any, separator = "") {
+
+        if (a === null || a === "" || typeof a !== "string") {
+            return b;
+        } else {
+            return a + separator + b;
+        }
+    }
+
+
+    static isBlank(text: string | null | undefined): boolean {
+
+        if (text === null || text == undefined) {
+            return true
+        }
+
+        return text.trim() === "";
+
+    }
+
+    static isNotBlank(text: string | null | undefined): boolean {
+
+        return !StringUtil.isBlank(text)
+
+    }
+
+
+    //将时间戳转换成62进制
+    static generateUniqueCode(num?: number): string {
+        //获取时间戳
+
+        if (num === undefined) {
+            num = new Date().getTime()
+        }
+
+        let standardString = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
+        let result;
+        let list: number[] = [];
+        let len = standardString.length;
+        let level;
+        for (level = 0; Math.floor(num / len) > 0; level++) {
+            result = num % len;
+            list.push(result)
+            num = (num - result) / len
+        }
+        list.push(num);
+        let code = '';
+        list.forEach((item) => {
+            code = standardString[item] + code;
+        })
+        return code
+    }
+
+    //字符串转换成十进制
+    static parseUniqueCode(str: string): number {
+
+        let exchangeString = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
+        let strNew = str.split("");
+        let list: number[] = [];
+        strNew.map((item: string) => {
+            list.push(exchangeString.indexOf(item));
+        });
+        let num = 0;
+        for (let i = 0; i < list.length; i++) {
+            num += list[i] * Math.pow(exchangeString.length, list.length - i - 1);
+        }
+        return num;
     }
-    return num;
-  }
 
 
 }
diff --git a/src/index.tsx b/src/index.tsx
index c4fa4d0..dae6a6a 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -7,7 +7,7 @@ import ReactDOM from 'react-dom';
 import App from './App';
 
 ReactDOM.render(
-  ,
-  document.getElementById('root')
+    ,
+    document.getElementById('root')
 );
 
diff --git a/src/pages/Frame.less b/src/pages/Frame.less
index 655a2cd..80ebd64 100644
--- a/src/pages/Frame.less
+++ b/src/pages/Frame.less
@@ -15,10 +15,7 @@
     height: 100%;
 
 
-
   }
 
 
-
-
 }
diff --git a/src/pages/Frame.tsx b/src/pages/Frame.tsx
index 8838171..50f491b 100644
--- a/src/pages/Frame.tsx
+++ b/src/pages/Frame.tsx
@@ -1,10 +1,5 @@
 import React from "react";
-import {
-  Redirect,
-  Route,
-  RouteComponentProps,
-  withRouter,
-} from "react-router-dom";
+import {Redirect, Route, RouteComponentProps, withRouter,} from "react-router-dom";
 
 import "./Frame.less";
 import TankComponent from "../common/component/TankComponent";
@@ -37,159 +32,161 @@ import Moon from "../common/model/global/Moon";
 import Sun from "../common/model/global/Sun";
 import FrameLoading from "./widget/FrameLoading";
 import Preference from "../common/model/preference/Preference";
-import { WebResultCode } from "../common/model/base/WebResultCode";
+import {WebResultCode} from "../common/model/base/WebResultCode";
 import MessageBoxUtil from "../common/util/MessageBoxUtil";
 import BottomLayout from "./layout/BottomLayout";
 import SideLayout from "./layout/SideLayout";
 import TopLayout from "./layout/TopLayout";
 import ContentLayout from "./layout/ContentLayout";
 
-interface IProps extends RouteComponentProps<{}> {}
+interface IProps extends RouteComponentProps<{}> {
+}
 
-interface IState {}
+interface IState {
+}
 
 class RawFrame extends TankComponent {
-  user: User = Moon.getSingleton().user;
+    user: User = Moon.getSingleton().user;
 
-  preference: Preference = Moon.getSingleton().preference;
+    preference: Preference = Moon.getSingleton().preference;
 
-  //是否已经完成初始化
-  initialized: boolean = false;
+    //是否已经完成初始化
+    initialized: boolean = false;
 
-  constructor(props: IProps) {
-    super(props);
-  }
-
-  componentDidMount() {
-    //装载全局的路由
-    Sun.getSingleton().reactRouter = this.props.history;
-    //装在全局Frame
-    Sun.getSingleton().frameComponent = this;
-
-    this.initialize();
-  }
-
-  //获取当前登录者的信息
-  initialize() {
-    let that = this;
-    let pathname: string = that.props.location.pathname;
-
-    this.preference.httpFetch(
-      function () {
-        // 白名单,不要求登录
-        let whitePaths = [
-          "/user/login",
-          "/user/register",
-          "/user/authentication",
-        ];
-        // 尝试登录名单,登录失败不做处理
-        let tryLoginPaths = [
-          "/share/detail",
-        ];
-
-        if(whitePaths.findIndex((path) => pathname.startsWith(path)) >= 0){
-          that.initialized = true;
-          that.updateUI();
-        } else if(tryLoginPaths.findIndex((path) => pathname.startsWith(path)) >= 0) {
-          that.user.httpInfo(false, function () {
-            that.initialized = true;
-            that.updateUI();
-          });
-        } else {
-          that.user.httpInfo(true, function () {
-            that.initialized = true;
-            that.updateUI();
-          });
-        }
-      },
-      function (errMessage: string, response: any) {
-        that.initialized = true;
-        that.updateUI();
-        if (
-          response &&
-          response.data &&
-          response.data["code"] === WebResultCode.NOT_INSTALLED
-        ) {
-          MessageBoxUtil.warning("网站尚未安装,即将引导进入安装页面!");
-          that.preference.installed = false;
-          Sun.navigateTo("/install/index");
-        }
-      }
-    );
-  }
-
-  render() {
-    let content: React.ReactNode;
-
-    if (this.initialized) {
-      content = (
-        
- - - - - - {this.preference.installed ? ( -
- } - /> - - - - - - - - - - - - - - - - - - } - /> - - - - - - -
- ) : ( -
- -
- )} -
- - -
- ); - } else { - content = ; + constructor(props: IProps) { + super(props); } - return
{content}
; - } + componentDidMount() { + //装载全局的路由 + Sun.getSingleton().reactRouter = this.props.history; + //装在全局Frame + Sun.getSingleton().frameComponent = this; + + this.initialize(); + } + + //获取当前登录者的信息 + initialize() { + let that = this; + let pathname: string = that.props.location.pathname; + + this.preference.httpFetch( + function () { + // 白名单,不要求登录 + let whitePaths = [ + "/user/login", + "/user/register", + "/user/authentication", + ]; + // 尝试登录名单,登录失败不做处理 + let tryLoginPaths = [ + "/share/detail", + ]; + + if (whitePaths.findIndex((path) => pathname.startsWith(path)) >= 0) { + that.initialized = true; + that.updateUI(); + } else if (tryLoginPaths.findIndex((path) => pathname.startsWith(path)) >= 0) { + that.user.httpInfo(false, function () { + that.initialized = true; + that.updateUI(); + }); + } else { + that.user.httpInfo(true, function () { + that.initialized = true; + that.updateUI(); + }); + } + }, + function (errMessage: string, response: any) { + that.initialized = true; + that.updateUI(); + if ( + response && + response.data && + response.data["code"] === WebResultCode.NOT_INSTALLED + ) { + MessageBoxUtil.warning("网站尚未安装,即将引导进入安装页面!"); + that.preference.installed = false; + Sun.navigateTo("/install/index"); + } + } + ); + } + + render() { + let content: React.ReactNode; + + if (this.initialized) { + content = ( +
+ + + + + + {this.preference.installed ? ( +
+ } + /> + + + + + + + + + + + + + + + + + + } + /> + + + + + + +
+ ) : ( +
+ +
+ )} +
+ + +
+ ); + } else { + content = ; + } + + return
{content}
; + } } const Frame = withRouter>(RawFrame); diff --git a/src/pages/bin/List.tsx b/src/pages/bin/List.tsx index 7b3a947..9ffe059 100644 --- a/src/pages/bin/List.tsx +++ b/src/pages/bin/List.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { RouteComponentProps } from "react-router-dom"; +import {RouteComponentProps} from "react-router-dom"; import "./List.less"; import TankComponent from "../../common/component/TankComponent"; import Pager from "../../common/model/base/Pager"; @@ -7,277 +7,279 @@ import Matter from "../../common/model/matter/Matter"; import Moon from "../../common/model/global/Moon"; import SortDirection from "../../common/model/base/SortDirection"; import MatterPanel from "../matter/widget/MatterPanel"; -import { Button, Col, Empty, Input, Modal, Pagination, Row, Space } from "antd"; +import {Button, Col, Empty, Input, Modal, Pagination, Row, Space} from "antd"; import MessageBoxUtil from "../../common/util/MessageBoxUtil"; import { - ExclamationCircleFilled, - PlusSquareOutlined, - MinusSquareOutlined, - SyncOutlined, - RedoOutlined, - CloseCircleOutlined, + CloseCircleOutlined, + ExclamationCircleFilled, + MinusSquareOutlined, + PlusSquareOutlined, + RedoOutlined, + SyncOutlined, } from "@ant-design/icons"; import ImagePreviewer from "../widget/previewer/ImagePreviewer"; -import { UserRole } from "../../common/model/user/UserRole"; +import {UserRole} from "../../common/model/user/UserRole"; import Lang from "../../common/model/global/Lang"; import TankTitle from "../widget/TankTitle"; -interface IProps extends RouteComponentProps {} +interface IProps extends RouteComponentProps { +} -interface IState {} +interface IState { +} export default class List extends TankComponent { - //当前文件夹信息。 - matter = new Matter(); - //当前选中的文件 - selectedMatters: Matter[] = []; - //获取分页的一个帮助器 - pager = new Pager(this, Matter, Pager.MAX_PAGE_SIZE); - user = Moon.getSingleton().user; - preference = Moon.getSingleton().preference; + //当前文件夹信息。 + matter = new Matter(); + //当前选中的文件 + selectedMatters: Matter[] = []; + //获取分页的一个帮助器 + pager = new Pager(this, Matter, Pager.MAX_PAGE_SIZE); + user = Moon.getSingleton().user; + preference = Moon.getSingleton().preference; - constructor(props: IProps) { - super(props); - } - - componentDidMount() { - //刷新一下列表 - if (this.user.role === UserRole.ADMINISTRATOR) { - this.pager.getFilter("userUuid")!.visible = true; - } else { - this.pager.setFilterValue("userUuid", this.user.uuid); - } - this.pager.enableHistory(); - this.refresh(); - } - - componentWillReceiveProps(nextProps: Readonly, nextContext: any) { - if (this.props.location.search !== nextProps.location.search) { - this.pager.enableHistory(); - this.refresh(); - } - } - - refresh() { - // 清空暂存区 - this.selectedMatters = []; - // 刷新文件列表 - this.refreshPager(); - } - - refreshPager() { - //如果没有任何的排序,默认使用时间倒序和文件夹在顶部 - if (!this.pager.getCurrentSortFilter()) { - this.pager.setFilterValue("orderDeleteTime", SortDirection.DESC); - this.pager.setFilterValue("orderDir", SortDirection.DESC); + constructor(props: IProps) { + super(props); } - // 过滤掉被软删除的文件 - this.pager.setFilterValue("deleted", true); + componentDidMount() { + //刷新一下列表 + if (this.user.role === UserRole.ADMINISTRATOR) { + this.pager.getFilter("userUuid")!.visible = true; + } else { + this.pager.setFilterValue("userUuid", this.user.uuid); + } + this.pager.enableHistory(); + this.refresh(); + } - this.pager.httpList(); - } + componentWillReceiveProps(nextProps: Readonly, nextContext: any) { + if (this.props.location.search !== nextProps.location.search) { + this.pager.enableHistory(); + this.refresh(); + } + } - checkMatter(matter?: Matter) { - if (matter) { - if (matter.check) { - this.selectedMatters.push(matter); - } else { - const index = this.selectedMatters.findIndex( - (item) => item.uuid === matter.uuid + refresh() { + // 清空暂存区 + this.selectedMatters = []; + // 刷新文件列表 + this.refreshPager(); + } + + refreshPager() { + //如果没有任何的排序,默认使用时间倒序和文件夹在顶部 + if (!this.pager.getCurrentSortFilter()) { + this.pager.setFilterValue("orderDeleteTime", SortDirection.DESC); + this.pager.setFilterValue("orderDir", SortDirection.DESC); + } + + // 过滤掉被软删除的文件 + this.pager.setFilterValue("deleted", true); + + this.pager.httpList(); + } + + checkMatter(matter?: Matter) { + if (matter) { + if (matter.check) { + this.selectedMatters.push(matter); + } else { + const index = this.selectedMatters.findIndex( + (item) => item.uuid === matter.uuid + ); + this.selectedMatters.splice(index, 1); + } + } else { + //统计所有的勾选 + this.selectedMatters = []; + this.pager.data.forEach((matter) => { + if (matter.check) { + this.selectedMatters.push(matter); + } + }); + } + this.updateUI(); + } + + checkAll() { + this.pager.data.forEach((i) => { + i.check = true; + }); + this.checkMatter(); + } + + checkNone() { + this.pager.data.forEach((i) => { + i.check = false; + }); + this.checkMatter(); + } + + deleteBatch() { + Modal.confirm({ + title: Lang.t("actionCanNotRevertConfirm"), + icon: , + onOk: () => { + const uuids = this.selectedMatters.map((i) => i.uuid).toString(); + this.matter.httpDeleteBatch(uuids, () => { + MessageBoxUtil.success(Lang.t("operationSuccess")); + this.refresh(); + }); + }, + }); + } + + recoverBatch() { + Modal.confirm({ + title: Lang.t("actionRecoveryConfirm"), + icon: , + onOk: () => { + const uuids = this.selectedMatters.map((i) => i.uuid).toString(); + this.matter.httpRecoveryBatch(uuids, () => { + MessageBoxUtil.success(Lang.t("operationSuccess")); + this.refresh(); + }); + }, + }); + } + + searchFile(value?: string) { + this.pager.resetFilter(); + if (value) { + this.pager.setFilterValue("orderCreateTime", SortDirection.DESC); + this.pager.setFilterValue("orderDir", SortDirection.DESC); + this.pager.setFilterValue("name", value); + this.pager.setFilterValue("deleted", true); + this.pager.httpList(); + } else { + this.refresh(); + } + } + + changeSearch(e: any) { + if (!e.currentTarget.value) this.searchFile(); + } + + changePage(page: number) { + this.pager.page = page - 1; // page的页数0基 + this.pager.httpList(); + this.updateUI(); + } + + previewImage(matter: Matter) { + let imageArray: string[] = []; + let startIndex = -1; + this.pager.data.forEach((item) => { + if (item.isImage()) { + imageArray.push(item.getPreviewUrl()); + if (item.uuid === matter.uuid) { + startIndex = imageArray.length - 1; + } + } + }); + + ImagePreviewer.showMultiPhoto(imageArray, startIndex); + } + + render() { + const {pager, selectedMatters} = this; + return ( +
+ + + + + + {selectedMatters.length !== pager.data.length ? ( + + ) : null} + {pager.data.length && + selectedMatters.length === pager.data.length ? ( + + ) : null} + {selectedMatters.length ? ( + <> + + + + ) : null} + + + + + + this.searchFile(value)} + onChange={(e) => this.changeSearch(e)} + enterButton + /> + + + +
+ {pager.loading || pager.data.length ? ( + pager.data.map((matter) => ( + this.refresh()} + onRecoverySuccess={() => this.refresh()} + onCheckMatter={(m) => this.checkMatter(m)} + onPreviewImage={(m) => this.previewImage(m)} + /> + )) + ) : ( + + )} +
+ this.changePage(page)} + current={pager.page + 1} + total={pager.totalItems} + pageSize={pager.pageSize} + hideOnSinglePage + /> +
); - this.selectedMatters.splice(index, 1); - } - } else { - //统计所有的勾选 - this.selectedMatters = []; - this.pager.data.forEach((matter) => { - if (matter.check) { - this.selectedMatters.push(matter); - } - }); } - this.updateUI(); - } - - checkAll() { - this.pager.data.forEach((i) => { - i.check = true; - }); - this.checkMatter(); - } - - checkNone() { - this.pager.data.forEach((i) => { - i.check = false; - }); - this.checkMatter(); - } - - deleteBatch() { - Modal.confirm({ - title: Lang.t("actionCanNotRevertConfirm"), - icon: , - onOk: () => { - const uuids = this.selectedMatters.map((i) => i.uuid).toString(); - this.matter.httpDeleteBatch(uuids, () => { - MessageBoxUtil.success(Lang.t("operationSuccess")); - this.refresh(); - }); - }, - }); - } - - recoverBatch() { - Modal.confirm({ - title: Lang.t("actionRecoveryConfirm"), - icon: , - onOk: () => { - const uuids = this.selectedMatters.map((i) => i.uuid).toString(); - this.matter.httpRecoveryBatch(uuids, () => { - MessageBoxUtil.success(Lang.t("operationSuccess")); - this.refresh(); - }); - }, - }); - } - - searchFile(value?: string) { - this.pager.resetFilter(); - if (value) { - this.pager.setFilterValue("orderCreateTime", SortDirection.DESC); - this.pager.setFilterValue("orderDir", SortDirection.DESC); - this.pager.setFilterValue("name", value); - this.pager.setFilterValue("deleted", true); - this.pager.httpList(); - } else { - this.refresh(); - } - } - - changeSearch(e: any) { - if (!e.currentTarget.value) this.searchFile(); - } - - changePage(page: number) { - this.pager.page = page - 1; // page的页数0基 - this.pager.httpList(); - this.updateUI(); - } - - previewImage(matter: Matter) { - let imageArray: string[] = []; - let startIndex = -1; - this.pager.data.forEach((item) => { - if (item.isImage()) { - imageArray.push(item.getPreviewUrl()); - if (item.uuid === matter.uuid) { - startIndex = imageArray.length - 1; - } - } - }); - - ImagePreviewer.showMultiPhoto(imageArray, startIndex); - } - - render() { - const { pager, selectedMatters } = this; - return ( -
- - - - - - {selectedMatters.length !== pager.data.length ? ( - - ) : null} - {pager.data.length && - selectedMatters.length === pager.data.length ? ( - - ) : null} - {selectedMatters.length ? ( - <> - - - - ) : null} - - - - - - this.searchFile(value)} - onChange={(e) => this.changeSearch(e)} - enterButton - /> - - - -
- {pager.loading || pager.data.length ? ( - pager.data.map((matter) => ( - this.refresh()} - onRecoverySuccess={() => this.refresh()} - onCheckMatter={(m) => this.checkMatter(m)} - onPreviewImage={(m) => this.previewImage(m)} - /> - )) - ) : ( - - )} -
- this.changePage(page)} - current={pager.page + 1} - total={pager.totalItems} - pageSize={pager.pageSize} - hideOnSinglePage - /> -
- ); - } } diff --git a/src/pages/dashboard/Index.tsx b/src/pages/dashboard/Index.tsx index 2db76f4..3802af2 100644 --- a/src/pages/dashboard/Index.tsx +++ b/src/pages/dashboard/Index.tsx @@ -28,431 +28,438 @@ interface IState { } interface IpStruct { - ip: string - times: number + ip: string + times: number } export default class Index extends TankComponent { - //获取分页的一个帮助器 - pager: Pager = new Pager(this, Dashboard, 15); + //获取分页的一个帮助器 + pager: Pager = new Pager(this, Dashboard, 15); - //今天的统计情况 - dashboard: Dashboard = new Dashboard(this) - yesterdayDashboard: Dashboard = new Dashboard(this) + //今天的统计情况 + dashboard: Dashboard = new Dashboard(this) + yesterdayDashboard: Dashboard = new Dashboard(this) - matterPager: Pager = new Pager(this, Matter, 10); + matterPager: Pager = new Pager(this, Matter, 10); - activeIpTop10: IpStruct[] = [] + activeIpTop10: IpStruct[] = [] - //****************作图需要的对象******************/ - days: number = 15 - //用来存放日期的,辅助x轴的生成 - dateStrings: string[] = [] + //****************作图需要的对象******************/ + days: number = 15 + //用来存放日期的,辅助x轴的生成 + dateStrings: string[] = [] - //调用量周环比 - standardWeekInvokeNum: number = 0 - compareWeekInvokeNum: number = 0 - //调用量日环比 - standardDayInvokeNum: number = 0 - compareDayInvokeNum: number = 0 - //UV周环比 - standardWeekUv: number = 0 - compareWeekUv: number = 0 - //UV日环比 - standardDayUv: number = 0 - compareDayUv: number = 0 - //文件总数周环比 - standardWeekMatterNum: number = 0 - compareWeekMatterNum: number = 0 - //文件总数日环比 - standardDayMatterNum: number = 0 - compareDayMatterNum: number = 0 - //文件大小周环比 - standardWeekSize: number = 0 - compareWeekSize: number = 0 - //文件大小日环比 - standardDaySize: number = 0 - compareDaySize: number = 0 + //调用量周环比 + standardWeekInvokeNum: number = 0 + compareWeekInvokeNum: number = 0 + //调用量日环比 + standardDayInvokeNum: number = 0 + compareDayInvokeNum: number = 0 + //UV周环比 + standardWeekUv: number = 0 + compareWeekUv: number = 0 + //UV日环比 + standardDayUv: number = 0 + compareDayUv: number = 0 + //文件总数周环比 + standardWeekMatterNum: number = 0 + compareWeekMatterNum: number = 0 + //文件总数日环比 + standardDayMatterNum: number = 0 + compareDayMatterNum: number = 0 + //文件大小周环比 + standardWeekSize: number = 0 + compareWeekSize: number = 0 + //文件大小日环比 + standardDaySize: number = 0 + compareDaySize: number = 0 - invokeListOption: any = { - tooltip: {}, - legend: { - data: ['PV', 'UV'] - }, - xAxis: { - name: Lang.t("assign.date"), - data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] - }, - yAxis: { - name: Lang.t("assign.num") - }, - series: [{ - name: 'PV', - type: 'bar', - data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - }, { - name: 'UV', - type: 'line', - data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - }] - }; + invokeListOption: any = { + tooltip: {}, + legend: { + data: ['PV', 'UV'] + }, + xAxis: { + name: Lang.t("assign.date"), + data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + }, + yAxis: { + name: Lang.t("assign.num") + }, + series: [{ + name: 'PV', + type: 'bar', + data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + }, { + name: 'UV', + type: 'line', + data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + }] + }; - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; + this.state = {}; - } - - componentDidMount() { - - this.refresh() - - } - - refresh() { - - this.updateDateStrings() - this.refreshDashboardPager() - this.refreshMatterPager() - this.refreshActiveIpTop10() - } - - updateDateStrings() { - let that = this; - //更新横坐标 从今天开始倒推 - let arr = [] - for (let d = that.days - 1; d >= 0; d--) { - let thenDate = new Date((new Date()).getTime() - d * 24 * 60 * 60 * 1000) - arr.push(DateUtil.simpleDate(thenDate)) } - that.dateStrings = arr - } - //获取15日调用分时数据 - refreshDashboardPager() { - let that = this; + componentDidMount() { - this.pager.setFilterValue("orderDt", SortDirection.DESC) + this.refresh() - this.pager.httpList(function (response: any) { + } - let list = that.pager.data + refresh() { - if (list.length > 0) { - that.dashboard.assign(list[0]) - } - - if (list.length > 1) { - that.yesterdayDashboard.assign(list[1]) - } - - //数据转换成map,方便检索 - let map: { [key: string]: Dashboard } = {} - for (let i = 0; i < list.length; i++) { - map[list[i].dt] = list[i] - } - - let invokeNumData = [] - let uvData = [] - let matterNumData = [] - let fileSizeData = [] - for (let i = 0; i < that.days; i++) { - invokeNumData.push(0) - uvData.push(0) - matterNumData.push(0) - fileSizeData.push(0) - } - - //按照日期对应。 - for (let i = 0; i < that.dateStrings.length; i++) { - let item = map[that.dateStrings[i]]; - if (item) { - invokeNumData[i] = item.invokeNum - uvData[i] = item.uv - matterNumData[i] = item.matterNum - fileSizeData[i] = item.fileSize + this.updateDateStrings() + this.refreshDashboardPager() + this.refreshMatterPager() + this.refreshActiveIpTop10() + } + updateDateStrings() { + let that = this; + //更新横坐标 从今天开始倒推 + let arr = [] + for (let d = that.days - 1; d >= 0; d--) { + let thenDate = new Date((new Date()).getTime() - d * 24 * 60 * 60 * 1000) + arr.push(DateUtil.simpleDate(thenDate)) } - } + that.dateStrings = arr + } - //同环比 - that.standardWeekInvokeNum = 0 - that.compareWeekInvokeNum = 0 - //调用量日环比 - that.standardDayInvokeNum = 0 - that.compareDayInvokeNum = 0 - //UV周环比 - that.standardWeekUv = 0 - that.compareWeekUv = 0 - //UV日环比 - that.standardDayUv = 0 - that.compareDayUv = 0 + //获取15日调用分时数据 + refreshDashboardPager() { + let that = this; - //文件总数周环比 - that.standardWeekMatterNum = 0 - that.compareWeekMatterNum = 0 - //文件总数日环比 - that.standardDayMatterNum = 0 - that.compareDayMatterNum = 0 - //文件大小周环比 - that.standardWeekSize = 0 - that.compareWeekSize = 0 - //文件大小日环比 - that.standardDaySize = 0 - that.compareDaySize = 0 + this.pager.setFilterValue("orderDt", SortDirection.DESC) - for (let i = 0; i < that.days; i++) { - if (i >= 0 && i <= 6) { - that.standardWeekInvokeNum += invokeNumData[i] - that.standardWeekUv += uvData[i] - that.standardWeekMatterNum += matterNumData[i] - that.standardWeekSize += fileSizeData[i] + this.pager.httpList(function (response: any) { - } else if (i >= 7 && i <= 13) { - that.compareWeekInvokeNum += invokeNumData[i] - that.compareWeekUv += uvData[i] - that.compareWeekMatterNum += matterNumData[i] - that.compareWeekSize += fileSizeData[i] - } - if (i === 12) { - that.standardDayInvokeNum = invokeNumData[i] - that.standardDayUv = uvData[i] - that.standardDayMatterNum = matterNumData[i] - that.standardDaySize = fileSizeData[i] + let list = that.pager.data - } - if (i === 13) { - that.compareDayInvokeNum = invokeNumData[i] - that.compareDayUv = uvData[i] - that.compareDayMatterNum = matterNumData[i] - that.compareDaySize = fileSizeData[i] - } - } + if (list.length > 0) { + that.dashboard.assign(list[0]) + } + + if (list.length > 1) { + that.yesterdayDashboard.assign(list[1]) + } + + //数据转换成map,方便检索 + let map: { [key: string]: Dashboard } = {} + for (let i = 0; i < list.length; i++) { + map[list[i].dt] = list[i] + } + + let invokeNumData = [] + let uvData = [] + let matterNumData = [] + let fileSizeData = [] + for (let i = 0; i < that.days; i++) { + invokeNumData.push(0) + uvData.push(0) + matterNumData.push(0) + fileSizeData.push(0) + } + + //按照日期对应。 + for (let i = 0; i < that.dateStrings.length; i++) { + let item = map[that.dateStrings[i]]; + if (item) { + invokeNumData[i] = item.invokeNum + uvData[i] = item.uv + matterNumData[i] = item.matterNum + fileSizeData[i] = item.fileSize + + } + } + + //同环比 + that.standardWeekInvokeNum = 0 + that.compareWeekInvokeNum = 0 + //调用量日环比 + that.standardDayInvokeNum = 0 + that.compareDayInvokeNum = 0 + //UV周环比 + that.standardWeekUv = 0 + that.compareWeekUv = 0 + //UV日环比 + that.standardDayUv = 0 + that.compareDayUv = 0 + + //文件总数周环比 + that.standardWeekMatterNum = 0 + that.compareWeekMatterNum = 0 + //文件总数日环比 + that.standardDayMatterNum = 0 + that.compareDayMatterNum = 0 + //文件大小周环比 + that.standardWeekSize = 0 + that.compareWeekSize = 0 + //文件大小日环比 + that.standardDaySize = 0 + that.compareDaySize = 0 + + for (let i = 0; i < that.days; i++) { + if (i >= 0 && i <= 6) { + that.standardWeekInvokeNum += invokeNumData[i] + that.standardWeekUv += uvData[i] + that.standardWeekMatterNum += matterNumData[i] + that.standardWeekSize += fileSizeData[i] + + } else if (i >= 7 && i <= 13) { + that.compareWeekInvokeNum += invokeNumData[i] + that.compareWeekUv += uvData[i] + that.compareWeekMatterNum += matterNumData[i] + that.compareWeekSize += fileSizeData[i] + } + if (i === 12) { + that.standardDayInvokeNum = invokeNumData[i] + that.standardDayUv = uvData[i] + that.standardDayMatterNum = matterNumData[i] + that.standardDaySize = fileSizeData[i] + + } + if (i === 13) { + that.compareDayInvokeNum = invokeNumData[i] + that.compareDayUv = uvData[i] + that.compareDayMatterNum = matterNumData[i] + that.compareDaySize = fileSizeData[i] + } + } - that.invokeListOption.xAxis.data = that.dateStrings.map((k) => k.substr(5)) - that.invokeListOption.series[0].data = invokeNumData - that.invokeListOption.series[1].data = uvData + that.invokeListOption.xAxis.data = that.dateStrings.map((k) => k.substr(5)) + that.invokeListOption.series[0].data = invokeNumData + that.invokeListOption.series[1].data = uvData - that.updateUI() - }) + that.updateUI() + }) - } + } - //获取下载前10的文件 - refreshMatterPager() { - let that = this; - that.matterPager.setFilterValue("orderTimes", SortDirection.DESC) - that.matterPager.httpList() - } + //获取下载前10的文件 + refreshMatterPager() { + let that = this; + that.matterPager.setFilterValue("orderTimes", SortDirection.DESC) + that.matterPager.httpList() + } - refreshActiveIpTop10() { - let that = this - that.dashboard.httpActiveIpTop10(function (data: any) { - if (data) { - that.activeIpTop10 = data - } - that.updateUI() - }) - } + refreshActiveIpTop10() { + let that = this + that.dashboard.httpActiveIpTop10(function (data: any) { + if (data) { + that.activeIpTop10 = data + } + that.updateUI() + }) + } - reRun() { - let that = this - that.dashboard.httpEtl(function (data: any) { + reRun() { + let that = this + that.dashboard.httpEtl(function (data: any) { - MessageBoxUtil.success(Lang.t("operationSuccess")) + MessageBoxUtil.success(Lang.t("operationSuccess")) - that.refresh() - }) - } + that.refresh() + }) + } - onChartReady() { + onChartReady() { - } + } - render() { + render() { - let that = this + let that = this - let dashboard: Dashboard = this.dashboard - let yesterdayDashboard: Dashboard = this.yesterdayDashboard + let dashboard: Dashboard = this.dashboard + let yesterdayDashboard: Dashboard = this.yesterdayDashboard - return ( -
+ return ( +
- - + + + + + +
+
+
{Lang.t("dashboard.totalInvokeNum")}
+
{dashboard.totalInvokeNum}
+
+ + +
+
+
+ {Lang.t("dashboard.yesterdayInvoke")}:{yesterdayDashboard.invokeNum} +
+
+ + + +
+
+
{Lang.t("dashboard.totalUV")}
+
{dashboard.totalUv}
+
+ + +
+
+
+ {Lang.t("dashboard.yesterdayUV")}:{yesterdayDashboard.uv} +
+
+ + + + +
+
+
{Lang.t("dashboard.totalMatterNum")}
+
{dashboard.totalMatterNum}
+
+ + +
+
+
+ {Lang.t("dashboard.yesterdayMatterNum")}:{yesterdayDashboard.matterNum} +
+
+ + + +
+
+
{Lang.t("dashboard.totalFileSize")}
+
{FileUtil.humanFileSize(dashboard.totalFileSize)}
+
+ + +
+
+
+ {Lang.t("dashboard.yesterdayMatterSize")}:{FileUtil.humanFileSize(yesterdayDashboard.fileSize)} +
+
+ +
+ + + + +
+
+ {Lang.t("dashboard.recentDayInvokeUV", 15)} +
+
+ +
+
+ + + +
+ + + + +
+
+ {Lang.t("dashboard.downloadMatterTop10")} +
+
+
    + { + this.matterPager.data.map((matter: Matter, index: number) => { + return ( +
  • + {index + 1} + {matter.name} + {matter.times} +
  • + ) + }) + } +
+
+
+ + + + + + + +
+
+ {Lang.t("dashboard.activeIpTop10")} +
+
+
    + { + this.activeIpTop10.map((item: IpStruct, index: number) => { + return ( +
  • + {index + 1} + {item.ip} + {item.times} +
  • + ) + }) + } +
+
+
+ + + +
- - -
-
-
{Lang.t("dashboard.totalInvokeNum")}
-
{dashboard.totalInvokeNum}
- - -
-
-
- {Lang.t("dashboard.yesterdayInvoke")}:{yesterdayDashboard.invokeNum} -
-
- - - -
-
-
{Lang.t("dashboard.totalUV")}
-
{dashboard.totalUv}
-
- - -
-
-
- {Lang.t("dashboard.yesterdayUV")}:{yesterdayDashboard.uv} -
-
- - - - -
-
-
{Lang.t("dashboard.totalMatterNum")}
-
{dashboard.totalMatterNum}
-
- - -
-
-
- {Lang.t("dashboard.yesterdayMatterNum")}:{yesterdayDashboard.matterNum} -
-
- - - -
-
-
{Lang.t("dashboard.totalFileSize")}
-
{FileUtil.humanFileSize(dashboard.totalFileSize)}
-
- - -
-
-
- {Lang.t("dashboard.yesterdayMatterSize")}:{FileUtil.humanFileSize(yesterdayDashboard.fileSize)} -
-
- -
- - - - -
-
- {Lang.t("dashboard.recentDayInvokeUV", 15)} -
-
- -
-
- - - -
- - - - -
-
- {Lang.t("dashboard.downloadMatterTop10")} -
-
-
    - { - this.matterPager.data.map((matter: Matter, index: number) => { - return ( -
  • - {index + 1} - {matter.name} - {matter.times} -
  • - ) - }) - } -
-
-
- - - - - - - -
-
- {Lang.t("dashboard.activeIpTop10")} -
-
-
    - { - this.activeIpTop10.map((item: IpStruct, index: number) => { - return ( -
  • - {index + 1} - {item.ip} - {item.times} -
  • - ) - }) - } -
-
-
- - - -
- -
- + {Lang.t("dashboard.warnHint")} - {Lang.t("dashboard.reRun")} + {Lang.t("dashboard.reRun")} } - type="warning" - /> -
+ type="warning" + /> +
-
- ); - } + + ); + } } diff --git a/src/pages/dashboard/theme.json b/src/pages/dashboard/theme.json index 15e1966..03d097d 100644 --- a/src/pages/dashboard/theme.json +++ b/src/pages/dashboard/theme.json @@ -1,474 +1,474 @@ { - "color": [ - "#215891", - "#67C23A", - "#7bd9a5" - ], - "backgroundColor": "rgba(0,0,0,0)", - "textStyle": {}, - "title": { - "textStyle": { - "color": "#666666" - }, - "subtextStyle": { - "color": "#999999" - } + "color": [ + "#215891", + "#67C23A", + "#7bd9a5" + ], + "backgroundColor": "rgba(0,0,0,0)", + "textStyle": {}, + "title": { + "textStyle": { + "color": "#666666" }, - "line": { - "itemStyle": { - "normal": { - "borderWidth": "2" - } - }, - "lineStyle": { - "normal": { - "width": "3" - } - }, - "symbolSize": "10", - "symbol": "emptyCircle", - "smooth": true - }, - "radar": { - "itemStyle": { - "normal": { - "borderWidth": "2" - } - }, - "lineStyle": { - "normal": { - "width": "3" - } - }, - "symbolSize": "10", - "symbol": "emptyCircle", - "smooth": true - }, - "bar": { - "itemStyle": { - "normal": { - "barBorderWidth": "0", - "barBorderColor": "#444444" - }, - "emphasis": { - "barBorderWidth": "0", - "barBorderColor": "#444444" - } - } - }, - "pie": { - "itemStyle": { - "normal": { - "borderWidth": "0", - "borderColor": "#444444" - }, - "emphasis": { - "borderWidth": "0", - "borderColor": "#444444" - } - } - }, - "scatter": { - "itemStyle": { - "normal": { - "borderWidth": "0", - "borderColor": "#444444" - }, - "emphasis": { - "borderWidth": "0", - "borderColor": "#444444" - } - } - }, - "boxplot": { - "itemStyle": { - "normal": { - "borderWidth": "0", - "borderColor": "#444444" - }, - "emphasis": { - "borderWidth": "0", - "borderColor": "#444444" - } - } - }, - "parallel": { - "itemStyle": { - "normal": { - "borderWidth": "0", - "borderColor": "#444444" - }, - "emphasis": { - "borderWidth": "0", - "borderColor": "#444444" - } - } - }, - "sankey": { - "itemStyle": { - "normal": { - "borderWidth": "0", - "borderColor": "#444444" - }, - "emphasis": { - "borderWidth": "0", - "borderColor": "#444444" - } - } - }, - "funnel": { - "itemStyle": { - "normal": { - "borderWidth": "0", - "borderColor": "#444444" - }, - "emphasis": { - "borderWidth": "0", - "borderColor": "#444444" - } - } - }, - "gauge": { - "itemStyle": { - "normal": { - "borderWidth": "0", - "borderColor": "#444444" - }, - "emphasis": { - "borderWidth": "0", - "borderColor": "#444444" - } - } - }, - "candlestick": { - "itemStyle": { - "normal": { - "color": "#d0648a", - "color0": "#ffffff", - "borderColor": "#d0648a", - "borderColor0": "#22c3aa", - "borderWidth": 1 - } - } - }, - "graph": { - "itemStyle": { - "normal": { - "borderWidth": "0", - "borderColor": "#444444" - } - }, - "lineStyle": { - "normal": { - "width": 1, - "color": "#aaa" - } - }, - "symbolSize": "10", - "symbol": "emptyCircle", - "smooth": true, - "color": [ - "#4ea397", - "#22c3aa", - "#7bd9a5" - ], - "label": { - "normal": { - "textStyle": { - "color": "#ffffff" - } - } - } - }, - "map": { - "itemStyle": { - "normal": { - "areaColor": "#eeeeee", - "borderColor": "#999999", - "borderWidth": "0.5" - }, - "emphasis": { - "areaColor": "rgba(34,195,170,0.25)", - "borderColor": "#22c3aa", - "borderWidth": "0.5" - } - }, - "label": { - "normal": { - "textStyle": { - "color": "#28544e" - } - }, - "emphasis": { - "textStyle": { - "color": "rgb(52,158,142)" - } - } - } - }, - "geo": { - "itemStyle": { - "normal": { - "areaColor": "#eeeeee", - "borderColor": "#999999", - "borderWidth": "0.5" - }, - "emphasis": { - "areaColor": "rgba(34,195,170,0.25)", - "borderColor": "#22c3aa", - "borderWidth": "0.5" - } - }, - "label": { - "normal": { - "textStyle": { - "color": "#28544e" - } - }, - "emphasis": { - "textStyle": { - "color": "rgb(52,158,142)" - } - } - } - }, - "categoryAxis": { - "axisLine": { - "show": true, - "lineStyle": { - "color": "#cccccc" - } - }, - "axisTick": { - "show": false, - "lineStyle": { - "color": "#333333" - } - }, - "axisLabel": { - "show": true, - "textStyle": { - "color": "#999999" - } - }, - "splitLine": { - "show": true, - "lineStyle": { - "color": [ - "#eeeeee" - ] - } - }, - "splitArea": { - "show": false, - "areaStyle": { - "color": [ - "rgba(250,250,250,0.3)", - "rgba(200,200,200,0.3)" - ] - } - } - }, - "valueAxis": { - "axisLine": { - "show": true, - "lineStyle": { - "color": "#cccccc" - } - }, - "axisTick": { - "show": false, - "lineStyle": { - "color": "#333333" - } - }, - "axisLabel": { - "show": true, - "textStyle": { - "color": "#999999" - } - }, - "splitLine": { - "show": true, - "lineStyle": { - "color": [ - "#eeeeee" - ] - } - }, - "splitArea": { - "show": false, - "areaStyle": { - "color": [ - "rgba(250,250,250,0.3)", - "rgba(200,200,200,0.3)" - ] - } - } - }, - "logAxis": { - "axisLine": { - "show": true, - "lineStyle": { - "color": "#cccccc" - } - }, - "axisTick": { - "show": false, - "lineStyle": { - "color": "#333333" - } - }, - "axisLabel": { - "show": true, - "textStyle": { - "color": "#999999" - } - }, - "splitLine": { - "show": true, - "lineStyle": { - "color": [ - "#eeeeee" - ] - } - }, - "splitArea": { - "show": false, - "areaStyle": { - "color": [ - "rgba(250,250,250,0.3)", - "rgba(200,200,200,0.3)" - ] - } - } - }, - "timeAxis": { - "axisLine": { - "show": true, - "lineStyle": { - "color": "#cccccc" - } - }, - "axisTick": { - "show": false, - "lineStyle": { - "color": "#333333" - } - }, - "axisLabel": { - "show": true, - "textStyle": { - "color": "#999999" - } - }, - "splitLine": { - "show": true, - "lineStyle": { - "color": [ - "#eeeeee" - ] - } - }, - "splitArea": { - "show": false, - "areaStyle": { - "color": [ - "rgba(250,250,250,0.3)", - "rgba(200,200,200,0.3)" - ] - } - } - }, - "toolbox": { - "iconStyle": { - "normal": { - "borderColor": "#aaaaaa" - }, - "emphasis": { - "borderColor": "#666" - } - } - }, - "legend": { - "textStyle": { - "color": "#999999" - } - }, - "tooltip": { - "axisPointer": { - "lineStyle": { - "color": "#ccc", - "width": 1 - }, - "crossStyle": { - "color": "#ccc", - "width": 1 - } - } - }, - "timeline": { - "lineStyle": { - "color": "#349e8e", - "width": 1 - }, - "itemStyle": { - "normal": { - "color": "#349e8e", - "borderWidth": "1" - }, - "emphasis": { - "color": "#57e8d2" - } - }, - "controlStyle": { - "normal": { - "color": "#349e8e", - "borderColor": "#349e8e", - "borderWidth": "0" - } - }, - "checkpointStyle": { - "color": "#22c3aa", - "borderColor": "rgba(34,195,170,0.25)" - }, - "label": { - "normal": { - "textStyle": { - "color": "#349e8e" - } - } - } - }, - "visualMap": { - "color": [ - "#d0648a", - "#22c3aa", - "rgba(123,217,165,0.2)" - ] - }, - "dataZoom": { - "backgroundColor": "#fff", - "dataBackgroundColor": "#dedede", - "fillerColor": "rgba(34,195,170,0.25)", - "handleColor": "#dddddd", - "handleSize": "100%", - "textStyle": { - "color": "#999" - } - }, - "markPoint": { - "label": { - "normal": { - "textStyle": { - "color": "#ffffff" - } - }, - "emphasis": { - "textStyle": { - "color": "#ffffff" - } - } - } + "subtextStyle": { + "color": "#999999" } + }, + "line": { + "itemStyle": { + "normal": { + "borderWidth": "2" + } + }, + "lineStyle": { + "normal": { + "width": "3" + } + }, + "symbolSize": "10", + "symbol": "emptyCircle", + "smooth": true + }, + "radar": { + "itemStyle": { + "normal": { + "borderWidth": "2" + } + }, + "lineStyle": { + "normal": { + "width": "3" + } + }, + "symbolSize": "10", + "symbol": "emptyCircle", + "smooth": true + }, + "bar": { + "itemStyle": { + "normal": { + "barBorderWidth": "0", + "barBorderColor": "#444444" + }, + "emphasis": { + "barBorderWidth": "0", + "barBorderColor": "#444444" + } + } + }, + "pie": { + "itemStyle": { + "normal": { + "borderWidth": "0", + "borderColor": "#444444" + }, + "emphasis": { + "borderWidth": "0", + "borderColor": "#444444" + } + } + }, + "scatter": { + "itemStyle": { + "normal": { + "borderWidth": "0", + "borderColor": "#444444" + }, + "emphasis": { + "borderWidth": "0", + "borderColor": "#444444" + } + } + }, + "boxplot": { + "itemStyle": { + "normal": { + "borderWidth": "0", + "borderColor": "#444444" + }, + "emphasis": { + "borderWidth": "0", + "borderColor": "#444444" + } + } + }, + "parallel": { + "itemStyle": { + "normal": { + "borderWidth": "0", + "borderColor": "#444444" + }, + "emphasis": { + "borderWidth": "0", + "borderColor": "#444444" + } + } + }, + "sankey": { + "itemStyle": { + "normal": { + "borderWidth": "0", + "borderColor": "#444444" + }, + "emphasis": { + "borderWidth": "0", + "borderColor": "#444444" + } + } + }, + "funnel": { + "itemStyle": { + "normal": { + "borderWidth": "0", + "borderColor": "#444444" + }, + "emphasis": { + "borderWidth": "0", + "borderColor": "#444444" + } + } + }, + "gauge": { + "itemStyle": { + "normal": { + "borderWidth": "0", + "borderColor": "#444444" + }, + "emphasis": { + "borderWidth": "0", + "borderColor": "#444444" + } + } + }, + "candlestick": { + "itemStyle": { + "normal": { + "color": "#d0648a", + "color0": "#ffffff", + "borderColor": "#d0648a", + "borderColor0": "#22c3aa", + "borderWidth": 1 + } + } + }, + "graph": { + "itemStyle": { + "normal": { + "borderWidth": "0", + "borderColor": "#444444" + } + }, + "lineStyle": { + "normal": { + "width": 1, + "color": "#aaa" + } + }, + "symbolSize": "10", + "symbol": "emptyCircle", + "smooth": true, + "color": [ + "#4ea397", + "#22c3aa", + "#7bd9a5" + ], + "label": { + "normal": { + "textStyle": { + "color": "#ffffff" + } + } + } + }, + "map": { + "itemStyle": { + "normal": { + "areaColor": "#eeeeee", + "borderColor": "#999999", + "borderWidth": "0.5" + }, + "emphasis": { + "areaColor": "rgba(34,195,170,0.25)", + "borderColor": "#22c3aa", + "borderWidth": "0.5" + } + }, + "label": { + "normal": { + "textStyle": { + "color": "#28544e" + } + }, + "emphasis": { + "textStyle": { + "color": "rgb(52,158,142)" + } + } + } + }, + "geo": { + "itemStyle": { + "normal": { + "areaColor": "#eeeeee", + "borderColor": "#999999", + "borderWidth": "0.5" + }, + "emphasis": { + "areaColor": "rgba(34,195,170,0.25)", + "borderColor": "#22c3aa", + "borderWidth": "0.5" + } + }, + "label": { + "normal": { + "textStyle": { + "color": "#28544e" + } + }, + "emphasis": { + "textStyle": { + "color": "rgb(52,158,142)" + } + } + } + }, + "categoryAxis": { + "axisLine": { + "show": true, + "lineStyle": { + "color": "#cccccc" + } + }, + "axisTick": { + "show": false, + "lineStyle": { + "color": "#333333" + } + }, + "axisLabel": { + "show": true, + "textStyle": { + "color": "#999999" + } + }, + "splitLine": { + "show": true, + "lineStyle": { + "color": [ + "#eeeeee" + ] + } + }, + "splitArea": { + "show": false, + "areaStyle": { + "color": [ + "rgba(250,250,250,0.3)", + "rgba(200,200,200,0.3)" + ] + } + } + }, + "valueAxis": { + "axisLine": { + "show": true, + "lineStyle": { + "color": "#cccccc" + } + }, + "axisTick": { + "show": false, + "lineStyle": { + "color": "#333333" + } + }, + "axisLabel": { + "show": true, + "textStyle": { + "color": "#999999" + } + }, + "splitLine": { + "show": true, + "lineStyle": { + "color": [ + "#eeeeee" + ] + } + }, + "splitArea": { + "show": false, + "areaStyle": { + "color": [ + "rgba(250,250,250,0.3)", + "rgba(200,200,200,0.3)" + ] + } + } + }, + "logAxis": { + "axisLine": { + "show": true, + "lineStyle": { + "color": "#cccccc" + } + }, + "axisTick": { + "show": false, + "lineStyle": { + "color": "#333333" + } + }, + "axisLabel": { + "show": true, + "textStyle": { + "color": "#999999" + } + }, + "splitLine": { + "show": true, + "lineStyle": { + "color": [ + "#eeeeee" + ] + } + }, + "splitArea": { + "show": false, + "areaStyle": { + "color": [ + "rgba(250,250,250,0.3)", + "rgba(200,200,200,0.3)" + ] + } + } + }, + "timeAxis": { + "axisLine": { + "show": true, + "lineStyle": { + "color": "#cccccc" + } + }, + "axisTick": { + "show": false, + "lineStyle": { + "color": "#333333" + } + }, + "axisLabel": { + "show": true, + "textStyle": { + "color": "#999999" + } + }, + "splitLine": { + "show": true, + "lineStyle": { + "color": [ + "#eeeeee" + ] + } + }, + "splitArea": { + "show": false, + "areaStyle": { + "color": [ + "rgba(250,250,250,0.3)", + "rgba(200,200,200,0.3)" + ] + } + } + }, + "toolbox": { + "iconStyle": { + "normal": { + "borderColor": "#aaaaaa" + }, + "emphasis": { + "borderColor": "#666" + } + } + }, + "legend": { + "textStyle": { + "color": "#999999" + } + }, + "tooltip": { + "axisPointer": { + "lineStyle": { + "color": "#ccc", + "width": 1 + }, + "crossStyle": { + "color": "#ccc", + "width": 1 + } + } + }, + "timeline": { + "lineStyle": { + "color": "#349e8e", + "width": 1 + }, + "itemStyle": { + "normal": { + "color": "#349e8e", + "borderWidth": "1" + }, + "emphasis": { + "color": "#57e8d2" + } + }, + "controlStyle": { + "normal": { + "color": "#349e8e", + "borderColor": "#349e8e", + "borderWidth": "0" + } + }, + "checkpointStyle": { + "color": "#22c3aa", + "borderColor": "rgba(34,195,170,0.25)" + }, + "label": { + "normal": { + "textStyle": { + "color": "#349e8e" + } + } + } + }, + "visualMap": { + "color": [ + "#d0648a", + "#22c3aa", + "rgba(123,217,165,0.2)" + ] + }, + "dataZoom": { + "backgroundColor": "#fff", + "dataBackgroundColor": "#dedede", + "fillerColor": "rgba(34,195,170,0.25)", + "handleColor": "#dddddd", + "handleSize": "100%", + "textStyle": { + "color": "#999" + } + }, + "markPoint": { + "label": { + "normal": { + "textStyle": { + "color": "#ffffff" + } + }, + "emphasis": { + "textStyle": { + "color": "#ffffff" + } + } + } + } } diff --git a/src/pages/dashboard/widget/RatePanel.less b/src/pages/dashboard/widget/RatePanel.less index 008ded1..821634c 100644 --- a/src/pages/dashboard/widget/RatePanel.less +++ b/src/pages/dashboard/widget/RatePanel.less @@ -1,8 +1,10 @@ .widget-rate-panel { margin-right: 5px; + .infinite { } + .no-data { } } diff --git a/src/pages/dashboard/widget/RatePanel.tsx b/src/pages/dashboard/widget/RatePanel.tsx index 462500d..99823e0 100644 --- a/src/pages/dashboard/widget/RatePanel.tsx +++ b/src/pages/dashboard/widget/RatePanel.tsx @@ -5,9 +5,9 @@ import {ArrowDownOutlined, ArrowUpOutlined} from "@ant-design/icons/lib"; import Color from "../../../common/model/base/option/Color"; interface IProps { - name: string - standardValue: number - compareValue: number + name: string + standardValue: number + compareValue: number } interface IState { @@ -16,66 +16,66 @@ interface IState { export default class RatePanel extends TankComponent { - constructor(props: IProps) { - super(props) - this.state = {} - } - - - componentDidMount() { - - } - - getValue(): number { - if (this.props.standardValue === 0) { - if (this.props.compareValue === 0) { - return 0; - } else { - return 100; - } - } else { - let v1 = this.props.compareValue - this.props.standardValue - let v2 = v1 / this.props.standardValue - return parseInt((v2 * 100).toFixed(0)) + constructor(props: IProps) { + super(props) + this.state = {} } - } - render() { - let that = this - let name: string = this.props.name + componentDidMount() { - let noData: boolean = this.props.standardValue === 0 && this.props.compareValue === 0 - let infinite: boolean = this.props.standardValue === 0 && this.props.compareValue > 0 - let value: number = this.getValue() + } - return ( - + getValue(): number { + if (this.props.standardValue === 0) { + if (this.props.compareValue === 0) { + return 0; + } else { + return 100; + } + } else { + let v1 = this.props.compareValue - this.props.standardValue + let v2 = v1 / this.props.standardValue + return parseInt((v2 * 100).toFixed(0)) + } + } + + render() { + + let that = this + let name: string = this.props.name + + let noData: boolean = this.props.standardValue === 0 && this.props.compareValue === 0 + let infinite: boolean = this.props.standardValue === 0 && this.props.compareValue > 0 + let value: number = this.getValue() + + return ( + {name} - {infinite ? ( - - ) : ( - noData ? ( - - - ) : ( - {value > 0 ? '+' : ''}{value}% - ) - )} + {infinite ? ( + + ) : ( + noData ? ( + - + ) : ( + {value > 0 ? '+' : ''}{value}% + ) + )} - { - (!noData && value < 0) && - () - } + { + (!noData && value < 0) && + () + } - { - (!noData && (infinite || value >= 0)) && - () - } + { + (!noData && (infinite || value >= 0)) && + () + } - ) - } + ) + } } diff --git a/src/pages/install/Index.tsx b/src/pages/install/Index.tsx index cff20fc..44b0bf9 100644 --- a/src/pages/install/Index.tsx +++ b/src/pages/install/Index.tsx @@ -27,81 +27,82 @@ interface IState { export default class Index extends TankComponent { - user: User = Moon.getSingleton().user; + user: User = Moon.getSingleton().user; - install: Install = new Install() + install: Install = new Install() - //当前高亮的tab - activeName: string = "first" + //当前高亮的tab + activeName: string = "first" - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } + this.state = {}; + } - componentDidMount() { - let that = this; + componentDidMount() { + let that = this; - that.updateUI(); - } + that.updateUI(); + } - render() { + render() { - let that = this; + let that = this; - let install: Install = this.install + let install: Install = this.install - return ( -
+ return ( +
- + - + - - { + + { - this.activeName = activeKey - this.updateUI() - }}> - - { - this.activeName = "second" - this.updateUI() - }}/> - - - { - this.activeName = "first" - this.updateUI() - }} onNextStep={() => { - this.activeName = "third" - this.updateUI() - }}/> - - - { - this.activeName = "second" - this.updateUI() - }} onNextStep={() => { - this.activeName = "forth" - this.updateUI() - }}/> - - - - - + this.activeName = activeKey + this.updateUI() + }}> + + { + this.activeName = "second" + this.updateUI() + }}/> + + + { + this.activeName = "first" + this.updateUI() + }} onNextStep={() => { + this.activeName = "third" + this.updateUI() + }}/> + + + { + this.activeName = "second" + this.updateUI() + }} onNextStep={() => { + this.activeName = "forth" + this.updateUI() + }}/> + + + + + - + -
- ); - } +
+ ); + } } diff --git a/src/pages/install/widget/CreateTablePanel.tsx b/src/pages/install/widget/CreateTablePanel.tsx index eb9d3b2..78b3b1e 100644 --- a/src/pages/install/widget/CreateTablePanel.tsx +++ b/src/pages/install/widget/CreateTablePanel.tsx @@ -5,12 +5,12 @@ import Install from "../../../common/model/install/Install"; import TankComponent from "../../../common/component/TankComponent"; import Color from "../../../common/model/base/option/Color"; import { - ArrowLeftOutlined, - ArrowRightOutlined, - CheckOutlined, - FormatPainterOutlined, - SoundOutlined, - SyncOutlined + ArrowLeftOutlined, + ArrowRightOutlined, + CheckOutlined, + FormatPainterOutlined, + SoundOutlined, + SyncOutlined } from "@ant-design/icons/lib"; import MessageBoxUtil from "../../../common/util/MessageBoxUtil"; import Lang from "../../../common/model/global/Lang"; @@ -18,9 +18,9 @@ import InstallFieldInfo from "../../../common/model/install/InstallFieldInfo"; interface IProps { - install: Install - onPreStep: () => void - onNextStep: () => void + install: Install + onPreStep: () => void + onNextStep: () => void } interface IState { @@ -29,210 +29,213 @@ interface IState { export default class CreateTablePanel extends TankComponent { - loading: boolean = true + loading: boolean = true - createTableLoading: boolean = false + createTableLoading: boolean = false - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } - - - componentDidMount() { - let that = this; - - this.fetchTableInfoList() - - } - - fetchTableInfoList() { - - let that = this - let install: Install = this.props.install - - this.loading = true - this.updateUI() - - install.httpTableInfoList(null, null, function () { - that.loading = false - that.updateUI() - }) - } - - createTable() { - //开始建表 - let that = this; - let install: Install = this.props.install - - that.createTableLoading = true - that.updateUI() - - install.httpCreateTable(function () { - MessageBoxUtil.success(Lang.t("install.createTableSuccess")) - }, null, function () { - - that.createTableLoading = false - that.updateUI() - }) - } - - goToPrevious() { - let that = this - - this.props.onPreStep() - - } - - goToNext() { - let that = this - let install: Install = this.props.install - - if (install.tableCreated()) { - - this.props.onNextStep() - - } else { - MessageBoxUtil.error(Lang.t("install.crateTableFirst")) + this.state = {}; } - } - render() { + componentDidMount() { + let that = this; - let that = this; + this.fetchTableInfoList() - let install: Install = this.props.install + } - let tableCreated: boolean = install.tableCreated() + fetchTableInfoList() { - return ( -
+ let that = this + let install: Install = this.props.install - - { - install.tableInfoList.map(function (tableInfo: any, index: number) { + this.loading = true + this.updateUI() - return ( -
-
- {tableInfo.name} + install.httpTableInfoList(null, null, function () { + that.loading = false + that.updateUI() + }) + } + createTable() { + //开始建表 + let that = this; + let install: Install = this.props.install + + that.createTableLoading = true + that.updateUI() + + install.httpCreateTable(function () { + MessageBoxUtil.success(Lang.t("install.createTableSuccess")) + }, null, function () { + + that.createTableLoading = false + that.updateUI() + }) + } + + goToPrevious() { + let that = this + + this.props.onPreStep() + + } + + goToNext() { + let that = this + let install: Install = this.props.install + + if (install.tableCreated()) { + + this.props.onNextStep() + + } else { + MessageBoxUtil.error(Lang.t("install.crateTableFirst")) + } + + } + + render() { + + let that = this; + + let install: Install = this.props.install + + let tableCreated: boolean = install.tableCreated() + + return ( +
+ + { - (tableInfo.tableExist && tableInfo.missingFields.length === 0) && ( - {Lang.t("install.installed")} - ) - } - - { - (tableInfo.tableExist && tableInfo.missingFields.length > 0) && ( - {Lang.t("install.installedButMissing")} - ) - } - - { - !tableInfo.tableExist && ( - {Lang.t("install.toBeInstalled")} - ) - } -
- -
- {Lang.t("install.allFields")}: - { - tableInfo.allFields.filter((field: InstallFieldInfo, index: number) => { - return field.name - }).map(function (field: InstallFieldInfo, j: number) { - - return ( - - {field.name} - - ) - }) - } -
- - - { - (tableInfo.tableExist && tableInfo.missingFields.length > 0) && ( -
- {Lang.t("install.missingFields")}: - { - tableInfo.missingFields.filter((field: InstallFieldInfo, index: number) => { - return field.name - }).map(function (field: InstallFieldInfo, j: number) { + install.tableInfoList.map(function (tableInfo: any, index: number) { return ( - - {field.name} - +
+
+ {tableInfo.name} + + { + (tableInfo.tableExist && tableInfo.missingFields.length === 0) && ( + {Lang.t("install.installed")} + ) + } + + { + (tableInfo.tableExist && tableInfo.missingFields.length > 0) && ( + {Lang.t("install.installedButMissing")} + ) + } + + { + !tableInfo.tableExist && ( + {Lang.t("install.toBeInstalled")} + ) + } +
+ +
+ {Lang.t("install.allFields")}: + { + tableInfo.allFields.filter((field: InstallFieldInfo, index: number) => { + return field.name + }).map(function (field: InstallFieldInfo, j: number) { + + return ( + + {field.name} + + ) + }) + } +
+ + + { + (tableInfo.tableExist && tableInfo.missingFields.length > 0) && ( +
+ {Lang.t("install.missingFields")}: + { + tableInfo.missingFields.filter((field: InstallFieldInfo, index: number) => { + return field.name + }).map(function (field: InstallFieldInfo, j: number) { + + return ( + + {field.name} + + ) + }) + } +
+ ) + } + +
) - }) - } -
- ) - } -
- ) - - }) - } + }) + } -
- -
{Lang.t("install.tableNotice")}
-
-
    -
  1. {Lang.t("install.tableNotice1")}
  2. -
  3. {Lang.t("install.tableNotice2")}
  4. -
  5. {Lang.t("install.tableNotice3")}
  6. -
  7. {Lang.t("install.tableNotice4")}
  8. -
-
-
} - type="info" - /> -
+
+ +
{Lang.t("install.tableNotice")}
+
+
    +
  1. {Lang.t("install.tableNotice1")}
  2. +
  3. {Lang.t("install.tableNotice2")}
  4. +
  5. {Lang.t("install.tableNotice3")}
  6. +
  7. {Lang.t("install.tableNotice4")}
  8. +
+
+
} + type="info" + /> +
-
- +
+ - + - - -
+ + +
- + - - ); - } + + ); + } } diff --git a/src/pages/install/widget/FinishPanel.tsx b/src/pages/install/widget/FinishPanel.tsx index 729169d..1f8174f 100644 --- a/src/pages/install/widget/FinishPanel.tsx +++ b/src/pages/install/widget/FinishPanel.tsx @@ -8,7 +8,7 @@ import Lang from "../../../common/model/global/Lang"; interface IProps { - install: Install + install: Install } @@ -19,64 +19,64 @@ interface IState { export default class FinishPanel extends TankComponent { - loading: boolean = false + loading: boolean = false - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } + this.state = {}; + } - componentDidMount() { - let that = this; + componentDidMount() { + let that = this; - that.updateUI(); - } + that.updateUI(); + } - finish() { + finish() { - let that = this - let install: Install = this.props.install + let that = this + let install: Install = this.props.install - that.loading = true - that.updateUI() + that.loading = true + that.updateUI() - install.httpFinish(function () { + install.httpFinish(function () { - window.location.href = "/" + window.location.href = "/" - }, null, function () { + }, null, function () { - that.loading = false - that.updateUI() + that.loading = false + that.updateUI() - }) + }) - } + } - render() { + render() { - let that = this; + let that = this; - return ( -
- } type="primary" key="home" loading={that.loading} - onClick={this.finish.bind(this)}> - {Lang.t("install.enterHome")} - - ]} - /> + return ( +
+ } type="primary" key="home" loading={that.loading} + onClick={this.finish.bind(this)}> + {Lang.t("install.enterHome")} + + ]} + /> -
- ); - } +
+ ); + } } diff --git a/src/pages/install/widget/MysqlPanel.tsx b/src/pages/install/widget/MysqlPanel.tsx index 797ca2e..bdac63b 100644 --- a/src/pages/install/widget/MysqlPanel.tsx +++ b/src/pages/install/widget/MysqlPanel.tsx @@ -9,8 +9,8 @@ import MessageBoxUtil from "../../../common/util/MessageBoxUtil"; import Lang from "../../../common/model/global/Lang"; interface IProps { - install: Install - onNextStep: () => void + install: Install + onNextStep: () => void } interface IState { @@ -18,240 +18,240 @@ interface IState { } export default class MysqlPanel extends TankComponent { - formRef = React.createRef(); + formRef = React.createRef(); - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } - - componentDidMount() { - let that = this; - - that.updateUI(); - } - - - onFinish(values: any) { - - let that = this - let install: Install = this.props.install - - install.dbType = values["dbType"] - install.mysqlHost = values["mysqlHost"] - install.mysqlPort = values["mysqlPort"] - install.mysqlSchema = values["mysqlSchema"] - install.mysqlUsername = values["mysqlUsername"] - install.mysqlPassword = values["mysqlPassword"] - install.mysqlCharset = values["mysqlCharset"] - - install.httpVerify(function () { - - install.verified = true - MessageBoxUtil.success(Lang.t("install.mysqlConnectionPass")) - that.updateUI() - - }, function (msg: any) { - - install.verified = false - MessageBoxUtil.error(msg) - that.updateUI() - - }) - }; - - onFinishFailed(errorInfo: any) { - - }; - - goToNext() { - let that = this - let install: Install = this.props.install - let useMysql = this.useMysql(); - if (!useMysql) { - install.verified = true + this.state = {}; } - if (install.verified) { - this.props.onNextStep() - } else { - MessageBoxUtil.error(Lang.t("install.validateMysqlFirst")) + componentDidMount() { + let that = this; + + that.updateUI(); } - } - useMysql(): boolean { - let that = this; + onFinish(values: any) { - let install: Install = this.props.install - let dbType = install.dbType - if (that.formRef && that.formRef.current) { - dbType = that.formRef.current!.getFieldValue("dbType") - install.dbType = dbType - } + let that = this + let install: Install = this.props.install - return dbType === "mysql" - } + install.dbType = values["dbType"] + install.mysqlHost = values["mysqlHost"] + install.mysqlPort = values["mysqlPort"] + install.mysqlSchema = values["mysqlSchema"] + install.mysqlUsername = values["mysqlUsername"] + install.mysqlPassword = values["mysqlPassword"] + install.mysqlCharset = values["mysqlCharset"] - render() { + install.httpVerify(function () { - let that = this; + install.verified = true + MessageBoxUtil.success(Lang.t("install.mysqlConnectionPass")) + that.updateUI() - let install: Install = this.props.install + }, function (msg: any) { - const layout = { - labelCol: {span: 6}, - wrapperCol: {span: 18}, + install.verified = false + MessageBoxUtil.error(msg) + that.updateUI() + + }) }; + onFinishFailed(errorInfo: any) { - let useMysql: boolean = this.useMysql() + }; - return ( -
+ goToNext() { + let that = this + let install: Install = this.props.install + let useMysql = this.useMysql(); + if (!useMysql) { + install.verified = true + } -
{ - that.updateUI() - }} - > - - - + if (install.verified) { + this.props.onNextStep() + } else { + MessageBoxUtil.error(Lang.t("install.validateMysqlFirst")) + } - { - useMysql && ( - - ) - } + } + + useMysql(): boolean { + let that = this; + + let install: Install = this.props.install + let dbType = install.dbType + if (that.formRef && that.formRef.current) { + dbType = that.formRef.current!.getFieldValue("dbType") + install.dbType = dbType + } + + return dbType === "mysql" + } + + render() { + + let that = this; + + let install: Install = this.props.install + + const layout = { + labelCol: {span: 6}, + wrapperCol: {span: 18}, + }; - { - useMysql && ( - - ) - } + let useMysql: boolean = this.useMysql() + + return ( +
+ + { + that.updateUI() + }} + > + + + + + { + useMysql && ( + + ) + } - { - useMysql && ( - - ) - } + { + useMysql && ( + + ) + } - { - useMysql && ( - - ) - } + { + useMysql && ( + + ) + } - { - useMysql && ( - - ) - } + { + useMysql && ( + + ) + } - { - useMysql && ( - - ) - } + { + useMysql && ( + + ) + } -
- -
{Lang.t("install.notice")}
-
- { - useMysql ? (
    -
  1. {Lang.t("install.mysqlNotice1")}
  2. -
  3. {Lang.t("install.mysqlNotice2")}
  4. -
+ { + useMysql && ( + + ) + } - ) : ( -
    -
  1. {Lang.t("install.sqliteNotice1")}
  2. -
- ) - } -
-
} - type="info" - /> -
+
+ +
{Lang.t("install.notice")}
+
+ { + useMysql ? (
    +
  1. {Lang.t("install.mysqlNotice1")}
  2. +
  3. {Lang.t("install.mysqlNotice2")}
  4. +
-
- { - useMysql && () - } + ) : ( +
    +
  1. {Lang.t("install.sqliteNotice1")}
  2. +
+ ) + } - -
+
+
} + type="info" + /> +
- +
+ { + useMysql && () + } -
- ); - } + + + + + + + ); + } } diff --git a/src/pages/install/widget/SetAdminPanel.tsx b/src/pages/install/widget/SetAdminPanel.tsx index 36fe2e1..7488dd3 100644 --- a/src/pages/install/widget/SetAdminPanel.tsx +++ b/src/pages/install/widget/SetAdminPanel.tsx @@ -9,20 +9,20 @@ import PhaseCreatePanel from "./inner/PhaseCreatePanel"; import Lang from "../../../common/model/global/Lang"; enum Phase { - //选择界面 - SELECTING = "SELECTING", - //验证管理员 - VERIFY = "VERIFY", - //创建管理员 - CREATE = "CREATE", + //选择界面 + SELECTING = "SELECTING", + //验证管理员 + VERIFY = "VERIFY", + //创建管理员 + CREATE = "CREATE", } interface IProps { - install: Install + install: Install - onPreStep: () => void - onNextStep: () => void + onPreStep: () => void + onNextStep: () => void } interface IState { @@ -31,98 +31,98 @@ interface IState { export default class SetAdminPanel extends TankComponent { - phase: Phase = Phase.SELECTING + phase: Phase = Phase.SELECTING - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } - - - componentDidMount() { - let that = this; - - } - - - goToPrevious() { - let that = this - - this.props.onPreStep() - - } - - goToNext() { - let that = this - let install: Install = this.props.install - - if (install.adminConfigured) { - - this.props.onNextStep() - - } else { - MessageBoxUtil.error(Lang.t("install.configAdminFirst")) + this.state = {}; } - } + + componentDidMount() { + let that = this; + + } - render() { + goToPrevious() { + let that = this - let that = this; - let install: Install = this.props.install - let phase: Phase = this.phase + this.props.onPreStep() - return ( -
- {phase === Phase.SELECTING && ( + } - { - if (install.adminList.length) { - that.phase = Phase.SELECTING - } else { - that.phase = Phase.CREATE - } - that.updateUI() - }} - onSelectVerify={() => { - that.phase = Phase.VERIFY - that.updateUI() - }} onSelectCreate={() => { - that.phase = Phase.CREATE - that.updateUI() - }} onPreStep={this.goToPrevious.bind(this)} onNextStep={this.goToNext.bind(this)} - /> - )} + goToNext() { + let that = this + let install: Install = this.props.install + + if (install.adminConfigured) { + + this.props.onNextStep() + + } else { + MessageBoxUtil.error(Lang.t("install.configAdminFirst")) + } + + } - {phase === Phase.VERIFY && ( - { + render() { - that.props.onNextStep() + let that = this; + let install: Install = this.props.install + let phase: Phase = this.phase - }} onPreStep={() => { - that.phase = Phase.SELECTING - that.updateUI() + return ( +
+ {phase === Phase.SELECTING && ( - }}/> - )} + { + if (install.adminList.length) { + that.phase = Phase.SELECTING + } else { + that.phase = Phase.CREATE + } + that.updateUI() + }} + onSelectVerify={() => { + that.phase = Phase.VERIFY + that.updateUI() + }} onSelectCreate={() => { + that.phase = Phase.CREATE + that.updateUI() + }} onPreStep={this.goToPrevious.bind(this)} onNextStep={this.goToNext.bind(this)} + /> + )} - {phase === Phase.CREATE && ( - { - that.props.onNextStep() + {phase === Phase.VERIFY && ( + { - }} onPreStep={() => { - that.phase = Phase.SELECTING - that.updateUI() + that.props.onNextStep() - }}/> - )} + }} onPreStep={() => { + that.phase = Phase.SELECTING + that.updateUI() -
- ) + }}/> + )} - } + {phase === Phase.CREATE && ( + { + + that.props.onNextStep() + + }} onPreStep={() => { + that.phase = Phase.SELECTING + that.updateUI() + + }}/> + )} + +
+ ) + + } } diff --git a/src/pages/install/widget/inner/PhaseCreatePanel.tsx b/src/pages/install/widget/inner/PhaseCreatePanel.tsx index 6a7ce79..b31ae70 100644 --- a/src/pages/install/widget/inner/PhaseCreatePanel.tsx +++ b/src/pages/install/widget/inner/PhaseCreatePanel.tsx @@ -9,10 +9,10 @@ import Lang from "../../../../common/model/global/Lang"; interface IProps { - install: Install + install: Install - onSuccess: () => void - onPreStep: () => void + onSuccess: () => void + onPreStep: () => void } @@ -23,125 +23,125 @@ interface IState { export default class PhaseCreatePanel extends TankComponent { - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } + this.state = {}; + } - componentDidMount() { - let that = this; + componentDidMount() { + let that = this; - } + } - onFinish(values: any) { + onFinish(values: any) { - let that = this; - let install: Install = this.props.install + let that = this; + let install: Install = this.props.install - install.adminUsername = values["adminUsername"] - install.adminPassword = values["adminPassword"] - install.adminRepassword = values["adminRepassword"] + install.adminUsername = values["adminUsername"] + install.adminPassword = values["adminPassword"] + install.adminRepassword = values["adminRepassword"] - install.httpCreateAdmin(function () { - MessageBoxUtil.success(Lang.t("install.createAdminSuccess")) - that.props.onSuccess() - }) - }; - - onFinishFailed(errorInfo: any) { - - }; - - render() { - - let that = this; - let install: Install = this.props.install - - const layout = { - labelCol: {span: 6}, - wrapperCol: {span: 18}, + install.httpCreateAdmin(function () { + MessageBoxUtil.success(Lang.t("install.createAdminSuccess")) + that.props.onSuccess() + }) }; + onFinishFailed(errorInfo: any) { - return ( -
+ }; -
-

{Lang.t("install.createAdministrator")}

-
+ render() { -
{ - that.updateUI() - }} - > - - - + let that = this; + let install: Install = this.props.install - - - + const layout = { + labelCol: {span: 6}, + wrapperCol: {span: 18}, + }; - ({ - validator(rule, value) { - if (!value || getFieldValue('adminPassword') === value) { - return Promise.resolve(); - } - return Promise.reject(Lang.t("user.passwordNotSame")); - }, - }), - ]} - > - - + return ( +
-
+
+

{Lang.t("install.createAdministrator")}

+
- + { + that.updateUI() + }} + > + + + - + + + -
- -
- ); - } + ({ + validator(rule, value) { + if (!value || getFieldValue('adminPassword') === value) { + return Promise.resolve(); + } + return Promise.reject(Lang.t("user.passwordNotSame")); + }, + }), + ]} + > + + + +
+ + + + + +
+ + +
+ ); + } } diff --git a/src/pages/install/widget/inner/PhaseSelectingPanel.tsx b/src/pages/install/widget/inner/PhaseSelectingPanel.tsx index 3eed394..2f9345f 100644 --- a/src/pages/install/widget/inner/PhaseSelectingPanel.tsx +++ b/src/pages/install/widget/inner/PhaseSelectingPanel.tsx @@ -5,22 +5,22 @@ import Install from "../../../../common/model/install/Install"; import User from "../../../../common/model/user/User"; import {Button} from "antd"; import { - ArrowLeftOutlined, - ArrowRightOutlined, - SecurityScanOutlined, - SyncOutlined, - UserAddOutlined + ArrowLeftOutlined, + ArrowRightOutlined, + SecurityScanOutlined, + SyncOutlined, + UserAddOutlined } from "@ant-design/icons/lib"; import Lang from "../../../../common/model/global/Lang"; interface IProps { - install: Install + install: Install - onRefresh: () => void - onSelectVerify: () => void - onSelectCreate: () => void - onPreStep: () => void - onNextStep: () => void + onRefresh: () => void + onSelectVerify: () => void + onSelectCreate: () => void + onPreStep: () => void + onNextStep: () => void } @@ -30,100 +30,100 @@ interface IState { export default class PhaseSelectingPanel extends TankComponent { - loadingAdminList: boolean = false + loadingAdminList: boolean = false - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } + this.state = {}; + } - componentDidMount() { - let that = this; + componentDidMount() { + let that = this; - this.refreshAdminList() - } + this.refreshAdminList() + } - refreshAdminList() { - //开始创建管理员 - let that = this; - let install: Install = this.props.install + refreshAdminList() { + //开始创建管理员 + let that = this; + let install: Install = this.props.install - that.loadingAdminList = true - that.updateUI() + that.loadingAdminList = true + that.updateUI() - install.httpAdminList(null, null, function () { - that.loadingAdminList = false - that.updateUI() - that.props.onRefresh() - }) - } + install.httpAdminList(null, null, function () { + that.loadingAdminList = false + that.updateUI() + that.props.onRefresh() + }) + } - render() { + render() { - let that = this; - let install: Install = this.props.install + let that = this; + let install: Install = this.props.install - return ( -
+ return ( +
-
- {Lang.t("install.detectAdministrator")}: -
- { - install.adminList.map(function (admin: User, index: number) { - return ( -
- {admin.username} -
- ) - }) - } +
+ {Lang.t("install.detectAdministrator")}: +
+ { + install.adminList.map(function (admin: User, index: number) { + return ( +
+ {admin.username} +
+ ) + }) + } -
- {Lang.t("install.useOrCreateAdministrator")} -
+
+ {Lang.t("install.useOrCreateAdministrator")} +
-
- +
+ - + - + - - + + -
+
-
- ); - } +
+ ); + } } diff --git a/src/pages/install/widget/inner/PhaseVerifyPanel.tsx b/src/pages/install/widget/inner/PhaseVerifyPanel.tsx index 5f4f1ef..a76622c 100644 --- a/src/pages/install/widget/inner/PhaseVerifyPanel.tsx +++ b/src/pages/install/widget/inner/PhaseVerifyPanel.tsx @@ -9,11 +9,11 @@ import Lang from "../../../../common/model/global/Lang"; interface IProps { - install: Install + install: Install - onSuccess: () => void - onPreStep: () => void + onSuccess: () => void + onPreStep: () => void } @@ -24,103 +24,103 @@ interface IState { export default class PhaseVerifyPanel extends TankComponent { - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } + this.state = {}; + } - componentDidMount() { - let that = this; + componentDidMount() { + let that = this; - } + } - onFinish(values: any) { + onFinish(values: any) { - let that = this; - let install: Install = this.props.install + let that = this; + let install: Install = this.props.install - install.adminUsername = values["adminUsername"] - install.adminPassword = values["adminPassword"] + install.adminUsername = values["adminUsername"] + install.adminPassword = values["adminPassword"] - install.httpValidateAdmin(function () { - MessageBoxUtil.success(Lang.t("install.validateAdminSuccess")) + install.httpValidateAdmin(function () { + MessageBoxUtil.success(Lang.t("install.validateAdminSuccess")) - that.props.onSuccess() - }) + that.props.onSuccess() + }) - }; - - onFinishFailed(errorInfo: any) { - - }; - - render() { - - let that = this; - let install: Install = this.props.install - - const layout = { - labelCol: {span: 6}, - wrapperCol: {span: 18}, }; + onFinishFailed(errorInfo: any) { - return ( -
+ }; -
-

{Lang.t("install.validateAdministrator")}

-
+ render() { -
{ - that.updateUI() - }} - > - - - + let that = this; + let install: Install = this.props.install - - - + const layout = { + labelCol: {span: 6}, + wrapperCol: {span: 18}, + }; -
- + return ( +
- +
+

{Lang.t("install.validateAdministrator")}

+
-
- +
{ + that.updateUI() + }} + > + + + -
- ); - } + + + + +
+ + + + + +
+ + +
+ ); + } } diff --git a/src/pages/layout/BottomLayout.tsx b/src/pages/layout/BottomLayout.tsx index e652fca..e88a4bb 100644 --- a/src/pages/layout/BottomLayout.tsx +++ b/src/pages/layout/BottomLayout.tsx @@ -6,50 +6,52 @@ import DefaultLogoPng from "../../assets/image/logo.png"; import Sun from "../../common/model/global/Sun"; import Lang from "../../common/model/global/Lang"; -interface IProps {} +interface IProps { +} -interface IState {} +interface IState { +} export default class BottomLayout extends TankComponent { - constructor(props: IProps) { - super(props); - this.state = {}; - } - - static changeLang() { - if (Lang.getSingleton().lang === "zh") { - Lang.getSingleton().lang = "en"; - } else { - Lang.getSingleton().lang = "zh"; + constructor(props: IProps) { + super(props); + this.state = {}; } - localStorage.setItem("_lang", Lang.getSingleton().lang); - Sun.updateFrame(); - } - render() { - const { preference } = Moon.getSingleton(); + static changeLang() { + if (Lang.getSingleton().lang === "zh") { + Lang.getSingleton().lang = "en"; + } else { + Lang.getSingleton().lang = "zh"; + } + localStorage.setItem("_lang", Lang.getSingleton().lang); + Sun.updateFrame(); + } - return ( -
+ render() { + const {preference} = Moon.getSingleton(); + + return ( +
- + - - + + - + {Lang.getSingleton().lang === "zh" ? "English" : "中文"} - {/*开源不易,请不要移除掉这里的代码,蓝眼云盘谢谢您! ^_^*/} - {/*It is not easy to open source,please do not remove the following code, thank you! ^_^ */} - + {/*开源不易,请不要移除掉这里的代码,蓝眼云盘谢谢您! ^_^*/} + {/*It is not easy to open source,please do not remove the following code, thank you! ^_^ */} + Powered by - logo {Lang.t("eyeblueTank")} + logo {Lang.t("eyeblueTank")} -
- ); - } +
+ ); + } } diff --git a/src/pages/layout/ContentLayout.tsx b/src/pages/layout/ContentLayout.tsx index 2e89df2..b517f88 100644 --- a/src/pages/layout/ContentLayout.tsx +++ b/src/pages/layout/ContentLayout.tsx @@ -12,26 +12,26 @@ interface IState { export default class ContentLayout extends TankComponent { - constructor(props: IProps) { - super(props) - this.state = {} - } + constructor(props: IProps) { + super(props) + this.state = {} + } - componentDidMount() { + componentDidMount() { - } + } - render() { + render() { - let that = this + let that = this - return ( + return ( -
- {this.props.children} -
+
+ {this.props.children} +
- ) - } + ) + } } diff --git a/src/pages/layout/SideLayout.less b/src/pages/layout/SideLayout.less index b78c758..4aa5676 100644 --- a/src/pages/layout/SideLayout.less +++ b/src/pages/layout/SideLayout.less @@ -2,58 +2,58 @@ //旁边布局 .layout-side { - @nav-text-color: white; - @font-highlight-color: #ddd; - @left-border-color: @brand-primary; + @nav-text-color: white; + @font-highlight-color: #ddd; + @left-border-color: @brand-primary; - transition: all 0.4s; - position: fixed; - width: @sidebar-width; - left: 0; - top: 0; - bottom: 0; - z-index: 1000; + transition: all 0.4s; + position: fixed; + width: @sidebar-width; + left: 0; + top: 0; + bottom: 0; + z-index: 1000; - background: #001529; + background: #001529; - //show-drawer只在手机屏幕生效 + //show-drawer只在手机屏幕生效 + @media (max-width: @screen-xs-max) { + left: -@sidebar-width; + &.show-drawer { + left: 0; + } + } + + .avatar-area { + text-align: center; + margin-top: 40px; + } + + .username-area { + padding: 10px 20px; + text-align: center; + color: #bbb; + + .username-text { + color: #bbb; + font-size: 16px; + } + } + + .install-area { + text-align: center; + margin-top: 40px; + margin-bottom: 20px; + + .install-logo { + width: 80px; + } + } + + .visible-xs { + display: none; @media (max-width: @screen-xs-max) { - left: -@sidebar-width; - &.show-drawer { - left: 0; - } - } - - .avatar-area { - text-align: center; - margin-top: 40px; - } - - .username-area { - padding: 10px 20px; - text-align: center; - color: #bbb; - - .username-text { - color: #bbb; - font-size: 16px; - } - } - - .install-area { - text-align: center; - margin-top: 40px; - margin-bottom: 20px; - - .install-logo { - width: 80px; - } - } - - .visible-xs { - display: none; - @media (max-width: @screen-xs-max) { - display: block; - } + display: block; } + } } diff --git a/src/pages/layout/SideLayout.tsx b/src/pages/layout/SideLayout.tsx index cd29c16..d645ef8 100644 --- a/src/pages/layout/SideLayout.tsx +++ b/src/pages/layout/SideLayout.tsx @@ -5,20 +5,22 @@ import Preference from '../../common/model/preference/Preference'; import Moon from '../../common/model/global/Moon'; import DefaultLogoPng from '../../assets/image/logo.png'; import Sun from '../../common/model/global/Sun'; -import { Link } from 'react-router-dom'; -import { UserRole } from '../../common/model/user/UserRole'; -import { Menu } from 'antd'; +import {Link} from 'react-router-dom'; +import {UserRole} from '../../common/model/user/UserRole'; +import {Menu} from 'antd'; import MenuItem from '../../common/menu/MenuItem'; import User from '../../common/model/user/User'; import MenuManager from '../../common/menu/MenuManager'; -import { InfoCircleOutlined } from '@ant-design/icons'; +import {InfoCircleOutlined} from '@ant-design/icons'; import Lang from '../../common/model/global/Lang'; import AboutModal from './widget/AboutModal'; import Capacity from './widget/Capacity'; -interface IProps {} +interface IProps { +} -interface IState {} +interface IState { +} export default class SideLayout extends TankComponent { constructor(props: IProps) { @@ -75,7 +77,7 @@ export default class SideLayout extends TankComponent { ) : (
- avatar + avatar
)} @@ -96,11 +98,11 @@ export default class SideLayout extends TankComponent { ); })} - + {Lang.t('layout.about')} - + ); } diff --git a/src/pages/layout/TopLayout.tsx b/src/pages/layout/TopLayout.tsx index 984b117..3f4406b 100644 --- a/src/pages/layout/TopLayout.tsx +++ b/src/pages/layout/TopLayout.tsx @@ -19,67 +19,67 @@ interface IState { export default class TopLayout extends TankComponent { - constructor(props: IProps) { - super(props) - this.state = {} - } - - componentDidMount() { - - } - - - goHome() { - - Sun.navigateTo("/") - } - - //logo可以使用自定义的。 - logoUrl() { - - let preference: Preference = Moon.getSingleton().preference - if (preference.logoUrl) { - return ImageUtil.handleImageUrl(preference.logoUrl, false, 200, 200) - - } else { - return DefaultLogoPng + constructor(props: IProps) { + super(props) + this.state = {} } - } - toggleDrawer() { - Sun.getSingleton().showDrawer = !Sun.getSingleton().showDrawer - Sun.updateFrame() - } + componentDidMount() { + + } - render() { + goHome() { - let that = this + Sun.navigateTo("/") + } - let preference: Preference = Moon.getSingleton().preference - return ( + //logo可以使用自定义的。 + logoUrl() { -
+ let preference: Preference = Moon.getSingleton().preference + if (preference.logoUrl) { + return ImageUtil.handleImageUrl(preference.logoUrl, false, 200, 200) -
- logo - {preference.name} -
+ } else { + return DefaultLogoPng + } + } -
- { - Sun.getSingleton().showDrawer ? ( + toggleDrawer() { + Sun.getSingleton().showDrawer = !Sun.getSingleton().showDrawer + Sun.updateFrame() + } - - ) : ( - - ) - } -
-
+ render() { - ) - } + let that = this + + let preference: Preference = Moon.getSingleton().preference + return ( + +
+ +
+ logo + {preference.name} +
+ +
+ { + Sun.getSingleton().showDrawer ? ( + + + ) : ( + + ) + } +
+ +
+ + ) + } } diff --git a/src/pages/layout/widget/AboutModal.tsx b/src/pages/layout/widget/AboutModal.tsx index 3b33cb0..b37a257 100644 --- a/src/pages/layout/widget/AboutModal.tsx +++ b/src/pages/layout/widget/AboutModal.tsx @@ -8,8 +8,8 @@ import "./AboutModal.less"; import Moon from "../../../common/model/global/Moon"; interface IProps { - onSuccess: () => any, - onClose: () => any + onSuccess: () => any, + onClose: () => any } interface IState { @@ -17,55 +17,55 @@ interface IState { export default class AboutModal extends TankComponent { - constructor(props: IProps) { - super(props); - } + constructor(props: IProps) { + super(props); + } - static open = () => { - const modal = Modal.confirm({ - className: "about-modal", - title: Lang.t("layout.about"), - width: "90vw", - okCancel: false, - okText: Lang.t("confirm"), - maskClosable: true, - content: ( - { - modal.destroy(); - }} - onClose={() => { - modal.destroy(); - }} - />) - }) - }; + static open = () => { + const modal = Modal.confirm({ + className: "about-modal", + title: Lang.t("layout.about"), + width: "90vw", + okCancel: false, + okText: Lang.t("confirm"), + maskClosable: true, + content: ( + { + modal.destroy(); + }} + onClose={() => { + modal.destroy(); + }} + />) + }) + }; - changeLang() { - BottomLayout.changeLang(); - this.updateUI(); - }; + changeLang() { + BottomLayout.changeLang(); + this.updateUI(); + }; - render() { - const {preference} = Moon.getSingleton(); - return ( -
+ render() { + const {preference} = Moon.getSingleton(); + return ( +
- + -

this.changeLang()}> - {Lang.getSingleton().lang === "zh" ? "English" : "中文"} -

-

- Powered by - logo - {Lang.t("eyeblueTank")} - -

-
- ) - } +

this.changeLang()}> + {Lang.getSingleton().lang === "zh" ? "English" : "中文"} +

+

+ Powered by + logo + {Lang.t("eyeblueTank")} + +

+
+ ) + } } diff --git a/src/pages/layout/widget/Capacity.less b/src/pages/layout/widget/Capacity.less index 9c2fa1d..b51fc36 100644 --- a/src/pages/layout/widget/Capacity.less +++ b/src/pages/layout/widget/Capacity.less @@ -1,11 +1,12 @@ .widget-capacity { - position: absolute; - bottom: 40px; - left: 0; - right: 0; - color: #fff; - padding: 0 24px; - .capacity-text { - color: rgba(255, 255, 255, 0.65); - } + position: absolute; + bottom: 40px; + left: 0; + right: 0; + color: #fff; + padding: 0 24px; + + .capacity-text { + color: rgba(255, 255, 255, 0.65); + } } diff --git a/src/pages/layout/widget/Capacity.tsx b/src/pages/layout/widget/Capacity.tsx index 5b67dc4..ddf42d0 100644 --- a/src/pages/layout/widget/Capacity.tsx +++ b/src/pages/layout/widget/Capacity.tsx @@ -1,15 +1,17 @@ import React from 'react'; -import { Progress } from 'antd'; +import {Progress} from 'antd'; import TankComponent from '../../../common/component/TankComponent'; import FileUtil from '../../../common/util/FileUtil'; import Moon from '../../../common/model/global/Moon'; import User from '../../../common/model/user/User'; -import { debounce } from '../../../common/util/OptimizeUtil'; +import {debounce} from '../../../common/util/OptimizeUtil'; import './Capacity.less'; -interface IProps {} +interface IProps { +} -interface IState {} +interface IState { +} export default class Capacity extends TankComponent { user: User = Moon.getSingleton().user; @@ -26,7 +28,7 @@ export default class Capacity extends TankComponent { } render() { - const { user } = this; + const {user} = this; return (
{user.totalSizeLimit !== -1 && ( diff --git a/src/pages/matter/Detail.tsx b/src/pages/matter/Detail.tsx index af19c86..c891afb 100644 --- a/src/pages/matter/Detail.tsx +++ b/src/pages/matter/Detail.tsx @@ -1,9 +1,9 @@ import React from "react"; -import { RouteComponentProps } from "react-router-dom"; +import {RouteComponentProps} from "react-router-dom"; import "./Detail.less"; import TankComponent from "../../common/component/TankComponent"; import Matter from "../../common/model/matter/Matter"; -import { Space, Spin, Tag } from "antd"; +import {Space, Spin, Tag} from "antd"; import StringUtil from "../../common/util/StringUtil"; import TankTitle from "../widget/TankTitle"; import DownloadToken from "../../common/model/download/token/DownloadToken"; @@ -17,130 +17,132 @@ import TankContentCard from "../widget/TankContentCard"; import Color from "../../common/model/base/option/Color"; interface RouteParam { - uuid: string; + uuid: string; } -interface IProps extends RouteComponentProps {} +interface IProps extends RouteComponentProps { +} -interface IState {} +interface IState { +} export default class Detail extends TankComponent { - matter = new Matter(); - downloadToken = new DownloadToken(); + matter = new Matter(); + downloadToken = new DownloadToken(); - constructor(props: IProps) { - super(props); - this.state = {}; - } + constructor(props: IProps) { + super(props); + this.state = {}; + } - componentDidMount() { - const { uuid } = this.props.match.params; - this.matter.uuid = uuid; - let that = this; - this.matter.httpDetail((response: any) => { - that.updateUI(); - if (!response.data.data.dir) { - that.downloadToken.httpFetchDownloadToken(that.matter.uuid!); - } - }); - } + componentDidMount() { + const {uuid} = this.props.match.params; + this.matter.uuid = uuid; + let that = this; + this.matter.httpDetail((response: any) => { + that.updateUI(); + if (!response.data.data.dir) { + that.downloadToken.httpFetchDownloadToken(that.matter.uuid!); + } + }); + } - copyLink() { - const { privacy } = this.matter; - const textToCopy = this.matter.getDownloadUrl( - privacy ? this.downloadToken.uuid! : undefined - ); - ClipboardUtil.copy(textToCopy, () => { - MessageBoxUtil.success(Lang.t("copySuccess")); - }); - }; + copyLink() { + const {privacy} = this.matter; + const textToCopy = this.matter.getDownloadUrl( + privacy ? this.downloadToken.uuid! : undefined + ); + ClipboardUtil.copy(textToCopy, () => { + MessageBoxUtil.success(Lang.t("copySuccess")); + }); + }; - recovery() { - this.matter.httpRecovery(() => { - this.matter.httpDetail(() => { - this.updateUI(); - }); - MessageBoxUtil.success(Lang.t("copySuccess")); - }); - }; + recovery() { + this.matter.httpRecovery(() => { + this.matter.httpDetail(() => { + this.updateUI(); + }); + MessageBoxUtil.success(Lang.t("copySuccess")); + }); + }; - render() { - const { matter } = this; - return ( - -
- + render() { + const {matter} = this; + return ( + +
+ - -
- - {matter.name} - {matter.deleted && ( - - {Lang.t("matter.deleted")} - - )} - - {matter.path} - - {DateUtil.simpleDateTime(matter.createTime)} - - - {DateUtil.simpleDateTime(matter.updateTime)} - - {matter.deleted && ( - - {DateUtil.simpleDateTime(matter.deleteTime)} - - )} - - {StringUtil.humanFileSize(matter.size)} - - {!matter.dir ? ( - <> - - {matter.privacy - ? Lang.t("matter.privateInfo") - : Lang.t("matter.publicInfo")} - - - {matter.times} - - - - matter.download()}> - {Lang.t("matter.download")} - - matter.preview()}> - {Lang.t("matter.preview")} - - this.copyLink()}> - {matter.privacy - ? Lang.t("matter.oneTimeLink") - : Lang.t("matter.copyPath")} - - {matter.deleted ? ( - this.recovery()}> - {Lang.t("matter.recovery")} - - ) : null} - - - - ) : null} - {matter.dir && matter.deleted && ( - - this.recovery()}>{Lang.t("matter.recovery")} - - )} -
-
-
+ +
+ + {matter.name} + {matter.deleted && ( + + {Lang.t("matter.deleted")} + + )} + + {matter.path} + + {DateUtil.simpleDateTime(matter.createTime)} + + + {DateUtil.simpleDateTime(matter.updateTime)} + + {matter.deleted && ( + + {DateUtil.simpleDateTime(matter.deleteTime)} + + )} + + {StringUtil.humanFileSize(matter.size)} + + {!matter.dir ? ( + <> + + {matter.privacy + ? Lang.t("matter.privateInfo") + : Lang.t("matter.publicInfo")} + + + {matter.times} + + + + matter.download()}> + {Lang.t("matter.download")} + + matter.preview()}> + {Lang.t("matter.preview")} + + this.copyLink()}> + {matter.privacy + ? Lang.t("matter.oneTimeLink") + : Lang.t("matter.copyPath")} + + {matter.deleted ? ( + this.recovery()}> + {Lang.t("matter.recovery")} + + ) : null} + + + + ) : null} + {matter.dir && matter.deleted && ( + + this.recovery()}>{Lang.t("matter.recovery")} + + )} +
+
+
- {!matter.dir && matter.uuid && matter.isImage() ? ( - - ) : null} -
- ); - } + {!matter.dir && matter.uuid && matter.isImage() ? ( + + ) : null} + + ); + } } diff --git a/src/pages/matter/List.less b/src/pages/matter/List.less index 2ff71ef..c1cdec8 100644 --- a/src/pages/matter/List.less +++ b/src/pages/matter/List.less @@ -11,9 +11,11 @@ align-items: center; background: rgba(0, 0, 0, 0.5); } + .ant-upload { display: inline-block; } + .buttons { display: flex; flex-wrap: wrap; diff --git a/src/pages/matter/List.tsx b/src/pages/matter/List.tsx index 230e654..6aac07a 100644 --- a/src/pages/matter/List.tsx +++ b/src/pages/matter/List.tsx @@ -1,5 +1,5 @@ -import React, { Children } from "react"; -import { RouteComponentProps } from "react-router-dom"; +import React, {Children} from "react"; +import {RouteComponentProps} from "react-router-dom"; import "./List.less"; import TankComponent from "../../common/component/TankComponent"; import Pager from "../../common/model/base/Pager"; @@ -9,33 +9,23 @@ import Director from "./widget/Director"; import SortDirection from "../../common/model/base/SortDirection"; import MatterPanel from "./widget/MatterPanel"; import UploadMatterPanel from "./widget/UploadMatterPanel"; -import { - Button, - Col, - Empty, - Input, - Modal, - Pagination, - Row, - Space, - Upload, -} from "antd"; +import {Button, Col, Empty, Input, Modal, Pagination, Row, Space, Upload,} from "antd"; import MessageBoxUtil from "../../common/util/MessageBoxUtil"; import { - CloudUploadOutlined, - DeleteOutlined, - DownloadOutlined, - DragOutlined, - ExclamationCircleFilled, - FolderOutlined, - MinusSquareOutlined, - PlusSquareOutlined, - ShareAltOutlined, - SyncOutlined, + CloudUploadOutlined, + DeleteOutlined, + DownloadOutlined, + DragOutlined, + ExclamationCircleFilled, + FolderOutlined, + MinusSquareOutlined, + PlusSquareOutlined, + ShareAltOutlined, + SyncOutlined, } from "@ant-design/icons"; import ImagePreviewer from "../widget/previewer/ImagePreviewer"; import Sun from "../../common/model/global/Sun"; -import { UserRole } from "../../common/model/user/UserRole"; +import {UserRole} from "../../common/model/user/UserRole"; import StringUtil from "../../common/util/StringUtil"; import MoveBatchModal from "./widget/MoveBatchModal"; import ShareOperationModal from "./widget/ShareOperationModal"; @@ -48,667 +38,670 @@ import Lang from "../../common/model/global/Lang"; import FileUtil from "../../common/util/FileUtil"; import SafeUtil from "../../common/util/SafeUtil"; import MatterSortPanel from "./widget/MatterSortPanel"; -import { UploadRequestOption as RcCustomRequestOptions } from "rc-upload/lib/interface"; +import {UploadRequestOption as RcCustomRequestOptions} from "rc-upload/lib/interface"; import Capacity from "../layout/widget/Capacity"; -interface IProps extends RouteComponentProps {} +interface IProps extends RouteComponentProps { +} -interface IState {} +interface IState { +} export default class List extends TankComponent { - //当前文件夹信息。 - matter = new Matter(); - //准备新建的文件。 - newMatter = new Matter(); + //当前文件夹信息。 + matter = new Matter(); + //准备新建的文件。 + newMatter = new Matter(); - //当前选中的文件 - selectedMatters: Matter[] = []; - //搜索的文字 - searchText: string | null = null; - //获取分页的一个帮助器 - pager = new Pager(this, Matter, Pager.MAX_PAGE_SIZE); - user = Moon.getSingleton().user; - preference = Moon.getSingleton().preference; - //导演 - director = new Director(); - //当前面包屑模型数组。 - breadcrumbModels: BreadcrumbModel[] = []; - //分享 - share = new Share(); + //当前选中的文件 + selectedMatters: Matter[] = []; + //搜索的文字 + searchText: string | null = null; + //获取分页的一个帮助器 + pager = new Pager(this, Matter, Pager.MAX_PAGE_SIZE); + user = Moon.getSingleton().user; + preference = Moon.getSingleton().preference; + //导演 + director = new Director(); + //当前面包屑模型数组。 + breadcrumbModels: BreadcrumbModel[] = []; + //分享 + share = new Share(); - newMatterRef = React.createRef(); - //用来判断是否展示遮罩层 - dragEnterCount = 0; + newMatterRef = React.createRef(); + //用来判断是否展示遮罩层 + dragEnterCount = 0; - //临时文件list,用于上传文件夹功能 - tempUploadList: File[] = []; + //临时文件list,用于上传文件夹功能 + tempUploadList: File[] = []; - //上传错误日志 - uploadErrorLogs: [string, string, string][] = []; + //上传错误日志 + uploadErrorLogs: [string, string, string][] = []; - //准备上传的一系列文件 - static uploadMatters: Matter[] = []; + //准备上传的一系列文件 + static uploadMatters: Matter[] = []; - //持有全局唯一的实例。 - static instance: List | null = null; + //持有全局唯一的实例。 + static instance: List | null = null; - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - List.instance = this; - } - - //拖拽上传 - drag = { - dragEnterListener: (e: DragEvent) => { - e.preventDefault(); - this.dragEnterCount++; - if (this.dragEnterCount > 0) this.updateUI(); - }, - dragleaveListener: (e: DragEvent) => { - e.preventDefault(); - this.dragEnterCount--; - if (this.dragEnterCount <= 0) this.updateUI(); - }, - dragoverListener: (e: DragEvent) => { - e.preventDefault(); - }, - dropListener: (e: DragEvent) => { - e.preventDefault(); - this.dragEnterCount = 0; - this.launchUpload(e.dataTransfer!.files); - this.updateUI(); - }, - register: () => { - const { - dragEnterListener, - dragleaveListener, - dragoverListener, - dropListener, - } = this.drag; - const el = document.getElementById("layout-content")!; - el.addEventListener("dragenter", dragEnterListener); - el.addEventListener("dragleave", dragleaveListener); - el.addEventListener("dragover", dragoverListener); - el.addEventListener("drop", dropListener); - }, - remove: () => { - const { - dragEnterListener, - dragleaveListener, - dragoverListener, - dropListener, - } = this.drag; - const el = document.getElementById("layout-content")!; - el.removeEventListener("dragenter", dragEnterListener); - el.removeEventListener("dragleave", dragleaveListener); - el.removeEventListener("dragover", dragoverListener); - el.removeEventListener("drop", dropListener); - }, - }; - - componentDidMount() { - //刷新一下列表 - if (this.user.role === UserRole.ADMINISTRATOR) { - this.pager.getFilter("userUuid")!.visible = true; - } else { - this.pager.setFilterValue("userUuid", this.user.uuid); - } - this.pager.enableHistory(); - this.refresh(); - this.drag.register(); - } - - componentWillReceiveProps(nextProps: Readonly, nextContext: any) { - if (this.props.location.search !== nextProps.location.search) { - this.pager.enableHistory(); - this.refresh(); - } - } - - componentWillUnmount() { - this.drag.remove(); - } - - refresh() { - // 清空暂存区 - this.selectedMatters = []; - // 刷新文件列表 - this.refreshPager(); - // 刷新面包屑 - this.refreshBreadcrumbs(); - } - - refreshPager() { - // 初始化当前matter uuid - if (this.matter.uuid !== this.pager.getFilterValue("puuid")) { - this.matter.uuid = - this.pager.getFilterValue("puuid") || Matter.MATTER_ROOT; + List.instance = this; } - this.pager.setFilterValue("puuid", this.matter.uuid); - - //如果没有任何的排序,默认使用时间倒序和文件夹在顶部 - if (!this.pager.getCurrentSortFilter()) { - this.pager.setFilterValue("orderCreateTime", SortDirection.DESC); - this.pager.setFilterValue("orderDir", SortDirection.DESC); - } - - // 过滤掉被软删除的文件 - this.pager.setFilterValue("deleted", false); - - this.pager.httpList(); - } - - checkMatter(matter?: Matter) { - if (matter) { - if (matter.check) { - this.selectedMatters.push(matter); - } else { - const index = this.selectedMatters.findIndex( - (item) => item.uuid === matter.uuid - ); - this.selectedMatters.splice(index, 1); - } - } else { - //统计所有的勾选 - this.selectedMatters = []; - this.pager.data.forEach((matter) => { - if (matter.check) { - this.selectedMatters.push(matter); - } - }); - } - this.updateUI(); - } - - checkAll() { - this.pager.data.forEach((i) => { - i.check = true; - }); - this.checkMatter(); - } - - checkNone() { - this.pager.data.forEach((i) => { - i.check = false; - }); - this.checkMatter(); - } - - deleteBatch() { - const uuids = this.selectedMatters.map((i) => i.uuid).toString(); - MatterDeleteModal.open( - () => { - this.matter.httpSoftDeleteBatch(uuids, () => { - MessageBoxUtil.success(Lang.t("operationSuccess")); - Capacity.instance?.refresh(); - this.refresh(); - }); - }, - () => { - this.matter.httpDeleteBatch(uuids, () => { - MessageBoxUtil.success(Lang.t("operationSuccess")); - Capacity.instance?.refresh(); - this.refresh(); - }); - } - ); - } - - downloadZip() { - const uuids = this.selectedMatters.map((i) => i.uuid).toString(); - Matter.downloadZip(uuids); - } - - toggleMoveBatch() { - MoveBatchModal.open((targetUuid) => { - const uuids = this.selectedMatters.map((i) => i.uuid).join(","); - this.matter.httpMove(uuids, targetUuid, () => { - MessageBoxUtil.success(Lang.t("operationSuccess")); - this.refresh(); - }); - }); - } - - triggerUpload(fileObj: RcCustomRequestOptions) { - const { file } = fileObj; - if (file) this.launchUpload(file as any); - } - - debounce(func: Function, wait: number) { - let timer: any = null; - return (fileObj: any) => { - const { file } = fileObj; - this.tempUploadList.push(file); - if (timer) { - clearTimeout(timer); - } - timer = setTimeout(func, wait); + //拖拽上传 + drag = { + dragEnterListener: (e: DragEvent) => { + e.preventDefault(); + this.dragEnterCount++; + if (this.dragEnterCount > 0) this.updateUI(); + }, + dragleaveListener: (e: DragEvent) => { + e.preventDefault(); + this.dragEnterCount--; + if (this.dragEnterCount <= 0) this.updateUI(); + }, + dragoverListener: (e: DragEvent) => { + e.preventDefault(); + }, + dropListener: (e: DragEvent) => { + e.preventDefault(); + this.dragEnterCount = 0; + this.launchUpload(e.dataTransfer!.files); + this.updateUI(); + }, + register: () => { + const { + dragEnterListener, + dragleaveListener, + dragoverListener, + dropListener, + } = this.drag; + const el = document.getElementById("layout-content")!; + el.addEventListener("dragenter", dragEnterListener); + el.addEventListener("dragleave", dragleaveListener); + el.addEventListener("dragover", dragoverListener); + el.addEventListener("drop", dropListener); + }, + remove: () => { + const { + dragEnterListener, + dragleaveListener, + dragoverListener, + dropListener, + } = this.drag; + const el = document.getElementById("layout-content")!; + el.removeEventListener("dragenter", dragEnterListener); + el.removeEventListener("dragleave", dragleaveListener); + el.removeEventListener("dragover", dragoverListener); + el.removeEventListener("drop", dropListener); + }, }; - } - triggerUploadDir = this.debounce(async () => { - await this.uploadDirectory(); - if (!this.uploadErrorLogs.length) { - MessageBoxUtil.success(Lang.t("matter.uploaded")); - } else { - // 上传错误弹出提示框 - const url = FileUtil.getErrorLogsToCSVUrl(this.uploadErrorLogs); - Modal.confirm({ - title: Lang.t("matter.uploadInfo"), - icon: , - content: Lang.t("matter.uploadErrorInfo"), - okText: Lang.t("matter.exportCSV"), - onOk: () => { - if (url) { - window.open(url); - } else { - MessageBoxUtil.warn(Lang.t("matter.unCompatibleBrowser")); - } - }, - }); - } - this.tempUploadList = []; - this.uploadErrorLogs = []; - this.refresh(); - }, 0); - - async uploadDirectory() { - const dirPathUuidMap: any = {}; // 存储已经创建好的文件夹map - for (let i = 0; i < this.tempUploadList.length; i++) { - const file: File = this.tempUploadList[i]; - const paths = file.webkitRelativePath.split("/"); - const pPaths = paths.slice(0, paths.length - 1); - const pPathStr = pPaths.join("/"); - if (!dirPathUuidMap[pPathStr]) { - // 递归创建其父文件夹 - for (let j = 1; j <= pPaths.length; j++) { - const midPaths = pPaths.slice(0, j); - const midPathStr = midPaths.join("/"); - if (!dirPathUuidMap[midPathStr]) { - const m = new Matter(this); - m.name = midPaths[midPaths.length - 1]; - m.puuid = - j > 1 - ? dirPathUuidMap[midPaths.slice(0, j - 1).join("/")] - : this.matter.uuid!; - m.userUuid = this.user.uuid!; - await m.httpCreateDirectory( - () => { - dirPathUuidMap[midPathStr] = m.uuid; - }, - (msg: string) => { - this.uploadErrorLogs.push([ - file.name, - file.webkitRelativePath, - msg, - ]); - } - ); - } + componentDidMount() { + //刷新一下列表 + if (this.user.role === UserRole.ADMINISTRATOR) { + this.pager.getFilter("userUuid")!.visible = true; + } else { + this.pager.setFilterValue("userUuid", this.user.uuid); } - } - if (dirPathUuidMap[pPathStr]) { - this.launchUpload(file, dirPathUuidMap[pPathStr], (msg?: string) => { - this.uploadErrorLogs.push([ - file.name, - file.webkitRelativePath, - `${msg}`, - ]); - }); - } + this.pager.enableHistory(); + this.refresh(); + this.drag.register(); } - } - launchUpload( - f: File | FileList, - puuid = this.matter.uuid!, - errHandle = () => {} - ) { - const files = f instanceof FileList ? f : [f]; - for (let i = 0; i < files.length; i++) { - const file = files[i]; - console.log(file); - // 判断文件是否是文件夹,是的话则停止上传 - const fileReader = new FileReader(); - fileReader.readAsDataURL(files[i].slice(0, 3)); - fileReader.onerror = () => { - MessageBoxUtil.error(Lang.t("matter.dropNotDirectory")); - }; - fileReader.onload = () => { - const m = new Matter(this); - m.dir = false; - m.puuid = puuid; - m.userUuid = this.user.uuid!; - - //判断文件大小。 - if (this.user.sizeLimit >= 0) { - if (file.size > this.user.sizeLimit) { - MessageBoxUtil.error( - Lang.t( - "matter.sizeExceedLimit", - StringUtil.humanFileSize(file.size), - StringUtil.humanFileSize(this.user.sizeLimit) - ) - ); - return; - } + componentWillReceiveProps(nextProps: Readonly, nextContext: any) { + if (this.props.location.search !== nextProps.location.search) { + this.pager.enableHistory(); + this.refresh(); } - m.file = file; - m.httpUpload( - () => { - const index = List.uploadMatters.findIndex( - (matter) => matter === m - ); - List.uploadMatters.splice(index, 1); - List.instance?.refresh(); - Capacity.instance?.refresh(); - }, - (msg: string) => { - List.instance?.updateUI(); - SafeUtil.safeCallback(errHandle)(msg); - } - ); - - List.uploadMatters.push(m); - }; } - } - shareBatch() { - const uuids = this.selectedMatters.map((i) => i.uuid).join(","); - ShareOperationModal.open((share: Share) => { - share.httpCreate(uuids, () => { - ShareDialogModal.open(share); - }); - }); - } - - searchFile(value?: string) { - this.pager.resetFilter(); - if (value) { - this.pager.setFilterValue("orderCreateTime", SortDirection.DESC); - this.pager.setFilterValue("orderDir", SortDirection.DESC); - this.pager.setFilterValue("name", value); - this.pager.httpList(); - } else { - this.refresh(); + componentWillUnmount() { + this.drag.remove(); } - } - changeSearch(e: any) { - if (!e.currentTarget.value) this.searchFile(); - } + refresh() { + // 清空暂存区 + this.selectedMatters = []; + // 刷新文件列表 + this.refreshPager(); + // 刷新面包屑 + this.refreshBreadcrumbs(); + } - changePage(page: number) { - this.pager.page = page - 1; // page的页数0基 - this.pager.httpList(); - this.updateUI(); - } - - createDirectory() { - this.newMatter.name = "matter.allFiles"; - this.newMatter.dir = true; - this.newMatter.editMode = true; - this.newMatter.puuid = this.matter.uuid || "root"; - this.newMatter.userUuid = this.user.uuid!; - this.director.createMode = true; - - this.updateUI(); - setTimeout(() => this.newMatterRef.current!.highLight()); - } - - previewImage(matter: Matter) { - let imageArray: string[] = []; - let startIndex = -1; - this.pager.data.forEach((item) => { - if (item.isImage()) { - imageArray.push(item.getPreviewUrl()); - if (item.uuid === matter.uuid) { - startIndex = imageArray.length - 1; + refreshPager() { + // 初始化当前matter uuid + if (this.matter.uuid !== this.pager.getFilterValue("puuid")) { + this.matter.uuid = + this.pager.getFilterValue("puuid") || Matter.MATTER_ROOT; } - } - }); - ImagePreviewer.showMultiPhoto(imageArray, startIndex); - } + this.pager.setFilterValue("puuid", this.matter.uuid); - delete() { - Capacity.instance?.refresh(); - this.refresh(); - } + //如果没有任何的排序,默认使用时间倒序和文件夹在顶部 + if (!this.pager.getCurrentSortFilter()) { + this.pager.setFilterValue("orderCreateTime", SortDirection.DESC); + this.pager.setFilterValue("orderDir", SortDirection.DESC); + } - goToDirectory(id: string) { - this.searchText = null; - this.pager.setFilterValue("puuid", id); - this.pager.setFilterValue("name", null); - this.pager.page = 0; - const query = this.pager.getParams(); - Sun.navigateQueryTo({ path: "/matter/list", query }); - this.refresh(); - } + // 过滤掉被软删除的文件 + this.pager.setFilterValue("deleted", false); - //刷新面包屑 - refreshBreadcrumbs() { - const uuid = this.pager.getFilterValue("puuid") || Matter.MATTER_ROOT; + this.pager.httpList(); + } - //根目录简单处理即可。 - if (uuid === Matter.MATTER_ROOT) { - this.matter.uuid = Matter.MATTER_ROOT; - this.breadcrumbModels = [ - { - name: Lang.t("matter.allFiles"), - path: "/matter/list", - query: {}, - displayDirect: true, - }, - ]; - } else { - this.matter.uuid = uuid; - this.matter.httpDetail(() => { - const arr = []; - let cur: Matter | null = this.matter; - do { - arr.push(cur); - cur = cur.parent; - } while (cur); - - this.breadcrumbModels = arr.reduceRight( - (t: any, item: Matter, i: number) => { - const query = this.pager.getParams(); - query["puuid"] = item.uuid!; - t.push({ - name: item.name, - path: "/matter/list", - query: query, - displayDirect: !i, // 当前目录不需要导航 + checkMatter(matter?: Matter) { + if (matter) { + if (matter.check) { + this.selectedMatters.push(matter); + } else { + const index = this.selectedMatters.findIndex( + (item) => item.uuid === matter.uuid + ); + this.selectedMatters.splice(index, 1); + } + } else { + //统计所有的勾选 + this.selectedMatters = []; + this.pager.data.forEach((matter) => { + if (matter.check) { + this.selectedMatters.push(matter); + } }); - return t; - }, - [ - { - name: Lang.t("matter.allFiles"), - path: "/matter/list", - query: {}, - displayDirect: false, - }, - ] - ); + } this.updateUI(); - }); } - } - render() { - const { pager, director, selectedMatters, dragEnterCount } = this; - return ( -
- {dragEnterCount > 0 ? ( -
- -
- ) : null} - + checkAll() { + this.pager.data.forEach((i) => { + i.check = true; + }); + this.checkMatter(); + } - - - - {selectedMatters.length !== pager.data.length ? ( - - ) : null} - {pager.data.length && - selectedMatters.length === pager.data.length ? ( - - ) : null} - {selectedMatters.length ? ( - <> - + checkNone() { + this.pager.data.forEach((i) => { + i.check = false; + }); + this.checkMatter(); + } - + deleteBatch() { + const uuids = this.selectedMatters.map((i) => i.uuid).toString(); + MatterDeleteModal.open( + () => { + this.matter.httpSoftDeleteBatch(uuids, () => { + MessageBoxUtil.success(Lang.t("operationSuccess")); + Capacity.instance?.refresh(); + this.refresh(); + }); + }, + () => { + this.matter.httpDeleteBatch(uuids, () => { + MessageBoxUtil.success(Lang.t("operationSuccess")); + Capacity.instance?.refresh(); + this.refresh(); + }); + } + ); + } - + downloadZip() { + const uuids = this.selectedMatters.map((i) => i.uuid).toString(); + Matter.downloadZip(uuids); + } - - - ) : null} + toggleMoveBatch() { + MoveBatchModal.open((targetUuid) => { + const uuids = this.selectedMatters.map((i) => i.uuid).join(","); + this.matter.httpMove(uuids, targetUuid, () => { + MessageBoxUtil.success(Lang.t("operationSuccess")); + this.refresh(); + }); + }); + } - this.triggerUpload(e)} - showUploadList={false} - multiple - > - - - - - - + triggerUpload(fileObj: RcCustomRequestOptions) { + const {file} = fileObj; + if (file) this.launchUpload(file as any); + } - - - - - this.searchFile(value)} - onChange={(e) => this.changeSearch(e)} - enterButton - /> - - + debounce(func: Function, wait: number) { + let timer: any = null; + return (fileObj: any) => { + const {file} = fileObj; + this.tempUploadList.push(file); + if (timer) { + clearTimeout(timer); + } + timer = setTimeout(func, wait); + }; + } - {Children.toArray( - List.uploadMatters.map((m) => ) - )} + triggerUploadDir = this.debounce(async () => { + await this.uploadDirectory(); + if (!this.uploadErrorLogs.length) { + MessageBoxUtil.success(Lang.t("matter.uploaded")); + } else { + // 上传错误弹出提示框 + const url = FileUtil.getErrorLogsToCSVUrl(this.uploadErrorLogs); + Modal.confirm({ + title: Lang.t("matter.uploadInfo"), + icon: , + content: Lang.t("matter.uploadErrorInfo"), + okText: Lang.t("matter.exportCSV"), + onOk: () => { + if (url) { + window.open(url); + } else { + MessageBoxUtil.warn(Lang.t("matter.unCompatibleBrowser")); + } + }, + }); + } + this.tempUploadList = []; + this.uploadErrorLogs = []; + this.refresh(); + }, 0); - {pager.data.length ? ( - this.refresh()} /> - ) : null} + async uploadDirectory() { + const dirPathUuidMap: any = {}; // 存储已经创建好的文件夹map + for (let i = 0; i < this.tempUploadList.length; i++) { + const file: File = this.tempUploadList[i]; + const paths = file.webkitRelativePath.split("/"); + const pPaths = paths.slice(0, paths.length - 1); + const pPathStr = pPaths.join("/"); + if (!dirPathUuidMap[pPathStr]) { + // 递归创建其父文件夹 + for (let j = 1; j <= pPaths.length; j++) { + const midPaths = pPaths.slice(0, j); + const midPathStr = midPaths.join("/"); + if (!dirPathUuidMap[midPathStr]) { + const m = new Matter(this); + m.name = midPaths[midPaths.length - 1]; + m.puuid = + j > 1 + ? dirPathUuidMap[midPaths.slice(0, j - 1).join("/")] + : this.matter.uuid!; + m.userUuid = this.user.uuid!; + await m.httpCreateDirectory( + () => { + dirPathUuidMap[midPathStr] = m.uuid; + }, + (msg: string) => { + this.uploadErrorLogs.push([ + file.name, + file.webkitRelativePath, + msg, + ]); + } + ); + } + } + } + if (dirPathUuidMap[pPathStr]) { + this.launchUpload(file, dirPathUuidMap[pPathStr], (msg?: string) => { + this.uploadErrorLogs.push([ + file.name, + file.webkitRelativePath, + `${msg}`, + ]); + }); + } + } + } - {director.createMode ? ( - this.refresh()} - /> - ) : null} -
- {pager.loading || pager.data.length ? ( - pager.data.map((matter) => ( - this.goToDirectory(id)} - onDeleteSuccess={() => this.delete()} - onCheckMatter={(m) => this.checkMatter(m)} - onPreviewImage={(m) => this.previewImage(m)} - /> - )) - ) : ( - - )} -
- this.changePage(page)} - current={pager.page + 1} - total={pager.totalItems} - pageSize={pager.pageSize} - hideOnSinglePage - /> -
- ); - } + launchUpload( + f: File | FileList, + puuid = this.matter.uuid!, + errHandle = () => { + } + ) { + const files = f instanceof FileList ? f : [f]; + for (let i = 0; i < files.length; i++) { + const file = files[i]; + console.log(file); + // 判断文件是否是文件夹,是的话则停止上传 + const fileReader = new FileReader(); + fileReader.readAsDataURL(files[i].slice(0, 3)); + fileReader.onerror = () => { + MessageBoxUtil.error(Lang.t("matter.dropNotDirectory")); + }; + fileReader.onload = () => { + const m = new Matter(this); + m.dir = false; + m.puuid = puuid; + m.userUuid = this.user.uuid!; + + //判断文件大小。 + if (this.user.sizeLimit >= 0) { + if (file.size > this.user.sizeLimit) { + MessageBoxUtil.error( + Lang.t( + "matter.sizeExceedLimit", + StringUtil.humanFileSize(file.size), + StringUtil.humanFileSize(this.user.sizeLimit) + ) + ); + return; + } + } + m.file = file; + m.httpUpload( + () => { + const index = List.uploadMatters.findIndex( + (matter) => matter === m + ); + List.uploadMatters.splice(index, 1); + List.instance?.refresh(); + Capacity.instance?.refresh(); + }, + (msg: string) => { + List.instance?.updateUI(); + SafeUtil.safeCallback(errHandle)(msg); + } + ); + + List.uploadMatters.push(m); + }; + } + } + + shareBatch() { + const uuids = this.selectedMatters.map((i) => i.uuid).join(","); + ShareOperationModal.open((share: Share) => { + share.httpCreate(uuids, () => { + ShareDialogModal.open(share); + }); + }); + } + + searchFile(value?: string) { + this.pager.resetFilter(); + if (value) { + this.pager.setFilterValue("orderCreateTime", SortDirection.DESC); + this.pager.setFilterValue("orderDir", SortDirection.DESC); + this.pager.setFilterValue("name", value); + this.pager.httpList(); + } else { + this.refresh(); + } + } + + changeSearch(e: any) { + if (!e.currentTarget.value) this.searchFile(); + } + + changePage(page: number) { + this.pager.page = page - 1; // page的页数0基 + this.pager.httpList(); + this.updateUI(); + } + + createDirectory() { + this.newMatter.name = "matter.allFiles"; + this.newMatter.dir = true; + this.newMatter.editMode = true; + this.newMatter.puuid = this.matter.uuid || "root"; + this.newMatter.userUuid = this.user.uuid!; + this.director.createMode = true; + + this.updateUI(); + setTimeout(() => this.newMatterRef.current!.highLight()); + } + + previewImage(matter: Matter) { + let imageArray: string[] = []; + let startIndex = -1; + this.pager.data.forEach((item) => { + if (item.isImage()) { + imageArray.push(item.getPreviewUrl()); + if (item.uuid === matter.uuid) { + startIndex = imageArray.length - 1; + } + } + }); + + ImagePreviewer.showMultiPhoto(imageArray, startIndex); + } + + delete() { + Capacity.instance?.refresh(); + this.refresh(); + } + + goToDirectory(id: string) { + this.searchText = null; + this.pager.setFilterValue("puuid", id); + this.pager.setFilterValue("name", null); + this.pager.page = 0; + const query = this.pager.getParams(); + Sun.navigateQueryTo({path: "/matter/list", query}); + this.refresh(); + } + + //刷新面包屑 + refreshBreadcrumbs() { + const uuid = this.pager.getFilterValue("puuid") || Matter.MATTER_ROOT; + + //根目录简单处理即可。 + if (uuid === Matter.MATTER_ROOT) { + this.matter.uuid = Matter.MATTER_ROOT; + this.breadcrumbModels = [ + { + name: Lang.t("matter.allFiles"), + path: "/matter/list", + query: {}, + displayDirect: true, + }, + ]; + } else { + this.matter.uuid = uuid; + this.matter.httpDetail(() => { + const arr = []; + let cur: Matter | null = this.matter; + do { + arr.push(cur); + cur = cur.parent; + } while (cur); + + this.breadcrumbModels = arr.reduceRight( + (t: any, item: Matter, i: number) => { + const query = this.pager.getParams(); + query["puuid"] = item.uuid!; + t.push({ + name: item.name, + path: "/matter/list", + query: query, + displayDirect: !i, // 当前目录不需要导航 + }); + return t; + }, + [ + { + name: Lang.t("matter.allFiles"), + path: "/matter/list", + query: {}, + displayDirect: false, + }, + ] + ); + this.updateUI(); + }); + } + } + + render() { + const {pager, director, selectedMatters, dragEnterCount} = this; + return ( +
+ {dragEnterCount > 0 ? ( +
+ +
+ ) : null} + + + + + + {selectedMatters.length !== pager.data.length ? ( + + ) : null} + {pager.data.length && + selectedMatters.length === pager.data.length ? ( + + ) : null} + {selectedMatters.length ? ( + <> + + + + + + + + + ) : null} + + this.triggerUpload(e)} + showUploadList={false} + multiple + > + + + + + + + + + + + + this.searchFile(value)} + onChange={(e) => this.changeSearch(e)} + enterButton + /> + + + + {Children.toArray( + List.uploadMatters.map((m) => ) + )} + + {pager.data.length ? ( + this.refresh()}/> + ) : null} + + {director.createMode ? ( + this.refresh()} + /> + ) : null} +
+ {pager.loading || pager.data.length ? ( + pager.data.map((matter) => ( + this.goToDirectory(id)} + onDeleteSuccess={() => this.delete()} + onCheckMatter={(m) => this.checkMatter(m)} + onPreviewImage={(m) => this.previewImage(m)} + /> + )) + ) : ( + + )} +
+ this.changePage(page)} + current={pager.page + 1} + total={pager.totalItems} + pageSize={pager.pageSize} + hideOnSinglePage + /> +
+ ); + } } diff --git a/src/pages/matter/widget/Director.ts b/src/pages/matter/widget/Director.ts index 5fc3c1b..1ac0025 100644 --- a/src/pages/matter/widget/Director.ts +++ b/src/pages/matter/widget/Director.ts @@ -1,14 +1,14 @@ //导演类,用户来让整个工作有序进行 export default class Director { //正在重命名 - renameMode:boolean = false + renameMode: boolean = false //正在创建新文件夹 - createMode:boolean = false + createMode: boolean = false //正在移动文件 - moveMode:boolean = false + moveMode: boolean = false - isEditing() { - return this.renameMode || this.createMode || this.moveMode - } + isEditing() { + return this.renameMode || this.createMode || this.moveMode + } } diff --git a/src/pages/matter/widget/MatterDeleteModal.tsx b/src/pages/matter/widget/MatterDeleteModal.tsx index b3110b1..25231c3 100644 --- a/src/pages/matter/widget/MatterDeleteModal.tsx +++ b/src/pages/matter/widget/MatterDeleteModal.tsx @@ -1,76 +1,77 @@ import React from "react"; import TankComponent from "../../../common/component/TankComponent"; -import { Modal, Button } from "antd"; +import {Button, Modal} from "antd"; import Lang from "../../../common/model/global/Lang"; import Moon from "../../../common/model/global/Moon"; -import { ExclamationCircleFilled } from "@ant-design/icons"; +import {ExclamationCircleFilled} from "@ant-design/icons"; import "./MatterDeleteModal.less"; import Preference from "../../../common/model/preference/Preference"; interface IProps { - onSoftDel: () => void; - onHardDel: () => void; - onClose: () => void; + onSoftDel: () => void; + onHardDel: () => void; + onClose: () => void; } -interface IState {} +interface IState { +} export default class MatterDeleteModal extends TankComponent { - constructor(props: IProps) { - super(props); - } + constructor(props: IProps) { + super(props); + } - static preference: Preference = Moon.getSingleton().preference; + static preference: Preference = Moon.getSingleton().preference; - static open(onSoftDel: () => void, onHardDel: () => void) { - let modal = Modal.warning({ - className: "delete-modal", - title: Lang.t("delete"), - icon: , - okCancel: false, - okButtonProps: { - className: "display-none", - }, - content: ( - { - onSoftDel(); - modal.destroy(); - }} - onHardDel={() => { - onHardDel(); - modal.destroy(); - }} - onClose={() => { - modal.destroy(); - }} - /> - ), - }); - } + static open(onSoftDel: () => void, onHardDel: () => void) { + let modal = Modal.warning({ + className: "delete-modal", + title: Lang.t("delete"), + icon: , + okCancel: false, + okButtonProps: { + className: "display-none", + }, + content: ( + { + onSoftDel(); + modal.destroy(); + }} + onHardDel={() => { + onHardDel(); + modal.destroy(); + }} + onClose={() => { + modal.destroy(); + }} + /> + ), + }); + } - render() { - return ( -
-

{Lang.t("actionDeleteConfirm")}

-
- - - {MatterDeleteModal.preference.getRecycleBinStatus() && ( - - )} -
-
- ); - } + render() { + return ( +
+

{Lang.t("actionDeleteConfirm")}

+
+ + + {MatterDeleteModal.preference.getRecycleBinStatus() && ( + + )} +
+
+ ); + } } diff --git a/src/pages/matter/widget/MatterImage.less b/src/pages/matter/widget/MatterImage.less index 55fc17b..b1551ce 100644 --- a/src/pages/matter/widget/MatterImage.less +++ b/src/pages/matter/widget/MatterImage.less @@ -1,16 +1,19 @@ .matter-image { .composite-box { display: flex; + .content { display: flex; flex-grow: 1; position: relative; + .text { display: flex; justify-content: center; align-content: center; } } + .ant-upload { position: absolute; left: 0; @@ -18,10 +21,12 @@ bottom: 0; top: 0; } + .border-short { border-top-right-radius: 0; border-bottom-right-radius: 0; } + .handle { flex-shrink: 0; border-bottom-left-radius: 0; diff --git a/src/pages/matter/widget/MatterImage.tsx b/src/pages/matter/widget/MatterImage.tsx index 946df09..4455684 100644 --- a/src/pages/matter/widget/MatterImage.tsx +++ b/src/pages/matter/widget/MatterImage.tsx @@ -3,127 +3,126 @@ import TankComponent from "../../../common/component/TankComponent"; import Moon from "../../../common/model/global/Moon"; import Matter from "../../../common/model/matter/Matter"; import ImagePreviewer from "../../widget/previewer/ImagePreviewer"; -import { Input, Upload, Button } from "antd"; +import {Button, Input, Upload} from "antd"; import UploadMatterPanel from "./UploadMatterPanel"; import "./MatterImage.less"; import MessageBoxUtil from "../../../common/util/MessageBoxUtil"; import SafeUtil from "../../../common/util/SafeUtil"; import Lang from "../../../common/model/global/Lang"; -import { - UploadRequestOption as RcCustomRequestOptions -} from 'rc-upload/lib/interface'; +import {UploadRequestOption as RcCustomRequestOptions} from 'rc-upload/lib/interface'; interface IProps { - value?: string; - onChange?: (value: string) => any; - preview?: boolean; //上传的照片是否需要预览 - previewWidth?: number; - filter?: string; - uploadHint?: string; + value?: string; + onChange?: (value: string) => any; + preview?: boolean; //上传的照片是否需要预览 + previewWidth?: number; + filter?: string; + uploadHint?: string; } -interface IState {} +interface IState { +} export default class MatterImage extends TankComponent { - // 是否手动上传模式 - manual = false; - matter = new Matter(this); - user = Moon.getSingleton().user; + // 是否手动上传模式 + manual = false; + matter = new Matter(this); + user = Moon.getSingleton().user; - constructor(props: IProps) { - super(props); - } - - changeLink(e: any) { - SafeUtil.safeCallback(this.props.onChange)(e.target.value); - }; - - triggerUpload(fileObj: RcCustomRequestOptions) { - const file = fileObj.file; - const { filter = "image", uploadHint = "" } = this.props; - if (file) { - - let fileSize = (file as any).size; - - if (this.user.sizeLimit >= 0 && fileSize > this.user.sizeLimit) { - MessageBoxUtil.error( - Lang.t("matter.sizeExceedLimit", fileSize, this.user.sizeLimit) - ); - return; - } - this.matter.assign({ - uploadHint, - filter, - file, - puuid: "root", - privacy: false, - dir: false, - alien: true, - userUuid: this.user.uuid, - }); - this.matter.httpUpload( - () => { - SafeUtil.safeCallback(this.props.onChange)( - this.matter.getPreviewUrl() - ); - this.matter = new Matter(); - this.updateUI(); - }, - () => this.updateUI() - ); + constructor(props: IProps) { + super(props); } - }; - toggleHandle() { - this.manual = !this.manual; - this.updateUI(); - }; + changeLink(e: any) { + SafeUtil.safeCallback(this.props.onChange)(e.target.value); + }; - render() { - const { manual, matter } = this; - const { - value, - preview = true, - previewWidth = 200, - uploadHint, - } = this.props; + triggerUpload(fileObj: RcCustomRequestOptions) { + const file = fileObj.file; + const {filter = "image", uploadHint = ""} = this.props; + if (file) { - return ( -
-
- {preview && value ? ( - ImagePreviewer.showSinglePhoto(value)} - /> - ) : null} -
-
- {manual ? ( - this.changeLink(e)} - /> - ) : ( - this.triggerUpload(e)} - showUploadList={false} - > - - - )} - -
- {uploadHint ?
{uploadHint}
: null} - -
- ); - } + let fileSize = (file as any).size; + + if (this.user.sizeLimit >= 0 && fileSize > this.user.sizeLimit) { + MessageBoxUtil.error( + Lang.t("matter.sizeExceedLimit", fileSize, this.user.sizeLimit) + ); + return; + } + this.matter.assign({ + uploadHint, + filter, + file, + puuid: "root", + privacy: false, + dir: false, + alien: true, + userUuid: this.user.uuid, + }); + this.matter.httpUpload( + () => { + SafeUtil.safeCallback(this.props.onChange)( + this.matter.getPreviewUrl() + ); + this.matter = new Matter(); + this.updateUI(); + }, + () => this.updateUI() + ); + } + }; + + toggleHandle() { + this.manual = !this.manual; + this.updateUI(); + }; + + render() { + const {manual, matter} = this; + const { + value, + preview = true, + previewWidth = 200, + uploadHint, + } = this.props; + + return ( +
+
+ {preview && value ? ( + ImagePreviewer.showSinglePhoto(value)} + /> + ) : null} +
+
+ {manual ? ( + this.changeLink(e)} + /> + ) : ( + this.triggerUpload(e)} + showUploadList={false} + > + + + )} + +
+ {uploadHint ?
{uploadHint}
: null} + +
+ ); + } } diff --git a/src/pages/matter/widget/MatterPanel.tsx b/src/pages/matter/widget/MatterPanel.tsx index 39896e9..c676ccc 100644 --- a/src/pages/matter/widget/MatterPanel.tsx +++ b/src/pages/matter/widget/MatterPanel.tsx @@ -10,582 +10,583 @@ import AnimateUtil from "../../../common/util/AnimateUtil"; import MessageBoxUtil from "../../../common/util/MessageBoxUtil"; import Expanding from "../../widget/Expanding"; import { - LockOutlined, - UnlockOutlined, - DownloadOutlined, - ExclamationCircleFilled, - LinkOutlined, - DeleteOutlined, - EditOutlined, - InfoCircleOutlined, - EllipsisOutlined, - RedoOutlined, - CloseCircleOutlined, + CloseCircleOutlined, + DeleteOutlined, + DownloadOutlined, + EditOutlined, + EllipsisOutlined, + ExclamationCircleFilled, + InfoCircleOutlined, + LinkOutlined, + LockOutlined, + RedoOutlined, + UnlockOutlined, } from "@ant-design/icons"; -import { Modal, Checkbox, Tooltip, Dropdown, Menu } from "antd"; -import { CheckboxChangeEvent } from "antd/es/checkbox"; +import {Checkbox, Dropdown, Menu, Modal, Tooltip} from "antd"; +import {CheckboxChangeEvent} from "antd/es/checkbox"; import SafeUtil from "../../../common/util/SafeUtil"; import ClipboardUtil from "../../../common/util/ClipboardUtil"; import Lang from "../../../common/model/global/Lang"; import MatterDeleteModal from "./MatterDeleteModal"; interface IProps { - matter: Matter; - recycleMode?: boolean; // 回收站模式,默认false,简化相关操作,不可进入文件夹里 - director?: Director; - onCreateDirectoryCallback?: () => any; - onDeleteSuccess?: () => any; - onRecoverySuccess?: () => any; - onCheckMatter?: (matter?: Matter) => any; - onPreviewImage?: (matter: Matter) => any; - onGoToDirectory?: (id: string) => any; + matter: Matter; + recycleMode?: boolean; // 回收站模式,默认false,简化相关操作,不可进入文件夹里 + director?: Director; + onCreateDirectoryCallback?: () => any; + onDeleteSuccess?: () => any; + onRecoverySuccess?: () => any; + onCheckMatter?: (matter?: Matter) => any; + onPreviewImage?: (matter: Matter) => any; + onGoToDirectory?: (id: string) => any; } -interface IState {} +interface IState { +} export default class MatterPanel extends TankComponent { - // 正在重命名的临时字段 - renameMatterName: string = ""; - // 正在向服务器提交rename的请求 - renamingLoading: boolean = false; - // 小屏幕下操作栏 - showMore: boolean = false; + // 正在重命名的临时字段 + renameMatterName: string = ""; + // 正在向服务器提交rename的请求 + renamingLoading: boolean = false; + // 小屏幕下操作栏 + showMore: boolean = false; - inputRef = React.createRef(); + inputRef = React.createRef(); - constructor(props: IProps) { - super(props); - this.state = {}; - } - - prepareRename() { - const { matter, director } = this.props; - if (director!.isEditing()) { - console.error("导演正忙着,不予执行"); - return; + constructor(props: IProps) { + super(props); + this.state = {}; } - //告诉导演,自己正在编辑 - director!.renameMode = true; - matter.editMode = true; - this.renameMatterName = matter.name!; - this.updateUI(); - setTimeout(() => { - if (!this.inputRef.current) return; - //如果是文件夹,全选中 - let dotIndex = matter.name!.lastIndexOf("."); - if (dotIndex === -1) { - AnimateUtil.setInputSelection( - this.inputRef.current, - 0, - this.renameMatterName.length + prepareRename() { + const {matter, director} = this.props; + if (director!.isEditing()) { + console.error("导演正忙着,不予执行"); + return; + } + + //告诉导演,自己正在编辑 + director!.renameMode = true; + matter.editMode = true; + this.renameMatterName = matter.name!; + this.updateUI(); + setTimeout(() => { + if (!this.inputRef.current) return; + //如果是文件夹,全选中 + let dotIndex = matter.name!.lastIndexOf("."); + if (dotIndex === -1) { + AnimateUtil.setInputSelection( + this.inputRef.current, + 0, + this.renameMatterName.length + ); + } else { + AnimateUtil.setInputSelection(this.inputRef.current, 0, dotIndex); + } + }); + } + + clipboard() { + let textToCopy = this.props.matter.getDownloadUrl(); + ClipboardUtil.copy(textToCopy, () => { + MessageBoxUtil.success(Lang.t("operationSuccess")); + }); + } + + deleteMatter() { + MatterDeleteModal.open( + () => { + this.props.matter.httpSoftDelete(() => { + MessageBoxUtil.success(Lang.t("operationSuccess")); + this.props.onDeleteSuccess!(); + }); + }, + () => { + this.props.matter.httpDelete(() => { + MessageBoxUtil.success(Lang.t("operationSuccess")); + this.props.onDeleteSuccess!(); + }); + } ); - } else { - AnimateUtil.setInputSelection(this.inputRef.current, 0, dotIndex); - } - }); - } + } - clipboard() { - let textToCopy = this.props.matter.getDownloadUrl(); - ClipboardUtil.copy(textToCopy, () => { - MessageBoxUtil.success(Lang.t("operationSuccess")); - }); - } - - deleteMatter() { - MatterDeleteModal.open( - () => { - this.props.matter.httpSoftDelete(() => { - MessageBoxUtil.success(Lang.t("operationSuccess")); - this.props.onDeleteSuccess!(); + hardDeleteMatter() { + Modal.confirm({ + title: Lang.t("actionCanNotRevertConfirm"), + icon: , + onOk: () => { + this.props.matter.httpDelete(() => { + MessageBoxUtil.success(Lang.t("operationSuccess")); + this.props.onDeleteSuccess!(); + }); + }, }); - }, - () => { - this.props.matter.httpDelete(() => { - MessageBoxUtil.success(Lang.t("operationSuccess")); - this.props.onDeleteSuccess!(); + } + + recoveryMatter() { + Modal.confirm({ + title: Lang.t("actionRecoveryConfirm"), + icon: , + onOk: () => { + this.props.matter.httpRecovery(() => { + MessageBoxUtil.success(Lang.t("operationSuccess")); + this.props.onRecoverySuccess!(); + }); + }, }); - } - ); - } + } - hardDeleteMatter() { - Modal.confirm({ - title: Lang.t("actionCanNotRevertConfirm"), - icon: , - onOk: () => { - this.props.matter.httpDelete(() => { - MessageBoxUtil.success(Lang.t("operationSuccess")); - this.props.onDeleteSuccess!(); + changeMatterName(e: any) { + this.renameMatterName = e.currentTarget.value; + this.updateUI(); + } + + finishRename() { + //有可能按enter的时候和blur同时了。 + if (this.renamingLoading) { + return; + } + const {matter, director} = this.props; + this.renamingLoading = true; + + matter.httpRename( + this.renameMatterName, + () => { + this.renamingLoading = false; + MessageBoxUtil.success(Lang.t("operationSuccess")); + //告诉导演,自己编辑完毕 + director!.renameMode = false; + matter.editMode = false; + }, + (msg: string) => { + this.renamingLoading = false; + MessageBoxUtil.error(msg); + //告诉导演,自己编辑完毕 + director!.renameMode = false; + matter.editMode = false; + }, + () => this.updateUI() + ); + } + + finishCreateDirectory() { + const {matter, director, onCreateDirectoryCallback} = this.props; + matter.name = this.renameMatterName; + matter.httpCreateDirectory( + () => { + director!.createMode = false; + matter.editMode = false; + matter.assign(new Matter()); + }, + (msg: string) => { + director!.createMode = false; + matter.editMode = false; + MessageBoxUtil.error(msg); + }, + () => onCreateDirectoryCallback!() + ); + } + + blurTrigger() { + const {matter, director} = this.props; + if (matter.editMode) { + if (director!.createMode) { + this.finishCreateDirectory(); + } else if (director!.renameMode) { + this.finishRename(); + } + } + } + + enterTrigger(e: any) { + if (e.key.toLowerCase() === "enter") { + this.inputRef.current!.blur(); + } + } + + changePrivacy(privacy: boolean) { + this.props.matter.httpChangePrivacy(privacy, () => { + this.updateUI(); }); - }, - }); - } - - recoveryMatter() { - Modal.confirm({ - title: Lang.t("actionRecoveryConfirm"), - icon: , - onOk: () => { - this.props.matter.httpRecovery(() => { - MessageBoxUtil.success(Lang.t("operationSuccess")); - this.props.onRecoverySuccess!(); - }); - }, - }); - } - - changeMatterName(e: any) { - this.renameMatterName = e.currentTarget.value; - this.updateUI(); - } - - finishRename() { - //有可能按enter的时候和blur同时了。 - if (this.renamingLoading) { - return; - } - const { matter, director } = this.props; - this.renamingLoading = true; - - matter.httpRename( - this.renameMatterName, - () => { - this.renamingLoading = false; - MessageBoxUtil.success(Lang.t("operationSuccess")); - //告诉导演,自己编辑完毕 - director!.renameMode = false; - matter.editMode = false; - }, - (msg: string) => { - this.renamingLoading = false; - MessageBoxUtil.error(msg); - //告诉导演,自己编辑完毕 - director!.renameMode = false; - matter.editMode = false; - }, - () => this.updateUI() - ); - } - - finishCreateDirectory() { - const { matter, director, onCreateDirectoryCallback } = this.props; - matter.name = this.renameMatterName; - matter.httpCreateDirectory( - () => { - director!.createMode = false; - matter.editMode = false; - matter.assign(new Matter()); - }, - (msg: string) => { - director!.createMode = false; - matter.editMode = false; - MessageBoxUtil.error(msg); - }, - () => onCreateDirectoryCallback!() - ); - } - - blurTrigger() { - const { matter, director } = this.props; - if (matter.editMode) { - if (director!.createMode) { - this.finishCreateDirectory(); - } else if (director!.renameMode) { - this.finishRename(); - } - } - } - - enterTrigger(e: any) { - if (e.key.toLowerCase() === "enter") { - this.inputRef.current!.blur(); - } - } - - changePrivacy(privacy: boolean) { - this.props.matter.httpChangePrivacy(privacy, () => { - this.updateUI(); - }); - } - - checkToggle(e: CheckboxChangeEvent) { - this.props.matter.check = e.target.checked; - this.props.onCheckMatter!(this.props.matter); - } - - highLight() { - this.inputRef.current!.select(); - } - - clickRow() { - const { - matter, - recycleMode = false, - director, - onGoToDirectory, - onPreviewImage, - } = this.props; - if (director && director.isEditing()) { - console.error("导演正忙着,不予执行"); - return; } - if (matter.dir) { - if (recycleMode) return; - onGoToDirectory!(matter.uuid!); - } else { - //图片进行预览操作 - if (matter.isImage()) { - onPreviewImage!(matter); - } else { - matter.preview(); - } + checkToggle(e: CheckboxChangeEvent) { + this.props.matter.check = e.target.checked; + this.props.onCheckMatter!(this.props.matter); } - } - toggleHandles() { - this.showMore = !this.showMore; - this.updateUI(); - } + highLight() { + this.inputRef.current!.select(); + } - renderPcOperation() { - const { matter, recycleMode = false } = this.props; + clickRow() { + const { + matter, + recycleMode = false, + director, + onGoToDirectory, + onPreviewImage, + } = this.props; + if (director && director.isEditing()) { + console.error("导演正忙着,不予执行"); + return; + } - // 文件操作在正常模式 or 回收站模式下不同,其中回收站模式只保留查看信息与彻底删除操作 - const handles = recycleMode ? ( - <> - - - SafeUtil.stopPropagationWrap(e)(this.recoveryMatter()) + if (matter.dir) { + if (recycleMode) return; + onGoToDirectory!(matter.uuid!); + } else { + //图片进行预览操作 + if (matter.isImage()) { + onPreviewImage!(matter); + } else { + matter.preview(); } - /> - - - - SafeUtil.stopPropagationWrap(e)( - Sun.navigateTo("/matter/detail/" + matter.uuid) - ) - } - /> - - - - SafeUtil.stopPropagationWrap(e)(this.hardDeleteMatter()) - } - /> - - - ) : ( - <> - {!matter.dir && matter.privacy && ( - - - SafeUtil.stopPropagationWrap(e)(this.changePrivacy(false)) - } - /> - - )} - {!matter.dir && !matter.privacy && ( - - - SafeUtil.stopPropagationWrap(e)(this.changePrivacy(true)) - } - /> - - )} - - - SafeUtil.stopPropagationWrap(e)( - Sun.navigateTo("/matter/detail/" + matter.uuid) - ) - } - /> - - - - SafeUtil.stopPropagationWrap(e)(this.prepareRename()) - } - /> - - - SafeUtil.stopPropagationWrap(e)(this.clipboard())} - /> - - - SafeUtil.stopPropagationWrap(e)(matter.download())} - /> - - - - SafeUtil.stopPropagationWrap(e)(this.deleteMatter()) - } - /> - - - ); + } + } - return ( -
- {handles} - + toggleHandles() { + this.showMore = !this.showMore; + this.updateUI(); + } + + renderPcOperation() { + const {matter, recycleMode = false} = this.props; + + // 文件操作在正常模式 or 回收站模式下不同,其中回收站模式只保留查看信息与彻底删除操作 + const handles = recycleMode ? ( + <> + + + SafeUtil.stopPropagationWrap(e)(this.recoveryMatter()) + } + /> + + + + SafeUtil.stopPropagationWrap(e)( + Sun.navigateTo("/matter/detail/" + matter.uuid) + ) + } + /> + + + + SafeUtil.stopPropagationWrap(e)(this.hardDeleteMatter()) + } + /> + + + ) : ( + <> + {!matter.dir && matter.privacy && ( + + + SafeUtil.stopPropagationWrap(e)(this.changePrivacy(false)) + } + /> + + )} + {!matter.dir && !matter.privacy && ( + + + SafeUtil.stopPropagationWrap(e)(this.changePrivacy(true)) + } + /> + + )} + + + SafeUtil.stopPropagationWrap(e)( + Sun.navigateTo("/matter/detail/" + matter.uuid) + ) + } + /> + + + + SafeUtil.stopPropagationWrap(e)(this.prepareRename()) + } + /> + + + SafeUtil.stopPropagationWrap(e)(this.clipboard())} + /> + + + SafeUtil.stopPropagationWrap(e)(matter.download())} + /> + + + + SafeUtil.stopPropagationWrap(e)(this.deleteMatter()) + } + /> + + + ); + + return ( +
+ {handles} + {StringUtil.humanFileSize(matter.size)} - - {recycleMode ? ( - + + {recycleMode ? ( + {DateUtil.simpleDateHourMinute(matter.deleteTime)} - - ) : ( - + + ) : ( + {DateUtil.simpleDateHourMinute(matter.updateTime)} - - )} -
- ); - } - - // 文件操作在正常模式 or 回收站模式下不同,其中回收站模式只保留查看信息与彻底删除操作 - getHandles() { - const { matter, recycleMode = false } = this.props; - // 回收站模式 - if (recycleMode) - return [ -
- SafeUtil.stopPropagationWrap(e)( - Sun.navigateTo("/matter/detail/" + this.props.matter.uuid) - ) - } - > - - {Lang.t("matter.fileDetail")} -
, -
- SafeUtil.stopPropagationWrap(e)(this.recoveryMatter()) - } - > - - {Lang.t("matter.recovery")} -
, -
- SafeUtil.stopPropagationWrap(e)(this.hardDeleteMatter()) - } - > - - {Lang.t("matter.hardDelete")} -
, - ]; - - // 普通模式 - const handles = []; - if (!matter.dir) { - handles.push( - matter.privacy ? ( -
- SafeUtil.stopPropagationWrap(e)(this.changePrivacy(false)) - } - > - - {Lang.t("matter.setPublic")} -
- ) : ( -
- SafeUtil.stopPropagationWrap(e)(this.changePrivacy(true)) - } - > - - {Lang.t("matter.setPrivate")} -
- ) - ); +
+ )} +
+ ); } - handles.push( -
- SafeUtil.stopPropagationWrap(e)( - Sun.navigateTo("/matter/detail/" + matter.uuid) - ) + + // 文件操作在正常模式 or 回收站模式下不同,其中回收站模式只保留查看信息与彻底删除操作 + getHandles() { + const {matter, recycleMode = false} = this.props; + // 回收站模式 + if (recycleMode) + return [ +
+ SafeUtil.stopPropagationWrap(e)( + Sun.navigateTo("/matter/detail/" + this.props.matter.uuid) + ) + } + > + + {Lang.t("matter.fileDetail")} +
, +
+ SafeUtil.stopPropagationWrap(e)(this.recoveryMatter()) + } + > + + {Lang.t("matter.recovery")} +
, +
+ SafeUtil.stopPropagationWrap(e)(this.hardDeleteMatter()) + } + > + + {Lang.t("matter.hardDelete")} +
, + ]; + + // 普通模式 + const handles = []; + if (!matter.dir) { + handles.push( + matter.privacy ? ( +
+ SafeUtil.stopPropagationWrap(e)(this.changePrivacy(false)) + } + > + + {Lang.t("matter.setPublic")} +
+ ) : ( +
+ SafeUtil.stopPropagationWrap(e)(this.changePrivacy(true)) + } + > + + {Lang.t("matter.setPrivate")} +
+ ) + ); } - > - - {Lang.t("matter.fileDetail")} -
, -
SafeUtil.stopPropagationWrap(e)(this.prepareRename())} - > - - {Lang.t("matter.rename")} -
, -
SafeUtil.stopPropagationWrap(e)(this.clipboard())} - > - - {Lang.t("matter.copyLink")} -
, -
SafeUtil.stopPropagationWrap(e)(matter.download())} - > - - {Lang.t("matter.download")} -
, -
SafeUtil.stopPropagationWrap(e)(this.deleteMatter())} - > - - {Lang.t("matter.delete")} -
- ); - return handles; - } + handles.push( +
+ SafeUtil.stopPropagationWrap(e)( + Sun.navigateTo("/matter/detail/" + matter.uuid) + ) + } + > + + {Lang.t("matter.fileDetail")} +
, +
SafeUtil.stopPropagationWrap(e)(this.prepareRename())} + > + + {Lang.t("matter.rename")} +
, +
SafeUtil.stopPropagationWrap(e)(this.clipboard())} + > + + {Lang.t("matter.copyLink")} +
, +
SafeUtil.stopPropagationWrap(e)(matter.download())} + > + + {Lang.t("matter.download")} +
, +
SafeUtil.stopPropagationWrap(e)(this.deleteMatter())} + > + + {Lang.t("matter.delete")} +
+ ); + return handles; + } - renderMobileOperation() { - const { matter, recycleMode = false } = this.props; + renderMobileOperation() { + const {matter, recycleMode = false} = this.props; - return ( -
-
+ return ( +
+
{DateUtil.simpleDateHourMinute( - recycleMode ? matter.deleteTime : matter.updateTime + recycleMode ? matter.deleteTime : matter.updateTime )} - + {StringUtil.humanFileSize(matter.size)} -
- {this.getHandles()} -
- ); - } +
+ {this.getHandles()} +
+ ); + } - render() { - const { matter } = this.props; + render() { + const {matter} = this.props; - const menu = ( - - {this.getHandles().map((item, i) => ( - {item} - ))} - - ); + const menu = ( + + {this.getHandles().map((item, i) => ( + {item} + ))} + + ); - return ( - -
-
SafeUtil.stopPropagationWrap(e)(this.clickRow())} - > -
-
-
+ return ( + +
+
SafeUtil.stopPropagationWrap(e)(this.clickRow())} + > +
+
+
SafeUtil.stopPropagationWrap(e)} + className="cell cell-hot" + onClick={(e) => SafeUtil.stopPropagationWrap(e)} > this.checkToggle(e)} + checked={matter.check} + onChange={(e) => this.checkToggle(e)} /> - - + + -
-
+
+
- {/*在大屏幕下的操作栏*/} -
- {matter.uuid && this.renderPcOperation()} -
+ {/*在大屏幕下的操作栏*/} +
+ {matter.uuid && this.renderPcOperation()} +
-
+
- SafeUtil.stopPropagationWrap(e)(this.toggleHandles()) - } + className="more-btn" + onClick={(e) => + SafeUtil.stopPropagationWrap(e)(this.toggleHandles()) + } > - + -
+
-
-
- {matter.editMode ? ( - +
+
+ {matter.editMode ? ( + this.changeMatterName(e)} - placeholder={Lang.t("matter.enterName")} - onBlur={() => this.blurTrigger()} - onKeyUp={(e) => this.enterTrigger(e)} + ref={this.inputRef} + className={matter.uuid!} + value={this.renameMatterName} + onChange={(e) => this.changeMatterName(e)} + placeholder={Lang.t("matter.enterName")} + onBlur={() => this.blurTrigger()} + onKeyUp={(e) => this.enterTrigger(e)} /> - ) : ( - + ) : ( + {matter.name} - {!matter.dir && !matter.privacy && ( - - - - )} + {!matter.dir && !matter.privacy && ( + + + + )} - )} -
-
-
-
+ )} +
+
+
+
- - {this.showMore ? this.renderMobileOperation() : null} - -
- - ); - } + + {this.showMore ? this.renderMobileOperation() : null} + +
+
+ ); + } } diff --git a/src/pages/matter/widget/MatterSortPanel.less b/src/pages/matter/widget/MatterSortPanel.less index f9a3130..b0d8e99 100644 --- a/src/pages/matter/widget/MatterSortPanel.less +++ b/src/pages/matter/widget/MatterSortPanel.less @@ -12,16 +12,19 @@ cursor: pointer; background-color: aliceblue; } + &-name { flex-grow: 1; padding-left: 10px; } + &-size { flex-shrink: 0; flex-basis: 90px; padding-left: 10px; cursor: pointer; } + &-date { flex-shrink: 0; flex-basis: 130px; diff --git a/src/pages/matter/widget/MatterSortPanel.tsx b/src/pages/matter/widget/MatterSortPanel.tsx index 90b73c5..cc2177e 100644 --- a/src/pages/matter/widget/MatterSortPanel.tsx +++ b/src/pages/matter/widget/MatterSortPanel.tsx @@ -7,8 +7,8 @@ import {ArrowDownOutlined, ArrowUpOutlined,} from "@ant-design/icons"; import Pager from "../../../common/model/base/Pager"; interface IProps { - pager: Pager, - refresh: () => any + pager: Pager, + refresh: () => any } interface IState { @@ -16,69 +16,69 @@ interface IState { export default class MatterSortPanel extends TankComponent { - static sortAutomaton = [SortDirection.ASC, SortDirection.DESC, null]; // 排序状态自动机:ASC -> DESC -> null -> ASC... + static sortAutomaton = [SortDirection.ASC, SortDirection.DESC, null]; // 排序状态自动机:ASC -> DESC -> null -> ASC... - changeFilterOrder(orderName: string) { - const {pager} = this.props; - ["orderName", "orderSize", "orderUpdateTime"] - .filter((name) => name !== orderName) - .forEach((key) => { - pager.setFilterValue(key, null); - }); - const filter = pager.getFilterValue(orderName); - const nextSortIndex = (MatterSortPanel.sortAutomaton.findIndex((key) => key === filter) + 1) % 3; + changeFilterOrder(orderName: string) { + const {pager} = this.props; + ["orderName", "orderSize", "orderUpdateTime"] + .filter((name) => name !== orderName) + .forEach((key) => { + pager.setFilterValue(key, null); + }); + const filter = pager.getFilterValue(orderName); + const nextSortIndex = (MatterSortPanel.sortAutomaton.findIndex((key) => key === filter) + 1) % 3; - pager.resetSortFilters() - pager.setFilterValue("orderDir", SortDirection.DESC); - pager.setFilterValue(orderName, MatterSortPanel.sortAutomaton[nextSortIndex]); - this.props.refresh(); - }; + pager.resetSortFilters() + pager.setFilterValue("orderDir", SortDirection.DESC); + pager.setFilterValue(orderName, MatterSortPanel.sortAutomaton[nextSortIndex]); + this.props.refresh(); + }; - render() { - const {pager} = this.props; + render() { + const {pager} = this.props; - return ( -
-
this.changeFilterOrder("orderName")} - > - 文件名 - {pager.getFilterValue("orderName") ? ( - pager.getFilterValue("orderName") === SortDirection.ASC ? ( - - ) : ( - - ) - ) : null} -
-
this.changeFilterOrder("orderSize")} - > - 大小 - {pager.getFilterValue("orderSize") ? ( - pager.getFilterValue("orderSize") === SortDirection.ASC ? ( - - ) : ( - - ) - ) : null} -
-
this.changeFilterOrder("orderUpdateTime")} - > - 修改日期 - {pager.getFilterValue("orderUpdateTime") ? ( - pager.getFilterValue("orderUpdateTime") === SortDirection.ASC ? ( - - ) : ( - - ) - ) : null} -
-
- ); - } + return ( +
+
this.changeFilterOrder("orderName")} + > + 文件名 + {pager.getFilterValue("orderName") ? ( + pager.getFilterValue("orderName") === SortDirection.ASC ? ( + + ) : ( + + ) + ) : null} +
+
this.changeFilterOrder("orderSize")} + > + 大小 + {pager.getFilterValue("orderSize") ? ( + pager.getFilterValue("orderSize") === SortDirection.ASC ? ( + + ) : ( + + ) + ) : null} +
+
this.changeFilterOrder("orderUpdateTime")} + > + 修改日期 + {pager.getFilterValue("orderUpdateTime") ? ( + pager.getFilterValue("orderUpdateTime") === SortDirection.ASC ? ( + + ) : ( + + ) + ) : null} +
+
+ ); + } } diff --git a/src/pages/matter/widget/MoveBatchModal.less b/src/pages/matter/widget/MoveBatchModal.less index fa3d435..924b276 100644 --- a/src/pages/matter/widget/MoveBatchModal.less +++ b/src/pages/matter/widget/MoveBatchModal.less @@ -1,21 +1,26 @@ .tree-wrapper { max-height: 80vh; overflow: auto; + .ant-tree-list { font-size: 16px; color: #606266; + .ant-tree-treenode { display: flex; align-items: center; height: 40px; } + .ant-tree-title { margin-left: 4px; } + .ant-tree-treenode-selected { &:before { background: rgba(0, 0, 0, 0.1) !important; } + .ant-tree-node-content-wrapper, .ant-tree-switcher { color: #606266 !important; @@ -23,6 +28,7 @@ } } } + .ant-modal-confirm-content { margin-top: 15px !important; } diff --git a/src/pages/matter/widget/MoveBatchModal.tsx b/src/pages/matter/widget/MoveBatchModal.tsx index db1b08c..6949df2 100644 --- a/src/pages/matter/widget/MoveBatchModal.tsx +++ b/src/pages/matter/widget/MoveBatchModal.tsx @@ -1,130 +1,130 @@ import React from "react"; import TankComponent from "../../../common/component/TankComponent"; -import {Modal, Tree, Button} from "antd"; +import {Button, Modal, Tree} from "antd"; import Pager from "../../../common/model/base/Pager"; import Matter from "../../../common/model/matter/Matter"; import "./MoveBatchModal.less"; import Lang from "../../../common/model/global/Lang"; -import {FolderFilled, FolderOpenFilled, ExclamationCircleFilled} from "@ant-design/icons"; +import {ExclamationCircleFilled, FolderFilled, FolderOpenFilled} from "@ant-design/icons"; interface IProps { - onSuccess: (uuid: string) => any; - onClose: () => any; + onSuccess: (uuid: string) => any; + onClose: () => any; } interface IState { } export default class MoveBatchModal extends TankComponent { - pager = new Pager(this, Matter, 10); - targetUuid = "root"; - treeData = [ - { - title: Lang.t("matter.root"), - key: "root", - }, - ]; + pager = new Pager(this, Matter, 10); + targetUuid = "root"; + treeData = [ + { + title: Lang.t("matter.root"), + key: "root", + }, + ]; - constructor(props: IProps) { - super(props); - } - - componentDidMount() { - this.pager.setFilterValue("orderCreateTime", "DESC"); - this.pager.setFilterValue("dir", true); - } - - static open(onSuccess: (uuid: string) => void) { - let modal = Modal.confirm({ - className: "move-modal", - title: Lang.t("matter.moveTo"), - icon: , - width: "90vw", - okCancel: false, - okButtonProps: { - className: "display-none", - }, - content: ( - { - modal.destroy(); - onSuccess(uuid); - }} - onClose={() => { - modal.destroy(); - }} - /> - ), - }); - } - - fetchData(treeNode: any, success: () => any) { - const {data: origin} = treeNode.props; - this.pager.setFilterValue("puuid", treeNode.key); - this.pager.httpList((response: any) => { - const {data, page, totalPages} = response.data.data; - origin.children = (origin.children || []).concat( - data.map((matter: Matter) => ({ - title: matter.name, - key: matter.uuid, - })) - ); - if (page + 1 < totalPages) { - this.pager.page++; - this.fetchData(treeNode, success); - } else { - this.pager.page = 0; - success(); - } - }); - }; - - onLoadData(treeNode: any) { - - return new Promise((resolve: any) => { - if (treeNode.props.children) { - resolve(); - return; - } - this.fetchData(treeNode, () => resolve()); - }).then(() => { - this.treeData = JSON.parse(JSON.stringify(this.treeData)); - this.updateUI(); - }); - }; - - onSelect(selectedKeys: any) { - if (selectedKeys.length) { - this.targetUuid = selectedKeys[0]; - this.updateUI(); + constructor(props: IProps) { + super(props); } - }; - render() { - return ( -
- this.onLoadData(e)} - onSelect={e => this.onSelect(e)} - icon={e => e.expanded ? : - } - /> -
- - -
-
- ); - } + componentDidMount() { + this.pager.setFilterValue("orderCreateTime", "DESC"); + this.pager.setFilterValue("dir", true); + } + + static open(onSuccess: (uuid: string) => void) { + let modal = Modal.confirm({ + className: "move-modal", + title: Lang.t("matter.moveTo"), + icon: , + width: "90vw", + okCancel: false, + okButtonProps: { + className: "display-none", + }, + content: ( + { + modal.destroy(); + onSuccess(uuid); + }} + onClose={() => { + modal.destroy(); + }} + /> + ), + }); + } + + fetchData(treeNode: any, success: () => any) { + const {data: origin} = treeNode.props; + this.pager.setFilterValue("puuid", treeNode.key); + this.pager.httpList((response: any) => { + const {data, page, totalPages} = response.data.data; + origin.children = (origin.children || []).concat( + data.map((matter: Matter) => ({ + title: matter.name, + key: matter.uuid, + })) + ); + if (page + 1 < totalPages) { + this.pager.page++; + this.fetchData(treeNode, success); + } else { + this.pager.page = 0; + success(); + } + }); + }; + + onLoadData(treeNode: any) { + + return new Promise((resolve: any) => { + if (treeNode.props.children) { + resolve(); + return; + } + this.fetchData(treeNode, () => resolve()); + }).then(() => { + this.treeData = JSON.parse(JSON.stringify(this.treeData)); + this.updateUI(); + }); + }; + + onSelect(selectedKeys: any) { + if (selectedKeys.length) { + this.targetUuid = selectedKeys[0]; + this.updateUI(); + } + }; + + render() { + return ( +
+ this.onLoadData(e)} + onSelect={e => this.onSelect(e)} + icon={e => e.expanded ? : + } + /> +
+ + +
+
+ ); + } } diff --git a/src/pages/matter/widget/ShareOperationModal.less b/src/pages/matter/widget/ShareOperationModal.less index 01d5269..44d694d 100644 --- a/src/pages/matter/widget/ShareOperationModal.less +++ b/src/pages/matter/widget/ShareOperationModal.less @@ -16,6 +16,7 @@ } } + .share-modal { max-width: 1000px; } diff --git a/src/pages/matter/widget/ShareOperationModal.tsx b/src/pages/matter/widget/ShareOperationModal.tsx index 8e1f2dc..72e4623 100644 --- a/src/pages/matter/widget/ShareOperationModal.tsx +++ b/src/pages/matter/widget/ShareOperationModal.tsx @@ -1,89 +1,87 @@ import React from "react"; import TankComponent from "../../../common/component/TankComponent"; -import { Modal, Button, Col, Row, Select } from "antd"; -import { ExclamationCircleFilled } from "@ant-design/icons"; +import {Button, Col, Modal, Row, Select} from "antd"; +import {ExclamationCircleFilled} from "@ant-design/icons"; import "./ShareOperationModal.less"; import Share from "../../../common/model/share/Share"; -import { - ShareExpireOptionList, - ShareExpireOption, -} from "../../../common/model/share/ShareExpireOption"; +import {ShareExpireOption, ShareExpireOptionList,} from "../../../common/model/share/ShareExpireOption"; import Lang from "../../../common/model/global/Lang"; interface IProps { - onSuccess: (share: Share) => any; - onClose: () => any; + onSuccess: (share: Share) => any; + onClose: () => any; } -interface IState {} +interface IState { +} export default class ShareOperationModal extends TankComponent { - share = new Share(); + share = new Share(); - constructor(props: IProps) { - super(props); - } + constructor(props: IProps) { + super(props); + } - static open = (confirmCallback: (share: Share) => any) => { - const modal = Modal.confirm({ - className: "share-modal", - title: Lang.t("matter.share"), - icon: , - width: "90vw", - okCancel: false, - okButtonProps: { - className: "display-none", - }, - content: ( - { - confirmCallback(share); - modal.destroy(); - }} - onClose={() => { - modal.destroy(); - }} - /> - ), - }); - }; + static open = (confirmCallback: (share: Share) => any) => { + const modal = Modal.confirm({ + className: "share-modal", + title: Lang.t("matter.share"), + icon: , + width: "90vw", + okCancel: false, + okButtonProps: { + className: "display-none", + }, + content: ( + { + confirmCallback(share); + modal.destroy(); + }} + onClose={() => { + modal.destroy(); + }} + /> + ), + }); + }; - selectChange(value: ShareExpireOption) { - this.share.expireOption = value; - this.updateUI(); - }; + selectChange(value: ShareExpireOption) { + this.share.expireOption = value; + this.updateUI(); + }; - render() { - const { share } = this; - return ( -
- - {Lang.t("matter.expire")} - - - - -
- - -
-
- ); - } + render() { + const {share} = this; + return ( +
+ + {Lang.t("matter.expire")} + + + + +
+ + +
+
+ ); + } } diff --git a/src/pages/matter/widget/UploadMatterPanel.less b/src/pages/matter/widget/UploadMatterPanel.less index 1a5fbb4..2f29d9a 100644 --- a/src/pages/matter/widget/UploadMatterPanel.less +++ b/src/pages/matter/widget/UploadMatterPanel.less @@ -15,6 +15,7 @@ .media { display: flex; justify-content: space-between; + .media-body { cursor: pointer; color: #555; diff --git a/src/pages/matter/widget/UploadMatterPanel.tsx b/src/pages/matter/widget/UploadMatterPanel.tsx index aae66fc..de23896 100644 --- a/src/pages/matter/widget/UploadMatterPanel.tsx +++ b/src/pages/matter/widget/UploadMatterPanel.tsx @@ -2,72 +2,75 @@ import React from "react"; import TankComponent from "../../../common/component/TankComponent"; import Matter from "../../../common/model/matter/Matter"; import StringUtil from "../../../common/util/StringUtil"; -import { Progress } from "antd"; -import { CloseOutlined } from "@ant-design/icons"; +import {Progress} from "antd"; +import {CloseOutlined} from "@ant-design/icons"; import "./UploadMatterPanel.less"; import Lang from "../../../common/model/global/Lang"; interface IProps { - matter: Matter; + matter: Matter; } -interface IState {} +interface IState { +} export default class UploadMatterPanel extends TankComponent { - constructor(props: IProps) { - super(props); - this.state = {}; - } + constructor(props: IProps) { + super(props); + this.state = {}; + } - format(percent: number) { - return `${percent.toFixed(1)}%`; - }; + format(percent: number) { + return `${percent.toFixed(1)}%`; + }; - componentDidMount() { - this.props.matter.reactComponent = this; - } + componentDidMount() { + this.props.matter.reactComponent = this; + } - componentWillReceiveProps(nextProps: Readonly, nextContext: any) {} - componentWillUnmount() { - this.props.matter.reactComponent = null; - } + componentWillReceiveProps(nextProps: Readonly, nextContext: any) { + } - render() { - const { matter } = this.props; - return ( -
- {matter.loading ? ( -
-
-
{matter.file!.name}
-
- matter.cancelUpload()} /> -
+ componentWillUnmount() { + this.props.matter.reactComponent = null; + } + + render() { + const {matter} = this.props; + return ( +
+ {matter.loading ? ( +
+
+
{matter.file!.name}
+
+ matter.cancelUpload()}/> +
+
+ this.format(matter.progress * 100)} + percent={matter.progress * 100} + status="active" + /> +
+ {`${Lang.t("matter.uploaded")}: ${StringUtil.humanFileSize( + matter.file!.size * matter.progress + )}/${StringUtil.humanFileSize(matter.file!.size)} ${ + matter.progress < 1 + ? `${Lang.t("matter.speed")}:${StringUtil.humanFileSize( + matter.speed + )}s` + : Lang.t("matter.finishingTip") + }`} +
+
+ ) : null}
- this.format(matter.progress * 100)} - percent={matter.progress * 100} - status="active" - /> -
- {`${Lang.t("matter.uploaded")}: ${StringUtil.humanFileSize( - matter.file!.size * matter.progress - )}/${StringUtil.humanFileSize(matter.file!.size)} ${ - matter.progress < 1 - ? `${Lang.t("matter.speed")}:${StringUtil.humanFileSize( - matter.speed - )}s` - : Lang.t("matter.finishingTip") - }`} -
-
- ) : null} -
- ); - } + ); + } } diff --git a/src/pages/matter/widget/imageCache/ImageCacheList.tsx b/src/pages/matter/widget/imageCache/ImageCacheList.tsx index f36b60c..fa4fb45 100644 --- a/src/pages/matter/widget/imageCache/ImageCacheList.tsx +++ b/src/pages/matter/widget/imageCache/ImageCacheList.tsx @@ -12,160 +12,160 @@ import Lang from "../../../../common/model/global/Lang"; import TankContentCard from "../../../widget/TankContentCard"; interface IProps { - initFilter: any; + initFilter: any; } interface IState { } export default class ImageCacheList extends TankComponent { - selectedImageCaches: ImageCache[] = []; - pager = new Pager(this, ImageCache, 2); + selectedImageCaches: ImageCache[] = []; + pager = new Pager(this, ImageCache, 2); - constructor(props: IProps) { - super(props); - this.state = {}; - this.pager.enableHistory() - } + constructor(props: IProps) { + super(props); + this.state = {}; + this.pager.enableHistory() + } - componentDidMount() { - this.refresh(); - } + componentDidMount() { + this.refresh(); + } - deleteBatch() { - Modal.confirm({ - title: Lang.t("actionCanNotRevertConfirm"), - icon: , - onOk: () => { - const uuids = this.selectedImageCaches.map((i) => i.uuid).toString(); - const imageCache = new ImageCache(); - imageCache.httpDeleteBatch(uuids, () => { - MessageBoxUtil.success(Lang.t("operationSuccess")); - this.refresh(); + deleteBatch() { + Modal.confirm({ + title: Lang.t("actionCanNotRevertConfirm"), + icon: , + onOk: () => { + const uuids = this.selectedImageCaches.map((i) => i.uuid).toString(); + const imageCache = new ImageCache(); + imageCache.httpDeleteBatch(uuids, () => { + MessageBoxUtil.success(Lang.t("operationSuccess")); + this.refresh(); + }); + }, }); - }, - }); - }; + }; - checkBatch(check: boolean) { - this.pager.data.forEach((i) => { - i.check = check; - }); - this.checkImageCache(); - }; + checkBatch(check: boolean) { + this.pager.data.forEach((i) => { + i.check = check; + }); + this.checkImageCache(); + }; - refresh() { - const {initFilter} = this.props; - if (initFilter) { - for (let key in initFilter) { - if (initFilter.hasOwnProperty(key)) { - this.pager.setFilterValue(key, initFilter[key]); + refresh() { + const {initFilter} = this.props; + if (initFilter) { + for (let key in initFilter) { + if (initFilter.hasOwnProperty(key)) { + this.pager.setFilterValue(key, initFilter[key]); + } + } } - } - } - this.pager.page = 0; - this.pager.httpList(); - this.selectedImageCaches = []; - }; + this.pager.page = 0; + this.pager.httpList(); + this.selectedImageCaches = []; + }; - checkImageCache(imageCache?: ImageCache) { - if (imageCache) { - if (imageCache.check) { - this.selectedImageCaches.push(imageCache); - } else { - const index = this.selectedImageCaches.findIndex( - (item) => item.uuid === imageCache.uuid - ); - this.selectedImageCaches.splice(index, 1); - } - } else { - this.selectedImageCaches.splice(0, this.selectedImageCaches.length); - this.pager.data.forEach((imageCache) => { - if (imageCache.check) { - this.selectedImageCaches.push(imageCache); + checkImageCache(imageCache?: ImageCache) { + if (imageCache) { + if (imageCache.check) { + this.selectedImageCaches.push(imageCache); + } else { + const index = this.selectedImageCaches.findIndex( + (item) => item.uuid === imageCache.uuid + ); + this.selectedImageCaches.splice(index, 1); + } + } else { + this.selectedImageCaches.splice(0, this.selectedImageCaches.length); + this.pager.data.forEach((imageCache) => { + if (imageCache.check) { + this.selectedImageCaches.push(imageCache); + } + }); } - }); - } - this.updateUI(); - }; + this.updateUI(); + }; - previewImageCache(imageCache: ImageCache) { - //从matter开始预览图片 - const imageArray: string[] = []; - let startIndex = -1; - this.pager.data.forEach((item) => { - imageArray.push(item.getResizeUrl()); - if (item.uuid === imageCache.uuid) { - startIndex = imageArray.length - 1; - } - }); + previewImageCache(imageCache: ImageCache) { + //从matter开始预览图片 + const imageArray: string[] = []; + let startIndex = -1; + this.pager.data.forEach((item) => { + imageArray.push(item.getResizeUrl()); + if (item.uuid === imageCache.uuid) { + startIndex = imageArray.length - 1; + } + }); - ImagePreviewer.showMultiPhoto(imageArray, startIndex); - }; + ImagePreviewer.showMultiPhoto(imageArray, startIndex); + }; - changePage(page: number) { - this.pager.page = page - 1; // page的页数0基 - this.pager.httpList(); - this.updateUI(); - }; + changePage(page: number) { + this.pager.page = page - 1; // page的页数0基 + this.pager.httpList(); + this.updateUI(); + }; - render() { - const {selectedImageCaches, pager} = this; - if (!pager.data.length) return ; - return ( -
- ; + return (
- - {selectedImageCaches.length ? ( - - ) : null} - {selectedImageCaches.length !== pager.data.length ? ( - - ) : null} - {pager.data.length && - selectedImageCaches.length === pager.data.length ? ( - - ) : null} - + + + {selectedImageCaches.length ? ( + + ) : null} + {selectedImageCaches.length !== pager.data.length ? ( + + ) : null} + {pager.data.length && + selectedImageCaches.length === pager.data.length ? ( + + ) : null} + +
+ } + /> + + + {pager.data.map((imageCache) => ( + this.refresh()} + onCheckImageCache={e => this.checkImageCache(e)} + onPreviewImageCache={e => this.previewImageCache(e)} + /> + ))} + + + + this.changePage(page)} + current={pager.page + 1} + total={pager.totalItems} + pageSize={pager.pageSize} + hideOnSinglePage + /> +
- } - /> - - - {pager.data.map((imageCache) => ( - this.refresh()} - onCheckImageCache={e => this.checkImageCache(e)} - onPreviewImageCache={e => this.previewImageCache(e)} - /> - ))} - - - - this.changePage(page)} - current={pager.page + 1} - total={pager.totalItems} - pageSize={pager.pageSize} - hideOnSinglePage - /> - -
- ); - } + ); + } } diff --git a/src/pages/matter/widget/imageCache/ImageCachePanel.less b/src/pages/matter/widget/imageCache/ImageCachePanel.less index 1a2b435..c133aec 100644 --- a/src/pages/matter/widget/imageCache/ImageCachePanel.less +++ b/src/pages/matter/widget/imageCache/ImageCachePanel.less @@ -3,6 +3,7 @@ .widget-image-cache-panel { border-bottom: 1px solid #eee; + &:last-child { border-bottom: none; } @@ -27,6 +28,7 @@ .basic-span; width: 90%; + input { width: 100%; height: 26px; @@ -49,6 +51,7 @@ .image-cache-operation { .basic-span; display: none; + i { font-size: 16px; margin-right: 5px; @@ -58,6 +61,7 @@ } } } + .image-cache-size { .basic-span; display: inline-block; @@ -65,6 +69,7 @@ text-align: left; margin-left: 20px; } + .image-cache-date { .basic-span; } @@ -89,17 +94,21 @@ .more-panel { border-top: 1px solid #eee; padding-left: 32px; + .cell-btn { border-top: 1px solid #eee; line-height: @inner-cell-height; vertical-align: middle; + &:first-child { border: 0; } } + .text { margin-left: 5px; } + .matter-size { margin-left: 15px; } diff --git a/src/pages/matter/widget/imageCache/ImageCachePanel.tsx b/src/pages/matter/widget/imageCache/ImageCachePanel.tsx index c032898..7bb1df8 100644 --- a/src/pages/matter/widget/imageCache/ImageCachePanel.tsx +++ b/src/pages/matter/widget/imageCache/ImageCachePanel.tsx @@ -1,15 +1,11 @@ import React from "react"; import TankComponent from "../../../../common/component/TankComponent"; -import { Checkbox, Modal } from "antd"; +import {Checkbox, Modal} from "antd"; import SafeUtil from "../../../../common/util/SafeUtil"; import ImageCache from "../../../../common/model/image/cache/ImageCache"; import ImageUtil from "../../../../common/util/ImageUtil"; -import { CheckboxChangeEvent } from "antd/es/checkbox"; -import { - DeleteOutlined, - ExclamationCircleFilled, - SmallDashOutlined, -} from "@ant-design/icons"; +import {CheckboxChangeEvent} from "antd/es/checkbox"; +import {DeleteOutlined, ExclamationCircleFilled, SmallDashOutlined,} from "@ant-design/icons"; import MessageBoxUtil from "../../../../common/util/MessageBoxUtil"; import FileUtil from "../../../../common/util/FileUtil"; import DateUtil from "../../../../common/util/DateUtil"; @@ -19,142 +15,143 @@ import StringUtil from "../../../../common/util/StringUtil"; import Lang from "../../../../common/model/global/Lang"; interface IProps { - imageCache: ImageCache; - onCheckImageCache: (imageCache?: ImageCache) => any; - onPreviewImageCache: (imageCache: ImageCache) => any; - onDeleteSuccess: () => any; + imageCache: ImageCache; + onCheckImageCache: (imageCache?: ImageCache) => any; + onPreviewImageCache: (imageCache: ImageCache) => any; + onDeleteSuccess: () => any; } -interface IState {} +interface IState { +} export default class ImageCachePanel extends TankComponent { - // 小屏幕下操作栏 - showMore = false; + // 小屏幕下操作栏 + showMore = false; - checkToggle(e: CheckboxChangeEvent) { - const { imageCache, onCheckImageCache } = this.props; - imageCache.check = e.target.checked; - onCheckImageCache(imageCache); - }; + checkToggle(e: CheckboxChangeEvent) { + const {imageCache, onCheckImageCache} = this.props; + imageCache.check = e.target.checked; + onCheckImageCache(imageCache); + }; - deleteImageCache() { - Modal.confirm({ - title: Lang.t("actionCanNotRevertConfirm"), - icon: , - onOk: () => { - this.props.imageCache.httpDel(() => { - MessageBoxUtil.success(Lang.t("operationSuccess")); - this.props.onDeleteSuccess!(); + deleteImageCache() { + Modal.confirm({ + title: Lang.t("actionCanNotRevertConfirm"), + icon: , + onOk: () => { + this.props.imageCache.httpDel(() => { + MessageBoxUtil.success(Lang.t("operationSuccess")); + this.props.onDeleteSuccess!(); + }); + }, }); - }, - }); - }; + }; - toggleHandles() { - this.showMore = !this.showMore; - this.updateUI(); - }; + toggleHandles() { + this.showMore = !this.showMore; + this.updateUI(); + }; - render() { - const { imageCache } = this.props; + render() { + const {imageCache} = this.props; - return ( -
-
- SafeUtil.stopPropagationWrap(e)( - this.props.onPreviewImageCache(imageCache) - ) - } - > -
-
-
+ return ( +
+
+ SafeUtil.stopPropagationWrap(e)( + this.props.onPreviewImageCache(imageCache) + ) + } + > +
+
+
SafeUtil.stopPropagationWrap(e)} - checked={imageCache.check} - onChange={e => this.checkToggle(e)} + onClick={(e) => SafeUtil.stopPropagationWrap(e)} + checked={imageCache.check} + onChange={e => this.checkToggle(e)} /> - + -
-
+
+
- {/*在大屏下的操作栏*/} -
- {imageCache.uuid ? ( -
- - SafeUtil.stopPropagationWrap(e)(this.deleteImageCache()) - } - /> - + {/*在大屏下的操作栏*/} +
+ {imageCache.uuid ? ( +
+ + SafeUtil.stopPropagationWrap(e)(this.deleteImageCache()) + } + /> + {FileUtil.humanFileSize(imageCache.size)} - + {DateUtil.simpleDateHourMinute(imageCache.updateTime)} -
- ) : null} -
+
+ ) : null} +
- {/*在小屏下的操作栏*/} -
+ {/*在小屏下的操作栏*/} +
- SafeUtil.stopPropagationWrap(e)(this.toggleHandles()) - } + className="more-btn" + onClick={(e) => + SafeUtil.stopPropagationWrap(e)(this.toggleHandles()) + } > - + -
+
-
-
- {imageCache.name} -
-
-
- - {this.showMore ? ( -
-
+
+
+ {imageCache.name} +
+
+
+ + {this.showMore ? ( +
+
{DateUtil.simpleDateHourMinute(imageCache.updateTime)} - + {StringUtil.humanFileSize(imageCache.size)} +
+
+ SafeUtil.stopPropagationWrap(e)(this.deleteImageCache()) + } + > + + {Lang.t("delete")} +
+
+ ) : null} +
-
- SafeUtil.stopPropagationWrap(e)(this.deleteImageCache()) - } - > - - {Lang.t("delete")} -
-
- ) : null} - -
-
- ); - } +
+ ); + } } diff --git a/src/pages/preference/Edit.tsx b/src/pages/preference/Edit.tsx index 9acaae7..10d0fe4 100644 --- a/src/pages/preference/Edit.tsx +++ b/src/pages/preference/Edit.tsx @@ -23,220 +23,220 @@ interface IState { } export default class Edit extends TankComponent { - formRef = React.createRef(); + formRef = React.createRef(); - user: User = Moon.getSingleton().user; - preference: Preference = Moon.getSingleton().preference; + user: User = Moon.getSingleton().user; + preference: Preference = Moon.getSingleton().preference; - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; + this.state = {}; - this.preference.detailLoading = true; - } + this.preference.detailLoading = true; + } - componentDidMount() { - let that = this; + componentDidMount() { + let that = this; - that.refreshPreference(); - } + that.refreshPreference(); + } - refreshPreference() { - let that = this; + refreshPreference() { + let that = this; - that.preference.httpFetch(function () { - that.preference.detailLoading = false; - that.updateUI(); - }); - } + that.preference.httpFetch(function () { + that.preference.detailLoading = false; + that.updateUI(); + }); + } - onFinish(values: any) { + onFinish(values: any) { - let that = this; + let that = this; - let user = that.user; + let user = that.user; - that.preference.assign(values); + that.preference.assign(values); - that.preference.httpSave(function () { - MessageBoxUtil.success(Lang.t("operationSuccess")); + that.preference.httpSave(function () { + MessageBoxUtil.success(Lang.t("operationSuccess")); - Sun.updateFrame(); + Sun.updateFrame(); - Sun.navigateTo("/preference/index"); - }); - } + Sun.navigateTo("/preference/index"); + }); + } - onFinishFailed(errorInfo: any) { + onFinishFailed(errorInfo: any) { - } + } - render() { - let that = this; + render() { + let that = this; - let preference = that.preference; + let preference = that.preference; - const layout = { - labelCol: {span: 6}, - wrapperCol: {span: 18}, - }; + const layout = { + labelCol: {span: 6}, + wrapperCol: {span: 18}, + }; - let initialValues: any = preference.getForm(); + let initialValues: any = preference.getForm(); - return ( -
- + return ( +
+ - -
that.updateUI()} - > - - - + + that.updateUI()} + > + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - - - + + + + + {Lang.t("preference.current")}: - {this.formRef && this.formRef.current - ? FileUtil.humanFileSize( - this.formRef.current.getFieldValue("downloadDirMaxSize") - ) - : FileUtil.humanFileSize(preference.defaultTotalSizeLimit)} + {this.formRef && this.formRef.current + ? FileUtil.humanFileSize( + this.formRef.current.getFieldValue("downloadDirMaxSize") + ) + : FileUtil.humanFileSize(preference.defaultTotalSizeLimit)} - + - - - - - + + + + + {Lang.t("preference.current")}: - {this.formRef && this.formRef.current - ? FileUtil.humanFileSize( - this.formRef.current.getFieldValue( - "defaultTotalSizeLimit" - ) - ) - : FileUtil.humanFileSize(preference.defaultTotalSizeLimit)} + {this.formRef && this.formRef.current + ? FileUtil.humanFileSize( + this.formRef.current.getFieldValue( + "defaultTotalSizeLimit" + ) + ) + : FileUtil.humanFileSize(preference.defaultTotalSizeLimit)} - + - - - - - + + + + + {Lang.t("preference.matterBinDefaultTip")} - + - - - + + + -
- +
+ +
+ +
- -
-
- ); - } + ); + } } diff --git a/src/pages/preference/Index.less b/src/pages/preference/Index.less index 50f3ded..cbadd17 100644 --- a/src/pages/preference/Index.less +++ b/src/pages/preference/Index.less @@ -26,6 +26,7 @@ align-items: center; justify-content: space-between; margin-bottom: 10px; + .title { font-size: 22px; margin: 0; diff --git a/src/pages/preference/Index.tsx b/src/pages/preference/Index.tsx index 0e55548..e53500d 100644 --- a/src/pages/preference/Index.tsx +++ b/src/pages/preference/Index.tsx @@ -5,12 +5,8 @@ import TankComponent from "../../common/component/TankComponent"; import User from "../../common/model/user/User"; import Moon from "../../common/model/global/Moon"; import TankTitle from "../widget/TankTitle"; -import {Button, Divider, Empty, Tag, Tooltip, message} from "antd"; -import { - EditOutlined, - ThunderboltOutlined, - ScanOutlined, -} from "@ant-design/icons"; +import {Button, Divider, Empty, message} from "antd"; +import {EditOutlined, ScanOutlined, ThunderboltOutlined,} from "@ant-design/icons"; import InfoCell from "../widget/InfoCell"; import Preference from "../../common/model/preference/Preference"; import TankContentCard from "../widget/TankContentCard"; @@ -19,10 +15,7 @@ import ImagePreviewer from "../widget/previewer/ImagePreviewer"; import Lang from "../../common/model/global/Lang"; import SingleTextModal from "../widget/SingleTextModal"; import MessageBoxUtil from "../../common/util/MessageBoxUtil"; -import { - ScanScopeType, - ScanScopeTypeMap, -} from "../../common/model/preference/model/ScanScopeType"; +import {ScanScopeType, ScanScopeTypeMap,} from "../../common/model/preference/model/ScanScopeType"; import PreviewEngineCell from "./widget/PreviewEngineCell"; import PreviewEngine from "../../common/model/preference/model/PreviewEngine"; @@ -33,229 +26,229 @@ interface IState { } export default class Index extends TankComponent { - user: User = Moon.getSingleton().user; + user: User = Moon.getSingleton().user; - preference: Preference = Moon.getSingleton().preference; + preference: Preference = Moon.getSingleton().preference; - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } + this.state = {}; + } - componentDidMount() { - this.refresh(); - } + componentDidMount() { + this.refresh(); + } - //refresh preference. - refresh() { - let that = this; + //refresh preference. + refresh() { + let that = this; - that.preference.httpFetch(function () { - that.updateUI(); - }); - } - - cleanup() { - let that = this; - let preference = this.preference; - - SingleTextModal.open( - Lang.t("preference.systemCleanupPrompt"), - "", - function (text: string) { - preference.httpSystemCleanup(text, function () { - MessageBoxUtil.success(Lang.t("operationSuccess")); + that.preference.httpFetch(function () { + that.updateUI(); }); - } - ); - } + } + + cleanup() { + let that = this; + let preference = this.preference; + + SingleTextModal.open( + Lang.t("preference.systemCleanupPrompt"), + "", + function (text: string) { + preference.httpSystemCleanup(text, function () { + MessageBoxUtil.success(Lang.t("operationSuccess")); + }); + } + ); + } - immediateScan() { - const hide = message.loading(Lang.t("preference.scanLoading"), 0); - this.preference.httpScanOnce( - () => { - message.success(Lang.t("operationSuccess")); - }, - null, - hide - ); - } + immediateScan() { + const hide = message.loading(Lang.t("preference.scanLoading"), 0); + this.preference.httpScanOnce( + () => { + message.success(Lang.t("operationSuccess")); + }, + null, + hide + ); + } - render() { - const { - previewConfig: {previewEngines}, - scanConfig, - } = this.preference; + render() { + const { + previewConfig: {previewEngines}, + scanConfig, + } = this.preference; - return ( -
- - - + return ( +
+ + + - -
-
-

{Lang.t("preference.basic")}

- - - -
- - {this.preference.name} - + +
+
+

{Lang.t("preference.basic")}

+ + + +
+ + {this.preference.name} + - - {this.preference.logoUrl && ( - logo { - ImagePreviewer.showSinglePhoto(this.preference.logoUrl!); - }} - /> - )} - + + {this.preference.logoUrl && ( + logo { + ImagePreviewer.showSinglePhoto(this.preference.logoUrl!); + }} + /> + )} + - - {this.preference.faviconUrl && ( - logo { - ImagePreviewer.showSinglePhoto(this.preference.faviconUrl!); - }} - /> - )} - + + {this.preference.faviconUrl && ( + logo { + ImagePreviewer.showSinglePhoto(this.preference.faviconUrl!); + }} + /> + )} + - + - + - + - + - - {this.preference.downloadDirMaxNum === -1 - ? Lang.t("preference.noLimit") - : this.preference.downloadDirMaxNum} - + + {this.preference.downloadDirMaxNum === -1 + ? Lang.t("preference.noLimit") + : this.preference.downloadDirMaxNum} + - - {FileUtil.humanFileSize(this.preference.downloadDirMaxSize)} - + + {FileUtil.humanFileSize(this.preference.downloadDirMaxSize)} + - - {FileUtil.humanFileSize(this.preference.defaultTotalSizeLimit)} - + + {FileUtil.humanFileSize(this.preference.defaultTotalSizeLimit)} + - - {this.preference.deletedKeepDays} 天 - + + {this.preference.deletedKeepDays} 天 + - - {this.preference.allowRegister ? Lang.t("yes") : Lang.t("no")} - + + {this.preference.allowRegister ? Lang.t("yes") : Lang.t("no")} + - - - https://tank-doc.eyeblue.cn/zh - - -
+ + + https://tank-doc.eyeblue.cn/zh + + +
- + -
-
-

{Lang.t("preference.preview")}

- - - -
-
- {previewEngines.map((engine, index) => ( - - ))} - {Children.toArray( - PreviewEngine.defaultPreviewEngines().map((engine) => ( - - )) - )} +
+
+

{Lang.t("preference.preview")}

+ + + +
+
+ {previewEngines.map((engine, index) => ( + + ))} + {Children.toArray( + PreviewEngine.defaultPreviewEngines().map((engine) => ( + + )) + )} +
+
+ + + +
+
+

{Lang.t("preference.scan")}

+
+ {scanConfig.enable ? ( + ) : ""} + + + + +
+
+
+ {scanConfig.enable ? ( + <> + + {scanConfig.cron} + + + {ScanScopeTypeMap[scanConfig.scope].name} + + {scanConfig.scope === ScanScopeType.CUSTOM && ( + + {scanConfig.usernames.join(", ")} + + )} + + ) : ( + + )} +
+
+
-
- - - -
-
-

{Lang.t("preference.scan")}

-
- {scanConfig.enable ? ( - ) : ""} - - - - -
-
-
- {scanConfig.enable ? ( - <> - - {scanConfig.cron} - - - {ScanScopeTypeMap[scanConfig.scope].name} - - {scanConfig.scope === ScanScopeType.CUSTOM && ( - - {scanConfig.usernames.join(", ")} - - )} - - ) : ( - - )} -
-
-
-
- ); - } + ); + } } diff --git a/src/pages/preference/PreviewEngineEdit.tsx b/src/pages/preference/PreviewEngineEdit.tsx index fb13b5a..a335aa7 100644 --- a/src/pages/preference/PreviewEngineEdit.tsx +++ b/src/pages/preference/PreviewEngineEdit.tsx @@ -22,68 +22,68 @@ interface IState { } export default class PreviewEngineEdit extends TankComponent { - formRef = React.createRef(); - preference: Preference = Moon.getSingleton().preference; + formRef = React.createRef(); + preference: Preference = Moon.getSingleton().preference; - constructor(props: IProps) { - super(props); - this.preference.detailLoading = true; - } + constructor(props: IProps) { + super(props); + this.preference.detailLoading = true; + } - componentDidMount() { - this.refresh(); - } + componentDidMount() { + this.refresh(); + } - refresh() { - this.preference.httpFetch(() => { - this.preference.detailLoading = false; - this.updateUI(); - }); - }; - - finish(values: any) { - this.preference.assign(values); - this.preference.httpSavePreviewEngine(function () { - MessageBoxUtil.success(Lang.t("operationSuccess")); - Sun.updateFrame(); - Sun.navigateTo("/preference/index"); - }); - }; - - render() { - const {preference} = this; - const layout = { - labelCol: {span: 6}, - wrapperCol: {span: 18}, + refresh() { + this.preference.httpFetch(() => { + this.preference.detailLoading = false; + this.updateUI(); + }); }; - return ( -
- - -
this.finish(e)} - onValuesChange={this.updateUI} - > - -
- {Lang.t("preference.previewConfig")} - -
- }> - -
-
- + finish(values: any) { + this.preference.assign(values); + this.preference.httpSavePreviewEngine(function () { + MessageBoxUtil.success(Lang.t("operationSuccess")); + Sun.updateFrame(); + Sun.navigateTo("/preference/index"); + }); + }; + + render() { + const {preference} = this; + const layout = { + labelCol: {span: 6}, + wrapperCol: {span: 18}, + }; + + return ( +
+ + + this.finish(e)} + onValuesChange={this.updateUI} + > + +
+ {Lang.t("preference.previewConfig")} + +
+ }> + +
+
+ +
+ +
- - -
- ); - } + ); + } } diff --git a/src/pages/preference/ScanEdit.tsx b/src/pages/preference/ScanEdit.tsx index 3226e91..a42f8b8 100644 --- a/src/pages/preference/ScanEdit.tsx +++ b/src/pages/preference/ScanEdit.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { RouteComponentProps } from "react-router-dom"; +import {RouteComponentProps} from "react-router-dom"; import "./ScanEdit.less"; import TankComponent from "../../common/component/TankComponent"; import Preference from "../../common/model/preference/Preference"; @@ -7,210 +7,205 @@ import Moon from "../../common/model/global/Moon"; import Lang from "../../common/model/global/Lang"; import TankTitle from "../widget/TankTitle"; import TankContentCard from "../widget/TankContentCard"; -import { Button, Form, Input, Select, Spin, Switch } from "antd"; -import { FormInstance } from "antd/lib/form"; -import { SaveOutlined } from "@ant-design/icons"; +import {Button, Form, Input, Select, Spin, Switch} from "antd"; +import {FormInstance} from "antd/lib/form"; +import {SaveOutlined} from "@ant-design/icons"; import MessageBoxUtil from "../../common/util/MessageBoxUtil"; import Sun from "../../common/model/global/Sun"; -import { - ScanScopeType, - ScanScopeTypeList, -} from "../../common/model/preference/model/ScanScopeType"; -import { - ScanCronType, - ScanCronTypeList, - ScanCronTypeValueList, -} from "../../common/model/preference/model/ScanCronType"; +import {ScanScopeType, ScanScopeTypeList,} from "../../common/model/preference/model/ScanScopeType"; +import {ScanCronType, ScanCronTypeList, ScanCronTypeValueList,} from "../../common/model/preference/model/ScanCronType"; import Pager from "../../common/model/base/Pager"; import User from "../../common/model/user/User"; import SortDirection from "../../common/model/base/SortDirection"; -interface IProps extends RouteComponentProps {} +interface IProps extends RouteComponentProps { +} -interface IState {} +interface IState { +} export default class ScanEdit extends TankComponent { - formRef = React.createRef(); + formRef = React.createRef(); - preference: Preference = Moon.getSingleton().preference; - pager: Pager = new Pager(this, User, 10); + preference: Preference = Moon.getSingleton().preference; + pager: Pager = new Pager(this, User, 10); - constructor(props: IProps) { - super(props); - this.preference.detailLoading = true; - } - - componentDidMount() { - this.preference.httpFetch(() => { - this.preference.detailLoading = false; - - // 给前端辅助字段赋值 - this.preference.scanConfig.cronType = this.preference.scanConfig.cron; - if ( - !ScanCronTypeValueList.includes(this.preference.scanConfig.cronType!) - ) { - this.preference.scanConfig.cronType = ScanCronType.CUSTOM; - } - - if (this.preference.scanConfig.scope !== ScanScopeType.ALL) { - this.preference.scanConfig.users = this.preference.scanConfig.usernames.map( - (name: string) => ({ - label: name, - value: name, - }) - ); - } - - this.updateUI(); - }); - } - - finish(values: any) { - if (values.scope === ScanScopeType.CUSTOM) { - this.preference.scanConfig.assign({ - ...values, - usernames: values.users.map((item: any) => item.value), - }); - } else { - this.preference.scanConfig.assign(values); + constructor(props: IProps) { + super(props); + this.preference.detailLoading = true; } - this.preference.httpSaveScan(function () { - MessageBoxUtil.success(Lang.t("operationSuccess")); - Sun.updateFrame(); - Sun.navigateTo("/preference/index"); - }); - }; + componentDidMount() { + this.preference.httpFetch(() => { + this.preference.detailLoading = false; - changeEnableScan(value: boolean) { - this.preference.scanConfig.enable = value; - this.updateUI(); - }; + // 给前端辅助字段赋值 + this.preference.scanConfig.cronType = this.preference.scanConfig.cron; + if ( + !ScanCronTypeValueList.includes(this.preference.scanConfig.cronType!) + ) { + this.preference.scanConfig.cronType = ScanCronType.CUSTOM; + } - changeCronType(value: ScanCronType) { - this.preference.scanConfig.cronType = value; - this.updateUI(); - }; + if (this.preference.scanConfig.scope !== ScanScopeType.ALL) { + this.preference.scanConfig.users = this.preference.scanConfig.usernames.map( + (name: string) => ({ + label: name, + value: name, + }) + ); + } - changeScopeType(value: ScanScopeType) { - this.preference.scanConfig.scope = value; - this.updateUI(); - }; + this.updateUI(); + }); + } - fetchUser(value: any) { - this.pager.resetFilter(); - this.pager.setFilterValue("orderCreateTime", SortDirection.DESC); - this.pager.setFilterValue("username", value); - this.pager.httpList(); - }; + finish(values: any) { + if (values.scope === ScanScopeType.CUSTOM) { + this.preference.scanConfig.assign({ + ...values, + usernames: values.users.map((item: any) => item.value), + }); + } else { + this.preference.scanConfig.assign(values); + } - render() { - const { preference, pager } = this; - - const layout = { - labelCol: { span: 6 }, - wrapperCol: { span: 18 }, + this.preference.httpSaveScan(function () { + MessageBoxUtil.success(Lang.t("operationSuccess")); + Sun.updateFrame(); + Sun.navigateTo("/preference/index"); + }); }; - return ( -
- - -
this.updateUI} - > - - - - {preference.scanConfig.enable && ( - <> - - - - {preference.scanConfig.cronType === ScanCronType.CUSTOM && ( - - - - )} - - - - {preference.scanConfig.scope === ScanScopeType.CUSTOM && ( - - - - )} - - )} -
- + + + {preference.scanConfig.enable && ( + <> + + + + {preference.scanConfig.cronType === ScanCronType.CUSTOM && ( + + + + )} + + + + {preference.scanConfig.scope === ScanScopeType.CUSTOM && ( + + + + )} + + )} +
+ +
+ +
- -
-
- ); - } + ); + } } diff --git a/src/pages/preference/widget/PreviewConfigPanel.tsx b/src/pages/preference/widget/PreviewConfigPanel.tsx index e4052d2..1fa4e6e 100644 --- a/src/pages/preference/widget/PreviewConfigPanel.tsx +++ b/src/pages/preference/widget/PreviewConfigPanel.tsx @@ -4,66 +4,67 @@ import TankComponent from "../../../common/component/TankComponent"; import PreviewConfig from "../../../common/model/preference/model/PreviewConfig"; import PreviewEngine from "../../../common/model/preference/model/PreviewEngine"; import PreviewEngineEditCell from "./PreviewEngineEditCell"; -import { Button } from "antd"; -import { PlusOutlined } from "@ant-design/icons"; +import {Button} from "antd"; +import {PlusOutlined} from "@ant-design/icons"; import Lang from "../../../common/model/global/Lang"; interface IProps { - previewConfig: PreviewConfig; + previewConfig: PreviewConfig; } -interface IState {} +interface IState { +} export default class PreviewConfigPanel extends TankComponent { - constructor(props: IProps) { - super(props); - this.state = {}; - } + constructor(props: IProps) { + super(props); + this.state = {}; + } - addEngine() { - let previewConfig: PreviewConfig = this.props.previewConfig; + addEngine() { + let previewConfig: PreviewConfig = this.props.previewConfig; - let engine: PreviewEngine = new PreviewEngine(); + let engine: PreviewEngine = new PreviewEngine(); - previewConfig.previewEngines.push(engine); + previewConfig.previewEngines.push(engine); - this.updateUI(); - }; + this.updateUI(); + }; - delEngineCell(index: number) { - this.props.previewConfig.previewEngines.splice(index, 1); - this.updateUI(); - }; + delEngineCell(index: number) { + this.props.previewConfig.previewEngines.splice(index, 1); + this.updateUI(); + }; - render() { - const { previewConfig } = this.props; + render() { + const {previewConfig} = this.props; - return ( -
- {previewConfig.previewEngines.map( - (previewEngine: PreviewEngine, index: number) => { - return ( - { - this.delEngineCell(index); - }} - /> - ); - } - )} + return ( +
+ {previewConfig.previewEngines.map( + (previewEngine: PreviewEngine, index: number) => { + return ( + { + this.delEngineCell(index); + }} + /> + ); + } + )} - -
- ); - } + +
+ ); + } } diff --git a/src/pages/preference/widget/PreviewEngineCell.less b/src/pages/preference/widget/PreviewEngineCell.less index fd5a9d2..6693e7c 100644 --- a/src/pages/preference/widget/PreviewEngineCell.less +++ b/src/pages/preference/widget/PreviewEngineCell.less @@ -3,11 +3,13 @@ border: 1px solid #eee; padding: 10px 10px 0; margin-bottom: 10px; + .tip-box { position: absolute; right: 0; top: 0; } + .title { font-size: 16px; margin-bottom: 10px; diff --git a/src/pages/preference/widget/PreviewEngineCell.tsx b/src/pages/preference/widget/PreviewEngineCell.tsx index 2d3c499..c4bd0c9 100644 --- a/src/pages/preference/widget/PreviewEngineCell.tsx +++ b/src/pages/preference/widget/PreviewEngineCell.tsx @@ -6,49 +6,49 @@ import Lang from "../../../common/model/global/Lang"; import InfoCell from "../../widget/InfoCell"; interface IProps { - engine: PreviewEngine; - order?: number; // 从1开始 + engine: PreviewEngine; + order?: number; // 从1开始 } export default function PreviewEngineCell(props: IProps) { - const {engine, order} = props; + const {engine, order} = props; - return ( -
-
-

- {order ? Lang.t("preference.previewEngine", order) : Lang.t("preference.defaultPreview")} -

- - {engine.url === '{originUrl}' ? '{url}' : engine.url} - - - {engine.extensions} - -
-
- { - order ? null : ( - - - {Lang.t("preference.defaultPreview")} - - - ) - } - - {engine.previewInSite ? ( - - {Lang.t("preference.previewCurrent")} - - ) : ( - - {Lang.t("preference.previewOpen")} - - )} - -
+ return ( +
+
+

+ {order ? Lang.t("preference.previewEngine", order) : Lang.t("preference.defaultPreview")} +

+ + {engine.url === '{originUrl}' ? '{url}' : engine.url} + + + {engine.extensions} + +
+
+ { + order ? null : ( + + + {Lang.t("preference.defaultPreview")} + + + ) + } + + {engine.previewInSite ? ( + + {Lang.t("preference.previewCurrent")} + + ) : ( + + {Lang.t("preference.previewOpen")} + + )} + +
-
- ); +
+ ); } diff --git a/src/pages/preference/widget/PreviewEngineEditCell.tsx b/src/pages/preference/widget/PreviewEngineEditCell.tsx index 8c9cc56..8b6d8ff 100644 --- a/src/pages/preference/widget/PreviewEngineEditCell.tsx +++ b/src/pages/preference/widget/PreviewEngineEditCell.tsx @@ -2,114 +2,114 @@ import React from "react"; import "./PreviewEngineEditCell.less"; import TankComponent from "../../../common/component/TankComponent"; import PreviewEngine from "../../../common/model/preference/model/PreviewEngine"; -import { DeleteOutlined } from "@ant-design/icons"; -import { Form, Input, Switch, Tooltip } from "antd"; +import {DeleteOutlined, QuestionCircleOutlined} from "@ant-design/icons"; +import {Form, Input, Switch, Tooltip} from "antd"; import Lang from "../../../common/model/global/Lang"; -import { QuestionCircleOutlined } from "@ant-design/icons"; interface IProps { - previewEngine: PreviewEngine; - index: number; - onDelete: () => void; + previewEngine: PreviewEngine; + index: number; + onDelete: () => void; } -interface IState {} +interface IState { +} export default class PreviewEngineEditCell extends TankComponent { - constructor(props: IProps) { - super(props); - } + constructor(props: IProps) { + super(props); + } - render() { - const { previewEngine } = this.props; + render() { + const {previewEngine} = this.props; - return ( -
-
- {Lang.t("preference.engine", this.props.index + 1)} - + return ( +
+
+ {Lang.t("preference.engine", this.props.index + 1)} + { - this.props.onDelete(); - }} + className="btn-action text-danger" + onClick={() => { + this.props.onDelete(); + }} /> -
-
- -
- {Lang.t("preference.engineReg")} -
- - } - rules={[ - { required: true, message: Lang.t("preference.engineRegHelper") }, - ]} - > - { - previewEngine.url = e.target.value; - this.updateUI(); - }} - /> -
+
+ +
+ {Lang.t("preference.engineReg")} + +
+ + } + rules={[ + {required: true, message: Lang.t("preference.engineRegHelper")}, + ]} + > + { + previewEngine.url = e.target.value; + this.updateUI(); + }} + /> +
- -
- {Lang.t("preference.engineSuffix")} - -
- - } - rules={[ - { - required: true, - message: Lang.t("preference.engineSuffixPlaceHolder"), - }, - ]} - > - { - previewEngine.extensions = e.target.value; - this.updateUI(); - }} - /> -
+ +
+ {Lang.t("preference.engineSuffix")} + +
+ + } + rules={[ + { + required: true, + message: Lang.t("preference.engineSuffixPlaceHolder"), + }, + ]} + > + { + previewEngine.extensions = e.target.value; + this.updateUI(); + }} + /> +
- -
- {Lang.t("preference.previewCurrent")} - + +
+ {Lang.t("preference.previewCurrent")} + +
+ + } + > + { + previewEngine.previewInSite = val; + this.updateUI(); + }} + /> +
- - } - > - { - previewEngine.previewInSite = val; - this.updateUI(); - }} - /> -
-
-
- ); - } +
+ ); + } } diff --git a/src/pages/share/Detail.tsx b/src/pages/share/Detail.tsx index 258221c..ea947d0 100644 --- a/src/pages/share/Detail.tsx +++ b/src/pages/share/Detail.tsx @@ -23,7 +23,7 @@ import ImagePreviewer from "../widget/previewer/ImagePreviewer"; import Lang from "../../common/model/global/Lang"; interface RouteParam { - uuid: string; + uuid: string; } interface IProps extends RouteComponentProps { @@ -33,271 +33,271 @@ interface IState { } export default class Detail extends TankComponent { - // 默认分享详情中分页大小 - static sharePagerSize = 50; + // 默认分享详情中分页大小 + static sharePagerSize = 50; - //当前面包屑模型数组。 - breadcrumbModels: BreadcrumbModel[] = []; + //当前面包屑模型数组。 + breadcrumbModels: BreadcrumbModel[] = []; - // 是否需要提取码 - needShareCode = true; + // 是否需要提取码 + needShareCode = true; - share = new Share(this); - pager = new Pager(this, Matter, Detail.sharePagerSize); - user = Moon.getSingleton().user; + share = new Share(this); + pager = new Pager(this, Matter, Detail.sharePagerSize); + user = Moon.getSingleton().user; - constructor(props: IProps) { - super(props); - } - - componentDidMount(): void { - this.share.uuid = this.props.match.params.uuid; - //如果query中有rootUuid那么就更新. - this.share.rootUuid = BrowserUtil.getQueryByName("shareRootUuid") || this.share.rootUuid; - - this.pager.enableHistory(); - this.refresh(); - } - - componentWillReceiveProps(nextProps: Readonly, nextContext: any) { - if (this.props.location.search !== nextProps.location.search) { - this.refresh(); - } - } - - refresh() { - const puuid = BrowserUtil.getQueryByName("puuid") || Matter.MATTER_ROOT; - if (puuid === Matter.MATTER_ROOT) { - this.share.rootUuid = Matter.MATTER_ROOT + constructor(props: IProps) { + super(props); } - this.share.httpBrowse(puuid, this.share.rootUuid, () => { - if (puuid === Matter.MATTER_ROOT) { - this.pager.clear(); - this.pager.totalItems = this.share.matters.length; - this.pager.data = this.share.matters; - } + componentDidMount(): void { + this.share.uuid = this.props.match.params.uuid; + //如果query中有rootUuid那么就更新. + this.share.rootUuid = BrowserUtil.getQueryByName("shareRootUuid") || this.share.rootUuid; - //刷新面包屑 - this.refreshBreadcrumbs(); - - this.needShareCode = false; - this.updateUI(); - }); - - this.refreshMatterPager(); - }; - - refreshMatterPager() { - //只有当鉴权通过,并且不是分享根目录时需要才去进行page请求,根目录下matters已经通过browse接口拿到了 - const puuid = BrowserUtil.getQueryByName("puuid"); - if (!this.needShareCode && puuid && puuid !== Matter.MATTER_ROOT) { - const { - uuid: shareUuid, - code: shareCode, - rootUuid: shareRootUuid, - } = this.share; - this.pager.setFilterValues({ - puuid, - shareUuid, - shareCode, - shareRootUuid, - orderCreateTime: SortDirection.DESC, // 默认以时间降序 - orderDir: SortDirection.DESC, // 默认文件夹排在前面 - }); - this.pager.httpList(); + this.pager.enableHistory(); + this.refresh(); } - }; - getFiles(value: string) { - this.share.code = value; - this.refresh(); - }; - - downloadZip() { - const puuid = BrowserUtil.getQueryByName("puuid") || Matter.MATTER_ROOT; - this.share.downloadZip(puuid); - }; - - cancelShare() { - Modal.confirm({ - title: Lang.t("share.cancelPrompt"), - icon: , - onOk: () => { - this.share.httpDel(() => { - MessageBoxUtil.success(Lang.t("operationSuccess")); - Sun.navigateTo("/share/list"); - }); - }, - }); - }; - - previewImage(matter: Matter) { - let imageArray: string[] = []; - let startIndex = -1; - const {share} = this; - this.pager.data.forEach((item) => { - if (item.isImage()) { - imageArray.push(item.getSharePreviewUrl(share.uuid!, share.code!, share.rootUuid)); - if (item.uuid === matter.uuid) { - startIndex = imageArray.length - 1; + componentWillReceiveProps(nextProps: Readonly, nextContext: any) { + if (this.props.location.search !== nextProps.location.search) { + this.refresh(); } - } - }); - - ImagePreviewer.showMultiPhoto(imageArray, startIndex); - }; - - goToDirectory(matterUuid?: string) { - const paramId = this.props.match.params.uuid; - - if (matterUuid) { - //share.rootUuid 一旦设置好了,只要根文件夹不换,那么就一直不会变。 - const puuid = BrowserUtil.getQueryByName("puuid"); - if (!puuid || puuid === Matter.MATTER_ROOT) { - this.share.rootUuid = matterUuid; - this.pager.clear(); - } - - this.pager.setFilterValue("puuid", matterUuid); - this.pager.page = 0; - const query = this.pager.getParams(); - Sun.navigateQueryTo({path: `/share/detail/${paramId}`, query}); - } else { - // 回到分享根目录,先将rootUuid交给根目录 - this.share.rootUuid = Matter.MATTER_ROOT; - this.pager.clear(); - Sun.navigateQueryTo({path: `/share/detail/${paramId}`}); } - }; - refreshBreadcrumbs() { - let that = this; + refresh() { + const puuid = BrowserUtil.getQueryByName("puuid") || Matter.MATTER_ROOT; + if (puuid === Matter.MATTER_ROOT) { + this.share.rootUuid = Matter.MATTER_ROOT + } - //清空 - that.breadcrumbModels = []; + this.share.httpBrowse(puuid, this.share.rootUuid, () => { + if (puuid === Matter.MATTER_ROOT) { + this.pager.clear(); + this.pager.totalItems = this.share.matters.length; + this.pager.data = this.share.matters; + } - that.breadcrumbModels.push({ - name: Lang.t("layout.allFiles"), - path: "/share/detail/" + this.share.uuid, - query: {}, - displayDirect: false, - }); + //刷新面包屑 + this.refreshBreadcrumbs(); - let pMatter = this.share.dirMatter; - while (pMatter && pMatter.uuid) { - //插入到最前面 - let query = this.pager.getParams(); - query["puuid"] = pMatter.uuid; - that.breadcrumbModels.splice(1, 0, { - name: pMatter.name, - path: "/share/detail/" + this.share.uuid, - query: query, - displayDirect: false, - }); - pMatter = pMatter.parent!; - } - }; + this.needShareCode = false; + this.updateUI(); + }); - render() { - const {share, needShareCode, user, pager} = this; + this.refreshMatterPager(); + }; - if (share.detailLoading && needShareCode) return ; - return ( -
- - {needShareCode ? ( -
- - - - - -
- ) : ( -
-
-
-
- - + refreshMatterPager() { + //只有当鉴权通过,并且不是分享根目录时需要才去进行page请求,根目录下matters已经通过browse接口拿到了 + const puuid = BrowserUtil.getQueryByName("puuid"); + if (!this.needShareCode && puuid && puuid !== Matter.MATTER_ROOT) { + const { + uuid: shareUuid, + code: shareCode, + rootUuid: shareRootUuid, + } = this.share; + this.pager.setFilterValues({ + puuid, + shareUuid, + shareCode, + shareRootUuid, + orderCreateTime: SortDirection.DESC, // 默认以时间降序 + orderDir: SortDirection.DESC, // 默认文件夹排在前面 + }); + this.pager.httpList(); + } + }; + + getFiles(value: string) { + this.share.code = value; + this.refresh(); + }; + + downloadZip() { + const puuid = BrowserUtil.getQueryByName("puuid") || Matter.MATTER_ROOT; + this.share.downloadZip(puuid); + }; + + cancelShare() { + Modal.confirm({ + title: Lang.t("share.cancelPrompt"), + icon: , + onOk: () => { + this.share.httpDel(() => { + MessageBoxUtil.success(Lang.t("operationSuccess")); + Sun.navigateTo("/share/list"); + }); + }, + }); + }; + + previewImage(matter: Matter) { + let imageArray: string[] = []; + let startIndex = -1; + const {share} = this; + this.pager.data.forEach((item) => { + if (item.isImage()) { + imageArray.push(item.getSharePreviewUrl(share.uuid!, share.code!, share.rootUuid)); + if (item.uuid === matter.uuid) { + startIndex = imageArray.length - 1; + } + } + }); + + ImagePreviewer.showMultiPhoto(imageArray, startIndex); + }; + + goToDirectory(matterUuid?: string) { + const paramId = this.props.match.params.uuid; + + if (matterUuid) { + //share.rootUuid 一旦设置好了,只要根文件夹不换,那么就一直不会变。 + const puuid = BrowserUtil.getQueryByName("puuid"); + if (!puuid || puuid === Matter.MATTER_ROOT) { + this.share.rootUuid = matterUuid; + this.pager.clear(); + } + + this.pager.setFilterValue("puuid", matterUuid); + this.pager.page = 0; + const query = this.pager.getParams(); + Sun.navigateQueryTo({path: `/share/detail/${paramId}`, query}); + } else { + // 回到分享根目录,先将rootUuid交给根目录 + this.share.rootUuid = Matter.MATTER_ROOT; + this.pager.clear(); + Sun.navigateQueryTo({path: `/share/detail/${paramId}`}); + } + }; + + refreshBreadcrumbs() { + let that = this; + + //清空 + that.breadcrumbModels = []; + + that.breadcrumbModels.push({ + name: Lang.t("layout.allFiles"), + path: "/share/detail/" + this.share.uuid, + query: {}, + displayDirect: false, + }); + + let pMatter = this.share.dirMatter; + while (pMatter && pMatter.uuid) { + //插入到最前面 + let query = this.pager.getParams(); + query["puuid"] = pMatter.uuid; + that.breadcrumbModels.splice(1, 0, { + name: pMatter.name, + path: "/share/detail/" + this.share.uuid, + query: query, + displayDirect: false, + }); + pMatter = pMatter.parent!; + } + }; + + render() { + const {share, needShareCode, user, pager} = this; + + if (share.detailLoading && needShareCode) return ; + return ( +
+ + {needShareCode ? ( +
+ + + + + +
+ ) : ( +
+
+
+
+ + {share.name} - {share.hasExpired() ? ( - + {share.hasExpired() ? ( + {Lang.t("share.expired")} - ) : null} + ) : null} -
-
- - - {user.uuid && user.uuid === share.userUuid ? ( - <> - - - - ) : null} - -
-
-
- +
+
+ + + {user.uuid && user.uuid === share.userUuid ? ( + <> + + + + ) : null} + +
+
+
+ {Lang.t("share.sharer")}: {share.username} - + {Lang.t("createTime")}:{" "} - {DateUtil.simpleDateHourMinute(share.createTime)} + {DateUtil.simpleDateHourMinute(share.createTime)} - + {share.expireInfinity - ? Lang.t("share.noExpire") - : `${Lang.t( - "share.expireTime" - )}:${DateUtil.simpleDateHourMinute(share.expireTime)}`} + ? Lang.t("share.noExpire") + : `${Lang.t( + "share.expireTime" + )}:${DateUtil.simpleDateHourMinute(share.expireTime)}`} - -
-
+ +
+
-
- -
+
+ +
- {pager.data.length ? ( - pager.data.map((matter) => ( - - )) - ) : ( - - )} -
- )} -
- ); - } + {pager.data.length ? ( + pager.data.map((matter) => ( + + )) + ) : ( + + )} +
+ )} +
+ ); + } } diff --git a/src/pages/share/List.tsx b/src/pages/share/List.tsx index 318e61f..8236b33 100644 --- a/src/pages/share/List.tsx +++ b/src/pages/share/List.tsx @@ -17,52 +17,52 @@ interface IState { } export default class List extends TankComponent { - pager = new Pager(this, Share, Pager.MAX_PAGE_SIZE); + pager = new Pager(this, Share, Pager.MAX_PAGE_SIZE); - constructor(props: IProps) { - super(props); - } + constructor(props: IProps) { + super(props); + } - componentDidMount() { - this.pager.enableHistory(); - this.refresh(); - } + componentDidMount() { + this.pager.enableHistory(); + this.refresh(); + } - refresh() { - this.pager.httpList(); - }; + refresh() { + this.pager.httpList(); + }; - changePage(page: number) { - this.pager.page = page - 1; // page的页数0基 - this.pager.httpList(); - this.updateUI(); - }; + changePage(page: number) { + this.pager.page = page - 1; // page的页数0基 + this.pager.httpList(); + this.updateUI(); + }; - render() { - const {pager} = this; + render() { + const {pager} = this; - return ( -
- + return ( +
+ - {pager.data.map((share) => ( - this.refresh()}/> - ))} + {pager.data.map((share) => ( + this.refresh()}/> + ))} - + - {pager.isEmpty() && ( - - )} + {pager.isEmpty() && ( + + )} -
- ); - } +
+ ); + } } diff --git a/src/pages/share/widget/ShareBar.less b/src/pages/share/widget/ShareBar.less index a2671c1..d3035ca 100644 --- a/src/pages/share/widget/ShareBar.less +++ b/src/pages/share/widget/ShareBar.less @@ -110,6 +110,7 @@ .text { margin-left: 5px; } + .cell-btn { border-top: 1px solid #eee; line-height: @inner-cell-height; diff --git a/src/pages/share/widget/ShareBar.tsx b/src/pages/share/widget/ShareBar.tsx index a84aa4a..5b3c94a 100644 --- a/src/pages/share/widget/ShareBar.tsx +++ b/src/pages/share/widget/ShareBar.tsx @@ -1,10 +1,5 @@ import React from "react"; -import { - InfoCircleOutlined, - DeleteOutlined, - SmallDashOutlined, - ExclamationCircleFilled, -} from "@ant-design/icons"; +import {DeleteOutlined, ExclamationCircleFilled, InfoCircleOutlined, SmallDashOutlined,} from "@ant-design/icons"; import TankComponent from "../../../common/component/TankComponent"; import SafeUtil from "../../../common/util/SafeUtil"; import DateUtil from "../../../common/util/DateUtil"; @@ -12,174 +7,175 @@ import Expanding from "../../widget/Expanding"; import Share from "../../../common/model/share/Share"; import Sun from "../../../common/model/global/Sun"; import "./ShareBar.less"; -import { Modal, Tooltip } from "antd"; +import {Modal, Tooltip} from "antd"; import MessageBoxUtil from "../../../common/util/MessageBoxUtil"; import ShareDialogModal from "./ShareDialogModal"; import Lang from "../../../common/model/global/Lang"; interface IProps { - share: Share; - onDeleteSuccess: () => any; + share: Share; + onDeleteSuccess: () => any; } -interface IState {} +interface IState { +} export default class ShareBar extends TankComponent { - // 小屏幕下操作栏 - showMore = false; + // 小屏幕下操作栏 + showMore = false; - constructor(props: IProps) { - super(props); - } + constructor(props: IProps) { + super(props); + } - showShare() { - ShareDialogModal.open(this.props.share); - }; + showShare() { + ShareDialogModal.open(this.props.share); + }; - delShare() { - Modal.confirm({ - title: Lang.t("actionCanNotRevertConfirm"), - icon: , - onOk: () => { - this.props.share.httpDel(() => { - MessageBoxUtil.success(Lang.t("operationSuccess")); - this.props.onDeleteSuccess(); + delShare() { + Modal.confirm({ + title: Lang.t("actionCanNotRevertConfirm"), + icon: , + onOk: () => { + this.props.share.httpDel(() => { + MessageBoxUtil.success(Lang.t("operationSuccess")); + this.props.onDeleteSuccess(); + }); + }, }); - }, - }); - }; + }; - toggleHandles() { - this.showMore = !this.showMore; - this.updateUI(); - }; + toggleHandles() { + this.showMore = !this.showMore; + this.updateUI(); + }; - render() { - const { share } = this.props; - const { showMore } = this; - return ( -
-
- SafeUtil.stopPropagationWrap(e)( - Sun.navigateTo(`/share/detail/${share.uuid}`) - ) - } - > -
-
-
+ render() { + const {share} = this.props; + const {showMore} = this; + return ( +
+
+ SafeUtil.stopPropagationWrap(e)( + Sun.navigateTo(`/share/detail/${share.uuid}`) + ) + } + > +
+
+
- + -
-
+
+
- {/*在大屏下的操作栏*/} -
-
+ {/*在大屏下的操作栏*/} +
+
- SafeUtil.stopPropagationWrap(e)(this.showShare()) - } + className="btn-action mr5 text-theme" + onClick={(e) => + SafeUtil.stopPropagationWrap(e)(this.showShare()) + } /> - SafeUtil.stopPropagationWrap(e)(this.delShare()) - } + className="btn-action text-danger" + onClick={(e) => + SafeUtil.stopPropagationWrap(e)(this.delShare()) + } /> - + {DateUtil.simpleDateHourMinute(share.updateTime)} - + - + {share.expireInfinity - ? Lang.t("share.noExpire") - : DateUtil.simpleDateHourMinute(share.expireTime)} + ? Lang.t("share.noExpire") + : DateUtil.simpleDateHourMinute(share.expireTime)} - -
-
+ +
+
- {/*在小屏幕下的操作栏*/} -
+ {/*在小屏幕下的操作栏*/} +
- SafeUtil.stopPropagationWrap(e)(this.toggleHandles()) - } + className="more-btn" + onClick={(e) => + SafeUtil.stopPropagationWrap(e)(this.toggleHandles()) + } > - + -
+
-
-
+
+
{share.name} - {share.hasExpired() ? ( - + {share.hasExpired() ? ( + {Lang.t("share.expired")} - ) : null} + ) : null} -
-
-
-
+
+
+
+
- - {showMore ? ( -
-
+ + {showMore ? ( +
+
{Lang.t("share.shareTime")}:{" "} - {DateUtil.simpleDateHourMinute(share.createTime)} + {DateUtil.simpleDateHourMinute(share.createTime)} - + {share.expireInfinity - ? Lang.t("share.noExpire") - : `${Lang.t("expireTime")}:${DateUtil.simpleDateHourMinute( - share.expireTime + ? Lang.t("share.noExpire") + : `${Lang.t("expireTime")}:${DateUtil.simpleDateHourMinute( + share.expireTime )}`} -
+
-
- SafeUtil.stopPropagationWrap(e)(this.showShare()) - } - > - - {Lang.t("share.shareDetail")} -
+
+ SafeUtil.stopPropagationWrap(e)(this.showShare()) + } + > + + {Lang.t("share.shareDetail")} +
-
- SafeUtil.stopPropagationWrap(e)(this.delShare()) - } - > - - {Lang.t("delete")} -
+
+ SafeUtil.stopPropagationWrap(e)(this.delShare()) + } + > + + {Lang.t("delete")} +
+
+ ) : null} +
- ) : null} -
-
- ); - } + ); + } } diff --git a/src/pages/share/widget/ShareDialogModal.less b/src/pages/share/widget/ShareDialogModal.less index 8b873e4..de7b618 100644 --- a/src/pages/share/widget/ShareDialogModal.less +++ b/src/pages/share/widget/ShareDialogModal.less @@ -1,5 +1,6 @@ .widget-share-dialog-panel { margin-top: 20px; + .share-block { .share-icon { diff --git a/src/pages/share/widget/ShareDialogModal.tsx b/src/pages/share/widget/ShareDialogModal.tsx index 93e173e..0f64cfa 100644 --- a/src/pages/share/widget/ShareDialogModal.tsx +++ b/src/pages/share/widget/ShareDialogModal.tsx @@ -2,7 +2,7 @@ import React from "react"; import TankComponent from "../../../common/component/TankComponent"; import Share from "../../../common/model/share/Share"; import {Button, Modal} from "antd"; -import { CopyOutlined, ExclamationCircleFilled } from "@ant-design/icons"; +import {CopyOutlined, ExclamationCircleFilled} from "@ant-design/icons"; import DateUtil from "../../../common/util/DateUtil"; import MessageBoxUtil from "../../../common/util/MessageBoxUtil"; import './ShareDialogModal.less'; @@ -10,96 +10,97 @@ import ClipboardUtil from "../../../common/util/ClipboardUtil"; import Lang from "../../../common/model/global/Lang"; interface IProps { - share: Share; - onSuccess: () => any; - onClose: () => any; + share: Share; + onSuccess: () => any; + onClose: () => any; } -interface IState {} +interface IState { +} export default class ShareDialogModal extends TankComponent { - constructor(props: IProps) { - super(props); - } + constructor(props: IProps) { + super(props); + } - clipboard(text: string) { - ClipboardUtil.copy(text, () => { - MessageBoxUtil.success(Lang.t("copySuccess")); - }) - }; + clipboard(text: string) { + ClipboardUtil.copy(text, () => { + MessageBoxUtil.success(Lang.t("copySuccess")); + }) + }; - copyAll() { - const { share } = this.props; - const text = `${Lang.t("share.link")}:${share.getLink()} ${Lang.t("share.code")}:${share.code}`; - this.clipboard(text); - }; + copyAll() { + const {share} = this.props; + const text = `${Lang.t("share.link")}:${share.getLink()} ${Lang.t("share.code")}:${share.code}`; + this.clipboard(text); + }; - static open = (share: Share) => { - let modal = Modal.confirm({ - className: "share-modal", - title: Lang.t("share.shareDetail"), - icon: , - width: "90vw", - okCancel: false, - okButtonProps: { - className: "display-none", - }, - maskClosable: true, - content: ( - { - modal.destroy(); - }} - onClose={() => { - modal.destroy(); - }} - /> - ), + static open = (share: Share) => { + let modal = Modal.confirm({ + className: "share-modal", + title: Lang.t("share.shareDetail"), + icon: , + width: "90vw", + okCancel: false, + okButtonProps: { + className: "display-none", + }, + maskClosable: true, + content: ( + { + modal.destroy(); + }} + onClose={() => { + modal.destroy(); + }} + /> + ), - }); - }; + }); + }; - render() { - const { share } = this.props; + render() { + const {share} = this.props; - return ( -
-
-
- - {share.name} -
-
- {Lang.t("share.sharer")}:{share.username} - + return ( +
+
+
+ + {share.name} +
+
+ {Lang.t("share.sharer")}:{share.username} + {share.expireInfinity - ? Lang.t("share.noExpire") - : `${Lang.t("share.expireTime")}:${DateUtil.simpleDateHourMinute( - share.expireTime + ? Lang.t("share.noExpire") + : `${Lang.t("share.expireTime")}:${DateUtil.simpleDateHourMinute( + share.expireTime )}`} -
-
- {Lang.t("share.link")}:{share.getLink()} - this.clipboard(share.getLink())} - /> -
-
- {Lang.t("share.code")}:{share.code} - this.clipboard(share.code!)} - /> -
-
-
- - -
-
- ); - } +
+
+ {Lang.t("share.link")}:{share.getLink()} + this.clipboard(share.getLink())} + /> +
+
+ {Lang.t("share.code")}:{share.code} + this.clipboard(share.code!)} + /> +
+
+
+ + +
+
+ ); + } } diff --git a/src/pages/share/widget/ShareMatterPanel.less b/src/pages/share/widget/ShareMatterPanel.less index 0c2624f..eea6606 100644 --- a/src/pages/share/widget/ShareMatterPanel.less +++ b/src/pages/share/widget/ShareMatterPanel.less @@ -21,9 +21,11 @@ line-height: @base-height; margin-left: 10px; } - .btn-action{ + + .btn-action { font-size: 15px; } + .media { > .pull-left { padding-right: 1px; @@ -58,7 +60,8 @@ white-space: nowrap; text-overflow: ellipsis; overflow: hidden; - .icon{ + + .icon { font-size: 11px; margin-left: 3px; } @@ -126,6 +129,7 @@ border-top: 1px solid #eee; line-height: @inner-cell-height; vertical-align: middle; + &:first-child { border-top: none; } diff --git a/src/pages/share/widget/ShareMatterPanel.tsx b/src/pages/share/widget/ShareMatterPanel.tsx index d064c03..7c3fb21 100644 --- a/src/pages/share/widget/ShareMatterPanel.tsx +++ b/src/pages/share/widget/ShareMatterPanel.tsx @@ -5,159 +5,156 @@ import "./ShareMatterPanel.less"; import StringUtil from "../../../common/util/StringUtil"; import DateUtil from "../../../common/util/DateUtil"; import Expanding from "../../widget/Expanding"; -import { - UnlockOutlined, - DownloadOutlined, - EllipsisOutlined, -} from "@ant-design/icons"; -import { Tooltip } from "antd"; +import {DownloadOutlined, EllipsisOutlined, UnlockOutlined,} from "@ant-design/icons"; +import {Tooltip} from "antd"; import SafeUtil from "../../../common/util/SafeUtil"; import Lang from "../../../common/model/global/Lang"; import Share from "../../../common/model/share/Share"; import ImageUtil from "../../../common/util/ImageUtil"; interface IProps { - matter: Matter; - share: Share; - onPreviewImage: (matter: Matter) => any; - onGoToDirectory: (id: string) => any; + matter: Matter; + share: Share; + onPreviewImage: (matter: Matter) => any; + onGoToDirectory: (id: string) => any; } -interface IState {} +interface IState { +} export default class ShareMatterPanel extends TankComponent { - // 小屏幕下操作栏 - showMore: boolean = false; + // 小屏幕下操作栏 + showMore: boolean = false; - constructor(props: IProps) { - super(props); - } - - clickRow() { - const { matter, share, onGoToDirectory, onPreviewImage } = this.props; - - if (matter.dir) { - onGoToDirectory(matter.uuid!); - } else { - //图片进行预览操作 - if (matter.isImage()) { - onPreviewImage(matter); - } else { - matter.preview(matter.getSharePreviewUrl(share.uuid!, share.code!, share.rootUuid)); - } + constructor(props: IProps) { + super(props); } - }; - getIcon() { - const { matter, share } = this.props; - if (matter.isImage()) { - return ImageUtil.handleImageUrl(matter.getSharePreviewUrl(share.uuid!, share.code!, share.rootUuid), false, 100, 100) - } else { - return matter.getIcon() - } - }; + clickRow() { + const {matter, share, onGoToDirectory, onPreviewImage} = this.props; - download() { - const { matter, share } = this.props; - matter.download(matter.getShareDownloadUrl(share.uuid!, share.code!, share.rootUuid)) - }; + if (matter.dir) { + onGoToDirectory(matter.uuid!); + } else { + //图片进行预览操作 + if (matter.isImage()) { + onPreviewImage(matter); + } else { + matter.preview(matter.getSharePreviewUrl(share.uuid!, share.code!, share.rootUuid)); + } + } + }; - toggleHandles() { - this.showMore = !this.showMore; - this.updateUI(); - }; + getIcon() { + const {matter, share} = this.props; + if (matter.isImage()) { + return ImageUtil.handleImageUrl(matter.getSharePreviewUrl(share.uuid!, share.code!, share.rootUuid), false, 100, 100) + } else { + return matter.getIcon() + } + }; - render() { - const { matter } = this.props; + download() { + const {matter, share} = this.props; + matter.download(matter.getShareDownloadUrl(share.uuid!, share.code!, share.rootUuid)) + }; - return ( -
-
SafeUtil.stopPropagationWrap(e)(this.clickRow())}> -
-
-
+ toggleHandles() { + this.showMore = !this.showMore; + this.updateUI(); + }; + + render() { + const {matter} = this.props; + + return ( +
+
SafeUtil.stopPropagationWrap(e)(this.clickRow())}> +
+
+
- + -
-
+
+
- {/*在大屏幕下的操作栏*/} -
-
- - - SafeUtil.stopPropagationWrap(e)(this.download()) - } - /> - + {/*在大屏幕下的操作栏*/} +
+
+ + + SafeUtil.stopPropagationWrap(e)(this.download()) + } + /> + - + {StringUtil.humanFileSize(matter.size)} - + - + {DateUtil.simpleDateHourMinute(matter.updateTime)} - -
-
+ +
+
-
+
- SafeUtil.stopPropagationWrap(e)(this.toggleHandles()) - } + className="more-btn" + onClick={(e) => + SafeUtil.stopPropagationWrap(e)(this.toggleHandles()) + } > - + -
+
-
-
+
+
{matter.name} - {!matter.dir && !matter.privacy && ( - - - - )} + {!matter.dir && !matter.privacy && ( + + + + )} -
-
-
-
+
+
+
+
- - {this.showMore ? ( -
-
- {DateUtil.simpleDateHourMinute(matter.updateTime)} - + + {this.showMore ? ( +
+
+ {DateUtil.simpleDateHourMinute(matter.updateTime)} + {StringUtil.humanFileSize(matter.size)} -
-
- SafeUtil.stopPropagationWrap(e)(this.download()) - } - > - - {Lang.t("matter.download")} -
+
+
+ SafeUtil.stopPropagationWrap(e)(this.download()) + } + > + + {Lang.t("matter.download")} +
+
+ ) : null} +
- ) : null} -
-
- ); - } + ); + } } diff --git a/src/pages/user/Authentication.tsx b/src/pages/user/Authentication.tsx index c693cb2..1631260 100644 --- a/src/pages/user/Authentication.tsx +++ b/src/pages/user/Authentication.tsx @@ -8,7 +8,7 @@ import Lang from "../../common/model/global/Lang"; interface RouteParam { - authentication: string + authentication: string } @@ -22,40 +22,39 @@ interface IState { export default class Authentication extends TankComponent { - //登录的那个用户 - user: User = Moon.getSingleton().user + //登录的那个用户 + user: User = Moon.getSingleton().user - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } + this.state = {}; + } - componentDidMount() { - let match = this.props.match; + componentDidMount() { + let match = this.props.match; + this.user.httpAuthenticationLogin(match.params.authentication, function () { + //转跳到首页 + //Sun.navigateTo("/") + window.location.href = "/" + }) + } - this.user.httpAuthenticationLogin(match.params.authentication, function () { - //转跳到首页 - //Sun.navigateTo("/") - window.location.href = "/" - }) - } + render() { - render() { + let that = this - let that = this + let user: User = this.user - let user: User = this.user - - return ( -
- {Lang.t("user.redirecting")} -
- ); - } + return ( +
+ {Lang.t("user.redirecting")} +
+ ); + } } diff --git a/src/pages/user/Detail.less b/src/pages/user/Detail.less index c174b99..83c1591 100644 --- a/src/pages/user/Detail.less +++ b/src/pages/user/Detail.less @@ -1,6 +1,7 @@ .page-user-detail { .handles { flex-wrap: wrap; + &-mobile { button { margin-bottom: 10px; diff --git a/src/pages/user/Detail.tsx b/src/pages/user/Detail.tsx index fa8ba26..1e72376 100644 --- a/src/pages/user/Detail.tsx +++ b/src/pages/user/Detail.tsx @@ -1,254 +1,252 @@ import React from "react"; import "./Detail.less"; import TankComponent from "../../common/component/TankComponent"; -import { Button, Tag, Space } from "antd"; +import {Button, Space, Tag} from "antd"; import InfoCell from "../widget/InfoCell"; import User from "../../common/model/user/User"; import Moon from "../../common/model/global/Moon"; import DateUtil from "../../common/util/DateUtil"; import TankTitle from "../widget/TankTitle"; import TankContentCard from "../widget/TankContentCard"; -import { Link, RouteComponentProps } from "react-router-dom"; +import {Link, RouteComponentProps} from "react-router-dom"; import ImagePreviewer from "../widget/previewer/ImagePreviewer"; -import { UserRole, UserRoleMap } from "../../common/model/user/UserRole"; +import {UserRole, UserRoleMap} from "../../common/model/user/UserRole"; import FileUtil from "../../common/util/FileUtil"; -import { UserStatus, UserStatusMap } from "../../common/model/user/UserStatus"; +import {UserStatus, UserStatusMap} from "../../common/model/user/UserStatus"; import BrowserUtil from "../../common/util/BrowserUtil"; import SingleTextModal from "../widget/SingleTextModal"; import MessageBoxUtil from "../../common/util/MessageBoxUtil"; import ChangePasswordModal from "./widget/ChangePasswordModal"; -import { - EditOutlined, - UnlockOutlined, - UserSwitchOutlined, -} from "@ant-design/icons"; +import {EditOutlined, UnlockOutlined, UserSwitchOutlined,} from "@ant-design/icons"; import TransfigurationModal from "./widget/TransfigurationModal"; -import { FileSyncOutlined, StopOutlined } from "@ant-design/icons/lib"; +import {FileSyncOutlined, StopOutlined} from "@ant-design/icons/lib"; import Lang from "../../common/model/global/Lang"; import Sun from "../../common/model/global/Sun"; interface RouteParam { - uuid: string; + uuid: string; } -interface IProps extends RouteComponentProps {} +interface IProps extends RouteComponentProps { +} -interface IState {} +interface IState { +} export default class Detail extends TankComponent { - //登录的那个用户 - user: User = Moon.getSingleton().user; + //登录的那个用户 + user: User = Moon.getSingleton().user; - //当前页面正在编辑的用户 - currentUser: User = new User(this); + //当前页面正在编辑的用户 + currentUser: User = new User(this); - //sync loading. - syncLoading: boolean = false; + //sync loading. + syncLoading: boolean = false; - constructor(props: IProps) { - super(props); - this.state = {}; - } + constructor(props: IProps) { + super(props); + this.state = {}; + } - componentDidMount() { - let that = this; - let match = this.props.match; - this.currentUser.uuid = match.params.uuid; - this.currentUser.httpDetail(); - } + componentDidMount() { + let that = this; + let match = this.props.match; + this.currentUser.uuid = match.params.uuid; + this.currentUser.httpDetail(); + } - resetPassword() { - let that = this; + resetPassword() { + let that = this; - SingleTextModal.open(Lang.t("user.enterNewPassword"), "", function ( - text: string - ) { - that.currentUser.httpResetPassword(text, function (response: any) { - MessageBoxUtil.success(Lang.t("operationSuccess")); - }); - }); - } + SingleTextModal.open(Lang.t("user.enterNewPassword"), "", function ( + text: string + ) { + that.currentUser.httpResetPassword(text, function (response: any) { + MessageBoxUtil.success(Lang.t("operationSuccess")); + }); + }); + } - transfiguration() { - let user: User = this.user; - let currentUser: User = this.currentUser; - TransfigurationModal.open(currentUser); - } + transfiguration() { + let user: User = this.user; + let currentUser: User = this.currentUser; + TransfigurationModal.open(currentUser); + } - toggleStatus() { - let that = this; - let user: User = this.user; - let currentUser: User = this.currentUser; - currentUser.httpToggleStatus(function () { - MessageBoxUtil.success(Lang.t("operationSuccess")); - that.updateUI(); - }); - } + toggleStatus() { + let that = this; + let user: User = this.user; + let currentUser: User = this.currentUser; + currentUser.httpToggleStatus(function () { + MessageBoxUtil.success(Lang.t("operationSuccess")); + that.updateUI(); + }); + } - syncPhysics() { - let that = this; - let user: User = this.user; - let currentUser: User = this.currentUser; - this.syncLoading = true; - currentUser.httpScan( - function () { - MessageBoxUtil.success(Lang.t("operationSuccess")); - that.updateUI(); - }, - null, - function () { - that.syncLoading = false; - that.updateUI(); - } - ); - } + syncPhysics() { + let that = this; + let user: User = this.user; + let currentUser: User = this.currentUser; + this.syncLoading = true; + currentUser.httpScan( + function () { + MessageBoxUtil.success(Lang.t("operationSuccess")); + that.updateUI(); + }, + null, + function () { + that.syncLoading = false; + that.updateUI(); + } + ); + } - changePassword() { - let user: User = this.user; - let currentUser: User = this.currentUser; - ChangePasswordModal.open(currentUser, function () { - MessageBoxUtil.success(Lang.t("operationSuccess")); - }); - } + changePassword() { + let user: User = this.user; + let currentUser: User = this.currentUser; + ChangePasswordModal.open(currentUser, function () { + MessageBoxUtil.success(Lang.t("operationSuccess")); + }); + } - render() { - const user: User = this.user; - const currentUser: User = this.currentUser; + render() { + const user: User = this.user; + const currentUser: User = this.currentUser; - const handles = ( - - {user.role === UserRole.ADMINISTRATOR && ( - - )} + const handles = ( + + {user.role === UserRole.ADMINISTRATOR && ( + + )} - {user.role === UserRole.ADMINISTRATOR && ( - - )} + {user.role === UserRole.ADMINISTRATOR && ( + + )} - {currentUser.uuid === user.uuid && ( - - )} + {currentUser.uuid === user.uuid && ( + + )} - - - + + + - {user.role === UserRole.ADMINISTRATOR && - currentUser.uuid !== user.uuid && ( - - )} + {user.role === UserRole.ADMINISTRATOR && + currentUser.uuid !== user.uuid && ( + + )} - {user.role === UserRole.ADMINISTRATOR && ( - - )} - - ); + {user.role === UserRole.ADMINISTRATOR && ( + + )} + + ); - return ( -
- - {!Sun.getSingleton().isMobile && handles} - - {Sun.getSingleton().isMobile && handles} + return ( +
+ + {!Sun.getSingleton().isMobile && handles} + + {Sun.getSingleton().isMobile && handles} - -
- avatar { - ImagePreviewer.showSinglePhoto(currentUser.getAvatarUrl(true)); - }} - /> -
{currentUser.username}
-
+ +
+ avatar { + ImagePreviewer.showSinglePhoto(currentUser.getAvatarUrl(true)); + }} + /> +
{currentUser.username}
+
- - - {UserRoleMap[currentUser.role].name} - - + + + {UserRoleMap[currentUser.role].name} + + - - {FileUtil.humanFileSize(currentUser.sizeLimit)} - + + {FileUtil.humanFileSize(currentUser.sizeLimit)} + - - {FileUtil.humanFileSize(currentUser.totalSizeLimit)} - + + {FileUtil.humanFileSize(currentUser.totalSizeLimit)} + - - {FileUtil.humanFileSize(currentUser.totalSize)} - + + {FileUtil.humanFileSize(currentUser.totalSize)} + - - - {UserStatusMap[currentUser.status].name} - - + + + {UserStatusMap[currentUser.status].name} + + - - {currentUser.lastIp} - + + {currentUser.lastIp} + - - {DateUtil.simpleDateTime(currentUser.lastTime)} - + + {DateUtil.simpleDateTime(currentUser.lastTime)} + - - {BrowserUtil.fullHost() + "/api/dav"} - + + {BrowserUtil.fullHost() + "/api/dav"} + - {currentUser.role === UserRole.ADMINISTRATOR && ( - - - https://tank-doc.eyeblue.cn - - - )} -
-
- ); - } + {currentUser.role === UserRole.ADMINISTRATOR && ( + + + https://tank-doc.eyeblue.cn + + + )} + +
+ ); + } } diff --git a/src/pages/user/Edit.tsx b/src/pages/user/Edit.tsx index 3ba7438..896007c 100644 --- a/src/pages/user/Edit.tsx +++ b/src/pages/user/Edit.tsx @@ -19,7 +19,7 @@ import MatterImage from "../matter/widget/MatterImage"; interface RouteParam { - uuid: string + uuid: string } @@ -33,235 +33,235 @@ interface IState { export default class Edit extends TankComponent { - formRef = React.createRef(); + formRef = React.createRef(); - createMode: boolean = false + createMode: boolean = false - //登录的那个用户 - user: User = Moon.getSingleton().user + //登录的那个用户 + user: User = Moon.getSingleton().user - //当前页面正在编辑的用户 - currentUser: User = new User(this) + //当前页面正在编辑的用户 + currentUser: User = new User(this) - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - this.currentUser.role = UserRole.USER - } - - componentDidMount() { - let match = this.props.match; - - if (match.params.uuid) { - this.createMode = false; - this.currentUser.uuid = match.params.uuid; - this.currentUser.httpDetail(); - } else { - this.createMode = true; - this.updateUI() + this.state = {}; + this.currentUser.role = UserRole.USER } - } + componentDidMount() { + let match = this.props.match; - onFinish(values: any) { + if (match.params.uuid) { + this.createMode = false; + this.currentUser.uuid = match.params.uuid; + this.currentUser.httpDetail(); + } else { + this.createMode = true; + this.updateUI() + } + + } + + onFinish(values: any) { - let that = this + let that = this - let user: User = this.user - let currentUser: User = this.currentUser + let user: User = this.user + let currentUser: User = this.currentUser - currentUser.assign(values) + currentUser.assign(values) - currentUser.httpSave(function () { - MessageBoxUtil.success(Lang.t("operationSuccess")) + currentUser.httpSave(function () { + MessageBoxUtil.success(Lang.t("operationSuccess")) - //如果是自己的资料修改成功,更新一下本地。 - if (user.uuid === currentUser.uuid) { - user.assign(currentUser) - } + //如果是自己的资料修改成功,更新一下本地。 + if (user.uuid === currentUser.uuid) { + user.assign(currentUser) + } - Sun.navigateBack() - }) + Sun.navigateBack() + }) - }; - - onFinishFailed(errorInfo: any) { - - }; - - - render() { - - let that = this - - let user: User = this.user - let currentUser: User = this.currentUser - - const layout = { - labelCol: {span: 6}, - wrapperCol: {span: 18}, }; - //当前是否为编辑自己的模式。 - let editSelf: boolean = false - if (!this.createMode && user.uuid === currentUser.uuid) { - editSelf = true - } + onFinishFailed(errorInfo: any) { - //是否可以编辑角色。 - let roleEditable: boolean = false - if (this.createMode || (user.uuid !== currentUser.uuid && user.role === UserRole.ADMINISTRATOR)) { - roleEditable = true - } + }; - return ( -
+ render() { - + let that = this - + let user: User = this.user + let currentUser: User = this.currentUser - + const layout = { + labelCol: {span: 6}, + wrapperCol: {span: 18}, + }; -
{ - that.updateUI() - }} - > - {editSelf && ( - - - - )} + //当前是否为编辑自己的模式。 + let editSelf: boolean = false + if (!this.createMode && user.uuid === currentUser.uuid) { + editSelf = true + } - - - + //是否可以编辑角色。 + let roleEditable: boolean = false + if (this.createMode || (user.uuid !== currentUser.uuid && user.role === UserRole.ADMINISTRATOR)) { + roleEditable = true + } - { - this.createMode && ( - - - - ) - } + return ( - { - this.createMode && ( - ({ - validator(rule, value) { - if (!value || getFieldValue('password') === value) { - return Promise.resolve(); +
+ + + + + + + + { + that.updateUI() + }} + > + {editSelf && ( + + + + )} + + + + + + { + this.createMode && ( + + + + ) } - return Promise.reject(Lang.t("user.passwordNotSame")); - }, - }), - ]} - > - - - ) - } - - - - - - - - {Lang.t("user.current")}: - {(this.formRef && this.formRef.current) ? - FileUtil.humanFileSize(this.formRef.current.getFieldValue("sizeLimit")) - : FileUtil.humanFileSize(currentUser.sizeLimit)} + { + this.createMode && ( + ({ + validator(rule, value) { + if (!value || getFieldValue('password') === value) { + return Promise.resolve(); + } + return Promise.reject(Lang.t("user.passwordNotSame")); + }, + }), + ]} + > + + + ) + } + + + + + + + + + {Lang.t("user.current")}: + {(this.formRef && this.formRef.current) ? + FileUtil.humanFileSize(this.formRef.current.getFieldValue("sizeLimit")) + : FileUtil.humanFileSize(currentUser.sizeLimit)} - + - - - - - {Lang.t("user.current")}: - {(this.formRef && this.formRef.current) ? - FileUtil.humanFileSize(this.formRef.current.getFieldValue("totalSizeLimit")) - : FileUtil.humanFileSize(currentUser.totalSizeLimit)} + + + + + {Lang.t("user.current")}: + {(this.formRef && this.formRef.current) ? + FileUtil.humanFileSize(this.formRef.current.getFieldValue("totalSizeLimit")) + : FileUtil.humanFileSize(currentUser.totalSizeLimit)} - + + +
+ +
+ + +
+ -
-
- - - - - -
- ); - } + ); + } } diff --git a/src/pages/user/List.tsx b/src/pages/user/List.tsx index 48b5f35..dfd082e 100644 --- a/src/pages/user/List.tsx +++ b/src/pages/user/List.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { Link, RouteComponentProps } from "react-router-dom"; +import {Link, RouteComponentProps} from "react-router-dom"; import "./List.less"; import SortDirection from "../../common/model/base/SortDirection"; import Pager from "../../common/model/base/Pager"; @@ -11,287 +11,280 @@ import TableEmpty from "../widget/TableEmpty"; import User from "../../common/model/user/User"; import TankComponent from "../../common/component/TankComponent"; import TankTitle from "../widget/TankTitle"; -import { ColumnProps } from "antd/lib/table"; -import { Table, Button, Modal, Tag, Tooltip } from "antd"; -import { - CheckCircleOutlined, - PlusOutlined, - StopOutlined, - UserSwitchOutlined, -} from "@ant-design/icons"; -import { UserRoleMap } from "../../common/model/user/UserRole"; -import { UserStatus, UserStatusMap } from "../../common/model/user/UserStatus"; -import { - DeleteOutlined, - EditOutlined, - ExclamationCircleFilled, -} from "@ant-design/icons/lib"; +import {ColumnProps} from "antd/lib/table"; +import {Button, Modal, Table, Tag, Tooltip} from "antd"; +import {CheckCircleOutlined, PlusOutlined, StopOutlined, UserSwitchOutlined,} from "@ant-design/icons"; +import {UserRoleMap} from "../../common/model/user/UserRole"; +import {UserStatus, UserStatusMap} from "../../common/model/user/UserStatus"; +import {DeleteOutlined, EditOutlined, ExclamationCircleFilled,} from "@ant-design/icons/lib"; import MessageBoxUtil from "../../common/util/MessageBoxUtil"; import Color from "../../common/model/base/option/Color"; import TransfigurationModal from "./widget/TransfigurationModal"; import Lang from "../../common/model/global/Lang"; import Moon from "../../common/model/global/Moon"; -interface IProps extends RouteComponentProps {} +interface IProps extends RouteComponentProps { +} -interface IState {} +interface IState { +} export default class List extends TankComponent { - //获取分页的一个帮助器 - pager: Pager = new Pager(this, User, 10); + //获取分页的一个帮助器 + pager: Pager = new Pager(this, User, 10); - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } - - componentDidMount() { - //刷新一下列表 - let that = this; - - that.pager.enableHistory(); - - that.refresh(); - } - - search() { - let that = this; - that.pager.page = 0; - that.refresh(); - } - - refresh() { - let that = this; - - //如果没有任何的排序,默认使用时间倒序 - if (!that.pager.getCurrentSortFilter()) { - that.pager.setFilterValue("orderCreateTime", SortDirection.DESC); + this.state = {}; } - that.pager.httpList(); - } + componentDidMount() { + //刷新一下列表 + let that = this; - toggleStatus(user: User) { - let that = this; - user.httpToggleStatus(function () { - MessageBoxUtil.success(Lang.t("operationSuccess")); - that.updateUI(); - }); - } + that.pager.enableHistory(); - delete(user: User) { - let that = this; - Modal.confirm({ - title: Lang.t("user.deleteHint", user.username), - icon: , - onOk: () => { - user.httpDel(function () { - MessageBoxUtil.success(Lang.t("operationSuccess")); - that.refresh(); + that.refresh(); + } + + search() { + let that = this; + that.pager.page = 0; + that.refresh(); + } + + refresh() { + let that = this; + + //如果没有任何的排序,默认使用时间倒序 + if (!that.pager.getCurrentSortFilter()) { + that.pager.setFilterValue("orderCreateTime", SortDirection.DESC); + } + + that.pager.httpList(); + } + + toggleStatus(user: User) { + let that = this; + user.httpToggleStatus(function () { + MessageBoxUtil.success(Lang.t("operationSuccess")); + that.updateUI(); }); - }, - }); - } + } - transfiguration(user: User) { - let that = this; - TransfigurationModal.open(user); - } + delete(user: User) { + let that = this; + Modal.confirm({ + title: Lang.t("user.deleteHint", user.username), + icon: , + onOk: () => { + user.httpDel(function () { + MessageBoxUtil.success(Lang.t("operationSuccess")); + that.refresh(); + }); + }, + }); + } - render() { - let that = this; + transfiguration(user: User) { + let that = this; + TransfigurationModal.open(user); + } - //router中传入的路由相关对象 - let match = this.props.match; + render() { + let that = this; - //pager对象 - let pager = this.pager; + //router中传入的路由相关对象 + let match = this.props.match; - let user: User = Moon.getSingleton().user; + //pager对象 + let pager = this.pager; - const columns: ColumnProps[] = [ - { - title: Lang.t("user.avatar"), - dataIndex: "avatarUrl", - render: (text: any, record: User, index: number): React.ReactNode => ( - - avatar - - ), - }, - { - title: Lang.t("user.username"), - dataIndex: "username", - render: (text: any, record: User, index: number): React.ReactNode => { - return ( -
-
- - {record.username} - -
- {user.uuid === record.uuid && ( -
(It's you)
- )} -
- ); - }, - }, - { - title: Lang.t("user.role"), - dataIndex: "role", - render: (text: any, record: User, index: number): React.ReactNode => ( - - {UserRoleMap[record.role].name} - - ), - }, - { - title: Lang.t("user.singleFileSizeLimit"), - dataIndex: "sizeLimit", - render: (text: any, record: User, index: number): React.ReactNode => ( - {FileUtil.humanFileSize(record.sizeLimit)} - ), - }, - { - title: Lang.t("user.totalFileSize"), - dataIndex: "totalSize", - render: (text: any, record: User, index: number): React.ReactNode => ( - {FileUtil.humanFileSize(record.totalSize)} - ), - }, - { - title: Lang.t("user.totalFileSizeLimit"), - dataIndex: "totalSizeLimit", - render: (text: any, record: User, index: number): React.ReactNode => ( - {FileUtil.humanFileSize(record.totalSizeLimit)} - ), - }, - { - title: Lang.t("user.status"), - dataIndex: "status", - render: (text: any, record: User, index: number): React.ReactNode => ( - - {UserStatusMap[record.status].name} - - ), - }, - { - title: Lang.t("user.lastLogin"), - dataIndex: "lastTime", - render: (text: any, record: User, index: number): React.ReactNode => ( -
-
{record.lastIp}
-
{DateUtil.simpleDateTime(record.lastTime)}
-
- ), - }, - { - title: Lang.t("createTime"), - dataIndex: "createTime", - sorter: true, - sortOrder: pager.getDefaultSortOrder("createTime"), - sortDirections: [SortDirection.DESCEND, SortDirection.ASCEND], - render: (text: any, record: User, index: number): React.ReactNode => - DateUtil.simpleDateTime(text), - }, - { - title: Lang.t("operation"), - dataIndex: "action", - render: (text: any, record: User) => ( - + let user: User = Moon.getSingleton().user; + + const columns: ColumnProps[] = [ + { + title: Lang.t("user.avatar"), + dataIndex: "avatarUrl", + render: (text: any, record: User, index: number): React.ReactNode => ( + + avatar + + ), + }, + { + title: Lang.t("user.username"), + dataIndex: "username", + render: (text: any, record: User, index: number): React.ReactNode => { + return ( +
+
+ + {record.username} + +
+ {user.uuid === record.uuid && ( +
(It's you)
+ )} +
+ ); + }, + }, + { + title: Lang.t("user.role"), + dataIndex: "role", + render: (text: any, record: User, index: number): React.ReactNode => ( + + {UserRoleMap[record.role].name} + + ), + }, + { + title: Lang.t("user.singleFileSizeLimit"), + dataIndex: "sizeLimit", + render: (text: any, record: User, index: number): React.ReactNode => ( + {FileUtil.humanFileSize(record.sizeLimit)} + ), + }, + { + title: Lang.t("user.totalFileSize"), + dataIndex: "totalSize", + render: (text: any, record: User, index: number): React.ReactNode => ( + {FileUtil.humanFileSize(record.totalSize)} + ), + }, + { + title: Lang.t("user.totalFileSizeLimit"), + dataIndex: "totalSizeLimit", + render: (text: any, record: User, index: number): React.ReactNode => ( + {FileUtil.humanFileSize(record.totalSizeLimit)} + ), + }, + { + title: Lang.t("user.status"), + dataIndex: "status", + render: (text: any, record: User, index: number): React.ReactNode => ( + + {UserStatusMap[record.status].name} + + ), + }, + { + title: Lang.t("user.lastLogin"), + dataIndex: "lastTime", + render: (text: any, record: User, index: number): React.ReactNode => ( +
+
{record.lastIp}
+
{DateUtil.simpleDateTime(record.lastTime)}
+
+ ), + }, + { + title: Lang.t("createTime"), + dataIndex: "createTime", + sorter: true, + sortOrder: pager.getDefaultSortOrder("createTime"), + sortDirections: [SortDirection.DESCEND, SortDirection.ASCEND], + render: (text: any, record: User, index: number): React.ReactNode => + DateUtil.simpleDateTime(text), + }, + { + title: Lang.t("operation"), + dataIndex: "action", + render: (text: any, record: User) => ( + - + - {record.status === UserStatus.OK && record.uuid !== user.uuid && ( - - - - )} + {record.status === UserStatus.OK && record.uuid !== user.uuid && ( + + + + )} - {record.status === UserStatus.DISABLED && - record.uuid !== user.uuid && ( - - - - )} + {record.status === UserStatus.DISABLED && + record.uuid !== user.uuid && ( + + + + )} - {record.status === UserStatus.DISABLED && - record.uuid !== user.uuid && ( - - - - )} + {record.status === UserStatus.DISABLED && + record.uuid !== user.uuid && ( + + + + )} - {record.uuid !== user.uuid && ( - - - - )} + {record.uuid !== user.uuid && ( + + + + )} - ), - }, - ]; + ), + }, + ]; - return ( -
- - - - - + return ( +
+ + + + + -
- -
- - ), - }} - /> - - ); - } +
+ +
+
+ ), + }} + /> + + ); + } } diff --git a/src/pages/user/Login.tsx b/src/pages/user/Login.tsx index 77d1ff4..4d61dd6 100644 --- a/src/pages/user/Login.tsx +++ b/src/pages/user/Login.tsx @@ -22,114 +22,116 @@ interface IState { export default class Login extends TankComponent { - user: User = Moon.getSingleton().user + user: User = Moon.getSingleton().user - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } + this.state = {}; + } - componentDidMount() { + componentDidMount() { - //进入登录页面,默认退出一次 - this.logout() - } + //进入登录页面,默认退出一次 + this.logout() + } - //退出登录 - logout() { + //退出登录 + logout() { - let that = this + let that = this - this.user.httpLogout(function () { - //刷新整个网站 - Sun.updateFrame() - }) + this.user.httpLogout(function () { + //刷新整个网站 + Sun.updateFrame() + }) - } + } - onFinish(values: any) { + onFinish(values: any) { - let that = this + let that = this - let user = that.user + let user = that.user - user.httpLogin(values["username"], values["password"], function () { - MessageBoxUtil.success(Lang.t("user.loginSuccess")) + user.httpLogin(values["username"], values["password"], function () { + MessageBoxUtil.success(Lang.t("user.loginSuccess")) - that.props.history.push('/') + that.props.history.push('/') - }) + }) - }; + }; - onFinishFailed(errorInfo: any) { + onFinishFailed(errorInfo: any) { - }; + }; - render() { + render() { - let that = this - let preference: Preference = Moon.getSingleton().preference + let that = this + let preference: Preference = Moon.getSingleton().preference - return ( -
+ return ( +
- -
+ + + +
+ {Lang.t("user.welcomeLogin")} +
+ + + + }/> + + + + }/> + + + + + + + { + preference.allowRegister && ( +
+ + {Lang.t("user.toToRegister")} + +
+ ) + } + + + + + + -
- {Lang.t("user.welcomeLogin")}
- - - - }/> - - - - }/> - - - - - - - { - preference.allowRegister && ( -
- - {Lang.t("user.toToRegister")} - -
- ) - } - - - - - - - - - ); - } + ); + } } diff --git a/src/pages/user/MobileList.tsx b/src/pages/user/MobileList.tsx index 5bf7507..5c06924 100644 --- a/src/pages/user/MobileList.tsx +++ b/src/pages/user/MobileList.tsx @@ -1,13 +1,13 @@ import React from "react"; -import { Link, RouteComponentProps } from "react-router-dom"; +import {Link, RouteComponentProps} from "react-router-dom"; import "./MobileList.less"; import SortDirection from "../../common/model/base/SortDirection"; import Pager from "../../common/model/base/Pager"; import User from "../../common/model/user/User"; import TankComponent from "../../common/component/TankComponent"; import TankTitle from "../widget/TankTitle"; -import { Button, Modal, Input, Pagination } from "antd"; -import { PlusOutlined, ExclamationCircleFilled } from "@ant-design/icons"; +import {Button, Input, Modal, Pagination} from "antd"; +import {ExclamationCircleFilled, PlusOutlined} from "@ant-design/icons"; import MessageBoxUtil from "../../common/util/MessageBoxUtil"; import Color from "../../common/model/base/option/Color"; import TransfigurationModal from "./widget/TransfigurationModal"; @@ -15,125 +15,127 @@ import Lang from "../../common/model/global/Lang"; import Moon from "../../common/model/global/Moon"; import MobileUserPanel from "./widget/MobileUserPanel"; -interface IProps extends RouteComponentProps {} +interface IProps extends RouteComponentProps { +} -interface IState {} +interface IState { +} export default class MobileList extends TankComponent { - //获取分页的一个帮助器 - pager: Pager = new Pager(this, User, 10); + //获取分页的一个帮助器 + pager: Pager = new Pager(this, User, 10); - constructor(props: IProps) { - super(props); - } - - componentDidMount(): void { - this.pager.enableHistory(); - this.refresh(); - } - - search() { - this.pager.page = 0; - this.refresh(); - }; - - refresh() { - //如果没有任何的排序,默认使用时间倒序 - if (!this.pager.getCurrentSortFilter()) { - this.pager.setFilterValue("orderCreateTime", SortDirection.DESC); + constructor(props: IProps) { + super(props); } - this.pager.httpList(); - }; - toggleStatus(user: User) { - user.httpToggleStatus(() => { - MessageBoxUtil.success(Lang.t("operationSuccess")); - this.updateUI(); - }); - }; + componentDidMount(): void { + this.pager.enableHistory(); + this.refresh(); + } - delete(user: User) { - Modal.confirm({ - title: Lang.t("user.deleteHint", user.username), - icon: , - onOk: () => { - user.httpDel(() => { - MessageBoxUtil.success(Lang.t("operationSuccess")); - this.refresh(); + search() { + this.pager.page = 0; + this.refresh(); + }; + + refresh() { + //如果没有任何的排序,默认使用时间倒序 + if (!this.pager.getCurrentSortFilter()) { + this.pager.setFilterValue("orderCreateTime", SortDirection.DESC); + } + this.pager.httpList(); + }; + + toggleStatus(user: User) { + user.httpToggleStatus(() => { + MessageBoxUtil.success(Lang.t("operationSuccess")); + this.updateUI(); }); - }, - }); - }; + }; - transfiguration(user: User) { - TransfigurationModal.open(user); - }; + delete(user: User) { + Modal.confirm({ + title: Lang.t("user.deleteHint", user.username), + icon: , + onOk: () => { + user.httpDel(() => { + MessageBoxUtil.success(Lang.t("operationSuccess")); + this.refresh(); + }); + }, + }); + }; - searchFile(value?: string) { - this.pager.resetFilter(); - if (value) { - this.pager.setFilterValue("orderCreateTime", SortDirection.DESC); - this.pager.setFilterValue("username", value); - this.pager.httpList(); - } else { - this.refresh(); + transfiguration(user: User) { + TransfigurationModal.open(user); + }; + + searchFile(value?: string) { + this.pager.resetFilter(); + if (value) { + this.pager.setFilterValue("orderCreateTime", SortDirection.DESC); + this.pager.setFilterValue("username", value); + this.pager.httpList(); + } else { + this.refresh(); + } + }; + + changeSearch(e: any) { + if (!e.currentTarget.value) this.searchFile(); + }; + + changePage(page: number) { + this.pager.page = page - 1; // page的页数0基 + this.pager.httpList(); + this.updateUI(); + }; + + render() { + const {pager} = this; + const currentUser = Moon.getSingleton().user; + return ( +
+ + + + + + +
+ this.searchFile(value)} + onChange={this.changeSearch.bind(this)} + enterButton + /> +
+ +
+ {pager.data.map((user) => ( + + ))} +
+ +
+ ); } - }; - - changeSearch(e: any) { - if (!e.currentTarget.value) this.searchFile(); - }; - - changePage(page: number) { - this.pager.page = page - 1; // page的页数0基 - this.pager.httpList(); - this.updateUI(); - }; - - render() { - const { pager } = this; - const currentUser = Moon.getSingleton().user; - return ( -
- - - - - - -
- this.searchFile(value)} - onChange={this.changeSearch.bind(this)} - enterButton - /> -
- -
- {pager.data.map((user) => ( - - ))} -
- -
- ); - } } diff --git a/src/pages/user/Register.tsx b/src/pages/user/Register.tsx index d634924..9ba4e4e 100644 --- a/src/pages/user/Register.tsx +++ b/src/pages/user/Register.tsx @@ -20,117 +20,120 @@ interface IState { export default class Register extends TankComponent { - user: User = Moon.getSingleton().user + user: User = Moon.getSingleton().user - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } + this.state = {}; + } - componentDidMount() { + componentDidMount() { - } + } - onFinish(values: any) { + onFinish(values: any) { - let that = this + let that = this - let user = that.user + let user = that.user - user.httpRegister(values["username"], values["password"], function () { - MessageBoxUtil.success(Lang.t("user.loginSuccess")) + user.httpRegister(values["username"], values["password"], function () { + MessageBoxUtil.success(Lang.t("user.loginSuccess")) - that.props.history.push('/') + that.props.history.push('/') - }) + }) - }; + }; - onFinishFailed(errorInfo: any) { + onFinishFailed(errorInfo: any) { - }; + }; - render() { + render() { - let that = this + let that = this - return ( -
+ return ( +
- -
+ + + +
+ {Lang.t("user.welcomeRegister")} +
+ + + + }/> + + + + }/> + + + ({ + validator(rule, value) { + if (!value || getFieldValue('password') === value) { + return Promise.resolve(); + } + return Promise.reject(Lang.t("user.passwordNotSame")); + }, + }), + ]} + > + + }/> + + + + + + + +
+ + {Lang.t("user.goToLogin")} + +
+ + + + + + -
- {Lang.t("user.welcomeRegister")}
- - - - }/> - - - - }/> - - - ({ - validator(rule, value) { - if (!value || getFieldValue('password') === value) { - return Promise.resolve(); - } - return Promise.reject(Lang.t("user.passwordNotSame")); - }, - }), - ]} - > - - }/> - - - - - - - -
- - {Lang.t("user.goToLogin")} - -
- - - - - - - - - ); - } + ); + } } diff --git a/src/pages/user/widget/ChangePasswordModal.tsx b/src/pages/user/widget/ChangePasswordModal.tsx index cf38763..45ca721 100644 --- a/src/pages/user/widget/ChangePasswordModal.tsx +++ b/src/pages/user/widget/ChangePasswordModal.tsx @@ -3,13 +3,12 @@ import Button from 'antd/lib/button'; import {Form, Input, Modal} from "antd" import TankComponent from "../../../common/component/TankComponent"; import User from "../../../common/model/user/User"; -import Moon from "../../../common/model/global/Moon"; import Lang from "../../../common/model/global/Lang"; interface IProps { - user: User - onSuccess: () => void - onClose: () => void + user: User + onSuccess: () => void + onClose: () => void } interface IState { @@ -18,142 +17,142 @@ interface IState { export default class ChangePasswordModal extends TankComponent { - constructor(props: IProps) { - super(props); - this.state = {}; - } + constructor(props: IProps) { + super(props); + this.state = {}; + } - componentDidMount() { + componentDidMount() { - } + } - static open(user: User, onSuccess: () => void) { + static open(user: User, onSuccess: () => void) { - let modal = Modal.success({ - okCancel: false, - okButtonProps: { - className: "display-none" - }, - icon: null, - content: { - modal.destroy() - onSuccess() - }} - onClose={() => { - modal.destroy() - }}/>, - }) + let modal = Modal.success({ + okCancel: false, + okButtonProps: { + className: "display-none" + }, + icon: null, + content: { + modal.destroy() + onSuccess() + }} + onClose={() => { + modal.destroy() + }}/>, + }) - } + } - onFinish(values: any) { + onFinish(values: any) { - let that = this + let that = this - let currentUser: User = this.props.user + let currentUser: User = this.props.user - currentUser.httpChangePassword(values["oldPassword"], values["repeatPassword"], function () { + currentUser.httpChangePassword(values["oldPassword"], values["repeatPassword"], function () { - that.props.onSuccess() + that.props.onSuccess() - }) + }) - }; - - onFinishFailed(errorInfo: any) { - - }; - - - render() { - - let that = this - - const layout = { - labelCol: {span: 8}, - wrapperCol: {span: 16}, - }; - const tailLayout = { - wrapperCol: {offset: 8, span: 16}, }; - return ( -
+ onFinishFailed(errorInfo: any) { -
-

- {Lang.t("user.editSomebodyPassword", that.props.user.username)} -

-
- -
- - - - - - - - - ({ - validator(rule, value) { - if (!value || getFieldValue('password') === value) { - return Promise.resolve(); - } - return Promise.reject(Lang.t("user.passwordNotSame")); - }, - }), - ]} - > - - + }; - + render() { - + let that = this - + const layout = { + labelCol: {span: 8}, + wrapperCol: {span: 16}, + }; + const tailLayout = { + wrapperCol: {offset: 8, span: 16}, + }; - + return ( +
- +
+

+ {Lang.t("user.editSomebodyPassword", that.props.user.username)} +

+
+ +
+ + + + + + + + + ({ + validator(rule, value) { + if (!value || getFieldValue('password') === value) { + return Promise.resolve(); + } + return Promise.reject(Lang.t("user.passwordNotSame")); + }, + }), + ]} + > + + -
- ); - } + + + + + + + + + + + +
+ ); + } } diff --git a/src/pages/user/widget/MobileUserPanel.less b/src/pages/user/widget/MobileUserPanel.less index 0b8a8cb..4355852 100644 --- a/src/pages/user/widget/MobileUserPanel.less +++ b/src/pages/user/widget/MobileUserPanel.less @@ -1,20 +1,24 @@ .mobile-user { background: #fff; + &:hover { background: aliceblue; cursor: pointer; } + .panel { display: flex; align-items: center; padding: 10px; border-top: 1px solid #eee; + .avatar { flex-shrink: 0; width: 40px; height: 40px; border-radius: 50%; } + .username { flex-grow: 1; margin: 0 10px; diff --git a/src/pages/user/widget/MobileUserPanel.tsx b/src/pages/user/widget/MobileUserPanel.tsx index f5dca4f..cb04095 100644 --- a/src/pages/user/widget/MobileUserPanel.tsx +++ b/src/pages/user/widget/MobileUserPanel.tsx @@ -3,22 +3,19 @@ import TankComponent from "../../../common/component/TankComponent"; import InfoCell from "../../widget/InfoCell"; import Lang from "../../../common/model/global/Lang"; import User from "../../../common/model/user/User"; -import { Link } from "react-router-dom"; -import { UserRoleMap } from "../../../common/model/user/UserRole"; -import { Tag, Tooltip } from "antd"; +import {Link} from "react-router-dom"; +import {UserRoleMap} from "../../../common/model/user/UserRole"; +import {Tag, Tooltip} from "antd"; import FileUtil from "../../../common/util/FileUtil"; -import { - UserStatus, - UserStatusMap, -} from "../../../common/model/user/UserStatus"; +import {UserStatus, UserStatusMap,} from "../../../common/model/user/UserStatus"; import DateUtil from "../../../common/util/DateUtil"; import { - EditOutlined, - StopOutlined, - CheckCircleOutlined, - UserSwitchOutlined, - DeleteOutlined, - EllipsisOutlined, + CheckCircleOutlined, + DeleteOutlined, + EditOutlined, + EllipsisOutlined, + StopOutlined, + UserSwitchOutlined, } from "@ant-design/icons"; import Color from "../../../common/model/base/option/Color"; import Expanding from "../../widget/Expanding"; @@ -27,127 +24,128 @@ import SafeUtil from "../../../common/util/SafeUtil"; import Sun from "../../../common/model/global/Sun"; interface IProps { - user: User; - isCurrentUser: boolean; - onToggleStatus: (user: User) => any; - onDelete: (user: User) => any; - onTransfiguration: (user: User) => any; + user: User; + isCurrentUser: boolean; + onToggleStatus: (user: User) => any; + onDelete: (user: User) => any; + onTransfiguration: (user: User) => any; } -interface IState {} +interface IState { +} export default class MobileUserPanel extends TankComponent { - // 小屏幕下操作栏 - showMore: boolean = false; + // 小屏幕下操作栏 + showMore: boolean = false; - constructor(props: IProps) { - super(props); - this.state = {}; - } + constructor(props: IProps) { + super(props); + this.state = {}; + } - clickRow() { - Sun.navigateTo(`/user/detail/${this.props.user.uuid}`); - }; + clickRow() { + Sun.navigateTo(`/user/detail/${this.props.user.uuid}`); + }; - toggleHandles() { - this.showMore = !this.showMore; - this.updateUI(); - }; + toggleHandles() { + this.showMore = !this.showMore; + this.updateUI(); + }; - render() { - const { user, isCurrentUser } = this.props; + render() { + const {user, isCurrentUser} = this.props; - return ( -
-
this.clickRow()}> - -

{user.username}

- - {UserRoleMap[user.role].name} - - - SafeUtil.stopPropagationWrap(e)(this.toggleHandles()) - } - /> -
- - - {this.showMore ? ( -
- - {FileUtil.humanFileSize(user.sizeLimit)} - - - {FileUtil.humanFileSize(user.totalSize)} - - - {FileUtil.humanFileSize(user.totalSizeLimit)} - - - - {UserStatusMap[user.status].name} - - - -
-
{user.lastIp}
-
{DateUtil.simpleDateTime(user.lastTime)}
+ return ( +
+
this.clickRow()}> + +

{user.username}

+ + {UserRoleMap[user.role].name} + + + SafeUtil.stopPropagationWrap(e)(this.toggleHandles()) + } + />
- - - {DateUtil.simpleDateTime(user.createTime)} - - -
- - - - - - {user.status === UserStatus.OK && !isCurrentUser && ( - - this.props.onToggleStatus(user)} - /> - - )} - {user.status === UserStatus.DISABLED && !isCurrentUser && ( - <> - - this.props.onToggleStatus(user)} - /> - - - this.props.onDelete(user)} - /> - - - )} - {!isCurrentUser && ( - - this.props.onTransfiguration(user)} - /> - - )} -
-
+ + + {this.showMore ? ( +
+ + {FileUtil.humanFileSize(user.sizeLimit)} + + + {FileUtil.humanFileSize(user.totalSize)} + + + {FileUtil.humanFileSize(user.totalSizeLimit)} + + + + {UserStatusMap[user.status].name} + + + +
+
{user.lastIp}
+
{DateUtil.simpleDateTime(user.lastTime)}
+
+
+ + {DateUtil.simpleDateTime(user.createTime)} + + +
+ + + + + + {user.status === UserStatus.OK && !isCurrentUser && ( + + this.props.onToggleStatus(user)} + /> + + )} + {user.status === UserStatus.DISABLED && !isCurrentUser && ( + <> + + this.props.onToggleStatus(user)} + /> + + + this.props.onDelete(user)} + /> + + + )} + {!isCurrentUser && ( + + this.props.onTransfiguration(user)} + /> + + )} +
+
+
+ ) : null} +
- ) : null} - -
- ); - } + ); + } } diff --git a/src/pages/user/widget/TransfigurationModal.tsx b/src/pages/user/widget/TransfigurationModal.tsx index 1534ca1..be5798e 100644 --- a/src/pages/user/widget/TransfigurationModal.tsx +++ b/src/pages/user/widget/TransfigurationModal.tsx @@ -7,12 +7,11 @@ import TankComponent from "../../../common/component/TankComponent"; import BrowserUtil from "../../../common/util/BrowserUtil"; import ClipboardUtil from "../../../common/util/ClipboardUtil"; import MessageBoxUtil from "../../../common/util/MessageBoxUtil"; -import Moon from "../../../common/model/global/Moon"; import Lang from "../../../common/model/global/Lang"; interface IProps { - user: User - onClose: () => void + user: User + onClose: () => void } interface IState { @@ -20,87 +19,87 @@ interface IState { export default class TransfigurationModal extends TankComponent { - authentication: string = "" + authentication: string = "" - constructor(props: IProps) { - super(props); - } + constructor(props: IProps) { + super(props); + } - componentDidMount() { + componentDidMount() { - let that = this + let that = this - this.props.user.httpTransfiguration(function (text: string) { + this.props.user.httpTransfiguration(function (text: string) { - that.authentication = text - that.updateUI() + that.authentication = text + that.updateUI() - }) + }) - } + } - static open(user: User) { + static open(user: User) { - let modal = Modal.success({ - okCancel: false, - okButtonProps: { - className: "display-none" - }, - icon: null, - content: { - modal.destroy() - }}/>, - }) + let modal = Modal.success({ + okCancel: false, + okButtonProps: { + className: "display-none" + }, + icon: null, + content: { + modal.destroy() + }}/>, + }) - } + } - render() { + render() { - let that = this + let that = this - let textToCopy = BrowserUtil.fullHost() + "/user/authentication/" + that.authentication + let textToCopy = BrowserUtil.fullHost() + "/user/authentication/" + that.authentication - return ( -
+ return ( +
-
-

- {Lang.t("user.transfigurationPromptText")} -

-
-
- {Lang.t("user.transfigurationPrompt")} -
-
- {textToCopy} -
+
+

+ {Lang.t("user.transfigurationPromptText")} +

+
+
+ {Lang.t("user.transfigurationPrompt")} +
+
+ {textToCopy} +
-
+
- + - -
+ ClipboardUtil.copy(textToCopy, function () { + MessageBoxUtil.success(Lang.t("copySuccess")) + that.props.onClose() + }, function () { + MessageBoxUtil.error(Lang.t("copyError")) + }) + }}>{Lang.t("copy")} +
-
- ); - } +
+ ); + } } diff --git a/src/pages/widget/BreadcrumbPanel.tsx b/src/pages/widget/BreadcrumbPanel.tsx index 6b135c3..eb8579e 100644 --- a/src/pages/widget/BreadcrumbPanel.tsx +++ b/src/pages/widget/BreadcrumbPanel.tsx @@ -7,7 +7,7 @@ import Sun from "../../common/model/global/Sun"; import {HomeOutlined} from "@ant-design/icons/lib"; interface IProps { - breadcrumbModels: BreadcrumbModel[] + breadcrumbModels: BreadcrumbModel[] } interface IState { @@ -15,45 +15,45 @@ interface IState { export default class BreadcrumbPanel extends TankComponent { - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } + this.state = {}; + } - render() { + render() { - return ( - + return ( + - - { - Sun.navigateTo("/") - }}/> - - - { - this.props.breadcrumbModels.map((item: BreadcrumbModel, index: number) => { - if (item.displayDirect) { - return ( - {item.name} - ) - } else { - return ( - - { - Sun.navigateQueryTo({ - path: item.path, - query: item.query - }) - }}>{item.name} + + { + Sun.navigateTo("/") + }}/> - ) - } - }) - } - - ) - } + + { + this.props.breadcrumbModels.map((item: BreadcrumbModel, index: number) => { + if (item.displayDirect) { + return ( + {item.name} + ) + } else { + return ( + + { + Sun.navigateQueryTo({ + path: item.path, + query: item.query + }) + }}>{item.name} + + ) + } + }) + } + + ) + } } diff --git a/src/pages/widget/ChangeNumModal.tsx b/src/pages/widget/ChangeNumModal.tsx index f5ff5db..78f9a8e 100644 --- a/src/pages/widget/ChangeNumModal.tsx +++ b/src/pages/widget/ChangeNumModal.tsx @@ -4,77 +4,77 @@ import {Input} from "antd" import MessageBoxUtil from "../../common/util/MessageBoxUtil"; interface IProps { - value: number - title?: string - onSuccess: (val: number) => void - onClose: () => void + value: number + title?: string + onSuccess: (val: number) => void + onClose: () => void } interface IState { - innerValue: number + innerValue: number } export default class ChangeNumModal extends React.Component { - constructor(props: IProps) { - super(props); - this.state = { - innerValue: this.props.value - }; - } - - - componentDidMount() { - - } - - onSubmitClick() { - if (this.state.innerValue) { - this.props.onSuccess(this.state.innerValue) - } else { - MessageBoxUtil.error("没有填写值,提交失败!") + constructor(props: IProps) { + super(props); + this.state = { + innerValue: this.props.value + }; } - } - - render() { - - let that = this - return ( -
+ componentDidMount() { -
-

- {that.props.title} -

-
+ } - { - that.setState({ - innerValue: parseInt(e.target.value) - }) + onSubmitClick() { + if (this.state.innerValue) { + this.props.onSuccess(this.state.innerValue) + } else { + MessageBoxUtil.error("没有填写值,提交失败!") + } + } - }}/> + render() { -
- - - - -
+ let that = this -
- ); - } + return ( +
+ +
+

+ {that.props.title} +

+
+ + { + that.setState({ + innerValue: parseInt(e.target.value) + }) + + }}/> + +
+ + + + +
+ + +
+ ); + } } diff --git a/src/pages/widget/Expanding.tsx b/src/pages/widget/Expanding.tsx index 22e7007..0355eb7 100644 --- a/src/pages/widget/Expanding.tsx +++ b/src/pages/widget/Expanding.tsx @@ -1,19 +1,21 @@ -import React, { Component } from "react"; +import React, {Component} from "react"; import VelocityReact from "velocity-react"; -interface IProps {} +interface IProps { +} -interface IState {} +interface IState { +} export default class Expanding extends Component { - render() { - return ( - - {this.props.children} - - ); - } + render() { + return ( + + {this.props.children} + + ); + } } diff --git a/src/pages/widget/FrameLoading.tsx b/src/pages/widget/FrameLoading.tsx index 7f47205..f45d6ff 100644 --- a/src/pages/widget/FrameLoading.tsx +++ b/src/pages/widget/FrameLoading.tsx @@ -16,27 +16,27 @@ interface IState { */ export default class FrameLoading extends TankComponent { - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } + this.state = {}; + } - render() { + render() { - let that = this + let that = this - return ( -
-
-
- -
-
- 加载中... -
-
-
- ) - } + return ( +
+
+
+ +
+
+ 加载中... +
+
+
+ ) + } } diff --git a/src/pages/widget/InfoCell.less b/src/pages/widget/InfoCell.less index 680ff89..f26baf0 100644 --- a/src/pages/widget/InfoCell.less +++ b/src/pages/widget/InfoCell.less @@ -1,6 +1,7 @@ .castle-widget-info-cell { word-break: break-all; margin-bottom: 10px; + .info-cell-name { color: #99a9bf; font-size: 14px; diff --git a/src/pages/widget/InfoCell.tsx b/src/pages/widget/InfoCell.tsx index 4236298..372a7a5 100644 --- a/src/pages/widget/InfoCell.tsx +++ b/src/pages/widget/InfoCell.tsx @@ -3,8 +3,8 @@ import "./InfoCell.less" import {Col, Row} from "antd" interface IProps { - name: string - firstSpan?: number + name: string + firstSpan?: number } interface IState { @@ -13,37 +13,36 @@ interface IState { export default class InfoCell extends React.Component { - constructor(props: IProps) { - super(props) - this.state = {} - } - - - - componentDidMount() { - - } - - - render() { - - let that = this - let name: string = this.props.name - - let firstSpan: number = 8 - if (this.props.firstSpan !== undefined) { - firstSpan = this.props.firstSpan + constructor(props: IProps) { + super(props) + this.state = {} } - let secondSpan: number = 24 - firstSpan - return ( - -
{name} - - {that.props.children} - - - ) - } + + componentDidMount() { + + } + + + render() { + + let that = this + let name: string = this.props.name + + let firstSpan: number = 8 + if (this.props.firstSpan !== undefined) { + firstSpan = this.props.firstSpan + } + let secondSpan: number = 24 - firstSpan + + return ( + + {name} + + {that.props.children} + + + ) + } } diff --git a/src/pages/widget/SingleTextModal.tsx b/src/pages/widget/SingleTextModal.tsx index 8ea5abc..384c72b 100644 --- a/src/pages/widget/SingleTextModal.tsx +++ b/src/pages/widget/SingleTextModal.tsx @@ -5,101 +5,101 @@ import TankComponent from "../../common/component/TankComponent"; import MessageBoxUtil from "../../common/util/MessageBoxUtil"; interface IProps { - value: string - title?: string - onSuccess: (val: string) => void - onClose: () => void + value: string + title?: string + onSuccess: (val: string) => void + onClose: () => void } interface IState { - innerValue: string + innerValue: string } export default class SingleTextModal extends TankComponent { - constructor(props: IProps) { - super(props); - this.state = { - innerValue: this.props.value - }; - } - - componentDidMount() { - - } - - static open(title: string, initialValue: string, onSuccess: (text: string) => void) { - - let modal = Modal.success({ - okCancel: false, - okButtonProps: { - className: "display-none" - }, - icon: null, - content: { - - modal.destroy() - - onSuccess(val) - - }} - onClose={() => { - modal.destroy() - }}/>, - }) - - } - - - onSubmitClick() { - if (this.state.innerValue) { - this.props.onSuccess(this.state.innerValue) - } else { - MessageBoxUtil.error("没有填写值,提交失败!") + constructor(props: IProps) { + super(props); + this.state = { + innerValue: this.props.value + }; } - } - render() { + componentDidMount() { - let that = this + } - return ( -
+ static open(title: string, initialValue: string, onSuccess: (text: string) => void) { -
-

- {that.props.title} -

-
+ let modal = Modal.success({ + okCancel: false, + okButtonProps: { + className: "display-none" + }, + icon: null, + content: { - { - that.setState({ - innerValue: e.target.value - }) + modal.destroy() - }}/> + onSuccess(val) -
+ }} + onClose={() => { + modal.destroy() + }}/>, + }) - - - -
+ } -
- ); - } + onSubmitClick() { + if (this.state.innerValue) { + this.props.onSuccess(this.state.innerValue) + } else { + MessageBoxUtil.error("没有填写值,提交失败!") + } + } + + render() { + + let that = this + + return ( +
+ +
+

+ {that.props.title} +

+
+ + { + that.setState({ + innerValue: e.target.value + }) + + }}/> + +
+ + + + +
+ + +
+ ); + } } diff --git a/src/pages/widget/StringsPicker.tsx b/src/pages/widget/StringsPicker.tsx index 048d4cf..94b2d69 100644 --- a/src/pages/widget/StringsPicker.tsx +++ b/src/pages/widget/StringsPicker.tsx @@ -5,15 +5,15 @@ import TankComponent from "../../common/component/TankComponent"; import SafeUtil from "../../common/util/SafeUtil"; interface IProps { - value?: string | null, - onChange?: (value: string | null) => void, - editable?: boolean + value?: string | null, + onChange?: (value: string | null) => void, + editable?: boolean } interface IState { - tags: string[], - inputVisible: boolean, - inputValue: string + tags: string[], + inputVisible: boolean, + inputValue: string } /** @@ -22,159 +22,158 @@ interface IState { */ export default class StringsPicker extends TankComponent { - innerValue: string | null = null + innerValue: string | null = null - inputDom: any = null + inputDom: any = null - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = { - tags: [], - inputVisible: false, - inputValue: "" + this.state = { + tags: [], + inputVisible: false, + inputValue: "" + }; + } + + componentDidMount() { + + //刷新一下列表 + let that = this + + this.fillBack() + } + + + componentWillReceiveProps(nextProps: Readonly, nextContext: any): void { + let that = this + + //每次刷新都尝试去回填。 + if (nextProps.value != this.innerValue) { + + that.fillBack(nextProps.value) + } + + } + + //回填 + fillBack(selectedValue?: string | null) { + let that = this + + if (!selectedValue) { + selectedValue = this.props.value + } + + let arr: string[] = [] + if (selectedValue) { + try { + arr = JSON.parse(selectedValue); + } catch (e) { + arr = [] + } + that.setState({tags: arr}) + } + + this.setState({ + tags: arr + }) + + } + + + handleClose(removedTag: string) { + const tags = this.state.tags.filter(tag => tag !== removedTag); + + + this.setState({tags}); + + + this.innerValue = JSON.stringify(tags) + //往外通知 + SafeUtil.safeCallback(this.props.onChange)(this.innerValue) }; - } - componentDidMount() { + showInput = () => { + this.setState({inputVisible: true}, () => this.inputDom.focus()); + }; - //刷新一下列表 - let that = this + handleInputChange(e: any) { - this.fillBack() - } + this.setState({inputValue: e.target.value}); + + }; + + handleInputConfirm = () => { + const {inputValue} = this.state; + let {tags} = this.state; + if (inputValue && tags.indexOf(inputValue) === -1) { + tags = [...tags, inputValue]; + } + + this.setState({ + tags, + inputVisible: false, + inputValue: '', + }); + + this.innerValue = JSON.stringify(tags) + + //往外通知 + SafeUtil.safeCallback(this.props.onChange)(this.innerValue) + + }; + + /** + * 由于Select控件具有内部自动搜索的能力,因此value要用nickname,realname,no的拼接 + */ + render() { + let tags: string[] = this.state.tags + let inputVisible: boolean = this.state.inputVisible + let inputValue: string = this.state.inputValue + + let editable: boolean = true + if (this.props.editable !== undefined) { + editable = this.props.editable + } - componentWillReceiveProps(nextProps: Readonly, nextContext: any): void { - let that = this - - //每次刷新都尝试去回填。 - if (nextProps.value != this.innerValue) { - - that.fillBack(nextProps.value) + return ( +
+ {tags.map((tag, index) => { + const isLongTag = tag.length > 20; + const tagElem = ( + this.handleClose(tag)}> + {isLongTag ? `${tag.slice(0, 20)}...` : tag} + + ); + return isLongTag ? ( + + {tagElem} + + ) : ( + tagElem + ); + })} + {inputVisible && editable && ( + { + this.inputDom = dom + }} + type="text" + size="small" + style={{width: 120}} + value={inputValue} + onChange={this.handleInputChange.bind(this)} + onBlur={this.handleInputConfirm} + onPressEnter={this.handleInputConfirm} + /> + )} + {!inputVisible && editable && ( + + 添加 + + )} +
+ ); } - - } - - //回填 - fillBack(selectedValue?: string | null) { - let that = this - - if (!selectedValue) { - selectedValue = this.props.value - } - - let arr: string[] = [] - if (selectedValue) { - try { - arr = JSON.parse(selectedValue); - } catch (e) { - arr = [] - } - that.setState({tags: arr}) - } - - this.setState({ - tags: arr - }) - - } - - - handleClose(removedTag: string) { - const tags = this.state.tags.filter(tag => tag !== removedTag); - - - - this.setState({tags}); - - - this.innerValue = JSON.stringify(tags) - //往外通知 - SafeUtil.safeCallback(this.props.onChange)(this.innerValue) - }; - - showInput = () => { - this.setState({inputVisible: true}, () => this.inputDom.focus()); - }; - - handleInputChange(e: any) { - - this.setState({inputValue: e.target.value}); - - }; - - handleInputConfirm = () => { - const {inputValue} = this.state; - let {tags} = this.state; - if (inputValue && tags.indexOf(inputValue) === -1) { - tags = [...tags, inputValue]; - } - - this.setState({ - tags, - inputVisible: false, - inputValue: '', - }); - - this.innerValue = JSON.stringify(tags) - - //往外通知 - SafeUtil.safeCallback(this.props.onChange)(this.innerValue) - - }; - - /** - * 由于Select控件具有内部自动搜索的能力,因此value要用nickname,realname,no的拼接 - */ - render() { - let tags: string[] = this.state.tags - let inputVisible: boolean = this.state.inputVisible - let inputValue: string = this.state.inputValue - - let editable: boolean = true - if (this.props.editable !== undefined) { - editable = this.props.editable - } - - - return ( -
- {tags.map((tag, index) => { - const isLongTag = tag.length > 20; - const tagElem = ( - this.handleClose(tag)}> - {isLongTag ? `${tag.slice(0, 20)}...` : tag} - - ); - return isLongTag ? ( - - {tagElem} - - ) : ( - tagElem - ); - })} - {inputVisible && editable && ( - { - this.inputDom = dom - }} - type="text" - size="small" - style={{width: 120}} - value={inputValue} - onChange={this.handleInputChange.bind(this)} - onBlur={this.handleInputConfirm} - onPressEnter={this.handleInputConfirm} - /> - )} - {!inputVisible && editable && ( - - 添加 - - )} -
- ); - } } diff --git a/src/pages/widget/TableEmpty.tsx b/src/pages/widget/TableEmpty.tsx index 34a7f3c..e4dedf8 100644 --- a/src/pages/widget/TableEmpty.tsx +++ b/src/pages/widget/TableEmpty.tsx @@ -7,8 +7,8 @@ import "./TableEmpty.less" import Pager from "../../common/model/base/Pager"; interface IProps { - pager: Pager - onRefresh?: () => void + pager: Pager + onRefresh?: () => void } interface IState { @@ -16,54 +16,54 @@ interface IState { class TableEmpty extends React.Component { - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } + this.state = {}; + } - render() { + render() { - let that = this + let that = this - let pager = this.props.pager + let pager = this.props.pager - let emptyContent = ( -
- + let emptyContent = ( +
+ { - SafeUtil.safeCallback(that.props.onRefresh)() + SafeUtil.safeCallback(that.props.onRefresh)() } }>点击重试 - -
- ) - let errorContent = ( -
- + +
+ ) + let errorContent = ( +
+ { - SafeUtil.safeCallback(that.props.onRefresh)() + SafeUtil.safeCallback(that.props.onRefresh)() } }>点击重试 - -
- ) +
+
+ ) - return ( -
- {pager.errorMessage ? errorContent : (pager.data.length ? "" : emptyContent)} -
+ return ( +
+ {pager.errorMessage ? errorContent : (pager.data.length ? "" : emptyContent)} +
- ) - ; - } + ) + ; + } } export default TableEmpty; diff --git a/src/pages/widget/TankContentCard.tsx b/src/pages/widget/TankContentCard.tsx index 7a3840e..576221c 100644 --- a/src/pages/widget/TankContentCard.tsx +++ b/src/pages/widget/TankContentCard.tsx @@ -4,7 +4,7 @@ import TankComponent from '../../common/component/TankComponent'; import {LoadingOutlined} from "@ant-design/icons/lib"; interface IProps { - loading?: boolean + loading?: boolean } interface IState { @@ -16,39 +16,39 @@ interface IState { */ export default class TankContentCard extends TankComponent { - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } - - componentDidMount() { - - //刷新一下列表 - let that = this - - } - - render() { - - let that = this - - let content: React.ReactNode - - if (that.props.loading) { - content = ( -
- -
- ) - } else { - content = that.props.children + this.state = {}; } - return ( -
- {content} -
- ); - } + componentDidMount() { + + //刷新一下列表 + let that = this + + } + + render() { + + let that = this + + let content: React.ReactNode + + if (that.props.loading) { + content = ( +
+ +
+ ) + } else { + content = that.props.children + } + + return ( +
+ {content} +
+ ); + } } diff --git a/src/pages/widget/TankTitle.tsx b/src/pages/widget/TankTitle.tsx index 787b77d..7eacc0f 100644 --- a/src/pages/widget/TankTitle.tsx +++ b/src/pages/widget/TankTitle.tsx @@ -3,32 +3,33 @@ import "./TankTitle.less"; import TankComponent from "../../common/component/TankComponent"; interface IProps { - name: React.ReactNode; + name: React.ReactNode; } -interface IState {} +interface IState { +} /** * 标题导航快捷插件 */ export default class TankTitle extends TankComponent { - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } + this.state = {}; + } - render() { + render() { - return ( -
+ return ( +
{this.props.name} - + {this.props.children} -
- ); - } +
+ ); + } } diff --git a/src/pages/widget/filter/CheckFilterBox.tsx b/src/pages/widget/filter/CheckFilterBox.tsx index 85dd210..01ee963 100644 --- a/src/pages/widget/filter/CheckFilterBox.tsx +++ b/src/pages/widget/filter/CheckFilterBox.tsx @@ -7,8 +7,8 @@ import CheckFilter from "../../../common/model/base/filter/CheckFilter"; const Option = Select.Option; interface IProps { - checkFilter: CheckFilter - onChange?: (value: boolean | null) => void + checkFilter: CheckFilter + onChange?: (value: boolean | null) => void } interface IState { @@ -16,42 +16,42 @@ interface IState { export default class CheckFilterBox extends React.Component { - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } + this.state = {}; + } - //改变某个filter的值 - onValueChange = (value: string) => { + //改变某个filter的值 + onValueChange = (value: string) => { - let that = this + let that = this - let checkFilter = this.props.checkFilter + let checkFilter = this.props.checkFilter - checkFilter.putValue(value) + checkFilter.putValue(value) - //通知外面变化了。 - SafeUtil.safeCallback(that.props.onChange)(checkFilter.value) + //通知外面变化了。 + SafeUtil.safeCallback(that.props.onChange)(checkFilter.value) - //更新UI - that.setState({}) + //更新UI + that.setState({}) - } + } - render() { + render() { - let that = this + let that = this - let checkFilter = this.props.checkFilter + let checkFilter = this.props.checkFilter - //用于回填的值 - let backValue = checkFilter.getValueString() + //用于回填的值 + let backValue = checkFilter.getValueString() - return ( - + return ( + @@ -66,8 +66,8 @@ export default class CheckFilterBox extends React.Component { - ); - } + ); + } } diff --git a/src/pages/widget/filter/DateFilterBox.tsx b/src/pages/widget/filter/DateFilterBox.tsx index be81bdc..7b3da7c 100644 --- a/src/pages/widget/filter/DateFilterBox.tsx +++ b/src/pages/widget/filter/DateFilterBox.tsx @@ -6,8 +6,8 @@ import {default as DateFilter} from "../../../common/model/base/filter/DateFilte import SafeUtil from "../../../common/util/SafeUtil"; interface IProps { - dateFilter: DateFilter - onChange?: (value: Date | null) => void + dateFilter: DateFilter + onChange?: (value: Date | null) => void } interface IState { @@ -16,47 +16,47 @@ interface IState { class DateFilterBox extends React.Component { - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } - - //改变某个filter的值 - onValueChange(momentTime: moment.Moment | null, dateString: string) { - - let that = this - - let filter = this.props.dateFilter - - if (momentTime) { - - filter.value = momentTime.toDate() - - } else { - filter.value = null + this.state = {}; } - //通知外面变化了。 - SafeUtil.safeCallback(that.props.onChange)(filter.value) + //改变某个filter的值 + onValueChange(momentTime: moment.Moment | null, dateString: string) { - //更新UI - that.setState({}) - } + let that = this - render() { + let filter = this.props.dateFilter - let that = this + if (momentTime) { - let dateFilter = this.props.dateFilter + filter.value = momentTime.toDate() - let value: moment.Moment | undefined = undefined - if (dateFilter.value) { - value = moment(dateFilter.value) + } else { + filter.value = null + } + + //通知外面变化了。 + SafeUtil.safeCallback(that.props.onChange)(filter.value) + + //更新UI + that.setState({}) } - return ( - + render() { + + let that = this + + let dateFilter = this.props.dateFilter + + let value: moment.Moment | undefined = undefined + if (dateFilter.value) { + value = moment(dateFilter.value) + } + + return ( + {dateFilter.name} @@ -64,18 +64,18 @@ class DateFilterBox extends React.Component { { - that.onValueChange(date, dateString) - }}/> + showTime + format={dateFilter.format} + value={value} + placeholder="请选择日期" + onChange={(date: moment.Moment | null, dateString: string) => { + that.onValueChange(date, dateString) + }}/> - ); - } + ); + } } export default DateFilterBox; diff --git a/src/pages/widget/filter/DateTimeFilterBox.tsx b/src/pages/widget/filter/DateTimeFilterBox.tsx index 7937c4d..4c2e9f9 100644 --- a/src/pages/widget/filter/DateTimeFilterBox.tsx +++ b/src/pages/widget/filter/DateTimeFilterBox.tsx @@ -6,8 +6,8 @@ import DateTimeFilter from "../../../common/model/base/filter/DateTimeFilter"; import SafeUtil from "../../../common/util/SafeUtil"; interface IProps { - dateTimeFilter: DateTimeFilter - onChange?: (value: Date | null) => void + dateTimeFilter: DateTimeFilter + onChange?: (value: Date | null) => void } interface IState { @@ -16,47 +16,47 @@ interface IState { class DateTimeFilterBox extends React.Component { - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } - - //改变某个filter的值 - onValueChange(momentTime: moment.Moment | null, dateString: string) { - - let that = this - - let filter = this.props.dateTimeFilter - - if (momentTime) { - - filter.value = momentTime.toDate() - - } else { - filter.value = null + this.state = {}; } - //通知外面变化了。 - SafeUtil.safeCallback(that.props.onChange)(filter.value) + //改变某个filter的值 + onValueChange(momentTime: moment.Moment | null, dateString: string) { - //更新UI - that.setState({}) - } + let that = this - render() { + let filter = this.props.dateTimeFilter - let that = this + if (momentTime) { - let dateTimeFilter = this.props.dateTimeFilter + filter.value = momentTime.toDate() - let value: moment.Moment | undefined = undefined - if (dateTimeFilter.value) { - value = moment(dateTimeFilter.value) + } else { + filter.value = null + } + + //通知外面变化了。 + SafeUtil.safeCallback(that.props.onChange)(filter.value) + + //更新UI + that.setState({}) } - return ( - + render() { + + let that = this + + let dateTimeFilter = this.props.dateTimeFilter + + let value: moment.Moment | undefined = undefined + if (dateTimeFilter.value) { + value = moment(dateTimeFilter.value) + } + + return ( + {dateTimeFilter.name} @@ -64,18 +64,18 @@ class DateTimeFilterBox extends React.Component { { - that.onValueChange(date, dateString) - }}/> + showTime + format={dateTimeFilter.format} + value={value} + placeholder="请选择日期时间" + onChange={(date: moment.Moment | null, dateString: string) => { + that.onValueChange(date, dateString) + }}/> - ); - } + ); + } } export default DateTimeFilterBox; diff --git a/src/pages/widget/filter/FilterPanel.tsx b/src/pages/widget/filter/FilterPanel.tsx index 4534653..23d2fde 100644 --- a/src/pages/widget/filter/FilterPanel.tsx +++ b/src/pages/widget/filter/FilterPanel.tsx @@ -21,18 +21,18 @@ import DateFilter from '../../../common/model/base/filter/DateFilter'; interface IProps { - onChange?: (value: any, key: any) => void + onChange?: (value: any, key: any) => void - filters: Filter[] + filters: Filter[] - //Selection 筛选宽松模式 会使用Button,单独占一行的模式。 - selectionButtonLoose?: boolean + //Selection 筛选宽松模式 会使用Button,单独占一行的模式。 + selectionButtonLoose?: boolean - //重置按钮触发 - onReset?: () => void + //重置按钮触发 + onReset?: () => void - //懒搜索模式,点击按钮时才触发搜索的动作,当传递了内容,就会出现搜索按钮。 - onSearch?: () => void + //懒搜索模式,点击按钮时才触发搜索的动作,当传递了内容,就会出现搜索按钮。 + onSearch?: () => void } @@ -47,146 +47,146 @@ interface IState { */ export default class FilterPanel extends React.Component { - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } - - - //当改变某个filter的值 - onChildChange(value: any, key: any) { - - let that = this; - - //通知外面变化了。 - SafeUtil.safeCallback(that.props.onChange)(value, key); - - //更新UI - that.setState({}); - - } - - //当改变某个filter的值 - onReset() { - - let that = this; - let filters = that.props.filters; - - for (let i = 0; i < filters.length; i++) { - let filter = filters[i]; - filter.reset(); + this.state = {}; } - //通知外面变化了。 - SafeUtil.safeCallback(that.props.onReset)(); + //当改变某个filter的值 + onChildChange(value: any, key: any) { - //更新UI - that.setState({}); - } + let that = this; + //通知外面变化了。 + SafeUtil.safeCallback(that.props.onChange)(value, key); - //当改变某个filter的值 - onSearch() { + //更新UI + that.setState({}); - let that = this; + } - //通知外面变化了。 - SafeUtil.safeCallback(that.props.onSearch)(); + //当改变某个filter的值 + onReset() { - //更新UI - that.setState({}); + let that = this; + let filters = that.props.filters; - } - - - render() { - - let that = this; - //router中传入的路由相关对象 - let filters = this.props.filters; - - let needSearchButton: boolean = !!this.props.onSearch; - - let needResetButton: boolean = !!this.props.onReset; - - return ( -
- { - filters.map(((filter: Filter, index: number) => { - - if ((filter instanceof InputFilter) && filter.visible) { - return ( - { - that.onChildChange(val, filter.key); - }}/> - ); - } else if ((filter instanceof DateTimeFilter) && filter.visible) { - return ( - { - that.onChildChange(val, filter.key); - }}/> - ); - } else if ((filter instanceof DateFilter) && filter.visible) { - return ( - { - that.onChildChange(val, filter.key); - }}/> - ); - } else if ((filter instanceof CheckFilter) && filter.visible) { - return ( - { - that.onChildChange(val, filter.key); - }}/> - ); - } else if ((filter instanceof HttpSelectionFilter) && filter.visible) { - //注意,子类放前面,父类放后面 - return ( - { - that.onChildChange(val, filter.key); - }}/> - ); - } else if ((filter instanceof SelectionFilter) && filter.visible) { - return ( - { - that.onChildChange(val, filter.key); - }}/> - ); - } else if ((filter instanceof SortFilter) && filter.visible) { - return ( - { - that.onChildChange(val, filter.key); - }}/> - ); - } else { - return null; - } - - })) + for (let i = 0; i < filters.length; i++) { + let filter = filters[i]; + filter.reset(); } -
- + //通知外面变化了。 + SafeUtil.safeCallback(that.props.onReset)(); - + //更新UI + that.setState({}); + } -
-
- ); - } + //当改变某个filter的值 + onSearch() { + + let that = this; + + //通知外面变化了。 + SafeUtil.safeCallback(that.props.onSearch)(); + + //更新UI + that.setState({}); + + } + + + render() { + + let that = this; + //router中传入的路由相关对象 + let filters = this.props.filters; + + let needSearchButton: boolean = !!this.props.onSearch; + + let needResetButton: boolean = !!this.props.onReset; + + return ( +
+ { + filters.map(((filter: Filter, index: number) => { + + if ((filter instanceof InputFilter) && filter.visible) { + return ( + { + that.onChildChange(val, filter.key); + }}/> + ); + } else if ((filter instanceof DateTimeFilter) && filter.visible) { + return ( + { + that.onChildChange(val, filter.key); + }}/> + ); + } else if ((filter instanceof DateFilter) && filter.visible) { + return ( + { + that.onChildChange(val, filter.key); + }}/> + ); + } else if ((filter instanceof CheckFilter) && filter.visible) { + return ( + { + that.onChildChange(val, filter.key); + }}/> + ); + } else if ((filter instanceof HttpSelectionFilter) && filter.visible) { + //注意,子类放前面,父类放后面 + return ( + { + that.onChildChange(val, filter.key); + }}/> + ); + } else if ((filter instanceof SelectionFilter) && filter.visible) { + return ( + { + that.onChildChange(val, filter.key); + }}/> + ); + } else if ((filter instanceof SortFilter) && filter.visible) { + return ( + { + that.onChildChange(val, filter.key); + }}/> + ); + } else { + return null; + } + + })) + } + +
+ + + + +
+ +
+ ); + } } diff --git a/src/pages/widget/filter/HttpSelectionFilterBox.tsx b/src/pages/widget/filter/HttpSelectionFilterBox.tsx index dc45b76..72747d8 100644 --- a/src/pages/widget/filter/HttpSelectionFilterBox.tsx +++ b/src/pages/widget/filter/HttpSelectionFilterBox.tsx @@ -12,8 +12,8 @@ import TankComponent from "../../../common/component/TankComponent"; const Option = Select.Option; interface IProps { - httpSelectionFilter: HttpSelectionFilter - onChange?: (value: string) => void + httpSelectionFilter: HttpSelectionFilter + onChange?: (value: string) => void } interface IState { @@ -23,104 +23,104 @@ interface IState { export default class HttpSelectionFilterBox extends TankComponent { - constructor(props: IProps) { - super(props); - this.state = {}; - } + constructor(props: IProps) { + super(props); + this.state = {}; + } - componentDidMount() { + componentDidMount() { - this.refresh() - } + this.refresh() + } - refresh() { - //刷新一下列表 - let that = this + refresh() { + //刷新一下列表 + let that = this - let filter = this.props.httpSelectionFilter + let filter = this.props.httpSelectionFilter - let url = filter.url + let url = filter.url - HttpUtil.httpGet(url, {}, function (response: any) { + HttpUtil.httpGet(url, {}, function (response: any) { - //尝试一次回填。因为这个时候才知道之前那个值是否有效。 - filter.options = response.data.data - filter.strictPutValue(filter.value) + //尝试一次回填。因为这个时候才知道之前那个值是否有效。 + filter.options = response.data.data + filter.strictPutValue(filter.value) - that.updateUI() - }) + that.updateUI() + }) - } + } - //改变某个filter的值 - onValueChange = (value: any) => { - let that = this + //改变某个filter的值 + onValueChange = (value: any) => { + let that = this - let filter = this.props.httpSelectionFilter + let filter = this.props.httpSelectionFilter - filter.value = value + filter.value = value - //通知外面变化了。 - SafeUtil.safeCallback(that.props.onChange)(filter.value) + //通知外面变化了。 + SafeUtil.safeCallback(that.props.onChange)(filter.value) - //更新UI - that.updateUI() - } + //更新UI + that.updateUI() + } - render() { + render() { - let that = this + let that = this - let filter = this.props.httpSelectionFilter + let filter = this.props.httpSelectionFilter - let selectionOptions = filter.options + let selectionOptions = filter.options - if (filter.selectionType === SelectionFilterType.COMBOBOX) { - return ( - + if (filter.selectionType === SelectionFilterType.COMBOBOX) { + return ( + {filter.name} ); - } else { - return ( - + } else { + return ( + {filter.name} { - this.onValueChange(e.target.value) - }} - //不希望对"全部"进行回填。 - value={filter.value === '' ? undefined : filter.value} + onChange={(e) => { + this.onValueChange(e.target.value) + }} + //不希望对"全部"进行回填。 + value={filter.value === '' ? undefined : filter.value} > 全部 - { - selectionOptions.map((item: SelectionOption, index: number) => { - return {item.name} - }) - } + { + selectionOptions.map((item: SelectionOption, index: number) => { + return {item.name} + }) + } - ); + ); + } + + } - - - } } diff --git a/src/pages/widget/filter/InputFilterBox.tsx b/src/pages/widget/filter/InputFilterBox.tsx index c37f532..60fa95e 100644 --- a/src/pages/widget/filter/InputFilterBox.tsx +++ b/src/pages/widget/filter/InputFilterBox.tsx @@ -6,8 +6,8 @@ import SafeUtil from "../../../common/util/SafeUtil"; interface IProps { - inputFilter: InputFilter - onChange?: (value: string | null) => void + inputFilter: InputFilter + onChange?: (value: string | null) => void } interface IState { @@ -16,50 +16,50 @@ interface IState { export default class InputFilterBox extends React.Component { - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; + this.state = {}; - } + } - //改变某个filter的值 - onValueChange(event: any) { + //改变某个filter的值 + onValueChange(event: any) { - let that = this + let that = this - let inputFilter: InputFilter = this.props.inputFilter + let inputFilter: InputFilter = this.props.inputFilter - inputFilter.value = event.target.value + inputFilter.value = event.target.value - //通知外面变化了。 - SafeUtil.safeCallback(that.props.onChange)(inputFilter.value) + //通知外面变化了。 + SafeUtil.safeCallback(that.props.onChange)(inputFilter.value) - //更新UI - that.setState({}) - } + //更新UI + that.setState({}) + } - render() { + render() { - let that = this + let that = this - let inputFilter: InputFilter = this.props.inputFilter + let inputFilter: InputFilter = this.props.inputFilter - return ( - + return ( + {inputFilter.name} + placeholder={inputFilter.placeholder} + value={inputFilter.value} + onChange={this.onValueChange.bind(this)}/> - ); - } + ); + } } diff --git a/src/pages/widget/filter/SelectionFilterBox.tsx b/src/pages/widget/filter/SelectionFilterBox.tsx index 1a8055a..2f56044 100644 --- a/src/pages/widget/filter/SelectionFilterBox.tsx +++ b/src/pages/widget/filter/SelectionFilterBox.tsx @@ -10,8 +10,8 @@ import SelectionFilterType from "../../../common/model/base/filter/SelectionFilt const Option = Select.Option; interface IProps { - selectionFilter: SelectionFilter - onChange?: (value: string) => void + selectionFilter: SelectionFilter + onChange?: (value: string) => void } interface IState { @@ -19,82 +19,82 @@ interface IState { export default class SelectionFilterBox extends React.Component { - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } + this.state = {}; + } - //改变某个filter的值 - onValueChange = (value: any) => { + //改变某个filter的值 + onValueChange = (value: any) => { - let that = this + let that = this - let selectionFilter = this.props.selectionFilter + let selectionFilter = this.props.selectionFilter - selectionFilter.value = value + selectionFilter.value = value - //通知外面变化了。 - SafeUtil.safeCallback(that.props.onChange)() + //通知外面变化了。 + SafeUtil.safeCallback(that.props.onChange)() - //更新UI - that.setState({}) + //更新UI + that.setState({}) - } + } - render() { + render() { - let that = this + let that = this - let selectionFilter = this.props.selectionFilter + let selectionFilter = this.props.selectionFilter - if (selectionFilter.selectionType === SelectionFilterType.COMBOBOX) { - return ( - + if (selectionFilter.selectionType === SelectionFilterType.COMBOBOX) { + return ( + {selectionFilter.name} - ); - } else { - return ( - + ); + } else { + return ( + {selectionFilter.name} { - this.onValueChange(e.target.value) - }} - //不希望对"全部"进行回填。 - value={selectionFilter.value === '' ? undefined : selectionFilter.value} + onChange={(e) => { + this.onValueChange(e.target.value) + }} + //不希望对"全部"进行回填。 + value={selectionFilter.value === '' ? undefined : selectionFilter.value} > 全部 - {selectionFilter.options ? - selectionFilter.options.map((item: SelectionOption, index: number) => { - return {item.name} - }) - : null} + {selectionFilter.options ? + selectionFilter.options.map((item: SelectionOption, index: number) => { + return {item.name} + }) + : null} - ); - } + ); + } - } + } } diff --git a/src/pages/widget/filter/SortFilterBox.tsx b/src/pages/widget/filter/SortFilterBox.tsx index 6efb338..b23c408 100644 --- a/src/pages/widget/filter/SortFilterBox.tsx +++ b/src/pages/widget/filter/SortFilterBox.tsx @@ -8,8 +8,8 @@ import SortDirection from "../../../common/model/base/SortDirection"; const Option = Select.Option; interface IProps { - sortFilter: SortFilter - onChange?: (value: SortDirection | null) => void + sortFilter: SortFilter + onChange?: (value: SortDirection | null) => void } interface IState { @@ -17,38 +17,38 @@ interface IState { export default class SortFilterBox extends React.Component { - constructor(props: IProps) { - super(props); + constructor(props: IProps) { + super(props); - this.state = {}; - } + this.state = {}; + } - //改变某个filter的值 - onValueChange = (value: string) => { + //改变某个filter的值 + onValueChange = (value: string) => { - let that = this + let that = this - let sortFilter = this.props.sortFilter + let sortFilter = this.props.sortFilter - sortFilter.putValue(value) + sortFilter.putValue(value) - //通知外面变化了。 - SafeUtil.safeCallback(that.props.onChange)(sortFilter.value) + //通知外面变化了。 + SafeUtil.safeCallback(that.props.onChange)(sortFilter.value) - //更新UI - that.setState({}) + //更新UI + that.setState({}) - } + } - render() { + render() { - let that = this + let that = this - let sortFilter = this.props.sortFilter + let sortFilter = this.props.sortFilter - return ( - + return ( + @@ -63,8 +63,8 @@ export default class SortFilterBox extends React.Component { - ); - } + ); + } } diff --git a/src/pages/widget/previewer/BrowserPreviewer.tsx b/src/pages/widget/previewer/BrowserPreviewer.tsx index 9ee38b6..8d16926 100644 --- a/src/pages/widget/previewer/BrowserPreviewer.tsx +++ b/src/pages/widget/previewer/BrowserPreviewer.tsx @@ -5,10 +5,10 @@ import FileUtil from "../../../common/util/FileUtil"; import {CloseOutlined} from "@ant-design/icons"; interface IProps { - name: string - url: string - size: number - onClose: () => void + name: string + url: string + size: number + onClose: () => void } interface IState { @@ -21,75 +21,75 @@ interface IState { */ export default class BrowserPreviewer extends React.Component { - constructor(props: IProps) { - super(props); - this.state = {}; - } + constructor(props: IProps) { + super(props); + this.state = {}; + } - componentDidMount() { + componentDidMount() { - } + } - //展示一系列图片 - static show(name: string, url: string, size: number) { + //展示一系列图片 + static show(name: string, url: string, size: number) { - let that = this; + let that = this; - const div: Element = document.createElement('div'); - document.body.appendChild(div); + const div: Element = document.createElement('div'); + document.body.appendChild(div); - let element: React.ReactElement = React.createElement( - BrowserPreviewer, - { - name: name, - url: url, - size: size, - onClose: () => { - //删除所有节点。 - const unmountResult = ReactDOM.unmountComponentAtNode(div); - if (unmountResult && div.parentNode) { + let element: React.ReactElement = React.createElement( + BrowserPreviewer, + { + name: name, + url: url, + size: size, + onClose: () => { + //删除所有节点。 + const unmountResult = ReactDOM.unmountComponentAtNode(div); + if (unmountResult && div.parentNode) { - div.parentNode.removeChild(div); + div.parentNode.removeChild(div); - } - } - } - ) + } + } + } + ) - //将react组件挂载到div中去。 - ReactDOM.render(element, div); + //将react组件挂载到div中去。 + ReactDOM.render(element, div); - } + } - render() { - return
-
+ render() { + return
+
-
+
-
+
-
- {this.props.name}({FileUtil.humanFileSize(this.props.size)}) -
+
+ {this.props.name}({FileUtil.humanFileSize(this.props.size)}) +
-
+
{ - this.props.onClose() + this.props.onClose() }}/> +
+ + +
+
+ +
- - -
-
- -
-
- } + } } diff --git a/src/pages/widget/previewer/ImagePreviewer.tsx b/src/pages/widget/previewer/ImagePreviewer.tsx index c28c2f6..d1cd717 100644 --- a/src/pages/widget/previewer/ImagePreviewer.tsx +++ b/src/pages/widget/previewer/ImagePreviewer.tsx @@ -144,6 +144,7 @@ export default class ImagePreviewer { div.parentNode.removeChild(div); } }); - photoSwipe.listen('afterChange', () => {}); + photoSwipe.listen('afterChange', () => { + }); } } diff --git a/src/pages/widget/previewer/PreviewerHelper.ts b/src/pages/widget/previewer/PreviewerHelper.ts index b4db211..a282c05 100644 --- a/src/pages/widget/previewer/PreviewerHelper.ts +++ b/src/pages/widget/previewer/PreviewerHelper.ts @@ -12,114 +12,114 @@ import DownloadToken from "../../../common/model/download/token/DownloadToken"; */ export default class PreviewerHelper { - static b64EncodeUnicode(str: string) { - // first we use encodeURIComponent to get percent-encoded UTF-8, - // then we convert the percent encodings into raw bytes which - // can be fed into btoa. - return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, - // function toSolidBytes(match, p1) { - (match, p1) => { - // console.debug('match: ' + match); - return String.fromCharCode(("0x" + p1) as any); - })); - } - - static b64DecodeUnicode(str: string) { - // Going backwards: from bytestream, to percent-encoding, to original string. - return decodeURIComponent(atob(str).split('').map(function (c) { - return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); - }).join('')); - } - - /** - * 准备好一个文件url - */ - static prepareMatterUrl( - matter: Matter, - needTokenUrl: boolean, - successCallback: (matterUrl: string) => void - ) { - if (needTokenUrl) { - //获取一个临时的下载token. - let downloadToken = new DownloadToken(); - downloadToken.httpFetchDownloadToken(matter.uuid!, function () { - let matterUrl = matter.getPreviewUrl(downloadToken.uuid!); - - successCallback(matterUrl); - }); - } else { - successCallback(matter.getPreviewUrl()); - } - } - - /** - * 对一个文件进行预览,自动选择预览引擎 - * @param matter 文件 - * @param previewUrl 文件预览url,分享文件预览需从外部把previewUrl传入 - */ - static preview(matter: Matter, previewUrl?: string) { - let fileName: string = matter.name; - let extension: string = MimeUtil.getExtensionWithoutDot(fileName); - if (!extension) { - MessageBoxUtil.warning(fileName + " 没有后缀名,无法预览"); - return; + static b64EncodeUnicode(str: string) { + // first we use encodeURIComponent to get percent-encoded UTF-8, + // then we convert the percent encodings into raw bytes which + // can be fed into btoa. + return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, + // function toSolidBytes(match, p1) { + (match, p1) => { + // console.debug('match: ' + match); + return String.fromCharCode(("0x" + p1) as any); + })); } - //去选择预览引擎。 - let previewConfig = Moon.getSingleton().preference.previewConfig; - - let previewEngine: PreviewEngine | null = null; - - //寻找用户自定义的预览引擎 - for (let engine of previewConfig.previewEngines) { - if (engine.canPreview(fileName)) { - previewEngine = engine; - break; - } + static b64DecodeUnicode(str: string) { + // Going backwards: from bytestream, to percent-encoding, to original string. + return decodeURIComponent(atob(str).split('').map(function (c) { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); + }).join('')); } - //寻找官方默认的预览引擎 - if (previewEngine === null) { - let defaultEngines = PreviewEngine.defaultPreviewEngines(); - for (let engine of defaultEngines) { - if (engine.canPreview(fileName)) { - previewEngine = engine; - break; - } - } - } + /** + * 准备好一个文件url + */ + static prepareMatterUrl( + matter: Matter, + needTokenUrl: boolean, + successCallback: (matterUrl: string) => void + ) { + if (needTokenUrl) { + //获取一个临时的下载token. + let downloadToken = new DownloadToken(); + downloadToken.httpFetchDownloadToken(matter.uuid!, function () { + let matterUrl = matter.getPreviewUrl(downloadToken.uuid!); - if (previewEngine === null) { - MessageBoxUtil.warning(fileName + " 无法预览"); - } else { - let targetUrl = previewEngine.url; - - const engine: PreviewEngine = previewEngine; - - if (previewUrl) { - targetUrl = targetUrl.replace("{originUrl}", previewUrl); - targetUrl = targetUrl.replace("{b64Url}", previewUrl); - targetUrl = targetUrl.replace("{url}", previewUrl); - if (engine.previewInSite) { - BrowserPreviewer.show(fileName, targetUrl, matter.size); + successCallback(matterUrl); + }); } else { - window.open(targetUrl); + successCallback(matter.getPreviewUrl()); + } + } + + /** + * 对一个文件进行预览,自动选择预览引擎 + * @param matter 文件 + * @param previewUrl 文件预览url,分享文件预览需从外部把previewUrl传入 + */ + static preview(matter: Matter, previewUrl?: string) { + let fileName: string = matter.name; + let extension: string = MimeUtil.getExtensionWithoutDot(fileName); + if (!extension) { + MessageBoxUtil.warning(fileName + " 没有后缀名,无法预览"); + return; + } + + //去选择预览引擎。 + let previewConfig = Moon.getSingleton().preference.previewConfig; + + let previewEngine: PreviewEngine | null = null; + + //寻找用户自定义的预览引擎 + for (let engine of previewConfig.previewEngines) { + if (engine.canPreview(fileName)) { + previewEngine = engine; + break; + } + } + + //寻找官方默认的预览引擎 + if (previewEngine === null) { + let defaultEngines = PreviewEngine.defaultPreviewEngines(); + for (let engine of defaultEngines) { + if (engine.canPreview(fileName)) { + previewEngine = engine; + break; + } + } + } + + if (previewEngine === null) { + MessageBoxUtil.warning(fileName + " 无法预览"); + } else { + let targetUrl = previewEngine.url; + + const engine: PreviewEngine = previewEngine; + + if (previewUrl) { + targetUrl = targetUrl.replace("{originUrl}", previewUrl); + targetUrl = targetUrl.replace("{b64Url}", previewUrl); + targetUrl = targetUrl.replace("{url}", previewUrl); + if (engine.previewInSite) { + BrowserPreviewer.show(fileName, targetUrl, matter.size); + } else { + window.open(targetUrl); + } + } else { + const needToken = matter.privacy && (targetUrl.indexOf("{url}") !== -1 || targetUrl.indexOf("{b64Url}") !== -1) + + PreviewerHelper.prepareMatterUrl(matter, needToken, function (url) { + targetUrl = targetUrl.replace("{originUrl}", matter.getPreviewUrl()); + targetUrl = targetUrl.replace("{b64Url}", encodeURIComponent(PreviewerHelper.b64EncodeUnicode(url))); + targetUrl = targetUrl.replace("{url}", encodeURIComponent(url)); + if (engine.previewInSite) { + BrowserPreviewer.show(fileName, targetUrl, matter.size); + } else { + window.open(targetUrl); + } + }); + } + } - } else { - const needToken = matter.privacy && (targetUrl.indexOf("{url}") !== -1||targetUrl.indexOf("{b64Url}") !== -1) - - PreviewerHelper.prepareMatterUrl(matter, needToken, function (url) { - targetUrl = targetUrl.replace("{originUrl}", matter.getPreviewUrl()); - targetUrl = targetUrl.replace("{b64Url}", encodeURIComponent(PreviewerHelper.b64EncodeUnicode(url))); - targetUrl = targetUrl.replace("{url}", encodeURIComponent(url)); - if (engine.previewInSite) { - BrowserPreviewer.show(fileName, targetUrl, matter.size); - } else { - window.open(targetUrl); - } - }); - } - } - } } diff --git a/src/react-app-env.d.ts b/src/react-app-env.d.ts index d81a2ca..c7e1314 100644 --- a/src/react-app-env.d.ts +++ b/src/react-app-env.d.ts @@ -1,20 +1,20 @@ /// declare module 'velocity-animate' { - import Velocity from 'velocity-animate'; - export default Velocity; + import Velocity from 'velocity-animate'; + export default Velocity; } declare module 'velocity-react' { - import VelocityReact from 'velocity-react'; - export default VelocityReact; + import VelocityReact from 'velocity-react'; + export default VelocityReact; } declare module 'comma-separated-values' { - import CSV from 'comma-separated-values'; - export default CSV; + import CSV from 'comma-separated-values'; + export default CSV; } declare interface File { - webkitRelativePath: string; + webkitRelativePath: string; }