Commit 2cde7958 authored by baixian's avatar baixian

微官网

parents ee0b95fa 85c724c2
......@@ -20,3 +20,4 @@
<div id="root"></div>
<script type="text/javascript" src="/dist/main.31c1eb.js"></script></body>
</html>
</html>
......@@ -125,6 +125,12 @@ export default {
clockList: `${dakaapi}common/clock`,
ads: `${dakaapi}member/website/ads`,
adsSave: `${dakaapi}member/website/ad/save`,
moments: `${dakaapi}member/website/moments`,
momentSave: `${dakaapi}member/website/moment/save`,
onlineClass: `${dakaapi}member/website/online_course`,
onlineClassSave: `${dakaapi}member/website/online_course/save`,
subjectMixture: `${dakaapi}member/website/subject_mixture`,
subjectMixtureSave: `${dakaapi}member/website/subject_mixture/save`,
},
schedule: `${dakaapi}member/erp/schedules`,
scheduleMgt: {
......
......@@ -20,6 +20,7 @@ import * as classMgtAjax from '../services/classmgt';
import * as uploader from '../services/uploader';
import { calendar } from '../utils/calendar';
import * as commonAjax from '../services/common';
import * as memberListAjax from '../services/clockmember';
import exportExcel from '../utils/exportexcel';
export default {
namespace: 'createtheme',
......@@ -2294,17 +2295,54 @@ export default {
},
// 闯关学员导出 UnlockStudentExport
* exportStudentExcel({ payload }, { call, put, select }) {
const { columns } = payload;
const {
columns, subject_id, subject_type, checkpoint_id,
} = payload;
const { emigratedObj } = yield select(state => state.createtheme);
const { sid } = yield select(state => state.webapp);
let newParams = '';
switch (subject_type) {
case 1:
newParams = {
subject_id,
subject_type,
school_id: sid,
extra: 'need_statistic',
};
break;
case 2:
newParams = {
subject_id,
subject_type,
school_id: sid,
extra: 'need_statistic',
};
break;
case 3:
newParams = {
subject_id,
subject_type,
school_id: sid,
checkpoint_id,
extra: 'need_statistic',
};
break;
default:
break;
}
const loading = message.loading('导出数据中...', 1);
const data = yield call(themeAjax.UnlockStudentExport, {
mode_id: emigratedObj.id,
});
const data = yield call(memberListAjax.memberList, newParams);
setTimeout(loading);
if (data.code == 200) {
const list = (data.data && data.data.list) || [];
if (list.length > 0) {
exportExcel(columns, list, '闯关打卡学员列表.xlsx', 'unlockStudent');
if (newParams.subject_type == 1) {
exportExcel(columns, list, '作业打卡学员列表.xlsx', 'jobClockStudent');
} else if (newParams.subject_type == 2) {
exportExcel(columns, list, '日历打卡学员列表.xlsx', 'unlockStudent');
} else if (newParams.subject_type == 3) {
exportExcel(columns, list, '闯关打卡学员列表.xlsx', 'unlockStudent');
}
} else {
message.error('暂时没有数据可以导出!', 0.5);
}
......
......@@ -6,12 +6,14 @@ import {
LocalStorage,
SessionStorage,
isExpired,
getRandomFilename,
getRandomFilename, getVideoDuration,
} from '../utils/index';
import * as uploader from '../services/uploader';
import * as officialwebajax from '../services/officialweb';
import * as commonajax from '../services/common';
import * as onlineAjax from '../services/onlineclasses';
import errorcode from '../common/errorcode';
import * as themeListAjax from '../services/newthemelist';
export default {
namespace: 'officialweb',
state: {
......@@ -65,6 +67,14 @@ export default {
name: 'classmoments',
desc: '课堂瞬间',
},
{
name: 'onlineclass',
desc: '在线课堂',
},
{
name: 'togetherclock',
desc: '一起打卡',
},
{
name: 'course',
desc: '体验课',
......@@ -106,6 +116,16 @@ export default {
data: {
},
},
{
type: 'onlineclass',
data: {
},
},
{
type: 'togetherclock',
data: {
},
},
{
type: 'course',
data: {
......@@ -122,6 +142,13 @@ export default {
adCarouselStatus: false, // 广告轮播保存状态
classMoment: [], // 课堂瞬间
classMomentStatus: false, // 课堂瞬间保存状态
progressRate: 0, // 上传进度
onlineClassList: [], // 在线课堂列表
onlineClassStatus: false, // 在线课堂保存状态
onlineClassTargetKeys: [], // 在线课堂推荐
togetherClockList: [], // 打卡列表
togetherClockStatus: false, // 一起来打卡保存状态
togetherClockTargetKeys: [], // 打卡推荐
},
subscriptions: {
setup({ dispatch, history }) { // eslint-disable-line
......@@ -172,7 +199,6 @@ export default {
const {
index,
} = payload;
console.log(index, 'index');
if (pageInfo[index].type != 'schoolinfo' && schoolInfo.id == 0) {
message.error('请先编辑模块一【机构信息】', 1);
yield put({
......@@ -437,9 +463,13 @@ export default {
} else {
message.error(schoolIntro.msg, 1);
}
yield put({
type: 'queryOnlineClassList',
});
yield put({
type: 'queryTogetherClockList',
});
setTimeout(infoLoad);
console.log(newpageInfo, 'newpageInfo11111111111');
console.log(schoolDetail, 'schoolDetail');
yield put({
type: 'updateState',
payload: {
......@@ -631,37 +661,56 @@ export default {
* queryvideosignature({ payload }, { call, put, select }) {
const { avatorUploader } = yield select(state => state.uploader);
const { userInfo, sid } = yield select(state => state.webapp);
const { files, uploadtype, orgIndex } = payload;
const {
files, uploadtype, orgIndex, progressCallBack,
} = payload;
const file = files.files ? files.files[0] : null;
const REGEXP_VIDEO = /^video\/\w+/;
const params = { type: 1, token: userInfo.token, schoolId: sid };
let signature = {};
if (file && file.size > 2000 * 1024 * 1024) {
message.error('视频的大小不能超过2GB,请重新上传', 1);
return;
}
if (file && (REGEXP_VIDEO.test(file.type) || file.type === '')) {
// const filesize = file.size / 1024;
// if (filesize > avatorUploader.maxsize) {
// message.error(`图片大小请控制在${Math.floor(avatorUploader.maxsize)}KB 以内`);
// }
const uploadSignature = yield call(uploader.uploadVideoSignature, params);
signature = uploadSignature.data;
yield put({
type: 'uploadvideo',
payload: {
signature,
avatorUploader,
files,
uploadtype,
orgIndex,
},
});
if (uploadSignature.code == 200) {
yield put({
type: 'uploadvideo',
payload: {
signature,
avatorUploader,
files,
uploadtype,
orgIndex,
progressCallBack,
},
});
} else {
yield put({
type: 'updateState',
payload: {
progressRate: 0,
},
});
yield put({
type: 'webapp/errorrequestresolve',
payload: {
data: uploadSignature,
},
});
}
}
},
* uploadvideo({ payload }, { call, put, select }) {
const {
signature, files, uploadtype, orgIndex,
progressCallBack,
} = payload;
const file = files.files ? files.files[0] : null;
const uploaderLoading = message.loading('正在上传视频', 0);
const { bannerVideo, orgdescs } = yield select(state => state.officialweb);
const { bannerVideo, orgdescs, classMoment } = yield select(state => state.officialweb);
let newbannerVideo = JSON.parse(JSON.stringify(bannerVideo));
const filename = `${signature.dir}${getRandomFilename(file.name)}`;
const params = {
......@@ -671,29 +720,62 @@ export default {
signature: signature.signature,
file,
url: signature.host,
callback: signature.callback,
};
const uploadImg = yield call(uploader.uploadVideo, params);
document.getElementById('uploadCommon').value = '';
const uploadImg = yield call(uploader.uploadVideo, params, (res) => {
progressCallBack(res);
});
const videoUrl = filename;
if (uploadtype == 'banner') {
newbannerVideo = [videoUrl];
yield delay(2000);
setTimeout(uploaderLoading);
if (JSON.stringify(uploadImg) == '{"status":"ok"}') {
yield put({
type: 'updateState',
payload: {
bannerVideo: newbannerVideo,
progressRate: 0,
},
});
} else if (uploadtype == 'orgdesccover') {
const neworgdescs = JSON.parse(JSON.stringify(orgdescs));
neworgdescs[orgIndex].content = [filename];
if (uploadtype == 'banner') {
newbannerVideo = [videoUrl];
yield delay(2000);
yield put({
type: 'updateState',
payload: {
bannerVideo: newbannerVideo,
},
});
} else if (uploadtype == 'orgdesccover') {
const neworgdescs = JSON.parse(JSON.stringify(orgdescs));
neworgdescs[orgIndex].content = [filename];
yield put({
type: 'officialweb/updateState',
payload: {
orgdescs: neworgdescs,
},
});
} else if (uploadtype == 'uploadClassMomentVideo') {
const duration = yield call(getVideoDuration, file);
classMoment[orgIndex].content.push({
type: 'video',
value: videoUrl,
duration,
});
yield put({
type: 'officialweb/updateState',
payload: {
classMoment: [...classMoment],
},
});
}
} else {
yield put({
type: 'officialweb/updateState',
type: 'updateState',
payload: {
orgdescs: neworgdescs,
progressRate: 0,
},
});
message.error('上传失败', 1);
}
setTimeout(uploaderLoading);
},
* delvideo({ payload }, { put }) {
yield put({
......@@ -1323,29 +1405,70 @@ export default {
setTimeout(loading);
if (data.code == 200) {
message.success('保存成功', 0.3);
yield put({
type: 'updateState',
payload: {
adCarouselStatus: false,
},
});
} else {
message.error(data.msg, 1);
}
},
// 课堂瞬间
* handleClassMomentPlate({ payload }, { call, put, select }) {
const { type } = payload;
const { classMoment } = yield select(state => state.officialweb);
if (classMoment.length >= 20) {
message.error('已超出添加上限!', 0.5);
return;
}
if (type == 1) {
classMoment.push({ title: '', content: [] });
} else {
classMoment.push({ title: '', content: [] });
classMoment.push({ title: '', content: [] });
yield put({
type: 'updateState',
payload: {
classMoment: [...classMoment],
},
});
},
* deleteClassMomentImg({ payload }, { call, put, select }) {
const { index, sort } = payload;
const { classMoment } = yield select(state => state.officialweb);
classMoment[index].content.splice(sort, 1);
yield put({
type: 'updateState',
payload: {
classMoment: [...classMoment],
},
});
},
* handleChangeMomentText({ payload }, { call, put, select }) {
const { index, value } = payload;
const { classMoment } = yield select(state => state.officialweb);
classMoment[index].title = value;
yield put({
type: 'updateState',
payload: {
classMoment: [...classMoment],
},
});
},
* moveClassMomentPlate({ payload }, { call, put, select }) {
const { index, direction } = payload;
const { classMoment } = yield select(state => state.officialweb);
const newPlate = JSON.parse(JSON.stringify(classMoment));
const currentImg = classMoment[index];
const preImg = classMoment[index - 1];
const afterImg = classMoment[index + 1];
if (direction == 'up') {
newPlate.splice(index - 1, 2, currentImg, preImg);
} else if (direction == 'down') {
newPlate.splice(index, 2, afterImg, currentImg);
}
yield put({
type: 'updateState',
payload: {
classMoment: newPlate,
},
});
},
* deleteClassMomentPlate({ payload }, { call, put, select }) {
const { index } = payload;
const { classMoment } = yield select(state => state.officialweb);
classMoment.splice(index, 1);
yield put({
type: 'updateState',
payload: {
......@@ -1353,6 +1476,182 @@ export default {
},
});
},
* saveClassMomentPlate({ payload }, { call, put, select }) {
const { classMoment, classMomentStatus } = yield select(state => state.officialweb);
const { sid } = yield select(state => state.webapp);
if (classMoment.length == 0) {
message.error('请先添加内容!', 0.5);
return;
}
if (classMoment.length > 0) {
let flag = false;
let imgFlag = false;
classMoment.forEach((item, index) => {
if (item.title == '') {
flag = true;
}
if (item.content.length == 0) {
imgFlag = true;
}
// eslint-disable-next-line no-param-reassign
item.content = JSON.stringify(item.content);
});
if (flag) {
message.error('标题不能为空', 0.5);
return;
}
if (imgFlag) {
message.error('请上传视频或者图片', 0.5);
return;
}
}
const loading = message.loading('数据保存中...');
if (classMomentStatus) {
return;
}
yield put({
type: 'updateState',
payload: {
classMomentStatus: true,
},
});
const data = yield call(officialwebajax.momentSave, {
school_id: sid,
data: JSON.stringify(classMoment),
});
yield put({
type: 'updateState',
payload: {
classMomentStatus: false,
},
});
setTimeout(loading);
if (data.code == 200) {
message.success('保存成功', 0.3);
} else {
message.error(data.msg, 1);
}
},
// 在线课堂版块
* queryOnlineClassList({ payload }, { call, put, select }) {
const { sid } = yield select(state => state.webapp);
const data = yield call(onlineAjax.courseList, {
school_id: sid,
});
if (data.code === 200) {
yield put({
type: 'updateState',
payload: {
onlineClassList: data.data && data.data.list,
},
});
} else {
yield put({
type: 'webapp/errorrequestresolve',
payload: {
data,
},
});
}
},
* saveOnlinePlate({ payload }, { call, put, select }) {
const { onlineClassTargetKeys, onlineClassStatus } = yield select(state => state.officialweb);
const { sid } = yield select(state => state.webapp);
if (onlineClassTargetKeys.length == 0) {
message.error('请先选择推荐课堂!', 0.5);
return;
}
const newList = [];
onlineClassTargetKeys.forEach((item, index) => {
newList.push({ online_course_id: item });
});
const loading = message.loading('数据保存中...');
if (onlineClassStatus) {
return;
}
yield put({
type: 'updateState',
payload: {
onlineClassStatus: true,
},
});
const data = yield call(officialwebajax.onlineClassSave, {
school_id: sid,
data: JSON.stringify(newList),
});
yield put({
type: 'updateState',
payload: {
classMomentStatus: false,
},
});
setTimeout(loading);
if (data.code == 200) {
message.success('保存成功', 0.3);
} else {
message.error(data.msg, 1);
}
},
// 一起来打卡模块
* queryTogetherClockList({ payload }, { call, put, select }) {
const { sid } = yield select(state => state.webapp);
const data = yield call(themeListAjax.clockList, {
school_id: sid,
});
if (data.code === 200) {
yield put({
type: 'updateState',
payload: {
togetherClockList: data.data && data.data.list,
},
});
} else {
yield put({
type: 'webapp/errorrequestresolve',
payload: {
data,
},
});
}
},
* saveClockPlate({ payload }, { call, put, select }) {
const { togetherClockTargetKeys, togetherClockStatus } = yield select(state => state.officialweb);
const { sid } = yield select(state => state.webapp);
if (togetherClockTargetKeys.length == 0) {
message.error('请先选择推荐课堂!', 0.5);
return;
}
const newList = [];
togetherClockTargetKeys.forEach((item, index) => {
newList.push({ subject_mixed_id: item });
});
const loading = message.loading('数据保存中...');
if (togetherClockStatus) {
return;
}
yield put({
type: 'updateState',
payload: {
togetherClockStatus: true,
},
});
const data = yield call(officialwebajax.subjectMixtureSave, {
school_id: sid,
data: JSON.stringify(newList),
});
yield put({
type: 'updateState',
payload: {
togetherClockStatus: false,
},
});
setTimeout(loading);
if (data.code == 200) {
message.success('保存成功', 0.3);
} else {
message.error(data.msg, 1);
}
},
* pageInit({ payload }, { call, put, select }) {
yield put({
type: 'updateState',
......@@ -1407,6 +1706,14 @@ export default {
name: 'classmoments',
desc: '课堂瞬间',
},
{
name: 'onlineclass',
desc: '在线课堂',
},
{
name: 'togetherclock',
desc: '一起打卡',
},
{
name: 'course',
desc: '体验课',
......@@ -1447,6 +1754,16 @@ export default {
data: {
},
},
{
type: 'onlineclass',
data: {
},
},
{
type: 'togetherclock',
data: {
},
},
{
type: 'course',
data: {
......@@ -1463,6 +1780,13 @@ export default {
adCarouselStatus: false, // 广告轮播保存状态
classMoment: [], // 课堂瞬间
classMomentStatus: false, // 课堂瞬间保存状态
progressRate: 0,
onlineClassList: [],
onlineClassStatus: false, // 在线课堂保存状态
onlineClassTargetKeys: [],
togetherClockList: [], // 打卡列表
togetherClockStatus: false, // 一起来打卡保存状态
togetherClockTargetKeys: [], // 打卡推荐
},
});
},
......
......@@ -172,6 +172,7 @@ export default {
const {
bannerImg, course, orgdescs,
adCarousel,
classMoment,
} = yield select(state => state.officialweb);
const {
cropperUrl, filename, uploadtype, orgType, orgIndex, imgIndex, action,
......@@ -252,6 +253,17 @@ export default {
adCarousel: [...adCarousel],
},
});
} else if (uploadtype == 'uploadClassMomentImg') {
classMoment[imgIndex].content.push({
type: 'img',
value: `${filename}?x-oss-process=${cropperUrl}`,
});
yield put({
type: 'officialweb/updateState',
payload: {
classMoment: [...classMoment],
},
});
}
},
* unloadstates({ payload }, { call, put }) { // 释放该页面存储的所有状态
......
......@@ -12,7 +12,7 @@ import {
Divider,
Switch,
TimePicker,
Collapse,
Tooltip,
DatePicker,
Select, Radio, InputNumber, Input, message, Table,
} from 'antd';
......@@ -152,12 +152,15 @@ class SuccessStoreForm extends React.Component {
},
});
}
exportExcelStudent = (columns) => {
exportExcelStudent = (columns, subject_id, checkpoint_id) => {
const { dispatch } = this.props;
dispatch({
type: 'createtheme/exportStudentExcel',
payload: {
columns,
subject_id,
subject_type: 3,
checkpoint_id,
},
});
}
......@@ -185,6 +188,63 @@ class SuccessStoreForm extends React.Component {
previewQrcode,
downloadTitle,
} = this.props;
const exportColumns = [
{
title: '微信昵称',
dataIndex: 'wechat_user',
key: 'wechat_user',
},
{
title: '闯关数',
dataIndex: 'unlock_count',
key: 'unlock_count',
},
{
title: '被点评',
dataIndex: 'review_count',
key: 'review_count',
},
{
title: '点评分数',
dataIndex: 'review_score',
key: 'review_score',
},
{
title: '被点赞',
dataIndex: 'passive_like_count',
key: 'passive_like_count',
},
{
title: '精选数量',
dataIndex: 'place_top_at_count',
key: 'place_top_at_count',
},
{
title: '积分数',
dataIndex: 'integral_count',
key: 'integral_count',
},
{
title: '分享数',
dataIndex: 'share_count',
key: 'share_count',
},
{
title: '姓名',
dataIndex: 'name',
key: 'name',
},
{
title: '手机号',
dataIndex: 'mobile',
key: 'mobile',
},
{
title: '信息收集',
dataIndex: 'value',
key: 'value',
},
];
const columns = [
{
title: '关卡名称',
......@@ -235,6 +295,8 @@ class SuccessStoreForm extends React.Component {
render: (text, record, index) => {
return (
<div>
<span className="hreflink" onClick={() => this.exportExcelStudent(exportColumns, emigratedObj.id, record.id)}>导出数据</span>
<Divider type="vertical" />
<span className="hreflink" onClick={() => this.edit(record)}>编辑</span>
<Divider type="vertical" />
<span className="hreflink" onClick={() => this.delete(record)}>删除</span>
......@@ -243,79 +305,6 @@ class SuccessStoreForm extends React.Component {
},
},
];
const exportColumns = [
{
title: '微信昵称',
dataIndex: 'wechat_user',
key: 'wechat_user',
render: (text, record) => {
return (
<span>{ record.wechat_user && record.wechat_user.nickname ? record.wechat_user.nickname : '-' }</span>
);
},
},
{
title: '闯关数',
dataIndex: 'unlock_count',
key: 'unlock_count',
},
{
title: '被点评',
dataIndex: 'review_count',
key: 'review_count',
},
{
title: '点评分数',
dataIndex: 'review_score',
key: 'review_score',
},
{
title: '被点赞',
dataIndex: 'passive_like_count',
key: 'passive_like_count',
},
{
title: '精选数量',
dataIndex: 'place_top_at_count',
key: 'place_top_at_count',
},
{
title: '带来访客',
dataIndex: 'total_share_uv',
key: 'total_share_uv',
},
{
title: '姓名',
dataIndex: 'name',
key: 'name',
render: (text, record) => {
return (
<span>{ record.infoCollection && record.infoCollection.name ? record.infoCollection.name : '-' }</span>
);
},
},
{
title: '手机号',
dataIndex: 'mobile',
key: 'mobile',
render: (text, record) => {
return (
<span>{ record.infoCollection && record.infoCollection.mobile ? record.infoCollection.mobile : '-' }</span>
);
},
},
{
title: '信息收集',
dataIndex: 'value',
key: 'value',
render: (text, record) => {
return (
<span>{ record.subjectStudent && record.subjectStudent.content ? JSON.parse(record.subjectStudent.content).value : '-' }</span>
);
},
},
];
return (
<div className={pageStyle.container}>
<div className={pageStyle.head}>
......@@ -327,7 +316,7 @@ class SuccessStoreForm extends React.Component {
</div>
</div>
<div>
<span className="hreflink" onClick={() => this.exportExcelStudent(exportColumns)}>导出数据</span>
<span className="hreflink" onClick={() => this.exportExcelStudent(exportColumns, emigratedObj.id, 0)}><Tooltip title="导出全部关卡数据">导出数据</Tooltip></span>
<Divider type="vertical" />
<span className="hreflink" onClick={() => this.handleRemark(emigratedObj)}>点评作业</span>
<Divider type="vertical" />
......
......@@ -251,6 +251,17 @@ class LiveClass extends React.Component {
},
});
}
exportExcelStudent = (columns, subject_id, subject_type) => {
const { dispatch } = this.props;
dispatch({
type: 'createtheme/exportStudentExcel',
payload: {
columns,
subject_id,
subject_type,
},
});
}
render() {
const {
userPermission,
......@@ -262,6 +273,115 @@ class LiveClass extends React.Component {
downloadTitle,
classList,
} = this.props;
const exportJobColumns = [
{
title: '微信昵称',
dataIndex: 'wechat_user',
key: 'wechat_user',
},
{
title: '被点评',
dataIndex: 'review_count',
key: 'review_count',
},
{
title: '点评分数',
dataIndex: 'review_score',
key: 'review_score',
},
{
title: '被点赞',
dataIndex: 'passive_like_count',
key: 'passive_like_count',
},
{
title: '精选数量',
dataIndex: 'place_top_at_count',
key: 'place_top_at_count',
},
{
title: '积分数',
dataIndex: 'integral_count',
key: 'integral_count',
},
{
title: '分享数',
dataIndex: 'share_count',
key: 'share_count',
},
{
title: '姓名',
dataIndex: 'name',
key: 'name',
},
{
title: '手机号',
dataIndex: 'mobile',
key: 'mobile',
},
{
title: '信息收集',
dataIndex: 'value',
key: 'value',
},
];
const exportColumns = [
{
title: '微信昵称',
dataIndex: 'wechat_user',
key: 'wechat_user',
},
{
title: '打卡天数',
dataIndex: 'unlock_count',
key: 'unlock_count',
},
{
title: '被点评',
dataIndex: 'review_count',
key: 'review_count',
},
{
title: '点评分数',
dataIndex: 'review_score',
key: 'review_score',
},
{
title: '被点赞',
dataIndex: 'passive_like_count',
key: 'passive_like_count',
},
{
title: '精选数量',
dataIndex: 'place_top_at_count',
key: 'place_top_at_count',
},
{
title: '积分数',
dataIndex: 'integral_count',
key: 'integral_count',
},
{
title: '分享数',
dataIndex: 'share_count',
key: 'share_count',
},
{
title: '姓名',
dataIndex: 'name',
key: 'name',
},
{
title: '手机号',
dataIndex: 'mobile',
key: 'mobile',
},
{
title: '信息收集',
dataIndex: 'value',
key: 'value',
},
];
const columns = [
{
title: '打卡名称',
......@@ -335,6 +455,10 @@ class LiveClass extends React.Component {
<div className={pageStyle.tableoperatebox}>
<span className="hreflink" onClick={() => this.editTheme(record)}>{record.subject_type == 3 ? '查看详情' : '编辑'}</span>
<Divider type="vertical" />
{
record.subject_type != 3 &&
<span className="hreflink" onClick={() => this.exportExcelStudent(record.subject_type == 1 ? exportJobColumns : exportColumns, record.id, record.subject_type)}>导出数据<Divider type="vertical" /></span>
}
{
record.subject_type != 3 &&
<span className="hreflink" onClick={() => this.copyClockMgt(record, 1)}>复制<Divider type="vertical" /></span>
......
......@@ -16,6 +16,10 @@ import AdCarousel from './pagecomponent/AdCarousel';
import AdCarouselEditor from './pagecomponent/AdCarouselEditor';
import ClassMoments from './pagecomponent/ClassMoments';
import ClassMomentsEditor from './pagecomponent/ClassMomentsEditor';
import OnlineClass from './pagecomponent/OnlineClass';
import OnlineClassEditor from './pagecomponent/OnlineClassEditor';
import TogetherClock from './pagecomponent/TogetherClock';
import TogetherClockEditor from './pagecomponent/TogetherClockEditor';
import Cropper from '../../components/Cropper';
class Officialweb extends React.Component {
componentDidMount() { // 挂载
......@@ -299,6 +303,60 @@ class Officialweb extends React.Component {
</div>
);
break;
case 'onlineclass':
renderDom = (
<div className={pageStyle.box} key={ele.type}>
<div
className={`${pageStyle.ContentBox} ${index == moduleSelect ? pageStyle.moduleSelect : ''}`}
key={ele.type}
onClick={event => this.moduleSelect(index, event)}
>
<OnlineClass />
{dragoverindex == index && <div className={pageStyle.dropendbox}>松开鼠标,模块会放在这里</div>}
</div>
{moduleSelect == index &&
<div className={pageStyle.blockOperateBox}>
{index == 6 && <div className={`${pageStyle.blockOperateItem} ${pageStyle.blockOperateItemGrey}`}><Icon className={pageStyle.blockOperateItemIcon} type="arrow-up" /></div>}
{index > 6 && <div className={pageStyle.blockOperateItem} onClick={() => this.pageBlockMove(index, 'up')}><Icon className={pageStyle.blockOperateItemIcon} type="arrow-up" /></div>}
{index < (newPageInfo.length - 1) && <div className={pageStyle.blockOperateItem} onClick={() => this.pageBlockMove(index, 'down')}><Icon className={pageStyle.blockOperateItemIcon} type="arrow-down" /></div>}
{index == (newPageInfo.length - 1) && <div className={`${pageStyle.blockOperateItem} ${pageStyle.blockOperateItemGrey}`}><Icon className={pageStyle.blockOperateItemIcon} type="arrow-down" /></div>}
</div>
}
{moduleSelect == index &&
<div className={pageStyle.editbox}>
<OnlineClassEditor />
</div>
}
</div>
);
break;
case 'togetherclock':
renderDom = (
<div className={pageStyle.box} key={ele.type}>
<div
className={`${pageStyle.ContentBox} ${index == moduleSelect ? pageStyle.moduleSelect : ''}`}
key={ele.type}
onClick={event => this.moduleSelect(index, event)}
>
<TogetherClock />
{dragoverindex == index && <div className={pageStyle.dropendbox}>松开鼠标,模块会放在这里</div>}
</div>
{moduleSelect == index &&
<div className={pageStyle.blockOperateBox}>
{index == 6 && <div className={`${pageStyle.blockOperateItem} ${pageStyle.blockOperateItemGrey}`}><Icon className={pageStyle.blockOperateItemIcon} type="arrow-up" /></div>}
{index > 6 && <div className={pageStyle.blockOperateItem} onClick={() => this.pageBlockMove(index, 'up')}><Icon className={pageStyle.blockOperateItemIcon} type="arrow-up" /></div>}
{index < (newPageInfo.length - 1) && <div className={pageStyle.blockOperateItem} onClick={() => this.pageBlockMove(index, 'down')}><Icon className={pageStyle.blockOperateItemIcon} type="arrow-down" /></div>}
{index == (newPageInfo.length - 1) && <div className={`${pageStyle.blockOperateItem} ${pageStyle.blockOperateItemGrey}`}><Icon className={pageStyle.blockOperateItemIcon} type="arrow-down" /></div>}
</div>
}
{moduleSelect == index &&
<div className={pageStyle.editbox}>
<TogetherClockEditor />
</div>
}
</div>
);
break;
case 'course':
renderDom = (
<div className={pageStyle.box} key={ele.type}>
......@@ -315,19 +373,6 @@ class Officialweb extends React.Component {
/>
{dragoverindex == index && <div className={pageStyle.dropendbox}>松开鼠标,模块会放在这里</div>}
</div>
{/* moduleSelect == index &&
<div className={pageStyle.blockOperateBox}>
{index == 2 && <div className={`${pageStyle.blockOperateItem} ${pageStyle.blockOperateItemGrey}`}><Icon className={pageStyle.blockOperateItemIcon} type="arrow-up" /></div>}
{index > 2 && <div className={pageStyle.blockOperateItem} onClick={() => this.pageBlockMove(index, 'up')}><Icon className={pageStyle.blockOperateItemIcon} type="arrow-up" /></div>}
{index < (newPageInfo.length - 1) && <div className={pageStyle.blockOperateItem} onClick={() => this.pageBlockMove(index, 'down')}><Icon className={pageStyle.blockOperateItemIcon} type="arrow-down" /></div>}
{index == (newPageInfo.length - 1) && <div className={`${pageStyle.blockOperateItem} ${pageStyle.blockOperateItemGrey}`}><Icon className={pageStyle.blockOperateItemIcon} type="arrow-down" /></div>}
</div>
*/}
{/* moduleSelect == index &&
<div className={pageStyle.editbox}>
<CourseEditor />
</div>
*/}
</div>
);
break;
......
import React from 'react';
import { connect } from 'dva';
import { Form, Layout, Input, Button, Icon, DatePicker, Modal, Popconfirm } from 'antd';
import { videoPoster, imagify } from '../../../utils/index';
import { Form, Layout, Input, Button, Icon, DatePicker, Modal, Popconfirm, Progress } from 'antd';
import { videoPoster, imagify, ossVideofy } from '../../../utils/index';
import PageStyle from './ClassMomentsEditor.less';
import pageStyle from '../../newtheme/ThemeEditor.less';
const FormItem = Form.Item;
const { Sider } = Layout;
class ClassMomentsEditor extends React.Component {
......@@ -37,133 +38,114 @@ class ClassMomentsEditor extends React.Component {
}
componentWillUnmount() {
}
uploadAvator = (e) => {
}
selectedMenu = (key) => {
const { dispatch } = this.props;
dispatch({
type: 'webapp/menuselected',
payload: key,
});
}
bannerTypeChoose = (type) => {
const { dispatch } = this.props;
dispatch({
type: 'officialweb/bannertypechoose',
payload: {
type,
},
});
}
delvideo = () => {
const { dispatch } = this.props;
dispatch({
type: 'officialweb/delvideo',
});
}
handleSubmit = (e) => {
const { dispatch } = this.props;
e.preventDefault();
dispatch({
type: 'officialweb/bannersave',
});
}
delbannerimg = (index) => {
const { dispatch } = this.props;
dispatch({
type: 'officialweb/delbannerimg',
payload: {
index,
},
});
}
movebannerimg = (index, direction) => {
const { dispatch } = this.props;
dispatch({
type: 'officialweb/movebannerimg',
payload: {
index,
direction,
},
});
}
handleClassMomentPlate = (type) => {
handleClassMomentPlate = () => {
const { dispatch } = this.props;
dispatch({
type: 'officialweb/handleClassMomentPlate',
payload: {
type,
},
});
setTimeout(() => {
const element = document.getElementById('listbox');
element.scrollTop = element.scrollHeight;
}, 200);
}
uploadAdBanner = (e, index) => {
uploadClassMomentImg = (e, index) => {
const { dispatch } = this.props;
const { avatorUploader } = this.state;
dispatch({
type: 'uploader/queryimgsignature',
payload: {
files: e.target,
uploadtype: 'uploadAdBanner',
uploadtype: 'uploadClassMomentImg',
avatorUploader,
imgIndex: index,
},
});
}
handleChangeAdText = (e, index, key) => {
deleteClassMomentImg = (index, sort) => {
const { dispatch } = this.props;
dispatch({
type: 'officialweb/handleChangeAdText',
type: 'officialweb/deleteClassMomentImg',
payload: {
value: e.target.value,
index,
key,
sort,
},
});
}
deleteAdBanner = (index) => {
handleChangeMomentText = (e, index) => {
const { dispatch } = this.props;
dispatch({
type: 'officialweb/deleteAdBanner',
type: 'officialweb/handleChangeMomentText',
payload: {
value: e.target.value,
index,
},
});
}
deleteAdCarouselPlate = (index) => {
deleteClassMomentPlate = (index) => {
const { dispatch } = this.props;
dispatch({
type: 'officialweb/deleteAdCarouselPlate',
type: 'officialweb/deleteClassMomentPlate',
payload: {
index,
},
});
}
moveAdCarouselPlate = (index, direction) => {
moveClassMomentPlate = (index, direction) => {
const { dispatch } = this.props;
dispatch({
type: 'officialweb/moveAdCarouselPlate',
type: 'officialweb/moveClassMomentPlate',
payload: {
index,
direction,
},
});
}
saveAdCarouselPlate = () => {
saveClassMomentPlate = () => {
const { dispatch } = this.props;
dispatch({
type: 'officialweb/saveAdCarouselPlate',
payload: {
},
type: 'officialweb/saveClassMomentPlate',
});
}
uploadCommon = (e, index) => {
const REGEXP_VIDEO = /^video\/\w+/;
const REGEXP_IMG = /^image\/\w+/;
const { files } = e.target;
const { dispatch } = this.props;
if (files && files[0] && REGEXP_VIDEO.test(files[0].type)) {
dispatch({
type: 'officialweb/queryvideosignature',
payload: {
files: e.target,
uploadtype: 'uploadClassMomentVideo',
orgIndex: index,
progressCallBack(res) {
dispatch({
type: 'officialweb/updateState',
payload: {
progressRate: ((res.loaded / res.total) * 100).toFixed(0),
},
});
},
},
});
} else if (files && files[0] && REGEXP_IMG.test(files[0].type)) {
const { avatorUploader } = this.state;
dispatch({
type: 'uploader/queryimgsignature',
payload: {
files: e.target,
uploadtype: 'uploadClassMomentImg',
avatorUploader,
imgIndex: index,
},
});
}
}
render() {
const {
classMoment,
classMomentStatus,
progressRate,
} = this.props;
const formItemLayout = {
labelCol: {
......@@ -175,8 +157,15 @@ class ClassMomentsEditor extends React.Component {
sm: { span: 20 },
},
};
console.log(classMoment, '11111');
return (
<div className={`${PageStyle.SchoolInfoEditorcontainer} SchoolInfoEditorcontainer`}>
{progressRate && progressRate > 0 ?
<div className={pageStyle.progressWrap}>
<Progress width={150} type="circle" percent={progressRate} />
<p> {progressRate == 100 ? '上传成功' : '上传中。。。'}</p>
</div> : ''
}
<div className={PageStyle.header}><span>课堂瞬间 </span><p>支持上传图片或视频,前四个视频/图片将在微官网首页【课堂瞬间】展示</p></div>
<div className={PageStyle.FormBox} id="listbox">
{
......@@ -185,52 +174,66 @@ class ClassMomentsEditor extends React.Component {
<div className={PageStyle.formItem}>
<div className={PageStyle.formLeft}>
{index == 0 && <div className={`${PageStyle.formItemIcon} ${PageStyle.formItemIconGray}`}><Icon className={PageStyle.itemIcon} type="arrow-up" /></div>}
{ index > 0 && <div className={PageStyle.formItemIcon} onClick={() => this.moveAdCarouselPlate(index, 'up')}><Icon className={PageStyle.itemIcon} type="arrow-up" /></div> }
{ index > 0 && <div className={PageStyle.formItemIcon} onClick={() => this.moveClassMomentPlate(index, 'up')}><Icon className={PageStyle.itemIcon} type="arrow-up" /></div> }
{index == (classMoment.length - 1) && <div className={`${PageStyle.formItemIcon} ${PageStyle.formItemIconGray}`}><Icon className={PageStyle.itemIcon} type="arrow-down" /></div>}
{index < (classMoment.length - 1) && <div className={PageStyle.formItemIcon} onClick={() => this.moveAdCarouselPlate(index, 'down')}><Icon className={PageStyle.itemIcon} type="arrow-down" /></div>}
{index < (classMoment.length - 1) && <div className={PageStyle.formItemIcon} onClick={() => this.moveClassMomentPlate(index, 'down')}><Icon className={PageStyle.itemIcon} type="arrow-down" /></div>}
<Popconfirm
placement="topLeft"
title="确定删除?"
okText="确定"
cancelText="取消"
onConfirm={() => this.deleteAdCarouselPlate(index)}
onConfirm={() => this.deleteClassMomentPlate(index)}
>
<div className={PageStyle.formItemIcon}><Icon className={PageStyle.itemIcon} type="delete" /></div>
</Popconfirm>
</div>
<div className={PageStyle.formRight}>
<div className={PageStyle.formRightImg}>
{
item.content.length > 0 && item.content.map((ele, i) => {
return (
<div className={PageStyle.imgList}>
<div className={PageStyle.imgItem}>
<img src={imagify(ele.value)} alt="图片" />
<div className={PageStyle.closeAdIcon} onClick={() => this.deleteAdBanner(index)}>
<Icon type="close" />
</div>
</div>
</div>
);
})
}
{
item.content.length <= 4 &&
<React.Fragment>
<input
type="file"
className={PageStyle.uploadInput}
accept="image/png, image/jpeg"
id="upload1"
onChange={(e) => { this.uploadAdBanner(e, index); }}
/>
<span>点击上传({item.content.length}/4)</span>
</React.Fragment>
}
<div className={PageStyle.imgList}>
{
item.content && item.content.length > 0 && item.content.map((ele, i) => {
switch (ele.type) {
case 'img':
return (
<div className={PageStyle.imgItem}>
<img className={PageStyle.img} src={imagify(ele.value)} alt="图片" />
<div className={PageStyle.closeAdIcon} onClick={() => this.deleteClassMomentImg(index, i)}>
<Icon type="close" />
</div>
</div>
);
case 'video':
return (
<div className={PageStyle.imgItem}>
<video className={PageStyle.img} controls="controls" src={ossVideofy(ele.value)} />
<div className={PageStyle.closeAdIcon} onClick={() => this.deleteClassMomentImg(index, i)}>
<Icon type="close" />
</div>
</div>
);
default:
return '';
}
})
}
{
item.content.length < 4 &&
<div className={PageStyle.formItemInputBox}>
<input
type="file"
className={PageStyle.uploadInput}
accept="image/png, image/jpeg, video/mp4,video/*"
id="uploadCommon"
onChange={(e) => { this.uploadCommon(e, index); }}
/>
<span>点击上传({item.content.length}/4)</span>
</div>
}
</div>
</div>
<div className={PageStyle.formRightItem}>
<FormItem {...formItemLayout} label="标题">
<Input value={item.title} onChange={e => this.handleChangeAdText(e, index, 'title')} placeholder="请输入课堂瞬间标题" />
<Input value={item.title} onChange={e => this.handleChangeMomentText(e, index)} placeholder="请输入课堂瞬间标题" />
</FormItem>
</div>
</div>
......@@ -239,15 +242,15 @@ class ClassMomentsEditor extends React.Component {
})
}
</div>
<div className={PageStyle.addPlate} >
发布课堂瞬间({classMoment.length}/20
<div className={PageStyle.AddFloatbox}>
<div className={`${PageStyle.AddItem} ${PageStyle.AddVideoItem}`} onClick={() => this.handleClassMomentPlate(1)}>添加视频</div>
<div className={`${PageStyle.AddItem} ${PageStyle.AddImgItem}`} onClick={() => this.handleClassMomentPlate(2)}>添加图片</div>
</div>
<div className={PageStyle.addPlate} onClick={this.handleClassMomentPlate}>
添加课堂瞬间({classMoment.length}/20
{/* <div className={PageStyle.AddFloatbox}> */}
{/* <div className={`${PageStyle.AddItem} ${PageStyle.AddImgItem}`} onClick={() => this.handleClassMomentPlate(1)}>添加图片</div> */}
{/* <div className={`${PageStyle.AddItem} ${PageStyle.AddVideoItem}`} onClick={() => this.handleClassMomentPlate(2)}>添加视频</div> */}
{/* </div> */}
</div>
<div className={PageStyle.btnbox}>
<Button type="primary" htmlType="submit" className={PageStyle.SubmitBtn} loading={classMomentStatus} onClick={this.saveAdCarouselPlate}>{classMomentStatus ? '保存中...' : '保存'}</Button>
<Button type="primary" htmlType="submit" className={PageStyle.SubmitBtn} loading={classMomentStatus} onClick={this.saveClassMomentPlate}>{classMomentStatus ? '保存中...' : '保存'}</Button>
</div>
</div>
);
......@@ -260,10 +263,12 @@ function mapStateToProps(state) {
const {
classMoment,
classMomentStatus,
progressRate,
} = state.officialweb;
return {
classMoment,
classMomentStatus,
progressRate,
};
}
export default connect(mapStateToProps)(ClassMomentsEditor);
......@@ -66,48 +66,64 @@
width: 350px;
}
.formRightImg {
width: 86px;
height: 86px;
position: relative;
border: 1px solid #979797;
margin-right: 15px;
display: flex;
align-items: center;
justify-content: center;
color: #0091FF;
text-align: center;
font-size: 14px;
margin-bottom: 15px;
.formItemTypeText {
font-size: 16px;
color: #000;
font-weight: 600;
margin-bottom: 10px;
}
.imgList {
width: 100%;
height: 100%;
margin-right: 10px;
display: flex;
align-items: center;
.imgItem {
width: 86px;
height: 86px;
margin-right: 10px;
position: relative;
.img {
width: 100%;
height: 100%;
display: block;
}
.closeAdIcon {
width: 30px;
height: 30px;
position: absolute;
right: 0;
top: 0;
color: #fff;
font-size: 20px;
cursor: pointer;
background-color: rgba(0,0,0,0.8);
line-height: 30px;
text-align: center;
}
}
}
.formItemInputBox {
position: relative;
width: 86px;
height: 86px;
border: 1px solid #979797;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
text-align: center;
.uploadInput {
position: absolute;
width: 100%;
height: 100%;
display: block;
left: 0;
top: 0;
opacity: 0;
z-index: 5;
}
}
.uploadInput {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
opacity: 0;
z-index: 5;
}
.closeAdIcon {
width: 30px;
height: 30px;
position: absolute;
right: 0;
top: 0;
color: #fff;
font-size: 20px;
cursor: pointer;
background-color: rgba(0,0,0,0.8);
line-height: 30px;
}
&>img {
width: 100%;
height: 100%;
......@@ -165,6 +181,7 @@
background-color: #fff;
border:1px dashed rgba(151,151,151,1);
margin-left: 75px;
cursor: pointer;
&:hover {
.AddFloatbox {
display: block;
......@@ -208,3 +225,23 @@
-webkit-transition: all .4s ease;
-o-transition: all .4s ease;
}
.progressWrap {
width: 300px;
height: 300px;
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #f1f1f1;
border-radius: 15px;
z-index: 9999;
&>p {
font-size: 18px;
margin-top: 30px;
color: #1e8bff;
}
}
import React from 'react';
import { connect } from 'dva';
import { Carousel, Icon } from 'antd';
import PageStyle from './OnlineClass.less';
import { ossVideofy, imagify, videoPoster } from '../../../utils/index';
class OnlineClass extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
componentWillMount() {
}
componentWillUnmount() {
}
render() {
const { banner } = this.props;
return (
<div className={PageStyle.Bannercontainer}>
在线课堂
</div>
);
}
}
OnlineClass.propTypes = {
};
function mapStateToProps(state) {
const {
menus, defaultMenu, collapsed,
} = state.webapp;
return {
menus,
defaultMenu,
collapsed,
};
}
export default connect(mapStateToProps)(OnlineClass);
import React from 'react';
import { connect } from 'dva';
import { Form, Layout, Transfer, Button, Icon, message, Modal, Popconfirm, Progress } from 'antd';
import { videoPoster, imagify, ossVideofy } from '../../../utils/index';
import PageStyle from './OnlineClassEditor.less';
const FormItem = Form.Item;
const { Sider } = Layout;
class OnlineClassEditor extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
componentWillMount() {
}
componentWillUnmount() {
}
saveOnlinePlate = () => {
const { dispatch } = this.props;
dispatch({
type: 'officialweb/saveOnlinePlate',
});
}
handleChangeOnline = (nextTargetKeys, direction, moveKeys) => {
if (nextTargetKeys.length > 4) {
message.error('首页只能推荐4个噢!', 0.5);
return;
}
const { dispatch } = this.props;
dispatch({
type: 'officialweb/updateState',
payload: {
onlineClassTargetKeys: [...nextTargetKeys],
},
});
};
render() {
const {
onlineClassList,
onlineClassStatus,
onlineClassTargetKeys,
} = this.props;
console.log(onlineClassTargetKeys, 'onlineClassTargetKeys');
return (
<div className={`${PageStyle.SchoolInfoEditorcontainer} SchoolInfoEditorcontainer`}>
<div className={PageStyle.header}><span>在线课堂 </span><p>您可以从课堂列表中最多选择4个课程在微官网首页【在线课堂】展示</p></div>
<div className={PageStyle.FormBox} id="listbox">
<div className={PageStyle.transferBox}>
<Transfer
dataSource={onlineClassList}
titles={['全部课堂', '首页推荐']}
onChange={this.handleChangeOnline}
targetKeys={onlineClassTargetKeys}
render={item => item.title}
rowKey={record => record.id}
showSearch
lazy
/>
</div>
</div>
<div className={PageStyle.btnbox}>
<Button type="primary" htmlType="submit" className={PageStyle.SubmitBtn} loading={onlineClassStatus} onClick={this.saveOnlinePlate}>{onlineClassStatus ? '保存中...' : '保存'}</Button>
</div>
</div>
);
}
}
OnlineClassEditor.propTypes = {
};
function mapStateToProps(state) {
const {
onlineClassList,
onlineClassStatus,
onlineClassTargetKeys,
} = state.officialweb;
return {
onlineClassList,
onlineClassStatus,
onlineClassTargetKeys,
};
}
export default connect(mapStateToProps)(OnlineClassEditor);
@import '../../../less/variables.less';
@images: '@{imagesroot}/webapp/';
.SchoolInfoEditorcontainer {
}
.header {
color: #000;
font-size: 14px;
&>span {
font-weight: 700;
line-height: 50px;
}
padding-left: 20px;
border-bottom: 1px solid rgba(0,0,0,0.05);
}
.FormBox {
padding-top: 30px;
padding-bottom: 30px;
max-height: 400px;
overflow-y: scroll;
}
.FormItemClass {
padding-left: 30px;
margin-bottom: 8px;
display: flex;
align-items: center;
}
.btnbox {
text-align: right;
padding: 14px 35px 12px 0;
.SubmitBtn {
height: 34px;
line-height: 34px;
background-color: #FFFFFF;
color: #000000;
font-size: 14px;
border: 1px solid #ECECEC;
&:hover {
background-color: #FFFFFF;
color: #000000;
font-size: 14px;
border: 1px solid #ECECEC;
}
&:active {
background-color: #FFFFFF;
color: #000000;
font-size: 14px;
border: 1px solid #ECECEC;
}
&:focus {
background-color: #FFFFFF;
color: #000000;
font-size: 14px;
border: 1px solid #ECECEC;
}
}
}
::-webkit-scrollbar {
width: 8px;
height: 10px;
background-color: rgba(0,0,0,0);
}
::-webkit-scrollbar-thumb {
border-radius: 6px;
background-color: rgba(0,0,0,.2);
transition: all .4s ease;
-moz-transition: all .4s ease;
-webkit-transition: all .4s ease;
-o-transition: all .4s ease;
}
.progressWrap {
width: 300px;
height: 300px;
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #f1f1f1;
border-radius: 15px;
z-index: 9999;
&>p {
font-size: 18px;
margin-top: 30px;
color: #1e8bff;
}
}
.transferBox {
margin-left: 27px;
margin-top: 20px;
background-color: #fff;
padding: 10px;
:global {
.ant-transfer-list {
width: 240px;
}
.ant-transfer-list-header {
border-top: 1px solid #e8e8e8;
}
}
}
import React from 'react';
import { connect } from 'dva';
import { Carousel, Icon } from 'antd';
import PageStyle from './TogetherClock.less';
import { ossVideofy, imagify, videoPoster } from '../../../utils/index';
class TogetherClock extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
componentWillMount() {
}
componentWillUnmount() {
}
render() {
const { banner } = this.props;
return (
<div className={PageStyle.Bannercontainer}>
一起打卡
</div>
);
}
}
TogetherClock.propTypes = {
};
function mapStateToProps(state) {
const {
menus, defaultMenu, collapsed,
} = state.webapp;
return {
menus,
defaultMenu,
collapsed,
};
}
export default connect(mapStateToProps)(TogetherClock);
import React from 'react';
import { connect } from 'dva';
import { Form, Layout, Transfer, Button, Icon, message, Modal, Popconfirm, Progress } from 'antd';
import { videoPoster, imagify, ossVideofy } from '../../../utils/index';
import PageStyle from './TogetherClockEditor.less';
const FormItem = Form.Item;
const { Sider } = Layout;
class TogetherClockEditor extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
componentWillMount() {
}
componentWillUnmount() {
}
saveClockPlate = () => {
const { dispatch } = this.props;
dispatch({
type: 'officialweb/saveClockPlate',
});
}
handleChangeClock = (nextTargetKeys, direction, moveKeys) => {
if (nextTargetKeys.length > 4) {
message.error('首页只能推荐4个噢!', 0.5);
return;
}
const { dispatch } = this.props;
dispatch({
type: 'officialweb/updateState',
payload: {
togetherClockTargetKeys: [...nextTargetKeys],
},
});
};
render() {
const {
togetherClockList,
togetherClockStatus,
togetherClockTargetKeys,
} = this.props;
return (
<div className={`${PageStyle.SchoolInfoEditorcontainer} SchoolInfoEditorcontainer`}>
<div className={PageStyle.header}><span>一起打卡 </span><p>您可以从打卡主题列表中最多选择4个主题在微官网首页【一起打卡】展示</p></div>
<div className={PageStyle.FormBox} id="listbox">
<div className={PageStyle.transferBox}>
<Transfer
dataSource={togetherClockList}
titles={['全部打卡', '首页推荐']}
onChange={this.handleChangeClock}
targetKeys={togetherClockTargetKeys}
render={item => item.title}
rowKey={record => record.id}
showSearch
lazy
/>
</div>
</div>
<div className={PageStyle.btnbox}>
<Button type="primary" htmlType="submit" className={PageStyle.SubmitBtn} loading={togetherClockStatus} onClick={this.saveClockPlate}>{togetherClockStatus ? '保存中...' : '保存'}</Button>
</div>
</div>
);
}
}
TogetherClockEditor.propTypes = {
};
function mapStateToProps(state) {
const {
togetherClockList,
togetherClockStatus,
togetherClockTargetKeys,
} = state.officialweb;
return {
togetherClockList,
togetherClockStatus,
togetherClockTargetKeys,
};
}
export default connect(mapStateToProps)(TogetherClockEditor);
@import '../../../less/variables.less';
@images: '@{imagesroot}/webapp/';
.SchoolInfoEditorcontainer {
}
.header {
color: #000;
font-size: 14px;
&>span {
font-weight: 700;
line-height: 50px;
}
padding-left: 20px;
border-bottom: 1px solid rgba(0,0,0,0.05);
}
.FormBox {
padding-top: 30px;
padding-bottom: 30px;
max-height: 400px;
overflow-y: scroll;
}
.FormItemClass {
padding-left: 30px;
margin-bottom: 8px;
display: flex;
align-items: center;
}
.btnbox {
text-align: right;
padding: 14px 35px 12px 0;
.SubmitBtn {
height: 34px;
line-height: 34px;
background-color: #FFFFFF;
color: #000000;
font-size: 14px;
border: 1px solid #ECECEC;
&:hover {
background-color: #FFFFFF;
color: #000000;
font-size: 14px;
border: 1px solid #ECECEC;
}
&:active {
background-color: #FFFFFF;
color: #000000;
font-size: 14px;
border: 1px solid #ECECEC;
}
&:focus {
background-color: #FFFFFF;
color: #000000;
font-size: 14px;
border: 1px solid #ECECEC;
}
}
}
::-webkit-scrollbar {
width: 8px;
height: 10px;
background-color: rgba(0,0,0,0);
}
::-webkit-scrollbar-thumb {
border-radius: 6px;
background-color: rgba(0,0,0,.2);
transition: all .4s ease;
-moz-transition: all .4s ease;
-webkit-transition: all .4s ease;
-o-transition: all .4s ease;
}
.progressWrap {
width: 300px;
height: 300px;
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #f1f1f1;
border-radius: 15px;
z-index: 9999;
&>p {
font-size: 18px;
margin-top: 30px;
color: #1e8bff;
}
}
.transferBox {
margin-left: 27px;
margin-top: 20px;
background-color: #fff;
padding: 10px;
:global {
.ant-transfer-list {
width: 240px;
}
.ant-transfer-list-header {
border-top: 1px solid #e8e8e8;
}
}
}
......@@ -119,3 +119,48 @@ export function adsSave(params) {
data,
});
}
export function momentList(params) {
const data = qs.stringify(params);
return request({
url: `${api.officaialweb.moments}?${data}`,
method: 'GET',
});
}
export function momentSave(params) {
const data = qs.stringify(params);
return request({
url: `${api.officaialweb.momentSave}`,
method: 'POST',
data,
});
}
export function onlineClassList(params) {
const data = qs.stringify(params);
return request({
url: `${api.officaialweb.onlineClass}?${data}`,
method: 'GET',
});
}
export function onlineClassSave(params) {
const data = qs.stringify(params);
return request({
url: `${api.officaialweb.onlineClassSave}`,
method: 'POST',
data,
});
}
export function subjectMixture(params) {
const data = qs.stringify(params);
return request({
url: `${api.officaialweb.subjectMixture}?${data}`,
method: 'GET',
});
}
export function subjectMixtureSave(params) {
const data = qs.stringify(params);
return request({
url: `${api.officaialweb.subjectMixtureSave}`,
method: 'POST',
data,
});
}
......@@ -40,16 +40,34 @@ function exportExcel(headers, data, fileName = 'XXX.xlsx', type) {
// eslint-disable-next-line array-callback-return
thisdata = data.map((item) => {
return {
wechat_user: item.wechat_user && item.wechat_user.nickname ? item.wechat_user.nickname : '',
unlock_count: item.unlock_count ? item.unlock_count : '-',
wechat_user: item.school_student && item.school_student.nickname ? item.school_student.nickname : '',
unlock_count: item.max_clock_count ? item.max_clock_count : '-',
review_count: item.review_count,
review_score: Number(item.review_score) / 5,
passive_like_count: item.passive_like_count,
passive_like_count: item.like_count,
place_top_at_count: item.place_top_at_count,
total_share_uv: item.total_share_uv,
name: item.subjectStudent && item.subjectStudent.name ? item.subjectStudent.name : '',
mobile: item.subjectStudent && item.subjectStudent.mobile ? item.subjectStudent.mobile : '',
value: item.subjectStudent && item.subjectStudent.content ? JSON.parse(item.subjectStudent.content).value : '',
integral_count: item.integral_count,
share_count: item.share_count,
name: item.name ? item.name : '',
mobile: item.mobile ? item.mobile : '',
value: item.content && item.content ? JSON.parse(item.content).value : '',
};
});
break;
case 'jobClockStudent':
// eslint-disable-next-line array-callback-return
thisdata = data.map((item) => {
return {
wechat_user: item.school_student && item.school_student.nickname ? item.school_student.nickname : '',
review_count: item.review_count,
review_score: Number(item.review_score) / 5,
passive_like_count: item.like_count,
place_top_at_count: item.place_top_at_count,
integral_count: item.integral_count,
share_count: item.share_count,
name: item.name ? item.name : '',
mobile: item.mobile ? item.mobile : '',
value: item.content && item.content ? JSON.parse(item.content).value : '',
};
});
break;
......
......@@ -25,7 +25,7 @@ axios.interceptors.request.use((config) => {
return Promise.reject(error);
});
// axios.defaults.timeout = 30000;
axios.defaults.timeout = 30000;
axios.defaults.timeout = 1000 * 60 * 2;
axios.defaults.retry = 1;
axios.defaults.retryDelay = 3000;
// Add a response interceptor
......
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