React页面设计初体验

1、定制路由

export default [
  //login
  {
    path: '/login',
    name: 'login',
    component: '../layouts/BlankLayout',
    routes: [
      { 
        path: '/login', 
        component: './Login/Index',
      }
    ]
  },
  // app
  {
    path: '/',
    component: '../layouts/BasicLayout',
    Routes: ['src/pages/Authorized'],
    authority: 'admin',
    routes: [
      {
        path: '/',
        redirect: '/system/user',
      },
      {
        path: '/system',
        name: 'system',
        routes: [
          {
            path: '/system/user',
            name: 'user',
            component: './System/User/Index',
          },
          {
            path: '/system/menu',
            name: 'menu',
            component: './System/Menu/Index',
          },
          {
            path: '/system/permission',
            name: 'permission',
            component: './System/Permission/Index',
          },
          {
            path: '/system/role',
            name: 'role',
            component: './System/Role/Index',
          },
        ],
      },
      {
        path: '/operation',
        name: 'operation',
        routes:[
          {
            path: '/operation/log',
            name: 'log',
            component: './Operation/Log/Index'
          },
          {
            path: '/operation/article',
            name: 'article',
            routes:[
              {
                path: '/operation/article',
                component: './Operation/Article/Index'
              },{
                path: '/operation/article/:id',
                name: 'edit',
                component: './Operation/Article/Edit'
              }
            ]
          },
          {
            path: '/operation/sqlmonitor',
            name: 'sqlmonitor',
            component: './Operation/SqlMonitor/Index'
          }
        ]
      },
      {
        component: '404',
      },
    ],
  },
];

2、定制API

/**
 * 这里就类似于Vue的api,这些api将在pages的各模块models引入
 * 也是与调用后端的URI相匹配的
 */
import { async } from "q";
// 引入request请求工具,Vue中同样也对request做了封装
import request, { download } from '@/utils/request';
import qs from 'qs';

// 这样定义可重用方便维护
const API_BASE = "/antdsp-api";
const USER_API = API_BASE + "/system/user";
const MENU_API = API_BASE + "/system/menu";
const ROLE_API = API_BASE + "/system/role";
const PERMISSION_API = API_BASE + "/system/permission";

export async function fetchAllUser(params){
    return request(`${USER_API}?${qs.stringify(params, { indices: false })}`);
}

/**
 * 添加用户
 *
 * URI = URI前缀(较固定,与后端mapping相匹配) + method(POST、PUT、DELETE、GET) + data
 * 最基本的必须有 URI前缀
 *
 * @param params 参数
 * @returns {Promise<void>}
 */
export async function addUser(params){
    return request(`${USER_API}`,{
        method: 'POST',
        data:{
            ...params
        }
    });
}

export async function updateUser(params){
    const userId = params.user.id;
    return request(`${USER_API}/${userId}`,{
        method: 'PUT',
        data:{
            ...params
        }
    });
}

export async function delUserById(params){
    return request(`${USER_API}/${params.id}`,{
        method: 'DELETE',
    });
}

export async function fetchUser(params){
    return request(`${USER_API}/${params.id}`,{
        method: 'GET'
    });
}

export async function fetchAllMenu(){
    return request(`${MENU_API}`)
}

export async function addMenu(params){

    return request(`${MENU_API}`,{
        method: 'POST',
        data:{
            ...params
        }
    });
}
export async function updateMenu(params){
    return request(`${MENU_API}`,{
        method: 'PUT',
        data:{
            ...params
        }
    });
}

export async function delMenuById(param){
    return request(`${MENU_API}/${param.id}`,{
        method: 'DELETE',
    })
}

export async function fetchAllRole(param){
    return request(`${ROLE_API}?${qs.stringify(param, { indices: false })}`)
}


export async function addRole(params){
    return request(`${ROLE_API}`,{
        method: 'POST',
        data: {
            ...params
        },
    })
}
export async function updateRole(params){
    return request(`${ROLE_API}`,{
        method: 'PUT',
        data: {
            ...params
        }
    });
}

export async function delRoleById(param){
    return request(`${ROLE_API}/${param.id}`,{
        method: 'DELETE'
    })
}

export async function fetchRoleById(param){
    return request(`${ROLE_API}/${param.id}`);
}

export async function queryRoles(){
    return request(`${ROLE_API}/queryRoleNameAndIds`);
}

export async function queryRoleMenus(){
    return request(`${MENU_API}/route`);
}

export async function fetchAllLog(param){
    return request(`${API_BASE}/operation/log?${qs.stringify(param, { indices: false })}`);
}

export async function exportLog(params){
    return download(`${API_BASE}/operation/log/export?${qs.stringify(params, { indices: false })}`)
}

export async function fetchAllPermission(params){
  return request(`${PERMISSION_API}?${qs.stringify(params, { indices: false })}`);
}

3、定制API与页面中间层permission.js

​
import {
  fetchAllPermission
} from '@/services/system';// 引入API

export default {

  namespace: 'systempermission',

  // 有点类似Vue的data
  state: {
    PermissionList:{
      data:[],
      pagination:{}
    }
  },

  effects: {
    *fetchAll({payload} , {call , put}){
      const response = yield call(fetchAllPermission, payload);
      yield put({
        type:'reducersPermissionList',
        payload: response,
      })
    }
  },

  reducers: {
    reducersPermissionList(state , action){
      return {
        ...state,
        PermissionList:{
          ...action.payload
        }
      }
    }
  }
}

​

4、定制页面index.js

import { PureComponent, Fragment } from 'react';
import { connect } from 'dva';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import Block from '@/custom/Block';
import {
  Card,
  Form,
  Button,
  Table,
  Divider,
  Input,
  Select,
  Modal,
  message,
  Popconfirm,
  Checkbox
} from 'antd'; // 引入antd组件
import UnipicUpload from '@/custom/UnipicUpload';
import AntdspConfig from '@/AntdspConfig'

const FormItem = Form.Item;

const UserStatus = {
  NORMAL: '正常',
  FORBIDDEN: '异常',
};

@connect(({ systempermission, loading }) => ({
  systempermission,
  loading: loading.models.systempermission,
}))
/**
 * PureComponent的子组件一般由3大部分构成:数据、事件、render()渲染
 */
@Form.create()// 创建表单,antd语法
export default class extends PureComponent {
  state = {
    confirmLoading: false,
    visible: false,
    current: {},
    formValue: {
      page: 1,
      count: 10,
    },
  };

  componentDidMount() {
    const { dispatch } = this.props;
    dispatch({
      type: 'systempermission/fetchAll',
      payload: {
        page: 1,
        count: 10,
      },
    });
  }

  // 条件查询事件
  handlerQueryOnClick = () => {
    const { form, dispatch } = this.props; // 从this.props取出form、dispatch
    form.validateFields((err, fieldsValue) => {
      let { formValue } = this.state.formValue;
      formValue = {
        ...fieldsValue,
        page: 1,
        count: 10,
      };
      this.setState({ formValue });// 更新state的formValue
      // 调用user.js里面的*fetchAll
      dispatch({
        type: 'systempermission/fetchAll',
        payload: {
          ...formValue,
        },
      });
    });
  };

  renderQueryForm = () => {
    const { getFieldDecorator } = this.props.form;

    return (
      <Block>
        <Form layout="inline">
          <FormItem label="登录名">
            {getFieldDecorator('loginname')(<Input placeholder={'请输入登录名'} />)}
          </FormItem>
          <FormItem label="状态">
            {getFieldDecorator('status')(
              <Select style={{ width: '120px' }} placeholder="请选择状态">
                <Select.Option value={'NORMAL'}>正常</Select.Option>
                <Select.Option value={'FORBIDDEN'}>异常</Select.Option>
              </Select>
            )}
          </FormItem>
          <FormItem>
            <Button type="primary" onClick={this.handlerQueryOnClick}>
              查询
            </Button>
          </FormItem>
        </Form>
      </Block>
    );
  };

  handlerTableOnChange = (pagination, filters, sorter) => {
    const { dispatch } = this.props;
    let { formValue } = this.state;

    formValue = {
      ...formValue,
      page: pagination.current,
      count: pagination.pageSize,
    };

    this.setState({
      formValue: {
        ...formValue,
      },
    });

    dispatch({
      type: 'systempermission/fetchAll',
      payload: {
        ...formValue,
      },
    });
  };
  // 显示弹窗
  handlerModalOnOk = e => {
    e.preventDefault();
  };

  // 删除事件

  // 渲染列表。数据、columns定义、return里面写html
  render() {
    const {
      systempermission: { PermissionList, detail },  // 命名空间:{ 对象1, 对象2, ......}
      loading,
    } = this.props;// 从user.js取出数据

    const columns = [
      {
        title: 'ID',
        dataIndex: 'id',
      },
      {
        title: '描述',
        dataIndex: 'desc',
      },
      {
        title: '创建时间',
        dataIndex: 'created',
      }
    ];

    return (
      <PageHeaderWrapper title="用户管理">
        <Card>
          {this.renderQueryForm()}

          <Block>
            <Button
              icon="plus"
              type="primary"
              onClick={(e) => {
                this.showModal(e , {});
              }}
            >
              新增
            </Button>
          </Block>
          <Table
            columns={columns}
            rowKey={'id'}
            dataSource={PermissionList.data}
            pagination={PermissionList.pagination}
            onChange={this.handlerTableOnChange}
            loading={loading}
          />
          <Modal
            title="编辑用户信息"
            centered={true}
            maskClosable={true}
            visible={this.state.visible}
            onCancel={() => {
              this.setState({ visible: false });
            }}
            onOk={this.handlerModalOnOk}
            confirmLoading={this.state.confirmLoading}
            destroyOnClose={true}
          >
            <EditUser
              wrappedComponentRef={formRef => (this.formRef = formRef)}
              detail={detail}
            />
          </Modal>
        </Card>
      </PageHeaderWrapper>
    );
  }
}

@Form.create() // 弹窗组件
export class EditUser extends PureComponent {
  // 比对密码事件
  compareToPassword = (rule, value, callback) => {
    const form = this.props.form;
    if (value && value !== form.getFieldValue('password')) {
      callback('两次密码输入不一致');
    } else {
      callback();
    }
  };

  handlerUploadOnChange=(imageurl)=>{
    console.log(imageurl);
    this.setState({
      avatar: imageurl
    })
  }

  roleToNameId(roleNameId){

    let newRoleNameId=[];

    roleNameId.map((item=>{
      let nameid = {
        label: item.roleName,
        value: item.id,
      }
      newRoleNameId.push(nameid);
    }));
    return newRoleNameId;
  }

  render() {
    const { getFieldDecorator } = this.props.form;
    const { detail: { user , roleIds , roles} } = this.props;

    const flag = Object.keys(user).length == 0;

    const formItemLayout = {
      labelCol: {
        xs: { span: 4 },
        sm: { span: 4 },
      },
      wrapperCol: {
        xs: { span: 12 },
        sm: { span: 12 },
      },
    };

    return (
      <div>
        <Form layout="horizontal" {...formItemLayout}>
          <FormItem label="头像">
            {getFieldDecorator('avatar',{
              initialValue: user.avatar
            })(
              <UnipicUpload
                group={"user"}
                onChange={()=>{this.handlerUploadOnChange}}
                image={user.avatar}
              />
            )}
          </FormItem>
          <FormItem label="登录名">
            {getFieldDecorator('loginname', {
              initialValue: user.loginname,
              rules: [
                {
                  required: true,
                  message: '请输入登录名',
                },
              ],
            })(<Input placeholder="将会成为您唯一的登入名" disabled={!flag} />)}
          </FormItem>
          {flag ? (
            <div>
              <FormItem label="密 码">
                {getFieldDecorator('password', {
                  rules: [
                    {
                      required: true,
                      message: '请输入密码',
                    },
                  ],
                })(<Input.Password placeholder="请输入密码" />)}
              </FormItem>
              <FormItem label="确认密码">
                {getFieldDecorator('repassword', {
                  rules: [
                    {
                      required: true,
                      message: '请输入密码',
                    },
                    {
                      validator: this.compareToPassword,
                    },
                  ],
                })(<Input.Password placeholder="确认密码" />)}
              </FormItem>
            </div>
          ) : null}
          <FormItem label="真实姓名">
            {getFieldDecorator('realname', {
              initialValue: user.realname,
            })(<Input placeholder="真实姓名" />)}
          </FormItem>
          <FormItem label="Email">
            {getFieldDecorator('email', {
              initialValue: user.email,
            })(<Input placeholder="email" />)}
          </FormItem>
          <FormItem label="Q  Q">
            {getFieldDecorator('qq', {
              initialValue: user.qq,
            })(<Input placeholder="qq" />)}
          </FormItem>
          <FormItem label="选择角色">
            {
              getFieldDecorator('roleIds',{
                initialValue: flag ? [] : roleIds
              })(
                <Checkbox.Group options={this.roleToNameId(roles)} ></Checkbox.Group>
              )
            }
          </FormItem>
        </Form>
      </div>
    );
  }
}

5、效果图:

如果对你有帮助帮忙点个赞哈

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡布奇诺-海晨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值