import React, { useState, useEffect } from 'react';
|
import {
|
Dialog,
|
DialogTitle,
|
DialogContent,
|
DialogActions,
|
TextField,
|
Button as MuiButton,
|
List,
|
ListItem,
|
ListItemText,
|
ListItemButton,
|
Chip,
|
Box,
|
Typography,
|
Divider,
|
Stack,
|
} from '@mui/material';
|
import { Search as SearchIcon } from '@mui/icons-material';
|
import request from '@/utils/request';
|
|
/**
|
* 接口选择器组件
|
* 用于从系统加载可用接口列表并选择
|
*/
|
const ApiSelector = ({ open, onClose, onSelect, currentUrl = '' }) => {
|
const [apiList, setApiList] = useState([]);
|
const [filteredApiList, setFilteredApiList] = useState([]);
|
const [searchText, setSearchText] = useState('');
|
const [loading, setLoading] = useState(false);
|
|
// 预定义的常用接口列表
|
const predefinedApis = [
|
{ method: 'POST', path: '/rcs/test/execute', description: 'RCS测试执行', category: 'RCS测试' },
|
{ method: 'POST', path: '/wcs/create/in/task', description: '创建入库任务', category: 'WCS' },
|
{ method: 'POST', path: '/rsf-open-api/rcs/api/open/location/allocate', description: '申请库位分配', category: 'RCS开放接口' },
|
{ method: 'POST', path: '/matnr/page', description: '物料分页查询', category: '基础数据' },
|
{ method: 'POST', path: '/basStation/list', description: '站点列表', category: '基础数据' },
|
{ method: 'POST', path: '/loc/page', description: '库位分页查询', category: '基础数据' },
|
{ method: 'POST', path: '/deviceSite/selectStaList/list', description: '设备站点列表', category: '基础数据' },
|
{ method: 'POST', path: '/task/list', description: '任务列表', category: '任务管理' },
|
{ method: 'POST', path: '/waitPakin/page', description: '组托单分页查询', category: '组托管理' },
|
];
|
|
useEffect(() => {
|
if (open) {
|
loadApiList();
|
}
|
}, [open]);
|
|
useEffect(() => {
|
filterApis();
|
}, [searchText, apiList]);
|
|
const loadApiList = async () => {
|
setLoading(true);
|
try {
|
// 这里可以从系统加载接口列表
|
// 暂时使用预定义列表
|
setApiList(predefinedApis);
|
} catch (error) {
|
console.error('加载接口列表失败:', error);
|
setApiList(predefinedApis);
|
} finally {
|
setLoading(false);
|
}
|
};
|
|
const filterApis = () => {
|
if (!searchText.trim()) {
|
setFilteredApiList(apiList);
|
return;
|
}
|
|
const filtered = apiList.filter(api => {
|
const searchLower = searchText.toLowerCase();
|
return (
|
api.path.toLowerCase().includes(searchLower) ||
|
api.description.toLowerCase().includes(searchLower) ||
|
api.category.toLowerCase().includes(searchLower) ||
|
api.method.toLowerCase().includes(searchLower)
|
);
|
});
|
setFilteredApiList(filtered);
|
};
|
|
const handleSelect = (api) => {
|
// 构建完整URL(需要根据实际环境配置)
|
const baseUrl = window.location.origin;
|
const fullUrl = api.path.startsWith('http') ? api.path : `${baseUrl}${api.path}`;
|
|
onSelect({
|
method: api.method,
|
url: fullUrl,
|
path: api.path,
|
description: api.description,
|
});
|
onClose();
|
};
|
|
const handleManualInput = () => {
|
onSelect({
|
method: 'POST',
|
url: currentUrl || '',
|
path: '',
|
description: '手动输入',
|
});
|
onClose();
|
};
|
|
return (
|
<Dialog open={open} onClose={onClose} maxWidth="md" fullWidth>
|
<DialogTitle>选择接口</DialogTitle>
|
<DialogContent>
|
<Stack spacing={2}>
|
<TextField
|
fullWidth
|
size="small"
|
placeholder="搜索接口路径、描述或分类..."
|
value={searchText}
|
onChange={(e) => setSearchText(e.target.value)}
|
InputProps={{
|
startAdornment: <SearchIcon sx={{ mr: 1, color: 'text.secondary' }} />,
|
}}
|
/>
|
|
<Box>
|
<Typography variant="subtitle2" gutterBottom>
|
常用接口 ({filteredApiList.length})
|
</Typography>
|
<List sx={{ maxHeight: 400, overflow: 'auto' }}>
|
{filteredApiList.map((api, index) => (
|
<ListItem key={index} disablePadding>
|
<ListItemButton onClick={() => handleSelect(api)}>
|
<ListItemText
|
primary={
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
<Chip
|
label={api.method}
|
size="small"
|
color={api.method === 'GET' ? 'primary' : 'secondary'}
|
/>
|
<Typography variant="body2" sx={{ fontFamily: 'monospace' }}>
|
{api.path}
|
</Typography>
|
</Box>
|
}
|
secondary={api.description}
|
/>
|
<Chip label={api.category} size="small" variant="outlined" />
|
</ListItemButton>
|
</ListItem>
|
))}
|
</List>
|
</Box>
|
|
<Divider />
|
|
<Box>
|
<Typography variant="subtitle2" gutterBottom>
|
手动输入
|
</Typography>
|
<TextField
|
fullWidth
|
size="small"
|
placeholder="输入完整的接口URL,如:http://example.com/api/test"
|
value={currentUrl}
|
onChange={(e) => {
|
// 这里可以更新currentUrl,但需要父组件支持
|
}}
|
helperText="可以直接输入完整的接口URL"
|
/>
|
</Box>
|
</Stack>
|
</DialogContent>
|
<DialogActions>
|
<MuiButton onClick={onClose}>取消</MuiButton>
|
<MuiButton onClick={handleManualInput} variant="contained">
|
使用手动输入
|
</MuiButton>
|
</DialogActions>
|
</Dialog>
|
);
|
};
|
|
export default ApiSelector;
|