|
@@ -0,0 +1,374 @@
|
|
|
|
+import React, { PureComponent } from 'react';
|
|
|
|
+import moment from 'moment';
|
|
|
|
+import { routerRedux } from 'dva/router';
|
|
|
|
+import queryString from 'query-string';
|
|
|
|
+import { connect } from 'dva';
|
|
|
|
+import { Spin, Popover, Badge, Table, Radio, Card, Form, Input, Icon, Button, Select, DatePicker } from 'antd';
|
|
|
|
+import PageHeaderLayout from '../../../layouts/PageHeaderLayout';
|
|
|
|
+import ResourceSelectModal from './resource';
|
|
|
|
+import { Codes, ossHost } from '../../../utils/config';
|
|
|
|
+
|
|
|
|
+@Form.create()
|
|
|
|
+@connect(state => ({
|
|
|
|
+ merchant: state.merchant,
|
|
|
|
+ resource: state.resource,
|
|
|
|
+ trainingDetail: state.trainingDetail,
|
|
|
|
+}))
|
|
|
|
+export default class TrainingDetail extends PureComponent {
|
|
|
|
+ state = { curClickedBtn: null };
|
|
|
|
+
|
|
|
|
+ componentDidMount() {
|
|
|
|
+ const { dispatch } = this.props;
|
|
|
|
+ dispatch({
|
|
|
|
+ type: 'merchant/query',
|
|
|
|
+ payload: {
|
|
|
|
+ pageSize: 1000,
|
|
|
|
+ pageNo: 1,
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 展示选择模态框 - 加载第一页数据
|
|
|
|
+ handleModalShow = (btnName) => {
|
|
|
|
+ this.setState({
|
|
|
|
+ curClickedBtn: btnName,
|
|
|
|
+ }, () => {
|
|
|
|
+ const { dispatch } = this.props;
|
|
|
|
+ if (btnName == 'imgBtn' || btnName == 'cvImgBtn') {
|
|
|
|
+ dispatch({ type: 'trainingDetail/showResourceModal' });
|
|
|
|
+ dispatch({
|
|
|
|
+ type: 'resource/query',
|
|
|
|
+ payload: {
|
|
|
|
+ pageNo: 1,
|
|
|
|
+ pageSize: 10,
|
|
|
|
+ type: Codes.CODE_IMAGE,
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 取消/关闭 - 隐藏选择模态框
|
|
|
|
+ handleModalCancel = () => {
|
|
|
|
+ const { curClickedBtn } = this.state;
|
|
|
|
+ const { dispatch } = this.props;
|
|
|
|
+ if (curClickedBtn == 'imgBtn' || curClickedBtn == 'cvImgBtn') {
|
|
|
|
+ dispatch({ type: 'trainingDetail/hideResourceModal' });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 提交 - 保存选择和排序完的数据到model中
|
|
|
|
+ handleModalOk = (data) => {
|
|
|
|
+ const { curClickedBtn } = this.state;
|
|
|
|
+ const { dispatch } = this.props;
|
|
|
|
+ if (curClickedBtn == 'imgBtn') {
|
|
|
|
+ dispatch({
|
|
|
|
+ type: 'trainingDetail/saveImgList',
|
|
|
|
+ payload: { imgList: data.map(item => item.path) },
|
|
|
|
+ });
|
|
|
|
+ } else if (curClickedBtn == 'cvImgBtn') {
|
|
|
|
+ dispatch({
|
|
|
|
+ type: 'trainingDetail/saveCoverImg',
|
|
|
|
+ payload: { coverUrl: data.path },
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 搜索
|
|
|
|
+ handleModalSearch = (data) => {
|
|
|
|
+ const { curClickedBtn } = this.state;
|
|
|
|
+ const { dispatch } = this.props;
|
|
|
|
+ const newData = { ...data };
|
|
|
|
+ if (newData.keyword) {
|
|
|
|
+ newData[newData.field] = newData.keyword;
|
|
|
|
+ }
|
|
|
|
+ delete newData.field;
|
|
|
|
+ delete newData.keyword;
|
|
|
|
+
|
|
|
|
+ if (curClickedBtn == 'imgBtn' || curClickedBtn == 'cvImgBtn') {
|
|
|
|
+ dispatch({
|
|
|
|
+ type: 'resource/query',
|
|
|
|
+ payload: { ...newData, pageNo: 1, pageSize: 10, type: Codes.CODE_IMAGE },
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 翻页 - 资源列表
|
|
|
|
+ handleModalTableChange = (pagination, filterArgs, filters) => {
|
|
|
|
+ const { curClickedBtn } = this.state;
|
|
|
|
+ const { dispatch } = this.props;
|
|
|
|
+ const newFilters = { ...filters };
|
|
|
|
+ if (newFilters.keyword) {
|
|
|
|
+ newFilters[newFilters.field] = newFilters.keyword;
|
|
|
|
+ delete newFilters.field;
|
|
|
|
+ delete newFilters.keyword;
|
|
|
|
+ } else {
|
|
|
|
+ delete newFilters.field;
|
|
|
|
+ delete newFilters.keyword;
|
|
|
|
+ }
|
|
|
|
+ const getValue = obj => Object.keys(obj).map(key => obj[key]).join(',');
|
|
|
|
+ const tableFilters = Object.keys(filterArgs).reduce((obj, key) => {
|
|
|
|
+ const newObj = { ...obj };
|
|
|
|
+ newObj[key] = getValue(filterArgs[key]);
|
|
|
|
+ return newObj;
|
|
|
|
+ }, {});
|
|
|
|
+
|
|
|
|
+ const data = { ...newFilters, ...tableFilters, pageNo: pagination.current, pageSize: pagination.pageSize };
|
|
|
|
+ Object.keys(data).map(key => data[key] ? null : delete data[key]);
|
|
|
|
+
|
|
|
|
+ if (curClickedBtn == 'imgBtn' || curClickedBtn == 'cvImgBtn') {
|
|
|
|
+ dispatch({ type: `resource/query`, payload: { ...data, status: Codes.CODE_NORMAL, type: Codes.CODE_IMAGE } });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ handlePageSubmit = (e) => {
|
|
|
|
+ e.preventDefault()
|
|
|
|
+ const {
|
|
|
|
+ dispatch,
|
|
|
|
+ form: {
|
|
|
|
+ validateFields,
|
|
|
|
+ getFieldsValue,
|
|
|
|
+ resetFields
|
|
|
|
+ },
|
|
|
|
+ trainingDetail: {
|
|
|
|
+ operType,
|
|
|
|
+ currentItem,
|
|
|
|
+ filters,
|
|
|
|
+ }
|
|
|
|
+ } = this.props;
|
|
|
|
+ validateFields((errors) => {
|
|
|
|
+ if (errors) { return; }
|
|
|
|
+
|
|
|
|
+ // 过滤掉gmtCreated, gmtModified, status三个字段
|
|
|
|
+ const { imgList, gmtCreated, gmtModified, ...restProps } = currentItem;
|
|
|
|
+ let newImgList;
|
|
|
|
+ if (Array.isArray(imgList) && imgList.length) {
|
|
|
|
+ newImgList = imgList;
|
|
|
|
+ } else {
|
|
|
|
+ newImgList = [];
|
|
|
|
+ }
|
|
|
|
+ const { title, openTime, closeTime } = getFieldsValue();
|
|
|
|
+ const openTimestamp = parseInt(moment(openTime).format('x'));
|
|
|
|
+ const closeTimestamp = parseInt(moment(closeTime).format('x'));
|
|
|
|
+
|
|
|
|
+ const data = {
|
|
|
|
+ ...getFieldsValue(),
|
|
|
|
+ name: title,
|
|
|
|
+ imgList: newImgList,
|
|
|
|
+ openTime: openTimestamp,
|
|
|
|
+ closeTime: closeTimestamp,
|
|
|
|
+ ...restProps,
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ // 其他参数
|
|
|
|
+ if (operType == 'create') {
|
|
|
|
+ data.type = Codes.CODE_TRAINING;
|
|
|
|
+ data.status = Codes.CODE_NORMAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ dispatch({
|
|
|
|
+ type: `trainingDetail/${operType}`,
|
|
|
|
+ payload: data,
|
|
|
|
+ callback: () => {
|
|
|
|
+ dispatch(
|
|
|
|
+ routerRedux.push({
|
|
|
|
+ pathname: '/product/training',
|
|
|
|
+ search: queryString.stringify(filters),
|
|
|
|
+ })
|
|
|
|
+ );
|
|
|
|
+ resetFields();
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ handlePageCancel = () => {
|
|
|
|
+ const { dispatch, trainingDetail: { filters } } = this.props;
|
|
|
|
+ dispatch({ type: 'trainingDetail/initState' });
|
|
|
|
+ dispatch(
|
|
|
|
+ routerRedux.push({
|
|
|
|
+ pathname: '/product/training',
|
|
|
|
+ search: queryString.stringify(filters),
|
|
|
|
+ })
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ render() {
|
|
|
|
+ const {
|
|
|
|
+ merchant,
|
|
|
|
+ resource,
|
|
|
|
+ training,
|
|
|
|
+ trainingDetail,
|
|
|
|
+ form: {
|
|
|
|
+ getFieldDecorator
|
|
|
|
+ },
|
|
|
|
+ } = this.props;
|
|
|
|
+ const {
|
|
|
|
+ itemLoading,
|
|
|
|
+ currentItem,
|
|
|
|
+ filters,
|
|
|
|
+ trainingModalVisible,
|
|
|
|
+ resourceModalVisible
|
|
|
|
+ } = trainingDetail;
|
|
|
|
+ const {
|
|
|
|
+ cpId,
|
|
|
|
+ title,
|
|
|
|
+ code,
|
|
|
|
+ name,
|
|
|
|
+ coverUrl,
|
|
|
|
+ imgList,
|
|
|
|
+ dateDesc,
|
|
|
|
+ openTime,
|
|
|
|
+ closeTime,
|
|
|
|
+ } = currentItem;
|
|
|
|
+ const { curClickedBtn } = this.state;
|
|
|
|
+
|
|
|
|
+ // 待选表格去掉分页的跳转及变换页码
|
|
|
|
+ if (resource && resource.pagination) {
|
|
|
|
+ delete resource.pagination.showQuickJumper;
|
|
|
|
+ delete resource.pagination.showSizeChanger;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const imgTableColumns = [{
|
|
|
|
+ title: '位置',
|
|
|
|
+ dataIndex: 'sort',
|
|
|
|
+ key: 'sort',
|
|
|
|
+ render: (text, record, index) => index + 1,
|
|
|
|
+ },{
|
|
|
|
+ title: '缩略图',
|
|
|
|
+ dataIndex: 'path',
|
|
|
|
+ key: 'path',
|
|
|
|
+ render: (text, record) => (
|
|
|
|
+ <Popover
|
|
|
|
+ content={<img alt="" src={`${ossHost}/${text}`} width={350} />}
|
|
|
|
+ title={record.name}
|
|
|
|
+ >
|
|
|
|
+ <img alt="" src={`${ossHost}/${text}`} width={70} />
|
|
|
|
+ </Popover>
|
|
|
|
+ ),
|
|
|
|
+ }];
|
|
|
|
+
|
|
|
|
+ const formItemLayout = {
|
|
|
|
+ labelCol: {
|
|
|
|
+ span: 7,
|
|
|
|
+ },
|
|
|
|
+ wrapperCol: {
|
|
|
|
+ span: 12,
|
|
|
|
+ },
|
|
|
|
+ };
|
|
|
|
+ const submitFormLayout = {
|
|
|
|
+ wrapperCol: {
|
|
|
|
+ xs: { span: 24, offset: 0 },
|
|
|
|
+ sm: { span: 10, offset: 7 },
|
|
|
|
+ },
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ return (
|
|
|
|
+ <PageHeaderLayout>
|
|
|
|
+ <Spin spinning={itemLoading}>
|
|
|
|
+ <Card title="师训信息">
|
|
|
|
+ <Form layout="horizontal" onSubmit={this.handlePageSubmit}>
|
|
|
|
+ <Form.Item label="师训编号" hasFeedback {...formItemLayout}>
|
|
|
|
+ {getFieldDecorator('code', {
|
|
|
|
+ rules: [{ required: true, type: 'string', message: "编号为必填项!" }],
|
|
|
|
+ initialValue: code,
|
|
|
|
+ })(<Input />)}
|
|
|
|
+ </Form.Item>
|
|
|
|
+ <Form.Item label="师训标题" hasFeedback {...formItemLayout}>
|
|
|
|
+ {getFieldDecorator('title', {
|
|
|
|
+ rules: [{ required: true, type: 'string', message: "标题为必填项!" }],
|
|
|
|
+ initialValue: title,
|
|
|
|
+ })(<Input />)}
|
|
|
|
+ </Form.Item>
|
|
|
|
+ <Form.Item label="活动时间" {...formItemLayout}>
|
|
|
|
+ {getFieldDecorator('dateDesc', {
|
|
|
|
+ rules: [{ required: true, type: 'string', message: "活动为必填项!" }],
|
|
|
|
+ initialValue: dateDesc,
|
|
|
|
+ })(<Input placeholder="请填写师训活动时间范围" />)}
|
|
|
|
+ </Form.Item>
|
|
|
|
+ <Form.Item label="起始日期" {...formItemLayout}>
|
|
|
|
+ {getFieldDecorator('openTime', {
|
|
|
|
+ rules: [{ required: true, message: '请选择起始日期' }],
|
|
|
|
+ initialValue: openTime && moment(openTime),
|
|
|
|
+ })(
|
|
|
|
+ <DatePicker
|
|
|
|
+ showTime
|
|
|
|
+ placeholder="选择日期时间"
|
|
|
|
+ format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
+ style={{ width: '100%' }}
|
|
|
|
+ />
|
|
|
|
+ )}
|
|
|
|
+ </Form.Item>
|
|
|
|
+ <Form.Item label="截止日期" {...formItemLayout}>
|
|
|
|
+ {getFieldDecorator('closeTime', {
|
|
|
|
+ rules: [{ required: true, message: '请选择截止日期' }],
|
|
|
|
+ initialValue: closeTime && moment(closeTime),
|
|
|
|
+ })(
|
|
|
|
+ <DatePicker
|
|
|
|
+ showTime
|
|
|
|
+ placeholder="选择日期时间"
|
|
|
|
+ format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
+ style={{ width: '100%' }}
|
|
|
|
+ />
|
|
|
|
+ )}
|
|
|
|
+ </Form.Item>
|
|
|
|
+ <Form.Item label="所属供应商:" {...formItemLayout}>
|
|
|
|
+ {getFieldDecorator('cpId', {
|
|
|
|
+ initialValue: cpId,
|
|
|
|
+ })(
|
|
|
|
+ <Select placeholder="请选择">{merchant.list.map(item => <Select.Option value={item.id} key={item.id}>{item.name}</Select.Option>)}</Select>
|
|
|
|
+ )}
|
|
|
|
+ </Form.Item>
|
|
|
|
+ <Form.Item label="封面图片" {...formItemLayout}>
|
|
|
|
+ <Button onClick={() => this.handleModalShow('cvImgBtn')} type="primary" icon="select" size="small">选择</Button>
|
|
|
|
+ {!coverUrl? null :
|
|
|
|
+ <Card
|
|
|
|
+ hoverable
|
|
|
|
+ bordered
|
|
|
|
+ cover={<img alt="" src={coverUrl.startsWith('http') ? coverUrl : `${ossHost}/${coverUrl}`} />}
|
|
|
|
+ style={{ width: 240, marginTop: 20 }}
|
|
|
|
+ >
|
|
|
|
+ </Card>}
|
|
|
|
+ </Form.Item>
|
|
|
|
+ <Form.Item label="图片列表" {...formItemLayout}>
|
|
|
|
+ <Button onClick={() => this.handleModalShow('imgBtn')} type="primary" size="small" icon="edit">编辑</Button>
|
|
|
|
+ </Form.Item>
|
|
|
|
+ <Form.Item wrapperCol={{ offset: 7, span: 12 }}>
|
|
|
|
+ <Table
|
|
|
|
+ locale={{
|
|
|
|
+ emptyText: <span style={{ color: "#C6D0D6" }}> <Icon type="frown-o"/>
|
|
|
|
+ 该师训下不包含任何图片,请选择!</span>
|
|
|
|
+ }}
|
|
|
|
+ dataSource={(imgList || []).map((item,index) => ({ id: index, path: item }))}
|
|
|
|
+ columns={imgTableColumns}
|
|
|
|
+ rowKey={record => record.id}
|
|
|
|
+ bordered
|
|
|
|
+ pagination={false}
|
|
|
|
+ />
|
|
|
|
+ </Form.Item>
|
|
|
|
+ <Form.Item {...submitFormLayout} style={{ marginTop: 32 }}>
|
|
|
|
+ <Button onClick={this.handlePageCancel}>取消</Button>
|
|
|
|
+ <Button type="primary" style={{ marginLeft: 35 }} htmlType="submit">提交</Button>
|
|
|
|
+ </Form.Item>
|
|
|
|
+ </Form>
|
|
|
|
+ {/*图片资源的模态选择框*/}
|
|
|
|
+ <ResourceSelectModal
|
|
|
|
+ mode={curClickedBtn == 'imgBtn' ? 'multiple' : 'single'}
|
|
|
|
+ rowKeyName="id"
|
|
|
|
+ modalVisible={resourceModalVisible}
|
|
|
|
+ width={600}
|
|
|
|
+ onOk={this.handleModalOk}
|
|
|
|
+ onCancel={this.handleModalCancel}
|
|
|
|
+ onSearch={this.handleModalSearch}
|
|
|
|
+ selTableData={[]}
|
|
|
|
+ fsTableDataSource={resource.list || []}
|
|
|
|
+ fsTableLoading={resource.listLoading}
|
|
|
|
+ fsTablePagination={resource.pagination}
|
|
|
|
+ fsTableOnChange={this.handleModalTableChange}
|
|
|
|
+ />
|
|
|
|
+ </Card>
|
|
|
|
+ </Spin>
|
|
|
|
+ </PageHeaderLayout>
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+}
|