Commit a9138e61 authored by baixian's avatar baixian

闯关优化

parent ead687d9
......@@ -18,5 +18,5 @@
</head>
<body>
<div id="root"></div>
<script type="text/javascript" src="/dist/main.43cf75.js"></script></body>
<script type="text/javascript" src="/dist/main.008db9.js"></script></body>
</html>
\ No newline at end of file
......@@ -180,6 +180,7 @@ export default {
unlockSubjectList: `${dakaapi}member/unlock_subject/index`,
edit_unlock_subject: `${dakaapi}member/unlock_subject/update`,
unlockSubjectDetail: `${dakaapi}member/unlock_subject/detail`,
unlockAddSubjectCount: `${dakaapi}member/unlock_subject/add_subject_count`,
},
getschooluuid: `${dakaapi}member/school_uuid`,
analyzeCenter: {
......
......@@ -1689,7 +1689,7 @@ export default {
const loadmessage = message.loading('小程序码生成中...', 0);
const data = yield call(commonAjax.generateQrcode, {
scene: `i=${record.class_id}&t=${record.id}`,
page: 'src/pages/morethemeindex/index',
page: 'src/pages/sharemoretheme/index',
width: 430,
});
if (data.code === 200) {
......@@ -1740,6 +1740,116 @@ export default {
pathname: `/sjd/addCustomsContent/${id}`,
}));
},
* addStoreCount({ payload }, { call, put, select }) {
const { id } = payload;
yield put(routerRedux.push({
pathname: `/sjd/addStoreCount/${id}`,
}));
},
// 额外关卡提交方法
* addSubjectCount({ payload }, { call, put, select }) {
const { sid } = yield select(state => state.webapp);
const {
emigrateLoading,
emigrateParams,
emigratedObj,
storeId,
} = yield select(state => state.createtheme);
if (emigrateLoading) {
return;
}
yield put({
type: 'updateState',
payload: {
emigrateLoading: true,
},
});
const newParams = { ...emigrateParams };
const {
is_cheat,
is_encrypt,
title,
text_require_status,
text_require_num,
image_require_status,
image_require_num,
video_require_status,
video_require_num,
audio_require_status,
audio_require_num,
force_status,
force_num,
callBack,
} = payload;
const loadmessage = message.loading('保存中...', 0);
const subjectCountData = yield call(themeAjax.unlockAddSubjectCount, {
id: emigratedObj.id,
school_id: sid,
});
if (subjectCountData.code == 200) {
const data = yield call(themeAjax.addTheme, Object.assign(newParams,
{
is_cheat,
is_encrypt,
title,
class_id: emigratedObj.class_id,
school_id: sid,
text_require_status,
text_require_num,
image_require_status,
image_require_num,
video_require_status,
video_require_num,
audio_require_status,
audio_require_num,
force_status,
force_num,
subject_type: 3,
unlock_mode_id: emigratedObj.id,
content: JSON.stringify(newParams.content),
sort: subjectCountData.data.subject_count,
},
));
yield put({
type: 'updateState',
payload: {
emigrateLoading: false,
},
});
setTimeout(loadmessage);
if (data.code === 200) {
if (callBack && (typeof callBack == 'function')) {
callBack();
}
yield put(routerRedux.goBack());
yield put({
type: 'updateState',
payload: {
isShowCustoms: false,
emigrateParams: {
title: '',
content: [],
},
},
});
message.success('保存成功', 0.5);
} else {
yield put({
type: 'webapp/errorrequestresolve',
payload: {
data,
},
});
}
} else {
yield put({
type: 'webapp/errorrequestresolve',
payload: {
data: subjectCountData.data,
},
});
}
},
* goEditShowCustoms({ payload }, { call, put, select }) {
const { item } = payload;
console.log(item);
......
......@@ -116,7 +116,7 @@ export default {
case 3:
params = {
scene: `i=${record.class_id}&t=${record.id}`,
page: 'src/pages/morethemeindex/index',
page: 'src/pages/sharemoretheme/index',
width: 430,
};
break;
......
......@@ -872,6 +872,39 @@ export default {
},
});
}
const addStoreCountActive = pathToRegexp('/sjd/addStoreCount/:id').exec(pathname);
if (addStoreCountActive) {
dispatch({
type: 'createtheme/pageInit',
payload: {
},
});
dispatch({
type: 'createtheme/createThemeModalfindEmigrated',
payload: {
store_id: addStoreCountActive[1],
},
});
dispatch({
type: 'updateState',
payload: {
breadcrumbList: [
{
path: 'sjd/classmgt',
name: '班级管理',
},
{
path: pathname,
name: '主题详情',
},
{
path: pathname,
name: '新建闯关打卡',
},
],
},
});
}
const editStoreActive = pathToRegexp('/sjd/editCustoms/:id').exec(pathname);
if (editStoreActive) {
dispatch({
......
import { connect } from 'dva';
import React from 'react';
import {
Form,
Icon,
Button,
Tabs,
Modal,
Row,
Col,
Divider,
Switch,
TimePicker,
Collapse,
DatePicker,
Select, Radio, InputNumber, Input, message,
Alert,
} from 'antd';
import pageStyle from './UnclockDetail.less';
import { hasBtnPower, imagify } from '../../../utils';
import ThemeEditor from '../ThemeEditor';
const { TabPane } = Tabs;
const FormItem = Form.Item;
const { Option } = Select;
const { TextArea } = Input;
const { RangePicker } = DatePicker;
const { confirm } = Modal;
class UnclockDetailForm extends React.Component {
constructor(props) {
super(props);
this.state = {
isShow: true,
textLength: 0,
};
}
componentDidUpdate() {
}
componentWillUnmount() { // 卸载
}
handleSubmit = (e) => {
const { dispatch, form } = this.props;
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
const {
title,
text_require_status,
text_require_num,
image_require_status,
image_require_num,
video_require_status,
video_require_num,
audio_require_status,
audio_require_num,
force_status,
force_num,
} = values;
dispatch({
type: 'createtheme/addSubjectCount',
payload: {
title,
is_cheat: 0,
is_encrypt: 0,
text_require_status: (text_require_status === true) && (text_require_status != undefined) ? 1 : 2,
text_require_num: text_require_num || 0,
image_require_status: (image_require_status === true) && (image_require_status != undefined) ? 1 : 2,
image_require_num: image_require_num || 0,
video_require_status: (video_require_status === true) && (video_require_status != undefined) ? 1 : 2,
video_require_num: video_require_num || 0,
audio_require_status: (audio_require_status === true) && (audio_require_status != undefined) ? 1 : 2,
audio_require_num: audio_require_num || 0,
force_status: (force_status === true) && (force_status != undefined) ? 1 : 2,
force_num: force_num || 0,
callBack: () => {
form.resetFields();
this.setState({
textLength: 0,
});
},
},
});
}
});
}
emigrateUploadImg = (e) => {
const { dispatch } = this.props;
dispatch({
type: 'createtheme/queryimagesignature',
payload: {
files: e.target,
uploadtype: 'quickEmigrateImg',
},
});
}
emigrateUploadAudio = (e) => {
const { dispatch } = this.props;
dispatch({
type: 'createtheme/queryvideosignature',
payload: {
files: e.target,
uploadtype: 'uploadVideoEmigrate',
},
});
}
emigrateUploadVoice = (e) => {
const { dispatch } = this.props;
dispatch({
type: 'createtheme/queryvoicesignature',
payload: {
files: e.target,
uploadtype: 'emigrateUploadVoice',
},
});
}
deleteEmigrate = (index) => {
const { dispatch } = this.props;
dispatch({
type: 'createtheme/deleteEmigrateImg',
payload: {
index,
},
});
}
handleClickShow = () => {
this.setState({
isShow: !this.state.isShow,
});
}
titleChange = (e) => {
const { emigrateParams } = this.props;
this.setState({
textLength: e.target.value.length - emigrateParams.title.length,
});
}
emigrateAddText = () => {
const { dispatch } = this.props;
dispatch({
type: 'createtheme/emigrateAddText',
payload: {
},
});
}
changeEmigrateText = (e, index) => {
const { dispatch } = this.props;
const textValue = e.target.value;
if (textValue.length > 500) {
message.error('最多500字', 0.5);
return;
}
dispatch({
type: 'createtheme/changeEmigrateText',
payload: {
textValue,
index,
},
});
}
emigrateMoveContent = (index, direction) => {
const { dispatch } = this.props;
dispatch({
type: 'createtheme/emigrateMoveContent',
payload: {
index,
direction,
},
});
}
handleLastStep = () => {
const { dispatch } = this.props;
confirm({
title: '提示',
content: '是否确认放弃当前编辑内容?\n',
icon: <Icon type="info-circle" theme="filled" style={{ color: '#1890ff', fontSize: 30 }} />,
onOk() {
dispatch({
type: 'createtheme/handleLastStep',
payload: {
},
});
},
onCancel() {
},
});
}
render() {
const { isShow, textLength } = this.state;
const {
form: { getFieldDecorator, getFieldValue },
emigrateLoading,
emigrateParams,
customsNumberList,
collapsed,
screenIsBig,
emigratedObj,
} = this.props;
const formItemModalLineLayout = {
labelCol: {
xs: { span: 3 },
md: { span: 3 },
},
wrapperCol: {
xs: { span: 21 },
md: { span: 21 },
},
};
const formItemverticalLayout = {
labelCol: {
xs: { span: 5 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 19 },
sm: { span: 19 },
},
};
const formItemModaltypeLayout = {
labelCol: {
xs: { span: 3 },
sm: { span: 3 },
},
wrapperCol: {
xs: { span: 21 },
sm: { span: 21 },
},
};
const selectBefore = (
<div>{textLength + (emigrateParams.title && emigrateParams.title.length)}/40</div>
);
return (
<div className={pageStyle.container}>
<Form labelAlign="left" onSubmit={this.handleSubmit}>
<div className={pageStyle.title}>关卡设置</div>
<div className={pageStyle.customs}>
</div>
<FormItem {...formItemModalLineLayout} label="关卡名称">
{getFieldDecorator('title', {
initialValue: emigrateParams.title,
rules: [
{
required: true,
message: '请输入关卡名称',
},
],
})(
<Input maxLength={40} onChange={e => this.titleChange(e)} addonAfter={selectBefore} placeholder="请输入关卡名称" style={{ width: 435 }} />,
)}
</FormItem>
<FormItem {...formItemModaltypeLayout} label="闯关介绍">
<div className={pageStyle.introduceWrap}>
<ThemeEditor
commentParams={emigrateParams}
editorUploadVoice={this.emigrateUploadVoice}
moveContent={this.emigrateMoveContent}
editorAddText={this.emigrateAddText}
editorUploadImg={this.emigrateUploadImg}
editorUploadAudio={this.emigrateUploadAudio}
editorChange={this.changeEmigrateText}
deleteThemeImg={this.deleteEmigrate}
/>
</div>
</FormItem>
<Divider />
<div className={pageStyle.title}>更多设置 <span onClick={this.handleClickShow} className={pageStyle.pack}>{isShow ? '收起' : '展开'}</span></div>
<div className={isShow ? pageStyle.panpelBox : pageStyle.panpelhideBox}>
<div className={pageStyle.commonwrap}>
<div className={pageStyle.commonleft}>
打卡要求:
</div>
<div className={pageStyle.commonright}>
<FormItem {...formItemModaltypeLayout} label="文字字数要求" style={{ marginBottom: 0 }}>
{getFieldDecorator('text_require_status', {
initialValue: emigrateParams.text_require_status === 1,
valuePropName: 'checked',
})(
<Switch checkedChildren="开启" unCheckedChildren="关闭" />,
)}
<span className="ant-form-text1">开启后,学员需要满足打卡字数(最多500)</span>
</FormItem>
{getFieldValue('text_require_status') === true ? (
<FormItem {...formItemverticalLayout} labelAlign="right" label="学员打卡最少">
{getFieldDecorator('text_require_num', {
initialValue: emigrateParams.text_require_num,
})(
<InputNumber placeholder="请输入" min={0} max={500} style={{ width: 100 }} />,
)}
<span className="ant-form-text">个文字</span>
</FormItem>
) : (
''
)}
<FormItem {...formItemModaltypeLayout} label="图片个数要求" style={{ marginBottom: 0 }}>
{getFieldDecorator('image_require_status', {
initialValue: emigrateParams.image_require_status === 1,
valuePropName: 'checked',
})(
<Switch checkedChildren="开启" unCheckedChildren="关闭" />,
)}
<span className="ant-form-text1">开启后,学员需要满足打卡图片个数(最多9)</span>
</FormItem>
{getFieldValue('image_require_status') === true ? (
<FormItem {...formItemverticalLayout} labelAlign="right" label="学员打卡最少">
{getFieldDecorator('image_require_num', {
initialValue: emigrateParams.image_require_num,
})(
<InputNumber placeholder="请输入" min={0} max={9} style={{ width: 100 }} />,
)}
<span className="ant-form-text">张图片</span>
</FormItem>
) : (
''
)}
<FormItem {...formItemModaltypeLayout} label="视频个数要求" style={{ marginBottom: 0 }}>
{getFieldDecorator('video_require_status', {
initialValue: emigrateParams.video_require_status === 1,
valuePropName: 'checked',
})(
<Switch checkedChildren="开启" unCheckedChildren="关闭" />,
)}
<span className="ant-form-text1">开启后,学员需要满足打卡视频个数(最多9)</span>
</FormItem>
{getFieldValue('video_require_status') === true ? (
<FormItem {...formItemverticalLayout} labelAlign="right" label="学员打卡最少">
{getFieldDecorator('video_require_num', { initialValue: emigrateParams.video_require_num })(
<InputNumber placeholder="请输入" min={0} max={9} style={{ width: 100 }} />,
)}
<span className="ant-form-text">个视频</span>
</FormItem>
) : (
''
)}
<FormItem {...formItemModaltypeLayout} label="录音时长要求" style={{ marginBottom: 0 }}>
{getFieldDecorator('audio_require_status', {
initialValue: emigrateParams.audio_require_status === 1,
valuePropName: 'checked',
})(
<Switch checkedChildren="开启" unCheckedChildren="关闭" />,
)}
<span className="ant-form-text1">开启后,学员需要满足录音时长要求(最多600)</span>
</FormItem>
{getFieldValue('audio_require_status') === true ? (
<FormItem {...formItemverticalLayout} labelAlign="right" label="学员打卡最少">
{getFieldDecorator('audio_require_num', { initialValue: emigrateParams.audio_require_num })(
<InputNumber placeholder="请输入" min={0} max={600} style={{ width: 100 }} />,
)}
<span className="ant-form-text">秒录音</span>
</FormItem>
) : (
''
)}
</div>
</div>
<div className={pageStyle.commonwrap}>
<div className={pageStyle.commonleft}>
规则设置:
</div>
<div className={pageStyle.commonright}>
<FormItem {...formItemModaltypeLayout} label="强制阅读模式" style={{ marginBottom: 0 }}>
{getFieldDecorator('force_status', {
initialValue: emigrateParams.force_status === 1,
valuePropName: 'checked',
})(
<Switch checkedChildren="开启" unCheckedChildren="关闭" />,
)}
<span className="ant-form-text1">开启后,学员必须在主题区域阅读规定时间才能打卡</span>
</FormItem>
{getFieldValue('force_status') === true ? (
<FormItem {...formItemverticalLayout} labelAlign="right" label="学员强制阅读">
{getFieldDecorator('force_num', { initialValue: emigrateParams.force_num })(
<InputNumber placeholder="请输入" min={0} style={{ width: 100 }} />,
)}
<span className="ant-form-text">分钟</span>
</FormItem>
) : (
''
)}
</div>
</div>
</div>
<div
className={pageStyle.footerBox}
style={{
left: screenIsBig ? (!collapsed ? '193px' : '102px') : 0, // eslint-disable-line
width: screenIsBig ? (`calc(100% - ${!collapsed ? '214px' : '122px'})`) : '100%', // eslint-disable-line
}}
>
<div>
<Button ghost type="primary" style={{ marginRight: 20 }} onClick={this.handleLastStep}>取消</Button>
<Button htmlType="submit" type="primary" loading={emigrateLoading}>
保存
</Button>
</div>
</div>
</Form>
</div>
);
}
}
UnclockDetailForm.propTypes = {
};
const UnclockDetail = Form.create()(UnclockDetailForm);
function mapStateToProps(state) {
const {
emigrateLoading,
emigrateParams,
emigratedObj,
releaseLoading,
customsNumberList,
} = state.createtheme;
const { collapsed, screenIsBig } = state.webapp;
return {
emigrateLoading,
emigrateParams,
emigratedObj,
releaseLoading,
customsNumberList,
collapsed,
screenIsBig,
};
}
export default connect(mapStateToProps)(UnclockDetail);
......@@ -26,6 +26,7 @@ const FormItem = Form.Item;
const { Option } = Select;
const { TextArea } = Input;
const { RangePicker } = DatePicker;
const { confirm } = Modal;
class SuccessStoreForm extends React.Component {
constructor(props) {
super(props);
......@@ -57,7 +58,21 @@ class SuccessStoreForm extends React.Component {
addStore = (id) => {
const { dispatch, customsNumberList } = this.props;
if (customsNumberList.length == 0) {
message.warning('关卡数量已满', 0.5);
confirm({
title: '提示',
content: '确认新增额外关卡?\n',
icon: <Icon type="info-circle" theme="filled" style={{ color: '#1890ff', fontSize: 30 }} />,
onOk() {
dispatch({
type: 'createtheme/addStoreCount',
payload: {
id,
},
});
},
onCancel() {
},
});
return;
}
dispatch({
......
......@@ -271,6 +271,11 @@ const UnclockDetail = props => (
{ UnclockDetail => (<UnclockDetail {...props} />) }
</Bundle>
);
const AddStoreCount = props => (
<Bundle load={() => import(/* webpackChunkName:"AddStoreCount" */'./pages/newtheme/customsclock/addStoreCount')}>
{ AddStoreCount => (<AddStoreCount {...props} />) }
</Bundle>
);
function RouterConfig({ history }) {
return (
<ConfigProvider locale={zhCN}>
......@@ -322,6 +327,7 @@ function RouterConfig({ history }) {
<Route path="/sjd/editCustoms/:id" exact component={EditCustoms} />
<Route path="/sjd/editCustomsContent/:id" exact component={UnclockDetail} />
<Route path="/sjd/addCustomsContent/:id" exact component={UnclockDetail} />
<Route path="/sjd/addStoreCount/:id" exact component={AddStoreCount} />
<Route component={Errorpage} />
</Switch>
</SjdIndex>
......
......@@ -93,3 +93,11 @@ export function getUnlockSubjectDetail(params) {
data,
});
}
export function unlockAddSubjectCount(params) {
const data = qs.stringify(params);
return request({
url: `${api.createtheme.unlockAddSubjectCount}`,
method: 'POST',
data,
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment