Commit 4ef073c8 by zhangleyuan

feat:修改创建课程

parent 93bfae68
/*
* @Author: louzhedong
* @Date: 2019-11-25 11:37:58
* @LastEditors: louzhedong
* @LastEditTime: 2019-11-25 11:37:58
* @Description:
*/
class XMEnum {
constructor(array) {
if (!Array.isArray(array)) {
throw 'array不是数组';
return;
}
array.map(item => {
this[item.name] = item;
})
}
}
export default XMEnum;
\ No newline at end of file
/*
* @Author: 吴文洁
* @Date: 2020-03-19 16:45:42
* @LastEditors: houyan
* @LastEditTime: 2020-06-24 11:24:54
* @Description:
*/
import XMEnum from './XMEnum';
export const HOME_WORK_TYPE = new XMEnum([
{
name: 'ONLY',
value: 'ONLY',
text: '单次(普通)',
},
{
name: 'EXAM',
value: 'EXAM',
text: '单次(测评)'
},
{
name: 'LOOP',
value: 'LOOP',
text: '连续(普通)'
}
])
export const RECORD_ERROR = new XMEnum([
{
name: 'NotAllowedError',
title: '请允许网页使用麦克风',
content: '麦克风已被禁用,请现在浏览器设置中允许当前望重使用你的麦克风'
},
{
name: 'PermissionDeniedError',
title: '请允许浏览器使用麦克风',
content: '麦克风已被禁用,请现在浏览器设置中允许使用麦克风'
},
{
name: 'NotFoundError',
title: '未找到麦克风设备',
content: '请确认麦克风是否可用'
},
{
name: 'DevicesNotFoundError',
title: '未找到麦克风设备',
content: '请确认麦克风是否可用'
},
{
name: 'NotSupportedError',
title: '设备不支持录音',
content: '该电脑暂不支持录音,请尝试使用其他设备'
}
]);
/*
* @Author: 吴文洁
* @Date: 2020-07-25 15:28:45
* @LastEditors: 吴文洁
* @LastEditTime: 2020-08-11 11:20:59
* @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
export const ORDER_TYPR_MAP = {
'CLASS': '上课扣费',
'RECORD': '录制扣费',
'RECHARGE': '充值',
'GIVE': '赠送',
'OTHER': '其他',
};
export const ORDER_DETAIL_TEXT_MAP = {
'RECORD': '录制扣费详情',
'CLASS': '上课扣费详情',
'RECHARGE': '充值详情',
'REFUND': '退款详情'
}
export const ORDER_STATUS_MAP = {
'PAY_UNDO': '待支付',
'PAY_SUCCESS': '已完成',
'PAY_CANCEL': '已失效'
}
export const ORDER_STATUS_COLOR_MAP = {
'PAY_SUCCESS': '#2FC83C',
'PAY_UNDO': '#FDBE31',
'PAY_CANCEL': '#CCCCCC',
}
export const PAT_TYPE_MAP = {
'ALI_PAY': '支付宝',
'WE_CHAT': '微信'
}
// 云课堂产品版本
export const CLOUD_CLASS_VERSION_MAP = {
'ULTIMATESELL': '旗舰版',
'PIP_TO_ULTIMATE': '标准版',
'HIGH_TO_ULTIMATE': '高级版'
}
export const LIVE_SHARE_MAP = {
dev: 'https://dev.xiaomai5.com/xiaomai-live-share/index.html#/',
rc: 'https://rc.xiaomai5.com/xiaomai-live-share/index.html#/',
gray: 'https://res.xiaomai5.com/xiaomai-live-share/gray/index.html#/',
prod: 'https://res.xiaomai5.com/xiaomai-live-share/index.html#/',
}
/*
* @Author: Michael
* @Date: 2020-02-10 10:08:39
* @Last Modified by: 吴文洁
* @Last Modified time: 2020-07-16 11:32:50
*/
const DEFAULT_SIZE_UNIT = 1000 * 1000; // 将B转换成M
const GIGABYTE_SIZE_UNIT = 1000 * 1000 * 1000; // 转换为G
const SupportFileType = [
"application/msword",
"text/csv",
"application/vnd.ms-excel",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"application/vnd.ms-powerpoint",
"application/pdf",
"image/jpeg",
"image/png",
"audio/mpeg",
"audio/mp4",
"video/mp4",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
"audio/mp3",
"application/wps-office.pdf",
"application/wps-office.xls"
];
const LocalFileType = [
"application/msword",
"application/vnd.ms-excel",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"application/vnd.ms-powerpoint",
"application/pdf",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
"application/wps-office.pdf",
"application/wps-office.xls"
]
const FileVerifyMap = {
"application/msword": {
type: "word",
maxSize: 10
},
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": {
type: "word",
maxSize: 10
},
"text/csv": {
type: "Excel",
maxSize: 10
},
"application/vnd.ms-excel": {
type: "Excel",
maxSize: 10
},
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": {
type: "Excel",
maxSize: 10
},
"application/wps-office.xls": {
type: "Excel",
maxSize: 10
},
"application/vnd.ms-powerpoint": {
type: "PPT",
maxSize: 20
},
"application/vnd.openxmlformats-officedocument.presentationml.presentation": {
type: "PPT",
maxSize: 20
},
"application/pdf": {
type: "PDF",
maxSize: 50
},
"application/wps-office.pdf": {
type: "PDF",
maxSize: 50
},
"image/jpeg": {
type: "JPG",
maxSize: 10
},
"image/png": {
type: "JPG",
maxSize: 10
},
"image/jpg": {
type: "JPG",
maxSize: 10
},
"image/gif": {
type: "GIF",
maxSize: 10
},
"audio/mpeg": {
type: "MP3",
maxSize: 50
},
"audio/mp3": {
type: "MP3",
maxSize: 50
},
"audio/mp4": {
type: "MP4",
maxSize: 50
},
"video/mp4": {
type: "MP4",
maxSize: 50
}
};
const LessonFileTypeEnum = {
TEACH_PLAN: "教案",
COURSEWARE: "课件",
HOMEWORK: "作业"
};
const FileTypeIcon = {
word: "https://image.xiaomaiketang.com/xm/6biwHTSPe5.png",
DOCX: "https://image.xiaomaiketang.com/xm/6biwHTSPe5.png",
DOC: "https://image.xiaomaiketang.com/xm/6biwHTSPe5.png",
DOCX: "https://image.xiaomaiketang.com/xm/6biwHTSPe5.png",
// 第一期备后端返回的是长的文件类型,备课版改版之后后端返回的是短的文件类型,且大写,所以做个兼容,下面的EXCEl也是一样的
WORD: "https://image.xiaomaiketang.com/xm/6biwHTSPe5.png",
Excel: "https://image.xiaomaiketang.com/xm/h6a6eF882a.png",
EXCEL: "https://image.xiaomaiketang.com/xm/h6a6eF882a.png",
PPT: "https://image.xiaomaiketang.com/xm/847pFAdYGW.png",
PPTX: "https://image.xiaomaiketang.com/xm/847pFAdYGW.png",
PDF: "https://image.xiaomaiketang.com/xm/rrEJMNkhTG.png",
MP3: "https://image.xiaomaiketang.com/xm/ykjnSWDyQ6.png",
MP4: "https://image.xiaomaiketang.com/xm/whSYMTdR57.png",
JPG: "https://image.xiaomaiketang.com/xm/XRkX8JBTPs.png",
JPEG: "https://image.xiaomaiketang.com/xm/XRkX8JBTPs.png",
PNG: "https://image.xiaomaiketang.com/xm/XRkX8JBTPs.png",
GIF: "https://image.xiaomaiketang.com/xm/XRkX8JBTPs.png",
BMP: "https://image.xiaomaiketang.com/xm/XRkX8JBTPs.png",
};
const UploadIcon = "https://image.xiaomaiketang.com/xm/4DXNrZWWsd.png";
const FailIcon = "https://image.xiaomaiketang.com/xm/ZkWbrrbiRn.png";
const StorageColor = {
blue: "#58B7EF",
yellow: "linear-gradient(to right, #FBD140, #FFA201)",
red: "#EC4B35"
};
const suffixMap = {
'doc': 'application/msword',
'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'ppt': 'application/vnd.ms-powerpoint',
'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'pdf': 'application/pdf',
'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'xls': 'application/vnd.ms-excel'
}
const DISK_MAP = {
MYSELF: '我的文件',
COMMON: '公共文件',
EMPLOYEE: '员工文件'
}
const NonCompliantFileMap = {
'video': {
accept: 'video/mp4',
confirm: {
title: '文件过大,无法上传',
content: '为保障学员的观看体验,上传的视频大小不能超过100M',
},
tooltip: '格式支持mp4,大小不超过100M'
}
}
export {
DEFAULT_SIZE_UNIT,
FileVerifyMap,
FileTypeIcon,
LessonFileTypeEnum,
UploadIcon,
FailIcon,
StorageColor,
GIGABYTE_SIZE_UNIT,
SupportFileType,
suffixMap,
LocalFileType,
DISK_MAP,
NonCompliantFileMap
};
/*
* @Author: 吴文洁
* @Date: 2020-07-23 17:11:49
* @LastEditors: 吴文洁
* @LastEditTime: 2020-07-23 17:14:32
* @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
const DEFAULT_SIZE_UNIT = 1024 * 1024; // 将B转换成M
const SupportFileType = [
"application/msword",
"application/vnd.ms-powerpoint",
"application/mspowerpoint",
"application/pdf",
"image/jpeg",
"audio/mpeg",
"audio/mp4",
"video/mp4",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
"audio/mp3",
"application/wps-office.pdf",
"audio/x-mpeg",
"image/png",
];
const suffixType = {
ppt: 'application/vnd.ms-powerpoint',
pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
doc: 'application/msword',
docx: 'application/msword',
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
xls: 'application/vnd.ms-excel',
pdf: 'application/pdf',
jpg: 'image/jpeg',
jpeg: 'image/jpeg',
png: 'image/png',
mp3: 'audio/mp3',
mp4: 'audio/mp4',
}
export default {
DEFAULT_SIZE_UNIT,
SupportFileType,
suffixType,
};
export const DEAL_TYPE = {
'NO': '未超上',
'UN_DEAL': '超上未处理',
'MAKE_UP': '补扣',
'IGNORE': '标记不处理'
};
export const OVERSTEP_TYPE = {
'CLASS_HOUR_OWE': '点名超上',
'MONTH_OWE': '按月超上',
'IMPORT_HOUR_OWE': '导入超上'
};
# 营销线相关常量
\ No newline at end of file
/*
* @Author: louzhedong
* @Date: 2019-11-25 11:40:53
* @LastEditors: louzhedong
* @LastEditTime: 2019-11-25 11:41:47
* @Description: 电子表单fieldProperty枚举
*/
import XMEnum from '../XMEnum';
const fieldProperty = new XMEnum([
{name: 'CUSTOM', code: -1},
{name: 'NAME', code: 1},
{name: 'PHONE', code: 2},
{name: 'GENDER', code: 3},
{name: 'AGE', code: 4},
{name: 'BIRTHDAY', code: 5},
{name: 'SCHOOL', code: 6},
{name: 'GRADE', code: 7},
{name: 'ADDRESS', code: 8},
]);
export default fieldProperty;
\ No newline at end of file
/*
* @Author: 吴文洁
* @Date: 2019-11-08 10:31:08
* @Last Modified by: 吴文洁
* @Last Modified time: 2020-02-25 15:50:21
礼品集市常量
*/
import Enum from '@/core/enum';
const OrderStateEnum = new Enum([{
key: 'PAY_WAITING',
value: '待付款',
icon: 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1573191434106.png?x-oss-process=image/resize,w_80,limit_0'
}, {
key: 'PAY_TIMEOUT',
value: '支付超时',
icon: 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1573191455406.png?x-oss-process=image/resize,w_80,limit_0'
}, {
key: 'WATING_AUDIT',
value: '待受理',
desc: '订单正在受理中,请耐心等待',
icon: 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1573191403102.png?x-oss-process=image/resize,w_80,limit_0'
}, {
key: 'PAY_SUCCESS',
value: '待受理',
desc: '订单正在受理中,请耐心等待',
icon: 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1573191403102.png?x-oss-process=image/resize,w_80,limit_0'
}, {
key: 'AUDIT_FAILED',
value: '受理失败',
icon: 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1574673840912.png?x-oss-process=image/resize,w_80,limit_0'
}, {
key: 'USER_CANCEL',
value: '已取消',
icon: 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1573191455406.png?x-oss-process=image/resize,w_80,limit_0'
}, {
key: 'WATING_DELIVER',
value: '待发货',
desc: '商品待发出,请耐心等待',
icon: 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1573191392327.png?x-oss-process=image/resize,w_80,limit_0'
}, {
key: 'FINISH_DELIVER',
value: '已发货',
desc: '商品已发出,正在快马加鞭的赶来~ ',
icon: 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1573191392327.png?x-oss-process=image/resize,w_80,limit_0'
}, {
key: 'RECEIVED',
value: '已完成',
desc: '本次交易已完成!',
icon: 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1573191420713.png?x-oss-process=image/resize,w_80,limit_0'
}]);
const RefundStateEnum = new Enum([{
key: 'WAITING_SURE',
value: '待确认',
}, {
key: 'REFUNDING',
value: '退款中',
}, {
key: 'REFUND_SUCCESS',
value: '退款成功',
}, {
key: 'REFUND_FAILED',
value: '退款失败',
}]);
const OrderStateMap = {
'PAY_WAITING': '待付款',
'USER_CANCEL': '已取消',
'WATING_DELIVER': '待发货',
'FINISH_DELIVER': '已发货',
'RECEIVED': '已完成',
'AUDIT_FAILED': '受理失败',
}
export {
OrderStateEnum,
RefundStateEnum,
OrderStateMap
}
\ No newline at end of file
/*
* @Author: 吴文洁
* @Date: 2019-09-25 18:07:33
* @Last Modified by: 吴文洁
* @Last Modified time: 2020-02-25 15:50:29
* @Descript: 会员宝相关常量
*/
import Enum from '@/core/enum';
const PointsExchangeStatus = new Enum([{
key: 'WATING_AUDIT',
id: 'WATING_AUDIT',
value: '待审核',
name: '待审核',
color: '#FF8534'
}, {
key: 'USER_CANCEL',
id: 'USER_CANCEL',
value: '已撤销',
name: '已撤销',
color: '#999'
}, {
key: 'WATING_DELIVER',
id: 'WATING_DELIVER',
value: '待发放',
name: '待发放',
color: '#58B7EF'
}, {
key: 'FINISH_DELIVER',
id: 'FINISH_DELIVER',
value: '已发放',
name: '已发放',
color: '#3BBDAA'
}]);
const orderStateMap = {
'WATING_AUDIT': '待审核',
'USER_CANCEL': '已撤销',
'WATING_DELIVER': '待发放',
'FINISH_DELIVER': '已发放'
}
export {
PointsExchangeStatus,
orderStateMap
}
\ No newline at end of file
/*
* @Author: 吴文洁
* @Date: 2020-02-25 15:56:03
* @Last Modified by: wufan
* @Last Modified time: 2020-07-09 12:07:14
微官网相关常量
*/
import XMEnum from '../XMEnum';
const marketingToolsTabNames = [{ type: 'show', name:'小麦秀' },{type: 'coupon',name:'优惠券'} ];
const TabNames = [
'brand', 'course', 'teacher', 'student',
'environment', 'activity', 'material', 'news'
];
const TextEnum = new XMEnum([
{
module: 'BRAND_INTRO',
name: 'brand',
tabLabel: '品牌介绍',
detailLabel: '机构详情',
placeholder: '请填写简介,30字以内',
coverUrl: 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1583836090586.png'
},
{
module: 'CAMPUS_ENVIRON',
name: 'environment',
tabLabel: '校区环境',
detailLabel: '校区详情',
placeholder: '请填写简介,30字以内',
coverUrl: 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1583836118436.png'
},
{
module: 'ACTIVITY_STYLE',
name: 'activity',
tabLabel: '活动风采',
nameLabel: '活动名称',
coverLabel: '活动封面',
detailLabel: '活动详情',
coverWidth: 156,
coverHeight: 80,
coverUrl: 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1583824443588.png'
},
{
module: 'HOT_COURSE',
name: 'course',
tabLabel: '热门课程',
nameLabel: '课程名称',
introLabel: '课程简介',
coverLabel: '课程封面',
detailLabel: '课程详情',
placeholder: '请填写课程简介,例如:针对4~8岁的孩子,重点培养的基础绘画技能、激发艺术表现。30字以内',
coverUrl: 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1583823404400.png'
},
{
module: 'FACULTY_TEAM',
name: 'teacher',
tabLabel: '师资团队',
nameLabel: '老师姓名',
introLabel: '老师简介',
coverLabel: '老师照片',
detailLabel: '老师详情',
placeholder: '请填写老师亮点,简短精炼,例如:5年教龄,名校毕业,平易近人。30字以内',
coverUrl: 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1583823414781.png'
},
{
module: 'STAR_STUDENT',
name: 'student',
tabLabel: '明星学员',
nameLabel: '学员姓名',
introLabel: '学员简介',
coverLabel: '学员照片',
detailLabel: '学员详情',
placeholder: '请填写学员简介/宣言,例如: 持之以恒,必将有好的收获。闪亮之星小阮的学习之旅~。30字以内',
coverUrl: 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1583823429407.png'
},
{
module: 'STUDY_MATERIALS',
name: 'material',
tabLabel: '学习资料',
nameLabel: '资料名称',
coverLabel: '资料封面',
detailLabel: '资料详情',
coverWidth: 156,
coverHeight: 80,
coverUrl: 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1583823443748.png'
},
{
module: 'NEWS',
name: 'news',
tabLabel: '新闻动态',
nameLabel: '新闻标题',
coverLabel: '新闻封面',
detailLabel: '新闻详情',
coverUrl: 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1583823455499.png'
},
])
export default TextEnum;
export {
TabNames,
marketingToolsTabNames
}
\ No newline at end of file
/*
* @Author: 吴文洁
* @Date: 2019-09-25 18:09:07
* @Last Modified by: wufan
* @Last Modified time: 2020-07-11 13:48:57
* @Description: 小麦秀相关常量
*/
const isRc = location.host.indexOf('rc') !== -1;
const isDev = location.host.indexOf('localhost') !== -1 || location.host.indexOf('dev.xiaomai5.com') !== -1;
const isGray = location.href.indexOf('gray') !== -1;
const isDev1 = location.href.indexOf('dev1') !== -1;
let host = 'https://dev.xiaomai5.com/show/';
let latestHost = 'https://dev.xiaomai5.com/xmshow/#/';
if (isDev) {
host = 'https://dev.xiaomai5.com/show/';
latestHost = 'https://dev.xiaomai5.com/xmshow/#/';
} else if (isDev1) {
host = 'https://dev1.xiaomai5.com/show/';
latestHost = 'https://dev1.xiaomai5.com/xmshow/#/';
} else if (isRc) {
host = 'https://rc.xiaomai5.com/show/';
latestHost = 'https://rc.xiaomai5.com/xmshow/#/';
} else if (isGray) {
host = 'https://res.xiaomai5.com/show/';
latestHost = 'https://res.xiaomai5.com/xmshow/gray/index.html#/';
} else {
host = 'https://res.xiaomai5.com/show/';
latestHost = 'https://res.xiaomai5.com/xmshow/index.html#/';
}
export const HOST = host;
export const LATESTHOST = latestHost;
export const IS_DEV = isDev;
export const IS_DEV1 = isDev1;
export const IS_RC = isRc;
export const IS_GRAY = isGray;
export const TEMPLATE_TYPE = {
'groupType': '团购',
'lessonType': '微传单',
'bargainType': '砍价',
'tyType': '集赞',
'solitaireType': '群接龙',
'redPackageType': '微游戏',
'rollType': '抽奖',
'voteType': '投票',
'gachaType':'扭蛋机',
'distributeType': '分销'
};
export const TAG_TYPE = {
'holiday': '节假日',
'spring': '春招',
'summer': '夏招',
'autumn': '秋招',
'winter': '冬招',
'keepClass': '续班',
'lesson': '体验课',
'other': '其他'
};
// 活动参与详情年级常量
export const GRADE = [
{ label: "学前", value: 1004 },
{ label: "小班", value: 1001 },
{ label: "中班", value: 1002 },
{ label: "大班", value: 1003 },
{ label: "小学", value: 7 },
{ label: "一年级", value: 1 },
{ label: "二年级", value: 2 },
{ label: "三年级", value: 3 },
{ label: "四年级", value: 4 },
{ label: "五年级", value: 5 },
{ label: "六年级", value: 6 },
{ label: "初中", value: 14 },
{ label: "初中一年级", value: 11 },
{ label: "初中二年级", value: 12 },
{ label: "初中三年级", value: 13 },
{ label: "高中", value: 104 },
{ label: "高中一年级", value: 101 },
{ label: "高中二年级", value: 102 },
{ label: "高中三年级", value: 103 }
];
// 活动参与详情性别常量
export const GENDER = [
{ label: "男", value: 1 },
{ label: "女", value: 2 }
];
export const SCENE_LIST = [
{
name: "全部",
val: "all",
active: true
},
{
name: "节假日",
val: "holiday"
},
{
name: "春招",
val: "spring"
},
{
name: "夏招",
val: "summer"
},
{
name: "秋招",
val: "autumn"
},
{
name: "冬招",
val: "winter"
},
{
name: "续班",
val: "keepClass"
},
{
name: "体验课",
val: "lesson"
},
{
name: "其他",
val: "other"
}
];
export const TYPE_LIST = [
{
name: "全部",
val: "all",
active: true
},
{
name: "微传单",
val: "lessonType"
},
{
name: "砍价",
val: "bargainType"
},
{
name: "团购",
val: "groupType"
},
{
name: "群接龙",
val: "solitaireType"
},
{
name: "集赞",
val: "tyType"
},
{
name: "微游戏",
val: "redPackageType"
},
{
name: "抽奖",
val: "rollType"
},
{
name: "投票",
val: "voteType"
},
{
name: "扭蛋机",
val: "gachaType"
},
{
name: '分销',
val: 'distributeType'
}
];
export const SHOW_STATUS = {
'IN_PROGRESS': {
status: 'IN_PROGRESS',
label: '进行中',
color:"rgba(47,200,60,1)"
},
'ENDED':{
status: 'ENDED',
label: '已结束',
color:"rgba(204,204,204,1)"
},
'IN_VALID': {
status: 'IN_VALID',
label: '已失效',
color:"rgba(204,204,204,1)"
},
'DELETED':{
status: 'DELETED',
label: '已删除',
color:"rgba(204,204,204,1)"
}
};
\ No newline at end of file
/*
* @Author: 陈剑宇
* @Date: 2020-10-28 14:27:07
* @LastEditTime: 2020-11-02 20:25:15
* @LastEditors: 陈剑宇
* @Description:
* @FilePath: /xiaomai-web-b/app/common/constants/punchClock/punchClock.js
* @symbol_custom_string_obkoro1: Copyright © 2020 杭州杰竞科技有限公司 版权所有
*/
export const DEFAULT_IMG_URL = 'https://image.xiaomaiketang.com/xm/2MWCKBNiya.png';
export const DEFAULT_CALENDAR_TEXT = '<p>亲爱的同学:</p><p>欢迎参加《麦麦教育0基础21天英语打卡活动》,大家都知道21天养成一个好习惯。在未来的21天里,老师将和同学们一起完成21个打卡任务,0基础锻炼口语发音能力,让听英语并且跟读英语成为生活中的一部分。</p><p>打卡时间:2020年6月1日-6月23日(共21天)</p><p>其中休息日:6月6日、6月7日</p><p>打卡任务:坚持21天英语打卡学习,并且分享至朋友圈</p><p>分享格式:麦麦教育0基础21天英语打卡+学生名字 +第X天 +坚持就是胜利!</p><p>打卡奖励:</p><p>①坚持完成“21天打卡”的宝贝可以获得精美小礼品!</p><p>②每天分享打卡任务到朋友圈的小宝贝,还可以获得一份大礼包哦~</p><p>老师有话说:小宝贝每天只可完成1个打卡任务,做到真正吃透后再进行下一个任务哦。</p>';
export const DEFAULT_PASS_TEXT = '<p>亲爱的同学:</p><p>欢迎参加《麦麦芭蕾形体初级课打卡活动》,我们将通过芭蕾的几个特性如开、绷、直等,使身体各部位发展均衡,宝贝们每天需学完当前课时并完成打卡,才能解锁下一个课时内容</p><p>打卡时间:2020年6月1日-6月21日(共21天)</p><p>关卡数:共15关</p><p>每日可解锁上限:2关</p><p>打卡任务:坚持初级课闯关打卡课程,并且分享至朋友圈</p><p>分享格式:麦麦芭蕾0基础形体课打卡+学生名字 +第X关 +坚持就是胜利!</p><p>打卡奖励:</p><p>①坚持完成“闯关打卡”的宝贝可以获得精美小礼品!</p><p>②每关都分享打卡任务到朋友圈的小宝贝,还可以获得一份大礼包哦~</p><p>老师有话说:小宝贝每天最多完成2个任务,做到真正吃透后再进行下一个任务哦</p>';
export const NUM_TO_WORD_MAP = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
// 日历打卡
export const CALENDAR_CLOCK = 'CALENDAR_CLOCK';
// 闯关打卡
export const PASS_GATE = 'PASS_GATE';
// 答题模式
export const ANSWER_THE_QUESTION = 'ANSWER_THE_QUESTION'
// 普通模式
export const ORDINARY = 'ORDINARY';
// 学生类型
export const STUDENT_TYPE = {
NORMAL: '在读学员',
POTENTIAL: '潜在学员',
HISTORY: '历史学员'
}
// 打卡情况
export const CLOCK_STATUS = {
CLOCKED: '已打卡',
NO_CLOCK: '未打卡',
NO_DATA: '从未打卡'
}
// 日签下载状况
export const DOWNLOAD_DAY_SIGN_STATUS = {
DOWNED: '已下载',
NO_DOWN: '未下载',
}
// 作业排序
export const ORDER_RULE_ENUM = [{
key: 'DEFAULT',
label: '默认排序'
},
{
key: 'SCORE',
label: '得分由高到低'
},
{
key: 'BE_LIKE_NUM',
label: '点赞数由高到低'
}
]
export const QUESTION_TYPE_MAP = [{
type: 'THE_RADIO',
title: '单选题',
componentType: 'Radio',
key: 'THE_RADIO',
icon: <React.Fragment>&#xe773;</React.Fragment>,
},
{
type: 'MULTI_SELECT',
title: '多选题',
componentType: 'Checkbox',
key: 'MULTI_SELECT',
icon: <React.Fragment>&#xe775;</React.Fragment>,
},
{
type: 'JUDGE',
title: '判断题',
componentType: 'Radio',
key: 'JUDGE',
icon: <React.Fragment>&#xe7bb;</React.Fragment>,
}
]
export const MODULE_MEDIA_MAP = [{
title: '文字',
icon: <React.Fragment>&#xe760;</React.Fragment>,
key: 'TEXT',
},
{
title: '图片',
icon: <React.Fragment>&#xe6ac;</React.Fragment>,
key: 'PICTURE',
},
{
title: '音频',
icon: <React.Fragment>&#xe75f;</React.Fragment>,
key: 'VOICE',
},
{
title: '视频',
icon: <React.Fragment>&#xe75e;</React.Fragment>,
key: 'VIDEO',
},
{
title: '文件',
icon: <React.Fragment>&#xe759;</React.Fragment>,
key: 'FILE',
}]
export const FILE_ACCEPT = {
PICTURE: 'image/jpg,image/jpeg,image/png,image/bmp,image/gif',
VIDEO: 'audio/mp4,video/mp4',
VOICE: 'audio/x-mpeg,audio/mp3,audio/mpeg,audio/wav,audio/x-m4a'
}
export const QUESTION_FILE_ACCEPT = {
PICTURE: 'image/jpg,image/jpeg,image/png,image/gif',
VIDEO: 'audio/mp4,video/mp4',
VOICE: 'audio/x-mpeg,audio/mp3,audio/mpeg'
}
export const MODE_ENUM_MAP = {
general: {
title: '普通模式',
enumType: 'ORDINARY',
example: [{
title: '普通模式',
img: 'https://image.xiaomaiketang.com/xm/jSQGeQQdkN.png'
}]
},
answer: {
title: '答题模式',
enumType: 'ANSWER_THE_QUESTION',
example: [{
title: '答题模式-答题首页',
img: 'https://image.xiaomaiketang.com/xm/Qb8WaDaNCM.png'
}, {
title: '答题模式-答题页',
img: 'https://image.xiaomaiketang.com/xm/ERkGNsRP4G.png'
}, {
title: '答题模式-答题报告',
img: 'https://image.xiaomaiketang.com/xm/HGyPthnCJx.png'
}]
}
}
export const MODE_MAP = [{
img: 'https://image.xiaomaiketang.com/xm/S6YYwZwitP.png',
title: '普通模式',
desc: '每一个任务内可加入文本、图片、音频、视频等内容,学员查看任务要求后直接提交打卡',
modeKey: 'general',
enumType: 'ORDINARY',
}, {
img: 'https://image.xiaomaiketang.com/xm/hPPwp8F2zT.png',
title: '答题模式',
desc: '可添加单选、多选、判断等类型题目,学生提交后系统将自动评分',
modeKey: 'answer',
enumType: 'ANSWER_THE_QUESTION',
}]
export const TRUE_OR_FALSE_MAP = [{
value: 'RIGHT_OR_WRONG',
label: ['对', '错']
},
{
value: 'T_F',
label: ['T', 'F'],
alias: ['True', 'False']
},
{
value: 'TICK',
label: ['✓', '×']
}
]
export const TRUE_OR_FALSE_KEY_MAP = {
RIGHT_OR_WRONG: ['对', '错'],
T_F: ['T', 'F'],
TICK: ['✓', '×']
}
export const MEDIA_DESC_MAP = {
VIDEO: '[视频]',
VOICE: '[音频]',
PICTURE: '[图片]'
}
/*
* @Author: sunbingqing
* @Date: 2019-08-05 11:05:00
......
import React from 'react';
import PropTypes from 'prop-types';
import { Modal, Button } from 'antd';
import UploadOss from '@/core/upload';
let cutFlag = false;
class ImgCutModalNew extends React.Component {
state = {
photoclip: null,
imgAddress: null
}
componentDidUpdate(prevProps) {
const { visible, cutWidth, cutHeight, imageFile, width, bizCode = 'HOMEWORK_FILE', compress, compressSize = 1024 } = this.props;
if (visible && imageFile) {
setTimeout(() => {
const { photoclip } = this.state;
const okBtnDom = document.querySelector('#clipBtn');
const options = {
size: [cutWidth, cutHeight],
rotateFree: false,
ok: okBtnDom,
maxZoom: 1,
style: {
jpgFillColor: 'transparent'
},
done: async (dataUrl) => {
const { name } = imageFile;
const fileName = window.random_string(16) + name.slice(name.lastIndexOf('.'));
const params = {
bizCode: bizCode,
accessTypeEnum: 'PUBLIC',
instId: LS.get('instId'),
resourceName: fileName
}
// 压缩
if (compress) {
const compressSizeByte = compressSize * 1024;
dataUrl = this.getBase64Size(dataUrl) > compressSizeByte ? await this.handleCompressImg(dataUrl, compressSizeByte, cutWidth) : dataUrl;
}
const cutImage = this.convertBase64UrlToBlob(dataUrl);
window.axios.Apollo("public/apollo/commonOssAuthority", params).then((res) => {
const { resourceId, accessId, policy, callback, signature,key, host } = res.result;
const localUrl = URL.createObjectURL(cutImage);
// 构建上传的表单
const xhr = new XMLHttpRequest();
const formData = new FormData();
formData.append("OSSAccessKeyId", accessId);
formData.append("policy", policy);
formData.append("callback", callback);
formData.append("Signature", signature);
formData.append("key", key);
formData.append("file", cutImage);
formData.append("success_action_status", 200);
xhr.open("POST", host);
xhr.onload = () => {
this.props.onOk(localUrl, resourceId);
setTimeout(() => {
cutFlag = false;
}, 2000)
};
xhr.send(formData);
this.setState({ xhr })
})
}
};
if (!photoclip) {
const _photoclip = new PhotoClip('#imgCutModalNew', options);
_photoclip.load(imageFile);
this.setState({ photoclip: _photoclip });
} else {
photoclip.load(imageFile);
}
}, 0);
}
}
// 压缩图片
handleCompressImg(dataUrl, compressSize, cutWidth) {
const that = this;
return new Promise((resolve, reject) => {
const newImage = new Image();
newImage.src = dataUrl;
newImage.setAttribute("crossOrigin", 'Anonymous'); //url为外域时需要
newImage.onload = function () {
let imgWidth = this.width;
let imgHeight = this.height;
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = cutWidth;
canvas.height = cutWidth * imgHeight / imgWidth;
let quality = 0.92;//压缩系数0-1之间
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
let base64 = canvas.toDataURL("image/jpeg", quality);
while (that.getBase64Size(base64) > compressSize) {
quality -= 0.01;
base64 = canvas.toDataURL("image/jpeg", quality);
}
resolve(base64);
}
})
}
// 获取base64文件大小
getBase64Size(baseStr) {
const eqTagIndex = baseStr.indexOf("=");
baseStr = eqTagIndex != -1 ? baseStr.substring(0, eqTagIndex) : baseStr;
const strLen = baseStr.length;
const fileSize = strLen - (strLen / 8) * 2;
return fileSize;
}
// base64转换成blol
convertBase64UrlToBlob(urlData) {
const bytes = window.atob(urlData.split(",")[1]);
const ab = new ArrayBuffer(bytes.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], { type: "image/png" });
}
handleImgCutDone = () => {
if (!cutFlag) {
cutFlag = true;
this.refs.hiddenBtn.click();
}
}
render() {
const {
visible, onClose, needReUpload, reUpload,
title, width, cutWidth, cutHeight,
cutContentWidth, cutContentHeight
} = this.props;
return (
<Modal
title={title}
width={width}
visible={visible}
onCancel={onClose}
footer={[
!needReUpload ?
<Button
key="back"
onClick={onClose}
>取消</Button> :
<Button
key="back"
onClick={reUpload}
>重新上传</Button>,
<Button
key="submit"
type="primary"
onClick={this.handleImgCutDone}
>确定</Button>
]}>
<div
id="imgCutModalNew"
style={{
width: `${cutContentWidth || 620}px`,
height: `${cutContentHeight || 420}px`
}}
></div>
<div
id="clipBtn"
style={{ display: 'none' }}
ref="hiddenBtn"
/>
</Modal>
)
}
}
// ImgCutModalNew.propTypes = {
// visible: PropTypes.bool,
// needReUpload: PropTypes.bool, // 是否需要重新上传
// title: PropTypes.string,
// width: PropTypes.number,
// cutWidth: PropTypes.number,
// cutHeight: PropTypes.number,
// imageFile: PropTypes.File
// };
ImgCutModalNew.defaultProps = {
width: 550,
cutWidth: 502,
cutHeight: 283,
needReUpload: false,
};
export default ImgCutModalNew;
\ No newline at end of file
import React from 'react'
import './ShowTips.less'
function ShowTips(props) {
return (
<div className={`xm-show-tip xm-type-${props.type || 'defulat'}`} >
<span className="icon iconfont">&#xe6f2;</span>
<p>{props.message}</p>
</div>
)
}
export default ShowTips
.xm-show-tip {
position: relative;
min-height:32px;
background:#FFF0E7;
border-radius:4px;
display: flex;
justify-content: flex-start;
align-items: center;
padding: 0 12px;
span.icon {
color:#FF8534;
line-height: 20px;
}
p {
color:#666666;
font-size: 14px;
line-height:20px;
margin-left: 12px;
}
}
.xm-type-default {
width: 100%;
}
.xm-type-info {
width: calc(~'100% - 190px');
}
\ No newline at end of file
......@@ -9,10 +9,12 @@ import SearchBar from './SearchBar.tsx';
import PageControl from './PageControl.tsx';
import CheckBox from './CheckBox.tsx';
import CropperModal from './CropperModal.tsx';
import ImgCutModalNew from './ImgCutModalNew';
export {
SearchBar,
PageControl,
CheckBox,
CropperModal
CropperModal,
ImgCutModalNew
}
\ No newline at end of file
/*
* @Author: wufan
* @Date: 2020-12-01 17:21:21
* @LastEditors: wufan
* @LastEditTime: 2020-12-09 14:49:24
* @LastEditors: zhangleyuan
* @LastEditTime: 2020-12-11 13:36:32
* @Description: Description
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import Service from "@/common/js/service";
export function sendLoginAuthCode(params: object) {
return Service.Hades("anon/hades/sendLoginAuthCode", params);
}
export function login(params: object) {
return Service.Hades("anon/hades/login", params);
}
export function getUserStore(params: object) {
return Service.Hades("public/hades/getUserStore", params);
}
return Service.Hades("public/hades/getUserStore", params);
}
export function getUserPermission(params: object) {
return Service.Hades("public/hades/getPermission", params);
}
export function logout(params: object) {
return Service.Hades("public/hades/logout", params);
}
......
......@@ -2,12 +2,12 @@
* @Author: wufan
* @Date: 2020-12-01 17:20:49
* @LastEditors: zhangleyuan
* @LastEditTime: 2020-12-07 11:08:23
* @LastEditTime: 2020-12-11 11:36:19
* @Description: Description
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import { getUserStore, getUserPermission ,logout,getStoreUser,sendBizAuthCode,editUserPhone,checkBizAuthCode,sendNewPhoneAuthCode} from '@/data-source/base/request-apis';
import { getUserStore, getUserPermission ,logout,getStoreUser,sendBizAuthCode,editUserPhone,checkBizAuthCode,sendNewPhoneAuthCode,sendLoginAuthCode,login} from '@/data-source/base/request-apis';
export default class StoreService {
// 获取员工列表
......@@ -40,4 +40,10 @@ export default class StoreService {
static sendNewPhoneAuthCode(params: any){
return sendNewPhoneAuthCode(params);
}
static sendLoginAuthCode(params: any){
return sendLoginAuthCode(params);
}
static login(params: any){
return login(params);
}
}
\ No newline at end of file
/*
* @Author: sunbingqing
* @Date: 2019-08-05 11:05:00
* @Last Modified by: zhujian
* @Last Modified time: 2020-05-26 19:50:20
*/
import React, { useEffect, useState } from 'react';
import { Spin, Select } from 'antd';
import "./CommonSelect.less";
import Bus from '@/core/bus';
import _ from 'underscore';
interface ClassSearchSelectProps {
style?: any;
label?: string;
id?: string;
multiple?: boolean;
query?: any;
courseId?: string;
courseIds?: Array<number>;
states?: any;
placeholder?: string;
defaultValue?: any;
className?: string;
classType?: number;
url?: string;
filter?: (value: any) => void;
hasNoneClass?: boolean;
needName?: boolean;
instId?: any;
hasNoClass?: any;
onSelect?: (val1: any, val2?: any) => void;
teacherId?: any;
}
const ClassSearchSelect = (props: ClassSearchSelectProps) => {
const { style, label, id, placeholder, defaultValue, className, classType, url, filter, hasNoneClass, needName, onSelect, hasNoClass } = props;
const multiple = props.multiple || false;
let timer: any;
let scroll: any;
const [query, setQuery] = useState(_.extend({
current: 1,
size: 10,
showNumber: 100,
classNameLike: '',
states: props.states || ['INIT', 'STUDYING', 'END'],
courseId: props.courseId,
courseIds: props.courseIds,
instId: props.instId
}, props.query));
const [dataSet, setDataSet] = useState([]);
const [isAll, setIsAll] = useState(false);
useEffect(() => {
Bus.bind('reset', handleQueryReset);
// fetchServerData();
return () => {
Bus.unbind('reset');
clearTimeout(timer);
clearTimeout(scroll);
};
}, []);
useEffect(() => {
setQuery((query: any) => ({ ...query, courseId: props.courseId }));
setTimeout(() => {
fetchServerData();
}, 300)
}, [props.courseId]);
const defprops = _.pick(props, 'open', 'getPopupContainer');
if (multiple) {
defprops.mode = 'multiple';
}
let selectValue = defaultValue;
if (!multiple && defaultValue != '-1') {
const list = _.filter(dataSet, (item: any) => {
return item.classId === defaultValue;
});
if (!list.length) {
selectValue = className || undefined;
}
}
function handleQueryReset() {
setQuery(() =>
_.extend({
current: 1,
size: 10,
showNumber: 100,
classNameLike: '',
states: props.states || ['INIT', 'STUDYING', 'END'],
courseId: null,
}, props.query),
);
fetchServerData();
}
function fetchServerData(current = 1) {
let queryTemp = { ...query, current, courseId: props.courseId || '' };
setQuery((query: any) => ({ ...query, current }));
if (!classType) {
queryTemp = { ...queryTemp, classType: '' };
setQuery((query: any) => ({ ...query, classType: '' }));
}
const urlTemp = url || 'public/class/digestList';
const param = _.extend(queryTemp, props.query);
if (url == "public/homework/getTeacherClassPage") {
window.axios.Zeus(urlTemp, param).then((res: any) => {
const data = res.result.records;
_.map(data, (item: any) => {
item.name = item.className;
item.formatName = item.className;
});
let dataSetTemp = [];
if (current === 1) {
dataSetTemp = filter ? filter(data) : data;
if (hasNoneClass) {
dataSetTemp.unshift({ classId: "1", name: '未选班' });
}
} else {
dataSetTemp = dataSet.concat(filter ? filter(data) : data);
}
setDataSet(dataSetTemp);
setIsAll(!res.result.hasNext);
});
} else {
window.axios.Business(urlTemp, param).then((res: any) => {
const data = res.result.records;
_.map(data, (item: any) => {
item.formatName = item.name;
});
let dataSetTemp = [];
if (current === 1) {
dataSetTemp = filter ? filter(data) : data;
if (hasNoneClass) {
dataSetTemp.unshift({ classId: "1", name: '未选班' });
}
} else {
dataSetTemp = dataSet.concat(filter ? filter(data) : data);
}
setDataSet(dataSetTemp);
setIsAll(!res.result.hasNext);
});
}
}
function searchName() {
clearTimeout(timer);
timer = setTimeout(() => {
fetchServerData();
}, 500);
}
function hasmore(e: any) {
clearTimeout(scroll);
const ulDom = e.currentTarget.getElementsByTagName("ul")[0];
if (ulDom.length <= 0) {
return;
}
scroll = setTimeout(() => {
if (ulDom.scrollTop + ulDom.clientHeight > ulDom.scrollHeight - 30 && !isAll) {
fetchServerData(query.current + 1);
}
}, 300);
}
function handleClassSelect(classId: string) {
if (!classId) { // 清空选项
const queryTemp = query;
queryTemp.classNameLike = "";
setQuery(() => queryTemp);
searchName();
}
// console.log(classId)
const queryTemp = query;
if (queryTemp.name) {
queryTemp.classNameLike = '';
setQuery(() => queryTemp);
fetchServerData();
}
if (!multiple) {
if (needName) {
const items = _.filter(dataSet, (item: any) => {
return item.classId === classId;
});
onSelect({ classId, formatName: !!items[0] && items[0].name });
return;
}
onSelect({ classId });
return;
}
onSelect(classId);
}
return (
<div className={"common-select staticSelect"} style={style}>
{
!!label && <div className='label'> {label}:</div>
}
<Select
id={id}
{...defprops}
showSearch
allowClear
onSearch={(value: string) => {
const queryTemp = query;
queryTemp.classNameLike = value;
setQuery(() => queryTemp);
searchName();
}}
// open
onPopupScroll={hasmore}
placeholder={placeholder}
value={selectValue}
onChange={handleClassSelect}
filterOption={(_input: any, option: any) => option}
>
{
hasNoClass && <Select.Option key={'-1'} value={'-1'} >未选班</Select.Option>
}
{
_.map(dataSet, (item: any, index: number) => {
return <Select.Option id={'class_select_item_' + index} key={item.classId} value={item.classId} title={item.name}>{item.name}</Select.Option>;
})
}
{!isAll &&
<Select.Option disabled style={{ textAlign: 'center' }} value="spin">
<Spin size="small" />
</Select.Option>
}
</Select>
</div>
);
};
export default ClassSearchSelect;
/*
* @Author: leehu
* @Date: 2017-09-04 11:52:25
* @Last Modified by: wangxiang
* @Last Modified time: 2020-11-06 14:09:38
*/
import React from 'react';
import PropTypes from 'prop-types';
import { Menu, Dropdown, Icon, Checkbox, Button, Input, Spin, Select, Row, Col } from 'antd';
import Bus from '@/core/bus';
const Option = Select.Option;
const Search = Input.Search;
class CourseSelect extends React.Component {
constructor(props) {
super(props);
this.state = {
close: true,
dataSource: [],
query: {
month: null,
current: 0,
size: 10,
courseNameLike: null,
showNumber: 100,
},
dataSet: [],
visible: false,
loading: false,
selectedIds: [],
selected: props.selected || [],
}
this.reset = () => {
this.handleQueryReset();
}
}
componentWillMount() {
Bus.bind('reset', this.handleQueryReset)
this.fetchServerData();
}
componentWillReceiveProps(nextProps) {
if ((this.props.courseId !== nextProps.courseId) ||
(this.props.queryOneToOne !== nextProps.queryOneToOne) ||
(this.props.queryOneTomore !== nextProps.queryOneTomore)) {
this.props = nextProps
this.fetchServerData();
}
}
handleQuery = () => {
this.fetchServerData();
}
handleQueryReset = () => {
this.setState({
query: {
current: 0,
size: 10000,
showNumber: 100,
courseNameLike: null,
}
}, () => {
this.fetchServerData();
});
}
fetchServerData(current = 1) {
const self = this;
const url = 'public/course/digestList'
let query = _.clone(this.state.query)
query.current = current;
const param = _.extend(query, this.props.query);
if (self.props.queryAll) {
delete param.status;
} else {
// 排除一对一
param.status = 'ON';
}
// if (this.props.status) {
// param.status = this.props.status
// }
if (self.props.queryOneToOne) {
param.courseType = 'ONEVONE'
delete param.status;
}
if (self.props.queryOneTomore) {
param.courseType = 'ONE2MANY'
delete param.status;
}
param.teacherId = self.props.teacherId;
param.studentId = self.props.studentId;
this.setState({
query: param
})
window.axios.Business(url, param).then((res) => {
let data = res.result.records;
// this.parseServerData(data);
data.map(function (item, index) {
item.title = item.name;
item.desc = item.name;
});
if (current >1) {
data = this.state.dataSet.concat(data)
}
// res.totalCount = 200
this.setState({
dataSet: data,
totalCount: res.result.total,
isAll: !res.result.hasNext,
loading: false
});
}).finally((res) => {
this.setState({ loading: false });
});
}
searchName = () => {
clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.fetchServerData()
}, 500)
}
handleCourseSelect = (course) => {
const query = this.state.query;
if (query.courseNameLike) {
query.courseNameLike = '';
this.setState({ query }, this.fetchServerData);
}
if (!this.props.multiple) {
if (this.props.needName) {
let list = _.filter(this.state.dataSet, (item) => {
return item.id == course;
})
this.props.onSelect(list[0] || {});
return;
}
this.props.onSelect({ id: course });
return;
}
this.props.onSelect(course);
}
hasmore = (dom) => {
clearTimeout(this.scroll)
let height = $(dom.currentTarget).find('ul li').last().position().top
this.scroll = setTimeout(() => {
if (height < 500 && !this.state.isAll) {
this.fetchServerData(this.state.query.current + 1)
}
}, 300)
}
render() {
let defprops = {}
if (this.props.multiple) {
defprops.mode = 'multiple'
}
return (
<div className={classNames("common-select staticSelect", { 'common-select-active': this.state.visible })} style={this.props.style}>
{
!!this.props.label && <div className='label'> {this.props.label}:</div>
}
<Select
id={this.props.id}
ref='course'
{...defprops}
showSearch
// style={{ width: '100%' }}
allowClear
// notFoundContent={this.state.fetching ? <Spin size="small" /> : null}
onSearch={(value) => {
const query = this.state.query;
query.courseNameLike = value
this.setState({ query }, this.searchName)
}}
onBlur={() => {
const query = this.state.query;
query.courseNameLike = null;
this.setState({ query }, this.searchName)
}}
// open
onPopupScroll={(dom) => {
this.hasmore(dom)
}}
placeholder={this.props.placeholder}
value={this.props.defaultValue || undefined}
onChange={this.handleCourseSelect}
filterOption={(input, option) => option}
>
{
_.map(this.state.dataSet, (item, index) => {
return <Select.Option id={'course_select_item_' + index} key={item.id} value={item.id} title={item.name}>
{item.name}
</Select.Option>
})
}
{!this.state.isAll &&
<Select.Option disabled style={{ textAlign: 'center' }} value="spin">
<Spin size="small" />
</Select.Option>
}
</Select>
</div>
)
}
}
CourseSelect.propTypes = {
};
CourseSelect.defaultProps = {
onSelect: () => { },
placeholder: '选择课程',
teacherId: null,
selected: [],
multiple: false,
query: {},
renderItem: null,
filter: null,
isAll: false
}
export default CourseSelect;
\ No newline at end of file
/*
* @Author: leehu
* @Date: 2017-09-01 16:29:44
* @Last Modified by: 吴文洁
* @Last Modified time: 2019-12-09 15:03:40
*/
import React from 'react';
import { Menu, Icon, Checkbox, Button, Input, Spin, Select, Row } from 'antd';
import "./StaticSelect.less";
class StaticSelect extends React.Component{
constructor(props) {
super(props);
this.state = {
close: true,
dataSet: [],
visible: false,
loading: false,
selectedIds: this.props.defaultValue,
selected: props.selected || [],
query: {
showNumber: 100,
},
}
this.reset = () => {
this.setState({ selectedIds: null })
}
}
componentDidMount() {
const dataSet = [];
_.map(_.allKeys(this.props.dataSource), (key) => {
this.props.dataSource[key] && dataSet.push({ id: key, name: this.props.dataSource[key] });
});
this.setState({ dataSet: dataSet });
}
componentWillReceiveProps(nextProps) {
const dataSet = _.isArray(nextProps.dataSource) ? nextProps.dataSource : [];
!_.isArray(nextProps.dataSource) && _.map(_.allKeys(nextProps.dataSource), (key) => {
nextProps.dataSource[key] && dataSet.push({ id: key, name: nextProps.dataSource[key] });
});
this.setState({ dataSet: dataSet });
}
handleSelect = (id) => {
if (!this.props.multiple) {
this.props.onSelect({ id });
return;
}
this.props.onSelect(id);
}
render() {
let defprops = {}
if (this.props.multiple) {
defprops.mode = 'multiple'
}
if (this.props.id) {
defprops.id = this.props.id
}
if(this.props.onFocus){
defprops.onFocus = this.props.onFocus;
}
const { objectProps } = this.props;
return (
<div className={classNames("common-select staticSelect", { 'common-select-active': this.state.visible })} style={this.props.style}>
{
!!this.props.label && <div className='label'> {this.props.label}:</div>
}
<Select
id={this.props.id}
{...defprops}
showSearch={this.props.showSearch}
// style={{ width: '100%' }}
disabled={this.props.disabled}
allowClear={this.props.allowClear}
placeholder={this.props.placeholder}
value={this.props.defaultValue || undefined}
defaultValue={this.props.defaultValue}
onChange={this.handleSelect}
filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
dropdownClassName={this.props.dropdownClassName}
>
{
_.map(this.state.dataSet, (item, index) => {
return <Select.Option id={this.props.id+'_item_'+index} key={this.props.id+''+index} value={item.id} title={item.name}>{item.name}</Select.Option>
})
}
</Select>
</div>
)
}
}
StaticSelect.propTypes = {
};
StaticSelect.defaultProps = {
onSelect: () => { },
showSearch: true,
allowClear: true,
defaultValue: '',
placeholder: '请选择',
dataSource: {},
style: {},
keyName: 'name',
multiple: false,
allSelectName: '全部班级',
width: 100,
student: true,
dropdownClassName: '',
}
export default StaticSelect;
\ No newline at end of file
@import '../../core/mixins.less';
.staticSelect{
display: flex;
align-items: center;
width: 100%;
.label{
margin-right: 8px;
flex-shrink: 0;
// height: 36px;
// line-height: 36px;
}
.ant-select-selection-selected-value{
position: absolute;
}
.ant-select,.ageBox{
.flex(1)
}
.ant-select-selection__rendered{
overflow: hidden;
ul{
position: absolute;
min-width: 100%;
right: 0px;
display: flex;
flex-wrap: nowrap;
}
}
}
\ No newline at end of file
/*
* @Author: 吴文洁
* @Date: 2020-07-17 15:49:11
* @Last Modified by: mikey.zhaopeng
* @Last Modified time: 2020-11-23 22:02:49
* @Description: 大班互动-添加/编辑直播课
*/
import React from 'react';
import { withRouter } from "react-router-dom";
import { Button, message, Modal } from 'antd';
import Bus from '@/core/bus';
import ShowTips from "@/components/ShowTips";
import Breadcrumbs from "@/components/Breadcrumbs";
import AddLiveBasic from './components/AddLiveBasic';
import AddLiveClass from './components/AddLiveClass';
import AddLiveIntro from './components/AddLiveIntro';
import PreviewCourseModal from './modal/PreviewCourseModal';
import LackConsumeStudentModal from './modal/LackConsumeStudentModal';
import moment from 'moment';
import './AddLive.less';
const defaultCover = 'https://image.xiaomaiketang.com/xm/YNfi45JwFA.png';
// const editBoxKey = window.random_string(16);
const defaultBasicInfo = {
courseName: null, // 课程名称
coverId: null,
coverUrl: defaultCover
};
const defaultClassInfo = {
teacherId: null,
teacherName: null,
liveDate: null,
timeHorizonStart: null,
timeHorizonEnd: null,
studentList: [], // 学员列表
assistant: [], // 已经选择的助教老师
liveType: "LARGE_CLASS_LIVE",
consumeClassTime: 30, // 累计在线时长, 默认30分钟
consumeHourNum: 1, // 课时, 默认1课时
calendarTime: [],
startTime: new Date().getTime() + 300000,
endTime: new Date().getTime() + 300000,
applyMode: ''
};
const defaultIntroInfo = {
needRecord: 'YES',
liveCourseWarmMedia: {},
// 讲师简介
liveCourseMediaRequests: [{
mediaType: 'TEXT',
mediaContent: '',
// key: editBoxKey
}],
}
class AddLive extends React.Component {
constructor(props) {
super(props);
const id = getParameterByName("id");
const type = getParameterByName("type");
this.state = {
id,
type,
after: false,
isXiaomai: false,
loading: false,
isEdit: true,
selectedAssistant: [], // 已经选择的助教数量
// 直播课基本信息
addLiveBasicInfo: {
courseName: null, // 课程名称
coverId: null,
coverUrl: defaultCover
},
// 直播课上课信息
addLiveClassInfo: {
teacherId: null,
teacherName: null,
liveDate: null,
timeHorizonStart: null,
timeHorizonEnd: null,
studentList: [], // 不扣课时学员列表
consumeStudentList: [], // 扣课时学员列表
excludeStudentIds: [], // 已经入库的不扣课时学员
excludeConsumeStudentIds: [], // 已经入口的扣课时学员
assistant: [], // 已经选择的助教老师
liveType: "LARGE_CLASS_LIVE",
consumeClassTime: 30, // 累计在线时长, 默认30分钟
consumeHourNum: 1, // 课时, 默认1课时
applyMode: '',
calendarTime: [], // 批量排课
startTime: new Date().getTime() + 300000, // 批量开始时分
endTime: new Date().getTime() + 300000 // 批量结束时分
},
// 直播课简介
addLiveIntroInfo: {
needRecord: 'YES',
liveCourseWarmMedia: {},
liveCourseMediaRequests: [{
mediaType: 'TEXT',
mediaContent: '',
// key: editBoxKey
}],
isAutoSendReport: true
},
}
}
componentDidMount() {
const { type } = this.state;
if (type === 'edit') {
this.getCourseDetail();
} else {
this.getLivePermission();
}
}
getCourseDetail = () => {
let { isEdit } = this.state;
this.setState({ loading: true });
// axios.Apollo('public/businessLive/getCourseDetail', {
// liveCourseId: this.state.id
// }).then((res) => {
// const {
// teacherId,
// studentIds,
// consumeStudentIds,
// courseName,
// coverUrl,
// coverId,
// intro,
// courseState,
// startTime,
// endTime,
// liveType,
// adminShowVOList,
// channel,
// podium,
// courseMediaVOS,
// nickname,
// needRecord,
// consumeHourNum,
// consumeClassTime,
// warmMedia,
// applyMode,
// autoSendReport
// } = res.result;
// const studentList = [];
// _.each(studentIds, (item) => {
// studentList.push({ studentId: item });
// });
// const selectedAssistant = _.map(adminShowVOList, (item) => ({
// id: item.adminId,
// adminName: item.adminName,
// }));
// const assistantId = _.pluck(adminShowVOList, "adminId");
// courseMediaVOS.map((item) => {
// item.key = window.random_string(16);
// return item;
// })
// const addLiveBasicInfo = {
// courseName,
// coverId,
// coverUrl: coverUrl || defaultCover,
// };
// const liveDate = startTime;
// const timeHorizonStart = startTime;
// const timeHorizonEnd = endTime;
// const addLiveClassInfo = {
// liveType,
// liveDate,
// nickname,
// teacherId,
// studentList,
// consumeHourNum,
// consumeClassTime,
// consumeStudentList: consumeStudentIds,
// timeHorizonStart,
// timeHorizonEnd,
// assistant: assistantId,
// excludeStudentIds: studentIds,
// excludeConsumeStudentIds: _.pluck(consumeStudentIds, 'studentId'),
// applyMode
// }
// const liveCourseMediaRequests = courseMediaVOS.length
// ? [...courseMediaVOS]
// : [{ mediaType: 'TEXT', mediaContent: '', key: window.random_string(16) }, ...courseMediaVOS];
// const addLiveIntroInfo = {
// liveCourseWarmMedia: warmMedia,
// needRecord,
// liveCourseMediaRequests,
// isAutoSendReport: !!(autoSendReport === "AUTO")
// }
// // 晚于开课前30分钟
// if(new Date().getTime() > startTime - 1800000) {
// isEdit = false
// }
// this.setState({
// isEdit,
// loading: false,
// selectedAssistant,
// addLiveIntroInfo,
// addLiveClassInfo,
// addLiveBasicInfo,
// after: courseState !== "UN_START",
// isXiaomai: channel === "XIAOMAI",
// });
// })
}
getLivePermission = () => {
// axios.Apollo("public/businessLive/queryLiveAccount").then((res) => {
// const { addParam } = this.state;
// let list = res.result || [];
// const isXiaomai = _.some(list, (item) => item.channel === "XIAOMAI");
// this.setState({ isXiaomai });
// });
}
// 修改基本信息
handleChangeBasicInfo = (field, value, _coverUrl) => {
const { coverUrl } = this.state.addLiveBasicInfo;
this.setState({
addLiveBasicInfo: {
...this.state.addLiveBasicInfo,
[field]: value,
coverUrl: _coverUrl ? _coverUrl : coverUrl,
}
})
}
// 修改上课信息
handleChangeClassInfo = (field, value, teacherList) => {
console.log("change-----",value);
const _value = value ? value.valueOf() : null;
if (teacherList) {
let selectedTeacher;
if (field === 'teacherId') {
selectedTeacher = _.find(teacherList, item => item.teacherId === value)
// 判断上课老师是否已经被选为了助教老师
const { addLiveClassInfo: { assistant } } = this.state;
if (selectedTeacher && assistant.includes(selectedTeacher.teacherId)) {
message.warning('上课老师和助教老师不能是同一个人');
return;
}
}
this.setState({
addLiveClassInfo: {
...this.state.addLiveClassInfo,
nickname: selectedTeacher ? selectedTeacher.teacherName: null,
[field]: _value,
}
});
} else {
if (field === 'assistant') {
// 判断助教老师是否已经被选为了上课老师
const { addLiveClassInfo: { teacherId } } = this.state;
if (_value && _value.includes(teacherId)) {
message.warning('上课老师和助教老师不能是同一个人');
return;
}
}
this.setState({
addLiveClassInfo: {
...this.state.addLiveClassInfo,
[field]: _value,
}
});
}
// 批量开始时间改变,结束时间自动同步一致
if (field === 'startTime') {
this.setState({
addLiveClassInfo: {
...this.state.addLiveClassInfo,
[field]: _value,
endTime: _value,
}
});
}
}
// 修改简介
handleChangeIntroInfo = (field, value) => {
this.setState({
addLiveIntroInfo: {
...this.state.addLiveIntroInfo,
[field]: value
}
})
}
// 完成创建/编辑
handleSubmit = () => {
const { addLiveBasicInfo, addLiveClassInfo, addLiveIntroInfo, id, isEdit, type } = this.state;
const {liveDate, timeHorizonStart} = addLiveClassInfo;
const _liveDate = moment(liveDate).format("YYYY-MM-DD");
const _timeHorizonStart = moment(timeHorizonStart).format('HH:mm');
const startTime = moment(_liveDate + ' ' + _timeHorizonStart).format('x');
if(type === 'edit' && isEdit && new Date().getTime() > startTime - 1800000) {
Modal.info({
title: "提示",
icon: (
<span className="icon iconfont default-confirm-icon">
&#xe6f4;
</span>
),
content: "晚于开课前30分钟,部分信息不可修改",
okText: '我知道了',
onOk: () => {
this.getCourseDetail();
}
});
return
}
this.handleValidate(addLiveBasicInfo, addLiveClassInfo, addLiveIntroInfo, isEdit).then((res) => {
if (!res) return;
const { type } = this.state;
const { courseName, coverId, coverUrl } = addLiveBasicInfo;
const {
podium,
liveType,
liveDate,
teacherId,
assistant,
studentList,
consumeHourNum,
timeHorizonEnd,
consumeClassTime,
timeHorizonStart,
consumeStudentList,
applyMode,
calendarTime,
} = addLiveClassInfo;
let { startTime, endTime } = addLiveClassInfo;
const { liveCourseMediaRequests, needRecord, liveCourseWarmMedia, isAutoSendReport} = addLiveIntroInfo;
if(window.NewVersion && type === 'add') {
startTime = startTime;
endTime = endTime;
} else {
const _liveDate = moment(liveDate).format("YYYY-MM-DD");
const _timeHorizonStart = moment(timeHorizonStart).format('HH:mm');
const _timeHorizonEnd = moment(timeHorizonEnd).format('HH:mm');
startTime = moment(_liveDate + ' ' + _timeHorizonStart).format('x');
endTime = moment(_liveDate + ' ' + _timeHorizonEnd).format('x');
}
const commonParams = {
coverId,
startTime,
endTime,
teacherId,
liveType,
consumeHourNum,
consumeClassTime,
adminIds: assistant,
courseName: courseName.trim(),
studentIds: _.pluck(studentList, "studentId"),
consumeStudentIds: consumeStudentList,
liveCourseMediaRequests: liveCourseMediaRequests.filter(item => { return !!item.mediaContent; }),
needRecord,
liveCourseWarmMedia,
applyMode,
autoSendReport: isAutoSendReport ? "AUTO":"OFF_AUTO",
calendarTime
}
if (type === 'add') {
const params = {
coverUrl,
...commonParams,
}
if(params.liveCourseWarmMedia && !params.liveCourseWarmMedia.mediaUrl) {
delete params.liveCourseWarmMedia
}
axios.Apollo("public/businessLive/createCourse", params).then((res) => {
if (!res) return;
message.success("新建成功");
localStorage.setItem('largeLiveCourseItem', JSON.stringify({
...params,
liveCourseId: res.result
}));
window.RCHistory.goBack();
});
} else {
const params = {
...commonParams,
liveCourseId: id,
}
if(params.liveCourseWarmMedia && !params.liveCourseWarmMedia.mediaUrl) {
delete params.liveCourseWarmMedia
}
axios.Apollo("public/businessLive/updateCourse", params).then((res) => {
message.success("更新成功");
this.setState({ loading: false });
window.RCHistory.goBack();
});
}
})
}
handleValidateLackConsumeModal = (consumeHourNum, calendarTime, consumeStudentList) => {
return new Promise((resolve) => {
const lackConsumeStudentList = [];
consumeStudentList.forEach(item => {
if(item.consumeHourNum < consumeHourNum * calendarTime.length) {
lackConsumeStudentList.push(item);
}
})
if(lackConsumeStudentList.length > 0) {
const lackConsumeStudentModal = (
<LackConsumeStudentModal
consumeHourNum={consumeHourNum}
calendarTime={calendarTime}
lackConsumeStudentList={lackConsumeStudentList}
onOk={() => {
resolve(true);
this.setState({
lackConsumeStudentModal: null
})
}}
onClose={() => {
resolve(false);
this.setState({
lackConsumeStudentModal: null
})
}}
/>
)
this.setState({
lackConsumeStudentModal
})
} else {
resolve(true);
}
})
}
handleValidate = (addLiveBasicInfo, addLiveClassInfo, addLiveIntroInfo, isEdit) => {
return new Promise((resolve) => {
const { type } = this.state;
// 校验基本信息(直播课名称)
const { courseName } = addLiveBasicInfo;
const {
liveDate, timeHorizonStart, timeHorizonEnd,
studentList, teacherId, calendarTime, consumeStudentList, consumeHourNum, consumeClassTime, applyMode
} = addLiveClassInfo;
const { liveCourseMediaRequests } = addLiveIntroInfo;
const currentTime = +new Date();
if(!courseName) {
message.warning('直播名称不能为空');
resolve(false);
return;
}
if(window.NewVersion && type === 'add') {
// 5.0新建 校验 批量排课
const { startTime, endTime } = addLiveClassInfo;
if(calendarTime.length && calendarTime.length === 0) {
message.warning('请选择上课日期');
resolve(false);
return;
} else if(startTime === endTime) {
message.warning('结束时间必须晚于开始时间');
resolve(false);
return;
}
// 若有今日排课 校验当前时间
const currentDay = moment(currentTime).format('YYYY-MM-DD');
const itemToday = _.find(calendarTime, (item) => {
const itemDay = moment(item).format('YYYY-MM-DD');
return itemDay === currentDay;
})
if(itemToday) {
const itemDay = moment(itemToday).format('YYYY-MM-DD');
const itemHour = moment(startTime).format('HH:mm');
if(itemDay === currentDay) {
if(moment(itemDay + ' ' + itemHour).format('x') < currentTime) {
message.warning('开始时间不能早于现在');
resolve(false);
return;
}
}
}
if(consumeClassTime > (endTime - startTime) / 60000) {
message.warning('到课规则时长不能超过排课时长');
resolve(false);
return;
}
} else {
const _liveDate = moment(liveDate).format("YYYY-MM-DD");
const _timeHorizonStart = moment(timeHorizonStart).format('HH:mm');
const _timeHorizonEnd = moment(timeHorizonEnd).format('HH:mm');
const startTime = moment(_liveDate + ' ' + _timeHorizonStart).format('x');
const endTime = moment(_liveDate + ' ' + _timeHorizonEnd).format('x');
if(!startTime || !endTime) {
message.warning('日期不能为空');
resolve(false);
return;
} else if (!timeHorizonStart) {
message.warning('开始时间不能为空');
resolve(false);
return;
} else if (!timeHorizonEnd) {
message.warning('结束时间不能为空');
resolve(false);
return;
} else if (isEdit && startTime < currentTime) {
message.warning('开始时间不能早于当前时间');
resolve(false);
return;
} else if (isEdit && endTime < currentTime) {
message.warning('结束时间不能早于当前时间');
resolve(false);
return;
} else if (isEdit && endTime <= startTime) {
message.warning("结束时间不能早于开始时间");
resolve(false);
return;
} else if(isEdit && consumeClassTime > (endTime - startTime) / 60000) {
message.warning("到课规则时长不能超过排课时长");
resolve(false);
return;
}
}
if(!teacherId) {
message.warning('上课老师不能为空');
resolve(false);
return;
} else if(!applyMode) {
message.warning('请选择分享设置');
resolve(false);
return;
} else {
const textIntro = liveCourseMediaRequests.filter(item => { return item.mediaType === 'TEXT'; });
for (let i = 0, len = textIntro.length; i < len; i++) {
if (textIntro[i].mediaContent && textIntro[i].mediaContentLength.length > 1000) {
message.warning(`第${i+1}个文字简介的字数超过了1000个字`);
resolve(false);
return;
}
}
}
if(window.NewVersion && type === 'add') {
this.handleValidateLackConsumeModal(consumeHourNum, calendarTime, consumeStudentList).then(res => {
resolve(res)
})
} else {
resolve(true);
}
});
}
// 显示预览课程弹窗
handleShowPreviewModal = () => {
const { addLiveBasicInfo, addLiveClassInfo, addLiveIntroInfo } = this.state;
const previewLiveCourseModal = (
<PreviewCourseModal
courseBasinInfo={addLiveBasicInfo}
courseClassInfo={addLiveClassInfo}
courseIntroInfo={addLiveIntroInfo}
close={() => {
this.setState({
previewLiveCourseModal: null
})
}}
/>
);
this.setState({ previewLiveCourseModal });
}
// 取消编辑并返回上一级路由
handleGoBack = () => {
// 比较state的addLiveBasicInfo, addLiveClassInfo, addLiveIntroInfo和默认数据是否相等
const { addLiveBasicInfo, addLiveClassInfo, addLiveIntroInfo } = this.state;
if (!_.isEqual(addLiveBasicInfo, defaultBasicInfo) ||
!_.isEqual(addLiveClassInfo, defaultClassInfo) ||
!_.isEqual(addLiveIntroInfo, defaultIntroInfo)
) {
Modal.confirm({
title: '确定要返回吗?',
content: '返回后,本次编辑的内容将不被保存',
okText: '确认返回',
cancelText: '留在本页',
icon: <span className="icon iconfont default-confirm-icon">&#xe6f4;</span>,
onOk: () => {
window.RCHistory.goBack();
}
})
} else {
// 直接返回
window.RCHistory.goBack();
}
}
render() {
const {
id, type, after, isXiaomai, selectedAssistant,
addLiveBasicInfo, addLiveClassInfo, addLiveIntroInfo,
isEdit
} = this.state;
return (
<div className="page add-live-page">
<Breadcrumbs
navList={type == "add" ? "新建直播课" : "编辑直播课"}
goBack={this.handleGoBack}
/>
<div className="box">
<div className="show-tips">
<ShowTips message="请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦助教保有依据国家规定及平台规则进行处理的权利" />
</div>
<div className="add-live-page__form">
<div className="basic-info__wrap">
<div className="title">基本信息</div>
<AddLiveBasic
liveScene="large"
isEdit={isEdit}
data={addLiveBasicInfo}
onChange={this.handleChangeBasicInfo}
/>
</div>
<div className="class-info__wrap">
<div className="title">上课信息</div>
<AddLiveClass
liveScene="large"
isEdit={isEdit}
after={after}
pageType={type}
isXiaomai={isXiaomai}
data={{...addLiveClassInfo, id} }
selectedAssistant={selectedAssistant}
onChange={this.handleChangeClassInfo}
/>
</div>
<div className="intro-info__wrap">
<div className="title">更多信息</div>
<AddLiveIntro
liveScene="large"
isEdit={isEdit}
data={addLiveIntroInfo}
isXiaomai={isXiaomai}
onChange={this.handleChangeIntroInfo}
/>
</div>
</div>
</div>
<div className="footer">
<Button onClick={this.handleGoBack}>取消</Button>
<Button onClick={this.handleShowPreviewModal}>预览课程介绍</Button>
<Button type="primary" onClick={_.debounce(() => this.handleSubmit(), 3000, true)}>保存</Button>
</div>
{ this.state.previewLiveCourseModal }
{ this.state.lackConsumeStudentModal }
</div>
)
}
}
export default withRouter(AddLive);
\ No newline at end of file
.add-live-page {
.box {
margin-bottom: 66px;
}
.add-live-page__form {
margin-top: 16px;
.title {
font-size: 16px;
color: #333;
font-weight: 500;
line-height: 22px;
}
.add-live__class-info {
margin-left: 24px;
.student {
margin-bottom: 16px;
}
}
.add-live__basic-info {
.course-name {
margin-left: 14px;
}
}
.add-live__intro-info {
margin-left: 50px;
}
.class-info__wrap,
.intro-info__wrap {
margin-top: 32px;
}
.add-live__intro-info {
margin-left: 0;
padding-left: 24px;
.label {
width: 100px;
text-align: right;
}
}
}
.footer {
position: fixed;
bottom: 0;
height: 58px;
width: 100%;
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 252px;
background: #fff;
border-top: 1px solid #E8E8E8;
z-index: 9999;
.ant-btn {
margin-left: 10px;
}
}
}
......@@ -13,22 +13,22 @@ import {
message, Spin, Tooltip
} from 'antd';
import TeacherSelectV5 from "@/modules/classManage_V5/classDetail/TeacherSelectV5";
// import TeacherSelectV5 from "@/modules/classManage_V5/classDetail/TeacherSelectV5";
import ChargeExplainModal from '../modal/ChargeExplainModal';
import SelectStudent from '../modal/select-student/index';
import MultipleDatePicker from '@/modules/class/MultipleDatePicker';
// import MultipleDatePicker from '@/modules/class/MultipleDatePicker';
import moment from 'moment';
import './AddLiveClass.less';
const defaultQuery = {
instId,
// instId,
size: 10,
current: 1,
adminName: null
}
const { instId } = window.currentUserInstInfo;
// const { instId } = window.currentUserInstInfo;
class AddLiveClass extends React.Component {
......@@ -61,10 +61,10 @@ class AddLiveClass extends React.Component {
}
// 获取用户是否是旗舰版的权限
handleFetchPermission = () => {
const { instId } = window.currentUserInstInfo;
// const { instId } = window.currentUserInstInfo;
this.setState({ loading: true });
axios.Business('public/inst/checkInstProduct', {
instId: instId || LS.get("instId"),
// instId: instId || LS.get("instId"),
productCodeList: ['ULTIMATESELL', 'PIP_TO_ULTIMATE', 'HIGH_TO_ULTIMATE']
}).then((res) => {
const { result } = res;
......@@ -79,36 +79,36 @@ class AddLiveClass extends React.Component {
// 获取助教老师列表
getAssistantList = (current = 1, selectList) => {
const { query, assistantList } = this.state;
const { selectedAssistant } = this.props;
const { teacherId, assistant } = this.props.data;
const idList = selectList ? selectList : assistant;
const _query = {
...query,
current,
idList,
size: idList.length <= 10 ? 10 : idList.length + 10
};
this.setState({ query: _query });
axios.Apollo("public/businessLive/queryAdminByName", _query).then((res) => {
const { result = {} } = res;
const { records = [], total = 0, hasNext } = result;
const list = current > 1 ? assistantList.concat(records) : records;
const _assistantList = _.uniq(
selectedAssistant.concat(
_.reject(list, (item) => item.id === teacherId)
),
false,
(item) => item.id
);
this.setState({
hasNext,
assistantList: list,
_assistantList: _assistantList
})
// const { query, assistantList } = this.state;
// const { selectedAssistant } = this.props;
// const { teacherId, assistant } = this.props.data;
// const idList = selectList ? selectList : assistant;
// const _query = {
// ...query,
// current,
// idList,
// size: idList.length <= 10 ? 10 : idList.length + 10
// };
// this.setState({ query: _query });
// axios.Apollo("public/businessLive/queryAdminByName", _query).then((res) => {
// const { result = {} } = res;
// const { records = [], total = 0, hasNext } = result;
// const list = current > 1 ? assistantList.concat(records) : records;
// const _assistantList = _.uniq(
// selectedAssistant.concat(
// _.reject(list, (item) => item.id === teacherId)
// ),
// false,
// (item) => item.id
// );
// this.setState({
// hasNext,
// assistantList: list,
// _assistantList: _assistantList
// })
});
// });
}
// 修改直播模式
......@@ -432,11 +432,11 @@ class AddLiveClass extends React.Component {
}
</span>
</div>
<MultipleDatePicker
{/* <MultipleDatePicker
selectDateList={calendarTime}
onSelect={this.selectMultiDate}
canSelectTodayBefore={false}
/>
/> */}
</div>
</div>
......@@ -518,7 +518,7 @@ class AddLiveClass extends React.Component {
}
<div className="teacher">
<span className="label"><span className="require">* </span>上课老师:</span>
<TeacherSelectV5
{/* <TeacherSelectV5
disabled={liveScene === 'large' && !isEdit}
ref="TeacherSelect"
showSearch={true}
......@@ -527,7 +527,7 @@ class AddLiveClass extends React.Component {
placeholder="请选择上课老师"
defaultValue={teacherId}
style={{ width: 240, marginTop: 6 }}
/>
/> */}
</div>
{
......
......@@ -14,7 +14,7 @@ import UploadOss from "@/core/upload";
import EditorBox from '../components/EditorBox';
import './AddLiveIntro.less';
import SelectPrepareFileModal from '../prepare-lesson/modal/SelectPrepareFileModal';
// import SelectPrepareFileModal from '../prepare-lesson/modal/SelectPrepareFileModal';
import { DISK_MAP } from '@/common/constants/academic/lessonEnum';
import { ImgCutModalNew } from '@/components';
......@@ -58,16 +58,16 @@ class AddLiveIntro extends React.Component {
}
// 获取机构可见的磁盘
handleFetchDiskList = () => {
axios.Apollo('public/apollo/getUserDisk', {}).then((res) => {
const { result = [] } = res;
const diskList = result.map((item) => {
return {
...item,
folderName: DISK_MAP[item.disk]
}
});
this.setState({ diskList });
});
// axios.Apollo('public/apollo/getUserDisk', {}).then((res) => {
// const { result = [] } = res;
// const diskList = result.map((item) => {
// return {
// ...item,
// folderName: DISK_MAP[item.disk]
// }
// });
// this.setState({ diskList });
// });
}
// 删除简介
handleDeleteIntro = (index) => {
......@@ -399,7 +399,7 @@ class AddLiveIntro extends React.Component {
</div>
</div>
{/* 选择暖场图文件弹窗 */}
<SelectPrepareFileModal
{/* <SelectPrepareFileModal
operateType="select"
accept="video/mp4,image/jpeg,image/png,image/jpg"
selectTypeList={['MP4', 'JPG', 'JPEG', 'PNG']}
......@@ -410,7 +410,7 @@ class AddLiveIntro extends React.Component {
this.setState({ showSelectFileModal: false })
}}
onSelect={this.handleSelectVideo}
/>
/> */}
</div>
)
}
......
......@@ -3,9 +3,9 @@
* @Author: zhangyi
* @Date: 2020-05-09 15:21:22
* @LastEditors: zhangleyuan
* @LastEditTime: 2020-12-09 15:14:28
* @LastEditTime: 2020-12-11 14:01:32
*/
import React from 'react'
import { Modal, Button, Table } from "antd";
import "./AccountChargeModal";
const data = [
......
/*
* @Author: 吴文洁
* @Date: 2020-07-23 14:54:16
* @LastEditors: 吴文洁
* @LastEditTime: 2020-08-28 10:49:49
* @LastEditors: zhangleyuan
* @LastEditTime: 2020-12-11 14:04:08
* @Description: 大班直播课预览弹窗
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
......@@ -68,7 +68,7 @@ class PreviewCourseModal extends React.Component {
} = this.dealWithTime(startTime, endTime);
liveDateStr = _liveDateStr;
startTimeStr = _startTimeStr,
startTimeStr = _startTimeStr;
endTimeStr = _endTimeStr;
}
......
/*
* @Author: 吴文洁
* @Date: 2020-08-07 16:28:41
* @LastEditors: 吴文洁
* @LastEditTime: 2020-09-23 20:36:51
* @LastEditors: zhangleyuan
* @LastEditTime: 2020-12-11 14:23:09
* @Description: 选择学员-筛选组件
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
......@@ -16,7 +16,7 @@ import { SearchBar } from '@/components';
import ClassSearchSelect from '@/modules/common/ClassSearchSelect';
import CourseSearchSelect from '@/modules/common/CourseSearchSelect';
import StaticSelect from '@/modules/common/StaticSelect';
import _ from 'underscore';
let resourceData = {};
_.map(window.RESOURCE, item => {
resourceData[item.code] = item.name
......
/*
* @Author: 吴文洁
* @Date: 2020-08-07 16:28:49
* @LastEditors: 吴文洁
* @LastEditTime: 2020-09-27 19:35:32
* @LastEditors: zhangleyuan
* @LastEditTime: 2020-12-11 14:23:20
* @Description: 选择学员-学员列表组件
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
......@@ -12,7 +12,7 @@ import { Table, Tooltip, Menu, Dropdown } from 'antd';
import Bus from '@/core/bus';
import { PageControl } from '@/components';
import _ from 'underscore';
let resourceData = {};
_.map(window.RESOURCE, item => {
......
......@@ -8,6 +8,7 @@ import CheckBeforeSendCode from '../../components/CheckBeforeSendCode';
import User from '@/common/js/user';
import axios from 'axios';
import _ from 'underscore';
import BaseService from "@/domains/basic-domain/baseService";
function Login(props) {
const [phone, setPhone] = useState(''); // 登录手机号
......@@ -52,9 +53,9 @@ function Login(props) {
serverType: "CLOUD_CLASS_LOGIN",
appTermEnum:'XIAOMAI_CLOUD_CLASS_PC_WEB_ADMIN'
}
axios.post('https://dev-heimdall.xiaomai5.com/hades/anon/hades/sendLoginAuthCode', params).then((res) => {
if (!res.data.success) {
setErrorMessage(res.data.message);
BaseService.sendLoginAuthCode(params).then((res) => {
if (!res.success) {
setErrorMessage(res.message);
} else {
timeSub(60);
setChecking1(true)
......@@ -87,15 +88,15 @@ function Login(props) {
authCode:phoneverify,
appTermEnum:"XIAOMAI_CLOUD_CLASS_PC_WEB_ADMIN"
}
axios.post('https://dev-heimdall.xiaomai5.com/hades/anon/hades/login', params).then((res) => {
const data = res.data;
if (!data.success) {
setErrorMessage(data.message);
BaseService.login(params).then((res) => {
if (!res.success) {
setErrorMessage(res.message);
} else {
User.setUserId(data.result.userId);
User.setToken(data.result.xmToken);
User.setUserId(res.result.userId);
User.setToken(res.result.xmToken);
window.RCHistory.push({
pathname: `/personal-info`,
pathname: `/
personal-info`,
})
}
})
......
/*
* @Author: 吴文洁
* @Date: 2020-04-29 10:26:32
* @LastEditors: wufan
* @LastEditTime: 2020-12-10 10:52:16
* @LastEditors: zhangleyuan
* @LastEditTime: 2020-12-11 14:26:24
* @Description: 内容线路由配置
*/
import EmployeesManagePage from '@/modules/store-manege/EmployeesManagePage';
import personalInfoPage from '@/modules/personalInfo';
import UserManagePage from '@/modules/store-manege/UserManagePage';
import StoreDecorationPage from '@/modules/store-manege/StoreDecorationPage';
import CourseCatalogPage from '@/modules/store-manege/CourseCatalogPage'
import LiveCoursePage from '@/modules/course-manage/LiveCoursePage'
import CourseCatalogPage from '@/modules/store-manege/CourseCatalogPage';
import LiveCoursePage from '@/modules/course-manage/LiveCoursePage';
import AddLivePage from '@/modules/course-manage/AddLive'
import ClassBook from '@/modules/resource-disk';
const mainRoutes = [
......@@ -42,7 +43,12 @@ const mainRoutes = [
{
path: '/live-course',
component:LiveCoursePage,
name: '课程分类'
name: '课程管理'
},
{
path: '/add-live-course',
component:AddLivePage,
name: '创建直播课'
},
{
path: '/resource-disk',
......
/*
* @Author: 吴文洁
* @Date: 2020-04-28 18:05:30
* @LastEditors: wufan
* @LastEditTime: 2020-12-02 11:37:13
* @LastEditors: zhangleyuan
* @LastEditTime: 2020-12-11 14:36:59
* @Description:
*/
import mainRoutes from './config/mainRoutes';
......@@ -36,7 +36,6 @@ const cache:any = {
path: '',
component: null
}
function dynamic (component:any) {
const resolveComponent = component
return asyncComponent({
......
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