import fetch from 'dva/fetch';
import {
notification
} from 'antd';
import qs from 'querystring';
const codeMessage = {
200: '请求成功',
201: '新建或修改数据成功',
202: '一个请求已经进入后台队列',
204: '删除数据成功',
400: '请求失败',
401: 'token失效',
403: '禁止访问',
404: '请求失败',
406: '请求方式错误',
500: '服务器错误',
502: '网关错误',
503: '服务不可用',
504: '网关超时',
};
// 检查ajax返回的状态
function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response;
}
/**
* 暂时没用,服务端返回的 status 始终为200
*
* @type {*|string|string}
*/
const errorText = codeMessage[response.status] || response.statusText;
notification.error({
message: `请求错误 ${response.status}: ${response.url}`,
description: errorText,
});
const error = new Error(response.statusText);
error.name = response.status;
error.response = response;
throw error;
}
// fetch超时处理
const TIMEOUT = 100000;
const timeoutFetch = (url, options) => {
let fetchPromise = fetch(url, options);
let timeoutPromise = new Promise((resolve, reject) => {
setTimeout(() => reject(new Error('请求超时')), TIMEOUT);
});
return Promise.race([fetchPromise, timeoutPromise]);
};
/**
* 请求url,返回promise 对象
*
* @param {string} url The URL we want to request
* @param {object} [options] The options we want to pass to "fetch"
* @return {object} An object containing either "data" or "err"
*/
export default function request(url, options) {
const defaultOptions = {
credentials: 'include',
method: 'GET',
mode: 'cors',
};
const mergeOptions = {
...defaultOptions,
...options
};
const userInfo = JSON.parse(window.sessionStorage.getItem('userInfo'));
const appKey = window.sessionStorage.getItem('appKey');
mergeOptions.headers = {
accept: 'application/json',
'content-type': 'application/json; charset=utf-8',
...mergeOptions.headers,
};
if (appKey) mergeOptions.headers.uuuappkey = appKey;
if (userInfo) mergeOptions.headers.uuutoken = userInfo.sessionId;
if (mergeOptions.method !== 'GET') {
mergeOptions.body = JSON.stringify(mergeOptions.body);
}
if (mergeOptions.method !== 'POST' && mergeOptions.params) {
url = `${url}${url.indexOf('?') !== -1 ? '&' : '?'}${qs.stringify(mergeOptions.params)}`;
}
if (!mergeOptions.hideTime && !mergeOptions.params) {
url = `${url}?timeStamp=${new Date().getTime()}`;
}
return timeoutFetch(url, mergeOptions)
.then(checkStatus)
.then((response) => {
return response.json();
})
.then((data) => {
if (data.code === 200 || data.success === true) {
return data;
}
if (data.code === 300) { // 接口出错
return data;
}
if (data.code === 401) { // token失效
notification.error({
message: 'token失效',
description: data.msg,
key: 'error'
});
window.g_app._store.dispatch({
type: 'app/logout'
});
return data;
}
if (data.code === 403) { // 没有权限
notification.error({
message: '没有权限',
description: data.msg,
key: 'error'
});
return data;
}
if (data.code >= 404 && data.code < 422) {
notification.error({
message: '请求失败',
description: data.msg,
key: 'error'
});
return data;
}
if (data.code <= 504 && data.code >= 500) {
notification.error({
message: '服务器错误',
description: data.msg,
key: 'error'
});
return data;
}
})
.catch((error) => {
const {
response
} = error;
let msg;
let statusCode;
if (response && response instanceof Object) {
const {
status,
statusText
} = response;
statusCode = status;
msg = statusText;
} else {
statusCode = 600;
msg = 'Network Error';
}
return Promise.reject({
success: false,
code: statusCode,
msg
});
});
}
调用:
import request from '../utils/request';
import { apiPrefix } from '../config/projectConfig';
// 获取 scheme 列表
export function oracleSchema() {
return request(`${apiPrefix}/api_manager/interface/api/fetchOracleSchemas`);
}
// 接口菜单层级树
export function interfaceLevel(pid) {
return request(
`${apiPrefix}/api_manager/interface/api/getAPILevelTree?pid=${pid}`,{
hideTime: true,
});
}
// 获取目录树
export function catalogTree() {
return request(`${apiPrefix}/api_manager/interface/api/getAPICatalogTree`);
}
// 搜索菜单树
export function searchLevelTree(search) {
return request(
`${apiPrefix}/api_manager/interface/api/searchAPILevelTree?search=${search}`, {
hideTime: true,
});
}
// 查询接口上级分类树
export function apiDirectory(apiId) {
return request(`${apiPrefix}/api_manager/interface/api/getAPIDirectory?apiId=${apiId}`, {
hideTime: true,
});
}
// 新增 API 树目录
export function addApiTree(params) {
return request(`${apiPrefix}/api_manager/interface/api/addApiTree`, {
method: 'POST',
body: params,
});
}
// 删除 API 树目录
export function delApiTree(params) {
return request(`${apiPrefix}/api_manager/interface/api/deleteApiTree?apiTreeId=${params.apiTreeId}`, {
method: 'DELETE',
hideTime: true,
});
}
/************************************************************************
* 接口相关
************************************************************************/
// 接口列表
export function apiList(params, pageNum, pageSize) {
return request(`${apiPrefix}/api_manager/interface/api/getApiList`, {
method: 'POST',
body: { ...params, pageNum, pageSize },
});
}
// 新增接口
export function addApi(params) {
return request(`${apiPrefix}/api_manager/interface/api/addApi`, {
method: 'POST',
body: params,
});
}
// 修改接口
export function updateApi(params) {
return request(`${apiPrefix}/api_manager/interface/api/updateApi`, {
method: 'PUT',
body: params,
});
}
// 删除接口
export function delApi(params) {
return request(`${apiPrefix}/api_manager/interface/api/deleteApi?apiId=${params.apiId}`, {
method: 'DELETE',
hideTime: true,
});
}
/************************************************************************
* sql相关
************************************************************************/
// 获取 sql
export function getApiSqlInfo(params) {
return request(`${apiPrefix}/api_manager/interface/api/getApiSqlInfo?apiId=${params.apiId}`, {
hideTime: true,
});
}
// 保存
export function interfaceDefSave(params) {
return request(`${apiPrefix}/api_manager/interface/api/interfaceDefSave`, {
method: 'POST',
body: params,
});
}
// 获取模型列表 - 表名
export function getBizList(params, pageNum, pageSize) {
return request(`${apiPrefix}/api_manager/interface/api/getBizList`, {
method: 'POST',
body: { ...params, pageNum, pageSize },
});
}
// 获取模型列表 - 列名
export function getBizColList(bizId) {
return request(`${apiPrefix}/api_manager/interface/api/getBizColList?bizId=${bizId}`, {
hideTime: true,
});
}
// 解析 sql 获得 select item 列表(出参)
export function selectItemsForSql(params) {
return request(`${apiPrefix}/api_manager/interface/api/getSelectItemsForSql`, {
method: 'POST',
body: params,
});
}
// 获取 procedure info
export function procedureInfo(params) {
return request(`${apiPrefix}/api_manager/interface/api/fetchOracleProcedureInfo`, {
method: 'POST',
body: params,
});
}
// 获取 procedure params
export function procedureParams({ owner, procedureName }) {
return request(`${apiPrefix}/api_manager/interface/api/fetchOracleAllProcedureParams`, {
params: {
owner,
procedureName,
},
});
}
/************************************************************************
* auth相关
************************************************************************/
// 获取系统名
export function appNameApi({ apiId }) {
return request(`${apiPrefix}/menu_manager/menu/api/getAppNameForApi?apiId=${apiId}`, {
method: 'POST',
hideTime: true,
});
}
// 获取指标列表
export function indexAppName(params) {
return request(`${apiPrefix}/menu_manager/menu/api/getIndexForAppName`, {
method: 'POST',
body: params,
});
}
// 保存 auth
export function addIndexAppName(params) {
return request(`${apiPrefix}/menu_manager/menu/api/addIndexForAppName`, {
method: 'POST',
body: [...params],
});
}
dva模型调用:
import { message } from 'antd';
import modelExtend from 'dva-model-extend';
import { pageModel } from '../../../utils/util';
import {
addApiTree,
addApi,
getApiSqlInfo,
interfaceDefSave,
selectItemsForSql,
procedureInfo,
procedureParams,
appNameApi,
indexAppName,
addIndexAppName,
} from '../../../services/modelInterface';
export default modelExtend(pageModel, {
namespace: 'interfaceModal',
state: {
interfaceDef: {},
},
effects: {
// 获取 接口定义
* getApiSqlInfo({ payload }, { call, put }) {
const { success, data } = yield call(getApiSqlInfo, payload);
if (success) {
if (data.apiType === 0) data.apiType = 1;
yield put({
type: 'updateState',
payload: {
interfaceDef: data,
},
});
return true;
} else {
message.error('初始化失败');
}
},
/************************************************************************
* sql 弹窗相关
************************************************************************/
// sql弹窗保存
* interfaceDefSave({ payload }, { call }) {
const { success } = yield call(interfaceDefSave, payload);
if (success) return true;
},
// 解析 sql 获得 select item 列表(出参)
* getSelectItemsForSql({ payload }, { call }) {
const { success, data } = yield call(selectItemsForSql, payload);
if (success) return data;
},
// 获取 oracleChildSchema
* procedureInfo({ payload }, { call }) {
const { success, data } = yield call(procedureInfo, payload);
if (success) return data.list;
},
// 获取 SP 入参字段
* procedureParams({ payload }, { call }) {
const { success, data } = yield call(procedureParams, payload);
if (success) return data;
},
/************************************************************************
* auth 弹窗相关
************************************************************************/
// 获取系统名
* appNameApi({ payload }, { call }) {
const { success, data } = yield call(appNameApi, payload);
if (success) return data;
},
// 获取指标
* indexAppName({ payload }, { call }) {
const { success, data } = yield call(indexAppName, payload);
if (success) return data;
},
// 保存auth
* addIndexAppName({ payload }, { call }) {
const { success } = yield call(addIndexAppName, payload);
if (success) return true;
},
},
});
模块组成:
组件具体使用:
import React, { Component, Fragment } from 'react';
import { connect } from 'dva';
import PropTypes from 'prop-types';
import { Col, Row, Button, Modal, Collapse, Card, Icon, Tooltip, Form, Input } from 'antd';
import { ContextMenu, MenuItem } from 'react-contextmenu';
import { Page, SearchTree, CommonTable, CustomModal, CustomForm, CommonSearch, Breadcrumb } from '@/components';
import { apiList } from '../../services/modelInterface';
import { modelInterfaceColumns, participationColumns } from './config/columns';
import { sqlForm, folderForm, interfaceForm } from './config/form';
import { modelInterfaceSearch } from './config/search';
import { getCrumb } from '../../utils/util';
import ModalView from './components';
import style from './index.less';
const { Panel } = Collapse;
const { TextArea } = Input;
@connect(({ modelInterface, loading }) => ({
...modelInterface,
loading,
}))
class ModelInterface extends Component {
tableRef = React.createRef();
state = {
editable: false,
searchParams: {},
selectedNode: {},
visible: false, // 模态框状态
modalType: '', // 模态框类型
record: {}, // 编辑时原始数据
};
static getDerivedStateFromProps(props, state) {
const { dispatch, selectedNode } = props;
if (props.selectedNode !== state.selectedNode && props.selectedNode) {
const { id, isDirectory } = props.selectedNode;
if (id) {
dispatch({ type: 'modelInterface/getBizDirectory', id });
if (!isDirectory) {
// dispatch({ type: 'bizFormTable/bizInfo', payload: { id } });
}
return { selectedNode };
}
}
return null;
}
// 处理搜索
handleSearch = (values) => {
this.setState({ searchParams: values });
};
// 模态框状态处理
showModal = async ({ record, modalType }) => {
const { dispatch } = this.props;
if (modalType === 'sql') {
const data = await dispatch({ type: 'interfaceModal/getApiSqlInfo', payload: { apiId: record.apiId } });
if (!data) return;
}
this.setState({ visible: true, modalType, record });
};
closeModal = () => this.setState({ visible: false, modalType: '', record: {} });
// 选择接口
handleSelect = async (keys, { node }) => {
const { dispatch, selectedNode } = this.props;
const dataRef = node.props['dataRef'];
const flag = selectedNode.id !== dataRef.id;
if (flag) {
this.setState({ editable: false });
if (dataRef['subNodeNum']) {
await dispatch({ type: 'modelInterface/levelTreeList', pid: dataRef.id });
}
dispatch({ type: 'modelInterface/updateState', payload: { selectedNode: dataRef } });
}
};
// 新增目录
handleAddFolder = (e, data, target) => {
const nodeItem = JSON.parse(target.getAttribute('data-item'));
this.setState({ visible: true, modalType: 'folder', record: { upperApiTreeId: nodeItem.id } });
};
// 删除目录
handleDelFolder = (e, data, target) => {
const nodeItem = JSON.parse(target.getAttribute('data-item'));
Modal.confirm({
title: '提示',
content: '你确定删除该目录嘛?',
onOk: async () => {
const { dispatch } = this.props;
await dispatch({ type: 'modelInterface/delApiTree', payload: { apiTreeId: nodeItem.id } });
dispatch({ type: 'modelInterface/interfaceTree' });
},
onCancel() { },
});
};
// 删除接口
handleDelInterface = (e, data, target) => {
const nodeItem = JSON.parse(target.getAttribute('data-item'));
Modal.confirm({
title: '提示',
content: '你确定删除该接口嘛?',
onOk: async () => {
const { dispatch } = this.props;
await dispatch({ type: 'modelInterface/delApi', payload: { apiId: nodeItem.id } });
this.tableRef.current.handleFirstPage();
},
onCancel() { },
});
};
// 保存
handleSubmit = async (values) => {
const { modalType, record } = this.state;
const { dispatch } = this.props;
if (modalType === 'folder') {
await dispatch({
type: 'modelInterface/addApiTree',
payload: { ...record, ...values },
});
dispatch({ type: 'modelInterface/interfaceTree' });
}
// 新增或编辑接口
if (modalType === 'updateApi' || modalType === 'addApi') {
const params = record && record.apiId ? { ...values, apiId: record.apiId } : values;
await dispatch({
type: `modelInterface/${modalType}`,
payload: params,
});
this.tableRef.current.handleFirstPage();
}
};
// 面包屑点击
handleCrumbClick = async (item) => {
const { dispatch } = this.props;
dispatch({ type: 'modelInterface/levelTreeList', pid: item.id });
};
render() {
const { visible, modalType, record, searchParams } = this.state;
const { selectedNode, interfaceTree, expandedKeys, directoryInfo, catalogTree, dispatch, loading, form } = this.props;
console.log('interfaceTree>>>>>', interfaceTree)
const columns = [
...modelInterfaceColumns,
{
title: '操作',
dataIndex: 'operator',
render: (text, record) => (
),
},
];
const paramsColumns = [
...participationColumns,
{
title: '操作',
dataIndex: 'operator',
render: (text, record) => (
),
},
];
return (
{/* 树列表 */}
dispatch={dispatch} placeholder='请输入表名称' config={{ key: 'id', title: 'name' }} showRightMenu={true} showRemoteSearch={true} treeData={interfaceTree} defaultExpandedKeys={expandedKeys} iconFlagOptions={{ icon: 'api' }} handleSelect={this.handleSelect} modelFunc="modelInterface/searchTreeWithColCount" /> {/* 表格列表 */}
{/* style={{ marginTop: 12 }} columnNumber={2} showResetBtn={false} formList={modelInterfaceSearch} handleSearch={this.handleSearch} /> */}
rowKey="apiId" bordered={false} selectType={false} ref={this.tableRef} columns={paramsColumns} fetchList={apiList} searchParams={{ upperId: selectedNode.id, ...searchParams }} /> {/* 系统 */} {[{ appName: 'UCM', appComment: '系统内容' }, { appName: 'ACP', appComment: '系统内容' },] > 0 && [{ appName: 'UCM', appComment: '系统内容' }, { appName: 'ACP', appComment: '系统内容' },].map((sys, index) => (
className={style.sysBox} bodyStyle={{ padding: '24px', height: 150 }} >
))}
{/* 菜单 */}
{[{ appName: 'UCM', appComment: '系统内容' }, { appName: 'ACP', appComment: '系统内容' },].length > 0 && [{ appName: 'UCM', appComment: '系统内容' }, { appName: 'ACP', appComment: '系统内容' },].map((sys, index) => (
className={style.sysBox} bodyStyle={{ padding: '24px', height: 150 }} >
))}
rowKey="apiId" bordered={false} selectType={false} ref={this.tableRef} columns={paramsColumns} fetchList={apiList} searchParams={{ upperId: selectedNode.id, ...searchParams }} />
{/* 目录、接口弹窗 */}
{
['auth', 'sql'].indexOf(modalType) === -1 && (
visible={visible} record={record} onCancel={this.closeModal} onSubmit={this.handleSubmit} renderTitle={() => { if (modalType === 'folder') { return (record && !record.id) ? '新增目录' : '编辑目录'; } if (modalType === 'addApi') { return '新增接口'; } if (modalType === 'updateApi') { return '编辑接口'; } }} renderContent={(formOpts) => ( {modalType === 'folder' && {(modalType === 'addApi' || modalType === 'updateApi') && )} /> ) } {/* 授权、SQL弹窗 */} ); } } export default Form.create()(ModelInterface); 本文链接: http://www.luyixian.cn/news_show_186363.aspx