laravel-react實戰打造企業級高併發分佈式電商小程序(三)–權限管理的前端
react
我們前端使用react
來做,我們這個後臺基於antd pro
。使用npm
創建它。
npm create umi
選擇 ant-design-pro
Select the boilerplate type (Use arrow keys)
❯ ant-design-pro - Create project with an layout-only ant-design-pro boilerplate, use together with umi block.
app - Create project with a simple boilerplate, support typescript.
block - Create a umi block.
library - Create a library with umi.
plugin - Create a umi plugin.
Ant Design Pro 腳手架將會自動安裝。
本地開發
啓動完成後會自動打開瀏覽器訪問 http://localhost:8000,你看到下面的頁面就代表成功了。
用戶管理
添加用戶管理的增刪改查,因爲後臺都需要一個表格展示數據,所以把表格抽出來一個組件。
在 src/components/
下面添加Table
文件夾,在src/components/Table/
下面創建CommonTable.jsx
.
src/components/Table/CommonTable.jsx
文件內容如下:
import { Table } from 'antd';
import { PureComponent } from 'react';
class CommonTable extends PureComponent{
constructor(props) {
super(props);
}
render() {
const {
datas: { data, page },
loading,
columns,
size,
} = this.props;
const paginationProps = {
showSizeChanger: true,
showQuickJumper: true,
...page
}
const scroll = {
x:true,
y:500,
scrollToFirstRowOnChange:true
}
console.log(data)
return <Table
dataSource={data}
columns={columns}
pagination={paginationProps}
bordered
loading={loading}
scroll={scroll}
rowKey="id"
size={size}
/>;
}
}
export default CommonTable;
接下來在src/pages/
下面新建auth
文件夾和src/pages/auth/users.js
。
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import CommonTable from '@/components/Table/CommonTable'
import { connect } from 'dva';
import { Popconfirm, Button, message, Card, Row, Col, Form, Modal, Input, Select } from 'antd'
const ButtonGroup = Button.Group;
const { Option } = Select;
const CreateForm = Form.create()(props => {
const { modalVisible, form, handleAdd, handleModalVisible, handleChange, roleList: { data } } = props
const okHandle = () => {
form.validateFields((err, fieldsValue) => {
if (err) return
form.resetFields()
handleAdd(fieldsValue)
})
}
return (
<Modal
destroyOnClose
title="創建用戶"
visible={modalVisible}
onOk={okHandle}
onCancel={() => handleModalVisible()}
>
<Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="用戶名稱">
{form.getFieldDecorator('name', {
rules: [{ required: true, message: '請輸入用戶名稱' }],
})(<Input placeholder="請輸入用戶名稱" />)}
</Form.Item>
<Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="用戶郵箱">
{form.getFieldDecorator('email', {
rules: [{ required: true, message: '請輸入用戶郵箱' }],
})(<Input placeholder="請輸入用戶郵箱" />)}
</Form.Item>
<Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="用戶密碼">
{form.getFieldDecorator('password', {
rules: [{ required: true, message: '請輸入用戶密碼' }],
})(<Input placeholder="請輸入用戶密碼" />)}
</Form.Item>
<Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="角色">
{form.getFieldDecorator('roleIds', {
rules: [{ required: true, message: '請選擇角色' }],
})(<Select
mode="multiple"
style={{ width: '100%' }}
placeholder="請選擇角色"
// defaultValue={['a10', 'c12']}
onChange={handleChange}
>
{data.map(t => <Option key={t.id} value={t.id} >{t.name}</Option>)}
</Select>)}
</Form.Item>
</Modal>
)
})
const EditForm = Form.create()(props => {
const { editModalVisible, form, handleSave, handleModalVisible, values: { name, email, roleIds }, handleChange, roleList: { data } } = props
const okHandle = () => {
form.validateFields((err, fieldsValue) => {
if (err) return
form.resetFields()
handleSave(fieldsValue)
})
}
console.log('默認值', name, email, roleIds)
return (
<Modal
destroyOnClose
title="修改用戶"
visible={editModalVisible}
onOk={okHandle}
onCancel={() => handleModalVisible()}
>
<Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="用戶名稱">
{form.getFieldDecorator('name', {
rules: [{ required: true, message: '請輸入用戶名稱' }],
initialValue: name,
})(<Input placeholder="請輸入用戶名稱" />)}
</Form.Item>
<Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="用戶郵箱">
{form.getFieldDecorator('email', {
rules: [{ required: true, message: '請輸入用戶郵箱' }],
initialValue: email,
})(<Input placeholder="請輸入用戶郵箱" />)}
</Form.Item>
<Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="角色">
{form.getFieldDecorator('roleIds', {
rules: [{ required: true, message: '請選擇角色' }],
initialValue: roleIds,
})(<Select
mode="multiple"
style={{ width: '100%' }}
placeholder="請選擇角色"
// defaultValue={['a10', 'c12']}
onChange={handleChange}
>
{data.map(t => <Option key={t.id} value={t.id} >{t.name}</Option>)}
</Select>)}
</Form.Item>
</Modal>
)
})
@connect(({ userList, loading, roleModel }) => ({
userList,
loading: loading.models.userList,
roleModel,
roleLoading: loading.models.roleModel,
}))
export default class Users extends React.PureComponent {
constructor(props) {
super(props)
this.state = {
pageIndex: 1,
pageSize: 10,
modalVisible: false,
editModalVisible: false,
values: {},
}
}
componentDidMount() {
this.handleSearch(this.state.pageIndex, this.state.pageSize)
}
// 獲取列
getColumns = () => [
{
title: '用戶名',
dataIndex: 'name',
key: 'name',
align: 'center',
width: 200,
},
{
title: '郵箱',
dataIndex: 'email',
key: 'email',
align: 'center',
width: 300,
},
{
title: '創建時間',
dataIndex: 'created_at',
key: 'created_at',
align: 'center',
width: 600,
},
{
title: '操作',
render: (text, record) => (
<ButtonGroup>
<Button type="primary" onClick={() => this.edit(record)}>修改</Button>
<Popconfirm title="確定要刪除嘛?" onConfirm={() => this.handleDelete(record.id)}>
<Button type="danger">刪除</Button>
</Popconfirm>
</ButtonGroup>
),
align: 'center',
},
]
// 搜索操作
handleSearch = (pageIndex, pageSize) => {
const { dispatch } = this.props
dispatch({
type: 'userList/getUserList',
params: {
pageIndex,
pageSize,
},
})
}
// 獲取角色列表
getRoles = () => {
const { dispatch } = this.props
dispatch({
type: 'roleModel/getRoleList',
params: {
pageIndex: 1,
pageSize: 10000,
},
})
}
edit = values => {
console.log('value:', values)
this.setState({
values,
})
this.editVisible(true)
}
// 顯示創建彈窗
createVisible = flag => {
// 獲取角色列表
this.getRoles()
this.setState({
modalVisible: !!flag,
})
}
// 顯示修改彈窗
editVisible = flag => {
this.setState({
editModalVisible: !!flag,
})
}
// 刪除操作
handleDelete = id => {
const { dispatch } = this.props
dispatch({
type: 'userList/delete',
params: id,
callback: () => {
message.success('刪除用戶成功!')
this.handleSearch(this.state.pageIndex, this.state.pageSize)
},
});
}
// 創建操作
handleAdd = fields => {
const { dispatch } = this.props
const newFieldsValue = {
name: fields.name,
email: fields.email,
password: fields.password,
roleIds: fields.roleIds,
}
// 跳到第一頁
this.setState({
pageIndex: 1,
})
dispatch({
type: 'userList/create',
params: newFieldsValue,
callback: () => {
message.success('新建用戶成功!')
this.handleSearch(this.state.pageIndex, this.state.pageSize)
},
})
this.createVisible()
}
handleSave= fields => {
const { dispatch } = this.props
console.log('表單', this.state.values)
const newFieldsValue = {
name: fields.name,
email: fields.email,
roleIds: fields.roleIds,
}
// 跳到第一頁
this.setState({
pageIndex: 1,
})
dispatch({
type: 'userList/save',
id: this.state.values.id,
params: newFieldsValue,
callback: () => {
message.success('修改用戶成功!')
this.handleSearch(this.state.pageIndex, this.state.pageSize)
},
})
this.editVisible()
}
handleChange = value => {
console.log(`selected ${value}`);
}
render() {
const { userList: { userList }, loading, roleModel: { roleList } } = this.props
console.log('props:', this.props)
console.log('load', loading)
console.log('roles', roleList)
return (
<PageHeaderWrapper>
<Card bordered={false}>
<Row>
<Col style={{ paddingBottom: 20 }}>
<Button icon="plus" type="primary" onClick={() => this.createVisible(true)}>新建用戶</Button>
</Col>
</Row>
<CommonTable
datas={userList}
loading={loading}
columns={this.getColumns()}
size="middle"
/>
</Card>
<CreateForm
handleAdd={this.handleAdd}
handleModalVisible={this.createVisible}
modalVisible={this.state.modalVisible}
roleList={roleList}
handleChange={this.handleChange}
/>
<EditForm
handleSave={this.handleSave}
handleModalVisible={this.editVisible}
editModalVisible={this.state.editModalVisible}
values={this.state.values}
roleList={roleList}
handleChange={this.handleChange}
/>
</PageHeaderWrapper>
)
}
}
在這個頁面中還用到了model
,所以我們創建model,在src/models
下面創建auth
文件夾和src/models/auth/userList.js
文件
import {getUsers, deleteUser, createUser, saveUser} from '@/services/auth/users'
export default {
namespace: 'userList',
state: {
userList:{
data: [],
page: {},
}
},
effects: {
*getUserList({params},{call, put}) {
// console.log(params)
const res = yield call(getUsers, params);
// console.log(res)
yield put({
type: 'get_user_list',
payload: res
})
},
*delete({params, callback},{call}) {
const res = yield call(deleteUser, params);
if (res !== false) {
callback()
}
},
*create({params, callback },{call}) {
const res = yield call(createUser, params);
if (res !== false) {
callback()
}
},
*save({id ,params, callback },{call}) {
const res = yield call(saveUser, id, params);
if (res !== false) {
callback()
}
}
},
reducers: {
get_user_list(state, action) {
return {
...state,
userList:{...state.userList,...action.payload},
}
}
},
};
這裏面使用了service來給後端發送請求,model裏面主要effects
裏面封裝了一些給page
使用的方法來操作數據,state
裏面存放了page
需要使用的數據。
我們創建service
,在src/services
下面創建auth
文件夾和src/services/auth/users.js
文件。
import request from '@/utils/request';
export async function getUsers(params) {
return request('/api/auth/users', {
method: 'get',
params,
});
}
export async function deleteUser(id) {
return request(`/api/auth/user/${id}`, {
method: 'delete',
});
}
export async function createUser(params) {
return request('/api/auth/user', {
method: 'post',
data: params,
});
}
export async function saveUser(id, params) {
return request(`/api/auth/user/${id}`, {
method: 'put',
data: params,
});
}
好了,接下來就完成了,可以看到service調用了後端剛剛的幾個用戶的增刪改查接口。而model調用了service封裝的接口來改變model中的數據。page通過調用model的數據進行渲染,調用函數進行操作數據。
我們還需要對request進行一個攔截器的封裝,因爲我們使用到了token機制。
在src/utils/request.js
文件下面添加如下內容:
// request攔截器, 改變url 或 options.
request.interceptors.request.use(async (url, options) => {
// console.log(url)
let token = localStorage.getItem('token');
if (!token) {
// 請求token
const res = await fetch('http://www.laraadmin.com/api/require_token', {
method: 'post',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json; charset=utf-8' },
})
const body = await res.json()
token = body.data
localStorage.setItem('token', token)
}
const headers = {
Authorization: token,
};
return (
{
url: `http://www.laraadmin.com${url}`,
options: { ...options, headers },
}
);
})
// response攔截器, 處理response
request.interceptors.response.use(async (response, options) => {
const res = await response.json()
// eslint-disable-next-line eqeqeq
if (res.code != 0) {
// eslint-disable-next-line eqeqeq
if (res.code == '400003') {
// 令牌過期
// console.log(response, options)
localStorage.removeItem('token')
// 重新請求
request(response.url, options)
} else {
message.error(res.msg)
return false
}
}
return res.data;
});
注意,這些內容放在最後一行上面,也就是下面這句的上面。
export default request;
接下來運行
npm run start
打開瀏覽器
localhost:8000
就可以看到結果了。
角色管理
接下來角色管理,也差不多,就不再寫那麼多目錄結構了。
src/pages/auth/role.js
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import CommonTable from '@/components/Table/CommonTable'
import { connect } from 'dva';
import {Popconfirm, Button, message, Card, Row, Col, Form, Modal, Input } from 'antd'
const ButtonGroup = Button.Group;
const CreateForm = Form.create()(props => {
const { modalVisible, form, handleAdd, handleModalVisible } = props
const okHandle = () => {
form.validateFields((err, fieldsValue) => {
if (err) return
form.resetFields()
handleAdd(fieldsValue)
})
}
return (
<Modal
destroyOnClose
title="創建角色"
visible={modalVisible}
onOk={okHandle}
onCancel={() => handleModalVisible()}
>
<Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="角色名稱">
{form.getFieldDecorator('name', {
rules: [{ required: true, message: '請輸入角色名稱' }],
})(<Input placeholder="請輸入角色名稱" />)}
</Form.Item>
</Modal>
)
})
const EditForm = Form.create()(props => {
const { editModalVisible, form, handleSave, handleModalVisible, values:{name} } = props
const okHandle = () => {
form.validateFields((err, fieldsValue) => {
if (err) return
form.resetFields()
handleSave(fieldsValue)
})
}
return (
<Modal
destroyOnClose
title="修改角色"
visible={editModalVisible}
onOk={okHandle}
onCancel={() => handleModalVisible()}
>
<Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="角色名稱">
{form.getFieldDecorator('name', {
rules: [{ required: true, message: '請輸入角色名稱' }],
initialValue:name
})(<Input placeholder="請輸入角色名稱" />)}
</Form.Item>
</Modal>
)
})
@connect(({ roleModel,loading }) => ({
roleModel,
loading: loading.models.roleModel,
}))
export default class Roles extends React.PureComponent{
constructor(props) {
super(props)
this.state = {
pageIndex: 1,
pageSize: 10,
modalVisible: false,
editModalVisible: false,
values: {},
}
}
componentDidMount() {
this.handleSearch(this.state.pageIndex, this.state.pageSize)
}
//獲取列
getColumns = () => {
return [
{
title: '角色名',
dataIndex: 'name',
key:'name',
align:'center',
width: 400,
},
{
title: '創建時間',
dataIndex: 'created_at',
key:'created_at',
align:'center',
width: 600,
},
{
title: '操作',
render: (text, record) => {
return (
<ButtonGroup>
<Button type="primary" onClick={() => this.edit(record)}>修改</Button>
<Popconfirm title="確定要刪除嘛?" onConfirm={() => this.handleDelete(record.id)}>
<Button type="danger">刪除</Button>
</Popconfirm>
</ButtonGroup>
);
},
align:'center'
},
];
}
//搜索操作
handleSearch = (pageIndex, pageSize) => {
const { dispatch } = this.props
dispatch({
type: 'roleModel/getRoleList',
params: {
pageIndex,
pageSize,
},
})
}
edit = (values) => {
this.setState({
values: values
})
this.editVisible(true)
}
//顯示創建彈窗
createVisible = flag => {
this.setState({
modalVisible: !!flag,
})
}
//顯示修改彈窗
editVisible = (flag) => {
this.setState({
editModalVisible: !!flag,
})
}
//刪除操作
handleDelete = (id) => {
const { dispatch } = this.props
dispatch({
type: 'roleModel/delete',
params: id,
callback: () =>{
message.success('刪除角色成功!')
this.handleSearch(this.state.pageIndex, this.state.pageSize)
}
});
}
//創建操作
handleAdd = (fields) => {
const { dispatch } = this.props
//跳到第一頁
this.setState({
pageIndex: 1,
})
dispatch({
type: 'roleModel/create',
params: fields,
callback: () => {
message.success('新建角色成功!')
this.handleSearch(this.state.pageIndex, this.state.pageSize)
},
})
this.createVisible()
}
handleSave= (fields) => {
const { dispatch } = this.props
//跳到第一頁
this.setState({
pageIndex: 1,
})
dispatch({
type: 'roleModel/save',
id: this.state.values.id,
params: fields,
callback: () => {
message.success('修改角色成功!')
this.handleSearch(this.state.pageIndex, this.state.pageSize)
},
})
this.editVisible()
}
render(){
const { roleModel:{roleList}, loading } = this.props
return (
<PageHeaderWrapper>
<Card bordered={false}>
<Row>
<Col style={{ paddingBottom: 20 }}>
<Button icon="plus" type="primary" onClick={() => this.createVisible(true)}>新建角色</Button>
</Col>
</Row>
<CommonTable
datas={roleList}
loading={loading}
columns={this.getColumns()}
size='middle'
/>
</Card>
<CreateForm
handleAdd={this.handleAdd}
handleModalVisible={this.createVisible}
modalVisible={this.state.modalVisible}
/>
<EditForm
handleSave={this.handleSave}
handleModalVisible={this.editVisible}
editModalVisible={this.state.editModalVisible}
values={this.state.values}
/>
</PageHeaderWrapper>
)
}
}
model
src/models/auth/roleModel.js
import { getRoles, deleteRole, createRole, saveRole } from '@/services/auth/roleService'
export default {
namespace: 'roleModel',
state: {
roleList:{
data: [],
page: {},
}
},
effects: {
*getRoleList({params},{call, put}) {
// console.log(params)
const res = yield call(getRoles, params);
// console.log(res)
yield put({
type: 'get_role_list',
payload: res
})
},
*delete({params, callback},{call}) {
const res = yield call(deleteRole, params);
if (res !== false) {
callback()
}
},
*create({params, callback },{call}) {
const res = yield call(createRole, params);
if (res !== false) {
callback()
}
},
*save({id ,params, callback },{call}) {
const res = yield call(saveRole, id, params);
if (res !== false) {
callback()
}
}
},
reducers: {
get_role_list(state, action) {
return {
...state,
roleList:{...state.roleList,...action.payload},
}
}
},
};
service
src/services/auth/roleService.js
import request from '@/utils/request';
export async function getRoles(params) {
return request('/api/auth/roles', {
method: 'get',
params,
});
}
export async function deleteRole(id) {
return request(`/api/auth/role/${id}`, {
method: 'delete',
});
}
export async function createRole(params) {
return request('/api/auth/role', {
method: 'post',
data: params,
});
}
export async function saveRole(id, params) {
return request(`/api/auth/role/${id}`, {
method: 'put',
data: params,
});
}
權限管理
page
src/pages/auth/permission.js
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import CommonTable from '@/components/Table/CommonTable'
import { connect } from 'dva';
import {Popconfirm, Button, message, Card, Row, Col, Form, Modal, Input, Select, TreeSelect } from 'antd'
const ButtonGroup = Button.Group;
const CreateForm = Form.create()(props => {
const { modalVisible, form, handleAdd, handleModalVisible, treeValue, treeData, treeOnChange } = props
const okHandle = () => {
form.validateFields((err, fieldsValue) => {
if (err) return
form.resetFields()
handleAdd(fieldsValue)
})
}
return (
<Modal
destroyOnClose
title="創建菜單"
visible={modalVisible}
onOk={okHandle}
onCancel={() => handleModalVisible()}
>
<Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="菜單名稱">
{form.getFieldDecorator('name', {
rules: [{ required: true, message: '請輸入菜單名稱' }],
})(<Input placeholder="請輸入菜單名稱" />)}
</Form.Item>
<Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="菜單類型">
{form.getFieldDecorator('type', {
rules: [{ required: true, message: '請輸入菜單類型' }],
initialValue:"menu"
})(<Select style={{ width: 120 }}>
<Select.Option value="menu">菜單</Select.Option>
<Select.Option value="action">功能</Select.Option>
</Select>)}
</Form.Item>
<Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="上級菜單">
{form.getFieldDecorator('parentId', {
setFieldsValue:treeValue
})(<TreeSelect
treeDataSimpleMode
treeDefaultExpandAll="false"
style={{ width: '100%' }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
placeholder="Please select"
treeDefaultExpandAll
onChange={treeOnChange}
/>)}
</Form.Item>
</Modal>
)
})
const EditForm = Form.create()(props => {
const { editModalVisible, form, handleSave, handleModalVisible, treeValue, treeData, treeOnChange, values:{name,type,parent_id} } = props
const okHandle = () => {
form.validateFields((err, fieldsValue) => {
if (err) return
form.resetFields()
handleSave(fieldsValue)
})
}
console.log('tree',treeValue,parent_id,type)
return (
<Modal
destroyOnClose
title="修改菜單"
visible={editModalVisible}
onOk={okHandle}
onCancel={() => handleModalVisible()}
>
<Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="菜單名稱">
{form.getFieldDecorator('name', {
rules: [{ required: true, message: '請輸入菜單名稱' }],
initialValue:name,
})(<Input placeholder="請輸入菜單名稱" />)}
</Form.Item>
<Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="菜單類型">
{form.getFieldDecorator('type', {
rules: [{ required: true, message: '請輸入菜單類型' }],
initialValue:type,
})(<Select style={{ width: 120 }}>
<Select.Option value="menu">菜單</Select.Option>
<Select.Option value="action">功能</Select.Option>
</Select>)}
</Form.Item>
<Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="上級菜單">
{form.getFieldDecorator('parentId', {
setFieldsValue:treeValue,
initialValue:parent_id,
})(<TreeSelect
treeDataSimpleMode
treeDefaultExpandAll="false"
style={{ width: '100%' }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
placeholder="Please select"
treeDefaultExpandAll
onChange={treeOnChange}
/>)}
</Form.Item>
</Modal>
)
})
@connect(({ permissionModel,loading }) => ({
permissionModel,
loading: loading.models.permissionModel,
}))
export default class Permission extends React.PureComponent{
constructor(props) {
super(props)
this.state = {
pageIndex: 1,
pageSize: 10,
modalVisible: false,
editModalVisible: false,
values: {},
treeValue:undefined,
}
}
//選擇上級菜單
treeOnChange = value => {
this.setState({ treeValue:value });
};
componentDidMount() {
this.handleSearch(this.state.pageIndex, this.state.pageSize)
}
//獲取列
getColumns = () => {
return [
{
title: '菜單名',
dataIndex: 'name',
key:'name',
align:'left',
},
{
title: '菜單類型',
dataIndex: 'type.name',
key:'type.name',
align:'center',
},
{
title: '創建時間',
dataIndex: 'created_at',
key:'created_at',
align:'center',
},
{
title: '操作',
render: (text, record) => {
return (
<ButtonGroup>
<Button type="primary" onClick={() => this.edit(record)}>修改</Button>
<Popconfirm title="確定要刪除嘛?" onConfirm={() => this.handleDelete(record.id)}>
<Button type="danger">刪除</Button>
</Popconfirm>
</ButtonGroup>
);
},
align:'center'
},
];
}
//搜索操作
handleSearch = (pageIndex, pageSize) => {
const { dispatch } = this.props
dispatch({
type: 'permissionModel/getPermissionList',
params: {
pageIndex,
pageSize,
},
})
}
edit = (values) => {
console.log('菜單',values)
this.getTreeList()
this.setState({
values: {...values,type:values.type.code}
})
this.editVisible(true)
}
//顯示創建彈窗
createVisible = flag => {
this.getTreeList()
this.setState({
modalVisible: !!flag,
})
}
//顯示修改彈窗
editVisible = (flag) => {
this.setState({
editModalVisible: !!flag,
})
}
//刪除操作
handleDelete = (id) => {
const { dispatch } = this.props
dispatch({
type: 'permissionModel/delete',
params: id,
callback: () =>{
message.success('刪除菜單成功!')
this.handleSearch(this.state.pageIndex, this.state.pageSize)
}
});
}
//創建操作
handleAdd = (fields) => {
const { dispatch } = this.props
//跳到第一頁
this.setState({
pageIndex: 1,
})
dispatch({
type: 'permissionModel/create',
params: fields,
callback: () => {
message.success('新建菜單成功!')
this.handleSearch(this.state.pageIndex, this.state.pageSize)
},
})
this.createVisible()
}
handleSave= (fields) => {
const { dispatch } = this.props
//跳到第一頁
this.setState({
pageIndex: 1,
})
dispatch({
type: 'permissionModel/save',
id: this.state.values.id,
params: fields,
callback: () => {
message.success('修改菜單成功!')
this.handleSearch(this.state.pageIndex, this.state.pageSize)
},
})
this.editVisible()
}
//獲取樹形列表
getTreeList = () => {
const {dispatch} = this.props
dispatch({
type: 'permissionModel/getTree',
})
}
render(){
const { permissionModel:{permissionList,permissionTrees }, loading } = this.props
const treeData = permissionTrees
console.log('list',permissionList)
return (
<PageHeaderWrapper>
<Card bordered={false}>
<Row>
<Col style={{ paddingBottom: 20 }}>
<Button icon="plus" type="primary" onClick={() => this.createVisible(true)}>新建菜單</Button>
</Col>
</Row>
<CommonTable
datas={permissionList}
loading={loading}
columns={this.getColumns()}
size='middle'
/>
</Card>
<CreateForm
handleAdd={this.handleAdd}
handleModalVisible={this.createVisible}
modalVisible={this.state.modalVisible}
treeData={treeData}
treeValue={this.state.treeValue}
treeOnChange={this.treeOnChange}
/>
<EditForm
handleSave={this.handleSave}
handleModalVisible={this.editVisible}
editModalVisible={this.state.editModalVisible}
treeData={treeData}
treeValue={this.state.treeValue}
treeOnChange={this.treeOnChange}
values={this.state.values}
/>
</PageHeaderWrapper>
)
}
}
model
src/models/auth/permissionModel.js
import { getPermissions, deletePermission, createPermission, savePermission, getPermissionTree } from '@/services/auth/permissionService'
export default {
namespace: 'permissionModel',
state: {
permissionList:{
data: [],
page: {},
},
permissionTrees:[]
},
effects: {
*getPermissionList({params},{call, put}) {
// console.log(params)
const res = yield call(getPermissions, params);
// console.log(res)
yield put({
type: 'get_list',
payload: res
})
},
*delete({params, callback},{call}) {
const res = yield call(deletePermission, params);
if (res !== false) {
callback()
}
},
*create({params, callback },{call}) {
const res = yield call(createPermission, params);
if (res !== false) {
callback()
}
},
*save({id ,params, callback },{call}) {
const res = yield call(savePermission, id, params);
if (res !== false) {
callback()
}
},
*getTree({params},{call, put}) {
const res = yield call(getPermissionTree, params);
yield put({
type: 'get_tree_list',
payload: res
})
}
},
reducers: {
get_list(state, action) {
return {
...state,
permissionList:{...state.permissionList,...action.payload},
}
},
get_tree_list(state, action) {
return {
...state,
permissionTrees:action.payload,
}
}
},
};
service
src/services/auth/permisiionService.js
import request from '@/utils/request';
export async function getPermissions(params) {
return request('/api/auth/permissions', {
method: 'get',
params,
});
}
export async function deletePermission(id) {
return request(`/api/auth/permission/${id}`, {
method: 'delete',
});
}
export async function createPermission(params) {
return request('/api/auth/permission', {
method: 'post',
data: params,
});
}
export async function savePermission(id, params) {
return request(`/api/auth/permission/${id}`, {
method: 'put',
data: params,
});
}
export async function getPermissionTree(params) {
return request('/api/auth/permission/tree', {
method: 'get',
params,
})
}
好了,權限管理完成了,可以自己試一下。因爲本系列主要講的是後端和高併發的應用而不是前端,所以前端這裏會略過。