123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512 |
- import React, { Component } from 'react';
- import pathToRegexp from 'path-to-regexp';
- import { connect } from 'dva';
- import { routerRedux } from 'dva/router';
- import { Form, Modal, Card, Button, Input, Switch, Row, Col, Carousel, Select } from 'antd';
- import { renderStatus, statusToBool, boolToStatus, genAbsolutePicUrl } from '../../../utils/utils';
- import AXDragSortTable from '../../../components/AXDragSortTable';
- import Selector from '../../../components/AXTableSelector/Selector';
- import FooterToolbar from '../../../components/FooterToolbar';
- import styles from './SupportCreate.less';
- const fieldLabels = {
- code: '配套编号',
- title: '配套标题',
- subTitle: '配套副标题',
- name: '配套全称',
- merchant: '内容提供商',
- digest: '配套概要',
- detail: '配套详情',
- coverUrl: '配套封面图',
- imgList: '配套滚动图册',
- status: '配套状态',
- };
- const formItemLayout = {
- labelCol: {
- xs: { span: 24 },
- sm: { span: 3 },
- },
- wrapperCol: {
- xs: { span: 24 },
- sm: { span: 14 },
- md: { span: 12 },
- },
- };
- @connect(({ loading, product, resource, merchant }) => ({
- product,
- resource,
- merchant,
- pLoading: loading.models.product,
- rLoading: loading.models.resource,
- submitting: loading.models.product,
- }))
- @Form.create()
- export default class SupportCreatePage extends Component {
- state = {
- coverSelectorDestroy: true,
- carouselSelectorDestroy: true,
- supportSelectorDestroy: true,
- };
- componentWillMount() {
- const match = pathToRegexp('/product/support/create').exec(this.props.location.pathname);
- if (match) {
- this.cleanPageState();
- }
- }
- componentDidMount() {
- const matchId = this.isEdit();
- if (matchId) {
- this.props.dispatch({
- type: 'product/fetchProductItem',
- payload: { pid: matchId },
- });
- }
- this.props.dispatch({
- type: 'merchant/fetchMerchantList',
- payload: { pageSize: 1000 }, // TODO 以后商户多了需要改写交互样式
- });
- }
- isEdit = () => {
- const { location } = this.props;
- const match = pathToRegexp('/product/support/edit/:id').exec(location.pathname);
- if (match) {
- return match[1];
- }
- return false;
- };
- cleanPageState = () => {
- this.props.dispatch({
- type: 'product/cleanItemState',
- payload: {},
- });
- };
- selectorDataFetcher = (name, params) => {
- switch (name) {
- case 'cover':
- this.props.dispatch({
- type: 'resource/fetchImageList',
- payload: params,
- });
- break;
- case 'carousel':
- this.props.dispatch({
- type: 'resource/fetchImageList',
- payload: params,
- });
- break;
- case 'support':
- this.props.dispatch({
- type: 'product/fetchSupportList',
- payload: params,
- });
- break;
- default:
- break;
- }
- };
- currentItemFormatter = (name, rows) => {
- let payload;
- switch (name) {
- case 'cover':
- payload = { coverUrl: rows[0].path };
- break;
- case 'carousel':
- payload = { imgList: rows.map(row => row.path) };
- break;
- case 'support':
- payload = { supportList: rows };
- break;
- default:
- break;
- }
- return payload;
- };
- handleSelectorModalShow = (name) => {
- this.setState({
- [`${name}SelectorDestroy`]: false,
- });
- this.selectorDataFetcher(name);
- };
- handleSelectorChange = (name, params) => {
- this.selectorDataFetcher(name, params);
- };
- handleSelectorFinish = (name, rows) => {
- this.setState({
- [`${name}SelectorDestroy`]: true,
- });
- const payload = this.currentItemFormatter(name, rows);
- this.props.dispatch({
- payload,
- type: 'product/fixCurrentItem',
- });
- };
- handleDragSortTableChange = (name, rows) => {
- const payload = this.currentItemFormatter(name, rows);
- this.props.dispatch({
- payload,
- type: 'product/fixCurrentItem',
- });
- };
- handleSelectorCancel = (name) => {
- this.setState({
- [`${name}SelectorDestroy`]: true,
- });
- };
- handlePageBack = () => {
- this.props.dispatch(routerRedux.push({
- pathname: '/product/support/list',
- state: this.props.location.state,
- }));
- };
- handlePageSubmit = (e) => {
- e.preventDefault();
- this.props.form.validateFieldsAndScroll((err, values) => {
- if (!err) {
- // 从表单提取基础信息字段
- const { status, title, subTitle, name, ...rest } = values;
- const newName = `${title}_${subTitle}`;
- const newVals = { newName, title, subTitle, status: boolToStatus(status), ...rest };
- // 从props中提取coverUrl、imgList、supportList字段
- const { product } = this.props;
- const { currentItem } = product;
- const { imgList, supportList, coverUrl } = currentItem;
- // 防止supportList为空
- let supportIdList;
- if (supportList && supportList.length) {
- supportIdList = supportList.map(item => item.id);
- }
- // 更新或者创建操作
- const matchId = this.isEdit();
- if (matchId) {
- const params = {
- imgList,
- coverUrl,
- supportList: supportIdList,
- id: matchId,
- ...newVals,
- };
- this.props.dispatch({
- type: 'product/updateSupportItem',
- payload: params,
- states: this.props.location.state,
- });
- } else {
- const params = {
- imgList,
- coverUrl,
- supportList: supportIdList,
- ...newVals,
- };
- this.props.dispatch({
- type: 'product/createSupportItem',
- payload: params,
- states: this.props.location.state,
- });
- }
- }
- });
- };
- render() {
- const {
- form, submitting, rLoading, pLoading, product, resource, merchant,
- } = this.props;
- const {
- supportSelectorDestroy, coverSelectorDestroy, carouselSelectorDestroy,
- } = this.state;
- const {
- currentItem,
- } = product;
- const {
- code, title, subTitle, name, digest, detail, status, coverUrl, cpId,
- imgList = [], supportList = [],
- } = currentItem;
- const {
- getFieldDecorator,
- } = form;
- const supportColumns = [{
- title: '配套编号',
- dataIndex: 'code',
- key: 1,
- width: '20%',
- render: (text, record) => (
- <a
- className="a-link"
- target="_blank"
- rel="noopener noreferrer"
- href={`/product/support/edit/${record.id}`}
- >
- {text}
- </a>
- ),
- }, {
- title: '配套名称',
- dataIndex: 'name',
- key: 2,
- width: '30%',
- render: (text, record) => (
- <a
- className="a-link"
- target="_blank"
- rel="noopener noreferrer"
- href={`/product/support/edit/${record.id}`}
- >
- {text}
- </a>
- ),
- }, {
- title: '配套状态',
- dataIndex: 'status',
- key: 3,
- render: text => renderStatus(text),
- }];
- const getMerchants = () => {
- const { list } = merchant;
- return list.map(item => ({
- text: item.name,
- key: item.id,
- }));
- };
- const getResourceModal = (isCover) => {
- return (
- <Modal
- width={isCover ? 900 : 1100}
- footer={null}
- visible
- title="图片资源"
- maskClosable={false}
- onCancel={() => this.handleSelectorCancel(isCover ? 'cover' : 'carousel')}
- >
- <Selector
- loading={rLoading}
- list={resource.list}
- pageNo={resource.pageNo}
- pageSize={resource.pageSize}
- totalSize={resource.totalSize}
- multiple={!isCover}
- selectorName={isCover ? 'PictureSingle' : 'Index'}
- onCancel={() => this.handleSelectorCancel(isCover ? 'cover' : 'carousel')}
- onChange={data => this.handleSelectorChange(isCover ? 'cover' : 'carousel', data)}
- onFinish={rows => this.handleSelectorFinish(isCover ? 'cover' : 'carousel', rows)}
- />
- </Modal>
- );
- };
- const getSupportModal = () => {
- return (
- <Modal
- width={1100}
- footer={null}
- visible
- title="配套资源"
- maskClosable={false}
- onCancel={() => this.handleSelectorCancel('support')}
- >
- <Selector
- multiple
- loading={pLoading}
- selectorName="Support"
- list={product.list}
- pageNo={product.pageNo}
- pageSize={product.pageSize}
- totalSize={product.totalSize}
- onCancel={() => this.handleSelectorCancel('support')}
- onChange={data => this.handleSelectorChange('support', data)}
- onFinish={rows => this.handleSelectorFinish('support', rows)}
- />
- </Modal>
- );
- };
- const renderSupportCardName = () => {
- return (
- <Button
- type="primary"
- onClick={() => this.handleSelectorModalShow('support')}
- >相关配套
- </Button>
- );
- };
- const renderCoverCardName = () => {
- return (
- <div className={styles.cardName}>
- <span>
- <a onClick={() => this.handleSelectorModalShow('cover')}>配套封面</a>
- </span>
- </div>
- );
- };
- const renderCarouselCardName = () => {
- return (
- <div className={styles.cardName}>
- <span>
- <a onClick={() => this.handleSelectorModalShow('carousel')}>详情图册</a>
- </span>
- </div>
- );
- };
- return (
- <div>
- {/* 基础信息Card */}
- <Card title="基础信息" style={{ marginBottom: 16 }}>
- <Form>
- <Form.Item hasFeedback label={fieldLabels.code} {...formItemLayout}>
- {getFieldDecorator('code', {
- rules: [
- {
- required: true, message: '请填写配套编号',
- }, {
- pattern: /^[a-zA-Z0-9|-]+$/g, message: '编号包含非法字符',
- },
- ],
- initialValue: code,
- })(
- <Input placeholder="请输入" />
- )}
- </Form.Item>
- {this.isEdit() && (
- <Form.Item label={fieldLabels.name} {...formItemLayout}>
- {getFieldDecorator('name', {
- initialValue: name,
- })(
- <Input disabled />
- )}
- </Form.Item>
- )}
- <Form.Item hasFeedback label={fieldLabels.title} {...formItemLayout}>
- {getFieldDecorator('title', {
- rules: [{ required: true, message: '请填写配套标题' }],
- initialValue: title,
- })(
- <Input placeholder="请输入" />
- )}
- </Form.Item>
- <Form.Item hasFeedback label={fieldLabels.subTitle} {...formItemLayout}>
- {getFieldDecorator('subTitle', {
- rules: [{ required: true, message: '请填写配套副标题' }],
- initialValue: subTitle,
- })(
- <Input placeholder="请输入" />
- )}
- </Form.Item>
- <Form.Item hasFeedback label={fieldLabels.merchant} {...formItemLayout}>
- {getFieldDecorator('cpId', {
- rules: [{ required: true, message: '请选择供应商' }],
- initialValue: cpId,
- })(
- <Select placeholder="请选择">
- {
- getMerchants().map(item => (
- <Select.Option key={item.key} value={item.key}>
- {item.text}
- </Select.Option>
- ))
- }
- </Select>
- )}
- </Form.Item>
- <Form.Item label={fieldLabels.digest} {...formItemLayout}>
- {getFieldDecorator('digest', {
- initialValue: digest,
- })(
- <Input.TextArea rows={4} placeholder="请输入" />
- )}
- </Form.Item>
- <Form.Item label={fieldLabels.detail} {...formItemLayout}>
- {getFieldDecorator('detail', {
- initialValue: detail,
- })(
- <Input.TextArea rows={6} placeholder="请输入" />
- )}
- </Form.Item>
- <Form.Item label={fieldLabels.status} {...formItemLayout}>
- {getFieldDecorator('status', {
- valuePropName: 'checked',
- initialValue: statusToBool(status),
- })(
- <Switch
- checkedChildren="正常"
- unCheckedChildren="删除"
- />
- )}
- </Form.Item>
- </Form>
- </Card>
- {/* 封面及走马灯选择Card */}
- <Card title="封面|图册" style={{ marginBottom: 16 }}>
- <Row gutter={16}>
- <Col
- md={{ span: 10, offset: 1 }}
- lg={{ span: 8, offset: 2 }}
- xl={{ span: 6, offset: 4 }}
- xxl={{ span: 4, offset: 5 }}
- >
- <Card
- hoverable
- title={renderCoverCardName()}
- >
- <div className={styles.cover}>
- <img src={coverUrl && genAbsolutePicUrl(coverUrl)} alt="" />
- </div>
- {!coverSelectorDestroy && getResourceModal(true)}
- </Card>
- </Col>
- <Col
- md={{ span: 10, offset: 2 }}
- lg={{ span: 8, offset: 4 }}
- xl={{ span: 6, offset: 4 }}
- xxl={{ span: 4, offset: 5 }}
- >
- <Card
- hoverable
- title={renderCarouselCardName()}
- >
- <div className={styles.carousel}>
- <Carousel autoplay>
- {
- imgList.map(
- path => (
- <img key={path} src={genAbsolutePicUrl(path)} alt="" />
- )
- )
- }
- </Carousel>
- </div>
- {!carouselSelectorDestroy && getResourceModal(false)}
- </Card>
- </Col>
- </Row>
- </Card>
- {/* 相关周边配套选择Card */}
- <Card title={renderSupportCardName()} style={{ marginBottom: 70 }}>
- <AXDragSortTable
- columns={supportColumns}
- data={supportList}
- onChange={rows => this.handleDragSortTableChange('support', rows)}
- />
- {!supportSelectorDestroy && getSupportModal()}
- </Card>
- <FooterToolbar style={{ width: '100%' }}>
- <Button
- onClick={this.handlePageBack}
- style={{ marginRight: 10 }}
- >取消
- </Button>
- <Button
- type="primary"
- loading={submitting}
- onClick={this.handlePageSubmit}
- >提交
- </Button>
- </FooterToolbar>
- </div>
- );
- }
- }
|