Commit b64f7607 by zhangleyuan

feat:新增登录的页面

parent 9f064025
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
@import './antd-override.less'; @import './antd-override.less';
@import './variable.less'; @import './variable.less';
#root{
height:100%;
}
.page-body { .page-body {
background: #fff; background: #fff;
padding: 16px; padding: 16px;
......
import React from 'react'
import PropTypes from 'prop-types';
import './CheckBeforeSendCode.less';
class CheckBeforeSendCode extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true,
id: window.random_string(),
}
}
componentDidMount() {
this.initCheckVerifyCode();
}
initCheckVerifyCode() {
this.setState({ loading: false })
const nc_token = ["FFFF0N000000000084CA", (new Date()).getTime(), Math.random()].join(':');
const NC_Opt = {
//声明滑动验证需要渲染的目标元素ID。
renderTo: `#${this.state.id}`,
//应用类型标识。它和使用场景标识(scene字段)一起决定了滑动验证的业务场景与后端对应使用的策略模型。您可以在人机验证控制台的配置管理页签找到对应的appkey字段值,请务必正确填写。
appkey: "FFFF0N000000000084CA",
//使用场景标识。它和应用类型标识(appkey字段)一起决定了滑动验证的业务场景与后端对应使用的策略模型。您可以在人机验证控制台的配置管理页签找到对应的scene值,请务必正确填写。
scene: "nc_login",
//滑动验证码的主键,请勿将该字段定义为固定值。确保每个用户每次打开页面时,其token值都是不同的。系统默认的格式为:”您的appkey”+”时间戳”+”随机数”。
token: nc_token,
//滑动条的宽度。
customWidth: 300,
//业务键字段,可为空。为便于线上问题的排查,建议您按照线上问题定位文档中推荐的方法配置该字段值。
trans:{"key1":"code0"},
//通过Dom的ID属性自动填写trans业务键,可为空。建议您按照线上问题定位文档中推荐的方法配置该字段值。
elementID: ["usernameID"],
//是否自定义配置底层采集组件。如无特殊场景,请使用默认值(0),即不自定义配置底层采集组件。
is_Opt: 0,
//语言。PC端Web页面场景默认支持18国语言,详细配置方法请参见自定义文案与多语言文档。
language: "cn",
//是否启用。一般情况,保持默认值(true)即可。
isEnabled: true,
//内部网络请求的超时时间。一般情况建议保持默认值(3000ms)。
timeout: 3000,
//允许服务器超时重复次数,默认5次。超过重复次数后将触发报错。
times:5,
//用于自定义滑动验证各项请求的接口地址。一般情况,请勿配置该参数。
apimap: {
// 'analyze': '//a.com/nocaptcha/analyze.jsonp',
// 'get_captcha': '//b.com/get_captcha/ver3',
// 'get_captcha': '//pin3.aliyun.com/get_captcha/ver3'
// 'get_img': '//c.com/get_img',
// 'checkcode': '//d.com/captcha/checkcode.jsonp',
// 'umid_Url': '//e.com/security/umscript/3.2.1/um.js',
// 'uab_Url': '//aeu.alicdn.com/js/uac/909.js',
// 'umid_serUrl': 'https://g.com/service/um.json'
},
//前端滑动验证通过时会触发该回调参数。您可以在该回调参数中将请求标识(token)、会话ID(sessionid)、签名串(sig)字段记录下来,随业务请求一同发送至您的服务端调用验签。
callback: (data) => {
this.props.callback(data, nc);
}
}
const nc = new noCaptcha(NC_Opt)
//用于自定义文案。详细配置方法请参见自定义文案与多语言文档。
nc.upLang('cn', {
_startTEXT: "请按住滑块,拖动到最右边",
_yesTEXT: "验证通过",
_error300: "点击<a href=\"javascript:__nc.reset()\">刷新</a>再来一次",
_errorNetwork: "网络不给力,请<a href=\"javascript:__nc.reset()\">点击刷新</a>"
})
}
render() {
return <div id={this.state.id} className="nc-container check-before-send"></div>
}
}
CheckBeforeSendCode.propTypes = {
callback: PropTypes.func,
}
export default CheckBeforeSendCode;
\ No newline at end of file
.check-before-send {
#nc_1_wrapper, .nc-container.tb-login #nc_1_wrapper {
width: 288px !important;
}
.nc_scale {
background: #FAFAFA;
border-radius: 4px;
height: 40px;
box-sizing: border-box;
.scale_text2 {
color: #666;
}
.nc_iconfont {
color: #FF8534;
font-weight: bold;
border-color: #e8e8e8;
height: 40px;
line-height: 40px;
width: 52px;
box-sizing: border-box;
}
}
.nc_scale span.nc-lang-cnt {
height: 40px;
line-height: 40px;
box-sizing: border-box;
}
.nc_scale .nc_ok, .nc_scale .nc_bg {
background: #FFE7D6;
border-radius: 4px 0 0 4px;
}
.nc_scale .btn_ok {
color: #FF8534;
height: 40px;
line-height: 40px;
box-sizing: border-box;
}
.errloading {
color: #fff;
white-space: nowrap;
overflow: hidden;
.nc-lang-cnt {
color: #666;
a {
color: #FC9C6B;
}
}
}
}
\ No newline at end of file
/**
* 处理一个学员,报名同一个包月课多次 的时间计算
* @param courseList
* @returns {*}
*/
import domtoimage from 'dom-to-image'
import { Popover } from 'antd'
import React from 'react'
// 时间控件优化方法
window.setCorrectDate = date => {
let _date = date;
if ((date - (+new Date()) < 30 * 60 * 1000)) {
const currentMinute = new Date().getMinutes();
if (currentMinute > 30) {
_date = moment().add(60 - currentMinute, 'minute');
} else {
_date = moment().add(30 - currentMinute, 'minute');
}
}
return _date;
}
// 优化四舍五入方法
if (!Number.prototype.toFixedCorrect) {
Number.prototype.toFixedCorrect = function (n) {
return Math.round((this * Math.pow(10, n)).toFixed(10) * 1) / Math.pow(10, n);
}
}
window.processMonthCourseDate = courseList => {
if (Array.isArray(courseList) && courseList.length > 0) {
// 因为所购买的时间不可能有重叠,先排序
courseList = courseList.sort(function(now, next) {
return parseInt(now.startDate) - parseInt(next.startDate)
})
// 总天数,与已完成天数
let sumDays = 0,
finishDays = 0,
givingDays = 0
courseList.forEach(function(item) {
if (item.endDate != item.purchaseEndDate) {
givingDays += moment(parseInt(item.endDate)).diff(
parseInt(item.purchaseEndDate),
'days'
)
}
const temp =
moment(parseInt(item.endDate)).diff(parseInt(item.startDate), 'days') +
1
sumDays += temp
if (item.endDate < Date.now()) {
finishDays += temp
} else if (item.startDate < Date.now() && Date.now() < item.endDate) {
finishDays += moment().diff(parseInt(item.startDate), 'days') + 1
}
})
let date = {}
for (let i = 0, len = courseList.length; i < len; i++) {
const course = courseList[i],
nextCourse = courseList[i + 1]
const startDate = (course.startDate = moment(parseInt(course.startDate))
.startOf('day')
.valueOf())
const purchaseEndDate = (course.purchaseEndDate = moment(
parseInt(course.purchaseEndDate)
)
.endOf('day')
.valueOf())
const endDate = (course.endDate = course.endDate
? moment(parseInt(course.endDate))
.endOf('day')
.valueOf()
: undefined)
if (i == 0 && Date.now() < startDate) {
date = {
startDate: startDate,
endDate: endDate,
purchaseEndDate: purchaseEndDate,
text: '课程未开始'
}
break
}
if ((i == len - 1 && endDate < Date.now()) || !endDate) {
date = {
text: '课程到期',
startDate: startDate,
endDate: endDate,
purchaseEndDate: purchaseEndDate
}
break
}
if (startDate < Date.now() && Date.now() < endDate) {
date = {
startDate: startDate,
endDate: endDate,
purchaseEndDate: purchaseEndDate,
text: '课程进行中'
}
break
} else if (
endDate < Date.now() &&
Date.now() < parseInt(nextCourse.startDate)
) {
date = {
startDate: parseInt(nextCourse.startDate),
endDate: parseInt(nextCourse.endDate),
purchaseEndDate: parseInt(nextCourse.purchaseEndDate),
text: '课程未开始'
}
break
}
}
// 总天数
date.sumDays = sumDays
// 已过去天数
date.finishDays = finishDays
// 剩余总天数
date.subDays = sumDays - finishDays
// 赠送天数
date.givingDays = givingDays
// 购买天数
date.purchaseDays = sumDays - givingDays
return date
}
return false
}
/**
* 生成树
* @param parentCode
* @param datas
* @param level
* @returns {Array}
*/
window.createTree = (parentCode, datas, level = 0) => {
const child = []
const childCodes = []
// 找子节点
for (let i in datas) {
const item = datas[i]
if (item.parent == parentCode) {
item.level = level
child.push(item)
childCodes.push(item.code)
}
}
const len = child.length
if (len > 0) {
if (parentCode != 0) {
datas[parentCode].child = child
datas[parentCode].childCodes = childCodes
}
for (let i = 0; i < len; i++) {
createTree(child[i].code, datas, level + 1)
}
}
return child
}
window.sortPermission = data => {
data.sort((a, b) => {
return a.sequence - b.sequence
})
for (let i = 0; i < data.length; i++) {
if (data[i].child) {
window.sortPermission(data[i].child)
}
}
return data
}
/**
* 生成指定长度的随机字符串
* @param len
* @returns {string}
*/
window.random_string = len => {
len = len || 32
const chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
const maxPos = chars.length
let pwd = ''
for (let i = 0; i < len; i++) {
pwd += chars.charAt(Math.floor(Math.random() * maxPos))
}
return pwd
}
/**
* 金额转大写
* @param num
* @returns {string|*}
*/
window.numberToChines = num => {
if (num != 0 && !num) return ''
let strOutput = ''
let strUnit = '仟佰拾亿仟佰拾万仟佰拾元角分'
num += '00'
const intPos = num.indexOf('.')
if (intPos >= 0) num = num.substring(0, intPos) + num.substr(intPos + 1, 2)
strUnit = strUnit.substr(strUnit.length - num.length)
for (let i = 0; i < num.length; i++)
strOutput +=
'零壹贰叁肆伍陆柒捌玖'.substr(num.substr(i, 1), 1) + strUnit.substr(i, 1)
return strOutput
.replace(/零角零分$/, '整')
.replace(/零[仟佰拾]/g, '零')
.replace(/零{2,}/g, '零')
.replace(/零([亿|万])/g, '$1')
.replace(/零+元/, '元')
.replace(/亿零{0,3}万/, '亿')
.replace(/^元/, '零元')
}
/**
* 人名币格式
* @param price 人名币
*
*/
window.getMoneyFormat = price => {
if (!_.isNumber(Number(price))) {
return '0.00'
}
const n = parseFloat(Math.round(price) / CONFIG.moneyUnit).toFixed(2)
const re = /(\d{1,3})(?=(\d{3})+(?:\.))/g
return n.replace(re, '$1,')
}
window.getNumberFormat = price => {
const n = price + ''
let arr = n.split('.')
if (arr[1]) {
arr[1] = arr[1].substring(0, 2)
}
arr.splice(2)
return arr.join('.')
}
/**
* 人名币转化为分
* @param price 人名币
*
*/
window.getMoneyByMoneyUnit = price => {
return Math.round(price * CONFIG.moneyUnit)
}
/**
* 时间格式
* @param format 时间格式
* @param timestamp 时间戳
*/
window.formatTime = (format, timestamp) => {
if (!timestamp) {
return
}
const date = new Date(parseInt(timestamp))
let y = date.getFullYear(),
m = date.getMonth() + 1,
d = date.getDate(),
h = date.getHours() - 8,
i = date.getMinutes(),
s = date.getSeconds(),
w = date.getDay()
return format
.replace('YYYY', y)
.replace('MM', m)
.replace('DD', d)
.replace('H', h)
.replace('i', i)
.replace('s', s)
}
window.formatDate = (format, timestamp) => {
if (!timestamp) return ''
if (timestamp == 0) return ''
const date = new Date(parseInt(timestamp))
let y = date.getFullYear(),
m = date.getMonth() + 1,
d = date.getDate(),
h = date.getHours(),
i = date.getMinutes(),
s = date.getSeconds(),
w = date.getDay(),
week = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
m = m < 10 ? '0' + m : m
d = d < 10 ? '0' + d : d
h = h < 10 ? '0' + h : h
i = i < 10 ? '0' + i : i
s = s < 10 ? '0' + s : s
return format
.replace('YYYY', y)
.replace('MM', m)
.replace('DD', d)
.replace('H', h)
.replace('i', i)
.replace('s', s)
.replace('WW', week[w])
}
/**
* 查询字符串参数
* @returns {Object}
* @constructor
*/
window.getRequest = () => {
const url = location.search //获取url中"?"符后的字串
const theRequest = {}
if (url.indexOf('?') != -1) {
const str = url.substr(1)
const strs = str.split('&')
for (var i = 0; i < strs.length; i++) {
theRequest[strs[i].split('=')[0]] = unescape(strs[i].split('=')[1])
}
}
return theRequest
}
window.getParameterByName = function(name) {
name = name.replace(/[\\[]/, '\\[').replace(/[\]]/, '\\]')
const regex = new RegExp('[\\?&]' + name + '=([^&#]*)')
const results = regex.exec(location.href)
return results === null
? ''
: decodeURIComponent(results[1].replace(/\+/g, ' '))
}
window.getUrlParam = function () {
const urlArr = location.href.split('/');
const str = urlArr[urlArr.length - 1];
const param = parseInt(str);
return isNaN(param) ? '' : str;
}
window.getStringParamete = function(string, name) {
const theRequest = {}
if (string.indexOf('?') != -1) {
const str = string.substr(1)
const strs = str.split('&')
for (var i = 0; i < strs.length; i++) {
theRequest[strs[i].split('=')[0]] = decodeURIComponent(strs[i].split('=')[1])
}
}
return theRequest[name]
}
/**
* dataURL 转 Blob
* @param dataurl
* @returns {Blob}
*/
window.dataURLtoBlob = dataurl => {
const arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
u8arr = new Uint8Array(n)
let n = bstr.length
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], {
type: mime
})
}
window.timeFormat = (time, defaultValue) => {
const stringTime = time
? (time / CONFIG.timeUnit).toFixed(2)
: defaultValue == undefined
? 0
: defaultValue
return Number(stringTime)
}
window.stringCompare = (s1, s2) => {
if (!(s1 && s2)) {
return true
}
const s1Arr = s1.split('.')
const s2Arr = s2.split('.')
var s1Num = 0
var s2Num = 0
var flag = true
s1Arr.map((item, index) => {
s1Num += item * Math.pow(10, 6 - 2 * index)
})
s2Arr.map((item, index) => {
s2Num += item * Math.pow(10, 6 - 2 * index)
})
return !(s1Num < s2Num)
}
window.timeFormatSixty = (time, defaultValue) => {
const stringTime = time
? (time / 60).toFixed(2)
: defaultValue == undefined
? 0
: defaultValue
return Number(stringTime)
}
window.type = obj => {
var toString = Object.prototype.toString
var map = {
'[object Boolean]': 'boolean',
'[object Number]': 'number',
'[object String]': 'string',
'[object Function]': 'function',
'[object Array]': 'array',
'[object Date]': 'date',
'[object RegExp]': 'regExp',
'[object Undefined]': 'undefined',
'[object Null]': 'null',
'[object Object]': 'object'
}
return map[toString.call(obj)]
}
window.deepClone = data => {
var self = this
var t = type(data),
o,
i,
ni
if (t === 'array') {
o = []
} else if (t === 'object') {
o = {}
} else {
return data
}
if (t === 'array') {
for (i = 0, ni = data.length; i < ni; i++) {
o.push(deepClone(data[i]))
}
return o
} else if (t === 'object') {
for (i in data) {
o[i] = deepClone(data[i])
}
return o
}
}
window.moneyFormat = (money, defaultValue) => {
const stringMoney = money
? (Math.round(money) / CONFIG.moneyUnit).toFixed(2)
: defaultValue == undefined
? 0
: defaultValue
return Number(stringMoney)
}
//格式化金额为千位加逗号
window.moneyFormatThousands = (number, places, symbol, thousand, decimal) => {
number = number || 0
places = !isNaN((places = Math.abs(places))) ? places : 2
symbol = symbol !== undefined ? symbol : ''
thousand = thousand || ','
decimal = decimal || '.'
let negative = number < 0 ? '-' : '',
i = parseInt((number = Math.abs(+number || 0).toFixed(places)), 10) + '',
j = i.length > 3 ? (i.length) % 3 : 0
return (
symbol +
negative +
(j ? i.substr(0, j) + thousand : '') +
i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thousand) +
(places
? decimal +
Math.abs(number - i)
.toFixed(places)
.slice(2)
: '')
)
}
/**
* js数字精度转换
*/
window.formatFloat = (f, digit = 2) => {
const m = Math.pow(10, digit)
return Math.round(f * m, 10) / m
}
/**
* 分钟数转成小时表示
* @param number
* @returns {string}
*/
window.intToHours = number => {
//如果的整数
let hours
let minutes
if (number % 1 == 0) {
hours = Math.floor(number / 60)
minutes = number % 60
}
hours = hours < 10 ? '0'.concat(hours) : hours
minutes = minutes < 10 ? '0'.concat(minutes) : minutes
return hours + ':' + minutes
}
window.getMonthLastDate = timestamp => {
const date = new Date(parseInt(timestamp))
const y = date.getFullYear()
const m = date.getMonth() + 2
let time = y + '-' + m + '-01'
time = new Date(time).getTime() - 1000
return time
}
/*
获取日期相差多少天
* */
window.getSubDays = (endDate, startDate) => {
return Math.ceil(
moment(parseInt(endDate)).diff(moment(parseInt(startDate))) / 86400000
)
}
window.getPlusMonths = (startDate, plusMonths) => {
let dtTmp = new Date(parseInt(startDate))
plusMonths = parseInt(plusMonths)
return (
new Date(
dtTmp.getFullYear(),
dtTmp.getMonth() + plusMonths,
dtTmp.getDate(),
dtTmp.getHours(),
dtTmp.getMinutes(),
dtTmp.getSeconds()
).getTime() - 1000
)
}
window.getReduceMonths = (endDate, reduceMonths) => {
let dtTmp = new Date(parseInt(endDate));
reduceMonths = parseInt(reduceMonths);
return (
new Date(
dtTmp.getFullYear(),
dtTmp.getMonth() - reduceMonths,
dtTmp.getDate(),
dtTmp.getHours(),
dtTmp.getMinutes(),
dtTmp.getSeconds()
).getTime() + 1000
);
}
window.getMinusMonths = (endDate, minusMonths) => {
let dtTmp = new Date(parseInt(endDate))
minusMonths = parseInt(minusMonths)
return new Date(dtTmp.getFullYear(), (dtTmp.getMonth()) - minusMonths, dtTmp.getDate(), dtTmp.getHours(), dtTmp.getMinutes(), dtTmp.getSeconds()).getTime()
}
window.getPlusDays = (startDate, plusDays) => {
let dtTmp = new Date(parseInt(startDate))
plusDays = parseInt(plusDays)
return new Date(Date.parse(dtTmp) + 86400000 * plusDays).getTime()
}
window.getMinusDays = (endDate, minusDays) => {
let dtTmp = new Date(parseInt(endDate))
minusDays = parseInt(minusDays)
return new Date(Date.parse(dtTmp) - (86400000 * minusDays)).getTime()
}
//判断课时是否为整数
window.deleteZero = classHour => {
return new Number(classHour).valueOf()
}
//判断是否为两位小数
window.isNumber = str => {
var regex = /^\d+\.?\d{0,2}$/
return regex.test(str)
}
// 判断是否是数组且长度不为0
window.isLongArr = arr => {
return Array.isArray(arr) && arr.length > 0
}
//判断是否为整数
window.isInteger = obj => {
return obj % 1 === 0
}
// 判断是否为 >=0 的数字
window.isPositiveNum = num => {
return isNumber(num) && Number(num) >= 0
}
/**
* 通过课程类型 type 和 课时 得到正确的课时
*/
window.getCorrectClassHour = (type, classHour) => {
if (type == 3) {
return classHour
} else if (type == 1 || type == 2) {
return timeFormat(classHour)
}
}
/**
* 返回下一个需要刷新的页面索引
* @param number total 总数据量
* @param number current 当前页面
* @param number size 页面展示个数
* @param number deleteNumber 删除数量
* @return number 需要刷新的页面
*/
window.nextReloadPageNumber = (total, current, size, deleteNumber) => {
const currentTotal = total - deleteNumber
const pageNumber = Math.max(parseInt(currentTotal - 1 / size), 0)
return Math.min(pageNumber, current)
}
// 获取剩余天数,设置课程有效期之后启用
window.getLeftExpiredDay = (expiredDate, minWarningDays, onlyShowTimeover) => {
const expiredDay = Math.floor(
(Number(expiredDate) - Date.now()) / (24 * 60 * 60000)
)
let tempStr = '(剩余' + expiredDay + '天)'
if (expiredDay <= 0) {
tempStr = '(已到期)'
}
// 最小预警天数
if (minWarningDays) {
if (expiredDay > minWarningDays) {
tempStr = ''
}
}
if (onlyShowTimeover) {
if (expiredDay > 0) {
tempStr = ''
}
}
return tempStr
}
// 处理月份
window.handleMonth = (num) => {
var result = ''
if (num < 12) {
result = `${num}个月`
} else {
var year = Math.floor(num / 12)
var month = num % 12
if (!month) {
result = `${year}年`
} else {
result = `${year}${month}月`
}
}
return result
}
// 检测是否为正确的手机号码
window.isValidPhone = phone => {
// const tempPhone = Number(phone)
return /^[0-9]{11}$/.test(phone)
}
window.timeFilter = time => {
const timeUnit = 60
let hour = Math.floor(time / timeUnit)
let minute = time % timeUnit
if (hour.toString().length == 1) {
hour = '0' + hour
}
if (minute.toString().length == 1) {
minute = '0' + minute
}
return hour + ':' + minute
}
window.getMinutesTime = date => {
const hour = parseInt(date / 60)
let mint = date - hour * 60
mint > 10 ? (mint = mint) : (mint = '0' + mint)
return hour + ':' + mint
}
// 冲突函数
window.clashFunction = data => {
const returnData = {
teachers: {},
students: {},
classRooms: {},
classes: {}
}
Array.isArray(data) &&
data.map(item => {
Array.isArray(item.instScheduleClassConflictVOList) &&
item.instScheduleClassConflictVOList.map(value => {
value.type = item.conflictType
if (item.conflictType == 1) {
//老师
if (!returnData.teachers[item.conflictName]) {
returnData.teachers[item.conflictName] = []
}
value.teacherName = item.conflictName
returnData.teachers[item.conflictName].push(value)
} else if (item.conflictType == 2) {
//学生
if (!returnData.students[item.conflictName]) {
returnData.students[item.conflictName] = []
}
value.studentName = item.conflictName
returnData.students[item.conflictName].push(value)
} else if (item.conflictType == 3) {
//本班冲突
if (!returnData.classRooms[item.conflictName]) {
returnData.classRooms[item.conflictName] = []
}
value.classRoomName = item.conflictName
returnData.classRooms[item.conflictName].push(value)
} else if (item.conflictType == 4) {
//班级冲突
if (!returnData.classes[item.conflictName]) {
returnData.classes[item.conflictName] = []
}
value.classesName = item.conflictName
returnData.classes[item.conflictName].push(value)
}
})
})
returnData.students = _.values(returnData.students)
returnData.teachers = _.values(returnData.teachers)
returnData.classRooms = _.values(returnData.classRooms)
returnData.classes = _.values(returnData.classes)
return returnData
}
function checkClash(url, query) {
let result = JSON.parse(axios.post(url, query, { sync: true }))
let hasClash = 0
if (result.data && result.data.constructor.name == 'Object') {
result.data = [result.data][0]
}
let returnData = window.clashFunction(result.data)
if (
returnData.classRooms.length > 0 ||
returnData.students.length > 0 ||
returnData.teachers.length > 0
) {
hasClash = returnData
}
if (typeof result == 'string') {
result = JSON.parse(result)
}
result.hasClash = hasClash
result.data = returnData
return result
}
window.checkClash = checkClash
window.caluDateTimeStamp = (date, minute) => {
let dateTimeStamp = date.startOf('day').valueOf()
if (minute) {
let minuteTimeStamp = parseInt(minute) * 60 * 1000
return dateTimeStamp + minuteTimeStamp
}
return dateTimeStamp
}
window.hashFilter = hash => {
if (!hash) {
return '/'
}
hash.replace(/#/, '')
let list = hash.split('/')
list = _.filter(list, item => {
return item && !/^[0-9]*$/.test(item)
})
return list.join('/')
}
window.getObjectURL = file => {
var url = null
if (window.createObjcectURL != undefined) {
url = window.createOjcectURL(file)
} else if (window.URL != undefined) {
url = window.URL.createObjectURL(file)
} else if (window.webkitURL != undefined) {
url = window.webkitURL.createObjectURL(file)
}
return url
}
window.setNumberInput = (str, ret = 1) => {
if (!str && !isNumber(str)) {
return ''
}
return str / ret
}
window.getNumberInput = (str, ret = 1) => {
str = str + ''
if (!str && !isNumber(str)) {
return ''
}
return str * ret
}
window.removeNull = function(param) {
if (!param) {
return
}
for (let attr in param) {
if (_.isNull(param[attr]) || _.isUndefined(param[attr])) {
delete param[attr]
continue
}
if (
typeof param[attr] == 'number' &&
(param[attr] + '').indexOf('.9999') != -1
) {
param[attr] = Math.round(param[attr])
}
if (typeof param[attr] == 'object') {
removeNull(param[attr])
}
}
}
window.convertBase64ToBlob = function(base64) {
var base64Arr = base64.split(',')
var imgtype = ''
var base64String = ''
if (base64Arr.length > 1) {
//如果是图片base64,去掉头信息
base64String = base64Arr[1]
imgtype = base64Arr[0].substring(
base64Arr[0].indexOf(':') + 1,
base64Arr[0].indexOf(';')
)
}
// 将base64解码
var bytes = atob(base64String)
//var bytes = base64;
var bytesCode = new ArrayBuffer(bytes.length)
// 转换为类型化数组
var byteArray = new Uint8Array(bytesCode)
// 将base64转换为ascii码
for (var i = 0; i < bytes.length; i++) {
byteArray[i] = bytes.charCodeAt(i)
}
// 生成Blob对象(文件对象)
return new Blob([bytesCode], { type: imgtype })
}
window.formatMsgCreateTime = function(createTime) {
const newTime =
moment().year() > moment(parseInt(createTime)).year()
? formatDate('YYYY-MM-DD H:i', parseInt(createTime))
: moment().dayOfYear() - 1 > moment(parseInt(createTime)).dayOfYear()
? formatDate('MM-DD H:i', parseInt(createTime))
: moment().dayOfYear() - 1 == moment(parseInt(createTime)).dayOfYear()
? '昨天 ' + formatDate('H:i', parseInt(createTime))
: Math.floor((moment().valueOf() - parseInt(createTime)) / 1000 / 60) > 60
? '今天' + formatDate('H:i', parseInt(createTime))
: Math.floor((moment().valueOf() - parseInt(createTime)) / 1000 / 60) > 1
? Math.floor((moment().valueOf() - parseInt(createTime)) / 1000 / 60) +
'分钟前'
: '刚刚'
return newTime
}
window.getBase64Img = (url, size = 500) => {
let img = document.getElementById('xm_img_div')
if (img) {
img.remove()
}
return new Promise((resolve, reject) => {
if (!url) {
resolve('')
}
url = url.replace(/http:/, "https:") + `?x-oss-process=image/resize,h_${size},w_${size}`;
img = document.createElement("div");
img.style.position = "fixed";
img.style.left = "-10000px";
img.id = "xm_img_div";
img.innerHTML = `<img id='xm_img_url' src=${url} />`;
document.body.appendChild(img);
setTimeout(() => {
let node = document.getElementById('xm_img_url')
domtoimage.toPng(node).then(imgData => {
resolve(imgData)
})
}, 2000)
})
}
window.getDateStr = timeStamp => {
const date = new Date(timeStamp)
const year = date.getFullYear()
let month = date.getMonth() + 1
let day = date.getDate()
if (month < 10) {
month = `0${month}`
}
if (day < 10) {
day = `0${day}`
}
return `${year}${month}${day}`
}
window.copyText = textContent => {
const inputDom = document.createElement('textarea')
inputDom.value = textContent
document.body.appendChild(inputDom)
inputDom.select()
document.execCommand('copy')
document.body.removeChild(inputDom)
}
window.downloadFile = (dataURL, fileName) => {
const eleDom = document.createElement('a')
const blob = window.convertBase64ToBlob(dataURL)
const href = window.getObjectURL(blob)
$(eleDom)
.attr({
href,
download: fileName
})
.get(0)
.click()
}
window.getCouponRule = record => {
const {
type,
couponType,
consumeAmount,
discount,
classHour,
giftName
} = record
let rule = ''
switch (type || couponType) {
case 1:
if (consumeAmount) {
rule = `满${consumeAmount / 100}可用`
}
break
case 2:
rule = `${discount / 10}折`
break
case 3:
rule = `${classHour / 100}课时`
break
case 4:
rule = giftName
break
default:
break
}
return rule
}
window.getCouponRuleNew = record => {
const {
type,
couponType,
consumeAmount,
decimalDiscountAmount,
discount,
classHour,
giftName
} = record
let rule = ''
switch (couponType) {
case 'CASH':
rule = `抵扣${decimalDiscountAmount}元`
break
case 'DISCOUNT':
rule = `${discount / 10}折`
break
case 'CLASS_HOUR':
rule = `${classHour / 100}课时`
break
case 'GIFT':
rule = giftName
break
default:
break
}
return rule
}
window.replaceString = str => {
return str.replace(/\n/g, '<br/>')
}
/**
处理换行字符
*/
window.replaceStringReverse = str => {
return str.replace(/<br\/>/g, '\n')
}
// 判断是否是腾讯视频
window.isTencentVideo = url => {
const TENCENT_FLAG = 'v.qq.com'
return url.indexOf(TENCENT_FLAG) >= 0
}
// 判断是否是优酷视频
window.isYoukuVideo = url => {
const YOUKU_FLAG = 'v.youku.com'
return url.indexOf(YOUKU_FLAG) >= 0
}
// 手机号中间4位星号处理
window.starPhone = (phone) => {
let newPhone = ''
if (phone) {
newPhone = phone.substr(0, 3) + '****' + phone.substr(7)
}
return newPhone
}
// 人民币格式 单位元
window.getMoneyFormatYuan = (price) => {
if (!_.isNumber(Number(price))) {
return '0.00'
}
const n = parseFloat(price).toFixed(2)
const re = /(\d{1,3})(?=(\d{3})+(?:\.))/g
return n.replace(re, '$1,')
}
// 处理定价标准 仅订单详情,打印收据预览可用
window.formatPriceStandard = (info) => {
let { quantityUnit, specName, commoditySpecs, purchaseItemType, unitPriceAfterDiscount,specCurrentPrice } = info
let newCommoditySpecs = JSON.parse(commoditySpecs || '[]') || {}
let { containQuantity, unitPrice, measurementUnits } = newCommoditySpecs
let content = ''
if (purchaseItemType != 'COURSE') {
content = `${specCurrentPrice}元/${ENUM.itemUnit[quantityUnit]}`
} else {
let text = containQuantity != 1 ? containQuantity : '/'
content = `${specName}(${specCurrentPrice}${text}${measurementUnits})`
}
return content
}
window.getCouponRuleNew = (record) => {
const { type, couponType, consumeAmount, decimalDiscountAmount, discount, classHour, giftName } = record
let rule = ''
switch (couponType) {
case 'CASH':
rule = `抵扣${decimalDiscountAmount}元`
break
case 'DISCOUNT':
rule = `${discount / 10}折`
break
case 'CLASS_HOUR':
rule = `${classHour / 100}课时`
break
case 'GIFT':
rule = giftName
break
default: break
}
return rule
}
window.renderCourseName = (list) => {
if (list && list.length) {
const associatedCourseList = JSON.parse(JSON.stringify(list))
const length = associatedCourseList.length
const majorCourseIndex = associatedCourseList.findIndex((item) => item.major === 'YES')
const majorCourse = associatedCourseList.splice(majorCourseIndex, 1)[0]
const content = (
<div className="course-content">
<p><i className="icon iconfont icon-zhu"></i>{majorCourse.name}</p>
{
associatedCourseList.map((item, index) => {
return <p><i className="icon iconfont icon-ci"></i>{item.name}</p>
})
}
</div>
)
return length > 1 ?
<span>{majorCourse.name}
<Popover placement="bottomLeft" content={content} arrowPointAtCenter>
<span style={{ color: '#FF7519', cursor: 'pointer' }}>{length}</span>
</Popover>
</span> :
<span>{majorCourse.name}</span>
}
return ''
}
window.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" });
}
// 小麦秀 new 标签显示
window.XMShowClassName = (date,itemName) => {
// 超过时间不显示
if (new Date().getTime() > date ) {
return '';
}
// 用户点击相应区域后不显示
if (localStorage.getItem(itemName) === 'true') {
return '';
}
return 'new-icon'
}
\ No newline at end of file
@sunLight: #FED951; @sunLight: #FED951;
@sun: #Fc9C6B; @sun: #FFB714;
@sunDark: #DD8029; @sunDark: #DD8029;
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
@sucess: @sun; @sucess: @sun;
@warning: #FB696A; @warning: #FF4F4F;
@border: #e8e8e8; @border: #e8e8e8;
......
import React, { useEffect, useRef, useState } from 'react'; import React, { useEffect, useRef, useState} from 'react';
import { import {
withRouter withRouter
} from 'react-router-dom'; } from 'react-router-dom';
import './Login.less'; import './Login.less';
import {Input,Popover} from 'antd';
import CheckBeforeSendCode from '../../components/CheckBeforeSendCode';
function Login(props) { function Login(props) {
const [openCheck1, setOpenCheck1] = useState(false);
const [checkObject1, setCheckObject1] = useState({});
const [checking1, setChecking1] = useState(false);
useEffect(() => { useEffect(() => {
}, []) }, [])
async function checkAccount(code, callback = () => { }) {
}
function checkSend(code) {
}
return ( return (
<div className="login-page" > <div className="login-page" >
<div className="login-main"> <div className="login-main">
<div className="left-banner"> <div className="left-banner">
<img src='https://image.xiaomaiketang.com/xm/DXDsNKB3Fn.png' alt="" style={{ width: 448, marginTop: 60 }} /> <div><img src={require("../../common/images/logo.png")} alt="" style={{ width: 60,height:61}} /></div>
<div class="name">小麦云课堂</div>
<div class="desc">一键开启直播授课 让知识更有价值</div>
</div> </div>
<div className="login-box"> <div className="login-box">
登录 <div className="login">
<div className="r">
<div className="title">
手机号登录
</div>
<form action="" className="login-form">
<div className="form">
<div className="username" style={{ marginBottom: 16 }}>
<Input
type="phone"
autoComplete="off"
name="account"
maxLength={11}
placeholder="手机号"
/>
</div>
<div className="phoneverify">
<Input
type="text"
id="phoneverify"
name="phoneverify"
placeholder="验证码"
autoComplete="off"
/>
<Popover
visible={false}
trigger="click"
title=""
content={<div>
<span style={{ fontSize: '12px', color: '#999', marginBottom: 8, display: 'block' }}>请完成安全验证</span>
<CheckBeforeSendCode
callback={(data, nc) => {
setCheckObject1(nc);
checkAccount(1, (userType) => {
handleSendSMSCode(data, userType);
setTimeout(() => {
setOpenCheck1(false);
}, 500)
})
}}
/>
</div>}
onVisibleChange={(value) => {
if (!value) {
setOpenCheck1(false);
}
}}
placement="bottomRight"
>
<div
className="btn"
id="sendVerifyCode"
onClick={() => {
if (checking1) return;
checkSend(1)
}}
>获取验证码</div>
</Popover>
</div>
<div className="error-message">
验证码有误
</div>
<div className="submit">
<div className="btn">
<button id='loginIn' type="submit">登录</button>
</div>
</div>
<div className="network-message">
<span className="icon iconfont">&#xe834;</span>网络不给力,请<span className="refresh">点击刷新</span>
</div>
</div>
</form>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
......
@import url('../../core/variables.less'); @import url('../../core/variables.less');
.login-page { .login-page {
position: static; // background: url('../../images/main_banner.png'); position: static;
// background-size: 100%;
font-family: "微软雅黑"; font-family: "微软雅黑";
padding: 0; padding: 0;
height: 100%;
min-width: 1200px; min-width: 1200px;
background: #21242E;
height:100%;
.login-main { .login-main {
min-width: 1200px; min-width: 1200px;
} }
.left-banner { .left-banner {
position: fixed;
min-width:315px;
text-align:center;
top: 50%;
left: 30%;
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
transform:translate(-50%, -50%);
.name{
font-size: 30px;
font-weight: 500;
color: #FFFFFF;
line-height: 42px;
margin-top:11px;
}
.desc{
font-size: 14px;
font-weight: 400;
color: #FFFFFF;
line-height: 20px;
margin-top:10px;
}
} }
.login-box { .login-box {
min-width: 360px;
height: 340px;
position: fixed;
top: 50%;
left: 70%;
-webkit-transform:translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-o-transform:translate(-50%, -50%);
transform: translate(-50%, -50%);
.go-to-site {
position: absolute;
bottom: -80px;
width: 200px;
margin: 0 auto;
left: 50%;
margin-left: -50px;
a {
color: #FFF;
text-decoration: none;
}
span.icon {
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
-ms-transform: rotate(180deg);
-o-transform: rotate(180deg);
transform: rotate(180deg);
font-size: 12px;
display: inline-block;
margin-right: 10px;
}
}
.login {
display: flex;
display: -webkit-flex;
flex-direction: row;
-webkit-flex-direction: row;
height: 100%;
overflow: hidden;
background-color: #ffffff;
border-radius: 4px; //box-shadow: 0 0 17px @sun;
.l {
width: 280px;
height: 100%;
background: @primary;
background: -webkit-gradient(linear, left top, left bottom, from(#ffaa1a), to(#ff8634)) !important;
display: flex;
display: -webkit-flex;
-webkit-flex-direction: column;
flex-direction: column;
align-items: center;
color: #ffffff;
font-size: 12px;
justify-content: center;
-webkit-justify-content: center;
.logo {
height: 125px;
img {
height: 100%;
}
}
.name {
font-size: 16px;
margin-bottom: 20px;
}
.desc {
opacity: .7;
margin-bottom: 20px;
}
.items {
ul {
padding: 0;
li {
.icon {
-webkit-transform: scale(.8);
-moz-transform: scale(.8);
-ms-transform: scale(.8);
-o-transform: scale(.8);
transform: scale(.8);
display: inline-block;
margin-right: 10px;
}
line-height: 30px;
list-style-type: none;
}
}
}
}
.r {
flex: 1;
-webkit-flex: 1;
height: 100%;
padding: 30px;
box-sizing: border-box;
position: relative;
&.show-qrcode {
.qrcode {
display: block;
}
.top-right-tip {
.computer {
display: inline-block;
}
.icon-container {
display: none;
}
}
}
.qrcode {
display: none;
text-align: center;
position: absolute;
background: #FFF;
z-index: 1;
left: 20px;
top: 28px;
padding-top: 20px;
img {
display: inline-block;
width: 180px;
}
}
.top-right-tip {
cursor: pointer;
position: absolute;
top: 4px;
right: 4px;
.computer {
display: none;
}
.icon-container {
position: relative;
height: 32px;
width: 32px;
display: inline-block;
.tips {
width: 69px;
position: absolute;
top: 0;
right: 36px;
img {
width: 100%;
}
}
.shade {
position: absolute;
width: 100%;
height: 150%;
top: 0;
margin-left: -100%;
background: #FFF;
transform-origin: right top;
transform: rotate(-45deg);
}
}
span.icon {
font-size: 32px;
}
}
.title {
font-size: 18px;
font-weight: 500;
color: #333333;
line-height: 25px;
text-align:center;
font-weight:bold;
margin-bottom:43px;
&::after {
}
.text1 {
color: black;
}
.icon {
font-size: 11px;
}
#login-method {
width: 100%;
text-align: center;
span {
color: #999;
font-weight: 400;
&:hover {
color: #333;
}
}
span.active {
font-weight: 500;
color: #333;
&::after {
content: '';
display: block;
width: 24px;
height: 4px;
border-radius: 3px;
background: #FF8534;
margin: 10px auto 0;
}
}
#password-login {
margin-right: 32px;
}
}
}
#password-icon {
color: #BFBFBF;
margin-right: 10px;
cursor: pointer;
&:hover {
color: #FC9C6B;
}
-webkit-user-select: none;
-moz-user-select:none;
-o-user-select:none;
-ms-user-select:none;
}
input {
display: block;
width: 100%;
height: 40px;
line-height: 40px;
border: 1px solid #e8e8e8; // border-bottom: 1px solid @xm-color-border;
padding-right: 30px;
padding-left: 10px;
margin-bottom: 16px;
background-color: transparent;
background-image: none;
border-radius: 4px;
box-sizing: border-box;
-webkit-transition: all .3s linear;
-moz-transition: all .3s linear;
-ms-transition: all .3s linear;
-o-transition: all .3s linear;
transition: all .3s linear;
&:focus,
&:active,
&:hover {
outline: none; // border: none!important;
// border-bottom: 1px solid @sun!important;
box-shadow: none;
border-color: @primary;
}
}
::-webkit-input-placeholder {
/* WebKit, Blink, Edge */
color: #ccc;
}
:-moz-placeholder {
/* Mozilla Firefox 4 to 18 */
color: #ccc;
}
::-moz-placeholder {
/* Mozilla Firefox 19+ */
color: #ccc;
}
:-ms-input-placeholder {
/* Internet Explorer 10-11 */
color: #ccc
}
input:-webkit-autofill,
textarea:-webkit-autofill,
select:-webkit-autofill {
-webkit-box-shadow: 0 0 0 1000px white inset;
}
.username,
.password,
.phoneverify {
height: 40px;
position: relative;
color: #666666;
.icon {
position: absolute;
right: 5px;
top: 5px;
font-size: 20px;
}
#sendVerifyCode {
cursor: pointer;
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
align-items: center;
-webkit-align-items: center;
position: absolute;
right: 10px;
top: -53px; // border: 1px solid @sun;
color: #333;
height: 25px;
width: 90px;
border-radius: 3px;
margin-top: 60px;
font-size: 14px; // font-weight: 300;
&:hover {
color: #FF8534;
}
&::before {
content: '';
display: block;
height: 20px;
width: 1px;
background-color: #e8e8e8;
margin-right: 10px;
}
}
}
.error-message{
font-size: 14px;
font-weight: 400;
color: @warning;
line-height: 20px;
margin-top:9px;
}
.network-message{
text-align:center;
font-size:14px;
color:#000;
margin-top:11px;
.icon{
font-size:14px;
color:@primary;
margin-right:8px;
}
.refresh{
font-size:14px;
color:#5289FA;
cursor: pointer;
}
}
#sendVoiceVerifyCode {
cursor: pointer;
}
.phoneverify-voice {
// padding-left: 5px;
margin-top: 10px;
&::after {}
}
.submit {
margin-top:11px;
button {
// font-weight: 300;
}
}
.apply {
cursor: pointer;
text-align: right;
margin-top: 10px;
color: #999;
float: right; // font-weight: 300;
span.icon {
font-size: 12px;
margin-left: 7px;
}
&:hover {
color: #FC9C6B;
}
}
.btn {
button {
display: block;
width: 100%;
background: @primary;
color: #fff;
font-size: 14px;
font-weight: 400;
line-height: 40px;
border-radius: 4px;
-webkit-transition: all .3s;
-moz-transition: all .3s;
-ms-transition: all .3s;
-o-transition: all .3s;
transition: all .3s;
cursor: pointer;
border: none;
&:hover {
opacity: 0.7;
background: linear-gradient(90deg, #FFB714 0%, #FFAD34 100%);
}
}
}
}
}
} }
} }
\ No newline at end of file
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