Commit 6dfd63c7 authored by baixian's avatar baixian

新建打卡

parent da0f0645
......@@ -151,5 +151,8 @@ export default {
integralRulesEdit: `${dakaapi}member/integral_rules/update`,
integralRulesList: `${dakaapi}member/integral_rules/show`,
},
createtheme: {
addTheme: `${dakaapi}member/subject`,
},
};
This diff is collapsed.
......@@ -37,6 +37,7 @@ import clockmgtModel from './clockmgt';
import playaudioModel from './playaudio';
import hqstatistical from './hqstatistical';
import integralModel from './integral';
import createThemeModal from './createtheme';
export default {
loginModel,
indexstaicModel,
......@@ -68,4 +69,5 @@ export default {
playaudioModel,
hqstatistical,
integralModel,
createThemeModal,
};
......@@ -63,6 +63,7 @@ export default {
chartEndDate: '',
start_time: '',
end_time: '',
tabIndex: 1,
},
subscriptions: {
setup({ dispatch, history }) { // eslint-disable-line
......@@ -544,6 +545,25 @@ export default {
// message.error(clockCharts.msg, 1);
}
},
* goTheme({ payload }, { call, put, select }) {
const { index } = payload;
yield put({
type: 'updateState',
payload: {
tabIndex: index,
},
});
yield put(routerRedux.push('/sjd/newtheme'));
},
* tabChange({ payload }, { call, put, select }) {
const { tabIndex } = payload;
yield put({
type: 'updateState',
payload: {
tabIndex,
},
});
},
* pageInit({ payload }, { call, put, select }) {
yield put({
type: 'updateState',
......
......@@ -541,6 +541,22 @@ export default {
},
});
}
if (pathname === '/sjd/newtheme') {
dispatch({
type: 'createtheme/queryClassList',
payload: {
},
});
dispatch({
type: 'webapp/updateState',
payload: {
breadcrumbList: [{
path: pathname,
name: '发布主题',
}],
},
});
}
});
},
},
......@@ -647,6 +663,9 @@ export default {
yield put({
type: 'integral/pageInit',
});
yield put({
type: 'createtheme/pageInit',
});
},
* onPageEnter({ payload }, { put, call, select }) {
const { pathname } = payload;
......
......@@ -57,10 +57,22 @@ class StaticCenter extends React.Component {
});
}
createTheme = () => {
message.warning('功能即将开放,敬请期待');
const { dispatch } = this.props;
dispatch({
type: 'indexstaic/goTheme',
payload: {
index: 1,
},
});
}
createCalendarTheme = () => {
message.warning('功能即将开放,敬请期待');
const { dispatch } = this.props;
dispatch({
type: 'indexstaic/goTheme',
payload: {
index: 2,
},
});
}
createUnlockTheme = () => {
message.warning('功能即将开放,敬请期待');
......@@ -575,6 +587,8 @@ function mapStateToProps(state) {
chartEndDate,
chartStartDate,
} = state.indexstaic;
// eslint-disable-next-line no-empty-pattern
const {} = state.classmgt;
return {
staticcenter,
clockCharts,
......
import { connect } from 'dva';
import React from 'react';
import { Icon, Divider, Tabs, Select, Form, Upload, Row, Col, Input, Radio, Modal, message } from 'antd';
import pageStyle from './ThemeEditor.less';
import { pageIn, hasBtnPower, imagify, ossVideofy } from '../../utils/index';
const { TabPane } = Tabs;
const { TextArea } = Input;
class ThemeEditor extends React.Component {
constructor(props) {
super(props);
this.state = {
previewVisible: false,
previewImage: '',
};
}
componentDidMount() { // 挂载
pageIn('轻校-发布主题');
}
componentDidUpdate() {
}
componentWillUnmount() { // 卸载
}
priviewImg = (img) => {
this.setState({
previewVisible: true,
previewImage: img,
});
}
handleCancel = () => {
this.setState({
previewVisible: false,
});
}
render() {
const { previewVisible, previewImage } = this.state;
const {
editorUploadImg,
commentParams,
editorUploadAudio,
editorChange,
deleteThemeImg,
deleteThemeVideo,
editorText,
} = this.props;
return (
<div className={pageStyle.container}>
<TextArea value={editorText} onChange={e => editorChange(e)} placeholder="请输入内容" style={{ width: 560 }} maxLength={500} rows={6} />
<div className={pageStyle.editorwrap}>
<div className={pageStyle.uploadimgbox}>
{commentParams.content.map((item, index) => (
item.type === 'img' &&
<div className={pageStyle.imgwrap}>
<img alt={item.type} className={pageStyle.teacheruploadimg} src={imagify(item.value)} />
<div className={pageStyle.imghide}>
<a title="预览文件" onClick={() => this.priviewImg(item.value)} href="javascript:;" ><Icon style={{ color: '#fff' }} type="eye" /> 预览</a>
<Divider type="vertical" />
<a title="删除文件" onClick={() => deleteThemeImg(index)} href="javascript:;"> <Icon style={{ color: '#fff' }} type="delete" />删除</a>
</div>
</div>
))}
{commentParams.content.map((item, index) => (
item.type === 'video' &&
<div className={pageStyle.videowrap}>
<video controls="controls" className={pageStyle.videoPoster} src={ossVideofy(item.value)} />
<div className={pageStyle.videohide}>
<a title="删除文件" onClick={() => deleteThemeImg(index)} href="javascript:;"> <Icon style={{ color: '#fff' }} type="delete" />删除</a>
</div>
</div>
))}
</div>
</div>
<div className={pageStyle.uploadflex}>
<div className={pageStyle.uploadimg}><input type="file" id="uploadImg" className={pageStyle.fileuploadinput} onChange={editorUploadImg} accept="image/*" /><Icon style={{ marginRight: 10 }} type="picture" />添加图片</div>
<div className={pageStyle.uploadimg}><input type="file" id="uploadVideo" className={pageStyle.fileuploadinput} onChange={editorUploadAudio} accept="video/*" /><Icon style={{ marginRight: 10 }} type="video-camera" />添加视频</div>
</div>
<Modal visible={previewVisible} footer={null} onCancel={this.handleCancel}>
<img alt="图片" style={{ width: '100%' }} src={imagify(previewImage)} />
</Modal>
</div>
);
}
}
ThemeEditor.propTypes = {
};
export default connect()(ThemeEditor);
.editorwrap {
width: 563px;
margin-top: 15px;
.uploadimgbox {
display: flex;
align-items: flex-end;
margin-bottom: 18px;
flex-wrap: wrap;
.imgwrap {
width: 135px;
height: 135px;
border-radius: 4px;
margin-right: 6px;
position: relative;
}
.imgwrap:hover {
cursor: pointer;
.imghide {
opacity: 1;
background-color: rgba(0,0,0,0.5);
transition: all .3s;
z-index: 1;
color: #fff;
}
}
.imghide {
position: absolute;
width: 100%;
height: 100%;
bottom: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
opacity: 0;
color: #fff;
z-index: -1;
a {
color: #fff;
}
}
.teacheruploadimg {
width: 100%;
height: 100%;
}
.teacheruploadimg:nth-child(4n){
margin-right: 0;
}
.videowrap {
width: 150px;
height: 150px;
position: relative;
.videoPoster {
width: 100%;
height: 100%;
}
}
.videowrap:hover {
cursor: pointer;
.videohide {
opacity: 1;
background-color: rgba(0,0,0,0.5);
transition: all .3s;
z-index: 1;
color: #fff;
}
}
.videohide {
position: absolute;
width: 100%;
height: 100%;
bottom: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
opacity: 0;
color: #fff;
z-index: -1;
a {
color: #fff;
}
}
}
}
.uploadflex {
display: flex;
align-items: center;
.uploadimg {
cursor: pointer;
width: 106px;
height: 32px;
line-height: 32px;
text-align: center;
border: 1px solid #D9D9D9;
border-radius: 4px;
color: rgba(0,0,0,0.65);
margin-left: 15px;
position: relative;
margin-right: 30px;
.fileuploadinput {
cursor: pointer;
position: absolute;
width: 100%;
height: 100%;
z-index: 1;
opacity: 0;
left: 0;
top: 0;
}
}
}
This diff is collapsed.
.container {
background-color: #fff;
padding: 0 20px;
position: relative;
}
.title {
font-size:16px;
font-family:PingFangSC;
font-weight:600;
color:rgba(0,0,0,0.85);
line-height:24px;
position: relative;
padding-bottom: 30px;
.pack {
font-size:14px;
font-family:PingFangSC;
font-weight:400;
color:rgba(24,144,255,1);
line-height:20px;
display: inline-block;
margin-left: 36px;
cursor: pointer;
}
}
.title:after {
position: absolute;
content: '';
display: block;
width: 3px;
height: 19px;
background-color: #1890FF;
left: -10px;
top: 4px;
border-radius:2px;
}
.commonwrap {
display: flex;
align-items: flex-start;
:global {
.ant-form-item-label > label::after {
content: '';
}
}
.commonleft {
width: 105px;
font-size:14px;
font-family:PingFangSC;
font-weight:400;
color:rgba(0,0,0,0.85);
line-height:40px;
}
.commonright {
width: 80%;
:global {
.ant-form-text1 {
font-size:12px;
font-family:PingFangSC;
font-weight:400;
color:rgba(0,0,0,0.55);
line-height:22px;
display: inline-block;
margin-left: 10px;
}
.ant-form-item .ant-switch {
margin-left: -12px;
}
}
}
}
.panpelBox {
display: block;
transition: all .3s;
}
.panpelhideBox {
display: none;
}
.toblock {
display: inline-block;
margin: 0 10px;
}
.calendarlist {
display: flex;
.calendaritem {
width: 40px;
height: 40px;
font-size: 14px;
border: 1px solid #D9D9D9;
line-height: 40px;
text-align: center;
border-radius: 50%;
color: #595959;
cursor: pointer;
}
.calendaritemActive {
width: 40px;
height: 40px;
font-size: 14px;
border: 1px solid #1890FF;
line-height: 40px;
text-align: center;
border-radius: 50%;
background-color: #1890FF;
color: #fff;
cursor: pointer;
}
.calendaritem:not(:last-child), .calendaritemActive:not(:last-child){
margin-right: 10px;
}
}
import { connect } from 'dva';
import React from 'react';
import { Icon, Button, Tabs, Select, Form, InputNumber, Row, Col, Input, Radio, Modal, message } from 'antd';
import pageStyle from './index.less';
import { pageIn, hasBtnPower } from '../../utils/index';
import JobClock from './jobclock/index';
import CalendarClock from './calendarclock/index';
const { TabPane } = Tabs;
class NewThemeForm extends React.Component {
componentDidMount() { // 挂载
pageIn('轻校-发布主题');
}
componentDidUpdate() {
}
componentWillUnmount() { // 卸载
}
tabChange=(key) => {
const { dispatch, tabIndex } = this.props;
dispatch({
type: 'indexstaic/tabChange',
payload: {
tabIndex: key,
},
});
}
render() {
const {
tabIndex,
} = this.props;
return (
<div className={pageStyle.container}>
<div className={pageStyle.typeTip}>主题类型</div>
<Tabs activeKey={`${tabIndex}`} tabPosition="left" onChange={this.tabChange} animated={false}>
<TabPane
tab={
<div className={pageStyle.makeitem}>
<div className={pageStyle.makeitemLeft}>
<div className={`${pageStyle.themeicon}`}>
<img src={`${__IMGCDN__}themeaicon.png`} alt="" />
</div>
<div className={pageStyle.themetypename}>新建作业打卡</div>
</div>
</div>
}
key="1"
>
<JobClock />
</TabPane>
<TabPane
tab={
<div className={pageStyle.makeitem}>
<div className={pageStyle.makeitemLeft}>
<div className={`${pageStyle.themeicon}`}>
<img src={`${__IMGCDN__}themebicon.png`} alt="" />
</div>
<div className={pageStyle.themetypename}>新建日历打卡</div>
</div>
</div>
}
key="2"
>
<CalendarClock />
</TabPane>
<TabPane
tab={
<div className={pageStyle.makeitem}>
<div className={pageStyle.makeitemLeft}>
<div className={`${pageStyle.themeicon}`}>
<img src={`${__IMGCDN__}themecicon.png`} alt="" />
</div>
<div className={pageStyle.themetypename}>新建闯关打卡</div>
</div>
</div>
}
key="3"
>
3
</TabPane>
</Tabs>
</div>
);
}
}
NewThemeForm.propTypes = {
};
const NewTheme = Form.create()(NewThemeForm);
function mapStateToProps(state) {
const {
tabIndex,
} = state.indexstaic;
return {
tabIndex,
};
}
export default connect(mapStateToProps)(NewTheme);
@import '../../less/variables.less';
.container {
background-color: #fff;
padding: 12px 20px 24px 20px;
position: relative;
overflow-y: hidden;
border-radius:2px 0px 2px 2px;
:global {
.ant-tabs .ant-tabs-left-bar .ant-tabs-tab, .ant-tabs .ant-tabs-right-bar .ant-tabs-tab {
padding: 0;
}
.ant-tabs-nav-scroll {
border-right: 1px solid rgba(0, 0, 0, .1);
padding-right: 30px;
}
.ant-tabs-ink-bar {
background-color: transparent;
}
.ant-tabs-tab {
border: 1px solid rgba(217, 217, 217, 1);
font-size: 18px;
font-weight: 400;
color: rgba(0, 0, 0, 0.65);
border-radius: 6px;
}
//.ant-tabs-tab:hover {
// border: none;
//}
.ant-tabs-nav .ant-tabs-tab-active {
border: none;
background: rgba(230, 247, 255, 1);
color: #1890FF;
}
}
}
.typeTip {
font-size: 16px;
font-family: PingFangSC;
font-weight: 600;
color: rgba(0, 0, 0, 0.85);
line-height: 24px;
margin-bottom: 30px;
}
.makeitem {
cursor: pointer;
width: 217px;
height: 59px;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 22px;
.makeitemLeft {
display: flex;
align-items: center;
}
}
.makeitem:hover {
cursor: pointer;
background: rgba(230, 247, 255, 1);
border: 0;
.themetypename {
font-weight: 400;
color: rgba(24, 144, 255, 1);
font-family: PingFangSC;
}
.themetypeicon {
color: rgba(24, 144, 255, 1);
}
}
.themeicon {
img {
width: 40px;
height: 40px;
margin-right: 15px;
}
}
This diff is collapsed.
.container {
background-color: #fff;
padding: 0 20px;
position: relative;
}
.title {
font-size:16px;
font-family:PingFangSC;
font-weight:600;
color:rgba(0,0,0,0.85);
line-height:24px;
position: relative;
padding-bottom: 30px;
.pack {
font-size:14px;
font-family:PingFangSC;
font-weight:400;
color:rgba(24,144,255,1);
line-height:20px;
display: inline-block;
margin-left: 36px;
cursor: pointer;
}
}
.title:after {
position: absolute;
content: '';
display: block;
width: 3px;
height: 19px;
background-color: #1890FF;
left: -10px;
top: 4px;
border-radius:2px;
}
.commonwrap {
display: flex;
align-items: flex-start;
:global {
.ant-form-item-label > label::after {
content: '';
}
}
.commonleft {
width: 105px;
font-size:14px;
font-family:PingFangSC;
font-weight:400;
color:rgba(0,0,0,0.85);
line-height:40px;
}
.commonright {
width: 80%;
:global {
.ant-form-text1 {
font-size:12px;
font-family:PingFangSC;
font-weight:400;
color:rgba(0,0,0,0.55);
line-height:22px;
display: inline-block;
margin-left: 10px;
}
.ant-form-item .ant-switch {
margin-left: -12px;
}
}
}
}
.panpelBox {
display: block;
transition: all .3s;
}
.panpelhideBox {
display: none;
}
......@@ -41,10 +41,15 @@ const IndexStaic = props => (
);
const Integralmanage = props => (
<Bundle load={() => import(/* webpackChunkName:"officialweb" */'./pages/integralmanage/index')}>
<Bundle load={() => import(/* webpackChunkName:"integralmanage" */'./pages/integralmanage/index')}>
{ Integralmanage => (<Integralmanage {...props} />) }
</Bundle>
);
const NewTheme = props => (
<Bundle load={() => import(/* webpackChunkName:"newtheme" */'./pages/newtheme/index')}>
{ NewTheme => (<NewTheme {...props} />) }
</Bundle>
);
const Storesetting = props => (
<Bundle load={() => import(/* webpackChunkName:"officialweb" */'./pages/integralmanage/storesetting/index')}>
{ Storesetting => (<Storesetting {...props} />) }
......@@ -166,6 +171,7 @@ function RouterConfig({ history }) {
render={() => (
<SjdIndex>
<Route path="/sjd/storesetting" exact component={Storesetting} />
<Route path="/sjd/newtheme" config={{ needAuth: true }} exact component={NewTheme} />
<Route path="/sjd/integralmanage" config={{ needAuth: true }} exact component={Integralmanage} />
<Route path="/sjd/officialweb" config={{ needAuth: true }} exact component={Officialweb} />
<Route path="/sjd/officialwebeditor" exact component={OfficialwebEditor} />
......
import qs from 'qs';
import request from '../utils/request';
import api from '../common/api';
export function addTheme(params) {
const data = qs.stringify(params);
return request({
url: `${api.createtheme.addTheme}`,
method: 'POST',
data,
});
}
......@@ -691,6 +691,65 @@ function DayCount(date1, date2) {
const day = parseInt(days / (1000 * 60 * 60 * 24));
return (day + 1);
}
// 获取某个时间段的周几
function getWeek(begin, end, weekNum) {
const dateArr = [];
const stimeArr = begin.split('-');
const etimeArr = end.split('-');
const stoday = new Date();
stoday.setUTCFullYear(stimeArr[0], stimeArr[1] - 1, stimeArr[2]);
const etoday = new Date();
etoday.setUTCFullYear(etimeArr[0], etimeArr[1] - 1, etimeArr[2]);
const unixDb = stoday.getTime();// 开始时间的毫秒数
const unixDe = etoday.getTime();// 结束时间的毫秒数
for (let k = unixDb; k <= unixDe;) {
// eslint-disable-next-line no-use-before-define,radix
const needJudgeDate = msToDate(parseInt(k)).withoutTime;
// 不加这个if判断直接push的话就是已知时间段内的所有日期
if (new Date(needJudgeDate).getDay() === weekNum) {
dateArr.push(needJudgeDate);
}
k += 24 * 60 * 60 * 1000;
}
return dateArr;
}
function msToDate(msec) {
const datetime = new Date(msec);
const year = datetime.getFullYear();
const month = datetime.getMonth();
const date = datetime.getDate();
const hour = datetime.getHours();
const minute = datetime.getMinutes();
const second = datetime.getSeconds();
const result1 = `${year
}-${
(month + 1) >= 10 ? (month + 1) : `0${month + 1}`
}-${
(date + 1) < 10 ? `0${date}` : date
} ${
(hour + 1) < 10 ? `0${hour}` : hour
}:${
(minute + 1) < 10 ? `0${minute}` : minute
}:${
(second + 1) < 10 ? `0${second}` : second}`;
const result2 = `${year
}-${
(month + 1) >= 10 ? (month + 1) : `0${month + 1}`
}-${
(date + 1) < 11 ? `0${date}` : date}`;
const result = {
hasTime: result1,
withoutTime: result2,
};
return result;
}
export {
......@@ -733,4 +792,5 @@ export {
getBetweenDays,
hasBtnPower,
DayCount,
getWeek,
};
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