From 49efc0e4df175a47fc20445d8ceafbb29555e562 Mon Sep 17 00:00:00 2001 From: maggieyyy <61950669+maggieyyy@users.noreply.github.com> Date: Tue, 20 Aug 2024 18:49:14 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=A4=9A=E8=AF=AD=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/i18next-scanner.config.js | 68 +++ frontend/package.json | 9 +- .../src/components/aoplatform/BasicLayout.tsx | 288 ++++----- .../src/components/aoplatform/CodePage.tsx | 7 +- .../src/components/aoplatform/DatePicker.tsx | 8 - .../aoplatform/DrawerWithFooter.tsx | 9 +- .../components/aoplatform/EditableTable.tsx | 74 ++- .../aoplatform/EditableTableWithModal.tsx | 12 +- .../src/components/aoplatform/GroupTree.tsx | 105 ---- .../src/components/aoplatform/InsidePage.tsx | 3 +- .../components/aoplatform/LanguageSetting.tsx | 48 ++ .../components/aoplatform/MemberTransfer.tsx | 17 +- .../aoplatform/MonacoEditorWrapper.tsx | 20 - .../src/components/aoplatform/Navigation.tsx | 100 --- .../src/components/aoplatform/PageList.tsx | 12 +- .../PublishApprovalModalContent.tsx | 159 +---- .../src/components/aoplatform/ResetPsw.tsx | 134 ---- .../SubscribeApprovalModalContent.tsx | 46 +- .../aoplatform/TableBtnWithPermission.tsx | 40 +- .../src/components/aoplatform/TimePicker.tsx | 16 - .../aoplatform/TimeRangeSelector.tsx | 11 +- .../aoplatform/TransferTable.module.css | 28 - .../components/aoplatform/TransferTable.tsx | 193 ------ .../src/components/aoplatform/UserAvatar.tsx | 120 ---- .../src/components/aoplatform/UserProfile.tsx | 152 ----- .../components/aoplatform/WithPermission.tsx | 5 +- .../CustomDialogComponent.tsx | 3 +- .../formily2-customize/SimpleMapComponent.tsx | 5 +- .../IntelligentPluginConfig.tsx | 30 +- .../IntelligentPluginList.tsx | 55 +- .../code-snippet/code-snippets.type.ts | 4 +- .../apispace/code-snippet/generate-code.ts | 5 +- .../apispace/code-snippet/index.tsx | 7 +- .../components/apispace/code-snippet/util.ts | 4 +- .../apispace/response-example/index.tsx | 11 +- .../common/src/components/postcat/ApiEdit.tsx | 18 +- .../src/components/postcat/ApiPreview.tsx | 21 +- .../ApiMessageBody/components/Binary.tsx | 3 +- .../components/ApiRequestEditor/index.tsx | 12 +- .../components/ApiResponseEditor/index.tsx | 7 +- .../components/MessageDataGrid/index.tsx | 30 +- .../ApiManager/components/UriInput/index.tsx | 3 +- .../components/ApiBasicInfoDisplay/index.tsx | 3 +- .../ApiPreview/components/ApiMatch/index.tsx | 9 +- .../ApiPreview/components/ApiProxy/index.tsx | 19 +- .../components/HeaderFields/index.tsx | 9 +- .../MessageBody/components/Binary.tsx | 2 +- .../components/MessageBody/index.tsx | 13 +- .../components/QueryFields/index.tsx | 9 +- .../ApiRequestTester/ImportMessage/index.tsx | 13 +- .../ApiRequestTester/TestBody/const.ts | 14 +- .../components/ApiRequestTester/index.tsx | 13 +- .../components/ResponseIndicator.tsx | 7 +- .../ApiTest/components/ApiResponse/index.tsx | 15 +- .../ApiTest/components/TestControl/index.tsx | 7 +- .../components/TestMessageDataGrid/index.tsx | 9 +- .../postcat/api/Clipboard/index.tsx | 3 +- .../components/postcat/api/Codebox/index.tsx | 12 +- .../postcat/api/Dialog/base-dialog.tsx | 6 +- .../api/MoreSetting/components/Example.tsx | 3 +- .../api/MoreSetting/components/ParamLimit.tsx | 7 +- .../MoreSetting/components/ParamPreview.tsx | 9 +- .../api/MoreSetting/components/ValueEnum.tsx | 11 +- .../postcat/api/MoreSetting/index.tsx | 11 +- .../components/postcat/api/Upload/index.tsx | 3 +- .../postcat/api/UploadButton/index.tsx | 5 +- .../common/src/const/api-detail/index.ts | 28 - .../common/src/const/approval/const.tsx | 246 +++++--- .../common/src/const/approval/type.tsx | 16 + .../packages/common/src/const/code/const.ts | 4 +- frontend/packages/common/src/const/const.ts | 20 - frontend/packages/common/src/const/const.tsx | 71 +++ frontend/packages/common/src/const/type.ts | 4 +- .../src/contexts/GlobalStateContext.tsx | 35 +- frontend/packages/common/src/hooks/copy.ts | 13 +- frontend/packages/common/src/hooks/excel.ts | 5 +- frontend/packages/common/src/locales/index.ts | 57 ++ .../common/src/locales/scan/en-GB.json | 570 ++++++++++++++++++ .../src/locales/scan/newJson/en-GB.json | 569 +++++++++++++++++ .../src/locales/scan/newJson/zh-CN.json | 569 +++++++++++++++++ .../common/src/locales/scan/zh-CN.json | 570 ++++++++++++++++++ frontend/packages/common/src/monacoConfig.ts | 1 - .../packages/common/src/utils/navigation.tsx | 4 +- .../common/src/utils/systemRunning.ts | 2 +- .../packages/common/src/utils/validate.ts | 3 +- frontend/packages/core/index.html | 4 +- frontend/packages/core/src/App.css | 18 +- frontend/packages/core/src/App.tsx | 24 +- .../components/aoplatform/RenderRoutes.tsx | 10 - .../packages/core/src/const/member/const.tsx | 19 +- .../core/src/const/partitions/const.tsx | 63 +- .../packages/core/src/const/role/const.tsx | 3 +- .../packages/core/src/const/system/const.tsx | 374 ++++++------ .../packages/core/src/const/system/type.ts | 4 +- .../packages/core/src/const/team/const.tsx | 53 +- .../packages/core/src/const/user/const.tsx | 13 +- frontend/packages/core/src/index.css | 11 +- frontend/packages/core/src/pages/Login.tsx | 21 +- .../core/src/pages/approval/ApprovalList.tsx | 36 +- .../core/src/pages/approval/ApprovalPage.tsx | 11 +- .../src/pages/auditLog/AuditLog.module.css | 8 - .../core/src/pages/auditLog/AuditLog.tsx | 308 ---------- .../packages/core/src/pages/email/Email.tsx | 136 ----- .../logRetrieval/LogRetrieval.module.css | 12 - .../src/pages/logRetrieval/LogRetrieval.tsx | 303 ---------- .../src/pages/logsettings/LogSettings.tsx | 11 +- .../logsettings/LogSettingsInstruction.tsx | 3 +- .../src/pages/member/MemberDropdownModal.tsx | 55 +- .../core/src/pages/member/MemberList.tsx | 69 +-- .../core/src/pages/member/MemberPage.tsx | 59 +- .../src/pages/member/Modal/AddDepModal.tsx | 23 +- .../member/Modal/AddToDepartmentModal.tsx | 21 +- .../src/pages/member/Modal/EditMember.tsx | 29 +- .../src/pages/member/Modal/RenameDepModal.tsx | 22 +- .../pages/partitions/PartitionInsideCert.tsx | 88 ++- .../partitions/PartitionInsideCluster.tsx | 19 +- .../partitions/PartitionInsideClusterNode.tsx | 27 +- .../resourcesettings/ResourceSettings.tsx | 7 +- .../core/src/pages/role/RoleConfig.tsx | 27 +- .../packages/core/src/pages/role/RoleList.tsx | 49 +- .../pages/serviceCategory/ServiceCategory.tsx | 41 +- .../ServiceHubCategoryConfig.tsx | 39 +- .../core/src/pages/system/SystemConfig.tsx | 89 +-- .../src/pages/system/SystemInsideDocument.tsx | 15 +- .../src/pages/system/SystemInsidePage.tsx | 9 +- .../pages/system/SystemInsideSubscriber.tsx | 64 +- .../core/src/pages/system/SystemList.tsx | 28 +- .../core/src/pages/system/SystemTopology.tsx | 9 +- .../system/api/SystemInsideApiCreate.tsx | 49 +- .../system/api/SystemInsideApiDetail.tsx | 17 +- .../system/api/SystemInsideApiDocument.tsx | 10 +- .../pages/system/api/SystemInsideApiList.tsx | 55 +- .../pages/system/api/SystemInsideApiProxy.tsx | 24 +- .../approval/SystemInsideApprovalList.tsx | 41 +- .../system/publish/SystemInsidePublish.tsx | 5 +- .../publish/SystemInsidePublishList.tsx | 106 ++-- .../publish/SystemInsidePublishOnline.tsx | 4 +- .../upstream/SystemInsideUpstreamContent.tsx | 65 +- .../core/src/pages/team/TeamConfig.tsx | 60 +- .../core/src/pages/team/TeamInsideMember.tsx | 68 +-- .../core/src/pages/team/TeamInsidePage.tsx | 8 +- .../packages/core/src/pages/team/TeamList.tsx | 55 +- .../core/src/pages/userProfile/ChangePsw.tsx | 23 +- .../src/pages/userProfile/UserProfile.tsx | 7 +- .../core/src/pages/webhook/Webhook.tsx | 391 ------------ frontend/packages/core/tsconfig.json | 2 +- 146 files changed, 4327 insertions(+), 3798 deletions(-) create mode 100644 frontend/i18next-scanner.config.js delete mode 100644 frontend/packages/common/src/components/aoplatform/DatePicker.tsx delete mode 100644 frontend/packages/common/src/components/aoplatform/GroupTree.tsx create mode 100644 frontend/packages/common/src/components/aoplatform/LanguageSetting.tsx delete mode 100644 frontend/packages/common/src/components/aoplatform/MonacoEditorWrapper.tsx delete mode 100644 frontend/packages/common/src/components/aoplatform/Navigation.tsx delete mode 100644 frontend/packages/common/src/components/aoplatform/ResetPsw.tsx delete mode 100644 frontend/packages/common/src/components/aoplatform/TimePicker.tsx delete mode 100644 frontend/packages/common/src/components/aoplatform/TransferTable.module.css delete mode 100644 frontend/packages/common/src/components/aoplatform/TransferTable.tsx delete mode 100644 frontend/packages/common/src/components/aoplatform/UserAvatar.tsx delete mode 100644 frontend/packages/common/src/components/aoplatform/UserProfile.tsx delete mode 100644 frontend/packages/common/src/const/const.ts create mode 100644 frontend/packages/common/src/const/const.tsx create mode 100644 frontend/packages/common/src/locales/index.ts create mode 100644 frontend/packages/common/src/locales/scan/en-GB.json create mode 100644 frontend/packages/common/src/locales/scan/newJson/en-GB.json create mode 100644 frontend/packages/common/src/locales/scan/newJson/zh-CN.json create mode 100644 frontend/packages/common/src/locales/scan/zh-CN.json delete mode 100644 frontend/packages/core/src/pages/auditLog/AuditLog.module.css delete mode 100644 frontend/packages/core/src/pages/auditLog/AuditLog.tsx delete mode 100644 frontend/packages/core/src/pages/email/Email.tsx delete mode 100644 frontend/packages/core/src/pages/logRetrieval/LogRetrieval.module.css delete mode 100644 frontend/packages/core/src/pages/logRetrieval/LogRetrieval.tsx delete mode 100644 frontend/packages/core/src/pages/webhook/Webhook.tsx diff --git a/frontend/i18next-scanner.config.js b/frontend/i18next-scanner.config.js new file mode 100644 index 00000000..9bcc8a4d --- /dev/null +++ b/frontend/i18next-scanner.config.js @@ -0,0 +1,68 @@ +const fs = require('fs'); +const { crc32 } = require('crc'); + +const systemLanguage = { + zh_CN: 'zh-CN', + en_GB: 'en-GB' +}; +// 读取已经存在在en.json文件的词条 +let existData = {}; +try { + console.log('Current working directory:', process.cwd()); + const existJsonData = fs.readFileSync('packages/common/src/locales/scan/en-GB.json'); + existData = JSON.parse(existJsonData); +} catch (error) { + if (error.code === 'ENOENT') { + console.warn('File not found: packages/common/src/locales/scan/en-GB.json. Creating an empty file.'); + fs.writeFileSync('packages/common/src/locales/scan/en-GB.json', JSON.stringify({})); + } else { + throw error; + } +} + +const keyList = Object.keys(existData); + +module.exports = { + input: [ + 'packages/*/src/**/*.{js,jsx,tsx,ts}', + // 不需要扫描的文件加! + '!packages/*/src/locales/**', + '!**/node_modules/**' + ], + output: 'packages/common/src/locales/scan', // 输出目录 + options: { + debug: true, + func: false, + trans: false, + lngs: [systemLanguage.zh_CN, systemLanguage.en_GB], + defaultLng: systemLanguage.zh_CN, + resource: { + loadPath: './newJson/{{lng}}.json', // 输入路径 (手动新建目录) + savePath: './newJson/{{lng}}.json', // 输出路径 (输出会根据输入路径内容自增, 不会覆盖已有的key) + jsonIndent: 2, + lineEnding: '\n' + }, + removeUnusedKeys: true, + nsSeparator: false, // namespace separator + keySeparator: false, // key separator + interpolation: { + prefix: '{{', + suffix: '}}' + } + }, + // 这里我们要实现将中文转换成crc格式, 通过crc格式key作为索引, 最终实现语言包的切换. + transform: function (file, enc, done) { + // 自己通过该函数来加工key或value + const { parser } = this; + const content = fs.readFileSync(file.path, enc); + parser.parseFuncFromString(content, { list: ['t'] }, (key, options) => { + options.defaultValue = key; + const hashKey = `K${crc32(key).toString(16)}`; // crc32转换格式 + // 如果词条不存在,则写入 + if (!keyList.includes(hashKey)) { + parser.set(hashKey, options); + } + }); + done(); + } +}; \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index 3ab17211..f16fd4b4 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -14,7 +14,8 @@ "serve:remotes": "lerna run serve --scope=remote --parallel", "dev": "lerna run dev --scope=core --stream", "dev:pro": "lerna run dev --scope=business-entry --stream", - "stop": "kill-port --port 5000,5001" + "stop": "kill-port --port 5000", + "scan":"i18next-scanner --config i18next-scanner.config.js" }, "keywords": [], "author": "", @@ -28,16 +29,19 @@ "@types/uuid": "^9.0.7", "@vitejs/plugin-react": "^4.2.0", "autoprefixer": "^10.4.16", + "crc": "^4.3.2", "dayjs": "^1.11.10", "dompurify": "^3.1.6", + "i18next": "^23.12.2", + "i18next-browser-languagedetector": "^8.0.0", "js-base64": "^3.7.5", - "moment": "^2.29.4", "postcss": "^8.4.31", "postcss-import": "^16.1.0", "postcss-nesting": "^12.1.5", "react": "^18.2.0", "react-ace": "^10.1.0", "react-dom": "^18.2.0", + "react-i18next": "^15.0.1", "react-router-dom": "^6.20.0", "tailwindcss": "^3.3.5", "uuid": "^9.0.1", @@ -64,6 +68,7 @@ "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.4", "file-saver": "^2.0.5", + "i18next-scanner": "^4.5.0", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "jest-fetch-mock": "^3.0.3", diff --git a/frontend/packages/common/src/components/aoplatform/BasicLayout.tsx b/frontend/packages/common/src/components/aoplatform/BasicLayout.tsx index 34c003a6..0d20a951 100644 --- a/frontend/packages/common/src/components/aoplatform/BasicLayout.tsx +++ b/frontend/packages/common/src/components/aoplatform/BasicLayout.tsx @@ -6,23 +6,26 @@ import { Button} from 'antd'; import Logo from '@common/assets/layout-logo.png'; import AvatarPic from '@common/assets/default-avatar.png' -import { routerKeyMap, TOTAL_MENU_ITEMS } from "./Navigation"; import {Outlet, useLocation, useNavigate} from "react-router-dom"; -import {useEffect, useMemo, useRef, useState} from "react"; +import { useEffect, useMemo, useState} from "react"; import { useGlobalContext } from '@common/contexts/GlobalStateContext.tsx'; import { PERMISSION_DEFINITION } from '@common/const/permissions.ts'; import { ProConfigProvider, ProLayout, } from '@ant-design/pro-components'; -import { UserProfile } from './UserProfile.tsx'; -import { ResetPsw, ResetPswHandle } from './ResetPsw.tsx'; -import { BasicResponse, STATUS_CODE } from '@common/const/const.ts'; -import { UserInfoType, UserProfileHandle } from '@common/const/type.ts'; +import { BasicResponse, RESPONSE_TIPS, routerKeyMap, STATUS_CODE } from '@common/const/const.tsx'; +import { UserInfoType } from '@common/const/type.ts'; import { useFetch } from '@common/hooks/http.ts'; -import { QuestionCircleOutlined } from '@ant-design/icons'; -import { Icon } from '@iconify/react/dist/iconify.js'; - +import { ProjectFilled } from '@ant-design/icons'; +import { getNavItem } from '@common/utils/navigation'; +import { Icon } from '@iconify/react'; +import { $t } from '@common/locales'; +import LanguageSetting from './LanguageSetting'; + +const APP_MODE = import.meta.env.VITE_APP_MODE; +export type MenuItem = Required['items'][number]; + const themeToken = { bgLayout:'#17163E;', header: { @@ -38,10 +41,46 @@ const themeToken = { const navigator = useNavigate() const location = useLocation() const currentUrl = location.pathname - const { accessData,checkPermission} = useGlobalContext() + const { state,accessData,checkPermission} = useGlobalContext() const [pathname, setPathname] = useState(currentUrl); const mainPage = project === 'core' ?'/service/list':'/serviceHub/list' + const TOTAL_MENU_ITEMS:MenuProps['items'] = useMemo(() => [ + getNavItem($t('工作空间'), 'workspace','/tenantManagement',, [ + getNavItem($t('我的'), 'my','/tenantManagement',null,[ + getNavItem({$t('应用')}, 'tenantManagement','/tenantManagement',,undefined,undefined,''), + getNavItem({$t('服务')}, 'service','/service',,undefined,undefined,''), + getNavItem({$t('团队')}, 'team','/team',,undefined,undefined,''), + ],undefined,''), + getNavItem({$t('API 市场')}, 'serviceHub','/serviceHub',,undefined,undefined,'system.workspace.api_market.view'), + ]), + + APP_MODE === 'pro' ? getNavItem($t('仪表盘'), 'mainPage', '/dashboard',,[ + getNavItem({$t('运行视图')}, 'dashboard','/dashboard',,undefined,undefined,''), + getNavItem({$t('系统拓扑图')}, 'systemrunning','/systemrunning',,undefined,undefined,''), + ]):null, + + getNavItem($t('系统设置'), 'operationCenter','/member',, [ + getNavItem($t('组织'), 'organization','/member',null,[ + getNavItem({$t('成员')}, 'member','/member',,undefined,undefined,'system.organization.member.view'), + getNavItem({$t('角色')}, 'role','/role',,undefined,undefined,'system.organization.role.view'), + ],undefined,''), + getNavItem($t('API 市场'), 'serviceHubSetting','/servicecategories',null,[ + getNavItem({$t('服务分类管理')}, 'servicecategories','/servicecategories',,undefined,undefined,'system.api_market.service_classification.view'), + ],undefined,'system.api_market.service_classification.view'), + + getNavItem($t('运维与集成'), 'maintenanceCenter','/cluster', null, [ + getNavItem({$t('集群')}, 'cluster','/cluster',,undefined,undefined,'system.devops.cluster.view'), + getNavItem({$t('证书')}, 'cert','/cert',,undefined,undefined,'system.devops.ssl_certificate.view'), + getNavItem({$t('日志')}, 'logsettings','/logsettings',,undefined,undefined,'system.devops.log_configuration.view'), + APP_MODE === 'pro' ? getNavItem({$t('资源')}, 'resourcesettings','/resourcesettings',null,undefined,undefined,'system.partition.self.view'):null, + APP_MODE === 'pro' ? getNavItem({$t('Open API')}, 'openapi','/openapi',null,undefined,undefined,'system.openapi.self.view'):null, + ]), + ]), + ],[state.language]) + + useEffect(()=>{console.log(state.language, $t('工作空间'))},[state.language]) + useEffect(() => { if(currentUrl === '/'){ navigator(mainPage) @@ -82,13 +121,13 @@ const themeToken = { const res = [...TOTAL_MENU_ITEMS]!.filter(x => x).map((x: any) => (x.routes ? { ...x, routes: filterMenu(x.routes) } : x)); // 返回处理后的数据 return { path: '/', routes: res.map(x=> ({...x, routes: x.routes?.filter(x=> (x.access || x.routes?.length > 0))})).filter(x=> (x.access || x.routes?.length > 0)) }; - }, [accessData]); + }, [accessData, state.language]); + - const { modal,message } = App.useApp() + + const { message } = App.useApp() const { dispatch,resetAccess,getGlobalAccessData} = useGlobalContext() const [userInfo,setUserInfo] = useState() - const resetPswRef = useRef(null) - const userProfileRef = useRef(null) const {fetchData} = useFetch() const navigate = useNavigate(); @@ -100,7 +139,7 @@ const themeToken = { setUserInfo(data.profile) dispatch({type:'UPDATE_USERDATA',userData:data.profile}) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }) } @@ -116,10 +155,10 @@ const themeToken = { if(code === STATUS_CODE.SUCCESS){ dispatch({type:'LOGOUT'}) resetAccess() - message.success(msg || '退出成功,将跳转至登录页') + message.success(msg || RESPONSE_TIPS.logoutSuccess) navigate('/login') }else{ - message.error(msg ||'操作失败') + message.error(msg ||RESPONSE_TIPS.error) } }) } @@ -129,49 +168,19 @@ const themeToken = { key: '2', label: ( ) }, { key: '3', label: ( ) }, ]; - const openModal = (type:'userSetting'|'resetPsw')=>{ - let title:string = '' - let content:string|React.ReactNode = '' - switch (type){ - case 'userSetting': - title='用户设置' - content= - break; - case 'resetPsw': - title='重置密码' - content= - break; - } - modal.confirm({ - title, - content, - onOk:()=>{ - switch (type){ - case 'userSetting': - return userProfileRef.current?.save().then((res)=>{if(res === true) getUserInfo()}) - case 'resetPsw': - return resetPswRef.current?.save().then((res)=>{if(res === true) logOut()}) - } - }, - width:600, - okText:'确认', - cancelText:'取消', - closable:true, - icon:<>, - }) - } + return(
- { - return document.getElementById('test-pro-layout') || document.body; - }} - > - { - return ( - -
{dom} -
-
- ); - }, - }} - actionsRender={(props) => { - if (props.isMobile) return []; - if (typeof window === 'undefined') return []; - return [ - - ]; - }} - headerTitleRender={() => ( -
- navigator(mainPage)} - /> -
- )} - logo={Logo} - pageTitleRender={()=>'APIPark - 企业API数据开放平台'} - menuFooterRender={(props) => { - if (props?.collapsed) return undefined; - }} - menuItemRender={(item, dom) => ( -
{ - // 同级目录点击无效 - if(item.key && routerKeyMap.get(item.key) && routerKeyMap.get(item.key).length > 0 && routerKeyMap.get(item.key)?.indexOf(pathname.split('/')[1]) !== -1){ - return - } - if(item.key === pathname.split('/')[1]){ - return - } - - if(item.path){ - navigator(item.path) - } - setPathname(item.path || ''); + { + return document.getElementById('test-pro-layout') || document.body; }} - > - {dom} -
- )} - fixSiderbar={true} - layout='mix' - splitMenus={true} - collapsed={false} - collapsedButtonRender={false} > -
- -
-
-
+ { + return ( + +
{dom} +
+
+ ); + }, + }} + actionsRender={(props) => { + if (props.isMobile) return []; + if (typeof window === 'undefined') return []; + return [ + , + + ]; + }} + headerTitleRender={() => ( +
+ navigator(mainPage)} + /> +
+ )} + logo={Logo} + pageTitleRender={()=>$t('APIPark - 企业API数据开放平台')} + menuFooterRender={(props) => { + if (props?.collapsed) return undefined; + }} + menuItemRender={(item, dom) => ( +
{ + // 同级目录点击无效 + if(item.key && routerKeyMap.get(item.key) && routerKeyMap.get(item.key).length > 0 && routerKeyMap.get(item.key)?.indexOf(pathname.split('/')[1]) !== -1){ + return + } + if(item.key === pathname.split('/')[1]){ + return + } + + if(item.path){ + navigator(item.path) + } + setPathname(item.path || ''); + }} + > + {dom} +
+ )} + fixSiderbar={true} + layout='mix' + splitMenus={true} + collapsed={false} + collapsedButtonRender={false} + > +
+ +
+
+
) diff --git a/frontend/packages/common/src/components/aoplatform/CodePage.tsx b/frontend/packages/common/src/components/aoplatform/CodePage.tsx index 15794b97..e0061adf 100644 --- a/frontend/packages/common/src/components/aoplatform/CodePage.tsx +++ b/frontend/packages/common/src/components/aoplatform/CodePage.tsx @@ -1,6 +1,7 @@ import { FC } from 'react'; import { Table } from 'antd'; import type { ColumnsType } from 'antd/es/table'; +import { $t } from '@common/locales'; interface DataType { httpStatusCode: string; @@ -11,17 +12,17 @@ interface DataType { const columns: ColumnsType = [ { - title: 'HTTP 状态码', + title:$t('HTTP 状态码'), dataIndex: 'httpStatusCode', key: 'httpStatusCode', }, { - title: '系统状态码', + title:$t('系统状态码'), dataIndex: 'systemStatusCode', key: 'systemStatusCode', }, { - title: '描述', + title: $t('描述'), dataIndex: 'description', key: 'description', ellipsis:true diff --git a/frontend/packages/common/src/components/aoplatform/DatePicker.tsx b/frontend/packages/common/src/components/aoplatform/DatePicker.tsx deleted file mode 100644 index 27b61113..00000000 --- a/frontend/packages/common/src/components/aoplatform/DatePicker.tsx +++ /dev/null @@ -1,8 +0,0 @@ - -import { DatePicker } from 'antd'; -import type { Moment } from 'moment'; -import momentGenerateConfig from 'rc-picker/lib/generate/moment'; - -const MyDatePicker = DatePicker.generatePicker(momentGenerateConfig); - -export default MyDatePicker; \ No newline at end of file diff --git a/frontend/packages/common/src/components/aoplatform/DrawerWithFooter.tsx b/frontend/packages/common/src/components/aoplatform/DrawerWithFooter.tsx index bc392c79..8b3885e6 100644 --- a/frontend/packages/common/src/components/aoplatform/DrawerWithFooter.tsx +++ b/frontend/packages/common/src/components/aoplatform/DrawerWithFooter.tsx @@ -2,6 +2,7 @@ import { Button, Drawer, DrawerProps, Space } from "antd"; import WithPermission from "./WithPermission"; import { useEffect, useState } from "react"; +import { $t } from '@common/locales'; export type DrawerWithFooterProps = DrawerProps & { onSubmit?: () => Promise|undefined @@ -17,7 +18,7 @@ export type DrawerWithFooterProps = DrawerProps & { cancelBtnTitle?:string } export function DrawerWithFooter(props:DrawerWithFooterProps){ - const {children,title,placement='right',onClose,onSubmit,submitDisabled = false,okBtnTitle='提交',cancelBtnTitle,open,submitAccess,showLastStep,onLastStep,notAutoClose,showOkBtn=true,extraBtn} = props + const {children,title,placement='right',onClose,onSubmit,submitDisabled = false,okBtnTitle= $t('提交'),cancelBtnTitle,open,submitAccess,showLastStep,onLastStep,notAutoClose,showOkBtn=true,extraBtn} = props const [submitLoading, setSubmitLoading] = useState(false) const handlerSubmit = ()=>{ setSubmitLoading(true) @@ -41,12 +42,12 @@ export function DrawerWithFooter(props:DrawerWithFooterProps){ {showOkBtn && } - { showLastStep && } + { showLastStep && } { extraBtn } - + } onClose={onClose} diff --git a/frontend/packages/common/src/components/aoplatform/EditableTable.tsx b/frontend/packages/common/src/components/aoplatform/EditableTable.tsx index d951cedc..6479420a 100644 --- a/frontend/packages/common/src/components/aoplatform/EditableTable.tsx +++ b/frontend/packages/common/src/components/aoplatform/EditableTable.tsx @@ -1,11 +1,14 @@ -import { EditableProTable, ProColumns } from "@ant-design/pro-components"; +import { EditableProTable } from "@ant-design/pro-components"; import { Button } from "antd"; import { useState, useEffect } from "react"; import { v4 as uuidv4} from 'uuid'; import WithPermission from "./WithPermission"; +import { PageProColumns } from "./PageList"; +import { Icon } from "@iconify/react/dist/iconify.js"; +import TableBtnWithPermission from "./TableBtnWithPermission"; interface EditableTableProps { - configFields: ProColumns[]; + configFields: PageProColumns[]; value?: T[]; // 外部传入的值 className?: string; onChange?: (newConfigItems: T[]) => void; // 当配置项变化时,外部传入的回调函数 @@ -54,43 +57,36 @@ const EditableTable = ({ editableKeys:disabled ? [] : configurations?.map(x=>x._id), actionRender: (row, config) => { return [ - , - (config.index !== configurations.length - 1 )&& , + { + const newId = uuidv4(); + setConfigurations((prev)=>{ + const tmpPreData = [...prev]; + const newId = uuidv4() + const lastRecord:{[k:string]:unknown} = tmpPreData[tmpPreData.length - 1]; + const newRecord :{[k:string]:unknown, _id:string}= { _id: newId }; + + // 当extendsId的长度大于0时,根据extendsId指定的字段从最后一个record中复制值 + if(extendsId && extendsId.length > 0) { + extendsId.forEach(field => { + newRecord[field] = lastRecord[field]; + }); + } + tmpPreData.splice(Number(config.index) + 1, 0,newRecord); + onChange?.(getNotEmptyValue(tmpPreData)); + return tmpPreData}); + setEditableRowKeys((prev)=>([...prev,newId])) + }} + btnTitle="增加"/>, + + (config.index !== configurations.length - 1 )&& { + setConfigurations((prev)=>{ + const tmpPreData = [...prev]; + tmpPreData.splice(Number(config.index), 1); + onChange?.(tmpPreData); + return tmpPreData}); + setEditableRowKeys((prev)=>(prev.filter(x=>x !== config._id))) + }}/>,, ]; }, onValuesChange: (record, recordList) => { diff --git a/frontend/packages/common/src/components/aoplatform/EditableTableWithModal.tsx b/frontend/packages/common/src/components/aoplatform/EditableTableWithModal.tsx index 734d2eb3..21869652 100644 --- a/frontend/packages/common/src/components/aoplatform/EditableTableWithModal.tsx +++ b/frontend/packages/common/src/components/aoplatform/EditableTableWithModal.tsx @@ -3,6 +3,8 @@ import { Button, Modal, Form, Table, FormInstance, TableProps, Divider } from 'a import { v4 as uuidv4 } from 'uuid'; import { ColumnsType } from 'antd/es/table'; import WithPermission from './WithPermission'; +import { $t } from '@common/locales'; +import { COLUMNS_TITLE, VALIDATE_MESSAGE } from '@common/const/const'; export interface ConfigField { title: string; @@ -90,9 +92,9 @@ const EditableTableWithModal = ({ })); !disabled && columns.push({ - title: '操作', + title: COLUMNS_TITLE.operate, key: 'action', - width:117, + btnNums:2, render: (_: unknown, record: T) => ( <>
@@ -109,7 +111,7 @@ const EditableTableWithModal = ({ {component} @@ -119,12 +121,12 @@ const EditableTableWithModal = ({ return ( <> - {!disabled && } + {!disabled && } {configurations.length > 0 && } MenuProps['items'] - withMore?:boolean - onEditGroup:(type:'rename'|'addChild'|'addPeer', entity:DataNode & T, val:string) => Promise|undefined - placeholder?:string -} - -export interface GroupTreeHandle { - startEdit:(id:string)=>void; - startAdd:(type:'peer',entity?:DataNode & T)=>void -} - -const GroupTree = forwardRef((props, ref)=>{ - const {groupData,selectedKeys,onSelect,addBtnName,addBtnAccess,treeNameSuffixKey,dropdownMenu,onEditGroup,placeholder="输入以搜索"} = props - const [treeData, setTreeData] = useState([]) - const [searchWord, setSearchWord] = useState('') - const [editingId, setEditingId] = useState('') - const [addStatus, setAddStatus] = useState(false) - - useImperativeHandle(ref, ()=>({ - startEdit:setEditingId, - startAdd:handlerAction - })) - - const handlerAction = (type:'peer')=>{ - if(type === 'peer'){ - setAddStatus(true) - setEditingId(uuidv4()) - } - } - - const getTreeData = (rawData?:DataNode[])=>{ - const loop = (data: DataNode[]): DataNode[] =>{ - const newData = [...data,...(addStatus? [{title:'',key:editingId,id:editingId}]:[])] - return newData.map((item) => { - const strTitle = item.title as string; - const index = strTitle.indexOf(searchWord); - const beforeStr = strTitle.substring(0, index); - const afterStr = strTitle.slice(index + searchWord.length); - const title = - index > -1 ? ( - - {beforeStr} - {searchWord} - {afterStr} {treeNameSuffixKey && ({item?.[treeNameSuffixKey as keyof DataNode] as string ?? 0})} - ) : ( - {strTitle}{treeNameSuffixKey && ({item?.[treeNameSuffixKey as keyof DataNode] as string?? 0})} - ) - return { - title:{setAddStatus(false);setEditingId('')}} editable editingId={editingId} entity={item} afterEdit={(val)=>onEditGroup?.(addStatus && editingId === item.key ? 'addPeer':'rename',item, val)?.then((res)=>{res && setEditingId('') ;res && setAddStatus(false) ; return res})}>{title}, - key: item.key, - id:item.key - }; - }) - }; - return rawData ? loop(rawData) :[]; - } - - - const onSearchWordChange = (e:string)=>{ - setSearchWord(e || '') - } - - useEffect(()=>{ - const n = getTreeData(groupData) - setTreeData(n) - },[groupData,editingId,searchWord]) - - return ( - <> - debounce(onSearchWordChange, 100)(e.target.value)} - allowClear placeholder={placeholder} - prefix={ }/> -
- } - blockNode={true} - treeData={treeData} - selectedKeys={selectedKeys} - onSelect={onSelect} - /> -
- {addBtnName && } - - ) -}) - -export default GroupTree \ No newline at end of file diff --git a/frontend/packages/common/src/components/aoplatform/InsidePage.tsx b/frontend/packages/common/src/components/aoplatform/InsidePage.tsx index 54fa5a14..669a8bda 100644 --- a/frontend/packages/common/src/components/aoplatform/InsidePage.tsx +++ b/frontend/packages/common/src/components/aoplatform/InsidePage.tsx @@ -4,6 +4,7 @@ import {useNavigate} from "react-router-dom"; import WithPermission from "@common/components/aoplatform/WithPermission"; import { FC, ReactNode } from "react"; import { ArrowLeftOutlined, LeftOutlined } from "@ant-design/icons"; +import { $t } from "@common/locales"; class InsidePageProps { @@ -36,7 +37,7 @@ const InsidePage:FC = ({showBanner=true,pageTitle,tagList,showB { showBanner &&
{backUrl &&
- +
}
diff --git a/frontend/packages/common/src/components/aoplatform/LanguageSetting.tsx b/frontend/packages/common/src/components/aoplatform/LanguageSetting.tsx new file mode 100644 index 00000000..cf329c0c --- /dev/null +++ b/frontend/packages/common/src/components/aoplatform/LanguageSetting.tsx @@ -0,0 +1,48 @@ +import { Dropdown, Row, Col, Button } from 'antd'; +import i18n from '@common/locales'; +import { $t } from '@common/locales'; +import { memo } from 'react'; +import { useGlobalContext } from '@common/contexts/GlobalStateContext'; +import { Icon } from '@iconify/react/dist/iconify.js'; + +const LanguageSetting = () => { + const { dispatch,state} = useGlobalContext() + const items = [ + { + key: 'cn', + label: , + title: $t('简体'), + }, + { + key: 'en', + label:, + title:$t('英文') + } + ]; + + const langLabel = items.find((item) => item?.key === state.language)?.title; + return ( + { + const { key } = e; + dispatch({ type: 'UPDATE_LANGUAGE', language: key }); + i18n.changeLanguage(key); + } + }} + > + + + ); +}; +export default memo(LanguageSetting); + diff --git a/frontend/packages/common/src/components/aoplatform/MemberTransfer.tsx b/frontend/packages/common/src/components/aoplatform/MemberTransfer.tsx index ee7e81ef..ef3acd31 100644 --- a/frontend/packages/common/src/components/aoplatform/MemberTransfer.tsx +++ b/frontend/packages/common/src/components/aoplatform/MemberTransfer.tsx @@ -2,12 +2,27 @@ import { GetProp, TransferProps, TreeDataNode, theme, Transfer, Tree, Spin } from "antd"; import { DataNode, TreeProps } from "antd/es/tree"; import { Ref, forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react"; -import { TransferTableHandle, TransferTableProps } from "./TransferTable"; import { ApartmentOutlined, LoadingOutlined, UserOutlined } from "@ant-design/icons"; import { debounce } from "lodash-es"; +import { ColumnsType } from "antd/es/table"; type TransferItem = GetProp[number]; +export type TransferTableProps = { + request?:(k?:string)=>Promise<{data:T[],success:boolean}> + columns: ColumnsType + primaryKey:string + onSelect:(selectedData:T[])=>void + tableType?:'member'|'api' + disabledData:string[] + searchPlaceholder?:string +} + +export type TransferTableHandle = { + selectedData: () => T[]; + selectedRowKeys: () => React.Key[]; +} + interface TreeTransferProps { dataSource: TreeDataNode[]; targetKeys: TransferProps['targetKeys']; diff --git a/frontend/packages/common/src/components/aoplatform/MonacoEditorWrapper.tsx b/frontend/packages/common/src/components/aoplatform/MonacoEditorWrapper.tsx deleted file mode 100644 index 911e47cc..00000000 --- a/frontend/packages/common/src/components/aoplatform/MonacoEditorWrapper.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { useEffect } from "react"; -import { editor } from "monaco-editor"; -import useInitializeMonaco from "@common/hooks/useInitializeMonaco"; -import { Editor, useMonaco } from '@monaco-editor/react' - -export type MonacoEditorRefType = editor.IStandaloneCodeEditor; -const MonacoEditorWrapper: React.FC = (props) => { - useInitializeMonaco(); - const monacoInstance = useMonaco(); - - useEffect(() => { - if (monacoInstance) { - // 在这里你可以访问并配置Monaco实例 - } - }, [monacoInstance]); - - return ; -}; - -export default MonacoEditorWrapper; \ No newline at end of file diff --git a/frontend/packages/common/src/components/aoplatform/Navigation.tsx b/frontend/packages/common/src/components/aoplatform/Navigation.tsx deleted file mode 100644 index afd18c5c..00000000 --- a/frontend/packages/common/src/components/aoplatform/Navigation.tsx +++ /dev/null @@ -1,100 +0,0 @@ - -import {FC, useEffect, useMemo, useState} from 'react'; -import type { MenuProps } from 'antd'; -import { Menu } from 'antd'; -import { useLocation, useNavigate} from "react-router-dom"; -import { getNavItem } from '@common/utils/navigation'; -import { PERMISSION_DEFINITION } from '@common/const/permissions'; -import { useGlobalContext } from '@common/contexts/GlobalStateContext'; -import { ProjectFilled } from '@ant-design/icons'; -import { Icon } from '@iconify/react'; -export type MenuItem = Required['items'][number]; - -const APP_MODE = import.meta.env.VITE_APP_MODE; - -// avoid changing route within ths same category -export const routerKeyMap = new Map([ - ['workspace',['tenantManagement','service','team','serviceHub']], - ['my',['tenantManagement','service','team']], - ['mainPage',['dashboard','systemrunning']], - ['operationCenter',['member','user','role','servicecategories']], - ['organization',['member','user','role']], - ['serviceHubSetting',['servicecategories']], - ['maintenanceCenter',['partition','logsettings','resourcesettings','openapi'] -]]) - - -export const TOTAL_MENU_ITEMS: MenuProps['items'] = [ - - getNavItem('工作空间', 'workspace','/tenantManagement',, [ - getNavItem('我的', 'my','/tenantManagement',null,[ - getNavItem(应用, 'tenantManagement','/tenantManagement',,undefined,undefined,''), - getNavItem(服务, 'service','/service',,undefined,undefined,''), - getNavItem(团队, 'team','/team',,undefined,undefined,''), - ],undefined,''), - getNavItem(API 市场, 'serviceHub','/serviceHub',,undefined,undefined,'system.workspace.api_market.view'), - ]), - - - APP_MODE === 'pro' ? getNavItem('仪表盘', 'mainPage', '/dashboard',,[ - getNavItem(运行视图, 'dashboard','/dashboard',,undefined,undefined,''), - getNavItem(系统拓扑图, 'systemrunning','/systemrunning',,undefined,undefined,''), - ]):null, - - getNavItem('系统设置', 'operationCenter','/member',, [ - getNavItem('组织', 'organization','/member',null,[ - getNavItem(成员, 'member','/member',,undefined,undefined,'system.organization.member.view'), - getNavItem(角色, 'role','/role',,undefined,undefined,'system.organization.role.view'), - ],undefined,''), - getNavItem('API 市场', 'serviceHubSetting','/servicecategories',null,[ - getNavItem(服务分类管理, 'servicecategories','/servicecategories',,undefined,undefined,'system.api_market.service_classification.view'), - ],undefined,'system.api_market.service_classification.view'), - - getNavItem('运维与集成', 'maintenanceCenter','/cluster', null, [ - getNavItem(集群, 'cluster','/cluster',,undefined,undefined,'system.devops.cluster.view'), - getNavItem(证书, 'cert','/cert',,undefined,undefined,'system.devops.ssl_certificate.view'), - getNavItem(日志, 'logsettings','/logsettings',,undefined,undefined,'system.devops.log_configuration.view'), - APP_MODE === 'pro' ? getNavItem(资源, 'resourcesettings','/resourcesettings',null,undefined,undefined,'system.partition.self.view'):null, - APP_MODE === 'pro' ? getNavItem(Open API, 'openapi','/openapi',null,undefined,undefined,'system.openapi.self.view'):null, - ]), - ]), -]; - -const Navigation: FC = () => { - const location = useLocation() - const [selectedKeys, setSelectedKeys] = useState('') - const currentUrl = location.pathname - const navigateTo = useNavigate() - const { accessData,checkPermission} = useGlobalContext() - - const onClick: MenuProps['onClick'] = (e) => { - if(location.pathname.split('/')[1] === e.key) return - const newUrl = routerKeyMap.get(e.key) - newUrl && navigateTo(newUrl) - }; - - const menuData = useMemo(()=>{ - const filterMenu = (menu:Array<{[k:string]:unknown}>)=>{ - return menu.filter(x=> x && (x.access ? checkPermission(x.access as keyof typeof PERMISSION_DEFINITION[0]): true)) - } - return TOTAL_MENU_ITEMS!.filter(x=>x).map((x)=> ( x.children ? {...x, children:filterMenu(x.children)} : x))?.filter(x=> x.key === 'service' || (x.children && x.children?.length > 0)) -},[accessData]) - - useEffect(() => { - setSelectedKeys(currentUrl.split('/')[1] === 'template' ? currentUrl.split('/')[2] : currentUrl.split('/')[1]) - }, [currentUrl]); - - return ( - - ); -}; - -export default Navigation; \ No newline at end of file diff --git a/frontend/packages/common/src/components/aoplatform/PageList.tsx b/frontend/packages/common/src/components/aoplatform/PageList.tsx index 7ea5b927..cd52353b 100644 --- a/frontend/packages/common/src/components/aoplatform/PageList.tsx +++ b/frontend/packages/common/src/components/aoplatform/PageList.tsx @@ -15,9 +15,11 @@ import { useGlobalContext } from '../../contexts/GlobalStateContext'; import { PERMISSION_DEFINITION } from '@common/const/permissions'; import { withMinimumDelay } from '@common/utils/ux'; +export type PageProColumns = ProColumns & {btnNums? : number} + interface PageListProps extends ProTableProps, RefAttributes { id?:string - columns: ProColumns[] + columns: PageProColumns[] request?:(params: (ParamsType & {pageSize?: number | undefined, current?: number | undefined, keyword?: string | undefined}), sorter: unknown, filter: unknown)=>Promise<{data:T[], success:boolean}> dropMenu?:MenuProps searchPlaceholder?:string @@ -49,6 +51,7 @@ interface PageListProps extends ProTableProps, RefAttributes>(props: React.PropsWithChildren>,ref: React.Ref) => { const {id,columns,request,dropMenu,searchPlaceholder,showPagination=true,primaryKey='id',addNewBtnTitle,addNewBtnAccess,tableClickAccess,tableClass,onAddNewBtnClick,beforeSearchNode,onSearchWordChange,manualReloadTable,afterNewBtn,dragSortKey,onDragSortEnd,tableTitle,rowSelection,onChange,dataSource,onRowClick,showColSetting=false,minVirtualHeight,noTop,addNewBtnWrapperClass,tableTitleClass,delayLoading = true,besidesTableHeight, noScroll} = props const parentRef = useRef(null); @@ -79,7 +82,6 @@ const PageList = >(props: React.PropsWithChild const res = parentRef.current.getBoundingClientRect(); const height = res.height - ((noTop ? 0 : 59) + 54 + (showPagination && !dragSortKey ? 52 : 0) +( besidesTableHeight ?? 0) + 1); // 减去顶部按钮、底部分页、表头高度 setTableWidth(minTableWidth - 5> res.width ? minTableWidth : undefined); - console.log(minTableWidth,res.width ) height && setTableHeight(minVirtualHeight === undefined ? height : (height > minVirtualHeight ? height : minVirtualHeight)); } }; @@ -114,7 +116,6 @@ const PageList = >(props: React.PropsWithChild let width:number = 0 const res = columns?.map( (x, index)=>{ - width += Number(x.width ?? ((x.filters || x.sorter) ? 120 : 100)) const sorter = localStorage.getItem(`${id}_sorter`) const filters = localStorage.getItem(`${id}_filters`) x.copyable = x.copyable ?? (index === 0 || x.dataIndex === 'id' || x.dataIndex === 'email') @@ -129,6 +130,11 @@ const PageList = >(props: React.PropsWithChild const xName = Array.isArray(x.dataIndex) ? x.dataIndex.join(','):x.dataIndex x.defaultFilteredValue = filtersObj?.[xName as string] } + if((index === columns.length -1 || x.key === 'option') && x.btnNums){ + const optionWidth = 24 + 18 * x.btnNums + (x.btnNums - 1) * 21 + x.width = Math.max(optionWidth, 54) + } + width += Number(x.width ?? ((x.filters || x.sorter) ? 120 : 100)) return x}) setMinTableWidth(width) return res diff --git a/frontend/packages/common/src/components/aoplatform/PublishApprovalModalContent.tsx b/frontend/packages/common/src/components/aoplatform/PublishApprovalModalContent.tsx index 2128cc7a..15eea8a2 100644 --- a/frontend/packages/common/src/components/aoplatform/PublishApprovalModalContent.tsx +++ b/frontend/packages/common/src/components/aoplatform/PublishApprovalModalContent.tsx @@ -1,106 +1,13 @@ -import {App, Col, Form, Input, Row, Table, Tooltip} from "antd"; +import {App, Col, Form, Input, Row, Table} from "antd"; import {forwardRef, useEffect, useImperativeHandle} from "react"; -import {PublishApprovalInfoType, PublishVersionTableListItem} from "@common/const/approval/type.tsx"; +import {PublishApprovalInfoType, PublishApprovalModalHandle, PublishApprovalModalProps, PublishVersionTableListItem} from "@common/const/approval/type.tsx"; import {useFetch} from "@common/hooks/http.ts"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, FORM_ERROR_TIPS, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE, VALIDATE_MESSAGE} from "@common/const/const.tsx"; import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; import { SYSTEM_PUBLISH_ONLINE_COLUMNS } from "@core/const/system/const.tsx"; -import { SystemInsidePublishOnlineItems } from "@core/pages/system/publish/SystemInsidePublishOnline.tsx"; +import { $t } from "@common/locales"; +import { ApprovalApiColumns, ApprovalUpstreamColumns } from "@common/const/approval/const"; -enum ChangeTypeEnum { - 'new' = '新增', - 'update' = '变更', - 'delete' = '删除', - 'none' = '无变更', - 'error' = '缺失字段' -} - -const statusColorClass = { - new: 'text-[#138913]', // 使用 Tailwind 的 Arbitrary Properties - update: 'text-[#03a9f4]', - delete: 'text-[#ff3b30]', - none: 'text-[var(--MAIN_TEXT)]', // 假设你也有一个“none”的状态 - }; - -const apiColumns = [ - { - title:'API 名称', - dataIndex:'name', - ellipsis:true - }, - { - title:'请求方式', - dataIndex:'method', - ellipsis:true - }, - { - title:'路径', - dataIndex:'path', - ellipsis:true - }, - { - title:'类型', - dataIndex:'change', - render:(_,entity)=>( - - - {ChangeTypeEnum[entity.change as (keyof typeof ChangeTypeEnum)] || '-'} - {entity.change === 'error' ?` 该 API 缺失 ${entity.proxyStatus == 1 && '转发信息,'} ${entity.docStatus == 1 && '文档信息,'} ${entity.upstreamStatus == 1 && '上游信息,'}请先补充`:''} - - ) - - } -] - -const upstreamColumns = [ - { - title:'上游类型', - dataIndex:'type', - ellipsis:true, - // filters: true, - // onFilter: true, - // valueType: 'select', - // filterSearch: true, - valueEnum:{ - 'static':{ - text:'静态上游' - }, - // 'dynamic':{ - // text:'动态上游' - // } - } - }, - { - title:'地址', - dataIndex:'addr', - render:(text:string[])=>(<>{text.join(',')}), - ellipsis:true - }, - { - title:'类型', - dataIndex:'change', - render:(_,entity)=>( - - {ChangeTypeEnum[entity.change as (keyof typeof ChangeTypeEnum)] || '-'} - {entity.change === 'error' ?` 该 API 缺失 ${entity.proxyStatus == 1 && '转发信息,'} ${entity.docStatus == 1 && '文档信息,'} ${entity.upstreamStatus == 1 && '上游信息,'}请先补充`:''} - ) - } -] - -type PublishApprovalModalProps = { - type:'approval'|'view'|'add'|'publish'|'online' - data:PublishApprovalInfoType | PublishApprovalInfoType &{id?:string} | PublishVersionTableListItem - insideSystem?:boolean - serviceId:string - teamId:string - clusterPublishStatus?:SystemInsidePublishOnlineItems[] -} - -export type PublishApprovalModalHandle = { - save:(operate:'pass'|'refuse') =>Promise - publish:(notSave?:boolean)=>Promise> - online:()=>Promise -} export const PublishApprovalModalContent = forwardRef((props, ref) => { const { message } = App.useApp() @@ -115,19 +22,19 @@ export const PublishApprovalModalContent = forwardRef{ if(operate === 'refuse' && form.getFieldValue('opinion') === '' ){ form.setFields([{ - name:'opinion',errors:['选择拒绝时,审批意见为必填'] + name:'opinion',errors:[FORM_ERROR_TIPS.refuseOpinion] }]) form.scrollToField('opinion') - return Promise.reject('未填写审核意见') + return Promise.reject(RESPONSE_TIPS.refuseOpinion) } return fetchData>(`service/publish/${operate === 'pass' ? 'accept' : 'refuse'}`,{method: 'PUT',eoBody:({comments:value.opinion}), eoParams:{id:data!.id, project:serviceId},eoTransformKeys:['versionRemark']}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) return Promise.resolve(true) }else{ - message.error(msg || '操作失败') - return Promise.reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + return Promise.reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> Promise.reject(errorInfo)) }).catch((err)=> {form.scrollToField(err.errorFields[0].name[0]); return Promise.reject(err)}) @@ -141,11 +48,11 @@ export const PublishApprovalModalContent = forwardRef{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(response) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }).catch((errorInfo)=> reject(errorInfo)) @@ -158,11 +65,11 @@ export const PublishApprovalModalContent = forwardRef>('service/publish/execute',{method: 'PUT', eoParams:{project:serviceId,id:(data as PublishVersionTableListItem).flowId},eoTransformKeys:['versionRemark']}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }).catch((errorInfo)=> reject(errorInfo)) @@ -184,22 +91,22 @@ export const PublishApprovalModalContent = forwardRef {!insideSystem && <> -
申请系统: + {$t('申请系统')}:{(data as PublishApprovalInfoType).project || '-'} - 所属团队: + {$t('所属团队')}:{(data as PublishApprovalInfoType).team || '-'} - 申请人: + {$t('申请人')}:{(data as PublishApprovalInfoType).applier || '-'} - 申请时间: + {$t('申请时间')}:{(data as PublishApprovalInfoType).applyTime || '-'} } @@ -220,54 +127,54 @@ export const PublishApprovalModalContent = forwardRef - + - + } - API 列表: + {$t('API 列表')}:
- 上游列表: + {$t('上游列表')}:
- + {/* {type !== 'add' && type !== 'publish' && - { form.setFields([ + { form.setFields([ { name: 'opinion', errors: [], // 设置为空数组来移除错误信息 diff --git a/frontend/packages/common/src/components/aoplatform/ResetPsw.tsx b/frontend/packages/common/src/components/aoplatform/ResetPsw.tsx deleted file mode 100644 index f3eb8d32..00000000 --- a/frontend/packages/common/src/components/aoplatform/ResetPsw.tsx +++ /dev/null @@ -1,134 +0,0 @@ -import { Form, Input} from "antd"; -import {forwardRef, useEffect, useImperativeHandle} from "react"; -import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; -import { UserInfoType } from "@common/const/type.ts"; - -type FieldType = { - userName:string - old:string - password:string - confirm:string -} -type ResetPswProps = { - entity?:UserInfoType -} - -export type ResetPswHandle = { - save:()=>Promise -} - -export const ResetPsw = forwardRef((props,ref)=>{ - const [form] = Form.useForm(); - - const save:()=>Promise = ()=>{ - return new Promise((resolve)=>{ - // form.validateFields().then((value)=>{ - // fetchData>(url,{method,eoBody:(value), eoTransformKeys:['departmentIds']}).then(response=>{ - // const {code,msg} = response - // if(code === STATUS_CODE.SUCCESS){ - // message.success(msg || '操作成功!') - resolve(true) - // }else{ - // message.error(msg || '操作失败') - // reject(msg || '操作失败') - // } - // }) - // }).catch((errorInfo)=> reject(errorInfo)) - }) - } - - const getPswStrength = (value: string) => { - const pswRegNum: RegExp = /[0-9]/ - const pswRegLowercase: RegExp = /[a-z]/ - const pswRegUppercase: RegExp = /[A-Z]/ - const pswRegSymbol: RegExp = /!@#$%^&*`~()-+=/ - let strength: number = 0 - if (pswRegNum.test(value)) { - strength++ - } - if (pswRegLowercase.test(value)) { - strength++ - } - if (pswRegUppercase.test(value)) { - strength++ - } - if (pswRegSymbol.test(value)) { - strength++ - } - return strength - } - - useImperativeHandle(ref, ()=>({ - save - }) - ) - - useEffect(() => { - // form.setFieldsValue({id:entity!.id}) - }, []); - - return ( -
- - label="账号" - name="userName" - hidden - rules={[{ required: true, message: '必填项',whitespace:true }]} - > - -
- - - label="旧密码" - name="old" - rules={[{ required: true, message: '必填项',whitespace:true }]} - > - - - - - label="新密码" - name="password" - hidden - // eslint-disable-next-line @typescript-eslint/no-unused-vars - rules={[{ required: true, message: '必填项',whitespace:true }, ({ getFieldValue }) => ({ - validator(_, value) { - if (!value || getPswStrength(value)>1) { - return Promise.resolve(); - } - return Promise.reject(new Error('密码强度:弱,建议使用英文、数字、特殊字符组合')); - }, - })]} - > - - - - - label="确认新密码" - name="confirm" - dependencies={['password']} - rules={[{ required: true, message: '必填项',whitespace:true }, ({ getFieldValue }) => ({ - validator(_, value) { - if (!value || getFieldValue('password') === value) { - return Promise.resolve(); - } - return Promise.reject(new Error('新密码与确认新密码不一致')); - }, - })]} - > - - - - - ) -}) \ No newline at end of file diff --git a/frontend/packages/common/src/components/aoplatform/SubscribeApprovalModalContent.tsx b/frontend/packages/common/src/components/aoplatform/SubscribeApprovalModalContent.tsx index 9f994993..8433ac7f 100644 --- a/frontend/packages/common/src/components/aoplatform/SubscribeApprovalModalContent.tsx +++ b/frontend/packages/common/src/components/aoplatform/SubscribeApprovalModalContent.tsx @@ -1,9 +1,11 @@ -import {App, Checkbox, Col, Form, Input, Row} from "antd"; +import {App, Col, Form, Input, Row} from "antd"; import { forwardRef, useEffect, useImperativeHandle} from "react"; import {SubscribeApprovalInfoType} from "@common/const/approval/type.tsx"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, FORM_ERROR_TIPS, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; import {useFetch} from "@common/hooks/http.ts"; import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; +import { SubscribeApprovalList } from "@common/const/approval/const"; +import { $t } from "@common/locales"; type SubscribeApprovalModalProps = { type:'approval'|'view' @@ -22,26 +24,6 @@ type FieldType = { opinion?:string; }; -const list = [ - { - title:'申请方应用',key:'application' - }, - { - title:'申请方所属团队',key:'applyTeam' - }, - { - title:'申请人',key:'applier' - }, - { - title:'申请时间',key:'applyTime' - }, - { - title:'申请服务',key:'service' - }, - { - title:'服务所属团队',key:'team' - } -] export const SubscribeApprovalModalContent = forwardRef((props, ref) => { const { message } = App.useApp() const {data, type,inSystem=false, teamId, serviceId} = props @@ -57,20 +39,20 @@ export const SubscribeApprovalModalContent = forwardRef{ if(operate === 'refuse' && form.getFieldValue('opinion') === ''){ form.setFields([{ - name:'opinion',errors:['必填项'] + name:'opinion',errors:[FORM_ERROR_TIPS.refuseOpinion] }]) form.scrollToField('opinion') - reject('未填写审核意见') + reject(RESPONSE_TIPS.refuseOpinion) return } fetchData>(`${inSystem?'service/':''}approval/subscribe`,{method: 'POST',eoBody:({opinion:value.opinion,operate}), eoParams:(inSystem ? {apply:data!.id, team:teamId} : {id:data!.id,team:teamId})}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }).catch((errorInfo)=> reject(errorInfo)) @@ -88,7 +70,7 @@ export const SubscribeApprovalModalContent = forwardRef{ - list?.map((x)=>( + SubscribeApprovalList?.map((x)=>( {x.title}:{(data as {[k:string]:unknown})?.[x.key]?.name || (data as {[k:string]:unknown})?.[x.key] || '-'} @@ -109,17 +91,17 @@ export const SubscribeApprovalModalContent = forwardRef - label="申请原因" + label={$t("申请原因")} name="reason" > - label="审核意见" + label={$t("审核意见")} name="opinion" - extra="选择拒绝时,审批意见为必填" + extra={FORM_ERROR_TIPS.refuseOpinion} > - { form.setFields([ + { form.setFields([ { name: 'opinion', errors: [], // 设置为空数组来移除错误信息 diff --git a/frontend/packages/common/src/components/aoplatform/TableBtnWithPermission.tsx b/frontend/packages/common/src/components/aoplatform/TableBtnWithPermission.tsx index 4d0223d4..0a1dbf89 100644 --- a/frontend/packages/common/src/components/aoplatform/TableBtnWithPermission.tsx +++ b/frontend/packages/common/src/components/aoplatform/TableBtnWithPermission.tsx @@ -1,20 +1,38 @@ import { Button, Tooltip } from "antd" -import { useState, useMemo, useEffect } from "react" +import { useState, useMemo, useEffect, useCallback } from "react" import { useGlobalContext } from "@common/contexts/GlobalStateContext" import { useNavigate } from "react-router-dom" +import { PERMISSION_DEFINITION } from "@common/const/permissions" +import { Icon } from "@iconify/react/dist/iconify.js" +import { $t } from "@common/locales" type TableBtnWithPermissionProps = { btnTitle:string - access:string, + access?:keyof typeof PERMISSION_DEFINITION[0], tooltip?:string, disabled?:boolean, navigateTo?:string, onClick?:(args?:unknown)=>void className?:string + btnType:string +} + +const TableIconName={ + 'add':'ic:baseline-add', + 'edit':'ic:baseline-edit', + 'delete':'ic:baseline-delete', + 'copy':'ic:baseline-file-copy', + 'view':'ic:baseline-remove-red-eye', + 'publish':'ic:baseline-publish', + 'approval':'ic:baseline-approval', + 'stop':'ic:baseline-stop-circle', + 'online':'ic:baseline-check-circle', + 'cancel':'ic:baseline-cancel-schedule-send', + 'refresh':'ic:baseline-refresh' } // 表格操作栏按钮,受权限控制 -const TableBtnWithPermission = ({btnTitle, access, tooltip, disabled, navigateTo, onClick,className}:TableBtnWithPermissionProps) => { +const TableBtnWithPermission = ({btnTitle, access, tooltip, disabled, navigateTo, onClick,className,btnType}:TableBtnWithPermissionProps) => { const [btnAccess, setBtnAccess] = useState(false) const {accessData,checkPermission} = useGlobalContext() @@ -22,19 +40,27 @@ const TableBtnWithPermission = ({btnTitle, access, tooltip, disabled, navigateTo const lastAccess = useMemo(()=>{ if(!access) return true return checkPermission(access) - },[access, accessData]) + },[access, accessData,checkPermission]) useEffect(()=>{ access ? setBtnAccess(lastAccess) : setBtnAccess(true) - },[]) + },[access, lastAccess]) + + const handleClick = useCallback((e: React.MouseEvent) => { + e.stopPropagation() + navigateTo ? navigate(navigateTo) : onClick?.() + }, [navigateTo, navigate, onClick]) + return (<>{ !btnAccess || (disabled&&tooltip) ? - + : - + + + } ); diff --git a/frontend/packages/common/src/components/aoplatform/TimePicker.tsx b/frontend/packages/common/src/components/aoplatform/TimePicker.tsx deleted file mode 100644 index ef440faf..00000000 --- a/frontend/packages/common/src/components/aoplatform/TimePicker.tsx +++ /dev/null @@ -1,16 +0,0 @@ - -import {forwardRef} from 'react'; -import type { PickerProps } from 'antd/es/date-picker/generatePicker'; -import type { Moment } from 'moment'; - -import DatePicker from './DatePicker'; - -export interface TimePickerProps extends Omit, 'picker'> {} - -const TimePicker = forwardRef((props, ref) => ( - -)); - -TimePicker.displayName = 'TimePicker'; - -export default TimePicker; \ No newline at end of file diff --git a/frontend/packages/common/src/components/aoplatform/TimeRangeSelector.tsx b/frontend/packages/common/src/components/aoplatform/TimeRangeSelector.tsx index e66dd9c2..09047604 100644 --- a/frontend/packages/common/src/components/aoplatform/TimeRangeSelector.tsx +++ b/frontend/packages/common/src/components/aoplatform/TimeRangeSelector.tsx @@ -4,6 +4,7 @@ import { Radio, DatePicker, GetProps, RadioChangeEvent } from 'antd'; import dayjs, { Dayjs } from 'dayjs'; import customParseFormat from 'dayjs/plugin/customParseFormat'; import "../../index.css" +import { $t } from '@common/locales'; type RangePickerProps = GetProps; export type RangeValue = [Dayjs | null, Dayjs | null] | null; @@ -94,12 +95,12 @@ const disabledDate: RangePickerProps['disabledDate'] = (current) => { return (
- {!hideTitle && } + {!hideTitle && } - 近1小时 - 近24小时 - 近3天 - 近7天 + {$t('近1小时')} + {$t('近24小时')} + {$t('近3天')} + {$t('近7天')} tr>th, - :global .ant-table-wrapper .ant-table-thead >tr>td{ - font-weight: normal; - background-color: var(--MAIN_BG); - border:none; - } - - :global .ant-table-wrapper .ant-table-tbody-virtual .ant-table-cell{ - border:none; - } - - :global .rc-virtual-list-scrollbar.rc-virtual-list-scrollbar-horizontal{ - display: none; - } - - :global .ant-table-wrapper .ant-table-tbody .ant-table-row > .ant-table-cell-row-hover{ - background: #EBEEF2; - } - - :global .ant-table-wrapper .ant-table-tbody .ant-table-row.ant-table-row-selected > .ant-table-cell-row-hover{ - background: #EBEEF2; - } - :global .ant-table-thead >tr>th:not(:last-child):not(.ant-table-selection-column):not(.ant-table-row-expand-icon-cell):not([colspan])::before{ - display: none; - } -} \ No newline at end of file diff --git a/frontend/packages/common/src/components/aoplatform/TransferTable.tsx b/frontend/packages/common/src/components/aoplatform/TransferTable.tsx deleted file mode 100644 index 69bbc141..00000000 --- a/frontend/packages/common/src/components/aoplatform/TransferTable.tsx +++ /dev/null @@ -1,193 +0,0 @@ - -import { Input,Table} from "antd"; -import {forwardRef, KeyboardEventHandler, Ref, useCallback, useEffect, useImperativeHandle, useRef, useState} from "react"; -import styles from './TransferTable.module.css' -import {CloseOutlined, SearchOutlined} from "@ant-design/icons"; -import {debounce} from "lodash-es"; -import {ColumnsType} from "antd/es/table"; - -export type TransferTableProps = { - request?:(k?:string)=>Promise<{data:T[],success:boolean}> - columns: ColumnsType - primaryKey:string - onSelect:(selectedData:T[])=>void - tableType?:'member'|'api' - disabledData:string[] - searchPlaceholder?:string -} - -export type TransferTableHandle = { - selectedData: () => T[]; - selectedRowKeys: () => React.Key[]; -} - -const TransferTable = forwardRef, TransferTableProps<{[k:string]:unknown}>>( - (props: TransferTableProps, ref:Ref>) => { - const {request,columns,primaryKey,onSelect,tableType,disabledData = [],searchPlaceholder} = props - const tblRef: Parameters[0]['ref'] = useRef(null); - const [selectedRowKeys, setSelectedRowKeys] = useState(disabledData); - const [selectedData, setSelectedData] = useState>([]) - const [dataSource, setDataSource] = useState([]) - const [searchWord, ] = useState('') - const [loading, setLoading] = useState(false) - const parentRef = useRef(null); - const [tableHeight, setTableHeight] = useState(window.innerHeight * 80 / 100 ); - const [tableShow, setTableShow] = useState(false); - - useImperativeHandle(ref, () =>({ - selectedData: () => selectedData, - selectedRowKeys: () => selectedRowKeys,})) - - const handlerLeftTableClick = (record:T & {[k:string]:string})=>{ - if(disabledData.indexOf(record[primaryKey||'id' as string] )!== -1) return - - const tmpSelectedRowKeys = [...selectedRowKeys]; - if (tmpSelectedRowKeys.indexOf(record[primaryKey||'id' as string]) !== -1) { - tmpSelectedRowKeys.splice(tmpSelectedRowKeys.indexOf(record[primaryKey||'id' as string]), 1); - } else { - tmpSelectedRowKeys.push(record[primaryKey||'id' as string]); - } - setSelectedRowKeys(tmpSelectedRowKeys); - let tmpSelectedData = [...selectedData] - if(tmpSelectedData.filter((x: T)=>x[primaryKey || 'id'] === record[primaryKey||'id' as string]).length > 0){ - tmpSelectedData = tmpSelectedData.filter((x: T)=>x[primaryKey || 'id'] !== record[primaryKey||'id' as string]) - }else{ - tmpSelectedData.push(record) - } - setSelectedData(tmpSelectedData) - } - - // const handlerRightTableClick = (record:T & {[k:string]:string})=>{ - // const tmpSelectedRowKeys = [...selectedRowKeys]; - // if (tmpSelectedRowKeys.indexOf(record[primaryKey||'id' as string]) >= 0) { - // tmpSelectedRowKeys.splice(tmpSelectedRowKeys.indexOf(record[primaryKey||'id' as string]), 1); - // } - // setSelectedRowKeys(tmpSelectedRowKeys); - // let tmpSelectedData = [...selectedData] - // tmpSelectedData = tmpSelectedData.filter((x: {[k:string]:string})=>x[primaryKey || 'id'] !== record[primaryKey||'id' as string]) - // setSelectedData(tmpSelectedData) - // } - - const onSelectChange = (newSelectedRowKeys: React.Key[], selectedRow:T[]) => { - setSelectedRowKeys(newSelectedRowKeys); - setSelectedData(selectedRow.filter((x:T)=>disabledData.indexOf(x[primaryKey || 'id'] as string) === -1)) - }; - const removeItem = (item:T )=>{ - setSelectedRowKeys(selectedRowKeys.filter((x)=>{return x!==item[primaryKey || 'id']})) - setSelectedData((prevData)=>prevData.filter((x:T)=>(x[primaryKey || 'id'] !== item[primaryKey || 'id']))) - } - - useEffect(() => { - onSelect && onSelect(selectedData) - }, [selectedData]); - - const operations = [ - { - title: '操作', - key: 'option', - width: 40, - valueType: 'option', - render: (_: React.ReactNode, entity: T) => [ - removeItem(entity as T)}/> - ], - } - ] - - const onSearchWordChange = (e: KeyboardEventHandler)=>{ - getDataSource(e.target.value) - } - - const getDataSource = (curSearchWord?:string)=>{ - setLoading(true) - request && request(curSearchWord ?? searchWord).then((res)=>{ - const {data,success} = res - setDataSource(success? data : []) - }).finally(()=>{setLoading(false)}) - } - - const debouncedSearch = useCallback( - debounce(onSearchWordChange, 600),[] - ) - - - useEffect(() => { - getDataSource() - const handleResize = () => { - if (parentRef.current) { - const res = parentRef.current.getBoundingClientRect(); - setTableHeight(res.height - 32 - 12 * 2 -42 -2) - setTimeout(()=>setTableShow(true),100) - // setTableWidth(res.width / 2 - 20 - 2 - 40) - // const height = res.height -( noTop ? 0 :52) - (dragSortKey ? 0 : 53) - 40;// 减去顶部按钮、底部分页、表头高度 - // height && setTableHeight(height); - } - }; - - const debouncedHandleResize = debounce(handleResize, 200); - - // 创建一个 ResizeObserver 来监听高度变化 - const resizeObserver = new ResizeObserver(debouncedHandleResize); - - // 开始监听 - if (parentRef.current ) { - resizeObserver.observe(parentRef.current); - } - - // 清理函数 - return () => { - resizeObserver.disconnect(); - }; - }, []); - return ( -
-
- {onSearchWordChange}}/>} /> - {tableShow &&
({ - disabled: disabledData.length > 0 && disabledData?.indexOf(record[primaryKey || 'id'] as string) !== -1, // Column configuration not to be checked - name: record[primaryKey || 'id'], - - }), - } - } - onRow={(record) => ({ - onClick: () => { - handlerLeftTableClick(record); - } - })} - />} - -
-
- 已选{tableType === 'member' ? '成员' : ' API'} ({selectedData.length}) -
-
({...col,className:(col.className || ' ') + 'pl-[20px]'})),...operations]} - showHeader={false} - rowKey={primaryKey} - dataSource={selectedData} - pagination={false} - ref={tblRef} - loading={loading} - /> - - ); -}) -export default TransferTable \ No newline at end of file diff --git a/frontend/packages/common/src/components/aoplatform/UserAvatar.tsx b/frontend/packages/common/src/components/aoplatform/UserAvatar.tsx deleted file mode 100644 index ade60c0c..00000000 --- a/frontend/packages/common/src/components/aoplatform/UserAvatar.tsx +++ /dev/null @@ -1,120 +0,0 @@ -import {App, Avatar, Dropdown, MenuProps} from "antd"; -import {useGlobalContext} from "@common/contexts/GlobalStateContext.tsx"; -import {FC, useEffect, useRef, useState} from "react"; -import {ResetPsw, ResetPswHandle} from "@common/components/aoplatform/ResetPsw.tsx"; -import {useFetch} from "@common/hooks/http.ts"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; -import {useNavigate} from "react-router-dom"; -import { UserInfoType, UserProfileHandle } from "@common/const/type.ts"; -import { UserProfile } from "./UserProfile.tsx"; -import AvatarPic from '@common/assets/avatar_default.svg' - -const UserAvatar: FC = () => { - const { modal,message } = App.useApp() - const { dispatch,resetAccess,getGlobalAccessData} = useGlobalContext() - const [userInfo,setUserInfo] = useState() - const resetPswRef = useRef(null) - const userProfileRef = useRef(null) - const {fetchData} = useFetch() - const navigate = useNavigate(); - - const getUserInfo = ()=>{ - fetchData>('account/profile',{method:'GET'}) - .then(response=>{ - const {code,data,msg} = response - if(code === STATUS_CODE.SUCCESS){ - setUserInfo(data.profile) - dispatch({type:'UPDATE_USERDATA',userData:data.profile}) - }else{ - message.error(msg || '操作失败') - } - }) - } - - useEffect(() => { - getUserInfo() - getGlobalAccessData() - }, []); - - const logOut = ()=>{ - fetchData>('account/logout',{method:'GET'}).then(response=>{ - const {code,msg} = response - if(code === STATUS_CODE.SUCCESS){ - dispatch({type:'LOGOUT'}) - resetAccess() - message.success(msg || '退出成功,将跳转至登录页') - navigate('/login') - }else{ - message.error(msg ||'操作失败') - } - }) - } - - const items: MenuProps['items'] = [ - // { - // key: '1', - // label: ( - // openModal('userSetting')}> - // 用户设置 - // - // ), - // }, - // { - // key: '2', - // label: ( - // openModal('resetPsw')}> - // 修改密码 - // - // ), - // }, - { - key: '3', - label: ( - - 退出登录 - - ), - }, - ]; - - const openModal = (type:'userSetting'|'resetPsw')=>{ - let title:string = '' - let content:string|React.ReactNode = '' - switch (type){ - case 'userSetting': - title='用户设置' - content= - break; - case 'resetPsw': - title='重置密码' - content= - break; - } - modal.confirm({ - title, - content, - onOk:()=>{ - switch (type){ - case 'userSetting': - return userProfileRef.current?.save().then((res)=>{if(res === true) getUserInfo()}) - case 'resetPsw': - return resetPswRef.current?.save().then((res)=>{if(res === true) logOut()}) - } - }, - width:600, - okText:'确认', - cancelText:'取消', - closable:true, - icon:<>, - }) - } - - - return ( - - {userInfo?.username||'unknown'} - - ) -} - -export default UserAvatar \ No newline at end of file diff --git a/frontend/packages/common/src/components/aoplatform/UserProfile.tsx b/frontend/packages/common/src/components/aoplatform/UserProfile.tsx deleted file mode 100644 index c6b98f7a..00000000 --- a/frontend/packages/common/src/components/aoplatform/UserProfile.tsx +++ /dev/null @@ -1,152 +0,0 @@ -import {App, Form, Input, Upload, UploadFile, UploadProps} from "antd"; -import {forwardRef, useEffect, useImperativeHandle, useState} from "react"; -import {useFetch} from "@common/hooks/http.ts"; -import {RcFile, UploadChangeParam} from "antd/es/upload"; -import {LoadingOutlined} from "@ant-design/icons"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; -import { UserInfoType, UserProfileHandle, UserProfileProps } from "@common/const/type"; -import { getImgBase64 } from "@common/utils/dataTransfer"; -import { Icon } from "@iconify/react/dist/iconify.js"; - -export const UserProfile = forwardRef((props,ref)=>{ - const { message } = App.useApp() - const [form] = Form.useForm(); - const {entity,} = props - const {fetchData} = useFetch() - const [imageBase64, setImageBase64] = useState(null); - const [loading, setLoading] = useState(false); - const [imageUrl, setImageUrl] = useState(); - - const save:()=>Promise = ()=>{ - return new Promise((resolve, reject)=>{ - form.validateFields().then((value)=>{ - fetchData>('account/profile',{method:'PUT',eoBody:value}).then(response=>{ - const {code,msg} = response - if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') - resolve(true) - }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') - } - }).catch((errorInfo)=> reject(errorInfo)) - }).catch((errorInfo)=> reject(errorInfo)) - }) - } - - useImperativeHandle(ref, ()=>({ - save - }) - ) - - - const handleChange: UploadProps['onChange'] = (info: UploadChangeParam) => { - if (info.file.status === 'uploading') { - setLoading(true); - return; - } - if (info.file.status === 'done') { - // Get this url from response in real world. - getImgBase64(info.file.originFileObj as RcFile, (url) => { - setLoading(false); - setImageUrl(url); - }); - } - if (info.fileList.length === 0) { - // 如果文件被移除,清除 logo 字段 - form.setFieldValue( "avatar", null ); - } - }; - - const uploadButton = ( -
-
- {loading ? : }
-
- ); - - const beforeUpload = (file: RcFile) => { - const reader = new FileReader(); - reader.onload = (e: ProgressEvent) => { - setImageBase64(e.target?.result as string); - form.setFieldValue("avatar",e.target?.result) - }; - reader.readAsDataURL(file); - return false; - }; - - useEffect(() => { - form.setFieldsValue(entity) - }, []); - - -const normFile = (e: unknown) => { - if (Array.isArray(e)) { - return e; - } - return( e as {fileList:unknown} )?.fileList; - }; - return (<> -
- - label="账号" - name="username" - rules={[{ required: true, message: '必填项',whitespace:true }]} - > - - - - - label="昵称" - name="nickname" - rules={[{ required: true, message: '必填项',whitespace:true }]} - > - - - - - label="头像" - name="avatar" - valuePropName="fileList" getValueFromEvent={normFile} - > - - {imageBase64 ? Logo : uploadButton} - - - - - - label="邮箱" - name="email" - rules={[{ required: true, message: '必填项' ,whitespace:true },{type:'email',message: '输入的不是有效邮箱格式'}]} - > - - - - - label="手机号码" - name="phone" - rules={[{pattern:/^(13[0-9]|14[5|7]|15[0|1|2|3|4|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$/, message:'输入的不是有效手机号码',warningOnly: true }]} - > - - - - - ) -}) \ No newline at end of file diff --git a/frontend/packages/common/src/components/aoplatform/WithPermission.tsx b/frontend/packages/common/src/components/aoplatform/WithPermission.tsx index 4e02581d..20fea9e7 100644 --- a/frontend/packages/common/src/components/aoplatform/WithPermission.tsx +++ b/frontend/packages/common/src/components/aoplatform/WithPermission.tsx @@ -3,6 +3,7 @@ import { Tooltip } from "antd"; import { ReactElement, cloneElement, useEffect, useMemo, useState } from "react"; import { useGlobalContext } from "../../contexts/GlobalStateContext"; import { PERMISSION_DEFINITION } from "@common/const/permissions"; +import { $t } from "@common/locales"; type WithPermissionProps = { access?:string | string[] @@ -20,7 +21,7 @@ const WithPermission = ({access, tooltip, children,disabled, showDisabled = true const lastAccess = useMemo(()=>{ if(!access) return true return checkPermission(access as keyof typeof PERMISSION_DEFINITION[0]) - },[access, accessData]) + },[access, accessData,checkPermission]) useEffect(()=>{ // 先判断权限,无论权限是否为true,如果disabled为true时则必须为ture @@ -36,7 +37,7 @@ const WithPermission = ({access, tooltip, children,disabled, showDisabled = true {editAccess && disabled && { cloneElement(children, {disabled:true})} } - {!editAccess && (children?.type?.displayName !== 'Button' && showDisabled ) && + {!editAccess && (children?.type?.displayName !== 'Button' && showDisabled ) && { cloneElement(children, {disabled:true})} } diff --git a/frontend/packages/common/src/components/aoplatform/formily2-customize/CustomDialogComponent.tsx b/frontend/packages/common/src/components/aoplatform/formily2-customize/CustomDialogComponent.tsx index 938fac75..c7bdd611 100644 --- a/frontend/packages/common/src/components/aoplatform/formily2-customize/CustomDialogComponent.tsx +++ b/frontend/packages/common/src/components/aoplatform/formily2-customize/CustomDialogComponent.tsx @@ -39,6 +39,7 @@ import { } from '@formily/antd-v5' import { CustomCodeboxComponent } from './CustomCodeboxComponent.tsx' import { SimpleMapComponent } from './SimpleMapComponent.tsx' +import { $t } from '@common/locales/index.ts' const SchemaField = createSchemaField({ components: { @@ -96,7 +97,7 @@ export const CustomDialogComponent = forwardRef( className="ant-formily-array-base-config" onClick={() => { const dialog = FormDialog( - editPage ? `编辑${title || ''}` : `添加${title || ''}`, + editPage ? $t('编辑(0)',[title||'']) : $t('添加(0)',[title||'']), () => { return ( { const { onChange, value, - placeholderKey = '请输入Key', - placeholderValue = '请输入Value' + placeholderKey = $t('请输入Key'), + placeholderValue = $t('请输入Value') } = props const [kvList, setKvList] = useState( diff --git a/frontend/packages/common/src/components/aoplatform/intelligent-plugin/IntelligentPluginConfig.tsx b/frontend/packages/common/src/components/aoplatform/intelligent-plugin/IntelligentPluginConfig.tsx index fc959714..4452ceab 100644 --- a/frontend/packages/common/src/components/aoplatform/intelligent-plugin/IntelligentPluginConfig.tsx +++ b/frontend/packages/common/src/components/aoplatform/intelligent-plugin/IntelligentPluginConfig.tsx @@ -43,12 +43,10 @@ import {CustomDialogComponent} from "@common/components/aoplatform/formily2-cust import {ArrayItemBlankComponent} from "@common/components/aoplatform/formily2-customize/ArrayItemBlankComponent.tsx"; import {DefaultOptionType} from "antd/es/cascader"; import {createSchemaField, FormProvider, RecursionField, useField, useForm} from "@formily/react"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; import {useFetch} from "@common/hooks/http.ts"; import {App} from "antd"; -import { config } from "process"; - - +import { $t } from "@common/locales"; export const DynamicRender = (props) => { const {schema} = props @@ -158,7 +156,7 @@ export const IntelligentPluginConfig = forwardRef>(type === 'add'?`dynamic/${moduleId}`:`dynamic/${moduleId}/config`,{method:type === 'add'? 'POST' : 'PUT',eoBody:form.values, eoParams:{...(type !== 'add' && {id:initFormValue.id})}}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }).catch((errorInfo:unknown)=> reject(errorInfo)) @@ -262,8 +260,8 @@ export const IntelligentPluginConfig = forwardRef{return{label:x.title, value:x.name}}) || []) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }) }) diff --git a/frontend/packages/common/src/components/aoplatform/intelligent-plugin/IntelligentPluginList.tsx b/frontend/packages/common/src/components/aoplatform/intelligent-plugin/IntelligentPluginList.tsx index 99492c07..aea8fff9 100644 --- a/frontend/packages/common/src/components/aoplatform/intelligent-plugin/IntelligentPluginList.tsx +++ b/frontend/packages/common/src/components/aoplatform/intelligent-plugin/IntelligentPluginList.tsx @@ -1,19 +1,20 @@ -import PageList from "@common/components/aoplatform/PageList.tsx"; +import PageList, { PageProColumns } from "@common/components/aoplatform/PageList.tsx"; import {App, Divider, Spin} from "antd"; import {useEffect, useRef, useState} from "react"; import { useLocation, useOutletContext, useParams} from "react-router-dom"; import {useBreadcrumb} from "@common/contexts/BreadcrumbContext.tsx"; -import {ActionType, ParamsType, ProColumns} from "@ant-design/pro-components"; +import {ActionType, ParamsType} from "@ant-design/pro-components"; import {RouterParams} from "@core/components/aoplatform/RenderRoutes.tsx"; import {DefaultOptionType} from "antd/es/cascader"; import {IntelligentPluginConfig, IntelligentPluginConfigHandle} from "./IntelligentPluginConfig.tsx"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, COLUMNS_TITLE, DELETE_TIPS, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; import {useFetch} from "@common/hooks/http.ts"; import {EntityItem} from "@common/const/type.ts"; import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; import TableBtnWithPermission from "@common/components/aoplatform/TableBtnWithPermission.tsx"; import { DrawerWithFooter } from "@common/components/aoplatform/DrawerWithFooter.tsx"; import { LoadingOutlined } from "@ant-design/icons"; +import { $t } from "@common/locales/index.ts"; type DynamicTableField = { name: string, @@ -95,7 +96,7 @@ export default function IntelligentPluginList(){ const [tableListDataSource, setTableListDataSource] = useState([]); const [tableHttpReload, setTableHttpReload] = useState(true); - const [columns,setColumns] = useState[] >([]) + const [columns,setColumns] = useState[] >([]) const {fetchData} = useFetch() const pageListRef = useRef(null); const [publishBtnLoading, setPublishBtnLoading] = useState(false) @@ -159,7 +160,7 @@ export default function IntelligentPluginList(){ const {title,drivers} = basic setBreadcrumb([ - {title:location.includes('resourcesettings') ? '资源配置': '日志配置'}, + {title:location.includes('resourcesettings') ? $t('资源'): $t('日志')}, { title } @@ -178,23 +179,23 @@ export default function IntelligentPluginList(){ setRenderSchema(resp.data.render) return Promise.resolve(resp.data.render) } - return Promise.reject(resp.msg || '操作失败') + return Promise.reject(resp.msg || RESPONSE_TIPS.error) }) } - const operation:ProColumns[] =[ + const operation:PageProColumns[] =[ { - title: '操作', + title: COLUMNS_TITLE.operate, key: 'option', - width: 150, fixed:'right', valueType: 'option', + btnNums:3, render: (_: React.ReactNode, entity: DynamicTableItem) => [ - {openModal('publish',entity)}} btnTitle={entity.status === '已发布' ? '下线' : '上线'}/>, + {openModal('publish',entity)}} btnTitle={entity.status === $t('已发布') ? $t('下线') : $t('上线')}/>, , - {openDrawer('edit',entity)}} btnTitle="查看"/>, + {openDrawer('edit',entity)}} btnTitle={$t("查看")}/>, , - {openModal('delete',entity)}} btnTitle="删除"/>, + {openModal('delete',entity)}} btnTitle={$t("删除")}/>, ], } ] @@ -213,11 +214,11 @@ export default function IntelligentPluginList(){ fetchData>(`dynamic/${moduleId}/batch`,{method:'DELETE',eoParams:{ids:JSON.stringify([entity!.id])}}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }) }) @@ -239,7 +240,7 @@ export default function IntelligentPluginList(){ } setCurDetail(data.info) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }).finally(()=>setDrawerLoading(false)) break; @@ -254,25 +255,25 @@ export default function IntelligentPluginList(){ let content:string|React.ReactNode = '' switch (type){ case 'publish':{ - message.loading('正在操作') - await fetchData>(`dynamic/${moduleId}/${entity!.status === '已发布' ? 'offline':'online'}`, { + message.loading(RESPONSE_TIPS.operating) + await fetchData>(`dynamic/${moduleId}/${entity!.status === $t('已发布') ? 'offline':'online'}`, { method: 'PUT', eoParams:{id:entity!.id}, }).then(response => { const {code, msg} = response if (code === STATUS_CODE.SUCCESS) { - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) return Promise.resolve(true) } else { - message.error(msg || '操作失败') - return Promise.reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + return Promise.reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> Promise.reject(errorInfo)) message.destroy() return;} case 'delete': title='删除' - content=确定删除?此操作无法恢复,确认操作? + content={DELETE_TIPS.default} break; } @@ -287,11 +288,11 @@ export default function IntelligentPluginList(){ } }, width: type === 'delete'? 600 : 900, - okText:'确认', + okText:$t('确认'), okButtonProps:{ disabled:false }, - cancelText:'取消', + cancelText:$t('取消'), closable:true, icon:<>, footer:(_, { OkBtn, CancelBtn }) =>{ @@ -316,8 +317,8 @@ export default function IntelligentPluginList(){ ref={pageListRef} columns = {[...columns,...operation]} request={(params)=>getIntelligentPluginTableList(params)} - addNewBtnTitle={`添加${pluginName}`} - searchPlaceholder={`搜索${pluginName}名称`} + addNewBtnTitle={$t('添加(0)',[$t(pluginName)])} + searchPlaceholder={$t('搜索(0)名称',[$t(pluginName)])} onChange={() => { setTableHttpReload(false) }} @@ -326,7 +327,7 @@ export default function IntelligentPluginList(){ onSearchWordChange={(e)=>{setSearchWord(e.target.value);setTableHttpReload(true);setTableHttpReload(true)}} /> - {setCurDetail(undefined);setDrawerOpen(false)}} onSubmit={()=>drawerFormRef.current?.save()?.then((res)=>{res && manualReloadTable();return res})} submitAccess=''> + {setCurDetail(undefined);setDrawerOpen(false)}} onSubmit={()=>drawerFormRef.current?.save()?.then((res)=>{res && manualReloadTable();return res})} submitAccess=''> } spinning={drawerLoading}> { if (!['HTTPS', 'HTTP'].includes(api.protocol?.toUpperCase())) { - tempCode = '暂不支持生成非 HTTPS 或非 HTTP 协议的代码示例' + tempCode = $t('暂不支持生成非 HTTPS 或非 HTTP 协议的代码示例') setCode(tempCode) return } @@ -186,7 +187,7 @@ type CodeSnippetCompoType = { (option) => (option.label as string).toLowerCase().indexOf(inputValue.toLowerCase()) > -1, ); - const [placeholderTxt, setPlaceholderTxt] = useState('搜索编程语言...') + const [placeholderTxt, setPlaceholderTxt] = useState($t('搜索编程语言...')) const [selectItemTxt, setSelectItemTxt ] = useState('') return ( @@ -194,7 +195,7 @@ type CodeSnippetCompoType = { <> - 编程语言:{$t('编程语言')}: onChange(value as unknown as number[],record)} placeholder={placeholderTxt} diff --git a/frontend/packages/common/src/components/apispace/code-snippet/util.ts b/frontend/packages/common/src/components/apispace/code-snippet/util.ts index f9231d51..3d1ac481 100644 --- a/frontend/packages/common/src/components/apispace/code-snippet/util.ts +++ b/frontend/packages/common/src/components/apispace/code-snippet/util.ts @@ -1,4 +1,4 @@ -import * as Mock from 'mockjs' +import {Random} from 'mockjs' import { PARAM_KEY_REF_TYPE, PARAM_LIST_TYPE, PARAM_LIS_ITEM_TYPE, PARAM_TYPE, PARAM_TYPE_REF_TYPE } from "./code-snippets.type" const DEFAULT_PARAM_KEY_REF: PARAM_KEY_REF_TYPE = { key: 'key', @@ -127,5 +127,5 @@ export function tranformJson( return result.join('\n') //分隔符会换行 } export function getRandomDataByType(type: PARAM_TYPE) { - return Mock.Random[Object.keys(Mock.Random).includes(type) ? type : 'string'](0, 5) + return Random[Object.keys(Random).includes(type) ? type : 'string'](0, 5) } diff --git a/frontend/packages/common/src/components/apispace/response-example/index.tsx b/frontend/packages/common/src/components/apispace/response-example/index.tsx index c605f8b4..df2a4de3 100644 --- a/frontend/packages/common/src/components/apispace/response-example/index.tsx +++ b/frontend/packages/common/src/components/apispace/response-example/index.tsx @@ -5,14 +5,15 @@ import {Collapse} from "@common/components/postcat/api/Collapse"; import {Box} from "@mui/material"; import {Codebox} from "@common/components/postcat/api/Codebox"; import { cloneDeep } from 'lodash-es'; +import { $t } from '@common/locales'; export interface ResponseExampleCompoEditorApi { getData: () => ResultListType[] | [] } const DEFAULT_RESULT_LIST = [ - {id:'success',name:'成功示例',httpCode:'200',content:''}, - {id:'failed',name:'失败示例',httpCode:'200',content:''}, + {id:'success',name:$t('成功示例'),httpCode:'200',content:''}, + {id:'failed',name:$t('失败示例'),httpCode:'200',content:''}, ] export const HTTP_STATUS_CODE = ['200', '403', '404', '410', '422', '500', '502', '503', '504'] @@ -76,7 +77,7 @@ export function ResponseExampleCompo ({ editorRef,title,detail,mode='view' }: {e value={item.httpCode} status={item.httpCode ? '' : 'error'} onSelect={(value)=>updateResultList(item.id,'httpCode',value)} - placeholder="HTTP 状态码" + placeholder={$t("HTTP 状态码")} /> } {mode === 'view' ? @@ -86,7 +87,7 @@ export function ResponseExampleCompo ({ editorRef,title,detail,mode='view' }: {e style={{ width: 200 }} value={item.httpContentType || 'text/html;charset=UTF-8'} onSelect={(value)=>updateResultList(item.id,'httpContentType',value)} - placeholder="默认 text/html;charset=UTF-8" + placeholder={$t("默认 text/html;charset=UTF-8")} />} {mode === 'view' ? @@ -94,7 +95,7 @@ export function ResponseExampleCompo ({ editorRef,title,detail,mode='view' }: {e { item.content ?
{item.content}
: - + } : <> updateResultList(item.id,'content',value)}/> diff --git a/frontend/packages/common/src/components/postcat/ApiEdit.tsx b/frontend/packages/common/src/components/postcat/ApiEdit.tsx index 1bf6aa94..b83d8d82 100644 --- a/frontend/packages/common/src/components/postcat/ApiEdit.tsx +++ b/frontend/packages/common/src/components/postcat/ApiEdit.tsx @@ -11,6 +11,8 @@ import { SystemApiDetail, SystemInsideApiProxyHandle } from "@core/const/system/ import SystemInsideApiProxy from "@core/pages/system/api/SystemInsideApiProxy"; import ApiMatch from "./api/ApiPreview/components/ApiMatch"; import {v4 as uuidv4} from 'uuid' +import { PLACEHOLDER } from "@common/const/const"; +import { $t } from "@common/locales"; const PROTOCOL_LIST = ['HTTP','HTTPS'] const HTTP_METHOD_LIST = ['POST','GET','PUT', 'DELETE','HEAD','OPTIONS','PATCH'] @@ -165,7 +167,7 @@ export default function ApiEdit({apiInfo,editorRef,loaded,serviceId, teamId}:{ap getData: () => { return proxyRef.current?.validate().then((res)=>{ const name = apiNameRef.current?.getData() - if(!name) return Promise.reject('请填写接口名称') + if(!name) return Promise.reject($t('请填写接口名称')) const newData :{apiInfo:Partial}= { apiInfo:{ info:{ @@ -200,7 +202,7 @@ export default function ApiEdit({apiInfo,editorRef,loaded,serviceId, teamId}:{ap getData:()=>description })) return ( - setDescription(e.target.value)} placeholder="请输入"/> + setDescription(e.target.value)} placeholder={PLACEHOLDER.input}/> ) }) @@ -229,25 +231,25 @@ export default function ApiEdit({apiInfo,editorRef,loaded,serviceId, teamId}:{ap - + { apiInfo?.match && apiInfo.match?.length > 0 && - {x.id = uuidv4();return x})} /> + {x.id = uuidv4();return x})} /> } - + - + - + - +
diff --git a/frontend/packages/common/src/components/postcat/ApiPreview.tsx b/frontend/packages/common/src/components/postcat/ApiPreview.tsx index c17c596a..f52fefa9 100644 --- a/frontend/packages/common/src/components/postcat/ApiPreview.tsx +++ b/frontend/packages/common/src/components/postcat/ApiPreview.tsx @@ -15,11 +15,12 @@ import {MessageType} from "./api/ApiManager/components/MessageDataGrid"; import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; import { ThemeProvider } from "@mui/material"; import { theme } from "./ApiEdit.tsx"; +import { $t } from "@common/locales/index.ts"; export const SearchBtn = ({entity}:{entity:unknown})=>{ return ( - 测试 API + {$t('测试 API')} ) } @@ -90,13 +91,13 @@ export default function ApiPreview(props:{testClick?:()=>void, entity:ApiDetail} { requestParams?.headerParams?.length > 0 && - } {requestBodyList?.length > 0 && void, entity:ApiDetail} { requestParams?.queryParams?.length > 0 && - } { requestParams?.restParams?.length > 0 && - } {/*

请求示例代码

*/} - + : undefined } /> - {resultList?.length > 0 && } + {resultList?.length > 0 && } { responseList?.[0]?.responseParams?.headerParams?.length > 0 && - } {responseBodyList?.length > 0 && void }) { return ( { @@ -62,7 +63,7 @@ export function ApiRequestEditor({ editorRef ,apiInfo=null,loaded}: { editorRef? const tabs: ApiRequestEditorTab[] = [ { - label: '请求头部', + label: $t('请求头部'), element: ( , dirty: false }, { - label: 'Query 参数', + label: $t('Query 参数'), element: ( , dirty: false @@ -93,7 +94,7 @@ export function ApiResponseEditor({ editorRef ,apiInfo=null, loaded}: { editorRe ) const getActions = useCallback( (params: GridRowParams) => { const actions = [ - handleOpenMoreSetting(params)} /> + handleOpenMoreSetting(params)} /> ] const isXML = contentType === 'XML' const isRoot = params.row.__globalIndex__ === 0 if (['JSON', 'XML'].includes(contentType)) { actions.unshift( { const newRow = EmptyRow() @@ -288,7 +289,7 @@ export function MessageDataGrid(props: MessageDataGridProps) if (!(isXML && isRoot)) { actions.unshift( { const newRow = EmptyRow() @@ -301,7 +302,7 @@ export function MessageDataGrid(props: MessageDataGridProps) } } if (renderRows.length > 1) { - actions.push( handleRowDelete(params)} />) + actions.push( handleRowDelete(params)} />) } return actions }, @@ -312,7 +313,7 @@ export function MessageDataGrid(props: MessageDataGridProps) const columns: (GridColDef | false)[] = [ messageType === 'Header' && { field: 'name', - headerName: '标签', + headerName: $t('标签'), editable: true, sortable:false, renderEditCell: (params) => { @@ -340,7 +341,7 @@ export function MessageDataGrid(props: MessageDataGridProps) }, messageType !== 'Header' && { field: 'name', - headerName: '参数名', + headerName: $t('参数名'), width: 200, editable: true, sortable: false, @@ -373,7 +374,7 @@ export function MessageDataGrid(props: MessageDataGridProps) { const newValue = e.target.value as string const rowIndex = params.row.__globalIndex__ @@ -395,7 +396,7 @@ export function MessageDataGrid(props: MessageDataGridProps) }, messageType === 'Body' && { field: 'dataType', - headerName: '类型', + headerName: $t('类型'), sortable: false, width: 120, type: 'singleSelect', @@ -429,7 +430,7 @@ export function MessageDataGrid(props: MessageDataGridProps) }, { field: 'isRequired', - headerName: '必需', + headerName: $t('必需'), headerAlign: 'left', sortable: false, type: 'boolean', @@ -443,7 +444,7 @@ export function MessageDataGrid(props: MessageDataGridProps) indeterminate={selectAll === 'indeterminate'} onChange={handleSelectAllChange} /> - 必需 + {$t('必需')} ) }, @@ -463,7 +464,7 @@ export function MessageDataGrid(props: MessageDataGridProps) }, { field: 'description', - headerName: '描述', + headerName: $t('描述'), sortable: false, flex: 1, minWidth: 200, @@ -484,7 +485,7 @@ export function MessageDataGrid(props: MessageDataGridProps) paddingRight: theme.spacing(1) } }} - placeholder='描述' + placeholder={$t('描述')} /> ) } @@ -492,7 +493,7 @@ export function MessageDataGrid(props: MessageDataGridProps) { field: 'paramAttr', sortable: false, - headerName: '示例', + headerName: $t('示例'), flex: 1, minWidth: 200, editable: true, @@ -515,8 +516,7 @@ export function MessageDataGrid(props: MessageDataGridProps) paddingRight: theme.spacing(1) } }} - placeholder='示例' - /> + placeholder={$t('示例')} /> ) } }, diff --git a/frontend/packages/common/src/components/postcat/api/ApiManager/components/UriInput/index.tsx b/frontend/packages/common/src/components/postcat/api/ApiManager/components/UriInput/index.tsx index 6a665187..c00d3ea1 100644 --- a/frontend/packages/common/src/components/postcat/api/ApiManager/components/UriInput/index.tsx +++ b/frontend/packages/common/src/components/postcat/api/ApiManager/components/UriInput/index.tsx @@ -3,6 +3,7 @@ import { SyntheticEvent } from 'react' import {ParseCurlResult} from "@common/const/api-detail"; import {HTTPMethod, RequestMethod} from "../../../RequestMethod"; import {ParseCurl} from "@common/utils/curl.ts"; +import { $t } from '@common/locales'; interface UriInputProps { inputValue?: string @@ -51,7 +52,7 @@ export function UriInput({ return ( [] = [ { field: 'key', - headerName: '参数名', + headerName: $t('参数名'), hideable: false, width:200 }, { field: 'position', - headerName: '参数位置', + headerName: $t('参数位置'), valueGetter: (params) => MatchPositionEnum[params.row.position], width:160 }, { field: 'matchType', - headerName: '匹配类型', + headerName: $t('匹配类型'), valueGetter: (params) => MatchTypeEnum[params.row.matchType], width:160 }, { field: 'pattern', - headerName: '参数值', + headerName: $t('参数值'), flex:1 } ] diff --git a/frontend/packages/common/src/components/postcat/api/ApiPreview/components/ApiProxy/index.tsx b/frontend/packages/common/src/components/postcat/api/ApiPreview/components/ApiProxy/index.tsx index d16cf0b5..83d4a19e 100644 --- a/frontend/packages/common/src/components/postcat/api/ApiPreview/components/ApiProxy/index.tsx +++ b/frontend/packages/common/src/components/postcat/api/ApiPreview/components/ApiProxy/index.tsx @@ -6,6 +6,7 @@ import { SystemApiProxyType, ProxyHeaderItem } from "@core/const/system/type" import { previewTableHoverSx, collapseTableSx } from "../../../PreviewTable" import { RenderMessageBody } from "../MessageBody" import { Collapse } from "../../../Collapse" +import { $t } from "@common/locales" interface HeaderFieldsProps { proxyInfo:SystemApiProxyType @@ -30,19 +31,19 @@ export default function ApiProxy({ proxyInfo, title, loading = false, onMoreSett const columns: GridColDef[] = [ { field: 'key', - headerName: '参数名', + headerName: $t('参数名'), width: 200, hideable: false }, { field: 'optType', - headerName: '操作类型', - valueGetter: (params) => params.row.optType === 'ADD'?'新增或修改':'删除', + headerName: $t('操作类型'), + valueGetter: (params) => params.row.optType === 'ADD'?$t('新增或修改'):$t('删除'), width: 200 }, { field: 'value', - headerName: '匹配参数值', + headerName: $t('匹配参数值'), flex: 1 }, ] @@ -51,31 +52,31 @@ export default function ApiProxy({ proxyInfo, title, loading = false, onMoreSett return [ { key: 'path', - label: '转发上游路径', + label: $t('转发上游路径'), children: proxyInfo?.path, style: {paddingBottom: '10px'}, }, { key: 'timeout', - label: '请求超时时间', + label: $t('请求超时时间'), children: proxyInfo?.timeout, style: {paddingBottom: '10px'}, }, // { // key: 'upstream', - // label: '绑定上游服务', + // label: $t('绑定上游服务', // children: proxyInfo?.upstream.name, // style: {paddingBottom: '10px'}, // }, { key: 'retry', - label: '重试时间', + label: $t('重试时间'), children: proxyInfo?.retry, style: {paddingBottom: '10px'}, }, ...(proxyInfo.headers.length > 0 ? [{ key: 'headers', - label: '转发上游请求头', + label: $t('转发上游请求头'), children: '', style: {paddingBottom: '10px'}, }]:[]) diff --git a/frontend/packages/common/src/components/postcat/api/ApiPreview/components/HeaderFields/index.tsx b/frontend/packages/common/src/components/postcat/api/ApiPreview/components/HeaderFields/index.tsx index e04f80a5..69bfafda 100644 --- a/frontend/packages/common/src/components/postcat/api/ApiPreview/components/HeaderFields/index.tsx +++ b/frontend/packages/common/src/components/postcat/api/ApiPreview/components/HeaderFields/index.tsx @@ -5,6 +5,7 @@ import { RenderMessageBody } from '../MessageBody' import {HeaderParamsType} from "@common/const/api-detail"; import {collapseTableSx, PreviewGridActionsCellItem, previewTableHoverSx} from "../../../PreviewTable"; import {Collapse} from "../../../Collapse"; +import { $t } from "@common/locales"; interface HeaderFieldsProps { rows?: HeaderParamsType[] @@ -29,13 +30,13 @@ export default function HeaderFields({ rows = [], title, loading = false, onMore const columns: GridColDef[] = [ { field: 'name', - headerName: '标签', + headerName: $t('标签'), width: 200, hideable: false }, { field: 'isRequired', - headerName: '必需', + headerName: $t('必需'), sortable: false, valueGetter: (params) => Boolean(params.row.isRequired), type: 'boolean', @@ -43,7 +44,7 @@ export default function HeaderFields({ rows = [], title, loading = false, onMore }, { field: 'description', - headerName: '描述', + headerName: $t('描述'), flex: 1 }, { @@ -57,7 +58,7 @@ export default function HeaderFields({ rows = [], title, loading = false, onMore getActions: (params) => [ onMoreSettingChange?.(params.row as unknown as RenderMessageBody)} /> diff --git a/frontend/packages/common/src/components/postcat/api/ApiPreview/components/MessageBody/components/Binary.tsx b/frontend/packages/common/src/components/postcat/api/ApiPreview/components/MessageBody/components/Binary.tsx index 6e310e2b..83bcad93 100644 --- a/frontend/packages/common/src/components/postcat/api/ApiPreview/components/MessageBody/components/Binary.tsx +++ b/frontend/packages/common/src/components/postcat/api/ApiPreview/components/MessageBody/components/Binary.tsx @@ -3,7 +3,7 @@ import { TextField } from '@mui/material' export function PreviewBodyBinary({ value }: { value: string;}) { return ( [] = [ { field: 'dataType', - headerName: '类型', + headerName: $t('类型'), valueGetter: (params) => ApiParamsType[params.row.dataType as ApiParamsType], width: 80 }, { field: 'isRequired', - headerName: '必需', + headerName: $t('必需'), sortable: false, valueGetter: (params) => Boolean(params.row.isRequired), type: 'boolean', @@ -64,12 +65,12 @@ export default function MessageBodyComponent({ }, { field: 'description', - headerName: '描述', + headerName: $t('描述'), flex: 1 }, { field: 'paramAttr', - headerName: '示例', + headerName:$t('示例'), valueGetter: (params) => params.row.paramAttr?.example, flex: 1 }, @@ -83,7 +84,7 @@ export default function MessageBodyComponent({ getActions: (params) => [ onMoreSettingChange?.(params.row)} /> @@ -105,7 +106,7 @@ export default function MessageBodyComponent({ rowHeight={40} pagination={false} groupingColDef={{ - headerName: '参数名', + headerName: $t('参数名'), sortable:true, width: 200, hideable: false, diff --git a/frontend/packages/common/src/components/postcat/api/ApiPreview/components/QueryFields/index.tsx b/frontend/packages/common/src/components/postcat/api/ApiPreview/components/QueryFields/index.tsx index b7aaf4a2..09e7c83d 100644 --- a/frontend/packages/common/src/components/postcat/api/ApiPreview/components/QueryFields/index.tsx +++ b/frontend/packages/common/src/components/postcat/api/ApiPreview/components/QueryFields/index.tsx @@ -6,6 +6,7 @@ import { RenderMessageBody } from '../MessageBody' import {QueryParamsType} from "@common/const/api-detail"; import {collapseTableSx, PreviewGridActionsCellItem, previewTableHoverSx} from "../../../PreviewTable"; import {Collapse} from "../../../Collapse"; +import { $t } from '@common/locales'; interface QueryFieldsProps { rows?: QueryParamsType[] @@ -30,13 +31,13 @@ export default function QueryFields({ rows = [], title, loading = false, onMoreS const columns: GridColDef[] = [ { field: 'name', - headerName: '参数名', + headerName: $t('参数名'), width: 200, hideable: false }, { field: 'isRequired', - headerName: '必需', + headerName: $t('必需'), sortable: false, valueGetter: (params) => Boolean(params.row.isRequired), type: 'boolean', @@ -44,7 +45,7 @@ export default function QueryFields({ rows = [], title, loading = false, onMoreS }, { field: 'description', - headerName: '描述', + headerName: $t('描述'), flex: 1 }, { @@ -58,7 +59,7 @@ export default function QueryFields({ rows = [], title, loading = false, onMoreS getActions: (params) => [ onMoreSettingChange?.(params.row as unknown as RenderMessageBody)} /> diff --git a/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiRequestTester/ImportMessage/index.tsx b/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiRequestTester/ImportMessage/index.tsx index 90c3e19b..a501397d 100644 --- a/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiRequestTester/ImportMessage/index.tsx +++ b/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiRequestTester/ImportMessage/index.tsx @@ -4,6 +4,7 @@ import { IconButton } from '../../../../IconButton' import {BaseDialog} from "../../../../Dialog"; import {Icon} from "../../../../Icon"; import {Codebox} from "../../../../Codebox"; +import { $t } from '@common/locales'; export type ImportMessageChangeType = 'replace-all' | 'insert-end' | 'replace-changed' @@ -65,7 +66,7 @@ export function ImportMessage({ type, onChange }: ImportMessageDialogProps) { return ( <> setOpen(true)} variant="outlined"> - 导入 + {$t('导入')} setOpen(false)} actionRender={null} title={`Import ${type}`}> @@ -74,7 +75,7 @@ export function ImportMessage({ type, onChange }: ImportMessageDialogProps) { - 导入格式 + {$t('导入格式')}
{example}
@@ -86,16 +87,16 @@ export function ImportMessage({ type, onChange }: ImportMessageDialogProps) {
diff --git a/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiRequestTester/TestBody/const.ts b/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiRequestTester/TestBody/const.ts index 7c8d7f3c..851a3a19 100644 --- a/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiRequestTester/TestBody/const.ts +++ b/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiRequestTester/TestBody/const.ts @@ -9,23 +9,23 @@ export const MimeTypes: { value: ContentType }[] = [ { - title: 'Text', + title:'Text', value: 'text/plain' }, { - title: 'JSON', + title:'JSON', value: 'application/json' }, { - title: 'XML', + title:'XML', value: 'application/xml' }, { - title: 'HTML', + title:'HTML', value: 'text/html' }, { - title: 'JavaScript', + title:'JavaScript', value: 'application/javascript' } ] @@ -35,11 +35,11 @@ export const FormContentTypes: { value: ContentType }[] = [ { - title: 'x-www-form-urlencoded', + title:'x-www-form-urlencoded', value: 'application/x-www-form-urlencoded' }, { - title: 'multipart/form-data', + title:'multipart/form-data', value: 'multipart/form-data' } ] \ No newline at end of file diff --git a/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiRequestTester/index.tsx b/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiRequestTester/index.tsx index f07cfc9e..f456040c 100644 --- a/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiRequestTester/index.tsx +++ b/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiRequestTester/index.tsx @@ -17,6 +17,7 @@ import { ImportMessage, ImportMessageChangeType, ImportMessageOption } from './I import {ApiBodyType, ApiDetail, ParseCurlResult, TestApiBodyType} from "@common/const/api-detail"; import {TestMessageDataGrid, TestMessageDataGridApi} from "../TestMessageDataGrid"; import {Indicator} from "../../../../Indicator"; +import { $t } from '@common/locales' export interface ApiRequestTesterApi { getEditMeta: () => { @@ -113,13 +114,13 @@ export function ApiRequestTester({ apiRef, onQueryChange ,apiInfo, loaded=true}: ) const handleImportChange = (changeType: ImportMessageChangeType, data: ImportMessageOption[]) => { - tabValue === '请求头' && headersApiRef.current?.importData(changeType, data) - tabValue === 'Query 参数' && queryApiRef.current?.importData(changeType, data) + tabValue === $t('请求头') && headersApiRef.current?.importData(changeType, data) + tabValue === $t('Query 参数') && queryApiRef.current?.importData(changeType, data) } const tabs = [ { - label: '请求头', + label: $t('请求头'), element: ( , dirty: false }, { - label: 'Query 参数', + label: $t('Query 参数'), element: ( , dirty: false } diff --git a/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiResponse/components/ResponseIndicator.tsx b/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiResponse/components/ResponseIndicator.tsx index 31810380..543c361d 100644 --- a/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiResponse/components/ResponseIndicator.tsx +++ b/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiResponse/components/ResponseIndicator.tsx @@ -1,6 +1,7 @@ import { Box, Chip, Typography } from '@mui/material' import {IconButton} from "../../../../IconButton"; import {byteToString} from "@common/utils/postcat.tsx"; +import { $t } from '@common/locales'; interface ResponseIndicatorProps { statusCode: number @@ -14,12 +15,12 @@ export function ResponseIndicator({ statusCode, size, time, onDownload }: Partia {statusCode}} /> - 大小: {byteToString(size || 0)} + {$t('大小')}: {byteToString(size || 0)} - 时间: {time} ms + {$t('时间')}: {time} ms - + ) : null } diff --git a/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiResponse/index.tsx b/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiResponse/index.tsx index 406d84d2..1c0d1793 100644 --- a/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiResponse/index.tsx +++ b/frontend/packages/common/src/components/postcat/api/ApiTest/components/ApiResponse/index.tsx @@ -6,6 +6,7 @@ import { HeaderPreview } from './components/HeaderPreview' import { ResponseIndicator } from './components/ResponseIndicator' import {TestResponse} from "@common/hooks/useTest.ts"; import {downloadFile} from "@common/utils/download.ts"; +import { $t } from '@common/locales' type TabType = 'Response' | 'Response Headers' | 'Body' | 'Request Headers' @@ -16,12 +17,12 @@ interface ApiResponseProps { export function ApiResponse({ data }: ApiResponseProps) { const tabHeight = 30 const theme = useTheme() - const [tabValue, setTabValue] = useState('Response') - const handleTabValueChange = (_evt: SyntheticEvent, value: TabType): void => { + const handleTabValueChange = useCallback((_evt: SyntheticEvent, value: TabType): void => { setTabValue(value) - } + },[]) + const response = data?.report.response const handleDownload = useCallback(() => { @@ -42,7 +43,7 @@ export function ApiResponse({ data }: ApiResponseProps) { const response = data?.report.response return [ { - title: '响应', + title: $t('响应'), name: 'Response', hidden: false, element: ( @@ -57,19 +58,19 @@ export function ApiResponse({ data }: ApiResponseProps) { ) }, { - title: '响应头', + title: $t('响应头'), name: 'Response Headers', hidden: !response?.headers.length, element: }, { - title:'正文', + title:$t('正文'), name: 'Body', hidden: !request?.body.length, element: }, { - title: '请求头', + title: $t('请求头'), name: 'Request Headers', hidden: !request?.headers.length, element: diff --git a/frontend/packages/common/src/components/postcat/api/ApiTest/components/TestControl/index.tsx b/frontend/packages/common/src/components/postcat/api/ApiTest/components/TestControl/index.tsx index 6125233f..6bb0ea50 100644 --- a/frontend/packages/common/src/components/postcat/api/ApiTest/components/TestControl/index.tsx +++ b/frontend/packages/common/src/components/postcat/api/ApiTest/components/TestControl/index.tsx @@ -1,4 +1,5 @@ // import { TabRouteObject, useTabStore } from '@/stores/tab' +import { $t } from '@common/locales' import { Button, Typography } from '@mui/material' import { TouchRippleActions } from '@mui/material/ButtonBase/TouchRipple' import { useEffect, useRef, useState } from 'react' @@ -66,15 +67,15 @@ export function TestControl({ onTest, onAbort, loading }: TestControlProps) { <> {!loading ? ( ) : ( diff --git a/frontend/packages/common/src/components/postcat/api/ApiTest/components/TestMessageDataGrid/index.tsx b/frontend/packages/common/src/components/postcat/api/ApiTest/components/TestMessageDataGrid/index.tsx index 93da7881..79a447d4 100644 --- a/frontend/packages/common/src/components/postcat/api/ApiTest/components/TestMessageDataGrid/index.tsx +++ b/frontend/packages/common/src/components/postcat/api/ApiTest/components/TestMessageDataGrid/index.tsx @@ -27,6 +27,7 @@ import {Icon} from "../../../Icon"; import {ApiParamsTypeOptions} from "../../../ApiManager/components/ApiMessageBody/constants.ts"; import {UploadButton} from "../../../UploadButton"; import {isNil} from "lodash-es"; +import { $t } from '@common/locales/index.ts'; type SafeAny = unknown export interface RenderBodyParamsType extends BodyParamsType { @@ -171,7 +172,7 @@ export function TestMessageDataGrid(props: TestMessageDataGridProps | false)[] = [ messageType === 'Headers' && { field: 'name', - headerName: '标签', + headerName: $t('标签'), editable: true, sortable: false, renderEditCell: (params) => { @@ -214,7 +215,7 @@ export function TestMessageDataGrid(props: TestMessageDataGridProps { diff --git a/frontend/packages/common/src/components/postcat/api/Codebox/index.tsx b/frontend/packages/common/src/components/postcat/api/Codebox/index.tsx index 97d658d1..205585a1 100644 --- a/frontend/packages/common/src/components/postcat/api/Codebox/index.tsx +++ b/frontend/packages/common/src/components/postcat/api/Codebox/index.tsx @@ -5,6 +5,8 @@ import { Editor, useMonaco } from '@monaco-editor/react' import { type editor as MonacoEditor } from 'monaco-editor' import { IconButton } from '../IconButton' import { message } from 'antd' +import { $t } from '@common/locales' +import { RESPONSE_TIPS } from '@common/const/const' export interface CodeboxApiRef { insertCode: (value: string) => void @@ -126,7 +128,7 @@ export const Codebox = memo((props: CodeboxProps) => { const copyCode = async (): Promise => { if (editorRef.current) { await navigator.clipboard.writeText(editorRef.current.getValue()) - message.success('复制成功') + message.success(RESPONSE_TIPS.copySuccess) } } @@ -166,16 +168,16 @@ export const Codebox = memo((props: CodeboxProps) => { {extraContent} - 格式化 + {$t('格式化')} - 复制 + {$t('复制')} - 搜索 + {$t('搜索')} {!readOnly && - 替代 + {$t('替代')} } ) : null} diff --git a/frontend/packages/common/src/components/postcat/api/Dialog/base-dialog.tsx b/frontend/packages/common/src/components/postcat/api/Dialog/base-dialog.tsx index 71e650bd..c9196674 100644 --- a/frontend/packages/common/src/components/postcat/api/Dialog/base-dialog.tsx +++ b/frontend/packages/common/src/components/postcat/api/Dialog/base-dialog.tsx @@ -7,6 +7,7 @@ import { type ReactNode } from 'react' import type { LoadingButtonProps } from '@mui/lab' import { LoadingButton } from '@mui/lab' import {renderComponent} from "@common/utils/postcat.tsx"; +import { $t } from '@common/locales' export interface BaseDialogProps extends DialogActionProps { open: boolean @@ -56,9 +57,8 @@ interface DialogActionProps { export function DialogActions(props: DialogActionProps): JSX.Element { - const CancelText = '取消' - const ConfirmText = '确定' - + const CancelText = $t('取消') + const ConfirmText = $t('确定') const { onClose, confirmBtn, diff --git a/frontend/packages/common/src/components/postcat/api/MoreSetting/components/Example.tsx b/frontend/packages/common/src/components/postcat/api/MoreSetting/components/Example.tsx index e029950f..37702302 100644 --- a/frontend/packages/common/src/components/postcat/api/MoreSetting/components/Example.tsx +++ b/frontend/packages/common/src/components/postcat/api/MoreSetting/components/Example.tsx @@ -1,5 +1,6 @@ import { Box, Typography, useTheme } from '@mui/material' import {Codebox} from "../../Codebox"; +import { $t } from '@common/locales'; interface ExampleProps { code: string @@ -29,7 +30,7 @@ export function Example({ code, onChange, readOnly = false }: ExampleProps) { }} > - 示例 + {$t('示例')} { if (isNaN(minVal) || minVal < 0) { - return `The ${minLabel} must not be negative.` + return $t('The (0) must not be negative.', [minLabel]) } if (isNaN(maxVal) || maxVal < 0) { - return `The ${maxLabel} must not be negative.` + return $t('The (0) must not be negative.',[maxLabel]) } if (minVal > maxVal) { - return `The ${maxLabel} must be greater than or equal to the ${minLabel}.` + return $t('The (0) must be greater than or equal to the (1).',[maxLabel, minLabel]) } return null diff --git a/frontend/packages/common/src/components/postcat/api/MoreSetting/components/ParamPreview.tsx b/frontend/packages/common/src/components/postcat/api/MoreSetting/components/ParamPreview.tsx index 3b30c625..bcb3c2f5 100644 --- a/frontend/packages/common/src/components/postcat/api/MoreSetting/components/ParamPreview.tsx +++ b/frontend/packages/common/src/components/postcat/api/MoreSetting/components/ParamPreview.tsx @@ -2,6 +2,7 @@ import { Box } from '@mui/material' import { DataGridPro, GridColDef, useGridApiRef } from '@mui/x-data-grid-pro' import { useEffect, useMemo } from 'react' import {previewTableHoverSx } from '../../PreviewTable' +import { $t } from '@common/locales' interface ParamPreviewProps { name?: string @@ -48,17 +49,17 @@ export function ParamPreview(props: ParamPreviewProps) { const columns: GridColDef[] = [ { field: 'name', - headerName: '参数名', + headerName: $t('参数名'), width: 120 }, { field: 'type', - headerName: '类型', + headerName: $t('类型'), width: 120 }, { field: 'required', - headerName: '必需', + headerName: $t('必需'), sortable: false, valueGetter: (params) => Boolean(params.row.isRequired), type: 'boolean', @@ -66,7 +67,7 @@ export function ParamPreview(props: ParamPreviewProps) { }, { field: 'description', - headerName: '描述', + headerName: $t('描述'), flex: 1 } ] diff --git a/frontend/packages/common/src/components/postcat/api/MoreSetting/components/ValueEnum.tsx b/frontend/packages/common/src/components/postcat/api/MoreSetting/components/ValueEnum.tsx index 98d540b3..22e64a25 100644 --- a/frontend/packages/common/src/components/postcat/api/MoreSetting/components/ValueEnum.tsx +++ b/frontend/packages/common/src/components/postcat/api/MoreSetting/components/ValueEnum.tsx @@ -13,6 +13,7 @@ import {IconButton} from "../../IconButton"; import {flattenTree, generateId, getActionColWidth} from "@common/utils/postcat.tsx"; import {EditableDataGridSx} from "../../ApiManager/components/EditableDataGrid"; import { commonTableSx } from '@common/const/api-detail/index.ts'; +import { $t } from '@common/locales'; export interface ValueEnum { value: string @@ -97,7 +98,7 @@ export function ValueEnum({ data, apiRef,readOnly = false }: ValueEnumProps) { const columns: GridColDef[] = [ { field: 'value', - headerName: '值枚举', + headerName: $t('值枚举'), type: 'string', sortable: false, flex: 1, @@ -109,7 +110,7 @@ export function ValueEnum({ data, apiRef,readOnly = false }: ValueEnumProps) { ) } @@ -170,7 +171,7 @@ export function ValueEnum({ data, apiRef,readOnly = false }: ValueEnumProps) { if (renderRows.length <= 1) return [] return [ { handleRowDelete(params) diff --git a/frontend/packages/common/src/components/postcat/api/MoreSetting/index.tsx b/frontend/packages/common/src/components/postcat/api/MoreSetting/index.tsx index 4b7ac44c..04880a5c 100644 --- a/frontend/packages/common/src/components/postcat/api/MoreSetting/index.tsx +++ b/frontend/packages/common/src/components/postcat/api/MoreSetting/index.tsx @@ -9,6 +9,7 @@ import { ParamLimit } from './components/ParamLimit' import {ParamAttrType} from "@common/const/api-detail"; import { BaseDialog} from "../Dialog/base-dialog.tsx"; import {ApiParamsTypeOptions} from "../ApiManager/components/ApiMessageBody/constants.ts"; +import { $t } from '@common/locales/index.ts' interface MoreSettingProps { open: boolean @@ -77,7 +78,7 @@ export function MoreSetting({ open, readOnly,onClose, param, onChange, hiddenCon } return ( - + ) : null} @@ -99,8 +100,8 @@ export function MoreSetting({ open, readOnly,onClose, param, onChange, hiddenCon ) : null} diff --git a/frontend/packages/common/src/components/postcat/api/Upload/index.tsx b/frontend/packages/common/src/components/postcat/api/Upload/index.tsx index ffff6448..9326362c 100644 --- a/frontend/packages/common/src/components/postcat/api/Upload/index.tsx +++ b/frontend/packages/common/src/components/postcat/api/Upload/index.tsx @@ -4,6 +4,7 @@ import { useDropzone } from 'react-dropzone' import { useAutoAnimate } from '@formkit/auto-animate/react' import { Icon } from '../Icon' import { IconButton } from '../IconButton' +import { $t } from '@common/locales' export interface UploadProps { value?: File | null @@ -48,7 +49,7 @@ export function Upload({ value, onChange }: UploadProps): JSX.Element { - {'将文件拖拽至此处上传,或点击选择文件上传'} + {$t('将文件拖拽至此处上传,或点击选择文件上传')} {value ? ( diff --git a/frontend/packages/common/src/components/postcat/api/UploadButton/index.tsx b/frontend/packages/common/src/components/postcat/api/UploadButton/index.tsx index e34b7f7a..7690db12 100644 --- a/frontend/packages/common/src/components/postcat/api/UploadButton/index.tsx +++ b/frontend/packages/common/src/components/postcat/api/UploadButton/index.tsx @@ -2,6 +2,7 @@ import { Box, Button, Typography } from '@mui/material' import type { ChangeEvent } from 'react' import { useRef } from 'react' import {file2Base64} from "@common/utils/postcat.tsx"; +import { $t } from '@common/locales'; interface UploadButtonProps { value?: @@ -42,9 +43,9 @@ export function UploadButton({ value, onChange }: UploadButtonProps): JSX.Elemen - {value?.length ? Files Selected: {value.length} : null} + {value?.length ? {$t('Files Selected')}: {value.length} : null} ) } diff --git a/frontend/packages/common/src/const/api-detail/index.ts b/frontend/packages/common/src/const/api-detail/index.ts index 74739155..1b1f4fd1 100644 --- a/frontend/packages/common/src/const/api-detail/index.ts +++ b/frontend/packages/common/src/const/api-detail/index.ts @@ -9,34 +9,6 @@ export interface MenuItem { content?: unknown } -export const GetMenuItem = (org_domain_id: string, project_domain_id: string, commonQuestionRes: unknown) => { - const Menus = [ - { key: 'introduction', name: '介绍', emoji: '📃', path: `/${org_domain_id}/api/${project_domain_id}/introduction` }, - { key: 'apiDocument', name: 'API 文档', emoji: '🔗', path: `/${org_domain_id}/api/${project_domain_id}/apiDocument` }, - { key: 'price', name: '价格套餐', emoji: '💎', path: `/${org_domain_id}/api/${project_domain_id}/price` }, - { key: 'guidence', name: '接入指南', emoji: '💡', path: `/${org_domain_id}/api/${project_domain_id}/guidence` } - ]; - - if (commonQuestionRes?.success && commonQuestionRes?.data?.content) { - Menus.splice(2, 0, { key: 'commonQuestion', name: '常见问题', emoji: '🌷', path: `/${org_domain_id}/api/${project_domain_id}/commonQuestion` }); - } - - return Menus; -}; - - -export const SKU_LIST = [ - { - name: '流量包', - key: 'flow' - }, - { - name: '订阅套餐', - key: 'subscribe' - } -] - -export const PROMISE_TEXT = ['服务保障', '未使用部分七天无理由退款', '正规企业商品来源', '交易流程全程监控'] export const DATA_TYPE = { JSON: '[json]', diff --git a/frontend/packages/common/src/const/approval/const.tsx b/frontend/packages/common/src/const/approval/const.tsx index 859660df..0f8eea2f 100644 --- a/frontend/packages/common/src/const/approval/const.tsx +++ b/frontend/packages/common/src/const/approval/const.tsx @@ -1,13 +1,14 @@ -import {ProColumns} from "@ant-design/pro-components"; import { ApprovalTableListItem, PublishTableListItem } from "./type"; import { Tooltip } from "antd"; +import { $t } from "@common/locales"; +import { PageProColumns } from "@common/components/aoplatform/PageList"; export const TODO_LIST_COLUMN_NOT_INCLUDE_KEY:string[] = ['status','approver','approvalTime'] -export const SUBSCRIBE_APPROVAL_TABLE_COLUMN : ProColumns[] = [ +export const SUBSCRIBE_APPROVAL_TABLE_COLUMN : PageProColumns[] = [ { - title: '申请时间', + title:$t('申请时间'), dataIndex: 'applyTime', ellipsis:true, width:182, @@ -17,44 +18,44 @@ export const SUBSCRIBE_APPROVAL_TABLE_COLUMN : ProColumns }, }, { - title: '申请方-应用', + title:$t('申请方-应用'), dataIndex: ['application','name'], ellipsis:true }, { - title: '申请服务', + title:$t('申请服务'), dataIndex: ['service','name'], ellipsis:true }, { - title: '服务所属系统', + title:$t('服务所属系统'), dataIndex: ['service','name'], ellipsis:true }, { - title: '服务所属团队', + title:$t('服务所属团队'), dataIndex: ['team','name'], ellipsis:true }, { - title: '审批状态', + title:$t('审批状态'), dataIndex: 'status', valueType: 'text', }, { - title: '申请人', + title:$t('申请人'), dataIndex: ['applier','name'], ellipsis: true, width:88, }, { - title: '审批人', + title:$t('审批人'), dataIndex: ['approver','name'], ellipsis: true, width:88 }, { - title: '审批时间', + title:$t('审批时间'), dataIndex: 'approvalTime', ellipsis: true, // sorter: true,, @@ -65,9 +66,9 @@ export const SUBSCRIBE_APPROVAL_TABLE_COLUMN : ProColumns }, ]; -export const SUBSCRIBE_APPROVAL_INNER_TODO_TABLE_COLUMN : ProColumns[] = [ +export const SUBSCRIBE_APPROVAL_INNER_TODO_TABLE_COLUMN : PageProColumns[] = [ { - title: '申请时间', + title:$t('申请时间'), dataIndex: 'applyTime', // sorter: true, ellipsis:true, @@ -78,13 +79,13 @@ export const SUBSCRIBE_APPROVAL_INNER_TODO_TABLE_COLUMN : ProColumns申请人
, + // title:$t('申请人', + title: {$t('申请人')}, dataIndex: ['applier','name'], ellipsis: true, filters: true, @@ -93,16 +94,16 @@ export const SUBSCRIBE_APPROVAL_INNER_TODO_TABLE_COLUMN : ProColumns[] = [ +export const SUBSCRIBE_APPROVAL_INNER_DONE_TABLE_COLUMN : PageProColumns[] = [ { - title: '申请时间', + title:$t('申请时间'), dataIndex: 'applyTime', // sorter: true, ellipsis:true, @@ -113,13 +114,13 @@ export const SUBSCRIBE_APPROVAL_INNER_DONE_TABLE_COLUMN : ProColumns申请人, + // title:$t('申请人', + title: {$t('申请人')}, dataIndex: ['applier','name'], ellipsis: true, filters: true, @@ -128,24 +129,24 @@ export const SUBSCRIBE_APPROVAL_INNER_DONE_TABLE_COLUMN : ProColumns拒绝], - [2,通过], + [0, {$t('拒绝')}], + [2,{$t('通过')}], ]), }, { - title: '审批人', + title:$t('审批人'), dataIndex: ['approver','name'], ellipsis: true, width:88, @@ -155,7 +156,7 @@ export const SUBSCRIBE_APPROVAL_INNER_DONE_TABLE_COLUMN : ProColumns( + + + {ChangeTypeEnum[entity.change as (keyof typeof ChangeTypeEnum)] || '-'} + {entity.change === 'error' ?$t('该 API 缺失(0)(1)(2)请先补充',[entity.proxyStatus == 1 && $t('转发信息,'),entity.docStatus == 1 && $t('文档信息,'),entity.upstreamStatus == 1 && $t('上游信息,')]):''} + + ) + + } +] + +export const ApprovalUpstreamColumns = [ + { + title:$t('上游类型'), + dataIndex:'type', + ellipsis:true, + valueEnum:{ + 'static':{ + text:$t('静态上游') + } + } + }, + { + title:$t('地址'), + dataIndex:'addr', + render:(text:string[])=>(<>{text.join(',')}), + ellipsis:true + }, + { + title:$t('类型'), + dataIndex:'change', + render:(_,entity)=>( + + {ChangeTypeEnum[entity.change as (keyof typeof ChangeTypeEnum)] || '-'} + {entity.change === 'error' ?$t('该 API 缺失(0)(1)(2)请先补充',[entity.proxyStatus == 1 && $t('转发信息,'),entity.docStatus == 1 && $t('文档信息,'),entity.upstreamStatus == 1 && $t('上游信息,')]):''} + ) + } +] + +const PublishStatusEnum = { + 'apply': $t('待审批'), + 'accept' : $t('审批通过'), + 'done' : $t('已发布'), + 'stop': $t('发布终止'), + 'close': $t('已关闭'), + 'refuse' : $t('已拒绝'), + 'error' : $t('发布异常'), + 'publishing' : $t('发布中') } -export const PUBLISH_APPROVAL_VERSION_INNER_TABLE_COLUMN : ProColumns[] = [ +export const PUBLISH_APPROVAL_VERSION_INNER_TABLE_COLUMN : PageProColumns[] = [ { - title: '发布版本', + title:$t('发布版本'), dataIndex: 'version', ellipsis:true, width:160, fixed:'left' }, { - title: '版本说明', + title:$t('版本说明'), dataIndex: 'remark', ellipsis:true }, { - title: '创建版本时间', + title:$t('创建版本时间'), dataIndex: 'createTime', ellipsis:true, sorter: (a,b)=> { @@ -243,7 +310,7 @@ export const PUBLISH_APPROVAL_VERSION_INNER_TABLE_COLUMN : ProColumns[] = [ +export const PUBLISH_APPROVAL_RECORD_INNER_TABLE_COLUMN : PageProColumns[] = [ { - title: '申请时间', + title:$t('申请时间'), dataIndex: 'applyTime', ellipsis:true, width:182, fixed:'left', }, { - title: '审核时间', + title:$t('审核时间'), dataIndex: 'approveTime', ellipsis:true, width:182, }, { - title: '版本号', + title:$t('版本号'), dataIndex: 'version', ellipsis:true }, { - title: '版本说明', + title:$t('版本说明'), dataIndex: 'remark', ellipsis:true }, { - title: '发布状态', + title:$t('发布状态'), dataIndex: 'status', ellipsis:true, valueEnum:new Map([ @@ -311,12 +378,12 @@ export const PUBLISH_APPROVAL_RECORD_INNER_TABLE_COLUMN : ProColumns[] = [ +export const PUBLISH_APPROVAL_TABLE_COLUMN : PageProColumns[] = [ { - title: '申请时间', + title:$t('申请时间'), dataIndex: 'applyTime', ellipsis:true, width:182, @@ -349,17 +416,17 @@ export const PUBLISH_APPROVAL_TABLE_COLUMN : ProColumns[] }, }, { - title: '申请系统', + title:$t('申请系统'), dataIndex: ['service','name'], ellipsis:true }, { - title: '所属团队', + title:$t('所属团队'), dataIndex: ['team','name'], ellipsis:true }, { - title: '审批状态', + title:$t('审批状态'), dataIndex: 'status', ellipsis:{ showTitle:true @@ -369,7 +436,7 @@ export const PUBLISH_APPROVAL_TABLE_COLUMN : ProColumns[] valueType: 'select', }, { - title: '申请人', + title:$t('申请人'), dataIndex: ['applier','name'], ellipsis: true, width:88, @@ -379,7 +446,7 @@ export const PUBLISH_APPROVAL_TABLE_COLUMN : ProColumns[] filterSearch: true, }, { - title: '审批人', + title:$t('审批人'), dataIndex: ['approver','name'], ellipsis: true, width:88, @@ -389,7 +456,7 @@ export const PUBLISH_APPROVAL_TABLE_COLUMN : ProColumns[] filterSearch: true, }, { - title: '审批时间', + title:$t('审批时间'), dataIndex: 'approvalTime', // sorter: true, ellipsis:true, @@ -400,3 +467,42 @@ export const PUBLISH_APPROVAL_TABLE_COLUMN : ProColumns[] }, }, ]; + +export const ChangeTypeEnum = { + 'new': $t('新增'), + 'update': $t('变更'), + 'delete' : $t('删除'), + 'none' : $t('无变更'), + 'error' : $t('缺失字段') +} +// export const APPROVAL_I18NEXT_FOR_ENUM = { +// [SubscribeEnum.Rejected]:$t('驳回'), +// [SubscribeEnum.Reviewing]:$t('审核中'), +// [SubscribeEnum.Subscribed]:$t('已订阅'), +// [SubscribeEnum.Unsubscribed]:$t('取消订阅'), +// [SubscribeEnum.CancelRequest]:$t('取消申请'), +// [SubscribeFromEnum.manual]:$t('手动添加'), +// [SubscribeFromEnum.subscribe]:$t('订阅申请'), +// } + + +export const SubscribeApprovalList = [ + { + title:$t('申请方应用'),key:'application' + }, + { + title:$t('申请方所属团队'),key:'applyTeam' + }, + { + title:$t('申请人'),key:'applier' + }, + { + title:$t('申请时间'),key:'applyTime' + }, + { + title:$t('申请服务'),key:'service' + }, + { + title:$t('服务所属团队'),key:'team' + } +] \ No newline at end of file diff --git a/frontend/packages/common/src/const/approval/type.tsx b/frontend/packages/common/src/const/approval/type.tsx index 8e0a7d9f..4a7c3d6d 100644 --- a/frontend/packages/common/src/const/approval/type.tsx +++ b/frontend/packages/common/src/const/approval/type.tsx @@ -100,4 +100,20 @@ export type PublishTableListItem = { service:EntityItem team:EntityItem status:keyof typeof PublishApplyStatusEnum +} + + +export type PublishApprovalModalProps = { + type:'approval'|'view'|'add'|'publish'|'online' + data:PublishApprovalInfoType | PublishApprovalInfoType &{id?:string} | PublishVersionTableListItem + insideSystem?:boolean + serviceId:string + teamId:string + clusterPublishStatus?:SystemInsidePublishOnlineItems[] +} + +export type PublishApprovalModalHandle = { + save:(operate:'pass'|'refuse') =>Promise + publish:(notSave?:boolean)=>Promise> + online:()=>Promise } \ No newline at end of file diff --git a/frontend/packages/common/src/const/code/const.ts b/frontend/packages/common/src/const/code/const.ts index 87f15a96..59529460 100644 --- a/frontend/packages/common/src/const/code/const.ts +++ b/frontend/packages/common/src/const/code/const.ts @@ -1,3 +1,5 @@ +import { $t } from "@common/locales" + const CODE_LANG = [ { label: 'Java(OK HTTP)', @@ -68,7 +70,7 @@ const CODE_LANG = [ ] }, { - label: '微信小程序', + label: $t('微信小程序'), value: 21 }, // { diff --git a/frontend/packages/common/src/const/const.ts b/frontend/packages/common/src/const/const.ts deleted file mode 100644 index b7937e72..00000000 --- a/frontend/packages/common/src/const/const.ts +++ /dev/null @@ -1,20 +0,0 @@ - -export type BasicResponse = { - code:number - data:T - msg:string -} - - -export const STATUS_CODE = { - SUCCESS:0, - UNANTHORIZED:401, - FORBIDDEN:403 -} - -export const STATUS_COLOR = { - 'done':'text-[#03a9f4]', - 'error':'text-[#ff3b30]' -} - -const NAV_HEIGHT = 72 \ No newline at end of file diff --git a/frontend/packages/common/src/const/const.tsx b/frontend/packages/common/src/const/const.tsx new file mode 100644 index 00000000..8bec4469 --- /dev/null +++ b/frontend/packages/common/src/const/const.tsx @@ -0,0 +1,71 @@ +import { $t } from "@common/locales" + +export type BasicResponse = { + code:number + data:T + msg:string +} + + +export const STATUS_CODE = { + SUCCESS:0, + UNANTHORIZED:401, + FORBIDDEN:403 +} + +export const STATUS_COLOR = { + 'done':'text-[#03a9f4]', + 'error':'text-[#ff3b30]' +} + + +// avoid changing route within ths same category +export const routerKeyMap = new Map([ + ['workspace',['tenantManagement','service','team','serviceHub']], + ['my',['tenantManagement','service','team']], + ['mainPage',['dashboard','systemrunning']], + ['operationCenter',['member','user','role','servicecategories']], + ['organization',['member','user','role']], + ['serviceHubSetting',['servicecategories']], + ['maintenanceCenter',['partition','logsettings','resourcesettings','openapi'] + ]]) + + + export const COLUMNS_TITLE = { + operate : $t('操作') + } + + export const VALIDATE_MESSAGE = { + required: $t('必填项'), + email:$t('不是有效邮箱地址') + } + + export const PLACEHOLDER = { + input:$t('请输入'), + select:$t('请选择'), + startWithAlphabet:$t('英文数字下划线任意一种,首字母必须为英文'), + specialStartWithAlphabet:$t('支持字母开头、英文数字中横线下划线组合') + } + + export const FORM_ERROR_TIPS = { + refuseOpinion: $t('选择拒绝时,审批意见为必填'), + clusterTest:$t('无法连接集群,请检查集群地址是否正确或防火墙配置'), + + } + + export const RESPONSE_TIPS = { + success: $t('操作成功'), + error: $t('操作失败'), + operating:$t('正在操作'), + loading:$t('正在加载数据'), + dataError:$t('获取数据失败'), + loginSuccess: $t('登录成功'), + logoutSuccess:$t('退出成功,将跳转至登录页'), + refuseOpinion: $t('未填写审核意见'), + copySuccess:$t('复制成功'), + copyError:$t('复制失败,请手动复制') + } + + export const DELETE_TIPS = { + default:$t('该数据删除后将无法找回,请确认是否删除?') + } \ No newline at end of file diff --git a/frontend/packages/common/src/const/type.ts b/frontend/packages/common/src/const/type.ts index 9f9c4f7e..1ea206cc 100644 --- a/frontend/packages/common/src/const/type.ts +++ b/frontend/packages/common/src/const/type.ts @@ -63,8 +63,8 @@ export type SimpleTeamItem = { } export type MatchItem = { - position:MatchPositionEnum - matchType:MatchTypeEnum + position:typeof MatchPositionEnum + matchType:typeof MatchTypeEnum key:string pattern:string id?:string diff --git a/frontend/packages/common/src/contexts/GlobalStateContext.tsx b/frontend/packages/common/src/contexts/GlobalStateContext.tsx index d9c0480f..0ab3888c 100644 --- a/frontend/packages/common/src/contexts/GlobalStateContext.tsx +++ b/frontend/packages/common/src/contexts/GlobalStateContext.tsx @@ -1,7 +1,7 @@ import {createContext, Dispatch, FC, ReactNode, useContext, useReducer, useState} from "react"; import { useFetch } from "@common/hooks/http"; import { App } from "antd"; -import { BasicResponse, STATUS_CODE } from "@common/const/const"; +import { BasicResponse, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const"; import { checkAccess } from "@common/utils/permission"; import { PERMISSION_DEFINITION } from "@common/const/permissions"; @@ -11,31 +11,31 @@ interface GlobalState { version: string; updateDate: string; powered:string; - mainPage:string + mainPage:string; + language:string; } -// Define the shape of the user data interface UserData { username: string; - // Add other user-related fields as needed } -// Define actions for state updates -type Action = +export type GlobalAction = | { type: 'LOGIN'} | { type: 'LOGOUT' } | { type: 'UPDATE_USERDATA'; userData: UserData } | { type: 'UPDATE_VERSION'; version: string } | { type: 'UPDATE_DATE'; updateDate: string } | { type: 'UPDATE_POWER'; powered: string } - | { type: 'UPDATE_MAIN_PAGE'; mainPage: string }; + | { type: 'UPDATE_MAIN_PAGE'; mainPage: string } + | { type: 'UPDATE_LANGUAGE'; language: string } + /* 存储用户登录、信息、权限等数据 */ -const GlobalContext = createContext<{ +export const GlobalContext = createContext<{ state: GlobalState; - dispatch: Dispatch; + dispatch: Dispatch; accessData:Map; pluginAccessDictionary:{[k:string]:string}; getGlobalAccessData:()=>void; @@ -49,8 +49,7 @@ const GlobalContext = createContext<{ } | undefined>(undefined); -// Define a reducer function to handle state updates -const globalReducer = (state: GlobalState, action: Action): GlobalState => { +const globalReducer = (state: GlobalState, action: GlobalAction): GlobalState => { switch (action.type) { case 'LOGIN': return { @@ -88,6 +87,11 @@ const globalReducer = (state: GlobalState, action: Action): GlobalState => { ...state, mainPage: action.mainPage, }; + case 'UPDATE_LANGUAGE': + return { + ...state, + language: action.language, + }; default: return state; } @@ -103,7 +107,8 @@ export const GlobalProvider: FC<{children:ReactNode}> = ({ children }) => { version: '1.0.0', updateDate: '2024-07-01', powered:'Powered by https://apipark.com', - mainPage:'/service/list' + mainPage:'/service/list', + language:'en' }); const [accessData,setAccessData] = useState>(new Map()) const [pluginAccessDictionary, setPluginAccessDictionary] = useState<{[k:string]:string}>({}) @@ -119,8 +124,8 @@ export const GlobalProvider: FC<{children:ReactNode}> = ({ children }) => { setAccessData(prevData => new Map(prevData).set('system', data.access)) resolve(data.response) }else{ - message.error(msg || '操作失败') - reject(data.msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(data.msg || RESPONSE_TIPS.error) } }) ) @@ -134,7 +139,7 @@ export const GlobalProvider: FC<{children:ReactNode}> = ({ children }) => { setAccessData(prevData => new Map(prevData).set('team', data.access)) setTeamDataFlushed(true) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }) } diff --git a/frontend/packages/common/src/hooks/copy.ts b/frontend/packages/common/src/hooks/copy.ts index fff54b98..e39352d8 100644 --- a/frontend/packages/common/src/hooks/copy.ts +++ b/frontend/packages/common/src/hooks/copy.ts @@ -1,10 +1,5 @@ -/* - * @Name: - * @Description: - * @Copyright: 广州银云信息科技有限公司 - * @LastEditors: maggieyyy - * @LastEditTime: 2024-05-10 16:38:56 - */ + +import { RESPONSE_TIPS } from '@common/const/const'; import { message } from 'antd'; import { useEffect, useState } from 'react'; @@ -14,7 +9,7 @@ const useCopyToClipboard = () => { const copyToClipboard = (text: string) => { if (navigator.clipboard && window.isSecureContext) { navigator.clipboard.writeText(text)?.then(() => { - message.success('复制成功') + message.success(RESPONSE_TIPS.copySuccess) setIsCopied(true) }) .catch((error) => { @@ -34,7 +29,7 @@ const useCopyToClipboard = () => { textArea.select(); new Promise((resolve, reject) => { if(document.execCommand('copy')) { - message.success('复制成功') + message.success(RESPONSE_TIPS.copySuccess) setIsCopied(true) resolve() } else { diff --git a/frontend/packages/common/src/hooks/excel.ts b/frontend/packages/common/src/hooks/excel.ts index c53a7d76..dc020e43 100644 --- a/frontend/packages/common/src/hooks/excel.ts +++ b/frontend/packages/common/src/hooks/excel.ts @@ -2,12 +2,13 @@ import * as ExcelJS from 'exceljs'; import { saveAs } from 'file-saver'; import { ProColumnType } from '@ant-design/pro-components'; +import { $t } from '@common/locales'; export const useExcelExport = () => { const createExcel = (sheetTitle: string, columns: ExcelJS.Column[], tableData: T[]) => { const workBook = new ExcelJS.Workbook() - const sheet = workBook.addWorksheet(sheetTitle || '默认工作表'); + const sheet = workBook.addWorksheet(sheetTitle || $t('默认工作表')); sheet.columns = columns; sheet.addRows(tableData); return workBook @@ -47,7 +48,7 @@ export const useExcelExport = () => { const getFileName = (fileTitle: string, date: [number, number]): string => { const [start, end] = date.map((time) => getDateFormat(time)); - return `${fileTitle}-${start}至${end}`; + return `${fileTitle}-${start}${$t('至')}${end}`; }; const getDateFormat = (time: number): string => { diff --git a/frontend/packages/common/src/locales/index.ts b/frontend/packages/common/src/locales/index.ts new file mode 100644 index 00000000..c4899f1d --- /dev/null +++ b/frontend/packages/common/src/locales/index.ts @@ -0,0 +1,57 @@ +import i18n from 'i18next'; +import { initReactI18next, useTranslation } from 'react-i18next'; +// i18next-browser-languagedetector插件 这是一个 i18next 语言检测插件,用于检测浏览器中的用户语言, +import LanguageDetector from 'i18next-browser-languagedetector'; +import crc32 from 'crc/crc32'; +// 引入需要实现国际化的简体、繁体、英文三种数据的json文件 +import zhCN from 'antd/locale/zh_CN'; +import enGB from 'antd/locale/en_GB'; +import localZh_CN from './scan/zh-CN.json'; // 本地翻译中文文件 +import localEn_GB from './scan/en-GB.json'; // 本地翻译英文文件 +// import config from '../../../../i18next-scanner.config.js'; + +const resources = { + cn: { + translation: localZh_CN, + ...zhCN + }, + en: { + translation: localEn_GB, + ...enGB + } +}; + +i18n + .use(LanguageDetector) // 嗅探当前浏览器语言 zh-CN + .use(initReactI18next) // 将 i18n 向下传递给 react-i18next + .init({ + // 初始化 + resources, // 本地多语言数据 + // fallbackLng: config.lang, // 默认当前环境的语言 + detection: { + caches: ['localStorage', 'sessionStorage', 'cookie'] + } + }); + +// --------这里是i18next-scanner新增的配置------------- +export const $t = (key: string, params?: any[]): string => { + const hashKey = `K${crc32(key).toString(16)}`; // 将中文转换成crc32格式去匹配对应的json语言包 + let words = i18n.t(hashKey); + // const { t } = useTranslation(); // 通过hooks + // let words = t(hashKey); + if (words === hashKey) { + words = key; + } + + // 配置传递参数的场景, 目前仅支持数组,可在此拓展 + if (Array.isArray(params)) { + const reg = /\((\d)\)/g; + words = words.replace(reg, (a: string, b: number) => { + return params[b]; + }); + } + return words; +}; + +export default i18n; + diff --git a/frontend/packages/common/src/locales/scan/en-GB.json b/frontend/packages/common/src/locales/scan/en-GB.json new file mode 100644 index 00000000..b7a24ee0 --- /dev/null +++ b/frontend/packages/common/src/locales/scan/en-GB.json @@ -0,0 +1,570 @@ +{ + "Kc0e5ef9f": "workspace", + "K48325b6": "Search for (0) names", + "K3d7465f7":"file log", + "K3863c722": "我的", + "Kfe93ef35": "应用", + "Kb58e0c3f": "服务", + "Kc9e489f5": "团队", + "K61c89f5f": "API 市场", + "K16d71239": "仪表盘", + "K714c192d": "运行视图", + "Kd57dfe97": "系统拓扑图", + "K3fe97dcc": "系统设置", + "K67ef3525": "组织", + "K74aef1ad": "成员", + "Kf644225f": "角色", + "K958da71f": "服务分类管理", + "Kf270ca55": "运维与集成", + "Ke93d36ed": "集群", + "K481e8a05": "证书", + "Kca53edd0": "日志", + "Kb283e720": "资源", + "K631d646f": "Open API", + "K6535ff9c": "账号设置", + "Kf15499b4": "退出登录", + "Kabbd6e6": "文档", + "K1196b104": "APIPark - 企业API数据开放平台", + "K1f42de3": "HTTP 状态码", + "K4770dff4": "系统状态码", + "Kf89e58f1": "描述", + "K9e53c664": "提交", + "Kf8e7294c": "上一步", + "Ka0451c97": "取消", + "Kb1dedda3": "关闭", + "Kb2fc7600": "添加配置", + "K4e07217d": "编辑配置", + "K4ea968fe": "编辑(0)", + "Ka7aaaeb": "添加(0)", + "Kaff78ecf": "请输入Key", + "K65d46535": "请输入Value", + "Kc14b2ea3": "返回", + "K11d3633a": "ID", + "Kbff43de3": "名称", + "K16ca79ef": "Driver", + "K7a369eef": "已发布", + "Kcfa1a4d2": "下线", + "K771dc3b7": "上线", + "K530f5951": "查看", + "Kecbd7449": "删除", + "K1cbe2507": "确认", + "Ka1d885c1": "添加", + "Kad207008": "编辑", + "K1ff96ff": "申请系统", + "K9bf855d6": "所属团队", + "K11b994ed": "申请人", + "K939baba7": "申请时间", + "Kdab2e63b": "版本号", + "K8b29c460": "版本说明", + "K36a72ad1": "API 列表", + "K54e44357": "上游列表", + "Kb8e8e6f5": "备注", + "K1ab0ae5b": "申请原因", + "K53c00c3c": "审核意见", + "K7edf331d": "时间", + "Kef45b208": "近1小时", + "K9dbf22b8": "近24小时", + "K820fbfab": "近3天", + "Kd6d28fc": "近7天", + "K23fda291": "暂无操作权限,请联系管理员分配。", + "K4618cb0a": "微信小程序", + "Ka854f511": "获取文件,需填路径", + "Kaa11a695": "暂不支持生成非 HTTPS 或非 HTTP 协议的代码示例", + "Kbe46924e": "搜索编程语言...", + "Ke8e4f258": "编程语言", + "K29c07a47": "成功示例", + "K1f5c814d": "失败示例", + "K4ef022d7": "默认 text/html;charset=UTF-8", + "Kd061b5bf": "暂未填写示例", + "Kc14cec33": "Binary", + "K48b4d9e3": "请求头部", + "Kcd347eaf": "请求体", + "K9e100bfe": "Query 参数", + "K3e9f12fd": "REST 参数", + "K2bfa290c": "api request editor", + "Kb36d111a": "返回头部", + "K980bde79": "返回值", + "Kb04d201a": "更多设置", + "Kee74f5b4": "添加子参数", + "Kc7d3106c": "向下添加行", + "Keaabd222": "标签", + "K8ad2c50e": "参数名", + "K67d68dd1": "类型", + "K29245f47": "必需", + "Ke32cbcd3": "示例", + "Kc13936c6": "输入 URL 或 cURL", + "Ka1ede006": "HTTP", + "K152ac44e": "参数位置", + "K1660ae72": "匹配类型", + "K91ced765": "参数值", + "K5b265628": "操作类型", + "K1826982d": "新增或修改", + "Kd65b55f5": "匹配参数值", + "K15f35bf2": "转发上游路径", + "K79dec0dd": "请求超时时间", + "K7d465645": "绑定上游服务", + "K63a6404d": "重试时间", + "K47740727": "转发上游请求头", + "K2b605d42": "More", + "K1df9fbd5": "导入", + "K5e85df18": "导入格式", + "K9eaf7885": "全量替换", + "Kf8c3a80b": "在末端插入", + "Kd96b2d7d": "增量更新", + "Kf2fc08eb": "请求头", + "Ka45f1d8": "Rest 参数", + "K94bb113a": "大小", + "K359919b5": "另存为文件", + "K38bf1b90": "响应", + "K59f4186e": "响应头", + "K5f1e23fd": "正文", + "Kf404ef7d": "发送(Enter)", + "K2dbfd648": "中止", + "Kacabc771": "秒", + "K13ae6a93": "复制", + "Ke54a14a3": "格式化", + "K43934f6d": "搜索", + "K741decac": "替代", + "Kd507abff": "确定", + "Kca2d1624": "The (0) must not be negative.", + "K792b255a": "The (0) must be greater than or equal to the (1).", + "Kf0bed26d": "值枚举", + "K633a03ca": "枚举", + "Kd2766caf": "最小长度", + "Kd6d52485": "最大长度", + "Kea15f66c": "最小值", + "K1af340ff": "最大值", + "K68691e16": "将文件拖拽至此处上传,或点击选择文件上传", + "Kcec46ae": "Upload Files", + "K760fb044": "Files Selected", + "Kea2bdee0": "请填写接口名称", + "K49053438": "详细说明", + "K148f6fa4": "高级匹配", + "K3ae4c789": "转发配置", + "K2f4d0a37": "请求参数", + "Kde2d6dbd": "返回示例", + "K70e6069c": "测试 API", + "Ke4603448": "请求 Header", + "K89fd86b3": "请求 Body", + "K8747e3c4": "请求示例代码", + "K8613e6e7": "响应示例", + "Kab1c2159": "响应 Header", + "Kd2be51d1": "响应 Body", + "K831aa6c0": "申请方-应用", + "K58ca9485": "申请服务", + "K283f55b4": "服务所属系统", + "Kd60d204": "服务所属团队", + "K3a9a3b75": "审批状态", + "K4f57b2de": "审批人", + "K31dabc6b": "审批时间", + "K8582af3f": "拒绝", + "K54e27f57": "通过", + "K7eeca185": "审批完成", + "Kd4061161": "发布审批中", + "K823bfe63": "在线", + "K97ddb3f8": "-", + "Kc9315fa1": "已拒绝", + "K3fbe7511": "发布异常", + "Ke64e695c": "发布中", + "K17f93984": "API 名称", + "K1365fe45": "请求方式", + "Kc380335f": "路径", + "K4ee62e8": "该 API 缺失(0)(1)(2)请先补充", + "K385591f3": "转发信息,", + "K68415c14": "文档信息,", + "K133b75e9": "上游信息,", + "Kad98e030": "上游类型", + "Kdeed8399": "静态上游", + "K78b1ca25": "地址", + "K6208054": "待审批", + "K1be7f021": "审批通过", + "K677a4959": "发布终止", + "Kfd6d2d3d": "已关闭", + "K9d7e880a": "发布版本", + "K855135f": "创建版本时间", + "Kcbf39b82": "版本状态", + "K339d15b5": "创建人", + "K7194cea2": "审核时间", + "K69827c60": "发布状态", + "K1644b775": "新增", + "K4fdf4dcc": "变更", + "K33d66e26": "无变更", + "K9b70c007": "缺失字段", + "Kd85208a3": "驳回", + "K8adf7f8b": "审核中", + "Kad6aa439": "已订阅", + "K3118fdb0": "取消订阅", + "K9a68443b": "取消申请", + "K18307d56": "手动添加", + "K705fe9f5": "订阅申请", + "Kbc96ebec": "申请方应用", + "K1f89176d": "申请方所属团队", + "Kfe731dfc": "操作", + "K71661ee8": "必填项", + "Kcbee3f8": "不是有效邮箱地址", + "K442cfba1": "请输入", + "K3bb646e4": "请选择", + "Ka4ecfa40": "英文数字下划线任意一种,首字母必须为英文", + "K39686a7f": "支持字母开头、英文数字中横线下划线组合", + "K4d6a0190": "选择拒绝时,审批意见为必填", + "K37318b68": "无法连接集群,请检查集群地址是否正确或防火墙配置", + "K7f0c746d": "操作成功", + "K6a365d01": "操作失败", + "K978062b6": "正在操作", + "Kca7bd6d4": "正在加载数据", + "K3c93b77e": "获取数据失败", + "Ke108c369": "登录成功", + "K9168d3e": "退出成功,将跳转至登录页", + "K2f8a7ab7": "未填写审核意见", + "Kb858d78a": "复制成功", + "K26e85d15": "复制失败,请手动复制", + "K5cfdd950": "该数据删除后将无法找回,请确认是否删除?", + "K2a3f24ac": "默认工作表", + "K7e1ab4b0": "至", + "Kf1b166e7": "详情", + "K28555332": "暂不支持带有双斜杠//的url", + "Keb9fcdad": "用户名", + "Kc654b275": "邮箱", + "Kbe2ecc69": "部门", + "K759fb403": "状态", + "K52c8a730": "启用", + "K718c9310": "禁用", + "K2c5882be": "绑定域名", + "K1cc07937": "过期日期", + "K8b7c2592": "更新者", + "Keefda53d": "更新时间", + "K9f3db3ca": "集群名称", + "Ke7487049": "集群 ID", + "Kb660ffe8": "节点名称", + "Kf12b3034": "管理地址", + "K867e6faf": "服务地址", + "K37348a5e": "集群同步地址", + "K151d2bb7": "环境名称", + "Kfa744afd": "集群数量", + "K23a3bd72": "异常", + "Ke039b9b5": "正常", + "K5c123bad": "角色名称", + "K76036e25": "HTTP 请求头", + "K8d4cbf50": "Cookie", + "K44607e3f": "全等匹配", + "Kc287500a": "前缀匹配", + "Kfc0b1147": "后缀匹配", + "Ka4a92043": "子串匹配", + "K30b2e44f": "非等匹配", + "Kb1587991": "空值匹配", + "K1e97dbd8": "存在匹配", + "Kc8ee3e62": "不存在匹配", + "K87c5a801": "区分大小写的正则匹配", + "K95f062f1": "不区分大小写的正则匹配", + "Kfbd230a5": "任意匹配", + "K413b9869": "服务名称", + "K1e84ad04": "服务 ID", + "K72b0c0b3": "API 数量", + "Kf7200cd9": "负责人", + "Kefaf9956": "创建时间", + "K98db2cb9": "申请状态", + "Ke792d01c": "所属服务", + "K61b62ace": "来源", + "Ke63767cf": "添加时间", + "K3a67ea90": "订阅方", + "K442937c4": "订阅时间", + "K34111022": "协议/方法", + "K62d10724": "URL", + "Ka9481f95": "创建者", + "Kf88d56fd": "上游 ID", + "K11a92fb2": "更新人", + "K2c2bc64f": "动态服务发现", + "Kc9a2a716": "HTTPS", + "Ka7f8266f": "带权轮询", + "Kd17edabd": "IP Hash", + "Kaeba0229": "透传客户端请求 Host", + "K6d7e2fd0": "使用上游服务 Host", + "K31332633": "重写 Host", + "Ke65db976": "权重", + "Kf966b12d": "内部服务:可通过网关访问,但不展示在服务广场", + "Kfc939e49": "公开服务:可通过网关访问,展示在服务广场,可被其他应用订阅", + "Ke96ccf45": " ", + "K5582ac8": "请求路径", + "K92485dd1": "所有 API", + "Ke64e43a": "隐藏鉴权信息", + "K1a78e6f0": "过期时间", + "K40bbb0a3": "服务ID", + "K9919285b": "服务类型", + "K63938137": "公开服务", + "Kfb20a12": "内部服务", + "Kedd64e4d": "停用", + "Ka29b346f": "地址(IP 端口或域名)", + "K63b1e0dc": "权重(0-999)", + "K74ab00a3": "已审批", + "Kea996156": "发布申请记录", + "Kbea7d266": "所属系统", + "Ka36c13cc": "调用系统名称", + "Kd78d73a7": "调用服务名称", + "K73c144eb": "当前系统名称", + "K285bd65e": "被调用服务名称", + "K5cbab635": "被调用系统名称", + "K93c2696e": "上线结果", + "K43fcaf94": "成功", + "Kc71c6a9": "上线失败", + "K56c686f8": "失败", + "K3ba29a85": "API", + "Kda8d5ea1": "上游", + "Kdefa9caa": "使用说明", + "K36856e71": "发布", + "K6382bbfd": "订阅管理", + "K2eef4e4": "订阅审批", + "Ka97bd9e5": "订阅方管理", + "K5974bf24": "管理", + "K3fa5c4c3": "调用拓扑图", + "Kb5c7b82d": "设置", + "K2472615e": "服务数量", + "Kc02aa5f1": "API数量", + "Ke08ff808": "添加日期", + "Kd7d84192": "姓名", + "Kc88e03b6": "团队角色", + "Kdf35c48c": "所有成员", + "K3818f03d": "审批", + "K56b4254f": "发布申请", + "Kd2c1a316": "登录", + "Kf076f63c": "请输入账号", + "K80a560a1": "账号", + "K25c895d5": "请输入密码", + "K551b0348": "密码", + "K480045ce": "Version (0)-(1)", + "Kadee8e49": "日志配置", + "K3453272": "APIPark 提供详尽的 API 调用日志,帮助企业监控、分析和审计 API 的运行状况。", + "K33c76dbc": "部门名称", + "K84829ca9": "父部门 ID", + "K4d7fc74b": "子部门名称", + "Ka16e6c44": "未激活、已禁用的成员无法加入到部门", + "Ked03ba97": "请选择成员需要新加入的部门", + "K5e237e06": "name", + "K184d3473": "添加账号", + "K1ecb35f2": "编辑成员信息", + "Ke6f00b44": "加入部门", + "K501cb1e7": "确定删除成员?此操作无法恢复,确认操作?", + "Kf20863b5": "成员与部门", + "K5f27a546": "输入用户名、邮箱查找成员", + "K26c698bb": "添加部门", + "Kb9cf2a7d": "添加子部门", + "Kc83551f5": "重命名", + "K3f1077c9": "设置成员和对应的角色,成员只能够看到权限范围内的功能和数据。", + "Kdce62a6": "搜索部门", + "K8ef69ee2": "密钥", + "Kba3507d6": "上传密钥", + "K93ac0f23": "密钥文件的后缀名一般为 .key 的文件内容", + "K7cdd1331": "上传证书", + "K6d91905d": "证书文件的后缀名一般为 .crt 或 .pem 的文件内容", + "Kd0f6ded7": "添加证书", + "Ke5732d60": "修改证书", + "K3ca07a70": "证书管理", + "Kdb927f83": "通过为 API 服务配置和管理 SSL 证书,企业可以加密数据传输,防止敏感信息被窃取或篡改。", + "K877985b7": "修改配置", + "Kdf66a675": "设置访问 API 的集群,让 API 在分布式环境中稳定运行,并且能够根据业务需求进行灵活扩展和优化。", + "Kaf074220": "未配置", + "K5878440c": "集群地址", + "K5e9022f8": "下一步", + "K8e7a0f80": "资源配置", + "Kabfe9512": "保存", + "K95c3fd8b": "设置角色的权限范围。", + "K138facd3": "系统级别角色", + "K6eac768d": "添加角色", + "Kb9c2cf02": "团队级别角色", + "Kb4ceecea": "添加子分类", + "K67479e88": "修改分类名称", + "K2bc75e2c": "添加分类", + "Kab4aab44": "重命名分类", + "K8e0e6977": "设置服务可选择的分类,方便团队成员快速找到API。", + "Ke595a20a": "分类名称", + "K9679728f": "父分类 ID", + "K9b2d08fd": "子分类名称", + "Kf14e76e5": "副本", + "K2e050340": "API 基础信息", + "K90f3c02f": "转发规则设置", + "K6ea8d549": "编辑文档", + "Kff5c18ac": "最后编辑人", + "K2eb99415": "转发规则", + "Ke93388fd": "编辑 API", + "K1b1ae3b0": "复制 API", + "K84aabfd4": "添加 API", + "K6a662463": "输入名称、URL 查找 API", + "K59bc6280": "API 详情", + "K2a16c93b": "单位:ms,最小值:1", + "K469e475a": "重试次数", + "Kd568e15c": "发布结果", + "K35f990b0": "查看详情", + "Kdbc1f6cb": "申请发布", + "Kb6860a3f": "回滚", + "Ka3494f4b": "请确认是否回滚?", + "Kb397a99f": "撤销申请", + "K7d401c0f": "请确认是否撤销申请?", + "Ke1b79b93": "终止发布", + "Ka2449180": "请确认是否终止发布?", + "K2cb02f38": "新建版本", + "Ka9c08390": "只允许上传PNG、JPG或SVG格式的图片", + "Kcf756b7a": "API 调用前缀", + "K43d101a": "选填,作为服务内所有API的前缀,比如host/{service_name}/{api_path},一旦保存无法修改", + "Kdc840242": "图标", + "K427a5bd5": "仅支持 .png .jpg .jpeg .svg 格式的图片文件, 大于 1KB 的文件将被压缩", + "K44bc352d": "Logo", + "Kf52a584d": "所属服务分类", + "K72b21be5": "设置服务展示在服务市场中的哪个分类下", + "Kde6bae17": "删除服务", + "K885ea699": "删除操作不可恢复,请谨慎操作!", + "K617f34f1": "最近一次更新者", + "K6ebca204": "最近一次更新时间", + "K39ab0358": "新增订阅方", + "K2d6658ed": "添加服务", + "K7b8f623f": "输入名称、ID、所属团队、负责人查找服务", + "Kdd9b5008": "后端默认使用的IP地址", + "K6bc47edb": "请求协议", + "Kc9acdb25": "负载均衡", + "K632dba5c": "转发 Host", + "Kc1f08a63": "重写域名", + "K628f6851": "超时时间", + "Kaff62621": "超时重试次数", + "Kc41ca30e": "调用频率限制", + "K813e1c0a": "团队名称", + "K692f5aa6": "团队 ID", + "K5de0bc2": "团队 ID(team_id)可用于检索团队,一旦保存无法修改。", + "Ka63dd985": "团队负责人", + "Ka6bcd272": "负责人对团队内的团队、服务、成员有管理权限", + "Ka2012bdd": "删除团队", + "Kbde1f3d": "服务数据清除后,方可删除", + "K395acc14": "移除成员", + "Kec46a57f": "添加成员", + "K48724410": "输入姓名查找", + "Kb9052305": "搜索用户名、邮箱", + "K5ece3bac": "设置团队和成员,然后你可以在团队内创建服务和应用、订阅API,成员只能看到所属团队内的服务和应用。", + "K510cdd27": "添加团队", + "K9244ae14": "输入名称、ID、负责人查找团队", + "Kc7b24b4b": "配置团队", + "Kecb51e2c": "旧密码", + "K8266bcf2": "新密码", + "Ka9aef039": "确认密码", + "Kcf42dcda": "两次密码不一致", + "Kf876a42d": "修改密码", + "K8ed884f": "管理个人账号", + "K9be8e1d7": "API调用统计", + "K521ab28e": "选择服务", + "Kcc8265e1": "选择API", + "K8aefc1e4": "请输入请求路径进行搜索", + "K50d471b2": "重置", + "Kee8ae330": "查询", + "Ka2c794a2": "导出", + "Kaf70c3b": "退出全屏", + "Kd22841a4": "(0)调用详情", + "K1512e983": "应用调用统计", + "Kb4d2007f": "请选择应用", + "K8c7f2d2e": "调用趋势", + "K657c3452": "(0)-(1)调用趋势", + "Kc04efb87": "调用量统计", + "Keb98266e": "加入总体数据对比", + "K18c2ed46": "(0)调用量", + "Kc3741830": "(0)调用成功率", + "Ka6aa5863": "请求总数", + "K9eaef42": "请求成功率", + "K7082a4af": "转发总数", + "K1ce386fb": "转发成功率", + "K87d6877e": "状态码4xx数", + "K4c8a54db": "状态码5xx数", + "Kd566283e": "调用总体趋势", + "Kd23a0be6": "请求报文量", + "Kec3e8361": "响应报文量", + "Ke6250744": "状态码4XX数", + "K2d79d4e1": "状态码5XX数", + "Kcf6553c6": "服务调用统计", + "Kffcfe375": "请选择服务", + "Ka65f739c": "调用详情", + "K89b7ac79": "API 请求量 Top10", + "Kc0915603": "应用调用量 Top10", + "Kf90b54": "服务被调用量 Top10", + "Kfb26388": "暂无请求统计数据", + "Kc8cbd8f8": "请求统计", + "K8dece48": "暂无转发统计数据", + "K1ee32434": "转发统计", + "Kcd125e4d": "暂无调用量统计数据", + "Kaa114e8b": "暂无报文量统计数据", + "K3ad84406": "报文量统计", + "K19a3ebe0": "请求成功数", + "Kcaa8259": "转发成功数", + "K888f038f": "失败状态码数", + "K42d2bef2": "平均响应时间(ms)", + "K9197c994": "最大响应时间(ms)", + "K7c2f3fee": "最小响应时间(ms)", + "K3d85ea54": "平均请求流量(KB)", + "Keec09d32": "最大请求流量(KB)", + "K3786b48": "最小请求流量(KB)", + "K5168eb63": "应用名称", + "K546e46f": "应用 ID", + "K4a1a14": "监控总览", + "K69741ea7": "服务被调用统计", + "K9c8d9933": "API 调用统计", + "K28cf9613": "每分钟", + "K18f25019": "每5分钟", + "Kf00f01ca": "每小时", + "Kfcda87fc": "每天", + "K29ec75dc": "每周", + "K145e4941": "亿", + "Ke6a935d": "万", + "K8f7abcab": " 次", + "K146477a8": "服务标签", + "K4de0af74": "服务分类", + "Kcce1af60": "订阅的服务", + "Kb6e9328f": "访问授权", + "Kb7e869a4": "应用管理", + "Kd59290a2": "搜索分类或标签", + "K6b75bdbc": "暂无API数据", + "Kd8a7a689": "搜索或选择应用", + "K4b15d6f5": "申请理由", + "Kb71b5a13": "鉴权类型", + "K4d1465ee": "Iss", + "K5dcd7ed8": "签名算法", + "K5b0eedd3": "Secret", + "K44f4ffe1": "RSA 公钥", + "Kc5ecd7d9": "用户名 JsonPath", + "K417d85cf": "校验字段", + "K3b82fe1d": "是否 Base64 加密", + "K49b5f4a3": "AK", + "K31418470": "SK", + "Kbfeb5297": "Apikey", + "K95764d1d": "删除应用", + "K217cb125": "鉴权详情", + "K2bb63eca": "添加鉴权", + "Kd74d69b7": "编辑鉴权", + "K9cbe1e0": "修改", + "Kd23d1716": "添加授权", + "K9dfa2c97": "永不过期", + "Kfa920c0": "到期时间", + "Kbeb4e991": "审批详情", + "Ked811bb1": "请确认是否取消订阅?", + "K50c39a62": "取消订阅申请", + "K1856c229": "请确认是否取消订阅申请?", + "K66ea2f0": "搜索服务", + "Kfeb2559b": "审批中", + "Ka2b6d281": "API 文档", + "K667bbbe7": "添加应用", + "Ka4b45550": "暂无服务描述", + "K3c7b175f": "订阅的服务数量:已通过 (0) 个,申请中 (1) 个", + "K850b4b2d": "状态码", + "Kbe3e9335": "退出测试", + "K370a3eb2": "服务市场", + "Kf7ec36d": "服务详情", + "K59cdbec3": "介绍", + "K4aa9ed2c": "申请", + "K6c060779": "服务信息", + "K8723422e": "接入应用", + "Kb97544cb": "供应方", + "Kb32f0afe": "分类", + "K81634069": "版本", + "K96a2f1c8": "无标签", + "K93d5a66e": "接入应用数量", + "K3e770a75": "鉴权 Token", + "K96059c69": "关联标签", + "K32263abd": "添加 Open Api", + "K7829bb78": "配置 Open Api", + "Kcdf76005": "Open Api", + "Ke2601944": "调用服务", + "K8504bca8": "放大", + "K693c1b41": "缩小" +} \ No newline at end of file diff --git a/frontend/packages/common/src/locales/scan/newJson/en-GB.json b/frontend/packages/common/src/locales/scan/newJson/en-GB.json new file mode 100644 index 00000000..a7a790cf --- /dev/null +++ b/frontend/packages/common/src/locales/scan/newJson/en-GB.json @@ -0,0 +1,569 @@ +{ + "Kc0e5ef9f": "工作空间", + "K3863c722": "我的", + "Kfe93ef35": "应用", + "Kb58e0c3f": "服务", + "Kc9e489f5": "团队", + "K61c89f5f": "API 市场", + "K16d71239": "仪表盘", + "K714c192d": "运行视图", + "Kd57dfe97": "系统拓扑图", + "K3fe97dcc": "系统设置", + "K67ef3525": "组织", + "K74aef1ad": "成员", + "Kf644225f": "角色", + "K958da71f": "服务分类管理", + "Kf270ca55": "运维与集成", + "Ke93d36ed": "集群", + "K481e8a05": "证书", + "Kca53edd0": "日志", + "Kb283e720": "资源", + "K631d646f": "Open API", + "K6535ff9c": "账号设置", + "Kf15499b4": "退出登录", + "Kabbd6e6": "文档", + "K1196b104": "APIPark - 企业API数据开放平台", + "K1f42de3": "HTTP 状态码", + "K4770dff4": "系统状态码", + "Kf89e58f1": "描述", + "K9e53c664": "提交", + "Kf8e7294c": "上一步", + "Ka0451c97": "取消", + "Kb1dedda3": "关闭", + "Kb2fc7600": "添加配置", + "K4e07217d": "编辑配置", + "K4ea968fe": "编辑(0)", + "Ka7aaaeb": "添加(0)", + "Kaff78ecf": "请输入Key", + "K65d46535": "请输入Value", + "Kc14b2ea3": "返回", + "K11d3633a": "ID", + "Kbff43de3": "名称", + "K16ca79ef": "Driver", + "K7a369eef": "已发布", + "Kcfa1a4d2": "下线", + "K771dc3b7": "上线", + "K530f5951": "查看", + "Kecbd7449": "删除", + "K1cbe2507": "确认", + "K48325b6": "搜索(0)名称", + "Ka1d885c1": "添加", + "Kad207008": "编辑", + "K1ff96ff": "申请系统", + "K9bf855d6": "所属团队", + "K11b994ed": "申请人", + "K939baba7": "申请时间", + "Kdab2e63b": "版本号", + "K8b29c460": "版本说明", + "K36a72ad1": "API 列表", + "K54e44357": "上游列表", + "Kb8e8e6f5": "备注", + "K1ab0ae5b": "申请原因", + "K53c00c3c": "审核意见", + "K7edf331d": "时间", + "Kef45b208": "近1小时", + "K9dbf22b8": "近24小时", + "K820fbfab": "近3天", + "Kd6d28fc": "近7天", + "K23fda291": "暂无操作权限,请联系管理员分配。", + "K4618cb0a": "微信小程序", + "Ka854f511": "获取文件,需填路径", + "Kaa11a695": "暂不支持生成非 HTTPS 或非 HTTP 协议的代码示例", + "Kbe46924e": "搜索编程语言...", + "Ke8e4f258": "编程语言", + "K29c07a47": "成功示例", + "K1f5c814d": "失败示例", + "K4ef022d7": "默认 text/html;charset=UTF-8", + "Kd061b5bf": "暂未填写示例", + "Kc14cec33": "Binary", + "K48b4d9e3": "请求头部", + "Kcd347eaf": "请求体", + "K9e100bfe": "Query 参数", + "K3e9f12fd": "REST 参数", + "K2bfa290c": "api request editor", + "Kb36d111a": "返回头部", + "K980bde79": "返回值", + "Kb04d201a": "更多设置", + "Kee74f5b4": "添加子参数", + "Kc7d3106c": "向下添加行", + "Keaabd222": "标签", + "K8ad2c50e": "参数名", + "K67d68dd1": "类型", + "K29245f47": "必需", + "Ke32cbcd3": "示例", + "Kc13936c6": "输入 URL 或 cURL", + "Ka1ede006": "HTTP", + "K152ac44e": "参数位置", + "K1660ae72": "匹配类型", + "K91ced765": "参数值", + "K5b265628": "操作类型", + "K1826982d": "新增或修改", + "Kd65b55f5": "匹配参数值", + "K15f35bf2": "转发上游路径", + "K79dec0dd": "请求超时时间", + "K7d465645": "绑定上游服务", + "K63a6404d": "重试时间", + "K47740727": "转发上游请求头", + "K2b605d42": "More", + "K1df9fbd5": "导入", + "K5e85df18": "导入格式", + "K9eaf7885": "全量替换", + "Kf8c3a80b": "在末端插入", + "Kd96b2d7d": "增量更新", + "Kf2fc08eb": "请求头", + "Ka45f1d8": "Rest 参数", + "K94bb113a": "大小", + "K359919b5": "另存为文件", + "K38bf1b90": "响应", + "K59f4186e": "响应头", + "K5f1e23fd": "正文", + "Kf404ef7d": "发送(Enter)", + "K2dbfd648": "中止", + "Kacabc771": "秒", + "K13ae6a93": "复制", + "Ke54a14a3": "格式化", + "K43934f6d": "搜索", + "K741decac": "替代", + "Kd507abff": "确定", + "Kca2d1624": "The (0) must not be negative.", + "K792b255a": "The (0) must be greater than or equal to the (1).", + "Kf0bed26d": "值枚举", + "K633a03ca": "枚举", + "Kd2766caf": "最小长度", + "Kd6d52485": "最大长度", + "Kea15f66c": "最小值", + "K1af340ff": "最大值", + "K68691e16": "将文件拖拽至此处上传,或点击选择文件上传", + "Kcec46ae": "Upload Files", + "K760fb044": "Files Selected", + "Kea2bdee0": "请填写接口名称", + "K49053438": "详细说明", + "K148f6fa4": "高级匹配", + "K3ae4c789": "转发配置", + "K2f4d0a37": "请求参数", + "Kde2d6dbd": "返回示例", + "K70e6069c": "测试 API", + "Ke4603448": "请求 Header", + "K89fd86b3": "请求 Body", + "K8747e3c4": "请求示例代码", + "K8613e6e7": "响应示例", + "Kab1c2159": "响应 Header", + "Kd2be51d1": "响应 Body", + "K831aa6c0": "申请方-应用", + "K58ca9485": "申请服务", + "K283f55b4": "服务所属系统", + "Kd60d204": "服务所属团队", + "K3a9a3b75": "审批状态", + "K4f57b2de": "审批人", + "K31dabc6b": "审批时间", + "K8582af3f": "拒绝", + "K54e27f57": "通过", + "K7eeca185": "审批完成", + "Kd4061161": "发布审批中", + "K823bfe63": "在线", + "K97ddb3f8": "-", + "Kc9315fa1": "已拒绝", + "K3fbe7511": "发布异常", + "Ke64e695c": "发布中", + "K17f93984": "API 名称", + "K1365fe45": "请求方式", + "Kc380335f": "路径", + "K4ee62e8": "该 API 缺失(0)(1)(2)请先补充", + "K385591f3": "转发信息,", + "K68415c14": "文档信息,", + "K133b75e9": "上游信息,", + "Kad98e030": "上游类型", + "Kdeed8399": "静态上游", + "K78b1ca25": "地址", + "K6208054": "待审批", + "K1be7f021": "审批通过", + "K677a4959": "发布终止", + "Kfd6d2d3d": "已关闭", + "K9d7e880a": "发布版本", + "K855135f": "创建版本时间", + "Kcbf39b82": "版本状态", + "K339d15b5": "创建人", + "K7194cea2": "审核时间", + "K69827c60": "发布状态", + "K1644b775": "新增", + "K4fdf4dcc": "变更", + "K33d66e26": "无变更", + "K9b70c007": "缺失字段", + "Kd85208a3": "驳回", + "K8adf7f8b": "审核中", + "Kad6aa439": "已订阅", + "K3118fdb0": "取消订阅", + "K9a68443b": "取消申请", + "K18307d56": "手动添加", + "K705fe9f5": "订阅申请", + "Kbc96ebec": "申请方应用", + "K1f89176d": "申请方所属团队", + "Kfe731dfc": "操作", + "K71661ee8": "必填项", + "Kcbee3f8": "不是有效邮箱地址", + "K442cfba1": "请输入", + "K3bb646e4": "请选择", + "Ka4ecfa40": "英文数字下划线任意一种,首字母必须为英文", + "K39686a7f": "支持字母开头、英文数字中横线下划线组合", + "K4d6a0190": "选择拒绝时,审批意见为必填", + "K37318b68": "无法连接集群,请检查集群地址是否正确或防火墙配置", + "K7f0c746d": "操作成功", + "K6a365d01": "操作失败", + "K978062b6": "正在操作", + "Kca7bd6d4": "正在加载数据", + "K3c93b77e": "获取数据失败", + "Ke108c369": "登录成功", + "K9168d3e": "退出成功,将跳转至登录页", + "K2f8a7ab7": "未填写审核意见", + "Kb858d78a": "复制成功", + "K26e85d15": "复制失败,请手动复制", + "K5cfdd950": "该数据删除后将无法找回,请确认是否删除?", + "K2a3f24ac": "默认工作表", + "K7e1ab4b0": "至", + "Kf1b166e7": "详情", + "K28555332": "暂不支持带有双斜杠//的url", + "Keb9fcdad": "用户名", + "Kc654b275": "邮箱", + "Kbe2ecc69": "部门", + "K759fb403": "状态", + "K52c8a730": "启用", + "K718c9310": "禁用", + "K2c5882be": "绑定域名", + "K1cc07937": "过期日期", + "K8b7c2592": "更新者", + "Keefda53d": "更新时间", + "K9f3db3ca": "集群名称", + "Ke7487049": "集群 ID", + "Kb660ffe8": "节点名称", + "Kf12b3034": "管理地址", + "K867e6faf": "服务地址", + "K37348a5e": "集群同步地址", + "K151d2bb7": "环境名称", + "Kfa744afd": "集群数量", + "K23a3bd72": "异常", + "Ke039b9b5": "正常", + "K5c123bad": "角色名称", + "K76036e25": "HTTP 请求头", + "K8d4cbf50": "Cookie", + "K44607e3f": "全等匹配", + "Kc287500a": "前缀匹配", + "Kfc0b1147": "后缀匹配", + "Ka4a92043": "子串匹配", + "K30b2e44f": "非等匹配", + "Kb1587991": "空值匹配", + "K1e97dbd8": "存在匹配", + "Kc8ee3e62": "不存在匹配", + "K87c5a801": "区分大小写的正则匹配", + "K95f062f1": "不区分大小写的正则匹配", + "Kfbd230a5": "任意匹配", + "K413b9869": "服务名称", + "K1e84ad04": "服务 ID", + "K72b0c0b3": "API 数量", + "Kf7200cd9": "负责人", + "Kefaf9956": "创建时间", + "K98db2cb9": "申请状态", + "Ke792d01c": "所属服务", + "K61b62ace": "来源", + "Ke63767cf": "添加时间", + "K3a67ea90": "订阅方", + "K442937c4": "订阅时间", + "K34111022": "协议/方法", + "K62d10724": "URL", + "Ka9481f95": "创建者", + "Kf88d56fd": "上游 ID", + "K11a92fb2": "更新人", + "K2c2bc64f": "动态服务发现", + "Kc9a2a716": "HTTPS", + "Ka7f8266f": "带权轮询", + "Kd17edabd": "IP Hash", + "Kaeba0229": "透传客户端请求 Host", + "K6d7e2fd0": "使用上游服务 Host", + "K31332633": "重写 Host", + "Ke65db976": "权重", + "Kf966b12d": "内部服务:可通过网关访问,但不展示在服务广场", + "Kfc939e49": "公开服务:可通过网关访问,展示在服务广场,可被其他应用订阅", + "Ke96ccf45": " ", + "K5582ac8": "请求路径", + "K92485dd1": "所有 API", + "Ke64e43a": "隐藏鉴权信息", + "K1a78e6f0": "过期时间", + "K40bbb0a3": "服务ID", + "K9919285b": "服务类型", + "K63938137": "公开服务", + "Kfb20a12": "内部服务", + "Kedd64e4d": "停用", + "Ka29b346f": "地址(IP 端口或域名)", + "K63b1e0dc": "权重(0-999)", + "K74ab00a3": "已审批", + "Kea996156": "发布申请记录", + "Kbea7d266": "所属系统", + "Ka36c13cc": "调用系统名称", + "Kd78d73a7": "调用服务名称", + "K73c144eb": "当前系统名称", + "K285bd65e": "被调用服务名称", + "K5cbab635": "被调用系统名称", + "K93c2696e": "上线结果", + "K43fcaf94": "成功", + "Kc71c6a9": "上线失败", + "K56c686f8": "失败", + "K3ba29a85": "API", + "Kda8d5ea1": "上游", + "Kdefa9caa": "使用说明", + "K36856e71": "发布", + "K6382bbfd": "订阅管理", + "K2eef4e4": "订阅审批", + "Ka97bd9e5": "订阅方管理", + "K5974bf24": "管理", + "K3fa5c4c3": "调用拓扑图", + "Kb5c7b82d": "设置", + "K2472615e": "服务数量", + "Kc02aa5f1": "API数量", + "Ke08ff808": "添加日期", + "Kd7d84192": "姓名", + "Kc88e03b6": "团队角色", + "Kdf35c48c": "所有成员", + "K3818f03d": "审批", + "K56b4254f": "发布申请", + "Kd2c1a316": "登录", + "Kf076f63c": "请输入账号", + "K80a560a1": "账号", + "K25c895d5": "请输入密码", + "K551b0348": "密码", + "K480045ce": "Version (0)-(1)", + "Kadee8e49": "日志配置", + "K3453272": "APIPark 提供详尽的 API 调用日志,帮助企业监控、分析和审计 API 的运行状况。", + "K33c76dbc": "部门名称", + "K84829ca9": "父部门 ID", + "K4d7fc74b": "子部门名称", + "Ka16e6c44": "未激活、已禁用的成员无法加入到部门", + "Ked03ba97": "请选择成员需要新加入的部门", + "K5e237e06": "name", + "K184d3473": "添加账号", + "K1ecb35f2": "编辑成员信息", + "Ke6f00b44": "加入部门", + "K501cb1e7": "确定删除成员?此操作无法恢复,确认操作?", + "Kf20863b5": "成员与部门", + "K5f27a546": "输入用户名、邮箱查找成员", + "K26c698bb": "添加部门", + "Kb9cf2a7d": "添加子部门", + "Kc83551f5": "重命名", + "K3f1077c9": "设置成员和对应的角色,成员只能够看到权限范围内的功能和数据。", + "Kdce62a6": "搜索部门", + "K8ef69ee2": "密钥", + "Kba3507d6": "上传密钥", + "K93ac0f23": "密钥文件的后缀名一般为 .key 的文件内容", + "K7cdd1331": "上传证书", + "K6d91905d": "证书文件的后缀名一般为 .crt 或 .pem 的文件内容", + "Kd0f6ded7": "添加证书", + "Ke5732d60": "修改证书", + "K3ca07a70": "证书管理", + "Kdb927f83": "通过为 API 服务配置和管理 SSL 证书,企业可以加密数据传输,防止敏感信息被窃取或篡改。", + "K877985b7": "修改配置", + "Kdf66a675": "设置访问 API 的集群,让 API 在分布式环境中稳定运行,并且能够根据业务需求进行灵活扩展和优化。", + "Kaf074220": "未配置", + "K5878440c": "集群地址", + "K5e9022f8": "下一步", + "K8e7a0f80": "资源配置", + "Kabfe9512": "保存", + "K95c3fd8b": "设置角色的权限范围。", + "K138facd3": "系统级别角色", + "K6eac768d": "添加角色", + "Kb9c2cf02": "团队级别角色", + "Kb4ceecea": "添加子分类", + "K67479e88": "修改分类名称", + "K2bc75e2c": "添加分类", + "Kab4aab44": "重命名分类", + "K8e0e6977": "设置服务可选择的分类,方便团队成员快速找到API。", + "Ke595a20a": "分类名称", + "K9679728f": "父分类 ID", + "K9b2d08fd": "子分类名称", + "Kf14e76e5": "副本", + "K2e050340": "API 基础信息", + "K90f3c02f": "转发规则设置", + "K6ea8d549": "编辑文档", + "Kff5c18ac": "最后编辑人", + "K2eb99415": "转发规则", + "Ke93388fd": "编辑 API", + "K1b1ae3b0": "复制 API", + "K84aabfd4": "添加 API", + "K6a662463": "输入名称、URL 查找 API", + "K59bc6280": "API 详情", + "K2a16c93b": "单位:ms,最小值:1", + "K469e475a": "重试次数", + "Kd568e15c": "发布结果", + "K35f990b0": "查看详情", + "Kdbc1f6cb": "申请发布", + "Kb6860a3f": "回滚", + "Ka3494f4b": "请确认是否回滚?", + "Kb397a99f": "撤销申请", + "K7d401c0f": "请确认是否撤销申请?", + "Ke1b79b93": "终止发布", + "Ka2449180": "请确认是否终止发布?", + "K2cb02f38": "新建版本", + "Ka9c08390": "只允许上传PNG、JPG或SVG格式的图片", + "Kcf756b7a": "API 调用前缀", + "K43d101a": "选填,作为服务内所有API的前缀,比如host/{service_name}/{api_path},一旦保存无法修改", + "Kdc840242": "图标", + "K427a5bd5": "仅支持 .png .jpg .jpeg .svg 格式的图片文件, 大于 1KB 的文件将被压缩", + "K44bc352d": "Logo", + "Kf52a584d": "所属服务分类", + "K72b21be5": "设置服务展示在服务市场中的哪个分类下", + "Kde6bae17": "删除服务", + "K885ea699": "删除操作不可恢复,请谨慎操作!", + "K617f34f1": "最近一次更新者", + "K6ebca204": "最近一次更新时间", + "K39ab0358": "新增订阅方", + "K2d6658ed": "添加服务", + "K7b8f623f": "输入名称、ID、所属团队、负责人查找服务", + "Kdd9b5008": "后端默认使用的IP地址", + "K6bc47edb": "请求协议", + "Kc9acdb25": "负载均衡", + "K632dba5c": "转发 Host", + "Kc1f08a63": "重写域名", + "K628f6851": "超时时间", + "Kaff62621": "超时重试次数", + "Kc41ca30e": "调用频率限制", + "K813e1c0a": "团队名称", + "K692f5aa6": "团队 ID", + "K5de0bc2": "团队 ID(team_id)可用于检索团队,一旦保存无法修改。", + "Ka63dd985": "团队负责人", + "Ka6bcd272": "负责人对团队内的团队、服务、成员有管理权限", + "Ka2012bdd": "删除团队", + "Kbde1f3d": "服务数据清除后,方可删除", + "K395acc14": "移除成员", + "Kec46a57f": "添加成员", + "K48724410": "输入姓名查找", + "Kb9052305": "搜索用户名、邮箱", + "K5ece3bac": "设置团队和成员,然后你可以在团队内创建服务和应用、订阅API,成员只能看到所属团队内的服务和应用。", + "K510cdd27": "添加团队", + "K9244ae14": "输入名称、ID、负责人查找团队", + "Kc7b24b4b": "配置团队", + "Kecb51e2c": "旧密码", + "K8266bcf2": "新密码", + "Ka9aef039": "确认密码", + "Kcf42dcda": "两次密码不一致", + "Kf876a42d": "修改密码", + "K8ed884f": "管理个人账号", + "K9be8e1d7": "API调用统计", + "K521ab28e": "选择服务", + "Kcc8265e1": "选择API", + "K8aefc1e4": "请输入请求路径进行搜索", + "K50d471b2": "重置", + "Kee8ae330": "查询", + "Ka2c794a2": "导出", + "Kaf70c3b": "退出全屏", + "Kd22841a4": "(0)调用详情", + "K1512e983": "应用调用统计", + "Kb4d2007f": "请选择应用", + "K8c7f2d2e": "调用趋势", + "K657c3452": "(0)-(1)调用趋势", + "Kc04efb87": "调用量统计", + "Keb98266e": "加入总体数据对比", + "K18c2ed46": "(0)调用量", + "Kc3741830": "(0)调用成功率", + "Ka6aa5863": "请求总数", + "K9eaef42": "请求成功率", + "K7082a4af": "转发总数", + "K1ce386fb": "转发成功率", + "K87d6877e": "状态码4xx数", + "K4c8a54db": "状态码5xx数", + "Kd566283e": "调用总体趋势", + "Kd23a0be6": "请求报文量", + "Kec3e8361": "响应报文量", + "Ke6250744": "状态码4XX数", + "K2d79d4e1": "状态码5XX数", + "Kcf6553c6": "服务调用统计", + "Kffcfe375": "请选择服务", + "Ka65f739c": "调用详情", + "K89b7ac79": "API 请求量 Top10", + "Kc0915603": "应用调用量 Top10", + "Kf90b54": "服务被调用量 Top10", + "Kfb26388": "暂无请求统计数据", + "Kc8cbd8f8": "请求统计", + "K8dece48": "暂无转发统计数据", + "K1ee32434": "转发统计", + "Kcd125e4d": "暂无调用量统计数据", + "Kaa114e8b": "暂无报文量统计数据", + "K3ad84406": "报文量统计", + "K19a3ebe0": "请求成功数", + "Kcaa8259": "转发成功数", + "K888f038f": "失败状态码数", + "K42d2bef2": "平均响应时间(ms)", + "K9197c994": "最大响应时间(ms)", + "K7c2f3fee": "最小响应时间(ms)", + "K3d85ea54": "平均请求流量(KB)", + "Keec09d32": "最大请求流量(KB)", + "K3786b48": "最小请求流量(KB)", + "K5168eb63": "应用名称", + "K546e46f": "应用 ID", + "K4a1a14": "监控总览", + "K69741ea7": "服务被调用统计", + "K9c8d9933": "API 调用统计", + "K28cf9613": "每分钟", + "K18f25019": "每5分钟", + "Kf00f01ca": "每小时", + "Kfcda87fc": "每天", + "K29ec75dc": "每周", + "K145e4941": "亿", + "Ke6a935d": "万", + "K8f7abcab": " 次", + "K146477a8": "服务标签", + "K4de0af74": "服务分类", + "Kcce1af60": "订阅的服务", + "Kb6e9328f": "访问授权", + "Kb7e869a4": "应用管理", + "Kd59290a2": "搜索分类或标签", + "K6b75bdbc": "暂无API数据", + "Kd8a7a689": "搜索或选择应用", + "K4b15d6f5": "申请理由", + "Kb71b5a13": "鉴权类型", + "K4d1465ee": "Iss", + "K5dcd7ed8": "签名算法", + "K5b0eedd3": "Secret", + "K44f4ffe1": "RSA 公钥", + "Kc5ecd7d9": "用户名 JsonPath", + "K417d85cf": "校验字段", + "K3b82fe1d": "是否 Base64 加密", + "K49b5f4a3": "AK", + "K31418470": "SK", + "Kbfeb5297": "Apikey", + "K95764d1d": "删除应用", + "K217cb125": "鉴权详情", + "K2bb63eca": "添加鉴权", + "Kd74d69b7": "编辑鉴权", + "K9cbe1e0": "修改", + "Kd23d1716": "添加授权", + "K9dfa2c97": "永不过期", + "Kfa920c0": "到期时间", + "Kbeb4e991": "审批详情", + "Ked811bb1": "请确认是否取消订阅?", + "K50c39a62": "取消订阅申请", + "K1856c229": "请确认是否取消订阅申请?", + "K66ea2f0": "搜索服务", + "Kfeb2559b": "审批中", + "Ka2b6d281": "API 文档", + "K667bbbe7": "添加应用", + "Ka4b45550": "暂无服务描述", + "K3c7b175f": "订阅的服务数量:已通过 (0) 个,申请中 (1) 个", + "K850b4b2d": "状态码", + "Kbe3e9335": "退出测试", + "K370a3eb2": "服务市场", + "Kf7ec36d": "服务详情", + "K59cdbec3": "介绍", + "K4aa9ed2c": "申请", + "K6c060779": "服务信息", + "K8723422e": "接入应用", + "Kb97544cb": "供应方", + "Kb32f0afe": "分类", + "K81634069": "版本", + "K96a2f1c8": "无标签", + "K93d5a66e": "接入应用数量", + "K3e770a75": "鉴权 Token", + "K96059c69": "关联标签", + "K32263abd": "添加 Open Api", + "K7829bb78": "配置 Open Api", + "Kcdf76005": "Open Api", + "Ke2601944": "调用服务", + "K8504bca8": "放大", + "K693c1b41": "缩小" +} diff --git a/frontend/packages/common/src/locales/scan/newJson/zh-CN.json b/frontend/packages/common/src/locales/scan/newJson/zh-CN.json new file mode 100644 index 00000000..a7a790cf --- /dev/null +++ b/frontend/packages/common/src/locales/scan/newJson/zh-CN.json @@ -0,0 +1,569 @@ +{ + "Kc0e5ef9f": "工作空间", + "K3863c722": "我的", + "Kfe93ef35": "应用", + "Kb58e0c3f": "服务", + "Kc9e489f5": "团队", + "K61c89f5f": "API 市场", + "K16d71239": "仪表盘", + "K714c192d": "运行视图", + "Kd57dfe97": "系统拓扑图", + "K3fe97dcc": "系统设置", + "K67ef3525": "组织", + "K74aef1ad": "成员", + "Kf644225f": "角色", + "K958da71f": "服务分类管理", + "Kf270ca55": "运维与集成", + "Ke93d36ed": "集群", + "K481e8a05": "证书", + "Kca53edd0": "日志", + "Kb283e720": "资源", + "K631d646f": "Open API", + "K6535ff9c": "账号设置", + "Kf15499b4": "退出登录", + "Kabbd6e6": "文档", + "K1196b104": "APIPark - 企业API数据开放平台", + "K1f42de3": "HTTP 状态码", + "K4770dff4": "系统状态码", + "Kf89e58f1": "描述", + "K9e53c664": "提交", + "Kf8e7294c": "上一步", + "Ka0451c97": "取消", + "Kb1dedda3": "关闭", + "Kb2fc7600": "添加配置", + "K4e07217d": "编辑配置", + "K4ea968fe": "编辑(0)", + "Ka7aaaeb": "添加(0)", + "Kaff78ecf": "请输入Key", + "K65d46535": "请输入Value", + "Kc14b2ea3": "返回", + "K11d3633a": "ID", + "Kbff43de3": "名称", + "K16ca79ef": "Driver", + "K7a369eef": "已发布", + "Kcfa1a4d2": "下线", + "K771dc3b7": "上线", + "K530f5951": "查看", + "Kecbd7449": "删除", + "K1cbe2507": "确认", + "K48325b6": "搜索(0)名称", + "Ka1d885c1": "添加", + "Kad207008": "编辑", + "K1ff96ff": "申请系统", + "K9bf855d6": "所属团队", + "K11b994ed": "申请人", + "K939baba7": "申请时间", + "Kdab2e63b": "版本号", + "K8b29c460": "版本说明", + "K36a72ad1": "API 列表", + "K54e44357": "上游列表", + "Kb8e8e6f5": "备注", + "K1ab0ae5b": "申请原因", + "K53c00c3c": "审核意见", + "K7edf331d": "时间", + "Kef45b208": "近1小时", + "K9dbf22b8": "近24小时", + "K820fbfab": "近3天", + "Kd6d28fc": "近7天", + "K23fda291": "暂无操作权限,请联系管理员分配。", + "K4618cb0a": "微信小程序", + "Ka854f511": "获取文件,需填路径", + "Kaa11a695": "暂不支持生成非 HTTPS 或非 HTTP 协议的代码示例", + "Kbe46924e": "搜索编程语言...", + "Ke8e4f258": "编程语言", + "K29c07a47": "成功示例", + "K1f5c814d": "失败示例", + "K4ef022d7": "默认 text/html;charset=UTF-8", + "Kd061b5bf": "暂未填写示例", + "Kc14cec33": "Binary", + "K48b4d9e3": "请求头部", + "Kcd347eaf": "请求体", + "K9e100bfe": "Query 参数", + "K3e9f12fd": "REST 参数", + "K2bfa290c": "api request editor", + "Kb36d111a": "返回头部", + "K980bde79": "返回值", + "Kb04d201a": "更多设置", + "Kee74f5b4": "添加子参数", + "Kc7d3106c": "向下添加行", + "Keaabd222": "标签", + "K8ad2c50e": "参数名", + "K67d68dd1": "类型", + "K29245f47": "必需", + "Ke32cbcd3": "示例", + "Kc13936c6": "输入 URL 或 cURL", + "Ka1ede006": "HTTP", + "K152ac44e": "参数位置", + "K1660ae72": "匹配类型", + "K91ced765": "参数值", + "K5b265628": "操作类型", + "K1826982d": "新增或修改", + "Kd65b55f5": "匹配参数值", + "K15f35bf2": "转发上游路径", + "K79dec0dd": "请求超时时间", + "K7d465645": "绑定上游服务", + "K63a6404d": "重试时间", + "K47740727": "转发上游请求头", + "K2b605d42": "More", + "K1df9fbd5": "导入", + "K5e85df18": "导入格式", + "K9eaf7885": "全量替换", + "Kf8c3a80b": "在末端插入", + "Kd96b2d7d": "增量更新", + "Kf2fc08eb": "请求头", + "Ka45f1d8": "Rest 参数", + "K94bb113a": "大小", + "K359919b5": "另存为文件", + "K38bf1b90": "响应", + "K59f4186e": "响应头", + "K5f1e23fd": "正文", + "Kf404ef7d": "发送(Enter)", + "K2dbfd648": "中止", + "Kacabc771": "秒", + "K13ae6a93": "复制", + "Ke54a14a3": "格式化", + "K43934f6d": "搜索", + "K741decac": "替代", + "Kd507abff": "确定", + "Kca2d1624": "The (0) must not be negative.", + "K792b255a": "The (0) must be greater than or equal to the (1).", + "Kf0bed26d": "值枚举", + "K633a03ca": "枚举", + "Kd2766caf": "最小长度", + "Kd6d52485": "最大长度", + "Kea15f66c": "最小值", + "K1af340ff": "最大值", + "K68691e16": "将文件拖拽至此处上传,或点击选择文件上传", + "Kcec46ae": "Upload Files", + "K760fb044": "Files Selected", + "Kea2bdee0": "请填写接口名称", + "K49053438": "详细说明", + "K148f6fa4": "高级匹配", + "K3ae4c789": "转发配置", + "K2f4d0a37": "请求参数", + "Kde2d6dbd": "返回示例", + "K70e6069c": "测试 API", + "Ke4603448": "请求 Header", + "K89fd86b3": "请求 Body", + "K8747e3c4": "请求示例代码", + "K8613e6e7": "响应示例", + "Kab1c2159": "响应 Header", + "Kd2be51d1": "响应 Body", + "K831aa6c0": "申请方-应用", + "K58ca9485": "申请服务", + "K283f55b4": "服务所属系统", + "Kd60d204": "服务所属团队", + "K3a9a3b75": "审批状态", + "K4f57b2de": "审批人", + "K31dabc6b": "审批时间", + "K8582af3f": "拒绝", + "K54e27f57": "通过", + "K7eeca185": "审批完成", + "Kd4061161": "发布审批中", + "K823bfe63": "在线", + "K97ddb3f8": "-", + "Kc9315fa1": "已拒绝", + "K3fbe7511": "发布异常", + "Ke64e695c": "发布中", + "K17f93984": "API 名称", + "K1365fe45": "请求方式", + "Kc380335f": "路径", + "K4ee62e8": "该 API 缺失(0)(1)(2)请先补充", + "K385591f3": "转发信息,", + "K68415c14": "文档信息,", + "K133b75e9": "上游信息,", + "Kad98e030": "上游类型", + "Kdeed8399": "静态上游", + "K78b1ca25": "地址", + "K6208054": "待审批", + "K1be7f021": "审批通过", + "K677a4959": "发布终止", + "Kfd6d2d3d": "已关闭", + "K9d7e880a": "发布版本", + "K855135f": "创建版本时间", + "Kcbf39b82": "版本状态", + "K339d15b5": "创建人", + "K7194cea2": "审核时间", + "K69827c60": "发布状态", + "K1644b775": "新增", + "K4fdf4dcc": "变更", + "K33d66e26": "无变更", + "K9b70c007": "缺失字段", + "Kd85208a3": "驳回", + "K8adf7f8b": "审核中", + "Kad6aa439": "已订阅", + "K3118fdb0": "取消订阅", + "K9a68443b": "取消申请", + "K18307d56": "手动添加", + "K705fe9f5": "订阅申请", + "Kbc96ebec": "申请方应用", + "K1f89176d": "申请方所属团队", + "Kfe731dfc": "操作", + "K71661ee8": "必填项", + "Kcbee3f8": "不是有效邮箱地址", + "K442cfba1": "请输入", + "K3bb646e4": "请选择", + "Ka4ecfa40": "英文数字下划线任意一种,首字母必须为英文", + "K39686a7f": "支持字母开头、英文数字中横线下划线组合", + "K4d6a0190": "选择拒绝时,审批意见为必填", + "K37318b68": "无法连接集群,请检查集群地址是否正确或防火墙配置", + "K7f0c746d": "操作成功", + "K6a365d01": "操作失败", + "K978062b6": "正在操作", + "Kca7bd6d4": "正在加载数据", + "K3c93b77e": "获取数据失败", + "Ke108c369": "登录成功", + "K9168d3e": "退出成功,将跳转至登录页", + "K2f8a7ab7": "未填写审核意见", + "Kb858d78a": "复制成功", + "K26e85d15": "复制失败,请手动复制", + "K5cfdd950": "该数据删除后将无法找回,请确认是否删除?", + "K2a3f24ac": "默认工作表", + "K7e1ab4b0": "至", + "Kf1b166e7": "详情", + "K28555332": "暂不支持带有双斜杠//的url", + "Keb9fcdad": "用户名", + "Kc654b275": "邮箱", + "Kbe2ecc69": "部门", + "K759fb403": "状态", + "K52c8a730": "启用", + "K718c9310": "禁用", + "K2c5882be": "绑定域名", + "K1cc07937": "过期日期", + "K8b7c2592": "更新者", + "Keefda53d": "更新时间", + "K9f3db3ca": "集群名称", + "Ke7487049": "集群 ID", + "Kb660ffe8": "节点名称", + "Kf12b3034": "管理地址", + "K867e6faf": "服务地址", + "K37348a5e": "集群同步地址", + "K151d2bb7": "环境名称", + "Kfa744afd": "集群数量", + "K23a3bd72": "异常", + "Ke039b9b5": "正常", + "K5c123bad": "角色名称", + "K76036e25": "HTTP 请求头", + "K8d4cbf50": "Cookie", + "K44607e3f": "全等匹配", + "Kc287500a": "前缀匹配", + "Kfc0b1147": "后缀匹配", + "Ka4a92043": "子串匹配", + "K30b2e44f": "非等匹配", + "Kb1587991": "空值匹配", + "K1e97dbd8": "存在匹配", + "Kc8ee3e62": "不存在匹配", + "K87c5a801": "区分大小写的正则匹配", + "K95f062f1": "不区分大小写的正则匹配", + "Kfbd230a5": "任意匹配", + "K413b9869": "服务名称", + "K1e84ad04": "服务 ID", + "K72b0c0b3": "API 数量", + "Kf7200cd9": "负责人", + "Kefaf9956": "创建时间", + "K98db2cb9": "申请状态", + "Ke792d01c": "所属服务", + "K61b62ace": "来源", + "Ke63767cf": "添加时间", + "K3a67ea90": "订阅方", + "K442937c4": "订阅时间", + "K34111022": "协议/方法", + "K62d10724": "URL", + "Ka9481f95": "创建者", + "Kf88d56fd": "上游 ID", + "K11a92fb2": "更新人", + "K2c2bc64f": "动态服务发现", + "Kc9a2a716": "HTTPS", + "Ka7f8266f": "带权轮询", + "Kd17edabd": "IP Hash", + "Kaeba0229": "透传客户端请求 Host", + "K6d7e2fd0": "使用上游服务 Host", + "K31332633": "重写 Host", + "Ke65db976": "权重", + "Kf966b12d": "内部服务:可通过网关访问,但不展示在服务广场", + "Kfc939e49": "公开服务:可通过网关访问,展示在服务广场,可被其他应用订阅", + "Ke96ccf45": " ", + "K5582ac8": "请求路径", + "K92485dd1": "所有 API", + "Ke64e43a": "隐藏鉴权信息", + "K1a78e6f0": "过期时间", + "K40bbb0a3": "服务ID", + "K9919285b": "服务类型", + "K63938137": "公开服务", + "Kfb20a12": "内部服务", + "Kedd64e4d": "停用", + "Ka29b346f": "地址(IP 端口或域名)", + "K63b1e0dc": "权重(0-999)", + "K74ab00a3": "已审批", + "Kea996156": "发布申请记录", + "Kbea7d266": "所属系统", + "Ka36c13cc": "调用系统名称", + "Kd78d73a7": "调用服务名称", + "K73c144eb": "当前系统名称", + "K285bd65e": "被调用服务名称", + "K5cbab635": "被调用系统名称", + "K93c2696e": "上线结果", + "K43fcaf94": "成功", + "Kc71c6a9": "上线失败", + "K56c686f8": "失败", + "K3ba29a85": "API", + "Kda8d5ea1": "上游", + "Kdefa9caa": "使用说明", + "K36856e71": "发布", + "K6382bbfd": "订阅管理", + "K2eef4e4": "订阅审批", + "Ka97bd9e5": "订阅方管理", + "K5974bf24": "管理", + "K3fa5c4c3": "调用拓扑图", + "Kb5c7b82d": "设置", + "K2472615e": "服务数量", + "Kc02aa5f1": "API数量", + "Ke08ff808": "添加日期", + "Kd7d84192": "姓名", + "Kc88e03b6": "团队角色", + "Kdf35c48c": "所有成员", + "K3818f03d": "审批", + "K56b4254f": "发布申请", + "Kd2c1a316": "登录", + "Kf076f63c": "请输入账号", + "K80a560a1": "账号", + "K25c895d5": "请输入密码", + "K551b0348": "密码", + "K480045ce": "Version (0)-(1)", + "Kadee8e49": "日志配置", + "K3453272": "APIPark 提供详尽的 API 调用日志,帮助企业监控、分析和审计 API 的运行状况。", + "K33c76dbc": "部门名称", + "K84829ca9": "父部门 ID", + "K4d7fc74b": "子部门名称", + "Ka16e6c44": "未激活、已禁用的成员无法加入到部门", + "Ked03ba97": "请选择成员需要新加入的部门", + "K5e237e06": "name", + "K184d3473": "添加账号", + "K1ecb35f2": "编辑成员信息", + "Ke6f00b44": "加入部门", + "K501cb1e7": "确定删除成员?此操作无法恢复,确认操作?", + "Kf20863b5": "成员与部门", + "K5f27a546": "输入用户名、邮箱查找成员", + "K26c698bb": "添加部门", + "Kb9cf2a7d": "添加子部门", + "Kc83551f5": "重命名", + "K3f1077c9": "设置成员和对应的角色,成员只能够看到权限范围内的功能和数据。", + "Kdce62a6": "搜索部门", + "K8ef69ee2": "密钥", + "Kba3507d6": "上传密钥", + "K93ac0f23": "密钥文件的后缀名一般为 .key 的文件内容", + "K7cdd1331": "上传证书", + "K6d91905d": "证书文件的后缀名一般为 .crt 或 .pem 的文件内容", + "Kd0f6ded7": "添加证书", + "Ke5732d60": "修改证书", + "K3ca07a70": "证书管理", + "Kdb927f83": "通过为 API 服务配置和管理 SSL 证书,企业可以加密数据传输,防止敏感信息被窃取或篡改。", + "K877985b7": "修改配置", + "Kdf66a675": "设置访问 API 的集群,让 API 在分布式环境中稳定运行,并且能够根据业务需求进行灵活扩展和优化。", + "Kaf074220": "未配置", + "K5878440c": "集群地址", + "K5e9022f8": "下一步", + "K8e7a0f80": "资源配置", + "Kabfe9512": "保存", + "K95c3fd8b": "设置角色的权限范围。", + "K138facd3": "系统级别角色", + "K6eac768d": "添加角色", + "Kb9c2cf02": "团队级别角色", + "Kb4ceecea": "添加子分类", + "K67479e88": "修改分类名称", + "K2bc75e2c": "添加分类", + "Kab4aab44": "重命名分类", + "K8e0e6977": "设置服务可选择的分类,方便团队成员快速找到API。", + "Ke595a20a": "分类名称", + "K9679728f": "父分类 ID", + "K9b2d08fd": "子分类名称", + "Kf14e76e5": "副本", + "K2e050340": "API 基础信息", + "K90f3c02f": "转发规则设置", + "K6ea8d549": "编辑文档", + "Kff5c18ac": "最后编辑人", + "K2eb99415": "转发规则", + "Ke93388fd": "编辑 API", + "K1b1ae3b0": "复制 API", + "K84aabfd4": "添加 API", + "K6a662463": "输入名称、URL 查找 API", + "K59bc6280": "API 详情", + "K2a16c93b": "单位:ms,最小值:1", + "K469e475a": "重试次数", + "Kd568e15c": "发布结果", + "K35f990b0": "查看详情", + "Kdbc1f6cb": "申请发布", + "Kb6860a3f": "回滚", + "Ka3494f4b": "请确认是否回滚?", + "Kb397a99f": "撤销申请", + "K7d401c0f": "请确认是否撤销申请?", + "Ke1b79b93": "终止发布", + "Ka2449180": "请确认是否终止发布?", + "K2cb02f38": "新建版本", + "Ka9c08390": "只允许上传PNG、JPG或SVG格式的图片", + "Kcf756b7a": "API 调用前缀", + "K43d101a": "选填,作为服务内所有API的前缀,比如host/{service_name}/{api_path},一旦保存无法修改", + "Kdc840242": "图标", + "K427a5bd5": "仅支持 .png .jpg .jpeg .svg 格式的图片文件, 大于 1KB 的文件将被压缩", + "K44bc352d": "Logo", + "Kf52a584d": "所属服务分类", + "K72b21be5": "设置服务展示在服务市场中的哪个分类下", + "Kde6bae17": "删除服务", + "K885ea699": "删除操作不可恢复,请谨慎操作!", + "K617f34f1": "最近一次更新者", + "K6ebca204": "最近一次更新时间", + "K39ab0358": "新增订阅方", + "K2d6658ed": "添加服务", + "K7b8f623f": "输入名称、ID、所属团队、负责人查找服务", + "Kdd9b5008": "后端默认使用的IP地址", + "K6bc47edb": "请求协议", + "Kc9acdb25": "负载均衡", + "K632dba5c": "转发 Host", + "Kc1f08a63": "重写域名", + "K628f6851": "超时时间", + "Kaff62621": "超时重试次数", + "Kc41ca30e": "调用频率限制", + "K813e1c0a": "团队名称", + "K692f5aa6": "团队 ID", + "K5de0bc2": "团队 ID(team_id)可用于检索团队,一旦保存无法修改。", + "Ka63dd985": "团队负责人", + "Ka6bcd272": "负责人对团队内的团队、服务、成员有管理权限", + "Ka2012bdd": "删除团队", + "Kbde1f3d": "服务数据清除后,方可删除", + "K395acc14": "移除成员", + "Kec46a57f": "添加成员", + "K48724410": "输入姓名查找", + "Kb9052305": "搜索用户名、邮箱", + "K5ece3bac": "设置团队和成员,然后你可以在团队内创建服务和应用、订阅API,成员只能看到所属团队内的服务和应用。", + "K510cdd27": "添加团队", + "K9244ae14": "输入名称、ID、负责人查找团队", + "Kc7b24b4b": "配置团队", + "Kecb51e2c": "旧密码", + "K8266bcf2": "新密码", + "Ka9aef039": "确认密码", + "Kcf42dcda": "两次密码不一致", + "Kf876a42d": "修改密码", + "K8ed884f": "管理个人账号", + "K9be8e1d7": "API调用统计", + "K521ab28e": "选择服务", + "Kcc8265e1": "选择API", + "K8aefc1e4": "请输入请求路径进行搜索", + "K50d471b2": "重置", + "Kee8ae330": "查询", + "Ka2c794a2": "导出", + "Kaf70c3b": "退出全屏", + "Kd22841a4": "(0)调用详情", + "K1512e983": "应用调用统计", + "Kb4d2007f": "请选择应用", + "K8c7f2d2e": "调用趋势", + "K657c3452": "(0)-(1)调用趋势", + "Kc04efb87": "调用量统计", + "Keb98266e": "加入总体数据对比", + "K18c2ed46": "(0)调用量", + "Kc3741830": "(0)调用成功率", + "Ka6aa5863": "请求总数", + "K9eaef42": "请求成功率", + "K7082a4af": "转发总数", + "K1ce386fb": "转发成功率", + "K87d6877e": "状态码4xx数", + "K4c8a54db": "状态码5xx数", + "Kd566283e": "调用总体趋势", + "Kd23a0be6": "请求报文量", + "Kec3e8361": "响应报文量", + "Ke6250744": "状态码4XX数", + "K2d79d4e1": "状态码5XX数", + "Kcf6553c6": "服务调用统计", + "Kffcfe375": "请选择服务", + "Ka65f739c": "调用详情", + "K89b7ac79": "API 请求量 Top10", + "Kc0915603": "应用调用量 Top10", + "Kf90b54": "服务被调用量 Top10", + "Kfb26388": "暂无请求统计数据", + "Kc8cbd8f8": "请求统计", + "K8dece48": "暂无转发统计数据", + "K1ee32434": "转发统计", + "Kcd125e4d": "暂无调用量统计数据", + "Kaa114e8b": "暂无报文量统计数据", + "K3ad84406": "报文量统计", + "K19a3ebe0": "请求成功数", + "Kcaa8259": "转发成功数", + "K888f038f": "失败状态码数", + "K42d2bef2": "平均响应时间(ms)", + "K9197c994": "最大响应时间(ms)", + "K7c2f3fee": "最小响应时间(ms)", + "K3d85ea54": "平均请求流量(KB)", + "Keec09d32": "最大请求流量(KB)", + "K3786b48": "最小请求流量(KB)", + "K5168eb63": "应用名称", + "K546e46f": "应用 ID", + "K4a1a14": "监控总览", + "K69741ea7": "服务被调用统计", + "K9c8d9933": "API 调用统计", + "K28cf9613": "每分钟", + "K18f25019": "每5分钟", + "Kf00f01ca": "每小时", + "Kfcda87fc": "每天", + "K29ec75dc": "每周", + "K145e4941": "亿", + "Ke6a935d": "万", + "K8f7abcab": " 次", + "K146477a8": "服务标签", + "K4de0af74": "服务分类", + "Kcce1af60": "订阅的服务", + "Kb6e9328f": "访问授权", + "Kb7e869a4": "应用管理", + "Kd59290a2": "搜索分类或标签", + "K6b75bdbc": "暂无API数据", + "Kd8a7a689": "搜索或选择应用", + "K4b15d6f5": "申请理由", + "Kb71b5a13": "鉴权类型", + "K4d1465ee": "Iss", + "K5dcd7ed8": "签名算法", + "K5b0eedd3": "Secret", + "K44f4ffe1": "RSA 公钥", + "Kc5ecd7d9": "用户名 JsonPath", + "K417d85cf": "校验字段", + "K3b82fe1d": "是否 Base64 加密", + "K49b5f4a3": "AK", + "K31418470": "SK", + "Kbfeb5297": "Apikey", + "K95764d1d": "删除应用", + "K217cb125": "鉴权详情", + "K2bb63eca": "添加鉴权", + "Kd74d69b7": "编辑鉴权", + "K9cbe1e0": "修改", + "Kd23d1716": "添加授权", + "K9dfa2c97": "永不过期", + "Kfa920c0": "到期时间", + "Kbeb4e991": "审批详情", + "Ked811bb1": "请确认是否取消订阅?", + "K50c39a62": "取消订阅申请", + "K1856c229": "请确认是否取消订阅申请?", + "K66ea2f0": "搜索服务", + "Kfeb2559b": "审批中", + "Ka2b6d281": "API 文档", + "K667bbbe7": "添加应用", + "Ka4b45550": "暂无服务描述", + "K3c7b175f": "订阅的服务数量:已通过 (0) 个,申请中 (1) 个", + "K850b4b2d": "状态码", + "Kbe3e9335": "退出测试", + "K370a3eb2": "服务市场", + "Kf7ec36d": "服务详情", + "K59cdbec3": "介绍", + "K4aa9ed2c": "申请", + "K6c060779": "服务信息", + "K8723422e": "接入应用", + "Kb97544cb": "供应方", + "Kb32f0afe": "分类", + "K81634069": "版本", + "K96a2f1c8": "无标签", + "K93d5a66e": "接入应用数量", + "K3e770a75": "鉴权 Token", + "K96059c69": "关联标签", + "K32263abd": "添加 Open Api", + "K7829bb78": "配置 Open Api", + "Kcdf76005": "Open Api", + "Ke2601944": "调用服务", + "K8504bca8": "放大", + "K693c1b41": "缩小" +} diff --git a/frontend/packages/common/src/locales/scan/zh-CN.json b/frontend/packages/common/src/locales/scan/zh-CN.json new file mode 100644 index 00000000..3787a6ec --- /dev/null +++ b/frontend/packages/common/src/locales/scan/zh-CN.json @@ -0,0 +1,570 @@ +{ + "Kc0e5ef9f": "工作空间", + "K48325b6": "搜索(0)名称", + "K3d7465f7":"文件日志", + "K3863c722": "我的", + "Kfe93ef35": "应用", + "Kb58e0c3f": "服务", + "Kc9e489f5": "团队", + "K61c89f5f": "API 市场", + "K16d71239": "仪表盘", + "K714c192d": "运行视图", + "Kd57dfe97": "系统拓扑图", + "K3fe97dcc": "系统设置", + "K67ef3525": "组织", + "K74aef1ad": "成员", + "Kf644225f": "角色", + "K958da71f": "服务分类管理", + "Kf270ca55": "运维与集成", + "Ke93d36ed": "集群", + "K481e8a05": "证书", + "Kca53edd0": "日志", + "Kb283e720": "资源", + "K631d646f": "Open API", + "K6535ff9c": "账号设置", + "Kf15499b4": "退出登录", + "Kabbd6e6": "文档", + "K1196b104": "APIPark - 企业API数据开放平台", + "K1f42de3": "HTTP 状态码", + "K4770dff4": "系统状态码", + "Kf89e58f1": "描述", + "K9e53c664": "提交", + "Kf8e7294c": "上一步", + "Ka0451c97": "取消", + "Kb1dedda3": "关闭", + "Kb2fc7600": "添加配置", + "K4e07217d": "编辑配置", + "K4ea968fe": "编辑(0)", + "Ka7aaaeb": "添加(0)", + "Kaff78ecf": "请输入Key", + "K65d46535": "请输入Value", + "Kc14b2ea3": "返回", + "K11d3633a": "ID", + "Kbff43de3": "名称", + "K16ca79ef": "Driver", + "K7a369eef": "已发布", + "Kcfa1a4d2": "下线", + "K771dc3b7": "上线", + "K530f5951": "查看", + "Kecbd7449": "删除", + "K1cbe2507": "确认", + "Ka1d885c1": "添加", + "Kad207008": "编辑", + "K1ff96ff": "申请系统", + "K9bf855d6": "所属团队", + "K11b994ed": "申请人", + "K939baba7": "申请时间", + "Kdab2e63b": "版本号", + "K8b29c460": "版本说明", + "K36a72ad1": "API 列表", + "K54e44357": "上游列表", + "Kb8e8e6f5": "备注", + "K1ab0ae5b": "申请原因", + "K53c00c3c": "审核意见", + "K7edf331d": "时间", + "Kef45b208": "近1小时", + "K9dbf22b8": "近24小时", + "K820fbfab": "近3天", + "Kd6d28fc": "近7天", + "K23fda291": "暂无操作权限,请联系管理员分配。", + "K4618cb0a": "微信小程序", + "Ka854f511": "获取文件,需填路径", + "Kaa11a695": "暂不支持生成非 HTTPS 或非 HTTP 协议的代码示例", + "Kbe46924e": "搜索编程语言...", + "Ke8e4f258": "编程语言", + "K29c07a47": "成功示例", + "K1f5c814d": "失败示例", + "K4ef022d7": "默认 text/html;charset=UTF-8", + "Kd061b5bf": "暂未填写示例", + "Kc14cec33": "Binary", + "K48b4d9e3": "请求头部", + "Kcd347eaf": "请求体", + "K9e100bfe": "Query 参数", + "K3e9f12fd": "REST 参数", + "K2bfa290c": "api request editor", + "Kb36d111a": "返回头部", + "K980bde79": "返回值", + "Kb04d201a": "更多设置", + "Kee74f5b4": "添加子参数", + "Kc7d3106c": "向下添加行", + "Keaabd222": "标签", + "K8ad2c50e": "参数名", + "K67d68dd1": "类型", + "K29245f47": "必需", + "Ke32cbcd3": "示例", + "Kc13936c6": "输入 URL 或 cURL", + "Ka1ede006": "HTTP", + "K152ac44e": "参数位置", + "K1660ae72": "匹配类型", + "K91ced765": "参数值", + "K5b265628": "操作类型", + "K1826982d": "新增或修改", + "Kd65b55f5": "匹配参数值", + "K15f35bf2": "转发上游路径", + "K79dec0dd": "请求超时时间", + "K7d465645": "绑定上游服务", + "K63a6404d": "重试时间", + "K47740727": "转发上游请求头", + "K2b605d42": "More", + "K1df9fbd5": "导入", + "K5e85df18": "导入格式", + "K9eaf7885": "全量替换", + "Kf8c3a80b": "在末端插入", + "Kd96b2d7d": "增量更新", + "Kf2fc08eb": "请求头", + "Ka45f1d8": "Rest 参数", + "K94bb113a": "大小", + "K359919b5": "另存为文件", + "K38bf1b90": "响应", + "K59f4186e": "响应头", + "K5f1e23fd": "正文", + "Kf404ef7d": "发送(Enter)", + "K2dbfd648": "中止", + "Kacabc771": "秒", + "K13ae6a93": "复制", + "Ke54a14a3": "格式化", + "K43934f6d": "搜索", + "K741decac": "替代", + "Kd507abff": "确定", + "Kca2d1624": "The (0) must not be negative.", + "K792b255a": "The (0) must be greater than or equal to the (1).", + "Kf0bed26d": "值枚举", + "K633a03ca": "枚举", + "Kd2766caf": "最小长度", + "Kd6d52485": "最大长度", + "Kea15f66c": "最小值", + "K1af340ff": "最大值", + "K68691e16": "将文件拖拽至此处上传,或点击选择文件上传", + "Kcec46ae": "Upload Files", + "K760fb044": "Files Selected", + "Kea2bdee0": "请填写接口名称", + "K49053438": "详细说明", + "K148f6fa4": "高级匹配", + "K3ae4c789": "转发配置", + "K2f4d0a37": "请求参数", + "Kde2d6dbd": "返回示例", + "K70e6069c": "测试 API", + "Ke4603448": "请求 Header", + "K89fd86b3": "请求 Body", + "K8747e3c4": "请求示例代码", + "K8613e6e7": "响应示例", + "Kab1c2159": "响应 Header", + "Kd2be51d1": "响应 Body", + "K831aa6c0": "申请方-应用", + "K58ca9485": "申请服务", + "K283f55b4": "服务所属系统", + "Kd60d204": "服务所属团队", + "K3a9a3b75": "审批状态", + "K4f57b2de": "审批人", + "K31dabc6b": "审批时间", + "K8582af3f": "拒绝", + "K54e27f57": "通过", + "K7eeca185": "审批完成", + "Kd4061161": "发布审批中", + "K823bfe63": "在线", + "K97ddb3f8": "-", + "Kc9315fa1": "已拒绝", + "K3fbe7511": "发布异常", + "Ke64e695c": "发布中", + "K17f93984": "API 名称", + "K1365fe45": "请求方式", + "Kc380335f": "路径", + "K4ee62e8": "该 API 缺失(0)(1)(2)请先补充", + "K385591f3": "转发信息,", + "K68415c14": "文档信息,", + "K133b75e9": "上游信息,", + "Kad98e030": "上游类型", + "Kdeed8399": "静态上游", + "K78b1ca25": "地址", + "K6208054": "待审批", + "K1be7f021": "审批通过", + "K677a4959": "发布终止", + "Kfd6d2d3d": "已关闭", + "K9d7e880a": "发布版本", + "K855135f": "创建版本时间", + "Kcbf39b82": "版本状态", + "K339d15b5": "创建人", + "K7194cea2": "审核时间", + "K69827c60": "发布状态", + "K1644b775": "新增", + "K4fdf4dcc": "变更", + "K33d66e26": "无变更", + "K9b70c007": "缺失字段", + "Kd85208a3": "驳回", + "K8adf7f8b": "审核中", + "Kad6aa439": "已订阅", + "K3118fdb0": "取消订阅", + "K9a68443b": "取消申请", + "K18307d56": "手动添加", + "K705fe9f5": "订阅申请", + "Kbc96ebec": "申请方应用", + "K1f89176d": "申请方所属团队", + "Kfe731dfc": "操作", + "K71661ee8": "必填项", + "Kcbee3f8": "不是有效邮箱地址", + "K442cfba1": "请输入", + "K3bb646e4": "请选择", + "Ka4ecfa40": "英文数字下划线任意一种,首字母必须为英文", + "K39686a7f": "支持字母开头、英文数字中横线下划线组合", + "K4d6a0190": "选择拒绝时,审批意见为必填", + "K37318b68": "无法连接集群,请检查集群地址是否正确或防火墙配置", + "K7f0c746d": "操作成功", + "K6a365d01": "操作失败", + "K978062b6": "正在操作", + "Kca7bd6d4": "正在加载数据", + "K3c93b77e": "获取数据失败", + "Ke108c369": "登录成功", + "K9168d3e": "退出成功,将跳转至登录页", + "K2f8a7ab7": "未填写审核意见", + "Kb858d78a": "复制成功", + "K26e85d15": "复制失败,请手动复制", + "K5cfdd950": "该数据删除后将无法找回,请确认是否删除?", + "K2a3f24ac": "默认工作表", + "K7e1ab4b0": "至", + "Kf1b166e7": "详情", + "K28555332": "暂不支持带有双斜杠//的url", + "Keb9fcdad": "用户名", + "Kc654b275": "邮箱", + "Kbe2ecc69": "部门", + "K759fb403": "状态", + "K52c8a730": "启用", + "K718c9310": "禁用", + "K2c5882be": "绑定域名", + "K1cc07937": "过期日期", + "K8b7c2592": "更新者", + "Keefda53d": "更新时间", + "K9f3db3ca": "集群名称", + "Ke7487049": "集群 ID", + "Kb660ffe8": "节点名称", + "Kf12b3034": "管理地址", + "K867e6faf": "服务地址", + "K37348a5e": "集群同步地址", + "K151d2bb7": "环境名称", + "Kfa744afd": "集群数量", + "K23a3bd72": "异常", + "Ke039b9b5": "正常", + "K5c123bad": "角色名称", + "K76036e25": "HTTP 请求头", + "K8d4cbf50": "Cookie", + "K44607e3f": "全等匹配", + "Kc287500a": "前缀匹配", + "Kfc0b1147": "后缀匹配", + "Ka4a92043": "子串匹配", + "K30b2e44f": "非等匹配", + "Kb1587991": "空值匹配", + "K1e97dbd8": "存在匹配", + "Kc8ee3e62": "不存在匹配", + "K87c5a801": "区分大小写的正则匹配", + "K95f062f1": "不区分大小写的正则匹配", + "Kfbd230a5": "任意匹配", + "K413b9869": "服务名称", + "K1e84ad04": "服务 ID", + "K72b0c0b3": "API 数量", + "Kf7200cd9": "负责人", + "Kefaf9956": "创建时间", + "K98db2cb9": "申请状态", + "Ke792d01c": "所属服务", + "K61b62ace": "来源", + "Ke63767cf": "添加时间", + "K3a67ea90": "订阅方", + "K442937c4": "订阅时间", + "K34111022": "协议/方法", + "K62d10724": "URL", + "Ka9481f95": "创建者", + "Kf88d56fd": "上游 ID", + "K11a92fb2": "更新人", + "K2c2bc64f": "动态服务发现", + "Kc9a2a716": "HTTPS", + "Ka7f8266f": "带权轮询", + "Kd17edabd": "IP Hash", + "Kaeba0229": "透传客户端请求 Host", + "K6d7e2fd0": "使用上游服务 Host", + "K31332633": "重写 Host", + "Ke65db976": "权重", + "Kf966b12d": "内部服务:可通过网关访问,但不展示在服务广场", + "Kfc939e49": "公开服务:可通过网关访问,展示在服务广场,可被其他应用订阅", + "Ke96ccf45": " ", + "K5582ac8": "请求路径", + "K92485dd1": "所有 API", + "Ke64e43a": "隐藏鉴权信息", + "K1a78e6f0": "过期时间", + "K40bbb0a3": "服务ID", + "K9919285b": "服务类型", + "K63938137": "公开服务", + "Kfb20a12": "内部服务", + "Kedd64e4d": "停用", + "Ka29b346f": "地址(IP 端口或域名)", + "K63b1e0dc": "权重(0-999)", + "K74ab00a3": "已审批", + "Kea996156": "发布申请记录", + "Kbea7d266": "所属系统", + "Ka36c13cc": "调用系统名称", + "Kd78d73a7": "调用服务名称", + "K73c144eb": "当前系统名称", + "K285bd65e": "被调用服务名称", + "K5cbab635": "被调用系统名称", + "K93c2696e": "上线结果", + "K43fcaf94": "成功", + "Kc71c6a9": "上线失败", + "K56c686f8": "失败", + "K3ba29a85": "API", + "Kda8d5ea1": "上游", + "Kdefa9caa": "使用说明", + "K36856e71": "发布", + "K6382bbfd": "订阅管理", + "K2eef4e4": "订阅审批", + "Ka97bd9e5": "订阅方管理", + "K5974bf24": "管理", + "K3fa5c4c3": "调用拓扑图", + "Kb5c7b82d": "设置", + "K2472615e": "服务数量", + "Kc02aa5f1": "API数量", + "Ke08ff808": "添加日期", + "Kd7d84192": "姓名", + "Kc88e03b6": "团队角色", + "Kdf35c48c": "所有成员", + "K3818f03d": "审批", + "K56b4254f": "发布申请", + "Kd2c1a316": "登录", + "Kf076f63c": "请输入账号", + "K80a560a1": "账号", + "K25c895d5": "请输入密码", + "K551b0348": "密码", + "K480045ce": "Version (0)-(1)", + "Kadee8e49": "日志配置", + "K3453272": "APIPark 提供详尽的 API 调用日志,帮助企业监控、分析和审计 API 的运行状况。", + "K33c76dbc": "部门名称", + "K84829ca9": "父部门 ID", + "K4d7fc74b": "子部门名称", + "Ka16e6c44": "未激活、已禁用的成员无法加入到部门", + "Ked03ba97": "请选择成员需要新加入的部门", + "K5e237e06": "name", + "K184d3473": "添加账号", + "K1ecb35f2": "编辑成员信息", + "Ke6f00b44": "加入部门", + "K501cb1e7": "确定删除成员?此操作无法恢复,确认操作?", + "Kf20863b5": "成员与部门", + "K5f27a546": "输入用户名、邮箱查找成员", + "K26c698bb": "添加部门", + "Kb9cf2a7d": "添加子部门", + "Kc83551f5": "重命名", + "K3f1077c9": "设置成员和对应的角色,成员只能够看到权限范围内的功能和数据。", + "Kdce62a6": "搜索部门", + "K8ef69ee2": "密钥", + "Kba3507d6": "上传密钥", + "K93ac0f23": "密钥文件的后缀名一般为 .key 的文件内容", + "K7cdd1331": "上传证书", + "K6d91905d": "证书文件的后缀名一般为 .crt 或 .pem 的文件内容", + "Kd0f6ded7": "添加证书", + "Ke5732d60": "修改证书", + "K3ca07a70": "证书管理", + "Kdb927f83": "通过为 API 服务配置和管理 SSL 证书,企业可以加密数据传输,防止敏感信息被窃取或篡改。", + "K877985b7": "修改配置", + "Kdf66a675": "设置访问 API 的集群,让 API 在分布式环境中稳定运行,并且能够根据业务需求进行灵活扩展和优化。", + "Kaf074220": "未配置", + "K5878440c": "集群地址", + "K5e9022f8": "下一步", + "K8e7a0f80": "资源配置", + "Kabfe9512": "保存", + "K95c3fd8b": "设置角色的权限范围。", + "K138facd3": "系统级别角色", + "K6eac768d": "添加角色", + "Kb9c2cf02": "团队级别角色", + "Kb4ceecea": "添加子分类", + "K67479e88": "修改分类名称", + "K2bc75e2c": "添加分类", + "Kab4aab44": "重命名分类", + "K8e0e6977": "设置服务可选择的分类,方便团队成员快速找到API。", + "Ke595a20a": "分类名称", + "K9679728f": "父分类 ID", + "K9b2d08fd": "子分类名称", + "Kf14e76e5": "副本", + "K2e050340": "API 基础信息", + "K90f3c02f": "转发规则设置", + "K6ea8d549": "编辑文档", + "Kff5c18ac": "最后编辑人", + "K2eb99415": "转发规则", + "Ke93388fd": "编辑 API", + "K1b1ae3b0": "复制 API", + "K84aabfd4": "添加 API", + "K6a662463": "输入名称、URL 查找 API", + "K59bc6280": "API 详情", + "K2a16c93b": "单位:ms,最小值:1", + "K469e475a": "重试次数", + "Kd568e15c": "发布结果", + "K35f990b0": "查看详情", + "Kdbc1f6cb": "申请发布", + "Kb6860a3f": "回滚", + "Ka3494f4b": "请确认是否回滚?", + "Kb397a99f": "撤销申请", + "K7d401c0f": "请确认是否撤销申请?", + "Ke1b79b93": "终止发布", + "Ka2449180": "请确认是否终止发布?", + "K2cb02f38": "新建版本", + "Ka9c08390": "只允许上传PNG、JPG或SVG格式的图片", + "Kcf756b7a": "API 调用前缀", + "K43d101a": "选填,作为服务内所有API的前缀,比如host/{service_name}/{api_path},一旦保存无法修改", + "Kdc840242": "图标", + "K427a5bd5": "仅支持 .png .jpg .jpeg .svg 格式的图片文件, 大于 1KB 的文件将被压缩", + "K44bc352d": "Logo", + "Kf52a584d": "所属服务分类", + "K72b21be5": "设置服务展示在服务市场中的哪个分类下", + "Kde6bae17": "删除服务", + "K885ea699": "删除操作不可恢复,请谨慎操作!", + "K617f34f1": "最近一次更新者", + "K6ebca204": "最近一次更新时间", + "K39ab0358": "新增订阅方", + "K2d6658ed": "添加服务", + "K7b8f623f": "输入名称、ID、所属团队、负责人查找服务", + "Kdd9b5008": "后端默认使用的IP地址", + "K6bc47edb": "请求协议", + "Kc9acdb25": "负载均衡", + "K632dba5c": "转发 Host", + "Kc1f08a63": "重写域名", + "K628f6851": "超时时间", + "Kaff62621": "超时重试次数", + "Kc41ca30e": "调用频率限制", + "K813e1c0a": "团队名称", + "K692f5aa6": "团队 ID", + "K5de0bc2": "团队 ID(team_id)可用于检索团队,一旦保存无法修改。", + "Ka63dd985": "团队负责人", + "Ka6bcd272": "负责人对团队内的团队、服务、成员有管理权限", + "Ka2012bdd": "删除团队", + "Kbde1f3d": "服务数据清除后,方可删除", + "K395acc14": "移除成员", + "Kec46a57f": "添加成员", + "K48724410": "输入姓名查找", + "Kb9052305": "搜索用户名、邮箱", + "K5ece3bac": "设置团队和成员,然后你可以在团队内创建服务和应用、订阅API,成员只能看到所属团队内的服务和应用。", + "K510cdd27": "添加团队", + "K9244ae14": "输入名称、ID、负责人查找团队", + "Kc7b24b4b": "配置团队", + "Kecb51e2c": "旧密码", + "K8266bcf2": "新密码", + "Ka9aef039": "确认密码", + "Kcf42dcda": "两次密码不一致", + "Kf876a42d": "修改密码", + "K8ed884f": "管理个人账号", + "K9be8e1d7": "API调用统计", + "K521ab28e": "选择服务", + "Kcc8265e1": "选择API", + "K8aefc1e4": "请输入请求路径进行搜索", + "K50d471b2": "重置", + "Kee8ae330": "查询", + "Ka2c794a2": "导出", + "Kaf70c3b": "退出全屏", + "Kd22841a4": "(0)调用详情", + "K1512e983": "应用调用统计", + "Kb4d2007f": "请选择应用", + "K8c7f2d2e": "调用趋势", + "K657c3452": "(0)-(1)调用趋势", + "Kc04efb87": "调用量统计", + "Keb98266e": "加入总体数据对比", + "K18c2ed46": "(0)调用量", + "Kc3741830": "(0)调用成功率", + "Ka6aa5863": "请求总数", + "K9eaef42": "请求成功率", + "K7082a4af": "转发总数", + "K1ce386fb": "转发成功率", + "K87d6877e": "状态码4xx数", + "K4c8a54db": "状态码5xx数", + "Kd566283e": "调用总体趋势", + "Kd23a0be6": "请求报文量", + "Kec3e8361": "响应报文量", + "Ke6250744": "状态码4XX数", + "K2d79d4e1": "状态码5XX数", + "Kcf6553c6": "服务调用统计", + "Kffcfe375": "请选择服务", + "Ka65f739c": "调用详情", + "K89b7ac79": "API 请求量 Top10", + "Kc0915603": "应用调用量 Top10", + "Kf90b54": "服务被调用量 Top10", + "Kfb26388": "暂无请求统计数据", + "Kc8cbd8f8": "请求统计", + "K8dece48": "暂无转发统计数据", + "K1ee32434": "转发统计", + "Kcd125e4d": "暂无调用量统计数据", + "Kaa114e8b": "暂无报文量统计数据", + "K3ad84406": "报文量统计", + "K19a3ebe0": "请求成功数", + "Kcaa8259": "转发成功数", + "K888f038f": "失败状态码数", + "K42d2bef2": "平均响应时间(ms)", + "K9197c994": "最大响应时间(ms)", + "K7c2f3fee": "最小响应时间(ms)", + "K3d85ea54": "平均请求流量(KB)", + "Keec09d32": "最大请求流量(KB)", + "K3786b48": "最小请求流量(KB)", + "K5168eb63": "应用名称", + "K546e46f": "应用 ID", + "K4a1a14": "监控总览", + "K69741ea7": "服务被调用统计", + "K9c8d9933": "API 调用统计", + "K28cf9613": "每分钟", + "K18f25019": "每5分钟", + "Kf00f01ca": "每小时", + "Kfcda87fc": "每天", + "K29ec75dc": "每周", + "K145e4941": "亿", + "Ke6a935d": "万", + "K8f7abcab": " 次", + "K146477a8": "服务标签", + "K4de0af74": "服务分类", + "Kcce1af60": "订阅的服务", + "Kb6e9328f": "访问授权", + "Kb7e869a4": "应用管理", + "Kd59290a2": "搜索分类或标签", + "K6b75bdbc": "暂无API数据", + "Kd8a7a689": "搜索或选择应用", + "K4b15d6f5": "申请理由", + "Kb71b5a13": "鉴权类型", + "K4d1465ee": "Iss", + "K5dcd7ed8": "签名算法", + "K5b0eedd3": "Secret", + "K44f4ffe1": "RSA 公钥", + "Kc5ecd7d9": "用户名 JsonPath", + "K417d85cf": "校验字段", + "K3b82fe1d": "是否 Base64 加密", + "K49b5f4a3": "AK", + "K31418470": "SK", + "Kbfeb5297": "Apikey", + "K95764d1d": "删除应用", + "K217cb125": "鉴权详情", + "K2bb63eca": "添加鉴权", + "Kd74d69b7": "编辑鉴权", + "K9cbe1e0": "修改", + "Kd23d1716": "添加授权", + "K9dfa2c97": "永不过期", + "Kfa920c0": "到期时间", + "Kbeb4e991": "审批详情", + "Ked811bb1": "请确认是否取消订阅?", + "K50c39a62": "取消订阅申请", + "K1856c229": "请确认是否取消订阅申请?", + "K66ea2f0": "搜索服务", + "Kfeb2559b": "审批中", + "Ka2b6d281": "API 文档", + "K667bbbe7": "添加应用", + "Ka4b45550": "暂无服务描述", + "K3c7b175f": "订阅的服务数量:已通过 (0) 个,申请中 (1) 个", + "K850b4b2d": "状态码", + "Kbe3e9335": "退出测试", + "K370a3eb2": "服务市场", + "Kf7ec36d": "服务详情", + "K59cdbec3": "介绍", + "K4aa9ed2c": "申请", + "K6c060779": "服务信息", + "K8723422e": "接入应用", + "Kb97544cb": "供应方", + "Kb32f0afe": "分类", + "K81634069": "版本", + "K96a2f1c8": "无标签", + "K93d5a66e": "接入应用数量", + "K3e770a75": "鉴权 Token", + "K96059c69": "关联标签", + "K32263abd": "添加 Open Api", + "K7829bb78": "配置 Open Api", + "Kcdf76005": "Open Api", + "Ke2601944": "调用服务", + "K8504bca8": "放大", + "K693c1b41": "缩小" +} \ No newline at end of file diff --git a/frontend/packages/common/src/monacoConfig.ts b/frontend/packages/common/src/monacoConfig.ts index 0bb1cdbe..97b65136 100644 --- a/frontend/packages/common/src/monacoConfig.ts +++ b/frontend/packages/common/src/monacoConfig.ts @@ -1,4 +1,3 @@ -import { loader } from '@monaco-editor/react'; import * as monaco from 'monaco-editor'; import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'; import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'; diff --git a/frontend/packages/common/src/utils/navigation.tsx b/frontend/packages/common/src/utils/navigation.tsx index 3b96d42d..1e48c7c4 100644 --- a/frontend/packages/common/src/utils/navigation.tsx +++ b/frontend/packages/common/src/utils/navigation.tsx @@ -1,5 +1,7 @@ +import { MenuProps } from "antd"; -import { MenuItem } from "@common/components/aoplatform/Navigation"; + +export type MenuItem = Required['items'][number]; export function getNavItem( label: React.ReactNode, diff --git a/frontend/packages/common/src/utils/systemRunning.ts b/frontend/packages/common/src/utils/systemRunning.ts index 6c71a68f..fb9f269e 100644 --- a/frontend/packages/common/src/utils/systemRunning.ts +++ b/frontend/packages/common/src/utils/systemRunning.ts @@ -251,7 +251,7 @@ import { TopologyProjectItem, TopologyServiceItem } from "@core/pages/systemRun // }, // defaultEdge: { // type: 'line-running', -// label: '详情', +// label: $t('详情', // labelCfg: { // style: { // fill: '5B8FF9', diff --git a/frontend/packages/common/src/utils/validate.ts b/frontend/packages/common/src/utils/validate.ts index 9e948ad2..e0a63f5e 100644 --- a/frontend/packages/common/src/utils/validate.ts +++ b/frontend/packages/common/src/utils/validate.ts @@ -1,7 +1,8 @@ +import { $t } from "@common/locales"; export const validateUrlSlash = (_, value) => { if (value && value.includes('//')) { - return Promise.reject(new Error('暂不支持带有双斜杠//的url')); + return Promise.reject(new Error($t('暂不支持带有双斜杠//的url'))); } return Promise.resolve(); }; \ No newline at end of file diff --git a/frontend/packages/core/index.html b/frontend/packages/core/index.html index cb9482b5..bde37005 100644 --- a/frontend/packages/core/index.html +++ b/frontend/packages/core/index.html @@ -10,7 +10,7 @@
- - + + diff --git a/frontend/packages/core/src/App.css b/frontend/packages/core/src/App.css index db6ae5ce..ef705ac1 100644 --- a/frontend/packages/core/src/App.css +++ b/frontend/packages/core/src/App.css @@ -1,5 +1,12 @@ @tailwind base; @tailwind components; + +@layer components { + .button-bottom-default { + @apply border-[0px] border-b-[1px] border-solid border-BORDER; + } +} + @tailwind utilities; @@ -36,17 +43,6 @@ background-color:'transparent' } -/* .ant-layout-sider-children{ - ul.ant-menu.ant-menu-root.ant-menu-inline > li:not(.ant-menu-item-selected) { - border-radius: 10px; - background-color: rgba(255,255,255,0.1); - border: 1px solid rgba(255,255,255,0.15); - } - .ant-menu-item { - height:40px; - margin-block:10px; - } -} */ .apipark-layout-global-header-collapsed-button{ color:hsl(0, 0%, 100%); diff --git a/frontend/packages/core/src/App.tsx b/frontend/packages/core/src/App.tsx index 9353440c..72c38005 100644 --- a/frontend/packages/core/src/App.tsx +++ b/frontend/packages/core/src/App.tsx @@ -1,11 +1,22 @@ import './App.css' -import { ConfigProvider } from 'antd'; +import { ConfigProvider, ConfigProviderProps, Radio, RadioChangeEvent } from 'antd'; import RenderRoutes from '@core/components/aoplatform/RenderRoutes'; import {BreadcrumbProvider} from "@common/contexts/BreadcrumbContext.tsx"; import { StyleProvider } from '@ant-design/cssinjs'; import zhCN from 'antd/locale/zh_CN'; +import enUS from 'antd/locale/en_US'; import useInitializeMonaco from "@common/hooks/useInitializeMonaco"; +import { useEffect, useState } from 'react'; +import 'dayjs/locale/zh-cn'; +import dayjs from 'dayjs'; +import { useTranslation } from "react-i18next"; +import { useGlobalContext } from '@common/contexts/GlobalStateContext'; + +type Locale = ConfigProviderProps['locale']; + +dayjs.locale('en'); + const antdComponentThemeToken = { token: { @@ -129,12 +140,21 @@ const antdComponentThemeToken = { } function App() { + const [locale, setLocal] = useState(enUS); useInitializeMonaco() + const { state} = useGlobalContext() + useEffect(() => { + console.log(state.language) + dayjs.locale(state.language); + setLocal(state.language === 'cn' ? zhCN : enUS); + },[state.language]) + + return ( diff --git a/frontend/packages/core/src/components/aoplatform/RenderRoutes.tsx b/frontend/packages/core/src/components/aoplatform/RenderRoutes.tsx index 0eba5332..ed6360f0 100644 --- a/frontend/packages/core/src/components/aoplatform/RenderRoutes.tsx +++ b/frontend/packages/core/src/components/aoplatform/RenderRoutes.tsx @@ -338,16 +338,6 @@ const PUBLIC_ROUTES:RouteConfig[] = [ } ] }, - { - path:'logretrieval', - lazy:lazy(() => import(/* webpackChunkName: "[request]" */ '@core/pages/logRetrieval/LogRetrieval.tsx')), - key:uuidv4(), - }, - { - path:'auditlog', - lazy:lazy(() => import(/* webpackChunkName: "[request]" */ '@core/pages/auditLog/AuditLog.tsx')), - key:uuidv4(), - }, { path:'assets', component:

设计中

, diff --git a/frontend/packages/core/src/const/member/const.tsx b/frontend/packages/core/src/const/member/const.tsx index ed2bb056..b785bff2 100644 --- a/frontend/packages/core/src/const/member/const.tsx +++ b/frontend/packages/core/src/const/member/const.tsx @@ -1,11 +1,12 @@ -import { ProColumns } from "@ant-design/pro-components"; +import { PageProColumns } from "@common/components/aoplatform/PageList"; import { MemberTableListItem } from "./type"; +import { $t } from "@common/locales"; -export const MEMBER_TABLE_COLUMNS: ProColumns[] = [ +export const MEMBER_TABLE_COLUMNS: PageProColumns[] = [ { - title: '用户名', + title:$t('用户名'), dataIndex: 'name', ellipsis:true, width:160, @@ -15,12 +16,12 @@ export const MEMBER_TABLE_COLUMNS: ProColumns[] = [ }, }, { - title: '邮箱', + title:$t('邮箱'), dataIndex: 'email', ellipsis:true, }, { - title: '部门', + title:$t('部门'), dataIndex: 'department', ellipsis:true, filterMode:'tree', @@ -31,20 +32,20 @@ export const MEMBER_TABLE_COLUMNS: ProColumns[] = [ filterSearch: true, }, { - title: '角色', + title:$t('角色'), dataIndex: 'roles', ellipsis:true, width:200 }, { - title:'状态', + title:$t('状态'), dataIndex:'enable', valueType: 'select', filters: true, onFilter: true, valueEnum:new Map([ - [true,启用], - [false,禁用], + [true,{$t('启用')}], + [false,{$t('禁用')}], ]) } ]; diff --git a/frontend/packages/core/src/const/partitions/const.tsx b/frontend/packages/core/src/const/partitions/const.tsx index 1dd04fe5..cc5f7f43 100644 --- a/frontend/packages/core/src/const/partitions/const.tsx +++ b/frontend/packages/core/src/const/partitions/const.tsx @@ -1,12 +1,13 @@ -import { ProColumns } from "@ant-design/pro-components"; import { PartitionCertTableListItem, PartitionClusterNodeModalTableListItem, PartitionClusterNodeTableListItem, PartitionClusterTableListItem, PartitionTableListItem } from "./types"; import { ColumnType } from "antd/es/table"; import CopyAddrList from "@common/components/aoplatform/CopyAddrList"; +import { $t } from "@common/locales"; +import { PageProColumns } from "@common/components/aoplatform/PageList"; -export const PARTITION_CERT_TABLE_COLUMNS: ProColumns[] = [ +export const PARTITION_CERT_TABLE_COLUMNS: PageProColumns[] = [ { - title: '证书', + title:$t('证书'), dataIndex: 'name', ellipsis:true, width:160, @@ -16,7 +17,7 @@ export const PARTITION_CERT_TABLE_COLUMNS: ProColumns( entity.domains.join(',') @@ -24,7 +25,7 @@ export const PARTITION_CERT_TABLE_COLUMNS: ProColumns[] = [ +export const PARTITION_CLUSTER_TABLE_COLUMNS : PageProColumns[] = [ { - title: '集群名称', + title:$t('集群名称'), dataIndex: 'name', ellipsis:true, width:160, @@ -66,13 +67,13 @@ export const PARTITION_CLUSTER_TABLE_COLUMNS : ProColumns[] = [ +export const PARTITION_CLUSTER_NODE_COLUMNS: PageProColumns[] = [ { - title: '节点名称', + title:$t('节点名称'), dataIndex: 'name', ellipsis:true, fixed:'left', @@ -102,28 +103,28 @@ export const PARTITION_CLUSTER_NODE_COLUMNS: ProColumns() }, { - title: '服务地址', + title:$t('服务地址'), dataIndex: 'serviceAddress', ellipsis:true, width:230, render:(_,entity)=>() }, { - title: '集群同步地址', + title:$t('集群同步地址'), dataIndex: 'peerAddress', ellipsis:true, width:230, render:(_,entity)=>() }, { - title: '状态', + title:$t('状态'), dataIndex: 'status', ellipsis:true, width:86, @@ -138,20 +139,20 @@ export const PARTITION_CLUSTER_NODE_COLUMNS: ProColumns[] = [ - {title:'名称', dataIndex:'name',width:200, + {title:$t('名称'), dataIndex:'name',width:200, ellipsis:true, fixed:'left'}, - {title:'管理地址', dataIndex:'managerAddress',width:240,ellipsis:true,render:(_,entity)=>()}, - {title:'服务地址', dataIndex:'serviceAddress',width:240,ellipsis:true,render:(_,entity)=>()}, - {title:'状态', dataIndex:'status', + {title:$t('管理地址'), dataIndex:'managerAddress',width:240,ellipsis:true,render:(_,entity)=>()}, + {title:$t('服务地址'), dataIndex:'serviceAddress',width:240,ellipsis:true,render:(_,entity)=>()}, + {title:$t('状态'), dataIndex:'status', render:(text)=>( {ClusterStatusEnum[text]} )} ] -export const PARTITION_LIST_COLUMNS: ProColumns[] = [ +export const PARTITION_LIST_COLUMNS: PageProColumns[] = [ { - title: '环境名称', + title:$t('环境名称'), dataIndex: 'name', ellipsis:true, fixed:'left', @@ -160,20 +161,20 @@ export const PARTITION_LIST_COLUMNS: ProColumns[] = [ }, }, { - title: 'ID', + title:$t('ID'), dataIndex: 'id', ellipsis:true, width:140, }, // { - // title: '集群数量', + // title:$t('集群数量', // dataIndex: 'clusterNum', // sorter: (a,b)=> { // return a.clusterNum - b.clusterNum // }, // }, { - title: '更新者', + title:$t('更新者'), dataIndex: ['updater','name'], ellipsis: true, filters: true, @@ -183,7 +184,7 @@ export const PARTITION_LIST_COLUMNS: ProColumns[] = [ filterSearch: true }, { - title: '更新时间', + title:$t('更新时间'), dataIndex: 'updateTime', ellipsis:true, width:182, @@ -193,9 +194,9 @@ export const PARTITION_LIST_COLUMNS: ProColumns[] = [ }, ]; -export enum ClusterStatusEnum { - '异常', - '正常' +export const ClusterStatusEnum ={ + 0: $t('异常'), + 1: $t('正常') } export const DASHBOARD_SETTING_DRIVER_OPTION_LIST = [ diff --git a/frontend/packages/core/src/const/role/const.tsx b/frontend/packages/core/src/const/role/const.tsx index 58093888..ca4f2cab 100644 --- a/frontend/packages/core/src/const/role/const.tsx +++ b/frontend/packages/core/src/const/role/const.tsx @@ -1,7 +1,8 @@ +import { $t } from "@common/locales" export const ROLE_TABLE_COLUMNS = [ { - title: '角色名称', + title:$t('角色名称'), dataIndex: 'name', ellipsis:true, fixed:'left', diff --git a/frontend/packages/core/src/const/system/const.tsx b/frontend/packages/core/src/const/system/const.tsx index eff6113f..a48c4b98 100644 --- a/frontend/packages/core/src/const/system/const.tsx +++ b/frontend/packages/core/src/const/system/const.tsx @@ -1,4 +1,3 @@ -import { ProColumns } from "@ant-design/pro-components"; import { GlobalNodeItem, MyServiceTableListItem, NodeItem, ProxyHeaderItem, ServiceApiTableListItem, SimpleApiItem, SystemApiTableListItem, SystemAuthorityTableListItem, SystemMemberTableListItem, SystemSubServiceTableListItem, SystemSubscriberTableListItem, SystemTableListItem, SystemUpstreamTableListItem } from "./type"; import { Input, InputNumber, MenuProps, Select, TabsProps, Tooltip } from "antd"; import { ColumnsType } from "antd/es/table"; @@ -6,21 +5,25 @@ import { getItem } from "@common/utils/navigation"; import { MatchItem, MemberItem } from "@common/const/type"; import { ConfigField } from "@common/components/aoplatform/EditableTableWithModal"; import { frontendTimeSorter } from "@common/utils/dataTransfer"; -import moment from "moment"; -import { STATUS_COLOR } from "@common/const/const"; +import { COLUMNS_TITLE, STATUS_COLOR, VALIDATE_MESSAGE } from "@common/const/const"; import { LoadingOutlined } from "@ant-design/icons"; import { SystemInsidePublishOnlineItems } from "../../pages/system/publish/SystemInsidePublishOnline"; +import dayjs from 'dayjs'; import { Link } from "react-router-dom"; +import { $t } from "@common/locales"; +import { PageProColumns } from "@common/components/aoplatform/PageList"; export enum SubscribeEnum{ - '驳回' = 0, - '审核中' = 1, - '已订阅' = 2, - '取消订阅' = 3, - '取消申请' = 4 + Rejected = 0, + Reviewing = 1, + Subscribed = 2, + Unsubscribed = 3, + CancelRequest = 4 } + + export const SubscribeStatusColor= { 2: 'text-[#138913]', // 使用 Tailwind 的 Arbitrary Properties 1: 'text-[#03a9f4]', @@ -30,29 +33,40 @@ export const SubscribeStatusColor= { }; export enum SubscribeFromEnum { - '手动添加' = 0, - '订阅申请' = 1 + manual = 0, + subscribe= 1 } -export enum MatchPositionEnum { - 'header' = 'HTTP 请求头', - 'query' = '请求参数', - 'cookie' = 'Cookie' +export const MatchPositionEnum = { + 'header' : $t('HTTP 请求头'), + 'query': $t('请求参数'), + 'cookie' : $t('Cookie') } -export enum MatchTypeEnum{ - 'EQUAL' = '全等匹配', - 'PREFIX' = '前缀匹配', - 'SUFFIX' = '后缀匹配', - 'SUBSTR' = '子串匹配', - 'UNEQUAL' = '非等匹配', - 'NULL' = '空值匹配', - 'EXIST' = '存在匹配', - 'UNEXIST'='不存在匹配', - 'REGEXP'='区分大小写的正则匹配', - 'REGEXPG'='不区分大小写的正则匹配', - 'unknown'='任意匹配' +export const MatchTypeEnum = { + 'EQUAL' : $t('全等匹配'), + 'PREFIX' : $t('前缀匹配'), + 'SUFFIX' :$t('后缀匹配'), + 'SUBSTR' : $t('子串匹配'), + 'UNEQUAL' : $t('非等匹配'), + 'NULL' : $t('空值匹配'), + 'EXIST' : $t('存在匹配'), + 'UNEXIST':$t('不存在匹配'), + 'REGEXP':$t('区分大小写的正则匹配'), + 'REGEXPG':$t('不区分大小写的正则匹配'), + 'unknown': $t('任意匹配') +} + + +export const SYSTEM_I18NEXT_FOR_ENUM = { + [SubscribeEnum.Rejected]:$t('驳回'), + [SubscribeEnum.Reviewing]:$t('审核中'), + [SubscribeEnum.Subscribed]:$t('已订阅'), + [SubscribeEnum.Unsubscribed]:$t('取消订阅'), + [SubscribeEnum.CancelRequest]:$t('取消申请'), + [SubscribeFromEnum.manual]:$t('手动添加'), + [SubscribeFromEnum.subscribe]:$t('订阅申请'), } export const HTTP_METHOD = ['GET','POST','PUT','DELETE','PATCH','HEAD'] @@ -70,9 +84,9 @@ export const ALGORITHM_ITEM = [ {label:'ES512',value:'ES512'}, ] -export const SYSTEM_TABLE_COLUMNS: ProColumns[] = [ +export const SYSTEM_TABLE_COLUMNS: PageProColumns[] = [ { - title: '服务名称', + title:$t('服务名称'), dataIndex: 'name', ellipsis:true, width:160, @@ -82,13 +96,13 @@ export const SYSTEM_TABLE_COLUMNS: ProColumns[] = [ }, }, { - title: '服务 ID', + title:$t('服务 ID'), dataIndex: 'id', width: 140, ellipsis:true, }, { - title: '所属团队', + title:$t('所属团队'), dataIndex: ['team','name'], ellipsis:true, // filters: true, @@ -96,7 +110,7 @@ export const SYSTEM_TABLE_COLUMNS: ProColumns[] = [ // filterSearch: true, }, { - title: 'API 数量', + title:$t('API 数量'), dataIndex: 'apiNum', ellipsis:true, sorter: (a,b)=> { @@ -104,12 +118,12 @@ export const SYSTEM_TABLE_COLUMNS: ProColumns[] = [ }, }, { - title: '描述', + title: $t('描述'), dataIndex: 'description', ellipsis:true, }, { - title: '负责人', + title:$t('负责人'), dataIndex: ['master','name'], ellipsis: true, width:108, @@ -119,7 +133,7 @@ export const SYSTEM_TABLE_COLUMNS: ProColumns[] = [ filterSearch: true, }, { - title: '创建时间', + title:$t('创建时间'), dataIndex: 'createTime', width:182, ellipsis:true, @@ -127,9 +141,9 @@ export const SYSTEM_TABLE_COLUMNS: ProColumns[] = [ } ]; -export const SYSTEM_SUBSERVICE_TABLE_COLUMNS: ProColumns[] = [ +export const SYSTEM_SUBSERVICE_TABLE_COLUMNS: PageProColumns[] = [ { - title: '服务名称', + title:$t('服务名称'), dataIndex: ['service','name'], ellipsis:true, width:160, @@ -139,13 +153,13 @@ export const SYSTEM_SUBSERVICE_TABLE_COLUMNS: ProColumns驳回], - [1,审核中], - [2,已订阅], - [3,取消订阅], - [4,取消申请], + [0,{$t('驳回')}], + [1,{$t('审核中')}], + [2,{$t('已订阅')}], + [3,{$t('取消订阅')}], + [4,{$t('取消申请')}], ]) }, { - title: '所属服务', + title:$t('所属服务'), dataIndex: ['project','name'], ellipsis:true }, { - title: '所属团队', + title:$t('所属团队'), dataIndex: ['team','name'], ellipsis:true }, { - title: '申请人', + title:$t('申请人'), dataIndex: ['applier','name'], ellipsis: true, width:88, @@ -183,19 +197,19 @@ export const SYSTEM_SUBSERVICE_TABLE_COLUMNS: ProColumns手动添加], - [1,订阅申请], + [0,{$t('手动添加')}], + [1,{$t('订阅申请')}], ]) }, { - title: '添加时间', + title:$t('添加时间'), dataIndex: 'createTime', ellipsis:true, width:182, @@ -206,9 +220,9 @@ export const SYSTEM_SUBSERVICE_TABLE_COLUMNS: ProColumns[] = [ +export const SYSTEM_SUBSCRIBER_TABLE_COLUMNS: PageProColumns[] = [ { - title: '服务名称', + title:$t('服务名称'), dataIndex: ['service','name'], ellipsis:true, width:160, @@ -218,55 +232,35 @@ export const SYSTEM_SUBSCRIBER_TABLE_COLUMNS: ProColumns手动添加], - [1,订阅申请], + [0,{$t('手动添加')}], + [1,{$t('订阅申请')}], ]) }, { - title: '订阅时间', + title:$t('订阅时间'), dataIndex: 'applyTime', ellipsis:true, width:182, @@ -278,7 +272,7 @@ export const SYSTEM_SUBSCRIBER_TABLE_COLUMNS: ProColumns = [ - {title:'成员', + {title:$t('成员'), render:(_,entity)=>{ return <>
@@ -292,9 +286,9 @@ export const memberModalColumn:ColumnsType = [ }} ] -export const SYSTEM_MEMBER_TABLE_COLUMN: ProColumns[] = [ +export const SYSTEM_MEMBER_TABLE_COLUMN: PageProColumns[] = [ { - title: '用户名', + title:$t('用户名'), dataIndex: ['user','name'], ellipsis:true, width:160, @@ -304,12 +298,12 @@ export const SYSTEM_MEMBER_TABLE_COLUMN: ProColumns[] }, }, { - title: '邮箱', + title:$t('邮箱'), dataIndex: 'email', ellipsis:true }, { - title: '角色', + title:$t('角色'), dataIndex: ['roles','name'], ellipsis:true @@ -318,7 +312,7 @@ export const SYSTEM_MEMBER_TABLE_COLUMN: ProColumns[] export const MATCH_CONFIG:ConfigField[] = [ { - title: '参数位置', + title:$t('参数位置'), key: 'position', component: , renderText: (value: unknown) => <>{value}, required: true }, { - title: '匹配类型', + title:$t('匹配类型'), key: 'matchType', component: , renderText: (value: string) => { @@ -356,9 +350,9 @@ export const MATCH_CONFIG:ConfigField[] = [ ] -export const SYSTEM_API_TABLE_COLUMNS: ProColumns[] = [ +export const SYSTEM_API_TABLE_COLUMNS: PageProColumns[] = [ { - title: '名称', + title:$t('名称'), dataIndex: 'name', ellipsis:true, width:160, @@ -369,7 +363,7 @@ export const SYSTEM_API_TABLE_COLUMNS: ProColumns[] = [ }, }, { - title: '协议/方法', + title:$t('协议/方法'), dataIndex: 'method', ellipsis:true, filters: true, @@ -384,12 +378,12 @@ export const SYSTEM_API_TABLE_COLUMNS: ProColumns[] = [ }, }, { - title: 'URL', + title:$t('URL'), dataIndex: 'requestPath', ellipsis:true }, { - title: '创建者', + title:$t('创建者'), dataIndex: ['creator','name'], ellipsis: true, filters: true, @@ -398,7 +392,7 @@ export const SYSTEM_API_TABLE_COLUMNS: ProColumns[] = [ filterSearch: true, }, { - title: '更新时间', + title:$t('更新时间'), dataIndex: 'updateTime', ellipsis:true, hideInSearch: true, @@ -409,9 +403,9 @@ export const SYSTEM_API_TABLE_COLUMNS: ProColumns[] = [ -export const SYSTEM_UPSTREAM_TABLE_COLUMNS: ProColumns[] = [ +export const SYSTEM_UPSTREAM_TABLE_COLUMNS: PageProColumns[] = [ { - title: '名称', + title:$t('名称'), dataIndex: 'name', ellipsis:true, width:160, @@ -421,13 +415,13 @@ export const SYSTEM_UPSTREAM_TABLE_COLUMNS: ProColumns[] = [ { - title: '操作类型', + title:$t('操作类型'), key: 'optType', component: , renderText: (value: string) => { @@ -514,7 +508,7 @@ export const PROXY_HEADER_CONFIG:ConfigField[] = [ }, required: true }, { - title: '参数值', + title:$t('参数值'), key: 'value', component: , renderText: (value: string) => { @@ -526,12 +520,12 @@ export const PROXY_HEADER_CONFIG:ConfigField[] = [ export const NODE_CONFIG:ConfigField[] = [ { - title: '集群', + title:$t('集群'), key: 'cluster', component: , renderText: (value: string) => { @@ -539,7 +533,7 @@ export const NODE_CONFIG:ConfigField[] = [ }, required: true }, { - title: '权重', + title:$t('权重'), key: 'weight', component: , renderText: (value: string) => { @@ -550,37 +544,37 @@ export const NODE_CONFIG:ConfigField[] = [ ] export const visualizations = [ - {label:'内部服务:可通过网关访问,但不展示在服务广场',value:'inner'}, - {label:'公开服务:可通过网关访问,展示在服务广场,可被其他应用订阅',value:'public'}]; + {label:$t('内部服务:可通过网关访问,但不展示在服务广场'),value:'inner'}, + {label:$t('公开服务:可通过网关访问,展示在服务广场,可被其他应用订阅'),value:'public'}]; -export const SYSTEM_MYSERVICE_API_TABLE_COLUMNS: ProColumns[] = [ +export const SYSTEM_MYSERVICE_API_TABLE_COLUMNS: PageProColumns[] = [ { - title: ' ', + title:$t(' '), dataIndex: 'id', width:'40px', fixed:'left' }, { - title: '名称', + title:$t('名称'), dataIndex: 'name', width:160, fixed:'left', ellipsis:true }, { - title: '请求方式', + title:$t('请求方式'), dataIndex: 'method', ellipsis:true }, { - title: '请求路径', + title:$t('请求路径'), dataIndex: 'path', ellipsis:true }, { - title: '描述', + title: $t('描述'), dataIndex: 'description', ellipsis:true } @@ -589,7 +583,7 @@ export const SYSTEM_MYSERVICE_API_TABLE_COLUMNS: ProColumns = [ { - title:'所有 API', + title:$t('所有 API'), dataIndex:'method', }, { @@ -600,9 +594,9 @@ export const apiModalColumn:ColumnsType = [ ] -export const SYSTEM_AUTHORITY_TABLE_COLUMNS: ProColumns[] = [ +export const SYSTEM_AUTHORITY_TABLE_COLUMNS: PageProColumns[] = [ { - title: '名称', + title:$t('名称'), dataIndex: 'name', ellipsis:true, width:160, @@ -612,7 +606,7 @@ export const SYSTEM_AUTHORITY_TABLE_COLUMNS: ProColumns ( - 0 ? 'text-status_fail' : ''}>{entity.expireTime === 0 ? '永不过期' :moment(entity.expireTime * 1000).format('YYYY-MM-DD hh:mm:ss')} + 0 ? 'text-status_fail' : ''}>{entity.expireTime === 0 ? '永不过期' :dayjs(entity.expireTime * 1000).format('YYYY-MM-DD hh:mm:ss')} ), sorter: (a,b)=> { return a.expireTime - b.expireTime }, }, { - title: '更新者', + title:$t('更新者'), dataIndex: ['updater','name'], ellipsis: true, width:88, @@ -664,7 +658,7 @@ export const SYSTEM_AUTHORITY_TABLE_COLUMNS: ProColumns[] = [ +export const SYSTEM_MYSERVICE_TABLE_COLUMNS: PageProColumns[] = [ { - title: '服务名称', + title:$t('服务名称'), dataIndex: 'name', ellipsis:true, width:160, @@ -688,13 +682,13 @@ export const SYSTEM_MYSERVICE_TABLE_COLUMNS: ProColumns[ }, }, { - title: '服务ID', + title:$t('服务ID'), dataIndex: 'id', width: 140, ellipsis:true }, { - title: '服务类型', + title:$t('服务类型'), dataIndex: 'serviceType', ellipsis:{ showTitle:true @@ -704,22 +698,22 @@ export const SYSTEM_MYSERVICE_TABLE_COLUMNS: ProColumns[ valueType: 'select', valueEnum:{ 'public':{ - text:'公开服务' + text:$t('公开服务') }, 'inner':{ - text:'内部服务' + text:$t('内部服务') } } }, { - title: 'API 数量', + title:$t('API 数量'), dataIndex: 'apiNum', sorter: (a,b)=> { return a.apiNum - b.apiNum }, }, { - title: '状态', + title:$t('状态'), dataIndex: 'status', ellipsis:{ showTitle:true @@ -728,12 +722,12 @@ export const SYSTEM_MYSERVICE_TABLE_COLUMNS: ProColumns[ onFilter: true, valueType: 'select', valueEnum:{ - 'on':启用 , - 'off':停用 + 'on':{$t('启用')} , + 'off':{$t('停用')} } }, { - title: '更新时间', + title:$t('更新时间'), key: 'updateTime', dataIndex: 'updateTime', ellipsis:true, @@ -743,7 +737,7 @@ export const SYSTEM_MYSERVICE_TABLE_COLUMNS: ProColumns[ }, }, { - title: '创建时间', + title:$t('创建时间'), key: 'createTime', dataIndex: 'createTime', width:182, @@ -756,9 +750,9 @@ export const SYSTEM_MYSERVICE_TABLE_COLUMNS: ProColumns[ -export const SYSTEM_UPSTREAM_GLOBAL_CONFIG_TABLE_COLUMNS: ProColumns[] = [ +export const SYSTEM_UPSTREAM_GLOBAL_CONFIG_TABLE_COLUMNS: PageProColumns[] = [ { - title: '地址(IP 端口或域名)', + title:$t('地址(IP 端口或域名)'), dataIndex: 'address', width: '50%', formItemProps: { @@ -768,23 +762,23 @@ export const SYSTEM_UPSTREAM_GLOBAL_CONFIG_TABLE_COLUMNS: ProColumnsnull }, ]; @@ -793,11 +787,11 @@ export const SYSTEM_UPSTREAM_GLOBAL_CONFIG_TABLE_COLUMNS: ProColumns{} + title:$t('申请状态'),key:'status',renderText:()=>{} }, { - title:'申请人',key:'applier',nested:'name' + title:$t('申请人'),key:'applier',nested:'name' }, - // { - // title:'审批人',key:'team',nested:'name' - // }, { - title:'申请时间',key:'applyTime' + title:$t('申请时间'),key:'applyTime' }, - // { - // title:'审批时间',key:'team' - // } ] export const SYSTEM_TOPOLOGY_NODE_TYPE_COLOR_MAP = { subscriberProject:{ stroke:'#3291F8FF', fill: '#3291F8FF', - name:'调用系统名称' + name:$t('调用系统名称') }, subscriberService:{ stroke:'#3D46F2', fill: '#7371FC33', - name:'调用服务名称' + name:$t('调用服务名称') }, curProject:{ stroke:'#7371FCFF', fill: '#7371FCFF', - name:'当前系统名称' + name:$t('当前系统名称') }, invokeService:{ stroke:'#3D46F2', fill: '#7371FC33', - name:'被调用服务名称' + name:$t('被调用服务名称') }, invokeProject:{ stroke:'#19C56BFF', fill: '#19C56BFF', - name:'被调用系统名称' + name:$t('被调用系统名称') }, application:{ stroke:'#ffa940', @@ -881,7 +869,7 @@ export const SYSTEM_TOPOLOGY_NODE_TYPE_COLOR_MAP = { export const SYSTEM_PUBLISH_ONLINE_COLUMNS = [ { - title: '上线结果', + title:$t('上线结果'), dataIndex: 'status', ellipsis:{ showTitle:true @@ -889,9 +877,9 @@ export const SYSTEM_TOPOLOGY_NODE_TYPE_COLOR_MAP = { render:(_:unknown,entity:SystemInsidePublishOnlineItems)=>{ switch(entity.status){ case 'done': - return 成功 + return {$t('成功')} case 'error': - return 失败 {entity.error} + return {$t('失败')} {entity.error} default: return } @@ -903,23 +891,23 @@ const APP_MODE = import.meta.env.VITE_APP_MODE; export const SYSTEM_PAGE_MENU_ITEMS: MenuProps['items'] = [ - getItem('服务', 'assets', null, + getItem($t('服务'), 'assets', null, [ - getItem(API, 'api',undefined,undefined,undefined,'team.service.api.view'), - getItem(上游, 'upstream',undefined,undefined,undefined,'team.service.upstream.view'), - getItem(使用说明, 'document',undefined,undefined,undefined,''), - getItem(发布, 'publish',undefined,undefined,undefined,'team.service.release.view'), + getItem({$t('API')}, 'api',undefined,undefined,undefined,'team.service.api.view'), + getItem({$t('上游')}, 'upstream',undefined,undefined,undefined,'team.service.upstream.view'), + getItem({$t('使用说明')}, 'document',undefined,undefined,undefined,''), + getItem({$t('发布')}, 'publish',undefined,undefined,undefined,'team.service.release.view'), ], 'group'), - getItem('订阅管理', 'provideSer', null, + getItem($t('订阅管理'), 'provideSer', null, [ - getItem(订阅审批, 'approval',undefined,undefined,undefined,'team.service.subscription.view'), - getItem(订阅方管理, 'subscriber',undefined,undefined,undefined,'team.service.subscription.view'), + getItem({$t('订阅审批')}, 'approval',undefined,undefined,undefined,'team.service.subscription.view'), + getItem({$t('订阅方管理')}, 'subscriber',undefined,undefined,undefined,'team.service.subscription.view'), ], 'group'), - getItem('管理', 'mng', null, + getItem($t('管理'), 'mng', null, [ - APP_MODE === 'pro' ? getItem(调用拓扑图, 'topology',undefined,undefined,undefined,'project.mySystem.topology.view'):null, - getItem(设置, 'setting',undefined,undefined,undefined,'')], + APP_MODE === 'pro' ? getItem({$t('调用拓扑图')}, 'topology',undefined,undefined,undefined,'project.mySystem.topology.view'):null, + getItem({$t('设置')}, 'setting',undefined,undefined,undefined,'')], 'group'), ]; diff --git a/frontend/packages/core/src/const/system/type.ts b/frontend/packages/core/src/const/system/type.ts index 3ab4f8c6..4694c26a 100644 --- a/frontend/packages/core/src/const/system/type.ts +++ b/frontend/packages/core/src/const/system/type.ts @@ -32,7 +32,7 @@ export type SystemConfigFieldType = { export type SystemSubServiceTableListItem = { id:string; - applyStatus:SubscribeEnum; + applyStatus:typeof SubscribeEnum; project:EntityItem; team:EntityItem service:EntityItem @@ -46,7 +46,7 @@ export type SystemSubServiceTableListItem = { export type SystemSubscriberTableListItem = { id:string service:EntityItem - applyStatus:SubscribeEnum + applyStatus:typeof SubscribeEnum project:EntityItem team:EntityItem; applier:EntityItem diff --git a/frontend/packages/core/src/const/team/const.tsx b/frontend/packages/core/src/const/team/const.tsx index 76d2d8f9..97dba627 100644 --- a/frontend/packages/core/src/const/team/const.tsx +++ b/frontend/packages/core/src/const/team/const.tsx @@ -1,16 +1,17 @@ -import { ProColumns } from "@ant-design/pro-components"; import { TeamMemberTableListItem, TeamTableListItem } from "./type"; import { ColumnsType } from "antd/es/table"; import { MemberItem } from "@common/const/type"; -import { getItem, getTabItem } from "@common/utils/navigation"; +import { getItem } from "@common/utils/navigation"; import { SystemTableListItem } from "../system/type"; -import { MenuProps, TabsProps } from "antd/lib"; +import { MenuProps } from "antd/lib"; import { Link } from "react-router-dom"; +import { $t } from "@common/locales"; +import { PageProColumns } from "@common/components/aoplatform/PageList"; -export const TEAM_TABLE_COLUMNS: ProColumns[] = [ +export const TEAM_TABLE_COLUMNS: PageProColumns[] = [ { - title: '名称', + title:$t('名称'), dataIndex: 'name', ellipsis:true, width:160, @@ -20,18 +21,18 @@ export const TEAM_TABLE_COLUMNS: ProColumns[] = [ }, }, { - title: 'ID', + title:$t('ID'), dataIndex: 'id', width: 140, ellipsis:true }, { - title: '描述', + title: $t('描述'), dataIndex: 'description', ellipsis:true }, { - title: '服务数量', + title:$t('服务数量'), dataIndex: 'serviceNum', ellipsis:true, sorter: (a,b)=> { @@ -39,7 +40,7 @@ export const TEAM_TABLE_COLUMNS: ProColumns[] = [ }, }, { - title: '负责人', + title:$t('负责人'), dataIndex: ['master','name'], ellipsis: true, width:108, @@ -49,7 +50,7 @@ export const TEAM_TABLE_COLUMNS: ProColumns[] = [ filterSearch: true, }, { - title: '创建时间', + title:$t('创建时间'), dataIndex: 'createTime', ellipsis:true, width:182, @@ -60,9 +61,9 @@ export const TEAM_TABLE_COLUMNS: ProColumns[] = [ ]; -export const TEAM_SYSTEM_TABLE_COLUMNS: ProColumns[] = [ +export const TEAM_SYSTEM_TABLE_COLUMNS: PageProColumns[] = [ { - title: '服务名称', + title:$t('服务名称'), dataIndex: 'name', ellipsis:true, width:160, @@ -72,18 +73,18 @@ export const TEAM_SYSTEM_TABLE_COLUMNS: ProColumns[] = [ }, }, { - title: '服务 ID', + title:$t('服务 ID'), dataIndex: 'id', width: 140, ellipsis:true }, { - title: '所属团队', + title:$t('所属团队'), dataIndex: ['team','name'], ellipsis:true }, { - title: 'API数量', + title:$t('API数量'), dataIndex: 'apiNum', ellipsis:true, sorter: (a,b)=> { @@ -91,7 +92,7 @@ export const TEAM_SYSTEM_TABLE_COLUMNS: ProColumns[] = [ }, }, { - title: '服务数量', + title:$t('服务数量'), dataIndex: 'serviceNum', ellipsis:true, sorter: (a,b)=> { @@ -99,7 +100,7 @@ export const TEAM_SYSTEM_TABLE_COLUMNS: ProColumns[] = [ }, }, { - title: '负责人', + title:$t('负责人'), dataIndex: ['master','name'], ellipsis: true, width:108, @@ -109,7 +110,7 @@ export const TEAM_SYSTEM_TABLE_COLUMNS: ProColumns[] = [ filterSearch: true }, { - title: '添加日期', + title:$t('添加日期'), dataIndex: 'createTime', ellipsis: true, sorter: (a,b)=> { @@ -118,9 +119,9 @@ export const TEAM_SYSTEM_TABLE_COLUMNS: ProColumns[] = [ }, ]; -export const TEAM_MEMBER_TABLE_COLUMNS: ProColumns[] = [ +export const TEAM_MEMBER_TABLE_COLUMNS: PageProColumns[] = [ { - title: '姓名', + title:$t('姓名'), dataIndex: ['user','name'], ellipsis:true, width:160, @@ -130,12 +131,12 @@ export const TEAM_MEMBER_TABLE_COLUMNS: ProColumns[] = }, }, { - title: '团队角色', + title:$t('团队角色'), dataIndex: 'roles', ellipsis:true, }, { - title: '添加日期', + title:$t('添加日期'), dataIndex: 'attachTime', ellipsis:true, sorter: (a,b)=> { @@ -146,7 +147,7 @@ export const TEAM_MEMBER_TABLE_COLUMNS: ProColumns[] = export const TEAM_MEMBER_MODAL_TABLE_COLUMNS:ColumnsType = [ - {title:'成员', + {title:$t('成员'), render:(_,entity)=>{ return <>
@@ -161,10 +162,10 @@ export const TEAM_MEMBER_MODAL_TABLE_COLUMNS:ColumnsType = [ ] export const TEAM_INSIDE_MENU_ITEMS: MenuProps['items'] = [ - getItem('管理', 'grp', null, + getItem($t('管理'), 'grp', null, [ - getItem(成员, 'member',undefined, undefined, undefined,'team.team.member.view'), - getItem(设置, 'setting',undefined,undefined,undefined,'team.team.team.edit')], + getItem({$t('成员')}, 'member',undefined, undefined, undefined,'team.team.member.view'), + getItem({$t('设置')}, 'setting',undefined,undefined,undefined,'team.team.team.edit')], 'group'), ]; \ No newline at end of file diff --git a/frontend/packages/core/src/const/user/const.tsx b/frontend/packages/core/src/const/user/const.tsx index a4e87916..3b9b2ecb 100644 --- a/frontend/packages/core/src/const/user/const.tsx +++ b/frontend/packages/core/src/const/user/const.tsx @@ -1,12 +1,13 @@ -import { ProColumns } from "@ant-design/pro-components"; import { ColumnsType } from "antd/es/table"; import { MemberItem } from "@common/const/type"; import { Tooltip } from "antd"; +import { $t } from "@common/locales"; +import { PageProColumns } from "@common/components/aoplatform/PageList"; -export const USER_LIST_COLUMNS: ProColumns[]= [ +export const USER_LIST_COLUMNS: PageProColumns[]= [ { - title: '用户名', + title:$t('用户名'), dataIndex: 'name', ellipsis:true, width:160, @@ -16,12 +17,12 @@ export const USER_LIST_COLUMNS: ProColumns[]= [ }, }, { - title: '邮箱', + title:$t('邮箱'), dataIndex: 'email', ellipsis:true, }, { - title: '部门', + title:$t('部门'), dataIndex: 'department', ellipsis:{ showTitle:true @@ -36,7 +37,7 @@ export const USER_LIST_COLUMNS: ProColumns[]= [ ]; export const MEMBER_MODAL_COLUMNS:ColumnsType = [ - {title:'所有成员', + {title:$t('所有成员'), width:215, render:(_,entity)=>{ diff --git a/frontend/packages/core/src/index.css b/frontend/packages/core/src/index.css index 8707926c..34a334d0 100644 --- a/frontend/packages/core/src/index.css +++ b/frontend/packages/core/src/index.css @@ -353,17 +353,20 @@ p{ color:var(--primary-color) !important; } - button.ant-btn.ant-btn-text{ + button.ant-btn.ant-btn-text.ant-btn-icon-only{ height:22px !important; + width:18px !important; } - button.ant-btn:not(:disabled):not(.text-table_text){ + + + /* button.ant-btn:not(:disabled):not(.text-table_text){ color:var(--primary-color); } button.ant-btn:not(:disabled):not(.text-table_text):hover{ color:var(--button-primary-hover-background-color) !important; - } + } */ } .ant-popover .ant-popover-inner{ @@ -1224,4 +1227,4 @@ div.preview-document{ } .ant-table-wrapper .ant-table-thead th.ant-table-column-has-sorters{ transition:none !important; -} \ No newline at end of file +} diff --git a/frontend/packages/core/src/pages/Login.tsx b/frontend/packages/core/src/pages/Login.tsx index 1f973686..e37b3c8c 100644 --- a/frontend/packages/core/src/pages/Login.tsx +++ b/frontend/packages/core/src/pages/Login.tsx @@ -2,10 +2,11 @@ import {FC, useCallback, useEffect, useRef, useState} from "react"; import {App, Button, Form, FormInstance, Input} from "antd"; import {useGlobalContext} from "@common/contexts/GlobalStateContext.tsx"; import {useFetch} from "@common/hooks/http.ts"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; import {useNavigate} from "react-router-dom"; // import {useCrypto} from "../hooks/crypto.ts"; import Logo from '@common/assets/logo.png' +import { $t } from "@common/locales"; const Login:FC = ()=> { const {state, dispatch} = useGlobalContext() @@ -61,7 +62,7 @@ const Login:FC = ()=> { if (code === STATUS_CODE.SUCCESS) { dispatch({type:'LOGIN'}) - message.success('登录成功'); + message.success(RESPONSE_TIPS.loginSuccess); const callbackUrl = new URLSearchParams(window.location.search).get('callbackUrl'); if (callbackUrl && callbackUrl !== 'null') { navigate(callbackUrl); @@ -102,7 +103,7 @@ const Login:FC = ()=> {
- 登录 + {$t('登录')}
{ @@ -123,11 +124,11 @@ const Login:FC = ()=> { @@ -137,7 +138,7 @@ const Login:FC = ()=> { className="p-0 bg-transparent rounded border-none mb-0" >
@@ -147,8 +148,8 @@ const Login:FC = ()=> {
-

Version {state.version}-{state.updateDate}

-

{state.powered}

+

{$t('Version (0)-(1)',[state.version,state.updateDate])}

+

{$t(state.powered)}

diff --git a/frontend/packages/core/src/pages/approval/ApprovalList.tsx b/frontend/packages/core/src/pages/approval/ApprovalList.tsx index 73cebe2c..d9332e9e 100644 --- a/frontend/packages/core/src/pages/approval/ApprovalList.tsx +++ b/frontend/packages/core/src/pages/approval/ApprovalList.tsx @@ -1,7 +1,7 @@ -import {ActionType, ProColumns} from "@ant-design/pro-components"; +import {ActionType} from "@ant-design/pro-components"; import {App, Button} from "antd"; import {useEffect, useMemo, useRef, useState} from "react"; -import PageList from "@common/components/aoplatform/PageList.tsx"; +import PageList, { PageProColumns } from "@common/components/aoplatform/PageList.tsx"; import { PUBLISH_APPROVAL_TABLE_COLUMN, SUBSCRIBE_APPROVAL_TABLE_COLUMN, @@ -10,9 +10,10 @@ import { import { ApprovalTableListItem, PublishApprovalInfoType, + PublishApprovalModalHandle, SubscribeApprovalInfoType, } from "@common/const/approval/type.tsx"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, COLUMNS_TITLE, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; import {useFetch} from "@common/hooks/http.ts"; import { SubscribeApprovalModalContent, @@ -20,11 +21,12 @@ import { } from "@common/components/aoplatform/SubscribeApprovalModalContent.tsx"; import { PublishApprovalModalContent, - PublishApprovalModalHandle + } from "@common/components/aoplatform/PublishApprovalModalContent.tsx"; import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; import { SimpleMemberItem } from "@common/const/type.ts"; import TableBtnWithPermission from "@common/components/aoplatform/TableBtnWithPermission.tsx"; +import { $t } from "@common/locales"; export default function ApprovalList({pageType,pageStatus}:{pageType:'subscribe'|'release',pageStatus:0|1}){ const { modal,message } = App.useApp() @@ -52,11 +54,11 @@ export default function ApprovalList({pageType,pageStatus}:{pageType:'subscribe' const {code,data,msg} = response if(code === STATUS_CODE.SUCCESS){ setTableListDataSource(data.approvals) - !init && message.success(msg || '操作成功') + !init && message.success(msg || RESPONSE_TIPS.success) setInit((prev)=>prev ? false : prev) return {data:data.approvals, success: true} }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return {data:[], success:false} } }).catch(() => { @@ -73,12 +75,12 @@ export default function ApprovalList({pageType,pageStatus}:{pageType:'subscribe' }, [pageType,pageStatus]); const openModal = async(type:'approval'|'view',entity:ApprovalTableListItem)=>{ - message.loading('正在加载数据') + message.loading(RESPONSE_TIPS.loading) const {code,data,msg} = await fetchData>(`approval/${pageType}`,{method:'GET',eoParams:{id:entity!.id},eoTransformKeys:['apply_project','apply_team','apply_time','approval_time']}) message.destroy() if(code === STATUS_CODE.SUCCESS){ const modalInst = modal.confirm({ - title:type === 'approval' ? '审批' : '查看', + title:type === 'approval' ? $t('审批') : $t('查看'), content:pageType === 'subscribe' ? :, @@ -90,8 +92,8 @@ export default function ApprovalList({pageType,pageStatus}:{pageType:'subscribe' } }, width:600, - okText:type === 'approval' ? '通过' :'确认', - cancelText:'取消', + okText:type === 'approval' ? $t('通过') :$t('确认'), + cancelText:$t('取消'), closable:true, onCancel:()=>{setApprovalBtnLoading(false)}, icon:<>, @@ -112,7 +114,7 @@ export default function ApprovalList({pageType,pageStatus}:{pageType:'subscribe' }, }) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return } } @@ -128,21 +130,21 @@ export default function ApprovalList({pageType,pageStatus}:{pageType:'subscribe' }) setMemberValueEnum(tmpValueEnum) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } } - const operation:ProColumns[] =[ + const operation:PageProColumns[] =[ { - title: '操作', + title: COLUMNS_TITLE.operate, key: 'option', - width: 62, + btnNums:1, fixed:'right', valueType: 'option', render: (_: React.ReactNode, entity: ApprovalTableListItem) => [ pageStatus === 0 ? - {openModal('approval',entity)}} btnTitle="审批"/> - :{openModal('view',entity)}} btnTitle="查看"/>, + {openModal('approval',entity)}} btnTitle="审批"/> + :{openModal('view',entity)}} btnTitle="查看"/>, ] } ] diff --git a/frontend/packages/core/src/pages/approval/ApprovalPage.tsx b/frontend/packages/core/src/pages/approval/ApprovalPage.tsx index 0e619bd2..fa7324d2 100644 --- a/frontend/packages/core/src/pages/approval/ApprovalPage.tsx +++ b/frontend/packages/core/src/pages/approval/ApprovalPage.tsx @@ -4,24 +4,25 @@ import {Link, useLocation, useNavigate} from "react-router-dom"; import {useEffect, useState} from "react"; import ApprovalList from "./ApprovalList.tsx"; import { getItem } from "@common/utils/navigation.tsx"; +import { $t } from "@common/locales/index.ts"; const menuItems: MenuProps['items'] = [ - getItem('管理', 'mng', null, + getItem($t('管理'), 'mng', null, [ - getItem(订阅申请, 'subscribe'), - getItem(发布申请, 'release')], + getItem({$t('订阅申请')}, 'subscribe'), + getItem({$t('发布申请')}, 'release')], 'group'), ]; const items: TabsProps['items'] = [ { key: '0', - label: '待审批', + label: $t('待审批'), }, { key: '1', - label: '已审批', + label: $t('已审批'), } ]; diff --git a/frontend/packages/core/src/pages/auditLog/AuditLog.module.css b/frontend/packages/core/src/pages/auditLog/AuditLog.module.css deleted file mode 100644 index f5f7edf5..00000000 --- a/frontend/packages/core/src/pages/auditLog/AuditLog.module.css +++ /dev/null @@ -1,8 +0,0 @@ -.audit-log-table{ - :global .ant-pro-table-search { - margin-block-end: 0px; - } - :global .ant-pro-query-filter.ant-pro-query-filter { - padding: 10px; - } -} \ No newline at end of file diff --git a/frontend/packages/core/src/pages/auditLog/AuditLog.tsx b/frontend/packages/core/src/pages/auditLog/AuditLog.tsx deleted file mode 100644 index 4d950a01..00000000 --- a/frontend/packages/core/src/pages/auditLog/AuditLog.tsx +++ /dev/null @@ -1,308 +0,0 @@ -import {ProColumns, ProProvider, ProTable} from "@ant-design/pro-components"; -import {FC, useContext, useEffect, useRef, useState} from "react"; -import {App, Button, Select, Space} from "antd"; -import {debounce} from "lodash-es"; -import styles from './AuditLog.module.css' -import {useBreadcrumb} from "@common/contexts/BreadcrumbContext.tsx"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; -import {useFetch} from "@common/hooks/http.ts"; -import {SortOrder} from "antd/es/table/interface"; -import {DefaultOptionType} from "antd/es/cascader"; -import moment from "moment"; -import { SimpleMemberItem } from "@common/const/type.ts"; - -type AuditLogTableListItem = { - operator:string; - operateType:string; - description:string; - ip:string; - operateTime:string -}; - -const searchTypeList = [{label:'包含',value:1},{label:'不包含',value:0}]; - -const AUDIT_LOG_COLUMNS_CONFIG: ProColumns[] = [ - { - title: '操作时间', - dataIndex: 'operateTime', - valueType: 'dateTimeRange', - order:1, - ellipsis:true, - fixed:'left', - width:182 - }, - { - title: '操作人', - dataIndex: ['operator','name'], - key: 'operator', - order:3, - valueType: 'multipleSelect' - }, - { - title: '操作类型', - dataIndex: 'operateType', - key: 'operateType', - order:2, - valueType: 'multipleSelect', - }, - { - title: '具体描述', - dataIndex: 'description', - key: 'description', - search:false - }, - { - title: 'IP', - dataIndex: 'ip', - key: 'ip', - search:false - } -]; - - - -const MultipleSelect: FC<{ - state: { - type: number; - fieldName:string; - options:DefaultOptionType[] - }; - /** Value 和 onChange 会被自动注入 */ - value?: string; - onChange?: (value: {[k:string]:unknown},) => void; -}> = (props) => { - const { state,value,onChange } = props; - - const [innerOptions, setOptions] = useState(state.options); - - const [searchType,setSearchType]=useState<1|0>(1) - const [searchValue,setSearchValue]=useState(null) - useEffect(() => { - setOptions(state.options); - }, [state.options]); - - const handleSearchTypeChange = (e:1|0)=>{setSearchType(e);onChange?.({include:searchType, value:searchValue})} - const handleSearchValueChange = (e:string|number|null)=>{ - //console.log(e) - setSearchValue(e); - onChange?.({include:searchType, value:e})} - - return ( - - - - ); -}; - - -export default function AuditLog(){ - const { message } = App.useApp() - const values = useContext(ProProvider); - const parentRef = useRef(null); - const [tableHeight, setTableHeight] = useState(window.innerHeight); - const { setBreadcrumb } = useBreadcrumb() - const [tableListDataSource, setTableListDataSource] = useState([]); - const {fetchData} = useFetch() - const [columns, setColumns] = useState[]>(AUDIT_LOG_COLUMNS_CONFIG) - const [operatorTypeList, setOperatorTypeList] = useState([]) - const [operatorList, setOperatorList] = useState([]) - - const getOperatorTypeList = async ()=>{ - setOperatorTypeList([]) - const {code,data,msg} = await fetchData}>>('audit/operate_types',{method:'GET',eoTransformKeys:['operate_types']}) - if(code === STATUS_CODE.SUCCESS){ - setOperatorTypeList(data.operateTypes?.map((x:{id:string,name:string})=>({label:x.name, value:x.id}))) - }else{ - message.error(msg || '操作失败') - } - } - - const getMemberList = async ()=>{ - setOperatorList([]) - const {code,data,msg} = await fetchData>('simple/member',{method:'GET'}) - if(code === STATUS_CODE.SUCCESS){ - setOperatorList(data.members?.map((x:SimpleMemberItem)=>{return { - label:x.name, value:x.id - }})) - }else{ - message.error(msg || '操作失败') - } - } - - const handleOperatorList = ()=>{ - setColumns((prevData)=> - prevData?.map((x)=>{ - if(x.dataIndex === 'operator'){ - x.renderFormItem = (item, { type, defaultRender, ...rest }, form) => { - const stateType = form.getFieldValue('operator'); - return ( - - ); - } - } - return x - })) - } - - const handleOperatorTypeList = async ()=>{ - setColumns((prevData)=> - prevData?.map((x)=>{ - if(x.dataIndex === 'operateType'){ - x.renderFormItem= (item, { type, defaultRender, ...rest }, form) => { - const stateType = form.getFieldValue('operator'); - return ( - - ); - } - } - return x - })) - } - - useEffect(() => { - setBreadcrumb([ - { - title:'审计日志' - }, - ]) - const handleResize = () => { - if (parentRef.current) { - const res = parentRef.current.getBoundingClientRect(); - const height = res.height - 52 - 40;// 减去顶部按钮、底部分页、表头高度 - //console.log(height, res?.height); - height && setTableHeight(height); - } - }; - const debouncedHandleResize = debounce(handleResize, 200); - const resizeObserver = new ResizeObserver(debouncedHandleResize); - if (parentRef.current) { - resizeObserver.observe(parentRef.current); - } - getOperatorTypeList().then(()=>{ - handleOperatorTypeList() - }) - getMemberList().then(()=>{ - handleOperatorList() - }) - return () => { - resizeObserver.disconnect(); - }; - }, []); - - const getAuditLogList =(params:unknown, sorter?:Record,filter?:Record): Promise<{ data: AuditLogTableListItem[], success: boolean }>=> { - const eoParams = { - ...(params.operateTime?.length > 0 ? { - startTime:moment(params.operateTime[0],'YYYY-MM-DD HH:mm:ss').valueOf() / 1000, - endTime:moment(params.operateTime[0],'YYYY-MM-DD HH:mm:ss').valueOf() / 1000 - }:{}), - ...(params.operator?.value?.length > 0 ? { - operator:JSON.stringify(params.operator.include ? params.operator.value :operatorList.filter(item=>!params.operator.value.includes(item.value))?.map(x=>x.value)) - }:{}), - ...(params.operateType?.value?.length > 0 ? { - operateType:JSON.stringify(params.operateType.include ? params.operateType.value :operatorTypeList.filter(item=>!params.operatorTypeList.value.includes(item.value))?.map(x=>x.value)) - }:{}), - } - return fetchData>('audit/logs',{method:'GET',eoParams,eoTransformKeys:['startTime','endTime','operateType','operate_type','operate_time']}).then(response=>{ - const {code,data,msg} = response - //console.log(code,data.items) - if(code === STATUS_CODE.SUCCESS){ - setTableListDataSource(data.items) - return {data:data.items, success: true} - }else{ - message.error(msg || '操作失败') - return {data:[], success:false} - } - }).catch(() => { - return {data:[], success:false} - }) - } - const getOutputLog = (params:unknown)=>{ - const eoParams = { - ...(params.operateTime?.length > 0 ? { - startTime:moment(params.operateTime[0]).valueOf() / 1000, - endTime:moment(params.operateTime[0]).valueOf() / 1000 - }:{}), - ...(params.operator?.value?.length > 0 ? { - operator:JSON.stringify(params.operator.include ? params.operator.value :operatorList.filter(item=>!params.operator.value.includes(item.value))?.map(x=>x.value)) - }:{}), - ...(params.operateType?.value?.length > 0 ? { - operateType:JSON.stringify(params.operateType.include ? params.operateType.value :operatorTypeList.filter(item=>!params.operatorTypeList.value.includes(item.value))?.map(x=>x.value)) - }:{}), - } - fetchData>('audit/logs/export',{method:'GET',eoParams,eoTransformKeys:['startTime','endTime','operateType','operate_type','operate_time']}).then(response=>{ - - if (!response.ok) { - throw new Error(`Network response was not ok: ${response.status}`); - } - // 从 response 中获取文件名 - const contentDisposition = response.headers.get('Content-Disposition'); - const filenameMatch = contentDisposition && contentDisposition.match(/filename="(.+?)"/); - const filename = filenameMatch ? filenameMatch[1] : '审计日志'; - const downloadLink = document.createElement('a'); - downloadLink.href = window.URL.createObjectURL(new Blob([response.blob()])); - downloadLink.setAttribute('download', filename); - document.body.appendChild(downloadLink); - downloadLink.click(); - document.body.removeChild(downloadLink); - }) - } - return ( - , 'multipleSelect'> - className={styles['audit-log-table']} - columns={columns} - request={(params, sort,filter) => getAuditLogList(params,sort,filter)} - rowKey="id" - options={{ - reload: false, - density: false, - setting: false, - }} - tableAlertRender={false} - size="middle" - scroll={{ y: tableHeight }} - search={{ - defaultCollapsed: false, - optionRender: (searchConfig, formProps, dom) => [ - ...dom.reverse(), - , - ], - }} - />) -} \ No newline at end of file diff --git a/frontend/packages/core/src/pages/email/Email.tsx b/frontend/packages/core/src/pages/email/Email.tsx deleted file mode 100644 index e0f017ba..00000000 --- a/frontend/packages/core/src/pages/email/Email.tsx +++ /dev/null @@ -1,136 +0,0 @@ -import {Alert, App, Button, Form, Input, InputNumber, Select} from "antd"; -import {useEffect, useState} from "react"; -import {useBreadcrumb} from "@common/contexts/BreadcrumbContext.tsx"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; -import {useFetch} from "@common/hooks/http.ts"; -import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; - -type EmailFieldType = { - uuid?: string; - smtpUrl?: string; - smtpPort?:number; - protocol?: string; - email?:string; - account?:string; - password?:string -}; - -const PROTOCOL_OPTIONS = [ - { label: '不设置任何协议', value: 'none' }, - { label: 'SSL协议', value: 'ssl' }, - { label: 'TLS协议', value: 'tls' } -] - -export default function Email(){ - const { message } = App.useApp() - const [form] = Form.useForm(); - const { setBreadcrumb } = useBreadcrumb() - const {fetchData} = useFetch() - const [uuid, setUuid] = useState('') - const [type,setType] = useState<'add'|'edit'>('add') - const save = () => { - form.validateFields().then(values => { - fetchData>('email',{method:type === 'add'? 'POST' : 'PUT',eoBody:({...values,...(type === 'add'? {}:{uuid})}), eoTransformKeys:['emailInfo','smtpUrl']}).then(response=>{ - const {code,msg} = response - if(code === STATUS_CODE.SUCCESS){ - type === 'add' && setType('edit') - message.success(msg || '操作成功!') - }else{ - message.error(msg || '操作失败') - } - }) - }) - }; - - const getEmailConfig = ()=>{ - fetchData>('email',{method:'GET',eoTransformKeys:['email_info','smtp_url']}).then(response=>{ - const {code,data,msg} = response - //console.log(data) - if(code === STATUS_CODE.SUCCESS && data.emailInfo){ - form.setFieldsValue({...data.emailInfo,protocol:data.emailInfo.protocol === '' ? 'none' : data.emailInfo.protocol}) - setType('edit') - setUuid(data.emailInfo.uuid) - }else{ - message.error(msg || '操作失败') - } - }) - } - - useEffect(() => { - setBreadcrumb([ - { - title:'邮箱设置' - }, - ]) - getEmailConfig() - }, []); - - return (<> - - - - - label="SMTP 地址" - name="smtpUrl" - rules={[{ required: true, message: '必填项',whitespace:true }]} - > - - - - - label="SMTP 端口" - name="smtpPort" - rules={[{ required: true, message: '必填项' }]} - > - - - - - label="通信协议" - name="protocol" - rules={[{ required: true, message: '必填项' }]} - > - - - - - label="账号" - name="account" - > - - - - - label="密码" - name="password" - > - - - - - - - - - ) -} \ No newline at end of file diff --git a/frontend/packages/core/src/pages/logRetrieval/LogRetrieval.module.css b/frontend/packages/core/src/pages/logRetrieval/LogRetrieval.module.css deleted file mode 100644 index 10a3b2ee..00000000 --- a/frontend/packages/core/src/pages/logRetrieval/LogRetrieval.module.css +++ /dev/null @@ -1,12 +0,0 @@ -.collapse-without-padding{ - :global .ant-collapse-header{ - background:#f7f8fa; - border-radius: 4px; - } - :global .ant-collapse-content-box{ - padding:0px !important; - } - :global .ant-list-footer{ - padding:4px 0; - } -} \ No newline at end of file diff --git a/frontend/packages/core/src/pages/logRetrieval/LogRetrieval.tsx b/frontend/packages/core/src/pages/logRetrieval/LogRetrieval.tsx deleted file mode 100644 index 38f4c901..00000000 --- a/frontend/packages/core/src/pages/logRetrieval/LogRetrieval.tsx +++ /dev/null @@ -1,303 +0,0 @@ - -import {App, Button, Cascader, Checkbox, Collapse, Empty, Modal, Select, Spin, Table} from "antd"; -import {useEffect, useState} from "react"; -import {ColumnsType} from "antd/es/table"; -import moment from 'moment' -import styles from './LogRetrieval.module.css' -import { saveAs } from 'file-saver' -import useWebSocket from "@common/hooks/webSocket.ts"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; -import {useFetch} from "@common/hooks/http.ts"; -import {useBreadcrumb} from "@common/contexts/BreadcrumbContext.tsx"; -import {EntityItem} from "@common/const/type.ts"; -import {DefaultOptionType} from "antd/es/cascader"; -import { SimplePartition } from "../../const/partitions/types.ts"; -import MonacoEditorWrapper ,{MonacoEditorRefType} from "@common/components/aoplatform/MonacoEditorWrapper.tsx" - - type FileItemType = { - file:string, - key:string, - mod:string, - size:string -} - type OutputItemType = { - files:FileItemType[], - name:string, - tail:string -} - -type OutputItemExtraInfo = { - cluster:string - node:string -} - - -export default function LogRetrieval(){ - - const {/* modal,*/message } = App.useApp() - // const [confirmLoading, setConfirmLoading] = useState(false); - const {fetchData} = useFetch() - const { setBreadcrumb } = useBreadcrumb() - const [clusterList,setClusterList] = useState([]) - const [nodeList,setNodeList] = useState([]) - const [searchCluster, setSearchCluster] = useState([]) - const [searchNode, setSearchNode] = useState([]) - const [outputListLoading, setOutputListLoading] = useState(true) - - const [outputList, setOutputList] = useState([]) - - const handleSearch = ()=>{} - const [isModalOpen, setIsModalOpen] = useState(false); - const [currentLogFile,setCurrentLogFile] = useState() - // 打开弹窗并连接WebSocket - const handleOpenModal = (x: OutputItemType) => { - setCurrentLogFile(x) - setIsModalOpen(true); - }; - - const getOutputList = (partition:string , cluster:string, node:string)=>{ - setOutputListLoading(true) - fetchData>('log/files',{method:'GET', eoParams:{cluster, node, partition}}).then(response=>{ - const {code,data,msg} = response - if(code === STATUS_CODE.SUCCESS){ - setOutputList(data.output?.map((x:OutputItemType)=>{return{...x,partition:partition, cluster:cluster,node:node, - files:handlerFileData(x.files) - }})) - }else{ - message.error(msg || '操作失败') - } - setOutputListLoading(false) - }) - } - - const handlerFileData = (files:Array)=>{ - return files.sort((a:FileItemType, b:FileItemType) => ((b.file + '').localeCompare(a.file + '')))?.map((x:FileItemType) => { - x.mod = moment(x.mod).format('yyyy-MM-DD HH:mm:ss') - return x - }) - } - - const getClusterList = ()=>{ - setClusterList([]) - fetchData>('simple/partitions/cluster',{method:'GET'}).then(response=>{ - const {code,data,msg} = response - if(code === STATUS_CODE.SUCCESS){ - setClusterList(data.partitions?.filter((x:SimplePartition)=>x.clusters?.length > 0).map( - (x:SimplePartition)=>{ - return { - label:x.name, - value:x.id, - children:x.clusters?.map((c)=>{return{ - label:c.name, - value:c.id, - isLeaf:true} - }) || [] - }})) - setSearchCluster([data.partitions[0]?.id, data.partitions[0]?.clusters[0]?.id]) - if(data.partitions.length == 0 || data.partitions[0]?.clusters.length == 0 ) return - getNodeList(data.partitions[0]?.id,data.partitions[0]?.clusters[0]?.id) - }else{ - message.error(msg || '操作失败') - } - }) - } - - const getNodeList = (partition:string, cluster:string)=>{ - setNodeList([]) - fetchData>(`simple/partition/cluster/nodes`,{method:'GET',eoParams:{cluster}}).then(response=>{ - const {code,data,msg} = response - if(code === STATUS_CODE.SUCCESS){ - setNodeList(data.nodes?.map((node:EntityItem) => { - return ({ label: node.name, value: node.id }) - })) - setSearchNode(data.nodes[0].id) - getOutputList(partition,cluster,data.nodes[0].id) - }else{ - message.error(msg || '操作失败') - } - }) - } - - useEffect(()=>{ - getNodeList(searchCluster[0],searchCluster[1]) - },[searchCluster]) - - useEffect(() => { - setBreadcrumb([{ title: '日志检索'}]) - getClusterList() - }, []); - - return (<> -
-
- - setSearchCluster(val as string[])} placeholder="请选择集群" /> -
-
- -
-} - - -const LogTailComponent = (props:{file:OutputItemType, isVisible:boolean,onClose:()=>void})=>{ - const { - file, - isVisible,onClose} = props - const [logContent, setLogContent] = useState() - const [connected,setConnected] = useState(false) - const [trackLogs, setTrackLogs] = useState(false); - const { createWs } = useWebSocket() - const [wsRef, setWsRef]=useState() - const [editorRef, setEditorRef] = useState() - const closeConnect = () => { - wsRef?.close() - setConnected(false) - } - - const clear = () => { - setLogContent('') - } - - const connectWs = (reConnect?:boolean) => { - setWsRef(createWsRef(!reConnect)) - setConnected(true) - } - - const download = () =>{ - const vDate = new Date() - const fileName: string = `${file.name}_${vDate.getFullYear() + '-' + (vDate.getMonth() + 1) + '-' + vDate.getDate()}` - saveAs(new Blob([logContent as string || ''], { type: 'text/plain;charset=utf-8' }), `${fileName}.txt`) - } - - const updateContent = (newContent:string)=>{ - setLogContent((prevContent)=>prevContent + newContent) - trackLogs && editorRef?.revealLine(editorRef?.getModel()?.getLineCount() || 0 as number); - } - - // init=true时,为初始化ws,需要清空content;init=false时,为重连,ws连接后显示‘已恢复连接’ - const createWsRef = (init:boolean) =>{ - return createWs(`ws://${window.location.host}/api/v1/log/tail/${file.tail}`,{ - onOpen: () => init ? setLogContent('') : updateContent('\n[...已恢复连接...]\n\n'), - onClose: () => updateContent('\n[...已中断连接...]\n'), - onMessage: ( event:MessageEvent) => updateContent(event.data + '\n'), - onError: (error:Event) => console.error('ws连接出现错误:', error)}) - } - - useEffect(() => { - if(isVisible){ - const newWs = createWsRef(true) - setWsRef(newWs) - }else{ - wsRef?.close() - } - return (wsRef?.close()) - }, [isVisible]); - - return ( - -
- setTrackLogs(e.target.checked)}> - 追踪最新日志 - - - {connected ? : - } -
-
- - -
- - ]} - > - { - setEditorRef(editor) - }} - /> -
) -} \ No newline at end of file diff --git a/frontend/packages/core/src/pages/logsettings/LogSettings.tsx b/frontend/packages/core/src/pages/logsettings/LogSettings.tsx index 10d5a87f..1f5acc31 100644 --- a/frontend/packages/core/src/pages/logsettings/LogSettings.tsx +++ b/frontend/packages/core/src/pages/logsettings/LogSettings.tsx @@ -3,11 +3,12 @@ import { Menu, MenuProps, Skeleton, message } from "antd"; import { Link, Outlet, useNavigate, useParams } from "react-router-dom"; import InsidePage from "@common/components/aoplatform/InsidePage"; import { useEffect, useState } from "react"; -import { BasicResponse, STATUS_CODE } from "@common/const/const"; +import { BasicResponse, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const"; import { DynamicMenuItem, } from "@common/const/type"; import { useFetch } from "@common/hooks/http"; import { getItem } from "@common/utils/navigation"; import { RouterParams } from "@core/components/aoplatform/RenderRoutes"; +import { $t } from "@common/locales"; const LogSettings = ()=>{ const {moduleId} = useParams(); @@ -36,8 +37,8 @@ const LogSettings = ()=>{ } return Promise.resolve(newMenu) }else{ - message.error(msg || '操作失败') - return Promise.reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + return Promise.reject(msg || RESPONSE_TIPS.error) } }) } @@ -60,8 +61,8 @@ const LogSettings = ()=>{ <>
{ setBreadcrumb([ - {title:'日志配置'} + {title:$t('日志配置')} ]) },[]) return ( diff --git a/frontend/packages/core/src/pages/member/MemberDropdownModal.tsx b/frontend/packages/core/src/pages/member/MemberDropdownModal.tsx index 2c72941a..c6e09ee5 100644 --- a/frontend/packages/core/src/pages/member/MemberDropdownModal.tsx +++ b/frontend/packages/core/src/pages/member/MemberDropdownModal.tsx @@ -1,9 +1,10 @@ import {App, Form, Input, TreeSelect} from "antd"; import {forwardRef, useEffect, useImperativeHandle, useState} from "react"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE, VALIDATE_MESSAGE} from "@common/const/const.tsx"; import {useFetch} from "@common/hooks/http.ts"; import { MemberDropdownModalHandle, MemberDropdownModalProps, DepartmentListItem, MemberDropdownModalFieldType, MemberTableListItem } from "../../const/member/type.ts"; import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; +import { $t } from "@common/locales/index.ts"; export const MemberDropdownModal = forwardRef((props,ref)=>{ const { message} = App.useApp() @@ -36,7 +37,7 @@ export const MemberDropdownModal = forwardRef{ if(!url || !method){ - reject('类型错误') + reject(RESPONSE_TIPS.error) return } form.validateFields().then((value)=>{ @@ -49,11 +50,11 @@ export const MemberDropdownModal = forwardRef{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }).catch((errorInfo)=> reject(errorInfo)) @@ -71,7 +72,7 @@ export const MemberDropdownModal = forwardRef {type === 'rename' && - label="ID" + label={$t("ID")} name="id" hidden - rules={[{ required: true, message: '必填项',whitespace:true }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required,whitespace:true }]} > - + } {(type === 'addDep' || type === 'rename') && - label="部门名称" + label={$t("部门名称")} name="name" - rules={[{ required: true, message: '必填项',whitespace:true }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required,whitespace:true }]} > - + } {type === 'addChild' &&<> - label="父部门 ID" + label={$t("父部门 ID")} name="parent" hidden - rules={[{ required: true, message: '必填项',whitespace:true }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required,whitespace:true }]} > - + - label="子部门名称" + label={$t("子部门名称")} name="name" - rules={[{ required: true, message: '必填项',whitespace:true }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required,whitespace:true }]} > - + } {(type === 'addMember'|| type ==='editMember') && <> - label="用户名" + label={$t("用户名")} name="name" - rules={[{required: true, message: '必填项',whitespace:true }]} + rules={[{required: true, message: VALIDATE_MESSAGE.required,whitespace:true }]} > - + - label="邮箱" + label={$t("邮箱")} name="email" - rules={[{required: true, message: '必填项',whitespace:true },{type:"email",message: '不是有效邮箱地址'}]} + rules={[{required: true, message: VALIDATE_MESSAGE.required,whitespace:true },{type:"email",message: VALIDATE_MESSAGE.email}]} > - + - label="部门" + label={$t("部门")} name="departmentIds" > ((props,ref)=>{ const {selectedUserIds} = props @@ -34,11 +35,11 @@ const AddToDepartment = forwardRef(( fetchData>('user/department/member',{method:'POST',eoBody:({userIds:selectedUserIds,departmentIds:selectedKeys}),eoTransformKeys:['departmentIds','userIds']}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }) @@ -63,7 +64,7 @@ const AddToDepartment = forwardRef(( children:data.departments.children.filter((x)=>x.id !== 'unknown' && x.id !== 'disable')}]) setExpandedKeys([newId]) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return {data:[], success:false} } }) @@ -81,8 +82,8 @@ const AddToDepartment = forwardRef(( return (
- -

请选择成员需要新加入的部门*

+ +

{$t('请选择成员需要新加入的部门')}*

(( treeData={treeData} selectedKeys={[selectedKeys]} expandedKeys={expandedKeys} - fieldNames={{title:'name',key:'id',children:'children'}} + fieldNames={{title:$t('name'),key:'id',children:'children'}} />
) @@ -119,17 +120,17 @@ const MemberList = ()=>{ const [selectedRowKeys, setSelectedRowKeys] = useState([]); const [departmentValueEnum,setDepartmentValueEnum] = useState([]) const {accessData} = useGlobalContext() - const [columns,setColumns] = useState[]>([]) + const [columns,setColumns] = useState[]>([]) - const operation:ProColumns[] =[ + const operation:PageProColumns[] =[ { - title: '操作', + title: COLUMNS_TITLE.operate, key: 'option', - width: 62, + btnNums:1, fixed:'right', valueType: 'option', render: (_: React.ReactNode, entity: MemberTableListItem) => [ - {openModal('editMember',entity)}} btnTitle="编辑"/>, + {openModal('editMember',entity)}} btnTitle="编辑"/>, ], } ] @@ -150,7 +151,7 @@ const MemberList = ()=>{ setInit((prev)=>prev ? false : prev) return {data:data.members, success: true} }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return {data:[], success:false} } }).catch(() => { @@ -206,11 +207,11 @@ const MemberList = ()=>{ fetchData>(url,{method,eoTransformKeys:['user_ids','userIds'],eoParams:params,eoBody:(body)}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) })} @@ -237,20 +238,20 @@ const MemberList = ()=>{ let content:string|React.ReactNode = '' switch (type){ case 'addMember': - title='添加账号' + title=$t('添加账号') content= break; case 'editMember': - title='编辑成员信息' + title=$t('编辑成员信息') content= break; case 'addToDep': - title='加入部门' + title=$t('加入部门') content= break; case 'delete': - title='删除' - content=确定删除成员?此操作无法恢复,确认操作? + title=$t('删除') + content={$t('确定删除成员?此操作无法恢复,确认操作?')} break; } @@ -270,11 +271,11 @@ const MemberList = ()=>{ } }, width:600, - okText:'确认', + okText:$t('确认'), okButtonProps:{ disabled : isActionAllowed(type) }, - cancelText:'取消', + cancelText:$t('取消'), closable:true, icon:<>, }) @@ -287,7 +288,7 @@ const MemberList = ()=>{ useEffect(()=>{ getRoleList() - setBreadcrumb([{ title: '成员与部门'}]) + setBreadcrumb([{ title: $t('成员与部门')}]) getDepartmentList() },[]) @@ -298,7 +299,7 @@ const MemberList = ()=>{ const tmpValueEnum:ColumnFilterItem[] = [{text:data.department.name, value:data.department.id,children:handleDepartmentListToFilter(data.department.children)}] setDepartmentValueEnum(tmpValueEnum) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } } @@ -308,11 +309,11 @@ const MemberList = ()=>{ fetchData>(`account/role`, {method: 'PUT',eoBody:({roles:value, users:[entity.id]})}).then(response => { const {code, msg} = response if (code === STATUS_CODE.SUCCESS) { - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) } else { - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }) @@ -348,7 +349,7 @@ const MemberList = ()=>{ setColumns(newCol) return } else { - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }) } @@ -360,8 +361,8 @@ const MemberList = ()=>{ ref={pageListRef} columns={[...columns, ...operation]} request={()=>getMemberList()} - addNewBtnTitle={(!memberGroupId ||['unknown','disable'].indexOf(memberGroupId?.toString()) === -1)?"添加账号" : ""} - searchPlaceholder="输入用户名、邮箱查找成员" + addNewBtnTitle={(!memberGroupId ||['unknown','disable'].indexOf(memberGroupId?.toString()) === -1)?$t("添加账号") : ""} + searchPlaceholder={$t("输入用户名、邮箱查找成员")} onAddNewBtnClick={() => { openModal('addMember') }} diff --git a/frontend/packages/core/src/pages/member/MemberPage.tsx b/frontend/packages/core/src/pages/member/MemberPage.tsx index 4d7b1378..0a18c5ea 100644 --- a/frontend/packages/core/src/pages/member/MemberPage.tsx +++ b/frontend/packages/core/src/pages/member/MemberPage.tsx @@ -2,12 +2,12 @@ import Tree, {DataNode} from "antd/es/tree"; import {Outlet, useNavigate, useParams } from "react-router-dom"; import {Key, useEffect, useMemo, useRef, useState} from "react"; -import {App, Button, Divider, Input } from "antd"; +import {App, Button, Input } from "antd"; import {debounce} from "lodash-es"; import {DownOutlined, SearchOutlined} from "@ant-design/icons"; import TreeWithMore from "@common/components/aoplatform/TreeWithMore.tsx"; import {useFetch} from "@common/hooks/http.ts"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; import { DepartmentListItem, MemberDropdownModalHandle } from "../../const/member/type.ts"; import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; import { RouterParams } from "@core/components/aoplatform/RenderRoutes.tsx"; @@ -18,6 +18,7 @@ import { RenameDepModal } from "./Modal/RenameDepModal.tsx"; import { AddDepModal } from "./Modal/AddDepModal.tsx"; import { EditMemberModal } from "./Modal/EditMember.tsx"; import InsidePage from "@common/components/aoplatform/InsidePage.tsx"; +import { $t } from "@common/locales/index.ts"; const MemberPage = ()=>{ const [searchWord, setSearchWord] = useState('') @@ -46,11 +47,11 @@ const MemberPage = ()=>{ fetchData>('user/department',{method:'DELETE',eoParams:{id}}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }) @@ -61,24 +62,24 @@ const MemberPage = ()=>{ let content:string|React.ReactNode = '' switch (type){ case 'addDep': - title='添加部门' + title=$t('添加部门') content= break; case 'addChild': - title='添加子部门' + title=$t('添加子部门') content= break; case 'addMember': - title='添加账号' + title=$t('添加账号') content= break; case 'rename': - title='重命名' + title=$t('重命名') content= break; case 'delete': - title='删除' - content='该数据删除后将无法找回,请确认是否删除?' + title=$t('删除') + content=$t('该数据删除后将无法找回,请确认是否删除?') break; } modal.confirm({ @@ -99,11 +100,11 @@ const MemberPage = ()=>{ } }, width:600, - okText:'确认', + okText:$t('确认'), okButtonProps:{ disabled : isActionAllowed(type) }, - cancelText:'取消', + cancelText:$t('取消'), closable:true, icon:<>, }) @@ -128,7 +129,7 @@ const MemberPage = ()=>{ key: 'addDep', label: ( ), }, @@ -136,7 +137,7 @@ const MemberPage = ()=>{ key: 'addChild', label: ( ), }, @@ -144,7 +145,7 @@ const MemberPage = ()=>{ key: 'addMember', label: ( ), }, @@ -152,7 +153,7 @@ const MemberPage = ()=>{ key: 'rename', label: ( ), }, @@ -160,7 +161,7 @@ const MemberPage = ()=>{ key: 'delete', label: ( ), }, @@ -216,28 +217,14 @@ const MemberPage = ()=>{ if(code === STATUS_CODE.SUCCESS){ setDepartmentList([data.departments]) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return {data:[], success:false} } }) } - // const getModalDepartmentList = ()=>{ - // setModalDepartmentList([]) - // fetchData>('simple/departments',{method:'GET'}).then(response=>{ - // const {code,data,msg} = response - // if(code === STATUS_CODE.SUCCESS){ - // setModalDepartmentList([data.department]) - // }else{ - // message.error(msg || '操作失败') - // return {data:[], success:false} - // } - // }) - // } - useEffect(() => { getDepartmentList() - // getModalDepartmentList() }, []); useEffect(()=>{ @@ -246,14 +233,14 @@ const MemberPage = ()=>{ return (
debounce(onSearchWordChange, 100)(e.target.value)} - allowClear placeholder="搜索部门" + allowClear placeholder={$t("搜索部门")} prefix={}/>
diff --git a/frontend/packages/core/src/pages/member/Modal/AddDepModal.tsx b/frontend/packages/core/src/pages/member/Modal/AddDepModal.tsx index 1e41f062..dfbbd5d3 100644 --- a/frontend/packages/core/src/pages/member/Modal/AddDepModal.tsx +++ b/frontend/packages/core/src/pages/member/Modal/AddDepModal.tsx @@ -1,9 +1,10 @@ import { App, Form, Input } from "antd"; import { forwardRef, useImperativeHandle, useEffect } from "react"; import WithPermission from "@common/components/aoplatform/WithPermission"; -import { BasicResponse, STATUS_CODE } from "@common/const/const"; +import { BasicResponse, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE, VALIDATE_MESSAGE } from "@common/const/const"; import { MemberDropdownModalHandle, MemberDropdownModalProps, MemberDropdownModalFieldType } from "../../../const/member/type"; import { useFetch } from "@common/hooks/http"; +import { $t } from "@common/locales"; export const AddDepModal = forwardRef((props,ref)=>{ const { message} = App.useApp() @@ -23,11 +24,11 @@ export const AddDepModal = forwardRef{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }).catch((errorInfo)=> reject(errorInfo)) @@ -52,26 +53,24 @@ export const AddDepModal = forwardRef {type === 'addChild' && - label="父部门 ID" + label={$t("父部门 ID")} name="parent" hidden - rules={[{ required: true, message: '必填项',whitespace:true }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required,whitespace:true }]} > - + } - label={`${type === 'addChild' ? '子' : ''}部门名称`} + label={[type === 'addChild' ? $t('子部门名称') : $t('部门名称')]} name="name" - rules={[{ required: true, message: '必填项',whitespace:true }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required,whitespace:true }]} > - + diff --git a/frontend/packages/core/src/pages/member/Modal/AddToDepartmentModal.tsx b/frontend/packages/core/src/pages/member/Modal/AddToDepartmentModal.tsx index a980b305..43717462 100644 --- a/frontend/packages/core/src/pages/member/Modal/AddToDepartmentModal.tsx +++ b/frontend/packages/core/src/pages/member/Modal/AddToDepartmentModal.tsx @@ -1,15 +1,16 @@ import { FolderOpenOutlined, FolderOutlined } from "@ant-design/icons" -import { App, TreeProps, Alert, Tree,DataNode } from "antd" +import { App, TreeProps, Alert, Tree } from "antd" import { forwardRef, useState, useImperativeHandle, useEffect } from "react" -import { BasicResponse, STATUS_CODE } from "@common/const/const" +import { BasicResponse, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const" import { AddToDepartmentHandle, AddToDepartmentProps, DepartmentListItem } from "../../../const/member/type" import { useFetch } from "@common/hooks/http" import {v4 as uuidv4} from 'uuid' +import { $t } from "@common/locales" const AddToDepartmentModal = forwardRef((props,ref)=>{ const {selectedUserIds} = props const [selectedKeys, setSelectedKeys] = useState([]) - const [treeData,setTreeData] = useState() + const [treeData,setTreeData] = useState() const { message } = App.useApp() const [expandedKeys, setExpandedKeys] = useState([]) const {fetchData} = useFetch() @@ -18,11 +19,11 @@ const AddToDepartmentModal = forwardRef>('user/department/member',{method:'POST',eoBody:({userIds:selectedUserIds,departmentIds:selectedKeys}),eoTransformKeys:['departmentIds','userIds']}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }) @@ -47,7 +48,7 @@ const AddToDepartmentModal = forwardRefx.id !== 'unknown' && x.id !== 'disable')}]) setExpandedKeys([newId]) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return {data:[], success:false} } }) @@ -65,8 +66,8 @@ const AddToDepartmentModal = forwardRef - -

请选择成员需要新加入的部门*

+ +

{$t('请选择成员需要新加入的部门')}*

) diff --git a/frontend/packages/core/src/pages/member/Modal/EditMember.tsx b/frontend/packages/core/src/pages/member/Modal/EditMember.tsx index ffa6cd8a..b3002d38 100644 --- a/frontend/packages/core/src/pages/member/Modal/EditMember.tsx +++ b/frontend/packages/core/src/pages/member/Modal/EditMember.tsx @@ -2,9 +2,10 @@ import { App, Form, Input, TreeSelect } from "antd"; import { forwardRef, useState, useImperativeHandle, useEffect } from "react"; import WithPermission from "@common/components/aoplatform/WithPermission"; -import { BasicResponse, STATUS_CODE } from "@common/const/const"; +import { BasicResponse, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE, VALIDATE_MESSAGE } from "@common/const/const"; import { MemberDropdownModalHandle, MemberDropdownModalProps, DepartmentListItem, MemberTableListItem, MemberDropdownModalFieldType } from "../../../const/member/type"; import { useFetch } from "@common/hooks/http"; +import { $t } from "@common/locales"; export const EditMemberModal = forwardRef((props,ref)=>{ const { message} = App.useApp() @@ -25,11 +26,11 @@ export const EditMemberModal = forwardRef{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }).catch((errorInfo)=> reject(errorInfo)) @@ -47,7 +48,7 @@ export const EditMemberModal = forwardRef['unknown','disable'].indexOf(x.id) === -1),disabled:true}]) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return {data:[], success:false} } }) @@ -75,26 +76,24 @@ export const EditMemberModal = forwardRef - label="用户名" + label={$t("用户名")} name="name" - rules={[{required: true, message: '必填项',whitespace:true }]} + rules={[{required: true, message: VALIDATE_MESSAGE.required,whitespace:true }]} > - + - label="邮箱" + label={$t("邮箱")} name="email" - rules={[{required: true, message: '必填项',whitespace:true },{type:"email",message: '不是有效邮箱地址'}]} + rules={[{required: true, message: VALIDATE_MESSAGE.required,whitespace:true },{type:"email",message: VALIDATE_MESSAGE.email}]} > - + - label="部门" + label={$t("部门")} name="departmentIds" > ((props,ref)=>{ const { message} = App.useApp() @@ -22,11 +23,11 @@ export const RenameDepModal = forwardRef{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }).catch((errorInfo)=> reject(errorInfo)) @@ -45,28 +46,25 @@ export const RenameDepModal = forwardRef
- label="ID" + label={$t("ID")} name="id" hidden - rules={[{ required: true, message: '必填项',whitespace:true }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required,whitespace:true }]} > - label="部门名称" + label={$t("部门名称")} name="name" - rules={[{ required: true, message: '必填项',whitespace:true }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required,whitespace:true }]} > - + ) diff --git a/frontend/packages/core/src/pages/partitions/PartitionInsideCert.tsx b/frontend/packages/core/src/pages/partitions/PartitionInsideCert.tsx index cec416da..019b9504 100644 --- a/frontend/packages/core/src/pages/partitions/PartitionInsideCert.tsx +++ b/frontend/packages/core/src/pages/partitions/PartitionInsideCert.tsx @@ -1,12 +1,9 @@ -import PageList from "@common/components/aoplatform/PageList.tsx" -import {ActionType, ProColumns} from "@ant-design/pro-components"; +import PageList, { PageProColumns } from "@common/components/aoplatform/PageList.tsx" +import {ActionType} from "@ant-design/pro-components"; import {FC, forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState} from "react"; -import {Link, useParams} from "react-router-dom"; -import {useBreadcrumb} from "@common/contexts/BreadcrumbContext.tsx"; import {App, Button, Col, Divider, Form, Input, Row, Upload} from "antd"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, COLUMNS_TITLE, DELETE_TIPS, RESPONSE_TIPS, STATUS_CODE, VALIDATE_MESSAGE} from "@common/const/const.tsx"; import {useFetch} from "@common/hooks/http.ts"; -import {RouterParams} from "@core/components/aoplatform/RenderRoutes.tsx"; import { Base64 } from 'js-base64'; import { PARTITION_CERT_TABLE_COLUMNS } from "../../const/partitions/const.tsx"; import { PartitionCertConfigHandle, PartitionCertConfigProps, PartitionCertTableListItem } from "../../const/partitions/types.ts"; @@ -17,6 +14,8 @@ import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx"; import { checkAccess } from "@common/utils/permission.ts"; import { PERMISSION_DEFINITION } from "@common/const/permissions.ts"; import InsidePage from "@common/components/aoplatform/InsidePage.tsx"; +import { $t } from "@common/locales/index.ts"; +import { useBreadcrumb } from "@common/contexts/BreadcrumbContext.tsx"; const CertConfigModal = forwardRef((props, ref) => { const { message } = App.useApp() @@ -35,11 +34,11 @@ const CertConfigModal = forwardRef>('certificate',{method:type === 'add'? 'POST' : 'PUT',eoBody:(body), eoParams:type === 'add' ? {}:{id:entity!.id}}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }).catch((errorInfo)=> reject(errorInfo)) @@ -53,7 +52,6 @@ const CertConfigModal = forwardRef { if(type === 'edit' && entity){ - //console.log(entity) form.setFieldsValue({key:Base64.decode(entity.key), pem:Base64.decode(entity.pem)}) forceUpdate({}) } @@ -67,28 +65,26 @@ const CertConfigModal = forwardRef
{ const reader = new FileReader(); - reader.readAsText(file); // 如果你想要纯文本 + reader.readAsText(file); reader.onload = ()=>{ const result = reader.result; - form.setFieldsValue({key: result}); // 更新表单的密钥字段 + form.setFieldsValue({key: result}); forceUpdate({}) } - return false; // 阻止自动上传 + return false; }}> - + @@ -96,7 +92,7 @@ const CertConfigModal = forwardRef { form.setFieldsValue({key: e.target.value}); // 当用户手动输入时更新表单的密钥字段 @@ -109,10 +105,10 @@ const CertConfigModal = forwardRef { const reader = new FileReader(); @@ -124,7 +120,7 @@ const CertConfigModal = forwardRef - + @@ -133,7 +129,7 @@ const CertConfigModal = forwardRef { form.setFieldsValue({pem: e.target.value}); // 当用户手动输入时更新表单的密钥字段 @@ -149,7 +145,6 @@ const CertConfigModal = forwardRef{ const { setBreadcrumb } = useBreadcrumb() const { modal,message } = App.useApp() - const [init, setInit] = useState(true) const {fetchData} = useFetch() const addRef = useRef(null) const editRef = useRef(null) @@ -161,10 +156,9 @@ const PartitionInsideCert:FC = ()=>{ return fetchData>('certificates',{method:'GET',eoTransformKeys:['partition_id','update_time','not_before','not_after']}).then(response=>{ const {code,data,msg} = response if(code === STATUS_CODE.SUCCESS){ - setInit((prev)=>prev ? false : prev) return {data:data.certificates, success: true} }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return {data:[], success:false} } }).catch(() => { @@ -177,11 +171,11 @@ const PartitionInsideCert:FC = ()=>{ fetchData>('certificate',{method:'DELETE',eoParams:{id:entity.id}}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }) @@ -192,24 +186,24 @@ const PartitionInsideCert:FC = ()=>{ let content:string | React.ReactNode= '' switch (type){ case 'add': - title='添加证书' + title=$t('添加证书') content= break; case 'edit':{ - title='修改证书' - message.loading('正在加载数据') + title=$t('修改证书') + message.loading(RESPONSE_TIPS.loading) const {code,data,msg} = await fetchData>('certificate',{method:'GET',eoParams:{id:entity!.id}}) message.destroy() if(code === STATUS_CODE.SUCCESS){ content= }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return } break;} case 'delete': - title='删除' - content='该数据删除后将无法找回,请确认是否删除?' + title=$t('删除') + content=DELETE_TIPS.default break; } @@ -227,11 +221,11 @@ const PartitionInsideCert:FC = ()=>{ } }, width:600, - okText:'确认', + okText:$t('确认'), okButtonProps:{ disabled : !checkAccess( `system.devops.ssl_certificate.${type}` as keyof typeof PERMISSION_DEFINITION[0], accessData) }, - cancelText:'取消', + cancelText:$t('取消'), closable:true, icon:<>, }) @@ -242,23 +236,23 @@ const PartitionInsideCert:FC = ()=>{ pageListRef.current?.reload() }; - const operation:ProColumns[] =[ + const operation:PageProColumns[] =[ { - title: '操作', + title: COLUMNS_TITLE.operate, key: 'option', - width: 105, fixed:'right', + btnNums:2, valueType: 'option', render: (_: React.ReactNode, entity: PartitionCertTableListItem) => [ - {openModal('edit',entity)}} btnTitle="编辑"/>, + {openModal('edit',entity)}} btnTitle="编辑"/>, , - {openModal('delete',entity)}} btnTitle="删除"/>] + {openModal('delete',entity)}} btnTitle="删除"/>] } ] useEffect(() => { setBreadcrumb([ - {title:'证书管理'} + {title:$t('证书管理')} ]) getMemberList() manualReloadTable() @@ -274,7 +268,7 @@ const PartitionInsideCert:FC = ()=>{ }) setMemberValueEnum(tmpValueEnum) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } } @@ -284,8 +278,8 @@ const PartitionInsideCert:FC = ()=>{ return ( @@ -295,7 +289,7 @@ const PartitionInsideCert:FC = ()=>{ columns = {[...columns,...operation]} request={()=>getPartitionCertList()} showPagination={false} - addNewBtnTitle="添加证书" + addNewBtnTitle={$t("添加证书")} addNewBtnAccess="system.devops.ssl_certificate.add" onAddNewBtnClick={()=>{openModal('add')}} onRowClick={(row:PartitionCertTableListItem)=>openModal('edit',row)} diff --git a/frontend/packages/core/src/pages/partitions/PartitionInsideCluster.tsx b/frontend/packages/core/src/pages/partitions/PartitionInsideCluster.tsx index 2a9773f2..e03f276f 100644 --- a/frontend/packages/core/src/pages/partitions/PartitionInsideCluster.tsx +++ b/frontend/packages/core/src/pages/partitions/PartitionInsideCluster.tsx @@ -1,13 +1,14 @@ import { FC, useEffect, useRef, useState} from "react"; import {useBreadcrumb} from "@common/contexts/BreadcrumbContext.tsx"; import {App, Button, Card, Col, Row, Spin, Tag} from "antd"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, STATUS_CODE} from "@common/const/const.tsx"; import {useFetch} from "@common/hooks/http.ts"; import { ClusterPageShowStatus, NodeModalHandle, PartitionClusterNodeTableListItem } from "../../const/partitions/types.ts"; import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; import { ClusterNodeModal } from "./PartitionInsideClusterNode.tsx"; import { LoadingOutlined } from "@ant-design/icons"; import InsidePage from "@common/components/aoplatform/InsidePage.tsx"; +import { $t } from "@common/locales/index.ts"; const PartitionInsideCluster:FC = ()=> { const {setBreadcrumb} = useBreadcrumb() @@ -26,7 +27,7 @@ const PartitionInsideCluster:FC = ()=> { data.nodes && data.nodes.length > 0 && setNodeData(data.nodes[0]) setShowStatus('view') } else { - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }).catch(() => { return {data: [], success: false} @@ -38,7 +39,7 @@ const PartitionInsideCluster:FC = ()=> { useEffect(() => { setBreadcrumb([ - {title: '集群'} + {title: $t('集群')} ]) getPartitionClusterInfo() }, []); @@ -46,7 +47,7 @@ const PartitionInsideCluster:FC = ()=> { const setClusterBtn = ()=>{ return (<> {showStatus === 'view' && - + } ) } @@ -54,8 +55,8 @@ const PartitionInsideCluster:FC = ()=> { return ( <> @@ -69,9 +70,9 @@ const PartitionInsideCluster:FC = ()=> { className="overflow-hidden w-full max-h-full flex flex-col justify-between" title={
APIPark Node {!loading && - { !nodeData && '未配置'} - { nodeData?.status === 1 && '正常' } - { nodeData?.status === 0 && '异常'} + { !nodeData && $t('未配置')} + { nodeData?.status === 1 && $t('正常') } + { nodeData?.status === 0 && $t('异常')} }
} extra={setClusterBtn()}> {showStatus === 'view'&& nodeData && ClusterConfigPreview(nodeData) } diff --git a/frontend/packages/core/src/pages/partitions/PartitionInsideClusterNode.tsx b/frontend/packages/core/src/pages/partitions/PartitionInsideClusterNode.tsx index a9d23ca2..51baa6ae 100644 --- a/frontend/packages/core/src/pages/partitions/PartitionInsideClusterNode.tsx +++ b/frontend/packages/core/src/pages/partitions/PartitionInsideClusterNode.tsx @@ -1,13 +1,12 @@ import {forwardRef, useImperativeHandle, useState} from "react"; -import {App, Button, Form, Input, Table} from "antd"; +import {App, Button, Form, Input} from "antd"; import {useFetch} from "@common/hooks/http.ts"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; -import { NODE_MODAL_COLUMNS } from "../../const/partitions/const.tsx"; +import {BasicResponse, FORM_ERROR_TIPS, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE, VALIDATE_MESSAGE} from "@common/const/const.tsx"; import { NodeModalHandle, PartitionClusterNodeModalTableListItem, PartitionClusterNodeTableListItem, NodeModalFieldType, NodeModalPropsType } from "../../const/partitions/types.ts"; import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; import { ClusterConfigPreview } from "./PartitionInsideCluster.tsx"; -import { set, values } from "lodash-es"; +import { $t } from "@common/locales/index.ts"; export const ClusterNodeModal = forwardRef((props,ref)=>{ const { message } = App.useApp() @@ -27,11 +26,11 @@ export const ClusterNodeModal = forwardRef( fetchData>('cluster/check', {method: 'POST', eoBody: (value),eoTransformKeys:['manager_address','service_address','peer_address']}).then(response => { const {code,data, msg} = response if (code === STATUS_CODE.SUCCESS) { - message.success(msg || '操作成功') + message.success(msg || RESPONSE_TIPS.success) setDataSource(data.nodes) changeStatus('preview') } else { - message.error(msg || '无法连接集群,请检查集群地址是否正确或防火墙配置') + message.error(msg ||FORM_ERROR_TIPS.clusterTest) setAddressError('error') } @@ -45,10 +44,10 @@ export const ClusterNodeModal = forwardRef( fetchData>('cluster/reset',{method:'PUT' ,eoBody:({managerAddress:form.getFieldValue('address')}), eoTransformKeys:['managerAddress']}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) getClusterInfo() }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> console.warn(errorInfo)) @@ -75,19 +74,19 @@ export const ClusterNodeModal = forwardRef( {status === 'edit' ? - label="集群地址" + label={$t("集群地址")} name="address" className="mb-0" validateStatus={addressError} - help={addressError ? form.getFieldValue('address')? '无法连接集群,请检查集群地址是否正确或防火墙配置' : '必填项' : ''} + help={addressError ? form.getFieldValue('address')? FORM_ERROR_TIPS.clusterTest : VALIDATE_MESSAGE.required : ''} > - test()} onChange={(e)=>setAddressError(e.target?.value ? '' : 'error')}/> + test()} onChange={(e)=>setAddressError(e.target?.value ? '' : 'error')}/> : dataSource && ClusterConfigPreview(dataSource?.[0] as unknown as PartitionClusterNodeTableListItem)}
- { status === 'edit' && } - { status === 'preview' && } - + { status === 'edit' && } + { status === 'preview' && } +
diff --git a/frontend/packages/core/src/pages/resourcesettings/ResourceSettings.tsx b/frontend/packages/core/src/pages/resourcesettings/ResourceSettings.tsx index 209832f4..e9abf44d 100644 --- a/frontend/packages/core/src/pages/resourcesettings/ResourceSettings.tsx +++ b/frontend/packages/core/src/pages/resourcesettings/ResourceSettings.tsx @@ -3,11 +3,12 @@ import { Menu, MenuProps, Skeleton, message } from "antd"; import { Link, Outlet, useNavigate, useParams } from "react-router-dom"; import InsidePage from "@common/components/aoplatform/InsidePage"; import { useEffect, useState } from "react"; -import { BasicResponse, STATUS_CODE } from "@common/const/const"; +import { BasicResponse, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const"; import { DynamicMenuItem } from "@common/const/type"; import { useFetch } from "@common/hooks/http"; import { getItem } from "@common/utils/navigation"; import { RouterParams } from "@core/components/aoplatform/RenderRoutes"; +import { $t } from "@common/locales"; const LogSettings = ()=>{ const {moduleId} = useParams(); @@ -36,7 +37,7 @@ const LogSettings = ()=>{ navigateTo(`/resourcesettings/template/${data.dynamics[0].name}`) } }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }).finally(()=>setLoading(false)) } @@ -59,7 +60,7 @@ const LogSettings = ()=>{ <>
{ const { message } = App.useApp() const [form] = Form.useForm(); - // const [formData, dispatch] = useReducer(formReducer, {}); - // const [dataSource,setDataSource] = useState([]) const {fetchData} = useFetch() const navigateTo = useNavigate() const { roleType, roleId} = useParams() @@ -153,7 +152,7 @@ const RoleConfig = ()=>{ generateDependenciesMap(newPermits) setPermissionTemplate(newPermits) }else{ - message.error(msg || '获取权限模板失败') + message.error(msg || RESPONSE_TIPS.dataError) } }) } @@ -165,8 +164,8 @@ const RoleConfig = ()=>{ form.setFieldsValue({name:data.role.name,permits:data.role.permit}) return Promise.resolve(true) }else{ - message.error(msg || '操作失败') - return Promise.reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + return Promise.reject(msg || RESPONSE_TIPS.error) } }).catch((errInfo)=>Promise.reject(errInfo)) } @@ -185,11 +184,11 @@ const RoleConfig = ()=>{ return fetchData>(`${roleType}/role`,{method:roleId === undefined? 'POST' : 'PUT',eoBody:({...body}),...(roleId !== undefined?{eoParams:{role:roleId}}:{})}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) return Promise.resolve(true) }else{ - message.error(msg || '操作失败') - return Promise.reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + return Promise.reject(msg || RESPONSE_TIPS.error) } }).catch((errInfo)=>Promise.reject(errInfo)) }; @@ -214,9 +213,9 @@ const RoleConfig = ()=>{ - + { {APP_MODE === 'pro' &&
}
diff --git a/frontend/packages/core/src/pages/role/RoleList.tsx b/frontend/packages/core/src/pages/role/RoleList.tsx index 9bf88d3d..17b101bd 100644 --- a/frontend/packages/core/src/pages/role/RoleList.tsx +++ b/frontend/packages/core/src/pages/role/RoleList.tsx @@ -1,9 +1,9 @@ import { App} from "antd"; -import PageList from "@common/components/aoplatform/PageList.tsx"; +import PageList, { PageProColumns } from "@common/components/aoplatform/PageList.tsx"; import { useEffect, useRef,} from "react"; -import {ActionType, ProColumns} from "@ant-design/pro-components"; +import {ActionType} from "@ant-design/pro-components"; import {useBreadcrumb} from "@common/contexts/BreadcrumbContext.tsx"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, COLUMNS_TITLE, DELETE_TIPS, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; import {useFetch} from "@common/hooks/http.ts"; import { ROLE_TABLE_COLUMNS } from "../../const/role/const.tsx"; import TableBtnWithPermission from "@common/components/aoplatform/TableBtnWithPermission.tsx"; @@ -13,6 +13,7 @@ import { checkAccess } from "@common/utils/permission.ts"; import { useNavigate } from "react-router-dom"; import { RoleTableListItem } from "@core/const/role/type.ts"; import InsidePage from "@common/components/aoplatform/InsidePage.tsx"; +import { $t } from "@common/locales/index.ts"; const RoleList = ()=>{ @@ -23,16 +24,16 @@ const RoleList = ()=>{ const {accessData} = useGlobalContext() const navigateTo = useNavigate() - const operation:(type:string)=>ProColumns[] =(type:string)=>[ + const operation:(type:string)=>PageProColumns[] =(type:string)=>[ // TODO 开源版隐藏操作 { - title: '操作', + title: COLUMNS_TITLE.operate, key: 'option', - width: 93, + btnNums:1, fixed:'right', valueType: 'option', render: (_: React.ReactNode, entity: RoleTableListItem) => [ - {navigateTo(`/role/${type}/config/${entity.id}`)}} btnTitle="查看"/>, + {navigateTo(`/role/${type}/config/${entity.id}`)}} btnTitle="查看"/>, // {navigateTo(`/role/${type}/config/${entity.id}`)}} btnTitle="编辑"/>, // , // {openModal(type as 'system'|'team','delete',entity)}} btnTitle="删除"/>, @@ -46,7 +47,7 @@ const RoleList = ()=>{ if(code === STATUS_CODE.SUCCESS){ return {data:data.roles, success: true} }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return {data:[], success:false} } }).catch(() => { @@ -59,11 +60,11 @@ const RoleList = ()=>{ fetchData>(`manage/role`,{method:'DELETE',eoParams:{id:entity.id}}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }) @@ -85,8 +86,8 @@ const RoleList = ()=>{ let content:string|React.ReactNode = '' switch (type){ case 'delete': - title='删除' - content='该数据删除后将无法找回,请确认是否删除?' + title=$t('删除') + content=DELETE_TIPS.default break; } @@ -100,11 +101,11 @@ const RoleList = ()=>{ } }, width:600, - okText:'确认', + okText:$t('确认'), okButtonProps:{ disabled:isActionAllowed(accessType, type) }, - cancelText:'取消', + cancelText:$t('取消'), closable:true, icon:<>, }) @@ -113,26 +114,26 @@ const RoleList = ()=>{ useEffect(() => { setBreadcrumb([ { - title: '角色'}]) + title: $t('角色')}]) }, []); return (<>
-

系统级别角色

+

{$t('系统级别角色')}

[], ...operation('system')]} + columns={[...ROLE_TABLE_COLUMNS as PageProColumns[], ...operation('system')]} request={()=>getRoleList('system')} - addNewBtnTitle="添加角色" + addNewBtnTitle={$t("添加角色")} showPagination={false} onAddNewBtnClick={() => { navigateTo(`/role/system/config`) @@ -142,15 +143,15 @@ const RoleList = ()=>{ onRowClick={(row:RoleTableListItem)=> navigateTo(`/role/system/config/${row.id}`)} tableClickAccess="system.organization.role.system.edit" /> -

团队级别角色

+

{$t('团队级别角色')}

[], ...operation('team')]} + columns={[...ROLE_TABLE_COLUMNS as PageProColumns[], ...operation('team')]} request={()=>getRoleList('team')} showPagination={false} - addNewBtnTitle="添加角色" + addNewBtnTitle={$t("添加角色")} onAddNewBtnClick={() => { navigateTo(`/role/team/config`) }} diff --git a/frontend/packages/core/src/pages/serviceCategory/ServiceCategory.tsx b/frontend/packages/core/src/pages/serviceCategory/ServiceCategory.tsx index 8834d662..688e9fc4 100644 --- a/frontend/packages/core/src/pages/serviceCategory/ServiceCategory.tsx +++ b/frontend/packages/core/src/pages/serviceCategory/ServiceCategory.tsx @@ -1,6 +1,6 @@ import TreeWithMore from "@common/components/aoplatform/TreeWithMore"; import WithPermission from "@common/components/aoplatform/WithPermission"; -import { BasicResponse, STATUS_CODE } from "@common/const/const"; +import { BasicResponse, DELETE_TIPS, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const"; import { PERMISSION_DEFINITION } from "@common/const/permissions"; import { useFetch } from "@common/hooks/http"; import { checkAccess } from "@common/utils/permission"; @@ -16,6 +16,7 @@ import { cloneDeep } from "lodash-es"; import { Icon } from "@iconify/react/dist/iconify.js"; import InsidePage from "@common/components/aoplatform/InsidePage"; import { EntityItem } from "@common/const/type"; +import { $t } from "@common/locales"; export default function ServiceCategory(){ const [gData, setGData] = useState([]); @@ -92,7 +93,7 @@ export default function ServiceCategory(){ key: 'addChildCate', label: ( ), }, @@ -100,7 +101,7 @@ export default function ServiceCategory(){ key: 'renameCate', label: ( ), }, @@ -108,7 +109,7 @@ export default function ServiceCategory(){ key: 'delete', label: ( ), }, @@ -157,20 +158,20 @@ export default function ServiceCategory(){ let content:string|React.ReactNode = '' switch (type){ case 'addCate': - title='添加分类' + title=$t('添加分类') content= break; case 'addChildCate': - title='添加子分类' + title=$t('添加子分类') content= break; case 'renameCate': - title='重命名分类' + title=$t('重命名分类') content= break; case 'delete': - title='删除' - content='该数据删除后将无法找回,请确认是否删除?' + title=$t('删除') + content=DELETE_TIPS.default break; } modal.confirm({ @@ -189,11 +190,11 @@ export default function ServiceCategory(){ } }, width:600, - okText:'确认', + okText:$t('确认'), okButtonProps:{ disabled : isActionAllowed(type) }, - cancelText:'取消', + cancelText:$t('取消'), closable:true, icon:<>, }) @@ -204,11 +205,11 @@ export default function ServiceCategory(){ fetchData>('catalogue',{method:'DELETE',eoParams:{catalogue:entity.id},}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功,即将刷新页面') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }) @@ -222,7 +223,7 @@ export default function ServiceCategory(){ getCategoryList() }else{ setGData(cateData) - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }).catch(()=>{setGData(cateData)}).finally(()=>{setLoading(false)}) } @@ -235,7 +236,7 @@ export default function ServiceCategory(){ setGData(data.catalogues) setCateData(data.catalogues) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }).finally(()=>{setLoading(false)}) } @@ -243,14 +244,14 @@ export default function ServiceCategory(){ useEffect(()=>{ setBreadcrumb([ { - title: '服务分类管理'}]) + title: $t('服务分类管理')}]) getCategoryList() },[]) return ( - +
diff --git a/frontend/packages/core/src/pages/serviceCategory/ServiceHubCategoryConfig.tsx b/frontend/packages/core/src/pages/serviceCategory/ServiceHubCategoryConfig.tsx index b4e31eaa..748a3fd9 100644 --- a/frontend/packages/core/src/pages/serviceCategory/ServiceHubCategoryConfig.tsx +++ b/frontend/packages/core/src/pages/serviceCategory/ServiceHubCategoryConfig.tsx @@ -1,9 +1,10 @@ import {App, Form, Input} from "antd"; import {forwardRef, useEffect, useImperativeHandle} from "react"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE, VALIDATE_MESSAGE} from "@common/const/const.tsx"; import {useFetch} from "@common/hooks/http.ts"; import { ServiceHubCategoryConfigHandle, ServiceHubCategoryConfigFieldType, ServiceHubCategoryConfigProps } from "@market/const/serviceHub/type.ts" import WithPermission from "@common/components/aoplatform/WithPermission"; +import { $t } from "@common/locales"; export const ServiceHubCategoryConfig = forwardRef((props,ref)=>{ const { message } = App.useApp() @@ -25,18 +26,18 @@ export const ServiceHubCategoryConfig = forwardRef{ if(!url || !method){ - reject('类型错误') + reject(RESPONSE_TIPS.error) return } form.validateFields().then((value)=>{ fetchData>(url,{method,eoBody:(value), eoParams:{ ...(type === 'renameCate' ? {catalogue:value.id} :undefined)}}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }).catch((errorInfo)=> reject(errorInfo)) @@ -52,14 +53,12 @@ export const ServiceHubCategoryConfig = forwardRef {type === 'renameCate' && - label="ID" + label={$t("ID")} name="id" hidden - rules={[{ required: true, message: '必填项',whitespace:true }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required,whitespace:true }]} > - + } {(type === 'addCate' || type === 'renameCate') && - label="分类名称" + label={$t("分类名称")} name="name" - rules={[{ required: true, message: '必填项' ,whitespace:true }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required ,whitespace:true }]} > - + } {type === 'addChildCate' &&<> - label="父分类 ID" + label={$t("父分类 ID")} name="parent" hidden - rules={[{ required: true, message: '必填项',whitespace:true }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required,whitespace:true }]} > - + - label="子分类名称" + label={$t("子分类名称")} name="name" - rules={[{ required: true, message: '必填项' ,whitespace:true }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required ,whitespace:true }]} > - + } diff --git a/frontend/packages/core/src/pages/system/SystemConfig.tsx b/frontend/packages/core/src/pages/system/SystemConfig.tsx index 21c6bd34..d3c718c4 100644 --- a/frontend/packages/core/src/pages/system/SystemConfig.tsx +++ b/frontend/packages/core/src/pages/system/SystemConfig.tsx @@ -3,7 +3,7 @@ import {forwardRef, useEffect, useImperativeHandle, useState} from "react"; import {App, Button, Form, Input, Radio, Row, Select, TreeSelect, Upload} from "antd"; import { Link, useNavigate, useParams} from "react-router-dom"; import {RouterParams} from "@core/components/aoplatform/RenderRoutes.tsx"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, DELETE_TIPS, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE, VALIDATE_MESSAGE} from "@common/const/const.tsx"; import {useFetch} from "@common/hooks/http.ts"; import {DefaultOptionType} from "antd/es/cascader"; import { EntityItem, MemberItem, SimpleTeamItem} from "@common/const/type.ts"; @@ -21,6 +21,7 @@ import { CategorizesType } from "@market/const/serviceHub/type.ts"; import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; import { Icon } from "@iconify/react/dist/iconify.js"; import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx"; +import { $t } from "@common/locales/index.ts"; const MAX_SIZE = 2 * 1024; // 1KB @@ -47,7 +48,7 @@ const SystemConfig = forwardRef((_,ref) => { const beforeUpload = async (file: RcFile) => { if (!['image/png', 'image/jpeg', 'image/svg+xml'].includes(file.type)) { - alert('只允许上传PNG、JPG或SVG格式的图片'); + alert($t('只允许上传PNG、JPG或SVG格式的图片')); return false; } @@ -104,7 +105,7 @@ const SystemConfig = forwardRef((_,ref) => { setServiceClassifyOptionList(data.catalogues) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }) } @@ -133,7 +134,7 @@ const SystemConfig = forwardRef((_,ref) => { setShowClassify(data.service.serviceType === 'public') },0) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }) }; @@ -143,12 +144,12 @@ const SystemConfig = forwardRef((_,ref) => { return fetchData>(serviceId === undefined? 'team/service':'service/info',{method:serviceId === undefined? 'POST' : 'PUT',eoParams: {...(serviceId === undefined ? {team:value.team} :{service:serviceId,team:teamId})},eoBody:({...value,prefix:value.prefix?.trim()}), eoTransformKeys:['serviceType']},).then(response=>{ const {code,data,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) setSystemInfo(data.service) return Promise.resolve(true) }else{ - message.error(msg || '操作失败') - return Promise.reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + return Promise.reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=>{ return Promise.reject(errorInfo) @@ -167,7 +168,7 @@ const SystemConfig = forwardRef((_,ref) => { label:x.name, value:x.id }})) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }) } @@ -176,10 +177,10 @@ const SystemConfig = forwardRef((_,ref) => { fetchData>('team/service',{method:'DELETE',eoParams:{team:teamId,service:serviceId}}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) navigate(`/service/list`) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }) } @@ -192,10 +193,10 @@ const SystemConfig = forwardRef((_,ref) => { getSystemInfo(); setBreadcrumb([ { - title: 服务 + title: {$t('服务')} }, { - title: '设置' + title: $t('设置') }]) } else { @@ -210,17 +211,17 @@ const SystemConfig = forwardRef((_,ref) => { const deleteSystemModal = async ()=>{ modal.confirm({ - title:'删除', - content:'该数据删除后将无法找回,请确认是否删除?', + title:$t('删除'), + content:DELETE_TIPS.default, onOk:()=> { return deleteSystem() }, width:600, - okText:'确认', + okText:$t('确认'), okButtonProps:{ danger:true }, - cancelText:'取消', + cancelText:$t('取消'), closable:true, icon:<> }) @@ -241,37 +242,37 @@ const SystemConfig = forwardRef((_,ref) => { >
- label="服务名称" + label={$t("服务名称")} name="name" - rules={[{ required: true, message: '必填项' ,whitespace:true }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required ,whitespace:true }]} > - + - label="服务ID" + label={$t("服务ID")} name="id" - rules={[{ required: true, message: '必填项' ,whitespace:true }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required ,whitespace:true }]} > - + - label="API 调用前缀" + label={$t("API 调用前缀")} name="prefix" - extra="选填,作为服务内所有API的前缀,比如host/{service_name}/{api_path},一旦保存无法修改" + extra={$t("选填,作为服务内所有API的前缀,比如host/{service_name}/{api_path},一旦保存无法修改")} rules={[ { validator: validateUrlSlash, }]} > - + - label="图标" + label={$t("图标")} name="logoFile" - extra="仅支持 .png .jpg .jpeg .svg 格式的图片文件, 大于 1KB 的文件将被压缩" + extra={$t("仅支持 .png .jpg .jpeg .svg 格式的图片文件, 大于 1KB 的文件将被压缩")} valuePropName="fileList" getValueFromEvent={normFile} > ((_,ref) => { - label="描述" + label={$t("描述")} name="description" > - + - label="Logo" + label={$t("Logo")} name="logo" hidden > {!onEdit && - label="所属团队" + label={$t("所属团队")} name="team" - rules={[{ required: true, message: '必填项' }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required }]} > - } - label="标签" + label={$t("标签")} name="tags" > - label="服务类型" + label={$t("服务类型")} name="serviceType" - rules={[{required: true, message: '必填项'}]} + rules={[{required: true, message: VALIDATE_MESSAGE.required}]} > {setShowClassify(e.target.value === 'public')}} /> {showClassify && - label="所属服务分类" + label={$t("所属服务分类")} name="catalogue" - extra="设置服务展示在服务市场中的哪个分类下" - rules={[{required: true, message: '必填项'}]} + extra={$t("设置服务展示在服务市场中的哪个分类下")} + rules={[{required: true, message: VALIDATE_MESSAGE.required}]} > ((_,ref) => { > } @@ -366,10 +367,10 @@ const SystemConfig = forwardRef((_,ref) => { {onEdit && <>
-

删除服务:删除操作不可恢复,请谨慎操作!

+

{$t('删除服务')}:{$t('删除操作不可恢复,请谨慎操作!')}

- +
diff --git a/frontend/packages/core/src/pages/system/SystemInsideDocument.tsx b/frontend/packages/core/src/pages/system/SystemInsideDocument.tsx index 16d8eb9d..b94f0544 100644 --- a/frontend/packages/core/src/pages/system/SystemInsideDocument.tsx +++ b/frontend/packages/core/src/pages/system/SystemInsideDocument.tsx @@ -2,16 +2,16 @@ import { Editor } from '@tinymce/tinymce-react'; import hljs from 'highlight.js'; import 'highlight.js/styles/default.css'; import {useEffect, useState} from "react"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; import {useFetch} from "@common/hooks/http.ts"; import {App, Button} from "antd"; import { EntityItem } from '@common/const/type.ts'; import WithPermission from '@common/components/aoplatform/WithPermission.tsx'; import { RouterParams } from '@core/components/aoplatform/RenderRoutes'; import { useParams } from 'react-router-dom'; +import { $t } from '@common/locales'; const ServiceInsideDocument = ()=>{ const { message } = App.useApp() - const [serviceName,setServiceName] = useState() const [updater,setUpdater] = useState() const [updateTime,setUpdateTime]=useState() const [initDoc, setInitDoc] = useState() @@ -23,10 +23,10 @@ const ServiceInsideDocument = ()=>{ fetchData>('service/doc',{method:'PUT',eoBody:({doc:doc}) ,eoParams:{service:serviceId,team:teamId},eoTransformKeys:['update_time']}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) getServiceDoc() }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }) } @@ -52,12 +52,11 @@ const ServiceInsideDocument = ()=>{ fetchData>('service/doc',{method:'GET',eoParams:{service:serviceId,team:teamId},eoTransformKeys:['update_time']}).then(response=>{ const {code,data,msg} = response if(code === STATUS_CODE.SUCCESS){ - setServiceName(data.doc.name) setUpdater(data.doc.updater.id === '' ? '-' : data.doc.updater.name) setUpdateTime(data.doc.updater.id === '' ? '-' : data.doc.updateTime) setInitDoc(data.doc.doc) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }) } @@ -137,8 +136,8 @@ const ServiceInsideDocument = ()=>{
-

最近一次更新者:{updater || '-'}最近一次更新时间:{updateTime || '-'}

- +

{$t('最近一次更新者')}:{updater || '-'}{$t('最近一次更新时间')}:{updateTime || '-'}

+
) diff --git a/frontend/packages/core/src/pages/system/SystemInsidePage.tsx b/frontend/packages/core/src/pages/system/SystemInsidePage.tsx index 1666f576..9185a2df 100644 --- a/frontend/packages/core/src/pages/system/SystemInsidePage.tsx +++ b/frontend/packages/core/src/pages/system/SystemInsidePage.tsx @@ -3,7 +3,7 @@ import {FC, useEffect, useMemo, useState} from "react"; import {Outlet, useLocation, useNavigate, useParams} from "react-router-dom"; import {RouterParams} from "@core/components/aoplatform/RenderRoutes.tsx"; import {App, Menu, MenuProps} from "antd"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; import {useFetch} from "@common/hooks/http.ts"; import { useSystemContext} from "../../contexts/SystemContext.tsx"; import { SYSTEM_PAGE_MENU_ITEMS } from "../../const/system/const.tsx"; @@ -14,6 +14,7 @@ import InsidePage from "@common/components/aoplatform/InsidePage.tsx"; import Paragraph from "antd/es/typography/Paragraph"; import { ItemType, MenuItemGroupType, MenuItemType } from "antd/es/menu/hooks/useItems"; import { cloneDeep } from "lodash-es"; +import { $t } from "@common/locales/index.ts"; const SystemInsidePage:FC = ()=> { const { message } = App.useApp() @@ -32,7 +33,7 @@ const SystemInsidePage:FC = ()=> { if(code === STATUS_CODE.SUCCESS){ setSystemInfo(data.service) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }) } @@ -46,7 +47,7 @@ const SystemInsidePage:FC = ()=> { setApiPrefix(data.prefix) setPrefixForce(data.force) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }) } @@ -105,7 +106,7 @@ const SystemInsidePage:FC = ()=> { <> 服务 ID:{serviceId || '-'} + {$t('服务 ID')}:{serviceId || '-'} }]} backUrl="/service/list">
diff --git a/frontend/packages/core/src/pages/system/SystemInsideSubscriber.tsx b/frontend/packages/core/src/pages/system/SystemInsideSubscriber.tsx index f7e7a631..c734a45b 100644 --- a/frontend/packages/core/src/pages/system/SystemInsideSubscriber.tsx +++ b/frontend/packages/core/src/pages/system/SystemInsideSubscriber.tsx @@ -1,26 +1,26 @@ -import {ActionType, ProColumns} from "@ant-design/pro-components"; +import {ActionType} from "@ant-design/pro-components"; import {FC, forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState} from "react"; import {Link, useParams} from "react-router-dom"; -import {App, Form, Select,TreeSelect} from "antd"; +import {App, Form,TreeSelect} from "antd"; import {useBreadcrumb} from "@common/contexts/BreadcrumbContext.tsx"; import {useFetch} from "@common/hooks/http.ts"; import { RouterParams } from "@core/components/aoplatform/RenderRoutes.tsx"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; -import PageList from "@common/components/aoplatform/PageList.tsx"; +import {BasicResponse, COLUMNS_TITLE, DELETE_TIPS, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE, VALIDATE_MESSAGE} from "@common/const/const.tsx"; +import PageList, { PageProColumns } from "@common/components/aoplatform/PageList.tsx"; import {DefaultOptionType} from "antd/es/cascader"; import { SYSTEM_SUBSCRIBER_TABLE_COLUMNS } from "../../const/system/const.tsx"; import { SystemSubscriberTableListItem, SystemSubscriberConfigFieldType, SystemSubscriberConfigHandle, SystemSubscriberConfigProps, SimpleSystemItem } from "../../const/system/type.ts"; -import { NewSimpleMemberItem, SimpleMemberItem } from "@common/const/type.ts"; +import { SimpleMemberItem } from "@common/const/type.ts"; import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; import TableBtnWithPermission from "@common/components/aoplatform/TableBtnWithPermission.tsx"; import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx"; import { checkAccess } from "@common/utils/permission.ts"; +import { $t } from "@common/locales/index.ts"; const SystemInsideSubscriber:FC = ()=>{ const { setBreadcrumb } = useBreadcrumb() const { modal,message } = App.useApp() const {fetchData} = useFetch() - const [init, setInit] = useState(true) const {serviceId, teamId} = useParams() const addRef = useRef(null) const pageListRef = useRef(null); @@ -30,10 +30,9 @@ const SystemInsideSubscriber:FC = ()=>{ return fetchData>('service/subscribers',{method:'GET',eoParams:{service:serviceId,team:teamId},eoTransformKeys:['apply_time']}).then(response=>{ const {code,data,msg} = response if(code === STATUS_CODE.SUCCESS){ - setInit((prev)=>prev ? false : prev) return {data:data.subscribers, success: true} }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return {data:[], success:false} } }).catch(() => { @@ -51,7 +50,7 @@ const SystemInsideSubscriber:FC = ()=>{ }) setMemberValueEnum(tmpValueEnum) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } } @@ -64,11 +63,11 @@ const SystemInsideSubscriber:FC = ()=>{ fetchData>('service/subscriber',{method:'DELETE',eoParams:{application:entity!.id,service:entity!.service.id,team:teamId}}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }) @@ -79,12 +78,12 @@ const SystemInsideSubscriber:FC = ()=>{ let content:string|React.ReactNode = '' switch (type){ case 'add': - title='新增订阅方' + title=$t('新增订阅方') content= break; case 'delete': - title='删除' - content='该数据删除后将无法找回,请确认是否删除?' + title=$t('删除') + content=DELETE_TIPS.default break; } @@ -100,25 +99,25 @@ const SystemInsideSubscriber:FC = ()=>{ } }, width:600, - okText:'确认', + okText:$t('确认'), okButtonProps:{ disabled : !checkAccess( `team.service.subscription.${type}`, accessData) }, - cancelText:'取消', + cancelText:$t('取消'), closable:true, icon:<>, }) } - const operation:ProColumns[] =[ + const operation:PageProColumns[] =[ { - title: '操作', + title: COLUMNS_TITLE.operate, key: 'option', - width: 62, + btnNums:1, fixed:'right', valueType: 'option', render: (_: React.ReactNode, entity: SystemSubscriberTableListItem) => [ - {openModal('delete',entity)}} btnTitle="删除"/>, + {openModal('delete',entity)}} btnTitle="删除"/>, ], } ] @@ -126,10 +125,10 @@ const SystemInsideSubscriber:FC = ()=>{ useEffect(() => { setBreadcrumb([ { - title:服务 + title:{$t('服务')} }, { - title:'订阅方管理' + title:$t('订阅方管理') } ]) getMemberList() @@ -148,7 +147,7 @@ const SystemInsideSubscriber:FC = ()=>{ request={()=>getSystemSubscriber()} // dataSource={tableListDataSource} showPagination={false} - addNewBtnTitle="新增订阅方" + addNewBtnTitle={$t("新增订阅方")} onAddNewBtnClick={()=>{openModal('add')}} addNewBtnAccess="team.service.subscription.add" tableClass="pr-PAGE_INSIDE_X" @@ -158,7 +157,6 @@ const SystemInsideSubscriber:FC = ()=>{ export default SystemInsideSubscriber - export const SystemSubscriberConfig = forwardRef((props, ref) => { const { message } = App.useApp() const { serviceId, teamId} = props @@ -171,11 +169,11 @@ export const SystemSubscriberConfig = forwardRef>('service/subscriber',{method:'POST',eoBody:({...value}), eoParams:{service:serviceId,team:teamId}}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }) }).catch((errorInfo)=> reject(errorInfo)) @@ -218,7 +216,7 @@ export const SystemSubscriberConfig = forwardRef - label="订阅方" + label={$t("订阅方")} name="application" - rules={[{ required: true, message: '必填项' }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required }]} > diff --git a/frontend/packages/core/src/pages/system/SystemList.tsx b/frontend/packages/core/src/pages/system/SystemList.tsx index d119387f..f1fbe627 100644 --- a/frontend/packages/core/src/pages/system/SystemList.tsx +++ b/frontend/packages/core/src/pages/system/SystemList.tsx @@ -4,7 +4,7 @@ import {FC, useEffect, useMemo, useRef, useState} from "react"; import {useNavigate} from "react-router-dom"; import { App} from "antd"; import {useBreadcrumb} from "@common/contexts/BreadcrumbContext.tsx"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; import {useFetch} from "@common/hooks/http.ts"; import { SimpleTeamItem ,SimpleMemberItem} from "@common/const/type.ts"; import { SystemConfigHandle, SystemTableListItem } from "../../const/system/type.ts"; @@ -12,6 +12,7 @@ import { SYSTEM_TABLE_COLUMNS } from "../../const/system/const.tsx"; import { DrawerWithFooter } from "@common/components/aoplatform/DrawerWithFooter.tsx"; import SystemConfig from "./SystemConfig.tsx"; import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx"; +import { $t } from "@common/locales/index.ts"; const SystemList:FC = ()=>{ const navigate = useNavigate(); @@ -19,12 +20,10 @@ const SystemList:FC = ()=>{ const { setBreadcrumb } = useBreadcrumb() const [teamList, setTeamList] = useState<{ [k: string]: { text: string; }; }>() const {fetchData} = useFetch() - const [init, setInit] = useState(true) const [tableListDataSource, setTableListDataSource] = useState([]); const [tableHttpReload, setTableHttpReload] = useState(true); const { message } = App.useApp() const pageListRef = useRef(null); - const [loading, setLoading] = useState(true) const [memberValueEnum, setMemberValueEnum] = useState<{[k:string]:{text:string}}>({}) const [open, setOpen] = useState(false); const drawerFormRef = useRef(null) @@ -42,11 +41,10 @@ const SystemList:FC = ()=>{ const {code,data,msg} = response if(code === STATUS_CODE.SUCCESS){ setTableListDataSource(data.services) - setInit((prev)=>prev ? false : prev) setTableHttpReload(false) return {data:data.services, success: true} }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return {data:[], success:false} } }).catch(() => { @@ -59,14 +57,13 @@ const SystemList:FC = ()=>{ const {code,data,msg} = response setTeamList(data.teams) if(code === STATUS_CODE.SUCCESS){ - setLoading(false) const tmpValueEnum:{[k:string]:{text:string}} = {} data.teams?.forEach((x:SimpleMemberItem)=>{ tmpValueEnum[x.name] = {text:x.name} }) setTeamList(tmpValueEnum) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return {data:[], success:false} } }) @@ -87,7 +84,7 @@ const SystemList:FC = ()=>{ }) setMemberValueEnum(tmpValueEnum) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } } @@ -96,16 +93,10 @@ const SystemList:FC = ()=>{ getMemberList() setBreadcrumb([ { - title: '服务' + title: $t('服务') }]) }, []); - // useEffect(() => { - // if(!init){ - // manualReloadTable() - // } - // }, []); - const onClose = () => { setOpen(false); }; @@ -124,7 +115,6 @@ const SystemList:FC = ()=>{ },[memberValueEnum,teamList]) return ( - //
{ ref={pageListRef} columns={[...columns]} request={()=>getSystemList()} - addNewBtnTitle="添加服务" - searchPlaceholder="输入名称、ID、所属团队、负责人查找服务" + addNewBtnTitle={$t("添加服务")} + searchPlaceholder={$t("输入名称、ID、所属团队、负责人查找服务")} onAddNewBtnClick={() => { setOpen(true) }} @@ -146,7 +136,7 @@ const SystemList:FC = ()=>{ }} onRowClick={(row:SystemTableListItem)=>navigate(`/service/${row.team.id}/inside/${row.id}`)} /> - drawerFormRef.current?.save()?.then((res)=>{res && manualReloadTable();return res})} > + drawerFormRef.current?.save()?.then((res)=>{res && manualReloadTable();return res})} >
diff --git a/frontend/packages/core/src/pages/system/SystemTopology.tsx b/frontend/packages/core/src/pages/system/SystemTopology.tsx index 3ef00d39..1433dd63 100644 --- a/frontend/packages/core/src/pages/system/SystemTopology.tsx +++ b/frontend/packages/core/src/pages/system/SystemTopology.tsx @@ -9,13 +9,14 @@ import { Link, useParams } from "react-router-dom"; import { RouterParams } from "@core/components/aoplatform/RenderRoutes"; import { useFetch } from "@common/hooks/http"; import { App, Button } from "antd"; -import { BasicResponse, STATUS_CODE } from "@common/const/const"; +import { BasicResponse, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const"; import { useSystemContext } from "../../contexts/SystemContext"; import { ZoomInOutlined, ZoomOutOutlined } from "@ant-design/icons"; import { useBreadcrumb } from "@common/contexts/BreadcrumbContext"; import { debounce } from "lodash-es"; import { SYSTEM_TOPOLOGY_NODE_TYPE_COLOR_MAP } from "../../const/system/const"; import { SystemTopologyResponse } from "../../const/system/type"; +import { $t } from "@common/locales"; export default function SystemTopology() { @@ -36,7 +37,7 @@ export default function SystemTopology() { if(code === STATUS_CODE.SUCCESS){ setGraphData(transformData({...data,currentSystem:{id:serviceId,name:systemInfo?.name || ''}})) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }) } @@ -109,10 +110,10 @@ export default function SystemTopology() { getNodeData() setBreadcrumb([ { - title: 服务 + title: {$t('服务')} }, { - title: '调用拓扑图' + title: $t('调用拓扑图') }]) },[serviceId]) diff --git a/frontend/packages/core/src/pages/system/api/SystemInsideApiCreate.tsx b/frontend/packages/core/src/pages/system/api/SystemInsideApiCreate.tsx index de24795b..0baa9a6a 100644 --- a/frontend/packages/core/src/pages/system/api/SystemInsideApiCreate.tsx +++ b/frontend/packages/core/src/pages/system/api/SystemInsideApiCreate.tsx @@ -1,16 +1,15 @@ import {App, Col, Form, Input, Row, Select} from "antd"; import {forwardRef, useEffect, useImperativeHandle, useRef} from "react"; -import { useParams} from "react-router-dom"; -import {RouterParams} from "@core/components/aoplatform/RenderRoutes.tsx"; import EditableTableWithModal from "@common/components/aoplatform/EditableTableWithModal.tsx"; import styles from "./SystemInsideApi.module.css" -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE, VALIDATE_MESSAGE} from "@common/const/const.tsx"; import {useFetch} from "@common/hooks/http.ts"; import { HTTP_METHOD, MATCH_CONFIG } from "../../../const/system/const.tsx"; import { SystemInsideApiCreateHandle, SystemInsideApiCreateProps, SystemApiProxyFieldType, SystemInsideApiProxyHandle } from "../../../const/system/type.ts"; import { MatchItem } from "@common/const/type.ts"; import { validateUrlSlash } from "@common/utils/validate.ts"; -import SystemInsideApiProxy from "./SystemInsideApiProxy.tsx"; +import { $t } from "@common/locales/index.ts"; +import SystemInsideApiProxy from "@core/pages/system/api/SystemInsideApiProxy"; const SystemInsideApiCreate = forwardRef((props, ref) => { const { message } = App.useApp() @@ -25,11 +24,11 @@ const SystemInsideApiCreate = forwardRef>('service/api',{method:'POST',eoBody:(body), eoParams: {service:serviceId,team:teamId},eoTransformKeys:['matchType']}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功,即将刷新页面') + message.success(msg || RESPONSE_TIPS.success) return Promise.resolve(true) }else{ - message.error(msg || '操作失败') - return Promise.reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + return Promise.reject(msg || RESPONSE_TIPS.error) } }).catch(errInfo=>Promise.reject(errInfo)) }) @@ -41,11 +40,11 @@ const SystemInsideApiCreate = forwardRef>('service/api/copy',{method:'POST',eoParams:{service:serviceId,team:teamId, api:entity!.id},eoBody:({...value,path:value.path.trim()})}).then(response=>{ const {code,data,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功,即将刷新页面') + message.success(msg || RESPONSE_TIPS.success) return resolve(data.api.id) }else{ - message.error(msg || '操作失败') - return reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + return reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }).catch((errorInfo)=> reject(errorInfo)) @@ -62,7 +61,7 @@ const SystemInsideApiCreate = forwardRef
-
API 基础信息 + {$t('API 基础信息')} - label="API 名称" + label={$t("API 名称")} name="name" - rules={[{ required: true, message: '必填项' ,whitespace:true }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required ,whitespace:true }]} > - + - label="描述" + label={$t("描述")} name="description" > - + - label="请求方式" + label={$t("请求方式")} name="method" - rules={[{ required: true, message: '必填项' }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required }]} > - { return { label:method, value:method} })}> - label="请求路径" + label={$t("请求路径")} name="path" - rules={[{ required: true, message: '必填项',whitespace:true }, + rules={[{ required: true, message: VALIDATE_MESSAGE.required,whitespace:true }, { validator: validateUrlSlash, }]} className={styles['form-input-group']} > + placeholder={PLACEHOLDER.input}/> - label="高级匹配" + label={$t("高级匹配")} name="match" > @@ -141,7 +140,7 @@ const SystemInsideApiCreate = forwardRef - 转发规则设置 + {$t('转发规则设置')} className="mb-0 bg-transparent border-none p-0" name="proxy" diff --git a/frontend/packages/core/src/pages/system/api/SystemInsideApiDetail.tsx b/frontend/packages/core/src/pages/system/api/SystemInsideApiDetail.tsx index 1e06ad1e..3238815d 100644 --- a/frontend/packages/core/src/pages/system/api/SystemInsideApiDetail.tsx +++ b/frontend/packages/core/src/pages/system/api/SystemInsideApiDetail.tsx @@ -1,6 +1,6 @@ import {useEffect, useRef, useState} from "react"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; import {useFetch} from "@common/hooks/http.ts"; import {App, Button, Spin} from "antd"; import ApiBasicInfoDisplay from "@common/components/postcat/api/ApiPreview/components/ApiBasicInfoDisplay"; @@ -15,6 +15,7 @@ import SystemInsideApiDocument from "./SystemInsideApiDocument.tsx"; import ScrollableSection from "@common/components/aoplatform/ScrollableSection.tsx"; import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; import { LoadingOutlined } from "@ant-design/icons"; +import { $t } from "@common/locales/index.ts"; const SystemInsideApiDetail = (props:SystemInsideApiDetailProps)=>{ const { message } = App.useApp() @@ -40,7 +41,7 @@ const SystemInsideApiDetail = (props:SystemInsideApiDetailProps)=>{ } setApiDetail(newApiDetail) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }).finally(()=>{setLoading(false)}) } @@ -62,29 +63,29 @@ const SystemInsideApiDetail = (props:SystemInsideApiDetailProps)=>{ apiDetail !== undefined && <>
- +

- 创建者:{apiDetail?.creator.name || '-'} - 最后编辑人:{apiDetail?.updater.name || '-'}更新时间:{apiDetail?.updateTime || '-'}

+ {$t('创建者')}:{apiDetail?.creator.name || '-'} + {$t('最后编辑人')}:{apiDetail?.updater.name || '-'}{$t('更新时间')}:{apiDetail?.updateTime || '-'}

}
{ apiDetail?.match && apiDetail.match?.length > 0 && - + } { apiDetail?.proxy && Object.keys(apiDetail?.proxy).length > 0 && - + } {apiDetail && }
drawerFormRef.current?.save()?.then((res)=>{res&& getApiDetail();return res})} diff --git a/frontend/packages/core/src/pages/system/api/SystemInsideApiDocument.tsx b/frontend/packages/core/src/pages/system/api/SystemInsideApiDocument.tsx index 8f1cd5e7..402e4bd4 100644 --- a/frontend/packages/core/src/pages/system/api/SystemInsideApiDocument.tsx +++ b/frontend/packages/core/src/pages/system/api/SystemInsideApiDocument.tsx @@ -2,7 +2,7 @@ import {forwardRef, useEffect, useImperativeHandle, useRef, useState} from "react"; import ApiEdit, {ApiEditApi} from "@common/components/postcat/ApiEdit.tsx"; import { Spin, message} from "antd"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; import {useFetch} from "@common/hooks/http.ts"; import { SystemApiDetail, SystemInsideApiDocumentHandle, SystemInsideApiDocumentProps } from "../../../const/system/type.ts"; import { LoadingOutlined } from "@ant-design/icons"; @@ -33,7 +33,7 @@ const SystemInsideApiDocument = forwardRef{setLoading(false)}) } @@ -43,11 +43,11 @@ const SystemInsideApiDocument = forwardRef>('service/api',{method:'PUT',eoParams:{service:serviceId,team:teamId,api:apiId},eoBody:(res.apiInfo)}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功') + message.success(msg || RESPONSE_TIPS.success) return Promise.resolve(true) }else{ - message.error(msg || '操作失败') - return Promise.reject(msg|| '操作失败') + message.error(msg || RESPONSE_TIPS.error) + return Promise.reject(msg|| RESPONSE_TIPS.error) } }).catch(errInfo => Promise.reject(errInfo)) }) diff --git a/frontend/packages/core/src/pages/system/api/SystemInsideApiList.tsx b/frontend/packages/core/src/pages/system/api/SystemInsideApiList.tsx index 68e74bbf..d70b6c64 100644 --- a/frontend/packages/core/src/pages/system/api/SystemInsideApiList.tsx +++ b/frontend/packages/core/src/pages/system/api/SystemInsideApiList.tsx @@ -1,10 +1,10 @@ -import PageList from "@common/components/aoplatform/PageList.tsx" -import {ActionType, ProColumns} from "@ant-design/pro-components"; +import PageList, { PageProColumns } from "@common/components/aoplatform/PageList.tsx" +import {ActionType} from "@ant-design/pro-components"; import {FC, useEffect, useMemo, useRef, useState} from "react"; import {Link, useParams} from "react-router-dom"; import {useBreadcrumb} from "@common/contexts/BreadcrumbContext.tsx"; import {App, Divider} from "antd"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, COLUMNS_TITLE, DELETE_TIPS, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; import { SimpleMemberItem} from '@common/const/type.ts' import {useFetch} from "@common/hooks/http.ts"; import {RouterParams} from "@core/components/aoplatform/RenderRoutes.tsx"; @@ -18,6 +18,7 @@ import { checkAccess } from "@common/utils/permission.ts"; import { DrawerWithFooter } from "@common/components/aoplatform/DrawerWithFooter.tsx"; import SystemInsideApiDetail from "./SystemInsideApiDetail.tsx"; import SystemInsideApiDocument from "./SystemInsideApiDocument.tsx"; +import { $t } from "@common/locales/index.ts"; const SystemInsideApiList:FC = ()=>{ const [searchWord, setSearchWord] = useState('') @@ -59,7 +60,7 @@ const SystemInsideApiList:FC = ()=>{ setTableHttpReload(false) return {data:data.apis, success: true} }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return {data:[], success:false} } }).catch(() => { @@ -72,11 +73,11 @@ const SystemInsideApiList:FC = ()=>{ fetchData>('service/api',{method:'DELETE',eoParams:{service:serviceId,team:teamId, api:entity!.id}}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }) @@ -87,20 +88,20 @@ const SystemInsideApiList:FC = ()=>{ let content:string|React.ReactNode = '' switch (type){ case 'copy':{ - title='复制 API' - message.loading('正在加载数据') + title=$t('复制 API') + message.loading(RESPONSE_TIPS.loading) const {code,data,msg} = await fetchData>('service/api/detail/simple',{method:'GET',eoParams:{service:serviceId,team:teamId, api:entity!.id}}) message.destroy() if(code === STATUS_CODE.SUCCESS){ content= }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return } break;} case 'delete': - title='删除' - content='该数据删除后将无法找回,请确认是否删除?' + title=$t('删除') + content=DELETE_TIPS.default break; } @@ -118,31 +119,31 @@ const SystemInsideApiList:FC = ()=>{ } }, width:type==='copy'? 900: 600, - okText:'确认', + okText:$t('确认'), okButtonProps:{ disabled : !checkAccess( `team.service.api.${type}`, accessData ) }, - cancelText:'取消', + cancelText:$t('取消'), closable:true, icon:<>, }) } - const operation:ProColumns[] =[ + const operation:PageProColumns[] =[ { - title: '操作', + title: COLUMNS_TITLE.operate, key: 'option', - width: 194, + btnNums:4, fixed:'right', valueType: 'option', render: (_: React.ReactNode, entity: SystemApiTableListItem) => [ - {openDrawer('view',entity)}} btnTitle="详情"/>, + {openDrawer('view',entity)}} btnTitle="详情"/>, , - {openModal('copy',entity)}} btnTitle="复制"/>, + {openModal('copy',entity)}} btnTitle="复制"/>, , - {openDrawer('edit',entity)}} btnTitle="编辑"/>, + {openDrawer('edit',entity)}} btnTitle="编辑"/>, entity.canDelete && , - entity.canDelete && {openModal('delete',entity)}} btnTitle="删除"/>, + entity.canDelete && {openModal('delete',entity)}} btnTitle="删除"/>, ], } ] @@ -162,7 +163,7 @@ const SystemInsideApiList:FC = ()=>{ }) setMemberValueEnum(tmpValueEnum) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } } @@ -176,10 +177,10 @@ const SystemInsideApiList:FC = ()=>{ useEffect(() => { setBreadcrumb([ { - title:服务 + title:{$t('服务')} }, { - title:'API' + title:$t('API') } ]) getMemberList() @@ -215,8 +216,8 @@ const SystemInsideApiList:FC = ()=>{ columns = {[...columns,...operation]} request={()=>getApiList()} dataSource={tableListDataSource} - addNewBtnTitle="添加 API" - searchPlaceholder="输入名称、URL 查找 API" + addNewBtnTitle={$t('添加 API')} + searchPlaceholder={$t('输入名称、URL 查找 API')} onAddNewBtnClick={()=>{openDrawer('add')}} addNewBtnAccess="team.service.api.add" tableClickAccess="team.service.api.view" @@ -229,7 +230,7 @@ const SystemInsideApiList:FC = ()=>{ tableClass="mr-PAGE_INSIDE_X " /> handlerSubmit()} diff --git a/frontend/packages/core/src/pages/system/api/SystemInsideApiProxy.tsx b/frontend/packages/core/src/pages/system/api/SystemInsideApiProxy.tsx index c372a7ff..91542285 100644 --- a/frontend/packages/core/src/pages/system/api/SystemInsideApiProxy.tsx +++ b/frontend/packages/core/src/pages/system/api/SystemInsideApiProxy.tsx @@ -4,6 +4,8 @@ import { forwardRef, useEffect, useImperativeHandle } from "react" import EditableTableWithModal from "@common/components/aoplatform/EditableTableWithModal"; import { PROXY_HEADER_CONFIG } from "../../../const/system/const"; import { SystemApiProxyType, ProxyHeaderItem, SystemInsideApiProxyHandle, SystemInsideApiProxyProps } from "../../../const/system/type"; +import { PLACEHOLDER, VALIDATE_MESSAGE } from "@common/const/const"; +import { $t } from "@common/locales"; const SystemInsideApiProxy = forwardRef((props,ref)=>{ const {value, onChange, className,initProxyValue} = props @@ -33,37 +35,35 @@ const SystemInsideApiProxy = forwardRef{onChange?.(allValues)}} autoComplete="off"> - label="转发上游路径" + label={$t("转发上游路径")} name={'path'} > - + - label="请求超时时间" + label={$t("请求超时时间")} name={'timeout'} - extra="单位:ms,最小值:1" - rules={[{required: true, message: '必填项'}]} + extra={$t("单位:ms,最小值:1")} + rules={[{required: true, message: VALIDATE_MESSAGE.required}]} > - + - label="重试次数" + label={$t("重试次数")} name={'retry'} - rules={[{required: true, message: '必填项'}]} + rules={[{required: true, message: VALIDATE_MESSAGE.required}]} > - + - label="转发上游请求头" + label={$t("转发上游请求头")} name={'headers'} > diff --git a/frontend/packages/core/src/pages/system/approval/SystemInsideApprovalList.tsx b/frontend/packages/core/src/pages/system/approval/SystemInsideApprovalList.tsx index 95954fda..f60e5de6 100644 --- a/frontend/packages/core/src/pages/system/approval/SystemInsideApprovalList.tsx +++ b/frontend/packages/core/src/pages/system/approval/SystemInsideApprovalList.tsx @@ -1,8 +1,8 @@ -import {ActionType, ProColumns} from "@ant-design/pro-components"; +import {ActionType} from "@ant-design/pro-components"; import {FC, useEffect, useMemo, useRef, useState} from "react"; import {Link, useLocation, useParams} from "react-router-dom"; -import PageList from "@common/components/aoplatform/PageList.tsx"; +import PageList, { PageProColumns } from "@common/components/aoplatform/PageList.tsx"; import {useBreadcrumb} from "@common/contexts/BreadcrumbContext.tsx"; import {App, Button} from "antd"; import { @@ -10,20 +10,20 @@ import { SUBSCRIBE_APPROVAL_INNER_TODO_TABLE_COLUMN, SubscribeApprovalTableListItem, TODO_LIST_COLUMN_NOT_INCLUDE_KEY } from "@common/const/approval/const.tsx"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, COLUMNS_TITLE, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; import {useFetch} from "@common/hooks/http.ts"; import {RouterParams} from "@core/components/aoplatform/RenderRoutes.tsx"; import { SubscribeApprovalModalContent, SubscribeApprovalModalHandle } from "@common/components/aoplatform/SubscribeApprovalModalContent.tsx"; -import {useSystemContext} from "../../../contexts/SystemContext.tsx"; import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; -import { EntityItem,SimpleMemberItem } from "@common/const/type.ts"; +import { SimpleMemberItem } from "@common/const/type.ts"; import TableBtnWithPermission from "@common/components/aoplatform/TableBtnWithPermission.tsx"; import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx"; import { checkAccess } from "@common/utils/permission.ts"; import { SubscribeApprovalInfoType } from "@common/const/approval/type.tsx"; +import { $t } from "@common/locales"; const SystemInsideApprovalList:FC = ()=>{ const { setBreadcrumb } = useBreadcrumb() @@ -42,19 +42,19 @@ const SystemInsideApprovalList:FC = ()=>{ const {accessData} = useGlobalContext() const openModal = async (type:'approval'|'view',entity:SubscribeApprovalTableListItem)=>{ - message.loading('正在加载数据') + message.loading(RESPONSE_TIPS.loading) const {code,data,msg} = await fetchData>('service/approval/subscribe',{method:'GET',eoParams:{apply:entity!.id, service:serviceId,team:teamId},eoTransformKeys:['apply_project','apply_team','apply_time','approval_time']}) message.destroy() if(code === STATUS_CODE.SUCCESS){ const modalIns = modal.confirm({ - title:type === 'approval' ? '审批' : '查看', + title:type === 'approval' ? $t('审批') : $t('查看'), content:, onOk:()=>{ return subscribeRef.current?.save('pass').then((res)=>res === true && manualReloadTable()) }, width:600, - okText:type === 'approval' ? '通过' : '确认', - cancelText:type === 'approval' ?'取消':'关闭', + okText:type === 'approval' ? $t('通过') : $t('确认'), + cancelText:type === 'approval' ?$t('取消'):$t('关闭'), okButtonProps:{ disabled : type === 'approval' ? !checkAccess('team.service.release.approval', accessData): false }, @@ -66,12 +66,11 @@ const SystemInsideApprovalList:FC = ()=>{ <> {type === 'approval' ? <> - + : <> - {/* */} } @@ -79,22 +78,22 @@ const SystemInsideApprovalList:FC = ()=>{ }, }) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return } } - const operation:ProColumns[] =[ + const operation:PageProColumns[] =[ { - title: '操作', + title: COLUMNS_TITLE.operate, key: 'option', - width: 62, + btnNums:1, fixed:'right', valueType: 'option', render: (_: React.ReactNode, entity: SubscribeApprovalTableListItem) => [ pageStatus === 0 ? - {openModal('approval',entity)}} btnTitle="审批"/> - :{openModal('view',entity)}} btnTitle="查看"/>, + {openModal('approval',entity)}} btnTitle="审批"/> + :{openModal('view',entity)}} btnTitle="查看"/>, ], } ] @@ -114,7 +113,7 @@ const SystemInsideApprovalList:FC = ()=>{ setInit((prev)=>prev ? false : prev) return {data:data.approvals, success: true} }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return {data:[], success:false} } }).catch(() => { @@ -132,7 +131,7 @@ const SystemInsideApprovalList:FC = ()=>{ }) setMemberValueEnum(tmpValueEnum) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } } @@ -148,10 +147,10 @@ const SystemInsideApprovalList:FC = ()=>{ useEffect(() => { setBreadcrumb([ { - title:服务 + title:{$t('服务')} }, { - title:'订阅审批' + title:$t('订阅审批') } ]) getMemberList() diff --git a/frontend/packages/core/src/pages/system/publish/SystemInsidePublish.tsx b/frontend/packages/core/src/pages/system/publish/SystemInsidePublish.tsx index f921259e..8a657373 100644 --- a/frontend/packages/core/src/pages/system/publish/SystemInsidePublish.tsx +++ b/frontend/packages/core/src/pages/system/publish/SystemInsidePublish.tsx @@ -5,6 +5,7 @@ import { Link, Outlet, useLocation, useNavigate, useParams } from "react-router- import { useBreadcrumb } from "@common/contexts/BreadcrumbContext" import { RouterParams } from "@core/components/aoplatform/RenderRoutes" import { SYSTEM_PUBLISH_TAB_ITEMS } from "../../../const/system/const" +import { $t } from "@common/locales" const SystemInsidePublic:FC = ()=>{ const { setBreadcrumb } = useBreadcrumb() @@ -27,10 +28,10 @@ const SystemInsidePublic:FC = ()=>{ useEffect(() => { setBreadcrumb([ { - title:服务 + title:{$t('服务')} }, { - title:'发布' + title:$t('发布') } ]) }, []); diff --git a/frontend/packages/core/src/pages/system/publish/SystemInsidePublishList.tsx b/frontend/packages/core/src/pages/system/publish/SystemInsidePublishList.tsx index 6ed6c58f..69ab08b3 100644 --- a/frontend/packages/core/src/pages/system/publish/SystemInsidePublishList.tsx +++ b/frontend/packages/core/src/pages/system/publish/SystemInsidePublishList.tsx @@ -1,12 +1,12 @@ -import { ActionType, ParamsType, ProColumns } from "@ant-design/pro-components"; +import { ActionType, ParamsType } from "@ant-design/pro-components"; import { App, Button, Divider } from "antd"; import { useState, useRef, useEffect, useMemo, FC } from "react"; import { useParams, Link, useLocation } from "react-router-dom"; -import PageList from "@common/components/aoplatform/PageList"; -import { PublishApprovalModalHandle, PublishApprovalModalContent } from "@common/components/aoplatform/PublishApprovalModalContent"; +import PageList, { PageProColumns } from "@common/components/aoplatform/PageList"; +import { PublishApprovalModalContent } from "@common/components/aoplatform/PublishApprovalModalContent"; import { RouterParams } from "@core/components/aoplatform/RenderRoutes"; import { PUBLISH_APPROVAL_RECORD_INNER_TABLE_COLUMN, PUBLISH_APPROVAL_VERSION_INNER_TABLE_COLUMN } from "@common/const/approval/const"; -import { BasicResponse, STATUS_CODE } from "@common/const/const"; +import { BasicResponse, COLUMNS_TITLE, DELETE_TIPS, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const"; import { SimpleMemberItem } from "@common/const/type.ts"; import { MemberTableListItem } from "../../../const/member/type"; import { useBreadcrumb } from "@common/contexts/BreadcrumbContext"; @@ -18,8 +18,9 @@ import { useGlobalContext } from "@common/contexts/GlobalStateContext"; import { PERMISSION_DEFINITION } from "@common/const/permissions"; import { checkAccess } from "@common/utils/permission"; import SystemInsidePublishOnline from "./SystemInsidePublishOnline"; -import { PublishVersionTableListItem, PublishTableListItem, PublishApprovalInfoType } from "@common/const/approval/type"; +import { PublishVersionTableListItem, PublishTableListItem, PublishApprovalInfoType, PublishApprovalModalHandle } from "@common/const/approval/type"; import { DrawerWithFooter } from "@common/components/aoplatform/DrawerWithFooter"; +import { $t } from "@common/locales"; const SystemInsidePublicList:FC = ()=>{ const { setBreadcrumb } = useBreadcrumb() @@ -31,9 +32,6 @@ const SystemInsidePublicList:FC = ()=>{ const [tableListDataSource, setTableListDataSource] = useState([]); const {serviceId, teamId} = useParams(); const drawerRef = useRef(null) - // const approvalRef = useRef(null) - // const addRef = useRef(null) - // const onlineRef = useRef(null) const [extraModalBtnLoading,setExtraModalBtnLoading] = useState(false) const [pageStatus,setPageStatus] = useState<0|1>(0 as 0|1) const [pageType, setPageType] = useState<'insideSystem'|'global'>('insideSystem') @@ -69,7 +67,7 @@ const SystemInsidePublicList:FC = ()=>{ setInit((prev)=>prev ? false : prev) return {data:finalRes, success: true} }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) setInit((prev)=>prev ? false : prev) return {data:[], success:false} } @@ -102,11 +100,11 @@ const SystemInsidePublicList:FC = ()=>{ fetchData>(url,{method,eoParams:params}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) })} @@ -119,7 +117,7 @@ const SystemInsidePublicList:FC = ()=>{ const handleOnline = (entity:PublishTableListItem | PublishVersionTableListItem)=>{ modal.confirm({ - title:'发布结果', + title:$t('发布结果'), content:, width: 600, closable: true, @@ -136,7 +134,7 @@ const SystemInsidePublicList:FC = ()=>{ setIsOkToPublish(false) switch (type) { case 'view':{ - message.loading('正在加载数据'); + message.loading(RESPONSE_TIPS.loading); const viewPublish:boolean = pageStatus !== 0 || ((entity as PublishVersionTableListItem)?.status && (entity as PublishVersionTableListItem)?.status !== 'none') const { code, data, msg } = await fetchData>( viewPublish ? 'service/publish':'service/release', @@ -144,66 +142,66 @@ const SystemInsidePublicList:FC = ()=>{ ); message.destroy(); if (code === STATUS_CODE.SUCCESS) { - setDrawerTitle('查看详情') + setDrawerTitle($t('查看详情')) setDrawerType(type) setDrawerData(viewPublish ? data.publish : data.release)} else { - message.error(msg || '操作失败'); + message.error(msg || RESPONSE_TIPS.error); return } break; } case 'online':{ - message.loading('正在加载数据'); + message.loading(RESPONSE_TIPS.loading); const { code, data, msg } = await fetchData>( 'service/publish', { method: 'GET', eoParams:{ id: (entity as PublishVersionTableListItem)?.flowId,service:serviceId,team:teamId },eoTransformKeys:['version_remark'] } ); message.destroy(); if (code === STATUS_CODE.SUCCESS) { - setDrawerTitle('上线') + setDrawerTitle($t('上线')) setDrawerType(type) - setDrawerOkTitle('上线') + setDrawerOkTitle($t('上线')) setDrawerData({...data.publish, flowId:(entity as PublishVersionTableListItem)?.flowId}) } else { - message.error(msg || '操作失败'); + message.error(msg || RESPONSE_TIPS.error); return } break; } case 'approval':{ - message.loading('正在加载数据'); + message.loading(RESPONSE_TIPS.loading); const { code, data, msg } = await fetchData>( 'service/publish', { method: 'GET', eoParams:{ id: (entity as PublishVersionTableListItem)?.flowId,service:serviceId,team:teamId },eoTransformKeys:['version_remark'] } ); message.destroy(); if (code === STATUS_CODE.SUCCESS) { - setDrawerTitle('审批') + setDrawerTitle($t('审批')) setDrawerType(type) setDrawerData(data.publish) - setDrawerOkTitle('通过') + setDrawerOkTitle($t('通过')) } else { - message.error(msg || '操作失败'); + message.error(msg || RESPONSE_TIPS.error); return } break; } case 'publish': case 'add':{ - message.loading('正在加载数据'); + message.loading(RESPONSE_TIPS.loading); const { code, data, msg } = await fetchData>( 'service/publish/check', { method: 'GET', eoParams:{service:serviceId,team:teamId, ...(type === 'publish' ?{ release:entity?.id }:{})},eoTransformKeys:['version_remark'] } ); message.destroy(); if (code === STATUS_CODE.SUCCESS) { - setDrawerTitle('申请发布') + setDrawerTitle($t('申请发布')) setDrawerType(type) setDrawerData({...data, ...(type === 'publish'&& {version:entity?.version, id:entity?.id})}) - setDrawerOkTitle('确认') + setDrawerOkTitle($t('确认')) setIsOkToPublish(data.isOk??true) } else { - message.error(msg || '操作失败'); + message.error(msg || RESPONSE_TIPS.error); return } break; @@ -218,20 +216,20 @@ const SystemInsidePublicList:FC = ()=>{ let content: string | React.ReactNode = ''; switch (type) { case 'delete': - title = '删除'; - content = '该数据删除后将无法找回,请确认是否删除?'; + title = $t('删除'); + content = DELETE_TIPS.default; break; case 'rollback': - title = '回滚'; - content = '请确认是否回滚?'; + title = $t('回滚'); + content = $t('请确认是否回滚?'); break; case 'cancel': - title = '撤销申请'; - content = '请确认是否撤销申请?'; + title = $t('撤销申请'); + content = $t('请确认是否撤销申请?'); break; case 'stop': - title = '终止发布'; - content = '请确认是否终止发布?'; + title = $t('终止发布'); + content = $t('请确认是否终止发布?'); break; } @@ -250,8 +248,8 @@ const SystemInsidePublicList:FC = ()=>{ } }, width: 600, - okText: '确认', - cancelText: '取消', + okText: $t('确认'), + cancelText: $t('取消'), onCancel:()=>{setExtraModalBtnLoading(false)}, closable: true, icon: <>, @@ -270,7 +268,7 @@ const SystemInsidePublicList:FC = ()=>{ }; const tableOperation = (entity:PublishTableListItem | PublishVersionTableListItem)=>{ - const viewBtn = {openDrawer('view',entity)}} btnTitle="查看详情"/> + const viewBtn = {openDrawer('view',entity)}} btnTitle="查看详情"/> let btnArr:React.ReactNode[] = [] if(pageType !== 'insideSystem' && pageStatus !== 0){ btnArr = [ @@ -281,11 +279,11 @@ const SystemInsidePublicList:FC = ()=>{ if((entity as PublishVersionTableListItem).status === 'accept'){ btnArr = [ - {openDrawer('online',entity)}} btnTitle="上线"/>, + {openDrawer('online',entity)}} btnTitle="上线"/>, , viewBtn, , - {openModal('stop',entity)}} btnTitle="终止发布"/> + {openModal('stop',entity)}} btnTitle="终止发布"/> ] } @@ -294,17 +292,17 @@ const SystemInsidePublicList:FC = ()=>{ btnArr = [ viewBtn, , - {openModal('stop',entity)}} btnTitle="终止发布"/> + {openModal('stop',entity)}} btnTitle="终止发布"/> ] } if((entity as PublishVersionTableListItem).status === 'apply'){ btnArr = [ - {openDrawer('approval',entity)}} btnTitle="审批"/>, + {openDrawer('approval',entity)}} btnTitle="审批"/>, , viewBtn, , - {openModal('cancel',entity)}} btnTitle="撤回申请"/> + {openModal('cancel',entity)}} btnTitle="撤回申请"/> ] } @@ -333,18 +331,18 @@ const SystemInsidePublicList:FC = ()=>{ } if((entity as PublishVersionTableListItem).canDelete){ - btnArr = [...btnArr, btnArr.length > 0 && ,{openModal('delete',entity)}} btnTitle="删除"/> ] + btnArr = [...btnArr, btnArr.length > 0 && ,{openModal('delete',entity)}} btnTitle="删除"/> ] } return btnArr } - const operation:ProColumns[] =[ + const operation:PageProColumns[] =[ { - title: '操作', + title: COLUMNS_TITLE.operate, key: 'option', - width:pageStatus === 0 ? 231 : 93, + btnNums:pageStatus === 0 ? 2 : 1, valueType: 'option', fixed:'right', render: (_: React.ReactNode, entity: PublishTableListItem|PublishVersionTableListItem) => tableOperation(entity) @@ -354,10 +352,10 @@ const SystemInsidePublicList:FC = ()=>{ useEffect(() => { setBreadcrumb([ { - title:服务 + title:{$t('服务')} }, { - title:'发布' + title:$t('发布') } ]) getMemberList() @@ -375,7 +373,7 @@ const SystemInsidePublicList:FC = ()=>{ }) setMemberValueEnum(tmpValueEnum) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } } @@ -438,7 +436,7 @@ const SystemInsidePublicList:FC = ()=>{ current?: number | undefined; keyword?: string | undefined; })=>getSystemPublishList(params)} - addNewBtnTitle={pageStatus === 0 ? "新建版本":''} + addNewBtnTitle={pageStatus === 0 ? $t("新建版本"):''} onAddNewBtnClick={()=>{openDrawer('add')}} addNewBtnAccess="team.service.release.add" onChange={() => { @@ -457,7 +455,7 @@ const SystemInsidePublicList:FC = ()=>{ okBtnTitle={drawerOkTitle} submitDisabled={drawerType === 'add' ? !isOkToPublish : false} submitAccess={`team.service.release.${drawerType === 'publish'? 'add' : drawerType}`} - cancelBtnTitle={drawerType === 'online' ? '关闭' : undefined} + cancelBtnTitle={drawerType === 'online' ? $t('关闭') : undefined} showOkBtn={drawerType !== 'view'} onSubmit={onSubmit} extraBtn={(drawerType === 'approval'||drawerType === 'online') ? @@ -487,7 +485,7 @@ const SystemInsidePublicList:FC = ()=>{ } }} > - {drawerType === 'approval'? "拒绝" : '终止发布'} + {drawerType === 'approval'? $t("拒绝") : $t('终止发布')} :undefined} > diff --git a/frontend/packages/core/src/pages/system/publish/SystemInsidePublishOnline.tsx b/frontend/packages/core/src/pages/system/publish/SystemInsidePublishOnline.tsx index edf50c03..dd9df2ed 100644 --- a/frontend/packages/core/src/pages/system/publish/SystemInsidePublishOnline.tsx +++ b/frontend/packages/core/src/pages/system/publish/SystemInsidePublishOnline.tsx @@ -3,7 +3,7 @@ import { App, Table } from "antd"; import { SYSTEM_PUBLISH_ONLINE_COLUMNS } from "../../../const/system/const"; import { useEffect, useState } from "react"; import { useFetch } from "@common/hooks/http"; -import { BasicResponse, STATUS_CODE } from "@common/const/const"; +import { BasicResponse, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const"; import { EntityItem } from "@common/const/type"; type SystemInsidePublishOnlineProps = { @@ -33,7 +33,7 @@ export default function SystemInsidePublishOnline(props:SystemInsidePublishOnlin setIsStopped(true) } }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> message.error(errorInfo)) } diff --git a/frontend/packages/core/src/pages/system/upstream/SystemInsideUpstreamContent.tsx b/frontend/packages/core/src/pages/system/upstream/SystemInsideUpstreamContent.tsx index b08280d2..4c28c1cf 100644 --- a/frontend/packages/core/src/pages/system/upstream/SystemInsideUpstreamContent.tsx +++ b/frontend/packages/core/src/pages/system/upstream/SystemInsideUpstreamContent.tsx @@ -10,9 +10,10 @@ import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; import { typeOptions, SYSTEM_UPSTREAM_GLOBAL_CONFIG_TABLE_COLUMNS, schemeOptions, balanceOptions, passHostOptions, PROXY_HEADER_CONFIG } from "../../../const/system/const.tsx"; import { Link, useParams } from "react-router-dom"; import { RouterParams } from "@core/components/aoplatform/RenderRoutes.tsx"; -import { BasicResponse, STATUS_CODE } from "@common/const/const.ts"; +import { BasicResponse, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE, VALIDATE_MESSAGE } from "@common/const/const.tsx"; import { useFetch } from "@common/hooks/http.ts"; import { useBreadcrumb } from "@common/contexts/BreadcrumbContext.tsx"; +import { $t } from "@common/locales/index.ts"; const DEFAULT_FORM_VALUE = { driver:'static', @@ -58,11 +59,11 @@ const SystemInsideUpstreamContent= forwardRef }).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) return Promise.resolve(true) }else{ - message.error(msg || '操作失败') - return Promise.reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + return Promise.reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> {return Promise.reject(errorInfo)}) }) @@ -79,7 +80,7 @@ const SystemInsideUpstreamContent= forwardRef setFormShowHost(data.upstream.passHost === 'rewrite') },0) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }).finally(()=>{ setLoading(false) @@ -98,7 +99,7 @@ const globalConfigNodesRule: FormItemProps['rules'] = [ if (filteredValue.length > 0) { return Promise.resolve(); } else { - return Promise.reject(new Error('必填项')); + return Promise.reject(new Error(VALIDATE_MESSAGE.required)); } }, }, @@ -107,10 +108,10 @@ const globalConfigNodesRule: FormItemProps['rules'] = [ useEffect(() => { setBreadcrumb([ { - title: 服务 + title: {$t('服务')} }, { - title: '上游' + title: $t('上游') }]) getUpstreamInfo(); @@ -132,19 +133,19 @@ const globalConfigNodesRule: FormItemProps['rules'] = [ > - label="上游类型" + label={$t("上游类型")} name="driver" - rules={[{ required: true, message: '必填项' }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required }]} > - label="服务地址" + label={$t("服务地址")} name="nodes" - tooltip="后端默认使用的IP地址" - rules={[{ required: true, message: '必填项' }, + tooltip={$t("后端默认使用的IP地址")} + rules={[{ required: true, message: VALIDATE_MESSAGE.required }, ...globalConfigNodesRule]} > @@ -153,68 +154,68 @@ const globalConfigNodesRule: FormItemProps['rules'] = [ - label="请求协议" + label={$t("请求协议")} name="scheme" - rules={[{ required: true, message: '必填项' }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required }]} > - - label="负载均衡" + label={$t("负载均衡")} name="balance" - rules={[{ required: true, message: '必填项' }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required }]} > - label="转发 Host" + label={$t("转发 Host")} name="passHost" - rules={[{ required: true, message: '必填项' }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required }]} > - setFormShowHost(val === 'rewrite')}> {formShowHost && - label="重写域名" + label={$t("重写域名")} name="upstreamHost" - rules={[{ required: true, message: '必填项',whitespace:true }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required,whitespace:true }]} > - + } - label="超时时间" + label={$t("超时时间")} name="timeout" - rules={[{ required: true, message: '必填项' }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required }]} > ms }/> - label="超时重试次数" + label={$t("超时重试次数")} name="retry" - rules={[{ required: true, message: '必填项' }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required }]} > 次} /> - label="调用频率限制" + label={$t("调用频率限制")} name="limitPeerSecond" - rules={[{ required: true, message: '必填项' }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required }]} > 次/秒 } /> - label="转发上游请求头" + label={$t("转发上游请求头")} name="proxyHeaders" className="mb-0" > @@ -227,7 +228,7 @@ const globalConfigNodesRule: FormItemProps['rules'] = [ className="border-none bg-transparent pt-btnrbase mb-0 pb-0" > diff --git a/frontend/packages/core/src/pages/team/TeamConfig.tsx b/frontend/packages/core/src/pages/team/TeamConfig.tsx index 13784150..85a9190a 100644 --- a/frontend/packages/core/src/pages/team/TeamConfig.tsx +++ b/frontend/packages/core/src/pages/team/TeamConfig.tsx @@ -3,7 +3,7 @@ import {App, Button, Form, Input, Row, Select} from "antd"; import {Link, useLocation, useNavigate, useParams} from "react-router-dom"; import {RouterParams} from "@core/components/aoplatform/RenderRoutes.tsx"; import { v4 as uuidv4 } from 'uuid' -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE, VALIDATE_MESSAGE} from "@common/const/const.tsx"; import {MemberItem} from "@common/const/type.ts"; import {useFetch} from "@common/hooks/http.ts"; import {DefaultOptionType} from "antd/es/cascader"; @@ -12,6 +12,7 @@ import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; import { useBreadcrumb } from "@common/contexts/BreadcrumbContext.tsx"; import { useTeamContext } from "../../contexts/TeamContext.tsx"; import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx"; +import { $t } from "@common/locales/index.ts"; export type TeamConfigHandle = { save:()=>Promise|undefined @@ -52,12 +53,12 @@ const TeamConfig= forwardRef((props,ref) => { return fetchData>(pageType === 'manage'?'manager/team' : 'team',{method:onEdit ? 'PUT' : 'POST', eoParams:params,eoBody:(value),eoTransformKeys:['teamId']}).then(response=>{ const {code,data,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) setTeamInfo?.(data.team) return Promise.resolve(true) }else{ - message.error(msg || '操作失败') - return Promise.reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + return Promise.reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=>{ return Promise.reject(errorInfo) @@ -73,7 +74,7 @@ const TeamConfig= forwardRef((props,ref) => { setCanDelete(data.team.canDelete) setTimeout(()=>{form.setFieldsValue({...data.team})},0) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }) }; @@ -87,7 +88,7 @@ const TeamConfig= forwardRef((props,ref) => { label:x.name, value:x.id }}) || []) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }) } @@ -97,13 +98,13 @@ const TeamConfig= forwardRef((props,ref) => { fetchData>(`manager/team`,{method:'DELETE',eoParams:{id:form.getFieldValue('id')}}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) navigateTo('/team/list') resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }) @@ -116,8 +117,8 @@ const TeamConfig= forwardRef((props,ref) => { form.setFieldsValue(entity) }else if (teamId !== undefined) { setBreadcrumb([ - {title:团队}, - {title:'设置'} + {title:{$t('团队')}}, + {title:$t('设置')} ]) setOnEdit(true); getTeamInfo(); @@ -139,63 +140,60 @@ const TeamConfig= forwardRef((props,ref) => { form={form} className={`mx-auto`} name="teamConfig" - // labelCol={{ offset:1, span: 4 }} - // wrapperCol={{ span: 19}} onFinish={onFinish} autoComplete="off" > - label="团队名称" + label={$t("团队名称")} name="name" - rules={[{ required: true, message: '必填项',whitespace:true }]} + rules={[{ required: true, message: VALIDATE_MESSAGE.required,whitespace:true }]} > - + - label="团队 ID" + label={$t("团队 ID")} name="id" - extra="团队 ID(team_id)可用于检索团队,一旦保存无法修改。" - rules={[{ required: true, message: '必填项',whitespace:true }]} + extra={$t("团队 ID(team_id)可用于检索团队,一旦保存无法修改。")} + rules={[{ required: true, message: VALIDATE_MESSAGE.required,whitespace:true }]} > - + {!onEdit && - label="团队负责人" + label={$t("团队负责人")} name="master" - extra="负责人对团队内的团队、服务、成员有管理权限" - rules={[{required: true, message: '必填项'}]} + extra={$t("负责人对团队内的团队、服务、成员有管理权限")} + rules={[{required: true, message: VALIDATE_MESSAGE.required}]} > - } - label="描述" + label={$t("描述")} name="description" > - + { onEdit && } {onEdit &&
-

删除团队:删除操作不可恢复,请谨慎操作!

+

{$t('删除团队')}:{$t('删除操作不可恢复,请谨慎操作!')}

- - + +
diff --git a/frontend/packages/core/src/pages/team/TeamInsideMember.tsx b/frontend/packages/core/src/pages/team/TeamInsideMember.tsx index 00d3e4e9..a24cc76e 100644 --- a/frontend/packages/core/src/pages/team/TeamInsideMember.tsx +++ b/frontend/packages/core/src/pages/team/TeamInsideMember.tsx @@ -1,11 +1,10 @@ -import PageList from "@common/components/aoplatform/PageList.tsx" -import {ActionType, ProColumns} from "@ant-design/pro-components"; +import PageList, { PageProColumns } from "@common/components/aoplatform/PageList.tsx" +import {ActionType} from "@ant-design/pro-components"; import {FC, useEffect, useMemo, useRef, useState} from "react"; import {Link, useParams} from "react-router-dom"; import {useBreadcrumb} from "@common/contexts/BreadcrumbContext.tsx"; import {App, Button, Modal, Select} from "antd"; -import {TransferTableHandle} from "@common/components/aoplatform/TransferTable.tsx"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, COLUMNS_TITLE, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; import {useFetch} from "@common/hooks/http.ts"; import {RouterParams} from "@core/components/aoplatform/RenderRoutes.tsx"; import {EntityItem, MemberItem} from "@common/const/type.ts"; @@ -14,10 +13,11 @@ import { TEAM_MEMBER_TABLE_COLUMNS } from "../../const/team/const.tsx"; import TableBtnWithPermission from "@common/components/aoplatform/TableBtnWithPermission.tsx"; import { checkAccess } from "@common/utils/permission.ts"; import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx"; -import MemberTransfer from "@common/components/aoplatform/MemberTransfer.tsx"; +import MemberTransfer, { TransferTableHandle } from "@common/components/aoplatform/MemberTransfer.tsx"; import { DepartmentListItem } from "../../const/member/type.ts"; import {v4 as uuidv4} from 'uuid' import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; +import { $t } from "@common/locales/index.ts"; export const getDepartmentWithMember = (department:(DepartmentListItem & {type?:'department'|'member'})[],departmentMap:Map) : (DepartmentWithMemberItem | undefined)[] =>{ return department.map((x:DepartmentListItem & {type?:'department'|'member'})=>{ @@ -52,17 +52,17 @@ const TeamInsideMember:FC = ()=>{ const [modalVisible, setModalVisible] = useState(false) const [addMemberBtnDisabled, setAddMemberBtnDisabled] = useState(true) const [allMemberSelectedDepartIds, setAllMemberSelectedDepartIds] = useState([]) - const [columns,setColumns] = useState[]>([]) + const [columns,setColumns] = useState[]>([]) - const operation:ProColumns[] =[ + const operation:PageProColumns[] =[ { - title: '操作', + title: COLUMNS_TITLE.operate, key: 'option', - width: 88, + btnNums:1, fixed:'right', valueType: 'option', render: (_: React.ReactNode, entity: TeamMemberTableListItem) => [ - {openModal('remove',entity)}} btnTitle="移出团队"/>] + {openModal('remove',entity)}} btnTitle="移出团队"/>] } ] @@ -127,7 +127,7 @@ const TeamInsideMember:FC = ()=>{ } return {data:data.members, success: true} }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return {data:[], success:false} } }).catch(() => { @@ -143,13 +143,13 @@ const TeamInsideMember:FC = ()=>{ fetchData>('team/member',{method:'POST' ,eoBody:({users:memberKeyFromModal}),eoParams:{team:teamId}}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) manualReloadTable() cleanModalData() resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)).finally(()=>setAddMemberBtnLoading(false)) }) @@ -161,11 +161,11 @@ const TeamInsideMember:FC = ()=>{ fetchData>(`team/member`,{method:'DELETE',eoParams:{team:teamId,user:entity.user.id}}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }) @@ -185,8 +185,8 @@ const TeamInsideMember:FC = ()=>{ setAddMemberBtnLoading(false) return case 'remove': - title='移除成员' - content=确定删除成员?此操作无法恢复,确认操作? + title=$t('移除成员') + content={$t('确定删除成员?此操作无法恢复,确认操作?')} break } @@ -197,11 +197,11 @@ const TeamInsideMember:FC = ()=>{ return removeMember(entity!).then((res)=>{if(res === true) manualReloadTable()}) }, width:600, - okText:'确认', + okText:$t('确认'), okButtonProps:{ disabled: !checkAccess(`team.team.member.edit`,accessData) }, - cancelText:'取消', + cancelText:$t('取消'), closable:true, icon:<> }) @@ -219,11 +219,11 @@ const TeamInsideMember:FC = ()=>{ fetchData>(`team/member/role`, {method: 'PUT',eoBody:({roles:value, users:[entity.user.id]}), eoParams: {team:teamId}}).then(response => { const {code, msg} = response if (code === STATUS_CODE.SUCCESS) { - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) } else { - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }) @@ -262,7 +262,7 @@ const TeamInsideMember:FC = ()=>{ setColumns(newCol) return } else { - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }) } @@ -271,8 +271,8 @@ const TeamInsideMember:FC = ()=>{ useEffect(() => { getRoleList() setBreadcrumb([ - {title:团队}, - {title:'成员'} + {title:{$t('团队')}}, + {title:$t('成员')} ]) manualReloadTable() }, [teamId]); @@ -287,16 +287,16 @@ const TeamInsideMember:FC = ()=>{ columns = {[...columns,...operation]} request={()=>getMemberList()} primaryKey="user.id" - addNewBtnTitle="添加成员" + addNewBtnTitle={$t('添加成员')} className="ml-[20px] mt-[20px] " - searchPlaceholder="输入姓名查找" + searchPlaceholder={$t("输入姓名查找")} onAddNewBtnClick={()=>{openModal('add')}} addNewBtnAccess="team.team.member.add" tableClickAccess="team.team.member.edit" onSearchWordChange={(e)=>{setSearchWord(e.target.value)}} /> - { maskClosable={false} footer={[ , , ]} > @@ -326,7 +326,7 @@ const TeamInsideMember:FC = ()=>{ const memberKeyFromModal = Array.from(selectedData)?.filter(x => allMemberIds.indexOf(x) === -1 &&selectableMemberIds.has(x)) || []; setAddMemberBtnDisabled((memberKeyFromModal.length === 0)); }} - searchPlaceholder="搜索用户名、邮箱" + searchPlaceholder={$t("搜索用户名、邮箱")} /> diff --git a/frontend/packages/core/src/pages/team/TeamInsidePage.tsx b/frontend/packages/core/src/pages/team/TeamInsidePage.tsx index a95ff213..4e28e3c2 100644 --- a/frontend/packages/core/src/pages/team/TeamInsidePage.tsx +++ b/frontend/packages/core/src/pages/team/TeamInsidePage.tsx @@ -3,7 +3,7 @@ import {FC, useEffect, useMemo, useState} from "react"; import { Outlet, useLocation, useNavigate, useParams} from "react-router-dom"; import {RouterParams} from "@core/components/aoplatform/RenderRoutes.tsx"; import {App, Menu, MenuProps} from "antd"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; import {useFetch} from "@common/hooks/http.ts"; import { TEAM_INSIDE_MENU_ITEMS } from "../../const/team/const.tsx"; import { useTeamContext } from "../../contexts/TeamContext.tsx"; @@ -13,8 +13,8 @@ import Paragraph from "antd/es/typography/Paragraph"; import { MenuItemGroupType, MenuItemType } from "antd/es/menu/hooks/useItems"; import { cloneDeep } from "lodash-es"; import { PERMISSION_DEFINITION } from "@common/const/permissions.ts"; -import { SimpleTeamItem } from "@common/const/type.ts"; import { TeamConfigType } from "@core/const/team/type.ts"; +import { $t } from "@common/locales/index.ts"; const TeamInsidePage:FC = ()=> { const { message } = App.useApp() @@ -61,7 +61,7 @@ const TeamInsidePage:FC = ()=> { if(code === STATUS_CODE.SUCCESS){ setTeamInfo?.(data.team) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } }) } @@ -92,7 +92,7 @@ const TeamInsidePage:FC = ()=> { 团队 ID:{teamId || '-'} + {$t('团队 ID')}:{teamId || '-'} }]} backUrl="/team/list" > diff --git a/frontend/packages/core/src/pages/team/TeamList.tsx b/frontend/packages/core/src/pages/team/TeamList.tsx index 3dcb6793..a5a40d0e 100644 --- a/frontend/packages/core/src/pages/team/TeamList.tsx +++ b/frontend/packages/core/src/pages/team/TeamList.tsx @@ -1,11 +1,11 @@ -import PageList from "@common/components/aoplatform/PageList.tsx" -import {ActionType, ProColumns} from "@ant-design/pro-components"; +import PageList, { PageProColumns } from "@common/components/aoplatform/PageList.tsx" +import {ActionType} from "@ant-design/pro-components"; import {FC, useEffect, useMemo, useRef, useState} from "react"; import {useLocation, useNavigate} from "react-router-dom"; import {useBreadcrumb} from "@common/contexts/BreadcrumbContext.tsx"; import {App, Divider, Modal} from "antd"; -import {BasicResponse, STATUS_CODE} from "@common/const/const.ts"; +import {BasicResponse, COLUMNS_TITLE, DELETE_TIPS, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; import { SimpleMemberItem } from "@common/const/type.ts"; import {useFetch} from "@common/hooks/http.ts"; import { TEAM_TABLE_COLUMNS } from "../../const/team/const.tsx"; @@ -15,6 +15,7 @@ import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx"; import { checkAccess } from "@common/utils/permission.ts"; import TeamConfig from "./TeamConfig.tsx"; import InsidePage from "@common/components/aoplatform/InsidePage.tsx"; +import { $t } from "@common/locales/index.ts"; const TeamList:FC = ()=>{ const [searchWord, setSearchWord] = useState('') @@ -38,7 +39,7 @@ const TeamList:FC = ()=>{ if(code === STATUS_CODE.SUCCESS){ return {data:data.teams, success: true} }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return {data:[], success:false} } }).catch(() => { @@ -51,11 +52,11 @@ const TeamList:FC = ()=>{ fetchData>(`manager/team`,{method:'DELETE',eoParams:{id:entity.id}}).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) resolve(true) }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) + reject(msg || RESPONSE_TIPS.error) } }).catch((errorInfo)=> reject(errorInfo)) }) @@ -71,7 +72,7 @@ const TeamList:FC = ()=>{ }) setMemberValueEnum(tmpValueEnum) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } } @@ -89,21 +90,21 @@ const TeamList:FC = ()=>{ setModalVisible(true) return;} case 'edit':{ - message.loading('正在加载数据') + message.loading(RESPONSE_TIPS.loading) const {code,data,msg} = await fetchData>(`manager/team`,{method:'GET',eoParams:{id:entity!.id}}) message.destroy() if(code === STATUS_CODE.SUCCESS){ setCurTeam({...data.team,master:data.team.master.id}) setModalVisible(true) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) return } setModalType('edit') return;} case 'delete': - title='删除' - content='该数据删除后将无法找回,请确认是否删除?' + title=$t('删除') + content=DELETE_TIPS.default break; } @@ -117,34 +118,34 @@ const TeamList:FC = ()=>{ } }, width:600, - okText:'确认', + okText:$t('确认'), okButtonProps:{ disabled : !checkAccess( `system.organization.team.${type}`, accessData) }, - cancelText:'取消', + cancelText:$t('取消'), closable:true, icon:<>, }) } - const operation:ProColumns[] =[ + const operation:PageProColumns[] =[ { - title: '操作', + title: COLUMNS_TITLE.operate, key: 'option', fixed:'right', - width: 96, + btnNums:2, valueType: 'option', render: (_: React.ReactNode, entity: TeamTableListItem) => [ - , + , , - {openModal('delete',entity)}} btnTitle="删除"/>, + {openModal('delete',entity)}} btnTitle="删除"/>, ], } ] useEffect(() => { setBreadcrumb([ - {title: '团队'} + {title: $t('团队')} ]) manualReloadTable() }, [currentUrl]); @@ -160,8 +161,8 @@ const TeamList:FC = ()=>{ return ( @@ -172,15 +173,15 @@ const TeamList:FC = ()=>{ columns = {[...columns,...operation]} request = {()=>getTeamList()} showPagination={false} - addNewBtnTitle='添加团队' + addNewBtnTitle={$t('添加团队')} addNewBtnAccess = "system.organization.team.add" - searchPlaceholder="输入名称、ID、负责人查找团队" + searchPlaceholder={$t("输入名称、ID、负责人查找团队")} onAddNewBtnClick={()=>{openModal('add')}} onSearchWordChange={(e)=>{setSearchWord(e.target.value)}} onRowClick={(row:TeamTableListItem)=>(navigate(`../inside/${row.id}/setting`))} /> { } }} onCancel={() => {setModalVisible(false)}} - okText="确认" + okText={$t("确认")} okButtonProps={{disabled : !checkAccess( `system.organization.team.edit`, accessData)}} - cancelText='取消' + cancelText={$t('取消')} closable={true} onOk={()=>teamConfigRef.current?.save().then((res)=>{ if(res){ diff --git a/frontend/packages/core/src/pages/userProfile/ChangePsw.tsx b/frontend/packages/core/src/pages/userProfile/ChangePsw.tsx index 389ef969..9746d501 100644 --- a/frontend/packages/core/src/pages/userProfile/ChangePsw.tsx +++ b/frontend/packages/core/src/pages/userProfile/ChangePsw.tsx @@ -1,8 +1,9 @@ import { App, Button, Form, Input } from "antd"; import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; -import { BasicResponse, STATUS_CODE } from "@common/const/const.ts"; +import { BasicResponse, RESPONSE_TIPS, STATUS_CODE, VALIDATE_MESSAGE } from "@common/const/const"; import { useFetch } from "@common/hooks/http.ts"; +import { $t } from "@common/locales"; const ChangePsw= () => { const { message } = App.useApp() @@ -20,9 +21,9 @@ const ChangePsw= () => { }).then(response=>{ const {code,msg} = response if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') + message.success(msg || RESPONSE_TIPS.success) }else{ - message.error(msg || '操作失败') + message.error(msg || RESPONSE_TIPS.error) } form.resetFields() }).catch((errorInfo)=> {console.warn(errorInfo)}) @@ -46,11 +47,11 @@ const ChangePsw= () => { @@ -58,11 +59,11 @@ const ChangePsw= () => { @@ -71,19 +72,19 @@ const ChangePsw= () => { ({ validator(_, value) { if (!value || getFieldValue('new_password') === value) { return Promise.resolve(); } - return Promise.reject(new Error('两次密码不一致')); + return Promise.reject(new Error($t('两次密码不一致'))); }, }), ]} @@ -95,7 +96,7 @@ const ChangePsw= () => { className="border-none bg-transparent pt-btnrbase mb-0 pb-0 pl-0" > diff --git a/frontend/packages/core/src/pages/userProfile/UserProfile.tsx b/frontend/packages/core/src/pages/userProfile/UserProfile.tsx index a9755369..07025e00 100644 --- a/frontend/packages/core/src/pages/userProfile/UserProfile.tsx +++ b/frontend/packages/core/src/pages/userProfile/UserProfile.tsx @@ -5,6 +5,7 @@ import {RouterParams} from "@core/components/aoplatform/RenderRoutes.tsx"; import { Menu} from "antd"; import InsidePage from "@common/components/aoplatform/InsidePage.tsx"; import { getItem } from "@common/utils/navigation.tsx"; +import { $t } from "@common/locales"; const UserProfile:FC = ()=> { const {teamId} = useParams(); @@ -14,7 +15,7 @@ const UserProfile:FC = ()=> { const menuData = [ - getItem(修改密码, 'changepsw')] + getItem({$t('修改密码')}, 'changepsw')] useEffect(() => { @@ -33,8 +34,8 @@ const UserProfile:FC = ()=> { return ( <>
[] = [ - { - title: 'Webhook 名称', - dataIndex: 'title', - ellipsis:true, - width:120, - fixed:'left' - }, - { - title: '通知 Url', - dataIndex: 'url', - ellipsis:true - }, - { - title: '请求方式', - dataIndex: 'method', - ellipsis:true - }, - { - title: '参数类型', - dataIndex: 'contentType' - }, - { - title: '更新者', - dataIndex: ['operator','name'], - ellipsis: true, - filters: true, - onFilter: true, - valueType: 'select', - filterSearch: true - }, - { - title: '更新时间', - dataIndex: 'updateTime', - ellipsis:true, - width:182, - }, -]; - - - -const methodsList:DefaultOptionType[] = [ - { label: 'POST', value: 'POST' }, - { label: 'GET', value: 'GET' } -] - -const contentTypesList: DefaultOptionType[] = [ - { label: 'JSON', value: 'JSON' }, - { label: 'form-data', value: 'form-data' } -] - -const noticeTypesList: DefaultOptionType[] = [ - { label: '单次发送', value: 'single' }, - { label: '多次发送', value: 'many' }] - - -type WebhookConfigProps = { - type:'add'|'edit' - entity?:WebhookFieldType -} - -type WebhookConfigHandle = { - save:()=>Promise -} - -type WebhookFieldType = { - uuid?:string - title:string - desc:string - url:string - method:string - contentType:string - noticeType:string - userSeparator?:string - header:Map | {[key:string]:string} - template:string -}; - -const WebhookConfig = forwardRef((props,ref)=>{ - const { message } = App.useApp() - const {type,entity} = props - const {fetchData} = useFetch() - const [form] = Form.useForm(); - const [noticeType,setNoticeType] = useState('') - - const save:()=>Promise = ()=>{ - return new Promise((resolve, reject)=>{ - form.validateFields().then((value)=>{ - fetchData>('webhook',{method:type === 'add'? 'POST' : 'PUT',eoBody:({...value,header:transferToMap(value.header)}),eoTransformKeys:['contentType','noticeType','userSeparator']}).then(response=>{ - const {code,msg} = response - if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') - resolve(true) - }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') - } - }).catch((errorInfo)=> reject(errorInfo)) - }).catch((errorInfo)=> reject(errorInfo)) - }) - } - - useImperativeHandle(ref, ()=>({ - save - }) - ) - - useEffect(() => { - if(type === 'edit' && entity){ - //console.log(entity) - form.setFieldsValue({...entity,header:transferToList(entity.header) || []}) - } - }, []); - - return ( -
- - label="模板名称" - name="title" - rules={[{ required: true, message: '必填项',whitespace:true },{pattern:new RegExp('^[\u4E00-\u9FA5A-Za-z]+$'),message:'仅支持中英文'}]} - > - - - - - - - - - - - - - - - - - - - - - - - - {noticeType === 'single' && - - - - } - - - - - - - - -
) -}) - -export default function Webhook(){ - // const [searchWord, setSearchWord] = useState('') - // const navigate = useNavigate(); - const { setBreadcrumb } = useBreadcrumb() - // const [teamPageType,setTeamPageType]=useState( '') - const { modal,message } = App.useApp() - // const [confirmLoading, setConfirmLoading] = useState(false); - const {fetchData} = useFetch() - const [memberValueEnum, setMemberValueEnum] = useState<{[k:string]:{text:string}}>({}) - - const pageListRef = useRef(null); - const addRef = useRef(null) - const editRef = useRef(null) - const {accessData} = useGlobalContext() - - - const getWebhookList = ()=>{ - return fetchData>('webhooks',{method:'GET',eoTransformKeys:['content_type','create_time','is_delete','update_time']}).then(response=>{ - const {code,data,msg} = response - if(code === STATUS_CODE.SUCCESS){ - return {data:data.webhooks, success: true} - }else{ - message.error(msg || '操作失败') - return {data:[], success:false} - } - }).catch(() => { - return {data:[], success:false} - }) - } - - - const manualReloadTable = () => { - pageListRef.current?.reload() - }; - - - const deleteWebhook = (entity:WebhookTableListItem)=>{ - return new Promise((resolve, reject)=>{ - fetchData>('webhook',{method:'DELETE',eoParams:{uuid:entity!.uuid}}).then(response=>{ - const {code,msg} = response - if(code === STATUS_CODE.SUCCESS){ - message.success(msg || '操作成功!') - resolve(true) - }else{ - message.error(msg || '操作失败') - reject(msg || '操作失败') - } - }).catch((errorInfo)=> reject(errorInfo)) - }) - } - - const openModal = async (type:'add'|'edit'|'delete',entity?:WebhookTableListItem)=>{ - //console.log(type,entity) - let title:string = '' - let content:string | React.ReactNode= '' - switch (type){ - case 'add': - title='编辑 Webhook' - content= - break; - case 'edit':{ - title='编辑 Webhook' - message.loading('正在加载数据') - const {code,data,msg} = await fetchData>('webhook',{method:'GET',eoParams:{uuid:entity!.uuid},eoTransformKeys:['content_type','notice_type','user_separator']}) - message.destroy() - //console.log(data) - if(code === STATUS_CODE.SUCCESS){ - content= - }else{ - message.error(msg || '操作失败') - return - } - break;} - case 'delete': - title='删除' - content='该数据删除后将无法找回,请确认是否删除?' - break; - } - - modal.confirm({ - title, - content, - onOk:()=>{ - switch (type){ - case 'add': - return addRef.current?.save().then((res)=>{if(res === true) manualReloadTable()}) - case 'edit': - return editRef.current?.save().then((res)=>{if(res === true) manualReloadTable()}) - case 'delete': - return deleteWebhook(entity!).then((res)=>{if(res === true) manualReloadTable()}) - } - }, - width:900, - okText:'确认', - okButtonProps:{ - disabled : !checkAccess(`system.webhook.self.${type}` as (keyof typeof PERMISSION_DEFINITION[0]), accessData) - }, - cancelText:'取消', - closable:true, - icon:<>, - }) - } - - const operation:ProColumns[] =[ - { - title: '操作', - key: 'option', - width: 93, - valueType: 'option', - render: (_: React.ReactNode, entity: WebhookTableListItem) => - [{openModal('edit',entity)}} btnTitle="查看"/>, - , - {openModal('delete',entity)}} btnTitle="删除"/>] - } - ] - - - const getMemberList = async ()=>{ - setMemberValueEnum({}) - const {code,data,msg} = await fetchData>('simple/member',{method:'GET'}) - if(code === STATUS_CODE.SUCCESS){ - const tmpValueEnum:{[k:string]:{text:string}} = {} - data.members?.forEach((x:SimpleMemberItem)=>{ - tmpValueEnum[x.name] = {text:x.name} - }) - setMemberValueEnum(tmpValueEnum) - }else{ - message.error(msg || '操作失败') - } - } - - useEffect(() => { - setBreadcrumb([ - {title:'Webhook 管理'} - ]) - getMemberList() - }, []); - - - const columns = useMemo(()=>{ - return WEBHOOK_TABLE_COLUMNS.map(x=>{if(x.filters &&((x.dataIndex as string[])?.indexOf('updater') !== -1) ){x.valueEnum = memberValueEnum} return x}) - },[memberValueEnum]) - - return ( - getWebhookList()} - primaryKey="uuid" - showPagination={false} - addNewBtnTitle="添加 Webhook" - onAddNewBtnClick={()=>{openModal('add')}} - onRowClick={(row:WebhookTableListItem)=>openModal('edit',row)} - /> - ) - -} \ No newline at end of file diff --git a/frontend/packages/core/tsconfig.json b/frontend/packages/core/tsconfig.json index d5e906d2..32fcee3b 100644 --- a/frontend/packages/core/tsconfig.json +++ b/frontend/packages/core/tsconfig.json @@ -25,6 +25,6 @@ "@market/*": ["../market/src/*"], }, }, - "include": ["src", "public/iconpark_eolink.js", "public/iconpark_apinto.js", "../common/src/component/aoplatform/EditableTableWithModal.tsx", "../common/src/components/aoplatform/TransferTable.tsx", "../common/src/components/aoplatform/TreeWithMore.tsx", "../common/src/components/aoplatform/DatePicker.tsx", "../common/src/components/aoplatform/TimeRangeSelector.tsx", "../common/src/components/aoplatform/TimePicker.tsx", "../common/src/components/aoplatform/MemberTransfer.tsx", "../common/src/components/aoplatform/Navigation.tsx", "../common/src/components/aoplatform/PageList.tsx", "../common/src/components/aoplatform/GroupTree.tsx", "../common/src/components/aoplatform/ErrorBoundary.tsx", "../common/src/components/aoplatform/ScrollableSection.tsx", "../common/src/utils/postcat.tsx", "../common/src/utils/curl.ts", "../common/src/components/aoplatform/ResetPsw.tsx", "../common/src/components/aoplatform/SubscribeApprovalModalContent.tsx", "src/components/aoplatform/RenderRoutes.tsx", "../common/src/components/aoplatform/PublishApprovalModalContent.tsx", "../common/src/components/aoplatform/InsidePage.tsx", "../common/src/const/type.ts", "../common/src/components/aoplatform/intelligent-plugin", "../common/src/const/domain"], + "include": ["src", "public/iconpark_eolink.js", "public/iconpark_apinto.js", "../common/src/component/aoplatform/EditableTableWithModal.tsx", "../common/src/components/aoplatform/TreeWithMore.tsx", "../common/src/components/aoplatform/DatePicker.tsx", "../common/src/components/aoplatform/TimeRangeSelector.tsx", "../common/src/components/aoplatform/TimePicker.tsx", "../common/src/components/aoplatform/MemberTransfer.tsx", "../common/src/components/aoplatform/PageList.tsx", "../common/src/components/aoplatform/ErrorBoundary.tsx", "../common/src/components/aoplatform/ScrollableSection.tsx", "../common/src/utils/postcat.tsx", "../common/src/utils/curl.ts", "../common/src/components/aoplatform/ResetPsw.tsx", "../common/src/components/aoplatform/SubscribeApprovalModalContent.tsx", "../common/src/components/aoplatform/InsidePageForHub.tsx", "src/components/aoplatform/RenderRoutes.tsx", "../common/src/components/aoplatform/PublishApprovalModalContent.tsx", "../common/src/components/aoplatform/InsidePage.tsx", "../common/src/const/type.ts", "../common/src/components/aoplatform/intelligent-plugin", "../common/src/const/domain"], "references": [{ "path": "./tsconfig.node.json" }] }