|
@@ -0,0 +1,717 @@
|
|
|
+import React from 'react';
|
|
|
+import { Link } from 'react-router-dom';
|
|
|
+import moment from 'moment';
|
|
|
+import { Form, Input, Button, Row, Col, InputNumber, Upload, DatePicker, Card, Icon } from 'antd';
|
|
|
+import './index.less';
|
|
|
+import Editor from '@src/components/Editor';
|
|
|
+import Page from '@src/containers/Page';
|
|
|
+import Block from '@src/components/Block';
|
|
|
+import TreeSelect from '@src/components/TreeSelect';
|
|
|
+import EditTableCell from '@src/components/EditTableCell';
|
|
|
+import Radio from '@src/components/Radio';
|
|
|
+import ActionLayout from '@src/layouts/ActionLayout';
|
|
|
+import TableLayout from '@src/layouts/TableLayout';
|
|
|
+
|
|
|
+import { formatFormError, formatSeconds, formatTreeData, getMap } from '@src/services/Tools';
|
|
|
+import { asyncSMessage } from '@src/services/AsyncTools';
|
|
|
+import { CrowdList, CourseStatus } from '../../../../Constant';
|
|
|
+import { Course } from '../../../stores/course';
|
|
|
+import { System } from '../../../stores/system';
|
|
|
+import { Exercise } from '../../../stores/exercise';
|
|
|
+
|
|
|
+const CourseStatusMap = getMap(CourseStatus, 'value', 'label');
|
|
|
+
|
|
|
+export default class extends Page {
|
|
|
+ init() {
|
|
|
+ this.exerciseMap = {};
|
|
|
+ this.actionList = [{
|
|
|
+ key: 'add',
|
|
|
+ type: 'primary',
|
|
|
+ name: '上传视频',
|
|
|
+ render: (item) => {
|
|
|
+ return <Upload
|
|
|
+ showUploadList={false}
|
|
|
+ beforeUpload={(file) => System.uploadVideo(file).then((result) => {
|
|
|
+ return Course.addNo({ courseId: this.params.id, resource: result.url, time: result.time });
|
|
|
+ }).then(() => {
|
|
|
+ this.refreshNo();
|
|
|
+ })}
|
|
|
+ >
|
|
|
+ <Button>{item.name}</Button>
|
|
|
+ </Upload>;
|
|
|
+ },
|
|
|
+ }];
|
|
|
+
|
|
|
+ this.noColumns = [{
|
|
|
+ title: '课程序号',
|
|
|
+ dataIndex: 'no',
|
|
|
+ }, {
|
|
|
+ title: '名称',
|
|
|
+ dataIndex: 'title',
|
|
|
+ render: (text, record) => {
|
|
|
+ return <EditTableCell value={text} onChange={(v) => {
|
|
|
+ this.changeNo('title', record.id, v);
|
|
|
+ }} />;
|
|
|
+ },
|
|
|
+ }, {
|
|
|
+ title: '时长',
|
|
|
+ dataIndex: 'time',
|
|
|
+ render: (text) => {
|
|
|
+ return formatSeconds(text);
|
|
|
+ },
|
|
|
+ }, {
|
|
|
+ title: '视频地址',
|
|
|
+ dataIndex: 'resource',
|
|
|
+ render: (text) => {
|
|
|
+ return <a href={text} target='_blank'>访问</a>;
|
|
|
+ },
|
|
|
+ }, {
|
|
|
+ title: '试用区间',
|
|
|
+ dataIndex: 'originContent',
|
|
|
+ render: (text, record) => {
|
|
|
+ return <EditTableCell value={text} onChange={(v) => {
|
|
|
+ this.changeNo('originContent', record.id, v);
|
|
|
+ }} />;
|
|
|
+ },
|
|
|
+ }, {
|
|
|
+ title: '操作',
|
|
|
+ dataIndex: 'handler',
|
|
|
+ render: (text, record) => {
|
|
|
+ const { total } = this.state;
|
|
|
+ return <div className="table-button">
|
|
|
+ {record.no > 1 && (
|
|
|
+ <a onClick={() => {
|
|
|
+ this.changeNo('no', record.id, record.no - 1);
|
|
|
+ }}>上移</a>
|
|
|
+ )}
|
|
|
+ {record.no <= total && (
|
|
|
+ <a onClick={() => {
|
|
|
+ this.changeNo('no', record.id, record.no + 1);
|
|
|
+ }}>下移</a>
|
|
|
+ )}
|
|
|
+ {(
|
|
|
+ <a onClick={() => {
|
|
|
+ this.delNo(record.id);
|
|
|
+ }}>删除</a>
|
|
|
+ )}
|
|
|
+ </div>;
|
|
|
+ },
|
|
|
+ }];
|
|
|
+
|
|
|
+ this.timeColumns = [{
|
|
|
+ title: '时间段',
|
|
|
+ dataIndex: 'time',
|
|
|
+ render: (text, record) => {
|
|
|
+ return <DatePicker.RangePicker value={[record.startTime, record.endTime]} onChange={(value) => {
|
|
|
+ this.changeTime(record.id, { startTime: value[0], endTime: value[1] });
|
|
|
+ }} />;
|
|
|
+ },
|
|
|
+ }, {
|
|
|
+ title: '学员数量',
|
|
|
+ dataIndex: 'studentNumber',
|
|
|
+ render: (text, record) => {
|
|
|
+ return <Link to={`/course/student/${this.params.id}?timeId=${record.id}`}>{text}</Link>;
|
|
|
+ },
|
|
|
+ }, {
|
|
|
+ title: '状态',
|
|
|
+ dataIndex: 'status',
|
|
|
+ render: (text) => {
|
|
|
+ return CourseStatusMap[text] || text;
|
|
|
+ },
|
|
|
+ }];
|
|
|
+
|
|
|
+ Exercise.courseStruct().then((result) => {
|
|
|
+ const list = result.map(row => { row.title = `${row.titleZh}/${row.titleEn}`; row.value = row.id; return row; });
|
|
|
+ const tree = formatTreeData(list, 'id', 'title', 'parentId');
|
|
|
+ this.exerciseMap = getMap(result.map(row => {
|
|
|
+ row.title = `${row.titleZh}/${row.titleEn}`;
|
|
|
+ row.value = row.id;
|
|
|
+ return row;
|
|
|
+ }), 'id');
|
|
|
+
|
|
|
+ this.setState({ exercise: tree });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ initData() {
|
|
|
+ const { id } = this.params;
|
|
|
+ const { module } = this.state.search;
|
|
|
+ let handler;
|
|
|
+ if (id) {
|
|
|
+ handler = Course.get({ id });
|
|
|
+ } else {
|
|
|
+ handler = Promise.resolve({ structId: 0, courseModule: module });
|
|
|
+ }
|
|
|
+
|
|
|
+ handler
|
|
|
+ .then(result => {
|
|
|
+ this.setState({ module: result.courseModule });
|
|
|
+ const { form } = this.props;
|
|
|
+ result.structId = `${result.structId}`;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ form.setFieldsValue(result);
|
|
|
+ if (id) {
|
|
|
+ switch (result.courseModule) {
|
|
|
+ case 'video':
|
|
|
+ this.refreshNo();
|
|
|
+ break;
|
|
|
+ case 'online':
|
|
|
+ this.refreshTime();
|
|
|
+ break;
|
|
|
+ case 'vs':
|
|
|
+ this.refreshTeacher();
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.setState({ data: result });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ refreshNo() {
|
|
|
+ const { id } = this.params;
|
|
|
+ Course.allNo({ courseId: id }).then(result => {
|
|
|
+ this.setState({ list: result, total: result.length, no: true });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ changeNo(field, id, value) {
|
|
|
+ Course.editNo({ id, [field]: value }).then(() => {
|
|
|
+ this.refreshNo();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ delNo(id) {
|
|
|
+ Course.delNo({ id }).then(() => {
|
|
|
+ this.refreshNo();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ refreshTime() {
|
|
|
+ const { id } = this.params;
|
|
|
+ Course.listTime({ courseId: id }).then(result => {
|
|
|
+ result.list = result.list.map(row => {
|
|
|
+ row.startTime = moment(row.startTime);
|
|
|
+ row.endTime = moment(row.endTime);
|
|
|
+ return row;
|
|
|
+ });
|
|
|
+ this.setState({ list: result.list, total: result.total, time: true });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ changeTime(id, data) {
|
|
|
+ data.id = id;
|
|
|
+ Course.editTime(data).then(() => {
|
|
|
+ this.refreshTime();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ refreshTeacher() {
|
|
|
+ const { id } = this.params;
|
|
|
+ Course.listTeacher({ courseId: id }).then(result => {
|
|
|
+ this.setState({ teachers: result.list, total: result.total, teacher: true });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ changeTeacher(field, index, value) {
|
|
|
+ const { teachers } = this.state;
|
|
|
+ teachers[index] = teachers[index] || {};
|
|
|
+ teachers[index][field] = value;
|
|
|
+ this.setState({ teachers });
|
|
|
+ }
|
|
|
+
|
|
|
+ addLength(key, data) {
|
|
|
+ this.state[key] = this.state[key] || [];
|
|
|
+ this.state[key].push(data);
|
|
|
+ this.setState({ [key]: this.state[key] });
|
|
|
+ }
|
|
|
+
|
|
|
+ deleteLength(key, start) {
|
|
|
+ this.state[key] = this.state[key] || [];
|
|
|
+ this.state[key].splice(start, 1);
|
|
|
+ this.setState({ [key]: this.state[key] });
|
|
|
+ }
|
|
|
+
|
|
|
+ submit() {
|
|
|
+ const { form } = this.props;
|
|
|
+ const { module } = this.state;
|
|
|
+ form.validateFields((err) => {
|
|
|
+ if (!err) {
|
|
|
+ const data = form.getFieldsValue();
|
|
|
+ data.parentStructId = this.exerciseMap[data.structId] ? this.exerciseMap[data.structId].parentId : 0;
|
|
|
+ data.extend = this.exerciseMap[data.structId] ? this.exerciseMap[data.structId].extend : '';
|
|
|
+ let handler;
|
|
|
+ if (data.id) {
|
|
|
+ handler = Course.edit(data);
|
|
|
+ } else {
|
|
|
+ data.courseModule = module;
|
|
|
+ handler = Course.add(data);
|
|
|
+ }
|
|
|
+ handler.then((result) => {
|
|
|
+ asyncSMessage('保存成功');
|
|
|
+ if (data.id) {
|
|
|
+ linkTo(`/course/detail/${data.id}`);
|
|
|
+ } else {
|
|
|
+ linkTo(`/course/detail/${result.id}`);
|
|
|
+ }
|
|
|
+ }).catch((e) => {
|
|
|
+ if (e.result) form.setFields(formatFormError(data, e.result));
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ renderVideo() {
|
|
|
+ const { exercise, data } = this.state;
|
|
|
+ const { getFieldDecorator } = this.props.form;
|
|
|
+ return <Block>
|
|
|
+ <Form>
|
|
|
+ {getFieldDecorator('id')(<input hidden />)}
|
|
|
+ {exercise && data.structId && <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='学科'>
|
|
|
+ {getFieldDecorator('structId', {
|
|
|
+ rules: [{
|
|
|
+ required: true, message: '请选择学科',
|
|
|
+ }],
|
|
|
+ initialValue: data.structId,
|
|
|
+ })(
|
|
|
+ <TreeSelect treeData={exercise} />,
|
|
|
+ )}
|
|
|
+ </Form.Item>}
|
|
|
+ <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='适合人群'>
|
|
|
+ {getFieldDecorator('crowd', {
|
|
|
+ rules: [
|
|
|
+ { required: true, message: '请选择' },
|
|
|
+ ],
|
|
|
+ })(
|
|
|
+ <Radio select={CrowdList} />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='定价'>
|
|
|
+ {getFieldDecorator('price', {
|
|
|
+ rules: [
|
|
|
+ { required: true, message: '请输入价格' },
|
|
|
+ ],
|
|
|
+ })(
|
|
|
+ <InputNumber placeholder='请输入' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='课程名称'>
|
|
|
+ {getFieldDecorator('title', {
|
|
|
+ rules: [
|
|
|
+ { required: true, message: '请输入课程名称' },
|
|
|
+ ],
|
|
|
+ })(
|
|
|
+ <Input placeholder='请输入课程名称' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='教师'>
|
|
|
+ {getFieldDecorator('teacher', {
|
|
|
+ rules: [
|
|
|
+ { required: true, message: '请输入教师' },
|
|
|
+ ],
|
|
|
+ })(
|
|
|
+ <Input placeholder='请输入教师' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ </Form>
|
|
|
+ </Block>;
|
|
|
+ }
|
|
|
+
|
|
|
+ renderNo() {
|
|
|
+ const { no } = this.state;
|
|
|
+ if (!no) return null;
|
|
|
+ return <Block>
|
|
|
+ <h1>上传正式视频</h1>
|
|
|
+ <ActionLayout
|
|
|
+ itemList={this.actionList}
|
|
|
+ selectedKeys={this.state.selectedKeys}
|
|
|
+ onAction={key => this.onAction(key)}
|
|
|
+ />
|
|
|
+ <TableLayout
|
|
|
+ columns={this.noColumns}
|
|
|
+ list={this.state.list}
|
|
|
+ pagination={false}
|
|
|
+ loading={this.props.core.loading}
|
|
|
+ onChange={(pagination, filters, sorter) => this.tableChange(pagination, filters, sorter)}
|
|
|
+ onSelect={(keys, rows) => this.tableSelect(keys, rows)}
|
|
|
+ selectedKeys={this.state.selectedKeys}
|
|
|
+ />
|
|
|
+ </Block>;
|
|
|
+ }
|
|
|
+
|
|
|
+ renderInfoVideo() {
|
|
|
+ const { getFieldDecorator } = this.props.form;
|
|
|
+ return <Block flex>
|
|
|
+ <h1>课程介绍</h1>
|
|
|
+ <Form>
|
|
|
+ <Form.Item label='老师资历'>
|
|
|
+ {getFieldDecorator('teacherContent', {
|
|
|
+ })(
|
|
|
+ <Editor placeholder='输入内容' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item label='基本参数'>
|
|
|
+ {getFieldDecorator('baseContent', {
|
|
|
+ })(
|
|
|
+ <Editor placeholder='输入内容' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item label='授课内容'>
|
|
|
+ {getFieldDecorator('courseContent', {
|
|
|
+ })(
|
|
|
+ <Editor placeholder='输入内容' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item label='授课重点'>
|
|
|
+ {getFieldDecorator('pointContent', {
|
|
|
+ })(
|
|
|
+ <Editor placeholder='输入内容' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item label='适合人群'>
|
|
|
+ {getFieldDecorator('crowdContent', {
|
|
|
+ })(
|
|
|
+ <Editor placeholder='输入内容' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ </Form>
|
|
|
+ </Block>;
|
|
|
+ }
|
|
|
+
|
|
|
+ renderSyllabus() {
|
|
|
+ const { getFieldDecorator } = this.props.form;
|
|
|
+ return <Block flex>
|
|
|
+ <Form>
|
|
|
+ <Form.Item label='授课大纲'>
|
|
|
+ {getFieldDecorator('syllabusContent', {
|
|
|
+ })(
|
|
|
+ <Editor placeholder='输入内容' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ </Form>
|
|
|
+ </Block>;
|
|
|
+ }
|
|
|
+
|
|
|
+ renderPromote() {
|
|
|
+ const { getFieldDecorator } = this.props.form;
|
|
|
+ return <Block flex>
|
|
|
+ <Form>
|
|
|
+ <Form.Item label='优惠信息'>
|
|
|
+ {getFieldDecorator('promoteContent', {
|
|
|
+ })(
|
|
|
+ <Editor placeholder='输入内容' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ </Form>
|
|
|
+ </Block>;
|
|
|
+ }
|
|
|
+
|
|
|
+ renderOnline() {
|
|
|
+ const { exercise, data } = this.state;
|
|
|
+ const { getFieldDecorator } = this.props.form;
|
|
|
+ return <Block>
|
|
|
+ <Form>
|
|
|
+ {getFieldDecorator('id')(<input hidden />)}
|
|
|
+ {exercise && data.structId && <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='学科'>
|
|
|
+ {getFieldDecorator('structId', {
|
|
|
+ rules: [{
|
|
|
+ required: true, message: '请选择学科',
|
|
|
+ }],
|
|
|
+ initialValue: data.structId,
|
|
|
+ })(
|
|
|
+ <TreeSelect treeData={exercise} />,
|
|
|
+ )}
|
|
|
+ </Form.Item>}
|
|
|
+ <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='课程名称'>
|
|
|
+ {getFieldDecorator('title', {
|
|
|
+ rules: [
|
|
|
+ { required: true, message: '请输入课程名称' },
|
|
|
+ ],
|
|
|
+ })(
|
|
|
+ <Input placeholder='请输入课程名称' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ </Form>
|
|
|
+ </Block>;
|
|
|
+ }
|
|
|
+
|
|
|
+ renderTime() {
|
|
|
+ const { time, timerange } = this.state;
|
|
|
+ if (!time) return null;
|
|
|
+ return <Block>
|
|
|
+ <h1>课时管理</h1>
|
|
|
+ <TableLayout
|
|
|
+ columns={this.timeColumns}
|
|
|
+ list={this.state.list}
|
|
|
+ pagination={false}
|
|
|
+ loading={this.props.core.loading}
|
|
|
+ onChange={(pagination, filters, sorter) => this.tableChange(pagination, filters, sorter)}
|
|
|
+ onSelect={(keys, rows) => this.tableSelect(keys, rows)}
|
|
|
+ selectedKeys={this.state.selectedKeys}
|
|
|
+ />
|
|
|
+ <Row>
|
|
|
+ <Col span={8}>
|
|
|
+ <Form.Item>
|
|
|
+ <DatePicker.RangePicker value={timerange} onChange={(value) => {
|
|
|
+ this.setState({ timerange: value });
|
|
|
+ }} />
|
|
|
+ </Form.Item>
|
|
|
+ </Col>
|
|
|
+ <Col span={1}>
|
|
|
+ <Form.Item>
|
|
|
+ <Button onClick={() => {
|
|
|
+ Course.addTime({ courseId: this.params.id, startTime: timerange[0], endTime: timerange[1] }).then(() => {
|
|
|
+ this.refreshTime();
|
|
|
+ this.setState({ timerange: null });
|
|
|
+ });
|
|
|
+ }}>添加</Button>
|
|
|
+ </Form.Item>
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+ </Block>;
|
|
|
+ }
|
|
|
+
|
|
|
+ renderVs() {
|
|
|
+ const { exercise, data } = this.state;
|
|
|
+ const { getFieldDecorator } = this.props.form;
|
|
|
+ return <Block>
|
|
|
+ <Form>
|
|
|
+ {getFieldDecorator('id')(<input hidden />)}
|
|
|
+ {exercise && data.structId && <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='学科'>
|
|
|
+ {getFieldDecorator('structId', {
|
|
|
+ rules: [{
|
|
|
+ required: true, message: '请选择学科',
|
|
|
+ }],
|
|
|
+ initialValue: data.structId,
|
|
|
+ })(
|
|
|
+ <TreeSelect treeData={exercise} />,
|
|
|
+ )}
|
|
|
+ </Form.Item>}
|
|
|
+ <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='课程名称'>
|
|
|
+ {getFieldDecorator('title', {
|
|
|
+ rules: [
|
|
|
+ { required: true, message: '请输入课程名称' },
|
|
|
+ ],
|
|
|
+ })(
|
|
|
+ <Input placeholder='请输入课程名称' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+
|
|
|
+ <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='定价'>
|
|
|
+ {getFieldDecorator('price', {
|
|
|
+ rules: [
|
|
|
+ { required: true, message: '请输入价格' },
|
|
|
+ ],
|
|
|
+ })(
|
|
|
+ <InputNumber placeholder='请输入' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='最小购买数量'>
|
|
|
+ {getFieldDecorator('minNumber', {
|
|
|
+ rules: [
|
|
|
+ { required: true, message: '请输入最小购买数量' },
|
|
|
+ ],
|
|
|
+ })(
|
|
|
+ <InputNumber placeholder='请输入' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='最大购买数量'>
|
|
|
+ {getFieldDecorator('maxNumber', {
|
|
|
+ rules: [
|
|
|
+ { required: true, message: '请输入最大购买数量' },
|
|
|
+ ],
|
|
|
+ })(
|
|
|
+ <InputNumber placeholder='请输入' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='有效期'>
|
|
|
+ {getFieldDecorator('expireDays', {
|
|
|
+ rules: [
|
|
|
+ { required: true, message: '请输入有效期' },
|
|
|
+ ],
|
|
|
+ })(
|
|
|
+ <InputNumber placeholder='天/10课时' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ </Form>
|
|
|
+ </Block>;
|
|
|
+ }
|
|
|
+
|
|
|
+ renderInfoVs() {
|
|
|
+ const { getFieldDecorator, setFieldsValue, getFieldValue } = this.props.form;
|
|
|
+ const image = getFieldValue('wechatAvatar') || null;
|
|
|
+ return <Block flex>
|
|
|
+ <h1>课程介绍</h1>
|
|
|
+ <Form>
|
|
|
+ <Form.Item label='服务介绍'>
|
|
|
+ {getFieldDecorator('serviceContent', {
|
|
|
+ })(
|
|
|
+ <Editor placeholder='输入内容' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item label='适合人群'>
|
|
|
+ {getFieldDecorator('crowdContent', {
|
|
|
+ })(
|
|
|
+ <Editor placeholder='输入内容' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item label='课时数'>
|
|
|
+ {getFieldDecorator('courseNoContent', {
|
|
|
+ })(
|
|
|
+ <Editor placeholder='输入内容' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item label='授课流程'>
|
|
|
+ {getFieldDecorator('processContent', {
|
|
|
+ })(
|
|
|
+ <Editor placeholder='输入内容' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item label='推广语'>
|
|
|
+ {getFieldDecorator('messageContent', {
|
|
|
+ })(
|
|
|
+ <Editor placeholder='输入内容' />,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item labelCol={{ span: 7 }} wrapperCol={{ span: 15 }} label='微信头像'>
|
|
|
+ {getFieldDecorator('wechatAvatar', {
|
|
|
+ rules: [
|
|
|
+ { required: true, message: '上传图片' },
|
|
|
+ ],
|
|
|
+ })(
|
|
|
+ <Upload
|
|
|
+ listType="picture-card"
|
|
|
+ showUploadList={false}
|
|
|
+ beforeUpload={(file) => System.uploadImage(file).then((result) => {
|
|
|
+ setFieldsValue({ wechatAvatar: result.url });
|
|
|
+ return Promise.reject();
|
|
|
+ })}
|
|
|
+ >
|
|
|
+ {image ? <img src={image} alt="avatar" /> : <div>
|
|
|
+ <Icon type={this.state.loading ? 'loading' : 'plus'} />
|
|
|
+ <div className="ant-upload-text">Upload</div>
|
|
|
+ </div>}
|
|
|
+ </Upload>,
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ </Form>
|
|
|
+ </Block>;
|
|
|
+ }
|
|
|
+
|
|
|
+ renderTeacher() {
|
|
|
+ const { teachers, teacher } = this.state;
|
|
|
+ if (!teacher) return null;
|
|
|
+ return <Block>
|
|
|
+ <h1>授课老师</h1>
|
|
|
+ <Form>
|
|
|
+ <Row>
|
|
|
+ {teachers.map((row, index) => {
|
|
|
+ return <Col span={7} offset={index % 3 ? 1 : 0}><Card>
|
|
|
+ <Button className="delete-button" size="small" onClick={() => {
|
|
|
+ if (row.id) {
|
|
|
+ Course.delTeacher(row.id).then(() => {
|
|
|
+ this.deleteLength('teachers', index);
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.deleteLength('teachers', index);
|
|
|
+ }
|
|
|
+ }}>
|
|
|
+ <Icon type="delete" />
|
|
|
+ </Button>
|
|
|
+ <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label='姓名'>
|
|
|
+ <Input placeholder='请输入姓名' value={row.realname} onChange={(e) => {
|
|
|
+ this.changeTeacher('realname', index, e.target.value);
|
|
|
+ }} />
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label='微信'>
|
|
|
+ <Input placeholder='请输入微信' value={row.wechat} onChange={(e) => {
|
|
|
+ this.changeTeacher('wechat', index, e.target.value);
|
|
|
+ }} />
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label='二维码'>
|
|
|
+ <Upload
|
|
|
+ listType="picture-card"
|
|
|
+ showUploadList={false}
|
|
|
+ beforeUpload={(file) => System.uploadImage(file).then((result) => {
|
|
|
+ this.changeTeacher('qr', index, result.url);
|
|
|
+ return Promise.reject();
|
|
|
+ })}
|
|
|
+ >
|
|
|
+ {row.qr ? <img src={row.qr} alt="avatar" /> : <div>
|
|
|
+ <Icon type={this.state.loading ? 'loading' : 'plus'} />
|
|
|
+ <div className="ant-upload-text">Upload</div>
|
|
|
+ </div>}
|
|
|
+ </Upload>
|
|
|
+ </Form.Item>
|
|
|
+ <Button onClick={() => {
|
|
|
+ let handler = null;
|
|
|
+ if (row.id) {
|
|
|
+ handler = Course.editTeacher(row);
|
|
|
+ } else {
|
|
|
+ handler = Course.addTeacher(Object.assign({ courseId: this.params.id }, row));
|
|
|
+ }
|
|
|
+ handler.then(() => {
|
|
|
+ this.refreshTeacher();
|
|
|
+ });
|
|
|
+ }}>{row.id ? '修改' : '添加'}</Button>
|
|
|
+ </Card></Col>;
|
|
|
+ })}
|
|
|
+ <Col span={7} offset={teachers.length % 3 ? 1 : 0}>
|
|
|
+ <Card className="plus" onClick={() => {
|
|
|
+ this.addLength('teachers', { realname: '', wechat: '', qr: '' });
|
|
|
+ }}>
|
|
|
+ <Icon type={'plus'} />
|
|
|
+ </Card>
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+ </Form>
|
|
|
+ </Block>;
|
|
|
+ }
|
|
|
+
|
|
|
+ renderContent() {
|
|
|
+ switch (this.state.module) {
|
|
|
+ case 'online':
|
|
|
+ return [this.renderOnline(), this.renderTime()];
|
|
|
+ case 'vs':
|
|
|
+ return [this.renderVs(), this.renderInfoVs(), this.renderTeacher()];
|
|
|
+ case 'video':
|
|
|
+ return [this.renderVideo(), this.renderNo(), this.renderInfoVideo(), this.renderSyllabus(), this.renderPromote()];
|
|
|
+ default:
|
|
|
+ return <div />;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ renderView() {
|
|
|
+ return <div flex>
|
|
|
+ {this.renderContent()}
|
|
|
+ <Row type="flex" justify="center">
|
|
|
+ <Col>
|
|
|
+ <Button type="primary" onClick={() => {
|
|
|
+ this.submit();
|
|
|
+ }}>保存</Button>
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+ </div>;
|
|
|
+ }
|
|
|
+}
|