提交 1438af9f 作者: 郁骅焌

增加tab新增编辑页

上级 22f289ea
......@@ -3,7 +3,10 @@ const routes = [
'/system/menu',
'/system/dept',
'/system/user',
'/system/center'
'/system/center',
'/demo/tabcrud',
'/demo/tabcrud/add',
'/demo/tabcrud/edit'
]
export default {
......
......@@ -116,6 +116,22 @@ export default defineConfig({
icon: 'SolutionOutlined',
component: './demo/crud',
},
{
path: '/demo/tabcrud',
name: 'tabcrud',
icon: 'SolutionOutlined',
component: './demo/tabcrud',
},
{
path: '/demo/tabcrud/add',
name: 'crudadd',
component: './demo/tabcrud/components/CreateForm',
},
{
path: '/demo/tabcrud/edit',
name: 'crudedit',
component: './demo/tabcrud/components/UpdateForm',
},
],
},
{
......
......@@ -13,5 +13,5 @@ export default {
},
title: 'Sage Framework',
pwa: false,
iconfontUrl: '',
iconfontUrl: '//at.alicdn.com/t/font_1873986_zq2zexdsrnm.js',
};
import React from 'react'
import { Card } from 'antd'
import './style.less'
/**
*
* @param props
*/
const SageCard = (props) => {
const componentProps = {
...props
}
return (
<Card {...componentProps} />
)
}
export default SageCard
......@@ -24,6 +24,8 @@ import SimplePictureUpload from '../Upload/SimplePictureUpload'
import MultiplePictureUpload from '../Upload/MultiplePictureUpload'
import NormalUpload from '../Upload/NormalUpload'
import './style.less'
const { TextArea } = Input
const { Option } = Select
const { MonthPicker, RangePicker } = DatePicker
......@@ -87,7 +89,12 @@ const SageForm = (props, ref) => {
const {
formFields,
colNum = 1,
showSubmitButton = false,
showButtonRow = false, // 是否显示按钮行
showSubmitButton = false, // 是否显示提交按钮
showReturnButton = false, // 是否显示取消按钮
submitText = '提交',
returnText = '返回',
onReturn,
tailLayout = {
wrapperCol: { offset: 4, span: 20 }
},
......@@ -96,6 +103,12 @@ const SageForm = (props, ref) => {
const [form] = Form.useForm();
// const onReturn = () => {
// if (props.onReturn) {
// props.onReturn()
// }
// }
// 暴露外部方法
useImperativeHandle(ref, () => ({
submit: () => form.submit(),
......@@ -245,18 +258,28 @@ const SageForm = (props, ref) => {
// initialValues={{ remember: true }}
validateMessages={validateMessages}
{...formProps}
className="sage-form"
>
<Row span={24}>
{formNode}
</Row>
{
showSubmitButton ?
showButtonRow ?
<Row span={24}>
<Col span={24}>
<Form.Item {...tailLayout}>
<Button type="primary" htmlType="submit">
保存
</Button>
{
showSubmitButton ?
<Button type="primary" htmlType="submit" className="sage-form-buttn">
{submitText}
</Button> : null
}
{
showReturnButton ?
<Button htmlType="button" onClick={() => onReturn && onReturn()} className="sage-form-buttn">
{returnText}
</Button> : null
}
</Form.Item>
</Col>
</Row> : null
......
.sage-form {
.sage-form-buttn {
margin-right: 8px;
}
}
......@@ -76,7 +76,7 @@ const SageTable = React.forwardRef((props, ref) => {
const { isFullscreen, setFull, exitFull } = useFullscreen({
dom: () => document.getElementsByClassName('ant-pro-page-header-wrap-children-content')[0],
});
const [tableSize, setTableSize] = useState('default');
const [tableSize, setTableSize] = useState('small');
const [loading, setLoading] = useState(false);
const [tableState, setTableState] = useState(initState);
......
......@@ -5,6 +5,7 @@ import SageModal from './Modal'
import SageForm from './Form'
import SageTree from './Tree'
import SageMessage from './Message'
import SageCard from './Card'
import SageLayoutLR from './Layout/LayoutLR'
export {
......@@ -15,5 +16,6 @@ export {
SageModal,
SageForm,
SageTree,
SageMessage
SageMessage,
SageCard
}
import React, { useState, useEffect, useImperativeHandle } from 'react';
import { Tabs, Menu, Dropdown, Button } from 'antd';
import { ReloadOutlined } from '@ant-design/icons';
import { useLocation, useIntl, history, dropByCacheKey } from 'umi';
import { useLocation, useIntl, history, dropByCacheKey, connect } from 'umi';
import './style.less';
const { REACT_APP_ENV } = process.env;
const { TabPane } = Tabs;
const TabBar = (props, ref) => {
const TabBar = (props) => {
const location = useLocation();
const { pathname } = location;
const {
menuTree
menuTree,
tabActiveKey,
tabPanes,
allPath
} = props;
const [panes, setPanes] = useState([
{ title: '首页', key: '/home', closable: false },
// { title: '测试标签1', key: '2' },
// { title: '测试标签2', key: '3' },
// { title: 'Crud', key: '/demo/crud' },
// { title: '测试标签3', key: '4' },
// { title: '测试标签4', key: '5' },
// { title: '测试标签5', key: '6' },
// { title: '测试标签6', key: '7' },
// { title: '测试标签7', key: '8' },
// { title: '测试标签8', key: '9' },
// { title: '测试标签9', key: '10' },
// { title: '测试标签10', key: '11' },
// { title: '测试标签11', key: '12' },
// { title: '测试标签12', key: '13' }
]);
const [activeKey, setActiveKey] = useState('');
const [allPath, setAllPath] = useState([]);
// const [panes, setPanes] = useState([
// { title: '首页', key: '/home', closable: false },
// // { title: '测试标签1', key: '2' },
// // { title: '测试标签2', key: '3' },
// // { title: 'Crud', key: '/demo/crud' },
// // { title: '测试标签3', key: '4' },
// // { title: '测试标签4', key: '5' },
// // { title: '测试标签5', key: '6' },
// // { title: '测试标签6', key: '7' },
// // { title: '测试标签7', key: '8' },
// // { title: '测试标签8', key: '9' },
// // { title: '测试标签9', key: '10' },
// // { title: '测试标签10', key: '11' },
// // { title: '测试标签11', key: '12' },
// // { title: '测试标签12', key: '13' }
// ]);
// const [activeKey, setActiveKey] = useState('');
// const [allPath, setAllPath] = useState([]);
const { formatMessage } = useIntl();
const checkPaneExist = (path) => {
let isExist = false;
for (let i = 0; i < panes.length; i++) {
if (panes[i].key === path) {
for (let i = 0; i < tabPanes.length; i++) {
if (tabPanes[i].key === path) {
isExist = true;
break;
}
......@@ -49,12 +52,18 @@ const TabBar = (props, ref) => {
return item.path === path;
});
if (p) {
const newPanes = panes.slice();
const newPanes = tabPanes.slice();
newPanes.push({
title: REACT_APP_ENV === 'dev' ? formatMessage({id: p.menuName}) : p.menuName,
key: path,
});
setPanes(newPanes);
props.dispatch({
type: 'global/updateState',
payload: {
tabPanes: newPanes
}
})
// setPanes(newPanes);
}
}
};
......@@ -72,11 +81,17 @@ const TabBar = (props, ref) => {
});
};
loopPath(menuTree || []);
setAllPath(list);
props.dispatch({
type: 'global/updateState',
payload: {
allPath: list
}
})
// setAllPath(list);
let isExist = false;
for (let i = 0; i < panes.length; i++) {
if (panes[i].key === pathname) {
for (let i = 0; i < tabPanes.length; i++) {
if (tabPanes[i].key === pathname) {
isExist = true;
break;
}
......@@ -86,25 +101,49 @@ const TabBar = (props, ref) => {
return item.path === pathname;
});
if (p) {
const newPanes = panes.slice();
const newPanes = tabPanes.slice();
newPanes.push({
title: REACT_APP_ENV === 'dev' ? formatMessage({id: p.menuName}) : p.menuName,
key: pathname,
});
setPanes(newPanes);
props.dispatch({
type: 'global/updateState',
payload: {
tabPanes: newPanes
}
})
// setPanes(newPanes);
}
}
setActiveKey(pathname);
props.dispatch({
type: 'global/updateState',
payload: {
tabActiveKey: pathname
}
})
// setActiveKey(pathname);
}, []);
const onChange = (activekey, fromMenu) => {
if (activekey !== activeKey) {
if (activekey !== tabActiveKey) {
// setTimeout(() => {
setActiveKey(activekey);
props.dispatch({
type: 'global/updateState',
payload: {
tabActiveKey: activekey
}
})
// setActiveKey(activekey);
// }, 200)
if (!fromMenu) {
props.setSelectedKeys([activekey])
props.dispatch({
type: 'global/updateState',
payload: {
menuSelectedKeys: [activekey]
}
})
// props.setSelectedKeys([activekey])
props.checkMenuOpen(activekey)
history.push(activekey);
} else {
......@@ -116,13 +155,13 @@ const TabBar = (props, ref) => {
const remove = (targetKey) => {
let lastActiveKey = '/home';
let lastIndex;
panes.forEach((pane, i) => {
tabPanes.forEach((pane, i) => {
if (pane.key === targetKey) {
lastIndex = i - 1;
}
});
const lastPanes = panes.filter((pane) => pane.key !== targetKey);
if (lastPanes.length && activeKey === targetKey) {
const lastPanes = tabPanes.filter((pane) => pane.key !== targetKey);
if (lastPanes.length && tabActiveKey === targetKey) {
if (lastIndex >= 0) {
lastActiveKey = lastPanes[lastIndex].key;
} else {
......@@ -132,10 +171,24 @@ const TabBar = (props, ref) => {
lastActiveKey = lastPanes[lastPanes.length - 1].key;
}
// setTimeout(() => {
setActiveKey(lastActiveKey);
props.dispatch({
type: 'global/updateState',
payload: {
tabActiveKey: lastActiveKey,
menuSelectedKeys: [lastActiveKey],
tabPanes: lastPanes
}
})
// setActiveKey(lastActiveKey);
// }, 200)
setPanes(lastPanes);
props.setSelectedKeys([lastActiveKey])
// props.dispatch({
// type: 'global/updateState',
// payload: {
// tabPanes: lastPanes
// }
// })
// setPanes(lastPanes);
// props.setSelectedKeys([lastActiveKey])
props.checkMenuOpen(lastActiveKey)
history.push(lastActiveKey);
};
......@@ -149,8 +202,8 @@ const TabBar = (props, ref) => {
// 刷新
const refreshTab = (e) => {
e.preventDefault();
dropByCacheKey(activeKey);
history.push(activeKey);
dropByCacheKey(tabActiveKey);
history.push(tabActiveKey);
};
const menu = (
......@@ -161,30 +214,30 @@ const TabBar = (props, ref) => {
</Menu>
);
const getPanes = () => {
return panes
}
// const getPanes = () => {
// return panes
// }
// 暴露外部方法
useImperativeHandle(ref, () => ({
onChange,
getPanes,
setPanes,
setActiveKey
}));
// useImperativeHandle(ref, () => ({
// onChange,
// getPanes,
// setPanes,
// setActiveKey
// }));
return (
<div className="sage-tabbar">
<div className="sage-tabbar-left">
<Tabs
onChange={onChange}
activeKey={activeKey}
activeKey={tabActiveKey}
type="editable-card"
hideAdd
tabBarGutter={4}
onEdit={onEdit}
>
{panes.map((pane) => (
{tabPanes.map((pane) => (
<TabPane tab={pane.title} key={pane.key} closable={pane.closable} />
))}
</Tabs>
......@@ -198,4 +251,11 @@ const TabBar = (props, ref) => {
);
};
export default React.forwardRef(TabBar);
export default connect(({ global }) => ({
collapsed: global.collapsed,
menuSelectedKeys: global.menuSelectedKeys,
menuOpenKeys: global.menuOpenKeys,
tabActiveKey: global.tabActiveKey,
tabPanes: global.tabPanes,
allPath: global.allPath
}))(TabBar);
export default {
IconUrl: '//at.alicdn.com/t/font_1873986_zq2zexdsrnm.js'
}
......@@ -13,17 +13,12 @@ import RightContent from '@/components/GlobalHeader/RightContent';
import TabBar from '@/components/TabBar';
import GlobalFooter from '@/components/GlobalFooter';
import { getAuthorityFromRouter } from '@/utils/utils';
import config from '@/config.js'
import logo from '../assets/logo.svg';
import './BasicLayout.less'
const { REACT_APP_ENV } = process.env;
const IconFont = createFromIconfontCN({
scriptUrl: config.IconUrl,
});
const { SubMenu } = Menu;
const noMatch = (
......@@ -84,17 +79,24 @@ const BasicLayout = (props) => {
},
currentUser,
route,
collapsed
collapsed,
menuSelectedKeys,
menuOpenKeys,
// tabActiveKey
} = props;
const [selectedKeys, setSelectedKeys] = useState([location.pathname])
const [openKeys, setOpenKeys] = useState([])
// const [selectedKeys, setSelectedKeys] = useState([location.pathname])
// const [openKeys, setOpenKeys] = useState([])
const IconFont = createFromIconfontCN({
scriptUrl: settings.iconfontUrl,
});
/**
* constructor
*/
const tabBarRef = useRef();
// const tabBarRef = useRef();
const handleMenuCollapse = (payload) => {
if (dispatch) {
......@@ -105,11 +107,11 @@ const BasicLayout = (props) => {
}
}; // get children authority
const handlePageChange = ({ pathname }) => {
if (tabBarRef.current) {
tabBarRef.current.onChange(pathname, true);
}
};
// const handlePageChange = ({ pathname }) => {
// if (tabBarRef.current) {
// tabBarRef.current.onChange(pathname, true);
// }
// };
const authorized = getAuthorityFromRouter(props.route.routes, location.pathname || '/') || {
authority: undefined,
......@@ -194,15 +196,36 @@ const BasicLayout = (props) => {
// 选中菜单
const handleSelectMenu = ({item, key}) => {
setSelectedKeys([key])
history.push(key)
if (tabBarRef.current) {
tabBarRef.current.onChange(key, true);
props.dispatch({
type: 'global/updateState',
payload: {
menuSelectedKeys: [key],
tabActiveKey: key
}
})
// setSelectedKeys([key])
props.dispatch({
type: 'global/checkPaneExist',
payload: {
path: key
}
})
history.push(key)
// if (tabBarRef.current) {
// tabBarRef.current.onChange(key, true);
// }
}
const handleOpenChange = (_openKeys) => {
setOpenKeys(_openKeys.length > 1 ? [_openKeys.slice().pop()] : _openKeys)
props.dispatch({
type: 'global/updateState',
payload: {
menuOpenKeys: _openKeys.length > 1 ? [_openKeys.slice().pop()] : _openKeys
}
})
// setOpenKeys(_openKeys.length > 1 ? [_openKeys.slice().pop()] : _openKeys)
}
const menuTree = useMemo(() => getMenuTree(), [])
......@@ -213,7 +236,13 @@ const BasicLayout = (props) => {
for (let i = 0; i < list.length; i++) {
if (list[i].path === key) {
if (list[i].parentPath) {
setOpenKeys([list[i].parentPath])
props.dispatch({
type: 'global/updateState',
payload: {
menuOpenKeys: [list[i].parentPath]
}
})
// setOpenKeys([list[i].parentPath])
}
// setOpenKeys(list[i].parentPath ? [list[i].parentPath] : [])
break
......@@ -227,15 +256,15 @@ const BasicLayout = (props) => {
}
useEffect(() => {
const currentPath = location.pathname
props.dispatch({
type: 'global/updateState',
payload: {
menuSelectedKeys: [currentPath]
}
})
checkMenuOpen(currentPath)
checkMenuOpen(selectedKeys[0])
// if (dispatch) {
// dispatch({
// type: 'user/fetchCurrent',
// });
// }
// document.getElementsByClassName('ant-layout-header')[0].style.width = 'calc(100% - 256px)'
// document.getElementsByClassName('sage-tabbar')[0].style.width = 'calc(100% - 256px)'
}, []);
/**
* init variables
......@@ -270,8 +299,8 @@ const BasicLayout = (props) => {
<div>
<Menu
style={{ width: '100%' }}
selectedKeys={selectedKeys}
openKeys={openKeys}
selectedKeys={menuSelectedKeys}
openKeys={menuOpenKeys}
mode="inline"
theme="dark"
onSelect={handleSelectMenu}
......@@ -295,10 +324,10 @@ const BasicLayout = (props) => {
<RightContent goCenter={goCenter} />
</div>
<TabBar
ref={tabBarRef}
// ref={tabBarRef}
currentUser={currentUser}
menuTree={menuTree}
setSelectedKeys={setSelectedKeys}
// setSelectedKeys={setSelectedKeys}
checkMenuOpen={checkMenuOpen}
/>
</div>
......@@ -366,5 +395,8 @@ const BasicLayout = (props) => {
export default connect(({ user, global, settings }) => ({
currentUser: user.currentUser,
collapsed: global.collapsed,
menuSelectedKeys: global.menuSelectedKeys,
menuOpenKeys: global.menuOpenKeys,
tabActiveKey: global.tabActiveKey,
settings,
}))(BasicLayout);
import { history, dropByCacheKey } from 'umi'
import { queryNotices } from '@/services/user';
const GlobalModel = {
......@@ -5,6 +6,13 @@ const GlobalModel = {
state: {
collapsed: false,
notices: [],
menuSelectedKeys: [],
menuOpenKeys: [],
tabActiveKey: '',
tabPanes: [
{ title: '首页', key: '/home', closable: false }
],
allPath: []
},
effects: {
*fetchNotices(_, { call, put, select }) {
......@@ -67,8 +75,127 @@ const GlobalModel = {
},
});
},
// 跳转tab
*goTab({ payload }, { put, select }) {
const globalState = yield select(state => state.global)
const newState = {}
newState.menuSelectedKeys = [payload.path]
newState.tabActiveKey = payload.path
let isExist = false;
for (let i = 0; i < globalState.tabPanes.length; i++) {
if (globalState.tabPanes[i].key === payload.path) {
isExist = true;
break;
}
}
if (!isExist) {
const newPanes = globalState.tabPanes.slice();
newPanes.push({
// title: REACT_APP_ENV === 'dev' ? formatMessage({id: p.menuName}) : p.menuName,
title: payload.name,
key: payload.path,
});
newState.tabPanes = newPanes
}
if (payload.query) {
history.push({
pathname: payload.path,
query: payload.query
});
} else {
history.push(payload.path)
}
yield put({
type: 'updateState',
payload: {
...newState
},
});
},
// 返回tab
*returnTab({ payload }, { put, select }) {
const globalState = yield select(state => state.global)
dropByCacheKey(payload.closePath)
const tabPanes = globalState.tabPanes.slice()
let removeIndex;
tabPanes.forEach((pane, i) => {
if (pane.key === payload.closePath) {
removeIndex = i;
}
});
tabPanes.splice(removeIndex, 1)
const newState = {}
newState.menuSelectedKeys = [payload.returnPath]
newState.tabActiveKey = payload.returnPath
let isExist = false;
for (let i = 0; i < tabPanes.length; i++) {
if (tabPanes[i].key === payload.returnPath) {
isExist = true;
break;
}
}
if (!isExist) {
const newPanes = tabPanes.slice();
newPanes.push({
// title: REACT_APP_ENV === 'dev' ? formatMessage({id: p.menuName}) : p.menuName,
title: payload.returnName,
key: payload.returnPath,
});
newState.tabPanes = newPanes
} else {
newState.tabPanes = tabPanes
}
history.push(payload.returnPath)
yield put({
type: 'updateState',
payload: {
...newState
},
});
},
},
reducers: {
updateState(state, { payload }) {
return {...state, ...payload}
},
checkPaneExist(state, { payload }) {
let isExist = false;
for (let i = 0; i < state.tabPanes.length; i++) {
if (state.tabPanes[i].key === payload.path) {
isExist = true;
break;
}
}
if (!isExist) {
const p = state.allPath.find((item) => {
return item.path === payload.path;
});
if (p) {
const newPanes = state.tabPanes.slice();
newPanes.push({
// title: REACT_APP_ENV === 'dev' ? formatMessage({id: p.menuName}) : p.menuName,
title: p.menuName,
key: payload.path,
});
return {...state, tabPanes: newPanes}
// setPanes(newPanes);
}
}
return {
...state
}
},
changeLayoutCollapsed(
state = {
notices: [],
......
import React, { useState, useEffect, useRef } from 'react'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { connect, dropByCacheKey } from 'umi'
import { SageTable, SageButton, SageMessage, ActionSet } from '@/components/Common'
import { PlusOutlined, EditOutlined, DeleteOutlined, VerticalAlignBottomOutlined, VerticalAlignTopOutlined } from '@ant-design/icons';
import moment from 'moment';
import { queryCrud, updateCrud, removeCrud, getCrudDetail } from './service';
// 详情数据
const initDetail = {
id: null
}
const CrudList = (props) => {
// 状态数据
const [detail, setDetail] = useState(initDetail) // 详情
const [editable, setEditable] = useState(true) // 编辑按钮状态
const [removeable, setRemoveable] = useState(true) // 删除按钮状态
// ref对象
const tableRef = useRef();
const modalRef = useRef();
const updateFormRef = useRef();
useEffect(() => {
}, [])
// 查询条件
const searchFields = [
{
name: 'field2',
label: '字段2',
type: 'input',
props: {
placeholder: '请输入'
}
},
{
name: 'field3',
label: '字段3', // (固定下拉数据)
type: 'select',
options: [
{ text: '选项1', value: 'select1' },
{ text: '选项2', value: 'select2' }
],
props: {
placeholder: '请输入',
allowClear: true
}
}
]
// 查询
const onSearchTable = (params) => {
if (tableRef.current) {
const postParams = Object.assign({ pageNum: 1 }, params)
// 处理查询条件
tableRef.current.queryTable(postParams)
}
}
// 重置
const onResetTable = () => {
if (tableRef.current) {
tableRef.current.queryTable({ pageNum: 1 }, 'reset')
}
}
const tableSearchFormProps = {
searchFields,
onSearchTable,
onResetTable
}
// 编辑
const handleEdit = async (event, record) => {
event.stopPropagation()
dropByCacheKey('/demo/tabcrud/edit')
props.dispatch({
type: 'global/goTab',
payload: {
path: `/demo/tabcrud/edit`,
name: '编辑Crud',
query: {
id: record.id
}
}
})
}
// 删除
const handleDelete = async (event, record) => {
event.stopPropagation()
const res = await removeCrud({ idArr: [record.id] })
if (res.isSuccess) {
SageMessage.success('删除成功')
tableRef.current.reloadTable()
}
}
// 表格
const columns = [
{
title: '字段1',
dataIndex: 'field1',
key: 'field1',
width: 200,
},
{
title: '字段2',
dataIndex: 'field2',
key: 'field2',
width: 200,
sortField: 't1.field2',
sorter: true
},
{
title: '字段3',
dataIndex: 'field3',
key: 'field3',
width: 200,
},
{
title: '字段4',
dataIndex: 'field4',
key: 'field4',
width: 200,
},
{
title: '字段5',
dataIndex: 'field5',
key: 'field5',
width: 200,
},
{
title: '字段6',
dataIndex: 'field6',
key: 'field6',
width: 200,
},
{
title: '字段7',
dataIndex: 'field7',
key: 'field7',
width: 200,
},
{
title: '字段8',
dataIndex: 'field8',
key: 'field8',
width: 200,
},
{
title: '字段9',
dataIndex: 'field9',
key: 'field9',
width: 200,
},
{
title: '字段10',
dataIndex: 'field10',
key: 'field10',
width: 200,
},
{
title: '字段11',
dataIndex: 'field11',
key: 'field11',
width: 200,
},
{
title: '字段12',
dataIndex: 'field12',
key: 'field12',
width: 200,
},
{
title: '字段13',
dataIndex: 'field13',
key: 'field13',
width: 200,
},
{
title: '字段14',
dataIndex: 'field14',
key: 'field14',
width: 200,
},
{
title: '字段15',
dataIndex: 'field15',
key: 'field15',
width: 200,
},
{
title: '字段16',
dataIndex: 'field16',
key: 'field16',
width: 200,
},
{
title: '字段17',
dataIndex: 'field17',
key: 'field17',
width: 200,
},
{
title: '字段18',
dataIndex: 'field18',
key: 'field18',
width: 300,
},
{
title: '字段19',
dataIndex: 'field19',
key: 'field19',
width: 200,
},
{
title: '字段20',
dataIndex: 'field20',
key: 'field20',
width: 200,
},
{
title: '字段21',
dataIndex: 'field21',
key: 'field21',
width: 200,
},
{
title: '字段22',
dataIndex: 'field22',
key: 'field22',
width: 200,
},
{
title: '字段23',
dataIndex: 'field23',
key: 'field23',
width: 200,
},
{
title: '字段24',
dataIndex: 'field24',
key: 'field24',
width: 300,
},
{
title: '字段25',
dataIndex: 'field25',
key: 'field25',
width: 200,
},
{
title: '创建时间',
dataIndex: 'createdAt',
key: 'createdAt',
width: 200,
sortField: 't1.created_At',
sorter: true
},
{
title: '操作',
fixed: 'right',
dataIndex: 'button',
key: 'action',
align: 'center',
render: (button, record) => {
const actionList = [
{ title: '编辑', method: (e) => handleEdit(e, record) },
{ title: '删除', method: (e) => handleDelete(e, record), isConfirm: true, confirmInfo: '确认删除该角色?' },
]
return <ActionSet actionList={actionList} record={record} />
},
width: 120
}
]
const tableProps = {
rowKey: 'id',
hasNumber: true,
hasCheck: true,
columns,
scroll: { x: '100vw' },
rowSelection: {
onChange: (selectedrowkeys, selectedrows) => {
tableRef.current.setSelectedRowKeys(selectedrowkeys)
tableRef.current.setSelectedRows(selectedrows)
setEditable(selectedrowkeys.length !== 1)
setRemoveable(selectedrowkeys.length === 0)
}
}
}
// 新建按钮
const onAdd = () => {
props.dispatch({
type: 'global/goTab',
payload: {
path: '/demo/tabcrud/add',
name: '新增Crud'
}
})
}
// 编辑按钮
const onEdit = (e) => {
const rowRecords = tableRef.current.getSelectedRows()
handleEdit(e, rowRecords[0])
}
// 删除按钮
const onDelete = async (e) => {
e.stopPropagation()
const rowRecords = tableRef.current.getSelectedRowKeys()
const res = await removeCrud({ idArr: rowRecords })
if (res.isSuccess) {
SageMessage.success('删除成功')
tableRef.current.reloadTable()
}
}
// 导入按钮
const onImport = (e) => {
alert('待实现')
}
// 导出按钮
const onExport = (e) => {
alert('待实现')
}
// 表格按钮操作
const tableToolProps = {
toolBarRender: () => {
return (
<>
<SageButton type="primary" icon={<PlusOutlined />} onClick={onAdd}>新增</SageButton>
<SageButton type="success" icon={<EditOutlined />} onClick={(e) => onEdit(e)} disabled={editable} style={{marginLeft: '8px'}}>编辑</SageButton>
<SageButton type="danger" icon={<DeleteOutlined />} onClick={(e) => onDelete(e)} disabled={removeable} style={{marginLeft: '8px'}}>删除</SageButton>
<SageButton type="warning" icon={<VerticalAlignBottomOutlined />} onClick={(e) => onImport(e)} style={{marginLeft: '8px'}}>导入</SageButton>
<SageButton type="warning" icon={<VerticalAlignTopOutlined />} onClick={(e) => onExport(e)} style={{marginLeft: '8px'}}>导出</SageButton>
</>
)
},
toolOptionConfig: ['reload', 'hiddensearch', 'density', 'fullScreen']
}
return (
<PageHeaderWrapper>
<SageTable
ref={tableRef}
{...tableSearchFormProps}
{...tableToolProps}
{...tableProps}
request={(params) => queryCrud(params)}
/>
</PageHeaderWrapper>
)
}
export default connect(({ global }) => ({
global
}))(CrudList)
import request from '@/utils/request';
import { requestPrefix } from '@/services/prefix'
export async function queryCrud(params) {
return request(`/${requestPrefix}/party/test/queryList`, {
method: 'POST',
data: { ...params },
});
}
export async function removeCrud(params) {
return request(`/${requestPrefix}/party/test/deleteBatch`, {
method: 'POST',
data: { ...params },
});
}
export async function addCrud(params) {
return request(`/${requestPrefix}/party/test/saveOrEdit`, {
method: 'POST',
data: { ...params },
});
}
export async function updateCrud(params) {
return request(`/${requestPrefix}/party/test/saveOrEdit`, {
method: 'POST',
data: { ...params },
});
}
// 查询
export function getCrudDetail(params) {
return request(`/${requestPrefix}/party/test/selectById`, {
method: 'POST',
data: { ...params },
})
}
import React, { useState, useEffect, useRef } from 'react'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { connect } from 'umi'
import { SageTable, SageModal, SageButton, SageMessage, ActionSet } from '@/components/Common'
import { createFromIconfontCN, PlusOutlined, EditOutlined, ReloadOutlined, SwapOutlined, DeleteOutlined, VerticalAlignBottomOutlined, VerticalAlignTopOutlined } from '@ant-design/icons';
import moment from 'moment';
import config from '@/config'
import { getEnumDropDownList } from '@/services/enum'
import { queryMenu, updateMenu, addMenu, removeMenu, getMenuDetail, clearMenu } from './service';
import CreateForm from './components/CreateForm'
import UpdateForm from './components/UpdateForm'
const IconFont = createFromIconfontCN({
scriptUrl: config.IconUrl,
});
// 详情数据
const initDetail = {
id: null
}
const MenuList = () => {
const MenuList = (props) => {
const { settings } = props
// 状态数据
const [detail, setDetail] = useState(initDetail) // 详情
......@@ -33,6 +30,10 @@ const MenuList = () => {
const createFormRef = useRef();
const updateFormRef = useRef();
const IconFont = createFromIconfontCN({
scriptUrl: settings.iconfontUrl,
});
useEffect(() => {
}, [])
......@@ -382,4 +383,6 @@ const MenuList = () => {
)
}
export default MenuList
export default connect(({ settings }) => ({
settings,
}))(MenuList);
......@@ -218,6 +218,7 @@ const Center = (props) => {
formFields={formFields}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
showButtonRow
showSubmitButton
tailLayout={{
wrapperCol: { offset: 3, span: 21 }
......@@ -232,6 +233,7 @@ const Center = (props) => {
formFields={formFields2}
onFinish={onFinish2}
onFinishFailed={onFinishFailed2}
showButtonRow
showSubmitButton
tailLayout={{
wrapperCol: { offset: 3, span: 21 }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论