ProductSpuAddOrUpdate.js 9.8 KB
Newer Older
1 2
/* eslint-disable */

3
import React, {PureComponent, Fragment, Component} from 'react';
4 5
// import crypto from 'crypto';
// import fs from 'fs';
6 7
import { connect } from 'dva';
import moment from 'moment';
8
import {Card, Form, Input, Radio, Button, Modal, Select, Upload, Icon, Spin, TreeSelect} from 'antd';
9 10
import PageHeaderWrapper from '@/components/PageHeaderWrapper';

11 12
// import * as qiniu from 'qiniu-js'
// import uuid from 'js-uuid';
13

14
import styles from './ProductSpuAddOrUpdate.less';
15 16
import ProductAttrSelectFormItem from "../../components/Product/ProductAttrSelectFormItem";
import ProductSkuAddOrUpdateTable from "../../components/Product/ProductSkuAddOrUpdateTable";
17
// import {fileGetQiniuToken} from "../../services/admin";
18
import PicturesWall from "../../components/Image/PicturesWall";
19 20 21
import {fileGetQiniuToken} from "../../services/admin";
import uuid from "js-uuid";
import * as qiniu from "qiniu-js";
22
import HtmlEditor from "../../components/Editor/HtmlEditor";
23 24 25

const FormItem = Form.Item;
const RadioGroup = Radio.Group;
26
const Option = Select.Option;
27 28

// roleList
29
@connect(({ productAttrList, productSpuAddOrUpdate, productCategoryList }) => ({
30 31
  // list: productSpuList.list.spus,
  // loading: loading.models.productSpuList,
32 33
  productAttrList,
  productSpuAddOrUpdate,
34
  allAttrTree: productAttrList.tree,
35 36
  loading: productSpuAddOrUpdate.loading,
  spu: productSpuAddOrUpdate.spu,
37 38
  attrTree: productSpuAddOrUpdate.attrTree,
  skus: productSpuAddOrUpdate.skus,
39
  categoryTree: productCategoryList.list,
40 41 42
}))

@Form.create()
43
class ProductSpuAddOrUpdate extends Component {
44
  state = {
45
    // modalVisible: false,
46
    modalType: 'add', //add update
47
    // initValues: {},
48
    htmlEditor: undefined,
49 50 51 52
  };

  componentDidMount() {
    const { dispatch } = this.props;
53
    const that = this;
54 55 56 57
    // 重置表单
    dispatch({
      type: 'productSpuAddOrUpdate/clear',
    });
58 59 60 61 62 63
    // 判断是否是更新
    const params = new URLSearchParams(this.props.location.search);
    if (params.get("id")) {
      let id = params.get("id");
      this.setState({
        modalType: 'update',
64
        id: id,
65 66 67 68
      })
      dispatch({
        type: 'productSpuAddOrUpdate/info',
        payload: parseInt(id),
69 70
        callback: function (data) {
          that.refs.picturesWall.setUrls(data.picUrls); // TODO 后续找找,有没更合适的做法
71 72
          // debugger;
          that.state.htmlEditor.setHtml(data.description);
73
        }
74 75 76
      })
    }
    // 获得规格列表
77
    dispatch({
78
      type: 'productAttrList/tree',
79 80 81 82 83 84
      payload: {
        name: '',
        pageNo: 0,
        pageSize: 10,
      },
    });
85
    // 获得商品分类
86
    dispatch({
87 88 89
      type: 'productCategoryList/tree',
      payload: {},
    });
90 91
  }

92 93 94 95 96 97 98 99
  handleAddAttr = e => {
    // alert('你猜');
    const { dispatch } = this.props;
    dispatch({
      type: 'productSpuAddOrUpdate/addAttr',
      payload: {
      },
    });
100
  };
101

102 103 104
  handleSubmit = e => {
    e.preventDefault();
    const { skus, dispatch } = this.props;
105
    const { modalType, id } = this.state;
106 107 108 109 110
    if (this.state.htmlEditor.isEmpty()) {
      alert('请设置商品描述!');
      return;
    }
    const description = this.state.htmlEditor.getHtml();
111
    // 获得图片
112
    let picUrls = this.refs.picturesWall.getUrls(); // TODO 芋艿,后续找找其他做法
113 114 115 116
    if (picUrls.length === 0) {
      alert('请必须上传一张图片!');
      return;
    }
117 118 119 120 121 122 123 124 125
    // 生成 skuStr 格式
    let skuStr = []; // 因为提交是字符串格式
    for (let i in skus) {
      let sku = skus[i];
      if (!sku.price || !sku.quantity) {
        continue;
      }
      let newAttr = {
        attrs: [],
126
        price: sku.price * 100,
127 128 129 130 131 132 133 134 135 136 137
        quantity: sku.quantity,
      }
      for (let j in sku.attrs) {
        newAttr.attrs.push(sku.attrs[j].id);
      }
      skuStr.push(newAttr);
    }
    if (skuStr.length === 0) {
      alert('请设置商品规格!');
      return;
    }
138

139
    // debugger;
140
    this.props.form.validateFields((err, values) => {
141
      // debugger;
142
      // 获得富文本编辑的描述
143
      if (!err) {
144 145 146 147 148 149 150
        if (modalType === 'add') {
          dispatch({
            type: 'productSpuAddOrUpdate/add',
            payload: {
              body: {
                ...values,
                picUrls: picUrls.join(','),
151 152
                skuStr: JSON.stringify(skuStr),
                description,
153 154 155 156 157 158 159 160 161 162 163
              }
            },
          });
        } else if (modalType === 'update') {
          dispatch({
            type: 'productSpuAddOrUpdate/update',
            payload: {
              body: {
                ...values,
                id,
                picUrls: picUrls.join(','),
164 165
                skuStr: JSON.stringify(skuStr),
                description,
166 167 168 169
              }
            },
          });
        }
170
      }
171
    });
172
    // console.log(fields);
173
  };
174

175 176
  render() {
    // debugger;
177
    const { form, skus, attrTree, allAttrTree, loading, spu, categoryTree, dispatch } = this.props;
178
    // const that = this;
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196

    // 处理分类筛选
    const buildSelectTree = (list) => {
      return list.map(item => {
        let children = [];
        if (item.children) {
          children = buildSelectTree(item.children);
        }
        return {
          title: item.name,
          value: item.id,
          key: item.id,
          children,
          selectable: item.pid > 0
        };
      });
    };
    let categoryTreeSelect = buildSelectTree(categoryTree);
197

198 199 200 201
    // 添加规格
    // debugger;
    let attrTreeHTML = [];
    if (attrTree && attrTree.length > 0) {
202 203
      // 已选择的的规格集合
      let selectedAttrIds = new Set();
204 205
      for (let i in attrTree) {
        let attr = attrTree[i];
206 207 208 209 210 211 212 213 214 215 216 217 218
        selectedAttrIds.add(attr.id);
      }
      // 创建每个规格下拉框的 HTML
      for (let i in attrTree) {
        let attr = attrTree[i];
        let itemProps = {
          attr: attr,
          allAttrTree: allAttrTree,
          dispatch: dispatch,
          selectedAttrIds: selectedAttrIds,
          index: i // 位置。不然无法正确修改 Model 指定位置的数据
        };
        attrTreeHTML.push(<ProductAttrSelectFormItem {...itemProps}  />);
219 220
      }
    }
221

222 223 224 225 226 227 228
    // 规格明细
    let productSkuProps = {
      attrTree: attrTree,
      skus: skus,
      dispatch: dispatch,
    };
    // console.log(productSkuProps);
229
    // let htmlEditor = undefined;
230

231 232
    return (
      <PageHeaderWrapper title="">
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
        <Spin spinning={loading}>
          <Card bordered={false}>
            <Form onSubmit={this.handleSubmit} hideRequiredMark style={{ marginTop: 8 }}>
              <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="商品名">
                {form.getFieldDecorator('name', {
                  rules: [{ required: true, message: '请输入商品名!', min: 2 }],
                  initialValue: spu.name,
                })(<Input placeholder="请输入" />)}
              </FormItem>
              <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="商品卖点">
                {form.getFieldDecorator('sellPoint', {
                  rules: [{ required: true, message: '请输入商品卖点!' }],
                  initialValue: spu.sellPoint,
                })(<Input placeholder="请输入" />)}
              </FormItem>
              <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="分类编号">
                {form.getFieldDecorator('cid', {
                  rules: [{ required: true, message: '请输入分类编号!' }],
251 252 253 254 255 256 257 258 259 260
                  initialValue: spu.cid,
                })(
                  <TreeSelect
                    showSearch
                    style={{ width: 300 }}
                    dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                    treeData={categoryTreeSelect}
                    placeholder="选择父分类"
                  />
                )}
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
              </FormItem>
              <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="商品主图"
                        extra="建议尺寸:800*800PX,单张大小不超过 2M,最多可上传 10 张">
                {/*{form.getFieldDecorator('picUrls', {*/}
                {/*  initialValue: '', // TODO 修改 // TODO 芋艿,做成上传组件*/}
                {/*})(<Input placeholder="请输入" />)}*/}
                <PicturesWall ref="picturesWall" maxLength={10} />
              </FormItem>
              <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="是否上架">
                {form.getFieldDecorator('visible', {
                  initialValue: spu.visible,
                })(
                  <RadioGroup>
                    <Radio value={true}></Radio>
                    <Radio value={false}></Radio>
                  </RadioGroup>
                )}
              </FormItem>
              <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="商品规格">
280 281 282 283
                <div>
                  {attrTreeHTML}
                  <Button onClick={this.handleAddAttr}>添加规格项目</Button>
                </div>
284 285 286 287 288 289 290
              </FormItem>
              {
                attrTree.length > 0 ? <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="规格明细">
                  {/*<Table defaultExpandAllRows={true} columns={columns} rowKey="id" />*/}
                  <ProductSkuAddOrUpdateTable {...productSkuProps} />
                </FormItem> : ''
              }
291 292
              <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="商品描述" required={false}>
                <HtmlEditor ref={(node) => this.state.htmlEditor = node} />
293 294 295 296 297
                <Button type="primary" htmlType="submit" style={{ marginLeft: 8 }} onSubmit={this.handleSubmit}>保存</Button>
              </FormItem>
            </Form>
          </Card>
        </Spin>
298 299 300 301 302 303
      </PageHeaderWrapper>
    );
  }
}

export default ProductSpuAddOrUpdate;