UNPKG

app-base-web

Version:
642 lines (618 loc) 17.9 kB
import React from 'react'; import {Layout, Tree, Table, Form, Row, Col, Button, Input, InputNumber, message, Modal} from 'antd' import UtilModal from '../../../library/util-modal'; import UtilDic from '../../../library/util-dic'; import UtilString from '../../../library/util-string'; import Jquery from '../../../library/jquery'; import Dic from '../../../library/dic'; import api from '../../../library/util-axios'; import EditTable from '../../../library/editTable'; // 系统管理-菜单管理 const title = "菜单管理" const url = "SysMenu/" class SysMenuList extends React.Component { constructor(props) { super(props) this.state = { params: { parentId: this.props.parentId, parentName: this.props.parentName }, data: [], pagination: {}, loading: false, selected: [],//Table checked //显藏控制 showView: false, showEdit: false, //values values: {}, } this.columns = [{ title: "序号", width: 50, fixed: "left", render: (text, record, index) => { return index + 1 } }, { title: "菜单ID", dataIndex: "id", width: 50, render: (text, record) => (<a className="btn-detail" onClick={() => this.onView(record)}>{text}</a>) }, { title: "菜单名称", dataIndex: "name", width: 200, render: (text, record) => (<a className="btn-detail" onClick={() => this.onView(record)}>{text}</a>) }, { title: "上级菜单名称", dataIndex: "parentName", width: 200 }, { title: "菜单类型", dataIndex: "type", width: 100, render: (text, record) => { return UtilDic.json("app", "菜单类型")[text] } }, { title: "样式", dataIndex: "className", width: 100 }, { title: "图标", dataIndex: "imgSrc", width: 100 }, { title: "参数", dataIndex: "params", width: 150 }, { title: "接口权限", dataIndex: "permission", width: 150 }, { title: "顺序号", dataIndex: "ord", width: 60 }] } componentDidMount() { this.onLoad(this.state.params) } /*** Table ***/ async onLoad(params) { this.setState({loading: true}) let rs = await api.get(url + "getList", params) let pagination = { pageSizeOptions: ["20", "100", "200", "500", "1000"], pageSize: params.pageSize || 20, defaultPageSize: params.pageSize || 20, showSizeChanger: true, showQuickJumper: true, total: rs.total, showTotal: (total) => { return `总记录 ${total} ` } } this.setState({ loading: false, showEdit: false, params, data: rs.data, pagination, }) } onChange = (pagination, filters, sorter) => { let params = this.state.params params.pageSize = pagination.pageSize params.pageIndex = pagination.current this.onLoad(params) } onSearch = (value) => { let params = this.state.params params.name = value this.onLoad(params) } onAdd = () => { let values = {} Object.keys(this.state.values).forEach(key => values[key] = undefined) values.parentId = this.state.params.parentId values.parentName = this.state.params.parentName this.setState({ showView: false, showEdit: true, values }) } onCopy = () => { let me = this; if (me.state.selected.length == 0) { message.error('请选择记录!'); return; } api.post(url + "copy", me.state.selected).then(function (rs) { if (rs.success) { message.info(rs.msg); me.onLoad(me.state.params || {}); } else { message.error(rs.msg); } }); } onView = (values) => { this.setState({ showView: true, loading: false, values }) } onEdit = (values) => { let me = this api.get(url + "getModel?id=" + values.id, {}, function (rs) { me.setState({ showEdit: true, showView: false, values: rs.data }) }) } onSave = (values) => { this.onLoad(this.state.params) if(this.props.onSave){ this.props.onSave() } } onDel = () => { let me = this; if (me.state.selected.length == 0) { message.error('请选择记录!'); return; } UtilModal.confirm({ content: '确定删除?', onOk: function () { api.post(url + "delete?id=" + me.state.selected).then(function (rs) { if (rs.success) { message.info(rs.msg) me.onLoad(me.state.params || {}) if(me.props.onSave){ me.props.onSave() } } else { message.error(rs.msg) } }); } }) } render() { var tableCfg = { scroll: {y: this.props.height - 210}, size: "middle", rowKey: "id", columns: this.columns, rowSelection: { selectedRowKeys: this.state.selected, onChange: (selectedRowKeys, selectedRows) => { this.setState({ selected: selectedRowKeys }) } }, rowClassName: (record) => { return record.id === this.state.selectedRowId ? 'row-selected' : '' }, onRow: (record) => { return { onClick: event => { this.setState({selectedRowId: record.id}) } } }, dataSource: this.state.data, pagination: this.state.pagination, loading: this.state.loading, onChange: this.onChange } return <div className="app-admin"> <div className={this.state.showView || this.state.showEdit ? "hide" : ""}> <Row> <Col className="main-title"><i className="iconfont icon-title"></i>{title}</Col> </Row> <Row className="main-toolbar"> <Col className="text-left" xs={16}> <Button className="btn-add" onClick={this.onAdd}><i className="iconfont icon-add"></i>录入</Button> <Button className="btn-copy" onClick={this.onCopy}><i className="iconfont icon-copy"></i>拷贝</Button> <Button className="btn-del" onClick={this.onDel}><i className="iconfont icon-del"></i>删除</Button> </Col> <Col className="text-right" xs={8}> <Input.Search placeholder="请输入名称" onSearch={value => this.onSearch(value)} enterButton/> </Col> </Row> <Table {...tableCfg} /> </div> {this.state.showView ? <FormView height={this.props.height - 140} values={this.state.values} onEdit={this.onEdit} onReturn={() => { this.setState({showView: false}) }} /> : ""} {this.state.showEdit ? <FormEdit height={this.props.height - 140} values={this.state.values} onSave={this.onSave} onCancel={() => { this.setState({showEdit: false}) }} onEditReturn={() => { this.setState({showEdit: false, showView: true}) }} /> : ""} </div> } } class MenuTree extends React.Component { constructor(props) { super(props) this.state = { value: undefined, label: undefined, treeData: [], treeKey:UtilString.uuid() } this.initData() } async initData() { let rs = await api.post("SysMenu/listTreeMenu", {}) this.setState({treeData: rs.data.treeData, defaultExpandedKeys: rs.data.defaultExpandedKeys, treeKey: UtilString.uuid()}) } onSelect = (selectedKeys, e) => { this.props.onSetParent(e.node.props.id, e.node.props.title) } render() { return (<Tree autoExpandParent={true} blockNode={true} checkable={false} treeData={this.state.treeData} defaultExpandAll={true} defaultExpandParent={true} defaultExpandedKeys={this.state.defaultExpandedKeys} showLine={true} draggable={true} selectable={true} onSelect={this.onSelect} key={this.state.treeKey} />) } } export default class SysMenu extends React.Component { constructor(props) { super(props) this.state = { parentId: -1, parentName: "", menuKey: UtilString.uuid(), menuTreeKey: UtilString.uuid(), isShowMenu:false } } onSetParent = (parentId, parentName) => { this.setState({ parentId, parentName, menuKey: UtilString.uuid(), isShowMenu: true }) } componentDidMount() { let timer = setInterval(function () { let el = Jquery(".ant-tree-iconEle") if (el.length > 0) { el.remove() clearInterval(timer) } }, 100) } onSave = ()=>{ this.setState({ menuTreeKey:UtilString.uuid() }) } render() { return <Layout style={{background: "#f0f2f5", height: "100%"}}> <Layout.Sider theme="light" width="200" style={{padding: "15px 20px", marginRight: "10px"}}> <MenuTree onSetParent={this.onSetParent} key={this.state.menuTreeKey}/> </Layout.Sider> <Layout.Content style={{background: "#fff", paddingLeft: "20px"}}> {this.state.isShowMenu ? <SysMenuList key={this.state.menuKey} parentId={this.state.parentId} parentName={this.state.parentName} onSave={this.onSave}/> : "请选择主菜单" } </Layout.Content> </Layout> } } class FormView extends React.Component { constructor(props) { super(props) this.state = { ...props.values } } componentDidMount() { let me = this api.get(url + "getModel?id=" + this.state.id, {}, function (rs) { me.setState({ ...rs.data }) }) } render() { return ( <Form className="form-view"> <div className="form-title"> <i>{title} - 详情</i> <span><Button className="btn-edit" onClick={(e) => { this.props.onEdit(this.state) }}><i className="iconfont icon-edit"></i>编辑</Button></span> </div> <div className="form-content" style={{height: this.props.height}}> <Row> <Col xs={24}><label>上级菜单名称</label><span>{this.state.parentName}</span></Col> </Row> <Row> <Col xs={24}><label>菜单ID</label><span>{this.state.id}</span></Col> </Row> <Row> <Col xs={24}><label>菜单名称</label><span>{this.state.name}</span></Col> </Row> <Row> <Col xs={24}><label>菜单类型</label><span>{UtilDic.json("app", "菜单类型")[this.state.type]}</span></Col> </Row> <Row> <Col xs={24}><label>样式</label><span>{this.state.className}</span></Col> </Row> <Row> <Col xs={24}><label>图标</label><span>{this.state.imgSrc}</span></Col> </Row> <Row> <Col xs={24}><label>参数</label><span>{this.state.params}</span></Col> </Row> <Row> <Col xs={24}><label>接口权限</label><span>{this.state.permission}</span></Col> </Row> <Row> <Col xs={24}><label>顺序号</label><span>{this.state.ord}</span></Col> </Row> </div> <div className="form-toolbar"> <Button className="btn-return" onClick={this.props.onReturn}><i className="iconfont icon-return"></i>返回</Button> </div> </Form> ) } } class FormEdit extends React.Component { constructor(props) { super(props) this.state = { ...props.values } this.formRef = React.createRef() } onSave = (values) => { let me = this values.id = this.state.id values.parentId = this.state.parentId if(this.state.params){ values.params = this.state.params } api.post(url + "save", values).then(function (rs) { if (rs.success) { message.info(rs.msg) me.props.onSave(values) } else { message.error(rs.msg) } }) //todo 应该通过redux来处理多级层级想回通讯 if(this.props.onSave){ this.props.onSave() } } //控制模态框 showModal = () => { //将对象转换成数组 let dataSource = [] let params = this.state.params if(params&&params.trim()!=''){ params = JSON.parse(params) for(let key in params){ let obj = {} obj['paramKey'] = key obj['paramValue'] = params[key] dataSource.push(obj) } } this.setState({ visible: true, dataSource }) } handleOk = e => { console.log(e) let params = {} let dataSource = this.refs.params.state.dataSource if (dataSource) { //循环取值 dataSource.map((item, index) => { let paramKey = item.paramKey let paramValue = item.paramValue if (paramKey && paramKey.trim() != '') { params[paramKey] = paramValue } }) if (JSON.stringify(params) != "{}") { this.setState({ params:JSON.stringify(params) }) } } this.setState({ visible: false, }) } handleCancel = e => { console.log(e) this.setState({ visible: false, }) } render() { return ( <div> <Modal title="添加参数" visible={this.state.visible} onOk={this.handleOk} onCancel={this.handleCancel} width={700} > <EditTable ref='params' dataSource={this.state.dataSource}/> </Modal> <Form ref={this.formRef} className="form-edit" layout="vertical" onFinish={this.onSave}> <div className="form-title"> <i> {title} - {this.state.id ? "编辑" : "录入"}</i> {this.state.id ? <span><Button className="btn-return" onClick={this.props.onEditReturn}><i className="iconfont icon-return"></i>返回</Button></span> : ""} </div> <div className="form-content" style={{height: this.props.height}}> <Row> <Col xs={24}> <Form.Item name="parentName" label="父级菜单" initialValue={this.state.parentName} > <Input disabled/> </Form.Item> </Col> </Row> <Row> <Col xs={24}> <Form.Item name="name" label="菜单名称" initialValue={this.state.name} rules={[{ required: true, message: '请输入菜单名称' }]} > <Input/> </Form.Item> </Col> </Row> <Row> <Col xs={24}> <Form.Item name="type" label="菜单类型" initialValue={this.state.type} rules={[{ required: true, message: '请输入菜单类型' }]} > <Dic params={{app: "app", type: "菜单类型"}}/> </Form.Item> </Col> </Row> <Row> <Col xs={24}> <Form.Item name="className" label="样式" initialValue={this.state.className} > <Input/> </Form.Item> </Col> </Row> <Row> <Col xs={24}> <Form.Item name="imgSrc" label="图标" initialValue={this.state.imgSrc} > <Input/> </Form.Item> </Col> </Row> <Row> <Col xs={24}> <Form.Item name="params" label="参数" initialValue={this.state.params} > <div style={{display: 'flex'}}> <Input.TextArea disabled={true} value={this.state.params}/> <Button onClick={this.showModal} className="btn-add" icon={<i className="iconfont icon-add"></i>}> 添加参数 </Button> </div> </Form.Item> </Col> </Row> <Row> <Col xs={24}> <Form.Item name="permission" label="接口权限" initialValue={this.state.permission} > <Input/> </Form.Item> </Col> </Row> <Row> <Col xs={24}> <Form.Item name="ord" label="顺序号" initialValue={this.state.ord} rules={[{ required: true, message: '请输入顺序号' }]} > <InputNumber style={{width: "100%"}}/> </Form.Item> </Col> </Row> </div> <div className="form-toolbar"> <Button className="btn-cancel" onClick={this.props.onCancel}><i className="iconfont icon-cancel"></i>取消</Button> <Button className="btn-submit" htmlType="submit"><i className="iconfont icon-submit"></i>提交</Button> </div> </Form> </div> ) } }