共享单车—— React后台管理系统开发手记:城市管理和订单管理
Posted ljq66
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了共享单车—— React后台管理系统开发手记:城市管理和订单管理相关的知识,希望对你有一定的参考价值。
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录。最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star。
一、城市管理
- pages->city->index.js:对应路由/admin/city
- 顶部子组件一:选择表单
class FilterForm extends React.Component{ render(){ const { getFieldDecorator } = this.props.form; return ( <Form layout="inline"> <FormItem label="城市"> { getFieldDecorator(‘city_id‘)( <Select style={{width:100}} placeholder="全部" > <Option value="">全部</Option> <Option value="1">北京市</Option> <Option value="2">天津市</Option> <Option value="3">深圳市</Option> </Select> ) } </FormItem> <FormItem label="用车模式"> { getFieldDecorator(‘mode‘)( <Select style={{ width: 120 }} placeholder="全部" > <Option value="">全部</Option> <Option value="1">指定停车点模式</Option> <Option value="2">禁停区模式</Option> </Select> ) } </FormItem> <FormItem label="营运模式"> { getFieldDecorator(‘op_mode‘)( <Select style={{ width: 80 }} placeholder="全部" > <Option value="">全部</Option> <Option value="1">自营</Option> <Option value="2">加盟</Option> </Select> ) } </FormItem> <FormItem label="加盟商授权状态"> { getFieldDecorator(‘auth_status‘)( <Select style={{ width: 100 }} placeholder="全部" > <Option value="">全部</Option> <Option value="1">已授权</Option> <Option value="2">未授权</Option> </Select> ) } </FormItem> <FormItem> <Button type="primary" style={{margin:‘0 20px‘}}>查询</Button> <Button>重置</Button> </FormItem> </Form> ); } } FilterForm = Form.create({})(FilterForm);
-
弹框子组件二:开通城市表单
class OpenCityForm extends React.Component{ render(){ const formItemLayout = { labelCol:{ //label标签占据列数 span:5 }, wrapperCol:{ //Form表单占据列数 span:19 } } const { getFieldDecorator } =this.props.form; return ( <Form layout="horizontal"> <FormItem label="选择城市" {...formItemLayout}> { getFieldDecorator(‘city_id‘,{ initialValue:‘1‘ })( <Select style={{ width: 100 }}> <Option value="">全部</Option> <Option value="1">北京市</Option> <Option value="2">天津市</Option> </Select> ) } </FormItem> <FormItem label="营运模式" {...formItemLayout}> { getFieldDecorator(‘op_mode‘, { initialValue: ‘1‘ })( <Select style={{ width: 100 }}> <Option value="1">自营</Option> <Option value="2">加盟</Option> </Select> ) } </FormItem> <FormItem label="用车模式" {...formItemLayout}> { getFieldDecorator(‘use_mode‘, { initialValue: ‘1‘ })( <Select style={{ width: 100 }}> <Option value="1">指定停车点</Option> <Option value="2">禁停区</Option> </Select> ) } </FormItem> </Form> ); } } OpenCityForm = Form.create({})(OpenCityForm);
-
Easy Mock城市管理的数据接口:/open_city
{ "code": 0, "msg": "", "list": { "item_list|10": [{ "id|+1": 1, "name": "@city", "mode|1-2": 1, "op_mode|1-2": 1, "franchisee_id": 77, "franchisee_name": "松果自营", "city_admins|1-2": [{ "user_name": "@cname", "user_id|+1": 10001 }], "open_time": "@datetime", "sys_user_name": "@cname", "update_time": 1546580667000 }] }, page: 1, page_size: 10, total: 20 }
- componentDidMount()中:调用this.requestList(),默认请求接口数据
componentDidMount(){ this.requestList(); } // 默认请求我们的接口数据 requestList = ()=>{ let _this = this; axios.ajax({ url: ‘/open_city‘, data:{ params:{ page:this.params.page } } }).then((res)=>{ let list = res.list.item_list.map((item, index) => { item.key = index; return item; }); this.setState({ list:list, pagination:Utils.pagination(res,(current)=>{ _this.params.page = current; _this.requestList(); }) }) }) }
-
Easy Mock城市开通的数据接口:/city/open
{ "code": 0, "list": "开通成功" }
-
【开通城市】按钮:监听onClick事件,调用this.handleOpenCity()显示弹框
state = { list:[], isShowOpenCity:false //默认隐藏弹框 } // 开通城市 handleOpenCity = ()=>{ this.setState({ isShowOpenCity:true }) }
-
Modal关键属性visible控制弹框的显示隐藏,关键事件onOk调用this.handleSubmit()提交表单信息
<Modal title="开通城市" visible={this.state.isShowOpenCity} onCancel={()=>{ this.setState({ isShowOpenCity:false }) }} onOk={this.handleSubmit} > <OpenCityForm wrappedComponentRef={(inst)=>{this.cityForm = inst;}}/> </Modal>
wrappedComponentRef属性:拿到表单中的信息对象inst,通过this.cityForm存到state中
-
城市开通信息提交
// 城市开通提交 handleSubmit = ()=>{ let cityInfo = this.cityForm.props.form.getFieldsValue(); console.log(cityInfo); axios.ajax({ url:‘/city/open‘, data:{ params:cityInfo } }).then((res)=>{ if(res.code === 0){ message.success(‘开通成功‘); this.setState({ isShowOpenCity:false }) this.requestList(); } }) }
- 实例代码
import React from ‘react‘; import { Card, Button, Table, Form, Select, Modal, message } from ‘antd‘; import axios from ‘./../../axios/index‘; import Utils from ‘./../../utils/utils‘; const FormItem = Form.Item; const Option = Select.Option; export default class City extends React.Component{ state = { list:[], isShowOpenCity:false //默认隐藏弹框 } params = { page:1 } componentDidMount(){ this.requestList(); } // 默认请求我们的接口数据 requestList = ()=>{ let _this = this; axios.ajax({ url: ‘/open_city‘, data:{ params:{ page:this.params.page } } }).then((res)=>{ let list = res.list.item_list.map((item, index) => { item.key = index; return item; }); this.setState({ list:list, pagination:Utils.pagination(res,(current)=>{ _this.params.page = current; _this.requestList(); }) }) }) } // 开通城市 handleOpenCity = ()=>{ this.setState({ isShowOpenCity:true }) } // 城市开通提交 handleSubmit = ()=>{ let cityInfo = this.cityForm.props.form.getFieldsValue(); console.log(cityInfo); axios.ajax({ url:‘/city/open‘, data:{ params:cityInfo } }).then((res)=>{ if(res.code === 0){ message.success(‘开通成功‘); this.setState({ isShowOpenCity:false }) this.requestList(); } }) } render(){ const columns = [ { title:‘城市ID‘, dataIndex:‘id‘ }, { title: ‘城市名称‘, dataIndex: ‘name‘ }, { title: ‘用车模式‘, dataIndex: ‘mode‘, render(mode){ return mode === 1 ?‘停车点‘:‘禁停区‘; } }, { title: ‘营运模式‘, dataIndex: ‘op_mode‘, render(op_mode) { return op_mode === 1 ? ‘自营‘ : ‘加盟‘; } }, { title: ‘授权加盟商‘, dataIndex: ‘franchisee_name‘ }, { title: ‘城市管理员‘, dataIndex: ‘city_admins‘, render(arr){ //处理数组类型 return arr.map((item)=>{ return item.user_name; }).join(‘,‘); } }, { title: ‘城市开通时间‘, dataIndex: ‘open_time‘ }, { title: ‘操作时间‘, dataIndex: ‘update_time‘, render: Utils.formateDate //格式化时间戳 }, { title: ‘操作人‘, dataIndex: ‘sys_user_name‘ } ] return ( <div> <Card> <FilterForm /> </Card> <Card style={{marginTop:10}}> <Button type="primary" onClick={this.handleOpenCity}>开通城市</Button> </Card> <div className="content-wrap"> <Table bordered columns={columns} dataSource={this.state.list} pagination={this.state.pagination} /> </div> <Modal title="开通城市" visible={this.state.isShowOpenCity} onCancel={()=>{ this.setState({ isShowOpenCity:false }) }} onOk={this.handleSubmit} > <OpenCityForm wrappedComponentRef={(inst)=>{this.cityForm = inst;}}/> </Modal> </div> ); } } //子组件一:选择表单 class FilterForm extends React.Component{ render(){ const { getFieldDecorator } = this.props.form; return ( <Form layout="inline"> <FormItem label="城市"> { getFieldDecorator(‘city_id‘)( <Select style={{width:100}} placeholder="全部" > <Option value="">全部</Option> <Option value="1">北京市</Option> <Option value="2">天津市</Option> <Option value="3">深圳市</Option> </Select> ) } </FormItem> <FormItem label="用车模式"> { getFieldDecorator(‘mode‘)( <Select style={{ width: 120 }} placeholder="全部" > <Option value="">全部</Option> <Option value="1">指定停车点模式</Option> <Option value="2">禁停区模式</Option> </Select> ) } </FormItem> <FormItem label="营运模式"> { getFieldDecorator(‘op_mode‘)( <Select style={{ width: 80 }} placeholder="全部" > <Option value="">全部</Option> <Option value="1">自营</Option> <Option value="2">加盟</Option> </Select> ) } </FormItem> <FormItem label="加盟商授权状态"> { getFieldDecorator(‘auth_status‘)( <Select style={{ width: 100 }} placeholder="全部" > <Option value="">全部</Option> <Option value="1">已授权</Option> <Option value="2">未授权</Option> </Select> ) } </FormItem> <FormItem> <Button type="primary" style={{margin:‘0 20px‘}}>查询</Button> <Button>重置</Button> </FormItem> </Form> ); } } FilterForm = Form.create({})(FilterForm); //子组件二:开通城市 class OpenCityForm extends React.Component{ render(){ const formItemLayout = { labelCol:{ //label标签占据列数 span:5 }, wrapperCol:{ //Form表单占据列数 span:19 } } const { getFieldDecorator } =this.props.form; return ( <Form layout="horizontal"> <FormItem label="选择城市" {...formItemLayout}> { getFieldDecorator(‘city_id‘,{ initialValue:‘1‘ })( <Select style={{ width: 100 }}> <Option value="">全部</Option> <Option value="1">北京市</Option> <Option value="2">天津市</Option> </Select> ) } </FormItem> <FormItem label="营运模式" {...formItemLayout}> { getFieldDecorator(‘op_mode‘, { initialValue: ‘1‘ })( <Select style={{ width: 100 }}> <Option value="1">自营</Option> <Option value="2">加盟</Option> </Select> ) } </FormItem> <FormItem label="用车模式" {...formItemLayout}> { getFieldDecorator(‘use_mode‘, { initialValue: ‘1‘ })( <Select style={{ width: 100 }}> <Option value="1">指定停车点</Option> <Option value="2">禁停区</Option> </Select> ) } </FormItem> </Form> ); } } OpenCityForm = Form.create({})(OpenCityForm);
二、订单管理
- 顶部子组件:选择表单
class FilterForm extends React.Component{ render(){ const { getFieldDecorator } = this.props.form; return ( <Form layout="inline"> <FormItem label="城市"> { getFieldDecorator(‘city_id‘)( <Select style={{width:100}} placeholder="全部" > <Option value="">全部</Option> <Option value="1">北京市</Option> <Option value="2">天津市</Option> <Option value="3">深圳市</Option> </Select> ) } </FormItem> <FormItem label="订单时间"> { getFieldDecorator(‘start_time‘)( <DatePicker showTime format="YYYY-MM-DD HH:mm:ss"/> ) } </FormItem> <FormItem style={{marginLeft: -10}}> { getFieldDecorator(‘end_time‘)( <DatePicker style={{marginLeft: 5}} showTime format="YYYY-MM-DD HH:mm:ss"/> ) } </FormItem> <FormItem label="订单状态"> { getFieldDecorator(‘status‘)( <Select style={{ width: 80 }} placeholder="全部" > <Option value="">全部</Option> <Option value="1">进行中</Option> <Option value="2">结束行程</Option> </Select> ) } </FormItem> <FormItem> <Button type="primary" style={{margin:‘0 5px‘}}>查询</Button> <Button>重置</Button> </FormItem> </Form> ); } } FilterForm = Form.create({})(FilterForm);
- Easy Mock订单数据接口:/order/list
{ "code": 0, "msg": "", "list": { "item_list|10": [{ "id": 2959165, "order_sn": /T180[0-9]{6}/, "bike_sn": "800116090", "user_id": 908352, "user_name": "@cname", "mobile": /1[0-9]{10}/, "distance": 2000, "total_time": 4000, "status|1-2": 1, "start_time": "@datetime", "end_time": "@datetime", "total_fee": 1000, "user_pay": 300 }] }, "page|1-9": 1, page_size: 10, total: 85, page_count: 9 }
同城市管理:调用this.requestList(),默认请求接口数据
- Easy Mock结束订单信息数据接口:/order/ebike_info
{ "code": 0, "list": { "id": 27296, "bike_sn": "800116116", "battery": 100, "start_time": "@datetime", "location": "西虹市海淀区桃花公园" } }
-
Easy Mock结束订单成功数据接口:/order/finish_order
{ "code": 0, "list": "ok" }
-
【结束订单】按钮:监听onClick事件,调用this.handleConfirm()显示确认结束弹框
<Button type="primary" style={{marginLeeft: 10}} onClick={this.handlConfirm}>结束订单</Button>
//订单结束确认 handleConfirm = () => { let item = this.state.selectedItem; if(!item){ Modal.info({ title: ‘信息‘, content: ‘请选择一条订单进行结束‘ }) return; } axios.ajax({ url: ‘/order/ebike_info‘, data: { params: { orderId: item.id } } }).then((res) => { if(res.code === 0 ){ this.setState({ orderInfo: res.list, orderConfirmVisible: true }) } }) }
-
确认取消:打开Modal弹框,显示要取消的订单信息
<Modal title="结束订单" visible={this.state.orderConfirmVisible} onCancel={() => { this.setState({ orderConfirmVisible: false }) }} onOk={this.handleFinishOrder} width={600}> <Form layout="horizontal"> <FormItem label="车辆编号" {...formItemLayout}> {this.state.orderInfo.bike_sn} </FormItem> <FormItem label="剩余电量" {...formItemLayout}> {this.state.orderInfo.battery + ‘%‘} </FormItem> <FormItem label="行程开始时间" {...formItemLayout}> {this.state.orderInfo.start_time} </FormItem> <FormItem label="当前位置" {...formItemLayout}> {this.state.orderInfo.location} </FormItem> </Form> </Modal>
-
结束订单:onOk事件调用this.handleFinishOrder()
//结束订单 handleFinishOrder = () => { let item = this.state.selectedItem; axios.ajax({ url: ‘/order/finish_order‘, data: { params: { orderId: item.id } } }).then((res) => { if(res.code === 0){ message.success(‘订单结束成功‘) this.setState({ orderConfirmVisible: false }) this.requestList(); } }) }
-
实例代码:
import React from ‘react‘ import { Card, Button, Table, Form, Select, Modal, message, DatePicker } from ‘antd‘; import axios from ‘./../../axios/index‘; import Utils from ‘./../../utils/utils‘; const FormItem = Form.Item; const Option = Select.Option; export default class Order extends React.Component{ state = { orderInfo: {}, orderConfirmVisible: false } params = { page:1 } componentDidMount(){ this.requestList(); } requestList = () => { let _this = this; axios.ajax({ url: ‘/order/list‘, data: { params: { page: this.params.page } } }).then((res) => { if(res.code === 0){ let list = res.list.item_list.map((item, index) => { item.key = index; return item; }); this.setState({ list:list, selectedRowKeys: [],//重置 pagination:Utils.pagination(res,(current)=>{ _this.params.page = current; _this.requestList(); }) }) } }) } //订单结束确认 handleConfirm = () => { let item = this.state.selectedItem; if(!item){ Modal.info({ title: ‘信息‘, content: ‘请选择一条订单进行结束‘ }) return; } axios.ajax({ url: ‘/order/ebike_info‘, data: { params: { orderId: item.id } } }).then((res) => { if(res.code === 0 ){ this.setState({ orderInfo: res.list, orderConfirmVisible: true }) } }) } //结束订单 handleFinishOrder = () => { let item = this.state.selectedItem; axios.ajax({ url: ‘/order/finish_order‘, data: { params: { orderId: item.id } } }).then((res) => { if(res.code === 0){ message.success(‘订单结束成功‘) this.setState({ orderConfirmVisible: false }) this.requestList(); } }) } onRowClick = (record, index) => { let selectKey = [index]; this.setState({ selectedRowKeys: selectKey, selectedItem: record }) } //订单详情页 openOrderDetail = () => { let item = this.state.selectedItem; if(!item){ Modal.info({ title: ‘信息‘, content: ‘请先选择一条订单‘ }) return; } window.open(`/#/common/order/detail/${item.id}`,‘_blank‘) } render(){ const columns = [ { title: ‘订单编号‘, dataIndex: ‘order_sn‘ }, { title: ‘车辆编号‘, dataIndex: ‘bike_sn‘ }, { title: ‘用户名‘, dataIndex: ‘user_name‘ }, { title: ‘手机号‘, dataIndex: ‘mobile‘ }, { title: ‘里程‘, dataIndex: ‘distance‘, render(distance){ return distance/1000 + ‘Km‘; } }, { title: ‘行驶时长‘, dataIndex: ‘total_time‘ }, { title: ‘状态‘, dataIndex: ‘status‘ }, { title: ‘开始时间‘, dataIndex: ‘start_time‘ }, { title: ‘结束时间‘, dataIndex: ‘end_time‘ }, { title: ‘订单金额‘, dataIndex: ‘total_fee‘ }, { title: ‘实付金额‘, dataIndex: ‘user_pay‘ } ] const formItemLayout = { labelCol: { span: 5 }, wrapperCol: { span: 19 } } const selectedRowKeys = this.state.selectedRowKeys; const rowSelection = { type: ‘radio‘, selectedRowKeys } return ( <div> <Card> <FilterForm /> </Card> <Card style={{marginTop:10}}> <Button type="primary" onClick={this.openOrderDetail}>订单详情</Button> <Button type="primary" style={{marginLeeft: 10}} onClick={this.handlConfirm}>结束订单</Button> </Card> <div className="content-wrap"> <Table bordered columns={columns} dataSource={this.state.list} pagination={this.state.pagination} rowSelection= {rowSelection} onRow={(record, index) => { return { onClick: () => { this.onRowClick(record, index); } } }} /> </div> <Modal title="结束订单" visible={this.state.orderConfirmVisible} onCancel={() => { this.setState({ orderConfirmVisible: false }) }} onOk={this.handleFinishOrder} width={600}> <Form layout="horizontal"> <FormItem label="车辆编号" {...formItemLayout}> {this.state.orderInfo.bike_sn} </FormItem> <FormItem label="剩余电量" {...formItemLayout}> {this.state.orderInfo.battery + ‘%‘} </FormItem> <FormItem label="行程开始时间" {...formItemLayout}> {this.state.orderInfo.start_time} </FormItem> <FormItem label="当前位置" {...formItemLayout}> {this.state.orderInfo.location} </FormItem> </Form> </Modal> </div> ) } } //子组件一:选择表单 class FilterForm extends React.Component{ render(){ const { getFieldDecorator } = this.props.form; return ( <Form layout="inline"> <FormItem label="城市"> { getFieldDecorator(‘city_id‘)( <Select style={{width:100}} placeholder="全部" > <Option value="">全部</Option> <Option value="1">北京市</Option> <Option value="2">天津市</Option> <Option value="3">深圳市</Option> </Select> ) } </FormItem> <FormItem label="订单时间"> { getFieldDecorator(‘start_time‘)( <DatePicker showTime format="YYYY-MM-DD HH:mm:ss"/> ) } </FormItem> <FormItem style={{marginLeft: -10}}> { getFieldDecorator(‘end_time‘)( <DatePicker style={{marginLeft: 5}} showTime format="YYYY-MM-DD HH:mm:ss"/> ) } </FormItem> <FormItem label="订单状态"> { getFieldDecorator(‘status‘)( <Select style={{ width: 80 }} placeholder="全部" > <Option value="">全部</Option> <Option value="1">进行中</Option> <Option value="2">结束行程</Option> </Select> ) } </FormItem> <FormItem> <Button type="primary" style={{margin:‘0 5px‘}}>查询</Button> <Button>重置</Button> </FormItem> </Form> ); } } FilterForm = Form.create({})(FilterForm);
三、订单详情
- 跳转详情页
- pages->order->index.js中:【订单详情】按钮监听onClick事件,调用this.openOrderDetail(),跳转路由
//订单详情页 openOrderDetail = () => { let item = this.state.selectedItem; if(!item){ Modal.info({ title: ‘信息‘, content: ‘请先选择一条订单‘ }) return; } window.open(`/#/common/order/detail/${item.id}`,‘_blank‘) }
关键:window.open(`/#/common/order/detail/${item.id}`,‘_blank‘)
-
src目录下:新建common.js,类似admin.js编写项目公共结构代码,负责路由详情页展示
import React from ‘react‘ import { Row, Col } from ‘antd‘; import Header from ‘./components/Header‘ import ‘./style/common.less‘ export default class Common extends React.Component { render() { return ( <div> <Row className="simple-page"> <Header menuType="second"/> </Row> <Row className="content"> {this.props.children} </Row> </div> ); } }
通过menuType:控制显示header组件的不同样式(components->header->index.js)
//其它代码 render() { const menuType = this.props.menuType; return ( <div className="header"> <Row className="header-top"> { menuType ? <Col span="6" className="logo"> <img src="/assets/logo-ant.svg" /> <span>LJQ 通用管理系统</span> </Col> : ‘‘ } <Col span={menuType ? 18 : 24}> <span>欢迎,{this.state.userName}</span> <a href=‘#‘>退出</a> </Col> </Row> { menuType ? ‘‘ : <Row className="breadcrumb"> <Col span={4} className="breadcrumb-title"> 首页 </Col> <Col span={20} className="weather"> <span className="date">{this.state.sysTime}</span> <span className="weather-detail">晴转多云</span> </Col> </Row> } </div> ) }
CSS样式:
//style->common.less ul,li{ list-style: none; } .clearfix{ &::after{ content:‘‘; clear: both; display: block; visibility: hidden; } } .content{ padding: 20px } //components->header->index.less //.common 页面简单头 .simple-page{ .header-top{ background: #1890ff; color: @colorM; } .ant-form, .ant-col-12, .weather{ display: none; } } //引入pages->order->detail.less
-
router.js中:引入Common组件,使用<Route />的render方法定义嵌套路由
<Route path="/common" render={() => <Common> <Route path="/common/order/detail/:orderId" component={OrderDetail} /> </Common> }/>
-
获取订单详情基础信息
-
Easy Mock订单详情数据接口:/order/detail
{ "code": 0, "msg": "", "list": { "status": 2, "order_sn": "T1803244422704080JGJI", "bike_sn": ‘802410001‘, "mode|1-2": 1, "start_location": "北京市昌平区回龙观东大街", "end_location": "北京市海淀区奥林匹克公园", "city_id": 1, "mobile": "13597482075", "user_name": "@cname", "distance": 10000, "bike_gps": "116.398806,40.008637", "start_time": 1546580667000, "end_time": 1546608995000, "total_time": 224, "position_list": [{ "lon": 116.361221, "lat": 40.043776 }, { "lon": 116.363736, "lat": 40.038086 }, { "lon": 116.364599, "lat": 40.036484 }, { "lon": 116.373438, "lat": 40.03538 }, { "lon": 116.377966, "lat": 40.036263 }, { "lon": 116.379762, "lat": 40.03654 }, { "lon": 116.38084, "lat": 40.033225 }, { "lon": 116.38084, "lat": 40.029413 }, { "lon": 116.381343, "lat": 40.021291 }, { "lon": 116.381846, "lat": 40.015821 }, { "lon": 116.382637, "lat": 40.008084 }, { "lon": 116.398806, "lat": 40.008637 } ], "area": [{ "lon": "116.274737", "lat": "40.139759", "ts": null }, { "lon": "116.316562", "lat": "40.144943", "ts": null }, { "lon": "116.351631", "lat": "40.129498", "ts": null }, { "lon": "116.390582", "lat": "40.082481", "ts": null }, { "lon": "116.38742", "lat": "40.01065", "ts": null }, { "lon": "116.414297", "lat": "40.01181", "ts": null }, { "lon": "116.696242", "lat": "39.964035", "ts": null }, { "lon": "116.494498", "lat": "39.851306", "ts": null }, { "lon": "116.238086", "lat": "39.848647", "ts": null }, { "lon": "116.189454", "lat": "39.999418", "ts": null }, { "lon": "116.244646", "lat": "39.990574", "ts": null }, { "lon": "116.281441", "lat": "40.008703", "ts": null }, { "lon": "116.271092", "lat": "40.142201", "ts": null }, { "lon": "116.271092", "lat": "40.142201", "ts": null } ], "area_list": null, "npl_list": [{ "id": 8265, "name": "北辰世纪中心-a座", "city_id": 1, "type": 3, "status": 0, "map_point": "116.39338796444|40.008120315215;116.39494038009002|40.008177258745;116.39496911688|40.006268094213;116.39512457763|40.004256795877;116.39360214742|40.004222412241;116.39357190147|40.005075745782;116.39351397873|40.005836165232;116.39338796444|40.008120315215", "map_point_array": [ "116.39338796444|40.008120315215", "116.396053|40.008273", "116.396448|40.006338", "116.396915|40.004266", "116.39192|40.004072", "116.391525|40.004984", "116.391381|40.005924", "116.391166|40.007913" ], "map_status": 1, "creator_name": "赵程程", "create_time": 1507863539000 }] } }
-
componentDidMount()中获取url参数orderId:调用this.getDetailInfo(orderId)获取订单详情数据
componentDidMount(){ let orderId = this.props.match.params.orderId; if(orderId){ this.getDetailInfo(orderId); } } getDetailInfo = (orderId) => { axios.ajax({ url: ‘/order/detail‘, data: { params: { orderId: orderId } } }).then((res) => { if(res.code === 0){ this.setState({ orderInfo: res.list }) this.renderMap(res.list); } }) }
关键:this.props.match.params.参数 详情:【React获取url参数—this.props.match】
-
实例代码
import React from ‘react‘; import { Card } from ‘antd‘; import axios from ‘../../axios‘; import ‘./detail.less‘; export default class Order extends React.Component{ state = {} componentDidMount(){ let orderId = this.props.match.params.orderId; if(orderId){ this.getDetailInfo(orderId); } } getDetailInfo = (orderId) => { axios.ajax({ url: ‘/order/detail‘, data: { params: { orderId: orderId } } }).then((res) => { if(res.code === 0){ this.setState({ orderInfo: res.list }) this.renderMap(res.list); } }) } //初始化地图 renderMap = (list) => { this.map = new window.BMap.Map(‘orderDetailMap‘); // this.map.centerAndZoom(‘北京‘, 11) //添加地图控件 this.addMapControl(); //调用路线图绘制方法 this.drawBikeRoute(list.position_list); //调用服务区绘制方法 this.drawServiceArea(list.area); } //添加地图控件 addMapControl = () => { let map = this.map; map.addControl(new window.BMap.ScaleControl({ anchor: window.BMAP_ANCHOR_TOP_RIGHT })); map.addControl(new window.BMap.NavigationControl({ anchor: window.BMAP_ANCHOR_TOP_RIGHT })); } //绘制用户行驶路线图 drawBikeRoute = (positionList) => { let map = this.map; let startPoint = ‘‘; let endPoint = ‘‘; if(positionList.length > 0){ //起点 let first = positionList[0]; startPoint = new window.BMap.Point(first.lon, first.lat); let startIcon = new window.BMap.Icon(‘/assets/start_point.png‘, new window.BMap.Size(36,42),{ imageSize: new window.BMap.Size(36,42), anchor: new window.BMap.Size(36,42) }) let startMarker = new window.BMap.Marker(startPoint, {icon: startIcon}); this.map.addOverlay(startMarker); //终点 let last = positionList[positionList.length-1]; endPoint = new window.BMap.Point(last.lon, last.lat); let endIcon = new window.BMap.Icon(‘/assets/end_point.png‘, new window.BMap.Size(36,42),{ imageSize: new window.BMap.Size(36,42), anchor: new window.BMap.Size(36,42) }) let endMarker = new window.BMap.Marker(endPoint, {icon: endIcon}); this.map.addOverlay(endMarker); //连接路线图 let trackPoint = []; for(let i=0; i<positionList.length; i++){ let point = positionList[i] trackPoint.push(new window.BMap.Point(point.lon, point.lat)) } let polyline = new window.BMap.Polyline(trackPoint, { strokeColor: ‘#1869AD‘, strokeWeight: 3, strokeOpacity: 1 }) this.map.addOverlay(polyline); //设置地图中心点 this.map.centerAndZoom(endPoint, 11) } } //绘制服务区 drawServiceArea = (positionList) => { let trackPoint = []; for(let i=0; i<positionList.length; i++){ let point = positionList[i] trackPoint.push(new window.BMap.Point(point.lon, point.lat)) } let polygon = new window.BMap.Polygon(trackPoint, { strokeColor: ‘#CE0000‘, strokeWeight: 4, strokeOpacity: 1, fillColor: ‘#ff8605‘, fillOpacity: 0.4 }) this.map.addOverlay(polygon); } render(){ const info = this.state.orderInfo || {}; return ( <div> <Card> <div id="orderDetailMap" className="order-map"></div> <div className="detail-items"> <div className="item-title">基础信息</div> <ul className="detail-form"> <li> <div className="detail-form-left">用车模式</div> <div className="detail-form-content">{info.mode === 1 ? ‘服务器‘ : ‘停车点‘}</div> </li> <li> <div className="detail-form-left">订单编号</div> <div className="detail-form-content">{info.order_sn}</div> </li> <li> <div className="detail-form-left">车辆编号</div> <div className="detail-form-content">{info.bike_sn}</div> </li> <li> <div className="detail-form-left">用户姓名</div> <div className="detail-form-content">{info.user_name}</div> </li> <li> <div className="detail-form-left">手机号码</div> <div className="detail-form-content">{info.mobile}</div> </li> </ul> </div> <div className="detail-items"> <div className="item-title">行驶轨迹</div> <ul className="detail-form"> <li> <div className="detail-form-left">行驶起点</div> <div className="detail-form-content">{info.start_location}</div> </li> <li> <div className="detail-form-left">行驶终点</div> <div className="detail-form-content">{info.end_location}</div> </li> <li> <div className="detail-form-left">行驶里程</div> <div className="detail-form-content">{info.distance/1000}Km</div> </li> </ul> </div> </Card> </div> ); } }
注:项目来自慕课网
以上是关于共享单车—— React后台管理系统开发手记:城市管理和订单管理的主要内容,如果未能解决你的问题,请参考以下文章
共享单车—— React后台管理系统开发手记:Redux集成开发
共享单车—— React后台管理系统开发手记:AntD Form基础组件
共享单车—— React后台管理系统开发手记:主页面架构设计
共享单车—— React后台管理系统开发手记:AntD Table高级表格