mirror of
https://github.com/APIParkLab/APIPark.git
synced 2026-06-14 20:41:15 +08:00
feat:多语言
This commit is contained in:
@@ -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();
|
||||
}
|
||||
};
|
||||
@@ -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",
|
||||
|
||||
@@ -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<MenuProps>['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',<Icon icon="ic:baseline-space-dashboard" width="18" height="18"/>, [
|
||||
getNavItem($t('我的'), 'my','/tenantManagement',null,[
|
||||
getNavItem(<a>{$t('应用')}</a>, 'tenantManagement','/tenantManagement',<Icon icon="ic:baseline-apps" width="18" height="18"/>,undefined,undefined,''),
|
||||
getNavItem(<a>{$t('服务')}</a>, 'service','/service',<Icon icon="ic:baseline-blinds-closed" width="18" height="18"/>,undefined,undefined,''),
|
||||
getNavItem(<a>{$t('团队')}</a>, 'team','/team',<Icon icon="ic:baseline-people-alt" width="18" height="18"/>,undefined,undefined,''),
|
||||
],undefined,''),
|
||||
getNavItem(<a>{$t('API 市场')}</a>, 'serviceHub','/serviceHub',<Icon icon="ic:baseline-hub" width="18" height="18"/>,undefined,undefined,'system.workspace.api_market.view'),
|
||||
]),
|
||||
|
||||
APP_MODE === 'pro' ? getNavItem($t('仪表盘'), 'mainPage', '/dashboard',<Icon icon="ic:baseline-bar-chart" width="18" height="18"/>,[
|
||||
getNavItem(<a >{$t('运行视图')}</a>, 'dashboard','/dashboard',<ProjectFilled />,undefined,undefined,''),
|
||||
getNavItem(<a >{$t('系统拓扑图')}</a>, 'systemrunning','/systemrunning',<ProjectFilled />,undefined,undefined,''),
|
||||
]):null,
|
||||
|
||||
getNavItem($t('系统设置'), 'operationCenter','/member',<Icon icon="ic:baseline-settings" width="18" height="18"/>, [
|
||||
getNavItem($t('组织'), 'organization','/member',null,[
|
||||
getNavItem(<a>{$t('成员')}</a>, 'member','/member',<Icon icon="ic:baseline-people-alt" width="18" height="18"/>,undefined,undefined,'system.organization.member.view'),
|
||||
getNavItem(<a>{$t('角色')}</a>, 'role','/role',<Icon icon="ic:baseline-verified-user" width="18" height="18"/>,undefined,undefined,'system.organization.role.view'),
|
||||
],undefined,''),
|
||||
getNavItem($t('API 市场'), 'serviceHubSetting','/servicecategories',null,[
|
||||
getNavItem(<a>{$t('服务分类管理')}</a>, 'servicecategories','/servicecategories',<Icon icon="ic:baseline-hub" width="18" height="18"/>,undefined,undefined,'system.api_market.service_classification.view'),
|
||||
],undefined,'system.api_market.service_classification.view'),
|
||||
|
||||
getNavItem($t('运维与集成'), 'maintenanceCenter','/cluster', null, [
|
||||
getNavItem(<a>{$t('集群')}</a>, 'cluster','/cluster',<Icon icon="ic:baseline-device-hub" width="18" height="18"/>,undefined,undefined,'system.devops.cluster.view'),
|
||||
getNavItem(<a>{$t('证书')}</a>, 'cert','/cert',<Icon icon="ic:baseline-security" width="18" height="18"/>,undefined,undefined,'system.devops.ssl_certificate.view'),
|
||||
getNavItem(<a>{$t('日志')}</a>, 'logsettings','/logsettings',<Icon icon="ic:baseline-sticky-note-2" width="18" height="18"/>,undefined,undefined,'system.devops.log_configuration.view'),
|
||||
APP_MODE === 'pro' ? getNavItem(<a>{$t('资源')}</a>, 'resourcesettings','/resourcesettings',null,undefined,undefined,'system.partition.self.view'):null,
|
||||
APP_MODE === 'pro' ? getNavItem(<a>{$t('Open API')}</a>, '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<UserInfoType>()
|
||||
const resetPswRef = useRef<ResetPswHandle>(null)
|
||||
const userProfileRef = useRef<UserProfileHandle>(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: (
|
||||
<Button key="changePsw" type="text" className="border-none p-0 flex items-center bg-transparent " onClick={()=>navigator('/userProfile/changepsw')}>
|
||||
账号设置
|
||||
{$t('账号设置')}
|
||||
</Button>)
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
label: (
|
||||
<Button key="logout" type="text" className="border-none p-0 flex items-center bg-transparent " onClick={logOut}>
|
||||
退出登录
|
||||
{$t('退出登录')}
|
||||
</Button>)
|
||||
},
|
||||
];
|
||||
|
||||
const openModal = (type:'userSetting'|'resetPsw')=>{
|
||||
let title:string = ''
|
||||
let content:string|React.ReactNode = ''
|
||||
switch (type){
|
||||
case 'userSetting':
|
||||
title='用户设置'
|
||||
content=<UserProfile ref={userProfileRef} entity={userInfo}/>
|
||||
break;
|
||||
case 'resetPsw':
|
||||
title='重置密码'
|
||||
content=<ResetPsw ref={resetPswRef} entity={userInfo} />
|
||||
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(
|
||||
<div
|
||||
@@ -182,97 +191,98 @@ const themeToken = {
|
||||
}}
|
||||
>
|
||||
<ProConfigProvider hashed={false}>
|
||||
<ConfigProvider
|
||||
getTargetContainer={() => {
|
||||
return document.getElementById('test-pro-layout') || document.body;
|
||||
}}
|
||||
>
|
||||
<ProLayout
|
||||
prefixCls="apipark-layout"
|
||||
location={{
|
||||
pathname,
|
||||
}}
|
||||
siderWidth={220}
|
||||
breakpoint={'lg'}
|
||||
route={headerMenuData}
|
||||
token={themeToken}
|
||||
siderMenuType="group"
|
||||
menu={{
|
||||
type: 'group',
|
||||
collapsedShowGroupTitle: true,
|
||||
}}
|
||||
disableMobile={true}
|
||||
avatarProps={{
|
||||
src: AvatarPic || userInfo?.avatar,
|
||||
size: 'small',
|
||||
title: userInfo?.username||'unknown',
|
||||
render: (props, dom) => {
|
||||
return (
|
||||
<Dropdown
|
||||
menu={{
|
||||
items
|
||||
}}
|
||||
>
|
||||
<div className='avatar-dom'>{dom}
|
||||
</div>
|
||||
</Dropdown>
|
||||
);
|
||||
},
|
||||
}}
|
||||
actionsRender={(props) => {
|
||||
if (props.isMobile) return [];
|
||||
if (typeof window === 'undefined') return [];
|
||||
return [
|
||||
<Button className=" text-[#ffffffb3] hover:text-[#fff] border-none" type="default" ghost onClick={()=>{window.open('https://docs.apipark.com','_blank')}}>
|
||||
<span className='flex items-center gap-[8px]'> <Icon icon="ic:baseline-help" width="14" height="14"/>文档</span>
|
||||
</Button>
|
||||
];
|
||||
}}
|
||||
headerTitleRender={() => (
|
||||
<div className="w-[192px] flex items-center">
|
||||
<img
|
||||
className="h-[20px] cursor-pointer "
|
||||
src={Logo}
|
||||
onClick={()=> navigator(mainPage)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
logo={Logo}
|
||||
pageTitleRender={()=>'APIPark - 企业API数据开放平台'}
|
||||
menuFooterRender={(props) => {
|
||||
if (props?.collapsed) return undefined;
|
||||
}}
|
||||
menuItemRender={(item, dom) => (
|
||||
<div
|
||||
onClick={() => {
|
||||
// 同级目录点击无效
|
||||
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 || '');
|
||||
<ConfigProvider
|
||||
getTargetContainer={() => {
|
||||
return document.getElementById('test-pro-layout') || document.body;
|
||||
}}
|
||||
>
|
||||
{dom}
|
||||
</div>
|
||||
)}
|
||||
fixSiderbar={true}
|
||||
layout='mix'
|
||||
splitMenus={true}
|
||||
collapsed={false}
|
||||
collapsedButtonRender={false}
|
||||
>
|
||||
<div className={`w-full h-calc-100vh-minus-navbar pl-PAGE_INSIDE_X pt-PAGE_INSIDE_T ${currentUrl.startsWith('/role/list') ? 'overflow-auto' : 'overflow-hidden' }`}>
|
||||
<Outlet />
|
||||
</div>
|
||||
</ProLayout>
|
||||
</ConfigProvider>
|
||||
<ProLayout
|
||||
prefixCls="apipark-layout"
|
||||
location={{
|
||||
pathname,
|
||||
}}
|
||||
siderWidth={220}
|
||||
breakpoint={'lg'}
|
||||
route={headerMenuData}
|
||||
token={themeToken}
|
||||
siderMenuType="group"
|
||||
menu={{
|
||||
type: 'group',
|
||||
collapsedShowGroupTitle: true,
|
||||
}}
|
||||
disableMobile={true}
|
||||
avatarProps={{
|
||||
src: AvatarPic || userInfo?.avatar,
|
||||
size: 'small',
|
||||
title: userInfo?.username||'unknown',
|
||||
render: (props, dom) => {
|
||||
return (
|
||||
<Dropdown
|
||||
menu={{
|
||||
items
|
||||
}}
|
||||
>
|
||||
<div className='avatar-dom'>{dom}
|
||||
</div>
|
||||
</Dropdown>
|
||||
);
|
||||
},
|
||||
}}
|
||||
actionsRender={(props) => {
|
||||
if (props.isMobile) return [];
|
||||
if (typeof window === 'undefined') return [];
|
||||
return [
|
||||
<LanguageSetting />,
|
||||
<Button className=" text-[#ffffffb3] hover:text-[#fff] border-none" type="default" ghost onClick={()=>{window.open('https://docs.apipark.com','_blank')}}>
|
||||
<span className='flex items-center gap-[8px]'> <Icon icon="ic:baseline-help" width="14" height="14"/>{$t('文档')}</span>
|
||||
</Button>
|
||||
];
|
||||
}}
|
||||
headerTitleRender={() => (
|
||||
<div className="w-[192px] flex items-center">
|
||||
<img
|
||||
className="h-[20px] cursor-pointer "
|
||||
src={Logo}
|
||||
onClick={()=> navigator(mainPage)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
logo={Logo}
|
||||
pageTitleRender={()=>$t('APIPark - 企业API数据开放平台')}
|
||||
menuFooterRender={(props) => {
|
||||
if (props?.collapsed) return undefined;
|
||||
}}
|
||||
menuItemRender={(item, dom) => (
|
||||
<div
|
||||
onClick={() => {
|
||||
// 同级目录点击无效
|
||||
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}
|
||||
</div>
|
||||
)}
|
||||
fixSiderbar={true}
|
||||
layout='mix'
|
||||
splitMenus={true}
|
||||
collapsed={false}
|
||||
collapsedButtonRender={false}
|
||||
>
|
||||
<div className={`w-full h-calc-100vh-minus-navbar pl-PAGE_INSIDE_X pt-PAGE_INSIDE_T ${currentUrl.startsWith('/role/list') ? 'overflow-auto' : 'overflow-hidden' }`}>
|
||||
<Outlet />
|
||||
</div>
|
||||
</ProLayout>
|
||||
</ConfigProvider>
|
||||
</ProConfigProvider>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -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<DataType> = [
|
||||
{
|
||||
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
|
||||
|
||||
@@ -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<Moment>(momentGenerateConfig);
|
||||
|
||||
export default MyDatePicker;
|
||||
@@ -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<boolean|string>|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<boolean>(false)
|
||||
const handlerSubmit = ()=>{
|
||||
setSubmitLoading(true)
|
||||
@@ -41,12 +42,12 @@ export function DrawerWithFooter(props:DrawerWithFooterProps){
|
||||
<Space className="flex flex-row-reverse" style={{}}>
|
||||
{showOkBtn && <WithPermission access={submitAccess}>
|
||||
<Button onClick={handlerSubmit} type="primary" loading={submitLoading} disabled={submitDisabled}>
|
||||
{okBtnTitle}
|
||||
{ okBtnTitle}
|
||||
</Button>
|
||||
</WithPermission>}
|
||||
{ showLastStep && <Button onClick={onLastStep ?? onClose}>上一步</Button>}
|
||||
{ showLastStep && <Button onClick={onLastStep ?? onClose}> { $t('上一步')}</Button>}
|
||||
{ extraBtn }
|
||||
<Button onClick={onClose}>{cancelBtnTitle ?? (showOkBtn ? '取消':'关闭')}</Button>
|
||||
<Button onClick={onClose}>{cancelBtnTitle ?? (showOkBtn ? $t('取消'):$t('关闭'))}</Button>
|
||||
</Space>
|
||||
}
|
||||
onClose={onClose}
|
||||
|
||||
@@ -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<T> {
|
||||
configFields: ProColumns<T>[];
|
||||
configFields: PageProColumns<T>[];
|
||||
value?: T[]; // 外部传入的值
|
||||
className?: string;
|
||||
onChange?: (newConfigItems: T[]) => void; // 当配置项变化时,外部传入的回调函数
|
||||
@@ -54,43 +57,36 @@ const EditableTable = <T extends { _id: string }>({
|
||||
editableKeys:disabled ? [] : configurations?.map(x=>x._id),
|
||||
actionRender: (row, config) => {
|
||||
return [
|
||||
<WithPermission access="" key="addPermission" ><Button type="text" className="h-[22px] border-none p-0 flex items-center bg-transparent "
|
||||
key="add"
|
||||
onClick={() => {
|
||||
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]))
|
||||
}}
|
||||
>
|
||||
增加
|
||||
</Button></WithPermission>,
|
||||
(config.index !== configurations.length - 1 )&& <WithPermission access=""><Button type="text" className="h-[22px] border-none p-0 flex items-center bg-transparent "
|
||||
key="edit"
|
||||
onClick={() => {
|
||||
setConfigurations((prev)=>{
|
||||
const tmpPreData = [...prev];
|
||||
tmpPreData.splice(Number(config.index), 1);
|
||||
onChange?.(tmpPreData);
|
||||
return tmpPreData});
|
||||
setEditableRowKeys((prev)=>(prev.filter(x=>x !== config._id)))
|
||||
}}
|
||||
>
|
||||
删除
|
||||
</Button></WithPermission>,
|
||||
<TableBtnWithPermission key="add" btnType="add" onClick={() => {
|
||||
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 )&& <TableBtnWithPermission key="delete" btnType="delete" btnTitle="删除"
|
||||
onClick={() => {
|
||||
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) => {
|
||||
|
||||
@@ -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<T> {
|
||||
title: string;
|
||||
@@ -90,9 +92,9 @@ const EditableTableWithModal = <T extends { _id?: string }>({
|
||||
}));
|
||||
|
||||
!disabled && columns.push({
|
||||
title: '操作',
|
||||
title: COLUMNS_TITLE.operate,
|
||||
key: 'action',
|
||||
width:117,
|
||||
btnNums:2,
|
||||
render: (_: unknown, record: T) => (
|
||||
<>
|
||||
<div className="flex items-center">
|
||||
@@ -109,7 +111,7 @@ const EditableTableWithModal = <T extends { _id?: string }>({
|
||||
<Form.Item
|
||||
label={title as string}
|
||||
name={key as string}
|
||||
rules={[{ required, message: `必填项`}]}
|
||||
rules={[{ required, message: VALIDATE_MESSAGE.required}]}
|
||||
>
|
||||
{component}
|
||||
</Form.Item>
|
||||
@@ -119,12 +121,12 @@ const EditableTableWithModal = <T extends { _id?: string }>({
|
||||
|
||||
return (
|
||||
<>
|
||||
{!disabled && <Button className="" disabled={disabled} onClick={() => showModal()}>添加配置</Button>}
|
||||
{!disabled && <Button className="" disabled={disabled} onClick={() => showModal()}>{$t('添加配置')}</Button>}
|
||||
{configurations.length > 0 &&
|
||||
<Table
|
||||
className={`mt-btnybase border-solid border-[1px] border-BORDER border-b-0 rounded ${className}`} {...tableProps} dataSource={configurations} size="small" columns={columns} rowKey="_id" pagination={false}/>}
|
||||
<Modal
|
||||
title={editingConfig ? '编辑配置' : '添加配置'}
|
||||
title={editingConfig ? $t('编辑配置') : $t('添加配置')}
|
||||
open={isModalVisible}
|
||||
onOk={handleOk}
|
||||
onCancel={handleCancel}
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
|
||||
import DirectoryTree from "antd/es/tree/DirectoryTree";
|
||||
import { DataNode, DirectoryTreeProps } from "antd/lib/tree";
|
||||
import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
|
||||
import TreeWithMore from "@common/components/aoplatform/TreeWithMore";
|
||||
import { SearchOutlined } from "@ant-design/icons";
|
||||
import { Input, Button, MenuProps } from "antd";
|
||||
import { debounce } from "lodash-es";
|
||||
import WithPermission from "@common/components/aoplatform/WithPermission";
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
type T = unknown
|
||||
|
||||
export interface GroupTreeProps extends DirectoryTreeProps{
|
||||
groupData?:(DataNode & T )[]
|
||||
addBtnName?:React.ReactNode
|
||||
addBtnAccess?:string
|
||||
treeNameSuffixKey?:string
|
||||
dropdownMenu?:(data:(DataNode & T )) => MenuProps['items']
|
||||
withMore?:boolean
|
||||
onEditGroup:(type:'rename'|'addChild'|'addPeer', entity:DataNode & T, val:string) => Promise<boolean>|undefined
|
||||
placeholder?:string
|
||||
}
|
||||
|
||||
export interface GroupTreeHandle {
|
||||
startEdit:(id:string)=>void;
|
||||
startAdd:(type:'peer',entity?:DataNode & T)=>void
|
||||
}
|
||||
|
||||
const GroupTree = forwardRef<GroupTreeHandle,GroupTreeProps>((props, ref)=>{
|
||||
const {groupData,selectedKeys,onSelect,addBtnName,addBtnAccess,treeNameSuffixKey,dropdownMenu,onEditGroup,placeholder="输入以搜索"} = props
|
||||
const [treeData, setTreeData] = useState<DataNode[]>([])
|
||||
const [searchWord, setSearchWord] = useState<string>('')
|
||||
const [editingId, setEditingId] = useState<string>('')
|
||||
const [addStatus, setAddStatus] = useState<boolean>(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 ? (
|
||||
<span >
|
||||
{beforeStr}
|
||||
<span className="text-theme">{searchWord}</span>
|
||||
{afterStr} {treeNameSuffixKey && <span>({item?.[treeNameSuffixKey as keyof DataNode] as string ?? 0})</span>}
|
||||
</span>) : (
|
||||
<span className='w-[100%] truncate'>{strTitle}{treeNameSuffixKey && <span>({item?.[treeNameSuffixKey as keyof DataNode] as string?? 0})</span>}</span>
|
||||
)
|
||||
return {
|
||||
title:<TreeWithMore dropdownMenu={dropdownMenu?.(item)} onBlur={()=>{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}</TreeWithMore>,
|
||||
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 (
|
||||
<>
|
||||
<Input className="w-[calc(100%-24px)] mx-btnbase my-btnybase" onChange={(e) => debounce(onSearchWordChange, 100)(e.target.value)}
|
||||
allowClear placeholder={placeholder}
|
||||
prefix={ <SearchOutlined className="cursor-pointer" />}/>
|
||||
<div className="max-h-[calc(100%-140px)] overflow-y-auto">
|
||||
<DirectoryTree
|
||||
icon={<></>}
|
||||
blockNode={true}
|
||||
treeData={treeData}
|
||||
selectedKeys={selectedKeys}
|
||||
onSelect={onSelect}
|
||||
/>
|
||||
</div>
|
||||
{addBtnName && <WithPermission access={addBtnAccess}><Button className="h-[22px] mt-[20px] mb-[16px] bottom-[0px] sticky border-none p-0 flex items-center bg-transparent text-theme ml-[10px] hover:text-A_HOVER" key='add' onClick={()=>handlerAction('peer')} >{addBtnName}</Button></WithPermission>}
|
||||
</>
|
||||
)
|
||||
})
|
||||
|
||||
export default GroupTree
|
||||
@@ -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<InsidePageProps> = ({showBanner=true,pageTitle,tagList,showB
|
||||
{ showBanner && <div className={`border-[0px] mr-PAGE_INSIDE_X ${showBorder ? 'border-b-[1px] border-solid border-BORDER' : ''}`}>
|
||||
<div className="mb-[30px]">
|
||||
{backUrl &&<div className="text-[18px] leading-[25px] mb-[12px]">
|
||||
<Button type="text" onClick={goBack}><ArrowLeftOutlined className="max-h-[14px]" />返回</Button>
|
||||
<Button type="text" onClick={goBack}><ArrowLeftOutlined className="max-h-[14px]" />{$t('返回')}</Button>
|
||||
</div>}
|
||||
<div className="flex justify-between mb-[20px] items-center ">
|
||||
<div className="flex items-center gap-TAG_LEFT ">
|
||||
|
||||
@@ -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: <Button key="cn" type="text" className="border-none p-0 flex items-center bg-transparent ">
|
||||
{$t('简体')}
|
||||
</Button>,
|
||||
title: $t('简体'),
|
||||
},
|
||||
{
|
||||
key: 'en',
|
||||
label:<Button key="en" type="text" className="border-none p-0 flex items-center bg-transparent ">
|
||||
{$t('英文')}
|
||||
</Button>,
|
||||
title:$t('英文')
|
||||
}
|
||||
];
|
||||
|
||||
const langLabel = items.find((item) => item?.key === state.language)?.title;
|
||||
return (
|
||||
<Dropdown
|
||||
trigger={['hover']}
|
||||
menu={{
|
||||
items,
|
||||
style:{minWidth:'80px'},
|
||||
onClick: (e) => {
|
||||
const { key } = e;
|
||||
dispatch({ type: 'UPDATE_LANGUAGE', language: key });
|
||||
i18n.changeLanguage(key);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Button className=" text-[#ffffffb3] hover:text-[#fff] border-none" type="default" ghost >
|
||||
<span className='flex items-center gap-[8px]'> <Icon icon="ic:baseline-language" width="14" height="14"/>{langLabel}</span>
|
||||
</Button>
|
||||
</Dropdown>
|
||||
);
|
||||
};
|
||||
export default memo(LanguageSetting);
|
||||
|
||||
@@ -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<TransferProps, 'dataSource'>[number];
|
||||
|
||||
export type TransferTableProps<T> = {
|
||||
request?:(k?:string)=>Promise<{data:T[],success:boolean}>
|
||||
columns: ColumnsType<T>
|
||||
primaryKey:string
|
||||
onSelect:(selectedData:T[])=>void
|
||||
tableType?:'member'|'api'
|
||||
disabledData:string[]
|
||||
searchPlaceholder?:string
|
||||
}
|
||||
|
||||
export type TransferTableHandle<T> = {
|
||||
selectedData: () => T[];
|
||||
selectedRowKeys: () => React.Key[];
|
||||
}
|
||||
|
||||
interface TreeTransferProps {
|
||||
dataSource: TreeDataNode[];
|
||||
targetKeys: TransferProps['targetKeys'];
|
||||
|
||||
@@ -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 <Editor {...props} />;
|
||||
};
|
||||
|
||||
export default MonacoEditorWrapper;
|
||||
@@ -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<MenuProps>['items'][number];
|
||||
|
||||
const APP_MODE = import.meta.env.VITE_APP_MODE;
|
||||
|
||||
// avoid changing route within ths same category
|
||||
export const routerKeyMap = new Map<string, string[]|string>([
|
||||
['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',<Icon icon="ic:baseline-space-dashboard" width="18" height="18"/>, [
|
||||
getNavItem('我的', 'my','/tenantManagement',null,[
|
||||
getNavItem(<a>应用</a>, 'tenantManagement','/tenantManagement',<Icon icon="ic:baseline-apps" width="18" height="18"/>,undefined,undefined,''),
|
||||
getNavItem(<a>服务</a>, 'service','/service',<Icon icon="ic:baseline-blinds-closed" width="18" height="18"/>,undefined,undefined,''),
|
||||
getNavItem(<a>团队</a>, 'team','/team',<Icon icon="ic:baseline-people-alt" width="18" height="18"/>,undefined,undefined,''),
|
||||
],undefined,''),
|
||||
getNavItem(<a>API 市场</a>, 'serviceHub','/serviceHub',<Icon icon="ic:baseline-hub" width="18" height="18"/>,undefined,undefined,'system.workspace.api_market.view'),
|
||||
]),
|
||||
|
||||
|
||||
APP_MODE === 'pro' ? getNavItem('仪表盘', 'mainPage', '/dashboard',<Icon icon="ic:baseline-bar-chart" width="18" height="18"/>,[
|
||||
getNavItem(<a >运行视图</a>, 'dashboard','/dashboard',<ProjectFilled />,undefined,undefined,''),
|
||||
getNavItem(<a >系统拓扑图</a>, 'systemrunning','/systemrunning',<ProjectFilled />,undefined,undefined,''),
|
||||
]):null,
|
||||
|
||||
getNavItem('系统设置', 'operationCenter','/member',<Icon icon="ic:baseline-settings" width="18" height="18"/>, [
|
||||
getNavItem('组织', 'organization','/member',null,[
|
||||
getNavItem(<a>成员</a>, 'member','/member',<Icon icon="ic:baseline-people-alt" width="18" height="18"/>,undefined,undefined,'system.organization.member.view'),
|
||||
getNavItem(<a>角色</a>, 'role','/role',<Icon icon="ic:baseline-verified-user" width="18" height="18"/>,undefined,undefined,'system.organization.role.view'),
|
||||
],undefined,''),
|
||||
getNavItem('API 市场', 'serviceHubSetting','/servicecategories',null,[
|
||||
getNavItem(<a>服务分类管理</a>, 'servicecategories','/servicecategories',<Icon icon="ic:baseline-hub" width="18" height="18"/>,undefined,undefined,'system.api_market.service_classification.view'),
|
||||
],undefined,'system.api_market.service_classification.view'),
|
||||
|
||||
getNavItem('运维与集成', 'maintenanceCenter','/cluster', null, [
|
||||
getNavItem(<a>集群</a>, 'cluster','/cluster',<Icon icon="ic:baseline-device-hub" width="18" height="18"/>,undefined,undefined,'system.devops.cluster.view'),
|
||||
getNavItem(<a>证书</a>, 'cert','/cert',<Icon icon="ic:baseline-security" width="18" height="18"/>,undefined,undefined,'system.devops.ssl_certificate.view'),
|
||||
getNavItem(<a>日志</a>, 'logsettings','/logsettings',<Icon icon="ic:baseline-sticky-note-2" width="18" height="18"/>,undefined,undefined,'system.devops.log_configuration.view'),
|
||||
APP_MODE === 'pro' ? getNavItem(<a>资源</a>, 'resourcesettings','/resourcesettings',null,undefined,undefined,'system.partition.self.view'):null,
|
||||
APP_MODE === 'pro' ? getNavItem(<a>Open API</a>, 'openapi','/openapi',null,undefined,undefined,'system.openapi.self.view'):null,
|
||||
]),
|
||||
]),
|
||||
];
|
||||
|
||||
const Navigation: FC = () => {
|
||||
const location = useLocation()
|
||||
const [selectedKeys, setSelectedKeys] = useState<string>('')
|
||||
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 (
|
||||
<Menu
|
||||
onClick={onClick}
|
||||
theme="dark"
|
||||
style={{height:'100%' }}
|
||||
selectedKeys={[selectedKeys]}
|
||||
defaultOpenKeys={['mainPage','dataAssets','operationCenter','maintenanceCenter']}
|
||||
mode="inline"
|
||||
items={[...menuData]}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default Navigation;
|
||||
@@ -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<T = any, ValueType = 'text'> = ProColumns<T , ValueType> & {btnNums? : number}
|
||||
|
||||
interface PageListProps<T> extends ProTableProps<T, unknown>, RefAttributes<ActionType> {
|
||||
id?:string
|
||||
columns: ProColumns<T,'text'>[]
|
||||
columns: PageProColumns<T,'text'>[]
|
||||
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<T> extends ProTableProps<T, unknown>, RefAttributes<Acti
|
||||
}
|
||||
|
||||
|
||||
|
||||
const PageList = <T extends Record<string, unknown>>(props: React.PropsWithChildren<PageListProps<T>>,ref: React.Ref<ActionType>) => {
|
||||
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<HTMLDivElement>(null);
|
||||
@@ -79,7 +82,6 @@ const PageList = <T extends Record<string, unknown>>(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 = <T extends Record<string, unknown>>(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 = <T extends Record<string, unknown>>(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
|
||||
|
||||
+33
-126
@@ -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)=>(
|
||||
<Tooltip placement="top" title={entity.change === 'error' ?`该 API 缺失 ${entity.proxyStatus == 1 && '转发信息,'} ${entity.docStatus == 1 && '文档信息,'} ${entity.upstreamStatus == 1 && '上游信息,'}请先补充`:''}>
|
||||
<span className={`${statusColorClass[entity.change as keyof typeof statusColorClass]} truncate block`}>
|
||||
{ChangeTypeEnum[entity.change as (keyof typeof ChangeTypeEnum)] || '-'}
|
||||
{entity.change === 'error' ?` 该 API 缺失 ${entity.proxyStatus == 1 && '转发信息,'} ${entity.docStatus == 1 && '文档信息,'} ${entity.upstreamStatus == 1 && '上游信息,'}请先补充`:''}
|
||||
</span>
|
||||
</Tooltip>)
|
||||
|
||||
}
|
||||
]
|
||||
|
||||
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)=>(
|
||||
<Tooltip placement="top" title={entity.change === 'error' ?`该 API 缺失 ${entity.proxyStatus == 1 && '转发信息,'} ${entity.docStatus == 1 && '文档信息,'} ${entity.upstreamStatus == 1 && '上游信息,'}请先补充`:''}>
|
||||
<span className={`${statusColorClass[entity.change as keyof typeof statusColorClass]} truncate block`}>{ChangeTypeEnum[entity.change as (keyof typeof ChangeTypeEnum)] || '-'}
|
||||
{entity.change === 'error' ?` 该 API 缺失 ${entity.proxyStatus == 1 && '转发信息,'} ${entity.docStatus == 1 && '文档信息,'} ${entity.upstreamStatus == 1 && '上游信息,'}请先补充`:''}</span>
|
||||
</Tooltip>)
|
||||
}
|
||||
]
|
||||
|
||||
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<boolean|string>
|
||||
publish:(notSave?:boolean)=>Promise<boolean|string|Record<string, unknown>>
|
||||
online:()=>Promise<boolean|string>
|
||||
}
|
||||
|
||||
export const PublishApprovalModalContent = forwardRef<PublishApprovalModalHandle,PublishApprovalModalProps>((props, ref) => {
|
||||
const { message } = App.useApp()
|
||||
@@ -115,19 +22,19 @@ export const PublishApprovalModalContent = forwardRef<PublishApprovalModalHandle
|
||||
return form.validateFields().then((value)=>{
|
||||
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<BasicResponse<null>>(`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<PublishApprovalModalHandle
|
||||
notSave ? 'service/publish/apply' : 'service/publish/release/do',{method: 'POST',eoBody:body, eoParams:{service:serviceId, team:teamId},eoTransformKeys:['versionRemark']}).then(response=>{
|
||||
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<PublishApprovalModalHandle
|
||||
fetchData<BasicResponse<null>>('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<PublishApprovalModalHandle
|
||||
<>
|
||||
{!insideSystem && <>
|
||||
<Row className="my-mbase">
|
||||
<Col className="text-left" span={4}><span >申请系统:</span></Col>
|
||||
<Col className="text-left" span={4}><span >{$t('申请系统')}:</span></Col>
|
||||
<Col span={18}>{(data as PublishApprovalInfoType).project || '-'}</Col>
|
||||
</Row>
|
||||
|
||||
<Row className="my-mbase">
|
||||
<Col className="text-left" span={4}><span >所属团队:</span></Col>
|
||||
<Col className="text-left" span={4}><span >{$t('所属团队')}:</span></Col>
|
||||
<Col span={18}>{(data as PublishApprovalInfoType).team || '-'}</Col>
|
||||
</Row>
|
||||
|
||||
<Row className="my-mbase">
|
||||
<Col className="text-left" span={4}><span >申请人:</span></Col>
|
||||
<Col className="text-left" span={4}><span >{$t('申请人')}:</span></Col>
|
||||
<Col span={18}>{(data as PublishApprovalInfoType).applier || '-'}</Col>
|
||||
</Row>
|
||||
|
||||
<Row className="my-mbase">
|
||||
<Col className="text-left" span={4}><span >申请时间:</span></Col>
|
||||
<Col className="text-left" span={4}><span >{$t('申请时间')}:</span></Col>
|
||||
<Col span={18}>{(data as PublishApprovalInfoType).applyTime || '-'}</Col>
|
||||
</Row>
|
||||
</> }
|
||||
@@ -220,54 +127,54 @@ export const PublishApprovalModalContent = forwardRef<PublishApprovalModalHandle
|
||||
insideSystem &&
|
||||
<>
|
||||
<Form.Item
|
||||
label="版本号"
|
||||
label={$t("版本号")}
|
||||
name="version"
|
||||
rules={[{required: true, message: '必填项',whitespace:true }]}
|
||||
rules={[{required: true, message: VALIDATE_MESSAGE.required,whitespace:true }]}
|
||||
>
|
||||
<Input className="w-INPUT_NORMAL" disabled={type !== 'add'} placeholder="请输入" />
|
||||
<Input className="w-INPUT_NORMAL" disabled={type !== 'add'} placeholder={PLACEHOLDER.input} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label="版本说明"
|
||||
label={$t("版本说明")}
|
||||
name="versionRemark"
|
||||
>
|
||||
<Input.TextArea className="w-INPUT_NORMAL" disabled={type !== 'add' && type !== 'publish'} placeholder="请输入" />
|
||||
<Input.TextArea className="w-INPUT_NORMAL" disabled={type !== 'add' && type !== 'publish'} placeholder={PLACEHOLDER.input} />
|
||||
</Form.Item>
|
||||
</>
|
||||
}
|
||||
<Row className="mt-mbase pb-[8px] h-[32px] font-bold" ><span >API 列表:</span></Row>
|
||||
<Row className="mt-mbase pb-[8px] h-[32px] font-bold" ><span >{$t('API 列表')}:</span></Row>
|
||||
<Row className="mb-mbase ">
|
||||
<Table
|
||||
columns={apiColumns}
|
||||
columns={ApprovalApiColumns}
|
||||
bordered={true}
|
||||
rowKey="id"
|
||||
size="small"
|
||||
dataSource={data.diffs?.apis || []}
|
||||
pagination={false}
|
||||
/></Row>
|
||||
<Row className="mt-mbase pb-[8px] h-[32px] font-bold" ><span >上游列表:</span></Row>
|
||||
<Row className="mt-mbase pb-[8px] h-[32px] font-bold" ><span >{$t('上游列表')}:</span></Row>
|
||||
<Row className="mb-mbase ">
|
||||
<Table
|
||||
bordered={true}
|
||||
columns={upstreamColumns}
|
||||
columns={ApprovalUpstreamColumns}
|
||||
size="small"
|
||||
rowKey="id"
|
||||
dataSource={data.diffs?.upstreams || []}
|
||||
pagination={false}
|
||||
/></Row>
|
||||
<Form.Item
|
||||
label="备注"
|
||||
label={$t("备注")}
|
||||
name="remark"
|
||||
>
|
||||
<Input.TextArea className="w-INPUT_NORMAL" disabled={type !== 'add' && type !== 'publish'} placeholder="请输入" />
|
||||
<Input.TextArea className="w-INPUT_NORMAL" disabled={type !== 'add' && type !== 'publish'} placeholder={PLACEHOLDER.input} />
|
||||
</Form.Item>
|
||||
{/*
|
||||
{type !== 'add' && type !== 'publish' && <Form.Item
|
||||
label="审批意见"
|
||||
label={$t("审批意见"
|
||||
name="opinion"
|
||||
extra="选择拒绝时,审批意见为必填"
|
||||
>
|
||||
<Input.TextArea className="w-INPUT_NORMAL" placeholder="请输入" onChange={()=>{ form.setFields([
|
||||
<Input.TextArea className="w-INPUT_NORMAL" placeholder={PLACEHOLDER.input} onChange={()=>{ form.setFields([
|
||||
{
|
||||
name: 'opinion',
|
||||
errors: [], // 设置为空数组来移除错误信息
|
||||
|
||||
@@ -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<boolean|string>
|
||||
}
|
||||
|
||||
export const ResetPsw = forwardRef<ResetPswHandle,ResetPswProps>((props,ref)=>{
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const save:()=>Promise<boolean | string> = ()=>{
|
||||
return new Promise((resolve)=>{
|
||||
// form.validateFields().then((value)=>{
|
||||
// fetchData<BasicResponse<null>>(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 (<WithPermission access="">
|
||||
<Form
|
||||
labelAlign='left'
|
||||
layout='vertical'
|
||||
form={form}
|
||||
scrollToFirstError
|
||||
className="mx-auto mt-mbase ml-mbase"
|
||||
name="resetPsw"
|
||||
// labelCol={{ span: 8 }}
|
||||
// wrapperCol={{ span: 10}}
|
||||
autoComplete="off"
|
||||
>
|
||||
<Form.Item<FieldType>
|
||||
label="账号"
|
||||
name="userName"
|
||||
hidden
|
||||
rules={[{ required: true, message: '必填项',whitespace:true }]}
|
||||
>
|
||||
<Input className="w-INPUT_NORMAL" placeholder="账号" disabled={true}/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item<FieldType>
|
||||
label="旧密码"
|
||||
name="old"
|
||||
rules={[{ required: true, message: '必填项',whitespace:true }]}
|
||||
>
|
||||
<Input className="w-INPUT_NORMAL" placeholder="请输入6-32位字符"/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item<FieldType>
|
||||
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('密码强度:弱,建议使用英文、数字、特殊字符组合'));
|
||||
},
|
||||
})]}
|
||||
>
|
||||
<Input className="w-INPUT_NORMAL" placeholder="请输入6-32位字符"/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item<FieldType>
|
||||
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('新密码与确认新密码不一致'));
|
||||
},
|
||||
})]}
|
||||
>
|
||||
<Input className="w-INPUT_NORMAL" placeholder="请输入6-32位字符"/>
|
||||
</Form.Item>
|
||||
|
||||
</Form>
|
||||
</WithPermission>)
|
||||
})
|
||||
+14
-32
@@ -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<SubscribeApprovalModalHandle,SubscribeApprovalModalProps>((props, ref) => {
|
||||
const { message } = App.useApp()
|
||||
const {data, type,inSystem=false, teamId, serviceId} = props
|
||||
@@ -57,20 +39,20 @@ export const SubscribeApprovalModalContent = forwardRef<SubscribeApprovalModalHa
|
||||
form.validateFields().then((value)=>{
|
||||
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<BasicResponse<null>>(`${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<SubscribeApprovalModalHa
|
||||
|
||||
return (
|
||||
<div className="my-btnybase">{
|
||||
list?.map((x)=>(
|
||||
SubscribeApprovalList?.map((x)=>(
|
||||
<Row key={x.key} className="leading-[32px] mb-btnbase mx-auto">
|
||||
<Col className="text-left" span={6}>{x.title}:</Col>
|
||||
<Col >{(data as {[k:string]:unknown})?.[x.key]?.name || (data as {[k:string]:unknown})?.[x.key] || '-'}</Col>
|
||||
@@ -109,17 +91,17 @@ export const SubscribeApprovalModalContent = forwardRef<SubscribeApprovalModalHa
|
||||
>
|
||||
|
||||
<Form.Item<FieldType>
|
||||
label="申请原因"
|
||||
label={$t("申请原因")}
|
||||
name="reason"
|
||||
>
|
||||
<Input.TextArea className="w-INPUT_NORMAL" disabled={true} placeholder=" " />
|
||||
</Form.Item>
|
||||
<Form.Item<FieldType>
|
||||
label="审核意见"
|
||||
label={$t("审核意见")}
|
||||
name="opinion"
|
||||
extra="选择拒绝时,审批意见为必填"
|
||||
extra={FORM_ERROR_TIPS.refuseOpinion}
|
||||
>
|
||||
<Input.TextArea className="w-INPUT_NORMAL" placeholder="请输入" onChange={()=>{ form.setFields([
|
||||
<Input.TextArea className="w-INPUT_NORMAL" placeholder={PLACEHOLDER.input} onChange={()=>{ form.setFields([
|
||||
{
|
||||
name: 'opinion',
|
||||
errors: [], // 设置为空数组来移除错误信息
|
||||
|
||||
@@ -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<boolean>(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<HTMLButtonElement>) => {
|
||||
e.stopPropagation()
|
||||
navigateTo ? navigate(navigateTo) : onClick?.()
|
||||
}, [navigateTo, navigate, onClick])
|
||||
|
||||
return (<>{
|
||||
!btnAccess || (disabled&&tooltip) ?
|
||||
<Tooltip placement="top" title={tooltip ?? `暂无${btnTitle}权限,请联系管理员分配。`}>
|
||||
<Button type="text" disabled={true} className={`h-[22px] border-none p-0 flex items-center bg-transparent ${className}`} key="view" >{btnTitle}</Button>
|
||||
<Button type="text" disabled={true} className={`h-[22px] border-none p-0 flex items-center bg-transparent ${className}`} key={btnType} icon={<Icon icon={TableIconName[btnType as keyof typeof TableIconName]} width="18" height="18"/>} >{}</Button>
|
||||
</Tooltip>
|
||||
:
|
||||
<Button type="text" disabled={disabled} className={`h-[22px] border-none p-0 flex items-center bg-transparent ${className} `} key="view" onClick={(e)=>{e.stopPropagation();navigateTo ? navigate(navigateTo) :onClick?.() }}>{btnTitle}</Button>
|
||||
<Tooltip placement="top" title={$t(btnTitle)}>
|
||||
<Button type="text" disabled={disabled} className={`h-[22px] border-none p-0 flex items-center bg-transparent ${className} `} key={btnType} icon={<Icon icon={TableIconName[btnType as keyof typeof TableIconName]} width="18" height="18"/>} onClick={handleClick}>{}</Button>
|
||||
</Tooltip>
|
||||
|
||||
}</>
|
||||
);
|
||||
|
||||
@@ -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<PickerProps<Moment>, 'picker'> {}
|
||||
|
||||
const TimePicker = forwardRef<unknown, TimePickerProps>((props, ref) => (
|
||||
<DatePicker {...props} picker="time" mode={undefined} ref={ref} />
|
||||
));
|
||||
|
||||
TimePicker.displayName = 'TimePicker';
|
||||
|
||||
export default TimePicker;
|
||||
@@ -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<typeof DatePicker.RangePicker>;
|
||||
export type RangeValue = [Dayjs | null, Dayjs | null] | null;
|
||||
@@ -94,12 +95,12 @@ const disabledDate: RangePickerProps['disabledDate'] = (current) => {
|
||||
|
||||
return (
|
||||
<div className="flex flex-nowrap items-center pt-btnybase mr-btnybase">
|
||||
{!hideTitle && <label className={`whitespace-nowrap `}>时间:</label>}
|
||||
{!hideTitle && <label className={`whitespace-nowrap `}>{$t('时间')}:</label>}
|
||||
<Radio.Group className="whitespace-nowrap" value={timeButton} onChange={handleRadioChange} buttonStyle="solid">
|
||||
<Radio.Button value="hour">近1小时</Radio.Button>
|
||||
<Radio.Button value="day">近24小时</Radio.Button>
|
||||
<Radio.Button value="threeDays">近3天</Radio.Button>
|
||||
<Radio.Button className="rounded-e-none" value="sevenDays">近7天</Radio.Button>
|
||||
<Radio.Button value="hour">{$t('近1小时')}</Radio.Button>
|
||||
<Radio.Button value="day">{$t('近24小时')}</Radio.Button>
|
||||
<Radio.Button value="threeDays">{$t('近3天')}</Radio.Button>
|
||||
<Radio.Button className="rounded-e-none" value="sevenDays">{$t('近7天')}</Radio.Button>
|
||||
</Radio.Group>
|
||||
<DatePicker.RangePicker
|
||||
value={datePickerValue}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
.transfer-table-member,
|
||||
.transfer-table-api{
|
||||
:global .ant-table-wrapper .ant-table-thead >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;
|
||||
}
|
||||
}
|
||||
@@ -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<T> = {
|
||||
request?:(k?:string)=>Promise<{data:T[],success:boolean}>
|
||||
columns: ColumnsType<T>
|
||||
primaryKey:string
|
||||
onSelect:(selectedData:T[])=>void
|
||||
tableType?:'member'|'api'
|
||||
disabledData:string[]
|
||||
searchPlaceholder?:string
|
||||
}
|
||||
|
||||
export type TransferTableHandle<T> = {
|
||||
selectedData: () => T[];
|
||||
selectedRowKeys: () => React.Key[];
|
||||
}
|
||||
|
||||
const TransferTable = forwardRef<TransferTableHandle<{[k:string]:unknown}>, TransferTableProps<{[k:string]:unknown}>>(
|
||||
<T extends {[k:string]:unknown}>(props: TransferTableProps<T>, ref:Ref<TransferTableHandle<T>>) => {
|
||||
const {request,columns,primaryKey,onSelect,tableType,disabledData = [],searchPlaceholder} = props
|
||||
const tblRef: Parameters<typeof Table>[0]['ref'] = useRef(null);
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>(disabledData);
|
||||
const [selectedData, setSelectedData] = useState<Array<T>>([])
|
||||
const [dataSource, setDataSource] = useState<T[]>([])
|
||||
const [searchWord, ] = useState<string>('')
|
||||
const [loading, setLoading] = useState<boolean>(false)
|
||||
const parentRef = useRef<HTMLDivElement>(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) => [
|
||||
<CloseOutlined className="p-0 w-full h-full hover:bg-bar-theme" onClick={()=>removeItem(entity as T)}/>
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
const onSearchWordChange = (e: KeyboardEventHandler<HTMLInputElement>)=>{
|
||||
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 (
|
||||
<div ref={parentRef} className={styles['transfer-table-'+`${tableType === 'member'? 'member':'api'}`] + ` flex flex-1 w-[550px] min-h-[404px] overflow-hidden`}>
|
||||
<div className="flex flex-col border-[1px] border-solid border-BORDER w-[calc(50%-10px)]">
|
||||
<Input className=" m-btnbase w-[calc(100%-24px)]" onChange={ debouncedSearch} onPressEnter={onSearchWordChange} allowClear placeholder={searchPlaceholder || "请输入"} prefix={<SearchOutlined className="cursor-pointer" onClick={()=>{onSearchWordChange}}/>} />
|
||||
{tableShow && <Table
|
||||
columns={columns}
|
||||
virtual
|
||||
size="small"
|
||||
scroll={{ x:100 ,y:tableHeight}}
|
||||
rowKey={primaryKey || 'id'}
|
||||
dataSource={dataSource}
|
||||
pagination={false}
|
||||
loading={loading}
|
||||
ref={tblRef}
|
||||
rowSelection={
|
||||
{
|
||||
selectedRowKeys,
|
||||
onChange: onSelectChange,
|
||||
columnWidth: 40,
|
||||
getCheckboxProps: (record: {[k:string]:string}) => ({
|
||||
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);
|
||||
}
|
||||
})}
|
||||
/>}
|
||||
</div>
|
||||
<div className= {`flex flex-col w-[calc(50%-10px)] ml-[20px] border-[1px] border-solid border-BORDER`}>
|
||||
<div className="leading-[32px] mt-btnybase mb-[54px]">
|
||||
<span className="ml-[20px]">已选{tableType === 'member' ? '成员' : ' API'} <span className="mr-[4px]">({selectedData.length})</span></span>
|
||||
</div>
|
||||
<Table
|
||||
virtual
|
||||
scroll={{x:200,y:tableHeight}}
|
||||
size="small"
|
||||
columns={[...columns?.map((col)=>({...col,className:(col.className || ' ') + 'pl-[20px]'})),...operations]}
|
||||
showHeader={false}
|
||||
rowKey={primaryKey}
|
||||
dataSource={selectedData}
|
||||
pagination={false}
|
||||
ref={tblRef}
|
||||
loading={loading}
|
||||
/>
|
||||
</div>
|
||||
</div>);
|
||||
})
|
||||
export default TransferTable
|
||||
@@ -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<UserInfoType>()
|
||||
const resetPswRef = useRef<ResetPswHandle>(null)
|
||||
const userProfileRef = useRef<UserProfileHandle>(null)
|
||||
const {fetchData} = useFetch()
|
||||
const navigate = useNavigate();
|
||||
|
||||
const getUserInfo = ()=>{
|
||||
fetchData<BasicResponse<{profile:UserInfoType}>>('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<BasicResponse<null>>('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: (
|
||||
// <a target="_blank" rel="noopener noreferrer" onClick={()=>openModal('userSetting')}>
|
||||
// 用户设置
|
||||
// </a>
|
||||
// ),
|
||||
// },
|
||||
// {
|
||||
// key: '2',
|
||||
// label: (
|
||||
// <a target="_blank" rel="noopener noreferrer" onClick={()=>openModal('resetPsw')}>
|
||||
// 修改密码
|
||||
// </a>
|
||||
// ),
|
||||
// },
|
||||
{
|
||||
key: '3',
|
||||
label: (
|
||||
<a className="block leading-[32px]" target="_blank" rel="noopener noreferrer" onClick={logOut}>
|
||||
退出登录
|
||||
</a>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const openModal = (type:'userSetting'|'resetPsw')=>{
|
||||
let title:string = ''
|
||||
let content:string|React.ReactNode = ''
|
||||
switch (type){
|
||||
case 'userSetting':
|
||||
title='用户设置'
|
||||
content=<UserProfile ref={userProfileRef} entity={userInfo}/>
|
||||
break;
|
||||
case 'resetPsw':
|
||||
title='重置密码'
|
||||
content=<ResetPsw ref={resetPswRef} entity={userInfo} />
|
||||
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 (
|
||||
<Dropdown menu={{ items }}>
|
||||
<span className="flex items-center"><Avatar className="mx-[6px]" src={AvatarPic || userInfo?.avatar}></Avatar><span>{userInfo?.username||'unknown'}</span></span>
|
||||
</Dropdown>
|
||||
)
|
||||
}
|
||||
|
||||
export default UserAvatar
|
||||
@@ -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<UserProfileHandle,UserProfileProps>((props,ref)=>{
|
||||
const { message } = App.useApp()
|
||||
const [form] = Form.useForm();
|
||||
const {entity,} = props
|
||||
const {fetchData} = useFetch()
|
||||
const [imageBase64, setImageBase64] = useState<string | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [imageUrl, setImageUrl] = useState<string>();
|
||||
|
||||
const save:()=>Promise<boolean | string> = ()=>{
|
||||
return new Promise((resolve, reject)=>{
|
||||
form.validateFields().then((value)=>{
|
||||
fetchData<BasicResponse<null>>('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<UploadFile>) => {
|
||||
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 = (
|
||||
<div>
|
||||
<div className="h-[68px] w-[68px] border-[1px] border-dashed border-BORDER flex items-center justify-center rounded bg-bar-theme cursor-pointer" style={{ marginTop: 8 }}>
|
||||
{loading ? <LoadingOutlined /> : <Icon icon="ic:baseline-add" width="18" height="18" className='mr-[2px]'/>}</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const beforeUpload = (file: RcFile) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e: ProgressEvent<FileReader>) => {
|
||||
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 (<>
|
||||
<Form
|
||||
labelAlign='left'
|
||||
layout='vertical'
|
||||
scrollToFirstError
|
||||
form={form}
|
||||
className="mx-auto mt-mbase "
|
||||
name="userProfile"
|
||||
// labelCol={{ span: 8 }}
|
||||
// wrapperCol={{ span: 10}}
|
||||
autoComplete="off"
|
||||
>
|
||||
<Form.Item<UserInfoType>
|
||||
label="账号"
|
||||
name="username"
|
||||
rules={[{ required: true, message: '必填项',whitespace:true }]}
|
||||
>
|
||||
<Input className="w-INPUT_NORMAL" placeholder="账号" disabled={true}/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item<UserInfoType>
|
||||
label="昵称"
|
||||
name="nickname"
|
||||
rules={[{ required: true, message: '必填项',whitespace:true }]}
|
||||
>
|
||||
<Input className="w-INPUT_NORMAL" placeholder="请输入"/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item<UserInfoType>
|
||||
label="头像"
|
||||
name="avatar"
|
||||
valuePropName="fileList" getValueFromEvent={normFile}
|
||||
>
|
||||
<Upload
|
||||
listType="picture"
|
||||
beforeUpload={beforeUpload}
|
||||
onChange={handleChange}
|
||||
showUploadList={false}
|
||||
maxCount={1}
|
||||
>
|
||||
{imageBase64 ? <img src={imageBase64} alt="Logo" style={{ maxWidth: '200px'}} /> : uploadButton}
|
||||
</Upload>
|
||||
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item<UserInfoType>
|
||||
label="邮箱"
|
||||
name="email"
|
||||
rules={[{ required: true, message: '必填项' ,whitespace:true },{type:'email',message: '输入的不是有效邮箱格式'}]}
|
||||
>
|
||||
<Input className="w-INPUT_NORMAL" placeholder="请输入"/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item<UserInfoType>
|
||||
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 }]}
|
||||
>
|
||||
<Input className="w-INPUT_NORMAL" placeholder="请输入"/>
|
||||
</Form.Item>
|
||||
|
||||
</Form>
|
||||
</>)
|
||||
})
|
||||
@@ -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 && <Tooltip title={tooltip}>
|
||||
{ cloneElement(children, {disabled:true})}
|
||||
</Tooltip>}
|
||||
{!editAccess && (children?.type?.displayName !== 'Button' && showDisabled ) && <Tooltip title={tooltip ?? "暂无操作权限,请联系管理员分配。"}>
|
||||
{!editAccess && (children?.type?.displayName !== 'Button' && showDisabled ) && <Tooltip title={tooltip ?? $t("暂无操作权限,请联系管理员分配。")}>
|
||||
{ cloneElement(children, {disabled:true})}
|
||||
</Tooltip>}
|
||||
|
||||
|
||||
+2
-1
@@ -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 (
|
||||
<FormLayout
|
||||
|
||||
+3
-2
@@ -1,13 +1,14 @@
|
||||
import {forwardRef, useImperativeHandle, useState} from 'react'
|
||||
|
||||
import { Input } from '@formily/antd-v5'
|
||||
import { $t } from '@common/locales'
|
||||
export const SimpleMapComponent = forwardRef(
|
||||
(props: { [k: string]: unknown }, ref) => {
|
||||
const {
|
||||
onChange,
|
||||
value,
|
||||
placeholderKey = '请输入Key',
|
||||
placeholderValue = '请输入Value'
|
||||
placeholderKey = $t('请输入Key'),
|
||||
placeholderValue = $t('请输入Value')
|
||||
} = props
|
||||
|
||||
const [kvList, setKvList] = useState(
|
||||
|
||||
+14
-16
@@ -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<IntelligentPluginConfigHandle
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
title: 'ID',
|
||||
title: $t('ID'),
|
||||
required: true,
|
||||
pattern: /^[a-zA-Z][a-zA-Z0-9-_]*$/,
|
||||
'x-decorator': 'FormItem',
|
||||
@@ -169,13 +167,13 @@ export const IntelligentPluginConfig = forwardRef<IntelligentPluginConfigHandle
|
||||
},
|
||||
'x-component': 'Input',
|
||||
'x-component-props': {
|
||||
placeholder: '支持字母开头、英文数字中横线下划线组合',
|
||||
placeholder: PLACEHOLDER.specialStartWithAlphabet,
|
||||
},
|
||||
'x-disabled': type === 'edit'
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
title: '名称',
|
||||
title: $t('名称'),
|
||||
required: true,
|
||||
'x-decorator': 'FormItem',
|
||||
'x-decorator-props': {
|
||||
@@ -185,12 +183,12 @@ export const IntelligentPluginConfig = forwardRef<IntelligentPluginConfigHandle
|
||||
},
|
||||
'x-component': 'Input',
|
||||
'x-component-props': {
|
||||
placeholder: '请输入名称',
|
||||
placeholder: PLACEHOLDER.input,
|
||||
}
|
||||
},
|
||||
driver: {
|
||||
type: 'string',
|
||||
title: 'Driver',
|
||||
title: $t('Driver'),
|
||||
required: true,
|
||||
'x-decorator': 'FormItem',
|
||||
'x-decorator-props': {
|
||||
@@ -207,7 +205,7 @@ export const IntelligentPluginConfig = forwardRef<IntelligentPluginConfigHandle
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
title: '描述',
|
||||
title: $t('描述'),
|
||||
'x-decorator': 'FormItem',
|
||||
'x-decorator-props': {
|
||||
labelCol:4,
|
||||
@@ -216,7 +214,7 @@ export const IntelligentPluginConfig = forwardRef<IntelligentPluginConfigHandle
|
||||
},
|
||||
'x-component': 'Input.TextArea',
|
||||
'x-component-props': {
|
||||
placeholder: '请输入描述',
|
||||
placeholder: PLACEHOLDER.input,
|
||||
}
|
||||
},
|
||||
config: {
|
||||
@@ -238,11 +236,11 @@ export const IntelligentPluginConfig = forwardRef<IntelligentPluginConfigHandle
|
||||
fetchData<BasicResponse<null>>(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<IntelligentPluginConfigHandle
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
resolve(data[skill]?.map((x:{name:string,title:string})=>{return{label:x.title, value:x.name}}) || [])
|
||||
}else{
|
||||
message.error(msg || '操作失败')
|
||||
reject(msg || '操作失败')
|
||||
message.error(msg || RESPONSE_TIPS.error)
|
||||
reject(msg || RESPONSE_TIPS.error)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
+28
-27
@@ -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<DynamicTableItem[]>([]);
|
||||
|
||||
const [tableHttpReload, setTableHttpReload] = useState(true);
|
||||
const [columns,setColumns] = useState<ProColumns<DynamicTableItem>[] >([])
|
||||
const [columns,setColumns] = useState<PageProColumns<DynamicTableItem>[] >([])
|
||||
const {fetchData} = useFetch()
|
||||
const pageListRef = useRef<ActionType>(null);
|
||||
const [publishBtnLoading, setPublishBtnLoading] = useState<boolean>(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<DynamicTableItem>[] =[
|
||||
const operation:PageProColumns<DynamicTableItem>[] =[
|
||||
{
|
||||
title: '操作',
|
||||
title: COLUMNS_TITLE.operate,
|
||||
key: 'option',
|
||||
width: 150,
|
||||
fixed:'right',
|
||||
valueType: 'option',
|
||||
btnNums:3,
|
||||
render: (_: React.ReactNode, entity: DynamicTableItem) => [
|
||||
<TableBtnWithPermission access={`${accessPrefix}.publish`} key="publish" onClick={()=>{openModal('publish',entity)}} btnTitle={entity.status === '已发布' ? '下线' : '上线'}/>,
|
||||
<TableBtnWithPermission access={`${accessPrefix}.publish`} key="publish" btnType="publish" onClick={()=>{openModal('publish',entity)}} btnTitle={entity.status === $t('已发布') ? $t('下线') : $t('上线')}/>,
|
||||
<Divider type="vertical" className="mx-0" key="div1"/>,
|
||||
<TableBtnWithPermission access={`${accessPrefix}.view`} key="edit" onClick={()=>{openDrawer('edit',entity)}} btnTitle="查看"/>,
|
||||
<TableBtnWithPermission access={`${accessPrefix}.view`} key="edit" btnType="edit" onClick={()=>{openDrawer('edit',entity)}} btnTitle={$t("查看")}/>,
|
||||
<Divider type="vertical" className="mx-0" key="div2"/>,
|
||||
<TableBtnWithPermission access={`${accessPrefix}.delete`} key="delete" onClick={()=>{openModal('delete',entity)}} btnTitle="删除"/>,
|
||||
<TableBtnWithPermission access={`${accessPrefix}.delete`} key="delete" btnType="delete" onClick={()=>{openModal('delete',entity)}} btnTitle={$t("删除")}/>,
|
||||
],
|
||||
}
|
||||
]
|
||||
@@ -213,11 +214,11 @@ export default function IntelligentPluginList(){
|
||||
fetchData<BasicResponse<null>>(`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<BasicResponse<DynamicPublish>>(`dynamic/${moduleId}/${entity!.status === '已发布' ? 'offline':'online'}`, {
|
||||
message.loading(RESPONSE_TIPS.operating)
|
||||
await fetchData<BasicResponse<DynamicPublish>>(`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=<span>确定删除<span className="text-status_fail"></span>?此操作无法恢复,确认操作?</span>
|
||||
content=<span>{DELETE_TIPS.default}</span>
|
||||
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)}}
|
||||
/>
|
||||
|
||||
<DrawerWithFooter title={`${drawerType === 'add' ? '添加' : '编辑'}${pluginName }`} open={drawerOpen} onClose={()=>{setCurDetail(undefined);setDrawerOpen(false)}} onSubmit={()=>drawerFormRef.current?.save()?.then((res)=>{res && manualReloadTable();return res})} submitAccess=''>
|
||||
<DrawerWithFooter title={`${drawerType === 'add' ? $t('添加') : $t('编辑')}${pluginName }`} open={drawerOpen} onClose={()=>{setCurDetail(undefined);setDrawerOpen(false)}} onSubmit={()=>drawerFormRef.current?.save()?.then((res)=>{res && manualReloadTable();return res})} submitAccess=''>
|
||||
<Spin indicator={<LoadingOutlined style={{ fontSize: 24 }} spin/>} spinning={drawerLoading}>
|
||||
<IntelligentPluginConfig
|
||||
ref={drawerFormRef!}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { $t } from "@common/locales"
|
||||
|
||||
export type PARAM_TYPE =
|
||||
| 'string'
|
||||
| 'float'
|
||||
@@ -113,7 +115,7 @@ export const CODE_SNIPPETS: CODE_LANGUAGE_SNIPPETS_TYPE[] = [
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '微信小程序',
|
||||
label: $t('微信小程序'),
|
||||
value: 21,
|
||||
isLeaf: true
|
||||
},
|
||||
|
||||
@@ -2,6 +2,7 @@ import { cloneDeep } from 'lodash-es'
|
||||
import { parseFormData, parseFileValue, parseFileType, parseHeaders, parseRequestBodyToString, parseUri, payloadStr, goCodeParseFormData } from './transform'
|
||||
// import { getJson } from '../.@common/utils/';
|
||||
import { ApiBodyType } from '@common/const/api-detail';
|
||||
import { $t } from '@common/locales';
|
||||
|
||||
function sameNameToParams(params: unknown) {
|
||||
params = cloneDeep(params)
|
||||
@@ -522,7 +523,7 @@ export function generateCode(
|
||||
if (multipart) {
|
||||
code =
|
||||
'<?php\r\n' +
|
||||
'//获取文件,需填路径 \r\n' +
|
||||
`//${$t('获取文件,需填路径')} \r\n` +
|
||||
'$file_path = "";\r\n' +
|
||||
`$file_name = "${langTmp.fileValue}";\r\n` +
|
||||
'$client = new http\\Client;\r\n' +
|
||||
@@ -599,7 +600,7 @@ export function generateCode(
|
||||
if (multipart) {
|
||||
code =
|
||||
'<?php\r\n\r\n' +
|
||||
'//获取文件,需填路径 \r\n' +
|
||||
`//${$t('获取文件,需填路径')} \r\n` +
|
||||
'$file_path = ""; \r\n\r\n' +
|
||||
'$curl = curl_init();\r\n\r\n' +
|
||||
'curl_setopt_array($curl, array(\r\n' +
|
||||
|
||||
@@ -12,6 +12,7 @@ import {ApiDetail} from "@common/const/api-detail";
|
||||
import {Codebox} from "@common/components/postcat//api/Codebox";
|
||||
import {Collapse} from "@common/components/postcat/api/Collapse";
|
||||
import {Box} from "@mui/material";
|
||||
import { $t } from '@common/locales';
|
||||
|
||||
type CodeSnippetCompoType = {
|
||||
title:string
|
||||
@@ -156,7 +157,7 @@ type CodeSnippetCompoType = {
|
||||
let tempCode = ''
|
||||
const getCode = (language: number | string) => {
|
||||
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 = {
|
||||
<Collapse title={title}>
|
||||
<Box width="100%">
|
||||
<>
|
||||
<Codebox extraContent={<><span className="ml-[12px]">编程语言:</span><Cascader
|
||||
<Codebox extraContent={<><span className="ml-[12px]">{$t('编程语言')}:</span><Cascader
|
||||
options={CODE_LANG}
|
||||
onChange={(value,record) => onChange(value as unknown as number[],record)}
|
||||
placeholder={placeholderTxt}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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")}
|
||||
/>}
|
||||
</div>
|
||||
{mode === 'view' ?
|
||||
@@ -94,7 +95,7 @@ export function ResponseExampleCompo ({ editorRef,title,detail,mode='view' }: {e
|
||||
{ item.content ?
|
||||
<pre className="border-[1px] border-solid border-BORDER p-[6px] rounded w-auto min-h-[130px] max-h-[500px] overflow-auto mt-[0px]">{item.content}</pre>
|
||||
:
|
||||
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂未填写示例"/>
|
||||
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description={$t("暂未填写示例")}/>
|
||||
}</>
|
||||
: <>
|
||||
<Codebox value={item.content} language='json' width="100%" height={'250px'} onChange={(value)=>updateResultList(item.id,'content',value)}/>
|
||||
|
||||
@@ -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<SystemApiDetail>}= {
|
||||
apiInfo:{
|
||||
info:{
|
||||
@@ -200,7 +202,7 @@ export default function ApiEdit({apiInfo,editorRef,loaded,serviceId, teamId}:{ap
|
||||
getData:()=>description
|
||||
}))
|
||||
return (
|
||||
<Input.TextArea className="w-full border-none" value={description} onChange={(e)=>setDescription(e.target.value)} placeholder="请输入"/>
|
||||
<Input.TextArea className="w-full border-none" value={description} onChange={(e)=>setDescription(e.target.value)} placeholder={PLACEHOLDER.input}/>
|
||||
)
|
||||
})
|
||||
|
||||
@@ -229,25 +231,25 @@ export default function ApiEdit({apiInfo,editorRef,loaded,serviceId, teamId}:{ap
|
||||
<Box>
|
||||
<Stack direction="column" spacing={3}>
|
||||
<ApiName apiInfo={apiInfo} ref={apiNameRef}/>
|
||||
<Collapse key="description" title='详细说明'>
|
||||
<Collapse key="description" title={$t('详细说明')}>
|
||||
<Description initDescription={apiInfo?.description} ref={descriptionRef}/>
|
||||
</Collapse>
|
||||
{
|
||||
apiInfo?.match && apiInfo.match?.length > 0 &&
|
||||
<ApiMatch title='高级匹配' rows={apiInfo?.match.map((x)=>{x.id = uuidv4();return x})} />
|
||||
<ApiMatch title={$t('高级匹配')} rows={apiInfo?.match.map((x)=>{x.id = uuidv4();return x})} />
|
||||
}
|
||||
|
||||
<Collapse title='转发配置' key="proxy" >
|
||||
<Collapse title={$t('转发配置')} key="proxy" >
|
||||
<SystemInsideApiProxy className="m-[12px] px-[12px]" initProxyValue={apiInfo?.proxy} serviceId={serviceId!} ref={proxyRef} />
|
||||
</Collapse>
|
||||
|
||||
<Collapse title='请求参数' key="request" >
|
||||
<Collapse title={$t('请求参数')} key="request" >
|
||||
<ApiRequestEditor editorRef={requestRef} apiInfo={apiInfo?.doc} loaded={loaded} />
|
||||
</Collapse>
|
||||
<Collapse title='返回值' key="response">
|
||||
<Collapse title={$t('返回值')} key="response">
|
||||
<ApiResponseEditor editorRef={responseRef} apiInfo={apiInfo?.doc} loaded={loaded}/>
|
||||
</Collapse>
|
||||
<ResponseExampleCompo editorRef={resultListRef} mode='edit' title='返回示例' detail={resultList}/>
|
||||
<ResponseExampleCompo editorRef={resultListRef} mode='edit' title={$t('返回示例')} detail={resultList}/>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
@@ -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 (
|
||||
<Tooltip >
|
||||
<span className="text-disabled">测试 API</span>
|
||||
<span className="text-disabled">{$t('测试 API')}</span>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
@@ -90,13 +91,13 @@ export default function ApiPreview(props:{testClick?:()=>void, entity:ApiDetail}
|
||||
|
||||
{
|
||||
requestParams?.headerParams?.length > 0 &&
|
||||
<HeaderFields title='请求 Header' rows={requestParams?.headerParams}
|
||||
<HeaderFields title={$t('请求 Header')} rows={requestParams?.headerParams}
|
||||
onMoreSettingChange={setCurrentMoreSettingParam} />
|
||||
}
|
||||
|
||||
{requestBodyList?.length > 0 &&
|
||||
<MessageBodyComponent
|
||||
title="请求 Body"
|
||||
title={$t("请求 Body")}
|
||||
rows={requestBodyList}
|
||||
contentType={requestParams?.bodyParams[0]?.contentType}
|
||||
onMoreSettingChange={setCurrentMoreSettingParam}
|
||||
@@ -105,40 +106,40 @@ export default function ApiPreview(props:{testClick?:()=>void, entity:ApiDetail}
|
||||
|
||||
{
|
||||
requestParams?.queryParams?.length > 0 &&
|
||||
<HeaderFields title='Query 参数' rows={requestParams?.queryParams}
|
||||
<HeaderFields title={$t('Query 参数')} rows={requestParams?.queryParams}
|
||||
onMoreSettingChange={setCurrentMoreSettingParam} />
|
||||
}
|
||||
|
||||
{
|
||||
requestParams?.restParams?.length > 0 &&
|
||||
<HeaderFields title='Rest 参数' rows={requestParams?.restParams}
|
||||
<HeaderFields title={$t('Rest 参数')} rows={requestParams?.restParams}
|
||||
onMoreSettingChange={setCurrentMoreSettingParam}/>
|
||||
}
|
||||
|
||||
{/*<h3 className="text-lg mb-btnybase font-normal flex items-center">请求示例代码</h3>*/}
|
||||
<CodeSnippetCompo
|
||||
title='请求示例代码'
|
||||
title={$t('请求示例代码')}
|
||||
api={entity}
|
||||
extraContent={ testClick ? <div className="ml-5">
|
||||
<Tooltip >
|
||||
<WithPermission access="" >
|
||||
<Button type='primary' onClick={handleTest} size='small' className='w-[114px]'>测试 API</Button>
|
||||
<Button type='primary' onClick={handleTest} size='small' className='w-[114px]'>{$t('测试 API')}</Button>
|
||||
</WithPermission>
|
||||
</Tooltip>
|
||||
</div> : undefined }
|
||||
/>
|
||||
|
||||
{resultList?.length > 0 && <ResponseExampleCompo title='响应示例' detail={resultList}/>}
|
||||
{resultList?.length > 0 && <ResponseExampleCompo title={$t('响应示例')} detail={resultList}/>}
|
||||
|
||||
{
|
||||
responseList?.[0]?.responseParams?.headerParams?.length > 0 &&
|
||||
<HeaderFields title='响应 Header' rows={ responseList?.[0]?.responseParams?.headerParams}
|
||||
<HeaderFields title={$t('响应 Header')} rows={ responseList?.[0]?.responseParams?.headerParams}
|
||||
onMoreSettingChange={setCurrentMoreSettingParam} />
|
||||
}
|
||||
|
||||
{responseBodyList?.length > 0 &&
|
||||
<MessageBodyComponent
|
||||
title="响应 Body"
|
||||
title={$t("响应 Body")}
|
||||
rows={responseBodyList}
|
||||
contentType={responseList?.[0]?.contentType}
|
||||
onMoreSettingChange={setCurrentMoreSettingParam}
|
||||
|
||||
+2
-1
@@ -1,10 +1,11 @@
|
||||
import { $t } from '@common/locales';
|
||||
import { TextField } from '@mui/material'
|
||||
import { SyntheticEvent } from 'react'
|
||||
|
||||
export function RequestBodyBinary({ value, onChange }: { value: string; onChange: (value: string) => void }) {
|
||||
return (
|
||||
<TextField
|
||||
label="Binary"
|
||||
label={$t("Binary")}
|
||||
multiline
|
||||
rows={4}
|
||||
value={value}
|
||||
|
||||
+6
-6
@@ -10,6 +10,7 @@ import {
|
||||
import {MessageDataGrid, MessageDataGridApi} from "../MessageDataGrid";
|
||||
import {Indicator} from "../../../../Indicator";
|
||||
import { ApiMessageBody, ApiMessageBodyApi } from '../ApiMessageBody';
|
||||
import { $t } from '@common/locales';
|
||||
|
||||
export interface ApiRequestEditorApi {
|
||||
getData: () => {
|
||||
@@ -62,7 +63,7 @@ export function ApiRequestEditor({ editorRef ,apiInfo=null,loaded}: { editorRef?
|
||||
|
||||
const tabs: ApiRequestEditorTab[] = [
|
||||
{
|
||||
label: '请求头部',
|
||||
label: $t('请求头部'),
|
||||
element: (
|
||||
<MessageDataGrid
|
||||
apiRef={headersRef}
|
||||
@@ -76,12 +77,12 @@ export function ApiRequestEditor({ editorRef ,apiInfo=null,loaded}: { editorRef?
|
||||
dirty: false
|
||||
},
|
||||
{
|
||||
label:'请求体',
|
||||
label:$t('请求体'),
|
||||
element: <ApiMessageBody bodyApiRef={bodyRef} mode="request" apiInfo={apiInfo} loaded={innerLoaded}/>,
|
||||
dirty: false
|
||||
},
|
||||
{
|
||||
label: 'Query 参数',
|
||||
label: $t('Query 参数'),
|
||||
element: (
|
||||
<MessageDataGrid
|
||||
apiRef={queryRef}
|
||||
@@ -95,7 +96,7 @@ export function ApiRequestEditor({ editorRef ,apiInfo=null,loaded}: { editorRef?
|
||||
dirty: false
|
||||
},
|
||||
{
|
||||
label: 'REST 参数',
|
||||
label: $t('REST 参数'),
|
||||
element: (
|
||||
<MessageDataGrid
|
||||
apiRef={restRef}
|
||||
@@ -123,12 +124,11 @@ export function ApiRequestEditor({ editorRef ,apiInfo=null,loaded}: { editorRef?
|
||||
|
||||
return (
|
||||
<Box sx={{
|
||||
// borderBottom: 1,
|
||||
borderColor: 'divider' }}>
|
||||
<Tabs
|
||||
value={tabValue}
|
||||
onChange={handleChange}
|
||||
aria-label="api request editor"
|
||||
aria-label={$t("api request editor")}
|
||||
sx={{
|
||||
minHeight: tabHeight,
|
||||
height: tabHeight,
|
||||
|
||||
+4
-3
@@ -5,6 +5,7 @@ import {ApiBodyType, BodyParamsType, HeaderParamsType} from "@common/const/api-d
|
||||
import {Indicator} from "../../../../Indicator";
|
||||
import { v4 as uuidv4} from 'uuid'
|
||||
import { ApiMessageBody, ApiMessageBodyApi } from '../ApiMessageBody';
|
||||
import { $t } from '@common/locales';
|
||||
|
||||
interface ApiRequestEditorTab {
|
||||
label: string
|
||||
@@ -54,7 +55,7 @@ export function ApiResponseEditor({ editorRef ,apiInfo=null, loaded}: { editorRe
|
||||
|
||||
const tabs: ApiRequestEditorTab[] = [
|
||||
{
|
||||
label: '返回头部',
|
||||
label: $t('返回头部'),
|
||||
element: (
|
||||
<MessageDataGrid
|
||||
apiRef={headersRef}
|
||||
@@ -68,7 +69,7 @@ export function ApiResponseEditor({ editorRef ,apiInfo=null, loaded}: { editorRe
|
||||
dirty: false
|
||||
},
|
||||
{
|
||||
label: '返回值',
|
||||
label: $t('返回值'),
|
||||
element: <ApiMessageBody bodyApiRef={bodyRef} mode="response" apiInfo={apiInfo}
|
||||
loaded={innerLoaded} />,
|
||||
dirty: false
|
||||
@@ -93,7 +94,7 @@ export function ApiResponseEditor({ editorRef ,apiInfo=null, loaded}: { editorRe
|
||||
<Tabs
|
||||
value={tabValue}
|
||||
onChange={handleChange}
|
||||
aria-label="api request editor"
|
||||
aria-label={$t("api request editor")}
|
||||
sx={{
|
||||
minHeight: tabHeight,
|
||||
height: tabHeight,
|
||||
|
||||
+15
-15
@@ -42,6 +42,7 @@ import {collapseTableSx} from "../../../PreviewTable";
|
||||
import {IconButton} from "../../../IconButton";
|
||||
import {Icon} from "../../../Icon";
|
||||
import {useMoreSettingHiddenConfig} from "./hooks/useMoreSettingHiddenConfig.ts";
|
||||
import { $t } from '@common/locales/index.ts'
|
||||
|
||||
export interface RenderMessageBody extends BodyParamsType {
|
||||
path?: string[]
|
||||
@@ -251,14 +252,14 @@ export function MessageDataGrid(props: MessageDataGridProps<RenderMessageBody>)
|
||||
const getActions = useCallback(
|
||||
(params: GridRowParams<RenderMessageBody>) => {
|
||||
const actions = [
|
||||
<IconButton title="更多设置" name="more" onClick={() => handleOpenMoreSetting(params)} />
|
||||
<IconButton title={$t("更多设置")} name="more" onClick={() => handleOpenMoreSetting(params)} />
|
||||
]
|
||||
const isXML = contentType === 'XML'
|
||||
const isRoot = params.row.__globalIndex__ === 0
|
||||
if (['JSON', 'XML'].includes(contentType)) {
|
||||
actions.unshift(
|
||||
<IconButton
|
||||
title="添加子参数"
|
||||
title={$t("添加子参数")}
|
||||
name="add"
|
||||
onClick={() => {
|
||||
const newRow = EmptyRow()
|
||||
@@ -288,7 +289,7 @@ export function MessageDataGrid(props: MessageDataGridProps<RenderMessageBody>)
|
||||
if (!(isXML && isRoot)) {
|
||||
actions.unshift(
|
||||
<IconButton
|
||||
title="向下添加行"
|
||||
title={$t("向下添加行")}
|
||||
name="down-small"
|
||||
onClick={() => {
|
||||
const newRow = EmptyRow()
|
||||
@@ -301,7 +302,7 @@ export function MessageDataGrid(props: MessageDataGridProps<RenderMessageBody>)
|
||||
}
|
||||
}
|
||||
if (renderRows.length > 1) {
|
||||
actions.push(<IconButton title="删除" name="delete" onClick={() => handleRowDelete(params)} />)
|
||||
actions.push(<IconButton title={$t("删除")} name="delete" onClick={() => handleRowDelete(params)} />)
|
||||
}
|
||||
return actions
|
||||
},
|
||||
@@ -312,7 +313,7 @@ export function MessageDataGrid(props: MessageDataGridProps<RenderMessageBody>)
|
||||
const columns: (GridColDef<RenderMessageBody> | false)[] = [
|
||||
messageType === 'Header' && {
|
||||
field: 'name',
|
||||
headerName: '标签',
|
||||
headerName: $t('标签'),
|
||||
editable: true,
|
||||
sortable:false,
|
||||
renderEditCell: (params) => {
|
||||
@@ -340,7 +341,7 @@ export function MessageDataGrid(props: MessageDataGridProps<RenderMessageBody>)
|
||||
},
|
||||
messageType !== 'Header' && {
|
||||
field: 'name',
|
||||
headerName: '参数名',
|
||||
headerName: $t('参数名'),
|
||||
width: 200,
|
||||
editable: true,
|
||||
sortable: false,
|
||||
@@ -373,7 +374,7 @@ export function MessageDataGrid(props: MessageDataGridProps<RenderMessageBody>)
|
||||
<TextField
|
||||
fullWidth
|
||||
value={params.value}
|
||||
placeholder='参数名'
|
||||
placeholder={$t('参数名')}
|
||||
onChange={(e) => {
|
||||
const newValue = e.target.value as string
|
||||
const rowIndex = params.row.__globalIndex__
|
||||
@@ -395,7 +396,7 @@ export function MessageDataGrid(props: MessageDataGridProps<RenderMessageBody>)
|
||||
},
|
||||
messageType === 'Body' && {
|
||||
field: 'dataType',
|
||||
headerName: '类型',
|
||||
headerName: $t('类型'),
|
||||
sortable: false,
|
||||
width: 120,
|
||||
type: 'singleSelect',
|
||||
@@ -429,7 +430,7 @@ export function MessageDataGrid(props: MessageDataGridProps<RenderMessageBody>)
|
||||
},
|
||||
{
|
||||
field: 'isRequired',
|
||||
headerName: '必需',
|
||||
headerName: $t('必需'),
|
||||
headerAlign: 'left',
|
||||
sortable: false,
|
||||
type: 'boolean',
|
||||
@@ -443,7 +444,7 @@ export function MessageDataGrid(props: MessageDataGridProps<RenderMessageBody>)
|
||||
indeterminate={selectAll === 'indeterminate'}
|
||||
onChange={handleSelectAllChange}
|
||||
/>
|
||||
<Typography sx={{fontSize:'14px'}}>必需</Typography>
|
||||
<Typography sx={{fontSize:'14px'}}>{$t('必需')}</Typography>
|
||||
</Box>
|
||||
)
|
||||
},
|
||||
@@ -463,7 +464,7 @@ export function MessageDataGrid(props: MessageDataGridProps<RenderMessageBody>)
|
||||
},
|
||||
{
|
||||
field: 'description',
|
||||
headerName: '描述',
|
||||
headerName: $t('描述'),
|
||||
sortable: false,
|
||||
flex: 1,
|
||||
minWidth: 200,
|
||||
@@ -484,7 +485,7 @@ export function MessageDataGrid(props: MessageDataGridProps<RenderMessageBody>)
|
||||
paddingRight: theme.spacing(1)
|
||||
}
|
||||
}}
|
||||
placeholder='描述'
|
||||
placeholder={$t('描述')}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -492,7 +493,7 @@ export function MessageDataGrid(props: MessageDataGridProps<RenderMessageBody>)
|
||||
{
|
||||
field: 'paramAttr',
|
||||
sortable: false,
|
||||
headerName: '示例',
|
||||
headerName: $t('示例'),
|
||||
flex: 1,
|
||||
minWidth: 200,
|
||||
editable: true,
|
||||
@@ -515,8 +516,7 @@ export function MessageDataGrid(props: MessageDataGridProps<RenderMessageBody>)
|
||||
paddingRight: theme.spacing(1)
|
||||
}
|
||||
}}
|
||||
placeholder='示例'
|
||||
/>
|
||||
placeholder={$t('示例')} />
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
+2
-1
@@ -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 (
|
||||
<TextField
|
||||
fullWidth
|
||||
placeholder="输入 URL 或 cURL"
|
||||
placeholder={$t("输入 URL 或 cURL")}
|
||||
value={inputValue}
|
||||
onChange={handleInputChange}
|
||||
sx={{
|
||||
|
||||
+2
-1
@@ -2,6 +2,7 @@
|
||||
import { Box, Chip, Stack, Typography, Skeleton } from '@mui/material'
|
||||
import {HTTPMethod, Protocol,RequestMethod} from "../../../RequestMethod";
|
||||
import {Clipboard} from "../../../Clipboard"
|
||||
import { $t } from '@common/locales';
|
||||
|
||||
interface ApiBasicInfoDisplayProps {
|
||||
apiName: string
|
||||
@@ -38,7 +39,7 @@ export default function ApiBasicInfoDisplay(props: Partial<ApiBasicInfoDisplayPr
|
||||
<Box display="flex">
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<Chip
|
||||
label="HTTP"
|
||||
label={$t("HTTP")}
|
||||
sx={{
|
||||
height:'22px',
|
||||
borderRadius: '4px',
|
||||
|
||||
+5
-4
@@ -6,6 +6,7 @@ import {collapseTableSx, previewTableHoverSx} from "../../../PreviewTable";
|
||||
import {Collapse} from "../../../Collapse";
|
||||
import { MatchPositionEnum, MatchTypeEnum } from "@core/const/system/const";
|
||||
import { MatchItem } from "@common/const/type";
|
||||
import { $t } from "@common/locales";
|
||||
|
||||
interface ApiMatchProps {
|
||||
rows?: MatchItem[]
|
||||
@@ -29,25 +30,25 @@ export default function ApiMatch({ rows = [], title, loading = false }: ApiMatch
|
||||
const columns: GridColDef<MatchItem>[] = [
|
||||
{
|
||||
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
|
||||
}
|
||||
]
|
||||
|
||||
+10
-9
@@ -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<ProxyHeaderItem>[] = [
|
||||
{
|
||||
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'},
|
||||
}]:[])
|
||||
|
||||
+5
-4
@@ -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<HeaderParamsType>[] = [
|
||||
{
|
||||
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) => [
|
||||
<PreviewGridActionsCellItem
|
||||
icon="more"
|
||||
label="More"
|
||||
label={$t("More")}
|
||||
key="more"
|
||||
onClick={() => onMoreSettingChange?.(params.row as unknown as RenderMessageBody)}
|
||||
/>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ import { TextField } from '@mui/material'
|
||||
export function PreviewBodyBinary({ value }: { value: string;}) {
|
||||
return (
|
||||
<TextField
|
||||
label="Binary"
|
||||
label={$t("Binary")}
|
||||
multiline
|
||||
disabled={true}
|
||||
rows={4}
|
||||
|
||||
+7
-6
@@ -6,6 +6,7 @@ import {collapseTableSx, PreviewGridActionsCellItem, previewTableHoverSx} from "
|
||||
import {Collapse} from "../../../Collapse";
|
||||
import { PreviewBodyBinary } from './components/Binary';
|
||||
import { PreviewBodyRaw } from './components/Raw';
|
||||
import { $t } from '@common/locales';
|
||||
|
||||
export interface RenderMessageBody extends BodyParamsType {
|
||||
path: string[]
|
||||
@@ -50,13 +51,13 @@ export default function MessageBodyComponent({
|
||||
const columns: GridColDef<RenderMessageBody>[] = [
|
||||
{
|
||||
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) => [
|
||||
<PreviewGridActionsCellItem
|
||||
icon="more"
|
||||
label="More"
|
||||
label={$t("More")}
|
||||
key="more"
|
||||
onClick={() => 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,
|
||||
|
||||
+5
-4
@@ -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<QueryParamsType>[] = [
|
||||
{
|
||||
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) => [
|
||||
<PreviewGridActionsCellItem
|
||||
icon="more"
|
||||
label="More"
|
||||
label={$t("More")}
|
||||
key="more"
|
||||
onClick={() => onMoreSettingChange?.(params.row as unknown as RenderMessageBody)}
|
||||
/>
|
||||
|
||||
+7
-6
@@ -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 (
|
||||
<>
|
||||
<IconButton name="import" sx={{ height: '30px' }} onClick={() => setOpen(true)} variant="outlined">
|
||||
导入
|
||||
{$t('导入')}
|
||||
</IconButton>
|
||||
<BaseDialog open={open} onClose={() => setOpen(false)} actionRender={null} title={`Import ${type}`}>
|
||||
<DialogContent sx={{ paddingTop: 0, minWidth: '800px' }}>
|
||||
@@ -74,7 +75,7 @@ export function ImportMessage({ type, onChange }: ImportMessageDialogProps) {
|
||||
<Paper elevation={0} sx={{ padding: 2, bgcolor: theme.palette.grey[200] }}>
|
||||
<Typography component="div" sx={{ display: 'flex', alignItems: 'center' }}>
|
||||
<Icon name="attention" mx={0} px={0} sx={{ display: 'inline-flex', marginRight: 0.5 }} />
|
||||
导入格式
|
||||
{$t('导入格式')}
|
||||
</Typography>
|
||||
<Typography variant="body2" component="div">
|
||||
<pre>{example}</pre>
|
||||
@@ -86,16 +87,16 @@ export function ImportMessage({ type, onChange }: ImportMessageDialogProps) {
|
||||
</DialogContent>
|
||||
<Box display="flex" p={3} pt={0} gap={2} justifyContent="flex-end">
|
||||
<Button variant="outlined" onClick={() => setOpen(false)}>
|
||||
取消
|
||||
{$t('取消')}
|
||||
</Button>
|
||||
<Button variant="outlined" onClick={() => handleChange('replace-all')}>
|
||||
全量替换
|
||||
{$t('全量替换')}
|
||||
</Button>
|
||||
<Button variant="outlined" onClick={() => handleChange('insert-end')}>
|
||||
在末端插入
|
||||
{$t('在末端插入')}
|
||||
</Button>
|
||||
<Button variant="contained" onClick={() => handleChange('replace-changed')}>
|
||||
增量更新
|
||||
{$t('增量更新')}
|
||||
</Button>
|
||||
</Box>
|
||||
</BaseDialog>
|
||||
|
||||
+7
-7
@@ -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'
|
||||
}
|
||||
]
|
||||
+7
-6
@@ -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: (
|
||||
<TestMessageDataGrid
|
||||
apiRef={headersApiRef}
|
||||
@@ -131,12 +132,12 @@ export function ApiRequestTester({ apiRef, onQueryChange ,apiInfo, loaded=true}:
|
||||
dirty: false
|
||||
},
|
||||
{
|
||||
label: '请求体',
|
||||
label: $t('请求体'),
|
||||
element: <TestBody bodyApiRef={bodyApiRef} onContentTypeChange={handleContentTypeChange} />,
|
||||
dirty: false
|
||||
},
|
||||
{
|
||||
label: 'Query 参数',
|
||||
label: $t('Query 参数'),
|
||||
element: (
|
||||
<TestMessageDataGrid
|
||||
apiRef={queryApiRef}
|
||||
@@ -150,7 +151,7 @@ export function ApiRequestTester({ apiRef, onQueryChange ,apiInfo, loaded=true}:
|
||||
dirty: false
|
||||
},
|
||||
{
|
||||
label: 'Rest 参数',
|
||||
label: $t('Rest 参数'),
|
||||
element: <TestMessageDataGrid apiRef={restApiRef} initialRows={apiRest} messageType="REST" />,
|
||||
dirty: false
|
||||
}
|
||||
|
||||
+4
-3
@@ -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
|
||||
<Box gap={2} px={1} display="flex" alignItems="center">
|
||||
<Chip label={<Typography>{statusCode}</Typography>} />
|
||||
<Typography>
|
||||
大小: {byteToString(size || 0)}
|
||||
{$t('大小')}: {byteToString(size || 0)}
|
||||
</Typography>
|
||||
<Typography>
|
||||
时间: {time} ms
|
||||
{$t('时间')}: {time} ms
|
||||
</Typography>
|
||||
<IconButton name="download" title='另存为文件' onClick={onDownload} />
|
||||
<IconButton name="download" title={$t('另存为文件')} onClick={onDownload} />
|
||||
</Box>
|
||||
) : null
|
||||
}
|
||||
|
||||
+8
-7
@@ -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<TabType>('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: <HeaderPreview data={response?.headers || []} />
|
||||
},
|
||||
{
|
||||
title:'正文',
|
||||
title:$t('正文'),
|
||||
name: 'Body',
|
||||
hidden: !request?.body.length,
|
||||
element: <Body data={request?.body} />
|
||||
},
|
||||
{
|
||||
title: '请求头',
|
||||
title: $t('请求头'),
|
||||
name: 'Request Headers',
|
||||
hidden: !request?.headers.length,
|
||||
element: <HeaderPreview data={request?.headers || []} />
|
||||
|
||||
+4
-3
@@ -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 ? (
|
||||
<Button touchRippleRef={testRippleRef} variant="contained" onClick={onTest}>
|
||||
发送(Enter)
|
||||
{$t('发送(Enter)')}
|
||||
</Button>
|
||||
) : (
|
||||
<Button variant="outlined" color="warning" onClick={onAbort}>
|
||||
<Typography>中止</Typography>
|
||||
<Typography>{$t('中止')}</Typography>
|
||||
{loadingTime ? (
|
||||
<Typography sx={{ paddingLeft: 1 }}>
|
||||
{' '}
|
||||
({loadingTime} {'秒'}){' '}
|
||||
({loadingTime} {$t('秒')}){' '}
|
||||
</Typography>
|
||||
) : null}
|
||||
</Button>
|
||||
|
||||
+5
-4
@@ -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<BodyParamsTy
|
||||
const columns: (GridColDef<RenderBodyParamsType> | false)[] = [
|
||||
messageType === 'Headers' && {
|
||||
field: 'name',
|
||||
headerName: '标签',
|
||||
headerName: $t('标签'),
|
||||
editable: true,
|
||||
sortable: false,
|
||||
renderEditCell: (params) => {
|
||||
@@ -214,7 +215,7 @@ export function TestMessageDataGrid(props: TestMessageDataGridProps<BodyParamsTy
|
||||
},
|
||||
messageType !== 'Headers' && {
|
||||
field: 'name',
|
||||
headerName:'参数名',
|
||||
headerName:$t('参数名'),
|
||||
width: 200,
|
||||
editable: true,
|
||||
sortable: false,
|
||||
@@ -244,7 +245,7 @@ export function TestMessageDataGrid(props: TestMessageDataGridProps<BodyParamsTy
|
||||
},
|
||||
messageType === 'Body' && {
|
||||
field: 'dataType',
|
||||
headerName: '类型',
|
||||
headerName: $t('类型'),
|
||||
sortable: false,
|
||||
width: 120,
|
||||
type: 'singleSelect',
|
||||
@@ -286,7 +287,7 @@ export function TestMessageDataGrid(props: TestMessageDataGridProps<BodyParamsTy
|
||||
{
|
||||
field: 'paramAttr',
|
||||
sortable: false,
|
||||
headerName: '参数值',
|
||||
headerName: $t('参数值'),
|
||||
flex: 1,
|
||||
minWidth: 200,
|
||||
editable: true,
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { ReactNode } from 'react'
|
||||
import { Box } from '@mui/material'
|
||||
import { IconButton } from '../IconButton'
|
||||
import useCopyToClipboard from "@common/hooks/copy.ts";
|
||||
import { $t } from '@common/locales';
|
||||
|
||||
export interface ClipboardProps {
|
||||
text: string
|
||||
@@ -14,7 +15,7 @@ export interface ClipboardProps {
|
||||
|
||||
export function Clipboard(props: ClipboardProps): JSX.Element {
|
||||
const { text, children, onError, onSuccess } = props
|
||||
const DefaultText = '复制'
|
||||
const DefaultText = $t('复制')
|
||||
const [buttonTitle, setButtonTitle] = useState(DefaultText)
|
||||
const { copyToClipboard } = useCopyToClipboard();
|
||||
const handleCopy = (): void => {
|
||||
|
||||
@@ -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<void> => {
|
||||
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}
|
||||
|
||||
<IconButton name="code" onClick={formatCode} sx={{color:'#333',transition:'none','&.MuiButtonBase-root:hover':{background:'transparent',color:'#3D46F2',transition:'none'}}}>
|
||||
格式化
|
||||
{$t('格式化')}
|
||||
</IconButton>
|
||||
<IconButton name="copy" onClick={copyCode} sx={{color:'#333',transition:'none','&.MuiButtonBase-root:hover':{background:'transparent',color:'#3D46F2',transition:'none'}}}>
|
||||
复制
|
||||
{$t('复制')}
|
||||
</IconButton>
|
||||
<IconButton name="search" onClick={searchInCode} sx={{color:'#333',transition:'none','&.MuiButtonBase-root:hover':{background:'transparent',color:'#3D46F2',transition:'none'}}}>
|
||||
搜索
|
||||
{$t('搜索')}
|
||||
</IconButton>
|
||||
{!readOnly &&<IconButton name="file-text" onClick={replaceInCode} sx={{color:'#333',transition:'none','&.MuiButtonBase-root:hover':{background:'transparent',color:'#3D46F2',transition:'none'}}}>
|
||||
替代
|
||||
{$t('替代')}
|
||||
</IconButton>}
|
||||
</Box></>
|
||||
) : null}
|
||||
|
||||
@@ -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,
|
||||
|
||||
+2
-1
@@ -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) {
|
||||
}}
|
||||
>
|
||||
<Typography fontSize={14} px={'12px'}>
|
||||
示例
|
||||
{$t('示例')}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Codebox
|
||||
|
||||
+4
-3
@@ -1,6 +1,7 @@
|
||||
|
||||
import { ChangeEvent, useEffect, useState } from 'react'
|
||||
import { FormControl, TextField, Box } from '@mui/material'
|
||||
import { $t } from '@common/locales';
|
||||
|
||||
interface ParamLimitProps {
|
||||
min: number | null
|
||||
@@ -17,15 +18,15 @@ export function ParamLimit({ min, max, onChange, minLabel = 'Minimum', maxLabel
|
||||
|
||||
const validate = (minVal: number, maxVal: number) => {
|
||||
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
|
||||
|
||||
+5
-4
@@ -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
|
||||
}
|
||||
]
|
||||
|
||||
+6
-5
@@ -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<Row>[] = [
|
||||
{
|
||||
field: 'value',
|
||||
headerName: '值枚举',
|
||||
headerName: $t('值枚举'),
|
||||
type: 'string',
|
||||
sortable: false,
|
||||
flex: 1,
|
||||
@@ -109,7 +110,7 @@ export function ValueEnum({ data, apiRef,readOnly = false }: ValueEnumProps) {
|
||||
<TextField
|
||||
fullWidth
|
||||
value={params.value}
|
||||
placeholder='枚举'
|
||||
placeholder={$t('枚举')}
|
||||
sx={{
|
||||
input: {
|
||||
paddingLeft: `${theme.spacing(1)} !important`,
|
||||
@@ -132,7 +133,7 @@ export function ValueEnum({ data, apiRef,readOnly = false }: ValueEnumProps) {
|
||||
},
|
||||
{
|
||||
field: 'description',
|
||||
headerName: '描述',
|
||||
headerName: $t('描述'),
|
||||
type: 'string',
|
||||
sortable: false,
|
||||
flex: 1,
|
||||
@@ -154,7 +155,7 @@ export function ValueEnum({ data, apiRef,readOnly = false }: ValueEnumProps) {
|
||||
paddingRight: `${theme.spacing(1)} !important`
|
||||
}
|
||||
}}
|
||||
placeholder='示例'
|
||||
placeholder={$t('示例')}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -170,7 +171,7 @@ export function ValueEnum({ data, apiRef,readOnly = false }: ValueEnumProps) {
|
||||
if (renderRows.length <= 1) return []
|
||||
return [
|
||||
<IconButton
|
||||
title='删除'
|
||||
title={$t('删除')}
|
||||
name="delete"
|
||||
onClick={() => {
|
||||
handleRowDelete(params)
|
||||
|
||||
@@ -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 (
|
||||
<BaseDialog open={open} onClose={onClose} title='更多设置' onConfirm={handleConfirm}>
|
||||
<BaseDialog open={open} onClose={onClose} title={$t('更多设置')} onConfirm={handleConfirm}>
|
||||
<Box px={2} pb={2} width={880}>
|
||||
<Stack spacing={2}>
|
||||
<ParamPreview
|
||||
@@ -90,8 +91,8 @@ export function MoreSetting({ open, readOnly,onClose, param, onChange, hiddenCon
|
||||
<ParamLimit
|
||||
min={param?.paramAttr?.minLength ?? 0}
|
||||
max={param?.paramAttr?.maxLength ?? 0}
|
||||
minLabel='最小长度'
|
||||
maxLabel='最大长度'
|
||||
minLabel={$t('最小长度')}
|
||||
maxLabel={$t('最大长度')}
|
||||
onChange={handleParamLengthChange}
|
||||
/>
|
||||
) : null}
|
||||
@@ -99,8 +100,8 @@ export function MoreSetting({ open, readOnly,onClose, param, onChange, hiddenCon
|
||||
<ParamLimit
|
||||
min={param?.paramAttr?.minValue ?? 0}
|
||||
max={param?.paramAttr?.maxValue ?? 0}
|
||||
minLabel='最小值'
|
||||
maxLabel='最大值'
|
||||
minLabel={$t('最小值')}
|
||||
maxLabel={$t('最大值')}
|
||||
onChange={handleParamValueChange}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
@@ -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 {
|
||||
<Box>
|
||||
<Icon size="30px" name="link-cloud" />
|
||||
</Box>
|
||||
<Typography>{'将文件拖拽至此处上传,或点击选择文件上传'}</Typography>
|
||||
<Typography>{$t('将文件拖拽至此处上传,或点击选择文件上传')}</Typography>
|
||||
</Paper>
|
||||
{value ? (
|
||||
<Box>
|
||||
|
||||
@@ -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
|
||||
<Box display="flex" alignItems="center">
|
||||
<input multiple type="file" ref={fileInputRef} style={{ display: 'none' }} onChange={handleFileChange} />
|
||||
<Button variant="outlined" color="primary" onClick={handleButtonClick}>
|
||||
Upload Files
|
||||
{$t('Upload Files')}
|
||||
</Button>
|
||||
{value?.length ? <Typography sx={{ marginLeft: 1 }}>Files Selected: {value.length}</Typography> : null}
|
||||
{value?.length ? <Typography sx={{ marginLeft: 1 }}>{$t('Files Selected')}: {value.length}</Typography> : null}
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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]',
|
||||
|
||||
@@ -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<ApprovalTableListItem>[] = [
|
||||
export const SUBSCRIBE_APPROVAL_TABLE_COLUMN : PageProColumns<ApprovalTableListItem>[] = [
|
||||
{
|
||||
title: '申请时间',
|
||||
title:$t('申请时间'),
|
||||
dataIndex: 'applyTime',
|
||||
ellipsis:true,
|
||||
width:182,
|
||||
@@ -17,44 +18,44 @@ export const SUBSCRIBE_APPROVAL_TABLE_COLUMN : ProColumns<ApprovalTableListItem>
|
||||
},
|
||||
},
|
||||
{
|
||||
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<ApprovalTableListItem>
|
||||
},
|
||||
];
|
||||
|
||||
export const SUBSCRIBE_APPROVAL_INNER_TODO_TABLE_COLUMN : ProColumns<SubscribeApprovalTableListItem>[] = [
|
||||
export const SUBSCRIBE_APPROVAL_INNER_TODO_TABLE_COLUMN : PageProColumns<SubscribeApprovalTableListItem>[] = [
|
||||
{
|
||||
title: '申请时间',
|
||||
title:$t('申请时间'),
|
||||
dataIndex: 'applyTime',
|
||||
// sorter: true,
|
||||
ellipsis:true,
|
||||
@@ -78,13 +79,13 @@ export const SUBSCRIBE_APPROVAL_INNER_TODO_TABLE_COLUMN : ProColumns<SubscribeAp
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '申请方-应用',
|
||||
title:$t('申请方-应用'),
|
||||
dataIndex: ['application','name'],
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
// title: '申请人',
|
||||
title: <Tooltip title="申请人" >申请人</Tooltip>,
|
||||
// title:$t('申请人',
|
||||
title: <Tooltip title={$t("申请人")} >{$t('申请人')}</Tooltip>,
|
||||
dataIndex: ['applier','name'],
|
||||
ellipsis: true,
|
||||
filters: true,
|
||||
@@ -93,16 +94,16 @@ export const SUBSCRIBE_APPROVAL_INNER_TODO_TABLE_COLUMN : ProColumns<SubscribeAp
|
||||
filterSearch: true
|
||||
},
|
||||
{
|
||||
title: '申请服务',
|
||||
title:$t('申请服务'),
|
||||
dataIndex: ['service','name'],
|
||||
ellipsis:true
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
export const SUBSCRIBE_APPROVAL_INNER_DONE_TABLE_COLUMN : ProColumns<SubscribeApprovalTableListItem>[] = [
|
||||
export const SUBSCRIBE_APPROVAL_INNER_DONE_TABLE_COLUMN : PageProColumns<SubscribeApprovalTableListItem>[] = [
|
||||
{
|
||||
title: '申请时间',
|
||||
title:$t('申请时间'),
|
||||
dataIndex: 'applyTime',
|
||||
// sorter: true,
|
||||
ellipsis:true,
|
||||
@@ -113,13 +114,13 @@ export const SUBSCRIBE_APPROVAL_INNER_DONE_TABLE_COLUMN : ProColumns<SubscribeAp
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '申请方-应用',
|
||||
title:$t('申请方-应用'),
|
||||
dataIndex: ['application','name'],
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
// title: '申请人',
|
||||
title: <Tooltip title="申请人" >申请人</Tooltip>,
|
||||
// title:$t('申请人',
|
||||
title: <Tooltip title={$t("申请人")} >{$t('申请人')}</Tooltip>,
|
||||
dataIndex: ['applier','name'],
|
||||
ellipsis: true,
|
||||
filters: true,
|
||||
@@ -128,24 +129,24 @@ export const SUBSCRIBE_APPROVAL_INNER_DONE_TABLE_COLUMN : ProColumns<SubscribeAp
|
||||
filterSearch: true,
|
||||
},
|
||||
{
|
||||
title: '申请服务',
|
||||
title:$t('申请服务'),
|
||||
dataIndex: ['service','name'],
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '审批状态',
|
||||
title:$t('审批状态'),
|
||||
dataIndex: 'status',
|
||||
valueType: 'select',
|
||||
ellipsis: true,
|
||||
filters: true,
|
||||
onFilter: true,
|
||||
valueEnum: new Map([
|
||||
[0, <span className="text-status_fail">拒绝</span>],
|
||||
[2,<span className="text-status_success">通过</span>],
|
||||
[0, <span className="text-status_fail">{$t('拒绝')}</span>],
|
||||
[2,<span className="text-status_success">{$t('通过')}</span>],
|
||||
]),
|
||||
},
|
||||
{
|
||||
title: '审批人',
|
||||
title:$t('审批人'),
|
||||
dataIndex: ['approver','name'],
|
||||
ellipsis: true,
|
||||
width:88,
|
||||
@@ -155,7 +156,7 @@ export const SUBSCRIBE_APPROVAL_INNER_DONE_TABLE_COLUMN : ProColumns<SubscribeAp
|
||||
filterSearch: true,
|
||||
},
|
||||
{
|
||||
title: '审批时间',
|
||||
title:$t('审批时间'),
|
||||
dataIndex: 'approvalTime',
|
||||
ellipsis: true,
|
||||
// sorter: true,,
|
||||
@@ -179,17 +180,17 @@ export type SubscribeApprovalTableListItem = {
|
||||
};
|
||||
|
||||
|
||||
export enum PublishApplyStatusEnum{
|
||||
'accept'="审批完成",
|
||||
'apply'="发布审批中",
|
||||
'running'="在线",
|
||||
'none'="-",
|
||||
'refuse'="已拒绝",
|
||||
export const PublishApplyStatusEnum = {
|
||||
'accept': $t("审批完成"),
|
||||
'apply': $t("发布审批中"),
|
||||
'running': $t("在线"),
|
||||
'none': $t("-"),
|
||||
'refuse': $t("已拒绝"),
|
||||
// eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
|
||||
'close' = '-',
|
||||
'stop' = '中止',
|
||||
'error' = '发布异常',
|
||||
'publishing' = '发布中'
|
||||
'close' : $t('-'),
|
||||
'stop' : $t('中止'),
|
||||
'error' : $t('发布异常'),
|
||||
'publishing' : $t('发布中')
|
||||
}
|
||||
|
||||
|
||||
@@ -209,33 +210,99 @@ export const PublishTableStatusColorClass = {
|
||||
'publishing':'text-[#46BE11]',
|
||||
}
|
||||
|
||||
export const ApprovalStatusColorClass = {
|
||||
new: 'text-[#138913]', // 使用 Tailwind 的 Arbitrary Properties
|
||||
update: 'text-[#03a9f4]',
|
||||
delete: 'text-[#ff3b30]',
|
||||
none: 'text-[var(--MAIN_TEXT)]', // 假设你也有一个“none”的状态
|
||||
};
|
||||
|
||||
enum PublishStatusEnum{
|
||||
'apply' = '待审批',
|
||||
'accept' = '审批通过',
|
||||
'done' = '已发布',
|
||||
'stop' = '发布终止',
|
||||
'close' = '已关闭',
|
||||
'refuse' = '已拒绝',
|
||||
'error' = '发布异常',
|
||||
'publishing' = '发布中'
|
||||
|
||||
|
||||
export const ApprovalApiColumns = [
|
||||
{
|
||||
title:$t('API 名称'),
|
||||
dataIndex:'name',
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title:$t('请求方式'),
|
||||
dataIndex:'method',
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title:$t('路径'),
|
||||
dataIndex:'path',
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title:$t('类型'),
|
||||
dataIndex:'change',
|
||||
render:(_,entity)=>(
|
||||
<Tooltip placement="top" title={entity.change === 'error' ?$t('该 API 缺失(0)(1)(2)请先补充',[entity.proxyStatus == 1 && $t('转发信息,'),entity.docStatus == 1 && $t('文档信息,'),entity.upstreamStatus == 1 && $t('上游信息,')]):''}>
|
||||
<span className={`${ApprovalStatusColorClass[entity.change as keyof typeof ApprovalStatusColorClass]} truncate block`}>
|
||||
{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('上游信息,')]):''}
|
||||
</span>
|
||||
</Tooltip>)
|
||||
|
||||
}
|
||||
]
|
||||
|
||||
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)=>(
|
||||
<Tooltip placement="top" title={entity.change === 'error' ? $t('该 API 缺失(0)(1)(2)请先补充',[entity.proxyStatus == 1 && $t('转发信息,'),entity.docStatus == 1 && $t('文档信息,'),entity.upstreamStatus == 1 && $t('上游信息,')]):''}>
|
||||
<span className={`${ApprovalStatusColorClass[entity.change as keyof typeof ApprovalStatusColorClass]} truncate block`}>{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('上游信息,')]):''}</span>
|
||||
</Tooltip>)
|
||||
}
|
||||
]
|
||||
|
||||
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<PublishTableListItem>[] = [
|
||||
export const PUBLISH_APPROVAL_VERSION_INNER_TABLE_COLUMN : PageProColumns<PublishTableListItem>[] = [
|
||||
{
|
||||
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<PublishTab
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '版本状态',
|
||||
title:$t('版本状态'),
|
||||
dataIndex: 'status',
|
||||
ellipsis:true,
|
||||
filters: true,
|
||||
@@ -260,7 +327,7 @@ export const PUBLISH_APPROVAL_VERSION_INNER_TABLE_COLUMN : ProColumns<PublishTab
|
||||
])
|
||||
},
|
||||
{
|
||||
title: '创建人',
|
||||
title:$t('创建人'),
|
||||
dataIndex: ['creator','name'],
|
||||
ellipsis: true,
|
||||
width:88,
|
||||
@@ -271,32 +338,32 @@ export const PUBLISH_APPROVAL_VERSION_INNER_TABLE_COLUMN : ProColumns<PublishTab
|
||||
}
|
||||
];
|
||||
|
||||
export const PUBLISH_APPROVAL_RECORD_INNER_TABLE_COLUMN : ProColumns<PublishTableListItem>[] = [
|
||||
export const PUBLISH_APPROVAL_RECORD_INNER_TABLE_COLUMN : PageProColumns<PublishTableListItem>[] = [
|
||||
{
|
||||
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<PublishTabl
|
||||
])
|
||||
},
|
||||
{
|
||||
title: '备注',
|
||||
title:$t('备注'),
|
||||
dataIndex: 'comments',
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '申请人',
|
||||
title:$t('申请人'),
|
||||
dataIndex: ['applicant','name'],
|
||||
ellipsis: true,
|
||||
width:88,
|
||||
@@ -326,7 +393,7 @@ export const PUBLISH_APPROVAL_RECORD_INNER_TABLE_COLUMN : ProColumns<PublishTabl
|
||||
filterSearch: true,
|
||||
},
|
||||
{
|
||||
title: '审批人',
|
||||
title:$t('审批人'),
|
||||
dataIndex: ['approver','name'],
|
||||
ellipsis: true,
|
||||
width:88,
|
||||
@@ -337,9 +404,9 @@ export const PUBLISH_APPROVAL_RECORD_INNER_TABLE_COLUMN : ProColumns<PublishTabl
|
||||
},
|
||||
];
|
||||
|
||||
export const PUBLISH_APPROVAL_TABLE_COLUMN : ProColumns<ApprovalTableListItem>[] = [
|
||||
export const PUBLISH_APPROVAL_TABLE_COLUMN : PageProColumns<ApprovalTableListItem>[] = [
|
||||
{
|
||||
title: '申请时间',
|
||||
title:$t('申请时间'),
|
||||
dataIndex: 'applyTime',
|
||||
ellipsis:true,
|
||||
width:182,
|
||||
@@ -349,17 +416,17 @@ export const PUBLISH_APPROVAL_TABLE_COLUMN : ProColumns<ApprovalTableListItem>[]
|
||||
},
|
||||
},
|
||||
{
|
||||
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<ApprovalTableListItem>[]
|
||||
valueType: 'select',
|
||||
},
|
||||
{
|
||||
title: '申请人',
|
||||
title:$t('申请人'),
|
||||
dataIndex: ['applier','name'],
|
||||
ellipsis: true,
|
||||
width:88,
|
||||
@@ -379,7 +446,7 @@ export const PUBLISH_APPROVAL_TABLE_COLUMN : ProColumns<ApprovalTableListItem>[]
|
||||
filterSearch: true,
|
||||
},
|
||||
{
|
||||
title: '审批人',
|
||||
title:$t('审批人'),
|
||||
dataIndex: ['approver','name'],
|
||||
ellipsis: true,
|
||||
width:88,
|
||||
@@ -389,7 +456,7 @@ export const PUBLISH_APPROVAL_TABLE_COLUMN : ProColumns<ApprovalTableListItem>[]
|
||||
filterSearch: true,
|
||||
},
|
||||
{
|
||||
title: '审批时间',
|
||||
title:$t('审批时间'),
|
||||
dataIndex: 'approvalTime',
|
||||
// sorter: true,
|
||||
ellipsis:true,
|
||||
@@ -400,3 +467,42 @@ export const PUBLISH_APPROVAL_TABLE_COLUMN : ProColumns<ApprovalTableListItem>[]
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
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'
|
||||
}
|
||||
]
|
||||
@@ -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<boolean|string>
|
||||
publish:(notSave?:boolean)=>Promise<boolean|string|Record<string, unknown>>
|
||||
online:()=>Promise<boolean|string>
|
||||
}
|
||||
@@ -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
|
||||
},
|
||||
// {
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
|
||||
export type BasicResponse<T> = {
|
||||
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
|
||||
@@ -0,0 +1,71 @@
|
||||
import { $t } from "@common/locales"
|
||||
|
||||
export type BasicResponse<T> = {
|
||||
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<string, string[]|string>([
|
||||
['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('该数据删除后将无法找回,请确认是否删除?')
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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<Action>;
|
||||
dispatch: Dispatch<GlobalAction>;
|
||||
accessData:Map<string,string[]>;
|
||||
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<Map<string,string[]>>(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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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<void>((resolve, reject) => {
|
||||
if(document.execCommand('copy')) {
|
||||
message.success('复制成功')
|
||||
message.success(RESPONSE_TIPS.copySuccess)
|
||||
setIsCopied(true)
|
||||
resolve()
|
||||
} else {
|
||||
|
||||
@@ -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 = <T>() => {
|
||||
|
||||
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 = <T>() => {
|
||||
|
||||
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 => {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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": "缩小"
|
||||
}
|
||||
@@ -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": "缩小"
|
||||
}
|
||||
@@ -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": "缩小"
|
||||
}
|
||||
@@ -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": "缩小"
|
||||
}
|
||||
@@ -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';
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { MenuProps } from "antd";
|
||||
|
||||
import { MenuItem } from "@common/components/aoplatform/Navigation";
|
||||
|
||||
export type MenuItem = Required<MenuProps>['items'][number];
|
||||
|
||||
export function getNavItem(
|
||||
label: React.ReactNode,
|
||||
|
||||
@@ -251,7 +251,7 @@ import { TopologyProjectItem, TopologyServiceItem } from "@core/pages/systemRun
|
||||
// },
|
||||
// defaultEdge: {
|
||||
// type: 'line-running',
|
||||
// label: '详情',
|
||||
// label: $t('详情',
|
||||
// labelCfg: {
|
||||
// style: {
|
||||
// fill: '5B8FF9',
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
@@ -10,7 +10,7 @@
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
<script src="/frontend/iconpark_eolink.js"></script>
|
||||
<script src="/frontend/iconpark_apinto.js"></script>
|
||||
<script async src="/frontend/iconpark_eolink.js"></script>
|
||||
<script async src="/frontend/iconpark_apinto.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -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%);
|
||||
|
||||
@@ -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<Locale>(enUS);
|
||||
useInitializeMonaco()
|
||||
const { state} = useGlobalContext()
|
||||
|
||||
useEffect(() => {
|
||||
console.log(state.language)
|
||||
dayjs.locale(state.language);
|
||||
setLocal(state.language === 'cn' ? zhCN : enUS);
|
||||
},[state.language])
|
||||
|
||||
|
||||
return (
|
||||
<StyleProvider hashPriority={"high"}>
|
||||
<ConfigProvider
|
||||
locale={zhCN}
|
||||
locale={locale}
|
||||
wave={{disabled:true}}
|
||||
theme={antdComponentThemeToken}>
|
||||
<BreadcrumbProvider>
|
||||
|
||||
@@ -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:<p>设计中</p>,
|
||||
|
||||
@@ -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<MemberTableListItem>[] = [
|
||||
export const MEMBER_TABLE_COLUMNS: PageProColumns<MemberTableListItem>[] = [
|
||||
{
|
||||
title: '用户名',
|
||||
title:$t('用户名'),
|
||||
dataIndex: 'name',
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
@@ -15,12 +16,12 @@ export const MEMBER_TABLE_COLUMNS: ProColumns<MemberTableListItem>[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
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<MemberTableListItem>[] = [
|
||||
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,<span className="text-status_success">启用</span>],
|
||||
[false,<span className="text-status_fail">禁用</span>],
|
||||
[true,<span className="text-status_success">{$t('启用')}</span>],
|
||||
[false,<span className="text-status_fail">{$t('禁用')}</span>],
|
||||
])
|
||||
}
|
||||
];
|
||||
|
||||
@@ -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<PartitionCertTableListItem>[] = [
|
||||
export const PARTITION_CERT_TABLE_COLUMNS: PageProColumns<PartitionCertTableListItem>[] = [
|
||||
{
|
||||
title: '证书',
|
||||
title:$t('证书'),
|
||||
dataIndex: 'name',
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
@@ -16,7 +17,7 @@ export const PARTITION_CERT_TABLE_COLUMNS: ProColumns<PartitionCertTableListItem
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '绑定域名',
|
||||
title:$t('绑定域名'),
|
||||
dataIndex: 'domains',
|
||||
renderText:(_,entity) =>(
|
||||
entity.domains.join(',')
|
||||
@@ -24,7 +25,7 @@ export const PARTITION_CERT_TABLE_COLUMNS: ProColumns<PartitionCertTableListItem
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '过期日期',
|
||||
title:$t('过期日期'),
|
||||
ellipsis: true,
|
||||
dataIndex: 'notAfter',
|
||||
width:100,
|
||||
@@ -34,7 +35,7 @@ export const PARTITION_CERT_TABLE_COLUMNS: ProColumns<PartitionCertTableListItem
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '更新者',
|
||||
title:$t('更新者'),
|
||||
dataIndex: ['updater','name'],
|
||||
ellipsis: true,
|
||||
filters: true,
|
||||
@@ -43,7 +44,7 @@ export const PARTITION_CERT_TABLE_COLUMNS: ProColumns<PartitionCertTableListItem
|
||||
filterSearch: true
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
title:$t('更新时间'),
|
||||
key: 'updateTime',
|
||||
dataIndex: 'updateTime',
|
||||
ellipsis:true,
|
||||
@@ -54,9 +55,9 @@ export const PARTITION_CERT_TABLE_COLUMNS: ProColumns<PartitionCertTableListItem
|
||||
},
|
||||
];
|
||||
|
||||
export const PARTITION_CLUSTER_TABLE_COLUMNS : ProColumns<PartitionClusterTableListItem>[] = [
|
||||
export const PARTITION_CLUSTER_TABLE_COLUMNS : PageProColumns<PartitionClusterTableListItem>[] = [
|
||||
{
|
||||
title: '集群名称',
|
||||
title:$t('集群名称'),
|
||||
dataIndex: 'name',
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
@@ -66,13 +67,13 @@ export const PARTITION_CLUSTER_TABLE_COLUMNS : ProColumns<PartitionClusterTableL
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '集群 ID',
|
||||
title:$t('集群 ID'),
|
||||
dataIndex: 'id',
|
||||
width: 140,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
title:$t('状态'),
|
||||
dataIndex: 'status',
|
||||
ellipsis:true,
|
||||
valueType: 'select',
|
||||
@@ -84,16 +85,16 @@ export const PARTITION_CLUSTER_TABLE_COLUMNS : ProColumns<PartitionClusterTableL
|
||||
])
|
||||
},
|
||||
{
|
||||
title: '描述',
|
||||
title: $t('描述'),
|
||||
dataIndex: 'description',
|
||||
ellipsis:true
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
export const PARTITION_CLUSTER_NODE_COLUMNS: ProColumns<PartitionClusterNodeTableListItem>[] = [
|
||||
export const PARTITION_CLUSTER_NODE_COLUMNS: PageProColumns<PartitionClusterNodeTableListItem>[] = [
|
||||
{
|
||||
title: '节点名称',
|
||||
title:$t('节点名称'),
|
||||
dataIndex: 'name',
|
||||
ellipsis:true,
|
||||
fixed:'left',
|
||||
@@ -102,28 +103,28 @@ export const PARTITION_CLUSTER_NODE_COLUMNS: ProColumns<PartitionClusterNodeTabl
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '管理地址',
|
||||
title:$t('管理地址'),
|
||||
dataIndex: 'managerAddress',
|
||||
ellipsis:true,
|
||||
width:200,
|
||||
render:(_,entity)=>(<CopyAddrList keyName="managerAddress" addrItem={entity} />)
|
||||
},
|
||||
{
|
||||
title: '服务地址',
|
||||
title:$t('服务地址'),
|
||||
dataIndex: 'serviceAddress',
|
||||
ellipsis:true,
|
||||
width:230,
|
||||
render:(_,entity)=>(<CopyAddrList keyName="serviceAddress" addrItem={entity} />)
|
||||
},
|
||||
{
|
||||
title: '集群同步地址',
|
||||
title:$t('集群同步地址'),
|
||||
dataIndex: 'peerAddress',
|
||||
ellipsis:true,
|
||||
width:230,
|
||||
render:(_,entity)=>(<CopyAddrList keyName="peerAddress" addrItem={entity} />)
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
title:$t('状态'),
|
||||
dataIndex: 'status',
|
||||
ellipsis:true,
|
||||
width:86,
|
||||
@@ -138,20 +139,20 @@ export const PARTITION_CLUSTER_NODE_COLUMNS: ProColumns<PartitionClusterNodeTabl
|
||||
];
|
||||
|
||||
export const NODE_MODAL_COLUMNS:ColumnType<PartitionClusterNodeModalTableListItem>[] = [
|
||||
{title:'名称', dataIndex:'name',width:200,
|
||||
{title:$t('名称'), dataIndex:'name',width:200,
|
||||
ellipsis:true,
|
||||
fixed:'left'},
|
||||
{title:'管理地址', dataIndex:'managerAddress',width:240,ellipsis:true,render:(_,entity)=>(<CopyAddrList keyName="managerAddress" addrItem={entity} />)},
|
||||
{title:'服务地址', dataIndex:'serviceAddress',width:240,ellipsis:true,render:(_,entity)=>(<CopyAddrList keyName="serviceAddress" addrItem={entity} />)},
|
||||
{title:'状态', dataIndex:'status',
|
||||
{title:$t('管理地址'), dataIndex:'managerAddress',width:240,ellipsis:true,render:(_,entity)=>(<CopyAddrList keyName="managerAddress" addrItem={entity} />)},
|
||||
{title:$t('服务地址'), dataIndex:'serviceAddress',width:240,ellipsis:true,render:(_,entity)=>(<CopyAddrList keyName="serviceAddress" addrItem={entity} />)},
|
||||
{title:$t('状态'), dataIndex:'status',
|
||||
render:(text)=>(
|
||||
<span className={text === 0 ? 'text-status_fail' : 'text-status_success'}>{ClusterStatusEnum[text]}</span>
|
||||
)}
|
||||
]
|
||||
|
||||
export const PARTITION_LIST_COLUMNS: ProColumns<PartitionTableListItem>[] = [
|
||||
export const PARTITION_LIST_COLUMNS: PageProColumns<PartitionTableListItem>[] = [
|
||||
{
|
||||
title: '环境名称',
|
||||
title:$t('环境名称'),
|
||||
dataIndex: 'name',
|
||||
ellipsis:true,
|
||||
fixed:'left',
|
||||
@@ -160,20 +161,20 @@ export const PARTITION_LIST_COLUMNS: ProColumns<PartitionTableListItem>[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
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<PartitionTableListItem>[] = [
|
||||
filterSearch: true
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
title:$t('更新时间'),
|
||||
dataIndex: 'updateTime',
|
||||
ellipsis:true,
|
||||
width:182,
|
||||
@@ -193,9 +194,9 @@ export const PARTITION_LIST_COLUMNS: ProColumns<PartitionTableListItem>[] = [
|
||||
},
|
||||
];
|
||||
|
||||
export enum ClusterStatusEnum {
|
||||
'异常',
|
||||
'正常'
|
||||
export const ClusterStatusEnum ={
|
||||
0: $t('异常'),
|
||||
1: $t('正常')
|
||||
}
|
||||
|
||||
export const DASHBOARD_SETTING_DRIVER_OPTION_LIST = [
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { $t } from "@common/locales"
|
||||
|
||||
export const ROLE_TABLE_COLUMNS = [
|
||||
{
|
||||
title: '角色名称',
|
||||
title:$t('角色名称'),
|
||||
dataIndex: 'name',
|
||||
ellipsis:true,
|
||||
fixed:'left',
|
||||
|
||||
@@ -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<SystemTableListItem>[] = [
|
||||
export const SYSTEM_TABLE_COLUMNS: PageProColumns<SystemTableListItem>[] = [
|
||||
{
|
||||
title: '服务名称',
|
||||
title:$t('服务名称'),
|
||||
dataIndex: 'name',
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
@@ -82,13 +96,13 @@ export const SYSTEM_TABLE_COLUMNS: ProColumns<SystemTableListItem>[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
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<SystemTableListItem>[] = [
|
||||
// filterSearch: true,
|
||||
},
|
||||
{
|
||||
title: 'API 数量',
|
||||
title:$t('API 数量'),
|
||||
dataIndex: 'apiNum',
|
||||
ellipsis:true,
|
||||
sorter: (a,b)=> {
|
||||
@@ -104,12 +118,12 @@ export const SYSTEM_TABLE_COLUMNS: ProColumns<SystemTableListItem>[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
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<SystemTableListItem>[] = [
|
||||
filterSearch: true,
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
title:$t('创建时间'),
|
||||
dataIndex: 'createTime',
|
||||
width:182,
|
||||
ellipsis:true,
|
||||
@@ -127,9 +141,9 @@ export const SYSTEM_TABLE_COLUMNS: ProColumns<SystemTableListItem>[] = [
|
||||
}
|
||||
];
|
||||
|
||||
export const SYSTEM_SUBSERVICE_TABLE_COLUMNS: ProColumns<SystemSubServiceTableListItem>[] = [
|
||||
export const SYSTEM_SUBSERVICE_TABLE_COLUMNS: PageProColumns<SystemSubServiceTableListItem>[] = [
|
||||
{
|
||||
title: '服务名称',
|
||||
title:$t('服务名称'),
|
||||
dataIndex: ['service','name'],
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
@@ -139,13 +153,13 @@ export const SYSTEM_SUBSERVICE_TABLE_COLUMNS: ProColumns<SystemSubServiceTableLi
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '服务 ID',
|
||||
title:$t('服务 ID'),
|
||||
dataIndex: ['service','name'],
|
||||
width: 140,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '申请状态',
|
||||
title:$t('申请状态'),
|
||||
dataIndex: 'applyStatus',
|
||||
ellipsis:{
|
||||
showTitle:true
|
||||
@@ -155,25 +169,25 @@ export const SYSTEM_SUBSERVICE_TABLE_COLUMNS: ProColumns<SystemSubServiceTableLi
|
||||
onFilter: true,
|
||||
valueType: 'select',
|
||||
valueEnum:new Map([
|
||||
[0,<span className={SubscribeStatusColor[0]}>驳回</span>],
|
||||
[1,<span className={SubscribeStatusColor[1]}>审核中</span>],
|
||||
[2,<span className={SubscribeStatusColor[2]}>已订阅</span>],
|
||||
[3,<span className={SubscribeStatusColor[3]}>取消订阅</span>],
|
||||
[4,<span className={SubscribeStatusColor[4]}>取消申请</span>],
|
||||
[0,<span className={SubscribeStatusColor[0]}>{$t('驳回')}</span>],
|
||||
[1,<span className={SubscribeStatusColor[1]}>{$t('审核中')}</span>],
|
||||
[2,<span className={SubscribeStatusColor[2]}>{$t('已订阅')}</span>],
|
||||
[3,<span className={SubscribeStatusColor[3]}>{$t('取消订阅')}</span>],
|
||||
[4,<span className={SubscribeStatusColor[4]}>{$t('取消申请')}</span>],
|
||||
])
|
||||
},
|
||||
{
|
||||
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<SystemSubServiceTableLi
|
||||
filterSearch: true,
|
||||
},
|
||||
{
|
||||
title: '来源',
|
||||
title:$t('来源'),
|
||||
dataIndex: 'from',
|
||||
ellipsis: true,
|
||||
filters: true,
|
||||
onFilter: true,
|
||||
valueType: 'select',
|
||||
valueEnum:new Map([
|
||||
[0,<span>手动添加</span>],
|
||||
[1,<span>订阅申请</span>],
|
||||
[0,<span>{$t('手动添加')}</span>],
|
||||
[1,<span>{$t('订阅申请')}</span>],
|
||||
])
|
||||
},
|
||||
{
|
||||
title: '添加时间',
|
||||
title:$t('添加时间'),
|
||||
dataIndex: 'createTime',
|
||||
ellipsis:true,
|
||||
width:182,
|
||||
@@ -206,9 +220,9 @@ export const SYSTEM_SUBSERVICE_TABLE_COLUMNS: ProColumns<SystemSubServiceTableLi
|
||||
];
|
||||
|
||||
|
||||
export const SYSTEM_SUBSCRIBER_TABLE_COLUMNS: ProColumns<SystemSubscriberTableListItem>[] = [
|
||||
export const SYSTEM_SUBSCRIBER_TABLE_COLUMNS: PageProColumns<SystemSubscriberTableListItem>[] = [
|
||||
{
|
||||
title: '服务名称',
|
||||
title:$t('服务名称'),
|
||||
dataIndex: ['service','name'],
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
@@ -218,55 +232,35 @@ export const SYSTEM_SUBSCRIBER_TABLE_COLUMNS: ProColumns<SystemSubscriberTableLi
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '服务 ID',
|
||||
title:$t('服务 ID'),
|
||||
dataIndex: 'id',
|
||||
width: 140,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '订阅方',
|
||||
title:$t('订阅方'),
|
||||
dataIndex: ['subscriber','name'],
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '所属团队',
|
||||
title:$t('所属团队'),
|
||||
dataIndex: ['team','name'],
|
||||
ellipsis:true
|
||||
},
|
||||
// {
|
||||
// title: '申请人',
|
||||
// dataIndex: ['applier','name'],
|
||||
// ellipsis:true,
|
||||
// width:88,
|
||||
// filters: true,
|
||||
// onFilter: true,
|
||||
// valueType: 'select',
|
||||
// filterSearch: true,
|
||||
// },
|
||||
// {
|
||||
// title: '审批人',
|
||||
// dataIndex: ['approver','name'],
|
||||
// ellipsis:true,
|
||||
// width:88,
|
||||
// filters: true,
|
||||
// onFilter: true,
|
||||
// valueType: 'select',
|
||||
// filterSearch: true,
|
||||
// },
|
||||
{
|
||||
title: '来源',
|
||||
title:$t('来源'),
|
||||
dataIndex: 'from',
|
||||
ellipsis:true,
|
||||
filters: true,
|
||||
onFilter: true,
|
||||
valueType: 'select',
|
||||
valueEnum:new Map([
|
||||
[0,<span>手动添加</span>],
|
||||
[1,<span>订阅申请</span>],
|
||||
[0,<span>{$t('手动添加')}</span>],
|
||||
[1,<span>{$t('订阅申请')}</span>],
|
||||
])
|
||||
},
|
||||
{
|
||||
title: '订阅时间',
|
||||
title:$t('订阅时间'),
|
||||
dataIndex: 'applyTime',
|
||||
ellipsis:true,
|
||||
width:182,
|
||||
@@ -278,7 +272,7 @@ export const SYSTEM_SUBSCRIBER_TABLE_COLUMNS: ProColumns<SystemSubscriberTableLi
|
||||
|
||||
|
||||
export const memberModalColumn:ColumnsType<MemberItem> = [
|
||||
{title:'成员',
|
||||
{title:$t('成员'),
|
||||
render:(_,entity)=>{
|
||||
return <>
|
||||
<div>
|
||||
@@ -292,9 +286,9 @@ export const memberModalColumn:ColumnsType<MemberItem> = [
|
||||
}}
|
||||
]
|
||||
|
||||
export const SYSTEM_MEMBER_TABLE_COLUMN: ProColumns<SystemMemberTableListItem>[] = [
|
||||
export const SYSTEM_MEMBER_TABLE_COLUMN: PageProColumns<SystemMemberTableListItem>[] = [
|
||||
{
|
||||
title: '用户名',
|
||||
title:$t('用户名'),
|
||||
dataIndex: ['user','name'],
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
@@ -304,12 +298,12 @@ export const SYSTEM_MEMBER_TABLE_COLUMN: ProColumns<SystemMemberTableListItem>[]
|
||||
},
|
||||
},
|
||||
{
|
||||
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<SystemMemberTableListItem>[]
|
||||
|
||||
export const MATCH_CONFIG:ConfigField<MatchItem>[] = [
|
||||
{
|
||||
title: '参数位置',
|
||||
title:$t('参数位置'),
|
||||
key: 'position',
|
||||
component: <Select className="w-INPUT_NORMAL" options={Object.entries(MatchPositionEnum)?.map(([key,value])=>{
|
||||
return { label:value, value:key}
|
||||
@@ -329,13 +323,13 @@ export const MATCH_CONFIG:ConfigField<MatchItem>[] = [
|
||||
required: true,
|
||||
ellipsis:true
|
||||
}, {
|
||||
title: '参数名',
|
||||
title:$t('参数名'),
|
||||
key: 'key',
|
||||
component: <Input className="w-INPUT_NORMAL" />,
|
||||
renderText: (value: unknown) => <>{value}</>,
|
||||
required: true
|
||||
}, {
|
||||
title: '匹配类型',
|
||||
title:$t('匹配类型'),
|
||||
key: 'matchType',
|
||||
component: <Select className="w-INPUT_NORMAL" options={Object.entries(MatchTypeEnum)?.map(([key,value])=>{
|
||||
return { label:value, value:key}
|
||||
@@ -345,7 +339,7 @@ export const MATCH_CONFIG:ConfigField<MatchItem>[] = [
|
||||
},
|
||||
required: true
|
||||
}, {
|
||||
title: '参数值',
|
||||
title:$t('参数值'),
|
||||
key: 'pattern',
|
||||
component: <Input className="w-INPUT_NORMAL"/>,
|
||||
renderText: (value: string) => {
|
||||
@@ -356,9 +350,9 @@ export const MATCH_CONFIG:ConfigField<MatchItem>[] = [
|
||||
]
|
||||
|
||||
|
||||
export const SYSTEM_API_TABLE_COLUMNS: ProColumns<SystemApiTableListItem>[] = [
|
||||
export const SYSTEM_API_TABLE_COLUMNS: PageProColumns<SystemApiTableListItem>[] = [
|
||||
{
|
||||
title: '名称',
|
||||
title:$t('名称'),
|
||||
dataIndex: 'name',
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
@@ -369,7 +363,7 @@ export const SYSTEM_API_TABLE_COLUMNS: ProColumns<SystemApiTableListItem>[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '协议/方法',
|
||||
title:$t('协议/方法'),
|
||||
dataIndex: 'method',
|
||||
ellipsis:true,
|
||||
filters: true,
|
||||
@@ -384,12 +378,12 @@ export const SYSTEM_API_TABLE_COLUMNS: ProColumns<SystemApiTableListItem>[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
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<SystemApiTableListItem>[] = [
|
||||
filterSearch: true,
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
title:$t('更新时间'),
|
||||
dataIndex: 'updateTime',
|
||||
ellipsis:true,
|
||||
hideInSearch: true,
|
||||
@@ -409,9 +403,9 @@ export const SYSTEM_API_TABLE_COLUMNS: ProColumns<SystemApiTableListItem>[] = [
|
||||
|
||||
|
||||
|
||||
export const SYSTEM_UPSTREAM_TABLE_COLUMNS: ProColumns<SystemUpstreamTableListItem>[] = [
|
||||
export const SYSTEM_UPSTREAM_TABLE_COLUMNS: PageProColumns<SystemUpstreamTableListItem>[] = [
|
||||
{
|
||||
title: '名称',
|
||||
title:$t('名称'),
|
||||
dataIndex: 'name',
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
@@ -421,13 +415,13 @@ export const SYSTEM_UPSTREAM_TABLE_COLUMNS: ProColumns<SystemUpstreamTableListIt
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '上游 ID',
|
||||
title:$t('上游 ID'),
|
||||
dataIndex: 'id',
|
||||
width: 140,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '创建人',
|
||||
title:$t('创建人'),
|
||||
dataIndex: ['creator','name'],
|
||||
ellipsis: true,
|
||||
width:88,
|
||||
@@ -437,7 +431,7 @@ export const SYSTEM_UPSTREAM_TABLE_COLUMNS: ProColumns<SystemUpstreamTableListIt
|
||||
filterSearch: true,
|
||||
},
|
||||
{
|
||||
title: '更新人',
|
||||
title:$t('更新人'),
|
||||
dataIndex: ['updater','name'],
|
||||
ellipsis: true,
|
||||
width:88,
|
||||
@@ -447,7 +441,7 @@ export const SYSTEM_UPSTREAM_TABLE_COLUMNS: ProColumns<SystemUpstreamTableListIt
|
||||
filterSearch: true,
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
title:$t('创建时间'),
|
||||
dataIndex: 'createTime',
|
||||
width:182,
|
||||
ellipsis:true,
|
||||
@@ -456,7 +450,7 @@ export const SYSTEM_UPSTREAM_TABLE_COLUMNS: ProColumns<SystemUpstreamTableListIt
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
title:$t('更新时间'),
|
||||
dataIndex: 'updateTime',
|
||||
width:182,
|
||||
ellipsis:true,
|
||||
@@ -466,47 +460,47 @@ export const SYSTEM_UPSTREAM_TABLE_COLUMNS: ProColumns<SystemUpstreamTableListIt
|
||||
},
|
||||
];
|
||||
|
||||
export enum UpstreamDriverEnum{
|
||||
'static'='静态上游',
|
||||
'discoveries'='动态服务发现',
|
||||
export const UpstreamDriverEnum = {
|
||||
'static':$t('静态上游'),
|
||||
'discoveries':$t('动态服务发现'),
|
||||
}
|
||||
|
||||
export const typeOptions = [
|
||||
{ label: '静态上游', value: 'static' },
|
||||
// { label: '动态服务发现', value: 'discoveries' },
|
||||
{ label: $t('静态上游'), value: 'static' },
|
||||
// { label: $t('动态服务发现', value: 'discoveries' },
|
||||
];
|
||||
|
||||
export const schemeOptions = [
|
||||
{ label:'HTTPS', value:'HTTPS'},
|
||||
{ label:'HTTP', value:'HTTP'},
|
||||
{ label:$t('HTTPS'), value:'HTTPS'},
|
||||
{ label:$t('HTTP'), value:'HTTP'},
|
||||
]
|
||||
export const balanceOptions = [
|
||||
{ label: '带权轮询', value: 'round-robin' },
|
||||
{ label: 'IP Hash', value: 'ip-hash' },
|
||||
{ label: $t('带权轮询'), value: 'round-robin' },
|
||||
{ label: $t('IP Hash'), value: 'ip-hash' },
|
||||
];
|
||||
|
||||
export const passHostOptions = [
|
||||
{ label:'透传客户端请求 Host', value:'pass'},
|
||||
{ label:'使用上游服务 Host', value:'node'},
|
||||
{ label:'重写 Host', value:'rewrite'},
|
||||
{ label:$t('透传客户端请求 Host'), value:'pass'},
|
||||
{ label:$t('使用上游服务 Host'), value:'node'},
|
||||
{ label:$t('重写 Host'), value:'rewrite'},
|
||||
]
|
||||
|
||||
export const proxyHeaderTypeOptions =[
|
||||
{label:'新增或修改', value: 'ADD' },
|
||||
{ label: '删除', value: 'DELETE' }
|
||||
{label:$t('新增或修改'), value: 'ADD' },
|
||||
{ label: $t('删除'), value: 'DELETE' }
|
||||
]
|
||||
|
||||
export const PROXY_HEADER_CONFIG:ConfigField<ProxyHeaderItem>[] = [
|
||||
{
|
||||
title: '操作类型',
|
||||
title:$t('操作类型'),
|
||||
key: 'optType',
|
||||
component: <Select className="w-INPUT_NORMAL" options={proxyHeaderTypeOptions}/>,
|
||||
renderText: (value: string) => {
|
||||
return (<>{value === 'ADD' ? '新增或修改':'删除'}</>)
|
||||
return (<>{value === 'ADD' ? $t('新增或修改'):$t('删除')}</>)
|
||||
},
|
||||
required: true
|
||||
}, {
|
||||
title: '参数名',
|
||||
title:$t('参数名'),
|
||||
key: 'key',
|
||||
component: <Input className="w-INPUT_NORMAL"/>,
|
||||
renderText: (value: string) => {
|
||||
@@ -514,7 +508,7 @@ export const PROXY_HEADER_CONFIG:ConfigField<ProxyHeaderItem>[] = [
|
||||
},
|
||||
required: true
|
||||
}, {
|
||||
title: '参数值',
|
||||
title:$t('参数值'),
|
||||
key: 'value',
|
||||
component: <Input className="w-INPUT_NORMAL" />,
|
||||
renderText: (value: string) => {
|
||||
@@ -526,12 +520,12 @@ export const PROXY_HEADER_CONFIG:ConfigField<ProxyHeaderItem>[] = [
|
||||
|
||||
export const NODE_CONFIG:ConfigField<NodeItem>[] = [
|
||||
{
|
||||
title: '集群',
|
||||
title:$t('集群'),
|
||||
key: 'cluster',
|
||||
component: <Select className="w-INPUT_NORMAL" options={[]}/>,
|
||||
required: true
|
||||
}, {
|
||||
title: '地址',
|
||||
title:$t('地址'),
|
||||
key: 'address',
|
||||
component: <Input className="w-INPUT_NORMAL" />,
|
||||
renderText: (value: string) => {
|
||||
@@ -539,7 +533,7 @@ export const NODE_CONFIG:ConfigField<NodeItem>[] = [
|
||||
},
|
||||
required: true
|
||||
}, {
|
||||
title: '权重',
|
||||
title:$t('权重'),
|
||||
key: 'weight',
|
||||
component: <InputNumber className="w-INPUT_NORMAL"/>,
|
||||
renderText: (value: string) => {
|
||||
@@ -550,37 +544,37 @@ export const NODE_CONFIG:ConfigField<NodeItem>[] = [
|
||||
]
|
||||
|
||||
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<ServiceApiTableListItem>[] = [
|
||||
export const SYSTEM_MYSERVICE_API_TABLE_COLUMNS: PageProColumns<ServiceApiTableListItem>[] = [
|
||||
{
|
||||
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<ServiceApiTableListI
|
||||
|
||||
export const apiModalColumn:ColumnsType<SimpleApiItem> = [
|
||||
{
|
||||
title:'所有 API',
|
||||
title:$t('所有 API'),
|
||||
dataIndex:'method',
|
||||
},
|
||||
{
|
||||
@@ -600,9 +594,9 @@ export const apiModalColumn:ColumnsType<SimpleApiItem> = [
|
||||
]
|
||||
|
||||
|
||||
export const SYSTEM_AUTHORITY_TABLE_COLUMNS: ProColumns<SystemAuthorityTableListItem>[] = [
|
||||
export const SYSTEM_AUTHORITY_TABLE_COLUMNS: PageProColumns<SystemAuthorityTableListItem>[] = [
|
||||
{
|
||||
title: '名称',
|
||||
title:$t('名称'),
|
||||
dataIndex: 'name',
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
@@ -612,7 +606,7 @@ export const SYSTEM_AUTHORITY_TABLE_COLUMNS: ProColumns<SystemAuthorityTableList
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '类型',
|
||||
title:$t('类型'),
|
||||
dataIndex: 'driver',
|
||||
ellipsis:true,
|
||||
filters: true,
|
||||
@@ -628,7 +622,7 @@ export const SYSTEM_AUTHORITY_TABLE_COLUMNS: ProColumns<SystemAuthorityTableList
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '隐藏鉴权信息',
|
||||
title:$t('隐藏鉴权信息'),
|
||||
dataIndex: 'hideCredential',
|
||||
ellipsis:{
|
||||
showTitle:true
|
||||
@@ -642,19 +636,19 @@ export const SYSTEM_AUTHORITY_TABLE_COLUMNS: ProColumns<SystemAuthorityTableList
|
||||
])
|
||||
},
|
||||
{
|
||||
title: '过期时间',
|
||||
title:$t('过期时间'),
|
||||
dataIndex: 'expireTime',
|
||||
ellipsis:true,
|
||||
width:182,
|
||||
render:(_: React.ReactNode, entity: SystemAuthorityTableListItem) => (
|
||||
<span className={entity.expireTime !== 0 && moment.now() - (entity.expireTime * 1000) > 0 ? 'text-status_fail' : ''}>{entity.expireTime === 0 ? '永不过期' :moment(entity.expireTime * 1000).format('YYYY-MM-DD hh:mm:ss')}</span>
|
||||
<span className={entity.expireTime !== 0 && dayjs().valueOf() - (entity.expireTime * 1000) > 0 ? 'text-status_fail' : ''}>{entity.expireTime === 0 ? '永不过期' :dayjs(entity.expireTime * 1000).format('YYYY-MM-DD hh:mm:ss')}</span>
|
||||
),
|
||||
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<SystemAuthorityTableList
|
||||
filterSearch: true,
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
title:$t('创建时间'),
|
||||
key: 'createTime',
|
||||
dataIndex: 'createTime',
|
||||
width:182,
|
||||
@@ -676,9 +670,9 @@ export const SYSTEM_AUTHORITY_TABLE_COLUMNS: ProColumns<SystemAuthorityTableList
|
||||
];
|
||||
|
||||
|
||||
export const SYSTEM_MYSERVICE_TABLE_COLUMNS: ProColumns<MyServiceTableListItem>[] = [
|
||||
export const SYSTEM_MYSERVICE_TABLE_COLUMNS: PageProColumns<MyServiceTableListItem>[] = [
|
||||
{
|
||||
title: '服务名称',
|
||||
title:$t('服务名称'),
|
||||
dataIndex: 'name',
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
@@ -688,13 +682,13 @@ export const SYSTEM_MYSERVICE_TABLE_COLUMNS: ProColumns<MyServiceTableListItem>[
|
||||
},
|
||||
},
|
||||
{
|
||||
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<MyServiceTableListItem>[
|
||||
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<MyServiceTableListItem>[
|
||||
onFilter: true,
|
||||
valueType: 'select',
|
||||
valueEnum:{
|
||||
'on':<span className="text-status_success">启用</span> ,
|
||||
'off':<span className="text-status_fail">停用</span>
|
||||
'on':<span className="text-status_success">{$t('启用')}</span> ,
|
||||
'off':<span className="text-status_fail">{$t('停用')}</span>
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
title:$t('更新时间'),
|
||||
key: 'updateTime',
|
||||
dataIndex: 'updateTime',
|
||||
ellipsis:true,
|
||||
@@ -743,7 +737,7 @@ export const SYSTEM_MYSERVICE_TABLE_COLUMNS: ProColumns<MyServiceTableListItem>[
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
title:$t('创建时间'),
|
||||
key: 'createTime',
|
||||
dataIndex: 'createTime',
|
||||
width:182,
|
||||
@@ -756,9 +750,9 @@ export const SYSTEM_MYSERVICE_TABLE_COLUMNS: ProColumns<MyServiceTableListItem>[
|
||||
|
||||
|
||||
|
||||
export const SYSTEM_UPSTREAM_GLOBAL_CONFIG_TABLE_COLUMNS: ProColumns<GlobalNodeItem & {_id:string}>[] = [
|
||||
export const SYSTEM_UPSTREAM_GLOBAL_CONFIG_TABLE_COLUMNS: PageProColumns<GlobalNodeItem & {_id:string}>[] = [
|
||||
{
|
||||
title: '地址(IP 端口或域名)',
|
||||
title:$t('地址(IP 端口或域名)'),
|
||||
dataIndex: 'address',
|
||||
width: '50%',
|
||||
formItemProps: {
|
||||
@@ -768,23 +762,23 @@ export const SYSTEM_UPSTREAM_GLOBAL_CONFIG_TABLE_COLUMNS: ProColumns<GlobalNodeI
|
||||
{
|
||||
required: true,
|
||||
whitespace: true,
|
||||
message: '此项是必填项',
|
||||
message: VALIDATE_MESSAGE.required,
|
||||
},
|
||||
],
|
||||
},
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '权重(0-999)',
|
||||
title:$t('权重(0-999)'),
|
||||
dataIndex: 'weight',
|
||||
valueType:'digit',
|
||||
formItemProps: {
|
||||
className:'p-0 bg-transparent border-none'}
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
title: COLUMNS_TITLE.operate,
|
||||
valueType: 'option',
|
||||
width: 90,
|
||||
btnNums:2,
|
||||
render: ()=>null
|
||||
},
|
||||
];
|
||||
@@ -793,11 +787,11 @@ export const SYSTEM_UPSTREAM_GLOBAL_CONFIG_TABLE_COLUMNS: ProColumns<GlobalNodeI
|
||||
export const SYSTEM_INSIDE_APPROVAL_TAB_ITEMS: TabsProps['items'] = [
|
||||
{
|
||||
key: '0',
|
||||
label: '待审批',
|
||||
label:$t('待审批'),
|
||||
},
|
||||
{
|
||||
key: '1',
|
||||
label: '已审批',
|
||||
label: $t('已审批'),
|
||||
}
|
||||
];
|
||||
|
||||
@@ -806,70 +800,64 @@ export const SYSTEM_INSIDE_APPROVAL_TAB_ITEMS: TabsProps['items'] = [
|
||||
export const SYSTEM_PUBLISH_TAB_ITEMS: TabsProps['items'] = [
|
||||
{
|
||||
key: '0',
|
||||
label: '发布版本',
|
||||
label: $t('发布版本'),
|
||||
},
|
||||
{
|
||||
key: '1',
|
||||
label: '发布申请记录',
|
||||
label: $t('发布申请记录'),
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
export const SYSTEM_SUBSCRIBE_APPROVAL_DETAIL_LIST = [
|
||||
{
|
||||
title:'服务名称',key:'service',nested:'name'
|
||||
title:$t('服务名称'),key:'service',nested:'name'
|
||||
},
|
||||
{
|
||||
title:'服务 ID',key:'applyTeam',nested:'id'
|
||||
title:$t('服务 ID'),key:'applyTeam',nested:'id'
|
||||
},
|
||||
{
|
||||
title:'所属团队',key:'team',nested:'name'
|
||||
title:$t('所属团队'),key:'team',nested:'name'
|
||||
},
|
||||
{
|
||||
title:'所属系统',key:'project',nested:'name'
|
||||
title:$t('所属系统'),key:'project',nested:'name'
|
||||
},
|
||||
{
|
||||
title:'申请状态',key:'status',renderText:()=>{}
|
||||
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 <span className={STATUS_COLOR[entity.status as keyof typeof STATUS_COLOR]}>成功</span>
|
||||
return <span className={STATUS_COLOR[entity.status as keyof typeof STATUS_COLOR]}>{$t('成功')}</span>
|
||||
case 'error':
|
||||
return <Tooltip title={entity.error || '上线失败'}><span className={`${STATUS_COLOR[entity.status as keyof typeof STATUS_COLOR]} truncate block`}>失败 {entity.error}</span></Tooltip>
|
||||
return <Tooltip title={entity.error || $t('上线失败')}><span className={`${STATUS_COLOR[entity.status as keyof typeof STATUS_COLOR]} truncate block`}>{$t('失败')} {entity.error}</span></Tooltip>
|
||||
default:
|
||||
return <LoadingOutlined className="text-theme" spin />
|
||||
}
|
||||
@@ -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(<Link to="./api">API</Link>, 'api',undefined,undefined,undefined,'team.service.api.view'),
|
||||
getItem(<Link to="./upstream">上游</Link>, 'upstream',undefined,undefined,undefined,'team.service.upstream.view'),
|
||||
getItem(<Link to="./document">使用说明</Link>, 'document',undefined,undefined,undefined,''),
|
||||
getItem(<Link to="./publish">发布</Link>, 'publish',undefined,undefined,undefined,'team.service.release.view'),
|
||||
getItem(<Link to="./api">{$t('API')}</Link>, 'api',undefined,undefined,undefined,'team.service.api.view'),
|
||||
getItem(<Link to="./upstream">{$t('上游')}</Link>, 'upstream',undefined,undefined,undefined,'team.service.upstream.view'),
|
||||
getItem(<Link to="./document">{$t('使用说明')}</Link>, 'document',undefined,undefined,undefined,''),
|
||||
getItem(<Link to="./publish">{$t('发布')}</Link>, 'publish',undefined,undefined,undefined,'team.service.release.view'),
|
||||
],
|
||||
'group'),
|
||||
getItem('订阅管理', 'provideSer', null,
|
||||
getItem($t('订阅管理'), 'provideSer', null,
|
||||
[
|
||||
getItem(<Link to="./approval">订阅审批</Link>, 'approval',undefined,undefined,undefined,'team.service.subscription.view'),
|
||||
getItem(<Link to="./subscriber">订阅方管理</Link>, 'subscriber',undefined,undefined,undefined,'team.service.subscription.view'),
|
||||
getItem(<Link to="./approval">{$t('订阅审批')}</Link>, 'approval',undefined,undefined,undefined,'team.service.subscription.view'),
|
||||
getItem(<Link to="./subscriber">{$t('订阅方管理')}</Link>, 'subscriber',undefined,undefined,undefined,'team.service.subscription.view'),
|
||||
],
|
||||
'group'),
|
||||
getItem('管理', 'mng', null,
|
||||
getItem($t('管理'), 'mng', null,
|
||||
[
|
||||
APP_MODE === 'pro' ? getItem(<Link to="./topology">调用拓扑图</Link>, 'topology',undefined,undefined,undefined,'project.mySystem.topology.view'):null,
|
||||
getItem(<Link to="./setting">设置</Link>, 'setting',undefined,undefined,undefined,'')],
|
||||
APP_MODE === 'pro' ? getItem(<Link to="./topology">{$t('调用拓扑图')}</Link>, 'topology',undefined,undefined,undefined,'project.mySystem.topology.view'):null,
|
||||
getItem(<Link to="./setting">{$t('设置')}</Link>, 'setting',undefined,undefined,undefined,'')],
|
||||
'group'),
|
||||
];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<TeamTableListItem>[] = [
|
||||
export const TEAM_TABLE_COLUMNS: PageProColumns<TeamTableListItem>[] = [
|
||||
{
|
||||
title: '名称',
|
||||
title:$t('名称'),
|
||||
dataIndex: 'name',
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
@@ -20,18 +21,18 @@ export const TEAM_TABLE_COLUMNS: ProColumns<TeamTableListItem>[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
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<TeamTableListItem>[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '负责人',
|
||||
title:$t('负责人'),
|
||||
dataIndex: ['master','name'],
|
||||
ellipsis: true,
|
||||
width:108,
|
||||
@@ -49,7 +50,7 @@ export const TEAM_TABLE_COLUMNS: ProColumns<TeamTableListItem>[] = [
|
||||
filterSearch: true,
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
title:$t('创建时间'),
|
||||
dataIndex: 'createTime',
|
||||
ellipsis:true,
|
||||
width:182,
|
||||
@@ -60,9 +61,9 @@ export const TEAM_TABLE_COLUMNS: ProColumns<TeamTableListItem>[] = [
|
||||
];
|
||||
|
||||
|
||||
export const TEAM_SYSTEM_TABLE_COLUMNS: ProColumns<SystemTableListItem>[] = [
|
||||
export const TEAM_SYSTEM_TABLE_COLUMNS: PageProColumns<SystemTableListItem>[] = [
|
||||
{
|
||||
title: '服务名称',
|
||||
title:$t('服务名称'),
|
||||
dataIndex: 'name',
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
@@ -72,18 +73,18 @@ export const TEAM_SYSTEM_TABLE_COLUMNS: ProColumns<SystemTableListItem>[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
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<SystemTableListItem>[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '服务数量',
|
||||
title:$t('服务数量'),
|
||||
dataIndex: 'serviceNum',
|
||||
ellipsis:true,
|
||||
sorter: (a,b)=> {
|
||||
@@ -99,7 +100,7 @@ export const TEAM_SYSTEM_TABLE_COLUMNS: ProColumns<SystemTableListItem>[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '负责人',
|
||||
title:$t('负责人'),
|
||||
dataIndex: ['master','name'],
|
||||
ellipsis: true,
|
||||
width:108,
|
||||
@@ -109,7 +110,7 @@ export const TEAM_SYSTEM_TABLE_COLUMNS: ProColumns<SystemTableListItem>[] = [
|
||||
filterSearch: true
|
||||
},
|
||||
{
|
||||
title: '添加日期',
|
||||
title:$t('添加日期'),
|
||||
dataIndex: 'createTime',
|
||||
ellipsis: true,
|
||||
sorter: (a,b)=> {
|
||||
@@ -118,9 +119,9 @@ export const TEAM_SYSTEM_TABLE_COLUMNS: ProColumns<SystemTableListItem>[] = [
|
||||
},
|
||||
];
|
||||
|
||||
export const TEAM_MEMBER_TABLE_COLUMNS: ProColumns<TeamMemberTableListItem>[] = [
|
||||
export const TEAM_MEMBER_TABLE_COLUMNS: PageProColumns<TeamMemberTableListItem>[] = [
|
||||
{
|
||||
title: '姓名',
|
||||
title:$t('姓名'),
|
||||
dataIndex: ['user','name'],
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
@@ -130,12 +131,12 @@ export const TEAM_MEMBER_TABLE_COLUMNS: ProColumns<TeamMemberTableListItem>[] =
|
||||
},
|
||||
},
|
||||
{
|
||||
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<TeamMemberTableListItem>[] =
|
||||
|
||||
|
||||
export const TEAM_MEMBER_MODAL_TABLE_COLUMNS:ColumnsType<MemberItem> = [
|
||||
{title:'成员',
|
||||
{title:$t('成员'),
|
||||
render:(_,entity)=>{
|
||||
return <>
|
||||
<div>
|
||||
@@ -161,10 +162,10 @@ export const TEAM_MEMBER_MODAL_TABLE_COLUMNS:ColumnsType<MemberItem> = [
|
||||
]
|
||||
|
||||
export const TEAM_INSIDE_MENU_ITEMS: MenuProps['items'] = [
|
||||
getItem('管理', 'grp', null,
|
||||
getItem($t('管理'), 'grp', null,
|
||||
[
|
||||
getItem(<Link to="member">成员</Link>, 'member',undefined, undefined, undefined,'team.team.member.view'),
|
||||
getItem(<Link to="setting">设置</Link>, 'setting',undefined,undefined,undefined,'team.team.team.edit')],
|
||||
getItem(<Link to="member">{$t('成员')}</Link>, 'member',undefined, undefined, undefined,'team.team.member.view'),
|
||||
getItem(<Link to="setting">{$t('设置')}</Link>, 'setting',undefined,undefined,undefined,'team.team.team.edit')],
|
||||
'group'),
|
||||
];
|
||||
|
||||
@@ -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<MemberItem>[]= [
|
||||
export const USER_LIST_COLUMNS: PageProColumns<MemberItem>[]= [
|
||||
{
|
||||
title: '用户名',
|
||||
title:$t('用户名'),
|
||||
dataIndex: 'name',
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
@@ -16,12 +17,12 @@ export const USER_LIST_COLUMNS: ProColumns<MemberItem>[]= [
|
||||
},
|
||||
},
|
||||
{
|
||||
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<MemberItem>[]= [
|
||||
];
|
||||
|
||||
export const MEMBER_MODAL_COLUMNS:ColumnsType<MemberItem> = [
|
||||
{title:'所有成员',
|
||||
{title:$t('所有成员'),
|
||||
width:215,
|
||||
|
||||
render:(_,entity)=>{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 = ()=> {
|
||||
<div className="h-full">
|
||||
<div>
|
||||
<div className="flex justify-center items-center">
|
||||
<span className="text-[24px] text-[#101010]">登录</span>
|
||||
<span className="text-[24px] text-[#101010]">{$t('登录')}</span>
|
||||
</div>
|
||||
|
||||
<Form onFinish={login} className="w-[350px] pt-[28px]"
|
||||
@@ -110,11 +111,11 @@ const Login:FC = ()=> {
|
||||
<Form.Item
|
||||
className="p-0 bg-transparent rounded border-none"
|
||||
name="username"
|
||||
rules={[{ required: true, message: '请输入账号' ,whitespace:true }]}
|
||||
rules={[{ required: true, message: $t('请输入账号') ,whitespace:true }]}
|
||||
>
|
||||
<Input
|
||||
className="w-[350px] h-[40px]"
|
||||
placeholder="账号"
|
||||
placeholder={$t("账号")}
|
||||
autoComplete="on"
|
||||
autoFocus
|
||||
/>
|
||||
@@ -123,11 +124,11 @@ const Login:FC = ()=> {
|
||||
<Form.Item
|
||||
className="p-0 bg-transparent rounded border-none"
|
||||
name="password"
|
||||
rules={[{ required: true, message: '请输入密码' }]}
|
||||
rules={[{ required: true, message: $t('请输入密码') }]}
|
||||
>
|
||||
<Input.Password
|
||||
className="w-[350px] h-[40px]"
|
||||
placeholder="密码"
|
||||
placeholder={$t("密码")}
|
||||
autoComplete="off"
|
||||
/>
|
||||
</Form.Item>
|
||||
@@ -137,7 +138,7 @@ const Login:FC = ()=> {
|
||||
className="p-0 bg-transparent rounded border-none mb-0"
|
||||
>
|
||||
<Button loading={loading} className="h-[40px] mt-mbase w-full inline-flex justify-center items-center" type="primary" htmlType="submit">
|
||||
登录
|
||||
{$t('登录')}
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</div>
|
||||
@@ -147,8 +148,8 @@ const Login:FC = ()=> {
|
||||
</section>
|
||||
|
||||
<section className="flex flex-col items-center mt-[46px] text-SECOND_TEXT">
|
||||
<p className="leading-[28px]">Version {state.version}-{state.updateDate}</p>
|
||||
<p className="leading-[28px]">{state.powered}</p>
|
||||
<p className="leading-[28px]">{$t('Version (0)-(1)',[state.version,state.updateDate])}</p>
|
||||
<p className="leading-[28px]">{$t(state.powered)}</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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<BasicResponse<{approval:PublishApprovalInfoType|SubscribeApprovalInfoType}>>(`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' ?
|
||||
<SubscribeApprovalModalContent ref={subscribeRef} data={data.approval as SubscribeApprovalInfoType} type={type}/>
|
||||
:<PublishApprovalModalContent ref={publishRef} data={data.approval as PublishApprovalInfoType} type={type} systemId={''}/>,
|
||||
@@ -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<ApprovalTableListItem>[] =[
|
||||
const operation:PageProColumns<ApprovalTableListItem>[] =[
|
||||
{
|
||||
title: '操作',
|
||||
title: COLUMNS_TITLE.operate,
|
||||
key: 'option',
|
||||
width: 62,
|
||||
btnNums:1,
|
||||
fixed:'right',
|
||||
valueType: 'option',
|
||||
render: (_: React.ReactNode, entity: ApprovalTableListItem) => [
|
||||
pageStatus === 0 ?
|
||||
<TableBtnWithPermission access="" key="approval" onClick={()=>{openModal('approval',entity)}} btnTitle="审批"/>
|
||||
:<TableBtnWithPermission access="" key="view" onClick={()=>{openModal('view',entity)}} btnTitle="查看"/>,
|
||||
<TableBtnWithPermission access="" key="approval" btnType="approval" onClick={()=>{openModal('approval',entity)}} btnTitle="审批"/>
|
||||
:<TableBtnWithPermission access="" key="view" btnType="publish" onClick={()=>{openModal('view',entity)}} btnTitle="查看"/>,
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -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(<Link to="/approval?type=subscribe">订阅申请</Link>, 'subscribe'),
|
||||
getItem(<Link to="/approval?type=release">发布申请</Link>, 'release')],
|
||||
getItem(<Link to="/approval?type=subscribe">{$t('订阅申请')}</Link>, 'subscribe'),
|
||||
getItem(<Link to="/approval?type=release">{$t('发布申请')}</Link>, 'release')],
|
||||
'group'),
|
||||
];
|
||||
|
||||
const items: TabsProps['items'] = [
|
||||
{
|
||||
key: '0',
|
||||
label: '待审批',
|
||||
label: $t('待审批'),
|
||||
},
|
||||
{
|
||||
key: '1',
|
||||
label: '已审批',
|
||||
label: $t('已审批'),
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user