OrderList.js 9.1 KB
Newer Older
sin's avatar
sin committed
1
import React, { PureComponent } from 'react';
sin's avatar
sin committed
2 3
import moment from 'moment';
import { connect } from 'dva';
sin's avatar
sin committed
4
import { Button, Card, Col, Divider, Form, Input, Row, Tabs, DatePicker, List } from 'antd';
sin's avatar
sin committed
5 6 7

import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import DictionaryText from '@/components/Dictionary/DictionaryText';
sin's avatar
sin committed
8
import OrderUpdatePayAmount from './OrderUpdatePayAmount';
sin's avatar
sin committed
9
import OrderDelivery from './OrderDelivery';
sin's avatar
sin committed
10 11
import OrderRemark from './OrderRemark';
import OrderCancel from './OrderCancel';
sin's avatar
sin committed
12 13 14 15
import dictionary from '@/utils/dictionary';

import styles from './OrderList.less';

16
const { RangePicker } = DatePicker;
sin's avatar
sin committed
17
const FormItem = Form.Item;
sin's avatar
sin committed
18
const { TabPane } = Tabs;
sin's avatar
sin committed
19

sin's avatar
sin committed
20 21
const OrderContent = props => {
  const { dispatch, item } = props;
sin's avatar
sin committed
22 23
  const { createTime, status, payAmount, id } = item;
  const { name, mobile } = item.orderRecipient || {};
sin's avatar
sin committed
24

sin's avatar
sin committed
25
  const handleUpdatePayAmount = updateOrderItem => {
sin's avatar
sin committed
26
    dispatch({
sin's avatar
sin committed
27
      type: 'orderList/changePayAmountVisible',
28
      payload: {
sin's avatar
sin committed
29 30 31 32
        payAmountVisible: true,
        payAmount: updateOrderItem.payAmount,
        orderId: updateOrderItem.orderId,
        orderItemId: updateOrderItem.id,
33
      },
sin's avatar
sin committed
34 35 36
    });
  };

sin's avatar
sin committed
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
  const handleOrderDelivery = () => {
    dispatch({
      type: 'orderDelivery/changeVisible',
      payload: {
        visible: true,
        orderId: id,
      },
    });

    dispatch({
      type: 'orderDelivery/getOrderItems',
      payload: {
        orderId: id,
      },
    });
  };
sin's avatar
sin committed
53 54 55 56 57 58

  const renderStatusButtons = () => {
    let res = '';
    if (status === 1) {
      res = <Button>取消订单</Button>;
    } else if (status === 2) {
sin's avatar
sin committed
59
      res = <Button onClick={() => handleOrderDelivery()}>发货</Button>;
sin's avatar
sin committed
60 61 62 63 64 65 66
    }
    return res;
  };

  const renderGoods = orderItems => {
    return orderItems.map(({ skuName, skuImage, quantity, price }) => {
      return (
sin's avatar
sin committed
67
        <div key={skuName} className={styles.orderGoods}>
sin's avatar
sin committed
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
          <img alt={skuName} className={`${styles.image}`} src={skuImage} />
          <div className={styles.contentItem}>
            <div>
              <a>{skuName}</a>
            </div>
            <div>秋季精选</div>
          </div>
          <div className={styles.contentItem}>
            <div>{quantity}</div>
            <div>
              {price / 100} /{quantity * (price / 100)} 
            </div>
          </div>
        </div>
      );
    });
  };

sin's avatar
sin committed
86 87
  return (
    <div className={styles.order}>
sin's avatar
sin committed
88 89
      <div className={`${styles.contentItem} ${styles.goodsContainer}`}>
        {renderGoods(item.orderItems)}
sin's avatar
sin committed
90 91
      </div>
      <div className={styles.contentItem}>
sin's avatar
sin committed
92 93
        <div>{name}</div>
        <div>{mobile}</div>
sin's avatar
sin committed
94 95 96 97 98 99 100 101 102 103
      </div>
      <div className={styles.contentItem}>
        <div className={styles.columnName}>(下单时间)</div>
        <div>{moment(createTime).format('YYYY-MM-DD HH:mm')}</div>
        <div>&nbsp;</div>
      </div>
      <div className={styles.contentItem}>
        <div>
          <DictionaryText dicKey={dictionary.ORDER_STATUS} dicValue={status} />
        </div>
sin's avatar
sin committed
104
        <div>{renderStatusButtons(props)}</div>
sin's avatar
sin committed
105 106 107 108 109
      </div>
      <div className={styles.contentItem}>
        <div className={styles.columnName}>(实付金额)</div>
        <div>{payAmount / 100}</div>
        <div>
sin's avatar
sin committed
110
          <a onClick={() => handleUpdatePayAmount(props)}>修改价格</a>
sin's avatar
sin committed
111 112 113 114 115 116 117 118 119
        </div>
      </div>
    </div>
  );
};

const OrderList = props => {
  const { list, dispatch, loading } = props;
  const { pagination, dataSource } = list;
sin's avatar
sin committed
120

sin's avatar
sin committed
121 122
  const paginationProps = {
    ...pagination,
sin's avatar
sin committed
123 124
  };

sin's avatar
sin committed
125 126 127 128 129 130 131 132 133 134 135 136
  const handleRemakeClick = item => {
    const { id, remark } = item;
    dispatch({
      type: 'orderList/changeRemakeVisible',
      payload: {
        remarkVisible: true,
        orderId: id,
        remark,
      },
    });
  };

sin's avatar
sin committed
137
  return (
sin's avatar
sin committed
138 139
    <List
      size="large"
sin's avatar
sin committed
140 141
      rowKey="id"
      loading={loading}
sin's avatar
sin committed
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
      pagination={paginationProps}
      dataSource={dataSource}
      renderItem={item => (
        <List.Item>
          <div className={styles.orderGroup}>
            <div className={styles.header}>
              <div>
                <span>订单号: {item.orderNo}</span>
                <Divider type="vertical" />
                <span>支付金额: {item.payAmount / 100} </span>
              </div>

              <div>
                <a>查看详情</a>
                <Divider type="vertical" />
sin's avatar
sin committed
157
                <a onClick={() => handleRemakeClick(item)}>备注</a>
sin's avatar
sin committed
158 159 160
              </div>
            </div>

sin's avatar
sin committed
161
            <OrderContent item={item} dispatch={dispatch} />
sin's avatar
sin committed
162 163 164
          </div>
        </List.Item>
      )}
sin's avatar
sin committed
165 166 167 168 169
    />
  );
};

// SearchForm
sin's avatar
sin committed
170
const SearchForm = Form.create()(props => {
sin's avatar
sin committed
171 172
  const {
    form: { getFieldDecorator },
173 174
    form,
    handleSearch,
sin's avatar
sin committed
175 176 177 178
  } = props;

  const handleFormReset = () => {};

179 180 181 182 183
  const onSubmit = e => {
    e.preventDefault();
    form.validateFields((err, fields) => {
      const buildTime = (fieldValue, key) => {
        const res = {};
sin's avatar
sin committed
184
        if (fieldValue && fieldValue.length >= 2) {
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
          const keySuffix = key.substring(0, 1).toUpperCase() + key.substring(1);
          res[`start${keySuffix}`] = fieldValue[0].format('YYYY-MM-DD HH:mm:ss');
          res[`end${keySuffix}`] = fieldValue[1].format('YYYY-MM-DD HH:mm:ss');
        }
        return res;
      };

      const timeFields = ['createTime', 'closingTime'];
      const buildSearchParams = fields2 => {
        let res = {};
        Object.keys(fields).map(objectKey => {
          const fieldValue = fields2[objectKey];
          if (timeFields.indexOf(objectKey) !== -1) {
            // 处理时间
            res = {
              ...res,
              ...buildTime(fieldValue, objectKey),
            };
          } else if (fieldValue !== undefined) {
            res[objectKey] = fieldValue;
          }
          return true;
        });
        return res;
      };

      const searchParams = buildSearchParams(fields);
      if (handleSearch) {
        handleSearch(searchParams);
      }
    });
  };
sin's avatar
sin committed
217 218

  return (
219
    <Form onSubmit={onSubmit} layout="inline">
sin's avatar
sin committed
220 221
      <Row gutter={{ md: 8, lg: 24, xl: 48 }}>
        <Col md={8} sm={24}>
222 223
          <FormItem label="订单id">
            {getFieldDecorator('id')(<Input placeholder="请输入订单id" />)}
sin's avatar
sin committed
224 225 226
          </FormItem>
        </Col>
        <Col md={8} sm={24}>
227 228
          <FormItem label="订单号">
            {getFieldDecorator('orderNo')(<Input placeholder="请输入订单号" />)}
sin's avatar
sin committed
229 230
          </FormItem>
        </Col>
231 232 233 234 235 236
      </Row>

      <Row gutter={{ md: 8, lg: 24, xl: 48 }}>
        <Col md={8} sm={24}>
          <FormItem label="创建时间">{getFieldDecorator('createTime')(<RangePicker />)}</FormItem>
        </Col>
sin's avatar
sin committed
237 238 239 240 241 242 243 244 245 246 247 248 249
        <Col md={8} sm={24}>
          <span className={styles.submitButtons}>
            <Button type="primary" htmlType="submit">
              查询
            </Button>
            <Button style={{ marginLeft: 8 }} onClick={handleFormReset}>
              重置
            </Button>
          </span>
        </Col>
      </Row>
    </Form>
  );
sin's avatar
sin committed
250
});
sin's avatar
sin committed
251

sin's avatar
sin committed
252
@connect(({ orderList, orderDelivery, loading }) => ({
sin's avatar
sin committed
253
  orderList,
254
  list: orderList.list,
sin's avatar
sin committed
255
  loading: loading.models.orderList,
sin's avatar
sin committed
256
  orderDelivery,
sin's avatar
sin committed
257 258 259
}))
class BasicList extends PureComponent {
  componentDidMount() {
260 261 262 263 264 265 266 267 268 269 270
    const {
      list: { pagination },
    } = this.props;

    this.queryList({
      pageNo: pagination.current,
      pageSize: pagination.pageSize,
    });
  }

  queryList = params => {
sin's avatar
sin committed
271
    const { dispatch } = this.props;
sin's avatar
sin committed
272 273 274
    // 保存每次操作 searchParams
    this.searchParams = params;
    // dispatch
sin's avatar
sin committed
275 276 277
    dispatch({
      type: 'orderList/queryPage',
      payload: {
278
        ...params,
sin's avatar
sin committed
279 280
      },
    });
281
  };
sin's avatar
sin committed
282

sin's avatar
sin committed
283
  handleEditorClick = () => {};
sin's avatar
sin committed
284

285 286 287 288 289 290 291 292 293
  handleSearch = fields => {
    const {
      list: { pagination },
    } = this.props;

    this.queryList({
      ...fields,
      pageNo: pagination.current,
      pageSize: pagination.pageSize,
sin's avatar
sin committed
294 295 296
    });
  };

sin's avatar
sin committed
297 298 299 300 301 302 303 304 305
  handleTabsChange = key => {
    const params = {
      ...this.searchParams,
      status: key,
    };

    this.queryList(params);
  };

sin's avatar
sin committed
306 307 308 309 310 311 312 313 314 315 316 317
  render() {
    return (
      <PageHeaderWrapper>
        <div className={styles.standardList}>
          <Card
            className={styles.listCard}
            bordered={false}
            title="订单列表"
            style={{ marginTop: 24 }}
            bodyStyle={{ padding: '0 32px 40px 32px' }}
          >
            <div className={styles.tableListForm}>
318
              <SearchForm {...this.props} handleSearch={this.handleSearch} />
sin's avatar
sin committed
319
            </div>
sin's avatar
sin committed
320 321 322 323 324 325 326 327 328
            <Tabs defaultActiveKey={null} onChange={this.handleTabsChange}>
              <TabPane tab="全部" key={null} />
              <TabPane tab="待付款" key={0} />
              <TabPane tab="待发货" key={1} />
              <TabPane tab="已发货" key={2} />
              <TabPane tab="已完成" key={3} />
              <TabPane tab="已关闭" key={4} />
            </Tabs>

sin's avatar
sin committed
329 330 331
            <OrderList {...this.props} handleEditorClick={this.handleEditorClick} />
          </Card>
        </div>
sin's avatar
sin committed
332 333

        <OrderUpdatePayAmount {...this.props} />
sin's avatar
sin committed
334 335
        <OrderRemark {...this.props} />
        <OrderCancel {...this.props} />
sin's avatar
sin committed
336 337

        <OrderDelivery {...this.props} />
sin's avatar
sin committed
338 339 340 341 342 343
      </PageHeaderWrapper>
    );
  }
}

export default BasicList;