mirror of
https://github.com/APIParkLab/APIPark.git
synced 2026-06-14 20:41:15 +08:00
@@ -15,6 +15,7 @@ export interface ConfigField<T> {
|
||||
renderText?: (value: unknown, record: T) => string;
|
||||
required?: boolean;
|
||||
ellipsis?:boolean
|
||||
unRender?:(form:FormInstance)=>boolean
|
||||
}
|
||||
|
||||
interface EditableTableWithModalProps<T> {
|
||||
@@ -39,6 +40,7 @@ const EditableTableWithModal = <T extends { _id?: string }>({
|
||||
const [configurations, setConfigurations] = useState<T[]>(value ||[]);
|
||||
const [editingConfig, setEditingConfig] = useState<T | null>(null);
|
||||
const {state} = useGlobalContext()
|
||||
const [formsValue, setFormsValue] = useState<FormInstance<unknown>>()
|
||||
|
||||
const showModal = (config?: T) => {
|
||||
if (config) {
|
||||
@@ -111,18 +113,23 @@ const EditableTableWithModal = <T extends { _id?: string }>({
|
||||
],[state.language, disabled, configFields])
|
||||
|
||||
|
||||
const formItems = configFields.map(({ title,key, component, required }) => {
|
||||
return (
|
||||
<Form.Item
|
||||
label={$t(title as string)}
|
||||
name={key as string}
|
||||
rules={[{ required}]}
|
||||
>
|
||||
{component}
|
||||
</Form.Item>
|
||||
)
|
||||
const formItems = useMemo(()=>{
|
||||
return configFields.map(({ title,key, component, required,unRender }) => {
|
||||
return (
|
||||
unRender && unRender(formsValue) ? null :
|
||||
<Form.Item
|
||||
label={$t(title as string)}
|
||||
name={key as string}
|
||||
rules={[{ required}]}
|
||||
>
|
||||
{component}
|
||||
</Form.Item>
|
||||
)
|
||||
})
|
||||
}
|
||||
);
|
||||
,[formsValue])
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -142,6 +149,9 @@ const EditableTableWithModal = <T extends { _id?: string }>({
|
||||
<WithPermission access=""><Form form={form} name="editableTableWithModal"
|
||||
layout="vertical"
|
||||
scrollToFirstError
|
||||
onFieldsChange={(()=>{
|
||||
setFormsValue(form.getFieldsValue())
|
||||
})}
|
||||
// labelCol={{ span: 7 }}
|
||||
// wrapperCol={{ span: 17}}
|
||||
autoComplete="off">
|
||||
|
||||
@@ -195,7 +195,7 @@ export const PublishApprovalModalContent = forwardRef<PublishApprovalModalHandle
|
||||
</Form.Item>
|
||||
</>
|
||||
}
|
||||
<Row className="mt-mbase pb-[8px] h-[32px] font-bold" ><span >{$t('API 列表')}:</span></Row>
|
||||
<Row className="mt-mbase pb-[8px] h-[32px] font-bold" ><span >{$t('路由列表')}:</span></Row>
|
||||
<Row className="mb-mbase ">
|
||||
<Table
|
||||
columns={translatedRouteColumns}
|
||||
|
||||
@@ -215,9 +215,9 @@ export const ApprovalStatusColorClass = {
|
||||
export const ApprovalRouteColumns = [
|
||||
{
|
||||
title:('请求方式'),
|
||||
dataIndex:'method',
|
||||
dataIndex:'methods',
|
||||
ellipsis:true,
|
||||
renderText:(value)=>value.join(',')
|
||||
render:(value)=>value?.join(', ')
|
||||
},
|
||||
{
|
||||
title:('路径'),
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
{
|
||||
"K4758140d": "路由列表"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
{
|
||||
"K71753476": "是否放行",
|
||||
"K597435c5": "监控",
|
||||
"Kde9d6e8e": "开启拦截后,网关会拦截所有该路径的请求,相当于防火墙禁用了特定路径的访问。"
|
||||
"K4758140d": "路由列表"
|
||||
}
|
||||
|
||||
@@ -72,8 +72,8 @@ export const SYSTEM_I18NEXT_FOR_ENUM = {
|
||||
|
||||
export const HTTP_METHOD = ['GET','POST','PUT','DELETE','PATCH','HEAD']
|
||||
export const API_PROTOCOL = [
|
||||
{label:'HTTP',value:'http'},
|
||||
{label:'HTTPS',value:'https'}
|
||||
{label:'HTTP',value:'HTTP'},
|
||||
{label:'HTTPS',value:'HTTPS'}
|
||||
]
|
||||
|
||||
|
||||
@@ -259,6 +259,7 @@ export const MATCH_CONFIG:ConfigField<MatchItem>[] = [
|
||||
}, {
|
||||
title:('参数值'),
|
||||
key: 'pattern',
|
||||
unRender:(formValue)=>{return formValue?.matchType === 'NULL' || formValue?.matchType==='EXIST' || formValue?.matchType === 'UNEXIST'},
|
||||
component: <Input className="w-INPUT_NORMAL"/>,
|
||||
renderText: (value: string) => {
|
||||
return value
|
||||
@@ -278,17 +279,17 @@ export const SYSTEM_API_TABLE_COLUMNS: PageProColumns<SystemApiTableListItem>[]
|
||||
title:('协议'),
|
||||
dataIndex: 'protocols',
|
||||
ellipsis:true,
|
||||
renderText:(value)=>value?.join(',')
|
||||
renderText:(value)=>value?.join(', ')
|
||||
},
|
||||
{
|
||||
title:('方法'),
|
||||
dataIndex: 'method',
|
||||
dataIndex: 'methods',
|
||||
ellipsis:true,
|
||||
renderText:(value)=>value?.join(',')
|
||||
renderText:(value)=>value?.join(', ')
|
||||
},
|
||||
{
|
||||
title:'是否放行',
|
||||
dataIndex:'isDisabled',
|
||||
dataIndex:'disable',
|
||||
ellipsis:true,
|
||||
filters: true,
|
||||
onFilter: true,
|
||||
|
||||
@@ -95,7 +95,7 @@ export type SystemApiProxyFieldType = {
|
||||
id:string;
|
||||
description?:string;
|
||||
path:string;
|
||||
method:string[];
|
||||
methods:string[];
|
||||
match:MatchItem[]
|
||||
isDisable?: boolean;
|
||||
service?:string;
|
||||
@@ -295,6 +295,7 @@ export type SystemInsideApiProxyProps = {
|
||||
teamId:string
|
||||
initProxyValue?:SystemApiProxyType
|
||||
value?:SystemApiProxyType
|
||||
type:'add'|'edit'
|
||||
onChange?: (newConfigItems: SystemApiProxyType) => void; // 当配置项变化时,外部传入的回调函数
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { $t } from "@common/locales";
|
||||
import { useGlobalContext } from "@common/contexts/GlobalStateContext";
|
||||
|
||||
const SystemInsideApiProxy = forwardRef<SystemInsideApiProxyHandle,SystemInsideApiProxyProps>((props,ref)=>{
|
||||
const {value, onChange, className,initProxyValue} = props
|
||||
const {value, onChange, className,initProxyValue,type} = props
|
||||
const {state} = useGlobalContext()
|
||||
const [form] = Form.useForm();
|
||||
|
||||
@@ -51,7 +51,7 @@ const SystemInsideApiProxy = forwardRef<SystemInsideApiProxyHandle,SystemInsideA
|
||||
label={$t("转发上游路径")}
|
||||
name={'path'}
|
||||
>
|
||||
<Input prefix="/" className="w-INPUT_NORMAL" placeholder={$t(PLACEHOLDER.input)}/>
|
||||
<Input prefix={type === 'edit' ? null :"/"} className="w-INPUT_NORMAL" placeholder={$t(PLACEHOLDER.input)}/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item<SystemApiProxyType>
|
||||
|
||||
@@ -25,7 +25,7 @@ const SystemInsideRouterCreate = forwardRef<SystemInsideRouterCreateHandle,Syste
|
||||
const onFinish = ()=>{
|
||||
return Promise.all([proxyRef.current?.validate?.(), form.validateFields()]).then(([,formValue])=>{
|
||||
const body = {...formValue,path:formValue.path.trim(),proxy:{...formValue.proxy,path:formValue.proxy.path ? (formValue.proxy.path.startsWith('/')? formValue.proxy.path: '/'+ formValue.proxy.path) : undefined}}
|
||||
return fetchData<BasicResponse<null>>('service/router',{method: type === 'add' ? 'POST' : 'PUT',eoBody:(body), eoParams: {service:serviceId,team:teamId, ...(type === 'edit' ? {router:entity?.id}: {})},eoTransformKeys:['matchType','isDisable']}).then(response=>{
|
||||
return fetchData<BasicResponse<null>>('service/router',{method: type === 'add' ? 'POST' : 'PUT',eoBody:(body), eoParams: {service:serviceId,team:teamId, ...(type === 'edit' ? {router:entity?.id}: {})},eoTransformKeys:['matchType','disable']}).then(response=>{
|
||||
const {code,msg} = response
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
message.success(msg || $t(RESPONSE_TIPS.success))
|
||||
@@ -63,11 +63,11 @@ const SystemInsideRouterCreate = forwardRef<SystemInsideRouterCreateHandle,Syste
|
||||
|
||||
const getRouterConfig = ()=>{
|
||||
setLoading(true)
|
||||
fetchData<BasicResponse<{router:SystemApiProxyFieldType}>>('service/router/detail',{method:'GET',eoParams:{service:serviceId,team:teamId, router:entity!.id}}).then(response=>{
|
||||
fetchData<BasicResponse<{router:SystemApiProxyFieldType}>>('service/router/detail',{method:'GET',eoParams:{service:serviceId,team:teamId, router:entity!.id}, eoTransformKeys:['create_time','update_time','match_type','upstream_id','opt_type']}).then(response=>{
|
||||
const {code,data,msg} = response
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
const {isDisable, protocols, path, method, description, match, proxy} = data.router
|
||||
form.setFieldsValue({isDisable, protocols, path, method, description, match,proxy
|
||||
const {disable, protocols, path, methods, description, match, proxy} = data.router
|
||||
form.setFieldsValue({disable, protocols, path, methods, description, match,proxy
|
||||
})
|
||||
}else{
|
||||
message.error(msg || $t(RESPONSE_TIPS.error))
|
||||
@@ -85,7 +85,7 @@ const SystemInsideRouterCreate = forwardRef<SystemInsideRouterCreateHandle,Syste
|
||||
form.setFieldValue('prefix',apiPrefix)
|
||||
form.setFieldValue(['proxy','timeout'],10000)
|
||||
form.setFieldValue(['proxy','retry'],0)
|
||||
form.setFieldValue('protocols',['http','https'])
|
||||
form.setFieldValue('protocols',['HTTP','HTTPS'])
|
||||
break;
|
||||
case 'copy':
|
||||
// form.setFieldsValue({
|
||||
@@ -134,7 +134,7 @@ const SystemInsideRouterCreate = forwardRef<SystemInsideRouterCreateHandle,Syste
|
||||
<Row className="mb-btnybase" > <Col ><span className="font-bold mr-[13px]">{$t('API 基础信息')}</span></Col></Row>
|
||||
<Form.Item<SystemApiProxyFieldType>
|
||||
label={$t("拦截该接口的请求")}
|
||||
name="isDisable"
|
||||
name="disable"
|
||||
extra={$t('开启拦截后,网关会拦截所有该路径的请求,相当于防火墙禁用了特定路径的访问。')}
|
||||
>
|
||||
<Switch />
|
||||
@@ -158,13 +158,13 @@ const SystemInsideRouterCreate = forwardRef<SystemInsideRouterCreateHandle,Syste
|
||||
}]}
|
||||
className={styles['form-input-group']}
|
||||
>
|
||||
<Input prefix={(prefixForce ? `${apiPrefix}/` :"/")} className="w-INPUT_NORMAL"
|
||||
<Input prefix={type === 'edit' ? null :(prefixForce ? `${apiPrefix}/` :"/")} className="w-INPUT_NORMAL"
|
||||
placeholder={$t(PLACEHOLDER.input)}/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item<SystemApiProxyFieldType>
|
||||
label={$t("请求方式")}
|
||||
name="method"
|
||||
name="methods"
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
<Select className="w-INPUT_NORMAL" placeholder={$t(PLACEHOLDER.select)} mode="multiple" options={HTTP_METHOD.map((method:string)=>{
|
||||
@@ -197,7 +197,7 @@ const SystemInsideRouterCreate = forwardRef<SystemInsideRouterCreateHandle,Syste
|
||||
className="mb-0 bg-transparent border-none p-0"
|
||||
name="proxy"
|
||||
>
|
||||
<SystemInsideApiProxy serviceId={serviceId!} teamId={teamId!} ref={proxyRef} />
|
||||
<SystemInsideApiProxy type={type} serviceId={serviceId!} teamId={teamId!} ref={proxyRef} />
|
||||
</Form.Item>
|
||||
</>}
|
||||
</div>
|
||||
|
||||
@@ -46,7 +46,7 @@ const SystemInsideRouterList:FC = ()=>{
|
||||
});
|
||||
}
|
||||
|
||||
return fetchData<BasicResponse<{routers:SystemApiTableListItem}>>('service/routers',{method:'GET',eoParams:{service:serviceId,team:teamId, keyword:searchWord},eoTransformKeys:['request_path','create_time','update_time','is_disable']}).then(response=>{
|
||||
return fetchData<BasicResponse<{routers:SystemApiTableListItem}>>('service/routers',{method:'GET',eoParams:{service:serviceId,team:teamId, keyword:searchWord},eoTransformKeys:['request_path','create_time','update_time','disable']}).then(response=>{
|
||||
const {code,data,msg} = response
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
setTableListDataSource(data.routers)
|
||||
@@ -171,7 +171,7 @@ const SystemInsideRouterList:FC = ()=>{
|
||||
x.valueEnum = tmpValueEnum
|
||||
}
|
||||
|
||||
if(x.filters &&((x.dataIndex as string[])?.indexOf('isDisabled') !== -1) ){
|
||||
if(x.filters &&((x.dataIndex as string[])?.indexOf('disable') !== -1) ){
|
||||
x.valueEnum = {
|
||||
true:{text:<span className="text-status_fail">{$t('拦截')}</span>},
|
||||
false:{text:<span className="text-status_success">{$t('放行')}</span>}
|
||||
@@ -201,7 +201,7 @@ const SystemInsideRouterList:FC = ()=>{
|
||||
request={()=>getRoutesList()}
|
||||
dataSource={tableListDataSource}
|
||||
addNewBtnTitle={$t('添加路由')}
|
||||
searchPlaceholder={$t('输入名称、URL 查找路由')}
|
||||
searchPlaceholder={$t('输入 URL 查找路由')}
|
||||
onAddNewBtnClick={()=>{openDrawer('add')}}
|
||||
addNewBtnAccess="team.service.router.add"
|
||||
tableClickAccess="team.service.router.view"
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
|
||||
import { App, Table } from "antd";
|
||||
import { App, Table, Tooltip } from "antd";
|
||||
import { SYSTEM_PUBLISH_ONLINE_COLUMNS } from "../../../const/system/const";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useFetch } from "@common/hooks/http";
|
||||
import { BasicResponse, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const";
|
||||
import { BasicResponse, RESPONSE_TIPS, STATUS_CODE, STATUS_COLOR } from "@common/const/const";
|
||||
import { EntityItem } from "@common/const/type";
|
||||
import { LoadingOutlined } from "@ant-design/icons";
|
||||
import { $t } from "@common/locales";
|
||||
import { useGlobalContext } from "@common/contexts/GlobalStateContext";
|
||||
|
||||
type SystemInsidePublishOnlineProps = {
|
||||
serviceId:string
|
||||
@@ -23,6 +26,7 @@ export default function SystemInsidePublishOnline(props:SystemInsidePublishOnlin
|
||||
const [dataSource, setDataSource] = useState<[]>()
|
||||
const {fetchData} = useFetch()
|
||||
const [isStopped, setIsStopped] = useState(false);
|
||||
const { state } = useGlobalContext()
|
||||
|
||||
const getOnlineStatus = ()=>{
|
||||
fetchData<BasicResponse<{publishStatusList:SystemInsidePublishOnlineItems[]}>>('service/publish/status',{method:'GET',eoParams:{service:serviceId,team:teamId, id}, eoTransformKeys:['publish_status_list']}).then(response=>{
|
||||
@@ -55,11 +59,28 @@ export default function SystemInsidePublishOnline(props:SystemInsidePublishOnlin
|
||||
};
|
||||
}, [isStopped]);
|
||||
|
||||
|
||||
const translatedPublishColumns = useMemo(()=>SYSTEM_PUBLISH_ONLINE_COLUMNS.map((x)=>{
|
||||
if(x.dataIndex === 'status'){
|
||||
return {...x,title:$t(x.title),
|
||||
render:(_:unknown,entity:SystemInsidePublishOnlineItems)=>{
|
||||
switch(entity.status){
|
||||
case 'done':
|
||||
return <span className={STATUS_COLOR[entity.status as keyof typeof STATUS_COLOR]}>{$t('成功')}</span>
|
||||
case 'error':
|
||||
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 />
|
||||
}
|
||||
}}
|
||||
}
|
||||
}),[state.language])
|
||||
|
||||
return (
|
||||
<Table
|
||||
className="min-h-[100px] h-full"
|
||||
bordered={true}
|
||||
columns={[...SYSTEM_PUBLISH_ONLINE_COLUMNS]}
|
||||
columns={translatedPublishColumns}
|
||||
size="small"
|
||||
rowKey="id"
|
||||
dataSource={dataSource}
|
||||
|
||||
@@ -17,7 +17,7 @@ const ServiceHubApiDocument = ({service}:{service:ServiceDetailType})=>{
|
||||
useEffect(()=>{
|
||||
if(!service) return
|
||||
setServiceName(service?.name)
|
||||
setApiDocument(service.apiDoc)
|
||||
setApiDocument(service?.apiDoc)
|
||||
},[service])
|
||||
|
||||
useEffect(() => {
|
||||
@@ -41,7 +41,7 @@ const ServiceHubApiDocument = ({service}:{service:ServiceDetailType})=>{
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Drawer
|
||||
{/* <Drawer
|
||||
title={serviceName}
|
||||
maskClosable={false}
|
||||
width="100%" placement="right" onClose={onClose} open={apiTestDrawOpen}
|
||||
@@ -51,7 +51,7 @@ const ServiceHubApiDocument = ({service}:{service:ServiceDetailType})=>{
|
||||
closeIcon={false}
|
||||
>
|
||||
<ApiTestGroup apiInfoList={apiDocs} selectedApiId={selectedTestApi}/>
|
||||
</Drawer>
|
||||
</Drawer> */}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user