创建
回显接口
index.tsx
import { Component } from "react";
import React from 'react';
import './index.less';
import SearchForm from './components/SearchForm';
import { BasicStateType } from '@/models/common.d';
import { ConnectProps, connect, Dispatch } from 'umi';
import { message, Popconfirm, Table, Row, Col, Button, Tooltip } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import { EyeOutlined, TeamOutlined } from '@ant-design/icons';
import EditForm from './components/EditForm'
import SeeForm from './components/SeeForm'
import AssignForm from './components/AssignForm'
import Delete from '@/assets/Organization/department/Delete.png'
import Pencil from '@/assets/Organization/department/pencil.png'
import { remove } from '@/service/roleService';
import deleteImg from '@/assets/Organization/Role/delete.png';
import editImg from '@/assets/Organization/Role/edit.png';
import eyeImg from '@/assets/Organization/Role/eye.png';
import peopleImg from '@/assets/Organization/Role/people.png';
const DEFAULT_PAGE: number = 1;
const DEFAULT_PAGE_SIZE: number = 10;
interface DataType {
id?: number;
key: React.ReactNode;
name: string;
age: number;
address: string;
State?: boolean;
children?: DataType[];
currentItem?: Role | null;
}
interface IndexPageState {
page: number;
pageSize: number;
queryPayload?: any;
currentUser?: User;
currentItem?: Role | null;
// 弹窗
detailTeam: boolean,
seedetailTeam: boolean,
assigndetailTeam: boolean,
visible: boolean;
isEdit: boolean;
}
interface IndexPageProps extends ConnectProps {
Items: Role[];
ItemsPerPage: number;
TotalItems: number;
TotalPages: number;
CurrentPage: number;
loading: boolean;
dispatch: Dispatch;
checkStrictly: boolean,
}
class IndexPage extends React.Component<IndexPageProps, IndexPageState>{
constructor(props: IndexPageProps) {
super(props);
this.state = {
checkStrictly: false,
detailTeam: false,
seedetailTeam: false,
assigndetailTeam: false,
page: DEFAULT_PAGE,
pageSize: DEFAULT_PAGE_SIZE,
currentItem: null,
visible: false,
isEdit: true,
};
}
componentDidMount = () => {
this.onSearch()
};
onSearch = () => {
const { page, pageSize, queryPayload } = this.state;
this.props.dispatch({
type: 'roleManagement/fetch',
payload: {
currenetPageIndex: page, pageSize: pageSize, ...queryPayload,
}
})
};
seedetailonEdit = (item?: Role) => {
this.setState({
seedetailTeam: true,
currentItem: item || null,
})
}
detailonEdit = (item?: Role) => {
console.log(item);
this.setState({
detailTeam: true,
currentItem: item || null,
})
}
assigndetailonEdit = (record: Role,isEdit: boolean) => {
this.setState({
assigndetailTeam: true,
isEdit: isEdit,
currentItem: record,
})
}
onDelete = async (id: number) => {
const res = await remove(id)
if (res?.Success) {
message.success('Success')
this.onSearch();
}
}
handlePageChange = (page: number, pageSize: number): void => {
this.setState({ page, pageSize }, () => {
this.onSearch();
});
};
handleSearch = (payload: any): void => {
this.setState({ queryPayload: payload }, () => {
this.onSearch();
});
};
columns: ColumnsType<Role> = [
{
title: 'Role name',
dataIndex: 'Name',
key: 'Rolename',
fixed: 'left',
},
{
title: 'Role code',
dataIndex: 'Code',
key: 'Rolecode',
},
{
title: 'State',
dataIndex: 'State',
key: 'State',
render: (value: Boolean) => value === true ? 'Enable' : 'Disable',
// render: (any, record: Role) => { return ( this.handleStatus(State))}
},
{
title: 'Role description',
dataIndex: 'Description',
key: 'Roledescription',
},
{
title: 'Creation time',
dataIndex: 'InputDate',
key: 'Creationtime',
},
{
title: 'Action',
dataIndex: 'action',
key: 'action',
render: (any, record: Role) => {
return <>
<p>
<Tooltip title={'Assign permissions'}>
<span style={{ color: 'rgba(0, 0, 0, 0.6)' }}
onClick={() => { this.assigndetailonEdit(record, false) }}
><img src={peopleImg} style={{ width: 20, height: 20 }} alt="" /></span>
</Tooltip>
<Tooltip title={'See permissions'}>
<span style={{ color: 'rgba(0, 0, 0, 0.6)' }}
onClick={() => { this.seedetailonEdit(record) }}
><img src={eyeImg} style={{ width: 20, height: 20 }} alt="" /></span>
</Tooltip>
<Tooltip title={'Edit'}>
<span style={{ color: 'rgba(0, 0, 0, 0.6)' }}
onClick={() => {
this.detailonEdit(record);
}}
><img src={editImg} style={{ width: 20, height: 20 }} alt="" />
</span>
</Tooltip>
<Tooltip title={'Delete'}>
<span style={{ color: 'red' }} >
<Popconfirm
title='Are you sure delete this item ?'
onConfirm={() => {
this.onDelete(record.Id)
}}
okText='Delete'
cancelText='Cancle'
className='deleterole'
>
<img src={deleteImg} style={{ width: 20, height: 20 }} alt="" />
</Popconfirm>
</span>
</Tooltip>
</p>
</>;
}
}
];
data: DataType[] = [
{
key: 1,
Name: 'John Brown sr.',
Code: '000000',
Description: 'Admin',
Creationtime: '2022-12-12 10:25',
State: 'Disable',
},
{
key: 2,
Name: 'OM',
Code: '0000000',
Description: 'OM',
Creationtime: '2022-12-12 10:25',
State: 'Disable',
},
{
key: 3,
Name: 'TM',
Code: '111111',
Description: 'TM',
Creationtime: '2022-12-12 10:25',
State: 'Disable',
},
];
filterMenu = (menus: Role[]) => {
return menus?.filter((menu: any) => {
return menu.ParentId === 0;
});
};
render() {
const { isEdit,detailTeam, seedetailTeam, assigndetailTeam, currentItem } = this.state;
const { checkStrictly, Items, loading, TotalItems, CurrentPage, ItemsPerPage, } = this.props;
return (
<div className='Role'>
<div className="Role-search">
<Row>
<Col span={22}>
<SearchForm
onSearch={(values) => {
this.setState(
{
page: DEFAULT_PAGE,
queryPayload: {
filter: {
...values,
},
},
},
() => {
this.onSearch();
}
);
}}
/>
</Col>
<Col span={2} className='SearchFormbuttom' style={{ textShadow: 'none !important', boxShadow: 'none !important', justifyContent: 'end', paddingRight: '24px', display: 'flex', alignItems: 'center' }}>
<Button onClick={() => { this.detailonEdit() }} type="primary" htmlType="submit" style={{ textShadow: 'none !important', boxShadow: 'none !important', justifyContent: 'end', paddingRight: '24px', borderRadius: '4px', height: '32px', backgroundColor: 'rgba(69, 87, 255, 1)', borderColor: 'rgba(69, 87, 255, 1)', color: '#fff' }}>Add role</Button>
</Col>
</Row>
</div>
<div className="Role-list">
<Table<Role>
rowKey={(record) => record.Id}
columns={this.columns}
dataSource={Items}
loading={loading}
pagination={
{
total: TotalItems,
current: CurrentPage,
// pageSize: ItemsPerPage,
pageSize: DEFAULT_PAGE_SIZE,
}
}
onChange={(pagination) => {
const { current, pageSize } = pagination;
this.handlePageChange(
current ?? DEFAULT_PAGE,
pageSize ?? DEFAULT_PAGE_SIZE
);
}}
/>
</div>
{
seedetailTeam &&
<SeeForm
visible={seedetailTeam}
onSubmit={() => {
this.setState({ seedetailTeam: false },
() => {
this.onSearch()
});
}}
onCancel={() => {
this.setState({ seedetailTeam: false });
}}
dataItem={currentItem}
/>
}
{
assigndetailTeam &&
<AssignForm
visible={assigndetailTeam}
isEdit={isEdit}
onSubmit={() => {
this.setState({ assigndetailTeam: false },
() => {
this.onSearch()
});
}}
onCancel={() => {
this.setState({ assigndetailTeam: false , currentItem: null}, () => {
this.onSearch()
});
}}
dataItem={currentItem}
currentItem={currentItem}
/>
}
</div>
)
}
}
export default connect(
(
{ roleManagement }:
{ roleManagement: BasicStateType<Role> }) => ({
...roleManagement,
})
)(IndexPage);
调接口
1.设置baseUrl.ts
2.定义接口变量名
3.设置接口路径(动态的)
model.tsx
import { Effect, Reducer, StateType, Subscription } from 'umi';
import { trim } from 'lodash';
import { query } from '@/service/roleService';
import { BasicEffect } from '@/models/common';
interface MenuEffect extends BasicEffect {
}
export interface ModelType {
namespace: string;
state: any;
effects: MenuEffect;
subscriptions: { setup: Subscription };
reducers: {
save: Reducer<StateType>;
};
}
const Model: ModelType = {
namespace: 'roleManagement',
state: {
items: [],
meta: { page: 1, pageSize: 10, total: 0 },
},
effects: {
*fetch({ payload }, { call, put }) {
const response = yield call(query, payload);
const { ResData } = response;
yield put({
type: 'save',
payload: ResData,
});
},
},
subscriptions: {
setup({ dispatch, history }) {
return history.listen(({ pathname }) => {
});
},
},
reducers: {
save(state, { payload }) {
return { ...state, ...payload };
},
},
};
export default Model;
AssginFrom.tsx
import React, { useEffect, useState } from 'react';
import { useIntl } from 'umi';
import { Modal, Input, Checkbox, message, Button } from 'antd';
import './AssignForm.less';
import { SearchOutlined } from '@ant-design/icons';
import type { CheckboxChangeEvent } from 'antd/es/checkbox';
import type { CheckboxValueType } from 'antd/es/checkbox/Group';
import closeImg from '@/assets/system/close.png';
import TreePermissions from './Tree';
import { getAllDepartmentUsers } from '@/service/departmentService';
import { create, update, get } from '@/service/agentService';
import { Role } from '@typings/model';
import { getCurrentUser } from '@/utils/authority';
import { AssignRolePermissions } from '@/service/permission';
import { query as Menuquery } from '@/service/menuService';
interface AddAgentsProps {
visible: boolean;
onSubmit: () => void;
onCancel: () => void;
isEdit?: boolean;
dataItem?: any;
currentItem?: any;
}
let members: Member[] = [];
const page: number = 1;
const pageSize: number = 99;
const AddAgents: React.FC<AddAgentsProps> = (props) => {
const { currentItem, visible, isEdit, onSubmit, onCancel } = props;
const [indeterminate, setIndeterminate] = useState(true);
const [checkedList, setCheckedList] = useState<CheckboxValueType[]>([]);
const [checkAll, setCheckAll] = useState(false);
const [plainOptions, setPlainOptions] = useState<any[]>([]);
const [searchVal, setSearchVal] = useState('');
const [assignMenus, setAssignMenus] = useState<React.Key[]>([]);
const [assignPermissions, setAssignPermissions] = useState<React.Key[]>([]);
const currentUser = getCurrentUser()
useEffect(() => {
// props.visible && MenuFunc()
!currentItem && MenuFunc()
}, []);
const MenuFunc = async () => {
const query = {
currenetPageIndex: page,
pageSize: pageSize,
}
const res = await Menuquery(query)
connectUser(res?.ResData)
setPlainOptions(members)
}
const mapToModel = (values: any): any => {
return {
// MemberId: currentItem?.RoleId,
// UserIds: checkedList,
Permissions: assignPermissions,
Menus: assignMenus,
RoleId: currentItem?.Id,
}
}
const onInsert = (value: any) => {
if (!checkedList.length && !currentItem) return
if (!assignPermissions.length && !assignMenus.length && !isEdit) return
const server = currentItem?.Id ? AssignRolePermissions : AssignRolePermissions;
server(mapToModel(value)).then((res) => {
const { Success } = res;
if (Success) {
onSubmit();
members = [];
message.success('success');
} else {
message.error('Fail');
}
})
}
const connectUser = (data: any) => {
data?.map((item: any) => {
if (item?.SubMenu) {
connectUser(item?.SubMenu)
} else {
item?.UserInfos?.map((User, idx) => members?.push(User))
}
})
}
const onCheckAllChange = (e: CheckboxChangeEvent) => {
setCheckedList(e.target.checked ? filterUser(plainOptions).map((item => item.Id)) : []);
setIndeterminate(false);
setCheckAll(e.target.checked);
}
const onChange = (list: CheckboxValueType[]) => {
setCheckedList(list);
setIndeterminate(!!list.length && list.length < plainOptions.length);
setCheckAll(list.length === plainOptions.length);
}
const filterUser = (users: Member[]) => {
return users?.filter(option => {
if (!isNaN(Number(searchVal))) {
return '10003'?.includes(searchVal)
} else {
return option?.Name?.toLocaleUpperCase()?.includes(searchVal)
}
})
}
// EnglishName
const toUpper = (ename: string) => {
return ename.substring(0, 2).toLocaleUpperCase()
}
const modalProps = !isEdit && { footer: isEdit, width: '35%', title: "Assign permissions" }
const rightStyles = (!isEdit || currentItem) && { style: { width: '100%', marginBottom: 16 } }
const modalPropsEdit = (isEdit && currentItem) && { width: '35%', title: "Assign permissions" }
return (
<Modal
title="Assign permissions"
width={'30%'}
onOk={onInsert}
onCancel={() => {
members = []
onCancel()
}}
visible={visible}
okText="Save"
className="add_agents_modal"
{...modalPropsEdit}
>
<section className="add_agents_sec" {...rightStyles}>
<section className="agents_right_sec" {...rightStyles}>
{
!modalProps && !currentItem ? <header className="agents_head">Assign permissions</header> : null
}
<div className="permissions_content">
{
(isEdit || currentItem) &&
<TreePermissions
currentItem={currentItem}
isEdit={isEdit}
onSuccess={(menus, permissions) => {
setAssignMenus(menus)
setAssignPermissions(permissions)
}}
/>
}
</div>
</section>
</section>
</Modal >
);
};
export default AddAgents;
Tree.tsx
import { Input, Tree } from 'antd';
import type { DataNode } from 'antd/es/tree';
import React, { useEffect, useState } from 'react';
import { query as queryPermissions } from '@/service/menuService';
import { SearchOutlined } from '@ant-design/icons';
import { getCurrentUser } from '@/utils/authority';
import { GetPermissionsAsync } from '@/service/permission';
import { Role } from '@typings/model';
import { map } from 'lodash';
const page: number = 1;
const pageSize: number = 99;
let keys = [];
interface TreePermissionsProps {
onSuccess: (Menus: any[], Permissions: any[]) => void;
currentItem?: Role | null;
isEdit?: boolean;
}
const TreePermissions: React.FC<TreePermissionsProps> = (props: TreePermissionsProps) => {
const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
const [checkedKeys, setCheckedKeys] = useState<React.Key[]>([]);
const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
const [autoExpandParent, setAutoExpandParent] = useState<boolean>(true);
const [searchValue, setSearchValue] = useState('');
const [treeData, setTreeData] = useState([]);
const [defaultCheckedKeys, setDefaultCheckedKeys] = useState<React.Key[]>([]);
const currentUser = getCurrentUser()
useEffect(() => {
props?.currentItem ? keys = [] : null;
queryPermissionsFunc();
}, [])
// 获取展示数据
const Filter = {
Id: props?.currentItem?.Id
}
const queryPermissionsFunc = async () => {
const query = {
currenetPageIndex: page,
pageSize: pageSize,
// Filter: !props?.isEdit ? Filter : null
}
const res = await queryPermissions(query)
const { Success } = res
if (!Success) return
const resTreeData = treeDataFunc(res?.ResData?.Items)
if (props?.isEdit || props?.currentItem) {
// const resSelectData = await queryPermissions({ ...query, Filter: { Id: props?.currentItem?.Id } })
// reserveDataFunc(resSelectData?.ResData?.Items)
const resSelectData = await GetPermissionsAsync(props?.currentItem?.Id)
reserveDataFunc(resSelectData?.ResData)
}
setTreeData(resTreeData)
}
const treeDataFunc = (treeData: any) => {
return treeData?.map((item: any) => {
return {
key: item?.hasOwnProperty('Path') ? `${item.Id},Menus` : `${item.Id},Permissions`,
title: item.Name,
children: (item.SubMenu || item?.Permissions) ? treeDataFunc(item.SubMenu || item?.Permissions) : []
}
})
}
const reserveDataFunc = (treeData: any) => {
// ['1,Menus' , '2,Permissions']
// item?.hasOwnProperty('Path') ? `${item.Id},Menus` : `${item.Id},Permissions`
treeData?.forEach((item: any) => {
if (!item?.SubMenu && !item?.Permissions?.length) {
keys.push(`${item.Id},Menus`)
} else if (item?.SubMenu && !item?.Permissions?.length) {
reserveDataFunc(item?.SubMenu)
} else if (!item?.SubMenu && item?.Permissions?.length) {
item?.Permissions?.forEach((pms) => {
keys.push(`${pms.Id},Permissions`)
})
}
})
setCheckedKeys(keys)
}
const getIds = (checkedKeys: any[], str: string) => {
const MenusId = checkedKeys?.filter(key => key?.includes(str))
return MenusId?.map(menu => Number(menu.split(',')[0]))
}
const onExpand = (expandedKeysValue: React.Key[]) => {
setExpandedKeys(expandedKeysValue);
setAutoExpandParent(false);
}
const onCheck = (checkedKeysValue: React.Key[]) => {
let expandKey = checkedKeysValue.length === 1 ? checkedKeysValue : expandedKeys
const exKeys = getIds(expandKey, 'Menus');
console.log('expandedKeys', expandedKeys)
console.log('expandKey', expandKey)
const Menus = getIds(checkedKeysValue, 'Menus');
console.log('checkedKeysValue', checkedKeysValue);
const Permissions = getIds(checkedKeysValue, 'Permissions');
console.log('Permissions', Permissions)
props?.onSuccess(Menus.concat(exKeys), Permissions)
setCheckedKeys(checkedKeysValue);
}
const onSelect = (selectedKeysValue: React.Key[], info: any) => {
setSelectedKeys(selectedKeysValue);
}
const dataList: { key: React.Key; title: string }[] = [];
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { value } = e.target;
const newExpandedKeys = dataList
.map(item => {
if (item.title.indexOf(value) > -1) {
return getParentKey(item.key, treeData);
}
return null;
})
.filter((item, i, self) => item && self.indexOf(item) === i);
setExpandedKeys(newExpandedKeys as React.Key[]);
setSearchValue(value);
setAutoExpandParent(true);
}
const getParentKey = (key: React.Key, tree: DataNode[]): React.Key => {
let parentKey: React.Key;
for (let i = 0; i < tree.length; i++) {
const node = tree[i];
if (node.children) {
if (node.children.some(item => item.key === key)) {
parentKey = node.key;
} else if (getParentKey(key, node.children)) {
parentKey = getParentKey(key, node.children);
}
}
}
return parentKey!;
}
const generateList = (data: DataNode[]) => {
for (let i = 0; i < data.length; i++) {
const node = data[i];
const { key, title } = node;
dataList.push({ key, title: title as string });
if (node.children) {
generateList(node.children);
}
}
}
// generateList(treeData);
return (
<>
{/* <Input
prefix={<SearchOutlined style={{ color: '#999' }} />}
style={{ borderRadius: 4, marginBottom: 16, width: '105%' }}
placeholder="Search" onChange={onChange} /> */}
<Tree
checkable
onExpand={onExpand}
expandedKeys={expandedKeys}
autoExpandParent={autoExpandParent}
onCheck={onCheck}
// checkStrictly={true}
checkedKeys={checkedKeys}
onSelect={onSelect}
selectedKeys={selectedKeys}
treeData={treeData}
/>
</>
);
};
export default TreePermissions;