Browse Source

fix:
1.更换下载点击图标。
2.替换所有原样下载的函数调用名称 testExport->exportAsIs。
feature:
1.新增水印功能。

wanrx 1 year ago
parent
commit
5c47fadd4f

+ 54 - 13
package-lock.json

@@ -18,6 +18,7 @@
         "@types/react": "17.0.38",
         "antd": "4.16.13",
         "antd-theme-generator": "1.2.11",
+        "antd-watermark": "^1.0.1",
         "axios": "^0.21.1",
         "chokidar": "^3.6.0",
         "classnames": "^2.3.1",
@@ -1880,11 +1881,11 @@
       }
     },
     "node_modules/@babel/runtime": {
-      "version": "7.17.8",
-      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.8.tgz",
-      "integrity": "sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==",
+      "version": "7.24.6",
+      "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.24.6.tgz",
+      "integrity": "sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw==",
       "dependencies": {
-        "regenerator-runtime": "^0.13.4"
+        "regenerator-runtime": "^0.14.0"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1903,6 +1904,11 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@babel/runtime/node_modules/regenerator-runtime": {
+      "version": "0.14.1",
+      "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+      "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
+    },
     "node_modules/@babel/template": {
       "version": "7.18.6",
       "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.6.tgz",
@@ -6559,6 +6565,21 @@
       "inBundle": true,
       "license": "ISC"
     },
+    "node_modules/antd-watermark": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/antd-watermark/-/antd-watermark-1.0.1.tgz",
+      "integrity": "sha512-fLPq5HqHKizl1gZuOrDbecjdkYPMMJl1ETRYmitq14vRvagKTuCF698DEaANIAiR1DKmCGm5UO1J5/7JK2opjw==",
+      "dependencies": {
+        "@babel/runtime": "^7.18.0"
+      },
+      "engines": {
+        "node": ">=8.x"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
     "node_modules/anymatch": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
@@ -31544,11 +31565,18 @@
       }
     },
     "@babel/runtime": {
-      "version": "7.17.8",
-      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.8.tgz",
-      "integrity": "sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==",
+      "version": "7.24.6",
+      "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.24.6.tgz",
+      "integrity": "sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw==",
       "requires": {
-        "regenerator-runtime": "^0.13.4"
+        "regenerator-runtime": "^0.14.0"
+      },
+      "dependencies": {
+        "regenerator-runtime": {
+          "version": "0.14.1",
+          "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+          "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
+        }
       }
     },
     "@babel/runtime-corejs3": {
@@ -32123,7 +32151,8 @@
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz",
       "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "@ctrl/tinycolor": {
       "version": "3.4.0",
@@ -35317,6 +35346,14 @@
         }
       }
     },
+    "antd-watermark": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/antd-watermark/-/antd-watermark-1.0.1.tgz",
+      "integrity": "sha512-fLPq5HqHKizl1gZuOrDbecjdkYPMMJl1ETRYmitq14vRvagKTuCF698DEaANIAiR1DKmCGm5UO1J5/7JK2opjw==",
+      "requires": {
+        "@babel/runtime": "^7.18.0"
+      }
+    },
     "anymatch": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
@@ -48357,7 +48394,8 @@
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-7.0.1.tgz",
       "integrity": "sha512-iLBFYz6VRYyLJEJsBJ8M3TCqNcckVzz4wFounSc5Oez35ogE/X+aoC5fFu103Ot7NyvjU3/xqIXn93Gp3kJk4g==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "postcss-svgo": {
       "version": "4.0.3",
@@ -48392,7 +48430,8 @@
       "version": "0.36.2",
       "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz",
       "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "postcss-unique-selectors": {
       "version": "4.0.1",
@@ -52266,7 +52305,8 @@
       "version": "9.0.3",
       "resolved": "https://registry.npmjs.org/stylelint-config-prettier/-/stylelint-config-prettier-9.0.3.tgz",
       "integrity": "sha512-5n9gUDp/n5tTMCq1GLqSpA30w2sqWITSSEiAWQlpxkKGAUbjcemQ0nbkRvRUa0B1LgD3+hCvdL7B1eTxy1QHJg==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "stylelint-config-recess-order": {
       "version": "3.0.0",
@@ -52281,7 +52321,8 @@
       "version": "8.0.0",
       "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-8.0.0.tgz",
       "integrity": "sha512-IK6dWvE000+xBv9jbnHOnBq01gt6HGVB2ZTsot+QsMpe82doDQ9hvplxfv4YnpEuUwVGGd9y6nbaAnhrjcxhZQ==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "stylelint-config-styled-components": {
       "version": "0.1.1",

+ 1 - 0
package.json

@@ -99,6 +99,7 @@
     "@types/react": "17.0.38",
     "antd": "4.16.13",
     "antd-theme-generator": "1.2.11",
+    "antd-watermark": "^1.0.1",
     "axios": "^0.21.1",
     "chokidar": "^3.6.0",
     "classnames": "^2.3.1",

+ 2 - 2
src/app/components/ChartEditor.tsx

@@ -573,7 +573,7 @@ export const ChartEditor: FC<ChartEditorProps> = ({
     setAllowQuery(false);
   }, [dispatch, drillOptionRef]);
 
-  const testExport = ()=>{
+  const exportAsIs = ()=>{
     // @ts-ignore
     const data = copyData(chart?.chart?.dataSet.spreadsheet, ',', false)
     download(data, 'filename')
@@ -674,7 +674,7 @@ export const ChartEditor: FC<ChartEditorProps> = ({
           onRefreshDataset={handleRefreshDataset}
           onCreateDownloadDataTask={handleCreateDownloadDataTask}
           onDateLevelChange={handleDateLevelChange}
-          testExport={testExport}
+          exportAsIs={exportAsIs}
         />
         <SaveForm
           width={400}

+ 1 - 1
src/app/components/ChartGraph/PivotSheetChart/AntVS2Wrapper.tsx

@@ -58,7 +58,7 @@ const AntVS2Wrapper: FC<AndvS2Config> = memo(
       });
     };
 
-    const testExport = (sheet)=>{
+    const exportAsIs = (sheet)=>{
       const data = copyData(sheet, '\t', false)
       // 导出数据 (filename.csv)
       download(data, 'filename')

+ 3 - 3
src/app/pages/ChartWorkbenchPage/components/ChartOperationPanel/ChartOperationPanel.tsx

@@ -41,7 +41,7 @@ const ChartOperationPanel: FC<{
   onDataViewChange?: (clear?: boolean) => void;
   onCreateDownloadDataTask?: () => void;
   selectedItems?: SelectedItem[];
-  testExport?: () => void;
+  exportAsIs?: () => void;
 }> = memo(
   ({
     chart,
@@ -53,7 +53,7 @@ const ChartOperationPanel: FC<{
     onDataViewChange,
     onCreateDownloadDataTask,
     selectedItems,
-    testExport
+    exportAsIs
   }) => {
     const { dataset, onRefreshDataset } = useContext(ChartDatasetContext);
     const { dataView, expensiveQuery } = useContext(ChartDataViewContext);
@@ -104,7 +104,7 @@ const ChartOperationPanel: FC<{
             onRefreshDataset={onRefreshDataset}
             onCreateDownloadDataTask={onCreateDownloadDataTask}
             selectedItems={selectedItems}
-            testExport={testExport}
+            exportAsIs={exportAsIs}
           />
         );
       }

+ 3 - 3
src/app/pages/ChartWorkbenchPage/components/ChartOperationPanel/components/ChartPresentPanel/ChartPresentPanel.tsx

@@ -62,7 +62,7 @@ const ChartPresentPanel: FC<{
   onCreateDownloadDataTask?: () => void;
   selectedItems?: SelectedItem[];
   dataView?: ChartDataView;
-  testExport?: () => void;
+  exportAsIs?: () => void;
 }> = memo(
   ({
     containerHeight,
@@ -76,7 +76,7 @@ const ChartPresentPanel: FC<{
     onCreateDownloadDataTask,
     selectedItems,
     dataView,
-    testExport
+    exportAsIs
   }) => {
     const translate = useI18NPrefix(`viz.palette.present`);
     const chartDispatcher = ChartIFrameContainerDispatcher.instance();
@@ -180,7 +180,7 @@ const ChartPresentPanel: FC<{
               type={chartType}
               translate={translate}
               onChange={setChartType}
-              testExport={testExport}
+              exportAsIs={exportAsIs}
               onCreateDownloadDataTask={onCreateDownloadDataTask}
             />
           </Col>

+ 6 - 5
src/app/pages/ChartWorkbenchPage/components/ChartOperationPanel/components/ChartPresentPanel/components/ChartTypeSelector.tsx

@@ -21,6 +21,7 @@ import {
   CloudDownloadOutlined,
   ConsoleSqlOutlined,
   TableOutlined,
+  DownloadOutlined
 } from '@ant-design/icons';
 import { Popconfirm } from 'antd';
 import { IW } from 'app/components';
@@ -42,8 +43,8 @@ const ChartTypeSelector: FC<{
   translate: (title: string) => string;
   onChange: (value) => void;
   onCreateDownloadDataTask?: () => void;
-  testExport?: () => void;
-}> = memo(({ type, onChange, onCreateDownloadDataTask,testExport }) => {
+  exportAsIs?: () => void;
+}> = memo(({ type, onChange, onCreateDownloadDataTask,exportAsIs }) => {
   const t = useI18NPrefix(`viz.action.common`);
   const typeChange = useCallback(
     type => () => {
@@ -93,10 +94,10 @@ const ChartTypeSelector: FC<{
       >
         <Popconfirm
           placement="left"
-          title={t('ok')}
-          onConfirm={testExport}
+          title={t('exportAsIs')}
+          onConfirm={exportAsIs}
         >
-          <CloudDownloadOutlined />
+          <DownloadOutlined />
         </Popconfirm>
       </TypeSelector>
     </StyledChartTypeSelector>

+ 3 - 3
src/app/pages/ChartWorkbenchPage/components/ChartOperationPanel/components/ChartPresentWrapper.tsx

@@ -41,7 +41,7 @@ const ChartPresentWrapper: FC<{
   onCreateDownloadDataTask?: () => void;
   dataView?: ChartDataView;
   selectedItems?: SelectedItem[];
-  testExport?: () => void;
+  exportAsIs?: () => void;
 }> = memo(
   ({
     containerHeight,
@@ -56,7 +56,7 @@ const ChartPresentWrapper: FC<{
     onRefreshDataset,
     onCreateDownloadDataTask,
     selectedItems,
-    testExport
+    exportAsIs
   }) => {
     const { ref: ChartGraphPanelRef } = useResizeObserver<any>({
       refreshMode: 'debounce',
@@ -93,7 +93,7 @@ const ChartPresentWrapper: FC<{
             onCreateDownloadDataTask={onCreateDownloadDataTask}
             selectedItems={selectedItems}
             dataView={dataView}
-            testExport={testExport}
+            exportAsIs={exportAsIs}
           />
         </ChartI18NContext.Provider>
       </StyledChartPresentWrapper>

+ 3 - 3
src/app/pages/ChartWorkbenchPage/components/ChartWorkbench/ChartWorkbench.tsx

@@ -61,7 +61,7 @@ const ChartWorkbench: FC<{
   onCreateDownloadDataTask?: () => void;
   onChartDrillOptionChange?: (option: IChartDrillOption) => void;
   onDateLevelChange?: (type: string, option: any) => void;
-  testExport?: () => void;
+  exportAsIs?: () => void;
 }> = memo(
   ({
     dataset,
@@ -83,7 +83,7 @@ const ChartWorkbench: FC<{
     onCreateDownloadDataTask,
     onChartDrillOptionChange,
     onDateLevelChange,
-    testExport
+     exportAsIs
   }) => {
     const language = useSelector(languageSelector);
     const dateFormat = useSelector(dateFormatSelector);
@@ -141,7 +141,7 @@ const ChartWorkbench: FC<{
                       onDataViewChange={onDataViewChange}
                       onCreateDownloadDataTask={onCreateDownloadDataTask}
                       selectedItems={selectedItems}
-                      testExport={testExport}
+                      exportAsIs={exportAsIs}
                     />
                   </StyledChartOperationPanel>
                 </StyledChartWorkbench>

+ 155 - 140
src/app/pages/MainPage/index.tsx

@@ -52,13 +52,17 @@ import { VizPage } from './pages/VizPage';
 import { useVizSlice } from './pages/VizPage/slice';
 import { initChartPreviewData } from './pages/VizPage/slice/thunks';
 import { useMainSlice } from './slice';
-import { selectOrgId } from './slice/selectors';
+import {selectOrgId} from './slice/selectors';
+import {
+  selectLoggedInUser,
+} from 'app/slice/selectors';
 import {
   getDataProviders,
   getLoggedInUserPermissions,
   getUserSettings,
 } from './slice/thunks';
 import { MainPageRouteParams } from './types';
+import Watermark from 'antd-watermark';
 
 export function MainPage() {
   useAppSlice();
@@ -69,6 +73,8 @@ export function MainPage() {
   const organizationMatch = useRouteMatch<MainPageRouteParams>(
     '/organizations/:orgId',
   );
+  const loggedInUser = useSelector(selectLoggedInUser)
+  console.log(loggedInUser)
   const orgId = useSelector(selectOrgId);
   const history = useHistory();
   // loaded first time
@@ -109,153 +115,162 @@ export function MainPage() {
     [dispatch, history],
   );
 
+  const wmContent = ()=>{
+    const name = loggedInUser?.name
+    const username = loggedInUser?.username
+    return `${name} ${username}`
+  }
+
   return (
     <AppContainer>
-      <Background />
-      <Navbar />
-      {orgId && (
-        <Switch>
-          <Route path="/" exact>
-            <Redirect to={`/organizations/${orgId}`} />
-          </Route>
-          <Route path="/confirminvite" component={ConfirmInvitePage} />
-          <Route path="/organizations/:orgId" exact>
-            <Redirect
-              to={`/organizations/${organizationMatch?.params.orgId}/vizs`}
+      <Watermark content={wmContent()} style={{width:'100%',display:'flex'}} font={{fontSize:22,color:'rgba(0,0,0,0.05)'}} gap={[150, 150]}>
+        <Background />
+        <Navbar />
+
+        {orgId && (
+          <Switch>
+            <Route path="/" exact>
+              <Redirect to={`/organizations/${orgId}`} />
+            </Route>
+            <Route path="/confirminvite" component={ConfirmInvitePage} />
+            <Route path="/organizations/:orgId" exact>
+              <Redirect
+                to={`/organizations/${organizationMatch?.params.orgId}/vizs`}
+              />
+            </Route>
+            <Route
+              path="/organizations/:orgId/vizs/chartEditor"
+              render={res => {
+                const hisSearch = new URLSearchParams(res.location.search);
+                const hisState = {
+                  dataChartId: hisSearch.get('dataChartId') || '',
+                  chartType: hisSearch.get('chartType') || 'dataChart',
+                  container: hisSearch.get('container') || 'dataChart',
+                  defaultViewId: hisSearch.get('defaultViewId') || '',
+                } as ChartEditorBaseProps;
+                return (
+                  <AccessRoute module={ResourceTypes.Viz}>
+                    <ChartEditor
+                      dataChartId={hisState.dataChartId}
+                      orgId={orgId}
+                      chartType={hisState.chartType}
+                      container={hisState.container}
+                      defaultViewId={hisState.defaultViewId}
+                      onClose={() => history.go(-1)}
+                      onSaveInDataChart={onSaveInDataChart}
+                    />
+                  </AccessRoute>
+                );
+              }}
             />
-          </Route>
-          <Route
-            path="/organizations/:orgId/vizs/chartEditor"
-            render={res => {
-              const hisSearch = new URLSearchParams(res.location.search);
-              const hisState = {
-                dataChartId: hisSearch.get('dataChartId') || '',
-                chartType: hisSearch.get('chartType') || 'dataChart',
-                container: hisSearch.get('container') || 'dataChart',
-                defaultViewId: hisSearch.get('defaultViewId') || '',
-              } as ChartEditorBaseProps;
-              return (
+
+            <Route
+              path="/organizations/:orgId/vizs/storyPlayer/:storyId"
+              render={() => <StoryPlayer />}
+            />
+            <Route
+              path="/organizations/:orgId/vizs/storyEditor/:storyId"
+              render={() => <StoryEditor />}
+            />
+            <Route
+              path="/organizations/:orgId/vizs/:vizId?"
+              render={() => (
                 <AccessRoute module={ResourceTypes.Viz}>
-                  <ChartEditor
-                    dataChartId={hisState.dataChartId}
-                    orgId={orgId}
-                    chartType={hisState.chartType}
-                    container={hisState.container}
-                    defaultViewId={hisState.defaultViewId}
-                    onClose={() => history.go(-1)}
-                    onSaveInDataChart={onSaveInDataChart}
-                  />
+                  <VizPage />
                 </AccessRoute>
-              );
-            }}
-          />
-
-          <Route
-            path="/organizations/:orgId/vizs/storyPlayer/:storyId"
-            render={() => <StoryPlayer />}
-          />
-          <Route
-            path="/organizations/:orgId/vizs/storyEditor/:storyId"
-            render={() => <StoryEditor />}
-          />
-          <Route
-            path="/organizations/:orgId/vizs/:vizId?"
-            render={() => (
-              <AccessRoute module={ResourceTypes.Viz}>
-                <VizPage />
-              </AccessRoute>
-            )}
-          />
-          <Route
-            path="/organizations/:orgId/views/:viewId?"
-            render={() => (
-              <AccessRoute module={ResourceTypes.View}>
-                <ViewPage />
-              </AccessRoute>
-            )}
-          />
-          <Route
-            path="/organizations/:orgId/sources"
-            render={() => (
-              <AccessRoute module={ResourceTypes.Source}>
-                <SourcePage />
-              </AccessRoute>
-            )}
-          />
-          <Route
-            path="/organizations/:orgId/schedules"
-            render={() => (
-              <AccessRoute module={ResourceTypes.Schedule}>
-                <SchedulePage />
-              </AccessRoute>
-            )}
-          />
-          <Route
-            path="/organizations/:orgId/members"
-            render={() => (
-              <AccessRoute module={ResourceTypes.User}>
-                <MemberPage />
-              </AccessRoute>
-            )}
-          />
-          <Route
-            path="/organizations/:orgId/roles"
-            render={() => (
-              <AccessRoute module={ResourceTypes.User}>
-                <MemberPage />
-              </AccessRoute>
-            )}
-          />
-          <Route path="/organizations/:orgId/permissions" exact>
-            <Redirect
-              to={`/organizations/${organizationMatch?.params.orgId}/permissions/subject`}
+              )}
             />
-          </Route>
+            <Route
+              path="/organizations/:orgId/views/:viewId?"
+              render={() => (
+                <AccessRoute module={ResourceTypes.View}>
+                  <ViewPage />
+                </AccessRoute>
+              )}
+            />
+            <Route
+              path="/organizations/:orgId/sources"
+              render={() => (
+                <AccessRoute module={ResourceTypes.Source}>
+                  <SourcePage />
+                </AccessRoute>
+              )}
+            />
+            <Route
+              path="/organizations/:orgId/schedules"
+              render={() => (
+                <AccessRoute module={ResourceTypes.Schedule}>
+                  <SchedulePage />
+                </AccessRoute>
+              )}
+            />
+            <Route
+              path="/organizations/:orgId/members"
+              render={() => (
+                <AccessRoute module={ResourceTypes.User}>
+                  <MemberPage />
+                </AccessRoute>
+              )}
+            />
+            <Route
+              path="/organizations/:orgId/roles"
+              render={() => (
+                <AccessRoute module={ResourceTypes.User}>
+                  <MemberPage />
+                </AccessRoute>
+              )}
+            />
+            <Route path="/organizations/:orgId/permissions" exact>
+              <Redirect
+                to={`/organizations/${organizationMatch?.params.orgId}/permissions/subject`}
+              />
+            </Route>
 
-          <Route
-            path="/organizations/:orgId/departments"
-            render={() => (
-              <AccessRoute module={ResourceTypes.Department}>
-                <DepartmentPage />
-              </AccessRoute>
-            )}
-          />
+            <Route
+              path="/organizations/:orgId/departments"
+              render={() => (
+                <AccessRoute module={ResourceTypes.Department}>
+                  <DepartmentPage />
+                </AccessRoute>
+              )}
+            />
 
-          <Route
-            path="/organizations/:orgId/permissions/:viewpoint"
-            render={() => (
-              <AccessRoute module={ResourceTypes.Manager}>
-                <PermissionPage />
-              </AccessRoute>
-            )}
-          />
-          <Route
-            path="/organizations/:orgId/variables"
-            render={() => (
-              <AccessRoute module={ResourceTypes.Manager}>
-                <VariablePage />
-              </AccessRoute>
-            )}
-          />
-          <Route
-            path="/organizations/:orgId/orgSettings"
-            render={() => (
-              <AccessRoute module={ResourceTypes.Manager}>
-                <OrgSettingPage />
-              </AccessRoute>
-            )}
-          />
-          <Route
-            path="/organizations/:orgId/resourceMigration"
-            render={() => (
-              <AccessRoute module={ResourceTypes.Manager}>
-                <ResourceMigrationPage />
-              </AccessRoute>
-            )}
-          />
-          <Route path="*" component={NotFoundPage} />
-        </Switch>
-      )}
+            <Route
+              path="/organizations/:orgId/permissions/:viewpoint"
+              render={() => (
+                <AccessRoute module={ResourceTypes.Manager}>
+                  <PermissionPage />
+                </AccessRoute>
+              )}
+            />
+            <Route
+              path="/organizations/:orgId/variables"
+              render={() => (
+                <AccessRoute module={ResourceTypes.Manager}>
+                  <VariablePage />
+                </AccessRoute>
+              )}
+            />
+            <Route
+              path="/organizations/:orgId/orgSettings"
+              render={() => (
+                <AccessRoute module={ResourceTypes.Manager}>
+                  <OrgSettingPage />
+                </AccessRoute>
+              )}
+            />
+            <Route
+              path="/organizations/:orgId/resourceMigration"
+              render={() => (
+                <AccessRoute module={ResourceTypes.Manager}>
+                  <ResourceMigrationPage />
+                </AccessRoute>
+              )}
+            />
+            <Route path="*" component={NotFoundPage} />
+          </Switch>
+        )}
+        </Watermark>
     </AppContainer>
   );
 }

+ 1 - 0
src/locales/zh/translation.json

@@ -882,6 +882,7 @@
     "action": {
       "common": {
         "exportForExcel": "导出到 Excel",
+        "exportAsIs": "原样导出",
         "confirm": "请确认",
         "ok": "确认",
         "cancel": "取消",